From 47a8df84bed22b7b33ac334c21729a24d55b7872 Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Tue, 12 May 2020 21:24:44 +0200 Subject: [PATCH 001/581] Support for VEML6075 and VEML 7700 Add support for VEML6075. -Shows UVA, UVB, UVIndex supported Commands are: | Command | Description | |----------------|------------------| |VEML6075power | Power up/down | |VEML6075dynamic | HD Mode | |VEML6075inttime | Integration Time | Add initial Support for VEML7700 (#8260) - the implementation based on Adafruit VEML7700 Libary. - Shows Illuminance and White Content of Light. --- I2CDEVICES.md | 4 +- lib/Adafruit_BusIO/.travis.yml | 23 ++ .../Adafruit_BusIO_Register.cpp | 258 ++++++++++++++ lib/Adafruit_BusIO/Adafruit_BusIO_Register.h | 69 ++++ lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp | 213 ++++++++++++ lib/Adafruit_BusIO/Adafruit_I2CDevice.h | 29 ++ lib/Adafruit_BusIO/Adafruit_I2CRegister.h | 8 + lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp | 301 ++++++++++++++++ lib/Adafruit_BusIO/Adafruit_SPIDevice.h | 62 ++++ lib/Adafruit_BusIO/LICENSE | 21 ++ lib/Adafruit_BusIO/README.md | 7 + .../i2c_address_detect/i2c_address_detect.ino | 21 ++ .../examples/i2c_readwrite/i2c_readwrite.ino | 41 +++ .../examples/i2c_registers/i2c_registers.ino | 38 +++ .../i2corspi_register/i2corspi_register.ino | 38 +++ .../examples/spi_modetest/spi_modetest.ino | 29 ++ .../examples/spi_readwrite/spi_readwrite.ino | 39 +++ .../examples/spi_registers/spi_registers.ino | 34 ++ lib/Adafruit_BusIO/library.properties | 9 + .../.github/ISSUE_TEMPLATE.md | 46 +++ .../.github/PULL_REQUEST_TEMPLATE.md | 26 ++ lib/Adafruit_VEML7700/.gitignore | 8 + lib/Adafruit_VEML7700/.travis.yml | 26 ++ lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp | 322 ++++++++++++++++++ lib/Adafruit_VEML7700/Adafruit_VEML7700.h | 113 ++++++ lib/Adafruit_VEML7700/README.md | 16 + .../examples/veml7700_test/veml7700_test.ino | 58 ++++ lib/Adafruit_VEML7700/library.properties | 9 + lib/Adafruit_VEML7700/license.txt | 26 ++ tasmota/i18n.h | 10 + tasmota/my_user_config.h | 2 + tasmota/support_features.ino | 9 +- tasmota/xsns_70_veml6075.ino | 306 +++++++++++++++++ tasmota/xsns_71_veml7700.ino | 117 +++++++ 34 files changed, 2334 insertions(+), 4 deletions(-) create mode 100644 lib/Adafruit_BusIO/.travis.yml create mode 100644 lib/Adafruit_BusIO/Adafruit_BusIO_Register.cpp create mode 100644 lib/Adafruit_BusIO/Adafruit_BusIO_Register.h create mode 100644 lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp create mode 100644 lib/Adafruit_BusIO/Adafruit_I2CDevice.h create mode 100644 lib/Adafruit_BusIO/Adafruit_I2CRegister.h create mode 100644 lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp create mode 100644 lib/Adafruit_BusIO/Adafruit_SPIDevice.h create mode 100644 lib/Adafruit_BusIO/LICENSE create mode 100644 lib/Adafruit_BusIO/README.md create mode 100644 lib/Adafruit_BusIO/examples/i2c_address_detect/i2c_address_detect.ino create mode 100644 lib/Adafruit_BusIO/examples/i2c_readwrite/i2c_readwrite.ino create mode 100644 lib/Adafruit_BusIO/examples/i2c_registers/i2c_registers.ino create mode 100644 lib/Adafruit_BusIO/examples/i2corspi_register/i2corspi_register.ino create mode 100644 lib/Adafruit_BusIO/examples/spi_modetest/spi_modetest.ino create mode 100644 lib/Adafruit_BusIO/examples/spi_readwrite/spi_readwrite.ino create mode 100644 lib/Adafruit_BusIO/examples/spi_registers/spi_registers.ino create mode 100644 lib/Adafruit_BusIO/library.properties create mode 100644 lib/Adafruit_VEML7700/.github/ISSUE_TEMPLATE.md create mode 100644 lib/Adafruit_VEML7700/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 lib/Adafruit_VEML7700/.gitignore create mode 100644 lib/Adafruit_VEML7700/.travis.yml create mode 100644 lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp create mode 100644 lib/Adafruit_VEML7700/Adafruit_VEML7700.h create mode 100644 lib/Adafruit_VEML7700/README.md create mode 100644 lib/Adafruit_VEML7700/examples/veml7700_test/veml7700_test.ino create mode 100644 lib/Adafruit_VEML7700/library.properties create mode 100644 lib/Adafruit_VEML7700/license.txt create mode 100644 tasmota/xsns_70_veml6075.ino create mode 100644 tasmota/xsns_71_veml7700.ino diff --git a/I2CDEVICES.md b/I2CDEVICES.md index cb42d97a4..008f16c99 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -69,4 +69,6 @@ Index | Define | Driver | Device | Address(es) | Description 45 | USE_HDC1080 | xsns_65 | HDC1080 | 0x40 | Temperature and Humidity sensor 46 | USE_IAQ | xsns_66 | IAQ | 0x5a | Air quality sensor 47 | USE_DISPLAY_SEVENSEG| xdsp_11 | HT16K33 | 0x70 - 0x77 | Seven segment LED - 48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor \ No newline at end of file + 48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor + 49 | USE_VEML6075 | xsns_68 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor + 50 | USE_VEML7700 | xsns_69 | VEML7700 | 0x10 | Ambient light intensity sensor \ No newline at end of file diff --git a/lib/Adafruit_BusIO/.travis.yml b/lib/Adafruit_BusIO/.travis.yml new file mode 100644 index 000000000..40754054e --- /dev/null +++ b/lib/Adafruit_BusIO/.travis.yml @@ -0,0 +1,23 @@ +language: c +sudo: false +cache: + directories: + - ~/arduino_ide + - ~/.arduino15/packages/ +git: + depth: false + quiet: true +env: + global: + - PRETTYNAME="Adafruit BusIO Library" + +before_install: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh) + +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_BusIO/Adafruit_BusIO_Register.cpp b/lib/Adafruit_BusIO/Adafruit_BusIO_Register.cpp new file mode 100644 index 000000000..2c2b22e00 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_BusIO_Register.cpp @@ -0,0 +1,258 @@ +#include + +/*! + * @brief Create a register we access over an I2C Device (which defines the bus and address) + * @param i2cdevice The I2CDevice to use for underlying I2C access + * @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits + * @param width The width of the register data itself, defaults to 1 byte + * @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST + * @param address_width The width of the register address itself, defaults to 1 byte + */ +Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr, + uint8_t width, uint8_t bitorder, uint8_t address_width) { + _i2cdevice = i2cdevice; + _spidevice = NULL; + _addrwidth = address_width; + _address = reg_addr; + _bitorder = bitorder; + _width = width; +} + +/*! + * @brief Create a register we access over an SPI Device (which defines the bus and CS pin) + * @param spidevice The SPIDevice to use for underlying I2C access + * @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits + * @param type The method we use to read/write data to SPI (which is not as well defined as I2C) + * @param width The width of the register data itself, defaults to 1 byte + * @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST + * @param address_width The width of the register address itself, defaults to 1 byte + */ +Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr, + Adafruit_BusIO_SPIRegType type, + uint8_t width, uint8_t bitorder, uint8_t address_width) { + _spidevice = spidevice; + _spiregtype = type; + _i2cdevice = NULL; + _addrwidth = address_width; + _address = reg_addr; + _bitorder = bitorder; + _width = width; +} + +/*! + * @brief Create a register we access over an I2C or SPI Device. This is a handy function because we + * can pass in NULL for the unused interface, allowing libraries to mass-define all the registers + * @param i2cdevice The I2CDevice to use for underlying I2C access, if NULL we use SPI + * @param spidevice The SPIDevice to use for underlying I2C access, if NULL we use I2C + * @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits + * @param type The method we use to read/write data to SPI (which is not as well defined as I2C) + * @param width The width of the register data itself, defaults to 1 byte + * @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST + * @param address_width The width of the register address itself, defaults to 1 byte + */ +Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, Adafruit_SPIDevice *spidevice, + Adafruit_BusIO_SPIRegType type, uint16_t reg_addr, + uint8_t width, uint8_t bitorder, uint8_t address_width) { + _spidevice = spidevice; + _i2cdevice = i2cdevice; + _spiregtype = type; + _addrwidth = address_width; + _address = reg_addr; + _bitorder = bitorder; + _width = width; +} + + +/*! + * @brief Write a buffer of data to the register location + * @param buffer Pointer to data to write + * @param len Number of bytes to write + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) { + + uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address>>8)}; + + if (_i2cdevice) { + return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth); + } + if (_spidevice) { + if (_spiregtype == ADDRBIT8_HIGH_TOREAD) { + addrbuffer[0] &= ~0x80; + } + return _spidevice->write( buffer, len, addrbuffer, _addrwidth); + } + return false; +} + +/*! + * @brief Write up to 4 bytes of data to the register location + * @param value Data to write + * @param numbytes How many bytes from 'value' to write + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::write(uint32_t value, uint8_t numbytes) { + if (numbytes == 0) { + numbytes = _width; + } + if (numbytes > 4) { + return false; + } + + for (int i=0; i>= 8; + } + return write(_buffer, numbytes); +} + +/*! + * @brief Read data from the register location. This does not do any error checking! + * @return Returns 0xFFFFFFFF on failure, value otherwise + */ +uint32_t Adafruit_BusIO_Register::read(void) { + if (! read(_buffer, _width)) { + return -1; + } + + uint32_t value = 0; + + for (int i=0; i < _width; i++) { + value <<= 8; + if (_bitorder == LSBFIRST) { + value |= _buffer[_width-i-1]; + } else { + value |= _buffer[i]; + } + } + + return value; +} + + +/*! + * @brief Read a buffer of data from the register location + * @param buffer Pointer to data to read into + * @param len Number of bytes to read + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) { + uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address>>8)}; + + if (_i2cdevice) { + return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len); + } + if (_spidevice) { + if (_spiregtype == ADDRBIT8_HIGH_TOREAD) { + addrbuffer[0] |= 0x80; + } + return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len); + } + return false; +} + +/*! + * @brief Read 2 bytes of data from the register location + * @param value Pointer to uint16_t variable to read into + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::read(uint16_t *value) { + if (! read(_buffer, 2)) { + return false; + } + + if (_bitorder == LSBFIRST) { + *value = _buffer[1]; + *value <<= 8; + *value |= _buffer[0]; + } else { + *value = _buffer[0]; + *value <<= 8; + *value |= _buffer[1]; + } + return true; +} + +/*! + * @brief Read 1 byte of data from the register location + * @param value Pointer to uint8_t variable to read into + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::read(uint8_t *value) { + if (! read(_buffer, 1)) { + return false; + } + + *value = _buffer[0]; + return true; +} + +/*! + * @brief Pretty printer for this register + * @param s The Stream to print to, defaults to &Serial + */ +void Adafruit_BusIO_Register::print(Stream *s) { + uint32_t val = read(); + s->print("0x"); s->print(val, HEX); +} + +/*! + * @brief Pretty printer for this register + * @param s The Stream to print to, defaults to &Serial + */ +void Adafruit_BusIO_Register::println(Stream *s) { + print(s); + s->println(); +} + + +/*! + * @brief Create a slice of the register that we can address without touching other bits + * @param reg The Adafruit_BusIO_Register which defines the bus/register + * @param bits The number of bits wide we are slicing + * @param shift The number of bits that our bit-slice is shifted from LSB + */ +Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift) { + _register = reg; + _bits = bits; + _shift = shift; +} + +/*! + * @brief Read 4 bytes of data from the register + * @return data The 4 bytes to read + */ +uint32_t Adafruit_BusIO_RegisterBits::read(void) { + uint32_t val = _register->read(); + val >>= _shift; + return val & ((1 << (_bits)) - 1); +} + + +/*! + * @brief Write 4 bytes of data to the register + * @param data The 4 bytes to write + */ +void Adafruit_BusIO_RegisterBits::write(uint32_t data) { + uint32_t val = _register->read(); + + // mask off the data before writing + uint32_t mask = (1 << (_bits)) - 1; + data &= mask; + + mask <<= _shift; + val &= ~mask; // remove the current data at that spot + val |= data << _shift; // and add in the new data + + _register->write(val, _register->width()); +} + +/*! + * @brief The width of the register data, helpful for doing calculations + * @returns The data width used when initializing the register + */ +uint8_t Adafruit_BusIO_Register::width(void) { return _width; } diff --git a/lib/Adafruit_BusIO/Adafruit_BusIO_Register.h b/lib/Adafruit_BusIO/Adafruit_BusIO_Register.h new file mode 100644 index 000000000..45ae1e146 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_BusIO_Register.h @@ -0,0 +1,69 @@ +#include +#include +#include + + +#ifndef Adafruit_BusIO_Register_h +#define Adafruit_BusIO_Register_h + +typedef enum _Adafruit_BusIO_SPIRegType { + ADDRBIT8_HIGH_TOREAD = 0, +} Adafruit_BusIO_SPIRegType; + +/*! + * @brief The class which defines a device register (a location to read/write data from) + */ +class Adafruit_BusIO_Register { + public: + Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr, + uint8_t width=1, uint8_t bitorder=LSBFIRST, + uint8_t address_width=1); + Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr, + Adafruit_BusIO_SPIRegType type, + uint8_t width=1, uint8_t bitorder=LSBFIRST, + uint8_t address_width=1); + + Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, + Adafruit_SPIDevice *spidevice, + Adafruit_BusIO_SPIRegType type, + uint16_t reg_addr, + uint8_t width=1, uint8_t bitorder=LSBFIRST, + uint8_t address_width=1); + + bool read(uint8_t *buffer, uint8_t len); + bool read(uint8_t *value); + bool read(uint16_t *value); + uint32_t read(void); + bool write(uint8_t *buffer, uint8_t len); + bool write(uint32_t value, uint8_t numbytes=0); + + uint8_t width(void); + + void print(Stream *s=&Serial); + void println(Stream *s=&Serial); + + private: + Adafruit_I2CDevice *_i2cdevice; + Adafruit_SPIDevice *_spidevice; + Adafruit_BusIO_SPIRegType _spiregtype; + uint16_t _address; + uint8_t _width, _addrwidth, _bitorder; + uint8_t _buffer[4]; // we wont support anything larger than uint32 for non-buffered read +}; + + +/*! + * @brief The class which defines a slice of bits from within a device register (a location to read/write data from) + */ +class Adafruit_BusIO_RegisterBits { + public: + Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift); + void write(uint32_t value); + uint32_t read(void); + private: + Adafruit_BusIO_Register *_register; + uint8_t _bits, _shift; +}; + + +#endif //BusIO_Register_h diff --git a/lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp b/lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp new file mode 100644 index 000000000..7813a6df7 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp @@ -0,0 +1,213 @@ +#include +#include + +//#define DEBUG_SERIAL Serial + +/*! + * @brief Create an I2C device at a given address + * @param addr The 7-bit I2C address for the device + * @param theWire The I2C bus to use, defaults to &Wire + */ +Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) { + _addr = addr; + _wire = theWire; + _begun = false; +#ifdef ARDUINO_ARCH_SAMD + _maxBufferSize = 250; // as defined in Wire.h's RingBuffer +#else + _maxBufferSize = 32; +#endif +} + +/*! + * @brief Initializes and does basic address detection + * @param addr_detect Whether we should attempt to detect the I2C address with a scan. + * 99% of sensors/devices don't mind but once in a while, they spaz on a scan! + * @return True if I2C initialized and a device with the addr found + */ +bool Adafruit_I2CDevice::begin(bool addr_detect) { + _wire->begin(); + _begun = true; + + if (addr_detect) { + return detected(); + } + return true; +} + + +/*! + * @brief Scans I2C for the address - note will give a false-positive + * if there's no pullups on I2C + * @return True if I2C initialized and a device with the addr found + */ +bool Adafruit_I2CDevice::detected(void) { + // Init I2C if not done yet + if (!_begun && !begin()) { + return false; + } + + // A basic scanner, see if it ACK's + _wire->beginTransmission(_addr); + if (_wire->endTransmission () == 0) { + return true; + } + return false; +} + +/*! + * @brief Write a buffer or two to the I2C device. Cannot be more than maxBufferSize() bytes. + * @param buffer Pointer to buffer of data to write + * @param len Number of bytes from buffer to write + * @param prefix_buffer Pointer to optional array of data to write before buffer. + * Cannot be more than maxBufferSize() bytes. + * @param prefix_len Number of bytes from prefix buffer to write + * @param stop Whether to send an I2C STOP signal on write + * @return True if write was successful, otherwise false. + */ +bool Adafruit_I2CDevice::write(uint8_t *buffer, size_t len, bool stop, uint8_t *prefix_buffer, size_t prefix_len) { + if ((len+prefix_len) > maxBufferSize()) { + // currently not guaranteed to work if more than 32 bytes! + // we will need to find out if some platforms have larger + // I2C buffer sizes :/ +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer")); +#endif + return false; + } + + _wire->beginTransmission(_addr); + + // Write the prefix data (usually an address) + if ((prefix_len != 0) && (prefix_buffer != NULL)) { + if (_wire->write(prefix_buffer, prefix_len) != prefix_len) { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println(F("\tI2CDevice failed to write")); +#endif + return false; + } + } + + // Write the data itself + if (_wire->write(buffer, len) != len) { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println(F("\tI2CDevice failed to write")); +#endif + return false; + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tI2CDevice Wrote: ")); + if ((prefix_len != 0) && (prefix_buffer != NULL)) { + for (uint16_t i=0; iendTransmission(stop) == 0) { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println("Sent!"); +#endif + return true; + } else { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println("Failed to send!"); +#endif + return false; + } +} + + +/*! + * @brief Read from I2C into a buffer from the I2C device. + * Cannot be more than maxBufferSize() bytes. + * @param buffer Pointer to buffer of data to read into + * @param len Number of bytes from buffer to read. + * @param stop Whether to send an I2C STOP signal on read + * @return True if read was successful, otherwise false. + */ +bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) { + if (len > maxBufferSize()) { + // currently not guaranteed to work if more than 32 bytes! + // we will need to find out if some platforms have larger + // I2C buffer sizes :/ +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println(F("\tI2CDevice could not read such a large buffer")); +#endif + return false; + } + + size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop); + if (recv != len) { + // Not enough data available to fulfill our obligation! +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: ")); + DEBUG_SERIAL.println(recv); +#endif + return false; + } + + for (uint16_t i=0; iread(); + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tI2CDevice Read: ")); + for (uint16_t i=0; i + +#ifndef Adafruit_I2CDevice_h +#define Adafruit_I2CDevice_h + +///< The class which defines how we will talk to this device over I2C +class Adafruit_I2CDevice { + public: + Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire=&Wire); + uint8_t address(void); + bool begin(bool addr_detect=true); + bool detected(void); + + bool read(uint8_t *buffer, size_t len, bool stop=true); + bool write(uint8_t *buffer, size_t len, bool stop=true, uint8_t *prefix_buffer=NULL, size_t prefix_len=0); + bool write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, bool stop=false); + + /*! @brief How many bytes we can read in a transaction + * @return The size of the Wire receive/transmit buffer */ + uint16_t maxBufferSize() { return _maxBufferSize; } + + private: + uint8_t _addr; + TwoWire *_wire; + bool _begun; + uint16_t _maxBufferSize; +}; + +#endif // Adafruit_I2CDevice_h diff --git a/lib/Adafruit_BusIO/Adafruit_I2CRegister.h b/lib/Adafruit_BusIO/Adafruit_I2CRegister.h new file mode 100644 index 000000000..703e93b76 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_I2CRegister.h @@ -0,0 +1,8 @@ +#include "Adafruit_BusIO_Register.h" +#ifndef _ADAFRUIT_I2C_REGISTER_H_ +#define _ADAFRUIT_I2C_REGISTER_H_ + +typedef Adafruit_BusIO_Register Adafruit_I2CRegister; +typedef Adafruit_BusIO_RegisterBits Adafruit_I2CRegisterBits; + +#endif diff --git a/lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp b/lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp new file mode 100644 index 000000000..1d599bb11 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp @@ -0,0 +1,301 @@ +#include +#include + +//#define DEBUG_SERIAL Serial + +/*! + * @brief Create an SPI device with the given CS pin and settins + * @param cspin The arduino pin number to use for chip select + * @param freq The SPI clock frequency to use, defaults to 1MHz + * @param dataOrder The SPI data order to use for bits within each byte, defaults to SPI_BITORDER_MSBFIRST + * @param dataMode The SPI mode to use, defaults to SPI_MODE0 + * @param theSPI The SPI bus to use, defaults to &theSPI + */ +Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq, BitOrder dataOrder, uint8_t dataMode, SPIClass *theSPI) { + _cs = cspin; + _sck = _mosi = _miso = -1; + _spi = theSPI; + _begun = false; + _spiSetting = new SPISettings(freq, dataOrder, dataMode); + _freq = freq; + _dataOrder = dataOrder; + _dataMode = dataMode; +} + +/*! + * @brief Create an SPI device with the given CS pin and settins + * @param cspin The arduino pin number to use for chip select + * @param sckpin The arduino pin number to use for SCK + * @param misopin The arduino pin number to use for MISO, set to -1 if not used + * @param mosipin The arduino pin number to use for MOSI, set to -1 if not used + * @param freq The SPI clock frequency to use, defaults to 1MHz + * @param dataOrder The SPI data order to use for bits within each byte, defaults to SPI_BITORDER_MSBFIRST + * @param dataMode The SPI mode to use, defaults to SPI_MODE0 + */ +Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin, int8_t misopin, int8_t mosipin, + uint32_t freq, BitOrder dataOrder, uint8_t dataMode) { + _cs = cspin; + _sck = sckpin; + _miso = misopin; + _mosi = mosipin; + _freq = freq; + _dataOrder = dataOrder; + _dataMode = dataMode; + _begun = false; + _spiSetting = new SPISettings(freq, dataOrder, dataMode); + _spi = NULL; +} + + +/*! + * @brief Initializes SPI bus and sets CS pin high + * @return Always returns true because there's no way to test success of SPI init + */ +bool Adafruit_SPIDevice::begin(void) { + pinMode(_cs, OUTPUT); + digitalWrite(_cs, HIGH); + + if (_spi) { // hardware SPI + _spi->begin(); + } else { + pinMode(_sck, OUTPUT); + + if (_dataMode==SPI_MODE0) { + digitalWrite(_sck, HIGH); + } else { + digitalWrite(_sck, LOW); + } + if (_mosi != -1) { + pinMode(_mosi, OUTPUT); + digitalWrite(_mosi, HIGH); + } + if (_miso != -1) { + pinMode(_miso, INPUT); + } + } + + _begun = true; + return true; +} + + +/*! + * @brief Transfer (send/receive) one byte over hard/soft SPI + * @param buffer The buffer to send and receive at the same time + * @param len The number of bytes to transfer + */ +void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) { + if (_spi) { + // hardware SPI is easy + _spi->transfer(buffer, len); + return; + } + + // for softSPI we'll do it by hand + for (size_t i=0; i> b) & 0x1) << (7-b); + } + send = temp; + } + for (int b=7; b>=0; b--) { + reply <<= 1; + if (_dataMode == SPI_MODE0) { + digitalWrite(_sck, LOW); + digitalWrite(_mosi, send & (1<> b) & 0x1) << (7-b); + } + reply = temp; + } + + buffer[i] = reply; + } + return; +} + + + +/*! + * @brief Transfer (send/receive) one byte over hard/soft SPI + * @param send The byte to send + * @return The byte received while transmitting + */ +uint8_t Adafruit_SPIDevice::transfer(uint8_t send) { + uint8_t data = send; + transfer(&data, 1); + return data; +} + + +/*! + * @brief Write a buffer or two to the SPI device. + * @param buffer Pointer to buffer of data to write + * @param len Number of bytes from buffer to write + * @param prefix_buffer Pointer to optional array of data to write before buffer. + * @param prefix_len Number of bytes from prefix buffer to write + * @return Always returns true because there's no way to test success of SPI writes + */ +bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len, uint8_t *prefix_buffer, size_t prefix_len) { + if (_spi) { + _spi->beginTransaction(*_spiSetting); + } + + digitalWrite(_cs, LOW); + // do the writing + for (size_t i=0; iendTransaction(); + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tSPIDevice Wrote: ")); + if ((prefix_len != 0) && (prefix_buffer != NULL)) { + for (uint16_t i=0; ibeginTransaction(*_spiSetting); + } + digitalWrite(_cs, LOW); + transfer(buffer, len); + digitalWrite(_cs, HIGH); + + if (_spi) { + _spi->endTransaction(); + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tSPIDevice Read: ")); + for (uint16_t i=0; ibeginTransaction(*_spiSetting); + } + + digitalWrite(_cs, LOW); + // do the writing + for (size_t i=0; iendTransaction(); + } + + return true; +} diff --git a/lib/Adafruit_BusIO/Adafruit_SPIDevice.h b/lib/Adafruit_BusIO/Adafruit_SPIDevice.h new file mode 100644 index 000000000..987cb3f62 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_SPIDevice.h @@ -0,0 +1,62 @@ +#include + +#ifndef Adafruit_SPIDevice_h +#define Adafruit_SPIDevice_h + +// some modern SPI definitions don't have BitOrder enum +#if (defined(__AVR__) && !defined(ARDUINO_ARCH_MEGAAVR)) || defined(ESP8266) || defined(TEENSYDUINO) +typedef enum _BitOrder { + SPI_BITORDER_MSBFIRST = MSBFIRST, + SPI_BITORDER_LSBFIRST = LSBFIRST, +} BitOrder; +#endif + +// some modern SPI definitions don't have BitOrder enum and have different SPI mode defines +#if defined(ESP32) +typedef enum _BitOrder { + SPI_BITORDER_MSBFIRST = SPI_MSBFIRST, + SPI_BITORDER_LSBFIRST = SPI_LSBFIRST, +} BitOrder; +#endif + +// Some platforms have a BitOrder enum but its named MSBFIRST/LSBFIRST +#if defined(ARDUINO_ARCH_SAMD) || defined(__SAM3X8E__) || defined(NRF52_SERIES) || defined(ARDUINO_ARCH_ARDUINO_CORE_STM32) || defined(ARDUINO_ARCH_MEGAAVR) || defined(_STM32_DEF_) + #define SPI_BITORDER_MSBFIRST MSBFIRST + #define SPI_BITORDER_LSBFIRST LSBFIRST +#endif + +///< The class which defines how we will talk to this device over SPI +class Adafruit_SPIDevice { + public: + Adafruit_SPIDevice(int8_t cspin, + uint32_t freq=1000000, + BitOrder dataOrder=SPI_BITORDER_MSBFIRST, + uint8_t dataMode=SPI_MODE0, + SPIClass *theSPI=&SPI); + + Adafruit_SPIDevice(int8_t cspin, int8_t sck, int8_t miso, int8_t mosi, + uint32_t freq=1000000, + BitOrder dataOrder=SPI_BITORDER_MSBFIRST, + uint8_t dataMode=SPI_MODE0); + + bool begin(void); + bool read(uint8_t *buffer, size_t len, uint8_t sendvalue=0xFF); + bool write(uint8_t *buffer, size_t len, uint8_t *prefix_buffer=NULL, size_t prefix_len=0); + bool write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, uint8_t sendvalue=0xFF); + + uint8_t transfer(uint8_t send); + void transfer(uint8_t *buffer, size_t len); + + private: + + SPIClass *_spi; + SPISettings *_spiSetting; + uint32_t _freq; + BitOrder _dataOrder; + uint8_t _dataMode; + + int8_t _cs, _sck, _mosi, _miso; + bool _begun; +}; + +#endif // Adafruit_SPIDevice_h diff --git a/lib/Adafruit_BusIO/LICENSE b/lib/Adafruit_BusIO/LICENSE new file mode 100644 index 000000000..860e3e285 --- /dev/null +++ b/lib/Adafruit_BusIO/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Adafruit Industries + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/lib/Adafruit_BusIO/README.md b/lib/Adafruit_BusIO/README.md new file mode 100644 index 000000000..a1830809c --- /dev/null +++ b/lib/Adafruit_BusIO/README.md @@ -0,0 +1,7 @@ +# Adafruit Bus IO Library [![Build Status](https://travis-ci.com/adafruit/Adafruit_BusIO.svg?branch=master)](https://travis-ci.com/adafruit/Adafruit_BusIO) + +This is a helper libary to abstract away I2C & SPI transactions and registers + +Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! + +MIT license, all text above must be included in any redistribution diff --git a/lib/Adafruit_BusIO/examples/i2c_address_detect/i2c_address_detect.ino b/lib/Adafruit_BusIO/examples/i2c_address_detect/i2c_address_detect.ino new file mode 100644 index 000000000..b1505254e --- /dev/null +++ b/lib/Adafruit_BusIO/examples/i2c_address_detect/i2c_address_detect.ino @@ -0,0 +1,21 @@ +#include + +Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(0x10); + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("I2C address detection test"); + + if (!i2c_dev.begin()) { + Serial.print("Did not find device at 0x"); + Serial.println(i2c_dev.address(), HEX); + while (1); + } + Serial.print("Device found on address 0x"); + Serial.println(i2c_dev.address(), HEX); +} + +void loop() { + +} diff --git a/lib/Adafruit_BusIO/examples/i2c_readwrite/i2c_readwrite.ino b/lib/Adafruit_BusIO/examples/i2c_readwrite/i2c_readwrite.ino new file mode 100644 index 000000000..909cf3118 --- /dev/null +++ b/lib/Adafruit_BusIO/examples/i2c_readwrite/i2c_readwrite.ino @@ -0,0 +1,41 @@ +#include + +#define I2C_ADDRESS 0x60 +Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS); + + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("I2C device read and write test"); + + if (!i2c_dev.begin()) { + Serial.print("Did not find device at 0x"); + Serial.println(i2c_dev.address(), HEX); + while (1); + } + Serial.print("Device found on address 0x"); + Serial.println(i2c_dev.address(), HEX); + + uint8_t buffer[32]; + // Try to read 32 bytes + i2c_dev.read(buffer, 32); + Serial.print("Read: "); + for (uint8_t i=0; i<32; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); + + // read a register by writing first, then reading + buffer[0] = 0x0C; // we'll reuse the same buffer + i2c_dev.write_then_read(buffer, 1, buffer, 2, false); + Serial.print("Write then Read: "); + for (uint8_t i=0; i<2; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); +} + +void loop() { + +} diff --git a/lib/Adafruit_BusIO/examples/i2c_registers/i2c_registers.ino b/lib/Adafruit_BusIO/examples/i2c_registers/i2c_registers.ino new file mode 100644 index 000000000..41a30436e --- /dev/null +++ b/lib/Adafruit_BusIO/examples/i2c_registers/i2c_registers.ino @@ -0,0 +1,38 @@ +#include +#include + +#define I2C_ADDRESS 0x60 +Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS); + + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("I2C device register test"); + + if (!i2c_dev.begin()) { + Serial.print("Did not find device at 0x"); + Serial.println(i2c_dev.address(), HEX); + while (1); + } + Serial.print("Device found on address 0x"); + Serial.println(i2c_dev.address(), HEX); + + Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST); + uint16_t id; + id_reg.read(&id); + Serial.print("ID register = 0x"); Serial.println(id, HEX); + + Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST); + uint16_t thresh; + thresh_reg.read(&thresh); + Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX); + + thresh_reg.write(~thresh); + + Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX); +} + +void loop() { + +} \ No newline at end of file diff --git a/lib/Adafruit_BusIO/examples/i2corspi_register/i2corspi_register.ino b/lib/Adafruit_BusIO/examples/i2corspi_register/i2corspi_register.ino new file mode 100644 index 000000000..555cf3b0d --- /dev/null +++ b/lib/Adafruit_BusIO/examples/i2corspi_register/i2corspi_register.ino @@ -0,0 +1,38 @@ +#include + +// Define which interface to use by setting the unused interface to NULL! + +#define SPIDEVICE_CS 10 +Adafruit_SPIDevice *spi_dev = NULL; // new Adafruit_SPIDevice(SPIDEVICE_CS); + +#define I2C_ADDRESS 0x5D +Adafruit_I2CDevice *i2c_dev = new Adafruit_I2CDevice(I2C_ADDRESS); + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("I2C or SPI device register test"); + + if (spi_dev && !spi_dev->begin()) { + Serial.println("Could not initialize SPI device"); + } + + if (i2c_dev) { + if (i2c_dev->begin()) { + Serial.print("Device found on I2C address 0x"); + Serial.println(i2c_dev->address(), HEX); + } else { + Serial.print("Did not find I2C device at 0x"); + Serial.println(i2c_dev->address(), HEX); + } + } + + Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F); + uint8_t id; + id_reg.read(&id); + Serial.print("ID register = 0x"); Serial.println(id, HEX); +} + +void loop() { + +} \ No newline at end of file diff --git a/lib/Adafruit_BusIO/examples/spi_modetest/spi_modetest.ino b/lib/Adafruit_BusIO/examples/spi_modetest/spi_modetest.ino new file mode 100644 index 000000000..10168c5ff --- /dev/null +++ b/lib/Adafruit_BusIO/examples/spi_modetest/spi_modetest.ino @@ -0,0 +1,29 @@ +#include + +#define SPIDEVICE_CS 10 +Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1); +//Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1); + + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("SPI device mode test"); + + if (!spi_dev.begin()) { + Serial.println("Could not initialize SPI device"); + while (1); + } +} + +void loop() { + Serial.println("\n\nTransfer test"); + for (uint16_t x=0; x<=0xFF; x++) { + uint8_t i = x; + Serial.print("0x"); Serial.print(i, HEX); + spi_dev.read(&i, 1, i); + Serial.print("/"); Serial.print(i, HEX); + Serial.print(", "); + delay(25); + } +} \ No newline at end of file diff --git a/lib/Adafruit_BusIO/examples/spi_readwrite/spi_readwrite.ino b/lib/Adafruit_BusIO/examples/spi_readwrite/spi_readwrite.ino new file mode 100644 index 000000000..6f2c063f0 --- /dev/null +++ b/lib/Adafruit_BusIO/examples/spi_readwrite/spi_readwrite.ino @@ -0,0 +1,39 @@ +#include + +#define SPIDEVICE_CS 10 +Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS); + + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("SPI device read and write test"); + + if (!spi_dev.begin()) { + Serial.println("Could not initialize SPI device"); + while (1); + } + + uint8_t buffer[32]; + + // Try to read 32 bytes + spi_dev.read(buffer, 32); + Serial.print("Read: "); + for (uint8_t i=0; i<32; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); + + // read a register by writing first, then reading + buffer[0] = 0x8F; // we'll reuse the same buffer + spi_dev.write_then_read(buffer, 1, buffer, 2, false); + Serial.print("Write then Read: "); + for (uint8_t i=0; i<2; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); +} + +void loop() { + +} diff --git a/lib/Adafruit_BusIO/examples/spi_registers/spi_registers.ino b/lib/Adafruit_BusIO/examples/spi_registers/spi_registers.ino new file mode 100644 index 000000000..e24f1aa9a --- /dev/null +++ b/lib/Adafruit_BusIO/examples/spi_registers/spi_registers.ino @@ -0,0 +1,34 @@ +#include +#include + +#define SPIDEVICE_CS 10 +Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS); + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("SPI device register test"); + + if (!spi_dev.begin()) { + Serial.println("Could not initialize SPI device"); + while (1); + } + + Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD); + uint8_t id; + id_reg.read(&id); + Serial.print("ID register = 0x"); Serial.println(id, HEX); + + Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST); + uint16_t thresh; + thresh_reg.read(&thresh); + Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX); + + thresh_reg.write(~thresh); + + Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX); +} + +void loop() { + +} \ No newline at end of file diff --git a/lib/Adafruit_BusIO/library.properties b/lib/Adafruit_BusIO/library.properties new file mode 100644 index 000000000..f63425a7d --- /dev/null +++ b/lib/Adafruit_BusIO/library.properties @@ -0,0 +1,9 @@ +name=Adafruit BusIO +version=1.0.10 +author=Adafruit +maintainer=Adafruit +sentence=This is a library for abstracting away UART, I2C and SPI interfacing +paragraph=This is a library for abstracting away UART, I2C and SPI interfacing +category=Signal Input/Output +url=https://github.com/adafruit/Adafruit_BusIO +architectures=* diff --git a/lib/Adafruit_VEML7700/.github/ISSUE_TEMPLATE.md b/lib/Adafruit_VEML7700/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..f0e26146f --- /dev/null +++ b/lib/Adafruit_VEML7700/.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_VEML7700/.github/PULL_REQUEST_TEMPLATE.md b/lib/Adafruit_VEML7700/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..7b641eb86 --- /dev/null +++ b/lib/Adafruit_VEML7700/.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_VEML7700/.gitignore b/lib/Adafruit_VEML7700/.gitignore new file mode 100644 index 000000000..542d266a9 --- /dev/null +++ b/lib/Adafruit_VEML7700/.gitignore @@ -0,0 +1,8 @@ +# osx +.DS_Store + +# doxygen +Doxyfile* +doxygen_sqlite3.db +html +*.tmp diff --git a/lib/Adafruit_VEML7700/.travis.yml b/lib/Adafruit_VEML7700/.travis.yml new file mode 100644 index 000000000..b967e9a08 --- /dev/null +++ b/lib/Adafruit_VEML7700/.travis.yml @@ -0,0 +1,26 @@ +language: c +sudo: false +cache: + directories: + - ~/arduino_ide + - ~/.arduino15/packages/ +git: + depth: false + quiet: true +env: + global: + - PRETTYNAME="Adafruit VEML7700 Arduino Library" + +before_install: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh) + +install: + - arduino --install-library "Adafruit BusIO" + +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_VEML7700/Adafruit_VEML7700.cpp b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp new file mode 100644 index 000000000..001d4995e --- /dev/null +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp @@ -0,0 +1,322 @@ +/*! + * @file Adafruit_VEML7700.cpp + * + * @mainpage Adafruit VEML7700 I2C Lux Sensor + * + * @section intro_sec Introduction + * + * I2C Driver for the VEML7700 I2C Lux sensor + * + * This is a library for the Adafruit VEML7700 breakout: + * http://www.adafruit.com/ + * + * 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 + * + * Limor Fried (Adafruit Industries) + * + * @section license License + * + * BSD (see license.txt) + * + * @section HISTORY + * + * v1.0 - First release + */ + +#include "Arduino.h" +#include + +#include "Adafruit_VEML7700.h" + +/*! + * @brief Instantiates a new VEML7700 class + */ +Adafruit_VEML7700::Adafruit_VEML7700(void) {} + +/*! + * @brief Setups the hardware for talking to the VEML7700 + * @param theWire An optional pointer to an I2C interface + * @return True if initialization was successful, otherwise false. + */ +boolean Adafruit_VEML7700::begin(TwoWire *theWire) { + i2c_dev = new Adafruit_I2CDevice(VEML7700_I2CADDR_DEFAULT, theWire); + + if (!i2c_dev->begin()) { + return false; + } + + ALS_Config = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_CONFIG, 2, LSBFIRST); + ALS_HighThreshold = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_THREHOLD_HIGH, 2, LSBFIRST); + ALS_LowThreshold = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_THREHOLD_LOW, 2, LSBFIRST); + Power_Saving = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_POWER_SAVE, 2, LSBFIRST); + ALS_Data = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_DATA, 2, LSBFIRST); + White_Data = new Adafruit_I2CRegister(i2c_dev, VEML7700_WHITE_DATA, 2, LSBFIRST); + Interrupt_Status = new Adafruit_I2CRegister(i2c_dev, VEML7700_INTERRUPTSTATUS, 2, LSBFIRST); + + ALS_Shutdown = new Adafruit_I2CRegisterBits(ALS_Config, 1, 0); // # bits, bit_shift + ALS_Interrupt_Enable = new Adafruit_I2CRegisterBits(ALS_Config, 1, 1); + ALS_Persistence = new Adafruit_I2CRegisterBits(ALS_Config, 2, 4); + ALS_Integration_Time = new Adafruit_I2CRegisterBits(ALS_Config, 4, 6); + ALS_Gain = new Adafruit_I2CRegisterBits(ALS_Config, 2, 11); + PowerSave_Enable = new Adafruit_I2CRegisterBits(Power_Saving, 1, 0); + PowerSave_Mode = new Adafruit_I2CRegisterBits(Power_Saving, 2, 1); + + enable(false); + interruptEnable(false); + setPersistence(VEML7700_PERS_1); + setGain(VEML7700_GAIN_1); + setIntegrationTime(VEML7700_IT_100MS); + powerSaveEnable(false); + enable(true); + + return true; +} + + +float Adafruit_VEML7700::normalize_resolution(float value) { + // adjust for gain (1x is normalized) + switch (getGain()) { + case VEML7700_GAIN_2: + value /= 2.0; break; + case VEML7700_GAIN_1_4: + value *= 4; break; + case VEML7700_GAIN_1_8: + value *= 8; break; + } + + // adjust for integrationtime (100ms is normalized) + switch (getIntegrationTime()) { + case VEML7700_IT_25MS: + value *= 4; break; + case VEML7700_IT_50MS: + value *= 2; break; + case VEML7700_IT_200MS: + value /= 2.0; break; + case VEML7700_IT_400MS: + value /= 4.0; break; + case VEML7700_IT_800MS: + value /= 8.0; break; + } + + return value; +} + +/*! + * @brief Read the calibrated lux value. See app note lux table on page 5 + * @returns Floating point Lux data (ALS multiplied by 0.0576) + */ +float Adafruit_VEML7700::readLux() { + return ( normalize_resolution(ALS_Data->read()) * 0.0576); // see app note lux table on page 5 +} + +/*! + * @brief Read the lux value with correction for non-linearity at high-lux settings + * @returns Floating point Lux data (ALS multiplied by 0.0576 and corrected for high-lux settings) + */ +float Adafruit_VEML7700::readLuxNormalized() { + float lux = readLux(); + + // user-provided correction for non-linearities at high lux/white values: + // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 + if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ + lux = 6.0135e-13*pow(lux,4) - 9.3924e-9*pow(lux,3) + 8.1488e-5*pow(lux,2) + 1.0023*lux; + } + + return lux; +} + +/*! + * @brief Read the raw ALS data + * @returns 16-bit data value from the ALS register + */ +uint16_t Adafruit_VEML7700::readALS() { + return ALS_Data->read(); +} + +/*! + * @brief Read the white light data + * @returns Floating point 'white light' data multiplied by 0.0576 + */ +float Adafruit_VEML7700::readWhite() { + // white_corrected= 2E-15*pow(VEML_white,4) + 4E-12*pow(VEML_white,3) + 9E-06*pow(VEML_white,)2 + 1.0179*VEML_white - 11.052; + return normalize_resolution(White_Data->read()) * 0.0576; // Unclear if this is the right multiplier +} + +/*! + * @brief Read the 'white light' value with correction for non-linearity at high-lux settings + * @returns Floating point 'white light' data multiplied by 0.0576 and corrected for high-lux settings + */ +float Adafruit_VEML7700::readWhiteNormalized() { + float white = readWhite(); + + // user-provided correction for non-linearities at high lux values: + // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 + if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ + white = 2E-15*pow(white,4) + 4E-12*pow(white,3) + 9E-06*pow(white,2) + 1.0179*white - 11.052; + } + + return white; +} + +/*! + * @brief Enable or disable the sensor + * @param enable The flag to enable/disable + */ +void Adafruit_VEML7700::enable(bool enable) { + ALS_Shutdown->write(!enable); +} + +/*! + * @brief Ask if the interrupt is enabled + * @returns True if enabled, false otherwise + */ +bool Adafruit_VEML7700::enabled(void) { + return !ALS_Shutdown->read(); +} + +/*! + * @brief Enable or disable the interrupt + * @param enable The flag to enable/disable + */ +void Adafruit_VEML7700::interruptEnable(bool enable) { + ALS_Interrupt_Enable->write(enable); +} + + +/*! + * @brief Ask if the interrupt is enabled + * @returns True if enabled, false otherwise + */ +bool Adafruit_VEML7700::interruptEnabled(void) { + return ALS_Interrupt_Enable->read(); +} + + +/*! + * @brief Set the ALS IRQ persistance setting + * @param pers Persistance constant, can be VEML7700_PERS_1, VEML7700_PERS_2, + * VEML7700_PERS_4 or VEML7700_PERS_8 + */ +void Adafruit_VEML7700::setPersistence(uint8_t pers) { + ALS_Persistence->write(pers); +} + +/*! + * @brief Get the ALS IRQ persistance setting + * @returns Persistance constant, can be VEML7700_PERS_1, VEML7700_PERS_2, + * VEML7700_PERS_4 or VEML7700_PERS_8 + */ +uint8_t Adafruit_VEML7700::getPersistence(void) { + return ALS_Persistence->read(); +} + +/*! + * @brief Set ALS integration time + * @param it Can be VEML7700_IT_100MS, VEML7700_IT_200MS, VEML7700_IT_400MS, + * VEML7700_IT_800MS, VEML7700_IT_50MS or VEML7700_IT_25MS + */ +void Adafruit_VEML7700::setIntegrationTime(uint8_t it) { + ALS_Integration_Time->write(it); +} + +/*! + * @brief Get ALS integration time + * @returns IT index, can be VEML7700_IT_100MS, VEML7700_IT_200MS, VEML7700_IT_400MS, + * VEML7700_IT_800MS, VEML7700_IT_50MS or VEML7700_IT_25MS + */ +uint8_t Adafruit_VEML7700::getIntegrationTime(void) { + return ALS_Integration_Time->read(); +} + +/*! + * @brief Set ALS gain + * @param gain Can be VEML7700_GAIN_1, VEML7700_GAIN_2, VEML7700_GAIN_1_8 or VEML7700_GAIN_1_4 + */ +void Adafruit_VEML7700::setGain(uint8_t gain) { + ALS_Gain->write(gain); +} + +/*! + * @brief Get ALS gain + * @returns Gain index, can be VEML7700_GAIN_1, VEML7700_GAIN_2, VEML7700_GAIN_1_8 or VEML7700_GAIN_1_4 + */ +uint8_t Adafruit_VEML7700::getGain(void) { + return ALS_Gain->read(); +} + + +/*! + * @brief Enable power save mode + * @param enable True if power save should be enabled + */ +void Adafruit_VEML7700::powerSaveEnable(bool enable) { + PowerSave_Enable->write(enable); +} + +/*! + * @brief Check if power save mode is enabled + * @returns True if power save is enabled + */ +bool Adafruit_VEML7700::powerSaveEnabled(void) { + return PowerSave_Enable->read(); +} + +/*! + * @brief Assign the power save register data + * @param mode The 16-bit data to write to VEML7700_ALS_POWER_SAVE + */ +void Adafruit_VEML7700::setPowerSaveMode(uint8_t mode) { + PowerSave_Mode->write(mode); +} + +/*! + * @brief Retrieve the power save register data + * @return 16-bit data from VEML7700_ALS_POWER_SAVE + */ +uint8_t Adafruit_VEML7700::getPowerSaveMode(void) { + return PowerSave_Mode->read(); +} + +/*! + * @brief Assign the low threshold register data + * @param value The 16-bit data to write to VEML7700_ALS_THREHOLD_LOW + */ +void Adafruit_VEML7700::setLowThreshold(uint16_t value) { + ALS_LowThreshold->write(value); +} + +/*! + * @brief Retrieve the low threshold register data + * @return 16-bit data from VEML7700_ALS_THREHOLD_LOW + */ +uint16_t Adafruit_VEML7700::getLowThreshold(void) { + return ALS_LowThreshold->read(); +} + +/*! + * @brief Assign the high threshold register data + * @param value The 16-bit data to write to VEML7700_ALS_THREHOLD_HIGH + */ +void Adafruit_VEML7700::setHighThreshold(uint16_t value) { + ALS_HighThreshold->write(value); +} + +/*! + * @brief Retrieve the high threshold register data + * @return 16-bit data from VEML7700_ALS_THREHOLD_HIGH + */ +uint16_t Adafruit_VEML7700::getHighThreshold(void) { + return ALS_HighThreshold->read(); +} + +/*! + * @brief Retrieve the interrupt status register data + * @return 16-bit data from VEML7700_INTERRUPTSTATUS + */ +uint16_t Adafruit_VEML7700::interruptStatus(void) { + return Interrupt_Status->read(); +} diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h new file mode 100644 index 000000000..b842a7bc1 --- /dev/null +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h @@ -0,0 +1,113 @@ +/*! + * @file Adafruit_VEML7700.h + * + * I2C Driver for VEML7700 Lux sensor + * + * This is a library for the Adafruit VEML7700 breakout: + * http://www.adafruit.com/ + * + * Adafruit invests time and resources providing this open source code, + *please support Adafruit and open-source hardware by purchasing products from + * Adafruit! + * + * + * BSD license (see license.txt) + */ + +#ifndef _ADAFRUIT_VEML7700_H +#define _ADAFRUIT_VEML7700_H + +#include "Arduino.h" +#include +#include +#include + +#define VEML7700_I2CADDR_DEFAULT 0x10 ///< I2C address + +#define VEML7700_ALS_CONFIG 0x00 ///< Light configuration register +#define VEML7700_ALS_THREHOLD_HIGH 0x01 ///< Light high threshold for irq +#define VEML7700_ALS_THREHOLD_LOW 0x02 ///< Light low threshold for irq +#define VEML7700_ALS_POWER_SAVE 0x03 ///< Power save regiester +#define VEML7700_ALS_DATA 0x04 ///< The light data output +#define VEML7700_WHITE_DATA 0x05 ///< The white light data output +#define VEML7700_INTERRUPTSTATUS 0x06 ///< What IRQ (if any) + +#define VEML7700_INTERRUPT_HIGH 0x4000 ///< Interrupt status for high threshold +#define VEML7700_INTERRUPT_LOW 0x8000 ///< Interrupt status for low threshold + +#define VEML7700_GAIN_1 0x00 ///< ALS gain 1x +#define VEML7700_GAIN_2 0x01 ///< ALS gain 2x +#define VEML7700_GAIN_1_8 0x02 ///< ALS gain 1/8x +#define VEML7700_GAIN_1_4 0x03 ///< ALS gain 1/4x + +#define VEML7700_IT_100MS 0x00 ///< ALS intetgration time 100ms +#define VEML7700_IT_200MS 0x01 ///< ALS intetgration time 200ms +#define VEML7700_IT_400MS 0x02 ///< ALS intetgration time 400ms +#define VEML7700_IT_800MS 0x03 ///< ALS intetgration time 800ms +#define VEML7700_IT_50MS 0x08 ///< ALS intetgration time 50ms +#define VEML7700_IT_25MS 0x0C ///< ALS intetgration time 25ms + +#define VEML7700_PERS_1 0x00 ///< ALS irq persisance 1 sample +#define VEML7700_PERS_2 0x01 ///< ALS irq persisance 2 samples +#define VEML7700_PERS_4 0x02 ///< ALS irq persisance 4 samples +#define VEML7700_PERS_8 0x03 ///< ALS irq persisance 8 samples + +#define VEML7700_POWERSAVE_MODE1 0x00 ///< Power saving mode 1 +#define VEML7700_POWERSAVE_MODE2 0x01 ///< Power saving mode 2 +#define VEML7700_POWERSAVE_MODE3 0x02 ///< Power saving mode 3 +#define VEML7700_POWERSAVE_MODE4 0x03 ///< Power saving mode 4 + + +/*! + * @brief Class that stores state and functions for interacting with + * VEML7700 Temp Sensor + */ +class Adafruit_VEML7700 { +public: + Adafruit_VEML7700(); + boolean begin(TwoWire *theWire = &Wire); + + void enable(bool enable); + bool enabled(void); + + void interruptEnable(bool enable); + bool interruptEnabled(void); + void setPersistence(uint8_t pers); + uint8_t getPersistence(void); + void setIntegrationTime(uint8_t it); + uint8_t getIntegrationTime(void); + void setGain(uint8_t gain); + uint8_t getGain(void); + void powerSaveEnable(bool enable); + bool powerSaveEnabled(void); + void setPowerSaveMode(uint8_t mode); + uint8_t getPowerSaveMode(void); + + void setLowThreshold(uint16_t value); + uint16_t getLowThreshold(void); + void setHighThreshold(uint16_t value); + uint16_t getHighThreshold(void); + uint16_t interruptStatus(void); + + + float readLux(); + float readLuxNormalized(); + + uint16_t readALS(); + float readWhite(); + float readWhiteNormalized(); + +private: + Adafruit_I2CRegister *ALS_Config, *ALS_Data, *White_Data, + *ALS_HighThreshold, *ALS_LowThreshold, *Power_Saving, *Interrupt_Status; + Adafruit_I2CRegisterBits *ALS_Shutdown, *ALS_Interrupt_Enable, + *ALS_Persistence, *ALS_Integration_Time, *ALS_Gain, + *PowerSave_Enable, *PowerSave_Mode; + + float normalize_resolution(float value); + + Adafruit_I2CDevice *i2c_dev; + +}; + +#endif diff --git a/lib/Adafruit_VEML7700/README.md b/lib/Adafruit_VEML7700/README.md new file mode 100644 index 000000000..fe3f3c898 --- /dev/null +++ b/lib/Adafruit_VEML7700/README.md @@ -0,0 +1,16 @@ +Adafruit_VEML7700 [![Build Status](https://travis-ci.com/adafruit/Adafruit_VEML7700.svg?branch=master)](https://travis-ci.com/adafruit/Adafruit_VEML7700) +================ + +This is the Adafruit VEML7700 Lux sensor library + +Tested and works great with the [Adafruit VEML7700 Breakout Board](http://www.adafruit.com/) + +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 Kevin Townsend/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_VEML7700/examples/veml7700_test/veml7700_test.ino b/lib/Adafruit_VEML7700/examples/veml7700_test/veml7700_test.ino new file mode 100644 index 000000000..64718112d --- /dev/null +++ b/lib/Adafruit_VEML7700/examples/veml7700_test/veml7700_test.ino @@ -0,0 +1,58 @@ +#include "Adafruit_VEML7700.h" + +Adafruit_VEML7700 veml = Adafruit_VEML7700(); + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("Adafruit VEML7700 Test"); + + if (!veml.begin()) { + Serial.println("Sensor not found"); + while (1); + } + Serial.println("Sensor found"); + + veml.setGain(VEML7700_GAIN_1); + veml.setIntegrationTime(VEML7700_IT_800MS); + + Serial.print(F("Gain: ")); + switch (veml.getGain()) { + case VEML7700_GAIN_1: Serial.println("1"); break; + case VEML7700_GAIN_2: Serial.println("2"); break; + case VEML7700_GAIN_1_4: Serial.println("1/4"); break; + case VEML7700_GAIN_1_8: Serial.println("1/8"); break; + } + + Serial.print(F("Integration Time (ms): ")); + switch (veml.getIntegrationTime()) { + case VEML7700_IT_25MS: Serial.println("25"); break; + case VEML7700_IT_50MS: Serial.println("50"); break; + case VEML7700_IT_100MS: Serial.println("100"); break; + case VEML7700_IT_200MS: Serial.println("200"); break; + case VEML7700_IT_400MS: Serial.println("400"); break; + case VEML7700_IT_800MS: Serial.println("800"); break; + } + + //veml.powerSaveEnable(true); + //veml.setPowerSaveMode(VEML7700_POWERSAVE_MODE4); + + veml.setLowThreshold(10000); + veml.setHighThreshold(20000); + veml.interruptEnable(true); +} + +void loop() { + Serial.print("Lux: "); Serial.println(veml.readLux()); + Serial.print("White: "); Serial.println(veml.readWhite()); + Serial.print("Raw ALS: "); Serial.println(veml.readALS()); + + uint16_t irq = veml.interruptStatus(); + if (irq & VEML7700_INTERRUPT_LOW) { + Serial.println("** Low threshold"); + } + if (irq & VEML7700_INTERRUPT_HIGH) { + Serial.println("** High threshold"); + } + delay(500); +} diff --git a/lib/Adafruit_VEML7700/library.properties b/lib/Adafruit_VEML7700/library.properties new file mode 100644 index 000000000..754bd2fd7 --- /dev/null +++ b/lib/Adafruit_VEML7700/library.properties @@ -0,0 +1,9 @@ +name=Adafruit VEML7700 Library +version=1.0.0 +author=Adafruit +maintainer=Adafruit +sentence=Arduino library for the VEML7700 sensors in the Adafruit shop +paragraph=Arduino library for the VEML7700 sensors in the Adafruit shop +category=Sensors +url=https://github.com/adafruit/Adafruit_VEML7700 +architectures=* diff --git a/lib/Adafruit_VEML7700/license.txt b/lib/Adafruit_VEML7700/license.txt new file mode 100644 index 000000000..f6a0f22b8 --- /dev/null +++ b/lib/Adafruit_VEML7700/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/tasmota/i18n.h b/tasmota/i18n.h index 089a9b55f..6e7910ca5 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -585,6 +585,16 @@ // Commands xsns_02_analog.ino #define D_CMND_ADCPARAM "AdcParam" +// xsns_70_veml6075.ino +#define D_JSON_UVA_INTENSITY "UvaIntensity" +#define D_JSON_UVB_INTENSITY "UvbItensity" +#define D_CMND_VEML6075_POWER "power" +#define D_CMND_VEML6075_DYNAMIC "dynamic" +#define D_CMND_VEML6075_INTTIME "inttime" + +// xsns_71_veml7700.ino +#define D_JSON_WHITE_CONTENT "WhiteContent" + /********************************************************************************************/ // Log message prefix diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 150a200e0..2547e8527 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -516,6 +516,8 @@ // #define USE_HDC1080 // [I2cDriver45] Enable HDC1080 temperature/humidity sensor (I2C address 0x40) (+1k5 code) // #define USE_IAQ // [I2cDriver46] Enable iAQ-core air quality sensor (I2C address 0x5a) (+0k6 code) // #define USE_AS3935 // [I2cDriver48] Enable AS3935 Franklin Lightning Sensor (I2C address 0x03) (+5k4 code) +// #define USE_VEML6075 // [I2cDriver49] Enable VEML6075 UVA/UVB/UVINDEX Sensor (I2C address 0x10) (+2k1 code) +// #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code) // #define USE_DISPLAY // Add I2C Display Support (+2k code) #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0 diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 02a04a962..ef757e5b6 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -563,10 +563,13 @@ void GetFeatures(void) #ifdef USE_THERMOSTAT feature6 |= 0x00000400; // xdrv_39_heating.ino #endif +#ifdef USE_VEML6075 + feature6 |= 0x00000800; // xsns_70_veml6075.ino +#endif +#ifdef USE_VEML7700 + feature6 |= 0x00001000; // xsns_71_veml7700.ino +#endif -// feature6 |= 0x00000800; - -// feature6 |= 0x00001000; // feature6 |= 0x00002000; // feature6 |= 0x00004000; // feature6 |= 0x00008000; diff --git a/tasmota/xsns_70_veml6075.ino b/tasmota/xsns_70_veml6075.ino new file mode 100644 index 000000000..00a8ebc8e --- /dev/null +++ b/tasmota/xsns_70_veml6075.ino @@ -0,0 +1,306 @@ +/* + xsns_70_veml6075.ino - VEML6075 Franklin Lightning Sensor support for Tasmota + + Copyright (C) 2020 Martin Wagner + + 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_VEML6075 +/*********************************************************************************************\ + * VEML6075 UVA/UVB/UVINDEX Sensor + * + * I2C Address: 0x10 +\*********************************************************************************************/ + +#define XSNS_70 70 +#define XI2C_49 49 // See I2CDEVICES.md + + +#define VEML6075_ADDR 0x10 // I2C address +#define VEML6075_CHIP_ID 0x26 // Manufacture ID + +// I2C register +#define VEML6075_REG_CONF 0x00 // Configuration register +#define VEML6075_REG_UVA 0x07 // UVA band raw measurement +#define VEML6075_REG_DARK 0x08 // Dark current (?) measurement +#define VEML6075_REG_UVB 0x09 // UVB band raw measurement +#define VEML6075_REG_UVCOMP1 0x0A // UV1 compensation value +#define VEML6075_REG_UVCOMP2 0x0B // UV2 compensation value +#define VEML6075_REG_ID 0x0C // ID Register + +// global constants for Calc +#define VEML6075_DEFAULT_UVA_A_COEFF 2.22 // Default for no coverglass +#define VEML6075_DEFAULT_UVA_B_COEFF 1.33 // Default for no coverglass +#define VEML6075_DEFAULT_UVB_C_COEFF 2.95 // Default for no coverglass +#define VEML6075_DEFAULT_UVB_D_COEFF 1.74 // Default for no coverglass +#define UVA_RESPONSIVITY_100MS_UNCOVERED 0.001461 // Default for no coverglass +#define UVB_RESPONSIVITY_100MS_UNCOVERED 0.002591 // Default for no coverglass + +const float UVA_RESPONSIVITY[] PROGMEM = +{ + UVA_RESPONSIVITY_100MS_UNCOVERED / 0.5016286645, // 50ms + UVA_RESPONSIVITY_100MS_UNCOVERED, // 100ms + UVA_RESPONSIVITY_100MS_UNCOVERED / 2.039087948, // 200ms + UVA_RESPONSIVITY_100MS_UNCOVERED / 3.781758958, // 400ms + UVA_RESPONSIVITY_100MS_UNCOVERED / 7.371335505 // 800ms +}; + +const float UVB_RESPONSIVITY[] PROGMEM = +{ + UVB_RESPONSIVITY_100MS_UNCOVERED / 0.5016286645, // 50ms + UVB_RESPONSIVITY_100MS_UNCOVERED, // 100ms + UVB_RESPONSIVITY_100MS_UNCOVERED / 2.039087948, // 200ms + UVB_RESPONSIVITY_100MS_UNCOVERED / 3.781758958, // 400ms + UVB_RESPONSIVITY_100MS_UNCOVERED / 7.371335505 // 800ms +}; + +// http and json defines +#define D_NAME_VEML6075 "VEML6075" +#define D_UVA_INTENSITY "UVA intensity" +#define D_UVB_INTENSITY "UVB intensity" + +const char HTTP_SNS_UVA[] PROGMEM = "{s}%s " D_UVA_INTENSITY "{m}%d " D_UNIT_WATT_METER_QUADRAT "{e}"; +const char HTTP_SNS_UVB[] PROGMEM = "{s}%s " D_UVB_INTENSITY "{m}%d " D_UNIT_WATT_METER_QUADRAT "{e}"; +const char HTTP_SNS_UVINDEX[] PROGMEM = "{s}%s " D_UV_INDEX "{m}%s {e}"; +const char JSON_SNS_VEML6075[] PROGMEM = ",\"%s\":{\"" D_JSON_UVA_INTENSITY "\":%d,\"" D_JSON_UVB_INTENSITY "\":%d,\"" D_JSON_UV_INDEX "\":%s}"; +const char S_JSON_VEML6075_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_VEML6075 "\":{\"%s\":%d}}"; + +const char kVEML6075_Commands[] PROGMEM = D_CMND_VEML6075_POWER "|" D_CMND_VEML6075_DYNAMIC "|" D_CMND_VEML6075_INTTIME; + +enum VEML6075_Commands { // commands for Console + CMND_VEML6075_PWR, + CMND_VEML6075_SET_HD, + CMND_VEML6075_SET_UVIT, + }; + +// global variables +struct VEML6075STRUCT +{ + char types[9] = D_NAME_VEML6075; + uint8_t address = VEML6075_ADDR; + uint8_t inttime = 0; + uint16_t uva = 0; + uint16_t uvb = 0; + uint16_t uva_raw = 0; + uint16_t uvb_raw = 0; + uint16_t comp1 = 0; + uint16_t comp2 = 0; + uint16_t conf = 0; + float uvi = 0.0f; +} veml6075_sensor; + +uint8_t veml6075_active = 0; + +// typedef of config register +typedef union { + struct { + uint8_t pwr:1; // Shut Down + uint8_t forded_auto:1; // Auto or forced + uint8_t forced_trigger:1; // Trigger forced mode + uint8_t hd:1; // High dynamic + uint8_t inttime:3; // Integration Time + uint8_t spare7:1; // spare + }; + uint16_t config; +} veml6075configRegister; + +veml6075configRegister veml6075Config; + +/********************************************************************************************/ + +uint16_t VEML6075read16 (uint8_t reg) { + uint16_t swap = I2cRead16(VEML6075_ADDR, reg); + uint16_t ret = ((swap & 0xFF) << 8) | (swap >> 8); + return ret; +} + +void VEML6075write16 (uint8_t reg, uint16_t val) { + uint16_t swap = ((val & 0xFF) << 8) | (val >> 8); + I2cWrite16(VEML6075_ADDR, reg, swap); +} + +float VEML6075calcUVA (void) { + float uva_calc = veml6075_sensor.uva_raw - (VEML6075_DEFAULT_UVA_A_COEFF * veml6075_sensor.comp1) - (VEML6075_DEFAULT_UVA_B_COEFF * veml6075_sensor.comp2); + return uva_calc; +} + +float VEML6075calcUVB (void) { + float uvb_calc = veml6075_sensor.uvb_raw - (VEML6075_DEFAULT_UVB_C_COEFF * veml6075_sensor.comp1) - (VEML6075_DEFAULT_UVB_D_COEFF * veml6075_sensor.comp2); + return uvb_calc; +} + +float VEML6075calcUVI (void) { + float uvi_calc = ((veml6075_sensor.uva * UVA_RESPONSIVITY[veml6075_sensor.inttime]) + (veml6075_sensor.uvb * UVB_RESPONSIVITY[veml6075_sensor.inttime])) / 2; + return uvi_calc; +} + +void VEML6075SetHD(uint8_t val){ + veml6075Config.hd = val; + VEML6075write16 (VEML6075_REG_CONF, veml6075Config.config); +} + +uint8_t VEML6075ReadHD(void){ + veml6075Config.config = VEML6075read16 (VEML6075_REG_CONF); + return veml6075Config.hd; +} + +void VEML6075SetUvIt(uint8_t val){ + veml6075Config.inttime = val; + VEML6075Pwr(1); + VEML6075write16 (VEML6075_REG_CONF, veml6075Config.config); + VEML6075Pwr(0); +} + +uint8_t VEML6075GetUvIt(void){ + veml6075Config.config = VEML6075read16 (VEML6075_REG_CONF); + return veml6075Config.inttime; +} + +void VEML6075Pwr(uint8_t val){ + veml6075Config.pwr = val; + VEML6075write16 (VEML6075_REG_CONF, veml6075Config.config); +} + +uint8_t VEML6075GetPwr(void){ + veml6075Config.config = VEML6075read16 (VEML6075_REG_CONF); + return veml6075Config.pwr; +} + +void VEML6075ReadData(void) +{ + veml6075_sensor.uva_raw = VEML6075read16 (VEML6075_REG_UVA); + veml6075_sensor.uvb_raw = VEML6075read16 (VEML6075_REG_UVB); + veml6075_sensor.comp1 = VEML6075read16 (VEML6075_REG_UVCOMP1); + veml6075_sensor.comp2 = VEML6075read16 (VEML6075_REG_UVCOMP2); + veml6075_sensor.inttime = VEML6075GetUvIt(); + veml6075_sensor.uva = VEML6075calcUVA(); + veml6075_sensor.uvb = VEML6075calcUVB(); + veml6075_sensor.uvi = VEML6075calcUVI(); +} + +bool VEML6075init(void) +{ + uint8_t id = VEML6075read16 (VEML6075_REG_ID); + if(id == VEML6075_CHIP_ID) // Sensor id + return true; + return false; +} + +void VEML6075Detect(void) { + if (I2cActive(veml6075_sensor.address)) return; + + if (VEML6075init()) { + I2cSetActiveFound(veml6075_sensor.address, veml6075_sensor.types); + VEML6075write16 (VEML6075_REG_CONF, 0x10); // set default + veml6075_active = 1; + } +} + +void VEML6075EverySecond(void) { + VEML6075ReadData(); +} + +bool VEML6075Cmd(void) { + char command[CMDSZ]; + uint8_t name_len = strlen(D_NAME_VEML6075); + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_VEML6075), name_len)) { + uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kVEML6075_Commands); + switch (command_code) { + case CMND_VEML6075_PWR: + if (XdrvMailbox.data_len) { + if (2 >= XdrvMailbox.payload) { + VEML6075Pwr(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML6075_COMMAND_NVALUE, command, VEML6075GetPwr()); + break; + case CMND_VEML6075_SET_HD: + if (XdrvMailbox.data_len) { + if (2 >= XdrvMailbox.payload) { + VEML6075SetHD(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML6075_COMMAND_NVALUE, command, VEML6075ReadHD()); + break; + case CMND_VEML6075_SET_UVIT: + if (XdrvMailbox.data_len) { + if (4 >= XdrvMailbox.payload) { + VEML6075SetUvIt(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML6075_COMMAND_NVALUE, command, VEML6075GetUvIt()); + break; + default: + return false; + } + return true; + } else { + return false; + } +} + +void VEML6075Show(bool json) +{ + char s_uvindex[FLOATSZ]; + dtostrfd(veml6075_sensor.uvi,1, s_uvindex); + + if (json) { + ResponseAppend_P(JSON_SNS_VEML6075, D_NAME_VEML6075, veml6075_sensor.uva, veml6075_sensor.uvb, s_uvindex); +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_UVA, D_NAME_VEML6075, veml6075_sensor.uva); + WSContentSend_PD(HTTP_SNS_UVB, D_NAME_VEML6075, veml6075_sensor.uvb); + WSContentSend_PD(HTTP_SNS_UVINDEX, D_NAME_VEML6075 ,s_uvindex); +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns70(uint8_t function) +{ + if (!I2cEnabled(XI2C_49)) { return false; } + + bool result = false; + + if (FUNC_INIT == function) { + VEML6075Detect(); + } + else if (veml6075_active) { + switch (function) { + case FUNC_EVERY_SECOND: + VEML6075EverySecond(); + break; + case FUNC_COMMAND: + result = VEML6075Cmd(); + break; + case FUNC_JSON_APPEND: + VEML6075Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + VEML6075Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_VEML6075 +#endif // USE_I2C diff --git a/tasmota/xsns_71_veml7700.ino b/tasmota/xsns_71_veml7700.ino new file mode 100644 index 000000000..89bae9320 --- /dev/null +++ b/tasmota/xsns_71_veml7700.ino @@ -0,0 +1,117 @@ +/* + xsns_71_VEML7700.ino - VEML7700 Franklin Lightning Sensor support for Tasmota + + Copyright (C) 2020 Martin Wagner + + 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_VEML7700 +/*********************************************************************************************\ + * VEML7700 ALS Sensor + * Using the Adafruit VEML7700 Libary + * I2C Address: 0x10 +\*********************************************************************************************/ + +#define XSNS_71 71 +#define XI2C_50 50 // See I2CDEVICES.md + +#include "Adafruit_VEML7700.h" +Adafruit_VEML7700 veml7700 = Adafruit_VEML7700(); //create object copy + +#define D_NAME_VEML7700 "VEML7700" +#define D_WHITE_CONTENT "White content" + +const char HTTP_SNS_LUX[] PROGMEM = "{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX " {e}"; +const char HTTP_SNS_WHITE[] PROGMEM = "{s}%s " D_WHITE_CONTENT "{m}%d {e}"; +const char JSON_SNS_VEML7700[] PROGMEM = ",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d,\"" D_JSON_WHITE_CONTENT "\":%d}"; + +struct VEML7700STRUCT +{ + char types[9] = D_NAME_VEML7700; + uint8_t address = VEML7700_I2CADDR_DEFAULT; + uint16_t lux = 0; + uint16_t white = 0; +} veml7700_sensor; + +uint8_t veml7700_active = 0; + +/********************************************************************************************/ + +void VEML7700Detect(void) { + if (I2cActive(veml7700_sensor.address)) return; + if (veml7700.begin()) { + I2cSetActiveFound(veml7700_sensor.address, veml7700_sensor.types); + veml7700_active = 1; + } +} + +void VEML7700EverySecond(void) { + veml7700_sensor.lux = (uint16_t) veml7700.readLux(); + veml7700_sensor.white = (uint16_t) veml7700.readWhite(); +} + +void VEML7700Show(bool json) +{ + if (json) { + ResponseAppend_P(JSON_SNS_VEML7700, D_NAME_VEML7700, veml7700_sensor.lux, veml7700_sensor.white); + +#ifdef USE_DOMOTICZ + if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, veml7700_sensor.lux); +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_LUX, D_NAME_VEML7700, veml7700_sensor.lux); + WSContentSend_PD(HTTP_SNS_WHITE, D_NAME_VEML7700, veml7700_sensor.white); +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns71(uint8_t function) +{ + if (!I2cEnabled(XI2C_50)) { return false; } + + bool result = false; + + if (FUNC_INIT == function) { + VEML7700Detect(); + } + else if (veml7700_active) { + switch (function) { + case FUNC_EVERY_SECOND: + VEML7700EverySecond(); + break; + case FUNC_COMMAND: + //result = VEML7700Cmd(); + break; + case FUNC_JSON_APPEND: + VEML7700Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + VEML7700Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_VEML7700 +#endif // USE_I2C From 88136168bbef46a929178429a7dcf6e03287359b Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Wed, 13 May 2020 12:52:20 +0200 Subject: [PATCH 002/581] Update tasmota_configurations.h --- tasmota/tasmota_configurations.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 37ac20237..8ba54e60b 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -83,6 +83,8 @@ #define USE_BME680 // Add additional support for BME680 sensor using Bosch BME680 library (+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_VEML6075 // Add I2C code for VEML6075 UVA/UVB/UVINDEX Sensor (+2k1 code) +// #define USE_VEML7700 // Add I2C code for VEML7700 Ambient Light sensor (+4k5 code) #define USE_ADS1115 // Add I2C code for ADS1115 16 bit A/D converter based on Adafruit ADS1x15 library (no library needed) (+0k7 code) #define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code) //#define USE_INA226 // Enable INA226 (I2C address 0x40, 0x41 0x44 or 0x45) Low voltage and current sensor (+2k3 code) From f619834dde75be1dbda656fb4343c74473093b8f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 15 May 2020 17:34:47 +0200 Subject: [PATCH 003/581] Ignore all user_config_override* --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5baf6b919..5ebd0bd78 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ .clang_complete .gcc-flags.json .cache -tasmota/user_config_override.h +tasmota/user_config_override* build build_output firmware.map From 05c45f7ad735b290c98c3d00d5e48eb82c366a65 Mon Sep 17 00:00:00 2001 From: Johannes Morgenroth Date: Sat, 16 May 2020 18:05:23 +0200 Subject: [PATCH 004/581] Remove flush() call after read of KNX packets The flush() call after read() causes empty packets being sent as response for all UDP packets received on that port. --- lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp b/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp index 5917e62f3..96f4e1c73 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp @@ -536,7 +536,6 @@ void ESPKNXIP::__loop_knx() uint8_t buf[read]; udp.read(buf, read); - udp.flush(); DEBUG_PRINT(F("Got packet:")); From 6c99b89788029525a8ec37721cc5b599fc896882 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Mon, 18 May 2020 16:17:22 +0200 Subject: [PATCH 005/581] Italian language update --- tasmota/language/it_IT.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 5fa0d51dd..09dcc266b 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -97,9 +97,9 @@ #define D_FALSE "Falso" #define D_FILE "File" #define D_FLOW_RATE "Flusso dati" -#define D_FREE_MEMORY "Memoria Libera" -#define D_PSR_MAX_MEMORY "PS-RAM Memory" -#define D_PSR_FREE_MEMORY "PS-RAM free Memory" +#define D_FREE_MEMORY "Memoria libera" +#define D_PSR_MAX_MEMORY "PS-RAM - Memoria" +#define D_PSR_FREE_MEMORY "PS-RAM - Memoria libera" #define D_FREQUENCY "Frequenza" #define D_GAS "Gas" #define D_GATEWAY "Gateway" @@ -302,7 +302,7 @@ #define D_OTHER_PARAMETERS "Altri parametri" #define D_TEMPLATE "Modello" #define D_ACTIVATE "Attiva" -#define D_DEVICE_NAME "Device Name" +#define D_DEVICE_NAME "Nome dispositivo" #define D_WEB_ADMIN_PASSWORD "Password amministratore web" #define D_MQTT_ENABLE "Abilita MQTT" #define D_FRIENDLY_NAME "Nome amichevole" From d8d9e334f6bd6383ef327545a8defb85bc9d464b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 18 May 2020 17:02:24 +0200 Subject: [PATCH 006/581] Add ValidTemplate function --- tasmota/support.ino | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tasmota/support.ino b/tasmota/support.ino index db4c9c26e..271ad81fe 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1132,6 +1132,16 @@ bool ValidModule(uint32_t index) return ValidTemplateModule(index); } +bool ValidTemplate(const char *search) { + char template_name[strlen(SettingsText(SET_TEMPLATE_NAME)) +1]; + char search_name[strlen(search) +1]; + + LowerCase(template_name, SettingsText(SET_TEMPLATE_NAME)); + LowerCase(search_name, search); + + return (strstr(template_name, search_name) != nullptr); +} + String AnyModuleName(uint32_t index) { if (USER_MODULE == index) { From ebbdb28e4897eb420d92d85dad05584c70e78c3b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 18 May 2020 17:06:11 +0200 Subject: [PATCH 007/581] Bump version to 8.3.1.1 --- RELEASENOTES.md | 9 +-------- tasmota/CHANGELOG.md | 8 ++++++++ tasmota/tasmota_version.h | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b2b110300..c55146eaa 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,11 +52,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.3.0.2 - -- Change Hass discovery from using Template or Module name to new Device name (#8462) -- Change KNX pow function to approximative pow saving 5k of code space -- Change Mutichannel Gas sensor pow function to approximative pow saving 5k of code space -- Change Quick Power Cycle detection from 4 to 7 power interrupts (#4066) -- Fix default state of ``SetOption73 0`` for button decoupling and send multi-press and hold MQTT messages -- Add command ``DeviceName`` defaults to FriendlyName1 and replaces FriendlyName1 in GUI +### Version 8.3.1.1 diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index a2638dffa..d24578cc3 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,5 +1,13 @@ ## Unreleased (development) +### 8.3.1.1 20200518 + +## Released + +### 8.3.1 20200518 + +- Release Fred + ### 8.3.0.2 20200517 - Change Hass discovery from using template name to new Device name (#8462) diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index d9f248e55..af18e431f 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08030002; +const uint32_t VERSION = 0x08030101; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; From 016258e3636280c59aa8f27d68a4297324845280 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 18 May 2020 20:06:47 +0200 Subject: [PATCH 008/581] Prepare compile flags for Arduino patches in flight --- platformio.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platformio.ini b/platformio.ini index 8a22cf67e..c9eb6d5f4 100755 --- a/platformio.ini +++ b/platformio.ini @@ -111,6 +111,9 @@ build_flags = ${esp_defaults.build_flags} -lstdc++ ; the following removes the 4-bytes alignment for PSTR(), waiting for a cleaner flag from Arduino Core -DPSTR\(s\)=\(__extension__\(\{static\ const\ char\ __c\[\]\ __attribute__\(\(__aligned__\(1\)\)\)\ __attribute__\(\(section\(\ \"\\\\\".irom0.pstr.\"\ __FILE__\ \".\"\ __STRINGIZE\(__LINE__\)\ \".\"\ \ __STRINGIZE\(__COUNTER__\)\ \"\\\\\"\,\ \\\\\"aSM\\\\\"\,\ \@progbits\,\ 1\ \#\"\)\)\)\ =\ \(s\)\;\ \&__c\[0\]\;\}\)\) + -DPSTR_ALIGN=1 + ; restrict to minimal mime-types + -DMIMETYPE_MINIMAL [irremoteesp_full] build_flags = -DUSE_IR_REMOTE_FULL From e1fbf640379c902588486c1427e8825b9ace14a3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 19 May 2020 11:15:31 +0200 Subject: [PATCH 009/581] Add command ``Rule0`` Add command ``Rule0`` to change global rule parameters --- RELEASENOTES.md | 2 ++ tasmota/CHANGELOG.md | 2 ++ tasmota/support_command.ino | 4 ++-- tasmota/xdrv_10_rules.ino | 20 ++++++++++++++++++++ tasmota/xdrv_99_debug.ino | 5 +++-- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index c55146eaa..71041b5da 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -53,3 +53,5 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog ### Version 8.3.1.1 + +- Add command ``Rule0`` to change global rule parameters diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index d24578cc3..e9ec2176d 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -2,6 +2,8 @@ ### 8.3.1.1 20200518 +- Add command ``Rule0`` to change global rule parameters + ## Released ### 8.3.1 20200518 diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index dbcd5a954..f262b5fcb 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1040,7 +1040,7 @@ void CmndModules(void) uint32_t j = i ? midx +1 : 0; if ((ResponseAppend_P(PSTR("\"%d\":\"%s\""), j, AnyModuleName(midx).c_str()) > (LOGSZ - TOPSZ)) || (i == sizeof(kModuleNiceList))) { ResponseJsonEndEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_STAT, UpperCase(XdrvMailbox.command, XdrvMailbox.command)); + MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; lines++; } @@ -1149,7 +1149,7 @@ void CmndGpios(void) char stemp1[TOPSZ]; if ((ResponseAppend_P(PSTR("\"%d\":\"%s\""), ridx, GetTextIndexed(stemp1, sizeof(stemp1), midx, kSensorNames)) > (LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(kGpioNiceList) -1)) { ResponseJsonEndEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_STAT, UpperCase(XdrvMailbox.command, XdrvMailbox.command)); + MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; lines++; } diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index ddb4de39d..d23f3e122 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -1954,6 +1954,26 @@ void RulesPreprocessCommand(char *pCommands) void CmndRule(void) { + if (0 == XdrvMailbox.index) { + char data = '\0'; + if (XdrvMailbox.data_len > 0) { // Allow show all if 0 + if (!((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 10))) { + if ('"' == XdrvMailbox.data[0]) { + data = '"'; // Save data as XdrvMailbox.data is destroyed + } else { + XdrvMailbox.data_len = 0; // Discard any additional text + } + } + } + for (uint32_t i = 1; i <= MAX_RULE_SETS; i++) { + XdrvMailbox.index = i; + XdrvMailbox.data[0] = data; // Only 0 or " + CmndRule(); + MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); + } + mqtt_data[0] = '\0'; // Disable further processing + return; + } uint8_t index = XdrvMailbox.index; if ((index > 0) && (index <= MAX_RULE_SETS)) { // if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules[index -1]))) { // TODO postpone size calculation diff --git a/tasmota/xdrv_99_debug.ino b/tasmota/xdrv_99_debug.ino index 672ff17d3..08f451c30 100644 --- a/tasmota/xdrv_99_debug.ino +++ b/tasmota/xdrv_99_debug.ino @@ -45,7 +45,6 @@ #define D_CMND_CFGDUMP "CfgDump" #define D_CMND_CFGPEEK "CfgPeek" #define D_CMND_CFGPOKE "CfgPoke" -#define D_CMND_CFGSHOW "CfgShow" #define D_CMND_CFGXOR "CfgXor" #define D_CMND_CPUCHECK "CpuChk" #define D_CMND_EXCEPTION "Exception" @@ -459,7 +458,9 @@ void CmndCfgXor(void) if (XdrvMailbox.data_len > 0) { Web.config_xor_on_set = XdrvMailbox.payload; } - ResponseCmndNumber(Web.config_xor_on_set); + char temp[10]; + snprintf_P(temp, sizeof(temp), PSTR("0x%02X"), Web.config_xor_on_set); + ResponseCmndChar(temp); } #endif // USE_WEBSERVER From d61345e79f9ef01eab12ecc66082ebc9322e0c58 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 19 May 2020 11:31:24 +0200 Subject: [PATCH 010/581] Add TEMPLATES.md generation tool --- tools/templates/templates.py | 98 ++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 tools/templates/templates.py diff --git a/tools/templates/templates.py b/tools/templates/templates.py new file mode 100644 index 000000000..c1d696cbc --- /dev/null +++ b/tools/templates/templates.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +""" + templates.py - template beautify TEMPLATES.md for Tasmota + + Copyright (C) 2020 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 . + +Requirements: + - Python + - pip pycurl certifi + +Instructions: + Execute command to produce file TEMPLATE.md as found in the Tasmota root folder + +Usage: + python templates.py + +""" + +import io +import pycurl +import certifi +from io import BytesIO +from io import StringIO +from datetime import datetime + +column = 27 # Start position of {"NAME":... in line + +def main(): + print ("\n*** templates.py v20200514 by Theo Arends ***") + + # Download from template website + buffer = BytesIO() + url = "https://templates.blakadder.com/list.json" + c = pycurl.Curl() + c.setopt(c.URL, url) + c.setopt(c.WRITEDATA, buffer) + c.setopt(c.CAINFO, certifi.where()) + c.perform() + c.close() + body = buffer.getvalue() + fin = StringIO(body.decode('UTF-8')) + + now = datetime.now() + month = now.strftime('%B') + year = now.strftime('%Y') + + # Write to root/TEMPLATES.md + fout = open("..\..\TEMPLATES.md","w+") + + fout.write("\"Logo\"\n") + fout.write("\n") + fout.write("# Templates\n") + fout.write("\n") + fout.write("Find below the available templates as of " + month + " " + year + ". More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates)\n") + + not_first = 0 + fline = fin.readlines() + for line in fline: + if line.strip(): + if line.startswith("##"): + if not_first: + fout.write('```\n') + fout.write('\n') + fout.write(line) + fout.write('```\n') + not_first = 1 + elif line.startswith("#"): + noop = 0 + else: + pos1 = line.find("{") + if pos1 < column: + a = column + 2 - pos1 + lout = line[0:pos1 - 4] + " "*a + line[pos1:len(line)] + else: + lout = line[0:pos1 - 4] + " " + line[pos1:len(line)] + fout.write(lout) + + fout.write('```\n') + + fout.close() + fin.close() + +if __name__ == "__main__": + main() From cd7f7195634fb1f7fdc4590bbf7311d9c8dd55d0 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 19 May 2020 15:52:10 +0200 Subject: [PATCH 011/581] Add more functionality to ``Switchmode`` 11 and 12 (#8450) Add more functionality to ``Switchmode`` 11 and 12 (#8450) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/support_switch.ino | 47 +++++++++++++------------------------ tasmota/support_tasmota.ino | 6 ++++- tasmota/tasmota.h | 2 +- 5 files changed, 24 insertions(+), 33 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 71041b5da..75c484388 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -55,3 +55,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ### Version 8.3.1.1 - Add command ``Rule0`` to change global rule parameters +- Add more functionality to ``Switchmode`` 11 and 12 (#8450) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index e9ec2176d..1f343928e 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,6 +3,7 @@ ### 8.3.1.1 20200518 - Add command ``Rule0`` to change global rule parameters +- Add more functionality to ``Switchmode`` 11 and 12 (#8450) ## Released diff --git a/tasmota/support_switch.ino b/tasmota/support_switch.ino index 64837c74c..46b642e5b 100644 --- a/tasmota/support_switch.ino +++ b/tasmota/support_switch.ino @@ -154,8 +154,15 @@ void SwitchHandler(uint8_t mode) if (Switch.hold_timer[i]) { Switch.hold_timer[i]--; + if (Switch.hold_timer[i] == loops_per_second * Settings.param[P_HOLD_TIME] / 25) { + if ((Settings.switchmode[i] == PUSHHOLDMULTI) & (NOT_PRESSED == Switch.last_state[i])) { + SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT + } + if ((Settings.switchmode[i] == PUSHHOLDMULTI_INV) & (PRESSED == Switch.last_state[i])) { + SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT + } + } if (0 == Switch.hold_timer[i]) { - switch (Settings.switchmode[i]) { case TOGGLEMULTI: switchflag = POWER_TOGGLE; // Toggle after hold @@ -202,51 +209,33 @@ void SwitchHandler(uint8_t mode) switchflag = ~button &1; // Follow inverted wall switch state break; case PUSHBUTTON: -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { if (PRESSED == button) { switchflag = POWER_TOGGLE; // Toggle with pushbutton to Gnd } break; case PUSHBUTTON_INV: -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { if (NOT_PRESSED == button) { switchflag = POWER_TOGGLE; // Toggle with releasing pushbutton from Gnd } break; case PUSHBUTTONHOLD: -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { if (PRESSED == button) { Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; // Start timer on button press } -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { if ((NOT_PRESSED == button) && (Switch.hold_timer[i])) { Switch.hold_timer[i] = 0; // Button released and hold timer not expired : stop timer... switchflag = POWER_TOGGLE; // ...and Toggle } break; case PUSHBUTTONHOLD_INV: -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { if (NOT_PRESSED == button) { Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; // Start timer on button press... } -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { if ((PRESSED == button) && (Switch.hold_timer[i])) { Switch.hold_timer[i] = 0; // Button released and hold timer not expired : stop timer. switchflag = POWER_TOGGLE; // ...and Toggle } break; -/* - // Reverted Fix switchmode 6 according to issue 7778 (#7831) - case PUSHBUTTONHOLD_INV: - if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; // Start timer on button press... - switchflag = POWER_TOGGLE; // ...and Toggle - } - if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { - Switch.hold_timer[i] = 0; // Button released : stop timer. - } - break; -*/ case TOGGLEMULTI: case FOLLOWMULTI: case FOLLOWMULTI_INV: @@ -258,36 +247,32 @@ void SwitchHandler(uint8_t mode) } break; case PUSHHOLDMULTI: -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { if (NOT_PRESSED == button) { if (Switch.hold_timer[i] != 0) { SendKey(KEY_SWITCH, i +1, POWER_INV); // Execute command via MQTT } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; - } -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { - if (PRESSED == button) { + } else { if (Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) { switchflag = POWER_TOGGLE; // Toggle with pushbutton + } else { + SendKey(KEY_SWITCH, i +1, POWER_RELEASE); // Execute command via MQTT } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } + Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; break; case PUSHHOLDMULTI_INV: -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { if (PRESSED == button) { if (Switch.hold_timer[i] != 0) { SendKey(KEY_SWITCH, i +1, POWER_INV); // Execute command via MQTT } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; - } -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { - if (NOT_PRESSED == button) { + } else { if (Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) { switchflag = POWER_TOGGLE; // Toggle with pushbutton + } else { + SendKey(KEY_SWITCH, i +1, POWER_RELEASE); // Execute command via MQTT } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } + Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; break; case PUSHON: if (PRESSED == button) { diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index b1cc56a68..90df92a37 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -423,6 +423,10 @@ bool SendKey(uint32_t key, uint32_t device, uint32_t state) // state 1 = POWER_ON = on // state 2 = POWER_TOGGLE = toggle // state 3 = POWER_HOLD = hold +// state 4 = POWER_INCREMENT = button still pressed +// state 5 = POWER_INV = button released +// state 6 = POWER_CLEAR = button released +// state 7 = POWER_RELEASE = button released // state 9 = CLEAR_RETAIN = clear retain flag char stopic[TOPSZ]; @@ -1232,7 +1236,7 @@ void SerialInput(void) } else if ((serial_in_byte_counter == INPUT_BUFFER_SIZE) #ifdef ESP8266 - || Serial.hasOverrun() // Default ESP8266 Serial buffer size is 256. Tasmota increases to INPUT_BUFFER_SIZE + || Serial.hasOverrun() #endif ) { serial_buffer_overrun = true; diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 0376f3429..7434ff28e 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -232,7 +232,7 @@ enum TopicOptions { CMND, STAT, TELE, nu1, RESULT_OR_CMND, RESULT_OR_STAT, RESUL enum ExecuteCommandPowerOptions { POWER_OFF, POWER_ON, POWER_TOGGLE, POWER_BLINK, POWER_BLINK_STOP, POWER_OFF_NO_STATE = 8, POWER_ON_NO_STATE, POWER_TOGGLE_NO_STATE, POWER_SHOW_STATE = 16 }; -enum SendKeyPowerOptions { POWER_HOLD = 3, POWER_INCREMENT = 4, POWER_INV = 5, POWER_CLEAR = 6, CLEAR_RETAIN = 9 }; +enum SendKeyPowerOptions { POWER_HOLD = 3, POWER_INCREMENT = 4, POWER_INV = 5, POWER_CLEAR = 6, POWER_RELEASE = 7, CLEAR_RETAIN = 9 }; enum SendKeyOptions { KEY_BUTTON, KEY_SWITCH }; enum SendKeyMultiClick { SINGLE = 10, DOUBLE = 11, TRIPLE = 12, QUAD = 13, PENTA = 14}; From 5921055e2f56601a9b246cd8675b245ab77dd588 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Tue, 19 May 2020 16:44:01 +0200 Subject: [PATCH 012/581] scripter update script compression option more google charts (histogram, tables, gauges) smal bug fixes --- tasmota/xdrv_10_scripter.ino | 103 +++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index f0608fcfb..8c2dcbc4f 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -66,8 +66,9 @@ keywords if then else endif, or, and are better readable for beginners (others m uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); -#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#include +#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) #include "FS.h" #include "SPIFFS.h" @@ -3035,7 +3036,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { uint8_t index=glob_script_mem.type[ind.index].index; if ((vtype&STYPE)==0) { // numeric result - if (glob_script_mem.type[index].bits.is_filter) { + if (glob_script_mem.type[ind.index].bits.is_filter) { uint8_t len=0; float *fa=Get_MFAddr(index,&len); //Serial.printf(">> 2 %d\n",(uint32_t)*fa); @@ -3965,6 +3966,25 @@ void ScriptSaveSettings(void) { glob_script_mem.script_mem_size=0; } + +#ifndef UNISHOXRSIZE +#define UNISHOXRSIZE 2560 +#endif +#ifdef USE_RULES_COMPRESSION +#ifndef USE_24C256 +#ifndef USE_SCRIPT_FATFS +#ifndef ESP32_SCRIPT_SIZE + uint32_t len_compressed = unishox_compress(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], UNISHOXRSIZE); + if (len_compressed > 0) { + AddLog_P2(LOG_LEVEL_INFO,PSTR("compressed to %d"),len_compressed * 100 / strlen(glob_script_mem.script_ram)); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); + } +#endif +#endif +#endif +#endif // USE_RULES_COMPRESSION + if (bitRead(Settings.rule_enabled, 0)) { int16_t res=Init_Scripter(); if (res) { @@ -4871,14 +4891,31 @@ const char SCRIPT_MSG_NUMINP[] PROGMEM = const char SCRIPT_MSG_GTABLE[] PROGMEM = "" "" - "" + "" + ""; + + +const char SCRIPT_MSG_GTABLEa[] PROGMEM = + ""; -const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'"; +const char SCRIPT_MSG_GOPT1[] PROGMEM = +"title:'%s',isStacked:false"; +const char SCRIPT_MSG_GOPT2[] PROGMEM = +"showRowNumber:true,sort:'disable',allowHtml:true,width:'100%%',height:'100%%',cssClassNames:cssc"; + +const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'"; void ScriptGetVarname(char *nbuf,char *sp, uint32_t blen) { uint32_t cnt; @@ -4897,8 +4934,9 @@ void ScriptWebShow(char mc) { char line[128]; char tmp[128]; uint8_t optflg=0; - char *lp=glob_script_mem.section_ptr+2; uint8_t chartindex=1; + uint8_t google_libs=0; + char *lp=glob_script_mem.section_ptr+2; while (lp) { while (*lp==SCRIPT_EOL) { lp++; @@ -4928,7 +4966,6 @@ void ScriptWebShow(char mc) { optflg=0; } - // check for input elements if (!strncmp(lin,"sl(",3)) { // insert slider sl(min max var left mid right) @@ -5108,8 +5145,8 @@ void ScriptWebShow(char mc) { uint8_t index=glob_script_mem.type[ind.index].index; if ((vtype&STYPE)==0) { // numeric result - //Serial.printf("numeric\n"); - if (glob_script_mem.type[index].bits.is_filter) { + //Serial.printf("numeric %d - %d \n",ind.index,index); + if (glob_script_mem.type[ind.index].bits.is_filter) { //Serial.printf("numeric array\n"); uint8_t len=0; float *fa=Get_MFAddr(index,&len); @@ -5130,7 +5167,13 @@ void ScriptWebShow(char mc) { //Serial.printf("arrays %d\n",anum); //Serial.printf("entries %d\n",entries); - WSContentSend_PD(SCRIPT_MSG_GTABLE); + if (!google_libs) { + WSContentSend_PD(SCRIPT_MSG_GTABLE); + google_libs=1; + } + + WSContentSend_PD(SCRIPT_MSG_GTABLEa); + // we know how many arrays and the number of entries // we need to fetch the labels now WSContentSend_PD("["); @@ -5180,27 +5223,40 @@ void ScriptWebShow(char mc) { lp=GetStringResult(lp,OPER_EQU,header,0); SCRIPT_SKIP_SPACES + char options[128]; + snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT1,header); + const char *type; if (*lp!=')') { switch (*lp) { case 'l': - type="LineChart"; + type=PSTR("LineChart"); break; case 'b': - type="BarChart"; + type=PSTR("BarChart"); break; case 'p': - type="PieChart"; + type=PSTR("PieChart"); break; + case 'g': + type=PSTR("Gauge"); + break; + case 't': + type=PSTR("Table"); + snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT2); + break; + case 'h': + type=PSTR("Histogram"); + break; default: - type="ColumnChart"; + type=PSTR("ColumnChart"); break; } } else { - type="ColumnChart"; + type=PSTR("ColumnChart"); } - WSContentSend_PD(SCRIPT_MSG_GTABLEb,header,type,chartindex); + WSContentSend_PD(SCRIPT_MSG_GTABLEb,options,type,chartindex); chartindex++; } else { Replace_Cmd_Vars(lin,0,tmp,sizeof(tmp)); @@ -5363,6 +5419,7 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { * Interface \*********************************************************************************************/ + bool Xdrv10(uint8_t function) { bool result = false; @@ -5377,6 +5434,19 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_pram=(uint8_t*)Settings.script_pram[0]; glob_script_mem.script_pram_size=PMEM_SIZE; +#ifdef USE_RULES_COMPRESSION +#ifndef USE_24C256 +#ifndef USE_SCRIPT_FATFS +#ifndef ESP32_SCRIPT_SIZE + glob_script_mem.script_ram=(char*)calloc(UNISHOXRSIZE+8,1); + if (!glob_script_mem.script_ram) { break; } + unishox_decompress(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, UNISHOXRSIZE); + glob_script_mem.script_size=UNISHOXRSIZE; +#endif +#endif +#endif +#endif // USE_RULES_COMPRESSION + #ifdef USE_BUTTON_EVENT for (uint32_t cnt=0;cnt Date: Tue, 19 May 2020 20:23:01 +0200 Subject: [PATCH 013/581] Fix unishox python --- lib/Unishox-1.0-shadinger/python/unishox.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Unishox-1.0-shadinger/python/unishox.py b/lib/Unishox-1.0-shadinger/python/unishox.py index feafe0500..6d00c7589 100644 --- a/lib/Unishox-1.0-shadinger/python/unishox.py +++ b/lib/Unishox-1.0-shadinger/python/unishox.py @@ -47,10 +47,10 @@ class Unishox: SHX_SET1B = 2 SHX_SET2 = 3 - sets = [[0, ' ', 'e', 0, 't', 'a', 'o', 'i', 'n', 's', 'r'], - [0, 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'], - ['f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', 0, 0, 0], - [0, '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'], + sets = [['\0', ' ', 'e', '\0', 't', 'a', 'o', 'i', 'n', 's', 'r'], + ['\0', 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'], + ['f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', '\0', '\0', '\0'], + ['\0', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'], ['.', ',', '-', '/', '?', '+', ' ', '(', ')', '$', '@'], [';', '#', ':', '<', '^', '*', '"', '{', '}', '[', ']'], ['=', '%', '\'', '>', '&', '_', '!', '\\', '|', '~', '`']] @@ -319,6 +319,8 @@ class Unishox: code = 0 count = 0 while count < 5: + if bit_no_p >= len_: + return -1, bit_no_p # detect marker if self.ESCAPE_MARKER == inn[bit_no_p >> 3]: bit_no_p += 8 # skip marker From a305f435e80934f3cc56b9094eec6ff4b45f1cbb Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 15:15:39 +1000 Subject: [PATCH 014/581] First pass at led pwm settings * Added settings for ledpwm_on and ledpwm_off with defaults that mimic current digitalwrite function * Changed ledpoweridx from digitalwrite to analogwrite * Add commands to change new settings --- tasmota/i18n.h | 4 ++++ tasmota/settings.h | 4 +++- tasmota/settings.ino | 9 +++++++++ tasmota/support_command.ino | 28 ++++++++++++++++++++++++++-- tasmota/support_tasmota.ino | 8 +++++++- 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index e8286e585..18c073d0d 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -586,6 +586,10 @@ // Commands xsns_02_analog.ino #define D_CMND_ADCPARAM "AdcParam" +// Commands led pwm settings +#define D_CMND_SETLEDPWMOFF "SetLedPwmOff" +#define D_CMND_SETLEDPWMON "SetLedPwmOn" + /********************************************************************************************/ // Log message prefix diff --git a/tasmota/settings.h b/tasmota/settings.h index edd3de523..11546fea3 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -569,8 +569,10 @@ struct { uint16_t windmeter_pulse_debounce; // F3A int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E + uint16_t ledpwm_on; // F3F + uint16_t ledpwm_off; // F41 - uint8_t free_f3f[121]; // F3F - Decrement if adding new Setting variables just above and below + uint8_t free_f42[117]; // F42 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below uint16_t pulse_counter_debounce_low; // FB8 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 5214add7a..7a6a27ac3 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1055,6 +1055,10 @@ void SettingsDefaultSet2(void) Settings.flag2 = flag2; Settings.flag3 = flag3; Settings.flag4 = flag4; + + // Led PWM + Settings.ledpwm_off = 0; + Settings.ledpwm_on = 1023; } /********************************************************************************************/ @@ -1419,4 +1423,9 @@ void SettingsDelta(void) Settings.version = VERSION; SettingsSave(1); } + // ledpwm + if (Settings.version < 0x080300002) { + Settings.ledpwm_off = 0; + Settings.ledpwm_on = 1023; + } } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index f262b5fcb..5adcc708f 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -27,7 +27,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" - D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" + D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_SETLEDPWMON "|" D_CMND_SETLEDPWMOFF "|" #ifdef USE_I2C D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|" #endif @@ -50,7 +50,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, - &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, + &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSetLedPwmOn, &CmndSetLedPwmOff, #ifdef USE_I2C &CmndI2cScan, CmndI2cDriver, #endif @@ -1890,3 +1890,27 @@ void CmndDriver(void) { XdrvCall(FUNC_COMMAND_DRIVER); } + +void CmndSetLedPwmOff(void) +{ + if ((XdrvMailbox.payload < 0) { + Settings.ledpwm_off = 0; + } else if (XdrvMailbox.payload > Settings.pwm_range) { + Settings.ledpwm_off = Settings.pwm_range; + } else { + Settings.ledpwm_off = XdrvMailbox.payload; + } + ResponseCmndNumber(Settings.ledpwm_off); +} + +void CmndSetLedPwmOn(void) +{ + if ((XdrvMailbox.payload < 0) { + Settings.ledpwm_on = 0; + } else if (XdrvMailbox.payload > Settings.pwm_range) { + Settings.ledpwm_on = Settings.pwm_range; + } else { + Settings.ledpwm_on = XdrvMailbox.payload; + } + ResponseCmndNumber(Settings.ledpwm_on); +} \ No newline at end of file diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 90df92a37..65d842686 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -351,7 +351,13 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } else { led_power &= (0xFF ^ mask); } - DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); + uint16_t led_pwm_set = 0; + if (bitRead(led_inverted, led)) { + led_pwm_set = state ? Settings.pwm_range - Settings.ledpwm_on : Settings.pwm_range - Settings.ledpwm_off; + } else { + led_pwm_set = state ? Settings.ledpwm_on : Settings.ledpwm_off; + } + analogWrite(led, led_pwm_set) } #ifdef USE_BUZZER if (led == 0) { From ce2696fef0066ee303423d89a40a0614d90df9a4 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 15:44:19 +1000 Subject: [PATCH 015/581] Fix compile errors Missing brackets and semicolons of course. Blame python. --- tasmota/support_command.ino | 6 +++--- tasmota/support_tasmota.ino | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 5adcc708f..b48723575 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1893,7 +1893,7 @@ void CmndDriver(void) void CmndSetLedPwmOff(void) { - if ((XdrvMailbox.payload < 0) { + if (XdrvMailbox.payload < 0) { Settings.ledpwm_off = 0; } else if (XdrvMailbox.payload > Settings.pwm_range) { Settings.ledpwm_off = Settings.pwm_range; @@ -1905,7 +1905,7 @@ void CmndSetLedPwmOff(void) void CmndSetLedPwmOn(void) { - if ((XdrvMailbox.payload < 0) { + if (XdrvMailbox.payload < 0) { Settings.ledpwm_on = 0; } else if (XdrvMailbox.payload > Settings.pwm_range) { Settings.ledpwm_on = Settings.pwm_range; @@ -1913,4 +1913,4 @@ void CmndSetLedPwmOn(void) Settings.ledpwm_on = XdrvMailbox.payload; } ResponseCmndNumber(Settings.ledpwm_on); -} \ No newline at end of file +} diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 65d842686..2508566ea 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -357,7 +357,7 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } else { led_pwm_set = state ? Settings.ledpwm_on : Settings.ledpwm_off; } - analogWrite(led, led_pwm_set) + analogWrite(led, led_pwm_set); } #ifdef USE_BUZZER if (led == 0) { From bd33574ee7c4a50de1fa97c03c964148edff8fe5 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 16:38:21 +1000 Subject: [PATCH 016/581] Align new settings to 2B boundaries Attempting to fix settings not working correctly (might have mucked up the boundaries and compiler put a padding byte in). --- tasmota/settings.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 11546fea3..10c28a2ca 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -569,12 +569,12 @@ struct { uint16_t windmeter_pulse_debounce; // F3A int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E - uint16_t ledpwm_on; // F3F - uint16_t ledpwm_off; // F41 - uint8_t free_f42[117]; // F42 - Decrement if adding new Setting variables just above and below + uint8_t free_f3f[117]; // F3F - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below + uint16_t ledpwm_on; // FB4 + uint16_t ledpwm_off; // FB6 uint16_t pulse_counter_debounce_low; // FB8 uint16_t pulse_counter_debounce_high; // FBA uint32_t keeloq_master_msb; // FBC From fb179c27aff44b90e037469dc7b2521fb6dae2db Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 21:43:11 +1000 Subject: [PATCH 017/581] Fixes * Setting commands don't update if no data is sent * Didn't understand how pin mapping worked duh. Fixed. --- tasmota/support_command.ino | 21 ++++++++++++--------- tasmota/support_tasmota.ino | 14 +++++++++++--- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index b48723575..b5ce6d074 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1893,24 +1893,27 @@ void CmndDriver(void) void CmndSetLedPwmOff(void) { - if (XdrvMailbox.payload < 0) { + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload < 0) { Settings.ledpwm_off = 0; - } else if (XdrvMailbox.payload > Settings.pwm_range) { + } else if (XdrvMailbox.payload > Settings.pwm_range) { Settings.ledpwm_off = Settings.pwm_range; - } else { - Settings.ledpwm_off = XdrvMailbox.payload; - } + } else { + Settings.ledpwm_off = XdrvMailbox.payload; + } ResponseCmndNumber(Settings.ledpwm_off); } void CmndSetLedPwmOn(void) { - if (XdrvMailbox.payload < 0) { + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload < 0) { Settings.ledpwm_on = 0; - } else if (XdrvMailbox.payload > Settings.pwm_range) { + } else if (XdrvMailbox.payload > Settings.pwm_range) { Settings.ledpwm_on = Settings.pwm_range; - } else { - Settings.ledpwm_on = XdrvMailbox.payload; + } else { + Settings.ledpwm_on = XdrvMailbox.payload; + } } ResponseCmndNumber(Settings.ledpwm_on); } diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 2508566ea..ba4b0fb1d 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -353,11 +353,19 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } uint16_t led_pwm_set = 0; if (bitRead(led_inverted, led)) { - led_pwm_set = state ? Settings.pwm_range - Settings.ledpwm_on : Settings.pwm_range - Settings.ledpwm_off; + if (state) { + led_pwm_set = Settings.pwm_range - Settings.ledpwm_on; + } else { + led_pwm_set = Settings.pwm_range - Settings.ledpwm_off; + } } else { - led_pwm_set = state ? Settings.ledpwm_on : Settings.ledpwm_off; + if (state) { + led_pwm_set = Settings.ledpwm_on; + } else { + led_pwm_set = Settings.ledpwm_off; + } } - analogWrite(led, led_pwm_set); + analogWrite(Pin(GPIO_LED1, led), led_pwm_set); } #ifdef USE_BUZZER if (led == 0) { From bea58f223fb68e42b300356663487f10cef37f40 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 19 May 2020 22:01:40 +1000 Subject: [PATCH 018/581] Oops Compile error. Forgot bracket. --- tasmota/support_command.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index b5ce6d074..263f5f713 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1901,6 +1901,7 @@ void CmndSetLedPwmOff(void) } else { Settings.ledpwm_off = XdrvMailbox.payload; } + } ResponseCmndNumber(Settings.ledpwm_off); } From e21cbfdc5d96a9acd3943b30a53d5f7492a13b7b Mon Sep 17 00:00:00 2001 From: George Date: Wed, 20 May 2020 11:25:32 +1000 Subject: [PATCH 019/581] More sensible behaviour * When setting PWM values, updates all the LEDs (instant response). Uses led_power values. * If LEDLINK not set, but LED1 is, LED1 is the status led. When turning on/off, setledlink uses digitalwrite (which does not respect the new pwm operation). In this case only, we will use the setledpoweridx instead of digitalwrite - costly (every 250ms this runs), but edge case / legacy. Allows more intuitive operation - if we blink an LED with the max and min PWM limits, we'd expect it to respect these. In this case, blink will also now update the led_power status, which keeps this accurate e.g. if ledpower 1 cmnd was sent, then blink occurred, led_state would read a 1 for that bit but the led would be off (but nothing was reading it for status so it didn't cause any trouble). Leaving digitalwrite when LEDLINK is defined as this is more efficient and the use case for pwm leds is to find buttons - link indicator would become more ambiguous for no benefit. --- tasmota/support_command.ino | 2 ++ tasmota/support_tasmota.ino | 13 +++++++++---- tasmota/tasmota.ino | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 263f5f713..314097235 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1901,6 +1901,7 @@ void CmndSetLedPwmOff(void) } else { Settings.ledpwm_off = XdrvMailbox.payload; } + UpdateLedPowerAll(); } ResponseCmndNumber(Settings.ledpwm_off); } @@ -1915,6 +1916,7 @@ void CmndSetLedPwmOn(void) } else { Settings.ledpwm_on = XdrvMailbox.payload; } + UpdateLedPowerAll(); } ResponseCmndNumber(Settings.ledpwm_on); } diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index ba4b0fb1d..5a28b76d6 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -336,6 +336,13 @@ void SetPowerOnState(void) blink_powersave = power; } +void UpdateLedPowerAll() +{ + for (uint32_t i = 0; i < leds_present; i++) { + SetLedPowerIdx(i, bitRead(led_power, i)); + } +} + void SetLedPowerIdx(uint32_t led, uint32_t state) { if (!PinUsed(GPIO_LEDLNK) && (0 == led)) { // Legacy - LED1 is link led only if LED2 is present @@ -400,10 +407,8 @@ void SetLedLink(uint32_t state) uint32_t led_pin = Pin(GPIO_LEDLNK); uint32_t led_inv = ledlnk_inverted; if (99 == led_pin) { // Legacy - LED1 is status - led_pin = Pin(GPIO_LED1); - led_inv = bitRead(led_inverted, 0); - } - if (led_pin < 99) { + SetLedPowerIdx(0, state); + } else if (led_pin < 99) { if (state) { state = 1; } digitalWrite(led_pin, (led_inv) ? !state : state); } diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index ecf1127ec..92e3169b2 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -1,4 +1,4 @@ -/* + /* tasmota.ino - Tasmota firmware for iTead Sonoff, Wemos and NodeMCU hardware Copyright (C) 2020 Theo Arends From 603b628f97cf41f1bdaf0285377cdc0274497f47 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 20 May 2020 12:13:05 +1000 Subject: [PATCH 020/581] Add pwm mode masking * Extra setting & command to set - allows masking of pwm mode. Use case is for leds attached to buttons for seeing at night; this way user can combine both pwm and digital leds (i.e. pwm for the button leds but non-button status leds can stay on/off). --- tasmota/i18n.h | 1 + tasmota/settings.h | 3 ++- tasmota/settings.ino | 2 ++ tasmota/support_command.ino | 28 ++++++++++++++++++++++++++-- tasmota/support_tasmota.ino | 28 ++++++++++++++++------------ 5 files changed, 47 insertions(+), 15 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 18c073d0d..d2c232658 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -589,6 +589,7 @@ // Commands led pwm settings #define D_CMND_SETLEDPWMOFF "SetLedPwmOff" #define D_CMND_SETLEDPWMON "SetLedPwmOn" +#define D_CMND_SETLEDPWMMODE "SetLedPwmMode" /********************************************************************************************/ diff --git a/tasmota/settings.h b/tasmota/settings.h index 10c28a2ca..0cc171601 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -569,8 +569,9 @@ struct { uint16_t windmeter_pulse_debounce; // F3A int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E + uint8_t ledpwm_mask; // F3F - uint8_t free_f3f[117]; // F3F - Decrement if adding new Setting variables just above and below + uint8_t free_f40[116]; // F40 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below uint16_t ledpwm_on; // FB4 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 7a6a27ac3..d9d913c0a 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1059,6 +1059,7 @@ void SettingsDefaultSet2(void) // Led PWM Settings.ledpwm_off = 0; Settings.ledpwm_on = 1023; + Settings.ledpwm_mask = 0; } /********************************************************************************************/ @@ -1427,5 +1428,6 @@ void SettingsDelta(void) if (Settings.version < 0x080300002) { Settings.ledpwm_off = 0; Settings.ledpwm_on = 1023; + Settings.ledpwm_mask = 0; } } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 314097235..2f327b9a1 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -27,7 +27,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" - D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_SETLEDPWMON "|" D_CMND_SETLEDPWMOFF "|" + D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_SETLEDPWMON "|" D_CMND_SETLEDPWMOFF "|" D_CMND_SETLEDPWMMODE "|" #ifdef USE_I2C D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|" #endif @@ -50,7 +50,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, - &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSetLedPwmOn, &CmndSetLedPwmOff, + &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSetLedPwmOn, &CmndSetLedPwmOff, &CmndSetLedPwmMode, #ifdef USE_I2C &CmndI2cScan, CmndI2cDriver, #endif @@ -1920,3 +1920,27 @@ void CmndSetLedPwmOn(void) } ResponseCmndNumber(Settings.ledpwm_on); } + +void CmndSetLedPwmMode(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_LEDS)) { + if (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; } + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { + uint32_t mask = 1 << (XdrvMailbox.index -1); // Led to configure + switch (XdrvMailbox.payload) { + case 0: // digital + Settings.ledpwm_mask &= (0xFF ^ mask); + break; + case 1: // pwm + Settings.ledpwm_mask |= mask; + break; + case 2: // toggle + Settings.ledpwm_mask ^= mask; + break; + } + UpdateLedPowerAll(); + } + bool state = bitRead(Settings.ledpwm_mask, XdrvMailbox.index -1); + ResponseCmndIdxChar(GetStateText(state)); + } +} diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 5a28b76d6..d96751e32 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -359,20 +359,24 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) led_power &= (0xFF ^ mask); } uint16_t led_pwm_set = 0; - if (bitRead(led_inverted, led)) { - if (state) { - led_pwm_set = Settings.pwm_range - Settings.ledpwm_on; - } else { - led_pwm_set = Settings.pwm_range - Settings.ledpwm_off; - } + if (bitRead(Settings.ledpwm_mask, led)) { + if (bitRead(led_inverted, led)) { + if (state) { + led_pwm_set = Settings.pwm_range - Settings.ledpwm_on; + } else { + led_pwm_set = Settings.pwm_range - Settings.ledpwm_off; + } + } else { + if (state) { + led_pwm_set = Settings.ledpwm_on; + } else { + led_pwm_set = Settings.ledpwm_off; + } + } + analogWrite(Pin(GPIO_LED1, led), led_pwm_set); } else { - if (state) { - led_pwm_set = Settings.ledpwm_on; - } else { - led_pwm_set = Settings.ledpwm_off; - } + DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); } - analogWrite(Pin(GPIO_LED1, led), led_pwm_set); } #ifdef USE_BUZZER if (led == 0) { From 833d89203f643fac9db10f6409754892cfb7cef2 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 20 May 2020 12:38:24 +1000 Subject: [PATCH 021/581] Fix settings delta fail bugfix - settings always default on boot *Moved block to right scope *Got version number right duh --- tasmota/settings.ino | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tasmota/settings.ino b/tasmota/settings.ino index d9d913c0a..85a205da2 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1416,6 +1416,13 @@ void SettingsDelta(void) if (Settings.rules[1][0] == 0) { Settings.rules[1][1] = 0; } if (Settings.rules[2][0] == 0) { Settings.rules[2][1] = 0; } } + + // ledpwm + if (Settings.version < 0x08030001) { + Settings.ledpwm_off = 0; + Settings.ledpwm_on = 1023; + Settings.ledpwm_mask = 0; + } if (Settings.version < 0x08030002) { SettingsUpdateText(SET_DEVICENAME, SettingsText(SET_FRIENDLYNAME1)); @@ -1424,10 +1431,5 @@ void SettingsDelta(void) Settings.version = VERSION; SettingsSave(1); } - // ledpwm - if (Settings.version < 0x080300002) { - Settings.ledpwm_off = 0; - Settings.ledpwm_on = 1023; - Settings.ledpwm_mask = 0; - } + } From b7f932391a4e9837e0553d2f016b31d9b4147fa3 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 20 May 2020 12:42:34 +0200 Subject: [PATCH 022/581] Change IRremoteESP8266 library updated to v2.7.7 --- lib/IRremoteESP8266-2.7.6/src/ir_Carrier.cpp | 103 --- lib/IRremoteESP8266-2.7.6/src/ir_Sharp.h | 107 --- lib/IRremoteESP8266-2.7.6/test/Makefile | 653 ------------------ lib/IRremoteESP8266-2.7.6/tools/Makefile | 248 ------- .../CPPLINT.cfg | 0 .../LICENSE.txt | 0 .../README.md | 4 +- .../README_fr.md | 4 +- .../ReleaseNotes.md | 31 + .../SupportedProtocols.md | 19 +- lib/IRremoteESP8266-2.7.7/docs/README.md | 1 + lib/IRremoteESP8266-2.7.7/docs/_config.yml | 1 + .../examples/BlynkIrRemote/BlynkIrRemote.ino | 196 ++++++ .../examples/BlynkIrRemote/platformio.ini | 34 + .../CommonAcControl/CommonAcControl.ino | 0 .../examples/CommonAcControl/platformio.ini | 0 .../ControlSamsungAC/ControlSamsungAC.ino | 0 .../examples/ControlSamsungAC/platformio.ini | 0 .../DumbIRRepeater/DumbIRRepeater.ino | 0 .../examples/DumbIRRepeater/platformio.ini | 0 .../examples/IRGCSendDemo/IRGCSendDemo.ino | 0 .../examples/IRGCSendDemo/platformio.ini | 0 .../examples/IRGCTCPServer/IRGCTCPServer.ino | 0 .../examples/IRGCTCPServer/platformio.ini | 0 .../examples/IRMQTTServer/IRMQTTServer.h | 18 +- .../examples/IRMQTTServer/IRMQTTServer.ino | 41 +- .../examples/IRMQTTServer/platformio.ini | 0 .../examples/IRServer/IRServer.ino | 0 .../examples/IRServer/platformio.ini | 0 .../examples/IRrecvDemo/IRrecvDemo.ino | 0 .../examples/IRrecvDemo/platformio.ini | 0 .../examples/IRrecvDump/IRrecvDump.ino | 0 .../examples/IRrecvDump/platformio.ini | 0 .../examples/IRrecvDumpV2/IRrecvDumpV2.ino | 0 .../examples/IRrecvDumpV2/platformio.ini | 0 .../examples/IRrecvDumpV3/BaseOTA.h | 71 ++ .../examples/IRrecvDumpV3/IRrecvDumpV3.ino | 166 +++++ .../examples/IRrecvDumpV3/platformio.ini | 52 ++ .../examples/IRsendDemo/IRsendDemo.ino | 0 .../examples/IRsendDemo/platformio.ini | 0 .../IRsendProntoDemo/IRsendProntoDemo.ino | 0 .../examples/IRsendProntoDemo/platformio.ini | 0 .../JVCPanasonicSendDemo.ino | 0 .../JVCPanasonicSendDemo/platformio.ini | 0 .../examples/LGACSend/LGACSend.ino | 0 .../examples/LGACSend/platformio.ini | 0 .../SmartIRRepeater/SmartIRRepeater.ino | 0 .../examples/SmartIRRepeater/platformio.ini | 0 .../examples/TurnOnArgoAC/TurnOnArgoAC.ino | 0 .../examples/TurnOnArgoAC/platformio.ini | 0 .../TurnOnDaikinAC/TurnOnDaikinAC.ino | 0 .../examples/TurnOnDaikinAC/platformio.ini | 0 .../TurnOnFujitsuAC/TurnOnFujitsuAC.ino | 0 .../examples/TurnOnFujitsuAC/platformio.ini | 0 .../examples/TurnOnGreeAC/TurnOnGreeAC.ino | 0 .../examples/TurnOnGreeAC/platformio.ini | 0 .../TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino | 0 .../TurnOnKelvinatorAC/platformio.ini | 0 .../TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino | 0 .../TurnOnMitsubishiAC/platformio.ini | 0 .../TurnOnMitsubishiHeavyAc.ino | 0 .../TurnOnMitsubishiHeavyAc/platformio.ini | 0 .../TurnOnPanasonicAC/TurnOnPanasonicAC.ino | 0 .../examples/TurnOnPanasonicAC/platformio.ini | 0 .../TurnOnToshibaAC/TurnOnToshibaAC.ino | 0 .../examples/TurnOnToshibaAC/platformio.ini | 0 .../TurnOnTrotecAC/TurnOnTrotecAC.ino | 0 .../examples/TurnOnTrotecAC/platformio.ini | 0 .../examples/Web-AC-control/README.md | 0 .../Web-AC-control/Web-AC-control.ino | 0 .../examples/Web-AC-control/platformio.ini | 0 .../examples/Web-AC-control/printscreen.png | Bin .../Web-AC-control/upload/favicon.ico | Bin .../Web-AC-control/upload/level_1_off.svg | 0 .../Web-AC-control/upload/level_1_on.svg | 0 .../Web-AC-control/upload/level_2_off.svg | 0 .../Web-AC-control/upload/level_2_on.svg | 0 .../Web-AC-control/upload/level_3_off.svg | 0 .../Web-AC-control/upload/level_3_on.svg | 0 .../Web-AC-control/upload/level_4_off.svg | 0 .../Web-AC-control/upload/level_4_on.svg | 0 .../examples/Web-AC-control/upload/ui.html | 0 .../examples/Web-AC-control/upload/ui.js | 0 .../keywords.txt | 206 +++++- .../library.json | 7 +- .../library.properties | 4 +- .../platformio.ini | 0 .../pylintrc | 0 .../src/CPPLINT.cfg | 0 .../src/IRac.cpp | 92 ++- .../src/IRac.h | 19 +- .../src/IRrecv.cpp | 106 +++ .../src/IRrecv.h | 44 +- .../src/IRremoteESP8266.h | 77 ++- .../src/IRsend.cpp | 46 +- .../src/IRsend.h | 22 + .../src/IRtext.cpp | 13 +- .../src/IRtext.h | 2 + .../src/IRtimer.cpp | 0 .../src/IRtimer.h | 0 .../src/IRutils.cpp | 0 .../src/IRutils.h | 0 .../src/i18n.h | 0 .../src/ir_Airwell.cpp | 0 .../src/ir_Aiwa.cpp | 0 .../src/ir_Amcor.cpp | 0 .../src/ir_Amcor.h | 2 +- .../src/ir_Argo.cpp | 0 .../src/ir_Argo.h | 2 +- lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp | 217 ++++++ .../src/ir_Coolix.cpp | 0 .../src/ir_Coolix.h | 2 +- .../src/ir_Daikin.cpp | 3 +- .../src/ir_Daikin.h | 22 +- lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.cpp | 429 ++++++++++++ lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.h | 161 +++++ .../src/ir_Denon.cpp | 0 .../src/ir_Dish.cpp | 0 lib/IRremoteESP8266-2.7.7/src/ir_Doshisha.cpp | 132 ++++ .../src/ir_Electra.cpp | 0 .../src/ir_Electra.h | 2 +- .../src/ir_Epson.cpp | 0 .../src/ir_Fujitsu.cpp | 0 .../src/ir_Fujitsu.h | 2 +- .../src/ir_GICable.cpp | 0 .../src/ir_GlobalCache.cpp | 0 .../src/ir_Goodweather.cpp | 0 .../src/ir_Goodweather.h | 2 +- .../src/ir_Gree.cpp | 106 ++- .../src/ir_Gree.h | 54 +- .../src/ir_Haier.cpp | 0 .../src/ir_Haier.h | 2 +- .../src/ir_Hitachi.cpp | 0 .../src/ir_Hitachi.h | 8 +- .../src/ir_Inax.cpp | 0 .../src/ir_JVC.cpp | 0 .../src/ir_Kelvinator.cpp | 0 .../src/ir_Kelvinator.h | 2 +- .../src/ir_LG.cpp | 0 .../src/ir_LG.h | 2 +- .../src/ir_Lasertag.cpp | 0 .../src/ir_Lego.cpp | 0 .../src/ir_Lutron.cpp | 0 .../src/ir_MWM.cpp | 0 .../src/ir_Magiquest.cpp | 0 .../src/ir_Magiquest.h | 0 .../src/ir_Midea.cpp | 0 .../src/ir_Midea.h | 2 +- .../src/ir_Mitsubishi.cpp | 0 .../src/ir_Mitsubishi.h | 6 +- .../src/ir_MitsubishiHeavy.cpp | 0 .../src/ir_MitsubishiHeavy.h | 2 +- .../src/ir_Multibrackets.cpp | 128 ++++ .../src/ir_NEC.cpp | 0 .../src/ir_NEC.h | 0 .../src/ir_Neoclima.cpp | 0 .../src/ir_Neoclima.h | 2 +- .../src/ir_Nikai.cpp | 0 .../src/ir_Panasonic.cpp | 0 .../src/ir_Panasonic.h | 2 +- .../src/ir_Pioneer.cpp | 0 .../src/ir_Pronto.cpp | 10 +- .../src/ir_RC5_RC6.cpp | 0 .../src/ir_RCMM.cpp | 0 .../src/ir_Samsung.cpp | 0 .../src/ir_Samsung.h | 2 +- .../src/ir_Sanyo.cpp | 0 .../src/ir_Sharp.cpp | 245 +++++-- lib/IRremoteESP8266-2.7.7/src/ir_Sharp.h | 165 +++++ .../src/ir_Sherwood.cpp | 0 .../src/ir_Sony.cpp | 0 .../src/ir_Symphony.cpp | 42 +- .../src/ir_Tcl.cpp | 0 .../src/ir_Tcl.h | 2 +- .../src/ir_Teco.cpp | 0 .../src/ir_Teco.h | 0 .../src/ir_Toshiba.cpp | 0 .../src/ir_Toshiba.h | 2 +- .../src/ir_Trotec.cpp | 0 .../src/ir_Trotec.h | 2 +- .../src/ir_Vestel.cpp | 0 .../src/ir_Vestel.h | 2 +- .../src/ir_Whirlpool.cpp | 0 .../src/ir_Whirlpool.h | 2 +- .../src/ir_Whynter.cpp | 0 .../src/locale/README.md | 0 .../src/locale/de-CH.h | 0 .../src/locale/de-DE.h | 0 .../src/locale/defaults.h | 24 + .../src/locale/en-AU.h | 0 .../src/locale/en-IE.h | 0 .../src/locale/en-UK.h | 0 .../src/locale/en-US.h | 0 .../src/locale/es-ES.h | 0 .../src/locale/fr-FR.h | 0 .../src/locale/it-IT.h | 0 .../src/locale/zh-CN.h | 0 .../test/IRac_test.cpp | 43 +- .../test/IRrecv_test.cpp | 0 .../test/IRrecv_test.h | 0 .../test/IRsend_test.cpp | 0 .../test/IRsend_test.h | 0 .../test/IRutils_test.cpp | 0 lib/IRremoteESP8266-2.7.7/test/Makefile | 159 +++++ .../test/ir_Airwell_test.cpp | 0 .../test/ir_Aiwa_test.cpp | 0 .../test/ir_Amcor_test.cpp | 0 .../test/ir_Argo_test.cpp | 0 .../test/ir_Carrier_test.cpp | 176 ++++- .../test/ir_Coolix_test.cpp | 0 .../test/ir_Daikin_test.cpp | 33 + .../test/ir_Delonghi_test.cpp | 362 ++++++++++ .../test/ir_Denon_test.cpp | 0 .../test/ir_Dish_test.cpp | 0 .../test/ir_Doshisha_test.cpp | 152 ++++ .../test/ir_Electra_test.cpp | 0 .../test/ir_Epson_test.cpp | 0 .../test/ir_Fujitsu_test.cpp | 0 .../test/ir_GICable_test.cpp | 0 .../test/ir_GlobalCache_test.cpp | 0 .../test/ir_Goodweather_test.cpp | 0 .../test/ir_Gree_test.cpp | 448 +++++++----- .../test/ir_Haier_test.cpp | 0 .../test/ir_Hitachi_test.cpp | 0 .../test/ir_Inax_test.cpp | 0 .../test/ir_JVC_test.cpp | 0 .../test/ir_Kelvinator_test.cpp | 0 .../test/ir_LG_test.cpp | 0 .../test/ir_Lasertag_test.cpp | 0 .../test/ir_Lego_test.cpp | 0 .../test/ir_Lutron_test.cpp | 0 .../test/ir_MWM_test.cpp | 0 .../test/ir_Magiquest_test.cpp | 0 .../test/ir_Midea_test.cpp | 0 .../test/ir_MitsubishiHeavy_test.cpp | 0 .../test/ir_Mitsubishi_test.cpp | 0 .../test/ir_Multibrackets_test.cpp | 98 +++ .../test/ir_NEC_test.cpp | 0 .../test/ir_Neoclima_test.cpp | 0 .../test/ir_Nikai_test.cpp | 0 .../test/ir_Panasonic_test.cpp | 0 .../test/ir_Pioneer_test.cpp | 0 .../test/ir_Pronto_test.cpp | 190 +++-- .../test/ir_RC5_RC6_test.cpp | 0 .../test/ir_RCMM_test.cpp | 0 .../test/ir_Samsung_test.cpp | 0 .../test/ir_Sanyo_test.cpp | 0 .../test/ir_Sharp_test.cpp | 387 +++++++++-- .../test/ir_Sherwood_test.cpp | 0 .../test/ir_Sony_test.cpp | 0 .../test/ir_Symphony_test.cpp | 59 +- .../test/ir_Tcl_test.cpp | 0 .../test/ir_Teco_test.cpp | 0 .../test/ir_Toshiba_test.cpp | 0 .../test/ir_Trotec_test.cpp | 0 .../test/ir_Vestel_test.cpp | 0 .../test/ir_Whirlpool_test.cpp | 0 .../test/ir_Whynter_test.cpp | 0 lib/IRremoteESP8266-2.7.7/tools/Makefile | 88 +++ .../tools/RawToGlobalCache.sh | 0 .../tools/auto_analyse_raw_data.py | 126 ++-- .../tools/auto_analyse_raw_data_test.py | 239 +++++-- .../tools/gc_decode.cpp | 0 .../tools/generate_irtext_h.sh | 0 .../tools/mkkeywords | 0 .../tools/mode2_decode.cpp | 0 .../tools/raw_to_pronto_code.py | 103 +++ .../tools/raw_to_pronto_code_test.py | 81 +++ .../tools/scrape_supported_devices.py | 3 +- tasmota/CHANGELOG.md | 1 + 270 files changed, 5131 insertions(+), 1794 deletions(-) delete mode 100644 lib/IRremoteESP8266-2.7.6/src/ir_Carrier.cpp delete mode 100644 lib/IRremoteESP8266-2.7.6/src/ir_Sharp.h delete mode 100644 lib/IRremoteESP8266-2.7.6/test/Makefile delete mode 100644 lib/IRremoteESP8266-2.7.6/tools/Makefile rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/CPPLINT.cfg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/LICENSE.txt (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/README.md (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/README_fr.md (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/ReleaseNotes.md (94%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/SupportedProtocols.md (88%) create mode 100644 lib/IRremoteESP8266-2.7.7/docs/README.md create mode 100644 lib/IRremoteESP8266-2.7.7/docs/_config.yml create mode 100644 lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/BlynkIrRemote.ino create mode 100644 lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/platformio.ini rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/CommonAcControl/CommonAcControl.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/CommonAcControl/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/ControlSamsungAC/ControlSamsungAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/ControlSamsungAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/DumbIRRepeater/DumbIRRepeater.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/DumbIRRepeater/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRGCSendDemo/IRGCSendDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRGCSendDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRGCTCPServer/IRGCTCPServer.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRGCTCPServer/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRMQTTServer/IRMQTTServer.h (96%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRMQTTServer/IRMQTTServer.ino (99%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRMQTTServer/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRServer/IRServer.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRServer/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRrecvDemo/IRrecvDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRrecvDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRrecvDump/IRrecvDump.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRrecvDump/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRrecvDumpV2/IRrecvDumpV2.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRrecvDumpV2/platformio.ini (100%) create mode 100644 lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/BaseOTA.h create mode 100644 lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/IRrecvDumpV3.ino create mode 100644 lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/platformio.ini rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRsendDemo/IRsendDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRsendDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRsendProntoDemo/IRsendProntoDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/IRsendProntoDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/JVCPanasonicSendDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/LGACSend/LGACSend.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/LGACSend/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/SmartIRRepeater/SmartIRRepeater.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/SmartIRRepeater/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnArgoAC/TurnOnArgoAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnArgoAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnDaikinAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnFujitsuAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnGreeAC/TurnOnGreeAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnGreeAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnKelvinatorAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnMitsubishiAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnMitsubishiHeavyAc/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnPanasonicAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnToshibaAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/TurnOnTrotecAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/README.md (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/Web-AC-control.ino (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/printscreen.png (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/favicon.ico (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/level_1_off.svg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/level_1_on.svg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/level_2_off.svg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/level_2_on.svg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/level_3_off.svg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/level_3_on.svg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/level_4_off.svg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/level_4_on.svg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/ui.html (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/examples/Web-AC-control/upload/ui.js (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/keywords.txt (94%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/library.json (88%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/library.properties (89%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/pylintrc (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/CPPLINT.cfg (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRac.cpp (97%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRac.h (95%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRrecv.cpp (92%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRrecv.h (92%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRremoteESP8266.h (93%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRsend.cpp (97%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRsend.h (96%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRtext.cpp (94%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRtext.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRtimer.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRtimer.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRutils.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/IRutils.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/i18n.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Airwell.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Aiwa.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Amcor.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Amcor.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Argo.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Argo.h (99%) create mode 100644 lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Coolix.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Coolix.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Daikin.cpp (99%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Daikin.h (98%) create mode 100644 lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.cpp create mode 100644 lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.h rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Denon.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Dish.cpp (100%) create mode 100644 lib/IRremoteESP8266-2.7.7/src/ir_Doshisha.cpp rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Electra.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Electra.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Epson.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Fujitsu.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Fujitsu.h (99%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_GICable.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_GlobalCache.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Goodweather.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Goodweather.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Gree.cpp (82%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Gree.h (74%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Haier.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Haier.h (99%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Hitachi.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Hitachi.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Inax.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_JVC.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Kelvinator.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Kelvinator.h (99%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_LG.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_LG.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Lasertag.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Lego.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Lutron.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_MWM.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Magiquest.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Magiquest.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Midea.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Midea.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Mitsubishi.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Mitsubishi.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_MitsubishiHeavy.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_MitsubishiHeavy.h (99%) create mode 100644 lib/IRremoteESP8266-2.7.7/src/ir_Multibrackets.cpp rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_NEC.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_NEC.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Neoclima.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Neoclima.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Nikai.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Panasonic.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Panasonic.h (99%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Pioneer.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Pronto.cpp (93%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_RC5_RC6.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_RCMM.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Samsung.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Samsung.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Sanyo.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Sharp.cpp (71%) create mode 100644 lib/IRremoteESP8266-2.7.7/src/ir_Sharp.h rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Sherwood.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Sony.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Symphony.cpp (58%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Tcl.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Tcl.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Teco.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Teco.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Toshiba.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Toshiba.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Trotec.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Trotec.h (98%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Vestel.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Vestel.h (99%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Whirlpool.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Whirlpool.h (99%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/ir_Whynter.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/README.md (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/de-CH.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/de-DE.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/defaults.h (96%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/en-AU.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/en-IE.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/en-UK.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/en-US.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/es-ES.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/fr-FR.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/it-IT.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/src/locale/zh-CN.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/IRac_test.cpp (97%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/IRrecv_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/IRrecv_test.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/IRsend_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/IRsend_test.h (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/IRutils_test.cpp (100%) create mode 100644 lib/IRremoteESP8266-2.7.7/test/Makefile rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Airwell_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Aiwa_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Amcor_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Argo_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Carrier_test.cpp (58%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Coolix_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Daikin_test.cpp (98%) create mode 100644 lib/IRremoteESP8266-2.7.7/test/ir_Delonghi_test.cpp rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Denon_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Dish_test.cpp (100%) create mode 100644 lib/IRremoteESP8266-2.7.7/test/ir_Doshisha_test.cpp rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Electra_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Epson_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Fujitsu_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_GICable_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_GlobalCache_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Goodweather_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Gree_test.cpp (65%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Haier_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Hitachi_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Inax_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_JVC_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Kelvinator_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_LG_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Lasertag_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Lego_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Lutron_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_MWM_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Magiquest_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Midea_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_MitsubishiHeavy_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Mitsubishi_test.cpp (100%) create mode 100644 lib/IRremoteESP8266-2.7.7/test/ir_Multibrackets_test.cpp rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_NEC_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Neoclima_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Nikai_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Panasonic_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Pioneer_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Pronto_test.cpp (69%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_RC5_RC6_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_RCMM_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Samsung_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Sanyo_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Sharp_test.cpp (69%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Sherwood_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Sony_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Symphony_test.cpp (70%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Tcl_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Teco_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Toshiba_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Trotec_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Vestel_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Whirlpool_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/test/ir_Whynter_test.cpp (100%) create mode 100644 lib/IRremoteESP8266-2.7.7/tools/Makefile rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/tools/RawToGlobalCache.sh (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/tools/auto_analyse_raw_data.py (89%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/tools/auto_analyse_raw_data_test.py (86%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/tools/gc_decode.cpp (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/tools/generate_irtext_h.sh (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/tools/mkkeywords (100%) rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/tools/mode2_decode.cpp (100%) create mode 100755 lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code.py create mode 100755 lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code_test.py rename lib/{IRremoteESP8266-2.7.6 => IRremoteESP8266-2.7.7}/tools/scrape_supported_devices.py (98%) diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Carrier.cpp b/lib/IRremoteESP8266-2.7.6/src/ir_Carrier.cpp deleted file mode 100644 index 293711a03..000000000 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Carrier.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2018 David Conran - -// Supports: -// Brand: Carrier/Surrey, Model: 42QG5A55970 remote -// Brand: Carrier/Surrey, Model: 619EGX0090E0 A/C -// Brand: Carrier/Surrey, Model: 619EGX0120E0 A/C -// Brand: Carrier/Surrey, Model: 619EGX0180E0 A/C -// Brand: Carrier/Surrey, Model: 619EGX0220E0 A/C -// Brand: Carrier/Surrey, Model: 53NGK009/012 Inverter - -#include "IRrecv.h" -#include "IRsend.h" -#include "IRutils.h" - -// Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/385 -const uint16_t kCarrierAcHdrMark = 8532; -const uint16_t kCarrierAcHdrSpace = 4228; -const uint16_t kCarrierAcBitMark = 628; -const uint16_t kCarrierAcOneSpace = 1320; -const uint16_t kCarrierAcZeroSpace = 532; -const uint16_t kCarrierAcGap = 20000; - -#if SEND_CARRIER_AC -// Send a Carrier HVAC formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kCarrierAcBits. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Work on real devices. -// -void IRsend::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) { - for (uint16_t r = 0; r <= repeat; r++) { - uint64_t temp_data = data; - // Carrier sends the data block three times. normal + inverted + normal. - for (uint16_t i = 0; i < 3; i++) { - sendGeneric(kCarrierAcHdrMark, kCarrierAcHdrSpace, kCarrierAcBitMark, - kCarrierAcOneSpace, kCarrierAcBitMark, kCarrierAcZeroSpace, - kCarrierAcBitMark, kCarrierAcGap, temp_data, nbits, 38, true, - 0, kDutyDefault); - temp_data = invertBits(temp_data, nbits); - } - } -} -#endif - -#if DECODE_CARRIER_AC -// Decode the supplied Carrier HVAC message. -// Carrier HVAC messages contain only 32 bits, but it is sent three(3) times. -// i.e. normal + inverted + normal -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kCarrierAcBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works. -// -bool IRrecv::decodeCarrierAC(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict) { - if (results->rawlen < ((2 * nbits + kHeader + kFooter) * 3) - 1 + offset) - return false; // Can't possibly be a valid Carrier message. - if (strict && nbits != kCarrierAcBits) - return false; // We expect Carrier to be 32 bits of message. - - uint64_t data = 0; - uint64_t prev_data = 0; - - for (uint8_t i = 0; i < 3; i++) { - prev_data = data; - // Match Header + Data + Footer - uint16_t used; - used = matchGeneric(results->rawbuf + offset, &data, - results->rawlen - offset, nbits, - kCarrierAcHdrMark, kCarrierAcHdrSpace, - kCarrierAcBitMark, kCarrierAcOneSpace, - kCarrierAcBitMark, kCarrierAcZeroSpace, - kCarrierAcBitMark, kCarrierAcGap, true); - if (!used) return false; - offset += used; - // Compliance. - if (strict) { - // Check if the data is an inverted copy of the previous data. - if (i > 0 && prev_data != invertBits(data, nbits)) return false; - } - } - - // Success - results->bits = nbits; - results->value = data; - results->decode_type = CARRIER_AC; - results->address = data >> 16; - results->command = data & 0xFFFF; - return true; -} -#endif diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Sharp.h b/lib/IRremoteESP8266-2.7.6/src/ir_Sharp.h deleted file mode 100644 index 03d27d44f..000000000 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Sharp.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2019 crankyoldgit - -// Supports: -// Brand: Sharp, Model: LC-52D62U TV -// Brand: Sharp, Model: AY-ZP40KR A/C -// Brand: Sharp, Model: AH-AxSAY A/C - -#ifndef IR_SHARP_H_ -#define IR_SHARP_H_ - -#ifndef UNIT_TEST -#include -#endif -#include "IRrecv.h" -#include "IRremoteESP8266.h" -#include "IRsend.h" -#ifdef UNIT_TEST -#include "IRsend_test.h" -#endif - -// Constants -const uint16_t kSharpAcHdrMark = 3800; -const uint16_t kSharpAcHdrSpace = 1900; -const uint16_t kSharpAcBitMark = 470; -const uint16_t kSharpAcZeroSpace = 500; -const uint16_t kSharpAcOneSpace = 1400; -const uint32_t kSharpAcGap = kDefaultMessageGap; - -const uint8_t kSharpAcAuto = 0b000; -const uint8_t kSharpAcDry = 0b011; -const uint8_t kSharpAcCool = 0b010; -const uint8_t kSharpAcHeat = 0b001; -const uint8_t kSharpAcMinTemp = 15; // Celsius -const uint8_t kSharpAcMaxTemp = 30; // Celsius -const uint8_t kSharpAcFanAuto = 0b010; // 2 -const uint8_t kSharpAcFanMin = 0b100; // 4 (FAN1) -const uint8_t kSharpAcFanMed = 0b011; // 3 (FAN2) -const uint8_t kSharpAcFanHigh = 0b101; // 5 (FAN3) -const uint8_t kSharpAcFanMax = 0b111; // 7 (FAN4) -const uint8_t kSharpAcByteTemp = 4; -const uint8_t kSharpAcBytePower = 5; -const uint8_t kSharpAcBitPowerOffset = 4; // 0b000x0000 -const uint8_t kSharpAcBitPreviousPowerOffset = 5; // 0b00x00000 -const uint8_t kSharpAcByteMode = 6; -const uint8_t kSharpAcModeSize = 2; // Mask 0b00000011; -const uint8_t kSharpAcByteFan = kSharpAcByteMode; -const uint8_t kSharpAcFanOffset = 4; // Mask 0b01110000 -const uint8_t kSharpAcFanSize = 3; // Nr. of Bits -const uint8_t kSharpAcByteButton = 10; -const uint8_t kSharpAcButtonOffset = 0; -const uint8_t kSharpAcButtonSize = 3; // Mask 0b00000xxx -const uint8_t kSharpAcButtonPowerMode = 0b000; // 0 -const uint8_t kSharpAcButtonTemp = 0b100; // 4 -const uint8_t kSharpAcButtonFan = 0b101; // 5 - -class IRSharpAc { - public: - explicit IRSharpAc(const uint16_t pin, const bool inverted = false, - const bool use_modulation = true); - -#if SEND_SHARP_AC - void send(const uint16_t repeat = kSharpAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } -#endif // SEND_SHARP_AC - void begin(void); - void on(void); - void off(void); - void setPower(const bool on); - void setPower(const bool on, const bool prev); - bool getPower(void); - void setPreviousPower(const bool on); - bool getPreviousPower(void); - void setTemp(const uint8_t temp); - uint8_t getTemp(void); - void setFan(const uint8_t fan); - uint8_t getFan(void); - void setMode(const uint8_t mode); - uint8_t getMode(void); - void setButton(const uint8_t button); - uint8_t getButton(void); - uint8_t* getRaw(void); - void setRaw(const uint8_t new_code[], - const uint16_t length = kSharpAcStateLength); - static bool validChecksum(uint8_t state[], - const uint16_t length = kSharpAcStateLength); - static uint8_t convertMode(const stdAc::opmode_t mode); - static uint8_t convertFan(const stdAc::fanspeed_t speed); - static stdAc::opmode_t toCommonMode(const uint8_t mode); - static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); - stdAc::state_t toCommon(void); - String toString(void); -#ifndef UNIT_TEST - - private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // # of bytes per command - uint8_t remote[kSharpAcStateLength]; - void stateReset(void); - void checksum(void); - static uint8_t calcChecksum(uint8_t state[], - const uint16_t length = kSharpAcStateLength); -}; - -#endif // IR_SHARP_H_ diff --git a/lib/IRremoteESP8266-2.7.6/test/Makefile b/lib/IRremoteESP8266-2.7.6/test/Makefile deleted file mode 100644 index dc0574a1d..000000000 --- a/lib/IRremoteESP8266-2.7.6/test/Makefile +++ /dev/null @@ -1,653 +0,0 @@ -# SYNOPSIS: -# -# make [all] - makes everything. -# make TARGET - makes the given target. -# make run - makes everything and runs all the tests. -# make clean - removes all files generated by make. -# make install-googletest - install the googletest code suite - -# Please tweak the following variable definitions as needed by your -# project, except GTEST_HEADERS, which you can use in your own targets -# but shouldn't modify. - -# Points to the root of Google Test, relative to where this file is. -# Remember to tweak this if you move this file. -GTEST_DIR = ../lib/googletest/googletest - -# Where to find user code. -USER_DIR = ../src -INCLUDES = -I$(USER_DIR) -I. - -# Flags passed to the preprocessor. -# Set Google Test's header directory as a system directory, such that -# the compiler doesn't generate warnings in Google Test headers. -CPPFLAGS += -isystem $(GTEST_DIR)/include -DUNIT_TEST -D_IR_LOCALE_=en-AU - -# Flags passed to the C++ compiler. -CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 - -# All tests produced by this Makefile. Remember to add new tests you -# created to the list. -TESTS = IRutils_test IRsend_test ir_NEC_test ir_GlobalCache_test \ - ir_Sherwood_test ir_Sony_test ir_Samsung_test ir_Kelvinator_test \ - ir_JVC_test ir_RCMM_test ir_LG_test ir_Mitsubishi_test ir_Sharp_test \ - ir_RC5_RC6_test ir_Panasonic_test ir_Dish_test ir_Whynter_test \ - ir_Aiwa_test ir_Denon_test ir_Sanyo_test ir_Daikin_test ir_Coolix_test \ - ir_Gree_test IRrecv_test ir_Pronto_test ir_Fujitsu_test ir_Nikai_test \ - ir_Toshiba_test ir_Midea_test ir_Magiquest_test ir_Lasertag_test \ - ir_Carrier_test ir_Haier_test ir_Hitachi_test ir_GICable_test \ - ir_Whirlpool_test ir_Lutron_test ir_Electra_test ir_Pioneer_test \ - ir_MWM_test ir_Vestel_test ir_Teco_test ir_Tcl_test ir_Lego_test IRac_test \ - ir_MitsubishiHeavy_test ir_Trotec_test ir_Argo_test ir_Goodweather_test \ - ir_Inax_test ir_Neoclima_test ir_Amcor_test ir_Epson_test ir_Symphony_test \ - ir_Airwell_test - -# All Google Test headers. Usually you shouldn't change this -# definition. -GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ - $(GTEST_DIR)/include/gtest/internal/*.h - -# House-keeping build targets. - -all : $(TESTS) - -clean : - rm -f $(TESTS) gtest.a gtest_main.a *.o - -# Build and run all the tests. -run : all - failed=""; \ - for unittest in $(TESTS); do \ - ./$${unittest} || failed="$${failed} $${unittest}"; \ - done; \ - if [ -n "$${failed}" ]; then \ - echo "FAIL: :-( :-( Unit test(s)$${failed} failed! :-( :-("; exit 1; \ - else \ - echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \ - fi - -run_tests : run - -install-googletest : - git clone -b v1.8.x https://github.com/google/googletest.git ../lib/googletest - -# Builds gtest.a and gtest_main.a. - -# Usually you shouldn't tweak such internal variables, indicated by a -# trailing _. -GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) - -# All the IR protocol object files. -PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.o \ - ir_LG.o ir_Mitsubishi.o ir_Fujitsu.o ir_Sharp.o ir_Sanyo.o ir_Denon.o ir_Dish.o \ - ir_Panasonic.o ir_Whynter.o ir_Coolix.o ir_Aiwa.o ir_Sherwood.o \ - ir_Kelvinator.o ir_Daikin.o ir_Gree.o ir_Pronto.o ir_Nikai.o ir_Toshiba.o \ - ir_Midea.o ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o \ - ir_Hitachi.o ir_GICable.o ir_Whirlpool.o ir_Lutron.o ir_Electra.o \ - ir_Pioneer.o ir_MWM.o ir_Vestel.o ir_Teco.o ir_Tcl.o ir_Lego.o ir_Argo.o \ - ir_Trotec.o ir_MitsubishiHeavy.o ir_Goodweather.o ir_Inax.o ir_Neoclima.o \ - ir_Amcor.o ir_Epson.o ir_Symphony.o ir_Airwell.o - -# All the IR Protocol header files. -PROTOCOLS_H = $(USER_DIR)/ir_Amcor.h \ - $(USER_DIR)/ir_Argo.h \ - $(USER_DIR)/ir_Gree.h \ - $(USER_DIR)/ir_Magiquest.h \ - $(USER_DIR)/ir_Coolix.h \ - $(USER_DIR)/ir_Electra.h \ - $(USER_DIR)/ir_Haier.h \ - $(USER_DIR)/ir_Hitachi.h \ - $(USER_DIR)/ir_Midea.h \ - $(USER_DIR)/ir_Toshiba.h \ - $(USER_DIR)/ir_Daikin.h \ - $(USER_DIR)/ir_Goodweather.h \ - $(USER_DIR)/ir_Kelvinator.h \ - $(USER_DIR)/ir_Mitsubishi.h \ - $(USER_DIR)/ir_MitsubishiHeavy.h \ - $(USER_DIR)/ir_NEC.h \ - $(USER_DIR)/ir_Neoclima.h \ - $(USER_DIR)/ir_Sharp.h \ - $(USER_DIR)/ir_Samsung.h \ - $(USER_DIR)/ir_Trotec.h \ - $(USER_DIR)/ir_Fujitsu.h \ - $(USER_DIR)/ir_LG.h \ - $(USER_DIR)/ir_Panasonic.h \ - $(USER_DIR)/ir_Whirlpool.h \ - $(USER_DIR)/ir_Vestel.h \ - $(USER_DIR)/ir_Tcl.h \ - $(USER_DIR)/ir_Teco.h \ - $(USER_DIR)/ir_Trotec.h -# Common object files -COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o IRac.o ir_GlobalCache.o \ - IRtext.o $(PROTOCOLS) gtest_main.a -# Common dependencies -COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \ - $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \ - $(USER_DIR)/IRac.h $(USER_DIR)/i18n.h $(USER_DIR)/IRtext.h \ - $(PROTOCOLS_H) - -# Common test dependencies -COMMON_TEST_DEPS = $(COMMON_DEPS) IRrecv_test.h IRsend_test.h - -# For simplicity and to avoid depending on Google Test's -# implementation details, the dependencies specified below are -# conservative and not optimized. This is fine as Google Test -# compiles fast and for ordinary users its source rarely changes. -gtest-all.o : $(GTEST_SRCS_) - $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ - $(GTEST_DIR)/src/gtest-all.cc - -gtest_main.o : $(GTEST_SRCS_) - $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ - $(GTEST_DIR)/src/gtest_main.cc - -gtest.a : gtest-all.o - $(AR) $(ARFLAGS) $@ $^ - -gtest_main.a : gtest-all.o gtest_main.o - $(AR) $(ARFLAGS) $@ $^ - -# Builds our test. A test should link with either gtest.a or -# gtest_main.a, depending on whether it defines its own main() -# function. - -IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/locale/*.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRtext.cpp - -IRutils.o : $(USER_DIR)/IRutils.cpp $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/locale/*.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRutils.cpp - -IRutils_test.o : IRutils_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRutils_test.cpp - -IRutils_test : IRutils_test.o ir_NEC.o ir_Nikai.o ir_Toshiba.o IRtext.o $(COMMON_OBJ) gtest_main.a - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -IRtimer.o : $(USER_DIR)/IRtimer.cpp $(USER_DIR)/IRtimer.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRtimer.cpp - -IRsend.o : $(USER_DIR)/IRsend.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRremoteESP8266.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRsend.cpp - -IRsend_test.o : IRsend_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRsend_test.cpp - -IRsend_test : IRsend_test.o $(COMMON_OBJ) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRrecv.cpp - -IRrecv_test.o : IRrecv_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRrecv_test.cpp - -IRrecv_test : IRrecv_test.o $(COMMON_OBJ) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRac.cpp - -IRac_test.o : IRac_test.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRac_test.cpp - -IRac_test : IRac_test.o $(COMMON_OBJ) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_NEC.o : $(USER_DIR)/ir_NEC.cpp $(USER_DIR)/ir_NEC.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_NEC.cpp - -ir_NEC_test.o : ir_NEC_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_NEC_test.cpp - -ir_NEC_test : $(COMMON_OBJ) ir_NEC_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_GlobalCache.o : $(USER_DIR)/ir_GlobalCache.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GlobalCache.cpp - -ir_GlobalCache_test.o : ir_GlobalCache_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_GlobalCache_test.cpp - -ir_GlobalCache_test : $(COMMON_OBJ) ir_GlobalCache_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Sherwood.o : $(USER_DIR)/ir_Sherwood.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sherwood.cpp - -ir_Sherwood_test.o : ir_Sherwood_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Sherwood_test.cpp - -ir_Sherwood_test : $(COMMON_OBJ) ir_Sherwood_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Sony.o : $(USER_DIR)/ir_Sony.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sony.cpp - -ir_Sony_test.o : ir_Sony_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Sony_test.cpp - -ir_Sony_test : $(COMMON_OBJ) ir_Sony_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Samsung.o : $(USER_DIR)/ir_Samsung.cpp $(USER_DIR)/ir_Samsung.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Samsung.cpp - -ir_Samsung_test.o : ir_Samsung_test.cpp $(USER_DIR)/ir_Samsung.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Samsung_test.cpp - -ir_Samsung_test : $(COMMON_OBJ) ir_Samsung_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Kelvinator.o : $(USER_DIR)/ir_Kelvinator.cpp $(USER_DIR)/ir_Kelvinator.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Kelvinator.cpp - -ir_Kelvinator_test.o : ir_Kelvinator_test.cpp $(USER_DIR)/ir_Kelvinator.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Kelvinator_test.cpp - -ir_Kelvinator_test : $(COMMON_OBJ) ir_Kelvinator_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_JVC.o : $(USER_DIR)/ir_JVC.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_JVC.cpp - -ir_JVC_test.o : ir_JVC_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_JVC_test.cpp - -ir_JVC_test : $(COMMON_OBJ) ir_JVC_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_RCMM.o : $(USER_DIR)/ir_RCMM.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_RCMM.cpp - -ir_RCMM_test.o : ir_RCMM_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_RCMM_test.cpp - -ir_RCMM_test : $(COMMON_OBJ) ir_RCMM_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_LG.o : $(USER_DIR)/ir_LG.h $(USER_DIR)/ir_LG.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_LG.cpp - -ir_LG_test.o : ir_LG_test.cpp $(USER_DIR)/ir_LG.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_LG_test.cpp - -ir_LG_test : $(COMMON_OBJ) ir_LG_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Mitsubishi.o : $(USER_DIR)/ir_Mitsubishi.h $(USER_DIR)/ir_Mitsubishi.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Mitsubishi.cpp - -ir_Mitsubishi_test.o : ir_Mitsubishi_test.cpp $(USER_DIR)/ir_Mitsubishi.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Mitsubishi_test.cpp - -ir_Mitsubishi_test : $(COMMON_OBJ) ir_Mitsubishi_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_MitsubishiHeavy.o : $(USER_DIR)/ir_MitsubishiHeavy.h $(USER_DIR)/ir_MitsubishiHeavy.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_MitsubishiHeavy.cpp - -ir_MitsubishiHeavy_test.o : ir_MitsubishiHeavy_test.cpp $(USER_DIR)/ir_MitsubishiHeavy.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_MitsubishiHeavy_test.cpp - -ir_MitsubishiHeavy_test : $(COMMON_OBJ) ir_MitsubishiHeavy_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Fujitsu.o : $(USER_DIR)/ir_Fujitsu.h $(USER_DIR)/ir_Fujitsu.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Fujitsu.cpp - -ir_Fujitsu_test.o : ir_Fujitsu_test.cpp $(USER_DIR)/ir_Fujitsu.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Fujitsu_test.cpp - -ir_Fujitsu_test : $(COMMON_OBJ) ir_Fujitsu_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Sharp.o : $(USER_DIR)/ir_Sharp.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Sharp.cpp - -ir_Sharp_test.o : ir_Sharp_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Sharp_test.cpp - -ir_Sharp_test : $(COMMON_OBJ) ir_Sharp_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_RC5_RC6.o : $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_RC5_RC6.cpp - -ir_RC5_RC6_test.o : ir_RC5_RC6_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_RC5_RC6_test.cpp - -ir_RC5_RC6_test : $(COMMON_OBJ) ir_RC5_RC6_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Panasonic.o : $(USER_DIR)/ir_Panasonic.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Panasonic.cpp - -ir_Panasonic_test.o : ir_Panasonic_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Panasonic_test.cpp - -ir_Panasonic_test : $(COMMON_OBJ) ir_Panasonic_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Dish.o : $(USER_DIR)/ir_Dish.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Dish.cpp - -ir_Dish_test.o : ir_Dish_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Dish_test.cpp - -ir_Dish_test : $(COMMON_OBJ) ir_Dish_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Whynter.o : $(USER_DIR)/ir_Whynter.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Whynter.cpp - -ir_Whynter_test.o : ir_Whynter_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Whynter_test.cpp - -ir_Whynter_test : $(COMMON_OBJ) ir_Whynter_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Coolix.o : $(USER_DIR)/ir_Coolix.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Coolix.cpp - -ir_Coolix_test.o : ir_Coolix_test.cpp $(USER_DIR)/ir_Coolix.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Coolix_test.cpp - -ir_Coolix_test : $(COMMON_OBJ) ir_Coolix_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Aiwa.o : $(USER_DIR)/ir_Aiwa.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Aiwa.cpp - -ir_Aiwa_test.o : ir_Aiwa_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Aiwa_test.cpp - -ir_Aiwa_test : $(COMMON_OBJ) ir_Aiwa_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Denon.o : $(USER_DIR)/ir_Denon.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Denon.cpp - -ir_Denon_test.o : ir_Denon_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Denon_test.cpp - -ir_Denon_test : $(COMMON_OBJ) ir_Denon_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Sanyo.o : $(USER_DIR)/ir_Sanyo.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sanyo.cpp - -ir_Sanyo_test.o : ir_Sanyo_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Sanyo_test.cpp - -ir_Sanyo_test : $(COMMON_OBJ) ir_Sanyo_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Daikin.o : $(USER_DIR)/ir_Daikin.cpp $(USER_DIR)/ir_Daikin.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Daikin.cpp - -ir_Daikin_test.o : ir_Daikin_test.cpp $(USER_DIR)/ir_Daikin.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Daikin_test.cpp - -ir_Daikin_test : $(COMMON_OBJ) ir_Daikin_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Gree.o : $(USER_DIR)/ir_Gree.cpp $(GTEST_HEADERS) $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Gree.cpp - -ir_Gree_test.o : ir_Gree_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Gree_test.cpp - -ir_Gree_test : $(COMMON_OBJ) ir_Gree_test.o ir_Kelvinator.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Pronto.o : $(USER_DIR)/ir_Pronto.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Pronto.cpp - -ir_Pronto_test.o : ir_Pronto_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Pronto_test.cpp - -ir_Pronto_test : $(COMMON_OBJ) ir_Pronto_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Nikai.o : $(USER_DIR)/ir_Nikai.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Nikai.cpp - -ir_Nikai_test.o : ir_Nikai_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Nikai_test.cpp - -ir_Nikai_test : $(COMMON_OBJ) ir_Nikai_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Toshiba.o : $(USER_DIR)/ir_Toshiba.cpp $(USER_DIR)/ir_Toshiba.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Toshiba.cpp - -ir_Toshiba_test.o : ir_Toshiba_test.cpp $(USER_DIR)/ir_Toshiba.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Toshiba_test.cpp - -ir_Toshiba_test : $(COMMON_OBJ) ir_Toshiba_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Midea.o : $(USER_DIR)/ir_Midea.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Midea.cpp - -ir_Midea_test.o : ir_Midea_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Midea_test.cpp - -ir_Midea_test : $(COMMON_OBJ) ir_Midea_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Magiquest.o : $(USER_DIR)/ir_Magiquest.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Magiquest.cpp - -ir_Magiquest_test.o : ir_Magiquest_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Magiquest_test.cpp - -ir_Magiquest_test : $(COMMON_OBJ) ir_Magiquest_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Lasertag.o : $(USER_DIR)/ir_Lasertag.cpp $(USER_DIR)/ir_RC5_RC6.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lasertag.cpp - -ir_Lasertag_test.o : ir_Lasertag_test.cpp $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Lasertag_test.cpp - -ir_Lasertag_test : $(COMMON_OBJ) ir_Lasertag_test.o ir_RC5_RC6.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Carrier.o : $(USER_DIR)/ir_Carrier.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Carrier.cpp - -ir_Carrier_test.o : ir_Carrier_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Carrier_test.cpp - -ir_Carrier_test : $(COMMON_OBJ) ir_Carrier_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Haier.o : $(USER_DIR)/ir_Haier.cpp $(USER_DIR)/ir_Haier.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Haier.cpp - -ir_Haier_test.o : ir_Haier_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Haier_test.cpp - -ir_Haier_test : $(COMMON_OBJ) ir_Haier_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Hitachi.o : $(USER_DIR)/ir_Hitachi.cpp $(USER_DIR)/ir_Hitachi.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Hitachi.cpp - -ir_Hitachi_test.o : ir_Hitachi_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Hitachi_test.cpp - -ir_Hitachi_test : $(COMMON_OBJ) ir_Hitachi_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_GICable.o : $(USER_DIR)/ir_GICable.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GICable.cpp - -ir_GICable_test.o : ir_GICable_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_GICable_test.cpp - -ir_GICable_test : $(COMMON_OBJ) ir_GICable_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Whirlpool.o : $(USER_DIR)/ir_Whirlpool.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Whirlpool.cpp - -ir_Whirlpool_test.o : ir_Whirlpool_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Whirlpool_test.cpp - -ir_Whirlpool_test : $(COMMON_OBJ) ir_Whirlpool_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Lutron.o : $(USER_DIR)/ir_Lutron.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lutron.cpp - -ir_Lutron_test.o : ir_Lutron_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Lutron_test.cpp - -ir_Lutron_test : $(COMMON_OBJ) ir_Lutron_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Electra.o : $(USER_DIR)/ir_Electra.h $(USER_DIR)/ir_Electra.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Electra.cpp - -ir_Electra_test.o : ir_Electra_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Electra_test.cpp - -ir_Electra_test : $(COMMON_OBJ) ir_Electra_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Pioneer.o : $(USER_DIR)/ir_Pioneer.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Pioneer.cpp - -ir_Pioneer_test.o : ir_Pioneer_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Pioneer_test.cpp - -ir_Pioneer_test : $(COMMON_OBJ) ir_Pioneer_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_MWM.o : $(USER_DIR)/ir_MWM.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_MWM.cpp - -ir_MWM_test.o : ir_MWM_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_MWM_test.cpp - -ir_MWM_test : $(COMMON_OBJ) ir_MWM_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Vestel.o : $(USER_DIR)/ir_Vestel.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Vestel.cpp - -ir_Vestel_test.o : ir_Vestel_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Vestel_test.cpp - -ir_Vestel_test : $(COMMON_OBJ) ir_Vestel_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Teco.o : $(USER_DIR)/ir_Teco.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Teco.cpp - -ir_Teco_test.o : ir_Teco_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Teco_test.cpp - -ir_Teco_test : $(COMMON_OBJ) ir_Teco_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Tcl.o : $(USER_DIR)/ir_Tcl.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Tcl.cpp - -ir_Tcl_test.o : ir_Tcl_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Tcl_test.cpp - -ir_Tcl_test : $(COMMON_OBJ) ir_Tcl_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Lego.o : $(USER_DIR)/ir_Lego.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lego.cpp - -ir_Lego_test.o : ir_Lego_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Lego_test.cpp - -ir_Lego_test : $(COMMON_OBJ) ir_Lego_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Argo.o : $(USER_DIR)/ir_Argo.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Argo.cpp - -ir_Argo_test.o : ir_Argo_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Argo_test.cpp - -ir_Argo_test : $(COMMON_OBJ) ir_Argo_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Trotec.o : $(USER_DIR)/ir_Trotec.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Trotec.cpp - -ir_Trotec_test.o : ir_Trotec_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Trotec_test.cpp - -ir_Trotec_test : $(COMMON_OBJ) ir_Trotec_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Goodweather.o : $(USER_DIR)/ir_Goodweather.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Goodweather.cpp - -ir_Goodweather_test.o : ir_Goodweather_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Goodweather_test.cpp - -ir_Goodweather_test : $(COMMON_OBJ) ir_Goodweather_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Inax.o : $(USER_DIR)/ir_Inax.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Inax.cpp - -ir_Inax_test.o : ir_Inax_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Inax_test.cpp - -ir_Inax_test : $(COMMON_OBJ) ir_Inax_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Neoclima.o : $(USER_DIR)/ir_Neoclima.h $(USER_DIR)/ir_Neoclima.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Neoclima.cpp - -ir_Neoclima_test.o : ir_Neoclima_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Neoclima_test.cpp - -ir_Neoclima_test : $(COMMON_OBJ) ir_Neoclima_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Amcor.o : $(USER_DIR)/ir_Amcor.h $(USER_DIR)/ir_Amcor.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Amcor.cpp - -ir_Amcor_test.o : ir_Amcor_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Amcor_test.cpp - -ir_Amcor_test : $(COMMON_OBJ) ir_Amcor_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Epson.o : $(USER_DIR)/ir_Epson.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Epson.cpp - -ir_Epson_test.o : ir_Epson_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Epson_test.cpp - -ir_Epson_test : $(COMMON_OBJ) ir_Epson_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Symphony.o : $(USER_DIR)/ir_Symphony.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Symphony.cpp - -ir_Symphony_test.o : ir_Symphony_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Symphony_test.cpp - -ir_Symphony_test : $(COMMON_OBJ) ir_Symphony_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Airwell.o : $(USER_DIR)/ir_Airwell.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Airwell.cpp - -ir_Airwell_test.o : ir_Airwell_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Airwell_test.cpp - -ir_Airwell_test : $(COMMON_OBJ) ir_Airwell_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ diff --git a/lib/IRremoteESP8266-2.7.6/tools/Makefile b/lib/IRremoteESP8266-2.7.6/tools/Makefile deleted file mode 100644 index cfbf2e33c..000000000 --- a/lib/IRremoteESP8266-2.7.6/tools/Makefile +++ /dev/null @@ -1,248 +0,0 @@ -# SYNOPSIS: -# -# make [all] - makes everything. -# make clean - removes all files generated by make. - -# Please tweak the following variable definitions as needed by your -# project, except GTEST_HEADERS, which you can use in your own targets -# but shouldn't modify. - - -# Where to find user code. -USER_DIR = ../src - -# Where to find test code. -TEST_DIR = ../test - -INCLUDES = -I$(USER_DIR) -I$(TEST_DIR) -# Flags passed to the preprocessor. -# Set Google Test's header directory as a system directory, such that -# the compiler doesn't generate warnings in Google Test headers. -CPPFLAGS += -DUNIT_TEST -D_IR_LOCALE_=en-AU - -# Flags passed to the C++ compiler. -CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 - -all : gc_decode mode2_decode - -run_tests : all - failed=""; \ - for py_unittest in *_test.py; do \ - echo "RUNNING: $${py_unittest}"; \ - python3 ./$${py_unittest} || failed="$${failed} $${py_unittest}"; \ - done; \ - if [ -n "$${failed}" ]; then \ - echo "FAIL: :-( :-( Unit test(s)$${failed} failed! :-( :-("; exit 1; \ - else \ - echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \ - fi - -clean : - rm -f *.o *.pyc gc_decode mode2_decode - - -# All the IR protocol object files. -PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.o \ - ir_LG.o ir_Mitsubishi.o ir_Fujitsu.o ir_Sharp.o ir_Sanyo.o \ - ir_Denon.o ir_Dish.o ir_Panasonic.o ir_Whynter.o ir_Coolix.o \ - ir_Aiwa.o ir_Sherwood.o ir_Kelvinator.o ir_Daikin.o ir_Gree.o \ - ir_Pronto.o ir_GlobalCache.o ir_Nikai.o ir_Toshiba.o ir_Midea.o \ - ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o ir_Hitachi.o \ - ir_GICable.o ir_Whirlpool.o ir_Lutron.o ir_Electra.o ir_Pioneer.o \ - ir_MWM.o ir_Vestel.o ir_Teco.o ir_Tcl.o ir_Lego.o \ - ir_MitsubishiHeavy.o ir_Goodweather.o ir_Inax.o ir_Argo.o \ - ir_Trotec.o ir_Neoclima.o ir_Amcor.o ir_Epson.o ir_Symphony.o \ - ir_Airwell.o - -# Common object files -COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o IRtext.o IRac.o $(PROTOCOLS) - -# Common dependencies -COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \ - $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \ - $(TEST_DIR)/IRsend_test.h $(USER_DIR)/IRtext.h $(USER_DIR)/i18n.h -# Common test dependencies -COMMON_TEST_DEPS = $(COMMON_DEPS) $(TEST_DIR)/IRsend_test.h - -gc_decode.o : gc_decode.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c gc_decode.cpp - -gc_decode : $(COMMON_OBJ) gc_decode.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -mode2_decode.o : mode2_decode.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c mode2_decode.cpp - -mode2_decode : $(COMMON_OBJ) mode2_decode.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/locale/*.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRtext.cpp - -IRutils.o : $(USER_DIR)/IRutils.cpp $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRutils.cpp - -IRtimer.o : $(USER_DIR)/IRtimer.cpp $(USER_DIR)/IRtimer.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRtimer.cpp - -IRsend.o : $(USER_DIR)/IRsend.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRremoteESP8266.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRsend.cpp - -IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRrecv.cpp - -ir_NEC.o : $(USER_DIR)/ir_NEC.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_NEC.cpp - -ir_GlobalCache.o : $(USER_DIR)/ir_GlobalCache.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GlobalCache.cpp - -ir_Sherwood.o : $(USER_DIR)/ir_Sherwood.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sherwood.cpp - -ir_Sony.o : $(USER_DIR)/ir_Sony.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sony.cpp - -ir_Samsung.o : $(USER_DIR)/ir_Samsung.cpp $(USER_DIR)/ir_Samsung.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Samsung.cpp - -ir_Kelvinator.o : $(USER_DIR)/ir_Kelvinator.cpp $(USER_DIR)/ir_Kelvinator.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Kelvinator.cpp - -ir_Inax.o : $(USER_DIR)/ir_Inax.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Inax.cpp - -ir_JVC.o : $(USER_DIR)/ir_JVC.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_JVC.cpp - -ir_RCMM.o : $(USER_DIR)/ir_RCMM.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_RCMM.cpp - -ir_LG.o : $(USER_DIR)/ir_LG.h $(USER_DIR)/ir_LG.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_LG.cpp - -ir_Mitsubishi.o : $(USER_DIR)/ir_Mitsubishi.h $(USER_DIR)/ir_Mitsubishi.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Mitsubishi.cpp - -ir_MitsubishiHeavy.o : $(USER_DIR)/ir_MitsubishiHeavy.h $(USER_DIR)/ir_MitsubishiHeavy.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_MitsubishiHeavy.cpp - -ir_Fujitsu.o : $(USER_DIR)/ir_Fujitsu.h $(USER_DIR)/ir_Fujitsu.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Fujitsu.cpp - -ir_Sharp.o : $(USER_DIR)/ir_Sharp.h $(USER_DIR)/ir_Sharp.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Sharp.cpp - -ir_RC5_RC6.o : $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_RC5_RC6.cpp - -ir_Panasonic.o : $(USER_DIR)/ir_Panasonic.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Panasonic.cpp - -ir_Dish.o : $(USER_DIR)/ir_Dish.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Dish.cpp - -ir_Whynter.o : $(USER_DIR)/ir_Whynter.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Whynter.cpp - -ir_Coolix.o : $(USER_DIR)/ir_Coolix.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Coolix.cpp - -ir_Aiwa.o : $(USER_DIR)/ir_Aiwa.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Aiwa.cpp - -ir_Denon.o : $(USER_DIR)/ir_Denon.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Denon.cpp - -ir_Sanyo.o : $(USER_DIR)/ir_Sanyo.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sanyo.cpp - -ir_Daikin.o : $(USER_DIR)/ir_Daikin.cpp $(USER_DIR)/ir_Daikin.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Daikin.cpp - -ir_Gree.o : $(USER_DIR)/ir_Gree.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Gree.cpp - -ir_Pronto.o : $(USER_DIR)/ir_Pronto.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Pronto.cpp - -ir_Nikai.o : $(USER_DIR)/ir_Nikai.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Nikai.cpp - -ir_Toshiba.o : $(USER_DIR)/ir_Toshiba.h $(USER_DIR)/ir_Toshiba.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Toshiba.cpp - -ir_Midea.o : $(USER_DIR)/ir_Midea.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Midea.cpp - -ir_Magiquest.o : $(USER_DIR)/ir_Magiquest.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Magiquest.cpp - -ir_Lasertag.o : $(USER_DIR)/ir_Lasertag.cpp $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lasertag.cpp - -ir_Carrier.o : $(USER_DIR)/ir_Carrier.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Carrier.cpp - -ir_Haier.o : $(USER_DIR)/ir_Haier.cpp $(USER_DIR)/ir_Haier.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Haier.cpp - -ir_Hitachi.o : $(USER_DIR)/ir_Hitachi.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Hitachi.cpp - -ir_GICable.o : $(USER_DIR)/ir_GICable.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GICable.cpp - -ir_Whirlpool.o : $(USER_DIR)/ir_Whirlpool.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Whirlpool.cpp - -ir_Lutron.o : $(USER_DIR)/ir_Lutron.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lutron.cpp - -ir_Electra.o : $(USER_DIR)/ir_Electra.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Electra.cpp - -ir_Pioneer.o : $(USER_DIR)/ir_Pioneer.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Pioneer.cpp - -ir_MWM.o : $(USER_DIR)/ir_MWM.cpp $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_MWM.cpp - -ir_Vestel.o : $(USER_DIR)/ir_Vestel.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Vestel.cpp - -ir_Teco.o : $(USER_DIR)/ir_Teco.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Teco.cpp - -ir_Tcl.o : $(USER_DIR)/ir_Tcl.cpp $(USER_DIR)/ir_Tcl.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Tcl.cpp - -ir_Trotec.o : $(USER_DIR)/ir_Trotec.cpp $(USER_DIR)/ir_Trotec.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Trotec.cpp - -ir_Lego.o : $(USER_DIR)/ir_Lego.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lego.cpp - -ir_Argo.o : $(USER_DIR)/ir_Argo.cpp $(USER_DIR)/ir_Argo.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Argo.cpp - -ir_Goodweather.o : $(USER_DIR)/ir_Goodweather.cpp $(USER_DIR)/ir_Goodweather.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Goodweather.cpp - -ir_Neoclima.o : $(USER_DIR)/ir_Neoclima.cpp $(USER_DIR)/ir_Neoclima.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Neoclima.cpp - -ir_Amcor.o : $(USER_DIR)/ir_Amcor.cpp $(USER_DIR)/ir_Amcor.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Amcor.cpp - -ir_Epson.o : $(USER_DIR)/ir_Epson.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Epson.cpp - -ir_Symphony.o : $(USER_DIR)/ir_Symphony.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Symphony.cpp - -ir_Airwell.o : $(USER_DIR)/ir_Airwell.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Airwell.cpp - -IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRac.cpp diff --git a/lib/IRremoteESP8266-2.7.6/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.7/CPPLINT.cfg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/CPPLINT.cfg rename to lib/IRremoteESP8266-2.7.7/CPPLINT.cfg diff --git a/lib/IRremoteESP8266-2.7.6/LICENSE.txt b/lib/IRremoteESP8266-2.7.7/LICENSE.txt similarity index 100% rename from lib/IRremoteESP8266-2.7.6/LICENSE.txt rename to lib/IRremoteESP8266-2.7.7/LICENSE.txt diff --git a/lib/IRremoteESP8266-2.7.6/README.md b/lib/IRremoteESP8266-2.7.7/README.md similarity index 98% rename from lib/IRremoteESP8266-2.7.6/README.md rename to lib/IRremoteESP8266-2.7.7/README.md index 83859d6b6..b3fa60ece 100644 --- a/lib/IRremoteESP8266-2.7.6/README.md +++ b/lib/IRremoteESP8266-2.7.7/README.md @@ -9,8 +9,8 @@ This library enables you to **send _and_ receive** infra-red signals on an [ESP8266](https://github.com/esp8266/Arduino) or an [ESP32](https://github.com/espressif/arduino-esp32) using the [Arduino framework](https://www.arduino.cc/) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* demodulators etc. -## v2.7.6 Now Available -Version 2.7.6 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes. +## v2.7.7 Now Available +Version 2.7.7 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes. #### Upgrading from pre-v2.0 Usage of the library has been slightly changed in v2.0. You will need to change your usage to work with v2.0 and beyond. You can read more about the changes required on our [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page. diff --git a/lib/IRremoteESP8266-2.7.6/README_fr.md b/lib/IRremoteESP8266-2.7.7/README_fr.md similarity index 98% rename from lib/IRremoteESP8266-2.7.6/README_fr.md rename to lib/IRremoteESP8266-2.7.7/README_fr.md index 6b6c6e7d0..9ff560fe8 100644 --- a/lib/IRremoteESP8266-2.7.6/README_fr.md +++ b/lib/IRremoteESP8266-2.7.7/README_fr.md @@ -9,8 +9,8 @@ Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole [ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc. -## v2.7.6 disponible -Version 2.7.6 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants. +## v2.7.7 disponible +Version 2.7.7 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants. #### mise à jour depuis pre-v2.0 L'utilisation de la librairie à un peu changer depuis la version in v2.0. Si vous voulez l'utiliser vous devrez changer votre utilisation aussi. Vous pouvez vous renseigner sur les précondition d'utilisation ici : [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page. diff --git a/lib/IRremoteESP8266-2.7.6/ReleaseNotes.md b/lib/IRremoteESP8266-2.7.7/ReleaseNotes.md similarity index 94% rename from lib/IRremoteESP8266-2.7.6/ReleaseNotes.md rename to lib/IRremoteESP8266-2.7.7/ReleaseNotes.md index 69cc753cd..0e7bc7bc5 100644 --- a/lib/IRremoteESP8266-2.7.6/ReleaseNotes.md +++ b/lib/IRremoteESP8266-2.7.7/ReleaseNotes.md @@ -1,5 +1,36 @@ # Release Notes +## _v2.7.7 (20200519)_ + +**[BREAKING CHANGES]** +- Fix Symphony protocol. (#1107, #1105) + * Now 12 bits and bits are inverted. All previous codes will no longer work. +- IRMQTTServer: Better handle power & mode operations for Home Assistant. (#1099, #1092) + * When `MQTT_CLIMATE_HA_MODE` is enabled (default) this will break previous operation mode resumption when power is changed. + +**[Bug Fixes]** +- Set correct return type for `.calibrate()` (#1095, #1093) + +**[Features]** +- Add basic support for Carrier 40 & 64 bit protocols. (#1125, #1112, #1127) +- Gree: Enable native support for Fahrenheit (#1124, #1121) +- Gree: Add option to control display temp source. (#1120, #1118) +- Add support for Multibrackets protocol. (#1106, #1103) +- Add RawToPronto.py tool & improve `sendPronto()` precision (#1104, #1103) +- Add support for `Doshisha` LED light protocol (#1115) +- Introduce IRrecvDumpV3 with basic OTA update support (#1111) +- Add detailed support for Delonghi A/C (#1098, #1096) +- Improved support for SharpAc. (#1094, #1091) +- Update auto_analyse to use new decode call structure. (#1102, #1097) +- Added Blynk app example (#1090) + +**[Misc]** +- update auto_analyse script to use new param documentation (#1126) +- Improve `raw_to_pronto_code.py` (#1122, #1103) +- Use pattern rules in Makefiles to reduce specific rule (#1110) +- Update list of supported Daikin models. (#1101) + + ## _v2.7.6 (20200425)_ **[Features]** diff --git a/lib/IRremoteESP8266-2.7.6/SupportedProtocols.md b/lib/IRremoteESP8266-2.7.7/SupportedProtocols.md similarity index 88% rename from lib/IRremoteESP8266-2.7.6/SupportedProtocols.md rename to lib/IRremoteESP8266-2.7.7/SupportedProtocols.md index ed4699de2..457da38bb 100644 --- a/lib/IRremoteESP8266-2.7.6/SupportedProtocols.md +++ b/lib/IRremoteESP8266-2.7.7/SupportedProtocols.md @@ -1,6 +1,6 @@ + Last generated: Tue 19 May 2020 11:48:47 +0000 ---> # IR Protocols supported by this library | Protocol | Brand | Model | A/C Model | Detailed A/C Support | @@ -14,9 +14,11 @@ | [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Beko](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | BINR 070/071 split-type A/C
BINR 070/071 split-type A/C
RG57K7(B)/BGEF Remote
RG57K7(B)/BGEF Remote | | Yes | | [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | MS12FU-10HRDN1-QRD0GW(B) A/C
MS12FU-10HRDN1-QRD0GW(B) A/C
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
RG52D/BGE Remote
RG52D/BGE Remote | | Yes | | [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Tokio](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote
AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote | | Yes | -| [Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.cpp) | **[Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.h)** | 17 Series A/C (DAIKIN128)
ARC423A5 remote
ARC433** remote
ARC433B69 remote
ARC477A1 remote
ARC480A5 remote (DAIKIN152)
BRC4C153 remote
BRC52B63 remote (DAIKIN128)
DGS01 remote (DAIKIN64)
FFN-C/FCN-F Series A/C (DAIKIN64)
FTE12HV2S A/C
FTXB09AXVJU A/C (DAIKIN128)
FTXB12AXVJU A/C (DAIKIN128)
FTXZ25NV1B A/C
FTXZ35NV1B A/C
FTXZ50NV1B A/C | | Yes | +| [Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.cpp) | **[Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.h)** | 17 Series A/C (DAIKIN128)
ARC423A5 remote
ARC433** remote
ARC433B69 remote
ARC466A33 remote (DAIKIN)
ARC477A1 remote
ARC480A5 remote (DAIKIN152)
BRC4C153 remote
BRC52B63 remote (DAIKIN128)
DGS01 remote (DAIKIN64)
FFN-C/FCN-F Series A/C (DAIKIN64)
FTE12HV2S A/C
FTXB09AXVJU A/C (DAIKIN128)
FTXB12AXVJU A/C (DAIKIN128)
FTXM-M A/C (DAIKIN)
FTXZ25NV1B A/C
FTXZ35NV1B A/C
FTXZ50NV1B A/C
M Series A/C (DAIKIN) | | Yes | +| [Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.cpp) | **[Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.h)** | PAC A95 | | Yes | | [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Unknown** | | | - | | [Dish](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Dish.cpp) | **DISH NETWORK** | echostar 301 | | - | +| [Doshisha](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Doshisha.cpp) | **Doshisha** | CZ-S32D LED Light
CZ-S38D LED Light
CZ-S50D LED Light
RCZ01 remote | | - | | [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[AUX](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | KFR-35GW/BpNFW=3 A/C
YKR-T/011 remote | | Yes | | [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | Classic INV 17 / AXW12DCS A/C
YKR-M/003E remote | | Yes | | [Epson](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Epson.cpp) | **Unknown** | | | - | @@ -26,6 +28,7 @@ | [GlobalCache](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GlobalCache.cpp) | **Unknown** | | | - | | [Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.cpp) | **[Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.h)** | ZH/JT-03 remote | | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[EKOKAI](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | A/C | YAW1F
YBOFB | Yes | +| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | YAA1FBF remote
YB1F2F remote | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | YBOFB remote
YBOFB2 remote | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[RusClimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | EACS/I-09HAR_X/N3 A/C
YAW1F remote | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Ultimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | Heat Pump | YAW1F
YBOFB | Yes | @@ -48,6 +51,7 @@ | [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | HC3000 Projector
KM14A 0179213 remote
MS-GK24VA A/C
TV | | Yes | | [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | 001CP T7WE10714 remote
KPOA remote
MSH-A24WV / MUH-A24WV A/C
PEAD-RP71JAA Ducted A/C | | Yes | | [MitsubishiHeavy](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.cpp) | **[Mitsubishi Heavy Industries](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.h)** | RKX502A001C remote
RLA502A700B remote
SRKxxZJ-S A/C
SRKxxZM-S A/C
SRKxxZMXA-S A/C | | Yes | +| [Multibrackets](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Multibrackets.cpp) | **Multibrackets** | Motorized Swing mount large - 4500 | | - | | [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Aloka](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | SleepyLights LED Lamp | | - | | [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | 42TL838 LCD TV | | - | | [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Yamaha](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | RAV561 remote
RXV585B A/V Receiver | | - | @@ -60,10 +64,14 @@ | [RCMM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RCMM.cpp) | **Microsoft** | XBOX 360 | | - | | [Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.cpp) | **[Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.h)** | AR09FSSDAWKNFA A/C
AR12HSSDBWKNEU A/C
AR12KSFPEWQNET A/C
AR12NXCXAWKXEU A/C
DB63-03556X003 remote
DB93-16761C remote
IEC-R03 remote
UA55H6300 TV | | Yes | | [Sanyo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sanyo.cpp) | **Unknown** | | | - | -| [Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.h)** | AH-AxSAY A/C
AY-ZP40KR A/C
LC-52D62U TV | | Yes | +| [Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.h)** | AH-AxSAY A/C
AH-XP10NRY A/C
AY-ZP40KR A/C
CRMC-820JBEZ remote
LC-52D62U TV | | Yes | | [Sherwood](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sherwood.cpp) | **Sherwood** | RC-138 remote
RD6505(B) Receiver | | - | | [Sony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sony.cpp) | **Sony** | HT-CT380 Soundbar (Uses 38kHz & 3 repeats) | | - | +| [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Blyss** | Owen-SW-5 3 Fan
WP-YK8 090218 remote | | - | +| [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **SamHop** | SM3015 Fan Remote Control
SM5021 Encoder chip
SM5032 Decoder chip | | - | +| [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Satellite Electronic** | ID6 Remote
JY199I Fan driver
JY199I-L Fan driver | | - | | [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Symphony** | Air Cooler 3Di | | - | +| [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Westinghouse** | 78095 Remote
Ceiling fan | | - | | [Tcl](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.cpp) | **[Leberg](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.h)** | LBS-TOR07 A/C | | Yes | | [Teco](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.cpp) | **[Alaska](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.h)** | SAC9010QC A/C
SAC9010QC remote | | Yes | | [Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.h)** | Akita EVO II
RAS 18SKP-ES
RAS-B13N3KV2
RAS-B13N3KVP-E
WC-L03SE
WH-TA04NE | | Yes | @@ -89,6 +97,8 @@ - AMCOR - ARGO - CARRIER_AC +- CARRIER_AC40 +- CARRIER_AC64 - COOLIX - DAIKIN - DAIKIN128 @@ -98,8 +108,10 @@ - DAIKIN2 - DAIKIN216 - DAIKIN64 +- DELONGHI_AC - DENON - DISH +- DOSHISHA - ELECTRA_AC - EPSON - FUJITSU_AC @@ -130,6 +142,7 @@ - MITSUBISHI_AC - MITSUBISHI_HEAVY_152 - MITSUBISHI_HEAVY_88 +- MULTIBRACKETS - MWM - NEC - NEC_LIKE diff --git a/lib/IRremoteESP8266-2.7.7/docs/README.md b/lib/IRremoteESP8266-2.7.7/docs/README.md new file mode 100644 index 000000000..fea1f636f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/docs/README.md @@ -0,0 +1 @@ +Documentation goes here. diff --git a/lib/IRremoteESP8266-2.7.7/docs/_config.yml b/lib/IRremoteESP8266-2.7.7/docs/_config.yml new file mode 100644 index 000000000..c74188174 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/BlynkIrRemote.ino b/lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/BlynkIrRemote.ino new file mode 100644 index 000000000..6e659bd64 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/BlynkIrRemote.ino @@ -0,0 +1,196 @@ +/************************************************************* + Emulate a physical remote via an iOS and Android App. + Copyright Gaurav Barwalia 2020 + + Download latest Blynk library here: + https://github.com/blynkkk/blynk-library/releases/latest + + Blynk is a platform with iOS and Android apps to control + Arduino, Raspberry Pi and the likes over the Internet. + You can easily build graphic interfaces for all your + projects by simply dragging and dropping widgets. + + Downloads, docs, tutorials: http://www.blynk.cc + Sketch generator: http://examples.blynk.cc + Blynk community: http://community.blynk.cc + Follow us: http://www.fb.com/blynkapp + http://twitter.com/blynk_app + + Blynk library is licensed under MIT license + This example code is in public domain. + + ************************************************************* + This example runs directly on ESP8266 chip. + + Note: This requires ESP8266 support package: + https://github.com/esp8266/Arduino + + Please be sure to select the right ESP8266 module + in the Tools -> Board menu! + + Change WiFi ssid, pass, and Blynk auth token to run :) + Feel free to apply it to any other example. It's simple! + *************************************************************/ + + /* + // After decoding received below codes + + // Power button + +18:12:33.993 -> Protocol : NEC +18:12:33.993 -> Code : 0x1FE50AF (32 Bits) +18:12:33.993 -> uint16_t rawData[71] = {9040, 4452, 606, 532, 606, 534, 630, 508, 604, 534, 604, 534, 604, 534, 630, 506, 606, 1646, 632, 1620, 606, 1646, 632, 1620, 630, 1620, 632, 1620, 630, 1620, 606, 1646, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1620, 632, 506, 632, 508, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1624, 628, 506, 632, 1620, 632, 1618, 632, 1620, 632, 1620, 632, 39016, 9040, 2216, 630}; // NEC 1FE50AF +18:12:34.027 -> uint32_t address = 0x80; +18:12:34.027 -> uint32_t command = 0xA; +18:12:34.027 -> uint64_t data = 0x1FE50AF; + +//mute button + +18:13:27.215 -> Protocol : NEC +18:13:27.215 -> Code : 0x1FE30CF (32 Bits) +18:13:27.215 -> uint16_t rawData[71] = {9094, 4398, 660, 478, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 660, 480, 658, 1594, 658, 1594, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 1592, 658, 1594, 660, 480, 658, 480, 658, 480, 658, 1592, 658, 1592, 658, 480, 658, 480, 660, 478, 660, 478, 658, 1594, 658, 1592, 658, 480, 658, 480, 658, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 38986, 9094, 2162, 658}; // NEC 1FE30CF +18:13:27.285 -> uint32_t address = 0x80; +18:13:27.285 -> uint32_t command = 0xC; +18:13:27.285 -> uint64_t data = 0x1FE30CF; + +//Vol. low + +18:14:44.427 -> Protocol : NEC +18:14:44.427 -> Code : 0x1FEC03F (32 Bits) +18:14:44.427 -> uint16_t rawData[71] = {9120, 4374, 658, 478, 658, 480, 658, 480, 658, 480, 658, 482, 658, 478, 658, 480, 658, 1594, 658, 1594, 658, 1592, 660, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 1592, 660, 480, 658, 1594, 658, 1594, 658, 480, 658, 480, 660, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 1594, 660, 1592, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 39002, 9094, 2162, 658}; // NEC 1FEC03F +18:14:44.497 -> uint32_t address = 0x80; +18:14:44.497 -> uint32_t command = 0x3; +18:14:44.497 -> uint64_t data = 0x1FEC03F; + +//VOl. High + +18:15:11.677 -> Protocol : NEC +18:15:11.677 -> Code : 0x1FE40BF (32 Bits) +18:15:11.677 -> uint16_t rawData[67] = {9068, 4426, 630, 506, 632, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 656, 1594, 630, 1622, 632, 1620, 630, 1622, 630, 508, 630, 508, 630, 1622, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 656, 482, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 632, 1620, 630}; // NEC 1FE40BF +18:15:11.747 -> uint32_t address = 0x80; +18:15:11.747 -> uint32_t command = 0x2; +18:15:11.747 -> uint64_t data = 0x1FE40BF; + +//Play/Pause + +18:15:38.529 -> Protocol : NEC +18:15:38.529 -> Code : 0x1FE32CD (32 Bits) +18:15:38.529 -> uint16_t rawData[71] = {9092, 4400, 632, 504, 658, 480, 658, 480, 632, 506, 658, 480, 658, 480, 658, 482, 632, 1620, 658, 1594, 658, 1594, 632, 1618, 658, 1594, 658, 1594, 632, 1620, 632, 1618, 634, 506, 658, 480, 658, 480, 632, 1620, 658, 1598, 656, 478, 658, 478, 658, 1594, 658, 482, 632, 1618, 632, 1618, 634, 506, 632, 506, 658, 1594, 632, 1620, 658, 480, 632, 1620, 658, 38998, 9094, 2162, 660}; // NEC 1FE32CD +18:15:38.564 -> uint32_t address = 0x80; +18:15:38.564 -> uint32_t command = 0x4C; +18:15:38.564 -> uint64_t data = 0x1FE32CD; + +//Song Back + +18:16:07.527 -> Protocol : NEC +18:16:07.527 -> Code : 0x1FEA05F (32 Bits) +18:16:07.562 -> uint16_t rawData[71] = {9590, 3902, 684, 452, 686, 456, 652, 480, 660, 480, 684, 456, 656, 480, 658, 480, 684, 1568, 658, 1594, 658, 1594, 686, 1566, 658, 1594, 684, 1568, 658, 1594, 658, 1594, 686, 454, 684, 1568, 686, 454, 658, 1594, 684, 454, 686, 454, 658, 480, 660, 480, 684, 454, 658, 482, 658, 1594, 682, 456, 658, 1596, 658, 1594, 686, 1568, 660, 1592, 684, 1568, 686, 38982, 9098, 2162, 684}; // NEC 1FEA05F +18:16:07.597 -> uint32_t address = 0x80; +18:16:07.597 -> uint32_t command = 0x5; +18:16:07.597 -> uint64_t data = 0x1FEA05F; + +//Song Forward + +18:17:20.541 -> Protocol : NEC +18:17:20.541 -> Code : 0x1FEE01F (32 Bits) +18:17:20.575 -> uint16_t rawData[71] = {9068, 4424, 632, 506, 630, 506, 632, 508, 606, 532, 632, 506, 630, 508, 630, 508, 632, 1620, 632, 1620, 632, 1620, 604, 1646, 606, 1646, 630, 1622, 604, 1646, 632, 1620, 606, 534, 630, 1622, 604, 1646, 630, 1622, 604, 534, 630, 508, 604, 534, 606, 534, 630, 508, 630, 508, 606, 534, 606, 532, 630, 1622, 604, 1646, 632, 1620, 604, 1648, 604, 1646, 604, 39040, 9040, 2216, 604}; // NEC 1FEE01F +18:17:20.610 -> uint32_t address = 0x80; +18:17:20.610 -> uint32_t command = 0x7; +18:17:20.610 -> uint64_t data = 0x1FEE01F; + + */ + +// check complete video tutorial here for program explanation https://www.youtube.com/watch?v=LqmkDKu54XY&t=17s + +/* Comment this out to disable prints and save space */ +#define BLYNK_PRINT Serial + +#if defined(ESP8266) +#include +#include +#else +#include +#endif // ESP8266 +#if defined(ESP32) +#include +#endif // ESP32 + +// IR library +#include +#include + +const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). +IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message. + +// You should get Auth Token in the Blynk App. +// Go to the Project Settings (nut icon). +char auth[] = "YourAuthToken"; + +// Your WiFi credentials. +// Set password to "" for open networks. +char ssid[] = "YourNetworkName"; +char pass[] = "YourPassword"; + + BLYNK_WRITE(V51) { // Power button + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE50AF); + } + } + + BLYNK_WRITE(V52) { // Mute button + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE30CF); + } + } + + BLYNK_WRITE(V53) { // Song Forward + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEE01F); + } + } + + BLYNK_WRITE(V54) { // Song Backward + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEA05F); + delay(10); // double tap back button to back one song + irsend.sendNEC(0x1FEA05F); + } + } + + BLYNK_WRITE(V55) { // Volume -- + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEC03F); + } + } + + BLYNK_WRITE(V56) { // Volume ++ + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE40BF); + } + } + + BLYNK_WRITE(V57) { // Play/Pause + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE32CD); + } + } + +void setup() { +#if defined(BLYNK_PRINT) + // Debug console + Serial.begin(115200); +#endif // BLYNK_PRINT + + Blynk.begin(auth, ssid, pass); +} + +void loop() { + Blynk.run(); +} diff --git a/lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/platformio.ini new file mode 100644 index 000000000..58f6b0f30 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/platformio.ini @@ -0,0 +1,34 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +platform = espressif8266 +build_flags = ; -D_IR_LOCALE_=en-AU + +[common] +lib_deps_builtin = +lib_deps_external = + Blynk + +[common_esp8266] +lib_deps_external = + ${common.lib_deps_builtin} + ${common.lib_deps_external} + +[common_esp32] +lib_deps_external = + ${common.lib_deps_builtin} + ${common.lib_deps_external} + +[env:nodemcuv2] +board = nodemcuv2 +lib_deps = ${common_esp8266.lib_deps_external} + +[env:esp32dev] +platform = espressif32 +board = esp32dev +lib_deps = ${common_esp32.lib_deps_external} diff --git a/lib/IRremoteESP8266-2.7.6/examples/CommonAcControl/CommonAcControl.ino b/lib/IRremoteESP8266-2.7.7/examples/CommonAcControl/CommonAcControl.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/CommonAcControl/CommonAcControl.ino rename to lib/IRremoteESP8266-2.7.7/examples/CommonAcControl/CommonAcControl.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/CommonAcControl/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/CommonAcControl/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/CommonAcControl/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/CommonAcControl/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/ControlSamsungAC/ControlSamsungAC.ino b/lib/IRremoteESP8266-2.7.7/examples/ControlSamsungAC/ControlSamsungAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/ControlSamsungAC/ControlSamsungAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/ControlSamsungAC/ControlSamsungAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/ControlSamsungAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/ControlSamsungAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/ControlSamsungAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/ControlSamsungAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/DumbIRRepeater/DumbIRRepeater.ino b/lib/IRremoteESP8266-2.7.7/examples/DumbIRRepeater/DumbIRRepeater.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/DumbIRRepeater/DumbIRRepeater.ino rename to lib/IRremoteESP8266-2.7.7/examples/DumbIRRepeater/DumbIRRepeater.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/DumbIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/DumbIRRepeater/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/DumbIRRepeater/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/DumbIRRepeater/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRGCSendDemo/IRGCSendDemo.ino b/lib/IRremoteESP8266-2.7.7/examples/IRGCSendDemo/IRGCSendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRGCSendDemo/IRGCSendDemo.ino rename to lib/IRremoteESP8266-2.7.7/examples/IRGCSendDemo/IRGCSendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRGCSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRGCSendDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRGCSendDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/IRGCSendDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRGCTCPServer/IRGCTCPServer.ino b/lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/IRGCTCPServer.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRGCTCPServer/IRGCTCPServer.ino rename to lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/IRGCTCPServer.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRGCTCPServer/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRGCTCPServer/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRMQTTServer/IRMQTTServer.h b/lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.h similarity index 96% rename from lib/IRremoteESP8266-2.7.6/examples/IRMQTTServer/IRMQTTServer.h rename to lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.h index c886b705b..b283e330f 100644 --- a/lib/IRremoteESP8266-2.7.6/examples/IRMQTTServer/IRMQTTServer.h +++ b/lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.h @@ -102,11 +102,23 @@ const uint32_t kMqttReconnectTime = 5000; // Delay(ms) between reconnect tries. #define MQTT_CLIMATE_STAT "stat" // Sub-topic for the climate stat topics. // Enable sending/receiving climate via JSON. `true` cost ~5k of program space. #define MQTT_CLIMATE_JSON false + // Use Home Assistant-style operation modes. -// i.e. Change the climate mode to "off" when turning the power "off". +// TL;DR: Power and Mode are linked together. One changes the other. +// i.e. +// - When power is set to "off", the mode is set to "off". +// - When the mode changes from "off" to something else, power is set to "on". // See: https://www.home-assistant.io/components/climate.mqtt/#modes -// Change to false, if your home automation system doesn't like this. +// *** WARNING *** +// This setting will cause IRMQTTServer to forget what the previous operation +// mode was. e.g. a power "on" -> "off" -> "on" will cause it to use the +// default mode for your A/C, not the previous mode. +// Typically this is "Auto" or "Cool" mode. +// Change to false, if your home automation system doesn't like this, or if +// you want IRMQTTServer to be the authoritative source for controling your +// A/C. #define MQTT_CLIMATE_HA_MODE true + // Do we send an IR message when we reboot and recover the existing A/C state? // If set to `false` you may miss requested state changes while the ESP was // down. If set to `true`, it will resend the previous desired state sent to the @@ -239,7 +251,7 @@ const uint16_t kJsonAcStateMaxSize = 1024; // Bytes // ----------------- End of User Configuration Section ------------------------- // Constants -#define _MY_VERSION_ "v1.4.9" +#define _MY_VERSION_ "v1.5.0" const uint8_t kRebootTime = 15; // Seconds const uint8_t kQuickDisplayTime = 2; // Seconds diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRMQTTServer/IRMQTTServer.ino b/lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.ino similarity index 99% rename from lib/IRremoteESP8266-2.7.6/examples/IRMQTTServer/IRMQTTServer.ino rename to lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.ino index c04c1e23b..6bf504b0e 100644 --- a/lib/IRremoteESP8266-2.7.6/examples/IRMQTTServer/IRMQTTServer.ino +++ b/lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.ino @@ -2964,40 +2964,47 @@ void updateClimate(stdAc::state_t *state, const String str, *state = jsonToState(*state, payload.c_str()); else #endif // MQTT_CLIMATE_JSON - if (str.equals(prefix + KEY_PROTOCOL)) + if (str.equals(prefix + KEY_PROTOCOL)) { state->protocol = strToDecodeType(payload.c_str()); - else if (str.equals(prefix + KEY_MODEL)) + } else if (str.equals(prefix + KEY_MODEL)) { state->model = IRac::strToModel(payload.c_str()); - else if (str.equals(prefix + KEY_POWER)) + } else if (str.equals(prefix + KEY_POWER)) { state->power = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_MODE)) +#if MQTT_CLIMATE_HA_MODE + if (!state->power) state->mode = stdAc::opmode_t::kOff; +#endif // MQTT_CLIMATE_HA_MODE + } else if (str.equals(prefix + KEY_MODE)) { state->mode = IRac::strToOpmode(payload.c_str()); - else if (str.equals(prefix + KEY_TEMP)) +#if MQTT_CLIMATE_HA_MODE + state->power = (state->mode != stdAc::opmode_t::kOff); +#endif // MQTT_CLIMATE_HA_MODE + } else if (str.equals(prefix + KEY_TEMP)) { state->degrees = payload.toFloat(); - else if (str.equals(prefix + KEY_FANSPEED)) + } else if (str.equals(prefix + KEY_FANSPEED)) { state->fanspeed = IRac::strToFanspeed(payload.c_str()); - else if (str.equals(prefix + KEY_SWINGV)) + } else if (str.equals(prefix + KEY_SWINGV)) { state->swingv = IRac::strToSwingV(payload.c_str()); - else if (str.equals(prefix + KEY_SWINGH)) + } else if (str.equals(prefix + KEY_SWINGH)) { state->swingh = IRac::strToSwingH(payload.c_str()); - else if (str.equals(prefix + KEY_QUIET)) + } else if (str.equals(prefix + KEY_QUIET)) { state->quiet = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_TURBO)) + } else if (str.equals(prefix + KEY_TURBO)) { state->turbo = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_ECONO)) + } else if (str.equals(prefix + KEY_ECONO)) { state->econo = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_LIGHT)) + } else if (str.equals(prefix + KEY_LIGHT)) { state->light = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_BEEP)) + } else if (str.equals(prefix + KEY_BEEP)) { state->beep = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_FILTER)) + } else if (str.equals(prefix + KEY_FILTER)) { state->filter = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_CLEAN)) + } else if (str.equals(prefix + KEY_CLEAN)) { state->clean = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_CELSIUS)) + } else if (str.equals(prefix + KEY_CELSIUS)) { state->celsius = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_SLEEP)) + } else if (str.equals(prefix + KEY_SLEEP)) { state->sleep = payload.toInt(); + } } bool sendClimate(const String topic_prefix, const bool retain, diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRMQTTServer/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRMQTTServer/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRServer/IRServer.ino b/lib/IRremoteESP8266-2.7.7/examples/IRServer/IRServer.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRServer/IRServer.ino rename to lib/IRremoteESP8266-2.7.7/examples/IRServer/IRServer.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRServer/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRServer/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRServer/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/IRServer/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRrecvDemo/IRrecvDemo.ino b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/IRrecvDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRrecvDemo/IRrecvDemo.ino rename to lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/IRrecvDemo.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRrecvDemo/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRrecvDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRrecvDump/IRrecvDump.ino b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/IRrecvDump.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRrecvDump/IRrecvDump.ino rename to lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/IRrecvDump.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRrecvDump/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRrecvDump/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV2/IRrecvDumpV2.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRrecvDumpV2/IRrecvDumpV2.ino rename to lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV2/IRrecvDumpV2.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRrecvDumpV2/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV2/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRrecvDumpV2/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV2/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/BaseOTA.h b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/BaseOTA.h new file mode 100644 index 000000000..5dd8db541 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/BaseOTA.h @@ -0,0 +1,71 @@ +// Copyright 2020 Christian Nilsson (@nikize) +// Based on public Arduino BasicOTA example + +#ifndef EXAMPLES_IRRECVDUMPV3_BASEOTA_H_ +#define EXAMPLES_IRRECVDUMPV3_BASEOTA_H_ + +#ifndef OTA_ENABLE +#define OTA_ENABLE false +#endif // OTA_ENABLE + +#if OTA_ENABLE + +#include +#include +#include +#include + +void OTAwifi() { + // start default wifi (previously saved on the ESP) for OTA + WiFi.mode(WIFI_STA); + WiFi.begin(); +} + +void OTAinit() { + // See BasicOTA ESP example for source and settings + + ArduinoOTA + .onStart([]() { + String type; + if (ArduinoOTA.getCommand() == U_FLASH) + type = "sketch"; + else + type = "filesystem"; + + Serial.println("Start updating " + type); + }) + .onEnd([]() { + Serial.println("\nEnd"); + }) + .onProgress([](unsigned int progress, unsigned int total) { + Serial.printf("Progress: %u%%\r", (progress / (total / 100))); + }) + .onError([](ota_error_t error) { + Serial.printf("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); + else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); + else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); + else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); + else if (error == OTA_END_ERROR) Serial.println("End Failed"); + }); + + ArduinoOTA.begin(); + Serial.println(); + if (WiFi.waitForConnectResult() == WL_CONNECTED) { + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + } else { + Serial.println("Wifi Connection Failed."); + } +} + +void OTAloopHandler() { + ArduinoOTA.handle(); +} + +#else // OTA_ENABLE +void OTAwifi() {} +void OTAinit() {} +void OTAloopHandler() {} +#endif // OTA_ENABLE +#endif // EXAMPLES_IRRECVDUMPV3_BASEOTA_H_ diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/IRrecvDumpV3.ino b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/IRrecvDumpV3.ino new file mode 100644 index 000000000..419ca9b4c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/IRrecvDumpV3.ino @@ -0,0 +1,166 @@ +/* + * IRremoteESP8266: IRrecvDumpV3 - dump details of IR codes with IRrecv + * An IR detector/demodulator must be connected to the input kRecvPin. + * + * Copyright 2009 Ken Shirriff, http://arcfn.com + * Copyright 2017-2019 David Conran + * + * Example circuit diagram: + * https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-receiving + * + * Changes: + * Version 1.1 May, 2020 + * - Create DumpV3 from DumpV2 + * - Add OTA Base + * Version 1.0 October, 2019 + * - Internationalisation (i18n) support. + * - Stop displaying the legacy raw timing info. + * Version 0.5 June, 2019 + * - Move A/C description to IRac.cpp. + * Version 0.4 July, 2018 + * - Minor improvements and more A/C unit support. + * Version 0.3 November, 2017 + * - Support for A/C decoding for some protocols. + * Version 0.2 April, 2017 + * - Decode from a copy of the data so we can start capturing faster thus + * reduce the likelihood of miscaptures. + * Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, + */ + +// Allow over air update +// #define OTA_ENABLE true +#include "BaseOTA.h" + +#include +#include +#include +#include +#include +#include + +// ==================== start of TUNEABLE PARAMETERS ==================== +// An IR detector/demodulator is connected to GPIO pin 14 +// e.g. D5 on a NodeMCU board. +// Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. +const uint16_t kRecvPin = 14; + +// The Serial connection baud rate. +// i.e. Status message will be sent to the PC at this baud rate. +// Try to avoid slow speeds like 9600, as you will miss messages and +// cause other problems. 115200 (or faster) is recommended. +// NOTE: Make sure you set your Serial Monitor to the same speed. +const uint32_t kBaudRate = 115200; + +// As this program is a special purpose capture/decoder, let us use a larger +// than normal buffer so we can handle Air Conditioner remote codes. +const uint16_t kCaptureBufferSize = 1024; + +// kTimeout is the Nr. of milli-Seconds of no-more-data before we consider a +// message ended. +// This parameter is an interesting trade-off. The longer the timeout, the more +// complex a message it can capture. e.g. Some device protocols will send +// multiple message packets in quick succession, like Air Conditioner remotes. +// Air Coniditioner protocols often have a considerable gap (20-40+ms) between +// packets. +// The downside of a large timeout value is a lot of less complex protocols +// send multiple messages when the remote's button is held down. The gap between +// them is often also around 20+ms. This can result in the raw data be 2-3+ +// times larger than needed as it has captured 2-3+ messages in a single +// capture. Setting a low timeout value can resolve this. +// So, choosing the best kTimeout value for your use particular case is +// quite nuanced. Good luck and happy hunting. +// NOTE: Don't exceed kMaxTimeoutMs. Typically 130ms. +#if DECODE_AC +// Some A/C units have gaps in their protocols of ~40ms. e.g. Kelvinator +// A value this large may swallow repeats of some protocols +const uint8_t kTimeout = 50; +#else // DECODE_AC +// Suits most messages, while not swallowing many repeats. +const uint8_t kTimeout = 15; +#endif // DECODE_AC +// Alternatives: +// const uint8_t kTimeout = 90; +// Suits messages with big gaps like XMP-1 & some aircon units, but can +// accidentally swallow repeated messages in the rawData[] output. +// +// const uint8_t kTimeout = kMaxTimeoutMs; +// This will set it to our currently allowed maximum. +// Values this high are problematic because it is roughly the typical boundary +// where most messages repeat. +// e.g. It will stop decoding a message and start sending it to serial at +// precisely the time when the next message is likely to be transmitted, +// and may miss it. + +// Set the smallest sized "UNKNOWN" message packets we actually care about. +// This value helps reduce the false-positive detection rate of IR background +// noise as real messages. The chances of background IR noise getting detected +// as a message increases with the length of the kTimeout value. (See above) +// The downside of setting this message too large is you can miss some valid +// short messages for protocols that this library doesn't yet decode. +// +// Set higher if you get lots of random short UNKNOWN messages when nothing +// should be sending a message. +// Set lower if you are sure your setup is working, but it doesn't see messages +// from your device. (e.g. Other IR remotes work.) +// NOTE: Set this value very high to effectively turn off UNKNOWN detection. +const uint16_t kMinUnknownSize = 12; + +// Legacy (No longer supported!) +// +// Change to `true` if you miss/need the old "Raw Timing[]" display. +#define LEGACY_TIMING_INFO false +// ==================== end of TUNEABLE PARAMETERS ==================== + +// Use turn on the save buffer feature for more complete capture coverage. +IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true); +decode_results results; // Somewhere to store the results + +// This section of code runs only once at start-up. +void setup() { + OTAwifi(); // start default wifi (previously saved on the ESP) for OTA +#if defined(ESP8266) + Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY); +#else // ESP8266 + Serial.begin(kBaudRate, SERIAL_8N1); +#endif // ESP8266 + while (!Serial) // Wait for the serial connection to be establised. + delay(50); + Serial.printf("\n" D_STR_IRRECVDUMP_STARTUP "\n", kRecvPin); + OTAinit(); // setup OTA handlers and show IP +#if DECODE_HASH + // Ignore messages with less than minimum on or off pulses. + irrecv.setUnknownThreshold(kMinUnknownSize); +#endif // DECODE_HASH + irrecv.enableIRIn(); // Start the receiver +} + +// The repeating section of the code +void loop() { + // Check if the IR code has been received. + if (irrecv.decode(&results)) { + // Display a crude timestamp. + uint32_t now = millis(); + Serial.printf(D_STR_TIMESTAMP " : %06u.%03u\n", now / 1000, now % 1000); + // Check if we got an IR message that was to big for our capture buffer. + if (results.overflow) + Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize); + // Display the library version the message was captured with. + Serial.println(D_STR_LIBRARY " : v" _IRREMOTEESP8266_VERSION_ "\n"); + // Display the basic output of what we found. + Serial.print(resultToHumanReadableBasic(&results)); + // Display any extra A/C info if we have it. + String description = IRAcUtils::resultAcToString(&results); + if (description.length()) Serial.println(D_STR_MESGDESC ": " + description); + yield(); // Feed the WDT as the text output can take a while to print. +#if LEGACY_TIMING_INFO + // Output legacy RAW timing info of the result. + Serial.println(resultToTimingInfo(&results)); + yield(); // Feed the WDT (again) +#endif // LEGACY_TIMING_INFO + // Output the results as source code + Serial.println(resultToSourceCode(&results)); + Serial.println(); // Blank line between entries + yield(); // Feed the WDT (again) + } + OTAloopHandler(); +} diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/platformio.ini new file mode 100644 index 000000000..62fa06d3a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/platformio.ini @@ -0,0 +1,52 @@ +[platformio] +src_dir = . + +[env] +; Default platform +platform = espressif8266 +; Default board +board = nodemcuv2 +framework = arduino +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +board = nodemcuv2 +; build_flags = -D_IR_LOCALE_=en-AU + +[env:esp32dev] +platform = espressif32 +board = esp32dev +; build_flags = -D_IR_LOCALE_=en-AU + +[env:de-CH] +build_flags = -D_IR_LOCALE_=de-CH ; German (Swiss) + +[env:de-DE] +build_flags = -D_IR_LOCALE_=de-DE ; German + +[env:en-AU] +build_flags = -D_IR_LOCALE_=en-AU ; English (Australian) (Default) + +[env:en-IE] +build_flags = -D_IR_LOCALE_=en-IE ; English (Irish) + +[env:en-UK] +build_flags = -D_IR_LOCALE_=en-UK ; English (UK) + +[env:en-US] +build_flags = -D_IR_LOCALE_=en-US ; English (Simplified) (USA) + +[env:es-ES] +build_flags = -D_IR_LOCALE_=es-ES ; Spanish + +[env:fr-FR] +build_flags = -D_IR_LOCALE_=fr-FR ; French + +[env:it-IT] +build_flags = -D_IR_LOCALE_=it-IT ; Italian + +[env:zh-CN] +build_flags = -D_IR_LOCALE_=zh-CN ; Chinese (Simplified) diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRsendDemo/IRsendDemo.ino b/lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/IRsendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRsendDemo/IRsendDemo.ino rename to lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/IRsendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRsendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRsendDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRsendProntoDemo/IRsendProntoDemo.ino b/lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/IRsendProntoDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRsendProntoDemo/IRsendProntoDemo.ino rename to lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/IRsendProntoDemo.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/IRsendProntoDemo/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/IRsendProntoDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino b/lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino rename to lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/JVCPanasonicSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/JVCPanasonicSendDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/LGACSend/LGACSend.ino b/lib/IRremoteESP8266-2.7.7/examples/LGACSend/LGACSend.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/LGACSend/LGACSend.ino rename to lib/IRremoteESP8266-2.7.7/examples/LGACSend/LGACSend.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/LGACSend/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/LGACSend/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/LGACSend/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/LGACSend/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/SmartIRRepeater/SmartIRRepeater.ino b/lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/SmartIRRepeater.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/SmartIRRepeater/SmartIRRepeater.ino rename to lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/SmartIRRepeater.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/SmartIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/SmartIRRepeater/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnArgoAC/TurnOnArgoAC.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/TurnOnArgoAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnArgoAC/TurnOnArgoAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/TurnOnArgoAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnArgoAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnArgoAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnDaikinAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnDaikinAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnFujitsuAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnFujitsuAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnGreeAC/TurnOnGreeAC.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/TurnOnGreeAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnGreeAC/TurnOnGreeAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/TurnOnGreeAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnGreeAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnGreeAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnKelvinatorAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnKelvinatorAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnMitsubishiAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnMitsubishiAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnMitsubishiHeavyAc/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnMitsubishiHeavyAc/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnPanasonicAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnPanasonicAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnToshibaAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnToshibaAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino b/lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/TurnOnTrotecAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/TurnOnTrotecAC/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/README.md b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/README.md similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/README.md rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/README.md diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/Web-AC-control.ino b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/Web-AC-control.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/Web-AC-control.ino rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/Web-AC-control.ino diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/platformio.ini rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/printscreen.png b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/printscreen.png similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/printscreen.png rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/printscreen.png diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/favicon.ico b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/favicon.ico similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/favicon.ico rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/favicon.ico diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_1_off.svg b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_1_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_1_off.svg rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_1_off.svg diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_1_on.svg b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_1_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_1_on.svg rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_1_on.svg diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_2_off.svg b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_2_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_2_off.svg rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_2_off.svg diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_2_on.svg b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_2_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_2_on.svg rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_2_on.svg diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_3_off.svg b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_3_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_3_off.svg rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_3_off.svg diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_3_on.svg b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_3_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_3_on.svg rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_3_on.svg diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_4_off.svg b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_4_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_4_off.svg rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_4_off.svg diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_4_on.svg b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_4_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/level_4_on.svg rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_4_on.svg diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/ui.html b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/ui.html similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/ui.html rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/ui.html diff --git a/lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/ui.js b/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/ui.js similarity index 100% rename from lib/IRremoteESP8266-2.7.6/examples/Web-AC-control/upload/ui.js rename to lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/ui.js diff --git a/lib/IRremoteESP8266-2.7.6/keywords.txt b/lib/IRremoteESP8266-2.7.7/keywords.txt similarity index 94% rename from lib/IRremoteESP8266-2.7.6/keywords.txt rename to lib/IRremoteESP8266-2.7.7/keywords.txt index 7b9e356af..907cba220 100644 --- a/lib/IRremoteESP8266-2.7.6/keywords.txt +++ b/lib/IRremoteESP8266-2.7.7/keywords.txt @@ -31,6 +31,7 @@ IRDaikin2 KEYWORD1 IRDaikin216 KEYWORD1 IRDaikin64 KEYWORD1 IRDaikinESP KEYWORD1 +IRDelonghiAc KEYWORD1 IRElectraAc KEYWORD1 IRFujitsuAC KEYWORD1 IRGoodweatherAc KEYWORD1 @@ -126,6 +127,7 @@ checkZjsSig KEYWORD2 checkZmsSig KEYWORD2 checksum KEYWORD2 clearOnTimerFlag KEYWORD2 +clearPowerSpecial KEYWORD2 clearSensorTemp KEYWORD2 clearSleepTimerFlag KEYWORD2 cmpStates KEYWORD2 @@ -153,6 +155,8 @@ decodeAmcor KEYWORD2 decodeArgo KEYWORD2 decodeCOOLIX KEYWORD2 decodeCarrierAC KEYWORD2 +decodeCarrierAC40 KEYWORD2 +decodeCarrierAC64 KEYWORD2 decodeDISH KEYWORD2 decodeDaikin KEYWORD2 decodeDaikin128 KEYWORD2 @@ -162,7 +166,9 @@ decodeDaikin176 KEYWORD2 decodeDaikin2 KEYWORD2 decodeDaikin216 KEYWORD2 decodeDaikin64 KEYWORD2 +decodeDelonghiAc KEYWORD2 decodeDenon KEYWORD2 +decodeDoshisha KEYWORD2 decodeElectraAC KEYWORD2 decodeEpson KEYWORD2 decodeFujitsuAC KEYWORD2 @@ -191,6 +197,7 @@ decodeMitsubishi136 KEYWORD2 decodeMitsubishi2 KEYWORD2 decodeMitsubishiAC KEYWORD2 decodeMitsubishiHeavy KEYWORD2 +decodeMultibrackets KEYWORD2 decodeNEC KEYWORD2 decodeNeoclima KEYWORD2 decodeNikai KEYWORD2 @@ -217,6 +224,7 @@ decodeVestelAc KEYWORD2 decodeWhirlpoolAC KEYWORD2 decodeWhynter KEYWORD2 defaultBits KEYWORD2 +delonghiac KEYWORD2 disableIRIn KEYWORD2 disableOffTimer KEYWORD2 disableOnTimer KEYWORD2 @@ -229,6 +237,7 @@ enableOffTimer KEYWORD2 enableOnTimer KEYWORD2 enableSleepTimer KEYWORD2 enableTimer KEYWORD2 +encodeDoshisha KEYWORD2 encodeJVC KEYWORD2 encodeLG KEYWORD2 encodeMagiQuest KEYWORD2 @@ -252,6 +261,7 @@ get3D KEYWORD2 get8CHeat KEYWORD2 getBeep KEYWORD2 getBit KEYWORD2 +getBoost KEYWORD2 getBreeze KEYWORD2 getBufSize KEYWORD2 getButton KEYWORD2 @@ -265,7 +275,9 @@ getCurrTime KEYWORD2 getCurrentDay KEYWORD2 getCurrentTime KEYWORD2 getDisplay KEYWORD2 +getDisplayTempSource KEYWORD2 getEcono KEYWORD2 +getEconoToggle KEYWORD2 getEye KEYWORD2 getEyeAuto KEYWORD2 getFan KEYWORD2 @@ -299,9 +311,9 @@ getOnTimer KEYWORD2 getOnTimerEnabled KEYWORD2 getOutsideQuiet KEYWORD2 getPower KEYWORD2 +getPowerSpecial KEYWORD2 getPowerToggle KEYWORD2 getPowerful KEYWORD2 -getPreviousPower KEYWORD2 getPurify KEYWORD2 getQuiet KEYWORD2 getRClevel KEYWORD2 @@ -314,6 +326,7 @@ getSilent KEYWORD2 getSleep KEYWORD2 getSleepTime KEYWORD2 getSleepTimerEnabled KEYWORD2 +getSpecial KEYWORD2 getSpeed KEYWORD2 getStartClock KEYWORD2 getStateLength KEYWORD2 @@ -331,12 +344,16 @@ getSwingVerticalPosition KEYWORD2 getTemp KEYWORD2 getTempOffset KEYWORD2 getTempRaw KEYWORD2 +getTempUnit KEYWORD2 getTime KEYWORD2 getTimer KEYWORD2 getTimerEnabled KEYWORD2 +getTimerTime KEYWORD2 +getTimerType KEYWORD2 getTolerance KEYWORD2 getTurbo KEYWORD2 getUseCelsius KEYWORD2 +getUseFahrenheit KEYWORD2 getVane KEYWORD2 getWeeklyTimerEnable KEYWORD2 getWiFi KEYWORD2 @@ -362,6 +379,7 @@ isOffTimerActive KEYWORD2 isOffTimerEnabled KEYWORD2 isOnTimerActive KEYWORD2 isOnTimerEnabled KEYWORD2 +isPowerSpecial KEYWORD2 isProtocolSupported KEYWORD2 isSpecialState KEYWORD2 isSwingVToggle KEYWORD2 @@ -380,6 +398,7 @@ matchAtLeast KEYWORD2 matchBytes KEYWORD2 matchData KEYWORD2 matchGeneric KEYWORD2 +matchGenericConstBitTime KEYWORD2 matchManchester KEYWORD2 matchMark KEYWORD2 matchSpace KEYWORD2 @@ -417,6 +436,8 @@ sendAmcor KEYWORD2 sendArgo KEYWORD2 sendCOOLIX KEYWORD2 sendCarrierAC KEYWORD2 +sendCarrierAC40 KEYWORD2 +sendCarrierAC64 KEYWORD2 sendDISH KEYWORD2 sendDaikin KEYWORD2 sendDaikin128 KEYWORD2 @@ -427,7 +448,9 @@ sendDaikin2 KEYWORD2 sendDaikin216 KEYWORD2 sendDaikin64 KEYWORD2 sendData KEYWORD2 +sendDelonghiAc KEYWORD2 sendDenon KEYWORD2 +sendDoshisha KEYWORD2 sendElectraAC KEYWORD2 sendEpson KEYWORD2 sendExtended KEYWORD2 @@ -464,6 +487,7 @@ sendMitsubishi2 KEYWORD2 sendMitsubishiAC KEYWORD2 sendMitsubishiHeavy152 KEYWORD2 sendMitsubishiHeavy88 KEYWORD2 +sendMultibrackets KEYWORD2 sendNEC KEYWORD2 sendNeoclima KEYWORD2 sendNikai KEYWORD2 @@ -503,6 +527,7 @@ setAuto KEYWORD2 setBeep KEYWORD2 setBit KEYWORD2 setBits KEYWORD2 +setBoost KEYWORD2 setBreeze KEYWORD2 setButton KEYWORD2 setClean KEYWORD2 @@ -514,7 +539,9 @@ setCurrTime KEYWORD2 setCurrentDay KEYWORD2 setCurrentTime KEYWORD2 setDisplay KEYWORD2 +setDisplayTempSource KEYWORD2 setEcono KEYWORD2 +setEconoToggle KEYWORD2 setEye KEYWORD2 setEyeAuto KEYWORD2 setFan KEYWORD2 @@ -552,9 +579,9 @@ setOnTimerActive KEYWORD2 setOnTimerEnabled KEYWORD2 setOutsideQuiet KEYWORD2 setPower KEYWORD2 +setPowerSpecial KEYWORD2 setPowerToggle KEYWORD2 setPowerful KEYWORD2 -setPreviousPower KEYWORD2 setPurify KEYWORD2 setQuiet KEYWORD2 setRaw KEYWORD2 @@ -565,6 +592,7 @@ setSensorTemp KEYWORD2 setSensorTempRaw KEYWORD2 setSilent KEYWORD2 setSleep KEYWORD2 +setSpecial KEYWORD2 setSpeed KEYWORD2 setStartClock KEYWORD2 setStopClock KEYWORD2 @@ -578,6 +606,7 @@ setSwingVToggle KEYWORD2 setSwingVertical KEYWORD2 setTemp KEYWORD2 setTempRaw KEYWORD2 +setTempUnit KEYWORD2 setTime KEYWORD2 setTimer KEYWORD2 setTimerActive KEYWORD2 @@ -586,6 +615,7 @@ setTolerance KEYWORD2 setTurbo KEYWORD2 setUnknownThreshold KEYWORD2 setUseCelsius KEYWORD2 +setUseFahrenheit KEYWORD2 setVane KEYWORD2 setWeeklyTimerEnable KEYWORD2 setWiFi KEYWORD2 @@ -666,6 +696,8 @@ ARRAH2E LITERAL1 ARREB1E LITERAL1 ARRY4 LITERAL1 CARRIER_AC LITERAL1 +CARRIER_AC40 LITERAL1 +CARRIER_AC64 LITERAL1 CARRIER_AC_BITS LITERAL1 COOLIX LITERAL1 COOLIX_BITS LITERAL1 @@ -695,6 +727,8 @@ DECODE_AIWA_RC_T501 LITERAL1 DECODE_AMCOR LITERAL1 DECODE_ARGO LITERAL1 DECODE_CARRIER_AC LITERAL1 +DECODE_CARRIER_AC40 LITERAL1 +DECODE_CARRIER_AC64 LITERAL1 DECODE_COOLIX LITERAL1 DECODE_DAIKIN LITERAL1 DECODE_DAIKIN128 LITERAL1 @@ -704,8 +738,10 @@ DECODE_DAIKIN176 LITERAL1 DECODE_DAIKIN2 LITERAL1 DECODE_DAIKIN216 LITERAL1 DECODE_DAIKIN64 LITERAL1 +DECODE_DELONGHI_AC LITERAL1 DECODE_DENON LITERAL1 DECODE_DISH LITERAL1 +DECODE_DOSHISHA LITERAL1 DECODE_ELECTRA_AC LITERAL1 DECODE_EPSON LITERAL1 DECODE_FUJITSU_AC LITERAL1 @@ -736,6 +772,7 @@ DECODE_MITSUBISHI136 LITERAL1 DECODE_MITSUBISHI2 LITERAL1 DECODE_MITSUBISHIHEAVY LITERAL1 DECODE_MITSUBISHI_AC LITERAL1 +DECODE_MULTIBRACKETS LITERAL1 DECODE_MWM LITERAL1 DECODE_NEC LITERAL1 DECODE_NEOCLIMA LITERAL1 @@ -763,6 +800,7 @@ DECODE_TROTEC LITERAL1 DECODE_VESTEL_AC LITERAL1 DECODE_WHIRLPOOL_AC LITERAL1 DECODE_WHYNTER LITERAL1 +DELONGHI_AC LITERAL1 DENON LITERAL1 DENON_48_BITS LITERAL1 DENON_BITS LITERAL1 @@ -771,6 +809,7 @@ DG11J13A LITERAL1 DG11J191 LITERAL1 DISH LITERAL1 DISH_BITS LITERAL1 +DOSHISHA LITERAL1 ELECTRA_AC LITERAL1 ENABLE_NOISE_FILTER_OPTION LITERAL1 EPSON LITERAL1 @@ -963,6 +1002,7 @@ MITSUBISHI_AC_VANE_AUTO_MOVE LITERAL1 MITSUBISHI_BITS LITERAL1 MITSUBISHI_HEAVY_152 LITERAL1 MITSUBISHI_HEAVY_88 LITERAL1 +MULTIBRACKETS LITERAL1 MWM LITERAL1 NEC LITERAL1 NEC_BITS LITERAL1 @@ -1003,6 +1043,8 @@ SEND_AIWA_RC_T501 LITERAL1 SEND_AMCOR LITERAL1 SEND_ARGO LITERAL1 SEND_CARRIER_AC LITERAL1 +SEND_CARRIER_AC40 LITERAL1 +SEND_CARRIER_AC64 LITERAL1 SEND_COOLIX LITERAL1 SEND_DAIKIN LITERAL1 SEND_DAIKIN128 LITERAL1 @@ -1012,8 +1054,10 @@ SEND_DAIKIN176 LITERAL1 SEND_DAIKIN2 LITERAL1 SEND_DAIKIN216 LITERAL1 SEND_DAIKIN64 LITERAL1 +SEND_DELONGHI_AC LITERAL1 SEND_DENON LITERAL1 SEND_DISH LITERAL1 +SEND_DOSHISHA LITERAL1 SEND_ELECTRA_AC LITERAL1 SEND_EPSON LITERAL1 SEND_FUJITSU_AC LITERAL1 @@ -1043,6 +1087,7 @@ SEND_MITSUBISHI136 LITERAL1 SEND_MITSUBISHI2 LITERAL1 SEND_MITSUBISHIHEAVY LITERAL1 SEND_MITSUBISHI_AC LITERAL1 +SEND_MULTIBRACKETS LITERAL1 SEND_MWM LITERAL1 SEND_NEC LITERAL1 SEND_NEOCLIMA LITERAL1 @@ -1252,8 +1297,24 @@ kBottomStr LITERAL1 kBreezeStr LITERAL1 kButtonStr LITERAL1 kCancelStr LITERAL1 +kCarrierAc40BitMark LITERAL1 +kCarrierAc40Bits LITERAL1 +kCarrierAc40HdrMark LITERAL1 +kCarrierAc40HdrSpace LITERAL1 +kCarrierAc40MinRepeat LITERAL1 +kCarrierAc40OneSpace LITERAL1 +kCarrierAc40ZeroSpace LITERAL1 +kCarrierAc64BitMark LITERAL1 +kCarrierAc64Bits LITERAL1 +kCarrierAc64Gap LITERAL1 +kCarrierAc64HdrMark LITERAL1 +kCarrierAc64HdrSpace LITERAL1 +kCarrierAc64MinRepeat LITERAL1 +kCarrierAc64OneSpace LITERAL1 +kCarrierAc64ZeroSpace LITERAL1 kCarrierAcBitMark LITERAL1 kCarrierAcBits LITERAL1 +kCarrierAcFreq LITERAL1 kCarrierAcGap LITERAL1 kCarrierAcHdrMark LITERAL1 kCarrierAcHdrSpace LITERAL1 @@ -1596,6 +1657,7 @@ kDaikin64SleepBit LITERAL1 kDaikin64SwingVBit LITERAL1 kDaikin64TempOffset LITERAL1 kDaikin64TempSize LITERAL1 +kDaikin64ToleranceDelta LITERAL1 kDaikin64ZeroSpace LITERAL1 kDaikinAuto LITERAL1 kDaikinBeepLoud LITERAL1 @@ -1701,6 +1763,51 @@ kDayStr LITERAL1 kDaysStr LITERAL1 kDefaultESP32Timer LITERAL1 kDefaultMessageGap LITERAL1 +kDelonghiAcAuto LITERAL1 +kDelonghiAcBitMark LITERAL1 +kDelonghiAcBits LITERAL1 +kDelonghiAcBoostBit LITERAL1 +kDelonghiAcChecksumOffset LITERAL1 +kDelonghiAcChecksumSize LITERAL1 +kDelonghiAcCool LITERAL1 +kDelonghiAcDefaultRepeat LITERAL1 +kDelonghiAcDry LITERAL1 +kDelonghiAcFan LITERAL1 +kDelonghiAcFanAuto LITERAL1 +kDelonghiAcFanHigh LITERAL1 +kDelonghiAcFanLow LITERAL1 +kDelonghiAcFanMedium LITERAL1 +kDelonghiAcFanOffset LITERAL1 +kDelonghiAcFanSize LITERAL1 +kDelonghiAcFreq LITERAL1 +kDelonghiAcGap LITERAL1 +kDelonghiAcHdrMark LITERAL1 +kDelonghiAcHdrSpace LITERAL1 +kDelonghiAcHoursSize LITERAL1 +kDelonghiAcMinsSize LITERAL1 +kDelonghiAcModeOffset LITERAL1 +kDelonghiAcModeSize LITERAL1 +kDelonghiAcOffTimerEnableBit LITERAL1 +kDelonghiAcOffTimerHoursOffset LITERAL1 +kDelonghiAcOffTimerMinsOffset LITERAL1 +kDelonghiAcOnTimerEnableBit LITERAL1 +kDelonghiAcOnTimerHoursOffset LITERAL1 +kDelonghiAcOnTimerMinsOffset LITERAL1 +kDelonghiAcOneSpace LITERAL1 +kDelonghiAcOverhead LITERAL1 +kDelonghiAcPowerBit LITERAL1 +kDelonghiAcSleepBit LITERAL1 +kDelonghiAcTempAutoDryMode LITERAL1 +kDelonghiAcTempFanMode LITERAL1 +kDelonghiAcTempMaxC LITERAL1 +kDelonghiAcTempMaxF LITERAL1 +kDelonghiAcTempMinC LITERAL1 +kDelonghiAcTempMinF LITERAL1 +kDelonghiAcTempOffset LITERAL1 +kDelonghiAcTempSize LITERAL1 +kDelonghiAcTempUnitBit LITERAL1 +kDelonghiAcTimerMax LITERAL1 +kDelonghiAcZeroSpace LITERAL1 kDenon48Bits LITERAL1 kDenonBitMark LITERAL1 kDenonBitMarkTicks LITERAL1 @@ -1734,6 +1841,15 @@ kDishRptSpaceTicks LITERAL1 kDishTick LITERAL1 kDishZeroSpace LITERAL1 kDishZeroSpaceTicks LITERAL1 +kDisplayTempStr LITERAL1 +kDoshishaBitMark LITERAL1 +kDoshishaBits LITERAL1 +kDoshishaFreq LITERAL1 +kDoshishaHdrMark LITERAL1 +kDoshishaHdrSpace LITERAL1 +kDoshishaOneSpace LITERAL1 +kDoshishaOverhead LITERAL1 +kDoshishaZeroSpace LITERAL1 kDownStr LITERAL1 kDry LITERAL1 kDryStr LITERAL1 @@ -1909,6 +2025,12 @@ kGreeBlockFooter LITERAL1 kGreeBlockFooterBits LITERAL1 kGreeCool LITERAL1 kGreeDefaultRepeat LITERAL1 +kGreeDisplayTempInside LITERAL1 +kGreeDisplayTempOff LITERAL1 +kGreeDisplayTempOffset LITERAL1 +kGreeDisplayTempOutside LITERAL1 +kGreeDisplayTempSet LITERAL1 +kGreeDisplayTempSize LITERAL1 kGreeDry LITERAL1 kGreeFan LITERAL1 kGreeFanAuto LITERAL1 @@ -1922,8 +2044,10 @@ kGreeHdrSpace LITERAL1 kGreeHeat LITERAL1 kGreeIFeelOffset LITERAL1 kGreeLightOffset LITERAL1 -kGreeMaxTemp LITERAL1 -kGreeMinTemp LITERAL1 +kGreeMaxTempC LITERAL1 +kGreeMaxTempF LITERAL1 +kGreeMinTempC LITERAL1 +kGreeMinTempF LITERAL1 kGreeMsgSpace LITERAL1 kGreeOneSpace LITERAL1 kGreePower1Offset LITERAL1 @@ -1942,6 +2066,8 @@ kGreeSwingMiddleUp LITERAL1 kGreeSwingSize LITERAL1 kGreeSwingUp LITERAL1 kGreeSwingUpAuto LITERAL1 +kGreeTempExtraDegreeFOffset LITERAL1 +kGreeTempOffset LITERAL1 kGreeTempSize LITERAL1 kGreeTimerEnabledOffset LITERAL1 kGreeTimerHalfHrOffset LITERAL1 @@ -1951,6 +2077,7 @@ kGreeTimerMax LITERAL1 kGreeTimerTensHrOffset LITERAL1 kGreeTimerTensHrSize LITERAL1 kGreeTurboOffset LITERAL1 +kGreeUseFahrenheitOffset LITERAL1 kGreeWiFiOffset LITERAL1 kGreeXfanOffset LITERAL1 kGreeZeroSpace LITERAL1 @@ -2191,6 +2318,7 @@ kInaxMinRepeat LITERAL1 kInaxOneSpace LITERAL1 kInaxTick LITERAL1 kInaxZeroSpace LITERAL1 +kInsideStr LITERAL1 kIonStr LITERAL1 kJvcBitMark LITERAL1 kJvcBitMarkTicks LITERAL1 @@ -2661,6 +2789,13 @@ kModeStr LITERAL1 kModelStr LITERAL1 kMouldStr LITERAL1 kMoveStr LITERAL1 +kMultibracketsBits LITERAL1 +kMultibracketsDefaultRepeat LITERAL1 +kMultibracketsFooterSpace LITERAL1 +kMultibracketsFreq LITERAL1 +kMultibracketsHdrMark LITERAL1 +kMultibracketsTick LITERAL1 +kMultibracketsTolerance LITERAL1 kNAStr LITERAL1 kNECBits LITERAL1 kNecBitMark LITERAL1 @@ -2917,6 +3052,22 @@ kRcmmRptLength LITERAL1 kRcmmRptLengthTicks LITERAL1 kRcmmTick LITERAL1 kRcmmTolerance LITERAL1 +kRcz01ChannelMask LITERAL1 +kRcz01CheckExpected LITERAL1 +kRcz01CheckMask LITERAL1 +kRcz01CommandLevel1 LITERAL1 +kRcz01CommandLevel2 LITERAL1 +kRcz01CommandLevel3 LITERAL1 +kRcz01CommandLevel4 LITERAL1 +kRcz01CommandLevelDown LITERAL1 +kRcz01CommandLevelUp LITERAL1 +kRcz01CommandMask LITERAL1 +kRcz01CommandNightLight LITERAL1 +kRcz01CommandOff LITERAL1 +kRcz01CommandOn LITERAL1 +kRcz01CommandSwitchChannel LITERAL1 +kRcz01CommandTimmer30 LITERAL1 +kRcz01CommandTimmer60 LITERAL1 kRepeat LITERAL1 kRepeatStr LITERAL1 kRight LITERAL1 @@ -3023,20 +3174,21 @@ kSensorStr LITERAL1 kSensorTempStr LITERAL1 kSetStr LITERAL1 kSharpAcAuto LITERAL1 +kSharpAcBitCleanOffset LITERAL1 +kSharpAcBitIonOffset LITERAL1 kSharpAcBitMark LITERAL1 -kSharpAcBitPowerOffset LITERAL1 -kSharpAcBitPreviousPowerOffset LITERAL1 +kSharpAcBitTimerEnabled LITERAL1 +kSharpAcBitTimerType LITERAL1 kSharpAcBits LITERAL1 -kSharpAcButtonFan LITERAL1 -kSharpAcButtonOffset LITERAL1 -kSharpAcButtonPowerMode LITERAL1 -kSharpAcButtonSize LITERAL1 -kSharpAcButtonTemp LITERAL1 -kSharpAcByteButton LITERAL1 +kSharpAcByteClean LITERAL1 kSharpAcByteFan LITERAL1 +kSharpAcByteIon LITERAL1 kSharpAcByteMode LITERAL1 -kSharpAcBytePower LITERAL1 +kSharpAcBytePowerSpecial LITERAL1 +kSharpAcByteSpecial LITERAL1 +kSharpAcByteSwing LITERAL1 kSharpAcByteTemp LITERAL1 +kSharpAcByteTimer LITERAL1 kSharpAcCool LITERAL1 kSharpAcDefaultRepeat LITERAL1 kSharpAcDry LITERAL1 @@ -3054,8 +3206,35 @@ kSharpAcHeat LITERAL1 kSharpAcMaxTemp LITERAL1 kSharpAcMinTemp LITERAL1 kSharpAcModeSize LITERAL1 +kSharpAcOffTimerType LITERAL1 +kSharpAcOnTimerType LITERAL1 kSharpAcOneSpace LITERAL1 +kSharpAcPowerOff LITERAL1 +kSharpAcPowerOn LITERAL1 +kSharpAcPowerOnFromOff LITERAL1 +kSharpAcPowerSetSpecialOff LITERAL1 +kSharpAcPowerSetSpecialOffset LITERAL1 +kSharpAcPowerSetSpecialOn LITERAL1 +kSharpAcPowerSpecialSize LITERAL1 +kSharpAcPowerTimerSetting LITERAL1 +kSharpAcPowerUnknown LITERAL1 +kSharpAcSpecialFan LITERAL1 +kSharpAcSpecialPower LITERAL1 +kSharpAcSpecialSwing LITERAL1 +kSharpAcSpecialTempEcono LITERAL1 +kSharpAcSpecialTimer LITERAL1 +kSharpAcSpecialTimerHalfHour LITERAL1 +kSharpAcSpecialTurbo LITERAL1 kSharpAcStateLength LITERAL1 +kSharpAcSwingNoToggle LITERAL1 +kSharpAcSwingOffset LITERAL1 +kSharpAcSwingSize LITERAL1 +kSharpAcSwingToggle LITERAL1 +kSharpAcTimerHoursMax LITERAL1 +kSharpAcTimerHoursOff LITERAL1 +kSharpAcTimerHoursOffset LITERAL1 +kSharpAcTimerHoursSize LITERAL1 +kSharpAcTimerIncrement LITERAL1 kSharpAcZeroSpace LITERAL1 kSharpAddressBits LITERAL1 kSharpAddressMask LITERAL1 @@ -3117,7 +3296,6 @@ kSwingVToggleStr LITERAL1 kSymphonyBits LITERAL1 kSymphonyDefaultRepeat LITERAL1 kSymphonyFooterGap LITERAL1 -kSymphonyFooterMark LITERAL1 kSymphonyOneMark LITERAL1 kSymphonyOneSpace LITERAL1 kSymphonyZeroMark LITERAL1 diff --git a/lib/IRremoteESP8266-2.7.6/library.json b/lib/IRremoteESP8266-2.7.7/library.json similarity index 88% rename from lib/IRremoteESP8266-2.7.6/library.json rename to lib/IRremoteESP8266-2.7.7/library.json index c2780ac6c..abf2f8070 100644 --- a/lib/IRremoteESP8266-2.7.6/library.json +++ b/lib/IRremoteESP8266-2.7.7/library.json @@ -1,6 +1,6 @@ { "name": "IRremoteESP8266", - "version": "2.7.6", + "version": "2.7.7", "keywords": "infrared, ir, remote, esp8266, esp32", "description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)", "repository": @@ -37,6 +37,11 @@ "name": "Massimiliano Pinto", "url": "https://github.com/pintomax/", "maintainer": true + }, + { + "name": "Christian Nilsson", + "url": "https://github.com/NiKiZe", + "maintainer": true } ], "frameworks": "arduino", diff --git a/lib/IRremoteESP8266-2.7.6/library.properties b/lib/IRremoteESP8266-2.7.7/library.properties similarity index 89% rename from lib/IRremoteESP8266-2.7.6/library.properties rename to lib/IRremoteESP8266-2.7.7/library.properties index b67edbce0..16c4f3bc6 100644 --- a/lib/IRremoteESP8266-2.7.6/library.properties +++ b/lib/IRremoteESP8266-2.7.7/library.properties @@ -1,7 +1,7 @@ name=IRremoteESP8266 -version=2.7.6 +version=2.7.7 author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff -maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto +maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto, Christian Nilsson sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32) paragraph=This library enables you to send and receive infra-red signals on an ESP8266 or an ESP32. category=Device Control diff --git a/lib/IRremoteESP8266-2.7.6/platformio.ini b/lib/IRremoteESP8266-2.7.7/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.6/platformio.ini rename to lib/IRremoteESP8266-2.7.7/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.6/pylintrc b/lib/IRremoteESP8266-2.7.7/pylintrc similarity index 100% rename from lib/IRremoteESP8266-2.7.6/pylintrc rename to lib/IRremoteESP8266-2.7.7/pylintrc diff --git a/lib/IRremoteESP8266-2.7.6/src/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.7/src/CPPLINT.cfg similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/CPPLINT.cfg rename to lib/IRremoteESP8266-2.7.7/src/CPPLINT.cfg diff --git a/lib/IRremoteESP8266-2.7.6/src/IRac.cpp b/lib/IRremoteESP8266-2.7.7/src/IRac.cpp similarity index 97% rename from lib/IRremoteESP8266-2.7.6/src/IRac.cpp rename to lib/IRremoteESP8266-2.7.7/src/IRac.cpp index abf450df9..3e56b0a46 100644 --- a/lib/IRremoteESP8266-2.7.6/src/IRac.cpp +++ b/lib/IRremoteESP8266-2.7.7/src/IRac.cpp @@ -126,6 +126,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_DAIKIN64 case decode_type_t::DAIKIN64: #endif +#if SEND_DELONGHI_AC + case decode_type_t::DELONGHI_AC: +#endif #if SEND_ELECTRA_AC case decode_type_t::ELECTRA_AC: #endif @@ -488,6 +491,22 @@ void IRac::daikin64(IRDaikin64 *ac, } #endif // SEND_DAIKIN64 +#if SEND_DELONGHI_AC +void IRac::delonghiac(IRDelonghiAc *ac, + const bool on, const stdAc::opmode_t mode, const bool celsius, + const float degrees, const stdAc::fanspeed_t fan, + const bool turbo, const int16_t sleep) { + ac->begin(); + ac->setPower(on); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees, !celsius); + ac->setFan(ac->convertFan(fan)); + ac->setBoost(turbo); + ac->setSleep(sleep >= 0); + ac->send(); +} +#endif // SEND_DELONGHI_AC + #if SEND_ELECTRA_AC void IRac::electra(IRElectraAc *ac, const bool on, const stdAc::opmode_t mode, @@ -600,15 +619,15 @@ void IRac::goodweather(IRGoodweatherAc *ac, #if SEND_GREE void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model, - const bool on, const stdAc::opmode_t mode, const float degrees, - const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, - const bool turbo, const bool light, const bool clean, - const int16_t sleep) { + const bool on, const stdAc::opmode_t mode, const bool celsius, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool turbo, + const bool light, const bool clean, const int16_t sleep) { ac->begin(); ac->setModel(model); ac->setPower(on); ac->setMode(ac->convertMode(mode)); - ac->setTemp(degrees); + ac->setTemp(degrees, !celsius); ac->setFan(ac->convertFan(fan)); ac->setSwingVertical(swingv == stdAc::swingv_t::kAuto, // Set auto flag. ac->convertSwingV(swingv)); @@ -1059,25 +1078,38 @@ void IRac::samsung(IRSamsungAc *ac, void IRac::sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, - const float degrees, const stdAc::fanspeed_t fan) { + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool turbo, + const bool filter, const bool clean) { ac->begin(); ac->setPower(on, prev_power); ac->setMode(ac->convertMode(mode)); ac->setTemp(degrees); ac->setFan(ac->convertFan(fan)); - // No Vertical swing setting available. + ac->setSwingToggle(swingv != stdAc::swingv_t::kOff); + // Econo deliberately not used as it cycles through 3 modes uncontrolably. + // ac->setEconoToggle(econo); + ac->setIon(filter); // No Horizontal swing setting available. // No Quiet setting available. - // No Turbo setting available. // No Light setting available. - // No Econo setting available. - // No Filter setting available. - // No Clean setting available. // No Beep setting available. // No Sleep setting available. // No Clock setting available. // Do setMode() again as it can affect fan speed and temp. ac->setMode(ac->convertMode(mode)); + // Clean after mode, as it can affect the mode, temp & fan speed. + if (clean) { + // A/C needs to be off before we can enter clean mode. + ac->setPower(false, prev_power); + ac->send(); + } + ac->setClean(clean); + if (turbo) { + ac->send(); // Send the current state. + // Set up turbo mode as it needs to be sent after everything else. + ac->setTurbo(true); + } ac->send(); } #endif // SEND_SHARP_AC @@ -1284,8 +1316,9 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired, case decode_type_t::ELECTRA_AC: result.light = desired.light ^ prev->light; break; - case decode_type_t::MIDEA: case decode_type_t::HITACHI_AC424: + case decode_type_t::MIDEA: + case decode_type_t::SHARP_AC: if ((desired.swingv == stdAc::swingv_t::kOff) ^ (prev->swingv == stdAc::swingv_t::kOff)) // It changed, so toggle. result.swingv = stdAc::swingv_t::kAuto; @@ -1459,6 +1492,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { break; } #endif // SEND_DAIKIN64 +#if SEND_DELONGHI_AC + case DELONGHI_AC: + { + IRDelonghiAc ac(_pin, _inverted, _modulation); + delonghiac(&ac, send.power, send.mode, send.celsius, degC, send.fanspeed, + send.turbo, send.sleep); + break; + } +#endif // SEND_DELONGHI_AC #if SEND_ELECTRA_AC case ELECTRA_AC: { @@ -1493,9 +1535,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { { IRGreeAC ac(_pin, (gree_ac_remote_model_t)send.model, _inverted, _modulation); - gree(&ac, (gree_ac_remote_model_t)send.model, send.power, send.mode, degC, - send.fanspeed, send.swingv, send.turbo, send.light, send.clean, - send.sleep); + gree(&ac, (gree_ac_remote_model_t)send.model, send.power, send.mode, + send.celsius, send.degrees, send.fanspeed, send.swingv, send.turbo, + send.light, send.clean, send.sleep); break; } #endif // SEND_GREE @@ -1660,7 +1702,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { IRSharpAc ac(_pin, _inverted, _modulation); bool prev_power = !send.power; if (prev != NULL) prev_power = prev->power; - sharp(&ac, send.power, prev_power, send.mode, degC, send.fanspeed); + sharp(&ac, send.power, prev_power, send.mode, degC, send.fanspeed, + send.swingv, send.turbo, send.filter, send.clean); break; } #endif // SEND_SHARP_AC @@ -2107,7 +2150,14 @@ namespace IRAcUtils { ac.setRaw(result->value); // Daikin64 uses value instead of state. return ac.toString(); } -#endif // DECODE_DAIKIN216 +#endif // DECODE_DAIKIN64 +#if DECODE_DELONGHI_AC + case decode_type_t::DELONGHI_AC: { + IRDelonghiAc ac(kGpioUnused); + ac.setRaw(result->value); // DelonghiAc uses value instead of state. + return ac.toString(); + } +#endif // DECODE_DELONGHI_AC #if DECODE_ELECTRA_AC case decode_type_t::ELECTRA_AC: { IRElectraAc ac(0); @@ -2420,6 +2470,14 @@ namespace IRAcUtils { break; } #endif // DECODE_DAIKIN64 +#if DECODE_DELONGHI_AC + case decode_type_t::DELONGHI_AC: { + IRDelonghiAc ac(kGpioUnused); + ac.setRaw(decode->value); // Uses value instead of state. + *result = ac.toCommon(); + break; + } +#endif // DECODE_DELONGHI_AC #if DECODE_ELECTRA_AC case decode_type_t::ELECTRA_AC: { IRElectraAc ac(kGpioUnused); diff --git a/lib/IRremoteESP8266-2.7.6/src/IRac.h b/lib/IRremoteESP8266-2.7.7/src/IRac.h similarity index 95% rename from lib/IRremoteESP8266-2.7.6/src/IRac.h rename to lib/IRremoteESP8266-2.7.7/src/IRac.h index 02faba36a..42c59321c 100644 --- a/lib/IRremoteESP8266-2.7.6/src/IRac.h +++ b/lib/IRremoteESP8266-2.7.7/src/IRac.h @@ -11,6 +11,7 @@ #include "ir_Argo.h" #include "ir_Coolix.h" #include "ir_Daikin.h" +#include "ir_Delonghi.h" #include "ir_Fujitsu.h" #include "ir_Electra.h" #include "ir_Goodweather.h" @@ -174,6 +175,12 @@ void daikin216(IRDaikin216 *ac, const bool quiet, const bool turbo, const int16_t sleep = -1, const int16_t clock = -1); #endif // SEND_DAIKIN64 +#if SEND_DELONGHI_AC + void delonghiac(IRDelonghiAc *ac, + const bool on, const stdAc::opmode_t mode, const bool celsius, + const float degrees, const stdAc::fanspeed_t fan, + const bool turbo, const int16_t sleep = -1); +#endif // SEND_DELONGHI_AC #if SEND_ELECTRA_AC void electra(IRElectraAc *ac, const bool on, const stdAc::opmode_t mode, @@ -201,10 +208,10 @@ void electra(IRElectraAc *ac, #endif // SEND_GOODWEATHER #if SEND_GREE void gree(IRGreeAC *ac, const gree_ac_remote_model_t model, - const bool on, const stdAc::opmode_t mode, const float degrees, - const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, - const bool turbo, const bool light, const bool clean, - const int16_t sleep = -1); + const bool on, const stdAc::opmode_t mode, const bool celsius, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool turbo, const bool light, + const bool clean, const int16_t sleep = -1); #endif // SEND_GREE #if SEND_HAIER_AC void haier(IRHaierAC *ac, @@ -325,7 +332,9 @@ void electra(IRElectraAc *ac, #if SEND_SHARP_AC void sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, - const float degrees, const stdAc::fanspeed_t fan); + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool turbo, const bool filter, + const bool clean); #endif // SEND_SHARP_AC #if SEND_TCL112AC void tcl112(IRTcl112Ac *ac, diff --git a/lib/IRremoteESP8266-2.7.6/src/IRrecv.cpp b/lib/IRremoteESP8266-2.7.7/src/IRrecv.cpp similarity index 92% rename from lib/IRremoteESP8266-2.7.6/src/IRrecv.cpp rename to lib/IRremoteESP8266-2.7.7/src/IRrecv.cpp index f59c1248c..316cf59c6 100644 --- a/lib/IRremoteESP8266-2.7.6/src/IRrecv.cpp +++ b/lib/IRremoteESP8266-2.7.7/src/IRrecv.cpp @@ -789,6 +789,26 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, DPRINTLN("Attempting Airwell decode"); if (decodeAirwell(results, offset)) return true; #endif // DECODE_AIRWELL +#if DECODE_DELONGHI_AC + DPRINTLN("Attempting Delonghi AC decode"); + if (decodeDelonghiAc(results, offset)) return true; +#endif // DECODE_DELONGHI_AC +#if DECODE_DOSHISHA + DPRINTLN("Attempting Doshisha decode"); + if (decodeDoshisha(results, offset)) return true; +#endif // DECODE_DOSHISHA +#if DECODE_MULTIBRACKETS + DPRINTLN("Attempting Multibrackets decode"); + if (decodeMultibrackets(results, offset)) return true; +#endif // DECODE_MULTIBRACKETS +#if DECODE_CARRIER_AC40 + DPRINTLN("Attempting Carrier 40bit decode"); + if (decodeCarrierAC40(results, offset)) return true; +#endif // DECODE_CARRIER_AC40 +#if DECODE_CARRIER_AC64 + DPRINTLN("Attempting Carrier 64bit decode"); + if (decodeCarrierAC64(results, offset)) return true; +#endif // DECODE_CARRIER_AC64 // Typically new protocols are added above this line. } #if DECODE_HASH @@ -1297,6 +1317,92 @@ uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, tolerance, excess, MSBfirst); } +// Match & decode a generic/typical constant bit time <= 64bit IR message. +// The data is stored at result_ptr. +// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip +// that requirement. +// +// Args: +// data_ptr: A pointer to where we are at in the capture buffer. +// result_ptr: A pointer to where to start storing the bits we decoded. +// remaining: The size of the capture buffer are remaining. +// nbits: Nr. of data bits we expect. +// hdrmark: Nr. of uSeconds for the expected header mark signal. +// hdrspace: Nr. of uSeconds for the expected header space signal. +// one: Nr. of uSeconds in an expected mark signal for a '1' bit. +// zero: Nr. of uSeconds in an expected mark signal for a '0' bit. +// footermark: Nr. of uSeconds for the expected footer mark signal. +// footerspace: Nr. of uSeconds for the expected footer space/gap signal. +// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? +// tolerance: Percentage error margin to allow. (Def: kUseDefTol) +// excess: Nr. of useconds. (Def: kMarkExcess) +// MSBfirst: Bit order to save the data in. (Def: true) +// Returns: +// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. +// +// Note: one + zero add up to the total time for a bit. +// e.g. mark(one) + space(zero) is a `1`, mark(zero) + space(one) is a `0`. +uint16_t IRrecv::matchGenericConstBitTime(volatile uint16_t *data_ptr, + uint64_t *result_ptr, + const uint16_t remaining, + const uint16_t nbits, + const uint16_t hdrmark, + const uint32_t hdrspace, + const uint16_t one, + const uint32_t zero, + const uint16_t footermark, + const uint32_t footerspace, + const bool atleast, + const uint8_t tolerance, + const int16_t excess, + const bool MSBfirst) { + uint16_t offset = 0; + uint64_t result = 0; + // If we expect a footermark, then this can be processed like normal. + if (footermark) + return _matchGeneric(data_ptr, result_ptr, NULL, true, remaining, nbits, + hdrmark, hdrspace, one, zero, zero, one, + footermark, footerspace, atleast, + tolerance, excess, MSBfirst); + // Overwise handle like normal, except for the last bit. and no footer. + uint16_t bits = (nbits > 0) ? nbits - 1 : 0; // Make sure we don't underflow. + offset = _matchGeneric(data_ptr, &result, NULL, true, remaining, bits, + hdrmark, hdrspace, one, zero, zero, one, 0, 0, false, + tolerance, excess, true); + if (!offset) return 0; // Didn't match. + // Now for the last bit. + if (remaining <= offset) return 0; // Not enough buffer. + result <<= 1; + bool last_bit = 0; + // Is the mark a '1' or a `0`? + if (matchMark(*(data_ptr + offset), one, tolerance, excess)) { // 1 + last_bit = 1; + result |= 1; + } else if (matchMark(*(data_ptr + offset), zero, tolerance, excess)) { // 0 + last_bit = 0; + } else { + return 0; // It's neither, so fail. + } + offset++; + uint32_t expected_space = (last_bit ? zero : one) + footerspace; + // If we are not at the end of the buffer, check for at least the expected + // space value. + if (remaining > offset) { + if (atleast) { + if (!matchAtLeast(*(data_ptr + offset), expected_space, tolerance, + excess)) + return false; + } else { + if (!matchSpace(*(data_ptr + offset), expected_space, tolerance)) + return false; + } + offset++; + } + if (!MSBfirst) result = reverseBits(result, nbits); + *result_ptr = result; + return offset; +} + // Match & decode a Manchester Code <= 64bit IR message. // The data is stored at result_ptr. // Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip diff --git a/lib/IRremoteESP8266-2.7.6/src/IRrecv.h b/lib/IRremoteESP8266-2.7.7/src/IRrecv.h similarity index 92% rename from lib/IRremoteESP8266-2.7.6/src/IRrecv.h rename to lib/IRremoteESP8266-2.7.7/src/IRrecv.h index aeea5b32d..2894683ac 100644 --- a/lib/IRremoteESP8266-2.7.6/src/IRrecv.h +++ b/lib/IRremoteESP8266-2.7.7/src/IRrecv.h @@ -221,6 +221,20 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); + uint16_t matchGenericConstBitTime(volatile uint16_t *data_ptr, + uint64_t *result_ptr, + const uint16_t remaining, + const uint16_t nbits, + const uint16_t hdrmark, + const uint32_t hdrspace, + const uint16_t one, + const uint32_t zero, + const uint16_t footermark, + const uint32_t footerspace, + const bool atleast = false, + const uint8_t tolerance = kUseDefTol, + const int16_t excess = kMarkExcess, + const bool MSBfirst = true); uint16_t matchManchester(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, @@ -471,7 +485,19 @@ class IRrecv { bool decodeCarrierAC(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kCarrierAcBits, const bool strict = true); -#endif +#endif // DECODE_CARRIER_AC +#if DECODE_CARRIER_AC40 + bool decodeCarrierAC40(decode_results *results, + uint16_t offset = kStartOffset, + const uint16_t nbits = kCarrierAc40Bits, + const bool strict = true); +#endif // DECODE_CARRIER_AC40 +#if DECODE_CARRIER_AC64 + bool decodeCarrierAC64(decode_results *results, + uint16_t offset = kStartOffset, + const uint16_t nbits = kCarrierAc64Bits, + const bool strict = true); +#endif // DECODE_CARRIER_AC64 #if DECODE_GOODWEATHER bool decodeGoodweather(decode_results *results, uint16_t offset = kStartOffset, @@ -593,6 +619,22 @@ class IRrecv { const uint16_t nbits = kAirwellBits, const bool strict = true); #endif // DECODE_AIRWELL +#if DECODE_DELONGHI_AC + bool decodeDelonghiAc(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kDelonghiAcBits, + const bool strict = true); +#endif // DECODE_DELONGHI_AC +#if DECODE_DOSHISHA + bool decodeDoshisha(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kDoshishaBits, + const bool strict = true); +#endif // DECODE_DOSHISHA +#if DECODE_MULTIBRACKETS + bool decodeMultibrackets(decode_results *results, + uint16_t offset = kStartOffset, + const uint16_t nbits = kMultibracketsBits, + const bool strict = true); +#endif // DECODE_MULTIBRACKETS }; #endif // IRRECV_H_ diff --git a/lib/IRremoteESP8266-2.7.6/src/IRremoteESP8266.h b/lib/IRremoteESP8266-2.7.7/src/IRremoteESP8266.h similarity index 93% rename from lib/IRremoteESP8266-2.7.6/src/IRremoteESP8266.h rename to lib/IRremoteESP8266-2.7.7/src/IRremoteESP8266.h index 2bf906697..deef5e5e5 100644 --- a/lib/IRremoteESP8266-2.7.6/src/IRremoteESP8266.h +++ b/lib/IRremoteESP8266-2.7.7/src/IRremoteESP8266.h @@ -52,7 +52,7 @@ #endif // UNIT_TEST // Library Version -#define _IRREMOTEESP8266_VERSION_ "2.7.6" +#define _IRREMOTEESP8266_VERSION_ "2.7.7" // Set the language & locale for the library. See the `locale` dir for options. #ifndef _IR_LOCALE_ @@ -383,6 +383,20 @@ #define SEND_CARRIER_AC _IR_ENABLE_DEFAULT_ #endif // SEND_CARRIER_AC +#ifndef DECODE_CARRIER_AC40 +#define DECODE_CARRIER_AC40 _IR_ENABLE_DEFAULT_ +#endif // DECODE_CARRIER_AC40 +#ifndef SEND_CARRIER_AC40 +#define SEND_CARRIER_AC40 _IR_ENABLE_DEFAULT_ +#endif // SEND_CARRIER_AC40 + +#ifndef DECODE_CARRIER_AC64 +#define DECODE_CARRIER_AC64 _IR_ENABLE_DEFAULT_ +#endif // DECODE_CARRIER_AC64 +#ifndef SEND_CARRIER_AC64 +#define SEND_CARRIER_AC64 _IR_ENABLE_DEFAULT_ +#endif // SEND_CARRIER_AC64 + #ifndef DECODE_HAIER_AC #define DECODE_HAIER_AC _IR_ENABLE_DEFAULT_ #endif // DECODE_HAIER_AC @@ -412,10 +426,10 @@ #endif // SEND_HITACHI_AC2 #ifndef DECODE_HITACHI_AC3 -#define DECODE_HITACHI_AC3 _IR_ENABLE_DEFAULT_ +#define DECODE_HITACHI_AC3 _IR_ENABLE_DEFAULT_ #endif // DECODE_HITACHI_AC3 #ifndef SEND_HITACHI_AC3 -#define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_ +#define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_ #endif // SEND_HITACHI_AC3 #ifndef DECODE_HITACHI_AC424 @@ -573,33 +587,54 @@ #endif // SEND_DAIKIN152 #ifndef DECODE_EPSON -#define DECODE_EPSON _IR_ENABLE_DEFAULT_ +#define DECODE_EPSON _IR_ENABLE_DEFAULT_ #endif // DECODE_EPSON #ifndef SEND_EPSON -#define SEND_EPSON _IR_ENABLE_DEFAULT_ +#define SEND_EPSON _IR_ENABLE_DEFAULT_ #endif // SEND_EPSON #ifndef DECODE_SYMPHONY -#define DECODE_SYMPHONY _IR_ENABLE_DEFAULT_ +#define DECODE_SYMPHONY _IR_ENABLE_DEFAULT_ #endif // DECODE_SYMPHONY #ifndef SEND_SYMPHONY -#define SEND_SYMPHONY _IR_ENABLE_DEFAULT_ +#define SEND_SYMPHONY _IR_ENABLE_DEFAULT_ #endif // SEND_SYMPHONY #ifndef DECODE_DAIKIN64 -#define DECODE_DAIKIN64 _IR_ENABLE_DEFAULT_ +#define DECODE_DAIKIN64 _IR_ENABLE_DEFAULT_ #endif // DECODE_DAIKIN64 #ifndef SEND_DAIKIN64 -#define SEND_DAIKIN64 _IR_ENABLE_DEFAULT_ +#define SEND_DAIKIN64 _IR_ENABLE_DEFAULT_ #endif // SEND_DAIKIN64 #ifndef DECODE_AIRWELL -#define DECODE_AIRWELL _IR_ENABLE_DEFAULT_ +#define DECODE_AIRWELL _IR_ENABLE_DEFAULT_ #endif // DECODE_AIRWELL #ifndef SEND_AIRWELL -#define SEND_AIRWELL _IR_ENABLE_DEFAULT_ +#define SEND_AIRWELL _IR_ENABLE_DEFAULT_ #endif // SEND_AIRWELL +#ifndef DECODE_DELONGHI_AC +#define DECODE_DELONGHI_AC _IR_ENABLE_DEFAULT_ +#endif // DECODE_DELONGHI_AC +#ifndef SEND_DELONGHI_AC +#define SEND_DELONGHI_AC _IR_ENABLE_DEFAULT_ +#endif // SEND_DELONGHI_AC + +#ifndef DECODE_DOSHISHA +#define DECODE_DOSHISHA _IR_ENABLE_DEFAULT_ +#endif // DECODE_DOSHISHA +#ifndef SEND_DOSHISHA +#define SEND_DOSHISHA _IR_ENABLE_DEFAULT_ +#endif // SEND_DOSHISHA + +#ifndef DECODE_MULTIBRACKETS +#define DECODE_MULTIBRACKETS _IR_ENABLE_DEFAULT_ +#endif // DECODE_MULTIBRACKETS +#ifndef SEND_MULTIBRACKETS +#define SEND_MULTIBRACKETS _IR_ENABLE_DEFAULT_ +#endif // SEND_MULTIBRACKETS + #if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \ DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \ DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \ @@ -727,8 +762,13 @@ enum decode_type_t { HITACHI_AC3, DAIKIN64, AIRWELL, + DELONGHI_AC, // 80 + DOSHISHA, + MULTIBRACKETS, + CARRIER_AC40, + CARRIER_AC64, // Add new entries before this one, and update it to point to the last entry. - kLastDecodeType = AIRWELL, + kLastDecodeType = CARRIER_AC64, }; // Message lengths & required repeat values @@ -750,6 +790,10 @@ const uint16_t kCoolixBits = 24; const uint16_t kCoolixDefaultRepeat = kSingleRepeat; const uint16_t kCarrierAcBits = 32; const uint16_t kCarrierAcMinRepeat = kNoRepeat; +const uint16_t kCarrierAc40Bits = 40; +const uint16_t kCarrierAc40MinRepeat = 2; +const uint16_t kCarrierAc64Bits = 64; +const uint16_t kCarrierAc64MinRepeat = kNoRepeat; const uint16_t kDaikinStateLength = 35; const uint16_t kDaikinBits = kDaikinStateLength * 8; const uint16_t kDaikinStateLengthShort = kDaikinStateLength - 8; @@ -775,11 +819,14 @@ const uint16_t kDaikin176DefaultRepeat = kNoRepeat; const uint16_t kDaikin216StateLength = 27; const uint16_t kDaikin216Bits = kDaikin216StateLength * 8; const uint16_t kDaikin216DefaultRepeat = kNoRepeat; +const uint16_t kDelonghiAcBits = 64; +const uint16_t kDelonghiAcDefaultRepeat = kNoRepeat; const uint16_t kDenonBits = 15; const uint16_t kDenon48Bits = 48; const uint16_t kDenonLegacyBits = 14; const uint16_t kDishBits = 16; const uint16_t kDishMinRepeat = 3; +const uint16_t kDoshishaBits = 40; const uint16_t kEpsonBits = 32; const uint16_t kEpsonMinRepeat = 2; const uint16_t kElectraAcStateLength = 13; @@ -852,6 +899,8 @@ const uint16_t kMitsubishiHeavy88MinRepeat = kNoRepeat; const uint16_t kMitsubishiHeavy152StateLength = 19; const uint16_t kMitsubishiHeavy152Bits = kMitsubishiHeavy152StateLength * 8; const uint16_t kMitsubishiHeavy152MinRepeat = kNoRepeat; +const uint16_t kMultibracketsBits = 8; +const uint16_t kMultibracketsDefaultRepeat = kSingleRepeat; const uint16_t kNikaiBits = 24; const uint16_t kNECBits = 32; const uint16_t kNeoclimaStateLength = 12; @@ -897,8 +946,8 @@ const uint16_t kSony15Bits = 15; const uint16_t kSony20Bits = 20; const uint16_t kSonyMinBits = 12; const uint16_t kSonyMinRepeat = 2; -const uint16_t kSymphonyBits = 11; -const uint16_t kSymphonyDefaultRepeat = kSingleRepeat; +const uint16_t kSymphonyBits = 12; +const uint16_t kSymphonyDefaultRepeat = 3; const uint16_t kTcl112AcStateLength = 14; const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8; const uint16_t kTcl112AcDefaultRepeat = kNoRepeat; diff --git a/lib/IRremoteESP8266-2.7.6/src/IRsend.cpp b/lib/IRremoteESP8266-2.7.7/src/IRsend.cpp similarity index 97% rename from lib/IRremoteESP8266-2.7.6/src/IRsend.cpp rename to lib/IRremoteESP8266-2.7.7/src/IRsend.cpp index bb5f55407..8995e2d33 100644 --- a/lib/IRremoteESP8266-2.7.6/src/IRsend.cpp +++ b/lib/IRremoteESP8266-2.7.7/src/IRsend.cpp @@ -607,13 +607,15 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) { case MITSUBISHI: case MITSUBISHI2: case MITSUBISHI_AC: + case MULTIBRACKETS: case SHERWOOD: - case SYMPHONY: case TOSHIBA_AC: return kSingleRepeat; // Special case AIRWELL: return kAirwellMinRepeats; + case CARRIER_AC40: + return kCarrierAc40MinRepeat; case DISH: return kDishMinRepeat; case EPSON: @@ -622,6 +624,8 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) { return kSonyMinRepeat; case SONY_38K: return kSonyMinRepeat + 1; + case SYMPHONY: + return kSymphonyDefaultRepeat; default: return kNoRepeat; } @@ -634,9 +638,10 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) { // int16_t: The number of bits. uint16_t IRsend::defaultBits(const decode_type_t protocol) { switch (protocol) { - case SYMPHONY: - return 11; + case MULTIBRACKETS: + return 8; case RC5: + case SYMPHONY: return 12; case LASERTAG: case RC5X: @@ -678,6 +683,10 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return 35; case SAMSUNG36: return 36; + case CARRIER_AC40: + return kCarrierAc40Bits; // 40 + case DOSHISHA: + return kDoshishaBits; // 40 case SANYO_LC7461: return kSanyoLC7461Bits; // 42 case GOODWEATHER: @@ -688,6 +697,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { case VESTEL_AC: return 56; case AMCOR: + case CARRIER_AC64: + case DELONGHI_AC: case PIONEER: return 64; case ARGO: @@ -722,8 +733,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return kHitachiAc1Bits; case HITACHI_AC2: return kHitachiAc2Bits; - case HITACHI_AC3: - return kHitachiAc3Bits; + case HITACHI_AC3: + return kHitachiAc3Bits; case HITACHI_AC424: return kHitachiAc424Bits; case KELVINATOR: @@ -790,6 +801,16 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, sendCarrierAC(data, nbits, min_repeat); break; #endif +#if SEND_CARRIER_AC40 + case CARRIER_AC40: + sendCarrierAC40(data, nbits, min_repeat); + break; +#endif // SEND_CARRIER_AC40 +#if SEND_CARRIER_AC64 + case CARRIER_AC64: + sendCarrierAC64(data, nbits, min_repeat); + break; +#endif // SEND_CARRIER_AC64 #if SEND_COOLIX case COOLIX: sendCOOLIX(data, nbits, min_repeat); @@ -800,6 +821,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, sendDaikin64(data, nbits, min_repeat); break; #endif +#if SEND_DELONGHI_AC + case DELONGHI_AC: + sendDelonghiAc(data, nbits, min_repeat); + break; +#endif #if SEND_DENON case DENON: sendDenon(data, nbits, min_repeat); @@ -810,6 +836,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, sendDISH(data, nbits, min_repeat); break; #endif +#if SEND_DOSHISHA + case DOSHISHA: + sendDoshisha(data, nbits, min_repeat); + break; +#endif #if SEND_EPSON case EPSON: sendEpson(data, nbits, min_repeat); @@ -883,6 +914,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, sendMitsubishi2(data, nbits, min_repeat); break; #endif +#if SEND_MULTIBRACKETS + case MULTIBRACKETS: + sendMultibrackets(data, nbits, min_repeat); + break; +#endif #if SEND_NIKAI case NIKAI: sendNikai(data, nbits, min_repeat); diff --git a/lib/IRremoteESP8266-2.7.6/src/IRsend.h b/lib/IRremoteESP8266-2.7.7/src/IRsend.h similarity index 96% rename from lib/IRremoteESP8266-2.7.6/src/IRsend.h rename to lib/IRremoteESP8266-2.7.7/src/IRsend.h index 8d5e6a862..85a3dde62 100644 --- a/lib/IRremoteESP8266-2.7.6/src/IRsend.h +++ b/lib/IRremoteESP8266-2.7.7/src/IRsend.h @@ -466,6 +466,14 @@ class IRsend { void sendCarrierAC(uint64_t data, uint16_t nbits = kCarrierAcBits, uint16_t repeat = kCarrierAcMinRepeat); #endif +#if SEND_CARRIER_AC40 + void sendCarrierAC40(uint64_t data, uint16_t nbits = kCarrierAc40Bits, + uint16_t repeat = kCarrierAc40MinRepeat); +#endif +#if SEND_CARRIER_AC64 + void sendCarrierAC64(uint64_t data, uint16_t nbits = kCarrierAc64Bits, + uint16_t repeat = kCarrierAc64MinRepeat); +#endif #if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02) void sendHaierAC(const unsigned char data[], const uint16_t nbytes = kHaierACStateLength, @@ -573,6 +581,20 @@ class IRsend { void sendAirwell(uint64_t data, uint16_t nbits = kAirwellBits, uint16_t repeat = kAirwellMinRepeats); #endif +#if SEND_DELONGHI_AC + void sendDelonghiAc(uint64_t data, uint16_t nbits = kDelonghiAcBits, + uint16_t repeat = kDelonghiAcDefaultRepeat); +#endif +#if SEND_DOSHISHA + void sendDoshisha(const uint64_t data, uint16_t nbits = kDoshishaBits, + const uint16_t repeat = kNoRepeat); + uint64_t encodeDoshisha(const uint8_t command, const uint8_t channel = 0); +#endif // SEND_DOSHISHA +#if SEND_MULTIBRACKETS + void sendMultibrackets(const uint64_t data, + const uint16_t nbits = kMultibracketsBits, + const uint16_t repeat = kMultibracketsDefaultRepeat); +#endif protected: #ifdef UNIT_TEST diff --git a/lib/IRremoteESP8266-2.7.6/src/IRtext.cpp b/lib/IRremoteESP8266-2.7.7/src/IRtext.cpp similarity index 94% rename from lib/IRremoteESP8266-2.7.6/src/IRtext.cpp rename to lib/IRremoteESP8266-2.7.7/src/IRtext.cpp index cb9ccd722..f612ed8d1 100644 --- a/lib/IRremoteESP8266-2.7.6/src/IRtext.cpp +++ b/lib/IRremoteESP8266-2.7.7/src/IRtext.cpp @@ -1,4 +1,7 @@ -// Copyright 2019 - David Conran (@crankyoldgit) +// Copyright 2019-2020 - David Conran (@crankyoldgit) + +/// @warn If you add or remove an entry in this file, you should run: +/// '../tools/generate_irtext_h.sh' to rebuild the `IRtext.h` file. #ifndef UNIT_TEST #include @@ -79,6 +82,7 @@ const PROGMEM char* kSlowStr = D_STR_SLOW; const PROGMEM char* kAirFlowStr = D_STR_AIRFLOW; const PROGMEM char* kStepStr = D_STR_STEP; const PROGMEM char* kNAStr = D_STR_NA; +const PROGMEM char* kInsideStr = D_STR_INSIDE; const PROGMEM char* kOutsideStr = D_STR_OUTSIDE; const PROGMEM char* kLoudStr = D_STR_LOUD; const PROGMEM char* kLowerStr = D_STR_LOWER; @@ -131,6 +135,7 @@ const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE; const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET; const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE; const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER; +const PROGMEM char* kDisplayTempStr = D_STR_DISPLAYTEMP; const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP; const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER; const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE; @@ -247,4 +252,10 @@ const PROGMEM char *kAllProtocolNamesStr = D_STR_HITACHI_AC3 "\x0" D_STR_DAIKIN64 "\x0" D_STR_AIRWELL "\x0" + D_STR_DELONGHI_AC "\x0" + D_STR_DOSHISHA "\x0" + D_STR_MULTIBRACKETS "\x0" + D_STR_CARRIER_AC40 "\x0" + D_STR_CARRIER_AC64 "\x0" + // New protocol strings should be added just above this line. "\x0"; // This string requires double null termination. diff --git a/lib/IRremoteESP8266-2.7.6/src/IRtext.h b/lib/IRremoteESP8266-2.7.7/src/IRtext.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/IRtext.h rename to lib/IRremoteESP8266-2.7.7/src/IRtext.h index cbce59747..112162f65 100644 --- a/lib/IRremoteESP8266-2.7.6/src/IRtext.h +++ b/lib/IRremoteESP8266-2.7.7/src/IRtext.h @@ -41,6 +41,7 @@ extern const char* kCommaSpaceStr; extern const char* kCoolStr; extern const char* kDaysStr; extern const char* kDayStr; +extern const char* kDisplayTempStr; extern const char* kDownStr; extern const char* kDryStr; extern const char* kEconoStr; @@ -64,6 +65,7 @@ extern const char* kHoursStr; extern const char* kHourStr; extern const char* kHumidStr; extern const char* kIFeelStr; +extern const char* kInsideStr; extern const char* kIonStr; extern const char* kLastStr; extern const char* kLeftMaxStr; diff --git a/lib/IRremoteESP8266-2.7.6/src/IRtimer.cpp b/lib/IRremoteESP8266-2.7.7/src/IRtimer.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/IRtimer.cpp rename to lib/IRremoteESP8266-2.7.7/src/IRtimer.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/IRtimer.h b/lib/IRremoteESP8266-2.7.7/src/IRtimer.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/IRtimer.h rename to lib/IRremoteESP8266-2.7.7/src/IRtimer.h diff --git a/lib/IRremoteESP8266-2.7.6/src/IRutils.cpp b/lib/IRremoteESP8266-2.7.7/src/IRutils.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/IRutils.cpp rename to lib/IRremoteESP8266-2.7.7/src/IRutils.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/IRutils.h b/lib/IRremoteESP8266-2.7.7/src/IRutils.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/IRutils.h rename to lib/IRremoteESP8266-2.7.7/src/IRutils.h diff --git a/lib/IRremoteESP8266-2.7.6/src/i18n.h b/lib/IRremoteESP8266-2.7.7/src/i18n.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/i18n.h rename to lib/IRremoteESP8266-2.7.7/src/i18n.h diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Airwell.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Airwell.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Airwell.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Airwell.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Aiwa.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Aiwa.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Aiwa.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Aiwa.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Amcor.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Amcor.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Amcor.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Amcor.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Amcor.h b/lib/IRremoteESP8266-2.7.7/src/ir_Amcor.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Amcor.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Amcor.h index fa8aa1edd..401bb787c 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Amcor.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Amcor.h @@ -86,7 +86,7 @@ class IRAmcorAc { void stateReset(); #if SEND_AMCOR void send(const uint16_t repeat = kAmcorDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_AMCOR void begin(); static uint8_t calcChecksum(const uint8_t state[], diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Argo.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Argo.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Argo.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Argo.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Argo.h b/lib/IRremoteESP8266-2.7.7/src/ir_Argo.h similarity index 99% rename from lib/IRremoteESP8266-2.7.6/src/ir_Argo.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Argo.h index 3c1281ea3..af674d46f 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Argo.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Argo.h @@ -131,7 +131,7 @@ class IRArgoAC { #if SEND_ARGO void send(const uint16_t repeat = kArgoDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_ARGO void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp new file mode 100644 index 000000000..f0d7f4317 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp @@ -0,0 +1,217 @@ +// Copyright 2018, 2020 David Conran + +// Supports: +// Brand: Carrier/Surrey, Model: 42QG5A55970 remote +// Brand: Carrier/Surrey, Model: 619EGX0090E0 A/C +// Brand: Carrier/Surrey, Model: 619EGX0120E0 A/C +// Brand: Carrier/Surrey, Model: 619EGX0180E0 A/C +// Brand: Carrier/Surrey, Model: 619EGX0220E0 A/C +// Brand: Carrier/Surrey, Model: 53NGK009/012 Inverter + +#include "IRrecv.h" +#include "IRsend.h" +#include "IRutils.h" + +// Constants +// Ref: +// https://github.com/crankyoldgit/IRremoteESP8266/issues/385 +const uint16_t kCarrierAcHdrMark = 8532; +const uint16_t kCarrierAcHdrSpace = 4228; +const uint16_t kCarrierAcBitMark = 628; +const uint16_t kCarrierAcOneSpace = 1320; +const uint16_t kCarrierAcZeroSpace = 532; +const uint16_t kCarrierAcGap = 20000; +const uint16_t kCarrierAcFreq = 38; // kHz. (An educated guess) + +const uint16_t kCarrierAc40HdrMark = 8402; +const uint16_t kCarrierAc40HdrSpace = 4166; +const uint16_t kCarrierAc40BitMark = 547; +const uint16_t kCarrierAc40OneSpace = 1540; +const uint16_t kCarrierAc40ZeroSpace = 497; + +// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1127 +const uint16_t kCarrierAc64HdrMark = 8940; +const uint16_t kCarrierAc64HdrSpace = 4556; +const uint16_t kCarrierAc64BitMark = 503; +const uint16_t kCarrierAc64OneSpace = 1736; +const uint16_t kCarrierAc64ZeroSpace = 615; +const uint32_t kCarrierAc64Gap = kDefaultMessageGap; // A guess. + + +#if SEND_CARRIER_AC +// Send a Carrier HVAC formatted message. +// +// Args: +// data: The message to be sent. +// nbits: The bit size of the message being sent. typically kCarrierAcBits. +// repeat: The number of times the message is to be repeated. +// +// Status: STABLE / Work on real devices. +// +void IRsend::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) { + for (uint16_t r = 0; r <= repeat; r++) { + uint64_t temp_data = data; + // Carrier sends the data block three times. normal + inverted + normal. + for (uint16_t i = 0; i < 3; i++) { + sendGeneric(kCarrierAcHdrMark, kCarrierAcHdrSpace, kCarrierAcBitMark, + kCarrierAcOneSpace, kCarrierAcBitMark, kCarrierAcZeroSpace, + kCarrierAcBitMark, kCarrierAcGap, temp_data, nbits, 38, true, + 0, kDutyDefault); + temp_data = invertBits(temp_data, nbits); + } + } +} +#endif + +#if DECODE_CARRIER_AC +// Decode the supplied Carrier HVAC message. +// Carrier HVAC messages contain only 32 bits, but it is sent three(3) times. +// i.e. normal + inverted + normal +// Args: +// results: Ptr to the data to decode and where to store the decode result. +// offset: The starting index to use when attempting to decode the raw data. +// Typically/Defaults to kStartOffset. +// nbits: Nr. of bits to expect in the data portion. +// Typically kCarrierAcBits. +// strict: Flag to indicate if we strictly adhere to the specification. +// Returns: +// boolean: True if it can decode it, false if it can't. +// +// Status: BETA / Probably works. +// +bool IRrecv::decodeCarrierAC(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < ((2 * nbits + kHeader + kFooter) * 3) - 1 + offset) + return false; // Can't possibly be a valid Carrier message. + if (strict && nbits != kCarrierAcBits) + return false; // We expect Carrier to be 32 bits of message. + + uint64_t data = 0; + uint64_t prev_data = 0; + + for (uint8_t i = 0; i < 3; i++) { + prev_data = data; + // Match Header + Data + Footer + uint16_t used; + used = matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kCarrierAcHdrMark, kCarrierAcHdrSpace, + kCarrierAcBitMark, kCarrierAcOneSpace, + kCarrierAcBitMark, kCarrierAcZeroSpace, + kCarrierAcBitMark, kCarrierAcGap, true); + if (!used) return false; + offset += used; + // Compliance. + if (strict) { + // Check if the data is an inverted copy of the previous data. + if (i > 0 && prev_data != invertBits(data, nbits)) return false; + } + } + + // Success + results->bits = nbits; + results->value = data; + results->decode_type = CARRIER_AC; + results->address = data >> 16; + results->command = data & 0xFFFF; + return true; +} +#endif // DECODE_CARRIER_AC + +#if SEND_CARRIER_AC40 +/// Send a Carrier 40bit HVAC formatted message. +/// Status: Alpha / Yet to be tested against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The bit size of the message being sent. +/// @param[in] repeat The number of times the message is to be repeated. +void IRsend::sendCarrierAC40(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kCarrierAc40HdrMark, kCarrierAc40HdrSpace, kCarrierAc40BitMark, + kCarrierAc40OneSpace, kCarrierAc40BitMark, kCarrierAc40ZeroSpace, + kCarrierAc40BitMark, kCarrierAcGap, + data, nbits, kCarrierAcFreq, true, repeat, kDutyDefault); +} +#endif // SEND_CARRIER_AC40 + +#if DECODE_CARRIER_AC40 +/// Decode the supplied Carrier 40-bit HVAC message. +/// Carrier HVAC messages contain only 40 bits, but it is sent three(3) times. +/// Status: BETA / Probably works. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +bool IRrecv::decodeCarrierAC40(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid Carrier message. + if (strict && nbits != kCarrierAc40Bits) + return false; // We expect Carrier to be 40 bits of message. + + if (!matchGeneric(results->rawbuf + offset, &(results->value), + results->rawlen - offset, nbits, + kCarrierAc40HdrMark, kCarrierAc40HdrSpace, + kCarrierAc40BitMark, kCarrierAc40OneSpace, + kCarrierAc40BitMark, kCarrierAc40ZeroSpace, + kCarrierAc40BitMark, kCarrierAcGap, true)) return false; + + // Success + results->bits = nbits; + results->decode_type = CARRIER_AC40; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_CARRIER_AC40 + +#if SEND_CARRIER_AC64 +/// Send a Carrier 64bit HVAC formatted message. +/// Status: Alpha / Yet to be tested against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The bit size of the message being sent. +/// @param[in] repeat The number of times the message is to be repeated. +void IRsend::sendCarrierAC64(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kCarrierAc64HdrMark, kCarrierAc64HdrSpace, kCarrierAc64BitMark, + kCarrierAc64OneSpace, kCarrierAc64BitMark, kCarrierAc64ZeroSpace, + kCarrierAc64BitMark, kCarrierAc64Gap, + data, nbits, kCarrierAcFreq, false, repeat, kDutyDefault); +} +#endif // SEND_CARRIER_AC64 + +#if DECODE_CARRIER_AC64 +/// Decode the supplied Carrier 64-bit HVAC message. +/// Status: BETA / Probably works. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +bool IRrecv::decodeCarrierAC64(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid Carrier message. + if (strict && nbits != kCarrierAc64Bits) + return false; // We expect Carrier to be 64 bits of message. + + if (!matchGeneric(results->rawbuf + offset, &(results->value), + results->rawlen - offset, nbits, + kCarrierAc64HdrMark, kCarrierAc64HdrSpace, + kCarrierAc64BitMark, kCarrierAc64OneSpace, + kCarrierAc64BitMark, kCarrierAc64ZeroSpace, + kCarrierAc64BitMark, kCarrierAc64Gap, true, + kUseDefTol, kMarkExcess, false)) return false; + + // Success + results->bits = nbits; + results->decode_type = CARRIER_AC64; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_CARRIER_AC64 diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Coolix.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Coolix.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Coolix.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Coolix.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Coolix.h b/lib/IRremoteESP8266-2.7.7/src/ir_Coolix.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Coolix.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Coolix.h index 6f7778416..7ffcf01a9 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Coolix.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Coolix.h @@ -106,7 +106,7 @@ class IRCoolixAC { void stateReset(); #if SEND_COOLIX void send(const uint16_t repeat = kCoolixDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_COOLIX void begin(); void on(); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Daikin.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Daikin.cpp similarity index 99% rename from lib/IRremoteESP8266-2.7.6/src/ir_Daikin.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Daikin.cpp index c18e77569..2bc0518ec 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Daikin.cpp +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Daikin.cpp @@ -3261,7 +3261,8 @@ bool IRrecv::decodeDaikin64(decode_results *results, uint16_t offset, kDaikin64BitMark, kDaikin64OneSpace, kDaikin64BitMark, kDaikin64ZeroSpace, kDaikin64BitMark, kDaikin64Gap, - false, _tolerance, kMarkExcess, false); + false, _tolerance + kDaikin64ToleranceDelta, + kMarkExcess, false); if (used == 0) return false; offset += used; // Footer #2 diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Daikin.h b/lib/IRremoteESP8266-2.7.7/src/ir_Daikin.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Daikin.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Daikin.h index 3630aa77b..3c6f542ff 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Daikin.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Daikin.h @@ -19,6 +19,9 @@ // Brand: Daikin, Model: ARC480A5 remote (DAIKIN152) // Brand: Daikin, Model: FFN-C/FCN-F Series A/C (DAIKIN64) // Brand: Daikin, Model: DGS01 remote (DAIKIN64) +// Brand: Daikin, Model: M Series A/C (DAIKIN) +// Brand: Daikin, Model: FTXM-M A/C (DAIKIN) +// Brand: Daikin, Model: ARC466A33 remote (DAIKIN) #ifndef IR_DAIKIN_H_ #define IR_DAIKIN_H_ @@ -441,7 +444,8 @@ const uint16_t kDaikin64LdrMark = kDaikin128LeaderMark; const uint16_t kDaikin64Gap = kDaikin128Gap; const uint16_t kDaikin64LdrSpace = kDaikin128LeaderSpace; const uint16_t kDaikin64Freq = kDaikin128Freq; // Hz. -const uint16_t kDaikin64Overhead = 9; +const uint8_t kDaikin64Overhead = 9; +const int8_t kDaikin64ToleranceDelta = 5; // +5% const uint64_t kDaikin64KnownGoodState = 0x7C16161607204216; const uint8_t kDaikin64ModeOffset = 8; @@ -503,7 +507,7 @@ class IRDaikinESP { #if SEND_DAIKIN void send(const uint16_t repeat = kDaikinDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(void); void on(void); @@ -578,7 +582,7 @@ class IRDaikin2 { #if SEND_DAIKIN2 void send(const uint16_t repeat = kDaikin2DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); void on(); @@ -672,7 +676,7 @@ class IRDaikin216 { #if SEND_DAIKIN216 void send(const uint16_t repeat = kDaikin216DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); uint8_t* getRaw(); @@ -722,7 +726,7 @@ class IRDaikin160 { #if SEND_DAIKIN160 void send(const uint16_t repeat = kDaikin160DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); uint8_t* getRaw(); @@ -768,7 +772,7 @@ class IRDaikin176 { #if SEND_DAIKIN176 void send(const uint16_t repeat = kDaikin176DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); uint8_t* getRaw(); @@ -817,7 +821,7 @@ class IRDaikin128 { const bool use_modulation = true); #if SEND_DAIKIN128 void send(const uint16_t repeat = kDaikin128DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_DAIKIN128 void begin(); void setPowerToggle(const bool toggle); @@ -886,7 +890,7 @@ class IRDaikin152 { #if SEND_DAIKIN152 void send(const uint16_t repeat = kDaikin152DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); uint8_t* getRaw(); @@ -942,7 +946,7 @@ class IRDaikin64 { #if SEND_DAIKIN64 void send(const uint16_t repeat = kDaikin64DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_DAIKIN64 void begin(); uint64_t getRaw(); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.cpp new file mode 100644 index 000000000..7f6c3158a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.cpp @@ -0,0 +1,429 @@ +// Copyright 2020 David Conran +// Delonghi based protocol. + +#include "ir_Delonghi.h" +#include "IRrecv.h" +#include "IRsend.h" +#include "IRtext.h" +#include "IRutils.h" +#include + +using irutils::addBoolToString; +using irutils::addModeToString; +using irutils::addFanToString; +using irutils::addLabeledString; +using irutils::addTempToString; +using irutils::minsToString; +using irutils::setBit; +using irutils::setBits; + +const uint16_t kDelonghiAcHdrMark = 8984; +const uint16_t kDelonghiAcBitMark = 572; +const uint16_t kDelonghiAcHdrSpace = 4200; +const uint16_t kDelonghiAcOneSpace = 1558; +const uint16_t kDelonghiAcZeroSpace = 510; +const uint32_t kDelonghiAcGap = kDefaultMessageGap; // A totally made-up guess. +const uint16_t kDelonghiAcFreq = 38000; // Hz. (Guess: most common frequency.) +const uint16_t kDelonghiAcOverhead = 3; + + +#if SEND_DELONGHI_AC +// Send an Delonghi AC formatted message. +// +// Args: +// data: The message to be sent. +// nbits: The number of bits of the message to be sent. +// Typically kDelonghiAcBits. +// repeat: The number of times the command is to be repeated. +// +// Status: STABLE / Reported as working on a real device. +// +// Ref: +// https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 +void IRsend::sendDelonghiAc(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kDelonghiAcHdrMark, kDelonghiAcHdrSpace, + kDelonghiAcBitMark, kDelonghiAcOneSpace, + kDelonghiAcBitMark, kDelonghiAcZeroSpace, + kDelonghiAcBitMark, kDelonghiAcGap, + data, nbits, kDelonghiAcFreq, false, // LSB First. + repeat, kDutyDefault); +} +#endif // SEND_DELONGHI_AC + +#if DECODE_DELONGHI_AC +// Decode the supplied DELONGHI_AC message. +// +// Args: +// results: Ptr to the data to decode and where to store the decode result. +// offset: The starting index to use when attempting to decode the raw data. +// Typically/Defaults to kStartOffset. +// nbits: The number of data bits to expect. Typically kDelonghiAcBits. +// strict: Flag indicating if we should perform strict matching. +// Returns: +// boolean: True if it can decode it, false if it can't. +// +// Status: STABLE / Expected to be working. +// +// Ref: +// https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 +bool IRrecv::decodeDelonghiAc(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kDelonghiAcOverhead - offset) + return false; // Too short a message to match. + if (strict && nbits != kDelonghiAcBits) + return false; + + uint64_t data = 0; + + // Header + Data + Footer + if (!matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kDelonghiAcHdrMark, kDelonghiAcHdrSpace, + kDelonghiAcBitMark, kDelonghiAcOneSpace, + kDelonghiAcBitMark, kDelonghiAcZeroSpace, + kDelonghiAcBitMark, kDelonghiAcGap, true, + _tolerance, kMarkExcess, false)) return false; + + // Compliance + if (strict && !IRDelonghiAc::validChecksum(data)) return false; + + // Success + results->decode_type = decode_type_t::DELONGHI_AC; + results->bits = nbits; + results->value = data; + results->command = 0; + results->address = 0; + return true; +} +#endif // DECODE_DELONGHI_AC + + +// Class for controlling the settings of a Delonghi A/C + +IRDelonghiAc::IRDelonghiAc(const uint16_t pin, const bool inverted, + const bool use_modulation) + : _irsend(pin, inverted, use_modulation) { this->stateReset(); } + +void IRDelonghiAc::begin(void) { _irsend.begin(); } + +#if SEND_DELONGHI_AC +void IRDelonghiAc::send(const uint16_t repeat) { + _irsend.sendDelonghiAc(getRaw(), kDelonghiAcBits, repeat); +} +#endif // SEND_DELONGHI_AC + +uint8_t IRDelonghiAc::calcChecksum(const uint64_t state) { + uint8_t sum = 0; + // Add up all the 8 bit chunks except for Most-significant 8 bits. + for (uint8_t offset = 0; offset < kDelonghiAcChecksumOffset; offset += 8) { + sum += GETBITS64(state, offset, 8); + } + return sum; +} + +bool IRDelonghiAc::validChecksum(const uint64_t state) { + return (GETBITS64(state, kDelonghiAcChecksumOffset, + kDelonghiAcChecksumSize) == + IRDelonghiAc::calcChecksum(state)); +} + +void IRDelonghiAc::checksum(void) { + setBits(&remote_state, kDelonghiAcChecksumOffset, kDelonghiAcChecksumSize, + calcChecksum(remote_state)); +} + +void IRDelonghiAc::stateReset(void) { + remote_state = 0x5400000000000153; + _saved_temp = 23; // DegC (Random reasonable default value) + _saved_temp_units = 0; // Celsius +} + +uint64_t IRDelonghiAc::getRaw(void) { + checksum(); // Ensure correct bit array before returning + return remote_state; +} + +void IRDelonghiAc::setRaw(const uint64_t state) { remote_state = state; } + +void IRDelonghiAc::on(void) { setPower(true); } + +void IRDelonghiAc::off(void) { setPower(false); } + +void IRDelonghiAc::setPower(const bool on) { + setBit(&remote_state, kDelonghiAcPowerBit, on); +} + +bool IRDelonghiAc::getPower(void) { + return GETBIT64(remote_state, kDelonghiAcPowerBit); +} + +void IRDelonghiAc::setTempUnit(const bool fahrenheit) { + setBit(&remote_state, kDelonghiAcTempUnitBit, fahrenheit); +} + +bool IRDelonghiAc::getTempUnit(void) { + return GETBIT64(remote_state, kDelonghiAcTempUnitBit); +} + +// Set the temp in deg C +void IRDelonghiAc::setTemp(const uint8_t degrees, const bool fahrenheit, + const bool force) { + uint8_t temp; + if (force) { + temp = degrees; // We've been asked to force set this value. + } else { + uint8_t temp_min = kDelonghiAcTempMinC; + uint8_t temp_max = kDelonghiAcTempMaxC; + setTempUnit(fahrenheit); + if (fahrenheit) { + temp_min = kDelonghiAcTempMinF; + temp_max = kDelonghiAcTempMaxF; + } + temp = std::max(temp_min, degrees); + temp = std::min(temp_max, temp); + _saved_temp = temp; + _saved_temp_units = fahrenheit; + temp = temp - temp_min + 1; + } + setBits(&remote_state, kDelonghiAcTempOffset, kDelonghiAcTempSize, + temp); +} + +uint8_t IRDelonghiAc::getTemp(void) { + return GETBITS64(remote_state, kDelonghiAcTempOffset, kDelonghiAcTempSize) + + (getTempUnit() ? kDelonghiAcTempMinF : kDelonghiAcTempMinC) - 1; +} + +// Set the speed of the fan +void IRDelonghiAc::setFan(const uint8_t speed) { + // Mode fan speed rules. + switch (getMode()) { + case kDelonghiAcFan: + // Fan mode can't have auto fan speed. + if (speed == kDelonghiAcFanAuto) { + if (getFan() == kDelonghiAcFanAuto) setFan(kDelonghiAcFanHigh); + return; + } + break; + case kDelonghiAcAuto: + case kDelonghiAcDry: + // Auto & Dry modes only allows auto fan speed. + if (speed != kDelonghiAcFanAuto) { + setFan(kDelonghiAcFanAuto); + return; + } + break; + } + // Bounds check enforcement + if (speed > kDelonghiAcFanLow) + setFan(kDelonghiAcFanAuto); + else + setBits(&remote_state, kDelonghiAcFanOffset, kDelonghiAcFanSize, speed); +} + +uint8_t IRDelonghiAc::getFan(void) { + return GETBITS64(remote_state, kDelonghiAcFanOffset, kDelonghiAcFanSize); +} + +// Convert a standard A/C Fan speed into its native fan speed. +uint8_t IRDelonghiAc::convertFan(const stdAc::fanspeed_t speed) { + switch (speed) { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: + return kDelonghiAcFanLow; + case stdAc::fanspeed_t::kMedium: + return kDelonghiAcFanMedium; + case stdAc::fanspeed_t::kHigh: + case stdAc::fanspeed_t::kMax: + return kDelonghiAcFanHigh; + default: + return kDelonghiAcFanAuto; + } +} + +// Convert a native fan speed to it's common equivalent. +stdAc::fanspeed_t IRDelonghiAc::toCommonFanSpeed(const uint8_t speed) { + switch (speed) { + case kDelonghiAcFanHigh: return stdAc::fanspeed_t::kMax; + case kDelonghiAcFanMedium: return stdAc::fanspeed_t::kMedium; + case kDelonghiAcFanLow: return stdAc::fanspeed_t::kMin; + default: return stdAc::fanspeed_t::kAuto; + } +} + +uint8_t IRDelonghiAc::getMode(void) { + return GETBITS64(remote_state, kDelonghiAcModeOffset, kDelonghiAcModeSize); +} + +void IRDelonghiAc::setMode(const uint8_t mode) { + switch (mode) { + case kDelonghiAcAuto: + case kDelonghiAcDry: + // Set special temp for these modes. + setTemp(kDelonghiAcTempAutoDryMode, getTempUnit(), true); + break; + case kDelonghiAcFan: + // Set special temp for this mode. + setTemp(kDelonghiAcTempFanMode, getTempUnit(), true); + break; + case kDelonghiAcCool: + break; + default: + this->setMode(kDelonghiAcAuto); + return; + } + setBits(&remote_state, kDelonghiAcModeOffset, kDelonghiAcModeSize, mode); + setFan(getFan()); // Re-force any fan speed constraints. + // Restore previous temp settings for cool mode. + if (mode == kDelonghiAcCool) setTemp(_saved_temp, _saved_temp_units); +} + +// Convert a standard A/C mode into its native mode. +uint8_t IRDelonghiAc::convertMode(const stdAc::opmode_t mode) { + switch (mode) { + case stdAc::opmode_t::kCool: + return kDelonghiAcCool; + case stdAc::opmode_t::kDry: + return kDelonghiAcDry; + case stdAc::opmode_t::kFan: + return kDelonghiAcFan; + default: + return kDelonghiAcAuto; + } +} + +// Convert a native mode to it's common equivalent. +stdAc::opmode_t IRDelonghiAc::toCommonMode(const uint8_t mode) { + switch (mode) { + case kDelonghiAcCool: return stdAc::opmode_t::kCool; + case kDelonghiAcDry: return stdAc::opmode_t::kDry; + case kDelonghiAcFan: return stdAc::opmode_t::kFan; + default: return stdAc::opmode_t::kAuto; + } +} + +// Aka Turbo. +void IRDelonghiAc::setBoost(const bool on) { + setBit(&remote_state, kDelonghiAcBoostBit, on); +} + +// Aka Turbo. +bool IRDelonghiAc::getBoost(void) { + return GETBIT64(remote_state, kDelonghiAcBoostBit); +} + +void IRDelonghiAc::setSleep(const bool on) { + setBit(&remote_state, kDelonghiAcSleepBit, on); +} + +bool IRDelonghiAc::getSleep(void) { + return GETBIT64(remote_state, kDelonghiAcSleepBit); +} + +void IRDelonghiAc::setOnTimerEnabled(const bool on) { + setBit(&remote_state, kDelonghiAcOnTimerEnableBit, on); +} + +bool IRDelonghiAc::getOnTimerEnabled(void) { + return GETBIT64(remote_state, kDelonghiAcOnTimerEnableBit); +} + +// Set the On timer to activate in nr of minutes. +// Args: +// nr_of_mins: Total nr of mins to wait before waking the device. +// (Max 23 hrs and 59 minutes. i.e. 1439 mins) +void IRDelonghiAc::setOnTimer(const uint16_t nr_of_mins) { + uint16_t value = std::min(kDelonghiAcTimerMax, nr_of_mins); + setBits(&remote_state, kDelonghiAcOnTimerMinsOffset, kDelonghiAcMinsSize, + value % 60); // Minutes. + setBits(&remote_state, kDelonghiAcOnTimerHoursOffset, kDelonghiAcHoursSize, + value / 60); // Hours. + // Enable or not? + setOnTimerEnabled(value > 0); +} + +uint16_t IRDelonghiAc::getOnTimer(void) { + return GETBITS64(remote_state, kDelonghiAcOnTimerHoursOffset, + kDelonghiAcHoursSize) * 60 + + GETBITS64(remote_state, kDelonghiAcOnTimerMinsOffset, + kDelonghiAcMinsSize); +} + +void IRDelonghiAc::setOffTimerEnabled(const bool on) { + setBit(&remote_state, kDelonghiAcOffTimerEnableBit, on); +} + +bool IRDelonghiAc::getOffTimerEnabled(void) { + return GETBIT64(remote_state, kDelonghiAcOffTimerEnableBit); +} + +// Set the Off timer to activate in nr of minutes. +// Args: +// nr_of_mins: Total nr of mins to wait before waking the device. +// (Max 23 hrs and 59 minutes. i.e. 1439 mins) +void IRDelonghiAc::setOffTimer(const uint16_t nr_of_mins) { + uint16_t value = std::min(kDelonghiAcTimerMax, nr_of_mins); + setBits(&remote_state, kDelonghiAcOffTimerMinsOffset, kDelonghiAcMinsSize, + value % 60); // Minutes. + setBits(&remote_state, kDelonghiAcOffTimerHoursOffset, kDelonghiAcHoursSize, + value / 60); // Hours. + // Enable or not? + setOffTimerEnabled(value > 0); +} + +uint16_t IRDelonghiAc::getOffTimer(void) { + return GETBITS64(remote_state, kDelonghiAcOffTimerHoursOffset, + kDelonghiAcHoursSize) * 60 + + GETBITS64(remote_state, kDelonghiAcOffTimerMinsOffset, + kDelonghiAcMinsSize); +} + +// Convert the A/C state to it's common equivalent. +stdAc::state_t IRDelonghiAc::toCommon(void) { + stdAc::state_t result; + result.protocol = decode_type_t::DELONGHI_AC; + result.power = getPower(); + // result.mode = this->toCommonMode(this->getMode()); + result.celsius = getTempUnit(); + result.degrees = getTemp(); + result.fanspeed = toCommonFanSpeed(this->getFan()); + result.turbo = getBoost(); + result.sleep = getSleep() ? 0 : -1; + // Not supported. + result.model = -1; + result.swingv = stdAc::swingv_t::kOff; + result.swingh = stdAc::swingh_t::kOff; + result.light = false; + result.filter = false; + result.econo = false; + result.quiet = false; + result.clean = false; + result.beep = false; + result.clock = -1; + return result; +} + +// Convert the internal state into a human readable string. +String IRDelonghiAc::toString(void) { + String result = ""; + result.reserve(80); // Reserve some heap for the string to reduce fragging. + result += addBoolToString(getPower(), kPowerStr, false); + result += addModeToString(getMode(), kDelonghiAcAuto, kDelonghiAcCool, + kDelonghiAcAuto, kDelonghiAcDry, kDelonghiAcFan); + result += addFanToString(getFan(), kDelonghiAcFanHigh, kDelonghiAcFanLow, + kDelonghiAcFanAuto, kDelonghiAcFanAuto, + kDelonghiAcFanMedium); + result += addTempToString(getTemp(), !getTempUnit()); + result += addBoolToString(getBoost(), kTurboStr); + result += addBoolToString(getSleep(), kSleepStr); + uint16_t mins = getOnTimer(); + result += addLabeledString((mins && getOnTimerEnabled()) ? minsToString(mins) + : kOffStr, + kOnTimerStr); + mins = getOffTimer(); + result += addLabeledString((mins && getOffTimerEnabled()) ? minsToString(mins) + : kOffStr, + kOffTimerStr); + return result; +} diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.h b/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.h new file mode 100644 index 000000000..8ba8e90f4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.h @@ -0,0 +1,161 @@ +// Delonghi A/C +// +// Copyright 2020 David Conran + +#ifndef IR_DELONGHI_H_ +#define IR_DELONGHI_H_ + +#define __STDC_LIMIT_MACROS +#include +#ifndef UNIT_TEST +#include +#endif +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif + +// Supports: +// Brand: Delonghi, Model: PAC A95 + +// Ref: +// https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 + +// Kudos: +// TheMaxxz: For the breakdown and mapping of the bit values. + +/* State bit map: + ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------+ +| FIXED HEADER | TEMPERATURE | FAN |F or C| ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------+ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + ++--+--+--+--+-----+-----+ +|ON| MODE |Boost|Sleep| ++--+--+--+--+-----+-----+ +16 17 18 19 20 21 + ++--+--+------------+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| 0| 0|Timer Enable| ON TIME HOUR | 0 0| ON TIME MIN | ++--+--+------------+--+--+--+--+--+--+--+--+--+--+--+--+--+ + 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 + ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| 0 0| OFF TIMER | CHECKSUM | ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 + +*/ + +// Constants +const uint8_t kDelonghiAcTempOffset = 8; +const uint8_t kDelonghiAcTempSize = 5; +const uint8_t kDelonghiAcTempMinC = 18; // Deg C +const uint8_t kDelonghiAcTempMaxC = 32; // Deg C +const uint8_t kDelonghiAcTempMinF = 64; // Deg F +const uint8_t kDelonghiAcTempMaxF = 90; // Deg F +const uint8_t kDelonghiAcTempAutoDryMode = 0; +const uint8_t kDelonghiAcTempFanMode = 0b00110; +const uint8_t kDelonghiAcFanOffset = kDelonghiAcTempOffset + + kDelonghiAcTempSize; // 13 +const uint8_t kDelonghiAcFanSize = 2; +const uint8_t kDelonghiAcFanAuto = 0b00; +const uint8_t kDelonghiAcFanHigh = 0b01; +const uint8_t kDelonghiAcFanMedium = 0b10; +const uint8_t kDelonghiAcFanLow = 0b11; +const uint8_t kDelonghiAcTempUnitBit = kDelonghiAcFanOffset + + kDelonghiAcFanSize; // 15 (1 = Celsius, 0 = Fahrenheit) +const uint8_t kDelonghiAcPowerBit = kDelonghiAcTempUnitBit + 1; // 16 +const uint8_t kDelonghiAcModeOffset = kDelonghiAcPowerBit + 1; // 17 +const uint8_t kDelonghiAcModeSize = 3; +const uint8_t kDelonghiAcCool = 0b000; +const uint8_t kDelonghiAcDry = 0b001; +const uint8_t kDelonghiAcFan = 0b010; +const uint8_t kDelonghiAcAuto = 0b100; +const uint8_t kDelonghiAcBoostBit = kDelonghiAcModeOffset + + kDelonghiAcModeSize; // 20 (Aka Turbo) +const uint8_t kDelonghiAcSleepBit = kDelonghiAcBoostBit + 1; // 21 +// Two zero bits +const uint8_t kDelonghiAcOnTimerEnableBit = kDelonghiAcSleepBit + 3; // 24 +const uint8_t kDelonghiAcHoursSize = 5; // Max 23 hrs +const uint8_t kDelonghiAcMinsSize = 6; // Max 59 mins +const uint16_t kDelonghiAcTimerMax = 23 * 60 + 59; +const uint8_t kDelonghiAcOnTimerHoursOffset = kDelonghiAcOnTimerEnableBit + + 1; // 25 +const uint8_t kDelonghiAcOnTimerMinsOffset = kDelonghiAcOnTimerHoursOffset + + kDelonghiAcHoursSize + 2; // 32 (inc another two zero bits) +// Two zero bits +const uint8_t kDelonghiAcOffTimerEnableBit = kDelonghiAcOnTimerMinsOffset + + kDelonghiAcMinsSize + 2; // 40 +const uint8_t kDelonghiAcOffTimerHoursOffset = kDelonghiAcOffTimerEnableBit + + 1; // 41 +const uint8_t kDelonghiAcOffTimerMinsOffset = kDelonghiAcOffTimerHoursOffset + + kDelonghiAcHoursSize + 2; // 48 (inc another two zero bits) +// Two zero bits +const uint8_t kDelonghiAcChecksumOffset = kDelonghiAcOffTimerMinsOffset + + kDelonghiAcMinsSize + 2; // 56 +const uint8_t kDelonghiAcChecksumSize = 8; + + +// Classes +class IRDelonghiAc { + public: + explicit IRDelonghiAc(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + + void stateReset(); +#if SEND_DELONGHI_AC + void send(const uint16_t repeat = kDelonghiAcDefaultRepeat); + int8_t calibrate(void) { return _irsend.calibrate(); } +#endif // SEND_DELONGHI_AC + void begin(); + static uint8_t calcChecksum(const uint64_t state); + static bool validChecksum(const uint64_t state); + void setPower(const bool on); + bool getPower(); + void on(); + void off(); + void setTempUnit(const bool celsius); + bool getTempUnit(void); + void setTemp(const uint8_t temp, const bool fahrenheit = false, + const bool force = false); + uint8_t getTemp(); + void setFan(const uint8_t speed); + uint8_t getFan(); + void setMode(const uint8_t mode); + uint8_t getMode(); + void setBoost(const bool on); // Aka Turbo + bool getBoost(); // Aka Turbo + void setSleep(const bool on); + bool getSleep(); + void setOnTimerEnabled(const bool on); + bool getOnTimerEnabled(void); + void setOnTimer(const uint16_t nr_of_mins); + uint16_t getOnTimer(void); + void setOffTimerEnabled(const bool on); + bool getOffTimerEnabled(void); + void setOffTimer(const uint16_t nr_of_mins); + uint16_t getOffTimer(void); + uint64_t getRaw(); + void setRaw(const uint64_t state); + uint8_t convertMode(const stdAc::opmode_t mode); + uint8_t convertFan(const stdAc::fanspeed_t speed); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + stdAc::state_t toCommon(void); + String toString(); +#ifndef UNIT_TEST + + private: + IRsend _irsend; +#else + IRsendTest _irsend; +#endif + uint64_t remote_state; // The state of the IR remote. + uint8_t _saved_temp; // The previously user requested temp value. + uint8_t _saved_temp_units; // The previously user requested temp units. + void checksum(void); +}; +#endif // IR_DELONGHI_H_ diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Denon.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Denon.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Denon.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Denon.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Dish.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Dish.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Dish.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Dish.cpp diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Doshisha.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Doshisha.cpp new file mode 100644 index 000000000..7352c2c84 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Doshisha.cpp @@ -0,0 +1,132 @@ +// Copyright 2020 Christian (nikize) +// Support for Doshisha protocol + +#include "IRrecv.h" +#include "IRsend.h" +#include "IRutils.h" + +// Supports: +// Brand: Doshisha, Model: CZ-S32D LED Light +// Brand: Doshisha, Model: CZ-S38D LED Light +// Brand: Doshisha, Model: CZ-S50D LED Light +// Brand: Doshisha, Model: RCZ01 remote +// +// Ref: https://www.doshisha-led.com/ + +const uint16_t kDoshishaHdrMark = 3412; +const uint16_t kDoshishaHdrSpace = 1722; +const uint16_t kDoshishaBitMark = 420; +const uint16_t kDoshishaOneSpace = 1310; +const uint16_t kDoshishaZeroSpace = 452; +const uint16_t kDoshishaFreq = 38000; +const uint16_t kDoshishaOverhead = 3; + +// basic structure of bits, and mask +const uint64_t kRcz01CheckMask = 0xffffffff00; +const uint64_t kRcz01CheckExpected = 0x800B304800; +const uint8_t kRcz01CommandMask = 0xFE; +const uint8_t kRcz01ChannelMask = 0x01; + +// Known commands - Here for documentation rather than actual usage +const uint8_t kRcz01CommandSwitchChannel = 0xD2; +const uint8_t kRcz01CommandTimmer60 = 0x52; +const uint8_t kRcz01CommandTimmer30 = 0x92; +const uint8_t kRcz01CommandOff = 0xA0; + +const uint8_t kRcz01CommandLevelDown = 0x2C; +const uint8_t kRcz01CommandLevelUp = 0xCC; +// below are the only ones that turns it on +const uint8_t kRcz01CommandLevel1 = 0xA4; +const uint8_t kRcz01CommandLevel2 = 0x24; +const uint8_t kRcz01CommandLevel3 = 0xC4; +const uint8_t kRcz01CommandLevel4 = 0xD0; + +const uint8_t kRcz01CommandOn = 0xC0; +const uint8_t kRcz01CommandNightLight = 0xC8; +// end Known commands + +#if SEND_DOSHISHA +// Send an Doshisha formatted message. +// +// Args: +// data: The message to be sent. +// nbits: The number of bits of the message to be sent. +// Typically kDelonghiAcBits. +// repeat: The number of times the command is to be repeated. +// +// Status: STABLE / working on a real device. +void IRsend::sendDoshisha(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kDoshishaHdrMark, kDoshishaHdrSpace, + kDoshishaBitMark, kDoshishaOneSpace, + kDoshishaBitMark, kDoshishaZeroSpace, + kDoshishaBitMark, kDefaultMessageGap, + data, nbits, kDoshishaFreq, true, repeat, kDutyDefault); +} + +// Encode Doshisha combining constant values with command and channel. +// +// Args: +// command: The commandcode to be sent. +// channel: The one bit channel 0 for CH1 and 1 for CH2 +// +// Status: STABLE / Working. +uint64_t IRsend::encodeDoshisha(const uint8_t command, const uint8_t channel) { + uint64_t data = kRcz01CheckExpected | + (command & kRcz01CommandMask) | + (channel & kRcz01ChannelMask); + return data; +} +#endif // SEND_DOSHISHA + +#if DECODE_DOSHISHA +// Decode the supplied Doshisha message. +// +// Args: +// results: Ptr to the data to decode and where to store the decode result. +// offset: The starting index to use when attempting to decode the raw data. +// Typically/Defaults to kStartOffset. +// nbits: The number of data bits to expect. Typically kDelonghiAcBits. +// strict: Flag indicating if we should perform strict matching. +// Returns: +// boolean: True if it can decode it, false if it can't. +// +// Status: STABLE / Expected to be working. +bool IRrecv::decodeDoshisha(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (strict && nbits != kDoshishaBits) + return false; + + uint64_t data = 0; + // Match Header + Data + if (!matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kDoshishaHdrMark, kDoshishaHdrSpace, + kDoshishaBitMark, kDoshishaOneSpace, + kDoshishaBitMark, kDoshishaZeroSpace, + kDoshishaBitMark, 0, + true, kTolerance, kMarkExcess, true)) return false; + + // e.g. data = 0x800B3048C0, nbits = 40 + + // RCZ01 remote commands starts with a lead bit set + if ((data & kRcz01CheckMask) != kRcz01CheckExpected) { + DPRINT(" decodeDoshisha data "); + DPRINT(uint64ToString(data, 16)); + DPRINT(" masked "); + DPRINT(uint64ToString(data & kRcz01CheckMask, 16)); + DPRINT(" not matching "); + DPRINT(uint64ToString(kRcz01CheckExpected, 16)); + DPRINTLN(" ."); + return false; // expected lead bits not matching + } + + // Success + results->decode_type = decode_type_t::DOSHISHA; + results->bits = nbits; + results->value = data; + results->command = data & kRcz01CommandMask; + results->address = data & kRcz01ChannelMask; + return true; +} +#endif // DECODE_DOSHISHA diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Electra.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Electra.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Electra.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Electra.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Electra.h b/lib/IRremoteESP8266-2.7.7/src/ir_Electra.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Electra.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Electra.h index 2d5fe09f5..0f0e119f7 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Electra.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Electra.h @@ -86,7 +86,7 @@ class IRElectraAc { void stateReset(void); #if SEND_ELECTRA_AC void send(const uint16_t repeat = kElectraAcMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_ELECTRA_AC void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Epson.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Epson.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Epson.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Epson.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Fujitsu.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Fujitsu.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Fujitsu.h b/lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.h similarity index 99% rename from lib/IRremoteESP8266-2.7.6/src/ir_Fujitsu.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.h index eae0edb8f..17e791ac8 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Fujitsu.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.h @@ -107,7 +107,7 @@ class IRFujitsuAC { void stateReset(void); #if SEND_FUJITSU_AC void send(const uint16_t repeat = kFujitsuAcMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_FUJITSU_AC void begin(void); void stepHoriz(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_GICable.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_GICable.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_GICable.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_GICable.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_GlobalCache.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_GlobalCache.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_GlobalCache.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_GlobalCache.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Goodweather.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Goodweather.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Goodweather.h b/lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Goodweather.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.h index 8f1953581..7e1d6115d 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Goodweather.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.h @@ -95,7 +95,7 @@ class IRGoodweatherAc { void stateReset(void); #if SEND_GOODWEATHER void send(const uint16_t repeat = kGoodweatherMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_GOODWEATHER void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Gree.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Gree.cpp similarity index 82% rename from lib/IRremoteESP8266-2.7.6/src/ir_Gree.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Gree.cpp index 81062d650..66eb3a2f0 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Gree.cpp +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Gree.cpp @@ -210,17 +210,60 @@ bool IRGreeAC::getPower(void) { return GETBIT8(remote_state[0], kGreePower1Offset); } -// Set the temp. in deg C -void IRGreeAC::setTemp(const uint8_t temp) { - uint8_t new_temp = std::max((uint8_t)kGreeMinTemp, temp); - new_temp = std::min((uint8_t)kGreeMaxTemp, new_temp); - if (getMode() == kGreeAuto) new_temp = 25; - setBits(&remote_state[1], kLowNibble, kGreeTempSize, new_temp - kGreeMinTemp); +/// Set the default temperature units to use. +/// @param[in] on Use Fahrenheit as the units. +/// true is Fahrenheit, false is Celsius. +void IRGreeAC::setUseFahrenheit(const bool on) { + setBit(&remote_state[3], kGreeUseFahrenheitOffset, on); } -// Return the set temp. in deg C +/// Get the default temperature units in use. +/// @return true is Fahrenheit, false is Celsius. +bool IRGreeAC::getUseFahrenheit(void) { + return GETBIT8(remote_state[3], kGreeUseFahrenheitOffset); +} + +/// Set the temp. in degrees +/// @param[in] temp Desired temperature in Degrees. +/// @param[in] fahrenheit Use units of Fahrenheit and set that as units used. +/// false is Celsius (Default), true is Fahrenheit. +/// @note The unit actually works in Celsius with a special optional +/// "extra degree" when sing Fahrenheit. +void IRGreeAC::setTemp(const uint8_t temp, const bool fahrenheit) { + float safecelsius = temp; + if (fahrenheit) + // Covert to F, and add a fudge factor to round to the expected degree. + // Why 0.6 you ask?! Because it works. Ya'd thing 0.5 would be good for + // rounding, but Noooooo! + safecelsius = fahrenheitToCelsius(temp + 0.6); + setUseFahrenheit(fahrenheit); // Set the correct Temp units. + + // Make sure we have desired temp in the correct range. + safecelsius = std::max(static_cast(kGreeMinTempC), safecelsius); + safecelsius = std::min(static_cast(kGreeMaxTempC), safecelsius); + // An operating mode of Auto locks the temp to a specific value. Do so. + if (getMode() == kGreeAuto) safecelsius = 25; + + // Set the "main" Celsius degrees. + setBits(&remote_state[1], kGreeTempOffset, kGreeTempSize, + safecelsius - kGreeMinTempC); + // Deal with the extra degree fahrenheit difference. + setBit(&remote_state[3], kGreeTempExtraDegreeFOffset, + (uint8_t)(safecelsius * 2) & 1); +} + +/// Return the set temperature +/// @return The temperature in degrees in the current units (C/F) set. uint8_t IRGreeAC::getTemp(void) { - return GETBITS8(remote_state[1], kLowNibble, kGreeTempSize) + kGreeMinTemp; + uint8_t deg = kGreeMinTempC + GETBITS8(remote_state[1], kGreeTempOffset, + kGreeTempSize); + if (getUseFahrenheit()) { + deg = celsiusToFahrenheit(deg); + // Retreive the "extra" fahrenheit from elsewhere in the code. + if (GETBIT8(remote_state[3], kGreeTempExtraDegreeFOffset)) deg++; + deg = std::max(deg, kGreeMinTempF); // Cover the fact that 61F is < 16C + } + return deg; } // Set the speed of the fan, 0-3, 0 is auto, 1-3 is the speed @@ -376,6 +419,28 @@ void IRGreeAC::setTimer(const uint16_t minutes) { hours % 10); } +/// Set temperature display mode. +/// i.e. Internal, External temperature sensing. +/// @param[in] mode The desired temp source to display. +/// @note In order for the A/C unit properly accept these settings. You must +/// cycle (send) in the following order: +/// kGreeDisplayTempOff(0) -> kGreeDisplayTempSet(1) -> +/// kGreeDisplayTempInside(2) ->kGreeDisplayTempOutside(3) -> +/// kGreeDisplayTempOff(0). +/// The unit will no behave correctly if the changes of this setting are sent +/// out of order. +/// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1118#issuecomment-628242152 +void IRGreeAC::setDisplayTempSource(const uint8_t mode) { + setBits(&remote_state[5], kGreeDisplayTempOffset, kGreeDisplayTempSize, mode); +} +/// Get the temperature display mode. +/// i.e. Internal, External temperature sensing. +/// @return The current temp source being displayed. +uint8_t IRGreeAC::getDisplayTempSource(void) { + return GETBITS8(remote_state[5], kGreeDisplayTempOffset, + kGreeDisplayTempSize); +} + // Convert a standard A/C mode into its native mode. uint8_t IRGreeAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { @@ -451,7 +516,7 @@ stdAc::state_t IRGreeAC::toCommon(void) { result.model = this->getModel(); result.power = this->getPower(); result.mode = this->toCommonMode(this->getMode()); - result.celsius = true; + result.celsius = !this->getUseFahrenheit(); result.degrees = this->getTemp(); result.fanspeed = this->toCommonFanSpeed(this->getFan()); if (this->getSwingVerticalAuto()) @@ -475,12 +540,12 @@ stdAc::state_t IRGreeAC::toCommon(void) { // Convert the internal state into a human readable string. String IRGreeAC::toString(void) { String result = ""; - result.reserve(150); // Reserve some heap for the string to reduce fragging. + result.reserve(220); // Reserve some heap for the string to reduce fragging. result += addModelToString(decode_type_t::GREE, getModel(), false); result += addBoolToString(getPower(), kPowerStr); result += addModeToString(getMode(), kGreeAuto, kGreeCool, kGreeHeat, kGreeDry, kGreeFan); - result += addTempToString(getTemp()); + result += addTempToString(getTemp(), !getUseFahrenheit()); result += addFanToString(getFan(), kGreeFanMax, kGreeFanMin, kGreeFanAuto, kGreeFanAuto, kGreeFanMed); result += addBoolToString(getTurbo(), kTurboStr); @@ -505,6 +570,25 @@ String IRGreeAC::toString(void) { result += ')'; result += addLabeledString( getTimerEnabled() ? minsToString(getTimer()) : kOffStr, kTimerStr); + uint8_t src = getDisplayTempSource(); + result += addIntToString(src, kDisplayTempStr); + result += kSpaceLBraceStr; + switch (src) { + case kGreeDisplayTempOff: + result += kOffStr; + break; + case kGreeDisplayTempSet: + result += kSetStr; + break; + case kGreeDisplayTempInside: + result += kInsideStr; + break; + case kGreeDisplayTempOutside: + result += kOutsideStr; + break; + default: result += kUnknownStr; + } + result += ')'; return result; } diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Gree.h b/lib/IRremoteESP8266-2.7.7/src/ir_Gree.h similarity index 74% rename from lib/IRremoteESP8266-2.7.6/src/ir_Gree.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Gree.h index 14cd7b84a..4748c4769 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Gree.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Gree.h @@ -8,6 +8,8 @@ // Brand: RusClimate, Model: YAW1F remote // Brand: Green, Model: YBOFB remote // Brand: Green, Model: YBOFB2 remote +// Brand: Gree, Model: YAA1FBF remote +// Brand: Gree, Model: YB1F2F remote #ifndef IR_GREE_H_ #define IR_GREE_H_ @@ -31,7 +33,7 @@ const uint8_t kGreeDry = 2; const uint8_t kGreeFan = 3; const uint8_t kGreeHeat = 4; -// Byte 0 +// Byte[0] const uint8_t kGreePower1Offset = 3; const uint8_t kGreeFanOffset = 4; const uint8_t kGreeFanSize = 2; // Bits @@ -41,17 +43,19 @@ const uint8_t kGreeFanMed = 2; const uint8_t kGreeFanMax = 3; const uint8_t kGreeSwingAutoOffset = 6; const uint8_t kGreeSleepOffset = 7; -// Byte 1 -const uint8_t kGreeTempSize = 4; -const uint8_t kGreeMinTemp = 16; // Celsius -const uint8_t kGreeMaxTemp = 30; // Celsius -const uint8_t kGreeTimerHalfHrOffset = 4; +// Byte[1] +const uint8_t kGreeTempOffset = 0; +const uint8_t kGreeTempSize = 4; // Mask 0b0000xxxx +const uint8_t kGreeMinTempC = 16; // Celsius +const uint8_t kGreeMaxTempC = 30; // Celsius +const uint8_t kGreeMinTempF = 61; // Fahrenheit +const uint8_t kGreeMaxTempF = 86; // Fahrenheit +const uint8_t kGreeTimerHalfHrOffset = 4; // Mask 0b000x0000 const uint8_t kGreeTimerTensHrOffset = 5; -const uint8_t kGreeTimerTensHrSize = 2; // Bits +const uint8_t kGreeTimerTensHrSize = 2; // Mask 0b0xx00000 const uint16_t kGreeTimerMax = 24 * 60; -const uint8_t kGreeTimerEnabledOffset = 7; - -// Byte 2 +const uint8_t kGreeTimerEnabledOffset = 7; // Mask 0bx0000000 +// Byte[2] const uint8_t kGreeTimerHoursOffset = 0; const uint8_t kGreeTimerHoursSize = 4; // Bits const uint8_t kGreeTurboOffset = 4; @@ -59,7 +63,10 @@ const uint8_t kGreeLightOffset = 5; // This might not be used. See #814 const uint8_t kGreePower2Offset = 6; const uint8_t kGreeXfanOffset = 7; -// Byte 4 +// Byte[3] +const uint8_t kGreeTempExtraDegreeFOffset = 2; // Mask 0b00000x00 +const uint8_t kGreeUseFahrenheitOffset = 3; // Mask 0b0000x000 +// Byte[4] const uint8_t kGreeSwingSize = 4; // Bits const uint8_t kGreeSwingLastPos = 0b0000; const uint8_t kGreeSwingAuto = 0b0001; @@ -71,9 +78,16 @@ const uint8_t kGreeSwingDown = 0b0110; const uint8_t kGreeSwingDownAuto = 0b0111; const uint8_t kGreeSwingMiddleAuto = 0b1001; const uint8_t kGreeSwingUpAuto = 0b1011; -// byte 5 -const uint8_t kGreeIFeelOffset = 2; -const uint8_t kGreeWiFiOffset = 6; +// Byte[5] +const uint8_t kGreeWiFiOffset = 6; // Mask 0b0x000000 +const uint8_t kGreeIFeelOffset = 2; // Mask 0b00000x00 +const uint8_t kGreeDisplayTempOffset = 0; +const uint8_t kGreeDisplayTempSize = 2; // Mask 0b000000xx +const uint8_t kGreeDisplayTempOff = 0b00; // 0 +const uint8_t kGreeDisplayTempSet = 0b01; // 1 +const uint8_t kGreeDisplayTempInside = 0b10; // 2 +const uint8_t kGreeDisplayTempOutside = 0b11; // 3 + // Legacy defines. #define GREE_AUTO kGreeAuto @@ -81,8 +95,8 @@ const uint8_t kGreeWiFiOffset = 6; #define GREE_DRY kGreeDry #define GREE_FAN kGreeFan #define GREE_HEAT kGreeHeat -#define GREE_MIN_TEMP kGreeMinTemp -#define GREE_MAX_TEMP kGreeMaxTemp +#define GREE_MIN_TEMP kGreeMinTempC +#define GREE_MAX_TEMP kGreeMaxTempC #define GREE_FAN_MAX kGreeFanMax #define GREE_SWING_LAST_POS kGreeSwingLastPos #define GREE_SWING_AUTO kGreeSwingAuto @@ -106,7 +120,7 @@ class IRGreeAC { void stateReset(void); #if SEND_GREE void send(const uint16_t repeat = kGreeDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_GREE void begin(void); void on(void); @@ -115,8 +129,10 @@ class IRGreeAC { gree_ac_remote_model_t getModel(void); void setPower(const bool on); bool getPower(void); - void setTemp(const uint8_t temp); + void setTemp(const uint8_t temp, const bool fahrenheit = false); uint8_t getTemp(void); + void setUseFahrenheit(const bool on); + bool getUseFahrenheit(void); void setFan(const uint8_t speed); uint8_t getFan(void); void setMode(const uint8_t new_mode); @@ -138,6 +154,8 @@ class IRGreeAC { uint8_t getSwingVerticalPosition(void); uint16_t getTimer(void); void setTimer(const uint16_t minutes); + void setDisplayTempSource(const uint8_t mode); + uint8_t getDisplayTempSource(void); uint8_t convertMode(const stdAc::opmode_t mode); uint8_t convertFan(const stdAc::fanspeed_t speed); uint8_t convertSwingV(const stdAc::swingv_t swingv); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Haier.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Haier.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Haier.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Haier.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Haier.h b/lib/IRremoteESP8266-2.7.7/src/ir_Haier.h similarity index 99% rename from lib/IRremoteESP8266-2.7.6/src/ir_Haier.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Haier.h index 587c4c560..92eb3b05c 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Haier.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Haier.h @@ -217,7 +217,7 @@ class IRHaierAC { #if SEND_HAIER_AC void send(const uint16_t repeat = kHaierAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HAIER_AC void begin(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Hitachi.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Hitachi.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Hitachi.h b/lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Hitachi.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.h index 0db3552ff..47fbb9b02 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Hitachi.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.h @@ -147,7 +147,7 @@ class IRHitachiAc { void stateReset(void); #if SEND_HITACHI_AC void send(const uint16_t repeat = kHitachiAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HITACHI_AC void begin(void); void on(void); @@ -198,7 +198,7 @@ class IRHitachiAc1 { void stateReset(void); #if SEND_HITACHI_AC1 void send(const uint16_t repeat = kHitachiAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HITACHI_AC1 void begin(void); void on(void); @@ -260,7 +260,7 @@ class IRHitachiAc424 { void stateReset(void); #if SEND_HITACHI_AC424 void send(const uint16_t repeat = kHitachiAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HITACHI_AC424 void begin(void); void on(void); @@ -307,7 +307,7 @@ class IRHitachiAc3 { void stateReset(void); #if SEND_HITACHI_AC3 void send(const uint16_t repeat = kHitachiAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HITACHI_AC3 void begin(void); uint8_t getMode(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Inax.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Inax.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Inax.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Inax.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_JVC.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_JVC.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_JVC.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_JVC.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Kelvinator.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Kelvinator.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Kelvinator.h b/lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.h similarity index 99% rename from lib/IRremoteESP8266-2.7.6/src/ir_Kelvinator.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.h index fac26bf2e..cd3a000dd 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Kelvinator.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.h @@ -141,7 +141,7 @@ class IRKelvinatorAC { void stateReset(void); #if SEND_KELVINATOR void send(const uint16_t repeat = kKelvinatorDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_KELVINATOR void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_LG.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_LG.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_LG.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_LG.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_LG.h b/lib/IRremoteESP8266-2.7.7/src/ir_LG.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_LG.h rename to lib/IRremoteESP8266-2.7.7/src/ir_LG.h index 1147b30b7..64b6a0b7c 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_LG.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_LG.h @@ -67,7 +67,7 @@ class IRLgAc { bool isValidLgAc(void); #if SEND_LG void send(const uint16_t repeat = kLgDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_LG void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Lasertag.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Lasertag.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Lasertag.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Lasertag.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Lego.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Lego.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Lego.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Lego.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Lutron.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Lutron.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Lutron.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Lutron.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_MWM.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_MWM.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_MWM.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_MWM.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Magiquest.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Magiquest.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Magiquest.h b/lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Magiquest.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.h diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Midea.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Midea.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Midea.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Midea.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Midea.h b/lib/IRremoteESP8266-2.7.7/src/ir_Midea.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Midea.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Midea.h index af005d729..be43a4df6 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Midea.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Midea.h @@ -74,7 +74,7 @@ class IRMideaAC { void stateReset(void); #if SEND_MIDEA void send(const uint16_t repeat = kMideaMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MIDEA void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Mitsubishi.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Mitsubishi.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Mitsubishi.h b/lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Mitsubishi.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.h index 31021514f..b9cc7b349 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Mitsubishi.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.h @@ -159,7 +159,7 @@ class IRMitsubishiAC { static bool validChecksum(const uint8_t* data); #if SEND_MITSUBISHI_AC void send(const uint16_t repeat = kMitsubishiACMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MITSUBISHI_AC void begin(void); void on(void); @@ -217,7 +217,7 @@ class IRMitsubishi136 { void stateReset(void); #if SEND_MITSUBISHI136 void send(const uint16_t repeat = kMitsubishi136MinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MITSUBISHI136 void begin(void); static bool validChecksum(const uint8_t* data, @@ -267,7 +267,7 @@ class IRMitsubishi112 { void stateReset(void); #if SEND_MITSUBISHI112 void send(const uint16_t repeat = kMitsubishi112MinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MITSUBISHI112 void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_MitsubishiHeavy.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_MitsubishiHeavy.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_MitsubishiHeavy.h b/lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.h similarity index 99% rename from lib/IRremoteESP8266-2.7.6/src/ir_MitsubishiHeavy.h rename to lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.h index 2c2097d03..39c30e0ac 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_MitsubishiHeavy.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.h @@ -133,7 +133,7 @@ class IRMitsubishiHeavy152Ac { void stateReset(void); #if SEND_MITSUBISHIHEAVY void send(const uint16_t repeat = kMitsubishiHeavy152MinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MITSUBISHIHEAVY void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Multibrackets.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Multibrackets.cpp new file mode 100644 index 000000000..0a0dfbe71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Multibrackets.cpp @@ -0,0 +1,128 @@ +// Copyright 2020 David Conran + +#include "IRrecv.h" +#include "IRsend.h" + +// Multibrackets protocol. +// +// Supports: +// Brand: Multibrackets, Model: Motorized Swing mount large - 4500 + +const uint16_t kMultibracketsTick = 5000; // uSeconds +const uint16_t kMultibracketsHdrMark = 3 * kMultibracketsTick; // uSeconds +const uint16_t kMultibracketsFooterSpace = 6 * kMultibracketsTick; // uSeconds +const uint8_t kMultibracketsTolerance = 5; // Percent +const uint16_t kMultibracketsFreq = 38000; // Hertz + +#if SEND_MULTIBRACKETS +// Send a Miltibrackets formatted message. +// +// Args: +// data: The message to be sent. +// nbits: The number of bits of the message to be sent. +// Typically kMultibracketsBits. +// repeat: The number of times the command is to be repeated. +// +// Status: BETA / Appears to be working. +// +// Ref: +// https://github.com/crankyoldgit/IRremoteESP8266/issues/1103 +// http://info.multibrackets.com/data/common/manuals/4500_code.pdf +void IRsend::sendMultibrackets(uint64_t data, uint16_t nbits, uint16_t repeat) { + enableIROut(kMultibracketsFreq); + for (uint16_t r = 0; r <= repeat; r++) { + uint16_t bits = nbits; + // Header + mark(kMultibracketsHdrMark); + // Data + // Send 0's until we get down to a bit size we can actually manage. + while (bits > sizeof(data) * 8) { + space(kMultibracketsTick); + bits--; + } + // Send the supplied data. + for (uint64_t mask = 1ULL << (bits - 1); mask; mask >>= 1) + if (data & mask) // Send a 1 + mark(kMultibracketsTick); + else // Send a 0 + space(kMultibracketsTick); + // Footer + space(kMultibracketsFooterSpace); + } +} +#endif // SEND_MULTIBRACKETS + +#if DECODE_MULTIBRACKETS +// Decode the Multibrackets message. +// +// Args: +// results: Ptr to the data to decode and where to store the decode result. +// offset: The starting index to use when attempting to decode the raw data. +// Typically/Defaults to kStartOffset. +// nbits: The number of data bits to expect. Typically kMultibracketsBits. +// strict: Flag indicating if we should perform strict matching. +// Returns: +// boolean: True if it can decode it, false if it can't. +// +// Status: BETA / Appears to be working. +// +// Ref: +// https://github.com/crankyoldgit/IRremoteESP8266/issues/1103 +// http://info.multibrackets.com/data/common/manuals/4500_code.pdf +bool IRrecv::decodeMultibrackets(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + // Compliance + if (strict && nbits != kMultibracketsBits) + return false; // Doesn't match our protocol defn. + + // Check there is enough unprocessed buffer left. + if (results->rawlen < offset) return false; + + // Header + int32_t remaining = *(results->rawbuf + offset); + if (!matchAtLeast(remaining, kMultibracketsHdrMark, kMultibracketsTolerance)) + return false; + remaining -= (kMultibracketsHdrMark / kRawTick); // Remove the header. + + // We are done with the header. Onto the data. + bool bit = true; + uint16_t bitsSoFar = 0; + uint64_t data = 0; + // Keep going till we run out of message or expected bits. + while (offset <= results->rawlen && bitsSoFar < nbits) { + // Have we finished processing this rawbuf value yet? + if (remaining <= 0) { // No more possible "bits" left in this value. + // Invert the bit for next time, and move along the rawbuf. + bit = !bit; + offset++; + // Load the next data point if there is one. + if (offset <= results->rawlen) remaining = *(results->rawbuf + offset); + } else { // Look for more bits in this entry. + if (matchAtLeast(remaining, kMultibracketsTick, + kMultibracketsTolerance)) { // There is! + data <<= 1; + data += bit; + bitsSoFar++; + } + remaining -= (kMultibracketsTick / kRawTick); // Remove the "bit". + } + } + + // Compliance + if (bitsSoFar != nbits) return false; + + // Footer + if (results->rawlen <= offset && !matchAtLeast(*(results->rawbuf + offset), + kMultibracketsFooterSpace, + kMultibracketsTolerance)) + return false; + + // Success + results->decode_type = decode_type_t::MULTIBRACKETS; + results->value = data; + results->bits = nbits; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_MULTIBRACKETS diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_NEC.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_NEC.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_NEC.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_NEC.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_NEC.h b/lib/IRremoteESP8266-2.7.7/src/ir_NEC.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_NEC.h rename to lib/IRremoteESP8266-2.7.7/src/ir_NEC.h diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Neoclima.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Neoclima.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Neoclima.h b/lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Neoclima.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.h index 360c665d6..e1555e917 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Neoclima.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.h @@ -92,7 +92,7 @@ class IRNeoclimaAc { void stateReset(void); #if SEND_NEOCLIMA void send(const uint16_t repeat = kNeoclimaMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_NEOCLIMA void begin(void); void setButton(const uint8_t button); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Nikai.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Nikai.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Nikai.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Nikai.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Panasonic.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Panasonic.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Panasonic.h b/lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.h similarity index 99% rename from lib/IRremoteESP8266-2.7.6/src/ir_Panasonic.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.h index 42e771fb3..c97f69fde 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Panasonic.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.h @@ -102,7 +102,7 @@ class IRPanasonicAc { void stateReset(void); #if SEND_PANASONIC void send(const uint16_t repeat = kPanasonicAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_PANASONIC void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Pioneer.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Pioneer.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Pioneer.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Pioneer.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Pronto.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Pronto.cpp similarity index 93% rename from lib/IRremoteESP8266-2.7.6/src/ir_Pronto.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Pronto.cpp index 6b7a779de..4a9a45d97 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Pronto.cpp +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Pronto.cpp @@ -69,7 +69,7 @@ void IRsend::sendPronto(uint16_t data[], uint16_t len, uint16_t repeat) { uint16_t seq_1_start = kProntoDataOffset; uint16_t seq_2_start = kProntoDataOffset + seq_1_len; - uint32_t periodic_time = calcUSecPeriod(hz, false); + uint32_t periodic_time_x10 = calcUSecPeriod(hz / 10, false); // Normal (1st sequence) case. // Is there a first (normal) sequence to send? @@ -78,8 +78,8 @@ void IRsend::sendPronto(uint16_t data[], uint16_t len, uint16_t repeat) { if (seq_1_len + seq_1_start > len) return; // Send the contents of the 1st sequence. for (uint16_t i = seq_1_start; i < seq_1_start + seq_1_len; i += 2) { - mark(data[i] * periodic_time); - space(data[i + 1] * periodic_time); + mark((data[i] * periodic_time_x10) / 10); + space((data[i + 1] * periodic_time_x10) / 10); } } else { // There was no first sequence to send, it is implied that we have to send @@ -96,8 +96,8 @@ void IRsend::sendPronto(uint16_t data[], uint16_t len, uint16_t repeat) { // Send the contents of the 2nd sequence. for (uint16_t r = 0; r < repeat; r++) for (uint16_t i = seq_2_start; i < seq_2_start + seq_2_len; i += 2) { - mark(data[i] * periodic_time); - space(data[i + 1] * periodic_time); + mark((data[i] * periodic_time_x10) / 10); + space((data[i + 1] * periodic_time_x10) / 10); } } } diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_RC5_RC6.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_RC5_RC6.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_RC5_RC6.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_RC5_RC6.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_RCMM.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_RCMM.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_RCMM.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_RCMM.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Samsung.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Samsung.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Samsung.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Samsung.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Samsung.h b/lib/IRremoteESP8266-2.7.7/src/ir_Samsung.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Samsung.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Samsung.h index 31b5ea181..9c9e6ab8e 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Samsung.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Samsung.h @@ -99,7 +99,7 @@ class IRSamsungAc { const bool calcchecksum = true); void sendOn(const uint16_t repeat = kSamsungAcDefaultRepeat); void sendOff(const uint16_t repeat = kSamsungAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_SAMSUNG_AC void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Sanyo.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Sanyo.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Sanyo.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Sanyo.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Sharp.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Sharp.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.6/src/ir_Sharp.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Sharp.cpp index 363271012..95a3de5cc 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Sharp.cpp +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Sharp.cpp @@ -46,6 +46,7 @@ using irutils::addIntToString; using irutils::addLabeledString; using irutils::addModeToString; using irutils::addTempToString; +using irutils::minsToString; using irutils::setBit; using irutils::setBits; @@ -324,6 +325,9 @@ void IRSharpAc::stateReset(void) { 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x01, 0x00, 0x00, 0x08, 0x80, 0x00, 0xE0, 0x01}; memcpy(remote, reset, kSharpAcStateLength); + _temp = getTemp(); + _mode = getMode(); + _fan = getFan(); } uint8_t *IRSharpAc::getRaw(void) { @@ -335,53 +339,74 @@ void IRSharpAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote, new_code, std::min(length, kSharpAcStateLength)); } -void IRSharpAc::setPreviousPower(const bool on) { - setBit(&remote[kSharpAcBytePower], kSharpAcBitPreviousPowerOffset, on); +void IRSharpAc::setPowerSpecial(const uint8_t value) { + setBits(&remote[kSharpAcBytePowerSpecial], kSharpAcPowerSetSpecialOffset, + kSharpAcPowerSpecialSize, value); } -bool IRSharpAc::getPreviousPower(void) { - return GETBIT8(remote[kSharpAcBytePower], kSharpAcBitPreviousPowerOffset); +uint8_t IRSharpAc::getPowerSpecial(void) { + return GETBITS8(remote[kSharpAcBytePowerSpecial], + kSharpAcPowerSetSpecialOffset, kSharpAcPowerSpecialSize); +} + +// Clear the "special"/non-normal bits in the power section. +// e.g. for normal/common command modes. +void IRSharpAc::clearPowerSpecial(void) { + setPowerSpecial(getPowerSpecial() & kSharpAcPowerOn); +} + +bool IRSharpAc::isPowerSpecial(void) { + switch (getPowerSpecial()) { + case kSharpAcPowerSetSpecialOff: + case kSharpAcPowerSetSpecialOn: + case kSharpAcPowerTimerSetting: return true; + default: return false; + } } void IRSharpAc::on(void) { setPower(true); } void IRSharpAc::off(void) { setPower(false); } -void IRSharpAc::setPower(const bool on) { - setPreviousPower(getPower()); - setBit(&remote[kSharpAcBytePower], kSharpAcBitPowerOffset, on); - setButton(kSharpAcButtonPowerMode); -} - -void IRSharpAc::setPower(const bool on, const bool prev) { - setPower(on); - setPreviousPower(prev); +void IRSharpAc::setPower(const bool on, const bool prev_on) { + setPowerSpecial(on ? (prev_on ? kSharpAcPowerOn : kSharpAcPowerOnFromOff) + : kSharpAcPowerOff); + // Power operations are incompatible with clean mode. + if (getClean()) setClean(false); + setSpecial(kSharpAcSpecialPower); } bool IRSharpAc::getPower(void) { - return GETBIT8(remote[kSharpAcBytePower], kSharpAcBitPowerOffset); -} - -void IRSharpAc::setButton(const uint8_t button) { - switch (button) { - case kSharpAcButtonPowerMode: - case kSharpAcButtonTemp: - case kSharpAcButtonFan: - setBits(&remote[kSharpAcByteButton], kSharpAcButtonOffset, - kSharpAcButtonSize, button); - break; - default: - setButton(kSharpAcButtonPowerMode); + switch (getPowerSpecial()) { + case kSharpAcPowerUnknown: + case kSharpAcPowerOff: return false; + default: return true; // Everything else is "probably" on. } } -uint8_t IRSharpAc::getButton(void) { - return GETBITS8(remote[kSharpAcByteButton], kSharpAcButtonOffset, - kSharpAcButtonSize); +void IRSharpAc::setSpecial(const uint8_t mode) { + switch (mode) { + case kSharpAcSpecialPower: + case kSharpAcSpecialTurbo: + case kSharpAcSpecialTempEcono: + case kSharpAcSpecialFan: + case kSharpAcSpecialSwing: + case kSharpAcSpecialTimer: + case kSharpAcSpecialTimerHalfHour: + remote[kSharpAcByteSpecial] = mode; + break; + default: + setSpecial(kSharpAcSpecialPower); + } } +uint8_t IRSharpAc::getSpecial(void) { return remote[kSharpAcByteSpecial]; } + // Set the temp in deg C -void IRSharpAc::setTemp(const uint8_t temp) { +// Args: +// temp: Desired Temperature (Celsius) +// save: Do we save this Temperature as a user set temp? (Default: true) +void IRSharpAc::setTemp(const uint8_t temp, const bool save) { switch (this->getMode()) { // Auto & Dry don't allow temp changes and have a special temp. case kSharpAcAuto: @@ -393,9 +418,11 @@ void IRSharpAc::setTemp(const uint8_t temp) { } uint8_t degrees = std::max(temp, kSharpAcMinTemp); degrees = std::min(degrees, kSharpAcMaxTemp); + if (save) _temp = degrees; setBits(&remote[kSharpAcByteTemp], kLowNibble, kNibbleSize, degrees - kSharpAcMinTemp); - setButton(kSharpAcButtonTemp); + setSpecial(kSharpAcSpecialTempEcono); + clearPowerSpecial(); } uint8_t IRSharpAc::getTemp(void) { @@ -407,25 +434,32 @@ uint8_t IRSharpAc::getMode(void) { return GETBITS8(remote[kSharpAcByteMode], kLowNibble, kSharpAcModeSize); } -void IRSharpAc::setMode(const uint8_t mode) { +void IRSharpAc::setMode(const uint8_t mode, const bool save) { switch (mode) { case kSharpAcAuto: case kSharpAcDry: - this->setFan(2); // When Dry or Auto, Fan always 2(Auto) - this->setTemp(0); // Dry/Auto have no temp setting. + // When Dry or Auto, Fan always 2(Auto) + this->setFan(kSharpAcFanAuto, false); // FALLTHRU case kSharpAcCool: case kSharpAcHeat: setBits(&remote[kSharpAcByteMode], kLowNibble, kSharpAcModeSize, mode); break; default: - this->setMode(kSharpAcAuto); + this->setMode(kSharpAcAuto, save); + return; } - setButton(kSharpAcButtonPowerMode); + // Dry/Auto have no temp setting. This step will enforce it. + this->setTemp(_temp, false); + // Save the mode in case we need to revert to it. eg. Clean + if (save) _mode = mode; + + setSpecial(kSharpAcSpecialPower); + clearPowerSpecial(); } // Set the speed of the fan -void IRSharpAc::setFan(const uint8_t speed) { +void IRSharpAc::setFan(const uint8_t speed, const bool save) { switch (speed) { case kSharpAcFanAuto: case kSharpAcFanMin: @@ -437,14 +471,123 @@ void IRSharpAc::setFan(const uint8_t speed) { break; default: this->setFan(kSharpAcFanAuto); + return; } - setButton(kSharpAcButtonFan); + if (save) _fan = speed; + setSpecial(kSharpAcSpecialFan); + clearPowerSpecial(); } uint8_t IRSharpAc::getFan(void) { return GETBITS8(remote[kSharpAcByteFan], kSharpAcFanOffset, kSharpAcFanSize); } +bool IRSharpAc::getTurbo(void) { + return (getPowerSpecial() == kSharpAcPowerSetSpecialOn) && + (getSpecial() == kSharpAcSpecialTurbo); +} + +// Note: If you use this method, you will need to send it before making +// other changes to the settings, as they may overwrite some of the bits +// used by this setting. +void IRSharpAc::setTurbo(const bool on) { + if (on) setFan(kSharpAcFanMax); + setPowerSpecial(on ? kSharpAcPowerSetSpecialOn : kSharpAcPowerSetSpecialOff); + setSpecial(kSharpAcSpecialTurbo); +} + +bool IRSharpAc::getSwingToggle(void) { + return GETBITS8(remote[kSharpAcByteSwing], kSharpAcSwingOffset, + kSharpAcSwingSize) == kSharpAcSwingToggle; +} + +void IRSharpAc::setSwingToggle(const bool on) { + setBits(&remote[kSharpAcByteSwing], kSharpAcSwingOffset, kSharpAcSwingSize, + on ? kSharpAcSwingToggle : kSharpAcSwingNoToggle); + if (on) setSpecial(kSharpAcSpecialSwing); +} + +bool IRSharpAc::getIon(void) { + return GETBIT8(remote[kSharpAcByteIon], kSharpAcBitIonOffset); +} + +void IRSharpAc::setIon(const bool on) { + setBit(&remote[kSharpAcByteIon], kSharpAcBitIonOffset, on); + clearPowerSpecial(); + if (on) setSpecial(kSharpAcSpecialSwing); +} + +bool IRSharpAc::getEconoToggle(void) { + return (getPowerSpecial() == kSharpAcPowerSetSpecialOn) && + (getSpecial() == kSharpAcSpecialTempEcono); +} + +// Warning: Probably incompatible with `setTurbo()` +void IRSharpAc::setEconoToggle(const bool on) { + if (on) setSpecial(kSharpAcSpecialTempEcono); + setPowerSpecial(on ? kSharpAcPowerSetSpecialOn : kSharpAcPowerSetSpecialOff); +} + +// Returns how long the timer is set for, in minutes. +uint16_t IRSharpAc::getTimerTime(void) { + return GETBITS8(remote[kSharpAcByteTimer], kSharpAcTimerHoursOffset, + kSharpAcTimerHoursSize) * kSharpAcTimerIncrement * 2 + + ((getSpecial() == kSharpAcSpecialTimerHalfHour) ? kSharpAcTimerIncrement + : 0); +} + +bool IRSharpAc::getTimerEnabled(void) { + return GETBIT8(remote[kSharpAcByteTimer], kSharpAcBitTimerEnabled); +} + +bool IRSharpAc::getTimerType(void) { + return GETBIT8(remote[kSharpAcByteTimer], kSharpAcBitTimerType); +} + +// Set or cancel the timer function. +// Args: +// enable: Is the timer to be enabled (true) or canceled(false)? +// timer_type: An On (true) or an Off (false). Ignored if canceled. +// mins: Nr. of minutes the timer is to be set to. +// Rounds down to 30 min increments. +// (max: 720 mins (12h), 0 is Off) +void IRSharpAc::setTimer(bool enable, bool timer_type, uint16_t mins) { + uint8_t half_hours = std::min(mins / kSharpAcTimerIncrement, + kSharpAcTimerHoursMax * 2); + if (half_hours == 0) enable = false; + if (!enable) { + half_hours = 0; + timer_type = kSharpAcOffTimerType; + } + setBit(&remote[kSharpAcByteTimer], kSharpAcBitTimerEnabled, enable); + setBit(&remote[kSharpAcByteTimer], kSharpAcBitTimerType, timer_type); + setBits(&remote[kSharpAcByteTimer], kSharpAcTimerHoursOffset, + kSharpAcTimerHoursSize, half_hours / 2); + // Handle non-round hours. + setSpecial((half_hours % 2) ? kSharpAcSpecialTimerHalfHour + : kSharpAcSpecialTimer); + setPowerSpecial(kSharpAcPowerTimerSetting); +} + +bool IRSharpAc::getClean(void) { + return GETBIT8(remote[kSharpAcByteClean], kSharpAcBitCleanOffset); +} + +// Note: Officially A/C unit needs to be "Off" before clean mode can be entered. +void IRSharpAc::setClean(const bool on) { + // Clean mode appears to be just default dry mode, with an extra bit set. + if (on) { + setMode(kSharpAcDry, false); + setPower(true, false); + } else { + // Restore the previous operation mode & fan speed. + setMode(_mode, false); + setFan(_fan, false); + } + setBit(&remote[kSharpAcByteClean], kSharpAcBitCleanOffset, on); + clearPowerSpecial(); +} + // Convert a standard A/C mode into its native mode. uint8_t IRSharpAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { @@ -499,15 +642,16 @@ stdAc::state_t IRSharpAc::toCommon(void) { result.celsius = true; result.degrees = this->getTemp(); result.fanspeed = this->toCommonFanSpeed(this->getFan()); + result.turbo = this->getTurbo(); + result.swingv = this->getSwingToggle() ? stdAc::swingv_t::kAuto + : stdAc::swingv_t::kOff; + result.filter = this->getIon(); + result.econo = this->getEconoToggle(); + result.clean = this->getClean(); // Not supported. - result.swingv = stdAc::swingv_t::kOff; result.swingh = stdAc::swingh_t::kOff; result.quiet = false; - result.turbo = false; - result.clean = false; result.beep = false; - result.econo = false; - result.filter = false; result.light = false; result.sleep = -1; result.clock = -1; @@ -517,14 +661,23 @@ stdAc::state_t IRSharpAc::toCommon(void) { // Convert the internal state into a human readable string. String IRSharpAc::toString(void) { String result = ""; - result.reserve(80); // Reserve some heap for the string to reduce fragging. - result += addBoolToString(getPower(), kPowerStr, false); - result += addBoolToString(getPreviousPower(), kPreviousPowerStr); + result.reserve(135); // Reserve some heap for the string to reduce fragging. + result += addLabeledString(isPowerSpecial() ? "-" + : (getPower() ? kOnStr : kOffStr), + kPowerStr, false); result += addModeToString(getMode(), kSharpAcAuto, kSharpAcCool, kSharpAcHeat, kSharpAcDry, kSharpAcAuto); result += addTempToString(getTemp()); result += addFanToString(getFan(), kSharpAcFanMax, kSharpAcFanMin, kSharpAcFanAuto, kSharpAcFanAuto, kSharpAcFanMed); + result += addBoolToString(getTurbo(), kTurboStr); + result += addBoolToString(getSwingToggle(), kSwingVToggleStr); + result += addBoolToString(getIon(), kIonStr); + result += addLabeledString(getEconoToggle() ? kToggleStr : "-", kEconoStr); + result += addBoolToString(getClean(), kCleanStr); + if (getTimerEnabled()) + result += addLabeledString(minsToString(getTimerTime()), + getTimerType() ? kOnTimerStr : kOffTimerStr); return result; } diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Sharp.h b/lib/IRremoteESP8266-2.7.7/src/ir_Sharp.h new file mode 100644 index 000000000..31f340817 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Sharp.h @@ -0,0 +1,165 @@ +// Copyright 2019 crankyoldgit + +// Supports: +// Brand: Sharp, Model: LC-52D62U TV +// Brand: Sharp, Model: AY-ZP40KR A/C +// Brand: Sharp, Model: AH-AxSAY A/C +// Brand: Sharp, Model: AH-XP10NRY A/C +// Brand: Sharp, Model: CRMC-820JBEZ remote + +#ifndef IR_SHARP_H_ +#define IR_SHARP_H_ + +#ifndef UNIT_TEST +#include +#endif +#include "IRrecv.h" +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif +#include "IRutils.h" + +// Constants +const uint16_t kSharpAcHdrMark = 3800; +const uint16_t kSharpAcHdrSpace = 1900; +const uint16_t kSharpAcBitMark = 470; +const uint16_t kSharpAcZeroSpace = 500; +const uint16_t kSharpAcOneSpace = 1400; +const uint32_t kSharpAcGap = kDefaultMessageGap; + +// Byte[4] +const uint8_t kSharpAcByteTemp = 4; +const uint8_t kSharpAcMinTemp = 15; // Celsius +const uint8_t kSharpAcMaxTemp = 30; // Celsius +// Byte[5] +const uint8_t kSharpAcBytePowerSpecial = 5; +const uint8_t kSharpAcPowerSetSpecialOffset = kHighNibble; // 0bxxxx0000 +const uint8_t kSharpAcPowerSpecialSize = kNibbleSize; // 0bxxxx0000 +const uint8_t kSharpAcPowerUnknown = 0; // 0b0000 +const uint8_t kSharpAcPowerOnFromOff = 1; // 0b0001 +const uint8_t kSharpAcPowerOff = 2; // 0b0010 +const uint8_t kSharpAcPowerOn = 3; // 0b0011 (Normal) +const uint8_t kSharpAcPowerSetSpecialOn = 6; // 0b0110 +const uint8_t kSharpAcPowerSetSpecialOff = 7; // 0b0111 +const uint8_t kSharpAcPowerTimerSetting = 8; // 0b1000 +// Byte[6] +const uint8_t kSharpAcByteMode = 6; +const uint8_t kSharpAcModeSize = 2; // Mask 0b000000xx; +const uint8_t kSharpAcAuto = 0b00; +const uint8_t kSharpAcDry = 0b11; +const uint8_t kSharpAcCool = 0b10; +const uint8_t kSharpAcHeat = 0b01; +const uint8_t kSharpAcByteClean = kSharpAcByteMode; +const uint8_t kSharpAcBitCleanOffset = 3; // Mask 0b0000x000 +const uint8_t kSharpAcByteFan = kSharpAcByteMode; +const uint8_t kSharpAcFanOffset = 4; // Mask 0b0xxx0000 +const uint8_t kSharpAcFanSize = 3; // Nr. of Bits +const uint8_t kSharpAcFanAuto = 0b010; // 2 +const uint8_t kSharpAcFanMin = 0b100; // 4 (FAN1) +const uint8_t kSharpAcFanMed = 0b011; // 3 (FAN2) +const uint8_t kSharpAcFanHigh = 0b101; // 5 (FAN3) +const uint8_t kSharpAcFanMax = 0b111; // 7 (FAN4) +// Byte[7] +const uint8_t kSharpAcByteTimer = 7; +const uint8_t kSharpAcTimerIncrement = 30; // Mins +const uint8_t kSharpAcTimerHoursOffset = kLowNibble; +const uint8_t kSharpAcTimerHoursSize = kNibbleSize; // Mask 0b0000xxxx +const uint8_t kSharpAcTimerHoursOff = 0b0000; +const uint8_t kSharpAcTimerHoursMax = 0b1100; // 12 +const uint8_t kSharpAcBitTimerType = 6; // Mask 0b0x000000 +const uint8_t kSharpAcOffTimerType = 0b0; +const uint8_t kSharpAcOnTimerType = 0b1; +const uint8_t kSharpAcBitTimerEnabled = 7; // Mask 0bx0000000 +// Byte[8] +const uint8_t kSharpAcByteSwing = 8; +const uint8_t kSharpAcSwingOffset = 0; +const uint8_t kSharpAcSwingSize = 3; // Mask 0b00000xxx +const uint8_t kSharpAcSwingToggle = 0b111; +const uint8_t kSharpAcSwingNoToggle = 0b000; +// Byte[10] +const uint8_t kSharpAcByteSpecial = 10; // Mask 0bxxxxxxxx +const uint8_t kSharpAcSpecialPower = 0x00; +const uint8_t kSharpAcSpecialTurbo = 0x01; +const uint8_t kSharpAcSpecialTempEcono = 0x04; +const uint8_t kSharpAcSpecialFan = 0x05; +const uint8_t kSharpAcSpecialSwing = 0x06; +const uint8_t kSharpAcSpecialTimer = 0xC0; +const uint8_t kSharpAcSpecialTimerHalfHour = 0xDE; +// Byte[11] +const uint8_t kSharpAcByteIon = 11; +const uint8_t kSharpAcBitIonOffset = 2; // Mask 0b00000x00 +// Byte[12] (Checksum) + + +class IRSharpAc { + public: + explicit IRSharpAc(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + +#if SEND_SHARP_AC + void send(const uint16_t repeat = kSharpAcDefaultRepeat); + int8_t calibrate(void) { return _irsend.calibrate(); } +#endif // SEND_SHARP_AC + void begin(void); + void on(void); + void off(void); + void setPower(const bool on, const bool prev_on = true); + bool getPower(void); + bool isPowerSpecial(void); + void setTemp(const uint8_t temp, const bool save = true); + uint8_t getTemp(void); + void setFan(const uint8_t fan, const bool save = true); + uint8_t getFan(void); + void setMode(const uint8_t mode, const bool save = true); + uint8_t getMode(void); + void setSpecial(const uint8_t mode); + uint8_t getSpecial(void); + bool getTurbo(void); + void setTurbo(const bool on); + bool getSwingToggle(void); + void setSwingToggle(const bool on); + bool getIon(void); + void setIon(const bool on); + bool getEconoToggle(void); + void setEconoToggle(const bool on); + uint16_t getTimerTime(void); + bool getTimerEnabled(void); + bool getTimerType(void); + void setTimer(bool enable, bool timer_type, uint16_t mins); + bool getClean(void); + void setClean(const bool on); + uint8_t* getRaw(void); + void setRaw(const uint8_t new_code[], + const uint16_t length = kSharpAcStateLength); + static bool validChecksum(uint8_t state[], + const uint16_t length = kSharpAcStateLength); + static uint8_t convertMode(const stdAc::opmode_t mode); + static uint8_t convertFan(const stdAc::fanspeed_t speed); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + stdAc::state_t toCommon(void); + String toString(void); +#ifndef UNIT_TEST + + private: + IRsend _irsend; +#else + IRsendTest _irsend; +#endif + // # of bytes per command + uint8_t remote[kSharpAcStateLength]; + uint8_t _temp; // Saved copy of the desired temp. + uint8_t _mode; // Saved copy of the desired mode. + uint8_t _fan; // Saved copy of the desired fan speed. + void stateReset(void); + void checksum(void); + static uint8_t calcChecksum(uint8_t state[], + const uint16_t length = kSharpAcStateLength); + void setPowerSpecial(const uint8_t value); + uint8_t getPowerSpecial(void); + void clearPowerSpecial(void); +}; + +#endif // IR_SHARP_H_ diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Sherwood.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Sherwood.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Sherwood.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Sherwood.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Sony.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Sony.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Sony.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Sony.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Symphony.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Symphony.cpp similarity index 58% rename from lib/IRremoteESP8266-2.7.6/src/ir_Symphony.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Symphony.cpp index f0194fdb8..a65821c33 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Symphony.cpp +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Symphony.cpp @@ -4,6 +4,16 @@ // Supports: // Brand: Symphony, Model: Air Cooler 3Di +// Brand: SamHop, Model: SM3015 Fan Remote Control +// Brand: SamHop, Model: SM5021 Encoder chip +// Brand: SamHop, Model: SM5032 Decoder chip +// Brand: Blyss, Model: Owen-SW-5 3 Fan +// Brand: Blyss, Model: WP-YK8 090218 remote +// Brand: Westinghouse, Model: Ceiling fan +// Brand: Westinghouse, Model: 78095 Remote +// Brand: Satellite Electronic, Model: ID6 Remote +// Brand: Satellite Electronic, Model: JY199I Fan driver +// Brand: Satellite Electronic, Model: JY199I-L Fan driver #include #include "IRrecv.h" @@ -14,12 +24,12 @@ // Constants // Ref: // https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 -const uint16_t kSymphonyZeroMark = 1250; -const uint16_t kSymphonyZeroSpace = 400; +const uint16_t kSymphonyZeroMark = 400; +const uint16_t kSymphonyZeroSpace = 1250; const uint16_t kSymphonyOneMark = kSymphonyZeroSpace; const uint16_t kSymphonyOneSpace = kSymphonyZeroMark; -const uint16_t kSymphonyFooterMark = kSymphonyOneMark; -const uint32_t kSymphonyFooterGap = 8000; +const uint32_t kSymphonyFooterGap = 4 * (kSymphonyZeroMark + + kSymphonyZeroSpace); #if SEND_SYMPHONY // Send a Symphony packet. @@ -33,11 +43,13 @@ const uint32_t kSymphonyFooterGap = 8000; // // Ref: // https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 +// https://github.com/crankyoldgit/IRremoteESP8266/issues/1105 +// https://www.alldatasheet.com/datasheet-pdf/pdf/124369/ANALOGICTECH/SM5021B.html void IRsend::sendSymphony(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(0, 0, kSymphonyOneMark, kSymphonyOneSpace, kSymphonyZeroMark, kSymphonyZeroSpace, - kSymphonyFooterMark, kSymphonyFooterGap, + 0, kSymphonyFooterGap, data, nbits, 38000, true, repeat, kDutyDefault); } #endif // SEND_SYMPHONY @@ -57,23 +69,25 @@ void IRsend::sendSymphony(uint64_t data, uint16_t nbits, uint16_t repeat) { // Status: STABLE / Should be working. // // Ref: -// +// https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 +// https://github.com/crankyoldgit/IRremoteESP8266/issues/1105 +// https://www.alldatasheet.com/datasheet-pdf/pdf/124369/ANALOGICTECH/SM5021B.html bool IRrecv::decodeSymphony(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint64_t data = 0; - if (results->rawlen < 2 * nbits + kFooter + offset - 1) + if (results->rawlen < 2 * nbits + offset - 1) return false; // Not enough entries to ever be SYMPHONY. // Compliance if (strict && nbits != kSymphonyBits) return false; - if (!matchGeneric(results->rawbuf + offset, &data, results->rawlen - offset, - nbits, - 0, 0, // No Header - kSymphonyOneMark, kSymphonyOneSpace, - kSymphonyZeroMark, kSymphonyZeroSpace, - kSymphonyFooterMark, kSymphonyFooterGap, true, - _tolerance, 0)) + if (!matchGenericConstBitTime(results->rawbuf + offset, &data, + results->rawlen - offset, + nbits, + 0, 0, // No Header + kSymphonyOneMark, kSymphonyZeroMark, + 0, kSymphonyFooterGap, true, + _tolerance, 0)) return false; // Success diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Tcl.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Tcl.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Tcl.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Tcl.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Tcl.h b/lib/IRremoteESP8266-2.7.7/src/ir_Tcl.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Tcl.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Tcl.h index 21e64a55a..3eef6838a 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Tcl.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Tcl.h @@ -63,7 +63,7 @@ class IRTcl112Ac { #if SEND_TCL112AC void send(const uint16_t repeat = kTcl112AcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_TCL void begin(void); uint8_t* getRaw(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Teco.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Teco.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Teco.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Teco.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Teco.h b/lib/IRremoteESP8266-2.7.7/src/ir_Teco.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Teco.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Teco.h diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Toshiba.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Toshiba.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Toshiba.h b/lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Toshiba.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.h index 7a679ceda..22fbd7240 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Toshiba.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.h @@ -62,7 +62,7 @@ class IRToshibaAC { void stateReset(void); #if SEND_TOSHIBA_AC void send(const uint16_t repeat = kToshibaACMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_TOSHIBA_AC void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Trotec.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Trotec.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Trotec.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Trotec.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Trotec.h b/lib/IRremoteESP8266-2.7.7/src/ir_Trotec.h similarity index 98% rename from lib/IRremoteESP8266-2.7.6/src/ir_Trotec.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Trotec.h index f836b2e5e..cc7f0b2fd 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Trotec.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Trotec.h @@ -69,7 +69,7 @@ class IRTrotecESP { #if SEND_TROTEC void send(const uint16_t repeat = kTrotecDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_TROTEC void begin(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Vestel.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Vestel.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Vestel.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Vestel.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Vestel.h b/lib/IRremoteESP8266-2.7.7/src/ir_Vestel.h similarity index 99% rename from lib/IRremoteESP8266-2.7.6/src/ir_Vestel.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Vestel.h index 38727b805..5facdc278 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Vestel.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Vestel.h @@ -116,7 +116,7 @@ class IRVestelAc { void stateReset(void); #if SEND_VESTEL_AC void send(void); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_VESTEL_AC void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Whirlpool.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Whirlpool.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Whirlpool.h b/lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.h similarity index 99% rename from lib/IRremoteESP8266-2.7.6/src/ir_Whirlpool.h rename to lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.h index 11fd6949e..d0cf95bef 100644 --- a/lib/IRremoteESP8266-2.7.6/src/ir_Whirlpool.h +++ b/lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.h @@ -93,7 +93,7 @@ class IRWhirlpoolAc { #if SEND_WHIRLPOOL_AC void send(const uint16_t repeat = kWhirlpoolAcDefaultRepeat, const bool calcchecksum = true); - uint8_t calibrate(void) { return _irsend.calibrate(); } + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_WHIRLPOOL_AC void begin(void); void on(void); diff --git a/lib/IRremoteESP8266-2.7.6/src/ir_Whynter.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Whynter.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/ir_Whynter.cpp rename to lib/IRremoteESP8266-2.7.7/src/ir_Whynter.cpp diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/README.md b/lib/IRremoteESP8266-2.7.7/src/locale/README.md similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/README.md rename to lib/IRremoteESP8266-2.7.7/src/locale/README.md diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/de-CH.h b/lib/IRremoteESP8266-2.7.7/src/locale/de-CH.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/de-CH.h rename to lib/IRremoteESP8266-2.7.7/src/locale/de-CH.h diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/de-DE.h b/lib/IRremoteESP8266-2.7.7/src/locale/de-DE.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/de-DE.h rename to lib/IRremoteESP8266-2.7.7/src/locale/de-DE.h diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/defaults.h b/lib/IRremoteESP8266-2.7.7/src/locale/defaults.h similarity index 96% rename from lib/IRremoteESP8266-2.7.6/src/locale/defaults.h rename to lib/IRremoteESP8266-2.7.7/src/locale/defaults.h index f96595616..5df78f7b9 100644 --- a/lib/IRremoteESP8266-2.7.6/src/locale/defaults.h +++ b/lib/IRremoteESP8266-2.7.7/src/locale/defaults.h @@ -189,6 +189,9 @@ #ifndef D_STR_SENSOR #define D_STR_SENSOR "Sensor" #endif // D_STR_SENSOR +#ifndef D_STR_DISPLAY +#define D_STR_DISPLAY "Display" +#endif // D_STR_DISPLAY #ifndef D_STR_WEEKLY #define D_STR_WEEKLY "Weekly" #endif // D_STR_WEEKLY @@ -216,6 +219,9 @@ #ifndef D_STR_NA #define D_STR_NA "N/A" #endif // D_STR_NA +#ifndef D_STR_INSIDE +#define D_STR_INSIDE "Inside" +#endif // D_STR_INSIDE #ifndef D_STR_OUTSIDE #define D_STR_OUTSIDE "Outside" #endif // D_STR_OUTSIDE @@ -369,6 +375,9 @@ #ifndef D_STR_PREVIOUSPOWER #define D_STR_PREVIOUSPOWER D_STR_PREVIOUS " " D_STR_POWER #endif // D_STR_PREVIOUSPOWER +#ifndef D_STR_DISPLAYTEMP +#define D_STR_DISPLAYTEMP D_STR_DISPLAY " " D_STR_TEMP +#endif // D_STR_DISPLAYTEMP #ifndef D_STR_SENSORTEMP #define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP #endif // D_STR_SENSORTEMP @@ -466,6 +475,12 @@ #ifndef D_STR_CARRIER_AC #define D_STR_CARRIER_AC "CARRIER_AC" #endif // D_STR_CARRIER_AC +#ifndef D_STR_CARRIER_AC40 +#define D_STR_CARRIER_AC40 D_STR_CARRIER_AC "40" +#endif // D_STR_CARRIER_AC40 +#ifndef D_STR_CARRIER_AC64 +#define D_STR_CARRIER_AC64 D_STR_CARRIER_AC "64" +#endif // D_STR_CARRIER_AC64 #ifndef D_STR_COOLIX #define D_STR_COOLIX "COOLIX" #endif // D_STR_COOLIX @@ -493,12 +508,18 @@ #ifndef D_STR_DAIKIN64 #define D_STR_DAIKIN64 "DAIKIN64" #endif // D_STR_DAIKIN64 +#ifndef D_STR_DELONGHI_AC +#define D_STR_DELONGHI_AC "DELONGHI_AC" +#endif // D_STR_DELONGHI_AC #ifndef D_STR_DENON #define D_STR_DENON "DENON" #endif // D_STR_DENON #ifndef D_STR_DISH #define D_STR_DISH "DISH" #endif // D_STR_DISH +#ifndef D_STR_DOSHISHA +#define D_STR_DOSHISHA "DOSHISHA" +#endif // D_STR_DOSHISHA #ifndef D_STR_ELECTRA_AC #define D_STR_ELECTRA_AC "ELECTRA_AC" #endif // D_STR_ELECTRA_AC @@ -592,6 +613,9 @@ #ifndef D_STR_MITSUBISHI_HEAVY_88 #define D_STR_MITSUBISHI_HEAVY_88 "MITSUBISHI_HEAVY_88" #endif // D_STR_MITSUBISHI_HEAVY_88 +#ifndef D_STR_MULTIBRACKETS +#define D_STR_MULTIBRACKETS "MULTIBRACKETS" +#endif // D_STR_MULTIBRACKETS #ifndef D_STR_MWM #define D_STR_MWM "MWM" #endif // D_STR_MWM diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/en-AU.h b/lib/IRremoteESP8266-2.7.7/src/locale/en-AU.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/en-AU.h rename to lib/IRremoteESP8266-2.7.7/src/locale/en-AU.h diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/en-IE.h b/lib/IRremoteESP8266-2.7.7/src/locale/en-IE.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/en-IE.h rename to lib/IRremoteESP8266-2.7.7/src/locale/en-IE.h diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/en-UK.h b/lib/IRremoteESP8266-2.7.7/src/locale/en-UK.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/en-UK.h rename to lib/IRremoteESP8266-2.7.7/src/locale/en-UK.h diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/en-US.h b/lib/IRremoteESP8266-2.7.7/src/locale/en-US.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/en-US.h rename to lib/IRremoteESP8266-2.7.7/src/locale/en-US.h diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/es-ES.h b/lib/IRremoteESP8266-2.7.7/src/locale/es-ES.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/es-ES.h rename to lib/IRremoteESP8266-2.7.7/src/locale/es-ES.h diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/fr-FR.h b/lib/IRremoteESP8266-2.7.7/src/locale/fr-FR.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/fr-FR.h rename to lib/IRremoteESP8266-2.7.7/src/locale/fr-FR.h diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/it-IT.h b/lib/IRremoteESP8266-2.7.7/src/locale/it-IT.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/it-IT.h rename to lib/IRremoteESP8266-2.7.7/src/locale/it-IT.h diff --git a/lib/IRremoteESP8266-2.7.6/src/locale/zh-CN.h b/lib/IRremoteESP8266-2.7.7/src/locale/zh-CN.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/src/locale/zh-CN.h rename to lib/IRremoteESP8266-2.7.7/src/locale/zh-CN.h diff --git a/lib/IRremoteESP8266-2.7.6/test/IRac_test.cpp b/lib/IRremoteESP8266-2.7.7/test/IRac_test.cpp similarity index 97% rename from lib/IRremoteESP8266-2.7.6/test/IRac_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/IRac_test.cpp index 8ddf98b59..93b8a73cb 100644 --- a/lib/IRremoteESP8266-2.7.6/test/IRac_test.cpp +++ b/lib/IRremoteESP8266-2.7.7/test/IRac_test.cpp @@ -4,6 +4,7 @@ #include "ir_Amcor.h" #include "ir_Argo.h" #include "ir_Daikin.h" +#include "ir_Delonghi.h" #include "ir_Electra.h" #include "ir_Fujitsu.h" #include "ir_Goodweather.h" @@ -377,6 +378,31 @@ TEST(TestIRac, Daikin64) { ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture)); } +TEST(TestIRac, DelonghiAc) { + IRDelonghiAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + char expected[] = + "Power: On, Mode: 0 (Cool), Fan: 2 (Medium), Temp: 77F, " + "Turbo: On, Sleep: On, On Timer: Off, Off Timer: Off"; + + ac.begin(); + irac.delonghiac(&ac, + true, // Power + stdAc::opmode_t::kCool, // Mode + false, // Celsius (i.e. Fahrenheit) + 77, // Degrees (F) + stdAc::fanspeed_t::kMedium, // Fan Speed + true, // Turbo + 360); // Sleep + ASSERT_EQ(expected, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(decode_type_t::DELONGHI_AC, ac._irsend.capture.decode_type); + ASSERT_EQ(kDelonghiAcBits, ac._irsend.capture.bits); + ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture)); +} + TEST(TestIRac, Electra) { IRElectraAc ac(kGpioUnused); IRac irac(kGpioUnused); @@ -518,17 +544,18 @@ TEST(TestIRac, Gree) { IRac irac(0); IRrecv capture(0); char expected[] = - "Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 22C, " + "Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 71F, " "Fan: 2 (Medium), Turbo: Off, IFeel: Off, WiFi: Off, XFan: On, " "Light: On, Sleep: On, Swing(V) Mode: Manual, " - "Swing(V): 3 (UNKNOWN), Timer: Off"; + "Swing(V): 3 (UNKNOWN), Timer: Off, Display Temp: 0 (Off)"; ac.begin(); irac.gree(&ac, gree_ac_remote_model_t::YAW1F, // Model true, // Power stdAc::opmode_t::kCool, // Mode - 22, // Celsius + false, // Celsius + 71, // Degrees (F) stdAc::fanspeed_t::kMedium, // Fan speed stdAc::swingv_t::kHigh, // Veritcal swing false, // Turbo @@ -1071,8 +1098,8 @@ TEST(TestIRac, Sharp) { IRac irac(0); IRrecv capture(0); char expected[] = - "Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 3 (Medium)"; + "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), " + "Turbo: Off, Swing(V) Toggle: On, Ion: On, Econo: -, Clean: Off"; ac.begin(); irac.sharp(&ac, @@ -1080,7 +1107,11 @@ TEST(TestIRac, Sharp) { true, // Previous Power stdAc::opmode_t::kCool, // Mode 28, // Celsius - stdAc::fanspeed_t::kMedium); // Fan speed + stdAc::fanspeed_t::kMedium, // Fan speed + stdAc::swingv_t::kAuto, // Veritcal swing + false, // Turbo + true, // Filter (Ion) + false); // Clean ASSERT_EQ(expected, ac.toString()); ac._irsend.makeDecodeResult(); EXPECT_TRUE(capture.decode(&ac._irsend.capture)); diff --git a/lib/IRremoteESP8266-2.7.6/test/IRrecv_test.cpp b/lib/IRremoteESP8266-2.7.7/test/IRrecv_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/IRrecv_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/IRrecv_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/IRrecv_test.h b/lib/IRremoteESP8266-2.7.7/test/IRrecv_test.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/IRrecv_test.h rename to lib/IRremoteESP8266-2.7.7/test/IRrecv_test.h diff --git a/lib/IRremoteESP8266-2.7.6/test/IRsend_test.cpp b/lib/IRremoteESP8266-2.7.7/test/IRsend_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/IRsend_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/IRsend_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/IRsend_test.h b/lib/IRremoteESP8266-2.7.7/test/IRsend_test.h similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/IRsend_test.h rename to lib/IRremoteESP8266-2.7.7/test/IRsend_test.h diff --git a/lib/IRremoteESP8266-2.7.6/test/IRutils_test.cpp b/lib/IRremoteESP8266-2.7.7/test/IRutils_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/IRutils_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/IRutils_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/Makefile b/lib/IRremoteESP8266-2.7.7/test/Makefile new file mode 100644 index 000000000..7b36c5743 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/test/Makefile @@ -0,0 +1,159 @@ +# SYNOPSIS: +# +# make [all] - makes everything. +# make TARGET - makes the given target. +# make run - makes everything and runs all the tests. +# make clean - removes all files generated by make. +# make install-googletest - install the googletest code suite + +# Please tweak the following variable definitions as needed by your +# project, except GTEST_HEADERS, which you can use in your own targets +# but shouldn't modify. + +# Points to the root of Google Test, relative to where this file is. +# Remember to tweak this if you move this file. +GTEST_DIR = ../lib/googletest/googletest + +# Where to find user code. +USER_DIR = ../src +INCLUDES = -I$(USER_DIR) -I. + +# Flags passed to the preprocessor. +# Set Google Test's header directory as a system directory, such that +# the compiler doesn't generate warnings in Google Test headers. +CPPFLAGS += -isystem $(GTEST_DIR)/include -DUNIT_TEST -D_IR_LOCALE_=en-AU + +# Flags passed to the C++ compiler. +CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 + +# All tests produced by this Makefile. generated from all *_test.cpp files +TESTS = $(patsubst %.cpp,%,$(wildcard *_test.cpp)) + +# All Google Test headers. Usually you shouldn't change this +# definition. +GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ + $(GTEST_DIR)/include/gtest/internal/*.h + +# House-keeping build targets. + +all : $(TESTS) + +clean : + rm -f $(TESTS) gtest.a gtest_main.a *.o + +# Build and run all the tests. +run : all + failed=""; \ + for unittest in $(TESTS); do \ + ./$${unittest} || failed="$${failed} $${unittest}"; \ + done; \ + if [ -n "$${failed}" ]; then \ + echo "FAIL: :-( :-( Unit test(s)$${failed} failed! :-( :-("; exit 1; \ + else \ + echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \ + fi + +run_tests : run + +install-googletest : + git clone -b v1.8.x https://github.com/google/googletest.git ../lib/googletest + +# Builds gtest.a and gtest_main.a. + +# Usually you shouldn't tweak such internal variables, indicated by a +# trailing _. +GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) + +# All the IR protocol object files. +PROTOCOL_OBJS = $(patsubst %.cpp,%.o,$(wildcard $(USER_DIR)/ir_*.cpp)) +PROTOCOLS = $(patsubst $(USER_DIR)/%,%,$(PROTOCOL_OBJS)) + +# All the IR Protocol header files. +PROTOCOLS_H = $(wildcard $(USER_DIR)/ir_*.h) + +# Common object files +COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o IRac.o ir_GlobalCache.o \ + IRtext.o $(PROTOCOLS) gtest_main.a +# Common dependencies +COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \ + $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \ + $(USER_DIR)/IRac.h $(USER_DIR)/i18n.h $(USER_DIR)/IRtext.h \ + $(PROTOCOLS_H) + +# Common test dependencies +COMMON_TEST_DEPS = $(COMMON_DEPS) IRrecv_test.h IRsend_test.h + +# For simplicity and to avoid depending on Google Test's +# implementation details, the dependencies specified below are +# conservative and not optimized. This is fine as Google Test +# compiles fast and for ordinary users its source rarely changes. +gtest-all.o : $(GTEST_SRCS_) + $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ + $(GTEST_DIR)/src/gtest-all.cc + +gtest_main.o : $(GTEST_SRCS_) + $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ + $(GTEST_DIR)/src/gtest_main.cc + +gtest.a : gtest-all.o + $(AR) $(ARFLAGS) $@ $^ + +gtest_main.a : gtest-all.o gtest_main.o + $(AR) $(ARFLAGS) $@ $^ + +# Keep all intermediate files. +.SECONDARY: + +# Builds our test. A test should link with either gtest.a or +# gtest_main.a, depending on whether it defines its own main() +# function. + +IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/locale/*.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRtext.cpp + +IRutils.o : $(USER_DIR)/IRutils.cpp $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/locale/*.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRutils.cpp + +IRutils_test.o : IRutils_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRutils_test.cpp + +IRutils_test : IRutils_test.o ir_NEC.o ir_Nikai.o ir_Toshiba.o IRtext.o $(COMMON_OBJ) gtest_main.a + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ + +IRtimer.o : $(USER_DIR)/IRtimer.cpp $(USER_DIR)/IRtimer.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRtimer.cpp + +IRsend.o : $(USER_DIR)/IRsend.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRremoteESP8266.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRsend.cpp + +IRsend_test.o : IRsend_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRsend_test.cpp + +IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRrecv.cpp + +IRrecv_test.o : IRrecv_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRrecv_test.cpp + +IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRac.cpp + +IRac_test.o : IRac_test.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRac_test.cpp + +# new specific targets goes above this line + +ir_%.o : $(USER_DIR)/ir_%.h $(USER_DIR)/ir_%.cpp $(COMMON_DEPS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp + +ir_%.o : $(USER_DIR)/ir_%.cpp $(COMMON_DEPS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp + +ir_%_test.o : ir_%_test.cpp $(USER_DIR)/ir_$%.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_$*_test.cpp + +ir_%_test.o : ir_%_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_$*_test.cpp + +%_test : $(COMMON_OBJ) %_test.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Airwell_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Airwell_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Airwell_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Airwell_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Aiwa_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Aiwa_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Aiwa_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Aiwa_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Amcor_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Amcor_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Amcor_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Amcor_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Argo_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Argo_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Argo_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Argo_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Carrier_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Carrier_test.cpp similarity index 58% rename from lib/IRremoteESP8266-2.7.6/test/ir_Carrier_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Carrier_test.cpp index f62a9d0f5..5e7a53220 100644 --- a/lib/IRremoteESP8266-2.7.6/test/ir_Carrier_test.cpp +++ b/lib/IRremoteESP8266-2.7.7/test/ir_Carrier_test.cpp @@ -1,5 +1,6 @@ -// Copyright 2018 David Conran +// Copyright 2018, 2020 David Conran +#include "IRac.h" #include "IRrecv.h" #include "IRsend.h" #include "IRsend_test.h" @@ -229,3 +230,176 @@ TEST(TestDecodeCarrierAC, RealExamples) { EXPECT_EQ(0xABE2, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); } + +TEST(TestUtils, Housekeeping) { + // CARRIER_AC + ASSERT_EQ("CARRIER_AC", typeToString(decode_type_t::CARRIER_AC)); + ASSERT_EQ(decode_type_t::CARRIER_AC, strToDecodeType("CARRIER_AC")); + ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC)); + ASSERT_EQ(kCarrierAcBits, + IRsend::defaultBits(decode_type_t::CARRIER_AC)); + ASSERT_EQ(kCarrierAcMinRepeat, + IRsend::minRepeats(decode_type_t::CARRIER_AC)); + + // CARRIER_AC40 + ASSERT_EQ("CARRIER_AC40", typeToString(decode_type_t::CARRIER_AC40)); + ASSERT_EQ(decode_type_t::CARRIER_AC40, strToDecodeType("CARRIER_AC40")); + ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC40)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC40)); + ASSERT_EQ(kCarrierAc40Bits, + IRsend::defaultBits(decode_type_t::CARRIER_AC40)); + ASSERT_EQ(kCarrierAc40MinRepeat, + IRsend::minRepeats(decode_type_t::CARRIER_AC40)); + + // CARRIER_AC64 + ASSERT_EQ("CARRIER_AC64", typeToString(decode_type_t::CARRIER_AC64)); + ASSERT_EQ(decode_type_t::CARRIER_AC64, strToDecodeType("CARRIER_AC64")); + ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC64)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC64)); + ASSERT_EQ(kCarrierAc64Bits, + IRsend::defaultBits(decode_type_t::CARRIER_AC64)); + ASSERT_EQ(kCarrierAc64MinRepeat, + IRsend::minRepeats(decode_type_t::CARRIER_AC64)); +} + +/// Decode a "real" example message. +TEST(TestDecodeCarrierAC40, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + // Data from: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1112#issuecomment-627961192 + const uint16_t rawData[83] = { + 8402, 4166, + 562, 1550, 538, 1526, 562, 1552, 538, 1524, 566, 504, 538, 504, 540, 480, + 564, 506, 538, 506, 538, 506, 538, 1550, 538, 1550, 540, 506, 538, 506, + 538, 1550, 538, 506, 540, 478, 564, 480, 564, 506, 540, 1550, 538, 506, + 540, 506, 538, 1524, 564, 506, 538, 1550, 538, 1550, 538, 482, 562, 482, + 562, 506, 540, 504, 540, 482, 562, 506, 538, 1550, 538, 1550, 540, 1524, + 564, 1526, 564, 480, 564, 1528, 562, 504, 540, 480, + 564}; // UNKNOWN BCF4730D + + irsend.sendRaw(rawData, 83, 38000); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC40, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAc40Bits, irsend.capture.bits); + EXPECT_EQ(0xF03212C0F4, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); +} + +/// Send & Decode a synthetic message. +TEST(TestDecodeCarrierAC40, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + + irsend.sendCarrierAC40(0xF03212C0F4); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC40, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAc40Bits, irsend.capture.bits); + EXPECT_EQ(0xF03212C0F4, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); + // Payload is sent a total of three times. + EXPECT_EQ( + "f38000d50" + // Initial + "m8402s4166" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497" + "m547s497m547s497m547s1540m547s1540m547s497m547s497m547s1540m547s497" + "m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497" + "m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497" + "m547s20000" + // Repeat #1 + "m8402s4166" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497" + "m547s497m547s497m547s1540m547s1540m547s497m547s497m547s1540m547s497" + "m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497" + "m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497" + "m547s20000" + // Repeat #2 + "m8402s4166" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497" + "m547s497m547s497m547s1540m547s1540m547s497m547s497m547s1540m547s497" + "m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497" + "m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497" + "m547s20000", + irsend.outputStr()); +} + +/// Decode a "real" example message. +TEST(TestDecodeCarrierAC64, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + // Data from: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1127#issuecomment-629713855 + const uint16_t rawData[131] = { + 8940, 4556, + 504, 616, 504, 616, 502, 1736, 504, 616, 504, 616, 504, 616, 502, 616, + 502, 1736, 504, 1736, 502, 616, 504, 1736, 504, 616, 502, 1736, 504, 616, + 502, 1736, 502, 616, 504, 616, 504, 1736, 502, 1736, 504, 1736, 502, 1736, + 504, 616, 502, 1736, 502, 616, 504, 616, 504, 1736, 504, 1736, 504, 1736, + 504, 616, 504, 1736, 502, 616, 502, 616, 504, 616, 504, 616, 502, 616, + 502, 616, 504, 1736, 504, 616, 504, 616, 502, 616, 504, 616, 504, 616, + 502, 616, 502, 616, 504, 616, 504, 616, 504, 616, 502, 616, 504, 616, + 504, 616, 502, 616, 502, 616, 504, 616, 504, 616, 504, 1736, 504, 616, + 504, 616, 504, 616, 504, 616, 504, 616, 504, 616, 504, 616, 502, 1736, + 504, 586, 502}; + + irsend.sendRaw(rawData, 131, 38000); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC64, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAc64Bits, irsend.capture.bits); + EXPECT_EQ(0x404000102E5E5584, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); +} + +/// Send & Decode a synthetic message. +TEST(TestDecodeCarrierAC64, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + + irsend.sendCarrierAC64(0x404000102E5E5584); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC64, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAc64Bits, irsend.capture.bits); + EXPECT_EQ(0x404000102E5E5584, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ( + "f38000d50m" + // Header + "8940s4556" + // Data + "m503s615m503s615m503s1736m503s615m503s615m503s615m503s615m503s1736" + "m503s1736m503s615m503s1736m503s615m503s1736m503s615m503s1736m503s615" + "m503s615m503s1736m503s1736m503s1736m503s1736m503s615m503s1736m503s615" + "m503s615m503s1736m503s1736m503s1736m503s615m503s1736m503s615m503s615" + "m503s615m503s615m503s615m503s615m503s1736m503s615m503s615m503s615" + "m503s615m503s615m503s615m503s615m503s615m503s615m503s615m503s615" + "m503s615m503s615m503s615m503s615m503s615m503s615m503s1736m503s615" + "m503s615m503s615m503s615m503s615m503s615m503s615m503s1736m503s615" + // Footer + "m503s100000", + irsend.outputStr()); +} diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Coolix_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Coolix_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Coolix_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Coolix_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Daikin_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Daikin_test.cpp similarity index 98% rename from lib/IRremoteESP8266-2.7.6/test/ir_Daikin_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Daikin_test.cpp index e37c6b00a..f57888c23 100644 --- a/lib/IRremoteESP8266-2.7.6/test/ir_Daikin_test.cpp +++ b/lib/IRremoteESP8266-2.7.7/test/ir_Daikin_test.cpp @@ -3690,3 +3690,36 @@ TEST(TestDaikin64Class, HumanReadable) { "Clock: 12:31, On Timer: 08:30, Off Timer: Off", ac.toString()); } + +TEST(TestDecodeDaikin64, Issue1092) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + + uint16_t rawData[137] = { + 9792, 9786, 9818, 9860, 4600, 2532, 338, 422, 332, 950, 362, 950, 360, + 378, 354, 954, 386, 378, 334, 376, 356, 382, 360, 380, 364, 946, 354, 410, + 334, 380, 364, 972, 328, 386, 358, 380, 364, 374, 358, 380, 362, 376, 356, + 382, 360, 378, 354, 410, 334, 404, 326, 412, 332, 408, 336, 376, 356, 382, + 362, 378, 354, 384, 360, 378, 354, 384, 358, 380, 354, 384, 358, 382, 362, + 976, 336, 974, 338, 374, 358, 980, 332, 380, 362, 376, 356, 382, 362, 376, + 356, 956, 356, 980, 330, 382, 360, 976, 334, 376, 356, 382, 360, 378, 354, + 384, 358, 952, 360, 950, 360, 378, 354, 384, 360, 952, 360, 378, 354, 384, + 358, 380, 364, 374, 358, 952, 360, 380, 362, 376, 356, 382, 382, 928, 362, + 376, 356, 20348, 4628}; // UNKNOWN C508A32A + + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData, 137, kDaikin64Freq); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::DAIKIN64, irsend.capture.decode_type); + ASSERT_EQ(kDaikin64Bits, irsend.capture.bits); + EXPECT_EQ(0x4426161600001216, irsend.capture.value); + EXPECT_EQ( + "Power Toggle: Off, Mode: 2 (Cool), Temp: 26C, Fan: 1 (Auto), " + "Turbo: Off, Quiet: Off, Swing(V): Off, Sleep: Off, " + "Clock: 00:00, On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + stdAc::state_t result, prev; + ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev)); +} diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Delonghi_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Delonghi_test.cpp new file mode 100644 index 000000000..9f069e40e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/test/ir_Delonghi_test.cpp @@ -0,0 +1,362 @@ +// Copyright 2020 David Conran + +#include "IRac.h" +#include "ir_Delonghi.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "IRutils.h" +#include "gtest/gtest.h" + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("DELONGHI_AC", typeToString(decode_type_t::DELONGHI_AC)); + ASSERT_EQ(decode_type_t::DELONGHI_AC, strToDecodeType("DELONGHI_AC")); + ASSERT_FALSE(hasACState(decode_type_t::DELONGHI_AC)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::DELONGHI_AC)); + ASSERT_EQ(kDelonghiAcBits, IRsend::defaultBits(decode_type_t::DELONGHI_AC)); + ASSERT_EQ(kDelonghiAcDefaultRepeat, + IRsend::minRepeats(decode_type_t::DELONGHI_AC)); +} + +TEST(TestDecodeDelonghiAc, SyntheticSelfDecode) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + + irsend.begin(); + irsend.reset(); + irsend.sendDelonghiAc(0x6900000D0D01FB53); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(DELONGHI_AC, irsend.capture.decode_type); + EXPECT_EQ(kDelonghiAcBits, irsend.capture.bits); + EXPECT_EQ(0x6900000D0D01FB53, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ(0, irsend.capture.address); +} + +TEST(TestDecodeDelonghiAc, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + // Data from: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1096#issue-610665633 + uint16_t rawData[131] = { + 8984, 4200, + 608, 1516, 608, 1516, 612, 472, 556, 528, 560, 1564, 556, 528, 560, 1564, + 564, 528, 552, 1572, 556, 1568, 556, 528, 552, 1572, 556, 1568, 560, 1564, + 552, 1572, 556, 1576, 552, 1568, 560, 528, 560, 524, 556, 528, 552, 532, + 560, 528, 552, 532, 556, 532, 560, 1564, 560, 528, 552, 1568, 560, 1564, + 564, 524, 556, 528, 560, 524, 556, 536, 556, 1568, 560, 524, 556, 1568, + 560, 1564, 584, 500, 588, 496, 584, 500, 592, 500, 588, 496, 584, 500, + 592, 496, 584, 500, 588, 496, 584, 500, 592, 492, 584, 508, 584, 500, + 588, 496, 584, 500, 592, 496, 584, 500, 580, 504, 584, 500, 580, 508, + 584, 1544, 584, 500, 588, 496, 584, 1540, 588, 500, 580, 1540, 588, 1536, + 588, 500, + 592}; + + irsend.reset(); + irsend.sendRaw(rawData, 263, 38000); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(DELONGHI_AC, irsend.capture.decode_type); + EXPECT_EQ(kDelonghiAcBits, irsend.capture.bits); + EXPECT_EQ(0x6900000D0D01FB53, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ( + "Power: On, Mode: 0 (Cool), Fan: 3 (Low), Temp: 90F, " + "Turbo: Off, Sleep: Off, On Timer: 06:13, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); +} + +// Tests for IRDelonghiAc class. + +TEST(TestIRDelonghiAcClass, Power) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.on(); + EXPECT_TRUE(ac.getPower()); + + ac.off(); + EXPECT_FALSE(ac.getPower()); + + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); + + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); + + // Ref: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1096#issuecomment-622521726 + ac.setRaw(0x5500000000010153); // Power on + EXPECT_TRUE(ac.getPower()); + ac.setRaw(0x5400000000000153); // Power off + EXPECT_FALSE(ac.getPower()); +} + +TEST(TestIRDelonghiAcClass, Temperature) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + // Celsius + ac.setTemp(0); + EXPECT_EQ(kDelonghiAcTempMinC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(255); + EXPECT_EQ(kDelonghiAcTempMaxC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMinC); + EXPECT_EQ(kDelonghiAcTempMinC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMaxC); + EXPECT_EQ(kDelonghiAcTempMaxC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMinC - 1); + EXPECT_EQ(kDelonghiAcTempMinC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMaxC + 1); + EXPECT_EQ(kDelonghiAcTempMaxC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(19); + EXPECT_EQ(19, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(29, false); + EXPECT_EQ(29, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + // Fahrenheit + ac.setTemp(0, true); + EXPECT_EQ(kDelonghiAcTempMinF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(255, true); + EXPECT_EQ(kDelonghiAcTempMaxF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMinF, true); + EXPECT_EQ(kDelonghiAcTempMinF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMaxF, true); + EXPECT_EQ(kDelonghiAcTempMaxF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMinF - 1, true); + EXPECT_EQ(kDelonghiAcTempMinF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMaxF + 1, true); + EXPECT_EQ(kDelonghiAcTempMaxF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(66, true); + EXPECT_EQ(66, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(75, true); + EXPECT_EQ(75, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(80, true); + EXPECT_EQ(80, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(88, true); + EXPECT_EQ(88, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); +} + +TEST(TestIRDelonghiAcClass, OperatingMode) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setMode(kDelonghiAcAuto); + EXPECT_EQ(kDelonghiAcAuto, ac.getMode()); + EXPECT_EQ(17, ac.getTemp()); // Check for special temp + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); // Look for fan speed enforcement + + ac.setMode(kDelonghiAcCool); + EXPECT_EQ(kDelonghiAcCool, ac.getMode()); + // Check changing to another mode that has a fixed temp and back keeps the + // existing temp. Only for Cool mode. + ac.setTemp(22); + EXPECT_EQ(22, ac.getTemp()); + ac.setMode(kDelonghiAcAuto); + EXPECT_NE(22, ac.getTemp()); + ac.setMode(kDelonghiAcCool); + EXPECT_EQ(22, ac.getTemp()); + + ac.setMode(kDelonghiAcDry); + EXPECT_EQ(kDelonghiAcDry, ac.getMode()); + EXPECT_EQ(17, ac.getTemp()); // Check for special temp + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); // Look for fan speed enforcement + + ac.setMode(kDelonghiAcFan); + EXPECT_EQ(kDelonghiAcFan, ac.getMode()); + EXPECT_EQ(23, ac.getTemp()); // Check for special temp + EXPECT_NE(kDelonghiAcFanAuto, ac.getFan()); // Look for fan speed enforcement + + ac.setMode(kDelonghiAcAuto + 1); + EXPECT_EQ(kDelonghiAcAuto, ac.getMode()); + + ac.setMode(255); + EXPECT_EQ(kDelonghiAcAuto, ac.getMode()); +} + +TEST(TestIRDelonghiAcClass, FanSpeed) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + ac.setMode(kDelonghiAcCool); // All fan speeds available in this mode. + + ac.setFan(0); + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); + + ac.setFan(255); + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); + + ac.setFan(kDelonghiAcFanHigh); + EXPECT_EQ(kDelonghiAcFanHigh, ac.getFan()); + + ac.setFan(kDelonghiAcFanLow + 1); + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); + + ac.setFan(1); + EXPECT_EQ(1, ac.getFan()); + + ac.setFan(2); + EXPECT_EQ(2, ac.getFan()); + + ac.setFan(3); + EXPECT_EQ(3, ac.getFan()); + + // Confirm changing to fan mode handles speed behaviour correctly. + ac.setFan(kDelonghiAcFanLow); + ac.setMode(kDelonghiAcFan); + EXPECT_EQ(kDelonghiAcFanLow, ac.getFan()); + ac.setMode(kDelonghiAcAuto); + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); + ac.setMode(kDelonghiAcFan); + EXPECT_NE(kDelonghiAcFanAuto, ac.getFan()); +} + +TEST(TestIRDelonghiAcClass, Boost) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setBoost(false); + EXPECT_FALSE(ac.getBoost()); + ac.setBoost(true); + EXPECT_TRUE(ac.getBoost()); + ac.setBoost(false); + EXPECT_FALSE(ac.getBoost()); +} + +TEST(TestIRDelonghiAcClass, Sleep) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setSleep(false); + EXPECT_FALSE(ac.getSleep()); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); + ac.setSleep(false); + EXPECT_FALSE(ac.getSleep()); +} + +TEST(TestIRDelonghiAcClass, OnTimer) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setOnTimerEnabled(false); + EXPECT_FALSE(ac.getOnTimerEnabled()); + ac.setOnTimerEnabled(true); + EXPECT_TRUE(ac.getOnTimerEnabled()); + ac.setOnTimerEnabled(false); + EXPECT_FALSE(ac.getOnTimerEnabled()); + + ac.setOnTimer(0); + EXPECT_FALSE(ac.getOnTimerEnabled()); + EXPECT_EQ(0, ac.getOnTimer()); + + ac.setOnTimer(1); + EXPECT_TRUE(ac.getOnTimerEnabled()); + EXPECT_EQ(1, ac.getOnTimer()); + + ac.setOnTimer(61); + EXPECT_TRUE(ac.getOnTimerEnabled()); + EXPECT_EQ(61, ac.getOnTimer()); + + ac.setOnTimerEnabled(false); + ac.setOnTimer(23 * 60 + 59); + EXPECT_TRUE(ac.getOnTimerEnabled()); + EXPECT_EQ(23 * 60 + 59, ac.getOnTimer()); + + ac.setOnTimerEnabled(false); + ac.setOnTimer(24 * 60); + EXPECT_TRUE(ac.getOnTimerEnabled()); + EXPECT_EQ(23 * 60 + 59, ac.getOnTimer()); +} + +TEST(TestIRDelonghiAcClass, OffTimer) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setOffTimerEnabled(false); + EXPECT_FALSE(ac.getOffTimerEnabled()); + ac.setOffTimerEnabled(true); + EXPECT_TRUE(ac.getOffTimerEnabled()); + ac.setOffTimerEnabled(false); + EXPECT_FALSE(ac.getOffTimerEnabled()); + + ac.setOffTimer(0); + EXPECT_FALSE(ac.getOffTimerEnabled()); + EXPECT_EQ(0, ac.getOffTimer()); + + ac.setOffTimer(1); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(1, ac.getOffTimer()); + + ac.setOffTimer(61); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(61, ac.getOffTimer()); + + ac.setOffTimerEnabled(false); + ac.setOffTimer(23 * 60 + 59); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(23 * 60 + 59, ac.getOffTimer()); + + ac.setOffTimerEnabled(false); + ac.setOffTimer(24 * 60); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(23 * 60 + 59, ac.getOffTimer()); + + // Real Data + // From: https://github.com/crankyoldgit/IRremoteESP8266/issues/1096#issuecomment-623115619 + // Setting off timer to 8:51 when the time on the remote displayed 16:05. + // (8:51 + 24:00 - 16:05 == 32:51 - 16:05 == 16:46) i.e. Turn off in 16h46m. + ac.setRaw(0xB12E210000000F53); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(16 * 60 + 46, ac.getOffTimer()); + EXPECT_FALSE(ac.getOnTimerEnabled()); + EXPECT_EQ(0, ac.getOnTimer()); +} diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Denon_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Denon_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Denon_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Denon_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Dish_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Dish_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Dish_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Dish_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Doshisha_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Doshisha_test.cpp new file mode 100644 index 000000000..8c69bfbb3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/test/ir_Doshisha_test.cpp @@ -0,0 +1,152 @@ +// Copyright 2020 Christian Nilsson + +#include "IRac.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "gtest/gtest.h" + +// Tests for decodeDoshisha(). + +TEST(TestDecodeDoshisha, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + // CH2 Light Level 1 + const uint16_t rawData_1[83] = { + 3404, 1718, + 416, 1306, 416, 460, 438, 432, 412, 460, 464, 396, 488, 394, 488, 394, + 488, 398, 460, 430, 468, 398, 484, 416, 468, 396, 488, 1264, 414, 460, + 436, 1286, 524, 1210, 470, 390, 434, 456, 414, 1288, 458, 1290, 438, 434, + 412, 458, 440, 434, 438, 418, 456, 432, 466, 1270, 438, 442, 438, 430, + 414, 1316, 412, 460, 440, 432, 412, 460, 440, 1264, 458, 434, 436, 1268, + 458, 436, 438, 412, 456, 1290, 438, 442, 436, 1290, + 464}; // DOSHISHA 800B3048A5 + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_1, 83, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + ASSERT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048A5, irsend.capture.value); + EXPECT_EQ(0b1, irsend.capture.address); + EXPECT_EQ(0xA4, irsend.capture.command); + + // CH2 OFF + const uint16_t rawData_2[83] = { + 3434, 1700, + 446, 1284, 442, 440, 442, 428, 444, 432, 440, 430, 442, 432, 472, 438, + 444, 446, 416, 430, 470, 416, 470, 438, 444, 442, 470, 1242, 440, 430, + 442, 1314, 390, 1344, 444, 440, 414, 432, 442, 1310, 412, 1318, 416, 458, + 416, 434, 438, 432, 418, 484, 416, 458, 442, 1298, 416, 466, 420, 428, + 442, 1316, 418, 432, 442, 430, 442, 434, 444, 1286, 440, 430, 444, 1288, + 444, 430, 444, 430, 442, 432, 498, 386, 498, 1242, + 474}; // DOSHISHA 800B3048A1 + + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_2, 175, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + ASSERT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048A1, irsend.capture.value); + EXPECT_EQ(0b1, irsend.capture.address); + EXPECT_EQ(0xA0, irsend.capture.command); + + // CH1 OFF + const uint16_t rawData_4[83] = { + 3470, 1670, + 444, 1294, 470, 408, 442, 430, 444, 412, 464, 440, 498, 386, 498, 388, + 474, 418, 440, 430, 472, 414, 474, 412, 472, 414, 470, 1268, 444, 428, + 448, 1284, 444, 1294, 472, 412, 446, 428, 442, 1284, 444, 1290, 444, 430, + 446, 430, 442, 410, 490, 406, 446, 428, 472, 1270, 472, 414, 442, 410, + 460, 1292, 444, 430, 442, 430, 444, 434, 444, 1286, 442, 432, 442, 1288, + 446, 430, 442, 414, 486, 386, 516, 388, 446, 438, + 446}; // DOSHISHA 800B3048A0 + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_4, 175, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + ASSERT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048A0, irsend.capture.value); + EXPECT_EQ(0b0, irsend.capture.address); + EXPECT_EQ(0xA0, irsend.capture.command); +} + +TEST(TestDecodeDoshisha, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + irsend.sendDoshisha(0x800B3048A5); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + EXPECT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048A5, irsend.capture.value); + EXPECT_EQ(0b1, irsend.capture.address); + EXPECT_EQ(0xA4, irsend.capture.command); + + EXPECT_EQ( + "f38000d50" + "m3412s1722" + "m420s1310m420s452m420s452m420s452m420s452m420s452m420s452" + "m420s452m420s452m420s452m420s452m420s452m420s1310m420s452" + "m420s1310m420s1310m420s452m420s452m420s1310m420s1310m420s452" + "m420s452m420s452m420s452m420s452m420s1310m420s452m420s452" + "m420s1310m420s452m420s452m420s452m420s1310m420s452m420s1310" + "m420s452m420s452m420s1310m420s452m420s1310" + "m420s100000", + irsend.outputStr()); + + irsend.reset(); + irsend.sendDoshisha(0x800B3048D0); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + EXPECT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048D0, irsend.capture.value); + EXPECT_EQ(irsend.encodeDoshisha(0xD0, 0b0), irsend.capture.value); + EXPECT_EQ(0b0, irsend.capture.address); + EXPECT_EQ(0xD0, irsend.capture.command); + EXPECT_EQ( + "f38000d50" + "m3412s1722" + "m420s1310m420s452m420s452m420s452m420s452m420s452m420s452" + "m420s452m420s452m420s452m420s452m420s452m420s1310m420s452" + "m420s1310m420s1310m420s452m420s452m420s1310m420s1310m420s452" + "m420s452m420s452m420s452m420s452m420s1310m420s452m420s452m420" + "s1310m420s452m420s452m420s452m420s1310m420s1310m420s452m420s1310" + "m420s452m420s452m420s452m420s452" + "m420s100000", + irsend.outputStr()); +} + +TEST(TestEncodeDoshisha, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + // kRcz01CheckExpected + EXPECT_EQ(0x800B304800, irsend.encodeDoshisha(0x00, 0b0)); + // kRcz01CommandTimmer30 + EXPECT_EQ(0x800B304892, irsend.encodeDoshisha(0x92, 0b0)); + // kRcz01CommandLevel1 + EXPECT_EQ(0x800B3048A5, irsend.encodeDoshisha(0xA4, 0b1)); + EXPECT_EQ(0x800B3048A4, irsend.encodeDoshisha(0xA4, 0b0)); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("DOSHISHA", typeToString(decode_type_t::DOSHISHA)); + ASSERT_EQ(decode_type_t::DOSHISHA, strToDecodeType("DOSHISHA")); + ASSERT_FALSE(hasACState(decode_type_t::DOSHISHA)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::DOSHISHA)); + ASSERT_EQ(kDoshishaBits, IRsend::defaultBits(decode_type_t::DOSHISHA)); + ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::DOSHISHA)); +} diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Electra_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Electra_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Electra_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Electra_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Epson_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Epson_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Epson_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Epson_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Fujitsu_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Fujitsu_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Fujitsu_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Fujitsu_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_GICable_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_GICable_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_GICable_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_GICable_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_GlobalCache_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_GlobalCache_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_GlobalCache_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_GlobalCache_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Goodweather_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Goodweather_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Goodweather_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Goodweather_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Gree_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Gree_test.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.6/test/ir_Gree_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Gree_test.cpp index a824cd10a..46b1b17b4 100644 --- a/lib/IRremoteESP8266-2.7.6/test/ir_Gree_test.cpp +++ b/lib/IRremoteESP8266-2.7.7/test/ir_Gree_test.cpp @@ -13,7 +13,7 @@ // Test sending typical data only. TEST(TestSendGreeChars, SendData) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); uint8_t gree_code[kGreeStateLength] = {0x12, 0x34, 0x56, 0x78, @@ -38,7 +38,7 @@ TEST(TestSendGreeChars, SendData) { } TEST(TestSendGreeUint64, SendData) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); irsend.reset(); @@ -62,7 +62,7 @@ TEST(TestSendGreeUint64, SendData) { // Test sending with repeats. TEST(TestSendGreeChars, SendWithRepeats) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); irsend.reset(); @@ -101,7 +101,7 @@ TEST(TestSendGreeChars, SendWithRepeats) { } TEST(TestSendGreeUint64, SendWithRepeats) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); irsend.reset(); @@ -137,7 +137,7 @@ TEST(TestSendGreeUint64, SendWithRepeats) { // Test sending atypical sizes. TEST(TestSendGreeChars, SendUnexpectedSizes) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); uint8_t gree_short_code[kGreeStateLength - 1] = {0x12, 0x34, 0x56, 0x78, @@ -169,7 +169,7 @@ TEST(TestSendGreeChars, SendUnexpectedSizes) { } TEST(TestSendGreeUint64, SendUnexpectedSizes) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); irsend.reset(); @@ -209,138 +209,184 @@ TEST(TestSendGree, CompareUint64ToCharResults) { // Tests for IRGreeAC class. TEST(TestGreeClass, Power) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.on(); - EXPECT_TRUE(irgree.getPower()); + ac.on(); + EXPECT_TRUE(ac.getPower()); - irgree.off(); - EXPECT_FALSE(irgree.getPower()); + ac.off(); + EXPECT_FALSE(ac.getPower()); - irgree.setPower(true); - EXPECT_TRUE(irgree.getPower()); + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); - irgree.setPower(false); - EXPECT_FALSE(irgree.getPower()); + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); } TEST(TestGreeClass, Temperature) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setMode(kGreeCool); + ac.setMode(kGreeCool); - irgree.setTemp(0); - EXPECT_EQ(kGreeMinTemp, irgree.getTemp()); + ac.setTemp(0); + EXPECT_EQ(kGreeMinTempC, ac.getTemp()); - irgree.setTemp(255); - EXPECT_EQ(kGreeMaxTemp, irgree.getTemp()); + ac.setTemp(255); + EXPECT_EQ(kGreeMaxTempC, ac.getTemp()); - irgree.setTemp(kGreeMinTemp); - EXPECT_EQ(kGreeMinTemp, irgree.getTemp()); + ac.setTemp(kGreeMinTempC); + EXPECT_EQ(kGreeMinTempC, ac.getTemp()); + EXPECT_FALSE(ac.getUseFahrenheit()); - irgree.setTemp(kGreeMaxTemp); - EXPECT_EQ(kGreeMaxTemp, irgree.getTemp()); + ac.setTemp(kGreeMaxTempC); + EXPECT_EQ(kGreeMaxTempC, ac.getTemp()); - irgree.setTemp(kGreeMinTemp - 1); - EXPECT_EQ(kGreeMinTemp, irgree.getTemp()); + ac.setTemp(kGreeMinTempC - 1); + EXPECT_EQ(kGreeMinTempC, ac.getTemp()); - irgree.setTemp(kGreeMaxTemp + 1); - EXPECT_EQ(kGreeMaxTemp, irgree.getTemp()); + ac.setTemp(kGreeMaxTempC + 1); + EXPECT_EQ(kGreeMaxTempC, ac.getTemp()); - irgree.setTemp(17); - EXPECT_EQ(17, irgree.getTemp()); + ac.setTemp(17); + EXPECT_EQ(17, ac.getTemp()); - irgree.setTemp(21); - EXPECT_EQ(21, irgree.getTemp()); + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); - irgree.setTemp(25); - EXPECT_EQ(25, irgree.getTemp()); + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); - irgree.setTemp(29); - EXPECT_EQ(29, irgree.getTemp()); + ac.setTemp(29); + EXPECT_EQ(29, ac.getTemp()); + + // Fahrenheit tests. + ac.setTemp(kGreeMinTempF, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMinTempF, ac.getTemp()); + + ac.setTemp(kGreeMaxTempF, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMaxTempF, ac.getTemp()); + + ac.setTemp(kGreeMaxTempF + 1, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMaxTempF, ac.getTemp()); + + ac.setTemp(kGreeMaxTempF - 1, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMaxTempF - 1, ac.getTemp()); + + ac.setTemp(kGreeMaxTempF - 2, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMaxTempF - 2, ac.getTemp()); + + ac.setTemp(kGreeMinTempF - 1, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMinTempF, ac.getTemp()); + + ac.setTemp(kGreeMinTempF + 1, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMinTempF + 1, ac.getTemp()); + + ac.setTemp(kGreeMinTempF + 2, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMinTempF + 2, ac.getTemp()); + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1121#issuecomment-628946040 + ac.setUseFahrenheit(false); + const uint8_t state[] = {0x09, 0x01, 0x20, 0x5C, 0x00, 0x20, 0x00, 0x20}; + ac.setRaw(state); + EXPECT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(63, ac.getTemp()); + EXPECT_EQ( + "Model: 2 (YBOFB), Power: On, Mode: 1 (Cool), Temp: 63F, Fan: 0 (Auto), " + "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, " + "Swing(V) Mode: Manual, Swing(V): 0 (Last), Timer: Off, " + "Display Temp: 0 (Off)", ac.toString()); } TEST(TestGreeClass, OperatingMode) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setTemp(17); - irgree.setMode(kGreeAuto); // Auto should lock the temp to 25C. - EXPECT_EQ(kGreeAuto, irgree.getMode()); - EXPECT_EQ(25, irgree.getTemp()); - irgree.setTemp(17); - EXPECT_EQ(25, irgree.getTemp()); + ac.setTemp(17); + ac.setMode(kGreeAuto); // Auto should lock the temp to 25C. + EXPECT_EQ(kGreeAuto, ac.getMode()); + EXPECT_EQ(25, ac.getTemp()); + ac.setTemp(17); + EXPECT_EQ(25, ac.getTemp()); - irgree.setMode(kGreeCool); - EXPECT_EQ(kGreeCool, irgree.getMode()); + ac.setMode(kGreeCool); + EXPECT_EQ(kGreeCool, ac.getMode()); - irgree.setMode(kGreeHeat); - EXPECT_EQ(kGreeHeat, irgree.getMode()); + ac.setMode(kGreeHeat); + EXPECT_EQ(kGreeHeat, ac.getMode()); ASSERT_NE(kGreeFanMax, 1); - irgree.setFan(kGreeFanMax); - irgree.setMode(kGreeDry); // Dry should lock the fan to speed 1. - EXPECT_EQ(kGreeDry, irgree.getMode()); - EXPECT_EQ(1, irgree.getFan()); - irgree.setFan(kGreeFanMax); - EXPECT_EQ(1, irgree.getFan()); + ac.setFan(kGreeFanMax); + ac.setMode(kGreeDry); // Dry should lock the fan to speed 1. + EXPECT_EQ(kGreeDry, ac.getMode()); + EXPECT_EQ(1, ac.getFan()); + ac.setFan(kGreeFanMax); + EXPECT_EQ(1, ac.getFan()); - irgree.setMode(kGreeFan); - EXPECT_EQ(kGreeFan, irgree.getMode()); + ac.setMode(kGreeFan); + EXPECT_EQ(kGreeFan, ac.getMode()); - irgree.setMode(kGreeHeat + 1); - EXPECT_EQ(kGreeAuto, irgree.getMode()); + ac.setMode(kGreeHeat + 1); + EXPECT_EQ(kGreeAuto, ac.getMode()); - irgree.setMode(255); - EXPECT_EQ(kGreeAuto, irgree.getMode()); + ac.setMode(255); + EXPECT_EQ(kGreeAuto, ac.getMode()); } TEST(TestGreeClass, Light) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setLight(true); - EXPECT_TRUE(irgree.getLight()); + ac.setLight(true); + EXPECT_TRUE(ac.getLight()); - irgree.setLight(false); - EXPECT_FALSE(irgree.getLight()); + ac.setLight(false); + EXPECT_FALSE(ac.getLight()); - irgree.setLight(true); - EXPECT_TRUE(irgree.getLight()); + ac.setLight(true); + EXPECT_TRUE(ac.getLight()); } TEST(TestGreeClass, XFan) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setXFan(true); - EXPECT_TRUE(irgree.getXFan()); + ac.setXFan(true); + EXPECT_TRUE(ac.getXFan()); - irgree.setXFan(false); - EXPECT_FALSE(irgree.getXFan()); + ac.setXFan(false); + EXPECT_FALSE(ac.getXFan()); - irgree.setXFan(true); - EXPECT_TRUE(irgree.getXFan()); + ac.setXFan(true); + EXPECT_TRUE(ac.getXFan()); } TEST(TestGreeClass, Turbo) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setTurbo(true); - EXPECT_TRUE(irgree.getTurbo()); + ac.setTurbo(true); + EXPECT_TRUE(ac.getTurbo()); - irgree.setTurbo(false); - EXPECT_FALSE(irgree.getTurbo()); + ac.setTurbo(false); + EXPECT_FALSE(ac.getTurbo()); - irgree.setTurbo(true); - EXPECT_TRUE(irgree.getTurbo()); + ac.setTurbo(true); + EXPECT_TRUE(ac.getTurbo()); } TEST(TestGreeClass, IFeel) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.begin(); ac.setIFeel(true); @@ -362,7 +408,7 @@ TEST(TestGreeClass, IFeel) { } TEST(TestGreeClass, WiFi) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.begin(); ac.setWiFi(true); @@ -384,148 +430,150 @@ TEST(TestGreeClass, WiFi) { } TEST(TestGreeClass, Sleep) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setSleep(true); - EXPECT_TRUE(irgree.getSleep()); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); - irgree.setSleep(false); - EXPECT_FALSE(irgree.getSleep()); + ac.setSleep(false); + EXPECT_FALSE(ac.getSleep()); - irgree.setSleep(true); - EXPECT_TRUE(irgree.getSleep()); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); } TEST(TestGreeClass, FanSpeed) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setFan(0); - EXPECT_EQ(0, irgree.getFan()); + ac.setFan(0); + EXPECT_EQ(0, ac.getFan()); - irgree.setFan(255); - EXPECT_EQ(kGreeFanMax, irgree.getFan()); + ac.setFan(255); + EXPECT_EQ(kGreeFanMax, ac.getFan()); - irgree.setFan(kGreeFanMax); - EXPECT_EQ(kGreeFanMax, irgree.getFan()); + ac.setFan(kGreeFanMax); + EXPECT_EQ(kGreeFanMax, ac.getFan()); - irgree.setFan(kGreeFanMax + 1); - EXPECT_EQ(kGreeFanMax, irgree.getFan()); + ac.setFan(kGreeFanMax + 1); + EXPECT_EQ(kGreeFanMax, ac.getFan()); - irgree.setFan(kGreeFanMax - 1); - EXPECT_EQ(kGreeFanMax - 1, irgree.getFan()); + ac.setFan(kGreeFanMax - 1); + EXPECT_EQ(kGreeFanMax - 1, ac.getFan()); - irgree.setFan(1); - EXPECT_EQ(1, irgree.getFan()); + ac.setFan(1); + EXPECT_EQ(1, ac.getFan()); - irgree.setFan(1); - EXPECT_EQ(1, irgree.getFan()); + ac.setFan(1); + EXPECT_EQ(1, ac.getFan()); - irgree.setFan(3); - EXPECT_EQ(3, irgree.getFan()); + ac.setFan(3); + EXPECT_EQ(3, ac.getFan()); } TEST(TestGreeClass, VerticalSwing) { - IRGreeAC irgree(0); - irgree.begin(); - EXPECT_FALSE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingLastPos, irgree.getSwingVerticalPosition()); + IRGreeAC ac(kGpioUnused); + ac.begin(); + EXPECT_FALSE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingLastPos, ac.getSwingVerticalPosition()); - irgree.setSwingVertical(true, kGreeSwingAuto); - EXPECT_TRUE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingAuto, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(true, kGreeSwingAuto); + EXPECT_TRUE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition()); - irgree.setSwingVertical(false, kGreeSwingMiddle); - EXPECT_FALSE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingMiddle, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(false, kGreeSwingMiddle); + EXPECT_FALSE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingMiddle, ac.getSwingVerticalPosition()); - irgree.setSwingVertical(true, kGreeSwingDownAuto); - EXPECT_TRUE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingDownAuto, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(true, kGreeSwingDownAuto); + EXPECT_TRUE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingDownAuto, ac.getSwingVerticalPosition()); // Out of bounds. - irgree.setSwingVertical(false, 255); - EXPECT_FALSE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingLastPos, irgree.getSwingVerticalPosition()); - irgree.setSwingVertical(false, kGreeSwingAuto); - EXPECT_FALSE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingLastPos, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(false, 255); + EXPECT_FALSE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingLastPos, ac.getSwingVerticalPosition()); + ac.setSwingVertical(false, kGreeSwingAuto); + EXPECT_FALSE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingLastPos, ac.getSwingVerticalPosition()); - irgree.setSwingVertical(true, 255); - EXPECT_TRUE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingAuto, irgree.getSwingVerticalPosition()); - irgree.setSwingVertical(true, kGreeSwingDown); - EXPECT_TRUE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingAuto, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(true, 255); + EXPECT_TRUE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition()); + ac.setSwingVertical(true, kGreeSwingDown); + EXPECT_TRUE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition()); } TEST(TestGreeClass, SetAndGetRaw) { - IRGreeAC irgree(0); + IRGreeAC ac(kGpioUnused); uint8_t initialState[kGreeStateLength] = {0x00, 0x09, 0x20, 0x50, 0x00, 0x20, 0x00, 0x50}; uint8_t expectedState[kGreeStateLength] = {0xA9, 0x05, 0xD0, 0x50, 0x00, 0x20, 0x00, 0xA0}; - EXPECT_STATE_EQ(initialState, irgree.getRaw(), kGreeBits); + EXPECT_STATE_EQ(initialState, ac.getRaw(), kGreeBits); // toggle the power state. - irgree.setPower(!irgree.getPower()); - irgree.setMode(kGreeCool); - irgree.setTemp(21); - irgree.setFan(2); - irgree.setLight(false); - irgree.setTurbo(true); - irgree.setSleep(true); - irgree.setXFan(true); + ac.setPower(!ac.getPower()); + ac.setMode(kGreeCool); + ac.setTemp(21); + ac.setFan(2); + ac.setLight(false); + ac.setTurbo(true); + ac.setSleep(true); + ac.setXFan(true); - EXPECT_EQ(kGreeCool, irgree.getMode()); - EXPECT_EQ(21, irgree.getTemp()); - EXPECT_EQ(2, irgree.getFan()); - EXPECT_FALSE(irgree.getLight()); - EXPECT_TRUE(irgree.getTurbo()); - EXPECT_TRUE(irgree.getSleep()); - EXPECT_TRUE(irgree.getXFan()); + EXPECT_EQ(kGreeCool, ac.getMode()); + EXPECT_EQ(21, ac.getTemp()); + EXPECT_EQ(2, ac.getFan()); + EXPECT_FALSE(ac.getLight()); + EXPECT_TRUE(ac.getTurbo()); + EXPECT_TRUE(ac.getSleep()); + EXPECT_TRUE(ac.getXFan()); - EXPECT_STATE_EQ(expectedState, irgree.getRaw(), kGreeBits); - irgree.setRaw(initialState); - EXPECT_STATE_EQ(initialState, irgree.getRaw(), kGreeBits); + EXPECT_STATE_EQ(expectedState, ac.getRaw(), kGreeBits); + ac.setRaw(initialState); + EXPECT_STATE_EQ(initialState, ac.getRaw(), kGreeBits); } TEST(TestGreeClass, HumanReadable) { - IRGreeAC irgree(0); + IRGreeAC ac(kGpioUnused); EXPECT_EQ( "Model: 1 (YAW1F), Power: Off, Mode: 0 (Auto), Temp: 25C, Fan: 0 (Auto), " "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, " "Swing(V) Mode: Manual, Swing(V): 0 (Last), " - "Timer: Off", - irgree.toString()); - irgree.on(); - irgree.setMode(kGreeCool); - irgree.setTemp(kGreeMinTemp); - irgree.setFan(kGreeFanMax); - irgree.setXFan(true); - irgree.setSleep(true); - irgree.setLight(false); - irgree.setTurbo(true); - irgree.setIFeel(true); - irgree.setWiFi(true); - irgree.setSwingVertical(true, kGreeSwingAuto); - irgree.setTimer(12 * 60 + 30); + "Timer: Off, Display Temp: 0 (Off)", + ac.toString()); + ac.on(); + ac.setMode(kGreeCool); + ac.setTemp(kGreeMinTempC); + ac.setFan(kGreeFanMax); + ac.setXFan(true); + ac.setSleep(true); + ac.setLight(false); + ac.setTurbo(true); + ac.setIFeel(true); + ac.setWiFi(true); + ac.setSwingVertical(true, kGreeSwingAuto); + ac.setTimer(12 * 60 + 30); + ac.setDisplayTempSource(3); EXPECT_EQ( "Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 3 (High), " "Turbo: On, IFeel: On, WiFi: On, XFan: On, Light: Off, Sleep: On, " - "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: 12:30", - irgree.toString()); + "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: 12:30, " + "Display Temp: 3 (Outside)", + ac.toString()); } // Tests for decodeGree(). // Decode a synthetic Gree message. TEST(TestDecodeGree, NormalSynthetic) { - IRsendTest irsend(4); - IRrecv irrecv(4); + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); irsend.begin(); uint8_t gree_code[kGreeStateLength] = {0x00, 0x09, 0x20, 0x50, @@ -542,9 +590,9 @@ TEST(TestDecodeGree, NormalSynthetic) { // Decode a real Gree message. TEST(TestDecodeGree, NormalRealExample) { - IRsendTest irsend(4); - IRrecv irrecv(4); - IRGreeAC irgree(4); + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + IRGreeAC ac(kGpioUnused); irsend.begin(); uint8_t gree_code[kGreeStateLength] = {0x19, 0x0A, 0x60, 0x50, @@ -572,18 +620,19 @@ TEST(TestDecodeGree, NormalRealExample) { EXPECT_EQ(GREE, irsend.capture.decode_type); ASSERT_EQ(kGreeBits, irsend.capture.bits); EXPECT_STATE_EQ(gree_code, irsend.capture.state, kGreeBits); - irgree.setRaw(irsend.capture.state); + ac.setRaw(irsend.capture.state); EXPECT_EQ( "Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 26C, Fan: 1 (Low), " "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, " - "Swing(V) Mode: Manual, Swing(V): 2 (UNKNOWN), Timer: Off", + "Swing(V) Mode: Manual, Swing(V): 2 (UNKNOWN), Timer: Off, " + "Display Temp: 3 (Outside)", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); } TEST(TestGreeClass, toCommon) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.setPower(true); ac.setMode(kGreeCool); ac.setTemp(20); @@ -616,7 +665,7 @@ TEST(TestGreeClass, toCommon) { } TEST(TestGreeClass, Issue814Power) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.begin(); // https://github.com/crankyoldgit/IRremoteESP8266/issues/814#issuecomment-511263921 @@ -633,7 +682,8 @@ TEST(TestGreeClass, Issue814Power) { EXPECT_EQ( "Model: 2 (YBOFB), Power: On, Mode: 1 (Cool), Temp: 23C, Fan: 1 (Low), " "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, " - "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: Off", + "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: Off, " + "Display Temp: 0 (Off)", ac.toString()); ac.off(); EXPECT_STATE_EQ(off, ac.getRaw(), kGreeBits); @@ -650,7 +700,7 @@ TEST(TestGreeClass, Issue814Power) { } TEST(TestGreeClass, Timer) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.begin(); ac.setTimer(0); @@ -689,3 +739,25 @@ TEST(TestGreeClass, Timer) { EXPECT_TRUE(ac.getTimerEnabled()); EXPECT_EQ(24 * 60, ac.getTimer()); } + +TEST(TestGreeClass, DisplayTempSource) { + IRGreeAC ac(kGpioUnused); + ac.begin(); + + ac.setDisplayTempSource(1); + EXPECT_EQ(1, ac.getDisplayTempSource()); + + ac.setDisplayTempSource(2); + EXPECT_EQ(2, ac.getDisplayTempSource()); + + ac.setDisplayTempSource(3); + EXPECT_EQ(3, ac.getDisplayTempSource()); + + ac.setDisplayTempSource(1); + EXPECT_EQ(1, ac.getDisplayTempSource()); + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1118#issuecomment-627674014 + const uint8_t state[8] = {0x4C, 0x04, 0x60, 0x50, 0x01, 0x02, 0x00, 0xA0}; + ac.setRaw(state); + EXPECT_EQ(2, ac.getDisplayTempSource()); +} diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Haier_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Haier_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Haier_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Haier_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Hitachi_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Hitachi_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Hitachi_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Hitachi_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Inax_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Inax_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Inax_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Inax_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_JVC_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_JVC_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_JVC_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_JVC_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Kelvinator_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Kelvinator_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Kelvinator_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Kelvinator_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_LG_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_LG_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_LG_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_LG_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Lasertag_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Lasertag_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Lasertag_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Lasertag_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Lego_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Lego_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Lego_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Lego_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Lutron_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Lutron_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Lutron_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Lutron_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_MWM_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_MWM_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_MWM_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_MWM_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Magiquest_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Magiquest_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Magiquest_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Magiquest_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Midea_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Midea_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Midea_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Midea_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_MitsubishiHeavy_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_MitsubishiHeavy_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_MitsubishiHeavy_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_MitsubishiHeavy_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Mitsubishi_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Mitsubishi_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Mitsubishi_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Mitsubishi_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Multibrackets_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Multibrackets_test.cpp new file mode 100644 index 000000000..7b58b3333 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/test/ir_Multibrackets_test.cpp @@ -0,0 +1,98 @@ +// Copyright 2020 David Conran + +#include "IRac.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "gtest/gtest.h" + +// Tests for decodeMultibrackets(). + +// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1103 + +TEST(TestDecodeMultibrackets, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + // The 1 + ok keypress: + uint16_t rawData_1[7] = {20100, 20472, 15092, 30704, 20102, 20472, 15086}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_1, 7, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type); + ASSERT_EQ(kMultibracketsBits, irsend.capture.bits); + EXPECT_EQ(0x87, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // ok keypress. + const uint16_t rawData_2[11] = { + 25124, 5108, 5038, 5110, 5034, 40940, 25132, 5108, 5036, 5110, 5036}; + + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_2, 11, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type); + ASSERT_EQ(kMultibracketsBits, irsend.capture.bits); + EXPECT_EQ(0xD4, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +} + +TEST(TestDecodeMultibrackets, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + irsend.sendMultibrackets(0x87); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type); + EXPECT_EQ(kMultibracketsBits, irsend.capture.bits); + EXPECT_EQ(0x87, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // Real data is: + // uint16_t rawData[7] = {20100, 20472, 15092, 30704, 20102, 20472, 15086}; + + EXPECT_EQ( + "f38000d50m20000s20000m15000s30000m20000s20000m15000s30000", + irsend.outputStr()); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("MULTIBRACKETS", typeToString(decode_type_t::MULTIBRACKETS)); + ASSERT_EQ(decode_type_t::MULTIBRACKETS, strToDecodeType("MULTIBRACKETS")); + ASSERT_FALSE(hasACState(decode_type_t::MULTIBRACKETS)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::MULTIBRACKETS)); + ASSERT_EQ(kMultibracketsBits, + IRsend::defaultBits(decode_type_t::MULTIBRACKETS)); + ASSERT_EQ(kMultibracketsDefaultRepeat, + IRsend::minRepeats(decode_type_t::MULTIBRACKETS)); +} + +TEST(TestDecodeMultibrackets, ShortNoRepeatExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + // The 1 + ok keypress: (edited to be bare minimum) + uint16_t rawData[3] = {20100, 20472, 15092}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData, 3, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type); + ASSERT_EQ(kMultibracketsBits, irsend.capture.bits); + EXPECT_EQ(0x87, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +} diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_NEC_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_NEC_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_NEC_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_NEC_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Neoclima_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Neoclima_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Neoclima_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Neoclima_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Nikai_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Nikai_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Nikai_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Nikai_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Panasonic_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Panasonic_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Panasonic_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Panasonic_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Pioneer_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Pioneer_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Pioneer_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Pioneer_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Pronto_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Pronto_test.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.6/test/ir_Pronto_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Pronto_test.cpp index b5020987f..8331192bc 100644 --- a/lib/IRremoteESP8266-2.7.6/test/ir_Pronto_test.cpp +++ b/lib/IRremoteESP8266-2.7.7/test/ir_Pronto_test.cpp @@ -58,7 +58,7 @@ TEST(TestSendPronto, MoreDataThanNeededInNormal) { uint16_t pronto_test[8] = {0x0000, 0x0067, 0x0001, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004}; irsend.sendPronto(pronto_test, 8); - EXPECT_EQ("f40244d50m25s50", + EXPECT_EQ("f40244d50m24s49", irsend.outputStr()); // Only send the data required. } @@ -71,7 +71,7 @@ TEST(TestSendPronto, MoreDataThanNeededInRepeat) { uint16_t pronto_test[8] = {0x0000, 0x0067, 0x0000, 0x0001, 0x0001, 0x0002, 0x0003, 0x0004}; irsend.sendPronto(pronto_test, 8); - EXPECT_EQ("f40244d50m25s50", + EXPECT_EQ("f40244d50m24s49", irsend.outputStr()); // Only send the data required. } @@ -84,10 +84,10 @@ TEST(TestSendPronto, MoreDataThanNeededInBoth) { uint16_t pronto_test[10] = {0x0000, 0x0067, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003, 0x0004, 0x5, 0x6}; irsend.sendPronto(pronto_test, 10); - EXPECT_EQ("f40244d50m25s50", + EXPECT_EQ("f40244d50m24s49", irsend.outputStr()); // Only send the data required. irsend.sendPronto(pronto_test, 10, 1); - EXPECT_EQ("f40244d50m25s50m75s100", + EXPECT_EQ("f40244d50m24s49m74s99", irsend.outputStr()); // Only the data required. } @@ -139,18 +139,18 @@ TEST(TestSendPronto, NonRepeatingCode) { EXPECT_EQ(0x0, irsend.capture.command); EXPECT_EQ( "f40244d50" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s600", + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s597", irsend.outputStr()); // Now try repeating it. @@ -166,18 +166,18 @@ TEST(TestSendPronto, NonRepeatingCode) { EXPECT_EQ(0x0, irsend.capture.command); EXPECT_EQ( "f40244d50" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s600", + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s597", irsend.outputStr()); } @@ -208,10 +208,10 @@ TEST(TestSendPronto, RepeatSequenceOnlyForSony) { EXPECT_EQ(0x24AE, irsend.capture.command); EXPECT_EQ( "f40244d50" - "m2400s600" - "m600s600m1200s600m1200s600m1200s600m600s600m1200s600m600s600m600s600" - "m1200s600m600s600m1200s600m1200s600m1200s600m600s600m600s600m1200s600" - "m600s600m600s600m1200s600m600s25350", + "m2390s597" + "m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597" + "m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597" + "m597s597m597s597m1195s597m597s25248", irsend.outputStr()); // Send the Pronto code with 2 repeats. @@ -226,18 +226,18 @@ TEST(TestSendPronto, RepeatSequenceOnlyForSony) { EXPECT_EQ(0x24AE, irsend.capture.command); EXPECT_EQ( "f40244d50" - "m2400s600" - "m600s600m1200s600m1200s600m1200s600m600s600m1200s600m600s600m600s600" - "m1200s600m600s600m1200s600m1200s600m1200s600m600s600m600s600m1200s600" - "m600s600m600s600m1200s600m600s25350" - "m2400s600" - "m600s600m1200s600m1200s600m1200s600m600s600m1200s600m600s600m600s600" - "m1200s600m600s600m1200s600m1200s600m1200s600m600s600m600s600m1200s600" - "m600s600m600s600m1200s600m600s25350" - "m2400s600" - "m600s600m1200s600m1200s600m1200s600m600s600m1200s600m600s600m600s600" - "m1200s600m600s600m1200s600m1200s600m1200s600m600s600m600s600m1200s600" - "m600s600m600s600m1200s600m600s25350", + "m2390s597" + "m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597" + "m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597" + "m597s597m597s597m1195s597m597s25248" + "m2390s597" + "m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597" + "m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597" + "m597s597m597s597m1195s597m597s25248" + "m2390s597" + "m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597" + "m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597" + "m597s597m597s597m1195s597m597s25248", irsend.outputStr()); } @@ -274,14 +274,14 @@ TEST(TestSendPronto, RepeatSequenceOnlyForPanasonic) { EXPECT_EQ(0x1007C7D, irsend.capture.command); EXPECT_EQ( "f36682d50" - "m3456s1701" - "m432s432m432s1296m432s432m432s432m432s432m432s432m432s432m432s432" - "m432s432m432s432m432s432m432s432m432s432m432s1296m432s432m432s432" - "m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s1296" - "m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s432" - "m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s432" - "m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s1296" - "m432s73224", + "m3494s1719" + "m436s436m436s1310m436s436m436s436m436s436m436s436m436s436m436s436" + "m436s436m436s436m436s436m436s436m436s436m436s1310m436s436m436s436" + "m436s436m436s436m436s436m436s436m436s436m436s436m436s436m436s1310" + "m436s436m436s436m436s436m436s436m436s436m436s436m436s436m436s436" + "m436s436m436s1310m436s1310m436s1310m436s1310m436s1310m436s436m436s436" + "m436s436m436s1310m436s1310m436s1310m436s1310m436s1310m436s436m436s1310" + "m436s74037", irsend.outputStr()); } @@ -315,12 +315,12 @@ TEST(TestSendPronto, NormalPlusRepeatSequence) { EXPECT_EQ(0x8, irsend.capture.command); EXPECT_EQ( "f38028d50" - "m8892s4446" - "m546s546m546s546m546s546m546s1664m546s1664m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s546m546s1664m546s1664m546s1664" - "m546s546m546s546m546s546m546s1664m546s546m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s1664m546s1664m546s1664m546s1664" - "m546s39858", + "m8994s4497" + "m552s552m552s552m552s552m552s1683m552s1683m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s552m552s1683m552s1683m552s1683" + "m552s552m552s552m552s552m552s1683m552s552m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s1683m552s1683m552s1683m552s1683" + "m552s40317", irsend.outputStr()); // Send it again with a single repeat. @@ -335,13 +335,13 @@ TEST(TestSendPronto, NormalPlusRepeatSequence) { EXPECT_EQ(0x8, irsend.capture.command); EXPECT_EQ( "f38028d50" - "m8892s4446" - "m546s546m546s546m546s546m546s1664m546s1664m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s546m546s1664m546s1664m546s1664" - "m546s546m546s546m546s546m546s1664m546s546m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s1664m546s1664m546s1664m546s1664" - "m546s39858" - "m8892s2210m546s95212", + "m8994s4497" + "m552s552m552s552m552s552m552s1683m552s1683m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s552m552s1683m552s1683m552s1683" + "m552s552m552s552m552s552m552s1683m552s552m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s1683m552s1683m552s1683m552s1683" + "m552s40317" + "m8994s2235m552s96310", irsend.outputStr()); // Send it again with a two repeats. @@ -356,14 +356,14 @@ TEST(TestSendPronto, NormalPlusRepeatSequence) { EXPECT_EQ(0x8, irsend.capture.command); EXPECT_EQ( "f38028d50" - "m8892s4446" - "m546s546m546s546m546s546m546s1664m546s1664m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s546m546s1664m546s1664m546s1664" - "m546s546m546s546m546s546m546s1664m546s546m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s1664m546s1664m546s1664m546s1664" - "m546s39858" - "m8892s2210m546s95212" - "m8892s2210m546s95212", + "m8994s4497" + "m552s552m552s552m552s552m552s1683m552s1683m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s552m552s1683m552s1683m552s1683" + "m552s552m552s552m552s552m552s1683m552s552m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s1683m552s1683m552s1683m552s1683" + "m552s40317" + "m8994s2235m552s96310" + "m8994s2235m552s96310", irsend.outputStr()); } @@ -391,3 +391,47 @@ TEST(TestSendPronto, Issue1034) { EXPECT_EQ(0xa3, irsend.capture.address); EXPECT_EQ(0x10, irsend.capture.command); } + +// Tests for #1103 +TEST(TestSendPronto, Issue1103) { + IRsendTest irsend(0); + IRrecv irrecv(0); + irsend.begin(); + // Based on raw data: + // uint16_t rawData[7] = {20100, 20472, 15092, 30704, 20102, 20472, 15086}; + // and output from `raw_to_pronto_code.py --hz 38000`: + // Pronto code = '0000 006D 0004 0000 02FB 0309 023D 048E 02FB 0309 023D 0ED8' + uint16_t pronto_test[12] = { + 0x0000, 0x006D, 0x0004, 0x0000, 0x02FB, 0x0309, 0x023D, 0x048E, + 0x02FB, 0x0309, 0x023D, 0x0ED8}; + irsend.reset(); + irsend.sendPronto(pronto_test, 12); + EXPECT_EQ( + "f38028d50m20066s20435m15069s30665m20066s20435m15069s99940", + irsend.outputStr()); + // Which pretty much matches the `rawData` above. + + // Shorter test. + // uint16_t rawData[4] = {20100, 20472, 15092, 30704}; + // and output from `raw_to_pronto_code.py --hz 38000`: + // Pronto code = '0000 006D 0002 0000 02FB 0309 023D 048E' + uint16_t pronto_test2[8] = { + 0x0000, 0x006D, 0x0002, 0x0000, 0x02FB, 0x0309, 0x023D, 0x048E}; + irsend.reset(); + irsend.sendPronto(pronto_test2, 8); + EXPECT_EQ( + "f38028d50m20066s20435m15069s30665", + irsend.outputStr()); + // Which pretty much matches the `rawData` above. + + // Ref: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1103#issuecomment-628946514 + uint16_t pronto_test_using_repeat[12] = { + 0x0000, 0x006D, 0x0000, 0x0004, 0x02fb, 0x0309, 0x023d, 0x048e, 0x02fb, + 0x0309, 0x023d, 0x0474}; + irsend.reset(); + irsend.sendPronto(pronto_test_using_repeat, 12); + EXPECT_EQ( + "f38028d50m20066s20435m15069s30665m20066s20435m15069s29982", + irsend.outputStr()); +} diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_RC5_RC6_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_RC5_RC6_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_RC5_RC6_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_RC5_RC6_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_RCMM_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_RCMM_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_RCMM_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_RCMM_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Samsung_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Samsung_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Samsung_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Samsung_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Sanyo_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Sanyo_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Sanyo_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Sanyo_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Sharp_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Sharp_test.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.6/test/ir_Sharp_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Sharp_test.cpp index 173c94f2a..c0c8bd5be 100644 --- a/lib/IRremoteESP8266-2.7.6/test/ir_Sharp_test.cpp +++ b/lib/IRremoteESP8266-2.7.7/test/ir_Sharp_test.cpp @@ -408,8 +408,8 @@ TEST(TestDecodeSharpAc, RealExample) { ASSERT_EQ(SHARP_AC, irsend.capture.decode_type); ASSERT_EQ(kSharpAcBits, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 27C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 27C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); @@ -448,23 +448,6 @@ TEST(TestIRUtils, SharpAc) { // Tests for IRSharpAc class. -TEST(TestSharpAcClass, Power) { - IRSharpAc ac(0); - ac.begin(); - - ac.on(); - EXPECT_TRUE(ac.getPower()); - - ac.off(); - EXPECT_FALSE(ac.getPower()); - - ac.setPower(true); - EXPECT_TRUE(ac.getPower()); - - ac.setPower(false); - EXPECT_FALSE(ac.getPower()); -} - TEST(TestSharpAcClass, Checksum) { uint8_t state[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCC, 0x31, 0x22, 0x00, 0x08, 0x80, 0x04, 0xE0, @@ -477,7 +460,7 @@ TEST(TestSharpAcClass, Checksum) { } TEST(TestSharpAcClass, Temperature) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); ac.setMode(kSharpAcCool); // Cool mode doesn't have temp restrictions. @@ -510,10 +493,20 @@ TEST(TestSharpAcClass, Temperature) { ac.setTemp(29); EXPECT_EQ(29, ac.getTemp()); + + // Auto & Dry have special temps. Per request, we should revert to the + // previous temp when we exit those modes. + + ac.setMode(kSharpAcAuto); + EXPECT_EQ(kSharpAcMinTemp, ac.getTemp()); + ac.setMode(kSharpAcDry); + EXPECT_EQ(kSharpAcMinTemp, ac.getTemp()); + ac.setMode(kSharpAcCool); + EXPECT_EQ(29, ac.getTemp()); } TEST(TestSharpAcClass, OperatingMode) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); ac.setTemp(25); @@ -547,7 +540,7 @@ TEST(TestSharpAcClass, OperatingMode) { TEST(TestSharpAcClass, FanSpeed) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); // Unexpected value should default to Auto. @@ -582,7 +575,7 @@ TEST(TestSharpAcClass, FanSpeed) { } TEST(TestSharpAcClass, ReconstructKnownState) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); uint8_t on_auto_auto[kSharpAcStateLength] = { @@ -593,8 +586,8 @@ TEST(TestSharpAcClass, ReconstructKnownState) { ac.setFan(kSharpAcFanAuto); ac.setMode(kSharpAcAuto); EXPECT_STATE_EQ(on_auto_auto, ac.getRaw(), kSharpAcBits); - EXPECT_EQ("Power: On, Previous Power: Off, Mode: 0 (Auto), Temp: 15C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_auto_28[kSharpAcStateLength] = { @@ -605,15 +598,15 @@ TEST(TestSharpAcClass, ReconstructKnownState) { ac.setMode(kSharpAcCool); ac.setFan(kSharpAcFanAuto); ac.setTemp(28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); EXPECT_STATE_EQ(cool_auto_28, ac.getRaw(), kSharpAcBits); } // https://github.com/crankyoldgit/IRremoteESP8266/issues/638#issue-421064165 TEST(TestSharpAcClass, KnownStates) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); uint8_t off_auto_auto[kSharpAcStateLength] = { @@ -621,65 +614,66 @@ TEST(TestSharpAcClass, KnownStates) { 0x31}; ASSERT_TRUE(ac.validChecksum(off_auto_auto)); ac.setRaw(off_auto_auto); - EXPECT_EQ("Power: Off, Previous Power: On, Mode: 0 (Auto), Temp: 15C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: Off, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t on_auto_auto[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x11, 0x20, 0x00, 0x08, 0x80, 0x00, 0xE0, 0x01}; ASSERT_TRUE(ac.validChecksum(on_auto_auto)); ac.setRaw(on_auto_auto); - EXPECT_EQ("Power: On, Previous Power: Off, Mode: 0 (Auto), Temp: 15C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_auto_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x22, 0x00, 0x08, 0x80, 0x04, 0xE0, 0x51}; ASSERT_TRUE(ac.validChecksum(cool_auto_28)); ac.setRaw(cool_auto_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_fan1_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x42, 0x00, 0x08, 0x80, 0x05, 0xE0, 0x21}; ASSERT_TRUE(ac.validChecksum(cool_fan1_28)); ac.setRaw(cool_fan1_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 4 (Low)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 4 (Low), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_fan2_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x32, 0x00, 0x08, 0x80, 0x05, 0xE0, 0x51}; ASSERT_TRUE(ac.validChecksum(cool_fan2_28)); ac.setRaw(cool_fan2_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 3 (Medium)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), " + "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_fan3_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x52, 0x00, 0x08, 0x80, 0x05, 0xE0, 0x31}; ASSERT_TRUE(ac.validChecksum(cool_fan3_28)); ac.setRaw(cool_fan3_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 5 (UNKNOWN)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 5 (UNKNOWN), " + "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_fan4_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x72, 0x00, 0x08, 0x80, 0x05, 0xE0, 0x11}; ASSERT_TRUE(ac.validChecksum(cool_fan4_28)); ac.setRaw(cool_fan4_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 7 (High)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); - /* Unsupported / Not yet reverse engineered. uint8_t cool_fan4_28_ion_on[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x61, 0x72, 0x08, 0x08, 0x80, 0x00, 0xE4, 0xD1}; ASSERT_TRUE(ac.validChecksum(cool_fan4_28_ion_on)); ac.setRaw(cool_fan4_28_ion_on); - EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 7 (Max)", + EXPECT_EQ("Power: -, Mode: 2 (Cool), Temp: 28C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off", ac.toString()); + /* Unsupported / Not yet reverse engineered. uint8_t cool_fan4_28_eco1[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x61, 0x72, 0x18, 0x08, 0x80, 0x00, 0xE8, 0x01}; @@ -692,13 +686,13 @@ TEST(TestSharpAcClass, KnownStates) { 0x11}; ASSERT_TRUE(ac.validChecksum(dry_auto)); ac.setRaw(dry_auto); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 3 (Dry), Temp: 15C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); } TEST(TestSharpAcClass, toCommon) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.setPower(true); ac.setMode(kSharpAcCool); ac.setTemp(20); @@ -725,32 +719,20 @@ TEST(TestSharpAcClass, toCommon) { ASSERT_EQ(-1, ac.toCommon().clock); } -TEST(TestSharpAcClass, PreviousPower) { +TEST(TestSharpAcClass, Power) { IRSharpAc ac(kGpioUnused); ac.setPower(false, false); EXPECT_FALSE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); ac.setPower(true); EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); ac.setPower(false); EXPECT_FALSE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); - ac.setPower(true); + ac.on(); EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); - ac.setPower(true); - EXPECT_TRUE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); - ac.setPreviousPower(false); - EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); - ac.setPreviousPower(true); - EXPECT_TRUE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); + ac.off(); + EXPECT_FALSE(ac.getPower()); ac.setPower(true, false); EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); // Data from: https://github.com/crankyoldgit/IRremoteESP8266/pull/1074#discussion_r403407146 // Command ON (previously OFF) -> 0xAA 5A CF 10 CB 11 22 00 08 80 00 E0 51 @@ -759,21 +741,18 @@ TEST(TestSharpAcClass, PreviousPower) { 0x00, 0x08, 0x80, 0x00, 0xE0, 0x51}; ac.setRaw(on_prev_off); EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); // Command ON (previously ON) -> 0xAA 5A CF 10 CB 31 22 00 08 80 04 E0 31 const uint8_t on_prev_on[] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCB, 0x31, 0x22, 0x00, 0x08, 0x80, 0x04, 0xE0, 0x31}; ac.setRaw(on_prev_on); EXPECT_TRUE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); // Command OFF (previously ON) -> 0xAA 5A CF 10 CB 21 22 00 08 80 00 E0 61 const uint8_t off_prev_on[] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCB, 0x21, 0x22, 0x00, 0x08, 0x80, 0x00, 0xE0, 0x61}; ac.setRaw(off_prev_on); EXPECT_FALSE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); /* Extra test data if needed. // Power:OFF Mode:2(Cool) Fan:2(Auto) Temp:22 const uint8_t collect1[13] = { @@ -810,3 +789,279 @@ TEST(TestSharpAcClass, PreviousPower) { 0x00, 0x08, 0x80, 0x00, 0xE0, 0xB1}; */ } + +TEST(TestSharpAcClass, Turbo) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + ac.setFan(kSharpAcFanMin); + ac.setTurbo(false); + EXPECT_FALSE(ac.getTurbo()); + EXPECT_EQ(kSharpAcFanMin, ac.getFan()); + + ac.setTurbo(true); + EXPECT_TRUE(ac.getTurbo()); + EXPECT_EQ(kSharpAcFanMax, ac.getFan()); + + ac.setTurbo(false); + EXPECT_FALSE(ac.getTurbo()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=0&range=D25 + const uint8_t on_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC6, 0x61, 0x72, + 0x00, 0x08, 0x80, 0x01, 0xF4, 0xE1}; + const uint8_t off_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC6, 0x71, 0x72, + 0x00, 0x08, 0x80, 0x01, 0xF4, 0xF1}; + ac.setRaw(on_state); + EXPECT_TRUE(ac.getTurbo()); + EXPECT_EQ(kSharpAcFanMax, ac.getFan()); + EXPECT_EQ( + "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: On, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off", + ac.toString()); + + ac.setRaw(off_state); + EXPECT_FALSE(ac.getTurbo()); + EXPECT_EQ( + "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off", + ac.toString()); +} + +TEST(TestSharpAcClass, SwingToggle) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + ac.setSwingToggle(false); + EXPECT_FALSE(ac.getSwingToggle()); + + ac.setSwingToggle(true); + EXPECT_TRUE(ac.getSwingToggle()); + + ac.setSwingToggle(false); + EXPECT_FALSE(ac.getSwingToggle()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=1057982086&range=C13:E14 + const uint8_t on_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xCA, 0x31, 0x22, + 0x00, 0x0F, 0x80, 0x06, 0xF4, 0x21}; + const uint8_t off_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC9, 0x31, 0x22, + 0x00, 0x08, 0x80, 0x04, 0xF4, 0x41}; + ac.setRaw(on_state); + EXPECT_TRUE(ac.getSwingToggle()); + + ac.setRaw(off_state); + EXPECT_FALSE(ac.getSwingToggle()); +} + +TEST(TestSharpAcClass, Ion) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + ac.setIon(false); + EXPECT_FALSE(ac.getIon()); + + ac.setIon(true); + EXPECT_TRUE(ac.getIon()); + + ac.setIon(false); + EXPECT_FALSE(ac.getIon()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=1057982086&range=B23:E31 + const uint8_t on_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xCA, 0x61, 0x22, + 0x08, 0x08, 0x80, 0x00, 0xF4, 0xE1}; + const uint8_t off_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xCA, 0x71, 0x22, + 0x08, 0x08, 0x80, 0x00, 0xF0, 0xB1}; + ac.setRaw(on_state); + EXPECT_TRUE(ac.getIon()); + ac.setRaw(off_state); + EXPECT_FALSE(ac.getIon()); +} + +TEST(TestSharpAcClass, Timers) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + // Off cases + ac.setTimer(false, kSharpAcOffTimerType, 0); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + ac.setTimer(false, kSharpAcOnTimerType, 0); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + ac.setTimer(true, kSharpAcOnTimerType, 0); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + ac.setTimer(false, kSharpAcOffTimerType, 12 * 60); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + ac.setTimer(true, kSharpAcOnTimerType, kSharpAcTimerIncrement - 1); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + // Trivial cases + ac.setTimer(true, kSharpAcOnTimerType, 30); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(30, ac.getTimerTime()); + EXPECT_TRUE(ac.isPowerSpecial()); + + ac.setTimer(true, kSharpAcOffTimerType, 60); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(60, ac.getTimerTime()); + + ac.setTimer(true, kSharpAcOnTimerType, 91); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(90, ac.getTimerTime()); + + // Bounds checks + ac.setTimer(true, kSharpAcOnTimerType, kSharpAcTimerHoursMax * 60); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(kSharpAcTimerHoursMax * 60, ac.getTimerTime()); + + ac.setTimer(false, kSharpAcOffTimerType, 0); // Known good. + ac.setTimer(true, kSharpAcOnTimerType, kSharpAcTimerHoursMax * 60 + + kSharpAcTimerIncrement); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(kSharpAcTimerHoursMax * 60, ac.getTimerTime()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=0&range=E51 + const uint8_t off_timer_8_5_hrs[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC6, 0x81, 0x72, + 0x88, 0x08, 0x80, 0xDE, 0xF4, 0x21}; + ac.setRaw(off_timer_8_5_hrs); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(8 * 60 + 30, ac.getTimerTime()); + EXPECT_TRUE(ac.isPowerSpecial()); + EXPECT_EQ( + "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off, Off Timer: 08:30", + ac.toString()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=0&range=E80 + const uint8_t on_timer_12_hrs[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC6, 0x81, 0x72, + 0xCC, 0x08, 0x80, 0xC0, 0xF4, 0xD1}; + ac.setRaw(on_timer_12_hrs); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(12 * 60, ac.getTimerTime()); + EXPECT_TRUE(ac.isPowerSpecial()); + EXPECT_EQ( + "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off, On Timer: 12:00", + ac.toString()); +} + +TEST(TestSharpAcClass, Clean) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + ac.setMode(kSharpAcCool); + ac.setTemp(25); + ASSERT_NE(kSharpAcDry, ac.getMode()); + ASSERT_NE(kSharpAcMinTemp, ac.getTemp()); + ASSERT_NE(kSharpAcFanAuto, ac.getFan()); + + ac.setClean(false); + EXPECT_FALSE(ac.getClean()); + + ac.setClean(true); + EXPECT_TRUE(ac.getClean()); + ASSERT_EQ(kSharpAcDry, ac.getMode()); + ASSERT_EQ(kSharpAcMinTemp, ac.getTemp()); + ASSERT_EQ(kSharpAcFanAuto, ac.getFan()); + + ac.setClean(false); + EXPECT_FALSE(ac.getClean()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=1057982086&range=B82:D85 + const uint8_t clean_on_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x11, 0x2B, + 0x00, 0x08, 0x80, 0x00, 0xF0, 0xA1}; + const uint8_t clean_off_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xCA, 0x11, 0x72, + 0x00, 0x08, 0x80, 0x00, 0xF0, 0x01}; + ac.setRaw(clean_on_state); + EXPECT_TRUE(ac.getClean()); + EXPECT_EQ( + "Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: On", + ac.toString()); + ac.setRaw(clean_off_state); + EXPECT_FALSE(ac.getClean()); + EXPECT_EQ( + "Power: On, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); + + // Try constructing the clean on state. + ac.setClean(true); + EXPECT_STATE_EQ(clean_on_state, ac.getRaw(), kSharpAcBits); + + // Try to replicate the exact sequence of commands to activate clean mode + // and compare it to captured values from the real remote. + // Ref: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1091#issuecomment-622378747 + ac.stateReset(); + // AC OFF (Mode Cool, Temp 25, Ion OFF, Fan 7) + ac.setMode(kSharpAcCool); + ac.setIon(false); + ac.setTemp(25); + ac.setFan(7); + ac.setPower(false); + EXPECT_EQ( + "Power: Off, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); + // Clean ON + ac.setClean(true); + EXPECT_EQ( + "Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: On", + ac.toString()); + // Clean OFF (state is identical to `off_msg`). + // i.e. It just clears the clean settings & turns off the device. + ac.setClean(false); + ac.setPower(false, true); + EXPECT_EQ( + "Power: Off, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); + // Clean ON + ac.setClean(true); + EXPECT_EQ( + "Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: On", + ac.toString()); + // AC OFF + ac.off(); + EXPECT_EQ( + "Power: Off, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); + // AC ON (Mode Cool, Temp 25, Ion OFF, Fan 7) + ac.on(); + EXPECT_EQ( + "Power: On, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); +} diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Sherwood_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Sherwood_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Sherwood_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Sherwood_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Sony_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Sony_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Sony_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Sony_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Symphony_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Symphony_test.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.6/test/ir_Symphony_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Symphony_test.cpp index ee4aadfda..e3f818136 100644 --- a/lib/IRremoteESP8266-2.7.6/test/ir_Symphony_test.cpp +++ b/lib/IRremoteESP8266-2.7.7/test/ir_Symphony_test.cpp @@ -13,15 +13,21 @@ TEST(TestSendSymphony, SendDataOnly) { IRsendTest irsend(kGpioUnused); irsend.begin(); - irsend.sendSymphony(0x137); + irsend.sendSymphony(0xD90); EXPECT_EQ( "f38000d50" "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400" "m400s1250m400s1250m400s1250" - "m400s8000" + "m400s7850" "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400" "m400s1250m400s1250m400s1250" - "m400s8000", + "m400s7850" + "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400" + "m400s1250m400s1250m400s1250" + "m400s7850" + "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400" + "m400s1250m400s1250m400s1250" + "m400s7850", irsend.outputStr()); } @@ -69,7 +75,7 @@ TEST(TestDecodeSymphony, RealMessageDecode) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x137, irsend.capture.value); + EXPECT_EQ(0xD90, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); @@ -81,10 +87,10 @@ TEST(TestDecodeSymphony, RealMessageDecode) { 1198, 1284, 396, 444, 1224, 470, 1200, 470, 1198, 472}; irsend.sendRaw(power, 23, 38000); irsend.makeDecodeResult(); - EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_TRUE(irrecv.decodeSymphony(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x137, irsend.capture.value); + EXPECT_EQ(0xD90, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); @@ -98,7 +104,7 @@ TEST(TestDecodeSymphony, RealMessageDecode) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x13E, irsend.capture.value); + EXPECT_EQ(0xD82, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); @@ -122,7 +128,7 @@ TEST(TestDecodeSymphony, RealMessageSentViaLibrary) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x137, irsend.capture.value); + EXPECT_EQ(0xD90, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); @@ -139,12 +145,47 @@ TEST(TestDecodeSymphony, RealMessageSentViaLibrary) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x137, irsend.capture.value); + EXPECT_EQ(0xD90, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); } +// Decode a real SM5021 generated message. +// Note: This used to fail because it had a "long" mark before the gap in mesg. +TEST(TestDecodeSymphony, Issue1105) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1105#issuecomment-625327833 + irsend.reset(); + uint16_t rawData[191] = { + 1324, 372, 1322, 398, 448, 1218, 476, 1216, 478, 1216, 478, 1218, 478, + 1218, 476, 1218, 476, 1220, 474, 1220, 474, 1220, 1346, 7128, 1320, 402, + 1290, 404, 440, 1252, 442, 1254, 440, 1254, 440, 1254, 440, 1254, 440, + 1254, 440, 1254, 442, 1254, 440, 1254, 1288, 7186, 1288, 408, 1286, 408, + 438, 1254, 440, 1254, 440, 1254, 440, 1254, 440, 1254, 440, 1256, 440, + 1254, 440, 1254, 440, 1254, 1288, 7186, 1288, 408, 1286, 408, 438, 1254, + 440, 1256, 440, 1254, 440, 1254, 440, 1254, 440, 1254, 438, 1256, 438, + 1256, 440, 1254, 1288, 7188, 1288, 408, 1286, 408, 438, 1256, 438, 1256, + 440, 1254, 438, 1256, 438, 1256, 438, 1256, 438, 1256, 438, 1256, 440, + 1254, 1288, 7188, 1286, 408, 1286, 408, 440, 1254, 438, 1256, 438, 1256, + 438, 1256, 440, 1254, 438, 1254, 440, 1256, 438, 1256, 440, 1256, 438, + 8038, 1284, 408, 1286, 408, 438, 1282, 412, 1282, 414, 1280, 414, 1280, + 414, 1282, 414, 1280, 412, 1276, 412, 1286, 414, 1282, 412, 8062, 1260, + 434, 1262, 432, 414, 1280, 414, 1282, 412, 1282, 412, 1282, 412, 1282, + 414, 1280, 414, 1282, 412, 1282, 412, 1282, 412}; // UNKNOWN 827AA7B + irsend.sendRaw(rawData, 191, 38000); + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); + EXPECT_EQ(kSymphonyBits, irsend.capture.bits); + EXPECT_EQ(0xC01, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_FALSE(irsend.capture.repeat); +} TEST(TestUtils, Housekeeping) { ASSERT_EQ("SYMPHONY", typeToString(decode_type_t::SYMPHONY)); diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Tcl_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Tcl_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Tcl_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Tcl_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Teco_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Teco_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Teco_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Teco_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Toshiba_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Toshiba_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Toshiba_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Toshiba_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Trotec_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Trotec_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Trotec_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Trotec_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Vestel_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Vestel_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Vestel_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Vestel_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Whirlpool_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Whirlpool_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Whirlpool_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Whirlpool_test.cpp diff --git a/lib/IRremoteESP8266-2.7.6/test/ir_Whynter_test.cpp b/lib/IRremoteESP8266-2.7.7/test/ir_Whynter_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/test/ir_Whynter_test.cpp rename to lib/IRremoteESP8266-2.7.7/test/ir_Whynter_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/tools/Makefile b/lib/IRremoteESP8266-2.7.7/tools/Makefile new file mode 100644 index 000000000..b30d1207c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/tools/Makefile @@ -0,0 +1,88 @@ +# SYNOPSIS: +# +# make [all] - makes everything. +# make clean - removes all files generated by make. + +# Please tweak the following variable definitions as needed by your +# project, except GTEST_HEADERS, which you can use in your own targets +# but shouldn't modify. + + +# Where to find user code. +USER_DIR = ../src + +# Where to find test code. +TEST_DIR = ../test + +INCLUDES = -I$(USER_DIR) -I$(TEST_DIR) +# Flags passed to the preprocessor. +# Set Google Test's header directory as a system directory, such that +# the compiler doesn't generate warnings in Google Test headers. +CPPFLAGS += -DUNIT_TEST -D_IR_LOCALE_=en-AU + +# Flags passed to the C++ compiler. +CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 + +all : gc_decode mode2_decode + +run_tests : all + failed=""; \ + for py_unittest in *_test.py; do \ + echo "RUNNING: $${py_unittest}"; \ + python3 ./$${py_unittest} || failed="$${failed} $${py_unittest}"; \ + done; \ + if [ -n "$${failed}" ]; then \ + echo "FAIL: :-( :-( Unit test(s)$${failed} failed! :-( :-("; exit 1; \ + else \ + echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \ + fi + +clean : + rm -f *.o *.pyc gc_decode mode2_decode + + +# Keep all intermediate files. +.SECONDARY: + +# All the IR protocol object files. +PROTOCOL_OBJS = $(patsubst %.cpp,%.o,$(wildcard $(USER_DIR)/ir_*.cpp)) +PROTOCOLS = $(patsubst $(USER_DIR)/%,%,$(PROTOCOL_OBJS)) + +# Common object files +COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o IRtext.o IRac.o $(PROTOCOLS) + +# Common dependencies +COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \ + $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \ + $(TEST_DIR)/IRsend_test.h $(USER_DIR)/IRtext.h $(USER_DIR)/i18n.h +# Common test dependencies +COMMON_TEST_DEPS = $(COMMON_DEPS) $(TEST_DIR)/IRsend_test.h + +IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/locale/*.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRtext.cpp + +IRutils.o : $(USER_DIR)/IRutils.cpp $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRutils.cpp + +IRsend.o : $(USER_DIR)/IRsend.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRremoteESP8266.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRsend.cpp + +IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRrecv.cpp + +# new specific targets goes above this line + +%_decode : $(COMMON_OBJ) %_decode.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ + +ir_%.o : $(USER_DIR)/ir_%.h $(USER_DIR)/ir_%.cpp $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp + +ir_%.o : $(USER_DIR)/ir_%.cpp $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp + +%.o : %.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $*.cpp + +%.o : $(USER_DIR)/%.cpp $(USER_DIR)/%.h $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/$*.cpp diff --git a/lib/IRremoteESP8266-2.7.6/tools/RawToGlobalCache.sh b/lib/IRremoteESP8266-2.7.7/tools/RawToGlobalCache.sh similarity index 100% rename from lib/IRremoteESP8266-2.7.6/tools/RawToGlobalCache.sh rename to lib/IRremoteESP8266-2.7.7/tools/RawToGlobalCache.sh diff --git a/lib/IRremoteESP8266-2.7.6/tools/auto_analyse_raw_data.py b/lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data.py similarity index 89% rename from lib/IRremoteESP8266-2.7.6/tools/auto_analyse_raw_data.py rename to lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data.py index 5bea3926a..4dc4cb698 100755 --- a/lib/IRremoteESP8266-2.7.6/tools/auto_analyse_raw_data.py +++ b/lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data.py @@ -403,49 +403,71 @@ def decode_data(message, defines, code, name="", output=sys.stdout): code["send"].extend([ "#if SEND_%s" % def_name.upper(), - "// Function should be safe up to 64 bits.", + "/// Send a %s formatted message." % name, + "/// Function should be safe up to 64 bits.", + "/// Status: ALPHA / Untested.", + "/// @param[in] data containing the IR command.", + "/// @param[in] nbits Nr. of bits to send. usually k%sBits" % name, + "/// @param[in] repeat Nr. of times the message is to be repeated.", "void IRsend::send%s(const uint64_t data, const uint16_t" " nbits, const uint16_t repeat) {" % def_name, " enableIROut(k%sFreq);" % name, " for (uint16_t r = 0; r <= repeat; r++) {", " uint64_t send_data = data;"]) code["send64+"].extend([ - "// Args:", - "// data: An array of bytes containing the IR command.", - "// It is assumed to be in MSB order for this code.\n" - "// nbytes: Nr. of bytes of data in the array." + "/// @param[in] data An array of bytes containing the IR command.", + "/// It is assumed to be in MSB order for this code.", + "/// @param[in] nbytes Nr. of bytes of data in the array." " (>=k%sStateLength)" % name, - "// repeat: Nr. of times the message is to be repeated.", - "//", - "// Status: ALPHA / Untested.", + "/// @param[in] repeat Nr. of times the message is to be repeated.", "void IRsend::send%s(const uint8_t data[], const uint16_t nbytes," " const uint16_t repeat) {" % def_name, " for (uint16_t r = 0; r <= repeat; r++) {", " uint16_t pos = 0;"]) code["recv"].extend([ "#if DECODE_%s" % def_name.upper(), - "// Function should be safe up to 64 bits.", - "bool IRrecv::decode%s(decode_results *results, const uint16_t nbits," - " const bool strict) {" % def_name, - " if (results->rawlen < 2 * nbits + k%sOverhead)" % name, + "/// Decode the supplied %s message." % name, + "/// Function should be safe up to 64 bits.", + "/// Status: ALPHA / Untested.", + "/// @param[in,out] results Ptr to the data to decode &" + " where to store the decode", + "/// @param[in] offset The starting index to use when" + " attempting to decode the", + "/// raw data. Typically/Defaults to kStartOffset.", + "/// @param[in] nbits The number of data bits to expect.", + "/// @param[in] strict Flag indicating if we should perform strict" + " matching.", + "/// @return A boolean. True if it can decode it, false if it can't.", + "bool IRrecv::decode%s(decode_results *results, uint16_t offset," + " const uint16_t nbits, const bool strict) {" % def_name, + " if (results->rawlen < 2 * nbits + k%sOverhead - offset)" % name, " return false; // Too short a message to match.", " if (strict && nbits != k%sBits)" % name, " return false;", "", - " uint16_t offset = kStartOffset;", " uint64_t data = 0;", " match_result_t data_result;"]) code["recv64+"].extend([ "#if DECODE_%s" % def_name.upper(), - "// Function should be safe over 64 bits.", - "bool IRrecv::decode%s(decode_results *results, const uint16_t nbits," - " const bool strict) {" % def_name, - " if (results->rawlen < 2 * nbits + k%sOverhead)" % name, + "/// Decode the supplied %s message." % name, + "/// Function should be safe over 64 bits.", + "/// Status: ALPHA / Untested.", + "/// @param[in,out] results Ptr to the data to decode &" + " where to store the decode", + "/// @param[in] offset The starting index to use when" + " attempting to decode the", + "/// raw data. Typically/Defaults to kStartOffset.", + "/// @param[in] nbits The number of data bits to expect.", + "/// @param[in] strict Flag indicating if we should perform" + " strict matching.", + "/// @return A boolean. True if it can decode it, false if it can't.", + "bool IRrecv::decode%s(decode_results *results, uint16_t offset," + " const uint16_t nbits, const bool strict) {" % def_name, + " if (results->rawlen < 2 * nbits + k%sOverhead - offset)" % name, " return false; // Too short a message to match.", " if (strict && nbits != k%sBits)" % name, " return false;", "", - " uint16_t offset = kStartOffset;", " uint16_t pos = 0;", " uint16_t used = 0;"]) @@ -630,7 +652,7 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout): else: def_name = "TBD" output.write("\nGenerating a VERY rough code outline:\n\n" - "// Copyright 2019 David Conran (crankyoldgit)\n" + "// Copyright 2020 David Conran (crankyoldgit)\n" "// Support for %s protocol\n\n" '#include "IRrecv.h"\n' '#include "IRsend.h"\n' @@ -656,12 +678,15 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout): code["send64+"] = [ "", "#if SEND_%s" % def_name.upper(), - "// Alternative >64bit function to send %s messages" % def_name.upper(), - "// Where data is:", - "// uint8_t data[k%sStateLength] = {0x%s};" % ( + "/// Send a %s formatted message." % name, + "/// Alternative >64bit function to send %s messages" % + def_name.upper(), + "/// Status: ALPHA / Untested.", + "/// Where data is:", + "/// uint8_t data[k%sStateLength] = {0x%s};" % ( name, ", 0x".join("%02X" % int(bits_str[i:i + 8], 2) for i in range(0, len(bits_str), 8))), - "//"] + code["send64+"] + "///"] + code["send64+"] for line in code["send64+"]: output.write("%s\n" % line) output.write("\n") @@ -681,6 +706,34 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout): for line in code["recv64+"]: output.write("%s\n" % line) +def add_rawdata_args(parser): + """Add the arguments for feeding in the rawdata string(s).""" + arg_group = parser.add_mutually_exclusive_group(required=True) + arg_group.add_argument( + "rawdata", + help="A rawData line from IRrecvDumpV2. e.g. 'uint16_t rawbuf[37] = {" + "7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494, " + "520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, " + "494, 520, 520, 520, 494, 520, 494, 520, 494, 520, 494};'", + nargs="?") + arg_group.add_argument( + "-f", "--file", help="Read in a rawData line from the file.") + arg_group.add_argument( + "--stdin", + help="Read in a rawData line from STDIN.", + action="store_true", + default=False) + +def get_rawdata(arg_options): + """Return the rawdata string(s) as per the options.""" + if arg_options.stdin: + return sys.stdin.read() + if arg_options.file: + with open(arg_options.file) as input_file: + return input_file.read() + else: + return arg_options.rawdata + def main(): """Parse the commandline arguments and call the method.""" @@ -701,16 +754,6 @@ def main(): help="Name of the protocol/device to use in code generation. E.g. Onkyo", dest="name", default="") - arg_group = arg_parser.add_mutually_exclusive_group(required=True) - arg_group.add_argument( - "rawdata", - help="A rawData line from IRrecvDumpV2. e.g. 'uint16_t rawbuf[37] = {" - "7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494, " - "520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, " - "494, 520, 520, 520, 494, 520, 494, 520, 494, 520, 494};'", - nargs="?") - arg_group.add_argument( - "-f", "--file", help="Read in a rawData line from the file.") arg_parser.add_argument( "-r", "--range", @@ -719,22 +762,11 @@ def main(): " it the same value.", dest="margin", default=200) - arg_group.add_argument( - "--stdin", - help="Read in a rawData line from STDIN.", - action="store_true", - default=False) + add_rawdata_args(arg_parser) arg_options = arg_parser.parse_args() - if arg_options.stdin: - data = sys.stdin.read() - elif arg_options.file: - with open(arg_options.file) as input_file: - data = input_file.read() - else: - data = arg_options.rawdata - parse_and_report(data, arg_options.margin, arg_options.gen_code, - arg_options.name) + parse_and_report(get_rawdata(arg_options), arg_options.margin, + arg_options.gen_code, arg_options.name) if __name__ == '__main__': diff --git a/lib/IRremoteESP8266-2.7.6/tools/auto_analyse_raw_data_test.py b/lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data_test.py similarity index 86% rename from lib/IRremoteESP8266-2.7.6/tools/auto_analyse_raw_data_test.py rename to lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data_test.py index fa3a87933..1f90c4661 100755 --- a/lib/IRremoteESP8266-2.7.6/tools/auto_analyse_raw_data_test.py +++ b/lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data_test.py @@ -279,7 +279,7 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' 'Generating a VERY rough code outline:\n' '\n' - '// Copyright 2019 David Conran (crankyoldgit)\n' + '// Copyright 2020 David Conran (crankyoldgit)\n' '// Support for FOO protocol\n' '\n' '#include "IRrecv.h"\n' @@ -301,7 +301,12 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'const uint16_t kFOOBits = 16; // Move to IRremoteESP8266.h\n' 'const uint16_t kFOOOverhead = 5;\n' '#if SEND_FOO\n' - '// Function should be safe up to 64 bits.\n' + '/// Send a FOO formatted message.\n' + '/// Function should be safe up to 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data containing the IR command.\n' + '/// @param[in] nbits Nr. of bits to send. usually kFOOBits\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendFOO(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(kFOOFreq);\n' @@ -332,15 +337,25 @@ class TestAutoAnalyseRawData(unittest.TestCase): '#endif // SEND_FOO\n' '\n' '#if DECODE_FOO\n' - '// Function should be safe up to 64 bits.\n' - 'bool IRrecv::decodeFOO(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kFOOOverhead)\n' + '/// Decode the supplied FOO message.\n' + '/// Function should be safe up to 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeFOO(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kFOOOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kFOOBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' @@ -540,7 +555,7 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' 'Generating a VERY rough code outline:\n' '\n' - '// Copyright 2019 David Conran (crankyoldgit)\n' + '// Copyright 2020 David Conran (crankyoldgit)\n' '// Support for Hitachi protocol\n' '\n' '#include "IRrecv.h"\n' @@ -568,7 +583,12 @@ class TestAutoAnalyseRawData(unittest.TestCase): "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '#if SEND_HITACHI\n' - '// Function should be safe up to 64 bits.\n' + '/// Send a Hitachi formatted message.\n' + '/// Function should be safe up to 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data containing the IR command.\n' + '/// @param[in] nbits Nr. of bits to send. usually kHitachiBits\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendHitachi(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(kHitachiFreq);\n' @@ -597,23 +617,22 @@ class TestAutoAnalyseRawData(unittest.TestCase): '#endif // SEND_HITACHI\n' '\n' '#if SEND_HITACHI\n' - '// Alternative >64bit function to send HITACHI messages\n' - '// Where data is:\n' - '// uint8_t data[kHitachiStateLength] = {0x80, 0x08, 0x00, 0x02,' + '/// Send a Hitachi formatted message.\n' + '/// Alternative >64bit function to send HITACHI messages\n' + '/// Status: ALPHA / Untested.\n' + '/// Where data is:\n' + '/// uint8_t data[kHitachiStateLength] = {0x80, 0x08, 0x00, 0x02,' ' 0xFD, 0xFF, 0x00, 0x33, 0xCC, 0x49, 0xB6, 0xC8, 0x37, 0x3A, 0xC5,' ' 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xCA,' ' 0x35, 0x8F, 0x70, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0xFE, 0xC0, 0x3F,' ' 0x80, 0x7F, 0x11, 0xEE, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,' ' 0x00, 0xFF, 0x00, 0xFF, 0x00};\n' - '//\n' - '// Args:\n' - '// data: An array of bytes containing the IR command.\n' - '// It is assumed to be in MSB order for this code.\n' - '// nbytes: Nr. of bytes of data in the array.' + '///\n' + '/// @param[in] data An array of bytes containing the IR command.\n' + '/// It is assumed to be in MSB order for this code.\n' + '/// @param[in] nbytes Nr. of bytes of data in the array.' ' (>=kHitachiStateLength)\n' - '// repeat: Nr. of times the message is to be repeated.\n' - '//\n' - '// Status: ALPHA / Untested.\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendHitachi(const uint8_t data[], const uint16_t nbytes,' ' const uint16_t repeat) {\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' @@ -641,15 +660,25 @@ class TestAutoAnalyseRawData(unittest.TestCase): "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '#if DECODE_HITACHI\n' - '// Function should be safe up to 64 bits.\n' - 'bool IRrecv::decodeHitachi(decode_results *results,' + '/// Decode the supplied Hitachi message.\n' + '/// Function should be safe up to 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeHitachi(decode_results *results, uint16_t offset,' ' const uint16_t nbits, const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kHitachiOverhead)\n' + ' if (results->rawlen < 2 * nbits + kHitachiOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kHitachiBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' @@ -695,15 +724,25 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' '// Note: This should be 64+ bit safe.\n' '#if DECODE_HITACHI\n' - '// Function should be safe over 64 bits.\n' - 'bool IRrecv::decodeHitachi(decode_results *results,' + '/// Decode the supplied Hitachi message.\n' + '/// Function should be safe over 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeHitachi(decode_results *results, uint16_t offset,' ' const uint16_t nbits, const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kHitachiOverhead)\n' + ' if (results->rawlen < 2 * nbits + kHitachiOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kHitachiBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint16_t pos = 0;\n' ' uint16_t used = 0;\n' '\n' @@ -824,7 +863,7 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' 'Generating a VERY rough code outline:\n' '\n' - '// Copyright 2019 David Conran (crankyoldgit)\n' + '// Copyright 2020 David Conran (crankyoldgit)\n' '// Support for FOO protocol\n' '\n' '#include "IRrecv.h"\n' @@ -850,7 +889,12 @@ class TestAutoAnalyseRawData(unittest.TestCase): "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '#if SEND_FOO\n' - '// Function should be safe up to 64 bits.\n' + '/// Send a FOO formatted message.\n' + '/// Function should be safe up to 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data containing the IR command.\n' + '/// @param[in] nbits Nr. of bits to send. usually kFOOBits\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendFOO(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(kFOOFreq);\n' @@ -907,18 +951,18 @@ class TestAutoAnalyseRawData(unittest.TestCase): '#endif // SEND_FOO\n' '\n' '#if SEND_FOO\n' - '// Alternative >64bit function to send FOO messages\n' - '// Where data is:\n' - '// uint8_t data[kFOOStateLength] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,' + '/// Send a FOO formatted message.\n' + '/// Alternative >64bit function to send FOO messages\n' + '/// Status: ALPHA / Untested.\n' + '/// Where data is:\n' + '/// uint8_t data[kFOOStateLength] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,' ' 0x5F, 0x40, 0x40, 0x2F, 0x2F, 0x6C, 0x6C, 0x2F, 0x2F, 0x6C, 0x6C};\n' - '//\n' - '// Args:\n' - '// data: An array of bytes containing the IR command.\n' - '// It is assumed to be in MSB order for this code.\n' - '// nbytes: Nr. of bytes of data in the array. (>=kFOOStateLength)\n' - '// repeat: Nr. of times the message is to be repeated.\n' - '//\n' - '// Status: ALPHA / Untested.\n' + '///\n' + '/// @param[in] data An array of bytes containing the IR command.\n' + '/// It is assumed to be in MSB order for this code.\n' + '/// @param[in] nbytes Nr. of bytes of data in the array.' + ' (>=kFOOStateLength)\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendFOO(const uint8_t data[], const uint16_t nbytes,' ' const uint16_t repeat) {\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' @@ -974,15 +1018,25 @@ class TestAutoAnalyseRawData(unittest.TestCase): "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't " 'work!\n' '#if DECODE_FOO\n' - '// Function should be safe up to 64 bits.\n' - 'bool IRrecv::decodeFOO(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kFOOOverhead)\n' + '/// Decode the supplied FOO message.\n' + '/// Function should be safe up to 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeFOO(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kFOOOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kFOOBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' @@ -1086,15 +1140,25 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' '// Note: This should be 64+ bit safe.\n' '#if DECODE_FOO\n' - '// Function should be safe over 64 bits.\n' - 'bool IRrecv::decodeFOO(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kFOOOverhead)\n' + '/// Decode the supplied FOO message.\n' + '/// Function should be safe over 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeFOO(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kFOOOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kFOOBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint16_t pos = 0;\n' ' uint16_t used = 0;\n' '\n' @@ -1229,7 +1293,7 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' 'Generating a VERY rough code outline:\n' '\n' - '// Copyright 2019 David Conran (crankyoldgit)\n' + '// Copyright 2020 David Conran (crankyoldgit)\n' '// Support for TBD protocol\n' '\n' '#include "IRrecv.h"\n' @@ -1254,7 +1318,12 @@ class TestAutoAnalyseRawData(unittest.TestCase): "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '#if SEND_TBD\n' - '// Function should be safe up to 64 bits.\n' + '/// Send a formatted message.\n' + '/// Function should be safe up to 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data containing the IR command.\n' + '/// @param[in] nbits Nr. of bits to send. usually kBits\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendTBD(const uint64_t data, const uint16_t nbits, const' ' uint16_t repeat) {\n' ' enableIROut(kFreq);\n' @@ -1274,18 +1343,18 @@ class TestAutoAnalyseRawData(unittest.TestCase): '#endif // SEND_TBD\n' '\n' '#if SEND_TBD\n' - '// Alternative >64bit function to send TBD messages\n' - '// Where data is:\n' - '// uint8_t data[kStateLength] = {0xA5, 0x5A, 0x00, 0x00, 0x40, 0x00,' - ' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};\n' - '//\n' - '// Args:\n' - '// data: An array of bytes containing the IR command.\n' - '// It is assumed to be in MSB order for this code.\n' - '// nbytes: Nr. of bytes of data in the array. (>=kStateLength)\n' - '// repeat: Nr. of times the message is to be repeated.\n' - '//\n' - '// Status: ALPHA / Untested.\n' + '/// Send a formatted message.\n' + '/// Alternative >64bit function to send TBD messages\n' + '/// Status: ALPHA / Untested.\n' + '/// Where data is:\n' + '/// uint8_t data[kStateLength] = {0xA5, 0x5A, 0x00, 0x00, 0x40,' + ' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};\n' + '///\n' + '/// @param[in] data An array of bytes containing the IR command.\n' + '/// It is assumed to be in MSB order for this code.\n' + '/// @param[in] nbytes Nr. of bytes of data in the array.' + ' (>=kStateLength)\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendTBD(const uint8_t data[], const uint16_t nbytes,' ' const uint16_t repeat) {\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' @@ -1309,15 +1378,25 @@ class TestAutoAnalyseRawData(unittest.TestCase): "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '#if DECODE_TBD\n' - '// Function should be safe up to 64 bits.\n' - 'bool IRrecv::decodeTBD(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kOverhead)\n' + '/// Decode the supplied message.\n' + '/// Function should be safe up to 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeTBD(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' @@ -1348,15 +1427,25 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' '// Note: This should be 64+ bit safe.\n' '#if DECODE_TBD\n' - '// Function should be safe over 64 bits.\n' - 'bool IRrecv::decodeTBD(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kOverhead)\n' + '/// Decode the supplied message.\n' + '/// Function should be safe over 64 bits.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeTBD(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint16_t pos = 0;\n' ' uint16_t used = 0;\n' '\n' diff --git a/lib/IRremoteESP8266-2.7.6/tools/gc_decode.cpp b/lib/IRremoteESP8266-2.7.7/tools/gc_decode.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/tools/gc_decode.cpp rename to lib/IRremoteESP8266-2.7.7/tools/gc_decode.cpp diff --git a/lib/IRremoteESP8266-2.7.6/tools/generate_irtext_h.sh b/lib/IRremoteESP8266-2.7.7/tools/generate_irtext_h.sh similarity index 100% rename from lib/IRremoteESP8266-2.7.6/tools/generate_irtext_h.sh rename to lib/IRremoteESP8266-2.7.7/tools/generate_irtext_h.sh diff --git a/lib/IRremoteESP8266-2.7.6/tools/mkkeywords b/lib/IRremoteESP8266-2.7.7/tools/mkkeywords similarity index 100% rename from lib/IRremoteESP8266-2.7.6/tools/mkkeywords rename to lib/IRremoteESP8266-2.7.7/tools/mkkeywords diff --git a/lib/IRremoteESP8266-2.7.6/tools/mode2_decode.cpp b/lib/IRremoteESP8266-2.7.7/tools/mode2_decode.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.6/tools/mode2_decode.cpp rename to lib/IRremoteESP8266-2.7.7/tools/mode2_decode.cpp diff --git a/lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code.py b/lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code.py new file mode 100755 index 000000000..307ae7121 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code.py @@ -0,0 +1,103 @@ +#!/usr/bin/python +"""Convert IRremoteESP8266's Raw data output into Pronto Code.""" +# +# Copyright 2020 David Conran +import argparse +import sys +from auto_analyse_raw_data import convert_rawdata, add_rawdata_args, get_rawdata + + +# pylint: disable=too-many-arguments +def parse_and_report(rawdata_str, hertz=38000, end_usecs=100000, + use_initial=False, generate_code=False, verbose=False, + output=sys.stdout): + """Analyse the rawdata c++ definition of a IR message.""" + + # Parse the input. + rawdata = convert_rawdata(rawdata_str) + if verbose: + output.write("Found %d timing entries.\n" % len(rawdata)) + + # Do we need to pad out the rawdata to make it even in length? + if end_usecs > 0 and len(rawdata) % 2 == 1: + rawdata.append(end_usecs) + + result = ["0000"] + # Work out the frequency code. + pronto_freq = int(1000000.0 / (hertz * 0.241246)) + if verbose: + output.write("Pronto frequency is %X (%d Hz).\n" % (pronto_freq, hertz)) + result.append("%04X" % pronto_freq) + period = 1000000.0 / max(1, hertz) + if verbose: + output.write("Pronto period is %f uSecs.\n" % period) + # Add the lengths to the code. + if use_initial: + result.append("%04x" % int(len(rawdata) / 2)) # Initial burst code length + result.append("%04x" % 0) # No Repeat code length + else: + result.append("%04x" % 0) # No Initial burst code length + result.append("%04x" % int(len(rawdata) / 2)) # Repeat code length + + # Add the data. + if verbose: + output.write("Raw data: %s " % rawdata) + for i in rawdata: + result.append("%04x" % int(i / period)) + if generate_code: + output.write("uint16_t pronto[%d] = {0x%s};\n" % (len(result), + ", 0x".join(result))) + else: + output.write("Pronto code = '%s'\n" % " ".join(result)) +# pylint: enable=too-many-arguments + + +def main(): + """Parse the commandline arguments and call the method.""" + arg_parser = argparse.ArgumentParser( + description="Read an IRremoteESP8266 rawData declaration and tries to " + "convert it in to a Pronto code.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + arg_parser.add_argument( + "--hz", + "--hertz", + type=int, + help="Frequency of the protocol to use in code generation. E.g. 38000Hz", + dest="hertz", + required=True) + arg_parser.add_argument( + "-c", + "--code", + action='store_true', + help="Output C/C++ code instead of human-readable.", + dest="generate_code") + arg_parser.add_argument( + "-g", + "--gap", + "--endgap", + type=int, + help="Nr. of uSeconds of gap to add to the end of the message.", + dest="usecs", + default=100000) + arg_parser.add_argument( + "-i", + "--initial_burst", + action='store_true', + help="Send using only the 'inital burst' section of the pronto code.", + dest="use_initial") + arg_parser.add_argument( + "-v", + "--verbose", + help="Increase output verbosity", + action="store_true", + dest="verbose", + default=False) + add_rawdata_args(arg_parser) + arg_options = arg_parser.parse_args() + parse_and_report(get_rawdata(arg_options), arg_options.hertz, + arg_options.usecs, arg_options.use_initial, + arg_options.generate_code, arg_options.verbose) + + +if __name__ == '__main__': + main() diff --git a/lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code_test.py b/lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code_test.py new file mode 100755 index 000000000..b7b029b66 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code_test.py @@ -0,0 +1,81 @@ +#!/usr/bin/python3 +"""Unit tests for raw_to_pronto_code.py""" +from io import StringIO +import unittest +import raw_to_pronto_code as pronto + +class TestRawToPronto(unittest.TestCase): + """Unit tests for the methods in raw_to_pronto_code.""" + + def test_parse_and_report_at_38000(self): + """Tests for the parse_and_report() function @ 38kHz.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 38000, 100000, True, False, False, + output) + self.assertEqual( + output.getvalue(), + "Pronto code = " + "'0000 006D 0004 0000 02fb 0309 023d 048e 02fb 0309 023d 0ed8'\n") + + def test_parse_and_report_at_36000(self): + """Tests for the parse_and_report() function @ 36kHz.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 36000, 100000, True, False, False, + output) + self.assertEqual( + output.getvalue(), + "Pronto code = " + "'0000 0073 0004 0000 02d3 02e0 021f 0451 02d3 02e0 021f 0e10'\n") + + def test_parse_and_report_at_57600(self): + """Tests for the parse_and_report() function @ 57.6kHz.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 57600, 100000, True, False, False, + output) + self.assertEqual( + output.getvalue(), + "Pronto code = " + "'0000 0047 0004 0000 0485 049b 0365 06e8 0485 049b 0364 1680'\n") + + def test_using_repeat(self): + """Tests for the parse_and_report() function @38kHz using repeat section.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 38000, 30000, False, False, False, + output) + self.assertEqual( + output.getvalue(), + "Pronto code = " + "'0000 006D 0000 0004 02fb 0309 023d 048e 02fb 0309 023d 0474'\n") + + def test_generate_code_output(self): + """Tests for the parse_and_report() function geneating code output.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 38000, 30000, True, True, False, output) + self.assertEqual( + output.getvalue(), + "uint16_t pronto[12] = {0x0000, 0x006D, 0x0004, 0x0000, 0x02fb, " + "0x0309, 0x023d, 0x048e, 0x02fb, 0x0309, 0x023d, 0x0474};\n") + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/lib/IRremoteESP8266-2.7.6/tools/scrape_supported_devices.py b/lib/IRremoteESP8266-2.7.7/tools/scrape_supported_devices.py similarity index 98% rename from lib/IRremoteESP8266-2.7.6/tools/scrape_supported_devices.py rename to lib/IRremoteESP8266-2.7.7/tools/scrape_supported_devices.py index c859bbf06..4beb6c9c3 100755 --- a/lib/IRremoteESP8266-2.7.6/tools/scrape_supported_devices.py +++ b/lib/IRremoteESP8266-2.7.7/tools/scrape_supported_devices.py @@ -23,7 +23,8 @@ EXCLUDED_ACS = ["Magiquest", "NEC"] MARKDOWN_HEADER = """""".format(time.asctime()) + Last generated: {} --->""".format( + time.strftime("%a %d %b %Y %H:%M:%S +0000", time.gmtime())) def getallprotocols(): diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 1f343928e..cd6ee9982 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -4,6 +4,7 @@ - Add command ``Rule0`` to change global rule parameters - Add more functionality to ``Switchmode`` 11 and 12 (#8450) +- Change IRremoteESP8266 library updated to v2.7.7 ## Released From 62afcad7215d304a1d9159c3103b922366d32db9 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 20 May 2020 15:55:55 +0200 Subject: [PATCH 023/581] Update platformio.ini --- platformio.ini | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index c9eb6d5f4..22259969c 100755 --- a/platformio.ini +++ b/platformio.ini @@ -109,8 +109,7 @@ build_flags = ${esp_defaults.build_flags} ; No exception code in firmware -fno-exceptions -lstdc++ - ; the following removes the 4-bytes alignment for PSTR(), waiting for a cleaner flag from Arduino Core - -DPSTR\(s\)=\(__extension__\(\{static\ const\ char\ __c\[\]\ __attribute__\(\(__aligned__\(1\)\)\)\ __attribute__\(\(section\(\ \"\\\\\".irom0.pstr.\"\ __FILE__\ \".\"\ __STRINGIZE\(__LINE__\)\ \".\"\ \ __STRINGIZE\(__COUNTER__\)\ \"\\\\\"\,\ \\\\\"aSM\\\\\"\,\ \@progbits\,\ 1\ \#\"\)\)\)\ =\ \(s\)\;\ \&__c\[0\]\;\}\)\) + ; the following removes the 4-bytes alignment for PSTR() -DPSTR_ALIGN=1 ; restrict to minimal mime-types -DMIMETYPE_MINIMAL From e32ced285dd2a40da52d79b374c960d5d87cac45 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 20 May 2020 20:09:47 +0200 Subject: [PATCH 024/581] Use Platformio framework ESP32 1.12.1 --- platformio_override_sample.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 071c28887..d292724c7 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -159,7 +159,7 @@ build_type = debug ; *** expect the unexpected. Many features not working!!! *** [common32] -platform = espressif32@1.12.0 +platform = espressif32@1.12.1 platform_packages = tool-esptoolpy@1.20800.0 board = esp32dev board_build.ldscript = esp32_out.ld From 3c994ad3a93e5f759d005f7e10fc11af89ae37c9 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 20 May 2020 21:08:15 +0200 Subject: [PATCH 025/581] Fix crash in unishox decompress #8486 --- lib/Unishox-1.0-shadinger/src/unishox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Unishox-1.0-shadinger/src/unishox.cpp b/lib/Unishox-1.0-shadinger/src/unishox.cpp index 4b17dce2e..2de356d3d 100644 --- a/lib/Unishox-1.0-shadinger/src/unishox.cpp +++ b/lib/Unishox-1.0-shadinger/src/unishox.cpp @@ -433,8 +433,8 @@ int32_t Unishox::getNumFromBits(uint32_t count) { // Code size optimized, recalculate adder[] like in encodeCount uint32_t Unishox::readCount(void) { int32_t idx = getCodeIdx(us_hcode); + if ((1 == idx) || (idx >= sizeof(bit_len)) || (idx < 0)) return 0; // unsupported or end of stream if (idx >= 1) idx--; // we skip v = 1 (code '0') since we no more accept 2 bits encoding - if ((idx >= sizeof(bit_len)) || (idx < 0)) return 0; // unsupported or end of stream int base; int till = 0; @@ -470,7 +470,7 @@ int32_t Unishox::unishox_decompress(const char *p_in, size_t p_len, char *p_out, len <<= 3; // *8, len in bits out[ol] = 0; - while (bit_no < len) { + while ((byte_no << 3) + bit_no - 8 < len) { int32_t h, v; char c = 0; byte is_upper = is_all_upper; From 7b42e6f338edd3865ea4d0752f2d0288f66a2ede Mon Sep 17 00:00:00 2001 From: Javier Arigita Date: Wed, 20 May 2020 22:10:49 +0200 Subject: [PATCH 026/581] Duty cycle output added, as well as possibility to disable physical output --- tasmota/xdrv_39_thermostat.ino | 82 ++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/tasmota/xdrv_39_thermostat.ino b/tasmota/xdrv_39_thermostat.ino index 8471bed40..f250a5c62 100644 --- a/tasmota/xdrv_39_thermostat.ino +++ b/tasmota/xdrv_39_thermostat.ino @@ -24,8 +24,8 @@ // Enable/disable debugging //#define DEBUG_THERMOSTAT -// Enable/disable experimental PI auto-tuning inspired by the Arduino Autotune Library by -// Brett Beauregard brettbeauregard.com +// Enable/disable experimental PI auto-tuning inspired by the Arduino +// Autotune Library by Brett Beauregard //#define USE_PI_AUTOTUNING // (Ziegler-Nichols closed loop method) #ifdef DEBUG_THERMOSTAT @@ -75,6 +75,8 @@ #define D_CMND_TIMEPIINTEGRREAD "TimePiIntegrRead" #define D_CMND_TIMESENSLOSTSET "TimeSensLostSet" #define D_CMND_DIAGNOSTICMODESET "DiagnosticModeSet" +#define D_CMND_CTRDUTYCYCLEREAD "CtrDutyCycleRead" +#define D_CMND_ENABLEOUTPUTSET "EnableOutputSet" enum ThermostatModes { THERMOSTAT_OFF, THERMOSTAT_AUTOMATIC_OP, THERMOSTAT_MANUAL_OP, THERMOSTAT_MODES_MAX }; #ifdef USE_PI_AUTOTUNING @@ -100,7 +102,11 @@ enum ThermostatSupportedInputSwitches { THERMOSTAT_INPUT_SWT1 = 1, // Buttons THERMOSTAT_INPUT_SWT2, THERMOSTAT_INPUT_SWT3, - THERMOSTAT_INPUT_SWT4 + THERMOSTAT_INPUT_SWT4, + THERMOSTAT_INPUT_SWT5, + THERMOSTAT_INPUT_SWT6, + THERMOSTAT_INPUT_SWT7, + THERMOSTAT_INPUT_SWT8 }; enum ThermostatSupportedOutputRelays { THERMOSTAT_OUTPUT_NONE, @@ -132,12 +138,12 @@ typedef union { uint32_t counter_seconds : 6; // Second counter used to track minutes uint32_t output_relay_number : 4; // Output relay number uint32_t input_switch_number : 3; // Input switch number + uint32_t enable_output : 1; // Enables / disables the physical output #ifdef USE_PI_AUTOTUNING uint32_t autotune_flag : 1; // Enable/disable autotune uint32_t autotune_perf_mode : 2; // Autotune performance mode - uint32_t free : 1; // Free bits #else - uint32_t free : 4; // Free bits + uint32_t free : 3; // Free bits #endif // USE_PI_AUTOTUNING }; } ThermostatStateBitfield; @@ -168,7 +174,8 @@ const char kThermostatCommands[] PROGMEM = "|" D_CMND_THERMOSTATMODESET "|" D_CM #endif // USE_PI_AUTOTUNING D_CMND_TIMEMINACTIONSET "|" D_CMND_TIMEMINTURNOFFACTIONSET "|" D_CMND_TEMPRUPDELTINSET "|" D_CMND_TEMPRUPDELTOUTSET "|" D_CMND_TIMERAMPUPMAXSET "|" D_CMND_TIMERAMPUPCYCLESET "|" D_CMND_TEMPRAMPUPPIACCERRSET "|" D_CMND_TIMEPIPROPORTREAD "|" - D_CMND_TIMEPIINTEGRREAD "|" D_CMND_TIMESENSLOSTSET "|" D_CMND_DIAGNOSTICMODESET; + D_CMND_TIMEPIINTEGRREAD "|" D_CMND_TIMESENSLOSTSET "|" D_CMND_DIAGNOSTICMODESET "|" D_CMND_CTRDUTYCYCLEREAD "|" + D_CMND_ENABLEOUTPUTSET; void (* const ThermostatCommand[])(void) PROGMEM = { &CmndThermostatModeSet, &CmndClimateModeSet, &CmndTempFrostProtectSet, &CmndControllerModeSet, &CmndInputSwitchSet, @@ -181,7 +188,8 @@ void (* const ThermostatCommand[])(void) PROGMEM = { &CmndTimeMaxActionSet, &CmndTimeMinActionSet, &CmndTimeMinTurnoffActionSet, &CmndTempRupDeltInSet, #endif // USE_PI_AUTOTUNING &CmndTempRupDeltOutSet, &CmndTimeRampupMaxSet, &CmndTimeRampupCycleSet, &CmndTempRampupPiAccErrSet, - &CmndTimePiProportRead, &CmndTimePiIntegrRead, &CmndTimeSensLostSet, &CmndDiagnosticModeSet }; + &CmndTimePiProportRead, &CmndTimePiIntegrRead, &CmndTimeSensLostSet, &CmndDiagnosticModeSet, &CmndCtrDutyCycleRead, + &CmndEnableOutputSet }; struct THERMOSTAT { ThermostatStateBitfield status; // Bittfield including states as well as several flags @@ -268,6 +276,7 @@ void ThermostatInit(uint8_t ctr_output) Thermostat[ctr_output].status.output_relay_number = (THERMOSTAT_RELAY_NUMBER + ctr_output); Thermostat[ctr_output].status.input_switch_number = (THERMOSTAT_SWITCH_NUMBER + ctr_output); Thermostat[ctr_output].status.use_input = INPUT_NOT_USED; + Thermostat[ctr_output].status.enable_output = IFACE_ON; Thermostat[ctr_output].diag.output_inconsist_ctr = 0; Thermostat[ctr_output].diag.diagnostic_mode = DIAGNOSTIC_ON; #ifdef USE_PI_AUTOTUNING @@ -275,7 +284,9 @@ void ThermostatInit(uint8_t ctr_output) Thermostat[ctr_output].status.autotune_perf_mode = AUTOTUNE_PERF_FAST; #endif // USE_PI_AUTOTUNING // Make sure the Output is OFF - ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_OFF, SRC_THERMOSTAT); + if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { + ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_OFF, SRC_THERMOSTAT); + } } bool ThermostatMinuteCounter(uint8_t ctr_output) @@ -292,7 +303,7 @@ bool ThermostatMinuteCounter(uint8_t ctr_output) inline bool ThermostatSwitchIdValid(uint8_t switchId) { - return (switchId >= THERMOSTAT_INPUT_SWT1 && switchId <= THERMOSTAT_INPUT_SWT4); + return (switchId >= THERMOSTAT_INPUT_SWT1 && switchId <= THERMOSTAT_INPUT_SWT8); } inline bool ThermostatRelayIdValid(uint8_t relayId) @@ -366,7 +377,8 @@ void ThermostatSignalPreProcessingSlow(uint8_t ctr_output) void ThermostatSignalPostProcessingSlow(uint8_t ctr_output) { // Increate counter when inconsistent output state exists - if (Thermostat[ctr_output].status.status_output != Thermostat[ctr_output].status.command_output) { + if ((Thermostat[ctr_output].status.status_output != Thermostat[ctr_output].status.command_output) + &&(Thermostat[ctr_output].status.enable_output == IFACE_ON)) { Thermostat[ctr_output].diag.output_inconsist_ctr++; } else { @@ -540,7 +552,9 @@ void ThermostatEmergencyShutdown(uint8_t ctr_output) // Emergency switch to THERMOSTAT_OFF Thermostat[ctr_output].status.thermostat_mode = THERMOSTAT_OFF; Thermostat[ctr_output].status.command_output = IFACE_OFF; - ThermostatOutputRelay(ctr_output, Thermostat[ctr_output].status.command_output); + if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { + ThermostatOutputRelay(ctr_output, Thermostat[ctr_output].status.command_output); + } } void ThermostatState(uint8_t ctr_output) @@ -576,7 +590,9 @@ void ThermostatOutputRelay(uint8_t ctr_output, uint32_t command) if ((command == IFACE_ON) && (Thermostat[ctr_output].status.status_output == IFACE_OFF)) { //#ifndef DEBUG_THERMOSTAT - ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_ON, SRC_THERMOSTAT); + if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { + ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_ON, SRC_THERMOSTAT); + } //#endif // DEBUG_THERMOSTAT Thermostat[ctr_output].status.status_output = IFACE_ON; #ifdef DEBUG_THERMOSTAT @@ -588,7 +604,9 @@ void ThermostatOutputRelay(uint8_t ctr_output, uint32_t command) // then switch output to OFF else if ((command == IFACE_OFF) && (Thermostat[ctr_output].status.status_output == IFACE_ON)) { //#ifndef DEBUG_THERMOSTAT - ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_OFF, SRC_THERMOSTAT); + if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { + ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_OFF, SRC_THERMOSTAT); + } //#endif // DEBUG_THERMOSTAT Thermostat[ctr_output].timestamp_output_off = uptime; Thermostat[ctr_output].status.status_output = IFACE_OFF; @@ -1917,6 +1935,44 @@ void CmndDiagnosticModeSet(void) } } +void CmndCtrDutyCycleRead(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + uint8_t value = 0; + if ( (Thermostat[ctr_output].status.controller_mode == CTR_PI) + || ((Thermostat[ctr_output].status.controller_mode == CTR_HYBRID) + &&(Thermostat[ctr_output].status.phase_hybrid_ctr == CTR_HYBRID_PI))) { + value = Thermostat[ctr_output].time_total_pi / Thermostat[ctr_output].time_pi_cycle; + } + else if ( (Thermostat[ctr_output].status.controller_mode == CTR_RAMP_UP) + || ((Thermostat[ctr_output].status.controller_mode == CTR_HYBRID) + &&(Thermostat[ctr_output].status.phase_hybrid_ctr == CTR_HYBRID_RAMP_UP))) { + if (Thermostat[ctr_output].status.status_output == IFACE_ON) { + value = 100; + } + else { + value = 0; + } + } + ResponseCmndNumber((int)value); + } +} + +void CmndEnableOutputSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(CharToFloat(XdrvMailbox.data)); + if ((value >= IFACE_OFF) && (value <= IFACE_ON)) { + Thermostat[ctr_output].status.enable_output = value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].diag.diagnostic_mode); + } +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ From f880d058edd2a22fe989f351a86380dc002d5983 Mon Sep 17 00:00:00 2001 From: Javier Arigita Date: Wed, 20 May 2020 22:21:25 +0200 Subject: [PATCH 027/581] Bugfix --- tasmota/xdrv_39_thermostat.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_39_thermostat.ino b/tasmota/xdrv_39_thermostat.ino index f250a5c62..79e842dc5 100644 --- a/tasmota/xdrv_39_thermostat.ino +++ b/tasmota/xdrv_39_thermostat.ino @@ -1969,7 +1969,7 @@ void CmndEnableOutputSet(void) Thermostat[ctr_output].status.enable_output = value; } } - ResponseCmndNumber((int)Thermostat[ctr_output].diag.diagnostic_mode); + ResponseCmndNumber((int)Thermostat[ctr_output].status.enable_output); } } From 5e6010d1d09baf7559b3b885b2fe37ef98c44640 Mon Sep 17 00:00:00 2001 From: Federico Leoni Date: Wed, 20 May 2020 22:11:07 -0300 Subject: [PATCH 028/581] Fix slider for PWM_MODULE --- tasmota/xdrv_12_home_assistant.ino | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index e9d8bd009..292ce3831 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -195,10 +195,15 @@ void HAssAnnounceRelayLight(void) bool ct_light = false; // Controls a CT Light when SetOption37 is >= 128 bool wt_light = false; // Controls a White Light when SetOption37 is >= 128 bool err_flag = false; // When true it blocks the creation of entities if the order of the Relays is not correct to avoid issue with Lights + bool PwmMod = false; // Controls PWM_DIMMER module uint8_t dimmer = 1; uint8_t max_lights = 1; + #ifdef ESP8266 + if (PWM_DIMMER == my_module_type) { PwmMod = true; } + #endif //ESP8266 + // If there is a special Light to be enabled and managed with SetOption68 or SetOption37 >= 128, Discovery calculates the maximum number of entities to be generated in advance if (PwmMulti) { max_lights = Light.subtype; } @@ -255,13 +260,8 @@ void HAssAnnounceRelayLight(void) TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); #ifdef USE_LIGHT - if ((i >= Light.device) - #ifdef ESP8266 - || PWM_DIMMER == my_module_type - #endif - ) - { - if (!RelayX) { + if ((i >= Light.device)) { + if (!RelayX || PwmMod) { char *brightness_command_topic = stemp1; strncpy_P(stemp3, Settings.flag.not_power_linked ? PSTR("last") : PSTR("brightness"), sizeof(stemp3)); // SetOption20 - Control power in relation to Dimmer/Color/Ct changes char channel_num[9]; From 9b519700c10017027f517653c7d5750cf183558c Mon Sep 17 00:00:00 2001 From: Paul C Diem Date: Wed, 20 May 2020 20:55:02 -0500 Subject: [PATCH 029/581] Publish state when dimmer button tapped --- tasmota/xdrv_35_pwm_dimmer.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_35_pwm_dimmer.ino b/tasmota/xdrv_35_pwm_dimmer.ino index fd7a9d86b..39ab399df 100644 --- a/tasmota/xdrv_35_pwm_dimmer.ino +++ b/tasmota/xdrv_35_pwm_dimmer.ino @@ -552,6 +552,7 @@ void PWMDimmerHandleButton(void) if (button_hold_time[button_index] >= now) { bri_offset = (is_down_button ? -1 : 1); dgr_item = 255; + state_updated = true; } // If the button was held and the hold was not processed by a rule, we changed the @@ -601,7 +602,7 @@ void PWMDimmerHandleButton(void) } if (new_bri != bri) { #ifdef USE_DEVICE_GROUPS - SendDeviceGroupMessage(power_button_index, (dgr_item ? DGR_MSGTYP_UPDATE : DGR_MSGTYP_UPDATE_MORE_TO_COME), DGR_ITEM_LIGHT_BRI, new_bri); + SendDeviceGroupMessage(power_button_index, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_ITEM_LIGHT_BRI, new_bri); #endif // USE_DEVICE_GROUPS #ifdef USE_PWM_DIMMER_REMOTE if (!active_device_is_local) @@ -663,7 +664,7 @@ void PWMDimmerHandleButton(void) // If we're not changing the brightness or toggling the power and we made changes, send a group // update. - else if (dgr_item) { + if (dgr_item) { #ifdef USE_DEVICE_GROUPS if (dgr_item == 255) dgr_item = 0; SendDeviceGroupMessage(power_button_index, (dgr_more_to_come ? DGR_MSGTYP_UPDATE_MORE_TO_COME : DGR_MSGTYP_UPDATE_DIRECT), dgr_item, dgr_value); From edaf6c493e303f64670357ddfcd7e6e78f0b40d5 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Thu, 21 May 2020 06:06:42 +0200 Subject: [PATCH 030/581] fix scripter unishox error, add 2 y axes line graph to google charts --- tasmota/xdrv_10_scripter.ino | 54 +++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 8c2dcbc4f..895049a21 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -52,7 +52,9 @@ keywords if then else endif, or, and are better readable for beginners (others m #endif #define MAXNVARS MAXVARS-MAXSVARS +#ifndef MAXFILT #define MAXFILT 5 +#endif #define SCRIPT_SVARSIZE 20 #define SCRIPT_MAXSSIZE 48 #define SCRIPT_EOL '\n' @@ -66,8 +68,17 @@ keywords if then else endif, or, and are better readable for beginners (others m uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); +#ifdef USE_RULES_COMPRESSION #include +Unishox compressor; // singleton +#define SCRIPT_COMPRESS compressor.unishox_compress +#define SCRIPT_DECOMPRESS compressor.unishox_decompress +#ifndef UNISHOXRSIZE +#define UNISHOXRSIZE 2560 +#endif +#endif + #if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) #include "FS.h" #include "SPIFFS.h" @@ -3966,20 +3977,20 @@ void ScriptSaveSettings(void) { glob_script_mem.script_mem_size=0; } - -#ifndef UNISHOXRSIZE -#define UNISHOXRSIZE 2560 -#endif #ifdef USE_RULES_COMPRESSION #ifndef USE_24C256 #ifndef USE_SCRIPT_FATFS #ifndef ESP32_SCRIPT_SIZE - uint32_t len_compressed = unishox_compress(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], UNISHOXRSIZE); + + //AddLog_P2(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); + uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram)+1, Settings.rules[0], MAX_SCRIPT_SIZE-1); + Settings.rules[0][len_compressed] = 0; if (len_compressed > 0) { - AddLog_P2(LOG_LEVEL_INFO,PSTR("compressed to %d"),len_compressed * 100 / strlen(glob_script_mem.script_ram)); + AddLog_P2(LOG_LEVEL_INFO,PSTR("script compressed to %d %%"),len_compressed * 100 / strlen(glob_script_mem.script_ram)); } else { AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); } + #endif #endif #endif @@ -4912,6 +4923,10 @@ const char SCRIPT_MSG_GTABLEb[] PROGMEM = const char SCRIPT_MSG_GOPT1[] PROGMEM = "title:'%s',isStacked:false"; +const char SCRIPT_MSG_GOPT3[] PROGMEM = +"title:'%s',vAxes:{0:{maxValue:%d},1:{maxValue:%d}},series:{0:{targetAxisIndex:0},1:{targetAxisIndex:1}}"; + + const char SCRIPT_MSG_GOPT2[] PROGMEM = "showRowNumber:true,sort:'disable',allowHtml:true,width:'100%%',height:'100%%',cssClassNames:cssc"; @@ -5223,14 +5238,27 @@ void ScriptWebShow(char mc) { lp=GetStringResult(lp,OPER_EQU,header,0); SCRIPT_SKIP_SPACES - char options[128]; + char options[256]; snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT1,header); + //uint32_t slen=sizeof(SCRIPT_MSG_GOPT1)+strlen(header); const char *type; if (*lp!=')') { switch (*lp) { case 'l': type=PSTR("LineChart"); + if (*(lp+1)=='2') { + // 2 y axes variant + lp+=2; + SCRIPT_SKIP_SPACES + float max1; + lp=GetNumericResult(lp,OPER_EQU,&max1,0); + SCRIPT_SKIP_SPACES + float max2; + lp=GetNumericResult(lp,OPER_EQU,&max2,0); + SCRIPT_SKIP_SPACES + snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT3,header,(uint32_t)max1,(uint32_t)max2); + } break; case 'b': type=PSTR("BarChart"); @@ -5255,6 +5283,7 @@ void ScriptWebShow(char mc) { } else { type=PSTR("ColumnChart"); } + lp++; WSContentSend_PD(SCRIPT_MSG_GTABLEb,options,type,chartindex); chartindex++; @@ -5423,6 +5452,7 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { bool Xdrv10(uint8_t function) { bool result = false; + char *sprt; switch (function) { case FUNC_PRE_INIT: @@ -5438,10 +5468,14 @@ bool Xdrv10(uint8_t function) #ifndef USE_24C256 #ifndef USE_SCRIPT_FATFS #ifndef ESP32_SCRIPT_SIZE - glob_script_mem.script_ram=(char*)calloc(UNISHOXRSIZE+8,1); - if (!glob_script_mem.script_ram) { break; } - unishox_decompress(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, UNISHOXRSIZE); + int32_t len_decompressed; + sprt=(char*)calloc(UNISHOXRSIZE+8,1); + if (!sprt) { break; } + glob_script_mem.script_ram=sprt; glob_script_mem.script_size=UNISHOXRSIZE; + len_decompressed = SCRIPT_DECOMPRESS(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, glob_script_mem.script_size); + glob_script_mem.script_ram[len_decompressed]=0; + //AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); #endif #endif #endif From fca5dc9471c25fdc29512be8150c52ba7eb9d683 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Thu, 21 May 2020 08:13:26 +0200 Subject: [PATCH 031/581] Update xdrv_10_scripter.ino --- tasmota/xdrv_10_scripter.ino | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 895049a21..eb0d00f29 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -68,7 +68,7 @@ keywords if then else endif, or, and are better readable for beginners (others m uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); -#ifdef USE_RULES_COMPRESSION +#ifdef USE_SCRIPT_COMPRESSION #include Unishox compressor; // singleton @@ -77,7 +77,7 @@ Unishox compressor; // singleton #ifndef UNISHOXRSIZE #define UNISHOXRSIZE 2560 #endif -#endif +#endif // USE_SCRIPT_COMPRESSION #if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) #include "FS.h" @@ -1768,7 +1768,7 @@ chknext: lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); lp++; //fvar=pow(fvar1,fvar2); - fvar=FastPrecisePow(fvar1,fvar2); + fvar=FastPrecisePowf(fvar1,fvar2); len=0; goto exit; } @@ -3977,7 +3977,7 @@ void ScriptSaveSettings(void) { glob_script_mem.script_mem_size=0; } -#ifdef USE_RULES_COMPRESSION +#ifdef USE_SCRIPT_COMPRESSION #ifndef USE_24C256 #ifndef USE_SCRIPT_FATFS #ifndef ESP32_SCRIPT_SIZE @@ -3994,7 +3994,7 @@ void ScriptSaveSettings(void) { #endif #endif #endif -#endif // USE_RULES_COMPRESSION +#endif // USE_SCRIPT_COMPRESSION if (bitRead(Settings.rule_enabled, 0)) { int16_t res=Init_Scripter(); @@ -5464,7 +5464,7 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_pram=(uint8_t*)Settings.script_pram[0]; glob_script_mem.script_pram_size=PMEM_SIZE; -#ifdef USE_RULES_COMPRESSION +#ifdef USE_SCRIPT_COMPRESSION #ifndef USE_24C256 #ifndef USE_SCRIPT_FATFS #ifndef ESP32_SCRIPT_SIZE @@ -5479,7 +5479,7 @@ bool Xdrv10(uint8_t function) #endif #endif #endif -#endif // USE_RULES_COMPRESSION +#endif // USE_SCRIPT_COMPRESSION #ifdef USE_BUTTON_EVENT for (uint32_t cnt=0;cnt Date: Thu, 21 May 2020 17:06:52 +0200 Subject: [PATCH 032/581] Update Change log --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 75c484388..f2c6ef4f7 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -54,5 +54,6 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ### Version 8.3.1.1 +- Change IRremoteESP8266 library updated to v2.7.7 - Add command ``Rule0`` to change global rule parameters - Add more functionality to ``Switchmode`` 11 and 12 (#8450) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index cd6ee9982..4b8d81fe7 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -2,9 +2,9 @@ ### 8.3.1.1 20200518 +- Change IRremoteESP8266 library updated to v2.7.7 - Add command ``Rule0`` to change global rule parameters - Add more functionality to ``Switchmode`` 11 and 12 (#8450) -- Change IRremoteESP8266 library updated to v2.7.7 ## Released From a068010edf9b2bafa834de31f3ceaa76a3f470f7 Mon Sep 17 00:00:00 2001 From: Federico Leoni Date: Thu, 21 May 2020 12:33:57 -0300 Subject: [PATCH 033/581] HAss force [is_topic_light] for Dimmer module --- tasmota/xdrv_12_home_assistant.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 292ce3831..7ede88b44 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -218,7 +218,7 @@ void HAssAnnounceRelayLight(void) for (uint32_t i = 1; i <= MAX_RELAYS; i++) { bool RelayX = PinUsed(GPIO_REL1 +i-1); - is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX; // SetOption30 - Enforce HAss autodiscovery as light + is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX || PwmMod; // SetOption30 - Enforce HAss autodiscovery as light mqtt_data[0] = '\0'; // Clear retained message @@ -237,7 +237,7 @@ void HAssAnnounceRelayLight(void) AddLog_P2(LOG_LEVEL_ERROR, PSTR("%s"), kHAssError2); } else { if (Settings.flag.hass_discovery && (RelayX || (Light.device > 0) && (max_lights > 0)) && !err_flag ) - { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59) + { // SetOption19 - Control Home Assistant automatic discovery (See SetOption59) char name[TOPSZ]; // friendlyname(33) + " " + index char value_template[33]; char prefix[TOPSZ]; @@ -260,7 +260,7 @@ void HAssAnnounceRelayLight(void) TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); #ifdef USE_LIGHT - if ((i >= Light.device)) { + if (i >= Light.device) { if (!RelayX || PwmMod) { char *brightness_command_topic = stemp1; strncpy_P(stemp3, Settings.flag.not_power_linked ? PSTR("last") : PSTR("brightness"), sizeof(stemp3)); // SetOption20 - Control power in relation to Dimmer/Color/Ct changes From f1205385bd82ca6488b1044fb8a7fe83ab06fc00 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 21 May 2020 17:49:59 +0200 Subject: [PATCH 034/581] Fix the GUI display of apostrophe Fix the GUI display of apostrophe in any name (#8489, #8323) --- tasmota/xdrv_01_webserver.ino | 24 ++++++++++++------------ tasmota/xdrv_02_mqtt.ino | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index a1e4a247b..7bb905aee 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -428,18 +428,18 @@ const char HTTP_FORM_MODULE[] PROGMEM = const char HTTP_FORM_WIFI[] PROGMEM = "
 " D_WIFI_PARAMETERS " " "
" - "

" D_AP1_SSID " (" STA_SSID1 ")

" - "


" - "

" D_AP2_SSID " (" STA_SSID2 ")

" - "


" - "

" D_HOSTNAME " (%s)

" - "

" D_CORS_DOMAIN "

"; + "

" D_AP1_SSID " (" STA_SSID1 ")

" // Need \" instead of ' to be able to use ' in text (#8489) + "


" + "

" D_AP2_SSID " (" STA_SSID2 ")

" + "


" + "

" D_HOSTNAME " (%s)

" + "

" D_CORS_DOMAIN "

"; const char HTTP_FORM_LOG1[] PROGMEM = "
 " D_LOGGING_PARAMETERS " " ""; const char HTTP_FORM_LOG2[] PROGMEM = - "

" D_SYSLOG_HOST " (" SYS_LOG_HOST ")

" + "

" D_SYSLOG_HOST " (" SYS_LOG_HOST ")

" "

" D_SYSLOG_PORT " (" STR(SYS_LOG_PORT) ")

" "

" D_TELEMETRY_PERIOD " (" STR(TELE_PERIOD) ")

"; @@ -448,15 +448,15 @@ const char HTTP_FORM_OTHER[] PROGMEM = "" "

" "
 " D_TEMPLATE " " - "

" + "

" "

" "
" "
" - "

" + "

" "
" "
" "
" - "

" + "

" "
"; const char HTTP_FORM_END[] PROGMEM = @@ -471,7 +471,7 @@ const char HTTP_FORM_UPG[] PROGMEM = "
" "
 " D_UPGRADE_BY_WEBSERVER " " "" - "
" D_OTA_URL "

" + "
" D_OTA_URL "

" "
" "


" "
 " D_UPGRADE_BY_FILE_UPLOAD " "; @@ -2004,7 +2004,7 @@ void HandleOtherConfiguration(void) #endif // USE_SONOFF_IFAN for (uint32_t i = 0; i < maxfn; i++) { snprintf_P(stemp, sizeof(stemp), PSTR("%d"), i +1); - WSContentSend_P(PSTR("" D_FRIENDLY_NAME " %d (" FRIENDLY_NAME "%s)

"), + WSContentSend_P(PSTR("" D_FRIENDLY_NAME " %d (" FRIENDLY_NAME "%s)

"), i +1, (i) ? stemp : "", i, diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index eaa2562e8..9e06f4e90 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -1240,14 +1240,14 @@ const char HTTP_BTN_MENU_MQTT[] PROGMEM = const char HTTP_FORM_MQTT1[] PROGMEM = "
 " D_MQTT_PARAMETERS " " "
" - "

" D_HOST " (" MQTT_HOST ")

" + "

" D_HOST " (" MQTT_HOST ")

" "

" D_PORT " (" STR(MQTT_PORT) ")

" - "

" D_CLIENT " (%s)

"; + "

" D_CLIENT " (%s)

"; const char HTTP_FORM_MQTT2[] PROGMEM = - "

" D_USER " (" MQTT_USER ")

" - "


" - "

" D_TOPIC " = %%topic%% (%s)

" - "

" D_FULL_TOPIC " (%s)

"; + "

" D_USER " (" MQTT_USER ")

" + "


" + "

" D_TOPIC " = %%topic%% (%s)

" + "

" D_FULL_TOPIC " (%s)

"; void HandleMqttConfiguration(void) { From 14807254bae4194c002f04c101a52097f5557e38 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 21 May 2020 18:03:05 +0200 Subject: [PATCH 035/581] Fix apostrophe regression --- tasmota/xdrv_01_webserver.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 7bb905aee..4fb1303ed 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -448,7 +448,7 @@ const char HTTP_FORM_OTHER[] PROGMEM = "" "

" "
 " D_TEMPLATE " " - "

" + "

" "

" "
" "
" From c8b575056870669f2462be9456386cd9bf813fb9 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 21 May 2020 20:12:41 +0200 Subject: [PATCH 036/581] Add dump of compressed rules over 512 chars and unishox decompress fix --- lib/Unishox-1.0-shadinger/src/unishox.cpp | 79 ++++++++++++----------- lib/Unishox-1.0-shadinger/src/unishox.h | 1 + tasmota/CHANGELOG.md | 1 + tasmota/xdrv_10_rules.ino | 20 +++++- 4 files changed, 64 insertions(+), 37 deletions(-) diff --git a/lib/Unishox-1.0-shadinger/src/unishox.cpp b/lib/Unishox-1.0-shadinger/src/unishox.cpp index 2de356d3d..9c235582a 100644 --- a/lib/Unishox-1.0-shadinger/src/unishox.cpp +++ b/lib/Unishox-1.0-shadinger/src/unishox.cpp @@ -57,7 +57,7 @@ typedef unsigned char byte; // we squeeze both c_95[] and l_95[] in a sinle array. // c_95[] uses only the 3 upper nibbles (or 12 most signifcant bits), while the last nibble encodes length (3..13) -uint16_t cl_95[95] PROGMEM = {0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12 }; +static uint16_t cl_95[95] PROGMEM = {0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12 }; // Original version with c/l separate // uint16_t c_95[95] PROGMEM = {0x4000, 0x3F80, 0x3D80, 0x3C80, 0x3BE0, 0x3E80, 0x3F40, 0x3EC0, 0x3BA0, 0x3BC0, 0x3D60, 0x3B60, 0x3A80, 0x3AC0, 0x3A00, 0x3B00, 0x38C0, 0x3900, 0x3940, 0x3960, 0x3980, 0x39A0, 0x39C0, 0x39E0, 0x39F0, 0x3880, 0x3CC0, 0x3C00, 0x3D00, 0x3E00, 0x3F00, 0x3B40, 0x3BF0, 0x2B00, 0x21C0, 0x20C0, 0x2100, 0x2600, 0x2300, 0x21E0, 0x2140, 0x2D00, 0x2358, 0x2340, 0x2080, 0x21A0, 0x2E00, 0x2C00, 0x2180, 0x2350, 0x2F80, 0x2F00, 0x2A00, 0x2160, 0x2330, 0x21F0, 0x2360, 0x2320, 0x2368, 0x3DE0, 0x3FA0, 0x3DF0, 0x3D40, 0x3F60, 0x3FF0, 0xB000, 0x1C00, 0x0C00, 0x1000, 0x6000, 0x3000, 0x1E00, 0x1400, 0xD000, 0x3580, 0x3400, 0x0800, 0x1A00, 0xE000, 0xC000, 0x1800, 0x3500, 0xF800, 0xF000, 0xA000, 0x1600, 0x3300, 0x1F00, 0x3600, 0x3200, 0x3680, 0x3DA0, 0x3FC0, 0x3DC0, 0x3FE0 }; // uint8_t l_95[95] PROGMEM = { 3, 11, 11, 10, 12, 10, 11, 10, 11, 11, 11, 11, 10, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 10, 10, 9, 10, 9, 10, 11, 12, 8, 11, 10, 10, 7, 11, 12, 11, 8, 13, 12, 10, 11, 8, 8, 11, 13, 9, 9, 8, 11, 12, 12, 13, 12, 13, 12, 11, 12, 11, 11, 12, 4, 7, 6, 6, 3, 7, 8, 7, 4, 9, 8, 6, 7, 4, 4, 7, 9, 5, 5, 4, 7, 8, 8, 9, 8, 9, 11, 11, 11, 12 }; @@ -66,7 +66,7 @@ enum {SHX_STATE_1 = 1, SHX_STATE_2}; // removed Unicode state enum {SHX_SET1 = 0, SHX_SET1A, SHX_SET1B, SHX_SET2, SHX_SET3, SHX_SET4, SHX_SET4A}; // changed mapping in Set3, Set4, Set4A to accomodate frequencies in Rules and Javascript -char sets[][11] PROGMEM = +static char sets[][11] PROGMEM = {{ 0, ' ', 'e', 0, 't', 'a', 'o', 'i', 'n', 's', 'r'}, { 0, 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'}, {'f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', 0, 0, 0}, @@ -87,7 +87,7 @@ char sets[][11] PROGMEM = // First 2 bits 00, Next 3 bits indicate index of code from 0, // last 3 bits indicate code length in bits // 0, 1, 2, 3, 4, -char us_vcode[32] PROGMEM = +static char us_vcode[32] PROGMEM = {2 + (0 << 3), 3 + (3 << 3), 3 + (1 << 3), 4 + (6 << 3), 0, // 5, 6, 7, 8, 9, 10 4 + (4 << 3), 3 + (2 << 3), 4 + (8 << 3), 0, 0, 0, @@ -98,7 +98,7 @@ char us_vcode[32] PROGMEM = // 24, 25, 26, 27, 28, 29, 30, 31 0, 0, 0, 0, 0, 0, 0, 5 + (10 << 3)}; // 0, 1, 2, 3, 4, 5, 6, 7, -char us_hcode[32] PROGMEM = +static char us_hcode[32] PROGMEM = {1 + (1 << 3), 2 + (0 << 3), 0, 3 + (2 << 3), 0, 0, 0, 5 + (3 << 3), // 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 5 + (5 << 3), @@ -107,28 +107,28 @@ char us_hcode[32] PROGMEM = // 24, 25, 26, 27, 28, 29, 30, 31 0, 0, 0, 0, 0, 0, 0, 5 + (6 << 3)}; -const char ESCAPE_MARKER = 0x2A; // Escape any null char +static const char ESCAPE_MARKER = 0x2A; // Escape any null char -const uint16_t TERM_CODE = 0x37C0; // 0b0011011111000000 -const uint16_t TERM_CODE_LEN = 10; -const uint16_t DICT_CODE = 0x0000; -const uint16_t DICT_CODE_LEN = 5; -const uint16_t DICT_OTHER_CODE = 0x0000; // not used -const uint16_t DICT_OTHER_CODE_LEN = 6; +static const uint16_t TERM_CODE = 0x37C0; // 0b0011011111000000 +static const uint16_t TERM_CODE_LEN = 10; +static const uint16_t DICT_CODE = 0x0000; +static const uint16_t DICT_CODE_LEN = 5; +static const uint16_t DICT_OTHER_CODE = 0x0000; // not used +static const uint16_t DICT_OTHER_CODE_LEN = 6; // const uint16_t RPT_CODE = 0x2370; // const uint16_t RPT_CODE_LEN = 13; -const uint16_t RPT_CODE_TASMOTA = 0x3780; -const uint16_t RPT_CODE_TASMOTA_LEN = 10; -const uint16_t BACK2_STATE1_CODE = 0x2000; // 0010 = back to lower case -const uint16_t BACK2_STATE1_CODE_LEN = 4; -const uint16_t BACK_FROM_UNI_CODE = 0xFE00; -const uint16_t BACK_FROM_UNI_CODE_LEN = 8; +static const uint16_t RPT_CODE_TASMOTA = 0x3780; +static const uint16_t RPT_CODE_TASMOTA_LEN = 10; +static const uint16_t BACK2_STATE1_CODE = 0x2000; // 0010 = back to lower case +static const uint16_t BACK2_STATE1_CODE_LEN = 4; +static const uint16_t BACK_FROM_UNI_CODE = 0xFE00; +static const uint16_t BACK_FROM_UNI_CODE_LEN = 8; // const uint16_t CRLF_CODE = 0x3780; // const uint16_t CRLF_CODE_LEN = 10; -const uint16_t LF_CODE = 0x3700; -const uint16_t LF_CODE_LEN = 9; -const uint16_t TAB_CODE = 0x2400; -const uint16_t TAB_CODE_LEN = 7; +static const uint16_t LF_CODE = 0x3700; +static const uint16_t LF_CODE_LEN = 9; +static const uint16_t TAB_CODE = 0x2400; +static const uint16_t TAB_CODE_LEN = 7; // const uint16_t UNI_CODE = 0x8000; // Unicode disabled // const uint16_t UNI_CODE_LEN = 3; // const uint16_t UNI_STATE_SPL_CODE = 0xF800; @@ -137,21 +137,21 @@ const uint16_t TAB_CODE_LEN = 7; // const uint16_t UNI_STATE_DICT_CODE_LEN = 7; // const uint16_t CONT_UNI_CODE = 0x2800; // const uint16_t CONT_UNI_CODE_LEN = 7; -const uint16_t ALL_UPPER_CODE = 0x2200; -const uint16_t ALL_UPPER_CODE_LEN = 8; -const uint16_t SW2_STATE2_CODE = 0x3800; -const uint16_t SW2_STATE2_CODE_LEN = 7; -const uint16_t ST2_SPC_CODE = 0x3B80; -const uint16_t ST2_SPC_CODE_LEN = 11; -const uint16_t BIN_CODE_TASMOTA = 0x8000; -const uint16_t BIN_CODE_TASMOTA_LEN = 3; +static const uint16_t ALL_UPPER_CODE = 0x2200; +static const uint16_t ALL_UPPER_CODE_LEN = 8; +static const uint16_t SW2_STATE2_CODE = 0x3800; +static const uint16_t SW2_STATE2_CODE_LEN = 7; +static const uint16_t ST2_SPC_CODE = 0x3B80; +static const uint16_t ST2_SPC_CODE_LEN = 11; +static const uint16_t BIN_CODE_TASMOTA = 0x8000; +static const uint16_t BIN_CODE_TASMOTA_LEN = 3; // const uint16_t BIN_CODE = 0x2000; // const uint16_t BIN_CODE_LEN = 9; #define NICE_LEN 5 // uint16_t mask[] PROGMEM = {0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00}; -uint8_t mask[] PROGMEM = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF}; +static const uint8_t mask[] PROGMEM = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF}; @@ -378,14 +378,19 @@ int32_t Unishox::unishox_compress(const char *p_in, size_t p_len, char *p_out, s state = SHX_STATE_1; append_bits(TERM_CODE, 8 - bits); // 0011 0111 1100 0000 TERM = 0011 0111 11 } - return ol/8+(ol%8?1:0); + return ol / 8; // we already arrived to a byte boundary + // return ol/8+(ol%8?1:0); } uint32_t Unishox::getNextBit(void) { if (8 == bit_no) { + if (byte_no >= len) { + in_eof = true; + return 1; // return only 1s, which appends 'r' in worst case + } byte_in = in[byte_no++]; if (ESCAPE_MARKER == byte_in) { - byte_in = in[byte_no++] - 1; + byte_in = in[byte_no++] - 1; // we shouldn't need to test if byte_no >= len, because it should not be possible to end with ESCAPE_MARKER } bit_no = 0; } @@ -399,8 +404,7 @@ int32_t Unishox::getCodeIdx(const char *code_type) { int32_t code = 0; int32_t count = 0; do { - if (bit_no >= len) - return -1; // invalid state + if (in_eof) return -1; // invalid state code += getNextBit() << count; count++; uint8_t code_type_code = pgm_read_byte(&code_type[code]); @@ -452,9 +456,11 @@ uint32_t Unishox::readCount(void) { void Unishox::decodeRepeat(void) { uint32_t dict_len = readCount() + NICE_LEN; uint32_t dist = readCount() + NICE_LEN - 1; + if (ol + dict_len <= len_out) { memcpy(out + ol, out + ol - dist, dict_len); ol += dict_len; } +} int32_t Unishox::unishox_decompress(const char *p_in, size_t p_len, char *p_out, size_t p_len_out) { in = p_in; @@ -462,15 +468,16 @@ int32_t Unishox::unishox_decompress(const char *p_in, size_t p_len, char *p_out, out = p_out; len_out = p_len_out; + in_eof = false; ol = 0; bit_no = 8; // force load of first byte, pretending we expired the last one byte_no = 0; dstate = SHX_SET1; is_all_upper = 0; - len <<= 3; // *8, len in bits out[ol] = 0; - while ((byte_no << 3) + bit_no - 8 < len) { + // while ((byte_no << 3) + bit_no - 8 < len) { + while (!in_eof) { int32_t h, v; char c = 0; byte is_upper = is_all_upper; diff --git a/lib/Unishox-1.0-shadinger/src/unishox.h b/lib/Unishox-1.0-shadinger/src/unishox.h index d1cda8976..9b6ba1329 100644 --- a/lib/Unishox-1.0-shadinger/src/unishox.h +++ b/lib/Unishox-1.0-shadinger/src/unishox.h @@ -48,6 +48,7 @@ private: uint32_t ol; int32_t bit_no; uint32_t byte_no; + bool in_eof; // have we reached end of file for compressed input const char * in; char * out; size_t len; diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 4b8d81fe7..54e1f63e9 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -5,6 +5,7 @@ - Change IRremoteESP8266 library updated to v2.7.7 - Add command ``Rule0`` to change global rule parameters - Add more functionality to ``Switchmode`` 11 and 12 (#8450) +- Add dump of compressed rules over 512 chars and unishox decompress fix ## Released diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index d23f3e122..25a62d288 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -2017,7 +2017,25 @@ void CmndRule(void) } String rule = GetRule(index - 1); size_t rule_len = rule.length(); - if (rule_len >= MAX_RULE_SIZE) { + if (rule_len > MAX_RULE_SIZE - 3) { + + size_t start_index = 0; // start from 0 + while (start_index < rule_len) { // until we reached end of rule + size_t last_index = start_index + MAX_RULE_SIZE - 3; // set max length to what would fit uncompressed, i.e. MAX_RULE_SIZE - 3 (first NULL + length + last NULL) + if (last_index < rule_len) { // if we didn't reach the end, try to shorten to last space character + int32_t next_index = rule.lastIndexOf(" ", last_index); + if (next_index > 0) { // if space was found and is not at the first position (i.e. we are progressing) + last_index = next_index; // shrink to the last space + } // otherwise it means there are no spaces, we need to cut somewhere even if the result cannot be entered back + } else { + last_index = rule_len; // until the end of the rule + } + AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: Rule%d %s%s"), + index, 0 == start_index ? PSTR("") : PSTR("+"), + rule.substring(start_index, last_index).c_str()); + start_index = last_index + 1; + } + // we need to split the rule in chunks rule = rule.substring(0, MAX_RULE_SIZE); rule += F("..."); From 609e7369bd76e5108ecc84ed63cfde0315017d09 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 21 May 2020 20:54:45 +0200 Subject: [PATCH 037/581] Add safe-guard in getNumFromBits() --- lib/Unishox-1.0-shadinger/src/unishox.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Unishox-1.0-shadinger/src/unishox.cpp b/lib/Unishox-1.0-shadinger/src/unishox.cpp index 9c235582a..743eed38c 100644 --- a/lib/Unishox-1.0-shadinger/src/unishox.cpp +++ b/lib/Unishox-1.0-shadinger/src/unishox.cpp @@ -420,6 +420,7 @@ int32_t Unishox::getNumFromBits(uint32_t count) { while (count--) { ret += getNextBit() << count; } + if (in_eof) return 0; return ret; } From 86921e60b212dc83fdffa0ea975df4e9bfb58679 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 22 May 2020 15:16:01 +0200 Subject: [PATCH 038/581] Add support for VEML6075 and VEML7700 - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) - Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) --- I2CDEVICES.md | 4 ++-- RELEASENOTES.md | 2 ++ tasmota/CHANGELOG.md | 2 ++ tasmota/xsns_70_veml6075.ino | 20 ++++++++++---------- tasmota/xsns_71_veml7700.ino | 11 +++++------ tools/decode-status.py | 11 ++++++----- 6 files changed, 27 insertions(+), 23 deletions(-) diff --git a/I2CDEVICES.md b/I2CDEVICES.md index 008f16c99..788145d3e 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -70,5 +70,5 @@ Index | Define | Driver | Device | Address(es) | Description 46 | USE_IAQ | xsns_66 | IAQ | 0x5a | Air quality sensor 47 | USE_DISPLAY_SEVENSEG| xdsp_11 | HT16K33 | 0x70 - 0x77 | Seven segment LED 48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor - 49 | USE_VEML6075 | xsns_68 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor - 50 | USE_VEML7700 | xsns_69 | VEML7700 | 0x10 | Ambient light intensity sensor \ No newline at end of file + 49 | USE_VEML6075 | xsns_70 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor + 50 | USE_VEML7700 | xsns_71 | VEML7700 | 0x10 | Ambient light intensity sensor \ No newline at end of file diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f2c6ef4f7..ab62c092f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -57,3 +57,5 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change IRremoteESP8266 library updated to v2.7.7 - Add command ``Rule0`` to change global rule parameters - Add more functionality to ``Switchmode`` 11 and 12 (#8450) +- Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) +- Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 54e1f63e9..056a0edd6 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -6,6 +6,8 @@ - Add command ``Rule0`` to change global rule parameters - Add more functionality to ``Switchmode`` 11 and 12 (#8450) - Add dump of compressed rules over 512 chars and unishox decompress fix +- Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) +- Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) ## Released diff --git a/tasmota/xsns_70_veml6075.ino b/tasmota/xsns_70_veml6075.ino index 00a8ebc8e..4735d1140 100644 --- a/tasmota/xsns_70_veml6075.ino +++ b/tasmota/xsns_70_veml6075.ino @@ -1,5 +1,5 @@ /* - xsns_70_veml6075.ino - VEML6075 Franklin Lightning Sensor support for Tasmota + xsns_70_veml6075.ino - VEML6075 UVA/UVB/UVINDEX Sensor support for Tasmota Copyright (C) 2020 Martin Wagner @@ -85,13 +85,13 @@ enum VEML6075_Commands { // commands for Console CMND_VEML6075_SET_HD, CMND_VEML6075_SET_UVIT, }; - + // global variables struct VEML6075STRUCT { char types[9] = D_NAME_VEML6075; uint8_t address = VEML6075_ADDR; - uint8_t inttime = 0; + uint8_t inttime = 0; uint16_t uva = 0; uint16_t uvb = 0; uint16_t uva_raw = 0; @@ -113,9 +113,9 @@ typedef union { uint8_t hd:1; // High dynamic uint8_t inttime:3; // Integration Time uint8_t spare7:1; // spare - }; + }; uint16_t config; -} veml6075configRegister; +} veml6075configRegister; veml6075configRegister veml6075Config; @@ -179,7 +179,7 @@ uint8_t VEML6075GetPwr(void){ return veml6075Config.pwr; } -void VEML6075ReadData(void) +void VEML6075ReadData(void) { veml6075_sensor.uva_raw = VEML6075read16 (VEML6075_REG_UVA); veml6075_sensor.uvb_raw = VEML6075read16 (VEML6075_REG_UVB); @@ -201,7 +201,7 @@ bool VEML6075init(void) void VEML6075Detect(void) { if (I2cActive(veml6075_sensor.address)) return; - + if (VEML6075init()) { I2cSetActiveFound(veml6075_sensor.address, veml6075_sensor.types); VEML6075write16 (VEML6075_REG_CONF, 0x10); // set default @@ -252,7 +252,7 @@ bool VEML6075Cmd(void) { } } -void VEML6075Show(bool json) +void VEML6075Show(bool json) { char s_uvindex[FLOATSZ]; dtostrfd(veml6075_sensor.uvi,1, s_uvindex); @@ -260,10 +260,10 @@ void VEML6075Show(bool json) if (json) { ResponseAppend_P(JSON_SNS_VEML6075, D_NAME_VEML6075, veml6075_sensor.uva, veml6075_sensor.uvb, s_uvindex); #ifdef USE_WEBSERVER - } else { + } else { WSContentSend_PD(HTTP_SNS_UVA, D_NAME_VEML6075, veml6075_sensor.uva); WSContentSend_PD(HTTP_SNS_UVB, D_NAME_VEML6075, veml6075_sensor.uvb); - WSContentSend_PD(HTTP_SNS_UVINDEX, D_NAME_VEML6075 ,s_uvindex); + WSContentSend_PD(HTTP_SNS_UVINDEX, D_NAME_VEML6075 ,s_uvindex); #endif // USE_WEBSERVER } } diff --git a/tasmota/xsns_71_veml7700.ino b/tasmota/xsns_71_veml7700.ino index 89bae9320..de28661cc 100644 --- a/tasmota/xsns_71_veml7700.ino +++ b/tasmota/xsns_71_veml7700.ino @@ -1,5 +1,5 @@ /* - xsns_71_VEML7700.ino - VEML7700 Franklin Lightning Sensor support for Tasmota + xsns_71_VEML7700.ino - VEML7700 Ambient light intensity Sensor support for Tasmota Copyright (C) 2020 Martin Wagner @@ -34,14 +34,13 @@ Adafruit_VEML7700 veml7700 = Adafruit_VEML7700(); //create object copy #define D_NAME_VEML7700 "VEML7700" #define D_WHITE_CONTENT "White content" -const char HTTP_SNS_LUX[] PROGMEM = "{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX " {e}"; const char HTTP_SNS_WHITE[] PROGMEM = "{s}%s " D_WHITE_CONTENT "{m}%d {e}"; const char JSON_SNS_VEML7700[] PROGMEM = ",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d,\"" D_JSON_WHITE_CONTENT "\":%d}"; struct VEML7700STRUCT { char types[9] = D_NAME_VEML7700; - uint8_t address = VEML7700_I2CADDR_DEFAULT; + uint8_t address = VEML7700_I2CADDR_DEFAULT; uint16_t lux = 0; uint16_t white = 0; } veml7700_sensor; @@ -67,13 +66,13 @@ void VEML7700Show(bool json) { if (json) { ResponseAppend_P(JSON_SNS_VEML7700, D_NAME_VEML7700, veml7700_sensor.lux, veml7700_sensor.white); - + #ifdef USE_DOMOTICZ if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, veml7700_sensor.lux); #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER - } else { - WSContentSend_PD(HTTP_SNS_LUX, D_NAME_VEML7700, veml7700_sensor.lux); + } else { + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, D_NAME_VEML7700, veml7700_sensor.lux); WSContentSend_PD(HTTP_SNS_WHITE, D_NAME_VEML7700, veml7700_sensor.white); #endif // USE_WEBSERVER } diff --git a/tools/decode-status.py b/tools/decode-status.py index 748589495..a992a621c 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -147,7 +147,8 @@ a_setoption = [[ "Disable non-json MQTT response", "Enable light fading at start/power on", "Set PWM Mode from regular PWM to ColorTemp control","", - "","","","", + "Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick", + "","","", "","","","", "","","","", "","","","", @@ -195,15 +196,15 @@ a_features = [[ "USE_INA226","USE_A4988_STEPPER","USE_DDS2382","USE_SM2135", "USE_SHUTTER","USE_PCF8574","USE_DDSU666","USE_DEEPSLEEP", "USE_SONOFF_SC","USE_SONOFF_RF","USE_SONOFF_L1","USE_EXS_DIMMER", - "USE_ARDUINO_SLAVE","USE_HIH6","USE_HPMA","USE_TSL2591", + "USE_TASMOTA_SLAVE","USE_HIH6","USE_HPMA","USE_TSL2591", "USE_DHT12","USE_DS1624","USE_GPS","USE_HOTPLUG", "USE_NRF24","USE_MIBLE","USE_HM10","USE_LE01MR", "USE_AHT1x","USE_WEMOS_MOTOR_V1","USE_DEVICE_GROUPS","USE_PWM_DIMMER" ],[ "USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080", "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", - "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","", - "","","","", + "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", + "USE_VEML7700","","","", "","","","", "","","","", "","","","", @@ -241,7 +242,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200507 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200510 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From 855e054db85400f0669a176064720e9949188385 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 22 May 2020 17:48:21 +0200 Subject: [PATCH 039/581] Change Energy JSON data - Bump version 8.3.1.2 - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportActiveTariff":[11.717,16.978]`` - Add Three Phase Export Active Energy to SDM630 driver --- RELEASENOTES.md | 5 ++- tasmota/CHANGELOG.md | 6 +++ tasmota/tasmota_version.h | 2 +- tasmota/xdrv_03_energy.ino | 82 ++++++++++++++++++++++++------------- tasmota/xnrg_08_sdm120.ino | 2 +- tasmota/xnrg_09_dds2382.ino | 2 +- tasmota/xnrg_10_sdm630.ino | 56 +++++++++++++++++-------- tasmota/xnrg_11_ddsu666.ino | 2 +- 8 files changed, 107 insertions(+), 50 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ab62c092f..4ff7a6b16 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,10 +52,13 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.3.1.1 +### Version 8.3.1.2 - Change IRremoteESP8266 library updated to v2.7.7 +- Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` +- Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportActiveTariff":[11.717,16.978]`` - Add command ``Rule0`` to change global rule parameters - Add more functionality to ``Switchmode`` 11 and 12 (#8450) - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) - Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) +- Add Three Phase Export Active Energy to SDM630 driver diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 056a0edd6..09ddf8b4f 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,5 +1,11 @@ ## Unreleased (development) +### 8.3.1.2 20200522 + +- Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` +- Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportActiveTariff":[11.717,16.978]`` +- Add Three Phase Export Active Energy to SDM630 driver + ### 8.3.1.1 20200518 - Change IRremoteESP8266 library updated to v2.7.7 diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index af18e431f..1b21293b2 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08030101; +const uint32_t VERSION = 0x08030102; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index 4210cea1c..7639fb2e8 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -80,10 +80,12 @@ struct ENERGY { float power_factor[3] = { NAN, NAN, NAN }; // 0.12 float frequency[3] = { NAN, NAN, NAN }; // 123.1 Hz +// float import_active[3] = { NAN, NAN, NAN }; // 123.123 kWh + float export_active[3] = { NAN, NAN, NAN }; // 123.123 kWh + float start_energy = 0; // 12345.12345 kWh total previous float daily = 0; // 123.123 kWh float total = 0; // 12345.12345 kWh total energy - float export_active = NAN; // 123.123 KWh unsigned long kWhtoday_delta = 0; // 1212312345 Wh 10^-5 (deca micro Watt hours) - Overflows to Energy.kWhtoday (HLW and CSE only) unsigned long kWhtoday_offset = 0; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = Energy.daily @@ -170,9 +172,18 @@ void EnergyUpdateToday(void) RtcSettings.energy_usage.last_usage_kWhtotal = (uint32_t)(Energy.total * 100000); uint32_t return_diff = 0; - if (!isnan(Energy.export_active)) { - return_diff = (uint32_t)(Energy.export_active * 100000) - RtcSettings.energy_usage.last_return_kWhtotal; - RtcSettings.energy_usage.last_return_kWhtotal = (uint32_t)(Energy.export_active * 100000); + if (!isnan(Energy.export_active[0])) { +// return_diff = (uint32_t)(Energy.export_active * 100000) - RtcSettings.energy_usage.last_return_kWhtotal; +// RtcSettings.energy_usage.last_return_kWhtotal = (uint32_t)(Energy.export_active * 100000); + + float export_active = 0.0; + for (uint32_t i = 0; i < Energy.phase_count; i++) { + if (!isnan(Energy.export_active[i])) { + export_active += Energy.export_active[i]; + } + } + return_diff = (uint32_t)(export_active * 100000) - RtcSettings.energy_usage.last_return_kWhtotal; + RtcSettings.energy_usage.last_return_kWhtotal = (uint32_t)(export_active * 100000); } if (EnergyTariff1Active()) { // Tarrif1 = Off-Peak @@ -466,13 +477,13 @@ void EnergyEverySecond(void) if (!isnan(Energy.reactive_power[i])) { Energy.reactive_power[i] = 0; } if (!isnan(Energy.frequency[i])) { Energy.frequency[i] = 0; } if (!isnan(Energy.power_factor[i])) { Energy.power_factor[i] = 0; } + if (!isnan(Energy.export_active[i])) { Energy.export_active[i] = 0; } data_valid--; } } } if (!data_valid) { - if (!isnan(Energy.export_active)) { Energy.export_active = 0; } Energy.start_energy = 0; XnrgCall(FUNC_ENERGY_RESET); @@ -948,29 +959,31 @@ void EnergyShow(bool json) char voltage_chr[Energy.phase_count][FLOATSZ]; char current_chr[Energy.phase_count][FLOATSZ]; char active_power_chr[Energy.phase_count][FLOATSZ]; + char export_active_chr[Energy.phase_count][FLOATSZ]; for (uint32_t i = 0; i < Energy.phase_count; i++) { dtostrfd(Energy.voltage[i], Settings.flag2.voltage_resolution, voltage_chr[i]); dtostrfd(Energy.current[i], Settings.flag2.current_resolution, current_chr[i]); dtostrfd(Energy.active_power[i], Settings.flag2.wattage_resolution, active_power_chr[i]); + dtostrfd(Energy.export_active[i], Settings.flag2.energy_resolution, export_active_chr[i]); } + char energy_total_chr[FLOATSZ]; + dtostrfd(Energy.total, Settings.flag2.energy_resolution, energy_total_chr); char energy_daily_chr[FLOATSZ]; dtostrfd(Energy.daily, Settings.flag2.energy_resolution, energy_daily_chr); char energy_yesterday_chr[FLOATSZ]; dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr); - char energy_total_chr[3][FLOATSZ]; - dtostrfd(Energy.total, Settings.flag2.energy_resolution, energy_total_chr[0]); - char export_active_chr[3][FLOATSZ]; - dtostrfd(Energy.export_active, Settings.flag2.energy_resolution, export_active_chr[0]); - uint8_t energy_total_fields = 1; + bool energy_tariff = false; + char energy_usage_chr[2][FLOATSZ]; + char energy_return_chr[2][FLOATSZ]; if (Settings.tariff[0][0] != Settings.tariff[1][0]) { - dtostrfd((float)RtcSettings.energy_usage.usage1_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_total_chr[1]); // Tariff1 - dtostrfd((float)RtcSettings.energy_usage.usage2_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_total_chr[2]); // Tariff2 - dtostrfd((float)RtcSettings.energy_usage.return1_kWhtotal / 100000, Settings.flag2.energy_resolution, export_active_chr[1]); // Tariff1 - dtostrfd((float)RtcSettings.energy_usage.return2_kWhtotal / 100000, Settings.flag2.energy_resolution, export_active_chr[2]); // Tariff2 - energy_total_fields = 3; + dtostrfd((float)RtcSettings.energy_usage.usage1_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_usage_chr[0]); // Tariff1 + dtostrfd((float)RtcSettings.energy_usage.usage2_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_usage_chr[1]); // Tariff2 + dtostrfd((float)RtcSettings.energy_usage.return1_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_return_chr[0]); // Tariff1 + dtostrfd((float)RtcSettings.energy_usage.return2_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_return_chr[1]); // Tariff2 + energy_tariff = true; } char value_chr[FLOATSZ *3]; // Used by EnergyFormatIndex @@ -980,15 +993,26 @@ void EnergyShow(bool json) if (json) { bool show_energy_period = (0 == tele_period); - ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"), + ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s"), GetDateAndTime(DT_ENERGY).c_str(), - EnergyFormatIndex(value_chr, energy_total_chr[0], json, energy_total_fields), + energy_total_chr); + + if (energy_tariff) { + ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL D_CMND_TARIFF "\":%s"), + EnergyFormatIndex(value_chr, energy_usage_chr[0], json, 2)); + } + + ResponseAppend_P(PSTR(",\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"), energy_yesterday_chr, energy_daily_chr); - if (!isnan(Energy.export_active)) { + if (!isnan(Energy.export_active[0])) { ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"), - EnergyFormatIndex(value_chr, export_active_chr[0], json, energy_total_fields)); + EnergyFormat(value_chr, export_active_chr[0], json)); + if (energy_tariff) { + ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE D_CMND_TARIFF "\":%s"), + EnergyFormatIndex(value_chr, energy_return_chr[0], json, 2)); + } } if (show_energy_period) { @@ -1028,14 +1052,14 @@ void EnergyShow(bool json) #ifdef USE_DOMOTICZ if (show_energy_period) { // Only send if telemetry - dtostrfd(Energy.total * 1000, 1, energy_total_chr[0]); - DomoticzSensorPowerEnergy((int)Energy.active_power[0], energy_total_chr[0]); // PowerUsage, EnergyToday + dtostrfd(Energy.total * 1000, 1, energy_total_chr); + DomoticzSensorPowerEnergy((int)Energy.active_power[0], energy_total_chr); // PowerUsage, EnergyToday - dtostrfd((float)RtcSettings.energy_usage.usage1_kWhtotal / 100, 1, energy_total_chr[1]); // Tariff1 - dtostrfd((float)RtcSettings.energy_usage.usage2_kWhtotal / 100, 1, energy_total_chr[2]); // Tariff2 - dtostrfd((float)RtcSettings.energy_usage.return1_kWhtotal / 100, 1, export_active_chr[1]); - dtostrfd((float)RtcSettings.energy_usage.return2_kWhtotal / 100, 1, export_active_chr[2]); - DomoticzSensorP1SmartMeter(energy_total_chr[1], energy_total_chr[2], export_active_chr[1], export_active_chr[2], (int)Energy.active_power[0]); + dtostrfd((float)RtcSettings.energy_usage.usage1_kWhtotal / 100, 1, energy_usage_chr[0]); // Tariff1 + dtostrfd((float)RtcSettings.energy_usage.usage2_kWhtotal / 100, 1, energy_usage_chr[1]); // Tariff2 + dtostrfd((float)RtcSettings.energy_usage.return1_kWhtotal / 100, 1, energy_return_chr[0]); + dtostrfd((float)RtcSettings.energy_usage.return2_kWhtotal / 100, 1, energy_return_chr[1]); + DomoticzSensorP1SmartMeter(energy_usage_chr[0], energy_usage_chr[1], energy_return_chr[0], energy_return_chr[1], (int)Energy.active_power[0]); if (Energy.voltage_available) { DomoticzSensor(DZ_VOLTAGE, voltage_chr[0]); // Voltage @@ -1082,9 +1106,9 @@ void EnergyShow(bool json) EnergyFormat(value_chr, frequency_chr[0], json, Energy.voltage_common)); } } - WSContentSend_PD(HTTP_ENERGY_SNS2, energy_daily_chr, energy_yesterday_chr, energy_total_chr[0]); - if (!isnan(Energy.export_active)) { - WSContentSend_PD(HTTP_ENERGY_SNS3, export_active_chr[0]); + WSContentSend_PD(HTTP_ENERGY_SNS2, energy_daily_chr, energy_yesterday_chr, energy_total_chr); + if (!isnan(Energy.export_active[0])) { + WSContentSend_PD(HTTP_ENERGY_SNS3, EnergyFormat(value_chr, export_active_chr[0], json)); } XnrgCall(FUNC_WEB_SENSOR); diff --git a/tasmota/xnrg_08_sdm120.ino b/tasmota/xnrg_08_sdm120.ino index 93af326f8..8f764ad52 100644 --- a/tasmota/xnrg_08_sdm120.ino +++ b/tasmota/xnrg_08_sdm120.ino @@ -134,7 +134,7 @@ void SDM120Every250ms(void) break; case 9: - Energy.export_active = value; // 6.216 kWh + Energy.export_active[0] = value; // 6.216 kWh break; case 10: diff --git a/tasmota/xnrg_09_dds2382.ino b/tasmota/xnrg_09_dds2382.ino index a516ea4a8..7acb36f05 100644 --- a/tasmota/xnrg_09_dds2382.ino +++ b/tasmota/xnrg_09_dds2382.ino @@ -74,7 +74,7 @@ void Dds2382EverySecond(void) if (Settings.flag3.dds2382_model) { // SetOption71 - Select different Modbus registers for Active Energy (#6531) offset = 19; } - Energy.export_active = (float)((buffer[offset] << 24) + (buffer[offset +1] << 16) + (buffer[offset +2] << 8) + buffer[offset +3]) / 100.0; // 429496.729 kW + Energy.export_active[0] = (float)((buffer[offset] << 24) + (buffer[offset +1] << 16) + (buffer[offset +2] << 8) + buffer[offset +3]) / 100.0; // 429496.729 kW float import_active = (float)((buffer[offset +4] << 24) + (buffer[offset +5] << 16) + (buffer[offset +6] << 8) + buffer[offset +7]) / 100.0; // 429496.729 kW EnergyUpdateTotal(import_active, true); // 484.708 kWh diff --git a/tasmota/xnrg_10_sdm630.ino b/tasmota/xnrg_10_sdm630.ino index 4bfeecc96..026c3b4e8 100644 --- a/tasmota/xnrg_10_sdm630.ino +++ b/tasmota/xnrg_10_sdm630.ino @@ -40,22 +40,30 @@ TasmotaModbus *Sdm630Modbus; const uint16_t sdm630_start_addresses[] { - 0x0000, // L1 - SDM630_VOLTAGE [V] - 0x0002, // L2 - SDM630_VOLTAGE [V] - 0x0004, // L3 - SDM630_VOLTAGE [V] - 0x0006, // L1 - SDM630_CURRENT [A] - 0x0008, // L2 - SDM630_CURRENT [A] - 0x000A, // L3 - SDM630_CURRENT [A] - 0x000C, // L1 - SDM630_POWER [W] - 0x000E, // L2 - SDM630_POWER [W] - 0x0010, // L3 - SDM630_POWER [W] - 0x0018, // L1 - SDM630_REACTIVE_POWER [VAR] - 0x001A, // L2 - SDM630_REACTIVE_POWER [VAR] - 0x001C, // L3 - SDM630_REACTIVE_POWER [VAR] - 0x001E, // L1 - SDM630_POWER_FACTOR - 0x0020, // L2 - SDM630_POWER_FACTOR - 0x0022, // L3 - SDM630_POWER_FACTOR - 0x0156 // Total - SDM630_TOTAL_ACTIVE_ENERGY [Wh] + // 3P4 3P3 1P2 Unit Description + 0x0000, // + - + V Phase 1 line to neutral volts + 0x0002, // + - - V Phase 2 line to neutral volts + 0x0004, // + - - V Phase 3 line to neutral volts + 0x0006, // + + + A Phase 1 current + 0x0008, // + + - A Phase 2 current + 0x000A, // + + - A Phase 3 current + 0x000C, // + - + W Phase 1 power + 0x000E, // + - + W Phase 2 power + 0x0010, // + - - W Phase 3 power + 0x0018, // + - + VAr Phase 1 volt amps reactive + 0x001A, // + - - VAr Phase 2 volt amps reactive + 0x001C, // + - - VAr Phase 3 volt amps reactive + 0x001E, // + - + Phase 1 power factor + 0x0020, // + - - Phase 2 power factor + 0x0022, // + - - Phase 3 power factor + 0x0046, // + + + Hz Frequency of supply voltages + 0x0160, // + + + kWh Phase 1 export active energy + 0x0162, // + + + kWh Phase 2 export active energy + 0x0164, // + + + kWh Phase 3 export active energy +// 0x015A, // + + + kWh Phase 1 import active energy +// 0x015C, // + + + kWh Phase 2 import active energy +// 0x015E, // + + + kWh Phase 3 import active energy + 0x0156 // + + + kWh Total active energy }; struct SDM630 { @@ -153,6 +161,22 @@ void SDM630Every250ms(void) break; case 15: + Energy.frequency[0] = value; + break; + + case 16: + Energy.export_active[0] = value; + break; + + case 17: + Energy.export_active[1] = value; + break; + + case 18: + Energy.export_active[2] = value; + break; + + case 19: EnergyUpdateTotal(value, true); break; } diff --git a/tasmota/xnrg_11_ddsu666.ino b/tasmota/xnrg_11_ddsu666.ino index 87b585d84..f01ad50a5 100644 --- a/tasmota/xnrg_11_ddsu666.ino +++ b/tasmota/xnrg_11_ddsu666.ino @@ -110,7 +110,7 @@ void DDSU666Every250ms(void) break; case 7: - Energy.export_active = value; // 6.216 kWh + Energy.export_active[0] = value; // 6.216 kWh break; } From 93ca102391998e03dbe583cda2b64772e955eb01 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 22 May 2020 18:31:14 +0200 Subject: [PATCH 040/581] Change ExportActiveTariff to ExportTariff --- RELEASENOTES.md | 2 +- tasmota/CHANGELOG.md | 2 +- tasmota/i18n.h | 1 + tasmota/xdrv_03_energy.ino | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 4ff7a6b16..07406b54f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -56,7 +56,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change IRremoteESP8266 library updated to v2.7.7 - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` -- Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportActiveTariff":[11.717,16.978]`` +- Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Add command ``Rule0`` to change global rule parameters - Add more functionality to ``Switchmode`` 11 and 12 (#8450) - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 09ddf8b4f..b4c77c4ab 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,7 +3,7 @@ ### 8.3.1.2 20200522 - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` -- Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportActiveTariff":[11.717,16.978]`` +- Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Add Three Phase Export Active Energy to SDM630 driver ### 8.3.1.1 20200518 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 698192e99..b0b0cd666 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -65,6 +65,7 @@ #define D_JSON_ERROR "Error" #define D_JSON_EVENT "Event" #define D_JSON_EVERY "Every" +#define D_JSON_EXPORT "Export" #define D_JSON_EXPORT_ACTIVE "ExportActive" #define D_JSON_EXPORT_REACTIVE "ExportReactive" #define D_JSON_FAILED "Failed" diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index 7639fb2e8..2caaaa292 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -1010,7 +1010,7 @@ void EnergyShow(bool json) ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"), EnergyFormat(value_chr, export_active_chr[0], json)); if (energy_tariff) { - ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE D_CMND_TARIFF "\":%s"), + ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT D_CMND_TARIFF "\":%s"), EnergyFormatIndex(value_chr, energy_return_chr[0], json, 2)); } } From 7ee9b2d34d06a3d3e42c6c2871a73c642a7884ac Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 22 May 2020 22:14:17 +0200 Subject: [PATCH 041/581] Compressed string in Wemo emulation --- lib/Unishox-1.0-shadinger/src/unishox.cpp | 17 +++-- tasmota/support.ino | 34 +++++++++- tasmota/xdrv_10_rules.ino | 15 +---- tasmota/xdrv_21_wemo.ino | 82 +++++++++++++++++++++-- 4 files changed, 123 insertions(+), 25 deletions(-) diff --git a/lib/Unishox-1.0-shadinger/src/unishox.cpp b/lib/Unishox-1.0-shadinger/src/unishox.cpp index 743eed38c..286a16280 100644 --- a/lib/Unishox-1.0-shadinger/src/unishox.cpp +++ b/lib/Unishox-1.0-shadinger/src/unishox.cpp @@ -388,9 +388,9 @@ uint32_t Unishox::getNextBit(void) { in_eof = true; return 1; // return only 1s, which appends 'r' in worst case } - byte_in = in[byte_no++]; + byte_in = pgm_read_byte(&in[byte_no++]); if (ESCAPE_MARKER == byte_in) { - byte_in = in[byte_no++] - 1; // we shouldn't need to test if byte_no >= len, because it should not be possible to end with ESCAPE_MARKER + byte_in = pgm_read_byte(&in[byte_no++]) - 1; // we shouldn't need to test if byte_no >= len, because it should not be possible to end with ESCAPE_MARKER } bit_no = 0; } @@ -479,6 +479,9 @@ int32_t Unishox::unishox_decompress(const char *p_in, size_t p_len, char *p_out, out[ol] = 0; // while ((byte_no << 3) + bit_no - 8 < len) { while (!in_eof) { + if (ol >= len_out) { + break; + } int32_t h, v; char c = 0; byte is_upper = is_all_upper; @@ -564,11 +567,11 @@ int32_t Unishox::unishox_decompress(const char *p_in, size_t p_len, char *p_out, } } out[ol++] = c; - - if (ol >= len_out) { - return -1; // overflow - } } - return ol; + if (ol > len_out) { + return -1; // overflow + } else { + return ol; + } } diff --git a/tasmota/support.ino b/tasmota/support.ino index 271ad81fe..a053b6c34 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1931,4 +1931,36 @@ String escapeJSONString(const char *str) { } return r; -} \ No newline at end of file +} + +/*********************************************************************************************\ + * Uncompress static PROGMEM strings +\*********************************************************************************************/ + +#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) + +#include + +Unishox compressor; + +String decompress(const char * compressed, size_t uncompressed_size) { + String content(""); + + uncompressed_size += 2; // take a security margin + + // We use a nasty trick here. To avoid allocating twice the buffer, + // we first extend the buffer of the String object to the target size (maybe overshooting by 7 bytes) + // then we decompress in this buffer, + // and finally assign the raw string to the String, which happens to work: String uses memmove(), so overlapping works + content.reserve(uncompressed_size); + char * buffer = content.begin(); + + int32_t len = compressor.unishox_decompress(compressed, strlen_P(compressed), buffer, uncompressed_size); + if (len > 0) { + buffer[len] = 0; // terminate string with NULL + content = buffer; // copy in place + } + return content; +} + +#endif // defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) \ No newline at end of file diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 25a62d288..7dcc90498 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -213,7 +213,7 @@ char rules_vars[MAX_RULE_VARS][33] = {{ 0 }}; #ifdef USE_RULES_COMPRESSION // Statically allocate one String per rule String k_rules[MAX_RULE_SETS] = { String(), String(), String() }; // Strings are created empty -Unishox compressor; // singleton +// Unishox compressor; // singleton #endif // USE_RULES_COMPRESSION // Returns whether the rule is uncompressed, which means the first byte is not NULL @@ -263,18 +263,7 @@ void GetRule_decompress(String &rule, const char *rule_head) { size_t buf_len = 1 + *rule_head * 8; // the first byte contains size of buffer for uncompressed rule / 8, buf_len may overshoot by 7 rule_head++; // advance to the actual compressed buffer - // We use a nasty trick here. To avoid allocating twice the buffer, - // we first extend the buffer of the String object to the target size (maybe overshooting by 7 bytes) - // then we decompress in this buffer, - // and finally assign the raw string to the String, which happens to work: String uses memmove(), so overlapping works - rule.reserve(buf_len); - char* buf = rule.begin(); - - int32_t len_decompressed = compressor.unishox_decompress(rule_head, strlen(rule_head), buf, buf_len); - buf[len_decompressed] = 0; // add NULL terminator - - // AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: Rawdecompressed: %d"), len_decompressed); - rule = buf; // assign the raw string to the String object (in reality re-writing the same data in the same place) + rule = decompress(rule_head, buf_len); } #endif // USE_RULES_COMPRESSION diff --git a/tasmota/xdrv_21_wemo.ino b/tasmota/xdrv_21_wemo.ino index fb123d4ab..20236df6e 100644 --- a/tasmota/xdrv_21_wemo.ino +++ b/tasmota/xdrv_21_wemo.ino @@ -85,6 +85,79 @@ void WemoRespondToMSearch(int echo_type) * Wemo web server additions \*********************************************************************************************/ +#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) + +//SetBinaryStateBinaryStateBinaryStateinGetBinaryStateBinaryStateBinaryStateoutBinaryStatebool0levelstring0\r\n\r\n +//Successfully compressed from 779 to 249 bytes (-68%) +const size_t WEMO_EVENTSERVICE_XML_size = 779; +const char WEMO_EVENTSERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\xE3\xE1\xEC\x17\xFE\x3C\xC8\x73\x08\xD3\x78\xF3" + "\xF3\xF9\x9E\x86\xCE\xB3\x90\xEB\x67\xB0\xFC\x3D\x0A\xC3\xAD\xCE\x20\xB7\xD4\x08" + "\x72\x0F\xC3\xD3\xAC\x6B\x3F\x0B\xCE\x88\x76\xF5\xFC\xC8\xBD\x57\x4C\xF4\x3B\x3A" + "\xC6\xB3\xF0\xF4\xBF\x8F\x0B\x1A\xFA\x81\x0B\x0D\x04\x29\x47\xE1\xE9\xF7\x46\x76" + "\x11\xD8\x08\x58\xC0\x27\x62\xBF\x61\x5D\x31\x0B\xD5\x74\xC8\xCE\xFF\xB6\x38\x20" + "\x4A\xC1\x01\x42\xF1\xE8\x26\xFD\x82\x0E\xE7\xBC\x7A\x1D\x80\x8B\x28\xF4\x3B\x01" + "\x17\x59\x04\x48\xE0\x83\xB9\x1D\x80\x87\xC1\x20\x24\x70\x58\x43\xC0\xDA\xF8\x2C" + "\xC1\x74\x0C\x2F\x82\xD0\x42\x8A\x08\x34\x81\x0B\x92\x42\xF5\x5D\x32\xA0\x41\xCE" + "\x7C\x08\xFA\x42\xF3\xE1\x09\x99\xBE\xAF\x1F\x0F\x61\x93\xF1\xEC\x05\x5E\x0A\x44" + "\xBA\xB2\xA3\x21\x8C\xFC\x1D\x98\x11\xE8\x76\x02\x24\xB3\xD0\x46\x62\xC5\x85\x44" + "\x67\x61\x0B\x67\xE1\xC6\x7A\x1D\x84\x09\x13\x0F\x43\xB0\x12\x34\xC0\x60\x5A\xD8" + "\x4C\xCD\x84\x09\x9A\xAF\xAB\xFB\xC3\xC0\xC5\x75\x73\xB0\x13\xB8\x6A\x3B\x3C\x18" + "\xC1\x0F\xC9\xC2\x91\xBA\x70\xA4\x6E"; + +//10GetMetaInfoGetMetaInfoMetaInfoinMetaInfostring0\r\n\r\n +//Successfully compressed from 479 to 253 bytes (-47.2%) +const size_t WEMO_METASERVICE_XML_size = 479; +const char WEMO_METASERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\xE3\xE1\xEC\x17\xFE\x3C\xC8\x73\x08\xD3\x78\xF3" + "\xF3\xF9\x9E\x86\xCE\xB3\x90\xEB\x67\xB0\xFC\x3D\x0B\xC3\x18\x64\x66\xFF\xED\xCE" + "\x3F\x0F\x41\xB6\x6B\xCF\x9F\x87\x21\xE8\x76\x10\x20\xC5\x3D\x06\xEF\x67\xCF\xC3" + "\x8C\xF4\x3B\x08\x10\x62\x9E\x87\x60\x24\x61\x56\x1D\x6E\x71\x05\xBE\xA0\x43\x90" + "\x7E\x1E\x9D\x63\x59\xF8\x43\xCE\x88\x6B\xAB\x2D\xE3\x18\x7A\x1D\x9D\x63\x59\xF8" + "\x7A\x5F\xC7\x85\x8D\x7D\x40\x83\x85\x7D\xD1\x9D\x84\x8E\xC0\x55\xC3\x3E\xC2\xBA" + "\x62\x17\xAA\xE9\x91\x9D\xFF\x6C\x70\x4C\xFC\x04\x5C\x04\x14\x2D\x9E\x82\x6F\xD8" + "\x20\xEC\x9B\xC7\xA1\xD8\x08\xB2\x8F\x43\xB0\x12\x75\xB3\xB0\x10\xF8\x0A\x04\x28" + "\xA0\x83\x48\x10\xB8\x74\x2F\x55\xD3\x2A\x2B\x04\x1C\xB7\xC0\x8F\x9E\x2F\x3E\x10" + "\x99\x9B\xEA\xF1\xF0\xF6\x19\x3F\x1E\xC0\x42\xE0\x68\x12\xF8\x17\x12\xEA\xCA\x8C" + "\x86\x33\xF3\xD5\xFD\xE1\xE3\xD0\xEC\x04\x49\xA7\xA0\x8C\xC5\x8B\x0A\x88\xCE\xC2" + "\x16\xCF\xC3\x8C\xF4\x3B\x08\x12\x26\x1E\x87\x60\x24\x69\x67\xE1\xE8\x76\x02\x76" + "\xDC\x76\x78\x31\x82\x1F\x93\x85\x23\x74\xE1\x48\xDC"; + +//%d\r\n +//Successfully compressed from 282 to 161 bytes (-42.9%) +const size_t WEMO_RESPONSE_STATE_SOAP_size = 282; +const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM = "\x3D\x3C\x79\x93\xE3\x36\x16\x0C\x68\xD8\x34\x2E\xF1\xE7\xE3\xE1\xEC\x15\x54\x30" + "\xF3\x3B\x0E\xCF\x06\x29\x8D\xBF\x1D\x0D\x83\x42\xF6\x58\xC3\xA6\x7C\x78\xEC\xF6" + "\x58\xC3\xB1\x82\x16\x1C\x76\x1E\xC5\xE3\xCD\xF0\x78\x26\xF0\xF1\x7A\x8C\x82\x60" + "\xBF\x8C\x02\x0E\x16\x76\x1E\xC3\xF0\xF4\xF1\xE6\x43\xB0\x43\x23\xF0\xF4\x16\x79" + "\x9F\x41\xBA\x21\xDB\xD7\xF3\x22\xF5\x5D\x32\xFB\xF0\xCC\xEF\x02\x1E\xDE\x2C\xF8" + "\x7B\x05\xFF\x8F\x32\x1C\xC2\x34\xDE\x3C\xFC\xFE\x67\xA1\xB3\xCC\x75\xFB\x43\x66" + "\x6F\xA8\xF3\x39\x0F\x61\xF8\x7A\x10\x23\x63\x67\xE1\xF4\x21\xE8\x76\x02\x3C\xC3" + "\xD0\xEC\x05\x4C\xFC\xFC\x3D\x0E\xC0\x43\xD8\xCE\xC0\x45\xE1\xA0\xFC\x9C\x29\x1B" + "\x8D"; + +//urn:Belkin:device:controllee:1{x1Belkin International Inc.Socket3.1415uuid:{x2{x30urn:Belkin:service:basicevent:1urn:Belkin:serviceId:basicevent1/upnp/control/basicevent1/upnp/event/basicevent1/eventservice.xmlurn:Belkin:service:metainfo:1urn:Belkin:serviceId:metainfo1/upnp/control/metainfo1/upnp/event/metainfo1/metainfoservice.xml\r\n +//Successfully compressed from 923 to 392 bytes (-57.5%) +const size_t WEMO_SETUP_XML_size = 923; +const char WEMO_SETUP_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E" + "\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\x21\xCC\x23\x4D\xE3\xCC\x46" + "\x67\xA1\xB3\xAC\xE4\x3A\xD9\xEC\x3F\x0F\x42\x04\x19\x20\x87\x10\xA8\xC8\x63\x3F" + "\x01\x33\x07\x3C\xC3\xCE\xAF\xE0\x41\x36\x79\x9C\x87\xA1\xD8\x40\x8D\x83\x9E\x86" + "\x3F\xAF\x84\x08\xC8\xBA\xC6\xB3\xF0\xF6\x9B\x0E\x43\xD0\xEC\x20\x48\x9C\x7A\x0D" + "\xBE\x16\x62\xC3\xA1\x7F\x7F\x3F\x01\x07\x31\x45\xBD\x4F\xFD\x75\xB9\xD6\x12\x2D" + "\xE0\xCE\x87\xA1\xD8\x09\x18\x21\xE8\x37\x04\x61\x17\x58\xD6\x7E\x17\xB0\x33\x47" + "\x47\xA1\xD8\x08\xB3\x81\x0A\xC8\xB1\xA3\x9F\xCF\xC3\x96\x74\x99\x34\x81\x0E\xD8" + "\x20\xD0\x3D\x08\x59\x08\x5C\x7E\x0B\x17\xA2\x1E\x67\xB4\xD8\x72\x8F\x43\xB0\x88" + "\x59\x08\x5C\x7E\x1E\x9E\x7F\xDB\x04\x3B\xA7\xB4\xD8\x72\xCF\x43\xB0\x81\x22\x71" + "\xE8\x3B\x7A\xFE\x64\x5E\xAB\xA6\x7E\x1C\x67\xA1\xD8\x40\x8F\x2C\xF4\xF3\xF9\x9E" + "\x86\xC8\x2D\xF5\x02\x24\x90\x44\x8A\x09\x7C\x46\x82\x15\x33\xCC\x75\xFB\x43\x66" + "\x6F\xA8\xF3\x39\x0F\x43\xB0\x81\x1F\x09\x04\x3C\x58\xB4\x40\x4E\xC5\x0B\x44\x04" + "\x6C\x58\x11\x71\x52\xD1\x0F\xC3\xD0\x10\xB8\xE0\x21\x65\xF2\x08\xFC\x3B\x05\x8C" + "\xE1\x87\x60\x21\x4D\x3B\x01\x23\x0D\x04\x6C\x08\xF4\x66\x6F\xA8\xBC\x2C\x70\x22" + "\xE1\xEC\xCD\xF5\x02\x4E\x1A\x08\xF8\x09\xE8\x45\xE0\xC6\x08\x2F\xE1\x11\xF8\x08" + "\x34\x81\x0B\x59\x3A\x1B\x06\x84\x7A\x1D\x80\x87\x5C\x11\x37\x2A\x01\x60\xBC\x34" + "\x0D\x75\x7B\xC6\x30\x18\x5F\x0C\xC0\x87\x8A\x03\x02\xE1\x90\x11\xB0\xB0\x5F\xE1" + "\x88\x11\xB0\xB0\x51\xE1\x80\x10\xEE\x82\xDF\x0C\x60\x87\x18\x10\x79\x7D\x04\x2E" + "\x83\xD1\xF8\x7A\x1D\x9F\xCC\xA3\xF2\x70\xA4\x6E"; +#else const char WEMO_EVENTSERVICE_XML[] PROGMEM = "" "" @@ -190,6 +263,7 @@ const char WEMO_SETUP_XML[] PROGMEM = "" "" "\r\n"; +#endif /********************************************************************************************/ @@ -219,7 +293,7 @@ void HandleUpnpEvent(void) } } - snprintf_P(event, sizeof(event), WEMO_RESPONSE_STATE_SOAP, state, bitRead(power, devices_present -1), state); + snprintf_P(event, sizeof(event), decompress(WEMO_RESPONSE_STATE_SOAP, WEMO_RESPONSE_STATE_SOAP_size).c_str(), state, bitRead(power, devices_present -1), state); WSSend(200, CT_XML, event); } @@ -227,21 +301,21 @@ void HandleUpnpService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_EVENT_SERVICE)); - WSSend(200, CT_PLAIN, FPSTR(WEMO_EVENTSERVICE_XML)); + WSSend(200, CT_PLAIN, decompress(WEMO_EVENTSERVICE_XML, WEMO_EVENTSERVICE_XML_size)); } void HandleUpnpMetaService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_META_SERVICE)); - WSSend(200, CT_PLAIN, FPSTR(WEMO_METASERVICE_XML)); + WSSend(200, CT_PLAIN, decompress(WEMO_METASERVICE_XML, WEMO_METASERVICE_XML_size)); } void HandleUpnpSetupWemo(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_SETUP)); - String setup_xml = FPSTR(WEMO_SETUP_XML); + String setup_xml = decompress(WEMO_SETUP_XML, WEMO_SETUP_XML_size); setup_xml.replace("{x1", SettingsText(SET_FRIENDLYNAME1)); setup_xml.replace("{x2", WemoUuid()); setup_xml.replace("{x3", WemoSerialnumber()); From 45b83a8c7729fa64bf9ae10ea14cfe9951582e48 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 22 May 2020 22:54:34 +0200 Subject: [PATCH 042/581] Compression candidates for Hue emulation --- tasmota/xdrv_20_hue.ino | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index 122166010..639f198bb 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -114,6 +114,29 @@ void HueRespondToMSearch(void) * Hue web server additions \*********************************************************************************************/ +//10http://{x1:80/urn:schemas-upnp-org:device:Basic:1Amazon-Echo-HA-Bridge ({x1)Royal Philips Electronicshttp://www.philips.comPhilips hue Personal Wireless LightingPhilips hue bridge 2012929000226503{x3uuid:{x2\r\n\r\n +//Successfully compressed from 625 to 391 bytes (-37.4%) +// const size_t HUE_DESCRIPTION_XML_size = 625; +// const char HUE_DESCRIPTION_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E" +// "\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\xF0\x62\x98\xDB\xF1\xD6\x2C" +// "\x67\x0C\x3A\xF3\xE3\xC7\x98\x8C\xCF\x43\x67\x59\xC8\x75\xB3\xD8\x7E\x1E\x85\xE1" +// "\x8C\x32\x33\x04\x1C\x78\xFC\x3D\x06\xD9\xAF\x3E\x7E\x1C\x87\xA1\xD8\x40\x83\x14" +// "\xF4\x1B\xBD\x9F\x3F\x0E\x33\xD0\xEC\x20\x41\x8A\x7A\x1D\x80\x91\x85\x10\xB2\xF9" +// "\x04\x43\xAF\xCC\xFC\x15\x54\x30\xF3\x3B\x0E\xC3\xDA\x6C\x39\x0F\x3F\xB3\xB0\xF4" +// "\x3B\x08\x10\xEA\x1E\x80\x83\xA2\x82\x1C\x42\xA3\x21\x8C\xFC\x05\x6D\xB4\xF3\x21" +// "\xD7\xED\x0C\xF3\x39\x0F\x43\xB0\x81\x1B\x0C\x3D\x0C\x7F\x5F\x08\x11\x91\x75\x8D" +// "\x67\xE1\x58\xDB\x36\xE7\x1D\x64\xC3\x15\x87\x59\x0A\x2B\x3A\xC8\x77\xF4\x41\xE6" +// "\x8E\xE9\xED\x36\x1C\x87\x78\xF4\x3B\x08\x12\x30\x63\xD0\x6D\xF0\xB3\x16\x1D\x0B" +// "\xFB\xF9\xF8\x5F\xC3\x2B\x09\x10\xC1\x5A\x16\x8C\xF2\x26\x13\x0E\xBF\x9D\xA1\xF8" +// "\xF4\x3B\x01\x23\x04\x04\x8C\x48\x85\x97\xC8\x20\x43\xE0\xDC\x7C\x7C\x7C\xE8\x30" +// "\x10\x71\xA3\xA0\x78\x34\x12\x71\x22\x16\x5F\x20\x8F\xC3\xD0\x6E\x08\xC2\x21\x1F" +// "\x83\xFE\x8C\xAD\xCE\x3F\x01\x0F\x49\x14\x2D\xA2\x18\xFF\xEC\xEB\x09\x10\xFE\xFD" +// "\x84\xFD\xE4\x41\x68\xF0\xAA\xDE\x1E\x3D\x0E\xC0\x4C\xC5\x41\x07\x27\x2E\xB1\xAC" +// "\x12\x32\x01\xC0\x83\xC2\x41\xCA\x72\x88\x10\xB1\x10\x42\xE1\x13\x04\x61\x17\x0B" +// "\x1A\x39\xFC\xFC\x38\xA9\x36\xEA\xBB\x5D\x90\x21\xE0\x20\x83\x58\xF4\xF3\xFE\xD8" +// "\x21\xCA\x3D\xA6\xC3\x96\x7A\x1D\x84\x09\x13\x8F\x42\x16\x42\x17\x1F\x82\xC5\xE8" +// "\x87\x99\xED\x36\x1C\xA3\xD0\xEC\x22\x16\x42\x17\x1F\x80\x87\xC7\x19\xF8\x7A\x1D" +// "\x9F\xCC\xA3\xF2\x70\xA4\x6E\x9C\x29\x1B\x8D"; const char HUE_DESCRIPTION_XML[] PROGMEM = "" "" @@ -137,22 +160,59 @@ const char HUE_DESCRIPTION_XML[] PROGMEM = "" "\r\n" "\r\n"; + +//%s"alert":"none","effect":"none","reachable":true} +//Successfully compressed from 50 to 34 bytes (-32%) +// const size_t HUE_LIGHTS_STATUS_JSON1_SUFFIX_size = 50; +// const char HUE_LIGHTS_STATUS_JSON1_SUFFIX[] PROGMEM = "\x3E\xBC\x7B\x2C\x27\xFA\x3D\x87\x99\xEC\xEC\xE6\x7B\x0E\xA3\xD8\xCC\x18\x61\x82" +// "\x34\xCF\xBB\x0C\x55\x8E\x09\x9E\xC3\xCE\xBE\x2D\x9E\xE3"; const char HUE_LIGHTS_STATUS_JSON1_SUFFIX[] PROGMEM = "%s\"alert\":\"none\"," "\"effect\":\"none\"," "\"reachable\":true}"; + +//,"type":"Extended color light","name":"%s","modelid":"%s","manufacturername":"%s","uniqueid":"%s"} +//Successfully compressed from 98 to 64 bytes (-34.7%) +// const size_t HUE_LIGHTS_STATUS_JSON2_size = 98; +// const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM = "\x3A\x8F\x65\x19\x0C\x67\xB0\xF3\x3D\x84\xCD\x94\xF8\x46\x22\x0F\x02\xCF\xA0\xB4" +// "\x78\x55\x1E\xC3\xA8\xF6\x75\x8D\x67\xB0\xF3\x3D\x87\xD7\x8F\x61\xD4\x7B\x06\xE0" +// "\x8C\x2D\x10\x11\x25\xDF\x0B\x31\x61\xD0\xBF\xBF\x82\x3E\x06\x2F\xB4\xD4\x2D\x82" +// "\x1E\x08\x7B\x8D"; const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM = ",\"type\":\"Extended color light\"," "\"name\":\"%s\"," "\"modelid\":\"%s\"," "\"manufacturername\":\"%s\"," "\"uniqueid\":\"%s\"}"; + +//{"name":"Group 0","lights":[{l1],"type":"LightGroup","action": +//Successfully compressed from 62 to 61 bytes (-1.6%) const char HUE_GROUP0_STATUS_JSON[] PROGMEM = "{\"name\":\"Group 0\"," "\"lights\":[{l1]," "\"type\":\"LightGroup\"," "\"action\":"; // "\"scene\":\"none\","; + +//{"name":"Philips hue","mac":"{ma","dhcp":true,"ipaddress":"{ip","netmask":"{ms","gateway":"{gw","proxyaddress":"none","proxyport":0,"bridgeid":"{br","UTC":"{dt","whitelist":{"{id":{"last use date":"{dt","create date":"{dt","name":"Remote"}},"swversion":"01041302","apiversion":"1.17.0","swupdate":{"updatestate":0,"url":"","text":"","notify": false},"linkbutton":false,"portalservices":false} +//Successfully compressed from 392 to 302 bytes (-23%) +// const size_t HueConfigResponse_JSON_size = 392; +// const char HueConfigResponse_JSON[] PROGMEM = "\x3D\xA7\xB3\xAC\x6B\x3D\x87\x99\xEC\x21\x82\xB4\x2D\x19\xE4\x28\x5B\x3D\x87\x51" +// "\xEC\x1B\x61\x9E\xC3\xCC\xF6\x1E\xD1\xB6\x7B\x0E\xA3\xD8\x20\xA0\xC6\x1E\xC3\xCE" +// "\xBE\x2D\x9D\x47\xB3\x46\x58\x82\x7D\xFB\xC7\xB0\xF3\x3D\x87\xB7\x46\x1E\xC3\xA8" +// "\xF6\x73\xA1\xB7\xE3\x43\xD8\x79\x9E\xC3\xDA\x37\xC7\xB0\xEA\x3D\x83\xD7\x4C\x7E" +// "\xCC\x8F\x61\xE6\x7B\x0F\x68\xF0\xF9\xEC\x3A\x8F\x60\xCF\xE1\xB0\xC8\x11\x71\x1E" +// "\xCE\x60\x87\x48\x66\x7E\x8F\x61\xE6\x71\x9D\x47\xB0\x87\x7F\x44\x1E\x7A\x21\xEC" +// "\x3C\xCF\x61\xED\x1D\xF3\xD8\x75\x1E\xC2\x16\x54\x41\x9E\xC3\xCC\xF6\x1E\xD1\x28" +// "\xF6\x1D\x47\xB0\x7C\x56\xD3\x0B\x7D\x47\xB0\xF3\x3D\xA7\xB0\xF6\xE8\x87\xB0\xF3" +// "\x3D\xA7\xB0\x2B\xF5\x21\x7E\x68\x4B\xA6\x08\x98\x30\x7F\x77\x40\x95\x40\x10\xB8" +// "\x3A\x2F\xB1\xB9\x4C\xF6\x1E\xE3\xDC\x75\x1E\xCF\x0F\x99\xBF\xFB\x73\x8F\x61\xE6" +// "\x7B\x0E\x38\xF2\x5B\xA3\xD8\x75\x1E\xC2\xB1\x9A\x08\xB5\x0E\x43\xA4\xF1\xD1\x9E" +// "\xC3\xA8\xF6\x17\x87\xC5\x8C\x04\x1C\xB0\xF6\x9E\xC0\x41\x8D\xEA\xBA\x67\xB0\xF3" +// "\x38\xCE\xA3\xD8\x42\xFE\x11\xEC\x3C\xCF\x61\xEC\x3A\x8F\x65\x33\x65\x02\x0C\x6E" +// "\xCA\xD3\x06\x47\xB0\xF3\x46\x2C\x2F\x33\xDC\x75\x1E\xC0\xB7\x8D\x07\x0B\xAA\xCE" +// "\x3D\x87\x99\x8B\x0B\xCC\xEA\x3D\x83\x33\xF5\x61\x79\xFC\xCF\x43\x7E\x04\x2A\x2B" +// "\x67\xB8"; const char HueConfigResponse_JSON[] PROGMEM = "{\"name\":\"Philips hue\"," "\"mac\":\"{ma\"," From 6154fd1015104dbdfbf885a5c9e3fe94384979fd Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 22 May 2020 23:05:55 +0200 Subject: [PATCH 043/581] Fixed compilation error --- tasmota/support.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index a053b6c34..f43a40569 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1939,7 +1939,7 @@ String escapeJSONString(const char *str) { #if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) -#include +#include Unishox compressor; From e780f2528328cf3a10f032b618054cd7dc98ca18 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 23 May 2020 17:13:04 +1000 Subject: [PATCH 044/581] Gamma correction Implement changes proposed by @s-hadinger review. * Use 0-255 range in settings * Apply gamma correction from xdrv_light & use changuintscale helper fn (as per pwm light routine) --- tasmota/settings.h | 8 ++++---- tasmota/settings.ino | 4 ++-- tasmota/support_command.ino | 8 ++++---- tasmota/support_tasmota.ino | 24 ++++++++---------------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 0cc171601..e8bae5182 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -570,12 +570,12 @@ struct { int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E uint8_t ledpwm_mask; // F3F - - uint8_t free_f40[116]; // F40 - Decrement if adding new Setting variables just above and below + uint8_t ledpwm_on; // F40 + uint8_t ledpwm_off; // F41 + + uint8_t free_f42[118]; // F42 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below - uint16_t ledpwm_on; // FB4 - uint16_t ledpwm_off; // FB6 uint16_t pulse_counter_debounce_low; // FB8 uint16_t pulse_counter_debounce_high; // FBA uint32_t keeloq_master_msb; // FBC diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 85a205da2..8d771a109 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1058,7 +1058,7 @@ void SettingsDefaultSet2(void) // Led PWM Settings.ledpwm_off = 0; - Settings.ledpwm_on = 1023; + Settings.ledpwm_on = 255; Settings.ledpwm_mask = 0; } @@ -1420,7 +1420,7 @@ void SettingsDelta(void) // ledpwm if (Settings.version < 0x08030001) { Settings.ledpwm_off = 0; - Settings.ledpwm_on = 1023; + Settings.ledpwm_on = 255; Settings.ledpwm_mask = 0; } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 2f327b9a1..f52fb7ea5 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1896,8 +1896,8 @@ void CmndSetLedPwmOff(void) if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.payload < 0) { Settings.ledpwm_off = 0; - } else if (XdrvMailbox.payload > Settings.pwm_range) { - Settings.ledpwm_off = Settings.pwm_range; + } else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_off = 255; } else { Settings.ledpwm_off = XdrvMailbox.payload; } @@ -1911,8 +1911,8 @@ void CmndSetLedPwmOn(void) if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.payload < 0) { Settings.ledpwm_on = 0; - } else if (XdrvMailbox.payload > Settings.pwm_range) { - Settings.ledpwm_on = Settings.pwm_range; + } else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_on = 255; } else { Settings.ledpwm_on = XdrvMailbox.payload; } diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index d96751e32..374cb6884 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -358,24 +358,16 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } else { led_power &= (0xFF ^ mask); } - uint16_t led_pwm_set = 0; + uint16_t pwm = 0; if (bitRead(Settings.ledpwm_mask, led)) { - if (bitRead(led_inverted, led)) { - if (state) { - led_pwm_set = Settings.pwm_range - Settings.ledpwm_on; - } else { - led_pwm_set = Settings.pwm_range - Settings.ledpwm_off; - } - } else { - if (state) { - led_pwm_set = Settings.ledpwm_on; - } else { - led_pwm_set = Settings.ledpwm_off; - } - } - analogWrite(Pin(GPIO_LED1, led), led_pwm_set); + #ifdef USE_LIGHT + pwm = changeUIntScale(ledGamma10(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 1023, 0, Settings.pwm_range); // gamma corrected + #else //USE_LIGHT + pwm = changeUIntScale((uint16_t)(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 255, 0, Settings.pwm_range); // linear + #endif //USE_LIGHT + analogWrite(Pin(GPIO_LED1, led), bitRead(led_inverted, led) ? Settings.pwm_range - pwm : pwm); } else { - DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); + DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); } } #ifdef USE_BUZZER From 02faa2ea492e56d2c66a40638070f3d93db91013 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 23 May 2020 10:05:57 +0200 Subject: [PATCH 045/581] Fix style and compilation error when no compression --- tasmota/support.ino | 2 +- tasmota/xdrv_10_rules.ino | 2 +- tasmota/xdrv_21_wemo.ino | 32 ++++++++++++++++++++++++-------- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index f43a40569..cecb5ffb2 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1943,7 +1943,7 @@ String escapeJSONString(const char *str) { Unishox compressor; -String decompress(const char * compressed, size_t uncompressed_size) { +String Decompress(const char * compressed, size_t uncompressed_size) { String content(""); uncompressed_size += 2; // take a security margin diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 7dcc90498..912a32ae5 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -263,7 +263,7 @@ void GetRule_decompress(String &rule, const char *rule_head) { size_t buf_len = 1 + *rule_head * 8; // the first byte contains size of buffer for uncompressed rule / 8, buf_len may overshoot by 7 rule_head++; // advance to the actual compressed buffer - rule = decompress(rule_head, buf_len); + rule = Decompress(rule_head, buf_len); } #endif // USE_RULES_COMPRESSION diff --git a/tasmota/xdrv_21_wemo.ino b/tasmota/xdrv_21_wemo.ino index 20236df6e..86022b084 100644 --- a/tasmota/xdrv_21_wemo.ino +++ b/tasmota/xdrv_21_wemo.ino @@ -89,7 +89,7 @@ void WemoRespondToMSearch(int echo_type) //SetBinaryStateBinaryStateBinaryStateinGetBinaryStateBinaryStateBinaryStateoutBinaryStatebool0levelstring0\r\n\r\n //Successfully compressed from 779 to 249 bytes (-68%) -const size_t WEMO_EVENTSERVICE_XML_size = 779; +const size_t WEMO_EVENTSERVICE_XML_SIZE = 779; const char WEMO_EVENTSERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\xE3\xE1\xEC\x17\xFE\x3C\xC8\x73\x08\xD3\x78\xF3" "\xF3\xF9\x9E\x86\xCE\xB3\x90\xEB\x67\xB0\xFC\x3D\x0A\xC3\xAD\xCE\x20\xB7\xD4\x08" "\x72\x0F\xC3\xD3\xAC\x6B\x3F\x0B\xCE\x88\x76\xF5\xFC\xC8\xBD\x57\x4C\xF4\x3B\x3A" @@ -106,7 +106,7 @@ const char WEMO_EVENTSERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\x //10GetMetaInfoGetMetaInfoMetaInfoinMetaInfostring0\r\n\r\n //Successfully compressed from 479 to 253 bytes (-47.2%) -const size_t WEMO_METASERVICE_XML_size = 479; +const size_t WEMO_METASERVICE_XML_SIZE = 479; const char WEMO_METASERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\xE3\xE1\xEC\x17\xFE\x3C\xC8\x73\x08\xD3\x78\xF3" "\xF3\xF9\x9E\x86\xCE\xB3\x90\xEB\x67\xB0\xFC\x3D\x0B\xC3\x18\x64\x66\xFF\xED\xCE" "\x3F\x0F\x41\xB6\x6B\xCF\x9F\x87\x21\xE8\x76\x10\x20\xC5\x3D\x06\xEF\x67\xCF\xC3" @@ -123,7 +123,7 @@ const char WEMO_METASERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\xE //%d\r\n //Successfully compressed from 282 to 161 bytes (-42.9%) -const size_t WEMO_RESPONSE_STATE_SOAP_size = 282; +const size_t WEMO_RESPONSE_STATE_SOAP_SIZE = 282; const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM = "\x3D\x3C\x79\x93\xE3\x36\x16\x0C\x68\xD8\x34\x2E\xF1\xE7\xE3\xE1\xEC\x15\x54\x30" "\xF3\x3B\x0E\xCF\x06\x29\x8D\xBF\x1D\x0D\x83\x42\xF6\x58\xC3\xA6\x7C\x78\xEC\xF6" "\x58\xC3\xB1\x82\x16\x1C\x76\x1E\xC5\xE3\xCD\xF0\x78\x26\xF0\xF1\x7A\x8C\x82\x60" @@ -136,7 +136,7 @@ const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM = "\x3D\x3C\x79\x93\xE3\x36\x16\x0 //urn:Belkin:device:controllee:1{x1Belkin International Inc.Socket3.1415uuid:{x2{x30urn:Belkin:service:basicevent:1urn:Belkin:serviceId:basicevent1/upnp/control/basicevent1/upnp/event/basicevent1/eventservice.xmlurn:Belkin:service:metainfo:1urn:Belkin:serviceId:metainfo1/upnp/control/metainfo1/upnp/event/metainfo1/metainfoservice.xml\r\n //Successfully compressed from 923 to 392 bytes (-57.5%) -const size_t WEMO_SETUP_XML_size = 923; +const size_t WEMO_SETUP_XML_SIZE = 923; const char WEMO_SETUP_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E" "\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\x21\xCC\x23\x4D\xE3\xCC\x46" "\x67\xA1\xB3\xAC\xE4\x3A\xD9\xEC\x3F\x0F\x42\x04\x19\x20\x87\x10\xA8\xC8\x63\x3F" @@ -293,7 +293,11 @@ void HandleUpnpEvent(void) } } - snprintf_P(event, sizeof(event), decompress(WEMO_RESPONSE_STATE_SOAP, WEMO_RESPONSE_STATE_SOAP_size).c_str(), state, bitRead(power, devices_present -1), state); +#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) + snprintf_P(event, sizeof(event), Decompress(WEMO_RESPONSE_STATE_SOAP, WEMO_RESPONSE_STATE_SOAP_SIZE).c_str(), state, bitRead(power, devices_present -1), state); +#else + snprintf_P(event, sizeof(event), WEMO_RESPONSE_STATE_SOAP, state, bitRead(power, devices_present -1), state); +#endif WSSend(200, CT_XML, event); } @@ -301,21 +305,33 @@ void HandleUpnpService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_EVENT_SERVICE)); - WSSend(200, CT_PLAIN, decompress(WEMO_EVENTSERVICE_XML, WEMO_EVENTSERVICE_XML_size)); +#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) + WSSend(200, CT_PLAIN, Decompress(WEMO_EVENTSERVICE_XML, WEMO_EVENTSERVICE_XML_SIZE)); +#else + WSSend(200, CT_PLAIN, FPSTR(WEMO_EVENTSERVICE_XML)); +#endif } void HandleUpnpMetaService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_META_SERVICE)); - WSSend(200, CT_PLAIN, decompress(WEMO_METASERVICE_XML, WEMO_METASERVICE_XML_size)); +#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) + WSSend(200, CT_PLAIN, Decompress(WEMO_METASERVICE_XML, WEMO_METASERVICE_XML_SIZE)); +#else + WSSend(200, CT_PLAIN, FPSTR(WEMO_METASERVICE_XML)); +#endif } void HandleUpnpSetupWemo(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_SETUP)); - String setup_xml = decompress(WEMO_SETUP_XML, WEMO_SETUP_XML_size); +#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) + String setup_xml = Decompress(WEMO_SETUP_XML, WEMO_SETUP_XML_SIZE); +#else + String setup_xml = FPSTR(WEMO_SETUP_XML); +#endif setup_xml.replace("{x1", SettingsText(SET_FRIENDLYNAME1)); setup_xml.replace("{x2", WemoUuid()); setup_xml.replace("{x3", WemoSerialnumber()); From 584b3c2ef856babc4b8071cf70cfe61264439034 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 23 May 2020 10:24:08 +0200 Subject: [PATCH 046/581] scripter update add direct access to some energy registers and sml registers make google charts optional #define USE_GOOGLE_CHARTS --- tasmota/xdrv_10_scripter.ino | 458 +++++++++++++++++++++++++---------- tasmota/xsns_53_sml.ino | 9 +- 2 files changed, 335 insertions(+), 132 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index eb0d00f29..199154644 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -1228,6 +1228,52 @@ chknext: fvar=UtcTime()-(uint32_t)EPOCH_OFFSET; goto exit; } +#ifdef USE_ENERGY_SENSOR + if (!strncmp(vname,"enrg[",5)) { + lp+=5; + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + while (*lp==' ') lp++; + switch ((uint32_t)fvar) { + case 0: + fvar=Energy.total; + break; + case 1: + fvar=Energy.voltage[0]; + break; + case 2: + fvar=Energy.voltage[1]; + break; + case 3: + fvar=Energy.voltage[2]; + break; + case 4: + fvar=Energy.current[0]; + break; + case 5: + fvar=Energy.current[1]; + break; + case 6: + fvar=Energy.current[2]; + break; + case 7: + fvar=Energy.active_power[0]; + break; + case 8: + fvar=Energy.active_power[1]; + break; + case 9: + fvar=Energy.active_power[2]; + break; + + default: + fvar=99999; + break; + } + len=0; + lp++; + goto exit; + } +#endif //USE_ENERGY_SENSOR break; case 'f': #ifdef USE_SCRIPT_FATFS @@ -1948,6 +1994,15 @@ chknext: } #endif #if defined(USE_SML_M) && defined (USE_SML_SCRIPT_CMD) + if (!strncmp(vname,"sml[",4)) { + lp+=4; + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + SCRIPT_SKIP_SPACES + fvar=SML_GetVal[fvar]; + lp++; + len=0; + goto exit; + } if (!strncmp(vname,"sml(",4)) { lp+=4; float fvar1; @@ -3948,6 +4003,12 @@ void ScriptSaveSettings(void) { strlcpy(glob_script_mem.script_ram,str.c_str(), glob_script_mem.script_size); + if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') { + AddLog_P2(LOG_LEVEL_INFO, PSTR("script error: must start with >D")); + bitWrite(Settings.rule_enabled, 0, 0); + } + + #if defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) if (glob_script_mem.flags&1) { EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram); @@ -3983,9 +4044,9 @@ void ScriptSaveSettings(void) { #ifndef ESP32_SCRIPT_SIZE //AddLog_P2(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); - uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram)+1, Settings.rules[0], MAX_SCRIPT_SIZE-1); - Settings.rules[0][len_compressed] = 0; + uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], MAX_SCRIPT_SIZE-1); if (len_compressed > 0) { + Settings.rules[0][len_compressed] = 0; AddLog_P2(LOG_LEVEL_INFO,PSTR("script compressed to %d %%"),len_compressed * 100 / strlen(glob_script_mem.script_ram)); } else { AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); @@ -4899,12 +4960,20 @@ const char SCRIPT_MSG_TEXTINP[] PROGMEM = const char SCRIPT_MSG_NUMINP[] PROGMEM = "
"; + +#ifdef USE_GOOGLE_CHARTS const char SCRIPT_MSG_GTABLE[] PROGMEM = "" "" - "" - "" - ""; + "" + ""; + +const char SCRIPT_MSG_TABLE[] PROGMEM = + ""; +const char SCRIPT_MSG_GAUGE[] PROGMEM = + ""; +const char SCRIPT_MSG_TIMELINE[] PROGMEM = + ""; const char SCRIPT_MSG_GTABLEa[] PROGMEM = @@ -4913,9 +4982,15 @@ const char SCRIPT_MSG_GTABLEa[] PROGMEM = "var data=google.visualization.arrayToDataTable(["; +const char SCRIPT_MSG_GTABLEd[] PROGMEM = +"['Timeline','start','end'],"; + +//#define CHART_EXTRA_OPTIONS ",width:'640px',height:'480px'" +#define CHART_EXTRA_OPTIONS + const char SCRIPT_MSG_GTABLEb[] PROGMEM = "]);" - "var options={%s};" + "var options={%s" CHART_EXTRA_OPTIONS "};" "var chart=new google.visualization.%s(document.getElementById('chart%1d'));" "chart.draw(data,options);}" "google.charts.setOnLoadCallback(drawChart);"; @@ -4923,15 +4998,83 @@ const char SCRIPT_MSG_GTABLEb[] PROGMEM = const char SCRIPT_MSG_GOPT1[] PROGMEM = "title:'%s',isStacked:false"; -const char SCRIPT_MSG_GOPT3[] PROGMEM = -"title:'%s',vAxes:{0:{maxValue:%d},1:{maxValue:%d}},series:{0:{targetAxisIndex:0},1:{targetAxisIndex:1}}"; - - const char SCRIPT_MSG_GOPT2[] PROGMEM = "showRowNumber:true,sort:'disable',allowHtml:true,width:'100%%',height:'100%%',cssClassNames:cssc"; +const char SCRIPT_MSG_GOPT3[] PROGMEM = +"title:'%s',isStacked:false,vAxes:{0:{maxValue:%d},1:{maxValue:%d}},series:{0:{targetAxisIndex:0},1:{targetAxisIndex:1}}%s"; + +const char SCRIPT_MSG_GOPT4[] PROGMEM = +//"hAxis:{minValue:new Date(0,1,1,0,0),maxValue:new Date(0,1,2,0,0),format:'HH:mm'}"; +"hAxis:{minValue:new Date(0,1,1,0,0),maxValue:new Date(0,1,2,0,0),format:'HH:mm'},theme: 'maximized'"; + +const char SCRIPT_MSG_GOPT5[] PROGMEM = +"new Date(0,1,1,%d,%d)"; + const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'"; +#define GLIBS_MAIN 1<<0 +#define GLIBS_TABLE 1<<1 +#define GLIBS_GAUGE 1<<2 +#define GLIBS_TIMELINE 1<<3 + +#define MAX_GARRAY 4 + +char *gc_get_arrays(char *lp, float **arrays, uint8_t *ranum, uint8_t *rentries) { +struct T_INDEX ind; +uint8_t vtype; +uint8 entries=0; + + uint8_t anum=0; + while (anum> 2 %d\n",(uint32_t)*fa); + if (fa && len>=entries) { + if (!entries) {entries = len;} + // add array to list + arrays[anum]=fa; + anum++; + } + } + } else { + lp=lp1; + break; + } + } + } + *ranum=anum; + *rentries=entries; + return lp; +} + +char *gc_send_labels(char *lp,uint32_t anum) { + WSContentSend_PD("["); + for (uint32_t cnt=0; cnt> 2 %d\n",(uint32_t)*fa); - if (fa && len>=entries) { - if (!entries) {entries = len;} - // add array to list - arrays[anum]=fa; - anum++; - } - } - } else { - lp=lp1; - break; - } - } - } - //Serial.printf("arrays %d\n",anum); - //Serial.printf("entries %d\n",entries); - - if (!google_libs) { - WSContentSend_PD(SCRIPT_MSG_GTABLE); - google_libs=1; - } - - WSContentSend_PD(SCRIPT_MSG_GTABLEa); - - // we know how many arrays and the number of entries - // we need to fetch the labels now - WSContentSend_PD("["); - for (uint32_t cnt=0; cntnanum) { + goto nextwebline; + } + // we know how many arrays and the number of entries + //Serial.printf("arrays %d\n",anum); + //Serial.printf("entries %d\n",entries); + if (ctype=='T') { + if (anum && !(entries&1)) { + WSContentSend_PD(SCRIPT_MSG_GTABLEa); + WSContentSend_PD(SCRIPT_MSG_GTABLEd); + char label[SCRIPT_MAXSSIZE]; + lp=GetStringResult(lp,OPER_EQU,label,0); + SCRIPT_SKIP_SPACES + char *lblp=label; + for (uint32_t ind=0; ind0) glob_script_mem.script_ram[len_decompressed]=0; //AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); #endif #endif @@ -5568,6 +5756,14 @@ bool Xdrv10(uint8_t function) glob_script_mem.flags=1; #endif + // a valid script MUST start with >D + if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') { + // clr all + memset(glob_script_mem.script_ram,0,glob_script_mem.script_size); + strcpy_P(glob_script_mem.script_ram, PSTR(">D\nscript error must start with >D")); + bitWrite(Settings.rule_enabled, 0, 0); + } + // assure permanent memory is 4 byte aligned { uint32_t ptr=(uint32_t)glob_script_mem.script_pram; ptr&=0xfffffffc; diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index c63478b48..3b4357b26 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -2151,6 +2151,7 @@ init10: #else #ifdef ESP32 meter_ss[meters] = new HardwareSerial(uart_index); + if (uart_index==0) { ClaimSerial(); } uart_index--; if (uart_index<0) uart_index=0; #else @@ -2216,7 +2217,13 @@ uint32_t SML_Write(uint32_t meter,char *hstr) { SML_Send_Seq(meter,hstr); return 1; } -#endif + +float SML_GetVal(uint32_t index) { + if (index<1 && index>SML_MAX_VARS) { index = 1;} + return meter_vars[index-1]; +} + +#endif // USE_SML_SCRIPT_CMD void SetDBGLed(uint8_t srcpin, uint8_t ledpin) { From 2eccc09086e24805e2b5db8f27085ba882c79723 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 23 May 2020 10:36:19 +0200 Subject: [PATCH 047/581] remove unishox def --- tasmota/xdrv_10_scripter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 199154644..cf148c97b 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -71,7 +71,7 @@ uint32_t DecodeLightId(uint32_t hue_id); #ifdef USE_SCRIPT_COMPRESSION #include -Unishox compressor; // singleton +//Unishox compressor; // singleton #define SCRIPT_COMPRESS compressor.unishox_compress #define SCRIPT_DECOMPRESS compressor.unishox_decompress #ifndef UNISHOXRSIZE From d0de78352f592aa611dc83348e0188b7be2d1990 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 23 May 2020 12:15:14 +0200 Subject: [PATCH 048/581] Fix Energy Frequency display --- tasmota/xdrv_03_energy.ino | 7 ++++--- tasmota/xnrg_07_ade7953.ino | 5 ++--- tasmota/xnrg_10_sdm630.ino | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index 2caaaa292..f5e4a729d 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -97,7 +97,8 @@ struct ENERGY { uint8_t data_valid[3] = { 0, 0, 0 }; uint8_t phase_count = 1; // Number of phases active - bool voltage_common = false; // Use single voltage and frequency + bool voltage_common = false; // Use single voltage + bool frequency_common = false; // Use single frequency bool kWhtoday_offset_init = false; bool voltage_available = true; // Enable if voltage is measured @@ -1036,7 +1037,7 @@ void EnergyShow(bool json) } if (!isnan(Energy.frequency[0])) { ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":%s"), - EnergyFormat(value_chr, frequency_chr[0], json, Energy.voltage_common)); + EnergyFormat(value_chr, frequency_chr[0], json, Energy.frequency_common)); } } if (Energy.voltage_available) { @@ -1103,7 +1104,7 @@ void EnergyShow(bool json) } if (!isnan(Energy.frequency[0])) { WSContentSend_PD(PSTR("{s}" D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"), - EnergyFormat(value_chr, frequency_chr[0], json, Energy.voltage_common)); + EnergyFormat(value_chr, frequency_chr[0], json, Energy.frequency_common)); } } WSContentSend_PD(HTTP_ENERGY_SNS2, energy_daily_chr, energy_yesterday_chr, energy_total_chr); diff --git a/tasmota/xnrg_07_ade7953.ino b/tasmota/xnrg_07_ade7953.ino index 44bec2e59..3d7b405d5 100644 --- a/tasmota/xnrg_07_ade7953.ino +++ b/tasmota/xnrg_07_ade7953.ino @@ -209,10 +209,9 @@ void Ade7953DrvInit(void) } I2cSetActiveFound(ADE7953_ADDR, "ADE7953"); Ade7953.init_step = 2; - Energy.phase_count = 2; // Handle two channels as two phases - Energy.voltage_common = true; // Use common voltage and frequency - + Energy.voltage_common = true; // Use common voltage + Energy.frequency_common = true; // Use common frequency energy_flg = XNRG_07; } } diff --git a/tasmota/xnrg_10_sdm630.ino b/tasmota/xnrg_10_sdm630.ino index 026c3b4e8..d239c1c73 100644 --- a/tasmota/xnrg_10_sdm630.ino +++ b/tasmota/xnrg_10_sdm630.ino @@ -203,6 +203,7 @@ void Sdm630SnsInit(void) if (result) { if (2 == result) { ClaimSerial(); } Energy.phase_count = 3; + Energy.frequency_common = true; // Use common frequency } else { energy_flg = ENERGY_NONE; } From dc9ce428889470de66a435aee155bedd5d185c85 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 23 May 2020 13:04:17 +0200 Subject: [PATCH 049/581] Refactor LedPwm code --- tasmota/i18n.h | 8 +++----- tasmota/settings.h | 13 +++++-------- tasmota/settings.ino | 18 +++++------------- tasmota/support_command.ino | 34 ++++++++++++++++++---------------- 4 files changed, 31 insertions(+), 42 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index a2e9e16b0..98e20d9ac 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -295,6 +295,9 @@ #define D_CMND_LEDPOWER "LedPower" #define D_CMND_LEDSTATE "LedState" #define D_CMND_LEDMASK "LedMask" +#define D_CMND_LEDPWMOFF "LedPwmOff" +#define D_CMND_LEDPWMON "LedPwmOn" +#define D_CMND_LEDPWMMODE "LedPwmMode" #define D_CMND_WIFIPOWER "WifiPower" #define D_CMND_SPEEDUNIT "SpeedUnit" #define D_CMND_I2CSCAN "I2CScan" @@ -587,11 +590,6 @@ // Commands xsns_02_analog.ino #define D_CMND_ADCPARAM "AdcParam" -// Commands led pwm settings -#define D_CMND_SETLEDPWMOFF "LedPwmOff" -#define D_CMND_SETLEDPWMON "LedPwmOn" -#define D_CMND_SETLEDPWMMODE "LedPwmMode" - // xsns_70_veml6075.ino #define D_JSON_UVA_INTENSITY "UvaIntensity" #define D_JSON_UVB_INTENSITY "UvbItensity" diff --git a/tasmota/settings.h b/tasmota/settings.h index e8bae5182..6ff0c4213 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -515,9 +515,7 @@ struct { uint8_t ot_hot_water_setpoint; // E8C uint8_t ot_boiler_setpoint; // E8D uint8_t ot_flags; // E8E - - uint8_t free_e8f[1]; // E8F - + uint8_t ledpwm_mask; // F8F uint16_t dimmer_hw_min; // E90 uint16_t dimmer_hw_max; // E92 uint32_t deepsleep; // E94 @@ -569,11 +567,10 @@ struct { uint16_t windmeter_pulse_debounce; // F3A int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E - uint8_t ledpwm_mask; // F3F - uint8_t ledpwm_on; // F40 - uint8_t ledpwm_off; // F41 - - uint8_t free_f42[118]; // F42 - Decrement if adding new Setting variables just above and below + uint8_t ledpwm_on; // F3F + uint8_t ledpwm_off; // F40 + + uint8_t free_f42[119]; // F41 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below uint16_t pulse_counter_debounce_low; // FB8 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 8d771a109..549799447 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -765,6 +765,9 @@ void SettingsDefaultSet2(void) Settings.blinkcount = APP_BLINKCOUNT; Settings.ledstate = APP_LEDSTATE; Settings.ledmask = APP_LEDMASK; +// Settings.ledpwm_off = 0; + Settings.ledpwm_on = 255; +// Settings.ledpwm_mask = 0; Settings.pulse_timer[0] = APP_PULSETIME; // for (uint32_t i = 1; i < MAX_PULSETIMERS; i++) { Settings.pulse_timer[i] = 0; } @@ -1055,11 +1058,6 @@ void SettingsDefaultSet2(void) Settings.flag2 = flag2; Settings.flag3 = flag3; Settings.flag4 = flag4; - - // Led PWM - Settings.ledpwm_off = 0; - Settings.ledpwm_on = 255; - Settings.ledpwm_mask = 0; } /********************************************************************************************/ @@ -1405,7 +1403,6 @@ void SettingsDelta(void) Settings.config_version = 1; // ESP32 #endif // ESP32 } - if (Settings.version < 0x08020006) { #ifdef ESP32 Settings.module = WEMOS; @@ -1416,18 +1413,13 @@ void SettingsDelta(void) if (Settings.rules[1][0] == 0) { Settings.rules[1][1] = 0; } if (Settings.rules[2][0] == 0) { Settings.rules[2][1] = 0; } } - - // ledpwm - if (Settings.version < 0x08030001) { + if (Settings.version < 0x08030002) { + SettingsUpdateText(SET_DEVICENAME, SettingsText(SET_FRIENDLYNAME1)); Settings.ledpwm_off = 0; Settings.ledpwm_on = 255; Settings.ledpwm_mask = 0; } - if (Settings.version < 0x08030002) { - SettingsUpdateText(SET_DEVICENAME, SettingsText(SET_FRIENDLYNAME1)); - } - Settings.version = VERSION; SettingsSave(1); } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index f52fb7ea5..2ee5c17c4 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -27,7 +27,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" - D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_SETLEDPWMON "|" D_CMND_SETLEDPWMOFF "|" D_CMND_SETLEDPWMMODE "|" + D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_LEDPWMON "|" D_CMND_LEDPWMOFF "|" D_CMND_LEDPWMMODE "|" #ifdef USE_I2C D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|" #endif @@ -50,7 +50,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, - &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSetLedPwmOn, &CmndSetLedPwmOff, &CmndSetLedPwmMode, + &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode, #ifdef USE_I2C &CmndI2cScan, CmndI2cDriver, #endif @@ -1891,37 +1891,39 @@ void CmndDriver(void) XdrvCall(FUNC_COMMAND_DRIVER); } -void CmndSetLedPwmOff(void) +void CmndLedPwmOff(void) { if (XdrvMailbox.data_len > 0) { - if (XdrvMailbox.payload < 0) { - Settings.ledpwm_off = 0; - } else if (XdrvMailbox.payload > 255) { - Settings.ledpwm_off = 255; + if (XdrvMailbox.payload < 0) { + Settings.ledpwm_off = 0; + } + else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_off = 255; } else { Settings.ledpwm_off = XdrvMailbox.payload; } - UpdateLedPowerAll(); + UpdateLedPowerAll(); } ResponseCmndNumber(Settings.ledpwm_off); } -void CmndSetLedPwmOn(void) +void CmndLedPwmOn(void) { if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.payload < 0) { - Settings.ledpwm_on = 0; - } else if (XdrvMailbox.payload > 255) { - Settings.ledpwm_on = 255; - } else { - Settings.ledpwm_on = XdrvMailbox.payload; + Settings.ledpwm_on = 0; } - UpdateLedPowerAll(); + else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_on = 255; + } else { + Settings.ledpwm_on = XdrvMailbox.payload; + } + UpdateLedPowerAll(); } ResponseCmndNumber(Settings.ledpwm_on); } -void CmndSetLedPwmMode(void) +void CmndLedPwmMode(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_LEDS)) { if (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; } From aafa0862ab8246786628acf7339ef76ce69c5aec Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 23 May 2020 13:09:16 +0200 Subject: [PATCH 050/581] Refactor LedPwm code --- tasmota/support_tasmota.ino | 27 ++++++++++++++------------- tasmota/tasmota.ino | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 374cb6884..08a2ac6ca 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -358,17 +358,17 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } else { led_power &= (0xFF ^ mask); } - uint16_t pwm = 0; - if (bitRead(Settings.ledpwm_mask, led)) { - #ifdef USE_LIGHT - pwm = changeUIntScale(ledGamma10(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 1023, 0, Settings.pwm_range); // gamma corrected - #else //USE_LIGHT - pwm = changeUIntScale((uint16_t)(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 255, 0, Settings.pwm_range); // linear - #endif //USE_LIGHT - analogWrite(Pin(GPIO_LED1, led), bitRead(led_inverted, led) ? Settings.pwm_range - pwm : pwm); - } else { - DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); - } + uint16_t pwm = 0; + if (bitRead(Settings.ledpwm_mask, led)) { +#ifdef USE_LIGHT + pwm = changeUIntScale(ledGamma10(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 1023, 0, Settings.pwm_range); // gamma corrected +#else //USE_LIGHT + pwm = changeUIntScale((uint16_t)(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 255, 0, Settings.pwm_range); // linear +#endif //USE_LIGHT + analogWrite(Pin(GPIO_LED1, led), bitRead(led_inverted, led) ? Settings.pwm_range - pwm : pwm); + } else { + DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); + } } #ifdef USE_BUZZER if (led == 0) { @@ -403,8 +403,9 @@ void SetLedLink(uint32_t state) uint32_t led_pin = Pin(GPIO_LEDLNK); uint32_t led_inv = ledlnk_inverted; if (99 == led_pin) { // Legacy - LED1 is status - SetLedPowerIdx(0, state); - } else if (led_pin < 99) { + SetLedPowerIdx(0, state); + } + else if (led_pin < 99) { if (state) { state = 1; } digitalWrite(led_pin, (led_inv) ? !state : state); } diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 92e3169b2..ecf1127ec 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -1,4 +1,4 @@ - /* +/* tasmota.ino - Tasmota firmware for iTead Sonoff, Wemos and NodeMCU hardware Copyright (C) 2020 Theo Arends From ca8b38d0d022c9a2fe50c0a338059717c2de68ec Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 23 May 2020 15:17:13 +0200 Subject: [PATCH 051/581] Add LedPwm commands Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/i18n.h | 6 +- tasmota/support_command.ino | 120 ++++++++++++++++++------------------ 4 files changed, 65 insertions(+), 63 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 07406b54f..b5c8332c7 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -58,6 +58,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Add command ``Rule0`` to change global rule parameters +- Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add more functionality to ``Switchmode`` 11 and 12 (#8450) - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) - Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index b4c77c4ab..b5f6d6ffe 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -5,6 +5,7 @@ - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Add Three Phase Export Active Energy to SDM630 driver +- Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) ### 8.3.1.1 20200518 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 98e20d9ac..89d931908 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -295,9 +295,9 @@ #define D_CMND_LEDPOWER "LedPower" #define D_CMND_LEDSTATE "LedState" #define D_CMND_LEDMASK "LedMask" -#define D_CMND_LEDPWMOFF "LedPwmOff" -#define D_CMND_LEDPWMON "LedPwmOn" -#define D_CMND_LEDPWMMODE "LedPwmMode" +#define D_CMND_LEDPWM_OFF "LedPwmOff" +#define D_CMND_LEDPWM_ON "LedPwmOn" +#define D_CMND_LEDPWM_MODE "LedPwmMode" #define D_CMND_WIFIPOWER "WifiPower" #define D_CMND_SPEEDUNIT "SpeedUnit" #define D_CMND_I2CSCAN "I2CScan" diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 2ee5c17c4..9851a5654 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -26,8 +26,8 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALCONFIG "|" D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" - D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" - D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_LEDPWMON "|" D_CMND_LEDPWMOFF "|" D_CMND_LEDPWMMODE "|" + D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_LEDPWM_ON "|" D_CMND_LEDPWM_OFF "|" D_CMND_LEDPWM_MODE "|" + D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" #ifdef USE_I2C D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|" #endif @@ -49,8 +49,8 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndButtonDebounce, &CmndSwitchDebounce, &CmndSyslog, &CmndLoghost, &CmndLogport, &CmndSerialSend, &CmndBaudrate, &CmndSerialConfig, &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, - &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, - &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode, + &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode, + &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, #ifdef USE_I2C &CmndI2cScan, CmndI2cDriver, #endif @@ -1804,6 +1804,62 @@ void CmndLedMask(void) ResponseCmndChar(stemp1); } +void CmndLedPwmOff(void) +{ + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload < 0) { + Settings.ledpwm_off = 0; + } + else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_off = 255; + } else { + Settings.ledpwm_off = XdrvMailbox.payload; + } + UpdateLedPowerAll(); + } + ResponseCmndNumber(Settings.ledpwm_off); +} + +void CmndLedPwmOn(void) +{ + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload < 0) { + Settings.ledpwm_on = 0; + } + else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_on = 255; + } else { + Settings.ledpwm_on = XdrvMailbox.payload; + } + UpdateLedPowerAll(); + } + ResponseCmndNumber(Settings.ledpwm_on); +} + +void CmndLedPwmMode(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_LEDS)) { + if (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; } + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { + uint32_t mask = 1 << (XdrvMailbox.index -1); // Led to configure + switch (XdrvMailbox.payload) { + case 0: // digital + Settings.ledpwm_mask &= (0xFF ^ mask); + break; + case 1: // pwm + Settings.ledpwm_mask |= mask; + break; + case 2: // toggle + Settings.ledpwm_mask ^= mask; + break; + } + UpdateLedPowerAll(); + } + bool state = bitRead(Settings.ledpwm_mask, XdrvMailbox.index -1); + ResponseCmndIdxChar(GetStateText(state)); + } +} + void CmndWifiPower(void) { if (XdrvMailbox.data_len > 0) { @@ -1890,59 +1946,3 @@ void CmndDriver(void) { XdrvCall(FUNC_COMMAND_DRIVER); } - -void CmndLedPwmOff(void) -{ - if (XdrvMailbox.data_len > 0) { - if (XdrvMailbox.payload < 0) { - Settings.ledpwm_off = 0; - } - else if (XdrvMailbox.payload > 255) { - Settings.ledpwm_off = 255; - } else { - Settings.ledpwm_off = XdrvMailbox.payload; - } - UpdateLedPowerAll(); - } - ResponseCmndNumber(Settings.ledpwm_off); -} - -void CmndLedPwmOn(void) -{ - if (XdrvMailbox.data_len > 0) { - if (XdrvMailbox.payload < 0) { - Settings.ledpwm_on = 0; - } - else if (XdrvMailbox.payload > 255) { - Settings.ledpwm_on = 255; - } else { - Settings.ledpwm_on = XdrvMailbox.payload; - } - UpdateLedPowerAll(); - } - ResponseCmndNumber(Settings.ledpwm_on); -} - -void CmndLedPwmMode(void) -{ - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_LEDS)) { - if (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; } - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { - uint32_t mask = 1 << (XdrvMailbox.index -1); // Led to configure - switch (XdrvMailbox.payload) { - case 0: // digital - Settings.ledpwm_mask &= (0xFF ^ mask); - break; - case 1: // pwm - Settings.ledpwm_mask |= mask; - break; - case 2: // toggle - Settings.ledpwm_mask ^= mask; - break; - } - UpdateLedPowerAll(); - } - bool state = bitRead(Settings.ledpwm_mask, XdrvMailbox.index -1); - ResponseCmndIdxChar(GetStateText(state)); - } -} From e69d5686067d9299b831183f8487a56a919a59d5 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 23 May 2020 15:52:59 +0200 Subject: [PATCH 052/581] Use Tasmota optimizations from @s-hadinger in latest Arduino core --- platformio_override_sample.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index d292724c7..edfb35678 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -85,7 +85,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage extends = tasmota_core -platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#a5432625d93f60d7e28cfdc5ed8abb3e0151951d +platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#52b3e5b7b3ccedcede665682f7896b637b64dbf5 ; *********** Alternative Options, enable only if you know exactly what you do ******** ; NONOSDK221 ; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221 From 2626345662d5921c3b51cbd3af42f2516bb78590 Mon Sep 17 00:00:00 2001 From: Matthijs Abma <4146168+abmaonline@users.noreply.github.com> Date: Sat, 23 May 2020 17:07:52 +0200 Subject: [PATCH 053/581] Store if current byte is delimiter for later reuse --- tasmota/support_tasmota.ino | 9 ++++++--- tasmota/xdrv_08_serial_bridge.ino | 8 +++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 08a2ac6ca..f3da57ffb 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1291,10 +1291,13 @@ void SerialInput(void) } } else { if (serial_in_byte || Settings.flag.mqtt_serial_raw) { // Any char between 1 and 127 or any char (0 - 255) - CMND_SERIALSEND3 + bool in_byte_is_delimiter = // Char is delimiter when... + (((Settings.serial_delimiter < 128) && (serial_in_byte == Settings.serial_delimiter)) || // Any char between 1 and 127 and being delimiter + ((Settings.serial_delimiter == 128) && !isprint(serial_in_byte))) && // Any char not between 32 and 127 + !Settings.flag.mqtt_serial_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter + if ((serial_in_byte_counter < INPUT_BUFFER_SIZE -1) && // Add char to string if it still fits and ... - ((isprint(serial_in_byte) && (128 == Settings.serial_delimiter)) || // Any char between 32 and 127 - ((serial_in_byte != Settings.serial_delimiter) && (128 != Settings.serial_delimiter)) || // Any char between 1 and 127 and not being delimiter - Settings.flag.mqtt_serial_raw)) { // Any char between 0 and 255 - CMND_SERIALSEND3 + !in_byte_is_delimiter) { // Char is not a delimiter serial_in_buffer[serial_in_byte_counter++] = serial_in_byte; serial_polling_window = millis(); } else { diff --git a/tasmota/xdrv_08_serial_bridge.ino b/tasmota/xdrv_08_serial_bridge.ino index a3ae5ae32..66a0cbc3d 100644 --- a/tasmota/xdrv_08_serial_bridge.ino +++ b/tasmota/xdrv_08_serial_bridge.ino @@ -54,11 +54,13 @@ void SerialBridgeInput(void) return; } if (serial_in_byte || serial_bridge_raw) { // Any char between 1 and 127 or any char (0 - 255) + bool in_byte_is_delimiter = // Char is delimiter when... + (((Settings.serial_delimiter < 128) && (serial_in_byte == Settings.serial_delimiter)) || // Any char between 1 and 127 and being delimiter + ((Settings.serial_delimiter == 128) && !isprint(serial_in_byte))) && // Any char not between 32 and 127 + !serial_bridge_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) && // Add char to string if it still fits and ... - ((isprint(serial_in_byte) && (128 == Settings.serial_delimiter)) || // Any char between 32 and 127 - ((serial_in_byte != Settings.serial_delimiter) && (128 != Settings.serial_delimiter)) || // Any char between 1 and 127 and not being delimiter - serial_bridge_raw)) { // Any char between 0 and 255 + !in_byte_is_delimiter) { // Char is not a delimiter serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte; serial_bridge_polling_window = millis(); // Wait for more data } else { From 7f18e1e8e3ded01d4d6d765882e3b80aefd837ed Mon Sep 17 00:00:00 2001 From: Matthijs Abma <4146168+abmaonline@users.noreply.github.com> Date: Sat, 23 May 2020 17:30:48 +0200 Subject: [PATCH 054/581] Split logic for adding char to buffer and sending the buffer, to make sure the char doesn't get lost when the buffer is full --- tasmota/support_tasmota.ino | 8 ++++++-- tasmota/xdrv_08_serial_bridge.ino | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index f3da57ffb..671b4ad9d 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1299,11 +1299,15 @@ void SerialInput(void) if ((serial_in_byte_counter < INPUT_BUFFER_SIZE -1) && // Add char to string if it still fits and ... !in_byte_is_delimiter) { // Char is not a delimiter serial_in_buffer[serial_in_byte_counter++] = serial_in_byte; - serial_polling_window = millis(); - } else { + } + + if ((serial_in_byte_counter >= INPUT_BUFFER_SIZE -1) || // Send message when buffer is full or ... + in_byte_is_delimiter) { // Char is delimiter serial_polling_window = 0; // Reception done - send mqtt break; } + + serial_polling_window = millis(); // Wait for next char } } diff --git a/tasmota/xdrv_08_serial_bridge.ino b/tasmota/xdrv_08_serial_bridge.ino index 66a0cbc3d..a713b5cfb 100644 --- a/tasmota/xdrv_08_serial_bridge.ino +++ b/tasmota/xdrv_08_serial_bridge.ino @@ -62,11 +62,15 @@ void SerialBridgeInput(void) if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) && // Add char to string if it still fits and ... !in_byte_is_delimiter) { // Char is not a delimiter serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte; - serial_bridge_polling_window = millis(); // Wait for more data - } else { + } + + if ((serial_bridge_in_byte_counter >= SERIAL_BRIDGE_BUFFER_SIZE -1) || // Send message when buffer is full or ... + in_byte_is_delimiter) { // Char is delimiter serial_bridge_polling_window = 0; // Publish now break; } + + serial_bridge_polling_window = millis(); // Wait for more data } } From a5a798853283cd36f46b081fd1f2ec7627e17f0b Mon Sep 17 00:00:00 2001 From: peteakalad Date: Sat, 23 May 2020 21:47:04 +0100 Subject: [PATCH 055/581] Add Adafruit_SGP30_Sensor-1.2.0 --- .../Adafruit_SGP30.cpp | 306 ++++++++++++++++++ .../Adafruit_SGP30.h | 80 +++++ lib/Adafruit_SGP30_Sensor-1.2.0/README.md | 54 ++++ .../examples/sgp30test/sgp30test.ino | 69 ++++ .../library.properties | 10 + lib/Adafruit_SGP30_Sensor-1.2.0/license.txt | 26 ++ lib/Adafruit_SGP30_Sensor-1.2.0/travis.yml | 27 ++ 7 files changed, 572 insertions(+) create mode 100644 lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.cpp create mode 100644 lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.h create mode 100644 lib/Adafruit_SGP30_Sensor-1.2.0/README.md create mode 100644 lib/Adafruit_SGP30_Sensor-1.2.0/examples/sgp30test/sgp30test.ino create mode 100644 lib/Adafruit_SGP30_Sensor-1.2.0/library.properties create mode 100644 lib/Adafruit_SGP30_Sensor-1.2.0/license.txt create mode 100644 lib/Adafruit_SGP30_Sensor-1.2.0/travis.yml diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.cpp b/lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.cpp new file mode 100644 index 000000000..936561ede --- /dev/null +++ b/lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.cpp @@ -0,0 +1,306 @@ +/*! + * @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. + * + */ + +#include "Arduino.h" + +#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 + * @param initSensor + * Optional pointer to prevent IAQinit to be called. Used for Deep + * Sleep. + * @return True if SGP30 found on I2C, False if something went wrong! + */ +boolean Adafruit_SGP30::begin(TwoWire *theWire, boolean initSensor) { + _i2caddr = SGP30_I2CADDR_DEFAULT; + _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 & 0xF0) != SGP30_FEATURESET) + return false; + if (initSensor) { + if (!IAQinit()) + return false; + } + + return true; +} + +/*! + * @brief Commands the sensor to perform a soft reset using the "General + * Call" mode. Take note that this is not sensor specific and all devices that + * support the General Call mode on the on the same I2C bus will perform this. + * + * @return True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::softReset(void) { + uint8_t command[2]; + command[0] = 0x00; + command[1] = 0x06; + return readWordFromCommand(command, 2, 10); +} + +/*! + * @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} + * @return 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 Commands the sensor to take a single H2/ethanol raw measurement. + * Places results in {@link rawH2} and {@link rawEthanol} + * @returns True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::IAQmeasureRaw(void) { + uint8_t command[2]; + command[0] = 0x20; + command[1] = 0x50; + uint16_t reply[2]; + if (!readWordFromCommand(command, 2, 25, reply, 2)) + return false; + rawEthanol = reply[1]; + rawH2 = 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 + * @return 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 + * @return 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 Set the absolute humidity value [mg/m^3] for compensation to + * increase precision of TVOC and eCO2. + * @param absolute_humidity + * A uint32_t [mg/m^3] which we will be used for compensation. + * If the absolute humidity is set to zero, humidity compensation + * will be disabled. + * @return True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::setHumidity(uint32_t absolute_humidity) { + if (absolute_humidity > 256000) { + return false; + } + + uint16_t ah_scaled = + (uint16_t)(((uint64_t)absolute_humidity * 256 * 16777) >> 24); + uint8_t command[5]; + command[0] = 0x20; + command[1] = 0x61; + command[2] = ah_scaled >> 8; + command[3] = ah_scaled & 0xFF; + command[4] = generateCRC(command + 2, 2); + + return readWordFromCommand(command, 5, 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) { + + _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; +} diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.h b/lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.h new file mode 100644 index 000000000..d50099e9d --- /dev/null +++ b/lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.h @@ -0,0 +1,80 @@ +/*! + * @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 + +// 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 + +/*! + * @brief Class that stores state and functions for interacting with + * SGP30 Gas Sensor + */ +class Adafruit_SGP30 { +public: + Adafruit_SGP30(); + boolean begin(TwoWire *theWire = &Wire, boolean initSensor = true); + boolean softReset(); + boolean IAQinit(); + boolean IAQmeasure(); + boolean IAQmeasureRaw(); + + boolean getIAQBaseline(uint16_t *eco2_base, uint16_t *tvoc_base); + boolean setIAQBaseline(uint16_t eco2_base, uint16_t tvoc_base); + boolean setHumidity(uint32_t absolute_humidity); + + /** 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 last measurement of the IAQ-calculated equivalent CO2 in ppm. This + * value is set when you call {@link IAQmeasureRaw()} **/ + uint16_t rawH2; + + /** The last measurement of the IAQ-calculated equivalent CO2 in ppm. This + * value is set when you call {@link IAQmeasureRaw()} **/ + uint16_t rawEthanol; + + /** 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_Sensor-1.2.0/README.md b/lib/Adafruit_SGP30_Sensor-1.2.0/README.md new file mode 100644 index 000000000..f4d35eeaa --- /dev/null +++ b/lib/Adafruit_SGP30_Sensor-1.2.0/README.md @@ -0,0 +1,54 @@ +# Adafruit SGP30 Gas / Air Quality I2C sensor [[![Build Status](https://github.com/adafruit/Adafruit_SGP30/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_SGP30/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_SGP30/html/index.html) + + + +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! + +# Installation +To install, use the Arduino Library Manager and search for "Adafruit SGP30" and install the library. + +## Dependencies + * [Adafruit ILI9341](https://github.com/adafruit/Adafruit_ILI9341) + * [Adafruit GFX Library](https://github.com/adafruit/Adafruit-GFX-Library) + +# Contributing + +Contributions are welcome! Please read our [Code of Conduct](https://github.com/adafruit/Adafruit_SGP30/blob/master/CODE_OF_CONDUCT.md>) +before contributing to help this project stay welcoming. + +## Documentation and doxygen +Documentation is produced by doxygen. Contributions should include documentation for any new code added. + +Some examples of how to use doxygen can be found in these guide pages: + +https://learn.adafruit.com/the-well-automated-arduino-library/doxygen + +https://learn.adafruit.com/the-well-automated-arduino-library/doxygen-tips + +## Formatting and clang-format +This library uses [`clang-format`](https://releases.llvm.org/download.html) to standardize the formatting of `.cpp` and `.h` files. +Contributions should be formatted using `clang-format`: + +The `-i` flag will make the changes to the file. +```bash +clang-format -i *.cpp *.h +``` +If you prefer to make the changes yourself, running `clang-format` without the `-i` flag will print out a formatted version of the file. You can save this to a file and diff it against the original to see the changes. + +Note that the formatting output by `clang-format` is what the automated formatting checker will expect. Any diffs from this formatting will result in a failed build until they are addressed. Using the `-i` flag is highly recommended. + +### clang-format resources + * [Binary builds and source available on the LLVM downloads page](https://releases.llvm.org/download.html) + * [Documentation and IDE integration](https://clang.llvm.org/docs/ClangFormat.html) + +## About this Driver +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_Sensor-1.2.0/examples/sgp30test/sgp30test.ino b/lib/Adafruit_SGP30_Sensor-1.2.0/examples/sgp30test/sgp30test.ino new file mode 100644 index 000000000..fbfbf49d5 --- /dev/null +++ b/lib/Adafruit_SGP30_Sensor-1.2.0/examples/sgp30test/sgp30test.ino @@ -0,0 +1,69 @@ +#include +#include "Adafruit_SGP30.h" + +Adafruit_SGP30 sgp; + +/* return absolute humidity [mg/m^3] with approximation formula +* @param temperature [°C] +* @param humidity [%RH] +*/ +uint32_t getAbsoluteHumidity(float temperature, float humidity) { + // approximation formula from Sensirion SGP30 Driver Integration chapter 3.15 + const float absoluteHumidity = 216.7f * ((humidity / 100.0f) * 6.112f * exp((17.62f * temperature) / (243.12f + temperature)) / (273.15f + temperature)); // [g/m^3] + const uint32_t absoluteHumidityScaled = static_cast(1000.0f * absoluteHumidity); // [mg/m^3] + return absoluteHumidityScaled; +} + +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 you have a temperature / humidity sensor, you can set the absolute humidity to enable the humditiy compensation for the air quality signals + //float temperature = 22.1; // [°C] + //float humidity = 45.2; // [%RH] + //sgp.setHumidity(getAbsoluteHumidity(temperature, humidity)); + + 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"); + + if (! sgp.IAQmeasureRaw()) { + Serial.println("Raw Measurement failed"); + return; + } + Serial.print("Raw H2 "); Serial.print(sgp.rawH2); Serial.print(" \t"); + Serial.print("Raw Ethanol "); Serial.print(sgp.rawEthanol); Serial.println(""); + + 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); + } +} diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/library.properties b/lib/Adafruit_SGP30_Sensor-1.2.0/library.properties new file mode 100644 index 000000000..5242ef25b --- /dev/null +++ b/lib/Adafruit_SGP30_Sensor-1.2.0/library.properties @@ -0,0 +1,10 @@ +name=Adafruit SGP30 Sensor +version=1.2.0 +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=* +depends=Adafruit ILI9341, Adafruit GFX Library diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/license.txt b/lib/Adafruit_SGP30_Sensor-1.2.0/license.txt new file mode 100644 index 000000000..f6a0f22b8 --- /dev/null +++ b/lib/Adafruit_SGP30_Sensor-1.2.0/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/lib/Adafruit_SGP30_Sensor-1.2.0/travis.yml b/lib/Adafruit_SGP30_Sensor-1.2.0/travis.yml new file mode 100644 index 000000000..428f3434e --- /dev/null +++ b/lib/Adafruit_SGP30_Sensor-1.2.0/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 From 615645e50e339a18eef574f92e5ac806091e1401 Mon Sep 17 00:00:00 2001 From: peteakalad Date: Sat, 23 May 2020 22:28:42 +0100 Subject: [PATCH 056/581] Fix for SPG30 Abs Humidity Not Shown on Web UI --- .../.github/ISSUE_TEMPLATE.md | 46 --- .../.github/PULL_REQUEST_TEMPLATE.md | 26 -- lib/Adafruit_SGP30-1.0.3/.gitignore | 4 - lib/Adafruit_SGP30-1.0.3/.travis.yml | 27 -- lib/Adafruit_SGP30-1.0.3/Adafruit_SGP30.cpp | 267 ------------------ lib/Adafruit_SGP30-1.0.3/Adafruit_SGP30.h | 69 ----- lib/Adafruit_SGP30-1.0.3/README.md | 18 -- .../examples/sgp30test/sgp30test.ino | 61 ---- lib/Adafruit_SGP30-1.0.3/library.properties | 9 - .../Adafruit_SGP30.cpp | 0 .../Adafruit_SGP30.h | 0 .../README.md | 0 .../examples/sgp30test/sgp30test.ino | 0 .../library.properties | 0 .../license.txt | 0 .../travis.yml | 0 lib/Adafruit_SGP30_Sensor-1.2.0/license.txt | 26 -- 17 files changed, 553 deletions(-) delete mode 100755 lib/Adafruit_SGP30-1.0.3/.github/ISSUE_TEMPLATE.md delete mode 100755 lib/Adafruit_SGP30-1.0.3/.github/PULL_REQUEST_TEMPLATE.md delete mode 100755 lib/Adafruit_SGP30-1.0.3/.gitignore delete mode 100755 lib/Adafruit_SGP30-1.0.3/.travis.yml delete mode 100755 lib/Adafruit_SGP30-1.0.3/Adafruit_SGP30.cpp delete mode 100755 lib/Adafruit_SGP30-1.0.3/Adafruit_SGP30.h delete mode 100755 lib/Adafruit_SGP30-1.0.3/README.md delete mode 100755 lib/Adafruit_SGP30-1.0.3/examples/sgp30test/sgp30test.ino delete mode 100755 lib/Adafruit_SGP30-1.0.3/library.properties rename lib/{Adafruit_SGP30_Sensor-1.2.0 => Adafruit_SGP30-1.2.0}/Adafruit_SGP30.cpp (100%) rename lib/{Adafruit_SGP30_Sensor-1.2.0 => Adafruit_SGP30-1.2.0}/Adafruit_SGP30.h (100%) rename lib/{Adafruit_SGP30_Sensor-1.2.0 => Adafruit_SGP30-1.2.0}/README.md (100%) rename lib/{Adafruit_SGP30_Sensor-1.2.0 => Adafruit_SGP30-1.2.0}/examples/sgp30test/sgp30test.ino (100%) rename lib/{Adafruit_SGP30_Sensor-1.2.0 => Adafruit_SGP30-1.2.0}/library.properties (100%) rename lib/{Adafruit_SGP30-1.0.3 => Adafruit_SGP30-1.2.0}/license.txt (100%) mode change 100755 => 100644 rename lib/{Adafruit_SGP30_Sensor-1.2.0 => Adafruit_SGP30-1.2.0}/travis.yml (100%) delete mode 100644 lib/Adafruit_SGP30_Sensor-1.2.0/license.txt diff --git a/lib/Adafruit_SGP30-1.0.3/.github/ISSUE_TEMPLATE.md b/lib/Adafruit_SGP30-1.0.3/.github/ISSUE_TEMPLATE.md deleted file mode 100755 index f0e26146f..000000000 --- a/lib/Adafruit_SGP30-1.0.3/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,46 +0,0 @@ -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.3/.github/PULL_REQUEST_TEMPLATE.md b/lib/Adafruit_SGP30-1.0.3/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100755 index 7b641eb86..000000000 --- a/lib/Adafruit_SGP30-1.0.3/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,26 +0,0 @@ -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.3/.gitignore b/lib/Adafruit_SGP30-1.0.3/.gitignore deleted file mode 100755 index 7f189125f..000000000 --- a/lib/Adafruit_SGP30-1.0.3/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*~ -Doxyfile* -doxygen_sqlite3.db -html \ No newline at end of file diff --git a/lib/Adafruit_SGP30-1.0.3/.travis.yml b/lib/Adafruit_SGP30-1.0.3/.travis.yml deleted file mode 100755 index 428f3434e..000000000 --- a/lib/Adafruit_SGP30-1.0.3/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -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.3/Adafruit_SGP30.cpp b/lib/Adafruit_SGP30-1.0.3/Adafruit_SGP30.cpp deleted file mode 100755 index ce6116863..000000000 --- a/lib/Adafruit_SGP30-1.0.3/Adafruit_SGP30.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/*! - * @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; - } - -// assume i2c initialized already to avoid resetting clock stretching -// _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 Set the absolute humidity value [mg/m^3] for compensation to increase precision of TVOC and eCO2. - @param absolute_humidity A uint32_t [mg/m^3] which we will be used for compensation. If the absolute humidity is set to zero, humidity compensation will be disabled. - @returns True if command completed successfully, false if something went wrong! -*/ -/**************************************************************************/ -boolean Adafruit_SGP30::setHumidity(uint32_t absolute_humidity) { - if (absolute_humidity > 256000) { - return false; - } - - uint16_t ah_scaled = (uint16_t)(((uint64_t)absolute_humidity * 256 * 16777) >> 24); - uint8_t command[5]; - command[0] = 0x20; - command[1] = 0x61; - command[2] = ah_scaled >> 8; - command[3] = ah_scaled & 0xFF; - command[4] = generateCRC(command+2, 2); - - return readWordFromCommand(command, 5, 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); - boolean setHumidity(uint32_t absolute_humidity); - - /** - * 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.3/README.md b/lib/Adafruit_SGP30-1.0.3/README.md deleted file mode 100755 index 44056b5c8..000000000 --- a/lib/Adafruit_SGP30-1.0.3/README.md +++ /dev/null @@ -1,18 +0,0 @@ -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.3/examples/sgp30test/sgp30test.ino b/lib/Adafruit_SGP30-1.0.3/examples/sgp30test/sgp30test.ino deleted file mode 100755 index b7ff8a70c..000000000 --- a/lib/Adafruit_SGP30-1.0.3/examples/sgp30test/sgp30test.ino +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include "Adafruit_SGP30.h" - -Adafruit_SGP30 sgp; - -/* return absolute humidity [mg/m^3] with approximation formula -* @param temperature [°C] -* @param humidity [%RH] -*/ -uint32_t getAbsoluteHumidity(float temperature, float humidity) { - // approximation formula from Sensirion SGP30 Driver Integration chapter 3.15 - const float absoluteHumidity = 216.7f * ((humidity / 100.0f) * 6.112f * exp((17.62f * temperature) / (243.12f + temperature)) / (273.15f + temperature)); // [g/m^3] - const uint32_t absoluteHumidityScaled = static_cast(1000.0f * absoluteHumidity); // [mg/m^3] - return absoluteHumidityScaled; -} - -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 you have a temperature / humidity sensor, you can set the absolute humidity to enable the humditiy compensation for the air quality signals - //float temperature = 22.1; // [°C] - //float humidity = 45.2; // [%RH] - //sgp.setHumidity(getAbsoluteHumidity(temperature, humidity)); - - 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.3/library.properties b/lib/Adafruit_SGP30-1.0.3/library.properties deleted file mode 100755 index 6c86464d1..000000000 --- a/lib/Adafruit_SGP30-1.0.3/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=Adafruit SGP30 Sensor -version=1.0.3 -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_Sensor-1.2.0/Adafruit_SGP30.cpp b/lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.cpp similarity index 100% rename from lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.cpp rename to lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.cpp diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.h b/lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.h similarity index 100% rename from lib/Adafruit_SGP30_Sensor-1.2.0/Adafruit_SGP30.h rename to lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.h diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/README.md b/lib/Adafruit_SGP30-1.2.0/README.md similarity index 100% rename from lib/Adafruit_SGP30_Sensor-1.2.0/README.md rename to lib/Adafruit_SGP30-1.2.0/README.md diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/examples/sgp30test/sgp30test.ino b/lib/Adafruit_SGP30-1.2.0/examples/sgp30test/sgp30test.ino similarity index 100% rename from lib/Adafruit_SGP30_Sensor-1.2.0/examples/sgp30test/sgp30test.ino rename to lib/Adafruit_SGP30-1.2.0/examples/sgp30test/sgp30test.ino diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/library.properties b/lib/Adafruit_SGP30-1.2.0/library.properties similarity index 100% rename from lib/Adafruit_SGP30_Sensor-1.2.0/library.properties rename to lib/Adafruit_SGP30-1.2.0/library.properties diff --git a/lib/Adafruit_SGP30-1.0.3/license.txt b/lib/Adafruit_SGP30-1.2.0/license.txt old mode 100755 new mode 100644 similarity index 100% rename from lib/Adafruit_SGP30-1.0.3/license.txt rename to lib/Adafruit_SGP30-1.2.0/license.txt diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/travis.yml b/lib/Adafruit_SGP30-1.2.0/travis.yml similarity index 100% rename from lib/Adafruit_SGP30_Sensor-1.2.0/travis.yml rename to lib/Adafruit_SGP30-1.2.0/travis.yml diff --git a/lib/Adafruit_SGP30_Sensor-1.2.0/license.txt b/lib/Adafruit_SGP30_Sensor-1.2.0/license.txt deleted file mode 100644 index f6a0f22b8..000000000 --- a/lib/Adafruit_SGP30_Sensor-1.2.0/license.txt +++ /dev/null @@ -1,26 +0,0 @@ -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. From 11cb3e838c88c5e3c51813667353d3c9e3b26e59 Mon Sep 17 00:00:00 2001 From: peteakalad Date: Sat, 23 May 2020 22:41:50 +0100 Subject: [PATCH 057/581] Fix for SGP30 for Abs Humidity on Web UI --- tasmota/xsns_21_sgp30.ino | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tasmota/xsns_21_sgp30.ino b/tasmota/xsns_21_sgp30.ino index e3aa2e9e8..ab417a8c3 100644 --- a/tasmota/xsns_21_sgp30.ino +++ b/tasmota/xsns_21_sgp30.ino @@ -118,12 +118,14 @@ void Sgp30Show(bool json) { if (sgp30_ready) { char abs_hum[33]; - + + if (global_update && global_humidity>0 && global_temperature!=9999) { + // has humidity + temperature + dtostrfd(sgp30_abshum,4,abs_hum); + } if (json) { ResponseAppend_P(PSTR(",\"SGP30\":{\"" D_JSON_ECO2 "\":%d,\"" D_JSON_TVOC "\":%d"), sgp.eCO2, sgp.TVOC); if (global_update && global_humidity>0 && global_temperature!=9999) { - // has humidity + temperature - dtostrfd(sgp30_abshum,4,abs_hum); ResponseAppend_P(PSTR(",\"" D_JSON_AHUM "\":%s"),abs_hum); } ResponseJsonEnd(); From f5f1bdefdbe42b3e20b36f217594dc7f2c1ee306 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 24 May 2020 09:57:11 +0200 Subject: [PATCH 058/581] Add wildcard patter for JSON marching in rules using ``?`` pattern --- tasmota/CHANGELOG.md | 1 + tasmota/support.ino | 59 --------------- tasmota/support_json.ino | 106 +++++++++++++++++++++++++++ tasmota/xdrv_10_rules.ino | 29 ++++---- tasmota/xdrv_20_hue.ino | 4 +- tasmota/xdrv_23_zigbee_1_headers.ino | 22 +----- tasmota/xdrv_23_zigbee_2_devices.ino | 8 +- tasmota/xdrv_23_zigbee_3_hue.ino | 6 +- tasmota/xdrv_23_zigbee_8_parsers.ino | 2 +- tasmota/xdrv_23_zigbee_9_impl.ino | 44 +++++------ 10 files changed, 154 insertions(+), 127 deletions(-) create mode 100644 tasmota/support_json.ino diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index b5f6d6ffe..02ae08cb9 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -6,6 +6,7 @@ - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Add Three Phase Export Active Energy to SDM630 driver - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) +- Add wildcard patter for JSON marching in rules using ``?`` pattern ### 8.3.1.1 20200518 diff --git a/tasmota/support.ino b/tasmota/support.ino index cecb5ffb2..c5006cf6c 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1874,65 +1874,6 @@ void AddLogBufferSize(uint32_t loglevel, uint8_t *buffer, uint32_t count, uint32 AddLog(loglevel); } -/*********************************************************************************************\ - * JSON parsing -\*********************************************************************************************/ - -// does the character needs to be escaped, and if so with which character -char escapeJSONChar(char c) { - if ((c == '\"') || (c == '\\')) { - return c; - } - if (c == '\n') { return 'n'; } - if (c == '\t') { return 't'; } - if (c == '\r') { return 'r'; } - if (c == '\f') { return 'f'; } - if (c == '\b') { return 'b'; } - return 0; -} - -String escapeJSONString(const char *str) { - String r(""); - if (nullptr == str) { return r; } - - bool needs_escape = false; - size_t len_out = 1; - const char * c = str; - - while (*c) { - if (escapeJSONChar(*c)) { - len_out++; - needs_escape = true; - } - c++; - len_out++; - } - - if (needs_escape) { - // we need to escape some chars - // allocate target buffer - r.reserve(len_out); - c = str; - char *d = r.begin(); - while (*c) { - char c2 = escapeJSONChar(*c); - if (c2) { - c++; - *d++ = '\\'; - *d++ = c2; - } else { - *d++ = *c++; - } - } - *d = 0; // add NULL terminator - r = (char*) r.begin(); // assign the buffer to the string - } else { - r = str; - } - - return r; -} - /*********************************************************************************************\ * Uncompress static PROGMEM strings \*********************************************************************************************/ diff --git a/tasmota/support_json.ino b/tasmota/support_json.ino new file mode 100644 index 000000000..eb933fc2d --- /dev/null +++ b/tasmota/support_json.ino @@ -0,0 +1,106 @@ +/* + support_json.ino - Static binary buffer for Zigbee on Tasmota + + Copyright (C) 2020 Theo Arends and Stephan Hadinger + + 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 . +*/ + +/*********************************************************************************************\ + * JSON parsing +\*********************************************************************************************/ + +// does the character needs to be escaped, and if so with which character +char EscapeJSONChar(char c) { + if ((c == '\"') || (c == '\\')) { + return c; + } + if (c == '\n') { return 'n'; } + if (c == '\t') { return 't'; } + if (c == '\r') { return 'r'; } + if (c == '\f') { return 'f'; } + if (c == '\b') { return 'b'; } + return 0; +} + +String EscapeJSONString(const char *str) { + String r(""); + if (nullptr == str) { return r; } + + bool needs_escape = false; + size_t len_out = 1; + const char * c = str; + + while (*c) { + if (EscapeJSONChar(*c)) { + len_out++; + needs_escape = true; + } + c++; + len_out++; + } + + if (needs_escape) { + // we need to escape some chars + // allocate target buffer + r.reserve(len_out); + c = str; + char *d = r.begin(); + while (*c) { + char c2 = EscapeJSONChar(*c); + if (c2) { + c++; + *d++ = '\\'; + *d++ = c2; + } else { + *d++ = *c++; + } + } + *d = 0; // add NULL terminator + r = (char*) r.begin(); // assign the buffer to the string + } else { + r = str; + } + + return r; +} + +/*********************************************************************************************\ + * Find key - case insensitive +\*********************************************************************************************/ + +// Given a JsonObject, finds the value as JsonVariant for the key needle. +// The search is case-insensitive, and will find the first match in the order of keys in JSON +// +// If the key is not found, returns a nullptr +// Input: needle cannot be NULL but may be PROGMEM +const JsonVariant &GetCaseInsensitive(const JsonObject &json, const char *needle) { + // key can be in PROGMEM + // if needle == "?" then we return the first valid key + bool wildcard = strcmp_P("?", needle) == 0; + if ((nullptr == &json) || (nullptr == needle) || (0 == pgm_read_byte(needle))) { + return *(JsonVariant*)nullptr; + } + + for (JsonObject::const_iterator it=json.begin(); it!=json.end(); ++it) { + const char *key = it->key; + const JsonVariant &value = it->value; + + if (wildcard || (0 == strcasecmp_P(key, needle))) { + return value; + } + } + // if not found + return *(JsonVariant*)nullptr; +} diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 912a32ae5..1ad618485 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -441,25 +441,20 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) break; } } - snprintf_P(stemp, sizeof(stemp), PSTR("%%TIME%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%TIME%"))) { rule_param = String(MinutesPastMidnight()); } - snprintf_P(stemp, sizeof(stemp), PSTR("%%UPTIME%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%UPTIME%"))) { rule_param = String(MinutesUptime()); } - snprintf_P(stemp, sizeof(stemp), PSTR("%%TIMESTAMP%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%TIMESTAMP%"))) { rule_param = GetDateAndTime(DT_LOCAL).c_str(); } #if defined(USE_TIMERS) && defined(USE_SUNRISE) - snprintf_P(stemp, sizeof(stemp), PSTR("%%SUNRISE%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%SUNRISE%"))) { rule_param = String(SunMinutes(0)); } - snprintf_P(stemp, sizeof(stemp), PSTR("%%SUNSET%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%SUNSET%"))) { rule_param = String(SunMinutes(1)); } #endif // USE_TIMERS and USE_SUNRISE @@ -493,13 +488,17 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) uint32_t i = 0; while ((pos = rule_name.indexOf("#")) > 0) { // "SUBTYPE1#SUBTYPE2#CURRENT" subtype = rule_name.substring(0, pos); - if (!(*obj)[subtype].success()) { return false; } // No subtype in JSON data - JsonObject &obj2 = (*obj)[subtype]; - obj = &obj2; + const JsonVariant & val = GetCaseInsensitive(*obj, subtype.c_str()); + if (nullptr == &val) { return false; } // not found + obj = &(val.as()); + if (!obj->success()) { return false; } // not a JsonObject + rule_name = rule_name.substring(pos +1); if (i++ > 10) { return false; } // Abandon possible loop } - if (!(*obj)[rule_name].success()) { return false; } // No name in JSON data + + const JsonVariant & val = GetCaseInsensitive(*obj, rule_name.c_str()); + if (nullptr == &val) { return false; } // last level not found const char* str_value; if (rule_name_idx) { str_value = (*obj)[rule_name][rule_name_idx -1]; // "CURRENT[1]" @@ -2036,7 +2035,7 @@ void CmndRule(void) XdrvMailbox.command, index, GetStateText(bitRead(Settings.rule_enabled, index -1)), GetStateText(bitRead(Settings.rule_once, index -1)), GetStateText(bitRead(Settings.rule_stop, index -1)), rule_len, MAX_RULE_SIZE - GetRuleLenStorage(index - 1), - escapeJSONString(rule.c_str()).c_str()); + EscapeJSONString(rule.c_str()).c_str()); } } diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index 639f198bb..17a0886db 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -437,8 +437,8 @@ void HueLightStatus2(uint8_t device, String *response) fname[fname_len] = 0x00; } snprintf_P(buf, buf_size, HUE_LIGHTS_STATUS_JSON2, - escapeJSONString(fname).c_str(), - escapeJSONString(Settings.user_template_name).c_str(), + EscapeJSONString(fname).c_str(), + EscapeJSONString(Settings.user_template_name).c_str(), PSTR("Tasmota"), GetHueDeviceId(device).c_str()); *response += buf; diff --git a/tasmota/xdrv_23_zigbee_1_headers.ino b/tasmota/xdrv_23_zigbee_1_headers.ino index 5a250c781..046450927 100644 --- a/tasmota/xdrv_23_zigbee_1_headers.ino +++ b/tasmota/xdrv_23_zigbee_1_headers.ino @@ -23,29 +23,9 @@ void ZigbeeZCLSend_Raw(uint16_t dtsAddr, uint16_t groupaddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId); - -// Get an JSON attribute, with case insensitive key search -const JsonVariant &getCaseInsensitive(const JsonObject &json, const char *needle) { - // key can be in PROGMEM - if ((nullptr == &json) || (nullptr == needle) || (0 == pgm_read_byte(needle))) { - return *(JsonVariant*)nullptr; - } - - for (JsonObject::const_iterator it=json.begin(); it!=json.end(); ++it) { - const char *key = it->key; - const JsonVariant &value = it->value; - - if (0 == strcasecmp_P(key, needle)) { - return value; - } - } - // if not found - return *(JsonVariant*)nullptr; -} - // get the result as a string (const char*) and nullptr if there is no field or the string is empty const char * getCaseInsensitiveConstCharNull(const JsonObject &json, const char *needle) { - const JsonVariant &val = getCaseInsensitive(json, needle); + const JsonVariant &val = GetCaseInsensitive(json, needle); if (&val) { const char *val_cs = val.as(); if (strlen(val_cs)) { diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 74d52c73e..c115052f7 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -1075,7 +1075,7 @@ int32_t Z_Devices::deviceRestore(const JsonObject &json) { size_t endpoints_len = 0; // read mandatory "Device" - const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device")); + const JsonVariant &val_device = GetCaseInsensitive(json, PSTR("Device")); if (nullptr != &val_device) { device = strToUInt(val_device); } else { @@ -1083,7 +1083,7 @@ int32_t Z_Devices::deviceRestore(const JsonObject &json) { } // read "IEEEAddr" 64 bits in format "0x0000000000000000" - const JsonVariant &val_ieeeaddr = getCaseInsensitive(json, PSTR("IEEEAddr")); + const JsonVariant &val_ieeeaddr = GetCaseInsensitive(json, PSTR("IEEEAddr")); if (nullptr != &val_ieeeaddr) { ieeeaddr = strtoull(val_ieeeaddr.as(), nullptr, 0); } @@ -1098,7 +1098,7 @@ int32_t Z_Devices::deviceRestore(const JsonObject &json) { manufid = getCaseInsensitiveConstCharNull(json, PSTR("Manufacturer")); // read "Light" - const JsonVariant &val_bulbtype = getCaseInsensitive(json, PSTR(D_JSON_ZIGBEE_LIGHT)); + const JsonVariant &val_bulbtype = GetCaseInsensitive(json, PSTR(D_JSON_ZIGBEE_LIGHT)); if (nullptr != &val_bulbtype) { bulbtype = strToUInt(val_bulbtype);; } // update internal device information @@ -1109,7 +1109,7 @@ int32_t Z_Devices::deviceRestore(const JsonObject &json) { if (&val_bulbtype) { setHueBulbtype(device, bulbtype); } // read "Endpoints" - const JsonVariant &val_endpoints = getCaseInsensitive(json, PSTR("Endpoints")); + const JsonVariant &val_endpoints = GetCaseInsensitive(json, PSTR("Endpoints")); if ((nullptr != &val_endpoints) && (val_endpoints.is())) { const JsonArray &arr_ep = val_endpoints.as(); endpoints_len = arr_ep.size(); diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino index d5c4b1f08..e4e8a8b63 100644 --- a/tasmota/xdrv_23_zigbee_3_hue.ino +++ b/tasmota/xdrv_23_zigbee_3_hue.ino @@ -85,9 +85,9 @@ void HueLightStatus2Zigbee(uint16_t shortaddr, String *response) snprintf_P(shortaddrname, sizeof(shortaddrname), PSTR("0x%04X"), shortaddr); snprintf_P(buf, buf_size, HUE_LIGHTS_STATUS_JSON2, - (friendlyName) ? escapeJSONString(friendlyName).c_str() : shortaddrname, - (modelId) ? escapeJSONString(modelId).c_str() : PSTR("Unknown"), - (manufacturerId) ? escapeJSONString(manufacturerId).c_str() : PSTR("Tasmota"), + (friendlyName) ? EscapeJSONString(friendlyName).c_str() : shortaddrname, + (modelId) ? EscapeJSONString(modelId).c_str() : PSTR("Unknown"), + (manufacturerId) ? EscapeJSONString(manufacturerId).c_str() : PSTR("Tasmota"), GetHueDeviceId(shortaddr).c_str()); *response += buf; diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 20aecd0f9..ffe108c5a 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -600,7 +600,7 @@ void Z_SendAFInfoRequest(uint16_t shortaddr) { void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, const JsonObject &json) { static const uint32_t OCCUPANCY_TIMEOUT = 90 * 1000; // 90 s // Read OCCUPANCY value if any - const JsonVariant &val_endpoint = getCaseInsensitive(json, PSTR(OCCUPANCY)); + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR(OCCUPANCY)); if (nullptr != &val_endpoint) { uint32_t occupancy = strToUInt(val_endpoint); diff --git a/tasmota/xdrv_23_zigbee_9_impl.ino b/tasmota/xdrv_23_zigbee_9_impl.ino index 40053c5a7..5c5181b6d 100644 --- a/tasmota/xdrv_23_zigbee_9_impl.ino +++ b/tasmota/xdrv_23_zigbee_9_impl.ino @@ -427,13 +427,13 @@ void CmndZbSend(void) { bool clusterSpecific = true; // parse JSON - const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device")); + const JsonVariant &val_device = GetCaseInsensitive(json, PSTR("Device")); if (nullptr != &val_device) { device = zigbee_devices.parseDeviceParam(val_device.as()); if (BAD_SHORTADDR == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } } if (BAD_SHORTADDR == device) { // if not found, check if we have a group - const JsonVariant &val_group = getCaseInsensitive(json, PSTR("Group")); + const JsonVariant &val_group = GetCaseInsensitive(json, PSTR("Group")); if (nullptr != &val_group) { groupaddr = strToUInt(val_group); } else { // no device nor group @@ -442,11 +442,11 @@ void CmndZbSend(void) { } } - const JsonVariant &val_endpoint = getCaseInsensitive(json, PSTR("Endpoint")); + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR("Endpoint")); if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } - const JsonVariant &val_manuf = getCaseInsensitive(json, PSTR("Manuf")); + const JsonVariant &val_manuf = GetCaseInsensitive(json, PSTR("Manuf")); if (nullptr != &val_manuf) { manuf = strToUInt(val_manuf); } - const JsonVariant &val_cmd = getCaseInsensitive(json, PSTR("Send")); + const JsonVariant &val_cmd = GetCaseInsensitive(json, PSTR("Send")); if (nullptr != &val_cmd) { // probe the type of the argument // If JSON object, it's high level commands @@ -582,7 +582,7 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind // Information about source device: "Device", "Endpoint", "Cluster" // - the source endpoint must have a known IEEE address - const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device")); + const JsonVariant &val_device = GetCaseInsensitive(json, PSTR("Device")); if (nullptr != &val_device) { srcDevice = zigbee_devices.parseDeviceParam(val_device.as()); } @@ -591,17 +591,17 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind uint64_t srcLongAddr = zigbee_devices.getDeviceLongAddr(srcDevice); if (0 == srcLongAddr) { ResponseCmndChar_P(PSTR("Unknown source IEEE address")); return; } // look for source endpoint - const JsonVariant &val_endpoint = getCaseInsensitive(json, PSTR("Endpoint")); + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR("Endpoint")); if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } // look for source cluster - const JsonVariant &val_cluster = getCaseInsensitive(json, PSTR("Cluster")); + const JsonVariant &val_cluster = GetCaseInsensitive(json, PSTR("Cluster")); if (nullptr != &val_cluster) { cluster = strToUInt(val_cluster); } // Either Device address // In this case the following parameters are mandatory // - "ToDevice" and the device must have a known IEEE address // - "ToEndpoint" - const JsonVariant &dst_device = getCaseInsensitive(json, PSTR("ToDevice")); + const JsonVariant &dst_device = GetCaseInsensitive(json, PSTR("ToDevice")); if (nullptr != &dst_device) { dstDevice = zigbee_devices.parseDeviceParam(dst_device.as()); if (BAD_SHORTADDR == dstDevice) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } @@ -612,12 +612,12 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind } if (0 == dstLongAddr) { ResponseCmndChar_P(PSTR("Unknown dest IEEE address")); return; } - const JsonVariant &val_toendpoint = getCaseInsensitive(json, PSTR("ToEndpoint")); + const JsonVariant &val_toendpoint = GetCaseInsensitive(json, PSTR("ToEndpoint")); if (nullptr != &val_toendpoint) { toendpoint = strToUInt(val_endpoint); } else { toendpoint = endpoint; } } // Or Group Address - we don't need a dstEndpoint in this case - const JsonVariant &to_group = getCaseInsensitive(json, PSTR("ToGroup")); + const JsonVariant &to_group = GetCaseInsensitive(json, PSTR("ToGroup")); if (nullptr != &to_group) { toGroup = strToUInt(to_group); } // make sure we don't have conflicting parameters @@ -907,13 +907,13 @@ void CmndZbRead(void) { size_t attrs_len = 0; uint8_t* attrs = nullptr; // empty string is valid - const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device")); + const JsonVariant &val_device = GetCaseInsensitive(json, PSTR("Device")); if (nullptr != &val_device) { device = zigbee_devices.parseDeviceParam(val_device.as()); if (BAD_SHORTADDR == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } } if (BAD_SHORTADDR == device) { // if not found, check if we have a group - const JsonVariant &val_group = getCaseInsensitive(json, PSTR("Group")); + const JsonVariant &val_group = GetCaseInsensitive(json, PSTR("Group")); if (nullptr != &val_group) { groupaddr = strToUInt(val_group); } else { // no device nor group @@ -922,14 +922,14 @@ void CmndZbRead(void) { } } - const JsonVariant &val_cluster = getCaseInsensitive(json, PSTR("Cluster")); + const JsonVariant &val_cluster = GetCaseInsensitive(json, PSTR("Cluster")); if (nullptr != &val_cluster) { cluster = strToUInt(val_cluster); } - const JsonVariant &val_endpoint = getCaseInsensitive(json, PSTR("Endpoint")); + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR("Endpoint")); if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } - const JsonVariant &val_manuf = getCaseInsensitive(json, PSTR("Manuf")); + const JsonVariant &val_manuf = GetCaseInsensitive(json, PSTR("Manuf")); if (nullptr != &val_manuf) { manuf = strToUInt(val_manuf); } - const JsonVariant &val_attr = getCaseInsensitive(json, PSTR("Read")); + const JsonVariant &val_attr = GetCaseInsensitive(json, PSTR("Read")); if (nullptr != &val_attr) { uint16_t val = strToUInt(val_attr); if (val_attr.is()) { @@ -1034,21 +1034,21 @@ void CmndZbConfig(void) { if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } // Channel - const JsonVariant &val_channel = getCaseInsensitive(json, PSTR("Channel")); + const JsonVariant &val_channel = GetCaseInsensitive(json, PSTR("Channel")); if (nullptr != &val_channel) { zb_channel = strToUInt(val_channel); } if (zb_channel < 11) { zb_channel = 11; } if (zb_channel > 26) { zb_channel = 26; } // PanID - const JsonVariant &val_pan_id = getCaseInsensitive(json, PSTR("PanID")); + const JsonVariant &val_pan_id = GetCaseInsensitive(json, PSTR("PanID")); if (nullptr != &val_pan_id) { zb_pan_id = strToUInt(val_pan_id); } // ExtPanID - const JsonVariant &val_ext_pan_id = getCaseInsensitive(json, PSTR("ExtPanID")); + const JsonVariant &val_ext_pan_id = GetCaseInsensitive(json, PSTR("ExtPanID")); if (nullptr != &val_ext_pan_id) { zb_ext_panid = strtoull(val_ext_pan_id.as(), nullptr, 0); } // KeyL - const JsonVariant &val_key_l = getCaseInsensitive(json, PSTR("KeyL")); + const JsonVariant &val_key_l = GetCaseInsensitive(json, PSTR("KeyL")); if (nullptr != &val_key_l) { zb_precfgkey_l = strtoull(val_key_l.as(), nullptr, 0); } // KeyH - const JsonVariant &val_key_h = getCaseInsensitive(json, PSTR("KeyH")); + const JsonVariant &val_key_h = GetCaseInsensitive(json, PSTR("KeyH")); if (nullptr != &val_key_h) { zb_precfgkey_h = strtoull(val_key_h.as(), nullptr, 0); } // Check if a parameter was changed after all From fe045c3c9d8c6b3ffce57cd6c63bed7d3deb589a Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 24 May 2020 10:00:32 +0200 Subject: [PATCH 059/581] Fixed description of file --- tasmota/support_json.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support_json.ino b/tasmota/support_json.ino index eb933fc2d..51fa0e6a3 100644 --- a/tasmota/support_json.ino +++ b/tasmota/support_json.ino @@ -1,5 +1,5 @@ /* - support_json.ino - Static binary buffer for Zigbee on Tasmota + support_json.ino - JSON support functions Copyright (C) 2020 Theo Arends and Stephan Hadinger From 6073bd9eb664e986f0befbfc83aa578ad34427ef Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 24 May 2020 11:55:39 +0200 Subject: [PATCH 060/581] Update changelog --- RELEASENOTES.md | 2 ++ tasmota/CHANGELOG.md | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b5c8332c7..f376168d1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -55,11 +55,13 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ### Version 8.3.1.2 - Change IRremoteESP8266 library updated to v2.7.7 +- Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Add command ``Rule0`` to change global rule parameters - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add more functionality to ``Switchmode`` 11 and 12 (#8450) +- Add wildcard pattern ``?`` for JSON matching in rules - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) - Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) - Add Three Phase Export Active Energy to SDM630 driver diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 02ae08cb9..472cb9ffa 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -4,9 +4,10 @@ - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` +- Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Add Three Phase Export Active Energy to SDM630 driver - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) -- Add wildcard patter for JSON marching in rules using ``?`` pattern +- Add wildcard pattern ``?`` for JSON matching in rules ### 8.3.1.1 20200518 From ebbbd37865b9e83bd3145f00b89ee6053f73f863 Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Sun, 24 May 2020 12:28:08 +0200 Subject: [PATCH 061/581] add private pow function in lib for future use alternate pow function for future use in Tasmota to calculate normalized Lux and normalized white values. --- lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp | 27 +++++++++++++++++++-- lib/Adafruit_VEML7700/Adafruit_VEML7700.h | 6 +++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp index 001d4995e..b719af9fa 100644 --- a/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp @@ -76,6 +76,29 @@ boolean Adafruit_VEML7700::begin(TwoWire *theWire) { return true; } +float Adafruit_VEML7700::alternate_pow(float a, float b) +{ + // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ + // calculate approximation with fraction of the exponent + int e = abs((int)b); + union { + double d; + int x[2]; + } u = { a }; + u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447); + u.x[0] = 0; + // exponentiation by squaring with the exponent's integer part + // double r = u.d makes everything much slower, not sure why + double r = 1.0; + while (e) { + if (e & 1) { + r *= a; + } + a *= a; + e >>= 1; + } + return r * u.d; +} float Adafruit_VEML7700::normalize_resolution(float value) { // adjust for gain (1x is normalized) @@ -123,7 +146,7 @@ float Adafruit_VEML7700::readLuxNormalized() { // user-provided correction for non-linearities at high lux/white values: // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ - lux = 6.0135e-13*pow(lux,4) - 9.3924e-9*pow(lux,3) + 8.1488e-5*pow(lux,2) + 1.0023*lux; + lux = 6.0135e-13*alternate_pow(lux,4) - 9.3924e-9*alternate_pow(lux,3) + 8.1488e-5*alternate_pow(lux,2) + 1.0023*lux; } return lux; @@ -156,7 +179,7 @@ float Adafruit_VEML7700::readWhiteNormalized() { // user-provided correction for non-linearities at high lux values: // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ - white = 2E-15*pow(white,4) + 4E-12*pow(white,3) + 9E-06*pow(white,2) + 1.0179*white - 11.052; + white = 2E-15*alternate_pow(white,4) + 4E-12*alternate_pow(white,3) + 9E-06*alternate_pow(white,2) + 1.0179*white - 11.052; } return white; diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h index b842a7bc1..13a0bded5 100644 --- a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h @@ -14,6 +14,11 @@ * BSD license (see license.txt) */ +/* + * change from device111 for Tasmota + * Add alternativ Pow function for readLuxNormalized() and readWhiteNormalized() + */ + #ifndef _ADAFRUIT_VEML7700_H #define _ADAFRUIT_VEML7700_H @@ -105,6 +110,7 @@ private: *PowerSave_Enable, *PowerSave_Mode; float normalize_resolution(float value); + float alternate_pow(float a, float b); Adafruit_I2CDevice *i2c_dev; From e1e604ee1263e72d03e17c178b32cda07b3e39c3 Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Sun, 24 May 2020 16:14:49 +0200 Subject: [PATCH 062/581] update veml7700 libary --- lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp | 24 --------------------- lib/Adafruit_VEML7700/Adafruit_VEML7700.h | 3 ++- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp index b719af9fa..27a9fc3a6 100644 --- a/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp @@ -76,30 +76,6 @@ boolean Adafruit_VEML7700::begin(TwoWire *theWire) { return true; } -float Adafruit_VEML7700::alternate_pow(float a, float b) -{ - // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ - // calculate approximation with fraction of the exponent - int e = abs((int)b); - union { - double d; - int x[2]; - } u = { a }; - u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447); - u.x[0] = 0; - // exponentiation by squaring with the exponent's integer part - // double r = u.d makes everything much slower, not sure why - double r = 1.0; - while (e) { - if (e & 1) { - r *= a; - } - a *= a; - e >>= 1; - } - return r * u.d; -} - float Adafruit_VEML7700::normalize_resolution(float value) { // adjust for gain (1x is normalized) switch (getGain()) { diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h index 13a0bded5..4ff8f3f78 100644 --- a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h @@ -62,6 +62,7 @@ #define VEML7700_POWERSAVE_MODE3 0x02 ///< Power saving mode 3 #define VEML7700_POWERSAVE_MODE4 0x03 ///< Power saving mode 4 +extern float FastPrecisePowf(const float x, const float y); /*! * @brief Class that stores state and functions for interacting with @@ -110,7 +111,7 @@ private: *PowerSave_Enable, *PowerSave_Mode; float normalize_resolution(float value); - float alternate_pow(float a, float b); + static inline float alternate_pow(float a, float b) { return FastPrecisePowf(a, b); } Adafruit_I2CDevice *i2c_dev; From 3829265e6dc80d23deb2d39a0677591d81433550 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 24 May 2020 17:13:10 +0200 Subject: [PATCH 063/581] Consolidate FastPrecisePowf --- .../src/MutichannelGasSensor.cpp | 50 +++++-------------- .../src/MutichannelGasSensor.h | 18 ++++--- .../esp-knx-ip-conversion.cpp | 26 +--------- lib/esp-knx-ip-0.5.2/esp-knx-ip.h | 5 ++ 4 files changed, 30 insertions(+), 69 deletions(-) diff --git a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp index 66e62fa4a..2d4d4c5dd 100644 --- a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp +++ b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp @@ -327,30 +327,6 @@ int16_t MutichannelGasSensor::readR(void) ** Returns: float value - concentration of the gas *********************************************************************************************************/ -float MutichannelGasSensor_pow(float a, float b) -{ - // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ - // calculate approximation with fraction of the exponent - int e = abs((int)b); - union { - double d; - int x[2]; - } u = { a }; - u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447); - u.x[0] = 0; - // exponentiation by squaring with the exponent's integer part - // double r = u.d makes everything much slower, not sure why - double r = 1.0; - while (e) { - if (e & 1) { - r *= a; - } - a *= a; - e >>= 1; - } - return r * u.d; -} - float MutichannelGasSensor::calcGas(int gas) { @@ -382,9 +358,9 @@ float MutichannelGasSensor::calcGas(int gas) int An_1 = get_addr_dta(CH_VALUE_CO); int An_2 = get_addr_dta(CH_VALUE_NO2); - ratio0 = (float)An_0/(float)A0_0*(1023.0-A0_0)/(1023.0-An_0); - ratio1 = (float)An_1/(float)A0_1*(1023.0-A0_1)/(1023.0-An_1); - ratio2 = (float)An_2/(float)A0_2*(1023.0-A0_2)/(1023.0-An_2); + ratio0 = (float)An_0/(float)A0_0*(1023.0f-A0_0)/(1023.0f-An_0); + ratio1 = (float)An_1/(float)A0_1*(1023.0f-A0_1)/(1023.0f-An_1); + ratio2 = (float)An_2/(float)A0_2*(1023.0f-A0_2)/(1023.0f-An_2); } @@ -394,42 +370,42 @@ float MutichannelGasSensor::calcGas(int gas) { case CO: { - c = MutichannelGasSensor_pow(ratio1, -1.179)*4.385; //mod by jack + c = pow(ratio1, -1.179f)*4.385f; //mod by jack break; } case NO2: { - c = MutichannelGasSensor_pow(ratio2, 1.007)/6.855; //mod by jack + c = pow(ratio2, 1.007f)/6.855f; //mod by jack break; } case NH3: { - c = MutichannelGasSensor_pow(ratio0, -1.67)/1.47; //modi by jack + c = pow(ratio0, -1.67f)/1.47f; //modi by jack break; } case C3H8: //add by jack { - c = MutichannelGasSensor_pow(ratio0, -2.518)*570.164; + c = pow(ratio0, -2.518f)*570.164f; break; } case C4H10: //add by jack { - c = MutichannelGasSensor_pow(ratio0, -2.138)*398.107; + c = pow(ratio0, -2.138f)*398.107f; break; } case GAS_CH4: //add by jack { - c = MutichannelGasSensor_pow(ratio1, -4.363)*630.957; + c = pow(ratio1, -4.363f)*630.957f; break; } case H2: //add by jack { - c = MutichannelGasSensor_pow(ratio1, -1.8)*0.73; + c = pow(ratio1, -1.8f)*0.73f; break; } case C2H5OH: //add by jack { - c = MutichannelGasSensor_pow(ratio1, -1.552)*1.622; + c = pow(ratio1, -1.552f)*1.622f; break; } default: @@ -630,7 +606,7 @@ float MutichannelGasSensor::getR0(unsigned char ch) // 0:CH3, 1:CO, 2:NO default:; } - float r = 56.0*(float)a/(1023.0-(float)a); + float r = 56.0f*(float)a/(1023.0f-(float)a); return r; } @@ -661,7 +637,7 @@ float MutichannelGasSensor::getRs(unsigned char ch) // 0:CH3, 1:CO, 2:NO default:; } - float r = 56.0*(float)a/(1023.0-(float)a); + float r = 56.0f*(float)a/(1023.0f-(float)a); return r; } diff --git a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h index 5f4ce7c7f..87ad10b46 100644 --- a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h +++ b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h @@ -6,7 +6,7 @@ 2015-3-17 http://www.seeed.cc/ modi by Jack, 2015-8 - + V2 by Loovee 2016-11-11 @@ -38,7 +38,7 @@ #define DEFAULT_I2C_ADDR 0x04 -#define ADDR_IS_SET 0 // if this is the first time to run, if 1126, set +#define ADDR_IS_SET 0 // if this is the first time to run, if 1126, set #define ADDR_FACTORY_ADC_NH3 2 #define ADDR_FACTORY_ADC_CO 4 #define ADDR_FACTORY_ADC_NO2 6 @@ -68,19 +68,23 @@ enum{CO, NO2, NH3, C3H8, C4H10, GAS_CH4, H2, C2H5OH}; +// FastPrecisePowf from tasmota/support_float.ino +extern float FastPrecisePowf(const float x, const float y); + class MutichannelGasSensor{ private: + static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } int __version; int __send_error; unsigned char dta_test[20]; - + unsigned int readChAdcValue(int ch); unsigned int adcValueR0_NH3_Buf; unsigned int adcValueR0_CO_Buf; unsigned int adcValueR0_NO2_Buf; - + public: uint8_t i2cAddress; //I2C address of this MCU @@ -98,7 +102,7 @@ public: int16_t readR0(void); int16_t readR(void); float calcGas(int gas); - + public: void begin(int address); @@ -107,7 +111,7 @@ public: void powerOn(void); void powerOff(void); void doCalibrate(void); - + //get gas concentration, unit: ppm float measure_CO(){return calcGas(CO);} float measure_NO2(){return calcGas(NO2);} @@ -117,7 +121,7 @@ public: float measure_CH4(){return calcGas(GAS_CH4);} float measure_H2(){return calcGas(H2);} float measure_C2H5OH(){return calcGas(C2H5OH);} - + float getR0(unsigned char ch); // 0:CH3, 1:CO, 2:NO2 float getRs(unsigned char ch); // 0:CH3, 1:CO, 2:NO2 diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip-conversion.cpp b/lib/esp-knx-ip-0.5.2/esp-knx-ip-conversion.cpp index 02f2f59be..9dc2fd563 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip-conversion.cpp +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip-conversion.cpp @@ -35,36 +35,12 @@ uint16_t ESPKNXIP::data_to_2byte_uint(uint8_t *data) return (uint16_t)((data[1] << 8) | data[2]); } -float esp_knx_pow(float a, float b) -{ - // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ - // calculate approximation with fraction of the exponent - int e = abs((int)b); - union { - double d; - int x[2]; - } u = { a }; - u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447); - u.x[0] = 0; - // exponentiation by squaring with the exponent's integer part - // double r = u.d makes everything much slower, not sure why - double r = 1.0; - while (e) { - if (e & 1) { - r *= a; - } - a *= a; - e >>= 1; - } - return r * u.d; -} - float ESPKNXIP::data_to_2byte_float(uint8_t *data) { //uint8_t sign = (data[1] & 0b10000000) >> 7; uint8_t expo = (data[1] & 0b01111000) >> 3; int16_t mant = ((data[1] & 0b10000111) << 8) | data[2]; - return 0.01f * mant * esp_knx_pow(2, expo); + return 0.01f * mant * pow(2, expo); } time_of_day_t ESPKNXIP::data_to_3byte_time(uint8_t *data) diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h index 7c6377bec..ea711825f 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h @@ -397,6 +397,9 @@ typedef struct __callback_assignment callback_id_t callback_id; } callback_assignment_t; +// FastPrecisePowf from tasmota/support_float.ino +extern float FastPrecisePowf(const float x, const float y); + class ESPKNXIP { public: ESPKNXIP(); @@ -564,6 +567,8 @@ class ESPKNXIP { callback_assignment_id_t __callback_register_assignment(address_t address, callback_id_t id); void __callback_delete_assignment(callback_assignment_id_t id); + static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } + ESP8266WebServer *server; address_t physaddr; From a4ce4830e867580097f672b8fbffbdc2728213fe Mon Sep 17 00:00:00 2001 From: Matthijs Abma <4146168+abmaonline@users.noreply.github.com> Date: Sat, 23 May 2020 17:34:59 +0200 Subject: [PATCH 064/581] Encode content when not raw or json --- tasmota/support_tasmota.ino | 6 +++++- tasmota/xdrv_08_serial_bridge.ino | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 671b4ad9d..6ccd057da 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1349,7 +1349,11 @@ void SerialInput(void) bool assume_json = (!Settings.flag.mqtt_serial_raw && (serial_in_buffer[0] == '{')); Response_P(PSTR("{\"" D_JSON_SERIALRECEIVED "\":%s%s%s}"), (assume_json) ? "" : "\"", - (Settings.flag.mqtt_serial_raw) ? ToHex_P((unsigned char*)serial_in_buffer, serial_in_byte_counter, hex_char, sizeof(hex_char)) : serial_in_buffer, + (Settings.flag.mqtt_serial_raw) + ? ToHex_P((unsigned char*)serial_in_buffer, serial_in_byte_counter, hex_char, sizeof(hex_char)) + : (assume_json) + ? serial_in_buffer + : EscapeJSONString(serial_in_buffer).c_str(), (assume_json) ? "" : "\""); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED)); XdrvRulesProcess(); diff --git a/tasmota/xdrv_08_serial_bridge.ino b/tasmota/xdrv_08_serial_bridge.ino index a713b5cfb..7aa6397dd 100644 --- a/tasmota/xdrv_08_serial_bridge.ino +++ b/tasmota/xdrv_08_serial_bridge.ino @@ -80,7 +80,11 @@ void SerialBridgeInput(void) bool assume_json = (!serial_bridge_raw && (serial_bridge_buffer[0] == '{')); Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":%s%s%s}"), (assume_json) ? "" : "\"", - (serial_bridge_raw) ? ToHex_P((unsigned char*)serial_bridge_buffer, serial_bridge_in_byte_counter, hex_char, sizeof(hex_char)) : serial_bridge_buffer, + (serial_bridge_raw) + ? ToHex_P((unsigned char*)serial_bridge_buffer, serial_bridge_in_byte_counter, hex_char, sizeof(hex_char)) + : (assume_json) + ? serial_bridge_buffer + : EscapeJSONString(serial_bridge_buffer).c_str(), (assume_json) ? "" : "\""); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); XdrvRulesProcess(); From 7210934774818200f14f37eb0a1c06e7361705c1 Mon Sep 17 00:00:00 2001 From: Matthijs Abma <4146168+abmaonline@users.noreply.github.com> Date: Sun, 24 May 2020 17:15:06 +0200 Subject: [PATCH 065/581] Cleanup code and only allocate buffer when needed --- tasmota/support_tasmota.ino | 25 ++++++++++++++++--------- tasmota/xdrv_08_serial_bridge.ino | 25 ++++++++++++++++--------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 6ccd057da..e0a45ce77 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1345,16 +1345,23 @@ void SerialInput(void) if (Settings.flag.mqtt_serial && serial_in_byte_counter && (millis() > (serial_polling_window + SERIAL_POLLING))) { // CMND_SERIALSEND and CMND_SERIALLOG serial_in_buffer[serial_in_byte_counter] = 0; // Serial data completed - char hex_char[(serial_in_byte_counter * 2) + 2]; bool assume_json = (!Settings.flag.mqtt_serial_raw && (serial_in_buffer[0] == '{')); - Response_P(PSTR("{\"" D_JSON_SERIALRECEIVED "\":%s%s%s}"), - (assume_json) ? "" : "\"", - (Settings.flag.mqtt_serial_raw) - ? ToHex_P((unsigned char*)serial_in_buffer, serial_in_byte_counter, hex_char, sizeof(hex_char)) - : (assume_json) - ? serial_in_buffer - : EscapeJSONString(serial_in_buffer).c_str(), - (assume_json) ? "" : "\""); + + Response_P(PSTR("{\"" D_JSON_SERIALRECEIVED "\":")); + if (assume_json) { + ResponseAppend_P(serial_in_buffer); + } else { + ResponseAppend_P(PSTR("\"")); + if (Settings.flag.mqtt_serial_raw) { + char hex_char[(serial_in_byte_counter * 2) + 2]; + ResponseAppend_P(ToHex_P((unsigned char*)serial_in_buffer, serial_in_byte_counter, hex_char, sizeof(hex_char))); + } else { + ResponseAppend_P(EscapeJSONString(serial_in_buffer).c_str()); + } + ResponseAppend_P(PSTR("\"")); + } + ResponseAppend_P(PSTR("}")); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED)); XdrvRulesProcess(); serial_in_byte_counter = 0; diff --git a/tasmota/xdrv_08_serial_bridge.ino b/tasmota/xdrv_08_serial_bridge.ino index 7aa6397dd..e50d4dd33 100644 --- a/tasmota/xdrv_08_serial_bridge.ino +++ b/tasmota/xdrv_08_serial_bridge.ino @@ -76,16 +76,23 @@ void SerialBridgeInput(void) if (serial_bridge_in_byte_counter && (millis() > (serial_bridge_polling_window + SERIAL_POLLING))) { serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // Serial data completed - char hex_char[(serial_bridge_in_byte_counter * 2) + 2]; bool assume_json = (!serial_bridge_raw && (serial_bridge_buffer[0] == '{')); - Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":%s%s%s}"), - (assume_json) ? "" : "\"", - (serial_bridge_raw) - ? ToHex_P((unsigned char*)serial_bridge_buffer, serial_bridge_in_byte_counter, hex_char, sizeof(hex_char)) - : (assume_json) - ? serial_bridge_buffer - : EscapeJSONString(serial_bridge_buffer).c_str(), - (assume_json) ? "" : "\""); + + Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":")); + if (assume_json) { + ResponseAppend_P(serial_bridge_buffer); + } else { + ResponseAppend_P(PSTR("\"")); + if (serial_bridge_raw) { + char hex_char[(serial_bridge_in_byte_counter * 2) + 2]; + ResponseAppend_P(ToHex_P((unsigned char*)serial_bridge_buffer, serial_bridge_in_byte_counter, hex_char, sizeof(hex_char))); + } else { + ResponseAppend_P(EscapeJSONString(serial_bridge_buffer).c_str()); + } + ResponseAppend_P(PSTR("\"")); + } + ResponseAppend_P(PSTR("}")); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); XdrvRulesProcess(); serial_bridge_in_byte_counter = 0; From 721c2c8f7fe0a7ae88fd4211d56d58bbdab71961 Mon Sep 17 00:00:00 2001 From: Matthijs Abma <4146168+abmaonline@users.noreply.github.com> Date: Sun, 24 May 2020 17:23:26 +0200 Subject: [PATCH 066/581] Reduce input buffer so hex/json encoded content always fits --- tasmota/tasmota.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 7434ff28e..942d718d2 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -124,12 +124,12 @@ const uint16_t SYSLOG_TIMER = 600; // Seconds to restore syslog_level const uint16_t SERIALLOG_TIMER = 600; // Seconds to disable SerialLog const uint8_t OTA_ATTEMPTS = 5; // Number of times to try fetching the new firmware -const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in serial command buffer +const uint16_t INPUT_BUFFER_SIZE = 510; // Max number of characters in serial command buffer: floor((MIN_MESSZ - len({"SerialReceived":""})) / 2) + 1 const uint16_t FLOATSZ = 16; // Max number of characters in float result from dtostrfd (max 32) const uint16_t CMDSZ = 24; // Max number of characters in command const uint16_t TOPSZ = 151; // Max number of characters in topic string const uint16_t LOGSZ = 700; // Max number of characters in log -const uint16_t MIN_MESSZ = 1040; // Min number of characters in MQTT message (1000 - TOPSZ - 9 header bytes) +const uint16_t MIN_MESSZ = 1040; // Min number of characters in MQTT message (1200 - TOPSZ - 9 header bytes) const uint8_t SENSOR_MAX_MISS = 5; // Max number of missed sensor reads before deciding it's offline From 822062fa899817c9df33c886564627ecc4b4df4b Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Sun, 24 May 2020 18:55:35 +0200 Subject: [PATCH 067/581] Consolidate FastPrecisePowf in veml7700 lib --- lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp | 8 ++++---- lib/Adafruit_VEML7700/Adafruit_VEML7700.h | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp index 27a9fc3a6..254d74788 100644 --- a/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp @@ -109,7 +109,7 @@ float Adafruit_VEML7700::normalize_resolution(float value) { * @returns Floating point Lux data (ALS multiplied by 0.0576) */ float Adafruit_VEML7700::readLux() { - return ( normalize_resolution(ALS_Data->read()) * 0.0576); // see app note lux table on page 5 + return ( normalize_resolution(ALS_Data->read()) * 0.0576f); // see app note lux table on page 5 } /*! @@ -122,7 +122,7 @@ float Adafruit_VEML7700::readLuxNormalized() { // user-provided correction for non-linearities at high lux/white values: // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ - lux = 6.0135e-13*alternate_pow(lux,4) - 9.3924e-9*alternate_pow(lux,3) + 8.1488e-5*alternate_pow(lux,2) + 1.0023*lux; + lux = 6.0135e-13f * pow(lux,4) - 9.3924e-9f * pow(lux,3) + 8.1488e-5f * pow(lux,2) + 1.0023f * lux; } return lux; @@ -142,7 +142,7 @@ uint16_t Adafruit_VEML7700::readALS() { */ float Adafruit_VEML7700::readWhite() { // white_corrected= 2E-15*pow(VEML_white,4) + 4E-12*pow(VEML_white,3) + 9E-06*pow(VEML_white,)2 + 1.0179*VEML_white - 11.052; - return normalize_resolution(White_Data->read()) * 0.0576; // Unclear if this is the right multiplier + return normalize_resolution(White_Data->read()) * 0.0576f; // Unclear if this is the right multiplier } /*! @@ -155,7 +155,7 @@ float Adafruit_VEML7700::readWhiteNormalized() { // user-provided correction for non-linearities at high lux values: // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ - white = 2E-15*alternate_pow(white,4) + 4E-12*alternate_pow(white,3) + 9E-06*alternate_pow(white,2) + 1.0179*white - 11.052; + white = 2E-15f * pow(white,4) + 4E-12f * pow(white,3) + 9E-06f * pow(white,2) + 1.0179f * white - 11.052f; } return white; diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h index 4ff8f3f78..5ae23f3b6 100644 --- a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h @@ -62,6 +62,7 @@ #define VEML7700_POWERSAVE_MODE3 0x02 ///< Power saving mode 3 #define VEML7700_POWERSAVE_MODE4 0x03 ///< Power saving mode 4 +// FastPrecisePowf from tasmota/support_float.ino extern float FastPrecisePowf(const float x, const float y); /*! @@ -111,7 +112,7 @@ private: *PowerSave_Enable, *PowerSave_Mode; float normalize_resolution(float value); - static inline float alternate_pow(float a, float b) { return FastPrecisePowf(a, b); } + static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } Adafruit_I2CDevice *i2c_dev; From eb6de5362804e44beeafd936ad56026048f1098c Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Sun, 24 May 2020 20:07:25 +0200 Subject: [PATCH 068/581] Fix setting addr typo --- tasmota/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 6ff0c4213..d524153aa 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -515,7 +515,7 @@ struct { uint8_t ot_hot_water_setpoint; // E8C uint8_t ot_boiler_setpoint; // E8D uint8_t ot_flags; // E8E - uint8_t ledpwm_mask; // F8F + uint8_t ledpwm_mask; // E8F uint16_t dimmer_hw_min; // E90 uint16_t dimmer_hw_max; // E92 uint32_t deepsleep; // E94 From c333b67669da0d72b0fb542d17ed8606b8850475 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 25 May 2020 10:21:36 +0200 Subject: [PATCH 069/581] Fix DisplaySevenSegment compilation error --- tasmota/settings.h | 2 +- tasmota/xdsp_11_sevenseg.ino | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index d524153aa..23a477e12 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -515,7 +515,7 @@ struct { uint8_t ot_hot_water_setpoint; // E8C uint8_t ot_boiler_setpoint; // E8D uint8_t ot_flags; // E8E - uint8_t ledpwm_mask; // E8F + uint8_t ledpwm_mask; // E8F uint16_t dimmer_hw_min; // E90 uint16_t dimmer_hw_max; // E92 uint32_t deepsleep; // E94 diff --git a/tasmota/xdsp_11_sevenseg.ino b/tasmota/xdsp_11_sevenseg.ino index 80056aa6e..20193e54e 100644 --- a/tasmota/xdsp_11_sevenseg.ino +++ b/tasmota/xdsp_11_sevenseg.ino @@ -239,8 +239,6 @@ void SevensegTime(boolean time_24) sevenseg.writeDisplay(); } -#endif // USE_DISPLAY_MODES1TO5 - void SevensegRefresh(void) // Every second { if (disp_power) { @@ -262,6 +260,8 @@ void SevensegRefresh(void) // Every second } } +#endif // USE_DISPLAY_MODES1TO5 + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -286,9 +286,11 @@ bool Xdsp11(uint8_t function) case FUNC_DISPLAY_CLEAR: SevensegClear(); break; +#ifdef USE_DISPLAY_MODES1TO5 case FUNC_DISPLAY_EVERY_SECOND: SevensegRefresh(); break; +#endif // USE_DISPLAY_MODES1TO5 case FUNC_DISPLAY_ONOFF: case FUNC_DISPLAY_POWER: SevensegOnOff(); From 90d3cd45c4c6043bff73b06d02fd0144528e57f5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 25 May 2020 11:44:17 +0200 Subject: [PATCH 070/581] Add command ``Time 4`` Add command ``Time 4`` to display timestamp using milliseconds (#8537) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 3 ++- tasmota/support.ino | 3 +++ tasmota/support_command.ino | 4 ++-- tasmota/support_rtc.ino | 7 +++++++ 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f376168d1..f78f518d5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -59,6 +59,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Add command ``Rule0`` to change global rule parameters +- Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add more functionality to ``Switchmode`` 11 and 12 (#8450) - Add wildcard pattern ``?`` for JSON matching in rules diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 472cb9ffa..91ddbf196 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -5,8 +5,9 @@ - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) -- Add Three Phase Export Active Energy to SDM630 driver +- Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) +- Add Three Phase Export Active Energy to SDM630 driver - Add wildcard pattern ``?`` for JSON matching in rules ### 8.3.1.1 20200518 diff --git a/tasmota/support.ino b/tasmota/support.ino index c5006cf6c..21d79b510 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -996,6 +996,9 @@ char* ResponseGetTime(uint32_t format, char* time_str) case 2: snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":%u"), UtcTime()); break; + case 3: + snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s.%d\""), GetDateAndTime(DT_LOCAL).c_str(), RtcMillis()); + break; default: snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 9851a5654..9d9fbfa19 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1641,12 +1641,12 @@ void CmndTime(void) // payload 1 = Time format {"Time":"2019-09-04T14:31:29"} // payload 2 = Time format {"Time":"2019-09-04T14:31:29","Epoch":1567600289} // payload 3 = Time format {"Time":1567600289} -// payload 4 = reserved +// payload 4 = Time format {"Time":"2019-09-04T14:31:29.123"} // payload 1451602800 - disable NTP and set time to epoch uint32_t format = Settings.flag2.time_format; if (XdrvMailbox.data_len > 0) { - if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 4)) { + if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 5)) { Settings.flag2.time_format = XdrvMailbox.payload -1; format = Settings.flag2.time_format; } else { diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino index 0b2249ec2..44e7dad29 100644 --- a/tasmota/support_rtc.ino +++ b/tasmota/support_rtc.ino @@ -47,6 +47,7 @@ struct RTC { uint32_t ntp_time = 0; uint32_t midnight = 0; uint32_t restart_time = 0; + uint32_t millis = 0; int32_t time_timezone = 0; uint8_t ntp_sync_minute = 0; bool midnight_now = false; @@ -239,6 +240,10 @@ uint32_t MinutesPastMidnight(void) return minutes; } +uint32_t RtcMillis(void) { + return (millis() - Rtc.millis) % 1000; +} + void BreakTime(uint32_t time_input, TIME_T &tm) { // break the given time_input into time components @@ -362,6 +367,8 @@ void RtcSecond(void) { TIME_T tmpTime; + Rtc.millis = millis(); + if (!Rtc.user_time_entry && !global_state.wifi_down) { uint8_t uptime_minute = (uptime / 60) % 60; // 0 .. 59 if ((Rtc.ntp_sync_minute > 59) && (uptime_minute > 2)) { From c1979cbd1839dafa9950440c2a0dc193224230c7 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 25 May 2020 15:49:03 +0200 Subject: [PATCH 071/581] fix >W section bug, some refactoring --- tasmota/xdrv_10_scripter.ino | 410 ++++++++++++++++++----------------- 1 file changed, 214 insertions(+), 196 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index cf148c97b..434028092 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -1993,12 +1993,13 @@ chknext: goto exit; } #endif + #if defined(USE_SML_M) && defined (USE_SML_SCRIPT_CMD) if (!strncmp(vname,"sml[",4)) { lp+=4; lp=GetNumericResult(lp,OPER_EQU,&fvar,0); SCRIPT_SKIP_SPACES - fvar=SML_GetVal[fvar]; + fvar=SML_GetVal(fvar); lp++; len=0; goto exit; @@ -2786,6 +2787,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { if (tasm_cmd_activ && tlen>0) return 0; uint8_t vtype=0,sindex,xflg,floop=0,globvindex,fromscriptcmd=0; + char *lp_next; int8_t globaindex; struct T_INDEX ind; uint8_t operand,lastop,numeric=1,if_state[IF_NEST],if_exe[IF_NEST],if_result[IF_NEST],and_or,ifstck=0; @@ -2925,6 +2927,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { // simple implementation, zero loop count not supported lp+=3; SCRIPT_SKIP_SPACES + lp_next=0; lp=isvar(lp,&vtype,&ind,0,0,0); if ((vtype!=VAR_NV) && (vtype&STYPE)==0) { // numeric var @@ -2947,22 +2950,26 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { // error toLogEOL("for error",lp); } - } else if (!strncmp(lp,"next",4) && floop>0) { - // for next loop - *cv_count+=cv_inc; - if (floop==1) { - if (*cv_count<=cv_max) { - lp=cv_ptr; + } else if (!strncmp(lp,"next",4)) { + lp+=4; + lp_next=lp; + if (floop>0) { + // for next loop + *cv_count+=cv_inc; + if (floop==1) { + if (*cv_count<=cv_max) { + lp=cv_ptr; + } else { + lp+=4; + floop=0; + } } else { - lp+=4; - floop=0; - } - } else { - if (*cv_count>=cv_max) { - lp=cv_ptr; - } else { - lp+=4; - floop=0; + if (*cv_count>=cv_max) { + lp=cv_ptr; + } else { + lp+=4; + floop=0; + } } } } @@ -3022,13 +3029,15 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { #endif if (!strncmp(lp,"break",5)) { - if (floop) { + lp+=5; + if (floop && lp_next) { // should break loop + lp=lp_next; floop=0; } else { section=0; } - break; + goto next_line; } else if (!strncmp(lp,"dp",2) && isdigit(*(lp+2))) { lp+=2; // number precision @@ -3357,6 +3366,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { goto next_line; } } else { + //Serial.printf(">> decode %s\n",lp ); // decode line if (*lp=='>' && tlen==1) { // called from cmdline @@ -4998,6 +5008,9 @@ const char SCRIPT_MSG_GTABLEb[] PROGMEM = const char SCRIPT_MSG_GOPT1[] PROGMEM = "title:'%s',isStacked:false"; +const char SCRIPT_MSG_GAUGEOPT[] PROGMEM = +"max:%d,redFrom:%d,redTo:%d,yellowFrom:%d,yellowTo:%d"; + const char SCRIPT_MSG_GOPT2[] PROGMEM = "showRowNumber:true,sort:'disable',allowHtml:true,width:'100%%',height:'100%%',cssClassNames:cssc"; @@ -5029,7 +5042,8 @@ uint8 entries=0; while (anum> %d - %d - %d\n",anum,entries,(uint32_t)*arrays[0]); *ranum=anum; *rentries=entries; return lp; @@ -5089,8 +5109,7 @@ uint32_t cnt; void ScriptWebShow(char mc) { uint8_t web_script=Run_Scripter(">W",-2,0); if (web_script==99) { - char line[128]; - char tmp[128]; + char tmp[256]; uint8_t optflg=0; uint8_t chartindex=1; uint8_t google_libs=0; @@ -5104,96 +5123,27 @@ void ScriptWebShow(char mc) { } if (*lp!=';') { // send this line to web - memcpy(line,lp,sizeof(line)); - line[sizeof(line)-1]=0; - char *cp=line; - for (uint32_t i=0; i0) { - cp="checked='checked'"; - uval=0; + Replace_Cmd_Vars(lp,1,tmp,sizeof(tmp)); + char *lin=tmp; + if (!mc && (*lin!='$')) { + // normal web section + if (*lin=='@') { + lin++; + optflg=1; } else { - cp=""; - uval=1; + optflg=0; } - WSContentSend_PD(SCRIPT_MSG_CHKBOX,label,(char*)cp,uval,vname); - - } else if (!strncmp(lin,"bu(",3)) { - char *lp=lin+3; - uint8_t bcnt=0; - char *found=lin; - while (bcnt<4) { - found=strstr(found,"bu("); - if (!found) break; - found+=3; - bcnt++; - } - uint8_t proz=100/bcnt; - if (!optflg && bcnt>1) proz-=2; - if (optflg) WSContentSend_PD(SCRIPT_MSG_BUT_START_TBL); - else WSContentSend_PD(SCRIPT_MSG_BUT_START); - for (uint32_t cnt=0;cnt0) { - cp=ontxt; + cp="checked='checked'"; uval=0; } else { - cp=offtxt; + cp=""; uval=1; } - if (bcnt>1 && cnt==bcnt-1) { - if (!optflg) proz+=2; + WSContentSend_PD(SCRIPT_MSG_CHKBOX,label,(char*)cp,uval,vname); + + } else if (!strncmp(lin,"bu(",3)) { + char *lp=lin+3; + uint8_t bcnt=0; + char *found=lin; + while (bcnt<4) { + found=strstr(found,"bu("); + if (!found) break; + found+=3; + bcnt++; } - if (!optflg) { - WSContentSend_PD(SCRIPT_MSG_BUTTONa,proz,uval,vname,cp); - } else { - WSContentSend_PD(SCRIPT_MSG_BUTTONa_TBL,proz,uval,vname,cp); + uint8_t proz=100/bcnt; + if (!optflg && bcnt>1) proz-=2; + if (optflg) WSContentSend_PD(SCRIPT_MSG_BUT_START_TBL); + else WSContentSend_PD(SCRIPT_MSG_BUT_START); + for (uint32_t cnt=0;cnt0) { + cp=ontxt; + uval=0; + } else { + cp=offtxt; + uval=1; + } + if (bcnt>1 && cnt==bcnt-1) { + if (!optflg) proz+=2; + } + if (!optflg) { + WSContentSend_PD(SCRIPT_MSG_BUTTONa,proz,uval,vname,cp); + } else { + WSContentSend_PD(SCRIPT_MSG_BUTTONa_TBL,proz,uval,vname,cp); + } + if (bcnt>1 && cnt1 && cnt%s
"),tmp); } else { - WSContentSend_PD(PSTR("{s}%s{e}"),tmp); + if (optflg) { + WSContentSend_PD(PSTR("
%s
"),tmp); + } else { + WSContentSend_PD(PSTR("{s}%s{e}"),tmp); + } } - } + // end standard web interface } else { + // main section interface if (*lin==mc) { #ifdef USE_GOOGLE_CHARTS lin++; + char *lp; if (!strncmp(lin,"gc(",3)) { // get google table lp=lin+3; SCRIPT_SKIP_SPACES const char *type; const char *func; - char options[256]; + char options[312]; uint8_t nanum=MAX_GARRAY; uint8_t y2f=0; char ctype; @@ -5377,18 +5389,9 @@ void ScriptWebShow(char mc) { char label[SCRIPT_MAXSSIZE]; lp=GetStringResult(lp,OPER_EQU,label,0); SCRIPT_SKIP_SPACES - char *lblp=label; for (uint32_t ind=0; ind=0) { + sprintf(lbl,"%d",todflg); + todflg++; + } else { + GetTextIndexed(lbl, sizeof(lbl), cnt, label); } WSContentSend_PD(lbl); WSContentSend_PD("',"); @@ -5466,17 +5470,31 @@ void ScriptWebShow(char mc) { SCRIPT_SKIP_SPACES snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT3,header,(uint32_t)max1,(uint32_t)max2,func); } + + if (ctype=='g') { + float yellowFrom; + lp=GetNumericResult(lp,OPER_EQU,&yellowFrom,0); + SCRIPT_SKIP_SPACES + float redFrom; + lp=GetNumericResult(lp,OPER_EQU,&redFrom,0); + SCRIPT_SKIP_SPACES + float maxValue; + lp=GetNumericResult(lp,OPER_EQU,&maxValue,0); + SCRIPT_SKIP_SPACES + float redTo=maxValue; + float yellowTo=redFrom; + snprintf_P(options,sizeof(options),SCRIPT_MSG_GAUGEOPT,(uint32_t)maxValue,(uint32_t)redFrom,(uint32_t)redTo, + (uint32_t)yellowFrom,(uint32_t)yellowTo); + } } WSContentSend_PD(SCRIPT_MSG_GTABLEb,options,type,chartindex); chartindex++; } else { - Replace_Cmd_Vars(lin,0,tmp,sizeof(tmp)); - WSContentSend_PD(PSTR("%s"),tmp); + WSContentSend_PD(PSTR("%s"),lin); } #else } else { - Replace_Cmd_Vars(lin,0,tmp,sizeof(tmp)); - WSContentSend_PD(PSTR("%s"),tmp); + // WSContentSend_PD(PSTR("%s"),lin); #endif //USE_GOOGLE_CHARTS } } @@ -5809,7 +5827,7 @@ bool Xdrv10(uint8_t function) #ifdef USE_SCRIPT_WEB_DISPLAY case FUNC_WEB_ADD_MAIN_BUTTON: if (bitRead(Settings.rule_enabled, 0)) { - ScriptWebShow('&'); + ScriptWebShow('$'); } break; #endif // USE_SCRIPT_WEB_DISPLAY From 2e88ced738c7264764b8a1265526c9689c8982bc Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 25 May 2020 17:25:47 +0200 Subject: [PATCH 072/581] Fix exception due to webcam problem Fix exception due to webcam problem (#8534) --- tasmota/xdrv_81_webcam.ino | 88 ++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/tasmota/xdrv_81_webcam.ino b/tasmota/xdrv_81_webcam.ino index fb2c86161..a43685e4c 100644 --- a/tasmota/xdrv_81_webcam.ino +++ b/tasmota/xdrv_81_webcam.ino @@ -94,14 +94,16 @@ WiFiClient client; #define HREF_GPIO_NUM 23 #define PCLK_GPIO_NUM 22 -uint8_t wc_up; -uint16_t wc_width; -uint16_t wc_height; -uint8_t wc_stream_active; +struct { + uint8_t up; + uint16_t width; + uint16_t height; + uint8_t stream_active; #ifdef USE_FACE_DETECT -uint8_t faces; -uint16_t face_detect_time; + uint8_t faces; + uint16_t face_detect_time; #endif +} Wc; /*********************************************************************************************/ @@ -128,18 +130,18 @@ bool WcPinUsed(void) { uint32_t WcSetup(int32_t fsiz) { if (fsiz > 10) { fsiz = 10; } - wc_stream_active = 0; + Wc.stream_active = 0; if (fsiz < 0) { esp_camera_deinit(); - wc_up = 0; + Wc.up = 0; return 0; } - if (wc_up) { + if (Wc.up) { esp_camera_deinit(); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Deinit")); - //return wc_up; + //return Wc.up; } //esp_log_level_set("*", ESP_LOG_VERBOSE); @@ -239,8 +241,12 @@ uint32_t WcSetup(int32_t fsiz) { wc_s->set_framesize(wc_s, (framesize_t)fsiz); camera_fb_t *wc_fb = esp_camera_fb_get(); - wc_width = wc_fb->width; - wc_height = wc_fb->height; + if (!wc_fb) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Failed to get the frame on time")); + return 0; + } + Wc.width = wc_fb->width; + Wc.height = wc_fb->height; esp_camera_fb_return(wc_fb); #ifdef USE_FACE_DETECT @@ -249,10 +255,10 @@ uint32_t WcSetup(int32_t fsiz) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Initialized")); - wc_up = 1; - if (psram) { wc_up=2; } + Wc.up = 1; + if (psram) { Wc.up=2; } - return wc_up; + return Wc.up; } /*********************************************************************************************/ @@ -299,17 +305,17 @@ int32_t WcSetOptions(uint32_t sel, int32_t value) { uint32_t WcGetWidth(void) { camera_fb_t *wc_fb = esp_camera_fb_get(); if (!wc_fb) { return 0; } - wc_width = wc_fb->width; + Wc.width = wc_fb->width; esp_camera_fb_return(wc_fb); - return wc_width; + return Wc.width; } uint32_t WcGetHeight(void) { camera_fb_t *wc_fb = esp_camera_fb_get(); if (!wc_fb) { return 0; } - wc_height = wc_fb->height; + Wc.height = wc_fb->height; esp_camera_fb_return(wc_fb); - return wc_height; + return Wc.height; } /*********************************************************************************************/ @@ -447,8 +453,8 @@ void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes, int face_ #define DL_SPIRAM_SUPPORT uint32_t WcSetFaceDetect(int32_t value) { - if (value >= 0) { face_detect_time = value; } - return faces; + if (value >= 0) { Wc.face_detect_time = value; } + return Wc.faces; } uint32_t face_ltime; @@ -464,7 +470,7 @@ uint32_t WcDetectFace(void) { int face_id = 0; camera_fb_t *fb; - if ((millis() - face_ltime) > face_detect_time) { + if ((millis() - face_ltime) > Wc.face_detect_time) { face_ltime = millis(); fb = esp_camera_fb_get(); if (!fb) { return ESP_FAIL; } @@ -492,7 +498,7 @@ uint32_t WcDetectFace(void) { box_array_t *net_boxes = face_detect(image_matrix, &mtmn_config); if (net_boxes){ detected = true; - faces = net_boxes->len; + Wc.faces = net_boxes->len; //if(recognition_enabled){ // face_id = run_face_recognition(image_matrix, net_boxes); //} @@ -502,10 +508,10 @@ uint32_t WcDetectFace(void) { free(net_boxes->landmark); free(net_boxes); } else { - faces = 0; + Wc.faces = 0; } dl_matrix3du_free(image_matrix); - //Serial.printf("face detected: %d",faces); + //Serial.printf("face detected: %d",Wc.faces); } } @@ -564,8 +570,8 @@ uint32_t WcGetFrame(int32_t bnum) { return 0; } if (!bnum) { - wc_width = wc_fb->width; - wc_height = wc_fb->height; + Wc.width = wc_fb->width; + Wc.height = wc_fb->height; esp_camera_fb_return(wc_fb); return 0; } @@ -691,9 +697,9 @@ void HandleImageBasic(void) { void HandleWebcamMjpeg(void) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Handle camserver")); -// if (!wc_stream_active) { +// if (!Wc.stream_active) { // always restart stream - wc_stream_active = 1; + Wc.stream_active = 1; client = CamServer->client(); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Create client")); // } @@ -710,25 +716,25 @@ void HandleWebcamMjpegTask(void) { if (!client.connected()) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Client fail")); - wc_stream_active = 0; + Wc.stream_active = 0; } - if (1 == wc_stream_active) { + if (1 == Wc.stream_active) { client.flush(); client.setTimeout(3); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Start stream")); client.print("HTTP/1.1 200 OK\r\n" "Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n" "\r\n"); - wc_stream_active = 2; + Wc.stream_active = 2; } - if (2 == wc_stream_active) { + if (2 == Wc.stream_active) { wc_fb = esp_camera_fb_get(); if (!wc_fb) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Frame fail")); - wc_stream_active = 0; + Wc.stream_active = 0; } } - if (2 == wc_stream_active) { + if (2 == Wc.stream_active) { if (wc_fb->format != PIXFORMAT_JPEG) { jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len); if (!jpeg_converted){ @@ -748,7 +754,7 @@ void HandleWebcamMjpegTask(void) { /* if (tlen!=_jpg_buf_len) { esp_camera_fb_return(wc_fb); - wc_stream_active=0; + Wc.stream_active=0; AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Send fail")); }*/ client.print("\r\n--" BOUNDARY "\r\n"); @@ -768,7 +774,7 @@ void HandleWebcamMjpegTask(void) { esp_camera_fb_return(wc_fb); //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: send frame")); } - if (0 == wc_stream_active) { + if (0 == Wc.stream_active) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Stream exit")); client.flush(); client.stop(); @@ -787,7 +793,7 @@ void HandleWebcamRoot(void) { uint32_t WcSetStreamserver(uint32_t flag) { if (global_state.wifi_down) { return 0; } - wc_stream_active = 0; + Wc.stream_active = 0; if (flag) { if (!CamServer) { @@ -821,11 +827,11 @@ void WcStreamControl() { void WcLoop(void) { if (CamServer) { CamServer->handleClient(); - if (wc_stream_active) { HandleWebcamMjpegTask(); } + if (Wc.stream_active) { HandleWebcamMjpegTask(); } } if (motion_detect) { WcDetectMotion(); } #ifdef USE_FACE_DETECT - if (face_detect_time) { WcDetectFace(); } + if (Wc.face_detect_time) { WcDetectFace(); } #endif } @@ -841,7 +847,7 @@ void WcShowStream(void) { WcStreamControl(); delay(50); // Give the webcam webserver some time to prepare the stream } - if (CamServer) { + if (CamServer && Wc.up) { WSContentSend_P(PSTR("

Webcam stream

"), WiFi.localIP().toString().c_str()); } From 53f459b43e9d9c6d954fbcc95eaaa5fdf6e80b8e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 25 May 2020 17:39:59 +0200 Subject: [PATCH 073/581] Build firmware --- .../{CI_github.yml => CI_github.yml.off} | 0 ...thub_ESP32.yml => CI_github_ESP32.yml.off} | 0 .github/workflows/Tasmota_build.yml | 1479 +++++++++++++++++ tools/Esptool/ESP32/boot_app0.bin | Bin 0 -> 8192 bytes tools/Esptool/ESP32/bootloader_dout_40m.bin | Bin 0 -> 15872 bytes tools/Esptool/ESP32/partitions.bin | Bin 0 -> 3072 bytes tools/Esptool/ESP32/readme.txt | 1 + 7 files changed, 1480 insertions(+) rename .github/workflows/{CI_github.yml => CI_github.yml.off} (100%) rename .github/workflows/{CI_github_ESP32.yml => CI_github_ESP32.yml.off} (100%) create mode 100644 .github/workflows/Tasmota_build.yml create mode 100644 tools/Esptool/ESP32/boot_app0.bin create mode 100644 tools/Esptool/ESP32/bootloader_dout_40m.bin create mode 100644 tools/Esptool/ESP32/partitions.bin create mode 100644 tools/Esptool/ESP32/readme.txt diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml.off similarity index 100% rename from .github/workflows/CI_github.yml rename to .github/workflows/CI_github.yml.off diff --git a/.github/workflows/CI_github_ESP32.yml b/.github/workflows/CI_github_ESP32.yml.off similarity index 100% rename from .github/workflows/CI_github_ESP32.yml rename to .github/workflows/CI_github_ESP32.yml.off diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml new file mode 100644 index 000000000..575e71ce6 --- /dev/null +++ b/.github/workflows/Tasmota_build.yml @@ -0,0 +1,1479 @@ +name: Build_firmware + +on: + push: + pull_request: + + +jobs: + tasmota_pull: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Use latest Tasmota development + run: | + git config --local user.name "Platformio BUILD" + git switch -c master + git remote add -f Tasmota "https://github.com/arendst/Tasmota.git" + git merge Tasmota/development --allow-unrelated-histories + - name: Push Tasmota # Push updates of latest Tasmota development to repo + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: 'master' + force: true + + + tasmota: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-minimal: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-minimal + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-lite: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-lite + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-knx: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-knx + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-sensors: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-sensors + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-display: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-display + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-ir: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-ir + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-ircustom: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-ircustom + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-BG: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-BG + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-BR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-BR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-CN: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-CN + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-CZ: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-CZ + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-DE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-DE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-ES: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-ES + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-FR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-FR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-GR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-GR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-HE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-HE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-HU: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-HU + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-IT: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-IT + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-KO: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-KO + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-NL: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-NL + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-PL: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-PL + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-PT: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-PT + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-RO: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-RO + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-RU: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-RU + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-SE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-SE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-SK: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-SK + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-TR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-TR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-TW: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-TW + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-UK: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-UK + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32 + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-minimal: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-minimal + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-lite: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-lite + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-webcam: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-webcam + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-knx: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-knx + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-sensors: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-sensors + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-display: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-display + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-ir: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-ir + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-ircustom: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-ircustom + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-BG: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-BG + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-BR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-BR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-CN: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-CN + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-CZ: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-CZ + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-DE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-DE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-ES: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-ES + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-FR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-FR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-GR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-GR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-HE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-HE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-HU: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-HU + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-IT: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-IT + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-KO: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-KO + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-NL: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-NL + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-PL: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-PL + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-PT: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-PT + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-RO: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-RO + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-RU: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-RU + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-SE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-SE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-SK: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-SK + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-TR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-TR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-TW: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-TW + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-UK: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-UK + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + Upload: + needs: [tasmota-UK, tasmota32-ircustom, tasmota32-UK, tasmota32-TW, tasmota32-TR] + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - uses: actions/download-artifact@v2 + with: + name: firmware + path: ./mv_firmware + - name: Display structure of downloaded files + run: ls -R + working-directory: ./mv_firmware + - name: Move firmware files in sub-folders + run: | + mkdir -p ./firmware/tasmota/languages + mkdir -p ./firmware/tasmota32/languages + mkdir -p ./firmware/tasmota32/ESP32_needed_files/ + mv ./mv_firmware/tasmota.* ./firmware/tasmota/ + mv ./mv_firmware/tasmota-sensors.* ./firmware/tasmota/ + mv ./mv_firmware/tasmota-minimal.* ./firmware/tasmota/ + mv ./mv_firmware/tasmota-lite.* ./firmware/tasmota/ + mv ./mv_firmware/tasmota-ir*.* ./firmware/tasmota/ + mv ./mv_firmware/tasmota-display.* ./firmware/tasmota/ + mv ./mv_firmware/tasmota-knx.* ./firmware/tasmota/ + mv ./mv_firmware/tasmota32.* ./firmware/tasmota32/ + mv ./mv_firmware/tasmota32-sensors.* ./firmware/tasmota32/ + mv ./mv_firmware/tasmota32-minimal.* ./firmware/tasmota32/ + mv ./mv_firmware/tasmota32-lite.* ./firmware/tasmota32/ + mv ./mv_firmware/tasmota32-ir*.* ./firmware/tasmota32/ + mv ./mv_firmware/tasmota32-display.* ./firmware/tasmota32/ + mv ./mv_firmware/tasmota32-web*.* ./firmware/tasmota32/ + mv ./mv_firmware/tasmota32-knx.* ./firmware/tasmota32/ + mv ./mv_firmware/tasmota32* ./firmware/tasmota32/languages/ + mv ./mv_firmware/* ./firmware/tasmota/languages/ + mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ + - name: Commit files # transfer the new binaries back into the repository + run: | + git config --local user.name "Platformio BUILD" + git rm -r --cached . + git add ./README.md + git add -f ./firmware/*.* + git commit -m "Tasmota ESP Binaries http://tasmota.com" + - name: Push changes # push the firmware files to branch firmware + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: 'firmware' + force: true diff --git a/tools/Esptool/ESP32/boot_app0.bin b/tools/Esptool/ESP32/boot_app0.bin new file mode 100644 index 0000000000000000000000000000000000000000..13562cabb9648287fdf70d2a22789fdf1e4156b4 GIT binary patch literal 8192 zcmeI#u?+wq2n0Z!&B7Ip%ZdwNPjZydJlFk*h+E9ra}_6R0t5&UAV7cs0RjXF5FkLH gk-)3}W&dyVhNuJx5FkK+009C72oNAZfWSu}0Te{nn*aa+ literal 0 HcmV?d00001 diff --git a/tools/Esptool/ESP32/bootloader_dout_40m.bin b/tools/Esptool/ESP32/bootloader_dout_40m.bin new file mode 100644 index 0000000000000000000000000000000000000000..eab1e96d1f50bb4718805292a647224b6e97ca22 GIT binary patch literal 15872 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 oulh%M6v Date: Mon, 25 May 2020 17:52:31 +0200 Subject: [PATCH 074/581] Add info text on cam init --- tasmota/xdrv_81_webcam.ino | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tasmota/xdrv_81_webcam.ino b/tasmota/xdrv_81_webcam.ino index a43685e4c..9cbeb4133 100644 --- a/tasmota/xdrv_81_webcam.ino +++ b/tasmota/xdrv_81_webcam.ino @@ -143,6 +143,7 @@ uint32_t WcSetup(int32_t fsiz) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Deinit")); //return Wc.up; } + Wc.up = 0; //esp_log_level_set("*", ESP_LOG_VERBOSE); @@ -225,7 +226,7 @@ uint32_t WcSetup(int32_t fsiz) { if (x) { free(x); } if (err != ESP_OK) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Init failed with error 0x%x"), err); + AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: Init failed with error 0x%x"), err); return 0; } @@ -242,7 +243,7 @@ uint32_t WcSetup(int32_t fsiz) { camera_fb_t *wc_fb = esp_camera_fb_get(); if (!wc_fb) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Failed to get the frame on time")); + AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: Init failed to get the frame on time")); return 0; } Wc.width = wc_fb->width; @@ -253,10 +254,10 @@ uint32_t WcSetup(int32_t fsiz) { fd_init(); #endif - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Initialized")); + AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: Initialized")); Wc.up = 1; - if (psram) { Wc.up=2; } + if (psram) { Wc.up = 2; } return Wc.up; } @@ -843,6 +844,7 @@ void WcPicSetup(void) { void WcShowStream(void) { if (Settings.webcam_config.stream) { +// if (!CamServer || !Wc.up) { if (!CamServer) { WcStreamControl(); delay(50); // Give the webcam webserver some time to prepare the stream From 065a6a35c7165314d91264908d6e42565e436255 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 25 May 2020 17:53:15 +0200 Subject: [PATCH 075/581] Activate Platformio Override --- .github/workflows/Tasmota_build.yml | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index 575e71ce6..e7e8c12d1 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -731,6 +731,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32 - uses: actions/upload-artifact@v2 with: @@ -754,6 +755,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-minimal - uses: actions/upload-artifact@v2 with: @@ -777,6 +779,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-lite - uses: actions/upload-artifact@v2 with: @@ -800,6 +803,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-webcam - uses: actions/upload-artifact@v2 with: @@ -823,6 +827,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-knx - uses: actions/upload-artifact@v2 with: @@ -846,6 +851,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-sensors - uses: actions/upload-artifact@v2 with: @@ -869,6 +875,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-display - uses: actions/upload-artifact@v2 with: @@ -892,6 +899,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-ir - uses: actions/upload-artifact@v2 with: @@ -915,6 +923,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-ircustom - uses: actions/upload-artifact@v2 with: @@ -938,6 +947,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-BG - uses: actions/upload-artifact@v2 with: @@ -961,6 +971,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-BR - uses: actions/upload-artifact@v2 with: @@ -984,6 +995,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-CN - uses: actions/upload-artifact@v2 with: @@ -1007,6 +1019,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-CZ - uses: actions/upload-artifact@v2 with: @@ -1030,6 +1043,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-DE - uses: actions/upload-artifact@v2 with: @@ -1053,6 +1067,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-ES - uses: actions/upload-artifact@v2 with: @@ -1076,6 +1091,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-FR - uses: actions/upload-artifact@v2 with: @@ -1099,6 +1115,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-GR - uses: actions/upload-artifact@v2 with: @@ -1122,6 +1139,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-HE - uses: actions/upload-artifact@v2 with: @@ -1145,6 +1163,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-HU - uses: actions/upload-artifact@v2 with: @@ -1168,6 +1187,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-IT - uses: actions/upload-artifact@v2 with: @@ -1191,6 +1211,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-KO - uses: actions/upload-artifact@v2 with: @@ -1214,6 +1235,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-NL - uses: actions/upload-artifact@v2 with: @@ -1237,6 +1259,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-PL - uses: actions/upload-artifact@v2 with: @@ -1260,6 +1283,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-PT - uses: actions/upload-artifact@v2 with: @@ -1283,6 +1307,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-RO - uses: actions/upload-artifact@v2 with: @@ -1306,6 +1331,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-RU - uses: actions/upload-artifact@v2 with: @@ -1329,6 +1355,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-SE - uses: actions/upload-artifact@v2 with: @@ -1352,6 +1379,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-SK - uses: actions/upload-artifact@v2 with: @@ -1375,6 +1403,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-TR - uses: actions/upload-artifact@v2 with: @@ -1398,6 +1427,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-TW - uses: actions/upload-artifact@v2 with: @@ -1421,6 +1451,7 @@ jobs: platformio update - name: Run PlatformIO run: | + mv platformio_override_sample.ini platformio_override.ini platformio run -e tasmota32-UK - uses: actions/upload-artifact@v2 with: From 4feefcc7b59ad1341d82e254badf6970b1215d34 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 25 May 2020 17:54:34 +0200 Subject: [PATCH 076/581] Branch dev --- .github/workflows/Tasmota_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index e7e8c12d1..899784a28 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -21,7 +21,7 @@ jobs: uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} - branch: 'master' + branch: 'development' force: true From 58494e4453a28c975ae104351ab2494ab6e148b5 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 25 May 2020 18:09:25 +0200 Subject: [PATCH 077/581] orig files --- .gitignore | 2 +- platformio.ini | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 5ebd0bd78..5baf6b919 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ .clang_complete .gcc-flags.json .cache -tasmota/user_config_override* +tasmota/user_config_override.h build build_output firmware.map diff --git a/platformio.ini b/platformio.ini index 22259969c..c9eb6d5f4 100755 --- a/platformio.ini +++ b/platformio.ini @@ -109,7 +109,8 @@ build_flags = ${esp_defaults.build_flags} ; No exception code in firmware -fno-exceptions -lstdc++ - ; the following removes the 4-bytes alignment for PSTR() + ; the following removes the 4-bytes alignment for PSTR(), waiting for a cleaner flag from Arduino Core + -DPSTR\(s\)=\(__extension__\(\{static\ const\ char\ __c\[\]\ __attribute__\(\(__aligned__\(1\)\)\)\ __attribute__\(\(section\(\ \"\\\\\".irom0.pstr.\"\ __FILE__\ \".\"\ __STRINGIZE\(__LINE__\)\ \".\"\ \ __STRINGIZE\(__COUNTER__\)\ \"\\\\\"\,\ \\\\\"aSM\\\\\"\,\ \@progbits\,\ 1\ \#\"\)\)\)\ =\ \(s\)\;\ \&__c\[0\]\;\}\)\) -DPSTR_ALIGN=1 ; restrict to minimal mime-types -DMIMETYPE_MINIMAL From fd069d7db8be741e25a02cd4ee864bca33f34813 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 25 May 2020 21:07:11 +0200 Subject: [PATCH 078/581] Hard coded logo link to arendst github --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c8d7c024..9e33aa956 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Tasmota logo](/tools/logo/TASMOTA_FullLogo_Vector.svg) +![Tasmota logo](https://github.com/arendst/Tasmota/blob/development/tools/logo/TASMOTA_FullLogo_Vector.svg) Alternative firmware for [ESP8266](https://en.wikipedia.org/wiki/ESP8266) based devices with **easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX**. _Written for Arduino IDE and PlatformIO._ From 4e18240532dfffa502ff11cfdff3ed0575700d1b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 25 May 2020 22:01:14 +0200 Subject: [PATCH 079/581] Trigger build --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e33aa956..a4cffdc56 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ _Written for Arduino IDE and PlatformIO._ [![License](https://img.shields.io/github/license/arendst/Tasmota.svg)](LICENSE.txt) [![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4) -If you like **Tasmota**, give it a star, or fork it and contribute! +If you like **Tasmota**, give it a star, or fork it and contribute! [![GitHub stars](https://img.shields.io/github/stars/arendst/Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Tasmota/stargazers) [![GitHub forks](https://img.shields.io/github/forks/arendst/Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Tasmota/network) From fc32debe0678b4d6399d158efdb8f0ed2cb680cc Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 25 May 2020 22:42:07 +0200 Subject: [PATCH 080/581] Build only when push --- .github/workflows/Tasmota_build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index 899784a28..66db1d377 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -2,8 +2,6 @@ name: Build_firmware on: push: - pull_request: - jobs: tasmota_pull: From 48d2bd5f27db14066e7d4e7cd5aaa2e655efb22b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 25 May 2020 22:45:20 +0200 Subject: [PATCH 081/581] Update and rename CI_github.yml.off to CI_github.yml --- .github/workflows/{CI_github.yml.off => CI_github.yml} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename .github/workflows/{CI_github.yml.off => CI_github.yml} (99%) diff --git a/.github/workflows/CI_github.yml.off b/.github/workflows/CI_github.yml similarity index 99% rename from .github/workflows/CI_github.yml.off rename to .github/workflows/CI_github.yml index 806952c3a..0fe2fd9c5 100644 --- a/.github/workflows/CI_github.yml.off +++ b/.github/workflows/CI_github.yml @@ -1,6 +1,7 @@ name: Tasmota CI -on: [push, pull_request] +on: + pull_request: jobs: tasmota: From ef1bd58d40d61a987df2a35c989b2622c0ba9598 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 25 May 2020 22:46:16 +0200 Subject: [PATCH 082/581] Update and rename CI_github_ESP32.yml.off to CI_github_ESP32.yml --- .../workflows/{CI_github_ESP32.yml.off => CI_github_ESP32.yml} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename .github/workflows/{CI_github_ESP32.yml.off => CI_github_ESP32.yml} (99%) diff --git a/.github/workflows/CI_github_ESP32.yml.off b/.github/workflows/CI_github_ESP32.yml similarity index 99% rename from .github/workflows/CI_github_ESP32.yml.off rename to .github/workflows/CI_github_ESP32.yml index 28221fb20..5184aeb7a 100644 --- a/.github/workflows/CI_github_ESP32.yml.off +++ b/.github/workflows/CI_github_ESP32.yml @@ -1,6 +1,7 @@ name: Tasmota ESP32 CI -on: [push, pull_request] +on: + pull_request: jobs: tasmota32: From de63d7088b63e235374a7490a02d25b961cc7b59 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 25 May 2020 23:21:01 +0200 Subject: [PATCH 083/581] Fix corrupt compression of some uppercase letters --- lib/Unishox-1.0-shadinger/src/unishox.cpp | 16 +++++++++++++--- lib/Unishox-1.0-shadinger/src/unishox.h | 3 --- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/Unishox-1.0-shadinger/src/unishox.cpp b/lib/Unishox-1.0-shadinger/src/unishox.cpp index 286a16280..51c9d4701 100644 --- a/lib/Unishox-1.0-shadinger/src/unishox.cpp +++ b/lib/Unishox-1.0-shadinger/src/unishox.cpp @@ -57,7 +57,9 @@ typedef unsigned char byte; // we squeeze both c_95[] and l_95[] in a sinle array. // c_95[] uses only the 3 upper nibbles (or 12 most signifcant bits), while the last nibble encodes length (3..13) -static uint16_t cl_95[95] PROGMEM = {0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12 }; +// static uint16_t cl_95[95] PROGMEM = {0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12 }; +// Patched, for len == 13, shift 1 bit right +static uint16_t cl_95[95] PROGMEM = {0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x46B0 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x46A0 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x46C0 + 13, 0x2320 + 12, 0x46D0 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12 }; // Original version with c/l separate // uint16_t c_95[95] PROGMEM = {0x4000, 0x3F80, 0x3D80, 0x3C80, 0x3BE0, 0x3E80, 0x3F40, 0x3EC0, 0x3BA0, 0x3BC0, 0x3D60, 0x3B60, 0x3A80, 0x3AC0, 0x3A00, 0x3B00, 0x38C0, 0x3900, 0x3940, 0x3960, 0x3980, 0x39A0, 0x39C0, 0x39E0, 0x39F0, 0x3880, 0x3CC0, 0x3C00, 0x3D00, 0x3E00, 0x3F00, 0x3B40, 0x3BF0, 0x2B00, 0x21C0, 0x20C0, 0x2100, 0x2600, 0x2300, 0x21E0, 0x2140, 0x2D00, 0x2358, 0x2340, 0x2080, 0x21A0, 0x2E00, 0x2C00, 0x2180, 0x2350, 0x2F80, 0x2F00, 0x2A00, 0x2160, 0x2330, 0x21F0, 0x2360, 0x2320, 0x2368, 0x3DE0, 0x3FA0, 0x3DF0, 0x3D40, 0x3F60, 0x3FF0, 0xB000, 0x1C00, 0x0C00, 0x1000, 0x6000, 0x3000, 0x1E00, 0x1400, 0xD000, 0x3580, 0x3400, 0x0800, 0x1A00, 0xE000, 0xC000, 0x1800, 0x3500, 0xF800, 0xF000, 0xA000, 0x1600, 0x3300, 0x1F00, 0x3600, 0x3200, 0x3680, 0x3DA0, 0x3FC0, 0x3DC0, 0x3FE0 }; // uint8_t l_95[95] PROGMEM = { 3, 11, 11, 10, 12, 10, 11, 10, 11, 11, 11, 11, 10, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 10, 10, 9, 10, 9, 10, 11, 12, 8, 11, 10, 10, 7, 11, 12, 11, 8, 13, 12, 10, 11, 8, 8, 11, 13, 9, 9, 8, 11, 12, 12, 13, 12, 13, 12, 11, 12, 11, 11, 12, 4, 7, 6, 6, 3, 7, 8, 7, 4, 9, 8, 6, 7, 4, 4, 7, 9, 5, 5, 4, 7, 8, 8, 9, 8, 9, 11, 11, 11, 12 }; @@ -156,7 +158,7 @@ static const uint8_t mask[] PROGMEM = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, void Unishox::append_bits(unsigned int code, int clen) { - +// Serial.printf("append_bits code = 0x%08X, clen %d\n", code, clen); byte cur_bit; byte blen; unsigned char a_byte; @@ -355,8 +357,14 @@ int32_t Unishox::unishox_compress(const char *p_in, size_t p_len, char *p_out, s if (c_in == 0 && state == SHX_STATE_2) append_bits(ST2_SPC_CODE, ST2_SPC_CODE_LEN); // space from Set2 ionstead of Set1 else { +// Serial.printf("Encode %c %d\n", c_in + 32, c_in); uint16_t cl = pgm_read_word(&cl_95[c_in]); - append_bits(cl & 0xFFF0, cl & 0x000F); + uint16_t cl_code = cl & 0xFFF0; + uint8_t cl_len = cl & 0x000F; + if (13 == cl_len) { + cl_code >>= 1; + } + append_bits(cl_code, cl_len); } } else if (c_in == 10) { append_bits(LF_CODE, LF_CODE_LEN); // LF @@ -394,6 +402,7 @@ uint32_t Unishox::getNextBit(void) { } bit_no = 0; } + // Serial.printf("getNextBit %d\n", byte_in & (0x80 >> bit_no) ? 1 : 0); return byte_in & (0x80 >> bit_no++) ? 1 : 0; } @@ -566,6 +575,7 @@ int32_t Unishox::unishox_decompress(const char *p_in, size_t p_len, char *p_out, } } } + // Serial.printf(">>>>>>>>>>>>>>>>>>>>>> Out = %c\n", c); out[ol++] = c; } diff --git a/lib/Unishox-1.0-shadinger/src/unishox.h b/lib/Unishox-1.0-shadinger/src/unishox.h index 9b6ba1329..6388be4cf 100644 --- a/lib/Unishox-1.0-shadinger/src/unishox.h +++ b/lib/Unishox-1.0-shadinger/src/unishox.h @@ -19,9 +19,6 @@ #ifndef unishox #define unishox -extern int32_t unishox_compress(const char *in, size_t len, char *out, size_t len_out); -//extern int32_t unishox_decompress(const char *in, size_t len, char *out, size_t len_out); - class Unishox { public: From 78b1bb6f31764c39c2d514f91363a1b15ed7486d Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 25 May 2020 23:29:54 +0200 Subject: [PATCH 084/581] Fix python version too --- lib/Unishox-1.0-shadinger/python/unishox.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Unishox-1.0-shadinger/python/unishox.py b/lib/Unishox-1.0-shadinger/python/unishox.py index 6d00c7589..1cce14706 100644 --- a/lib/Unishox-1.0-shadinger/python/unishox.py +++ b/lib/Unishox-1.0-shadinger/python/unishox.py @@ -36,7 +36,8 @@ class Unishox: """ # pylint: disable=bad-continuation,bad-whitespace,line-too-long - cl_95 = [0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12] + #cl_95 = [0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12] + cl_95 = [0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x46B0 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x46A0 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x46C0 + 13, 0x2320 + 12, 0x46D0 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12] # enum {SHX_STATE_1 = 1, SHX_STATE_2}; // removed Unicode state SHX_STATE_1 = 1 @@ -280,7 +281,11 @@ class Unishox: else: # ol = self.append_bits(out, ol, pgm_read_word(&c_95[c_in]), pgm_read_byte(&l_95[c_in]), state); // original version with c/l in split arrays cl = self.cl_95[c_in] - ol = self.append_bits(out, ol, cl & 0xFFF0, cl & 0x000F, state) + cl_code = cl & 0xFFF0 + cl_len = cl & 0x000F + if cl_len == 13: + cl_code = cl_code >> 1 + ol = self.append_bits(out, ol, cl_code, cl_len, state) elif c_in == 10: ol = self.append_bits(out, ol, self.LF_CODE, self.LF_CODE_LEN, state) # LF From 7b9eb6916e49ed185d58af12425b0ef32100af0f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 26 May 2020 07:53:11 +0200 Subject: [PATCH 085/581] revert absolut Logo link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a4cffdc56..51f205664 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Tasmota logo](https://github.com/arendst/Tasmota/blob/development/tools/logo/TASMOTA_FullLogo_Vector.svg) +![Tasmota logo](/tools/logo/TASMOTA_FullLogo_Vector.svg) Alternative firmware for [ESP8266](https://en.wikipedia.org/wiki/ESP8266) based devices with **easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX**. _Written for Arduino IDE and PlatformIO._ From 87704bb1f54d9bed3a9398fd1ba07fad13244346 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 26 May 2020 07:54:53 +0200 Subject: [PATCH 086/581] Add firmware build badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 51f205664..f5d40a631 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ In addition to the [release webpage](https://github.com/arendst/Tasmota/releases [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) [![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) +[![Build_firmware](https://github.com/arendst/Tasmota/workflows/Build_firmware/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3ABuild_firmware) See [tasmota/CHANGELOG.md](tasmota/CHANGELOG.md) for detailed change information. From c42fb4b9b35cd28d406a6901a3b15ff578497640 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 26 May 2020 08:23:51 +0200 Subject: [PATCH 087/581] Add files via upload --- FIRMWARE.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 FIRMWARE.md diff --git a/FIRMWARE.md b/FIRMWARE.md new file mode 100644 index 000000000..aa83b9c94 --- /dev/null +++ b/FIRMWARE.md @@ -0,0 +1,46 @@ +![Tasmota logo](https://github.com/arendst/Tasmota/blob/development/tools/logo/TASMOTA_FullLogo_Vector.svg) + +Alternative firmware for [ESP8266](https://en.wikipedia.org/wiki/ESP8266) based devices with **easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX**. +_Written for Arduino IDE and PlatformIO._ + +[![GitHub version](https://img.shields.io/github/release/arendst/Tasmota.svg)](https://github.com/arendst/Tasmota/releases/latest) +[![GitHub download](https://img.shields.io/github/downloads/arendst/Tasmota/total.svg)](https://github.com/arendst/Tasmota/releases/latest) +[![License](https://img.shields.io/github/license/arendst/Tasmota.svg)](LICENSE.txt) +[![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4) + +If you like **Tasmota**, give it a star, or fork it and contribute! + +[![GitHub stars](https://img.shields.io/github/stars/arendst/Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Tasmota/stargazers) +[![GitHub forks](https://img.shields.io/github/forks/arendst/Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Tasmota/network) +[![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/tasmota) + +See [RELEASENOTES.md](RELEASENOTES.md) for release information. + +In addition to the [release webpage](https://github.com/arendst/Tasmota/releases/latest) the binaries can also be downloaded from http://thehackbox.org/tasmota/release/ + +## Development + +[![Dev Version](https://img.shields.io/badge/development%20version-v8.3.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) +[![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) +[![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) +[![Build_firmware](https://github.com/arendst/Tasmota/workflows/Build_firmware/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3ABuild_firmware) + + +Unless your Tasmota powered device exhibits a problem or you need to make use of a feature that is not available in the Tasmota version currently installed on your device, leave your device alone - it works so don't make unnecessary changes! If the release version (i.e., the master branch) exhibits unexpected behaviour for your device and configuration, you should upgrade to the latest development version instead to see if your problem is resolved as some bugs in previous releases or development builds may already have been resolved. + +If new commits have been merged and they compile successfuly, new binary files for every variant will be placed here https://github.com/arendst/Tasmota/tree/firmware/firmware (this URL address can NOT be used for OTA updates) It is important to note that these binaries are based on the current development codebase. These commits are tested as much as is possible and are typically quite stable. However, it is infeasible to test on the hundreds of different types of devices with all the available configuration options permitted. + +Note that there is a chance, as with any upgrade, that the device may not function as expected. You must always account for the possibility that you may need to flash the device via the serial programming interface if the OTA upgrade fails. Even with the master release, you should always attempt to test the device or a similar prototype before upgrading a device which is in production or is hard to reach. And, as always, make a backup of the device configuration before beginning any firmware update. + +## Disclaimer + +:warning: **DANGER OF ELECTROCUTION** :warning: + +If your device connects to mains electricity (AC power) there is danger of electrocution if not installed properly. If you don't know how to install it, please call an electrician (***Beware:*** certain countries prohibit installation without a licensed electrician present). Remember: _**SAFETY FIRST**_. It is not worth the risk to yourself, your family and your home if you don't know exactly what you are doing. Never tinker or try to flash a device using the serial programming interface while it is connected to MAINS ELECTRICITY (AC power). + +We don't take any responsibility nor liability for using this software nor for the installation or any tips, advice, videos, etc. given by any member of this site or any related site. + +## Quick Install +Download one of the binaries https://github.com/arendst/Tasmota/tree/firmware/firmware and flash it to your hardware [using our installation guide](https://tasmota.github.io/docs/Getting-Started). + From 9c789d1b6fb972f910b2ea56b6ba3f0da130d507 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 26 May 2020 08:24:36 +0200 Subject: [PATCH 088/581] failsafe mv --- .github/workflows/Tasmota_build.yml | 37 +++++++++++++++-------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index 66db1d377..819771059 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -1475,24 +1475,25 @@ jobs: mkdir -p ./firmware/tasmota/languages mkdir -p ./firmware/tasmota32/languages mkdir -p ./firmware/tasmota32/ESP32_needed_files/ - mv ./mv_firmware/tasmota.* ./firmware/tasmota/ - mv ./mv_firmware/tasmota-sensors.* ./firmware/tasmota/ - mv ./mv_firmware/tasmota-minimal.* ./firmware/tasmota/ - mv ./mv_firmware/tasmota-lite.* ./firmware/tasmota/ - mv ./mv_firmware/tasmota-ir*.* ./firmware/tasmota/ - mv ./mv_firmware/tasmota-display.* ./firmware/tasmota/ - mv ./mv_firmware/tasmota-knx.* ./firmware/tasmota/ - mv ./mv_firmware/tasmota32.* ./firmware/tasmota32/ - mv ./mv_firmware/tasmota32-sensors.* ./firmware/tasmota32/ - mv ./mv_firmware/tasmota32-minimal.* ./firmware/tasmota32/ - mv ./mv_firmware/tasmota32-lite.* ./firmware/tasmota32/ - mv ./mv_firmware/tasmota32-ir*.* ./firmware/tasmota32/ - mv ./mv_firmware/tasmota32-display.* ./firmware/tasmota32/ - mv ./mv_firmware/tasmota32-web*.* ./firmware/tasmota32/ - mv ./mv_firmware/tasmota32-knx.* ./firmware/tasmota32/ - mv ./mv_firmware/tasmota32* ./firmware/tasmota32/languages/ - mv ./mv_firmware/* ./firmware/tasmota/languages/ - mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ + [ ! -f ./mv_firmware/tasmota.* ] || mv ./mv_firmware/tasmota.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-sensors.* ] || mv ./mv_firmware/tasmota-sensors.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-minimal.* ] || mv ./mv_firmware/tasmota-minimal.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-lite.* ] || mv ./mv_firmware/tasmota-lite.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-ir*.* ] || mv ./mv_firmware/tasmota-ir*.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-display.* ] || mv ./mv_firmware/tasmota-display.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-knx.* ] || mv ./mv_firmware/tasmota-knx.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota32.* ] || mv ./mv_firmware/tasmota32.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-sensors.* ] || mv ./mv_firmware/tasmota32-sensors.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-minimal.* ] || mv ./mv_firmware/tasmota32-minimal.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-lite.* ] || mv ./mv_firmware/tasmota32-lite.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-ir*.* ] || mv ./mv_firmware/tasmota32-ir*.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-display.* ] || mv ./mv_firmware/tasmota32-display.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-web*.* ] || mv ./mv_firmware/tasmota32-web*.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-knx.* ] || mv ./mv_firmware/tasmota32-knx.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32* ] || mv ./mv_firmware/tasmota32* ./firmware/tasmota32/languages/ + [ ! -f ./mv_firmware/* ] || mv ./mv_firmware/* ./firmware/tasmota/languages/ + [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ + [ ! -f ./FIRMWARE.md ] || mv -f ./FIRMWARE.md ./README.md - name: Commit files # transfer the new binaries back into the repository run: | git config --local user.name "Platformio BUILD" From 0e105ee1c9f7c8d1eca935d2627d7927e3f51914 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 26 May 2020 08:51:22 +0200 Subject: [PATCH 089/581] replaced release against changelog --- FIRMWARE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FIRMWARE.md b/FIRMWARE.md index aa83b9c94..2f1905981 100644 --- a/FIRMWARE.md +++ b/FIRMWARE.md @@ -14,7 +14,7 @@ If you like **Tasmota**, give it a star, or fork it and contribute! [![GitHub forks](https://img.shields.io/github/forks/arendst/Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Tasmota/network) [![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/tasmota) -See [RELEASENOTES.md](RELEASENOTES.md) for release information. +See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/tasmota/CHANGELOG.md) for changes since last release. In addition to the [release webpage](https://github.com/arendst/Tasmota/releases/latest) the binaries can also be downloaded from http://thehackbox.org/tasmota/release/ From a237af20a5c5f5a613e31a5e1e6a2eca3b7cde52 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 26 May 2020 08:52:57 +0200 Subject: [PATCH 090/581] Remove release link --- FIRMWARE.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/FIRMWARE.md b/FIRMWARE.md index 2f1905981..4feb4126d 100644 --- a/FIRMWARE.md +++ b/FIRMWARE.md @@ -16,8 +16,6 @@ If you like **Tasmota**, give it a star, or fork it and contribute! See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/tasmota/CHANGELOG.md) for changes since last release. -In addition to the [release webpage](https://github.com/arendst/Tasmota/releases/latest) the binaries can also be downloaded from http://thehackbox.org/tasmota/release/ - ## Development [![Dev Version](https://img.shields.io/badge/development%20version-v8.3.x.x-blue.svg)](https://github.com/arendst/Tasmota) From b3540879ab6065df636f49df888212528a7618ea Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 26 May 2020 10:26:41 +0200 Subject: [PATCH 091/581] Zero fill millis positions to three digits --- tasmota/support.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 21d79b510..9d1ff07f4 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -997,7 +997,7 @@ char* ResponseGetTime(uint32_t format, char* time_str) snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":%u"), UtcTime()); break; case 3: - snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s.%d\""), GetDateAndTime(DT_LOCAL).c_str(), RtcMillis()); + snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s.%03d\""), GetDateAndTime(DT_LOCAL).c_str(), RtcMillis()); break; default: snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); From 78f106ccb7f7f640d80b3ccc928822ba6aaba8d3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 26 May 2020 11:50:35 +0200 Subject: [PATCH 092/581] Fix Time 0 NTP sync --- tasmota/support_rtc.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino index 44e7dad29..f73be73c1 100644 --- a/tasmota/support_rtc.ino +++ b/tasmota/support_rtc.ino @@ -466,7 +466,6 @@ void RtcSetTime(uint32_t epoch) Rtc.user_time_entry = true; Rtc.utc_time = epoch -1; // Will be corrected by RtcSecond } - RtcSecond(); } void RtcInit(void) From 7bfbe95d0fd5e9f6c9a70932a8e6feca71b6f881 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 26 May 2020 12:15:20 +0200 Subject: [PATCH 093/581] Update tasmota.h --- tasmota/tasmota.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 942d718d2..fdace042c 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -124,7 +124,7 @@ const uint16_t SYSLOG_TIMER = 600; // Seconds to restore syslog_level const uint16_t SERIALLOG_TIMER = 600; // Seconds to disable SerialLog const uint8_t OTA_ATTEMPTS = 5; // Number of times to try fetching the new firmware -const uint16_t INPUT_BUFFER_SIZE = 510; // Max number of characters in serial command buffer: floor((MIN_MESSZ - len({"SerialReceived":""})) / 2) + 1 +const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in serial command buffer const uint16_t FLOATSZ = 16; // Max number of characters in float result from dtostrfd (max 32) const uint16_t CMDSZ = 24; // Max number of characters in command const uint16_t TOPSZ = 151; // Max number of characters in topic string From bacb730b5384e6c9f66026a74cf4853a5a042232 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 26 May 2020 12:35:21 +0200 Subject: [PATCH 094/581] Fix escape of non-JSON received serial data Fix escape of non-JSON received serial data (#8329) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/support_tasmota.ino | 6 +++--- tasmota/xdrv_08_serial_bridge.ino | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f78f518d5..2ac283ffb 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -58,6 +58,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` +- Fix escape of non-JSON received serial data (#8329) - Add command ``Rule0`` to change global rule parameters - Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 91ddbf196..c7a2866a7 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -5,6 +5,7 @@ - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) +- Fix escape of non-JSON received serial data (#8329) - Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add Three Phase Export Active Energy to SDM630 driver diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index e0a45ce77..a3271131b 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1300,7 +1300,7 @@ void SerialInput(void) !in_byte_is_delimiter) { // Char is not a delimiter serial_in_buffer[serial_in_byte_counter++] = serial_in_byte; } - + if ((serial_in_byte_counter >= INPUT_BUFFER_SIZE -1) || // Send message when buffer is full or ... in_byte_is_delimiter) { // Char is delimiter serial_polling_window = 0; // Reception done - send mqtt @@ -1346,7 +1346,7 @@ void SerialInput(void) if (Settings.flag.mqtt_serial && serial_in_byte_counter && (millis() > (serial_polling_window + SERIAL_POLLING))) { // CMND_SERIALSEND and CMND_SERIALLOG serial_in_buffer[serial_in_byte_counter] = 0; // Serial data completed bool assume_json = (!Settings.flag.mqtt_serial_raw && (serial_in_buffer[0] == '{')); - + Response_P(PSTR("{\"" D_JSON_SERIALRECEIVED "\":")); if (assume_json) { ResponseAppend_P(serial_in_buffer); @@ -1360,7 +1360,7 @@ void SerialInput(void) } ResponseAppend_P(PSTR("\"")); } - ResponseAppend_P(PSTR("}")); + ResponseJsonEnd(); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED)); XdrvRulesProcess(); diff --git a/tasmota/xdrv_08_serial_bridge.ino b/tasmota/xdrv_08_serial_bridge.ino index e50d4dd33..0dec9cb6b 100644 --- a/tasmota/xdrv_08_serial_bridge.ino +++ b/tasmota/xdrv_08_serial_bridge.ino @@ -63,7 +63,7 @@ void SerialBridgeInput(void) !in_byte_is_delimiter) { // Char is not a delimiter serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte; } - + if ((serial_bridge_in_byte_counter >= SERIAL_BRIDGE_BUFFER_SIZE -1) || // Send message when buffer is full or ... in_byte_is_delimiter) { // Char is delimiter serial_bridge_polling_window = 0; // Publish now @@ -91,7 +91,7 @@ void SerialBridgeInput(void) } ResponseAppend_P(PSTR("\"")); } - ResponseAppend_P(PSTR("}")); + ResponseJsonEnd(); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); XdrvRulesProcess(); From c0cab842dc14306637d0e4da5a2cc6d32be6961b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 26 May 2020 14:25:33 +0200 Subject: [PATCH 095/581] Replace Travis with general CI tests --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 26db830ac..34c3c2b98 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,7 +53,7 @@ The process is straight-forward. 2. Only relevant files should be touched (Also beware if your editor has auto-formatting feature enabled). 3. Only one feature/fix should be added per PR. 4. If adding a new functionality (new hardware, new library support) not related to an existing component move it to it's own modules (.ino file). -5. PRs that don't compile (break Travis) or cause coding errors will not be merged. Please fix the issue. Same goes for PRs that are raised against older commit in dev - you might need to rebase and resolve conflicts. +5. PRs that don't compile (fail in CI Tests) or cause coding errors will not be merged. Please fix the issue. Same goes for PRs that are raised against older commit in dev - you might need to rebase and resolve conflicts. 6. All pull requests should undergo peer review by at least one contributor other than the creator, excepts for the owner. 7. All pull requests should consider updates to the documentation. 8. Pull requests that address an outstanding issue, particularly an issue deemed to be severe, should be given priority. From a3964d1679b61576121b91de869a3a142d0f0cfb Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 26 May 2020 14:38:31 +0200 Subject: [PATCH 096/581] Add NTP: Not synced message Add NTP: Not synced message (#8142) --- tasmota/support_rtc.ino | 75 +++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino index f73be73c1..d0d9db393 100644 --- a/tasmota/support_rtc.ino +++ b/tasmota/support_rtc.ino @@ -48,6 +48,7 @@ struct RTC { uint32_t midnight = 0; uint32_t restart_time = 0; uint32_t millis = 0; + uint32_t last_sync = 0; int32_t time_timezone = 0; uint8_t ntp_sync_minute = 0; bool midnight_now = false; @@ -369,40 +370,48 @@ void RtcSecond(void) Rtc.millis = millis(); - if (!Rtc.user_time_entry && !global_state.wifi_down) { - uint8_t uptime_minute = (uptime / 60) % 60; // 0 .. 59 - if ((Rtc.ntp_sync_minute > 59) && (uptime_minute > 2)) { - Rtc.ntp_sync_minute = 1; // If sync prepare for a new cycle - } - uint8_t offset = (uptime < 30) ? RtcTime.second : (((ESP_getChipId() & 0xF) * 3) + 3) ; // First try ASAP to sync. If fails try once every 60 seconds based on chip id - if ( (((offset == RtcTime.second) && ( (RtcTime.year < 2016) || // Never synced - (Rtc.ntp_sync_minute == uptime_minute))) || // Re-sync every hour - ntp_force_sync ) ) { // Forced sync - Rtc.ntp_time = sntp_get_current_timestamp(); - if (Rtc.ntp_time > START_VALID_TIME) { // Fix NTP bug in core 2.4.1/SDK 2.2.1 (returns Thu Jan 01 08:00:10 1970 after power on) - ntp_force_sync = false; - Rtc.utc_time = Rtc.ntp_time; - Rtc.ntp_sync_minute = 60; // Sync so block further requests - if (Rtc.restart_time == 0) { - Rtc.restart_time = Rtc.utc_time - uptime; // save first ntp time as restart time - } - BreakTime(Rtc.utc_time, tmpTime); - RtcTime.year = tmpTime.year + 1970; - Rtc.daylight_saving_time = RuleToTime(Settings.tflag[1], RtcTime.year); - Rtc.standard_time = RuleToTime(Settings.tflag[0], RtcTime.year); - - // Do not use AddLog_P2 here (interrupt routine) if syslog or mqttlog is enabled. UDP/TCP will force exception 9 - PrepLog_P2(LOG_LEVEL_DEBUG, PSTR("NTP: " D_UTC_TIME " %s, " D_DST_TIME " %s, " D_STD_TIME " %s"), - GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str()); - - if (Rtc.local_time < START_VALID_TIME) { // 2016-01-01 - rules_flag.time_init = 1; - } else { - rules_flag.time_set = 1; - } - } else { - Rtc.ntp_sync_minute++; // Try again in next minute + if (!Rtc.user_time_entry) { + if (!global_state.wifi_down) { + uint8_t uptime_minute = (uptime / 60) % 60; // 0 .. 59 + if ((Rtc.ntp_sync_minute > 59) && (uptime_minute > 2)) { + Rtc.ntp_sync_minute = 1; // If sync prepare for a new cycle } + uint8_t offset = (uptime < 30) ? RtcTime.second : (((ESP_getChipId() & 0xF) * 3) + 3) ; // First try ASAP to sync. If fails try once every 60 seconds based on chip id + if ( (((offset == RtcTime.second) && ( (RtcTime.year < 2016) || // Never synced + (Rtc.ntp_sync_minute == uptime_minute))) || // Re-sync every hour + ntp_force_sync ) ) { // Forced sync + Rtc.ntp_time = sntp_get_current_timestamp(); + if (Rtc.ntp_time > START_VALID_TIME) { // Fix NTP bug in core 2.4.1/SDK 2.2.1 (returns Thu Jan 01 08:00:10 1970 after power on) + ntp_force_sync = false; + Rtc.utc_time = Rtc.ntp_time; + Rtc.last_sync = Rtc.ntp_time; + Rtc.ntp_sync_minute = 60; // Sync so block further requests + if (Rtc.restart_time == 0) { + Rtc.restart_time = Rtc.utc_time - uptime; // save first ntp time as restart time + } + BreakTime(Rtc.utc_time, tmpTime); + RtcTime.year = tmpTime.year + 1970; + Rtc.daylight_saving_time = RuleToTime(Settings.tflag[1], RtcTime.year); + Rtc.standard_time = RuleToTime(Settings.tflag[0], RtcTime.year); + + // Do not use AddLog_P2 here (interrupt routine) if syslog or mqttlog is enabled. UDP/TCP will force exception 9 + PrepLog_P2(LOG_LEVEL_DEBUG, PSTR("NTP: " D_UTC_TIME " %s, " D_DST_TIME " %s, " D_STD_TIME " %s"), + GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str()); + + if (Rtc.local_time < START_VALID_TIME) { // 2016-01-01 + rules_flag.time_init = 1; + } else { + rules_flag.time_set = 1; + } + } else { + Rtc.ntp_sync_minute++; // Try again in next minute + } + } + } + if ((Rtc.utc_time > (1 * 60 * 60)) && (Rtc.last_sync < Rtc.utc_time - (1 * 60 * 60))) { // Every hour a warning + // Do not use AddLog_P2 here (interrupt routine) if syslog or mqttlog is enabled. UDP/TCP will force exception 9 + PrepLog_P2(LOG_LEVEL_DEBUG, PSTR("NTP: Not synced")); + Rtc.last_sync = Rtc.utc_time; } } From 12391c30a7cbf3069c66bab71b19baf7d891aa42 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 26 May 2020 14:43:21 +0200 Subject: [PATCH 097/581] Relax NTP: Not synced message --- tasmota/support_rtc.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino index d0d9db393..e918ae99d 100644 --- a/tasmota/support_rtc.ino +++ b/tasmota/support_rtc.ino @@ -408,7 +408,7 @@ void RtcSecond(void) } } } - if ((Rtc.utc_time > (1 * 60 * 60)) && (Rtc.last_sync < Rtc.utc_time - (1 * 60 * 60))) { // Every hour a warning + if ((Rtc.utc_time > (2 * 60 * 60)) && (Rtc.last_sync < Rtc.utc_time - (2 * 60 * 60))) { // Every two hours a warning // Do not use AddLog_P2 here (interrupt routine) if syslog or mqttlog is enabled. UDP/TCP will force exception 9 PrepLog_P2(LOG_LEVEL_DEBUG, PSTR("NTP: Not synced")); Rtc.last_sync = Rtc.utc_time; From 66233b1749b3c847342befbba3583689f1ad12d2 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 26 May 2020 17:08:13 +0200 Subject: [PATCH 098/581] Add support for full MAC address Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/my_user_config.h | 6 +++--- tasmota/support_tasmota.ino | 9 ++++++--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2ac283ffb..7fb0366a3 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -62,6 +62,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``Rule0`` to change global rule parameters - Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) +- Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) - Add more functionality to ``Switchmode`` 11 and 12 (#8450) - Add wildcard pattern ``?`` for JSON matching in rules - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index c7a2866a7..487c94e64 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -10,6 +10,7 @@ - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add Three Phase Export Active Energy to SDM630 driver - Add wildcard pattern ``?`` for JSON matching in rules +- Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) ### 8.3.1.1 20200518 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 1a65eb571..46d88e0d7 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -118,12 +118,12 @@ #define PUB_PREFIX2 "tele" // [Prefix3] Tasmota devices publish telemetry data to %prefix%/%topic% being PUB_PREFIX2/MQTT_TOPIC/UPTIME, POWER and TIME // May be named the same as PUB_PREFIX // %topic% token options (also ButtonTopic and SwitchTopic) -#define MQTT_TOPIC PROJECT "_%06X" // [Topic] unique MQTT device topic including device MAC address +#define MQTT_TOPIC PROJECT "_%06X" // [Topic] unique MQTT device topic including (part of) device MAC address #define MQTT_GRPTOPIC "tasmotas" // [GroupTopic] MQTT Group topic #define MQTT_GROUPTOPIC_FORMAT false // [SetOption75] GroupTopic replaces %topic% (false) or fixed topic cmnd/grouptopic (true) #define MQTT_BUTTON_TOPIC "0" // [ButtonTopic] MQTT button topic, "0" = same as MQTT_TOPIC, set to 'PROJECT "_BTN_%06X"' for unique topic including device MAC address #define MQTT_SWITCH_TOPIC "0" // [SwitchTopic] MQTT button topic, "0" = same as MQTT_TOPIC, set to 'PROJECT "_SW_%06X"' for unique topic including device MAC address -#define MQTT_CLIENT_ID "DVES_%06X" // [MqttClient] Also fall back topic using Chip Id = last 6 characters of MAC address +#define MQTT_CLIENT_ID "DVES_%06X" // [MqttClient] Also fall back topic using last 6 characters of MAC address or use "DVES_%12X" for complete MAC address // -- MQTT - Telemetry ---------------------------- #define TELE_PERIOD 300 // [TelePeriod] Telemetry (0 = disable, 10 - 3600 seconds) @@ -648,7 +648,7 @@ #define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26) #define USE_ZIGBEE_PRECFGKEY_L 0x0F0D0B0907050301L // note: changing requires to re-pair all devices #define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices - + #define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms) // -- Other sensors/drivers ----------------------- diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index a3271131b..03848bf0d 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -41,12 +41,15 @@ char* Format(char* output, const char* input, int size) snprintf_P(tmp, size, PSTR("%s%c0%dd"), output, '%', digits); snprintf_P(output, size, tmp, ESP_getChipId() & 0x1fff); // %04d - short chip ID in dec, like in hostname } else { - snprintf_P(tmp, size, PSTR("%s%c0%dX"), output, '%', digits); - snprintf_P(output, size, tmp, ESP_getChipId()); // %06X - full chip ID in hex + String mac_address = WiFi.macAddress(); + mac_address.replace(":", ""); + if (digits > 12) { digits = 12; } + String mac_part = mac_address.substring(12 - digits); + snprintf_P(output, size, PSTR("%s%s"), output, mac_part.c_str()); // %01X .. %12X - mac address in hex } } else { if (strchr(token, 'd')) { - snprintf_P(output, size, PSTR("%s%d"), output, ESP_getChipId()); // %d - full chip ID in dec + snprintf_P(output, size, PSTR("%s%d"), output, ESP_getChipId()); // %d - full chip ID in dec digits = 8; } } From 371870a8269b7705e914fe9cc81241da3c9812c8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 26 May 2020 17:38:34 +0200 Subject: [PATCH 099/581] Fix ESP32 GUI template upload Fix ESP32 GUI template upload (#8534) --- tasmota/xdrv_01_webserver.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 4fb1303ed..e4f2bd4a4 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -448,7 +448,7 @@ const char HTTP_FORM_OTHER[] PROGMEM = "" "

" "
 " D_TEMPLATE " " - "

" + "

" // We need ' apostrophe here as the template contains " quotation mark "

" "
" "
" @@ -2041,7 +2041,7 @@ void HandleOtherConfiguration(void) void OtherSaveSettings(void) { - char tmp[TOPSZ]; + char tmp[300]; // Needs to hold complete ESP32 template of minimal 230 chars char webindex[5]; char friendlyname[TOPSZ]; char message[LOGSZ]; From f80d2ede3aaf69b15dd88e5a4ff73c960995e049 Mon Sep 17 00:00:00 2001 From: Peter Halicky Date: Tue, 26 May 2020 18:20:46 +0200 Subject: [PATCH 100/581] fix default power state logic invoked even if already serviced by a driver --- tasmota/support_tasmota.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 08a2ac6ca..049d5f9e9 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -222,8 +222,8 @@ void SetDevicePower(power_t rpower, uint32_t source) else if (EXS_RELAY == my_module_type) { SetLatchingRelay(rpower, 1); } - else #endif // ESP8266 + else { for (uint32_t i = 0; i < devices_present; i++) { power_t state = rpower &1; From 7064a82fbf7095f49d0740650cb3392ccf57a3bb Mon Sep 17 00:00:00 2001 From: Staars Date: Tue, 26 May 2020 20:43:55 +0200 Subject: [PATCH 101/581] update NimBLE-Arduino --- libesp32/NimBLE-Arduino/API_DIFFERENCES.md | 42 +- libesp32/NimBLE-Arduino/README.md | 18 +- .../examples/NimBLE_Server/NimBLE_Server.ino | 3 +- libesp32/NimBLE-Arduino/src/FreeRTOS.cpp | 34 +- libesp32/NimBLE-Arduino/src/FreeRTOS.h | 4 +- .../NimBLE-Arduino/src/HIDKeyboardTypes.h | 58 +- libesp32/NimBLE-Arduino/src/HIDTypes.h | 4 +- libesp32/NimBLE-Arduino/src/NimBLE2902.cpp | 38 +- libesp32/NimBLE-Arduino/src/NimBLE2902.h | 18 +- libesp32/NimBLE-Arduino/src/NimBLE2904.cpp | 48 +- libesp32/NimBLE-Arduino/src/NimBLE2904.h | 86 +-- libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp | 87 ++- libesp32/NimBLE-Arduino/src/NimBLEAddress.h | 34 +- .../src/NimBLEAdvertisedDevice.cpp | 46 +- .../src/NimBLEAdvertisedDevice.h | 12 +- .../NimBLE-Arduino/src/NimBLEAdvertising.cpp | 628 +++++++++--------- .../NimBLE-Arduino/src/NimBLEAdvertising.h | 85 +-- libesp32/NimBLE-Arduino/src/NimBLEBeacon.cpp | 57 +- libesp32/NimBLE-Arduino/src/NimBLEBeacon.h | 47 +- .../src/NimBLECharacteristic.cpp | 407 ++++++------ .../NimBLE-Arduino/src/NimBLECharacteristic.h | 184 ++--- .../src/NimBLECharacteristicMap.cpp | 74 ++- libesp32/NimBLE-Arduino/src/NimBLEClient.cpp | 448 +++++++------ libesp32/NimBLE-Arduino/src/NimBLEClient.h | 105 +-- .../NimBLE-Arduino/src/NimBLEDescriptor.cpp | 107 +-- .../NimBLE-Arduino/src/NimBLEDescriptor.h | 79 +-- .../src/NimBLEDescriptorMap.cpp | 80 +-- libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp | 268 ++++---- libesp32/NimBLE-Arduino/src/NimBLEDevice.h | 118 +++- .../NimBLE-Arduino/src/NimBLEEddystoneTLM.cpp | 54 +- .../NimBLE-Arduino/src/NimBLEEddystoneTLM.h | 52 +- .../NimBLE-Arduino/src/NimBLEEddystoneURL.cpp | 188 +++--- .../NimBLE-Arduino/src/NimBLEEddystoneURL.h | 36 +- libesp32/NimBLE-Arduino/src/NimBLELog.h | 8 +- .../src/NimBLERemoteCharacteristic.cpp | 412 +++++++----- .../src/NimBLERemoteCharacteristic.h | 99 +-- .../src/NimBLERemoteDescriptor.cpp | 167 +++-- .../src/NimBLERemoteDescriptor.h | 49 +- .../src/NimBLERemoteService.cpp | 230 ++++--- .../NimBLE-Arduino/src/NimBLERemoteService.h | 64 +- libesp32/NimBLE-Arduino/src/NimBLEScan.cpp | 153 +++-- libesp32/NimBLE-Arduino/src/NimBLEScan.h | 29 +- .../NimBLE-Arduino/src/NimBLESecurity.cpp | 6 +- libesp32/NimBLE-Arduino/src/NimBLESecurity.h | 6 +- libesp32/NimBLE-Arduino/src/NimBLEServer.cpp | 299 +++++---- libesp32/NimBLE-Arduino/src/NimBLEServer.h | 35 +- libesp32/NimBLE-Arduino/src/NimBLEService.cpp | 189 +++--- libesp32/NimBLE-Arduino/src/NimBLEService.h | 94 +-- .../NimBLE-Arduino/src/NimBLEServiceMap.cpp | 80 ++- libesp32/NimBLE-Arduino/src/NimBLEUUID.cpp | 156 ++--- libesp32/NimBLE-Arduino/src/NimBLEUUID.h | 23 +- libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp | 114 ++-- libesp32/NimBLE-Arduino/src/NimBLEUtils.h | 7 +- libesp32/NimBLE-Arduino/src/NimBLEValue.cpp | 63 +- libesp32/NimBLE-Arduino/src/NimBLEValue.h | 42 +- libesp32/NimBLE-Arduino/src/console/console.h | 2 +- .../src/esp-hci/src/esp_nimble_hci.c | 2 +- libesp32/NimBLE-Arduino/src/esp_nimble_cfg.h | 4 +- libesp32/NimBLE-Arduino/src/esp_nimble_hci.h | 2 +- libesp32/NimBLE-Arduino/src/esp_nimble_mem.h | 3 +- libesp32/NimBLE-Arduino/src/host/ble_gap.h | 32 +- libesp32/NimBLE-Arduino/src/host/ble_store.h | 2 - libesp32/NimBLE-Arduino/src/mesh/glue.h | 7 +- libesp32/NimBLE-Arduino/src/modlog/modlog.h | 34 +- .../nimble/host/mesh/src/src/ble_gap_priv.h | 1 + .../nimble/host/mesh/src/src/ble_hs_id_priv.h | 4 + .../host/mesh/src/src/ble_hs_pvcy_priv.h | 3 + .../host/mesh/src/src/ble_hs_resolv_priv.h | 108 +++ .../nimble/host/mesh/src/src/ble_sm_priv.h | 4 + .../src/nimble/host/src/ble_att_cmd.c | 7 +- .../src/nimble/host/src/ble_gap.c | 55 +- .../src/nimble/host/src/ble_gap_priv.h | 2 +- .../src/nimble/host/src/ble_gatts.c | 37 +- .../src/nimble/host/src/ble_hs_conn.c | 8 +- .../src/nimble/host/src/ble_hs_hci.c | 2 +- .../src/nimble/host/src/ble_hs_hci_evt.c | 18 +- .../src/nimble/host/src/ble_hs_misc.c | 8 +- .../src/nimble/host/src/ble_hs_priv.h | 6 +- .../src/nimble/host/src/ble_l2cap_sig.c | 9 +- .../src/nimble/host/src/ble_l2cap_sig_cmd.c | 8 +- .../src/nimble/host/src/ble_sm.c | 27 +- .../src/nimble/host/src/ble_sm_cmd.c | 11 +- .../src/nimble/host/src/ble_sm_priv.h | 8 +- .../src/nimble/host/src/ble_store_util.c | 195 +----- .../host/store/config/src/ble_store_nvs.c | 4 +- .../NimBLE-Arduino/src/nimble/nimble_npl.h | 3 +- .../NimBLE-Arduino/src/nimble/nimble_port.h | 1 - libesp32/NimBLE-Arduino/src/nimconfig.h | 128 +++- .../src/port/src/esp_nimble_mem.c | 8 +- 89 files changed, 3612 insertions(+), 3015 deletions(-) create mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h diff --git a/libesp32/NimBLE-Arduino/API_DIFFERENCES.md b/libesp32/NimBLE-Arduino/API_DIFFERENCES.md index d50356924..32bf4a2f0 100644 --- a/libesp32/NimBLE-Arduino/API_DIFFERENCES.md +++ b/libesp32/NimBLE-Arduino/API_DIFFERENCES.md @@ -100,7 +100,7 @@ The `BLEAdvertisedDeviceCallbacks` class `onResult()` method now receives a poin Defined as: ``` bool connect(NimBLEAdvertisedDevice* device, bool refreshServices = true); -bool connect(NimBLEAddress address, uint8_t type = BLE_ADDR_TYPE_PUBLIC, bool refreshServices = true); +bool connect(NimBLEAddress address, uint8_t type = BLE_ADDR_PUBLIC, bool refreshServices = true); ``` If set to false the client will use the services database it retrieved from the peripheral last time it connected. This allows for faster connections and power saving if the devices just dropped connection and want to reconnect. @@ -111,6 +111,46 @@ NimBLERemoteCharacteristic::registerForNotify(); ``` Now return true or false to indicate success or failure so you can choose to disconnect or try again. +``` +NimBLEClient::getServices() +NimBLERemoteService::getCharacteristics() +``` +Now return a pointer to a `std::vector` of the respective object database instead of `std::map`. + +`NimBLERemoteService::getCharacteristicsByHandle()` +Has been removed from the API as it is no longer maintained in the library. + +The last two above changes reduce the heap usage significantly with minimal application code adjustments. + +**NEW** on May 23, 2020 +> ``` +> NimBLEClient::getServices(bool refresh = false) +> NimBLERemoteService::getCharacteristics(bool refresh = false) +> NimBLERemoteCharacteristic::getDecriptors(bool refresh = false) +>``` +> These methods now take an optional (bool) parameter. +If true it will clear the respective vector and retrieve all the respective attributes from the peripheral. +If false it will retrieve the attributes only if the vector is empty, otherwise the vector is returned +with the currently stored attributes. + +> Removed the automatic discovery of all peripheral attributes as they consumed time and resources for data +the user may not be interested in. + +> Added `NimBLEClient::discoverAtrributes()` for the user to discover all the peripheral attributes +to replace the the former functionality. + + +> ``` +>getService(NimBLEUUID) +>getCharacteristic(NimBLEUUID) +>getDescriptor(NimBLEUUID) +>``` +>These methods will now check the respective vectors for the attribute object and, if not found, will retrieve (only) +the specified attribute from the peripheral. + +> These changes allow more control for the user to manage the resources used for the attributes. + + #### Client Security: The client will automatically initiate security when the peripheral responds that it's required. The default configuration will use "just-works" pairing with no bonding, if you wish to enable bonding see below. diff --git a/libesp32/NimBLE-Arduino/README.md b/libesp32/NimBLE-Arduino/README.md index 5271d12a3..514416e29 100644 --- a/libesp32/NimBLE-Arduino/README.md +++ b/libesp32/NimBLE-Arduino/README.md @@ -1,11 +1,14 @@ # *** UPDATE *** -Server now handles long reads and writes, still work to do on client. - -NEW Client callback created - ```bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params)``` -Called when the server wants to change the connection parameters, return true to accept them or false if not. -Check NimBLE_Client.ino example for a demonstration. +**Breaking change:** Client and scan now use `std::vector` instead of `std::map` for storing the remote attribute database. + +This change will affect your application code if you use `NimBLEClient::getServices()` or `NimBLERemoteService::getCharacteristics()` +in your application as they now return a pointer to `std::vector` of the respective attributes. +In addition `NimBLERemoteService::getCharacteristicsByHandle()` has been removed as it is no longer maintained in the library. +These changes were necessary due to the amount of resources required to use `std::map`, it was not justifed by any benfit it provided. + +It is expected that there will be minimal impact on most applications, if you need help adjusting your code please create an issue. # NimBLE-Arduino A fork of the NimBLE stack restructured for compilation in the Ardruino IDE with a CPP library for use with ESP32. @@ -59,10 +62,9 @@ Change the settings in the `nimconfig.h` file to customize NimBLE to your projec # Continuing development: -This Library is tracking the esp-nimble repo, nimble-1.2.0-idf master branch, currently [@0a1604a.](https://github.com/espressif/esp-nimble) - -Also tracking the NimBLE related changes in esp-idf, master branch, currently [@48bd2d7.](https://github.com/espressif/esp-idf/tree/master/components/bt/host/nimble) +This Library is tracking the esp-nimble repo, nimble-1.2.0-idf master branch, currently [@fead24e.](https://github.com/espressif/esp-nimble) +Also tracking the NimBLE related changes in esp-idf, master branch, currently [@2bc28bb.](https://github.com/espressif/esp-idf/tree/master/components/bt/host/nimble) # Acknowledgments: diff --git a/libesp32/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino b/libesp32/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino index cd48cb348..e0be793d5 100644 --- a/libesp32/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino +++ b/libesp32/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino @@ -61,8 +61,7 @@ class ServerCallbacks: public NimBLEServerCallbacks { void onAuthenticationComplete(ble_gap_conn_desc* desc){ /** Check that encryption was successful, if not we disconnect the client */ if(!desc->sec_state.encrypted) { - /** NOTE: createServer returns the current server reference unless one is not already created */ - NimBLEDevice::createServer()->disconnect(desc->conn_handle); + NimBLEDevice::getServer()->disconnect(desc->conn_handle); Serial.println("Encrypt connection failed - disconnecting client"); return; } diff --git a/libesp32/NimBLE-Arduino/src/FreeRTOS.cpp b/libesp32/NimBLE-Arduino/src/FreeRTOS.cpp index 2cc7a988f..f6bbe171b 100644 --- a/libesp32/NimBLE-Arduino/src/FreeRTOS.cpp +++ b/libesp32/NimBLE-Arduino/src/FreeRTOS.cpp @@ -89,28 +89,28 @@ uint32_t FreeRTOS::Semaphore::wait(std::string owner) { * @return True if we took the semaphore within timeframe. */ bool FreeRTOS::Semaphore::timedWait(std::string owner, uint32_t timeoutMs) { - NIMBLE_LOGD(LOG_TAG, ">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str()); + NIMBLE_LOGD(LOG_TAG, ">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str()); - if (m_usePthreads && timeoutMs != portMAX_DELAY) { - assert(false); // We apparently don't have a timed wait for pthreads. - } + if (m_usePthreads && timeoutMs != portMAX_DELAY) { + assert(false); // We apparently don't have a timed wait for pthreads. + } - auto ret = pdTRUE; + auto ret = pdTRUE; - if (m_usePthreads) { - pthread_mutex_lock(&m_pthread_mutex); - } else { - ret = xSemaphoreTake(m_semaphore, timeoutMs); - } + if (m_usePthreads) { + pthread_mutex_lock(&m_pthread_mutex); + } else { + ret = xSemaphoreTake(m_semaphore, timeoutMs); + } - if (m_usePthreads) { - pthread_mutex_unlock(&m_pthread_mutex); - } else { - xSemaphoreGive(m_semaphore); - } + if (m_usePthreads) { + pthread_mutex_unlock(&m_pthread_mutex); + } else { + xSemaphoreGive(m_semaphore); + } - NIMBLE_LOGD(LOG_TAG, "<< wait: Semaphore %s released: %d", toString().c_str(), ret); - return ret; + NIMBLE_LOGD(LOG_TAG, "<< wait: Semaphore %s released: %d", toString().c_str(), ret); + return ret; } // wait diff --git a/libesp32/NimBLE-Arduino/src/FreeRTOS.h b/libesp32/NimBLE-Arduino/src/FreeRTOS.h index 07877275f..a6737b757 100644 --- a/libesp32/NimBLE-Arduino/src/FreeRTOS.h +++ b/libesp32/NimBLE-Arduino/src/FreeRTOS.h @@ -40,9 +40,9 @@ public: bool take(std::string owner = ""); bool take(uint32_t timeoutMs, std::string owner = ""); std::string toString(); - bool timedWait(std::string owner = "", uint32_t timeoutMs = portMAX_DELAY); + bool timedWait(std::string owner = "", uint32_t timeoutMs = portMAX_DELAY); uint32_t wait(std::string owner = ""); - uint32_t value(){ return m_value; }; + uint32_t value(){ return m_value; }; private: SemaphoreHandle_t m_semaphore; diff --git a/libesp32/NimBLE-Arduino/src/HIDKeyboardTypes.h b/libesp32/NimBLE-Arduino/src/HIDKeyboardTypes.h index 4e221d57f..531437ee4 100644 --- a/libesp32/NimBLE-Arduino/src/HIDKeyboardTypes.h +++ b/libesp32/NimBLE-Arduino/src/HIDKeyboardTypes.h @@ -26,9 +26,9 @@ /* Modifiers */ enum MODIFIER_KEY { - KEY_CTRL = 1, - KEY_SHIFT = 2, - KEY_ALT = 4, + KEY_CTRL = 1, + KEY_SHIFT = 2, + KEY_ALT = 4, }; @@ -43,37 +43,37 @@ enum MEDIA_KEY { }; enum FUNCTION_KEY { - KEY_F1 = 128, /* F1 key */ - KEY_F2, /* F2 key */ - KEY_F3, /* F3 key */ - KEY_F4, /* F4 key */ - KEY_F5, /* F5 key */ - KEY_F6, /* F6 key */ - KEY_F7, /* F7 key */ - KEY_F8, /* F8 key */ - KEY_F9, /* F9 key */ - KEY_F10, /* F10 key */ - KEY_F11, /* F11 key */ - KEY_F12, /* F12 key */ + KEY_F1 = 128, /* F1 key */ + KEY_F2, /* F2 key */ + KEY_F3, /* F3 key */ + KEY_F4, /* F4 key */ + KEY_F5, /* F5 key */ + KEY_F6, /* F6 key */ + KEY_F7, /* F7 key */ + KEY_F8, /* F8 key */ + KEY_F9, /* F9 key */ + KEY_F10, /* F10 key */ + KEY_F11, /* F11 key */ + KEY_F12, /* F12 key */ - KEY_PRINT_SCREEN, /* Print Screen key */ - KEY_SCROLL_LOCK, /* Scroll lock */ - KEY_CAPS_LOCK, /* caps lock */ - KEY_NUM_LOCK, /* num lock */ - KEY_INSERT, /* Insert key */ - KEY_HOME, /* Home key */ - KEY_PAGE_UP, /* Page Up key */ - KEY_PAGE_DOWN, /* Page Down key */ + KEY_PRINT_SCREEN, /* Print Screen key */ + KEY_SCROLL_LOCK, /* Scroll lock */ + KEY_CAPS_LOCK, /* caps lock */ + KEY_NUM_LOCK, /* num lock */ + KEY_INSERT, /* Insert key */ + KEY_HOME, /* Home key */ + KEY_PAGE_UP, /* Page Up key */ + KEY_PAGE_DOWN, /* Page Down key */ - RIGHT_ARROW, /* Right arrow */ - LEFT_ARROW, /* Left arrow */ - DOWN_ARROW, /* Down arrow */ - UP_ARROW, /* Up arrow */ + RIGHT_ARROW, /* Right arrow */ + LEFT_ARROW, /* Left arrow */ + DOWN_ARROW, /* Down arrow */ + UP_ARROW, /* Up arrow */ }; typedef struct { - unsigned char usage; - unsigned char modifier; + unsigned char usage; + unsigned char modifier; } KEYMAP; #ifdef US_KEYBOARD diff --git a/libesp32/NimBLE-Arduino/src/HIDTypes.h b/libesp32/NimBLE-Arduino/src/HIDTypes.h index 64850ef8a..726b84be3 100644 --- a/libesp32/NimBLE-Arduino/src/HIDTypes.h +++ b/libesp32/NimBLE-Arduino/src/HIDTypes.h @@ -89,8 +89,8 @@ #define MAX_HID_REPORT_SIZE (64) typedef struct { - uint32_t length; - uint8_t data[MAX_HID_REPORT_SIZE]; + uint32_t length; + uint8_t data[MAX_HID_REPORT_SIZE]; } HID_REPORT; #endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2902.cpp b/libesp32/NimBLE-Arduino/src/NimBLE2902.cpp index b23206032..04a07b6f9 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLE2902.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLE2902.cpp @@ -3,7 +3,7 @@ * * Created: on March 10, 2020 * Author H2zero - * + * * Originally: * * BLE2902.cpp @@ -20,16 +20,19 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLE2902.h" -NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic) -: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2902), - BLE_GATT_CHR_F_READ | - BLE_GATT_CHR_F_WRITE, - 2, pCharacterisitic) +NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic) +: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2902), + BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE, + 2, pCharacterisitic) { - uint8_t data[2] = { 0, 0 }; - setValue(data, 2); + uint8_t data[2] = { 0, 0 }; + setValue(data, 2); } // NimBLE2902 @@ -38,7 +41,7 @@ NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic) * @return The notifications value. True if notifications are enabled and false if not. */ bool NimBLE2902::getNotifications() { - return (getValue()[0] & (1 << 0)) != 0; + return (getValue()[0] & (1 << 0)) != 0; } // getNotifications @@ -47,7 +50,7 @@ bool NimBLE2902::getNotifications() { * @return The indications value. True if indications are enabled and false if not. */ bool NimBLE2902::getIndications() { - return (getValue()[0] & (1 << 1)) != 0; + return (getValue()[0] & (1 << 1)) != 0; } // getIndications @@ -56,9 +59,9 @@ bool NimBLE2902::getIndications() { * @param [in] flag The indications flag. */ void NimBLE2902::setIndications(bool flag) { - uint8_t *pValue = getValue(); - if (flag) pValue[0] |= 1 << 1; - else pValue[0] &= ~(1 << 1); + uint8_t *pValue = getValue(); + if (flag) pValue[0] |= 1 << 1; + else pValue[0] &= ~(1 << 1); } // setIndications @@ -67,9 +70,10 @@ void NimBLE2902::setIndications(bool flag) { * @param [in] flag The notifications flag. */ void NimBLE2902::setNotifications(bool flag) { - uint8_t *pValue = getValue(); - if (flag) pValue[0] |= 1 << 0; - else pValue[0] &= ~(1 << 0); + uint8_t *pValue = getValue(); + if (flag) pValue[0] |= 1 << 0; + else pValue[0] &= ~(1 << 0); } // setNotifications -#endif \ No newline at end of file +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2902.h b/libesp32/NimBLE-Arduino/src/NimBLE2902.h index dcecbaa28..f7fc55569 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLE2902.h +++ b/libesp32/NimBLE-Arduino/src/NimBLE2902.h @@ -3,7 +3,7 @@ * * Created: on March 10, 2020 * Author H2zero - * + * * Originally: * * BLE2902.h @@ -17,6 +17,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLEDescriptor.h" #include @@ -35,16 +38,17 @@ */ class NimBLE2902: public NimBLEDescriptor { public: - bool getNotifications(); - bool getIndications(); - void setNotifications(bool flag); - void setIndications(bool flag); + bool getNotifications(); + bool getIndications(); + void setNotifications(bool flag); + void setIndications(bool flag); private: - NimBLE2902(NimBLECharacteristic* pCharacterisitic); + NimBLE2902(NimBLECharacteristic* pCharacterisitic); friend class NimBLECharacteristic; std::map m_subscribedMap; }; // NimBLE2902 +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif /* CONFIG_BT_ENABLED */ -#endif /* MAIN_NIMBLE2902_H_ */ \ No newline at end of file +#endif /* MAIN_NIMBLE2902_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2904.cpp b/libesp32/NimBLE-Arduino/src/NimBLE2904.cpp index 59ef00580..d85cd87e4 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLE2904.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLE2904.cpp @@ -3,7 +3,7 @@ * * Created: on March 13, 2020 * Author H2zero - * + * * Originally: * * BLE2904.cpp @@ -19,21 +19,24 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLE2904.h" -NimBLE2904::NimBLE2904(NimBLECharacteristic* pCharacterisitic) +NimBLE2904::NimBLE2904(NimBLECharacteristic* pCharacterisitic) : NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2904), - BLE_GATT_CHR_F_READ, - sizeof(BLE2904_Data), - pCharacterisitic) + BLE_GATT_CHR_F_READ, + sizeof(BLE2904_Data), + pCharacterisitic) { - m_data.m_format = 0; - m_data.m_exponent = 0; - m_data.m_namespace = 1; // 1 = Bluetooth SIG Assigned Numbers - m_data.m_unit = 0; - m_data.m_description = 0; - setValue((uint8_t*) &m_data, sizeof(m_data)); + m_data.m_format = 0; + m_data.m_exponent = 0; + m_data.m_namespace = 1; // 1 = Bluetooth SIG Assigned Numbers + m_data.m_unit = 0; + m_data.m_description = 0; + setValue((uint8_t*) &m_data, sizeof(m_data)); } // BLE2902 @@ -41,8 +44,8 @@ NimBLE2904::NimBLE2904(NimBLECharacteristic* pCharacterisitic) * @brief Set the description. */ void NimBLE2904::setDescription(uint16_t description) { - m_data.m_description = description; - setValue((uint8_t*) &m_data, sizeof(m_data)); + m_data.m_description = description; + setValue((uint8_t*) &m_data, sizeof(m_data)); } @@ -50,8 +53,8 @@ void NimBLE2904::setDescription(uint16_t description) { * @brief Set the exponent. */ void NimBLE2904::setExponent(int8_t exponent) { - m_data.m_exponent = exponent; - setValue((uint8_t*) &m_data, sizeof(m_data)); + m_data.m_exponent = exponent; + setValue((uint8_t*) &m_data, sizeof(m_data)); } // setExponent @@ -59,8 +62,8 @@ void NimBLE2904::setExponent(int8_t exponent) { * @brief Set the format. */ void NimBLE2904::setFormat(uint8_t format) { - m_data.m_format = format; - setValue((uint8_t*) &m_data, sizeof(m_data)); + m_data.m_format = format; + setValue((uint8_t*) &m_data, sizeof(m_data)); } // setFormat @@ -68,8 +71,8 @@ void NimBLE2904::setFormat(uint8_t format) { * @brief Set the namespace. */ void NimBLE2904::setNamespace(uint8_t namespace_value) { - m_data.m_namespace = namespace_value; - setValue((uint8_t*) &m_data, sizeof(m_data)); + m_data.m_namespace = namespace_value; + setValue((uint8_t*) &m_data, sizeof(m_data)); } // setNamespace @@ -79,8 +82,9 @@ void NimBLE2904::setNamespace(uint8_t namespace_value) { * @param [in] unit The type of units of this characteristic as defined by assigned numbers. */ void NimBLE2904::setUnit(uint16_t unit) { - m_data.m_unit = unit; - setValue((uint8_t*) &m_data, sizeof(m_data)); + m_data.m_unit = unit; + setValue((uint8_t*) &m_data, sizeof(m_data)); } // setUnit -#endif \ No newline at end of file +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2904.h b/libesp32/NimBLE-Arduino/src/NimBLE2904.h index b2aafb0c6..dd665a2bb 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLE2904.h +++ b/libesp32/NimBLE-Arduino/src/NimBLE2904.h @@ -3,7 +3,7 @@ * * Created: on March 13, 2020 * Author H2zero - * + * * Originally: * * BLE2904.h @@ -17,14 +17,17 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLEDescriptor.h" struct BLE2904_Data { - uint8_t m_format; - int8_t m_exponent; - uint16_t m_unit; // See https://www.bluetooth.com/specifications/assigned-numbers/units - uint8_t m_namespace; - uint16_t m_description; + uint8_t m_format; + int8_t m_exponent; + uint16_t m_unit; // See https://www.bluetooth.com/specifications/assigned-numbers/units + uint8_t m_namespace; + uint16_t m_description; } __attribute__((packed)); @@ -38,45 +41,46 @@ struct BLE2904_Data { */ class NimBLE2904: public NimBLEDescriptor { public: - static const uint8_t FORMAT_BOOLEAN = 1; - static const uint8_t FORMAT_UINT2 = 2; - static const uint8_t FORMAT_UINT4 = 3; - static const uint8_t FORMAT_UINT8 = 4; - static const uint8_t FORMAT_UINT12 = 5; - static const uint8_t FORMAT_UINT16 = 6; - static const uint8_t FORMAT_UINT24 = 7; - static const uint8_t FORMAT_UINT32 = 8; - static const uint8_t FORMAT_UINT48 = 9; - static const uint8_t FORMAT_UINT64 = 10; - static const uint8_t FORMAT_UINT128 = 11; - static const uint8_t FORMAT_SINT8 = 12; - static const uint8_t FORMAT_SINT12 = 13; - static const uint8_t FORMAT_SINT16 = 14; - static const uint8_t FORMAT_SINT24 = 15; - static const uint8_t FORMAT_SINT32 = 16; - static const uint8_t FORMAT_SINT48 = 17; - static const uint8_t FORMAT_SINT64 = 18; - static const uint8_t FORMAT_SINT128 = 19; - static const uint8_t FORMAT_FLOAT32 = 20; - static const uint8_t FORMAT_FLOAT64 = 21; - static const uint8_t FORMAT_SFLOAT16 = 22; - static const uint8_t FORMAT_SFLOAT32 = 23; - static const uint8_t FORMAT_IEEE20601 = 24; - static const uint8_t FORMAT_UTF8 = 25; - static const uint8_t FORMAT_UTF16 = 26; - static const uint8_t FORMAT_OPAQUE = 27; + static const uint8_t FORMAT_BOOLEAN = 1; + static const uint8_t FORMAT_UINT2 = 2; + static const uint8_t FORMAT_UINT4 = 3; + static const uint8_t FORMAT_UINT8 = 4; + static const uint8_t FORMAT_UINT12 = 5; + static const uint8_t FORMAT_UINT16 = 6; + static const uint8_t FORMAT_UINT24 = 7; + static const uint8_t FORMAT_UINT32 = 8; + static const uint8_t FORMAT_UINT48 = 9; + static const uint8_t FORMAT_UINT64 = 10; + static const uint8_t FORMAT_UINT128 = 11; + static const uint8_t FORMAT_SINT8 = 12; + static const uint8_t FORMAT_SINT12 = 13; + static const uint8_t FORMAT_SINT16 = 14; + static const uint8_t FORMAT_SINT24 = 15; + static const uint8_t FORMAT_SINT32 = 16; + static const uint8_t FORMAT_SINT48 = 17; + static const uint8_t FORMAT_SINT64 = 18; + static const uint8_t FORMAT_SINT128 = 19; + static const uint8_t FORMAT_FLOAT32 = 20; + static const uint8_t FORMAT_FLOAT64 = 21; + static const uint8_t FORMAT_SFLOAT16 = 22; + static const uint8_t FORMAT_SFLOAT32 = 23; + static const uint8_t FORMAT_IEEE20601 = 24; + static const uint8_t FORMAT_UTF8 = 25; + static const uint8_t FORMAT_UTF16 = 26; + static const uint8_t FORMAT_OPAQUE = 27; - void setDescription(uint16_t); - void setExponent(int8_t exponent); - void setFormat(uint8_t format); - void setNamespace(uint8_t namespace_value); - void setUnit(uint16_t unit); + void setDescription(uint16_t); + void setExponent(int8_t exponent); + void setFormat(uint8_t format); + void setNamespace(uint8_t namespace_value); + void setUnit(uint16_t unit); private: - NimBLE2904(NimBLECharacteristic* pCharacterisitic); + NimBLE2904(NimBLECharacteristic* pCharacterisitic); friend class NimBLECharacteristic; - BLE2904_Data m_data; + BLE2904_Data m_data; }; // BLE2904 +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif /* CONFIG_BT_ENABLED */ -#endif /* MAIN_NIMBLE2904_H_ */ \ No newline at end of file +#endif /* MAIN_NIMBLE2904_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp b/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp index 074ce7e84..b6bc9526b 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp @@ -3,7 +3,7 @@ * * Created: on Jan 24 2020 * Author H2zero - * + * * Originally: * * BLEAddress.cpp @@ -14,9 +14,13 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include + #include "NimBLEAddress.h" #include "NimBLEUtils.h" +#include "NimBLELog.h" +static const char* LOG_TAG = "NimBLEAddress"; /************************************************* NOTE: NimBLE addresses are in INVERSE ORDER! @@ -43,26 +47,49 @@ NimBLEAddress::NimBLEAddress(ble_addr_t address) { * * @param [in] stringAddress The hex representation of the address. */ -NimBLEAddress::NimBLEAddress(std::string stringAddress) { - if (stringAddress.length() != 17) return; +NimBLEAddress::NimBLEAddress(const std::string &stringAddress) { + if (stringAddress.length() == 0) { + memset(m_address, 0, 6); + return; + } + + if (stringAddress.length() == 6) { + std::reverse_copy(stringAddress.data(), stringAddress.data() + 6, m_address); + return; + } + + if (stringAddress.length() != 17) { + memset(m_address, 0, sizeof m_address); // "00:00:00:00:00:00" represents an invalid address + NIMBLE_LOGD(LOG_TAG, "Invalid address '%s'", stringAddress.c_str()); + return; + } int data[6]; - sscanf(stringAddress.c_str(), "%x:%x:%x:%x:%x:%x", &data[5], &data[4], &data[3], &data[2], &data[1], &data[0]); - m_address[0] = (uint8_t) data[0]; - m_address[1] = (uint8_t) data[1]; - m_address[2] = (uint8_t) data[2]; - m_address[3] = (uint8_t) data[3]; - m_address[4] = (uint8_t) data[4]; - m_address[5] = (uint8_t) data[5]; + if(sscanf(stringAddress.c_str(), "%x:%x:%x:%x:%x:%x", &data[5], &data[4], &data[3], &data[2], &data[1], &data[0]) != 6) { + memset(m_address, 0, sizeof m_address); // "00:00:00:00:00:00" represents an invalid address + NIMBLE_LOGD(LOG_TAG, "Invalid address '%s'", stringAddress.c_str()); + } + for(size_t index = 0; index < sizeof m_address; index++) { + m_address[index] = data[index]; + } } // BLEAddress /** - * @brief Constructor for compatibility with bluedrioid esp library. - * @param [in] esp_bd_addr_t struct containing the address. + * @brief Constructor for compatibility with bluedroid esp library. + * @param [in] uint8_t[6] or esp_bd_addr_t struct containing the address. */ -NimBLEAddress::NimBLEAddress(esp_bd_addr_t address) { - NimBLEUtils::memrcpy(m_address, address, 6); +NimBLEAddress::NimBLEAddress(uint8_t address[6]) { + std::reverse_copy(address, address + sizeof m_address, m_address); +} // NimBLEAddress + + +/** + * @brief Constructor for address using a hex value. Use the same byte order, so use 0xa4c1385def16 for "a4:c1:38:5d:ef:16" + * @param [in] uint64_t containing the address. + */ +NimBLEAddress::NimBLEAddress(const uint64_t &address) { + memcpy(m_address, &address, sizeof m_address); } // NimBLEAddress @@ -71,8 +98,8 @@ NimBLEAddress::NimBLEAddress(esp_bd_addr_t address) { * @param [in] otherAddress The other address to compare against. * @return True if the addresses are equal. */ -bool NimBLEAddress::equals(NimBLEAddress otherAddress) { - return memcmp(otherAddress.getNative(), m_address, 6) == 0; +bool NimBLEAddress::equals(const NimBLEAddress &otherAddress) const { + return *this == otherAddress; } // equals @@ -80,7 +107,7 @@ bool NimBLEAddress::equals(NimBLEAddress otherAddress) { * @brief Return the native representation of the address. * @return The native representation of the address. */ -uint8_t *NimBLEAddress::getNative() { +const uint8_t *NimBLEAddress::getNative() const { return m_address; } // getNative @@ -96,13 +123,23 @@ uint8_t *NimBLEAddress::getNative() { * * @return The string representation of the address. */ -std::string NimBLEAddress::toString() { - auto size = 18; - char *res = (char*)malloc(size); - snprintf(res, size, "%02x:%02x:%02x:%02x:%02x:%02x", m_address[5], m_address[4], m_address[3], m_address[2], m_address[1], m_address[0]); - std::string ret(res); - free(res); - return ret; - +std::string NimBLEAddress::toString() const { + return std::string(*this); } // toString + + +bool NimBLEAddress::operator ==(const NimBLEAddress & rhs) const { + return memcmp(rhs.m_address, m_address, sizeof m_address) == 0; +} + +bool NimBLEAddress::operator !=(const NimBLEAddress & rhs) const { + return !this->operator==(rhs); +} + +NimBLEAddress::operator std::string() const { + char buffer[18]; + sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", m_address[5], m_address[4], m_address[3], m_address[2], m_address[1], m_address[0]); + return std::string(buffer); +} + #endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAddress.h b/libesp32/NimBLE-Arduino/src/NimBLEAddress.h index ac1f26ca6..e81a2bdf3 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAddress.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEAddress.h @@ -3,7 +3,7 @@ * * Created: on Jan 24 2020 * Author H2zero - * + * * Originally: * * BLEAddress.h @@ -24,22 +24,7 @@ /**************************/ #include - -typedef enum { - BLE_ADDR_TYPE_PUBLIC = 0x00, - BLE_ADDR_TYPE_RANDOM = 0x01, - BLE_ADDR_TYPE_RPA_PUBLIC = 0x02, - BLE_ADDR_TYPE_RPA_RANDOM = 0x03, -} esp_nimble_addr_type_t; - -typedef uint8_t esp_ble_addr_type_t ; - -/// Bluetooth address length -#define ESP_BD_ADDR_LEN 6 - -/// Bluetooth device address -typedef uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN]; - +#include /** * @brief A %BLE device address. @@ -49,11 +34,16 @@ typedef uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN]; class NimBLEAddress { public: NimBLEAddress(ble_addr_t address); - NimBLEAddress(esp_bd_addr_t address); - NimBLEAddress(std::string stringAddress); - bool equals(NimBLEAddress otherAddress); - uint8_t* getNative(); - std::string toString(); + NimBLEAddress(uint8_t address[6]); + NimBLEAddress(const std::string &stringAddress); + NimBLEAddress(const uint64_t &address); + bool equals(const NimBLEAddress &otherAddress) const; + const uint8_t* getNative() const; + std::string toString() const; + + bool operator ==(const NimBLEAddress & rhs) const; + bool operator !=(const NimBLEAddress & rhs) const; + operator std::string() const; private: uint8_t m_address[6]; diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp index ff0097a25..3634bac8a 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp @@ -3,7 +3,7 @@ * * Created: on Jan 24 2020 * Author H2zero - * + * * Originally: * * BLEAdvertisedDevice.cpp @@ -14,6 +14,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + #include "NimBLEAdvertisedDevice.h" #include "NimBLEUtils.h" #include "NimBLELog.h" @@ -121,7 +124,7 @@ std::string NimBLEAdvertisedDevice::getServiceData() { * @brief Get the service data UUID. * @return The service data UUID. */ - + NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID() { return m_serviceDataUUID; } // getServiceDataUUID @@ -131,7 +134,7 @@ NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID() { * @brief Get the Service UUID. * @return The Service UUID of the advertised device. */ - + NimBLEUUID NimBLEAdvertisedDevice::getServiceUUID() { //TODO Remove it eventually, is no longer useful return m_serviceUUIDs[0]; } // getServiceUUID @@ -141,7 +144,7 @@ NimBLEUUID NimBLEAdvertisedDevice::getServiceUUID() { //TODO Remove it eventual * @brief Check advertised serviced for existence required UUID * @return Return true if service is advertised */ -bool NimBLEAdvertisedDevice::isAdvertisingService(NimBLEUUID uuid){ +bool NimBLEAdvertisedDevice::isAdvertisingService(const NimBLEUUID &uuid){ for (int i = 0; i < m_serviceUUIDs.size(); i++) { NIMBLE_LOGI(LOG_TAG, "Comparing UUIDS: %s %s", m_serviceUUIDs[i].toString().c_str(), uuid.toString().c_str()); if (m_serviceUUIDs[i].equals(uuid)) return true; @@ -270,7 +273,7 @@ bool NimBLEAdvertisedDevice::haveTXPower() { u8p = fields->svc_data_uuid16; length = fields->svc_data_uuid16_len; - + if (length < 2) { NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_SERVICE_DATA"); } @@ -287,23 +290,23 @@ bool NimBLEAdvertisedDevice::haveTXPower() { u8p = fields->svc_data_uuid16; length = fields->svc_data_uuid16_len; - + if (length < 4) { NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_32SERVICE_DATA"); } - + uint32_t uuid = *(uint32_t*) u8p; setServiceDataUUID(NimBLEUUID(uuid)); if (length > 4) { setServiceData(std::string(reinterpret_cast(u8p + 4), length - 4)); } } - + if (fields->svc_data_uuid128 != NULL) { u8p = fields->svc_data_uuid16; length = fields->svc_data_uuid16_len; - + if (length < 16) { NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_128SERVICE_DATA"); } @@ -318,7 +321,7 @@ bool NimBLEAdvertisedDevice::haveTXPower() { NIMBLE_LOGD(LOG_TAG, " appearance=0x%04x", fields->appearance); setAppearance(fields->appearance); } - + /**** TODO: create storage and fucntions for these parameters if (fields->public_tgt_addr != NULL) { NIMBLE_LOGD(LOG_TAG, " public_tgt_addr="); @@ -329,7 +332,7 @@ bool NimBLEAdvertisedDevice::haveTXPower() { } NIMBLE_LOGD(LOG_TAG, "\n"); } - + if (fields->slave_itvl_range != NULL) { NIMBLE_LOGD(LOG_TAG, " slave_itvl_range="); print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN); @@ -350,7 +353,7 @@ bool NimBLEAdvertisedDevice::haveTXPower() { setManufacturerData(std::string(reinterpret_cast(fields->mfg_data), fields->mfg_data_len)); } } //parseAdvertisement - + /** * @brief Set the address of the advertised device. @@ -430,7 +433,7 @@ void NimBLEAdvertisedDevice::setScan(NimBLEScan* pScan) { * @brief Set the Service UUID for this device. * @param [in] serviceUUID The discovered serviceUUID */ - + void NimBLEAdvertisedDevice::setServiceUUID(const char* serviceUUID) { return setServiceUUID(NimBLEUUID(serviceUUID)); } // setServiceUUID @@ -441,6 +444,12 @@ void NimBLEAdvertisedDevice::setServiceUUID(const char* serviceUUID) { * @param [in] serviceUUID The discovered serviceUUID */ void NimBLEAdvertisedDevice::setServiceUUID(NimBLEUUID serviceUUID) { + // Don't add duplicates + for (int i = 0; i < m_serviceUUIDs.size(); i++) { + if (m_serviceUUIDs[i].equals(serviceUUID)) { + return; + } + } m_serviceUUIDs.push_back(serviceUUID); m_haveServiceUUID = true; NIMBLE_LOGD(LOG_TAG,"- addServiceUUID(): serviceUUID: %s", serviceUUID.toString().c_str()); @@ -482,9 +491,9 @@ void NimBLEAdvertisedDevice::setTXPower(int8_t txPower) { * @brief Create a string representation of this device. * @return A string representation of this device. */ -std::string NimBLEAdvertisedDevice::toString() { +std::string NimBLEAdvertisedDevice::toString() { std::string res = "Name: " + getName() + ", Address: " + getAddress().toString(); - + if (haveAppearance()) { char val[6]; snprintf(val, sizeof(val), "%d", getAppearance()); @@ -502,16 +511,16 @@ std::string NimBLEAdvertisedDevice::toString() { if (haveServiceUUID()) { res += ", serviceUUID: " + getServiceUUID().toString(); } - + if (haveTXPower()) { char val[5]; snprintf(val, sizeof(val), "%d", getTXPower()); res += ", txPower: "; res += val; } - + res += ", advType: " + std::string(NimBLEUtils::advTypeToString(m_advType)); - + return res; } // toString @@ -542,5 +551,6 @@ void NimBLEAdvertisedDevice::setAdvertisementResult(uint8_t* payload, uint8_t le m_payloadLength = length; } +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h index b6b2f706b..7a4115f28 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h @@ -3,7 +3,7 @@ * * Created: on Jan 24 2020 * Author H2zero - * + * * Originally: * * BLEAdvertisedDevice.h @@ -17,6 +17,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + #include "NimBLEAddress.h" #include "NimBLEScan.h" #include "NimBLEUUID.h" @@ -24,7 +27,7 @@ #include "host/ble_hs_adv.h" #include -#include +#include class NimBLEScan; @@ -54,7 +57,7 @@ public: void setAddressType(uint8_t type); - bool isAdvertisingService(NimBLEUUID uuid); + bool isAdvertisingService(const NimBLEUUID &uuid); bool haveAppearance(); bool haveManufacturerData(); bool haveName(); @@ -92,7 +95,7 @@ private: bool m_haveTXPower; - NimBLEAddress m_address = NimBLEAddress("\0\0\0\0\0\0"); + NimBLEAddress m_address = NimBLEAddress(""); uint8_t m_advType; uint16_t m_appearance; int m_deviceType; @@ -129,5 +132,6 @@ public: virtual void onResult(NimBLEAdvertisedDevice* advertisedDevice) = 0; }; +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ #endif /* COMPONENTS_NIMBLEADVERTISEDDEVICE_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp index bfdf49dfe..7c930bfc6 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp @@ -3,7 +3,7 @@ * * Created: on March 3, 2020 * Author H2zero - * + * * Originally: * * BLEAdvertising.cpp @@ -15,6 +15,10 @@ */ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + #include "services/gap/ble_svc_gap.h" #include "NimBLEAdvertising.h" #include "NimBLEDevice.h" @@ -31,26 +35,26 @@ static const char* LOG_TAG = "NimBLEAdvertising"; */ NimBLEAdvertising::NimBLEAdvertising() { memset(&m_advData, 0, sizeof m_advData); - memset(&m_scanData, 0, sizeof m_scanData); - memset(&m_advParams, 0, sizeof m_advParams); + memset(&m_scanData, 0, sizeof m_scanData); + memset(&m_advParams, 0, sizeof m_advParams); const char *name = ble_svc_gap_device_name(); - m_advData.name = (uint8_t *)name; + m_advData.name = (uint8_t *)name; m_advData.name_len = strlen(name); m_advData.name_is_complete = 1; m_scanData.tx_pwr_lvl_is_present = 1; m_scanData.tx_pwr_lvl = NimBLEDevice::getPower(); m_advData.flags = (BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP); - m_advData.appearance = 0; - m_advData.appearance_is_present = 0; - m_advData.mfg_data_len = 0; - m_advData.mfg_data = nullptr; - - m_advParams.conn_mode = BLE_GAP_CONN_MODE_UND; + m_advData.appearance = 0; + m_advData.appearance_is_present = 0; + m_advData.mfg_data_len = 0; + m_advData.mfg_data = nullptr; + + m_advParams.conn_mode = BLE_GAP_CONN_MODE_UND; m_advParams.disc_mode = BLE_GAP_DISC_MODE_GEN; - m_advParams.itvl_min = 0; - m_advParams.itvl_max = 0; - + m_advParams.itvl_min = 0; + m_advParams.itvl_max = 0; + } // NimBLEAdvertising @@ -58,8 +62,8 @@ NimBLEAdvertising::NimBLEAdvertising() { * @brief Add a service uuid to exposed list of services. * @param [in] serviceUUID The UUID of the service to expose. */ -void NimBLEAdvertising::addServiceUUID(NimBLEUUID serviceUUID) { - m_serviceUUIDs.push_back(serviceUUID); +void NimBLEAdvertising::addServiceUUID(const NimBLEUUID &serviceUUID) { + m_serviceUUIDs.push_back(serviceUUID); } // addServiceUUID @@ -68,7 +72,7 @@ void NimBLEAdvertising::addServiceUUID(NimBLEUUID serviceUUID) { * @param [in] serviceUUID The string representation of the service to expose. */ void NimBLEAdvertising::addServiceUUID(const char* serviceUUID) { - addServiceUUID(NimBLEUUID(serviceUUID)); + addServiceUUID(NimBLEUUID(serviceUUID)); } // addServiceUUID @@ -80,34 +84,34 @@ void NimBLEAdvertising::addServiceUUID(const char* serviceUUID) { * @return N/A. */ void NimBLEAdvertising::setAppearance(uint16_t appearance) { - m_advData.appearance = appearance; - m_advData.appearance_is_present = 1; + m_advData.appearance = appearance; + m_advData.appearance_is_present = 1; } // setAppearance void NimBLEAdvertising::setAdvertisementType(uint8_t adv_type){ - m_advParams.conn_mode = adv_type; + m_advParams.conn_mode = adv_type; } // setAdvertisementType void NimBLEAdvertising::setMinInterval(uint16_t mininterval) { - m_advParams.itvl_min = mininterval; + m_advParams.itvl_min = mininterval; } // setMinInterval void NimBLEAdvertising::setMaxInterval(uint16_t maxinterval) { - m_advParams.itvl_max = maxinterval; + m_advParams.itvl_max = maxinterval; } // setMaxInterval // These are dummy functions for now for compatibility void NimBLEAdvertising::setMinPreferred(uint16_t mininterval) { - //m_advData.min_interval = mininterval; -} // + //m_advData.min_interval = mininterval; +} // void NimBLEAdvertising::setMaxPreferred(uint16_t maxinterval) { - //m_advData.max_interval = maxinterval; -} // + //m_advData.max_interval = maxinterval; +} // ////////////////////////////////////////////////////////// void NimBLEAdvertising::setScanResponse(bool set) { - m_scanResp = set; + m_scanResp = set; } /** @@ -116,44 +120,44 @@ void NimBLEAdvertising::setScanResponse(bool set) { * @param [in] connectWhitelistOnly If true, only allow connections from those on the white list. */ void NimBLEAdvertising::setScanFilter(bool scanRequestWhitelistOnly, bool connectWhitelistOnly) { - NIMBLE_LOGD(LOG_TAG, ">> setScanFilter: scanRequestWhitelistOnly: %d, connectWhitelistOnly: %d", scanRequestWhitelistOnly, connectWhitelistOnly); - if (!scanRequestWhitelistOnly && !connectWhitelistOnly) { - m_advParams.filter_policy = BLE_HCI_ADV_FILT_NONE; - NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); - return; - } - if (scanRequestWhitelistOnly && !connectWhitelistOnly) { - m_advParams.filter_policy = BLE_HCI_ADV_FILT_SCAN; - NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); - return; - } - if (!scanRequestWhitelistOnly && connectWhitelistOnly) { - m_advParams.filter_policy = BLE_HCI_ADV_FILT_CONN; - NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); - return; - } - if (scanRequestWhitelistOnly && connectWhitelistOnly) { - m_advParams.filter_policy = BLE_HCI_ADV_FILT_BOTH; - NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); - return; - } + NIMBLE_LOGD(LOG_TAG, ">> setScanFilter: scanRequestWhitelistOnly: %d, connectWhitelistOnly: %d", scanRequestWhitelistOnly, connectWhitelistOnly); + if (!scanRequestWhitelistOnly && !connectWhitelistOnly) { + m_advParams.filter_policy = BLE_HCI_ADV_FILT_NONE; + NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); + return; + } + if (scanRequestWhitelistOnly && !connectWhitelistOnly) { + m_advParams.filter_policy = BLE_HCI_ADV_FILT_SCAN; + NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); + return; + } + if (!scanRequestWhitelistOnly && connectWhitelistOnly) { + m_advParams.filter_policy = BLE_HCI_ADV_FILT_CONN; + NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); + return; + } + if (scanRequestWhitelistOnly && connectWhitelistOnly) { + m_advParams.filter_policy = BLE_HCI_ADV_FILT_BOTH; + NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); + return; + } } // setScanFilter /** * @brief Set the advertisement data that is to be published in a regular advertisement. * @param [in] advertisementData The data to be advertised. */ - + void NimBLEAdvertising::setAdvertisementData(NimBLEAdvertisementData& advertisementData) { - NIMBLE_LOGD(LOG_TAG, ">> setAdvertisementData"); - int rc = ble_gap_adv_set_data( - (uint8_t*)advertisementData.getPayload().data(), - advertisementData.getPayload().length()); - if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc)); - } - m_customAdvData = true; // Set the flag that indicates we are using custom advertising data. - NIMBLE_LOGD(LOG_TAG, "<< setAdvertisementData"); + NIMBLE_LOGD(LOG_TAG, ">> setAdvertisementData"); + int rc = ble_gap_adv_set_data( + (uint8_t*)advertisementData.getPayload().data(), + advertisementData.getPayload().length()); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + m_customAdvData = true; // Set the flag that indicates we are using custom advertising data. + NIMBLE_LOGD(LOG_TAG, "<< setAdvertisementData"); } // setAdvertisementData @@ -162,15 +166,15 @@ void NimBLEAdvertising::setAdvertisementData(NimBLEAdvertisementData& advertisem * @param [in] advertisementData The data to be advertised. */ void NimBLEAdvertising::setScanResponseData(NimBLEAdvertisementData& advertisementData) { - NIMBLE_LOGD(LOG_TAG, ">> setScanResponseData"); - int rc = ble_gap_adv_rsp_set_data( - (uint8_t*)advertisementData.getPayload().data(), - advertisementData.getPayload().length()); - if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_rsp_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc)); - } - m_customScanResponseData = true; // Set the flag that indicates we are using custom scan response data. - NIMBLE_LOGD(LOG_TAG, "<< setScanResponseData"); + NIMBLE_LOGD(LOG_TAG, ">> setScanResponseData"); + int rc = ble_gap_adv_rsp_set_data( + (uint8_t*)advertisementData.getPayload().data(), + advertisementData.getPayload().length()); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_rsp_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + m_customScanResponseData = true; // Set the flag that indicates we are using custom scan response data. + NIMBLE_LOGD(LOG_TAG, "<< setScanResponseData"); } // setScanResponseData @@ -180,186 +184,195 @@ void NimBLEAdvertising::setScanResponseData(NimBLEAdvertisementData& advertiseme * @return N/A. */ void NimBLEAdvertising::start() { - NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData); - + NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData); + // If Host is not synced we cannot start advertising. if(!NimBLEDevice::m_synced) { NIMBLE_LOGE(LOG_TAG, "Host reset, wait for sync."); return; } - - if(NimBLEDevice::createServer()->getConnectedCount() >= NIMBLE_MAX_CONNECTIONS) { - NIMBLE_LOGW(LOG_TAG, "Max connections reached - not advertising"); - return; + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + NimBLEServer* pServer = NimBLEDevice::getServer(); + if(pServer != nullptr) { + if(!pServer->m_gattsStarted){ + pServer->start(); + } else if(pServer->getConnectedCount() >= NIMBLE_MAX_CONNECTIONS) { + NIMBLE_LOGW(LOG_TAG, "Max connections reached - not advertising"); + return; + } } - - int numServices = m_serviceUUIDs.size(); +#endif + + int numServices = m_serviceUUIDs.size(); int rc = 0; uint8_t addressType; - uint8_t payloadLen = 3; //start with 3 bytes for the flags data - + uint8_t payloadLen = 3; //start with 3 bytes for the flags data + // If already advertising just return if(ble_gap_adv_active()) { return; } - - NimBLEServer* pServer = NimBLEDevice::createServer(); - if(!pServer->m_gattsStarted){ - pServer->start(); - } - - if (!m_customAdvData && !m_advSvcsSet && numServices > 0) { - for (int i = 0; i < numServices; i++) { - if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_16) { - int add = (m_advData.num_uuids16 > 0) ? 2 : 4; - if((payloadLen + add) > 31){ - m_advData.uuids16_is_complete = 0; - continue; - } - payloadLen += add; - - if(nullptr == (m_advData.uuids16 = (ble_uuid16_t*)realloc(m_advData.uuids16, - (m_advData.num_uuids16 + 1) * sizeof(ble_uuid16_t)))) + + if (!m_customAdvData && !m_advSvcsSet && numServices > 0) { + for (int i = 0; i < numServices; i++) { + if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_16) { + int add = (m_advData.num_uuids16 > 0) ? 2 : 4; + if((payloadLen + add) > 31){ + m_advData.uuids16_is_complete = 0; + continue; + } + payloadLen += add; + + if(nullptr == (m_advData.uuids16 = (ble_uuid16_t*)realloc(m_advData.uuids16, + (m_advData.num_uuids16 + 1) * sizeof(ble_uuid16_t)))) { NIMBLE_LOGE(LOG_TAG, "Error, no mem"); abort(); } - memcpy(&m_advData.uuids16[m_advData.num_uuids16].value, + memcpy(&m_advData.uuids16[m_advData.num_uuids16].value, &m_serviceUUIDs[i].getNative()->u16.value, sizeof(uint16_t)); - + m_advData.uuids16[m_advData.num_uuids16].u.type = BLE_UUID_TYPE_16; m_advData.uuids16_is_complete = 1; m_advData.num_uuids16++; - } - if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_32) { - int add = (m_advData.num_uuids32 > 0) ? 4 : 6; - if((payloadLen + add) > 31){ - m_advData.uuids32_is_complete = 0; - continue; - } - payloadLen += add; - + } + if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_32) { + int add = (m_advData.num_uuids32 > 0) ? 4 : 6; + if((payloadLen + add) > 31){ + m_advData.uuids32_is_complete = 0; + continue; + } + payloadLen += add; + if(nullptr == (m_advData.uuids32 = (ble_uuid32_t*)realloc(m_advData.uuids32, - (m_advData.num_uuids32 + 1) * sizeof(ble_uuid32_t)))) + (m_advData.num_uuids32 + 1) * sizeof(ble_uuid32_t)))) { NIMBLE_LOGE(LOG_TAG, "Error, no mem"); abort(); } - memcpy(&m_advData.uuids32[m_advData.num_uuids32].value, + memcpy(&m_advData.uuids32[m_advData.num_uuids32].value, &m_serviceUUIDs[i].getNative()->u32.value, sizeof(uint32_t)); - - m_advData.uuids32[m_advData.num_uuids32].u.type = BLE_UUID_TYPE_32; + + m_advData.uuids32[m_advData.num_uuids32].u.type = BLE_UUID_TYPE_32; m_advData.uuids32_is_complete = 1; m_advData.num_uuids32++; - } - if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_128){ - int add = (m_advData.num_uuids128 > 0) ? 16 : 18; - if((payloadLen + add) > 31){ - m_advData.uuids128_is_complete = 0; - continue; - } - payloadLen += add; - - if(nullptr == (m_advData.uuids128 = (ble_uuid128_t*)realloc(m_advData.uuids128, + } + if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_128){ + int add = (m_advData.num_uuids128 > 0) ? 16 : 18; + if((payloadLen + add) > 31){ + m_advData.uuids128_is_complete = 0; + continue; + } + payloadLen += add; + + if(nullptr == (m_advData.uuids128 = (ble_uuid128_t*)realloc(m_advData.uuids128, (m_advData.num_uuids128 + 1) * sizeof(ble_uuid128_t)))) { NIMBLE_LOGE(LOG_TAG, "Error, no mem"); abort(); } - memcpy(&m_advData.uuids128[m_advData.num_uuids128].value, + memcpy(&m_advData.uuids128[m_advData.num_uuids128].value, &m_serviceUUIDs[i].getNative()->u128.value, 16); - - m_advData.uuids128[m_advData.num_uuids128].u.type = BLE_UUID_TYPE_128; + + m_advData.uuids128[m_advData.num_uuids128].u.type = BLE_UUID_TYPE_128; m_advData.uuids128_is_complete = 1; m_advData.num_uuids128++; - } - } - - // check if there is room for the name, if not put it in scan data - if((payloadLen + m_advData.name_len) > 29) { - if(m_scanResp){ - m_scanData.name = m_advData.name; - m_scanData.name_len = m_advData.name_len; - m_scanData.name_is_complete = m_advData.name_is_complete; - m_advData.name = nullptr; - m_advData.name_len = 0; - } else { - // if not using scan response just cut the name down - // leaving 2 bytes for the data specifier. - m_advData.name_len = (29 - payloadLen); - } - m_advData.name_is_complete = 0; - } - - if(m_advData.name_len > 0) { - payloadLen += (m_advData.name_len + 2); - } - - if(m_scanResp) { - // name length + type byte + length byte + tx power type + length + data - if((m_scanData.name_len + 5) > 31) { - // prioritize name data over tx power - m_scanData.tx_pwr_lvl_is_present = 0; - m_scanData.tx_pwr_lvl = 0; - // limit name to 29 to leave room for the data specifiers - if(m_scanData.name_len > 29) { - m_scanData.name_len = 29; - m_scanData.name_is_complete = false; - } - } - - rc = ble_gap_adv_rsp_set_fields(&m_scanData); - if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "error setting scan response data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); - abort(); - } - // if not using scan response and there is room, - // throw the tx power data into the advertisment + } + } + + // check if there is room for the name, if not put it in scan data + if((payloadLen + m_advData.name_len) > 29) { + if(m_scanResp){ + m_scanData.name = m_advData.name; + m_scanData.name_len = m_advData.name_len; + m_scanData.name_is_complete = m_advData.name_is_complete; + m_advData.name = nullptr; + m_advData.name_len = 0; + } else { + // if not using scan response just cut the name down + // leaving 2 bytes for the data specifier. + m_advData.name_len = (29 - payloadLen); + } + m_advData.name_is_complete = 0; + } + + if(m_advData.name_len > 0) { + payloadLen += (m_advData.name_len + 2); + } + + if(m_scanResp) { + // name length + type byte + length byte + tx power type + length + data + if((m_scanData.name_len + 5) > 31) { + // prioritize name data over tx power + m_scanData.tx_pwr_lvl_is_present = 0; + m_scanData.tx_pwr_lvl = 0; + // limit name to 29 to leave room for the data specifiers + if(m_scanData.name_len > 29) { + m_scanData.name_len = 29; + m_scanData.name_is_complete = false; + } + } + + rc = ble_gap_adv_rsp_set_fields(&m_scanData); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "error setting scan response data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + abort(); + } + // if not using scan response and there is room, + // throw the tx power data into the advertisment } else if (payloadLen < 29) { - m_advData.tx_pwr_lvl_is_present = 1; - m_advData.tx_pwr_lvl = NimBLEDevice::getPower(); - } - + m_advData.tx_pwr_lvl_is_present = 1; + m_advData.tx_pwr_lvl = NimBLEDevice::getPower(); + } + rc = ble_gap_adv_set_fields(&m_advData); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "error setting advertisement data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); abort(); } - + if(m_advData.num_uuids128 > 0) { free(m_advData.uuids128); m_advData.uuids128 = nullptr; m_advData.num_uuids128 = 0; } - + if(m_advData.num_uuids32 > 0) { free(m_advData.uuids32); m_advData.uuids32 = nullptr; m_advData.num_uuids32 = 0; } - + if(m_advData.num_uuids16 > 0) { free(m_advData.uuids16); m_advData.uuids16 = nullptr; m_advData.num_uuids16 = 0; } - + m_advSvcsSet = true; } - + rc = ble_hs_id_infer_auto(0, &addressType); if (rc != 0) { NIMBLE_LOGC(LOG_TAG, "Error determining address type; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); abort(); - } + } +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) rc = ble_gap_adv_start(addressType, NULL, BLE_HS_FOREVER, - &m_advParams, NimBLEServer::handleGapEvent, NimBLEDevice::createServer()); //get a reference to the server (does not create a new one) + &m_advParams, + (pServer != nullptr) ? NimBLEServer::handleGapEvent : NULL, + pServer); +#else + rc = ble_gap_adv_start(addressType, NULL, BLE_HS_FOREVER, + &m_advParams, NULL,NULL); +#endif if (rc != 0) { NIMBLE_LOGC(LOG_TAG, "Error enabling advertising; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); abort(); } - - NIMBLE_LOGD(LOG_TAG, "<< Advertising start"); + + NIMBLE_LOGD(LOG_TAG, "<< Advertising start"); } // start @@ -369,35 +382,35 @@ void NimBLEAdvertising::start() { * @return N/A. */ void NimBLEAdvertising::stop() { - NIMBLE_LOGD(LOG_TAG, ">> stop"); - int rc = ble_gap_adv_stop(); - if (rc != 0 && rc != BLE_HS_EALREADY) { - NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_stop rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); - return; - } + NIMBLE_LOGD(LOG_TAG, ">> stop"); + int rc = ble_gap_adv_stop(); + if (rc != 0 && rc != BLE_HS_EALREADY) { + NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_stop rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + return; + } - NIMBLE_LOGD(LOG_TAG, "<< stop"); + NIMBLE_LOGD(LOG_TAG, "<< stop"); } // stop /** - * Host reset seems to clear advertising data, + * Host reset seems to clear advertising data, * we need clear the flag so it reloads it. - */ + */ void NimBLEAdvertising::onHostReset() { m_advSvcsSet = false; } - + /** * @brief Add data to the payload to be advertised. * @param [in] data The data to be added to the payload. */ -void NimBLEAdvertisementData::addData(std::string data) { - if ((m_payload.length() + data.length()) > BLE_HS_ADV_MAX_SZ) { - return; - } - m_payload.append(data); +void NimBLEAdvertisementData::addData(const std::string &data) { + if ((m_payload.length() + data.length()) > BLE_HS_ADV_MAX_SZ) { + return; + } + m_payload.append(data); } // addData @@ -409,10 +422,10 @@ void NimBLEAdvertisementData::addData(std::string data) { * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml */ void NimBLEAdvertisementData::setAppearance(uint16_t appearance) { - char cdata[2]; - cdata[0] = 3; - cdata[1] = BLE_HS_ADV_TYPE_APPEARANCE; // 0x19 - addData(std::string(cdata, 2) + std::string((char*) &appearance, 2)); + char cdata[2]; + cdata[0] = 3; + cdata[1] = BLE_HS_ADV_TYPE_APPEARANCE; // 0x19 + addData(std::string(cdata, 2) + std::string((char*) &appearance, 2)); } // setAppearance @@ -420,36 +433,36 @@ void NimBLEAdvertisementData::setAppearance(uint16_t appearance) { * @brief Set the complete services. * @param [in] uuid The single service to advertise. */ -void NimBLEAdvertisementData::setCompleteServices(NimBLEUUID uuid) { - char cdata[2]; - switch (uuid.bitSize()) { - case 16: { - // [Len] [0x02] [LL] [HH] - cdata[0] = 3; - cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS16; // 0x03 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2)); - break; - } +void NimBLEAdvertisementData::setCompleteServices(const NimBLEUUID &uuid) { + char cdata[2]; + switch (uuid.bitSize()) { + case 16: { + // [Len] [0x02] [LL] [HH] + cdata[0] = 3; + cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS16; // 0x03 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2)); + break; + } - case 32: { - // [Len] [0x04] [LL] [LL] [HH] [HH] - cdata[0] = 5; - cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS32; // 0x05 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4)); - break; - } + case 32: { + // [Len] [0x04] [LL] [LL] [HH] [HH] + cdata[0] = 5; + cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS32; // 0x05 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4)); + break; + } - case 128: { - // [Len] [0x04] [0] [1] ... [15] - cdata[0] = 17; - cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS128; // 0x07 - addData(std::string(cdata, 2) + std::string((char*) uuid.getNative()->u128.value, 16)); - break; - } + case 128: { + // [Len] [0x04] [0] [1] ... [15] + cdata[0] = 17; + cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS128; // 0x07 + addData(std::string(cdata, 2) + std::string((char*) uuid.getNative()->u128.value, 16)); + break; + } - default: - return; - } + default: + return; + } } // setCompleteServices @@ -463,18 +476,18 @@ void NimBLEAdvertisementData::setCompleteServices(NimBLEUUID uuid) { * * ESP_BLE_ADV_FLAG_DMT_CONTROLLER_SPT * * ESP_BLE_ADV_FLAG_DMT_HOST_SPT * * ESP_BLE_ADV_FLAG_NON_LIMIT_DISC - * * + * * * * ****THESE ARE SUPPORTED**** * * BLE_HS_ADV_F_DISC_LTD * * BLE_HS_ADV_F_DISC_GEN * * BLE_HS_ADV_F_BREDR_UNSUP - must always use with NimBLE */ void NimBLEAdvertisementData::setFlags(uint8_t flag) { - char cdata[3]; - cdata[0] = 2; - cdata[1] = BLE_HS_ADV_TYPE_FLAGS; // 0x01 - cdata[2] = flag | BLE_HS_ADV_F_BREDR_UNSUP; - addData(std::string(cdata, 3)); + char cdata[3]; + cdata[0] = 2; + cdata[1] = BLE_HS_ADV_TYPE_FLAGS; // 0x01 + cdata[2] = flag | BLE_HS_ADV_F_BREDR_UNSUP; + addData(std::string(cdata, 3)); } // setFlag @@ -482,13 +495,13 @@ void NimBLEAdvertisementData::setFlags(uint8_t flag) { * @brief Set manufacturer specific data. * @param [in] data Manufacturer data. */ -void NimBLEAdvertisementData::setManufacturerData(std::string data) { - NIMBLE_LOGD("NimBLEAdvertisementData", ">> setManufacturerData"); - char cdata[2]; - cdata[0] = data.length() + 1; - cdata[1] = BLE_HS_ADV_TYPE_MFG_DATA ; // 0xff - addData(std::string(cdata, 2) + data); - NIMBLE_LOGD("NimBLEAdvertisementData", "<< setManufacturerData"); +void NimBLEAdvertisementData::setManufacturerData(const std::string &data) { + NIMBLE_LOGD("NimBLEAdvertisementData", ">> setManufacturerData"); + char cdata[2]; + cdata[0] = data.length() + 1; + cdata[1] = BLE_HS_ADV_TYPE_MFG_DATA ; // 0xff + addData(std::string(cdata, 2) + data); + NIMBLE_LOGD("NimBLEAdvertisementData", "<< setManufacturerData"); } // setManufacturerData @@ -496,13 +509,13 @@ void NimBLEAdvertisementData::setManufacturerData(std::string data) { * @brief Set the name. * @param [in] The complete name of the device. */ -void NimBLEAdvertisementData::setName(std::string name) { - NIMBLE_LOGD("NimBLEAdvertisementData", ">> setName: %s", name.c_str()); - char cdata[2]; - cdata[0] = name.length() + 1; - cdata[1] = BLE_HS_ADV_TYPE_COMP_NAME; // 0x09 - addData(std::string(cdata, 2) + name); - NIMBLE_LOGD("NimBLEAdvertisementData", "<< setName"); +void NimBLEAdvertisementData::setName(const std::string &name) { + NIMBLE_LOGD("NimBLEAdvertisementData", ">> setName: %s", name.c_str()); + char cdata[2]; + cdata[0] = name.length() + 1; + cdata[1] = BLE_HS_ADV_TYPE_COMP_NAME; // 0x09 + addData(std::string(cdata, 2) + name); + NIMBLE_LOGD("NimBLEAdvertisementData", "<< setName"); } // setName @@ -510,36 +523,36 @@ void NimBLEAdvertisementData::setName(std::string name) { * @brief Set the partial services. * @param [in] uuid The single service to advertise. */ -void NimBLEAdvertisementData::setPartialServices(NimBLEUUID uuid) { - char cdata[2]; - switch (uuid.bitSize()) { - case 16: { - // [Len] [0x02] [LL] [HH] - cdata[0] = 3; - cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS16; // 0x02 - addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u16.value, 2)); - break; - } +void NimBLEAdvertisementData::setPartialServices(const NimBLEUUID &uuid) { + char cdata[2]; + switch (uuid.bitSize()) { + case 16: { + // [Len] [0x02] [LL] [HH] + cdata[0] = 3; + cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS16; // 0x02 + addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u16.value, 2)); + break; + } - case 32: { - // [Len] [0x04] [LL] [LL] [HH] [HH] - cdata[0] = 5; - cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS32; // 0x04 - addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u32.value, 4)); - break; - } + case 32: { + // [Len] [0x04] [LL] [LL] [HH] [HH] + cdata[0] = 5; + cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS32; // 0x04 + addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u32.value, 4)); + break; + } - case 128: { - // [Len] [0x04] [0] [1] ... [15] - cdata[0] = 17; - cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS128; // 0x06 - addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u128.value, 16)); - break; - } + case 128: { + // [Len] [0x04] [0] [1] ... [15] + cdata[0] = 17; + cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS128; // 0x06 + addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u128.value, 16)); + break; + } - default: - return; - } + default: + return; + } } // setPartialServices @@ -548,36 +561,36 @@ void NimBLEAdvertisementData::setPartialServices(NimBLEUUID uuid) { * @param [in] uuid The UUID to set with the service data. Size of UUID will be used. * @param [in] data The data to be associated with the service data advert. */ -void NimBLEAdvertisementData::setServiceData(NimBLEUUID uuid, std::string data) { - char cdata[2]; - switch (uuid.bitSize()) { - case 16: { - // [Len] [0x16] [UUID16] data - cdata[0] = data.length() + 3; - cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID16; // 0x16 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2) + data); - break; - } +void NimBLEAdvertisementData::setServiceData(const NimBLEUUID &uuid, const std::string &data) { + char cdata[2]; + switch (uuid.bitSize()) { + case 16: { + // [Len] [0x16] [UUID16] data + cdata[0] = data.length() + 3; + cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID16; // 0x16 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2) + data); + break; + } - case 32: { - // [Len] [0x20] [UUID32] data - cdata[0] = data.length() + 5; - cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID32; // 0x20 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4) + data); - break; - } + case 32: { + // [Len] [0x20] [UUID32] data + cdata[0] = data.length() + 5; + cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID32; // 0x20 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4) + data); + break; + } - case 128: { - // [Len] [0x21] [UUID128] data - cdata[0] = data.length() + 17; - cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID128; // 0x21 - addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u128.value, 16) + data); - break; - } + case 128: { + // [Len] [0x21] [UUID128] data + cdata[0] = data.length() + 17; + cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID128; // 0x21 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u128.value, 16) + data); + break; + } - default: - return; - } + default: + return; + } } // setServiceData @@ -585,13 +598,13 @@ void NimBLEAdvertisementData::setServiceData(NimBLEUUID uuid, std::string data) * @brief Set the short name. * @param [in] The short name of the device. */ -void NimBLEAdvertisementData::setShortName(std::string name) { - NIMBLE_LOGD("NimBLEAdvertisementData", ">> setShortName: %s", name.c_str()); - char cdata[2]; - cdata[0] = name.length() + 1; - cdata[1] = BLE_HS_ADV_TYPE_INCOMP_NAME; // 0x08 - addData(std::string(cdata, 2) + name); - NIMBLE_LOGD("NimBLEAdvertisementData", "<< setShortName"); +void NimBLEAdvertisementData::setShortName(const std::string &name) { + NIMBLE_LOGD("NimBLEAdvertisementData", ">> setShortName: %s", name.c_str()); + char cdata[2]; + cdata[0] = name.length() + 1; + cdata[1] = BLE_HS_ADV_TYPE_INCOMP_NAME; // 0x08 + addData(std::string(cdata, 2) + name); + NIMBLE_LOGD("NimBLEAdvertisementData", "<< setShortName"); } // setShortName @@ -600,7 +613,8 @@ void NimBLEAdvertisementData::setShortName(std::string name) { * @return The payload that is to be advertised. */ std::string NimBLEAdvertisementData::getPayload() { - return m_payload; + return m_payload; } // getPayload -#endif /* CONFIG_BT_ENABLED */ \ No newline at end of file +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h index 5e4d58a9a..f30b1581c 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h @@ -3,7 +3,7 @@ * * Created: on March 3, 2020 * Author H2zero - * + * * Originally: * * BLEAdvertising.h @@ -17,6 +17,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + #include "host/ble_gap.h" /**** FIX COMPILATION ****/ #undef min @@ -42,24 +45,24 @@ * @brief Advertisement data set by the programmer to be published by the %BLE server. */ class NimBLEAdvertisementData { - // Only a subset of the possible BLE architected advertisement fields are currently exposed. Others will - // be exposed on demand/request or as time permits. - // + // Only a subset of the possible BLE architected advertisement fields are currently exposed. Others will + // be exposed on demand/request or as time permits. + // public: - void setAppearance(uint16_t appearance); - void setCompleteServices(NimBLEUUID uuid); - void setFlags(uint8_t); - void setManufacturerData(std::string data); - void setName(std::string name); - void setPartialServices(NimBLEUUID uuid); - void setServiceData(NimBLEUUID uuid, std::string data); - void setShortName(std::string name); - void addData(std::string data); // Add data to the payload. - std::string getPayload(); // Retrieve the current advert payload. + void setAppearance(uint16_t appearance); + void setCompleteServices(const NimBLEUUID &uuid); + void setFlags(uint8_t); + void setManufacturerData(const std::string &data); + void setName(const std::string &name); + void setPartialServices(const NimBLEUUID &uuid); + void setServiceData(const NimBLEUUID &uuid, const std::string &data); + void setShortName(const std::string &name); + void addData(const std::string &data); // Add data to the payload. + std::string getPayload(); // Retrieve the current advert payload. private: - friend class NimBLEAdvertising; - std::string m_payload; // The payload of the advertisement. + friend class NimBLEAdvertising; + std::string m_payload; // The payload of the advertisement. }; // NimBLEAdvertisementData @@ -70,36 +73,40 @@ private: */ class NimBLEAdvertising { public: - NimBLEAdvertising(); - void addServiceUUID(NimBLEUUID serviceUUID); - void addServiceUUID(const char* serviceUUID); - void start(); - void stop(); - void setAppearance(uint16_t appearance); + NimBLEAdvertising(); + void addServiceUUID(const NimBLEUUID &serviceUUID); + void addServiceUUID(const char* serviceUUID); + void start(); + void stop(); + void setAppearance(uint16_t appearance); void setAdvertisementType(uint8_t adv_type); - void setMaxInterval(uint16_t maxinterval); - void setMinInterval(uint16_t mininterval); - void setAdvertisementData(NimBLEAdvertisementData& advertisementData); - void setScanFilter(bool scanRequertWhitelistOnly, bool connectWhitelistOnly); - void setScanResponseData(NimBLEAdvertisementData& advertisementData); - void setPrivateAddress(uint8_t type = BLE_ADDR_RANDOM); + void setMaxInterval(uint16_t maxinterval); + void setMinInterval(uint16_t mininterval); + void setAdvertisementData(NimBLEAdvertisementData& advertisementData); + void setScanFilter(bool scanRequertWhitelistOnly, bool connectWhitelistOnly); + void setScanResponseData(NimBLEAdvertisementData& advertisementData); + void setPrivateAddress(uint8_t type = BLE_ADDR_RANDOM); - void setMinPreferred(uint16_t); - void setMaxPreferred(uint16_t); - void setScanResponse(bool); + void setMinPreferred(uint16_t); + void setMaxPreferred(uint16_t); + void setScanResponse(bool); private: friend class NimBLEDevice; + void onHostReset(); - ble_hs_adv_fields m_advData; - ble_hs_adv_fields m_scanData; - ble_gap_adv_params m_advParams; - std::vector m_serviceUUIDs; - bool m_customAdvData = false; // Are we using custom advertising data? - bool m_customScanResponseData = false; // Are we using custom scan response data? - bool m_scanResp = true; + + ble_hs_adv_fields m_advData; + ble_hs_adv_fields m_scanData; + ble_gap_adv_params m_advParams; + std::vector m_serviceUUIDs; + bool m_customAdvData = false; // Are we using custom advertising data? + bool m_customScanResponseData = false; // Are we using custom scan response data? + bool m_scanResp = true; bool m_advSvcsSet = false; }; + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif /* CONFIG_BT_ENABLED */ -#endif /* MAIN_BLEADVERTISING_H_ */ \ No newline at end of file +#endif /* MAIN_BLEADVERTISING_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEBeacon.cpp b/libesp32/NimBLE-Arduino/src/NimBLEBeacon.cpp index d9f32aee6..718a507f5 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEBeacon.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEBeacon.cpp @@ -3,7 +3,7 @@ * * Created: on March 15 2020 * Author H2zero - * + * * Originally: * * BLEBeacon.cpp @@ -13,6 +13,7 @@ */ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) + #include #include "NimBLEBeacon.h" #include "NimBLELog.h" @@ -22,71 +23,71 @@ static const char* LOG_TAG = "NimBLEBeacon"; NimBLEBeacon::NimBLEBeacon() { - m_beaconData.manufacturerId = 0x4c00; - m_beaconData.subType = 0x02; - m_beaconData.subTypeLength = 0x15; - m_beaconData.major = 0; - m_beaconData.minor = 0; - m_beaconData.signalPower = 0; - memset(m_beaconData.proximityUUID, 0, sizeof(m_beaconData.proximityUUID)); + m_beaconData.manufacturerId = 0x4c00; + m_beaconData.subType = 0x02; + m_beaconData.subTypeLength = 0x15; + m_beaconData.major = 0; + m_beaconData.minor = 0; + m_beaconData.signalPower = 0; + memset(m_beaconData.proximityUUID, 0, sizeof(m_beaconData.proximityUUID)); } // NimBLEBeacon std::string NimBLEBeacon::getData() { - return std::string((char*) &m_beaconData, sizeof(m_beaconData)); + return std::string((char*) &m_beaconData, sizeof(m_beaconData)); } // getData uint16_t NimBLEBeacon::getMajor() { - return m_beaconData.major; + return m_beaconData.major; } uint16_t NimBLEBeacon::getManufacturerId() { - return m_beaconData.manufacturerId; + return m_beaconData.manufacturerId; } uint16_t NimBLEBeacon::getMinor() { - return m_beaconData.minor; + return m_beaconData.minor; } NimBLEUUID NimBLEBeacon::getProximityUUID() { - return NimBLEUUID(m_beaconData.proximityUUID, 16, false); + return NimBLEUUID(m_beaconData.proximityUUID, 16, false); } int8_t NimBLEBeacon::getSignalPower() { - return m_beaconData.signalPower; + return m_beaconData.signalPower; } /** * Set the raw data for the beacon record. */ -void NimBLEBeacon::setData(std::string data) { - if (data.length() != sizeof(m_beaconData)) { - NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d", +void NimBLEBeacon::setData(const std::string &data) { + if (data.length() != sizeof(m_beaconData)) { + NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d", data.length(), sizeof(m_beaconData)); - return; - } - memcpy(&m_beaconData, data.data(), sizeof(m_beaconData)); + return; + } + memcpy(&m_beaconData, data.data(), sizeof(m_beaconData)); } // setData void NimBLEBeacon::setMajor(uint16_t major) { - m_beaconData.major = ENDIAN_CHANGE_U16(major); + m_beaconData.major = ENDIAN_CHANGE_U16(major); } // setMajor void NimBLEBeacon::setManufacturerId(uint16_t manufacturerId) { - m_beaconData.manufacturerId = ENDIAN_CHANGE_U16(manufacturerId); + m_beaconData.manufacturerId = ENDIAN_CHANGE_U16(manufacturerId); } // setManufacturerId void NimBLEBeacon::setMinor(uint16_t minor) { - m_beaconData.minor = ENDIAN_CHANGE_U16(minor); + m_beaconData.minor = ENDIAN_CHANGE_U16(minor); } // setMinior -void NimBLEBeacon::setProximityUUID(NimBLEUUID uuid) { - uuid = uuid.to128(); - memcpy(m_beaconData.proximityUUID, uuid.getNative()->u128.value, 16); +void NimBLEBeacon::setProximityUUID(const NimBLEUUID &uuid) { + NimBLEUUID temp_uuid = uuid; + temp_uuid.to128(); + memcpy(m_beaconData.proximityUUID, temp_uuid.getNative()->u128.value, 16); } // setProximityUUID void NimBLEBeacon::setSignalPower(int8_t signalPower) { - m_beaconData.signalPower = signalPower; + m_beaconData.signalPower = signalPower; } // setSignalPower - #endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLEBeacon.h b/libesp32/NimBLE-Arduino/src/NimBLEBeacon.h index c0c15c8eb..82ee61c53 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEBeacon.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEBeacon.h @@ -3,7 +3,7 @@ * * Created: on March 15 2020 * Author H2zero - * + * * Originally: * * BLEBeacon2.h @@ -14,6 +14,7 @@ #ifndef MAIN_NIMBLEBEACON_H_ #define MAIN_NIMBLEBEACON_H_ + #include "NimBLEUUID.h" /** * @brief Representation of a beacon. @@ -22,29 +23,29 @@ */ class NimBLEBeacon { private: - struct { - uint16_t manufacturerId; - uint8_t subType; - uint8_t subTypeLength; - uint8_t proximityUUID[16]; - uint16_t major; - uint16_t minor; - int8_t signalPower; - } __attribute__((packed)) m_beaconData; + struct { + uint16_t manufacturerId; + uint8_t subType; + uint8_t subTypeLength; + uint8_t proximityUUID[16]; + uint16_t major; + uint16_t minor; + int8_t signalPower; + } __attribute__((packed)) m_beaconData; public: - NimBLEBeacon(); - std::string getData(); - uint16_t getMajor(); - uint16_t getMinor(); - uint16_t getManufacturerId(); - NimBLEUUID getProximityUUID(); - int8_t getSignalPower(); - void setData(std::string data); - void setMajor(uint16_t major); - void setMinor(uint16_t minor); - void setManufacturerId(uint16_t manufacturerId); - void setProximityUUID(NimBLEUUID uuid); - void setSignalPower(int8_t signalPower); + NimBLEBeacon(); + std::string getData(); + uint16_t getMajor(); + uint16_t getMinor(); + uint16_t getManufacturerId(); + NimBLEUUID getProximityUUID(); + int8_t getSignalPower(); + void setData(const std::string &data); + void setMajor(uint16_t major); + void setMinor(uint16_t minor); + void setManufacturerId(uint16_t manufacturerId); + void setProximityUUID(const NimBLEUUID &uuid); + void setSignalPower(int8_t signalPower); }; // NimBLEBeacon #endif /* MAIN_NIMBLEBEACON_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp index d69fee8cd..dd1be3bf0 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp @@ -3,7 +3,7 @@ * * Created: on March 3, 2020 * Author H2zero - * + * * BLECharacteristic.cpp * * Created on: Jun 22, 2017 @@ -12,6 +12,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLECharacteristic.h" #include "NimBLE2902.h" #include "NimBLE2904.h" @@ -32,7 +35,7 @@ static const char* LOG_TAG = "NimBLECharacteristic"; * @param [in] uuid - UUID (const char*) for the characteristic. * @param [in] properties - Properties for the characteristic. */ -NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties, NimBLEService* pService) +NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties, NimBLEService* pService) : NimBLECharacteristic(NimBLEUUID(uuid), properties, pService) { } @@ -41,19 +44,19 @@ NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties * @param [in] uuid - UUID for the characteristic. * @param [in] properties - Properties for the characteristic. */ -NimBLECharacteristic::NimBLECharacteristic(NimBLEUUID uuid, uint16_t properties, NimBLEService* pService) { - m_uuid = uuid; - m_handle = NULL_HANDLE; - m_properties = properties; - m_pCallbacks = &defaultCallback; +NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties, NimBLEService* pService) { + m_uuid = uuid; + m_handle = NULL_HANDLE; + m_properties = properties; + m_pCallbacks = &defaultCallback; m_pService = pService; // Backward Compatibility - to be removed -/* setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0); - setReadProperty((properties & PROPERTY_READ) != 0); - setWriteProperty((properties & PROPERTY_WRITE) != 0); - setNotifyProperty((properties & PROPERTY_NOTIFY) != 0); - setIndicateProperty((properties & PROPERTY_INDICATE) != 0); - setWriteNoResponseProperty((properties & PROPERTY_WRITE_NR) != 0); +/* setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0); + setReadProperty((properties & PROPERTY_READ) != 0); + setWriteProperty((properties & PROPERTY_WRITE) != 0); + setNotifyProperty((properties & PROPERTY_NOTIFY) != 0); + setIndicateProperty((properties & PROPERTY_INDICATE) != 0); + setWriteNoResponseProperty((properties & PROPERTY_WRITE_NR) != 0); */ /////////////////////////////////////////// } // NimBLECharacteristic @@ -71,14 +74,14 @@ NimBLECharacteristic::~NimBLECharacteristic() { * @return N/A. */ void NimBLECharacteristic::addDescriptor(NimBLEDescriptor* pDescriptor) { - NIMBLE_LOGD(LOG_TAG, ">> addDescriptor(): Adding %s to %s", pDescriptor->toString().c_str(), toString().c_str()); - // Check that we don't add the same descriptor twice. - if (m_descriptorMap.getByUUID(pDescriptor->getUUID()) != nullptr) { - NIMBLE_LOGW(LOG_TAG, "<< Adding a new descriptor with the same UUID as a previous one"); - //return; - } - m_descriptorMap.setByUUID(pDescriptor->getUUID(), pDescriptor); - NIMBLE_LOGD(LOG_TAG, "<< addDescriptor()"); + NIMBLE_LOGD(LOG_TAG, ">> addDescriptor(): Adding %s to %s", pDescriptor->toString().c_str(), toString().c_str()); + // Check that we don't add the same descriptor twice. + if (m_descriptorMap.getByUUID(pDescriptor->getUUID()) != nullptr) { + NIMBLE_LOGW(LOG_TAG, "<< Adding a new descriptor with the same UUID as a previous one"); + //return; + } + m_descriptorMap.setByUUID(pDescriptor->getUUID(), pDescriptor); + NIMBLE_LOGD(LOG_TAG, "<< addDescriptor()"); } // addDescriptor @@ -89,7 +92,7 @@ void NimBLECharacteristic::addDescriptor(NimBLEDescriptor* pDescriptor) { * @return The new BLE descriptor. */ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint32_t properties, uint16_t max_len) { - return createDescriptor(NimBLEUUID(uuid), properties, max_len); + return createDescriptor(NimBLEUUID(uuid), properties, max_len); } @@ -99,9 +102,9 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint3 * @param [in] properties - The properties of the descriptor. * @return The new BLE descriptor. */ -NimBLEDescriptor* NimBLECharacteristic::createDescriptor(NimBLEUUID uuid, uint32_t properties, uint16_t max_len) { - NimBLEDescriptor* pDescriptor = nullptr; - if(uuid.equals(NimBLEUUID((uint16_t)0x2902))) { +NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, uint32_t properties, uint16_t max_len) { + NimBLEDescriptor* pDescriptor = nullptr; + if(uuid.equals(NimBLEUUID((uint16_t)0x2902))) { if(!(m_properties & BLE_GATT_CHR_F_NOTIFY) && !(m_properties & BLE_GATT_CHR_F_INDICATE)) { assert(0 && "Cannot create 2902 descriptior without characteristic notification or indication property set"); } @@ -112,15 +115,15 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(NimBLEUUID uuid, uint32 } else { return pDescriptor; } - - } else if (uuid.equals(NimBLEUUID((uint16_t)0x2904))) { - pDescriptor = new NimBLE2904(this); - - } else { - pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this); - } - addDescriptor(pDescriptor); - return pDescriptor; + + } else if (uuid.equals(NimBLEUUID((uint16_t)0x2904))) { + pDescriptor = new NimBLE2904(this); + + } else { + pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this); + } + addDescriptor(pDescriptor); + return pDescriptor; } // createCharacteristic @@ -130,7 +133,7 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(NimBLEUUID uuid, uint32 * @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned. */ NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* descriptorUUID) { - return m_descriptorMap.getByUUID(NimBLEUUID(descriptorUUID)); + return m_descriptorMap.getByUUID(NimBLEUUID(descriptorUUID)); } // getDescriptorByUUID @@ -139,8 +142,8 @@ NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* descript * @param [in] descriptorUUID The UUID of the descriptor that we wish to retrieve. * @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned. */ -NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(NimBLEUUID descriptorUUID) { - return m_descriptorMap.getByUUID(descriptorUUID); +NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID &descriptorUUID) { + return m_descriptorMap.getByUUID(descriptorUUID); } // getDescriptorByUUID @@ -149,17 +152,17 @@ NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(NimBLEUUID descripto * @return The handle of the characteristic. */ uint16_t NimBLECharacteristic::getHandle() { - return m_handle; + return m_handle; } // getHandle /* void NimBLECharacteristic::setAccessPermissions(uint16_t perm) { - m_permissions = perm; + m_permissions = perm; } */ uint8_t NimBLECharacteristic::getProperties() { - return m_properties; + return m_properties; } // getProperties @@ -167,7 +170,7 @@ uint8_t NimBLECharacteristic::getProperties() { * @brief Get the service associated with this characteristic. */ NimBLEService* NimBLECharacteristic::getService() { - return m_pService; + return m_pService; } // getService @@ -176,7 +179,7 @@ NimBLEService* NimBLECharacteristic::getService() { * @return The UUID of the characteristic. */ NimBLEUUID NimBLECharacteristic::getUUID() { - return m_uuid; + return m_uuid; } // getUUID @@ -185,7 +188,7 @@ NimBLEUUID NimBLECharacteristic::getUUID() { * @return A pointer to storage containing the current characteristic value. */ std::string NimBLECharacteristic::getValue() { - return m_value.getValue(); + return m_value.getValue(); } // getValue @@ -194,51 +197,60 @@ std::string NimBLECharacteristic::getValue() { * @return A pointer to storage containing the current characteristic data. */ uint8_t* NimBLECharacteristic::getData() { - return m_value.getData(); + return m_value.getData(); } // getData +/** + * @brief Retrieve the the current data length of the characteristic. + * @return The length of the current characteristic data. + */ +size_t NimBLECharacteristic:: getDataLength() { + return m_value.getLength(); +} + + int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { - const ble_uuid_t *uuid; + const ble_uuid_t *uuid; int rc; - NimBLECharacteristic* pCharacteristic = (NimBLECharacteristic*)arg; - - NIMBLE_LOGD(LOG_TAG, "Characteristic %s %s event", pCharacteristic->getUUID().toString().c_str(), + NimBLECharacteristic* pCharacteristic = (NimBLECharacteristic*)arg; + + NIMBLE_LOGD(LOG_TAG, "Characteristic %s %s event", pCharacteristic->getUUID().toString().c_str(), ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR ? "Read" : "Write"); - - uuid = ctxt->chr->uuid; - if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){ + + uuid = ctxt->chr->uuid; + if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){ switch(ctxt->op) { case BLE_GATT_ACCESS_OP_READ_CHR: { //NIMBLE_LOGD(LOG_TAG, "read char pkthdr len:%d flags:%d", ctxt->om->om_pkthdr_len, ctxt->om->om_flags); - // If the packet header is only 8 bytes this is a follow up of a long read - // so we don't want to call the onRead() callback again. - if(ctxt->om->om_pkthdr_len > 8) { - pCharacteristic->m_pCallbacks->onRead(pCharacteristic); - } + // If the packet header is only 8 bytes this is a follow up of a long read + // so we don't want to call the onRead() callback again. + if(ctxt->om->om_pkthdr_len > 8) { + pCharacteristic->m_pCallbacks->onRead(pCharacteristic); + } rc = os_mbuf_append(ctxt->om, pCharacteristic->getData(), pCharacteristic->m_value.getLength()); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } - + case BLE_GATT_ACCESS_OP_WRITE_CHR: { //NIMBLE_LOGD(LOG_TAG, "write char pkthdr len:%d datalen:%d", ctxt->om->om_pkthdr_len, ctxt->om->om_len); if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - + //pCharacteristic->setValue(ctxt->om->om_data, ctxt->om->om_len); - pCharacteristic->m_value.addPart(ctxt->om->om_data, ctxt->om->om_len); - os_mbuf *next; - next = SLIST_NEXT(ctxt->om, om_next); - while(next != NULL){ - //NIMBLE_LOGD(LOG_TAG, "Found long write data, len:%d", next->om_len); - pCharacteristic->m_value.addPart(next->om_data, next->om_len); - next = SLIST_NEXT(next, om_next); - } - pCharacteristic->m_value.commit(); + pCharacteristic->m_value.addPart(ctxt->om->om_data, ctxt->om->om_len); + os_mbuf *next; + next = SLIST_NEXT(ctxt->om, om_next); + while(next != NULL){ + //NIMBLE_LOGD(LOG_TAG, "Found long write data, len:%d", next->om_len); + pCharacteristic->m_value.addPart(next->om_data, next->om_len); + next = SLIST_NEXT(next, om_next); + } + pCharacteristic->m_value.commit(); pCharacteristic->m_pCallbacks->onWrite(pCharacteristic); return 0; @@ -246,11 +258,11 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han default: break; } - } - + } + return BLE_ATT_ERR_UNLIKELY; } - + /** * @brief Set the subscribe status for this characteristic. @@ -265,23 +277,23 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { if(event->subscribe.cur_indicate) { subVal |= NIMBLE_DESC_FLAG_INDICATE; } - + m_semaphoreConfEvt.give((subVal | NIMBLE_DESC_FLAG_INDICATE) ? 0 : NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED); - + NIMBLE_LOGI(LOG_TAG, "New subscribe value for conn: %d val: %d", event->subscribe.conn_handle, subVal); - + NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID((uint16_t)0x2902); - if(p2902 == nullptr){ - ESP_LOGE(LOG_TAG, "No 2902 descriptor found for %s", getUUID().toString().c_str()); + if(p2902 == nullptr){ + ESP_LOGE(LOG_TAG, "No 2902 descriptor found for %s", getUUID().toString().c_str()); return; - } - + } + p2902->setNotifications(subVal & NIMBLE_DESC_FLAG_NOTIFY); p2902->setIndications(subVal & NIMBLE_DESC_FLAG_INDICATE); p2902->m_pCallbacks->onWrite(p2902); - - + + auto it = p2902->m_subscribedMap.find(event->subscribe.conn_handle); if(subVal > 0 && it == p2902->m_subscribedMap.cend()) { p2902->m_subscribedMap.insert(std::pair(event->subscribe.conn_handle, subVal)); @@ -290,12 +302,12 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { p2902->m_subscribedMap.erase(event->subscribe.conn_handle); return; } -/* +/* if(event->subscribe.reason == BLE_GAP_SUBSCRIBE_REASON_TERM) { p2902->m_subscribedMap.erase(event->subscribe.conn_handle); return; } -*/ +*/ (*it).second = subVal; } @@ -307,11 +319,11 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { * @return N/A */ void NimBLECharacteristic::indicate() { - NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", m_value.getValue().length()); - notify(false); - NIMBLE_LOGD(LOG_TAG, "<< indicate"); + NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", m_value.getValue().length()); + notify(false); + NIMBLE_LOGD(LOG_TAG, "<< indicate"); } // indicate - + /** * @brief Send a notify. * A notification is a transmission of up to the first 20 bytes of the characteristic value. An notification @@ -319,29 +331,29 @@ void NimBLECharacteristic::indicate() { * @return N/A. */ void NimBLECharacteristic::notify(bool is_notification) { - NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", m_value.getValue().length()); + NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", m_value.getValue().length()); - assert(getService() != nullptr); - assert(getService()->getServer() != nullptr); + assert(getService() != nullptr); + assert(getService()->getServer() != nullptr); if (getService()->getServer()->getConnectedCount() == 0) { - NIMBLE_LOGD(LOG_TAG, "<< notify: No connected clients."); - return; - } - + NIMBLE_LOGD(LOG_TAG, "<< notify: No connected clients."); + return; + } + m_pCallbacks->onNotify(this); - + int rc = 0; NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID((uint16_t)0x2902); - + for (auto it = p2902->m_subscribedMap.cbegin(); it != p2902->m_subscribedMap.cend(); ++it) { uint16_t _mtu = getService()->getServer()->getPeerMTU((*it).first); - // Must rebuild the data on each loop iteration as NimBLE will release it. + // Must rebuild the data on each loop iteration as NimBLE will release it. size_t length = m_value.getValue().length(); uint8_t* data = (uint8_t*)m_value.getValue().data(); os_mbuf *om; - + if(_mtu == 0) { //NIMBLE_LOGD(LOG_TAG, "peer not connected, removing from map"); p2902->m_subscribedMap.erase((*it).first); @@ -351,33 +363,33 @@ void NimBLECharacteristic::notify(bool is_notification) { } continue; } - + if (length > _mtu - 3) { - NIMBLE_LOGW(LOG_TAG, "- Truncating to %d bytes (maximum notify size)", _mtu - 3); - } - + NIMBLE_LOGW(LOG_TAG, "- Truncating to %d bytes (maximum notify size)", _mtu - 3); + } + if((*it).second == 0) { //NIMBLE_LOGI(LOG_TAG, "Skipping unsubscribed client"); continue; } - + if(is_notification && (!((*it).second & NIMBLE_DESC_FLAG_NOTIFY))) { - NIMBLE_LOGW(LOG_TAG, + NIMBLE_LOGW(LOG_TAG, "Sending notification to client subscribed to indications, sending indication instead"); is_notification = false; } - + if(!is_notification && (!((*it).second & NIMBLE_DESC_FLAG_INDICATE))) { NIMBLE_LOGW(LOG_TAG, "Sending indication to client subscribed to notifications, sending notifications instead"); is_notification = true; } - + // don't create the m_buf until we are sure to send the data or else // we could be allocating a buffer that doesn't get released. // We also must create it in each loop iteration because it is consumed with each host call. om = ble_hs_mbuf_from_flat(data, length); - + if(!is_notification) { m_semaphoreConfEvt.take("indicate"); rc = ble_gattc_indicate_custom((*it).first, m_handle, om); @@ -386,9 +398,9 @@ void NimBLECharacteristic::notify(bool is_notification) { m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_GATT, rc); return; } - + rc = m_semaphoreConfEvt.wait(); - + if(rc == BLE_HS_ETIMEOUT) { m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT, rc); } else if(rc == BLE_HS_EDONE) { @@ -401,12 +413,12 @@ void NimBLECharacteristic::notify(bool is_notification) { if(rc == 0) { m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::SUCCESS_NOTIFY, 0); } else { - m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_GATT, rc); + m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_GATT, rc); } } - } + } - NIMBLE_LOGD(LOG_TAG, "<< notify"); + NIMBLE_LOGD(LOG_TAG, "<< notify"); } // Notify @@ -415,11 +427,11 @@ void NimBLECharacteristic::notify(bool is_notification) { * @param [in] pCallbacks An instance of a callbacks structure used to define any callbacks for the characteristic. */ void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallbacks) { - if (pCallbacks != nullptr){ - m_pCallbacks = pCallbacks; - } else { - m_pCallbacks = &defaultCallback; - } + if (pCallbacks != nullptr){ + m_pCallbacks = pCallbacks; + } else { + m_pCallbacks = &defaultCallback; + } } // setCallbacks // Backward compatibility - to be removed //////////////////////////////// @@ -431,11 +443,11 @@ void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallback * @return N/A */ void NimBLECharacteristic::setBroadcastProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_BROADCAST); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_BROADCAST); - } + if (value) { + m_properties = (m_properties | BLE_GATT_CHR_F_BROADCAST); + } else { + m_properties = (m_properties & ~BLE_GATT_CHR_F_BROADCAST); + } } // setBroadcastProperty @@ -444,11 +456,11 @@ void NimBLECharacteristic::setBroadcastProperty(bool value) { * @param [in] value Set to true if we are to allow indicate messages. */ void NimBLECharacteristic::setIndicateProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_INDICATE); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_INDICATE); - } + if (value) { + m_properties = (m_properties | BLE_GATT_CHR_F_INDICATE); + } else { + m_properties = (m_properties & ~BLE_GATT_CHR_F_INDICATE); + } } // setIndicateProperty @@ -457,11 +469,11 @@ void NimBLECharacteristic::setIndicateProperty(bool value) { * @param [in] value Set to true if we are to allow notification messages. */ void NimBLECharacteristic::setNotifyProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_NOTIFY); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_NOTIFY); - } + if (value) { + m_properties = (m_properties | BLE_GATT_CHR_F_NOTIFY); + } else { + m_properties = (m_properties & ~BLE_GATT_CHR_F_NOTIFY); + } } // setNotifyProperty @@ -470,11 +482,11 @@ void NimBLECharacteristic::setNotifyProperty(bool value) { * @param [in] value Set to true if we are to allow reads. */ void NimBLECharacteristic::setReadProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_READ); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_READ); - } + if (value) { + m_properties = (m_properties | BLE_GATT_CHR_F_READ); + } else { + m_properties = (m_properties & ~BLE_GATT_CHR_F_READ); + } } // setReadProperty @@ -483,11 +495,11 @@ void NimBLECharacteristic::setReadProperty(bool value) { * @param [in] value Set to true if we are to allow writes with no response. */ void NimBLECharacteristic::setWriteNoResponseProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_WRITE_NO_RSP); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE_NO_RSP); - } + if (value) { + m_properties = (m_properties | BLE_GATT_CHR_F_WRITE_NO_RSP); + } else { + m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE_NO_RSP); + } } // setWriteNoResponseProperty @@ -496,11 +508,11 @@ void NimBLECharacteristic::setWriteNoResponseProperty(bool value) { * @param [in] value Set to true if we are to allow writes. */ void NimBLECharacteristic::setWriteProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_WRITE ); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE ); - } + if (value) { + m_properties = (m_properties | BLE_GATT_CHR_F_WRITE ); + } else { + m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE ); + } } // setWriteProperty ////////////////////////////////////////////////////////////////////////////////// @@ -509,24 +521,24 @@ void NimBLECharacteristic::setWriteProperty(bool value) { * @param [in] data The data to set for the characteristic. * @param [in] length The length of the data in bytes. */ -void NimBLECharacteristic::setValue(uint8_t* data, size_t length) { - char* pHex = NimBLEUtils::buildHexData(nullptr, data, length); - NIMBLE_LOGD(LOG_TAG, ">> setValue: length=%d, data=%s, characteristic UUID=%s", length, pHex, getUUID().toString().c_str()); - free(pHex); +void NimBLECharacteristic::setValue(const uint8_t* data, size_t length) { + char* pHex = NimBLEUtils::buildHexData(nullptr, data, length); + NIMBLE_LOGD(LOG_TAG, ">> setValue: length=%d, data=%s, characteristic UUID=%s", length, pHex, getUUID().toString().c_str()); + free(pHex); + + if (length > BLE_ATT_ATTR_MAX_LEN) { + NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN); + return; + } + + m_value.setValue(data, length); - if (length > BLE_ATT_ATTR_MAX_LEN) { - NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN); - return; - } - - m_value.setValue(data, length); - // if(m_handle != NULL_HANDLE) { //ble_gatts_chr_updated(m_handle); // ble_gattc_notify(getService()->getServer()->m_connId, m_handle); // } - - NIMBLE_LOGD(LOG_TAG, "<< setValue"); + + NIMBLE_LOGD(LOG_TAG, "<< setValue"); } // setValue @@ -537,43 +549,43 @@ void NimBLECharacteristic::setValue(uint8_t* data, size_t length) { * @param [in] Set the value of the characteristic. * @return N/A. */ -void NimBLECharacteristic::setValue(std::string value) { - setValue((uint8_t*)(value.data()), value.length()); +void NimBLECharacteristic::setValue(const std::string &value) { + setValue((uint8_t*)(value.data()), value.length()); } // setValue void NimBLECharacteristic::setValue(uint16_t& data16) { - uint8_t temp[2]; - temp[0] = data16; - temp[1] = data16 >> 8; - setValue(temp, 2); + uint8_t temp[2]; + temp[0] = data16; + temp[1] = data16 >> 8; + setValue(temp, 2); } // setValue void NimBLECharacteristic::setValue(uint32_t& data32) { - uint8_t temp[4]; - temp[0] = data32; - temp[1] = data32 >> 8; - temp[2] = data32 >> 16; - temp[3] = data32 >> 24; - setValue(temp, 4); + uint8_t temp[4]; + temp[0] = data32; + temp[1] = data32 >> 8; + temp[2] = data32 >> 16; + temp[3] = data32 >> 24; + setValue(temp, 4); } // setValue void NimBLECharacteristic::setValue(int& data32) { - uint8_t temp[4]; - temp[0] = data32; - temp[1] = data32 >> 8; - temp[2] = data32 >> 16; - temp[3] = data32 >> 24; - setValue(temp, 4); + uint8_t temp[4]; + temp[0] = data32; + temp[1] = data32 >> 8; + temp[2] = data32 >> 16; + temp[3] = data32 >> 24; + setValue(temp, 4); } // setValue void NimBLECharacteristic::setValue(float& data32) { - float temp = data32; - setValue((uint8_t*)&temp, 4); + float temp = data32; + setValue((uint8_t*)&temp, 4); } // setValue void NimBLECharacteristic::setValue(double& data64) { - double temp = data64; - setValue((uint8_t*)&temp, 8); + double temp = data64; + setValue((uint8_t*)&temp, 8); } // setValue @@ -582,18 +594,18 @@ void NimBLECharacteristic::setValue(double& data64) { * @return A string representation of the characteristic. */ std::string NimBLECharacteristic::toString() { - std::string res = "UUID: " + m_uuid.toString() + ", handle : 0x"; - char hex[5]; - snprintf(hex, sizeof(hex), "%04x", m_handle); - res += hex; - res += " "; - if (m_properties & BLE_GATT_CHR_PROP_READ ) res += "Read "; - if (m_properties & BLE_GATT_CHR_PROP_WRITE) res += "Write "; - if (m_properties & BLE_GATT_CHR_PROP_WRITE_NO_RSP) res += "WriteNoResponse "; - if (m_properties & BLE_GATT_CHR_PROP_BROADCAST) res += "Broadcast "; - if (m_properties & BLE_GATT_CHR_PROP_NOTIFY) res += "Notify "; - if (m_properties & BLE_GATT_CHR_PROP_INDICATE) res += "Indicate "; - return res; + std::string res = "UUID: " + m_uuid.toString() + ", handle : 0x"; + char hex[5]; + snprintf(hex, sizeof(hex), "%04x", m_handle); + res += hex; + res += " "; + if (m_properties & BLE_GATT_CHR_PROP_READ ) res += "Read "; + if (m_properties & BLE_GATT_CHR_PROP_WRITE) res += "Write "; + if (m_properties & BLE_GATT_CHR_PROP_WRITE_NO_RSP) res += "WriteNoResponse "; + if (m_properties & BLE_GATT_CHR_PROP_BROADCAST) res += "Broadcast "; + if (m_properties & BLE_GATT_CHR_PROP_NOTIFY) res += "Notify "; + if (m_properties & BLE_GATT_CHR_PROP_INDICATE) res += "Indicate "; + return res; } // toString @@ -605,7 +617,7 @@ NimBLECharacteristicCallbacks::~NimBLECharacteristicCallbacks() {} * @param [in] pCharacteristic The characteristic that is the source of the event. */ void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic) { - NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default"); + NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default"); } // onRead @@ -614,7 +626,7 @@ void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic * @param [in] pCharacteristic The characteristic that is the source of the event. */ void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic) { - NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default"); + NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default"); } // onWrite @@ -623,7 +635,7 @@ void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristi * @param [in] pCharacteristic The characteristic that is the source of the event. */ void NimBLECharacteristicCallbacks::onNotify(NimBLECharacteristic* pCharacteristic) { - NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onNotify: default"); + NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onNotify: default"); } // onNotify @@ -634,7 +646,8 @@ void NimBLECharacteristicCallbacks::onNotify(NimBLECharacteristic* pCharacterist * @param [in] code Additional code of underlying errors */ void NimBLECharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code) { - NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onStatus: default"); + NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onStatus: default"); } // onStatus -#endif /* CONFIG_BT_ENABLED */ \ No newline at end of file +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h index 1787937bd..25e1ec7f7 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h +++ b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h @@ -3,7 +3,7 @@ * * Created: on March 3, 2020 * Author H2zero - * + * * Originally: * BLECharacteristic.h * @@ -16,6 +16,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "host/ble_hs.h" /**** FIX COMPILATION ****/ #undef min @@ -23,10 +26,10 @@ /**************************/ typedef enum { - READ = BLE_GATT_CHR_F_READ, + READ = BLE_GATT_CHR_F_READ, READ_ENC = BLE_GATT_CHR_F_READ_ENC, READ_AUTHEN = BLE_GATT_CHR_F_READ_AUTHEN, - READ_AUTHOR = BLE_GATT_CHR_F_READ_AUTHOR, + READ_AUTHOR = BLE_GATT_CHR_F_READ_AUTHOR, WRITE = BLE_GATT_CHR_F_WRITE, WRITE_NR = BLE_GATT_CHR_F_WRITE_NO_RSP, WRITE_ENC = BLE_GATT_CHR_F_WRITE_ENC, @@ -57,21 +60,21 @@ class NimBLECharacteristicCallbacks; */ class NimBLEDescriptorMap { public: - void setByUUID(const char* uuid, NimBLEDescriptor* pDescriptor); - void setByUUID(NimBLEUUID uuid, NimBLEDescriptor* pDescriptor); -// void setByHandle(uint16_t handle, NimBLEDescriptor* pDescriptor); - NimBLEDescriptor* getByUUID(const char* uuid); - NimBLEDescriptor* getByUUID(NimBLEUUID uuid); -// NimBLEDescriptor* getByHandle(uint16_t handle); - std::string toString(); - NimBLEDescriptor* getFirst(); - NimBLEDescriptor* getNext(); + void setByUUID(const char* uuid, NimBLEDescriptor* pDescriptor); + void setByUUID(const NimBLEUUID &uuid, NimBLEDescriptor* pDescriptor); +// void setByHandle(uint16_t handle, NimBLEDescriptor* pDescriptor); + NimBLEDescriptor* getByUUID(const char* uuid); + NimBLEDescriptor* getByUUID(const NimBLEUUID &uuid); +// NimBLEDescriptor* getByHandle(uint16_t handle); + std::string toString(); + NimBLEDescriptor* getFirst(); + NimBLEDescriptor* getNext(); uint8_t getSize(); - + private: - std::map m_uuidMap; -// std::map m_handleMap; - std::map::iterator m_iterator; + std::map m_uuidMap; +// std::map m_handleMap; + std::map::iterator m_iterator; }; @@ -83,84 +86,85 @@ private: */ class NimBLECharacteristic { public: - NimBLEDescriptor* createDescriptor(const char* uuid, - uint32_t properties = NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE, + NimBLEDescriptor* createDescriptor(const char* uuid, + uint32_t properties = NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, uint16_t max_len = 100); - NimBLEDescriptor* createDescriptor(NimBLEUUID uuid, - uint32_t properties = NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE, + NimBLEDescriptor* createDescriptor(const NimBLEUUID &uuid, + uint32_t properties = NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, uint16_t max_len = 100); - - NimBLEDescriptor* getDescriptorByUUID(const char* descriptorUUID); - NimBLEDescriptor* getDescriptorByUUID(NimBLEUUID descriptorUUID); - NimBLEUUID getUUID(); - std::string getValue(); - uint8_t* getData(); - void indicate(); - void notify(bool is_notification = true); - void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks); + NimBLEDescriptor* getDescriptorByUUID(const char* descriptorUUID); + NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &descriptorUUID); + NimBLEUUID getUUID(); + std::string getValue(); + uint8_t* getData(); + size_t getDataLength(); + + void indicate(); + void notify(bool is_notification = true); + void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks); // Backward Compatibility - to be removed void setBroadcastProperty(bool value); - void setIndicateProperty(bool value); - void setNotifyProperty(bool value); - void setReadProperty(bool value); + void setIndicateProperty(bool value); + void setNotifyProperty(bool value); + void setReadProperty(bool value); void setWriteProperty(bool value); - void setWriteNoResponseProperty(bool value); -////////////////////////////////////////////////////// - void setValue(uint8_t* data, size_t size); - void setValue(std::string value); - void setValue(uint16_t& data16); - void setValue(uint32_t& data32); - void setValue(int& data32); - void setValue(float& data32); - void setValue(double& data64); + void setWriteNoResponseProperty(bool value); +////////////////////////////////////////////////////// + void setValue(const uint8_t* data, size_t size); + void setValue(const std::string &value); + void setValue(uint16_t& data16); + void setValue(uint32_t& data32); + void setValue(int& data32); + void setValue(float& data32); + void setValue(double& data64); - std::string toString(); - uint16_t getHandle(); -// void setAccessPermissions(uint16_t perm); + std::string toString(); + uint16_t getHandle(); +// void setAccessPermissions(uint16_t perm); // Backward Compatibility - to be removed -/* static const uint32_t PROPERTY_READ = 1<<0; - static const uint32_t PROPERTY_WRITE = 1<<1; - static const uint32_t PROPERTY_NOTIFY = 1<<2; - static const uint32_t PROPERTY_BROADCAST = 1<<3; - static const uint32_t PROPERTY_INDICATE = 1<<4; - static const uint32_t PROPERTY_WRITE_NR = 1<<5; +/* static const uint32_t PROPERTY_READ = 1<<0; + static const uint32_t PROPERTY_WRITE = 1<<1; + static const uint32_t PROPERTY_NOTIFY = 1<<2; + static const uint32_t PROPERTY_BROADCAST = 1<<3; + static const uint32_t PROPERTY_INDICATE = 1<<4; + static const uint32_t PROPERTY_WRITE_NR = 1<<5; */ ////////////////////////////////////////////////////// - + private: - friend class NimBLEServer; - friend class NimBLEService; -// friend class NimBLEDescriptor; -// friend class NimBLECharacteristicMap; + friend class NimBLEServer; + friend class NimBLEService; +// friend class NimBLEDescriptor; +// friend class NimBLECharacteristicMap; - NimBLECharacteristic(const char* uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE, - NimBLEService* pService = nullptr); - NimBLECharacteristic(NimBLEUUID uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE, - NimBLEService* pService = nullptr); - virtual ~NimBLECharacteristic(); + NimBLECharacteristic(const char* uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + virtual ~NimBLECharacteristic(); - NimBLEUUID m_uuid; - NimBLEDescriptorMap m_descriptorMap; - uint16_t m_handle; - uint16_t m_properties; - NimBLECharacteristicCallbacks* m_pCallbacks; - NimBLEService* m_pService; - NimBLEValue m_value; -// uint16_t m_permissions; - - void addDescriptor(NimBLEDescriptor* pDescriptor); + NimBLEUUID m_uuid; + NimBLEDescriptorMap m_descriptorMap; + uint16_t m_handle; + uint16_t m_properties; + NimBLECharacteristicCallbacks* m_pCallbacks; + NimBLEService* m_pService; + NimBLEValue m_value; +// uint16_t m_permissions; + + void addDescriptor(NimBLEDescriptor* pDescriptor); NimBLEService* getService(); uint8_t getProperties(); void setSubscribe(struct ble_gap_event *event); - static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, + static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); - FreeRTOS::Semaphore m_semaphoreConfEvt = FreeRTOS::Semaphore("ConfEvt"); + FreeRTOS::Semaphore m_semaphoreConfEvt = FreeRTOS::Semaphore("ConfEvt"); }; // NimBLECharacteristic @@ -174,21 +178,23 @@ private: class NimBLECharacteristicCallbacks { public: typedef enum { - SUCCESS_INDICATE, - SUCCESS_NOTIFY, - ERROR_INDICATE_DISABLED, - ERROR_NOTIFY_DISABLED, - ERROR_GATT, - ERROR_NO_CLIENT, - ERROR_INDICATE_TIMEOUT, - ERROR_INDICATE_FAILURE - }Status; - - virtual ~NimBLECharacteristicCallbacks(); - virtual void onRead(NimBLECharacteristic* pCharacteristic); - virtual void onWrite(NimBLECharacteristic* pCharacteristic); + SUCCESS_INDICATE, + SUCCESS_NOTIFY, + ERROR_INDICATE_DISABLED, + ERROR_NOTIFY_DISABLED, + ERROR_GATT, + ERROR_NO_CLIENT, + ERROR_INDICATE_TIMEOUT, + ERROR_INDICATE_FAILURE + }Status; + + virtual ~NimBLECharacteristicCallbacks(); + virtual void onRead(NimBLECharacteristic* pCharacteristic); + virtual void onWrite(NimBLECharacteristic* pCharacteristic); virtual void onNotify(NimBLECharacteristic* pCharacteristic); - virtual void onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code); + virtual void onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code); }; + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif /* CONFIG_BT_ENABLED */ -#endif /*MAIN_NIMBLECHARACTERISTIC_H_*/ \ No newline at end of file +#endif /*MAIN_NIMBLECHARACTERISTIC_H_*/ diff --git a/libesp32/NimBLE-Arduino/src/NimBLECharacteristicMap.cpp b/libesp32/NimBLE-Arduino/src/NimBLECharacteristicMap.cpp index 9ee741bc0..b3cdcf9c6 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLECharacteristicMap.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLECharacteristicMap.cpp @@ -12,6 +12,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLEService.h" #include "NimBLELog.h" @@ -20,9 +23,9 @@ * @brief Return the characteristic by handle. * @param [in] handle The handle to look up the characteristic. * @return The characteristic. - */ + */ NimBLECharacteristic* NimBLECharacteristicMap::getByHandle(uint16_t handle) { - return m_handleMap.at(handle); + return m_handleMap.at(handle); } // getByHandle @@ -41,21 +44,21 @@ NimBLECharacteristic* NimBLECharacteristicMap::getByUUID(const char* uuid) { * @param [in] UUID The UUID to look up the characteristic. * @return The characteristic. */ -NimBLECharacteristic* NimBLECharacteristicMap::getByUUID(NimBLEUUID uuid) { - for (auto &myPair : m_uuidMap) { - if (myPair.first->getUUID().equals(uuid)) { - return myPair.first; - } - } +NimBLECharacteristic* NimBLECharacteristicMap::getByUUID(const NimBLEUUID &uuid) { + for (auto &myPair : m_uuidMap) { + if (myPair.first->getUUID().equals(uuid)) { + return myPair.first; + } + } - return nullptr; + return nullptr; } // getByUUID /** * @brief Get the number of characteristics in the map. */ uint8_t NimBLECharacteristicMap::getSize() { - return (uint8_t)m_uuidMap.size(); + return (uint8_t)m_uuidMap.size(); } // getSize /** @@ -63,11 +66,11 @@ uint8_t NimBLECharacteristicMap::getSize() { * @return The first characteristic in the map. */ NimBLECharacteristic* NimBLECharacteristicMap::getFirst() { - m_iterator = m_uuidMap.begin(); - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLECharacteristic* pRet = m_iterator->first; - m_iterator++; - return pRet; + m_iterator = m_uuidMap.begin(); + if (m_iterator == m_uuidMap.end()) return nullptr; + NimBLECharacteristic* pRet = m_iterator->first; + m_iterator++; + return pRet; } // getFirst @@ -76,10 +79,10 @@ NimBLECharacteristic* NimBLECharacteristicMap::getFirst() { * @return The next characteristic in the map. */ NimBLECharacteristic* NimBLECharacteristicMap::getNext() { - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLECharacteristic* pRet = m_iterator->first; - m_iterator++; - return pRet; + if (m_iterator == m_uuidMap.end()) return nullptr; + NimBLECharacteristic* pRet = m_iterator->first; + m_iterator++; + return pRet; } // getNext @@ -90,7 +93,7 @@ NimBLECharacteristic* NimBLECharacteristicMap::getNext() { * @return N/A. */ void NimBLECharacteristicMap::setByHandle(uint16_t handle, NimBLECharacteristic* characteristic) { - m_handleMap.insert(std::pair(handle, characteristic)); + m_handleMap.insert(std::pair(handle, characteristic)); } // setByHandle @@ -100,8 +103,8 @@ void NimBLECharacteristicMap::setByHandle(uint16_t handle, NimBLECharacteristic* * @param [in] characteristic The characteristic to cache. * @return N/A. */ -void NimBLECharacteristicMap::setByUUID(NimBLECharacteristic* pCharacteristic, NimBLEUUID uuid) { - m_uuidMap.insert(std::pair(pCharacteristic, uuid.toString())); +void NimBLECharacteristicMap::setByUUID(NimBLECharacteristic* pCharacteristic, const NimBLEUUID &uuid) { + m_uuidMap.insert(std::pair(pCharacteristic, uuid.toString())); } // setByUUID @@ -110,19 +113,20 @@ void NimBLECharacteristicMap::setByUUID(NimBLECharacteristic* pCharacteristic, N * @return A string representation of the characteristic map. */ std::string NimBLECharacteristicMap::toString() { - std::string res; - int count = 0; - char hex[5]; - for (auto &myPair: m_uuidMap) { - if (count > 0) {res += "\n";} - snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle()); - count++; - res += "handle: 0x"; - res += hex; - res += ", uuid: " + myPair.first->getUUID().toString(); - } - return res; + std::string res; + int count = 0; + char hex[5]; + for (auto &myPair: m_uuidMap) { + if (count > 0) {res += "\n";} + snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle()); + count++; + res += "handle: 0x"; + res += hex; + res += ", uuid: " + myPair.first->getUUID().toString(); + } + return res; } // toString -#endif /* CONFIG_BT_ENABLED */ \ No newline at end of file +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp b/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp index 3930acf88..a385126d2 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp @@ -3,17 +3,20 @@ * * Created: on Jan 26 2020 * Author H2zero - * + * * Originally: * BLEClient.cpp * * Created on: Mar 22, 2017 * Author: kolban */ - + #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + #include "NimBLEClient.h" #include "NimBLEUtils.h" #include "NimBLEDevice.h" @@ -40,8 +43,8 @@ static NimBLEClientCallbacks defaultCallbacks; * Since there is a hierarchical relationship here, we will have the idea that from a NimBLERemoteService will own * zero or more remote characteristics and a NimBLERemoteCharacteristic will own zero or more remote NimBLEDescriptors. * - * We will assume that a NimBLERemoteService contains a map that maps NimBLEUUIDs to the set of owned characteristics - * and that a NimBLECharacteristic contains a map that maps NimBLEUUIDs to the set of owned descriptors. + * We will assume that a NimBLERemoteService contains a vector of owned characteristics + * and that a NimBLECharacteristic contains a vector of owned descriptors. * * */ @@ -50,18 +53,17 @@ NimBLEClient::NimBLEClient() { m_pClientCallbacks = &defaultCallbacks; m_conn_id = BLE_HS_CONN_HANDLE_NONE; - m_haveServices = false; m_isConnected = false; - m_connectTimeout = 30000; - - m_pConnParams.scan_itvl = 16; // Scan interval in 0.625ms units (NimBLE Default) + m_connectTimeout = 30000; + + m_pConnParams.scan_itvl = 16; // Scan interval in 0.625ms units (NimBLE Default) m_pConnParams.scan_window = 16; // Scan window in 0.625ms units (NimBLE Default) - m_pConnParams.itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN; // min_int = 0x10*1.25ms = 20ms - m_pConnParams.itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX; // max_int = 0x20*1.25ms = 40ms - m_pConnParams.latency = BLE_GAP_INITIAL_CONN_LATENCY; // number of packets allowed to skip (extends max interval) - m_pConnParams.supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT; // timeout = 400*10ms = 4000ms + m_pConnParams.itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN; // min_int = 0x10*1.25ms = 20ms + m_pConnParams.itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX; // max_int = 0x20*1.25ms = 40ms + m_pConnParams.latency = BLE_GAP_INITIAL_CONN_LATENCY; // number of packets allowed to skip (extends max interval) + m_pConnParams.supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT; // timeout = 400*10ms = 4000ms m_pConnParams.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; // Minimum length of connection event in 0.625ms units - m_pConnParams.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; // Maximum length of connection event in 0.625ms units + m_pConnParams.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; // Maximum length of connection event in 0.625ms units } // NimBLEClient @@ -69,12 +71,12 @@ NimBLEClient::NimBLEClient() * @brief Destructor, private - only callable by NimBLEDevice::deleteClient * to ensure proper disconnect and removal from device list. */ -NimBLEClient::~NimBLEClient() { - // We may have allocated service references associated with this client. +NimBLEClient::~NimBLEClient() { + // We may have allocated service references associated with this client. // Before we are finished with the client, we must release resources. clearServices(); - - if(m_deleteCallbacks) { + + if(m_deleteCallbacks && m_pClientCallbacks != &defaultCallbacks) { delete m_pClientCallbacks; } @@ -87,11 +89,11 @@ NimBLEClient::~NimBLEClient() { void NimBLEClient::clearServices() { NIMBLE_LOGD(LOG_TAG, ">> clearServices"); // Delete all the services. - for (auto &myPair : m_servicesMap) { - delete myPair.second; + for(auto &it: m_servicesVector) { + delete it; } - m_servicesMap.clear(); - m_haveServices = false; + m_servicesVector.clear(); + NIMBLE_LOGD(LOG_TAG, "<< clearServices"); } // clearServices @@ -101,10 +103,10 @@ void NimBLEClient::clearServices() { */ /* void NimBLEClient::onHostReset() { - + } - */ - + */ + /** * Add overloaded function to ease connect to peer device with not public address */ @@ -120,14 +122,14 @@ bool NimBLEClient::connect(NimBLEAdvertisedDevice* device, bool refreshServices) * @param [in] address The address of the partner. * @return True on success. */ -bool NimBLEClient::connect(NimBLEAddress address, uint8_t type, bool refreshServices) { +bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refreshServices) { NIMBLE_LOGD(LOG_TAG, ">> connect(%s)", address.toString().c_str()); - + if(!NimBLEDevice::m_synced) { NIMBLE_LOGC(LOG_TAG, "Host reset, wait for sync."); return false; } - + if(ble_gap_conn_active()) { NIMBLE_LOGE(LOG_TAG, "Connection in progress - must wait."); return false; @@ -135,15 +137,15 @@ bool NimBLEClient::connect(NimBLEAddress address, uint8_t type, bool refreshServ int rc = 0; m_peerAddress = address; - + ble_addr_t peerAddrt; memcpy(&peerAddrt.val, address.getNative(),6); peerAddrt.type = type; - + m_semaphoreOpenEvt.take("connect"); - + /** Try to connect the the advertiser. Allow 30 seconds (30000 ms) for - * timeout (default value of m_connectTimeout). + * timeout (default value of m_connectTimeout). * Loop on BLE_HS_EBUSY if the scan hasn't stopped yet. */ do{ @@ -153,21 +155,21 @@ bool NimBLEClient::connect(NimBLEAddress address, uint8_t type, bool refreshServ vTaskDelay(1); } }while(rc == BLE_HS_EBUSY); - + if (rc != 0 && rc != BLE_HS_EDONE) { NIMBLE_LOGE(LOG_TAG, "Error: Failed to connect to device; addr_type=%d " "addr=%s, rc=%d; %s", - type, + type, m_peerAddress.toString().c_str(), rc, NimBLEUtils::returnCodeToString(rc)); - + m_semaphoreOpenEvt.give(); m_waitingToConnect = false; return false; } - + m_waitingToConnect = true; - + rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete. if(rc != 0){ @@ -178,21 +180,9 @@ bool NimBLEClient::connect(NimBLEAddress address, uint8_t type, bool refreshServ NIMBLE_LOGD(LOG_TAG, "Refreshing Services for: (%s)", address.toString().c_str()); clearServices(); } - - if (!m_haveServices) { - if (!retrieveServices()) { - // error getting services, make sure we disconnect and release any resources before returning - disconnect(); - clearServices(); - return false; - } - else{ - NIMBLE_LOGD(LOG_TAG, "Found %d services", getServices()->size()); - } - } - m_pClientCallbacks->onConnect(this); - + m_pClientCallbacks->onConnect(this); + NIMBLE_LOGD(LOG_TAG, "<< connect()"); return true; } // connect @@ -204,23 +194,23 @@ bool NimBLEClient::connect(NimBLEAddress address, uint8_t type, bool refreshServ * @return True on success. */ bool NimBLEClient::secureConnection() { - + m_semeaphoreSecEvt.take("secureConnection"); - + int rc = NimBLEDevice::startSecurity(m_conn_id); if(rc != 0){ m_semeaphoreSecEvt.give(); return false; } - + rc = m_semeaphoreSecEvt.wait("secureConnection"); if(rc != 0){ return false; } - + return true; } - + /** * @brief Disconnect from the peer. @@ -240,7 +230,7 @@ int NimBLEClient::disconnect(uint8_t reason) { // the device can be found again. NimBLEDevice::removeIgnored(m_peerAddress); } - + NIMBLE_LOGD(LOG_TAG, "<< disconnect()"); return rc; } // disconnect @@ -250,23 +240,23 @@ int NimBLEClient::disconnect(uint8_t reason) { * @brief Set the connection paramaters to use when connecting to a server. */ void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterval, - uint16_t latency, uint16_t timeout, + uint16_t latency, uint16_t timeout, uint16_t scanInterval, uint16_t scanWindow)/*, uint16_t minConnTime, uint16_t maxConnTime)*/ { - m_pConnParams.scan_itvl = scanInterval; // Scan interval in 0.625ms units + m_pConnParams.scan_itvl = scanInterval; // Scan interval in 0.625ms units m_pConnParams.scan_window = scanWindow; // Scan window in 0.625ms units - m_pConnParams.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms - m_pConnParams.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms - m_pConnParams.latency = latency; // number of packets allowed to skip (extends max interval) - m_pConnParams.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms - - // These are not used by NimBLE at this time - Must leave at defaults + m_pConnParams.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms + m_pConnParams.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms + m_pConnParams.latency = latency; // number of packets allowed to skip (extends max interval) + m_pConnParams.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms + + // These are not used by NimBLE at this time - Must leave at defaults //m_pConnParams->min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units - //m_pConnParams->max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units - - int rc = NimBLEUtils::checkConnParams(&m_pConnParams); + //m_pConnParams->max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units + + int rc = NimBLEUtils::checkConnParams(&m_pConnParams); assert(rc == 0 && "Invalid Connection parameters"); } @@ -274,24 +264,24 @@ void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterva /** * Update connection parameters can be called only after connection has been established */ -void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval, +void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout) -{ - ble_gap_upd_params params; +{ + ble_gap_upd_params params; - params.latency = latency; - params.itvl_max = maxInterval; - params.itvl_min = minInterval; - params.supervision_timeout = timeout; - // These are not used by NimBLE at this time - Must leave at defaults + params.latency = latency; + params.itvl_max = maxInterval; + params.itvl_min = minInterval; + params.supervision_timeout = timeout; + // These are not used by NimBLE at this time - Must leave at defaults params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; - + int rc = ble_gap_update_params(m_conn_id, ¶ms); if(rc != 0) { NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); - } + } } @@ -331,19 +321,37 @@ int NimBLEClient::getRssi() { NIMBLE_LOGE(LOG_TAG, "<< getRssi(): Not connected"); return 0; } - + int8_t rssiValue = 0; int rc = ble_gap_conn_rssi(m_conn_id, &rssiValue); if(rc != 0) { - NIMBLE_LOGE(LOG_TAG, "Failed to read RSSI error code: %d, %s", + NIMBLE_LOGE(LOG_TAG, "Failed to read RSSI error code: %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); return 0; } - + return rssiValue; } // getRssi +/** + * @brief Get iterator to the beginning of the vector of remote service pointers. + * @return An iterator to the beginning of the vector of remote service pointers. + */ +std::vector::iterator NimBLEClient::begin() { + return m_servicesVector.begin(); +} + + +/** + * @brief Get iterator to the end of the vector of remote service pointers. + * @return An iterator to the end of the vector of remote service pointers. + */ +std::vector::iterator NimBLEClient::end() { + return m_servicesVector.end(); +} + + /** * @brief Get the service BLE Remote Service instance corresponding to the uuid. * @param [in] uuid The UUID of the service being sought. @@ -359,29 +367,62 @@ NimBLERemoteService* NimBLEClient::getService(const char* uuid) { * @param [in] uuid The UUID of the service being sought. * @return A reference to the Service or nullptr if don't know about it. */ -NimBLERemoteService* NimBLEClient::getService(NimBLEUUID uuid) { +NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) { NIMBLE_LOGD(LOG_TAG, ">> getService: uuid: %s", uuid.toString().c_str()); - if (!m_haveServices) { - return nullptr; - } - std::string uuidStr = uuid.toString(); - for (auto &myPair : m_servicesMap) { - if (myPair.first == uuidStr) { + for(auto &it: m_servicesVector) { + if(it->getUUID() == uuid) { NIMBLE_LOGD(LOG_TAG, "<< getService: found the service with uuid: %s", uuid.toString().c_str()); - return myPair.second; + return it; } - } + } + + size_t prev_size = m_servicesVector.size(); + if(retrieveServices(&uuid)) { + if(m_servicesVector.size() > prev_size) { + return m_servicesVector.back(); + } + } + NIMBLE_LOGD(LOG_TAG, "<< getService: not found"); return nullptr; } // getService /** - * @Get a pointer to the map of found services. - */ -std::map* NimBLEClient::getServices() { - return &m_servicesMap; + * @Get a pointer to the vector of found services. + * @param [in] bool value to indicate if the current vector should be cleared and + * subsequently all services retrieved from the peripheral. + * If false the vector will be returned with the currently stored services, + * if vector is empty it will retrieve all services from the peripheral. + * @return a pointer to the vector of available services. + */ +std::vector* NimBLEClient::getServices(bool refresh) { + if(refresh) { + clearServices(); + } + + if(m_servicesVector.empty()) { + if (!retrieveServices()) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to get services"); + } + else{ + NIMBLE_LOGI(LOG_TAG, "Found %d services", m_servicesVector.size()); + } + } + return &m_servicesVector; +} + + +/** + * @ Retrieves the full database of attributes that the peripheral has available. + */ +void NimBLEClient::discoverAttributes() { + for(auto svc: *getServices(true)) { + for(auto chr: *svc->getCharacteristics(true)) { + chr->getDescriptors(true); + } + } } @@ -391,44 +432,40 @@ std::map* NimBLEClient::getServices() { * services and wait until we have received them all. * We then ask for the characteristics for each service found and their desciptors. * @return true on success otherwise false if an error occurred - */ -bool NimBLEClient::retrieveServices() { + */ +bool NimBLEClient::retrieveServices(const NimBLEUUID *uuid_filter) { /** * Design * ------ * We invoke ble_gattc_disc_all_svcs. This will request a list of the services exposed by the * peer BLE partner to be returned in the callback function provided. */ - + NIMBLE_LOGD(LOG_TAG, ">> retrieveServices"); - + int rc = 0; + if(!m_isConnected){ NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve services -aborting"); return false; } m_semaphoreSearchCmplEvt.take("retrieveServices"); - - int rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, this); - + + if(uuid_filter == nullptr) { + rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, this); + } else { + rc = ble_gattc_disc_svc_by_uuid(m_conn_id, &uuid_filter->getNative()->u, + NimBLEClient::serviceDiscoveredCB, this); + } + if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_svcs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); - m_haveServices = false; m_semaphoreSearchCmplEvt.give(); return false; } - + // wait until we have all the services - // If sucessful, remember that we now have services. - m_haveServices = (m_semaphoreSearchCmplEvt.wait("retrieveServices") == 0); - if(m_haveServices){ - for (auto &myPair : m_servicesMap) { - if(!m_isConnected || !myPair.second->retrieveCharacteristics()) { - NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve characteristics -aborting"); - return false; - } - } - + if(m_semaphoreSearchCmplEvt.wait("retrieveServices") == 0){ NIMBLE_LOGD(LOG_TAG, "<< retrieveServices"); return true; } @@ -440,16 +477,18 @@ bool NimBLEClient::retrieveServices() { /** - * @brief STATIC Callback for the service discovery API function. + * @brief STATIC Callback for the service discovery API function. * When a service is found or there is none left or there was an error * the API will call this and report findings. */ int NimBLEClient::serviceDiscoveredCB( - uint16_t conn_handle, + uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_svc *service, void *arg) + const struct ble_gatt_svc *service, void *arg) { - NIMBLE_LOGD(LOG_TAG,"Service Discovered >> status: %d handle: %d", error->status, conn_handle); + NIMBLE_LOGD(LOG_TAG,"Service Discovered >> status: %d handle: %d", + error->status, (error->status == 0) ? service->start_handle : -1); + NimBLEClient *peer = (NimBLEClient*)arg; int rc=0; @@ -460,13 +499,13 @@ int NimBLEClient::serviceDiscoveredCB( switch (error->status) { case 0: { - // Found a service - add it to the map + // Found a service - add it to the vector NimBLERemoteService* pRemoteService = new NimBLERemoteService(peer, service); - peer->m_servicesMap.insert(std::pair(pRemoteService->getUUID().toString(), pRemoteService)); + peer->m_servicesVector.push_back(pRemoteService); break; } case BLE_HS_EDONE:{ - // All services discovered; start discovering characteristics. + // All services discovered; start discovering characteristics. //NIMBLE_LOGD(LOG_TAG,"Giving search semaphore - completed"); peer->m_semaphoreSearchCmplEvt.give(0); @@ -481,7 +520,7 @@ int NimBLEClient::serviceDiscoveredCB( if (rc != 0) { // pass non-zero to semaphore on error to indicate an error finding services - peer->m_semaphoreSearchCmplEvt.give(1); + peer->m_semaphoreSearchCmplEvt.give(1); } NIMBLE_LOGD(LOG_TAG,"<< Service Discovered. status: %d", rc); return rc; @@ -494,12 +533,13 @@ int NimBLEClient::serviceDiscoveredCB( * @param [in] characteristicUUID The characteristic whose value we wish to read. * @returns characteristic value or an empty string if not found */ -std::string NimBLEClient::getValue(NimBLEUUID serviceUUID, NimBLEUUID characteristicUUID) { - NIMBLE_LOGD(LOG_TAG, ">> getValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); - +std::string NimBLEClient::getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID) { + NIMBLE_LOGD(LOG_TAG, ">> getValue: serviceUUID: %s, characteristicUUID: %s", + serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); + std::string ret = ""; NimBLERemoteService* pService = getService(serviceUUID); - + if(pService != nullptr) { NimBLERemoteCharacteristic* pChar = pService->getCharacteristic(characteristicUUID); if(pChar != nullptr) { @@ -518,19 +558,22 @@ std::string NimBLEClient::getValue(NimBLEUUID serviceUUID, NimBLEUUID characteri * @param [in] characteristicUUID The characteristic whose value we wish to write. * @returns true if successful otherwise false */ -bool NimBLEClient::setValue(NimBLEUUID serviceUUID, NimBLEUUID characteristicUUID, std::string value) { - NIMBLE_LOGD(LOG_TAG, ">> setValue: serviceUUID: %s, characteristicUUID: %s", serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); - +bool NimBLEClient::setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID, + const std::string &value) +{ + NIMBLE_LOGD(LOG_TAG, ">> setValue: serviceUUID: %s, characteristicUUID: %s", + serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); + bool ret = false; NimBLERemoteService* pService = getService(serviceUUID); - + if(pService != nullptr) { NimBLERemoteCharacteristic* pChar = pService->getCharacteristic(characteristicUUID); if(pChar != nullptr) { ret = pChar->writeValue(value); } } - + NIMBLE_LOGD(LOG_TAG, "<< setValue"); return ret; } // setValue @@ -552,8 +595,8 @@ uint16_t NimBLEClient::getMTU() { * @param [in] arg = pointer to the client instance */ /*STATIC*/ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) { - - NimBLEClient* client = (NimBLEClient*)arg; + + NimBLEClient* client = (NimBLEClient*)arg; //struct ble_gap_conn_desc desc; //struct ble_hs_adv_fields fields; int rc; @@ -566,22 +609,22 @@ uint16_t NimBLEClient::getMTU() { case BLE_GAP_EVENT_DISCONNECT: { if(!client->m_isConnected) return 0; - + if(client->m_conn_id != event->disconnect.conn.conn_handle) return 0; - + client->m_isConnected = false; client->m_waitingToConnect=false; // Remove the device from ignore list so we will scan it again NimBLEDevice::removeIgnored(client->m_peerAddress); - + NIMBLE_LOGI(LOG_TAG, "disconnect; reason=%d, %s", event->disconnect.reason, NimBLEUtils::returnCodeToString(event->disconnect.reason)); //print_conn_desc(&event->disconnect.conn); //MODLOG_DFLT(INFO, "\n"); - - // If Host reset tell the device now before returning to prevent + + // If Host reset tell the device now before returning to prevent // any errors caused by calling host functions before resyncing. switch(event->disconnect.reason) { case BLE_HS_ETIMEOUT_HCI: @@ -591,19 +634,19 @@ uint16_t NimBLEClient::getMTU() { NIMBLE_LOGC(LOG_TAG, "Disconnect - host reset, rc=%d", event->disconnect.reason); NimBLEDevice::onReset(event->disconnect.reason); break; - default: + default: break; } - + //client->m_conn_id = BLE_HS_CONN_HANDLE_NONE; - - // Indicate a non-success return value to any semaphores waiting + + // Indicate a non-success return value to any semaphores waiting client->m_semaphoreOpenEvt.give(1); client->m_semaphoreSearchCmplEvt.give(1); client->m_semeaphoreSecEvt.give(1); - + client->m_pClientCallbacks->onDisconnect(client); - + return 0; } // BLE_GAP_EVENT_DISCONNECT @@ -611,26 +654,26 @@ uint16_t NimBLEClient::getMTU() { if(!client->m_waitingToConnect) return 0; - + //if(client->m_conn_id != BLE_HS_CONN_HANDLE_NONE) // return 0; - + client->m_waitingToConnect=false; - + if (event->connect.status == 0) { client->m_isConnected = true; - + NIMBLE_LOGD(LOG_TAG, "Connection established"); - + client->m_conn_id = event->connect.conn_handle; - + // rc = ble_gap_conn_find(event->connect.conn_handle, &desc); // assert(rc == 0); // print_conn_desc(&desc); // MODLOG_DFLT(INFO, "\n"); - - // In the case of a multiconnecting device we ignore this device when + + // In the case of a multiconnecting device we ignore this device when // scanning since we are already connected to it NimBLEDevice::addIgnored(client->m_peerAddress); @@ -638,9 +681,9 @@ uint16_t NimBLEClient::getMTU() { if(rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gattc_exchange_mtu: rc=%d %s",rc, NimBLEUtils::returnCodeToString(rc)); - // if error getting mtu indicate a connection error. + // if error getting mtu indicate a connection error. client->m_semaphoreOpenEvt.give(rc); - } + } } else { // Connection attempt failed NIMBLE_LOGE(LOG_TAG, "Error: Connection failed; status=%d %s", @@ -654,35 +697,45 @@ uint16_t NimBLEClient::getMTU() { case BLE_GAP_EVENT_NOTIFY_RX: { if(client->m_conn_id != event->notify_rx.conn_handle) return 0; - + NIMBLE_LOGD(LOG_TAG, "Notify Recieved for handle: %d",event->notify_rx.attr_handle); - if(!client->m_haveServices) - return 0; - - for(auto &sPair : client->m_servicesMap){ + + for(auto &it: client->m_servicesVector) { // Dont waste cycles searching services without this handle in their range - if(sPair.second->getEndHandle() < event->notify_rx.attr_handle) { + if(it->getEndHandle() < event->notify_rx.attr_handle) { continue; } - auto cMap = sPair.second->getCharacteristicsByHandle(); - NIMBLE_LOGD(LOG_TAG, "checking service %s for handle: %d", sPair.second->getUUID().toString().c_str(),event->notify_rx.attr_handle); - auto characteristic = cMap->find(event->notify_rx.attr_handle); - if(characteristic != cMap->end()) { - NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", characteristic->second->toString().c_str()); - - if (characteristic->second->m_notifyCallback != nullptr) { - NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s", characteristic->second->toString().c_str()); - characteristic->second->m_notifyCallback(characteristic->second, event->notify_rx.om->om_data, event->notify_rx.om->om_len, !event->notify_rx.indication); + + auto cVector = &it->m_characteristicVector; + NIMBLE_LOGD(LOG_TAG, "checking service %s for handle: %d", + it->getUUID().toString().c_str(), + event->notify_rx.attr_handle); + + auto characteristic = cVector->cbegin(); + for(; characteristic != cVector->cend(); ++characteristic) { + if((*characteristic)->m_handle == event->notify_rx.attr_handle) + break; + } + + if(characteristic != cVector->cend()) { + NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", (*characteristic)->toString().c_str()); + + if ((*characteristic)->m_notifyCallback != nullptr) { + NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s", + (*characteristic)->toString().c_str()); + (*characteristic)->m_notifyCallback(*characteristic, event->notify_rx.om->om_data, + event->notify_rx.om->om_len, + !event->notify_rx.indication); } - + break; } } - + return 0; } // BLE_GAP_EVENT_NOTIFY_RX - - case BLE_GAP_EVENT_CONN_UPDATE_REQ: + + case BLE_GAP_EVENT_CONN_UPDATE_REQ: case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: { if(client->m_conn_id != event->conn_update_req.conn_handle){ return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE @@ -696,7 +749,7 @@ uint16_t NimBLEClient::getMTU() { rc = client->m_pClientCallbacks->onConnParamsUpdateRequest(client, event->conn_update_req.peer_params) ? 0 : BLE_ERR_CONN_PARMS; - + if(!rc && event->type == BLE_GAP_EVENT_CONN_UPDATE_REQ ) { event->conn_update_req.self_params->itvl_min = client->m_pConnParams.itvl_min; @@ -708,7 +761,7 @@ uint16_t NimBLEClient::getMTU() { NIMBLE_LOGD(LOG_TAG, "%s peer params", (rc == 0) ? "Accepted" : "Rejected"); return rc; } // BLE_GAP_EVENT_CONN_UPDATE_REQ, BLE_GAP_EVENT_L2CAP_UPDATE_REQ - + case BLE_GAP_EVENT_CONN_UPDATE: { if(client->m_conn_id != event->conn_update.conn_handle){ return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE @@ -720,28 +773,28 @@ uint16_t NimBLEClient::getMTU() { } return 0; } // BLE_GAP_EVENT_CONN_UPDATE - + case BLE_GAP_EVENT_ENC_CHANGE: { if(client->m_conn_id != event->enc_change.conn_handle){ return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE } - + if(event->enc_change.status == 0) { struct ble_gap_conn_desc desc; rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); assert(rc == 0); - + if(NimBLEDevice::m_securityCallbacks != nullptr) { NimBLEDevice::m_securityCallbacks->onAuthenticationComplete(&desc); } else { client->m_pClientCallbacks->onAuthenticationComplete(&desc); } } - + client->m_semeaphoreSecEvt.give(event->enc_change.status); return 0; } //BLE_GAP_EVENT_ENC_CHANGE - + case BLE_GAP_EVENT_MTU: { if(client->m_conn_id != event->mtu.conn_handle){ return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE @@ -749,15 +802,14 @@ uint16_t NimBLEClient::getMTU() { NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d", event->mtu.conn_handle, event->mtu.value); - client->m_semaphoreOpenEvt.give(0); - //client->m_mtu = event->mtu.value; + client->m_semaphoreOpenEvt.give(0); return 0; } // BLE_GAP_EVENT_MTU - + case BLE_GAP_EVENT_PASSKEY_ACTION: { struct ble_sm_io pkey = {0}; - - if(client->m_conn_id != event->passkey.conn_handle) + + if(client->m_conn_id != event->passkey.conn_handle) return 0; if (event->passkey.params.action == BLE_SM_IOACT_DISP) { @@ -765,7 +817,7 @@ uint16_t NimBLEClient::getMTU() { pkey.passkey = NimBLEDevice::m_passkey; // This is the passkey to be entered on peer rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); - + } else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %d", event->passkey.params.numcmp); pkey.action = event->passkey.params.action; @@ -779,8 +831,8 @@ uint16_t NimBLEClient::getMTU() { rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); - - //TODO: Handle out of band pairing + + //TODO: Handle out of band pairing } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) { static uint8_t tem_oob[16] = {0}; pkey.action = event->passkey.params.action; @@ -789,11 +841,11 @@ uint16_t NimBLEClient::getMTU() { } rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); - //////// + //////// } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) { NIMBLE_LOGD(LOG_TAG, "Enter the passkey"); pkey.action = event->passkey.params.action; - + // Compatibility only - Do not use, should be removed the in future if(NimBLEDevice::m_securityCallbacks != nullptr) { pkey.passkey = NimBLEDevice::m_securityCallbacks->onPassKeyRequest(); @@ -804,14 +856,14 @@ uint16_t NimBLEClient::getMTU() { rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); - + } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { NIMBLE_LOGD(LOG_TAG, "No passkey action required"); } return 0; } // BLE_GAP_EVENT_PASSKEY_ACTION - + default: { return 0; } @@ -833,10 +885,10 @@ bool NimBLEClient::isConnected() { */ void NimBLEClient::setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, bool deleteCallbacks) { if (pClientCallbacks != nullptr){ - m_pClientCallbacks = pClientCallbacks; - } else { - m_pClientCallbacks = &defaultCallbacks; - } + m_pClientCallbacks = pClientCallbacks; + } else { + m_pClientCallbacks = &defaultCallbacks; + } m_deleteCallbacks = deleteCallbacks; } // setClientCallbacks @@ -848,8 +900,9 @@ void NimBLEClient::setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, b std::string NimBLEClient::toString() { std::string res = "peer address: " + m_peerAddress.toString(); res += "\nServices:\n"; - for (auto &myPair : m_servicesMap) { - res += myPair.second->toString() + "\n"; + + for(auto &it: m_servicesVector) { + res += it->toString() + "\n"; } return res; @@ -865,7 +918,7 @@ void NimBLEClientCallbacks::onDisconnect(NimBLEClient* pClient) { } bool NimBLEClientCallbacks::onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) { - NIMBLE_LOGD("NimBLEClientCallbacks", "onConnParamsUpdateRequest: default"); + NIMBLE_LOGD("NimBLEClientCallbacks", "onConnParamsUpdateRequest: default"); return true; } @@ -890,4 +943,5 @@ bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){ return true; } +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEClient.h b/libesp32/NimBLE-Arduino/src/NimBLEClient.h index 3d3613c0f..4bf2c33d2 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEClient.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEClient.h @@ -3,7 +3,7 @@ * * Created: on Jan 26 2020 * Author H2zero - * + * * Originally: * BLEClient.h * @@ -14,16 +14,24 @@ #ifndef MAIN_NIMBLECLIENT_H_ #define MAIN_NIMBLECLIENT_H_ -#if defined(CONFIG_BT_ENABLED) #include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) #include "NimBLEAddress.h" #include "NimBLEAdvertisedDevice.h" #include "NimBLERemoteService.h" -#include +#include #include +typedef struct { + const NimBLEUUID *uuid; + const void *attribute; +} disc_filter_t; + class NimBLERemoteService; class NimBLEClientCallbacks; class NimBLEAdvertisedDevice; @@ -33,64 +41,68 @@ class NimBLEAdvertisedDevice; */ class NimBLEClient { public: - bool connect(NimBLEAdvertisedDevice* device, bool refreshServices = true); - bool connect(NimBLEAddress address, uint8_t type = BLE_ADDR_TYPE_PUBLIC, bool refreshServices = true); // Connect to the remote BLE Server - int disconnect(uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); // Disconnect from the remote BLE Server - NimBLEAddress getPeerAddress(); // Get the address of the remote BLE Server - int getRssi(); // Get the RSSI of the remote BLE Server - std::map* getServices(); // Get a map of the services offered by the remote BLE Server - NimBLERemoteService* getService(const char* uuid); // Get a reference to a specified service offered by the remote BLE server. - NimBLERemoteService* getService(NimBLEUUID uuid); // Get a reference to a specified service offered by the remote BLE server. - std::string getValue(NimBLEUUID serviceUUID, NimBLEUUID characteristicUUID); // Get the value of a given characteristic at a given service. - bool setValue(NimBLEUUID serviceUUID, NimBLEUUID characteristicUUID, std::string value); // Set the value of a given characteristic at a given service. - bool isConnected(); // Return true if we are connected. - void setClientCallbacks(NimBLEClientCallbacks *pClientCallbacks, bool deleteCallbacks = true); - std::string toString(); // Return a string representation of this client. - uint16_t getConnId(); - uint16_t getMTU(); - bool secureConnection(); - void setConnectTimeout(uint8_t timeout); - void setConnectionParams(uint16_t minInterval, uint16_t maxInterval, - uint16_t latency, uint16_t timeout, - uint16_t scanInterval=16, uint16_t scanWindow=16); // NimBLE default scan settings - void updateConnParams(uint16_t minInterval, uint16_t maxInterval, - uint16_t latency, uint16_t timeout); - - + bool connect(NimBLEAdvertisedDevice* device, bool refreshServices = true); + bool connect(const NimBLEAddress &address, uint8_t type = BLE_ADDR_PUBLIC, + bool refreshServices = true); + int disconnect(uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); + NimBLEAddress getPeerAddress(); + int getRssi(); + std::vector* getServices(bool refresh = false); + std::vector::iterator begin(); + std::vector::iterator end(); + NimBLERemoteService* getService(const char* uuid); + NimBLERemoteService* getService(const NimBLEUUID &uuid); + std::string getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID); + bool setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID, + const std::string &value); + bool isConnected(); + void setClientCallbacks(NimBLEClientCallbacks *pClientCallbacks, + bool deleteCallbacks = true); + std::string toString(); + uint16_t getConnId(); + uint16_t getMTU(); + bool secureConnection(); + void setConnectTimeout(uint8_t timeout); + void setConnectionParams(uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout, + uint16_t scanInterval=16, uint16_t scanWindow=16); + void updateConnParams(uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout); + void discoverAttributes(); + private: NimBLEClient(); ~NimBLEClient(); - friend class NimBLEDevice; - friend class NimBLERemoteService; - static int handleGapEvent(struct ble_gap_event *event, void *arg); - static int serviceDiscoveredCB(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *service, void *arg); - void clearServices(); // Clear any existing services. - bool retrieveServices(); //Retrieve services from the server -// void onHostReset(); + friend class NimBLEDevice; + friend class NimBLERemoteService; - NimBLEAddress m_peerAddress = NimBLEAddress("\0\0\0\0\0\0"); // The BD address of the remote server. - uint16_t m_conn_id; - bool m_haveServices = false; // Have we previously obtain the set of services from the remote server. - bool m_isConnected = false; // Are we currently connected. - bool m_waitingToConnect =false; - bool m_deleteCallbacks = true; - int32_t m_connectTimeout; - //uint16_t m_mtu = 23; + static int handleGapEvent(struct ble_gap_event *event, void *arg); + static int serviceDiscoveredCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *service, + void *arg); + void clearServices(); + bool retrieveServices(const NimBLEUUID *uuid_filter = nullptr); + NimBLEAddress m_peerAddress = NimBLEAddress(""); + uint16_t m_conn_id; + bool m_isConnected = false; + bool m_waitingToConnect =false; + bool m_deleteCallbacks = true; + int32_t m_connectTimeout; NimBLEClientCallbacks* m_pClientCallbacks = nullptr; - FreeRTOS::Semaphore m_semaphoreOpenEvt = FreeRTOS::Semaphore("OpenEvt"); FreeRTOS::Semaphore m_semaphoreSearchCmplEvt = FreeRTOS::Semaphore("SearchCmplEvt"); FreeRTOS::Semaphore m_semeaphoreSecEvt = FreeRTOS::Semaphore("Security"); - std::map m_servicesMap; - + std::vector m_servicesVector; + private: friend class NimBLEClientCallbacks; ble_gap_conn_params m_pConnParams; -}; // class NimBLEClient +}; // class NimBLEClient /** @@ -109,5 +121,6 @@ public: virtual bool onConfirmPIN(uint32_t pin); }; +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif // CONFIG_BT_ENABLED #endif /* MAIN_NIMBLECLIENT_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp index 828334505..0d414d316 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp @@ -3,7 +3,7 @@ * * Created: on March 10, 2020 * Author H2zero - * + * * Originally: * * BLEDescriptor.cpp @@ -14,6 +14,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLEService.h" #include "NimBLEDescriptor.h" #include "NimBLELog.h" @@ -29,26 +32,26 @@ static NimBLEDescriptorCallbacks defaultCallbacks; /** * @brief NimBLEDescriptor constructor. */ -NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16_t max_len, - NimBLECharacteristic* pCharacteristic) +NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16_t max_len, + NimBLECharacteristic* pCharacteristic) : NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) { -} +} /** * @brief NimBLEDescriptor constructor. */ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_t max_len, - NimBLECharacteristic* pCharacteristic) + NimBLECharacteristic* pCharacteristic) { - m_uuid = uuid; - m_value.attr_len = 0; // Initial length is 0. - m_value.attr_max_len = max_len; // Maximum length of the data. - m_handle = NULL_HANDLE; // Handle is initially unknown. - m_pCharacteristic = nullptr; // No initial characteristic. + m_uuid = uuid; + m_value.attr_len = 0; // Initial length is 0. + m_value.attr_max_len = max_len; // Maximum length of the data. + m_handle = NULL_HANDLE; // Handle is initially unknown. + m_pCharacteristic = nullptr; // No initial characteristic. m_pCallbacks = &defaultCallbacks; // No initial callback. m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value. m_properties = 0; - + if (properties & BLE_GATT_CHR_F_READ) { // convert uint16_t properties to uint8_t m_properties |= BLE_ATT_F_READ; } @@ -81,7 +84,7 @@ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_ * @brief NimBLEDescriptor destructor. */ NimBLEDescriptor::~NimBLEDescriptor() { - free(m_value.attr_value); // Release the storage we created in the constructor. + free(m_value.attr_value); // Release the storage we created in the constructor. } // ~NimBLEDescriptor /** @@ -89,7 +92,7 @@ NimBLEDescriptor::~NimBLEDescriptor() { * @return The handle for this descriptor. */ uint16_t NimBLEDescriptor::getHandle() { - return m_handle; + return m_handle; } // getHandle @@ -98,7 +101,7 @@ uint16_t NimBLEDescriptor::getHandle() { * @return The length (in bytes) of the value of this descriptor. */ size_t NimBLEDescriptor::getLength() { - return m_value.attr_len; + return m_value.attr_len; } // getLength @@ -106,7 +109,7 @@ size_t NimBLEDescriptor::getLength() { * @brief Get the UUID of the descriptor. */ NimBLEUUID NimBLEDescriptor::getUUID() { - return m_uuid; + return m_uuid; } // getUUID @@ -115,7 +118,7 @@ NimBLEUUID NimBLEDescriptor::getUUID() { * @return A pointer to the value of this descriptor. */ uint8_t* NimBLEDescriptor::getValue() { - return m_value.attr_value; + return m_value.attr_value; } // getValue @@ -125,25 +128,25 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, { const ble_uuid_t *uuid; int rc; - NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg; - - NIMBLE_LOGD(LOG_TAG, "Descriptor %s %s event", pDescriptor->getUUID().toString().c_str(), + NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg; + + NIMBLE_LOGD(LOG_TAG, "Descriptor %s %s event", pDescriptor->getUUID().toString().c_str(), ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC ? "Read" : "Write"); - - uuid = ctxt->chr->uuid; - if(ble_uuid_cmp(uuid, &pDescriptor->getUUID().getNative()->u) == 0){ + + uuid = ctxt->chr->uuid; + if(ble_uuid_cmp(uuid, &pDescriptor->getUUID().getNative()->u) == 0){ switch(ctxt->op) { case BLE_GATT_ACCESS_OP_READ_DSC: { pDescriptor->m_pCallbacks->onRead(pDescriptor); rc = os_mbuf_append(ctxt->om, pDescriptor->getValue(), pDescriptor->getLength()); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } - + case BLE_GATT_ACCESS_OP_WRITE_DSC: { if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - + pDescriptor->setValue(ctxt->om->om_data, ctxt->om->om_len); pDescriptor->m_pCallbacks->onWrite(pDescriptor); return 0; @@ -151,8 +154,8 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, default: break; } - } - + } + return BLE_ATT_ERR_UNLIKELY; } @@ -162,10 +165,10 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, */ void NimBLEDescriptor::setCallbacks(NimBLEDescriptorCallbacks* pCallbacks) { if (pCallbacks != nullptr){ - m_pCallbacks = pCallbacks; - } else { - m_pCallbacks = &defaultCallbacks; - } + m_pCallbacks = pCallbacks; + } else { + m_pCallbacks = &defaultCallbacks; + } } // setCallbacks @@ -176,9 +179,9 @@ void NimBLEDescriptor::setCallbacks(NimBLEDescriptorCallbacks* pCallbacks) { * @return N/A. */ void NimBLEDescriptor::setHandle(uint16_t handle) { - NIMBLE_LOGD(LOG_TAG, ">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle); - m_handle = handle; - NIMBLE_LOGD(LOG_TAG, "<< setHandle()"); + NIMBLE_LOGD(LOG_TAG, ">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle); + m_handle = handle; + NIMBLE_LOGD(LOG_TAG, "<< setHandle()"); } // setHandle @@ -187,13 +190,13 @@ void NimBLEDescriptor::setHandle(uint16_t handle) { * @param [in] data The data to set for the descriptor. * @param [in] length The length of the data in bytes. */ -void NimBLEDescriptor::setValue(uint8_t* data, size_t length) { - if (length > BLE_ATT_ATTR_MAX_LEN) { - NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN); - return; - } - m_value.attr_len = length; - memcpy(m_value.attr_value, data, length); +void NimBLEDescriptor::setValue(const uint8_t* data, size_t length) { + if (length > BLE_ATT_ATTR_MAX_LEN) { + NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN); + return; + } + m_value.attr_len = length; + memcpy(m_value.attr_value, data, length); } // setValue @@ -201,16 +204,16 @@ void NimBLEDescriptor::setValue(uint8_t* data, size_t length) { * @brief Set the value of the descriptor. * @param [in] value The value of the descriptor in string form. */ -void NimBLEDescriptor::setValue(std::string value) { - setValue((uint8_t*) value.data(), value.length()); +void NimBLEDescriptor::setValue(const std::string &value) { + setValue((uint8_t*) value.data(), value.length()); } // setValue /* void NimBLEDescriptor::setAccessPermissions(uint8_t perm) { - m_permissions = perm; + m_permissions = perm; } -*/ +*/ /** @@ -218,10 +221,10 @@ void NimBLEDescriptor::setAccessPermissions(uint8_t perm) { * @return A string representation of the descriptor. */ std::string NimBLEDescriptor::toString() { - char hex[5]; - snprintf(hex, sizeof(hex), "%04x", m_handle); - std::string res = "UUID: " + m_uuid.toString() + ", handle: 0x" + hex; - return res; + char hex[5]; + snprintf(hex, sizeof(hex), "%04x", m_handle); + std::string res = "UUID: " + m_uuid.toString() + ", handle: 0x" + hex; + return res; } // toString @@ -232,7 +235,7 @@ NimBLEDescriptorCallbacks::~NimBLEDescriptorCallbacks() {} * @param [in] pDescriptor The descriptor that is the source of the event. */ void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) { - NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default"); + NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default"); } // onRead @@ -241,8 +244,8 @@ void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) { * @param [in] pDescriptor The descriptor that is the source of the event. */ void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor) { - NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default"); + NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default"); } // onWrite - -#endif /* CONFIG_BT_ENABLED */ \ No newline at end of file +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h index 4f376a99b..8af3560d3 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h @@ -3,7 +3,7 @@ * * Created: on March 10, 2020 * Author H2zero - * + * * Originally: * * BLEDescriptor.h @@ -17,6 +17,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLECharacteristic.h" #include "NimBLEUUID.h" #include "FreeRTOS.h" @@ -43,44 +46,44 @@ class NimBLEDescriptorCallbacks; */ class NimBLEDescriptor { public: - virtual ~NimBLEDescriptor(); - uint16_t getHandle(); // Get the handle of the descriptor. - size_t getLength(); // Get the length of the value of the descriptor. - NimBLEUUID getUUID(); // Get the UUID of the descriptor. - uint8_t* getValue(); // Get a pointer to the value of the descriptor. -// void setAccessPermissions(uint8_t perm); // Set the permissions of the descriptor. - void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); // Set callbacks to be invoked for the descriptor. - void setValue(uint8_t* data, size_t size); // Set the value of the descriptor as a pointer to data. - void setValue(std::string value); // Set the value of the descriptor as a data buffer. + virtual ~NimBLEDescriptor(); + uint16_t getHandle(); // Get the handle of the descriptor. + size_t getLength(); // Get the length of the value of the descriptor. + NimBLEUUID getUUID(); // Get the UUID of the descriptor. + uint8_t* getValue(); // Get a pointer to the value of the descriptor. +// void setAccessPermissions(uint8_t perm); // Set the permissions of the descriptor. + void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); // Set callbacks to be invoked for the descriptor. + void setValue(const uint8_t* data, size_t size); // Set the value of the descriptor as a pointer to data. + void setValue(const std::string &value); // Set the value of the descriptor as a data buffer. - std::string toString(); // Convert the descriptor to a string representation. + std::string toString(); // Convert the descriptor to a string representation. private: - friend class NimBLEDescriptorMap; - friend class NimBLECharacteristic; + friend class NimBLEDescriptorMap; + friend class NimBLECharacteristic; friend class NimBLEService; - friend class NimBLE2902; - friend class NimBLE2904; - - NimBLEDescriptor(const char* uuid, uint16_t properties, - uint16_t max_len, - NimBLECharacteristic* pCharacteristic); - - NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, - uint16_t max_len, - NimBLECharacteristic* pCharacteristic); - - NimBLEUUID m_uuid; - uint16_t m_handle; - NimBLEDescriptorCallbacks* m_pCallbacks; - NimBLECharacteristic* m_pCharacteristic; - uint8_t m_properties; - attr_value_t m_value; + friend class NimBLE2902; + friend class NimBLE2904; - static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, + NimBLEDescriptor(const char* uuid, uint16_t properties, + uint16_t max_len, + NimBLECharacteristic* pCharacteristic); + + NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, + uint16_t max_len, + NimBLECharacteristic* pCharacteristic); + + NimBLEUUID m_uuid; + uint16_t m_handle; + NimBLEDescriptorCallbacks* m_pCallbacks; + NimBLECharacteristic* m_pCharacteristic; + uint8_t m_properties; + attr_value_t m_value; + + static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); - - void setHandle(uint16_t handle); + + void setHandle(uint16_t handle); }; // BLEDescriptor @@ -93,9 +96,11 @@ private: */ class NimBLEDescriptorCallbacks { public: - virtual ~NimBLEDescriptorCallbacks(); - virtual void onRead(NimBLEDescriptor* pDescriptor); - virtual void onWrite(NimBLEDescriptor* pDescriptor); + virtual ~NimBLEDescriptorCallbacks(); + virtual void onRead(NimBLEDescriptor* pDescriptor); + virtual void onWrite(NimBLEDescriptor* pDescriptor); }; + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif /* CONFIG_BT_ENABLED */ -#endif /* MAIN_NIMBLEDESCRIPTOR_H_ */ \ No newline at end of file +#endif /* MAIN_NIMBLEDESCRIPTOR_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDescriptorMap.cpp b/libesp32/NimBLE-Arduino/src/NimBLEDescriptorMap.cpp index 8d0a13d29..0ca1cbeeb 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDescriptorMap.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEDescriptorMap.cpp @@ -3,7 +3,7 @@ * * Created: on March 10, 2020 * Author H2zero - * + * * Originally: * * BLEDescriptorMap.cpp @@ -13,6 +13,10 @@ */ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLECharacteristic.h" #include "NimBLEDescriptor.h" @@ -23,7 +27,7 @@ * @return The descriptor. If not present, then nullptr is returned. */ NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(const char* uuid) { - return getByUUID(NimBLEUUID(uuid)); + return getByUUID(NimBLEUUID(uuid)); } @@ -32,13 +36,13 @@ NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(const char* uuid) { * @param [in] UUID The UUID to look up the descriptor. * @return The descriptor. If not present, then nullptr is returned. */ -NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(NimBLEUUID uuid) { - for (auto &myPair : m_uuidMap) { - if (myPair.first->getUUID().equals(uuid)) { - return myPair.first; - } - } - return nullptr; +NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(const NimBLEUUID &uuid) { + for (auto &myPair : m_uuidMap) { + if (myPair.first->getUUID().equals(uuid)) { + return myPair.first; + } + } + return nullptr; } // getByUUID @@ -49,7 +53,7 @@ NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(NimBLEUUID uuid) { */ /* NimBLEDescriptor* NimBLEDescriptorMap::getByHandle(uint16_t handle) { - return m_handleMap.at(handle); + return m_handleMap.at(handle); } // getByHandle */ @@ -60,7 +64,7 @@ NimBLEDescriptor* NimBLEDescriptorMap::getByHandle(uint16_t handle) { * @return N/A. */ void NimBLEDescriptorMap::setByUUID(const char* uuid, NimBLEDescriptor* pDescriptor){ - m_uuidMap.insert(std::pair(pDescriptor, uuid)); + m_uuidMap.insert(std::pair(pDescriptor, uuid)); } // setByUUID @@ -71,8 +75,8 @@ void NimBLEDescriptorMap::setByUUID(const char* uuid, NimBLEDescriptor* pDescrip * @param [in] characteristic The descriptor to cache. * @return N/A. */ -void NimBLEDescriptorMap::setByUUID(NimBLEUUID uuid, NimBLEDescriptor* pDescriptor) { - m_uuidMap.insert(std::pair(pDescriptor, uuid.toString())); +void NimBLEDescriptorMap::setByUUID(const NimBLEUUID &uuid, NimBLEDescriptor* pDescriptor) { + m_uuidMap.insert(std::pair(pDescriptor, uuid.toString())); } // setByUUID @@ -84,7 +88,7 @@ void NimBLEDescriptorMap::setByUUID(NimBLEUUID uuid, NimBLEDescriptor* pDescript */ /* void NimBLEDescriptorMap::setByHandle(uint16_t handle, NimBLEDescriptor* pDescriptor) { - m_handleMap.insert(std::pair(handle, pDescriptor)); + m_handleMap.insert(std::pair(handle, pDescriptor)); } // setByHandle */ @@ -93,7 +97,7 @@ void NimBLEDescriptorMap::setByHandle(uint16_t handle, NimBLEDescriptor* pDescri * @brief Get the number of descriptors in the map. */ uint8_t NimBLEDescriptorMap::getSize() { - return (uint8_t)m_uuidMap.size(); + return (uint8_t)m_uuidMap.size(); } // getSize @@ -102,18 +106,18 @@ uint8_t NimBLEDescriptorMap::getSize() { * @return A string representation of the descriptor map. */ std::string NimBLEDescriptorMap::toString() { - std::string res; - char hex[5]; - int count = 0; - for (auto &myPair : m_uuidMap) { - if (count > 0) {res += "\n";} - snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle()); - count++; - res += "handle: 0x"; - res += hex; - res += ", uuid: " + myPair.first->getUUID().toString(); - } - return res; + std::string res; + char hex[5]; + int count = 0; + for (auto &myPair : m_uuidMap) { + if (count > 0) {res += "\n";} + snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle()); + count++; + res += "handle: 0x"; + res += hex; + res += ", uuid: " + myPair.first->getUUID().toString(); + } + return res; } // toString @@ -122,11 +126,11 @@ std::string NimBLEDescriptorMap::toString() { * @return The first descriptor in the map. */ NimBLEDescriptor* NimBLEDescriptorMap::getFirst() { - m_iterator = m_uuidMap.begin(); - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLEDescriptor* pRet = m_iterator->first; - m_iterator++; - return pRet; + m_iterator = m_uuidMap.begin(); + if (m_iterator == m_uuidMap.end()) return nullptr; + NimBLEDescriptor* pRet = m_iterator->first; + m_iterator++; + return pRet; } // getFirst @@ -135,9 +139,11 @@ NimBLEDescriptor* NimBLEDescriptorMap::getFirst() { * @return The next descriptor in the map. */ NimBLEDescriptor* NimBLEDescriptorMap::getNext() { - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLEDescriptor* pRet = m_iterator->first; - m_iterator++; - return pRet; + if (m_iterator == m_uuidMap.end()) return nullptr; + NimBLEDescriptor* pRet = m_iterator->first; + m_iterator++; + return pRet; } // getNext -#endif /* CONFIG_BT_ENABLED */ \ No newline at end of file + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp b/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp index a8de6718c..1540f6327 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp @@ -3,7 +3,7 @@ * * Created: on Jan 24 2020 * Author H2zero - * + * * Originally: * * BLEDevice.cpp @@ -14,6 +14,7 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" #include "NimBLEDevice.h" #include "NimBLEUtils.h" @@ -39,38 +40,37 @@ static const char* LOG_TAG = "NimBLEDevice"; /** * Singletons for the NimBLEDevice. */ -bool NimBLEDevice_initialized = false; +bool initialized = false; +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) NimBLEScan* NimBLEDevice::m_pScan = nullptr; +#endif +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) NimBLEServer* NimBLEDevice::m_pServer = nullptr; +#endif uint32_t NimBLEDevice::m_passkey = 123456; bool NimBLEDevice::m_synced = false; +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) NimBLEAdvertising* NimBLEDevice::m_bleAdvertising = nullptr; +#endif gap_event_handler NimBLEDevice::m_customGapHandler = nullptr; ble_gap_event_listener NimBLEDevice::m_listener; +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) std::list NimBLEDevice::m_cList; +#endif std::list NimBLEDevice::m_ignoreList; NimBLESecurityCallbacks* NimBLEDevice::m_securityCallbacks = nullptr; - -//std::map BLEDevice::m_connectedClientsMap; - -//gattc_event_handler BLEDevice::m_customGattcHandler = nullptr; -//gatts_event_handler BLEDevice::m_customGattsHandler = nullptr; /** * @brief Create a new instance of a server. * @return A new instance of the server. */ +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) /* STATIC */ NimBLEServer* NimBLEDevice::createServer() { -/*#ifndef CONFIG_GATTS_ENABLE // Check that BLE GATTS is enabled in make menuconfig - NIMBLE_LOGE(LOG_TAG, "BLE GATTS is not enabled - CONFIG_GATTS_ENABLE not defined"); - abort(); -#endif // CONFIG_GATTS_ENABLE -*/ if(NimBLEDevice::m_pServer == nullptr) { NimBLEDevice::m_pServer = new NimBLEServer(); - ble_gatts_reset(); + ble_gatts_reset(); ble_svc_gap_init(); ble_svc_gatt_init(); } @@ -79,22 +79,34 @@ NimBLESecurityCallbacks* NimBLEDevice::m_securityCallbacks = nullptr; } // createServer +/** + * @brief Get the instance of the server. + * @return A pointer to the server instance. + */ +/* STATIC */ NimBLEServer* NimBLEDevice::getServer() { + return m_pServer; +} // getServer +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) NimBLEAdvertising* NimBLEDevice::getAdvertising() { - if(m_bleAdvertising == nullptr) { - m_bleAdvertising = new NimBLEAdvertising(); - } - return m_bleAdvertising; + if(m_bleAdvertising == nullptr) { + m_bleAdvertising = new NimBLEAdvertising(); + } + return m_bleAdvertising; } void NimBLEDevice::startAdvertising() { - getAdvertising()->start(); + getAdvertising()->start(); } // startAdvertising void NimBLEDevice::stopAdvertising() { getAdvertising()->stop(); } // stopAdvertising +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) /** @@ -102,25 +114,27 @@ void NimBLEDevice::stopAdvertising() { * @return The scanning object reference. This is a singleton object. The caller should not * try and release/delete it. */ +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) /* STATIC */ NimBLEScan* NimBLEDevice::getScan() { if (m_pScan == nullptr) { m_pScan = new NimBLEScan(); } return m_pScan; } // getScan - +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) /** * @brief Creates a new client object and maintains a list of all client objects - * each client can connect to 1 peripheral device. + * each client can connect to 1 peripheral device. * @return A reference to the new client object. */ +#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) /* STATIC */ NimBLEClient* NimBLEDevice::createClient() { if(m_cList.size() >= NIMBLE_MAX_CONNECTIONS) { - NIMBLE_LOGW("Number of clients exceeds Max connections. Max=(%d)", + NIMBLE_LOGW("Number of clients exceeds Max connections. Max=(%d)", NIMBLE_MAX_CONNECTIONS); } - + NimBLEClient* pClient = new NimBLEClient(); m_cList.push_back(pClient); @@ -137,7 +151,7 @@ void NimBLEDevice::stopAdvertising() { if(pClient == nullptr) { return false; } - + if(pClient->m_isConnected) { if (pClient->disconnect() != 0) { return false; @@ -146,7 +160,7 @@ void NimBLEDevice::stopAdvertising() { vTaskDelay(1); } } - + if(pClient->m_waitingToConnect) { if(ble_gap_conn_cancel() != 0){ return false; @@ -155,10 +169,10 @@ void NimBLEDevice::stopAdvertising() { vTaskDelay(1); } } - + m_cList.remove(pClient); delete pClient; - + return true; } // deleteClient @@ -202,7 +216,7 @@ void NimBLEDevice::stopAdvertising() { * @param [in] a NimBLEAddress of the peer to search for. * @return A reference pointer to the client with the peer address. */ -/* STATIC */NimBLEClient* NimBLEDevice::getClientByPeerAddress(NimBLEAddress peer_addr) { +/* STATIC */NimBLEClient* NimBLEDevice::getClientByPeerAddress(const NimBLEAddress &peer_addr) { for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { if((*it)->getPeerAddress().equals(peer_addr)) { return (*it); @@ -225,18 +239,20 @@ void NimBLEDevice::stopAdvertising() { return nullptr; } // getDisconnectedClient +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) + /** * @brief Set the transmission power. * The power level can be one of: - * * ESP_PWR_LVL_N12 = 0, !< Corresponding to -12dbm - * * ESP_PWR_LVL_N9 = 1, !< Corresponding to -9dbm - * * ESP_PWR_LVL_N6 = 2, !< Corresponding to -6dbm - * * ESP_PWR_LVL_N3 = 3, !< Corresponding to -3dbm - * * ESP_PWR_LVL_N0 = 4, !< Corresponding to 0dbm - * * ESP_PWR_LVL_P3 = 5, !< Corresponding to +3dbm - * * ESP_PWR_LVL_P6 = 6, !< Corresponding to +6dbm - * * ESP_PWR_LVL_P9 = 7, !< Corresponding to +9dbm + * * ESP_PWR_LVL_N12 = 0, !< Corresponding to -12dbm + * * ESP_PWR_LVL_N9 = 1, !< Corresponding to -9dbm + * * ESP_PWR_LVL_N6 = 2, !< Corresponding to -6dbm + * * ESP_PWR_LVL_N3 = 3, !< Corresponding to -3dbm + * * ESP_PWR_LVL_N0 = 4, !< Corresponding to 0dbm + * * ESP_PWR_LVL_P3 = 5, !< Corresponding to +3dbm + * * ESP_PWR_LVL_P6 = 6, !< Corresponding to +6dbm + * * ESP_PWR_LVL_P9 = 7, !< Corresponding to +9dbm * @param [in] powerLevel. */ /* STATIC */ void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) { @@ -251,26 +267,26 @@ void NimBLEDevice::stopAdvertising() { /* STATIC */ int NimBLEDevice::getPower(esp_ble_power_type_t powerType) { - switch(esp_ble_tx_power_get(powerType)) { - case ESP_PWR_LVL_N12: - return -12; - case ESP_PWR_LVL_N9: - return -9; - case ESP_PWR_LVL_N6: - return -6; - case ESP_PWR_LVL_N3: - return -6; - case ESP_PWR_LVL_N0: - return 0; - case ESP_PWR_LVL_P3: - return 3; - case ESP_PWR_LVL_P6: - return 6; - case ESP_PWR_LVL_P9: - return 9; - default: - return BLE_HS_ADV_TX_PWR_LVL_AUTO; - } + switch(esp_ble_tx_power_get(powerType)) { + case ESP_PWR_LVL_N12: + return -12; + case ESP_PWR_LVL_N9: + return -9; + case ESP_PWR_LVL_N6: + return -6; + case ESP_PWR_LVL_N3: + return -6; + case ESP_PWR_LVL_N0: + return 0; + case ESP_PWR_LVL_P3: + return 3; + case ESP_PWR_LVL_P6: + return 6; + case ESP_PWR_LVL_P9: + return 9; + default: + return BLE_HS_ADV_TX_PWR_LVL_AUTO; + } } // setPower @@ -282,13 +298,13 @@ void NimBLEDevice::stopAdvertising() { /* STATIC*/ NimBLEAddress NimBLEDevice::getAddress() { ble_addr_t addr = {BLE_ADDR_PUBLIC, 0}; //ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL) - + if(BLE_HS_ENOADDR == ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL)) { NIMBLE_LOGD(LOG_TAG, "Public address not found, checking random"); addr.type = BLE_ADDR_RANDOM; ble_hs_id_copy_addr(BLE_ADDR_RANDOM, addr.val, NULL); } - + return NimBLEAddress(addr); } // getAddress @@ -309,13 +325,13 @@ void NimBLEDevice::stopAdvertising() { */ /* STATIC */int NimBLEDevice::setMTU(uint16_t mtu) { NIMBLE_LOGD(LOG_TAG, ">> setLocalMTU: %d", mtu); - + int rc = ble_att_set_preferred_mtu(mtu); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "Could not set local mtu value to: %d", mtu); } - + NIMBLE_LOGD(LOG_TAG, "<< setLocalMTU"); return rc; } // setMTU @@ -337,26 +353,32 @@ void NimBLEDevice::stopAdvertising() { if(!m_synced) { return; } - + m_synced = false; - + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) if(m_pScan != nullptr) { m_pScan->onHostReset(); } -/* Not needed +#endif + +/* Not needed if(m_pServer != nullptr) { m_pServer->onHostReset(); } - + for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { (*it)->onHostReset(); } -*/ +*/ + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) if(m_bleAdvertising != nullptr) { m_bleAdvertising->onHostReset(); } - - NIMBLE_LOGC(LOG_TAG, "Resetting state; reason=%d, %s", reason, +#endif + + NIMBLE_LOGC(LOG_TAG, "Resetting state; reason=%d, %s", reason, NimBLEUtils::returnCodeToString(reason)); } // onReset @@ -372,21 +394,27 @@ void NimBLEDevice::stopAdvertising() { if(m_synced) { return; } - + /* Make sure we have proper identity address set (public preferred) */ int rc = ble_hs_util_ensure_addr(0); assert(rc == 0); - + m_synced = true; - - if(m_pScan != nullptr) { - // Restart scanning with the last values sent, allow to clear results. - m_pScan->start(m_pScan->m_duration, m_pScan->m_scanCompleteCB); - } - - if(m_bleAdvertising != nullptr) { - // Restart advertisng, parameters should already be set. - m_bleAdvertising->start(); + + if(initialized) { +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + if(m_pScan != nullptr) { + // Restart scanning with the last values sent, allow to clear results. + m_pScan->start(m_pScan->m_duration, m_pScan->m_scanCompleteCB); + } +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + if(m_bleAdvertising != nullptr) { + // Restart advertisng, parameters should already be set. + m_bleAdvertising->start(); + } +#endif } } // onSync @@ -408,58 +436,57 @@ void NimBLEDevice::stopAdvertising() { * @brief Initialize the %BLE environment. * @param deviceName The device name of the device. */ -/* STATIC */ void NimBLEDevice::init(std::string deviceName) { - if(!NimBLEDevice_initialized){ - NimBLEDevice_initialized = true; // Set the initialization flag to ensure we are only initialized once. - +/* STATIC */ void NimBLEDevice::init(const std::string &deviceName) { + if(!initialized){ int rc=0; esp_err_t errRc = ESP_OK; - + #ifdef ARDUINO_ARCH_ESP32 // make sure the linker includes esp32-hal-bt.c so ardruino init doesn't release BLE memory. btStarted(); #endif errRc = nvs_flash_init(); - + if (errRc == ESP_ERR_NVS_NO_FREE_PAGES || errRc == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); errRc = nvs_flash_init(); } ESP_ERROR_CHECK(errRc); - + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); - + nimble_port_init(); - - // Setup callbacks for host events + + // Setup callbacks for host events ble_hs_cfg.reset_cb = NimBLEDevice::onReset; ble_hs_cfg.sync_cb = NimBLEDevice::onSync; - + // Set initial security capabilities - ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT; + ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT; ble_hs_cfg.sm_bonding = 0; ble_hs_cfg.sm_mitm = 0; ble_hs_cfg.sm_sc = 1; ble_hs_cfg.sm_our_key_dist = 1; ble_hs_cfg.sm_their_key_dist = 3; - + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; /*TODO: Implement handler for this*/ - + // Set the device name. rc = ble_svc_gap_device_name_set(deviceName.c_str()); assert(rc == 0); ble_store_config_init(); - + nimble_port_freertos_init(NimBLEDevice::host_task); } // Wait for host and controller to sync before returning and accepting new tasks while(!m_synced){ vTaskDelay(1 / portTICK_PERIOD_MS); } - //vTaskDelay(200 / portTICK_PERIOD_MS); // Delay for 200 msecs as a workaround to an apparent Arduino environment issue. + + initialized = true; // Set the initialization flag to ensure we are only initialized once. } // init @@ -470,13 +497,14 @@ void NimBLEDevice::stopAdvertising() { int ret = nimble_port_stop(); if (ret == 0) { nimble_port_deinit(); - + ret = esp_nimble_hci_and_controller_deinit(); if (ret != ESP_OK) { NIMBLE_LOGE(LOG_TAG, "esp_nimble_hci_and_controller_deinit() failed with error: %d", ret); } - - NimBLEDevice_initialized = false; + + initialized = false; + m_synced = false; } } // deinit @@ -485,7 +513,7 @@ void NimBLEDevice::stopAdvertising() { * @brief Check if the initialization is complete. */ bool NimBLEDevice::getInitialized() { - return NimBLEDevice_initialized; + return initialized; } // getInitialized @@ -507,12 +535,12 @@ bool NimBLEDevice::getInitialized() { * @brief Set the authorization mode for this device. * @param A bitmap indicating what modes are supported. * The bits are defined as follows: - ** 0x01 BLE_SM_PAIR_AUTHREQ_BOND - ** 0x04 BLE_SM_PAIR_AUTHREQ_MITM - ** 0x08 BLE_SM_PAIR_AUTHREQ_SC - ** 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported. + ** 0x01 BLE_SM_PAIR_AUTHREQ_BOND + ** 0x04 BLE_SM_PAIR_AUTHREQ_MITM + ** 0x08 BLE_SM_PAIR_AUTHREQ_SC + ** 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported. ** 0xe2 BLE_SM_PAIR_AUTHREQ_RESERVED - for reference only. - */ + */ /*STATIC*/void NimBLEDevice::setSecurityAuth(uint8_t auth_req) { NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0, (auth_req & BLE_SM_PAIR_AUTHREQ_MITM)>0, @@ -525,8 +553,8 @@ bool NimBLEDevice::getInitialized() { * @param One of the following: ** 0x00 BLE_HS_IO_DISPLAY_ONLY DisplayOnly IO capability ** 0x01 BLE_HS_IO_DISPLAY_YESNO DisplayYesNo IO capability - ** 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability - ** 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability + ** 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability + ** 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability ** 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability */ /*STATIC*/ void NimBLEDevice::setSecurityIOCap(uint8_t iocap) { @@ -537,7 +565,7 @@ bool NimBLEDevice::getInitialized() { /** * @brief If we are the initiator of the security procedure this sets the keys we will distribute. * @param A bitmap indicating which keys to distribute during pairing. - * The bits are defined as follows: + * The bits are defined as follows: ** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Distribute the encryption key. ** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Distribute the ID key (IRK). ** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN @@ -551,7 +579,7 @@ bool NimBLEDevice::getInitialized() { /** * @brief Set the keys we are willing to accept during pairing. * @param A bitmap indicating which keys to accept during pairing. - * The bits are defined as follows: + * The bits are defined as follows: ** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Accept the encryption key. ** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Accept the ID key (IRK). ** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN @@ -594,14 +622,14 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) { */ /* STATIC */int NimBLEDevice::startSecurity(uint16_t conn_id) { /* if(m_securityCallbacks != nullptr) { - m_securityCallbacks->onSecurityRequest(); + m_securityCallbacks->onSecurityRequest(); } - */ + */ int rc = ble_gap_security_initiate(conn_id); if(rc != 0){ NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); } - + return rc; } // startSecurity @@ -610,7 +638,7 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) { * @brief Check if the device address is on our ignore list. * @return True if ignoring. */ -/*STATIC*/ bool NimBLEDevice::isIgnored(NimBLEAddress address) { +/*STATIC*/ bool NimBLEDevice::isIgnored(const NimBLEAddress &address) { for(auto &it : m_ignoreList) { if(it.equals(address)){ return true; @@ -625,7 +653,7 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) { * @brief Add a device to the ignore list. * @param Address of the device we want to ignore. */ -/*STATIC*/ void NimBLEDevice::addIgnored(NimBLEAddress address) { +/*STATIC*/ void NimBLEDevice::addIgnored(const NimBLEAddress &address) { m_ignoreList.push_back(address); } @@ -634,7 +662,7 @@ void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) { * @brief Remove a device from the ignore list. * @param Address of the device we want to remove from the list. */ -/*STATIC*/void NimBLEDevice::removeIgnored(NimBLEAddress address) { +/*STATIC*/void NimBLEDevice::removeIgnored(const NimBLEAddress &address) { for(auto it = m_ignoreList.begin(); it != m_ignoreList.end(); ++it) { if((*it).equals(address)){ m_ignoreList.erase(it); @@ -659,20 +687,4 @@ void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) { } // setCustomGapHandler -/** - * @brief Backward compatibility for bluedroid gatt events. - * NimBLe does not send GATT events - */ - /* -void BLEDevice::setCustomGattcHandler(gattc_event_handler handler) { - setCustomGapHandler(handler); -} - -void BLEDevice::setCustomGattsHandler(gatts_event_handler handler) { - setCustomGapHandler(handler); -} -*/ -/**********************************************************/ - - #endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDevice.h b/libesp32/NimBLE-Arduino/src/NimBLEDevice.h index b2731c23f..c4a6d0417 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDevice.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEDevice.h @@ -3,7 +3,7 @@ * * Created: on Jan 24 2020 * Author H2zero - * + * * Originally: * * BLEDevice.h @@ -17,11 +17,27 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) #include "NimBLEScan.h" -#include "NimBLEUtils.h" +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +#include "NimBLEAdvertising.h" +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) #include "NimBLEClient.h" +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #include "NimBLEServer.h" +#endif + +#include "NimBLEUtils.h" #include "NimBLESecurity.h" +#include "NimBLEAddress.h" #include "esp_bt.h" @@ -50,43 +66,47 @@ #define BLEAdvertising NimBLEAdvertising #define BLEServerCallbacks NimBLEServerCallbacks #define BLECharacteristicCallbacks NimBLECharacteristicCallbacks -#define BLEAdvertisementData NimBLEAdvertisementData -#define BLEDescriptor NimBLEDescriptor -#define BLE2902 NimBLE2902 -#define BLE2904 NimBLE2904 -#define BLEDescriptorCallbacks NimBLEDescriptorCallbacks +#define BLEAdvertisementData NimBLEAdvertisementData +#define BLEDescriptor NimBLEDescriptor +#define BLE2902 NimBLE2902 +#define BLE2904 NimBLE2904 +#define BLEDescriptorCallbacks NimBLEDescriptorCallbacks #define BLEBeacon NimBLEBeacon #define BLEEddystoneTLM NimBLEEddystoneTLM #define BLEEddystoneURL NimBLEEddystoneURL #ifdef CONFIG_BT_NIMBLE_MAX_CONNECTIONS #define NIMBLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS -#else +#else #define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS #endif - + /** * @brief BLE functions. */ typedef int (*gap_event_handler)(ble_gap_event *event, void *arg); -//typedef void (*gattc_event_handler)(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* param); -//typedef void (*gatts_event_handler)(esp_gatts_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gatts_cb_param_t* param); extern "C" void ble_store_config_init(void); class NimBLEDevice { public: - static void init(std::string deviceName); // Initialize the local BLE environment. + static void init(const std::string &deviceName); static void deinit(); static bool getInitialized(); static NimBLEAddress getAddress(); static std::string toString(); - static NimBLEScan* getScan(); // Get the scan object - static NimBLEClient* createClient(); - static NimBLEServer* createServer(); - static bool deleteClient(NimBLEClient* pClient); + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + static NimBLEScan* getScan(); +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + static NimBLEServer* createServer(); + static NimBLEServer* getServer(); +#endif + static void setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT); - static int getPower(esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT); + static int getPower(esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT); static void setCustomGapHandler(gap_event_handler handler); static void setSecurityAuth(bool bonding, bool mitm, bool sc); static void setSecurityAuth(uint8_t auth_req); @@ -98,39 +118,69 @@ public: static void setSecurityCallbacks(NimBLESecurityCallbacks* pCallbacks); static int setMTU(uint16_t mtu); static uint16_t getMTU(); - static bool isIgnored(NimBLEAddress address); - static void addIgnored(NimBLEAddress address); - static void removeIgnored(NimBLEAddress address); + static bool isIgnored(const NimBLEAddress &address); + static void addIgnored(const NimBLEAddress &address); + static void removeIgnored(const NimBLEAddress &address); + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) static NimBLEAdvertising* getAdvertising(); - static void startAdvertising(); - static void stopAdvertising(); + static void startAdvertising(); + static void stopAdvertising(); +#endif + +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + static NimBLEClient* createClient(); + static bool deleteClient(NimBLEClient* pClient); static NimBLEClient* getClientByID(uint16_t conn_id); - static NimBLEClient* getClientByPeerAddress(NimBLEAddress peer_addr); + static NimBLEClient* getClientByPeerAddress(const NimBLEAddress &peer_addr); static NimBLEClient* getDisconnectedClient(); - static size_t getClientListSize(); - static std::list* getClientList(); - + static size_t getClientListSize(); + static std::list* getClientList(); +#endif + private: - friend class NimBLEServer; +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) friend class NimBLEClient; +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) friend class NimBLEScan; - friend class NimBLEAdvertising; +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + friend class NimBLEServer; friend class NimBLECharacteristic; - +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + friend class NimBLEAdvertising; +#endif + static void onReset(int reason); static void onSync(void); static void host_task(void *param); - static int startSecurity( uint16_t conn_id); - - static bool m_synced; + static int startSecurity(uint16_t conn_id); + static bool m_synced; + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) static NimBLEScan* m_pScan; +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) static NimBLEServer* m_pServer; +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) static NimBLEAdvertising* m_bleAdvertising; - static ble_gap_event_listener m_listener; - static uint32_t m_passkey; +#endif + +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) static std::list m_cList; +#endif static std::list m_ignoreList; static NimBLESecurityCallbacks* m_securityCallbacks; + static uint32_t m_passkey; + static ble_gap_event_listener m_listener; public: static gap_event_handler m_customGapHandler; diff --git a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.cpp b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.cpp index b601d8de0..990a36f52 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.cpp @@ -3,7 +3,7 @@ * * Created: on March 15 2020 * Author H2zero - * + * * Originally: * * BLEEddystoneTLM.cpp @@ -26,41 +26,41 @@ static const char LOG_TAG[] = "NimBLEEddystoneTLM"; NimBLEEddystoneTLM::NimBLEEddystoneTLM() { - beaconUUID = 0xFEAA; - m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE; - m_eddystoneData.version = 0; - m_eddystoneData.volt = 3300; // 3300mV = 3.3V - m_eddystoneData.temp = (uint16_t) ((float) 23.00 * 256); // 8.8 fixed format - m_eddystoneData.advCount = 0; - m_eddystoneData.tmil = 0; + beaconUUID = 0xFEAA; + m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE; + m_eddystoneData.version = 0; + m_eddystoneData.volt = 3300; // 3300mV = 3.3V + m_eddystoneData.temp = (uint16_t) ((float) 23.00 * 256); // 8.8 fixed format + m_eddystoneData.advCount = 0; + m_eddystoneData.tmil = 0; } // NimBLEEddystoneTLM std::string NimBLEEddystoneTLM::getData() { - return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); + return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); } // getData NimBLEUUID NimBLEEddystoneTLM::getUUID() { - return NimBLEUUID(beaconUUID); + return NimBLEUUID(beaconUUID); } // getUUID uint8_t NimBLEEddystoneTLM::getVersion() { - return m_eddystoneData.version; + return m_eddystoneData.version; } // getVersion uint16_t NimBLEEddystoneTLM::getVolt() { - return ENDIAN_CHANGE_U16(m_eddystoneData.volt); + return ENDIAN_CHANGE_U16(m_eddystoneData.volt); } // getVolt float NimBLEEddystoneTLM::getTemp() { - return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f; + return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f; } // getTemp uint32_t NimBLEEddystoneTLM::getCount() { - return ENDIAN_CHANGE_U32(m_eddystoneData.advCount); + return ENDIAN_CHANGE_U32(m_eddystoneData.advCount); } // getCount uint32_t NimBLEEddystoneTLM::getTime() { - return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10; + return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10; } // getTime std::string NimBLEEddystoneTLM::toString() { @@ -116,37 +116,37 @@ std::string NimBLEEddystoneTLM::toString() { /** * Set the raw data for the beacon record. */ -void NimBLEEddystoneTLM::setData(std::string data) { - if (data.length() != sizeof(m_eddystoneData)) { - NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d", +void NimBLEEddystoneTLM::setData(const std::string &data) { + if (data.length() != sizeof(m_eddystoneData)) { + NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d", data.length(), sizeof(m_eddystoneData)); - return; - } + return; + } memcpy(&m_eddystoneData, data.data(), data.length()); } // setData -void NimBLEEddystoneTLM::setUUID(NimBLEUUID l_uuid) { - beaconUUID = l_uuid.getNative()->u16.value; +void NimBLEEddystoneTLM::setUUID(const NimBLEUUID &l_uuid) { + beaconUUID = l_uuid.getNative()->u16.value; } // setUUID void NimBLEEddystoneTLM::setVersion(uint8_t version) { - m_eddystoneData.version = version; + m_eddystoneData.version = version; } // setVersion void NimBLEEddystoneTLM::setVolt(uint16_t volt) { - m_eddystoneData.volt = volt; + m_eddystoneData.volt = volt; } // setVolt void NimBLEEddystoneTLM::setTemp(float temp) { - m_eddystoneData.temp = (uint16_t)temp; + m_eddystoneData.temp = (uint16_t)temp; } // setTemp void NimBLEEddystoneTLM::setCount(uint32_t advCount) { - m_eddystoneData.advCount = advCount; + m_eddystoneData.advCount = advCount; } // setCount void NimBLEEddystoneTLM::setTime(uint32_t tmil) { - m_eddystoneData.tmil = tmil; + m_eddystoneData.tmil = tmil; } // setTime #endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.h b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.h index 3c7219eb6..eb1cb0721 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.h @@ -3,7 +3,7 @@ * * Created: on March 15 2020 * Author H2zero - * + * * Originally: * * BLEEddystoneTLM.h @@ -27,33 +27,33 @@ */ class NimBLEEddystoneTLM { public: - NimBLEEddystoneTLM(); - std::string getData(); - NimBLEUUID getUUID(); - uint8_t getVersion(); - uint16_t getVolt(); - float getTemp(); - uint32_t getCount(); - uint32_t getTime(); - std::string toString(); - void setData(std::string data); - void setUUID(NimBLEUUID l_uuid); - void setVersion(uint8_t version); - void setVolt(uint16_t volt); - void setTemp(float temp); - void setCount(uint32_t advCount); - void setTime(uint32_t tmil); + NimBLEEddystoneTLM(); + std::string getData(); + NimBLEUUID getUUID(); + uint8_t getVersion(); + uint16_t getVolt(); + float getTemp(); + uint32_t getCount(); + uint32_t getTime(); + std::string toString(); + void setData(const std::string &data); + void setUUID(const NimBLEUUID &l_uuid); + void setVersion(uint8_t version); + void setVolt(uint16_t volt); + void setTemp(float temp); + void setCount(uint32_t advCount); + void setTime(uint32_t tmil); private: - uint16_t beaconUUID; - struct { - uint8_t frameType; - uint8_t version; - uint16_t volt; - uint16_t temp; - uint32_t advCount; - uint32_t tmil; - } __attribute__((packed)) m_eddystoneData; + uint16_t beaconUUID; + struct { + uint8_t frameType; + uint8_t version; + uint16_t volt; + uint16_t temp; + uint32_t advCount; + uint32_t tmil; + } __attribute__((packed)) m_eddystoneData; }; // NimBLEEddystoneTLM diff --git a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.cpp b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.cpp index c1d2aff6f..ce7975958 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.cpp @@ -3,7 +3,7 @@ * * Created: on March 15 2020 * Author H2zero - * + * * Originally: * * BLEEddystoneURL.cpp @@ -22,102 +22,102 @@ static const char LOG_TAG[] = "NimBLEEddystoneURL"; NimBLEEddystoneURL::NimBLEEddystoneURL() { - beaconUUID = 0xFEAA; - lengthURL = 0; - m_eddystoneData.frameType = EDDYSTONE_URL_FRAME_TYPE; - m_eddystoneData.advertisedTxPower = 0; - memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url)); + beaconUUID = 0xFEAA; + lengthURL = 0; + m_eddystoneData.frameType = EDDYSTONE_URL_FRAME_TYPE; + m_eddystoneData.advertisedTxPower = 0; + memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url)); } // BLEEddystoneURL std::string NimBLEEddystoneURL::getData() { - return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); + return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); } // getData NimBLEUUID NimBLEEddystoneURL::getUUID() { - return NimBLEUUID(beaconUUID); + return NimBLEUUID(beaconUUID); } // getUUID int8_t NimBLEEddystoneURL::getPower() { - return m_eddystoneData.advertisedTxPower; + return m_eddystoneData.advertisedTxPower; } // getPower std::string NimBLEEddystoneURL::getURL() { - return std::string((char*) &m_eddystoneData.url, sizeof(m_eddystoneData.url)); + return std::string((char*) &m_eddystoneData.url, sizeof(m_eddystoneData.url)); } // getURL std::string NimBLEEddystoneURL::getDecodedURL() { - std::string decodedURL = ""; + std::string decodedURL = ""; - switch (m_eddystoneData.url[0]) { - case 0x00: - decodedURL += "http://www."; - break; - case 0x01: - decodedURL += "https://www."; - break; - case 0x02: - decodedURL += "http://"; - break; - case 0x03: - decodedURL += "https://"; - break; - default: - decodedURL += m_eddystoneData.url[0]; - } + switch (m_eddystoneData.url[0]) { + case 0x00: + decodedURL += "http://www."; + break; + case 0x01: + decodedURL += "https://www."; + break; + case 0x02: + decodedURL += "http://"; + break; + case 0x03: + decodedURL += "https://"; + break; + default: + decodedURL += m_eddystoneData.url[0]; + } - for (int i = 1; i < lengthURL; i++) { - if (m_eddystoneData.url[i] > 33 && m_eddystoneData.url[i] < 127) { - decodedURL += m_eddystoneData.url[i]; - } else { - switch (m_eddystoneData.url[i]) { - case 0x00: - decodedURL += ".com/"; - break; - case 0x01: - decodedURL += ".org/"; - break; - case 0x02: - decodedURL += ".edu/"; - break; - case 0x03: - decodedURL += ".net/"; - break; - case 0x04: - decodedURL += ".info/"; - break; - case 0x05: - decodedURL += ".biz/"; - break; - case 0x06: - decodedURL += ".gov/"; - break; - case 0x07: - decodedURL += ".com"; - break; - case 0x08: - decodedURL += ".org"; - break; - case 0x09: - decodedURL += ".edu"; - break; - case 0x0A: - decodedURL += ".net"; - break; - case 0x0B: - decodedURL += ".info"; - break; - case 0x0C: - decodedURL += ".biz"; - break; - case 0x0D: - decodedURL += ".gov"; - break; - default: - break; - } - } - } - return decodedURL; + for (int i = 1; i < lengthURL; i++) { + if (m_eddystoneData.url[i] > 33 && m_eddystoneData.url[i] < 127) { + decodedURL += m_eddystoneData.url[i]; + } else { + switch (m_eddystoneData.url[i]) { + case 0x00: + decodedURL += ".com/"; + break; + case 0x01: + decodedURL += ".org/"; + break; + case 0x02: + decodedURL += ".edu/"; + break; + case 0x03: + decodedURL += ".net/"; + break; + case 0x04: + decodedURL += ".info/"; + break; + case 0x05: + decodedURL += ".biz/"; + break; + case 0x06: + decodedURL += ".gov/"; + break; + case 0x07: + decodedURL += ".com"; + break; + case 0x08: + decodedURL += ".org"; + break; + case 0x09: + decodedURL += ".edu"; + break; + case 0x0A: + decodedURL += ".net"; + break; + case 0x0B: + decodedURL += ".info"; + break; + case 0x0C: + decodedURL += ".biz"; + break; + case 0x0D: + decodedURL += ".gov"; + break; + default: + break; + } + } + } + return decodedURL; } // getDecodedURL @@ -125,30 +125,30 @@ std::string NimBLEEddystoneURL::getDecodedURL() { /** * Set the raw data for the beacon record. */ -void NimBLEEddystoneURL::setData(std::string data) { - if (data.length() > sizeof(m_eddystoneData)) { - NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and max expected %d", +void NimBLEEddystoneURL::setData(const std::string &data) { + if (data.length() > sizeof(m_eddystoneData)) { + NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and max expected %d", data.length(), sizeof(m_eddystoneData)); - return; - } - memset(&m_eddystoneData, 0, sizeof(m_eddystoneData)); - memcpy(&m_eddystoneData, data.data(), data.length()); - lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url)); + return; + } + memset(&m_eddystoneData, 0, sizeof(m_eddystoneData)); + memcpy(&m_eddystoneData, data.data(), data.length()); + lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url)); } // setData -void NimBLEEddystoneURL::setUUID(NimBLEUUID l_uuid) { - beaconUUID = l_uuid.getNative()->u16.value; +void NimBLEEddystoneURL::setUUID(const NimBLEUUID &l_uuid) { + beaconUUID = l_uuid.getNative()->u16.value; } // setUUID void NimBLEEddystoneURL::setPower(int8_t advertisedTxPower) { - m_eddystoneData.advertisedTxPower = advertisedTxPower; + m_eddystoneData.advertisedTxPower = advertisedTxPower; } // setPower -void NimBLEEddystoneURL::setURL(std::string url) { +void NimBLEEddystoneURL::setURL(const std::string &url) { if (url.length() > sizeof(m_eddystoneData.url)) { - NIMBLE_LOGE(LOG_TAG, "Unable to set the url ... length passed in was %d and max expected %d", + NIMBLE_LOGE(LOG_TAG, "Unable to set the url ... length passed in was %d and max expected %d", url.length(), sizeof(m_eddystoneData.url)); - return; + return; } memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url)); memcpy(m_eddystoneData.url, url.data(), url.length()); diff --git a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.h b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.h index 2e135886a..9c5f37f80 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.h @@ -3,7 +3,7 @@ * * Created: on March 15 2020 * Author H2zero - * + * * Originally: * * BLEEddystoneURL.h @@ -27,25 +27,25 @@ */ class NimBLEEddystoneURL { public: - NimBLEEddystoneURL(); - std::string getData(); - NimBLEUUID getUUID(); - int8_t getPower(); - std::string getURL(); - std::string getDecodedURL(); - void setData(std::string data); - void setUUID(NimBLEUUID l_uuid); - void setPower(int8_t advertisedTxPower); - void setURL(std::string url); + NimBLEEddystoneURL(); + std::string getData(); + NimBLEUUID getUUID(); + int8_t getPower(); + std::string getURL(); + std::string getDecodedURL(); + void setData(const std::string &data); + void setUUID(const NimBLEUUID &l_uuid); + void setPower(int8_t advertisedTxPower); + void setURL(const std::string &url); private: - uint16_t beaconUUID; - uint8_t lengthURL; - struct { - uint8_t frameType; - int8_t advertisedTxPower; - uint8_t url[16]; - } __attribute__((packed)) m_eddystoneData; + uint16_t beaconUUID; + uint8_t lengthURL; + struct { + uint8_t frameType; + int8_t advertisedTxPower; + uint8_t url[16]; + } __attribute__((packed)) m_eddystoneData; }; // NIMBLEEddystoneURL diff --git a/libesp32/NimBLE-Arduino/src/NimBLELog.h b/libesp32/NimBLE-Arduino/src/NimBLELog.h index d223a046e..b519c0faa 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLELog.h +++ b/libesp32/NimBLE-Arduino/src/NimBLELog.h @@ -14,11 +14,11 @@ #include "modlog/modlog.h" -// If Arduino is being used, strip out the colors and ignore log printing below ui setting. -// Note: because CONFIG_LOG_DEFAULT_LEVEL is set at ERROR in Arduino we must use MODLOG_DFLT(ERROR +// If Arduino is being used, strip out the colors and ignore log printing below ui setting. +// Note: because CONFIG_LOG_DEFAULT_LEVEL is set at ERROR in Arduino we must use MODLOG_DFLT(ERROR // otherwise no messages will be printed above that level. #ifdef ARDUINO_ARCH_ESP32 -#ifndef CORE_DEBUG_LEVEL +#ifndef CORE_DEBUG_LEVEL #define CORE_DEBUG_LEVEL CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL #endif @@ -48,7 +48,7 @@ #define NIMBLE_LOGC( tag, format, ... ) MODLOG_DFLT(CRITICAL, "CRIT %s: "#format"\n",tag,##__VA_ARGS__) -#else +#else #define NIMBLE_LOGE( tag, format, ... ) MODLOG_DFLT(ERROR, "\033[0;31mE %s: "#format"\033[0m\n",tag,##__VA_ARGS__) #define NIMBLE_LOGW( tag, format, ... ) MODLOG_DFLT(WARN, "\033[0;33mW %s: "#format"\033[0m\n",tag,##__VA_ARGS__) #define NIMBLE_LOGI( tag, format, ... ) MODLOG_DFLT(INFO, "\033[0;32mI %s: "#format"\033[0m\n",tag,##__VA_ARGS__) diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp index a48354c57..85760b433 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp @@ -3,7 +3,7 @@ * * Created: on Jan 27 2020 * Author H2zero - * + * * Originally: * * BLERemoteCharacteristic.cpp @@ -15,6 +15,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + #include "NimBLERemoteCharacteristic.h" #include "NimBLEUtils.h" #include "NimBLELog.h" @@ -32,27 +35,31 @@ static const char* LOG_TAG = "NimBLERemoteCharacteristic"; * ble_uuid_any_t uuid; * }; */ - NimBLERemoteCharacteristic::NimBLERemoteCharacteristic(NimBLERemoteService *pRemoteService, const struct ble_gatt_chr *chr) { + NimBLERemoteCharacteristic::NimBLERemoteCharacteristic(NimBLERemoteService *pRemoteService, + const struct ble_gatt_chr *chr) +{ switch (chr->uuid.u.type) { - case BLE_UUID_TYPE_16: + case BLE_UUID_TYPE_16: m_uuid = NimBLEUUID(chr->uuid.u16.value); break; - case BLE_UUID_TYPE_32: + case BLE_UUID_TYPE_32: m_uuid = NimBLEUUID(chr->uuid.u32.value); break; - case BLE_UUID_TYPE_128: + case BLE_UUID_TYPE_128: m_uuid = NimBLEUUID(const_cast(&chr->uuid.u128)); break; default: m_uuid = nullptr; break; } - m_handle = chr->val_handle; - m_defHandle = chr->def_handle; - m_charProp = chr->properties; - m_pRemoteService = pRemoteService; - m_notifyCallback = nullptr; + m_handle = chr->val_handle; + m_defHandle = chr->def_handle; + m_charProp = chr->properties; + m_pRemoteService = pRemoteService; + m_notifyCallback = nullptr; + m_rawData = nullptr; + m_dataLen = 0; } // NimBLERemoteCharacteristic @@ -61,7 +68,9 @@ static const char* LOG_TAG = "NimBLERemoteCharacteristic"; */ NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() { removeDescriptors(); // Release resources for any descriptor information we may have allocated. - if(m_rawData != nullptr) free(m_rawData); + if(m_rawData != nullptr) { + free(m_rawData); + } } // ~NimBLERemoteCharacteristic /* @@ -132,91 +141,170 @@ bool NimBLERemoteCharacteristic::canWriteNoResponse() { /** * @brief Callback used by the API when a descriptor is discovered or search complete. */ -int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, +int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, const struct ble_gatt_error *error, - uint16_t chr_val_handle, + uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, - void *arg) + void *arg) { - NIMBLE_LOGD(LOG_TAG,"Descriptor Discovered >> status: %d handle: %d", error->status, conn_handle); - - NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)arg; + NIMBLE_LOGD(LOG_TAG,"Descriptor Discovered >> status: %d handle: %d", + error->status, (error->status == 0) ? dsc->handle : -1); + + disc_filter_t *filter = (disc_filter_t*)arg; + NimBLEUUID *uuid_filter = (NimBLEUUID*)filter->uuid; + NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)filter->attribute; int rc=0; // Make sure the discovery is for this device if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ return 0; } - + switch (error->status) { case 0: { - // Found a descriptor - add it to the map + if(dsc->uuid.u.type == BLE_UUID_TYPE_16 && dsc->uuid.u16.value == uint16_t(0x2803)) { + NIMBLE_LOGD(LOG_TAG,"Descriptor NOT found - end of Characteristic definintion"); + rc = BLE_HS_EDONE; + break; + } + if(uuid_filter != nullptr) { + if(ble_uuid_cmp(&uuid_filter->getNative()->u, &dsc->uuid.u) != 0) { + return 0; + } else { + NIMBLE_LOGD(LOG_TAG,"Descriptor Found"); + rc = BLE_HS_EDONE; + } + } + // Found a descriptor - add it to the vector NimBLERemoteDescriptor* pNewRemoteDescriptor = new NimBLERemoteDescriptor(characteristic, dsc); - characteristic->m_descriptorMap.insert(std::pair(pNewRemoteDescriptor->getUUID().toString(), pNewRemoteDescriptor)); - - break; - } - case BLE_HS_EDONE:{ - /* All descriptors in this characteristic discovered; */ - characteristic->m_semaphoreGetDescEvt.give(0); - rc = 0; + characteristic->m_descriptorVector.push_back(pNewRemoteDescriptor); break; } default: rc = error->status; break; } - if (rc != 0) { + + /** If rc == BLE_HS_EDONE, release the semaphore with a success error code and stop the discovery process. + * Else if rc == 0, just return 0 to continue the discovery until we get BLE_HS_EDONE. + * If we get any other error code tell the application to abort by returning non-zero in the semaphore rc. + */ + if (rc == BLE_HS_EDONE) { + characteristic->m_semaphoreGetDescEvt.give(0); + } else if(rc != 0) { /* Error; abort discovery. */ - // pass non-zero to semaphore on error to indicate an error finding descriptors - characteristic->m_semaphoreGetDescEvt.give(1); + // pass error code to semaphore waiting + characteristic->m_semaphoreGetDescEvt.give(rc); } NIMBLE_LOGD(LOG_TAG,"<< Descriptor Discovered. status: %d", rc); return rc; } + /** * @brief Populate the descriptors (if any) for this characteristic. * @param [in] the end handle of the characteristic, or the service, whichever comes first. */ -bool NimBLERemoteCharacteristic::retrieveDescriptors(uint16_t endHdl) { +bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filter) { NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str()); int rc = 0; - //removeDescriptors(); // Remove any existing descriptors. - + disc_filter_t filter; + filter.uuid = uuid_filter; + filter.attribute = this; + m_semaphoreGetDescEvt.take("retrieveDescriptors"); - + rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(), m_handle, - endHdl, + getRemoteService()->getEndHandle(), NimBLERemoteCharacteristic::descriptorDiscCB, - this); + &filter); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); m_semaphoreGetDescEvt.give(); return false; } - - if(m_semaphoreGetDescEvt.wait("retrieveCharacteristics") != 0) { - // if there was an error release the resources - //removeDescriptors(); + + if(m_semaphoreGetDescEvt.wait("retrieveDescriptors") != 0) { return false; } - + return true; - NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", m_descriptorMap.size()); + NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", m_descriptorVector.size()); } // getDescriptors /** - * @brief Retrieve the map of descriptors keyed by UUID. - */ -std::map* NimBLERemoteCharacteristic::getDescriptors() { - return &m_descriptorMap; + * @brief Get the descriptor instance with the given UUID that belongs to this characteristic. + * @param [in] uuid The UUID of the descriptor to find. + * @return The Remote descriptor (if present) or null if not present. + */ +NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID &uuid) { + NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str()); + + for(auto &it: m_descriptorVector) { + if(it->getUUID() == uuid) { + NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: found"); + return it; + } + } + + size_t prev_size = m_descriptorVector.size(); + if(retrieveDescriptors(&uuid)) { + if(m_descriptorVector.size() > prev_size) { + return m_descriptorVector.back(); + } + } + NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: Not found"); + return nullptr; +} // getDescriptor + + +/** + * @Get a pointer to the vector of found descriptors. + * @param [in] bool value to indicate if the current vector should be cleared and + * subsequently all descriptors for this characteristic retrieved from the peripheral. + * If false the vector will be returned with the currently stored descriptors, + * if the vector is empty it will retrieve all descriptors for this characteristic + * from the peripheral. + * @return a pointer to the vector of descriptors for this characteristic. + */ +std::vector* NimBLERemoteCharacteristic::getDescriptors(bool refresh) { + if(refresh) { + removeDescriptors(); + } + + if(m_descriptorVector.empty()) { + if (!retrieveDescriptors()) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to get descriptors"); + } + else{ + NIMBLE_LOGI(LOG_TAG, "Found %d descriptor(s)", m_descriptorVector.size()); + } + } + return &m_descriptorVector; } // getDescriptors +/** + * @brief Get iterator to the beginning of the vector of remote descriptor pointers. + * @return An iterator to the beginning of the vector of remote descriptor pointers. + */ +std::vector::iterator NimBLERemoteCharacteristic::begin() { + return m_descriptorVector.begin(); +} + + +/** + * @brief Get iterator to the end of the vector of remote descriptor pointers. + * @return An iterator to the end of the vector of remote descriptor pointers. + */ +std::vector::iterator NimBLERemoteCharacteristic::end() { + return m_descriptorVector.end(); +} + + /** * @brief Get the handle for this characteristic. * @return The handle for this characteristic. @@ -234,25 +322,6 @@ uint16_t NimBLERemoteCharacteristic::getDefHandle() { } // getDefHandle -/** - * @brief Get the descriptor instance with the given UUID that belongs to this characteristic. - * @param [in] uuid The UUID of the descriptor to find. - * @return The Remote descriptor (if present) or null if not present. - */ -NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(NimBLEUUID uuid) { - NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str()); - std::string v = uuid.toString(); - for (auto &myPair : m_descriptorMap) { - if (myPair.first == v) { - NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: found"); - return myPair.second; - } - } - NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: Not found"); - return nullptr; -} // getDescriptor - - /** * @brief Get the remote service associated with this characteristic. * @return The remote service associated with this characteristic. @@ -309,19 +378,22 @@ uint8_t NimBLERemoteCharacteristic::readUInt8() { return 0; } // readUInt8 - + /** * @brief Read the value of the remote characteristic. * @return The value of the remote characteristic. */ std::string NimBLERemoteCharacteristic::readValue() { - NIMBLE_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x", getUUID().toString().c_str(), getHandle(), getHandle()); + NIMBLE_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x", + getUUID().toString().c_str(), getHandle(), getHandle()); int rc = 0; int retryCount = 1; + // Clear the value before reading. + m_value = ""; NimBLEClient* pClient = getRemoteService()->getClient(); - + // Check to see that we are connected. if (!pClient->isConnected()) { NIMBLE_LOGE(LOG_TAG, "Disconnected"); @@ -330,38 +402,41 @@ std::string NimBLERemoteCharacteristic::readValue() { do { m_semaphoreReadCharEvt.take("readValue"); - - rc = ble_gattc_read(pClient->getConnId(), m_handle, - NimBLERemoteCharacteristic::onReadCB, this); - -// long read experiment -/* rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, - NimBLERemoteCharacteristic::onReadCB, this); -*/ + + rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, + NimBLERemoteCharacteristic::onReadCB, + this); if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "Error: Failed to read characteristic; rc=%d", rc); - m_semaphoreReadCharEvt.give(); + NIMBLE_LOGE(LOG_TAG, "Error: Failed to read characteristic; rc=%d, %s", + rc, NimBLEUtils::returnCodeToString(rc)); + m_semaphoreReadCharEvt.give(0); return ""; } - + rc = m_semaphoreReadCharEvt.wait("readValue"); switch(rc){ case 0: + case BLE_HS_EDONE: + rc = 0; + break; + // Characteristic is not long-readable, return with what we have. + case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): + NIMBLE_LOGI(LOG_TAG, "Attribute not long"); + rc = 0; break; - case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): if (retryCount && pClient->secureConnection()) break; - /* Else falls through. */ + /* Else falls through. */ default: return ""; } } while(rc != 0 && retryCount--); - + NIMBLE_LOGD(LOG_TAG, "<< readValue(): length: %d", m_value.length()); - return (rc == 0) ? m_value : ""; + return m_value; } // readValue @@ -371,39 +446,28 @@ std::string NimBLERemoteCharacteristic::readValue() { */ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, void *arg) + struct ble_gatt_attr *attr, void *arg) { NimBLERemoteCharacteristic* characteristic = (NimBLERemoteCharacteristic*)arg; - - // Make sure the discovery is for this device - if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ + uint16_t conn_id = characteristic->getRemoteService()->getClient()->getConnId(); + + // Make sure the read is for this client + if(conn_id != conn_handle) { return 0; } NIMBLE_LOGI(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle); -// long read experiment -/* if(attr && (attr->om->om_len >= (ble_att_mtu(characteristic->getRemoteService()->getClient()->getConnId()) - 1))){ - - return 0; + + if(error->status == 0) { + if(attr) { + NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len); + + characteristic->m_value += std::string((char*) attr->om->om_data, attr->om->om_len); + return 0; + } } -*/ - - if(characteristic->m_rawData != nullptr) { - free(characteristic->m_rawData); - } - - if (error->status == 0) { - characteristic->m_value = std::string((char*) attr->om->om_data, attr->om->om_len); - characteristic->m_rawData = (uint8_t*) calloc(attr->om->om_len, sizeof(uint8_t)); - memcpy(characteristic->m_rawData, attr->om->om_data, attr->om->om_len); - characteristic->m_semaphoreReadCharEvt.give(0); - } else { - characteristic->m_rawData = nullptr; - characteristic->m_value = ""; - characteristic->m_semaphoreReadCharEvt.give(error->status); - } - -// characteristic->m_semaphoreReadCharEvt.give(error->status); - return 0; //1 + // Read complete release semaphore and let the app can continue. + characteristic->m_semaphoreReadCharEvt.give(error->status); + return 0; } @@ -423,7 +487,7 @@ bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallbac uint8_t val[] = {0x01, 0x00}; NimBLERemoteDescriptor* desc = getDescriptor(NimBLEUUID((uint16_t)0x2902)); - if(desc == nullptr) + if(desc == nullptr) return false; if(notifyCallback != nullptr){ @@ -437,25 +501,24 @@ bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallbac } NIMBLE_LOGD(LOG_TAG, "<< registerForNotify()"); - + return desc->writeValue(val, 2, response); } // registerForNotify /** - * @brief Delete the descriptors in the descriptor map. - * We maintain a map called m_descriptorMap that contains pointers to BLERemoteDescriptors - * object references. Since we allocated these in this class, we are also responsible for deleteing - * them. This method does just that. + * @brief Delete the descriptors in the descriptor vector. + * We maintain a vector called m_descriptorVector that contains pointers to BLERemoteDescriptors + * object references. Since we allocated these in this class, we are also responsible for deleteing + * them. This method does just that. * @return N/A. */ void NimBLERemoteCharacteristic::removeDescriptors() { - // Iterate through all the descriptors releasing their storage and erasing them from the map. - for (auto &myPair : m_descriptorMap) { - m_descriptorMap.erase(myPair.first); - delete myPair.second; + // Iterate through all the descriptors releasing their storage and erasing them from the vector. + for(auto &it: m_descriptorVector) { + delete it; } - m_descriptorMap.clear(); // Technically not neeeded, but just to be sure. + m_descriptorVector.clear(); } // removeCharacteristics @@ -476,11 +539,11 @@ std::string NimBLERemoteCharacteristic::toString() { res += " 0x"; snprintf(val, sizeof(val), "%02x", m_charProp); res += val; - - for (auto &myPair : m_descriptorMap) { - res += "\n" + myPair.second->toString(); + + for(auto &it: m_descriptorVector) { + res += "\n" + it->toString(); } - + return res; } // toString @@ -491,7 +554,7 @@ std::string NimBLERemoteCharacteristic::toString() { * @param [in] response Do we expect a response? * @return false if not connected or cant perform write for some reason. */ -bool NimBLERemoteCharacteristic::writeValue(std::string newValue, bool response) { +bool NimBLERemoteCharacteristic::writeValue(const std::string &newValue, bool response) { return writeValue((uint8_t*)newValue.c_str(), strlen(newValue.c_str()), response); } // writeValue @@ -516,62 +579,70 @@ bool NimBLERemoteCharacteristic::writeValue(uint8_t newValue, bool response) { * @param [in] response Whether we require a response from the write. * @return false if not connected or cant perform write for some reason. */ -bool NimBLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool response) { - +bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length, bool response) { + NIMBLE_LOGD(LOG_TAG, ">> writeValue(), length: %d", length); - + NimBLEClient* pClient = getRemoteService()->getClient(); int rc = 0; int retryCount = 1; -// uint16_t mtu; - + uint16_t mtu; + // Check to see that we are connected. if (!pClient->isConnected()) { NIMBLE_LOGE(LOG_TAG, "Disconnected"); return false; } - -// mtu = ble_att_mtu(pClient->getConnId()) - 3; - if(/*!length > mtu &&*/ !response) { + mtu = ble_att_mtu(pClient->getConnId()) - 3; + + // Check if the data length is longer than we can write in 1 connection event. + // If so we must do a long write which requires a response. + if(length <= mtu && !response) { rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length); return (rc==0); } - + do { m_semaphoreWriteCharEvt.take("writeValue"); -// long write experiment -/* if(length > mtu) { - NIMBLE_LOGD(LOG_TAG,"long write"); + + if(length > mtu) { + NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length); os_mbuf *om = ble_hs_mbuf_from_flat(data, length); rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om, - NimBLERemoteCharacteristic::onWriteCB, + NimBLERemoteCharacteristic::onWriteCB, this); } else { -*/ - rc = ble_gattc_write_flat(pClient->getConnId(), m_handle, - data, length, - NimBLERemoteCharacteristic::onWriteCB, - this); -// } + rc = ble_gattc_write_flat(pClient->getConnId(), m_handle, + data, length, + NimBLERemoteCharacteristic::onWriteCB, + this); + } if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "Error: Failed to write characteristic; rc=%d", rc); m_semaphoreWriteCharEvt.give(); return false; } - + rc = m_semaphoreWriteCharEvt.wait("writeValue"); switch(rc){ case 0: + case BLE_HS_EDONE: + rc = 0; break; - + case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): + NIMBLE_LOGE(LOG_TAG, "Long write not supported by peer; Truncating length to %d", mtu); + retryCount++; + length = mtu; + break; + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): if (retryCount && pClient->secureConnection()) break; - /* Else falls through. */ + /* Else falls through. */ default: return false; } @@ -588,44 +659,61 @@ bool NimBLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool r */ int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, void *arg) + struct ble_gatt_attr *attr, void *arg) { NimBLERemoteCharacteristic* characteristic = (NimBLERemoteCharacteristic*)arg; - - // Make sure the discovery is for this device + + // Make sure the discovery is for this device if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ return 0; } - + NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle); - - if (error->status == 0) { - characteristic->m_semaphoreWriteCharEvt.give(0); - } else { + characteristic->m_semaphoreWriteCharEvt.give(error->status); - characteristic->m_semaphoreWriteCharEvt.give(error->status); - } - return 0; } /** * @brief Read raw data from remote characteristic as hex bytes - * @return return pointer data read + * @return uint8_t pointer to the data read. */ uint8_t* NimBLERemoteCharacteristic::readRawData() { + if(m_rawData != nullptr) { + free(m_rawData); + m_rawData = nullptr; + } + + m_dataLen = m_value.length(); + // If we have data copy it to rawData + if(m_dataLen) { + m_rawData = (uint8_t*) calloc(m_dataLen, sizeof(uint8_t)); + memcpy(m_rawData, m_value.data(), m_dataLen); + } + return m_rawData; } +/** + * @brief Get the length of the data read from the remote characteristic. + * @return size_t length of the data in bytes. + */ +size_t NimBLERemoteCharacteristic::getDataLength() { + return m_value.length(); +} + + void NimBLERemoteCharacteristic::releaseSemaphores() { - for (auto &dPair : m_descriptorMap) { - dPair.second->releaseSemaphores(); + for (auto &it: m_descriptorVector) { + it->releaseSemaphores(); } m_semaphoreWriteCharEvt.give(1); m_semaphoreGetDescEvt.give(1); m_semaphoreReadCharEvt.give(1); } + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h index c107be79d..0b7d490d6 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h @@ -3,7 +3,7 @@ * * Created: on Jan 27 2020 * Author H2zero - * + * * Originally: * * BLERemoteCharacteristic.h @@ -17,19 +17,20 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) -//#include "NimBLEUUID.h" -//#include "FreeRTOS.h" +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + #include "NimBLERemoteService.h" #include "NimBLERemoteDescriptor.h" -//#include -#include +#include class NimBLERemoteService; class NimBLERemoteDescriptor; -typedef void (*notify_callback)(NimBLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify); +typedef void (*notify_callback)(NimBLERemoteCharacteristic* pBLERemoteCharacteristic, + uint8_t* pData, size_t length, bool isNotify); /** * @brief A model of a remote %BLE characteristic. @@ -39,47 +40,58 @@ public: ~NimBLERemoteCharacteristic(); // Public member functions - bool canBroadcast(); - bool canIndicate(); - bool canNotify(); - bool canRead(); - bool canWrite(); - bool canWriteNoResponse(); - NimBLERemoteDescriptor* getDescriptor(NimBLEUUID uuid); - std::map* getDescriptors(); - uint16_t getHandle(); - uint16_t getDefHandle(); - NimBLEUUID getUUID(); - std::string readValue(); - uint8_t readUInt8(); - uint16_t readUInt16(); - uint32_t readUInt32(); - bool registerForNotify(notify_callback _callback, bool notifications = true, bool response = true); - bool writeValue(uint8_t* data, size_t length, bool response = false); - bool writeValue(std::string newValue, bool response = false); - bool writeValue(uint8_t newValue, bool response = false); - std::string toString(); - uint8_t* readRawData(); - NimBLERemoteService* getRemoteService(); + bool canBroadcast(); + bool canIndicate(); + bool canNotify(); + bool canRead(); + bool canWrite(); + bool canWriteNoResponse(); + std::vector::iterator begin(); + std::vector::iterator end(); + NimBLERemoteDescriptor* getDescriptor(const NimBLEUUID &uuid); + std::vector* getDescriptors(bool refresh = false); + uint16_t getHandle(); + uint16_t getDefHandle(); + NimBLEUUID getUUID(); + std::string readValue(); + uint8_t readUInt8(); + uint16_t readUInt16(); + uint32_t readUInt32(); + bool registerForNotify(notify_callback _callback, + bool notifications = true, + bool response = true); + bool writeValue(const uint8_t* data, + size_t length, + bool response = false); + bool writeValue(const std::string &newValue, + bool response = false); + bool writeValue(uint8_t newValue, + bool response = false); + std::string toString(); + uint8_t* readRawData(); + size_t getDataLength(); + NimBLERemoteService* getRemoteService(); private: NimBLERemoteCharacteristic(NimBLERemoteService *pRemoteservice, const struct ble_gatt_chr *chr); - - friend class NimBLEClient; - friend class NimBLERemoteService; - friend class NimBLERemoteDescriptor; + + friend class NimBLEClient; + friend class NimBLERemoteService; + friend class NimBLERemoteDescriptor; // Private member functions void removeDescriptors(); - bool retrieveDescriptors(uint16_t endHdl); - static int onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg); - static int onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg); + bool retrieveDescriptors(const NimBLEUUID *uuid_filter = nullptr); + static int onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg); + static int onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg); void releaseSemaphores(); static int descriptorDiscCB(uint16_t conn_handle, const struct ble_gatt_error *error, - uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, - void *arg); - + uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, + void *arg); + // Private properties NimBLEUUID m_uuid; uint8_t m_charProp; @@ -90,11 +102,14 @@ private: FreeRTOS::Semaphore m_semaphoreReadCharEvt = FreeRTOS::Semaphore("ReadCharEvt"); FreeRTOS::Semaphore m_semaphoreWriteCharEvt = FreeRTOS::Semaphore("WriteCharEvt"); std::string m_value; - uint8_t* m_rawData = nullptr; + uint8_t* m_rawData; + size_t m_dataLen; notify_callback m_notifyCallback; - // We maintain a map of descriptors owned by this characteristic keyed by a string representation of the UUID. - std::map m_descriptorMap; -}; // BLERemoteCharacteristic + // We maintain a vector of descriptors owned by this characteristic. + std::vector m_descriptorVector; +}; // NimBLERemoteCharacteristic + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ #endif /* COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp index d862a8cd0..057a68a1c 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp @@ -3,7 +3,7 @@ * * Created: on Jan 27 2020 * Author H2zero - * + * * Originally: * * BLERemoteDescriptor.cpp @@ -14,7 +14,11 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + #include "NimBLERemoteDescriptor.h" +#include "NimBLEUtils.h" #include "NimBLELog.h" static const char* LOG_TAG = "NimBLERemoteDescriptor"; @@ -24,17 +28,17 @@ static const char* LOG_TAG = "NimBLERemoteDescriptor"; * @param [in] Reference to the Characteristic that this belongs to. * @param [in] Reference to the struct that contains the descriptor information. */ -NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemoteCharacteristic, - const struct ble_gatt_dsc *dsc) +NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemoteCharacteristic, + const struct ble_gatt_dsc *dsc) { switch (dsc->uuid.u.type) { - case BLE_UUID_TYPE_16: + case BLE_UUID_TYPE_16: m_uuid = NimBLEUUID(dsc->uuid.u16.value); break; - case BLE_UUID_TYPE_32: + case BLE_UUID_TYPE_32: m_uuid = NimBLEUUID(dsc->uuid.u32.value); break; - case BLE_UUID_TYPE_128: + case BLE_UUID_TYPE_128: m_uuid = NimBLEUUID(const_cast(&dsc->uuid.u128)); break; default: @@ -43,7 +47,7 @@ NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemo } m_handle = dsc->handle; m_pRemoteCharacteristic = pRemoteCharacteristic; - + } @@ -80,75 +84,87 @@ NimBLEUUID NimBLERemoteDescriptor::getUUID() { */ int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, void *arg) + struct ble_gatt_attr *attr, void *arg) { NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)arg; - + uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId(); + // Make sure the discovery is for this device - if(desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId() != conn_handle){ + if(conn_id != conn_handle){ return 0; } - + NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle); - - if (error->status == 0) { - desc->m_value = std::string((char*) attr->om->om_data, attr->om->om_len); - desc->m_semaphoreReadDescrEvt.give(0); - } else { - desc->m_value = ""; - desc->m_semaphoreReadDescrEvt.give(error->status); + + if(error->status == 0){ + if(attr){ + NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len); + + desc->m_value += std::string((char*) attr->om->om_data, attr->om->om_len); + return 0; + } } - + + // Read complete release semaphore and let the app can continue. + desc->m_semaphoreReadDescrEvt.give(error->status); return 0; } std::string NimBLERemoteDescriptor::readValue() { NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str()); - - NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient(); - + int rc = 0; int retryCount = 1; - + // Clear the value before reading. + m_value = ""; + + NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient(); + // Check to see that we are connected. if (!pClient->isConnected()) { NIMBLE_LOGE(LOG_TAG, "Disconnected"); return ""; } - + do { m_semaphoreReadDescrEvt.take("ReadDescriptor"); - - rc = ble_gattc_read(pClient->getConnId(), m_handle, - NimBLERemoteDescriptor::onReadCB, this); - + + rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, + NimBLERemoteDescriptor::onReadCB, + this); if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "Descriptor read failed, code: %d", rc); - m_semaphoreReadDescrEvt.give(); + NIMBLE_LOGE(LOG_TAG, "Error: Failed to read descriptor; rc=%d, %s", + rc, NimBLEUtils::returnCodeToString(rc)); + m_semaphoreReadDescrEvt.give(0); return ""; } - + rc = m_semaphoreReadDescrEvt.wait("ReadDescriptor"); switch(rc){ case 0: + case BLE_HS_EDONE: + rc = 0; + break; + // Descriptor is not long-readable, return with what we have. + case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): + NIMBLE_LOGI(LOG_TAG, "Attribute not long"); + rc = 0; break; - case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): if (retryCount && pClient->secureConnection()) break; - /* Else falls through. */ + /* Else falls through. */ default: return ""; } } while(rc != 0 && retryCount--); - NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %d, rc: %d", m_value.length(), rc); - - return (rc == 0) ? m_value : ""; + NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %d", m_value.length()); + return m_value; } // readValue @@ -189,7 +205,7 @@ std::string NimBLERemoteDescriptor::toString() { res += ", handle: "; snprintf(val, sizeof(val), "%d", getHandle()); res += val; - + return res; } // toString @@ -200,23 +216,19 @@ std::string NimBLERemoteDescriptor::toString() { */ int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, void *arg) + struct ble_gatt_attr *attr, void *arg) { NimBLERemoteDescriptor* descriptor = (NimBLERemoteDescriptor*)arg; - - // Make sure the discovery is for this device + + // Make sure the discovery is for this device if(descriptor->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId() != conn_handle){ return 0; } - + NIMBLE_LOGD(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle); - - if (error->status == 0) { - descriptor->m_semaphoreDescWrite.give(0); - } else { - descriptor->m_semaphoreDescWrite.give(error->status); - } - + + descriptor->m_semaphoreDescWrite.give(error->status); + return 0; } @@ -227,58 +239,79 @@ int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle, * @param [in] length The length of the data to send. * @param [in] response True if we expect a response. */ -bool NimBLERemoteDescriptor::writeValue(uint8_t* data, size_t length, bool response) { +bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool response) { NIMBLE_LOGD(LOG_TAG, ">> Descriptor writeValue: %s", toString().c_str()); - + NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient(); - + int rc = 0; int retryCount = 1; - + uint16_t mtu; + // Check to see that we are connected. if (!pClient->isConnected()) { NIMBLE_LOGE(LOG_TAG, "Disconnected"); return false; } - - if(!response) { + + mtu = ble_att_mtu(pClient->getConnId()) - 3; + + // Check if the data length is longer than we can write in 1 connection event. + // If so we must do a long write which requires a response. + if(length <= mtu && !response) { rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length); - return (rc==0); + return (rc == 0); } - + do { m_semaphoreDescWrite.take("WriteDescriptor"); - - rc = ble_gattc_write_flat(pClient->getConnId(), m_handle, - data, length, - NimBLERemoteDescriptor::onWriteCB, - this); + + if(length > mtu) { + NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length); + os_mbuf *om = ble_hs_mbuf_from_flat(data, length); + rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om, + NimBLERemoteDescriptor::onWriteCB, + this); + } else { + rc = ble_gattc_write_flat(pClient->getConnId(), m_handle, + data, length, + NimBLERemoteDescriptor::onWriteCB, + this); + } + if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "Error: Failed to write descriptor; rc=%d", rc); m_semaphoreDescWrite.give(); return false; } - + rc = m_semaphoreDescWrite.wait("WriteDescriptor"); switch(rc){ case 0: + case BLE_HS_EDONE: + rc = 0; break; - + case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): + NIMBLE_LOGE(LOG_TAG, "Long write not supported by peer; Truncating length to %d", mtu); + retryCount++; + length = mtu; + break; + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): if (retryCount && pClient->secureConnection()) break; - /* Else falls through. */ + /* Else falls through. */ default: return false; } } while(rc != 0 && retryCount--); NIMBLE_LOGD(LOG_TAG, "<< Descriptor writeValue, rc: %d",rc); - return (rc == 0); //true; + return (rc == 0); } // writeValue @@ -287,7 +320,7 @@ bool NimBLERemoteDescriptor::writeValue(uint8_t* data, size_t length, bool respo * @param [in] newValue The data to send to the remote descriptor. * @param [in] response True if we expect a response. */ -bool NimBLERemoteDescriptor::writeValue(std::string newValue, bool response) { +bool NimBLERemoteDescriptor::writeValue(const std::string &newValue, bool response) { return writeValue((uint8_t*) newValue.data(), newValue.length(), response); } // writeValue @@ -309,4 +342,6 @@ void NimBLERemoteDescriptor::releaseSemaphores() { m_semaphoreDescWrite.give(1); m_semaphoreReadDescrEvt.give(1); } + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h index 004d89705..23fe13f6b 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h @@ -3,7 +3,7 @@ * * Created: on Jan 27 2020 * Author H2zero - * + * * Originally: * * BLERemoteDescriptor.h @@ -17,6 +17,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + #include "NimBLERemoteCharacteristic.h" class NimBLERemoteCharacteristic; @@ -25,34 +28,40 @@ class NimBLERemoteCharacteristic; */ class NimBLERemoteDescriptor { public: - uint16_t getHandle(); + uint16_t getHandle(); NimBLERemoteCharacteristic* getRemoteCharacteristic(); - NimBLEUUID getUUID(); - std::string readValue(void); - uint8_t readUInt8(void); - uint16_t readUInt16(void); - uint32_t readUInt32(void); - std::string toString(void); - bool writeValue(uint8_t* data, size_t length, bool response = false); - bool writeValue(std::string newValue, bool response = false); - bool writeValue(uint8_t newValue, bool response = false); + NimBLEUUID getUUID(); + std::string readValue(void); + uint8_t readUInt8(void); + uint16_t readUInt16(void); + uint32_t readUInt32(void); + std::string toString(void); + bool writeValue(const uint8_t* data, size_t length, bool response = false); + bool writeValue(const std::string &newValue, bool response = false); + bool writeValue(uint8_t newValue, bool response = false); private: - friend class NimBLERemoteCharacteristic; - NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemoteCharacteristic, const struct ble_gatt_dsc *dsc); - static int onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg); - static int onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg); - void releaseSemaphores(); + friend class NimBLERemoteCharacteristic; - uint16_t m_handle; // Server handle of this descriptor. - NimBLEUUID m_uuid; // UUID of this descriptor. - std::string m_value; // Last received value of the descriptor. - NimBLERemoteCharacteristic* m_pRemoteCharacteristic; // Reference to the Remote characteristic of which this descriptor is associated. + NimBLERemoteDescriptor (NimBLERemoteCharacteristic* pRemoteCharacteristic, + const struct ble_gatt_dsc *dsc); + static int onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg); + static int onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg); + void releaseSemaphores(); + + uint16_t m_handle; + NimBLEUUID m_uuid; + std::string m_value; + NimBLERemoteCharacteristic* m_pRemoteCharacteristic; FreeRTOS::Semaphore m_semaphoreReadDescrEvt = FreeRTOS::Semaphore("ReadDescrEvt"); FreeRTOS::Semaphore m_semaphoreDescWrite = FreeRTOS::Semaphore("WriteDescEvt"); }; + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ #endif /* COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp index 28c2cc33e..193a40b1a 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp @@ -3,7 +3,7 @@ * * Created: on Jan 27 2020 * Author H2zero - * + * * Originally: * * BLERemoteService.cpp @@ -14,6 +14,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + #include "NimBLERemoteService.h" #include "NimBLEUtils.h" #include "NimBLEDevice.h" @@ -25,19 +28,19 @@ static const char* LOG_TAG = "NimBLERemoteService"; * @brief Remote Service constructor. * @param [in] Reference to the client this belongs to. * @param [in] Refernce to the structure with the services' information. - */ + */ NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service) { - NIMBLE_LOGD(LOG_TAG, ">> BLERemoteService()"); + NIMBLE_LOGD(LOG_TAG, ">> NimBLERemoteService()"); m_pClient = pClient; switch (service->uuid.u.type) { - case BLE_UUID_TYPE_16: + case BLE_UUID_TYPE_16: m_uuid = NimBLEUUID(service->uuid.u16.value); break; - case BLE_UUID_TYPE_32: + case BLE_UUID_TYPE_32: m_uuid = NimBLEUUID(service->uuid.u32.value); break; - case BLE_UUID_TYPE_128: + case BLE_UUID_TYPE_128: m_uuid = NimBLEUUID(const_cast(&service->uuid.u128)); break; default: @@ -46,43 +49,63 @@ NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble } m_startHandle = service->start_handle; m_endHandle = service->end_handle; - m_haveCharacteristics = false; - - NIMBLE_LOGD(LOG_TAG, "<< BLERemoteService()"); + NIMBLE_LOGD(LOG_TAG, "<< NimBLERemoteService()"); } /** * @brief When deleting the service make sure we delete all characteristics and descriptors. * Also release any semaphores they may be holding. - */ + */ NimBLERemoteService::~NimBLERemoteService() { removeCharacteristics(); } +/** + * @brief Get iterator to the beginning of the vector of remote characteristic pointers. + * @return An iterator to the beginning of the vector of remote characteristic pointers. + */ +std::vector::iterator NimBLERemoteService::begin() { + return m_characteristicVector.begin(); +} + + +/** + * @brief Get iterator to the end of the vector of remote characteristic pointers. + * @return An iterator to the end of the vector of remote characteristic pointers. + */ +std::vector::iterator NimBLERemoteService::end() { + return m_characteristicVector.end(); +} + + /** * @brief Get the remote characteristic object for the characteristic UUID. * @param [in] uuid Remote characteristic uuid. * @return Reference to the remote characteristic object. - */ + */ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* uuid) { return getCharacteristic(NimBLEUUID(uuid)); } // getCharacteristic - + /** * @brief Get the characteristic object for the UUID. * @param [in] uuid Characteristic uuid. * @return Reference to the characteristic object, or nullptr if not found. */ -NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(NimBLEUUID uuid) { - if (m_haveCharacteristics) { - std::string v = uuid.toString(); - for (auto &myPair : m_characteristicMap) { - if (myPair.first == v) { - return myPair.second; - } +NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID &uuid) { + for(auto &it: m_characteristicVector) { + if(it->getUUID() == uuid) { + return it; + } + } + + size_t prev_size = m_characteristicVector.size(); + if(retrieveCharacteristics(&uuid)) { + if(m_characteristicVector.size() > prev_size) { + return m_characteristicVector.back(); } } @@ -90,15 +113,43 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(NimBLEUUID uu } // getCharacteristic +/** + * @Get a pointer to the vector of found characteristics. + * @param [in] bool value to indicate if the current vector should be cleared and + * subsequently all characteristics for this service retrieved from the peripheral. + * If false the vector will be returned with the currently stored characteristics, + * if the vector is empty it will retrieve all characteristics of this service + * from the peripheral. + * @return a pointer to the vector of descriptors for this characteristic. + */ + +std::vector* NimBLERemoteService::getCharacteristics(bool refresh) { + if(refresh) { + removeCharacteristics(); + } + + if(m_characteristicVector.empty()) { + if (!retrieveCharacteristics()) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to get characteristics"); + } + else{ + NIMBLE_LOGI(LOG_TAG, "Found %d characteristics", m_characteristicVector.size()); + } + } + return &m_characteristicVector; +} // getCharacteristics + + /** * @brief Callback for Characterisic discovery. */ -int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, +int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_chr *chr, void *arg) + const struct ble_gatt_chr *chr, void *arg) { - NIMBLE_LOGD(LOG_TAG,"Characteristic Discovered >> status: %d handle: %d", error->status, conn_handle); - + NIMBLE_LOGD(LOG_TAG,"Characteristic Discovered >> status: %d handle: %d", + error->status, (error->status == 0) ? chr->val_handle : -1); + NimBLERemoteService *service = (NimBLERemoteService*)arg; int rc=0; @@ -106,13 +157,12 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, if(service->getClient()->getConnId() != conn_handle){ return 0; } - + switch (error->status) { case 0: { - // Found a service - add it to the map + // Found a service - add it to the vector NimBLERemoteCharacteristic* pRemoteCharacteristic = new NimBLERemoteCharacteristic(service, chr); - service->m_characteristicMap.insert(std::pair(pRemoteCharacteristic->getUUID().toString(), pRemoteCharacteristic)); - service->m_characteristicMapByHandle.insert(std::pair(chr->val_handle, pRemoteCharacteristic)); + service->m_characteristicVector.push_back(pRemoteCharacteristic); break; } case BLE_HS_EDONE:{ @@ -145,84 +195,46 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, * This function will not return until we have all the characteristics. * @return N/A */ -bool NimBLERemoteService::retrieveCharacteristics() { +bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter) { NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str()); - + int rc = 0; //removeCharacteristics(); // Forget any previous characteristics. - + m_semaphoreGetCharEvt.take("retrieveCharacteristics"); - - rc = ble_gattc_disc_all_chrs(m_pClient->getConnId(), - m_startHandle, - m_endHandle, - NimBLERemoteService::characteristicDiscCB, - this); + + if(uuid_filter == nullptr) { + rc = ble_gattc_disc_all_chrs(m_pClient->getConnId(), + m_startHandle, + m_endHandle, + NimBLERemoteService::characteristicDiscCB, + this); + } else { + rc = ble_gattc_disc_chrs_by_uuid(m_pClient->getConnId(), + m_startHandle, + m_endHandle, + &uuid_filter->getNative()->u, + NimBLERemoteService::characteristicDiscCB, + this); + } + if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); - m_haveCharacteristics = false; m_semaphoreGetCharEvt.give(); return false; } - - m_haveCharacteristics = (m_semaphoreGetCharEvt.wait("retrieveCharacteristics") == 0); - if(m_haveCharacteristics){ - uint16_t endHdl = 0xFFFF; - NIMBLE_LOGD(LOG_TAG, "Found %d Characteristics", m_characteristicMapByHandle.size()); - for (auto it = m_characteristicMapByHandle.cbegin(); it != m_characteristicMapByHandle.cend(); ++it) { - NIMBLE_LOGD(LOG_TAG, "Found UUID: %s Handle: %d Def Handle: %d", (*it).second->getUUID().toString().c_str(), (*it).second->getHandle(), (*it).second->getDefHandle()); - // The descriptor handle is between this characteristic val_handle and the next ones def_handle - // so make the end of the scan at the handle before the next characteristic def_handle - - // Make sure we don't go past the service end handle - if(++it != m_characteristicMapByHandle.cend()){ - NIMBLE_LOGD(LOG_TAG, "Next UUID: %s Handle: %d Def Handle: %d", (*it).second->getUUID().toString().c_str(), (*it).second->getHandle(),(*it).second->getDefHandle()); - - endHdl = (*it).second->getDefHandle()-1; - } - else{ - NIMBLE_LOGD(LOG_TAG, "END CHARS"); - endHdl = m_endHandle; - } - --it; - - //If there is no handles between this characteristic and the next there is no descriptor so skip to the next - if((*it).second->getHandle() != endHdl){ - if(!m_pClient->m_isConnected || !(*it).second->retrieveDescriptors(endHdl)) { - return false; - } - } - //NIMBLE_LOGD(LOG_TAG, "Found %d Characteristics in service UUID: %s", chars->size(), myPair.first.c_str()); - } - + + if(m_semaphoreGetCharEvt.wait("retrieveCharacteristics") == 0){ NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()"); return true; } - + NIMBLE_LOGE(LOG_TAG, "Could not retrieve characteristics"); return false; - + } // retrieveCharacteristics -/** - * @brief Retrieve a map of all the characteristics of this service. - * @return A map of all the characteristics of this service. - */ -std::map* NimBLERemoteService::getCharacteristics() { - return &m_characteristicMap; -} // getCharacteristics - - -/** - * @brief Retrieve a map of all the characteristics of this service. - * @return A map of all the characteristics of this service. - */ -std::map* NimBLERemoteService::getCharacteristicsByHandle() { - return &m_characteristicMapByHandle; -} // getCharacteristicsByHandle - - /** * @brief Get the client associated with this service. * @return A reference to the client associated with this service. @@ -261,12 +273,12 @@ NimBLEUUID NimBLERemoteService::getUUID() { * @param [in] characteristicUuid The characteristic to read. * @returns a string containing the value or an empty string if not found or error. */ -std::string NimBLERemoteService::getValue(NimBLEUUID characteristicUuid) { +std::string NimBLERemoteService::getValue(const NimBLEUUID &characteristicUuid) { NIMBLE_LOGD(LOG_TAG, ">> readValue: uuid: %s", characteristicUuid.toString().c_str()); - + std::string ret = ""; NimBLERemoteCharacteristic* pChar = getCharacteristic(characteristicUuid); - + if(pChar != nullptr) { ret = pChar->readValue(); } @@ -282,12 +294,12 @@ std::string NimBLERemoteService::getValue(NimBLEUUID characteristicUuid) { * @param [in] value The value to set. * @returns true on success, false if not found or error */ -bool NimBLERemoteService::setValue(NimBLEUUID characteristicUuid, std::string value) { +bool NimBLERemoteService::setValue(const NimBLEUUID &characteristicUuid, const std::string &value) { NIMBLE_LOGD(LOG_TAG, ">> setValue: uuid: %s", characteristicUuid.toString().c_str()); - + bool ret = false; NimBLERemoteCharacteristic* pChar = getCharacteristic(characteristicUuid); - + if(pChar != nullptr) { ret = pChar->writeValue(value); } @@ -298,20 +310,17 @@ bool NimBLERemoteService::setValue(NimBLEUUID characteristicUuid, std::string va /** - * @brief Delete the characteristics in the characteristics map. - * We maintain a map called m_characteristicsMap that contains pointers to BLERemoteCharacteristic - * object references. Since we allocated these in this class, we are also responsible for deleteing - * them. This method does just that. + * @brief Delete the characteristics in the characteristics vector. + * We maintain a vector called m_characteristicsVector that contains pointers to BLERemoteCharacteristic + * object references. Since we allocated these in this class, we are also responsible for deleting + * them. This method does just that. * @return N/A. */ void NimBLERemoteService::removeCharacteristics() { - m_characteristicMap.clear(); // Clear the map - - for (auto &myPair : m_characteristicMapByHandle) { - delete myPair.second; + for(auto &it: m_characteristicVector) { + delete it; } - m_characteristicMapByHandle.clear(); // Clear the map - + m_characteristicVector.clear(); // Clear the vector } // removeCharacteristics @@ -334,9 +343,9 @@ std::string NimBLERemoteService::toString() { snprintf(val, sizeof(val), "%04x", m_endHandle); res += " 0x"; res += val; - - for (auto &myPair : m_characteristicMap) { - res += "\n" + myPair.second->toString(); + + for (auto &it: m_characteristicVector) { + res += "\n" + it->toString(); } return res; @@ -345,13 +354,14 @@ std::string NimBLERemoteService::toString() { /** * @brief called when an error occurrs and we need to release the semaphores to resume operations. - * Will release all characteristic and subsequently all descriptor semaphores for this service. + * Will release all characteristic and subsequently all descriptor semaphores for this service. */ void NimBLERemoteService::releaseSemaphores() { - for (auto &cPair : m_characteristicMapByHandle) { - cPair.second->releaseSemaphores(); + for(auto &it: m_characteristicVector) { + it->releaseSemaphores(); } m_semaphoreGetCharEvt.give(1); } +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h index bef8f0b52..3803498d0 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h @@ -3,7 +3,7 @@ * * Created: on Jan 27 2020 * Author H2zero - * + * * Originally: * * BLERemoteService.h @@ -17,12 +17,15 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + #include "NimBLEClient.h" #include "NimBLEUUID.h" #include "FreeRTOS.h" #include "NimBLERemoteCharacteristic.h" -#include +#include class NimBLEClient; class NimBLERemoteCharacteristic; @@ -36,54 +39,51 @@ public: virtual ~NimBLERemoteService(); // Public methods - NimBLERemoteCharacteristic* getCharacteristic(const char* uuid); // Get the specified characteristic reference. - NimBLERemoteCharacteristic* getCharacteristic(NimBLEUUID uuid); // Get the specified characteristic reference. -// BLERemoteCharacteristic* getCharacteristic(uint16_t uuid); // Get the specified characteristic reference. - std::map* getCharacteristics(); - std::map* getCharacteristicsByHandle(); // Get the characteristics map. -// void getCharacteristics(std::map* pCharacteristicMap); - - NimBLEClient* getClient(void); // Get a reference to the client associated with this service. - uint16_t getHandle(); // Get the handle of this service. - NimBLEUUID getUUID(void); // Get the UUID of this service. - std::string getValue(NimBLEUUID characteristicUuid); // Get the value of a characteristic. - bool setValue(NimBLEUUID characteristicUuid, std::string value); // Set the value of a characteristic. - std::string toString(void); + std::vector::iterator begin(); + std::vector::iterator end(); + NimBLERemoteCharacteristic* getCharacteristic(const char* uuid); + NimBLERemoteCharacteristic* getCharacteristic(const NimBLEUUID &uuid); + NimBLEClient* getClient(void); + uint16_t getHandle(); + NimBLEUUID getUUID(void); + std::string getValue(const NimBLEUUID &characteristicUuid); + bool setValue(const NimBLEUUID &characteristicUuid, + const std::string &value); + std::string toString(void); + std::vector* getCharacteristics(bool refresh = false); private: // Private constructor ... never meant to be created by a user application. - NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc *service); + NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc *service); // Friends friend class NimBLEClient; friend class NimBLERemoteCharacteristic; // Private methods - bool retrieveCharacteristics(void); // Retrieve the characteristics from the BLE Server. - static int characteristicDiscCB(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_chr *chr, void *arg); + bool retrieveCharacteristics(const NimBLEUUID *uuid_filter = nullptr); + static int characteristicDiscCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, + void *arg); - uint16_t getStartHandle(); // Get the start handle for this service. - uint16_t getEndHandle(); // Get the end handle for this service. + uint16_t getStartHandle(); + uint16_t getEndHandle(); void releaseSemaphores(); void removeCharacteristics(); // Properties - // We maintain a map of characteristics owned by this service keyed by a string representation of the UUID. - std::map m_characteristicMap; + // We maintain a vector of characteristics owned by this service. + std::vector m_characteristicVector; - // We maintain a map of characteristics owned by this service keyed by a handle. - std::map m_characteristicMapByHandle; - - bool m_haveCharacteristics; // Have we previously obtained the characteristics. NimBLEClient* m_pClient; FreeRTOS::Semaphore m_semaphoreGetCharEvt = FreeRTOS::Semaphore("GetCharEvt"); - NimBLEUUID m_uuid; // The UUID of this service. - uint16_t m_startHandle; // The starting handle of this service. - uint16_t m_endHandle; // The ending handle of this service. -}; // BLERemoteService + NimBLEUUID m_uuid; + uint16_t m_startHandle; + uint16_t m_endHandle; +}; // NimBLERemoteService +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ #endif /* COMPONENTS_NIMBLEREMOTESERVICE_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp b/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp index e5cbed1f0..6d738f951 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp @@ -3,7 +3,7 @@ * * Created: on Jan 24 2020 * Author H2zero - * + * * Originally: * * BLEScan.cpp @@ -14,6 +14,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + #include "NimBLEScan.h" #include "NimBLEUtils.h" #include "NimBLEDevice.h" @@ -40,7 +43,7 @@ static const char* LOG_TAG = "NimBLEScan"; * directed advertisement shall not be ignored if the InitA is a * resolvable private address. */ - + //#define BLE_HCI_SCAN_FILT_NO_WL (0) //#define BLE_HCI_SCAN_FILT_USE_WL (1) //#define BLE_HCI_SCAN_FILT_NO_WL_INITA (2) @@ -63,7 +66,7 @@ NimBLEScan::NimBLEScan() { m_scan_params.itvl = 0; // This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. (units=0.625 msec) m_scan_params.window = 0; // The duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval (units=0.625 msec) m_scan_params.limited = 0; // If set, only discover devices in limited discoverable mode. - m_scan_params.filter_duplicates = 1; // If set, the controller ignores all but the first advertisement from each device. + m_scan_params.filter_duplicates = 0; // If set, the controller ignores all but the first advertisement from each device. m_pAdvertisedDeviceCallbacks = nullptr; m_stopped = true; m_wantDuplicates = false; @@ -76,33 +79,33 @@ NimBLEScan::NimBLEScan() { * @param [in] param Parameter data for this event. */ /*STATIC*/int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) { - + NimBLEScan* pScan = (NimBLEScan*)arg; struct ble_hs_adv_fields fields; int rc = 0; - + switch(event->type) { case BLE_GAP_EVENT_DISC: { - if(pScan->m_stopped) { - NIMBLE_LOGE(LOG_TAG, "Scan stop called, ignoring results."); - return 0; - } - + if(pScan->m_stopped) { + NIMBLE_LOGE(LOG_TAG, "Scan stop called, ignoring results."); + return 0; + } + rc = ble_hs_adv_parse_fields(&fields, event->disc.data, event->disc.length_data); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "Gap Event Parse ERROR."); return 0; } - + NimBLEAddress advertisedAddress(event->disc.addr); // Print advertisement data // print_adv_fields(&fields); // If we are not scanning, nothing to do with the extra results. - if (pScan->m_stopped) { + if (pScan->m_stopped) { return 0; } @@ -111,16 +114,18 @@ NimBLEScan::NimBLEScan() { NIMBLE_LOGI(LOG_TAG, "Ignoring device: address: %s", advertisedAddress.toString().c_str()); return 0; } - - NimBLEAdvertisedDevice* advertisedDevice = nullptr; - - // If we've seen this device before get a pointer to it from the map - auto it = pScan->m_scanResults.m_advertisedDevicesMap.find(advertisedAddress.toString()); - if(it != pScan->m_scanResults.m_advertisedDevicesMap.cend()) { - advertisedDevice = (*it).second; + + NimBLEAdvertisedDevice* advertisedDevice = nullptr; + + // If we've seen this device before get a pointer to it from the vector + for(auto &it: pScan->m_scanResults.m_advertisedDevicesVector) { + if(it->getAddress() == advertisedAddress) { + advertisedDevice = it; + break; + } } - // If we haven't seen this device before; create a new instance and insert it in the map. + // If we haven't seen this device before; create a new instance and insert it in the vector. // Otherwise just update the relevant parameters of the already known device. if(advertisedDevice == nullptr){ advertisedDevice = new NimBLEAdvertisedDevice(); @@ -128,20 +133,20 @@ NimBLEScan::NimBLEScan() { advertisedDevice->setAddress(advertisedAddress); //NIMBLE_LOGE(LOG_TAG, "advertisement type: %d, %s",event->disc.event_type, NimBLEUtils::advTypeToString(event->disc.event_type)); advertisedDevice->setAdvType(event->disc.event_type); - pScan->m_scanResults.m_advertisedDevicesMap.insert(std::pair(advertisedAddress.toString(), advertisedDevice)); + pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice); NIMBLE_LOGI(LOG_TAG, "NEW DEVICE FOUND: %s", advertisedAddress.toString().c_str()); } else{ NIMBLE_LOGI(LOG_TAG, "UPDATING PREVIOUSLY FOUND DEVICE: %s", advertisedAddress.toString().c_str()); } - advertisedDevice->setRSSI(event->disc.rssi); + advertisedDevice->setRSSI(event->disc.rssi); advertisedDevice->parseAdvertisement(&fields); advertisedDevice->setScan(pScan); advertisedDevice->setAdvertisementResult(event->disc.data, event->disc.length_data); if (pScan->m_pAdvertisedDeviceCallbacks) { // If not active scanning report the result to the listener. - if(pScan->m_scan_params.passive) { + if(pScan->m_scan_params.passive || event->disc.event_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) { pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice); // Otherwise wait for the scan response so we can report all of the data at once. } else if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) { @@ -155,13 +160,13 @@ NimBLEScan::NimBLEScan() { case BLE_GAP_EVENT_DISC_COMPLETE: { NIMBLE_LOGD(LOG_TAG, "discovery complete; reason=%d", event->disc_complete.reason); - + if (pScan->m_scanCompleteCB != nullptr) { pScan->m_scanCompleteCB(pScan->m_scanResults); } - + pScan->m_stopped = true; - pScan->m_semaphoreScanEnd.give(); + pScan->m_semaphoreScanEnd.give(); return 0; } @@ -224,13 +229,13 @@ void NimBLEScan::setWindow(uint16_t windowMSecs) { */ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue) { NIMBLE_LOGD(LOG_TAG, ">> start(duration=%d)", duration); - + // If Host is not synced we cannot start scanning. if(!NimBLEDevice::m_synced) { NIMBLE_LOGC(LOG_TAG, "Host reset, wait for sync."); return false; } - + if(ble_gap_conn_active()) { NIMBLE_LOGE(LOG_TAG, "Connection in progress - must wait."); return false; @@ -244,12 +249,12 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul m_stopped = false; m_semaphoreScanEnd.take("start"); - + // Save the callback to be invoked when the scan completes. - m_scanCompleteCB = scanCompleteCB; + m_scanCompleteCB = scanCompleteCB; // Save the duration in the case that the host is reset so we can reuse it. m_duration = duration; - + // If 0 duration specified then we assume a continuous scan is desired. if(duration == 0){ duration = BLE_HS_FOREVER; @@ -257,22 +262,22 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul else{ duration = duration*1000; // convert duration to milliseconds } - + // if we are connecting to devices that are advertising even after being connected, multiconnecting peripherals - // then we should not clear map or we will connect the same device few times + // then we should not clear vector or we will connect the same device few times if(!is_continue) { clearResults(); } - + int rc = 0; - do{ - rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params, + do{ + rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params, NimBLEScan::handleGapEvent, this); if(rc == BLE_HS_EBUSY) { vTaskDelay(2); } } while(rc == BLE_HS_EBUSY); - + if (rc != 0 && rc != BLE_HS_EDONE) { NIMBLE_LOGE(LOG_TAG, "Error initiating GAP discovery procedure; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); @@ -305,7 +310,7 @@ NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) { */ void NimBLEScan::stop() { NIMBLE_LOGD(LOG_TAG, ">> stop()"); - + int rc = ble_gap_disc_cancel(); if (rc != 0 && rc != BLE_HS_EALREADY) { NIMBLE_LOGE(LOG_TAG, "Failed to cancel scan; rc=%d\n", rc); @@ -313,23 +318,28 @@ void NimBLEScan::stop() { } m_stopped = true; - + if (m_scanCompleteCB != nullptr) { m_scanCompleteCB(m_scanResults); } - + m_semaphoreScanEnd.give(); - + NIMBLE_LOGD(LOG_TAG, "<< stop()"); } // stop // delete peer device from cache after disconnecting, it is required in case we are connecting to devices with not public address -void NimBLEScan::erase(NimBLEAddress address) { +void NimBLEScan::erase(const NimBLEAddress &address) { NIMBLE_LOGI(LOG_TAG, "erase device: %s", address.toString().c_str()); - NimBLEAdvertisedDevice *advertisedDevice = m_scanResults.m_advertisedDevicesMap.find(address.toString())->second; - m_scanResults.m_advertisedDevicesMap.erase(address.toString()); - delete advertisedDevice; + + for(auto it = m_scanResults.m_advertisedDevicesVector.begin(); it != m_scanResults.m_advertisedDevicesVector.end(); ++it) { + if((*it)->getAddress() == address) { + delete *it; + m_scanResults.m_advertisedDevicesVector.erase(it); + break; + } + } } @@ -356,10 +366,10 @@ NimBLEScanResults NimBLEScan::getResults() { * @brief Clear the results of the scan. */ void NimBLEScan::clearResults() { - for(auto _dev : m_scanResults.m_advertisedDevicesMap){ - delete _dev.second; + for(auto &it: m_scanResults.m_advertisedDevicesVector) { + delete it; } - m_scanResults.m_advertisedDevicesMap.clear(); + m_scanResults.m_advertisedDevicesVector.clear(); } @@ -379,7 +389,7 @@ void NimBLEScanResults::dump() { * @return The number of devices found in the last scan. */ int NimBLEScanResults::getCount() { - return m_advertisedDevicesMap.size(); + return m_advertisedDevicesVector.size(); } // getCount @@ -390,14 +400,43 @@ int NimBLEScanResults::getCount() { * @return The device at the specified index. */ NimBLEAdvertisedDevice NimBLEScanResults::getDevice(uint32_t i) { - uint32_t x = 0; - NimBLEAdvertisedDevice dev = *m_advertisedDevicesMap.begin()->second; - for (auto it = m_advertisedDevicesMap.begin(); it != m_advertisedDevicesMap.end(); it++) { - dev = *it->second; - if (x==i) break; - x++; - } - return dev; + return *m_advertisedDevicesVector[i]; } + +/** + * @brief Get iterator to the beginning of the vector of advertised device pointers. + * @return An iterator to the beginning of the vector of advertised device pointers. + */ +std::vector::iterator NimBLEScanResults::begin() { + return m_advertisedDevicesVector.begin(); +} + + +/** + * @brief Get iterator to the end of the vector of advertised device pointers. + * @return An iterator to the end of the vector of advertised device pointers. + */ +std::vector::iterator NimBLEScanResults::end() { + return m_advertisedDevicesVector.end(); +} + + +/** + * @brief Return a pointer to the specified device at the given address. + * If the address is not found a nullptr is returned. + * @param [in] address The address of the device. + * @return A pointer to the device at the specified address. + */ +NimBLEAdvertisedDevice *NimBLEScanResults::getDevice(const NimBLEAddress &address) { + for(size_t index = 0; index < m_advertisedDevicesVector.size(); index++) { + if(m_advertisedDevicesVector[index]->getAddress() == address) { + return m_advertisedDevicesVector[index]; + } + } + + return nullptr; +} + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) #endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEScan.h b/libesp32/NimBLE-Arduino/src/NimBLEScan.h index a19a3da0e..3cab25784 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEScan.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEScan.h @@ -3,7 +3,7 @@ * * Created: on Jan 24 2020 * Author H2zero - * + * * Originally: * * BLEScan.h @@ -16,17 +16,21 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + #include "NimBLEAdvertisedDevice.h" #include "FreeRTOS.h" #include "host/ble_gap.h" -#include +#include class NimBLEDevice; class NimBLEScan; class NimBLEAdvertisedDevice; class NimBLEAdvertisedDeviceCallbacks; +class NimBLEAddress; /** * @brief The result of having performed a scan. @@ -37,13 +41,16 @@ class NimBLEAdvertisedDeviceCallbacks; */ class NimBLEScanResults { public: - void dump(); - int getCount(); - NimBLEAdvertisedDevice getDevice(uint32_t i); + void dump(); + int getCount(); + NimBLEAdvertisedDevice getDevice(uint32_t i); + std::vector::iterator begin(); + std::vector::iterator end(); + NimBLEAdvertisedDevice *getDevice(const NimBLEAddress &address); private: friend NimBLEScan; - std::map m_advertisedDevicesMap; + std::vector m_advertisedDevicesVector; }; /** @@ -62,15 +69,15 @@ public: void stop(); void clearResults(); NimBLEScanResults getResults(); - void erase(NimBLEAddress address); - - + void erase(const NimBLEAddress &address); + + private: NimBLEScan(); friend class NimBLEDevice; static int handleGapEvent(ble_gap_event* event, void* arg); void onHostReset(); - + NimBLEAdvertisedDeviceCallbacks* m_pAdvertisedDeviceCallbacks = nullptr; void (*m_scanCompleteCB)(NimBLEScanResults scanResults); ble_gap_disc_params m_scan_params; @@ -82,6 +89,6 @@ private: uint32_t m_duration; }; - +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) #endif /* CONFIG_BT_ENABLED */ #endif /* COMPONENTS_NIMBLE_SCAN_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLESecurity.cpp b/libesp32/NimBLE-Arduino/src/NimBLESecurity.cpp index 0651858d0..8a0dbd952 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLESecurity.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLESecurity.cpp @@ -3,7 +3,7 @@ * * Created: on Feb 22 2020 * Author H2zero - * + * * Originally: * * BLESecurity.cpp @@ -73,7 +73,7 @@ void NimBLESecurity::setRespEncryptionKey(uint8_t resp_key) { * */ void NimBLESecurity::setKeySize(uint8_t key_size) { - + //m_keySize = key_size; //esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &m_keySize, sizeof(uint8_t)); } //setKeySize @@ -132,7 +132,7 @@ char* BLESecurity::esp_key_type_to_str(esp_ble_key_type_t key_type) { break; } return key_str; - + } // esp_key_type_to_str */ #endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLESecurity.h b/libesp32/NimBLE-Arduino/src/NimBLESecurity.h index 60e4f443d..50c732c9b 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLESecurity.h +++ b/libesp32/NimBLE-Arduino/src/NimBLESecurity.h @@ -3,7 +3,7 @@ * * Created: on Feb 22 2020 * Author H2zero - * + * * Originally: * * BLESecurity.h @@ -12,8 +12,8 @@ * Author: chegewara */ -/** This class exists for backward compatibility - Should not be used in new code - * See the security functions in NimBLEDevice and callbacks in NimBLEServer / NimBLEClient +/** This class exists for backward compatibility - Should not be used in new code + * See the security functions in NimBLEDevice and callbacks in NimBLEServer / NimBLEClient */ #ifndef COMPONENTS_NIMBLESECURITY_H_ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp b/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp index 5e94b563d..d731bad5b 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp @@ -3,7 +3,7 @@ * * Created: on March 2, 2020 * Author H2zero - * + * * Originally: * * BLEServer.cpp @@ -15,6 +15,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLEServer.h" #include "NimBLE2902.h" #include "NimBLEUtils.h" @@ -32,10 +35,10 @@ static NimBLEServerCallbacks defaultCallbacks; * the BLEDevice class. */ NimBLEServer::NimBLEServer() { - m_connId = BLE_HS_CONN_HANDLE_NONE; + m_connId = BLE_HS_CONN_HANDLE_NONE; m_svcChgChrHdl = 0xffff; - m_pServerCallbacks = &defaultCallbacks; - m_gattsStarted = false; + m_pServerCallbacks = &defaultCallbacks; + m_gattsStarted = false; } // BLEServer @@ -48,7 +51,7 @@ NimBLEServer::NimBLEServer() { * @return A reference to the new service object. */ NimBLEService* NimBLEServer::createService(const char* uuid) { - return createService(NimBLEUUID(uuid)); + return createService(NimBLEUUID(uuid)); } @@ -62,21 +65,21 @@ NimBLEService* NimBLEServer::createService(const char* uuid) { * @param [in] inst_id With multiple services with the same UUID we need to provide inst_id value different for each service. * @return A reference to the new service object. */ -NimBLEService* NimBLEServer::createService(NimBLEUUID uuid, uint32_t numHandles, uint8_t inst_id) { - NIMBLE_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str()); +NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid, uint32_t numHandles, uint8_t inst_id) { + NIMBLE_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str()); - // Check that a service with the supplied UUID does not already exist. - if (m_serviceMap.getByUUID(uuid) != nullptr) { - NIMBLE_LOGW(LOG_TAG, "<< Attempt to create a new service with uuid %s but a service with that UUID already exists.", - uuid.toString().c_str()); - } + // Check that a service with the supplied UUID does not already exist. + if (m_serviceMap.getByUUID(uuid) != nullptr) { + NIMBLE_LOGW(LOG_TAG, "<< Attempt to create a new service with uuid %s but a service with that UUID already exists.", + uuid.toString().c_str()); + } - NimBLEService* pService = new NimBLEService(uuid, numHandles, this); - pService->m_instId = inst_id; - m_serviceMap.setByUUID(uuid, pService); // Save a reference to this service being on this server. + NimBLEService* pService = new NimBLEService(uuid, numHandles, this); + pService->m_instId = inst_id; + m_serviceMap.setByUUID(uuid, pService); // Save a reference to this service being on this server. - NIMBLE_LOGD(LOG_TAG, "<< createService"); - return pService; + NIMBLE_LOGD(LOG_TAG, "<< createService"); + return pService; } // createService @@ -86,7 +89,7 @@ NimBLEService* NimBLEServer::createService(NimBLEUUID uuid, uint32_t numHandles, * @return A reference to the service object. */ NimBLEService* NimBLEServer::getServiceByUUID(const char* uuid) { - return m_serviceMap.getByUUID(uuid); + return m_serviceMap.getByUUID(uuid); } @@ -95,8 +98,8 @@ NimBLEService* NimBLEServer::getServiceByUUID(const char* uuid) { * @param [in] uuid The UUID of the new service. * @return A reference to the service object. */ -NimBLEService* NimBLEServer::getServiceByUUID(NimBLEUUID uuid) { - return m_serviceMap.getByUUID(uuid); +NimBLEService* NimBLEServer::getServiceByUUID(const NimBLEUUID &uuid) { + return m_serviceMap.getByUUID(uuid); } @@ -106,7 +109,7 @@ NimBLEService* NimBLEServer::getServiceByUUID(NimBLEUUID uuid) { * @return An advertising object. */ NimBLEAdvertising* NimBLEServer::getAdvertising() { - return BLEDevice::getAdvertising(); + return BLEDevice::getAdvertising(); } @@ -116,58 +119,58 @@ NimBLEAdvertising* NimBLEServer::getAdvertising() { * @return Client connection id. */ uint16_t NimBLEServer::getConnId() { - return m_connId; + return m_connId; } /** - * @brief Start the GATT server. Required to be called after setup of all + * @brief Start the GATT server. Required to be called after setup of all * services and characteristics / descriptors for the NimBLE host to register them. */ void NimBLEServer::start() { - if(m_gattsStarted) { - NIMBLE_LOGW(LOG_TAG, "Gatt server already started"); - return; - } - + if(m_gattsStarted) { + NIMBLE_LOGW(LOG_TAG, "Gatt server already started"); + return; + } + int rc = ble_gatts_start(); if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "ble_gatts_start; rc=%d, %s", rc, + NIMBLE_LOGE(LOG_TAG, "ble_gatts_start; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); abort(); } - -#if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4) + +#if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4) ble_gatts_show_local(); -#endif +#endif ble_uuid16_t svc = {BLE_UUID_TYPE_16, 0x1801}; ble_uuid16_t chr = {BLE_UUID_TYPE_16, 0x2a05}; - - rc = ble_gatts_find_chr(&svc.u, &chr.u, NULL, &m_svcChgChrHdl); + + rc = ble_gatts_find_chr(&svc.u, &chr.u, NULL, &m_svcChgChrHdl); if(rc != 0) { - NIMBLE_LOGE(LOG_TAG, "ble_gatts_find_chr: rc=%d, %s", rc, + NIMBLE_LOGE(LOG_TAG, "ble_gatts_find_chr: rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); abort(); } - + NIMBLE_LOGI(LOG_TAG, "Service changed characterisic handle: %d", m_svcChgChrHdl); - + // Build a map of characteristics with Notify / Indicate capabilities for event handling uint8_t numSvcs = m_serviceMap.getRegisteredServiceCount(); NimBLEService* pService = m_serviceMap.getFirst(); - + for(int i = 0; i < numSvcs; i++) { - uint8_t numChrs = pService->m_characteristicMap.getSize(); - NimBLECharacteristic* pChr = pService->m_characteristicMap.getFirst(); - + uint8_t numChrs = pService->m_characteristicMap.getSize(); + NimBLECharacteristic* pChr = pService->m_characteristicMap.getFirst(); + if(pChr != nullptr) { for( int d = 0; d < numChrs; d++) { // if Notify / Indicate is enabled but we didn't create the descriptor // we do it now. - if((pChr->m_properties & BLE_GATT_CHR_F_INDICATE) || + if((pChr->m_properties & BLE_GATT_CHR_F_INDICATE) || (pChr->m_properties & BLE_GATT_CHR_F_NOTIFY)) { - + if(nullptr == pChr->getDescriptorByUUID("2902")) { pChr->createDescriptor("2902"); } @@ -179,8 +182,8 @@ void NimBLEServer::start() { } pService = m_serviceMap.getNext(); } - - m_gattsStarted = true; + + m_gattsStarted = true; } @@ -192,13 +195,13 @@ void NimBLEServer::start() { */ int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) { NIMBLE_LOGD(LOG_TAG, ">> disconnect()"); - + int rc = ble_gap_terminate(connId, reason); if(rc != 0){ - NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc, + NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); } - + return rc; NIMBLE_LOGD(LOG_TAG, "<< disconnect()"); } @@ -209,7 +212,7 @@ int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) { * @return The number of connected clients. */ uint32_t NimBLEServer::getConnectedCount() { - return m_connectedServersMap.size(); + return m_connectedServersMap.size(); } // getConnectedCount @@ -222,15 +225,15 @@ uint32_t NimBLEServer::getConnectedCount() { * */ /*STATIC*/int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) { - NimBLEServer* server = (NimBLEServer*)arg; - NIMBLE_LOGD(LOG_TAG, ">> handleGapEvent: %s", - NimBLEUtils::gapEventToString(event->type)); + NimBLEServer* server = (NimBLEServer*)arg; + NIMBLE_LOGD(LOG_TAG, ">> handleGapEvent: %s", + NimBLEUtils::gapEventToString(event->type)); int rc = 0; struct ble_gap_conn_desc desc; - - switch(event->type) { - - case BLE_GAP_EVENT_CONNECT: { + + switch(event->type) { + + case BLE_GAP_EVENT_CONNECT: { if (event->connect.status != 0) { /* Connection failed; resume advertising */ NIMBLE_LOGC(LOG_TAG, "Connection failed"); @@ -240,21 +243,21 @@ uint32_t NimBLEServer::getConnectedCount() { else { server->m_connId = event->connect.conn_handle; server->addPeerDevice((void*)server, false, server->m_connId); - + ble_gap_conn_desc desc; rc = ble_gap_conn_find(event->connect.conn_handle, &desc); assert(rc == 0); - + server->m_pServerCallbacks->onConnect(server); - server->m_pServerCallbacks->onConnect(server, &desc); + server->m_pServerCallbacks->onConnect(server, &desc); } return 0; - } // BLE_GAP_EVENT_CONNECT - - + } // BLE_GAP_EVENT_CONNECT + + case BLE_GAP_EVENT_DISCONNECT: { - // If Host reset tell the device now before returning to prevent + // If Host reset tell the device now before returning to prevent // any errors caused by calling host functions before resyncing. switch(event->disconnect.reason) { case BLE_HS_ETIMEOUT_HCI: @@ -264,22 +267,22 @@ uint32_t NimBLEServer::getConnectedCount() { NIMBLE_LOGC(LOG_TAG, "Disconnect - host reset, rc=%d", event->disconnect.reason); NimBLEDevice::onReset(event->disconnect.reason); break; - default: + default: break; } - + server->removePeerDevice(event->disconnect.conn.conn_handle, false); - server->m_connId = BLE_HS_CONN_HANDLE_NONE; + server->m_connId = BLE_HS_CONN_HANDLE_NONE; server->m_pServerCallbacks->onDisconnect(server); - + return 0; } // BLE_GAP_EVENT_DISCONNECT - + case BLE_GAP_EVENT_SUBSCRIBE: { NIMBLE_LOGI(LOG_TAG, "subscribe event; cur_notify=%d\n value handle; " "val_handle=%d\n", event->subscribe.cur_notify, event->subscribe.attr_handle); - + auto it = server->m_notifyChrMap.find(event->subscribe.attr_handle); if(it != server->m_notifyChrMap.cend()) { (*it).second->setSubscribe(event); @@ -287,7 +290,7 @@ uint32_t NimBLEServer::getConnectedCount() { return 0; } // BLE_GAP_EVENT_SUBSCRIBE - + case BLE_GAP_EVENT_MTU: { NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d", event->mtu.conn_handle, @@ -295,7 +298,7 @@ uint32_t NimBLEServer::getConnectedCount() { server->updatePeerMTU(event->mtu.conn_handle, event->mtu.value); return 0; } // BLE_GAP_EVENT_MTU - + case BLE_GAP_EVENT_NOTIFY_TX: { if(event->notify_tx.indication && event->notify_tx.status != 0) { auto it = server->m_notifyChrMap.find(event->notify_tx.attr_handle); @@ -303,15 +306,15 @@ uint32_t NimBLEServer::getConnectedCount() { (*it).second->m_semaphoreConfEvt.give(event->notify_tx.status); } } - + return 0; } // BLE_GAP_EVENT_NOTIFY_TX - + case BLE_GAP_EVENT_CONN_UPDATE: { NIMBLE_LOGD(LOG_TAG, "Connection parameters updated."); return 0; } // BLE_GAP_EVENT_CONN_UPDATE - + case BLE_GAP_EVENT_REPEAT_PAIRING: { /* We already have a bond with the peer, but it is attempting to * establish a new secure link. This app sacrifices security for @@ -328,8 +331,8 @@ uint32_t NimBLEServer::getConnectedCount() { */ return BLE_GAP_REPEAT_PAIRING_RETRY; } // BLE_GAP_EVENT_REPEAT_PAIRING - - case BLE_GAP_EVENT_ENC_CHANGE: { + + case BLE_GAP_EVENT_ENC_CHANGE: { rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); if(rc != 0) { return BLE_ATT_ERR_INVALID_HANDLE; @@ -341,10 +344,10 @@ uint32_t NimBLEServer::getConnectedCount() { } else { server->m_pServerCallbacks->onAuthenticationComplete(&desc); } - + return 0; } // BLE_GAP_EVENT_ENC_CHANGE - + case BLE_GAP_EVENT_PASSKEY_ACTION: { struct ble_sm_io pkey = {0}; @@ -359,7 +362,7 @@ uint32_t NimBLEServer::getConnectedCount() { } rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc); - + } else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %d", event->passkey.params.numcmp); pkey.action = event->passkey.params.action; @@ -370,11 +373,11 @@ uint32_t NimBLEServer::getConnectedCount() { } else { pkey.numcmp_accept = server->m_pServerCallbacks->onConfirmPIN(event->passkey.params.numcmp); } - + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc); - - //TODO: Handle out of band pairing + + //TODO: Handle out of band pairing } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) { static uint8_t tem_oob[16] = {0}; pkey.action = event->passkey.params.action; @@ -383,35 +386,35 @@ uint32_t NimBLEServer::getConnectedCount() { } rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_OOB; ble_sm_inject_io result: %d", rc); - ////////////////////////////////// + ////////////////////////////////// } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) { NIMBLE_LOGD(LOG_TAG, "Enter the passkey"); pkey.action = event->passkey.params.action; - + // Compatibility only - Do not use, should be removed the in future if(NimBLEDevice::m_securityCallbacks != nullptr) { pkey.passkey = NimBLEDevice::m_securityCallbacks->onPassKeyRequest(); ///////////////////////////////////////////// } else { pkey.passkey = server->m_pServerCallbacks->onPassKeyRequest(); - } + } rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_INPUT; ble_sm_inject_io result: %d", rc); - + } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { NIMBLE_LOGD(LOG_TAG, "No passkey action required"); } - + NIMBLE_LOGD(LOG_TAG, "<< handleGATTServerEvent"); return 0; } // BLE_GAP_EVENT_PASSKEY_ACTION - default: - break; - } + default: + break; + } - NIMBLE_LOGD(LOG_TAG, "<< handleGATTServerEvent"); + NIMBLE_LOGD(LOG_TAG, "<< handleGATTServerEvent"); return 0; } // handleGATTServerEvent @@ -427,10 +430,10 @@ uint32_t NimBLEServer::getConnectedCount() { */ void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks) { if (pCallbacks != nullptr){ - m_pServerCallbacks = pCallbacks; - } else { - m_pServerCallbacks = &defaultCallbacks; - } + m_pServerCallbacks = pCallbacks; + } else { + m_pServerCallbacks = &defaultCallbacks; + } } // setCallbacks @@ -439,9 +442,9 @@ void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks) { */ /* void BLEServer::removeService(BLEService* service) { - service->stop(); - service->executeDelete(); - m_serviceMap.removeService(service); + service->stop(); + service->executeDelete(); + m_serviceMap.removeService(service); } */ @@ -453,9 +456,9 @@ void BLEServer::removeService(BLEService* service) { * retrieving the advertising object and invoking start upon it. */ void NimBLEServer::startAdvertising() { - NIMBLE_LOGD(LOG_TAG, ">> startAdvertising"); - NimBLEDevice::startAdvertising(); - NIMBLE_LOGD(LOG_TAG, "<< startAdvertising"); + NIMBLE_LOGD(LOG_TAG, ">> startAdvertising"); + NimBLEDevice::startAdvertising(); + NIMBLE_LOGD(LOG_TAG, "<< startAdvertising"); } // startAdvertising @@ -463,51 +466,51 @@ void NimBLEServer::startAdvertising() { * @brief Stop advertising. */ void NimBLEServer::stopAdvertising() { - NIMBLE_LOGD(LOG_TAG, ">> stopAdvertising"); - NimBLEDevice::stopAdvertising(); - NIMBLE_LOGD(LOG_TAG, "<< stopAdvertising"); + NIMBLE_LOGD(LOG_TAG, ">> stopAdvertising"); + NimBLEDevice::stopAdvertising(); + NIMBLE_LOGD(LOG_TAG, "<< stopAdvertising"); } // startAdvertising - + /** * Allow to connect GATT server to peer device * Probably can be used in ANCS for iPhone */ /* bool BLEServer::connect(BLEAddress address) { - esp_bd_addr_t addr; - memcpy(&addr, address.getNative(), 6); - // Perform the open connection request against the target BLE Server. - m_semaphoreOpenEvt.take("connect"); - esp_err_t errRc = ::esp_ble_gatts_open( - getGattsIf(), - addr, // address - 1 // direct connection - ); - if (errRc != ESP_OK) { - ESP_LOGE(LOG_TAG, "esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); - return false; - } + esp_bd_addr_t addr; + memcpy(&addr, address.getNative(), 6); + // Perform the open connection request against the target BLE Server. + m_semaphoreOpenEvt.take("connect"); + esp_err_t errRc = ::esp_ble_gatts_open( + getGattsIf(), + addr, // address + 1 // direct connection + ); + if (errRc != ESP_OK) { + ESP_LOGE(LOG_TAG, "esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); + return false; + } - uint32_t rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete. - ESP_LOGD(LOG_TAG, "<< connect(), rc=%d", rc==ESP_GATT_OK); - return rc == ESP_GATT_OK; + uint32_t rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete. + ESP_LOGD(LOG_TAG, "<< connect(), rc=%d", rc==ESP_GATT_OK); + return rc == ESP_GATT_OK; } // connect */ void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer) { - NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default"); + NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default"); } // onConnect void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) { - NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default"); + NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default"); } // onConnect void NimBLEServerCallbacks::onDisconnect(NimBLEServer* pServer) { - NIMBLE_LOGD("NimBLEServerCallbacks", "onDisconnect(): Default"); + NIMBLE_LOGD("NimBLEServerCallbacks", "onDisconnect(): Default"); } // onDisconnect uint32_t NimBLEServerCallbacks::onPassKeyRequest(){ @@ -533,14 +536,14 @@ bool NimBLEServerCallbacks::onConfirmPIN(uint32_t pin){ /* multi connect support */ void NimBLEServer::updatePeerMTU(uint16_t conn_id, uint16_t mtu) { - const std::map::iterator it = m_connectedServersMap.find(conn_id); - if (it != m_connectedServersMap.end()) { - it->second.mtu = mtu; - } + const std::map::iterator it = m_connectedServersMap.find(conn_id); + if (it != m_connectedServersMap.end()) { + it->second.mtu = mtu; + } } std::map NimBLEServer::getPeerDevices() { - return m_connectedServersMap; + return m_connectedServersMap; } @@ -558,17 +561,17 @@ uint16_t NimBLEServer::getPeerMTU(uint16_t conn_id) { } void NimBLEServer::addPeerDevice(void* peer, bool _client, uint16_t conn_id) { - conn_status_t status = { - .peer_device = peer, - .connected = true, - .mtu = 23 - }; + conn_status_t status = { + .peer_device = peer, + .connected = true, + .mtu = 23 + }; - m_connectedServersMap.insert(std::pair(conn_id, status)); + m_connectedServersMap.insert(std::pair(conn_id, status)); } void NimBLEServer::removePeerDevice(uint16_t conn_id, bool _client) { - m_connectedServersMap.erase(conn_id); + m_connectedServersMap.erase(conn_id); } /* multi connect support */ @@ -576,20 +579,20 @@ void NimBLEServer::removePeerDevice(uint16_t conn_id, bool _client) { /** * Update connection parameters can be called only after connection has been established */ -void NimBLEServer::updateConnParams(uint16_t conn_handle, - uint16_t minInterval, uint16_t maxInterval, +void NimBLEServer::updateConnParams(uint16_t conn_handle, + uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout, - uint16_t minConnTime, uint16_t maxConnTime) + uint16_t minConnTime, uint16_t maxConnTime) { - ble_gap_upd_params params; + ble_gap_upd_params params; - params.latency = latency; - params.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms - params.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms - params.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms + params.latency = latency; + params.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms + params.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms + params.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms params.min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units params.max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units - + int rc = ble_gap_update_params(conn_handle, ¶ms); if(rc != 0) { NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); @@ -602,7 +605,9 @@ void NimBLEServer::onHostReset() { for(auto it = m_notifyChrMap.cbegin(); it != m_notifyChrMap.cend(); ++it) { (*it).second->m_semaphoreConfEvt.give(0); } - + } */ -#endif // CONFIG_BT_ENABLED \ No newline at end of file + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEServer.h b/libesp32/NimBLE-Arduino/src/NimBLEServer.h index 436f20361..903eb2392 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEServer.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEServer.h @@ -3,7 +3,7 @@ * * Created: on March 2, 2020 * Author H2zero - * + * * Originally: * * BLEServer.h @@ -17,6 +17,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLEAddress.h" #include "NimBLEUUID.h" #include "NimBLEAdvertising.h" @@ -24,14 +27,13 @@ #include "NimBLESecurity.h" #include "FreeRTOS.h" - #include class NimBLEService; class NimBLECharacteristic; class NimBLEServerCallbacks; -/* TODO possibly refactor this struct */ +/* TODO possibly refactor this struct */ typedef struct { void *peer_device; // peer device BLEClient or BLEServer - maybe its better to have 2 structures or union here bool connected; // do we need it? @@ -45,11 +47,11 @@ typedef struct { class NimBLEServiceMap { public: // NimBLEService* getByHandle(uint16_t handle); - NimBLEService* getByUUID(const char* uuid); - NimBLEService* getByUUID(NimBLEUUID uuid, uint8_t inst_id = 0); + NimBLEService* getByUUID(const char* uuid); + NimBLEService* getByUUID(const NimBLEUUID &uuid, uint8_t inst_id = 0); // void setByHandle(uint16_t handle, NimBLEService* service); void setByUUID(const char* uuid, NimBLEService* service); - void setByUUID(NimBLEUUID uuid, NimBLEService* service); + void setByUUID(const NimBLEUUID &uuid, NimBLEService* service); std::string toString(); NimBLEService* getFirst(); NimBLEService* getNext(); @@ -69,8 +71,8 @@ private: class NimBLEServer { public: uint32_t getConnectedCount(); - NimBLEService* createService(const char* uuid); - NimBLEService* createService(NimBLEUUID uuid, uint32_t numHandles=15, uint8_t inst_id=0); + NimBLEService* createService(const char* uuid); + NimBLEService* createService(const NimBLEUUID &uuid, uint32_t numHandles=15, uint8_t inst_id=0); NimBLEAdvertising* getAdvertising(); void setCallbacks(NimBLEServerCallbacks* pCallbacks); void startAdvertising(); @@ -78,11 +80,11 @@ public: void start(); // void removeService(BLEService* service); NimBLEService* getServiceByUUID(const char* uuid); - NimBLEService* getServiceByUUID(NimBLEUUID uuid); + NimBLEService* getServiceByUUID(const NimBLEUUID &uuid); int disconnect(uint16_t connID, uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); // bool connect(BLEAddress address); - void updateConnParams(uint16_t conn_handle, - uint16_t minInterval, uint16_t maxInterval, + void updateConnParams(uint16_t conn_handle, + uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout, uint16_t minConnTime=0, uint16_t maxConnTime=0); @@ -106,15 +108,15 @@ private: // BLEAdvertising m_bleAdvertising; uint16_t m_connId; uint16_t m_svcChgChrHdl; - bool m_gattsStarted; - + bool m_gattsStarted; + std::map m_connectedServersMap; std::map m_notifyChrMap; NimBLEServiceMap m_serviceMap; NimBLEServerCallbacks* m_pServerCallbacks; - static int handleGapEvent(struct ble_gap_event *event, void *arg); + static int handleGapEvent(struct ble_gap_event *event, void *arg); }; // NimBLEServer @@ -141,7 +143,7 @@ public: * @param [in] pServer A reference to the %BLE server that received the existing client disconnection. */ virtual void onDisconnect(NimBLEServer* pServer); - + virtual uint32_t onPassKeyRequest(); //{return 0;} virtual void onPassKeyNotify(uint32_t pass_key); //{} virtual bool onSecurityRequest(); //{return true;} @@ -150,5 +152,6 @@ public: }; // BLEServerCallbacks +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif /* CONFIG_BT_ENABLED */ -#endif /* MAIN_NIMBLESERVER_H_ */ \ No newline at end of file +#endif /* MAIN_NIMBLESERVER_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEService.cpp b/libesp32/NimBLE-Arduino/src/NimBLEService.cpp index 4bf6f34ff..6036a38ad 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEService.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEService.cpp @@ -3,7 +3,7 @@ * * Created: on March 2, 2020 * Author H2zero - * + * * Originally: * * BLEService.cpp @@ -17,6 +17,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLEService.h" #include "NimBLEUtils.h" #include "NimBLELog.h" @@ -33,7 +36,7 @@ static const char* LOG_TAG = "NimBLEService"; // Tag for logging. * @param [in] uuid The UUID of the service. * @param [in] numHandles The maximum number of handles associated with the service. */ -NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer) +NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer) : NimBLEService(NimBLEUUID(uuid), numHandles, pServer) { } @@ -43,11 +46,11 @@ NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer * @param [in] uuid The UUID of the service. * @param [in] numHandles The maximum number of handles associated with the service. */ -NimBLEService::NimBLEService(NimBLEUUID uuid, uint16_t numHandles, NimBLEServer* pServer) { - m_uuid = uuid; - m_handle = NULL_HANDLE; - m_pServer = pServer; - m_numHandles = numHandles; +NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer) { + m_uuid = uuid; + m_handle = NULL_HANDLE; + m_pServer = pServer; + m_numHandles = numHandles; } // NimBLEService @@ -56,10 +59,10 @@ NimBLEService::NimBLEService(NimBLEUUID uuid, uint16_t numHandles, NimBLEServer* * @return N/A. */ void NimBLEService::dump() { - NIMBLE_LOGD(LOG_TAG, "Service: uuid:%s, handle: 0x%.2x", - m_uuid.toString().c_str(), - m_handle); - NIMBLE_LOGD(LOG_TAG, "Characteristics:\n%s", m_characteristicMap.toString().c_str()); + NIMBLE_LOGD(LOG_TAG, "Service: uuid:%s, handle: 0x%.2x", + m_uuid.toString().c_str(), + m_handle); + NIMBLE_LOGD(LOG_TAG, "Characteristics:\n%s", m_characteristicMap.toString().c_str()); } // dump @@ -68,7 +71,7 @@ void NimBLEService::dump() { * @return the UUID of the service. */ NimBLEUUID NimBLEService::getUUID() { - return m_uuid; + return m_uuid; } // getUUID @@ -78,45 +81,46 @@ NimBLEUUID NimBLEService::getUUID() { * Starting a service also means that we can create the corresponding characteristics. * @return Start the service. */ - + bool NimBLEService::start() { - NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: %s", toString().c_str()); - int rc = 0; - // Nimble requires an array of services to be sent to the api - // Since we are adding 1 at a time we create an array of 2 and set the type - // of the second service to 0 to indicate the end of the array. + NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: %s", toString().c_str()); + int rc = 0; + // Nimble requires an array of services to be sent to the api + // Since we are adding 1 at a time we create an array of 2 and set the type + // of the second service to 0 to indicate the end of the array. ble_gatt_svc_def* svc = new ble_gatt_svc_def[2]; - ble_gatt_chr_def* pChr_a = nullptr; + ble_gatt_chr_def* pChr_a = nullptr; ble_gatt_dsc_def* pDsc_a = nullptr; - + svc[0].type = BLE_GATT_SVC_TYPE_PRIMARY; svc[0].uuid = &m_uuid.getNative()->u; - svc[0].includes = NULL; - - uint8_t numChrs = m_characteristicMap.getSize(); - - NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str()); - - if(!numChrs){ - svc[0].characteristics = NULL; - }else{ + svc[0].includes = NULL; + + uint8_t numChrs = m_characteristicMap.getSize(); + + NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str()); + + if(!numChrs){ + svc[0].characteristics = NULL; + }else{ // Nimble requires the last characteristic to have it's uuid = 0 to indicate the end // of the characteristics for the service. We create 1 extra and set it to null // for this purpose. - pChr_a = new ble_gatt_chr_def[numChrs+1]; - NimBLECharacteristic* pCharacteristic = m_characteristicMap.getFirst(); - - for(uint8_t i=0; i < numChrs; i++) { + pChr_a = new ble_gatt_chr_def[numChrs+1]; + NimBLECharacteristic* pCharacteristic = m_characteristicMap.getFirst(); + + for(uint8_t i=0; i < numChrs; i++) { uint8_t numDscs = pCharacteristic->m_descriptorMap.getSize(); if(numDscs) { // skip 2902 as it's automatically created by NimBLE // if Indicate or Notify flags are set - if((pCharacteristic->m_properties & BLE_GATT_CHR_F_INDICATE) || - (pCharacteristic->m_properties & BLE_GATT_CHR_F_NOTIFY)) { + if(((pCharacteristic->m_properties & BLE_GATT_CHR_F_INDICATE) || + (pCharacteristic->m_properties & BLE_GATT_CHR_F_NOTIFY)) && + pCharacteristic->getDescriptorByUUID("2902") != nullptr) { numDscs--; } } - + if(!numDscs){ pChr_a[i].descriptors = NULL; } else { @@ -139,41 +143,41 @@ bool NimBLEService::start() { pDescriptor = pCharacteristic->m_descriptorMap.getNext(); d++; } - + pDsc_a[numDscs].uuid = NULL; pChr_a[i].descriptors = pDsc_a; } - - pChr_a[i].uuid = &pCharacteristic->m_uuid.getNative()->u; + + pChr_a[i].uuid = &pCharacteristic->m_uuid.getNative()->u; pChr_a[i].access_cb = NimBLECharacteristic::handleGapEvent; pChr_a[i].arg = pCharacteristic; pChr_a[i].flags = pCharacteristic->m_properties; pChr_a[i].min_key_size = 0; pChr_a[i].val_handle = &pCharacteristic->m_handle; - pCharacteristic = m_characteristicMap.getNext(); - } - - pChr_a[numChrs].uuid = NULL; - svc[0].characteristics = pChr_a; - } - - // end of services must indicate to api with type = 0 - svc[1].type = 0; - + pCharacteristic = m_characteristicMap.getNext(); + } + + pChr_a[numChrs].uuid = NULL; + svc[0].characteristics = pChr_a; + } + + // end of services must indicate to api with type = 0 + svc[1].type = 0; + rc = ble_gatts_count_cfg((const ble_gatt_svc_def*)svc); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gatts_count_cfg failed, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); return false; } - + rc = ble_gatts_add_svcs((const ble_gatt_svc_def*)svc); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gatts_add_svcs, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); return false; - + } - NIMBLE_LOGD(LOG_TAG, "<< start()"); + NIMBLE_LOGD(LOG_TAG, "<< start()"); return true; } // start @@ -183,13 +187,13 @@ bool NimBLEService::start() { * @param [in] handle The handle associated with the service. */ void NimBLEService::setHandle(uint16_t handle) { - NIMBLE_LOGD(LOG_TAG, ">> setHandle - Handle=0x%.2x, service UUID=%s)", handle, getUUID().toString().c_str()); - if (m_handle != NULL_HANDLE) { - NIMBLE_LOGE(LOG_TAG, "!!! Handle is already set %.2x", m_handle); - return; - } - m_handle = handle; - NIMBLE_LOGD(LOG_TAG, "<< setHandle"); + NIMBLE_LOGD(LOG_TAG, ">> setHandle - Handle=0x%.2x, service UUID=%s)", handle, getUUID().toString().c_str()); + if (m_handle != NULL_HANDLE) { + NIMBLE_LOGE(LOG_TAG, "!!! Handle is already set %.2x", m_handle); + return; + } + m_handle = handle; + NIMBLE_LOGD(LOG_TAG, "<< setHandle"); } // setHandle @@ -198,7 +202,7 @@ void NimBLEService::setHandle(uint16_t handle) { * @return The handle associated with this service. */ uint16_t NimBLEService::getHandle() { - return m_handle; + return m_handle; } // getHandle @@ -207,26 +211,26 @@ uint16_t NimBLEService::getHandle() { * @param [in] pCharacteristic A pointer to the characteristic to be added. */ void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) { - // We maintain a mapping of characteristics owned by this service. These are managed by the - // BLECharacteristicMap class instance found in m_characteristicMap. We add the characteristic - // to the map and then ask the service to add the characteristic at the BLE level (ESP-IDF). + // We maintain a mapping of characteristics owned by this service. These are managed by the + // BLECharacteristicMap class instance found in m_characteristicMap. We add the characteristic + // to the map and then ask the service to add the characteristic at the BLE level (ESP-IDF). - NIMBLE_LOGD(LOG_TAG, ">> addCharacteristic()"); - NIMBLE_LOGD(LOG_TAG, "Adding characteristic: uuid=%s to service: %s", - pCharacteristic->getUUID().toString().c_str(), - toString().c_str()); + NIMBLE_LOGD(LOG_TAG, ">> addCharacteristic()"); + NIMBLE_LOGD(LOG_TAG, "Adding characteristic: uuid=%s to service: %s", + pCharacteristic->getUUID().toString().c_str(), + toString().c_str()); - // Check that we don't add the same characteristic twice. - if (m_characteristicMap.getByUUID(pCharacteristic->getUUID()) != nullptr) { - NIMBLE_LOGW(LOG_TAG, "<< Adding a new characteristic with the same UUID as a previous one"); - //return; - } + // Check that we don't add the same characteristic twice. + if (m_characteristicMap.getByUUID(pCharacteristic->getUUID()) != nullptr) { + NIMBLE_LOGW(LOG_TAG, "<< Adding a new characteristic with the same UUID as a previous one"); + //return; + } - // Remember this characteristic in our map of characteristics. At this point, we can lookup by UUID - // but not by handle. The handle is allocated to us on the ESP_GATTS_ADD_CHAR_EVT. - m_characteristicMap.setByUUID(pCharacteristic, pCharacteristic->getUUID()); + // Remember this characteristic in our map of characteristics. At this point, we can lookup by UUID + // but not by handle. The handle is allocated to us on the ESP_GATTS_ADD_CHAR_EVT. + m_characteristicMap.setByUUID(pCharacteristic, pCharacteristic->getUUID()); - NIMBLE_LOGD(LOG_TAG, "<< addCharacteristic()"); + NIMBLE_LOGD(LOG_TAG, "<< addCharacteristic()"); } // addCharacteristic @@ -237,7 +241,7 @@ void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) { * @return The new BLE characteristic. */ NimBLECharacteristic* NimBLEService::createCharacteristic(const char* uuid, uint32_t properties) { - return createCharacteristic(NimBLEUUID(uuid), properties); + return createCharacteristic(NimBLEUUID(uuid), properties); } @@ -247,21 +251,21 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const char* uuid, uint * @param [in] properties - The properties of the characteristic. * @return The new BLE characteristic. */ -NimBLECharacteristic* NimBLEService::createCharacteristic(NimBLEUUID uuid, uint32_t properties) { - NimBLECharacteristic* pCharacteristic = new NimBLECharacteristic(uuid, properties, this); - addCharacteristic(pCharacteristic); +NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid, uint32_t properties) { + NimBLECharacteristic* pCharacteristic = new NimBLECharacteristic(uuid, properties, this); + addCharacteristic(pCharacteristic); //pCharacteristic->executeCreate(this); - return pCharacteristic; + return pCharacteristic; } // createCharacteristic NimBLECharacteristic* NimBLEService::getCharacteristic(const char* uuid) { - return getCharacteristic(NimBLEUUID(uuid)); + return getCharacteristic(NimBLEUUID(uuid)); } -NimBLECharacteristic* NimBLEService::getCharacteristic(NimBLEUUID uuid) { - return m_characteristicMap.getByUUID(uuid); +NimBLECharacteristic* NimBLEService::getCharacteristic(const NimBLEUUID &uuid) { + return m_characteristicMap.getByUUID(uuid); } @@ -273,12 +277,12 @@ NimBLECharacteristic* NimBLEService::getCharacteristic(NimBLEUUID uuid) { * @return A string representation of this service. */ std::string NimBLEService::toString() { - std::string res = "UUID: " + getUUID().toString(); - char hex[5]; - snprintf(hex, sizeof(hex), "%04x", getHandle()); - res += ", handle: 0x"; - res += hex; - return res; + std::string res = "UUID: " + getUUID().toString(); + char hex[5]; + snprintf(hex, sizeof(hex), "%04x", getHandle()); + res += ", handle: 0x"; + res += hex; + return res; } // toString @@ -287,7 +291,8 @@ std::string NimBLEService::toString() { * @return The BLEServer associated with this service. */ NimBLEServer* NimBLEService::getServer() { - return m_pServer; + return m_pServer; } // getServer -#endif // CONFIG_BT_ENABLED \ No newline at end of file +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEService.h b/libesp32/NimBLE-Arduino/src/NimBLEService.h index 70fed3bb2..1cb0f6153 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEService.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEService.h @@ -3,7 +3,7 @@ * * Created: on March 2, 2020 * Author H2zero - * + * * Originally: * * BLEService.h @@ -17,6 +17,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLECharacteristic.h" #include "NimBLEServer.h" #include "NimBLEUUID.h" @@ -31,21 +34,21 @@ class NimBLECharacteristic; */ class NimBLECharacteristicMap { public: - void setByUUID(NimBLECharacteristic* pCharacteristic, const char* uuid); - void setByUUID(NimBLECharacteristic* pCharacteristic, NimBLEUUID uuid); - void setByHandle(uint16_t handle, NimBLECharacteristic* pCharacteristic); - NimBLECharacteristic* getByUUID(const char* uuid); - NimBLECharacteristic* getByUUID(NimBLEUUID uuid); - NimBLECharacteristic* getByHandle(uint16_t handle); - NimBLECharacteristic* getFirst(); - NimBLECharacteristic* getNext(); - uint8_t getSize(); - std::string toString(); + void setByUUID(NimBLECharacteristic* pCharacteristic, const char* uuid); + void setByUUID(NimBLECharacteristic* pCharacteristic, const NimBLEUUID &uuid); + void setByHandle(uint16_t handle, NimBLECharacteristic* pCharacteristic); + NimBLECharacteristic* getByUUID(const char* uuid); + NimBLECharacteristic* getByUUID(const NimBLEUUID &uuid); + NimBLECharacteristic* getByHandle(uint16_t handle); + NimBLECharacteristic* getFirst(); + NimBLECharacteristic* getNext(); + uint8_t getSize(); + std::string toString(); private: - std::map m_uuidMap; - std::map m_handleMap; - std::map::iterator m_iterator; + std::map m_uuidMap; + std::map m_handleMap; + std::map::iterator m_iterator; }; @@ -55,42 +58,43 @@ private: */ class NimBLEService { public: - NimBLECharacteristic* createCharacteristic(const char* uuid, - uint32_t properties = NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE); - - NimBLECharacteristic* createCharacteristic(NimBLEUUID uuid, - uint32_t properties = NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE); - - void dump(); - NimBLECharacteristic* getCharacteristic(const char* uuid); - NimBLECharacteristic* getCharacteristic(NimBLEUUID uuid); - NimBLEUUID getUUID(); - NimBLEServer* getServer(); - bool start(); -// void stop(); - std::string toString(); - uint16_t getHandle(); - uint8_t m_instId = 0; + NimBLECharacteristic* createCharacteristic(const char* uuid, + uint32_t properties = NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE); + + NimBLECharacteristic* createCharacteristic(const NimBLEUUID &uuid, + uint32_t properties = NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE); + + void dump(); + NimBLECharacteristic* getCharacteristic(const char* uuid); + NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid); + NimBLEUUID getUUID(); + NimBLEServer* getServer(); + bool start(); +// void stop(); + std::string toString(); + uint16_t getHandle(); + uint8_t m_instId = 0; private: - NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer); - NimBLEService(NimBLEUUID uuid, uint16_t numHandles, NimBLEServer* pServer); - friend class NimBLEServer; - friend class NimBLEDevice; - - void addCharacteristic(NimBLECharacteristic* pCharacteristic); + NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer); + NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer); + friend class NimBLEServer; + friend class NimBLEDevice; - NimBLECharacteristicMap m_characteristicMap; - uint16_t m_handle; - NimBLEServer* m_pServer = nullptr; - NimBLEUUID m_uuid; + void addCharacteristic(NimBLECharacteristic* pCharacteristic); - uint16_t m_numHandles; - void setHandle(uint16_t handle); + NimBLECharacteristicMap m_characteristicMap; + uint16_t m_handle; + NimBLEServer* m_pServer = nullptr; + NimBLEUUID m_uuid; + + uint16_t m_numHandles; + void setHandle(uint16_t handle); }; // BLEService +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif // CONFIG_BT_ENABLED -#endif /* MAIN_NIMBLESERVICE_H_ */ \ No newline at end of file +#endif /* MAIN_NIMBLESERVICE_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEServiceMap.cpp b/libesp32/NimBLE-Arduino/src/NimBLEServiceMap.cpp index 779c49a13..e5b96e676 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEServiceMap.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEServiceMap.cpp @@ -3,7 +3,7 @@ * * Created: on March 7, 2020 * Author H2zero - * + * * Originally: * * BLEServiceMap.cpp @@ -14,6 +14,9 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLEService.h" @@ -23,7 +26,7 @@ * @return The characteristic. */ NimBLEService* NimBLEServiceMap::getByUUID(const char* uuid) { - return getByUUID(NimBLEUUID(uuid)); + return getByUUID(NimBLEUUID(uuid)); } /** @@ -31,14 +34,14 @@ NimBLEService* NimBLEServiceMap::getByUUID(const char* uuid) { * @param [in] UUID The UUID to look up the service. * @return The characteristic. */ -NimBLEService* NimBLEServiceMap::getByUUID(NimBLEUUID uuid, uint8_t inst_id) { - for (auto &myPair : m_uuidMap) { - if (myPair.first->getUUID().equals(uuid)) { - return myPair.first; - } - } - //return m_uuidMap.at(uuid.toString()); - return nullptr; +NimBLEService* NimBLEServiceMap::getByUUID(const NimBLEUUID &uuid, uint8_t inst_id) { + for (auto &myPair : m_uuidMap) { + if (myPair.first->getUUID().equals(uuid)) { + return myPair.first; + } + } + //return m_uuidMap.at(uuid.toString()); + return nullptr; } // getByUUID @@ -49,7 +52,7 @@ NimBLEService* NimBLEServiceMap::getByUUID(NimBLEUUID uuid, uint8_t inst_id) { */ /* NimBLEService* NimBLEServiceMap::getByHandle(uint16_t handle) { - return m_handleMap.at(handle); + return m_handleMap.at(handle); } // getByHandle */ @@ -59,8 +62,8 @@ NimBLEService* NimBLEServiceMap::getByHandle(uint16_t handle) { * @param [in] characteristic The service to cache. * @return N/A. */ -void NimBLEServiceMap::setByUUID(NimBLEUUID uuid, NimBLEService* service) { - m_uuidMap.insert(std::pair(service, uuid.toString())); +void NimBLEServiceMap::setByUUID(const NimBLEUUID &uuid, NimBLEService* service) { + m_uuidMap.insert(std::pair(service, uuid.toString())); } // setByUUID @@ -72,7 +75,7 @@ void NimBLEServiceMap::setByUUID(NimBLEUUID uuid, NimBLEService* service) { */ /* void NimBLEServiceMap::setByHandle(uint16_t handle, NimBLEService* service) { - m_handleMap.insert(std::pair(handle, service)); + m_handleMap.insert(std::pair(handle, service)); } // setByHandle */ @@ -81,15 +84,15 @@ void NimBLEServiceMap::setByHandle(uint16_t handle, NimBLEService* service) { * @return A string representation of the service map. */ std::string NimBLEServiceMap::toString() { - std::string res; - //char hex[5]; - for (auto &myPair: m_uuidMap) { - // res += "handle: 0x"; - // snprintf(hex, sizeof(hex), "%04x", myPair.first); - // res += hex; - res += ", uuid: " + myPair.second + "\n"; - } - return res; + std::string res; + //char hex[5]; + for (auto &myPair: m_uuidMap) { + // res += "handle: 0x"; + // snprintf(hex, sizeof(hex), "%04x", myPair.first); + // res += hex; + res += ", uuid: " + myPair.second + "\n"; + } + return res; } // toString @@ -98,40 +101,45 @@ std::string NimBLEServiceMap::toString() { * @return The first service in the map. */ NimBLEService* NimBLEServiceMap::getFirst() { - m_iterator = m_uuidMap.begin(); - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLEService* pRet = m_iterator->first; - m_iterator++; - return pRet; + m_iterator = m_uuidMap.begin(); + if (m_iterator == m_uuidMap.end()) return nullptr; + NimBLEService* pRet = m_iterator->first; + m_iterator++; + return pRet; } // getFirst + /** * @brief Get the next service in the map. * @return The next service in the map. */ NimBLEService* NimBLEServiceMap::getNext() { - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLEService* pRet = m_iterator->first; - m_iterator++; - return pRet; + if (m_iterator == m_uuidMap.end()) return nullptr; + NimBLEService* pRet = m_iterator->first; + m_iterator++; + return pRet; } // getNext + /** * @brief Removes service from maps. * @return N/A. */ void NimBLEServiceMap::removeService(NimBLEService* service) { - //m_handleMap.erase(service->getHandle()); - m_uuidMap.erase(service); + //m_handleMap.erase(service->getHandle()); + m_uuidMap.erase(service); } // removeService + /** * @brief Returns the amount of registered services * @return amount of registered services */ int NimBLEServiceMap::getRegisteredServiceCount(){ - //return m_handleMap.size(); + //return m_handleMap.size(); return m_uuidMap.size(); } -#endif /* CONFIG_BT_ENABLED */ \ No newline at end of file + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUUID.cpp b/libesp32/NimBLE-Arduino/src/NimBLEUUID.cpp index 0002d1911..4a9d7e876 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEUUID.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEUUID.cpp @@ -3,7 +3,7 @@ * * Created: on Jan 24 2020 * Author H2zero - * + * * Originally: * * BLEUUID.cpp @@ -18,6 +18,8 @@ #include "NimBLEUUID.h" #include "NimBLELog.h" +#include + static const char* LOG_TAG = "NimBLEUUID"; @@ -38,54 +40,29 @@ static const char* LOG_TAG = "NimBLEUUID"; * * @param [in] value The string to build a UUID from. */ - NimBLEUUID::NimBLEUUID(std::string value) { + NimBLEUUID::NimBLEUUID(const std::string &value) { m_valueSet = true; if (value.length() == 4) { m_uuid.u.type = BLE_UUID_TYPE_16; - m_uuid.u16.value = 0; - for(int i=0;i '9') MSB -= 7; - if(LSB > '9') LSB -= 7; - m_uuid.u16.value += (((MSB&0x0F) <<4) | (LSB & 0x0F))<<(2-i)*4; - i+=2; - } + m_uuid.u16.value = strtoul(value.c_str(), NULL, 16); } else if (value.length() == 8) { m_uuid.u.type = BLE_UUID_TYPE_32; - m_uuid.u32.value = 0; - for(int i=0;i '9') MSB -= 7; - if(LSB > '9') LSB -= 7; - m_uuid.u32.value += (((MSB&0x0F) <<4) | (LSB & 0x0F))<<(6-i)*4; - i+=2; - } + m_uuid.u32.value = strtoul(value.c_str(), NULL, 16); } - else if (value.length() == 16) { // how we can have 16 byte length string reprezenting 128 bit uuid??? needs to be investigated (lack of time) - m_uuid.u.type = BLE_UUID_TYPE_128; - NimBLEUtils::memrcpy(m_uuid.u128.value, (uint8_t*)value.data(), 16); + else if (value.length() == 16) { + *this = NimBLEUUID((uint8_t*)value.data(), 16, true); } else if (value.length() == 36) { // If the length of the string is 36 bytes then we will assume it is a long hex string in // UUID format. - m_uuid.u.type = BLE_UUID_TYPE_128; - int n = 0; - for(int i=0;i '9') MSB -= 7; - if(LSB > '9') LSB -= 7; - m_uuid.u128.value[15-n++] = ((MSB&0x0F) <<4) | (LSB & 0x0F); - i+=2; - } + char * position = const_cast(value.c_str()); + uint32_t first = strtoul(position, &position, 16); + uint16_t second = strtoul(position + 1, &position, 16); + uint16_t third = strtoul(position + 1, &position, 16); + uint16_t fourth = strtoul(position + 1, &position, 16); + uint64_t fifth = strtoull(position + 1, NULL, 16); + *this = NimBLEUUID(first, second, third, (uint64_t(fourth) << 48) + fifth); } else { NIMBLE_LOGE(LOG_TAG,"ERROR: UUID value not 2, 4, 16 or 36 bytes"); @@ -101,7 +78,7 @@ static const char* LOG_TAG = "NimBLEUUID"; * @param [in] size The size of the data. * @param [in] msbFirst Is the MSB first in pData memory? */ -NimBLEUUID::NimBLEUUID(uint8_t* pData, size_t size, bool msbFirst) { +NimBLEUUID::NimBLEUUID(const uint8_t* pData, size_t size, bool msbFirst) { /*** TODO: change this to use the Nimble function for various lenght UUIDs: int ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len); ***/ @@ -110,8 +87,9 @@ NimBLEUUID::NimBLEUUID(uint8_t* pData, size_t size, bool msbFirst) { return; } m_uuid.u.type = BLE_UUID_TYPE_128; + if (msbFirst) { - NimBLEUtils::memrcpy(m_uuid.u128.value, pData, 16); + std::reverse_copy(pData, pData + 16, m_uuid.u128.value); } else { memcpy(m_uuid.u128.value, pData, 16); } @@ -148,14 +126,33 @@ NimBLEUUID::NimBLEUUID(uint32_t uuid) { * * @param [in] uuid The native UUID. */ - -NimBLEUUID::NimBLEUUID(ble_uuid128_t* uuid) { +NimBLEUUID::NimBLEUUID(const ble_uuid128_t* uuid) { m_uuid.u.type = BLE_UUID_TYPE_128; memcpy(m_uuid.u128.value, uuid->value, 16); m_valueSet = true; } // NimBLEUUID +/** + * @brief Create a UUID from the 128bit value using hex parts instead of string, + * instead of BLEUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"), it becomes + * BLEUUID(0xebe0ccb0, 0x7a0a, 0x4b0c, 0x8a1a6ff2997da3a6) + * + * @param [in] first The first 32bit of the UUID. + * @param [in] second The next 16bit of the UUID. + * @param [in] third The next 16bit of the UUID. + * @param [in] fourth The last 64bit of the UUID, combining the last 2 parts of the string equivalent + */ +NimBLEUUID::NimBLEUUID(uint32_t first, uint16_t second, uint16_t third, uint64_t fourth) { + m_uuid.u.type = BLE_UUID_TYPE_128; + memcpy(m_uuid.u128.value + 12, &first, 4); + memcpy(m_uuid.u128.value + 10, &second, 2); + memcpy(m_uuid.u128.value + 8, &third, 2); + memcpy(m_uuid.u128.value, &fourth, 8); + m_valueSet = true; +} + + NimBLEUUID::NimBLEUUID() { m_valueSet = false; } // NimBLEUUID @@ -165,7 +162,7 @@ NimBLEUUID::NimBLEUUID() { * @brief Get the number of bits in this uuid. * @return The number of bits in the UUID. One of 16, 32 or 128. */ -uint8_t NimBLEUUID::bitSize() { +uint8_t NimBLEUUID::bitSize() const { if (!m_valueSet) return 0; return m_uuid.u.type; } // bitSize @@ -177,11 +174,8 @@ uint8_t NimBLEUUID::bitSize() { * @param [in] uuid The UUID to compare against. * @return True if the UUIDs are equal and false otherwise. */ -bool NimBLEUUID::equals(NimBLEUUID uuid) { - if(ble_uuid_cmp(&m_uuid.u, &uuid.getNative()->u) == 0){ - return true; - } - return false; +bool NimBLEUUID::equals(const NimBLEUUID &uuid) const { + return *this == uuid; } @@ -194,8 +188,7 @@ bool NimBLEUUID::equals(NimBLEUUID uuid) { * NNNNNNNN * */ - -NimBLEUUID NimBLEUUID::fromString(std::string _uuid) { +NimBLEUUID NimBLEUUID::fromString(const std::string &_uuid) { uint8_t start = 0; if (strstr(_uuid.c_str(), "0x") != nullptr) { // If the string starts with 0x, skip those characters. start = 2; @@ -220,7 +213,7 @@ NimBLEUUID NimBLEUUID::fromString(std::string _uuid) { * * @return The native UUID value or NULL if not set. */ -ble_uuid_any_t* NimBLEUUID::getNative() { +const ble_uuid_any_t* NimBLEUUID::getNative() const { if (m_valueSet == false) { NIMBLE_LOGD(LOG_TAG,"<< Return of un-initialized UUID!"); return nullptr; @@ -235,47 +228,20 @@ ble_uuid_any_t* NimBLEUUID::getNative() { * A UUID can be internally represented as 16bit, 32bit or the full 128bit. This method * will convert 16 or 32 bit representations to the full 128bit. */ -NimBLEUUID NimBLEUUID::to128() { +const NimBLEUUID &NimBLEUUID::to128() { // If we either don't have a value or are already a 128 bit UUID, nothing further to do. if (!m_valueSet || m_uuid.u.type == BLE_UUID_TYPE_128) { return *this; } - // If we are 16 bit or 32 bit, then set the 4 bytes of the variable part of the UUID. + // If we are 16 bit or 32 bit, then set the other bytes of the UUID. if (m_uuid.u.type == BLE_UUID_TYPE_16) { - uint16_t temp = m_uuid.u16.value; - m_uuid.u128.value[15] = 0; - m_uuid.u128.value[14] = 0; - m_uuid.u128.value[13] = (temp >> 8) & 0xff; - m_uuid.u128.value[12] = temp & 0xff; - + *this = NimBLEUUID(m_uuid.u16.value, 0x0000, 0x1000, 0x800000805f9b34fb); } else if (m_uuid.u.type == BLE_UUID_TYPE_32) { - uint32_t temp = m_uuid.u32.value; - m_uuid.u128.value[15] = (temp >> 24) & 0xff; - m_uuid.u128.value[14] = (temp >> 16) & 0xff; - m_uuid.u128.value[13] = (temp >> 8) & 0xff; - m_uuid.u128.value[12] = temp & 0xff; + *this = NimBLEUUID(m_uuid.u32.value, 0x0000, 0x1000, 0x800000805f9b34fb); } - // Set the fixed parts of the UUID. - m_uuid.u128.value[11] = 0x00; - m_uuid.u128.value[10] = 0x00; - - m_uuid.u128.value[9] = 0x10; - m_uuid.u128.value[8] = 0x00; - - m_uuid.u128.value[7] = 0x80; - m_uuid.u128.value[6] = 0x00; - - m_uuid.u128.value[5] = 0x00; - m_uuid.u128.value[4] = 0x80; - m_uuid.u128.value[3] = 0x5f; - m_uuid.u128.value[2] = 0x9b; - m_uuid.u128.value[1] = 0x34; - m_uuid.u128.value[0] = 0xfb; - - m_uuid.u.type = BLE_UUID_TYPE_128; return *this; } // to128 @@ -290,12 +256,32 @@ NimBLEUUID NimBLEUUID::to128() { * * @return A string representation of the UUID. */ -std::string NimBLEUUID::toString() { - if (!m_valueSet) return ""; // If we have no value, nothing to format. +std::string NimBLEUUID::toString() const { + return std::string(*this); +} // toString + + +bool NimBLEUUID::operator ==(const NimBLEUUID & rhs) const { + if(m_valueSet && rhs.m_valueSet) { + return ble_uuid_cmp(&m_uuid.u, &rhs.m_uuid.u) == 0; + } + + return m_valueSet == rhs.m_valueSet; +} + + +bool NimBLEUUID::operator !=(const NimBLEUUID & rhs) const { + return !this->operator==(rhs); +} + + +NimBLEUUID::operator std::string() const { + if (!m_valueSet) return std::string(); // If we have no value, nothing to format. char buf[BLE_UUID_STR_LEN]; return ble_uuid_to_str(&m_uuid.u, buf); -} // toString +} + #endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUUID.h b/libesp32/NimBLE-Arduino/src/NimBLEUUID.h index 63230fba5..f07bb3df5 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEUUID.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEUUID.h @@ -30,18 +30,23 @@ */ class NimBLEUUID { public: - NimBLEUUID(std::string uuid); + NimBLEUUID(const std::string &uuid); NimBLEUUID(uint16_t uuid); NimBLEUUID(uint32_t uuid); - NimBLEUUID(ble_uuid128_t* uuid); - NimBLEUUID(uint8_t* pData, size_t size, bool msbFirst); + NimBLEUUID(const ble_uuid128_t* uuid); + NimBLEUUID(const uint8_t* pData, size_t size, bool msbFirst); + NimBLEUUID(uint32_t first, uint16_t second, uint16_t third, uint64_t fourth); NimBLEUUID(); - uint8_t bitSize(); // Get the number of bits in this uuid. - bool equals(NimBLEUUID uuid); - ble_uuid_any_t* getNative(); - NimBLEUUID to128(); - std::string toString(); - static NimBLEUUID fromString(std::string uuid); // Create a NimBLEUUID from a string + uint8_t bitSize() const; // Get the number of bits in this uuid. + bool equals(const NimBLEUUID &uuid) const; + const ble_uuid_any_t* getNative() const; + const NimBLEUUID & to128(); + std::string toString() const; + static NimBLEUUID fromString(const std::string &uuid); // Create a NimBLEUUID from a string + + bool operator ==(const NimBLEUUID & rhs) const; + bool operator !=(const NimBLEUUID & rhs) const; + operator std::string() const; private: ble_uuid_any_t m_uuid; // The underlying UUID structure that this class wraps. diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp b/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp index 3911fd7ed..9036d4d30 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp @@ -3,7 +3,7 @@ * * Created: on Jan 25 2020 * Author H2zero - * + * */ #include "sdkconfig.h" @@ -11,38 +11,10 @@ #include "NimBLEUtils.h" #include "NimBLELog.h" +#include "nimconfig.h" -static const char* LOG_TAG = "NimBLEUtils"; +static const char* LOG_TAG = "NimBLEUtils"; -/** - * @brief Copy memory from source to target but in reverse order. - * - * When we move memory from one location it is normally: - * - * ``` - * [0][1][2]...[n] -> [0][1][2]...[n] - * ``` - * - * with this function, it is: - * - * ``` - * [0][1][2]...[n] -> [n][n-1][n-2]...[0] - * ``` - * - * @param [in] target The target of the copy - * @param [in] source The source of the copy - * @param [in] size The number of bytes to copy - */ -void NimBLEUtils::memrcpy(uint8_t* target, uint8_t* source, uint32_t size) { - assert(size > 0); - target += (size - 1); // Point target to the last byte of the target data - while (size > 0) { - *target = *source; - target--; - source++; - size--; - } -} // memrcpy int NimBLEUtils::checkConnParams(ble_gap_conn_params* params) { /* Check connection interval min */ @@ -78,6 +50,7 @@ int NimBLEUtils::checkConnParams(ble_gap_conn_params* params) { const char* NimBLEUtils::returnCodeToString(int rc) { +#if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT) switch(rc) { case 0: return "SUCCESS"; @@ -355,19 +328,22 @@ const char* NimBLEUtils::returnCodeToString(int rc) { return "Pairing over the LE transport failed - Pairing Request sent over the BR/EDR transport in process."; case (0x0500+BLE_SM_ERR_CROSS_TRANS ): return "BR/EDR Link Key generated on the BR/EDR transport cannot be used to derive and distribute keys for the LE transport."; - default: return "Unknown"; } -} +#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT) + return ""; +#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT) +} + /** * @brief Convert the BLE Advertising Data flags to a string. * @param adFlags The flags to convert * @return std::string A string representation of the advertising flags. */ - const char* NimBLEUtils::advTypeToString(uint8_t advType) { +#if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT) switch(advType) { case BLE_HCI_ADV_TYPE_ADV_IND : //0 return "Undirected - Connectable / Scannable"; @@ -382,7 +358,9 @@ const char* NimBLEUtils::advTypeToString(uint8_t advType) { default: return "Unknown flag"; } - +#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT) + return ""; +#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT) } // adFlagsToString @@ -394,7 +372,7 @@ const char* NimBLEUtils::advTypeToString(uint8_t advType) { * @param [in] length The length of the data to convert. * @return A pointer to the formatted buffer. */ -char* NimBLEUtils::buildHexData(uint8_t* target, uint8_t* source, uint8_t length) { +char* NimBLEUtils::buildHexData(uint8_t* target, const uint8_t* source, uint8_t length) { // Guard against too much data. if (length > 100) length = 100; @@ -422,91 +400,97 @@ char* NimBLEUtils::buildHexData(uint8_t* target, uint8_t* source, uint8_t length } // buildHexData - void NimBLEUtils::dumpGapEvent(ble_gap_event *event, void *arg){ +#if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT) NIMBLE_LOGD(LOG_TAG, "Received a GAP event: %s", gapEventToString(event->type)); +#endif } + /** * @brief Convert a BT GAP event type to a string representation. * @param [in] eventType The type of event. * @return A string representation of the event type. */ const char* NimBLEUtils::gapEventToString(uint8_t eventType) { +#if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT) switch (eventType) { case BLE_GAP_EVENT_CONNECT : //0 return "BLE_GAP_EVENT_CONNECT "; - + case BLE_GAP_EVENT_DISCONNECT: //1 return "BLE_GAP_EVENT_DISCONNECT"; - + case BLE_GAP_EVENT_CONN_UPDATE: //3 return "BLE_GAP_EVENT_CONN_UPDATE"; - - case BLE_GAP_EVENT_CONN_UPDATE_REQ: //4 + + case BLE_GAP_EVENT_CONN_UPDATE_REQ: //4 return "BLE_GAP_EVENT_CONN_UPDATE_REQ"; - - case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: //5 + + case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: //5 return "BLE_GAP_EVENT_L2CAP_UPDATE_REQ"; - + case BLE_GAP_EVENT_TERM_FAILURE: //6 return "BLE_GAP_EVENT_TERM_FAILURE"; - + case BLE_GAP_EVENT_DISC: //7 return "BLE_GAP_EVENT_DISC"; - - case BLE_GAP_EVENT_DISC_COMPLETE: //8 + + case BLE_GAP_EVENT_DISC_COMPLETE: //8 return "BLE_GAP_EVENT_DISC_COMPLETE"; - - case BLE_GAP_EVENT_ADV_COMPLETE: //9 + + case BLE_GAP_EVENT_ADV_COMPLETE: //9 return "BLE_GAP_EVENT_ADV_COMPLETE"; - - case BLE_GAP_EVENT_ENC_CHANGE: //10 + + case BLE_GAP_EVENT_ENC_CHANGE: //10 return "BLE_GAP_EVENT_ENC_CHANGE"; - + case BLE_GAP_EVENT_PASSKEY_ACTION : //11 return "BLE_GAP_EVENT_PASSKEY_ACTION"; - + case BLE_GAP_EVENT_NOTIFY_RX: //12 return "BLE_GAP_EVENT_NOTIFY_RX"; - + case BLE_GAP_EVENT_NOTIFY_TX : //13 return "BLE_GAP_EVENT_NOTIFY_TX"; - + case BLE_GAP_EVENT_SUBSCRIBE : //14 return "BLE_GAP_EVENT_SUBSCRIBE"; - + case BLE_GAP_EVENT_MTU: //15 return "BLE_GAP_EVENT_MTU"; - + case BLE_GAP_EVENT_IDENTITY_RESOLVED: //16 return "BLE_GAP_EVENT_IDENTITY_RESOLVED"; - + case BLE_GAP_EVENT_REPEAT_PAIRING: //17 return "BLE_GAP_EVENT_REPEAT_PAIRING"; - + case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: //18 return "BLE_GAP_EVENT_PHY_UPDATE_COMPLETE"; - + case BLE_GAP_EVENT_EXT_DISC: //19 return "BLE_GAP_EVENT_EXT_DISC"; #ifdef BLE_GAP_EVENT_PERIODIC_SYNC // IDF 4.0 does not support these case BLE_GAP_EVENT_PERIODIC_SYNC: //20 return "BLE_GAP_EVENT_PERIODIC_SYNC"; - + case BLE_GAP_EVENT_PERIODIC_REPORT: //21 return "BLE_GAP_EVENT_PERIODIC_REPORT"; - + case BLE_GAP_EVENT_PERIODIC_SYNC_LOST: //22 return "BLE_GAP_EVENT_PERIODIC_SYNC_LOST"; - + case BLE_GAP_EVENT_SCAN_REQ_RCVD: //23 return "BLE_GAP_EVENT_SCAN_REQ_RCVD"; -#endif +#endif default: NIMBLE_LOGD(LOG_TAG, "gapEventToString: Unknown event type %d 0x%.2x", eventType, eventType); return "Unknown event type"; } +#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT) + return ""; +#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT) } // gapEventToString @@ -698,4 +682,4 @@ void print_addr(const void *addr) u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); } -#endif //CONFIG_BT_ENABLED \ No newline at end of file +#endif //CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUtils.h b/libesp32/NimBLE-Arduino/src/NimBLEUtils.h index 3c7021db0..b26d41a51 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEUtils.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEUtils.h @@ -3,7 +3,7 @@ * * Created: on Jan 25 2020 * Author H2zero - * + * */ #ifndef COMPONENTS_NIMBLEUTILS_H_ @@ -25,13 +25,12 @@ class NimBLEUtils { public: static void dumpGapEvent(ble_gap_event *event, void *arg); static const char* gapEventToString(uint8_t eventType); - static char* buildHexData(uint8_t* target, uint8_t* source, uint8_t length); + static char* buildHexData(uint8_t* target, const uint8_t* source, uint8_t length); static const char* advTypeToString(uint8_t advType); static const char* returnCodeToString(int rc); - static void memrcpy(uint8_t* target, uint8_t* source, uint32_t size); static int checkConnParams(ble_gap_conn_params* params); }; #endif // CONFIG_BT_ENABLED -#endif // COMPONENTS_NIMBLEUTILS_H_ \ No newline at end of file +#endif // COMPONENTS_NIMBLEUTILS_H_ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEValue.cpp b/libesp32/NimBLE-Arduino/src/NimBLEValue.cpp index 808812bc3..aa437c60c 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEValue.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEValue.cpp @@ -3,7 +3,7 @@ * * Created: on March 6, 2020 * Author H2zero - * + * * Originally: * * BLEValue.cpp @@ -14,15 +14,18 @@ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include "NimBLEValue.h" #include "NimBLELog.h" static const char* LOG_TAG="NimBLEValue"; NimBLEValue::NimBLEValue() { - m_accumulation = ""; - m_value = ""; - m_readOffset = 0; + m_accumulation = ""; + m_value = ""; + m_readOffset = 0; } // NimBLEValue @@ -31,9 +34,9 @@ NimBLEValue::NimBLEValue() { * The accumulation is a growing set of data that is added to until a commit or cancel. * @param [in] part A message part being added. */ -void NimBLEValue::addPart(std::string part) { - NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", part.length()); - m_accumulation += part; +void NimBLEValue::addPart(const std::string &part) { + NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", part.length()); + m_accumulation += part; } // addPart @@ -43,9 +46,9 @@ void NimBLEValue::addPart(std::string part) { * @param [in] pData A message part being added. * @param [in] length The number of bytes being added. */ -void NimBLEValue::addPart(uint8_t* pData, size_t length) { - NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", length); - m_accumulation += std::string((char*) pData, length); +void NimBLEValue::addPart(const uint8_t* pData, size_t length) { + NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", length); + m_accumulation += std::string((char*) pData, length); } // addPart @@ -53,9 +56,9 @@ void NimBLEValue::addPart(uint8_t* pData, size_t length) { * @brief Cancel the current accumulation. */ void NimBLEValue::cancel() { - NIMBLE_LOGD(LOG_TAG, ">> cancel"); - m_accumulation = ""; - m_readOffset = 0; + NIMBLE_LOGD(LOG_TAG, ">> cancel"); + m_accumulation = ""; + m_readOffset = 0; } // cancel @@ -66,12 +69,12 @@ void NimBLEValue::cancel() { * we now have the complete message and commit the change as a unit. */ void NimBLEValue::commit() { - NIMBLE_LOGD(LOG_TAG, ">> commit"); - // If there is nothing to commit, do nothing. - if (m_accumulation.length() == 0) return; - setValue(m_accumulation); - m_accumulation = ""; - m_readOffset = 0; + NIMBLE_LOGD(LOG_TAG, ">> commit"); + // If there is nothing to commit, do nothing. + if (m_accumulation.length() == 0) return; + setValue(m_accumulation); + m_accumulation = ""; + m_readOffset = 0; } // commit @@ -80,7 +83,7 @@ void NimBLEValue::commit() { * @return A pointer to the data. */ uint8_t* NimBLEValue::getData() { - return (uint8_t*) m_value.data(); + return (uint8_t*) m_value.data(); } @@ -89,7 +92,7 @@ uint8_t* NimBLEValue::getData() { * @return The length of the data in bytes. */ size_t NimBLEValue::getLength() { - return m_value.length(); + return m_value.length(); } // getLength @@ -98,7 +101,7 @@ size_t NimBLEValue::getLength() { * @return The read offset into the read. */ uint16_t NimBLEValue::getReadOffset() { - return m_readOffset; + return m_readOffset; } // getReadOffset @@ -106,7 +109,7 @@ uint16_t NimBLEValue::getReadOffset() { * @brief Get the current value. */ std::string NimBLEValue::getValue() { - return m_value; + return m_value; } // getValue @@ -115,15 +118,15 @@ std::string NimBLEValue::getValue() { * @param [in] readOffset The offset into the read. */ void NimBLEValue::setReadOffset(uint16_t readOffset) { - m_readOffset = readOffset; + m_readOffset = readOffset; } // setReadOffset /** * @brief Set the current value. */ -void NimBLEValue::setValue(std::string value) { - m_value = value; +void NimBLEValue::setValue(const std::string &value) { + m_value = value; } // setValue @@ -132,9 +135,9 @@ void NimBLEValue::setValue(std::string value) { * @param [in] pData The data for the current value. * @param [in] The length of the new current value. */ -void NimBLEValue::setValue(uint8_t* pData, size_t length) { - m_value = std::string((char*) pData, length); +void NimBLEValue::setValue(const uint8_t* pData, size_t length) { + m_value = std::string((char*) pData, length); } // setValue - -#endif // CONFIG_BT_ENABLED \ No newline at end of file +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEValue.h b/libesp32/NimBLE-Arduino/src/NimBLEValue.h index 2fa1fcb4e..4fdeb9bc4 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEValue.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEValue.h @@ -3,9 +3,9 @@ * * Created: on March 6, 2020 * Author H2zero - * + * * Originally: - * + * * BLEValue.h * * Created on: Jul 17, 2017 @@ -16,6 +16,10 @@ #define MAIN_BLEVALUE_H_ #include "sdkconfig.h" #if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + #include /** @@ -23,24 +27,26 @@ */ class NimBLEValue { public: - NimBLEValue(); - void addPart(std::string part); - void addPart(uint8_t* pData, size_t length); - void cancel(); - void commit(); - uint8_t* getData(); - size_t getLength(); - uint16_t getReadOffset(); - std::string getValue(); - void setReadOffset(uint16_t readOffset); - void setValue(std::string value); - void setValue(uint8_t* pData, size_t length); + NimBLEValue(); + void addPart(const std::string &part); + void addPart(const uint8_t* pData, size_t length); + void cancel(); + void commit(); + uint8_t* getData(); + size_t getLength(); + uint16_t getReadOffset(); + std::string getValue(); + void setReadOffset(uint16_t readOffset); + void setValue(const std::string &value); + void setValue(const uint8_t* pData, size_t length); private: - std::string m_accumulation; - uint16_t m_readOffset; - std::string m_value; + std::string m_accumulation; + uint16_t m_readOffset; + std::string m_value; }; + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif // CONFIG_BT_ENABLED -#endif /* MAIN_BLEVALUE_H_ */ \ No newline at end of file +#endif /* MAIN_BLEVALUE_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/console/console.h b/libesp32/NimBLE-Arduino/src/console/console.h index 342d6f699..96f965159 100644 --- a/libesp32/NimBLE-Arduino/src/console/console.h +++ b/libesp32/NimBLE-Arduino/src/console/console.h @@ -18,4 +18,4 @@ #define console_printf printf -#endif \ No newline at end of file +#endif diff --git a/libesp32/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c b/libesp32/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c index 8d994c444..e4ab99932 100644 --- a/libesp32/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c +++ b/libesp32/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c @@ -519,4 +519,4 @@ esp_err_t esp_nimble_hci_and_controller_deinit(void) } return ESP_OK; -} \ No newline at end of file +} diff --git a/libesp32/NimBLE-Arduino/src/esp_nimble_cfg.h b/libesp32/NimBLE-Arduino/src/esp_nimble_cfg.h index 16d4253be..384ec4a56 100644 --- a/libesp32/NimBLE-Arduino/src/esp_nimble_cfg.h +++ b/libesp32/NimBLE-Arduino/src/esp_nimble_cfg.h @@ -1,6 +1,4 @@ -/* Modifications copyright (C) 2020 Ryan Powell */ - #ifndef __ESP_NIMBLE_CFG__ #define __ESP_NIMBLE_CFG__ #include "nimconfig.h" @@ -470,7 +468,7 @@ #endif #ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT -#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT CONFIG_BT_NIMBLE_FLOW_CTRL_TX_ON_DISCONNECT +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT #endif #ifndef MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS diff --git a/libesp32/NimBLE-Arduino/src/esp_nimble_hci.h b/libesp32/NimBLE-Arduino/src/esp_nimble_hci.h index 3c66ca796..e10436f3c 100644 --- a/libesp32/NimBLE-Arduino/src/esp_nimble_hci.h +++ b/libesp32/NimBLE-Arduino/src/esp_nimble_hci.h @@ -135,4 +135,4 @@ esp_err_t esp_nimble_hci_and_controller_deinit(void); } #endif -#endif /* __ESP_NIMBLE_HCI_H__ */ \ No newline at end of file +#endif /* __ESP_NIMBLE_HCI_H__ */ diff --git a/libesp32/NimBLE-Arduino/src/esp_nimble_mem.h b/libesp32/NimBLE-Arduino/src/esp_nimble_mem.h index d257c5466..90e52a20d 100644 --- a/libesp32/NimBLE-Arduino/src/esp_nimble_mem.h +++ b/libesp32/NimBLE-Arduino/src/esp_nimble_mem.h @@ -1,4 +1,3 @@ - /* * Copyright 2020 Espressif Systems (Shanghai) PTE LTD * @@ -37,4 +36,4 @@ void nimble_platform_mem_free(void *ptr); } #endif -#endif /* __ESP_NIMBLE_MEM_H__ */ \ No newline at end of file +#endif /* __ESP_NIMBLE_MEM_H__ */ diff --git a/libesp32/NimBLE-Arduino/src/host/ble_gap.h b/libesp32/NimBLE-Arduino/src/host/ble_gap.h index 9ef4e18ef..b4dbdb051 100644 --- a/libesp32/NimBLE-Arduino/src/host/ble_gap.h +++ b/libesp32/NimBLE-Arduino/src/host/ble_gap.h @@ -98,8 +98,8 @@ struct hci_conn_update; #define BLE_GAP_INITIAL_CONN_LATENCY 0 #define BLE_GAP_INITIAL_SUPERVISION_TIMEOUT 0x0100 -#define BLE_GAP_INITIAL_CONN_MIN_CE_LEN 0x0010 -#define BLE_GAP_INITIAL_CONN_MAX_CE_LEN 0x0300 +#define BLE_GAP_INITIAL_CONN_MIN_CE_LEN 0x0000 +#define BLE_GAP_INITIAL_CONN_MAX_CE_LEN 0x0000 #define BLE_GAP_ROLE_MASTER 0 #define BLE_GAP_ROLE_SLAVE 1 @@ -1783,6 +1783,20 @@ int ble_gap_unpair(const ble_addr_t *peer_addr); */ int ble_gap_unpair_oldest_peer(void); +/** + * Similar to `ble_gap_unpair_oldest_peer()`, except it makes sure that the + * peer received in input parameters is not deleted. + * + * @param peer_addr Address of the peer (not to be deleted) + * + * @return 0 on success; + * A BLE host HCI return code if the controller + * rejected the request; + * A BLE host core return code on unexpected + * error. + */ +int ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr); + #define BLE_GAP_PRIVATE_MODE_NETWORK 0 #define BLE_GAP_PRIVATE_MODE_DEVICE 1 @@ -1886,20 +1900,6 @@ struct ble_gap_event_listener { SLIST_ENTRY(ble_gap_event_listener) link; }; -/** - * Similar to `ble_gap_unpair_oldest_peer()`, except it makes sure that current - * peer is not deleted. - * - * @param peer_addr Address of the current peer (not to be deleted) - * - * @return 0 on success; - * A BLE host HCI return code if the controller - * rejected the request; - * A BLE host core return code on unexpected - * error. - */ -int ble_gap_unpair_oldest_except_curr(const ble_addr_t *curr_peer); - /** * Registers listener for GAP events * diff --git a/libesp32/NimBLE-Arduino/src/host/ble_store.h b/libesp32/NimBLE-Arduino/src/host/ble_store.h index e470f8ec3..a3eca5d23 100644 --- a/libesp32/NimBLE-Arduino/src/host/ble_store.h +++ b/libesp32/NimBLE-Arduino/src/host/ble_store.h @@ -288,8 +288,6 @@ int ble_store_clear(void); /*** Utility functions. */ -int ble_store_clean_old_cccds(const ble_addr_t *curr_peer); - int ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, int max_peers); diff --git a/libesp32/NimBLE-Arduino/src/mesh/glue.h b/libesp32/NimBLE-Arduino/src/mesh/glue.h index 3b1636dcc..08e81fa41 100644 --- a/libesp32/NimBLE-Arduino/src/mesh/glue.h +++ b/libesp32/NimBLE-Arduino/src/mesh/glue.h @@ -330,11 +330,8 @@ static inline void net_buf_simple_restore(struct os_mbuf *buf, buf->om_len = state->len; } -static inline void sys_memcpy_swap(void *destination, const void *source, size_t length) +static inline void sys_memcpy_swap(void *dst, const void *src, size_t length) { - u8_t *dst = destination; - const u8_t *src = source; - __ASSERT(((src < dst && (src + length) <= dst) || (src > dst && (dst + length) <= src)), "Source and destination buffers must not overlap"); @@ -342,7 +339,7 @@ static inline void sys_memcpy_swap(void *destination, const void *source, size_t src += length - 1; for (; length > 0; length--) { - *dst++ = *src--; + *((u8_t *)dst++) = *((u8_t *)src--); } } diff --git a/libesp32/NimBLE-Arduino/src/modlog/modlog.h b/libesp32/NimBLE-Arduino/src/modlog/modlog.h index e8752d465..e81ea3812 100644 --- a/libesp32/NimBLE-Arduino/src/modlog/modlog.h +++ b/libesp32/NimBLE-Arduino/src/modlog/modlog.h @@ -41,31 +41,43 @@ modlog_dummy(const char *msg, ...) #endif #ifdef ESP_PLATFORM -/// Uncomment these and comment out the 3 defines below to see NimBLE messages in Arduino. -/* +#define MODLOG_ESP_LOCAL(level, ml_msg_, ...) do { \ + if (LOG_LOCAL_LEVEL >= level) esp_log_write(level, "NimBLE", ml_msg_, ##__VA_ARGS__); \ +} while(0) + +#ifdef ARDUINO_ARCH_ESP32 +#include "nimconfig.h" +#endif + +#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_BT_NIMBLE_DEBUG) + #define MODLOG_DEBUG(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_ERROR, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) #define MODLOG_INFO(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_ERROR, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) #define MODLOG_WARN(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_ERROR, "NimBLE",ml_msg_, ##__VA_ARGS__) -*/ + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) + +#else + #define MODLOG_DEBUG(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_DEBUG, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_DEBUG, ml_msg_, ##__VA_ARGS__) #define MODLOG_INFO(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_INFO, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_INFO, ml_msg_, ##__VA_ARGS__) #define MODLOG_WARN(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_WARN, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_WARN, ml_msg_, ##__VA_ARGS__) + +#endif #define MODLOG_ERROR(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_ERROR, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) #define MODLOG_CRITICAL(ml_mod_, ml_msg_, ...) \ - esp_log_write(ESP_LOG_ERROR, "NimBLE",ml_msg_, ##__VA_ARGS__) + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) #else diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h index 4285cfa43..c80872898 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h @@ -119,6 +119,7 @@ void ble_gap_preempt(void); void ble_gap_preempt_done(void); void ble_gap_conn_broken(uint16_t conn_handle, int reason); +void ble_gap_reset_state(int reason); int32_t ble_gap_timer(void); int ble_gap_init(void); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_id_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_id_priv.h index aa2827d41..c031b9511 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_id_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_id_priv.h @@ -33,6 +33,10 @@ int ble_hs_id_use_addr(uint8_t addr_type); void ble_hs_id_reset(void); void ble_hs_id_rnd_reset(void); +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) +bool ble_hs_is_rpa(uint8_t *addr, uint8_t addr_type); +int ble_hs_id_set_pseudo_rnd(const uint8_t *); +#endif #ifdef __cplusplus } #endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_pvcy_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_pvcy_priv.h index 7f0aa4b90..86157da0f 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_pvcy_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_pvcy_priv.h @@ -35,6 +35,9 @@ int ble_hs_pvcy_add_entry(const uint8_t *addr, uint8_t addrtype, const uint8_t *irk); int ble_hs_pvcy_ensure_started(void); int ble_hs_pvcy_set_mode(const ble_addr_t *addr, uint8_t priv_mode); +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) +bool ble_hs_pvcy_enabled(void); +#endif #ifdef __cplusplus } diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h new file mode 100644 index 000000000..568aa89ab --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h @@ -0,0 +1,108 @@ +/* + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) +/* + * An entry in the resolving list. + */ +struct ble_hs_resolv_entry { + uint8_t rl_addr_type; + uint8_t rl_local_irk[16]; + uint8_t rl_peer_irk[16]; + uint8_t rl_identity_addr[BLE_DEV_ADDR_LEN]; + uint8_t rl_pseudo_id[BLE_DEV_ADDR_LEN]; + uint8_t rl_local_rpa[BLE_DEV_ADDR_LEN]; + uint8_t rl_peer_rpa[BLE_DEV_ADDR_LEN]; +}; + +#if MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST) +/* Persist peer records in NVS. XXX Need to handle this in `store` module */ +int ble_store_persist_peer_records(void); +#endif + +struct ble_hs_peer_sec { + ble_addr_t peer_addr; + uint8_t irk[16]; + uint8_t irk_present: 1; +}; +/* + * BLE host peer device record, this helps in storing peer RPA before bond is + * created and IRKs are exchanged. + */ +struct ble_hs_dev_records { + bool rec_used; + uint8_t pseudo_addr[BLE_DEV_ADDR_LEN]; + uint8_t rand_addr[BLE_DEV_ADDR_LEN]; + uint8_t identity_addr[BLE_DEV_ADDR_LEN]; + struct ble_hs_peer_sec peer_sec; +}; + +/* Add a device to the resolving list */ +int ble_hs_resolv_list_add(uint8_t *cmdbuf); +int ble_hs_gen_own_rpa_random(void); +uint8_t *ble_hs_get_rpa_local(void); + +/* Remove a device from the resolving list */ +int ble_hs_resolv_list_rmv(uint8_t, uint8_t *); +/* Clear the resolving list and peer dev record */ +void ble_hs_resolv_list_clear_all(void); + +/* Address resolution enable command */ +void ble_hs_resolv_enable(bool); + +/* Finds 'addr' in resolving list. Doesnt check if address resolution enabled */ +struct ble_hs_resolv_entry * +ble_hs_resolv_list_find(uint8_t *addr); + +/* Returns true if host based RPA (privacy) is enabled */ +bool ble_host_rpa_enabled(void); + +/* Searches peer device records (RPA) and fetches matching RL, peer_address + * into input parameters if RL is found */ +void +ble_rpa_replace_peer_params_with_rl(uint8_t *, uint8_t *, struct ble_hs_resolv_entry **); + +int ble_rpa_resolv_add_peer_rec(uint8_t *); + +struct ble_hs_dev_records *ble_rpa_get_peer_dev_records(void); +int ble_rpa_get_num_peer_dev_records(void); +void ble_rpa_set_num_peer_dev_records(int); +int ble_rpa_remove_peer_dev_rec(struct ble_hs_dev_records *); +struct ble_hs_dev_records *ble_rpa_find_peer_dev_rec(uint8_t *); + +/* Set the resolvable private address timeout */ +int ble_hs_resolv_set_rpa_tmo(uint16_t); + +/* Resolve a resolvable private address */ +int ble_hs_resolv_rpa(uint8_t *rpa, uint8_t *irk); + +/* Initialize resolv*/ +void ble_hs_resolv_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h index 3f64b7786..74205bd0c 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h @@ -399,6 +399,7 @@ int ble_sm_slave_initiate(uint16_t conn_handle); int ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, const uint8_t *ltk, uint16_t ediv, uint64_t rand_val, int auth); +int ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data); int ble_sm_init(void); #define BLE_SM_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ @@ -419,6 +420,9 @@ int ble_sm_init(void); #define ble_sm_init() 0 +#define ble_sm_alg_encrypt(key, plaintext, enc_data) \ + BLE_HS_ENOTSUP + #endif struct ble_l2cap_chan *ble_sm_create_chan(uint16_t handle); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd.c index 999f57a2b..bad192df5 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_att_cmd.c @@ -66,11 +66,10 @@ ble_att_tx(uint16_t conn_handle, struct os_mbuf *txom) ble_hs_lock(); - ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, - &chan); - if (chan == NULL) { + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn, + &chan); + if (rc != 0) { os_mbuf_free_chain(txom); - rc = BLE_HS_ENOTCONN; } else { ble_att_truncate_to_mtu(chan, txom); rc = ble_l2cap_tx(conn, chan, txom); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gap.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gap.c index e65640128..09ae27047 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gap.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gap.c @@ -17,8 +17,6 @@ * under the License. */ - /* Modifications copyright (C) 2020 Ryan Powell */ - #include #include #include @@ -1855,7 +1853,6 @@ ble_gap_update_timer(void) ble_hs_unlock(); if (entry != NULL) { - ble_gap_update_notify(conn_handle, BLE_HS_ETIMEOUT); ble_gap_update_entry_free(entry); } } while (entry != NULL); @@ -5303,8 +5300,7 @@ ble_gap_unpair_oldest_peer(void) } if (num_peers == 0) { - return BLE_HS_ENOENT; - //return 0; + return 0; } rc = ble_gap_unpair(&oldest_peer_id_addr); @@ -5316,14 +5312,14 @@ ble_gap_unpair_oldest_peer(void) } int -ble_gap_unpair_oldest_except_curr(const ble_addr_t *curr_peer) +ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr) { - ble_addr_t oldest_peer_id_addr[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; + ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; int num_peers; int rc, i; rc = ble_store_util_bonded_peers( - &oldest_peer_id_addr[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); + &peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); if (rc != 0) { return rc; } @@ -5333,21 +5329,16 @@ ble_gap_unpair_oldest_except_curr(const ble_addr_t *curr_peer) } for (i = 0; i < num_peers; i++) { - if (memcmp(curr_peer, &oldest_peer_id_addr[i], sizeof (ble_addr_t)) != 0) { + if (ble_addr_cmp(peer_addr, &peer_id_addrs[i]) != 0) { break; } } - if (i < num_peers) { - rc = ble_gap_unpair(&oldest_peer_id_addr[i]); - if (rc != 0) { - return rc; - } - } else { + if (i >= num_peers) { return BLE_HS_ENOMEM; } - return 0; + return ble_gap_unpair(&peer_id_addrs[i]); } void @@ -5371,7 +5362,8 @@ ble_gap_passkey_event(uint16_t conn_handle, } void -ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored) +ble_gap_enc_event(uint16_t conn_handle, int status, + int security_restored, int bonded) { #if !NIMBLE_BLE_SM return; @@ -5387,17 +5379,24 @@ ble_gap_enc_event(uint16_t conn_handle, int status, int security_restored) ble_gap_event_listener_call(&event); ble_gap_call_conn_event_cb(&event, conn_handle); -/* H2zero mod - If bonding is not enabled don't store cccd data - if (status == 0) { -*/ - if (status == 0 && ble_hs_cfg.sm_bonding) { -/* End mod */ - if (security_restored) { - ble_gatts_bonding_restored(conn_handle); - } else { - ble_gatts_bonding_established(conn_handle); - } + if (status != 0) { + return; + } + + /* If encryption succeded and encryption has been restored for bonded device, + * notify gatt server so it has chance to send notification/indication if needed. + */ + if (security_restored) { + ble_gatts_bonding_restored(conn_handle); + return; + } + + /* If this is fresh pairing and bonding has been established, + * notify gatt server about that so previous subscriptions (before bonding) + * can be stored. + */ + if (bonded) { + ble_gatts_bonding_established(conn_handle); } } diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gap_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gap_priv.h index c80872898..90c32e22a 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gap_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gap_priv.h @@ -99,7 +99,7 @@ int ble_gap_rx_l2cap_update_req(uint16_t conn_handle, struct ble_gap_upd_params *params); void ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt); void ble_gap_enc_event(uint16_t conn_handle, int status, - int security_restored); + int security_restored, int bonded); void ble_gap_passkey_event(uint16_t conn_handle, struct ble_gap_passkey_params *passkey_params); void ble_gap_notify_rx_event(uint16_t conn_handle, uint16_t attr_handle, diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gatts.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gatts.c index e84361cbe..fccf10274 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gatts.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_gatts.c @@ -1689,30 +1689,29 @@ ble_gatts_bonding_established(uint16_t conn_handle) conn = ble_hs_conn_find(conn_handle); BLE_HS_DBG_ASSERT(conn != NULL); + BLE_HS_DBG_ASSERT(conn->bhc_sec_state.bonded); - if (conn->bhc_sec_state.bonded) { - cccd_value.peer_addr = conn->bhc_peer_addr; - gatt_srv = &conn->bhc_gatt_svr; + cccd_value.peer_addr = conn->bhc_peer_addr; + gatt_srv = &conn->bhc_gatt_svr; - for (i = 0; i < gatt_srv->num_clt_cfgs; ++i) { - clt_cfg = (gatt_srv->clt_cfgs + i); - if (clt_cfg == NULL) { - continue; - } + for (i = 0; i < gatt_srv->num_clt_cfgs; ++i) { + clt_cfg = (gatt_srv->clt_cfgs + i); + if (clt_cfg == NULL) { + continue; + } - if (clt_cfg->flags != 0) { - cccd_value.chr_val_handle = clt_cfg->chr_val_handle; - cccd_value.flags = clt_cfg->flags; - cccd_value.value_changed = 0; + if (clt_cfg->flags != 0) { + cccd_value.chr_val_handle = clt_cfg->chr_val_handle; + cccd_value.flags = clt_cfg->flags; + cccd_value.value_changed = 0; - /* Store write use ble_hs_lock */ - ble_hs_unlock(); - ble_store_write_cccd(&cccd_value); - ble_hs_lock(); + /* Store write use ble_hs_lock */ + ble_hs_unlock(); + ble_store_write_cccd(&cccd_value); + ble_hs_lock(); - conn = ble_hs_conn_find(conn_handle); - BLE_HS_DBG_ASSERT(conn != NULL); - } + conn = ble_hs_conn_find(conn_handle); + BLE_HS_DBG_ASSERT(conn != NULL); } } diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn.c index c19851577..eb65e3288 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_conn.c @@ -410,18 +410,16 @@ ble_hs_conn_addrs(const struct ble_hs_conn *conn, #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) /* RPA: Override peer address information. */ - struct ble_hs_resolv_entry *rl = NULL; - ble_addr_t bhc_peer_addr; bhc_peer_addr.type = conn->bhc_peer_addr.type; memcpy(bhc_peer_addr.val, conn->bhc_peer_addr.val, BLE_DEV_ADDR_LEN); - + + struct ble_hs_resolv_entry *rl = NULL; rl = ble_hs_resolv_list_find(bhc_peer_addr.val); if (rl != NULL) { - addrs->peer_ota_addr = conn->bhc_peer_rpa_addr; memcpy(addrs->peer_id_addr.val, rl->rl_identity_addr, BLE_DEV_ADDR_LEN); addrs->peer_id_addr.type = rl->rl_addr_type; - + if (ble_host_rpa_enabled()) { uint8_t *local_id = NULL; ble_hs_id_addr(BLE_ADDR_PUBLIC, (const uint8_t **) &local_id, NULL); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci.c index 94126679c..92ffde8fd 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci.c @@ -240,7 +240,7 @@ ble_hs_hci_process_ack(uint16_t expected_opcode, } if (rc == 0) { - if (params_buf == NULL) { + if (params_buf == NULL || out_ack->bha_params == NULL) { out_ack->bha_params_len = 0; } else { if (out_ack->bha_params_len > params_buf_len) { diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_evt.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_evt.c index 3f7c5d791..30dc92f28 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_evt.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_hci_evt.c @@ -333,18 +333,10 @@ ble_hs_hci_evt_le_conn_complete(uint8_t subevent, uint8_t *data, int len) uint8_t *local_id_rpa = ble_hs_get_rpa_local(); memcpy(evt.local_rpa, local_id_rpa, 6); } - + struct ble_hs_resolv_entry *rl = NULL; ble_rpa_replace_peer_params_with_rl(evt.peer_addr, &evt.peer_addr_type, &rl); - if (rl == NULL) { - if (ble_rpa_resolv_add_peer_rec(evt.peer_addr) != 0) { - BLE_HS_LOG(DEBUG, "Memory unavailable for new peer record\n"); - } - } - /* Set the correct RPA for logging */ - memcpy(evt.peer_rpa, data + 6, BLE_DEV_ADDR_LEN); - #endif } else { memset(evt.local_rpa, 0, BLE_DEV_ADDR_LEN); @@ -441,14 +433,6 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, uint8_t *data, int len) memcpy(desc.addr.val, data + off, 6); off += 6; -#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) - if (ble_host_rpa_enabled()) { - /* Now RPA to be resolved here, since controller is unaware of the - * address is RPA */ - ble_rpa_replace_peer_params_with_rl(desc.addr.val, - &desc.addr.type, NULL); - } -#endif desc.length_data = data[off]; ++off; diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_misc.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_misc.c index e6bb3825b..00200d316 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_misc.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_misc.c @@ -56,7 +56,7 @@ ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, return rc; } -void +int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan) @@ -66,7 +66,9 @@ ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, int rc; rc = ble_hs_misc_conn_chan_find(conn_handle, cid, &conn, &chan); - BLE_HS_DBG_ASSERT_EVAL(rc == 0); + if (rc != 0) { + return rc; + } if (out_conn != NULL) { *out_conn = conn; @@ -74,6 +76,8 @@ ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, if (out_chan != NULL) { *out_chan = chan; } + + return 0; } uint8_t diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_priv.h index 27bf904b7..49269546c 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_priv.h @@ -115,9 +115,9 @@ int ble_hs_hci_evt_acl_process(struct os_mbuf *om); int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan); -void ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, - struct ble_hs_conn **out_conn, - struct ble_l2cap_chan **out_chan); +int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, + struct ble_hs_conn **out_conn, + struct ble_l2cap_chan **out_chan); uint8_t ble_hs_misc_addr_type_to_id(uint8_t addr_type); int ble_hs_misc_restore_irks(void); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig.c index 07a338ae6..bc73d954a 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig.c @@ -473,8 +473,13 @@ ble_l2cap_sig_update(uint16_t conn_handle, STATS_INC(ble_l2cap_stats, update_init); ble_hs_lock(); - ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, - &conn, &chan); + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, + &conn, &chan); + if (rc != 0) { + ble_hs_unlock(); + goto done; + } + master = conn->bhc_flags & BLE_HS_CONN_F_MASTER; ble_hs_unlock(); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig_cmd.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig_cmd.c index 366dde625..510420f09 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig_cmd.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_l2cap_sig_cmd.c @@ -28,9 +28,11 @@ ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom) int rc; ble_hs_lock(); - ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, - &conn, &chan); - rc = ble_l2cap_tx(conn, chan, txom); + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG, + &conn, &chan); + if (rc == 0) { + rc = ble_l2cap_tx(conn, chan, txom); + } ble_hs_unlock(); return rc; diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm.c index 1bc55a625..6fa6f00c4 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm.c @@ -538,6 +538,11 @@ ble_sm_persist_keys(struct ble_sm_proc *proc) case BLE_ADDR_PUBLIC: case BLE_ADDR_PUBLIC_ID: conn->bhc_peer_addr.type = BLE_ADDR_PUBLIC_ID; +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) + /* In case of Host based privacy, we should not be changing + * peer address type to BLE_ADDR_PUBLIC_ID */ + conn->bhc_peer_addr.type = BLE_ADDR_PUBLIC; +#endif break; case BLE_ADDR_RANDOM: @@ -944,7 +949,7 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res) if (res->enc_cb) { BLE_HS_DBG_ASSERT(proc == NULL || rm); - ble_gap_enc_event(conn_handle, res->app_status, res->restore); + ble_gap_enc_event(conn_handle, res->app_status, res->restore, res->bonded); } if (res->app_status == 0 && @@ -1198,6 +1203,7 @@ ble_sm_enc_event_rx(uint16_t conn_handle, uint8_t evt_status, int encrypted) ble_hs_unlock(); + res.bonded = bonded; ble_sm_process_result(conn_handle, &res); } @@ -1793,8 +1799,21 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om, */ proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_NONE, -1, &prev); if (proc != NULL) { - /* Pairing already in progress; abort old procedure and start new. */ - /* XXX: Check the spec on this. */ + /* Fail if procedure is in progress unless we sent a slave security + * request to peer. + */ + if (proc->state != BLE_SM_PROC_STATE_SEC_REQ) { + res->sm_err = BLE_SM_ERR_UNSPECIFIED; + res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_UNSPECIFIED); + ble_hs_unlock(); + return; + } + + /* Remove the procedure because it was allocated when + * sending the Slave Security Request and it will be allocated + * again later in this method. We should probably refactor this + * in the future. + */ ble_sm_proc_remove(proc, prev); ble_sm_proc_free(proc); } @@ -2459,7 +2478,7 @@ ble_sm_timer(void) * procedures without reconnect. */ while ((proc = STAILQ_FIRST(&exp_list)) != NULL) { - ble_gap_enc_event(proc->conn_handle, BLE_HS_ETIMEOUT, 0); + ble_gap_enc_event(proc->conn_handle, BLE_HS_ETIMEOUT, 0, 0); STAILQ_REMOVE_HEAD(&exp_list, next); ble_sm_proc_free(proc); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm_cmd.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm_cmd.c index b5e674e75..e12e109d5 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm_cmd.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm_cmd.c @@ -52,14 +52,19 @@ ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom) { struct ble_l2cap_chan *chan; struct ble_hs_conn *conn; + int rc; BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task()); STATS_INC(ble_l2cap_stats, sm_tx); - ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SM, - &conn, &chan); - return ble_l2cap_tx(conn, chan, txom); + rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SM, + &conn, &chan); + if (rc == 0) { + rc = ble_l2cap_tx(conn, chan, txom); + } + + return rc; } #if NIMBLE_BLE_SM diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm_priv.h index 74205bd0c..bbb4b03ae 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_sm_priv.h @@ -277,10 +277,10 @@ struct ble_sm_result { uint8_t sm_err; struct ble_gap_passkey_params passkey_params; void *state_arg; - unsigned execute:1; - unsigned enc_cb:1; - unsigned persist_keys:1; - unsigned restore:1; + unsigned execute : 1; + unsigned enc_cb : 1; + unsigned bonded : 1; + unsigned restore : 1; }; #if MYNEWT_VAL(BLE_HS_DEBUG) diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_store_util.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_store_util.c index 9813a8650..73c71d93b 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_store_util.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_store_util.c @@ -19,6 +19,7 @@ #include "host/ble_store.h" #include "ble_hs_priv.h" +#include "ble_hs_resolv_priv.h" struct ble_store_util_peer_set { ble_addr_t *peer_id_addrs; @@ -27,12 +28,6 @@ struct ble_store_util_peer_set { int status; }; -struct ble_store_util_peer_cccd_set { - struct ble_store_util_peer_set peer_set; - ble_addr_t *curr_peer_addr; -}; - - static int ble_store_util_iter_unique_peer(int obj_type, union ble_store_value *val, @@ -65,42 +60,6 @@ ble_store_util_iter_unique_peer(int obj_type, return 0; } -static int -ble_store_util_iter_peer_cccd(int obj_type, - union ble_store_value *val, - void *arg) -{ - struct ble_store_util_peer_cccd_set *set; - int i; - - set = arg; - - /* Do nothing if this peer is a duplicate or current peer */ - for (i = 0; i < set->peer_set.num_peers; i++) { - if (ble_addr_cmp(set->peer_set.peer_id_addrs + i, &val->cccd.peer_addr) == 0) { - return 0; - } - - if (set->curr_peer_addr != NULL) { - if (ble_addr_cmp(set->curr_peer_addr, &val->cccd.peer_addr) == 0) { - return 0; - } - } - } - - if (set->peer_set.num_peers >= set->peer_set.max_peers) { - /* Overflow; abort the iterate procedure. */ - set->peer_set.status = BLE_HS_ENOMEM; - return 1; - } - - set->peer_set.peer_id_addrs[set->peer_set.num_peers] = val->cccd.peer_addr; - set->peer_set.num_peers++; - - return 0; -} - - /** * Retrieves the set of peer addresses for which a bond has been established. * @@ -141,51 +100,6 @@ ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, int *out_num_peers, return 0; } -/** - * Retrieves the set of peer addresses for which CCCDs are subscribed. - * - * @param out_peer_id_addrs On success, the set of peer addresses - * gets written here. - * @param out_num_peers On success, the number of peer addresses gets written - * here. - * @param max_peers The capacity of the destination buffer. - * - * @param curr_peer_addrs Current peer's address, ignore if NULL - * - * @return 0 on success; - * BLE_HS_ENOMEM if the destination buffer is too - * small; - * Other nonzero on error. - */ -static int -ble_store_util_subscribed_cccds(ble_addr_t *out_peer_id_addrs, int *out_num_peers, - int max_peers, ble_addr_t *curr_peer_addr) -{ - struct ble_store_util_peer_cccd_set set = { - .peer_set = { - .peer_id_addrs = out_peer_id_addrs, - .num_peers = 0, - .max_peers = max_peers, - .status = 0, - }, - .curr_peer_addr = curr_peer_addr, - }; - int rc; - - rc = ble_store_iterate(BLE_STORE_OBJ_TYPE_CCCD, - ble_store_util_iter_peer_cccd, - &set); - if (rc != 0) { - return rc; - } - if (set.peer_set.status != 0) { - return set.peer_set.status; - } - - *out_num_peers = set.peer_set.num_peers; - return 0; -} - /** * Deletes all entries from the store that are attached to the specified peer * address. This function deletes security entries and CCCD records. @@ -222,6 +136,25 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr) return rc; } +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) + struct ble_hs_dev_records *peer_rec = + ble_rpa_find_peer_dev_rec(key.sec.peer_addr.val); + + if (peer_rec != NULL) { + rc = ble_hs_resolv_list_rmv(peer_rec->peer_sec.peer_addr.type, + peer_rec->peer_sec.peer_addr.val); + if (rc != 0) { + /* We can't do anything much here, continue with removing from peer_record */ + BLE_HS_LOG(DEBUG, "Peer Device was not removed from RL \n"); + } + + rc = ble_rpa_remove_peer_dev_rec(peer_rec); + if (rc != 0) { + return rc; + } + } +#endif + return 0; } @@ -305,63 +238,6 @@ ble_store_util_delete_oldest_peer(void) return 0; } -/** - * Delete CCCDs of unbonded devices. - * - * @param curr_peer Current peer's address (not to delete), ignore - * ignore if NULL - * - * @return 0 on success; - * nonzero on error. - */ -int -ble_store_clean_old_cccds(const ble_addr_t *curr_peer) -{ - ble_addr_t peer_cccd_addrs[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)]; - ble_addr_t peer_bonded_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)]; - int num_bonded_peers, num_cccd_peers; - int i, j, rc; - - rc = ble_store_util_subscribed_cccds(&peer_cccd_addrs[0], &num_cccd_peers, - MYNEWT_VAL(BLE_STORE_MAX_CCCDS), - (void *) curr_peer); - if (rc != 0) { - return rc; - } - - rc = ble_store_util_bonded_peers(&peer_bonded_addrs[0], &num_bonded_peers, - MYNEWT_VAL(BLE_STORE_MAX_BONDS)); - if (rc != 0) { - return rc; - } - - union ble_store_key key = {0}; - /* Init rc to BLE_HS_ENOENT to indicate no CCCD is deleted */ - rc = BLE_HS_ENOENT; - - for (i = 0; i < num_cccd_peers; i++) { - key.cccd.peer_addr = peer_cccd_addrs[i]; - - for (j = 0; j < num_bonded_peers; j++) { - if (memcmp(&peer_cccd_addrs[i], &peer_bonded_addrs[j], - sizeof(ble_addr_t)) == 0) { - break; - } - } - - if (j < num_bonded_peers) { - continue; - } - - rc = ble_store_util_delete_all(BLE_STORE_OBJ_TYPE_CCCD, &key); - if (rc != 0) { - return rc; - } - } - - return rc; -} - /** * Round-robin status callback. If a there is insufficient storage capacity * for a new record, delete the oldest bond and proceed with the persist @@ -374,33 +250,18 @@ ble_store_clean_old_cccds(const ble_addr_t *curr_peer) int ble_store_util_status_rr(struct ble_store_status_event *event, void *arg) { - int rc = BLE_HS_EUNKNOWN; switch (event->event_code) { case BLE_STORE_EVENT_OVERFLOW: switch (event->overflow.obj_type) { - case BLE_STORE_OBJ_TYPE_OUR_SEC: - case BLE_STORE_OBJ_TYPE_PEER_SEC: - return ble_gap_unpair_oldest_peer(); - case BLE_STORE_OBJ_TYPE_CCCD: - /* Try to remove unbonded CCCDs first */ - if ((rc = ble_store_clean_old_cccds((void *) &event->overflow.value->cccd.peer_addr)) == BLE_HS_ENOENT) { - /* No unbonded CCCDs found to delete, try unpairing oldest peer - * except current peer */ - return ble_gap_unpair_oldest_except_curr((void *) &event->overflow.value->cccd.peer_addr); - } - return rc; + case BLE_STORE_OBJ_TYPE_OUR_SEC: + case BLE_STORE_OBJ_TYPE_PEER_SEC: + return ble_gap_unpair_oldest_peer(); + case BLE_STORE_OBJ_TYPE_CCCD: + /* Try unpairing oldest peer except current peer */ + return ble_gap_unpair_oldest_except(&event->overflow.value->cccd.peer_addr); - default: - return BLE_HS_EUNKNOWN; - - /* case BLE_STORE_OBJ_TYPE_OUR_SEC: - case BLE_STORE_OBJ_TYPE_PEER_SEC: - case BLE_STORE_OBJ_TYPE_CCCD: - return ble_gap_unpair_oldest_peer(); - - default: - return BLE_HS_EUNKNOWN; - */ + default: + return BLE_HS_EUNKNOWN; } case BLE_STORE_EVENT_FULL: diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_nvs.c b/libesp32/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_nvs.c index 450b0e7f4..a6fea44c7 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_nvs.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_nvs.c @@ -210,11 +210,11 @@ get_nvs_db_attribute(int obj_type, bool empty, void *value, int num_value) err = get_nvs_matching_index(&p_dev_rec, value, num_value, sizeof(struct ble_hs_dev_records)); } else { - if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) { + if (obj_type != BLE_STORE_OBJ_TYPE_CCCD) { err = get_nvs_matching_index(&cur.sec, value, num_value, sizeof(struct ble_store_value_sec)); } else { - err = get_nvs_matching_index(&cur.sec, value, num_value, + err = get_nvs_matching_index(&cur.cccd, value, num_value, sizeof(struct ble_store_value_cccd)); } } diff --git a/libesp32/NimBLE-Arduino/src/nimble/nimble_npl.h b/libesp32/NimBLE-Arduino/src/nimble/nimble_npl.h index 689d363d9..883832289 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/nimble_npl.h +++ b/libesp32/NimBLE-Arduino/src/nimble/nimble_npl.h @@ -16,8 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - -/* Modifications copyright (C) 2020 Ryan Powell*/ #ifndef _NIMBLE_NPL_H_ #define _NIMBLE_NPL_H_ @@ -26,6 +24,7 @@ #include #include #include "nimconfig.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/nimble_port.h b/libesp32/NimBLE-Arduino/src/nimble/nimble_port.h index aa5e6390f..e8996a666 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/nimble_port.h +++ b/libesp32/NimBLE-Arduino/src/nimble/nimble_port.h @@ -17,7 +17,6 @@ * under the License. */ - /* Modifications copyright (C) 2020 Ryan Powell */ #ifndef _NIMBLE_PORT_H #define _NIMBLE_PORT_H diff --git a/libesp32/NimBLE-Arduino/src/nimconfig.h b/libesp32/NimBLE-Arduino/src/nimconfig.h index 4db8562bb..0be27c198 100644 --- a/libesp32/NimBLE-Arduino/src/nimconfig.h +++ b/libesp32/NimBLE-Arduino/src/nimconfig.h @@ -1,17 +1,100 @@ #pragma once -#define CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL 1 -#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS 3 -#define CONFIG_BT_NIMBLE_MAX_BONDS 3 -#define CONFIG_BT_NIMBLE_MAX_CCCDS 8 -#define CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM 0 -#define CONFIG_BT_NIMBLE_PINNED_TO_CORE_0 1 + +#include "sdkconfig.h" +/** For ESP-IDF compatibility + * + * Some versions of ESP-IDF used the config name format "CONFIG_NIMBLE_". + * This converts them to "CONFIG_BT_NIMBLE_" format used in the latest IDF. + */ +/* Detect if using ESP-IDF or Arduino (Arduino won't have these defines in sdkconfig)*/ +#if defined(CONFIG_BT_NIMBLE_TASK_STACK_SIZE) || defined(CONFIG_NIMBLE_TASK_STACK_SIZE) + +#if defined(CONFIG_NIMBLE_ENABLED) +#define CONFIG_BT_NIMBLE_ENABLED +#endif + +#if defined(CONFIG_NIMBLE_ROLE_OBSERVER) +#define CONFIG_BT_NIMBLE_ROLE_OBSERVER +#endif + +#if defined(CONFIG_NIMBLE_ROLE_BROADCASTER) +#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER +#endif + +#if defined(CONFIG_NIMBLE_ROLE_CENTRAL) +#define CONFIG_BT_NIMBLE_ROLE_CENTRAL +#endif + +#if defined(CONFIG_NIMBLE_ROLE_PERIPHERAL) +#define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL +#endif + +#if defined(CONFIG_NIMBLE_DEBUG) +#define CONFIG_BT_NIMBLE_DEBUG +#endif + +#else // Using Arduino + +/*********************************************** + * Arduino config options + **********************************************/ + +/** Comment out if not using NimBLE Client functions + * Reduces flash size by approx. 7kB. + */ +#define CONFIG_BT_NIMBLE_ROLE_CENTRAL + +/** Comment out if not using NimBLE Scan functions + * Reduces flash size by approx. 26kB. + */ +#define CONFIG_BT_NIMBLE_ROLE_OBSERVER + +/** Comment out if not using NimBLE Server functions + * Reduces flash size by approx. 16kB. + */ +// #define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL // Tasmota + +/** Comment out if not using NimBLE Advertising functions + * Reduces flash size by approx. 5kB. + */ +// #define CONFIG_BT_NIMBLE_ROLE_BROADCASTER // Tasmota + +/** Uncomment to see debug log messages from the NimBLE host + * Uses approx. 32kB of flash memory. + */ +// #define CONFIG_BT_NIMBLE_DEBUG + +/** Uncomment to see NimBLE host return codes as text debug log messages. + * Uses approx. 7kB of flash memory. + */ +// #define CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT + +/** Uncomment to see GAP event codes as text in debug log messages. + * Uses approx. 1kB of flash memory. + */ +// #define CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT + +/** Uncomment to see advertisment types as text while scanning in debug log messages. + * Uses approx. 250 bytes of flash memory. + */ +// #define CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT + +/** Sets the core NimBLE host runs on */ #define CONFIG_BT_NIMBLE_PINNED_TO_CORE 0 + +/** Sets the stack size for the NimBLE host task */ #define CONFIG_BT_NIMBLE_TASK_STACK_SIZE 4096 -#define CONFIG_BT_NIMBLE_ROLE_CENTRAL 1 -#define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL 1 -#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER 1 -#define CONFIG_BT_NIMBLE_ROLE_OBSERVER 1 -#define CONFIG_BT_NIMBLE_NVS_PERSIST 1 + +/** Sets the number of simultaneous connections (esp controller max is 9) */ +#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS 3 + +/** Sets the number of devices allowed to store/bond with */ +#define CONFIG_BT_NIMBLE_MAX_BONDS 3 // Tasmota + +/** Sets the number of CCCD's to store per bonded device */ +#define CONFIG_BT_NIMBLE_MAX_CCCDS 3 // Tasmota + +#define CONFIG_BT_NIMBLE_NVS_PERSIST 0 // Tasmota #define CONFIG_BT_NIMBLE_SM_LEGACY 1 #define CONFIG_BT_NIMBLE_SM_SC 1 #define CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME "nimble" @@ -29,6 +112,23 @@ #define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH 2 #define CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT 1 #define CONFIG_BT_NIMBLE_RPA_TIMEOUT 900 -#define CONFIG_BT_ENABLED 1 -#define CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY 1 -#define CONFIG_BT_NIMBLE_DEBUG 0 +#define CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM 0 + +/** Do not comment out */ +#ifndef CONFIG_BT_ENABLED +#define CONFIG_BT_ENABLED +#endif +#define CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY +#define CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL + +#endif // #if defined(CONFIG_BT_NIMBLE_TASK_STACK_SIZE) || defined(CONFIG_NIMBLE_TASK_STACK_SIZE) + +/** Cannot use client without scan */ +#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) && !defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +#define CONFIG_BT_NIMBLE_ROLE_OBSERVER +#endif + +/** Cannot use server without advertise */ +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) && !defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER +#endif diff --git a/libesp32/NimBLE-Arduino/src/port/src/esp_nimble_mem.c b/libesp32/NimBLE-Arduino/src/port/src/esp_nimble_mem.c index ae2a69c20..a26e9b2f4 100644 --- a/libesp32/NimBLE-Arduino/src/port/src/esp_nimble_mem.c +++ b/libesp32/NimBLE-Arduino/src/port/src/esp_nimble_mem.c @@ -19,8 +19,6 @@ * under the License. */ - /* Modifications copyright (C) 2020 Ryan Powell */ - #include "esp_attr.h" #include "esp_heap_caps.h" #include "nimconfig.h" @@ -32,6 +30,8 @@ IRAM_ATTR void *nimble_platform_mem_malloc(size_t size) return heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL return heap_caps_malloc(size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT + return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #else return malloc(size); #endif @@ -43,6 +43,8 @@ IRAM_ATTR void *nimble_platform_mem_calloc(size_t n, size_t size) return heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT + return heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); #else return calloc(n, size); #endif @@ -51,4 +53,4 @@ IRAM_ATTR void *nimble_platform_mem_calloc(size_t n, size_t size) IRAM_ATTR void nimble_platform_mem_free(void *ptr) { heap_caps_free(ptr); -} \ No newline at end of file +} From 9f8d0fcd85744705d8ccdf99026ba46c0943670d Mon Sep 17 00:00:00 2001 From: Staars Date: Tue, 26 May 2020 20:44:40 +0200 Subject: [PATCH 102/581] update driver --- tasmota/xsns_62_MI_ESP32.ino | 360 +++++++++++++++++++---------------- 1 file changed, 201 insertions(+), 159 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index c9a5ba73a..28c927db9 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -225,18 +225,26 @@ class MI32SensorCallback : public NimBLEClientCallbacks { class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { void onResult(NimBLEAdvertisedDevice* advertisedDevice) { - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice.getAddress().toString().c_str(),advertisedDevice.getServiceData().length()); - if (advertisedDevice->getServiceData().length() == 0) return; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + if (advertisedDevice->getServiceData().length() == 0) { + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + MI32Scan->erase(advertisedDevice->getAddress()); + return; + } uint16_t uuid = advertisedDevice->getServiceDataUUID().getNative()->u16.value; - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%x"),uuid); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("UUID: %x"),uuid); uint8_t addr[6]; memcpy(addr,advertisedDevice->getAddress().getNative(),6); MI32_ReverseMAC(addr); if(uuid==0xfe95) { - MI32ParseResponse((char*)advertisedDevice->getServiceData().c_str(),advertisedDevice->getServiceData().length(), addr); + MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); } else if(uuid==0xfdcd) { - MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().c_str(),advertisedDevice->getServiceData().length(), addr); + MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); + } + else { + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + MI32Scan->erase(advertisedDevice->getAddress()); } }; }; @@ -391,47 +399,57 @@ void MI32StartTask(uint32_t task){ } } -void MI32ConnectActiveSensor(){ // only use inside a task !! +bool MI32ConnectActiveSensor(){ // only use inside a task !! + MI32.mode.connected = 0; MI32Client = nullptr; - esp_bd_addr_t address; - memcpy(address,MIBLEsensors[MI32.state.sensor].serial,sizeof(address)); + Wifi.counter = Wifi.counter + 20; // hopefully less interference + NimBLEAddress _address = NimBLEAddress(MIBLEsensors[MI32.state.sensor].serial); if(NimBLEDevice::getClientListSize()) { - MI32Client = NimBLEDevice::getClientByPeerAddress(NimBLEAddress(address)); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: found any clients in the cList"),D_CMND_MI32); + MI32Client = NimBLEDevice::getClientByPeerAddress(_address); if(MI32Client){ - if(!MI32Client->connect(NimBLEAddress(address), 0,false)) { - MI32.mode.willConnect = 0; - vTaskDelete( NULL ); - } + // Should be impossible + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: got connected client"),D_CMND_MI32); } else { + // Should be the norm after the first iteration MI32Client = NimBLEDevice::getDisconnectedClient(); + DEBUG_SENSOR_LOG(PSTR("%s: got disconnected client"),D_CMND_MI32); } } + + if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { + MI32.mode.willConnect = 0; + DEBUG_SENSOR_LOG(PSTR("%s: max connection already reached"),D_CMND_MI32); + return false; + } if(!MI32Client) { - if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { - MI32.mode.willConnect = 0; - vTaskDelete( NULL ); - } + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: will create client"),D_CMND_MI32); MI32Client = NimBLEDevice::createClient(); MI32Client->setClientCallbacks(&MI32SensorCB , false); - MI32Client->setConnectionParams(12,12,0,51); - MI32Client->setConnectTimeout(10); - if (!MI32Client->connect(NimBLEAddress(address),0,false)) { - MI32.mode.willConnect = 0; - NimBLEDevice::deleteClient(MI32Client); - vTaskDelete( NULL ); - } + MI32Client->setConnectionParams(12,12,0,48); + MI32Client->setConnectTimeout(30); } + if (!MI32Client->connect(_address,false)) { + MI32.mode.willConnect = 0; + NimBLEDevice::deleteClient(MI32Client); + DEBUG_SENSOR_LOG(PSTR("%s: did not connect client"),D_CMND_MI32); + return false; + } + DEBUG_SENSOR_LOG(PSTR("%s: did create new client"),D_CMND_MI32); + return true; + // } } void MI32StartScanTask(){ if (MI32.mode.connected) return; MI32.mode.runningScan = 1; + // Wifi.counter = Wifi.counter + 3; xTaskCreatePinnedToCore( MI32ScanTask, /* Function to implement the task */ "MI32ScanTask", /* Name of the task */ - 4096, /* Stack size in words */ + 8192, /* Stack size in words */ NULL, /* Task input parameter */ 0, /* Priority of the task */ NULL, /* Task handle. */ @@ -440,17 +458,18 @@ void MI32StartScanTask(){ } void MI32ScanTask(void *pvParameters){ - NimBLEScan* pScan = NimBLEDevice::getScan(); - pScan->setAdvertisedDeviceCallbacks(&MI32ScanCallbacks); - pScan->setActiveScan(false); - pScan->start(5, MI32scanEndedCB); // hard coded duration + if (MI32Scan == nullptr) MI32Scan = NimBLEDevice::getScan(); + DEBUG_SENSOR_LOG(PSTR("%s: Scan Cache Length: %u"),D_CMND_MI32, MI32Scan->getResults().getCount()); + MI32Scan->setAdvertisedDeviceCallbacks(&MI32ScanCallbacks); + MI32Scan->setActiveScan(false); + MI32Scan->start(5, MI32scanEndedCB, true); // hard coded duration uint32_t timer = 0; while (MI32.mode.runningScan){ if (timer>15){ vTaskDelete( NULL ); } timer++; - vTaskDelay(1000); + vTaskDelay(1000/ portTICK_PERIOD_MS); } vTaskDelete( NULL ); } @@ -474,47 +493,62 @@ void MI32SensorTask(void *pvParameters){ MI32.mode.willConnect = 0; vTaskDelete( NULL ); } - MI32ConnectActiveSensor(); - MI32.mode.readingDone = 1; - switch(MIBLEsensors[MI32.state.sensor].type){ - case LYWSD03MMC: - MI32.mode.readingDone = 0; - MI32connectLYWSD03(); - break; - default: - break; - } - uint32_t timer = 0; - while (!MI32.mode.readingDone){ - if (timer>150){ + if (MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + MI32Client->disconnect(); + NimBLEDevice::deleteClient(MI32Client); + MI32.mode.willConnect = 0; + vTaskDelay(100/ portTICK_PERIOD_MS); + vTaskDelete( NULL ); + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); + } + + timer = 150; + switch(MIBLEsensors[MI32.state.sensor].type){ + case LYWSD03MMC: + MI32.mode.readingDone = 0; + if(MI32connectLYWSD03forNotification()) timer=0; + break; + default: break; } - timer++; - vTaskDelay(100); + + while (!MI32.mode.readingDone){ + if (timer>150){ + break; + } + timer++; + vTaskDelay(100/ portTICK_PERIOD_MS); + } + MI32Client->disconnect(); + DEBUG_SENSOR_LOG(PSTR("%s: requested disconnect"),D_CMND_MI32); } - MI32Client->disconnect(); - NimBLEDevice::deleteClient(MI32Client); - vTaskDelay(500); + vTaskDelay(500/ portTICK_PERIOD_MS); MI32.mode.connected = 0; vTaskDelete( NULL ); } -void MI32connectLYWSD03(){ +bool MI32connectLYWSD03forNotification(){ NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"); - static BLEUUID charUUID("ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6"); + static BLEUUID serviceUUID(0xebe0ccb0,0x7a0a,0x4b0c,0x8a1a6ff2997da3a6); + static BLEUUID charUUID(0xebe0ccc1,0x7a0a,0x4b0c,0x8a1a6ff2997da3a6); pSvc = MI32Client->getService(serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(charUUID); } - if(pChr->canNotify()) { - if(!pChr->registerForNotify(MI32notifyCB)) { - MI32.mode.willConnect = 0; - MI32Client->disconnect(); - return; + if (pChr){ + if(pChr->canNotify()) { + if(pChr->registerForNotify(MI32notifyCB)) { + return true; + } } } + return false; } void MI32StartTimeTask(){ @@ -536,45 +570,48 @@ void MI32TimeTask(void *pvParameters){ MI32.mode.shallSetTime = 0; vTaskDelete( NULL ); } - MI32ConnectActiveSensor(); - uint32_t timer = 0; - while (MI32.mode.connected == 0){ - if (timer>1000){ - break; + if(MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); } - timer++; - vTaskDelay(10); - } - NimBLERemoteService* pSvc = nullptr; - NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); - static BLEUUID charUUID("EBE0CCB7-7A0A-4B0C-8A1A-6FF2997DA3A6"); - pSvc = MI32Client->getService(serviceUUID); - if(pSvc) { - pChr = pSvc->getCharacteristic(charUUID); - } - if(pChr->canWrite()) { - union { - uint8_t buf[5]; - uint32_t time; - } _utc; - _utc.time = Rtc.utc_time; - _utc.buf[4] = Rtc.time_timezone / 60; + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + static BLEUUID charUUID(0xEBE0CCB7,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + pSvc = MI32Client->getService(serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(charUUID); - if(!pChr->writeValue(_utc.buf,sizeof(_utc.buf),true)) { // true is important ! - MI32.mode.willConnect = 0; - MI32Client->disconnect(); } - else { - MI32.mode.shallSetTime = 0; - MI32.mode.willSetTime = 0; + if (pChr){ + if(pChr->canWrite()) { + union { + uint8_t buf[5]; + uint32_t time; + } _utc; + _utc.time = Rtc.utc_time; + _utc.buf[4] = Rtc.time_timezone / 60; + + if(!pChr->writeValue(_utc.buf,sizeof(_utc.buf),true)) { // true is important ! + MI32.mode.willConnect = 0; + MI32Client->disconnect(); + } + else { + MI32.mode.shallSetTime = 0; + MI32.mode.willSetTime = 0; + } + } } + MI32Client->disconnect(); } - MI32Client->disconnect(); - NimBLEDevice::deleteClient(MI32Client); - vTaskDelay(500); + vTaskDelay(500/ portTICK_PERIOD_MS); MI32.mode.connected = 0; vTaskDelete( NULL ); } @@ -582,6 +619,8 @@ void MI32TimeTask(void *pvParameters){ void MI32StartBatteryTask(){ if (MI32.mode.connected) return; MI32.mode.willReadBatt = 1; + MI32.mode.willConnect = 1; + MI32.mode.canScan = 0; xTaskCreatePinnedToCore( MI32BatteryTask, /* Function to implement the task */ "MI32BatteryTask", /* Name of the task */ @@ -605,31 +644,32 @@ void MI32BatteryTask(void *pvParameters){ } MI32.mode.connected = 0; - MI32ConnectActiveSensor(); - uint32_t timer = 0; - while (MI32.mode.connected == 0){ - if (timer>1000){ + if(MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(30/ portTICK_PERIOD_MS); + } + + switch(MIBLEsensors[MI32.state.sensor].type){ + case FLORA: + MI32batteryFLORA(); + break; + case LYWSD02: + MI32batteryLYWSD02(); + break; + case CGD1: + MI32batteryCGD1(); break; } - timer++; - vTaskDelay(10); - } - - switch(MIBLEsensors[MI32.state.sensor].type){ - case FLORA: - MI32batteryFLORA(); - break; - case LYWSD02: - MI32batteryLYWSD02(); - break; - case CGD1: - MI32batteryCGD1(); - break; - } - MI32Client->disconnect(); + MI32Client->disconnect(); + } MI32.mode.willReadBatt = 0; - NimBLEDevice::deleteClient(MI32Client); - vTaskDelay(500); + // Wifi.counter = 0; // Now check it + vTaskDelay(500/ portTICK_PERIOD_MS); MI32.mode.connected = 0; vTaskDelete( NULL ); } @@ -641,27 +681,26 @@ void MI32batteryFLORA(){ break; } timer++; - vTaskDelay(10); + vTaskDelay(10/ portTICK_PERIOD_MS); } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s connected for battery"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); + DEBUG_SENSOR_LOG(PSTR("%s connected for battery"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID FLserviceUUID("00001204-0000-1000-8000-00805f9b34fb"); - static BLEUUID FLcharUUID("00001a02-0000-1000-8000-00805f9b34fb"); + static BLEUUID FLserviceUUID(0x00001204,0x0000,0x1000,0x800000805f9b34fb); + static BLEUUID FLcharUUID(0x00001a02,0x0000,0x1000,0x800000805f9b34fb); pSvc = MI32Client->getService(FLserviceUUID); - if(pSvc) { /** make sure it's not null */ + if(pSvc) { pChr = pSvc->getCharacteristic(FLcharUUID); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: got Flora char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); } - else { - MI32.mode.readingDone = 1; - return; - } - if(pChr->canRead()) { - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); + if (pChr){ + DEBUG_SENSOR_LOG(PSTR("%s: got Flora char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + if(pChr->canRead()) { + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); + } } + MI32.mode.readingDone = 1; } void MI32batteryLYWSD02(){ @@ -671,27 +710,27 @@ void MI32batteryLYWSD02(){ break; } timer++; - vTaskDelay(10); + vTaskDelay(10/ portTICK_PERIOD_MS); } NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID LY2serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); - static BLEUUID LY2charUUID("EBE0CCC4-7A0A-4B0C-8A1A-6FF2997DA3A6"); + static BLEUUID LY2serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + static BLEUUID LY2charUUID(0xEBE0CCC4,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); pSvc = MI32Client->getService(LY2serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(LY2charUUID); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: got LYWSD02 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); } - else { - return; - } - if(pChr->canRead()) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("LYWSD02 char")); - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); + if (pChr){ + DEBUG_SENSOR_LOG( PSTR("%s: got LYWSD02 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + if(pChr->canRead()) { + DEBUG_SENSOR_LOG(PSTR("LYWSD02 char")); + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); + } } + MI32.mode.readingDone = 1; } void MI32batteryCGD1(){ @@ -701,26 +740,26 @@ void MI32batteryCGD1(){ break; } timer++; - vTaskDelay(10); + vTaskDelay(10/ portTICK_PERIOD_MS); } NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID CGD1serviceUUID("180F"); - static BLEUUID CGD1charUUID("2A19"); + static BLEUUID CGD1serviceUUID((uint16_t)0x180F); + static BLEUUID CGD1charUUID((uint16_t)0x2A19); pSvc = MI32Client->getService(CGD1serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(CGD1charUUID); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: got CGD1 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); } - else { - return; - } - if(pChr->canRead()) { - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); + if (pChr){ + DEBUG_SENSOR_LOG(PSTR("%s: got CGD1 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + if(pChr->canRead()) { + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); + } } + MI32.mode.readingDone = 1; } @@ -740,14 +779,14 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ } MI32_ReverseMAC(_beacon.Mac); - DEBUG_SENSOR_LOG(PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); - DEBUG_SENSOR_LOG(PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); if(MIBLEsensors[_slot].type==4 || MIBLEsensors[_slot].type==6){ DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type); return; } - DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kMI32SlaveType[MIBLEsensors[_slot].type-1],_slot); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32SlaveType[MIBLEsensors[_slot].type-1],_slot); switch(_beacon.type){ case 0x04: _tempFloat=(float)(_beacon.temp)/10.0f; @@ -755,7 +794,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].temp=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); break; case 0x06: _tempFloat=(float)(_beacon.hum)/10.0f; @@ -763,11 +802,11 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].hum=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode 6: U16: %u Hum"), _beacon.hum); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _beacon.hum); break; case 0x07: MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff; - DEBUG_SENSOR_LOG(PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); break; case 0x08: _tempFloat =(float)_beacon.moist; @@ -775,7 +814,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].moisture=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); break; case 0x09: _tempFloat=(float)(_beacon.fert); @@ -783,14 +822,14 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].fertility=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); break; case 0x0a: if(_beacon.bat<101){ MIBLEsensors[_slot].bat = _beacon.bat; DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode a: U8: %u %%"), _beacon.bat); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode a: U8: %u %%"), _beacon.bat); break; case 0x0d: _tempFloat=(float)(_beacon.HT.temp)/10.0f; @@ -803,7 +842,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); break; } } @@ -911,6 +950,8 @@ void MI32EverySecond(bool restart){ _counter = 0; MI32.mode.canScan = 0; MI32.mode.canConnect = 1; + MI32.mode.willReadBatt = 0; + MI32.mode.willConnect = 0; return; } @@ -940,9 +981,9 @@ void MI32EverySecond(bool restart){ if(_counter==0) { MI32.state.sensor = _nextSensorSlot; - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u"),D_CMND_MI32, MI32.state.sensor); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u of %u"),D_CMND_MI32, MI32.state.sensor, MIBLEsensors.size()-1); MI32.mode.canScan = 0; - if (MI32.mode.runningScan == 1 || MI32.mode.connected == 1) return; + if (MI32.mode.runningScan|| MI32.mode.connected || MI32.mode.willConnect) return; _nextSensorSlot++; MI32.mode.canConnect = 1; if(MI32.mode.connected == 0) { @@ -956,7 +997,7 @@ void MI32EverySecond(bool restart){ } } - if (MI32.state.sensor==MIBLEsensors.size()-1) { + if (_nextSensorSlot>(MIBLEsensors.size()-1)) { _nextSensorSlot= 0; _counter++; if (MI32.mode.shallReadBatt){ @@ -1056,6 +1097,7 @@ const char HTTP_MI32_HL[] PROGMEM = "{s}
{m}
{e}"; void MI32Show(bool json) { + if (json) { for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { /* @@ -1069,7 +1111,7 @@ void MI32Show(bool json) MIBLEsensors[i].serial[3], MIBLEsensors[i].serial[4], MIBLEsensors[i].serial[5]); if (MIBLEsensors[i].type == FLORA) { - if (!isnan(MIBLEsensors[i].temp)) { // this is the error code -> no temperature + if (!isnan(MIBLEsensors[i].temp)) { char temperature[FLOATSZ]; // all sensors have temperature dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), temperature); @@ -1196,4 +1238,4 @@ bool Xsns62(uint8_t function) return result; } #endif // USE_MI_ESP32 -#endif // ESP32 +#endif // ESP32 \ No newline at end of file From ba905255ee5f3ab11ab37942a89d6922eeff8498 Mon Sep 17 00:00:00 2001 From: Staars Date: Tue, 26 May 2020 20:45:55 +0200 Subject: [PATCH 103/581] remove second method to suppress warning --- platformio_override_sample.ini | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index edfb35678..ee6fca3df 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -175,9 +175,7 @@ upload_speed = 921600 extra_scripts = ${common.extra_scripts} build_flags = ${esp_defaults.build_flags} -; NimBLE-Arduino uses arithmetic on void- and function-pointers, this is only a cosmetic warning suppression - -Wno-pointer-arith - + -D BUFFER_LENGTH=128 -D MQTT_MAX_PACKET_SIZE=1200 -D uint32=uint32_t From f46e28d1d08aac77edc95812a3f00c5ff55c2dca Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 26 May 2020 21:46:34 +0200 Subject: [PATCH 104/581] Use latest ESP framework 1.12.2 --- platformio_override_sample.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index edfb35678..f588248bd 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -159,7 +159,7 @@ build_type = debug ; *** expect the unexpected. Many features not working!!! *** [common32] -platform = espressif32@1.12.1 +platform = espressif32@1.12.2 platform_packages = tool-esptoolpy@1.20800.0 board = esp32dev board_build.ldscript = esp32_out.ld From 55aac3f4a7a1cf96aafa3b0987cac9024c6c1e85 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 26 May 2020 21:48:14 +0200 Subject: [PATCH 105/581] Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8599df428..20d80249a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,7 +7,7 @@ - [ ] Only relevant files were touched - [ ] Only one feature/fix was added per PR. - [ ] The code change is tested and works on core ESP8266 V.2.7.1 - - [ ] The code change is tested and works on core ESP32 V.1.12.0 + - [ ] The code change is tested and works on core ESP32 V.1.12.2 - [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). _NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_ From bc6d7ceb876675678eb12a93cc4f9e051cdd247e Mon Sep 17 00:00:00 2001 From: Paul C Diem Date: Tue, 26 May 2020 22:07:25 -0500 Subject: [PATCH 106/581] Add support for SetOption88 to put each relay in a separate device groups --- tasmota/settings.h | 2 +- tasmota/support_device_groups.ino | 35 ++++++++++++++++++++++++------- tasmota/support_tasmota.ino | 7 ++++++- tasmota/tasmota_globals.h | 2 +- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 23a477e12..accf21842 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -107,7 +107,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t device_groups_enabled : 1; // bit 3 (v8.1.0.9) - SetOption85 - Enable Device Groups uint32_t led_timeout : 1; // bit 4 (v8.1.0.9) - SetOption86 - PWM Dimmer Turn brightness LED's off 5 seconds after last change uint32_t powered_off_led : 1; // bit 5 (v8.1.0.9) - SetOption87 - PWM Dimmer Turn red LED on when powered off - uint32_t remote_device_mode : 1; // bit 6 (v8.1.0.9) - SetOption88 - PWM Dimmer Buttons control remote devices + uint32_t remote_device_mode : 1; // bit 6 (v8.1.0.9) - SetOption88 - Enable relays in separate device groups/PWM Dimmer Buttons control remote devices uint32_t zigbee_distinct_topics : 1; // bit 7 (v8.1.0.10) - SetOption89 - Distinct MQTT topics per device for Zigbee (#7835) uint32_t only_json_message : 1; // bit 8 (v8.2.0.3) - SetOption90 - Disable non-json MQTT response uint32_t fade_at_startup : 1; // bit 9 (v8.2.0.3) - SetOption91 - Enable light fading at start/power on diff --git a/tasmota/support_device_groups.ino b/tasmota/support_device_groups.ino index 30b5bacc0..9572c9a6a 100644 --- a/tasmota/support_device_groups.ino +++ b/tasmota/support_device_groups.ino @@ -110,6 +110,23 @@ bool DeviceGroupItemShared(bool incoming, uint8_t item) void DeviceGroupsInit(void) { + // If no module set the device group count, ... + if (!device_group_count) { + + // If relays in sepaate device groups is enabled, set the device group count to highest numbered + // relay. + if (Settings.flag4.remote_device_mode) { // SetOption88 - Enable relays in separate device groups + for (uint32_t relay_index = 0; relay_index < MAX_RELAYS; relay_index++) { + if (PinUsed(GPIO_REL1, relay_index)) device_group_count = relay_index + 1; + } + } + + // Otherwise, set the device group count to 1. + else { + device_group_count = 1; + } + } + // If there are more device group names set than the number of device groups needed by the // mdoule, use the device group name count as the device group count. for (; device_group_count < MAX_DEV_GROUP_NAMES; device_group_count++) { @@ -368,13 +385,18 @@ void SendReceiveDeviceGroupMessage(struct device_group * device_group, struct de log_remaining--; switch (item) { case DGR_ITEM_POWER: - if (device_group->local) { + if (Settings.flag4.remote_device_mode) { // SetOption88 - Enable relays in separate device groups + bool on = (value & 1); + if (on != (power & 1)) ExecuteCommandPower(device_group_index + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE); + } + else if (device_group->local) { uint8_t mask_devices = value >> 24; if (mask_devices > devices_present) mask_devices = devices_present; - for (uint32_t i = 0; i < devices_present; i++) { + for (uint32_t i = 0; i < mask_devices; i++) { uint32_t mask = 1 << i; bool on = (value & mask); if (on != (power & mask)) ExecuteCommandPower(i + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE); + if (Settings.flag4.remote_device_mode) break; // SetOption88 - Enable relays in separate device groups } } break; @@ -475,7 +497,9 @@ bool _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes building_status_message = true; // Call the drivers to build the status update. - if (device_group->local) SendLocalDeviceGroupMessage(DGR_MSGTYP_PARTIAL_UPDATE, DGR_ITEM_POWER, power); + if (device_group->local || Settings.flag4.remote_device_mode) { // SetOption88 - Enable relays in separate device groups + SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_PARTIAL_UPDATE, DGR_ITEM_POWER, power); + } XdrvMailbox.index = device_group_index << 16; XdrvMailbox.command_code = DGR_ITEM_STATUS; XdrvMailbox.topic = (char *)&device_group_index; @@ -648,10 +672,7 @@ bool _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes *message_ptr++ = value & 0xff; value >>= 8; // For the power item, the device count is overlayed onto the highest 8 bits. - if (item == DGR_ITEM_POWER) { - if (!value) - value = (device_group_index == 0 ? devices_present : 1); - } + if (item == DGR_ITEM_POWER && !value) value = (device_group_index == 0 ? devices_present : 1); *message_ptr++ = value; } } diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 654afe082..f21512900 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -571,7 +571,12 @@ void ExecuteCommandPower(uint32_t device, uint32_t state, uint32_t source) power ^= mask; } #ifdef USE_DEVICE_GROUPS - if (SRC_REMOTE != source && SRC_RETRY != source) SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_POWER, power); + if (SRC_REMOTE != source && SRC_RETRY != source) { + if (Settings.flag4.remote_device_mode) // SetOption88 - Enable relays in separate device groups + SendDeviceGroupMessage(device - 1, DGR_MSGTYP_UPDATE, DGR_ITEM_POWER, (power >> device - 1) & 1 | 0x01000000); // Explicitly set number of relays to one + else + SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_POWER, power); + } #endif // USE_DEVICE_GROUPS SetDevicePower(power, source); #ifdef USE_DOMOTICZ diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 27a730ec5..4c91bb2d1 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -335,7 +335,7 @@ const char kWebColors[] PROGMEM = #ifdef USE_DEVICE_GROUPS #define SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, ...) _SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, __VA_ARGS__, 0) #define SendLocalDeviceGroupMessage(REQUEST_TYPE, ...) _SendDeviceGroupMessage(0, REQUEST_TYPE, __VA_ARGS__, 0) -uint8_t device_group_count = 1; +uint8_t device_group_count = 0; #endif // USE_DEVICE_GROUPS #ifdef DEBUG_TASMOTA_CORE From 77c60229cc4afa782384b6f8e0d3ad5fc40eb2f6 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Wed, 27 May 2020 11:14:17 +0200 Subject: [PATCH 107/581] ESP32 support for SSD1351 --- lib/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp | 234 ++++++++++++---------- platformio_override_sample.ini | 4 +- tasmota/tasmota_globals.h | 2 +- tasmota/xdsp_09_SSD1351.ino | 1 - 4 files changed, 133 insertions(+), 108 deletions(-) diff --git a/lib/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp b/lib/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp index 3e1ccb2c7..c822fe565 100644 --- a/lib/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp +++ b/lib/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp @@ -29,6 +29,8 @@ SSD1351::SSD1351(int8_t cs,int8_t mosi,int8_t sclk) : Renderer(SSD1351_WIDTH, SS _hwspi = 0; } +#ifndef ESP32 + #include "spi_register.h" /* CPU Clock = 80 Mhz @@ -189,84 +191,81 @@ void SSD1351::writedata(uint8_t d) { } -uint16_t SSD1351::GetColorFromIndex(uint8_t index) { - if (index>=sizeof(ssd1351_colors)/2) index=0; - return ssd1351_colors[index]; -} +void ICACHE_RAM_ATTR SSD1351::fastSPIwrite(uint8_t d,uint8_t dc) { -void SSD1351::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { - setRotation(rot); - invertDisplay(false); - setTextWrap(false); // Allow text to run off edges - cp437(true); - setTextFont(font&3); - setTextSize(size&7); - setTextColor(SSD1351_WHITE,SSD1351_BLACK); - setCursor(0,0); - fillScreen(SSD1351_BLACK); - stop(); -} + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_cs); + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); + if(dc) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); + else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); -void SSD1351::DisplayOnff(int8_t on) { - if (on) { - writecommand(SSD1351_CMD_DISPLAYON); //Display on - } else { - writecommand(SSD1351_CMD_DISPLAYOFF); + for(uint8_t bit = 0x80; bit; bit >>= 1) { + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); + if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); + else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); } - stop(); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_cs); } -// dimmer 0-100 -void SSD1351::dim(uint8_t contrast) { - writecommand(SSD1351_CMD_CONTRASTMASTER); - if (contrast>15) contrast=15; - writedata(contrast); - stop(); + +#else +// ESP32 section +uint8_t ssd131_start; + +void SSD1351::writedata(uint8_t d) { + fastSPIwrite(d,1); } -/* -if (SSD_COMSPLIT == 1){ - _remapReg |= ((1 << 5)); - } else { - _remapReg |= ((0 << 5)); - } - setRegister_cont(CMD_CMDLOCK,SSD_COMMANDLOCK1); - setRegister_cont(CMD_CMDLOCK,SSD_COMMANDLOCK2); - writecommand_cont(CMD_DISPLAYOFF); - setRegister_cont(CMD_CLOCKDIV,SSD_CLOCKDIV); - setRegister_cont(CMD_MUXRATIO,SSD_MUXRATIO); - setRegister_cont(CMD_STARTLINE,SSD_STARTLINE); >>> - setRegister_cont(CMD_DISPLAYOFFSET,SSD_DISPLAYOFFSET); - setRegister_cont(CMD_SETGPIO,SSD_SETGPIO); - setRegister_cont(CMD_FUNCTIONSELECT,SSD_FUNCTIONSELECT); - writecommand_cont(CMD_SETVSL); - writedata8_cont(SSD_SETVSL_A);writedata8_cont(SSD_SETVSL_B);writedata8_cont(SSD_SETVSL_C); - writecommand_cont(CMD_CONTRASTABC); - writedata8_cont(SSD_CONTRAST_A);writedata8_cont(SSD_CONTRAST_B);writedata8_cont(SSD_CONTRAST_C); - setRegister_cont(CMD_MASTERCURRENT,SSD_MASTERCURRENT); >>> - writecommand_cont(CMD_DISPLAYENHANCE); >> - if (SSD_ENHANCE){ - writedata8_cont(0xA4); - } else { - writedata8_cont(0x00); - } - writedata8_cont(0x00); - writedata8_cont(0x00); - #if defined(SSD_GAMMASET) - //writecommand_cont(CMD_GRAYSCALE); for (uint8_t i =0;i<32;i++){writedata8_cont(SSD_GRAYTABLE[i]);} - #else - writecommand_cont(CMD_USELUT); - #endif - // phase here - setRegister_cont(CMD_PRECHARGE,SSD_PRECHARGE); >> - setRegister_cont(CMD_PRECHARGE2,SSD_PRECHARGE2); - setRegister_cont(CMD_VCOMH,SSD_VCOMH); - #endif - //setAddrWindow_cont(0,0,SSD_WIDTH-1,SSD_HEIGHT-1,false);// ??? - //_pushColors_cont(_defaultBgColor, SSD_CGRAM);//??? - //Normal Display and turn ON - writecommand_cont(CMD_NORMALDISPLAY); -*/ +void SSD1351::writecommand(uint8_t c) { + fastSPIwrite(c,0); +} + +#include "soc/spi_reg.h" +#include "soc/spi_struct.h" +#include "esp32-hal-spi.h" +#include "esp32-hal.h" +#include "soc/spi_struct.h" + +SPISettings oled_spiSettings; + +// diconnect from spi +void SSD1351::start(void) { + if (ssd131_start) return; + SPI.beginTransaction(oled_spiSettings); + ssd131_start = 1; +} + +// reconnect to spi +void SSD1351::stop(void) { + if (!ssd131_start) return; + SPI.endTransaction(); + ssd131_start = 0; +} + +// since ardunio transferBits ia completely disfunctional +// we use our own hardware driver for 9 bit spi +void SSD1351::fastSPIwrite(uint8_t d,uint8_t dc) { + digitalWrite( _cs, LOW); + + uint32_t regvalue=d>>1; + if (dc) regvalue|=0x80; + else regvalue&=0x7f; + if (d&1) regvalue|=0x8000; + + REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); + REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1); + uint32_t *dp=(uint32_t*)SPI_W0_REG(3); + *dp=regvalue; + REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + + digitalWrite( _cs, HIGH); +} + +#endif + + static const uint8_t PROGMEM initList[] = { SSD1351_CMD_COMMANDLOCK, 1, // Set command lock, 1 arg 0x12, @@ -305,34 +304,30 @@ static const uint8_t PROGMEM initList[] = { 0 }; // END OF COMMAND LIST - void SSD1351::sendcommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes) { - writecommand(commandByte); - for (int i=0; i=sizeof(ssd1351_colors)/2) index=0; + return ssd1351_colors[index]; +} + +void SSD1351::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { + setRotation(rot); + invertDisplay(false); + setTextWrap(false); // Allow text to run off edges + cp437(true); + setTextFont(font&3); + setTextSize(size&7); + setTextColor(SSD1351_WHITE,SSD1351_BLACK); + setCursor(0,0); + fillScreen(SSD1351_BLACK); + stop(); +} + +void SSD1351::DisplayOnff(int8_t on) { + if (on) { + writecommand(SSD1351_CMD_DISPLAYON); //Display on + } else { + writecommand(SSD1351_CMD_DISPLAYOFF); + } + stop(); +} + +// dimmer 0-100 +void SSD1351::dim(uint8_t contrast) { + writecommand(SSD1351_CMD_CONTRASTMASTER); + if (contrast>15) contrast=15; + writedata(contrast); + stop(); +} + +#define ssd1351_swap(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation void SSD1351::setAddrWindow_i(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h) { @@ -501,20 +544,3 @@ void SSD1351::drawFastHLine(int16_t x,int16_t y,int16_t w,uint16_t color) { } stop(); } - -void ICACHE_RAM_ATTR SSD1351::fastSPIwrite(uint8_t d,uint8_t dc) { - - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_cs); - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); - if(dc) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); - else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); - WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); - - for(uint8_t bit = 0x80; bit; bit >>= 1) { - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); - if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); - else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); - WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); - } - WRITE_PERI_REG( PIN_OUT_SET, 1<<_cs); -} diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index e60b27f9a..695973c2e 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -167,7 +167,7 @@ board_build.partitions = esp32_partition_app1984k_spiffs64k.csv board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_cpu = ${common.board_build.f_cpu} build_unflags = ${common.build_unflags} - -Wpointer-arith + -Wpointer-arith monitor_speed = ${common.monitor_speed} upload_port = ${common.upload_port} upload_resetmethod = ${common.upload_resetmethod} @@ -193,5 +193,5 @@ lib_extra_dirs = lib_ignore = ILI9488 - SSD3115 + ; SSD3115 cc1101 diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 4c91bb2d1..37e39e451 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -301,7 +301,7 @@ const char kWebColors[] PROGMEM = #undef USE_HM10 // Disable support for HM-10 as a BLE-bridge as an alternative is using the internal ESP32 BLE #undef USE_KEELOQ // Disable support for Jarolift rollers by Keeloq algorithm as it's library cc1101 is not compatible with ESP32 #undef USE_DISPLAY_ILI9488 // Disable as it's library JaretBurkett_ILI9488-gemu-1.0 is not compatible with ESP32 -#undef USE_DISPLAY_SSD1351 // Disable as it's library Adafruit_SSD1351_gemu-1.0 is not compatible with ESP32 +//#undef USE_DISPLAY_SSD1351 // Disable as it's library Adafruit_SSD1351_gemu-1.0 is not compatible with ESP32 #endif // ESP32 diff --git a/tasmota/xdsp_09_SSD1351.ino b/tasmota/xdsp_09_SSD1351.ino index 5f3148be6..822025d16 100644 --- a/tasmota/xdsp_09_SSD1351.ino +++ b/tasmota/xdsp_09_SSD1351.ino @@ -71,7 +71,6 @@ void SSD1351_InitDriver() { } delay(100); - SPI.begin(); ssd1351->begin(); renderer = ssd1351; renderer->DisplayInit(DISPLAY_INIT_MODE,Settings.display_size,Settings.display_rotate,Settings.display_font); From 55e56fee43fefbf308242ab8e48493009398f32e Mon Sep 17 00:00:00 2001 From: Staars Date: Wed, 27 May 2020 15:59:32 +0200 Subject: [PATCH 108/581] Touch pin as button for ESP32 --- tasmota/support_button.ino | 39 +++++++++++++++++++++++++++++--- tasmota/support_tasmota.ino | 6 +++++ tasmota/tasmota_template_ESP32.h | 6 +++-- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/tasmota/support_button.ino b/tasmota/support_button.ino index e48723a2a..96dfaf73a 100644 --- a/tasmota/support_button.ino +++ b/tasmota/support_button.ino @@ -24,6 +24,10 @@ \*********************************************************************************************/ #define MAX_RELAY_BUTTON1 5 // Max number of relay controlled by BUTTON1 +#ifdef ESP32 +#define TOUCH_PIN_THRESHOLD 12 // Smaller value will treated as button press +#define TOUCH_HIT_THRESHOLD 3 // successful hits to filter out noise +#endif // ESP32 const char kMultiPress[] PROGMEM = "|SINGLE|DOUBLE|TRIPLE|QUAD|PENTA|"; @@ -40,6 +44,10 @@ struct BUTTON { uint8_t dual_receive_count = 0; // Sonoff dual input flag uint8_t no_pullup_mask = 0; // key no pullup flag (1 = no pullup) uint8_t inverted_mask = 0; // Key inverted flag (1 = inverted) +#ifdef ESP32 + uint8_t touch_mask = 0; // Touch flag (1 = inverted) + uint8_t touch_hits[MAX_KEYS] = { 0 }; // Hits in a row to filter out noise +#endif // ESP32 uint8_t present = 0; // Number of buttons found flag uint8_t adc = 99; // ADC0 button number } Button; @@ -55,7 +63,12 @@ void ButtonInvertFlag(uint8 button_bit) { bitSet(Button.inverted_mask, button_bit); } - +#ifdef ESP32 +void ButtonTouchFlag(uint8 button_bit) +{ + bitSet(Button.touch_mask, button_bit); +} +#endif // ESP32 void ButtonInit(void) { Button.present = 0; @@ -131,11 +144,32 @@ void ButtonHandler(void) } } else -#endif // ESP8266 if (PinUsed(GPIO_KEY1, button_index)) { button_present = 1; button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index)); } +#else + if (PinUsed(GPIO_KEY1, button_index)) { + button_present = 1; + if (bitRead(Button.touch_mask, button_index)){ // Touch + uint32_t _value = touchRead(Pin(GPIO_KEY1, button_index)); + button = NOT_PRESSED; + if (_value != 0){ // probably read-error + if(_value < TOUCH_PIN_THRESHOLD){ + if(++Button.touch_hits[button_index]>TOUCH_HIT_THRESHOLD){ + button = PRESSED; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Touch value: %u hits: %u"), _value, Button.touch_hits[button_index]); + } + } + else Button.touch_hits[button_index] = 0; + } + else Button.touch_hits[button_index] = 0; + } + else{ // Normal button + button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index)); + } + } +#endif // ESP8266 #ifndef USE_ADC_VCC if (Button.adc == button_index) { button_present = 1; @@ -147,7 +181,6 @@ void ButtonHandler(void) } } #endif // USE_ADC_VCC - if (button_present) { XdrvMailbox.index = button_index; XdrvMailbox.payload = button; diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index f21512900..26341b416 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1472,6 +1472,12 @@ void GpioInit(void) ButtonInvertFlag(mpin - AGPIO(GPIO_KEY1_INV_NP)); // 0 .. 3 mpin -= (AGPIO(GPIO_KEY1_INV_NP) - AGPIO(GPIO_KEY1)); } +#ifdef ESP32 + else if ((mpin >= AGPIO(GPIO_KEY1_TC)) && (mpin < (AGPIO(GPIO_KEY1_TC) + MAX_KEYS))) { + ButtonTouchFlag(mpin - AGPIO(GPIO_KEY1_TC)); // 0 .. 3 + mpin -= (AGPIO(GPIO_KEY1_TC) - AGPIO(GPIO_KEY1)); + } +#endif //ESP32 else if ((mpin >= AGPIO(GPIO_REL1_INV)) && (mpin < (AGPIO(GPIO_REL1_INV) + MAX_RELAYS))) { bitSet(rel_inverted, mpin - AGPIO(GPIO_REL1_INV)); mpin -= (AGPIO(GPIO_REL1_INV) - AGPIO(GPIO_REL1)); diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 5fac8c85d..3b5ad9120 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -44,7 +44,7 @@ enum UserSelectablePins { GPIO_NONE, // Not used - GPIO_KEY1, GPIO_KEY1_NP, GPIO_KEY1_INV, GPIO_KEY1_INV_NP, // 4 x Button + GPIO_KEY1, GPIO_KEY1_NP, GPIO_KEY1_INV, GPIO_KEY1_INV_NP, GPIO_KEY1_TC, // 4 x Button + Touch GPIO_SWT1, GPIO_SWT1_NP, // 8 x User connected external switches GPIO_REL1, GPIO_REL1_INV, // 8 x Relays GPIO_LED1, GPIO_LED1_INV, // 4 x Leds @@ -138,7 +138,7 @@ enum ProgramSelectablePins { // Text in webpage Module Parameters and commands GPIOS and GPIO const char kSensorNames[] PROGMEM = D_SENSOR_NONE "|" - D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "_n|" D_SENSOR_BUTTON "_i|" D_SENSOR_BUTTON "_in|" + D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "_n|" D_SENSOR_BUTTON "_i|" D_SENSOR_BUTTON "_in|" D_SENSOR_BUTTON "_tc|" D_SENSOR_SWITCH "|" D_SENSOR_SWITCH "_n|" D_SENSOR_RELAY "|" D_SENSOR_RELAY "_i|" D_SENSOR_LED "|" D_SENSOR_LED "_i|" @@ -230,6 +230,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_KEY1_NP) + MAX_KEYS, AGPIO(GPIO_KEY1_INV) + MAX_KEYS, AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS, + AGPIO(GPIO_KEY1_TC) + MAX_KEYS, AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES, AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays @@ -549,6 +550,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #define MAX_GPIO_PIN 40 // Number of supported GPIO #define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11) #define MAX_USER_PINS 36 // MAX_GPIO_PIN - MIN_FLASH_PINS +// #define MAX_TOUCH_PINS 10 // Number of supported TOUCH PINS #define WEMOS_MODULE 0 // Wemos module // 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839 From fb23aa41c28e7249eb4da207b925bb850192db31 Mon Sep 17 00:00:00 2001 From: Staars Date: Wed, 27 May 2020 16:52:44 +0200 Subject: [PATCH 109/581] do not break gpio configs --- tasmota/tasmota_template_ESP32.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 3b5ad9120..7d47b0409 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -44,7 +44,7 @@ enum UserSelectablePins { GPIO_NONE, // Not used - GPIO_KEY1, GPIO_KEY1_NP, GPIO_KEY1_INV, GPIO_KEY1_INV_NP, GPIO_KEY1_TC, // 4 x Button + Touch + GPIO_KEY1, GPIO_KEY1_NP, GPIO_KEY1_INV, GPIO_KEY1_INV_NP, // 4 x Button GPIO_SWT1, GPIO_SWT1_NP, // 8 x User connected external switches GPIO_REL1, GPIO_REL1_INV, // 8 x Relays GPIO_LED1, GPIO_LED1_INV, // 4 x Leds @@ -127,6 +127,7 @@ enum UserSelectablePins { GPIO_WEBCAM_PSRCS, GPIO_BOILER_OT_RX, GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin GPIO_WINDMETER_SPEED, // WindMeter speed counter pin + GPIO_KEY1_TC, // Touch pin as button GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -138,7 +139,7 @@ enum ProgramSelectablePins { // Text in webpage Module Parameters and commands GPIOS and GPIO const char kSensorNames[] PROGMEM = D_SENSOR_NONE "|" - D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "_n|" D_SENSOR_BUTTON "_i|" D_SENSOR_BUTTON "_in|" D_SENSOR_BUTTON "_tc|" + D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "_n|" D_SENSOR_BUTTON "_i|" D_SENSOR_BUTTON "_in|" D_SENSOR_SWITCH "|" D_SENSOR_SWITCH "_n|" D_SENSOR_RELAY "|" D_SENSOR_RELAY "_i|" D_SENSOR_LED "|" D_SENSOR_LED "_i|" @@ -215,7 +216,7 @@ const char kSensorNames[] PROGMEM = D_GPIO_WEBCAM_HSD "|" D_GPIO_WEBCAM_PSRCS "|" D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" - D_SENSOR_WINDMETER_SPEED + D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BUTTON "_tc" ; const char kSensorNamesFixed[] PROGMEM = @@ -230,7 +231,6 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_KEY1_NP) + MAX_KEYS, AGPIO(GPIO_KEY1_INV) + MAX_KEYS, AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS, - AGPIO(GPIO_KEY1_TC) + MAX_KEYS, AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES, AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays @@ -543,6 +543,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD, AGPIO(GPIO_WEBCAM_PSRCS), #endif + AGPIO(GPIO_KEY1_TC) + MAX_KEYS }; //******************************************************************************************** @@ -550,7 +551,6 @@ const uint16_t kGpioNiceList[] PROGMEM = { #define MAX_GPIO_PIN 40 // Number of supported GPIO #define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11) #define MAX_USER_PINS 36 // MAX_GPIO_PIN - MIN_FLASH_PINS -// #define MAX_TOUCH_PINS 10 // Number of supported TOUCH PINS #define WEMOS_MODULE 0 // Wemos module // 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839 From 3a1155f2b63c8bfca93040fc91e890e00c3a006f Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 27 May 2020 19:42:43 +0200 Subject: [PATCH 110/581] reduce footprint of multicast udp listener --- lib/UdpListener/library.properties | 7 + lib/UdpListener/src/UdpListener.h | 207 +++++++++++++++++++++++++++++ tasmota/support_udp.ino | 58 +++++--- 3 files changed, 255 insertions(+), 17 deletions(-) create mode 100644 lib/UdpListener/library.properties create mode 100644 lib/UdpListener/src/UdpListener.h diff --git a/lib/UdpListener/library.properties b/lib/UdpListener/library.properties new file mode 100644 index 000000000..1d453bc6c --- /dev/null +++ b/lib/UdpListener/library.properties @@ -0,0 +1,7 @@ +name=UdpListener +version=1.0 +author=Ivan Grokhotkov, Stephan Hadinger +maintainer=Stephan +sentence=UdpListener optimized for static and limite memory allocation, to reduce memory footprint of receiving SSDP request, as a replacement for WifiUdp. +paragraph=This class only handles receiving UDP Multicast packets. For sending packets, use WifiUdp. +architectures=esp8266 diff --git a/lib/UdpListener/src/UdpListener.h b/lib/UdpListener/src/UdpListener.h new file mode 100644 index 000000000..90cacff1e --- /dev/null +++ b/lib/UdpListener/src/UdpListener.h @@ -0,0 +1,207 @@ +/* + UdpListener.h - webserver for Tasmota + + Copyright (C) 2020 Theo Arends & Stephan Hadinger + + 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 .@ +*/ + +// adapted from: +/* + UdpContext.h - UDP connection handling on top of lwIP + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + * This is a stripped down version of Udp handler to avoid overflowing + * memory when lots of multicast SSDP packets arrive. + * The pbuf is freed immediately upon arrival of the packet. + * + * Packet data are kept in a statically area in RAM and keeps + * only the first bytes (200 by default) of each packet. + * The number of packets treated is limited (3 by default), any + * new packet arriving is dropped. + * + * This class does only receiving multicast packets for LWIP2 +*/ + +#ifndef UDPMULTICASTLISTENER_H +#define UDPMULTICASTLISTENER_H + +// #include + +extern "C" { +#include +#include +} + +template +struct UdpPacket { + IPAddress srcaddr; + IPAddress dstaddr; + int16_t srcport; + netif* input_netif; + size_t len; + uint8_t buf[PACKET_SIZE]; +}; + +template +class UdpListener +{ +public: + + typedef std::function rxhandler_t; + + UdpListener(size_t packet_number) + : _pcb(0) + , _packet_number(packet_number) + , _buffers(nullptr) + , _udp_packets(0) + , _udp_ready(false) + , _udp_index(0) + { + _packet_number = packet_number; + _buffers = new UdpPacket[_packet_number]; + _pcb = udp_new(); + } + + ~UdpListener() + { + udp_remove(_pcb); + _pcb = 0; + delete[] _buffers; + _buffers = nullptr; + } + + void reset(void) + { + _udp_packets = 0; + _udp_index = 0; + } + + bool listen(const IPAddress& addr, uint16_t port) + { + if (!_buffers) { return false; } + udp_recv(_pcb, &_s_recv, (void *) this); + err_t err = udp_bind(_pcb, addr, port); + return err == ERR_OK; + } + + void disconnect() + { + udp_disconnect(_pcb); + } + + bool next() + { + if (!_buffers) { return false; } + if (_udp_packets > 0) { + if (!_udp_ready) { + // we just consume the first packet + _udp_ready = true; + } else { + _udp_packets--; + _udp_index = (_udp_index + 1) % _packet_number; // advance to next buffer index in ring + if (_udp_packets == 0) { + _udp_ready = false; + } + } + } else { + _udp_ready = false; + } + return _udp_ready; + } + + UdpPacket * read(void) + { + if (!_buffers) { return nullptr; } + if (_udp_ready) { // we have a packet ready to consume + return &_buffers[_udp_index]; + } else { + return nullptr; + } + } + +private: + + void _recv(udp_pcb *upcb, pbuf *pb, + const ip_addr_t *srcaddr, u16_t srcport) + { + if (!_buffers) { pbuf_free(pb); return; } + // Serial.printf(">>> _recv: _udp_packets = %d, _udp_index = %d, tot_len = %d\n", _udp_packets, _udp_index, pb->tot_len); + if (_udp_packets >= _packet_number) { + // we don't have slots anymore, drop packet + pbuf_free(pb); + return; + } + + uint8_t next_slot = (_udp_index + _udp_packets) % _packet_number; + + size_t packet_len = pb->tot_len; + if (packet_len > PACKET_SIZE) { packet_len = PACKET_SIZE; } + + uint8_t * dst = &_buffers[next_slot].buf[0]; + void* buf = pbuf_get_contiguous(pb, dst, PACKET_SIZE, packet_len, 0); + if (buf) { + + if (buf != dst) + memcpy(dst, buf, packet_len); + _buffers[next_slot].len = packet_len; + + _buffers[next_slot].srcaddr = srcaddr; + _buffers[next_slot].dstaddr = ip_current_dest_addr(); + _buffers[next_slot].srcport = srcport; + _buffers[next_slot].input_netif = ip_current_input_netif(); + _udp_packets++; // we have one packet ready + } + pbuf_free(pb); // free memory immediately + } + + static void _s_recv(void *arg, + udp_pcb *upcb, pbuf *p, + CONST ip_addr_t *srcaddr, u16_t srcport) + { + reinterpret_cast(arg)->_recv(upcb, p, srcaddr, srcport); + } + +private: + udp_pcb* _pcb; + uint8_t _packet_number; + + UdpPacket * _buffers; + + // how many packets are ready. + int8_t _udp_packets; // number of udp packets ready to consume + bool _udp_ready; // is a packet currenlty consumed after a call to next() + // ring buffer ranges from 0..(_packet_number-1) + int8_t _udp_index; // current index in the ring buffer +}; + +#endif //UDPCONTEXTLIGHT_H \ No newline at end of file diff --git a/tasmota/support_udp.ino b/tasmota/support_udp.ino index 451135e6a..e8974d664 100644 --- a/tasmota/support_udp.ino +++ b/tasmota/support_udp.ino @@ -19,10 +19,16 @@ #ifdef USE_EMULATION -#define UDP_BUFFER_SIZE 200 // Max UDP buffer size needed for M-SEARCH message +#ifndef UDP_BUFFER_SIZE +#define UDP_BUFFER_SIZE 120 // Max UDP buffer size needed for M-SEARCH message +#endif +#ifndef UDP_MAX_PACKETS +#define UDP_MAX_PACKETS 3 // we support x more packets than the current one +#endif #define UDP_MSEARCH_SEND_DELAY 1500 // Delay in ms before M-Search response is send #include +#include "UdpListener.h" Ticker TickerMSearch; IPAddress udp_remote_ip; // M-Search remote IP address @@ -31,6 +37,8 @@ uint16_t udp_remote_port; // M-Search remote port bool udp_connected = false; bool udp_response_mutex = false; // M-Search response mutex to control re-entry +UdpListener UdpCtx(UDP_MAX_PACKETS); + /*********************************************************************************************\ * UPNP/SSDP search targets \*********************************************************************************************/ @@ -48,10 +56,14 @@ const char SSDP_ALL[] PROGMEM = "ssdp:all"; bool UdpDisconnect(void) { if (udp_connected) { + // flush any outgoing packet PortUdp.flush(); #ifdef USE_DEVICE_GROUPS + // stop + UdpCtx.stop(); PortUdp.stop(); #else // USE_DEVICE_GROUPS + // stop all WiFiUDP::stopAll(); #endif // !USE_DEVICE_GROUPS AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP D_MULTICAST_DISABLED)); @@ -64,13 +76,19 @@ bool UdpConnect(void) { if (!udp_connected && !restart_flag) { // Simple Service Discovery Protocol (SSDP) - if (PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), 1900)) { - AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED)); - udp_response_mutex = false; - udp_connected = true; - } else { + + UdpCtx.reset(); + if (igmp_joingroup(WiFi.localIP(), IPAddress(239,255,255,250)) == ERR_OK) { // addr 239.255.255.250 + ip_addr_t addr = IPADDR4_INIT(INADDR_ANY); + if (UdpCtx.listen(&addr, 1900)) { // port 1900 + // OK + AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED)); + udp_response_mutex = false; + udp_connected = true; + } + } + if (!udp_connected) { // if connection failed AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_JOIN_FAILED)); - udp_connected = false; } } return udp_connected; @@ -79,14 +97,20 @@ bool UdpConnect(void) void PollUdp(void) { if (udp_connected) { - while (PortUdp.parsePacket()) { - char packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet + // parsePacket + while (UdpCtx.next()) { + // while (PortUdp.parsePacket()) { + UdpPacket *packet; - int len = PortUdp.read(packet_buffer, UDP_BUFFER_SIZE -1); - packet_buffer[len] = 0; + packet = UdpCtx.read(); + if (packet->len >= UDP_BUFFER_SIZE) { + packet->len--; // leave space for NULL terminator + } + packet->buf[packet->len] = 0; // add NULL at the end of the packer + char * packet_buffer = (char*) &packet->buf; - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet (%d)"), len); -// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), packet_buffer); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet (%d)"), packet->len); + // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), packet_buffer); // Simple Service Discovery Protocol (SSDP) if (Settings.flag2.emulation) { @@ -97,11 +121,11 @@ void PollUdp(void) #endif udp_response_mutex = true; - udp_remote_ip = PortUdp.remoteIP(); - udp_remote_port = PortUdp.remotePort(); + udp_remote_ip = packet->srcaddr; + udp_remote_port = packet->srcport; -// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet from %s:%d\n%s"), -// udp_remote_ip.toString().c_str(), udp_remote_port, packet_buffer); + // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet from %s:%d\n%s"), + // udp_remote_ip.toString().c_str(), udp_remote_port, packet_buffer); uint32_t response_delay = UDP_MSEARCH_SEND_DELAY + ((millis() &0x7) * 100); // 1500 - 2200 msec From c65a3dfba7b687dfcec58e020432005eb8e71001 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 27 May 2020 20:48:40 +0200 Subject: [PATCH 111/581] Fix compilation issue --- lib/UdpListener/src/UdpListener.h | 2 +- tasmota/support_udp.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/UdpListener/src/UdpListener.h b/lib/UdpListener/src/UdpListener.h index 90cacff1e..a94787902 100644 --- a/lib/UdpListener/src/UdpListener.h +++ b/lib/UdpListener/src/UdpListener.h @@ -204,4 +204,4 @@ private: int8_t _udp_index; // current index in the ring buffer }; -#endif //UDPCONTEXTLIGHT_H \ No newline at end of file +#endif //UDPMULTICASTLISTENER_H \ No newline at end of file diff --git a/tasmota/support_udp.ino b/tasmota/support_udp.ino index e8974d664..588ad2f2f 100644 --- a/tasmota/support_udp.ino +++ b/tasmota/support_udp.ino @@ -58,9 +58,9 @@ bool UdpDisconnect(void) if (udp_connected) { // flush any outgoing packet PortUdp.flush(); + UdpCtx.disconnect(); #ifdef USE_DEVICE_GROUPS // stop - UdpCtx.stop(); PortUdp.stop(); #else // USE_DEVICE_GROUPS // stop all From 0327c4a5478f31f068090a1075aa3a46e4f62409 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 27 May 2020 23:52:25 +0200 Subject: [PATCH 112/581] Udp fix for ESP32 --- lib/UdpListener/src/UdpListener.h | 2 ++ tasmota/support_udp.ino | 39 ++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/UdpListener/src/UdpListener.h b/lib/UdpListener/src/UdpListener.h index a94787902..a369a5d81 100644 --- a/lib/UdpListener/src/UdpListener.h +++ b/lib/UdpListener/src/UdpListener.h @@ -55,6 +55,7 @@ #ifndef UDPMULTICASTLISTENER_H #define UDPMULTICASTLISTENER_H +#ifdef ESP8266 // #include extern "C" { @@ -204,4 +205,5 @@ private: int8_t _udp_index; // current index in the ring buffer }; +#endif // ESP8266 #endif //UDPMULTICASTLISTENER_H \ No newline at end of file diff --git a/tasmota/support_udp.ino b/tasmota/support_udp.ino index 588ad2f2f..cccb64b4e 100644 --- a/tasmota/support_udp.ino +++ b/tasmota/support_udp.ino @@ -22,13 +22,9 @@ #ifndef UDP_BUFFER_SIZE #define UDP_BUFFER_SIZE 120 // Max UDP buffer size needed for M-SEARCH message #endif -#ifndef UDP_MAX_PACKETS -#define UDP_MAX_PACKETS 3 // we support x more packets than the current one -#endif #define UDP_MSEARCH_SEND_DELAY 1500 // Delay in ms before M-Search response is send #include -#include "UdpListener.h" Ticker TickerMSearch; IPAddress udp_remote_ip; // M-Search remote IP address @@ -37,7 +33,14 @@ uint16_t udp_remote_port; // M-Search remote port bool udp_connected = false; bool udp_response_mutex = false; // M-Search response mutex to control re-entry +#ifdef ESP8266 +#ifndef UDP_MAX_PACKETS +#define UDP_MAX_PACKETS 3 // we support x more packets than the current one +#endif + +#include "UdpListener.h" UdpListener UdpCtx(UDP_MAX_PACKETS); +#endif /*********************************************************************************************\ * UPNP/SSDP search targets @@ -58,7 +61,9 @@ bool UdpDisconnect(void) if (udp_connected) { // flush any outgoing packet PortUdp.flush(); +#ifdef ESP8266 UdpCtx.disconnect(); +#endif #ifdef USE_DEVICE_GROUPS // stop PortUdp.stop(); @@ -76,7 +81,7 @@ bool UdpConnect(void) { if (!udp_connected && !restart_flag) { // Simple Service Discovery Protocol (SSDP) - +#ifdef ESP8266 UdpCtx.reset(); if (igmp_joingroup(WiFi.localIP(), IPAddress(239,255,255,250)) == ERR_OK) { // addr 239.255.255.250 ip_addr_t addr = IPADDR4_INIT(INADDR_ANY); @@ -86,6 +91,12 @@ bool UdpConnect(void) udp_response_mutex = false; udp_connected = true; } +#else // ESP32 + if (PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), 1900)) { + AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED)); + udp_response_mutex = false; + udp_connected = true; +#endif } if (!udp_connected) { // if connection failed AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_JOIN_FAILED)); @@ -97,19 +108,24 @@ bool UdpConnect(void) void PollUdp(void) { if (udp_connected) { - // parsePacket +#ifdef ESP8266 while (UdpCtx.next()) { - // while (PortUdp.parsePacket()) { UdpPacket *packet; - packet = UdpCtx.read(); if (packet->len >= UDP_BUFFER_SIZE) { packet->len--; // leave space for NULL terminator } packet->buf[packet->len] = 0; // add NULL at the end of the packer char * packet_buffer = (char*) &packet->buf; + int32_t len = packet->len; +#else // ESP32 + while (PortUdp.parsePacket()) { + char packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet (%d)"), packet->len); + int32_t len = PortUdp.read(packet_buffer, UDP_BUFFER_SIZE -1); + packet_buffer[len] = 0; +#endif + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet (%d)"), len); // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), packet_buffer); // Simple Service Discovery Protocol (SSDP) @@ -121,8 +137,13 @@ void PollUdp(void) #endif udp_response_mutex = true; +#ifdef ESP8266 udp_remote_ip = packet->srcaddr; udp_remote_port = packet->srcport; +#else + udp_remote_ip = PortUdp.remoteIP(); + udp_remote_port = PortUdp.remotePort(); +#endif // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet from %s:%d\n%s"), // udp_remote_ip.toString().c_str(), udp_remote_port, packet_buffer); From ea482721351f92ce8eb036cfbd98a6b8bf3e95fc Mon Sep 17 00:00:00 2001 From: Staars Date: Thu, 28 May 2020 09:57:42 +0200 Subject: [PATCH 113/581] make NimBLEDevice::initialized static --- libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp b/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp index 1540f6327..1695a5177 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp @@ -40,7 +40,7 @@ static const char* LOG_TAG = "NimBLEDevice"; /** * Singletons for the NimBLEDevice. */ -bool initialized = false; +static bool initialized = false; #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) NimBLEScan* NimBLEDevice::m_pScan = nullptr; #endif From d5e7384704cb72e548460219f7dcd4d27c069765 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 28 May 2020 11:55:27 +0200 Subject: [PATCH 114/581] add flash syntax --- tools/Esptool/ESP32/readme.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/Esptool/ESP32/readme.txt b/tools/Esptool/ESP32/readme.txt index b0730aaff..2d09d6faa 100644 --- a/tools/Esptool/ESP32/readme.txt +++ b/tools/Esptool/ESP32/readme.txt @@ -1 +1,5 @@ This files are needed for flashing Tasmota with esptool.py to a ESP32 + +Command syntax for flashing Tasmota32 firmware on ESP32 via Esptool (replace COM Port Number!): + +esptool.py --chip esp32 --port COM5 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 bootloader_dout_40m.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 tasmota32.bin From 8e95a679848655536c4440b278ed95ba9376bfc8 Mon Sep 17 00:00:00 2001 From: blakadder Date: Thu, 28 May 2020 16:38:52 +0200 Subject: [PATCH 115/581] Update readme.txt --- tools/Esptool/ESP32/readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Esptool/ESP32/readme.txt b/tools/Esptool/ESP32/readme.txt index 2d09d6faa..bdedc87de 100644 --- a/tools/Esptool/ESP32/readme.txt +++ b/tools/Esptool/ESP32/readme.txt @@ -1,4 +1,4 @@ -This files are needed for flashing Tasmota with esptool.py to a ESP32 +These files are needed for flashing Tasmota32 with esptool.py to an ESP32. Command syntax for flashing Tasmota32 firmware on ESP32 via Esptool (replace COM Port Number!): From 357341899c624597d616dcf99045be6c4941043b Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Fri, 29 May 2020 19:29:03 +0200 Subject: [PATCH 116/581] ILI9488 ESP32 --- lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp | 232 ++++++++---------- platformio_override_sample.ini | 2 +- tasmota/tasmota_globals.h | 4 +- tasmota/xdsp_08_ILI9488.ino | 25 +- tasmota/xdsp_10_RA8876.ino | 3 + 5 files changed, 132 insertions(+), 134 deletions(-) diff --git a/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp b/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp index 3e0aca9ee..e507fdf1b 100644 --- a/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp +++ b/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp @@ -19,7 +19,7 @@ #include // if using software spi this optimizes the code -#define SWSPI_OPTMODE + #define ILI9488_START start(); #define ILI9488_STOP stop(); @@ -37,9 +37,6 @@ ILI9488::ILI9488(int8_t cs,int8_t mosi,int8_t sclk,int8_t bp) : Renderer(ILI9488 _hwspi = 0; } - -#include "spi_register.h" - /* CPU Clock = 80 Mhz @@ -73,6 +70,10 @@ GPIO15: PERIPHS_IO_MUX_MTDO_U uint8_t ili9488_start; +#ifndef ESP32 +// ESP8266 +#include "spi_register.h" +#define SWSPI_OPTMODE uint32_t ili9488_clock; uint32_t ili9488_usr; uint32_t ili9488_usr1; @@ -192,32 +193,6 @@ void ILI9488::stop(void) { ili9488_start=0; } - -#if 0 -// code from espressif SDK -/****************************************************************************** - * FunctionName : spi_lcd_9bit_write - * Description : SPI 9bits transmission function for driving LCD TM035PDZV36 - * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid - * uint8 high_bit - first high bit of the data, 0 is for "0",the other value 1-255 is for "1" - * uint8 low_8bit- the rest 8bits of the data. -*******************************************************************************/ -void spi_lcd_9bit_write(uint8_t high_bit,uint8_t low_8bit) -{ - uint32_t regvalue; - uint8_t bytetemp; - - if(high_bit) bytetemp=(low_8bit>>1)|0x80; - else bytetemp=(low_8bit>>1)&0x7f; - - regvalue= ((8&SPI_USR_COMMAND_BITLEN)<>= 1) { + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); + if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); + else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); } + WRITE_PERI_REG( PIN_OUT_SET, 1<<_cs); } -*/ +#else +// ESP32 section +void ILI9488::writedata(uint8_t d) { + fastSPIwrite(d,1); +} + +void ILI9488::writecommand(uint8_t c) { + fastSPIwrite(c,0); +} + +#include "soc/spi_reg.h" +#include "soc/spi_struct.h" +#include "esp32-hal-spi.h" +#include "esp32-hal.h" +#include "soc/spi_struct.h" + +// since ardunio transferBits ia completely disfunctional +// we use our own hardware driver for 9 bit spi +void ILI9488::fastSPIwrite(uint8_t d,uint8_t dc) { + digitalWrite( _cs, LOW); + + uint32_t regvalue=d>>1; + if (dc) regvalue|=0x80; + else regvalue&=0x7f; + if (d&1) regvalue|=0x8000; + + REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); + REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1); + uint32_t *dp=(uint32_t*)SPI_W0_REG(3); + *dp=regvalue; + REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + + digitalWrite( _cs, HIGH); +} + +SPISettings ili9488_spiSettings; + +void ILI9488::start(void) { + if (ili9488_start) return; + SPI.beginTransaction(ili9488_spiSettings); + ili9488_start=1; +} +void ILI9488::stop(void) { + if (!ili9488_start) return; + SPI.endTransaction(); + ili9488_start=0; +} +#endif + uint16_t ILI9488::GetColorFromIndex(uint8_t index) { if (index>=sizeof(ili9488_colors)/2) index=0; @@ -339,14 +344,23 @@ void ILI9488::begin(void) { pinMode(_bp, OUTPUT); digitalWrite(_bp,HIGH); } + +#ifndef ESP32 if ((_sclk==14) && (_mosi==13) && (_cs==15)) { // we use hardware spi + SPI.begin(); _hwspi=1; spi_lcd_mode_init(); } else { // we must use software spi _hwspi=0; } +#else + SPI.begin(_sclk,-1,_mosi, -1); + ili9488_spiSettings = SPISettings(10000000, MSBFIRST, SPI_MODE3); + _hwspi=1; +#endif + ILI9488_START delay(1); @@ -844,9 +858,9 @@ uint32_t pack_rgb(uint32_t r, uint32_t g, uint32_t b) { return ulswap(data); } +#ifndef ESP32 // fill a rectangle -void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { +void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { ILI9488_START // rudimentary clipping (drawChar w/big text requires this) @@ -990,7 +1004,35 @@ void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, #endif } +#else +// ESP32 +void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { + // rudimentary clipping (drawChar w/big text requires this) + if((x >= _width) || (y >= _height)) return; + if((x + w - 1) >= _width) w = _width - x; + if((y + h - 1) >= _height) h = _height - y; + + setAddrWindow(x, y, x+w-1, y+h-1); + + uint8_t r = (color & 0xF800) >> 11; + uint8_t g = (color & 0x07E0) >> 5; + uint8_t b = color & 0x001F; + + r = (r * 255) / 31; + g = (g * 255) / 63; + b = (b * 255) / 31; + + for(y=h; y>0; y--) { + for(x=w; x>0; x--) { + writedata(r); + writedata(g); + writedata(b); + } + } + ILI9488_STOP +} +#endif // Pass 8-bit (each) R,G,B, get back 16-bit packed color uint16_t ILI9488::color565(uint8_t r, uint8_t g, uint8_t b) { @@ -1040,65 +1082,3 @@ void ILI9488::invertDisplay(boolean i) { writecommand(i ? ILI9488_INVON : ILI9488_INVOFF); ILI9488_STOP } - -void ICACHE_RAM_ATTR ILI9488::fastSPIwrite(uint8_t d,uint8_t dc) { - - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_cs); - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); - if(dc) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); - else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); - WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); - - for(uint8_t bit = 0x80; bit; bit >>= 1) { - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); - if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); - else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); - WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); - } - WRITE_PERI_REG( PIN_OUT_SET, 1<<_cs); -} - -/* - - uint16_t ILI9488::readcommand16(uint8_t c) { - digitalWrite(_dc, LOW); - if (_cs) - digitalWrite(_cs, LOW); - - spiwrite(c); - pinMode(_sid, INPUT); // input! - uint16_t r = spiread(); - r <<= 8; - r |= spiread(); - if (_cs) - digitalWrite(_cs, HIGH); - - pinMode(_sid, OUTPUT); // back to output - return r; - } - - uint32_t ILI9488::readcommand32(uint8_t c) { - digitalWrite(_dc, LOW); - if (_cs) - digitalWrite(_cs, LOW); - spiwrite(c); - pinMode(_sid, INPUT); // input! - - dummyclock(); - dummyclock(); - - uint32_t r = spiread(); - r <<= 8; - r |= spiread(); - r <<= 8; - r |= spiread(); - r <<= 8; - r |= spiread(); - if (_cs) - digitalWrite(_cs, HIGH); - - pinMode(_sid, OUTPUT); // back to output - return r; - } - - */ diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 695973c2e..22256f679 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -192,6 +192,6 @@ lib_extra_dirs = libesp32 lib_ignore = - ILI9488 + ; ILI9488 ; SSD3115 cc1101 diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 37e39e451..44826fa64 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -300,7 +300,7 @@ const char kWebColors[] PROGMEM = #undef USE_HM10 // Disable support for HM-10 as a BLE-bridge as an alternative is using the internal ESP32 BLE #undef USE_KEELOQ // Disable support for Jarolift rollers by Keeloq algorithm as it's library cc1101 is not compatible with ESP32 -#undef USE_DISPLAY_ILI9488 // Disable as it's library JaretBurkett_ILI9488-gemu-1.0 is not compatible with ESP32 +//#undef USE_DISPLAY_ILI9488 // Disable as it's library JaretBurkett_ILI9488-gemu-1.0 is not compatible with ESP32 //#undef USE_DISPLAY_SSD1351 // Disable as it's library Adafruit_SSD1351_gemu-1.0 is not compatible with ESP32 #endif // ESP32 @@ -335,7 +335,7 @@ const char kWebColors[] PROGMEM = #ifdef USE_DEVICE_GROUPS #define SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, ...) _SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, __VA_ARGS__, 0) #define SendLocalDeviceGroupMessage(REQUEST_TYPE, ...) _SendDeviceGroupMessage(0, REQUEST_TYPE, __VA_ARGS__, 0) -uint8_t device_group_count = 0; +uint8_t device_group_count = 1; #endif // USE_DEVICE_GROUPS #ifdef DEBUG_TASMOTA_CORE diff --git a/tasmota/xdsp_08_ILI9488.ino b/tasmota/xdsp_08_ILI9488.ino index 1dc877e18..e49e7bffe 100644 --- a/tasmota/xdsp_08_ILI9488.ino +++ b/tasmota/xdsp_08_ILI9488.ino @@ -84,18 +84,33 @@ void ILI9488_InitDriver() bppin=Pin(GPIO_BACKLIGHT); } - // init renderer - if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK)) { - ili9488 = new ILI9488(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK),bppin); +#ifdef ESP32 +#undef HW_SPI_MOSI +#define HW_SPI_MOSI 23 +#undef HW_SPI_MISO +#define HW_SPI_MISO 19 +#undef HW_SPI_CLK +#define HW_SPI_CLK 18 +#else +#undef HW_SPI_MOSI +#define HW_SPI_MOSI 13 +#undef HW_SPI_MISO +#define HW_SPI_MISO 12 +#undef HW_SPI_CLK +#define HW_SPI_CLK 14 +#endif + + // init renderer, must use hardware spi + if (PinUsed(GPIO_SSPI_CS) && (Pin(GPIO_SSPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SSPI_SCLK)==HW_SPI_CLK)) { + ili9488 = new ILI9488(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK),bppin); } else { - if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { + if (PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SPI_CLK)==HW_SPI_CLK)) { ili9488 = new ILI9488(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK),bppin); } else { return; } } - SPI.begin(); ili9488->begin(); renderer = ili9488; renderer->DisplayInit(DISPLAY_INIT_MODE,Settings.display_size,Settings.display_rotate,Settings.display_font); diff --git a/tasmota/xdsp_10_RA8876.ino b/tasmota/xdsp_10_RA8876.ino index 6a44708cb..aa8e82f4d 100644 --- a/tasmota/xdsp_10_RA8876.ino +++ b/tasmota/xdsp_10_RA8876.ino @@ -72,8 +72,11 @@ void RA8876_InitDriver() bg_color = RA8876_BLACK; #ifdef ESP32 +#undef HW_SPI_MOSI #define HW_SPI_MOSI 23 +#undef HW_SPI_MISO #define HW_SPI_MISO 19 +#undef HW_SPI_CLK #define HW_SPI_CLK 18 #else #undef HW_SPI_MOSI From 10e059c3631074895f84d53f8570508f7a8a8665 Mon Sep 17 00:00:00 2001 From: rando-calrissian <37273799+rando-calrissian@users.noreply.github.com> Date: Fri, 29 May 2020 11:18:39 -0700 Subject: [PATCH 117/581] Add files via upload Added the ability to set the displayed temperature units (C/F) for Xiaomi LYWSD02 devices. --- tasmota/xsns_62_MI_ESP32.ino | 471 ++++++++++++++++++++--------------- 1 file changed, 266 insertions(+), 205 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 28c927db9..1844edc2c 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -53,6 +53,8 @@ struct { uint32_t willSetTime:1; uint32_t shallReadBatt:1; uint32_t willReadBatt:1; + uint32_t shallSetUnit:1; + uint32_t willSetUnit:1; } mode; struct { uint8_t sensor; // points to to the number 0...255 @@ -152,7 +154,7 @@ BLEScanResults MI32foundDevices; const char S_JSON_MI32_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%d}"; const char S_JSON_MI32_COMMAND[] PROGMEM = "{\"" D_CMND_MI32 "%s%s\"}"; -const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery"; +const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit"; #define FLORA 1 #define MJ_HT_V1 2 @@ -185,7 +187,8 @@ enum MI32_Commands { // commands useable in console or rules CMND_MI32_PERIOD, // set period like TELE-period in seconds between read-cycles CMND_MI32_TIME, // set LYWSD02-Time from ESP8266-time CMND_MI32_PAGE, // sensor entries per web page, which will be shown alternated - CMND_MI32_BATTERY // read all battery levels + CMND_MI32_BATTERY, // read all battery levels + CMND_MI32_UNIT // toggles the displayed unit between C/F (LYWSD02) }; enum MI32_TASK { @@ -193,6 +196,7 @@ enum MI32_TASK { MI32_TASK_CONN = 1, MI32_TASK_TIME = 2, MI32_TASK_BATT = 3, + MI32_TASK_UNIT = 4, }; /*********************************************************************************************\ @@ -225,26 +229,18 @@ class MI32SensorCallback : public NimBLEClientCallbacks { class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { void onResult(NimBLEAdvertisedDevice* advertisedDevice) { - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); - if (advertisedDevice->getServiceData().length() == 0) { - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); - MI32Scan->erase(advertisedDevice->getAddress()); - return; - } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice.getAddress().toString().c_str(),advertisedDevice.getServiceData().length()); + if (advertisedDevice->getServiceData().length() == 0) return; uint16_t uuid = advertisedDevice->getServiceDataUUID().getNative()->u16.value; - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("UUID: %x"),uuid); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%x"),uuid); uint8_t addr[6]; memcpy(addr,advertisedDevice->getAddress().getNative(),6); MI32_ReverseMAC(addr); if(uuid==0xfe95) { - MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); + MI32ParseResponse((char*)advertisedDevice->getServiceData().c_str(),advertisedDevice->getServiceData().length(), addr); } else if(uuid==0xfdcd) { - MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); - } - else { - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); - MI32Scan->erase(advertisedDevice->getAddress()); + MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().c_str(),advertisedDevice->getServiceData().length(), addr); } }; }; @@ -394,62 +390,56 @@ void MI32StartTask(uint32_t task){ if (MI32.mode.willReadBatt == 1) return; MI32StartBatteryTask(); break; + case MI32_TASK_UNIT: + if (MI32.mode.shallSetUnit == 0) return; + MI32StartUnitTask(); + break; default: break; } } -bool MI32ConnectActiveSensor(){ // only use inside a task !! - MI32.mode.connected = 0; +void MI32ConnectActiveSensor(){ // only use inside a task !! MI32Client = nullptr; - Wifi.counter = Wifi.counter + 20; // hopefully less interference - NimBLEAddress _address = NimBLEAddress(MIBLEsensors[MI32.state.sensor].serial); + esp_bd_addr_t address; + memcpy(address,MIBLEsensors[MI32.state.sensor].serial,sizeof(address)); if(NimBLEDevice::getClientListSize()) { - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: found any clients in the cList"),D_CMND_MI32); - MI32Client = NimBLEDevice::getClientByPeerAddress(_address); + MI32Client = NimBLEDevice::getClientByPeerAddress(NimBLEAddress(address)); if(MI32Client){ - // Should be impossible - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: got connected client"),D_CMND_MI32); + if(!MI32Client->connect(NimBLEAddress(address), 0,false)) { + MI32.mode.willConnect = 0; + vTaskDelete( NULL ); + } } else { - // Should be the norm after the first iteration MI32Client = NimBLEDevice::getDisconnectedClient(); - DEBUG_SENSOR_LOG(PSTR("%s: got disconnected client"),D_CMND_MI32); } } - - if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { - MI32.mode.willConnect = 0; - DEBUG_SENSOR_LOG(PSTR("%s: max connection already reached"),D_CMND_MI32); - return false; - } if(!MI32Client) { - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: will create client"),D_CMND_MI32); + if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { + MI32.mode.willConnect = 0; + vTaskDelete( NULL ); + } MI32Client = NimBLEDevice::createClient(); MI32Client->setClientCallbacks(&MI32SensorCB , false); - MI32Client->setConnectionParams(12,12,0,48); - MI32Client->setConnectTimeout(30); + MI32Client->setConnectionParams(12,12,0,51); + MI32Client->setConnectTimeout(10); + if (!MI32Client->connect(NimBLEAddress(address),0,false)) { + MI32.mode.willConnect = 0; + NimBLEDevice::deleteClient(MI32Client); + vTaskDelete( NULL ); + } } - if (!MI32Client->connect(_address,false)) { - MI32.mode.willConnect = 0; - NimBLEDevice::deleteClient(MI32Client); - DEBUG_SENSOR_LOG(PSTR("%s: did not connect client"),D_CMND_MI32); - return false; - } - DEBUG_SENSOR_LOG(PSTR("%s: did create new client"),D_CMND_MI32); - return true; - // } } void MI32StartScanTask(){ if (MI32.mode.connected) return; MI32.mode.runningScan = 1; - // Wifi.counter = Wifi.counter + 3; xTaskCreatePinnedToCore( MI32ScanTask, /* Function to implement the task */ "MI32ScanTask", /* Name of the task */ - 8192, /* Stack size in words */ + 4096, /* Stack size in words */ NULL, /* Task input parameter */ 0, /* Priority of the task */ NULL, /* Task handle. */ @@ -458,18 +448,17 @@ void MI32StartScanTask(){ } void MI32ScanTask(void *pvParameters){ - if (MI32Scan == nullptr) MI32Scan = NimBLEDevice::getScan(); - DEBUG_SENSOR_LOG(PSTR("%s: Scan Cache Length: %u"),D_CMND_MI32, MI32Scan->getResults().getCount()); - MI32Scan->setAdvertisedDeviceCallbacks(&MI32ScanCallbacks); - MI32Scan->setActiveScan(false); - MI32Scan->start(5, MI32scanEndedCB, true); // hard coded duration + NimBLEScan* pScan = NimBLEDevice::getScan(); + pScan->setAdvertisedDeviceCallbacks(&MI32ScanCallbacks); + pScan->setActiveScan(false); + pScan->start(5, MI32scanEndedCB); // hard coded duration uint32_t timer = 0; while (MI32.mode.runningScan){ if (timer>15){ vTaskDelete( NULL ); } timer++; - vTaskDelay(1000/ portTICK_PERIOD_MS); + vTaskDelay(1000); } vTaskDelete( NULL ); } @@ -493,62 +482,47 @@ void MI32SensorTask(void *pvParameters){ MI32.mode.willConnect = 0; vTaskDelete( NULL ); } - if (MI32ConnectActiveSensor()){ - uint32_t timer = 0; - while (MI32.mode.connected == 0){ - if (timer>1000){ - MI32Client->disconnect(); - NimBLEDevice::deleteClient(MI32Client); - MI32.mode.willConnect = 0; - vTaskDelay(100/ portTICK_PERIOD_MS); - vTaskDelete( NULL ); - } - timer++; - vTaskDelay(10/ portTICK_PERIOD_MS); - } - - timer = 150; - switch(MIBLEsensors[MI32.state.sensor].type){ - case LYWSD03MMC: - MI32.mode.readingDone = 0; - if(MI32connectLYWSD03forNotification()) timer=0; - break; - default: + MI32ConnectActiveSensor(); + MI32.mode.readingDone = 1; + switch(MIBLEsensors[MI32.state.sensor].type){ + case LYWSD03MMC: + MI32.mode.readingDone = 0; + MI32connectLYWSD03(); + break; + default: + break; + } + uint32_t timer = 0; + while (!MI32.mode.readingDone){ + if (timer>150){ break; } - - while (!MI32.mode.readingDone){ - if (timer>150){ - break; - } - timer++; - vTaskDelay(100/ portTICK_PERIOD_MS); - } - MI32Client->disconnect(); - DEBUG_SENSOR_LOG(PSTR("%s: requested disconnect"),D_CMND_MI32); + timer++; + vTaskDelay(100); } - vTaskDelay(500/ portTICK_PERIOD_MS); + MI32Client->disconnect(); + NimBLEDevice::deleteClient(MI32Client); + vTaskDelay(500); MI32.mode.connected = 0; vTaskDelete( NULL ); } -bool MI32connectLYWSD03forNotification(){ +void MI32connectLYWSD03(){ NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID serviceUUID(0xebe0ccb0,0x7a0a,0x4b0c,0x8a1a6ff2997da3a6); - static BLEUUID charUUID(0xebe0ccc1,0x7a0a,0x4b0c,0x8a1a6ff2997da3a6); + static BLEUUID serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"); + static BLEUUID charUUID("ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6"); pSvc = MI32Client->getService(serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(charUUID); } - if (pChr){ - if(pChr->canNotify()) { - if(pChr->registerForNotify(MI32notifyCB)) { - return true; - } + if(pChr->canNotify()) { + if(!pChr->registerForNotify(MI32notifyCB)) { + MI32.mode.willConnect = 0; + MI32Client->disconnect(); + return; } } - return false; } void MI32StartTimeTask(){ @@ -570,57 +544,123 @@ void MI32TimeTask(void *pvParameters){ MI32.mode.shallSetTime = 0; vTaskDelete( NULL ); } + MI32ConnectActiveSensor(); - if(MI32ConnectActiveSensor()){ - uint32_t timer = 0; - while (MI32.mode.connected == 0){ - if (timer>1000){ - break; - } - timer++; - vTaskDelay(10/ portTICK_PERIOD_MS); + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; } - - NimBLERemoteService* pSvc = nullptr; - NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); - static BLEUUID charUUID(0xEBE0CCB7,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); - pSvc = MI32Client->getService(serviceUUID); - if(pSvc) { - pChr = pSvc->getCharacteristic(charUUID); - + timer++; + vTaskDelay(10); } - if (pChr){ - if(pChr->canWrite()) { - union { - uint8_t buf[5]; - uint32_t time; - } _utc; - _utc.time = Rtc.utc_time; - _utc.buf[4] = Rtc.time_timezone / 60; - if(!pChr->writeValue(_utc.buf,sizeof(_utc.buf),true)) { // true is important ! - MI32.mode.willConnect = 0; - MI32Client->disconnect(); - } - else { - MI32.mode.shallSetTime = 0; - MI32.mode.willSetTime = 0; - } - } - } - MI32Client->disconnect(); + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); + static BLEUUID charUUID("EBE0CCB7-7A0A-4B0C-8A1A-6FF2997DA3A6"); + pSvc = MI32Client->getService(serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(charUUID); } - vTaskDelay(500/ portTICK_PERIOD_MS); + if(pChr->canWrite()) { + union { + uint8_t buf[5]; + uint32_t time; + } _utc; + _utc.time = Rtc.utc_time; + _utc.buf[4] = Rtc.time_timezone / 60; + + if(!pChr->writeValue(_utc.buf,sizeof(_utc.buf),true)) { // true is important ! + MI32.mode.willConnect = 0; + MI32Client->disconnect(); + } + else { + MI32.mode.shallSetTime = 0; + MI32.mode.willSetTime = 0; + } + } + MI32Client->disconnect(); + NimBLEDevice::deleteClient(MI32Client); + vTaskDelay(500); MI32.mode.connected = 0; vTaskDelete( NULL ); } +void MI32StartUnitTask(){ + MI32.mode.willConnect = 1; + xTaskCreatePinnedToCore( + MI32UnitTask, /* Function to implement the task */ + "MI32UnitTask", /* Name of the task */ + 8912, /* Stack size in words */ + NULL, /* Task input parameter */ + 15, /* Priority of the task */ + NULL, /* Task handle. */ + 0); /* Core where the task should run */ + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Start unit set"),D_CMND_MI32); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: with sensor: %u"),D_CMND_MI32, MI32.state.sensor); +} + +void MI32UnitTask(void *pvParameters){ + if (MIBLEsensors[MI32.state.sensor].type != LYWSD02) { + MI32.mode.shallSetUnit = 0; + vTaskDelete( NULL ); + } + MI32ConnectActiveSensor(); + + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(10); + } + + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); + static BLEUUID charUUID("EBE0CCBE-7A0A-4B0C-8A1A-6FF2997DA3A6"); + pSvc = MI32Client->getService(serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(charUUID); + } + + uint8_t curUnit; + + if(pChr->canRead()) { + const char *buf = pChr->readValue().c_str(); + if( buf[0] != 0 && buf[0]<101 ){ + curUnit = buf[0]; + } + } + else { + return; + } + + if(pChr->canWrite()) { + curUnit = curUnit == 0x01?0xFF:0x01; // C/F + + if(!pChr->writeValue(&curUnit,sizeof(curUnit),true)) { // true is important ! + MI32.mode.willConnect = 0; + MI32Client->disconnect(); + } + else { + MI32.mode.shallSetUnit = 0; + MI32.mode.willSetUnit = 0; + } + } + MI32Client->disconnect(); + NimBLEDevice::deleteClient(MI32Client); + vTaskDelay(500); + MI32.mode.connected = 0; + vTaskDelete( NULL ); +} + + void MI32StartBatteryTask(){ if (MI32.mode.connected) return; MI32.mode.willReadBatt = 1; - MI32.mode.willConnect = 1; - MI32.mode.canScan = 0; xTaskCreatePinnedToCore( MI32BatteryTask, /* Function to implement the task */ "MI32BatteryTask", /* Name of the task */ @@ -644,32 +684,31 @@ void MI32BatteryTask(void *pvParameters){ } MI32.mode.connected = 0; - if(MI32ConnectActiveSensor()){ - uint32_t timer = 0; - while (MI32.mode.connected == 0){ - if (timer>1000){ - break; - } - timer++; - vTaskDelay(30/ portTICK_PERIOD_MS); - } - - switch(MIBLEsensors[MI32.state.sensor].type){ - case FLORA: - MI32batteryFLORA(); - break; - case LYWSD02: - MI32batteryLYWSD02(); - break; - case CGD1: - MI32batteryCGD1(); + MI32ConnectActiveSensor(); + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ break; } - MI32Client->disconnect(); - } + timer++; + vTaskDelay(10); + } + + switch(MIBLEsensors[MI32.state.sensor].type){ + case FLORA: + MI32batteryFLORA(); + break; + case LYWSD02: + MI32batteryLYWSD02(); + break; + case CGD1: + MI32batteryCGD1(); + break; + } + MI32Client->disconnect(); MI32.mode.willReadBatt = 0; - // Wifi.counter = 0; // Now check it - vTaskDelay(500/ portTICK_PERIOD_MS); + NimBLEDevice::deleteClient(MI32Client); + vTaskDelay(500); MI32.mode.connected = 0; vTaskDelete( NULL ); } @@ -681,26 +720,27 @@ void MI32batteryFLORA(){ break; } timer++; - vTaskDelay(10/ portTICK_PERIOD_MS); + vTaskDelay(10); } - DEBUG_SENSOR_LOG(PSTR("%s connected for battery"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s connected for battery"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID FLserviceUUID(0x00001204,0x0000,0x1000,0x800000805f9b34fb); - static BLEUUID FLcharUUID(0x00001a02,0x0000,0x1000,0x800000805f9b34fb); + static BLEUUID FLserviceUUID("00001204-0000-1000-8000-00805f9b34fb"); + static BLEUUID FLcharUUID("00001a02-0000-1000-8000-00805f9b34fb"); pSvc = MI32Client->getService(FLserviceUUID); - if(pSvc) { + if(pSvc) { /** make sure it's not null */ pChr = pSvc->getCharacteristic(FLcharUUID); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: got Flora char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); } - if (pChr){ - DEBUG_SENSOR_LOG(PSTR("%s: got Flora char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); - if(pChr->canRead()) { - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); - } + else { + MI32.mode.readingDone = 1; + return; + } + if(pChr->canRead()) { + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); } - MI32.mode.readingDone = 1; } void MI32batteryLYWSD02(){ @@ -710,27 +750,27 @@ void MI32batteryLYWSD02(){ break; } timer++; - vTaskDelay(10/ portTICK_PERIOD_MS); + vTaskDelay(10); } NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID LY2serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); - static BLEUUID LY2charUUID(0xEBE0CCC4,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + static BLEUUID LY2serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); + static BLEUUID LY2charUUID("EBE0CCC4-7A0A-4B0C-8A1A-6FF2997DA3A6"); pSvc = MI32Client->getService(LY2serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(LY2charUUID); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: got LYWSD02 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); } - if (pChr){ - DEBUG_SENSOR_LOG( PSTR("%s: got LYWSD02 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); - if(pChr->canRead()) { - DEBUG_SENSOR_LOG(PSTR("LYWSD02 char")); - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); - } + else { + return; + } + if(pChr->canRead()) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("LYWSD02 char")); + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); } - MI32.mode.readingDone = 1; } void MI32batteryCGD1(){ @@ -740,26 +780,26 @@ void MI32batteryCGD1(){ break; } timer++; - vTaskDelay(10/ portTICK_PERIOD_MS); + vTaskDelay(10); } NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID CGD1serviceUUID((uint16_t)0x180F); - static BLEUUID CGD1charUUID((uint16_t)0x2A19); + static BLEUUID CGD1serviceUUID("180F"); + static BLEUUID CGD1charUUID("2A19"); pSvc = MI32Client->getService(CGD1serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(CGD1charUUID); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: got CGD1 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); } - if (pChr){ - DEBUG_SENSOR_LOG(PSTR("%s: got CGD1 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); - if(pChr->canRead()) { - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); - } + else { + return; + } + if(pChr->canRead()) { + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); } - MI32.mode.readingDone = 1; } @@ -779,14 +819,14 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ } MI32_ReverseMAC(_beacon.Mac); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); + DEBUG_SENSOR_LOG(PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + DEBUG_SENSOR_LOG(PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); if(MIBLEsensors[_slot].type==4 || MIBLEsensors[_slot].type==6){ DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type); return; } - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32SlaveType[MIBLEsensors[_slot].type-1],_slot); + DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kMI32SlaveType[MIBLEsensors[_slot].type-1],_slot); switch(_beacon.type){ case 0x04: _tempFloat=(float)(_beacon.temp)/10.0f; @@ -794,7 +834,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].temp=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); + DEBUG_SENSOR_LOG(PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); break; case 0x06: _tempFloat=(float)(_beacon.hum)/10.0f; @@ -802,11 +842,11 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].hum=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _beacon.hum); + DEBUG_SENSOR_LOG(PSTR("Mode 6: U16: %u Hum"), _beacon.hum); break; case 0x07: MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff; - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); + DEBUG_SENSOR_LOG(PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); break; case 0x08: _tempFloat =(float)_beacon.moist; @@ -814,7 +854,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].moisture=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); + DEBUG_SENSOR_LOG(PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); break; case 0x09: _tempFloat=(float)(_beacon.fert); @@ -822,14 +862,14 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].fertility=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); + DEBUG_SENSOR_LOG(PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); break; case 0x0a: if(_beacon.bat<101){ MIBLEsensors[_slot].bat = _beacon.bat; DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode a: U8: %u %%"), _beacon.bat); + DEBUG_SENSOR_LOG(PSTR("Mode a: U8: %u %%"), _beacon.bat); break; case 0x0d: _tempFloat=(float)(_beacon.HT.temp)/10.0f; @@ -842,7 +882,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated")); } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); + DEBUG_SENSOR_LOG(PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); break; } } @@ -950,8 +990,6 @@ void MI32EverySecond(bool restart){ _counter = 0; MI32.mode.canScan = 0; MI32.mode.canConnect = 1; - MI32.mode.willReadBatt = 0; - MI32.mode.willConnect = 0; return; } @@ -964,6 +1002,15 @@ void MI32EverySecond(bool restart){ } } + if (MI32.mode.shallSetUnit) { + MI32.mode.canScan = 0; + MI32.mode.canConnect = 0; + if (MI32.mode.willSetUnit == 0){ + MI32.mode.willSetUnit = 1; + MI32StartTask(MI32_TASK_UNIT); + } + } + if (MI32.mode.willReadBatt) return; if (_counter>MI32.period) { @@ -981,9 +1028,9 @@ void MI32EverySecond(bool restart){ if(_counter==0) { MI32.state.sensor = _nextSensorSlot; - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u of %u"),D_CMND_MI32, MI32.state.sensor, MIBLEsensors.size()-1); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u"),D_CMND_MI32, MI32.state.sensor); MI32.mode.canScan = 0; - if (MI32.mode.runningScan|| MI32.mode.connected || MI32.mode.willConnect) return; + if (MI32.mode.runningScan == 1 || MI32.mode.connected == 1) return; _nextSensorSlot++; MI32.mode.canConnect = 1; if(MI32.mode.connected == 0) { @@ -997,7 +1044,7 @@ void MI32EverySecond(bool restart){ } } - if (_nextSensorSlot>(MIBLEsensors.size()-1)) { + if (MI32.state.sensor==MIBLEsensors.size()-1) { _nextSensorSlot= 0; _counter++; if (MI32.mode.shallReadBatt){ @@ -1057,6 +1104,21 @@ bool MI32Cmd(void) { } Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload); break; + case CMND_MI32_UNIT: + if (XdrvMailbox.data_len > 0) { + if(MIBLEsensors.size()>XdrvMailbox.payload){ + if(MIBLEsensors[XdrvMailbox.payload].type == LYWSD02){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: will set Unit"),D_CMND_MI32); + MI32.state.sensor = XdrvMailbox.payload; + MI32.mode.canScan = 0; + MI32.mode.canConnect = 0; + MI32.mode.shallSetUnit = 1; + MI32.mode.willSetUnit = 0; + } + } + } + Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload); + break; case CMND_MI32_PAGE: if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.payload == 0) XdrvMailbox.payload = MI32.perPage; // ignore 0 @@ -1097,7 +1159,6 @@ const char HTTP_MI32_HL[] PROGMEM = "{s}
{m}
{e}"; void MI32Show(bool json) { - if (json) { for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { /* @@ -1111,7 +1172,7 @@ void MI32Show(bool json) MIBLEsensors[i].serial[3], MIBLEsensors[i].serial[4], MIBLEsensors[i].serial[5]); if (MIBLEsensors[i].type == FLORA) { - if (!isnan(MIBLEsensors[i].temp)) { + if (!isnan(MIBLEsensors[i].temp)) { // this is the error code -> no temperature char temperature[FLOATSZ]; // all sensors have temperature dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), temperature); @@ -1238,4 +1299,4 @@ bool Xsns62(uint8_t function) return result; } #endif // USE_MI_ESP32 -#endif // ESP32 \ No newline at end of file +#endif // ESP32 From 671942aa60a241868ca48c98593ed836eb33b2f8 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Fri, 29 May 2020 20:54:15 +0200 Subject: [PATCH 118/581] faster ili9488 fill --- lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp b/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp index e507fdf1b..495c18ad8 100644 --- a/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp +++ b/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp @@ -74,6 +74,9 @@ uint8_t ili9488_start; // ESP8266 #include "spi_register.h" #define SWSPI_OPTMODE +// this enables the 27 bit packed mode +#define RGB_PACK_MODE + uint32_t ili9488_clock; uint32_t ili9488_usr; uint32_t ili9488_usr1; @@ -259,6 +262,8 @@ void ILI9488::writecommand(uint8_t c) { #include "esp32-hal.h" #include "soc/spi_struct.h" +#define RGB_PACK_MODE + // since ardunio transferBits ia completely disfunctional // we use our own hardware driver for 9 bit spi void ILI9488::fastSPIwrite(uint8_t d,uint8_t dc) { @@ -831,8 +836,7 @@ void ILI9488::fillScreen(uint16_t color) { //#define WRITE_SPI_REG -// this enables the 27 bit packed mode -#define RGB_PACK_MODE + // extremely strange => if this code is merged into pack_rgb() the software crashes // swap bytes @@ -1023,17 +1027,39 @@ void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t colo g = (g * 255) / 63; b = (b * 255) / 31; +#ifdef RGB_PACK_MODE + // init 27 bit mode + uint32_t data=pack_rgb(r,g,b); + REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); + REG_WRITE(SPI_MOSI_DLEN_REG(3), 27 - 1); + uint32_t *dp=(uint32_t*)SPI_W0_REG(3); + digitalWrite( _cs, LOW); +#endif + for(y=h; y>0; y--) { for(x=w; x>0; x--) { + #ifndef RGB_PACK_MODE writedata(r); writedata(g); writedata(b); + #else + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + *dp=data; + REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); + #endif } } + +#ifdef RGB_PACK_MODE + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + digitalWrite( _cs, HIGH); +#endif + ILI9488_STOP } #endif + // Pass 8-bit (each) R,G,B, get back 16-bit packed color uint16_t ILI9488::color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); From b069b89561069246a2a4569e6daf585e04275e62 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 29 May 2020 22:52:45 +0200 Subject: [PATCH 119/581] Add Zigbee options to ``ZbSend`` to write and report attributes --- tasmota/CHANGELOG.md | 1 + tasmota/i18n.h | 5 + tasmota/xdrv_10_rules.ino | 32 + tasmota/xdrv_23_zigbee_2_devices.ino | 44 +- tasmota/xdrv_23_zigbee_5_converters.ino | 1066 ++++++++++++--------- tasmota/xdrv_23_zigbee_7_statemachine.ino | 19 +- tasmota/xdrv_23_zigbee_8_parsers.ino | 7 +- tasmota/xdrv_23_zigbee_9_impl.ino | 560 +++++++---- 8 files changed, 1025 insertions(+), 709 deletions(-) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 487c94e64..9fb3490fc 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -11,6 +11,7 @@ - Add Three Phase Export Active Energy to SDM630 driver - Add wildcard pattern ``?`` for JSON matching in rules - Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) +- Add Zigbee options to ``ZbSend`` to write and report attributes ### 8.3.1.1 20200518 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 89d931908..e5f3e395a 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -513,10 +513,15 @@ #define D_CMND_ZIGBEE_FORGET "Forget" #define D_CMND_ZIGBEE_SAVE "Save" #define D_CMND_ZIGBEE_LINKQUALITY "LinkQuality" + #define D_CMND_ZIGBEE_CLUSTER "Cluster" #define D_CMND_ZIGBEE_ENDPOINT "Endpoint" #define D_CMND_ZIGBEE_GROUP "Group" + #define D_CMND_ZIGBEE_MANUF "Manuf" + #define D_CMND_ZIGBEE_DEVICE "Device" #define D_CMND_ZIGBEE_READ "Read" #define D_CMND_ZIGBEE_SEND "Send" +#define D_CMND_ZIGBEE_WRITE "Write" +#define D_CMND_ZIGBEE_REPORT "Report" #define D_JSON_ZIGBEE_ZCL_SENT "ZbZCLSent" #define D_JSON_ZIGBEE_RECEIVED "ZbReceived" #define D_CMND_ZIGBEE_BIND "Bind" diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 1ad618485..8dd185a29 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -458,6 +458,21 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) rule_param = String(SunMinutes(1)); } #endif // USE_TIMERS and USE_SUNRISE +// #ifdef USE_ZIGBEE +// if (rule_param.startsWith(F("%ZBDEVICE%"))) { +// snprintf_P(stemp, sizeof(stemp), PSTR("0x%04X"), Z_GetLastDevice()); +// rule_param = String(stemp); +// } +// if (rule_param.startsWith(F("%ZBGROUP%"))) { +// rule_param = String(Z_GetLastGroup()); +// } +// if (rule_param.startsWith(F("%ZBCLUSTER%"))) { +// rule_param = String(Z_GetLastCluster()); +// } +// if (rule_param.startsWith(F("%ZBENDPOINT%"))) { +// rule_param = String(Z_GetLastEndpoint()); +// } +// #endif rule_param.toUpperCase(); strlcpy(rule_svalue, rule_param.c_str(), sizeof(rule_svalue)); @@ -701,6 +716,13 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved) RulesVarReplace(commands, F("%SUNRISE%"), String(SunMinutes(0))); RulesVarReplace(commands, F("%SUNSET%"), String(SunMinutes(1))); #endif // USE_TIMERS and USE_SUNRISE +#ifdef USE_ZIGBEE + snprintf_P(stemp, sizeof(stemp), PSTR("0x%04X"), Z_GetLastDevice()); + RulesVarReplace(commands, F("%ZBDEVICE%"), String(stemp)); + RulesVarReplace(commands, F("%ZBGROUP%"), String(Z_GetLastGroup())); + RulesVarReplace(commands, F("%ZBCLUSTER%"), String(Z_GetLastCluster())); + RulesVarReplace(commands, F("%ZBENDPOINT%"), String(Z_GetLastEndpoint())); +#endif char command[commands.length() +1]; strlcpy(command, commands.c_str(), sizeof(command)); @@ -1261,6 +1283,16 @@ bool findNextVariableValue(char * &pVarname, float &value) } else if (sVarName.equals(F("SUNSET"))) { value = SunMinutes(1); #endif +// #ifdef USE_ZIGBEE +// // } else if (sVarName.equals(F("ZBDEVICE"))) { +// // value = Z_GetLastDevice(); +// } else if (sVarName.equals(F("ZBGROUP"))) { +// value = Z_GetLastGroup(); +// } else if (sVarName.equals(F("ZBCLUSTER"))) { +// value = Z_GetLastCluster(); +// } else if (sVarName.equals(F("ZBENDPOINT"))) { +// value = Z_GetLastEndpoint(); +// #endif } else { succeed = false; } diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index c115052f7..60f116002 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -26,6 +26,24 @@ #endif const uint16_t kZigbeeSaveDelaySeconds = ZIGBEE_SAVE_DELAY_SECONDS; // wait for x seconds +/*********************************************************************************************\ + * Structures for Rules variables related to the last received message +\*********************************************************************************************/ + +typedef struct Z_LastMessageVars { + uint16_t device; // device short address + uint16_t groupaddr; // group address + uint16_t cluster; // cluster id + uint8_t endpoint; // source endpoint +} Z_LastMessageVars; + +Z_LastMessageVars gZbLastMessage; + +uint16_t Z_GetLastDevice(void) { return gZbLastMessage.device; } +uint16_t Z_GetLastGroup(void) { return gZbLastMessage.groupaddr; } +uint16_t Z_GetLastCluster(void) { return gZbLastMessage.cluster; } +uint8_t Z_GetLastEndpoint(void) { return gZbLastMessage.endpoint; } + /*********************************************************************************************\ * Structures for device configuration \*********************************************************************************************/ @@ -256,7 +274,7 @@ int32_t Z_Devices::findEndpointInVector(const std::vector & vecOfElements, u // entry with same shortaddr or longaddr exists. // Z_Device & Z_Devices::createDeviceEntry(uint16_t shortaddr, uint64_t longaddr) { - if (!shortaddr && !longaddr) { return *(Z_Device*) nullptr; } // it is not legal to create an enrty with both short/long addr null + if ((BAD_SHORTADDR == shortaddr) && !longaddr) { return *(Z_Device*) nullptr; } // it is not legal to create this entry //Z_Device* device_alloc = (Z_Device*) malloc(sizeof(Z_Device)); Z_Device* device_alloc = new Z_Device{ longaddr, @@ -340,7 +358,7 @@ int32_t Z_Devices::findFriendlyName(const char * name) const { if (name_len) { for (auto &elem : _devices) { if (elem->friendlyName) { - if (strcmp(elem->friendlyName, name) == 0) { return found; } + if (strcasecmp(elem->friendlyName, name) == 0) { return found; } } found++; } @@ -860,21 +878,21 @@ const JsonObject *Z_Devices::jsonGet(uint16_t shortaddr) { void Z_Devices::jsonPublishFlush(uint16_t shortaddr) { Z_Device & device = getShortAddr(shortaddr); if (&device == nullptr) { return; } // don't crash if not found - JsonObject * json = device.json; - if (json == nullptr) { return; } // abort if nothing in buffer + JsonObject & json = *device.json; + if (&json == nullptr) { return; } // abort if nothing in buffer const char * fname = zigbee_devices.getFriendlyName(shortaddr); bool use_fname = (Settings.flag4.zigbee_use_names) && (fname); // should we replace shortaddr with friendlyname? - // Remove redundant "Name" or "Device" - if (use_fname) { - json->remove(F(D_JSON_ZIGBEE_NAME)); - } else { - json->remove(F(D_JSON_ZIGBEE_DEVICE)); - } + // save parameters is global variables to be used by Rules + gZbLastMessage.device = shortaddr; // %zbdevice% + gZbLastMessage.groupaddr = json[F(D_CMND_ZIGBEE_GROUP)]; // %zbgroup% + gZbLastMessage.cluster = json[F(D_CMND_ZIGBEE_CLUSTER)]; // %zbcluster% + gZbLastMessage.endpoint = json[F(D_CMND_ZIGBEE_ENDPOINT)]; // %zbendpoint% + // dump json in string String msg = ""; - json->printTo(msg); + json.printTo(msg); zigbee_devices.jsonClear(shortaddr); if (use_fname) { @@ -889,7 +907,7 @@ void Z_Devices::jsonPublishFlush(uint16_t shortaddr) { } else { MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); } - XdrvRulesProcess(); + XdrvRulesProcess(); // apply rules } void Z_Devices::jsonPublishNow(uint16_t shortaddr, JsonObject & values) { @@ -923,7 +941,7 @@ uint16_t Z_Devices::parseDeviceParam(const char * param, bool short_must_be_know if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 99)) { shortaddr = zigbee_devices.isKnownIndex(XdrvMailbox.payload - 1); } - } else if ((dataBuf[0] == '0') && (dataBuf[1] == 'x')) { + } else if ((dataBuf[0] == '0') && ((dataBuf[1] == 'x') || (dataBuf[1] == 'X'))) { // starts with 0x if (strlen(dataBuf) < 18) { // expect a short address diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index dfb69d4a7..5da74a1ed 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -79,476 +79,6 @@ uint8_t Z_getDatatypeLen(uint8_t t) { } } -typedef union ZCLHeaderFrameControl_t { - struct { - uint8_t frame_type : 2; // 00 = across entire profile, 01 = cluster specific - uint8_t manuf_specific : 1; // Manufacturer Specific Sub-field - uint8_t direction : 1; // 0 = tasmota to zigbee, 1 = zigbee to tasmota - uint8_t disable_def_resp : 1; // don't send back default response - uint8_t reserved : 3; - } b; - uint32_t d8; // raw 8 bits field -} ZCLHeaderFrameControl_t; - - -class ZCLFrame { -public: - - ZCLFrame(uint8_t frame_control, uint16_t manuf_code, uint8_t transact_seq, uint8_t cmd_id, - const char *buf, size_t buf_len, uint16_t clusterid, uint16_t groupaddr, - uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, - uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber, - uint32_t timestamp): - _manuf_code(manuf_code), _transact_seq(transact_seq), _cmd_id(cmd_id), - _payload(buf_len ? buf_len : 250), // allocate the data frame from source or preallocate big enough - _cluster_id(clusterid), _groupaddr(groupaddr), - _srcaddr(srcaddr), _srcendpoint(srcendpoint), _dstendpoint(dstendpoint), _wasbroadcast(wasbroadcast), - _linkquality(linkquality), _securityuse(securityuse), _seqnumber(seqnumber), - _timestamp(timestamp) - { - _frame_control.d8 = frame_control; - _payload.addBuffer(buf, buf_len); - }; - - - void log(void) { - char hex_char[_payload.len()*2+2]; - ToHex_P((unsigned char*)_payload.getBuffer(), _payload.len(), hex_char, sizeof(hex_char)); - Response_P(PSTR("{\"" D_JSON_ZIGBEEZCL_RECEIVED "\":{" - "\"groupid\":%d," "\"clusterid\":%d," "\"srcaddr\":\"0x%04X\"," - "\"srcendpoint\":%d," "\"dstendpoint\":%d," "\"wasbroadcast\":%d," - "\"" D_CMND_ZIGBEE_LINKQUALITY "\":%d," "\"securityuse\":%d," "\"seqnumber\":%d," - "\"timestamp\":%d," - "\"fc\":\"0x%02X\",\"manuf\":\"0x%04X\",\"transact\":%d," - "\"cmdid\":\"0x%02X\",\"payload\":\"%s\"}}"), - _groupaddr, _cluster_id, _srcaddr, - _srcendpoint, _dstendpoint, _wasbroadcast, - _linkquality, _securityuse, _seqnumber, - _timestamp, - _frame_control, _manuf_code, _transact_seq, _cmd_id, - hex_char); - if (Settings.flag3.tuya_serial_mqtt_publish) { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); - XdrvRulesProcess(); - } else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); - } - } - - static ZCLFrame parseRawFrame(const SBuffer &buf, uint8_t offset, uint8_t len, uint16_t clusterid, uint16_t groupid, - uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, - uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber, - uint32_t timestamp) { // parse a raw frame and build the ZCL frame object - uint32_t i = offset; - ZCLHeaderFrameControl_t frame_control; - uint16_t manuf_code = 0; - uint8_t transact_seq; - uint8_t cmd_id; - - frame_control.d8 = buf.get8(i++); - if (frame_control.b.manuf_specific) { - manuf_code = buf.get16(i); - i += 2; - } - transact_seq = buf.get8(i++); - cmd_id = buf.get8(i++); - ZCLFrame zcl_frame(frame_control.d8, manuf_code, transact_seq, cmd_id, - (const char *)(buf.buf() + i), len + offset - i, - clusterid, groupid, - srcaddr, srcendpoint, dstendpoint, wasbroadcast, - linkquality, securityuse, seqnumber, - timestamp); - return zcl_frame; - } - - bool isClusterSpecificCommand(void) { - return _frame_control.b.frame_type & 1; - } - - static void generateAttributeName(const JsonObject& json, uint16_t cluster, uint16_t attr, char *key, size_t key_len); - void parseRawAttributes(JsonObject& json, uint8_t offset = 0); - void parseReadAttributes(JsonObject& json, uint8_t offset = 0); - void parseResponse(void); - void parseClusterSpecificCommand(JsonObject& json, uint8_t offset = 0); - void postProcessAttributes(uint16_t shortaddr, JsonObject& json); - - inline void setGroupId(uint16_t groupid) { - _groupaddr = groupid; - } - - inline void setClusterId(uint16_t clusterid) { - _cluster_id = clusterid; - } - - inline uint8_t getCmdId(void) const { - return _cmd_id; - } - - inline uint16_t getClusterId(void) const { - return _cluster_id; - } - - inline uint16_t getSrcEndpoint(void) const { - return _srcendpoint; - } - - const SBuffer &getPayload(void) const { - return _payload; - } - - uint16_t getManufCode(void) const { - return _manuf_code; - } - -private: - ZCLHeaderFrameControl_t _frame_control = { .d8 = 0 }; - uint16_t _manuf_code = 0; // optional - uint8_t _transact_seq = 0; // transaction sequence number - uint8_t _cmd_id = 0; - SBuffer _payload; - uint16_t _cluster_id = 0; - uint16_t _groupaddr = 0; - // information from decoded ZCL frame - uint16_t _srcaddr; - uint8_t _srcendpoint; - uint8_t _dstendpoint; - uint8_t _wasbroadcast; - uint8_t _linkquality; - uint8_t _securityuse; - uint8_t _seqnumber; - uint32_t _timestamp; -}; - -// Zigbee ZCL converters - -// from https://github.com/Koenkk/zigbee-shepherd-converters/blob/638d29f0cace6343052b9a4e7fd60980fa785479/converters/fromZigbee.js#L55 -// Input voltage in mV, i.e. 3000 = 3.000V -// Output percentage from 0 to 100 as int -uint8_t toPercentageCR2032(uint32_t voltage) { - uint32_t percentage; - if (voltage < 2100) { - percentage = 0; - } else if (voltage < 2440) { - percentage = 6 - ((2440 - voltage) * 6) / 340; - } else if (voltage < 2740) { - percentage = 18 - ((2740 - voltage) * 12) / 300; - } else if (voltage < 2900) { - percentage = 42 - ((2900 - voltage) * 24) / 160; - } else if (voltage < 3000) { - percentage = 100 - ((3000 - voltage) * 58) / 100; - } else if (voltage >= 3000) { - percentage = 100; - } - return percentage; -} - - -uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer &buf, - uint32_t offset, uint32_t buflen) { - - uint32_t i = offset; - uint32_t attrtype = buf.get8(i++); - - // fallback - enter a null value - json[attrid_str] = (char*) nullptr; - - uint32_t len = Z_getDatatypeLen(attrtype); // pre-compute lenght, overloaded for variable length attributes - - // now parse accordingly to attr type - switch (attrtype) { - // case Znodata: // nodata - // case Zunk: // unk - // break; - case Zbool: // bool - case Zuint8: // uint8 - case Zenum8: // enum8 - { - uint8_t uint8_val = buf.get8(i); - // i += 1; - if (0xFF != uint8_val) { - json[attrid_str] = uint8_val; - } - } - break; - case Zuint16: // uint16 - case Zenum16: // enum16 - { - uint16_t uint16_val = buf.get16(i); - // i += 2; - if (0xFFFF != uint16_val) { - json[attrid_str] = uint16_val; - } - } - break; - case Zuint32: // uint32 - { - uint32_t uint32_val = buf.get32(i); - // i += 4; - if (0xFFFFFFFF != uint32_val) { - json[attrid_str] = uint32_val; - } - } - break; - // Note: uint40, uint48, uint56, uint64 are displayed as Hex - // Note: int40, int48, int56, int64 are displayed as Hex - case Zuint40: // uint40 - case Zuint48: // uint48 - case Zuint56: // uint56 - case Zuint64: // uint64 - case Zint40: // int40 - case Zint48: // int48 - case Zint56: // int56 - case Zint64: // int64 - { - // uint8_t len = attrtype - 0x27; // 5 - 8 - // print as HEX - char hex[2*len+1]; - ToHex_P(buf.buf(i), len, hex, sizeof(hex)); - json[attrid_str] = hex; - // i += len; - } - break; - case Zint8: // int8 - { - int8_t int8_val = buf.get8(i); - // i += 1; - if (0x80 != int8_val) { - json[attrid_str] = int8_val; - } - } - break; - case Zint16: // int16 - { - int16_t int16_val = buf.get16(i); - // i += 2; - if (0x8000 != int16_val) { - json[attrid_str] = int16_val; - } - } - break; - case Zint32: // int32 - { - int32_t int32_val = buf.get32(i); - // i += 4; - if (0x80000000 != int32_val) { - json[attrid_str] = int32_val; - } - } - break; - - case Zoctstr: // octet string, 1 byte len - case Zstring: // char string, 1 byte len - case Zoctstr16: // octet string, 2 bytes len - case Zstring16: // char string, 2 bytes len - // For strings, default is to try to do a real string, but reverts to octet stream if null char is present or on some exceptions - { - bool parse_as_string = true; - len = (attrtype <= 0x42) ? buf.get8(i) : buf.get16(i); // len is 8 or 16 bits - i += (attrtype <= 0x42) ? 1 : 2; // increment pointer - if (i + len > buf.len()) { // make sure we don't get past the buffer - len = buf.len() - i; - } - - // check if we can safely use a string - if ((0x41 == attrtype) || (0x43 == attrtype)) { parse_as_string = false; } - - if (parse_as_string) { - char str[len+1]; - strncpy(str, buf.charptr(i), len); - str[len] = 0x00; - json[attrid_str] = str; - } else { - // print as HEX - char hex[2*len+1]; - ToHex_P(buf.buf(i), len, hex, sizeof(hex)); - json[attrid_str] = hex; - } - - // i += len; - // break; - } - // i += buf.get8(i) + 1; - break; - - case Zdata8: // data8 - case Zmap8: // map8 - { - uint8_t uint8_val = buf.get8(i); - // i += 1; - json[attrid_str] = uint8_val; - } - break; - case Zdata16: // data16 - case Zmap16: // map16 - { - uint16_t uint16_val = buf.get16(i); - // i += 2; - json[attrid_str] = uint16_val; - } - break; - case Zdata32: // data32 - case Zmap32: // map32 - { - uint32_t uint32_val = buf.get32(i); - // i += 4; - json[attrid_str] = uint32_val; - } - break; - - case Zsingle: // float - { - uint32_t uint32_val = buf.get32(i); - float * float_val = (float*) &uint32_val; - // i += 4; - json[attrid_str] = *float_val; - } - break; - - // TODO - case ZToD: // ToD - case Zdate: // date - case ZUTC: // UTC - case ZclusterId: // clusterId - case ZattribId: // attribId - case ZbacOID: // bacOID - case ZEUI64: // EUI64 - case Zkey128: // key128 - case Zsemi: // semi (float on 2 bytes) - break; - - // Other un-implemented data types - case Zdata24: // data24 - case Zdata40: // data40 - case Zdata48: // data48 - case Zdata56: // data56 - case Zdata64: // data64 - break; - // map - case Zmap24: // map24 - case Zmap40: // map40 - case Zmap48: // map48 - case Zmap56: // map56 - case Zmap64: // map64 - break; - case Zdouble: // double precision - { - uint64_t uint64_val = buf.get64(i); - double * double_val = (double*) &uint64_val; - // i += 8; - json[attrid_str] = *double_val; - } - break; - } - i += len; - - // String pp; // pretty print - // json[attrid_str].prettyPrintTo(pp); - // // now store the attribute - // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZCL attribute decoded, id %s, type 0x%02X, val=%s"), - // attrid_str, attrtype, pp.c_str()); - return i - offset; // how much have we increased the index -} - -// Generate an attribute name based on cluster number, attribute, and suffix if duplicates -void ZCLFrame::generateAttributeName(const JsonObject& json, uint16_t cluster, uint16_t attr, char *key, size_t key_len) { - uint32_t suffix = 1; - - snprintf_P(key, key_len, PSTR("%04X/%04X"), cluster, attr); - while (json.containsKey(key)) { - suffix++; - snprintf_P(key, key_len, PSTR("%04X/%04X+%d"), cluster, attr, suffix); // add "0008/0001+2" suffix if duplicate - } -} - -// First pass, parse all attributes in their native format -void ZCLFrame::parseRawAttributes(JsonObject& json, uint8_t offset) { - uint32_t i = offset; - uint32_t len = _payload.len(); - - while (len >= i + 3) { - uint16_t attrid = _payload.get16(i); - i += 2; - - char key[16]; - generateAttributeName(json, _cluster_id, attrid, key, sizeof(key)); - - // exception for Xiaomi lumi.weather - specific field to be treated as octet and not char - if ((0x0000 == _cluster_id) && (0xFF01 == attrid)) { - if (0x42 == _payload.get8(i)) { - _payload.set8(i, 0x41); // change type from 0x42 to 0x41 - } - } - i += parseSingleAttribute(json, key, _payload, i, len); - } -} - -// ZCL_READ_ATTRIBUTES_RESPONSE -void ZCLFrame::parseReadAttributes(JsonObject& json, uint8_t offset) { - uint32_t i = offset; - uint32_t len = _payload.len(); - - while (len - i >= 4) { - uint16_t attrid = _payload.get16(i); - i += 2; - uint8_t status = _payload.get8(i++); - - if (0 == status) { - char key[16]; - generateAttributeName(json, _cluster_id, attrid, key, sizeof(key)); - - i += parseSingleAttribute(json, key, _payload, i, len); - } - } -} - -// ZCL_DEFAULT_RESPONSE -void ZCLFrame::parseResponse(void) { - if (_payload.len() < 2) { return; } // wrong format - uint8_t cmd = _payload.get8(0); - uint8_t status = _payload.get8(1); - - DynamicJsonBuffer jsonBuffer; - JsonObject& json = jsonBuffer.createObject(); - - // "Device" - char s[12]; - snprintf_P(s, sizeof(s), PSTR("0x%04X"), _srcaddr); - json[F(D_JSON_ZIGBEE_DEVICE)] = s; - // "Name" - const char * friendlyName = zigbee_devices.getFriendlyName(_srcaddr); - if (friendlyName) { - json[F(D_JSON_ZIGBEE_NAME)] = (char*) friendlyName; - } - // "Command" - snprintf_P(s, sizeof(s), PSTR("%04X!%02X"), _cluster_id, cmd); - json[F(D_JSON_ZIGBEE_CMD)] = s; - // "Status" - json[F(D_JSON_ZIGBEE_STATUS)] = status; - // "StatusMessage" - json[F(D_JSON_ZIGBEE_STATUS_MSG)] = getZigbeeStatusMessage(status); - // Add Endpoint - json[F(D_CMND_ZIGBEE_ENDPOINT)] = _srcendpoint; - // Add Group if non-zero - if (_groupaddr) { - json[F(D_CMND_ZIGBEE_GROUP)] = _groupaddr; - } - // Add linkquality - json[F(D_CMND_ZIGBEE_LINKQUALITY)] = _linkquality; - - String msg(""); - msg.reserve(100); - json.printTo(msg); - Response_P(PSTR("{\"" D_JSON_ZIGBEE_RESPONSE "\":%s}"), msg.c_str()); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); -} - - -// Parse non-normalized attributes -void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) { - convertClusterSpecific(json, _cluster_id, _cmd_id, _frame_control.b.direction, _payload); - sendHueUpdate(_srcaddr, _groupaddr, _cluster_id, _cmd_id, _frame_control.b.direction); -} // return value: // 0 = keep initial value @@ -684,13 +214,13 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zuint8, Cx0000, 0x0002, Z(StackVersion), &Z_Copy }, { Zuint8, Cx0000, 0x0003, Z(HWVersion), &Z_Copy }, { Zstring, Cx0000, 0x0004, Z(Manufacturer), &Z_ManufKeep }, // record Manufacturer - { Zstring, Cx0000, 0x0005, Z(ModelId), &Z_ModelKeep }, // record Model + { Zstring, Cx0000, 0x0005, Z(ModelId), &Z_ModelKeep }, // record Model { Zstring, Cx0000, 0x0006, Z(DateCode), &Z_Copy }, { Zenum8, Cx0000, 0x0007, Z(PowerSource), &Z_Copy }, { Zstring, Cx0000, 0x4000, Z(SWBuildID), &Z_Copy }, - { Zunk, Cx0000, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zunk, Cx0000, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values // Cmd 0x0A - Cluster 0x0000, attribute 0xFF01 - proprietary - { Zmap8, Cx0000, 0xFF01, nullptr, &Z_AqaraSensor }, // Occupancy (map8) + { Zmap8, Cx0000, 0xFF01, nullptr, &Z_AqaraSensor }, // Occupancy (map8) // Power Configuration cluster { Zuint16, Cx0001, 0x0000, Z(MainsVoltage), &Z_Copy }, @@ -712,8 +242,8 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { //{ Zmap8, Cx0005, 0x0004, Z(NameSupport), &Z_Copy }, // On/off cluster - { Zbool, Cx0006, 0x0000, Z(Power), &Z_Copy }, - { Zbool, Cx0006, 0x8000, Z(Power), &Z_Copy }, // See 7280 + { Zbool, Cx0006, 0x0000, Z(Power), &Z_Copy }, + { Zbool, Cx0006, 0x8000, Z(Power), &Z_Copy }, // See 7280 // On/Off Switch Configuration cluster { Zenum8, Cx0007, 0x0000, Z(SwitchType), &Z_Copy }, @@ -735,7 +265,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zmap8, Cx000A, 0x0001, Z(TimeStatus), &Z_Copy }, { Zint32, Cx000A, 0x0002, Z(TimeZone), &Z_Copy }, { Zuint32, Cx000A, 0x0003, Z(DstStart), &Z_Copy }, - { Zuint32, Cx000A, 0x0004, Z(DstEnd), &Z_Copy }, + { Zuint32, Cx000A, 0x0004, Z(DstEnd), &Z_Copy }, { Zint32, Cx000A, 0x0005, Z(DstShift), &Z_Copy }, { Zuint32, Cx000A, 0x0006, Z(StandardTime), &Z_Copy }, { Zuint32, Cx000A, 0x0007, Z(LocalTime), &Z_Copy }, @@ -1032,6 +562,590 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { }; + +typedef union ZCLHeaderFrameControl_t { + struct { + uint8_t frame_type : 2; // 00 = across entire profile, 01 = cluster specific + uint8_t manuf_specific : 1; // Manufacturer Specific Sub-field + uint8_t direction : 1; // 0 = tasmota to zigbee, 1 = zigbee to tasmota + uint8_t disable_def_resp : 1; // don't send back default response + uint8_t reserved : 3; + } b; + uint32_t d8; // raw 8 bits field +} ZCLHeaderFrameControl_t; + + +class ZCLFrame { +public: + + ZCLFrame(uint8_t frame_control, uint16_t manuf_code, uint8_t transact_seq, uint8_t cmd_id, + const char *buf, size_t buf_len, uint16_t clusterid, uint16_t groupaddr, + uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, + uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber, + uint32_t timestamp): + _manuf_code(manuf_code), _transact_seq(transact_seq), _cmd_id(cmd_id), + _payload(buf_len ? buf_len : 250), // allocate the data frame from source or preallocate big enough + _cluster_id(clusterid), _groupaddr(groupaddr), + _srcaddr(srcaddr), _srcendpoint(srcendpoint), _dstendpoint(dstendpoint), _wasbroadcast(wasbroadcast), + _linkquality(linkquality), _securityuse(securityuse), _seqnumber(seqnumber), + _timestamp(timestamp) + { + _frame_control.d8 = frame_control; + _payload.addBuffer(buf, buf_len); + }; + + + void log(void) { + char hex_char[_payload.len()*2+2]; + ToHex_P((unsigned char*)_payload.getBuffer(), _payload.len(), hex_char, sizeof(hex_char)); + Response_P(PSTR("{\"" D_JSON_ZIGBEEZCL_RECEIVED "\":{" + "\"groupid\":%d," "\"clusterid\":%d," "\"srcaddr\":\"0x%04X\"," + "\"srcendpoint\":%d," "\"dstendpoint\":%d," "\"wasbroadcast\":%d," + "\"" D_CMND_ZIGBEE_LINKQUALITY "\":%d," "\"securityuse\":%d," "\"seqnumber\":%d," + "\"timestamp\":%d," + "\"fc\":\"0x%02X\",\"manuf\":\"0x%04X\",\"transact\":%d," + "\"cmdid\":\"0x%02X\",\"payload\":\"%s\"}}"), + _groupaddr, _cluster_id, _srcaddr, + _srcendpoint, _dstendpoint, _wasbroadcast, + _linkquality, _securityuse, _seqnumber, + _timestamp, + _frame_control, _manuf_code, _transact_seq, _cmd_id, + hex_char); + if (Settings.flag3.tuya_serial_mqtt_publish) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); + XdrvRulesProcess(); + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); + } + } + + static ZCLFrame parseRawFrame(const SBuffer &buf, uint8_t offset, uint8_t len, uint16_t clusterid, uint16_t groupid, + uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, + uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber, + uint32_t timestamp) { // parse a raw frame and build the ZCL frame object + uint32_t i = offset; + ZCLHeaderFrameControl_t frame_control; + uint16_t manuf_code = 0; + uint8_t transact_seq; + uint8_t cmd_id; + + frame_control.d8 = buf.get8(i++); + if (frame_control.b.manuf_specific) { + manuf_code = buf.get16(i); + i += 2; + } + transact_seq = buf.get8(i++); + cmd_id = buf.get8(i++); + ZCLFrame zcl_frame(frame_control.d8, manuf_code, transact_seq, cmd_id, + (const char *)(buf.buf() + i), len + offset - i, + clusterid, groupid, + srcaddr, srcendpoint, dstendpoint, wasbroadcast, + linkquality, securityuse, seqnumber, + timestamp); + return zcl_frame; + } + + bool isClusterSpecificCommand(void) { + return _frame_control.b.frame_type & 1; + } + + static void generateAttributeName(const JsonObject& json, uint16_t cluster, uint16_t attr, char *key, size_t key_len); + void parseRawAttributes(JsonObject& json, uint8_t offset = 0); + void parseReadAttributes(JsonObject& json, uint8_t offset = 0); + void parseReadAttributesResponse(JsonObject& json, uint8_t offset = 0); + void parseResponse(void); + void parseClusterSpecificCommand(JsonObject& json, uint8_t offset = 0); + void postProcessAttributes(uint16_t shortaddr, JsonObject& json); + + inline void setGroupId(uint16_t groupid) { + _groupaddr = groupid; + } + + inline void setClusterId(uint16_t clusterid) { + _cluster_id = clusterid; + } + + inline uint8_t getCmdId(void) const { + return _cmd_id; + } + + inline uint16_t getClusterId(void) const { + return _cluster_id; + } + + inline uint16_t getSrcEndpoint(void) const { + return _srcendpoint; + } + + const SBuffer &getPayload(void) const { + return _payload; + } + + uint16_t getManufCode(void) const { + return _manuf_code; + } + +private: + ZCLHeaderFrameControl_t _frame_control = { .d8 = 0 }; + uint16_t _manuf_code = 0; // optional + uint8_t _transact_seq = 0; // transaction sequence number + uint8_t _cmd_id = 0; + SBuffer _payload; + uint16_t _cluster_id = 0; + uint16_t _groupaddr = 0; + // information from decoded ZCL frame + uint16_t _srcaddr; + uint8_t _srcendpoint; + uint8_t _dstendpoint; + uint8_t _wasbroadcast; + uint8_t _linkquality; + uint8_t _securityuse; + uint8_t _seqnumber; + uint32_t _timestamp; +}; + +// Zigbee ZCL converters + +// from https://github.com/Koenkk/zigbee-shepherd-converters/blob/638d29f0cace6343052b9a4e7fd60980fa785479/converters/fromZigbee.js#L55 +// Input voltage in mV, i.e. 3000 = 3.000V +// Output percentage from 0 to 100 as int +uint8_t toPercentageCR2032(uint32_t voltage) { + uint32_t percentage; + if (voltage < 2100) { + percentage = 0; + } else if (voltage < 2440) { + percentage = 6 - ((2440 - voltage) * 6) / 340; + } else if (voltage < 2740) { + percentage = 18 - ((2740 - voltage) * 12) / 300; + } else if (voltage < 2900) { + percentage = 42 - ((2900 - voltage) * 24) / 160; + } else if (voltage < 3000) { + percentage = 100 - ((3000 - voltage) * 58) / 100; + } else if (voltage >= 3000) { + percentage = 100; + } + return percentage; +} + +// +// Appends the attribute value to Write or to Report +// Adds to buf: +// - 2 bytes: attribute identigier +// - 1 byte: attribute type +// - n bytes: value (typically between 1 and 4 bytes, or bigger for strings) +// returns number of bytes of attribute, or <0 if error +int32_t encodeSingleAttribute(class SBuffer &buf, const JsonVariant &val, uint16_t attr, uint8_t attrtype) { + uint32_t len = Z_getDatatypeLen(attrtype); // pre-compute lenght, overloaded for variable length attributes + + uint32_t u32 = val.as(); + int32_t i32 = val.as(); + float f32 = val.as(); + + buf.add16(attr); // prepend with attribute identifier + buf.add8(attrtype); // prepend with attribute type + + switch (attrtype) { + // unsigned 8 + case Zbool: // bool + case Zuint8: // uint8 + case Zenum8: // enum8 + case Zdata8: // data8 + case Zmap8: // map8 + buf.add8(u32); + break; + // unsigned 16 + case Zuint16: // uint16 + case Zenum16: // enum16 + case Zdata16: // data16 + case Zmap16: // map16 + buf.add16(u32); + break; + // unisgned 32 + case Zuint32: // uint32 + case Zdata32: // data32 + case Zmap32: // map32 + buf.add32(u32); + break; + + // signed 8 + case Zint8: // int8 + buf.add8(i32); + break; + case Zint16: // int16 + buf.add16(i32); + break; + case Zint32: // int32 + buf.add32(i32); + break; + + case Zsingle: // float + uint32_t *f_ptr; + buf.add32( *((uint32_t*)&f32) ); // cast float as uint32_t + break; + + case Zstring: + case Zstring16: + { + const char * val_str = val.as(); + if (nullptr == val_str) { return -2; } + size_t val_len = strlen(val_str); + if (val_len > 32) { val_len = 32; } + len = val_len + 1; + buf.add8(val_len); + if (Zstring16 == attrtype) { + buf.add8(0); // len is on 2 bytes + len++; + } + for (uint32_t i = 0; i < val_len; i++) { + buf.add8(val_str[i]); + } + } + break; + + default: + // remove the attribute type we just added + buf.setLen(buf.len() - 3); + return -1; + } + return len + 3; +} + +uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer &buf, + uint32_t offset, uint32_t buflen) { + + uint32_t i = offset; + uint32_t attrtype = buf.get8(i++); + + // fallback - enter a null value + json[attrid_str] = (char*) nullptr; + + uint32_t len = Z_getDatatypeLen(attrtype); // pre-compute lenght, overloaded for variable length attributes + + // now parse accordingly to attr type + switch (attrtype) { + // case Znodata: // nodata + // case Zunk: // unk + // break; + case Zbool: // bool + case Zuint8: // uint8 + case Zenum8: // enum8 + { + uint8_t uint8_val = buf.get8(i); + // i += 1; + if (0xFF != uint8_val) { + json[attrid_str] = uint8_val; + } + } + break; + case Zuint16: // uint16 + case Zenum16: // enum16 + { + uint16_t uint16_val = buf.get16(i); + // i += 2; + if (0xFFFF != uint16_val) { + json[attrid_str] = uint16_val; + } + } + break; + case Zuint32: // uint32 + { + uint32_t uint32_val = buf.get32(i); + // i += 4; + if (0xFFFFFFFF != uint32_val) { + json[attrid_str] = uint32_val; + } + } + break; + // Note: uint40, uint48, uint56, uint64 are displayed as Hex + // Note: int40, int48, int56, int64 are displayed as Hex + case Zuint40: // uint40 + case Zuint48: // uint48 + case Zuint56: // uint56 + case Zuint64: // uint64 + case Zint40: // int40 + case Zint48: // int48 + case Zint56: // int56 + case Zint64: // int64 + { + // uint8_t len = attrtype - 0x27; // 5 - 8 + // print as HEX + char hex[2*len+1]; + ToHex_P(buf.buf(i), len, hex, sizeof(hex)); + json[attrid_str] = hex; + // i += len; + } + break; + case Zint8: // int8 + { + int8_t int8_val = buf.get8(i); + // i += 1; + if (0x80 != int8_val) { + json[attrid_str] = int8_val; + } + } + break; + case Zint16: // int16 + { + int16_t int16_val = buf.get16(i); + // i += 2; + if (0x8000 != int16_val) { + json[attrid_str] = int16_val; + } + } + break; + case Zint32: // int32 + { + int32_t int32_val = buf.get32(i); + // i += 4; + if (0x80000000 != int32_val) { + json[attrid_str] = int32_val; + } + } + break; + + case Zoctstr: // octet string, 1 byte len + case Zstring: // char string, 1 byte len + case Zoctstr16: // octet string, 2 bytes len + case Zstring16: // char string, 2 bytes len + // For strings, default is to try to do a real string, but reverts to octet stream if null char is present or on some exceptions + { + bool parse_as_string = true; + len = (attrtype <= 0x42) ? buf.get8(i) : buf.get16(i); // len is 8 or 16 bits + i += (attrtype <= 0x42) ? 1 : 2; // increment pointer + if (i + len > buf.len()) { // make sure we don't get past the buffer + len = buf.len() - i; + } + + // check if we can safely use a string + if ((0x41 == attrtype) || (0x43 == attrtype)) { parse_as_string = false; } + + if (parse_as_string) { + char str[len+1]; + strncpy(str, buf.charptr(i), len); + str[len] = 0x00; + json[attrid_str] = str; + } else { + // print as HEX + char hex[2*len+1]; + ToHex_P(buf.buf(i), len, hex, sizeof(hex)); + json[attrid_str] = hex; + } + + // i += len; + // break; + } + // i += buf.get8(i) + 1; + break; + + case Zdata8: // data8 + case Zmap8: // map8 + { + uint8_t uint8_val = buf.get8(i); + // i += 1; + json[attrid_str] = uint8_val; + } + break; + case Zdata16: // data16 + case Zmap16: // map16 + { + uint16_t uint16_val = buf.get16(i); + // i += 2; + json[attrid_str] = uint16_val; + } + break; + case Zdata32: // data32 + case Zmap32: // map32 + { + uint32_t uint32_val = buf.get32(i); + // i += 4; + json[attrid_str] = uint32_val; + } + break; + + case Zsingle: // float + { + uint32_t uint32_val = buf.get32(i); + float * float_val = (float*) &uint32_val; + // i += 4; + json[attrid_str] = *float_val; + } + break; + + // TODO + case ZToD: // ToD + case Zdate: // date + case ZUTC: // UTC + case ZclusterId: // clusterId + case ZattribId: // attribId + case ZbacOID: // bacOID + case ZEUI64: // EUI64 + case Zkey128: // key128 + case Zsemi: // semi (float on 2 bytes) + break; + + // Other un-implemented data types + case Zdata24: // data24 + case Zdata40: // data40 + case Zdata48: // data48 + case Zdata56: // data56 + case Zdata64: // data64 + break; + // map + case Zmap24: // map24 + case Zmap40: // map40 + case Zmap48: // map48 + case Zmap56: // map56 + case Zmap64: // map64 + break; + case Zdouble: // double precision + { + uint64_t uint64_val = buf.get64(i); + double * double_val = (double*) &uint64_val; + // i += 8; + json[attrid_str] = *double_val; + } + break; + } + i += len; + + // String pp; // pretty print + // json[attrid_str].prettyPrintTo(pp); + // // now store the attribute + // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZCL attribute decoded, id %s, type 0x%02X, val=%s"), + // attrid_str, attrtype, pp.c_str()); + return i - offset; // how much have we increased the index +} + +// Generate an attribute name based on cluster number, attribute, and suffix if duplicates +void ZCLFrame::generateAttributeName(const JsonObject& json, uint16_t cluster, uint16_t attr, char *key, size_t key_len) { + uint32_t suffix = 1; + + snprintf_P(key, key_len, PSTR("%04X/%04X"), cluster, attr); + while (json.containsKey(key)) { + suffix++; + snprintf_P(key, key_len, PSTR("%04X/%04X+%d"), cluster, attr, suffix); // add "0008/0001+2" suffix if duplicate + } +} + +// First pass, parse all attributes in their native format +void ZCLFrame::parseRawAttributes(JsonObject& json, uint8_t offset) { + uint32_t i = offset; + uint32_t len = _payload.len(); + + while (len >= i + 3) { + uint16_t attrid = _payload.get16(i); + i += 2; + + char key[16]; + generateAttributeName(json, _cluster_id, attrid, key, sizeof(key)); + + // exception for Xiaomi lumi.weather - specific field to be treated as octet and not char + if ((0x0000 == _cluster_id) && (0xFF01 == attrid)) { + if (0x42 == _payload.get8(i)) { + _payload.set8(i, 0x41); // change type from 0x42 to 0x41 + } + } + i += parseSingleAttribute(json, key, _payload, i, len); + } +} + +// ZCL_READ_ATTRIBUTES +// TODO +void ZCLFrame::parseReadAttributes(JsonObject& json, uint8_t offset) { + uint32_t i = offset; + uint32_t len = _payload.len(); + + json[F(D_CMND_ZIGBEE_CLUSTER)] = _cluster_id; + + JsonArray &attr_list = json.createNestedArray(F("Read")); + JsonObject &attr_names = json.createNestedObject(F("ReadNames")); + while (len - i >= 2) { + uint16_t attrid = _payload.get16(i); + attr_list.add(attrid); + + // find the attribute name + for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + const Z_AttributeConverter *converter = &Z_PostProcess[i]; + uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); + uint16_t conv_attribute = pgm_read_word(&converter->attribute); + + if ((conv_cluster == _cluster_id) && (conv_attribute == attrid)) { + attr_names[(const __FlashStringHelper*) converter->name] = true; + break; + } + } + i += 2; + } +} + +// ZCL_READ_ATTRIBUTES_RESPONSE +void ZCLFrame::parseReadAttributesResponse(JsonObject& json, uint8_t offset) { + uint32_t i = offset; + uint32_t len = _payload.len(); + + while (len >= 4 + i) { + uint16_t attrid = _payload.get16(i); + i += 2; + uint8_t status = _payload.get8(i++); + + if (0 == status) { + char key[16]; + generateAttributeName(json, _cluster_id, attrid, key, sizeof(key)); + + i += parseSingleAttribute(json, key, _payload, i, len); + } + } +} + +// ZCL_DEFAULT_RESPONSE +void ZCLFrame::parseResponse(void) { + if (_payload.len() < 2) { return; } // wrong format + uint8_t cmd = _payload.get8(0); + uint8_t status = _payload.get8(1); + + DynamicJsonBuffer jsonBuffer; + JsonObject& json = jsonBuffer.createObject(); + + // "Device" + char s[12]; + snprintf_P(s, sizeof(s), PSTR("0x%04X"), _srcaddr); + json[F(D_JSON_ZIGBEE_DEVICE)] = s; + // "Name" + const char * friendlyName = zigbee_devices.getFriendlyName(_srcaddr); + if (friendlyName) { + json[F(D_JSON_ZIGBEE_NAME)] = (char*) friendlyName; + } + // "Command" + snprintf_P(s, sizeof(s), PSTR("%04X!%02X"), _cluster_id, cmd); + json[F(D_JSON_ZIGBEE_CMD)] = s; + // "Status" + json[F(D_JSON_ZIGBEE_STATUS)] = status; + // "StatusMessage" + json[F(D_JSON_ZIGBEE_STATUS_MSG)] = getZigbeeStatusMessage(status); + // Add Endpoint + json[F(D_CMND_ZIGBEE_ENDPOINT)] = _srcendpoint; + // Add Group if non-zero + if (_groupaddr) { + json[F(D_CMND_ZIGBEE_GROUP)] = _groupaddr; + } + // Add linkquality + json[F(D_CMND_ZIGBEE_LINKQUALITY)] = _linkquality; + + String msg(""); + msg.reserve(100); + json.printTo(msg); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_RESPONSE "\":%s}"), msg.c_str()); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); + XdrvRulesProcess(); +} + + +// Parse non-normalized attributes +void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) { + convertClusterSpecific(json, _cluster_id, _cmd_id, _frame_control.b.direction, _payload); + sendHueUpdate(_srcaddr, _groupaddr, _cluster_id, _cmd_id, _frame_control.b.direction); +} + // ====================================================================== // Record Manuf int32_t Z_ManufKeep(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index 590c795ac..4297a4375 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -106,10 +106,11 @@ enum Zigbee_StateMachine_Instruction_Set { // Labels used in the State Machine -- internal only const uint8_t ZIGBEE_LABEL_INIT_COORD = 10; // Start ZNP as coordinator const uint8_t ZIGBEE_LABEL_START_COORD = 11; // Start ZNP as coordinator -const uint8_t ZIGBEE_LABEL_INIT_ROUTER = 12; // Start ZNP as router +const uint8_t ZIGBEE_LABEL_INIT_ROUTER = 12; // Init ZNP as router const uint8_t ZIGBEE_LABEL_START_ROUTER = 13; // Start ZNP as router -const uint8_t ZIGBEE_LABEL_INIT_DEVICE = 14; // Start ZNP as end-device -// const uint8_t ZIGBEE_LABEL_START_DEVICE = 15; // Start ZNP as end-device - same as ZIGBEE_LABEL_START_ROUTER +const uint8_t ZIGBEE_LABEL_INIT_DEVICE = 14; // Init ZNP as end-device +const uint8_t ZIGBEE_LABEL_START_DEVICE = 15; // Start ZNP as end-device +const uint8_t ZIGBEE_LABEL_START_ROUTER_DEVICE = 16; // Start common to router and device const uint8_t ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST = 19; // common post configuration for router and device const uint8_t ZIGBEE_LABEL_READY = 20; // goto label 20 for main loop const uint8_t ZIGBEE_LABEL_MAIN_LOOP = 21; // main loop @@ -400,7 +401,7 @@ void Z_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_pani const char kCheckingDeviceConfiguration[] PROGMEM = D_LOG_ZIGBEE "checking device configuration"; const char kConfiguredCoord[] PROGMEM = "Configured, starting coordinator"; const char kConfiguredRouter[] PROGMEM = "Configured, starting router"; -const char kConfiguredDevice[] PROGMEM = "Configured, starting end-device"; +const char kConfiguredDevice[] PROGMEM = "Configured, starting device"; const char kStarted[] PROGMEM = "Started"; const char kZigbeeStarted[] PROGMEM = D_LOG_ZIGBEE "Zigbee started"; const char kResetting[] PROGMEM = "Resetting configuration"; @@ -426,7 +427,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_WAIT_RECV_FUNC(2000, ZBR_VERSION, &Z_ReceiveCheckVersion) // Check if version is valid // Dispatching whether coordinator, router or end-device - ZI_CALL(&Z_SwitchDeviceType, 0) // goto ZIGBEE_LABEL_START_ROUTER, ZIGBEE_LABEL_START_DEVICE or continue if coordinator + ZI_CALL(&Z_SwitchDeviceType, 0) // goto ZIGBEE_LABEL_INIT_ROUTER, ZIGBEE_LABEL_INIT_DEVICE or continue if coordinator // ====================================================================== // Start as Zigbee Coordinator @@ -537,8 +538,9 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_SEND(ZBS_LOGTYPE) // check the logical type ZI_WAIT_RECV(1000, ZBS_LOGTYPE_ROUTER) // it should be coordinator - ZI_LABEL(ZIGBEE_LABEL_START_ROUTER) // Init as a router + // ZI_LABEL(ZIGBEE_LABEL_START_ROUTER) // Init as a router ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredRouter) + ZI_LABEL(ZIGBEE_LABEL_START_ROUTER_DEVICE) ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) ZI_SEND(ZBS_AF_REGISTER_ALL) // Z_AF register for endpoint 01, profile 0x0104 Home Automation ZI_WAIT_RECV(1000, ZBR_AF_REGISTER) @@ -570,7 +572,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_SEND(ZBS_WNV_ZNPHC) // Write NV ZNP Has Configured ZI_WAIT_RECV(1000, ZBR_WNV_OK) - ZI_GOTO(ZIGBEE_LABEL_START_ROUTER) + ZI_GOTO(ZIGBEE_LABEL_START_ROUTER_DEVICE) // ====================================================================== // Start as Zigbee Device @@ -583,7 +585,8 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_SEND(ZBS_LOGTYPE) // check the logical type ZI_WAIT_RECV(1000, ZBS_LOGTYPE_DEVICE) // it should be coordinator - ZI_GOTO(ZIGBEE_LABEL_START_ROUTER) + ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredDevice) + ZI_GOTO(ZIGBEE_LABEL_START_ROUTER_DEVICE) ZI_LABEL(ZIGBEE_LABEL_FACT_RESET_DEVICE) // Factory reset for router ZI_MQTT_STATE(ZIGBEE_STATUS_RESET_CONF, kResetting) diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index ffe108c5a..0b1144eb5 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -653,13 +653,16 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { JsonObject& json = jsonBuffer.createObject(); if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_DEFAULT_RESPONSE == zcl_received.getCmdId())) { - zcl_received.parseResponse(); + zcl_received.parseResponse(); // Zigbee general "Degault Response", publish ZbResponse message } else { // Build the ZbReceive json if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_REPORT_ATTRIBUTES == zcl_received.getCmdId())) { - zcl_received.parseRawAttributes(json); + zcl_received.parseRawAttributes(json); // Zigbee report attributes from sensors if (clusterid) { defer_attributes = true; } // don't defer system Cluster=0 messages } else if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_READ_ATTRIBUTES_RESPONSE == zcl_received.getCmdId())) { + zcl_received.parseReadAttributesResponse(json); + if (clusterid) { defer_attributes = true; } // don't defer system Cluster=0 messages + } else if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_READ_ATTRIBUTES == zcl_received.getCmdId())) { zcl_received.parseReadAttributes(json); if (clusterid) { defer_attributes = true; } // don't defer system Cluster=0 messages } else if (zcl_received.isClusterSpecificCommand()) { diff --git a/tasmota/xdrv_23_zigbee_9_impl.ino b/tasmota/xdrv_23_zigbee_9_impl.ino index 5c5181b6d..38627f91f 100644 --- a/tasmota/xdrv_23_zigbee_9_impl.ino +++ b/tasmota/xdrv_23_zigbee_9_impl.ino @@ -32,7 +32,7 @@ TasmotaSerial *ZigbeeSerial = nullptr; const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEE_PERMITJOIN "|" D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" - D_CMND_ZIGBEE_PROBE "|" D_CMND_ZIGBEE_READ "|" D_CMND_ZIGBEEZNPRECEIVE "|" + D_CMND_ZIGBEE_PROBE "|" D_CMND_ZIGBEEZNPRECEIVE "|" D_CMND_ZIGBEE_FORGET "|" D_CMND_ZIGBEE_SAVE "|" D_CMND_ZIGBEE_NAME "|" D_CMND_ZIGBEE_BIND "|" D_CMND_ZIGBEE_UNBIND "|" D_CMND_ZIGBEE_PING "|" D_CMND_ZIGBEE_MODELID "|" D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" @@ -42,7 +42,7 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix void (* const ZigbeeCommand[])(void) PROGMEM = { &CmndZbZNPSend, &CmndZbPermitJoin, &CmndZbStatus, &CmndZbReset, &CmndZbSend, - &CmndZbProbe, &CmndZbRead, &CmndZbZNPReceive, + &CmndZbProbe, &CmndZbZNPReceive, &CmndZbForget, &CmndZbSave, &CmndZbName, &CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId, &CmndZbLight, &CmndZbRestore, &CmndZbBindState, @@ -393,9 +393,301 @@ void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint, } } +// Parse "Report" or "Write" attribute +void ZbSendReportWrite(const JsonVariant &val_pubwrite, uint16_t device, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint16_t manuf, bool write) { + SBuffer buf(200); // buffer to store the binary output of attibutes + + const JsonObject &attrs = val_pubwrite.as(); + // iterate on keys + for (JsonObject::const_iterator it=attrs.begin(); it!=attrs.end(); ++it) { + const char *key = it->key; + const JsonVariant &value = it->value; + + uint16_t attr_id = 0xFFFF; + uint16_t cluster_id = 0xFFFF; + uint8_t type_id = Znodata; + + // check if the name has the format "XXXX/YYYY" where XXXX is the cluster, YYYY the attribute id + // alternative "XXXX/YYYY%ZZ" where ZZ is the type (for unregistered attributes) + char * delimiter = strchr(key, '/'); + char * delimiter2 = strchr(key, '%'); + if (delimiter) { + cluster_id = strtoul(key, &delimiter, 16); + if (!delimiter2) { + attr_id = strtoul(delimiter+1, nullptr, 16); + } else { + attr_id = strtoul(delimiter+1, &delimiter2, 16); + type_id = strtoul(delimiter2+1, nullptr, 16); + } + } + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("cluster_id = 0x%04X, attr_id = 0x%04X"), cluster_id, attr_id); + + // do we already know the type, i.e. attribute and cluster are also known + if (Znodata == type_id) { + // scan attributes to find by name, and retrieve type + for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + const Z_AttributeConverter *converter = &Z_PostProcess[i]; + bool match = false; + uint16_t local_attr_id = pgm_read_word(&converter->attribute); + uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short)); + uint8_t local_type_id = pgm_read_byte(&converter->type); + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Try cluster = 0x%04X, attr = 0x%04X, type_id = 0x%02X"), local_cluster_id, local_attr_id, local_type_id); + + if (delimiter) { + if ((cluster_id == local_cluster_id) && (attr_id == local_attr_id)) { + type_id = local_type_id; + break; + } + } else if (converter->name) { + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Comparing '%s' with '%s'"), attr_name, converter->name); + if (0 == strcasecmp_P(key, converter->name)) { + // match + cluster_id = local_cluster_id; + attr_id = local_attr_id; + type_id = local_type_id; + break; + } + } + } + } + + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("cluster_id = 0x%04X, attr_id = 0x%04X, type_id = 0x%02X"), cluster_id, attr_id, type_id); + if ((0xFFFF == attr_id) || (0xFFFF == cluster_id)) { + Response_P(PSTR("{\"%s\":\"%s'%s'\"}"), XdrvMailbox.command, PSTR("Unknown attribute "), key); + return; + } + if (Znodata == type_id) { + Response_P(PSTR("{\"%s\":\"%s'%s'\"}"), XdrvMailbox.command, PSTR("Unknown attribute type for attribute "), key); + return; + } + + if (0xFFFF == cluster) { + cluster = cluster_id; // set the cluster for this packet + } else if (cluster != cluster_id) { + ResponseCmndChar_P(PSTR("No more than one cluster id per command")); + return; + } + // push the value in the buffer + int32_t res = encodeSingleAttribute(buf, value, attr_id, type_id); + if (res < 0) { + Response_P(PSTR("{\"%s\":\"%s'%s' 0x%02X\"}"), XdrvMailbox.command, PSTR("Unsupported attribute type "), key, type_id); + return; + } + } + + // did we have any attribute? + if (0 == buf.len()) { + ResponseCmndChar_P(PSTR("No attribute in list")); + return; + } + + // all good, send the packet + ZigbeeZCLSend_Raw(device, groupaddr, cluster, endpoint, write ? ZCL_WRITE_ATTRIBUTES : ZCL_REPORT_ATTRIBUTES, false /* not cluster specific */, manuf, buf.getBuffer(), buf.len(), false /* noresponse */, zigbee_devices.getNextSeqNumber(device)); + ResponseCmndDone(); +} + +// Parse the "Send" attribute and send the command +void ZbSendSend(const JsonVariant &val_cmd, uint16_t device, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint16_t manuf) { + uint8_t cmd = 0; + String cmd_str = ""; // the actual low-level command, either specified or computed + const char *cmd_s; // pointer to payload string + bool clusterSpecific = true; + + static char delim[] = ", "; // delimiters for parameters + // probe the type of the argument + // If JSON object, it's high level commands + // If String, it's a low level command + if (val_cmd.is()) { + // we have a high-level command + const JsonObject &cmd_obj = val_cmd.as(); + int32_t cmd_size = cmd_obj.size(); + if (cmd_size > 1) { + Response_P(PSTR("Only 1 command allowed (%d)"), cmd_size); + return; + } else if (1 == cmd_size) { + // We have exactly 1 command, parse it + JsonObject::const_iterator it = cmd_obj.begin(); // just get the first key/value + String key = it->key; + const JsonVariant& value = it->value; + uint32_t x = 0, y = 0, z = 0; + uint16_t cmd_var; + + const __FlashStringHelper* tasmota_cmd = zigbeeFindCommand(key.c_str(), &cluster, &cmd_var); + if (tasmota_cmd) { + cmd_str = tasmota_cmd; + } else { + Response_P(PSTR("Unrecognized zigbee command: %s"), key.c_str()); + return; + } + + // parse the JSON value, depending on its type fill in x,y,z + if (value.is()) { + x = value.as() ? 1 : 0; + } else if (value.is()) { + x = value.as(); + } else { + // if non-bool or non-int, trying char* + const char *s_const = value.as(); + if (s_const != nullptr) { + char s[strlen(s_const)+1]; + strcpy(s, s_const); + if ((nullptr != s) && (0x00 != *s)) { // ignore any null or empty string, could represent 'null' json value + char *sval = strtok(s, delim); + if (sval) { + x = ZigbeeAliasOrNumber(sval); + sval = strtok(nullptr, delim); + if (sval) { + y = ZigbeeAliasOrNumber(sval); + sval = strtok(nullptr, delim); + if (sval) { + z = ZigbeeAliasOrNumber(sval); + } + } + } + } + } + } + + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: command_template = %s"), cmd_str.c_str()); + if (0xFF == cmd_var) { // if command number is a variable, replace it with x + cmd = x; + x = y; // and shift other variables + y = z; + } else { + cmd = cmd_var; // or simply copy the cmd number + } + cmd_str = zigbeeCmdAddParams(cmd_str.c_str(), x, y, z); // fill in parameters + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: command_final = %s"), cmd_str.c_str()); + cmd_s = cmd_str.c_str(); + } else { + // we have zero command, pass through until last error for missing command + } + } else if (val_cmd.is()) { + // low-level command + cmd_str = val_cmd.as(); + // Now parse the string to extract cluster, command, and payload + // Parse 'cmd' in the form "AAAA_BB/CCCCCCCC" or "AAAA!BB/CCCCCCCC" + // where AA is the cluster number, BBBB the command number, CCCC... the payload + // First delimiter is '_' for a global command, or '!' for a cluster specific command + const char * data = cmd_str.c_str(); + cluster = parseHex(&data, 4); + + // delimiter + if (('_' == *data) || ('!' == *data)) { + if ('_' == *data) { clusterSpecific = false; } + data++; + } else { + ResponseCmndChar_P(PSTR("Wrong delimiter for payload")); + return; + } + // parse cmd number + cmd = parseHex(&data, 2); + + // move to end of payload + // delimiter is optional + if ('/' == *data) { data++; } // skip delimiter + + cmd_s = data; + } else { + // we have an unsupported command type, just ignore it and fallback to missing command + } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZigbeeZCLSend device: 0x%04X, group: 0x%04X, endpoint:%d, cluster:0x%04X, cmd:0x%02X, send:\"%s\""), + device, groupaddr, endpoint, cluster, cmd, cmd_s); + zigbeeZCLSendStr(device, groupaddr, endpoint, clusterSpecific, manuf, cluster, cmd, cmd_s); + ResponseCmndDone(); +} + + +// Parse the "Send" attribute and send the command +void ZbSendRead(const JsonVariant &val_attr, uint16_t device, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint16_t manuf) { + // ZbSend {"Device":"0xF289","Cluster":0,"Endpoint":3,"Read":5} + // ZbSend {"Device":"0xF289","Cluster":"0x0000","Endpoint":"0x0003","Read":"0x0005"} + // ZbSend {"Device":"0xF289","Cluster":0,"Endpoint":3,"Read":[5,6,7,4]} + // ZbSend {"Device":"0xF289","Endpoint":3,"Read":{"ModelId":true}} + // ZbSend {"Device":"0xF289","Read":{"ModelId":true}} + + // params + size_t attrs_len = 0; + uint8_t* attrs = nullptr; // empty string is valid + + uint16_t val = strToUInt(val_attr); + if (val_attr.is()) { + const JsonArray& attr_arr = val_attr.as(); + attrs_len = attr_arr.size() * 2; + attrs = new uint8_t[attrs_len]; + + uint32_t i = 0; + for (auto value : attr_arr) { + uint16_t val = strToUInt(value); + attrs[i++] = val & 0xFF; + attrs[i++] = val >> 8; + } + } else if (val_attr.is()) { + const JsonObject& attr_obj = val_attr.as(); + attrs_len = attr_obj.size() * 2; + attrs = new uint8_t[attrs_len]; + uint32_t actual_attr_len = 0; + + // iterate on keys + for (JsonObject::const_iterator it=attr_obj.begin(); it!=attr_obj.end(); ++it) { + const char *key = it->key; + // const JsonVariant &value = it->value; // we don't need the value here, only keys are relevant + + bool found = false; + // scan attributes to find by name, and retrieve type + for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + const Z_AttributeConverter *converter = &Z_PostProcess[i]; + bool match = false; + uint16_t local_attr_id = pgm_read_word(&converter->attribute); + uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short)); + // uint8_t local_type_id = pgm_read_byte(&converter->type); + + if ((converter->name) && (0 == strcasecmp_P(key, converter->name))) { + // match name + // check if there is a conflict with cluster + // TODO + attrs[actual_attr_len++] = local_attr_id & 0xFF; + attrs[actual_attr_len++] = local_attr_id >> 8; + found = true; + break; // found, exit loop + } + } + if (!found) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: Unknown attribute name (ignored): %s"), key); + } + } + + attrs_len = actual_attr_len; + } else { + attrs_len = 2; + attrs = new uint8_t[attrs_len]; + attrs[0] = val & 0xFF; // little endian + attrs[1] = val >> 8; + } + + if (attrs_len > 0) { + ZigbeeZCLSend_Raw(device, groupaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, manuf, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(device)); + ResponseCmndDone(); + } else { + ResponseCmndChar_P(PSTR("Missing parameters")); + } + + if (attrs) { delete[] attrs; } +} + // // Command `ZbSend` // +// Examples: +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"0006/0000":0}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"Power":0}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"AqaraRotate":0}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"AqaraRotate":12.5}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"006/0000%39":12.5}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"AnalogInApplicationType":1000000}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"TimeZone":-1000000}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"Manufacturer":"Tasmota","ModelId":"Tasmota Z2T Router"}} void CmndZbSend(void) { // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":1} } // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":"3"} } @@ -405,7 +697,7 @@ void CmndZbSend(void) { // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":true} } // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":"true"} } // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"ShutterClose":null} } - // ZbSend { "devicse":"0x1234", "endpoint":"0x03", "send":{"Power":1} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":1} } // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Color":"1,2"} } // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Color":"0x1122,0xFFEE"} } if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } @@ -414,26 +706,21 @@ void CmndZbSend(void) { if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } // params - static char delim[] = ", "; // delimiters for parameters - uint16_t device = BAD_SHORTADDR; // 0x0000 is local, so considered invalid - uint16_t groupaddr = 0x0000; // group address - uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint - uint16_t manuf = 0x0000; // Manuf Id in ZCL frame - // Command elements - uint16_t cluster = 0; - uint8_t cmd = 0; - String cmd_str = ""; // the actual low-level command, either specified or computed - const char *cmd_s; // pointer to payload string - bool clusterSpecific = true; + uint16_t device = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid + uint16_t groupaddr = 0x0000; // group address valid only if device == BAD_SHORTADDR + uint16_t cluster = 0xFFFF; // no default + uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint + uint16_t manuf = 0x0000; // Manuf Id in ZCL frame - // parse JSON - const JsonVariant &val_device = GetCaseInsensitive(json, PSTR("Device")); + + // parse "Device" and "Group" + const JsonVariant &val_device = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_DEVICE)); if (nullptr != &val_device) { device = zigbee_devices.parseDeviceParam(val_device.as()); if (BAD_SHORTADDR == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } } if (BAD_SHORTADDR == device) { // if not found, check if we have a group - const JsonVariant &val_group = GetCaseInsensitive(json, PSTR("Group")); + const JsonVariant &val_group = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_GROUP)); if (nullptr != &val_group) { groupaddr = strToUInt(val_group); } else { // no device nor group @@ -442,116 +729,54 @@ void CmndZbSend(void) { } } - const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR("Endpoint")); + // read other parameters + const JsonVariant &val_cluster = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_CLUSTER)); + if (nullptr != &val_cluster) { cluster = strToUInt(val_cluster); } + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_ENDPOINT)); if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } - const JsonVariant &val_manuf = GetCaseInsensitive(json, PSTR("Manuf")); + const JsonVariant &val_manuf = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_MANUF)); if (nullptr != &val_manuf) { manuf = strToUInt(val_manuf); } - const JsonVariant &val_cmd = GetCaseInsensitive(json, PSTR("Send")); + + // infer endpoint + if (BAD_SHORTADDR == device) { + endpoint = 0xFF; // endpoint not used for group addresses + } else if (0 == endpoint) { + endpoint = zigbee_devices.findFirstEndpoint(device); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: guessing endpoint %d"), endpoint); + } + + const JsonVariant &val_cmd = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_SEND)); + const JsonVariant &val_read = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_READ)); + const JsonVariant &val_write = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_WRITE)); + const JsonVariant &val_publish = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_REPORT)); + uint32_t multi_cmd = (nullptr != &val_cmd) + (nullptr != &val_read) + (nullptr != &val_write) + (nullptr != &val_publish); + if (multi_cmd > 1) { + ResponseCmndChar_P(PSTR("Can only have one of: 'Send', 'Read', 'Write' or 'Report'")); + return; + } + if (nullptr != &val_cmd) { - // probe the type of the argument - // If JSON object, it's high level commands - // If String, it's a low level command - if (val_cmd.is()) { - // we have a high-level command - const JsonObject &cmd_obj = val_cmd.as(); - int32_t cmd_size = cmd_obj.size(); - if (cmd_size > 1) { - Response_P(PSTR("Only 1 command allowed (%d)"), cmd_size); - return; - } else if (1 == cmd_size) { - // We have exactly 1 command, parse it - JsonObject::const_iterator it = cmd_obj.begin(); // just get the first key/value - String key = it->key; - const JsonVariant& value = it->value; - uint32_t x = 0, y = 0, z = 0; - uint16_t cmd_var; - - const __FlashStringHelper* tasmota_cmd = zigbeeFindCommand(key.c_str(), &cluster, &cmd_var); - if (tasmota_cmd) { - cmd_str = tasmota_cmd; - } else { - Response_P(PSTR("Unrecognized zigbee command: %s"), key.c_str()); - return; - } - - // parse the JSON value, depending on its type fill in x,y,z - if (value.is()) { - x = value.as() ? 1 : 0; - } else if (value.is()) { - x = value.as(); - } else { - // if non-bool or non-int, trying char* - const char *s_const = value.as(); - if (s_const != nullptr) { - char s[strlen(s_const)+1]; - strcpy(s, s_const); - if ((nullptr != s) && (0x00 != *s)) { // ignore any null or empty string, could represent 'null' json value - char *sval = strtok(s, delim); - if (sval) { - x = ZigbeeAliasOrNumber(sval); - sval = strtok(nullptr, delim); - if (sval) { - y = ZigbeeAliasOrNumber(sval); - sval = strtok(nullptr, delim); - if (sval) { - z = ZigbeeAliasOrNumber(sval); - } - } - } - } - } - } - - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: command_template = %s"), cmd_str.c_str()); - if (0xFF == cmd_var) { // if command number is a variable, replace it with x - cmd = x; - x = y; // and shift other variables - y = z; - } else { - cmd = cmd_var; // or simply copy the cmd number - } - cmd_str = zigbeeCmdAddParams(cmd_str.c_str(), x, y, z); // fill in parameters - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: command_final = %s"), cmd_str.c_str()); - cmd_s = cmd_str.c_str(); - } else { - // we have zero command, pass through until last error for missing command - } - } else if (val_cmd.is()) { - // low-level command - cmd_str = val_cmd.as(); - // Now parse the string to extract cluster, command, and payload - // Parse 'cmd' in the form "AAAA_BB/CCCCCCCC" or "AAAA!BB/CCCCCCCC" - // where AA is the cluster number, BBBB the command number, CCCC... the payload - // First delimiter is '_' for a global command, or '!' for a cluster specific command - const char * data = cmd_str.c_str(); - cluster = parseHex(&data, 4); - - // delimiter - if (('_' == *data) || ('!' == *data)) { - if ('_' == *data) { clusterSpecific = false; } - data++; - } else { - ResponseCmndChar_P(PSTR("Wrong delimiter for payload")); - return; - } - // parse cmd number - cmd = parseHex(&data, 2); - - // move to end of payload - // delimiter is optional - if ('/' == *data) { data++; } // skip delimiter - - cmd_s = data; - } else { - // we have an unsupported command type, just ignore it and fallback to missing command + // "Send":{...commands...} + ZbSendSend(val_cmd, device, groupaddr, cluster, endpoint, manuf); + } else if (nullptr != &val_read) { + // "Read":{...attributes...}, "Read":attribute or "Read":[...attributes...] + ZbSendRead(val_read, device, groupaddr, cluster, endpoint, manuf); + } else if (nullptr != &val_write) { + if ((0 == endpoint) || (!val_write.is())) { + ResponseCmndChar_P(PSTR("Missing parameters")); + return; } - - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZigbeeZCLSend device: 0x%04X, group: 0x%04X, endpoint:%d, cluster:0x%04X, cmd:0x%02X, send:\"%s\""), - device, groupaddr, endpoint, cluster, cmd, cmd_s); - zigbeeZCLSendStr(device, groupaddr, endpoint, clusterSpecific, manuf, cluster, cmd, cmd_s); - ResponseCmndDone(); + // "Write":{...attributes...} + ZbSendReportWrite(val_write, device, groupaddr, cluster, endpoint, manuf, true /* write */); + } else if (nullptr != &val_publish) { + if ((0 == endpoint) || (!val_publish.is())) { + ResponseCmndChar_P(PSTR("Missing parameters")); + return; + } + // "Report":{...attributes...} + ZbSendReportWrite(val_publish, device, groupaddr, cluster, endpoint, manuf, false /* report */); } else { - Response_P(PSTR("Missing zigbee 'Send'")); + Response_P(PSTR("Missing zigbee 'Send', 'Write' or 'Report'")); return; } } @@ -570,7 +795,6 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } // params - // static char delim[] = ", "; // delimiters for parameters uint16_t srcDevice = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid uint16_t dstDevice = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid uint64_t dstLongAddr = 0; @@ -582,7 +806,7 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind // Information about source device: "Device", "Endpoint", "Cluster" // - the source endpoint must have a known IEEE address - const JsonVariant &val_device = GetCaseInsensitive(json, PSTR("Device")); + const JsonVariant &val_device = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_DEVICE)); if (nullptr != &val_device) { srcDevice = zigbee_devices.parseDeviceParam(val_device.as()); } @@ -591,10 +815,10 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind uint64_t srcLongAddr = zigbee_devices.getDeviceLongAddr(srcDevice); if (0 == srcLongAddr) { ResponseCmndChar_P(PSTR("Unknown source IEEE address")); return; } // look for source endpoint - const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR("Endpoint")); + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_ENDPOINT)); if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } // look for source cluster - const JsonVariant &val_cluster = GetCaseInsensitive(json, PSTR("Cluster")); + const JsonVariant &val_cluster = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_CLUSTER)); if (nullptr != &val_cluster) { cluster = strToUInt(val_cluster); } // Either Device address @@ -885,90 +1109,6 @@ void CmndZbRestore(void) { ResponseCmndDone(); } -// -// Command `ZbRead` -// Send an attribute read command to a device, specifying cluster and list of attributes -// -void CmndZbRead(void) { - // ZbRead {"Device":"0xF289","Cluster":0,"Endpoint":3,"Attr":5} - // ZbRead {"Device":"0xF289","Cluster":"0x0000","Endpoint":"0x0003","Attr":"0x0005"} - // ZbRead {"Device":"0xF289","Cluster":0,"Endpoint":3,"Attr":[5,6,7,4]} - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - DynamicJsonBuffer jsonBuf; - JsonObject &json = jsonBuf.parseObject((const char*) XdrvMailbox.data); - if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } - - // params - uint16_t device = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid - uint16_t groupaddr = 0x0000; // if 0x0000 ignore group adress - uint16_t cluster = 0x0000; // default to general cluster - uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint - uint16_t manuf = 0x0000; // Manuf Id in ZCL frame - size_t attrs_len = 0; - uint8_t* attrs = nullptr; // empty string is valid - - const JsonVariant &val_device = GetCaseInsensitive(json, PSTR("Device")); - if (nullptr != &val_device) { - device = zigbee_devices.parseDeviceParam(val_device.as()); - if (BAD_SHORTADDR == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - } - if (BAD_SHORTADDR == device) { // if not found, check if we have a group - const JsonVariant &val_group = GetCaseInsensitive(json, PSTR("Group")); - if (nullptr != &val_group) { - groupaddr = strToUInt(val_group); - } else { // no device nor group - ResponseCmndChar_P(PSTR("Unknown device")); - return; - } - } - - const JsonVariant &val_cluster = GetCaseInsensitive(json, PSTR("Cluster")); - if (nullptr != &val_cluster) { cluster = strToUInt(val_cluster); } - const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR("Endpoint")); - if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } - const JsonVariant &val_manuf = GetCaseInsensitive(json, PSTR("Manuf")); - if (nullptr != &val_manuf) { manuf = strToUInt(val_manuf); } - - const JsonVariant &val_attr = GetCaseInsensitive(json, PSTR("Read")); - if (nullptr != &val_attr) { - uint16_t val = strToUInt(val_attr); - if (val_attr.is()) { - const JsonArray& attr_arr = val_attr.as(); - attrs_len = attr_arr.size() * 2; - attrs = new uint8_t[attrs_len]; - - uint32_t i = 0; - for (auto value : attr_arr) { - uint16_t val = strToUInt(value); - attrs[i++] = val & 0xFF; - attrs[i++] = val >> 8; - } - } else { - attrs_len = 2; - attrs = new uint8_t[attrs_len]; - attrs[0] = val & 0xFF; // little endian - attrs[1] = val >> 8; - } - } - - if ((0 == endpoint) && (device)) { // try to compute the endpoint - endpoint = zigbee_devices.findFirstEndpoint(device); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbRead: guessing endpoint 0x%02X"), endpoint); - } - if (BAD_SHORTADDR == device) { - endpoint = 0xFF; // endpoint not used for group addresses - } - - if ((0 != endpoint) && (attrs_len > 0)) { - ZigbeeZCLSend_Raw(device, groupaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, manuf, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(device)); - ResponseCmndDone(); - } else { - ResponseCmndChar_P(PSTR("Missing parameters")); - } - - if (attrs) { delete[] attrs; } -} - // // Command `ZbPermitJoin` // Allow or Deny pairing of new Zigbee devices From ce3dfd1066de1ae6ee63276c41b619ce652148ff Mon Sep 17 00:00:00 2001 From: rando-calrissian <37273799+rando-calrissian@users.noreply.github.com> Date: Fri, 29 May 2020 15:41:49 -0700 Subject: [PATCH 120/581] Add files via upload Added ESP32 support for changing the displayed temperature unit on LYWSD02 BLE device --- tasmota/xsns_62_MI_ESP32.ino | 435 +++++++++++++++++++---------------- 1 file changed, 236 insertions(+), 199 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 1844edc2c..264ffbb52 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -229,18 +229,26 @@ class MI32SensorCallback : public NimBLEClientCallbacks { class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { void onResult(NimBLEAdvertisedDevice* advertisedDevice) { - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice.getAddress().toString().c_str(),advertisedDevice.getServiceData().length()); - if (advertisedDevice->getServiceData().length() == 0) return; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + if (advertisedDevice->getServiceData().length() == 0) { + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + MI32Scan->erase(advertisedDevice->getAddress()); + return; + } uint16_t uuid = advertisedDevice->getServiceDataUUID().getNative()->u16.value; - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%x"),uuid); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("UUID: %x"),uuid); uint8_t addr[6]; memcpy(addr,advertisedDevice->getAddress().getNative(),6); MI32_ReverseMAC(addr); if(uuid==0xfe95) { - MI32ParseResponse((char*)advertisedDevice->getServiceData().c_str(),advertisedDevice->getServiceData().length(), addr); + MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); } else if(uuid==0xfdcd) { - MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().c_str(),advertisedDevice->getServiceData().length(), addr); + MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); + } + else { + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + MI32Scan->erase(advertisedDevice->getAddress()); } }; }; @@ -399,47 +407,57 @@ void MI32StartTask(uint32_t task){ } } -void MI32ConnectActiveSensor(){ // only use inside a task !! +bool MI32ConnectActiveSensor(){ // only use inside a task !! + MI32.mode.connected = 0; MI32Client = nullptr; - esp_bd_addr_t address; - memcpy(address,MIBLEsensors[MI32.state.sensor].serial,sizeof(address)); + Wifi.counter = Wifi.counter + 20; // hopefully less interference + NimBLEAddress _address = NimBLEAddress(MIBLEsensors[MI32.state.sensor].serial); if(NimBLEDevice::getClientListSize()) { - MI32Client = NimBLEDevice::getClientByPeerAddress(NimBLEAddress(address)); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: found any clients in the cList"),D_CMND_MI32); + MI32Client = NimBLEDevice::getClientByPeerAddress(_address); if(MI32Client){ - if(!MI32Client->connect(NimBLEAddress(address), 0,false)) { - MI32.mode.willConnect = 0; - vTaskDelete( NULL ); - } + // Should be impossible + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: got connected client"),D_CMND_MI32); } else { + // Should be the norm after the first iteration MI32Client = NimBLEDevice::getDisconnectedClient(); + DEBUG_SENSOR_LOG(PSTR("%s: got disconnected client"),D_CMND_MI32); } } + + if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { + MI32.mode.willConnect = 0; + DEBUG_SENSOR_LOG(PSTR("%s: max connection already reached"),D_CMND_MI32); + return false; + } if(!MI32Client) { - if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { - MI32.mode.willConnect = 0; - vTaskDelete( NULL ); - } + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: will create client"),D_CMND_MI32); MI32Client = NimBLEDevice::createClient(); MI32Client->setClientCallbacks(&MI32SensorCB , false); - MI32Client->setConnectionParams(12,12,0,51); - MI32Client->setConnectTimeout(10); - if (!MI32Client->connect(NimBLEAddress(address),0,false)) { - MI32.mode.willConnect = 0; - NimBLEDevice::deleteClient(MI32Client); - vTaskDelete( NULL ); - } + MI32Client->setConnectionParams(12,12,0,48); + MI32Client->setConnectTimeout(30); } + if (!MI32Client->connect(_address,false)) { + MI32.mode.willConnect = 0; + NimBLEDevice::deleteClient(MI32Client); + DEBUG_SENSOR_LOG(PSTR("%s: did not connect client"),D_CMND_MI32); + return false; + } + DEBUG_SENSOR_LOG(PSTR("%s: did create new client"),D_CMND_MI32); + return true; + // } } void MI32StartScanTask(){ if (MI32.mode.connected) return; MI32.mode.runningScan = 1; + // Wifi.counter = Wifi.counter + 3; xTaskCreatePinnedToCore( MI32ScanTask, /* Function to implement the task */ "MI32ScanTask", /* Name of the task */ - 4096, /* Stack size in words */ + 8192, /* Stack size in words */ NULL, /* Task input parameter */ 0, /* Priority of the task */ NULL, /* Task handle. */ @@ -448,17 +466,18 @@ void MI32StartScanTask(){ } void MI32ScanTask(void *pvParameters){ - NimBLEScan* pScan = NimBLEDevice::getScan(); - pScan->setAdvertisedDeviceCallbacks(&MI32ScanCallbacks); - pScan->setActiveScan(false); - pScan->start(5, MI32scanEndedCB); // hard coded duration + if (MI32Scan == nullptr) MI32Scan = NimBLEDevice::getScan(); + DEBUG_SENSOR_LOG(PSTR("%s: Scan Cache Length: %u"),D_CMND_MI32, MI32Scan->getResults().getCount()); + MI32Scan->setAdvertisedDeviceCallbacks(&MI32ScanCallbacks); + MI32Scan->setActiveScan(false); + MI32Scan->start(5, MI32scanEndedCB, true); // hard coded duration uint32_t timer = 0; while (MI32.mode.runningScan){ if (timer>15){ vTaskDelete( NULL ); } timer++; - vTaskDelay(1000); + vTaskDelay(1000/ portTICK_PERIOD_MS); } vTaskDelete( NULL ); } @@ -482,47 +501,62 @@ void MI32SensorTask(void *pvParameters){ MI32.mode.willConnect = 0; vTaskDelete( NULL ); } - MI32ConnectActiveSensor(); - MI32.mode.readingDone = 1; - switch(MIBLEsensors[MI32.state.sensor].type){ - case LYWSD03MMC: - MI32.mode.readingDone = 0; - MI32connectLYWSD03(); - break; - default: - break; - } - uint32_t timer = 0; - while (!MI32.mode.readingDone){ - if (timer>150){ + if (MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + MI32Client->disconnect(); + NimBLEDevice::deleteClient(MI32Client); + MI32.mode.willConnect = 0; + vTaskDelay(100/ portTICK_PERIOD_MS); + vTaskDelete( NULL ); + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); + } + + timer = 150; + switch(MIBLEsensors[MI32.state.sensor].type){ + case LYWSD03MMC: + MI32.mode.readingDone = 0; + if(MI32connectLYWSD03forNotification()) timer=0; + break; + default: break; } - timer++; - vTaskDelay(100); + + while (!MI32.mode.readingDone){ + if (timer>150){ + break; + } + timer++; + vTaskDelay(100/ portTICK_PERIOD_MS); + } + MI32Client->disconnect(); + DEBUG_SENSOR_LOG(PSTR("%s: requested disconnect"),D_CMND_MI32); } - MI32Client->disconnect(); - NimBLEDevice::deleteClient(MI32Client); - vTaskDelay(500); + vTaskDelay(500/ portTICK_PERIOD_MS); MI32.mode.connected = 0; vTaskDelete( NULL ); } -void MI32connectLYWSD03(){ +bool MI32connectLYWSD03forNotification(){ NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"); - static BLEUUID charUUID("ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6"); + static BLEUUID serviceUUID(0xebe0ccb0,0x7a0a,0x4b0c,0x8a1a6ff2997da3a6); + static BLEUUID charUUID(0xebe0ccc1,0x7a0a,0x4b0c,0x8a1a6ff2997da3a6); pSvc = MI32Client->getService(serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(charUUID); } - if(pChr->canNotify()) { - if(!pChr->registerForNotify(MI32notifyCB)) { - MI32.mode.willConnect = 0; - MI32Client->disconnect(); - return; + if (pChr){ + if(pChr->canNotify()) { + if(pChr->registerForNotify(MI32notifyCB)) { + return true; + } } } + return false; } void MI32StartTimeTask(){ @@ -544,45 +578,48 @@ void MI32TimeTask(void *pvParameters){ MI32.mode.shallSetTime = 0; vTaskDelete( NULL ); } - MI32ConnectActiveSensor(); - uint32_t timer = 0; - while (MI32.mode.connected == 0){ - if (timer>1000){ - break; + if(MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); } - timer++; - vTaskDelay(10); - } - NimBLERemoteService* pSvc = nullptr; - NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); - static BLEUUID charUUID("EBE0CCB7-7A0A-4B0C-8A1A-6FF2997DA3A6"); - pSvc = MI32Client->getService(serviceUUID); - if(pSvc) { - pChr = pSvc->getCharacteristic(charUUID); - } - if(pChr->canWrite()) { - union { - uint8_t buf[5]; - uint32_t time; - } _utc; - _utc.time = Rtc.utc_time; - _utc.buf[4] = Rtc.time_timezone / 60; + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + static BLEUUID charUUID(0xEBE0CCB7,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + pSvc = MI32Client->getService(serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(charUUID); - if(!pChr->writeValue(_utc.buf,sizeof(_utc.buf),true)) { // true is important ! - MI32.mode.willConnect = 0; - MI32Client->disconnect(); } - else { - MI32.mode.shallSetTime = 0; - MI32.mode.willSetTime = 0; + if (pChr){ + if(pChr->canWrite()) { + union { + uint8_t buf[5]; + uint32_t time; + } _utc; + _utc.time = Rtc.utc_time; + _utc.buf[4] = Rtc.time_timezone / 60; + + if(!pChr->writeValue(_utc.buf,sizeof(_utc.buf),true)) { // true is important ! + MI32.mode.willConnect = 0; + MI32Client->disconnect(); + } + else { + MI32.mode.shallSetTime = 0; + MI32.mode.willSetTime = 0; + } + } } + MI32Client->disconnect(); } - MI32Client->disconnect(); - NimBLEDevice::deleteClient(MI32Client); - vTaskDelay(500); + vTaskDelay(500/ portTICK_PERIOD_MS); MI32.mode.connected = 0; vTaskDelete( NULL ); } @@ -606,61 +643,58 @@ void MI32UnitTask(void *pvParameters){ MI32.mode.shallSetUnit = 0; vTaskDelete( NULL ); } - MI32ConnectActiveSensor(); - uint32_t timer = 0; - while (MI32.mode.connected == 0){ - if (timer>1000){ - break; + if(MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); } - timer++; - vTaskDelay(10); + + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); + static BLEUUID charUUID("EBE0CCBE-7A0A-4B0C-8A1A-6FF2997DA3A6"); + pSvc = MI32Client->getService(serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(charUUID); } - NimBLERemoteService* pSvc = nullptr; - NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); - static BLEUUID charUUID("EBE0CCBE-7A0A-4B0C-8A1A-6FF2997DA3A6"); - pSvc = MI32Client->getService(serviceUUID); - if(pSvc) { - pChr = pSvc->getCharacteristic(charUUID); - } + if(pChr->canRead()){ + uint8_t curUnit; + const char *buf = pChr->readValue().c_str(); + if( buf[0] != 0 && buf[0]<101 ){ + curUnit = buf[0]; + } - uint8_t curUnit; + if(pChr->canWrite()) { + curUnit = curUnit == 0x01?0xFF:0x01; // C/F - if(pChr->canRead()) { - const char *buf = pChr->readValue().c_str(); - if( buf[0] != 0 && buf[0]<101 ){ - curUnit = buf[0]; + if(!pChr->writeValue(&curUnit,sizeof(curUnit),true)) { // true is important ! + MI32.mode.willConnect = 0; + MI32Client->disconnect(); + } + else { + MI32.mode.shallSetUnit = 0; + MI32.mode.willSetUnit = 0; + } + } } + MI32Client->disconnect(); } - else { - return; - } - - if(pChr->canWrite()) { - curUnit = curUnit == 0x01?0xFF:0x01; // C/F - - if(!pChr->writeValue(&curUnit,sizeof(curUnit),true)) { // true is important ! - MI32.mode.willConnect = 0; - MI32Client->disconnect(); - } - else { - MI32.mode.shallSetUnit = 0; - MI32.mode.willSetUnit = 0; - } - } - MI32Client->disconnect(); - NimBLEDevice::deleteClient(MI32Client); - vTaskDelay(500); + vTaskDelay(500/ portTICK_PERIOD_MS); MI32.mode.connected = 0; vTaskDelete( NULL ); } - void MI32StartBatteryTask(){ if (MI32.mode.connected) return; MI32.mode.willReadBatt = 1; + MI32.mode.willConnect = 1; + MI32.mode.canScan = 0; xTaskCreatePinnedToCore( MI32BatteryTask, /* Function to implement the task */ "MI32BatteryTask", /* Name of the task */ @@ -684,31 +718,32 @@ void MI32BatteryTask(void *pvParameters){ } MI32.mode.connected = 0; - MI32ConnectActiveSensor(); - uint32_t timer = 0; - while (MI32.mode.connected == 0){ - if (timer>1000){ + if(MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(30/ portTICK_PERIOD_MS); + } + + switch(MIBLEsensors[MI32.state.sensor].type){ + case FLORA: + MI32batteryFLORA(); + break; + case LYWSD02: + MI32batteryLYWSD02(); + break; + case CGD1: + MI32batteryCGD1(); break; } - timer++; - vTaskDelay(10); - } - - switch(MIBLEsensors[MI32.state.sensor].type){ - case FLORA: - MI32batteryFLORA(); - break; - case LYWSD02: - MI32batteryLYWSD02(); - break; - case CGD1: - MI32batteryCGD1(); - break; - } - MI32Client->disconnect(); + MI32Client->disconnect(); + } MI32.mode.willReadBatt = 0; - NimBLEDevice::deleteClient(MI32Client); - vTaskDelay(500); + // Wifi.counter = 0; // Now check it + vTaskDelay(500/ portTICK_PERIOD_MS); MI32.mode.connected = 0; vTaskDelete( NULL ); } @@ -720,27 +755,26 @@ void MI32batteryFLORA(){ break; } timer++; - vTaskDelay(10); + vTaskDelay(10/ portTICK_PERIOD_MS); } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s connected for battery"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); + DEBUG_SENSOR_LOG(PSTR("%s connected for battery"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID FLserviceUUID("00001204-0000-1000-8000-00805f9b34fb"); - static BLEUUID FLcharUUID("00001a02-0000-1000-8000-00805f9b34fb"); + static BLEUUID FLserviceUUID(0x00001204,0x0000,0x1000,0x800000805f9b34fb); + static BLEUUID FLcharUUID(0x00001a02,0x0000,0x1000,0x800000805f9b34fb); pSvc = MI32Client->getService(FLserviceUUID); - if(pSvc) { /** make sure it's not null */ + if(pSvc) { pChr = pSvc->getCharacteristic(FLcharUUID); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: got Flora char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); } - else { - MI32.mode.readingDone = 1; - return; - } - if(pChr->canRead()) { - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); + if (pChr){ + DEBUG_SENSOR_LOG(PSTR("%s: got Flora char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + if(pChr->canRead()) { + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); + } } + MI32.mode.readingDone = 1; } void MI32batteryLYWSD02(){ @@ -750,27 +784,27 @@ void MI32batteryLYWSD02(){ break; } timer++; - vTaskDelay(10); + vTaskDelay(10/ portTICK_PERIOD_MS); } NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID LY2serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); - static BLEUUID LY2charUUID("EBE0CCC4-7A0A-4B0C-8A1A-6FF2997DA3A6"); + static BLEUUID LY2serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + static BLEUUID LY2charUUID(0xEBE0CCC4,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); pSvc = MI32Client->getService(LY2serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(LY2charUUID); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: got LYWSD02 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); } - else { - return; - } - if(pChr->canRead()) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("LYWSD02 char")); - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); + if (pChr){ + DEBUG_SENSOR_LOG( PSTR("%s: got LYWSD02 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + if(pChr->canRead()) { + DEBUG_SENSOR_LOG(PSTR("LYWSD02 char")); + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); + } } + MI32.mode.readingDone = 1; } void MI32batteryCGD1(){ @@ -780,26 +814,26 @@ void MI32batteryCGD1(){ break; } timer++; - vTaskDelay(10); + vTaskDelay(10/ portTICK_PERIOD_MS); } NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID CGD1serviceUUID("180F"); - static BLEUUID CGD1charUUID("2A19"); + static BLEUUID CGD1serviceUUID((uint16_t)0x180F); + static BLEUUID CGD1charUUID((uint16_t)0x2A19); pSvc = MI32Client->getService(CGD1serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(CGD1charUUID); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: got CGD1 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); } - else { - return; - } - if(pChr->canRead()) { - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); + if (pChr){ + DEBUG_SENSOR_LOG(PSTR("%s: got CGD1 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + if(pChr->canRead()) { + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); + } } + MI32.mode.readingDone = 1; } @@ -819,14 +853,14 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ } MI32_ReverseMAC(_beacon.Mac); - DEBUG_SENSOR_LOG(PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); - DEBUG_SENSOR_LOG(PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); if(MIBLEsensors[_slot].type==4 || MIBLEsensors[_slot].type==6){ DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type); return; } - DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kMI32SlaveType[MIBLEsensors[_slot].type-1],_slot); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32SlaveType[MIBLEsensors[_slot].type-1],_slot); switch(_beacon.type){ case 0x04: _tempFloat=(float)(_beacon.temp)/10.0f; @@ -834,7 +868,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].temp=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); break; case 0x06: _tempFloat=(float)(_beacon.hum)/10.0f; @@ -842,11 +876,11 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].hum=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode 6: U16: %u Hum"), _beacon.hum); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _beacon.hum); break; case 0x07: MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff; - DEBUG_SENSOR_LOG(PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); break; case 0x08: _tempFloat =(float)_beacon.moist; @@ -854,7 +888,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].moisture=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); break; case 0x09: _tempFloat=(float)(_beacon.fert); @@ -862,14 +896,14 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].fertility=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); break; case 0x0a: if(_beacon.bat<101){ MIBLEsensors[_slot].bat = _beacon.bat; DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode a: U8: %u %%"), _beacon.bat); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode a: U8: %u %%"), _beacon.bat); break; case 0x0d: _tempFloat=(float)(_beacon.HT.temp)/10.0f; @@ -882,7 +916,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated")); } - DEBUG_SENSOR_LOG(PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); break; } } @@ -990,6 +1024,8 @@ void MI32EverySecond(bool restart){ _counter = 0; MI32.mode.canScan = 0; MI32.mode.canConnect = 1; + MI32.mode.willReadBatt = 0; + MI32.mode.willConnect = 0; return; } @@ -1028,9 +1064,9 @@ void MI32EverySecond(bool restart){ if(_counter==0) { MI32.state.sensor = _nextSensorSlot; - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u"),D_CMND_MI32, MI32.state.sensor); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u of %u"),D_CMND_MI32, MI32.state.sensor, MIBLEsensors.size()-1); MI32.mode.canScan = 0; - if (MI32.mode.runningScan == 1 || MI32.mode.connected == 1) return; + if (MI32.mode.runningScan|| MI32.mode.connected || MI32.mode.willConnect) return; _nextSensorSlot++; MI32.mode.canConnect = 1; if(MI32.mode.connected == 0) { @@ -1044,7 +1080,7 @@ void MI32EverySecond(bool restart){ } } - if (MI32.state.sensor==MIBLEsensors.size()-1) { + if (_nextSensorSlot>(MIBLEsensors.size()-1)) { _nextSensorSlot= 0; _counter++; if (MI32.mode.shallReadBatt){ @@ -1159,6 +1195,7 @@ const char HTTP_MI32_HL[] PROGMEM = "{s}
{m}
{e}"; void MI32Show(bool json) { + if (json) { for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { /* @@ -1172,7 +1209,7 @@ void MI32Show(bool json) MIBLEsensors[i].serial[3], MIBLEsensors[i].serial[4], MIBLEsensors[i].serial[5]); if (MIBLEsensors[i].type == FLORA) { - if (!isnan(MIBLEsensors[i].temp)) { // this is the error code -> no temperature + if (!isnan(MIBLEsensors[i].temp)) { char temperature[FLOATSZ]; // all sensors have temperature dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), temperature); @@ -1299,4 +1336,4 @@ bool Xsns62(uint8_t function) return result; } #endif // USE_MI_ESP32 -#endif // ESP32 +#endif // ESP32 \ No newline at end of file From 16aa38be4943cb1f4edadf89f30feeb84de70763 Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Sat, 30 May 2020 01:05:10 +0200 Subject: [PATCH 121/581] fix Min stage settings --- tasmota/xsns_67_as3935.ino | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tasmota/xsns_67_as3935.ino b/tasmota/xsns_67_as3935.ino index 59618c32a..2b73a2749 100644 --- a/tasmota/xsns_67_as3935.ino +++ b/tasmota/xsns_67_as3935.ino @@ -465,8 +465,18 @@ bool AS3935SetDefault() { void AS3935InitSettings() { if(Settings.as3935_functions.nf_autotune){ - AS3935SetGain(INDOORS); - AS3935SetNoiseFloor(0); + if(Settings.as3935_parameter.nf_autotune_min) { + if (Settings.as3935_parameter.nf_autotune_min > 7) { + AS3935SetGain(OUTDOORS); + AS3935SetNoiseFloor(Settings.as3935_parameter.nf_autotune_min - 8); + } else { + AS3935SetGain(INDOORS); + AS3935SetNoiseFloor(Settings.as3935_parameter.nf_autotune_min); + } + } else { + AS3935SetGain(INDOORS); + AS3935SetNoiseFloor(0); + } } I2cWrite8(AS3935_ADDR, 0x00, Settings.as3935_sensor_cfg[0]); I2cWrite8(AS3935_ADDR, 0x01, Settings.as3935_sensor_cfg[1]); From 3d42fae8bdd07b3e7fab4c17f1e6d70eef398650 Mon Sep 17 00:00:00 2001 From: Paul C Diem Date: Fri, 29 May 2020 18:55:33 -0500 Subject: [PATCH 122/581] Fix SO88 incoming power state check --- tasmota/support_device_groups.ino | 3 +-- tasmota/support_tasmota.ino | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tasmota/support_device_groups.ino b/tasmota/support_device_groups.ino index 9572c9a6a..3e40f189f 100644 --- a/tasmota/support_device_groups.ino +++ b/tasmota/support_device_groups.ino @@ -387,7 +387,7 @@ void SendReceiveDeviceGroupMessage(struct device_group * device_group, struct de case DGR_ITEM_POWER: if (Settings.flag4.remote_device_mode) { // SetOption88 - Enable relays in separate device groups bool on = (value & 1); - if (on != (power & 1)) ExecuteCommandPower(device_group_index + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE); + if (on != (power & (1 << device_group_index))) ExecuteCommandPower(device_group_index + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE); } else if (device_group->local) { uint8_t mask_devices = value >> 24; @@ -396,7 +396,6 @@ void SendReceiveDeviceGroupMessage(struct device_group * device_group, struct de uint32_t mask = 1 << i; bool on = (value & mask); if (on != (power & mask)) ExecuteCommandPower(i + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE); - if (Settings.flag4.remote_device_mode) break; // SetOption88 - Enable relays in separate device groups } } break; diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 26341b416..3cbfb497c 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -573,7 +573,7 @@ void ExecuteCommandPower(uint32_t device, uint32_t state, uint32_t source) #ifdef USE_DEVICE_GROUPS if (SRC_REMOTE != source && SRC_RETRY != source) { if (Settings.flag4.remote_device_mode) // SetOption88 - Enable relays in separate device groups - SendDeviceGroupMessage(device - 1, DGR_MSGTYP_UPDATE, DGR_ITEM_POWER, (power >> device - 1) & 1 | 0x01000000); // Explicitly set number of relays to one + SendDeviceGroupMessage(device - 1, DGR_MSGTYP_UPDATE, DGR_ITEM_POWER, (power >> (device - 1)) & 1 | 0x01000000); // Explicitly set number of relays to one else SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_POWER, power); } From 7f1514e6da269972fabe458ef3b5cdabd40cba2d Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 30 May 2020 10:48:12 +0200 Subject: [PATCH 123/581] some fixes and optimizations --- tasmota/xdrv_10_scripter.ino | 139 ++++++++++++++++++++++------------- 1 file changed, 88 insertions(+), 51 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 434028092..a2562a36c 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -1276,6 +1276,7 @@ chknext: #endif //USE_ENERGY_SENSOR break; case 'f': +//#define DEBUG_FS #ifdef USE_SCRIPT_FATFS if (!strncmp(vname,"fo(",3)) { lp+=3; @@ -1304,6 +1305,9 @@ chknext: for (uint8_t cnt=0;cnt=SFS_MAX) ind=SFS_MAX-1; - glob_script_mem.files[ind].close(); - glob_script_mem.file_flags[ind].is_open=0; + if (fvar>=0) { + uint8_t ind=fvar; + if (ind>=SFS_MAX) ind=SFS_MAX-1; +#ifdef DEBUG_FS + AddLog_P2(LOG_LEVEL_INFO,PSTR("closing file %d"),ind); +#endif + glob_script_mem.files[ind].close(); + glob_script_mem.file_flags[ind].is_open=0; + } fvar=0; lp++; len=0; @@ -2951,7 +2966,6 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { toLogEOL("for error",lp); } } else if (!strncmp(lp,"next",4)) { - lp+=4; lp_next=lp; if (floop>0) { // for next loop @@ -4300,8 +4314,7 @@ void Script_Check_Hue(String *response) { uint8_t hue_script_found=Run_Scripter(">H",-2,0); if (hue_script_found!=99) return; - char line[128]; - char tmp[128]; + char tmp[256]; uint8_t hue_devs=0; uint8_t vindex=0; char *cp; @@ -4316,17 +4329,7 @@ void Script_Check_Hue(String *response) { } if (*lp!=';') { // check this line - memcpy(line,lp,sizeof(line)); - line[sizeof(line)-1]=0; - cp=line; - for (uint32_t i=0; im",-2,0); if (msect==99) { - char line[128]; - char tmp[128]; + char tmp[256]; char *lp=glob_script_mem.section_ptr+2; while (lp) { while (*lp==SCRIPT_EOL) { @@ -5530,17 +5532,7 @@ uint8_t msect=Run_Scripter(">m",-2,0); } if (*lp!=';') { // send this line to smtp - memcpy(line,lp,sizeof(line)); - line[sizeof(line)-1]=0; - char *cp=line; - for (uint32_t i=0; iprintln(tmp); func(tmp); } @@ -5563,8 +5555,7 @@ uint8_t msect=Run_Scripter(">m",-2,0); void ScriptJsonAppend(void) { uint8_t web_script=Run_Scripter(">J",-2,0); if (web_script==99) { - char line[128]; - char tmp[128]; + char tmp[256]; char *lp=glob_script_mem.section_ptr+2; while (lp) { while (*lp==SCRIPT_EOL) { @@ -5575,17 +5566,7 @@ void ScriptJsonAppend(void) { } if (*lp!=';') { // send this line to mqtt - memcpy(line,lp,sizeof(line)); - line[sizeof(line)-1]=0; - char *cp=line; - for (uint32_t i=0; it1",3,0); + } +} + +void script_task2(void *arg) { + //uint32_t lastms=millis(); + //uint32_t time; + while (1) { + //time=millis()-lastms; + //lastms=millis(); + //time=esp32_tasks[1].task_timer-time; + //if (timet2",3,0); + } +} +uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { + //return 0; + BaseType_t res = 0; + if (core > 1) { core = 1; } + if (num == 1) { + if (esp32_tasks[0].task_t) { vTaskDelete(esp32_tasks[0].task_t); } + res = xTaskCreatePinnedToCore(script_task1, "T1", STASK_STACK, NULL, STASK_PRIO, &esp32_tasks[0].task_t, core); + esp32_tasks[0].task_timer = time; + } else { + if (esp32_tasks[1].task_t) { vTaskDelete(esp32_tasks[1].task_t); } + res = xTaskCreatePinnedToCore(script_task2, "T2", STASK_STACK, NULL, STASK_PRIO, &esp32_tasks[1].task_t, core); + esp32_tasks[1].task_timer = time; + } + return res; +} +#else + uint16_t task_timer1; uint16_t task_timer2; TaskHandle_t task_t1; @@ -5625,13 +5667,6 @@ void script_task2(void *arg) { Run_Scripter(">t2",3,0); } } -#ifndef STASK_STACK -#define STASK_STACK 4096 -#endif - -#ifndef STASK_PRIO -#define STASK_PRIO 5 -#endif uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { //return 0; @@ -5648,6 +5683,8 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { } return res; } +#endif + #endif // USE_SCRIPT_TASK #endif // ESP32 /*********************************************************************************************\ From 7e28e03d7814c4a07ac31f706235517e24ee5fdf Mon Sep 17 00:00:00 2001 From: Staars Date: Sat, 30 May 2020 13:50:22 +0200 Subject: [PATCH 124/581] add commands to touch pin button on ESP32 --- tasmota/i18n.h | 5 ++++ tasmota/support_button.ino | 16 +++++++++--- tasmota/support_command.ino | 50 +++++++++++++++++++++++++++++++++++-- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 89d931908..1f0b00807 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -319,6 +319,11 @@ #define D_CMND_HUMOFFSET "HumOffset" #define D_CMND_GLOBAL_TEMP "GlobalTemp" #define D_CMND_GLOBAL_HUM "GlobalHum" +#ifdef ESP32 +#define D_CMND_TOUCH_CAL "TouchCal" +#define D_CMND_TOUCH_THRES "TouchThres" +#define D_CMND_TOUCH_NUM "TouchNum" +#endif //ESP32 // Commands xdrv_01_mqtt.ino #define D_CMND_MQTTLOG "MqttLog" diff --git a/tasmota/support_button.ino b/tasmota/support_button.ino index 96dfaf73a..a92a56be5 100644 --- a/tasmota/support_button.ino +++ b/tasmota/support_button.ino @@ -52,6 +52,14 @@ struct BUTTON { uint8_t adc = 99; // ADC0 button number } Button; +#ifdef ESP32 +struct TOUCH_BUTTON { + uint8_t pin_threshold = TOUCH_PIN_THRESHOLD; + uint8_t hit_threshold = TOUCH_HIT_THRESHOLD; + uint8_t calibration = 0; // Bitfield +} TOUCH_BUTTON; +#endif // ESP32 + /********************************************************************************************/ void ButtonPullupFlag(uint8 button_bit) @@ -155,15 +163,15 @@ void ButtonHandler(void) uint32_t _value = touchRead(Pin(GPIO_KEY1, button_index)); button = NOT_PRESSED; if (_value != 0){ // probably read-error - if(_value < TOUCH_PIN_THRESHOLD){ - if(++Button.touch_hits[button_index]>TOUCH_HIT_THRESHOLD){ - button = PRESSED; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Touch value: %u hits: %u"), _value, Button.touch_hits[button_index]); + if(_value < TOUCH_BUTTON.pin_threshold){ + if(++Button.touch_hits[button_index]>TOUCH_BUTTON.hit_threshold){ + if (!bitRead(TOUCH_BUTTON.calibration, button_index+1)) button = PRESSED; } } else Button.touch_hits[button_index] = 0; } else Button.touch_hits[button_index] = 0; + if (bitRead(TOUCH_BUTTON.calibration, button_index+1)) AddLog_P2(LOG_LEVEL_INFO, PSTR("PLOT: %u, %u, %u,"),button_index+1, _value, Button.touch_hits[button_index]); // button number (1..4) , value, continuous hits under threshold } else{ // Normal button button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index)); diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 9d9fbfa19..6c44391a9 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -38,7 +38,11 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix #endif // USE_DEVICE_GROUPS_SEND D_CMND_DEVGROUP_SHARE "|" D_CMND_DEVGROUPSTATUS "|" #endif // USE_DEVICE_GROUPS - D_CMND_SENSOR "|" D_CMND_DRIVER; + D_CMND_SENSOR "|" D_CMND_DRIVER +#ifdef ESP32 + "|" D_CMND_TOUCH_CAL "|" D_CMND_TOUCH_THRES "|" D_CMND_TOUCH_NUM +#endif //ESP32 + ; void (* const TasmotaCommand[])(void) PROGMEM = { &CmndBacklog, &CmndDelay, &CmndPower, &CmndStatus, &CmndState, &CmndSleep, &CmndUpgrade, &CmndUpgrade, &CmndOtaUrl, @@ -61,7 +65,11 @@ void (* const TasmotaCommand[])(void) PROGMEM = { #endif // USE_DEVICE_GROUPS_SEND &CmndDevGroupShare, &CmndDevGroupStatus, #endif // USE_DEVICE_GROUPS - &CmndSensor, &CmndDriver }; + &CmndSensor, &CmndDriver +#ifdef ESP32 + ,&CmndTouchCal, &CmndTouchThres, &CmndTouchNum +#endif //ESP32 + }; const char kWifiConfig[] PROGMEM = D_WCFG_0_RESTART "||" D_WCFG_2_WIFIMANAGER "||" D_WCFG_4_RETRY "|" D_WCFG_5_WAIT "|" D_WCFG_6_SERIAL "|" D_WCFG_7_WIFIMANAGER_RESET_ONLY; @@ -1946,3 +1954,41 @@ void CmndDriver(void) { XdrvCall(FUNC_COMMAND_DRIVER); } + +#ifdef ESP32 +void CmndTouchCal(void) +{ + if (XdrvMailbox.payload >= 0) { + if (XdrvMailbox.payload < MAX_KEYS + 1) TOUCH_BUTTON.calibration = bitSet(TOUCH_BUTTON.calibration, XdrvMailbox.payload); + if (XdrvMailbox.payload == 0) TOUCH_BUTTON.calibration = 0; + if (XdrvMailbox.payload == 255) TOUCH_BUTTON.calibration = 255; // all pinss + } + Response_P(PSTR("{\"" D_CMND_TOUCH_CAL "\": %u"), TOUCH_BUTTON.calibration); + ResponseJsonEnd(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("Button Touchvalue Hits,")); +} + +void CmndTouchThres(void) +{ + if (XdrvMailbox.payload >= 0) { + if (XdrvMailbox.payload<256){ + TOUCH_BUTTON.pin_threshold = XdrvMailbox.payload; + } + } + Response_P(PSTR("{\"" D_CMND_TOUCH_THRES "\": %u"), TOUCH_BUTTON.pin_threshold); + ResponseJsonEnd(); +} + +void CmndTouchNum(void) +{ + if (XdrvMailbox.payload >= 0) { + if (XdrvMailbox.payload<32){ + TOUCH_BUTTON.hit_threshold = XdrvMailbox.payload; + } + } + Response_P(PSTR("{\"" D_CMND_TOUCH_NUM "\": %u"), TOUCH_BUTTON.hit_threshold); + ResponseJsonEnd(); + +} + +#endif //ESP32 \ No newline at end of file From bf73728224c3a778d1f5a6a9055e81486392f4da Mon Sep 17 00:00:00 2001 From: Staars Date: Sat, 30 May 2020 13:50:57 +0200 Subject: [PATCH 125/581] add semi-generic serial plotter to PIO --- pio/serial-plotter.py | 188 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100755 pio/serial-plotter.py diff --git a/pio/serial-plotter.py b/pio/serial-plotter.py new file mode 100755 index 000000000..5abde9c72 --- /dev/null +++ b/pio/serial-plotter.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python + +""" + serial-plotter.py - for Tasmota + + Copyright (C) 2020 Christian Baars + + 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 . + +Requirements: + - Python + - pip3 matplotlib + - a Tasmotadriver that plots + +Instructions: + expects serial data in the format: + 'PLOT: graphnumber value' + graph (1-4) + integer value + Code snippet example: (last value will be ignored) + AddLog_P2(LOG_LEVEL_INFO, PSTR("PLOT: %u, %u, %u,"),button_index+1, _value, Button.touch_hits[button_index]); + +Usage: + set serial config in code + ./serial-plotter.py + set output in tasmota, e.g.; TouchCal 1..4 (via Textbox) + +""" +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.animation as animation +from matplotlib.widgets import TextBox +import time +import serial +import argparse + +#default values +port = '/dev/cu.SLAB_USBtoUART' +baud = 115200 + +#command line input +parser = argparse.ArgumentParser() +parser.add_argument("--port", "-p", help="change serial port, default: " + port) +parser.add_argument("--baud", "-b", help="change baud rate, default: " + str(baud)) +args = parser.parse_args() +if args.port: + print("change serial port to %s" % args.port) + port = args.port +if args.baud: + print("change baud rate to %s" % args.baud) + baud = args.baud + + +#time range +dt = 0.01 +t = np.arange(0.0, 100, dt) + +#lists for the data +xs = [0] #counting up x +ys = [[0],[0],[0],[0]] #4 fixed graphs for now +max_y = 1 +# min_y = 0 + +fig = plt.figure('Tasmota Serial Plotter') +ax = fig.add_subplot(111, autoscale_on=True, xlim=(0, 200), ylim=(0, 20)) #fixed x scale for now, y will adapt +ax.grid() + +line1, = ax.plot([], [], color = "r", label='G 1') +line2, = ax.plot([], [], color = "g", label='G 2') +line3, = ax.plot([], [], color = "b", label='G 3') +line4, = ax.plot([], [], color = "y", label='G 4') + +time_template = 'time = %.1fs' +time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes) + +ser = serial.Serial() +ser.port = port +ser.baudrate = baud +ser.timeout = 0 #return immediately +try: + ser.open() +except: + print("Could not connect to serial with settings: " + str(ser.port) + ' at ' + str(ser.baudrate) + 'baud') + print("port available?") + exit() + +if ser.is_open==True: + print("Serial Plotter started ...:") + plt.title('connected to ' + str(ser.port) + ' at ' + str(ser.baudrate) + 'baud') +else: + print("Could not connect to serial: " + str(ser.port) + ' at ' + str(ser.baudrate) + 'baud') + plt.title('NOT connected to ' + str(ser.port) + ' at ' + str(ser.baudrate) + 'baud') + +def init(): + line1.set_data([], []) + line2.set_data([], []) + line3.set_data([], []) + line4.set_data([], []) + time_text.set_text('') + return [line1,line2,line3,line4,time_text ] #was line + + +def parse_line(data_line): + pos = data_line.find("PLOT:", 10) + if pos<0: + # print("wrong format") + return 0,0 + + raw_data = data_line[pos+6:] + val_list = raw_data.split(',') + try: + g = int(val_list[0]) + v = int(val_list[1]) + return g, v + except: + return 0,0 + +def update(num, line1, line2): + global xs, ys, max_y + + time_text.set_text(time_template % (num*dt) ) + + receive_data = str(ser.readline()) #string + + g, v = parse_line(receive_data) + if (g in range(1,5)): + # print(v,g) + if v>max_y: + max_y = v + print(max_y) + ax.set_ylim([0, max_y * 1.2]) + + idx = 0 + for y in ys: + y.append(y[-1]) + if idx == g-1: + y[-1] = v + idx = idx +1 + xs.append(xs[-1]+1) + + if len(ys[0])>200: + xs.pop() + for y in ys: + y.pop(0) + line1.set_data(xs, ys[0]) + line2.set_data(xs, ys[1]) + line3.set_data(xs, ys[2]) + line4.set_data(xs, ys[3]) + return [line1,line2,line3,line4, time_text] + +def handle_close(evt): + print('Closing serial connection') + ser.close() + print('Closed serial plotter') + +ani = animation.FuncAnimation(fig, update, None, fargs=[line1, line2], + interval=10, blit=True, init_func=init) + +ax.set_xlabel('Last 200 Samples') +ax.set_ylabel('Values') + +fig.canvas.mpl_connect('close_event', handle_close) + +def submit(text): + print (text) + ser.write(text.encode() + "\n".encode()) + +plt.subplots_adjust(bottom=0.25) +axbox = plt.axes([0.15, 0.05, 0.7, 0.075]) +text_box = TextBox(axbox, 'Send:', initial='') +text_box.on_submit(submit) + +ax.legend(loc='lower right', ncol=2) + +if ser.is_open==True: + plt.show() + From 86fc34e612e3b234faf010dffd281ef8abc93589 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 30 May 2020 14:27:07 +0200 Subject: [PATCH 126/581] Move serial-plotter --- {pio => tools}/serial-plotter.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {pio => tools}/serial-plotter.py (100%) mode change 100755 => 100644 diff --git a/pio/serial-plotter.py b/tools/serial-plotter.py old mode 100755 new mode 100644 similarity index 100% rename from pio/serial-plotter.py rename to tools/serial-plotter.py From 29070f1136e3f269da03df8b4799659533b256bd Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 30 May 2020 14:59:52 +0200 Subject: [PATCH 127/581] Add ``CpuFrequency`` and ``FlashFrequency`` to status 0 - Add ``CpuFrequency`` to ``status 2`` - Add ``FlashFrequency`` to ``status 4`` --- RELEASENOTES.md | 3 +++ tasmota/CHANGELOG.md | 2 ++ tasmota/support_command.ino | 16 ++++++++-------- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7fb0366a3..bf2983136 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -68,3 +68,6 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) - Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) - Add Three Phase Export Active Energy to SDM630 driver +- Add Zigbee options to ``ZbSend`` to write and report attributes +- Add ``CpuFrequency`` to ``status 2`` +- Add ``FlashFrequency`` to ``status 4`` diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 9fb3490fc..8e48a6302 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -12,6 +12,8 @@ - Add wildcard pattern ``?`` for JSON matching in rules - Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) - Add Zigbee options to ``ZbSend`` to write and report attributes +- Add ``CpuFrequency`` to ``status 2`` +- Add ``FlashFrequency`` to ``status 4`` ### 8.3.1.1 20200518 diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 6c44391a9..f143a9316 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -41,7 +41,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_SENSOR "|" D_CMND_DRIVER #ifdef ESP32 "|" D_CMND_TOUCH_CAL "|" D_CMND_TOUCH_THRES "|" D_CMND_TOUCH_NUM -#endif //ESP32 +#endif //ESP32 ; void (* const TasmotaCommand[])(void) PROGMEM = { @@ -65,10 +65,10 @@ void (* const TasmotaCommand[])(void) PROGMEM = { #endif // USE_DEVICE_GROUPS_SEND &CmndDevGroupShare, &CmndDevGroupStatus, #endif // USE_DEVICE_GROUPS - &CmndSensor, &CmndDriver + &CmndSensor, &CmndDriver #ifdef ESP32 ,&CmndTouchCal, &CmndTouchThres, &CmndTouchNum -#endif //ESP32 +#endif //ESP32 }; const char kWifiConfig[] PROGMEM = @@ -444,14 +444,14 @@ void CmndStatus(void) ",\"" D_JSON_BOOTVERSION "\":%d" #endif ",\"" D_JSON_COREVERSION "\":\"" ARDUINO_CORE_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\"," - "\"Hardware\":\"%s\"" + "\"CpuFrequency\":%d,\"Hardware\":\"%s\"" "%s}}"), my_version, my_image, GetBuildDateAndTime().c_str() #ifdef ESP8266 , ESP.getBootVersion() #endif , ESP.getSdkVersion(), - GetDeviceHardware().c_str(), + ESP.getCpuFreqMHz(), GetDeviceHardware().c_str(), GetStatistics().c_str()); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "2")); } @@ -476,7 +476,7 @@ void CmndStatus(void) #ifdef ESP8266 ",\"" D_JSON_FLASHCHIPID "\":\"%06X\"" #endif - ",\"" D_JSON_FLASHMODE "\":%d,\"" + ",\"FlashFrequency\":%d,\"" D_JSON_FLASHMODE "\":%d,\"" D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"), ESP_getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP_getFreeHeap()/1024, #ifdef ESP32 @@ -486,7 +486,7 @@ void CmndStatus(void) #ifdef ESP8266 , ESP.getFlashChipId() #endif - , ESP.getFlashChipMode(), + , ESP.getFlashChipSpeed()/1000000, ESP.getFlashChipMode(), LANGUAGE_LCID, feature_drv1, feature_drv2, feature_sns1, feature_sns2, feature5, feature6); XsnsDriverState(); ResponseAppend_P(PSTR(",\"Sensors\":")); @@ -1980,7 +1980,7 @@ void CmndTouchThres(void) } void CmndTouchNum(void) -{ +{ if (XdrvMailbox.payload >= 0) { if (XdrvMailbox.payload<32){ TOUCH_BUTTON.hit_threshold = XdrvMailbox.payload; From 54806fd527357603e6f60477d73ebf04a6f3b48b Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 30 May 2020 15:29:47 +0200 Subject: [PATCH 128/581] files system update --- tasmota/xdrv_10_scripter.ino | 145 +++++++++++++++++++++++------------ tasmota/xdrv_13_display.ino | 21 +++-- 2 files changed, 110 insertions(+), 56 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index a2562a36c..0edfad516 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -64,7 +64,6 @@ keywords if then else endif, or, and are better readable for beginners (others m #define MAX_SCRIPT_SIZE MAX_RULE_SIZE*MAX_RULE_SETS - uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); @@ -79,30 +78,40 @@ uint32_t DecodeLightId(uint32_t hue_id); #endif #endif // USE_SCRIPT_COMPRESSION -#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#if (defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)) || (USE_SCRIPT_FATFS==-1) + +#ifdef ESP32 #include "FS.h" #include "SPIFFS.h" +#else +#include +#endif +FS *fsp; void SaveFile(const char *name,const uint8_t *buf,uint32_t len) { - File file = SPIFFS.open(name, FILE_WRITE); + File file = fsp->open(name, "w"); if (!file) return; file.write(buf, len); file.close(); } #define FORMAT_SPIFFS_IF_FAILED true -uint8_t spiffs_mounted=0; +uint8_t fs_mounted=0; void LoadFile(const char *name,uint8_t *buf,uint32_t len) { - if (!spiffs_mounted) { + if (!fs_mounted) { +#ifdef ESP32 if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)){ +#else + if(!fsp->begin()){ +#endif //Serial.println("SPIFFS Mount Failed"); return; } - spiffs_mounted=1; + fs_mounted=1; } - File file = SPIFFS.open(name); + File file = fsp->open(name, "r"); if (!file) return; file.read(buf, len); file.close(); @@ -116,29 +125,43 @@ enum {OPER_EQU=1,OPER_PLS,OPER_MIN,OPER_MUL,OPER_DIV,OPER_PLSEQU,OPER_MINEQU,OPE enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD}; #ifdef USE_SCRIPT_FATFS + +#if USE_SCRIPT_FATFS>=0 #include - -//#define USE_MMC - -#ifdef USE_MMC -#include -#undef FS_USED -#define FS_USED SD_MMC -#else #include -#undef FS_USED -#define FS_USED SD +#ifdef ESP32 +FS *fsp; +#else +SDClass *fsp; +#endif #endif #ifndef ESP32 +// esp8266 + +#if USE_SCRIPT_FATFS>=0 +// old fs #undef FILE_WRITE #define FILE_WRITE (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT) #define FILE_APPEND (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT | sdfat::O_APPEND) + +#else +// new fs +#undef FILE_WRITE +#define FILE_WRITE "w" +#undef FILE_READ +#define FILE_READ "r" +#undef FILE_APPEND +#define FILE_APPEND "a" #endif +#endif // USE_SCRIPT_FATFS>=0 + + #ifndef FAT_SCRIPT_SIZE #define FAT_SCRIPT_SIZE 4096 #endif + #ifdef ESP32 #undef FAT_SCRIPT_NAME #define FAT_SCRIPT_NAME "/script.txt" @@ -150,7 +173,8 @@ enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD}; #if USE_STANDARD_SPI_LIBRARY==0 #warning ("FATFS standard spi should be used"); #endif -#endif + +#endif // USE_SCRIPT_FATFS #ifdef SUPPORT_MQTT_EVENT #include // Import LinkedList library @@ -624,10 +648,18 @@ char *script; #ifdef USE_SCRIPT_FATFS if (!glob_script_mem.script_sd_found) { + +#if USE_SCRIPT_FATFS>=0 + fsp=&SD; + #ifdef USE_MMC - if (FS_USED.begin()) { + if (fsp->begin()) { #else - if (FS_USED.begin(USE_SCRIPT_FATFS)) { + if (SD.begin(USE_SCRIPT_FATFS)) { +#endif + +#else + if (fsp->begin()) { #endif glob_script_mem.script_sd_found=1; } else { @@ -1308,7 +1340,7 @@ chknext: #ifdef DEBUG_FS AddLog_P2(LOG_LEVEL_INFO,PSTR("open file for read %d"),cnt); #endif - glob_script_mem.files[cnt]=FS_USED.open(str,FILE_READ); + glob_script_mem.files[cnt]=fsp->open(str,FILE_READ); if (glob_script_mem.files[cnt].isDirectory()) { glob_script_mem.files[cnt].rewindDirectory(); glob_script_mem.file_flags[cnt].is_dir=1; @@ -1318,12 +1350,12 @@ chknext: } else { if (mode==1) { - glob_script_mem.files[cnt]=FS_USED.open(str,FILE_WRITE); + glob_script_mem.files[cnt]=fsp->open(str,FILE_WRITE); #ifdef DEBUG_FS AddLog_P2(LOG_LEVEL_INFO,PSTR("open file for write %d"),cnt); #endif } else { - glob_script_mem.files[cnt]=FS_USED.open(str,FILE_APPEND); + glob_script_mem.files[cnt]=fsp->open(str,FILE_APPEND); #ifdef DEBUG_FS AddLog_P2(LOG_LEVEL_INFO,PSTR("open file for append %d"),cnt); #endif @@ -1465,7 +1497,7 @@ chknext: lp+=3; char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); - FS_USED.remove(str); + fsp->remove(str); lp++; len=0; goto exit; @@ -1505,7 +1537,7 @@ chknext: char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); // execute script - File ef=FS_USED.open(str); + File ef=fsp->open(str,FILE_READ); if (ef) { uint16_t fsiz=ef.size(); if (fsiz<2048) { @@ -1527,7 +1559,7 @@ chknext: lp+=4; char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); - fvar=FS_USED.mkdir(str); + fvar=fsp->mkdir(str); lp++; len=0; goto exit; @@ -1536,7 +1568,7 @@ chknext: lp+=4; char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); - fvar=FS_USED.rmdir(str); + fvar=fsp->rmdir(str); lp++; len=0; goto exit; @@ -1545,7 +1577,7 @@ chknext: lp+=3; char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); - if (FS_USED.exists(str)) fvar=1; + if (fsp->exists(str)) fvar=1; else fvar=0; lp++; len=0; @@ -3714,7 +3746,7 @@ void ListDir(char *path, uint8_t depth) { char format[12]; sprintf(format,"%%-%ds",24-depth); - File dir=FS_USED.open(path); + File dir=fsp->open(path, FILE_READ); if (dir) { dir.rewindDirectory(); if (strlen(path)>1) { @@ -3836,8 +3868,8 @@ void script_upload(void) { if (upload.status == UPLOAD_FILE_START) { char npath[48]; sprintf(npath,"%s/%s",path,upload.filename.c_str()); - FS_USED.remove(npath); - upload_file=FS_USED.open(npath,FILE_WRITE); + fsp->remove(npath); + upload_file=fsp->open(npath,FILE_WRITE); if (!upload_file) Web.upload_error=1; } else if(upload.status == UPLOAD_FILE_WRITE) { if (upload_file) upload_file.write(upload.buf,upload.currentSize); @@ -3856,12 +3888,12 @@ uint8_t DownloadFile(char *file) { File download_file; WiFiClient download_Client; - if (!FS_USED.exists(file)) { + if (!fsp->exists(file)) { AddLog_P(LOG_LEVEL_INFO,PSTR("file not found")); return 0; } - download_file=FS_USED.open(file,FILE_READ); + download_file=fsp->open(file,FILE_READ); if (!download_file) { AddLog_P(LOG_LEVEL_INFO,PSTR("could not open file")); return 0; @@ -4041,16 +4073,16 @@ void ScriptSaveSettings(void) { #if !defined(USE_24C256) && defined(USE_SCRIPT_FATFS) if (glob_script_mem.flags&1) { - FS_USED.remove(FAT_SCRIPT_NAME); - File file=FS_USED.open(FAT_SCRIPT_NAME,FILE_WRITE); + fsp->remove(FAT_SCRIPT_NAME); + File file=fsp->open(FAT_SCRIPT_NAME,FILE_WRITE); file.write((const uint8_t*)glob_script_mem.script_ram,FAT_SCRIPT_SIZE); file.close(); } #endif -#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#if defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) if (glob_script_mem.flags&1) { - SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,ESP32_SCRIPT_SIZE); + SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,LITTLEFS_SCRIPT_SIZE); } #endif } @@ -4065,7 +4097,7 @@ void ScriptSaveSettings(void) { #ifdef USE_SCRIPT_COMPRESSION #ifndef USE_24C256 #ifndef USE_SCRIPT_FATFS -#ifndef ESP32_SCRIPT_SIZE +#ifndef LITTLEFS_SCRIPT_SIZE //AddLog_P2(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], MAX_SCRIPT_SIZE-1); @@ -5710,7 +5742,7 @@ bool Xdrv10(uint8_t function) #ifdef USE_SCRIPT_COMPRESSION #ifndef USE_24C256 #ifndef USE_SCRIPT_FATFS -#ifndef ESP32_SCRIPT_SIZE +#ifndef LITTLEFS_SCRIPT_SIZE int32_t len_decompressed; sprt=(char*)calloc(UNISHOXRSIZE+8,1); if (!sprt) { break; } @@ -5756,10 +5788,14 @@ bool Xdrv10(uint8_t function) #endif #endif + #ifdef USE_SCRIPT_FATFS +#if USE_SCRIPT_FATFS>=0 + fsp = &SD; + #ifdef USE_MMC - if (FS_USED.begin()) { + if (fsp->begin()) { #else #ifdef ESP32 @@ -5767,10 +5803,15 @@ bool Xdrv10(uint8_t function) SPI.begin(Pin(GPIO_SPI_CLK),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_MOSI), -1); } #endif - if (FS_USED.begin(USE_SCRIPT_FATFS)) { + if (SD.begin(USE_SCRIPT_FATFS)) { #endif - //FS_USED.dateTimeCallback(dateTime); +#else + fsp = &LittleFS; + if (fsp->begin()) { +#endif + + //fsp->dateTimeCallback(dateTime); glob_script_mem.script_sd_found=1; char *script; @@ -5778,8 +5819,8 @@ bool Xdrv10(uint8_t function) if (!script) break; glob_script_mem.script_ram=script; glob_script_mem.script_size=FAT_SCRIPT_SIZE; - if (FS_USED.exists(FAT_SCRIPT_NAME)) { - File file=FS_USED.open(FAT_SCRIPT_NAME,FILE_READ); + if (fsp->exists(FAT_SCRIPT_NAME)) { + File file=fsp->open(FAT_SCRIPT_NAME,FILE_READ); file.read((uint8_t*)script,FAT_SCRIPT_SIZE); file.close(); } @@ -5796,15 +5837,21 @@ bool Xdrv10(uint8_t function) #endif -#if defined(ESP32) && defined(ESP32_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#if defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) + +#ifdef ESP32 + fsp = &SPIFFS; +#else + fsp = &LittleFS; +#endif char *script; - script=(char*)calloc(ESP32_SCRIPT_SIZE+4,1); + script=(char*)calloc(LITTLEFS_SCRIPT_SIZE+4,1); if (!script) break; - LoadFile("/script.txt",(uint8_t*)script,ESP32_SCRIPT_SIZE); + LoadFile("/script.txt",(uint8_t*)script,LITTLEFS_SCRIPT_SIZE); glob_script_mem.script_ram=script; - glob_script_mem.script_size=ESP32_SCRIPT_SIZE; - script[ESP32_SCRIPT_SIZE-1]=0; + glob_script_mem.script_size=LITTLEFS_SCRIPT_SIZE; + script[LITTLEFS_SCRIPT_SIZE-1]=0; // use rules storage for permanent vars glob_script_mem.script_pram=(uint8_t*)Settings.rules[0]; glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE; diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index d2466d051..43245c794 100644 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -505,7 +505,7 @@ void DisplayText(void) cp += var; linebuf[fill] = 0; break; -#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) +#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) && USE_SCRIPT_FATFS>=0 case 'P': { char *ep=strchr(cp,':'); if (ep) { @@ -1510,8 +1510,13 @@ void rgb888_to_565(uint8_t *in, uint16_t *out, uint32_t len); #endif #endif +#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) && USE_SCRIPT_FATFS>=0 -#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) +#ifdef ESP32 +extern FS *fsp; +#else +extern SDClass *fsp; +#endif #define XBUFF_LEN 128 void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) { if (!renderer) return; @@ -1527,7 +1532,7 @@ void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) { if (!strcmp(estr,"rgb")) { // special rgb format - fp=SD.open(file,FILE_READ); + fp=fsp->open(file,FILE_READ); if (!fp) return; uint16_t xsize; fp.read((uint8_t*)&xsize,2); @@ -1564,7 +1569,7 @@ void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) { #ifdef ESP32 #ifdef JPEG_PICTS if (psramFound()) { - fp=SD.open(file,FILE_READ); + fp=fsp->open(file,FILE_READ); if (!fp) return; uint32_t size = fp.size(); uint8_t *mem = (uint8_t *)heap_caps_malloc(size+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); @@ -1850,7 +1855,9 @@ void DisplayCheckGraph() { #if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) +#ifdef ESP32 #include +#endif void Save_graph(uint8_t num, char *path) { if (!renderer) return; @@ -1858,8 +1865,8 @@ void Save_graph(uint8_t num, char *path) { struct GRAPH *gp=graph[index]; if (!gp) return; File fp; - SD.remove(path); - fp=SD.open(path,FILE_WRITE); + fsp->remove(path); + fp=fsp->open(path,FILE_WRITE); if (!fp) return; char str[32]; sprintf_P(str,PSTR("%d\t%d\t%d\t"),gp->xcnt,gp->xs,gp->ys); @@ -1884,7 +1891,7 @@ void Restore_graph(uint8_t num, char *path) { struct GRAPH *gp=graph[index]; if (!gp) return; File fp; - fp=SD.open(path,FILE_READ); + fp=fsp->open(path,FILE_READ); if (!fp) return; char vbuff[32]; char *cp=vbuff; From 8447a3a703a1d556e7a41369dcc2265fb673c971 Mon Sep 17 00:00:00 2001 From: Staars Date: Sun, 31 May 2020 10:37:52 +0200 Subject: [PATCH 129/581] Update serial-plotter.py, more infos in the code, small refactorings --- tools/serial-plotter.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tools/serial-plotter.py b/tools/serial-plotter.py index 5abde9c72..83ec6dba6 100644 --- a/tools/serial-plotter.py +++ b/tools/serial-plotter.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ serial-plotter.py - for Tasmota @@ -20,7 +20,8 @@ Requirements: - Python - - pip3 matplotlib + - pip3 install matplotlib pyserial + - for Windows: Full python install including tkinter - a Tasmotadriver that plots Instructions: @@ -32,8 +33,7 @@ Instructions: AddLog_P2(LOG_LEVEL_INFO, PSTR("PLOT: %u, %u, %u,"),button_index+1, _value, Button.touch_hits[button_index]); Usage: - set serial config in code - ./serial-plotter.py + ./serial-plotter.py --port /dev/PORT --baud BAUD (or change defaults in the script) set output in tasmota, e.g.; TouchCal 1..4 (via Textbox) """ @@ -44,6 +44,10 @@ from matplotlib.widgets import TextBox import time import serial import argparse +import sys + +print("Python version") +print (sys.version) #default values port = '/dev/cu.SLAB_USBtoUART' @@ -164,25 +168,25 @@ def handle_close(evt): ser.close() print('Closed serial plotter') +def submit(text): + print (text) + ser.write(text.encode() + "\n".encode()) + + ani = animation.FuncAnimation(fig, update, None, fargs=[line1, line2], interval=10, blit=True, init_func=init) ax.set_xlabel('Last 200 Samples') ax.set_ylabel('Values') +plt.subplots_adjust(bottom=0.25) +ax.legend(loc='lower right', ncol=2) fig.canvas.mpl_connect('close_event', handle_close) -def submit(text): - print (text) - ser.write(text.encode() + "\n".encode()) - -plt.subplots_adjust(bottom=0.25) axbox = plt.axes([0.15, 0.05, 0.7, 0.075]) text_box = TextBox(axbox, 'Send:', initial='') text_box.on_submit(submit) -ax.legend(loc='lower right', ncol=2) - if ser.is_open==True: plt.show() - + \ No newline at end of file From 72014b777314fad588bb09e0f38b6ed8e3f6d520 Mon Sep 17 00:00:00 2001 From: halfbakery Date: Sun, 31 May 2020 12:46:15 +0200 Subject: [PATCH 130/581] Make a previously undocumented switch debouncing feature clean and official --- tasmota/support_switch.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/support_switch.ino b/tasmota/support_switch.ino index 46b642e5b..c13243c0e 100644 --- a/tasmota/support_switch.ino +++ b/tasmota/support_switch.ino @@ -82,8 +82,8 @@ void SwitchProbe(void) if (uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit uint8_t state_filter = Settings.switch_debounce / SWITCH_PROBE_INTERVAL; // 5, 10, 15 - uint8_t force_high = (Settings.switch_debounce % 50) &1; // 51, 101, 151 etc - uint8_t force_low = (Settings.switch_debounce % 50) &2; // 52, 102, 152 etc + uint8_t force_high = (Settings.switch_debounce % 10) &1; // 51, 101, 151 etc + uint8_t force_low = (Settings.switch_debounce % 10) &2; // 52, 102, 152 etc for (uint32_t i = 0; i < MAX_SWITCHES; i++) { if (PinUsed(GPIO_SWT1, i)) { From b97e7cd1e475e228d0b47ba735e045d0f1b00766 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 31 May 2020 16:28:02 +0200 Subject: [PATCH 131/581] Fix Sonoff Dual Buttons Fix Sonoff Dual Buttons (#8560) --- tasmota/support_button.ino | 71 +++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/tasmota/support_button.ino b/tasmota/support_button.ino index a92a56be5..bf058db4e 100644 --- a/tasmota/support_button.ino +++ b/tasmota/support_button.ino @@ -44,7 +44,7 @@ struct BUTTON { uint8_t dual_receive_count = 0; // Sonoff dual input flag uint8_t no_pullup_mask = 0; // key no pullup flag (1 = no pullup) uint8_t inverted_mask = 0; // Key inverted flag (1 = inverted) -#ifdef ESP32 +#ifdef ESP32 uint8_t touch_mask = 0; // Touch flag (1 = inverted) uint8_t touch_hits[MAX_KEYS] = { 0 }; // Hits in a row to filter out noise #endif // ESP32 @@ -80,6 +80,11 @@ void ButtonTouchFlag(uint8 button_bit) void ButtonInit(void) { Button.present = 0; +#ifdef ESP8266 + if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) { + Button.present++; + } +#endif // ESP8266 for (uint32_t i = 0; i < MAX_KEYS; i++) { if (PinUsed(GPIO_KEY1, i)) { Button.present++; @@ -151,29 +156,35 @@ void ButtonHandler(void) Button.dual_code = 0; } } - else - if (PinUsed(GPIO_KEY1, button_index)) { - button_present = 1; - button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index)); + else { + if (PinUsed(GPIO_KEY1, button_index)) { + button_present = 1; + button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index)); + } } #else if (PinUsed(GPIO_KEY1, button_index)) { button_present = 1; - if (bitRead(Button.touch_mask, button_index)){ // Touch + if (bitRead(Button.touch_mask, button_index)) { // Touch uint32_t _value = touchRead(Pin(GPIO_KEY1, button_index)); button = NOT_PRESSED; - if (_value != 0){ // probably read-error - if(_value < TOUCH_BUTTON.pin_threshold){ - if(++Button.touch_hits[button_index]>TOUCH_BUTTON.hit_threshold){ - if (!bitRead(TOUCH_BUTTON.calibration, button_index+1)) button = PRESSED; + if (_value != 0) { // Probably read-error + if (_value < TOUCH_BUTTON.pin_threshold) { + if (++Button.touch_hits[button_index] > TOUCH_BUTTON.hit_threshold) { + if (!bitRead(TOUCH_BUTTON.calibration, button_index+1)) { + button = PRESSED; + } } + } else { + Button.touch_hits[button_index] = 0; } - else Button.touch_hits[button_index] = 0; + } else { + Button.touch_hits[button_index] = 0; } - else Button.touch_hits[button_index] = 0; - if (bitRead(TOUCH_BUTTON.calibration, button_index+1)) AddLog_P2(LOG_LEVEL_INFO, PSTR("PLOT: %u, %u, %u,"),button_index+1, _value, Button.touch_hits[button_index]); // button number (1..4) , value, continuous hits under threshold - } - else{ // Normal button + if (bitRead(TOUCH_BUTTON.calibration, button_index+1)) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("PLOT: %u, %u, %u,"), button_index+1, _value, Button.touch_hits[button_index]); // Button number (1..4), value, continuous hits under threshold + } + } else { // Normal button button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index)); } } @@ -210,12 +221,12 @@ void ButtonHandler(void) if (!Button.hold_timer[button_index]) { button_pressed = true; } // Do not allow within 1 second } if (button_pressed) { - if (!Settings.flag3.mqtt_buttons) { + if (!Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally } } else { - MqttButtonTopic(button_index +1, 1, 0); // SetOption73 (0) - Decouple button from relay and send just mqtt topic + MqttButtonTopic(button_index +1, 1, 0); // SetOption73 (0) - Decouple button from relay and send just mqtt topic } } } @@ -244,7 +255,7 @@ void ButtonHandler(void) Button.hold_timer[button_index] = 0; } else { Button.hold_timer[button_index]++; - if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action + if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action if (Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button held for factor times longer snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_SETOPTION "13 0")); // Disable single press only ExecuteCommand(scmnd, SRC_BUTTON); @@ -252,13 +263,13 @@ void ButtonHandler(void) } else { if (Button.hold_timer[button_index] == loops_per_second * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button hold Button.press_counter[button_index] = 0; - if (Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic + if (Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic MqttButtonTopic(button_index +1, 3, 1); } else { SendKey(KEY_BUTTON, button_index +1, POWER_HOLD); // Execute Hold command via MQTT if ButtonTopic is set } } else { - if (!Settings.flag.button_restrict) { + if (!Settings.flag.button_restrict) { // SetOption1 - Control button multipress if ((Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10)) { // SetOption32 (40) - Button held for factor times longer Button.press_counter[button_index] = 0; snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1")); @@ -269,14 +280,14 @@ void ButtonHandler(void) } } - if (!Settings.flag.button_single) { // SetOption13 (0) - Allow multi-press + if (!Settings.flag.button_single) { // SetOption13 (0) - Allow multi-press if (Button.window_timer[button_index]) { Button.window_timer[button_index]--; } else { if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < 7)) { bool single_press = false; - if (Button.press_counter[button_index] < 3) { // Single or Double press + if (Button.press_counter[button_index] < 3) { // Single or Double press #ifdef ESP8266 if ((SONOFF_DUAL_R2 == my_module_type) || (SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) { single_press = true; @@ -301,15 +312,21 @@ void ButtonHandler(void) if (WifiState() > WIFI_RESTART) { // Wifimanager active restart_flag = 1; } - if (!Settings.flag3.mqtt_buttons) { - if (Button.press_counter[button_index] == 1) { // By default first press always send a TOGGLE (2) + if (!Settings.flag3.mqtt_buttons) { // SetOption73 - Detach buttons from relays and enable MQTT action state for multipress + if (Button.press_counter[button_index] == 1) { // By default first press always send a TOGGLE (2) ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON); } else { SendKey(KEY_BUTTON, button_index +1, Button.press_counter[button_index] +9); // 2,3,4 and 5 press send just the key value (11,12,13 and 14) for rules - if (0 == button_index) { // BUTTON1 can toggle up to 5 relays if present. If a relay is not present will send out the key value (2,11,12,13 and 14) for rules - if ((Button.press_counter[button_index] > 1 && PinUsed(GPIO_REL1, Button.press_counter[button_index]-1)) && Button.press_counter[button_index] <= MAX_RELAY_BUTTON1) { + if (0 == button_index) { // BUTTON1 can toggle up to 5 relays if present. If a relay is not present will send out the key value (2,11,12,13 and 14) for rules + bool valid_relay = PinUsed(GPIO_REL1, Button.press_counter[button_index]-1); +#ifdef ESP8266 + if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) { + valid_relay = (Button.press_counter[button_index] <= devices_present); + } +#endif // ESP8266 + if ((Button.press_counter[button_index] > 1) && valid_relay && (Button.press_counter[button_index] <= MAX_RELAY_BUTTON1)) { ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: Relay%d found on GPIO%d"), Button.press_counter[button_index], Pin(GPIO_REL1, Button.press_counter[button_index]-1)); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: Relay%d found on GPIO%d"), Button.press_counter[button_index], Pin(GPIO_REL1, Button.press_counter[button_index]-1)); } } } From 917124af2614ae5ea10531c242983feb9b560f0b Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Mon, 1 Jun 2020 11:51:57 +0200 Subject: [PATCH 132/581] fix start without stop condition --- tasmota/support.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/support.ino b/tasmota/support.ino index 9d1ff07f4..839e126f6 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1459,6 +1459,7 @@ bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size) } retry--; } + if (!retry) Wire.endTransmission(); return status; } From f1a2fb2b8d30c92b3780d6ac1e20f2784bb443d0 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 1 Jun 2020 15:17:32 +0200 Subject: [PATCH 133/581] fix serial buffer issues --- lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp | 1 + tasmota/xsns_52_ibeacon.ino | 10 ++++++---- tasmota/xsns_53_sml.ino | 19 ++++++++++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) mode change 100644 => 100755 tasmota/xsns_52_ibeacon.ino diff --git a/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp b/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp index 6b41d068c..7a09518c2 100644 --- a/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp +++ b/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp @@ -174,6 +174,7 @@ bool TasmotaSerial::begin(long speed, int stop_bits) { m_uart = tasmota_serial_index; tasmota_serial_index--; TSerial = new HardwareSerial(m_uart); + if (TM_SERIAL_BUFFER_SIZE != serial_buffer_size) TSerial->setRxBufferSize(serial_buffer_size); if (2 == m_stop_bits) { TSerial->begin(speed, SERIAL_8N2, m_rx_pin, m_tx_pin); } else { diff --git a/tasmota/xsns_52_ibeacon.ino b/tasmota/xsns_52_ibeacon.ino old mode 100644 new mode 100755 index 88b040e76..5f9c0f3ba --- a/tasmota/xsns_52_ibeacon.ino +++ b/tasmota/xsns_52_ibeacon.ino @@ -25,6 +25,8 @@ #include +#define TMSBSIZ 256 + #define HM17_BAUDRATE 9600 #define IBEACON_DEBUG @@ -96,7 +98,7 @@ void IBEACON_Init() { // actually doesnt work reliably with software serial if (PinUsed(GPIO_IBEACON_RX) && PinUsed(GPIO_IBEACON_TX)) { - IBEACON_Serial = new TasmotaSerial(Pin(GPIO_IBEACON_RX), Pin(GPIO_IBEACON_TX),1); + IBEACON_Serial = new TasmotaSerial(Pin(GPIO_IBEACON_RX), Pin(GPIO_IBEACON_TX),1,0,TMSBSIZ); if (IBEACON_Serial->begin(HM17_BAUDRATE)) { if (IBEACON_Serial->hardwareSerial()) { ClaimSerial(); @@ -144,7 +146,7 @@ void hm17_every_second(void) { void hm17_sbclr(void) { memset(hm17_sbuffer,0,HM17_BSIZ); hm17_sindex=0; - IBEACON_Serial->flush(); + //IBEACON_Serial->flush(); } void hm17_sendcmd(uint8_t cmd) { @@ -405,7 +407,7 @@ hm17_v110: } } else { #ifdef IBEACON_DEBUG - if (hm17_debug) AddLog_P2(LOG_LEVEL_INFO, PSTR(">>%s"),&hm17_sbuffer[8]); + if (hm17_debug) AddLog_P2(LOG_LEVEL_INFO, PSTR(">->%s"),&hm17_sbuffer[8]); #endif } break; @@ -517,7 +519,7 @@ bool xsns52_cmd(void) { #ifdef IBEACON_DEBUG else if (*cp=='d') { cp++; - if (*cp) hm17_debug=atoi(cp); + hm17_debug=atoi(cp); Response_P(S_JSON_IBEACON, XSNS_52,"debug",hm17_debug); } #endif diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index 3b4357b26..cb51bcc82 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -49,6 +49,8 @@ #define SPECIAL_SS #endif +#define TMSBSIZ 256 + // addresses a bug in meter DWS74 //#define DWS74_BUG @@ -2144,9 +2146,9 @@ init10: // serial input, init #ifdef SPECIAL_SS if (meter_desc_p[meters].type=='m' || meter_desc_p[meters].type=='M' || meter_desc_p[meters].type=='p') { - meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1); + meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,0,TMSBSIZ); } else { - meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,1); + meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,1,TMSBSIZ); } #else #ifdef ESP32 @@ -2154,8 +2156,9 @@ init10: if (uart_index==0) { ClaimSerial(); } uart_index--; if (uart_index<0) uart_index=0; + meter_ss[meters]->setRxBufferSize(TMSBSIZ); #else - meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1); + meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,0,TMSBSIZ); #endif #endif @@ -2188,6 +2191,15 @@ uint32_t SML_SetBaud(uint32_t meter, uint32_t br) { if (meter<1 || meter>meters_used) return 0; meter--; if (!meter_ss[meter]) return 0; + +#ifdef ESP32 + meter_ss[meter]->flush(); + if (meter_desc_p[meter].type=='M') { + meter_ss[meter]->begin(br,SERIAL_8E1,meter_desc_p[meter].srcpin,meter_desc_p[meter].trxpin); + } else { + meter_ss[meter]->begin(br,SERIAL_8N1,meter_desc_p[meter].srcpin,meter_desc_p[meter].trxpin); + } +#else if (meter_ss[meter]->begin(br)) { meter_ss[meter]->flush(); } @@ -2196,6 +2208,7 @@ uint32_t SML_SetBaud(uint32_t meter, uint32_t br) { Serial.begin(br, SERIAL_8E1); } } +#endif return 1; } From 02375d6b28647529c6dc55cd5fba66d17b97ab7b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 1 Jun 2020 15:45:22 +0200 Subject: [PATCH 134/581] Update TasmotaSerial.cpp --- lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp b/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp index 7a09518c2..6982779d5 100644 --- a/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp +++ b/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp @@ -174,7 +174,9 @@ bool TasmotaSerial::begin(long speed, int stop_bits) { m_uart = tasmota_serial_index; tasmota_serial_index--; TSerial = new HardwareSerial(m_uart); - if (TM_SERIAL_BUFFER_SIZE != serial_buffer_size) TSerial->setRxBufferSize(serial_buffer_size); + if (serial_buffer_size > 256) { + TSerial->setRxBufferSize(serial_buffer_size); + } if (2 == m_stop_bits) { TSerial->begin(speed, SERIAL_8N2, m_rx_pin, m_tx_pin); } else { From eafaccfcda2515a2c2cc0538c6831694d6790c85 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 1 Jun 2020 18:00:56 +0200 Subject: [PATCH 135/581] Add support for up to two BH1750 sensors Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/settings.h | 5 +- tasmota/xsns_10_bh1750.ino | 177 ++++++++++++++++++++++--------------- 4 files changed, 108 insertions(+), 76 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index bf2983136..f0f2c1e69 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -71,3 +71,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add Zigbee options to ``ZbSend`` to write and report attributes - Add ``CpuFrequency`` to ``status 2`` - Add ``FlashFrequency`` to ``status 4`` +- Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 8e48a6302..60563404f 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -14,6 +14,7 @@ - Add Zigbee options to ``ZbSend`` to write and report attributes - Add ``CpuFrequency`` to ``status 2`` - Add ``FlashFrequency`` to ``status 4`` +- Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) ### 8.3.1.1 20200518 diff --git a/tasmota/settings.h b/tasmota/settings.h index accf21842..0ad7a3533 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -232,9 +232,8 @@ typedef union { struct { uint8_t spare0 : 1; uint8_t spare1 : 1; - uint8_t spare2 : 1; - uint8_t spare3 : 1; - uint8_t bh1750_resolution : 2; // Sensor10 1,2,3 + uint8_t bh1750_2_resolution : 2; + uint8_t bh1750_1_resolution : 2; // Sensor10 1,2,3 uint8_t hx711_json_weight_change : 1; // Sensor34 8,x - Enable JSON message on weight change uint8_t mhz19b_abc_disable : 1; // Disable ABC (Automatic Baseline Correction for MHZ19(B) (0 = Enabled (default), 1 = Disabled with Sensor15 command) }; diff --git a/tasmota/xsns_10_bh1750.ino b/tasmota/xsns_10_bh1750.ino index a098166df..7af8e3960 100644 --- a/tasmota/xsns_10_bh1750.ino +++ b/tasmota/xsns_10_bh1750.ino @@ -22,6 +22,11 @@ /*********************************************************************************************\ * BH1750 - Ambient Light Intensity * + * Bh1750Resolution1 0..2 - Set BH1750 1 resolution mode + * Bh1750Resolution2 0..2 - Set BH1750 2 resolution mode + * Bh1750MTime1 30..255 - Set BH1750 1 MT register + * Bh1750MTime2 30..255 - Set BH1750 2 MT register + * * I2C Address: 0x23 or 0x5C \*********************************************************************************************/ @@ -38,119 +43,148 @@ #define BH1750_MEASUREMENT_TIME_HIGH 0x40 // Measurement Time register high 3 bits #define BH1750_MEASUREMENT_TIME_LOW 0x60 // Measurement Time register low 5 bits -struct BH1750DATA { - uint8_t address; +#define D_PRFX_BH1750 "Bh1750" +#define D_CMND_RESOLUTION "Resolution" +#define D_CMND_MTREG "MTime" + +const char kBh1750Commands[] PROGMEM = D_PRFX_BH1750 "|" // Prefix + D_CMND_RESOLUTION "|" D_CMND_MTREG ; + +void (* const Bh1750Command[])(void) PROGMEM = { + &CmndBh1750Resolution, &CmndBh1750MTime }; + +struct { uint8_t addresses[2] = { BH1750_ADDR1, BH1750_ADDR2 }; uint8_t resolution[3] = { BH1750_CONTINUOUS_HIGH_RES_MODE, BH1750_CONTINUOUS_HIGH_RES_MODE2, BH1750_CONTINUOUS_LOW_RES_MODE }; - uint8_t type = 0; - uint8_t valid = 0; - uint8_t mtreg = 69; // Default Measurement Time - uint16_t illuminance = 0; + uint8_t count = 0; char types[7] = "BH1750"; } Bh1750; +struct { + uint8_t address; + uint8_t valid = 0; + uint8_t mtreg = 69; // Default Measurement Time + uint16_t illuminance = 0; +} Bh1750_sensors[2]; + /*********************************************************************************************/ -bool Bh1750SetResolution(void) -{ - Wire.beginTransmission(Bh1750.address); - Wire.write(Bh1750.resolution[Settings.SensorBits1.bh1750_resolution]); +uint8_t Bh1750Resolution(uint32_t sensor_index) { + uint8_t settings_resolution = Settings.SensorBits1.bh1750_1_resolution; + if (1 == sensor_index) { + settings_resolution = Settings.SensorBits1.bh1750_2_resolution; + } + return settings_resolution; +} + +bool Bh1750SetResolution(uint32_t sensor_index) { + Wire.beginTransmission(Bh1750_sensors[sensor_index].address); + Wire.write(Bh1750.resolution[Bh1750Resolution(sensor_index)]); return (!Wire.endTransmission()); } -bool Bh1750SetMTreg(void) -{ - Wire.beginTransmission(Bh1750.address); - uint8_t data = BH1750_MEASUREMENT_TIME_HIGH | ((Bh1750.mtreg >> 5) & 0x07); +bool Bh1750SetMTreg(uint32_t sensor_index) { + Wire.beginTransmission(Bh1750_sensors[sensor_index].address); + uint8_t data = BH1750_MEASUREMENT_TIME_HIGH | ((Bh1750_sensors[sensor_index].mtreg >> 5) & 0x07); Wire.write(data); if (Wire.endTransmission()) { return false; } - Wire.beginTransmission(Bh1750.address); - data = BH1750_MEASUREMENT_TIME_LOW | (Bh1750.mtreg & 0x1F); + Wire.beginTransmission(Bh1750_sensors[sensor_index].address); + data = BH1750_MEASUREMENT_TIME_LOW | (Bh1750_sensors[sensor_index].mtreg & 0x1F); Wire.write(data); if (Wire.endTransmission()) { return false; } - return Bh1750SetResolution(); + return Bh1750SetResolution(sensor_index); } -bool Bh1750Read(void) -{ - if (Bh1750.valid) { Bh1750.valid--; } +bool Bh1750Read(uint32_t sensor_index) { + if (Bh1750_sensors[sensor_index].valid) { Bh1750_sensors[sensor_index].valid--; } + + if (2 != Wire.requestFrom(Bh1750_sensors[sensor_index].address, (uint8_t)2)) { return false; } - if (2 != Wire.requestFrom(Bh1750.address, (uint8_t)2)) { return false; } float illuminance = (Wire.read() << 8) | Wire.read(); - illuminance /= (1.2 * (69 / (float)Bh1750.mtreg)); - if (1 == Settings.SensorBits1.bh1750_resolution) { + illuminance /= (1.2 * (69 / (float)Bh1750_sensors[sensor_index].mtreg)); + if (1 == Bh1750Resolution(sensor_index)) { illuminance /= 2; } - Bh1750.illuminance = illuminance; + Bh1750_sensors[sensor_index].illuminance = illuminance; - Bh1750.valid = SENSOR_MAX_MISS; + Bh1750_sensors[sensor_index].valid = SENSOR_MAX_MISS; return true; } /********************************************************************************************/ -void Bh1750Detect(void) -{ +void Bh1750Detect(void) { for (uint32_t i = 0; i < sizeof(Bh1750.addresses); i++) { - Bh1750.address = Bh1750.addresses[i]; - if (I2cActive(Bh1750.address)) { continue; } + if (I2cActive(Bh1750.addresses[i])) { continue; } - if (Bh1750SetMTreg()) { - I2cSetActiveFound(Bh1750.address, Bh1750.types); - Bh1750.type = 1; - break; + Bh1750_sensors[Bh1750.count].address = Bh1750.addresses[i]; + if (Bh1750SetMTreg(Bh1750.count)) { + I2cSetActiveFound(Bh1750_sensors[Bh1750.count].address, Bh1750.types); + Bh1750.count++; } } } -void Bh1750EverySecond(void) -{ - // 1mS - if (!Bh1750Read()) { - AddLogMissed(Bh1750.types, Bh1750.valid); +void Bh1750EverySecond(void) { + for (uint32_t i = 0; i < Bh1750.count; i++) { + // 1mS + if (!Bh1750Read(i)) { +// AddLogMissed(Bh1750.types, Bh1750.valid); + } } } /*********************************************************************************************\ - * Command Sensor10 - * - * 0 - High resolution mode (default) - * 1 - High resolution mode 2 - * 2 - Low resolution mode - * 31..254 - Measurement Time value (not persistent, default is 69) + * Commands \*********************************************************************************************/ -bool Bh1750CommandSensor(void) -{ - if (XdrvMailbox.data_len) { +void CmndBh1750Resolution(void) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Bh1750.count)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { - Settings.SensorBits1.bh1750_resolution = XdrvMailbox.payload; - Bh1750SetResolution(); - } - else if ((XdrvMailbox.payload > 30) && (XdrvMailbox.payload < 255)) { - Bh1750.mtreg = XdrvMailbox.payload; - Bh1750SetMTreg(); + if (1 == XdrvMailbox.index) { + Settings.SensorBits1.bh1750_1_resolution = XdrvMailbox.payload; + } else { + Settings.SensorBits1.bh1750_2_resolution = XdrvMailbox.payload; + } + Bh1750SetResolution(XdrvMailbox.index -1); } + ResponseCmndIdxNumber(Bh1750Resolution(XdrvMailbox.index -1)); } - Response_P(PSTR("{\"" D_CMND_SENSOR "10\":{\"Resolution\":%d,\"MTime\":%d}}"), Settings.SensorBits1.bh1750_resolution, Bh1750.mtreg); - - return true; } -void Bh1750Show(bool json) -{ - if (Bh1750.valid) { - if (json) { - ResponseAppend_P(JSON_SNS_ILLUMINANCE, Bh1750.types, Bh1750.illuminance); -#ifdef USE_DOMOTICZ - if (0 == tele_period) { - DomoticzSensor(DZ_ILLUMINANCE, Bh1750.illuminance); +void CmndBh1750MTime(void) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Bh1750.count)) { + if ((XdrvMailbox.payload > 30) && (XdrvMailbox.payload < 255)) { + Bh1750_sensors[XdrvMailbox.index -1].mtreg = XdrvMailbox.payload; + Bh1750SetMTreg(XdrvMailbox.index -1); + } + ResponseCmndIdxNumber(Bh1750_sensors[XdrvMailbox.index -1].mtreg); + } +} + +/********************************************************************************************/ + +void Bh1750Show(bool json) { + for (uint32_t sensor_index = 0; sensor_index < Bh1750.count; sensor_index++) { + if (Bh1750_sensors[sensor_index].valid) { + char sensor_name[10]; + strlcpy(sensor_name, Bh1750.types, sizeof(sensor_name)); + if (Bh1750.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%d"), sensor_name, IndexSeparator(), sensor_index +1); // BH1750-1 } + + if (json) { + ResponseAppend_P(JSON_SNS_ILLUMINANCE, sensor_name, Bh1750_sensors[sensor_index].illuminance); +#ifdef USE_DOMOTICZ + if ((0 == tele_period) && (0 == sensor_index)) { + DomoticzSensor(DZ_ILLUMINANCE, Bh1750_sensors[sensor_index].illuminance); + } #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER - } else { - WSContentSend_PD(HTTP_SNS_ILLUMINANCE, Bh1750.types, Bh1750.illuminance); + } else { + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, sensor_name, Bh1750_sensors[sensor_index].illuminance); #endif // USE_WEBSERVER + } } } } @@ -159,8 +193,7 @@ void Bh1750Show(bool json) * Interface \*********************************************************************************************/ -bool Xsns10(uint8_t function) -{ +bool Xsns10(uint8_t function) { if (!I2cEnabled(XI2C_11)) { return false; } bool result = false; @@ -168,15 +201,13 @@ bool Xsns10(uint8_t function) if (FUNC_INIT == function) { Bh1750Detect(); } - else if (Bh1750.type) { + else if (Bh1750.count) { switch (function) { case FUNC_EVERY_SECOND: Bh1750EverySecond(); break; - case FUNC_COMMAND_SENSOR: - if (XSNS_10 == XdrvMailbox.index) { - result = Bh1750CommandSensor(); - } + case FUNC_COMMAND: + result = DecodeCommand(kBh1750Commands, Bh1750Command); break; case FUNC_JSON_APPEND: Bh1750Show(1); From 0fd566846bbdc994e157f2ac1117ccd880bac761 Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Mon, 1 Jun 2020 18:43:53 +0200 Subject: [PATCH 136/581] update de language for illuminance for a "more" German Word --- tasmota/language/de_DE.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 9f676f101..aa83ec0c2 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -107,7 +107,7 @@ #define D_HOST "Host" #define D_HOSTNAME "Hostname" #define D_HUMIDITY "Feuchtigkeit" -#define D_ILLUMINANCE "Beleuchtungsintensität" +#define D_ILLUMINANCE "Beleuchtungsstärke" #define D_IMMEDIATE "direkt" // Button immediate #define D_INDEX "Index" #define D_INFO "Info" From 965c2ae8072ba39c5028e051abb6ab33d5d2fb58 Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Mon, 1 Jun 2020 18:48:08 +0200 Subject: [PATCH 137/581] add 2 commands for VEML7700 Sensor (gain, integration time); value normalizing activated --- tasmota/xsns_71_veml7700.ino | 97 +++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 7 deletions(-) diff --git a/tasmota/xsns_71_veml7700.ino b/tasmota/xsns_71_veml7700.ino index de28661cc..18a57bcf7 100644 --- a/tasmota/xsns_71_veml7700.ino +++ b/tasmota/xsns_71_veml7700.ino @@ -37,12 +37,27 @@ Adafruit_VEML7700 veml7700 = Adafruit_VEML7700(); //create object copy const char HTTP_SNS_WHITE[] PROGMEM = "{s}%s " D_WHITE_CONTENT "{m}%d {e}"; const char JSON_SNS_VEML7700[] PROGMEM = ",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d,\"" D_JSON_WHITE_CONTENT "\":%d}"; +#define D_CMND_VEML7700_PWR "power" +#define D_CMND_VEML7700_GAIN "gain" +#define D_CMND_VEML7700_INTTIME "inttime" + +const char S_JSON_VEML7700_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_VEML7700 "\":{\"%s\":%d}}"; +const char kVEML7700_Commands[] PROGMEM = D_CMND_VEML7700_PWR "|" D_CMND_VEML7700_GAIN "|" D_CMND_VEML7700_INTTIME; + +enum VEML7700_Commands { // commands for Console + CMND_VEML7700_PWR, + CMND_VEML7700_GAIN, + CMND_VEML7700_SET_IT, + }; + struct VEML7700STRUCT { char types[9] = D_NAME_VEML7700; uint8_t address = VEML7700_I2CADDR_DEFAULT; uint16_t lux = 0; uint16_t white = 0; + uint16_t lux_normalized = 0; + uint16_t white_normalized = 0; } veml7700_sensor; uint8_t veml7700_active = 0; @@ -57,27 +72,95 @@ void VEML7700Detect(void) { } } +uint16_t VEML7700TranslateItMs (uint8_t ittime){ + switch (ittime) { + case 0: return 100; + case 1: return 200; + case 2: return 400; + case 3: return 800; + case 8: return 50; + case 12: return 25; + default: return 0xFFFF; + } +} + +uint8_t VEML7700TranslateItInt (uint16_t ittimems){ + switch (ittimems) { + case 100: return 0; + case 200: return 1; + case 400: return 2; + case 800: return 3; + case 50: return 8; + case 25: return 12; + default: return 0xFF; + } +} + void VEML7700EverySecond(void) { - veml7700_sensor.lux = (uint16_t) veml7700.readLux(); - veml7700_sensor.white = (uint16_t) veml7700.readWhite(); + veml7700_sensor.lux_normalized = (uint16_t) veml7700.readLuxNormalized(); + veml7700_sensor.white_normalized = (uint16_t) veml7700.readWhiteNormalized(); + //veml7700_sensor.lux = (uint16_t) veml7700.readLux(); + //veml7700_sensor.white = (uint16_t) veml7700.readWhite(); } void VEML7700Show(bool json) { if (json) { - ResponseAppend_P(JSON_SNS_VEML7700, D_NAME_VEML7700, veml7700_sensor.lux, veml7700_sensor.white); + ResponseAppend_P(JSON_SNS_VEML7700, D_NAME_VEML7700, veml7700_sensor.lux_normalized, veml7700_sensor.white); #ifdef USE_DOMOTICZ - if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, veml7700_sensor.lux); + if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, veml7700_sensor.lux_normalized); #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { - WSContentSend_PD(HTTP_SNS_ILLUMINANCE, D_NAME_VEML7700, veml7700_sensor.lux); - WSContentSend_PD(HTTP_SNS_WHITE, D_NAME_VEML7700, veml7700_sensor.white); + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, D_NAME_VEML7700, veml7700_sensor.lux_normalized); + WSContentSend_PD(HTTP_SNS_WHITE, D_NAME_VEML7700, veml7700_sensor.white_normalized); #endif // USE_WEBSERVER } } +bool VEML7700Cmd(void) { + char command[CMDSZ]; + uint8_t name_len = strlen(D_NAME_VEML7700); + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_VEML7700), name_len)) { + uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kVEML7700_Commands); + switch (command_code) { + case CMND_VEML7700_PWR: + if (XdrvMailbox.data_len) { + if (2 >= XdrvMailbox.payload) { + veml7700.enable(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML7700_COMMAND_NVALUE, command, veml7700.enabled()); + break; + case CMND_VEML7700_GAIN: + if (XdrvMailbox.data_len) { + if (4 >= XdrvMailbox.payload) { + veml7700.setGain(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML7700_COMMAND_NVALUE, command, veml7700.getGain()); + break; + case CMND_VEML7700_SET_IT: { + if (XdrvMailbox.data_len) { + uint8_t data = VEML7700TranslateItInt(XdrvMailbox.payload); + if (0xFF != data) { + veml7700.setIntegrationTime(data); + } + } + uint16_t dataret = VEML7700TranslateItMs(veml7700.getIntegrationTime()); + Response_P(S_JSON_VEML7700_COMMAND_NVALUE, command, dataret); + } + break; + default: + return false; + } + return true; + } + else { + return false; + } +} /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -97,7 +180,7 @@ bool Xsns71(uint8_t function) VEML7700EverySecond(); break; case FUNC_COMMAND: - //result = VEML7700Cmd(); + result = VEML7700Cmd(); break; case FUNC_JSON_APPEND: VEML7700Show(1); From 8c29ead09d52151c8e441dbd598ce743b0672678 Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Tue, 2 Jun 2020 08:35:49 +0200 Subject: [PATCH 138/581] Add support for up to eight MCP9808 temperature sensors --- BUILDS.md | 3 + I2CDEVICES.md | 3 +- RELEASENOTES.md | 1 + .../.github/ISSUE_TEMPLATE.md | 46 +++ .../.github/PULL_REQUEST_TEMPLATE.md | 26 ++ .../.github/workflows/githubci.yml | 32 ++ lib/Adafruit_MCP9808_Tasmota/.gitignore | 8 + .../Adafruit_MCP9808.cpp | 273 ++++++++++++++++++ .../Adafruit_MCP9808.h | 87 ++++++ lib/Adafruit_MCP9808_Tasmota/README.md | 18 ++ lib/Adafruit_MCP9808_Tasmota/assets/board.jpg | Bin 0 -> 134987 bytes .../code-of-conduct.md | 127 ++++++++ .../examples/mcp9808test/mcp9808test.ino | 69 +++++ .../library.properties | 10 + lib/Adafruit_MCP9808_Tasmota/license.txt | 26 ++ tasmota/my_user_config.h | 1 + tasmota/support_features.ino | 4 +- tasmota/tasmota_configurations.h | 1 + tasmota/xsns_72_mcp9808.ino | 136 +++++++++ tools/decode-status.py | 2 +- 20 files changed, 870 insertions(+), 3 deletions(-) create mode 100644 lib/Adafruit_MCP9808_Tasmota/.github/ISSUE_TEMPLATE.md create mode 100644 lib/Adafruit_MCP9808_Tasmota/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 lib/Adafruit_MCP9808_Tasmota/.github/workflows/githubci.yml create mode 100644 lib/Adafruit_MCP9808_Tasmota/.gitignore create mode 100644 lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.cpp create mode 100644 lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.h create mode 100644 lib/Adafruit_MCP9808_Tasmota/README.md create mode 100644 lib/Adafruit_MCP9808_Tasmota/assets/board.jpg create mode 100644 lib/Adafruit_MCP9808_Tasmota/code-of-conduct.md create mode 100644 lib/Adafruit_MCP9808_Tasmota/examples/mcp9808test/mcp9808test.ino create mode 100644 lib/Adafruit_MCP9808_Tasmota/library.properties create mode 100644 lib/Adafruit_MCP9808_Tasmota/license.txt create mode 100644 tasmota/xsns_72_mcp9808.ino diff --git a/BUILDS.md b/BUILDS.md index ec1720d44..92d081c1e 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -139,6 +139,9 @@ | USE_HRXL | - | - | - | - | x | - | - | | USE_TASMOTA_SLAVE | - | - | - | - | - | - | - | | USE_OPENTHERM | - | - | - | - | - | - | - | +| USE_VEML6075 | - | - | - | - | - | - | - | +| USE_VEML7700 | - | - | - | - | - | - | - | +| USE_MCP9808 | - | - | - | - | - | - | - | | | | | | | | | | | USE_NRF24 | - | - | - | - | - | - | - | | USE_MIBLE | - | - | - | - | - | - | - | diff --git a/I2CDEVICES.md b/I2CDEVICES.md index 788145d3e..4f6718b90 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -71,4 +71,5 @@ Index | Define | Driver | Device | Address(es) | Description 47 | USE_DISPLAY_SEVENSEG| xdsp_11 | HT16K33 | 0x70 - 0x77 | Seven segment LED 48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor 49 | USE_VEML6075 | xsns_70 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor - 50 | USE_VEML7700 | xsns_71 | VEML7700 | 0x10 | Ambient light intensity sensor \ No newline at end of file + 50 | USE_VEML7700 | xsns_71 | VEML7700 | 0x10 | Ambient light intensity sensor + 51 | USE_MCP9808 | xsns_72 | MCP9808 | 0x18 - 0x1F | Temperature sensor \ No newline at end of file diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f0f2c1e69..2453fd5d4 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -72,3 +72,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add ``CpuFrequency`` to ``status 2`` - Add ``FlashFrequency`` to ``status 4`` - Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) +- Add support for up to eight MCP9808 temperature sensors by device111 (#8594) diff --git a/lib/Adafruit_MCP9808_Tasmota/.github/ISSUE_TEMPLATE.md b/lib/Adafruit_MCP9808_Tasmota/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..f0e26146f --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/.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_MCP9808_Tasmota/.github/PULL_REQUEST_TEMPLATE.md b/lib/Adafruit_MCP9808_Tasmota/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..7b641eb86 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/.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_MCP9808_Tasmota/.github/workflows/githubci.yml b/lib/Adafruit_MCP9808_Tasmota/.github/workflows/githubci.yml new file mode 100644 index 000000000..cb226da94 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/.github/workflows/githubci.yml @@ -0,0 +1,32 @@ +name: Arduino Library CI + +on: [pull_request, push, repository_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/setup-python@v1 + with: + python-version: '3.x' + - uses: actions/checkout@v2 + - uses: actions/checkout@v2 + with: + repository: adafruit/ci-arduino + path: ci + + - name: pre-install + run: bash ci/actions_install.sh + + - name: test platforms + run: python3 ci/build_platform.py main_platforms + + - name: clang + run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . + + - name: doxygen + env: + GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} + PRETTYNAME : "Adafruit MCP9808 Arduino Library" + run: bash ci/doxy_gen_and_deploy.sh diff --git a/lib/Adafruit_MCP9808_Tasmota/.gitignore b/lib/Adafruit_MCP9808_Tasmota/.gitignore new file mode 100644 index 000000000..542d266a9 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/.gitignore @@ -0,0 +1,8 @@ +# osx +.DS_Store + +# doxygen +Doxyfile* +doxygen_sqlite3.db +html +*.tmp diff --git a/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.cpp b/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.cpp new file mode 100644 index 000000000..db3fa9f86 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.cpp @@ -0,0 +1,273 @@ +/*! + * @file Adafruit_MCP9808.cpp + * + * @mainpage Adafruit MCP9808 I2C Temp Sensor + * + * @section intro_sec Introduction + * + * I2C Driver for Microchip's MCP9808 I2C Temp sensor + * + * This is a library for the Adafruit MCP9808 breakout: + * http://www.adafruit.com/products/1782 + * + * 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 + * + * K.Townsend (Adafruit Industries) + * + * @section license License + * + * BSD (see license.txt) + * + * @section HISTORY + * + * v1.0 - First release + * + * changes by Martin Wagner for tasmota project: + * + * - the libary supports variabel I2C address + * + */ + +#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#ifdef __AVR_ATtiny85__ +#include "TinyWireM.h" +#define Wire TinyWireM +#else +#include +#endif + +#include "Adafruit_MCP9808.h" + +/*! + * @brief Instantiates a new MCP9808 class + */ +Adafruit_MCP9808::Adafruit_MCP9808() {} + +/*! + * @brief Setups the HW + * @param *theWire + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::begin(TwoWire *theWire) { + _wire = theWire; + _i2caddr = MCP9808_I2CADDR_DEFAULT; + return init(); +} + +/*! + * @brief Setups the HW + * @param addr + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::begin(uint8_t addr) { + _i2caddr = addr; + _wire = &Wire; + return init(); +} + +/*! + * @brief Setups the HW + * @param addr + * @param *theWire + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::begin(uint8_t addr, TwoWire *theWire) { + _i2caddr = addr; + _wire = theWire; + return init(); +} + +/*! + * @brief Setups the HW with default address + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::begin() { + _i2caddr = MCP9808_I2CADDR_DEFAULT; + _wire = &Wire; + return init(); +} + +/*! + * @brief init function + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::init() { + _wire->begin(); + + if (read16(MCP9808_REG_MANUF_ID) != 0x0054) + return false; + if (read16(MCP9808_REG_DEVICE_ID) != 0x0400) + return false; + + write16(MCP9808_REG_CONFIG, 0x0); + return true; +} + +/*! + * @brief Reads the 16-bit temperature register and returns the Centigrade + * temperature as a float. + * @return Temperature in Centigrade. + */ +float Adafruit_MCP9808::readTempC(uint8_t addr) { + _i2caddr = addr; + float temp = NAN; + uint16_t t = read16(MCP9808_REG_AMBIENT_TEMP); + + if (t != 0xFFFF) { + temp = t & 0x0FFF; + temp /= 16.0; + if (t & 0x1000) + temp -= 256; + } + + return temp; +} + +/*! + * @brief Reads the 16-bit temperature register and returns the Fahrenheit + * temperature as a float. + * @return Temperature in Fahrenheit. + */ +float Adafruit_MCP9808::readTempF(uint8_t addr) { + _i2caddr = addr; + float temp = NAN; + uint16_t t = read16(MCP9808_REG_AMBIENT_TEMP); + + if (t != 0xFFFF) { + temp = t & 0x0FFF; + temp /= 16.0; + if (t & 0x1000) + temp -= 256; + + temp = temp * 9.0 / 5.0 + 32; + } + + return temp; +} + +/*! + * @brief Set Sensor to Shutdown-State or wake up (Conf_Register BIT8) + * @param sw true = shutdown / false = wakeup + */ +void Adafruit_MCP9808::shutdown_wake(uint8_t addr, boolean sw) { + _i2caddr = addr; + uint16_t conf_shutdown; + uint16_t conf_register = read16(MCP9808_REG_CONFIG); + if (sw == true) { + conf_shutdown = conf_register | MCP9808_REG_CONFIG_SHUTDOWN; + write16(MCP9808_REG_CONFIG, conf_shutdown); + } + if (sw == false) { + conf_shutdown = conf_register & ~MCP9808_REG_CONFIG_SHUTDOWN; + write16(MCP9808_REG_CONFIG, conf_shutdown); + } +} + +/*! + * @brief Shutdown MCP9808 + */ +void Adafruit_MCP9808::shutdown(uint8_t addr) { shutdown_wake(addr, true); } + +/*! + * @brief Wake up MCP9808 + */ +void Adafruit_MCP9808::wake(uint8_t addr) { + shutdown_wake(addr, false); + delay(250); +} + +/*! + * @brief Get Resolution Value + * @return Resolution value + */ +uint8_t Adafruit_MCP9808::getResolution(uint8_t addr) { + _i2caddr = addr; + return read8(MCP9808_REG_RESOLUTION); +} + +/*! + * @brief Set Resolution Value + * @param value + */ +void Adafruit_MCP9808::setResolution(uint8_t addr, uint8_t value) { + _i2caddr = addr; + write8(MCP9808_REG_RESOLUTION, value & 0x03); +} + +/*! + * @brief Low level 16 bit write procedures + * @param reg + * @param value + */ +void Adafruit_MCP9808::write16(uint8_t reg, uint16_t value) { + _wire->beginTransmission(_i2caddr); + _wire->write((uint8_t)reg); + _wire->write(value >> 8); + _wire->write(value & 0xFF); + _wire->endTransmission(); +} + +/*! + * @brief Low level 16 bit read procedure + * @param reg + * @return value + */ +uint16_t Adafruit_MCP9808::read16(uint8_t reg) { + uint16_t val = 0xFFFF; + uint8_t state; + + _wire->beginTransmission(_i2caddr); + _wire->write((uint8_t)reg); + state = _wire->endTransmission(); + + if (state == 0) { + _wire->requestFrom((uint8_t)_i2caddr, (uint8_t)2); + val = _wire->read(); + val <<= 8; + val |= _wire->read(); + } + + return val; +} + +/*! + * @brief Low level 8 bit write procedure + * @param reg + * @param value + */ +void Adafruit_MCP9808::write8(uint8_t reg, uint8_t value) { + _wire->beginTransmission(_i2caddr); + _wire->write((uint8_t)reg); + _wire->write(value); + _wire->endTransmission(); +} + +/*! + * @brief Low level 8 bit read procedure + * @param reg + * @return value + */ +uint8_t Adafruit_MCP9808::read8(uint8_t reg) { + uint8_t val = 0xFF; + uint8_t state; + + _wire->beginTransmission(_i2caddr); + _wire->write((uint8_t)reg); + state = _wire->endTransmission(); + + if (state == 0) { + _wire->requestFrom((uint8_t)_i2caddr, (uint8_t)1); + val = _wire->read(); + } + + return val; +} diff --git a/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.h b/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.h new file mode 100644 index 000000000..c93351ca1 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.h @@ -0,0 +1,87 @@ +/*! + * @file Adafruit_MCP9808.h + * + * I2C Driver for Microchip's MCP9808 I2C Temp sensor + * + * This is a library for the Adafruit MCP9808 breakout: + * http://www.adafruit.com/products/1782 + * + * Adafruit invests time and resources providing this open source code, + *please support Adafruit and open-source hardware by purchasing products from + * Adafruit! + * + * + * BSD license (see license.txt) + * + * changes by Martin Wagner for tasmota project: + * + * - the libary supports variabel I2C address + * + */ + +#ifndef _ADAFRUIT_MCP9808_H +#define _ADAFRUIT_MCP9808_H + +#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#include + +#define MCP9808_I2CADDR_DEFAULT 0x18 ///< I2C address +#define MCP9808_REG_CONFIG 0x01 ///< MCP9808 config register + +#define MCP9808_REG_CONFIG_SHUTDOWN 0x0100 ///< shutdown config +#define MCP9808_REG_CONFIG_CRITLOCKED 0x0080 ///< critical trip lock +#define MCP9808_REG_CONFIG_WINLOCKED 0x0040 ///< alarm window lock +#define MCP9808_REG_CONFIG_INTCLR 0x0020 ///< interrupt clear +#define MCP9808_REG_CONFIG_ALERTSTAT 0x0010 ///< alert output status +#define MCP9808_REG_CONFIG_ALERTCTRL 0x0008 ///< alert output control +#define MCP9808_REG_CONFIG_ALERTSEL 0x0004 ///< alert output select +#define MCP9808_REG_CONFIG_ALERTPOL 0x0002 ///< alert output polarity +#define MCP9808_REG_CONFIG_ALERTMODE 0x0001 ///< alert output mode + +#define MCP9808_REG_UPPER_TEMP 0x02 ///< upper alert boundary +#define MCP9808_REG_LOWER_TEMP 0x03 ///< lower alert boundery +#define MCP9808_REG_CRIT_TEMP 0x04 ///< critical temperature +#define MCP9808_REG_AMBIENT_TEMP 0x05 ///< ambient temperature +#define MCP9808_REG_MANUF_ID 0x06 ///< manufacture ID +#define MCP9808_REG_DEVICE_ID 0x07 ///< device ID +#define MCP9808_REG_RESOLUTION 0x08 ///< resolutin + +/*! + * @brief Class that stores state and functions for interacting with + * MCP9808 Temp Sensor + */ +class Adafruit_MCP9808 { +public: + Adafruit_MCP9808(); + bool begin(); + bool begin(TwoWire *theWire); + bool begin(uint8_t addr); + bool begin(uint8_t addr, TwoWire *theWire); + + bool init(); + float readTempC(uint8_t addr); + float readTempF(uint8_t addr); + uint8_t getResolution(uint8_t addr); + void setResolution(uint8_t addr, uint8_t value); + + void shutdown_wake(uint8_t addr, boolean sw); + void shutdown(uint8_t addr); + void wake(uint8_t addr); + + void write16(uint8_t reg, uint16_t val); + uint16_t read16(uint8_t reg); + + void write8(uint8_t reg, uint8_t val); + uint8_t read8(uint8_t reg); + +private: + TwoWire *_wire; + uint8_t _i2caddr; +}; + +#endif diff --git a/lib/Adafruit_MCP9808_Tasmota/README.md b/lib/Adafruit_MCP9808_Tasmota/README.md new file mode 100644 index 000000000..0623f214f --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/README.md @@ -0,0 +1,18 @@ +# Adafruit MCP9808 Library [![Build Status](https://github.com/adafruit/Adafruit_MCP9808_Library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_MCP9808_Library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_MCP9808_Library/html/index.html) + + + +This is the Adafruit MCP9808 Precision I2C Temperature sensor library + +Tested and works great with the Adafruit MCP9808 Breakout Board +* http://www.adafruit.com/products/1782 + +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 Kevin Townsend/Limor Fried for Adafruit Industries. +BSD license, check license.txt for more information +All text above must be included in any redistribution + +To install, use the Arduino Library Manager and search for "Adafruit MCP9808" and install the library. diff --git a/lib/Adafruit_MCP9808_Tasmota/assets/board.jpg b/lib/Adafruit_MCP9808_Tasmota/assets/board.jpg new file mode 100644 index 0000000000000000000000000000000000000000..69644e1c59e1ff997f97f2d9a639cf5dd6ad52b5 GIT binary patch literal 134987 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

QU8y~Z}(3ND7)e$MB`E}e{z(iDF2hd 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�t?P(0(nom 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

+T?-|in?1wF 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

@mgB8CCc36&plE% zUlwdz=ol}2%$kPEgR%(7X;MNvJziw9;vOwUL>}r5EEVdr1HEYjE+d7j$%8&;-M0tD zkB?~vldQ5?2p!Ul4KpH5;w12h6buIB3aracPsB*gRb62X4?kSV;DxGv7lG1yNx}K( zWik=xw?uSN`u+0k(B(N}w)}o1g80Co1+L=aNB0VU&C6W7X*FFDeQ3+=BZ(bC3VS73 z-2qA}WHZJ*9{Z;yxsBxlUDPl%m@CZrN^Nh1UzDkc@%XpOWtv`z^29%V+TB0y)Es=S zAo`RD++)IM!fp^F6jzm6Me?=yzo1S9!z|kP4I3i@IR*R zPiLEyf)BsCe)?@$@?cO7y}lSQV9ou%9J#Zllb>QG4ANO!#EG}I`6kaf6gRzb6%7w~ z>~UOwe-?%8%g!)$r^Qb)WuP=8rE&XvI`u*+@c%K> zejf6oT=bS=y(x_y5g+K7MQQS4+F*slc-G~%6;O{zN@J_6Vph}iEIdTvNz5nRdY|uc zFb6EGzjG^1=vP2k4nZSoozD8bO?E!im+&Sq?{KzB&13@WF@oV9gQWswXO36p`qfvm#ilh7MYdC1}G~NnfpnC zSXoR07Yl%)Q{4slVHQsXg3b-mPX|U90y7!D^-MRO`YHa*uLdL%nX6@X%v`mQfD zmZixo>D7fnzuqXGwf|(zusOWSZ}vsv+5xFiE*Er=RlAYUYYq%lafp$*<6rX5sG^Yc z@DVuvetgdEOK4BJx&BnxW@!?tKb}j{JMFqxrXw>|0V zvF7tDCim_MAyW5<9|6080IOxXiIAPsB9~JNpZg2lNQV3`Q&4u16zo`GR*NY5m6$j3 zjGOUFmji7sfBW|hsXujt<`$10L0XvLOD;j%$c4*^`(Sf*(w5I-H4-x?1xee?&te)u zRHxttO`t|SRMCF&hmV3e0pGX6en!13>966*A{?C)gS-Gy;qMhMR0fy~y(OZaQhRqX zMjTmLo)DczC_6%0>m?Y8B@l% z=!q1_?lb}`X~P6>*-L(om4Kv(IQ`MT_x*I$q49fUnm@pcm*j-~u!{jpizW(RYqFww z02<_m|7ejmD`17J2mb*C?cbXMkPWWfx$u^rp6BHCF%+Ok)CEb#iB?SUFr&8A{{u)= zW~L+z10NrrsvYUyxGTV-Kff>ZUU0%CJExGMcKnIRI(ZRvk|xWTScX11+I(I#DLtJO z5p>q<@DsWnedPcm;FzxHFYJ6yHHm=#6<%1B*h|SbHOVx_A=MY_vH;=6oQC&2V`PBV zMcVTxCwMzkhvzcceg4%70}wN_ip*1;6I+Z+hU39V%yD^uA%e$3yED8+x8}ehjyO)o zW_F#-{u~kbT5d8aoZ+?pOc2=pfwJ4(1N`kAjnYWH=A&nWSKJJdMh?{1@tNy)W)6?b z>1`nZehW=}J!6X5{NWG4Rg0-I-_MJFep)PVDSu}@e;e>;>~HEPFuTf|YT=hExj9M5 z1BsV@C)w&p+Ed5bl|@UP2<-Ck*1T%bo@BuT5Aw?^6meBM(IGm>=wxj95fhV;FfNEd@ybQd#(&r*~yNcZu-p=sUWGTmPvfCmxzPAg{#qiuEY- z?A3KYtp3mWglQbt^5)Dwp64Sl+BF5pjSh3#Xk>Quzx=JXj}sLK!B=%)E(5qRZVZ;ymz(PqbyTO1y1^$J~1I)7Mmx~6awj{4 zl^8f|EoL6wPQq*13e5LL72#cP{IF&>%iRFk{9&%7PREK9>(=8sgy z0{shZhSAt=+_n|CO3#9+$AZpszUXIjK}rg%ykzwNl}0Bws*iAh^4K9m=Qx=nx&oQA zdTr~%5`%J=(TCyNs+>lK_wz2o`1Gd{V01FK=ba=Ck#_P3^xYkq*KAyVd54{Ihq{U$ z*iR&Of@)um1*`eo8+F<hd9ZKU>ZIXYe9>Vm44L|y!t!r zh|(|TWL7QnAE0zIRc4Cer_adf=DZ~w?;k>wKmA(!l@9x#`C^6&GS4F}E1D}k{F6t{ zrvT+k3H=pOS6f8{q5RO2hTLr+-I2uBCOoAuSc~}VlzVDM9;H>~0|?UG!ymc(=Fx{2FVfQ`1HWX)77qb? z7#W0UkC2^oIV6PX9l2vLUQs<6Oz_>6_0(Gbb*e3gMxis6>kF}Jo6B+_XUzk={}+yO zdfC^957TykkrKII0iWC$5X#b}G5Kg**I-d1FW*5%J%*e>@9-$+Pg!Qei!u-7X-^BZDQ#Sm5?oBgH(Emj~zmhtos9=J#|ZBix0(OvJIG`!8WPteLYARl*UW^*^#6^&QP7)Glo} zY0U$Y=eeh%BkJ_*KmR3|%oeg#>mfE0zvDdw4e*yu@Rtl(wK;OK>$&M0xpBNZ%Eg!{ z{v11N3gl*KJ1dCXZM89g={X9eD$7fixhwBIGe(A=KWYn0`qTV}s`@$IJfT`!h2Geg zEK^PoY9fh;cC30vV9NhD?n+G;X?mQTP%zA5x+zG)Hd?*dXn%E7Ja0z9p<5NiXiz|` z4Iz=D9k*FoEcdv-d3!rd{L@+e<|C|DCA>d()xA;Nm(gIwB*UhAb;h$zREdU&T=akR zxWZ_|$gJD8mp+h>6jzV_+m|U$)MR%1uuEz>cnIzxvh&xZWGd8kMeAa=u-r3&sj^GX zn2^n3Zl?43K5I#{?;uu~raWr6G%w$a0|&Gfa)mjAGDkv%Xyi#DEJ+)BR#Gz>^uP&s08#A{H9Oa6^{FzJU`;)q#hN$#f^6vj_CEiX275J= z4(SLE(|@>Mv;Ta_&PipUw}CN^+`{$n=KjFi3uoM4qqKIRx18zP@sjfau4tajDluJG zQ)Z|C0DSx3L{nzJt8Z5f$*C*3wo5~`T*xxUJ zgdWJAxOa*a{}7I|w78M{xyqsVKqMhIxwPT#*=3XG)e1#W_*(xWm)#RqraWoIKF^Uw zd3Jfm&Tl2a`;H#+$*s4?!(28nsq=ShsTLn|2Ga2m3XO2jATk}jNvO$wxOBZI$e_Ld z<3nhPw+_`V4nhv!)p~;E^=rwCXASy^g>nA@ zcDYt^EYtL8Ukx!awakb{9{K)nbCh%je!gemH=~oU%C7)t@J}HB^4@*Gs)ZS@mtjy` zUvWvv5aG8IujNh5^|&iscY;!C^^V1D=fF&ueytOtEMt{)V=a`3^xM%tfjQmXO;hWT zf|*UO3D1Ew%!(zT!lOz89AQ~9%lomv?+15fM)SNZA#%G*`%vKXOBoU84vMg3mOzHR zCQ2V~Xl+~Io0B2A3J=(`Orxa#056OiQR{D0#FMddFy1(L7`MRr!2;oxWVp~-*ascn zwoDDy(rrpOuA>#Z9fp9G#pf|4xr+C!iVuYKakD~-o+US~?As5LiybN9X_K2(5L()3 z_k*}+&%ZAPsqKBYcm2wH@Y}~CMvifrH#`zE82;j`s;Msk|I~q0FIV$F0rw#mqLX@6 z!M>Z;n|34flN*pZ$|8 zv_-Q6$ zhX04(N{uk{)IsI&2byL8t%e9ay~%7?zyKK~W;o>94#7fdbs*gXtMdoQ(qvilNhRex zqt8i`BNK{G*@I)8W;tCO7I!M&(^zby!M?j$5{kxW0aBMAYYcc-qnL$`9Aq&r0-@-P zkuj{J;&rQ$SNfXuc9*4+&Z!luCZiWNOW9jlE1ofp3U-AgRKZ*@;|%?^MmWYN<{w=( z1+|7o*DYdkwSQ$heaCM%E_0AZ-_p*4mSV%9+P=*Je}$qdvAqzjpa(L`g=m}Jv4Yu{ z{xVZH0*BFk9!?*>9mosK_A`4v50e$CSgW?>4pomo+;do82V22kiu($FIa+o+9xaK_ z7Yt<3`NV+(E}Nd!<09n{LC+WL9386-VW%?dJp?ah{}c7bs;nL#xaVoEzHwxL0(B3^`WM|xXQ9vnoP&IMo$lVo3Mo;k{ z^YANfpV7-J%;MGM$(tRZL{#Fi#Q+m*9~9JExlUbckmr{c{njL`c~bGwOvd2iE_vmx zKwB@$&&WY*DY8QrDnNQ^KdmB#P6gK~#5g)2c03zeU8aUX}7n?t-N zS^2;V_$T93%WQy3ltemxu)}Ads15xOP_te`8EvB!W|2d6w6|TjtsOX9i6TGz#U^%o zc7xUHayJ-ZqOD=VXN_W|L({L9BI>glq&XO7HpYf~Tnc-6aANN}_XVQO=u7fAwRpX# zv;LRq%Q7n3zy)j63bRF*y^ixu*xydTee{v}U@0fgAV8;BOJKD$VpnD7m0Vw%I?tK2 zQ+opdSyxrzq%1%wE%^+9?4prtRv@@R*^LE-BYPL#pZfo9#)jA^hAf1orrl|{*+Itx_TMf2&zUPX`2UQws2&>KPy@coL)*?@V zxbsQleKW)Gy!HP8((TBpqGO$p(uUXac6N5JRzgtANZ~U-A9x4QtuChKIb)G*F7B^x z0q4z63rVQGET|6RniMoJnRKGH&?l9RP7m0Qc|6Edl5>}{bi*EMKss#fcF>nT+{f%u){`lXJ!`I!rmEIWRT)*-6Hi~CXQ)mU_%DceR-Ln>vRoH+T zxdM68TqDacyOrAcd@1b6(nHT)*a=cX__9g78(2mg^#9)S8-xk;UfuRY|63lx;%3>& z$xOX?!RgLvAhHyEZn906$>DE=V}$vrSw0K7QKEjd5`TPpOG1YLt)@WbyFi~f*K zwe2=lISH^Ydn)Vud1#KLHXs#2Gq{ zDcZhbZEOr$nsn0$H*=5a-5kv^7x;RX!8iy=d54lqooU&L?P!#c7kB?g#9n+qR?OCm z>gLJ_uqk4=yPm-46^`UpdZV8k#l4=-#_o@~sTHG^mMsf5gfKyxipU))pPYhYyiWw}lDhC`Bi$Yy)xZ6KG&>fsN)O653vic{>{7I2)Djbr5T*TO<3Lb|Od zeH0&6YbqL?rEag5QfAJV^K(UaCEAIb!0@b9%F3qe%>EO7-0})4s{a*nGNzcU z8K=~#g1g-j<8CLh%z1HRw=7w$2-rljeI`l}c}!q_)-+`$RJUP8FCPMZe_ii+FRfid##X-Ih>*Y_k_xwB1Mhp7>$NX<+%i8 z7m{5sCB;h9{KXv2R#wV`LtEX@>+-I6>V&vDD?QgBC%E4yIH!*n$E&FRYrS)eY5RUs!fqtikvKxS6N+EOK&i;`h&|TRHYrmtJv+ z+3>UStM9zsW)BXX^TSZV)e={uN|O93j$GUxZ8YGYIpc@De1<9M9@EbxjkR#BsfXT_ zV}3_yW{+lgZAAG$e873lZsem)AdJI=kOSQ9*U1rrZ8r^vzf>**#Kn?|>F8b)B%t3V#TX&Lij)dEvQiW^ql04FHM1&QONqq%rdtS2lK7-)4c+m7yTn># zw{w_N@W?@=Y&u+BB62BX7AFP2ftZEx5RAT(M>;EsW9$B5x21d)r^{B(e+0Q^9t+|N z5lKmfVwhw_H6dMysiCs{5r#GN>Nf;yi4@hLP96%Y%O;oe zriZzI|LAN2)YOdqk^NhkEimd&l(m|qsQL=QFJE$Oh0}c-&ls&oS}v}N6DRYY?xba;+y;I@GV#FW3HT;JH+Oy z6gm4Al5@;GDxr{jLYR>w^xN-W_kg^LAU0F&8+fYjCPQZ75Y|0px?^<+YQ2Z@!%KL?ZQVZub>o4gGNoF5$$-B@cs3 zs@xWi!YEOtJU$X~>kET_N^0a6#yzzmp06dn5_PQA$M}AE-=6u-4{KIAUx_{nN^~Qj*`Y8CKB`Jk5L&rX)gK2!xHXW zaXsRQ=BIxFS96STNs#6D*8hGoFv2945XeprPs%oakCAX2Ic2|WsC7g->w(x17RzqR zu0@m7ywO!U5*b)RqM6a8}|RXtzf>y^ft zmA$%KkzevboWPsQr?|9NVufe${m8|#O95WFDnb?=SJ4A3YN(dyIYAtZy?7N@g-Oq1 zci2_;K`rxA$HLpvfTVR?FBMn-_xMRQ0@6ktFokW+h`@I{E)iQ61k8WN z>WVdj(ic5m=9$pnyuoi8P8-QKlBXFM{PJ5%^wi!in=F1mv<}v$FIZvZR2AvCox$bf z2Eq(xa4fx$${#mA%AU{i_5#@}EV2c(!uG|VCplOvuLnb1GAhPH(Ed5#ftz=X;Y7%5 z(^|!V?d%L5#%?*nM#~+q5Gle#-T|gd*0-mXYPcK#PiNMHyi;wnt9rDH5;CM|(fdAfMKf+ZsY2aQ1*b{oH&33^GYLPi zmUj|s>%I*Tco(}SGGgPOkzxAZ!H{9)!^?LB37M~dxirp8RfaH2pTntk1|(Mg}n4PXd{R@?nEX2n2S`G~1R#w~d6Gj?4r)1x;Bqj)$z zcCUORt;9`C&ufzq!l=g)hLqnX@iwVTn9gY7qk|_qkpjnbIms-ugkT(tU2(EuV>M7% z7W;t%Et3?$)8aa(K=a2vhwMU@ZGQn_C$+p;jvnoIzKqM`{St{mV zC1z_1g-Zo6=m4^p#A4Hac)N*JTdiq*S?J?nMj8SFl;*6Ng^hwAA$1y^fO_y6t##e8 zh+6mJ2n~wGTw#0@qcA_0{0{9qxjjC5WVIgm7Au{VH$^**){j7oosh zs9r@SjTXh{lfHH;9xM^D+py?{*cU@2d1T0m#FFus~Uk>>lK^VDK{;+iD9VQm$rJ$la#eN;;we9qp;%n_9xar`175#Lgiw~c7jN<6>6_WMPV zD(UrWQLM(@aIoS#8AxL0htqi(>2 zWOo0z>CACO48g1 zGP7;{$IyxU_HdT@`^zsxfKsYXjkBwILmC$4_o5vw4SQ#JjCsn7Pa~_1VYTqx(zlKo zvEdMlr&O=rl+mq%|A?4e8DuhexX(sMORW2>g=+G{{dwnue9PxyLH{kzBdwX^IJ%hh zc08BLfHJ0rNl)=(cg-#Dv6l`~NCvJ+T(WAeA~3;jr)&)K?pWc}$xDk&#-fd&oi>(l z?D1ntzenwrb#wql<^*yd5Eh>$?TJESIdUGe@ zq{%T|O5NfDlSZ(IcX#xS;maW+Yy3yt?=s=3L_#<@qa3?nr_dkJ*(V~%F)a4=oPN`O zSdjQrdh!?XPh(eTqpC~*h}iKnK1U;CfVdPse}7ZH!1vxGWZw_(dd}I0!gZQ2#7L3~ zVWeDC+ceJn3Zi|%m zFkaQkoqOmhDVX#qcYMgpX{OtwJEppLcobyyX@$Ut6Pp~e$hDc=`WX}LKo5;FD->Dn z-SR2Aca^5~&ggd+yj}udQ9JcM&+!aX~v~cKs{gK1nNHB^mU_N*TUUeMTxR6*c zthf1|dW#oxzh@UVe1YxL_f=EYun{dMd}$PmL&6r#wk-pD$Hc+M&?4g_A@A`G*%!5> zG(ud~ESJCv(1H5C*zvR0Ud@4SyT*EZInT8g-6?lmjCPd?j5~)gJ&H0o^+(S3h$Y5!2 zrww4Q7En#cm78^nmC+WgQW}M@t{cS+?!$PlG`tz2KjbgqwP&jl<5JAbNFy-DDMC9a zvbpP9iS;1@f7;1Yk{wslp8Qbca0#nY>aX_|8Fv1Y^+s+yV~;{wSJwrOtCxM zR+c-NI0ToMed0eoM?n+F>zJ~P>xwW#&w_$*Oqmv#QQ*+%Q+0epFsS$PIOl8KagF(p z*=}693oGivPB%D=6@qg)G?^xiM$Iccr#J+TUKi?eGaH{<9N2>roC1GzP&QWVH|=d+ zQ3xTz*oMxdN2D~^ofV^DM~dd}$1@oz9GvUMBwuph<)SNfL0XlYzv@+-WwO>hJ8?o= zJw9GOx0JfhRzcy17~%c3f(XGBQ5e)P<@D>mQ$ZmPmELELWs%uH6~nk|SIMoB2T2CL zGWtwcNUoDP%)L$FebjUFnUPl)ZiUg34JXxAAM-sZ&ZUpcU+>h8)%xNgqFosY0Q{{E z51D69%w};tzMYR6expx?-bc?!n|ZPriiaRhWSa(z%!Fl;9~<2hE4hqI7=>>vDc%LN z2od;fmuD^N=%B%3eehU!^VGTiWWQ6UsXuKy_mjvO4iU>|Uk~EAqvT)u6?Z zKtQe8qPE{+FEQ4s=L&^*$JA4ZG|Yjxs{#8)gYbH?>nq-=>UKYY?AQOoImqBuMZz=Cz1A`aHY>O z@}yM0)TZz^s+{T6%6MSL%B?Z+-ZJpDr3R+M!WtEE5B1zx>%V}X&tU;^)N8t0sVCT7 zVKJ)jmnIX&ABsDH5%(M}n*ms+ccgUJ0yivBel(9CE5PdvM54u!!|Id@Rokz9@n*S> zrrYm!VOy$N2=hvqIU3vHAQ}?wD;nA{TUUBQlNY{yw z#Wik-#Li^O695I0Py@^UrEp#&yfP~Ni)QI~iJ`}`PdGM2AhE&4WeWAsV(m>^lH$LcmHba;M|7S@uxEzCagU#Zn>{mK z#-S$n*x}fidE`4Qzr1OmGEysLvWs7WEsTXAYd-k}lT{I1bU-55S-lVq=wuxJ7I6Am z>xSs(FNU9c&44Qa_a&asXF<1sBDF6El=shOE^y?qeDN(kmK;h=M3^k=VbAX|F?z7t zaI($V%9|)|JB5x#V?M8!6ovfwPJ(@UnR;%_YoPbxk}A7B#id3()zC1y)9>)VgsYEV zbDR-x$a7ZWW)9e*j@lP4#jxx_y>96%)EF>fs*^m57Zqd9t6v1tS4SZnN-fA(JNLW& zIs)VJ9~o}Ld322>mdggW*Pnx*(;r>b$r4STph?UNr9b zXxY_-CGlN!M0N=DIx`U4JozYJMlIryfSpuhk;Z<@kc260wys()r)b%lgb3o=ryHw2 zZE6L`SIicEVHFt@DTR;1giIlCd6iegJyU80bv3jHDU=x5-qd0B+dtMa(o@b21Ihm; z`G10XHJo0g+DrZ`uN~U?;H%PjJc`f1?OueXaKhuVNfDjB2jsPrvTM=Duk+1V=7qVKMC2ew5L}W(18%4k36wn(!Yn!K492t+nonfhmXn$ zRuYa0smEqt<*juOQ6Jg^?4o5GwQ8z=x0)TQa@5zU{hkceg@|~%3SE_Ytc%W^MN}j) zKjx@+`P@ecZj-MCV&FjmH|9<|vVu$Sv&BDuT~L4#Ffj$KfD9wKYJyW(HK>chOM9w* z@)k>P%MLDv{wvX5DY4YFlB<0B?1|bWIH!`z^k|I$mktkpMk2h9eAIv=t>jGB6mo!Igi3_!eb^tyKQQg9 z*gV#(5ag9T^P>tl^R4WIA3-D5{#+bcgt9Zc!d!UP?_mONvhZh$Pfb{$dGn=!oy1`w z!DhJwZ+&-v3ReB_Mj?RrvF*<*hihAbOm0-g_0jWnN#+cGiO(r(ugVpd7(5G{XC);~ zx_>dDgE8chW2&QvBtL=U?)T;Nfqw?>M_34*If|57_9$qb6!R61$cFU*aYe6zkD1V- zF8UiKk{cqwkn|Z-TsoOA?i6)hguyN6WS%gZL-)=MWNEu7HPtC7Fd#R-4kP4m@;az^ zrOOyo!kbdcyC)Xtz|8CMtXkk>`FBo|7|Xz>2dEX>aI9^Cb2N=Q>X0~w-iXjT_-1@1fYrZdJ+x+!P2Q1Ock_wj!LukLwVPBBtn z4|idZ!X?r=yVf2dzh0=99@(!{TUapBn8-ojBJ30ojKU(mBas`AJ`W;fTd!lMgl;SC7B z>|Ys{8}WY0e*s`kZ-!*eL5Ej%8?7NgsiveXpOgYUCaknHvl6?;nBNtA<%TXaQKv}k zp5;PaS~RYOa{p)6O|e{3J=7q>Lo~6l{5O=_DcX`UU_op>Gy{b1%M{FDH8YC4AzG<3 zpBFr59fpo{UBe4jJ{t%jMk1&f>^$Q!YWUFEyj5&@0ZJ|YJl=g?9Uvkh;;P+#YSY1~ z+-7-45%}7RVSLp8%O8mg?o7qPCc1KQ|NYj`e>U>(rybv(643IWTOjKk*GYbJ4+iD| z^V_@vpDI_2jT-VV5*`t(i^cU!t=l=T;+nI#9$V z$agf5O;odJE#}&wA((VvBV{4I5=vd`aXR1rBfX_WV#HNYoBK^N%3cCCuXq67OD_-NjhD^A&Be42R8Z{b+CtWMe(c@!zR zVL&5!ZsIj+etKnpRTjQV8|1C@z57~_>6_0|rg%p5H*nn(QQbD+!9#d;3;OCetffsA*Q%O}5 z!f}SkWVGbIW8AnVs6TWcdhG+HJ2+`su@ky_zUh{&Q8H9BiYvsu=QnI(M10hBE( zp5JYYu!R(FGk`=a@Pf9 z_TI8%c$XQY$sKh)AVBtC02DzePI(Y4zZZc&sR@5<0v(A}K^jmNwp15w^`4u^ade$c zHIJtH&MhRmVX}iIKU!%YKUVIBSlhg-+hcYY@0RloUwao7$r9HuObWK% zE#%}s`XttcSt||B5bI*J_|PF)lD`%^mz&FWK})|NlsjfcH_Cy*R5P5BjW3NO)gwC) zf~P#LEYvxU+UYv|>TxH1OTZ;YTFN0QG3wL?^tBXDNQ(J(08mc(vbAtY&##nQrgui| z%<(3@6ch=l2sE6C5-*yHr3nWo7g&Lj8>2(Y0EoX7`Z=lfUmO-S)-P@Jkn!%vav8TwTuf81>~O6*r`3BeT*i&9F zhH}q6%FbMoV%(k?CWN3hDoST*ieXrCw`f9sk&d?$TH8BL(i@CZD(X2Ff57IR@N39E zbTH_1YX!{oxGFC&RE*3=1z(*d5 zWktyv**EE0yPXL?!QBXMUx7Of9qxK(`GlGl$S+4Ze4;9iC+)P-+$9=Kl$OFZC_B$M zJ3OT2*djxMFsY6XJ)U@1;ULV%JgE$^_XNXG43>+$ii}bF#thWo`jv|UIXvNDRrAnV zIXg5v)xBzN6iOei)asoq_n_8`M?OOslPAei6y$MOqZy`o{a5Z>wvVxKU1sb0+7nSl zj?yhd{Ed-@)#@&<;D*=X$oYRoM6XhFwU6g26}y)te(gm(Ogg^g9T~m*uS4SPoH~08 z;<;93cBzc|H@f}qikB!RBOAhe-kg@f*9|F?gz(?)EA~R$uq)+zZiZAdOS77HN-C*0 z@?|l89DDj>x1>RwE!c2Ma)T31#wm*}G@)a^M?_(~yPct+$&(^{F6Z@fiJ z)wpnep|zU;qG27kq*~lQIqQq#CmWs3+ns@T-H6#nivR)*(eQX zgsOiFN)o8KnBuiZkh3s(S(4n~DHOW#j&*Rc8zs9TiJm<(hM(EIprdGXwJt>@4Ao^* zW~UYTTfs&0kj{LW7>@K`IgC*iB{sfL|FNU7%lVgAArA7NyPX6Y$f4w5Kcuq=RF}-{ zD5YBtgqVb#&L$=*@$=52c;rD%J^U+cxB)h^fUz)mSwR<*-%3m`E)6z@S=gzH{O~sQ ze$M*7l+Xy6!rbhY(XcE#Z`6RFrb2fu`fT(Rl*1TTP9+8mUJkDqf?t^2WO5@7jEPm3 zgT0K#DwF;KlD>C8lTGwe(>$=BC?R{O&r5FPF{yHx#4^0#tc-C8{0rE;^NH;>CRhl{ zerT>&CVGyaX+`v zJQhZt<1KY&$vCV(KW^H8ffl;L*m43{f04SHTBOqrK7K2mGB#_W*rYAgx`ajQ!1U

GlLP^L_K+$T7eq-aYlJMt8V*_5(>Co{?-hXxcCHe+$5=M z1-h(52JQ6Sa>Co7hEA@sW?qvueRTy)Hn2;JQ@+^Woj?e&Nxh+eoSb_4r&`!jAk zB{k8!ZY@Q%Ya3IyygPbRYj*IxD6E4(qZziBp{9~ z_^&+YMUf%mJsH+VYMCN4G4};BiokiF9&K#SXSk~gKBHNF;$^3uG4!SI^B?;g8B>?y z=2QE<<=rNCkPFw}=E`2)ssZ+2NEo_-Ta-W1t^+t^J@Ri4+{lq<*sX&|E(JG*I;a*Z zw188eZf~J|`9t=>1v$zFVT(_-Pb%Cd1o(;L;R&H1c)%6lu3w-2om&QSsj0c5w(4Q0 zN&Z?7hv%4q6&r^{mfaxRY%``?-4Vxc-m+kfr`AS}K+uQpauUarZ=`-U3JnonHoy!< zY3a?GEwF!rB@``ROJUXpYDbr}ZoIn*!Pr#o5ri-4h=$=ND61pm{80I)lrnwjW}L2tiP4WPBLF z2%W2j?`mB+RU7sWTbHD4D^7AV=_KJkJvV@iSY9b&Dz~^6%Mr)CLJ{t$eVfb%_3eG% zmX#%5fzt>Ou6`rN-RKm_vAJAYY+!QJueB|if;mk|B(vI4GUh|phWx&n^*^Yyc zj<6I0Cx^YF!+>>uQBJ4pa`&;a0-iCR9=%ThnigFA0Y}lZtfZWmSkh{U44UK0kiR}x z9uaG<42#XRW3gxqTdInjug%S8@@Mo^m39yO#EKHerm62*)5CiqW+{$Q(^YRrV!wS^z)3h)59j8Zqr zbOiiWxU(4Kn)vfL0QZu)`WwC3e=4()^~4}69clSw2MC-(@he;IxklVK#D^4NpEx9t z1SIK;zv&N%4boInWcA60$vq@?dQKFTe!AN3II~hy|Bw}i^UWMvH$ulB zk;YLgX{nRCwd@j{KsixdY_LNYgP%i-UfW8zU;t1< zxcJb#Y$Jl#rFoBec`27=FsFW=V7Q&!T9nJnorv*0^uoT|WXsL7=eKTc^6*wvQ5QFN zI1gnUc^vc;u)h_IDx+LVzVDg&2x|c*Rgf0Ha!?#9L z5^dH|=MPxB#vjQ_5@<#LG9Fq6FAFP+C#i({r56|4h%vo5unRTL7{Riwo7)Sfd+L=W zYi9m20pqJ+`f9X5|~BpOX3`}j*gqz9!7E$g-$h`TH;-p z7+~BqVyO2Qc@tsn?^=DzkKslHY#138iY;}9HO2mb*|VSrM3F=rX1)9q}IOes#JDdOuV zxUyzhmR78%r!x8zf%7wY#OjvUAj?wFH)#&tl|NGcQ5|<$JP`g{cyQf4zze~YeUDgN zn<#O@G`VDuP^?Gk=0;jro_wp#!!pK;9BAxJhDpM}i?hPTUZy~pQeCTx`k~YQP+B9A zK+=ajmmi>khbbM>Xt@8)^;o;Ylp9hycn|MW!%NXc+$7vz03*Evf+0mjt(06|-O7`u zgA{h={x4wsS}z&(s@5@s%Pblmzyk^38uQw?bui}O>14v+<)pfuRHbXL(~sMWcDVwZ zpc`|-ImsU+ArhZ|X=(j3GXNXoB?|un`iMP|=tIivO$D_ImhAOejIXDah>IjXijM71 zANp|d;|oT-M>Gw+!coRZdZ@Jj@Ool*)lJSeMC5YRCnAS}-68kjO-+u39CbSE(S0uG zx{oeZVEu58<7J@(H*IEf(giNVac)LHDf8&YO~{QHg|>gWP@&#DQ%MfW`~Ei7x7FClZX;%I^ zEZ|hC&$2&!-*C0M$xDXt&aWRsd0Xukc`m1TnuSYF)|BSk0*U1<)@TyBcah_xbCX}% z)8^2=(!pSTKLZ?$*P7qlvaKFw7i?u5FW~~amvpINWb4CqSeW*G{jQf#wETfG`X&N% zoLNCLO?gTGkJMo#E^3Y@JgbVj7M9MH_aZ!bYWqLs78}+QUj;ujP!vxSqbDg zmJ-(x;!N%9s$drRwc{fE8vA5JSkXnbZKUU1_km&dfi;U_Vsy8{hMM2yd`W1mO#iSK z09OGV6nvP_7g(Obn9;6I*t!E(^iM4fSDH8er$1bT5g!J@M}HlW5pN5RrW`pK2{Lp& z%o}r|Yz%Z&f_jcDK68>oq%b(I!JG!)`dhV)@>LO>UyqhQ0J=o_g`FE`eiT=7z?X!j z770a5Y0OwlCn5ELyrWvo1^JJq23*sOSDU0l+>nMkOZU6vli%*AL{QQe&^#rz+G;F2 zxIW+(Mi!^IOf)oX%Z6`G`Xj@?-oGWXSXH6TcG%u$DewO}^|dzgOHGEf{2dY$HyV0@ z3A@C+csO?p9>~qS<`hH@26p!;u&liL3uvF=DNh8+Zk~?3668xyeqvyFWJzRYV{6#! z-HttW5=`!mK%NSzHxIF9rz-E%YSFap`7KMYtZXhc8ZjGQ&(!$>B}`fyv4YUv#uR+$ zMq?M-*yh;RSvUjokUL6otId{|MGXAmX`6!4;O{2o6l?1Ib3x|*3z_(bNbm6 z04>Hn8TAq@NsGukKX8Kf{4r=1MgE3W9xld->}GYhyncU9qfKA^Fr`WIlZc)~6Y8NW!lk#m%J zxVS-x5ot6}eu4|VOnt&)WYIXR;{H=AO(gtiyTIs!g{ZtRm`@C#?^L#`Nkc13mn$Gg zOk(aG3m4)OD#D=p|5gb+GDV5rKkN;o;*^tbJ$QK z!y7)#DTwj2x;VP$;wy^(iS%x{-^7fGm%RA5L7wPrk zp#Tp_ZIz*U@x$pbC8RT919)+Efvo%IxwI1Y!jfv{;h_Z)XmU+mt|T2QrNlXWrv0c^ zAw?7uB|)N)Ygi^^-tKv}W`@6Zbl+NX&X%E9So3pPT3bJgZp^m@Xk2obH%5x;pQ;pq$tUlIS@RECfI9yeMP zXB@X1K2K+)9+?GlS4BDYfpjutc1w1HI)3_Ok~sZ+sWwt^WrdHTz=ROh3uzA`&-&t? zptC%C<<3u?*Kb}Kw(L?oonqEuln7xFe$aX8QsF-PCuq#kYwKuT->`GFswqj11b|^0 z?cygX+L8>8J?m$O(K=ms#q1%{5RFt~5(8tS(!<1M&naauK(cC+c648atfHeJ3*|{Y z(_U2+%gi?ok5&m>jPelZp02;J$RhsLWlWRz6eE25j)+v5p^vF>`UmD5>zCZ;%LFT9 zV5PL(WnfbWv<(Zmd-1XNEtQDr)dpcDA10Wg#t!H8g8#VL2r)6Smu{w_x!l*oe+l#O z!9l`^0>xr4tb2ITbP6g&UeF_;1MjF#?Mq?dzbck`e|y=IaUHP8$~6@UZNPJ$elqDA)2GWdcLCzRq zL25IpzbIGlb!F*Yl7AXYxnjHo5*;~8Oi4%}ylQG>HU5IK4*F=#b-8CZs-?%nBK=UJ z{5)^ppWQ|RaOc_2A1yTZ3PyEA>TzXCWE1?FeD6ZF%8CnVCrkif`?6 z4m$v#y*HZl_=Q}`K#yu2xOYOuZV-Ou8mk=c+(Fy`WIEse=f$Q%?y(_M?p0HqNRqgg z4^FEFjaheI_zQSxF?oTb+S1m`{3j*(phY(Q3mB}Df9#-c9&xNz zwGmY6zU+_dxUE1|mu=UCl4;fz%nTgcFu~(?)h-nmY>Q=_2pk4GcR9OxE6<{U{Ww+P zAVBK+eTC1P%Ms0Qxk1d+nZ7~4XEoynboV2dU8D=UxySdrRMbQO;*}G{fBdd8G&7?{ zm$YWeL=b(r_u$vvMaB??L^PGsSLD}gsl`%nP41A*)gTb-t6B@D1fpn_Y{ z!&PlAwo?ikuq-&3p)2`9i31y1TA?J;QE9?bQn>AvbisId?hn%H6 zD;PIW30=M7Q&aFjxN!8S_`xo3P-TIDMr zn3kxwMZ?9`{b4&H7Axg2d~fpPou@K+yHu9>qlbb+mt{4v2ZPGIUt*?y#cq^3#O|gK z-4&9tygrWd-ZYi7iX}30AHUp1UA7^{oLMOq>M<^$n*RAOw%WDgJ%%}MW$RDS7e_05 zNA<1Fz}S#~y2|lip>3X>j;0%2_y^1xqcjrVHjWOsgLHysdZy zKB{iM`jPN3HU!bgmDBiIEullXs<14+P*s(TLcYBVF6VQC;{B(;DQ8{fgog^>-CLb0 z;y23=hs8h-(Rxi-g<$i)0Da~~DrTDO;xyH)p4iOv<2~1T)@8NdqZ?A9$YwquFbi+pkFII0e zPF;^=aKpw>PKO54^RTW%8r7q~pPabfWde^ClK=x#aBip2lWL2sWFRsub!NDG#4UI& z3e_R=s<*F-o46EB8MT!$GQZltWbj28Gq5^c`tXt=SPBwdM7Aw<&cm)JBVw=4@EUe8 z1bqKFHT3QdHk={S`{%*LCDwcv$M{D^n;uy#%6cz}0SimZO6+TbcQa_Gt(JE2SE0iz zhrt?ScNRs8$V=~-+!#!P4>z9b*W%=WS`m~(%x(h!sLnXd)8|-?j?yeCT8a;vLaS3E zP5g2)tAg<^nuN4Nd+DwXPkQ7*1?!f*i{hT$wXs~5Fg59%=E#J@uS)RT_?N|8SSKw@fm2ZPT@S_K&{~d+&xOkc@!84SPKI344U&L+U(+j!u zilu_bS52}dxyR2Rcy`^ytM~xVqQ;{e#IycDj$>-ksp1T@x|^!=zfo)#4vqD(dbwkT z*gwx?-ORGBezD2w`-KD=!NTUNn|QD}P$$Ff-#p_y$Nn9@9ZT^X_4gCWYV{3-NnOdi z;<*2oR7rDpuEXOzYd4}!u3>Gjt_g?Bc68ci*^b{*UJv<$Q+3)9wQeV_nMJgJVq!{f z`5maLfG0L@<%sIk$^KluL}#@uwgq6I2yksHYlmA@iEjmN-I&K;V)rEp zJv58wUfiW#KD6>Qf=7iNhwK#hOYF_I<>1|D=e5h|r$8F@HZ!tGQiJCFpMnpoZ9}?dQ*7zL7y%lGeAhseQRS zkk+us|Am(RliVitQ?F=VeF+kEHifA^(pd=rM;dcW74T7N%REFaSe``T!`A#Nuu}Q- zUE(|nW6QnR{j&Uzwf;bUBrTz?hU4Q}C8e&Cj$hSNxHhC6(YJc&*`ElzHZO2|a7jS= zP{vR?{m;@{2^fo9j;4V*&dzDBI{7X#?N?M)*Z#$qgUcbK3=9a)U#gF#86y-vQkGm@ z(Spu^oC4iW7-gsThFht16V($p zA#2F(IrU`emHdM;k-vbke>if7#D#vy8CuWaL*Tp${`;e6%GNp95%pPAeU#;9JWGsg zH0R((*Ug@cgfA6p^G&<;897Tf@4ufsXOjmq4sYUe8eZHjrz&xm65eH5jlkAF&nQVj=v|LO^5{F!cDWm+a9L3ebPM_Dl=;vV@%tRF{ig5UrF3Q2Y z6=kofRfJNfinOehd#9hmt{|`USsO@SzLP@DeFF$n`nFFtY$+gmJBif}%atC<8XFDj zxWATjdq{GdYSz2Gr*6}a5Yi|^FRlor(jT+K zeRkn%LpaB?>nk>TCT=T2s>ij_{;5zr!Tx#~DDZ<(@>$(?&AXhIH%V|Vw#mG){`5GZ` zD^>mX`O9E@Q>diJM9pkX{3&xoc5Q(~l>!q0zcIiTnEXR-G6xx*K!ZiQfZK|+U79-V zy}1!_0_U$=D^n8>cXxTDkZ&sAkcFgjRxSn>qvw8P-d6T@CuQO6qHcn(6*j_3YhR(|F$8JCoFel`9Jz@4?3c_|cA}9h4UbqV zIpTT`TFG$nJbKQ?c%%NM!lq(UUXoj`hR{p8F^=Ei=Tpzq?so>Zmt|fUghhp##xZ+4 z0+v}pZY-c%rIWkOlf^vYT%4=Ol1EZjPT7uz+%YUOL1;nm$jujITbM~(gmN{WX>;hxWJ zTs(o)(oo=3aOw1`S-mHj?WKGY-3XRr#jc2r$0)vx%*hpGw^!9PzZ*aOcw*d=^#$tL zSs0%v#?~^so~?9zV5NKNh+b>Q1dXB**>FHVzrNC&H+j15GV1))^}!E|k3YV+))gWB zLQw=9lz`to2#bG=xJ5#prX@<1Cu<9xzZ=y?Ye*gZ-t5!y?647r-aqIwOyp2PtqVqf zFmS#E!sT=YkzZ>&Wz#RNhrfT#yG1Omtrrm zun;)w3Bob8weui$&32q>9^=;NRHEct zso6i;au$4;lM@d}g1-a=_+|BM6LGiad>U8TlpyElcQtMn%9Ad#9W8gN@LI)PJ&NHT zOcHtRZ<{ylG6ol300sF_9cIZciUx@R2zb9RC=55ykj%x;d`I2RgK&z= zn|`DF2o}8tibRQ#n{-(hH#RNg`Sc!#aw1yE=!kZGB%CBysOH?8w%to)_F&gGogqbZrrcindDJci(mL-j?w&5?6R*uX?)iCjB12 zv)6sH&`_R{jV>%WU?Zeuya_ZI7JbO}ve;YlF5gPM(&nTapOl20b#!3qaYs0o0k%cs zu6%~!zBy#+_ZNVRf2*UH2+oDyNd3k(1C?_!)b0!cajfV;nfA(&)4^Oi&ncJx-zzEo z)ay@jVHKNKV(#LPHN}1wC$4l-Cn@-z=p{qTQt*@fwPEJ~$OXz;_+Nk>vxb#4ps!R* zaAfYr+n(Sn3$)@d9$p~l{hgKht$`H(MWw~e!w+@Wk}&ju>lWNHWhyPGMEj5QlZzlv zn_L{OO?_5Z<|EH#H17TCI#Tb2hGbrY!RyOd|u&oslAh0y7#1vBx z0LHNx<8YIXJ=IMH!9rfkt4(NbkY%JWYO;GMB5Pzld>avTH#^?kbR+cX*|Zx@q?9L9 z>!h~-s*d~vW4!w2Qf4*qaq^8b@SN&4muQ&U;AUmCT}uwI2dGd&_gN)YDkY>^DXSN~ z*3*DPGLq{_QPT`o}A6!=xl~A;Z{DC}|9s?RbUE)X40WxmhxGN;b$)BIOvO@Sb z>s=oWDhMKmki0r_qGGa{p<{-@{7;ZgFygtynSHLQQt#lh*lJWnEB_l6_5488$JY@U zuXd6W(eQl2lmTo@ZSTa{^(XWB-WB3Pb>0xPfV=-hDG_fvF>;E7-_Flh zD^|WTuwbJs5q+$(Z5DCM>9cFOalejd(sG#s7;k(EIBxS`;O1X8A0^u|RoLd9=Mf% ziY_{{A=FVUS7LjYZt;2M)^zfn0Zs%?1UUm|&NH3hB%&!*D^hiOoSH|zeL_Y}ao-Vm&D5ceJBUN z-3qx>2T+`+Q}m%Jk=Fk|iq6HK>Hq!1+YFn;jEZ6##wgz$D~Fk38Itp{S}l>V~3*U*b`n~eE9Cu!zbc`2Tl z`@R*aktExO?ji&>27G~@kB3YiW>~BEni@;+$Axb>_0SD$wL~U$4=!I()jGWocXZje zOq#|Y8wxeWv& z!DSV?qg@1%hvT*EIo7}rCm{UBky9MDM;_s3TI&ZU?zHYk+KCPzc3d2v*bU`V3B_(& z0{Y%?4y-l)QkhSt2&4PuTB6_Aw$Am4p>uW5@i*NJU#TImmHh)xom0s#0;@2Pk~hs0 z)=L_uxTDzftE0yH!WH}U%8~6-%l3FShOS+scHUbYVUabXbo-oBD}8sX3~~B-_cP=# zoMB-{l0rusXg_o3c^5qAT8hgL&XfmTukP?L`1N+&e8{44 zobOBbwXF$!D~JX1aG;NS5c!YR#-}7jkc?MBs_z!tR+>l98FhigzJC!g7_`e&{x3JT zt+^e?i)JYdq&@ow*jOHDgFh2Idv2agw)@sb)T0LKa&jt<6M6On&$Z!AP<3zqFlxoT zMGax<{U`ILb}JkIHpYj|V4ex&hEm<ce)7{+;~uH}`+6TLP32I(arEy$K^s4lSGZuN zk}*U}H7BjswA8e!1f{uXJ}r~go{6XH{iVA3E(++Sx>j}G`v+6j3(7{0F!$XRs+$8lic>HndD^ z$6Dz8{GY->{i*TI2{lG`y9!G_^w1yR*u&Sm5x`Zl{m))XS}QNIVZN@q1B+GBtr&E| zV3PL{vNP}8LhB%ixNRm##<^ms~nl)7Be!T>@kh(;miKQxFi-1QzU~g1LIddn3+es zzwhjvI?<+%eK`oKNy!*s?!4$N$aFafe

s)C%R`)K=0ZE9jnj?4>0k>wf5LYLwKA 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. + +On the Adafruit Discord, you may send an open message from any channel +to all Community Helpers by tagging @community helpers. You may also send an +open message from any channel, or a direct message to @kattni#1507, +@tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or +@Andon#8175. + +Email and direct message reports will be kept confidential. + +In situations on Discord where the issue is particularly egregious, possibly +illegal, requires immediate action, or violates the Discord terms of service, +you should also report the message directly to Discord. + +These are the steps for upholding our community’s standards of conduct. + +1. Any member of the community may report any situation that violates the +Adafruit Community Code of Conduct. All reports will be reviewed and +investigated. +2. If the behavior is an egregious violation, the community member who +committed the violation may be banned immediately, without warning. +3. Otherwise, moderators will first respond to such behavior with a warning. +4. Moderators follow a soft "three strikes" policy - the community member may +be given another chance, if they are receptive to the warning and change their +behavior. +5. If the community member is unreceptive or unreasonable when warned by a +moderator, or the warning goes unheeded, they may be banned for a first or +second offense. Repeated offenses will result in the community member being +banned. + +## Scope + +This Code of Conduct and the enforcement policies listed above apply to all +Adafruit Community venues. This includes but is not limited to any community +spaces (both public and private), the entire Adafruit Discord server, and +Adafruit GitHub repositories. Examples of Adafruit Community spaces include +but are not limited to meet-ups, audio chats on the Adafruit Discord, or +interaction at a conference. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. As a community +member, you are representing our community, and are expected to behave +accordingly. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.4, available at +, +and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). + +For other projects adopting the Adafruit Community Code of +Conduct, please contact the maintainers of those projects for enforcement. +If you wish to use this code of conduct for your own project, consider +explicitly mentioning your moderation policy or making a copy with your +own moderation policy so as to avoid confusion. diff --git a/lib/Adafruit_MCP9808_Tasmota/examples/mcp9808test/mcp9808test.ino b/lib/Adafruit_MCP9808_Tasmota/examples/mcp9808test/mcp9808test.ino new file mode 100644 index 000000000..6002487e9 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/examples/mcp9808test/mcp9808test.ino @@ -0,0 +1,69 @@ + +/**************************************************************************/ +/*! +This is a demo for the Adafruit MCP9808 breakout +----> http://www.adafruit.com/products/1782 +Adafruit invests time and resources providing this open source code, +please support Adafruit and open-source hardware by purchasing +products from Adafruit! +*/ +/**************************************************************************/ + +#include +#include "Adafruit_MCP9808.h" + +// Create the MCP9808 temperature sensor object +Adafruit_MCP9808 tempsensor = Adafruit_MCP9808(); + +void setup() { + Serial.begin(9600); + while (!Serial); //waits for serial terminal to be open, necessary in newer arduino boards. + Serial.println("MCP9808 demo"); + + // Make sure the sensor is found, you can also pass in a different i2c + // address with tempsensor.begin(0x19) for example, also can be left in blank for default address use + // Also there is a table with all addres possible for this sensor, you can connect multiple sensors + // to the same i2c bus, just configure each sensor with a different address and define multiple objects for that + // A2 A1 A0 address + // 0 0 0 0x18 this is the default address + // 0 0 1 0x19 + // 0 1 0 0x1A + // 0 1 1 0x1B + // 1 0 0 0x1C + // 1 0 1 0x1D + // 1 1 0 0x1E + // 1 1 1 0x1F + if (!tempsensor.begin(0x18)) { + Serial.println("Couldn't find MCP9808! Check your connections and verify the address is correct."); + while (1); + } + + Serial.println("Found MCP9808!"); + + tempsensor.setResolution(3); // sets the resolution mode of reading, the modes are defined in the table bellow: + // Mode Resolution SampleTime + // 0 0.5°C 30 ms + // 1 0.25°C 65 ms + // 2 0.125°C 130 ms + // 3 0.0625°C 250 ms +} + +void loop() { + Serial.println("wake up MCP9808.... "); // wake up MCP9808 - power consumption ~200 mikro Ampere + tempsensor.wake(); // wake up, ready to read! + + // Read and print out the temperature, also shows the resolution mode used for reading. + Serial.print("Resolution in mode: "); + Serial.println (tempsensor.getResolution()); + float c = tempsensor.readTempC(); + float f = tempsensor.readTempF(); + Serial.print("Temp: "); + Serial.print(c, 4); Serial.print("*C\t and "); + Serial.print(f, 4); Serial.println("*F."); + + delay(2000); + Serial.println("Shutdown MCP9808.... "); + tempsensor.shutdown_wake(1); // shutdown MSP9808 - power consumption ~0.1 mikro Ampere, stops temperature sampling + Serial.println(""); + delay(200); +} diff --git a/lib/Adafruit_MCP9808_Tasmota/library.properties b/lib/Adafruit_MCP9808_Tasmota/library.properties new file mode 100644 index 000000000..3c4ee86ce --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/library.properties @@ -0,0 +1,10 @@ +name=Adafruit MCP9808 Library +version=1.1.2 +author=Adafruit +maintainer=Adafruit +sentence=Arduino library for the MCP9808 sensors in the Adafruit shop +paragraph=Arduino library for the MCP9808 sensors in the Adafruit shop +category=Sensors +url=https://github.com/adafruit/Adafruit_MCP9808_Library +architectures=* +depends=Adafruit Unified Sensor diff --git a/lib/Adafruit_MCP9808_Tasmota/license.txt b/lib/Adafruit_MCP9808_Tasmota/license.txt new file mode 100644 index 000000000..f6a0f22b8 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/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/tasmota/my_user_config.h b/tasmota/my_user_config.h index 46d88e0d7..0d968b1f8 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -518,6 +518,7 @@ // #define USE_AS3935 // [I2cDriver48] Enable AS3935 Franklin Lightning Sensor (I2C address 0x03) (+5k4 code) // #define USE_VEML6075 // [I2cDriver49] Enable VEML6075 UVA/UVB/UVINDEX Sensor (I2C address 0x10) (+2k1 code) // #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code) +// #define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code) // #define USE_DISPLAY // Add I2C Display Support (+2k code) #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0 diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index ef757e5b6..5622bcde9 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -569,8 +569,10 @@ void GetFeatures(void) #ifdef USE_VEML7700 feature6 |= 0x00001000; // xsns_71_veml7700.ino #endif +#ifdef USE_MCP9808 + feature6 |= 0x00002000; // xsns_72_mcp9808.ino +#endif -// feature6 |= 0x00002000; // feature6 |= 0x00004000; // feature6 |= 0x00008000; diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 8ba54e60b..811076d8f 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -154,6 +154,7 @@ #define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) //#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) +//#define USE_MCP9808 // Add support for MCP9808 temperature sensor (+0k9 code) #define USE_ENERGY_SENSOR // Add energy sensors (-14k code) #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) diff --git a/tasmota/xsns_72_mcp9808.ino b/tasmota/xsns_72_mcp9808.ino new file mode 100644 index 000000000..42fdd7ab9 --- /dev/null +++ b/tasmota/xsns_72_mcp9808.ino @@ -0,0 +1,136 @@ +/* + xsns_72_mcp9808 - MCP9808 I2C temperature sensor support for Tasmota + + Copyright (C) 2020 Martin Wagner and 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_MCP9808 +/*********************************************************************************************\ + * MCP9808 - Temperature Sensor + * + * I2C Address: 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F + * +\*********************************************************************************************/ + +#define XSNS_72 72 +#define XI2C_51 51 // See I2CDEVICES.md + +#include "Adafruit_MCP9808.h" +Adafruit_MCP9808 mcp9808 = Adafruit_MCP9808(); // create object copy + +#define MCP9808_MAX_SENSORS 8 +#define MCP9808_START_ADDRESS 0x18 + +struct { +char types[9] = "MCP9808"; +uint8_t count = 0; +} mcp9808_cfg; + +struct { + float temperature = NAN; + uint8_t address; +} mcp9808_sensors[MCP9808_MAX_SENSORS]; + +/********************************************************************************************/ + +float MCP9808Read(uint8_t addr) { + float t = mcp9808.readTempC(addr); + return t; +} + +void MCP9808Detect(void) { + for (uint8_t i = 0; i < MCP9808_MAX_SENSORS; i++) { + if (!I2cSetDevice(MCP9808_START_ADDRESS + i)) { continue; } + + if (mcp9808.begin(MCP9808_START_ADDRESS + i)) { + mcp9808_sensors[mcp9808_cfg.count].address = MCP9808_START_ADDRESS + i; + I2cSetActiveFound(mcp9808_sensors[mcp9808_cfg.count].address, mcp9808_cfg.types); + mcp9808.setResolution (mcp9808_sensors[mcp9808_cfg.count].address, 2); // Set Resolution to 0.125°C + mcp9808_cfg.count++; + } + } +} + +void MCP9808EverySecond(void) { + for (uint32_t i = 0; i < mcp9808_cfg.count; i++) { + float t = MCP9808Read(mcp9808_sensors[i].address); + mcp9808_sensors[i].temperature = ConvertTemp(t); + } +} + +void MCP9808Show(bool json) { + for (uint32_t i = 0; i < mcp9808_cfg.count; i++) { + char temperature[33]; + dtostrfd(mcp9808_sensors[i].temperature, Settings.flag2.temperature_resolution, temperature); + + char sensor_name[10]; + strlcpy(sensor_name, mcp9808_cfg.types, sizeof(sensor_name)); + if (mcp9808_cfg.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%d"), sensor_name, IndexSeparator(), i +1); // MCP9808-1 + } + + if (json) { + ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), sensor_name, temperature); + if (0 == tele_period) { +#ifdef USE_DOMOTICZ + DomoticzSensor(DZ_TEMP, temperature); +#endif // USE_DOMOTICZ +#ifdef USE_KNX + KnxSensor(KNX_TEMPERATURE, mcp9808_sensors[i].temperature); +#endif // USE_KNX + } +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, temperature, TempUnit()); +#endif // USE_WEBSERVER + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns72(uint8_t function) +{ + if (!I2cEnabled(XI2C_51)) { return false; } + bool result = false; + + if (FUNC_INIT == function) { + MCP9808Detect(); + } + else if (mcp9808_cfg.count){ + switch (function) { + case FUNC_EVERY_SECOND: + MCP9808EverySecond(); + break; + case FUNC_JSON_APPEND: + MCP9808Show(1); + break; + #ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + MCP9808Show(0); + break; + #endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_MCP9808 +#endif // USE_I2C \ No newline at end of file diff --git a/tools/decode-status.py b/tools/decode-status.py index a992a621c..67898d784 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -204,7 +204,7 @@ a_features = [[ "USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080", "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", - "USE_VEML7700","","","", + "USE_VEML7700","USE_MCP9808","","", "","","","", "","","","", "","","","", From 05a2c3c164ce324f4f263286c0cd63636cb6f358 Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Tue, 2 Jun 2020 11:34:25 +0200 Subject: [PATCH 139/581] correction of BUILS.md and mcp9808 Domoticz index --- BUILDS.md | 6 +++--- tasmota/xsns_72_mcp9808.ino | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BUILDS.md b/BUILDS.md index 92d081c1e..7e642de4e 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -120,6 +120,9 @@ | USE_WEMOS_MOTOR_V1 | - | - | - | - | x | - | - | | USE_IAQ | - | - | - | - | x | - | - | | USE_AS3935 | - | - | - | - | x | - | - | +| USE_VEML6075 | - | - | - | - | - | - | - | +| USE_VEML7700 | - | - | - | - | - | - | - | +| USE_MCP9808 | - | - | - | - | - | - | - | | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks | USE_SPI | - | - | - | - | - | - | x | @@ -139,9 +142,6 @@ | USE_HRXL | - | - | - | - | x | - | - | | USE_TASMOTA_SLAVE | - | - | - | - | - | - | - | | USE_OPENTHERM | - | - | - | - | - | - | - | -| USE_VEML6075 | - | - | - | - | - | - | - | -| USE_VEML7700 | - | - | - | - | - | - | - | -| USE_MCP9808 | - | - | - | - | - | - | - | | | | | | | | | | | USE_NRF24 | - | - | - | - | - | - | - | | USE_MIBLE | - | - | - | - | - | - | - | diff --git a/tasmota/xsns_72_mcp9808.ino b/tasmota/xsns_72_mcp9808.ino index 42fdd7ab9..fdd200099 100644 --- a/tasmota/xsns_72_mcp9808.ino +++ b/tasmota/xsns_72_mcp9808.ino @@ -86,7 +86,7 @@ void MCP9808Show(bool json) { if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), sensor_name, temperature); - if (0 == tele_period) { + if ((0 == tele_period) && (0 == i)) { #ifdef USE_DOMOTICZ DomoticzSensor(DZ_TEMP, temperature); #endif // USE_DOMOTICZ From e57bbb2b7d10ce4a525b6c5121bd462787d77111 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 2 Jun 2020 12:09:31 +0200 Subject: [PATCH 140/581] Some code refactoring --- tasmota/xsns_26_lm75ad.ino | 2 +- tasmota/xsns_59_ds1624.ino | 2 +- tasmota/xsns_72_mcp9808.ino | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tasmota/xsns_26_lm75ad.ino b/tasmota/xsns_26_lm75ad.ino index 5b735dcb7..d5073f759 100644 --- a/tasmota/xsns_26_lm75ad.ino +++ b/tasmota/xsns_26_lm75ad.ino @@ -89,7 +89,7 @@ void LM75ADShow(bool json) dtostrfd(t, Settings.flag2.temperature_resolution, temperature); if (json) { - ResponseAppend_P(PSTR(",\"LM75AD\":{\"" D_JSON_TEMPERATURE "\":%s}"), temperature); + ResponseAppend_P(JSON_SNS_TEMP, "LM75AD", temperature); #ifdef USE_DOMOTICZ if (0 == tele_period) DomoticzSensor(DZ_TEMP, temperature); #endif // USE_DOMOTICZ diff --git a/tasmota/xsns_59_ds1624.ino b/tasmota/xsns_59_ds1624.ino index f3ffcd1f1..60b176c6e 100644 --- a/tasmota/xsns_59_ds1624.ino +++ b/tasmota/xsns_59_ds1624.ino @@ -184,7 +184,7 @@ void DS1624Show(bool json) dtostrfd(ds1624_sns[i].value, Settings.flag2.temperature_resolution, temperature); if (json) { - ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), ds1624_sns[i].name, temperature); + ResponseAppend_P(JSON_SNS_TEMP, ds1624_sns[i].name, temperature); if ((0 == tele_period) && once) { #ifdef USE_DOMOTICZ DomoticzSensor(DZ_TEMP, temperature); diff --git a/tasmota/xsns_72_mcp9808.ino b/tasmota/xsns_72_mcp9808.ino index fdd200099..0d757c684 100644 --- a/tasmota/xsns_72_mcp9808.ino +++ b/tasmota/xsns_72_mcp9808.ino @@ -55,9 +55,9 @@ float MCP9808Read(uint8_t addr) { void MCP9808Detect(void) { for (uint8_t i = 0; i < MCP9808_MAX_SENSORS; i++) { - if (!I2cSetDevice(MCP9808_START_ADDRESS + i)) { continue; } + if (!I2cSetDevice(MCP9808_START_ADDRESS + i)) { continue; } - if (mcp9808.begin(MCP9808_START_ADDRESS + i)) { + if (mcp9808.begin(MCP9808_START_ADDRESS + i)) { mcp9808_sensors[mcp9808_cfg.count].address = MCP9808_START_ADDRESS + i; I2cSetActiveFound(mcp9808_sensors[mcp9808_cfg.count].address, mcp9808_cfg.types); mcp9808.setResolution (mcp9808_sensors[mcp9808_cfg.count].address, 2); // Set Resolution to 0.125°C @@ -77,7 +77,7 @@ void MCP9808Show(bool json) { for (uint32_t i = 0; i < mcp9808_cfg.count; i++) { char temperature[33]; dtostrfd(mcp9808_sensors[i].temperature, Settings.flag2.temperature_resolution, temperature); - + char sensor_name[10]; strlcpy(sensor_name, mcp9808_cfg.types, sizeof(sensor_name)); if (mcp9808_cfg.count > 1) { @@ -85,7 +85,7 @@ void MCP9808Show(bool json) { } if (json) { - ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), sensor_name, temperature); + ResponseAppend_P(JSON_SNS_TEMP, sensor_name, temperature); if ((0 == tele_period) && (0 == i)) { #ifdef USE_DOMOTICZ DomoticzSensor(DZ_TEMP, temperature); From 57639d95241a0c85e7665ffe878d2f26b6bbdb0d Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Tue, 2 Jun 2020 12:24:29 +0200 Subject: [PATCH 141/581] fix VEML7700 MQTT white value message and I2C detect --- tasmota/xsns_71_veml7700.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasmota/xsns_71_veml7700.ino b/tasmota/xsns_71_veml7700.ino index 18a57bcf7..3869e72d6 100644 --- a/tasmota/xsns_71_veml7700.ino +++ b/tasmota/xsns_71_veml7700.ino @@ -54,8 +54,8 @@ struct VEML7700STRUCT { char types[9] = D_NAME_VEML7700; uint8_t address = VEML7700_I2CADDR_DEFAULT; - uint16_t lux = 0; - uint16_t white = 0; + //uint16_t lux = 0; + //uint16_t white = 0; uint16_t lux_normalized = 0; uint16_t white_normalized = 0; } veml7700_sensor; @@ -65,7 +65,7 @@ uint8_t veml7700_active = 0; /********************************************************************************************/ void VEML7700Detect(void) { - if (I2cActive(veml7700_sensor.address)) return; + if (!I2cSetDevice(veml7700_sensor.address)) return; if (veml7700.begin()) { I2cSetActiveFound(veml7700_sensor.address, veml7700_sensor.types); veml7700_active = 1; @@ -106,7 +106,7 @@ void VEML7700EverySecond(void) { void VEML7700Show(bool json) { if (json) { - ResponseAppend_P(JSON_SNS_VEML7700, D_NAME_VEML7700, veml7700_sensor.lux_normalized, veml7700_sensor.white); + ResponseAppend_P(JSON_SNS_VEML7700, D_NAME_VEML7700, veml7700_sensor.lux_normalized, veml7700_sensor.white_normalized); #ifdef USE_DOMOTICZ if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, veml7700_sensor.lux_normalized); From 006af71803757ec52f85665b730b5174115463bc Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 2 Jun 2020 17:35:25 +0200 Subject: [PATCH 142/581] no need for HueEmulation for core 2.4.2 anymore. Out of support. --- tasmota/Parsing.cpp | 627 -------------------------------------------- 1 file changed, 627 deletions(-) delete mode 100644 tasmota/Parsing.cpp diff --git a/tasmota/Parsing.cpp b/tasmota/Parsing.cpp deleted file mode 100644 index a7665d7b1..000000000 --- a/tasmota/Parsing.cpp +++ /dev/null @@ -1,627 +0,0 @@ -/* - Parsing.cpp - HTTP request parsing. - - Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling) -*/ - -#ifdef ESP8266 - -// Use patched Parsing.cpp to fix ALEXA parsing issue in v2.4.2 -#include -#if defined(ARDUINO_ESP8266_RELEASE_2_4_2) -#warning **** Tasmota is using v2.4.2 patched Parsing.cpp as planned **** - -#include -#include "WiFiServer.h" -#include "WiFiClient.h" -#include "ESP8266WebServer.h" -#include "detail/mimetable.h" - -//#define DEBUG_ESP_HTTP_SERVER -#ifdef DEBUG_ESP_PORT -#define DEBUG_OUTPUT DEBUG_ESP_PORT -#else -#define DEBUG_OUTPUT Serial -#endif - -static const char Content_Type[] PROGMEM = "Content-Type"; -static const char filename[] PROGMEM = "filename"; - -static char* readBytesWithTimeout(WiFiClient& client, size_t maxLength, size_t& dataLength, int timeout_ms) -{ - char *buf = nullptr; - dataLength = 0; - while (dataLength < maxLength) { - int tries = timeout_ms; - size_t newLength; - while (!(newLength = client.available()) && tries--) delay(1); - if (!newLength) { - break; - } - if (!buf) { - buf = (char *) malloc(newLength + 1); - if (!buf) { - return nullptr; - } - } - else { - char* newBuf = (char *) realloc(buf, dataLength + newLength + 1); - if (!newBuf) { - free(buf); - return nullptr; - } - buf = newBuf; - } - client.readBytes(buf + dataLength, newLength); - dataLength += newLength; - buf[dataLength] = '\0'; - } - return buf; -} - -bool ESP8266WebServer::_parseRequest(WiFiClient& client) { - // Read the first line of HTTP request - String req = client.readStringUntil('\r'); - client.readStringUntil('\n'); - //reset header value - for (int i = 0; i < _headerKeysCount; ++i) { - _currentHeaders[i].value =String(); - } - - // First line of HTTP request looks like "GET /path HTTP/1.1" - // Retrieve the "/path" part by finding the spaces - int addr_start = req.indexOf(' '); - int addr_end = req.indexOf(' ', addr_start + 1); - if (addr_start == -1 || addr_end == -1) { -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Invalid request: "); - DEBUG_OUTPUT.println(req); -#endif - return false; - } - - String methodStr = req.substring(0, addr_start); - String url = req.substring(addr_start + 1, addr_end); - String versionEnd = req.substring(addr_end + 8); - _currentVersion = atoi(versionEnd.c_str()); - String searchStr = ""; - int hasSearch = url.indexOf('?'); - if (hasSearch != -1){ - searchStr = url.substring(hasSearch + 1); - url = url.substring(0, hasSearch); - } - _currentUri = url; - _chunked = false; - - HTTPMethod method = HTTP_GET; - if (methodStr == F("POST")) { - method = HTTP_POST; - } else if (methodStr == F("DELETE")) { - method = HTTP_DELETE; - } else if (methodStr == F("OPTIONS")) { - method = HTTP_OPTIONS; - } else if (methodStr == F("PUT")) { - method = HTTP_PUT; - } else if (methodStr == F("PATCH")) { - method = HTTP_PATCH; - } - _currentMethod = method; - -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("method: "); - DEBUG_OUTPUT.print(methodStr); - DEBUG_OUTPUT.print(" url: "); - DEBUG_OUTPUT.print(url); - DEBUG_OUTPUT.print(" search: "); - DEBUG_OUTPUT.println(searchStr); -#endif - - //attach handler - RequestHandler* handler; - for (handler = _firstHandler; handler; handler = handler->next()) { - if (handler->canHandle(_currentMethod, _currentUri)) - break; - } - _currentHandler = handler; - - String formData; - // below is needed only when POST type request - if (method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH || method == HTTP_DELETE){ - String boundaryStr; - String headerName; - String headerValue; - bool isForm = false; - bool isEncoded = false; - uint32_t contentLength = 0; - //parse headers - while(1){ - req = client.readStringUntil('\r'); - client.readStringUntil('\n'); - if (req == "") break;//no moar headers - int headerDiv = req.indexOf(':'); - if (headerDiv == -1){ - break; - } - headerName = req.substring(0, headerDiv); - headerValue = req.substring(headerDiv + 1); - headerValue.trim(); - _collectHeader(headerName.c_str(),headerValue.c_str()); - - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("headerName: "); - DEBUG_OUTPUT.println(headerName); - DEBUG_OUTPUT.print("headerValue: "); - DEBUG_OUTPUT.println(headerValue); - #endif - - if (headerName.equalsIgnoreCase(FPSTR(Content_Type))){ - using namespace mime; - if (headerValue.startsWith(FPSTR(mimeTable[txt].mimeType))){ - isForm = false; - } else if (headerValue.startsWith(F("application/x-www-form-urlencoded"))){ - isForm = false; - isEncoded = true; - } else if (headerValue.startsWith(F("multipart/"))){ - boundaryStr = headerValue.substring(headerValue.indexOf('=') + 1); - boundaryStr.replace("\"",""); - isForm = true; - } - } else if (headerName.equalsIgnoreCase(F("Content-Length"))){ - contentLength = headerValue.toInt(); - } else if (headerName.equalsIgnoreCase(F("Host"))){ - _hostHeader = headerValue; - } - } - - if (!isForm){ - size_t plainLength; - char* plainBuf = readBytesWithTimeout(client, contentLength, plainLength, HTTP_MAX_POST_WAIT); - if (plainLength < contentLength) { - free(plainBuf); - return false; - } - if (contentLength > 0) { - if(isEncoded){ - //url encoded form - if (searchStr != "") searchStr += '&'; - searchStr += plainBuf; - } - _parseArguments(searchStr); - if(!isEncoded||(0==_currentArgCount)){ // @20180124OF01: Workarround for Alexa Bug - //plain post json or other data - RequestArgument& arg = _currentArgs[_currentArgCount++]; - arg.key = F("plain"); - arg.value = String(plainBuf); - } - - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Plain: "); - DEBUG_OUTPUT.println(plainBuf); - #endif - free(plainBuf); - } else { - // No content - but we can still have arguments in the URL. - _parseArguments(searchStr); - } - } - - if (isForm){ - _parseArguments(searchStr); - if (!_parseForm(client, boundaryStr, contentLength)) { - return false; - } - } - } else { - String headerName; - String headerValue; - //parse headers - while(1){ - req = client.readStringUntil('\r'); - client.readStringUntil('\n'); - if (req == "") break;//no moar headers - int headerDiv = req.indexOf(':'); - if (headerDiv == -1){ - break; - } - headerName = req.substring(0, headerDiv); - headerValue = req.substring(headerDiv + 2); - _collectHeader(headerName.c_str(),headerValue.c_str()); - - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("headerName: "); - DEBUG_OUTPUT.println(headerName); - DEBUG_OUTPUT.print("headerValue: "); - DEBUG_OUTPUT.println(headerValue); - #endif - - if (headerName.equalsIgnoreCase("Host")){ - _hostHeader = headerValue; - } - } - _parseArguments(searchStr); - } - client.flush(); - -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Request: "); - DEBUG_OUTPUT.println(url); - DEBUG_OUTPUT.print(" Arguments: "); - DEBUG_OUTPUT.println(searchStr); -#endif - - return true; -} - -bool ESP8266WebServer::_collectHeader(const char* headerName, const char* headerValue) { - for (int i = 0; i < _headerKeysCount; i++) { - if (_currentHeaders[i].key.equalsIgnoreCase(headerName)) { - _currentHeaders[i].value=headerValue; - return true; - } - } - return false; -} - -void ESP8266WebServer::_parseArguments(String data) { -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("args: "); - DEBUG_OUTPUT.println(data); -#endif - if (_currentArgs) - delete[] _currentArgs; - _currentArgs = 0; - if (data.length() == 0) { - _currentArgCount = 0; - _currentArgs = new RequestArgument[1]; - return; - } - _currentArgCount = 1; - - for (int i = 0; i < (int)data.length(); ) { - i = data.indexOf('&', i); - if (i == -1) - break; - ++i; - ++_currentArgCount; - } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("args count: "); - DEBUG_OUTPUT.println(_currentArgCount); -#endif - - _currentArgs = new RequestArgument[_currentArgCount+1]; - int pos = 0; - int iarg; - for (iarg = 0; iarg < _currentArgCount;) { - int equal_sign_index = data.indexOf('=', pos); - int next_arg_index = data.indexOf('&', pos); -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("pos "); - DEBUG_OUTPUT.print(pos); - DEBUG_OUTPUT.print("=@ "); - DEBUG_OUTPUT.print(equal_sign_index); - DEBUG_OUTPUT.print(" &@ "); - DEBUG_OUTPUT.println(next_arg_index); -#endif - if ((equal_sign_index == -1) || ((equal_sign_index > next_arg_index) && (next_arg_index != -1))) { -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("arg missing value: "); - DEBUG_OUTPUT.println(iarg); -#endif - if (next_arg_index == -1) - break; - pos = next_arg_index + 1; - continue; - } - RequestArgument& arg = _currentArgs[iarg]; - arg.key = urlDecode(data.substring(pos, equal_sign_index)); - arg.value = urlDecode(data.substring(equal_sign_index + 1, next_arg_index)); -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("arg "); - DEBUG_OUTPUT.print(iarg); - DEBUG_OUTPUT.print(" key: "); - DEBUG_OUTPUT.print(arg.key); - DEBUG_OUTPUT.print(" value: "); - DEBUG_OUTPUT.println(arg.value); -#endif - ++iarg; - if (next_arg_index == -1) - break; - pos = next_arg_index + 1; - } - _currentArgCount = iarg; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("args count: "); - DEBUG_OUTPUT.println(_currentArgCount); -#endif - -} - -void ESP8266WebServer::_uploadWriteByte(uint8_t b){ - if (_currentUpload->currentSize == HTTP_UPLOAD_BUFLEN){ - if(_currentHandler && _currentHandler->canUpload(_currentUri)) - _currentHandler->upload(*this, _currentUri, *_currentUpload); - _currentUpload->totalSize += _currentUpload->currentSize; - _currentUpload->currentSize = 0; - } - _currentUpload->buf[_currentUpload->currentSize++] = b; -} - -uint8_t ESP8266WebServer::_uploadReadByte(WiFiClient& client){ - int res = client.read(); - if(res == -1){ - while(!client.available() && client.connected()) - yield(); - res = client.read(); - } - return (uint8_t)res; -} - -bool ESP8266WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){ - (void) len; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Parse Form: Boundary: "); - DEBUG_OUTPUT.print(boundary); - DEBUG_OUTPUT.print(" Length: "); - DEBUG_OUTPUT.println(len); -#endif - String line; - int retry = 0; - do { - line = client.readStringUntil('\r'); - ++retry; - } while (line.length() == 0 && retry < 3); - - client.readStringUntil('\n'); - //start reading the form - if (line == ("--"+boundary)){ - RequestArgument* postArgs = new RequestArgument[32]; - int postArgsLen = 0; - while(1){ - String argName; - String argValue; - String argType; - String argFilename; - bool argIsFile = false; - - line = client.readStringUntil('\r'); - client.readStringUntil('\n'); - if (line.length() > 19 && line.substring(0, 19).equalsIgnoreCase(F("Content-Disposition"))){ - int nameStart = line.indexOf('='); - if (nameStart != -1){ - argName = line.substring(nameStart+2); - nameStart = argName.indexOf('='); - if (nameStart == -1){ - argName = argName.substring(0, argName.length() - 1); - } else { - argFilename = argName.substring(nameStart+2, argName.length() - 1); - argName = argName.substring(0, argName.indexOf('"')); - argIsFile = true; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg FileName: "); - DEBUG_OUTPUT.println(argFilename); -#endif - //use GET to set the filename if uploading using blob - if (argFilename == F("blob") && hasArg(FPSTR(filename))) - argFilename = arg(FPSTR(filename)); - } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg Name: "); - DEBUG_OUTPUT.println(argName); -#endif - using namespace mime; - argType = FPSTR(mimeTable[txt].mimeType); - line = client.readStringUntil('\r'); - client.readStringUntil('\n'); - if (line.length() > 12 && line.substring(0, 12).equalsIgnoreCase(FPSTR(Content_Type))){ - argType = line.substring(line.indexOf(':')+2); - //skip next line - client.readStringUntil('\r'); - client.readStringUntil('\n'); - } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg Type: "); - DEBUG_OUTPUT.println(argType); -#endif - if (!argIsFile){ - while(1){ - line = client.readStringUntil('\r'); - client.readStringUntil('\n'); - if (line.startsWith("--"+boundary)) break; - if (argValue.length() > 0) argValue += "\n"; - argValue += line; - } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg Value: "); - DEBUG_OUTPUT.println(argValue); - DEBUG_OUTPUT.println(); -#endif - - RequestArgument& arg = postArgs[postArgsLen++]; - arg.key = argName; - arg.value = argValue; - - if (line == ("--"+boundary+"--")){ -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Done Parsing POST"); -#endif - break; - } - } else { - _currentUpload.reset(new HTTPUpload()); - _currentUpload->status = UPLOAD_FILE_START; - _currentUpload->name = argName; - _currentUpload->filename = argFilename; - _currentUpload->type = argType; - _currentUpload->totalSize = 0; - _currentUpload->currentSize = 0; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Start File: "); - DEBUG_OUTPUT.print(_currentUpload->filename); - DEBUG_OUTPUT.print(" Type: "); - DEBUG_OUTPUT.println(_currentUpload->type); -#endif - if(_currentHandler && _currentHandler->canUpload(_currentUri)) - _currentHandler->upload(*this, _currentUri, *_currentUpload); - _currentUpload->status = UPLOAD_FILE_WRITE; - uint8_t argByte = _uploadReadByte(client); -readfile: - while(argByte != 0x0D){ - if (!client.connected()) return _parseFormUploadAborted(); - _uploadWriteByte(argByte); - argByte = _uploadReadByte(client); - } - - argByte = _uploadReadByte(client); - if (!client.connected()) return _parseFormUploadAborted(); - if (argByte == 0x0A){ - argByte = _uploadReadByte(client); - if (!client.connected()) return _parseFormUploadAborted(); - if ((char)argByte != '-'){ - //continue reading the file - _uploadWriteByte(0x0D); - _uploadWriteByte(0x0A); - goto readfile; - } else { - argByte = _uploadReadByte(client); - if (!client.connected()) return _parseFormUploadAborted(); - if ((char)argByte != '-'){ - //continue reading the file - _uploadWriteByte(0x0D); - _uploadWriteByte(0x0A); - _uploadWriteByte((uint8_t)('-')); - goto readfile; - } - } - - uint8_t endBuf[boundary.length()]; - client.readBytes(endBuf, boundary.length()); - - if (strstr((const char*)endBuf, boundary.c_str()) != nullptr){ - if(_currentHandler && _currentHandler->canUpload(_currentUri)) - _currentHandler->upload(*this, _currentUri, *_currentUpload); - _currentUpload->totalSize += _currentUpload->currentSize; - _currentUpload->status = UPLOAD_FILE_END; - if(_currentHandler && _currentHandler->canUpload(_currentUri)) - _currentHandler->upload(*this, _currentUri, *_currentUpload); -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("End File: "); - DEBUG_OUTPUT.print(_currentUpload->filename); - DEBUG_OUTPUT.print(" Type: "); - DEBUG_OUTPUT.print(_currentUpload->type); - DEBUG_OUTPUT.print(" Size: "); - DEBUG_OUTPUT.println(_currentUpload->totalSize); -#endif - line = client.readStringUntil(0x0D); - client.readStringUntil(0x0A); - if (line == "--"){ -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Done Parsing POST"); -#endif - break; - } - continue; - } else { - _uploadWriteByte(0x0D); - _uploadWriteByte(0x0A); - _uploadWriteByte((uint8_t)('-')); - _uploadWriteByte((uint8_t)('-')); - uint32_t i = 0; - while(i < boundary.length()){ - _uploadWriteByte(endBuf[i++]); - } - argByte = _uploadReadByte(client); - goto readfile; - } - } else { - _uploadWriteByte(0x0D); - goto readfile; - } - break; - } - } - } - } - - int iarg; - int totalArgs = ((32 - postArgsLen) < _currentArgCount)?(32 - postArgsLen):_currentArgCount; - for (iarg = 0; iarg < totalArgs; iarg++){ - RequestArgument& arg = postArgs[postArgsLen++]; - arg.key = _currentArgs[iarg].key; - arg.value = _currentArgs[iarg].value; - } - if (_currentArgs) delete[] _currentArgs; - _currentArgs = new RequestArgument[postArgsLen]; - for (iarg = 0; iarg < postArgsLen; iarg++){ - RequestArgument& arg = _currentArgs[iarg]; - arg.key = postArgs[iarg].key; - arg.value = postArgs[iarg].value; - } - _currentArgCount = iarg; - if (postArgs) - delete[] postArgs; - return true; - } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Error: line: "); - DEBUG_OUTPUT.println(line); -#endif - return false; -} - -String ESP8266WebServer::urlDecode(const String& text) -{ - String decoded = ""; - char temp[] = "0x00"; - unsigned int len = text.length(); - unsigned int i = 0; - while (i < len) - { - char decodedChar; - char encodedChar = text.charAt(i++); - if ((encodedChar == '%') && (i + 1 < len)) - { - temp[2] = text.charAt(i++); - temp[3] = text.charAt(i++); - - decodedChar = strtol(temp, NULL, 16); - } - else { - if (encodedChar == '+') - { - decodedChar = ' '; - } - else { - decodedChar = encodedChar; // normal ascii char - } - } - decoded += decodedChar; - } - return decoded; -} - -bool ESP8266WebServer::_parseFormUploadAborted(){ - _currentUpload->status = UPLOAD_FILE_ABORTED; - if(_currentHandler && _currentHandler->canUpload(_currentUri)) - _currentHandler->upload(*this, _currentUri, *_currentUpload); - return false; -} - -#endif // ARDUINO_ESP8266_RELEASE - -#endif // ESP8266 From 98fc7db8fa9fdf789e84591b4c85c95793307d10 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 2 Jun 2020 18:02:36 +0200 Subject: [PATCH 143/581] Flash_freq in override --- platformio_override_sample.ini | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 22256f679..f85ce989f 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -52,6 +52,11 @@ build_flags = ${core_active.build_flags} ; set CPU frequency to 80MHz (default) or 160MHz ;board_build.f_cpu = 160000000L +; set Flash chip frequency to 40MHz (default), 20MHz, 26Mhz, 80Mhz +;board_build.f_flash = 20000000L +;board_build.f_flash = 26000000L +;board_build.f_flash = 80000000L + ; *** Upload Serial reset method for Wemos and NodeMCU upload_port = COM5 From bf19634e1cd27497123f479860f40bdb0ab11850 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 2 Jun 2020 18:04:31 +0200 Subject: [PATCH 144/581] Update platformio_tasmota_env.ini --- platformio_tasmota_env.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio_tasmota_env.ini b/platformio_tasmota_env.ini index dbf79d288..3d08d5cd6 100644 --- a/platformio_tasmota_env.ini +++ b/platformio_tasmota_env.ini @@ -5,6 +5,7 @@ framework = ${common.framework} board = ${common.board} board_build.ldscript = ${common.board_build.ldscript} board_build.flash_mode = ${common.board_build.flash_mode} +board_build.f_flash = ${common.board_build.f_flash} board_build.f_cpu = ${common.board_build.f_cpu} build_unflags = ${common.build_unflags} build_flags = ${common.build_flags} From e997ce4a8abf8af1a99ced6c369b909e9fbe5bce Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 2 Jun 2020 18:05:15 +0200 Subject: [PATCH 145/581] Update platformio_tasmota_env32.ini --- platformio_tasmota_env32.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index f4f99282c..4398dcb04 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -6,6 +6,7 @@ board = ${common32.board} board_build.ldscript = ${common32.board_build.ldscript} board_build.partitions = ${common32.board_build.partitions} board_build.flash_mode = ${common32.board_build.flash_mode} +board_build.f_flash = ${common32.board_build.f_flash} board_build.f_cpu = ${common32.board_build.f_cpu} monitor_speed = ${common32.monitor_speed} upload_port = ${common32.upload_port} From a5868452a054a4b892758154d0872765390e9b0e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 2 Jun 2020 18:06:04 +0200 Subject: [PATCH 146/581] Update platformio_override_sample.ini --- platformio_override_sample.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index f85ce989f..2becf05f7 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -170,6 +170,7 @@ board = esp32dev board_build.ldscript = esp32_out.ld board_build.partitions = esp32_partition_app1984k_spiffs64k.csv board_build.flash_mode = ${common.board_build.flash_mode} +board_build.f_flash = ${common.board_build.f_flash} board_build.f_cpu = ${common.board_build.f_cpu} build_unflags = ${common.build_unflags} -Wpointer-arith From f10ed3261c51eb3630d1e9302b86c4238242682a Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Tue, 2 Jun 2020 19:13:06 +0200 Subject: [PATCH 147/581] AS3935, add stage to json, fix overwrite nf-floor --- tasmota/i18n.h | 1 + tasmota/xsns_67_as3935.ino | 13 +++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index b538e705e..073f537b2 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -147,6 +147,7 @@ #define D_JSON_SPEED "Speed" #define D_JSON_SPEED_UNIT "SpeedUnit" #define D_JSON_SSID "SSId" +#define D_JSON_STAGE "Stage" #define D_JSON_STARTDST "StartDST" // Start Daylight Savings Time #define D_JSON_STARTED "Started" #define D_JSON_STARTUPUTC "StartupUTC" diff --git a/tasmota/xsns_67_as3935.ino b/tasmota/xsns_67_as3935.ino index 2b73a2749..3e795b91a 100644 --- a/tasmota/xsns_67_as3935.ino +++ b/tasmota/xsns_67_as3935.ino @@ -51,8 +51,6 @@ #define INDOORS 0x24 #define OUTDOORS 0x1C - - // Global const char HTTP_SNS_UNIT_KILOMETER[] PROGMEM = D_UNIT_KILOMETER; // Http @@ -78,7 +76,7 @@ const char HTTP_SNS_AS3935_INTNOEV[] PROGMEM = "{s}%s: " D_AS3935_INTNOEV "{e}"; const char HTTP_SNS_AS3935_MSG[] PROGMEM = "{s}%s: " D_AS3935_LIGHT " " D_AS3935_APRX " %d " D_UNIT_KILOMETER " " D_AS3935_AWAY "{e}"; const char* const HTTP_SNS_AS3935_TABLE_1[] PROGMEM = { HTTP_SNS_AS3935_EMPTY, HTTP_SNS_AS3935_MSG, HTTP_SNS_AS3935_OUT, HTTP_SNS_AS3935_NOT, HTTP_SNS_AS3935_ABOVE, HTTP_SNS_AS3935_NOISE, HTTP_SNS_AS3935_DISTURB, HTTP_SNS_AS3935_INTNOEV }; // Json -const char JSON_SNS_AS3935_EVENTS[] PROGMEM = ",\"%s\":{\"" D_JSON_EVENT "\":%d,\"" D_JSON_DISTANCE "\":%d,\"" D_JSON_ENERGY "\":%u}"; +const char JSON_SNS_AS3935_EVENTS[] PROGMEM = ",\"%s\":{\"" D_JSON_EVENT "\":%d,\"" D_JSON_DISTANCE "\":%d,\"" D_JSON_ENERGY "\":%u,\"" D_JSON_STAGE "\":%d}"; // Json Command const char* const S_JSON_AS3935_COMMAND_ONOFF[] PROGMEM = {"\"" D_AS3935_OFF "\"","\"" D_AS3935_ON"\""}; const char* const S_JSON_AS3935_COMMAND_GAIN[] PROGMEM = {"\"" D_AS3935_INDOORS "\"", "\"" D_AS3935_OUTDOORS "\""}; @@ -473,9 +471,6 @@ void AS3935InitSettings() { AS3935SetGain(INDOORS); AS3935SetNoiseFloor(Settings.as3935_parameter.nf_autotune_min); } - } else { - AS3935SetGain(INDOORS); - AS3935SetNoiseFloor(0); } } I2cWrite8(AS3935_ADDR, 0x00, Settings.as3935_sensor_cfg[0]); @@ -756,8 +751,10 @@ bool AS3935Cmd(void) { void AH3935Show(bool json) { if (json) { - ResponseAppend_P(JSON_SNS_AS3935_EVENTS, D_SENSOR_AS3935, as3935_sensor.mqtt_irq, as3935_sensor.distance, as3935_sensor.intensity ); - + uint16_t vrms; + uint8_t stage; + AS3935CalcVrmsLevel(vrms, stage); + ResponseAppend_P(JSON_SNS_AS3935_EVENTS, D_SENSOR_AS3935, as3935_sensor.mqtt_irq, as3935_sensor.distance, as3935_sensor.intensity, stage); #ifdef USE_WEBSERVER } else { uint8_t gain = AS3935GetGainInt(); From 0a88c56376a305546204ff1b48d5993e87fe5929 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 2 Jun 2020 21:46:56 +0200 Subject: [PATCH 148/581] Update platformio.ini --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index c9eb6d5f4..04835d6c0 100755 --- a/platformio.ini +++ b/platformio.ini @@ -74,6 +74,7 @@ build_flags = ${core_active.build_flags} build_unflags = -Wall board_build.f_cpu = 80000000L +board_build.f_flash = 40000000L monitor_speed = 115200 upload_speed = 115200 ; *** Upload Serial reset method for Wemos and NodeMCU From 6dd50a394c1f4a5ac8cee0bf086d59ba92d5511f Mon Sep 17 00:00:00 2001 From: halfbakery Date: Tue, 2 Jun 2020 22:17:20 +0200 Subject: [PATCH 149/581] Add support for switches using an AC detection circuitry --- tasmota/support_switch.ino | 123 ++++++++++++++++++++++++++++++------- 1 file changed, 101 insertions(+), 22 deletions(-) diff --git a/tasmota/support_switch.ino b/tasmota/support_switch.ino index c13243c0e..9fc3b57c3 100644 --- a/tasmota/support_switch.ino +++ b/tasmota/support_switch.ino @@ -26,6 +26,8 @@ \*********************************************************************************************/ const uint8_t SWITCH_PROBE_INTERVAL = 10; // Time in milliseconds between switch input probe +const uint8_t SWITCH_FAST_PROBE_INTERVAL =2;// Time in milliseconds between switch input probe for AC detection +const uint8_t AC_PERIOD = (20 + SWITCH_FAST_PROBE_INTERVAL - 1) / SWITCH_FAST_PROBE_INTERVAL; // Duration of an AC wave in probe intervals #include @@ -38,6 +40,7 @@ struct SWITCH { uint8_t last_state[MAX_SWITCHES]; // Last wall switch states uint8_t hold_timer[MAX_SWITCHES] = { 0 }; // Timer for wallswitch push button hold uint8_t virtual_state[MAX_SWITCHES]; // Virtual switch states + uint8_t first_change = 0; uint8_t present = 0; } Switch; @@ -81,60 +84,136 @@ void SwitchProbe(void) { if (uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit - uint8_t state_filter = Settings.switch_debounce / SWITCH_PROBE_INTERVAL; // 5, 10, 15 - uint8_t force_high = (Settings.switch_debounce % 10) &1; // 51, 101, 151 etc - uint8_t force_low = (Settings.switch_debounce % 10) &2; // 52, 102, 152 etc + uint8_t state_filter; + uint8_t debounce_flags = Settings.switch_debounce % 10; + uint8_t force_high = debounce_flags &1; // 51, 101, 151 etc + uint8_t force_low = debounce_flags &2; // 52, 102, 152 etc + uint8_t ac_detect = debounce_flags == 9; + uint8_t switch_probe_interval; + uint8_t first_change = Switch.first_change; + + if (ac_detect) { + switch_probe_interval = SWITCH_FAST_PROBE_INTERVAL; + if (Settings.switch_debounce < 2 * AC_PERIOD * SWITCH_FAST_PROBE_INTERVAL + 9) { + state_filter = 2 * AC_PERIOD; + } else if (Settings.switch_debounce > (0x7f - 2 * AC_PERIOD) * SWITCH_FAST_PROBE_INTERVAL) { + state_filter = 0x7f; + } else { + state_filter = (Settings.switch_debounce - 9) / SWITCH_FAST_PROBE_INTERVAL; + } + } else { + switch_probe_interval = SWITCH_PROBE_INTERVAL; + state_filter = Settings.switch_debounce / SWITCH_PROBE_INTERVAL; // 5, 10, 15 + } for (uint32_t i = 0; i < MAX_SWITCHES; i++) { if (PinUsed(GPIO_SWT1, i)) { // Olimex user_switch2.c code to fix 50Hz induced pulses if (1 == digitalRead(Pin(GPIO_SWT1, i))) { - if (force_high) { // Enabled with SwitchDebounce x1 - if (1 == Switch.virtual_state[i]) { - Switch.state[i] = state_filter; // With noisy input keep current state 1 unless constant 0 + if (ac_detect) { // Enabled with SwitchDebounce x9 + Switch.state[i] |= 0x80; + if (Switch.state[i] > 0x80) { + Switch.state[i]--; + if (0x80 == Switch.state[i]) { + Switch.virtual_state[i] = 0; + Switch.first_change = false; + } } - } + } else { - if (Switch.state[i] < state_filter) { - Switch.state[i]++; - if (state_filter == Switch.state[i]) { - Switch.virtual_state[i] = 1; + if (force_high) { // Enabled with SwitchDebounce x1 + if (1 == Switch.virtual_state[i]) { + Switch.state[i] = state_filter; // With noisy input keep current state 1 unless constant 0 + } + } + + if (Switch.state[i] < state_filter) { + Switch.state[i]++; + if (state_filter == Switch.state[i]) { + Switch.virtual_state[i] = 1; + } } } } else { - if (force_low) { // Enabled with SwitchDebounce x2 - if (0 == Switch.virtual_state[i]) { - Switch.state[i] = 0; // With noisy input keep current state 0 unless constant 1 + if (ac_detect) { // Enabled with SwitchDebounce x9 + /* + * Moes MS-104B and similar devices using an AC detection circuitry + * on their switch inputs generating an ~4 ms long low pulse every + * AC wave. We start the time measurement on the falling edge. + * + * state: bit7: previous state, bit6..0: counter + */ + if (Switch.state[i] & 0x80) { + Switch.state[i] &= 0x7f; + if (Switch.state[i] < state_filter - 2 * AC_PERIOD) { + Switch.state[i] += 2 * AC_PERIOD; + } else { + Switch.state[i] = state_filter; + Switch.virtual_state[i] = 1; + if (first_change) { + Switch.last_state[i] = 1; + Switch.first_change = false; + } + } + } else { + if (Switch.state[i] > 0x00) { + Switch.state[i]--; + if (0x00 == Switch.state[i]) { + Switch.virtual_state[i] = 0; + Switch.first_change = false; + } + } } - } + } else { - if (Switch.state[i] > 0) { - Switch.state[i]--; - if (0 == Switch.state[i]) { - Switch.virtual_state[i] = 0; + if (force_low) { // Enabled with SwitchDebounce x2 + if (0 == Switch.virtual_state[i]) { + Switch.state[i] = 0; // With noisy input keep current state 0 unless constant 1 + } + } + + if (Switch.state[i] > 0) { + Switch.state[i]--; + if (0 == Switch.state[i]) { + Switch.virtual_state[i] = 0; + } } } } } } - TickerSwitch.attach_ms(SWITCH_PROBE_INTERVAL, SwitchProbe); // Re-arm as core 2.3.0 does only support ONCE mode + TickerSwitch.attach_ms(switch_probe_interval, SwitchProbe); // Re-arm as core 2.3.0 does only support ONCE mode } void SwitchInit(void) { + uint8_t ac_detect = Settings.switch_debounce % 10 == 9; + Switch.present = 0; for (uint32_t i = 0; i < MAX_SWITCHES; i++) { Switch.last_state[i] = 1; // Init global to virtual switch state; if (PinUsed(GPIO_SWT1, i)) { Switch.present++; pinMode(Pin(GPIO_SWT1, i), bitRead(Switch.no_pullup_mask, i) ? INPUT : ((16 == Pin(GPIO_SWT1, i)) ? INPUT_PULLDOWN_16 : INPUT_PULLUP)); - Switch.last_state[i] = digitalRead(Pin(GPIO_SWT1, i)); // Set global now so doesn't change the saved power state on first switch check + if (ac_detect) { + Switch.state[i] = 0x80 + 2 * AC_PERIOD; + Switch.last_state[i] = 0; // Will set later in the debouncing code + } else { + Switch.last_state[i] = digitalRead(Pin(GPIO_SWT1, i)); // Set global now so doesn't change the saved power state on first switch check + } } Switch.virtual_state[i] = Switch.last_state[i]; } - if (Switch.present) { TickerSwitch.attach_ms(SWITCH_PROBE_INTERVAL, SwitchProbe); } + if (Switch.present) { + if (ac_detect) { + TickerSwitch.attach_ms(SWITCH_FAST_PROBE_INTERVAL, SwitchProbe); + Switch.first_change = true; + } else { + TickerSwitch.attach_ms(SWITCH_PROBE_INTERVAL, SwitchProbe); + } + } } /*********************************************************************************************\ From 3748bb2121a1efddfd7828923a95c49e25b97156 Mon Sep 17 00:00:00 2001 From: m-hume Date: Wed, 3 Jun 2020 13:06:01 +0100 Subject: [PATCH 150/581] Label sensors with hex address --- tasmota/xsns_72_mcp9808.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/xsns_72_mcp9808.ino b/tasmota/xsns_72_mcp9808.ino index 0d757c684..8af129f97 100644 --- a/tasmota/xsns_72_mcp9808.ino +++ b/tasmota/xsns_72_mcp9808.ino @@ -78,10 +78,10 @@ void MCP9808Show(bool json) { char temperature[33]; dtostrfd(mcp9808_sensors[i].temperature, Settings.flag2.temperature_resolution, temperature); - char sensor_name[10]; + char sensor_name[11]; strlcpy(sensor_name, mcp9808_cfg.types, sizeof(sensor_name)); if (mcp9808_cfg.count > 1) { - snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%d"), sensor_name, IndexSeparator(), i +1); // MCP9808-1 + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%02X"), sensor_name, IndexSeparator(), mcp9808_sensors[i].address); // MCP9808-18, MCP9808-1A etc. } if (json) { @@ -133,4 +133,4 @@ bool Xsns72(uint8_t function) } #endif // USE_MCP9808 -#endif // USE_I2C \ No newline at end of file +#endif // USE_I2C From f035932c7486d239b040f404ab441adfd3485735 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 3 Jun 2020 15:12:23 +0200 Subject: [PATCH 151/581] Change BH1750 indexes to I2C address --- tasmota/xsns_10_bh1750.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_10_bh1750.ino b/tasmota/xsns_10_bh1750.ino index 7af8e3960..2c3c801a7 100644 --- a/tasmota/xsns_10_bh1750.ino +++ b/tasmota/xsns_10_bh1750.ino @@ -170,7 +170,7 @@ void Bh1750Show(bool json) { char sensor_name[10]; strlcpy(sensor_name, Bh1750.types, sizeof(sensor_name)); if (Bh1750.count > 1) { - snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%d"), sensor_name, IndexSeparator(), sensor_index +1); // BH1750-1 + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%02X"), sensor_name, IndexSeparator(), Bh1750_sensors[sensor_index].address); // BH1750-23 } if (json) { From 45397293e1c54fa673e3a7f1f5d67f2909e5c6ba Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 3 Jun 2020 22:39:04 +0200 Subject: [PATCH 152/581] Add Zigbee auto-responder for common attributes --- tasmota/CHANGELOG.md | 1 + tasmota/i18n.h | 1 + tasmota/support_json.ino | 8 +- tasmota/xdrv_04_light.ino | 4 + tasmota/xdrv_23_zigbee_0_constants.ino | 1 - tasmota/xdrv_23_zigbee_2_devices.ino | 2 + tasmota/xdrv_23_zigbee_5_converters.ino | 705 +++++++++++++----------- tasmota/xdrv_23_zigbee_8_parsers.ino | 88 ++- tasmota/xdrv_23_zigbee_9_impl.ino | 100 +++- 9 files changed, 563 insertions(+), 347 deletions(-) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 60563404f..e12680d36 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -15,6 +15,7 @@ - Add ``CpuFrequency`` to ``status 2`` - Add ``FlashFrequency`` to ``status 4`` - Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) +- Add Zigbee auto-responder for common attributes ### 8.3.1.1 20200518 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 073f537b2..01122fabd 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -528,6 +528,7 @@ #define D_CMND_ZIGBEE_SEND "Send" #define D_CMND_ZIGBEE_WRITE "Write" #define D_CMND_ZIGBEE_REPORT "Report" +#define D_CMND_ZIGBEE_RESPONSE "Response" #define D_JSON_ZIGBEE_ZCL_SENT "ZbZCLSent" #define D_JSON_ZIGBEE_RECEIVED "ZbReceived" #define D_CMND_ZIGBEE_BIND "Bind" diff --git a/tasmota/support_json.ino b/tasmota/support_json.ino index 51fa0e6a3..902a6e926 100644 --- a/tasmota/support_json.ino +++ b/tasmota/support_json.ino @@ -89,7 +89,7 @@ const JsonVariant &GetCaseInsensitive(const JsonObject &json, const char *needle // key can be in PROGMEM // if needle == "?" then we return the first valid key bool wildcard = strcmp_P("?", needle) == 0; - if ((nullptr == &json) || (nullptr == needle) || (0 == pgm_read_byte(needle))) { + if ((nullptr == &json) || (nullptr == needle) || (0 == pgm_read_byte(needle)) || (!json.success())) { return *(JsonVariant*)nullptr; } @@ -104,3 +104,9 @@ const JsonVariant &GetCaseInsensitive(const JsonObject &json, const char *needle // if not found return *(JsonVariant*)nullptr; } + +// This function returns true if the JsonObject contains the specified key +// It's just a wrapper to the previous function but it can be tricky to test nullptr on an object ref +bool HasKeyCaseInsensitive(const JsonObject &json, const char *needle) { + return &GetCaseInsensitive(json, needle) != nullptr; +} diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 79e0510ad..1d6ac6a58 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1429,6 +1429,10 @@ void LightGetHSB(uint16_t *hue, uint8_t *sat, uint8_t *bri) { light_state.getHSB(hue, sat, bri); } +void LightGetXY(float *X, float *Y) { + light_state.getXY(X, Y); +} + void LightHsToRgb(uint16_t hue, uint8_t sat, uint8_t *r_r, uint8_t *r_g, uint8_t *r_b) { light_state.HsToRgb(hue, sat, r_r, r_g, r_b); } diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index 28628f93c..57bf22499 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -384,7 +384,6 @@ enum ZCL_Global_Commands { ZCL_DEFAULT_RESPONSE = 0x0b, ZCL_DISCOVER_ATTRIBUTES = 0x0c, ZCL_DISCOVER_ATTRIBUTES_RESPONSE = 0x0d - }; #define ZF(s) static const char ZS_ ## s[] PROGMEM = #s; diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 60f116002..23a9343d4 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -526,6 +526,8 @@ void Z_Devices::addEndpoint(uint16_t shortaddr, uint8_t endpoint) { // Find the first endpoint of the device uint8_t Z_Devices::findFirstEndpoint(uint16_t shortaddr) const { + // When in router of end-device mode, the coordinator was not probed, in this case always talk to endpoint 1 + if (0x0000 == shortaddr) { return 1; } int32_t found = findShortAddr(shortaddr); if (found < 0) return 0; // avoid creating an entry if the device was never seen const Z_Device &device = devicesAt(found); diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 5da74a1ed..bf508d9c2 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -89,7 +89,9 @@ typedef struct Z_AttributeConverter { uint8_t cluster_short; uint16_t attribute; const char * name; - Z_AttrConverter func; + int16_t multiplier; // multiplier for numerical value, (if > 0 multiply by x, if <0 device by x) + uint8_t cb; // callback func from Z_ConvOperators + // Z_AttrConverter func; } Z_AttributeConverter; // Cluster numbers are store in 8 bits format to save space, @@ -118,6 +120,16 @@ uint16_t CxToCluster(uint8_t cx) { return 0xFFFF; } +enum Z_ConvOperators { + Z_Nop, // copy value + Z_AddPressureUnit, // add pressure unit attribute (non numerical) + Z_ManufKeep, // copy and record Manufacturer attribute + Z_ModelKeep, // copy and record ModelId attribute + Z_AqaraSensor, // decode prioprietary Aqara Sensor message + Z_AqaraVibration, // decode Aqara vibration modes + Z_AqaraCube, // decode Aqara cube +}; + ZF(ZCLVersion) ZF(AppVersion) ZF(StackVersion) ZF(HWVersion) ZF(Manufacturer) ZF(ModelId) ZF(DateCode) ZF(PowerSource) ZF(SWBuildID) ZF(Power) ZF(SwitchType) ZF(Dimmer) ZF(MainsVoltage) ZF(MainsFrequency) ZF(BatteryVoltage) ZF(BatteryPercentage) @@ -209,356 +221,356 @@ ZF(SoftwareRevision) ZF(POD) ZF(AvailablePower) ZF(PowerThreshold) ZF(ProductRev ZF(NumberOfResets) ZF(PersistentMemoryWrites) ZF(LastMessageLQI) ZF(LastMessageRSSI) // list of post-processing directives const Z_AttributeConverter Z_PostProcess[] PROGMEM = { - { Zuint8, Cx0000, 0x0000, Z(ZCLVersion), &Z_Copy }, - { Zuint8, Cx0000, 0x0001, Z(AppVersion), &Z_Copy }, - { Zuint8, Cx0000, 0x0002, Z(StackVersion), &Z_Copy }, - { Zuint8, Cx0000, 0x0003, Z(HWVersion), &Z_Copy }, - { Zstring, Cx0000, 0x0004, Z(Manufacturer), &Z_ManufKeep }, // record Manufacturer - { Zstring, Cx0000, 0x0005, Z(ModelId), &Z_ModelKeep }, // record Model - { Zstring, Cx0000, 0x0006, Z(DateCode), &Z_Copy }, - { Zenum8, Cx0000, 0x0007, Z(PowerSource), &Z_Copy }, - { Zstring, Cx0000, 0x4000, Z(SWBuildID), &Z_Copy }, - { Zunk, Cx0000, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint8, Cx0000, 0x0000, Z(ZCLVersion), 1, Z_Nop }, + { Zuint8, Cx0000, 0x0001, Z(AppVersion), 1, Z_Nop }, + { Zuint8, Cx0000, 0x0002, Z(StackVersion), 1, Z_Nop }, + { Zuint8, Cx0000, 0x0003, Z(HWVersion), 1, Z_Nop }, + { Zstring, Cx0000, 0x0004, Z(Manufacturer), 1, Z_ManufKeep }, // record Manufacturer + { Zstring, Cx0000, 0x0005, Z(ModelId), 1, Z_ModelKeep }, // record Model + { Zstring, Cx0000, 0x0006, Z(DateCode), 1, Z_Nop }, + { Zenum8, Cx0000, 0x0007, Z(PowerSource), 1, Z_Nop }, + { Zstring, Cx0000, 0x4000, Z(SWBuildID), 1, Z_Nop }, + { Zunk, Cx0000, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Cmd 0x0A - Cluster 0x0000, attribute 0xFF01 - proprietary - { Zmap8, Cx0000, 0xFF01, nullptr, &Z_AqaraSensor }, // Occupancy (map8) + { Zmap8, Cx0000, 0xFF01, nullptr, 0, Z_AqaraSensor }, // Occupancy (map8) // Power Configuration cluster - { Zuint16, Cx0001, 0x0000, Z(MainsVoltage), &Z_Copy }, - { Zuint8, Cx0001, 0x0001, Z(MainsFrequency), &Z_Copy }, - { Zuint8, Cx0001, 0x0020, Z(BatteryVoltage), &Z_FloatDiv10 }, - { Zuint8, Cx0001, 0x0021, Z(BatteryPercentage), &Z_FloatDiv2 }, + { Zuint16, Cx0001, 0x0000, Z(MainsVoltage), 1, Z_Nop }, + { Zuint8, Cx0001, 0x0001, Z(MainsFrequency), 1, Z_Nop }, + { Zuint8, Cx0001, 0x0020, Z(BatteryVoltage), -10,Z_Nop }, // divide by 10 + { Zuint8, Cx0001, 0x0021, Z(BatteryPercentage), -2, Z_Nop }, // divide by 2 // Device Temperature Configuration cluster - { Zint16, Cx0002, 0x0000, Z(CurrentTemperature), &Z_Copy }, - { Zint16, Cx0002, 0x0001, Z(MinTempExperienced), &Z_Copy }, - { Zint16, Cx0002, 0x0002, Z(MaxTempExperienced), &Z_Copy }, - { Zuint16, Cx0002, 0x0003, Z(OverTempTotalDwell), &Z_Copy }, + { Zint16, Cx0002, 0x0000, Z(CurrentTemperature), 1, Z_Nop }, + { Zint16, Cx0002, 0x0001, Z(MinTempExperienced), 1, Z_Nop }, + { Zint16, Cx0002, 0x0002, Z(MaxTempExperienced), 1, Z_Nop }, + { Zuint16, Cx0002, 0x0003, Z(OverTempTotalDwell), 1, Z_Nop }, // Scenes cluster - { Zuint8, Cx0005, 0x0000, Z(SceneCount), &Z_Copy }, - { Zuint8, Cx0005, 0x0001, Z(CurrentScene), &Z_Copy }, - { Zuint16, Cx0005, 0x0002, Z(CurrentGroup), &Z_Copy }, - { Zbool, Cx0005, 0x0003, Z(SceneValid), &Z_Copy }, - //{ Zmap8, Cx0005, 0x0004, Z(NameSupport), &Z_Copy }, + { Zuint8, Cx0005, 0x0000, Z(SceneCount), 1, Z_Nop }, + { Zuint8, Cx0005, 0x0001, Z(CurrentScene), 1, Z_Nop }, + { Zuint16, Cx0005, 0x0002, Z(CurrentGroup), 1, Z_Nop }, + { Zbool, Cx0005, 0x0003, Z(SceneValid), 1, Z_Nop }, + //{ Zmap8, Cx0005, 0x0004, Z(NameSupport), 1, Z_Nop }, // On/off cluster - { Zbool, Cx0006, 0x0000, Z(Power), &Z_Copy }, - { Zbool, Cx0006, 0x8000, Z(Power), &Z_Copy }, // See 7280 + { Zbool, Cx0006, 0x0000, Z(Power), 1, Z_Nop }, + { Zbool, Cx0006, 0x8000, Z(Power), 1, Z_Nop }, // See 7280 // On/Off Switch Configuration cluster - { Zenum8, Cx0007, 0x0000, Z(SwitchType), &Z_Copy }, + { Zenum8, Cx0007, 0x0000, Z(SwitchType), 1, Z_Nop }, // Level Control cluster - { Zuint8, Cx0008, 0x0000, Z(Dimmer), &Z_Copy }, - // { Zuint16, Cx0008, 0x0001, Z(RemainingTime", &Z_Copy }, - // { Zuint16, Cx0008, 0x0010, Z(OnOffTransitionTime", &Z_Copy }, - // { Zuint8, Cx0008, 0x0011, Z(OnLevel", &Z_Copy }, - // { Zuint16, Cx0008, 0x0012, Z(OnTransitionTime", &Z_Copy }, - // { Zuint16, Cx0008, 0x0013, Z(OffTransitionTime", &Z_Copy }, - // { Zuint16, Cx0008, 0x0014, Z(DefaultMoveRate", &Z_Copy }, + { Zuint8, Cx0008, 0x0000, Z(Dimmer), 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0001, Z(RemainingTime", 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0010, Z(OnOffTransitionTime", 1, Z_Nop }, + // { Zuint8, Cx0008, 0x0011, Z(OnLevel", 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0012, Z(OnTransitionTime", 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0013, Z(OffTransitionTime", 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0014, Z(DefaultMoveRate", 1, Z_Nop }, // Alarms cluster - { Zuint16, Cx0009, 0x0000, Z(AlarmCount), &Z_Copy }, + { Zuint16, Cx0009, 0x0000, Z(AlarmCount), 1, Z_Nop }, // Time cluster - { ZUTC, Cx000A, 0x0000, Z(Time), &Z_Copy }, - { Zmap8, Cx000A, 0x0001, Z(TimeStatus), &Z_Copy }, - { Zint32, Cx000A, 0x0002, Z(TimeZone), &Z_Copy }, - { Zuint32, Cx000A, 0x0003, Z(DstStart), &Z_Copy }, - { Zuint32, Cx000A, 0x0004, Z(DstEnd), &Z_Copy }, - { Zint32, Cx000A, 0x0005, Z(DstShift), &Z_Copy }, - { Zuint32, Cx000A, 0x0006, Z(StandardTime), &Z_Copy }, - { Zuint32, Cx000A, 0x0007, Z(LocalTime), &Z_Copy }, - { ZUTC, Cx000A, 0x0008, Z(LastSetTime), &Z_Copy }, - { ZUTC, Cx000A, 0x0009, Z(ValidUntilTime), &Z_Copy }, + { ZUTC, Cx000A, 0x0000, Z(Time), 1, Z_Nop }, + { Zmap8, Cx000A, 0x0001, Z(TimeStatus), 1, Z_Nop }, + { Zint32, Cx000A, 0x0002, Z(TimeZone), 1, Z_Nop }, + { Zuint32, Cx000A, 0x0003, Z(DstStart), 1, Z_Nop }, + { Zuint32, Cx000A, 0x0004, Z(DstEnd), 1, Z_Nop }, + { Zint32, Cx000A, 0x0005, Z(DstShift), 1, Z_Nop }, + { Zuint32, Cx000A, 0x0006, Z(StandardTime), 1, Z_Nop }, + { Zuint32, Cx000A, 0x0007, Z(LocalTime), 1, Z_Nop }, + { ZUTC, Cx000A, 0x0008, Z(LastSetTime), 1, Z_Nop }, + { ZUTC, Cx000A, 0x0009, Z(ValidUntilTime), 1, Z_Nop }, // RSSI Location cluster - { Zdata8, Cx000B, 0x0000, Z(LocationType), &Z_Copy }, - { Zenum8, Cx000B, 0x0001, Z(LocationMethod), &Z_Copy }, - { Zuint16, Cx000B, 0x0002, Z(LocationAge), &Z_Copy }, - { Zuint8, Cx000B, 0x0003, Z(QualityMeasure), &Z_Copy }, - { Zuint8, Cx000B, 0x0004, Z(NumberOfDevices), &Z_Copy }, + { Zdata8, Cx000B, 0x0000, Z(LocationType), 1, Z_Nop }, + { Zenum8, Cx000B, 0x0001, Z(LocationMethod), 1, Z_Nop }, + { Zuint16, Cx000B, 0x0002, Z(LocationAge), 1, Z_Nop }, + { Zuint8, Cx000B, 0x0003, Z(QualityMeasure), 1, Z_Nop }, + { Zuint8, Cx000B, 0x0004, Z(NumberOfDevices), 1, Z_Nop }, // Analog Input cluster - // { 0xFF, Cx000C, 0x0004, Z(AnalogInActiveText), &Z_Copy }, - { Zstring, Cx000C, 0x001C, Z(AnalogInDescription), &Z_Copy }, - // { 0xFF, Cx000C, 0x002E, Z(AnalogInInactiveText), &Z_Copy }, - { Zsingle, Cx000C, 0x0041, Z(AnalogInMaxValue), &Z_Copy }, - { Zsingle, Cx000C, 0x0045, Z(AnalogInMinValue), &Z_Copy }, - { Zbool, Cx000C, 0x0051, Z(AnalogInOutOfService), &Z_Copy }, - { Zsingle, Cx000C, 0x0055, Z(AqaraRotate), &Z_Copy }, - // { 0xFF, Cx000C, 0x0057, Z(AnalogInPriorityArray),&Z_Copy }, - { Zenum8, Cx000C, 0x0067, Z(AnalogInReliability), &Z_Copy }, - // { 0xFF, Cx000C, 0x0068, Z(AnalogInRelinquishDefault),&Z_Copy }, - { Zsingle, Cx000C, 0x006A, Z(AnalogInResolution), &Z_Copy }, - { Zmap8, Cx000C, 0x006F, Z(AnalogInStatusFlags), &Z_Copy }, - { Zenum16, Cx000C, 0x0075, Z(AnalogInEngineeringUnits),&Z_Copy }, - { Zuint32, Cx000C, 0x0100, Z(AnalogInApplicationType),&Z_Copy }, - { Zuint16, Cx000C, 0xFF05, Z(Aqara_FF05), &Z_Copy }, + // { 0xFF, Cx000C, 0x0004, Z(AnalogInActiveText), 1, Z_Nop }, + { Zstring, Cx000C, 0x001C, Z(AnalogInDescription), 1, Z_Nop }, + // { 0xFF, Cx000C, 0x002E, Z(AnalogInInactiveText), 1, Z_Nop }, + { Zsingle, Cx000C, 0x0041, Z(AnalogInMaxValue), 1, Z_Nop }, + { Zsingle, Cx000C, 0x0045, Z(AnalogInMinValue), 1, Z_Nop }, + { Zbool, Cx000C, 0x0051, Z(AnalogInOutOfService), 1, Z_Nop }, + { Zsingle, Cx000C, 0x0055, Z(AqaraRotate), 1, Z_Nop }, + // { 0xFF, Cx000C, 0x0057, Z(AnalogInPriorityArray),1, Z_Nop }, + { Zenum8, Cx000C, 0x0067, Z(AnalogInReliability), 1, Z_Nop }, + // { 0xFF, Cx000C, 0x0068, Z(AnalogInRelinquishDefault),1, Z_Nop }, + { Zsingle, Cx000C, 0x006A, Z(AnalogInResolution), 1, Z_Nop }, + { Zmap8, Cx000C, 0x006F, Z(AnalogInStatusFlags), 1, Z_Nop }, + { Zenum16, Cx000C, 0x0075, Z(AnalogInEngineeringUnits),1, Z_Nop }, + { Zuint32, Cx000C, 0x0100, Z(AnalogInApplicationType),1, Z_Nop }, + { Zuint16, Cx000C, 0xFF05, Z(Aqara_FF05), 1, Z_Nop }, // Analog Output cluster - { Zstring, Cx000D, 0x001C, Z(AnalogOutDescription), &Z_Copy }, - { Zsingle, Cx000D, 0x0041, Z(AnalogOutMaxValue), &Z_Copy }, - { Zsingle, Cx000D, 0x0045, Z(AnalogOutMinValue), &Z_Copy }, - { Zbool, Cx000D, 0x0051, Z(AnalogOutOutOfService),&Z_Copy }, - { Zsingle, Cx000D, 0x0055, Z(AnalogOutValue), &Z_Copy }, - // { Zunk, Cx000D, 0x0057, Z(AnalogOutPriorityArray),&Z_Copy }, - { Zenum8, Cx000D, 0x0067, Z(AnalogOutReliability), &Z_Copy }, - { Zsingle, Cx000D, 0x0068, Z(AnalogOutRelinquishDefault),&Z_Copy }, - { Zsingle, Cx000D, 0x006A, Z(AnalogOutResolution), &Z_Copy }, - { Zmap8, Cx000D, 0x006F, Z(AnalogOutStatusFlags), &Z_Copy }, - { Zenum16, Cx000D, 0x0075, Z(AnalogOutEngineeringUnits),&Z_Copy }, - { Zuint32, Cx000D, 0x0100, Z(AnalogOutApplicationType),&Z_Copy }, + { Zstring, Cx000D, 0x001C, Z(AnalogOutDescription), 1, Z_Nop }, + { Zsingle, Cx000D, 0x0041, Z(AnalogOutMaxValue), 1, Z_Nop }, + { Zsingle, Cx000D, 0x0045, Z(AnalogOutMinValue), 1, Z_Nop }, + { Zbool, Cx000D, 0x0051, Z(AnalogOutOutOfService),1, Z_Nop }, + { Zsingle, Cx000D, 0x0055, Z(AnalogOutValue), 1, Z_Nop }, + // { Zunk, Cx000D, 0x0057, Z(AnalogOutPriorityArray),1, Z_Nop }, + { Zenum8, Cx000D, 0x0067, Z(AnalogOutReliability), 1, Z_Nop }, + { Zsingle, Cx000D, 0x0068, Z(AnalogOutRelinquishDefault),1, Z_Nop }, + { Zsingle, Cx000D, 0x006A, Z(AnalogOutResolution), 1, Z_Nop }, + { Zmap8, Cx000D, 0x006F, Z(AnalogOutStatusFlags), 1, Z_Nop }, + { Zenum16, Cx000D, 0x0075, Z(AnalogOutEngineeringUnits),1, Z_Nop }, + { Zuint32, Cx000D, 0x0100, Z(AnalogOutApplicationType),1, Z_Nop }, // Analog Value cluster - { Zstring, Cx000E, 0x001C, Z(AnalogDescription), &Z_Copy }, - { Zbool, Cx000E, 0x0051, Z(AnalogOutOfService), &Z_Copy }, - { Zsingle, Cx000E, 0x0055, Z(AnalogValue), &Z_Copy }, - { Zunk, Cx000E, 0x0057, Z(AnalogPriorityArray), &Z_Copy }, - { Zenum8, Cx000E, 0x0067, Z(AnalogReliability), &Z_Copy }, - { Zsingle, Cx000E, 0x0068, Z(AnalogRelinquishDefault),&Z_Copy }, - { Zmap8, Cx000E, 0x006F, Z(AnalogStatusFlags), &Z_Copy }, - { Zenum16, Cx000E, 0x0075, Z(AnalogEngineeringUnits),&Z_Copy }, - { Zuint32, Cx000E, 0x0100, Z(AnalogApplicationType),&Z_Copy }, + { Zstring, Cx000E, 0x001C, Z(AnalogDescription), 1, Z_Nop }, + { Zbool, Cx000E, 0x0051, Z(AnalogOutOfService), 1, Z_Nop }, + { Zsingle, Cx000E, 0x0055, Z(AnalogValue), 1, Z_Nop }, + { Zunk, Cx000E, 0x0057, Z(AnalogPriorityArray), 1, Z_Nop }, + { Zenum8, Cx000E, 0x0067, Z(AnalogReliability), 1, Z_Nop }, + { Zsingle, Cx000E, 0x0068, Z(AnalogRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx000E, 0x006F, Z(AnalogStatusFlags), 1, Z_Nop }, + { Zenum16, Cx000E, 0x0075, Z(AnalogEngineeringUnits),1, Z_Nop }, + { Zuint32, Cx000E, 0x0100, Z(AnalogApplicationType),1, Z_Nop }, // Binary Input cluster - { Zstring, Cx000F, 0x0004, Z(BinaryInActiveText), &Z_Copy }, - { Zstring, Cx000F, 0x001C, Z(BinaryInDescription), &Z_Copy }, - { Zstring, Cx000F, 0x002E, Z(BinaryInInactiveText),&Z_Copy }, - { Zbool, Cx000F, 0x0051, Z(BinaryInOutOfService),&Z_Copy }, - { Zenum8, Cx000F, 0x0054, Z(BinaryInPolarity), &Z_Copy }, - { Zstring, Cx000F, 0x0055, Z(BinaryInValue), &Z_Copy }, - // { 0xFF, Cx000F, 0x0057, Z(BinaryInPriorityArray),&Z_Copy }, - { Zenum8, Cx000F, 0x0067, Z(BinaryInReliability), &Z_Copy }, - { Zmap8, Cx000F, 0x006F, Z(BinaryInStatusFlags), &Z_Copy }, - { Zuint32, Cx000F, 0x0100, Z(BinaryInApplicationType),&Z_Copy }, + { Zstring, Cx000F, 0x0004, Z(BinaryInActiveText), 1, Z_Nop }, + { Zstring, Cx000F, 0x001C, Z(BinaryInDescription), 1, Z_Nop }, + { Zstring, Cx000F, 0x002E, Z(BinaryInInactiveText),1, Z_Nop }, + { Zbool, Cx000F, 0x0051, Z(BinaryInOutOfService),1, Z_Nop }, + { Zenum8, Cx000F, 0x0054, Z(BinaryInPolarity), 1, Z_Nop }, + { Zstring, Cx000F, 0x0055, Z(BinaryInValue), 1, Z_Nop }, + // { 0xFF, Cx000F, 0x0057, Z(BinaryInPriorityArray),1, Z_Nop }, + { Zenum8, Cx000F, 0x0067, Z(BinaryInReliability), 1, Z_Nop }, + { Zmap8, Cx000F, 0x006F, Z(BinaryInStatusFlags), 1, Z_Nop }, + { Zuint32, Cx000F, 0x0100, Z(BinaryInApplicationType),1, Z_Nop }, // Binary Output cluster - { Zstring, Cx0010, 0x0004, Z(BinaryOutActiveText), &Z_Copy }, - { Zstring, Cx0010, 0x001C, Z(BinaryOutDescription), &Z_Copy }, - { Zstring, Cx0010, 0x002E, Z(BinaryOutInactiveText),&Z_Copy }, - { Zuint32, Cx0010, 0x0042, Z(BinaryOutMinimumOffTime),&Z_Copy }, - { Zuint32, Cx0010, 0x0043, Z(BinaryOutMinimumOnTime),&Z_Copy }, - { Zbool, Cx0010, 0x0051, Z(BinaryOutOutOfService),&Z_Copy }, - { Zenum8, Cx0010, 0x0054, Z(BinaryOutPolarity), &Z_Copy }, - { Zbool, Cx0010, 0x0055, Z(BinaryOutValue), &Z_Copy }, - // { Zunk, Cx0010, 0x0057, Z(BinaryOutPriorityArray),&Z_Copy }, - { Zenum8, Cx0010, 0x0067, Z(BinaryOutReliability), &Z_Copy }, - { Zbool, Cx0010, 0x0068, Z(BinaryOutRelinquishDefault),&Z_Copy }, - { Zmap8, Cx0010, 0x006F, Z(BinaryOutStatusFlags), &Z_Copy }, - { Zuint32, Cx0010, 0x0100, Z(BinaryOutApplicationType),&Z_Copy }, + { Zstring, Cx0010, 0x0004, Z(BinaryOutActiveText), 1, Z_Nop }, + { Zstring, Cx0010, 0x001C, Z(BinaryOutDescription), 1, Z_Nop }, + { Zstring, Cx0010, 0x002E, Z(BinaryOutInactiveText),1, Z_Nop }, + { Zuint32, Cx0010, 0x0042, Z(BinaryOutMinimumOffTime),1, Z_Nop }, + { Zuint32, Cx0010, 0x0043, Z(BinaryOutMinimumOnTime),1, Z_Nop }, + { Zbool, Cx0010, 0x0051, Z(BinaryOutOutOfService),1, Z_Nop }, + { Zenum8, Cx0010, 0x0054, Z(BinaryOutPolarity), 1, Z_Nop }, + { Zbool, Cx0010, 0x0055, Z(BinaryOutValue), 1, Z_Nop }, + // { Zunk, Cx0010, 0x0057, Z(BinaryOutPriorityArray),1, Z_Nop }, + { Zenum8, Cx0010, 0x0067, Z(BinaryOutReliability), 1, Z_Nop }, + { Zbool, Cx0010, 0x0068, Z(BinaryOutRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx0010, 0x006F, Z(BinaryOutStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0010, 0x0100, Z(BinaryOutApplicationType),1, Z_Nop }, // Binary Value cluster - { Zstring, Cx0011, 0x0004, Z(BinaryActiveText), &Z_Copy }, - { Zstring, Cx0011, 0x001C, Z(BinaryDescription), &Z_Copy }, - { Zstring, Cx0011, 0x002E, Z(BinaryInactiveText), &Z_Copy }, - { Zuint32, Cx0011, 0x0042, Z(BinaryMinimumOffTime), &Z_Copy }, - { Zuint32, Cx0011, 0x0043, Z(BinaryMinimumOnTime), &Z_Copy }, - { Zbool, Cx0011, 0x0051, Z(BinaryOutOfService), &Z_Copy }, - { Zbool, Cx0011, 0x0055, Z(BinaryValue), &Z_Copy }, - // { Zunk, Cx0011, 0x0057, Z(BinaryPriorityArray), &Z_Copy }, - { Zenum8, Cx0011, 0x0067, Z(BinaryReliability), &Z_Copy }, - { Zbool, Cx0011, 0x0068, Z(BinaryRelinquishDefault),&Z_Copy }, - { Zmap8, Cx0011, 0x006F, Z(BinaryStatusFlags), &Z_Copy }, - { Zuint32, Cx0011, 0x0100, Z(BinaryApplicationType),&Z_Copy }, + { Zstring, Cx0011, 0x0004, Z(BinaryActiveText), 1, Z_Nop }, + { Zstring, Cx0011, 0x001C, Z(BinaryDescription), 1, Z_Nop }, + { Zstring, Cx0011, 0x002E, Z(BinaryInactiveText), 1, Z_Nop }, + { Zuint32, Cx0011, 0x0042, Z(BinaryMinimumOffTime), 1, Z_Nop }, + { Zuint32, Cx0011, 0x0043, Z(BinaryMinimumOnTime), 1, Z_Nop }, + { Zbool, Cx0011, 0x0051, Z(BinaryOutOfService), 1, Z_Nop }, + { Zbool, Cx0011, 0x0055, Z(BinaryValue), 1, Z_Nop }, + // { Zunk, Cx0011, 0x0057, Z(BinaryPriorityArray), 1, Z_Nop }, + { Zenum8, Cx0011, 0x0067, Z(BinaryReliability), 1, Z_Nop }, + { Zbool, Cx0011, 0x0068, Z(BinaryRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx0011, 0x006F, Z(BinaryStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0011, 0x0100, Z(BinaryApplicationType),1, Z_Nop }, // Multistate Input cluster - // { Zunk, Cx0012, 0x000E, Z(MultiInStateText), &Z_Copy }, - { Zstring, Cx0012, 0x001C, Z(MultiInDescription), &Z_Copy }, - { Zuint16, Cx0012, 0x004A, Z(MultiInNumberOfStates),&Z_Copy }, - { Zbool, Cx0012, 0x0051, Z(MultiInOutOfService), &Z_Copy }, - { Zuint16, Cx0012, 0x0055, Z(MultiInValue), &Z_AqaraCube }, - { Zenum8, Cx0012, 0x0067, Z(MultiInReliability), &Z_Copy }, - { Zmap8, Cx0012, 0x006F, Z(MultiInStatusFlags), &Z_Copy }, - { Zuint32, Cx0012, 0x0100, Z(MultiInApplicationType),&Z_Copy }, + // { Zunk, Cx0012, 0x000E, Z(MultiInStateText), 1, Z_Nop }, + { Zstring, Cx0012, 0x001C, Z(MultiInDescription), 1, Z_Nop }, + { Zuint16, Cx0012, 0x004A, Z(MultiInNumberOfStates),1, Z_Nop }, + { Zbool, Cx0012, 0x0051, Z(MultiInOutOfService), 1, Z_Nop }, + { Zuint16, Cx0012, 0x0055, Z(MultiInValue), 0, Z_AqaraCube }, + { Zenum8, Cx0012, 0x0067, Z(MultiInReliability), 1, Z_Nop }, + { Zmap8, Cx0012, 0x006F, Z(MultiInStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0012, 0x0100, Z(MultiInApplicationType),1, Z_Nop }, // Multistate output - // { Zunk, Cx0013, 0x000E, Z(MultiOutStateText), &Z_Copy }, - { Zstring, Cx0013, 0x001C, Z(MultiOutDescription), &Z_Copy }, - { Zuint16, Cx0013, 0x004A, Z(MultiOutNumberOfStates),&Z_Copy }, - { Zbool, Cx0013, 0x0051, Z(MultiOutOutOfService), &Z_Copy }, - { Zuint16, Cx0013, 0x0055, Z(MultiOutValue), &Z_Copy }, - // { Zunk, Cx0013, 0x0057, Z(MultiOutPriorityArray),&Z_Copy }, - { Zenum8, Cx0013, 0x0067, Z(MultiOutReliability), &Z_Copy }, - { Zuint16, Cx0013, 0x0068, Z(MultiOutRelinquishDefault),&Z_Copy }, - { Zmap8, Cx0013, 0x006F, Z(MultiOutStatusFlags), &Z_Copy }, - { Zuint32, Cx0013, 0x0100, Z(MultiOutApplicationType),&Z_Copy }, + // { Zunk, Cx0013, 0x000E, Z(MultiOutStateText), 1, Z_Nop }, + { Zstring, Cx0013, 0x001C, Z(MultiOutDescription), 1, Z_Nop }, + { Zuint16, Cx0013, 0x004A, Z(MultiOutNumberOfStates),1, Z_Nop }, + { Zbool, Cx0013, 0x0051, Z(MultiOutOutOfService), 1, Z_Nop }, + { Zuint16, Cx0013, 0x0055, Z(MultiOutValue), 1, Z_Nop }, + // { Zunk, Cx0013, 0x0057, Z(MultiOutPriorityArray),1, Z_Nop }, + { Zenum8, Cx0013, 0x0067, Z(MultiOutReliability), 1, Z_Nop }, + { Zuint16, Cx0013, 0x0068, Z(MultiOutRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx0013, 0x006F, Z(MultiOutStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0013, 0x0100, Z(MultiOutApplicationType),1, Z_Nop }, // Multistate Value cluster - // { Zunk, Cx0014, 0x000E, Z(MultiStateText), &Z_Copy }, - { Zstring, Cx0014, 0x001C, Z(MultiDescription), &Z_Copy }, - { Zuint16, Cx0014, 0x004A, Z(MultiNumberOfStates), &Z_Copy }, - { Zbool, Cx0014, 0x0051, Z(MultiOutOfService), &Z_Copy }, - { Zuint16, Cx0014, 0x0055, Z(MultiValue), &Z_Copy }, - { Zenum8, Cx0014, 0x0067, Z(MultiReliability), &Z_Copy }, - { Zuint16, Cx0014, 0x0068, Z(MultiRelinquishDefault),&Z_Copy }, - { Zmap8, Cx0014, 0x006F, Z(MultiStatusFlags), &Z_Copy }, - { Zuint32, Cx0014, 0x0100, Z(MultiApplicationType), &Z_Copy }, + // { Zunk, Cx0014, 0x000E, Z(MultiStateText), 1, Z_Nop }, + { Zstring, Cx0014, 0x001C, Z(MultiDescription), 1, Z_Nop }, + { Zuint16, Cx0014, 0x004A, Z(MultiNumberOfStates), 1, Z_Nop }, + { Zbool, Cx0014, 0x0051, Z(MultiOutOfService), 1, Z_Nop }, + { Zuint16, Cx0014, 0x0055, Z(MultiValue), 1, Z_Nop }, + { Zenum8, Cx0014, 0x0067, Z(MultiReliability), 1, Z_Nop }, + { Zuint16, Cx0014, 0x0068, Z(MultiRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx0014, 0x006F, Z(MultiStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0014, 0x0100, Z(MultiApplicationType), 1, Z_Nop }, // Power Profile cluster - { Zuint8, Cx001A, 0x0000, Z(TotalProfileNum), &Z_Copy }, - { Zbool, Cx001A, 0x0001, Z(MultipleScheduling), &Z_Copy }, - { Zmap8, Cx001A, 0x0002, Z(EnergyFormatting), &Z_Copy }, - { Zbool, Cx001A, 0x0003, Z(EnergyRemote), &Z_Copy }, - { Zmap8, Cx001A, 0x0004, Z(ScheduleMode), &Z_Copy }, + { Zuint8, Cx001A, 0x0000, Z(TotalProfileNum), 1, Z_Nop }, + { Zbool, Cx001A, 0x0001, Z(MultipleScheduling), 1, Z_Nop }, + { Zmap8, Cx001A, 0x0002, Z(EnergyFormatting), 1, Z_Nop }, + { Zbool, Cx001A, 0x0003, Z(EnergyRemote), 1, Z_Nop }, + { Zmap8, Cx001A, 0x0004, Z(ScheduleMode), 1, Z_Nop }, // Poll Control cluster - { Zuint32, Cx0020, 0x0000, Z(CheckinInterval), &Z_Copy }, - { Zuint32, Cx0020, 0x0001, Z(LongPollInterval), &Z_Copy }, - { Zuint16, Cx0020, 0x0002, Z(ShortPollInterval), &Z_Copy }, - { Zuint16, Cx0020, 0x0003, Z(FastPollTimeout), &Z_Copy }, - { Zuint32, Cx0020, 0x0004, Z(CheckinIntervalMin), &Z_Copy }, - { Zuint32, Cx0020, 0x0005, Z(LongPollIntervalMin), &Z_Copy }, - { Zuint16, Cx0020, 0x0006, Z(FastPollTimeoutMax), &Z_Copy }, + { Zuint32, Cx0020, 0x0000, Z(CheckinInterval), 1, Z_Nop }, + { Zuint32, Cx0020, 0x0001, Z(LongPollInterval), 1, Z_Nop }, + { Zuint16, Cx0020, 0x0002, Z(ShortPollInterval), 1, Z_Nop }, + { Zuint16, Cx0020, 0x0003, Z(FastPollTimeout), 1, Z_Nop }, + { Zuint32, Cx0020, 0x0004, Z(CheckinIntervalMin), 1, Z_Nop }, + { Zuint32, Cx0020, 0x0005, Z(LongPollIntervalMin), 1, Z_Nop }, + { Zuint16, Cx0020, 0x0006, Z(FastPollTimeoutMax), 1, Z_Nop }, // Shade Configuration cluster - { Zuint16, Cx0100, 0x0000, Z(PhysicalClosedLimit), &Z_Copy }, - { Zuint8, Cx0100, 0x0001, Z(MotorStepSize), &Z_Copy }, - { Zmap8, Cx0100, 0x0002, Z(Status), &Z_Copy }, - { Zuint16, Cx0100, 0x0010, Z(ClosedLimit), &Z_Copy }, - { Zenum8, Cx0100, 0x0011, Z(Mode), &Z_Copy }, + { Zuint16, Cx0100, 0x0000, Z(PhysicalClosedLimit), 1, Z_Nop }, + { Zuint8, Cx0100, 0x0001, Z(MotorStepSize), 1, Z_Nop }, + { Zmap8, Cx0100, 0x0002, Z(Status), 1, Z_Nop }, + { Zuint16, Cx0100, 0x0010, Z(ClosedLimit), 1, Z_Nop }, + { Zenum8, Cx0100, 0x0011, Z(Mode), 1, Z_Nop }, // Door Lock cluster - { Zenum8, Cx0101, 0x0000, Z(LockState), &Z_Copy }, - { Zenum8, Cx0101, 0x0001, Z(LockType), &Z_Copy }, - { Zbool, Cx0101, 0x0002, Z(ActuatorEnabled), &Z_Copy }, - { Zenum8, Cx0101, 0x0003, Z(DoorState), &Z_Copy }, - { Zuint32, Cx0101, 0x0004, Z(DoorOpenEvents), &Z_Copy }, - { Zuint32, Cx0101, 0x0005, Z(DoorClosedEvents), &Z_Copy }, - { Zuint16, Cx0101, 0x0006, Z(OpenPeriod), &Z_Copy }, + { Zenum8, Cx0101, 0x0000, Z(LockState), 1, Z_Nop }, + { Zenum8, Cx0101, 0x0001, Z(LockType), 1, Z_Nop }, + { Zbool, Cx0101, 0x0002, Z(ActuatorEnabled), 1, Z_Nop }, + { Zenum8, Cx0101, 0x0003, Z(DoorState), 1, Z_Nop }, + { Zuint32, Cx0101, 0x0004, Z(DoorOpenEvents), 1, Z_Nop }, + { Zuint32, Cx0101, 0x0005, Z(DoorClosedEvents), 1, Z_Nop }, + { Zuint16, Cx0101, 0x0006, Z(OpenPeriod), 1, Z_Nop }, // Aqara Lumi Vibration Sensor - { Zuint16, Cx0101, 0x0055, Z(AqaraVibrationMode), &Z_AqaraVibration }, - { Zuint16, Cx0101, 0x0503, Z(AqaraVibrationsOrAngle), &Z_Copy }, - { Zuint32, Cx0101, 0x0505, Z(AqaraVibration505), &Z_Copy }, - { Zuint48, Cx0101, 0x0508, Z(AqaraAccelerometer), &Z_AqaraVibration }, + { Zuint16, Cx0101, 0x0055, Z(AqaraVibrationMode), 0, Z_AqaraVibration }, + { Zuint16, Cx0101, 0x0503, Z(AqaraVibrationsOrAngle), 1, Z_Nop }, + { Zuint32, Cx0101, 0x0505, Z(AqaraVibration505), 1, Z_Nop }, + { Zuint48, Cx0101, 0x0508, Z(AqaraAccelerometer), 0, Z_AqaraVibration }, // Window Covering cluster - { Zenum8, Cx0102, 0x0000, Z(WindowCoveringType), &Z_Copy }, - { Zuint16, Cx0102, 0x0001, Z(PhysicalClosedLimitLift),&Z_Copy }, - { Zuint16, Cx0102, 0x0002, Z(PhysicalClosedLimitTilt),&Z_Copy }, - { Zuint16, Cx0102, 0x0003, Z(CurrentPositionLift), &Z_Copy }, - { Zuint16, Cx0102, 0x0004, Z(CurrentPositionTilt), &Z_Copy }, - { Zuint16, Cx0102, 0x0005, Z(NumberofActuationsLift),&Z_Copy }, - { Zuint16, Cx0102, 0x0006, Z(NumberofActuationsTilt),&Z_Copy }, - { Zmap8, Cx0102, 0x0007, Z(ConfigStatus), &Z_Copy }, - { Zuint8, Cx0102, 0x0008, Z(CurrentPositionLiftPercentage),&Z_Copy }, - { Zuint8, Cx0102, 0x0009, Z(CurrentPositionTiltPercentage),&Z_Copy }, - { Zuint16, Cx0102, 0x0010, Z(InstalledOpenLimitLift),&Z_Copy }, - { Zuint16, Cx0102, 0x0011, Z(InstalledClosedLimitLift),&Z_Copy }, - { Zuint16, Cx0102, 0x0012, Z(InstalledOpenLimitTilt),&Z_Copy }, - { Zuint16, Cx0102, 0x0013, Z(InstalledClosedLimitTilt),&Z_Copy }, - { Zuint16, Cx0102, 0x0014, Z(VelocityLift), &Z_Copy }, - { Zuint16, Cx0102, 0x0015, Z(AccelerationTimeLift),&Z_Copy }, - { Zuint16, Cx0102, 0x0016, Z(DecelerationTimeLift), &Z_Copy }, - { Zmap8, Cx0102, 0x0017, Z(Mode), &Z_Copy }, - { Zoctstr, Cx0102, 0x0018, Z(IntermediateSetpointsLift),&Z_Copy }, - { Zoctstr, Cx0102, 0x0019, Z(IntermediateSetpointsTilt),&Z_Copy }, + { Zenum8, Cx0102, 0x0000, Z(WindowCoveringType), 1, Z_Nop }, + { Zuint16, Cx0102, 0x0001, Z(PhysicalClosedLimitLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0002, Z(PhysicalClosedLimitTilt),1, Z_Nop }, + { Zuint16, Cx0102, 0x0003, Z(CurrentPositionLift), 1, Z_Nop }, + { Zuint16, Cx0102, 0x0004, Z(CurrentPositionTilt), 1, Z_Nop }, + { Zuint16, Cx0102, 0x0005, Z(NumberofActuationsLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0006, Z(NumberofActuationsTilt),1, Z_Nop }, + { Zmap8, Cx0102, 0x0007, Z(ConfigStatus), 1, Z_Nop }, + { Zuint8, Cx0102, 0x0008, Z(CurrentPositionLiftPercentage),1, Z_Nop }, + { Zuint8, Cx0102, 0x0009, Z(CurrentPositionTiltPercentage),1, Z_Nop }, + { Zuint16, Cx0102, 0x0010, Z(InstalledOpenLimitLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0011, Z(InstalledClosedLimitLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0012, Z(InstalledOpenLimitTilt),1, Z_Nop }, + { Zuint16, Cx0102, 0x0013, Z(InstalledClosedLimitTilt),1, Z_Nop }, + { Zuint16, Cx0102, 0x0014, Z(VelocityLift), 1, Z_Nop }, + { Zuint16, Cx0102, 0x0015, Z(AccelerationTimeLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0016, Z(DecelerationTimeLift), 1, Z_Nop }, + { Zmap8, Cx0102, 0x0017, Z(Mode), 1, Z_Nop }, + { Zoctstr, Cx0102, 0x0018, Z(IntermediateSetpointsLift),1, Z_Nop }, + { Zoctstr, Cx0102, 0x0019, Z(IntermediateSetpointsTilt),1, Z_Nop }, // Color Control cluster - { Zuint8, Cx0300, 0x0000, Z(Hue), &Z_Copy }, - { Zuint8, Cx0300, 0x0001, Z(Sat), &Z_Copy }, - { Zuint16, Cx0300, 0x0002, Z(RemainingTime), &Z_Copy }, - { Zuint16, Cx0300, 0x0003, Z(X), &Z_Copy }, - { Zuint16, Cx0300, 0x0004, Z(Y), &Z_Copy }, - { Zenum8, Cx0300, 0x0005, Z(DriftCompensation), &Z_Copy }, - { Zstring, Cx0300, 0x0006, Z(CompensationText), &Z_Copy }, - { Zuint16, Cx0300, 0x0007, Z(CT), &Z_Copy }, - { Zenum8, Cx0300, 0x0008, Z(ColorMode), &Z_Copy }, - { Zuint8, Cx0300, 0x0010, Z(NumberOfPrimaries), &Z_Copy }, - { Zuint16, Cx0300, 0x0011, Z(Primary1X), &Z_Copy }, - { Zuint16, Cx0300, 0x0012, Z(Primary1Y), &Z_Copy }, - { Zuint8, Cx0300, 0x0013, Z(Primary1Intensity), &Z_Copy }, - { Zuint16, Cx0300, 0x0015, Z(Primary2X), &Z_Copy }, - { Zuint16, Cx0300, 0x0016, Z(Primary2Y), &Z_Copy }, - { Zuint8, Cx0300, 0x0017, Z(Primary2Intensity), &Z_Copy }, - { Zuint16, Cx0300, 0x0019, Z(Primary3X), &Z_Copy }, - { Zuint16, Cx0300, 0x001A, Z(Primary3Y), &Z_Copy }, - { Zuint8, Cx0300, 0x001B, Z(Primary3Intensity), &Z_Copy }, - { Zuint16, Cx0300, 0x0030, Z(WhitePointX), &Z_Copy }, - { Zuint16, Cx0300, 0x0031, Z(WhitePointY), &Z_Copy }, - { Zuint16, Cx0300, 0x0032, Z(ColorPointRX), &Z_Copy }, - { Zuint16, Cx0300, 0x0033, Z(ColorPointRY), &Z_Copy }, - { Zuint8, Cx0300, 0x0034, Z(ColorPointRIntensity), &Z_Copy }, - { Zuint16, Cx0300, 0x0036, Z(ColorPointGX), &Z_Copy }, - { Zuint16, Cx0300, 0x0037, Z(ColorPointGY), &Z_Copy }, - { Zuint8, Cx0300, 0x0038, Z(ColorPointGIntensity), &Z_Copy }, - { Zuint16, Cx0300, 0x003A, Z(ColorPointBX), &Z_Copy }, - { Zuint16, Cx0300, 0x003B, Z(ColorPointBY), &Z_Copy }, - { Zuint8, Cx0300, 0x003C, Z(ColorPointBIntensity), &Z_Copy }, + { Zuint8, Cx0300, 0x0000, Z(Hue), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0001, Z(Sat), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0002, Z(RemainingTime), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0003, Z(X), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0004, Z(Y), 1, Z_Nop }, + { Zenum8, Cx0300, 0x0005, Z(DriftCompensation), 1, Z_Nop }, + { Zstring, Cx0300, 0x0006, Z(CompensationText), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0007, Z(CT), 1, Z_Nop }, + { Zenum8, Cx0300, 0x0008, Z(ColorMode), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0010, Z(NumberOfPrimaries), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0011, Z(Primary1X), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0012, Z(Primary1Y), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0013, Z(Primary1Intensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0015, Z(Primary2X), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0016, Z(Primary2Y), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0017, Z(Primary2Intensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0019, Z(Primary3X), 1, Z_Nop }, + { Zuint16, Cx0300, 0x001A, Z(Primary3Y), 1, Z_Nop }, + { Zuint8, Cx0300, 0x001B, Z(Primary3Intensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0030, Z(WhitePointX), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0031, Z(WhitePointY), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0032, Z(ColorPointRX), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0033, Z(ColorPointRY), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0034, Z(ColorPointRIntensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0036, Z(ColorPointGX), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0037, Z(ColorPointGY), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0038, Z(ColorPointGIntensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x003A, Z(ColorPointBX), 1, Z_Nop }, + { Zuint16, Cx0300, 0x003B, Z(ColorPointBY), 1, Z_Nop }, + { Zuint8, Cx0300, 0x003C, Z(ColorPointBIntensity), 1, Z_Nop }, // Illuminance Measurement cluster - { Zuint16, Cx0400, 0x0000, Z(Illuminance), &Z_Copy }, // Illuminance (in Lux) - { Zuint16, Cx0400, 0x0001, Z(IlluminanceMinMeasuredValue), &Z_Copy }, // - { Zuint16, Cx0400, 0x0002, Z(IlluminanceMaxMeasuredValue), &Z_Copy }, // - { Zuint16, Cx0400, 0x0003, Z(IlluminanceTolerance), &Z_Copy }, // - { Zenum8, Cx0400, 0x0004, Z(IlluminanceLightSensorType), &Z_Copy }, // - { Zunk, Cx0400, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint16, Cx0400, 0x0000, Z(Illuminance), 1, Z_Nop }, // Illuminance (in Lux) + { Zuint16, Cx0400, 0x0001, Z(IlluminanceMinMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0400, 0x0002, Z(IlluminanceMaxMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0400, 0x0003, Z(IlluminanceTolerance), 1, Z_Nop }, // + { Zenum8, Cx0400, 0x0004, Z(IlluminanceLightSensorType), 1, Z_Nop }, // + { Zunk, Cx0400, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Illuminance Level Sensing cluster - { Zenum8, Cx0401, 0x0000, Z(IlluminanceLevelStatus), &Z_Copy }, // Illuminance (in Lux) - { Zenum8, Cx0401, 0x0001, Z(IlluminanceLightSensorType), &Z_Copy }, // LightSensorType - { Zuint16, Cx0401, 0x0010, Z(IlluminanceTargetLevel), &Z_Copy }, // - { Zunk, Cx0401, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zenum8, Cx0401, 0x0000, Z(IlluminanceLevelStatus), 1, Z_Nop }, // Illuminance (in Lux) + { Zenum8, Cx0401, 0x0001, Z(IlluminanceLightSensorType), 1, Z_Nop }, // LightSensorType + { Zuint16, Cx0401, 0x0010, Z(IlluminanceTargetLevel), 1, Z_Nop }, // + { Zunk, Cx0401, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Temperature Measurement cluster - { Zint16, Cx0402, 0x0000, Z(Temperature), &Z_FloatDiv100 }, // Temperature - { Zint16, Cx0402, 0x0001, Z(TemperatureMinMeasuredValue), &Z_FloatDiv100 }, // - { Zint16, Cx0402, 0x0002, Z(TemperatureMaxMeasuredValue), &Z_FloatDiv100 }, // - { Zuint16, Cx0402, 0x0003, Z(TemperatureTolerance), &Z_FloatDiv100 }, // - { Zunk, Cx0402, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zint16, Cx0402, 0x0000, Z(Temperature), -100, Z_Nop }, // divide by 100 + { Zint16, Cx0402, 0x0001, Z(TemperatureMinMeasuredValue), -100, Z_Nop }, // + { Zint16, Cx0402, 0x0002, Z(TemperatureMaxMeasuredValue), -100, Z_Nop }, // + { Zuint16, Cx0402, 0x0003, Z(TemperatureTolerance), -100, Z_Nop }, // + { Zunk, Cx0402, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Pressure Measurement cluster - { Zunk, Cx0403, 0x0000, Z(PressureUnit), &Z_AddPressureUnit }, // Pressure Unit - { Zint16, Cx0403, 0x0000, Z(Pressure), &Z_Copy }, // Pressure - { Zint16, Cx0403, 0x0001, Z(PressureMinMeasuredValue), &Z_Copy }, // - { Zint16, Cx0403, 0x0002, Z(PressureMaxMeasuredValue), &Z_Copy }, // - { Zuint16, Cx0403, 0x0003, Z(PressureTolerance), &Z_Copy }, // - { Zint16, Cx0403, 0x0010, Z(PressureScaledValue), &Z_Copy }, // - { Zint16, Cx0403, 0x0011, Z(PressureMinScaledValue), &Z_Copy }, // - { Zint16, Cx0403, 0x0012, Z(PressureMaxScaledValue), &Z_Copy }, // - { Zuint16, Cx0403, 0x0013, Z(PressureScaledTolerance), &Z_Copy }, // - { Zint8, Cx0403, 0x0014, Z(PressureScale), &Z_Copy }, // - { Zunk, Cx0403, 0xFFFF, nullptr, &Z_Remove }, // Remove all other Pressure values + { Zunk, Cx0403, 0x0000, Z(PressureUnit), 0, Z_AddPressureUnit }, // Pressure Unit + { Zint16, Cx0403, 0x0000, Z(Pressure), 1, Z_Nop }, // Pressure + { Zint16, Cx0403, 0x0001, Z(PressureMinMeasuredValue), 1, Z_Nop }, // + { Zint16, Cx0403, 0x0002, Z(PressureMaxMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0403, 0x0003, Z(PressureTolerance), 1, Z_Nop }, // + { Zint16, Cx0403, 0x0010, Z(PressureScaledValue), 1, Z_Nop }, // + { Zint16, Cx0403, 0x0011, Z(PressureMinScaledValue), 1, Z_Nop }, // + { Zint16, Cx0403, 0x0012, Z(PressureMaxScaledValue), 1, Z_Nop }, // + { Zuint16, Cx0403, 0x0013, Z(PressureScaledTolerance), 1, Z_Nop }, // + { Zint8, Cx0403, 0x0014, Z(PressureScale), 1, Z_Nop }, // + { Zunk, Cx0403, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other Pressure values // Flow Measurement cluster - { Zuint16, Cx0404, 0x0000, Z(FlowRate), &Z_FloatDiv10 }, // Flow (in m3/h) - { Zuint16, Cx0404, 0x0001, Z(FlowMinMeasuredValue), &Z_Copy }, // - { Zuint16, Cx0404, 0x0002, Z(FlowMaxMeasuredValue), &Z_Copy }, // - { Zuint16, Cx0404, 0x0003, Z(FlowTolerance), &Z_Copy }, // - { Zunk, Cx0404, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint16, Cx0404, 0x0000, Z(FlowRate), -10, Z_Nop }, // Flow (in m3/h) + { Zuint16, Cx0404, 0x0001, Z(FlowMinMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0404, 0x0002, Z(FlowMaxMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0404, 0x0003, Z(FlowTolerance), 1, Z_Nop }, // + { Zunk, Cx0404, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Relative Humidity Measurement cluster - { Zuint16, Cx0405, 0x0000, Z(Humidity), &Z_FloatDiv100 }, // Humidity - { Zuint16, Cx0405, 0x0001, Z(HumidityMinMeasuredValue), &Z_Copy }, // - { Zuint16, Cx0405, 0x0002, Z(HumidityMaxMeasuredValue), &Z_Copy }, // - { Zuint16, Cx0405, 0x0003, Z(HumidityTolerance), &Z_Copy }, // - { Zunk, Cx0405, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint16, Cx0405, 0x0000, Z(Humidity), -100, Z_Nop }, // Humidity + { Zuint16, Cx0405, 0x0001, Z(HumidityMinMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0405, 0x0002, Z(HumidityMaxMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0405, 0x0003, Z(HumidityTolerance), 1, Z_Nop }, // + { Zunk, Cx0405, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Occupancy Sensing cluster - { Zmap8, Cx0406, 0x0000, Z(Occupancy), &Z_Copy }, // Occupancy (map8) - { Zenum8, Cx0406, 0x0001, Z(OccupancySensorType), &Z_Copy }, // OccupancySensorType - { Zunk, Cx0406, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zmap8, Cx0406, 0x0000, Z(Occupancy), 1, Z_Nop }, // Occupancy (map8) + { Zenum8, Cx0406, 0x0001, Z(OccupancySensorType), 1, Z_Nop }, // OccupancySensorType + { Zunk, Cx0406, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Meter Identification cluster - { Zstring, Cx0B01, 0x0000, Z(CompanyName), &Z_Copy }, - { Zuint16, Cx0B01, 0x0001, Z(MeterTypeID), &Z_Copy }, - { Zuint16, Cx0B01, 0x0004, Z(DataQualityID), &Z_Copy }, - { Zstring, Cx0B01, 0x0005, Z(CustomerName), &Z_Copy }, - { Zoctstr, Cx0B01, 0x0006, Z(Model), &Z_Copy }, - { Zoctstr, Cx0B01, 0x0007, Z(PartNumber), &Z_Copy }, - { Zoctstr, Cx0B01, 0x0008, Z(ProductRevision), &Z_Copy }, - { Zoctstr, Cx0B01, 0x000A, Z(SoftwareRevision), &Z_Copy }, - { Zstring, Cx0B01, 0x000B, Z(UtilityName), &Z_Copy }, - { Zstring, Cx0B01, 0x000C, Z(POD), &Z_Copy }, - { Zint24, Cx0B01, 0x000D, Z(AvailablePower), &Z_Copy }, - { Zint24, Cx0B01, 0x000E, Z(PowerThreshold), &Z_Copy }, + { Zstring, Cx0B01, 0x0000, Z(CompanyName), 1, Z_Nop }, + { Zuint16, Cx0B01, 0x0001, Z(MeterTypeID), 1, Z_Nop }, + { Zuint16, Cx0B01, 0x0004, Z(DataQualityID), 1, Z_Nop }, + { Zstring, Cx0B01, 0x0005, Z(CustomerName), 1, Z_Nop }, + { Zoctstr, Cx0B01, 0x0006, Z(Model), 1, Z_Nop }, + { Zoctstr, Cx0B01, 0x0007, Z(PartNumber), 1, Z_Nop }, + { Zoctstr, Cx0B01, 0x0008, Z(ProductRevision), 1, Z_Nop }, + { Zoctstr, Cx0B01, 0x000A, Z(SoftwareRevision), 1, Z_Nop }, + { Zstring, Cx0B01, 0x000B, Z(UtilityName), 1, Z_Nop }, + { Zstring, Cx0B01, 0x000C, Z(POD), 1, Z_Nop }, + { Zint24, Cx0B01, 0x000D, Z(AvailablePower), 1, Z_Nop }, + { Zint24, Cx0B01, 0x000E, Z(PowerThreshold), 1, Z_Nop }, // Diagnostics cluster - { Zuint16, Cx0B05, 0x0000, Z(NumberOfResets), &Z_Copy }, - { Zuint16, Cx0B05, 0x0001, Z(PersistentMemoryWrites),&Z_Copy }, - { Zuint8, Cx0B05, 0x011C, Z(LastMessageLQI), &Z_Copy }, - { Zuint8, Cx0B05, 0x011D, Z(LastMessageRSSI), &Z_Copy }, + { Zuint16, Cx0B05, 0x0000, Z(NumberOfResets), 1, Z_Nop }, + { Zuint16, Cx0B05, 0x0001, Z(PersistentMemoryWrites),1, Z_Nop }, + { Zuint8, Cx0B05, 0x011C, Z(LastMessageLQI), 1, Z_Nop }, + { Zuint8, Cx0B05, 0x011D, Z(LastMessageRSSI), 1, Z_Nop }, }; @@ -650,7 +662,7 @@ public: } static void generateAttributeName(const JsonObject& json, uint16_t cluster, uint16_t attr, char *key, size_t key_len); - void parseRawAttributes(JsonObject& json, uint8_t offset = 0); + void parseReportAttributes(JsonObject& json, uint8_t offset = 0); void parseReadAttributes(JsonObject& json, uint8_t offset = 0); void parseReadAttributesResponse(JsonObject& json, uint8_t offset = 0); void parseResponse(void); @@ -734,36 +746,50 @@ uint8_t toPercentageCR2032(uint32_t voltage) { // - 1 byte: attribute type // - n bytes: value (typically between 1 and 4 bytes, or bigger for strings) // returns number of bytes of attribute, or <0 if error -int32_t encodeSingleAttribute(class SBuffer &buf, const JsonVariant &val, uint16_t attr, uint8_t attrtype) { +// status: shall we insert a status OK (0x00) as required by ReadResponse +int32_t encodeSingleAttribute(class SBuffer &buf, const JsonVariant &val, float val_f, uint16_t attr, uint8_t attrtype, bool status = false) { uint32_t len = Z_getDatatypeLen(attrtype); // pre-compute lenght, overloaded for variable length attributes + uint32_t u32; + int32_t i32; + float f32; - uint32_t u32 = val.as(); - int32_t i32 = val.as(); - float f32 = val.as(); + if (&val) { + u32 = val.as(); + i32 = val.as(); + f32 = val.as(); + } else { + u32 = val_f; + i32 = val_f; + f32 = val_f; + } buf.add16(attr); // prepend with attribute identifier + if (status) { + buf.add8(Z_SUCCESS); // status OK = 0x00 + } buf.add8(attrtype); // prepend with attribute type switch (attrtype) { // unsigned 8 - case Zbool: // bool + case Zbool: // bool case Zuint8: // uint8 case Zenum8: // enum8 case Zdata8: // data8 - case Zmap8: // map8 + case Zmap8: // map8 buf.add8(u32); break; // unsigned 16 - case Zuint16: // uint16 - case Zenum16: // enum16 - case Zdata16: // data16 + case Zuint16: // uint16 + case Zenum16: // enum16 + case Zdata16: // data16 case Zmap16: // map16 buf.add16(u32); break; // unisgned 32 - case Zuint32: // uint32 - case Zdata32: // data32 + case Zuint32: // uint32 + case Zdata32: // data32 case Zmap32: // map32 + case ZUTC: // UTC - epoch 32 bits, seconds since 1-Jan-2000 buf.add32(u32); break; @@ -786,7 +812,7 @@ int32_t encodeSingleAttribute(class SBuffer &buf, const JsonVariant &val, uint16 case Zstring: case Zstring16: { - const char * val_str = val.as(); + const char * val_str = (&val) ? val.as() : ""; // avoid crash if &val is null if (nullptr == val_str) { return -2; } size_t val_len = strlen(val_str); if (val_len > 32) { val_len = 32; } @@ -804,10 +830,10 @@ int32_t encodeSingleAttribute(class SBuffer &buf, const JsonVariant &val, uint16 default: // remove the attribute type we just added - buf.setLen(buf.len() - 3); + buf.setLen(buf.len() - (status ? 4 : 3)); return -1; } - return len + 3; + return len + (status ? 4 : 3); } uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer &buf, @@ -848,6 +874,7 @@ uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer } break; case Zuint32: // uint32 + case ZUTC: // UTC { uint32_t uint32_val = buf.get32(i); // i += 4; @@ -974,7 +1001,6 @@ uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer // TODO case ZToD: // ToD case Zdate: // date - case ZUTC: // UTC case ZclusterId: // clusterId case ZattribId: // attribId case ZbacOID: // bacOID @@ -1028,7 +1054,7 @@ void ZCLFrame::generateAttributeName(const JsonObject& json, uint16_t cluster, u } // First pass, parse all attributes in their native format -void ZCLFrame::parseRawAttributes(JsonObject& json, uint8_t offset) { +void ZCLFrame::parseReportAttributes(JsonObject& json, uint8_t offset) { uint32_t i = offset; uint32_t len = _payload.len(); @@ -1083,7 +1109,7 @@ void ZCLFrame::parseReadAttributesResponse(JsonObject& json, uint8_t offset) { uint32_t i = offset; uint32_t len = _payload.len(); - while (len >= 4 + i) { + while (len >= i + 4) { uint16_t attrid = _payload.get16(i); i += 2; uint8_t status = _payload.get8(i++); @@ -1148,48 +1174,36 @@ void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) { // ====================================================================== // Record Manuf -int32_t Z_ManufKeep(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_ManufKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { json[new_name] = value; zigbee_devices.setManufId(shortaddr, value.as()); return 1; } // -int32_t Z_ModelKeep(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_ModelKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { json[new_name] = value; zigbee_devices.setModelId(shortaddr, value.as()); return 1; } -// ====================================================================== -// Remove attribute -int32_t Z_Remove(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - return 1; // remove original key -} - -// Copy value as-is -int32_t Z_Copy(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = value; - return 1; // remove original key -} - // Add pressure unit -int32_t Z_AddPressureUnit(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_AddPressureUnitFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { json[new_name] = F(D_UNIT_PRESSURE); return 0; // keep original key } // Convert int to float and divide by 100 -int32_t Z_FloatDiv100(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_FloatDiv100Func(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { json[new_name] = ((float)value) / 100.0f; return 1; // remove original key } // Convert int to float and divide by 10 -int32_t Z_FloatDiv10(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_FloatDiv10Func(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { json[new_name] = ((float)value) / 10.0f; return 1; // remove original key } // Convert int to float and divide by 10 -int32_t Z_FloatDiv2(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_FloatDiv2Func(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { json[new_name] = ((float)value) / 2.0f; return 1; // remove original key } @@ -1203,7 +1217,7 @@ int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu } // Aqara Cube -int32_t Z_AqaraCube(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_AqaraCubeFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { json[new_name] = value; // copy the original value int32_t val = value; const __FlashStringHelper *aqara_cube = F("AqaraCube"); @@ -1262,7 +1276,7 @@ int32_t Z_AqaraCube(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& j } // Aqara Vibration Sensor - special proprietary attributes -int32_t Z_AqaraVibration(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_AqaraVibrationFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { //json[new_name] = value; switch (attr) { case 0x0055: @@ -1313,7 +1327,7 @@ int32_t Z_AqaraVibration(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObje return 1; // remove original key } -int32_t Z_AqaraSensor(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_AqaraSensorFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { String hex = value; SBuffer buf2 = SBuffer::SBufferFromHex(hex.c_str(), hex.length()); uint32_t i = 0; @@ -1373,6 +1387,50 @@ int32_t Z_AqaraSensor(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& } // ====================================================================== +// apply the transformation from the converter +int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, + uint16_t cluster, uint16_t attr, int16_t multiplier, uint16_t cb) { + // apply multiplier if needed + if (1 == multiplier) { // copy unchanged + json[new_name] = value; + } else if (0 != multiplier) { + if (multiplier > 0) { + json[new_name] = ((float)value) * multiplier; + } else { + json[new_name] = ((float)value) / multiplier; + } + } + + // apply callback if needed + Z_AttrConverter func = nullptr; + switch (cb) { + case Z_Nop: + return 1; // drop original key + case Z_AddPressureUnit: + func = &Z_AddPressureUnitFunc; + break; + case Z_ManufKeep: + func = &Z_ManufKeepFunc; + break; + case Z_ModelKeep: + func = &Z_ModelKeepFunc; + break; + case Z_AqaraSensor: + func = &Z_AqaraSensorFunc; + break; + case Z_AqaraVibration: + func = &Z_AqaraVibrationFunc; + break; + case Z_AqaraCube: + func = &Z_AqaraCubeFunc; + break; + }; + + if (func) { + return (*func)(zcl, shortaddr, json, name, value, new_name, cluster, attr); + } +} + void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) { // iterate on json elements for (auto kv : json) { @@ -1434,12 +1492,15 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); uint16_t conv_attribute = pgm_read_word(&converter->attribute); + int16_t conv_multiplier = pgm_read_word(&converter->multiplier); + uint16_t conv_cb = pgm_read_word(&converter->cb); // callback id if ((conv_cluster == cluster) && ((conv_attribute == attribute) || (conv_attribute == 0xFFFF)) ) { String new_name_str = (const __FlashStringHelper*) converter->name; if (suffix > 1) { new_name_str += suffix; } // append suffix number - int32_t drop = (*converter->func)(this, shortaddr, json, key, value, new_name_str, conv_cluster, conv_attribute); + // apply the transformation + int32_t drop = Z_ApplyConverter(this, shortaddr, json, key, value, new_name_str, conv_cluster, conv_attribute, conv_multiplier, conv_cb); if (drop) { json.remove(key); } diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 0b1144eb5..996103fe5 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -657,21 +657,24 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { } else { // Build the ZbReceive json if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_REPORT_ATTRIBUTES == zcl_received.getCmdId())) { - zcl_received.parseRawAttributes(json); // Zigbee report attributes from sensors + zcl_received.parseReportAttributes(json); // Zigbee report attributes from sensors if (clusterid) { defer_attributes = true; } // don't defer system Cluster=0 messages } else if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_READ_ATTRIBUTES_RESPONSE == zcl_received.getCmdId())) { zcl_received.parseReadAttributesResponse(json); if (clusterid) { defer_attributes = true; } // don't defer system Cluster=0 messages } else if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_READ_ATTRIBUTES == zcl_received.getCmdId())) { zcl_received.parseReadAttributes(json); - if (clusterid) { defer_attributes = true; } // don't defer system Cluster=0 messages + // never defer read_attributes, so the auto-responder can send response back on a per cluster basis } else if (zcl_received.isClusterSpecificCommand()) { zcl_received.parseClusterSpecificCommand(json); } - String msg(""); - msg.reserve(100); - json.printTo(msg); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZCL_RAW_RECEIVED ": {\"0x%04X\":%s}"), srcaddr, msg.c_str()); + + { // fence to force early de-allocation of msg + String msg(""); + msg.reserve(100); + json.printTo(msg); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZCL_RAW_RECEIVED ": {\"0x%04X\":%s}"), srcaddr, msg.c_str()); + } zcl_received.postProcessAttributes(srcaddr, json); // Add Endpoint @@ -701,6 +704,9 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { } else { // Publish immediately zigbee_devices.jsonPublishNow(srcaddr, json); + + // Add auto-responder here + Z_AutoResponder(srcaddr, clusterid, srcendpoint, json[F("ReadNames")]); } } return -1; @@ -817,4 +823,74 @@ int32_t Z_State_Ready(uint8_t value) { return 0; // continue } +// +// Auto-responder for Read request from extenal devices. +// +// Mostly used for routers/end-devices +// json: holds the attributes in JSON format +void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const JsonObject &json) { + DynamicJsonBuffer jsonBuffer; + JsonObject& json_out = jsonBuffer.createObject(); + + // responder + switch (cluster) { + case 0x0000: + if (HasKeyCaseInsensitive(json, PSTR("ModelId"))) { json_out[F("ModelId")] = F("Tasmota Z2T"); } + if (HasKeyCaseInsensitive(json, PSTR("Manufacturer"))) { json_out[F("Manufacturer")] = F("Tasmota"); } + break; +#ifdef USE_LIGHT + case 0x0006: + if (HasKeyCaseInsensitive(json, PSTR("Power"))) { json_out[F("Power")] = Light.power ? 1 : 0; } + break; + case 0x0008: + if (HasKeyCaseInsensitive(json, PSTR("Dimmer"))) { json_out[F("Dimmer")] = LightGetDimmer(0); } + break; + case 0x0300: + { + uint16_t hue; + uint8_t sat; + float XY[2]; + LightGetHSB(&hue, &sat, nullptr); + LightGetXY(&XY[0], &XY[1]); + uint16_t uxy[2]; + for (uint32_t i = 0; i < ARRAY_SIZE(XY); i++) { + uxy[i] = XY[i] * 65536.0f; + uxy[i] = (uxy[i] > 0xFEFF) ? uxy[i] : 0xFEFF; + } + if (HasKeyCaseInsensitive(json, PSTR("Hue"))) { json_out[F("Hue")] = changeUIntScale(hue, 0, 360, 0, 254); } + if (HasKeyCaseInsensitive(json, PSTR("Sat"))) { json_out[F("Sat")] = changeUIntScale(sat, 0, 255, 0, 254); } + if (HasKeyCaseInsensitive(json, PSTR("CT"))) { json_out[F("CT")] = LightGetColorTemp(); } + if (HasKeyCaseInsensitive(json, PSTR("X"))) { json_out[F("X")] = uxy[0]; } + if (HasKeyCaseInsensitive(json, PSTR("Y"))) { json_out[F("Y")] = uxy[1]; } + } + break; +#endif + case 0x000A: // Time + if (HasKeyCaseInsensitive(json, PSTR("Time"))) { json_out[F("Time")] = Rtc.utc_time; } + if (HasKeyCaseInsensitive(json, PSTR("TimeStatus"))) { json_out[F("TimeStatus")] = (Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? 0x02 : 0x00; } // if time is beyond 2010 then we are synchronized + if (HasKeyCaseInsensitive(json, PSTR("TimeZone"))) { json_out[F("TimeZone")] = Settings.toffset[0] * 60; } // seconds + break; + } + + if (json_out.size() > 0) { + // we have a non-empty output + + // log first + String msg(""); + msg.reserve(100); + json_out.printTo(msg); + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: Auto-responder: ZbSend {\"Device\":\"0x%04X\"" + ",\"Cluster\":\"0x%04X\"" + ",\"Endpoint\":%d" + ",\"Response\":%s}" + ), + srcaddr, cluster, endpoint, + msg.c_str()); + + // send + const JsonVariant &json_out_v = json_out; + ZbSendReportWrite(json_out_v, srcaddr, 0 /* group */,cluster, endpoint, 0 /* manuf */, ZCL_READ_ATTRIBUTES_RESPONSE); + } +} + #endif // USE_ZIGBEE diff --git a/tasmota/xdrv_23_zigbee_9_impl.ino b/tasmota/xdrv_23_zigbee_9_impl.ino index 38627f91f..0ea39c194 100644 --- a/tasmota/xdrv_23_zigbee_9_impl.ino +++ b/tasmota/xdrv_23_zigbee_9_impl.ino @@ -393,19 +393,25 @@ void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint, } } -// Parse "Report" or "Write" attribute -void ZbSendReportWrite(const JsonVariant &val_pubwrite, uint16_t device, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint16_t manuf, bool write) { +// Parse "Report", "Write" or "Response" attribute +// Operation is one of: ZCL_REPORT_ATTRIBUTES (0x0A), ZCL_WRITE_ATTRIBUTES (0x02) or ZCL_READ_ATTRIBUTES_RESPONSE (0x01) +void ZbSendReportWrite(const JsonObject &val_pubwrite, uint16_t device, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint16_t manuf, uint32_t operation) { SBuffer buf(200); // buffer to store the binary output of attibutes - const JsonObject &attrs = val_pubwrite.as(); + if (nullptr == XdrvMailbox.command) { + XdrvMailbox.command = (char*) ""; // prevent a crash when calling ReponseCmndChar and there was no previous command + } + // iterate on keys - for (JsonObject::const_iterator it=attrs.begin(); it!=attrs.end(); ++it) { + for (JsonObject::const_iterator it=val_pubwrite.begin(); it!=val_pubwrite.end(); ++it) { const char *key = it->key; const JsonVariant &value = it->value; uint16_t attr_id = 0xFFFF; uint16_t cluster_id = 0xFFFF; uint8_t type_id = Znodata; + int16_t multiplier = 1; // multiplier to adjust the key value + float val_f = 0.0f; // alternative value if multiplier is used // check if the name has the format "XXXX/YYYY" where XXXX is the cluster, YYYY the attribute id // alternative "XXXX/YYYY%ZZ" where ZZ is the type (for unregistered attributes) @@ -431,6 +437,7 @@ void ZbSendReportWrite(const JsonVariant &val_pubwrite, uint16_t device, uint16_ uint16_t local_attr_id = pgm_read_word(&converter->attribute); uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short)); uint8_t local_type_id = pgm_read_byte(&converter->type); + int16_t local_multiplier = pgm_read_word(&converter->multiplier); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Try cluster = 0x%04X, attr = 0x%04X, type_id = 0x%02X"), local_cluster_id, local_attr_id, local_type_id); if (delimiter) { @@ -445,12 +452,14 @@ void ZbSendReportWrite(const JsonVariant &val_pubwrite, uint16_t device, uint16_ cluster_id = local_cluster_id; attr_id = local_attr_id; type_id = local_type_id; + multiplier = local_multiplier; break; } } } } + // Buffer ready, do some sanity checks // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("cluster_id = 0x%04X, attr_id = 0x%04X, type_id = 0x%02X"), cluster_id, attr_id, type_id); if ((0xFFFF == attr_id) || (0xFFFF == cluster_id)) { Response_P(PSTR("{\"%s\":\"%s'%s'\"}"), XdrvMailbox.command, PSTR("Unknown attribute "), key); @@ -467,8 +476,19 @@ void ZbSendReportWrite(const JsonVariant &val_pubwrite, uint16_t device, uint16_ ResponseCmndChar_P(PSTR("No more than one cluster id per command")); return; } + // apply multiplier if needed + bool use_val = true; + if ((0 != multiplier) && (1 != multiplier)) { + val_f = value; + if (multiplier > 0) { // inverse of decoding + val_f = val_f / multiplier; + } else { + val_f = val_f * multiplier; + } + use_val = false; + } // push the value in the buffer - int32_t res = encodeSingleAttribute(buf, value, attr_id, type_id); + int32_t res = encodeSingleAttribute(buf, use_val ? value : *(const JsonVariant*)nullptr, val_f, attr_id, type_id, operation == ZCL_READ_ATTRIBUTES_RESPONSE); // force status if Reponse if (res < 0) { Response_P(PSTR("{\"%s\":\"%s'%s' 0x%02X\"}"), XdrvMailbox.command, PSTR("Unsupported attribute type "), key, type_id); return; @@ -482,7 +502,7 @@ void ZbSendReportWrite(const JsonVariant &val_pubwrite, uint16_t device, uint16_ } // all good, send the packet - ZigbeeZCLSend_Raw(device, groupaddr, cluster, endpoint, write ? ZCL_WRITE_ATTRIBUTES : ZCL_REPORT_ATTRIBUTES, false /* not cluster specific */, manuf, buf.getBuffer(), buf.len(), false /* noresponse */, zigbee_devices.getNextSeqNumber(device)); + ZigbeeZCLSend_Raw(device, groupaddr, cluster, endpoint, operation, false /* not cluster specific */, manuf, buf.getBuffer(), buf.len(), false /* noresponse */, zigbee_devices.getNextSeqNumber(device)); ResponseCmndDone(); } @@ -511,14 +531,22 @@ void ZbSendSend(const JsonVariant &val_cmd, uint16_t device, uint16_t groupaddr, const JsonVariant& value = it->value; uint32_t x = 0, y = 0, z = 0; uint16_t cmd_var; + uint16_t local_cluster_id; - const __FlashStringHelper* tasmota_cmd = zigbeeFindCommand(key.c_str(), &cluster, &cmd_var); + const __FlashStringHelper* tasmota_cmd = zigbeeFindCommand(key.c_str(), &local_cluster_id, &cmd_var); if (tasmota_cmd) { cmd_str = tasmota_cmd; } else { Response_P(PSTR("Unrecognized zigbee command: %s"), key.c_str()); return; } + // check cluster + if (0xFFFF == cluster) { + cluster = local_cluster_id; + } else if (cluster != local_cluster_id) { + ResponseCmndChar_P(PSTR("No more than one cluster id per command")); + return; + } // parse the JSON value, depending on its type fill in x,y,z if (value.is()) { @@ -570,7 +598,15 @@ void ZbSendSend(const JsonVariant &val_cmd, uint16_t device, uint16_t groupaddr, // where AA is the cluster number, BBBB the command number, CCCC... the payload // First delimiter is '_' for a global command, or '!' for a cluster specific command const char * data = cmd_str.c_str(); - cluster = parseHex(&data, 4); + uint16_t local_cluster_id = parseHex(&data, 4); + + // check cluster + if (0xFFFF == cluster) { + cluster = local_cluster_id; + } else if (cluster != local_cluster_id) { + ResponseCmndChar_P(PSTR("No more than one cluster id per command")); + return; + } // delimiter if (('_' == *data) || ('!' == *data)) { @@ -650,6 +686,14 @@ void ZbSendRead(const JsonVariant &val_attr, uint16_t device, uint16_t groupaddr attrs[actual_attr_len++] = local_attr_id & 0xFF; attrs[actual_attr_len++] = local_attr_id >> 8; found = true; + // check cluster + if (0xFFFF == cluster) { + cluster = local_cluster_id; + } else if (cluster != local_cluster_id) { + ResponseCmndChar_P(PSTR("No more than one cluster id per command")); + if (attrs) { delete[] attrs; } + return; + } break; // found, exit loop } } @@ -728,6 +772,8 @@ void CmndZbSend(void) { return; } } + // from here, either device has a device shortaddr, or if BAD_SHORTADDR then use group address + // Note: groupaddr == 0 is valid // read other parameters const JsonVariant &val_cluster = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_CLUSTER)); @@ -739,44 +785,64 @@ void CmndZbSend(void) { // infer endpoint if (BAD_SHORTADDR == device) { - endpoint = 0xFF; // endpoint not used for group addresses - } else if (0 == endpoint) { + endpoint = 0xFF; // endpoint not used for group addresses, so use a dummy broadcast endpoint + } else if (0 == endpoint) { // if it was not already specified, try to guess it endpoint = zigbee_devices.findFirstEndpoint(device); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: guessing endpoint %d"), endpoint); } + if (0 == endpoint) { // after this, if it is still zero, then it's an error + ResponseCmndChar_P(PSTR("Missing endpoint")); + return; + } + // from here endpoint is valid and non-zero + // cluster may be already specified or 0xFFFF const JsonVariant &val_cmd = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_SEND)); const JsonVariant &val_read = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_READ)); const JsonVariant &val_write = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_WRITE)); const JsonVariant &val_publish = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_REPORT)); - uint32_t multi_cmd = (nullptr != &val_cmd) + (nullptr != &val_read) + (nullptr != &val_write) + (nullptr != &val_publish); + const JsonVariant &val_response = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_RESPONSE)); + uint32_t multi_cmd = (nullptr != &val_cmd) + (nullptr != &val_read) + (nullptr != &val_write) + (nullptr != &val_publish)+ (nullptr != &val_response); if (multi_cmd > 1) { - ResponseCmndChar_P(PSTR("Can only have one of: 'Send', 'Read', 'Write' or 'Report'")); + ResponseCmndChar_P(PSTR("Can only have one of: 'Send', 'Read', 'Write', 'Report' or 'Reponse'")); return; } + // from here we have one and only one command if (nullptr != &val_cmd) { // "Send":{...commands...} + // we accept either a string or a JSON object ZbSendSend(val_cmd, device, groupaddr, cluster, endpoint, manuf); } else if (nullptr != &val_read) { // "Read":{...attributes...}, "Read":attribute or "Read":[...attributes...] + // we accept eitehr a number, a string, an array of numbers/strings, or a JSON object ZbSendRead(val_read, device, groupaddr, cluster, endpoint, manuf); } else if (nullptr != &val_write) { - if ((0 == endpoint) || (!val_write.is())) { + // only KSON object + if (!val_write.is()) { ResponseCmndChar_P(PSTR("Missing parameters")); return; } // "Write":{...attributes...} - ZbSendReportWrite(val_write, device, groupaddr, cluster, endpoint, manuf, true /* write */); + ZbSendReportWrite(val_write, device, groupaddr, cluster, endpoint, manuf, ZCL_WRITE_ATTRIBUTES); } else if (nullptr != &val_publish) { - if ((0 == endpoint) || (!val_publish.is())) { + // "Report":{...attributes...} + // only KSON object + if (!val_publish.is()) { ResponseCmndChar_P(PSTR("Missing parameters")); return; } + ZbSendReportWrite(val_publish, device, groupaddr, cluster, endpoint, manuf, ZCL_REPORT_ATTRIBUTES); + } else if (nullptr != &val_response) { // "Report":{...attributes...} - ZbSendReportWrite(val_publish, device, groupaddr, cluster, endpoint, manuf, false /* report */); + // only KSON object + if (!val_response.is()) { + ResponseCmndChar_P(PSTR("Missing parameters")); + return; + } + ZbSendReportWrite(val_response, device, groupaddr, cluster, endpoint, manuf, ZCL_READ_ATTRIBUTES_RESPONSE); } else { - Response_P(PSTR("Missing zigbee 'Send', 'Write' or 'Report'")); + Response_P(PSTR("Missing zigbee 'Send', 'Write', 'Report' or 'Response'")); return; } } From 5558da527abf2a3b0cb5c06d0593981c934f177c Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 3 Jun 2020 16:09:28 +1000 Subject: [PATCH 153/581] Add MAX6675 sensor This is basically a cut down version of MAX31855 without reference temperature reading and lower resolution (only positive, 12bit only). This implements 16bit protocol (31855 uses 32bit). SetOption94 enables the new behavior. Signed-off-by: Alexey Kardashevskiy --- Changes: v2: * treat occasional 0xfff as an error * do not add new sensor pins, use SetOption94 instead --- tasmota/settings.h | 2 +- tasmota/xsns_39_max31855.ino | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 0ad7a3533..1b0cc0951 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -113,7 +113,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t fade_at_startup : 1; // bit 9 (v8.2.0.3) - SetOption91 - Enable light fading at start/power on uint32_t pwm_ct_mode : 1; // bit 10 (v8.2.0.4) - SetOption92 - Set PWM Mode from regular PWM to ColorTemp control (Xiaomi Philips ...) uint32_t compress_rules_cpu : 1; // bit 11 (v8.2.0.6) - SetOption93 - Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick - uint32_t spare12 : 1; + uint32_t max6675 : 1; // bit 12 (v8.3.1.2) - SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855 uint32_t spare13 : 1; uint32_t spare14 : 1; uint32_t spare15 : 1; diff --git a/tasmota/xsns_39_max31855.ino b/tasmota/xsns_39_max31855.ino index c8cdfc7aa..e80f879c5 100644 --- a/tasmota/xsns_39_max31855.ino +++ b/tasmota/xsns_39_max31855.ino @@ -50,6 +50,20 @@ void MAX31855_Init(void){ * Acquires the raw data via SPI, checks for MAX31855 errors and fills result structure */ void MAX31855_GetResult(void){ + // Controlled via SetOption94 + if (Settings.flag4.max6675) { + int32_t RawData = MAX31855_ShiftIn(16); + int32_t temp = (RawData >> 3) & ((1 << 12) - 1); + + /* Occasionally the sensor returns 0xfff, consider it an error */ + if (temp == ((1 << 12) - 1)) + return; + + MAX31855_Result.ErrorCode = 0; + MAX31855_Result.ReferenceTemperature = NAN; + MAX31855_Result.ProbeTemperature = ConvertTemp(0.25 * temp); + return; + } int32_t RawData = MAX31855_ShiftIn(32); uint8_t probeerror = RawData & 0x7; From 41f77f688cf0ed9133f5d29248d99bc125c65291 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 4 Jun 2020 11:36:58 +0200 Subject: [PATCH 154/581] Add command ``SetOption94 0/1`` Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) --- RELEASENOTES.md | 2 + tasmota/CHANGELOG.md | 1 + tasmota/my_user_config.h | 10 +- tasmota/xsns_39_max31855.ino | 229 ++++++++++++++++++----------------- 4 files changed, 127 insertions(+), 115 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2453fd5d4..5e4429dde 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -61,6 +61,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Fix escape of non-JSON received serial data (#8329) - Add command ``Rule0`` to change global rule parameters - Add command ``Time 4`` to display timestamp using milliseconds (#8537) +- Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) - Add more functionality to ``Switchmode`` 11 and 12 (#8450) @@ -69,6 +70,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) - Add Three Phase Export Active Energy to SDM630 driver - Add Zigbee options to ``ZbSend`` to write and report attributes +- Add Zigbee auto-responder for common attributes - Add ``CpuFrequency`` to ``status 2`` - Add ``FlashFrequency`` to ``status 4`` - Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index e12680d36..54e1a5f63 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -7,6 +7,7 @@ - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Fix escape of non-JSON received serial data (#8329) - Add command ``Time 4`` to display timestamp using milliseconds (#8537) +- Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add Three Phase Export Active Energy to SDM630 driver - Add wildcard pattern ``?`` for JSON matching in rules diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 0d968b1f8..050c2e390 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -612,12 +612,12 @@ // -- Low level interface devices ----------------- #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code) -//#define USE_MAX31855 // Add support for MAX31855 K-Type thermocouple sensor using softSPI +//#define USE_MAX31855 // Add support for MAX31855/MAX6675 K-Type thermocouple sensor using softSPI //#define USE_MAX31865 // Add support for MAX31865 RTD sensors using softSPI - #define MAX31865_PTD_WIRES 2 // PTDs come in several flavors. Pick yours - #define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!) - #define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000) - #define MAX31865_PTD_BIAS 0 // To calibrate your not-so-good PTD + #define MAX31865_PTD_WIRES 2 // PTDs come in several flavors. Pick yours + #define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!) + #define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000) + #define MAX31865_PTD_BIAS 0 // To calibrate your not-so-good PTD // -- IR Remote features - all protocols from IRremoteESP8266 -------------------------- // IR Full Protocols mode is activated through platform.io only. diff --git a/tasmota/xsns_39_max31855.ino b/tasmota/xsns_39_max31855.ino index e80f879c5..fcdb69094 100644 --- a/tasmota/xsns_39_max31855.ino +++ b/tasmota/xsns_39_max31855.ino @@ -18,20 +18,27 @@ */ #ifdef USE_MAX31855 +/*********************************************************************************************\ + * MAX31855 and MAX6675 - Thermocouple + * + * SetOption94 0 - MAX31855 + * SetOption94 1 - MAX6675 +\*********************************************************************************************/ #define XSNS_39 39 -bool initialized = false; +const char kMax31855Types[] PROGMEM = "MAX31855|MAX6675"; -struct MAX31855_ResultStruct{ - uint8_t ErrorCode; // Error Codes: 0 = No Error / 1 = TC open circuit / 2 = TC short to GND / 4 = TC short to VCC - float ProbeTemperature; // Measured temperature of the 'hot' TC junction (probe temp) - float ReferenceTemperature; // Measured temperature of the 'cold' TC junction (reference temp) +bool max31855_initialized = false; + +struct MAX31855_ResultStruct { + uint8_t ErrorCode; // Error Codes: 0 = No Error / 1 = TC open circuit / 2 = TC short to GND / 4 = TC short to VCC + float ProbeTemperature; // Measured temperature of the 'hot' TC junction (probe temp) + float ReferenceTemperature; // Measured temperature of the 'cold' TC junction (reference temp) } MAX31855_Result; -void MAX31855_Init(void){ - if(initialized) - return; +void MAX31855_Init(void) { + if (PinUsed(GPIO_MAX31855CS) && PinUsed(GPIO_MAX31855CLK) && PinUsed(GPIO_MAX31855DO)) { // Set GPIO modes for SW-SPI pinMode(Pin(GPIO_MAX31855CS), OUTPUT); @@ -42,120 +49,122 @@ void MAX31855_Init(void){ digitalWrite(Pin(GPIO_MAX31855CS), HIGH); digitalWrite(Pin(GPIO_MAX31855CLK), LOW); - initialized = true; -} - -/* -* MAX31855_GetResult(void) -* Acquires the raw data via SPI, checks for MAX31855 errors and fills result structure -*/ -void MAX31855_GetResult(void){ - // Controlled via SetOption94 - if (Settings.flag4.max6675) { - int32_t RawData = MAX31855_ShiftIn(16); - int32_t temp = (RawData >> 3) & ((1 << 12) - 1); - - /* Occasionally the sensor returns 0xfff, consider it an error */ - if (temp == ((1 << 12) - 1)) - return; - - MAX31855_Result.ErrorCode = 0; - MAX31855_Result.ReferenceTemperature = NAN; - MAX31855_Result.ProbeTemperature = ConvertTemp(0.25 * temp); - return; - } - int32_t RawData = MAX31855_ShiftIn(32); - uint8_t probeerror = RawData & 0x7; - - MAX31855_Result.ErrorCode = probeerror; - MAX31855_Result.ReferenceTemperature = MAX31855_GetReferenceTemperature(RawData); - if(probeerror) - MAX31855_Result.ProbeTemperature = NAN; // Return NaN if MAX31855 reports an error - else - MAX31855_Result.ProbeTemperature = MAX31855_GetProbeTemperature(RawData); -} - - -/* -* MAX31855_GetProbeTemperature(int32_t RawData) -* Decodes and returns the temperature of TCs 'hot' junction from RawData -*/ -float MAX31855_GetProbeTemperature(int32_t RawData){ - if(RawData & 0x80000000) - RawData = (RawData >> 18) | 0xFFFFC000; // Negative value - Drop lower 18 bits and extend to negative number - else - RawData >>= 18; // Positiv value - Drop lower 18 bits - - float result = (RawData * 0.25); // MAX31855 LSB resolution is 0.25°C for probe temperature - - return ConvertTemp(result); // Check if we have to convert to Fahrenheit -} - -/* -* MAX31855_GetReferenceTemperature(int32_t RawData) -* Decodes and returns the temperature of TCs 'cold' junction from RawData -*/ -float MAX31855_GetReferenceTemperature(int32_t RawData){ - if(RawData & 0x8000) - RawData = (RawData >> 4) | 0xFFFFF000; // Negative value - Drop lower 4 bits and extend to negative number - else - RawData = (RawData >> 4) & 0x00000FFF; // Positiv value - Drop lower 4 bits and mask out remaining bits (probe temp, error bit, etc.) - - float result = (RawData * 0.0625); // MAX31855 LSB resolution is 0.0625°C for reference temperature - - return ConvertTemp(result); // Check if we have to convert to Fahrenheit + max31855_initialized = true; + } } /* * MAX31855_ShiftIn(uint8_t Length) * Communicates with MAX31855 via SW-SPI and returns the raw data read from the chip */ -int32_t MAX31855_ShiftIn(uint8_t Length){ - int32_t dataIn = 0; +int32_t MAX31855_ShiftIn(uint8_t Length) { + int32_t dataIn = 0; - digitalWrite(Pin(GPIO_MAX31855CS), LOW); // CS = LOW -> Start SPI communication - delayMicroseconds(1); // CS fall to output enable = max. 100ns + digitalWrite(Pin(GPIO_MAX31855CS), LOW); // CS = LOW -> Start SPI communication + delayMicroseconds(1); // CS fall to output enable = max. 100ns - for (uint32_t i = 0; i < Length; i++) - { - digitalWrite(Pin(GPIO_MAX31855CLK), LOW); - delayMicroseconds(1); // CLK pulse width low = min. 100ns / CLK fall to output valid = max. 40ns - dataIn <<= 1; - if(digitalRead(Pin(GPIO_MAX31855DO))) - dataIn |= 1; - digitalWrite(Pin(GPIO_MAX31855CLK), HIGH); - delayMicroseconds(1); // CLK pulse width high = min. 100ns - } - - digitalWrite(Pin(GPIO_MAX31855CS), HIGH); // CS = HIGH -> End SPI communication + for (uint32_t i = 0; i < Length; i++) { digitalWrite(Pin(GPIO_MAX31855CLK), LOW); - return dataIn; + delayMicroseconds(1); // CLK pulse width low = min. 100ns / CLK fall to output valid = max. 40ns + dataIn <<= 1; + if (digitalRead(Pin(GPIO_MAX31855DO))) { + dataIn |= 1; + } + digitalWrite(Pin(GPIO_MAX31855CLK), HIGH); + delayMicroseconds(1); // CLK pulse width high = min. 100ns + } + + digitalWrite(Pin(GPIO_MAX31855CS), HIGH); // CS = HIGH -> End SPI communication + digitalWrite(Pin(GPIO_MAX31855CLK), LOW); + return dataIn; } -void MAX31855_Show(bool Json){ - char probetemp[33]; - char referencetemp[33]; - dtostrfd(MAX31855_Result.ProbeTemperature, Settings.flag2.temperature_resolution, probetemp); - dtostrfd(MAX31855_Result.ReferenceTemperature, Settings.flag2.temperature_resolution, referencetemp); +/* +* MAX31855_GetProbeTemperature(int32_t RawData) +* Decodes and returns the temperature of TCs 'hot' junction from RawData +*/ +float MAX31855_GetProbeTemperature(int32_t RawData) { + if (RawData & 0x80000000) { + RawData = (RawData >> 18) | 0xFFFFC000; // Negative value - Drop lower 18 bits and extend to negative number + } else { + RawData >>= 18; // Positiv value - Drop lower 18 bits + } + float result = (RawData * 0.25); // MAX31855 LSB resolution is 0.25°C for probe temperature - if(Json){ - ResponseAppend_P(PSTR(",\"MAX31855\":{\"" D_JSON_PROBETEMPERATURE "\":%s,\"" D_JSON_REFERENCETEMPERATURE "\":%s,\"" D_JSON_ERROR "\":%d}"), \ - probetemp, referencetemp, MAX31855_Result.ErrorCode); + return ConvertTemp(result); // Check if we have to convert to Fahrenheit +} + +/* +* MAX31855_GetReferenceTemperature(int32_t RawData) +* Decodes and returns the temperature of TCs 'cold' junction from RawData +*/ +float MAX31855_GetReferenceTemperature(int32_t RawData) { + if (RawData & 0x8000) { + RawData = (RawData >> 4) | 0xFFFFF000; // Negative value - Drop lower 4 bits and extend to negative number + } else { + RawData = (RawData >> 4) & 0x00000FFF; // Positiv value - Drop lower 4 bits and mask out remaining bits (probe temp, error bit, etc.) + } + float result = (RawData * 0.0625); // MAX31855 LSB resolution is 0.0625°C for reference temperature + + return ConvertTemp(result); // Check if we have to convert to Fahrenheit +} + +/* +* MAX31855_GetResult(void) +* Acquires the raw data via SPI, checks for MAX31855 errors and fills result structure +*/ +void MAX31855_GetResult(void) { + if (Settings.flag4.max6675) { // SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855 + int32_t RawData = MAX31855_ShiftIn(16); + int32_t temp = (RawData >> 3) & ((1 << 12) - 1); + + /* Occasionally the sensor returns 0xfff, consider it an error */ + if (temp == ((1 << 12) - 1)) { return; } + + MAX31855_Result.ErrorCode = 0; + MAX31855_Result.ReferenceTemperature = NAN; + MAX31855_Result.ProbeTemperature = ConvertTemp(0.25 * temp); + } else { + int32_t RawData = MAX31855_ShiftIn(32); + uint8_t probeerror = RawData & 0x7; + + MAX31855_Result.ErrorCode = probeerror; + MAX31855_Result.ReferenceTemperature = MAX31855_GetReferenceTemperature(RawData); + if (probeerror) { + MAX31855_Result.ProbeTemperature = NAN; // Return NaN if MAX31855 reports an error + } else { + MAX31855_Result.ProbeTemperature = MAX31855_GetProbeTemperature(RawData); + } + } +} + +void MAX31855_Show(bool Json) { + char probetemp[33]; + char referencetemp[33]; + dtostrfd(MAX31855_Result.ProbeTemperature, Settings.flag2.temperature_resolution, probetemp); + dtostrfd(MAX31855_Result.ReferenceTemperature, Settings.flag2.temperature_resolution, referencetemp); + + char sensor_name[10]; + GetTextIndexed(sensor_name, sizeof(sensor_name), Settings.flag4.max6675, kMax31855Types); + + if (Json) { + ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_PROBETEMPERATURE "\":%s,\"" D_JSON_REFERENCETEMPERATURE "\":%s,\"" D_JSON_ERROR "\":%d}"), \ + sensor_name, probetemp, referencetemp, MAX31855_Result.ErrorCode); #ifdef USE_DOMOTICZ - if (0 == tele_period) { - DomoticzSensor(DZ_TEMP, probetemp); - } + if (0 == tele_period) { + DomoticzSensor(DZ_TEMP, probetemp); + } #endif // USE_DOMOTICZ #ifdef USE_KNX - if (0 == tele_period) { - KnxSensor(KNX_TEMPERATURE, MAX31855_Result.ProbeTemperature); - } -#endif // USE_KNX - } else { -#ifdef USE_WEBSERVER - WSContentSend_PD(HTTP_SNS_TEMP, "MAX31855", probetemp, TempUnit()); -#endif // USE_WEBSERVER + if (0 == tele_period) { + KnxSensor(KNX_TEMPERATURE, MAX31855_Result.ProbeTemperature); } +#endif // USE_KNX +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, probetemp, TempUnit()); +#endif // USE_WEBSERVER + } } /*********************************************************************************************\ @@ -165,12 +174,12 @@ void MAX31855_Show(bool Json){ bool Xsns39(uint8_t function) { bool result = false; - if(PinUsed(GPIO_MAX31855CS) && PinUsed(GPIO_MAX31855CLK) && PinUsed(GPIO_MAX31855DO)){ + if (FUNC_INIT == function) { + MAX31855_Init(); + } + else if (max31855_initialized) { switch (function) { - case FUNC_INIT: - MAX31855_Init(); - break; case FUNC_EVERY_SECOND: MAX31855_GetResult(); break; From dac14073c99056fdb7f506b19dd0cdac8321877a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 4 Jun 2020 12:28:01 +0200 Subject: [PATCH 155/581] Fix windmeter interrupt service routine Fix windmeter interrupt service routine (#8614) --- tasmota/xsns_68_windmeter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_68_windmeter.ino b/tasmota/xsns_68_windmeter.ino index c0e5de2aa..3faa7ecb7 100644 --- a/tasmota/xsns_68_windmeter.ino +++ b/tasmota/xsns_68_windmeter.ino @@ -83,7 +83,7 @@ void WindMeterUpdateSpeed(void) if (time_diff > Settings.windmeter_pulse_debounce * 1000) { WindMeter.counter_time = time; WindMeter.counter++; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("WMET: Counter %d"), WindMeter.counter); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("WMET: Counter %d"), WindMeter.counter); } } From c20bb9ab58f85819a0640894e91865c6756e3e7d Mon Sep 17 00:00:00 2001 From: Janusz Kostorz <48957313+jkostorz@users.noreply.github.com> Date: Thu, 4 Jun 2020 22:27:30 +0200 Subject: [PATCH 156/581] increasing in color temperature change speed --- tasmota/support_rotary.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 25c064a18..6d79744f4 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -117,7 +117,7 @@ void RotaryHandler(void) Rotary.changed = 1; // button1 is pressed: set color temperature int16_t t = LightGetColorTemp(); - t = t + (Rotary.position - Rotary.last_position); + t = t + ((Rotary.position - Rotary.last_position) * 4); if (t < 153) { t = 153; } From 9d86c15685db3f4103e2a47bc3eeb747c830d700 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 5 Jun 2020 11:53:53 +0200 Subject: [PATCH 157/581] Some webserver code saving --- tasmota/xdrv_01_webserver.ino | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index e4f2bd4a4..6bf15230e 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -34,8 +34,8 @@ const uint16_t CHUNKED_BUFFER_SIZE = (MESSZ / 2) - 100; // Chunk buffer size (should be smaller than half mqtt_data size = MESSZ) const uint16_t HTTP_REFRESH_TIME = 2345; // milliseconds -#define HTTP_RESTART_RECONNECT_TIME 9000 // milliseconds -#define HTTP_OTA_RESTART_RECONNECT_TIME 20000 // milliseconds +const uint16_t HTTP_RESTART_RECONNECT_TIME = 9000; // milliseconds - Allow time for restart and wifi reconnect +const uint16_t HTTP_OTA_RESTART_RECONNECT_TIME = 28000; // milliseconds - Allow time for uploading binary, unzip/write to final destination and wifi reconnect #include #include @@ -170,12 +170,8 @@ const char HTTP_SCRIPT_WIFI[] PROGMEM = "eb('p1').focus();" "}"; -const char HTTP_SCRIPT_RELOAD[] PROGMEM = - "setTimeout(function(){location.href='.';}," STR(HTTP_RESTART_RECONNECT_TIME) ");"; - -// Local OTA upgrade requires more time to complete cp: before web ui should be reloaded -const char HTTP_SCRIPT_RELOAD_OTA[] PROGMEM = - "setTimeout(function(){location.href='.';}," STR(HTTP_OTA_RESTART_RECONNECT_TIME) ");"; +const char HTTP_SCRIPT_RELOAD_TIME[] PROGMEM = + "setTimeout(function(){location.href='.';},%d);"; const char HTTP_SCRIPT_CONSOL[] PROGMEM = "var sn=0,id=0;" // Scroll position, Get most of weblog initially @@ -980,7 +976,7 @@ void WebRestart(uint32_t type) bool reset_only = (HTTP_MANAGER_RESET_ONLY == Web.state); WSContentStart_P((type) ? S_SAVE_CONFIGURATION : S_RESTART, !reset_only); - WSContentSend_P(HTTP_SCRIPT_RELOAD); + WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_RESTART_RECONNECT_TIME); WSContentSendStyle(); if (type) { WSContentSend_P(PSTR("

" D_CONFIGURATION_SAVED "
")); @@ -2346,7 +2342,7 @@ void HandleUpgradeFirmwareStart(void) } WSContentStart_P(S_INFORMATION); - WSContentSend_P(HTTP_SCRIPT_RELOAD_OTA); + WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_OTA_RESTART_RECONNECT_TIME); WSContentSendStyle(); WSContentSend_P(PSTR("
" D_UPGRADE_STARTED " ...
")); WSContentSend_P(HTTP_MSG_RSTRT); @@ -2371,7 +2367,7 @@ void HandleUploadDone(void) WSContentStart_P(S_INFORMATION); if (!Web.upload_error) { - WSContentSend_P(HTTP_SCRIPT_RELOAD_OTA); // Refesh main web ui after OTA upgrade + WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_OTA_RESTART_RECONNECT_TIME); // Refesh main web ui after OTA upgrade } WSContentSendStyle(); WSContentSend_P(PSTR("
" D_UPLOAD " =0 fsp=&SD; - -#ifdef USE_MMC - if (fsp->begin()) { -#else if (SD.begin(USE_SCRIPT_FATFS)) { -#endif - #else if (fsp->begin()) { #endif @@ -738,13 +762,14 @@ float median_array(float *array,uint8_t len) { } -float *Get_MFAddr(uint8_t index,uint8_t *len) { +float *Get_MFAddr(uint8_t index,uint8_t *len,uint8_t *ipos) { *len=0; uint8_t *mp=(uint8_t*)glob_script_mem.mfilt; for (uint8_t count=0; countnumvals&0x7f; + if (ipos) *ipos=mflp->index; return mflp->rbuff; } mp+=sizeof(struct M_FILT)+((mflp->numvals&0x7f)-1)*sizeof(float); @@ -936,6 +961,56 @@ if (hsv.S == 0) { #endif //#endif +#ifdef USE_ANGLE_FUNC +uint32_t pulse_time_hl; +uint32_t pulse_time_lh; +uint32_t pulse_ltime_hl; +uint32_t pulse_ltime_lh; +uint8_t pt_pin; + +void MP_Timer(void) ICACHE_RAM_ATTR; + +#define MPT_DEBOUNCE 10 + +void MP_Timer(void) { + uint32_t level = digitalRead(pt_pin&0x3f); + uint32_t ms = millis(); + uint32_t time; + if (level) { + // rising edge + pulse_ltime_lh = ms; + time = ms - pulse_ltime_hl; + if (time>MPT_DEBOUNCE) pulse_time_hl = time; + } else { + // falling edge + pulse_ltime_hl = ms; + time = ms - pulse_ltime_lh; + if (time>MPT_DEBOUNCE) pulse_time_lh = time; + } +} + +uint32_t MeasurePulseTime(int32_t in) { + if (in >= 0) { + // define pin; + pt_pin = in; + pinMode(pt_pin&0x3f,INPUT_PULLUP); + attachInterrupt(pt_pin&0x3f, MP_Timer, CHANGE); + pulse_ltime_lh = millis(); + pulse_ltime_hl = millis(); + return 0; + } + uint32_t ptime; + if (in==-1) { + ptime = pulse_time_lh; + pulse_time_lh = 0; + } else { + ptime = pulse_time_hl; + pulse_time_hl = 0; + } + return ptime; +} +#endif // USE_ANGLE_FUNC + // vtype => ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number // no flash strings here for performance reasons!!! char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,JsonObject *jo) { @@ -1720,6 +1795,15 @@ chknext: len=0; goto exit; } +#ifdef USE_ANGLE_FUNC + if (!strncmp(vname,"mpt(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + fvar=MeasurePulseTime(fvar); + lp++; + len=0; + goto exit; + } +#endif if (!strncmp(vname,"micros",6)) { fvar=micros(); goto exit; @@ -3159,7 +3243,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { // numeric result if (glob_script_mem.type[ind.index].bits.is_filter) { uint8_t len=0; - float *fa=Get_MFAddr(index,&len); + float *fa=Get_MFAddr(index,&len,0); //Serial.printf(">> 2 %d\n",(uint32_t)*fa); if (fa && len) ws2812_set_array(fa,len,fvar); } @@ -4065,26 +4149,26 @@ void ScriptSaveSettings(void) { } -#if defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#ifdef EEP_SCRIPT_SIZE if (glob_script_mem.flags&1) { EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram); } -#endif +#endif // EEP_SCRIPT_SIZE -#if !defined(USE_24C256) && defined(USE_SCRIPT_FATFS) +#ifdef USE_SCRIPT_FATFS if (glob_script_mem.flags&1) { fsp->remove(FAT_SCRIPT_NAME); File file=fsp->open(FAT_SCRIPT_NAME,FILE_WRITE); file.write((const uint8_t*)glob_script_mem.script_ram,FAT_SCRIPT_SIZE); file.close(); } -#endif +#endif // USE_SCRIPT_FATFS -#if defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#ifdef LITTLEFS_SCRIPT_SIZE if (glob_script_mem.flags&1) { SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,LITTLEFS_SCRIPT_SIZE); } -#endif +#endif // LITTLEFS_SCRIPT_SIZE } if (glob_script_mem.script_mem) { @@ -4095,10 +4179,6 @@ void ScriptSaveSettings(void) { } #ifdef USE_SCRIPT_COMPRESSION -#ifndef USE_24C256 -#ifndef USE_SCRIPT_FATFS -#ifndef LITTLEFS_SCRIPT_SIZE - //AddLog_P2(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], MAX_SCRIPT_SIZE-1); if (len_compressed > 0) { @@ -4107,10 +4187,6 @@ void ScriptSaveSettings(void) { } else { AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); } - -#endif -#endif -#endif #endif // USE_SCRIPT_COMPRESSION if (bitRead(Settings.rule_enabled, 0)) { @@ -5068,10 +5144,11 @@ const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'"; #define MAX_GARRAY 4 -char *gc_get_arrays(char *lp, float **arrays, uint8_t *ranum, uint8_t *rentries) { +char *gc_get_arrays(char *lp, float **arrays, uint8_t *ranum, uint8_t *rentries, uint8_t *ipos) { struct T_INDEX ind; uint8_t vtype; uint8 entries=0; +uint8_t cipos=0; uint8_t anum=0; while (anum> 2 %d\n",(uint32_t)*fa); if (fa && len>=entries) { - if (!entries) {entries = len;} + if (!entries) { + entries = len; + } // add array to list arrays[anum]=fa; anum++; @@ -5111,6 +5190,7 @@ uint8 entries=0; //Serial.printf(">> %d - %d - %d\n",anum,entries,(uint32_t)*arrays[0]); *ranum=anum; *rentries=entries; + *ipos=cipos; return lp; } @@ -5409,7 +5489,8 @@ void ScriptWebShow(char mc) { float *arrays[MAX_GARRAY]; uint8_t anum=0; uint8 entries=0; - lp=gc_get_arrays(lp, &arrays[0], &anum, &entries); + uint8 ipos=0; + lp=gc_get_arrays(lp, &arrays[0], &anum, &entries, &ipos); if (anum>nanum) { goto nextwebline; @@ -5456,28 +5537,38 @@ void ScriptWebShow(char mc) { int8_t todflg=-1; if (!strncmp(label,"cnt",3)) { todflg=atoi(&label[3]); + if (todflg>=entries) todflg=entries-1; } + uint32_t aind=ipos; + if (aind>=entries) aind=entries-1; for (uint32_t cnt=0; cnt=0) { sprintf(lbl,"%d",todflg); todflg++; + if (todflg>=entries) { + todflg=0; + } } else { - GetTextIndexed(lbl, sizeof(lbl), cnt, label); + GetTextIndexed(lbl, sizeof(lbl), aind, label); } WSContentSend_PD(lbl); WSContentSend_PD("',"); for (uint32_t ind=0; ind=entries) { + aind=0; + } } // get header @@ -5722,7 +5813,7 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { /*********************************************************************************************\ * Interface \*********************************************************************************************/ - +//const esp_partition_t *esp32_part; bool Xdrv10(uint8_t function) { @@ -5740,9 +5831,6 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_pram_size=PMEM_SIZE; #ifdef USE_SCRIPT_COMPRESSION -#ifndef USE_24C256 -#ifndef USE_SCRIPT_FATFS -#ifndef LITTLEFS_SCRIPT_SIZE int32_t len_decompressed; sprt=(char*)calloc(UNISHOXRSIZE+8,1); if (!sprt) { break; } @@ -5751,9 +5839,6 @@ bool Xdrv10(uint8_t function) len_decompressed = SCRIPT_DECOMPRESS(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, glob_script_mem.script_size); if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed]=0; //AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); -#endif -#endif -#endif #endif // USE_SCRIPT_COMPRESSION #ifdef USE_BUTTON_EVENT @@ -5762,10 +5847,8 @@ bool Xdrv10(uint8_t function) } #endif -#ifdef USE_24C256 -#ifndef USE_SCRIPT_FATFS - if (I2cEnabled(XI2C_37)) { - if (I2cSetDevice(EEPROM_ADDRESS)) { +#ifdef EEP_SCRIPT_SIZE + if (eeprom_init(EEP_SCRIPT_SIZE)) { // found 32kb eeprom char *script; script=(char*)calloc(EEP_SCRIPT_SIZE+4,1); @@ -5782,34 +5865,26 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE; glob_script_mem.flags=1; - I2cSetActiveFound(EEPROM_ADDRESS, "EEPROM"); - } } -#endif -#endif +#endif // EEP_SCRIPT_SIZE #ifdef USE_SCRIPT_FATFS #if USE_SCRIPT_FATFS>=0 - fsp = &SD; - -#ifdef USE_MMC - if (fsp->begin()) { -#else - + // fs on SD card #ifdef ESP32 if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { - SPI.begin(Pin(GPIO_SPI_CLK),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_MOSI), -1); + SPI.begin(Pin(GPIO_SPI_CLK),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_MOSI), -1); } -#endif +#endif // ESP32 + fsp = &SD; if (SD.begin(USE_SCRIPT_FATFS)) { -#endif - #else - fsp = &LittleFS; - if (fsp->begin()) { -#endif + // fs on flash + fsp = &LittleFS; + if (fsp->begin()) { +#endif // USE_SCRIPT_FATFS>=0 //fsp->dateTimeCallback(dateTime); @@ -5834,14 +5909,18 @@ bool Xdrv10(uint8_t function) } else { glob_script_mem.script_sd_found=0; } -#endif +#endif // USE_SCRIPT_FATFS -#if defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS) +#ifdef LITTLEFS_SCRIPT_SIZE #ifdef ESP32 + // spiffs on esp32 fsp = &SPIFFS; + //esp32_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,ESP_PARTITION_SUBTYPE_DATA_SPIFFS,NULL); + //Serial.printf("address %d - %d - %s\n",esp32_part->address,esp32_part->size, esp32_part->label); #else + // lfs on esp8266 fsp = &LittleFS; #endif char *script; @@ -5856,7 +5935,7 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_pram=(uint8_t*)Settings.rules[0]; glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE; glob_script_mem.flags=1; -#endif +#endif // LITTLEFS_SCRIPT_SIZE // a valid script MUST start with >D if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') { From 0bfb79e6942f5eb50146c946df7c7c89b72bc53e Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 5 Jun 2020 22:27:47 +0200 Subject: [PATCH 160/581] Fix Zigbee Time and add TimeEpoch --- tasmota/xdrv_23_zigbee_5_converters.ino | 3 ++- tasmota/xdrv_23_zigbee_8_parsers.ino | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index bf508d9c2..02a0f4d6d 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -136,7 +136,7 @@ ZF(MainsVoltage) ZF(MainsFrequency) ZF(BatteryVoltage) ZF(BatteryPercentage) ZF(CurrentTemperature) ZF(MinTempExperienced) ZF(MaxTempExperienced) ZF(OverTempTotalDwell) ZF(SceneCount) ZF(CurrentScene) ZF(CurrentGroup) ZF(SceneValid) ZF(AlarmCount) ZF(Time) ZF(TimeStatus) ZF(TimeZone) ZF(DstStart) ZF(DstEnd) -ZF(DstShift) ZF(StandardTime) ZF(LocalTime) ZF(LastSetTime) ZF(ValidUntilTime) +ZF(DstShift) ZF(StandardTime) ZF(LocalTime) ZF(LastSetTime) ZF(ValidUntilTime) ZF(TimeEpoch) ZF(LocationType) ZF(LocationMethod) ZF(LocationAge) ZF(QualityMeasure) ZF(NumberOfDevices) @@ -283,6 +283,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zuint32, Cx000A, 0x0007, Z(LocalTime), 1, Z_Nop }, { ZUTC, Cx000A, 0x0008, Z(LastSetTime), 1, Z_Nop }, { ZUTC, Cx000A, 0x0009, Z(ValidUntilTime), 1, Z_Nop }, + { ZUTC, Cx000A, 0xFF00, Z(TimeEpoch), 1, Z_Nop }, // Tasmota specific, epoch // RSSI Location cluster { Zdata8, Cx000B, 0x0000, Z(LocationType), 1, Z_Nop }, diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 996103fe5..aad2732ca 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -866,7 +866,8 @@ void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const break; #endif case 0x000A: // Time - if (HasKeyCaseInsensitive(json, PSTR("Time"))) { json_out[F("Time")] = Rtc.utc_time; } + if (HasKeyCaseInsensitive(json, PSTR("Time"))) { json_out[F("Time")] = (Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? Rtc.utc_time - 946684800 : Rtc.utc_time; } + if (HasKeyCaseInsensitive(json, PSTR("TimeEpoch"))) { json_out[F("TimeEpoch")] = Rtc.utc_time; } if (HasKeyCaseInsensitive(json, PSTR("TimeStatus"))) { json_out[F("TimeStatus")] = (Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? 0x02 : 0x00; } // if time is beyond 2010 then we are synchronized if (HasKeyCaseInsensitive(json, PSTR("TimeZone"))) { json_out[F("TimeZone")] = Settings.toffset[0] * 60; } // seconds break; From a7b70f04e085e55115600e004edfe9032bf522c9 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 6 Jun 2020 06:38:12 +0200 Subject: [PATCH 161/581] Update esp32_partition_app1984k_spiffs60k.csv converted and verified with gen_esp32part.py tool --- esp32_partition_app1984k_spiffs60k.csv | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/esp32_partition_app1984k_spiffs60k.csv b/esp32_partition_app1984k_spiffs60k.csv index e8bcd9d49..9c5f895a0 100644 --- a/esp32_partition_app1984k_spiffs60k.csv +++ b/esp32_partition_app1984k_spiffs60k.csv @@ -1,7 +1,8 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x1F0000, -app1, app, ota_1, 0x200000, 0x1F0000, -spiffs, data, spiffs, 0x3F0000,0xf000, -eeprom, data, nvs, 0x3FF000,0x1000, +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +nvs,data,nvs,0x9000,20K, +otadata,data,ota,0xe000,8K, +app0,app,ota_0,0x10000,1984K, +app1,app,ota_1,0x200000,1984K, +spiffs,data,spiffs,0x3f0000,60K, +eeprom,data,nvs,0x3ff000,4K, From 8a67477cab1ea54c4dadf4b0f38942d8e87cdc2f Mon Sep 17 00:00:00 2001 From: Matteo Albinola Date: Sat, 6 Jun 2020 09:25:00 +0200 Subject: [PATCH 162/581] Make ISR variables volatile --- tasmota/xsns_68_windmeter.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xsns_68_windmeter.ino b/tasmota/xsns_68_windmeter.ino index 3faa7ecb7..5487c898c 100644 --- a/tasmota/xsns_68_windmeter.ino +++ b/tasmota/xsns_68_windmeter.ino @@ -58,8 +58,8 @@ float const windmeter_pi = 3.1415926535897932384626433; // Pi float const windmeter_2pi = windmeter_pi * 2; struct WINDMETER { - uint32_t counter_time; - unsigned long counter = 0; + volatile uint32_t counter_time; + volatile unsigned long counter = 0; //uint32_t speed_time; float speed = 0; float last_tele_speed = 0; From 7077a80541a5ac79c0fe37fbaa8c9d0cc7ac53a5 Mon Sep 17 00:00:00 2001 From: Staars Date: Sat, 6 Jun 2020 20:04:10 +0200 Subject: [PATCH 163/581] unify USE_*_COMPRESSION to USE_UNISHOX_COMPRESSION --- tasmota/my_user_config.h | 6 ++++-- tasmota/support.ino | 4 ++-- tasmota/xdrv_10_rules.ino | 32 ++++++++++++++++---------------- tasmota/xdrv_10_scripter.ino | 22 +++++++++++----------- tasmota/xdrv_21_wemo.ino | 10 +++++----- 5 files changed, 38 insertions(+), 36 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index b6008abcf..466a8991e 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -394,12 +394,14 @@ // -- Ping ---------------------------------------- // #define USE_PING // Enable Ping command (+2k code) +#define USE_UNISHOX_COMPRESSION // add support for string compression for RULES or SCRIPT + // -- Rules or Script ---------------------------- // Select none or only one of the below defines USE_RULES or USE_SCRIPT #define USE_RULES // Add support for rules (+8k code) - #define USE_RULES_COMPRESSION // Compresses rules in Flash at about ~50% (+3.3k code) + // with USE_UNISHOX_COMPRESSION // Compresses rules in Flash at about ~50% (+3.3k code) //#define USE_SCRIPT // Add support for script (+17k code) - #define USE_SCRIPT_COMPRESSION + // supports USE_UNISHOX_COMPRESSION //#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support // #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem) diff --git a/tasmota/support.ino b/tasmota/support.ino index 839e126f6..8d915cf05 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1882,7 +1882,7 @@ void AddLogBufferSize(uint32_t loglevel, uint8_t *buffer, uint32_t count, uint32 * Uncompress static PROGMEM strings \*********************************************************************************************/ -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION #include @@ -1908,4 +1908,4 @@ String Decompress(const char * compressed, size_t uncompressed_size) { return content; } -#endif // defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) \ No newline at end of file +#endif // USE_UNISHOX_COMPRESSION \ No newline at end of file diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 8dd185a29..10c4c22e8 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -210,15 +210,15 @@ char rules_vars[MAX_RULE_VARS][33] = {{ 0 }}; */ /*******************************************************************************************/ -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION // Statically allocate one String per rule String k_rules[MAX_RULE_SETS] = { String(), String(), String() }; // Strings are created empty // Unishox compressor; // singleton -#endif // USE_RULES_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION // Returns whether the rule is uncompressed, which means the first byte is not NULL inline bool IsRuleUncompressed(uint32_t idx) { -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION return Settings.rules[idx][0] ? true : false; // first byte not NULL, the rule is not empty and not compressed #else return true; @@ -227,7 +227,7 @@ inline bool IsRuleUncompressed(uint32_t idx) { // Returns whether the rule is empty, which requires two consecutive NULL inline bool IsRuleEmpty(uint32_t idx) { -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION return (Settings.rules[idx][0] == 0) && (Settings.rules[idx][1] == 0) ? true : false; #else return (Settings.rules[idx][0] == 0) ? true : false; @@ -236,7 +236,7 @@ inline bool IsRuleEmpty(uint32_t idx) { // Returns the approximate (+3-0) length of the rule, not counting the trailing NULL size_t GetRuleLen(uint32_t idx) { - // no need to use #ifdef USE_RULES_COMPRESSION, the compiler will optimize since first test is always true + // no need to use #ifdef USE_UNISHOX_COMPRESSION, the compiler will optimize since first test is always true if (IsRuleUncompressed(idx)) { return strlen(Settings.rules[idx]); } else { // either empty or compressed @@ -246,7 +246,7 @@ size_t GetRuleLen(uint32_t idx) { // Returns the actual Flash storage for the Rule, including trailing NULL size_t GetRuleLenStorage(uint32_t idx) { -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION if (Settings.rules[idx][0] || !Settings.rules[idx][1]) { // if first byte is non-NULL it is uncompressed, if second byte is NULL, then it's either uncompressed or empty return 1 + strlen(Settings.rules[idx]); // uncompressed or empty } else { @@ -257,7 +257,7 @@ size_t GetRuleLenStorage(uint32_t idx) { #endif } -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION // internal function, do the actual decompression void GetRule_decompress(String &rule, const char *rule_head) { size_t buf_len = 1 + *rule_head * 8; // the first byte contains size of buffer for uncompressed rule / 8, buf_len may overshoot by 7 @@ -265,7 +265,7 @@ void GetRule_decompress(String &rule, const char *rule_head) { rule = Decompress(rule_head, buf_len); } -#endif // USE_RULES_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION // // Read rule in memory, uncompress if needed @@ -275,7 +275,7 @@ String GetRule(uint32_t idx) { if (IsRuleUncompressed(idx)) { return String(Settings.rules[idx]); } else { -#ifdef USE_RULES_COMPRESSION // we still do #ifdef to make sure we don't link unnecessary code +#ifdef USE_UNISHOX_COMPRESSION // we still do #ifdef to make sure we don't link unnecessary code String rule(""); if (Settings.rules[idx][1] == 0) { return rule; } // the rule is empty @@ -295,7 +295,7 @@ String GetRule(uint32_t idx) { } } -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION // internal function, comrpess rule and store a cached version uncompressed (except if SetOption94 1) // If out == nullptr, we are in dry-run mode, so don't keep rule in cache int32_t SetRule_compress(uint32_t idx, const char *in, size_t in_len, char *out, size_t out_len) { @@ -312,7 +312,7 @@ int32_t SetRule_compress(uint32_t idx, const char *in, size_t in_len, char *out, } return len_compressed; } -#endif // USE_RULES_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION // Returns: // >= 0 : the actual stored size @@ -343,7 +343,7 @@ int32_t SetRule(uint32_t idx, const char *content, bool append = false) { Settings.rules[idx][1] = 0; } -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION if (0 != len_in + offset) { // do a dry-run compression to display how much it would be compressed int32_t len_compressed, len_uncompressed; @@ -353,11 +353,11 @@ int32_t SetRule(uint32_t idx, const char *content, bool append = false) { AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: Stored uncompressed, would compress from %d to %d (-%d%%)"), len_uncompressed, len_compressed, 100 - changeUIntScale(len_compressed, 0, len_uncompressed, 0, 100)); } -#endif // USE_RULES_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION return len_in + offset; } else { -#ifdef USE_RULES_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION int32_t len_compressed; // allocate temp buffer so we don't nuke the rule if it's too big to fit char *buf_out = (char*) malloc(MAX_RULE_SIZE + 8); // take some margin @@ -390,9 +390,9 @@ int32_t SetRule(uint32_t idx, const char *content, bool append = false) { free(buf_out); return len_compressed; -#else // USE_RULES_COMPRESSION +#else // USE_UNISHOX_COMPRESSION return -1; // the rule does not fit and we can't compress -#endif // USE_RULES_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION } } diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 80164f992..888fa3cb8 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -73,7 +73,7 @@ uint32_t DecodeLightId(uint32_t hue_id); #ifdef USE_SCRIPT_FATFS #undef LITTLEFS_SCRIPT_SIZE #undef EEP_SCRIPT_SIZE -#undef USE_SCRIPT_COMPRESSION +#undef USE_UNISHOX_COMPRESSION #if USE_SCRIPT_FATFS==-1 #ifdef ESP32 #error "script fat file option -1 currently not supported for ESP32" @@ -88,13 +88,13 @@ uint32_t DecodeLightId(uint32_t hue_id); // lfs on esp8266 spiffs on esp32 #ifdef LITTLEFS_SCRIPT_SIZE #undef EEP_SCRIPT_SIZE -#undef USE_SCRIPT_COMPRESSION +#undef USE_UNISHOX_COMPRESSION #pragma message "script little file system option used" #endif // LITTLEFS_SCRIPT_SIZE // eeprom script #ifdef EEP_SCRIPT_SIZE -#undef USE_SCRIPT_COMPRESSION +#undef USE_UNISHOX_COMPRESSION #ifdef USE_24C256 #pragma message "script 24c256 file option used" #else @@ -104,12 +104,12 @@ uint32_t DecodeLightId(uint32_t hue_id); #endif // EEP_SCRIPT_SIZE // compression last option before default -#ifdef USE_SCRIPT_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION #pragma message "script compression option used" -#endif // USE_SCRIPT_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION -#ifdef USE_SCRIPT_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION #include #define SCRIPT_COMPRESS compressor.unishox_compress @@ -117,7 +117,7 @@ uint32_t DecodeLightId(uint32_t hue_id); #ifndef UNISHOXRSIZE #define UNISHOXRSIZE 2560 #endif -#endif // USE_SCRIPT_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION #if defined(LITTLEFS_SCRIPT_SIZE) || (USE_SCRIPT_FATFS==-1) @@ -4178,7 +4178,7 @@ void ScriptSaveSettings(void) { glob_script_mem.script_mem_size=0; } -#ifdef USE_SCRIPT_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION //AddLog_P2(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], MAX_SCRIPT_SIZE-1); if (len_compressed > 0) { @@ -4187,7 +4187,7 @@ void ScriptSaveSettings(void) { } else { AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); } -#endif // USE_SCRIPT_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION if (bitRead(Settings.rule_enabled, 0)) { int16_t res=Init_Scripter(); @@ -5830,7 +5830,7 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_pram=(uint8_t*)Settings.script_pram[0]; glob_script_mem.script_pram_size=PMEM_SIZE; -#ifdef USE_SCRIPT_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION int32_t len_decompressed; sprt=(char*)calloc(UNISHOXRSIZE+8,1); if (!sprt) { break; } @@ -5839,7 +5839,7 @@ bool Xdrv10(uint8_t function) len_decompressed = SCRIPT_DECOMPRESS(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, glob_script_mem.script_size); if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed]=0; //AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); -#endif // USE_SCRIPT_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION #ifdef USE_BUTTON_EVENT for (uint32_t cnt=0;cntSetBinaryStateBinaryStateBinaryStateinGetBinaryStateBinaryStateBinaryStateoutBinaryStatebool0levelstring0\r\n\r\n //Successfully compressed from 779 to 249 bytes (-68%) @@ -293,7 +293,7 @@ void HandleUpnpEvent(void) } } -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION snprintf_P(event, sizeof(event), Decompress(WEMO_RESPONSE_STATE_SOAP, WEMO_RESPONSE_STATE_SOAP_SIZE).c_str(), state, bitRead(power, devices_present -1), state); #else snprintf_P(event, sizeof(event), WEMO_RESPONSE_STATE_SOAP, state, bitRead(power, devices_present -1), state); @@ -305,7 +305,7 @@ void HandleUpnpService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_EVENT_SERVICE)); -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION WSSend(200, CT_PLAIN, Decompress(WEMO_EVENTSERVICE_XML, WEMO_EVENTSERVICE_XML_SIZE)); #else WSSend(200, CT_PLAIN, FPSTR(WEMO_EVENTSERVICE_XML)); @@ -316,7 +316,7 @@ void HandleUpnpMetaService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_META_SERVICE)); -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION WSSend(200, CT_PLAIN, Decompress(WEMO_METASERVICE_XML, WEMO_METASERVICE_XML_SIZE)); #else WSSend(200, CT_PLAIN, FPSTR(WEMO_METASERVICE_XML)); @@ -327,7 +327,7 @@ void HandleUpnpSetupWemo(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_SETUP)); -#if defined(USE_RULES_COMPRESSION) || defined(USE_SCRIPT_COMPRESSION) +#ifdef USE_UNISHOX_COMPRESSION String setup_xml = Decompress(WEMO_SETUP_XML, WEMO_SETUP_XML_SIZE); #else String setup_xml = FPSTR(WEMO_SETUP_XML); From 71d5ca5036536986569077b4b538514a585ce53c Mon Sep 17 00:00:00 2001 From: Staars Date: Sat, 6 Jun 2020 21:52:20 +0200 Subject: [PATCH 164/581] adding unishox compression to the webserver --- tasmota/xdrv_01_webserver.ino | 257 +++++++++++++++++++++++++++++++++- 1 file changed, 256 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 6bf15230e..7fcd82a9f 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -48,6 +48,47 @@ enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTASLAVE }; static const char * HEADER_KEYS[] = { "User-Agent", }; +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_JAVASCRIPT_ES6 +// insert D_HTML_LANGUAGE later +const size_t HTTP_HEADER1_SIZE = 377; +const char HTTP_HEADER1_COMPRESSED[] PROGMEM = "\x3D\x0F\xE1\x10\x98\x1D\x19\x0C\x64\x85\x50\xD0\x8F\xC3\xD0\x55\x0D\x09\x05\x7C" + "\x3C\x7C\x3F\xB2\xEC\xD7\xE6\x86\x7D\x78\xFE\xCB\xB3\x5F\x9A\x1A\x0C\x2B\xF7\x8F" + "\x87\xB0\xF6\x1F\x87\xA0\xA7\x62\x1F\x87\xA0\xD7\x56\x83\x15\x7F\xF3\xA3\xE1\xF6" + "\x2E\x8C\x1D\x67\x3E\x7D\x90\x21\x52\xEB\x1A\xCF\x87\xB0\xCF\x58\xF8\xCC\xFD\x1E" + "\xC4\x1E\x75\x3E\xA3\xE1\xEC\x1F\xD1\x28\x51\xF0\x46\x67\xA1\xB3\xAC\x7F\x44\xA1" + "\x47\x56\xF6\xD6\xD8\x47\x5F\x83\xB0\x99\xF0\xE4\x3A\x88\x5F\x9F\xCE\xBF\x07\x61" + "\x58\xE0\x99\xF3\xB0\xF6\x1D\x87\xE1\xE9\x5B\x41\x33\xF0\xFA\xF2\x3A\xD1\xF5\xE3" + "\xD0\xEC\x04\x19\x67\xA7\x83\xFE\x8C\xA3\xF0\xCE\xFE\x8D\x87\xCE\x16\x10\x47\x50" + "\x54\x75\x56\x1D\x54\x30\xEA\x18\x19\xF0\xFB\x3E\xCF\x0C\x71\xF3\xC7\xC3\xF0\x4C" + "\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35\xF5\x10\xE3\x22\xD1\x0E\xEF\x8E\xF1\xE0" + "\xD5\xE0\x48\xBA\x6A\x16\xFE\x64\x5E\x61\x30\xEB\x3E\x77\x7C\x77\x8F\x1E\x18\x7C" + "\xD3\xE1\xF8\xC7\x1D\xDD\x3B\xC7\x4A\x32\x18\xCF\x87\x74\x11\xA4\x1F\x0F\x87\xDD" + "\x33\x65\x1F\x67\x68\xFB\x19\x7E\xF0\xFE\x7C\x43\xEC\xF3\x04\x19\xC7\x78\xF0\x3E" + "\x11\xF0\xC1\xF0\xFC\x1F\xDE\x13\x07\xCE\x96\x20\x84\xCC\xDF\x51\x05\xBE\xA7\xCF" + "\xE7\x74\xFB\x0B\x2C\x43\xEC\xEA\x30\x77\x8F\x06"; +#define HTTP_HEADER1 Decompress(HTTP_HEADER1_COMPRESSED,HTTP_HEADER1_SIZE).c_str() +#else +const size_t HTTP_HEADER1_SIZE = 431; +const char HTTP_HEADER1_COMPRESSED[] PROGMEM = "\x3D\x0F\xE1\x10\x98\x1D\x19\x0C\x64\x85\x50\xD0\x8F\xC3\xD0\x55\x0D\x09\x05\x7C" + "\x3C\x7C\x3F\xB2\xEC\xD7\xE6\x86\x7D\x78\xFE\xCB\xB3\x5F\x9A\x1A\x0C\x2B\xF7\x8F" + "\x87\xB0\xF6\x1F\x87\xA0\xA7\x62\x1F\x87\xA0\xD7\x56\x83\x15\x7F\xF3\xA3\xE1\xF6" + "\x2E\x8C\x1D\x67\x3E\x7D\x90\x21\x52\xEB\x1A\xCF\x87\xB0\xCF\x58\xF8\xCC\xFD\x1E" + "\xC4\x1E\x75\x3E\xA3\xE1\xEC\x1F\xD1\x28\x51\xF0\x46\x67\xA1\xB3\xAC\x7F\x44\xA1" + "\x47\x56\xF6\xD6\xD8\x47\x5F\x83\xB0\x99\xF0\xE4\x3A\x88\x5F\x9F\xCE\xBF\x07\x61" + "\x58\xE0\x99\xF3\xB0\xF6\x1D\x87\xE1\xE9\x5B\x41\x33\xF0\xFA\xF2\x3A\xD1\xF5\xE3" + "\xD0\xEC\x04\x19\x67\xA7\x83\xFE\x8C\xA3\xF0\xCE\xFE\x8D\x87\xCE\x16\x10\x47\x50" + "\x54\x75\x56\x1D\x54\x30\xEA\x18\x19\xF0\xFB\x3E\xCF\x06\x05\xF0\x75\xB9\xC9\x8E" + "\x3B\xBE\x3B\xC7\xB7\xEE\x85\xFF\x90\x98\x18\xB1\xAF\xA8\xE8\x3C\xE8\x98\x4C\x6B" + "\xEA\x21\xC6\x45\xA2\x1D\xDF\x1D\xE3\xC1\xEE\x04\x4C\x38\xD5\xE0\x4F\xC3\x8D\x42" + "\xDF\xCC\x8B\xCC\x26\x1D\x67\xC1\x27\x0D\xF0\xC3\xBB\xA7\x78\xF6\xB1\xC7\x77\x4E" + "\xF1\xD2\x8C\x86\x33\xE1\xDD\x04\x69\x07\xC3\xE1\xF7\x4C\xD9\x47\xD9\xDA\x3E\xC6" + "\x5F\xBC\x3F\x9F\x10\xFB\x3C\xC1\x06\x70\x23\xE3\xE3\xE1\x1D\xD3\x07\x78\xF6\x8F" + "\xEF\x09\x83\xE7\x4B\x10\x42\x66\x6F\xA8\x82\xDF\x53\xE7\xF3\xBA\x7D\x85\x96\x21" + "\xF6\x75\x18\x3B\xC7\x83\xDC"; +#define HTTP_HEADER1 Decompress(HTTP_HEADER1_COMPRESSED,HTTP_HEADER1_SIZE).c_str() +#endif // USE_JAVASCRIPT_ES6 +#else const char HTTP_HEADER1[] PROGMEM = "" "" @@ -78,7 +119,8 @@ const char HTTP_HEADER1[] PROGMEM = "function wl(f){" // Execute multiple window.onload "window.addEventListener('load',f);" "}"; -#endif +#endif // USE_JAVASCRIPT_ES6 +#endif //USE_UNISHOX_COMPRESSION const char HTTP_SCRIPT_COUNTER[] PROGMEM = "var cn=180;" // seconds @@ -91,6 +133,58 @@ const char HTTP_SCRIPT_COUNTER[] PROGMEM = "}" "wl(u);"; +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SCRIPT_WEB_DISPLAY +const size_t HTTP_SCRIPT_ROOT_SIZE = 706; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x98\xF0\xA3\xE1\xC8\x78\x23\x02\xF8\x3A\xDC\xE4\x15\x9D\xD1\x87\x78" + "\xF6\x99\xDF\xD5\x9F\x0F\xB3\xEC\xF1\xA6\x0E\xE8\x56\x74\xBF\x8F\x0B\x1A\xFA\xBC" + "\x74\x09\xF0\xF5\x0A\x3E\x1F\x0E\x43\xBC\x7B\x4A\xCF\x83\x0F\x01\x84\xEF\xE5\x5A" + "\x35\xE0\xBA\x3B\xA1\x51\xDE\x3C\x1E\xED\x30\x77\x4D\x87\xF0\xF9\xC2\xC2\x08\xEF" + "\x1E\xD3\x61\xD2\xC7\x67\xE8\xEE\x9D\xE3\xC1\xEE\x36\x1F\x39\x8F\xA2\x36\x10\xD2" + "\x08\x85\x55\x0C\x2F\xB3\x50\xB7\xEA\x3B\xA7\x78\xF0\x6C\x3A\x67\x7D\xD8\x86\x5E" + "\xAB\xA6\x18\xAB\xE1\xE6\x7C\x04\x3D\xA0\xEE\x9D\xE3\xDB\xA6\x0E\xE9\xB0\xE9\xF7" + "\x62\x19\x17\xAA\xE9\x9F\x0F\x87\x30\xFD\x1F\xA2\x36\x1D\x3D\x57\x42\xFC\x7C\x3E" + "\x1C\xA6\xC8\x10\x78\x07\xF1\xF0\xD8\x74\xFB\xF0\xCC\xEF\x32\xA6\x6C\xA3\xA7\xD8" + "\xC0\xAC\x36\x77\x4E\xC3\xDB\x47\xB8\xEC\x1E\x3A\x8F\x61\xE9\x56\x38\x26\xBD\x46" + "\x41\x33\xE1\xF6\x3F\xA2\x50\xA3\xCC\xE4\x6C\xFA\x3E\x8F\xB3\xF0\xF6\x1D\xE2\x04" + "\x6C\x2B\xC0\x85\x85\x7C\xFC\x3D\x28\x50\x24\xD7\x1A\x08\x35\xCE\xCA\x14\x7E\x1E" + "\x94\x20\x24\xD8\x60\x87\x60\x43\xF0\xF4\x3B\x2B\xE0\x93\x64\x33\xDC\x76\x0F\x1D" + "\x47\xB0\xFA\x3E\x8F\xB3\xF0\xF4\x13\x4C\xC1\x0F\x60\xA6\x6C\xA3\xAE\xC2\xD1\xEE" + "\x3C\xC3\x7D\x4F\xE7\x83\x19\xD4\x75\x8F\xBD\x1E\x15\x47\x99\xEC\x3B\xC7\x86\x38" + "\xEE\x9F\x61\x1C\x87\xD9\xDE\x3A\x16\xF7\x3F\x90\xA2\xA2\x1A\x41\x1F\x3C\x78\x3D" + "\xC7\xB8\xF1\xA6\x11\xDD\xF9\x8F\x0A\x3B\xC8\xF6\x9B\x0E\x98\x31\xF1\xDD\x3E\xC8" + "\x78\x99\x51\xF6\x75\x1F\x67\x43\xB4\x34\xF8\x72\x1F\x67\x6C\xAC\xEA\xAF\x8B\x67" + "\x78\xF0\x6C\x3A\x79\xF0\x87\x74\xEF\x1E\x02\xA3\xE7\x9D\x02\x27\x20\x36\x75\x1F" + "\x42\x1D\xE3\xC1\xEE\x3D\xC0\x89\xCA\x77\x99\x9D\x9D\xD1\x97\xF3\xAB\x4C\xEF\xE7" + "\x78\xF6\x85\x67\x74\xFB\x3F\x5E\x33\x3E\x1F\x67\x6F\x4C\xEF\xE7\x6C\xFB\x3F\x67" + "\xD9\xDB\x19\x7F\x3B\xC7\x80\x46\xC3\x74\x12\x30\xD0\x42\xE6\x78\x14\xF1\x4F\x98" + "\xF0\xA3\xE1\xC6\x40\x8D\x8D\x8C\xF9\xDD\x30\x77\x8F\x6E\x98\x47\x74\xC1\xDE\x47" + "\xB4\x14\x37\xA0\x42\xCB\xCF\x72\x61\x79\xA3\xDA\x09\x9C\xE1\x02\x1E\x60\x7B\x8D"; +#define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() +#else +const size_t HTTP_SCRIPT_ROOT_SIZE = 486; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x59\xDD\x18\x77\x8F\x69\x9D\xFD\x59\xF0\xFB\x3E\xCF\x1A" + "\x60\xEE\x85\x67\x4B\xF8\xF0\xB1\xAF\xAB\xC7\x40\x9F\x0F\x50\xA3\xE1\xF0\xE4\x3B" + "\xC7\xB4\xAC\xF8\x30\xF0\x18\x4E\xFE\x55\xA3\x5E\x0B\xA3\xBA\x15\x1D\xE3\xC1\xEE" + "\xD3\x07\x74\xD8\x7F\x0F\x9C\x2C\x20\x8E\xF1\xED\x36\x1D\x2C\x76\x7E\x8E\xE9\xDE" + "\x3C\x1E\xE3\x61\xF3\x98\xFA\x23\x61\x0D\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3" + "\xBA\x77\x8F\x06\xC3\xA6\x77\xDD\x88\x65\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xDA" + "\x0E\xE9\xDE\x3D\xBA\x60\xEE\x9B\x0E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F" + "\xD1\xFA\x23\x61\xD3\xD5\x74\x2F\xC7\xC3\xE1\xCA\x6C\x81\x07\x80\x7F\x1F\x0D\x87" + "\x4F\xBF\x0C\xCE\xF3\x2A\x2B\x66\xCA\x3A\x7D\x8C\x0A\xC3\x67\x74\xEC\x3D\xB4\x7B" + "\x8E\xC1\xE3\xA8\xF6\x1E\x95\x63\x82\x6B\xD4\x64\x13\x3E\x1F\x63\xFA\x25\x0A\x3C" + "\xCE\x46\xCF\xA3\xE8\xFB\x3F\x0F\x61\xDE\x20\x46\xC2\xBC\x08\x58\x57\xCF\xC3\xD2" + "\x85\x02\x4D\x71\xA0\x83\x5C\xEC\xA1\x47\xE1\xE9\x42\x02\x4D\x86\x08\x76\x04\x3F" + "\x0F\x43\xB2\xBE\x09\x36\x43\x3D\xC7\x60\xF1\xD4\x7B\x0F\xA3\xE8\xFB\x3F\x0F\x41" + "\x34\xCC\x10\xF6\x0A\x66\xCA\x3A\xEC\x2D\x1E\xE3\xCC\x37\xD4\xFE\x78\x31\x9D\x47" + "\x58\xFB\xD1\xE1\x54\x79\x9E\xC3\xBC\x78\x63\x8E\xE9\xF6\x11\xC8\x7D\x9D\xE3\xA1" + "\x6F\x73\xF9\x0A\x2A\x2B\x21\xA4\x11\xF3\xC7\x83\xDC\x7B\x8F\x06\xC3\xA6\x0C\x7C" + "\x77\x4F\xB2\x1E\x26\x54\x7D\x9D\x47\xD9\xD0\xED\x0D\x3E\x1C\x87\xD9\xDB\x2B\x3A" + "\xAB\xE2\xD9\xDE\x3C\x1B\x0E\x9E\x7C\x21\xDD\x3B\xC7\x80\xA8\xF9\xE7\x40\x89\xC7" + "\xB5\x9D\x47\xD0\x87\x78\xF0\x7B\x8D"; +#define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() +#endif // USE_SCRIPT_WEB_DISPLAY +#else const char HTTP_SCRIPT_ROOT[] PROGMEM = #ifdef USE_SCRIPT_WEB_DISPLAY "var rfsh=1;" @@ -151,7 +245,22 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = "lt=setTimeout(la,%d);" // Settings.web_refresh "}"; #endif // USE_SCRIPT_WEB_DISPLAY +#endif //USE_UNISHOX_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_SCRIPT_ROOT_PART2_SIZE = 222; +const char HTTP_SCRIPT_ROOT_PART2_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x06\x77\x4C\xCE\xAD\x3A\x86\x1D\xE3\xDB\xA6\x0E\xEB\x1C" + "\x77\x4F\xBF\x1F\x67\x78\xEF\x1E\xDD\x30\x77\x4C\xCF\x87\xC3\xEC\x51\xF6\x7F\x8F" + "\xF1\x99\xF0\xF8\x7D\x88\x7D\x9D\xE3\xDA\x67\x7F\x5E\x08\xF8\xC7\x1D\xD3\xEF\xC1" + "\x1C\xC3\xEC\xEF\x1D\x08\xCE\xC2\x16\xCF\x2A\x01\x85\x87\x9D\x3D\x46\x41\x33\xA0" + "\xEB\x0C\xD0\x7B\xF8\x2F\x84\x3E\x1F\x61\x6F\x3B\xF9\xD6\x3D\xFB\x13\x5F\x51\xDD" + "\xAC\x5F\xD1\xE1\x54\x75\x7C\x78\x71\xDD\x3E\xCE\xDF\x82\x3B\x67\xD9\xF4\x7D\x1D" + "\x40\x89\x14\x10\xE2\x9D\xE3\xA8\x57\x82\x3B\xA7\xD9\xDB\x04\x1D\x14\xE5\x10\x21" + "\xE8\xA7\x6C\xFB\x3A\x8E\x46\xCF\xA3\xE8\xEA\xD6\x7D\x1F\x47\x78\xEF\x1F\x67\x83" + "\xDC\x7B\x88\x2B\x3B\xA7\xD9\xFA\x3E\xCE\xD9\x99\xDB\xD3\xB6\x7D\x9F\x0F\xB3\xB6" + "\x30\xEF\x1E\x0F\x70\xF8\x47\x74\x2B\x3B\xC7\x83"; +#define HTTP_SCRIPT_ROOT_PART2 Decompress(HTTP_SCRIPT_ROOT_PART2_COMPRESSED,HTTP_SCRIPT_ROOT_PART2_SIZE).c_str() +#else const char HTTP_SCRIPT_ROOT_PART2[] PROGMEM = "function lc(v,i,p){" "if(eb('s')){" // Check if Saturation is in DOM otherwise javascript fails on la() @@ -163,6 +272,7 @@ const char HTTP_SCRIPT_ROOT_PART2[] PROGMEM = "la('&'+v+i+'='+p);" "}" "wl(la);"; +#endif //USE_UNISHOX_COMPRESSION const char HTTP_SCRIPT_WIFI[] PROGMEM = "function c(l){" @@ -173,6 +283,42 @@ const char HTTP_SCRIPT_WIFI[] PROGMEM = const char HTTP_SCRIPT_RELOAD_TIME[] PROGMEM = "setTimeout(function(){location.href='.';},%d);"; +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_SCRIPT_CONSOL_SIZE = 853; +const char HTTP_SCRIPT_CONSOL_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x71\xF0\xE3\x3A\x8B\x44\x3E\x1C\x67\x82\x30\x2F\x83\xAD\xCE\x41\x1D" + "\xD1\x87\x78\xF6\x99\xDF\xD0\x67\x56\x1F\x0F\xB3\xEC\xEA\xA3\xC0\x61\x3B\xF9\x56" + "\x8D\x78\x2E\x8E\xE8\x54\x77\x8F\x14\x7C\x63\x8E\xE9\xF7\x47\x21\xF6\x77\x8F\x05" + "\xA6\x0E\xE8\xC3\xE1\xF0\xE4\x3B\xC7\xB4\x83\x3E\x31\xC7\x74\xFB\x0C\xE4\x3E\xCE" + "\xF1\xE0\xB0\xF8\x7D\x9F\xA0\xCE\x43\xE1\xF6\x76\xC9\xF0\x78\x23\x21\x65\xF2\xD2" + "\x0F\x06\x8C\xCE\x7D\x47\x74\x33\xA1\x9D\x84\x2D\x9D\xE3\xC0\x21\x45\x3E\x1F\x67" + "\xD9\xE2\x8E\x9E\x0F\xF8\x10\x45\x58\x30\xF8\x71\x11\xBD\x2A\x01\xF1\xEE\x3E\x02" + "\x35\x13\xC1\xEE\xD3\x07\x74\x11\xA6\x1F\x87\xCF\x71\xDE\x3D\xBA\x60\xEE\x9B\x0F" + "\xE1\xF3\x85\x84\x11\xDE\x3D\xA6\xC3\xA5\x8E\xCF\xD1\xDD\x3B\xC7\x83\xDC\x6C\x3E" + "\x73\x1F\x44\x6C\x21\xA4\x11\x0A\xAA\x18\x5F\x66\xA1\x6F\xD4\x77\x4E\xF1\xE0\xD8" + "\x74\xCE\xFB\xB1\x0C\xBD\x57\x4C\x31\x57\xC3\xCC\xF8\x08\x7C\x28\x1D\xD0\x41\xCA" + "\x8E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F\xD1\xFA\x23\x61\xD3\xD5\x74\x2F" + "\xC7\xC3\xE1\xCA\x6C\x81\x07\x87\x03\x69\xD4\x21\xE0\x43\xE1\xB0\xE9\xF7\xE1\x99" + "\xDE\x65\x4C\xD9\x47\x4F\x0C\x0B\x68\xEE\x9D\x87\xB8\xE4\x3B\x0E\xF1\xE0\xB4\x43" + "\xE0\x87\x4F\x0A\xD3\x14\x77\x4E\xF1\xE3\x4C\x1D\xD0\x44\x92\x7C\x3E\x1C\x67\x78" + "\xF6\x95\x02\x2F\x0A\x27\xB8\xDA\x09\x38\x29\xB4\xE8\x13\xE1\xEA\x14\x7E\x02\x2E" + "\x06\x76\xCF\x86\xD3\xC1\xEE\x05\xDE\x1E\x4F\x71\xE0\xD8\x74\xC1\x8F\x8E\xE9\xF6" + "\x43\xC4\xCA\x8F\xB3\xA8\xFB\x0F\xC7\x68\x33\x94\x7C\x3E\xCE\xD9\x68\x87\x6F\x0E" + "\xAA\xF8\xB6\x77\x8F\x06\xC3\xA7\x9F\x08\x77\x4E\xF1\xE0\xF7\x05\x47\xCF\x3A\x04" + "\x4E\x4A\x4E\xA3\xE8\x43\xBC\x78\xFB\xA1\x7F\xE4\x62\xC2\xF3\x3C\x1E\xE1\xF0\x8E" + "\xE8\x47\x78\xF0\x67\x7F\x42\x83\x3E\x1E\xF1\xEF\x9D\x41\xF0\x23\xF2\xF4\x28\xEE" + "\x9D\xE3\xDA\x08\x7C\xA2\x9D\x2C\x41\x09\x99\xBE\xA2\x0B\x7D\x4F\x9F\xCE\xE9\xF6" + "\x68\xCC\x84\xC1\xFE\x3E\xCE\xA0\x44\xE2\xDD\x82\x0F\x12\xA3\x81\x13\x97\xB3\xA8" + "\x33\xE3\x3A\x1A\x33\x22\x0F\x04\x67\x8D\x30\x77\x4E\x5F\xCF\x87\xC2\x0C\xFF\x1F" + "\xE3\x98\xCF\x87\xC2\x0C\xEF\x1E\xD1\xC7\x4B\x17\x58\x1E\x0D\x18\x13\xA6\x7C\x3E" + "\xF0\xC1\x83\xEC\xF0\x7B\x8E\x5F\xCF\x87\xC2\x0C\xED\x1D\xD3\xB6\x76\xC3\xE3\xF0" + "\x50\x60\x85\xC4\x31\xFA\x3F\x47\x74\x3E\x3E\x02\x24\xB3\xBC\x75\x0E\x04\x2E\x2E" + "\x85\x06\x7B\xC1\xF1\xD6\x72\x1E\xF9\xFE\x3F\xC7\xD9\xF6\x77\x8F\x3C\x67\xC3\xE1" + "\x06\x76\x8E\xE9\xC6\x7E\x1D\x67\x59\x07\xC0\x83\x88\x1C\x64\x0A\x78\x41\xC9\x67" + "\xC3\xE1\x06\x7E\x8F\xD1\xDD\x04\x4C\xC4\xFC\x39\x11\xFA\x3F\x44\x28\x33\xA0\xCC" + "\x18\x77\x4E\xF1\xD4\x28\x33\xA0\xBE\x04\x1E\x44\x01\x0B\x1C\x3B\xC7\x50\x7C\x7C" + "\x38\xCE\xF1\xEE\x3B\xC7\x83\xDC\x43\xE1\x1D\xD1\x47\x78\xF0"; +#define HTTP_SCRIPT_CONSOL Decompress(HTTP_SCRIPT_CONSOL_COMPRESSED,HTTP_SCRIPT_CONSOL_SIZE).c_str() +#else const char HTTP_SCRIPT_CONSOL[] PROGMEM = "var sn=0,id=0;" // Scroll position, Get most of weblog initially "function l(p){" // Console log and command service @@ -222,6 +368,7 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = "});" "}" "wl(h);"; // Add console command key eventlistener after name has been synced with id (= wl(jd)) +#endif //USE_UNISHOX_COMPRESSION const char HTTP_MODULE_TEMPLATE_REPLACE[] PROGMEM = "}2%d'>%s (%d}3"; // }2 and }3 are used in below os.replace @@ -231,6 +378,34 @@ const char HTTP_MODULE_TEMPLATE_REPLACE_INDEX[] PROGMEM = const char HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX[] PROGMEM = "}2%d'>%s}3"; // }2 and }3 are used in below os.replace +#if defined(USE_UNISHOX_COMPRESSION) && defined(ESP32) +// no compression on ESP8266, we would lose 16 bytes +const size_t HTTP_SCRIPT_MODULE_TEMPLATE_SIZE = 602; +const char HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED[] PROGMEM = "\x33\xBF\xAC\xF1\xD4\x2B\xC7\x83\x02\xF8\x3A\xDC\xE4\x1B\x3B\xBA\x75\x1A\x8E\xF1" + "\xED\x33\xBF\xAC\x3E\x09\x81\x8B\x1A\xFA\x8E\x81\xFD\xDD\x32\x61\x31\xAF\xA8\xEE" + "\x9F\x78\x32\xB7\x38\xFB\x3B\xC7\x8C\x3A\x53\x36\x51\x07\x9D\x4F\xA8\xF9\xA7\x83" + "\x51\xD2\xC6\x0C\x7C\x21\x06\x2B\x42\x10\xEE\xE1\xDE\x3C\x1E\xE0\x44\xCD\xB2\x8E" + "\xE8\xF1\xD5\xE0\x41\xCD\xAC\xF9\xE3\xF4\x71\x91\xB0\xC1\x86\x71\x9D\x44\x38\xF8" + "\x71\x9D\x44\x19\xD4\x30\xEA\x08\xEA\xA3\xE1\xAB\xC7\x74\xFB\x3C\x85\x1F\x67\x6C" + "\x78\xEF\x1D\x42\xCF\x9E\x3F\x47\x19\x1B\x0E\x37\x08\xC1\xE0\x23\xE5\x1D\x01\x07" + "\x4D\xF1\xD0\x27\xC3\xD4\x28\xF0\x63\x3E\x77\x74\xF8\x11\xE3\x4F\x1A\x75\x9D\x67" + "\x78\xF6\x8C\x04\x5B\xC7\xBD\xA7\x59\xC8\x7B\xE7\x42\x19\x7F\x7D\x45\xD8\x23\x3C" + "\x0C\x3A\x7D\x8D\xC3\x36\x08\x3B\x70\x24\xE0\x87\x78\xF0\x7B\x82\x3E\x0A\x04\xAC" + "\xC8\xE3\x3C\x16\x9E\x81\x1E\x34\xED\x9D\xB3\xBC\x7B\x43\x3E\x0A\xF1\xEF\x69\xEF" + "\x82\x17\x2A\x01\xE7\x8D\x30\x77\x6C\xF8\x7C\x0C\xEF\x1E\xD1\xC0\x89\x50\xE3\x70" + "\x8C\x1E\x07\x7D\xD9\xA1\xE0\xF7\x1E\xEF\x1F\x87\xE1\xF0\xE6\x90\x21\x64\x47\x21" + "\xE0\xB4\xF4\x3E\x0E\x04\x2C\x8D\x9D\xD3\xBB\xA7\xA1\xC8\xCE\xF1\xDA\x3B\xA7\xD9" + "\xDC\x3E\xCE\xD9\x69\xDE\x3C\xF4\xEA\xA3\xBC\x78\x3D\xCC\x71\xDD\x3E\xC5\x1F\x67" + "\x6C\x78\xEF\x1D\x0C\xEC\x21\x6C\xF8\x2C\xED\x9C\x87\x82\xA3\xA7\xA8\xC8\x26\x74" + "\x33\xDF\x68\xED\x0B\x68\xC8\xF8\x77\x47\x1F\x87\x19\xDE\x3B\x47\xD9\xF6\x79\x9F" + "\x64\x2B\x44\x11\xF1\xF6\x08\xDC\x58\xF8\xD0\xEE\xF8\xEA\x1E\x04\x3E\x42\xF3\xC7" + "\x4F\xB1\x81\x58\x6C\xEE\x9D\x87\xB8\xE5\x1D\x84\x3C\x75\x1E\xC3\xD0\x10\x78\x4B" + "\x40\x83\x9E\x9F\x67\xB0\xEF\x02\x35\xD3\x96\x76\x10\xF1\xD4\x7B\x0F\x43\xB0\x10" + "\x6F\x1F\x87\xB0\xEF\x1E\x18\xE3\xBA\x7D\x8F\x1F\x67\x6C\x78\xEF\x1D\x37\xB9\xFC" + "\x85\x15\x10\xD2\x08\xF9\x80\x8D\x48\x10\x72\x13\xBA\x3C\x7A\x1C\x48\xEF\x1D\xA2" + "\x04\x3E\x47\x4F\x3F\x1E\x34\xC0\x20\xD0\x3D\xA0\x85\xC9\xF9\xE0\xF7\x1E\xE3"; +#define HTTP_SCRIPT_MODULE_TEMPLATE Decompress(HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED,HTTP_SCRIPT_MODULE_TEMPLATE_SIZE).c_str() +#else const char HTTP_SCRIPT_MODULE_TEMPLATE[] PROGMEM = #ifdef ESP8266 "var os;" @@ -264,7 +439,25 @@ const char HTTP_SCRIPT_MODULE_TEMPLATE[] PROGMEM = "if(g<99){ot(g,s);}" "}"; #endif // ESP8266 - ESP32 +#endif //USE_UNISHOX_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_SCRIPT_TEMPLATE_SIZE = 303; +const char HTTP_SCRIPT_TEMPLATE_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x08\x77\x45\x9D\x46\x0E\xF1\xED\x33\xBF\xA3\x61\xF3\x98" + "\xFA\x23\x61\x0D\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3\xBA\x77\x8F\x06\xC3\xA6" + "\x77\xDD\x88\x65\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xC7\x4E\xE9\xDE\x3D\xBA\x60" + "\xEE\xD0\xAD\xF1\xD3\xEE\xC4\x32\x2F\x55\xD3\x3E\x1F\x0E\x61\xFA\x3F\x45\x42\xB7" + "\xC7\x4F\x55\xD0\xBF\x1F\x0F\x87\x29\xB3\xBC\x7B\x48\x10\x70\x43\xBC\x78\x3D\xC7" + "\xB8\xF0\x6C\x3A\x60\xC7\xC7\x74\xFB\x21\xE2\x65\x47\xD9\xD4\x2C\xEA\xAF\x8B\x67" + "\x78\xF0\x6C\x3A\x79\xF0\x87\x74\xEF\x1E\x0F\x71\x9D\xFD\x06\x78\x04\x4E\x2A\x01" + "\x4D\x87\x21\xDD\x21\xC0\x83\xBF\xE9\xD4\x6B\x3A\x87\x8E\xA3\x43\xAB\x0F\x18\x7C" + "\x1C\x74\xFB\xF0\xCC\xEF\x32\xA6\x6C\xA3\xA7\x86\x05\xB4\x77\x4E\xC3\xDC\x72\x1D" + "\x87\x78\xF0\x46\x87\xCC\x3A\x78\x56\x98\xA3\xBA\x77\x8F\x1A\x60\xEE\xB1\xC7\x74" + "\xFB\xF1\xC8\x7D\x9D\xE3\xA1\x19\xD8\x42\xD9\xF0\xF8\x7D\x9F\x67\x78\xF6\x82\x55" + "\x03\x43\xC1\xEE\x1E\x04\x5C\x44\x10\xB2\x93\xEC\xEA\x3E\xCE\xF1\xE3\x3C\x7C\x3D" + "\x86"; +#define HTTP_SCRIPT_TEMPLATE Decompress(HTTP_SCRIPT_TEMPLATE_COMPRESSED,HTTP_SCRIPT_TEMPLATE_SIZE).c_str() +#else const char HTTP_SCRIPT_TEMPLATE[] PROGMEM = "function ld(u,f){" "var x=new XMLHttpRequest();" @@ -286,6 +479,8 @@ const char HTTP_SCRIPT_TEMPLATE[] PROGMEM = "}" "g=o.shift().split(',');" // GPIO - Array separator "os=\""; // }2'0'>None (0)}3}2'17'>Button1 (17)}3... +#endif //USE_UNISHOX_COMPRESSION + const char HTTP_SCRIPT_TEMPLATE2[] PROGMEM = "j=0;" "for(i=0;i<" STR(MAX_USER_PINS) ";i++){" // Supports 13 GPIOs @@ -333,6 +528,19 @@ const char HTTP_SCRIPT_INFO_END[] PROGMEM = "}" "wl(i);"; +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_HEAD_LAST_SCRIPT_SIZE = 226; +const char HTTP_HEAD_LAST_SCRIPT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x46\xB1\x0E\xE9\xDE\x3D\xA6\x77\xF5\x47\xC3\x8C\xEA\x2D\x3E" + "\x09\x81\x8B\x1A\xFA\x8E\x86\xA1\x6F\xE6\x45\xE6\x13\x0E\xB3\xE5\x61\x04\x77\x4F" + "\xBD\xE1\x82\xE8\xEA\x1C\x2E\xAB\x38\xEA\xA6\x6C\xAB\xFB\xB3\xAB\xCC\x26\x1D\x1F" + "\x67\x78\xF0\x3E\x2B\x42\x67\x77\x4E\x81\x3E\x1E\xA1\x47\xE1\xF2\x8E\xF1\xED\xD3" + "\x07\x77\x4F\x7A\x8F\x7C\xEF\x1E\xDD\x3D\xEA\x3D\xF3\xDE\x3E\xFA\xC6\xB3\xEC\xF7" + "\xCF\x87\x77\x4F\x7A\x8F\x7C\xE8\x2A\x2B\xFC\x57\x55\xFD\x1C\x2E\x99\xDD\x3E\xF4" + "\x43\xEC\xEF\x1F\xA3\xF4\x77\x4F\xE0\x27\x57\xEB\x1A\xCF\xB3\xBC\x77\x8E\xF1\xDA" + "\x04\x1C\x87\x44\x3E\xCF\x7C\xF3\x04\x7C\xB0\xF0\x7B\xA8\xED\x9D\xB3\xC1\xEE\x3D" + "\xC3\xE1\x1D\xD3\x58\x87\x78\xF0\x7A\x1D\x9E\x0F\xFA\x32\x8F\xC3"; +#define HTTP_HEAD_LAST_SCRIPT Decompress(HTTP_HEAD_LAST_SCRIPT_COMPRESSED,HTTP_HEAD_LAST_SCRIPT_SIZE).c_str() +#else const char HTTP_HEAD_LAST_SCRIPT[] PROGMEM = "function jd(){" // Add label name='' based on provided id='' "var t=0,i=document.querySelectorAll('input,button,textarea,select');" @@ -345,7 +553,29 @@ const char HTTP_HEAD_LAST_SCRIPT[] PROGMEM = "}" "wl(jd);" // Add name='' to any id='' in input,button,textarea,select ""; +#endif //USE_UNISHOX_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_HEAD_STYLE1_SIZE = 591; +const char HTTP_HEAD_STYLE1_COMPRESSED[] PROGMEM = "\x3D\x3D\x46\x41\x33\xF0\x4D\x33\x3A\x8C\x6B\x08\x4F\x3A\x3A\xB7\x86\x0B\xA3\xAB" + "\xCC\x26\x1D\x1E\xD1\x96\x20\x9B\xC3\xC7\x99\xCD\x21\x86\xC3\xC1\x8C\xEA\x3A\xFD" + "\xA6\xD6\x79\x9C\x84\xC6\x9E\x0F\x70\x21\xE1\xA7\xB4\x75\x86\x68\x3D\xFC\x17\xC2" + "\x1E\x67\x91\xF4\x71\xF1\x1B\x0F\x07\xB8\x61\xED\x1B\x7F\x1E\xDE\x3C\xCE\x33\xA6" + "\x93\x1A\x8E\x33\xC1\xEE\x2D\xE1\x82\xE8\xF6\x8F\xE8\x94\x28\xF3\x39\x1B\x3E\x8F" + "\xA3\xC1\x0E\xC3\x61\xD7\xED\x36\xEF\x0F\x1E\x63\xB3\xE2\x3F\x9D\x63\xB0\xD8\x78" + "\x3A\xC7\xD8\xE3\x4D\xA3\xAC\x14\xAD\x0D\xC3\x68\x29\x57\x04\xCD\x84\x3C\x0B\x3E" + "\x08\x7B\x6E\xF0\xC1\x74\x7B\xD4\x64\x31\x9F\x03\x14\xC3\x34\x1D\x86\xC3\xDF\x04" + "\x1E\x11\x41\x06\x8F\xEC\x4D\xC3\xDF\x04\x3D\xF1\x8D\x3C\x02\x0F\x03\x87\x5F\xF4" + "\x78\x55\x1E\x67\x38\x86\x1B\x0F\x06\x6F\xF5\xA1\xD8\x47\x5D\x85\xA3\xDC\x79\x9D" + "\x67\x21\x0C\x04\x9C\xCF\xF7\xC3\xCC\x10\xF1\xE3\x89\x1F\x47\xD1\xE0\xF7\x10\x21" + "\x71\x3E\x09\x1C\x28\x82\xC7\x2A\x01\x54\xCD\x95\x7F\x76\x7B\x7E\xFD\xA6\xD6\x79" + "\x82\x1E\xA0\x78\x04\x2C\xC8\xE7\xCF\xA3\xE8\xF0\x42\x9E\x8F\x0A\xA3\xCC\xE5\xCF" + "\x90\xC3\x61\xE0\x11\xF8\xFA\xC3\x37\xF3\x01\x60\xF9\xE7\x62\xEB\x01\x6B\x45\x1D" + "\x82\x19\x1E\xDA\x66\xCA\x04\x2E\x0A\x83\x7D\x4F\xE0\x83\xC9\xE9\x8B\x1B\xA1\x19" + "\x1E\x66\x6F\xE2\x5F\x59\xD5\xEB\xEF\x1D\x7E\x7F\xD3\x2A\x01\x9B\x98\x1E\xEA\x10" + "\x11\x39\x7D\x38\xC8\x61\xB0\xF0\x7B\x8D"; +#define HTTP_HEAD_STYLE1 Decompress(HTTP_HEAD_STYLE1_COMPRESSED,HTTP_HEAD_STYLE1_SIZE).c_str() +#else const char HTTP_HEAD_STYLE1[] PROGMEM = "" @@ -847,7 +1098,11 @@ void WSContentStart_P(const char* title, bool auth) WSContentBegin(200, CT_HTML); if (title != nullptr) { +#ifdef USE_UNISHOX_COMPRESSION + WSContentSend_P(HTTP_HEADER1, D_HTML_LANGUAGE, SettingsText(SET_DEVICENAME), title); +#else WSContentSend_P(HTTP_HEADER1, SettingsText(SET_DEVICENAME), title); +#endif //USE_UNISHOX_COMPRESSION } } From 66679515053d907c7cd81234121a0bcb106df197 Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Sat, 6 Jun 2020 22:35:41 +0200 Subject: [PATCH 165/581] Working sample --- lib/LOLIN_HP303B/README.md | 4 + .../i2c_background/i2c_background.ino | 98 + .../examples/i2c_command/i2c_command.ino | 75 + .../examples/i2c_interrupt/i2c_interrupt.ino | 112 ++ lib/LOLIN_HP303B/keywords.txt | 26 + lib/LOLIN_HP303B/library.properties | 9 + lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp | 1668 +++++++++++++++++ lib/LOLIN_HP303B/src/LOLIN_HP303B.h | 144 ++ lib/LOLIN_HP303B/src/util/hp303b_consts.h | 258 +++ tasmota/support_features.ino | 4 +- tasmota/xsns_73_hp303b.ino | 161 ++ tools/decode-status.py | 2 +- 12 files changed, 2559 insertions(+), 2 deletions(-) create mode 100644 lib/LOLIN_HP303B/README.md create mode 100644 lib/LOLIN_HP303B/examples/i2c_background/i2c_background.ino create mode 100644 lib/LOLIN_HP303B/examples/i2c_command/i2c_command.ino create mode 100644 lib/LOLIN_HP303B/examples/i2c_interrupt/i2c_interrupt.ino create mode 100644 lib/LOLIN_HP303B/keywords.txt create mode 100644 lib/LOLIN_HP303B/library.properties create mode 100644 lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp create mode 100644 lib/LOLIN_HP303B/src/LOLIN_HP303B.h create mode 100644 lib/LOLIN_HP303B/src/util/hp303b_consts.h create mode 100644 tasmota/xsns_73_hp303b.ino diff --git a/lib/LOLIN_HP303B/README.md b/lib/LOLIN_HP303B/README.md new file mode 100644 index 000000000..24d6c2d1b --- /dev/null +++ b/lib/LOLIN_HP303B/README.md @@ -0,0 +1,4 @@ +# Arduino library for the HP303B +### Installation +- Clone this repository or download&unzip [zip file](https://github.com/wemos/LOLIN_HP303B_Library/archive/master.zip) into Arduino/libraries + diff --git a/lib/LOLIN_HP303B/examples/i2c_background/i2c_background.ino b/lib/LOLIN_HP303B/examples/i2c_background/i2c_background.ino new file mode 100644 index 000000000..1b9ae6e68 --- /dev/null +++ b/lib/LOLIN_HP303B/examples/i2c_background/i2c_background.ino @@ -0,0 +1,98 @@ +#include + +// HP303B Opject +LOLIN_HP303B HP303BPressureSensor = LOLIN_HP303B(); + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + //Call begin to initialize HP303BPressureSensor + //The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. + //HP303BPressureSensor.begin(Wire, 0x76); + //Use the commented line below instead to use the default I2C address. + HP303BPressureSensor.begin(); + + //temperature measure rate (value from 0 to 7) + //2^temp_mr temperature measurement results per second + int16_t temp_mr = 2; + //temperature oversampling rate (value from 0 to 7) + //2^temp_osr internal temperature measurements per result + //A higher value increases precision + int16_t temp_osr = 2; + //pressure measure rate (value from 0 to 7) + //2^prs_mr pressure measurement results per second + int16_t prs_mr = 2; + //pressure oversampling rate (value from 0 to 7) + //2^prs_osr internal pressure measurements per result + //A higher value increases precision + int16_t prs_osr = 2; + //startMeasureBothCont enables background mode + //temperature and pressure ar measured automatically + //High precision and hgh measure rates at the same time are not available. + //Consult Datasheet (or trial and error) for more information + int16_t ret = HP303BPressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); + //Use one of the commented lines below instead to measure only temperature or pressure + //int16_t ret = HP303BPressureSensor.startMeasureTempCont(temp_mr, temp_osr); + //int16_t ret = HP303BPressureSensor.startMeasurePressureCont(prs_mr, prs_osr); + + + if (ret != 0) + { + Serial.print("Init FAILED! ret = "); + Serial.println(ret); + } + else + { + Serial.println("Init complete!"); + } +} + + + +void loop() +{ + unsigned char pressureCount = 20; + int32_t pressure[pressureCount]; + unsigned char temperatureCount = 20; + int32_t temperature[temperatureCount]; + + //This function writes the results of continuous measurements to the arrays given as parameters + //The parameters temperatureCount and pressureCount should hold the sizes of the arrays temperature and pressure when the function is called + //After the end of the function, temperatureCount and pressureCount hold the numbers of values written to the arrays + //Note: The HP303B cannot save more than 32 results. When its result buffer is full, it won't save any new measurement results + int16_t ret = HP303BPressureSensor.getContResults(temperature, temperatureCount, pressure, pressureCount); + + if (ret != 0) + { + Serial.println(); + Serial.println(); + Serial.print("FAIL! ret = "); + Serial.println(ret); + } + else + { + Serial.println(); + Serial.println(); + Serial.print(temperatureCount); + Serial.println(" temperature values found: "); + for (int16_t i = 0; i < temperatureCount; i++) + { + Serial.print(temperature[i]); + Serial.println(" degrees of Celsius"); + } + + Serial.println(); + Serial.print(pressureCount); + Serial.println(" pressure values found: "); + for (int16_t i = 0; i < pressureCount; i++) + { + Serial.print(pressure[i]); + Serial.println(" Pascal"); + } + } + + //Wait some time, so that the HP303B can refill its buffer + delay(10000); +} diff --git a/lib/LOLIN_HP303B/examples/i2c_command/i2c_command.ino b/lib/LOLIN_HP303B/examples/i2c_command/i2c_command.ino new file mode 100644 index 000000000..e629f7d5f --- /dev/null +++ b/lib/LOLIN_HP303B/examples/i2c_command/i2c_command.ino @@ -0,0 +1,75 @@ +#include + +// HP303B Opject +LOLIN_HP303B HP303BPressureSensor; + + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + + //Call begin to initialize HP303BPressureSensor + //The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. + //HP303BPressureSensor.begin(Wire, 0x76); + //Use the commented line below instead of the one above to use the default I2C address. + //if you are using the Pressure 3 click Board, you need 0x76 + HP303BPressureSensor.begin(); + + Serial.println("Init complete!"); +} + + + +void loop() +{ + int32_t temperature; + int32_t pressure; + int16_t oversampling = 7; + int16_t ret; + Serial.println(); + + //lets the HP303B perform a Single temperature measurement with the last (or standard) configuration + //The result will be written to the paramerter temperature + //ret = HP303BPressureSensor.measureTempOnce(temperature); + //the commented line below does exactly the same as the one above, but you can also config the precision + //oversampling can be a value from 0 to 7 + //the HP303B will perform 2^oversampling internal temperature measurements and combine them to one result with higher precision + //measurements with higher precision take more time, consult datasheet for more information + ret = HP303BPressureSensor.measureTempOnce(temperature, oversampling); + + if (ret != 0) + { + //Something went wrong. + //Look at the library code for more information about return codes + Serial.print("FAIL! ret = "); + Serial.println(ret); + } + else + { + Serial.print("Temperature: "); + Serial.print(temperature); + Serial.println(" degrees of Celsius"); + } + + //Pressure measurement behaves like temperature measurement + //ret = HP303BPressureSensor.measurePressureOnce(pressure); + ret = HP303BPressureSensor.measurePressureOnce(pressure, oversampling); + if (ret != 0) + { + //Something went wrong. + //Look at the library code for more information about return codes + Serial.print("FAIL! ret = "); + Serial.println(ret); + } + else + { + Serial.print("Pressure: "); + Serial.print(pressure); + Serial.println(" Pascal"); + } + + //Wait some time + delay(500); +} diff --git a/lib/LOLIN_HP303B/examples/i2c_interrupt/i2c_interrupt.ino b/lib/LOLIN_HP303B/examples/i2c_interrupt/i2c_interrupt.ino new file mode 100644 index 000000000..d1221109b --- /dev/null +++ b/lib/LOLIN_HP303B/examples/i2c_interrupt/i2c_interrupt.ino @@ -0,0 +1,112 @@ +#include + +// HP303B Opject +LOLIN_HP303B HP303BPressureSensor = LOLIN_HP303B(); + +void onFifoFull(); + +const unsigned char pressureLength = 50; +unsigned char pressureCount = 0; +int32_t pressure[pressureLength]; +unsigned char temperatureCount = 0; +const unsigned char temperatureLength = 50; +int32_t temperature[temperatureLength]; + + + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + //Call begin to initialize HP303BPressureSensor + //The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. + //HP303BPressureSensor.begin(Wire, 0x76); + //Use the commented line below instead to use the default I2C address. + HP303BPressureSensor.begin(); + + int16_t ret = HP303BPressureSensor.setInterruptPolarity(1); + ret = HP303BPressureSensor.setInterruptSources(1, 0, 0); + //clear interrupt flag by reading + HP303BPressureSensor.getIntStatusFifoFull(); + + //initialization of Interrupt for Controller unit + //SDO pin of HP303B has to be connected with interrupt pin + int16_t interruptPin = 3; + pinMode(interruptPin, INPUT); + attachInterrupt(digitalPinToInterrupt(interruptPin), onFifoFull, RISING); + + //start of a continuous measurement just like before + int16_t temp_mr = 3; + int16_t temp_osr = 2; + int16_t prs_mr = 1; + int16_t prs_osr = 3; + ret = HP303BPressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); + if (ret != 0) + { + Serial.print("Init FAILED! ret = "); + Serial.println(ret); + } + else + { + Serial.println("Init complete!"); + } +} + + +void loop() +{ + //do other stuff + Serial.println("loop running"); + delay(500); + + + //if result arrays are full + //This could also be in the interrupt handler, but it would take too much time for a proper ISR + if (pressureCount == pressureLength && temperatureCount == temperatureLength) + { + //print results + Serial.println(); + Serial.println(); + Serial.print(temperatureCount); + Serial.println(" temperature values found: "); + for (int16_t i = 0; i < temperatureCount; i++) + { + Serial.print(temperature[i]); + Serial.println(" degrees of Celsius"); + } + Serial.println(); + Serial.print(pressureCount); + Serial.println(" pressure values found: "); + for (int16_t i = 0; i < pressureCount; i++) + { + Serial.print(pressure[i]); + Serial.println(" Pascal"); + } + Serial.println(); + Serial.println(); + //reset result counters + pressureCount = 0; + temperatureCount = 0; + } +} + + +//interrupt handler +void onFifoFull() +{ + //message for debugging + Serial.println("Interrupt handler called"); + + //clear interrupt flag by reading + HP303BPressureSensor.getIntStatusFifoFull(); + + //calculate the number of free indexes in the result arrays + unsigned char prs_freespace = pressureLength - pressureCount; + unsigned char temp_freespace = temperatureLength - temperatureCount; + //read the results from HP303B, new results will be added at the end of the arrays + HP303BPressureSensor.getContResults(&temperature[temperatureCount], temp_freespace, &pressure[pressureCount], prs_freespace); + //after reading the result counters are increased by the amount of new results + pressureCount += prs_freespace; + temperatureCount += temp_freespace; +} diff --git a/lib/LOLIN_HP303B/keywords.txt b/lib/LOLIN_HP303B/keywords.txt new file mode 100644 index 000000000..b283317f5 --- /dev/null +++ b/lib/LOLIN_HP303B/keywords.txt @@ -0,0 +1,26 @@ +####################################### +# Syntax Coloring Map For DHT12 +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +DHT12 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +get KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +cTemp LITERAL1 +fTemp LITERAL1 +humidity LITERAL1 + + + diff --git a/lib/LOLIN_HP303B/library.properties b/lib/LOLIN_HP303B/library.properties new file mode 100644 index 000000000..7f71ad2b2 --- /dev/null +++ b/lib/LOLIN_HP303B/library.properties @@ -0,0 +1,9 @@ +name=LOLIN_HP303B +version=1.0.0 +author=WEMOS.CC +maintainer=WEMOS.CC +sentence=Library for the HP303B.. +paragraph=LOLIN HP303B +category=Device Control +url=https://github.com/wemos/LOLIN_HP303B_Library +architectures=* diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp new file mode 100644 index 000000000..43fcd435e --- /dev/null +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp @@ -0,0 +1,1668 @@ +#include "LOLIN_HP303B.h" + + + +const int32_t LOLIN_HP303B::scaling_facts[HP303B__NUM_OF_SCAL_FACTS] + = {524288, 1572864, 3670016, 7864320, 253952, 516096, 1040384, 2088960}; + + + +//////// Constructor, Destructor, begin, end //////// + + +/** + * Standard Constructor + */ +LOLIN_HP303B::LOLIN_HP303B(void) +{ + //assume that initialization has failed before it has been done + m_initFail = 1U; +} + +/** + * Standard Destructor + */ +LOLIN_HP303B::~LOLIN_HP303B(void) +{ + end(); +} + + + +/** + * Standard I2C begin function + * + * &bus: I2CBus which connects MC to HP303B + * slaveAddress: Address of the HP303B (0x77 or 0x76) + */ +void LOLIN_HP303B::begin(TwoWire &bus, uint8_t slaveAddress) +{ + //this flag will show if the initialization was successful + m_initFail = 0U; + + //Set I2C bus connection + m_SpiI2c = 1U; + m_i2cbus = &bus; + m_slaveAddress = slaveAddress; + + // Init bus + m_i2cbus->begin(); + + delay(50); //startup time of HP303B + + init(); +} + +void LOLIN_HP303B::begin(uint8_t slaveAddress) +{ + begin(Wire,slaveAddress); +} + +/** + * SPI begin function for HP303B with 4-wire SPI + */ +void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect) +{ + begin(bus, chipSelect, 0U); +} + +/** + * Standard SPI begin function + * + * &bus: SPI bus which connects MC to HP303B + * chipSelect: Number of the CS line for the HP303B + * threeWire: 1 if HP303B is connected with 3-wire SPI + * 0 if HP303B is connected with 4-wire SPI (standard) + */ +void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) +{ + //this flag will show if the initialization was successful + m_initFail = 0U; + + //Set SPI bus connection + m_SpiI2c = 0U; + m_spibus = &bus; + m_chipSelect = chipSelect; + + // Init bus + m_spibus->begin(); + m_spibus->setDataMode(SPI_MODE3); + + pinMode(m_chipSelect, OUTPUT); + digitalWrite(m_chipSelect, HIGH); + + delay(50); //startup time of HP303B + + //switch to 3-wire mode if necessary + //do not use writeByteBitfield or check option to set SPI mode! + //Reading is not possible until SPI-mode is valid + if(threeWire) + { + m_threeWire = 1U; + if(writeByte(HP303B__REG_ADR_SPI3W, HP303B__REG_CONTENT_SPI3W)) + { + m_initFail = 1U; + return; + } + } + + init(); +} + +/** + * End function for HP303B + * Sets the sensor to idle mode + */ +void LOLIN_HP303B::end(void) +{ + standby(); +} + + +//////// Declaration of other public functions starts here //////// + + +/** + * returns the Product ID of the connected HP303B sensor + */ +uint8_t LOLIN_HP303B::getProductId(void) +{ + return m_productID; +} + +/** + * returns the Revision ID of the connected HP303B sensor + */ +uint8_t LOLIN_HP303B::getRevisionId(void) +{ + return m_revisionID; +} + +/** + * Sets the HP303B to standby mode + * + * returns: 0 on success + * -2 if object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::standby(void) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //set device to idling mode + int16_t ret = setOpMode(IDLE); + if(ret != HP303B__SUCCEEDED) + { + return ret; + } + //flush the FIFO + ret = writeByteBitfield(1U, HP303B__REG_INFO_FIFO_FL); + if(ret < 0) + { + return ret; + } + //disable the FIFO + ret = writeByteBitfield(0U, HP303B__REG_INFO_FIFO_EN); + return ret; +} + + +/** + * performs one temperature measurement and writes result to the given address + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * It will not be written if result==NULL + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measureTempOnce(int32_t &result) +{ + return measureTempOnce(result, m_tempOsr); +} + +/** + * performs one temperature measurement and writes result to the given address + * the desired precision can be set with oversamplingRate + * + * &result: reference to a 32-Bit signed Integer where the result will be written + * It will not be written if result==NULL + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurement + * If this value equals n, the HP303B will perform + * 2^n measurements and combine the results + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measureTempOnce(int32_t &result, uint8_t oversamplingRate) +{ + //Start measurement + int16_t ret = startMeasureTempOnce(oversamplingRate); + if(ret!=HP303B__SUCCEEDED) + { + return ret; + } + + //wait until measurement is finished + delay(calcBusyTime(0U, m_tempOsr)/HP303B__BUSYTIME_SCALING); + delay(HP303B__BUSYTIME_FAILSAFE); + + ret = getSingleResult(result); + if(ret!=HP303B__SUCCEEDED) + { + standby(); + } + return ret; +} + +/** + * starts a single temperature measurement + * + * returns: 0 on success + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::startMeasureTempOnce(void) +{ + return startMeasureTempOnce(m_tempOsr); +} + +/** + * starts a single temperature measurement + * The desired precision can be set with oversamplingRate + * + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurement + * If this value equals n, the HP303B will perform + * 2^n measurements and combine the results + * returns: 0 on success + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::startMeasureTempOnce(uint8_t oversamplingRate) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if(m_opMode!=IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + + if(oversamplingRate!=m_tempOsr) + { + //configuration of oversampling rate + if(configTemp(0U, oversamplingRate) != HP303B__SUCCEEDED) + { + return HP303B__FAIL_UNKNOWN; + } + } + + //set device to temperature measuring mode + return setOpMode(0U, 1U, 0U); +} + +/** + * performs one pressure measurement and writes result to the given address + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * It will not be written if result==NULL + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measurePressureOnce(int32_t &result) +{ + return measurePressureOnce(result, m_prsOsr); +} + +/** + * performs one pressure measurement and writes result to the given address + * the desired precision can be set with oversamplingRate + * + * &result: reference to a 32-Bit signed Integer where the result will be written + * It will not be written if result==NULL + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurement + * If this value equals n, the HP303B will perform + * 2^n measurements and combine the results + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measurePressureOnce(int32_t &result, uint8_t oversamplingRate) +{ + //start the measurement + int16_t ret = startMeasurePressureOnce(oversamplingRate); + if(ret != HP303B__SUCCEEDED) + { + return ret; + } + + //wait until measurement is finished + delay(calcBusyTime(0U, m_prsOsr)/HP303B__BUSYTIME_SCALING); + delay(HP303B__BUSYTIME_FAILSAFE); + + ret = getSingleResult(result); + if(ret!=HP303B__SUCCEEDED) + { + standby(); + } + return ret; +} + +/** + * starts a single pressure measurement + * + * returns: 0 on success + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::startMeasurePressureOnce(void) +{ + return startMeasurePressureOnce(m_prsOsr); +} + +/** + * starts a single pressure measurement + * The desired precision can be set with oversamplingRate + * + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurement + * If this value equals n, the HP303B will perform + * 2^n measurements and combine the results + * returns: 0 on success + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::startMeasurePressureOnce(uint8_t oversamplingRate) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if(m_opMode != IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + //configuration of oversampling rate, lowest measure rate to avoid conflicts + if(oversamplingRate != m_prsOsr) + { + if(configPressure(0U, oversamplingRate)) + { + return HP303B__FAIL_UNKNOWN; + } + } + //set device to pressure measuring mode + return setOpMode(0U, 0U, 1U); +} + +/** + * gets the result a single temperature or pressure measurement in °C or Pa + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * returns: 0 on success + * -4 if the HP303B is still busy + * -3 if the HP303B is not in command mode + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::getSingleResult(int32_t &result) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + + //read finished bit for current opMode + int16_t rdy; + switch(m_opMode) + { + case CMD_TEMP: //temperature + rdy = readByteBitfield(HP303B__REG_INFO_TEMP_RDY); + break; + case CMD_PRS: //pressure + rdy = readByteBitfield(HP303B__REG_INFO_PRS_RDY); + break; + default: //HP303B not in command mode + return HP303B__FAIL_TOOBUSY; + } + + //read new measurement result + switch(rdy) + { + case HP303B__FAIL_UNKNOWN: //could not read ready flag + return HP303B__FAIL_UNKNOWN; + case 0: //ready flag not set, measurement still in progress + return HP303B__FAIL_UNFINISHED; + case 1: //measurement ready, expected case + LOLIN_HP303B::Mode oldMode = m_opMode; + m_opMode = IDLE; //opcode was automatically reseted by HP303B + switch(oldMode) + { + case CMD_TEMP: //temperature + return getTemp(&result); //get and calculate the temperature value + case CMD_PRS: //pressure + return getPressure(&result); //get and calculate the pressure value + default: + return HP303B__FAIL_UNKNOWN; //should already be filtered above + } + } + return HP303B__FAIL_UNKNOWN; +} + +/** + * starts a continuous temperature measurement + * The desired precision can be set with oversamplingRate + * The desired number of measurements per second can be set with measureRate + * + * measureRate: a value from 0 to 7 that decides about + * the number of measurements per second + * If this value equals n, the HP303B will perform + * 2^n measurements per second + * oversamplingRate: a value from 0 to 7 that decides about + * the precision of the measurements + * If this value equals m, the HP303B will perform + * 2^m internal measurements and combine the results + * to one more exact measurement + * returns: 0 on success + * -4 if measureRate or oversamplingRate is too high + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + * NOTE: If measure rate is n and oversampling rate is m, + * the HP303B performs 2^(n+m) internal measurements per second. + * The HP303B cannot operate with high precision and high speed + * at the same time. + * Consult the datasheet for more information. + */ +int16_t LOLIN_HP303B::startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if(m_opMode != IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + //abort if speed and precision are too high + if(calcBusyTime(measureRate, oversamplingRate) >= HP303B__MAX_BUSYTIME) + { + return HP303B__FAIL_UNFINISHED; + } + //update precision and measuring rate + if(configTemp(measureRate, oversamplingRate)) + { + return HP303B__FAIL_UNKNOWN; + } + //enable result FIFO + if(writeByteBitfield(1U, HP303B__REG_INFO_FIFO_EN)) + { + return HP303B__FAIL_UNKNOWN; + } + //Start measuring in background mode + if(setOpMode(1U, 1U, 0U)) + { + return HP303B__FAIL_UNKNOWN; + } + return HP303B__SUCCEEDED; +} + + +/** + * starts a continuous temperature measurement + * The desired precision can be set with oversamplingRate + * The desired number of measurements per second can be set with measureRate + * + * measureRate: a value from 0 to 7 that decides about + * the number of measurements per second + * If this value equals n, the HP303B will perform + * 2^n measurements per second + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurements + * If this value equals m, the HP303B will perform + * 2^m internal measurements + * and combine the results to one more exact measurement + * returns: 0 on success + * -4 if measureRate or oversamplingRate is too high + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + * NOTE: If measure rate is n and oversampling rate is m, + * the HP303B performs 2^(n+m) internal measurements per second. + * The HP303B cannot operate with high precision and high speed + * at the same time. + * Consult the datasheet for more information. + */ +int16_t LOLIN_HP303B::startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if(m_opMode != IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + //abort if speed and precision are too high + if(calcBusyTime(measureRate, oversamplingRate) >= HP303B__MAX_BUSYTIME) + { + return HP303B__FAIL_UNFINISHED; + } + //update precision and measuring rate + if(configPressure(measureRate, oversamplingRate)) + return HP303B__FAIL_UNKNOWN; + //enable result FIFO + if(writeByteBitfield(1U, HP303B__REG_INFO_FIFO_EN)) + { + return HP303B__FAIL_UNKNOWN; + } + //Start measuring in background mode + if(setOpMode(1U, 0U, 1U)) + { + return HP303B__FAIL_UNKNOWN; + } + return HP303B__SUCCEEDED; +} + +/** + * starts a continuous temperature and pressure measurement + * The desired precision can be set with tempOsr and prsOsr + * The desired number of measurements per second can be set with tempMr and prsMr + * + * tempMr measure rate for temperature + * tempOsr oversampling rate for temperature + * prsMr measure rate for pressure + * prsOsr oversampling rate for pressure + * returns: 0 on success + * -4 if precision or speed is too high + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + * NOTE: High precision and speed for both temperature and pressure + * can not be reached at the same time. + * Estimated time for temperature and pressure measurement + * is the sum of both values. + * This sum must not be more than 1 second. + * Consult the datasheet for more information. + */ +int16_t LOLIN_HP303B::startMeasureBothCont(uint8_t tempMr, + uint8_t tempOsr, + uint8_t prsMr, + uint8_t prsOsr) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if(m_opMode!=IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + //abort if speed and precision are too high + if(calcBusyTime(tempMr, tempOsr) + calcBusyTime(prsMr, prsOsr)>=HP303B__MAX_BUSYTIME) + { + return HP303B__FAIL_UNFINISHED; + } + //update precision and measuring rate + if(configTemp(tempMr, tempOsr)) + { + return HP303B__FAIL_UNKNOWN; + } + //update precision and measuring rate + if(configPressure(prsMr, prsOsr)) + return HP303B__FAIL_UNKNOWN; + //enable result FIFO + if(writeByteBitfield(1U, HP303B__REG_INFO_FIFO_EN)) + { + return HP303B__FAIL_UNKNOWN; + } + //Start measuring in background mode + if(setOpMode(1U, 1U, 1U)) + { + return HP303B__FAIL_UNKNOWN; + } + return HP303B__SUCCEEDED; +} + +/** + * Gets the results from continuous measurements and writes them to given arrays + * + * *tempBuffer: The start address of the buffer where the temperature results + * are written + * If this is NULL, no temperature results will be written out + * &tempCount: This has to be a reference to a number which contains + * the size of the buffer for temperature results. + * When the function ends, it will contain + * the number of bytes written to the buffer + * *prsBuffer: The start address of the buffer where the pressure results + * are written + * If this is NULL, no pressure results will be written out + * &prsCount: This has to be a reference to a number which contains + * the size of the buffer for pressure results. + * When the function ends, it will contain + * the number of bytes written to the buffer + * returns: 0 on success + * -3 if HP303B is not in background mode + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::getContResults(int32_t *tempBuffer, + uint8_t &tempCount, + int32_t *prsBuffer, + uint8_t &prsCount) +{ + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in background mode + if(!(m_opMode & INVAL_OP_CONT_NONE)) + { + return HP303B__FAIL_TOOBUSY; + } + + //prepare parameters for buffer length and count + uint8_t tempLen = tempCount; + uint8_t prsLen = prsCount; + tempCount = 0U; + prsCount = 0U; + + //while FIFO is not empty + while(readByteBitfield(HP303B__REG_INFO_FIFO_EMPTY) == 0) + { + int32_t result; + //read next result from FIFO + int16_t type = getFIFOvalue(&result); + switch(type) + { + case 0: //temperature + //calculate compensated pressure value + result = calcTemp(result); + //if buffer exists and is not full + //write result to buffer and increase temperature result counter + if(tempBuffer != NULL) + { + if(tempCount> HP303B__REG_SHIFT_INT_EN_FIFO; + tempReady &= HP303B__REG_MASK_INT_EN_TEMP >> HP303B__REG_SHIFT_INT_EN_TEMP; + prsReady &= HP303B__REG_MASK_INT_EN_PRS >> HP303B__REG_SHIFT_INT_EN_PRS; + //read old value from register + int16_t regData = readByte(HP303B__REG_ADR_INT_EN_FIFO); + if(regData <0) + { + return HP303B__FAIL_UNKNOWN; + } + uint8_t toWrite = (uint8_t)regData; + //update FIFO enable bit + toWrite &= ~HP303B__REG_MASK_INT_EN_FIFO; //clear bit + toWrite |= fifoFull << HP303B__REG_SHIFT_INT_EN_FIFO; //set new bit + //update TempReady enable bit + toWrite &= ~HP303B__REG_MASK_INT_EN_TEMP; + toWrite |= tempReady << HP303B__REG_SHIFT_INT_EN_TEMP; + //update PrsReady enable bit + toWrite &= ~HP303B__REG_MASK_INT_EN_PRS; + toWrite |= prsReady << HP303B__REG_SHIFT_INT_EN_PRS; + //write updated value to register + return writeByte(HP303B__REG_ADR_INT_EN_FIFO, toWrite); +} + +/** + * Gets the interrupt status flag of the FIFO + * + * Returns: 1 if the FIFO is full and caused an interrupt + * 0 if the FIFO is not full or FIFO interrupt is disabled + * -1 on fail + */ +int16_t LOLIN_HP303B::getIntStatusFifoFull(void) +{ + return readByteBitfield(HP303B__REG_INFO_INT_FLAG_FIFO); +} + +/** + * Gets the interrupt status flag that indicates a finished temperature measurement + * + * Returns: 1 if a finished temperature measurement caused an interrupt + * 0 if there is no finished temperature measurement + * or interrupts are disabled + * -1 on fail + */ +int16_t LOLIN_HP303B::getIntStatusTempReady(void) +{ + return readByteBitfield(HP303B__REG_INFO_INT_FLAG_TEMP); +} + +/** + * Gets the interrupt status flag that indicates a finished pressure measurement + * + * Returns: 1 if a finished pressure measurement caused an interrupt + * 0 if there is no finished pressure measurement + * or interrupts are disabled + * -1 on fail + */ +int16_t LOLIN_HP303B::getIntStatusPrsReady(void) +{ + return readByteBitfield(HP303B__REG_INFO_INT_FLAG_PRS); +} + +/** + * Function to fix a hardware problem on some devices + * You have this problem if you measure a temperature which is too high (e.g. 60°C when temperature is around 20°C) + * Call correctTemp() directly after begin() to fix this issue + */ +int16_t LOLIN_HP303B::correctTemp(void) +{ + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + writeByte(0x0E, 0xA5); + writeByte(0x0F, 0x96); + writeByte(0x62, 0x02); + writeByte(0x0E, 0x00); + writeByte(0x0F, 0x00); + + //perform a first temperature measurement (again) + //the most recent temperature will be saved internally + //and used for compensation when calculating pressure + int32_t trash; + measureTempOnce(trash); + + return HP303B__SUCCEEDED; +} + + + +//////// Declaration of private functions starts here //////// + + +/** + * Initializes the sensor. + * This function has to be called from begin() + * and requires a valid bus initialization. + */ +void LOLIN_HP303B::init(void) +{ + int16_t prodId = readByteBitfield(HP303B__REG_INFO_PROD_ID); + if(prodId != HP303B__PROD_ID) + { + //Connected device is not a HP303B + m_initFail = 1U; + return; + } + m_productID = prodId; + + int16_t revId = readByteBitfield(HP303B__REG_INFO_REV_ID); + if(revId < 0) + { + m_initFail = 1U; + return; + } + m_revisionID = revId; + + //find out which temperature sensor is calibrated with coefficients... + int16_t sensor = readByteBitfield(HP303B__REG_INFO_TEMP_SENSORREC); + if(sensor < 0) + { + m_initFail = 1U; + return; + } + + //...and use this sensor for temperature measurement + m_tempSensor = sensor; + if(writeByteBitfield((uint8_t)sensor, HP303B__REG_INFO_TEMP_SENSOR) < 0) + { + m_initFail = 1U; + return; + } + + //read coefficients + if(readcoeffs() < 0) + { + m_initFail = 1U; + return; + } + + //set to standby for further configuration + standby(); + + //set measurement precision and rate to standard values; + configTemp(HP303B__TEMP_STD_MR, HP303B__TEMP_STD_OSR); + configPressure(HP303B__PRS_STD_MR, HP303B__PRS_STD_OSR); + + //perform a first temperature measurement + //the most recent temperature will be saved internally + //and used for compensation when calculating pressure + int32_t trash; + measureTempOnce(trash); + + //make sure the HP303B is in standby after initialization + standby(); + + // Fix IC with a fuse bit problem, which lead to a wrong temperature + // Should not affect ICs without this problem + correctTemp(); +} + + +/** + * reads the compensation coefficients from the HP303B + * this is called once from init(), which is called from begin() + * + * returns: 0 on success, -1 on fail + */ +int16_t LOLIN_HP303B::readcoeffs(void) +{ + uint8_t buffer[HP303B__REG_LEN_COEF]; + //read COEF registers to buffer + int16_t ret = readBlock(HP303B__REG_ADR_COEF, + HP303B__REG_LEN_COEF, + buffer); + //abort if less than REG_LEN_COEF bytes were read + if(ret < HP303B__REG_LEN_COEF) + { + return HP303B__FAIL_UNKNOWN; + } + + //compose coefficients from buffer content + m_c0Half = ((uint32_t)buffer[0] << 4) + | (((uint32_t)buffer[1] >> 4) & 0x0F); + //this construction recognizes non-32-bit negative numbers + //and converts them to 32-bit negative numbers with 2's complement + if(m_c0Half & ((uint32_t)1 << 11)) + { + m_c0Half -= (uint32_t)1 << 12; + } + //c0 is only used as c0*0.5, so c0_half is calculated immediately + m_c0Half = m_c0Half / 2U; + + //now do the same thing for all other coefficients + m_c1 = (((uint32_t)buffer[1] & 0x0F) << 8) | (uint32_t)buffer[2]; + if(m_c1 & ((uint32_t)1 << 11)) + { + m_c1 -= (uint32_t)1 << 12; + } + + m_c00 = ((uint32_t)buffer[3] << 12) + | ((uint32_t)buffer[4] << 4) + | (((uint32_t)buffer[5] >> 4) & 0x0F); + if(m_c00 & ((uint32_t)1 << 19)) + { + m_c00 -= (uint32_t)1 << 20; + } + + m_c10 = (((uint32_t)buffer[5] & 0x0F) << 16) + | ((uint32_t)buffer[6] << 8) + | (uint32_t)buffer[7]; + if(m_c10 & ((uint32_t)1<<19)) + { + m_c10 -= (uint32_t)1 << 20; + } + + m_c01 = ((uint32_t)buffer[8] << 8) + | (uint32_t)buffer[9]; + if(m_c01 & ((uint32_t)1 << 15)) + { + m_c01 -= (uint32_t)1 << 16; + } + + m_c11 = ((uint32_t)buffer[10] << 8) + | (uint32_t)buffer[11]; + if(m_c11 & ((uint32_t)1 << 15)) + { + m_c11 -= (uint32_t)1 << 16; + } + + m_c20 = ((uint32_t)buffer[12] << 8) + | (uint32_t)buffer[13]; + if(m_c20 & ((uint32_t)1 << 15)) + { + m_c20 -= (uint32_t)1 << 16; + } + + m_c21 = ((uint32_t)buffer[14] << 8) + | (uint32_t)buffer[15]; + if(m_c21 & ((uint32_t)1 << 15)) + { + m_c21 -= (uint32_t)1 << 16; + } + + m_c30 = ((uint32_t)buffer[16] << 8) + | (uint32_t)buffer[17]; + if(m_c30 & ((uint32_t)1 << 15)) + { + m_c30 -= (uint32_t)1 << 16; + } + + return HP303B__SUCCEEDED; +} + +/** + * Sets the Operation Mode of the HP303B + * + * background: determines the general behavior of the HP303B + * 0 enables command mode (only measure on commands) + * 1 enables background mode (continuous work in background) + * temperature: set 1 to measure temperature + * pressure: set 1 to measure pressure + * return: 0 on success, -1 on fail + * + * NOTE! + * You cannot set background to 1 without setting temperature and pressure + * You cannot set both temperature and pressure when background mode is disabled + */ +int16_t LOLIN_HP303B::setOpMode(uint8_t background, uint8_t temperature, uint8_t pressure) +{ + uint8_t opMode = (background & HP303B__LSB) << 2U + | (temperature & HP303B__LSB) << 1U + | (pressure & HP303B__LSB); + return setOpMode(opMode); +} + + +/** + * Sets the Operation Mode of the HP303B + * + * opMode: the new OpMode that has to be set + * return: 0 on success, -1 on fail + * + * NOTE! + * You cannot set background to 1 without setting temperature and pressure + * You cannot set both temperature and pressure when background mode is disabled + */ +int16_t LOLIN_HP303B::setOpMode(uint8_t opMode) +{ + //Filter irrelevant bits + opMode &= HP303B__REG_MASK_OPMODE >> HP303B__REG_SHIFT_OPMODE; + //Filter invalid OpModes + if(opMode == INVAL_OP_CMD_BOTH || opMode == INVAL_OP_CONT_NONE) + { + return HP303B__FAIL_UNKNOWN; + } + //Set OpMode + if(writeByte(HP303B__REG_ADR_OPMODE, opMode)) + { + return HP303B__FAIL_UNKNOWN; + } + m_opMode = (LOLIN_HP303B::Mode)opMode; + return HP303B__SUCCEEDED; +} + +/** + * Configures temperature measurement + * + * tempMr: the new measure rate for temperature + * This can be a value from 0U to 7U. + * Actual measure rate will be 2^tempMr, + * so this will be a value from 1 to 128. + * tempOsr: the new oversampling rate for temperature + * This can be a value from 0U to 7U. + * Actual measure rate will be 2^tempOsr, + * so this will be a value from 1 to 128. + * returns: 0 normally or -1 on fail + */ +int16_t LOLIN_HP303B::configTemp(uint8_t tempMr, uint8_t tempOsr) +{ + //mask parameters + tempMr &= HP303B__REG_MASK_TEMP_MR >> HP303B__REG_SHIFT_TEMP_MR; + tempOsr &= HP303B__REG_MASK_TEMP_OSR >> HP303B__REG_SHIFT_TEMP_OSR; + + //set config register according to parameters + uint8_t toWrite = tempMr << HP303B__REG_SHIFT_TEMP_MR; + toWrite |= tempOsr << HP303B__REG_SHIFT_TEMP_OSR; + //using recommended temperature sensor + toWrite |= HP303B__REG_MASK_TEMP_SENSOR + & (m_tempSensor << HP303B__REG_SHIFT_TEMP_SENSOR); + int16_t ret = writeByte(HP303B__REG_ADR_TEMP_MR, toWrite); + //abort immediately on fail + if(ret != HP303B__SUCCEEDED) + { + return HP303B__FAIL_UNKNOWN; + } + + //set TEMP SHIFT ENABLE if oversampling rate higher than eight(2^3) + if(tempOsr > HP303B__OSR_SE) + { + ret=writeByteBitfield(1U, HP303B__REG_INFO_TEMP_SE); + } + else + { + ret=writeByteBitfield(0U, HP303B__REG_INFO_TEMP_SE); + } + + if(ret == HP303B__SUCCEEDED) + { //save new settings + m_tempMr = tempMr; + m_tempOsr = tempOsr; + } + else + { + //try to rollback on fail avoiding endless recursion + //this is to make sure that shift enable and oversampling rate + //are always consistent + if(tempMr != m_tempMr || tempOsr != m_tempOsr) + { + configTemp(m_tempMr, m_tempOsr); + } + } + return ret; +} + +/** + * Configures pressure measurement + * + * prsMr: the new measure rate for pressure + * This can be a value from 0U to 7U. + * Actual measure rate will be 2^prs_mr, + * so this will be a value from 1 to 128. + * prsOs: the new oversampling rate for temperature + * This can be a value from 0U to 7U. + * Actual measure rate will be 2^prsOsr, + * so this will be a value from 1 to 128. + * returns: 0 normally or -1 on fail + */ +int16_t LOLIN_HP303B::configPressure(uint8_t prsMr, uint8_t prsOsr) +{ + //mask parameters + prsMr &= HP303B__REG_MASK_PRS_MR >> HP303B__REG_SHIFT_PRS_MR; + prsOsr &= HP303B__REG_MASK_PRS_OSR >> HP303B__REG_SHIFT_PRS_OSR; + + //set config register according to parameters + uint8_t toWrite = prsMr << HP303B__REG_SHIFT_PRS_MR; + toWrite |= prsOsr << HP303B__REG_SHIFT_PRS_OSR; + int16_t ret = writeByte(HP303B__REG_ADR_PRS_MR, toWrite); + //abort immediately on fail + if(ret != HP303B__SUCCEEDED) + { + return HP303B__FAIL_UNKNOWN; + } + + //set PM SHIFT ENABLE if oversampling rate higher than eight(2^3) + if(prsOsr > HP303B__OSR_SE) + { + ret = writeByteBitfield(1U, HP303B__REG_INFO_PRS_SE); + } + else + { + ret = writeByteBitfield(0U, HP303B__REG_INFO_PRS_SE); + } + + if(ret == HP303B__SUCCEEDED) + { //save new settings + m_prsMr = prsMr; + m_prsOsr = prsOsr; + } + else + { //try to rollback on fail avoiding endless recursion + //this is to make sure that shift enable and oversampling rate + //are always consistent + if(prsMr != m_prsMr || prsOsr != m_prsOsr) + { + configPressure(m_prsMr, m_prsOsr); + } + } + return ret; +} + +/** + * calculates the time that the HP303B needs for 2^mr measurements + * with an oversampling rate of 2^osr + * + * mr: Measure rate for temperature or pressure + * osr: Oversampling rate for temperature or pressure + * returns: time that the HP303B needs for this measurement + * a value of 10000 equals 1 second + * NOTE! The measurement time for temperature and pressure + * in sum must not be more than 1 second! + * Timing behavior of pressure and temperature sensors + * can be considered as equal. + */ +uint16_t LOLIN_HP303B::calcBusyTime(uint16_t mr, uint16_t osr) +{ + //mask parameters first + mr &= HP303B__REG_MASK_TEMP_MR >> HP303B__REG_SHIFT_TEMP_MR; + osr &= HP303B__REG_MASK_TEMP_OSR >> HP303B__REG_SHIFT_TEMP_OSR; + //formula from datasheet (optimized) + return ((uint32_t)20U << mr) + ((uint32_t)16U << (osr + mr)); +} + +/** + * Gets the next temperature measurement result in degrees of Celsius + * + * result: address where the result will be written + * returns: 0 on success + * -1 on fail; + */ +int16_t LOLIN_HP303B::getTemp(int32_t *result) +{ + uint8_t buffer[3] = {0}; + //read raw pressure data to buffer + + int16_t i = readBlock(HP303B__REG_ADR_TEMP, + HP303B__REG_LEN_TEMP, + buffer); + if(i != HP303B__REG_LEN_TEMP) + { + //something went wrong + return HP303B__FAIL_UNKNOWN; + } + + //compose raw temperature value from buffer + int32_t temp = (uint32_t)buffer[0] << 16 + | (uint32_t)buffer[1] << 8 + | (uint32_t)buffer[2]; + //recognize non-32-bit negative numbers + //and convert them to 32-bit negative numbers using 2's complement + if(temp & ((uint32_t)1 << 23)) + { + temp -= (uint32_t)1 << 24; + } + + //return temperature + *result = calcTemp(temp); + return HP303B__SUCCEEDED; +} + +/** + * Gets the next pressure measurement result in Pa + * + * result: address where the result will be written + * returns: 0 on success + * -1 on fail; + */ +int16_t LOLIN_HP303B::getPressure(int32_t *result) +{ + uint8_t buffer[3] = {0}; + //read raw pressure data to buffer + int16_t i = readBlock(HP303B__REG_ADR_PRS, + HP303B__REG_LEN_PRS, + buffer); + if(i != HP303B__REG_LEN_PRS) + { + //something went wrong + //negative pressure is not allowed + return HP303B__FAIL_UNKNOWN; + } + + //compose raw pressure value from buffer + int32_t prs = (uint32_t)buffer[0] << 16 + | (uint32_t)buffer[1] << 8 + | (uint32_t)buffer[2]; + //recognize non-32-bit negative numbers + //and convert them to 32-bit negative numbers using 2's complement + if(prs & ((uint32_t)1 << 23)) + { + prs -= (uint32_t)1 << 24; + } + + *result = calcPressure(prs); + return HP303B__SUCCEEDED; +} + +/** + * reads the next raw value from the HP303B FIFO + * + * value: address where the value will be written + * returns: -1 on fail + * 0 if result is a temperature raw value + * 1 if result is a pressure raw value + */ +int16_t LOLIN_HP303B::getFIFOvalue(int32_t* value) +{ + //abort on invalid argument + if(value == NULL) + { + return HP303B__FAIL_UNKNOWN; + } + + uint8_t buffer[HP303B__REG_LEN_PRS] = {0}; + //always read from pressure raw value register + int16_t i = readBlock(HP303B__REG_ADR_PRS, + HP303B__REG_LEN_PRS, + buffer); + if(i != HP303B__REG_LEN_PRS) + { + //something went wrong + //return error code + return HP303B__FAIL_UNKNOWN; + } + //compose raw pressure value from buffer + *value = (uint32_t)buffer[0] << 16 + | (uint32_t)buffer[1] << 8 + | (uint32_t)buffer[2]; + //recognize non-32-bit negative numbers + //and convert them to 32-bit negative numbers using 2's complement + if(*value & ((uint32_t)1 << 23)) + { + *value -= (uint32_t)1 << 24; + } + + //least significant bit shows measurement type + return buffer[2] & HP303B__LSB; +} + +/** + * Calculates a scaled and compensated pressure value from raw data + * raw: raw temperature value read from HP303B + * returns: temperature value in °C + */ +int32_t LOLIN_HP303B::calcTemp(int32_t raw) +{ + double temp = raw; + + //scale temperature according to scaling table and oversampling + temp /= scaling_facts[m_tempOsr]; + + //update last measured temperature + //it will be used for pressure compensation + m_lastTempScal = temp; + + //Calculate compensated temperature + temp = m_c0Half + m_c1 * temp; + + //return temperature + return (int32_t)temp; +} + +/** + * Calculates a scaled and compensated pressure value from raw data + * raw: raw pressure value read from HP303B + * returns: pressure value in Pa + */ +int32_t LOLIN_HP303B::calcPressure(int32_t raw) +{ + double prs = raw; + + //scale pressure according to scaling table and oversampling + prs /= scaling_facts[m_prsOsr]; + + //Calculate compensated pressure + prs = m_c00 + + prs * (m_c10 + prs * (m_c20 + prs * m_c30)) + + m_lastTempScal * (m_c01 + prs * (m_c11 + prs * m_c21)); + + //return pressure + return (int32_t)prs; +} + +/** + * reads a byte from HP303B + * + * regAdress: Address that has to be read + * returns: register content or -1 on fail + */ +int16_t LOLIN_HP303B::readByte(uint8_t regAddress) +{ + //delegate to specialized function if HP303B is connected via SPI + if(m_SpiI2c==0) + { + return readByteSPI(regAddress); + } + + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); + m_i2cbus->endTransmission(0); + //request 1 byte from slave + if(m_i2cbus->requestFrom(m_slaveAddress, 1U, 1U) > 0) + { + return m_i2cbus->read(); //return this byte on success + } + else + { + return HP303B__FAIL_UNKNOWN; //if 0 bytes were read successfully + } +} + +/** + * reads a byte from HP303B via SPI + * this function is automatically called by readByte + * if HP303B is connected via SPI + * + * regAdress: Address that has to be read + * returns: register content or -1 on fail + */ +int16_t LOLIN_HP303B::readByteSPI(uint8_t regAddress) +{ + //this function is only made for communication via SPI + if(m_SpiI2c != 0) + { + return HP303B__FAIL_UNKNOWN; + } + //mask regAddress + regAddress &= ~HP303B__SPI_RW_MASK; + //reserve and initialize bus + m_spibus->beginTransaction(SPISettings(HP303B__SPI_MAX_FREQ, + MSBFIRST, + SPI_MODE3)); + //enable ChipSelect for HP303B + digitalWrite(m_chipSelect, LOW); + //send address with read command to HP303B + m_spibus->transfer(regAddress | HP303B__SPI_READ_CMD); + //receive register content from HP303B + uint8_t ret = m_spibus->transfer(0xFF); //send a dummy byte while receiving + //disable ChipSelect for HP303B + digitalWrite(m_chipSelect, HIGH); + //close current SPI transaction + m_spibus->endTransaction(); + //return received data + return ret; +} + +/** + * reads a block from HP303B + * + * regAdress: Address that has to be read + * length: Length of data block + * buffer: Buffer where data will be stored + * returns: number of bytes that have been read successfully + * NOTE! This is not always equal to length + * due to rx-Buffer overflow etc. + */ +int16_t LOLIN_HP303B::readBlock(uint8_t regAddress, uint8_t length, uint8_t *buffer) +{ + //delegate to specialized function if HP303B is connected via SPI + if(m_SpiI2c == 0) + { + return readBlockSPI(regAddress, length, buffer); + } + //do not read if there is no buffer + if(buffer == NULL) + { + return 0; //0 bytes read successfully + } + + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); + m_i2cbus->endTransmission(0); + //request length bytes from slave + int16_t ret = m_i2cbus->requestFrom(m_slaveAddress, length, 1U); + //read all received bytes to buffer + for(int16_t count = 0; count < ret; count++) + { + buffer[count] = m_i2cbus->read(); + } + return ret; +} + +/** + * reads a block from HP303B via SPI + * + * regAdress: Address that has to be read + * length: Length of data block + * readbuffer: Buffer where data will be stored + * returns: number of bytes that have been read successfully + * NOTE! This is not always equal to length + * due to rx-Buffer overflow etc. + */ +int16_t LOLIN_HP303B::readBlockSPI(uint8_t regAddress, uint8_t length, uint8_t *buffer) +{ + //this function is only made for communication via SPI + if(m_SpiI2c != 0) + { + return HP303B__FAIL_UNKNOWN; + } + //do not read if there is no buffer + if(buffer == NULL) + { + return 0; //0 bytes were read successfully + } + //mask regAddress + regAddress &= ~HP303B__SPI_RW_MASK; + //reserve and initialize bus + m_spibus->beginTransaction(SPISettings(HP303B__SPI_MAX_FREQ, + MSBFIRST, + SPI_MODE3)); + //enable ChipSelect for HP303B + digitalWrite(m_chipSelect, LOW); + //send address with read command to HP303B + m_spibus->transfer(regAddress | HP303B__SPI_READ_CMD); + + //receive register contents from HP303B + for(uint8_t count = 0; count < length; count++) + { + buffer[count] = m_spibus->transfer(0xFF);//send a dummy byte while receiving + } + + //disable ChipSelect for HP303B + digitalWrite(m_chipSelect, HIGH); + //close current SPI transaction + m_spibus->endTransaction(); + //return received data + return length; +} + +/** + * writes a given byte to a given register of HP303B without checking + * + * regAdress: Address of the register that has to be updated + * data: Byte that will be written to the register + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByte(uint8_t regAddress, uint8_t data) +{ + return writeByte(regAddress, data, 0U); +} + +/** + * writes a given byte to a given register of HP303B + * + * regAdress: Address of the register that has to be updated + * data: Byte that will be written to the register + * check: If this is true, register content will be read after writing + * to check if update was successful + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByte(uint8_t regAddress, uint8_t data, uint8_t check) +{ + //delegate to specialized function if HP303B is connected via SPI + if(m_SpiI2c==0) + { + return writeByteSpi(regAddress, data, check); + } + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); //Write Register number to buffer + m_i2cbus->write(data); //Write data to buffer + if(m_i2cbus->endTransmission() != 0) //Send buffer content to slave + { + return HP303B__FAIL_UNKNOWN; + } + else + { + if(check == 0) return 0; //no checking + if(readByte(regAddress) == data) //check if desired by calling function + { + return HP303B__SUCCEEDED; + } + else + { + return HP303B__FAIL_UNKNOWN; + } + } +} + +/** + * writes a given byte to a given register of HP303B via SPI + * + * regAdress: Address of the register that has to be updated + * data: Byte that will be written to the register + * check: If this is true, register content will be read after writing + * to check if update was successful + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check) +{ + //this function is only made for communication via SPI + if(m_SpiI2c != 0) + { + return HP303B__FAIL_UNKNOWN; + } + //mask regAddress + regAddress &= ~HP303B__SPI_RW_MASK; + //reserve and initialize bus + m_spibus->beginTransaction(SPISettings(HP303B__SPI_MAX_FREQ, + MSBFIRST, + SPI_MODE3)); + //enable ChipSelect for HP303B + digitalWrite(m_chipSelect, LOW); + //send address with read command to HP303B + m_spibus->transfer(regAddress | HP303B__SPI_WRITE_CMD); + + //write register content from HP303B + m_spibus->transfer(data); + + //disable ChipSelect for HP303B + digitalWrite(m_chipSelect, HIGH); + //close current SPI transaction + m_spibus->endTransaction(); + + //check if necessary + if(check == 0) + { + //no checking necessary + return HP303B__SUCCEEDED; + } + //checking necessary + if(readByte(regAddress) == data) + { + //check passed + return HP303B__SUCCEEDED; + } + else + { + //check failed + return HP303B__FAIL_UNKNOWN; + } +} + +/** + * updates some given bits of a given register of HP303B without checking + * + * regAdress: Address of the register that has to be updated + * data: BitValues that will be written to the register + * shift: Amount of bits the data byte is shifted (left) before being masked + * mask: Masks the bits of the register that have to be updated + * Bits with value 1 are updated + * Bits with value 0 are not changed + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByteBitfield(uint8_t data, + uint8_t regAddress, + uint8_t mask, + uint8_t shift) +{ + return writeByteBitfield(data, regAddress, mask, shift, 0U); +} + +/** + * updates some given bits of a given register of HP303B + * + * regAdress: Address of the register that has to be updated + * data: BitValues that will be written to the register + * shift: Amount of bits the data byte is shifted (left) before being masked + * mask: Masks the bits of the register that have to be updated + * Bits with value 1 are updated + * Bits with value 0 are not changed + * check: enables/disables check after writing + * 0 disables check + * if check fails, -1 will be returned + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByteBitfield(uint8_t data, + uint8_t regAddress, + uint8_t mask, + uint8_t shift, + uint8_t check) +{ + int16_t old = readByte(regAddress); + if(old < 0) + { + //fail while reading + return old; + } + return writeByte(regAddress, ((uint8_t)old & ~mask)|((data << shift) & mask), check); +} + +/** + * reads some given bits of a given register of HP303B + * + * regAdress: Address of the register that has to be updated + * mask: Masks the bits of the register that have to be updated + * Bits masked with value 1 are read + * Bits masked with value 0 are set 0 + * shift: Amount of bits the data byte is shifted (right) after being masked + * return: read and processed bits + * or -1 on fail + */ +int16_t LOLIN_HP303B::readByteBitfield(uint8_t regAddress, uint8_t mask, uint8_t shift) +{ + int16_t ret = readByte(regAddress); + if(ret<0) + { + return ret; + } + return (((uint8_t)ret) & mask) >> shift; +} diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h new file mode 100644 index 000000000..f9c54e356 --- /dev/null +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h @@ -0,0 +1,144 @@ +#ifndef __LOLIN_HP303B_H +#define __LOLIN_HP303B_H + +#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#include +#include +#include "util/hp303b_consts.h" + +class LOLIN_HP303B +{ +public: + //constructor + LOLIN_HP303B(void); + //destructor + ~LOLIN_HP303B(void); + //begin + void begin(TwoWire &bus, uint8_t slaveAddress); + void begin(uint8_t slaveAddress=HP303B__STD_SLAVE_ADDRESS); + void begin(SPIClass &bus, int32_t chipSelect); + void begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire); + //end + void end(void); + + //general + uint8_t getProductId(void); + uint8_t getRevisionId(void); + + //Idle Mode + int16_t standby(void); + + //Command Mode + int16_t measureTempOnce(int32_t &result); + int16_t measureTempOnce(int32_t &result, uint8_t oversamplingRate); + int16_t startMeasureTempOnce(void); + int16_t startMeasureTempOnce(uint8_t oversamplingRate); + int16_t measurePressureOnce(int32_t &result); + int16_t measurePressureOnce(int32_t &result, uint8_t oversamplingRate); + int16_t startMeasurePressureOnce(void); + int16_t startMeasurePressureOnce(uint8_t oversamplingRate); + int16_t getSingleResult(int32_t &result); + + //Background Mode + int16_t startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate); + int16_t startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate); + int16_t startMeasureBothCont(uint8_t tempMr, uint8_t tempOsr, uint8_t prsMr, uint8_t prsOsr); + int16_t getContResults(int32_t *tempBuffer, uint8_t &tempCount, int32_t *prsBuffer, uint8_t &prsCount); + + //Interrupt Control + int16_t setInterruptPolarity(uint8_t polarity); + int16_t setInterruptSources(uint8_t fifoFull, uint8_t tempReady, uint8_t prsReady); + int16_t getIntStatusFifoFull(void); + int16_t getIntStatusTempReady(void); + int16_t getIntStatusPrsReady(void); + + //function to fix a hardware problem on some devices + int16_t correctTemp(void); + +private: + //scaling factor table + static const int32_t scaling_facts[HP303B__NUM_OF_SCAL_FACTS]; + + //enum for operating mode + enum Mode + { + IDLE = 0x00, + CMD_PRS = 0x01, + CMD_TEMP = 0x02, + INVAL_OP_CMD_BOTH = 0x03, //invalid + INVAL_OP_CONT_NONE = 0x04, //invalid + CONT_PRS = 0x05, + CONT_TMP = 0x06, + CONT_BOTH = 0x07 + }; + Mode m_opMode; + + //flags + uint8_t m_initFail; + uint8_t m_productID; + uint8_t m_revisionID; + + //settings + uint8_t m_tempMr; + uint8_t m_tempOsr; + uint8_t m_prsMr; + uint8_t m_prsOsr; + uint8_t m_tempSensor; + + //compensation coefficients + int32_t m_c0Half; + int32_t m_c1; + int32_t m_c00; + int32_t m_c10; + int32_t m_c01; + int32_t m_c11; + int32_t m_c20; + int32_t m_c21; + int32_t m_c30; + //last measured scaled temperature + //(necessary for pressure compensation) + double m_lastTempScal; + + //bus specific + uint8_t m_SpiI2c; //0=SPI, 1=I2C + //used for I2C + TwoWire *m_i2cbus; + uint8_t m_slaveAddress; + //used for SPI + SPIClass *m_spibus; + int32_t m_chipSelect; + uint8_t m_threeWire; + + //measurement + void init(void); + int16_t readcoeffs(void); + int16_t setOpMode(uint8_t background, uint8_t temperature, uint8_t pressure); + int16_t setOpMode(uint8_t opMode); + int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr); + int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr); + uint16_t calcBusyTime(uint16_t temp_rate, uint16_t temp_osr); + int16_t getTemp(int32_t *result); + int16_t getPressure(int32_t *result); + int16_t getFIFOvalue(int32_t *value); + int32_t calcTemp(int32_t raw); + int32_t calcPressure(int32_t raw); + + //bus specific + int16_t readByte(uint8_t regAddress); + int16_t readByteSPI(uint8_t regAddress); + int16_t readBlock(uint8_t regAddress, uint8_t length, uint8_t *buffer); + int16_t readBlockSPI(uint8_t regAddress, uint8_t length, uint8_t *readbuffer); + int16_t writeByte(uint8_t regAddress, uint8_t data); + int16_t writeByte(uint8_t regAddress, uint8_t data, uint8_t check); + int16_t writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check); + int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift); + int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift, uint8_t check); + int16_t readByteBitfield(uint8_t regAddress, uint8_t mask, uint8_t shift); +}; + +#endif diff --git a/lib/LOLIN_HP303B/src/util/hp303b_consts.h b/lib/LOLIN_HP303B/src/util/hp303b_consts.h new file mode 100644 index 000000000..f93629e93 --- /dev/null +++ b/lib/LOLIN_HP303B/src/util/hp303b_consts.h @@ -0,0 +1,258 @@ +/** + * + * + */ + +#ifndef __HP303B_CONSTS_H_ +#define __HP303B_CONSTS_H_ + + + //general Constants +#define HP303B__PROD_ID 0U +#define HP303B__STD_SLAVE_ADDRESS 0x77U +#define HP303B__SPI_WRITE_CMD 0x00U +#define HP303B__SPI_READ_CMD 0x80U +#define HP303B__SPI_RW_MASK 0x80U +#define HP303B__SPI_MAX_FREQ 100000U + +#define HP303B__LSB 0x01U + +#define HP303B__TEMP_STD_MR 2U +#define HP303B__TEMP_STD_OSR 3U +#define HP303B__PRS_STD_MR 2U +#define HP303B__PRS_STD_OSR 3U +#define HP303B__OSR_SE 3U +//we use 0.1 mS units for time calculations, so 10 units are one millisecond +#define HP303B__BUSYTIME_SCALING 10U +// DPS310 has 10 milliseconds of spare time for each synchronous measurement / per second for asynchronous measurements +// this is for error prevention on friday-afternoon-products :D +// you can set it to 0 if you dare, but there is no warranty that it will still work +#define HP303B__BUSYTIME_FAILSAFE 10U +#define HP303B__MAX_BUSYTIME ((1000U-HP303B__BUSYTIME_FAILSAFE)*HP303B__BUSYTIME_SCALING) +#define HP303B__NUM_OF_SCAL_FACTS 8 + +#define HP303B__SUCCEEDED 0 +#define HP303B__FAIL_UNKNOWN -1 +#define HP303B__FAIL_INIT_FAILED -2 +#define HP303B__FAIL_TOOBUSY -3 +#define HP303B__FAIL_UNFINISHED -4 + + + //Constants for register manipulation + //SPI mode (3 or 4 wire) +#define HP303B__REG_ADR_SPI3W 0x09U +#define HP303B__REG_CONTENT_SPI3W 0x01U + + + //product id +#define HP303B__REG_INFO_PROD_ID HP303B__REG_ADR_PROD_ID, \ + HP303B__REG_MASK_PROD_ID, \ + HP303B__REG_SHIFT_PROD_ID +#define HP303B__REG_ADR_PROD_ID 0x0DU +#define HP303B__REG_MASK_PROD_ID 0x0FU +#define HP303B__REG_SHIFT_PROD_ID 0U + + //revision id +#define HP303B__REG_INFO_REV_ID HP303B__REG_ADR_REV_ID, \ + HP303B__REG_MASK_REV_ID, \ + HP303B__REG_SHIFT_REV_ID +#define HP303B__REG_ADR_REV_ID 0x0DU +#define HP303B__REG_MASK_REV_ID 0xF0U +#define HP303B__REG_SHIFT_REV_ID 4U + + //operating mode +#define HP303B__REG_INFO_OPMODE HP303B__REG_ADR_OPMODE, \ + HP303B__REG_MASK_OPMODE, \ + HP303B__REG_SHIFT_OPMODE +#define HP303B__REG_ADR_OPMODE 0x08U +#define HP303B__REG_MASK_OPMODE 0x07U +#define HP303B__REG_SHIFT_OPMODE 0U + + + //temperature measure rate +#define HP303B__REG_INFO_TEMP_MR HP303B__REG_ADR_TEMP_MR, \ + HP303B__REG_MASK_TEMP_MR, \ + HP303B__REG_SHIFT_TEMP_MR +#define HP303B__REG_ADR_TEMP_MR 0x07U +#define HP303B__REG_MASK_TEMP_MR 0x70U +#define HP303B__REG_SHIFT_TEMP_MR 4U + + //temperature oversampling rate +#define HP303B__REG_INFO_TEMP_OSR HP303B__REG_ADR_TEMP_OSR, \ + HP303B__REG_MASK_TEMP_OSR, \ + HP303B__REG_SHIFT_TEMP_OSR +#define HP303B__REG_ADR_TEMP_OSR 0x07U +#define HP303B__REG_MASK_TEMP_OSR 0x07U +#define HP303B__REG_SHIFT_TEMP_OSR 0U + + //temperature sensor +#define HP303B__REG_INFO_TEMP_SENSOR HP303B__REG_ADR_TEMP_SENSOR, \ + HP303B__REG_MASK_TEMP_SENSOR, \ + HP303B__REG_SHIFT_TEMP_SENSOR +#define HP303B__REG_ADR_TEMP_SENSOR 0x07U +#define HP303B__REG_MASK_TEMP_SENSOR 0x80U +#define HP303B__REG_SHIFT_TEMP_SENSOR 7U + + //temperature sensor recommendation +#define HP303B__REG_INFO_TEMP_SENSORREC HP303B__REG_ADR_TEMP_SENSORREC, \ + HP303B__REG_MASK_TEMP_SENSORREC, \ + HP303B__REG_SHIFT_TEMP_SENSORREC +#define HP303B__REG_ADR_TEMP_SENSORREC 0x28U +#define HP303B__REG_MASK_TEMP_SENSORREC 0x80U +#define HP303B__REG_SHIFT_TEMP_SENSORREC 7U + + //temperature shift enable (if temp_osr>3) +#define HP303B__REG_INFO_TEMP_SE HP303B__REG_ADR_TEMP_SE, \ + HP303B__REG_MASK_TEMP_SE, \ + HP303B__REG_SHIFT_TEMP_SE +#define HP303B__REG_ADR_TEMP_SE 0x09U +#define HP303B__REG_MASK_TEMP_SE 0x08U +#define HP303B__REG_SHIFT_TEMP_SE 3U + + + //pressure measure rate +#define HP303B__REG_INFO_PRS_MR HP303B__REG_ADR_PRS_MR, \ + HP303B__REG_MASK_PRS_MR, \ + HP303B__REG_SHIFT_PRS_MR +#define HP303B__REG_ADR_PRS_MR 0x06U +#define HP303B__REG_MASK_PRS_MR 0x70U +#define HP303B__REG_SHIFT_PRS_MR 4U + + //pressure oversampling rate +#define HP303B__REG_INFO_PRS_OSR HP303B__REG_ADR_PRS_OSR, \ + HP303B__REG_MASK_PRS_OSR, \ + HP303B__REG_SHIFT_PRS_OSR +#define HP303B__REG_ADR_PRS_OSR 0x06U +#define HP303B__REG_MASK_PRS_OSR 0x07U +#define HP303B__REG_SHIFT_PRS_OSR 0U + + //pressure shift enable (if prs_osr>3) +#define HP303B__REG_INFO_PRS_SE HP303B__REG_ADR_PRS_SE, \ + HP303B__REG_MASK_PRS_SE, \ + HP303B__REG_SHIFT_PRS_SE +#define HP303B__REG_ADR_PRS_SE 0x09U +#define HP303B__REG_MASK_PRS_SE 0x04U +#define HP303B__REG_SHIFT_PRS_SE 2U + + + //temperature ready flag +#define HP303B__REG_INFO_TEMP_RDY HP303B__REG_ADR_TEMP_RDY, \ + HP303B__REG_MASK_TEMP_RDY, \ + HP303B__REG_SHIFT_TEMP_RDY +#define HP303B__REG_ADR_TEMP_RDY 0x08U +#define HP303B__REG_MASK_TEMP_RDY 0x20U +#define HP303B__REG_SHIFT_TEMP_RDY 5U + + //pressure ready flag +#define HP303B__REG_INFO_PRS_RDY HP303B__REG_ADR_PRS_RDY, \ + HP303B__REG_MASK_PRS_RDY, \ + HP303B__REG_SHIFT_PRS_RDY +#define HP303B__REG_ADR_PRS_RDY 0x08U +#define HP303B__REG_MASK_PRS_RDY 0x10U +#define HP303B__REG_SHIFT_PRS_RDY 4U + + //pressure value +#define HP303B__REG_ADR_PRS 0x00U +#define HP303B__REG_LEN_PRS 3U + + //temperature value +#define HP303B__REG_ADR_TEMP 0x03U +#define HP303B__REG_LEN_TEMP 3U + + //compensation coefficients +#define HP303B__REG_ADR_COEF 0x10U +#define HP303B__REG_LEN_COEF 18 + + + //FIFO enable +#define HP303B__REG_INFO_FIFO_EN HP303B__REG_ADR_FIFO_EN, \ + HP303B__REG_MASK_FIFO_EN, \ + HP303B__REG_SHIFT_FIFO_EN +#define HP303B__REG_ADR_FIFO_EN 0x09U +#define HP303B__REG_MASK_FIFO_EN 0x02U +#define HP303B__REG_SHIFT_FIFO_EN 1U + + //FIFO flush +#define HP303B__REG_INFO_FIFO_FL HP303B__REG_ADR_FIFO_EN, \ + HP303B__REG_MASK_FIFO_EN, \ + HP303B__REG_SHIFT_FIFO_EN +#define HP303B__REG_ADR_FIFO_FL 0x0CU +#define HP303B__REG_MASK_FIFO_FL 0x80U +#define HP303B__REG_SHIFT_FIFO_FL 7U + + //FIFO empty +#define HP303B__REG_INFO_FIFO_EMPTY HP303B__REG_ADR_FIFO_EMPTY, \ + HP303B__REG_MASK_FIFO_EMPTY, \ + HP303B__REG_SHIFT_FIFO_EMPTY +#define HP303B__REG_ADR_FIFO_EMPTY 0x0BU +#define HP303B__REG_MASK_FIFO_EMPTY 0x01U +#define HP303B__REG_SHIFT_FIFO_EMPTY 0U + + //FIFO full +#define HP303B__REG_INFO_FIFO_FULL HP303B__REG_ADR_FIFO_FULL, \ + HP303B__REG_MASK_FIFO_FULL, \ + HP303B__REG_SHIFT_FIFO_FULL +#define HP303B__REG_ADR_FIFO_FULL 0x0BU +#define HP303B__REG_MASK_FIFO_FULL 0x02U +#define HP303B__REG_SHIFT_FIFO_FULL 1U + + + //INT HL +#define HP303B__REG_INFO_INT_HL HP303B__REG_ADR_INT_HL, \ + HP303B__REG_MASK_INT_HL, \ + HP303B__REG_SHIFT_INT_HL +#define HP303B__REG_ADR_INT_HL 0x09U +#define HP303B__REG_MASK_INT_HL 0x80U +#define HP303B__REG_SHIFT_INT_HL 7U + + //INT FIFO enable +#define HP303B__REG_INFO_INT_EN_FIFO HP303B__REG_ADR_INT_EN_FIFO, \ + HP303B__REG_MASK_INT_EN_FIFO, \ + HP303B__REG_SHIFT_INT_EN_FIFO +#define HP303B__REG_ADR_INT_EN_FIFO 0x09U +#define HP303B__REG_MASK_INT_EN_FIFO 0x40U +#define HP303B__REG_SHIFT_INT_EN_FIFO 6U + + //INT TEMP enable +#define HP303B__REG_INFO_INT_EN_TEMP HP303B__REG_ADR_INT_EN_TEMP, \ + HP303B__REG_MASK_INT_EN_TEMP, \ + HP303B__REG_SHIFT_INT_EN_TEMP +#define HP303B__REG_ADR_INT_EN_TEMP 0x09U +#define HP303B__REG_MASK_INT_EN_TEMP 0x20U +#define HP303B__REG_SHIFT_INT_EN_TEMP 5U + + //INT PRS enable +#define HP303B__REG_INFO_INT_EN_PRS HP303B__REG_ADR_INT_EN_PRS, \ + HP303B__REG_MASK_INT_EN_PRS, \ + HP303B__REG_SHIFT_INT_EN_PRS +#define HP303B__REG_ADR_INT_EN_PRS 0x09U +#define HP303B__REG_MASK_INT_EN_PRS 0x10U +#define HP303B__REG_SHIFT_INT_EN_PRS 4U + + //INT FIFO flag +#define HP303B__REG_INFO_INT_FLAG_FIFO HP303B__REG_ADR_INT_FLAG_FIFO, \ + HP303B__REG_MASK_INT_FLAG_FIFO, \ + HP303B__REG_SHIFT_INT_FLAG_FIFO +#define HP303B__REG_ADR_INT_FLAG_FIFO 0x0AU +#define HP303B__REG_MASK_INT_FLAG_FIFO 0x04U +#define HP303B__REG_SHIFT_INT_FLAG_FIFO 2U + + //INT TMP flag +#define HP303B__REG_INFO_INT_FLAG_TEMP HP303B__REG_ADR_INT_FLAG_TEMP, \ + HP303B__REG_MASK_INT_FLAG_TEMP, \ + HP303B__REG_SHIFT_INT_FLAG_TEMP +#define HP303B__REG_ADR_INT_FLAG_TEMP 0x0AU +#define HP303B__REG_MASK_INT_FLAG_TEMP 0x02U +#define HP303B__REG_SHIFT_INT_FLAG_TEMP 1U + + //INT PRS flag +#define HP303B__REG_INFO_INT_FLAG_PRS HP303B__REG_ADR_INT_FLAG_PRS, \ + HP303B__REG_MASK_INT_FLAG_PRS, \ + HP303B__REG_SHIFT_INT_FLAG_PRS +#define HP303B__REG_ADR_INT_FLAG_PRS 0x0AU +#define HP303B__REG_MASK_INT_FLAG_PRS 0x01U +#define HP303B__REG_SHIFT_INT_FLAG_PRS 0U + + + +#endif /* DPS310_CONSTS_H_ */ diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 5622bcde9..25a8a2203 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -572,8 +572,10 @@ void GetFeatures(void) #ifdef USE_MCP9808 feature6 |= 0x00002000; // xsns_72_mcp9808.ino #endif +#ifdef USE_HP303B + feature6 |= 0x00004000; // xsns_73_hp303b.ino +#endif -// feature6 |= 0x00004000; // feature6 |= 0x00008000; // feature6 |= 0x00010000; diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino new file mode 100644 index 000000000..e5df20508 --- /dev/null +++ b/tasmota/xsns_73_hp303b.ino @@ -0,0 +1,161 @@ +/* + xsns_72_hp303b.ino - HP303B digital barometric air pressure sensor support for Tasmota + + Copyright (C) 2020 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_HP303B +/*********************************************************************************************\ + * HP303B - Gas (TVOC - Total Volatile Organic Compounds) and Air Quality (CO2) + * + * Source: Lolin LOLIN_HP303B_Library + * + * I2C Address: 0x77 or 0x76 +\*********************************************************************************************/ + +#define XSNS_73 73 +#define XI2C_52 52 // See I2CDEVICES.md + +#define HP303B_ADDR1 0x77 +#define HP303B_ADDR2 0x76 + +#include +// HP303B Opject +LOLIN_HP303B HP303BSensor = LOLIN_HP303B(); + +struct HP303BDATA +{ + uint8_t address; + uint8_t addresses[2] = {HP303B_ADDR1, HP303B_ADDR2}; + uint8_t type = 0; + uint8_t valid = 0; + int32_t temperature; + int32_t pressure; + int16_t oversampling = 7; + char types[7] = "HP303B"; +} HP303B; + +/*********************************************************************************************/ + +bool HP303B_Read(int32_t &t, int32_t &p, uint8_t hp303b_address) +{ + HP303BSensor.begin(hp303b_address); + + int16_t ret; + + ret = HP303BSensor.measureTempOnce(t, HP303B.oversampling); + if (ret != 0) + return false; + + ret = HP303BSensor.measurePressureOnce(p, HP303B.oversampling); + if (ret != 0) + return false; + + HP303B.temperature = ConvertTemp(t); + HP303B.pressure = ConvertPressure(p); + + return true; +} + +/********************************************************************************************/ + +void HP303B_Detect(void) +{ + for (uint32_t i = 0; i < sizeof(HP303B.addresses); i++) + { + if (!I2cSetDevice(HP303B.addresses[i])) + { + continue; + } + + int32_t t; + int32_t p; + if (HP303B_Read(t, p, HP303B.addresses[i])) + { + I2cSetActiveFound(HP303B.addresses[i], HP303B.types); + HP303B.address = HP303B.addresses[i]; + HP303B.type = 1; + } + } +} + +void HP303B_Show(bool json) +{ + + if (HP303B_Read(HP303B.temperature, HP303B.pressure, HP303B.address)) + { + if (json) + { + ResponseAppend_P(PSTR(",\"HP303B\":{\"" D_JSON_TEMPERATURE "\":%d,\"" D_JSON_PRESSURE "\":%d"), HP303B.temperature, HP303B.pressure); +#ifdef USE_DOMOTICZ + if (0 == tele_period) + { + DomoticzSensor(DZ_TEMP, HP303B.temperature); + } +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } + else + { + char str_temperature[12]; + char str_pressure[12]; + + itoa(HP303B.temperature, str_temperature, 10); + itoa(HP303B.pressure, str_pressure, 10); + + WSContentSend_PD(HTTP_SNS_TEMP, "HP303B", str_temperature, TempUnit()); + WSContentSend_PD(HTTP_SNS_PRESSURE, "HP303B", str_pressure, PressureUnit().c_str()); +#endif // USE_WEBSERVER + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns73(uint8_t function) +{ + if (!I2cEnabled(XI2C_52)) + { + return false; + } + + bool result = false; + + if (FUNC_INIT == function) + { + HP303B_Detect(); + } + else if (HP303B.type) + { + switch (function) + { + case FUNC_JSON_APPEND: + HP303B_Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + HP303B_Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_HP303B +#endif // USE_I2C diff --git a/tools/decode-status.py b/tools/decode-status.py index 67898d784..b77ddf2c6 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -204,7 +204,7 @@ a_features = [[ "USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080", "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", - "USE_VEML7700","USE_MCP9808","","", + "USE_VEML7700","USE_MCP9808","USE_HP303B","", "","","","", "","","","", "","","","", From 2da09526ba41f73663b7ddda55df80c3104c2407 Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Sat, 6 Jun 2020 23:05:55 +0200 Subject: [PATCH 166/581] switched to float values and converted Pa to hPa --- tasmota/xsns_73_hp303b.ino | 64 ++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index e5df20508..3f508b7d8 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -36,36 +36,35 @@ // HP303B Opject LOLIN_HP303B HP303BSensor = LOLIN_HP303B(); -struct HP303BDATA -{ - uint8_t address; - uint8_t addresses[2] = {HP303B_ADDR1, HP303B_ADDR2}; - uint8_t type = 0; - uint8_t valid = 0; - int32_t temperature; - int32_t pressure; - int16_t oversampling = 7; - char types[7] = "HP303B"; -} HP303B; +uint8_t address; +uint8_t addresses[2] = {HP303B_ADDR1, HP303B_ADDR2}; +uint8_t type = 0; +uint8_t valid = 0; +float temperature; +float pressure; +int16_t oversampling = 7; +char types[7] = "HP303B"; /*********************************************************************************************/ -bool HP303B_Read(int32_t &t, int32_t &p, uint8_t hp303b_address) +bool HP303B_Read(float &temperature, float &pressure, uint8_t hp303b_address) { HP303BSensor.begin(hp303b_address); + int32_t t; + int32_t p; int16_t ret; - ret = HP303BSensor.measureTempOnce(t, HP303B.oversampling); + ret = HP303BSensor.measureTempOnce(t, oversampling); if (ret != 0) return false; - ret = HP303BSensor.measurePressureOnce(p, HP303B.oversampling); + ret = HP303BSensor.measurePressureOnce(p, oversampling); if (ret != 0) return false; - HP303B.temperature = ConvertTemp(t); - HP303B.pressure = ConvertPressure(p); + temperature = (float)ConvertTemp(t); + pressure = (float)ConvertPressure(p) / 100; //conversion to hPa return true; } @@ -74,20 +73,20 @@ bool HP303B_Read(int32_t &t, int32_t &p, uint8_t hp303b_address) void HP303B_Detect(void) { - for (uint32_t i = 0; i < sizeof(HP303B.addresses); i++) + for (uint32_t i = 0; i < sizeof(addresses); i++) { - if (!I2cSetDevice(HP303B.addresses[i])) + if (!I2cSetDevice(addresses[i])) { continue; } - int32_t t; - int32_t p; - if (HP303B_Read(t, p, HP303B.addresses[i])) + float t; + float p; + if (HP303B_Read(t, p, addresses[i])) { - I2cSetActiveFound(HP303B.addresses[i], HP303B.types); - HP303B.address = HP303B.addresses[i]; - HP303B.type = 1; + I2cSetActiveFound(addresses[i], types); + address = addresses[i]; + type = 1; } } } @@ -95,26 +94,25 @@ void HP303B_Detect(void) void HP303B_Show(bool json) { - if (HP303B_Read(HP303B.temperature, HP303B.pressure, HP303B.address)) + if (HP303B_Read(temperature, pressure, address)) { if (json) { - ResponseAppend_P(PSTR(",\"HP303B\":{\"" D_JSON_TEMPERATURE "\":%d,\"" D_JSON_PRESSURE "\":%d"), HP303B.temperature, HP303B.pressure); + ResponseAppend_P(PSTR(",\"HP303B\":{\"" D_JSON_TEMPERATURE "\":%d,\"" D_JSON_PRESSURE "\":%d"), temperature, pressure); #ifdef USE_DOMOTICZ if (0 == tele_period) { - DomoticzSensor(DZ_TEMP, HP303B.temperature); + DomoticzSensor(DZ_TEMP, temperature); } #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { - char str_temperature[12]; - char str_pressure[12]; - - itoa(HP303B.temperature, str_temperature, 10); - itoa(HP303B.pressure, str_pressure, 10); + char str_temperature[33]; + dtostrfd(temperature, Settings.flag2.temperature_resolution, str_temperature); + char str_pressure[33]; + dtostrfd(pressure, Settings.flag2.pressure_resolution, str_pressure); WSContentSend_PD(HTTP_SNS_TEMP, "HP303B", str_temperature, TempUnit()); WSContentSend_PD(HTTP_SNS_PRESSURE, "HP303B", str_pressure, PressureUnit().c_str()); @@ -140,7 +138,7 @@ bool Xsns73(uint8_t function) { HP303B_Detect(); } - else if (HP303B.type) + else if (type) { switch (function) { From d3a59fd65c3f5834d9fb61eee1374d50a2f14db3 Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Sun, 7 Jun 2020 16:33:28 +0200 Subject: [PATCH 167/581] Changed driver to measure float --- lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp | 82 +++++++++++++-------------- lib/LOLIN_HP303B/src/LOLIN_HP303B.h | 22 +++---- tasmota/xsns_73_hp303b.ino | 17 +++--- 3 files changed, 60 insertions(+), 61 deletions(-) diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp index 43fcd435e..fdeebd6a0 100644 --- a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp @@ -181,7 +181,7 @@ int16_t LOLIN_HP303B::standby(void) * -2 if the object initialization failed * -1 on other fail */ -int16_t LOLIN_HP303B::measureTempOnce(int32_t &result) +int16_t LOLIN_HP303B::measureTempOnce(float &result) { return measureTempOnce(result, m_tempOsr); } @@ -202,7 +202,7 @@ int16_t LOLIN_HP303B::measureTempOnce(int32_t &result) * -2 if the object initialization failed * -1 on other fail */ -int16_t LOLIN_HP303B::measureTempOnce(int32_t &result, uint8_t oversamplingRate) +int16_t LOLIN_HP303B::measureTempOnce(float &result, uint8_t oversamplingRate) { //Start measurement int16_t ret = startMeasureTempOnce(oversamplingRate); @@ -286,7 +286,7 @@ int16_t LOLIN_HP303B::startMeasureTempOnce(uint8_t oversamplingRate) * -2 if the object initialization failed * -1 on other fail */ -int16_t LOLIN_HP303B::measurePressureOnce(int32_t &result) +int16_t LOLIN_HP303B::measurePressureOnce(float &result) { return measurePressureOnce(result, m_prsOsr); } @@ -307,7 +307,7 @@ int16_t LOLIN_HP303B::measurePressureOnce(int32_t &result) * -2 if the object initialization failed * -1 on other fail */ -int16_t LOLIN_HP303B::measurePressureOnce(int32_t &result, uint8_t oversamplingRate) +int16_t LOLIN_HP303B::measurePressureOnce(float &result, uint8_t oversamplingRate) { //start the measurement int16_t ret = startMeasurePressureOnce(oversamplingRate); @@ -388,7 +388,7 @@ int16_t LOLIN_HP303B::startMeasurePressureOnce(uint8_t oversamplingRate) * -2 if the object initialization failed * -1 on other fail */ -int16_t LOLIN_HP303B::getSingleResult(int32_t &result) +int16_t LOLIN_HP303B::getSingleResult(float &result) { //abort if initialization failed if(m_initFail) @@ -636,9 +636,9 @@ int16_t LOLIN_HP303B::startMeasureBothCont(uint8_t tempMr, * -2 if the object initialization failed * -1 on other fail */ -int16_t LOLIN_HP303B::getContResults(int32_t *tempBuffer, +int16_t LOLIN_HP303B::getContResults(float *tempBuffer, uint8_t &tempCount, - int32_t *prsBuffer, + float *prsBuffer, uint8_t &prsCount) { if(m_initFail) @@ -660,7 +660,7 @@ int16_t LOLIN_HP303B::getContResults(int32_t *tempBuffer, //while FIFO is not empty while(readByteBitfield(HP303B__REG_INFO_FIFO_EMPTY) == 0) { - int32_t result; + float result; //read next result from FIFO int16_t type = getFIFOvalue(&result); switch(type) @@ -820,13 +820,13 @@ int16_t LOLIN_HP303B::correctTemp(void) writeByte(0x62, 0x02); writeByte(0x0E, 0x00); writeByte(0x0F, 0x00); - + //perform a first temperature measurement (again) //the most recent temperature will be saved internally //and used for compensation when calculating pressure - int32_t trash; + float trash; measureTempOnce(trash); - + return HP303B__SUCCEEDED; } @@ -892,13 +892,13 @@ void LOLIN_HP303B::init(void) //perform a first temperature measurement //the most recent temperature will be saved internally //and used for compensation when calculating pressure - int32_t trash; + float trash; measureTempOnce(trash); //make sure the HP303B is in standby after initialization - standby(); + standby(); - // Fix IC with a fuse bit problem, which lead to a wrong temperature + // Fix IC with a fuse bit problem, which lead to a wrong temperature // Should not affect ICs without this problem correctTemp(); } @@ -1192,9 +1192,9 @@ uint16_t LOLIN_HP303B::calcBusyTime(uint16_t mr, uint16_t osr) * returns: 0 on success * -1 on fail; */ -int16_t LOLIN_HP303B::getTemp(int32_t *result) +int16_t LOLIN_HP303B::getTemp(float *result) { - uint8_t buffer[3] = {0}; + unsigned char buffer[3] = {0}; //read raw pressure data to buffer int16_t i = readBlock(HP303B__REG_ADR_TEMP, @@ -1207,14 +1207,14 @@ int16_t LOLIN_HP303B::getTemp(int32_t *result) } //compose raw temperature value from buffer - int32_t temp = (uint32_t)buffer[0] << 16 - | (uint32_t)buffer[1] << 8 - | (uint32_t)buffer[2]; + float temp = buffer[0] << 16 + | buffer[1] << 8 + | buffer[2]; //recognize non-32-bit negative numbers //and convert them to 32-bit negative numbers using 2's complement - if(temp & ((uint32_t)1 << 23)) + if(temp > 0x7FFFFF) { - temp -= (uint32_t)1 << 24; + temp = temp - 0x1000000; } //return temperature @@ -1229,9 +1229,9 @@ int16_t LOLIN_HP303B::getTemp(int32_t *result) * returns: 0 on success * -1 on fail; */ -int16_t LOLIN_HP303B::getPressure(int32_t *result) +int16_t LOLIN_HP303B::getPressure(float *result) { - uint8_t buffer[3] = {0}; + unsigned char buffer[3] = {0}; //read raw pressure data to buffer int16_t i = readBlock(HP303B__REG_ADR_PRS, HP303B__REG_LEN_PRS, @@ -1244,14 +1244,12 @@ int16_t LOLIN_HP303B::getPressure(int32_t *result) } //compose raw pressure value from buffer - int32_t prs = (uint32_t)buffer[0] << 16 - | (uint32_t)buffer[1] << 8 - | (uint32_t)buffer[2]; + float prs = buffer[0] << 16 | buffer[1] << 8 | buffer[2]; //recognize non-32-bit negative numbers //and convert them to 32-bit negative numbers using 2's complement - if(prs & ((uint32_t)1 << 23)) + if(prs > 0x7FFFFF) { - prs -= (uint32_t)1 << 24; + prs = prs - 0x1000000; } *result = calcPressure(prs); @@ -1266,7 +1264,7 @@ int16_t LOLIN_HP303B::getPressure(int32_t *result) * 0 if result is a temperature raw value * 1 if result is a pressure raw value */ -int16_t LOLIN_HP303B::getFIFOvalue(int32_t* value) +int16_t LOLIN_HP303B::getFIFOvalue(float *value) { //abort on invalid argument if(value == NULL) @@ -1274,7 +1272,7 @@ int16_t LOLIN_HP303B::getFIFOvalue(int32_t* value) return HP303B__FAIL_UNKNOWN; } - uint8_t buffer[HP303B__REG_LEN_PRS] = {0}; + unsigned char buffer[HP303B__REG_LEN_PRS] = {0}; //always read from pressure raw value register int16_t i = readBlock(HP303B__REG_ADR_PRS, HP303B__REG_LEN_PRS, @@ -1286,14 +1284,14 @@ int16_t LOLIN_HP303B::getFIFOvalue(int32_t* value) return HP303B__FAIL_UNKNOWN; } //compose raw pressure value from buffer - *value = (uint32_t)buffer[0] << 16 - | (uint32_t)buffer[1] << 8 - | (uint32_t)buffer[2]; + *value = buffer[0] << 16 + | buffer[1] << 8 + | buffer[2]; //recognize non-32-bit negative numbers //and convert them to 32-bit negative numbers using 2's complement - if(*value & ((uint32_t)1 << 23)) + if(*value > 0x7FFFFF) { - *value -= (uint32_t)1 << 24; + *value = *value - 0x1000000; } //least significant bit shows measurement type @@ -1305,10 +1303,10 @@ int16_t LOLIN_HP303B::getFIFOvalue(int32_t* value) * raw: raw temperature value read from HP303B * returns: temperature value in °C */ -int32_t LOLIN_HP303B::calcTemp(int32_t raw) +float LOLIN_HP303B::calcTemp(float raw) { double temp = raw; - + //scale temperature according to scaling table and oversampling temp /= scaling_facts[m_tempOsr]; @@ -1320,7 +1318,7 @@ int32_t LOLIN_HP303B::calcTemp(int32_t raw) temp = m_c0Half + m_c1 * temp; //return temperature - return (int32_t)temp; + return (float)temp; } /** @@ -1328,7 +1326,7 @@ int32_t LOLIN_HP303B::calcTemp(int32_t raw) * raw: raw pressure value read from HP303B * returns: pressure value in Pa */ -int32_t LOLIN_HP303B::calcPressure(int32_t raw) +float LOLIN_HP303B::calcPressure(float raw) { double prs = raw; @@ -1341,7 +1339,7 @@ int32_t LOLIN_HP303B::calcPressure(int32_t raw) + m_lastTempScal * (m_c01 + prs * (m_c11 + prs * m_c21)); //return pressure - return (int32_t)prs; + return (float)prs; } /** @@ -1357,7 +1355,7 @@ int16_t LOLIN_HP303B::readByte(uint8_t regAddress) { return readByteSPI(regAddress); } - + m_i2cbus->beginTransmission(m_slaveAddress); m_i2cbus->write(regAddress); m_i2cbus->endTransmission(0); @@ -1429,7 +1427,7 @@ int16_t LOLIN_HP303B::readBlock(uint8_t regAddress, uint8_t length, uint8_t *buf { return 0; //0 bytes read successfully } - + m_i2cbus->beginTransmission(m_slaveAddress); m_i2cbus->write(regAddress); m_i2cbus->endTransmission(0); diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h index f9c54e356..ce65e17f1 100644 --- a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h @@ -34,21 +34,21 @@ public: int16_t standby(void); //Command Mode - int16_t measureTempOnce(int32_t &result); - int16_t measureTempOnce(int32_t &result, uint8_t oversamplingRate); + int16_t measureTempOnce(float &result); + int16_t measureTempOnce(float &result, uint8_t oversamplingRate); int16_t startMeasureTempOnce(void); int16_t startMeasureTempOnce(uint8_t oversamplingRate); - int16_t measurePressureOnce(int32_t &result); - int16_t measurePressureOnce(int32_t &result, uint8_t oversamplingRate); + int16_t measurePressureOnce(float &result); + int16_t measurePressureOnce(float &result, uint8_t oversamplingRate); int16_t startMeasurePressureOnce(void); int16_t startMeasurePressureOnce(uint8_t oversamplingRate); - int16_t getSingleResult(int32_t &result); + int16_t getSingleResult(float &result); //Background Mode int16_t startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate); int16_t startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate); int16_t startMeasureBothCont(uint8_t tempMr, uint8_t tempOsr, uint8_t prsMr, uint8_t prsOsr); - int16_t getContResults(int32_t *tempBuffer, uint8_t &tempCount, int32_t *prsBuffer, uint8_t &prsCount); + int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount); //Interrupt Control int16_t setInterruptPolarity(uint8_t polarity); @@ -122,11 +122,11 @@ private: int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr); int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr); uint16_t calcBusyTime(uint16_t temp_rate, uint16_t temp_osr); - int16_t getTemp(int32_t *result); - int16_t getPressure(int32_t *result); - int16_t getFIFOvalue(int32_t *value); - int32_t calcTemp(int32_t raw); - int32_t calcPressure(int32_t raw); + int16_t getTemp(float *result); + int16_t getPressure(float *result); + int16_t getFIFOvalue(float *value); + float calcTemp(float raw); + float calcPressure(float raw); //bus specific int16_t readByte(uint8_t regAddress); diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index 3f508b7d8..926a437ad 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -51,8 +51,8 @@ bool HP303B_Read(float &temperature, float &pressure, uint8_t hp303b_address) { HP303BSensor.begin(hp303b_address); - int32_t t; - int32_t p; + float t; + float p; int16_t ret; ret = HP303BSensor.measureTempOnce(t, oversampling); @@ -96,9 +96,15 @@ void HP303B_Show(bool json) if (HP303B_Read(temperature, pressure, address)) { + char str_temperature[33]; + dtostrfd(temperature, Settings.flag2.temperature_resolution, str_temperature); + char str_pressure[33]; + dtostrfd(pressure, Settings.flag2.pressure_resolution, str_pressure); + if (json) { - ResponseAppend_P(PSTR(",\"HP303B\":{\"" D_JSON_TEMPERATURE "\":%d,\"" D_JSON_PRESSURE "\":%d"), temperature, pressure); + ResponseAppend_P(PSTR(",\"HP303B\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), str_temperature, str_pressure); + ResponseJsonEnd(); #ifdef USE_DOMOTICZ if (0 == tele_period) { @@ -109,11 +115,6 @@ void HP303B_Show(bool json) } else { - char str_temperature[33]; - dtostrfd(temperature, Settings.flag2.temperature_resolution, str_temperature); - char str_pressure[33]; - dtostrfd(pressure, Settings.flag2.pressure_resolution, str_pressure); - WSContentSend_PD(HTTP_SNS_TEMP, "HP303B", str_temperature, TempUnit()); WSContentSend_PD(HTTP_SNS_PRESSURE, "HP303B", str_pressure, PressureUnit().c_str()); #endif // USE_WEBSERVER From c6fede2bf4ddd9c2ef215f23be668c1d1848f0e5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 7 Jun 2020 17:21:29 +0200 Subject: [PATCH 168/581] Basic support for BL0940 Basic support for BL0940 (#8175) --- tasmota/language/bg_BG.h | 1 + tasmota/language/cs_CZ.h | 1 + tasmota/language/de_DE.h | 1 + tasmota/language/el_GR.h | 1 + tasmota/language/en_GB.h | 1 + tasmota/language/es_ES.h | 1 + tasmota/language/fr_FR.h | 1 + tasmota/language/he_HE.h | 1 + tasmota/language/hu_HU.h | 1 + tasmota/language/it_IT.h | 1 + tasmota/language/ko_KO.h | 1 + tasmota/language/nl_NL.h | 1 + tasmota/language/pl_PL.h | 1 + tasmota/language/pt_BR.h | 1 + tasmota/language/pt_PT.h | 1 + tasmota/language/ro_RO.h | 1 + tasmota/language/ru_RU.h | 1 + tasmota/language/sk_SK.h | 1 + tasmota/language/sv_SE.h | 1 + tasmota/language/tr_TR.h | 1 + tasmota/language/uk_UA.h | 1 + tasmota/language/zh_CN.h | 1 + tasmota/language/zh_TW.h | 1 + tasmota/my_user_config.h | 13 +- tasmota/support_features.ino | 5 +- tasmota/tasmota.h | 1 + tasmota/tasmota_template.h | 13 +- tasmota/xnrg_14_bl0940.ino | 307 +++++++++++++++++++++++++++++++++++ tools/decode-status.py | 7 +- 29 files changed, 354 insertions(+), 15 deletions(-) create mode 100644 tasmota/xnrg_14_bl0940.ino diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index a40df8551..935704e74 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 33839ed4d..a04a6b16b 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index aa83ec0c2..02464daa6 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index ec6275dbd..333458c72 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 48208a0bb..92637b350 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index de021791e..701f3e107 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index dbe9c597a..f91bd7fbd 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index fe77159c1..3550a1abd 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 844fa2f8f..1a58472e4 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 09dcc266b..f1af3765f 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 - TX" #define D_SENSOR_LE01MR_RX "LE-01MR - RX" #define D_SENSOR_LE01MR_TX "LE-01MR - TX" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 - GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 - GDO2" #define D_SENSOR_HRXL_RX "HRXL - RX" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 5ab580ce8..a004ecec7 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 84ce656e3..ab6a28485 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 8ee529292..aea969baf 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 39e7affb0..02c4b4ecc 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index aabd353fe..4507cecba 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 77a2240ca..66e82ad55 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 0e5cd24ac..7c7fc770b 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index d8bdd2ece..e242f9bc1 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 64a540f96..1649b7f5f 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index c62981f8d..8a1063d7a 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 0b90eaf53..a16675ae4 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index e521054f5..0da3126fd 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index bfa967b6d..1fb664d08 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -672,6 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 466a8991e..edf920e74 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -394,18 +394,18 @@ // -- Ping ---------------------------------------- // #define USE_PING // Enable Ping command (+2k code) -#define USE_UNISHOX_COMPRESSION // add support for string compression for RULES or SCRIPT +// -- Compression --------------------------------- +#define USE_UNISHOX_COMPRESSION // Add support for string compression in Rules or Scripts // -- Rules or Script ---------------------------- // Select none or only one of the below defines USE_RULES or USE_SCRIPT #define USE_RULES // Add support for rules (+8k code) - // with USE_UNISHOX_COMPRESSION // Compresses rules in Flash at about ~50% (+3.3k code) -//#define USE_SCRIPT // Add support for script (+17k code) - // supports USE_UNISHOX_COMPRESSION - //#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support - // #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem) // #define SUPPORT_IF_STATEMENT // Add support for IF statement in rules (+4k2 code, -332 bytes mem) + +//#define USE_SCRIPT // Add support for script (+17k code) + //#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support + // #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code) // -- Optional modules ---------------------------- @@ -611,6 +611,7 @@ //#define USE_LE01MR // Add support for F&F LE-01MR Modbus energy monitor (+1k code) #define LE01MR_SPEED 9600 // LE-01MR modbus baudrate (default: 9600) #define LE01MR_ADDR 1 // LE-01MR modbus address (default: 0x01) +#define USE_BL0940 // Add support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code) // -- Low level interface devices ----------------- #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 5622bcde9..20bb9acf3 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -572,8 +572,9 @@ void GetFeatures(void) #ifdef USE_MCP9808 feature6 |= 0x00002000; // xsns_72_mcp9808.ino #endif - -// feature6 |= 0x00004000; +#ifdef USE_BL0940 + feature6 |= 0x00004000; // xnrg_14_bl0940.ino +#endif // feature6 |= 0x00008000; // feature6 |= 0x00010000; diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index fdace042c..949acec1b 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -293,6 +293,7 @@ enum SettingsTextIndex { SET_OTAURL, SET_TEMPLATE_NAME, SET_DEV_GROUP_NAME1, SET_DEV_GROUP_NAME2, SET_DEV_GROUP_NAME3, SET_DEV_GROUP_NAME4, SET_DEVICENAME, + SET_TELEGRAMTOKEN, SET_MAX }; enum DevGroupMessageType { DGR_MSGTYP_FULL_STATUS, DGR_MSGTYP_PARTIAL_UPDATE, DGR_MSGTYP_UPDATE, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_MSGTYP_UPDATE_DIRECT, DGR_MSGTYPE_UPDATE_COMMAND }; diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index b3d3b48ba..8b44a547b 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -233,6 +233,7 @@ enum UserSelectablePins { GPIO_BOILER_OT_RX, // OpenTherm Boiler RX pin GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin GPIO_WINDMETER_SPEED, // WindMeter speed counter pin + GPIO_BL0940_RX, // BL0940 serial interface GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -322,7 +323,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_ELECTRIQ_MOODL "|" D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX "|" D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" - D_SENSOR_WINDMETER_SPEED + D_SENSOR_WINDMETER_SPEED "|" + D_SENSOR_BL0940_RX ; const char kSensorNamesFixed[] PROGMEM = @@ -553,15 +555,18 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_DDSU666 GPIO_DDSU666_TX, // DDSU666 Serial interface GPIO_DDSU666_RX, // DDSU666 Serial interface -#endif // USE_DDSU666 +#endif #ifdef USE_SOLAX_X1 GPIO_SOLAXX1_TX, // Solax Inverter tx pin GPIO_SOLAXX1_RX, // Solax Inverter rx pin -#endif // USE_SOLAX_X1 +#endif #ifdef USE_LE01MR GPIO_LE01MR_RX, // F7F LE-01MR energy meter rx pin GPIO_LE01MR_TX, // F7F LE-01MR energy meter tx pin -#endif // IFDEF:USE_LE01MR +#endif +#ifdef USE_BL0940 + GPIO_BL0940_RX, // BL0940 Serial interface +#endif #endif // USE_ENERGY_SENSOR // Serial diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino new file mode 100644 index 000000000..ff5d61ff2 --- /dev/null +++ b/tasmota/xnrg_14_bl0940.ino @@ -0,0 +1,307 @@ +/* + xnrg_14_bl0940.ino - BL0940 energy sensor support for Tasmota + + Copyright (C) 2020 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_ENERGY_SENSOR +#ifdef USE_BL0940 +/*********************************************************************************************\ + * BL0940 - Energy (Blitzwolf SHP10) + * + * Template {"NAME":"BW-SHP10","GPIO":[0,148,0,207,158,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} + * + * Based on datasheet from http://www.belling.com.cn/media/file_object/bel_product/BL0940/datasheet/BL0940_V1.1_en.pdf +\*********************************************************************************************/ + +#define XNRG_14 14 + +#define BL0940_PULSES_NOT_INITIALIZED -1 + +#define BL0940_BUFFER_SIZE 36 + +#define BL0940_WRITE_COMMAND 0xA0 // 0xA8 according to documentation +#define BL0940_REG_I_FAST_RMS_CTRL 0x10 +#define BL0940_REG_MODE 0x18 +#define BL0940_REG_SOFT_RESET 0x19 +#define BL0940_REG_USR_WRPROT 0x1A +#define BL0940_REG_TPS_CTRL 0x1B + +#define BL0940_READ_COMMAND 0x50 // 0x58 according to documentation +#define BL0940_FULL_PACKET 0xAA +#define BL0940_PACKET_HEADER 0x55 // 0x58 according to documentation + +#include + +TasmotaSerial *Bl0940Serial = nullptr; + +struct BL0940 { + long voltage = 0; + long current = 0; + long power = 0; + long power_cycle_first = 0; + long cf_pulses = 0; + long cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; + float temperature; + + int byte_counter = 0; + uint8_t *rx_buffer = nullptr; + uint8_t power_invalid = 0; + bool received = false; +} Bl0940; + +const uint8_t bl0940_init[5][6] = { + { BL0940_WRITE_COMMAND, BL0940_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38 }, // Reset to default + { BL0940_WRITE_COMMAND, BL0940_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0 }, // Enable User Operation Write + { BL0940_WRITE_COMMAND, BL0940_REG_MODE, 0x00, 0x10, 0x00, 0x37 }, // 0x0100 = CF_UNABLE energy pulse, AC_FREQ_SEL 50Hz, RMS_UPDATE_SEL 800mS + { BL0940_WRITE_COMMAND, BL0940_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE }, // 0x47FF = Over-current and leakage alarm on, Automatic temperature measurement, Interval 100mS + { BL0940_WRITE_COMMAND, BL0940_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B }}; // 0x181C = Half cycle, Fast RMS threshold 6172 + +void Bl0940Received(void) { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 + // 55 F2 03 00 00 00 00 7E 02 00 D4 B0 72 AC 01 00 00 00 00 02 01 00 00 00 00 00 00 00 BA 01 00 FE 03 00 83 + // 55 88 02 00 49 00 00 FE 02 00 AF EF 71 D2 01 00 EB FF FF 49 01 00 00 00 00 02 00 00 CF 01 00 FE 03 00 9F + // 55 B9 33 00 DE 45 00 94 02 00 CF E4 70 63 02 00 6C 4C 00 13 01 00 09 00 00 00 00 00 E4 01 00 FE 03 00 72 + // Hd IFRms--- Current- Reserved Voltage- Reserved Power--- Reserved CF------ Reserved TPS1---- TPS2---- Ck + + if (Bl0940.rx_buffer[0] != BL0940_PACKET_HEADER) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: Invalid data")); + return; + } + + Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10]; + Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4]; + Bl0940.power = Bl0940.rx_buffer[18] << 16 | Bl0940.rx_buffer[17] << 8 | Bl0940.rx_buffer[16]; + Bl0940.cf_pulses = Bl0940.rx_buffer[24] << 16 | Bl0940.rx_buffer[23] << 8 | Bl0940.rx_buffer[22]; + uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; + Bl0940.temperature = ((170.0f/448.0f)*(((float)tps1/2.0f)-32.0f))-45.0f; + + if (Energy.power_on) { // Powered on + Energy.voltage[0] = (float)Bl0940.voltage / Settings.energy_voltage_calibration; + if (power != 0) { + Energy.active_power[0] = (float)Bl0940.power / Settings.energy_power_calibration; + Energy.current[0] = (float)Bl0940.current / (Settings.energy_current_calibration * 100); + } else { + Energy.active_power[0] = 0; + Energy.current[0] = 0; + } + } else { // Powered off + Bl0940.power_cycle_first = 0; + Energy.voltage[0] = 0; + Energy.active_power[0] = 0; + Energy.current[0] = 0; + } +} + +bool Bl0940SerialInput(void) { + while (Bl0940Serial->available()) { + yield(); + uint8_t serial_in_byte = Bl0940Serial->read(); + if (!Bl0940.received && (BL0940_PACKET_HEADER == serial_in_byte)) { // Packet header + Bl0940.received = true; + Bl0940.byte_counter = 0; + } + if (Bl0940.received) { + Bl0940.rx_buffer[Bl0940.byte_counter++] = serial_in_byte; + if (BL0940_BUFFER_SIZE == Bl0940.byte_counter) { + + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, Bl0940.rx_buffer, BL0940_BUFFER_SIZE -1); + + uint8_t checksum = BL0940_READ_COMMAND; + for (uint32_t i = 0; i < BL0940_BUFFER_SIZE -2; i++) { checksum += Bl0940.rx_buffer[i]; } + checksum ^= 0xFF; + if (checksum == Bl0940.rx_buffer[34]) { + Energy.data_valid[0] = 0; + Bl0940Received(); + Bl0940.received = false; + return true; + } else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); + do { // Sync buffer with data (issue #1907 and #3425) + memmove(Bl0940.rx_buffer, Bl0940.rx_buffer +1, BL0940_BUFFER_SIZE -1); + Bl0940.byte_counter--; + } while ((Bl0940.byte_counter > 1) && (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0])); + if (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0]) { + Bl0940.received = false; + Bl0940.byte_counter = 0; + } + } + } + } + } +} + +/********************************************************************************************/ + +void Bl0940EverySecond(void) { + if (Energy.data_valid[0] > ENERGY_WATCHDOG) { + Bl0940.voltage = 0; + Bl0940.current = 0; + Bl0940.power = 0; + } else { + long cf_frequency = 0; + + if (BL0940_PULSES_NOT_INITIALIZED == Bl0940.cf_pulses_last_time) { + Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; // Init after restart + } else { + if (Bl0940.cf_pulses < Bl0940.cf_pulses_last_time) { // Rolled over after 16777215 pulses + cf_frequency = (0x1000000 - Bl0940.cf_pulses_last_time) + Bl0940.cf_pulses; + } else { + cf_frequency = Bl0940.cf_pulses - Bl0940.cf_pulses_last_time; + } + if (cf_frequency && Energy.active_power[0]) { + unsigned long delta = (cf_frequency * Settings.energy_power_calibration) / 36; + // prevent invalid load delta steps even checksum is valid (issue #5789): +// if (delta <= (3680*100/36) * 10 ) { // max load for S31/Pow R2: 3.68kW + // prevent invalid load delta steps even checksum is valid but allow up to 4kW (issue #7155): + if (delta <= (4000*100/36) * 10 ) { // max load for S31/Pow R2: 4.00kW + Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; + Energy.kWhtoday_delta += delta; + } + else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: Load overflow")); + Bl0940.cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; + } + EnergyUpdateToday(); + } + } + } + + Bl0940Serial->flush(); + Bl0940Serial->write(BL0940_READ_COMMAND); + Bl0940Serial->write(BL0940_FULL_PACKET); +} + +void Bl0940SnsInit(void) { + // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions + Bl0940Serial = new TasmotaSerial(Pin(GPIO_BL0940_RX), Pin(GPIO_TXD), 1); + if (Bl0940Serial->begin(4800, 2)) { + if (Bl0940Serial->hardwareSerial()) { + ClaimSerial(); + } + if (HLW_UREF_PULSE == Settings.energy_voltage_calibration) { + Settings.energy_voltage_calibration = 33003; + Settings.energy_current_calibration = 2243; + Settings.energy_power_calibration = 1414; + } + + for (uint32_t i = 0; i < 5; i++) { + for (uint32_t j = 0; j < 6; j++) { + Bl0940Serial->write(bl0940_init[i][j]); +// Bl0940Serial->write(pgm_read_byte(bl0940_init + (6 * i) + j)); // Wrong byte order! + } + delay(1); + } + + } else { + energy_flg = ENERGY_NONE; + } +} + +void Bl0940DrvInit(void) { + if (PinUsed(GPIO_BL0940_RX) && PinUsed(GPIO_TXD)) { + Bl0940.rx_buffer = (uint8_t*)(malloc(BL0940_BUFFER_SIZE)); + if (Bl0940.rx_buffer != nullptr) { + energy_flg = XNRG_14; + } + } +} + +bool Bl0940Command(void) { + bool serviced = true; + + uint32_t value = (uint32_t)(CharToFloat(XdrvMailbox.data) * 100); // 1.23 = 123 + + if (CMND_POWERSET == Energy.command_code) { + if (XdrvMailbox.data_len && Bl0940.power) { + Settings.energy_power_calibration = (Bl0940.power * 100) / value; + } + } + else if (CMND_VOLTAGESET == Energy.command_code) { + if (XdrvMailbox.data_len && Bl0940.voltage) { + Settings.energy_voltage_calibration = (Bl0940.voltage * 100) / value; + } + } + else if (CMND_CURRENTSET == Energy.command_code) { + if (XdrvMailbox.data_len && Bl0940.current) { + Settings.energy_current_calibration = Bl0940.current / value; + } + } + else serviced = false; // Unknown command + + return serviced; +} + +void Bl0940Show(bool json) +{ + char temperature[33]; + dtostrfd(Bl0940.temperature, Settings.flag2.temperature_resolution, temperature); + + if (json) { + ResponseAppend_P(JSON_SNS_TEMP, "BL0940", temperature); + if (0 == tele_period) { +#ifdef USE_DOMOTICZ + DomoticzSensor(DZ_TEMP, temperature); +#endif // USE_DOMOTICZ +#ifdef USE_KNX + KnxSensor(KNX_TEMPERATURE, Bl0940.temperature); +#endif // USE_KNX + } +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, "", temperature, TempUnit()); +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xnrg14(uint8_t function) +{ + bool result = false; + + switch (function) { + case FUNC_LOOP: + if (Bl0940Serial) { Bl0940SerialInput(); } + break; + case FUNC_ENERGY_EVERY_SECOND: + Bl0940EverySecond(); + break; + case FUNC_JSON_APPEND: + Bl0940Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + Bl0940Show(0); + break; +#endif // USE_WEBSERVER + case FUNC_COMMAND: + result = Bl0940Command(); + break; + case FUNC_INIT: + Bl0940SnsInit(); + break; + case FUNC_PRE_INIT: + Bl0940DrvInit(); + break; + } + return result; +} + +#endif // USE_BL0940 +#endif // USE_ENERGY_SENSOR diff --git a/tools/decode-status.py b/tools/decode-status.py index 67898d784..1ce04951e 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -148,7 +148,8 @@ a_setoption = [[ "Enable light fading at start/power on", "Set PWM Mode from regular PWM to ColorTemp control","", "Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick", - "","","", + "Implement simpler MAX6675 protocol instead of MAX31855", + "","", "","","","", "","","","", "","","","", @@ -204,7 +205,7 @@ a_features = [[ "USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080", "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", - "USE_VEML7700","USE_MCP9808","","", + "USE_VEML7700","USE_MCP9808","USE_BL0940","", "","","","", "","","","", "","","","", @@ -242,7 +243,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200510 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200607 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From e54c85f83e8e584f42b29e0c69155b0a6aae101a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 7 Jun 2020 17:59:54 +0200 Subject: [PATCH 169/581] Add full support for BL0940 Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/xnrg_14_bl0940.ino | 28 +++------------------------- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5e4429dde..fdac7edde 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -75,3 +75,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add ``FlashFrequency`` to ``status 4`` - Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) - Add support for up to eight MCP9808 temperature sensors by device111 (#8594) +- Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 54e1a5f63..4f7d3132b 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -17,6 +17,7 @@ - Add ``FlashFrequency`` to ``status 4`` - Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) - Add Zigbee auto-responder for common attributes +- Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) ### 8.3.1.1 20200518 diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index ff5d61ff2..99a738e81 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -152,31 +152,9 @@ void Bl0940EverySecond(void) { Bl0940.current = 0; Bl0940.power = 0; } else { - long cf_frequency = 0; - - if (BL0940_PULSES_NOT_INITIALIZED == Bl0940.cf_pulses_last_time) { - Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; // Init after restart - } else { - if (Bl0940.cf_pulses < Bl0940.cf_pulses_last_time) { // Rolled over after 16777215 pulses - cf_frequency = (0x1000000 - Bl0940.cf_pulses_last_time) + Bl0940.cf_pulses; - } else { - cf_frequency = Bl0940.cf_pulses - Bl0940.cf_pulses_last_time; - } - if (cf_frequency && Energy.active_power[0]) { - unsigned long delta = (cf_frequency * Settings.energy_power_calibration) / 36; - // prevent invalid load delta steps even checksum is valid (issue #5789): -// if (delta <= (3680*100/36) * 10 ) { // max load for S31/Pow R2: 3.68kW - // prevent invalid load delta steps even checksum is valid but allow up to 4kW (issue #7155): - if (delta <= (4000*100/36) * 10 ) { // max load for S31/Pow R2: 4.00kW - Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; - Energy.kWhtoday_delta += delta; - } - else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: Load overflow")); - Bl0940.cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; - } - EnergyUpdateToday(); - } + if (Energy.active_power[0]) { + Energy.kWhtoday_delta += (Energy.active_power[0] * 1000) / 36; + EnergyUpdateToday(); } } From aa5587f9e19444d33aae379e8f9dcadc1d2cad30 Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Mon, 8 Jun 2020 08:58:38 +0200 Subject: [PATCH 170/581] Mover begin() to detect function --- tasmota/xsns_73_hp303b.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index 926a437ad..abff91f09 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -49,8 +49,6 @@ char types[7] = "HP303B"; bool HP303B_Read(float &temperature, float &pressure, uint8_t hp303b_address) { - HP303BSensor.begin(hp303b_address); - float t; float p; int16_t ret; @@ -80,6 +78,8 @@ void HP303B_Detect(void) continue; } + HP303BSensor.begin(addresses[i]); + float t; float p; if (HP303B_Read(t, p, addresses[i])) @@ -87,6 +87,7 @@ void HP303B_Detect(void) I2cSetActiveFound(addresses[i], types); address = addresses[i]; type = 1; + break; } } } From d6e1ecbe2624695552c101d501ea8ded9193d12e Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Mon, 8 Jun 2020 09:13:01 +0200 Subject: [PATCH 171/581] Moved global variables to struct --- tasmota/xsns_73_hp303b.ino | 47 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index abff91f09..5a16ca905 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -35,16 +35,17 @@ #include // HP303B Opject LOLIN_HP303B HP303BSensor = LOLIN_HP303B(); +uint8_t bhp303b_addresses[2] = {HP303B_ADDR1, HP303B_ADDR2}; -uint8_t address; -uint8_t addresses[2] = {HP303B_ADDR1, HP303B_ADDR2}; -uint8_t type = 0; -uint8_t valid = 0; -float temperature; -float pressure; -int16_t oversampling = 7; -char types[7] = "HP303B"; - +struct BHP303B { + uint8_t address; + uint8_t type = 0; + uint8_t valid = 0; + float temperature; + float pressure; + int16_t oversampling = 7; + char types[7] = "HP303B"; +} bhp303b_sensor; /*********************************************************************************************/ bool HP303B_Read(float &temperature, float &pressure, uint8_t hp303b_address) @@ -53,11 +54,11 @@ bool HP303B_Read(float &temperature, float &pressure, uint8_t hp303b_address) float p; int16_t ret; - ret = HP303BSensor.measureTempOnce(t, oversampling); + ret = HP303BSensor.measureTempOnce(t, bhp303b_sensor.oversampling); if (ret != 0) return false; - ret = HP303BSensor.measurePressureOnce(p, oversampling); + ret = HP303BSensor.measurePressureOnce(p, bhp303b_sensor.oversampling); if (ret != 0) return false; @@ -71,22 +72,22 @@ bool HP303B_Read(float &temperature, float &pressure, uint8_t hp303b_address) void HP303B_Detect(void) { - for (uint32_t i = 0; i < sizeof(addresses); i++) + for (uint32_t i = 0; i < sizeof(bhp303b_addresses); i++) { - if (!I2cSetDevice(addresses[i])) + if (!I2cSetDevice(bhp303b_addresses[i])) { continue; } - HP303BSensor.begin(addresses[i]); + HP303BSensor.begin(bhp303b_addresses[i]); float t; float p; - if (HP303B_Read(t, p, addresses[i])) + if (HP303B_Read(t, p, bhp303b_addresses[i])) { - I2cSetActiveFound(addresses[i], types); - address = addresses[i]; - type = 1; + I2cSetActiveFound(bhp303b_addresses[i], bhp303b_sensor.types); + bhp303b_sensor.address = bhp303b_addresses[i]; + bhp303b_sensor.type = 1; break; } } @@ -95,12 +96,12 @@ void HP303B_Detect(void) void HP303B_Show(bool json) { - if (HP303B_Read(temperature, pressure, address)) + if (HP303B_Read(bhp303b_sensor.temperature, bhp303b_sensor.pressure, bhp303b_sensor.address)) { char str_temperature[33]; - dtostrfd(temperature, Settings.flag2.temperature_resolution, str_temperature); + dtostrfd(bhp303b_sensor.temperature, Settings.flag2.temperature_resolution, str_temperature); char str_pressure[33]; - dtostrfd(pressure, Settings.flag2.pressure_resolution, str_pressure); + dtostrfd(bhp303b_sensor.pressure, Settings.flag2.pressure_resolution, str_pressure); if (json) { @@ -109,7 +110,7 @@ void HP303B_Show(bool json) #ifdef USE_DOMOTICZ if (0 == tele_period) { - DomoticzSensor(DZ_TEMP, temperature); + DomoticzSensor(DZ_TEMP, bhp303b_sensor.temperature); } #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER @@ -140,7 +141,7 @@ bool Xsns73(uint8_t function) { HP303B_Detect(); } - else if (type) + else if (bhp303b_sensor.type) { switch (function) { From 6038921f93a06baca4ba73d7a16329c3483188e0 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 8 Jun 2020 09:24:49 +0200 Subject: [PATCH 172/581] scripter upload scripts --- lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp | 2 + tasmota/xdrv_10_scripter.ino | 170 ++++++++++++++---- 2 files changed, 134 insertions(+), 38 deletions(-) diff --git a/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp b/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp index 495c18ad8..c7cdeba0a 100644 --- a/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp +++ b/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp @@ -249,10 +249,12 @@ void ICACHE_RAM_ATTR ILI9488::fastSPIwrite(uint8_t d,uint8_t dc) { #else // ESP32 section void ILI9488::writedata(uint8_t d) { + ILI9488_START fastSPIwrite(d,1); } void ILI9488::writecommand(uint8_t c) { + ILI9488_START fastSPIwrite(c,0); } diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 888fa3cb8..5a79d50b5 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -1975,6 +1975,19 @@ chknext: fvar=glob_script_mem.script_mem_size+(glob_script_mem.script_size)+(PMEM_SIZE); goto exit; } + if (!strncmp(vname,"rnd(",4)) { + // tasmota switch state + GetNumericResult(vname+4,OPER_EQU,&fvar,0); + if (fvar<0) { + randomSeed(-fvar); + fvar=0; + } else { + fvar=random(fvar); + } + // skip ] bracket + len++; + goto exit; + } break; case 's': if (!strncmp(vname,"secs",4)) { @@ -3786,6 +3799,76 @@ const char HTTP_FORM_SDC_HREF[] PROGMEM = #endif +uint8_t *script_ex_ptr; +uint16_t uplsize; +uint8_t sc_state; + +// upload script and start immediately +void script_upload_start(void) { + + //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload execute")); + + HTTPUpload& upload = Webserver->upload(); + if (upload.status == UPLOAD_FILE_START) { + //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload start")); + script_ex_ptr=(uint8_t*)glob_script_mem.script_ram; + //AddLog_P2(LOG_LEVEL_INFO, PSTR("HTP: upload file %s, %d"),upload.filename.c_str(),upload.totalSize); + + if (strcmp(upload.filename.c_str(),"execute_script")) { + Web.upload_error=1; + WSSend(500, CT_PLAIN, F("500: wrong filename")); + return; + } + if (upload.totalSize>=glob_script_mem.script_size) { + Web.upload_error=1; + WSSend(500, CT_PLAIN, F("500: file to large")); + return; + } + uplsize=0; + + sc_state = bitRead(Settings.rule_enabled, 0); + bitWrite(Settings.rule_enabled,0,0); + + } else if(upload.status == UPLOAD_FILE_WRITE) { + //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload write")); + uint32_t csiz=upload.currentSize; + uint32_t tsiz=glob_script_mem.script_size-1; + if (uplsize" D_UPLOAD " " D_SUCCESSFUL "
"), WebColor(COL_TEXT_SUCCESS)); + WSContentSend_P(PSTR("

")); + WSContentSend_P(PSTR("

"),"/upl",D_UPL_DONE); + //WSContentSpaceButton(BUTTON_MAIN); + WSContentStop(); + } + WSContentStart_P(S_SCRIPT_FILE_UPLOAD); WSContentSendStyle(); WSContentSend_P(HTTP_FORM_FILE_UPLOAD,D_SDCARD_DIR); @@ -3931,18 +4025,6 @@ void Script_FileUploadConfiguration(void) File upload_file; -void ScriptFileUploadSuccess(void) { - WSContentStart_P(S_INFORMATION); - WSContentSendStyle(); - WSContentSend_P(PSTR("
" D_UPLOAD " " D_SUCCESSFUL "
"), WebColor(COL_TEXT_SUCCESS)); - WSContentSend_P(PSTR("

")); - WSContentSend_P(PSTR("

"),"/upl",D_UPL_DONE); - //WSContentSpaceButton(BUTTON_MAIN); - WSContentStop(); -} - - void script_upload(void) { @@ -4090,8 +4172,31 @@ void HandleScriptConfiguration(void) { WSContentSend_P(HTTP_SCRIPT_FORM_END); WSContentSpaceButton(BUTTON_CONFIGURATION); WSContentStop(); - } +} +void SaveScript(void) { + +#ifdef EEP_SCRIPT_SIZE + if (glob_script_mem.flags&1) { + EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram); + } +#endif // EEP_SCRIPT_SIZE + +#ifdef USE_SCRIPT_FATFS + if (glob_script_mem.flags&1) { + fsp->remove(FAT_SCRIPT_NAME); + File file=fsp->open(FAT_SCRIPT_NAME,FILE_WRITE); + file.write((const uint8_t*)glob_script_mem.script_ram,FAT_SCRIPT_SIZE); + file.close(); + } +#endif // USE_SCRIPT_FATFS + +#ifdef LITTLEFS_SCRIPT_SIZE + if (glob_script_mem.flags&1) { + SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,LITTLEFS_SCRIPT_SIZE); + } +#endif // LITTLEFS_SCRIPT_SIZE +} void ScriptSaveSettings(void) { @@ -4148,29 +4253,14 @@ void ScriptSaveSettings(void) { bitWrite(Settings.rule_enabled, 0, 0); } + SaveScript(); -#ifdef EEP_SCRIPT_SIZE - if (glob_script_mem.flags&1) { - EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram); - } -#endif // EEP_SCRIPT_SIZE - -#ifdef USE_SCRIPT_FATFS - if (glob_script_mem.flags&1) { - fsp->remove(FAT_SCRIPT_NAME); - File file=fsp->open(FAT_SCRIPT_NAME,FILE_WRITE); - file.write((const uint8_t*)glob_script_mem.script_ram,FAT_SCRIPT_SIZE); - file.close(); - } -#endif // USE_SCRIPT_FATFS - -#ifdef LITTLEFS_SCRIPT_SIZE - if (glob_script_mem.flags&1) { - SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,LITTLEFS_SCRIPT_SIZE); - } -#endif // LITTLEFS_SCRIPT_SIZE } + SaveScriptEnd(); +} + +void SaveScriptEnd(void) { if (glob_script_mem.script_mem) { Scripter_save_pvars(); free(glob_script_mem.script_mem); @@ -4183,7 +4273,7 @@ void ScriptSaveSettings(void) { uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], MAX_SCRIPT_SIZE-1); if (len_compressed > 0) { Settings.rules[0][len_compressed] = 0; - AddLog_P2(LOG_LEVEL_INFO,PSTR("script compressed to %d %%"),len_compressed * 100 / strlen(glob_script_mem.script_ram)); + AddLog_P2(LOG_LEVEL_INFO,PSTR("script compressed to %d bytes = %d %%"),len_compressed,len_compressed * 100 / strlen(glob_script_mem.script_ram)); } else { AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); } @@ -4204,8 +4294,6 @@ void ScriptSaveSettings(void) { #if defined(USE_SCRIPT_HUE) && defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) && defined(USE_LIGHT) - - #define HUE_DEV_MVNUM 5 #define HUE_DEV_NSIZE 16 struct HUE_SCRIPT { @@ -5738,7 +5826,9 @@ void script_task1(void *arg) { //if (timet1",3,0); + if (bitRead(Settings.rule_enabled, 0)) { + Run_Scripter(">t1",3,0); + } } } @@ -5752,7 +5842,9 @@ void script_task2(void *arg) { //if (timet2",3,0); + if (bitRead(Settings.rule_enabled, 0)) { + Run_Scripter(">t2",3,0); + } } } uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { @@ -5997,6 +6089,8 @@ bool Xdrv10(uint8_t function) case FUNC_WEB_ADD_HANDLER: Webserver->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration); Webserver->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration); + Webserver->on("/exs", HTTP_POST,[]() { Webserver->sendHeader("Location","/exs");Webserver->send(303);},script_upload_start); + Webserver->on("/exs", HTTP_GET,ScriptExecuteUploadSuccess); #ifdef USE_SCRIPT_FATFS Webserver->on("/u3", HTTP_POST,[]() { Webserver->sendHeader("Location","/u3");Webserver->send(303);},script_upload); From abfa4f4fcd8fb24b5d47a8a599cadd5acd8e5bda Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Mon, 8 Jun 2020 10:19:51 +0200 Subject: [PATCH 173/581] refactored implementation --- tasmota/xsns_73_hp303b.ino | 50 +++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index 5a16ca905..ad439e555 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -44,12 +44,14 @@ struct BHP303B { float temperature; float pressure; int16_t oversampling = 7; - char types[7] = "HP303B"; + char name[7] = "HP303B"; } bhp303b_sensor; /*********************************************************************************************/ -bool HP303B_Read(float &temperature, float &pressure, uint8_t hp303b_address) +bool HP303B_Read() { + if (bhp303b_sensor.valid) { bhp303b_sensor.valid--; } + float t; float p; int16_t ret; @@ -62,9 +64,10 @@ bool HP303B_Read(float &temperature, float &pressure, uint8_t hp303b_address) if (ret != 0) return false; - temperature = (float)ConvertTemp(t); - pressure = (float)ConvertPressure(p) / 100; //conversion to hPa + bhp303b_sensor.temperature = (float)ConvertTemp(t); + bhp303b_sensor.pressure = (float)ConvertPressure(p) / 100; //conversion to hPa + bhp303b_sensor.valid = SENSOR_MAX_MISS; return true; } @@ -74,29 +77,33 @@ void HP303B_Detect(void) { for (uint32_t i = 0; i < sizeof(bhp303b_addresses); i++) { - if (!I2cSetDevice(bhp303b_addresses[i])) - { - continue; - } + if (I2cActive(bhp303b_addresses[i])) { return; } - HP303BSensor.begin(bhp303b_addresses[i]); + bhp303b_sensor.address = bhp303b_addresses[i]; - float t; - float p; - if (HP303B_Read(t, p, bhp303b_addresses[i])) + HP303BSensor.begin( bhp303b_sensor.address); + + if (HP303B_Read()) { - I2cSetActiveFound(bhp303b_addresses[i], bhp303b_sensor.types); - bhp303b_sensor.address = bhp303b_addresses[i]; + I2cSetActiveFound(bhp303b_sensor.address, bhp303b_sensor.name); bhp303b_sensor.type = 1; break; } } } +void HP303B_EverySecond(void) +{ + if (uptime &1) { + if (!HP303B_Read()) { + AddLogMissed(bhp303b_sensor.name, bhp303b_sensor.valid); + } + } +} + void HP303B_Show(bool json) { - - if (HP303B_Read(bhp303b_sensor.temperature, bhp303b_sensor.pressure, bhp303b_sensor.address)) + if (bhp303b_sensor.valid) { char str_temperature[33]; dtostrfd(bhp303b_sensor.temperature, Settings.flag2.temperature_resolution, str_temperature); @@ -130,21 +137,20 @@ void HP303B_Show(bool json) bool Xsns73(uint8_t function) { - if (!I2cEnabled(XI2C_52)) - { - return false; - } + if (!I2cEnabled(XI2C_52)) { return false; } bool result = false; - if (FUNC_INIT == function) - { + if (FUNC_INIT == function) { HP303B_Detect(); } else if (bhp303b_sensor.type) { switch (function) { + case FUNC_EVERY_SECOND: + HP303B_EverySecond(); + break; case FUNC_JSON_APPEND: HP303B_Show(1); break; From 56ea7279bd32cfa688e15543552a34b4da5cb52c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 8 Jun 2020 10:55:12 +0200 Subject: [PATCH 174/581] Fix ESP32 compilation --- tasmota/tasmota_template_ESP32.h | 9 +++++++-- tasmota/xnrg_14_bl0940.ino | 17 +++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 7d47b0409..aea45ea6a 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -127,7 +127,8 @@ enum UserSelectablePins { GPIO_WEBCAM_PSRCS, GPIO_BOILER_OT_RX, GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin GPIO_WINDMETER_SPEED, // WindMeter speed counter pin - GPIO_KEY1_TC, // Touch pin as button + GPIO_KEY1_TC, // Touch pin as button + GPIO_BL0940_RX, // BL0940 serial interface GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -216,7 +217,8 @@ const char kSensorNames[] PROGMEM = D_GPIO_WEBCAM_HSD "|" D_GPIO_WEBCAM_PSRCS "|" D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" - D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BUTTON "_tc" + D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BUTTON "_tc|" + D_SENSOR_BL0940_RX ; const char kSensorNamesFixed[] PROGMEM = @@ -403,6 +405,9 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin #endif // IFDEF:USE_LE01MR +#ifdef USE_BL0940 + AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface +#endif #endif // USE_ENERGY_SENSOR // Serial diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index 99a738e81..cd9fcb884 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -29,7 +29,9 @@ #define XNRG_14 14 -#define BL0940_PULSES_NOT_INITIALIZED -1 +#define BL0940_PREF 1430 +#define BL0940_UREF 33000 +#define BL0940_IREF 2750 #define BL0940_BUFFER_SIZE 36 @@ -42,6 +44,7 @@ #define BL0940_READ_COMMAND 0x50 // 0x58 according to documentation #define BL0940_FULL_PACKET 0xAA + #define BL0940_PACKET_HEADER 0x55 // 0x58 according to documentation #include @@ -53,13 +56,11 @@ struct BL0940 { long current = 0; long power = 0; long power_cycle_first = 0; - long cf_pulses = 0; - long cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; +// long cf_pulses = 0; float temperature; int byte_counter = 0; uint8_t *rx_buffer = nullptr; - uint8_t power_invalid = 0; bool received = false; } Bl0940; @@ -85,7 +86,7 @@ void Bl0940Received(void) { Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10]; Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4]; Bl0940.power = Bl0940.rx_buffer[18] << 16 | Bl0940.rx_buffer[17] << 8 | Bl0940.rx_buffer[16]; - Bl0940.cf_pulses = Bl0940.rx_buffer[24] << 16 | Bl0940.rx_buffer[23] << 8 | Bl0940.rx_buffer[22]; +// Bl0940.cf_pulses = Bl0940.rx_buffer[24] << 16 | Bl0940.rx_buffer[23] << 8 | Bl0940.rx_buffer[22]; uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; Bl0940.temperature = ((170.0f/448.0f)*(((float)tps1/2.0f)-32.0f))-45.0f; @@ -171,9 +172,9 @@ void Bl0940SnsInit(void) { ClaimSerial(); } if (HLW_UREF_PULSE == Settings.energy_voltage_calibration) { - Settings.energy_voltage_calibration = 33003; - Settings.energy_current_calibration = 2243; - Settings.energy_power_calibration = 1414; + Settings.energy_voltage_calibration = BL0940_UREF; + Settings.energy_current_calibration = BL0940_IREF; + Settings.energy_power_calibration = BL0940_PREF; } for (uint32_t i = 0; i < 5; i++) { From b16621dde4b7279fa3819ab7568dcd6858739b30 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 8 Jun 2020 11:04:45 +0200 Subject: [PATCH 175/581] Fix BL0940 temperature calculation --- tasmota/xnrg_14_bl0940.ino | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index cd9fcb884..e9ad6ee45 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -55,7 +55,7 @@ struct BL0940 { long voltage = 0; long current = 0; long power = 0; - long power_cycle_first = 0; +// long power_cycle_first = 0; // long cf_pulses = 0; float temperature; @@ -88,7 +88,8 @@ void Bl0940Received(void) { Bl0940.power = Bl0940.rx_buffer[18] << 16 | Bl0940.rx_buffer[17] << 8 | Bl0940.rx_buffer[16]; // Bl0940.cf_pulses = Bl0940.rx_buffer[24] << 16 | Bl0940.rx_buffer[23] << 8 | Bl0940.rx_buffer[22]; uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; - Bl0940.temperature = ((170.0f/448.0f)*(((float)tps1/2.0f)-32.0f))-45.0f; + float t = ((170.0f/448.0f)*(((float)tps1/2.0f)-32.0f))-45.0f; + Bl0940.temperature = ConvertTemp(t); if (Energy.power_on) { // Powered on Energy.voltage[0] = (float)Bl0940.voltage / Settings.energy_voltage_calibration; @@ -100,7 +101,7 @@ void Bl0940Received(void) { Energy.current[0] = 0; } } else { // Powered off - Bl0940.power_cycle_first = 0; +// Bl0940.power_cycle_first = 0; Energy.voltage[0] = 0; Energy.active_power[0] = 0; Energy.current[0] = 0; @@ -111,7 +112,7 @@ bool Bl0940SerialInput(void) { while (Bl0940Serial->available()) { yield(); uint8_t serial_in_byte = Bl0940Serial->read(); - if (!Bl0940.received && (BL0940_PACKET_HEADER == serial_in_byte)) { // Packet header + if (!Bl0940.received && (BL0940_PACKET_HEADER == serial_in_byte)) { Bl0940.received = true; Bl0940.byte_counter = 0; } From 0b41d321d4ac0761b296aa7eeb9276963a65dc49 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 8 Jun 2020 11:13:57 +0200 Subject: [PATCH 176/581] Fix BL0940 checksum message --- tasmota/xnrg_14_bl0940.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index e9ad6ee45..655f3d8df 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -131,12 +131,13 @@ bool Bl0940SerialInput(void) { Bl0940.received = false; return true; } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); +// AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); do { // Sync buffer with data (issue #1907 and #3425) memmove(Bl0940.rx_buffer, Bl0940.rx_buffer +1, BL0940_BUFFER_SIZE -1); Bl0940.byte_counter--; } while ((Bl0940.byte_counter > 1) && (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0])); if (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0]) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); Bl0940.received = false; Bl0940.byte_counter = 0; } From 7e1c62e78442c7a3d773a0bcea564c86f0469d3a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 8 Jun 2020 12:52:05 +0200 Subject: [PATCH 177/581] Add Unishox tools --- tools/unishox/clipboard-const-converter.py | 112 +++++ tools/unishox/unishox.py | 520 +++++++++++++++++++++ tools/unishox/unishox.pyc | Bin 0 -> 14134 bytes 3 files changed, 632 insertions(+) create mode 100644 tools/unishox/clipboard-const-converter.py create mode 100644 tools/unishox/unishox.py create mode 100644 tools/unishox/unishox.pyc diff --git a/tools/unishox/clipboard-const-converter.py b/tools/unishox/clipboard-const-converter.py new file mode 100644 index 000000000..ee180d8a9 --- /dev/null +++ b/tools/unishox/clipboard-const-converter.py @@ -0,0 +1,112 @@ +from tkinter import Tk +import unishox + +# get text from clipboard expecting something like that: +# const char HTTP_SCRIPT_WIFI[] PROGMEM = +# "function c(l){" // comments +# "eb('s1').value=l.innerText||l.textContent;" // comments +# "eb('p1').focus();" // comments +# // comments +# "}"; + +text = Tk().clipboard_get() +# print(text) + +# parsing and cleaning +text_list = text.splitlines() +text = '' #just reuse the string +const_name = '' #default if no name will be found + +line_number = 0 +for line in text_list: + pos = line.find("const char") + # print(pos, line) + if pos > -1: + line_list = line.rsplit(" ") + for el in line_list: + if el.find('[]') > -1: + const_name = el[:-2] #extract the "const char" variable name + line_list.pop(line_number) + else: # remove line comments + line_el = line.rsplit("//") + # print('Splitted line list by //' % line_el) + # print(line_el[0]) + text = text + line_el[0] + line_number = line_number +1 + +# print const_name +# print text + +#remove unwanted quotation marks +qm = [] +pos =0 +last_char = "" +for char in text: + if char == "\"": + if last_char != "\\": + qm.append(pos) #find all quotation marks without preceding backslash + last_char = char + pos = pos + 1 +# print(qm) +lastel = 0 +input = "" +for pos in qm: + sub = text[lastel+1:pos:] + if not sub.isspace() and pos-lastel > 1: + # print(lastel, pos) + input = input + sub #only copy substrings that are not whitespace + # print(text[lastel+1:pos:]) + lastel = pos + +print("####### Parsing intput:") +print("Const char name: ",const_name) +print('####### Cleaned input:') +print(input) + +#construct output (taken from shadinger) +input = input.replace("\\t", "\t") +input = input.replace("\\n", "\n") +input = input.replace("\\r", "\r") +input = input.replace("\\f", "\f") +input = input.replace("\\b", "\b") +input = input.replace("\\\"", u"\u0022") + +in_bytes = bytearray(input, 'utf-8') +in_len = len(in_bytes) +out_bytes = bytearray(in_len * 2) + +UNISHOX = unishox.Unishox() +out_len = UNISHOX.compress(in_bytes, len(in_bytes), out_bytes, len(out_bytes)) +print("####### Compression result:") +print("Compressed from {i} to {o}, -{p:.1f}%".format(i=in_len, o=out_len, p=(100-out_len/in_len*100))) +out_bytes = out_bytes[:out_len] # truncate to right size + +#PROGMEM is growing in steps 0,8,24,40,56,... bytes of data resulting in size of 0,16,32,48,64,... bytes +for in_real in range(8,in_len+16,16): + if in_real>=in_len: + print("Old real PROGMEM-size:",in_real+8,"(unused bytes:",in_real-in_len,")") + break +for out_real in range(8,out_len+16,16): + if out_real>=out_len: + print("New real PROGMEM-size:",out_real+8,"(unused bytes:",out_real-out_len,")") + break +print("the optimal case would be raw bytes + 8, real difference: ", in_real - out_real, "bytes") +# https://www.geeksforgeeks.org/break-list-chunks-size-n-python/ +def chunked(my_list, n): + return [my_list[i * n:(i + 1) * n] for i in range((len(my_list) + n - 1) // n )] + +# split in chunks of 20 characters +chunks = chunked(out_bytes, 20) + +lines_raw = [ "\"\\x" + "\\x".join( [ '{:02X}'.format(b) for b in chunk ] ) + "\"" for chunk in chunks ] +line_complete = "const char " + const_name + "_COMPRESSED" +"[] PROGMEM = " + ("\n" + " "*29).join(lines_raw) + ";" +lines = "const size_t " + const_name +"_SIZE = {size};\n{lines}".format(size=in_len, lines=line_complete) + +print('####### Final output:') +print(lines) + +definition = "#define " + const_name + " Decompress(" + const_name + "_COMPRESSED" + "," + const_name +"_SIZE" + ").c_str()" +print(definition) + + +# maybe add export to clipboard for later ... \ No newline at end of file diff --git a/tools/unishox/unishox.py b/tools/unishox/unishox.py new file mode 100644 index 000000000..1cce14706 --- /dev/null +++ b/tools/unishox/unishox.py @@ -0,0 +1,520 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Python Class for compressing short strings. + +This class contains a highly modified and optimized version of Unishox +for Tasmota converted in C ported to Pyhton3. + +It was basically developed to individually compress and decompress small strings +(see https://github.com/siara-cc/Unishox) +In general compression utilities such as zip, gzip do not compress short strings +well and often expand them. They also use lots of memory which makes them unusable +in constrained environments like Arduino. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +class Unishox: + """ + This is a highly modified and optimized version of Unishox + for Tasmota, aimed at compressing `Rules` which are typically + short strings from 50 to 500 bytes. + + @author Stephan Hadinger + @revised Norbert Richter + """ + + # pylint: disable=bad-continuation,bad-whitespace,line-too-long + #cl_95 = [0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12] + cl_95 = [0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x46B0 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x46A0 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x46C0 + 13, 0x2320 + 12, 0x46D0 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12] + + # enum {SHX_STATE_1 = 1, SHX_STATE_2}; // removed Unicode state + SHX_STATE_1 = 1 + SHX_STATE_2 = 2 + + SHX_SET1 = 0 + SHX_SET1A = 1 + SHX_SET1B = 2 + SHX_SET2 = 3 + + sets = [['\0', ' ', 'e', '\0', 't', 'a', 'o', 'i', 'n', 's', 'r'], + ['\0', 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'], + ['f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', '\0', '\0', '\0'], + ['\0', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'], + ['.', ',', '-', '/', '?', '+', ' ', '(', ')', '$', '@'], + [';', '#', ':', '<', '^', '*', '"', '{', '}', '[', ']'], + ['=', '%', '\'', '>', '&', '_', '!', '\\', '|', '~', '`']] + + us_vcode = [2 + (0 << 3), 3 + (3 << 3), 3 + (1 << 3), 4 + (6 << 3), 0, + # 5, 6, 7, 8, 9, 10 + 4 + (4 << 3), 3 + (2 << 3), 4 + (8 << 3), 0, 0, 0, + # 11, 12, 13, 14, 15 + 4 + (7 << 3), 0, 4 + (5 << 3), 0, 5 + (9 << 3), + # 16, 17, 18, 19, 20, 21, 22, 23 + 0, 0, 0, 0, 0, 0, 0, 0, + # 24, 25, 26, 27, 28, 29, 30, 31 + 0, 0, 0, 0, 0, 0, 0, 5 + (10 << 3) ] + # 0, 1, 2, 3, 4, 5, 6, 7, + us_hcode = [1 + (1 << 3), 2 + (0 << 3), 0, 3 + (2 << 3), 0, 0, 0, 5 + (3 << 3), + # 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 5 + (5 << 3), + # 16, 17, 18, 19, 20, 21, 22, 23 + 0, 0, 0, 0, 0, 0, 0, 5 + (4 << 3), + # 24, 25, 26, 27, 28, 29, 30, 31 + 0, 0, 0, 0, 0, 0, 0, 5 + (6 << 3) ] + # pylint: enable=bad-continuation,bad-whitespace + + ESCAPE_MARKER = 0x2A + + TERM_CODE = 0x37C0 + # TERM_CODE_LEN = 10 + DICT_CODE = 0x0000 + DICT_CODE_LEN = 5 + #DICT_OTHER_CODE = 0x0000 + #DICT_OTHER_CODE_LEN = 6 + RPT_CODE_TASMOTA = 0x3780 + RPT_CODE_TASMOTA_LEN = 10 + BACK2_STATE1_CODE = 0x2000 + BACK2_STATE1_CODE_LEN = 4 + #BACK_FROM_UNI_CODE = 0xFE00 + #BACK_FROM_UNI_CODE_LEN = 8 + LF_CODE = 0x3700 + LF_CODE_LEN = 9 + TAB_CODE = 0x2400 + TAB_CODE_LEN = 7 + ALL_UPPER_CODE = 0x2200 + ALL_UPPER_CODE_LEN = 8 + SW2_STATE2_CODE = 0x3800 + SW2_STATE2_CODE_LEN = 7 + ST2_SPC_CODE = 0x3B80 + ST2_SPC_CODE_LEN = 11 + BIN_CODE_TASMOTA = 0x8000 + BIN_CODE_TASMOTA_LEN = 3 + + NICE_LEN = 5 + + mask = [0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF] + + # pylint: disable=missing-function-docstring,invalid-name + + # Input + # out = bytearray + def append_bits(self, out, ol, code, clen, state): + #print("Append bits {ol} {code} {clen} {state}".format(ol=ol, code=code, clen=clen, state=state)) + if state == self.SHX_STATE_2: + # remove change state prefix + if (code >> 9) == 0x1C: + code <<= 7 + clen -= 7 + while clen > 0: + cur_bit = ol % 8 + blen = 8 if (clen > 8) else clen + a_byte = (code >> 8) & self.mask[blen - 1] + #print("append_bits a_byte {ab} blen {blen}".format(ab=a_byte,blen=blen)) + a_byte >>= cur_bit + if blen + cur_bit > 8: + blen = (8 - cur_bit) + if cur_bit == 0: + out[ol // 8] = a_byte + else: + out[ol // 8] |= a_byte + code <<= blen + ol += blen + if 0 == ol % 8: # pylint: disable=misplaced-comparison-constant + # we completed a full byte + last_c = out[(ol // 8) - 1] + if last_c in (0, self.ESCAPE_MARKER): + out[ol // 8] = 1 + last_c # increment to 0x01 or 0x2B + out[(ol // 8) -1] = self.ESCAPE_MARKER # replace old value with marker + ol += 8 # add one full byte + clen -= blen + return ol + + codes = [0x82, 0xC3, 0xE5, 0xED, 0xF5] # pylint: disable=bad-whitespace + bit_len = [ 5, 7, 9, 12, 16] # pylint: disable=bad-whitespace + + def encodeCount(self, out, ol, count): + #print("encodeCount ol = {ol}, count = {count}".format(ol=ol, count=count)) + till = 0 + base = 0 + for i in range(len(self.bit_len)): + bit_len_i = self.bit_len[i] + till += (1 << bit_len_i) + if count < till: + codes_i = self.codes[i] + ol = self.append_bits(out, ol, (codes_i & 0xF8) << 8, codes_i & 0x07, 1) + #print("encodeCount append_bits ol = {ol}, code = {code}, len = {len}".format(ol=ol,code=(codes_i & 0xF8) << 8,len=codes_i & 0x07)) + ol = self.append_bits(out, ol, (count - base) << (16 - bit_len_i), bit_len_i, 1) + #print("encodeCount append_bits ol = {ol}, code = {code}, len = {len}".format(ol=ol,code=(count - base) << (16 - bit_len_i),len=bit_len_i)) + return ol + base = till + return ol + + # Returns (int, ol, state, is_all_upper) + def matchOccurance(self, inn, len_, l_, out, ol, state, is_all_upper): + # int j, k; + longest_dist = 0 + longest_len = 0 + #for (j = l_ - self.NICE_LEN; j >= 0; j--) { + j = l_ - self.NICE_LEN + while j >= 0: + k = l_ + #for (k = l_; k < len && j + k - l_ < l_; k++) { + while k < len_ and j + k - l_ < l_: + if inn[k] != inn[j + k - l_]: + break + k += 1 + if k - l_ > self.NICE_LEN - 1: + match_len = k - l_ - self.NICE_LEN + match_dist = l_ - j - self.NICE_LEN + 1 + if match_len > longest_len: + longest_len = match_len + longest_dist = match_dist + j -= 1 + + if longest_len: + #print("longest_len {ll}".format(ll=longest_len)) + #ol_save = ol + if state == self.SHX_STATE_2 or is_all_upper: + is_all_upper = 0 + state = self.SHX_STATE_1 + ol = self.append_bits(out, ol, self.BACK2_STATE1_CODE, self.BACK2_STATE1_CODE_LEN, state) + + ol = self.append_bits(out, ol, self.DICT_CODE, self.DICT_CODE_LEN, 1) + ol = self.encodeCount(out, ol, longest_len) + ol = self.encodeCount(out, ol, longest_dist) + #print("longest_len {ll} longest_dist {ld} ol {ols}-{ol}".format(ll=longest_len, ld=longest_dist, ol=ol, ols=ol_save)) + l_ += longest_len + self.NICE_LEN + l_ -= 1 + + return l_, ol, state, is_all_upper + return -l_, ol, state, is_all_upper + + + def compress(self, inn, len_, out, len_out): + ol = 0 + state = self.SHX_STATE_1 + is_all_upper = 0 + l = 0 + while l < len_: + # for (l=0; l 0: + #print("matchOccurance l = {l} l_old = {lo}".format(l=l,lo=l_old)) + l += 1 # for loop + continue + + l = -l + + if state == self.SHX_STATE_2: # if Set2 + if ord(' ') <= c_in <= ord('@') or ord('[') <= c_in <= ord('`') or ord('{') <= c_in <= ord('~'): + pass + else: + state = self.SHX_STATE_1 # back to Set1 and lower case + ol = self.append_bits(out, ol, self.BACK2_STATE1_CODE, self.BACK2_STATE1_CODE_LEN, state) + + is_upper = 0 + if ord('A') <= c_in <= ord('Z'): + is_upper = 1 + else: + if is_all_upper: + is_all_upper = 0 + ol = self.append_bits(out, ol, self.BACK2_STATE1_CODE, self.BACK2_STATE1_CODE_LEN, state) + + if 32 <= c_in <= 126: + if is_upper and not is_all_upper: + ll = l+5 + # for (ll=l+5; ll>=l && ll ord('Z'): + break + + ll -= 1 + + if ll == l-1: + ol = self.append_bits(out, ol, self.ALL_UPPER_CODE, self.ALL_UPPER_CODE_LEN, state) # CapsLock + is_all_upper = 1 + + if state == self.SHX_STATE_1 and ord('0') <= c_in <= ord('9'): + ol = self.append_bits(out, ol, self.SW2_STATE2_CODE, self.SW2_STATE2_CODE_LEN, state) # Switch to sticky Set2 + state = self.SHX_STATE_2 + + c_in -= 32 + if is_all_upper and is_upper: + c_in += 32 + if c_in == 0 and state == self.SHX_STATE_2: + ol = self.append_bits(out, ol, self.ST2_SPC_CODE, self.ST2_SPC_CODE_LEN, state) # space from Set2 ionstead of Set1 + else: + # ol = self.append_bits(out, ol, pgm_read_word(&c_95[c_in]), pgm_read_byte(&l_95[c_in]), state); // original version with c/l in split arrays + cl = self.cl_95[c_in] + cl_code = cl & 0xFFF0 + cl_len = cl & 0x000F + if cl_len == 13: + cl_code = cl_code >> 1 + ol = self.append_bits(out, ol, cl_code, cl_len, state) + + elif c_in == 10: + ol = self.append_bits(out, ol, self.LF_CODE, self.LF_CODE_LEN, state) # LF + elif c_in == '\t': + ol = self.append_bits(out, ol, self.TAB_CODE, self.TAB_CODE_LEN, state) # TAB + else: + ol = self.append_bits(out, ol, self.BIN_CODE_TASMOTA, self.BIN_CODE_TASMOTA_LEN, state) # Binary, we reuse the Unicode marker which 3 bits instead of 9 + ol = self.encodeCount(out, ol, (255 - c_in) & 0xFF) + + + # check that we have some headroom in the output buffer + if ol // 8 >= len_out - 4: + return -1 # we risk overflow and crash + + l += 1 + + bits = ol % 8 + if bits: + ol = self.append_bits(out, ol, self.TERM_CODE, 8 - bits, 1) # 0011 0111 1100 0000 TERM = 0011 0111 11 + return (ol + 7) // 8 + # return ol // 8 + 1 if (ol%8) else 0 + + + def getBitVal(self, inn, bit_no, count): + c_in = inn[bit_no >> 3] + if bit_no >> 3 and self.ESCAPE_MARKER == inn[(bit_no >> 3) - 1]: + c_in -= 1 + r = 1 << count if (c_in & (0x80 >> (bit_no % 8))) else 0 + #print("getBitVal r={r}".format(r=r)) + return r + + # Returns: + # 0..11 + # or -1 if end of stream + def getCodeIdx(self, code_type, inn, len_, bit_no_p): + code = 0 + count = 0 + while count < 5: + if bit_no_p >= len_: + return -1, bit_no_p + # detect marker + if self.ESCAPE_MARKER == inn[bit_no_p >> 3]: + bit_no_p += 8 # skip marker + + if bit_no_p >= len_: + return -1, bit_no_p + + code += self.getBitVal(inn, bit_no_p, count) + bit_no_p += 1 + count += 1 + code_type_code = code_type[code] + if code_type_code and (code_type_code & 0x07) == count: + #print("getCodeIdx = {r}".format(r=code_type_code >> 3)) + return code_type_code >> 3, bit_no_p + + #print("getCodeIdx not found = {r}".format(r=1)) + return 1, bit_no_p + + def getNumFromBits(self, inn, bit_no, count): + ret = 0 + while count: + count -= 1 + if self.ESCAPE_MARKER == inn[bit_no >> 3]: + bit_no += 8 # skip marker + ret += self.getBitVal(inn, bit_no, count) + bit_no += 1 + return ret + + def readCount(self, inn, bit_no_p, len_): + (idx, bit_no_p) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no_p) + if idx >= 1: + idx -= 1 # we skip v = 1 (code '0') since we no more accept 2 bits encoding + if idx >= 5 or idx < 0: + return 0, bit_no_p # unsupported or end of stream + till = 0 + bit_len_idx = 0 + base = 0 + #for (uint32_t i = 0; i <= idx; i++) { + i = 0 + while i <= idx: + # for i in range(idx): + base = till + bit_len_idx = self.bit_len[i] + till += (1 << bit_len_idx) + i += 1 + + count = self.getNumFromBits(inn, bit_no_p, bit_len_idx) + base + #print("readCount getNumFromBits = {count} ({bl})".format(count=count,bl=bit_len_idx)) + + bit_no_p += bit_len_idx + return count, bit_no_p + + def decodeRepeat(self, inn, len_, out, ol, bit_no): + #print("decodeRepeat Enter") + (dict_len, bit_no) = self.readCount(inn, bit_no, len_) + dict_len += self.NICE_LEN + (dist, bit_no) = self.readCount(inn, bit_no, len_) + dist += self.NICE_LEN - 1 + #memcpy(out + ol, out + ol - dist, dict_len); + i = 0 + while i < dict_len: + #for i in range(dict_len): + out[ol + i] = out[ol - dist + i] + i += 1 + ol += dict_len + + return ol, bit_no + + def decompress(self, inn, len_, out, len_out): + ol = 0 + bit_no = 0 + dstate = self.SHX_SET1 + is_all_upper = 0 + + len_ <<= 3 # *8, len_ in bits + out[ol] = 0 + while bit_no < len_: + c = 0 + is_upper = is_all_upper + (v, bit_no) = self.getCodeIdx(self.us_vcode, inn, len_, bit_no) # read vCode + #print("bit_no {b}. v = {v}".format(b=bit_no,v=v)) + if v < 0: + break # end of stream + h = dstate # Set1 or Set2 + if v == 0: # Switch which is common to Set1 and Set2, first entry + (h, bit_no) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no) # read hCode + #print("bit_no {b}. h = {h}".format(b=bit_no,h=h)) + if h < 0: + break # end of stream + if h == self.SHX_SET1: # target is Set1 + if dstate == self.SHX_SET1: # Switch from Set1 to Set1 us UpperCase + if is_all_upper: # if CapsLock, then back to LowerCase + is_upper = 0 + is_all_upper = 0 + continue + + (v, bit_no) = self.getCodeIdx(self.us_vcode, inn, len_, bit_no) # read again vCode + if v < 0: + break # end of stream + if v == 0: + (h, bit_no) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no) # read second hCode + if h < 0: + break # end of stream + if h == self.SHX_SET1: # If double Switch Set1, the CapsLock + is_all_upper = 1 + continue + + is_upper = 1 # anyways, still uppercase + else: + dstate = self.SHX_SET1 # if Set was not Set1, switch to Set1 + continue + + elif h == self.SHX_SET2: # If Set2, switch dstate to Set2 + if dstate == self.SHX_SET1: + dstate = self.SHX_SET2 + continue + + if h != self.SHX_SET1: # all other Sets (why not else) + (v, bit_no) = self.getCodeIdx(self.us_vcode, inn, len_, bit_no) # we changed set, now read vCode for char + if v < 0: + break # end of stream + + if v == 0 and h == self.SHX_SET1A: + #print("v = 0, h = self.SHX_SET1A") + if is_upper: + (temp, bit_no) = self.readCount(inn, bit_no, len_) + out[ol] = 255 - temp # binary + ol += 1 + else: + (ol, bit_no) = self.decodeRepeat(inn, len_, out, ol, bit_no) # dist + continue + + if h == self.SHX_SET1 and v == 3: + # was Unicode, will do Binary instead + (temp, bit_no) = self.readCount(inn, bit_no, len_) + out[ol] = 255 - temp # binary + ol += 1 + continue + + if h < 7 and v < 11: + #print("h {h} v {v}".format(h=h,v=v)) + c = ord(self.sets[h][v]) + if ord('a') <= c <= ord('z'): + if is_upper: + c -= 32 # go to UpperCase for letters + else: # handle all other cases + if is_upper and dstate == self.SHX_SET1 and v == 1: + c = ord('\t') # If UpperCase Space, change to TAB + if h == self.SHX_SET1B: + if 8 == v: # was LF or RPT, now only LF # pylint: disable=misplaced-comparison-constant + out[ol] = ord('\n') + ol += 1 + continue + + if 9 == v: # was CRLF, now RPT # pylint: disable=misplaced-comparison-constant + (count, bit_no) = self.readCount(inn, bit_no, len_) + count += 4 + if ol + count >= len_out: + return -1 # overflow + + rpt_c = out[ol - 1] + while count: + count -= 1 + out[ol] = rpt_c + ol += 1 + continue + + if 10 == v: # pylint: disable=misplaced-comparison-constant + break # TERM, stop decoding + + out[ol] = c + ol += 1 + + if ol >= len_out: + return -1 # overflow + + return ol + + # pylint: enable=missing-function-docstring + + +if __name__ == "__main__": + # pylint: disable=line-too-long + UNISHOX = Unishox() + BYTES_ = bytearray(2048) + INN = bytearray(b'ON Switch1#State==1 DO Add1 1 ENDON ON Var1#State==0 DO ShutterStop1 ENDON ON Var1#State==1 DO ShutterClose1 ENDON ON Var1#State>=2 DO Var1 0 ENDON ON Shutter1#Close DO Var1 0 ENDON ON Switch2#State==1 DO Add2 1 ENDON ON Var2#State==0 DO ShutterStop1 ENDON ON Var2#State==1 DO ShutterOpen1 ENDON ON Var2#State>=2 DO Var2 0 ENDON ON Shutter1#Open DO Var2 0 ENDON') + LEN_ = UNISHOX.compress(INN, len(INN), BYTES_, len(BYTES_)) + print("Compressed from {fromm} to {to} ({p}%)".format(fromm=len(INN), to=LEN_, p=(100-LEN_/len(INN)*100))) + + OUT = bytearray(2048) + LEN_ = UNISHOX.decompress(BYTES_, LEN_, OUT, len(OUT)) + print(str(OUT, 'utf-8').split('\x00')[0]) diff --git a/tools/unishox/unishox.pyc b/tools/unishox/unishox.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2c127f091cd9e566505df0886064be9f61e9950 GIT binary patch literal 14134 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 Co^0d* literal 0 HcmV?d00001 From 61ea7535a80cf0e0f3283df550437865568e26f4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 8 Jun 2020 15:09:51 +0200 Subject: [PATCH 178/581] Refactor and Domoticzify VL53L0X driver Refactor and Domoticzify VL53L0X driver (#8637, #8640) --- tasmota/xsns_45_vl53l0x.ino | 102 ++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 38 deletions(-) diff --git a/tasmota/xsns_45_vl53l0x.ino b/tasmota/xsns_45_vl53l0x.ino index ef9de345c..f3a9bbe74 100644 --- a/tasmota/xsns_45_vl53l0x.ino +++ b/tasmota/xsns_45_vl53l0x.ino @@ -1,5 +1,5 @@ /* - xsns_45_vl53l0x.ino - VL53L0X support for Tasmota + xsns_45_vl53l0x.ino - VL53L0X time of flight sensor support for Tasmota Copyright (C) 2020 Theo Arends and Gerhard Mutz @@ -19,23 +19,30 @@ #ifdef USE_I2C #ifdef USE_VL53L0X +/*********************************************************************************************\ + * VL53L0x time of flight sensor + * + * I2C Addres: 0x29 +\*********************************************************************************************/ -#define XSNS_45 45 -#define XI2C_31 31 // See I2CDEVICES.md +#define XSNS_45 45 +#define XI2C_31 31 // See I2CDEVICES.md #include #include "VL53L0X.h" VL53L0X sensor; -uint8_t vl53l0x_ready = 0; -uint16_t vl53l0x_distance; -uint16_t Vl53l0_buffer[5]; -uint8_t Vl53l0_index; +struct { + uint16_t distance; + uint16_t distance_prev; + uint16_t buffer[5]; + uint8_t ready = 0; + uint8_t index; +} Vl53l0x; /********************************************************************************************/ -void Vl53l0Detect(void) -{ +void Vl53l0Detect(void) { if (!I2cSetDevice(0x29)) { return; } if (!sensor.init()) { return; } @@ -49,9 +56,9 @@ void Vl53l0Detect(void) // instead, provide a desired inter-measurement period in // ms (e.g. sensor.startContinuous(100)). sensor.startContinuous(); - vl53l0x_ready = 1; + Vl53l0x.ready = 1; - Vl53l0_index=0; + Vl53l0x.index = 0; } #ifdef USE_WEBSERVER @@ -61,50 +68,64 @@ const char HTTP_SNS_VL53L0X[] PROGMEM = #define USE_VL_MEDIAN -void Vl53l0Every_250MSecond(void) -{ - uint16_t tbuff[5],tmp; - uint8_t flag; - +void Vl53l0Every_250MSecond(void) { // every 200 ms uint16_t dist = sensor.readRangeContinuousMillimeters(); - if (dist==0 || dist>2000) { - dist=9999; + if ((0 == dist) || (dist > 2000)) { + dist = 9999; } #ifdef USE_VL_MEDIAN // store in ring buffer - Vl53l0_buffer[Vl53l0_index]=dist; - Vl53l0_index++; - if (Vl53l0_index>=5) Vl53l0_index=0; + Vl53l0x.buffer[Vl53l0x.index] = dist; + Vl53l0x.index++; + if (Vl53l0x.index >= 5) { + Vl53l0x.index = 0; + } // sort list and take median - memmove(tbuff,Vl53l0_buffer,sizeof(tbuff)); - for (byte ocnt=0; ocnt<5; ocnt++) { - flag=0; - for (byte count=0; count<4; count++) { - if (tbuff[count]>tbuff[count+1]) { - tmp=tbuff[count]; - tbuff[count]=tbuff[count+1]; - tbuff[count+1]=tmp; - flag=1; + uint16_t tbuff[5]; + memmove(tbuff, Vl53l0x.buffer, sizeof(tbuff)); + uint16_t tmp; + uint8_t flag; + for (uint32_t ocnt = 0; ocnt < 5; ocnt++) { + flag = 0; + for (uint32_t count = 0; count < 4; count++) { + if (tbuff[count] > tbuff[count +1]) { + tmp = tbuff[count]; + tbuff[count] = tbuff[count +1]; + tbuff[count +1] = tmp; + flag = 1; } } - if (!flag) break; + if (!flag) { break; } } - vl53l0x_distance=tbuff[2]; + Vl53l0x.distance = tbuff[2]; #else - vl53l0x_distance=dist; + Vl53l0x.distance = dist; #endif } -void Vl53l0Show(boolean json) -{ +#ifdef USE_DOMOTICZ +void Vl53l0Every_Second(void) { + if (abs(Vl53l0x.distance - Vl53l0x.distance_prev) > 8) { + Vl53l0x.distance_prev = Vl53l0x.distance; + DomoticzSensor(DZ_ILLUMINANCE, Vl53l0x.distance); + } +} +#endif // USE_DOMOTICZ + +void Vl53l0Show(boolean json) { if (json) { - ResponseAppend_P(PSTR(",\"VL53L0X\":{\"" D_JSON_DISTANCE "\":%d}"), vl53l0x_distance); + ResponseAppend_P(PSTR(",\"VL53L0X\":{\"" D_JSON_DISTANCE "\":%d}"), Vl53l0x.distance); +#ifdef USE_DOMOTICZ + if (0 == tele_period) { + DomoticzSensor(DZ_ILLUMINANCE, Vl53l0x.distance); + } +#endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { - WSContentSend_PD(HTTP_SNS_VL53L0X, vl53l0x_distance); + WSContentSend_PD(HTTP_SNS_VL53L0X, Vl53l0x.distance); #endif } } @@ -122,11 +143,16 @@ bool Xsns45(byte function) if (FUNC_INIT == function) { Vl53l0Detect(); } - else if (vl53l0x_ready) { + else if (Vl53l0x.ready) { switch (function) { case FUNC_EVERY_250_MSECOND: Vl53l0Every_250MSecond(); break; +#ifdef USE_DOMOTICZ + case FUNC_EVERY_SECOND: + Vl53l0Every_Second(); + break; +#endif // USE_DOMOTICZ case FUNC_JSON_APPEND: Vl53l0Show(1); break; From 92643e89d023aafbfc4af8e09cc4de9771f5627b Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Mon, 8 Jun 2020 20:37:04 +0200 Subject: [PATCH 179/581] Added support for multiple i2c addresses --- lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp | 32 +++---- lib/LOLIN_HP303B/src/LOLIN_HP303B.h | 10 +-- tasmota/xsns_73_hp303b.ino | 115 ++++++++++++++------------ 3 files changed, 84 insertions(+), 73 deletions(-) diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp index fdeebd6a0..7f7f60a3f 100644 --- a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp @@ -35,7 +35,7 @@ LOLIN_HP303B::~LOLIN_HP303B(void) * &bus: I2CBus which connects MC to HP303B * slaveAddress: Address of the HP303B (0x77 or 0x76) */ -void LOLIN_HP303B::begin(TwoWire &bus, uint8_t slaveAddress) +uint8_t LOLIN_HP303B::begin(TwoWire &bus, uint8_t slaveAddress) { //this flag will show if the initialization was successful m_initFail = 0U; @@ -50,20 +50,20 @@ void LOLIN_HP303B::begin(TwoWire &bus, uint8_t slaveAddress) delay(50); //startup time of HP303B - init(); + return init(); } -void LOLIN_HP303B::begin(uint8_t slaveAddress) +uint8_t LOLIN_HP303B::begin(uint8_t slaveAddress) { - begin(Wire,slaveAddress); + return begin(Wire,slaveAddress); } /** * SPI begin function for HP303B with 4-wire SPI */ -void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect) +uint8_t LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect) { - begin(bus, chipSelect, 0U); + return begin(bus, chipSelect, 0U); } /** @@ -74,7 +74,7 @@ void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect) * threeWire: 1 if HP303B is connected with 3-wire SPI * 0 if HP303B is connected with 4-wire SPI (standard) */ -void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) +uint8_t LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) { //this flag will show if the initialization was successful m_initFail = 0U; @@ -102,11 +102,11 @@ void LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) if(writeByte(HP303B__REG_ADR_SPI3W, HP303B__REG_CONTENT_SPI3W)) { m_initFail = 1U; - return; + return 0U; } } - init(); + return init(); } /** @@ -840,14 +840,14 @@ int16_t LOLIN_HP303B::correctTemp(void) * This function has to be called from begin() * and requires a valid bus initialization. */ -void LOLIN_HP303B::init(void) +uint8_t LOLIN_HP303B::init(void) { int16_t prodId = readByteBitfield(HP303B__REG_INFO_PROD_ID); if(prodId != HP303B__PROD_ID) { //Connected device is not a HP303B m_initFail = 1U; - return; + return 0U; } m_productID = prodId; @@ -855,7 +855,7 @@ void LOLIN_HP303B::init(void) if(revId < 0) { m_initFail = 1U; - return; + return 0U; } m_revisionID = revId; @@ -864,7 +864,7 @@ void LOLIN_HP303B::init(void) if(sensor < 0) { m_initFail = 1U; - return; + return 0U; } //...and use this sensor for temperature measurement @@ -872,14 +872,14 @@ void LOLIN_HP303B::init(void) if(writeByteBitfield((uint8_t)sensor, HP303B__REG_INFO_TEMP_SENSOR) < 0) { m_initFail = 1U; - return; + return 0U; } //read coefficients if(readcoeffs() < 0) { m_initFail = 1U; - return; + return 0U; } //set to standby for further configuration @@ -901,6 +901,8 @@ void LOLIN_HP303B::init(void) // Fix IC with a fuse bit problem, which lead to a wrong temperature // Should not affect ICs without this problem correctTemp(); + + return 1U; } diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h index ce65e17f1..651b80380 100644 --- a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h @@ -19,10 +19,10 @@ public: //destructor ~LOLIN_HP303B(void); //begin - void begin(TwoWire &bus, uint8_t slaveAddress); - void begin(uint8_t slaveAddress=HP303B__STD_SLAVE_ADDRESS); - void begin(SPIClass &bus, int32_t chipSelect); - void begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire); + uint8_t begin(TwoWire &bus, uint8_t slaveAddress); + uint8_t begin(uint8_t slaveAddress=HP303B__STD_SLAVE_ADDRESS); + uint8_t begin(SPIClass &bus, int32_t chipSelect); + uint8_t begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire); //end void end(void); @@ -115,7 +115,7 @@ private: uint8_t m_threeWire; //measurement - void init(void); + uint8_t init(void); int16_t readcoeffs(void); int16_t setOpMode(uint8_t background, uint8_t temperature, uint8_t pressure); int16_t setOpMode(uint8_t opMode); diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index ad439e555..b56fa6ded 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -29,45 +29,47 @@ #define XSNS_73 73 #define XI2C_52 52 // See I2CDEVICES.md -#define HP303B_ADDR1 0x77 -#define HP303B_ADDR2 0x76 - #include -// HP303B Opject +// HP303B Object LOLIN_HP303B HP303BSensor = LOLIN_HP303B(); -uint8_t bhp303b_addresses[2] = {HP303B_ADDR1, HP303B_ADDR2}; + +#define HP303B_MAX_SENSORS 2 +#define HP303B_START_ADDRESS 0x76 + +struct { +char types[7] = "HP303B"; +uint8_t count = 0; +int16_t oversampling = 7; +} hp303b_cfg; struct BHP303B { uint8_t address; - uint8_t type = 0; uint8_t valid = 0; - float temperature; - float pressure; - int16_t oversampling = 7; - char name[7] = "HP303B"; -} bhp303b_sensor; + float temperature = NAN; + float pressure = NAN; +} hp303b_sensor[HP303B_MAX_SENSORS]; /*********************************************************************************************/ -bool HP303B_Read() +bool HP303B_Read(uint8_t hp303b_idx) { - if (bhp303b_sensor.valid) { bhp303b_sensor.valid--; } + if (hp303b_sensor[hp303b_idx].valid) { hp303b_sensor[hp303b_idx].valid--; } float t; float p; int16_t ret; - ret = HP303BSensor.measureTempOnce(t, bhp303b_sensor.oversampling); + ret = HP303BSensor.measureTempOnce(t, hp303b_cfg.oversampling); if (ret != 0) return false; - ret = HP303BSensor.measurePressureOnce(p, bhp303b_sensor.oversampling); + ret = HP303BSensor.measurePressureOnce(p, hp303b_cfg.oversampling); if (ret != 0) return false; - bhp303b_sensor.temperature = (float)ConvertTemp(t); - bhp303b_sensor.pressure = (float)ConvertPressure(p) / 100; //conversion to hPa + hp303b_sensor[hp303b_idx].temperature = (float)ConvertTemp(t); + hp303b_sensor[hp303b_idx].pressure = (float)ConvertPressure(p) / 100; //conversion to hPa - bhp303b_sensor.valid = SENSOR_MAX_MISS; + hp303b_sensor[hp303b_idx].valid = SENSOR_MAX_MISS; return true; } @@ -75,18 +77,15 @@ bool HP303B_Read() void HP303B_Detect(void) { - for (uint32_t i = 0; i < sizeof(bhp303b_addresses); i++) + for (uint32_t i = 0; i < HP303B_MAX_SENSORS; i++) { - if (I2cActive(bhp303b_addresses[i])) { return; } + if (I2cActive(HP303B_START_ADDRESS + i)) { return; } - bhp303b_sensor.address = bhp303b_addresses[i]; - - HP303BSensor.begin( bhp303b_sensor.address); - - if (HP303B_Read()) + if (HP303BSensor.begin(HP303B_START_ADDRESS + i)) { - I2cSetActiveFound(bhp303b_sensor.address, bhp303b_sensor.name); - bhp303b_sensor.type = 1; + hp303b_sensor[hp303b_cfg.count].address = HP303B_START_ADDRESS + i; + I2cSetActiveFound(hp303b_sensor[hp303b_cfg.count].address, hp303b_cfg.types); + hp303b_cfg.count++; break; } } @@ -94,39 +93,49 @@ void HP303B_Detect(void) void HP303B_EverySecond(void) { - if (uptime &1) { - if (!HP303B_Read()) { - AddLogMissed(bhp303b_sensor.name, bhp303b_sensor.valid); + for (uint32_t i = 0; i < hp303b_cfg.count; i++) { + if (uptime &1) { + if (!HP303B_Read(i)) { + AddLogMissed(hp303b_cfg.types, hp303b_sensor[i].valid); } } + } } void HP303B_Show(bool json) { - if (bhp303b_sensor.valid) - { - char str_temperature[33]; - dtostrfd(bhp303b_sensor.temperature, Settings.flag2.temperature_resolution, str_temperature); - char str_pressure[33]; - dtostrfd(bhp303b_sensor.pressure, Settings.flag2.pressure_resolution, str_pressure); - - if (json) - { - ResponseAppend_P(PSTR(",\"HP303B\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), str_temperature, str_pressure); - ResponseJsonEnd(); -#ifdef USE_DOMOTICZ - if (0 == tele_period) - { - DomoticzSensor(DZ_TEMP, bhp303b_sensor.temperature); - } -#endif // USE_DOMOTICZ -#ifdef USE_WEBSERVER + for (uint32_t i = 0; i < hp303b_cfg.count; i++) { + char sensor_name[12]; + strlcpy(sensor_name, hp303b_cfg.types, sizeof(sensor_name)); + if (hp303b_cfg.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c0x%02X"), sensor_name, IndexSeparator(), hp303b_sensor[i].address); // MCP9808-18, MCP9808-1A etc. } - else + + if (hp303b_sensor[i].valid) { - WSContentSend_PD(HTTP_SNS_TEMP, "HP303B", str_temperature, TempUnit()); - WSContentSend_PD(HTTP_SNS_PRESSURE, "HP303B", str_pressure, PressureUnit().c_str()); -#endif // USE_WEBSERVER + char str_temperature[33]; + dtostrfd(hp303b_sensor[i].temperature, Settings.flag2.temperature_resolution, str_temperature); + char str_pressure[33]; + dtostrfd(hp303b_sensor[i].pressure, Settings.flag2.pressure_resolution, str_pressure); + + if (json) + { + ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), sensor_name, str_temperature, str_pressure); + ResponseJsonEnd(); + #ifdef USE_DOMOTICZ + if (0 == tele_period) + { + DomoticzSensor(DZ_TEMP, hp303b_sensor[i].temperature); + } + #endif // USE_DOMOTICZ + #ifdef USE_WEBSERVER + } + else + { + WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, str_temperature, TempUnit()); + WSContentSend_PD(HTTP_SNS_PRESSURE, sensor_name, str_pressure, PressureUnit().c_str()); + #endif // USE_WEBSERVER + } } } } @@ -144,7 +153,7 @@ bool Xsns73(uint8_t function) if (FUNC_INIT == function) { HP303B_Detect(); } - else if (bhp303b_sensor.type) + else if (hp303b_cfg.count) { switch (function) { From 4b8c58ce5693bb7bb42d0de4dbaab26a7eb0397e Mon Sep 17 00:00:00 2001 From: Staars Date: Mon, 8 Jun 2020 21:14:43 +0200 Subject: [PATCH 180/581] add unishox compression to xdrv_09_timers.ino --- tasmota/xdrv_09_timers.ino | 155 ++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_09_timers.ino b/tasmota/xdrv_09_timers.ino index 61d5bc737..1ecfb0b67 100644 --- a/tasmota/xdrv_09_timers.ino +++ b/tasmota/xdrv_09_timers.ino @@ -500,6 +500,15 @@ const char S_CONFIGURE_TIMER[] PROGMEM = D_CONFIGURE_TIMER; const char HTTP_BTN_MENU_TIMER[] PROGMEM = "

"; +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_TIMER_SCRIPT1_SIZE = 106; +const char HTTP_TIMER_SCRIPT1_COMPRESSED[] PROGMEM = "\x33\xBF\xA1\x94\x7C\x3D\xE3\xDF\x3A\x83\xA3\xE1\xC4\x8F\x04\x60\x5F\x07\x5B\x9C" + "\x83\x67\x77\x4E\xA3\x51\xDE\x3D\xA6\x77\xF5\x87\xC1\x30\x31\x63\x5F\x51\xD0\x3F" + "\xBB\xA6\x4C\x26\x35\xF5\x1D\xD3\xEF\x06\x56\xE7\x1F\x67\x78\xF1\x87\x4A\x66\xCA" + "\x20\xF3\xA9\xF5\x1F\x34\xF0\x6A\x3A\x58\xC1\x8F\x84\x20\xC5\x68\x42\x1D\xDC\x3B" + "\xC7\x83\xDC"; +#define HTTP_TIMER_SCRIPT1 Decompress(HTTP_TIMER_SCRIPT1_COMPRESSED,HTTP_TIMER_SCRIPT1_SIZE).c_str() +#else const char HTTP_TIMER_SCRIPT1[] PROGMEM = "var pt=[],ct=99;" "function ce(i,q){" // Create select option @@ -507,7 +516,33 @@ const char HTTP_TIMER_SCRIPT1[] PROGMEM = "o.textContent=i;" "q.appendChild(o);" "}"; +#endif //USE_UNISHOX_COMPRESSION + #ifdef USE_SUNRISE +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_TIMER_SCRIPT2_SIZE = 630; +const char HTTP_TIMER_SCRIPT2_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x43\xD4\x77\x4E\xF1\xED\x33\xBF\xA1\xA7\x50\xC3\xA8\xD4\x78" + "\x1A\x7C\x35\x78\xEE\x9F\x7B\xC3\x05\xD1\xEF\x75\x8D\x67\xC3\xD9\xF1\x0F\x61\xEF" + "\x9E\x61\x8A\x61\x9A\x31\x0F\xB3\xBC\x74\x33\xB0\x85\xB3\xC0\xC3\xE0\xCA\x3D\xE0" + "\xE8\xF7\xCF\xD1\xC6\x46\xC3\x9E\x22\x30\x46\x0F\x1A\x60\xEE\x8D\x3E\x1F\x0E\x33" + "\xBC\x7B\x4B\xD8\x77\x4E\x33\xBC\x78\x23\x51\xF0\x86\xDD\x0A\x3A\x18\x0B\x33\xE7" + "\x74\x61\xD8\x73\x99\xDE\x3C\x16\x98\x3B\xA6\xA3\xD0\xE4\x67\x78\xF6\x91\xA8\xF8" + "\x7D\x9C\x67\xD9\xDB\x23\x51\xE0\xF7\x1A\xBC\x77\x4F\xB3\xC8\x56\x02\x1E\x5E\x7C" + "\x35\x1E\x0D\x47\xC1\x87\xD1\xF4\x73\x99\x02\x9E\x10\x37\x41\x1B\x08\x3D\xDA\x60" + "\xEE\x9D\xD1\xA7\xC3\xE1\xC8\x77\x8F\xF1\xFE\x3B\xA4\x34\xF8\x7C\x39\x47\x78\xEF" + "\x1E\xD2\xF6\x1D\xD3\x90\x81\x53\x59\x3F\x0F\x87\x25\x1D\xE3\xDA\x46\xA3\xAC\xF8" + "\x72\x51\xE0\x8D\x5E\x3B\xA7\xD9\xE4\x27\xCF\xB3\xBC\x74\xF3\x09\x87\x4C\x42\xDE" + "\x11\x9B\x0F\x87\x21\xE0\xF7\x13\x0B\xCC\xF6\x82\x9D\xC3\x8C\xF0\x7B\x88\x19\x67" + "\x04\x87\xB8\x11\x38\xE6\xF6\x1D\xD1\xC7\x78\xF6\xE1\xF0\x11\x32\xD3\xC3\x3E\x61" + "\xD0\x31\x5A\x10\x84\xC2\x63\x5F\x51\x07\x82\xFA\x8F\x1A\x60\xEE\x8E\x3E\x1F\x0E" + "\x43\xBC\x40\x8F\xC0\x1D\x19\x04\xCE\x86\x7B\xED\x1D\xA1\x6D\x19\x1F\x0F\xB3\xEC" + "\xF1\xA6\x0E\xEB\x3F\x0E\x4A\x3B\xC7\xB4\x8C\x67\xCE\xEE\x9F\x0E\x4A\x3C\x16\x9E" + "\x87\xC3\x95\x67\x82\xD3\xB6\x76\xCE\xF1\xED\xC3\xA7\xD8\xDC\x33\x64\x18\xAD\x08" + "\x43\xBB\x87\x40\xAF\xD4\x08\x7A\x08\xAD\x08\x43\xBC\x78\x3D\xC7\xB8\x13\x38\x68" + "\x04\xCD\x04\x56\x88\x23\xE0\x41\xD1\xCF\x43\x95\x64\x0A\x3A\x38\x6C\xEE\xE9\xD5" + "\x87\x78\xF0\x7B\x8F\x71\xEE\x3D\xC6"; +#define HTTP_TIMER_SCRIPT2 Decompress(HTTP_TIMER_SCRIPT2_COMPRESSED,HTTP_TIMER_SCRIPT2_SIZE).c_str() +#else const char HTTP_TIMER_SCRIPT2[] PROGMEM = "function gt(){" // Set hours and minutes according to mode "var m,p,q;" @@ -538,7 +573,55 @@ const char HTTP_TIMER_SCRIPT2[] PROGMEM = "if(e<23){for(i=12;i<=23;i++){ce(i,o);}}" // Create hours select options "}" "}"; -#endif +#endif //USE_UNISHOX_COMPRESSION +#endif //USE_SUNRISE + +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SUNRISE +const size_t HTTP_TIMER_SCRIPT3_SIZE = 587; +const char HTTP_TIMER_SCRIPT3_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x5E\xA3\xBA\x77\x8F\x69\x9D\xFD\x69\xD4\x11\xD4\x34\xEA\xE3" + "\xA8\x61\xD5\xE3\xC0\xD3\xE1\xC6\x78\x2F\x1F\x0E\x33\xC1\x71\xF0\xE4\x3D\x0F\x4B" + "\x87\x82\xD3\x07\x75\x8E\x3B\xA7\xDD\x9C\x67\xD9\xDE\x3A\x10\x62\x98\x66\x8C\x43" + "\xBC\x7B\x7C\x7F\x8F\x9C\x78\x3D\xDC\x7C\x39\x0F\x43\xD2\x69\x02\x1D\xFF\x82\x75" + "\xF3\x19\xF3\xBB\xA7\xC3\x8C\xF0\x5A\x7A\x1C\xF1\xE0\xB4\xED\x9D\xB3\xBC\x7B\x78" + "\xF8\x72\x1E\x87\xA1\xDD\x9C\x76\xCB\x4E\xF0\x21\xE2\x83\xE7\xD9\xDB\xD0\x4C\xC5" + "\x4F\x70\xD3\xE1\xAB\xC7\x74\xFB\xDE\x18\x2E\x8F\x7B\xAC\x6B\x3E\x1E\xCF\x88\x7B" + "\x0F\x7C\xF3\x04\x2C\x0C\xFB\x3B\xC7\x43\x3B\x08\x5B\x3C\x78\xFF\x1F\x0E\xE8\x2F" + "\xE0\xA7\xA1\xE8\x72\x91\xDE\x3C\x16\x98\x3B\xA7\xD0\x87\xE1\xC6\x77\x8F\x69\x69" + "\xF0\xD5\xE3\xBA\x7D\x9E\x42\x1C\x87\xD9\xDE\x3A\x17\x98\x4C\x3A\x62\x16\xF0\x8C" + "\xD8\x78\xD3\x07\x77\x4F\xC3\xE1\xC6\x77\x8F\x69\x78\xFF\x1F\x0E\xEE\x9E\x87\xA1" + "\xCA\xB3\xBC\x78\x3D\xC4\x08\x7A\x11\xE4\x30\x13\x30\xD3\xD0\xF4\x39\x5E\x3B\xC7" + "\x83\xDC\x4C\x2F\x33\xDB\xE3\xFC\x7C\x39\x67\xA1\xE9\x5E\x3C\x1E\xE2\x08\xF8\x77" + "\x41\x07\x0D\x15\x80\x97\x86\x9E\xB3\x9C\xCE\xF1\xDB\x23\x57\x8E\xE9\xF6\x79\x0D" + "\xD0\x4B\xB0\x77\x8F\xD1\xC6\x46\xC3\x9E\x22\x30\x46\x0F\x1A\x60\xEE\x8D\x3E\x02" + "\x16\xC2\x11\xE0\xF7\x69\x83\xBA\x77\x46\x9F\x0F\x87\x21\xDE\x3F\xC7\xF8\xEE\x90" + "\xD3\xE1\xF0\xE5\x1D\xE3\xBC\x7B\x4B\x4C\x02\x0E\x78\x27\xC1\x2F\x20\x3F\x0E\x33" + "\xBC\x7B\x4B\x4C\x1D\xD0\x8F\xC3\x8C\xEF\x1E\xD2\x08\xED\x9F\x0E\x7A\x99\xE0\xF7" + "\x1E\xE2\xF1\xFE\x3E\x04\x08\x59\xC1\xEE\xF1\xFE\x04\x3D\xE4\x68\xF8\x27\xEB\xA7" + "\x19\x11\x83\xBC\x7A\x1E\x87\x24\x3C\x10\xCA\x3D\xE0\xE8\xF7\xCF\x9E\x3C\x31\xC7" + "\x74\xFB\xA3\x8C\x81\x0F\x8A\x63\xE0\xCA\x3A\x1A\xF3\x78\xEE\x9D\xE3\xC1\xEE"; +#define HTTP_TIMER_SCRIPT3 Decompress(HTTP_TIMER_SCRIPT3_COMPRESSED,HTTP_TIMER_SCRIPT3_SIZE).c_str() +#else +const size_t HTTP_TIMER_SCRIPT3_SIZE = 424; +const char HTTP_TIMER_SCRIPT3_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x5E\xA3\xBA\x77\x8F\x69\x9D\xFD\x69\xD4\x11\xD4\x34\xEA\xE3" + "\xA8\x61\xD5\xE3\xC0\xD3\xE1\xC6\x78\x2F\x1F\x0E\x33\xC1\x71\xF0\xE4\x3D\x0F\x4B" + "\x87\x82\xD3\x07\x75\x8E\x3B\xA7\xDD\x9C\x67\xD9\xDE\x3A\x10\x62\x98\x66\x8C\x43" + "\xBC\x7B\x7C\x7F\x8F\x9C\x78\x3D\xDC\x7C\x39\x0F\x43\xD2\x69\x02\x1D\xFF\x82\x75" + "\xF3\x19\xF3\xBB\xA7\xC3\x8C\xF0\x5A\x7A\x1C\xF1\xE0\xB4\xED\x9D\xB3\xBC\x7B\x78" + "\xF8\x72\x1E\x87\xA1\xDD\x9C\x76\xCB\x4E\xF0\x21\xE2\x83\xE7\xD9\xDB\xD0\x4C\xC5" + "\x4F\x76\x98\x3B\xA7\xD0\x87\xE1\xC6\x77\x8F\x69\x69\xF0\xD5\xE3\xBA\x7D\x9E\x42" + "\x1C\x87\xD9\xDE\x3A\x17\x98\x4C\x3A\x62\x16\xF0\x8C\xD8\x78\xD3\x07\x77\x4F\xC3" + "\xE1\xC6\x77\x8F\x69\x78\xFF\x1F\x0E\xEE\x9E\x87\xA1\xCA\xB3\xBC\x78\x3D\xC5\xE3" + "\xFC\x7C\x3B\xA6\xAF\x1D\xD3\xEC\xF2\x18\x09\x98\x69\xE8\x7A\x1C\xAF\x1D\xE3\xC1" + "\xEE\x26\x17\x99\xED\xF1\xFE\x3E\x1C\xB3\xD0\xF4\xAF\x1E\x0F\x71\x04\x7C\x3B\xA0" + "\x83\x86\x8A\xC0\x4B\xC3\x4F\x59\xCE\x67\x78\xED\x91\xAB\xC7\x74\xFB\x3C\x86\xE8" + "\x25\xD8\x3B\xC7\xE8\xE3\x23\x61\xCF\x11\x18\x23\x07\x8D\x30\x77\x46\x9F\x01\x0B" + "\x61\x08\x10\x75\xB0\x41\xCA\xC6\x8F\x82\x7E\x1E\x71\x91\x18\x3B\xC7\xA1\xE8\x72" + "\x43\xC1\x0C\xA3\xDE\x0E\x8F\x7C\xF9\xE3\xC3\x1C\x77\x4F\xBA\x38\xCF\xB3\xBC\x74" + "\x23\x3B\x08\x5B\x3E\x0C\xA3\xA1\xAF\x37\x8E\xE9\xDE\x3C\x1E\xE3"; +#define HTTP_TIMER_SCRIPT3 Decompress(HTTP_TIMER_SCRIPT3_COMPRESSED,HTTP_TIMER_SCRIPT3_SIZE).c_str() +#endif //USE_SUNRISE +#else const char HTTP_TIMER_SCRIPT3[] PROGMEM = "function st(){" // Save parameters to hidden area "var i,l,m,n,p,s;" @@ -568,6 +651,58 @@ const char HTTP_TIMER_SCRIPT3[] PROGMEM = "pt[ct]=s;" "eb('t0').value=pt.join();" // Save parameters from array to hidden area "}"; +#endif //USE_UNISHOX_COMPRESSION + +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SUNRISE +const size_t HTTP_TIMER_SCRIPT4_SIZE = 548; +const char HTTP_TIMER_SCRIPT4_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x59\x47\x76\x8E\xA6\x77\x8F\x69\x9D\xFD\x69\xD5\xC7\x56\x1D" + "\x43\x0E\xA3\x51\xD5\xE3\xC6\x98\x3B\xA1\xD1\xE8\x71\x23\xBC\x7B\x4B\xD4\x77\x4E" + "\xF1\xE0\xF7\x07\x47\xCA\x3C\x61\xF0\x4C\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35" + "\xF5\x78\x87\x19\x10\x61\x5F\xBC\x5D\x63\x59\xDD\x3E\xE8\x23\xEC\xEF\x1E\x0C\x67" + "\xCE\xEE\x9F\x0E\x33\xC1\x69\xE9\x87\x40\x9F\x0F\x50\xA3\xC6\x9D\xB3\xB6\x77\x8F" + "\x6E\x1E\xF6\x9E\xF9\xD3\xD4\x64\x13\x3A\x07\xEF\x15\x33\x65\x1F\x0F\x60\xEB\x0C" + "\xD0\x7B\xF8\x2F\x84\x3C\xCF\x23\xE8\xE3\xE2\x36\x1E\x03\xC0\xB3\xE0\x85\x20\xC6" + "\x75\x1D\x63\xEF\x47\x85\x51\xE7\xD9\xF1\xB6\x11\xE0\xF6\x1E\xE6\x0C\x53\x1F\x1D" + "\x81\x08\x78\x3D\x87\x8F\x1F\x06\x51\xEF\x07\x47\xBE\x78\x18\x7C\x3B\xBE\x3F\x0F" + "\xC3\x94\x8E\xF1\xFA\xB3\xC1\x31\xC7\x74\xFB\x1C\x7D\x9D\xB1\x87\x78\xE8\x18\xA6" + "\x19\xA3\x10\xF8\x72\x1E\x08\x7A\x8E\xE9\xDE\x3C\x1A\x8F\x87\x77\xC7\xE1\xF8\x72" + "\x43\xBC\x7E\x99\x1B\x08\xC1\xE3\x4C\x1D\xD3\x51\xE8\x72\x33\xBC\x7B\x48\xD4\x7C" + "\x3E\xCE\x33\xEC\xED\x91\xA8\xF0\x7B\x8D\x5E\x3B\xA7\xD9\xE4\x34\x7C\xFB\x3B\xC7" + "\x43\x3B\x08\x5B\x3E\x1A\x81\x1B\x85\xB3\x9E\x20\x41\xE1\x50\x10\x74\x43\xBA\x72" + "\x71\xDB\x2D\x3B\xC7\x78\xFD\x1C\x87\x82\x63\x8E\xE9\xF6\x3E\x7D\x9D\xBD\x04\x5D" + "\x20\x61\xE0\xF7\x69\x83\xBA\x7D\x08\x7E\x1C\x64\x08\x78\x51\xCA\xB2\x04\x1D\x34" + "\xD5\xE3\xBA\x7D\x9E\x42\x1C\x84\x08\x99\xD8\xC3\xB6\x72\x10\x21\xF0\x28\x73\xC7" + "\x78\xFD\x59\x02\x0D\xC1\x87\x21\xF6\x77\x8E\x85\xE6\x13\x0E\x98\x85\xBC\x23\x36" + "\x1F\x06\x1E\x0F\x70\x20\xE0\x67\x26\x90\x21\xE9\xFF\x38\xCF\xB2\x04\x7D\x38\x10" + "\x6D\x9C\xB8\x40\x87\x6E\xC1\x26\xD9\xEE"; +#define HTTP_TIMER_SCRIPT4 Decompress(HTTP_TIMER_SCRIPT4_COMPRESSED,HTTP_TIMER_SCRIPT4_SIZE).c_str() +#else +const size_t HTTP_TIMER_SCRIPT4_SIZE = 620; +const char HTTP_TIMER_SCRIPT4_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x59\x47\x76\x8E\xA6\x77\x8F\x69\x9D\xFD\x69\xD5\xC7\x56\x1D" + "\x43\x0E\xA3\x51\xD5\xE3\xC6\x98\x3B\xA1\xD1\xE8\x71\x23\xBC\x7B\x4B\xD4\x77\x4E" + "\xF1\xE0\xF7\x07\x47\xCA\x3C\x61\xF0\x4C\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35" + "\xF5\x78\x87\x19\x10\x61\x5F\xBC\x5D\x63\x59\xDD\x3E\xE8\x23\xEC\xEF\x1E\x0C\x67" + "\xCE\xEE\x9F\x0E\x33\xC1\x69\xE9\x87\x40\x9F\x0F\x50\xA3\xC6\x9D\xB3\xB6\x77\x8F" + "\x6E\x1E\xF6\x9E\xF9\xD3\xD4\x64\x13\x3A\x07\xEF\x15\x33\x65\x1F\x0F\x60\xEB\x0C" + "\xD0\x7B\xF8\x2F\x84\x3C\xCF\x23\xE8\xE3\xE2\x36\x1E\x03\xC0\xB3\xE0\x85\x20\xC6" + "\x75\x1D\x63\xEF\x47\x85\x51\xE7\xD9\xF1\xB6\x11\xE0\xF6\x1E\xE6\x0C\x53\x1F\x1D" + "\x81\x08\x78\x3D\x87\x8F\x1F\x06\x51\xEF\x07\x47\xBE\x78\x18\x7C\xF1\xFA\x38\xC8" + "\xD8\x73\xC4\x46\x08\xC1\xE0\xD4\x7C\x21\xB7\x42\x8E\x86\x02\xCC\xF9\xDD\x18\x76" + "\x1C\xE6\x77\x8F\x05\xA6\x0E\xE9\xA8\xF4\x39\x19\xDE\x3D\xA4\x6A\x3E\x1F\x67\x19" + "\xF6\x76\xC8\xD4\x78\x3D\xC6\xAF\x1D\xD3\xEC\xF2\x15\x87\xD9\xDE\x3A\x19\xD8\x42" + "\xD9\xF0\xD4\x78\x35\x1F\x06\x1F\x47\xD1\xCE\x64\x0A\x78\x40\xDD\x04\x8C\x20\xEE" + "\xF8\xFC\x3F\x0E\x48\x77\x8F\xD3\x23\x61\x18\x05\x4C\x38\x7C\x11\xB0\xE0\x45\xE2" + "\x8C\xE7\x88\x10\x78\x9C\x18\x7C\x3B\xBE\x3F\x0F\xC3\xBA\x72\x71\xDB\x2D\x3B\xC7" + "\x78\xFD\x1C\x87\x82\x63\x8E\xE9\xF6\x3E\x7D\x9D\xBD\x3B\xC7\x40\xC5\x30\xCD\x18" + "\x87\xC1\x87\x83\xDD\xA6\x0E\xE9\xF4\x21\xF8\x71\x90\x21\xE1\x47\x2A\x2B\xC8\x10" + "\x74\xD3\x57\x8E\xE9\xF6\x79\x08\x72\x10\x22\x67\x63\x0E\xD9\xC8\x78\x20\x42\xBC" + "\x73\xC7\x78\xFD\x59\x02\x0D\xC1\x87\x21\xF6\x77\x8E\x85\xE6\x13\x0E\x98\x85\xBC" + "\x23\x36\x1F\x06\x1E\x0F\x70\x20\xE0\x67\x26\x90\x21\xE9\xFF\x38\xCF\xB2\x04\x7D" + "\x38\x10\x6D\x9C\xB8\x40\x87\x6E\xC1\x26\xD9\xEE"; +#define HTTP_TIMER_SCRIPT4 Decompress(HTTP_TIMER_SCRIPT4_COMPRESSED,HTTP_TIMER_SCRIPT4_SIZE).c_str() +#endif //USE_SUNRISE +#else const char HTTP_TIMER_SCRIPT4[] PROGMEM = "function ot(t,e){" // Select tab and update elements "var i,n,o,p,q,s;" @@ -594,6 +729,8 @@ const char HTTP_TIMER_SCRIPT4[] PROGMEM = "p=(s>>15)&1;eb('r0').checked=p;" // Set repeat "p=(s>>31)&1;eb('a0').checked=p;" // Set arm "}"; +#endif //USE_UNISHOX_COMPRESSION + const char HTTP_TIMER_SCRIPT5[] PROGMEM = "function it(){" // Initialize elements and select first tab "var b,i,o,s;" @@ -664,6 +801,17 @@ const char HTTP_FORM_TIMER3[] PROGMEM = const char HTTP_FORM_TIMER3[] PROGMEM = "" D_TIMER_TIME " "; #endif // USE_SUNRISE + +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_FORM_TIMER4_SIZE = 249; +const char HTTP_FORM_TIMER4_COMPRESSED[] PROGMEM = "\x3D\x3C\x32\xF8\xFC\x3D\x3C\xC2\x61\xD2\xF5\x19\x04\xCF\x87\xD8\xFE\x89\x42\x8F" + "\x33\x9C\xC8\x61\xB0\xF0\x7D\xAD\x10\xF8\x7D\x8A\xC3\xEC\xFC\x3D\x0E\xC0\x41\xC0" + "\x4F\xC3\xD0\xEC\xF0\xCB\xE3\xF0\xFD\x70\xEF\x0C\x3C\x1F\x5E\x04\x18\x80\xC0\x72" + "\x41\xBA\x09\xD9\x23\x1B\xE1\x87\x83\xD0\x71\xF8\x76\xCE\xC3\xAC\xF4\x3B\x07\x02" + "\x16\x68\x0C\x0B\x2C\x1F\x04\xDC\xB0\xF4\x3B\x04\xD3\x33\xF0\xF4\x1D\xF3\xF0\xF4" + "\x13\x4C\xD6\x88\x7C\x3E\xC4\xF1\xF6\xBA\xC6\xB3\xE1\xF6\x27\x8F\xB0\x42\xBA"; +#define HTTP_FORM_TIMER4 Decompress(HTTP_FORM_TIMER4_COMPRESSED,HTTP_FORM_TIMER4_SIZE).c_str() +#else const char HTTP_FORM_TIMER4[] PROGMEM = "" " " D_HOUR_MINUTE_SEPARATOR " " @@ -672,6 +820,7 @@ const char HTTP_FORM_TIMER4[] PROGMEM = "" "

" "
"; +#endif //USE_UNISHOX_COMPRESSION void HandleTimerConfiguration(void) { @@ -705,7 +854,11 @@ void HandleTimerConfiguration(void) #else WSContentSend_P(HTTP_FORM_TIMER3); #endif // USE_SUNRISE +#ifdef USE_UNISHOX_COMPRESSION + WSContentSend_P(HTTP_FORM_TIMER4,D_HOUR_MINUTE_SEPARATOR); +#else WSContentSend_P(HTTP_FORM_TIMER4); +#endif //USE_UNISHOX_COMPRESSION WSContentSend_P(HTTP_FORM_END); WSContentSpaceButton(BUTTON_CONFIGURATION); WSContentStop(); From 9d2d22558c9150a23eb86a88ba4fad0a4a9a22a5 Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Tue, 9 Jun 2020 09:14:44 +0200 Subject: [PATCH 181/581] Resolved review comments --- tasmota/xsns_73_hp303b.ino | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index b56fa6ded..01145e0d1 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -79,14 +79,13 @@ void HP303B_Detect(void) { for (uint32_t i = 0; i < HP303B_MAX_SENSORS; i++) { - if (I2cActive(HP303B_START_ADDRESS + i)) { return; } + if (!I2cSetDevice(HP303B_START_ADDRESS + i )) { continue; } if (HP303BSensor.begin(HP303B_START_ADDRESS + i)) { hp303b_sensor[hp303b_cfg.count].address = HP303B_START_ADDRESS + i; I2cSetActiveFound(hp303b_sensor[hp303b_cfg.count].address, hp303b_cfg.types); hp303b_cfg.count++; - break; } } } @@ -108,7 +107,7 @@ void HP303B_Show(bool json) char sensor_name[12]; strlcpy(sensor_name, hp303b_cfg.types, sizeof(sensor_name)); if (hp303b_cfg.count > 1) { - snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c0x%02X"), sensor_name, IndexSeparator(), hp303b_sensor[i].address); // MCP9808-18, MCP9808-1A etc. + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c0x%02X"), sensor_name, IndexSeparator(), hp303b_sensor[i].address); // HP303B-0x76, HP303B-0x77 } if (hp303b_sensor[i].valid) @@ -123,8 +122,8 @@ void HP303B_Show(bool json) ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), sensor_name, str_temperature, str_pressure); ResponseJsonEnd(); #ifdef USE_DOMOTICZ - if (0 == tele_period) - { + // Domoticz and knx only support one temp sensor + if ((0 == tele_period) && (0 == i)) { DomoticzSensor(DZ_TEMP, hp303b_sensor[i].temperature); } #endif // USE_DOMOTICZ From 56c491050e5510f82640e8a2daefd80db4dd41f2 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 9 Jun 2020 11:25:43 +0200 Subject: [PATCH 182/581] Fix AP switch Fix AP switch (#8635) --- tasmota/support_command.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index f143a9316..abda76482 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1431,6 +1431,7 @@ void CmndAp(void) case 2: // AP2 Settings.sta_active = XdrvMailbox.payload -1; } + Settings.wifi_channel = 0; // Disable stored AP restart_flag = 2; } Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active)); From 20bdc0e22136931912053ddc7b0ca077818c963e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 9 Jun 2020 13:25:31 +0200 Subject: [PATCH 183/581] Delete unishox.pyc --- tools/unishox/unishox.pyc | Bin 14134 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/unishox/unishox.pyc diff --git a/tools/unishox/unishox.pyc b/tools/unishox/unishox.pyc deleted file mode 100644 index d2c127f091cd9e566505df0886064be9f61e9950..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14134 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 Co^0d* From 7fbed52c459f4ce69a2de20153d8f9adf7fffd7a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 9 Jun 2020 13:28:16 +0200 Subject: [PATCH 184/581] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5baf6b919..75ff90814 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ ## OS specific ######## .DS_Store .fuse_hidden* +*.pyc ## Project files ###### .pioenvs From 37561276080efe2836c2e44df067da0a5df2e51e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 9 Jun 2020 13:50:59 +0200 Subject: [PATCH 185/581] Revert "Merge pull request #8645 from Staars/timers" This reverts commit c9126cec196739bb9dcde348f3969ff237f26cbc, reversing changes made to 947ccc92756d6c60b5912c27bbdbf16816ad9536. --- tasmota/xdrv_09_timers.ino | 155 +------------------------------------ 1 file changed, 1 insertion(+), 154 deletions(-) diff --git a/tasmota/xdrv_09_timers.ino b/tasmota/xdrv_09_timers.ino index 1ecfb0b67..61d5bc737 100644 --- a/tasmota/xdrv_09_timers.ino +++ b/tasmota/xdrv_09_timers.ino @@ -500,15 +500,6 @@ const char S_CONFIGURE_TIMER[] PROGMEM = D_CONFIGURE_TIMER; const char HTTP_BTN_MENU_TIMER[] PROGMEM = "

"; -#ifdef USE_UNISHOX_COMPRESSION -const size_t HTTP_TIMER_SCRIPT1_SIZE = 106; -const char HTTP_TIMER_SCRIPT1_COMPRESSED[] PROGMEM = "\x33\xBF\xA1\x94\x7C\x3D\xE3\xDF\x3A\x83\xA3\xE1\xC4\x8F\x04\x60\x5F\x07\x5B\x9C" - "\x83\x67\x77\x4E\xA3\x51\xDE\x3D\xA6\x77\xF5\x87\xC1\x30\x31\x63\x5F\x51\xD0\x3F" - "\xBB\xA6\x4C\x26\x35\xF5\x1D\xD3\xEF\x06\x56\xE7\x1F\x67\x78\xF1\x87\x4A\x66\xCA" - "\x20\xF3\xA9\xF5\x1F\x34\xF0\x6A\x3A\x58\xC1\x8F\x84\x20\xC5\x68\x42\x1D\xDC\x3B" - "\xC7\x83\xDC"; -#define HTTP_TIMER_SCRIPT1 Decompress(HTTP_TIMER_SCRIPT1_COMPRESSED,HTTP_TIMER_SCRIPT1_SIZE).c_str() -#else const char HTTP_TIMER_SCRIPT1[] PROGMEM = "var pt=[],ct=99;" "function ce(i,q){" // Create select option @@ -516,33 +507,7 @@ const char HTTP_TIMER_SCRIPT1[] PROGMEM = "o.textContent=i;" "q.appendChild(o);" "}"; -#endif //USE_UNISHOX_COMPRESSION - #ifdef USE_SUNRISE -#ifdef USE_UNISHOX_COMPRESSION -const size_t HTTP_TIMER_SCRIPT2_SIZE = 630; -const char HTTP_TIMER_SCRIPT2_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x43\xD4\x77\x4E\xF1\xED\x33\xBF\xA1\xA7\x50\xC3\xA8\xD4\x78" - "\x1A\x7C\x35\x78\xEE\x9F\x7B\xC3\x05\xD1\xEF\x75\x8D\x67\xC3\xD9\xF1\x0F\x61\xEF" - "\x9E\x61\x8A\x61\x9A\x31\x0F\xB3\xBC\x74\x33\xB0\x85\xB3\xC0\xC3\xE0\xCA\x3D\xE0" - "\xE8\xF7\xCF\xD1\xC6\x46\xC3\x9E\x22\x30\x46\x0F\x1A\x60\xEE\x8D\x3E\x1F\x0E\x33" - "\xBC\x7B\x4B\xD8\x77\x4E\x33\xBC\x78\x23\x51\xF0\x86\xDD\x0A\x3A\x18\x0B\x33\xE7" - "\x74\x61\xD8\x73\x99\xDE\x3C\x16\x98\x3B\xA6\xA3\xD0\xE4\x67\x78\xF6\x91\xA8\xF8" - "\x7D\x9C\x67\xD9\xDB\x23\x51\xE0\xF7\x1A\xBC\x77\x4F\xB3\xC8\x56\x02\x1E\x5E\x7C" - "\x35\x1E\x0D\x47\xC1\x87\xD1\xF4\x73\x99\x02\x9E\x10\x37\x41\x1B\x08\x3D\xDA\x60" - "\xEE\x9D\xD1\xA7\xC3\xE1\xC8\x77\x8F\xF1\xFE\x3B\xA4\x34\xF8\x7C\x39\x47\x78\xEF" - "\x1E\xD2\xF6\x1D\xD3\x90\x81\x53\x59\x3F\x0F\x87\x25\x1D\xE3\xDA\x46\xA3\xAC\xF8" - "\x72\x51\xE0\x8D\x5E\x3B\xA7\xD9\xE4\x27\xCF\xB3\xBC\x74\xF3\x09\x87\x4C\x42\xDE" - "\x11\x9B\x0F\x87\x21\xE0\xF7\x13\x0B\xCC\xF6\x82\x9D\xC3\x8C\xF0\x7B\x88\x19\x67" - "\x04\x87\xB8\x11\x38\xE6\xF6\x1D\xD1\xC7\x78\xF6\xE1\xF0\x11\x32\xD3\xC3\x3E\x61" - "\xD0\x31\x5A\x10\x84\xC2\x63\x5F\x51\x07\x82\xFA\x8F\x1A\x60\xEE\x8E\x3E\x1F\x0E" - "\x43\xBC\x40\x8F\xC0\x1D\x19\x04\xCE\x86\x7B\xED\x1D\xA1\x6D\x19\x1F\x0F\xB3\xEC" - "\xF1\xA6\x0E\xEB\x3F\x0E\x4A\x3B\xC7\xB4\x8C\x67\xCE\xEE\x9F\x0E\x4A\x3C\x16\x9E" - "\x87\xC3\x95\x67\x82\xD3\xB6\x76\xCE\xF1\xED\xC3\xA7\xD8\xDC\x33\x64\x18\xAD\x08" - "\x43\xBB\x87\x40\xAF\xD4\x08\x7A\x08\xAD\x08\x43\xBC\x78\x3D\xC7\xB8\x13\x38\x68" - "\x04\xCD\x04\x56\x88\x23\xE0\x41\xD1\xCF\x43\x95\x64\x0A\x3A\x38\x6C\xEE\xE9\xD5" - "\x87\x78\xF0\x7B\x8F\x71\xEE\x3D\xC6"; -#define HTTP_TIMER_SCRIPT2 Decompress(HTTP_TIMER_SCRIPT2_COMPRESSED,HTTP_TIMER_SCRIPT2_SIZE).c_str() -#else const char HTTP_TIMER_SCRIPT2[] PROGMEM = "function gt(){" // Set hours and minutes according to mode "var m,p,q;" @@ -573,55 +538,7 @@ const char HTTP_TIMER_SCRIPT2[] PROGMEM = "if(e<23){for(i=12;i<=23;i++){ce(i,o);}}" // Create hours select options "}" "}"; -#endif //USE_UNISHOX_COMPRESSION -#endif //USE_SUNRISE - -#ifdef USE_UNISHOX_COMPRESSION -#ifdef USE_SUNRISE -const size_t HTTP_TIMER_SCRIPT3_SIZE = 587; -const char HTTP_TIMER_SCRIPT3_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x5E\xA3\xBA\x77\x8F\x69\x9D\xFD\x69\xD4\x11\xD4\x34\xEA\xE3" - "\xA8\x61\xD5\xE3\xC0\xD3\xE1\xC6\x78\x2F\x1F\x0E\x33\xC1\x71\xF0\xE4\x3D\x0F\x4B" - "\x87\x82\xD3\x07\x75\x8E\x3B\xA7\xDD\x9C\x67\xD9\xDE\x3A\x10\x62\x98\x66\x8C\x43" - "\xBC\x7B\x7C\x7F\x8F\x9C\x78\x3D\xDC\x7C\x39\x0F\x43\xD2\x69\x02\x1D\xFF\x82\x75" - "\xF3\x19\xF3\xBB\xA7\xC3\x8C\xF0\x5A\x7A\x1C\xF1\xE0\xB4\xED\x9D\xB3\xBC\x7B\x78" - "\xF8\x72\x1E\x87\xA1\xDD\x9C\x76\xCB\x4E\xF0\x21\xE2\x83\xE7\xD9\xDB\xD0\x4C\xC5" - "\x4F\x70\xD3\xE1\xAB\xC7\x74\xFB\xDE\x18\x2E\x8F\x7B\xAC\x6B\x3E\x1E\xCF\x88\x7B" - "\x0F\x7C\xF3\x04\x2C\x0C\xFB\x3B\xC7\x43\x3B\x08\x5B\x3C\x78\xFF\x1F\x0E\xE8\x2F" - "\xE0\xA7\xA1\xE8\x72\x91\xDE\x3C\x16\x98\x3B\xA7\xD0\x87\xE1\xC6\x77\x8F\x69\x69" - "\xF0\xD5\xE3\xBA\x7D\x9E\x42\x1C\x87\xD9\xDE\x3A\x17\x98\x4C\x3A\x62\x16\xF0\x8C" - "\xD8\x78\xD3\x07\x77\x4F\xC3\xE1\xC6\x77\x8F\x69\x78\xFF\x1F\x0E\xEE\x9E\x87\xA1" - "\xCA\xB3\xBC\x78\x3D\xC4\x08\x7A\x11\xE4\x30\x13\x30\xD3\xD0\xF4\x39\x5E\x3B\xC7" - "\x83\xDC\x4C\x2F\x33\xDB\xE3\xFC\x7C\x39\x67\xA1\xE9\x5E\x3C\x1E\xE2\x08\xF8\x77" - "\x41\x07\x0D\x15\x80\x97\x86\x9E\xB3\x9C\xCE\xF1\xDB\x23\x57\x8E\xE9\xF6\x79\x0D" - "\xD0\x4B\xB0\x77\x8F\xD1\xC6\x46\xC3\x9E\x22\x30\x46\x0F\x1A\x60\xEE\x8D\x3E\x02" - "\x16\xC2\x11\xE0\xF7\x69\x83\xBA\x77\x46\x9F\x0F\x87\x21\xDE\x3F\xC7\xF8\xEE\x90" - "\xD3\xE1\xF0\xE5\x1D\xE3\xBC\x7B\x4B\x4C\x02\x0E\x78\x27\xC1\x2F\x20\x3F\x0E\x33" - "\xBC\x7B\x4B\x4C\x1D\xD0\x8F\xC3\x8C\xEF\x1E\xD2\x08\xED\x9F\x0E\x7A\x99\xE0\xF7" - "\x1E\xE2\xF1\xFE\x3E\x04\x08\x59\xC1\xEE\xF1\xFE\x04\x3D\xE4\x68\xF8\x27\xEB\xA7" - "\x19\x11\x83\xBC\x7A\x1E\x87\x24\x3C\x10\xCA\x3D\xE0\xE8\xF7\xCF\x9E\x3C\x31\xC7" - "\x74\xFB\xA3\x8C\x81\x0F\x8A\x63\xE0\xCA\x3A\x1A\xF3\x78\xEE\x9D\xE3\xC1\xEE"; -#define HTTP_TIMER_SCRIPT3 Decompress(HTTP_TIMER_SCRIPT3_COMPRESSED,HTTP_TIMER_SCRIPT3_SIZE).c_str() -#else -const size_t HTTP_TIMER_SCRIPT3_SIZE = 424; -const char HTTP_TIMER_SCRIPT3_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x5E\xA3\xBA\x77\x8F\x69\x9D\xFD\x69\xD4\x11\xD4\x34\xEA\xE3" - "\xA8\x61\xD5\xE3\xC0\xD3\xE1\xC6\x78\x2F\x1F\x0E\x33\xC1\x71\xF0\xE4\x3D\x0F\x4B" - "\x87\x82\xD3\x07\x75\x8E\x3B\xA7\xDD\x9C\x67\xD9\xDE\x3A\x10\x62\x98\x66\x8C\x43" - "\xBC\x7B\x7C\x7F\x8F\x9C\x78\x3D\xDC\x7C\x39\x0F\x43\xD2\x69\x02\x1D\xFF\x82\x75" - "\xF3\x19\xF3\xBB\xA7\xC3\x8C\xF0\x5A\x7A\x1C\xF1\xE0\xB4\xED\x9D\xB3\xBC\x7B\x78" - "\xF8\x72\x1E\x87\xA1\xDD\x9C\x76\xCB\x4E\xF0\x21\xE2\x83\xE7\xD9\xDB\xD0\x4C\xC5" - "\x4F\x76\x98\x3B\xA7\xD0\x87\xE1\xC6\x77\x8F\x69\x69\xF0\xD5\xE3\xBA\x7D\x9E\x42" - "\x1C\x87\xD9\xDE\x3A\x17\x98\x4C\x3A\x62\x16\xF0\x8C\xD8\x78\xD3\x07\x77\x4F\xC3" - "\xE1\xC6\x77\x8F\x69\x78\xFF\x1F\x0E\xEE\x9E\x87\xA1\xCA\xB3\xBC\x78\x3D\xC5\xE3" - "\xFC\x7C\x3B\xA6\xAF\x1D\xD3\xEC\xF2\x18\x09\x98\x69\xE8\x7A\x1C\xAF\x1D\xE3\xC1" - "\xEE\x26\x17\x99\xED\xF1\xFE\x3E\x1C\xB3\xD0\xF4\xAF\x1E\x0F\x71\x04\x7C\x3B\xA0" - "\x83\x86\x8A\xC0\x4B\xC3\x4F\x59\xCE\x67\x78\xED\x91\xAB\xC7\x74\xFB\x3C\x86\xE8" - "\x25\xD8\x3B\xC7\xE8\xE3\x23\x61\xCF\x11\x18\x23\x07\x8D\x30\x77\x46\x9F\x01\x0B" - "\x61\x08\x10\x75\xB0\x41\xCA\xC6\x8F\x82\x7E\x1E\x71\x91\x18\x3B\xC7\xA1\xE8\x72" - "\x43\xC1\x0C\xA3\xDE\x0E\x8F\x7C\xF9\xE3\xC3\x1C\x77\x4F\xBA\x38\xCF\xB3\xBC\x74" - "\x23\x3B\x08\x5B\x3E\x0C\xA3\xA1\xAF\x37\x8E\xE9\xDE\x3C\x1E\xE3"; -#define HTTP_TIMER_SCRIPT3 Decompress(HTTP_TIMER_SCRIPT3_COMPRESSED,HTTP_TIMER_SCRIPT3_SIZE).c_str() -#endif //USE_SUNRISE -#else +#endif const char HTTP_TIMER_SCRIPT3[] PROGMEM = "function st(){" // Save parameters to hidden area "var i,l,m,n,p,s;" @@ -651,58 +568,6 @@ const char HTTP_TIMER_SCRIPT3[] PROGMEM = "pt[ct]=s;" "eb('t0').value=pt.join();" // Save parameters from array to hidden area "}"; -#endif //USE_UNISHOX_COMPRESSION - -#ifdef USE_UNISHOX_COMPRESSION -#ifdef USE_SUNRISE -const size_t HTTP_TIMER_SCRIPT4_SIZE = 548; -const char HTTP_TIMER_SCRIPT4_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x59\x47\x76\x8E\xA6\x77\x8F\x69\x9D\xFD\x69\xD5\xC7\x56\x1D" - "\x43\x0E\xA3\x51\xD5\xE3\xC6\x98\x3B\xA1\xD1\xE8\x71\x23\xBC\x7B\x4B\xD4\x77\x4E" - "\xF1\xE0\xF7\x07\x47\xCA\x3C\x61\xF0\x4C\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35" - "\xF5\x78\x87\x19\x10\x61\x5F\xBC\x5D\x63\x59\xDD\x3E\xE8\x23\xEC\xEF\x1E\x0C\x67" - "\xCE\xEE\x9F\x0E\x33\xC1\x69\xE9\x87\x40\x9F\x0F\x50\xA3\xC6\x9D\xB3\xB6\x77\x8F" - "\x6E\x1E\xF6\x9E\xF9\xD3\xD4\x64\x13\x3A\x07\xEF\x15\x33\x65\x1F\x0F\x60\xEB\x0C" - "\xD0\x7B\xF8\x2F\x84\x3C\xCF\x23\xE8\xE3\xE2\x36\x1E\x03\xC0\xB3\xE0\x85\x20\xC6" - "\x75\x1D\x63\xEF\x47\x85\x51\xE7\xD9\xF1\xB6\x11\xE0\xF6\x1E\xE6\x0C\x53\x1F\x1D" - "\x81\x08\x78\x3D\x87\x8F\x1F\x06\x51\xEF\x07\x47\xBE\x78\x18\x7C\x3B\xBE\x3F\x0F" - "\xC3\x94\x8E\xF1\xFA\xB3\xC1\x31\xC7\x74\xFB\x1C\x7D\x9D\xB1\x87\x78\xE8\x18\xA6" - "\x19\xA3\x10\xF8\x72\x1E\x08\x7A\x8E\xE9\xDE\x3C\x1A\x8F\x87\x77\xC7\xE1\xF8\x72" - "\x43\xBC\x7E\x99\x1B\x08\xC1\xE3\x4C\x1D\xD3\x51\xE8\x72\x33\xBC\x7B\x48\xD4\x7C" - "\x3E\xCE\x33\xEC\xED\x91\xA8\xF0\x7B\x8D\x5E\x3B\xA7\xD9\xE4\x34\x7C\xFB\x3B\xC7" - "\x43\x3B\x08\x5B\x3E\x1A\x81\x1B\x85\xB3\x9E\x20\x41\xE1\x50\x10\x74\x43\xBA\x72" - "\x71\xDB\x2D\x3B\xC7\x78\xFD\x1C\x87\x82\x63\x8E\xE9\xF6\x3E\x7D\x9D\xBD\x04\x5D" - "\x20\x61\xE0\xF7\x69\x83\xBA\x7D\x08\x7E\x1C\x64\x08\x78\x51\xCA\xB2\x04\x1D\x34" - "\xD5\xE3\xBA\x7D\x9E\x42\x1C\x84\x08\x99\xD8\xC3\xB6\x72\x10\x21\xF0\x28\x73\xC7" - "\x78\xFD\x59\x02\x0D\xC1\x87\x21\xF6\x77\x8E\x85\xE6\x13\x0E\x98\x85\xBC\x23\x36" - "\x1F\x06\x1E\x0F\x70\x20\xE0\x67\x26\x90\x21\xE9\xFF\x38\xCF\xB2\x04\x7D\x38\x10" - "\x6D\x9C\xB8\x40\x87\x6E\xC1\x26\xD9\xEE"; -#define HTTP_TIMER_SCRIPT4 Decompress(HTTP_TIMER_SCRIPT4_COMPRESSED,HTTP_TIMER_SCRIPT4_SIZE).c_str() -#else -const size_t HTTP_TIMER_SCRIPT4_SIZE = 620; -const char HTTP_TIMER_SCRIPT4_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x59\x47\x76\x8E\xA6\x77\x8F\x69\x9D\xFD\x69\xD5\xC7\x56\x1D" - "\x43\x0E\xA3\x51\xD5\xE3\xC6\x98\x3B\xA1\xD1\xE8\x71\x23\xBC\x7B\x4B\xD4\x77\x4E" - "\xF1\xE0\xF7\x07\x47\xCA\x3C\x61\xF0\x4C\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35" - "\xF5\x78\x87\x19\x10\x61\x5F\xBC\x5D\x63\x59\xDD\x3E\xE8\x23\xEC\xEF\x1E\x0C\x67" - "\xCE\xEE\x9F\x0E\x33\xC1\x69\xE9\x87\x40\x9F\x0F\x50\xA3\xC6\x9D\xB3\xB6\x77\x8F" - "\x6E\x1E\xF6\x9E\xF9\xD3\xD4\x64\x13\x3A\x07\xEF\x15\x33\x65\x1F\x0F\x60\xEB\x0C" - "\xD0\x7B\xF8\x2F\x84\x3C\xCF\x23\xE8\xE3\xE2\x36\x1E\x03\xC0\xB3\xE0\x85\x20\xC6" - "\x75\x1D\x63\xEF\x47\x85\x51\xE7\xD9\xF1\xB6\x11\xE0\xF6\x1E\xE6\x0C\x53\x1F\x1D" - "\x81\x08\x78\x3D\x87\x8F\x1F\x06\x51\xEF\x07\x47\xBE\x78\x18\x7C\xF1\xFA\x38\xC8" - "\xD8\x73\xC4\x46\x08\xC1\xE0\xD4\x7C\x21\xB7\x42\x8E\x86\x02\xCC\xF9\xDD\x18\x76" - "\x1C\xE6\x77\x8F\x05\xA6\x0E\xE9\xA8\xF4\x39\x19\xDE\x3D\xA4\x6A\x3E\x1F\x67\x19" - "\xF6\x76\xC8\xD4\x78\x3D\xC6\xAF\x1D\xD3\xEC\xF2\x15\x87\xD9\xDE\x3A\x19\xD8\x42" - "\xD9\xF0\xD4\x78\x35\x1F\x06\x1F\x47\xD1\xCE\x64\x0A\x78\x40\xDD\x04\x8C\x20\xEE" - "\xF8\xFC\x3F\x0E\x48\x77\x8F\xD3\x23\x61\x18\x05\x4C\x38\x7C\x11\xB0\xE0\x45\xE2" - "\x8C\xE7\x88\x10\x78\x9C\x18\x7C\x3B\xBE\x3F\x0F\xC3\xBA\x72\x71\xDB\x2D\x3B\xC7" - "\x78\xFD\x1C\x87\x82\x63\x8E\xE9\xF6\x3E\x7D\x9D\xBD\x3B\xC7\x40\xC5\x30\xCD\x18" - "\x87\xC1\x87\x83\xDD\xA6\x0E\xE9\xF4\x21\xF8\x71\x90\x21\xE1\x47\x2A\x2B\xC8\x10" - "\x74\xD3\x57\x8E\xE9\xF6\x79\x08\x72\x10\x22\x67\x63\x0E\xD9\xC8\x78\x20\x42\xBC" - "\x73\xC7\x78\xFD\x59\x02\x0D\xC1\x87\x21\xF6\x77\x8E\x85\xE6\x13\x0E\x98\x85\xBC" - "\x23\x36\x1F\x06\x1E\x0F\x70\x20\xE0\x67\x26\x90\x21\xE9\xFF\x38\xCF\xB2\x04\x7D" - "\x38\x10\x6D\x9C\xB8\x40\x87\x6E\xC1\x26\xD9\xEE"; -#define HTTP_TIMER_SCRIPT4 Decompress(HTTP_TIMER_SCRIPT4_COMPRESSED,HTTP_TIMER_SCRIPT4_SIZE).c_str() -#endif //USE_SUNRISE -#else const char HTTP_TIMER_SCRIPT4[] PROGMEM = "function ot(t,e){" // Select tab and update elements "var i,n,o,p,q,s;" @@ -729,8 +594,6 @@ const char HTTP_TIMER_SCRIPT4[] PROGMEM = "p=(s>>15)&1;eb('r0').checked=p;" // Set repeat "p=(s>>31)&1;eb('a0').checked=p;" // Set arm "}"; -#endif //USE_UNISHOX_COMPRESSION - const char HTTP_TIMER_SCRIPT5[] PROGMEM = "function it(){" // Initialize elements and select first tab "var b,i,o,s;" @@ -801,17 +664,6 @@ const char HTTP_FORM_TIMER3[] PROGMEM = const char HTTP_FORM_TIMER3[] PROGMEM = "" D_TIMER_TIME " "; #endif // USE_SUNRISE - -#ifdef USE_UNISHOX_COMPRESSION -const size_t HTTP_FORM_TIMER4_SIZE = 249; -const char HTTP_FORM_TIMER4_COMPRESSED[] PROGMEM = "\x3D\x3C\x32\xF8\xFC\x3D\x3C\xC2\x61\xD2\xF5\x19\x04\xCF\x87\xD8\xFE\x89\x42\x8F" - "\x33\x9C\xC8\x61\xB0\xF0\x7D\xAD\x10\xF8\x7D\x8A\xC3\xEC\xFC\x3D\x0E\xC0\x41\xC0" - "\x4F\xC3\xD0\xEC\xF0\xCB\xE3\xF0\xFD\x70\xEF\x0C\x3C\x1F\x5E\x04\x18\x80\xC0\x72" - "\x41\xBA\x09\xD9\x23\x1B\xE1\x87\x83\xD0\x71\xF8\x76\xCE\xC3\xAC\xF4\x3B\x07\x02" - "\x16\x68\x0C\x0B\x2C\x1F\x04\xDC\xB0\xF4\x3B\x04\xD3\x33\xF0\xF4\x1D\xF3\xF0\xF4" - "\x13\x4C\xD6\x88\x7C\x3E\xC4\xF1\xF6\xBA\xC6\xB3\xE1\xF6\x27\x8F\xB0\x42\xBA"; -#define HTTP_FORM_TIMER4 Decompress(HTTP_FORM_TIMER4_COMPRESSED,HTTP_FORM_TIMER4_SIZE).c_str() -#else const char HTTP_FORM_TIMER4[] PROGMEM = "" " " D_HOUR_MINUTE_SEPARATOR " " @@ -820,7 +672,6 @@ const char HTTP_FORM_TIMER4[] PROGMEM = "" "
" "
"; -#endif //USE_UNISHOX_COMPRESSION void HandleTimerConfiguration(void) { @@ -854,11 +705,7 @@ void HandleTimerConfiguration(void) #else WSContentSend_P(HTTP_FORM_TIMER3); #endif // USE_SUNRISE -#ifdef USE_UNISHOX_COMPRESSION - WSContentSend_P(HTTP_FORM_TIMER4,D_HOUR_MINUTE_SEPARATOR); -#else WSContentSend_P(HTTP_FORM_TIMER4); -#endif //USE_UNISHOX_COMPRESSION WSContentSend_P(HTTP_FORM_END); WSContentSpaceButton(BUTTON_CONFIGURATION); WSContentStop(); From 5f9b5c377dcd049cd562be806f5ff449f30f9e10 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 9 Jun 2020 13:55:21 +0200 Subject: [PATCH 186/581] Revert "Revert "Merge pull request #8645 from Staars/timers"" This reverts commit 37561276080efe2836c2e44df067da0a5df2e51e. --- tasmota/xdrv_09_timers.ino | 155 ++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_09_timers.ino b/tasmota/xdrv_09_timers.ino index 61d5bc737..1ecfb0b67 100644 --- a/tasmota/xdrv_09_timers.ino +++ b/tasmota/xdrv_09_timers.ino @@ -500,6 +500,15 @@ const char S_CONFIGURE_TIMER[] PROGMEM = D_CONFIGURE_TIMER; const char HTTP_BTN_MENU_TIMER[] PROGMEM = "

"; +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_TIMER_SCRIPT1_SIZE = 106; +const char HTTP_TIMER_SCRIPT1_COMPRESSED[] PROGMEM = "\x33\xBF\xA1\x94\x7C\x3D\xE3\xDF\x3A\x83\xA3\xE1\xC4\x8F\x04\x60\x5F\x07\x5B\x9C" + "\x83\x67\x77\x4E\xA3\x51\xDE\x3D\xA6\x77\xF5\x87\xC1\x30\x31\x63\x5F\x51\xD0\x3F" + "\xBB\xA6\x4C\x26\x35\xF5\x1D\xD3\xEF\x06\x56\xE7\x1F\x67\x78\xF1\x87\x4A\x66\xCA" + "\x20\xF3\xA9\xF5\x1F\x34\xF0\x6A\x3A\x58\xC1\x8F\x84\x20\xC5\x68\x42\x1D\xDC\x3B" + "\xC7\x83\xDC"; +#define HTTP_TIMER_SCRIPT1 Decompress(HTTP_TIMER_SCRIPT1_COMPRESSED,HTTP_TIMER_SCRIPT1_SIZE).c_str() +#else const char HTTP_TIMER_SCRIPT1[] PROGMEM = "var pt=[],ct=99;" "function ce(i,q){" // Create select option @@ -507,7 +516,33 @@ const char HTTP_TIMER_SCRIPT1[] PROGMEM = "o.textContent=i;" "q.appendChild(o);" "}"; +#endif //USE_UNISHOX_COMPRESSION + #ifdef USE_SUNRISE +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_TIMER_SCRIPT2_SIZE = 630; +const char HTTP_TIMER_SCRIPT2_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x43\xD4\x77\x4E\xF1\xED\x33\xBF\xA1\xA7\x50\xC3\xA8\xD4\x78" + "\x1A\x7C\x35\x78\xEE\x9F\x7B\xC3\x05\xD1\xEF\x75\x8D\x67\xC3\xD9\xF1\x0F\x61\xEF" + "\x9E\x61\x8A\x61\x9A\x31\x0F\xB3\xBC\x74\x33\xB0\x85\xB3\xC0\xC3\xE0\xCA\x3D\xE0" + "\xE8\xF7\xCF\xD1\xC6\x46\xC3\x9E\x22\x30\x46\x0F\x1A\x60\xEE\x8D\x3E\x1F\x0E\x33" + "\xBC\x7B\x4B\xD8\x77\x4E\x33\xBC\x78\x23\x51\xF0\x86\xDD\x0A\x3A\x18\x0B\x33\xE7" + "\x74\x61\xD8\x73\x99\xDE\x3C\x16\x98\x3B\xA6\xA3\xD0\xE4\x67\x78\xF6\x91\xA8\xF8" + "\x7D\x9C\x67\xD9\xDB\x23\x51\xE0\xF7\x1A\xBC\x77\x4F\xB3\xC8\x56\x02\x1E\x5E\x7C" + "\x35\x1E\x0D\x47\xC1\x87\xD1\xF4\x73\x99\x02\x9E\x10\x37\x41\x1B\x08\x3D\xDA\x60" + "\xEE\x9D\xD1\xA7\xC3\xE1\xC8\x77\x8F\xF1\xFE\x3B\xA4\x34\xF8\x7C\x39\x47\x78\xEF" + "\x1E\xD2\xF6\x1D\xD3\x90\x81\x53\x59\x3F\x0F\x87\x25\x1D\xE3\xDA\x46\xA3\xAC\xF8" + "\x72\x51\xE0\x8D\x5E\x3B\xA7\xD9\xE4\x27\xCF\xB3\xBC\x74\xF3\x09\x87\x4C\x42\xDE" + "\x11\x9B\x0F\x87\x21\xE0\xF7\x13\x0B\xCC\xF6\x82\x9D\xC3\x8C\xF0\x7B\x88\x19\x67" + "\x04\x87\xB8\x11\x38\xE6\xF6\x1D\xD1\xC7\x78\xF6\xE1\xF0\x11\x32\xD3\xC3\x3E\x61" + "\xD0\x31\x5A\x10\x84\xC2\x63\x5F\x51\x07\x82\xFA\x8F\x1A\x60\xEE\x8E\x3E\x1F\x0E" + "\x43\xBC\x40\x8F\xC0\x1D\x19\x04\xCE\x86\x7B\xED\x1D\xA1\x6D\x19\x1F\x0F\xB3\xEC" + "\xF1\xA6\x0E\xEB\x3F\x0E\x4A\x3B\xC7\xB4\x8C\x67\xCE\xEE\x9F\x0E\x4A\x3C\x16\x9E" + "\x87\xC3\x95\x67\x82\xD3\xB6\x76\xCE\xF1\xED\xC3\xA7\xD8\xDC\x33\x64\x18\xAD\x08" + "\x43\xBB\x87\x40\xAF\xD4\x08\x7A\x08\xAD\x08\x43\xBC\x78\x3D\xC7\xB8\x13\x38\x68" + "\x04\xCD\x04\x56\x88\x23\xE0\x41\xD1\xCF\x43\x95\x64\x0A\x3A\x38\x6C\xEE\xE9\xD5" + "\x87\x78\xF0\x7B\x8F\x71\xEE\x3D\xC6"; +#define HTTP_TIMER_SCRIPT2 Decompress(HTTP_TIMER_SCRIPT2_COMPRESSED,HTTP_TIMER_SCRIPT2_SIZE).c_str() +#else const char HTTP_TIMER_SCRIPT2[] PROGMEM = "function gt(){" // Set hours and minutes according to mode "var m,p,q;" @@ -538,7 +573,55 @@ const char HTTP_TIMER_SCRIPT2[] PROGMEM = "if(e<23){for(i=12;i<=23;i++){ce(i,o);}}" // Create hours select options "}" "}"; -#endif +#endif //USE_UNISHOX_COMPRESSION +#endif //USE_SUNRISE + +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SUNRISE +const size_t HTTP_TIMER_SCRIPT3_SIZE = 587; +const char HTTP_TIMER_SCRIPT3_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x5E\xA3\xBA\x77\x8F\x69\x9D\xFD\x69\xD4\x11\xD4\x34\xEA\xE3" + "\xA8\x61\xD5\xE3\xC0\xD3\xE1\xC6\x78\x2F\x1F\x0E\x33\xC1\x71\xF0\xE4\x3D\x0F\x4B" + "\x87\x82\xD3\x07\x75\x8E\x3B\xA7\xDD\x9C\x67\xD9\xDE\x3A\x10\x62\x98\x66\x8C\x43" + "\xBC\x7B\x7C\x7F\x8F\x9C\x78\x3D\xDC\x7C\x39\x0F\x43\xD2\x69\x02\x1D\xFF\x82\x75" + "\xF3\x19\xF3\xBB\xA7\xC3\x8C\xF0\x5A\x7A\x1C\xF1\xE0\xB4\xED\x9D\xB3\xBC\x7B\x78" + "\xF8\x72\x1E\x87\xA1\xDD\x9C\x76\xCB\x4E\xF0\x21\xE2\x83\xE7\xD9\xDB\xD0\x4C\xC5" + "\x4F\x70\xD3\xE1\xAB\xC7\x74\xFB\xDE\x18\x2E\x8F\x7B\xAC\x6B\x3E\x1E\xCF\x88\x7B" + "\x0F\x7C\xF3\x04\x2C\x0C\xFB\x3B\xC7\x43\x3B\x08\x5B\x3C\x78\xFF\x1F\x0E\xE8\x2F" + "\xE0\xA7\xA1\xE8\x72\x91\xDE\x3C\x16\x98\x3B\xA7\xD0\x87\xE1\xC6\x77\x8F\x69\x69" + "\xF0\xD5\xE3\xBA\x7D\x9E\x42\x1C\x87\xD9\xDE\x3A\x17\x98\x4C\x3A\x62\x16\xF0\x8C" + "\xD8\x78\xD3\x07\x77\x4F\xC3\xE1\xC6\x77\x8F\x69\x78\xFF\x1F\x0E\xEE\x9E\x87\xA1" + "\xCA\xB3\xBC\x78\x3D\xC4\x08\x7A\x11\xE4\x30\x13\x30\xD3\xD0\xF4\x39\x5E\x3B\xC7" + "\x83\xDC\x4C\x2F\x33\xDB\xE3\xFC\x7C\x39\x67\xA1\xE9\x5E\x3C\x1E\xE2\x08\xF8\x77" + "\x41\x07\x0D\x15\x80\x97\x86\x9E\xB3\x9C\xCE\xF1\xDB\x23\x57\x8E\xE9\xF6\x79\x0D" + "\xD0\x4B\xB0\x77\x8F\xD1\xC6\x46\xC3\x9E\x22\x30\x46\x0F\x1A\x60\xEE\x8D\x3E\x02" + "\x16\xC2\x11\xE0\xF7\x69\x83\xBA\x77\x46\x9F\x0F\x87\x21\xDE\x3F\xC7\xF8\xEE\x90" + "\xD3\xE1\xF0\xE5\x1D\xE3\xBC\x7B\x4B\x4C\x02\x0E\x78\x27\xC1\x2F\x20\x3F\x0E\x33" + "\xBC\x7B\x4B\x4C\x1D\xD0\x8F\xC3\x8C\xEF\x1E\xD2\x08\xED\x9F\x0E\x7A\x99\xE0\xF7" + "\x1E\xE2\xF1\xFE\x3E\x04\x08\x59\xC1\xEE\xF1\xFE\x04\x3D\xE4\x68\xF8\x27\xEB\xA7" + "\x19\x11\x83\xBC\x7A\x1E\x87\x24\x3C\x10\xCA\x3D\xE0\xE8\xF7\xCF\x9E\x3C\x31\xC7" + "\x74\xFB\xA3\x8C\x81\x0F\x8A\x63\xE0\xCA\x3A\x1A\xF3\x78\xEE\x9D\xE3\xC1\xEE"; +#define HTTP_TIMER_SCRIPT3 Decompress(HTTP_TIMER_SCRIPT3_COMPRESSED,HTTP_TIMER_SCRIPT3_SIZE).c_str() +#else +const size_t HTTP_TIMER_SCRIPT3_SIZE = 424; +const char HTTP_TIMER_SCRIPT3_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x5E\xA3\xBA\x77\x8F\x69\x9D\xFD\x69\xD4\x11\xD4\x34\xEA\xE3" + "\xA8\x61\xD5\xE3\xC0\xD3\xE1\xC6\x78\x2F\x1F\x0E\x33\xC1\x71\xF0\xE4\x3D\x0F\x4B" + "\x87\x82\xD3\x07\x75\x8E\x3B\xA7\xDD\x9C\x67\xD9\xDE\x3A\x10\x62\x98\x66\x8C\x43" + "\xBC\x7B\x7C\x7F\x8F\x9C\x78\x3D\xDC\x7C\x39\x0F\x43\xD2\x69\x02\x1D\xFF\x82\x75" + "\xF3\x19\xF3\xBB\xA7\xC3\x8C\xF0\x5A\x7A\x1C\xF1\xE0\xB4\xED\x9D\xB3\xBC\x7B\x78" + "\xF8\x72\x1E\x87\xA1\xDD\x9C\x76\xCB\x4E\xF0\x21\xE2\x83\xE7\xD9\xDB\xD0\x4C\xC5" + "\x4F\x76\x98\x3B\xA7\xD0\x87\xE1\xC6\x77\x8F\x69\x69\xF0\xD5\xE3\xBA\x7D\x9E\x42" + "\x1C\x87\xD9\xDE\x3A\x17\x98\x4C\x3A\x62\x16\xF0\x8C\xD8\x78\xD3\x07\x77\x4F\xC3" + "\xE1\xC6\x77\x8F\x69\x78\xFF\x1F\x0E\xEE\x9E\x87\xA1\xCA\xB3\xBC\x78\x3D\xC5\xE3" + "\xFC\x7C\x3B\xA6\xAF\x1D\xD3\xEC\xF2\x18\x09\x98\x69\xE8\x7A\x1C\xAF\x1D\xE3\xC1" + "\xEE\x26\x17\x99\xED\xF1\xFE\x3E\x1C\xB3\xD0\xF4\xAF\x1E\x0F\x71\x04\x7C\x3B\xA0" + "\x83\x86\x8A\xC0\x4B\xC3\x4F\x59\xCE\x67\x78\xED\x91\xAB\xC7\x74\xFB\x3C\x86\xE8" + "\x25\xD8\x3B\xC7\xE8\xE3\x23\x61\xCF\x11\x18\x23\x07\x8D\x30\x77\x46\x9F\x01\x0B" + "\x61\x08\x10\x75\xB0\x41\xCA\xC6\x8F\x82\x7E\x1E\x71\x91\x18\x3B\xC7\xA1\xE8\x72" + "\x43\xC1\x0C\xA3\xDE\x0E\x8F\x7C\xF9\xE3\xC3\x1C\x77\x4F\xBA\x38\xCF\xB3\xBC\x74" + "\x23\x3B\x08\x5B\x3E\x0C\xA3\xA1\xAF\x37\x8E\xE9\xDE\x3C\x1E\xE3"; +#define HTTP_TIMER_SCRIPT3 Decompress(HTTP_TIMER_SCRIPT3_COMPRESSED,HTTP_TIMER_SCRIPT3_SIZE).c_str() +#endif //USE_SUNRISE +#else const char HTTP_TIMER_SCRIPT3[] PROGMEM = "function st(){" // Save parameters to hidden area "var i,l,m,n,p,s;" @@ -568,6 +651,58 @@ const char HTTP_TIMER_SCRIPT3[] PROGMEM = "pt[ct]=s;" "eb('t0').value=pt.join();" // Save parameters from array to hidden area "}"; +#endif //USE_UNISHOX_COMPRESSION + +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SUNRISE +const size_t HTTP_TIMER_SCRIPT4_SIZE = 548; +const char HTTP_TIMER_SCRIPT4_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x59\x47\x76\x8E\xA6\x77\x8F\x69\x9D\xFD\x69\xD5\xC7\x56\x1D" + "\x43\x0E\xA3\x51\xD5\xE3\xC6\x98\x3B\xA1\xD1\xE8\x71\x23\xBC\x7B\x4B\xD4\x77\x4E" + "\xF1\xE0\xF7\x07\x47\xCA\x3C\x61\xF0\x4C\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35" + "\xF5\x78\x87\x19\x10\x61\x5F\xBC\x5D\x63\x59\xDD\x3E\xE8\x23\xEC\xEF\x1E\x0C\x67" + "\xCE\xEE\x9F\x0E\x33\xC1\x69\xE9\x87\x40\x9F\x0F\x50\xA3\xC6\x9D\xB3\xB6\x77\x8F" + "\x6E\x1E\xF6\x9E\xF9\xD3\xD4\x64\x13\x3A\x07\xEF\x15\x33\x65\x1F\x0F\x60\xEB\x0C" + "\xD0\x7B\xF8\x2F\x84\x3C\xCF\x23\xE8\xE3\xE2\x36\x1E\x03\xC0\xB3\xE0\x85\x20\xC6" + "\x75\x1D\x63\xEF\x47\x85\x51\xE7\xD9\xF1\xB6\x11\xE0\xF6\x1E\xE6\x0C\x53\x1F\x1D" + "\x81\x08\x78\x3D\x87\x8F\x1F\x06\x51\xEF\x07\x47\xBE\x78\x18\x7C\x3B\xBE\x3F\x0F" + "\xC3\x94\x8E\xF1\xFA\xB3\xC1\x31\xC7\x74\xFB\x1C\x7D\x9D\xB1\x87\x78\xE8\x18\xA6" + "\x19\xA3\x10\xF8\x72\x1E\x08\x7A\x8E\xE9\xDE\x3C\x1A\x8F\x87\x77\xC7\xE1\xF8\x72" + "\x43\xBC\x7E\x99\x1B\x08\xC1\xE3\x4C\x1D\xD3\x51\xE8\x72\x33\xBC\x7B\x48\xD4\x7C" + "\x3E\xCE\x33\xEC\xED\x91\xA8\xF0\x7B\x8D\x5E\x3B\xA7\xD9\xE4\x34\x7C\xFB\x3B\xC7" + "\x43\x3B\x08\x5B\x3E\x1A\x81\x1B\x85\xB3\x9E\x20\x41\xE1\x50\x10\x74\x43\xBA\x72" + "\x71\xDB\x2D\x3B\xC7\x78\xFD\x1C\x87\x82\x63\x8E\xE9\xF6\x3E\x7D\x9D\xBD\x04\x5D" + "\x20\x61\xE0\xF7\x69\x83\xBA\x7D\x08\x7E\x1C\x64\x08\x78\x51\xCA\xB2\x04\x1D\x34" + "\xD5\xE3\xBA\x7D\x9E\x42\x1C\x84\x08\x99\xD8\xC3\xB6\x72\x10\x21\xF0\x28\x73\xC7" + "\x78\xFD\x59\x02\x0D\xC1\x87\x21\xF6\x77\x8E\x85\xE6\x13\x0E\x98\x85\xBC\x23\x36" + "\x1F\x06\x1E\x0F\x70\x20\xE0\x67\x26\x90\x21\xE9\xFF\x38\xCF\xB2\x04\x7D\x38\x10" + "\x6D\x9C\xB8\x40\x87\x6E\xC1\x26\xD9\xEE"; +#define HTTP_TIMER_SCRIPT4 Decompress(HTTP_TIMER_SCRIPT4_COMPRESSED,HTTP_TIMER_SCRIPT4_SIZE).c_str() +#else +const size_t HTTP_TIMER_SCRIPT4_SIZE = 620; +const char HTTP_TIMER_SCRIPT4_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x59\x47\x76\x8E\xA6\x77\x8F\x69\x9D\xFD\x69\xD5\xC7\x56\x1D" + "\x43\x0E\xA3\x51\xD5\xE3\xC6\x98\x3B\xA1\xD1\xE8\x71\x23\xBC\x7B\x4B\xD4\x77\x4E" + "\xF1\xE0\xF7\x07\x47\xCA\x3C\x61\xF0\x4C\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35" + "\xF5\x78\x87\x19\x10\x61\x5F\xBC\x5D\x63\x59\xDD\x3E\xE8\x23\xEC\xEF\x1E\x0C\x67" + "\xCE\xEE\x9F\x0E\x33\xC1\x69\xE9\x87\x40\x9F\x0F\x50\xA3\xC6\x9D\xB3\xB6\x77\x8F" + "\x6E\x1E\xF6\x9E\xF9\xD3\xD4\x64\x13\x3A\x07\xEF\x15\x33\x65\x1F\x0F\x60\xEB\x0C" + "\xD0\x7B\xF8\x2F\x84\x3C\xCF\x23\xE8\xE3\xE2\x36\x1E\x03\xC0\xB3\xE0\x85\x20\xC6" + "\x75\x1D\x63\xEF\x47\x85\x51\xE7\xD9\xF1\xB6\x11\xE0\xF6\x1E\xE6\x0C\x53\x1F\x1D" + "\x81\x08\x78\x3D\x87\x8F\x1F\x06\x51\xEF\x07\x47\xBE\x78\x18\x7C\xF1\xFA\x38\xC8" + "\xD8\x73\xC4\x46\x08\xC1\xE0\xD4\x7C\x21\xB7\x42\x8E\x86\x02\xCC\xF9\xDD\x18\x76" + "\x1C\xE6\x77\x8F\x05\xA6\x0E\xE9\xA8\xF4\x39\x19\xDE\x3D\xA4\x6A\x3E\x1F\x67\x19" + "\xF6\x76\xC8\xD4\x78\x3D\xC6\xAF\x1D\xD3\xEC\xF2\x15\x87\xD9\xDE\x3A\x19\xD8\x42" + "\xD9\xF0\xD4\x78\x35\x1F\x06\x1F\x47\xD1\xCE\x64\x0A\x78\x40\xDD\x04\x8C\x20\xEE" + "\xF8\xFC\x3F\x0E\x48\x77\x8F\xD3\x23\x61\x18\x05\x4C\x38\x7C\x11\xB0\xE0\x45\xE2" + "\x8C\xE7\x88\x10\x78\x9C\x18\x7C\x3B\xBE\x3F\x0F\xC3\xBA\x72\x71\xDB\x2D\x3B\xC7" + "\x78\xFD\x1C\x87\x82\x63\x8E\xE9\xF6\x3E\x7D\x9D\xBD\x3B\xC7\x40\xC5\x30\xCD\x18" + "\x87\xC1\x87\x83\xDD\xA6\x0E\xE9\xF4\x21\xF8\x71\x90\x21\xE1\x47\x2A\x2B\xC8\x10" + "\x74\xD3\x57\x8E\xE9\xF6\x79\x08\x72\x10\x22\x67\x63\x0E\xD9\xC8\x78\x20\x42\xBC" + "\x73\xC7\x78\xFD\x59\x02\x0D\xC1\x87\x21\xF6\x77\x8E\x85\xE6\x13\x0E\x98\x85\xBC" + "\x23\x36\x1F\x06\x1E\x0F\x70\x20\xE0\x67\x26\x90\x21\xE9\xFF\x38\xCF\xB2\x04\x7D" + "\x38\x10\x6D\x9C\xB8\x40\x87\x6E\xC1\x26\xD9\xEE"; +#define HTTP_TIMER_SCRIPT4 Decompress(HTTP_TIMER_SCRIPT4_COMPRESSED,HTTP_TIMER_SCRIPT4_SIZE).c_str() +#endif //USE_SUNRISE +#else const char HTTP_TIMER_SCRIPT4[] PROGMEM = "function ot(t,e){" // Select tab and update elements "var i,n,o,p,q,s;" @@ -594,6 +729,8 @@ const char HTTP_TIMER_SCRIPT4[] PROGMEM = "p=(s>>15)&1;eb('r0').checked=p;" // Set repeat "p=(s>>31)&1;eb('a0').checked=p;" // Set arm "}"; +#endif //USE_UNISHOX_COMPRESSION + const char HTTP_TIMER_SCRIPT5[] PROGMEM = "function it(){" // Initialize elements and select first tab "var b,i,o,s;" @@ -664,6 +801,17 @@ const char HTTP_FORM_TIMER3[] PROGMEM = const char HTTP_FORM_TIMER3[] PROGMEM = "" D_TIMER_TIME " "; #endif // USE_SUNRISE + +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_FORM_TIMER4_SIZE = 249; +const char HTTP_FORM_TIMER4_COMPRESSED[] PROGMEM = "\x3D\x3C\x32\xF8\xFC\x3D\x3C\xC2\x61\xD2\xF5\x19\x04\xCF\x87\xD8\xFE\x89\x42\x8F" + "\x33\x9C\xC8\x61\xB0\xF0\x7D\xAD\x10\xF8\x7D\x8A\xC3\xEC\xFC\x3D\x0E\xC0\x41\xC0" + "\x4F\xC3\xD0\xEC\xF0\xCB\xE3\xF0\xFD\x70\xEF\x0C\x3C\x1F\x5E\x04\x18\x80\xC0\x72" + "\x41\xBA\x09\xD9\x23\x1B\xE1\x87\x83\xD0\x71\xF8\x76\xCE\xC3\xAC\xF4\x3B\x07\x02" + "\x16\x68\x0C\x0B\x2C\x1F\x04\xDC\xB0\xF4\x3B\x04\xD3\x33\xF0\xF4\x1D\xF3\xF0\xF4" + "\x13\x4C\xD6\x88\x7C\x3E\xC4\xF1\xF6\xBA\xC6\xB3\xE1\xF6\x27\x8F\xB0\x42\xBA"; +#define HTTP_FORM_TIMER4 Decompress(HTTP_FORM_TIMER4_COMPRESSED,HTTP_FORM_TIMER4_SIZE).c_str() +#else const char HTTP_FORM_TIMER4[] PROGMEM = "" " " D_HOUR_MINUTE_SEPARATOR " " @@ -672,6 +820,7 @@ const char HTTP_FORM_TIMER4[] PROGMEM = "" "
" "
"; +#endif //USE_UNISHOX_COMPRESSION void HandleTimerConfiguration(void) { @@ -705,7 +854,11 @@ void HandleTimerConfiguration(void) #else WSContentSend_P(HTTP_FORM_TIMER3); #endif // USE_SUNRISE +#ifdef USE_UNISHOX_COMPRESSION + WSContentSend_P(HTTP_FORM_TIMER4,D_HOUR_MINUTE_SEPARATOR); +#else WSContentSend_P(HTTP_FORM_TIMER4); +#endif //USE_UNISHOX_COMPRESSION WSContentSend_P(HTTP_FORM_END); WSContentSpaceButton(BUTTON_CONFIGURATION); WSContentStop(); From 78e40da9d85ab9ba19ca8d48d4427c32a73aee4d Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Tue, 9 Jun 2020 11:10:08 -0300 Subject: [PATCH 187/581] Update comment on MQTT Retained messages at my_user_config.h file --- tasmota/my_user_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index edf920e74..6e20a598e 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -101,7 +101,7 @@ #define MQTT_SWITCH_RETAIN false // [SwitchRetain] Switch may send retain flag (false = off, true = on) #define MQTT_SENSOR_RETAIN false // [SensorRetain] Sensor may send retain flag (false = off, true = on) #define MQTT_NO_HOLD_RETAIN false // [SetOption62] Disable retain flag on HOLD messages -//#define MQTT_NO_RETAIN // Disable all retain flags (including LWT!) if unsupported by broker (eg Losant) +//#define MQTT_NO_RETAIN // Disable all retain flags (This don't include LWT!) if unsupported by broker (eg Losant) #define MQTT_STATUS_OFF "OFF" // [StateText1] Command or Status result when turned off (needs to be a string like "0" or "Off") #define MQTT_STATUS_ON "ON" // [StateText2] Command or Status result when turned on (needs to be a string like "1" or "On") From 152c2801ae834f170005215335c7cfb569610697 Mon Sep 17 00:00:00 2001 From: Federico Leoni Date: Tue, 9 Jun 2020 14:08:57 -0300 Subject: [PATCH 188/581] Prep for Tuya MCU Discovery --- tasmota/tasmota.h | 8 +++++ tasmota/xdrv_16_tuyamcu.ino | 62 ++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 949acec1b..c3913e8a1 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -344,4 +344,12 @@ const SerConfu8 kTasmotaSerialConfig[] PROGMEM = { SERIAL_5O2, SERIAL_6O2, SERIAL_7O2, SERIAL_8O2 }; +enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE, TUYA_MCU_FUNC_SWT1 = 1, TUYA_MCU_FUNC_SWT2, TUYA_MCU_FUNC_SWT3, TUYA_MCU_FUNC_SWT4, + TUYA_MCU_FUNC_REL1 = 11, TUYA_MCU_FUNC_REL2, TUYA_MCU_FUNC_REL3, TUYA_MCU_FUNC_REL4, TUYA_MCU_FUNC_REL5, + TUYA_MCU_FUNC_REL6, TUYA_MCU_FUNC_REL7, TUYA_MCU_FUNC_REL8, TUYA_MCU_FUNC_DIMMER = 21, TUYA_MCU_FUNC_POWER = 31, + TUYA_MCU_FUNC_CURRENT, TUYA_MCU_FUNC_VOLTAGE, TUYA_MCU_FUNC_BATTERY_STATE, TUYA_MCU_FUNC_BATTERY_PERCENTAGE, + TUYA_MCU_FUNC_REL1_INV = 41, TUYA_MCU_FUNC_REL2_INV, TUYA_MCU_FUNC_REL3_INV, TUYA_MCU_FUNC_REL4_INV, TUYA_MCU_FUNC_REL5_INV, + TUYA_MCU_FUNC_REL6_INV, TUYA_MCU_FUNC_REL7_INV, TUYA_MCU_FUNC_REL8_INV, TUYA_MCU_FUNC_LOWPOWER_MODE = 51, TUYA_MCU_FUNC_LAST = 255 +}; + #endif // _TASMOTA_H_ diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index bada16061..5c5b1a120 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -73,37 +73,37 @@ struct TUYA { } Tuya; -enum TuyaSupportedFunctions { - TUYA_MCU_FUNC_NONE, - TUYA_MCU_FUNC_SWT1 = 1, // Buttons - TUYA_MCU_FUNC_SWT2, - TUYA_MCU_FUNC_SWT3, - TUYA_MCU_FUNC_SWT4, - TUYA_MCU_FUNC_REL1 = 11, // Relays - TUYA_MCU_FUNC_REL2, - TUYA_MCU_FUNC_REL3, - TUYA_MCU_FUNC_REL4, - TUYA_MCU_FUNC_REL5, - TUYA_MCU_FUNC_REL6, - TUYA_MCU_FUNC_REL7, - TUYA_MCU_FUNC_REL8, - TUYA_MCU_FUNC_DIMMER = 21, - TUYA_MCU_FUNC_POWER = 31, - TUYA_MCU_FUNC_CURRENT, - TUYA_MCU_FUNC_VOLTAGE, - TUYA_MCU_FUNC_BATTERY_STATE, - TUYA_MCU_FUNC_BATTERY_PERCENTAGE, - TUYA_MCU_FUNC_REL1_INV = 41, // Inverted Relays - TUYA_MCU_FUNC_REL2_INV, - TUYA_MCU_FUNC_REL3_INV, - TUYA_MCU_FUNC_REL4_INV, - TUYA_MCU_FUNC_REL5_INV, - TUYA_MCU_FUNC_REL6_INV, - TUYA_MCU_FUNC_REL7_INV, - TUYA_MCU_FUNC_REL8_INV, - TUYA_MCU_FUNC_LOWPOWER_MODE = 51, - TUYA_MCU_FUNC_LAST = 255 -}; +// enum TuyaSupportedFunctions { +// TUYA_MCU_FUNC_NONE, +// TUYA_MCU_FUNC_SWT1 = 1, // Buttons +// TUYA_MCU_FUNC_SWT2, +// TUYA_MCU_FUNC_SWT3, +// TUYA_MCU_FUNC_SWT4, +// TUYA_MCU_FUNC_REL1 = 11, // Relays +// TUYA_MCU_FUNC_REL2, +// TUYA_MCU_FUNC_REL3, +// TUYA_MCU_FUNC_REL4, +// TUYA_MCU_FUNC_REL5, +// TUYA_MCU_FUNC_REL6, +// TUYA_MCU_FUNC_REL7, +// TUYA_MCU_FUNC_REL8, +// TUYA_MCU_FUNC_DIMMER = 21, +// TUYA_MCU_FUNC_POWER = 31, +// TUYA_MCU_FUNC_CURRENT, +// TUYA_MCU_FUNC_VOLTAGE, +// TUYA_MCU_FUNC_BATTERY_STATE, +// TUYA_MCU_FUNC_BATTERY_PERCENTAGE, +// TUYA_MCU_FUNC_REL1_INV = 41, // Inverted Relays +// TUYA_MCU_FUNC_REL2_INV, +// TUYA_MCU_FUNC_REL3_INV, +// TUYA_MCU_FUNC_REL4_INV, +// TUYA_MCU_FUNC_REL5_INV, +// TUYA_MCU_FUNC_REL6_INV, +// TUYA_MCU_FUNC_REL7_INV, +// TUYA_MCU_FUNC_REL8_INV, +// TUYA_MCU_FUNC_LOWPOWER_MODE = 51, +// TUYA_MCU_FUNC_LAST = 255 +// }; const char kTuyaCommand[] PROGMEM = "|" // No prefix D_CMND_TUYA_MCU "|" D_CMND_TUYA_MCU_SEND_STATE; From ba40667bb998982c47b84d52d170ec99a2901657 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 9 Jun 2020 22:21:08 +0200 Subject: [PATCH 189/581] Fix compilation with gnu++17 / c17 --- lib/bearssl-esp8266/src/pgmspace_bearssl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bearssl-esp8266/src/pgmspace_bearssl.h b/lib/bearssl-esp8266/src/pgmspace_bearssl.h index 5a42114f5..e616ffe2e 100644 --- a/lib/bearssl-esp8266/src/pgmspace_bearssl.h +++ b/lib/bearssl-esp8266/src/pgmspace_bearssl.h @@ -50,7 +50,7 @@ extern "C" { // w1, w0 #define pgm_read_with_offset(addr, res) \ - asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \ + __asm__ ("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \ "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \ "l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \ "slli %0, %0, 3\n" /* Mulitiply offset by 8, yielding an offset in bits */ \ From 325564fbc7da74211b70b166f27bcea9d832a022 Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Wed, 10 Jun 2020 10:03:02 +0200 Subject: [PATCH 190/581] Added option to set i2c address in measure...Once in lib --- lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp | 46 ++++++++++++++++++++++++--- lib/LOLIN_HP303B/src/LOLIN_HP303B.h | 6 ++-- tasmota/xsns_73_hp303b.ino | 4 +-- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp index 7f7f60a3f..b73e12b83 100644 --- a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp @@ -183,7 +183,23 @@ int16_t LOLIN_HP303B::standby(void) */ int16_t LOLIN_HP303B::measureTempOnce(float &result) { - return measureTempOnce(result, m_tempOsr); + return measureTempOnce(result, m_slaveAddress, m_tempOsr); +} + +/** + * performs one temperature measurement and writes result to the given address + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * It will not be written if result==NULL + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measureTempOnce(float &result, uint8_t slaveAddress) +{ + return measureTempOnce(result, slaveAddress, m_tempOsr); } /** @@ -202,8 +218,11 @@ int16_t LOLIN_HP303B::measureTempOnce(float &result) * -2 if the object initialization failed * -1 on other fail */ -int16_t LOLIN_HP303B::measureTempOnce(float &result, uint8_t oversamplingRate) +int16_t LOLIN_HP303B::measureTempOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate) { + //Set I2C bus connection + m_slaveAddress = slaveAddress; + //Start measurement int16_t ret = startMeasureTempOnce(oversamplingRate); if(ret!=HP303B__SUCCEEDED) @@ -288,7 +307,23 @@ int16_t LOLIN_HP303B::startMeasureTempOnce(uint8_t oversamplingRate) */ int16_t LOLIN_HP303B::measurePressureOnce(float &result) { - return measurePressureOnce(result, m_prsOsr); + return measurePressureOnce(result, m_slaveAddress, m_prsOsr); +} + +/** + * performs one pressure measurement and writes result to the given address + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * It will not be written if result==NULL + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measurePressureOnce(float &result, uint8_t slaveAddress) +{ + return measurePressureOnce(result, slaveAddress, m_prsOsr); } /** @@ -307,8 +342,11 @@ int16_t LOLIN_HP303B::measurePressureOnce(float &result) * -2 if the object initialization failed * -1 on other fail */ -int16_t LOLIN_HP303B::measurePressureOnce(float &result, uint8_t oversamplingRate) +int16_t LOLIN_HP303B::measurePressureOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate) { + //Set I2C bus connection + m_slaveAddress = slaveAddress; + //start the measurement int16_t ret = startMeasurePressureOnce(oversamplingRate); if(ret != HP303B__SUCCEEDED) diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h index 651b80380..4d04ff6da 100644 --- a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h @@ -35,11 +35,13 @@ public: //Command Mode int16_t measureTempOnce(float &result); - int16_t measureTempOnce(float &result, uint8_t oversamplingRate); + int16_t measureTempOnce(float &result, uint8_t slaveAddress); + int16_t measureTempOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate); int16_t startMeasureTempOnce(void); int16_t startMeasureTempOnce(uint8_t oversamplingRate); int16_t measurePressureOnce(float &result); - int16_t measurePressureOnce(float &result, uint8_t oversamplingRate); + int16_t measurePressureOnce(float &result, uint8_t slaveAddress); + int16_t measurePressureOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate); int16_t startMeasurePressureOnce(void); int16_t startMeasurePressureOnce(uint8_t oversamplingRate); int16_t getSingleResult(float &result); diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index 01145e0d1..1be0a1606 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -58,11 +58,11 @@ bool HP303B_Read(uint8_t hp303b_idx) float p; int16_t ret; - ret = HP303BSensor.measureTempOnce(t, hp303b_cfg.oversampling); + ret = HP303BSensor.measureTempOnce(t, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling); if (ret != 0) return false; - ret = HP303BSensor.measurePressureOnce(p, hp303b_cfg.oversampling); + ret = HP303BSensor.measurePressureOnce(p, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling); if (ret != 0) return false; From 127254b2838b820f55d144da4eb53f4a7c650e76 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 10 Jun 2020 12:59:14 +0200 Subject: [PATCH 191/581] Attempt to solve string corruption Attempt to solve string corruption (#8651) --- tasmota/settings.ino | 46 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 549799447..f8aa19ab9 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -391,8 +391,7 @@ void UpdateQuickPowerCycle(bool update) * Config Settings.text char array support \*********************************************************************************************/ -uint32_t GetSettingsTextLen(void) -{ +uint32_t GetSettingsTextLen(void) { char* position = Settings.text_pool; for (uint32_t size = 0; size < SET_MAX; size++) { while (*position++ != '\0') { } @@ -400,8 +399,20 @@ uint32_t GetSettingsTextLen(void) return position - Settings.text_pool; } -bool SettingsUpdateText(uint32_t index, const char* replace_me) -{ +bool settings_text_mutex = false; +uint32_t settings_text_busy_count = 0; + +bool SettingsUpdateFinished(void) { + uint32_t wait_loop = 10; + while (settings_text_mutex && wait_loop) { // Wait for any update to finish + yield(); + delayMicroseconds(1); + wait_loop--; + } + return (wait_loop > 0); // true if finished +} + +bool SettingsUpdateText(uint32_t index, const char* replace_me) { if (index >= SET_MAX) { return false; // Setting not supported - internal error } @@ -438,16 +449,24 @@ bool SettingsUpdateText(uint32_t index, const char* replace_me) return false; // Replace text too long } - if (diff != 0) { - // Shift Settings.text up or down - memmove_P(Settings.text_pool + start_pos + replace_len, Settings.text_pool + end_pos, char_len - end_pos); - } - // Replace text - memmove_P(Settings.text_pool + start_pos, replace, replace_len); - // Fill for future use - memset(Settings.text_pool + char_len + diff, 0x00, settings_text_size - char_len - diff); + if (settings_text_mutex && !SettingsUpdateFinished()) { + settings_text_busy_count++; + } else { + settings_text_mutex = true; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG "CR %d/%d"), GetSettingsTextLen(), settings_text_size); + if (diff != 0) { + // Shift Settings.text up or down + memmove_P(Settings.text_pool + start_pos + replace_len, Settings.text_pool + end_pos, char_len - end_pos); + } + // Replace text + memmove_P(Settings.text_pool + start_pos, replace, replace_len); + // Fill for future use + memset(Settings.text_pool + char_len + diff, 0x00, settings_text_size - char_len - diff); + + settings_text_mutex = false; + } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG "CR %d/%d, Busy %d"), GetSettingsTextLen(), settings_text_size, settings_text_busy_count); return true; } @@ -459,6 +478,7 @@ char* SettingsText(uint32_t index) if (index >= SET_MAX) { position += settings_text_size -1; // Setting not supported - internal error - return empty string } else { + SettingsUpdateFinished(); for (;index > 0; index--) { while (*position++ != '\0') { } } From 1d68fe9bc6e770f0f3ac590b98cfcadfe410a52e Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 10 Jun 2020 20:14:46 +0200 Subject: [PATCH 192/581] Cleaned TLS options and prepare for TELEGRAM --- tasmota/StackThunk_light.cpp | 2 +- tasmota/WiFiClientSecureLightBearSSL.cpp | 1827 +++++++++++----------- tasmota/WiFiClientSecureLightBearSSL.h | 442 +++--- tasmota/my_user_config.h | 12 + tasmota/tasmota.ino | 4 +- tasmota/tasmota_ca.ino | 93 +- tasmota/tasmota_globals.h | 2 +- 7 files changed, 1223 insertions(+), 1159 deletions(-) mode change 100644 => 100755 tasmota/WiFiClientSecureLightBearSSL.cpp mode change 100644 => 100755 tasmota/WiFiClientSecureLightBearSSL.h diff --git a/tasmota/StackThunk_light.cpp b/tasmota/StackThunk_light.cpp index 5dcc20d62..c9f9bc78e 100644 --- a/tasmota/StackThunk_light.cpp +++ b/tasmota/StackThunk_light.cpp @@ -40,7 +40,7 @@ uint32_t *stack_thunk_light_save = NULL; /* Saved A1 while in BearSSL */ uint32_t stack_thunk_light_refcnt = 0; //#define _stackSize (5600/4) -#if defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_TLS_FORCE_EC_CIPHER) +#ifdef USE_MQTT_TLS_FORCE_EC_CIPHER #define _stackSize (5300/4) // using a light version of bearssl we can save 300 bytes #else #define _stackSize (3600/4) // using a light version of bearssl we can save 2k diff --git a/tasmota/WiFiClientSecureLightBearSSL.cpp b/tasmota/WiFiClientSecureLightBearSSL.cpp old mode 100644 new mode 100755 index 434522b14..d0907788e --- a/tasmota/WiFiClientSecureLightBearSSL.cpp +++ b/tasmota/WiFiClientSecureLightBearSSL.cpp @@ -1,912 +1,915 @@ -/* - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (c) 2018 Earle F. Philhower, III - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "my_user_config.h" -//#ifdef USE_MQTT_TLS -#if defined ESP8266 && (defined(USE_MQTT_TLS) || defined (USE_SENDMAIL)) - -//#define DEBUG_TLS - -#define LWIP_INTERNAL - -#include -#include -#include - -extern "C" { -#include "osapi.h" -#include "ets_sys.h" -} -#include "debug.h" -#include "WiFiClientSecureLightBearSSL.h" // needs to be before "ESP8266WiFi.h" to avoid conflict with Arduino headers -#include "ESP8266WiFi.h" -#include "WiFiClient.h" -#include "StackThunk_light.h" -#include "lwip/opt.h" -#include "lwip/ip.h" -#include "lwip/tcp.h" -#include "lwip/inet.h" -#include "lwip/netif.h" -#include -#include "c_types.h" - -#include -#ifndef ARDUINO_ESP8266_RELEASE_2_5_2 -#undef DEBUG_TLS -#endif - -#ifdef DEBUG_TLS -#include "coredecls.h" -#define LOG_HEAP_SIZE(a) _Log_heap_size(a) -void _Log_heap_size(const char *msg) { - register uint32_t *sp asm("a1"); - int freestack = 4 * (sp - g_pcont->stack); - Serial.printf("%s %d, Fragmentation=%d, Thunkstack=%d, Free stack=%d, FreeContStack=%d\n", - msg, ESP.getFreeHeap(), ESP.getHeapFragmentation(), stack_thunk_light_get_max_usage(), - freestack, ESP.getFreeContStack()); -} -#else -#define LOG_HEAP_SIZE(a) -#endif - -// Stack thunked versions of calls -// Initially in BearSSLHelpers.h -extern "C" { -extern unsigned char *thunk_light_br_ssl_engine_recvapp_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_light_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len); -extern unsigned char *thunk_light_br_ssl_engine_recvrec_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_light_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len); -extern unsigned char *thunk_light_br_ssl_engine_sendapp_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_light_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len); -extern unsigned char *thunk_light_br_ssl_engine_sendrec_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_light_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len); -}; - -// Second stack thunked helpers -make_stack_thunk_light(br_ssl_engine_recvapp_ack); -make_stack_thunk_light(br_ssl_engine_recvapp_buf); -make_stack_thunk_light(br_ssl_engine_recvrec_ack); -make_stack_thunk_light(br_ssl_engine_recvrec_buf); -make_stack_thunk_light(br_ssl_engine_sendapp_ack); -make_stack_thunk_light(br_ssl_engine_sendapp_buf); -make_stack_thunk_light(br_ssl_engine_sendrec_ack); -make_stack_thunk_light(br_ssl_engine_sendrec_buf); - -// create new version of Thunk function to store on SYS stack -// unless the Thunk was initialized. Thanks to AES128 GCM, we can keep -// symetric processing on the stack -void min_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvapp_ack(cc, len); - } else { - return br_ssl_engine_recvapp_ack(cc, len); - } -} -unsigned char *min_br_ssl_engine_recvapp_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvapp_buf(cc, len); - } else { - return br_ssl_engine_recvapp_buf(cc, len); - } -} -void min_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvrec_ack(cc, len); - } else { - return br_ssl_engine_recvrec_ack(cc, len); - } -} -unsigned char *min_br_ssl_engine_recvrec_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvrec_buf(cc, len); - } else { - return br_ssl_engine_recvrec_buf(cc, len); - } -} -void min_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendapp_ack(cc, len); - } else { - return br_ssl_engine_sendapp_ack(cc, len); - } -} -unsigned char *min_br_ssl_engine_sendapp_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendapp_buf(cc, len); - } else { - return br_ssl_engine_sendapp_buf(cc, len); - } -} -void min_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendrec_ack(cc, len); - } else { - return br_ssl_engine_sendrec_ack(cc, len); - } -} -unsigned char *min_br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendrec_buf(cc, len); - } else { - return br_ssl_engine_sendrec_buf(cc, len); - } -} - -// Use min_ instead of original thunk_ -#define br_ssl_engine_recvapp_ack min_br_ssl_engine_recvapp_ack -#define br_ssl_engine_recvapp_buf min_br_ssl_engine_recvapp_buf -#define br_ssl_engine_recvrec_ack min_br_ssl_engine_recvrec_ack -#define br_ssl_engine_recvrec_buf min_br_ssl_engine_recvrec_buf -#define br_ssl_engine_sendapp_ack min_br_ssl_engine_sendapp_ack -#define br_ssl_engine_sendapp_buf min_br_ssl_engine_sendapp_buf -#define br_ssl_engine_sendrec_ack min_br_ssl_engine_sendrec_ack -#define br_ssl_engine_sendrec_buf min_br_ssl_engine_sendrec_buf - -//#define DEBUG_ESP_SSL -#ifdef DEBUG_ESP_SSL -#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__) -//#define DEBUG_BSSL(fmt, ...) Serial.printf(fmt, ## __VA_ARGS__) -#else -#define DEBUG_BSSL(...) -#endif - -namespace BearSSL { - -void WiFiClientSecure_light::_clear() { - // TLS handshake may take more than the 5 second default timeout - _timeout = 10000; // 10 seconds max, it should never go over 6 seconds - - _sc = nullptr; - _ctx_present = false; - _eng = nullptr; - _iobuf_in = nullptr; - _iobuf_out = nullptr; - _now = 0; // You can override or ensure time() is correct w/configTime - setBufferSizes(1024, 1024); // reasonable minimum - _handshake_done = false; - _last_error = 0; - _recvapp_buf = nullptr; - _recvapp_len = 0; - _fingerprint_any = true; // by default accept all fingerprints - _fingerprint1 = nullptr; - _fingerprint2 = nullptr; - _chain_P = nullptr; - _sk_ec_P = nullptr; - _ta_P = nullptr; - _max_thunkstack_use = 0; -} - -// Constructor -WiFiClientSecure_light::WiFiClientSecure_light(int recv, int xmit) : WiFiClient() { - _clear(); -LOG_HEAP_SIZE("StackThunk before"); - //stack_thunk_light_add_ref(); -LOG_HEAP_SIZE("StackThunk after"); - // now finish the setup - setBufferSizes(recv, xmit); // reasonable minimum - allocateBuffers(); -} - -WiFiClientSecure_light::~WiFiClientSecure_light() { - if (_client) { - _client->unref(); - _client = nullptr; - } - //_cipher_list = nullptr; // std::shared will free if last reference - _freeSSL(); -} - -void WiFiClientSecure_light::allocateBuffers(void) { - // We prefer to allocate all buffers at start, rather than lazy allocation and deallocation - // in the long run it avoids heap fragmentation and improves stability - LOG_HEAP_SIZE("allocateBuffers before"); - _sc = std::make_shared(); - LOG_HEAP_SIZE("allocateBuffers ClientContext"); - _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); - _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); - LOG_HEAP_SIZE("allocateBuffers after"); -} - -void WiFiClientSecure_light::setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk, - unsigned allowed_usages, unsigned cert_issuer_key_type) { - _chain_P = cert; - _sk_ec_P = sk; - _allowed_usages = allowed_usages; - _cert_issuer_key_type = cert_issuer_key_type; -} - -void WiFiClientSecure_light::setTrustAnchor(const br_x509_trust_anchor *ta) { - _ta_P = ta; -} - -void WiFiClientSecure_light::setBufferSizes(int recv, int xmit) { - // Following constants taken from bearssl/src/ssl/ssl_engine.c (not exported unfortunately) - const int MAX_OUT_OVERHEAD = 85; - const int MAX_IN_OVERHEAD = 325; - - // The data buffers must be between 512B and 16KB - recv = std::max(512, std::min(16384, recv)); - xmit = std::max(512, std::min(16384, xmit)); - - // Add in overhead for SSL protocol - recv += MAX_IN_OVERHEAD; - xmit += MAX_OUT_OVERHEAD; - _iobuf_in_size = recv; - _iobuf_out_size = xmit; -} - -bool WiFiClientSecure_light::stop(unsigned int maxWaitMs) { -#ifdef ARDUINO_ESP8266_RELEASE_2_4_2 - WiFiClient::stop(); // calls our virtual flush() - _freeSSL(); - return true; -#else - bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush() - _freeSSL(); - return ret; -#endif -} - -bool WiFiClientSecure_light::flush(unsigned int maxWaitMs) { - (void) _run_until(BR_SSL_SENDAPP); -#ifdef ARDUINO_ESP8266_RELEASE_2_4_2 - WiFiClient::flush(); -#else - return WiFiClient::flush(maxWaitMs); -#endif -} - -int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) { - clearLastError(); - if (!WiFiClient::connect(ip, port)) { - setLastError(ERR_TCP_CONNECT); - return 0; - } - return _connectSSL(nullptr); -} - -int WiFiClientSecure_light::connect(const char* name, uint16_t port) { - IPAddress remote_addr; - clearLastError(); - if (!WiFi.hostByName(name, remote_addr)) { - DEBUG_BSSL("connect: Name loopup failure\n"); - setLastError(ERR_CANT_RESOLVE_IP); - return 0; - } - if (!WiFiClient::connect(remote_addr, port)) { - DEBUG_BSSL("connect: Unable to connect TCP socket\n"); - _last_error = ERR_TCP_CONNECT; - return 0; - } - LOG_HEAP_SIZE("Before calling _connectSSL"); - return _connectSSL(name); -} - -void WiFiClientSecure_light::_freeSSL() { - _ctx_present = false; - _recvapp_buf = nullptr; - _recvapp_len = 0; - // This connection is toast - _handshake_done = false; -} - -bool WiFiClientSecure_light::_clientConnected() { - return (_client && _client->state() == ESTABLISHED); -} - -uint8_t WiFiClientSecure_light::connected() { - if (available() || (_clientConnected() && _handshake_done)) { - return true; - } - return false; -} - -size_t WiFiClientSecure_light::_write(const uint8_t *buf, size_t size, bool pmem) { - size_t sent_bytes = 0; - - if (!connected() || !size || !_handshake_done) { - return 0; - } - - do { - // Ensure we yield if we need multiple fragments to avoid WDT - if (sent_bytes) { - optimistic_yield(1000); - } - - // Get BearSSL to a state where we can send - if (_run_until(BR_SSL_SENDAPP) < 0) { - break; - } - - if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { - size_t sendapp_len; - unsigned char *sendapp_buf = br_ssl_engine_sendapp_buf(_eng, &sendapp_len); - int to_send = size > sendapp_len ? sendapp_len : size; - if (pmem) { - memcpy_P(sendapp_buf, buf, to_send); - } else { - memcpy(sendapp_buf, buf, to_send); - } - br_ssl_engine_sendapp_ack(_eng, to_send); - br_ssl_engine_flush(_eng, 0); - flush(); - buf += to_send; - sent_bytes += to_send; - size -= to_send; - } else { - break; - } - } while (size); - - LOG_HEAP_SIZE("_write"); - return sent_bytes; -} - -size_t WiFiClientSecure_light::write(const uint8_t *buf, size_t size) { - return _write(buf, size, false); -} - -size_t WiFiClientSecure_light::write_P(PGM_P buf, size_t size) { - return _write((const uint8_t *)buf, size, true); -} - -// We have to manually read and send individual chunks. -size_t WiFiClientSecure_light::write(Stream& stream) { - size_t totalSent = 0; - size_t countRead; - size_t countSent; - - if (!connected() || !_handshake_done) { - DEBUG_BSSL("write: Connect/handshake not completed yet\n"); - return 0; - } - - do { - uint8_t temp[256]; // Temporary chunk size same as ClientContext - countSent = 0; - countRead = stream.readBytes(temp, sizeof(temp)); - if (countRead) { - countSent = _write((const uint8_t*)temp, countRead, true); - totalSent += countSent; - } - yield(); // Feed the WDT - } while ((countSent == countRead) && (countSent > 0)); - return totalSent; -} - -int WiFiClientSecure_light::read(uint8_t *buf, size_t size) { - if (!ctx_present() || !_handshake_done) { - return -1; - } - - int avail = available(); - bool conn = connected(); - if (!avail && conn) { - return 0; // We're still connected, but nothing to read - } - if (!avail && !conn) { - DEBUG_BSSL("read: Not connected, none left available\n"); - return -1; - } - - if (avail) { - // Take data from the recvapp buffer - int to_copy = _recvapp_len < size ? _recvapp_len : size; - memcpy(buf, _recvapp_buf, to_copy); - br_ssl_engine_recvapp_ack(_eng, to_copy); - _recvapp_buf = nullptr; - _recvapp_len = 0; - return to_copy; - } - - if (!conn) { - DEBUG_BSSL("read: Not connected\n"); - return -1; - } - return 0; // If we're connected, no error but no read. -} - -int WiFiClientSecure_light::read() { - uint8_t c; - if (1 == read(&c, 1)) { - return c; - } - DEBUG_BSSL("read: failed\n"); - return -1; -} - -int WiFiClientSecure_light::available() { - if (_recvapp_buf) { - return _recvapp_len; // Anything from last call? - } - _recvapp_buf = nullptr; - _recvapp_len = 0; - if (!ctx_present() || _run_until(BR_SSL_RECVAPP, false) < 0) { - return 0; - } - int st = br_ssl_engine_current_state(_eng); - if (st == BR_SSL_CLOSED) { - return 0; // Nothing leftover, SSL is closed - } - if (st & BR_SSL_RECVAPP) { - _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); - return _recvapp_len; - } - - return 0; -} - -int WiFiClientSecure_light::peek() { - if (!ctx_present() || !available()) { - DEBUG_BSSL("peek: Not connected, none left available\n"); - return -1; - } - if (_recvapp_buf && _recvapp_len) { - return _recvapp_buf[0]; - } - DEBUG_BSSL("peek: No data left\n"); - return -1; -} - -size_t WiFiClientSecure_light::peekBytes(uint8_t *buffer, size_t length) { - size_t to_copy = 0; - if (!ctx_present()) { - DEBUG_BSSL("peekBytes: Not connected\n"); - return 0; - } - - _startMillis = millis(); - while ((available() < (int) length) && ((millis() - _startMillis) < 5000)) { - yield(); - } - - to_copy = _recvapp_len < length ? _recvapp_len : length; - memcpy(buffer, _recvapp_buf, to_copy); - return to_copy; -} - -/* --- Copied almost verbatim from BEARSSL SSL_IO.C --- - Run the engine, until the specified target state is achieved, or - an error occurs. The target state is SENDAPP, RECVAPP, or the - combination of both (the combination matches either). When a match is - achieved, this function returns 0. On error, it returns -1. -*/ -int WiFiClientSecure_light::_run_until(unsigned target, bool blocking) { -//LOG_HEAP_SIZE("_run_until 1"); - if (!ctx_present()) { - DEBUG_BSSL("_run_until: Not connected\n"); - return -1; - } - for (int no_work = 0; blocking || no_work < 2;) { - if (blocking) { - // Only for blocking operations can we afford to yield() - optimistic_yield(100); - } - - int state; - state = br_ssl_engine_current_state(_eng); - if (state & BR_SSL_CLOSED) { - return -1; - } - - if (!(_client->state() == ESTABLISHED) && !WiFiClient::available()) { - return (state & target) ? 0 : -1; - } - - /* - If there is some record data to send, do it. This takes - precedence over everything else. - */ - if (state & BR_SSL_SENDREC) { - unsigned char *buf; - size_t len; - int wlen; - - buf = br_ssl_engine_sendrec_buf(_eng, &len); - wlen = WiFiClient::write(buf, len); - if (wlen <= 0) { - /* - If we received a close_notify and we - still send something, then we have our - own response close_notify to send, and - the peer is allowed by RFC 5246 not to - wait for it. - */ - return -1; - } - if (wlen > 0) { - br_ssl_engine_sendrec_ack(_eng, wlen); - } - no_work = 0; - continue; - } - - /* - If we reached our target, then we are finished. - */ - if (state & target) { - return 0; - } - /* - If some application data must be read, and we did not - exit, then this means that we are trying to write data, - and that's not possible until the application data is - read. This may happen if using a shared in/out buffer, - and the underlying protocol is not strictly half-duplex. - This is unrecoverable here, so we report an error. - */ - if (state & BR_SSL_RECVAPP) { - DEBUG_BSSL("_run_until: Fatal protocol state\n"); - return -1; - } - /* - If we reached that point, then either we are trying - to read data and there is some, or the engine is stuck - until a new record is obtained. - */ - if (state & BR_SSL_RECVREC) { - if (WiFiClient::available()) { - unsigned char *buf; - size_t len; - int rlen; - - buf = br_ssl_engine_recvrec_buf(_eng, &len); - rlen = WiFiClient::read(buf, len); - if (rlen < 0) { - return -1; - } - if (rlen > 0) { - br_ssl_engine_recvrec_ack(_eng, rlen); - } - no_work = 0; - continue; - } - } - /* - We can reach that point if the target RECVAPP, and - the state contains SENDAPP only. This may happen with - a shared in/out buffer. In that case, we must flush - the buffered data to "make room" for a new incoming - record. - */ - br_ssl_engine_flush(_eng, 0); - - no_work++; // We didn't actually advance here - } - // We only get here if we ran through the loop without getting anything done - return -1; -} - -bool WiFiClientSecure_light::_wait_for_handshake() { - _handshake_done = false; - while (!_handshake_done && _clientConnected()) { - int ret = _run_until(BR_SSL_SENDAPP); - if (ret < 0) { - DEBUG_BSSL("_wait_for_handshake: failed\n"); - break; - } - if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { - _handshake_done = true; - } - optimistic_yield(1000); - } - return _handshake_done; -} - -static uint8_t htoi (unsigned char c) -{ - if (c>='0' && c <='9') return c - '0'; - else if (c>='A' && c<='F') return 10 + c - 'A'; - else if (c>='a' && c<='f') return 10 + c - 'a'; - else return 255; -} - -extern "C" { - - // see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c - void tohex(unsigned char * in, size_t insz, char * out, size_t outsz) { - unsigned char * pin = in; - static const char * hex = "0123456789ABCDEF"; - char * pout = out; - for(; pin < in+insz; pout +=3, pin++){ - pout[0] = hex[(*pin>>4) & 0xF]; - pout[1] = hex[ *pin & 0xF]; - pout[2] = ':'; - if (pout + 3 - out > outsz){ - /* Better to truncate output string than overflow buffer */ - /* it would be still better to either return a status */ - /* or ensure the target buffer is large enough and it never happen */ - break; - } - } - pout[-1] = 0; - } - - - // BearSSL doesn't define a true insecure decoder, so we make one ourselves - // from the simple parser. It generates the issuer and subject hashes and - // the SHA1 fingerprint, only one (or none!) of which will be used to - // "verify" the certificate. - - // Private x509 decoder state - struct br_x509_pubkeyfingerprint_context { - const br_x509_class *vtable; - bool done_cert; // did we parse the first cert already? - bool fingerprint_all; - uint8_t *pubkey_recv_fingerprint; - const uint8_t *fingerprint1; - const uint8_t *fingerprint2; - unsigned usages; // pubkey usage - br_x509_decoder_context ctx; // defined in BearSSL - }; - - // Callback on the first byte of any certificate - static void pubkeyfingerprint_start_chain(const br_x509_class **ctx, const char *server_name) { - br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - // Don't process anything but the first certificate in the chain - if (!xc->done_cert) { - br_x509_decoder_init(&xc->ctx, nullptr, nullptr, nullptr, nullptr); - } - (void)server_name; // ignore server name - } - - // Callback for each certificate present in the chain (but only operates - // on the first one by design). - static void pubkeyfingerprint_start_cert(const br_x509_class **ctx, uint32_t length) { - (void) ctx; // do nothing - (void) length; - } - - // Callback for each byte stream in the chain. Only process first cert. - static void pubkeyfingerprint_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) { - br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - // Don't process anything but the first certificate in the chain - if (!xc->done_cert) { - br_x509_decoder_push(&xc->ctx, (const void*)buf, len); - } - } - - // Callback on individual cert end. - static void pubkeyfingerprint_end_cert(const br_x509_class **ctx) { - br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - xc->done_cert = true; // first cert already processed - } - - static void pubkeyfingerprint_pubkey_fingerprint(br_sha1_context *shactx, br_rsa_public_key rsakey) { - br_sha1_init(shactx); - br_sha1_update(shactx, "ssh-rsa", 7); // tag - br_sha1_update(shactx, rsakey.e, rsakey.elen); // exponent - br_sha1_update(shactx, rsakey.n, rsakey.nlen); // modulus - } - - // Callback when complete chain has been parsed. - // Return 0 on validation success, !0 on validation error - static unsigned pubkeyfingerprint_end_chain(const br_x509_class **ctx) { - br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - - br_sha1_context sha1_context; - pubkeyfingerprint_pubkey_fingerprint(&sha1_context, xc->ctx.pkey.key.rsa); - br_sha1_out(&sha1_context, xc->pubkey_recv_fingerprint); // copy to fingerprint - - if (!xc->fingerprint_all) { - if (0 == memcmp(xc->fingerprint1, xc->pubkey_recv_fingerprint, 20)) { - return 0; - } - if (0 == memcmp(xc->fingerprint2, xc->pubkey_recv_fingerprint, 20)) { - return 0; - } - return 1; // no match, error - } else { - // Default (no validation at all) or no errors in prior checks = success. - return 0; - } - } - - // Return the public key from the validator (set by x509_minimal) - static const br_x509_pkey *pubkeyfingerprint_get_pkey(const br_x509_class *const *ctx, unsigned *usages) { - const br_x509_pubkeyfingerprint_context *xc = (const br_x509_pubkeyfingerprint_context *)ctx; - - if (usages != NULL) { - *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; // I said we were insecure! - } - return &xc->ctx.pkey; - } - - // Set up the x509 insecure data structures for BearSSL core to use. - void br_x509_pubkeyfingerprint_init(br_x509_pubkeyfingerprint_context *ctx, - const uint8_t *fingerprint1, const uint8_t *fingerprint2, - uint8_t *recv_fingerprint, - bool fingerprint_all) { - static const br_x509_class br_x509_pubkeyfingerprint_vtable PROGMEM = { - sizeof(br_x509_pubkeyfingerprint_context), - pubkeyfingerprint_start_chain, - pubkeyfingerprint_start_cert, - pubkeyfingerprint_append, - pubkeyfingerprint_end_cert, - pubkeyfingerprint_end_chain, - pubkeyfingerprint_get_pkey - }; - - memset(ctx, 0, sizeof * ctx); - ctx->vtable = &br_x509_pubkeyfingerprint_vtable; - ctx->done_cert = false; - ctx->fingerprint1 = fingerprint1; - ctx->fingerprint2 = fingerprint2; - ctx->pubkey_recv_fingerprint = recv_fingerprint; - ctx->fingerprint_all = fingerprint_all; - } - - // We limit to a single cipher to reduce footprint - // we reference it, don't put in PROGMEM - static const uint16_t suites[] = { -#if defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_TLS_FORCE_EC_CIPHER) - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -#else - BR_TLS_RSA_WITH_AES_128_GCM_SHA256 -#endif - }; - - // Default initializion for our SSL clients - static void br_ssl_client_base_init(br_ssl_client_context *cc) { - br_ssl_client_zero(cc); - // forbid SSL renegociation, as we free the Private Key after handshake - br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); - - br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); - br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - br_ssl_client_set_default_rsapub(cc); - br_ssl_engine_set_default_rsavrfy(&cc->eng); - - // install hashes - br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - - // AES CTR/GCM small version, not contstant time (we don't really care here as there is no TPM anyways) - br_ssl_engine_set_gcm(&cc->eng, &br_sslrec_in_gcm_vtable, &br_sslrec_out_gcm_vtable); - br_ssl_engine_set_aes_ctr(&cc->eng, &br_aes_small_ctr_vtable); - br_ssl_engine_set_ghash(&cc->eng, &br_ghash_ctmul32); - -#if defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_TLS_FORCE_EC_CIPHER) - // we support only P256 EC curve for AWS IoT, no EC curve for Letsencrypt unless forced - br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15); -#endif - } -} - -// Called by connect() to do the actual SSL setup and handshake. -// Returns if the SSL handshake succeeded. -bool WiFiClientSecure_light::_connectSSL(const char* hostName) { -#ifdef USE_MQTT_AWS_IOT - if ((!_chain_P) || (!_sk_ec_P)) { - setLastError(ERR_MISSING_EC_KEY); - return false; - } -#endif - - // Validation context, either full CA validation or checking only fingerprints -#ifdef USE_MQTT_TLS_CA_CERT - br_x509_minimal_context *x509_minimal; -#else - br_x509_pubkeyfingerprint_context *x509_insecure; -#endif - - LOG_HEAP_SIZE("_connectSSL.start"); - - do { // used to exit on Out of Memory error and keep all cleanup code at the same place - // ============================================================ - // allocate Thunk stack, move to alternate stack and initialize - stack_thunk_light_add_ref(); - LOG_HEAP_SIZE("Thunk allocated"); - DEBUG_BSSL("_connectSSL: start connection\n"); - _freeSSL(); - clearLastError(); - if (!stack_thunk_light_get_stack_bot()) break; - - _ctx_present = true; - _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr - - br_ssl_client_base_init(_sc.get()); - - // ============================================================ - // Allocatte and initialize Decoder Context - LOG_HEAP_SIZE("_connectSSL before DecoderContext allocation"); - // Only failure possible in the installation is OOM - #ifdef USE_MQTT_TLS_CA_CERT - x509_minimal = (br_x509_minimal_context*) malloc(sizeof(br_x509_minimal_context)); - if (!x509_minimal) break; - br_x509_minimal_init(x509_minimal, &br_sha256_vtable, _ta_P, 1); - br_x509_minimal_set_rsa(x509_minimal, br_ssl_engine_get_rsavrfy(_eng)); - br_x509_minimal_set_hash(x509_minimal, br_sha256_ID, &br_sha256_vtable); - br_ssl_engine_set_x509(_eng, &x509_minimal->vtable); - - #else - x509_insecure = (br_x509_pubkeyfingerprint_context*) malloc(sizeof(br_x509_pubkeyfingerprint_context)); - //x509_insecure = std::unique_ptr(new br_x509_pubkeyfingerprint_context); - if (!x509_insecure) break; - br_x509_pubkeyfingerprint_init(x509_insecure, _fingerprint1, _fingerprint2, _recv_fingerprint, _fingerprint_any); - br_ssl_engine_set_x509(_eng, &x509_insecure->vtable); - #endif - LOG_HEAP_SIZE("_connectSSL after DecoderContext allocation"); - - // ============================================================ - // Set send/receive buffers - br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); - - // ============================================================ - // allocate Private key if needed, only if USE_MQTT_AWS_IOT - LOG_HEAP_SIZE("_connectSSL before PrivKey allocation"); - #ifdef USE_MQTT_AWS_IOT - // ============================================================ - // Set the EC Private Key, only USE_MQTT_AWS_IOT - // limited to P256 curve - br_ssl_client_set_single_ec(_sc.get(), _chain_P, 1, - _sk_ec_P, _allowed_usages, - _cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default()); - #endif // USE_MQTT_AWS_IOT - - // ============================================================ - // Start TLS connection, ALL - if (!br_ssl_client_reset(_sc.get(), hostName, 0)) break; - - auto ret = _wait_for_handshake(); - #ifdef DEBUG_ESP_SSL - if (!ret) { - DEBUG_BSSL("Couldn't connect. Error = %d\n", getLastError()); - } else { - DEBUG_BSSL("Connected! MFLNStatus = %d\n", getMFLNStatus()); - } - #endif - LOG_HEAP_SIZE("_connectSSL.end"); - _max_thunkstack_use = stack_thunk_light_get_max_usage(); - stack_thunk_light_del_ref(); - //stack_thunk_light_repaint(); - LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk"); - - #ifdef USE_MQTT_TLS_CA_CERT - free(x509_minimal); - #else - free(x509_insecure); - #endif - LOG_HEAP_SIZE("_connectSSL after release of Priv Key"); - return ret; - } while (0); - - // ============================================================ - // if we arrived here, this means we had an OOM error, cleaning up - setLastError(ERR_OOM); - DEBUG_BSSL("_connectSSL: Out of memory\n"); - stack_thunk_light_del_ref(); -#ifdef USE_MQTT_TLS_CA_CERT - free(x509_minimal); -#else - free(x509_insecure); -#endif - LOG_HEAP_SIZE("_connectSSL clean_on_error"); - return false; -} - -}; - -#include "t_bearssl_tasmota_config.h" - -#endif // USE_MQTT_TLS +/* + WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries + - Mostly compatible with Arduino WiFi shield library and standard + WiFiClient/ServerSecure (except for certificate handling). + + Copyright (c) 2018 Earle F. Philhower, III + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "my_user_config.h" +#if defined(ESP8266) && defined(USE_TLS) + +// #define DEBUG_TLS +// #define DEBUG_ESP_SSL + +#define LWIP_INTERNAL + +#include +#include +#include + +extern "C" { +#include "osapi.h" +#include "ets_sys.h" +} +#include "debug.h" +#include "WiFiClientSecureLightBearSSL.h" // needs to be before "ESP8266WiFi.h" to avoid conflict with Arduino headers +#include "ESP8266WiFi.h" +#include "WiFiClient.h" +#include "StackThunk_light.h" +#include "lwip/opt.h" +#include "lwip/ip.h" +#include "lwip/tcp.h" +#include "lwip/inet.h" +#include "lwip/netif.h" +#include +#include "c_types.h" + +#include +#ifndef ARDUINO_ESP8266_RELEASE_2_5_2 +#undef DEBUG_TLS +#endif + +#ifdef DEBUG_TLS +#include "coredecls.h" +#define LOG_HEAP_SIZE(a) _Log_heap_size(a) +void _Log_heap_size(const char *msg) { + register uint32_t *sp asm("a1"); + int freestack = 4 * (sp - g_pcont->stack); + Serial.printf("%s %d, Fragmentation=%d, Thunkstack=%d, Free stack=%d, FreeContStack=%d\n", + msg, ESP.getFreeHeap(), ESP.getHeapFragmentation(), stack_thunk_light_get_max_usage(), + freestack, ESP.getFreeContStack()); +} +#else +#define LOG_HEAP_SIZE(a) +#endif + +// Stack thunked versions of calls +// Initially in BearSSLHelpers.h +extern "C" { +extern unsigned char *thunk_light_br_ssl_engine_recvapp_buf( const br_ssl_engine_context *cc, size_t *len); +extern void thunk_light_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len); +extern unsigned char *thunk_light_br_ssl_engine_recvrec_buf( const br_ssl_engine_context *cc, size_t *len); +extern void thunk_light_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len); +extern unsigned char *thunk_light_br_ssl_engine_sendapp_buf( const br_ssl_engine_context *cc, size_t *len); +extern void thunk_light_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len); +extern unsigned char *thunk_light_br_ssl_engine_sendrec_buf( const br_ssl_engine_context *cc, size_t *len); +extern void thunk_light_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len); +}; + +// Second stack thunked helpers +make_stack_thunk_light(br_ssl_engine_recvapp_ack); +make_stack_thunk_light(br_ssl_engine_recvapp_buf); +make_stack_thunk_light(br_ssl_engine_recvrec_ack); +make_stack_thunk_light(br_ssl_engine_recvrec_buf); +make_stack_thunk_light(br_ssl_engine_sendapp_ack); +make_stack_thunk_light(br_ssl_engine_sendapp_buf); +make_stack_thunk_light(br_ssl_engine_sendrec_ack); +make_stack_thunk_light(br_ssl_engine_sendrec_buf); + +// create new version of Thunk function to store on SYS stack +// unless the Thunk was initialized. Thanks to AES128 GCM, we can keep +// symetric processing on the stack +void min_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvapp_ack(cc, len); + } else { + return br_ssl_engine_recvapp_ack(cc, len); + } +} +unsigned char *min_br_ssl_engine_recvapp_buf(const br_ssl_engine_context *cc, size_t *len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvapp_buf(cc, len); + } else { + return br_ssl_engine_recvapp_buf(cc, len); + } +} +void min_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvrec_ack(cc, len); + } else { + return br_ssl_engine_recvrec_ack(cc, len); + } +} +unsigned char *min_br_ssl_engine_recvrec_buf(const br_ssl_engine_context *cc, size_t *len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvrec_buf(cc, len); + } else { + return br_ssl_engine_recvrec_buf(cc, len); + } +} +void min_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendapp_ack(cc, len); + } else { + return br_ssl_engine_sendapp_ack(cc, len); + } +} +unsigned char *min_br_ssl_engine_sendapp_buf(const br_ssl_engine_context *cc, size_t *len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendapp_buf(cc, len); + } else { + return br_ssl_engine_sendapp_buf(cc, len); + } +} +void min_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendrec_ack(cc, len); + } else { + return br_ssl_engine_sendrec_ack(cc, len); + } +} +unsigned char *min_br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, size_t *len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendrec_buf(cc, len); + } else { + return br_ssl_engine_sendrec_buf(cc, len); + } +} + +// Use min_ instead of original thunk_ +#define br_ssl_engine_recvapp_ack min_br_ssl_engine_recvapp_ack +#define br_ssl_engine_recvapp_buf min_br_ssl_engine_recvapp_buf +#define br_ssl_engine_recvrec_ack min_br_ssl_engine_recvrec_ack +#define br_ssl_engine_recvrec_buf min_br_ssl_engine_recvrec_buf +#define br_ssl_engine_sendapp_ack min_br_ssl_engine_sendapp_ack +#define br_ssl_engine_sendapp_buf min_br_ssl_engine_sendapp_buf +#define br_ssl_engine_sendrec_ack min_br_ssl_engine_sendrec_ack +#define br_ssl_engine_sendrec_buf min_br_ssl_engine_sendrec_buf + +//#define DEBUG_ESP_SSL +#ifdef DEBUG_ESP_SSL +//#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__) +#define DEBUG_BSSL(fmt, ...) Serial.printf(fmt, ## __VA_ARGS__) +#else +#define DEBUG_BSSL(...) +#endif + +namespace BearSSL { + +void WiFiClientSecure_light::_clear() { + // TLS handshake may take more than the 5 second default timeout + _timeout = 10000; // 10 seconds max, it should never go over 6 seconds + + _sc = nullptr; + _ctx_present = false; + _eng = nullptr; + _iobuf_in = nullptr; + _iobuf_out = nullptr; + _now = 0; // You can override or ensure time() is correct w/configTime + setBufferSizes(1024, 1024); // reasonable minimum + _handshake_done = false; + _last_error = 0; + _recvapp_buf = nullptr; + _recvapp_len = 0; + _fingerprint_any = true; // by default accept all fingerprints + _fingerprint1 = nullptr; + _fingerprint2 = nullptr; + _chain_P = nullptr; + _sk_ec_P = nullptr; + _ta_P = nullptr; + _max_thunkstack_use = 0; +} + +// Constructor +WiFiClientSecure_light::WiFiClientSecure_light(int recv, int xmit) : WiFiClient() { + _clear(); +LOG_HEAP_SIZE("StackThunk before"); + //stack_thunk_light_add_ref(); +LOG_HEAP_SIZE("StackThunk after"); + // now finish the setup + setBufferSizes(recv, xmit); // reasonable minimum + allocateBuffers(); +} + +WiFiClientSecure_light::~WiFiClientSecure_light() { + if (_client) { + _client->unref(); + _client = nullptr; + } + //_cipher_list = nullptr; // std::shared will free if last reference + _freeSSL(); +} + +void WiFiClientSecure_light::allocateBuffers(void) { + // We prefer to allocate all buffers at start, rather than lazy allocation and deallocation + // in the long run it avoids heap fragmentation and improves stability + LOG_HEAP_SIZE("allocateBuffers before"); + _sc = std::make_shared(); + LOG_HEAP_SIZE("allocateBuffers ClientContext"); + _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); + _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); + LOG_HEAP_SIZE("allocateBuffers after"); +} + +void WiFiClientSecure_light::setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk, + unsigned allowed_usages, unsigned cert_issuer_key_type) { + _chain_P = cert; + _sk_ec_P = sk; + _allowed_usages = allowed_usages; + _cert_issuer_key_type = cert_issuer_key_type; +} + +void WiFiClientSecure_light::setTrustAnchor(const br_x509_trust_anchor *ta) { + _ta_P = ta; +} + +void WiFiClientSecure_light::setBufferSizes(int recv, int xmit) { + // Following constants taken from bearssl/src/ssl/ssl_engine.c (not exported unfortunately) + const int MAX_OUT_OVERHEAD = 85; + const int MAX_IN_OVERHEAD = 325; + + // The data buffers must be between 512B and 16KB + recv = std::max(512, std::min(16384, recv)); + xmit = std::max(512, std::min(16384, xmit)); + + // Add in overhead for SSL protocol + recv += MAX_IN_OVERHEAD; + xmit += MAX_OUT_OVERHEAD; + _iobuf_in_size = recv; + _iobuf_out_size = xmit; +} + +bool WiFiClientSecure_light::stop(unsigned int maxWaitMs) { +#ifdef ARDUINO_ESP8266_RELEASE_2_4_2 + WiFiClient::stop(); // calls our virtual flush() + _freeSSL(); + return true; +#else + bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush() + _freeSSL(); + return ret; +#endif +} + +bool WiFiClientSecure_light::flush(unsigned int maxWaitMs) { + (void) _run_until(BR_SSL_SENDAPP); +#ifdef ARDUINO_ESP8266_RELEASE_2_4_2 + WiFiClient::flush(); +#else + return WiFiClient::flush(maxWaitMs); +#endif +} + +int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) { + DEBUG_BSSL("connect(%s,%d)", ip.toString().c_str(), port); + clearLastError(); + if (!WiFiClient::connect(ip, port)) { + setLastError(ERR_TCP_CONNECT); + return 0; + } + return _connectSSL(nullptr); +} + +int WiFiClientSecure_light::connect(const char* name, uint16_t port) { + DEBUG_BSSL("connect(%s,%d)\n", name, port); + IPAddress remote_addr; + clearLastError(); + if (!WiFi.hostByName(name, remote_addr)) { + DEBUG_BSSL("connect: Name loopup failure\n"); + setLastError(ERR_CANT_RESOLVE_IP); + return 0; + } + DEBUG_BSSL("connect(%s,%d)\n", remote_addr.toString().c_str(), port); + if (!WiFiClient::connect(remote_addr, port)) { + DEBUG_BSSL("connect: Unable to connect TCP socket\n"); + _last_error = ERR_TCP_CONNECT; + return 0; + } + LOG_HEAP_SIZE("Before calling _connectSSL"); + return _connectSSL(name); +} + +void WiFiClientSecure_light::_freeSSL() { + _ctx_present = false; + _recvapp_buf = nullptr; + _recvapp_len = 0; + // This connection is toast + _handshake_done = false; +} + +bool WiFiClientSecure_light::_clientConnected() { + return (_client && _client->state() == ESTABLISHED); +} + +uint8_t WiFiClientSecure_light::connected() { + if (available() || (_clientConnected() && _handshake_done)) { + return true; + } + return false; +} + +size_t WiFiClientSecure_light::_write(const uint8_t *buf, size_t size, bool pmem) { + size_t sent_bytes = 0; + + if (!connected() || !size || !_handshake_done) { + return 0; + } + + do { + // Ensure we yield if we need multiple fragments to avoid WDT + if (sent_bytes) { + optimistic_yield(1000); + } + + // Get BearSSL to a state where we can send + if (_run_until(BR_SSL_SENDAPP) < 0) { + break; + } + + if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { + size_t sendapp_len; + unsigned char *sendapp_buf = br_ssl_engine_sendapp_buf(_eng, &sendapp_len); + int to_send = size > sendapp_len ? sendapp_len : size; + if (pmem) { + memcpy_P(sendapp_buf, buf, to_send); + } else { + memcpy(sendapp_buf, buf, to_send); + } + br_ssl_engine_sendapp_ack(_eng, to_send); + br_ssl_engine_flush(_eng, 0); + flush(); + buf += to_send; + sent_bytes += to_send; + size -= to_send; + } else { + break; + } + } while (size); + + LOG_HEAP_SIZE("_write"); + return sent_bytes; +} + +size_t WiFiClientSecure_light::write(const uint8_t *buf, size_t size) { + return _write(buf, size, false); +} + +size_t WiFiClientSecure_light::write_P(PGM_P buf, size_t size) { + return _write((const uint8_t *)buf, size, true); +} + +// We have to manually read and send individual chunks. +size_t WiFiClientSecure_light::write(Stream& stream) { + size_t totalSent = 0; + size_t countRead; + size_t countSent; + + if (!connected() || !_handshake_done) { + DEBUG_BSSL("write: Connect/handshake not completed yet\n"); + return 0; + } + + do { + uint8_t temp[256]; // Temporary chunk size same as ClientContext + countSent = 0; + countRead = stream.readBytes(temp, sizeof(temp)); + if (countRead) { + countSent = _write((const uint8_t*)temp, countRead, true); + totalSent += countSent; + } + yield(); // Feed the WDT + } while ((countSent == countRead) && (countSent > 0)); + return totalSent; +} + +int WiFiClientSecure_light::read(uint8_t *buf, size_t size) { + if (!ctx_present() || !_handshake_done) { + return -1; + } + + int avail = available(); + bool conn = connected(); + if (!avail && conn) { + return 0; // We're still connected, but nothing to read + } + if (!avail && !conn) { + DEBUG_BSSL("read: Not connected, none left available\n"); + return -1; + } + + if (avail) { + // Take data from the recvapp buffer + int to_copy = _recvapp_len < size ? _recvapp_len : size; + memcpy(buf, _recvapp_buf, to_copy); + br_ssl_engine_recvapp_ack(_eng, to_copy); + _recvapp_buf = nullptr; + _recvapp_len = 0; + return to_copy; + } + + if (!conn) { + DEBUG_BSSL("read: Not connected\n"); + return -1; + } + return 0; // If we're connected, no error but no read. +} + +int WiFiClientSecure_light::read() { + uint8_t c; + if (1 == read(&c, 1)) { + return c; + } + DEBUG_BSSL("read: failed\n"); + return -1; +} + +int WiFiClientSecure_light::available() { + if (_recvapp_buf) { + return _recvapp_len; // Anything from last call? + } + _recvapp_buf = nullptr; + _recvapp_len = 0; + if (!ctx_present() || _run_until(BR_SSL_RECVAPP, false) < 0) { + return 0; + } + int st = br_ssl_engine_current_state(_eng); + if (st == BR_SSL_CLOSED) { + return 0; // Nothing leftover, SSL is closed + } + if (st & BR_SSL_RECVAPP) { + _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); + return _recvapp_len; + } + + return 0; +} + +int WiFiClientSecure_light::peek() { + if (!ctx_present() || !available()) { + DEBUG_BSSL("peek: Not connected, none left available\n"); + return -1; + } + if (_recvapp_buf && _recvapp_len) { + return _recvapp_buf[0]; + } + DEBUG_BSSL("peek: No data left\n"); + return -1; +} + +size_t WiFiClientSecure_light::peekBytes(uint8_t *buffer, size_t length) { + size_t to_copy = 0; + if (!ctx_present()) { + DEBUG_BSSL("peekBytes: Not connected\n"); + return 0; + } + + _startMillis = millis(); + while ((available() < (int) length) && ((millis() - _startMillis) < 5000)) { + yield(); + } + + to_copy = _recvapp_len < length ? _recvapp_len : length; + memcpy(buffer, _recvapp_buf, to_copy); + return to_copy; +} + +/* --- Copied almost verbatim from BEARSSL SSL_IO.C --- + Run the engine, until the specified target state is achieved, or + an error occurs. The target state is SENDAPP, RECVAPP, or the + combination of both (the combination matches either). When a match is + achieved, this function returns 0. On error, it returns -1. +*/ +int WiFiClientSecure_light::_run_until(unsigned target, bool blocking) { +//LOG_HEAP_SIZE("_run_until 1"); + if (!ctx_present()) { + DEBUG_BSSL("_run_until: Not connected\n"); + return -1; + } + for (int no_work = 0; blocking || no_work < 2;) { + if (blocking) { + // Only for blocking operations can we afford to yield() + optimistic_yield(100); + } + + int state; + state = br_ssl_engine_current_state(_eng); + if (state & BR_SSL_CLOSED) { + return -1; + } + + if (!(_client->state() == ESTABLISHED) && !WiFiClient::available()) { + return (state & target) ? 0 : -1; + } + + /* + If there is some record data to send, do it. This takes + precedence over everything else. + */ + if (state & BR_SSL_SENDREC) { + unsigned char *buf; + size_t len; + int wlen; + + buf = br_ssl_engine_sendrec_buf(_eng, &len); + wlen = WiFiClient::write(buf, len); + if (wlen <= 0) { + /* + If we received a close_notify and we + still send something, then we have our + own response close_notify to send, and + the peer is allowed by RFC 5246 not to + wait for it. + */ + return -1; + } + if (wlen > 0) { + br_ssl_engine_sendrec_ack(_eng, wlen); + } + no_work = 0; + continue; + } + + /* + If we reached our target, then we are finished. + */ + if (state & target) { + return 0; + } + /* + If some application data must be read, and we did not + exit, then this means that we are trying to write data, + and that's not possible until the application data is + read. This may happen if using a shared in/out buffer, + and the underlying protocol is not strictly half-duplex. + This is unrecoverable here, so we report an error. + */ + if (state & BR_SSL_RECVAPP) { + DEBUG_BSSL("_run_until: Fatal protocol state\n"); + return -1; + } + /* + If we reached that point, then either we are trying + to read data and there is some, or the engine is stuck + until a new record is obtained. + */ + if (state & BR_SSL_RECVREC) { + if (WiFiClient::available()) { + unsigned char *buf; + size_t len; + int rlen; + + buf = br_ssl_engine_recvrec_buf(_eng, &len); + rlen = WiFiClient::read(buf, len); + if (rlen < 0) { + return -1; + } + if (rlen > 0) { + br_ssl_engine_recvrec_ack(_eng, rlen); + } + no_work = 0; + continue; + } + } + /* + We can reach that point if the target RECVAPP, and + the state contains SENDAPP only. This may happen with + a shared in/out buffer. In that case, we must flush + the buffered data to "make room" for a new incoming + record. + */ + br_ssl_engine_flush(_eng, 0); + + no_work++; // We didn't actually advance here + } + // We only get here if we ran through the loop without getting anything done + return -1; +} + +bool WiFiClientSecure_light::_wait_for_handshake() { + _handshake_done = false; + while (!_handshake_done && _clientConnected()) { + int ret = _run_until(BR_SSL_SENDAPP); + if (ret < 0) { + DEBUG_BSSL("_wait_for_handshake: failed\n"); + break; + } + if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { + _handshake_done = true; + } + optimistic_yield(1000); + } + return _handshake_done; +} + +static uint8_t htoi (unsigned char c) +{ + if (c>='0' && c <='9') return c - '0'; + else if (c>='A' && c<='F') return 10 + c - 'A'; + else if (c>='a' && c<='f') return 10 + c - 'a'; + else return 255; +} + +extern "C" { + + // see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c + void tohex(unsigned char * in, size_t insz, char * out, size_t outsz) { + unsigned char * pin = in; + static const char * hex = "0123456789ABCDEF"; + char * pout = out; + for(; pin < in+insz; pout +=3, pin++){ + pout[0] = hex[(*pin>>4) & 0xF]; + pout[1] = hex[ *pin & 0xF]; + pout[2] = ':'; + if (pout + 3 - out > outsz){ + /* Better to truncate output string than overflow buffer */ + /* it would be still better to either return a status */ + /* or ensure the target buffer is large enough and it never happen */ + break; + } + } + pout[-1] = 0; + } + + + // BearSSL doesn't define a true insecure decoder, so we make one ourselves + // from the simple parser. It generates the issuer and subject hashes and + // the SHA1 fingerprint, only one (or none!) of which will be used to + // "verify" the certificate. + + // Private x509 decoder state + struct br_x509_pubkeyfingerprint_context { + const br_x509_class *vtable; + bool done_cert; // did we parse the first cert already? + bool fingerprint_all; + uint8_t *pubkey_recv_fingerprint; + const uint8_t *fingerprint1; + const uint8_t *fingerprint2; + unsigned usages; // pubkey usage + br_x509_decoder_context ctx; // defined in BearSSL + }; + + // Callback on the first byte of any certificate + static void pubkeyfingerprint_start_chain(const br_x509_class **ctx, const char *server_name) { + br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; + // Don't process anything but the first certificate in the chain + if (!xc->done_cert) { + br_x509_decoder_init(&xc->ctx, nullptr, nullptr, nullptr, nullptr); + } + (void)server_name; // ignore server name + } + + // Callback for each certificate present in the chain (but only operates + // on the first one by design). + static void pubkeyfingerprint_start_cert(const br_x509_class **ctx, uint32_t length) { + (void) ctx; // do nothing + (void) length; + } + + // Callback for each byte stream in the chain. Only process first cert. + static void pubkeyfingerprint_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) { + br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; + // Don't process anything but the first certificate in the chain + if (!xc->done_cert) { + br_x509_decoder_push(&xc->ctx, (const void*)buf, len); + } + } + + // Callback on individual cert end. + static void pubkeyfingerprint_end_cert(const br_x509_class **ctx) { + br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; + xc->done_cert = true; // first cert already processed + } + + static void pubkeyfingerprint_pubkey_fingerprint(br_sha1_context *shactx, br_rsa_public_key rsakey) { + br_sha1_init(shactx); + br_sha1_update(shactx, "ssh-rsa", 7); // tag + br_sha1_update(shactx, rsakey.e, rsakey.elen); // exponent + br_sha1_update(shactx, rsakey.n, rsakey.nlen); // modulus + } + + // Callback when complete chain has been parsed. + // Return 0 on validation success, !0 on validation error + static unsigned pubkeyfingerprint_end_chain(const br_x509_class **ctx) { + br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; + + br_sha1_context sha1_context; + pubkeyfingerprint_pubkey_fingerprint(&sha1_context, xc->ctx.pkey.key.rsa); + br_sha1_out(&sha1_context, xc->pubkey_recv_fingerprint); // copy to fingerprint + + if (!xc->fingerprint_all) { + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) { + return 0; + } + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) { + return 0; + } + return 1; // no match, error + } else { + // Default (no validation at all) or no errors in prior checks = success. + return 0; + } + } + + // Return the public key from the validator (set by x509_minimal) + static const br_x509_pkey *pubkeyfingerprint_get_pkey(const br_x509_class *const *ctx, unsigned *usages) { + const br_x509_pubkeyfingerprint_context *xc = (const br_x509_pubkeyfingerprint_context *)ctx; + + if (usages != NULL) { + *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; // I said we were insecure! + } + return &xc->ctx.pkey; + } + + // Set up the x509 insecure data structures for BearSSL core to use. + void br_x509_pubkeyfingerprint_init(br_x509_pubkeyfingerprint_context *ctx, + const uint8_t *fingerprint1, const uint8_t *fingerprint2, + uint8_t *recv_fingerprint, + bool fingerprint_all) { + static const br_x509_class br_x509_pubkeyfingerprint_vtable PROGMEM = { + sizeof(br_x509_pubkeyfingerprint_context), + pubkeyfingerprint_start_chain, + pubkeyfingerprint_start_cert, + pubkeyfingerprint_append, + pubkeyfingerprint_end_cert, + pubkeyfingerprint_end_chain, + pubkeyfingerprint_get_pkey + }; + + memset(ctx, 0, sizeof * ctx); + ctx->vtable = &br_x509_pubkeyfingerprint_vtable; + ctx->done_cert = false; + ctx->fingerprint1 = fingerprint1; + ctx->fingerprint2 = fingerprint2; + ctx->pubkey_recv_fingerprint = recv_fingerprint; + ctx->fingerprint_all = fingerprint_all; + } + + // We limit to a single cipher to reduce footprint + // we reference it, don't put in PROGMEM + static const uint16_t suites[] = { +#ifdef USE_MQTT_TLS_FORCE_EC_CIPHER + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 +#else + BR_TLS_RSA_WITH_AES_128_GCM_SHA256 +#endif + }; + + // Default initializion for our SSL clients + static void br_ssl_client_base_init(br_ssl_client_context *cc) { + br_ssl_client_zero(cc); + // forbid SSL renegociation, as we free the Private Key after handshake + br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); + + br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); + br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); + br_ssl_client_set_default_rsapub(cc); + br_ssl_engine_set_default_rsavrfy(&cc->eng); + + // install hashes + br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + + // AES CTR/GCM small version, not contstant time (we don't really care here as there is no TPM anyways) + br_ssl_engine_set_gcm(&cc->eng, &br_sslrec_in_gcm_vtable, &br_sslrec_out_gcm_vtable); + br_ssl_engine_set_aes_ctr(&cc->eng, &br_aes_small_ctr_vtable); + br_ssl_engine_set_ghash(&cc->eng, &br_ghash_ctmul32); + +#ifdef USE_MQTT_TLS_FORCE_EC_CIPHER + // we support only P256 EC curve for AWS IoT, no EC curve for Letsencrypt unless forced + br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15); +#endif + } +} + +// Called by connect() to do the actual SSL setup and handshake. +// Returns if the SSL handshake succeeded. +bool WiFiClientSecure_light::_connectSSL(const char* hostName) { +// #ifdef USE_MQTT_AWS_IOT +// if ((!_chain_P) || (!_sk_ec_P)) { +// setLastError(ERR_MISSING_EC_KEY); +// return false; +// } +// #endif + + // Validation context, either full CA validation or checking only fingerprints +#ifdef USE_MQTT_TLS_CA_CERT + br_x509_minimal_context *x509_minimal; +#else + br_x509_pubkeyfingerprint_context *x509_insecure; +#endif + + LOG_HEAP_SIZE("_connectSSL.start"); + + do { // used to exit on Out of Memory error and keep all cleanup code at the same place + // ============================================================ + // allocate Thunk stack, move to alternate stack and initialize + stack_thunk_light_add_ref(); + LOG_HEAP_SIZE("Thunk allocated"); + DEBUG_BSSL("_connectSSL: start connection\n"); + _freeSSL(); + clearLastError(); + if (!stack_thunk_light_get_stack_bot()) break; + + _ctx_present = true; + _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr + + br_ssl_client_base_init(_sc.get()); + + // ============================================================ + // Allocatte and initialize Decoder Context + LOG_HEAP_SIZE("_connectSSL before DecoderContext allocation"); + // Only failure possible in the installation is OOM + #ifdef USE_MQTT_TLS_CA_CERT + x509_minimal = (br_x509_minimal_context*) malloc(sizeof(br_x509_minimal_context)); + if (!x509_minimal) break; + br_x509_minimal_init(x509_minimal, &br_sha256_vtable, _ta_P, 1); + br_x509_minimal_set_rsa(x509_minimal, br_ssl_engine_get_rsavrfy(_eng)); + br_x509_minimal_set_hash(x509_minimal, br_sha256_ID, &br_sha256_vtable); + br_ssl_engine_set_x509(_eng, &x509_minimal->vtable); + + #else + x509_insecure = (br_x509_pubkeyfingerprint_context*) malloc(sizeof(br_x509_pubkeyfingerprint_context)); + //x509_insecure = std::unique_ptr(new br_x509_pubkeyfingerprint_context); + if (!x509_insecure) break; + br_x509_pubkeyfingerprint_init(x509_insecure, _fingerprint1, _fingerprint2, _recv_fingerprint, _fingerprint_any); + br_ssl_engine_set_x509(_eng, &x509_insecure->vtable); + #endif + LOG_HEAP_SIZE("_connectSSL after DecoderContext allocation"); + + // ============================================================ + // Set send/receive buffers + br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); + + // ============================================================ + // allocate Private key if needed, only if USE_MQTT_AWS_IOT + LOG_HEAP_SIZE("_connectSSL before PrivKey allocation"); + #ifdef USE_MQTT_AWS_IOT + // ============================================================ + // Set the EC Private Key, only USE_MQTT_AWS_IOT + // limited to P256 curve + br_ssl_client_set_single_ec(_sc.get(), _chain_P, 1, + _sk_ec_P, _allowed_usages, + _cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default()); + #endif // USE_MQTT_AWS_IOT + + // ============================================================ + // Start TLS connection, ALL + if (!br_ssl_client_reset(_sc.get(), hostName, 0)) break; + + auto ret = _wait_for_handshake(); + #ifdef DEBUG_ESP_SSL + if (!ret) { + DEBUG_BSSL("Couldn't connect. Error = %d\n", getLastError()); + } else { + DEBUG_BSSL("Connected! MFLNStatus = %d\n", getMFLNStatus()); + } + #endif + LOG_HEAP_SIZE("_connectSSL.end"); + _max_thunkstack_use = stack_thunk_light_get_max_usage(); + stack_thunk_light_del_ref(); + //stack_thunk_light_repaint(); + LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk"); + + #ifdef USE_MQTT_TLS_CA_CERT + free(x509_minimal); + #else + free(x509_insecure); + #endif + LOG_HEAP_SIZE("_connectSSL after release of Priv Key"); + return ret; + } while (0); + + // ============================================================ + // if we arrived here, this means we had an OOM error, cleaning up + setLastError(ERR_OOM); + DEBUG_BSSL("_connectSSL: Out of memory\n"); + stack_thunk_light_del_ref(); +#ifdef USE_MQTT_TLS_CA_CERT + free(x509_minimal); +#else + free(x509_insecure); +#endif + LOG_HEAP_SIZE("_connectSSL clean_on_error"); + return false; +} + +}; + +#include "t_bearssl_tasmota_config.h" + +#endif // USE_TLS diff --git a/tasmota/WiFiClientSecureLightBearSSL.h b/tasmota/WiFiClientSecureLightBearSSL.h old mode 100644 new mode 100755 index 5dd0df35e..e5908275e --- a/tasmota/WiFiClientSecureLightBearSSL.h +++ b/tasmota/WiFiClientSecureLightBearSSL.h @@ -1,221 +1,221 @@ -/* - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (c) 2018 Earle F. Philhower, III - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#ifndef wificlientlightbearssl_h -#define wificlientlightbearssl_h -#if defined(USE_MQTT_TLS) || defined (USE_SENDMAIL) -#include -#include "WiFiClient.h" -#include - -namespace BearSSL { - -class WiFiClientSecure_light : public WiFiClient { - public: - WiFiClientSecure_light(int recv, int xmit); - ~WiFiClientSecure_light() override; - - void allocateBuffers(void); - - int connect(IPAddress ip, uint16_t port) override; - int connect(const char* name, uint16_t port) override; - - uint8_t connected() override; - size_t write(const uint8_t *buf, size_t size) override; - size_t write_P(PGM_P buf, size_t size) override; - size_t write(const char *buf) { - return write((const uint8_t*)buf, strlen(buf)); - } - size_t write_P(const char *buf) { - return write_P((PGM_P)buf, strlen_P(buf)); - } - size_t write(Stream& stream); // Note this is not virtual - int read(uint8_t *buf, size_t size) override; - int available() override; - int read() override; - int peek() override; - size_t peekBytes(uint8_t *buffer, size_t length) override; - bool flush(unsigned int maxWaitMs); - bool stop(unsigned int maxWaitMs); - void flush() override { (void)flush(0); } - void stop() override { (void)stop(0); } - - // Only check SHA1 fingerprint of public key - void setPubKeyFingerprint(const uint8_t *f1, const uint8_t *f2, - bool f_any = false) { - _fingerprint1 = f1; - _fingerprint2 = f2; - _fingerprint_any = f_any; - } - const uint8_t * getRecvPubKeyFingerprint(void) { - return _recv_fingerprint; - } - - void setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk, - unsigned allowed_usages, unsigned cert_issuer_key_type); - - void setTrustAnchor(const br_x509_trust_anchor *ta); - - // Sets the requested buffer size for transmit and receive - void setBufferSizes(int recv, int xmit); - - // Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection) - int getMFLNStatus() { - return connected() && br_ssl_engine_get_mfln_negotiated(_eng); - } - - int32_t getLastError(void) { - if (_last_error) { - return _last_error; - } else { - return br_ssl_engine_last_error(_eng); - } - } - inline void setLastError(int32_t err) { - _last_error = err; - } - inline void clearLastError(void) { - _last_error = 0; - } - inline size_t getMaxThunkStackUse(void) { - return _max_thunkstack_use; - } - - private: - void _clear(); - bool _ctx_present; - std::shared_ptr _sc; - inline bool ctx_present() { - return _ctx_present; - } - br_ssl_engine_context *_eng; // &_sc->eng, to allow for client or server contexts - std::shared_ptr _iobuf_in; - std::shared_ptr _iobuf_out; - time_t _now; - int _iobuf_in_size; - int _iobuf_out_size; - bool _handshake_done; - uint64_t _last_error; - - bool _fingerprint_any; // accept all fingerprints - const uint8_t *_fingerprint1; // fingerprint1 to be checked against - const uint8_t *_fingerprint2; // fingerprint2 to be checked against - uint8_t _recv_fingerprint[20]; // fingerprint received - - unsigned char *_recvapp_buf; - size_t _recvapp_len; - - bool _clientConnected(); // Is the underlying socket alive? - bool _connectSSL(const char *hostName); // Do initial SSL handshake - void _freeSSL(); - int _run_until(unsigned target, bool blocking = true); - size_t _write(const uint8_t *buf, size_t size, bool pmem); - bool _wait_for_handshake(); // Sets and return the _handshake_done after connecting - - // Optional client certificate - const br_x509_certificate *_chain_P; // PROGMEM certificate - const br_ec_private_key *_sk_ec_P; // PROGMEM private key - const br_x509_trust_anchor *_ta_P; // PROGMEM server CA - unsigned _allowed_usages; - unsigned _cert_issuer_key_type; - - // record the maximum use of ThunkStack for monitoring - size_t _max_thunkstack_use; - -}; - -#define ERR_OOM -1000 -#define ERR_CANT_RESOLVE_IP -1001 -#define ERR_TCP_CONNECT -1002 -#define ERR_MISSING_EC_KEY -1003 -#define ERR_MISSING_CA -1004 - -// For reference, BearSSL error codes: -// #define BR_ERR_OK 0 -// #define BR_ERR_BAD_PARAM 1 -// #define BR_ERR_BAD_STATE 2 -// #define BR_ERR_UNSUPPORTED_VERSION 3 -// #define BR_ERR_BAD_VERSION 4 -// #define BR_ERR_BAD_LENGTH 5 -// #define BR_ERR_TOO_LARGE 6 -// #define BR_ERR_BAD_MAC 7 -// #define BR_ERR_NO_RANDOM 8 -// #define BR_ERR_UNKNOWN_TYPE 9 -// #define BR_ERR_UNEXPECTED 10 -// #define BR_ERR_BAD_CCS 12 -// #define BR_ERR_BAD_ALERT 13 -// #define BR_ERR_BAD_HANDSHAKE 14 -// #define BR_ERR_OVERSIZED_ID 15 -// #define BR_ERR_BAD_CIPHER_SUITE 16 -// #define BR_ERR_BAD_COMPRESSION 17 -// #define BR_ERR_BAD_FRAGLEN 18 -// #define BR_ERR_BAD_SECRENEG 19 -// #define BR_ERR_EXTRA_EXTENSION 20 -// #define BR_ERR_BAD_SNI 21 -// #define BR_ERR_BAD_HELLO_DONE 22 -// #define BR_ERR_LIMIT_EXCEEDED 23 -// #define BR_ERR_BAD_FINISHED 24 -// #define BR_ERR_RESUME_MISMATCH 25 -// #define BR_ERR_INVALID_ALGORITHM 26 -// #define BR_ERR_BAD_SIGNATURE 27 -// #define BR_ERR_WRONG_KEY_USAGE 28 -// #define BR_ERR_NO_CLIENT_AUTH 29 -// #define BR_ERR_IO 31 -// #define BR_ERR_RECV_FATAL_ALERT 256 -// #define BR_ERR_SEND_FATAL_ALERT 512 -// #define BR_ERR_X509_OK 32 -// #define BR_ERR_X509_INVALID_VALUE 33 -// #define BR_ERR_X509_TRUNCATED 34 -// #define BR_ERR_X509_EMPTY_CHAIN 35 -// #define BR_ERR_X509_INNER_TRUNC 36 -// #define BR_ERR_X509_BAD_TAG_CLASS 37 -// #define BR_ERR_X509_BAD_TAG_VALUE 38 -// #define BR_ERR_X509_INDEFINITE_LENGTH 39 -// #define BR_ERR_X509_EXTRA_ELEMENT 40 -// #define BR_ERR_X509_UNEXPECTED 41 -// #define BR_ERR_X509_NOT_CONSTRUCTED 42 -// #define BR_ERR_X509_NOT_PRIMITIVE 43 -// #define BR_ERR_X509_PARTIAL_BYTE 44 -// #define BR_ERR_X509_BAD_BOOLEAN 45 -// #define BR_ERR_X509_OVERFLOW 46 -// #define BR_ERR_X509_BAD_DN 47 -// #define BR_ERR_X509_BAD_TIME 48 -// #define BR_ERR_X509_UNSUPPORTED 49 -// #define BR_ERR_X509_LIMIT_EXCEEDED 50 -// #define BR_ERR_X509_WRONG_KEY_TYPE 51 -// #define BR_ERR_X509_BAD_SIGNATURE 52 -// #define BR_ERR_X509_TIME_UNKNOWN 53 -// #define BR_ERR_X509_EXPIRED 54 -// #define BR_ERR_X509_DN_MISMATCH 55 -// #define BR_ERR_X509_BAD_SERVER_NAME 56 -// #define BR_ERR_X509_CRITICAL_EXTENSION 57 -// #define BR_ERR_X509_NOT_CA 58 -// #define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59 -// #define BR_ERR_X509_WEAK_PUBLIC_KEY 60 -// #define BR_ERR_X509_NOT_TRUSTED 62 - -}; - -#endif // USE_MQTT_TLS -#endif // wificlientlightbearssl_h +/* + WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries + - Mostly compatible with Arduino WiFi shield library and standard + WiFiClient/ServerSecure (except for certificate handling). + + Copyright (c) 2018 Earle F. Philhower, III + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#ifndef wificlientlightbearssl_h +#define wificlientlightbearssl_h +#ifdef USE_TLS +#include +#include "WiFiClient.h" +#include + +namespace BearSSL { + +class WiFiClientSecure_light : public WiFiClient { + public: + WiFiClientSecure_light(int recv, int xmit); + ~WiFiClientSecure_light() override; + + void allocateBuffers(void); + + int connect(IPAddress ip, uint16_t port) override; + int connect(const char* name, uint16_t port) override; + + uint8_t connected() override; + size_t write(const uint8_t *buf, size_t size) override; + size_t write_P(PGM_P buf, size_t size) override; + size_t write(const char *buf) { + return write((const uint8_t*)buf, strlen(buf)); + } + size_t write_P(const char *buf) { + return write_P((PGM_P)buf, strlen_P(buf)); + } + size_t write(Stream& stream); // Note this is not virtual + int read(uint8_t *buf, size_t size) override; + int available() override; + int read() override; + int peek() override; + size_t peekBytes(uint8_t *buffer, size_t length) override; + bool flush(unsigned int maxWaitMs); + bool stop(unsigned int maxWaitMs); + void flush() override { (void)flush(0); } + void stop() override { (void)stop(0); } + + // Only check SHA1 fingerprint of public key + void setPubKeyFingerprint(const uint8_t *f1, const uint8_t *f2, + bool f_any = false) { + _fingerprint1 = f1; + _fingerprint2 = f2; + _fingerprint_any = f_any; + } + const uint8_t * getRecvPubKeyFingerprint(void) { + return _recv_fingerprint; + } + + void setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk, + unsigned allowed_usages, unsigned cert_issuer_key_type); + + void setTrustAnchor(const br_x509_trust_anchor *ta); + + // Sets the requested buffer size for transmit and receive + void setBufferSizes(int recv, int xmit); + + // Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection) + int getMFLNStatus() { + return connected() && br_ssl_engine_get_mfln_negotiated(_eng); + } + + int32_t getLastError(void) { + if (_last_error) { + return _last_error; + } else { + return br_ssl_engine_last_error(_eng); + } + } + inline void setLastError(int32_t err) { + _last_error = err; + } + inline void clearLastError(void) { + _last_error = 0; + } + inline size_t getMaxThunkStackUse(void) { + return _max_thunkstack_use; + } + + private: + void _clear(); + bool _ctx_present; + std::shared_ptr _sc; + inline bool ctx_present() { + return _ctx_present; + } + br_ssl_engine_context *_eng; // &_sc->eng, to allow for client or server contexts + std::shared_ptr _iobuf_in; + std::shared_ptr _iobuf_out; + time_t _now; + int _iobuf_in_size; + int _iobuf_out_size; + bool _handshake_done; + uint64_t _last_error; + + bool _fingerprint_any; // accept all fingerprints + const uint8_t *_fingerprint1; // fingerprint1 to be checked against + const uint8_t *_fingerprint2; // fingerprint2 to be checked against + uint8_t _recv_fingerprint[20]; // fingerprint received + + unsigned char *_recvapp_buf; + size_t _recvapp_len; + + bool _clientConnected(); // Is the underlying socket alive? + bool _connectSSL(const char *hostName); // Do initial SSL handshake + void _freeSSL(); + int _run_until(unsigned target, bool blocking = true); + size_t _write(const uint8_t *buf, size_t size, bool pmem); + bool _wait_for_handshake(); // Sets and return the _handshake_done after connecting + + // Optional client certificate + const br_x509_certificate *_chain_P; // PROGMEM certificate + const br_ec_private_key *_sk_ec_P; // PROGMEM private key + const br_x509_trust_anchor *_ta_P; // PROGMEM server CA + unsigned _allowed_usages; + unsigned _cert_issuer_key_type; + + // record the maximum use of ThunkStack for monitoring + size_t _max_thunkstack_use; + +}; + +#define ERR_OOM -1000 +#define ERR_CANT_RESOLVE_IP -1001 +#define ERR_TCP_CONNECT -1002 +// #define ERR_MISSING_EC_KEY -1003 // deprecated, AWS IoT is not called if the private key is not present +#define ERR_MISSING_CA -1004 + +// For reference, BearSSL error codes: +// #define BR_ERR_OK 0 +// #define BR_ERR_BAD_PARAM 1 +// #define BR_ERR_BAD_STATE 2 +// #define BR_ERR_UNSUPPORTED_VERSION 3 +// #define BR_ERR_BAD_VERSION 4 +// #define BR_ERR_BAD_LENGTH 5 +// #define BR_ERR_TOO_LARGE 6 +// #define BR_ERR_BAD_MAC 7 +// #define BR_ERR_NO_RANDOM 8 +// #define BR_ERR_UNKNOWN_TYPE 9 +// #define BR_ERR_UNEXPECTED 10 +// #define BR_ERR_BAD_CCS 12 +// #define BR_ERR_BAD_ALERT 13 +// #define BR_ERR_BAD_HANDSHAKE 14 +// #define BR_ERR_OVERSIZED_ID 15 +// #define BR_ERR_BAD_CIPHER_SUITE 16 +// #define BR_ERR_BAD_COMPRESSION 17 +// #define BR_ERR_BAD_FRAGLEN 18 +// #define BR_ERR_BAD_SECRENEG 19 +// #define BR_ERR_EXTRA_EXTENSION 20 +// #define BR_ERR_BAD_SNI 21 +// #define BR_ERR_BAD_HELLO_DONE 22 +// #define BR_ERR_LIMIT_EXCEEDED 23 +// #define BR_ERR_BAD_FINISHED 24 +// #define BR_ERR_RESUME_MISMATCH 25 +// #define BR_ERR_INVALID_ALGORITHM 26 +// #define BR_ERR_BAD_SIGNATURE 27 +// #define BR_ERR_WRONG_KEY_USAGE 28 +// #define BR_ERR_NO_CLIENT_AUTH 29 +// #define BR_ERR_IO 31 +// #define BR_ERR_RECV_FATAL_ALERT 256 +// #define BR_ERR_SEND_FATAL_ALERT 512 +// #define BR_ERR_X509_OK 32 +// #define BR_ERR_X509_INVALID_VALUE 33 +// #define BR_ERR_X509_TRUNCATED 34 +// #define BR_ERR_X509_EMPTY_CHAIN 35 +// #define BR_ERR_X509_INNER_TRUNC 36 +// #define BR_ERR_X509_BAD_TAG_CLASS 37 +// #define BR_ERR_X509_BAD_TAG_VALUE 38 +// #define BR_ERR_X509_INDEFINITE_LENGTH 39 +// #define BR_ERR_X509_EXTRA_ELEMENT 40 +// #define BR_ERR_X509_UNEXPECTED 41 +// #define BR_ERR_X509_NOT_CONSTRUCTED 42 +// #define BR_ERR_X509_NOT_PRIMITIVE 43 +// #define BR_ERR_X509_PARTIAL_BYTE 44 +// #define BR_ERR_X509_BAD_BOOLEAN 45 +// #define BR_ERR_X509_OVERFLOW 46 +// #define BR_ERR_X509_BAD_DN 47 +// #define BR_ERR_X509_BAD_TIME 48 +// #define BR_ERR_X509_UNSUPPORTED 49 +// #define BR_ERR_X509_LIMIT_EXCEEDED 50 +// #define BR_ERR_X509_WRONG_KEY_TYPE 51 +// #define BR_ERR_X509_BAD_SIGNATURE 52 +// #define BR_ERR_X509_TIME_UNKNOWN 53 +// #define BR_ERR_X509_EXPIRED 54 +// #define BR_ERR_X509_DN_MISMATCH 55 +// #define BR_ERR_X509_BAD_SERVER_NAME 56 +// #define BR_ERR_X509_CRITICAL_EXTENSION 57 +// #define BR_ERR_X509_NOT_CA 58 +// #define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59 +// #define BR_ERR_X509_WEAK_PUBLIC_KEY 60 +// #define BR_ERR_X509_NOT_TRUSTED 62 + +}; + +#endif // USE_TLS +#endif // wificlientlightbearssl_h diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 6e20a598e..4a75b4b98 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -753,4 +753,16 @@ #error "Select either USE_RULES or USE_SCRIPT. They can't both be used at the same time" #endif +/*********************************************************************************************\ + * Post-process compile options for TLS +\*********************************************************************************************/ + +#if defined(USE_MQTT_TLS) || defined(USE_SENDMAIL) || defined(USE_TELEGRAM) + #define USE_TLS // flag indicates we need to include TLS code + + #if defined(USE_MQTT_AWS_IOT) || defined(USE_TELEGRAM) + #define USE_MQTT_TLS_FORCE_EC_CIPHER // AWS IoT and TELEGRAM require EC Cipher + #endif +#endif + #endif // _MY_USER_CONFIG_H_ diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index ecf1127ec..78c50edc3 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -36,9 +36,9 @@ #include "tasmota_version.h" // Tasmota version information #include "tasmota.h" // Enumeration used in my_user_config.h #include "my_user_config.h" // Fixed user configurable options -#ifdef USE_MQTT_TLS +#ifdef USE_TLS #include // We need to include before "tasmota_globals.h" to take precedence over the BearSSL version in Arduino -#endif // USE_MQTT_TLS +#endif // USE_TLS #include "tasmota_globals.h" // Function prototypes and global configuration #include "i18n.h" // Language support configured by my_user_config.h #include "tasmota_template.h" // Hardware configuration diff --git a/tasmota/tasmota_ca.ino b/tasmota/tasmota_ca.ino index 8e75f891e..1db0a8c63 100644 --- a/tasmota/tasmota_ca.ino +++ b/tasmota/tasmota_ca.ino @@ -21,9 +21,8 @@ // Please use fingerprint validation instead // However, the CA are available below for future use if it appears to be useful -#ifdef USE_MQTT_TLS_CA_CERT +#if defined(USE_TLS) && defined(USE_MQTT_TLS_CA_CERT) -#ifndef USE_MQTT_AWS_IOT /*********************************************************************************************\ * LetsEncrypt IdenTrust DST Root CA X3 certificate, RSA 2048 bits SHA 256, valid until 20210417 * @@ -35,7 +34,7 @@ * remove "static" and add "PROGMEM" \*********************************************************************************************/ -static const unsigned char PROGMEM TA0_DN[] = { +static const unsigned char PROGMEM LetsEncrypt_DN[] = { 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x4C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6E, 0x63, 0x72, @@ -45,7 +44,7 @@ static const unsigned char PROGMEM TA0_DN[] = { 0x79, 0x20, 0x58, 0x33 }; -static const unsigned char PROGMEM TA0_RSA_N[] = { +static const unsigned char PROGMEM LetsEncrypt_RSA_N[] = { 0x9C, 0xD3, 0x0C, 0xF0, 0x5A, 0xE5, 0x2E, 0x47, 0xB7, 0x72, 0x5D, 0x37, 0x83, 0xB3, 0x68, 0x63, 0x30, 0xEA, 0xD7, 0x35, 0x26, 0x19, 0x25, 0xE1, 0xBD, 0xBE, 0x35, 0xF1, 0x70, 0x92, 0x2F, 0xB7, 0xB8, 0x4B, 0x41, 0x05, @@ -70,27 +69,22 @@ static const unsigned char PROGMEM TA0_RSA_N[] = { 0xD8, 0x7D, 0xC3, 0x93 }; -static const unsigned char TA0_RSA_E[] = { +static const unsigned char LetsEncrypt_RSA_E[] = { 0x01, 0x00, 0x01 }; static const br_x509_trust_anchor PROGMEM LetsEncryptX3CrossSigned_TA = { - { (unsigned char *)TA0_DN, sizeof TA0_DN }, + { (unsigned char *)LetsEncrypt_DN, sizeof LetsEncrypt_DN }, BR_X509_TA_CA, { BR_KEYTYPE_RSA, { .rsa = { - (unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N, - (unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E, + (unsigned char *)LetsEncrypt_RSA_N, sizeof LetsEncrypt_RSA_N, + (unsigned char *)LetsEncrypt_RSA_E, sizeof LetsEncrypt_RSA_E, } } } }; -#define TAs_NUM 1 - -#endif // not USE_MQTT_AWS_IOT - -#ifdef USE_MQTT_AWS_IOT /*********************************************************************************************\ * Amazon Root CA, RSA 2048 bits SHA 256, valid until 20380117 * @@ -103,7 +97,7 @@ static const br_x509_trust_anchor PROGMEM LetsEncryptX3CrossSigned_TA = { \*********************************************************************************************/ -const unsigned char PROGMEM TA0_DN[] = { +const unsigned char PROGMEM AmazonRootCA1_DN[] = { 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, @@ -111,7 +105,7 @@ const unsigned char PROGMEM TA0_DN[] = { 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 }; -const unsigned char PROGMEM TA0_RSA_N[] = { +const unsigned char PROGMEM AmazonRootCA1_RSA_N[] = { 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, @@ -136,24 +130,79 @@ const unsigned char PROGMEM TA0_RSA_N[] = { 0x9A, 0xC8, 0xAA, 0x0D }; -static const unsigned char PROGMEM TA0_RSA_E[] = { +static const unsigned char PROGMEM AmazonRootCA1_RSA_E[] = { 0x01, 0x00, 0x01 }; const br_x509_trust_anchor PROGMEM AmazonRootCA1_TA = { - { (unsigned char *)TA0_DN, sizeof TA0_DN }, + { (unsigned char *)AmazonRootCA1_DN, sizeof AmazonRootCA1_DN }, BR_X509_TA_CA, { BR_KEYTYPE_RSA, { .rsa = { - (unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N, - (unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E, + (unsigned char *)AmazonRootCA1_RSA_N, sizeof AmazonRootCA1_RSA_N, + (unsigned char *)AmazonRootCA1_RSA_E, sizeof AmazonRootCA1_RSA_E, } } } }; -#define TAs_NUM 1 +// we add a separate CA for telegram +/*********************************************************************************************\ + * GoDaddy Daddy Secure Certificate Authority - G2, RSA 2048 bits SHA 256, valid until 20220523 + * + * to convert do: "brssl ta GoDaddyCA.pem" + * then copy and paste below, chain the generic names to the same as below + * remove "static" and add "PROGMEM" +\*********************************************************************************************/ -#endif // USE_MQTT_AWS_IOT +const unsigned char GoDaddyCAG2_DN[] PROGMEM = { + 0x30, 0x3E, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x18, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x43, 0x6F, 0x6E, 0x74, + 0x72, 0x6F, 0x6C, 0x20, 0x56, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x61, 0x70, 0x69, 0x2E, 0x74, 0x65, 0x6C, 0x65, 0x67, 0x72, 0x61, 0x6D, + 0x2E, 0x6F, 0x72, 0x67 +}; -#endif // USE_MQTT_TLS_CA_CERT +const unsigned char GoDaddyCAG2_RSA_N[] PROGMEM = { + 0xB4, 0xA3, 0x16, 0x9E, 0x5C, 0x57, 0xC9, 0x89, 0x65, 0xED, 0xEA, 0x78, + 0x0B, 0xAE, 0x8A, 0x58, 0x2F, 0xAE, 0x5A, 0xC8, 0x6E, 0x49, 0x8D, 0xFC, + 0x57, 0xA5, 0x98, 0x88, 0x78, 0x2E, 0x0B, 0x3C, 0x40, 0x3C, 0x21, 0x2E, + 0x9A, 0x94, 0x98, 0x33, 0xA7, 0xE3, 0x42, 0xA7, 0x85, 0xFA, 0xD0, 0x73, + 0x84, 0x01, 0x1C, 0x72, 0x39, 0x37, 0x23, 0xB5, 0x56, 0x1D, 0x43, 0xA5, + 0x71, 0x14, 0x08, 0x24, 0xA5, 0x39, 0xCC, 0xDE, 0x58, 0x53, 0x94, 0x8E, + 0x2A, 0x42, 0xA7, 0x4E, 0x2D, 0x07, 0x32, 0x9E, 0xBA, 0x8B, 0xD3, 0x2A, + 0xA9, 0x9E, 0xC0, 0xE3, 0xCE, 0x9A, 0x10, 0x96, 0x45, 0x58, 0x7A, 0xC7, + 0x1E, 0x45, 0x14, 0x23, 0x92, 0xBB, 0x54, 0x82, 0x88, 0x94, 0x49, 0xB6, + 0xBE, 0x81, 0x21, 0x00, 0x29, 0x6D, 0xC9, 0xCE, 0x8B, 0x39, 0x3A, 0xDC, + 0x35, 0x15, 0xD9, 0xEB, 0x47, 0x9C, 0xEF, 0xBA, 0x09, 0x0E, 0x16, 0xE4, + 0xD9, 0xEB, 0x72, 0x30, 0xFA, 0x49, 0xAB, 0x98, 0x31, 0x7C, 0xB3, 0xAC, + 0x2B, 0x29, 0x91, 0x87, 0x08, 0x41, 0x72, 0x5E, 0x35, 0xC7, 0x87, 0x04, + 0x22, 0xF5, 0x48, 0x76, 0x30, 0x6D, 0x88, 0xDF, 0xF2, 0xA5, 0x29, 0x13, + 0x70, 0xB3, 0x87, 0x02, 0xD5, 0x6B, 0x58, 0xB1, 0xE8, 0x73, 0xC7, 0xE4, + 0xEF, 0x79, 0x86, 0xA4, 0x07, 0x5F, 0x67, 0xB4, 0x79, 0x8D, 0xA4, 0x25, + 0x01, 0x82, 0x8C, 0xE0, 0x30, 0x17, 0xCB, 0x4B, 0x5C, 0xFB, 0xEB, 0x4C, + 0x12, 0x51, 0xB9, 0xC9, 0x04, 0x1F, 0x7E, 0xD2, 0xF8, 0xBA, 0xF5, 0x35, + 0x8D, 0x8A, 0x1C, 0x37, 0x82, 0xF0, 0x15, 0x73, 0x00, 0x6E, 0x3D, 0x1C, + 0x76, 0x8B, 0x01, 0x74, 0x81, 0x3D, 0xE4, 0x2C, 0xA7, 0xCC, 0x2F, 0x66, + 0xDC, 0x44, 0xA8, 0x27, 0x3F, 0xEA, 0xD0, 0xA7, 0xA8, 0xF1, 0xCB, 0xEA, + 0xDA, 0x07, 0x38, 0xBD +}; + +const unsigned char GoDaddyCAG2_RSA_E[] PROGMEM = { + 0x01, 0x00, 0x01 +}; + +const br_x509_trust_anchor GoDaddyCAG2_TA PROGMEM = { + { (unsigned char *)GoDaddyCAG2_DN, sizeof GoDaddyCAG2_DN }, + 0, + { + BR_KEYTYPE_RSA, + { .rsa = { + (unsigned char *)GoDaddyCAG2_RSA_N, sizeof GoDaddyCAG2_RSA_N, + (unsigned char *)GoDaddyCAG2_RSA_E, sizeof GoDaddyCAG2_RSA_E, + } } + } +}; + +#endif // defined(USE_TLS) && defined(USE_MQTT_TLS_CA_CERT) diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 44826fa64..f33024c45 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -88,7 +88,7 @@ extern "C" void resetPins(); const uint16_t WEB_LOG_SIZE = 4000; // Max number of characters in weblog #endif -#if defined(USE_MQTT_TLS) && defined(ARDUINO_ESP8266_RELEASE_2_3_0) +#if defined(USE_TLS) && defined(ARDUINO_ESP8266_RELEASE_2_3_0) #error "TLS is no more supported on Core 2.3.0, use 2.4.2 or higher." #endif From dc8d354f161c74fefbcbf4a22b78364d4b25a720 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 10 Jun 2020 21:14:18 +0200 Subject: [PATCH 193/581] Fix asm for gcc17 --- tasmota/StackThunk_light.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/StackThunk_light.h b/tasmota/StackThunk_light.h index 13a0cb7d3..164417000 100644 --- a/tasmota/StackThunk_light.h +++ b/tasmota/StackThunk_light.h @@ -52,7 +52,7 @@ extern uint32_t stack_thunk_light_refcnt; // Thunking macro #define make_stack_thunk_light(fcnToThunk) \ -__asm("\n\ +__asm__("\n\ .text\n\ .literal_position\n\ .literal .LC_STACK_VALUE"#fcnToThunk", 0xdeadbeef\n\ From 8cbb35ec4fbb00e29e754c0602c75af1a2c70fce Mon Sep 17 00:00:00 2001 From: Robert Jaakke Date: Wed, 10 Jun 2020 21:54:32 +0200 Subject: [PATCH 194/581] Removed m_initFail check because we moved it to begin() --- lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp index b73e12b83..c6f8aeb1d 100644 --- a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp @@ -147,11 +147,6 @@ uint8_t LOLIN_HP303B::getRevisionId(void) */ int16_t LOLIN_HP303B::standby(void) { - //abort if initialization failed - if(m_initFail) - { - return HP303B__FAIL_INIT_FAILED; - } //set device to idling mode int16_t ret = setOpMode(IDLE); if(ret != HP303B__SUCCEEDED) @@ -270,11 +265,6 @@ int16_t LOLIN_HP303B::startMeasureTempOnce(void) */ int16_t LOLIN_HP303B::startMeasureTempOnce(uint8_t oversamplingRate) { - //abort if initialization failed - if(m_initFail) - { - return HP303B__FAIL_INIT_FAILED; - } //abort if device is not in idling mode if(m_opMode!=IDLE) { @@ -394,11 +384,6 @@ int16_t LOLIN_HP303B::startMeasurePressureOnce(void) */ int16_t LOLIN_HP303B::startMeasurePressureOnce(uint8_t oversamplingRate) { - //abort if initialization failed - if(m_initFail) - { - return HP303B__FAIL_INIT_FAILED; - } //abort if device is not in idling mode if(m_opMode != IDLE) { @@ -428,12 +413,6 @@ int16_t LOLIN_HP303B::startMeasurePressureOnce(uint8_t oversamplingRate) */ int16_t LOLIN_HP303B::getSingleResult(float &result) { - //abort if initialization failed - if(m_initFail) - { - return HP303B__FAIL_INIT_FAILED; - } - //read finished bit for current opMode int16_t rdy; switch(m_opMode) From 440219fd91afef1b763a02efc80cadd9663d369d Mon Sep 17 00:00:00 2001 From: Phil Dubach Date: Wed, 10 Jun 2020 19:55:49 -0700 Subject: [PATCH 195/581] Fix thermostat when using local sensor Macros are not expanded in string constants, so the thermostat driver never managed to obtain the current temperature from the local sensor (SensorInputSet 1). --- tasmota/xdrv_39_thermostat.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_39_thermostat.ino b/tasmota/xdrv_39_thermostat.ino index 79e842dc5..768088117 100644 --- a/tasmota/xdrv_39_thermostat.ino +++ b/tasmota/xdrv_39_thermostat.ino @@ -1331,7 +1331,7 @@ void ThermostatGetLocalSensor(uint8_t ctr_output) { DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject((const char*)mqtt_data); if (root.success()) { - const char* value_c = root["THERMOSTAT_SENSOR_NAME"]["Temperature"]; + const char* value_c = root[THERMOSTAT_SENSOR_NAME]["Temperature"]; if (value_c != NULL && strlen(value_c) > 0 && (isdigit(value_c[0]) || (value_c[0] == '-' && isdigit(value_c[1])) ) ) { int16_t value = (int16_t)(CharToFloat(value_c) * 10); if ( (value >= -1000) From 2453beb30f7e6b1792b2ac073deb84fd7b16b9af Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Thu, 11 Jun 2020 06:43:24 +0200 Subject: [PATCH 196/581] scripter fix sdcard regression --- tasmota/xdrv_10_scripter.ino | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 5a79d50b5..4d0bc1588 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -3979,8 +3979,7 @@ void ListDir(char *path, uint8_t depth) { char path[48]; -void Script_FileUploadConfiguration(void) -{ +void Script_FileUploadConfiguration(void) { uint8_t depth=0; strcpy(path,"/"); @@ -3995,17 +3994,6 @@ void Script_FileUploadConfiguration(void) } } - void ScriptFileUploadSuccess(void) { - WSContentStart_P(S_INFORMATION); - WSContentSendStyle(); - WSContentSend_P(PSTR("
" D_UPLOAD " " D_SUCCESSFUL "
"), WebColor(COL_TEXT_SUCCESS)); - WSContentSend_P(PSTR("

")); - WSContentSend_P(PSTR("

"),"/upl",D_UPL_DONE); - //WSContentSpaceButton(BUTTON_MAIN); - WSContentStop(); - } - WSContentStart_P(S_SCRIPT_FILE_UPLOAD); WSContentSendStyle(); WSContentSend_P(HTTP_FORM_FILE_UPLOAD,D_SDCARD_DIR); @@ -4023,13 +4011,22 @@ void Script_FileUploadConfiguration(void) Web.upload_error = 0; } +void ScriptFileUploadSuccess(void) { + WSContentStart_P(S_INFORMATION); + WSContentSendStyle(); + WSContentSend_P(PSTR("
" D_UPLOAD " " D_SUCCESSFUL "
"), WebColor(COL_TEXT_SUCCESS)); + WSContentSend_P(PSTR("

")); + WSContentSend_P(PSTR("

"),"/upl",D_UPL_DONE); + //WSContentSpaceButton(BUTTON_MAIN); + WSContentStop(); +} + + File upload_file; - void script_upload(void) { - //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload")); - HTTPUpload& upload = Webserver->upload(); if (upload.status == UPLOAD_FILE_START) { char npath[48]; From ce4f987367461dd1cdc16627bbd039050b6f0ad4 Mon Sep 17 00:00:00 2001 From: Staars Date: Thu, 11 Jun 2020 09:55:07 +0200 Subject: [PATCH 197/581] bugfix --- tasmota/xsns_48_chirp.ino | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tasmota/xsns_48_chirp.ino b/tasmota/xsns_48_chirp.ino index 9606b419c..934dff205 100644 --- a/tasmota/xsns_48_chirp.ino +++ b/tasmota/xsns_48_chirp.ino @@ -20,6 +20,8 @@ Version Date Action Description -------------------------------------------------------------------------------------------- + 1.0.0.2 20200611 changed - bugfix: decouple restart of the work loop from FUNC_JSON_APPEND callback + --- 1.0.0.1 20190917 changed - rework of the inner loop to enable delays in the middle of I2C-reads changed - double send address change only for fw>0x25 changed - use DEBUG_SENSOR_LOG, change ILLUMINANCE to DARKNESS @@ -300,7 +302,7 @@ void ChirpServiceAllSensors(uint8_t job){ void ChirpEvery100MSecond(void) { - // DEBUG_SENSOR_LOG(PSTR("CHIRP: every second")); + // DEBUG_SENSOR_LOG(PSTR("CHIRP: every 100 mseconds, counter: %u, next job: %u"),chirp_timeout_count,chirp_next_job); if(chirp_timeout_count == 0) { //countdown complete, now do something switch(chirp_next_job) { case 0: //this should only be called after driver initialization @@ -377,10 +379,11 @@ void ChirpEvery100MSecond(void) break; case 13: DEBUG_SENSOR_LOG(PSTR("CHIRP: paused, waiting for TELE")); + chirp_next_job++; break; case 14: if (Settings.tele_period > 16){ - chirp_timeout_count = (Settings.tele_period - 17) * 10; // sync it with the TELEPERIOD, we need about up to 17 seconds to measure + chirp_timeout_count = (Settings.tele_period - 16) * 10; // sync it with the TELEPERIOD, we need about up to 16 seconds to measure DEBUG_SENSOR_LOG(PSTR("CHIRP: timeout 1/10 sec: %u, tele: %u"), chirp_timeout_count, Settings.tele_period); } else{ @@ -533,7 +536,6 @@ bool Xsns48(uint8_t function) break; case FUNC_JSON_APPEND: ChirpShow(1); - chirp_next_job = 14; // TELE done, now compute time for next measure cycle break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: From e05e9ea7139d753e0d7bfb884cb7ddbe17b30fe7 Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 11 Jun 2020 14:52:31 +0200 Subject: [PATCH 198/581] Creation --- lib/LibTeleinfo/README.md | 65 +++ lib/LibTeleinfo/library.json | 19 + lib/LibTeleinfo/library.properties | 9 + lib/LibTeleinfo/src/LibTeleinfo.cpp | 842 ++++++++++++++++++++++++++++ lib/LibTeleinfo/src/LibTeleinfo.h | 138 +++++ 5 files changed, 1073 insertions(+) create mode 100755 lib/LibTeleinfo/README.md create mode 100755 lib/LibTeleinfo/library.json create mode 100755 lib/LibTeleinfo/library.properties create mode 100644 lib/LibTeleinfo/src/LibTeleinfo.cpp create mode 100755 lib/LibTeleinfo/src/LibTeleinfo.h diff --git a/lib/LibTeleinfo/README.md b/lib/LibTeleinfo/README.md new file mode 100755 index 000000000..11a90ac2b --- /dev/null +++ b/lib/LibTeleinfo/README.md @@ -0,0 +1,65 @@ +Teleinfo (Aka TIC) Universal Library +==================================== + +This is a generic Teleinfo French Meter Measure Library, it can be used on Arduino like device and also such as Spark Core, Particle, ESP8266, Raspberry PI or anywhere you can do Cpp code ... + +You can see Teleinformation official french datasheet [there][1] + +Since this is really dedicated to French energy measuring system, I will continue in French + +Installation +============ + +Copier le contenu de ce dossier (download zip) dans le dossier libraries de votre environnement Arduino Vous devriez avoir maintenant quelque chose comme `your_sketchbook_folder/libraries/LibTeleinfo` et ce dossier doit contentir les fichiers .cpp et .h ainsi que le sous dossier `examples`. +
+Pour trouver votre dossier de sketchbook, dans l'environnement IDE, allez dans File>Preferences. +
+allez voir ce [tutorial][2] sur les librairies Arduino si beoin. +
+ +Documentation +============= + +J'ai écrit un article [dédié][10] sur cette librairie, vous pouvez aussi voir les [catégories][6] associées à la téléinfo sur mon [blog][7]. +Pour les commentaires et le support vous pouvez allez sur le [forum][8] dédié ou dans la [communauté][9] + +Sketch d'exemples +================= + +- [Arduino_Softserial_Etiquette][3] Affiche des informations de téléinformation reçue étiquette par étiquette +- [Arduino_Softserial_Blink][11] Affiche des informations de téléinformation reçue trame par trame avec clignotement LED court/long si les données ont été modifiés +- [Arduino_Softserial_JSON][4] Retourne les informations de téléinformation au format JSON sur la liaison série. +- [Raspberry_JSON][12] Retourne les informations de téléinformation au format JSON sur stdout. +- [Wifinfo][5] ESP8266, ESP32 Wifi Teleinformation, Web + Rest + bonus, version en cours de développement, à venir mais un article [dédié][13] est déjà présent sur mon blog +- [ESP32][14] ESP32 Basic test pour WifInfo32 nouveau nom Denky :-) + +Pourquoi +======== +- J'utilise la téléinfo dans plusieurs de mes programmes et j'en avais marre de devoir faire des copier/coller de code constament, j'ai donc décidé de faire une librairie commune que j'utilise sans me poser de question + +License +======= +Cette oeuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International. + +Si vous êtes une entreprise et que vous souhaitez participer car vous utilisez cette librairie dans du hardware (box, automate, ...), vous pouvez toujours m'envoyer un exemplaire de votre fabrication, c'est toujours sympa de voir ce qui est fait avec ce code ;-) + +Divers +====== +Vous pouvez aller voir les nouveautés et autres projets sur [blog][7] + +[1]: http://www.erdf.fr/sites/default/files/ERDF-NOI-CPT_02E.pdf +[2]: http://learn.adafruit.com/arduino-tips-tricks-and-techniques/arduino-libraries +[6]: https://hallard.me/category/tinfo/ +[7]: https://hallard.me +[8]: https://community.hallard.me/category/7 +[9]: https://community.hallard.me +[10]: https://hallard.me/libteleinfo + +[3]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Arduino_Softserial/Arduino_Softserial_Etiquette.ino +[4]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Arduino_Softserial_JSON/Arduino_Softserial_JSON.ino +[5]: https://github.com/hallard/LibTeleinfo/tree/master/examples/Wifinfo/Wifinfo.ino +[11]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Arduino_Softserial/Arduino_Softserial_Blink.ino +[12]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Raspberry_JSON/Raspberry_JSON.ino +[13]: https://hallard.me/wifiinfo/ +[14]: https://github.com/hallard/LibTeleinfo/blob/master/examples/ESP32/ESP32.ino + diff --git a/lib/LibTeleinfo/library.json b/lib/LibTeleinfo/library.json new file mode 100755 index 000000000..068618ce0 --- /dev/null +++ b/lib/LibTeleinfo/library.json @@ -0,0 +1,19 @@ +{ + "name": "LibTeleinfo", + "version": "1.1.0", + "keywords": "teleinfo, french, meter, power, erdf, linky, tic", + "description": "Decoder for Teleinfo (aka TIC) from French smart power meters", + "repository": + { + "type": "git", + "url": "https://github.com/hallard/LibTeleinfo.git" + }, + "authors": + { + "name": "Charles-Henri Hallard", + "url": "http://hallard.me" + }, + "frameworks": "arduino", + "platforms": "*" +} + diff --git a/lib/LibTeleinfo/library.properties b/lib/LibTeleinfo/library.properties new file mode 100755 index 000000000..2420c5fc2 --- /dev/null +++ b/lib/LibTeleinfo/library.properties @@ -0,0 +1,9 @@ +name=LibTeleinfo +version=1.1.0 +author=Charles-Henri Hallard +maintainer=Charles-Henri Hallard +sentence=Decoder for Teleinfo (aka TIC) from French smart power meters +paragraph=This is a generic Teleinfo (aka TIC) French Meter Measure Library, it can be used on Arduino, Particle, ESP8266, Raspberry PI or anywhere you can do Cpp coding. +category=Communication +url=https://github.com/hallard/LibTeleinfo +architectures=* \ No newline at end of file diff --git a/lib/LibTeleinfo/src/LibTeleinfo.cpp b/lib/LibTeleinfo/src/LibTeleinfo.cpp new file mode 100644 index 000000000..b2d597f28 --- /dev/null +++ b/lib/LibTeleinfo/src/LibTeleinfo.cpp @@ -0,0 +1,842 @@ +// ********************************************************************************** +// Driver definition for French Teleinfo +// ********************************************************************************** +// Creative Commons Attrib Share-Alike License +// You are free to use/extend this library but please abide with the CC-BY-SA license: +// http://creativecommons.org/licenses/by-sa/4.0/ +// +// For any explanation about teleinfo ou use , see my blog +// http://hallard.me/category/tinfo +// +// Code based on following datasheet +// http://www.erdf.fr/sites/default/files/ERDF-NOI-CPT_02E.pdf +// +// Written by Charles-Henri Hallard (http://hallard.me) +// +// History : V1.00 2015-06-14 - First release +// V2.00 2020-06-11 - Integration into Tasmota +// +// All text above must be included in any redistribution. +// +// Edit : Tab size set to 2 but I converted tab to sapces +// +// ********************************************************************************** + +#include "LibTeleinfo.h" + +/* ====================================================================== +Class : TInfo +Purpose : Constructor +Input : - +Output : - +Comments: - +====================================================================== */ +TInfo::TInfo() +{ + // Init of our linked list + _valueslist.name = NULL; + _valueslist.value = NULL; + _valueslist.checksum = '\0'; + _valueslist.flags = TINFO_FLAGS_NONE; + + // callback + _fn_ADPS = NULL; + _fn_data = NULL; + _fn_new_frame = NULL; + _fn_updated_frame = NULL; +} + +/* ====================================================================== +Function: init +Purpose : try to guess +Input : - +Output : - +Comments: - +====================================================================== */ +void TInfo::init() +{ + // free up linked list (in case on recall init()) + listDelete(); + + // clear our receive buffer + clearBuffer(); + + // We're in INIT in term of receive data + _state = TINFO_INIT; +} + +/* ====================================================================== +Function: attachADPS +Purpose : attach a callback when we detected a ADPS on any phase +Input : callback function +Output : - +Comments: - +====================================================================== */ +void TInfo::attachADPS(void (*fn_ADPS)(uint8_t phase)) +{ + // indicate the user callback + _fn_ADPS = fn_ADPS; +} + +/* ====================================================================== +Function: attachNewData +Purpose : attach a callback when we detected a new/changed value +Input : callback function +Output : - +Comments: - +====================================================================== */ +void TInfo::attachData(void (*fn_data)(ValueList * valueslist, uint8_t state)) +{ + // indicate the user callback + _fn_data = fn_data; +} + +/* ====================================================================== +Function: attachNewFrame +Purpose : attach a callback when we received a full frame +Input : callback function +Output : - +Comments: - +====================================================================== */ +void TInfo::attachNewFrame(void (*fn_new_frame)(ValueList * valueslist)) +{ + // indicate the user callback + _fn_new_frame = fn_new_frame; +} + +/* ====================================================================== +Function: attachChangedFrame +Purpose : attach a callback when we received a full frame where data + has changed since the last frame (cool to update data) +Input : callback function +Output : - +Comments: - +====================================================================== */ +void TInfo::attachUpdatedFrame(void (*fn_updated_frame)(ValueList * valueslist)) +{ + // indicate the user callback + _fn_updated_frame = fn_updated_frame; +} + +/* ====================================================================== +Function: clearBuffer +Purpose : clear and init the buffer +Input : - +Output : - +Comments: - +====================================================================== */ +void TInfo::clearBuffer() +{ + // Clear our buffer, set index to 0 + memset(_recv_buff, 0, TINFO_BUFSIZE); + _recv_idx = 0; +} + + +/* ====================================================================== +Function: addCustomValue +Purpose : let user add custom values (mainly for testing) +Input : Pointer to the label name + pointer to the value + pointer on flag state of the label +Output : pointer to the new node (or founded one) +Comments: checksum is calculated before adding, no need to bother with +====================================================================== */ +ValueList * TInfo::addCustomValue(char * name, char * value, uint8_t * flags) +{ + // Little check + if (name && *name && value && *value) { + ValueList * me; + + // Same as if we really received this line + customLabel(name, value, flags); + me = valueAdd(name, value, calcChecksum(name,value), flags); + + if ( me ) { + // something to do with new datas + if (*flags & (TINFO_FLAGS_UPDATED | TINFO_FLAGS_ADDED | TINFO_FLAGS_ALERT) ) { + // this frame will for sure be updated + _frame_updated = true; + } + return (me); + } + } + + // Error or Already Exists + return ( (ValueList *) NULL); +} + +/* ====================================================================== +Function: valueAdd +Purpose : Add element to the Linked List of values +Input : Pointer to the label name + pointer to the value + checksum value + flag state of the label (modified by function) +Output : pointer to the new node (or founded one) +Comments: - state of the label changed by the function +====================================================================== */ +ValueList * TInfo::valueAdd(char * name, char * value, uint8_t checksum, uint8_t * flags) +{ + // Get our linked list + ValueList * me = &_valueslist; + + uint8_t lgname = strlen(name); + uint8_t lgvalue = strlen(value); + uint8_t thischeck = calcChecksum(name,value); + + // just some paranoia + if (thischeck != checksum ) { + TI_Debug(name); + TI_Debug('='); + TI_Debug(value); + TI_Debug(F(" '")); + TI_Debug((char) checksum); + TI_Debug(F("' Not added bad checksum calculated '")); + TI_Debug((char) thischeck); + TI_Debugln(F("'")); + } else { + // Got one and all seems good ? + if (me && lgname && lgvalue && checksum) { + // Create pointer on the new node + ValueList *newNode = NULL; + ValueList *parNode = NULL ; + + // Loop thru the node + while (me->next) { + // save parent node + parNode = me ; + + // go to next node + me = me->next; + + // Check if we already have this LABEL (same name AND same size) + if (lgname==strlen(me->name) && strncmp(me->name, name, lgname)==0) { + // Already got also this value return US + if (lgvalue==strlen(me->value) && strncmp(me->value, value, lgvalue) == 0) { + *flags |= TINFO_FLAGS_EXIST; + me->flags = *flags; + return ( me ); + } else { + // We changed the value + *flags |= TINFO_FLAGS_UPDATED; + me->flags = *flags ; + // Do we have enought space to hold new value ? + if (strlen(me->value) >= lgvalue ) { + // Copy it + strlcpy(me->value, value , lgvalue ); + me->checksum = checksum ; + + // That's all + return (me); + } else { + // indicate our parent node that the next node + // is not us anymore but the next we have + parNode->next = me->next; + + // free up this node + free (me); + + // Return to parent (that will now point on next node and not us) + // and continue loop just in case we have sevral with same name + me = parNode; + } + } + } + } + + // Our linked list structure sizeof(ValueList) + // + Name + '\0' + // + Value + '\0' + size_t size ; + #if defined (ESP8266) || defined (ESP32) + lgname = ESP_allocAlign(lgname+1); // Align name buffer + lgvalue = ESP_allocAlign(lgvalue+1); // Align value buffer + // Align the whole structure + size = ESP_allocAlign( sizeof(ValueList) + lgname + lgvalue ) ; + #else + size = sizeof(ValueList) + lgname + 1 + lgvalue + 1 ; + #endif + + // Create new node with size to store strings + if ((newNode = (ValueList *) malloc(size) ) == NULL) + return ( (ValueList *) NULL ); + + // get our buffer Safe + memset(newNode, 0, size); + + // Put the new node on the list + me->next = newNode; + + // First String located after last struct element + // Second String located after the First + \0 + newNode->checksum = checksum; + newNode->name = (char *) newNode + sizeof(ValueList); + newNode->value = (char *) newNode->name + lgname + 1; + + // Copy the string data + memcpy(newNode->name , name , lgname ); + memcpy(newNode->value, value , lgvalue ); + + // So we just created this node but was it new + // or was matter of text size ? + if ( (*flags & TINFO_FLAGS_UPDATED) == 0) { + // so we added this node ! + *flags |= TINFO_FLAGS_ADDED ; + newNode->flags = *flags; + } + + TI_Debug(F("Added '")); + TI_Debug(name); + TI_Debug('='); + TI_Debug(value); + TI_Debug(F("' '")); + TI_Debug((char) checksum); + TI_Debugln(F("'")); + + // return pointer on the new node + return (newNode); + } + + } // Checksum OK + + + // Error or Already Exists + return ( (ValueList *) NULL); +} + +/* ====================================================================== +Function: valueRemoveFlagged +Purpose : remove element to the Linked List of values where +Input : paramter flags +Output : true if found and removed +Comments: - +====================================================================== */ +boolean TInfo::valueRemoveFlagged(uint8_t flags) +{ + boolean deleted = false; + + // Get our linked list + ValueList * me = &_valueslist; + ValueList *parNode = NULL ; + + // Got one and all seems good ? + if (me) { + // Loop thru the node + while (me->next) { + // save parent node + parNode = me ; + + // go to next node + me = me->next; + + // found the flags? + if (me->flags & flags ) { + // indicate our parent node that the next node + // is not us anymore but the next we have + parNode->next = me->next; + + // free up this node + free (me); + + // Return to parent (that will now point on next node and not us) + // and continue loop just in case we have sevral with same name + me = parNode; + deleted = true; + } + } + } + + return (deleted); +} + +/* ====================================================================== +Function: valueRemove +Purpose : remove element to the Linked List of values +Input : Pointer to the label name +Output : true if found and removed +Comments: - +====================================================================== */ +boolean TInfo::valueRemove(char * name) +{ + boolean deleted = false; + + // Get our linked list + ValueList * me = &_valueslist; + ValueList *parNode = NULL ; + + uint8_t lgname = strlen(name); + + // Got one and all seems good ? + if (me && lgname) { + // Loop thru the node + while (me->next) { + // save parent node + parNode = me ; + + // go to next node + me = me->next; + + // found ? + if (strncmp(me->name, name, lgname) == 0) { + // indicate our parent node that the next node + // is not us anymore but the next we have + parNode->next = me->next; + + // free up this node + free (me); + + // Return to parent (that will now point on next node and not us) + // and continue loop just in case we have sevral with same name + me = parNode; + deleted = true; + } + } + } + + return (deleted); +} + +/* ====================================================================== +Function: valueGet +Purpose : get value of one element +Input : Pointer to the label name + pointer to the value where we fill data +Output : pointer to the value where we filled data NULL is not found +====================================================================== */ +char * TInfo::valueGet(char * name, char * value) +{ + // Get our linked list + ValueList * me = &_valueslist; + uint8_t lgname = strlen(name); + + // Got one and all seems good ? + if (me && lgname) { + + // Loop thru the node + while (me->next) { + + // go to next node + me = me->next; + + // Check if we match this LABEL + if (lgname==strlen(me->name) && strncmp(me->name, name, lgname)==0) { + // this one has a value ? + if (me->value) { + // copy to dest buffer + uint8_t lgvalue = strlen(me->value); + strlcpy(value, me->value , lgvalue ); + return ( value ); + } + } + } + } + // not found + return ( NULL); +} + +/* ====================================================================== +Function: getTopList +Purpose : return a pointer on the top of the linked list +Input : - +Output : Pointer +====================================================================== */ +ValueList * TInfo::getList(void) +{ + // Get our linked list + return &_valueslist; +} + +/* ====================================================================== +Function: valuesDump +Purpose : dump linked list content +Input : - +Output : total number of values +====================================================================== */ +uint8_t TInfo::valuesDump(void) +{ + // Get our linked list + ValueList * me = &_valueslist; + uint8_t index = 0; + + // Got one ? + if (me) { + // Loop thru the node + while (me->next) { + // go to next node + me = me->next; + + index++; + TI_Debug(index) ; + TI_Debug(F(") ")) ; + + if (me->name) { + TI_Debug(me->name) ; + } else { + TI_Debug(F("NULL")) ; + } + + TI_Debug(F("=")) ; + + if (me->value) { + TI_Debug(me->value) ; + } else { + TI_Debug(F("NULL")) ; + } + + TI_Debug(F(" '")) ; + TI_Debug(me->checksum) ; + TI_Debug(F("' ")); + + // Flags management + if ( me->flags) { + TI_Debug(F("Flags:0x")); + TI_Debugf("%02X =>", me->flags); + if ( me->flags & TINFO_FLAGS_EXIST) { + TI_Debug(F("Exist ")) ; + } + if ( me->flags & TINFO_FLAGS_UPDATED) { + TI_Debug(F("Updated ")) ; + } + if ( me->flags & TINFO_FLAGS_ADDED) { + TI_Debug(F("New ")) ; + } + } + + TI_Debugln() ; + } + } + + return index; +} + +/* ====================================================================== +Function: labelCount +Purpose : Count the number of label in the list +Input : - +Output : element numbers +====================================================================== */ +int TInfo::labelCount() +{ + int count = 0; + + // Get our linked list + ValueList * me = &_valueslist; + + if (me) + while ((me = me->next)) + count++; + + return (count); +} + +/* ====================================================================== +Function: listDelete +Purpose : Delete the ENTIRE Linked List, not a value +Input : - +Output : True if Ok False Otherwise +====================================================================== */ +boolean TInfo::listDelete() +{ + // Get our linked list + ValueList * me = &_valueslist; + + // Got a pointer + if (me) { + ValueList *current; + + // For each linked list + while ((current = me->next)) { + // Get the next + me->next = current->next; + + // Free the current + free(current); + } + + // Free the top element + me->next = NULL ; + + // Ok + return (true); + } + + return (false); +} + +/* ====================================================================== +Function: checksum +Purpose : calculate the checksum based on data/value fields +Input : label name + label value +Output : checksum +Comments: return '\0' in case of error +====================================================================== */ +unsigned char TInfo::calcChecksum(char *etiquette, char *valeur) +{ + uint8_t sum = ' '; // Somme des codes ASCII du message + un espace + + // avoid dead loop, always check all is fine + if (etiquette && valeur) { + // this will not hurt and may save our life ;-) + if (strlen(etiquette) && strlen(valeur)) { + while (*etiquette) + sum += *etiquette++ ; + + while(*valeur) + sum += *valeur++ ; + + return ( (sum & 63) + ' ' ) ; + } + } + return 0; +} + +/* ====================================================================== +Function: customLabel +Purpose : do action when received a correct label / value + checksum line +Input : plabel : pointer to string containing the label + pvalue : pointer to string containing the associated value + pflags pointer in flags value if we need to cchange it +Output : +Comments: +====================================================================== */ +void TInfo::customLabel( char * plabel, char * pvalue, uint8_t * pflags) +{ + int8_t phase = -1; + + // Monophasé + if (strcmp(plabel, "ADPS")==0 ) + phase=0; + + // For testing + //if (strcmp(plabel, "IINST")==0 ) { + // *pflags |= TINFO_FLAGS_ALERT; + //} + + // triphasé c'est ADIR + Num Phase + if (plabel[0]=='A' && plabel[1]=='D' && plabel[2]=='I' && plabel[3]=='R' && plabel[4]>='1' && plabel[4]<='3') { + phase = plabel[4]-'0'; + } + + // Nous avons un ADPS ? + if (phase>=0 && phase <=3) { + // ne doit pas être sauvé définitivement + *pflags |= TINFO_FLAGS_ALERT; + + // Traitement de l'ADPS demandé par le sketch + if (_fn_ADPS) + _fn_ADPS(phase); + } +} + +/* ====================================================================== +Function: checkLine +Purpose : check one line of teleinfo received +Input : - +Output : pointer to the data object in the linked list if OK else NULL +Comments: +====================================================================== */ +ValueList * TInfo::checkLine(char * pline) +{ + char * p; + char * ptok; + char * pend; + char * pvalue; + char checksum; + char buff[TINFO_BUFSIZE]; + uint8_t flags = TINFO_FLAGS_NONE; + //boolean err = true ; // Assume error + int len ; // Group len + + if (pline==NULL) + return NULL; + + len = strlen(pline); + + // a line should be at least 7 Char + // 2 Label + Space + 1 etiquette + space + checksum + \r + if ( len < 7 ) + return NULL; + + // Get our own working copy + strlcpy( buff, _recv_buff, len+1); + + p = &buff[0]; + ptok = p; // for sure we start with token name + pend = p + len; // max size + + // Init values + pvalue = NULL; + checksum = 0; + + //TI_Debug("Got ["); + //TI_Debug(len); + //TI_Debug("] "); + + + // Loop in buffer + while ( p < pend ) { + // start of token value + if ( *p==' ' && ptok) { + // Isolate token name + *p++ = '\0'; + + // 1st space, it's the label value + if (!pvalue) + pvalue = p; + else + // 2nd space, so it's the checksum + checksum = *p; + } + // new line ? ok we got all we need ? + + if ( *p=='\r' ) { + *p='\0'; + + // Good format ? + if ( ptok && pvalue && checksum ) { + // Always check to avoid bad behavior + if(strlen(ptok) && strlen(pvalue)) { + // Is checksum is OK + if ( calcChecksum(ptok,pvalue) == checksum) { + // In case we need to do things on specific labels + customLabel(ptok, pvalue, &flags); + + // Add value to linked lists of values + ValueList * me = valueAdd(ptok, pvalue, checksum, &flags); + + // value correctly added/changed + if ( me ) { + // something to do with new datas + if (flags & (TINFO_FLAGS_UPDATED | TINFO_FLAGS_ADDED | TINFO_FLAGS_ALERT) ) { + // this frame will for sure be updated + _frame_updated = true; + + // Do we need to advertise user callback + if (_fn_data) + _fn_data(me, flags); + } + } + } + } + } + } + // Next char + p++; + + } // While + + return NULL; +} + +/* ====================================================================== +Function: process +Purpose : teleinfo serial char received processing, should be called + my main loop, this will take care of managing all the other +Input : pointer to the serial used +Output : teleinfo global state +====================================================================== */ +_State_e TInfo::process(char c) +{ + // be sure 7 bits only + c &= 0x7F; + + // What we received ? + switch (c) { + // start of transmission ??? + case TINFO_STX: + // Clear buffer, begin to store in it + clearBuffer(); + + // by default frame is not "updated" + // if data change we'll set this flag + _frame_updated = false; + + // We were waiting fo this one ? + if (_state == TINFO_INIT || _state == TINFO_WAIT_STX ) { + TI_Debugln(F("TINFO_WAIT_ETX")); + _state = TINFO_WAIT_ETX; + } + break; + + // End of transmission ? + case TINFO_ETX: + + // Normal working mode ? + if (_state == TINFO_READY) { + // Get on top of our linked list + ValueList * me = &_valueslist; + + // Call user callback if any + if (_frame_updated && _fn_updated_frame) + _fn_updated_frame(me); + else if (_fn_new_frame) + _fn_new_frame(me); + + #ifdef TI_Debug + valuesDump(); + #endif + + // It's important there since all user job is done + // to remove the alert flags from table (ADPS for example) + // it will be put back again next time if any + valueRemoveFlagged(TINFO_FLAGS_ALERT); + } + + // We were waiting fo this one ? + if (_state == TINFO_WAIT_ETX) { + TI_Debugln(F("TINFO_READY")); + _state = TINFO_READY; + } + else if ( _state == TINFO_INIT) { + TI_Debugln(F("TINFO_WAIT_STX")); + _state = TINFO_WAIT_STX ; + } + + break; + + // Start of group \n ? + case TINFO_SGR: + // Do nothing we'll work at end of group + // we can safely ignore this char + break; + + // End of group \r ? + case TINFO_EGR: + // Are we ready to process ? + if (_state == TINFO_READY) { + // Store data recceived (we'll need it) + if ( _recv_idx < TINFO_BUFSIZE) + _recv_buff[_recv_idx++]=c; + + // clear the end of buffer (paranoia inside) + memset(&_recv_buff[_recv_idx], 0, TINFO_BUFSIZE-_recv_idx); + + // check the group we've just received + checkLine(_recv_buff) ; + + // Whatever error or not, we done + clearBuffer(); + } + break; + + // other char ? + default: + { + // Only in a ready state of course + if (_state == TINFO_READY) { + // If buffer is not full, Store data + if ( _recv_idx < TINFO_BUFSIZE) + _recv_buff[_recv_idx++]=c; + else + clearBuffer(); + } + } + break; + } + + return _state; +} + + diff --git a/lib/LibTeleinfo/src/LibTeleinfo.h b/lib/LibTeleinfo/src/LibTeleinfo.h new file mode 100755 index 000000000..00b5495c4 --- /dev/null +++ b/lib/LibTeleinfo/src/LibTeleinfo.h @@ -0,0 +1,138 @@ +// ********************************************************************************** +// Driver definition for French Teleinfo +// ********************************************************************************** +// Creative Commons Attrib Share-Alike License +// You are free to use/extend this library but please abide with the CC-BY-SA license: +// http://creativecommons.org/licenses/by-sa/4.0/ +// +// For any explanation about teleinfo ou use , see my blog +// http://hallard.me/category/tinfo +// +// Code based on following datasheet +// http://www.erdf.fr/sites/default/files/ERDF-NOI-CPT_02E.pdf +// +// Written by Charles-Henri Hallard (http://hallard.me) +// +// History : V1.00 2015-06-14 - First release +// V2.00 2020-06-11 - Integration into Tasmota +// +// All text above must be included in any redistribution. +// +// Edit : Tab size set to 2 but I converted tab to sapces +// +// ********************************************************************************** + +#ifndef LibTeleinfo_h +#define LibTeleinfo_h + +// Define this if you want library to be verbose +//#define TI_DEBUG + +// I prefix debug macro to be sure to use specific for THIS library +// debugging, this should not interfere with main sketch or other +// libraries +#ifdef TI_DEBUG + #ifdef ESP8266 + #define TI_Debug(x) Serial1.print(x) + #define TI_Debugln(x) Serial1.println(x) + #define TI_Debugf(...) Serial1.printf(__VA_ARGS__) + #define TI_Debugflush Serial1.flush + #else + #define TI_Debug(x) Serial.print(x) + #define TI_Debugln(x) Serial.println(x) + #define TI_Debugf(...) Serial.printf(__VA_ARGS__) + #define TI_Debugflush Serial.flush + #endif +#else + #define TI_Debug(x) + #define TI_Debugln(x) + #define TI_Debugf(...) + #define TI_Debugflush +#endif + +// For 4 bytes Aligment boundaries +#define ESP_allocAlign(size) ((size + 3) & ~((size_t) 3)) + +#pragma pack(push) // push current alignment to stack +#pragma pack(1) // set alignment to 1 byte boundary + +// Linked list structure containing all values received +typedef struct _ValueList ValueList; +struct _ValueList +{ + ValueList *next; // next element + char * name; // LABEL of value name + char * value; // value + uint8_t checksum;// checksum + uint8_t flags; // specific flags +}; + +#pragma pack(pop) + +// Library state machine +enum _State_e { + TINFO_INIT, // We're in init + TINFO_WAIT_STX, // We're waiting for STX + TINFO_WAIT_ETX, // We had STX, We're waiting for ETX + TINFO_READY // We had STX AND ETX, So we're OK +}; + +// what we done with received value (also for callback flags) +#define TINFO_FLAGS_NONE 0x00 +#define TINFO_FLAGS_NOTHING 0x01 +#define TINFO_FLAGS_ADDED 0x02 +#define TINFO_FLAGS_EXIST 0x04 +#define TINFO_FLAGS_UPDATED 0x08 +#define TINFO_FLAGS_ALERT 0x80 /* This will generate an alert */ + +// Local buffer for one line of teleinfo +// maximum size, I think it should be enought +#define TINFO_BUFSIZE 64 + +// Teleinfo start and end of frame characters +#define TINFO_STX 0x02 +#define TINFO_ETX 0x03 +#define TINFO_SGR '\n' // start of group +#define TINFO_EGR '\r' // End of group + +class TInfo +{ + public: + TInfo(); + void init(); + _State_e process (char c); + void attachADPS(void (*_fn_ADPS)(uint8_t phase)); + void attachData(void (*_fn_data)(ValueList * valueslist, uint8_t state)); + void attachNewFrame(void (*_fn_new_frame)(ValueList * valueslist)); + void attachUpdatedFrame(void (*_fn_updated_frame)(ValueList * valueslist)); + ValueList * addCustomValue(char * name, char * value, uint8_t * flags); + ValueList * getList(void); + uint8_t valuesDump(void); + char * valueGet(char * name, char * value); + boolean listDelete(); + unsigned char calcChecksum(char *etiquette, char *valeur) ; + + private: + void clearBuffer(); + ValueList * valueAdd (char * name, char * value, uint8_t checksum, uint8_t * flags); + boolean valueRemove (char * name); + boolean valueRemoveFlagged(uint8_t flags); + int labelCount(); + void customLabel( char * plabel, char * pvalue, uint8_t * pflags) ; + ValueList * checkLine(char * pline) ; + + _State_e _state; // Teleinfo machine state + ValueList _valueslist; // Linked list of teleinfo values + char _recv_buff[TINFO_BUFSIZE]; // line receive buffer + uint8_t _recv_idx; // index in receive buffer + boolean _frame_updated; // Data on the frame has been updated + void (*_fn_ADPS)(uint8_t phase); + void (*_fn_data)(ValueList * valueslist, uint8_t state); + void (*_fn_new_frame)(ValueList * valueslist); + void (*_fn_updated_frame)(ValueList * valueslist); + + //volatile uint8_t *dcport; + //uint8_t dcpinmask; +}; + +#endif From ac65758cc385b42cca84abf6cf42f7528a43e00c Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 11 Jun 2020 14:53:10 +0200 Subject: [PATCH 199/581] Added support of TELEINFO --- tasmota/tasmota_configurations.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 811076d8f..2af371976 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -167,6 +167,7 @@ #define USE_DDSU666 // Add support for Chint DDSU666 Modbus energy monitor (+0k6 code) //#define USE_SOLAX_X1 // Add support for Solax X1 series Modbus log info (+3k1 code) //#define USE_LE01MR // Add support for F&F LE-01MR modbus energy meter (+2k code) +//#define USE_TELEINFO // Add support for French Energy Provider metering telemetry #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #define USE_MAX31855 // Add support for MAX31855 K-Type thermocouple sensor using softSPI @@ -263,6 +264,8 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) + #undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry + #define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram) #define USE_DISPLAY // Add I2C Display Support (+2k code) @@ -353,6 +356,7 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) + #undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry //#undef USE_DS18x20 // Disable support for DS18x20 sensors with id sort, single scan and read retry (+1k3 code) @@ -496,6 +500,8 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) +#undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry + #undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI @@ -621,6 +627,7 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) +#undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry #undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI From 4c5b2f37fdbcb742083165e25d92f5cb4c69a051 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 11 Jun 2020 17:30:33 +0200 Subject: [PATCH 200/581] Add initial support for Telegram Add initial support for Telegram bot (#8619) --- RELEASENOTES.md | 3 +- tasmota/CHANGELOG.md | 4 + tasmota/my_user_config.h | 5 + tasmota/support_features.ino | 4 +- tasmota/tasmota.h | 13 +- tasmota/tasmota_version.h | 2 +- tasmota/xdrv_40_telegram.ino | 479 +++++++++++++++++++++++++++++++++++ tools/decode-status.py | 4 +- 8 files changed, 503 insertions(+), 11 deletions(-) create mode 100644 tasmota/xdrv_40_telegram.ino diff --git a/RELEASENOTES.md b/RELEASENOTES.md index fdac7edde..ab01ddaa4 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,7 +52,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.3.1.2 +### Version 8.3.1.3 - Change IRremoteESP8266 library updated to v2.7.7 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) @@ -76,3 +76,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) - Add support for up to eight MCP9808 temperature sensors by device111 (#8594) - Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) +- Add initial support for Telegram bot (#8619) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 4f7d3132b..9033a2bba 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased (development) +### 8.3.1.3 20200611 + +- Add initial support for Telegram bot (#8619) + ### 8.3.1.2 20200522 - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 4a75b4b98..ea2e6eefe 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -367,6 +367,11 @@ // Full documentation here: https://github.com/arendst/Tasmota/wiki/AWS-IoT // #define USE_4K_RSA // Support 4096 bits certificates, instead of 2048 +// -- Telegram Protocol --------------------------- +//#define USE_TELEGRAM // Support for Telegram protocol (+49k code, +7.0k mem and +4.8k additional during connection handshake) + #define USE_TELEGRAM_FINGERPRINT "\xB2\x72\x47\xA6\x69\x8C\x3C\x69\xF9\x58\x6C\xF3\x60\x02\xFB\x83\xFA\x8B\x1F\x23" // Telegram api.telegram.org TLS public key fingerpring +// #define USE_MQTT_TLS_CA_CERT // Use certificate instead of fingerprint + // -- KNX IP Protocol ----------------------------- //#define USE_KNX // Enable KNX IP Protocol Support (+9.4k code, +3k7 mem) #define USE_KNX_WEB_MENU // Enable KNX WEB MENU (+8.3k code, +144 mem) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 20bb9acf3..04de532d6 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -575,7 +575,9 @@ void GetFeatures(void) #ifdef USE_BL0940 feature6 |= 0x00004000; // xnrg_14_bl0940.ino #endif -// feature6 |= 0x00008000; +#ifdef USE_TELEGRAM + feature6 |= 0x00008000; // xdrv_40_telegram.ino +#endif // feature6 |= 0x00010000; // feature6 |= 0x00020000; diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index c3913e8a1..49347f1f8 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -293,7 +293,7 @@ enum SettingsTextIndex { SET_OTAURL, SET_TEMPLATE_NAME, SET_DEV_GROUP_NAME1, SET_DEV_GROUP_NAME2, SET_DEV_GROUP_NAME3, SET_DEV_GROUP_NAME4, SET_DEVICENAME, - SET_TELEGRAMTOKEN, + SET_TELEGRAM_TOKEN, SET_TELEGRAM_CHATID, SET_MAX }; enum DevGroupMessageType { DGR_MSGTYP_FULL_STATUS, DGR_MSGTYP_PARTIAL_UPDATE, DGR_MSGTYP_UPDATE, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_MSGTYP_UPDATE_DIRECT, DGR_MSGTYPE_UPDATE_COMMAND }; @@ -321,9 +321,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER, SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER, - SRC_THERMOSTAT, SRC_MAX }; + SRC_THERMOSTAT, SRC_CHAT, SRC_MAX }; const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|" - "Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|Thermostat"; + "Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|" + "Thermostat|Chat"; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; @@ -344,10 +345,10 @@ const SerConfu8 kTasmotaSerialConfig[] PROGMEM = { SERIAL_5O2, SERIAL_6O2, SERIAL_7O2, SERIAL_8O2 }; -enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE, TUYA_MCU_FUNC_SWT1 = 1, TUYA_MCU_FUNC_SWT2, TUYA_MCU_FUNC_SWT3, TUYA_MCU_FUNC_SWT4, - TUYA_MCU_FUNC_REL1 = 11, TUYA_MCU_FUNC_REL2, TUYA_MCU_FUNC_REL3, TUYA_MCU_FUNC_REL4, TUYA_MCU_FUNC_REL5, +enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE, TUYA_MCU_FUNC_SWT1 = 1, TUYA_MCU_FUNC_SWT2, TUYA_MCU_FUNC_SWT3, TUYA_MCU_FUNC_SWT4, + TUYA_MCU_FUNC_REL1 = 11, TUYA_MCU_FUNC_REL2, TUYA_MCU_FUNC_REL3, TUYA_MCU_FUNC_REL4, TUYA_MCU_FUNC_REL5, TUYA_MCU_FUNC_REL6, TUYA_MCU_FUNC_REL7, TUYA_MCU_FUNC_REL8, TUYA_MCU_FUNC_DIMMER = 21, TUYA_MCU_FUNC_POWER = 31, - TUYA_MCU_FUNC_CURRENT, TUYA_MCU_FUNC_VOLTAGE, TUYA_MCU_FUNC_BATTERY_STATE, TUYA_MCU_FUNC_BATTERY_PERCENTAGE, + TUYA_MCU_FUNC_CURRENT, TUYA_MCU_FUNC_VOLTAGE, TUYA_MCU_FUNC_BATTERY_STATE, TUYA_MCU_FUNC_BATTERY_PERCENTAGE, TUYA_MCU_FUNC_REL1_INV = 41, TUYA_MCU_FUNC_REL2_INV, TUYA_MCU_FUNC_REL3_INV, TUYA_MCU_FUNC_REL4_INV, TUYA_MCU_FUNC_REL5_INV, TUYA_MCU_FUNC_REL6_INV, TUYA_MCU_FUNC_REL7_INV, TUYA_MCU_FUNC_REL8_INV, TUYA_MCU_FUNC_LOWPOWER_MODE = 51, TUYA_MCU_FUNC_LAST = 255 }; diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 1b21293b2..f22a0288b 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08030102; +const uint32_t VERSION = 0x08030103; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino new file mode 100644 index 000000000..a2ec2e49f --- /dev/null +++ b/tasmota/xdrv_40_telegram.ino @@ -0,0 +1,479 @@ +/* + xdrv_40_telegram.ino - telegram for Tasmota + + Copyright (C) 2020 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_TELEGRAM +/*********************************************************************************************\ + * Telegram bot + * + * Supported commands: + * TGToken - Add your BotFather created bot token (default none) + * TGChatId - Add your BotFather created bot chat id (default none) + * TGPoll - Telegram receive poll time (default 10 seconds) + * TGState 0 - Disable telegram sending (default) + * TGState 1 - Enable telegram sending + * TGState 2 - Disable telegram listener (default) + * TGState 3 - Enable telegram listener + * TGState 4 - Disable telegram response echo (default) + * TGState 5 - Enable telegram response echo + * TGSend - If telegram sending is enabled AND a chat id is present then send data + * + * Tested with defines + * #define USE_TELEGRAM // Support for Telegram protocol + * #define USE_TELEGRAM_FINGERPRINT "\xB2\x72\x47\xA6\x69\x8C\x3C\x69\xF9\x58\x6C\xF3\x60\x02\xFB\x83\xFA\x8B\x1F\x23" // Telegram api.telegram.org TLS public key fingerpring +\*********************************************************************************************/ + +#define XDRV_40 40 + +#define TELEGRAM_SEND_RETRY 4 // Retries +#define TELEGRAM_LOOP_WAIT 10 // Seconds + +#ifdef USE_MQTT_TLS_CA_CERT + static const uint32_t tls_rx_size = 2048; // since Telegram CA is bigger than 1024 bytes, we need to increase rx buffer + static const uint32_t tls_tx_size = 1024; +#else + static const uint32_t tls_rx_size = 1024; + static const uint32_t tls_tx_size = 1024; +#endif + +#include "WiFiClientSecureLightBearSSL.h" +BearSSL::WiFiClientSecure_light *telegramClient = nullptr; + +static const uint8_t Telegram_Fingerprint[] PROGMEM = USE_TELEGRAM_FINGERPRINT; + +struct { + String message[3][6]; // amount of messages read per time (update_id, name_id, name, lastname, chat_id, text) + uint8_t state = 0; + uint8_t index = 0; + uint8_t retry = 0; + uint8_t poll = TELEGRAM_LOOP_WAIT; + uint8_t wait = 0; + bool send_enable = false; + bool recv_enable = false; + bool echo_enable = false; + bool recv_busy = false; +} Telegram; + +bool TelegramInit(void) { + bool init_done = false; + if (strlen(SettingsText(SET_TELEGRAM_TOKEN))) { + if (!telegramClient) { + telegramClient = new BearSSL::WiFiClientSecure_light(tls_rx_size, tls_tx_size); +#ifdef USE_MQTT_TLS_CA_CERT + telegramClient->setTrustAnchor(&GoDaddyCAG2_TA); +#else + telegramClient->setPubKeyFingerprint(Telegram_Fingerprint, Telegram_Fingerprint, false); // check server fingerprint +#endif + + Telegram.message[0][0]="0"; // Number of received messages + Telegram.message[1][0]=""; + Telegram.message[0][1]="0"; // Code of last read Message + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Started")); + } + + init_done = true; + } + return init_done; +} + +/************************************************************************************************** + * function to achieve connection to api.telegram.org and send command to telegram * + * (Argument to pass: URL to address to Telegram) * + **************************************************************************************************/ +String TelegramConnectToTelegram(String command) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Cmnd %s"), command.c_str()); + + if (!TelegramInit()) { return ""; } + + String response = ""; + uint32_t tls_connect_time = millis(); + + if (telegramClient->connect("api.telegram.org", 443)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Connected in %d ms, max ThunkStack used %d"), + millis() - tls_connect_time, telegramClient->getMaxThunkStackUse()); + + telegramClient->println("GET /"+command); + + String a = ""; + char c; + int ch_count=0; + uint32_t now = millis(); + bool avail = false; + while (millis() -now < 1500) { + while (telegramClient->available()) { + char c = telegramClient->read(); + if (ch_count < 700) { + response = response + c; + ch_count++; + } + avail = true; + } + if (avail) { + break; + } + } + + telegramClient->stop(); + } + + return response; +} + +/*************************************************************** + * GetUpdates - function to receive all messages from telegram * + * (Argument to pass: the last+1 message to read) * + ***************************************************************/ +void TelegramGetUpdates(String offset) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: getUpdates")); + + if (!TelegramInit()) { return; } + + String _token = SettingsText(SET_TELEGRAM_TOKEN); + String command = "bot" + _token + "/getUpdates?offset=" + offset; + String response = TelegramConnectToTelegram(command); //recieve reply from telegram.org + + // {"ok":true,"result":[]} + // or + // {"ok":true,"result":[ + // {"update_id":973125394, + // "message":{"message_id":25, + // "from":{"id":139920293,"is_bot":false,"first_name":"Theo","last_name":"Arends","username":"tjatja","language_code":"nl"}, + // "chat":{"id":139920293,"first_name":"Theo","last_name":"Arends","username":"tjatja","type":"private"}, + // "date":1591877503, + // "text":"M1" + // } + // }, + // {"update_id":973125395, + // "message":{"message_id":26, + // "from":{"id":139920293,"is_bot":false,"first_name":"Theo","last_name":"Arends","username":"tjatja","language_code":"nl"}, + // "chat":{"id":139920293,"first_name":"Theo","last_name":"Arends","username":"tjatja","type":"private"}, + // "date":1591877508, + // "text":"M2" + // } + // } + // ]} + // or + // {"ok":true,"result":[ + // {"update_id":973125396, + // "message":{"message_id":29, + // "from":{"id":139920293,"is_bot":false,"first_name":"Theo","last_name":"Arends","username":"tjatja","language_code":"nl"}, + // "chat":{"id":139920293,"first_name":"Theo","last_name":"Arends","username":"tjatja","type":"private"}, + // "date":1591879753, + // "text":"/power toggle", + // "entities":[{"offset":0,"length":6,"type":"bot_command"}] + // } + // } + // ]} + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TLG: Response %s"), response.c_str()); + + // parsing of reply from Telegram into separate received messages + int i = 0; //messages received counter + if (response != "") { + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Sent Update request messages up to %s"), offset.c_str()); + + String a = ""; + int ch_count = 0; + String c; + for (uint32_t n = 1; n < response.length() +1; n++) { //Search for each message start + ch_count++; + c = response.substring(n -1, n); + a = a + c; + if (ch_count > 8) { + if (a.substring(ch_count -9) == "update_id") { + if (i > 1) { break; } + Telegram.message[i][0] = a.substring(0, ch_count -11); + a = a.substring(ch_count-11); + i++; + ch_count = 11; + } + } + } + if (1 == i) { + Telegram.message[i][0] = a.substring(0, ch_count); //Assign of parsed message into message matrix if only 1 message) + } + if (i > 1) { i = i -1; } + } + //check result of parsing process + if (response == "") { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Failed to update")); + return; + } + if (0 == i) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: No new messages")); + Telegram.message[0][0] = "0"; + } else { + Telegram.message[0][0] = String(i); //returns how many messages are in the array + for (int b = 1; b < i+1; b++) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Msg %d %s"), b, Telegram.message[b][0].c_str()); + } + + TelegramAnalizeMessage(); + } +} + +void TelegramAnalizeMessage(void) { + for (uint32_t i = 1; i < Telegram.message[0][0].toInt() +1; i++) { + Telegram.message[i][5] = ""; + + DynamicJsonBuffer jsonBuffer; + JsonObject &root = jsonBuffer.parseObject(Telegram.message[i][0]); + if (root.success()) { + Telegram.message[i][0] = root["update_id"].as(); + Telegram.message[i][1] = root["message"]["from"]["id"].as(); + Telegram.message[i][2] = root["message"]["from"]["first_name"].as(); + Telegram.message[i][3] = root["message"]["from"]["last_name"].as(); + Telegram.message[i][4] = root["message"]["chat"]["id"].as(); + Telegram.message[i][5] = root["message"]["text"].as(); + } + + int id = Telegram.message[Telegram.message[0][0].toInt()][0].toInt() +1; + Telegram.message[0][1] = id; // Write id of last read message + + for (int j = 0; j < 6; j++) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TLG: Parsed%d \"%s\""), j, Telegram.message[i][j].c_str()); + } + } +} + +bool TelegramSendMessage(String chat_id, String text) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: sendMessage")); + + if (!TelegramInit()) { return false; } + + bool sent = false; + if (text != "") { + String _token = SettingsText(SET_TELEGRAM_TOKEN); + String command = "bot" + _token + "/sendMessage?chat_id=" + chat_id + "&text=" + text; + String response = TelegramConnectToTelegram(command); + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TLG: Response %s"), response.c_str()); + + if (response.startsWith("{\"ok\":true")) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Message sent")); + sent = true; + } + + } + + return sent; +} + +/* +void TelegramSendGetMe(void) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: getMe")); + + if (!TelegramInit()) { return; } + + String _token = SettingsText(SET_TELEGRAM_TOKEN); + String command = "bot" + _token + "/getMe"; + String response = TelegramConnectToTelegram(command); + + // {"ok":true,"result":{"id":1179906608,"is_bot":true,"first_name":"Tasmota","username":"tasmota_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TLG: Response %s"), response.c_str()); +} +*/ + +String TelegramExecuteCommand(const char *svalue) { + String response = ""; + + uint32_t curridx = web_log_index; + ExecuteCommand(svalue, SRC_CHAT); + if (web_log_index != curridx) { + uint32_t counter = curridx; + response = F("{"); + bool cflg = false; + do { + char* tmp; + size_t len; + GetLog(counter, &tmp, &len); + if (len) { + // [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] + char* JSON = (char*)memchr(tmp, '{', len); + if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) + size_t JSONlen = len - (JSON - tmp); + if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); } + char stemp[JSONlen]; + strlcpy(stemp, JSON +1, JSONlen -2); + if (cflg) { response += F(","); } + response += stemp; + cflg = true; + } + } + counter++; + counter &= 0xFF; + if (!counter) counter++; // Skip 0 as it is not allowed + } while (counter != web_log_index); + response += F("}"); + } else { + response = F("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}"); + } + + return response; +} + +void TelegramLoop(void) { + if (!global_state.wifi_down && (Telegram.recv_enable || Telegram.echo_enable)) { + switch (Telegram.state) { + case 0: + TelegramInit(); + Telegram.state++; + break; + case 1: + TelegramGetUpdates(Telegram.message[0][1]); // launch API GetUpdates up to xxx message + Telegram.index = 1; + Telegram.retry = TELEGRAM_SEND_RETRY; + Telegram.state++; + break; + case 2: + if (Telegram.echo_enable) { + if (Telegram.retry && (Telegram.index < Telegram.message[0][0].toInt() + 1)) { + if (TelegramSendMessage(Telegram.message[Telegram.index][4], Telegram.message[Telegram.index][5])) { + Telegram.index++; + Telegram.retry = TELEGRAM_SEND_RETRY; + } else { + Telegram.retry--; + } + } else { + Telegram.message[0][0] = ""; // All messages have been replied - reset new messages + Telegram.wait = Telegram.poll; + Telegram.state++; + } + } else { + if (Telegram.message[0][0].toInt() && (Telegram.message[Telegram.index][5].length() > 0)) { + String logging = TelegramExecuteCommand(Telegram.message[Telegram.index][5].c_str()); + if (logging.length() > 0) { + TelegramSendMessage(Telegram.message[Telegram.index][4], logging); + } + } + Telegram.message[0][0] = ""; // All messages have been replied - reset new messages + Telegram.wait = Telegram.poll; + Telegram.state++; + } + break; + case 3: + if (Telegram.wait) { + Telegram.wait--; + } else { + Telegram.state = 1; + } + } + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +#define D_CMND_TGSTATE "State" +#define D_CMND_TGPOLL "Poll" +#define D_CMND_TGSEND "Send" +#define D_CMND_TGTOKEN "Token" +#define D_CMND_TGCHATID "ChatId" + +const char kTelegramCommands[] PROGMEM = "TG|" // Prefix + D_CMND_TGSTATE "|" D_CMND_TGPOLL "|" D_CMND_TGTOKEN "|" D_CMND_TGCHATID "|" D_CMND_TGSEND; + +void (* const TelegramCommand[])(void) PROGMEM = { + &CmndTgState, &CmndTgPoll, &CmndTgToken, &CmndTgChatId, &CmndTgSend }; + +void CmndTgState(void) { + if (XdrvMailbox.data_len > 0) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) { + switch (XdrvMailbox.payload) { + case 0: // Off + case 1: // On + Telegram.send_enable = XdrvMailbox.payload &1; + break; + case 2: // Off + case 3: // On + Telegram.recv_enable = XdrvMailbox.payload &1; + break; + case 4: // Off + case 5: // On + Telegram.echo_enable = XdrvMailbox.payload &1; + break; + } + } + } + snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":{\"Send\":\"%s\",\"Receive\":\"%s\",\"Echo\":\"%s\"}}"), + XdrvMailbox.command, GetStateText(Telegram.send_enable), GetStateText(Telegram.recv_enable), GetStateText(Telegram.echo_enable)); +} + +void CmndTgPoll(void) { + if ((XdrvMailbox.payload >= 4) && (XdrvMailbox.payload <= 300)) { + Telegram.poll = XdrvMailbox.payload; + if (Telegram.poll < Telegram.wait) { + Telegram.wait = Telegram.poll; + } + } + ResponseCmndNumber(Telegram.poll); +} + +void CmndTgToken(void) { + if (XdrvMailbox.data_len > 0) { + SettingsUpdateText(SET_TELEGRAM_TOKEN, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data); + } + ResponseCmndChar(SettingsText(SET_TELEGRAM_TOKEN)); +} + +void CmndTgChatId(void) { + if (XdrvMailbox.data_len > 0) { + SettingsUpdateText(SET_TELEGRAM_CHATID, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data); + } + ResponseCmndChar(SettingsText(SET_TELEGRAM_CHATID)); +} + +void CmndTgSend(void) { + if (!Telegram.send_enable || !strlen(SettingsText(SET_TELEGRAM_CHATID))) { + ResponseCmndChar(D_JSON_FAILED); + return; + } + if (XdrvMailbox.data_len > 0) { + String message = XdrvMailbox.data; + String chat_id = SettingsText(SET_TELEGRAM_CHATID); + if (!TelegramSendMessage(chat_id, message)) { + ResponseCmndChar(D_JSON_FAILED); + return; + } + } + ResponseCmndDone(); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv40(uint8_t function) +{ + bool result = false; + + switch (function) { + case FUNC_EVERY_SECOND: + TelegramLoop(); + break; + case FUNC_COMMAND: + result = DecodeCommand(kTelegramCommands, TelegramCommand); + break; + } + return result; +} +#endif // USE_TELEGRAM diff --git a/tools/decode-status.py b/tools/decode-status.py index 1ce04951e..4228b69df 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -205,7 +205,7 @@ a_features = [[ "USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080", "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", - "USE_VEML7700","USE_MCP9808","USE_BL0940","", + "USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM", "","","","", "","","","", "","","","", @@ -243,7 +243,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200607 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200611 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From 18b00f9cbeca16572cf79f6506cfc57114f8fceb Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 11 Jun 2020 17:52:10 +0200 Subject: [PATCH 201/581] Change telegram command prefix to Tm --- tasmota/xdrv_40_telegram.ino | 76 ++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino index a2ec2e49f..ce0d83f10 100644 --- a/tasmota/xdrv_40_telegram.ino +++ b/tasmota/xdrv_40_telegram.ino @@ -22,16 +22,16 @@ * Telegram bot * * Supported commands: - * TGToken - Add your BotFather created bot token (default none) - * TGChatId - Add your BotFather created bot chat id (default none) - * TGPoll - Telegram receive poll time (default 10 seconds) - * TGState 0 - Disable telegram sending (default) - * TGState 1 - Enable telegram sending - * TGState 2 - Disable telegram listener (default) - * TGState 3 - Enable telegram listener - * TGState 4 - Disable telegram response echo (default) - * TGState 5 - Enable telegram response echo - * TGSend - If telegram sending is enabled AND a chat id is present then send data + * TmToken - Add your BotFather created bot token (default none) + * TmChatId - Add your BotFather created bot chat id (default none) + * TmPoll - Telegram receive poll time (default 10 seconds) + * TmState 0 - Disable telegram sending (default) + * TmState 1 - Enable telegram sending + * TmState 2 - Disable telegram listener (default) + * TmState 3 - Enable telegram listener + * TmState 4 - Disable telegram response echo (default) + * TmState 5 - Enable telegram response echo + * TmSend - If telegram sending is enabled AND a chat id is present then send data * * Tested with defines * #define USE_TELEGRAM // Support for Telegram protocol @@ -84,7 +84,7 @@ bool TelegramInit(void) { Telegram.message[1][0]=""; Telegram.message[0][1]="0"; // Code of last read Message - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Started")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Started")); } init_done = true; @@ -97,7 +97,7 @@ bool TelegramInit(void) { * (Argument to pass: URL to address to Telegram) * **************************************************************************************************/ String TelegramConnectToTelegram(String command) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Cmnd %s"), command.c_str()); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Cmnd %s"), command.c_str()); if (!TelegramInit()) { return ""; } @@ -105,7 +105,7 @@ String TelegramConnectToTelegram(String command) { uint32_t tls_connect_time = millis(); if (telegramClient->connect("api.telegram.org", 443)) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Connected in %d ms, max ThunkStack used %d"), + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Connected in %d ms, max ThunkStack used %d"), millis() - tls_connect_time, telegramClient->getMaxThunkStackUse()); telegramClient->println("GET /"+command); @@ -140,7 +140,7 @@ String TelegramConnectToTelegram(String command) { * (Argument to pass: the last+1 message to read) * ***************************************************************/ void TelegramGetUpdates(String offset) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: getUpdates")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: getUpdates")); if (!TelegramInit()) { return; } @@ -181,13 +181,13 @@ void TelegramGetUpdates(String offset) { // } // ]} - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TLG: Response %s"), response.c_str()); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); // parsing of reply from Telegram into separate received messages int i = 0; //messages received counter if (response != "") { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Sent Update request messages up to %s"), offset.c_str()); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Sent Update request messages up to %s"), offset.c_str()); String a = ""; int ch_count = 0; @@ -213,16 +213,16 @@ void TelegramGetUpdates(String offset) { } //check result of parsing process if (response == "") { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Failed to update")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Failed to update")); return; } if (0 == i) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: No new messages")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: No new messages")); Telegram.message[0][0] = "0"; } else { Telegram.message[0][0] = String(i); //returns how many messages are in the array for (int b = 1; b < i+1; b++) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Msg %d %s"), b, Telegram.message[b][0].c_str()); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Msg %d %s"), b, Telegram.message[b][0].c_str()); } TelegramAnalizeMessage(); @@ -248,13 +248,13 @@ void TelegramAnalizeMessage(void) { Telegram.message[0][1] = id; // Write id of last read message for (int j = 0; j < 6; j++) { - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TLG: Parsed%d \"%s\""), j, Telegram.message[i][j].c_str()); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Parsed%d \"%s\""), j, Telegram.message[i][j].c_str()); } } } bool TelegramSendMessage(String chat_id, String text) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: sendMessage")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: sendMessage")); if (!TelegramInit()) { return false; } @@ -264,10 +264,10 @@ bool TelegramSendMessage(String chat_id, String text) { String command = "bot" + _token + "/sendMessage?chat_id=" + chat_id + "&text=" + text; String response = TelegramConnectToTelegram(command); - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TLG: Response %s"), response.c_str()); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); if (response.startsWith("{\"ok\":true")) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: Message sent")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Message sent")); sent = true; } @@ -278,7 +278,7 @@ bool TelegramSendMessage(String chat_id, String text) { /* void TelegramSendGetMe(void) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TLG: getMe")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: getMe")); if (!TelegramInit()) { return; } @@ -288,7 +288,7 @@ void TelegramSendGetMe(void) { // {"ok":true,"result":{"id":1179906608,"is_bot":true,"first_name":"Tasmota","username":"tasmota_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TLG: Response %s"), response.c_str()); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); } */ @@ -383,19 +383,19 @@ void TelegramLoop(void) { * Commands \*********************************************************************************************/ -#define D_CMND_TGSTATE "State" -#define D_CMND_TGPOLL "Poll" -#define D_CMND_TGSEND "Send" -#define D_CMND_TGTOKEN "Token" -#define D_CMND_TGCHATID "ChatId" +#define D_CMND_TMSTATE "State" +#define D_CMND_TMPOLL "Poll" +#define D_CMND_TMSEND "Send" +#define D_CMND_TMTOKEN "Token" +#define D_CMND_TMCHATID "ChatId" -const char kTelegramCommands[] PROGMEM = "TG|" // Prefix - D_CMND_TGSTATE "|" D_CMND_TGPOLL "|" D_CMND_TGTOKEN "|" D_CMND_TGCHATID "|" D_CMND_TGSEND; +const char kTelegramCommands[] PROGMEM = "Tm|" // Prefix + D_CMND_TMSTATE "|" D_CMND_TMPOLL "|" D_CMND_TMTOKEN "|" D_CMND_TMCHATID "|" D_CMND_TMSEND; void (* const TelegramCommand[])(void) PROGMEM = { - &CmndTgState, &CmndTgPoll, &CmndTgToken, &CmndTgChatId, &CmndTgSend }; + &CmndTmState, &CmndTmPoll, &CmndTmToken, &CmndTmChatId, &CmndTmSend }; -void CmndTgState(void) { +void CmndTmState(void) { if (XdrvMailbox.data_len > 0) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) { switch (XdrvMailbox.payload) { @@ -418,7 +418,7 @@ void CmndTgState(void) { XdrvMailbox.command, GetStateText(Telegram.send_enable), GetStateText(Telegram.recv_enable), GetStateText(Telegram.echo_enable)); } -void CmndTgPoll(void) { +void CmndTmPoll(void) { if ((XdrvMailbox.payload >= 4) && (XdrvMailbox.payload <= 300)) { Telegram.poll = XdrvMailbox.payload; if (Telegram.poll < Telegram.wait) { @@ -428,21 +428,21 @@ void CmndTgPoll(void) { ResponseCmndNumber(Telegram.poll); } -void CmndTgToken(void) { +void CmndTmToken(void) { if (XdrvMailbox.data_len > 0) { SettingsUpdateText(SET_TELEGRAM_TOKEN, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data); } ResponseCmndChar(SettingsText(SET_TELEGRAM_TOKEN)); } -void CmndTgChatId(void) { +void CmndTmChatId(void) { if (XdrvMailbox.data_len > 0) { SettingsUpdateText(SET_TELEGRAM_CHATID, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data); } ResponseCmndChar(SettingsText(SET_TELEGRAM_CHATID)); } -void CmndTgSend(void) { +void CmndTmSend(void) { if (!Telegram.send_enable || !strlen(SettingsText(SET_TELEGRAM_CHATID))) { ResponseCmndChar(D_JSON_FAILED); return; From 24cd4276256aeaefe9fd67ca34978bcf81ac2f73 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 11 Jun 2020 18:18:03 +0200 Subject: [PATCH 202/581] Remove debugging info from telegram --- tasmota/xdrv_40_telegram.ino | 39 ++++++++++++++---------------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino index ce0d83f10..97c5aa453 100644 --- a/tasmota/xdrv_40_telegram.ino +++ b/tasmota/xdrv_40_telegram.ino @@ -84,7 +84,7 @@ bool TelegramInit(void) { Telegram.message[1][0]=""; Telegram.message[0][1]="0"; // Code of last read Message - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Started")); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TGM: Started")); } init_done = true; @@ -92,12 +92,8 @@ bool TelegramInit(void) { return init_done; } -/************************************************************************************************** - * function to achieve connection to api.telegram.org and send command to telegram * - * (Argument to pass: URL to address to Telegram) * - **************************************************************************************************/ String TelegramConnectToTelegram(String command) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Cmnd %s"), command.c_str()); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Cmnd %s"), command.c_str()); if (!TelegramInit()) { return ""; } @@ -105,8 +101,7 @@ String TelegramConnectToTelegram(String command) { uint32_t tls_connect_time = millis(); if (telegramClient->connect("api.telegram.org", 443)) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Connected in %d ms, max ThunkStack used %d"), - millis() - tls_connect_time, telegramClient->getMaxThunkStackUse()); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Connected in %d ms, max ThunkStack used %d"), millis() - tls_connect_time, telegramClient->getMaxThunkStackUse()); telegramClient->println("GET /"+command); @@ -135,12 +130,8 @@ String TelegramConnectToTelegram(String command) { return response; } -/*************************************************************** - * GetUpdates - function to receive all messages from telegram * - * (Argument to pass: the last+1 message to read) * - ***************************************************************/ void TelegramGetUpdates(String offset) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: getUpdates")); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: getUpdates")); if (!TelegramInit()) { return; } @@ -181,13 +172,13 @@ void TelegramGetUpdates(String offset) { // } // ]} - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); +// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); // parsing of reply from Telegram into separate received messages int i = 0; //messages received counter if (response != "") { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Sent Update request messages up to %s"), offset.c_str()); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Sent Update request messages up to %s"), offset.c_str()); String a = ""; int ch_count = 0; @@ -213,16 +204,16 @@ void TelegramGetUpdates(String offset) { } //check result of parsing process if (response == "") { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Failed to update")); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Failed to update")); return; } if (0 == i) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: No new messages")); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: No new messages")); Telegram.message[0][0] = "0"; } else { Telegram.message[0][0] = String(i); //returns how many messages are in the array for (int b = 1; b < i+1; b++) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Msg %d %s"), b, Telegram.message[b][0].c_str()); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Msg %d %s"), b, Telegram.message[b][0].c_str()); } TelegramAnalizeMessage(); @@ -248,13 +239,13 @@ void TelegramAnalizeMessage(void) { Telegram.message[0][1] = id; // Write id of last read message for (int j = 0; j < 6; j++) { - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Parsed%d \"%s\""), j, Telegram.message[i][j].c_str()); +// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Parsed%d \"%s\""), j, Telegram.message[i][j].c_str()); } } } bool TelegramSendMessage(String chat_id, String text) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: sendMessage")); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: sendMessage")); if (!TelegramInit()) { return false; } @@ -264,10 +255,10 @@ bool TelegramSendMessage(String chat_id, String text) { String command = "bot" + _token + "/sendMessage?chat_id=" + chat_id + "&text=" + text; String response = TelegramConnectToTelegram(command); - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); +// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); if (response.startsWith("{\"ok\":true")) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Message sent")); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Message sent")); sent = true; } @@ -278,7 +269,7 @@ bool TelegramSendMessage(String chat_id, String text) { /* void TelegramSendGetMe(void) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: getMe")); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: getMe")); if (!TelegramInit()) { return; } @@ -288,7 +279,7 @@ void TelegramSendGetMe(void) { // {"ok":true,"result":{"id":1179906608,"is_bot":true,"first_name":"Tasmota","username":"tasmota_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); +// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); } */ From 11d64865347d268a5933c7b645d86f8fa2091e27 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 11 Jun 2020 19:13:08 +0200 Subject: [PATCH 203/581] Fix time 4 display with SO52 1 --- tasmota/support.ino | 2 +- tasmota/support_rtc.ino | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 8d915cf05..b27cb072d 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -997,7 +997,7 @@ char* ResponseGetTime(uint32_t format, char* time_str) snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":%u"), UtcTime()); break; case 3: - snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s.%03d\""), GetDateAndTime(DT_LOCAL).c_str(), RtcMillis()); + snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL_MILLIS).c_str()); break; default: snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino index e918ae99d..445976eb3 100644 --- a/tasmota/support_rtc.ino +++ b/tasmota/support_rtc.ino @@ -206,6 +206,14 @@ String GetDateAndTime(uint8_t time_type) break; } String dt = GetDT(time); // 2017-03-07T11:08:02 + + if (DT_LOCAL_MILLIS == time_type) { + char ms[10]; + snprintf_P(ms, sizeof(ms), PSTR(".%03d"), RtcMillis()); + dt += ms; + time_type = DT_LOCAL; + } + if (Settings.flag3.time_append_timezone && (DT_LOCAL == time_type)) { // SetOption52 - Append timezone to JSON time dt += GetTimeZone(); // 2017-03-07T11:08:02-07:00 } From 536730273596bb1563c2b6cc8a23c82c4571d91f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 11 Jun 2020 19:14:39 +0200 Subject: [PATCH 204/581] Fix compile error --- tasmota/tasmota.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 49347f1f8..3d3811c89 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -214,7 +214,7 @@ enum WeekInMonthOptions {Last, First, Second, Third, Fourth}; enum DayOfTheWeekOptions {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat}; enum MonthNamesOptions {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; enum HemisphereOptions {North, South}; -enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_LOCALNOTZ, DT_DST, DT_STD, DT_RESTART, DT_ENERGY, DT_BOOTCOUNT }; +enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_LOCALNOTZ, DT_DST, DT_STD, DT_RESTART, DT_ENERGY, DT_BOOTCOUNT, DT_LOCAL_MILLIS }; enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; From 5427fc937e686f262ee96f2a3d3479cdb6006caf Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 11 Jun 2020 21:14:30 +0200 Subject: [PATCH 205/581] Fix Dimmer tele inconsistency when SO37 128 --- tasmota/xdrv_04_light.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 1d6ac6a58..a8eaf9629 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1555,10 +1555,10 @@ void LightState(uint8_t append) if (!Light.pwm_multi_channels) { if (unlinked) { // RGB and W are unlinked, we display the second Power/Dimmer - ResponseAppend_P(PSTR("\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "%d\":%d" - ",\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "%d\":%d"), - Light.device, GetStateText(Light.power & 1), Light.device, light_state.getDimmer(1), - Light.device + 1, GetStateText(Light.power & 2 ? 1 : 0), Light.device + 1, light_state.getDimmer(2)); + ResponseAppend_P(PSTR("\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "1\":%d" + ",\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "2\":%d"), + Light.device, GetStateText(Light.power & 1), light_state.getDimmer(1), + Light.device + 1, GetStateText(Light.power & 2 ? 1 : 0), light_state.getDimmer(2)); } else { GetPowerDevice(scommand, Light.device, sizeof(scommand), Settings.flag.device_index_enable); // SetOption26 - Switch between POWER or POWER1 ResponseAppend_P(PSTR("\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d"), scommand, GetStateText(Light.power & 1), From 03cd543127317f3984fea0cdc3149421128824ca Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 12 Jun 2020 12:38:52 +0200 Subject: [PATCH 206/581] Add support for HP303B Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/my_user_config.h | 1 + tasmota/tasmota_configurations.h | 1 + tasmota/xsns_73_hp303b.ino | 114 ++++++++++++++++--------------- 5 files changed, 62 insertions(+), 56 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ab01ddaa4..c1637501c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -77,3 +77,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for up to eight MCP9808 temperature sensors by device111 (#8594) - Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) - Add initial support for Telegram bot (#8619) +- Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 9033a2bba..0c6ef82bd 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,6 +3,7 @@ ### 8.3.1.3 20200611 - Add initial support for Telegram bot (#8619) +- Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) ### 8.3.1.2 20200522 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index ea2e6eefe..d6a140663 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -527,6 +527,7 @@ // #define USE_VEML6075 // [I2cDriver49] Enable VEML6075 UVA/UVB/UVINDEX Sensor (I2C address 0x10) (+2k1 code) // #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code) // #define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code) +// #define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) // #define USE_DISPLAY // Add I2C Display Support (+2k code) #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0 diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 811076d8f..ff81e486d 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -155,6 +155,7 @@ //#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) //#define USE_MCP9808 // Add support for MCP9808 temperature sensor (+0k9 code) +//#define USE_HP303B // Add support for HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) #define USE_ENERGY_SENSOR // Add energy sensors (-14k code) #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index 1be0a1606..0d9363409 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -16,58 +16,57 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ + #ifdef USE_I2C #ifdef USE_HP303B /*********************************************************************************************\ - * HP303B - Gas (TVOC - Total Volatile Organic Compounds) and Air Quality (CO2) + * HP303B - Pressure and temperature sensor * * Source: Lolin LOLIN_HP303B_Library * * I2C Address: 0x77 or 0x76 \*********************************************************************************************/ -#define XSNS_73 73 -#define XI2C_52 52 // See I2CDEVICES.md +#define XSNS_73 73 +#define XI2C_52 52 // See I2CDEVICES.md + +#define HP303B_MAX_SENSORS 2 +#define HP303B_START_ADDRESS 0x76 #include // HP303B Object LOLIN_HP303B HP303BSensor = LOLIN_HP303B(); -#define HP303B_MAX_SENSORS 2 -#define HP303B_START_ADDRESS 0x76 - struct { -char types[7] = "HP303B"; -uint8_t count = 0; -int16_t oversampling = 7; + int16_t oversampling = 7; + char types[7] = "HP303B"; + uint8_t count = 0; } hp303b_cfg; struct BHP303B { - uint8_t address; - uint8_t valid = 0; float temperature = NAN; float pressure = NAN; + uint8_t address; + uint8_t valid = 0; } hp303b_sensor[HP303B_MAX_SENSORS]; + /*********************************************************************************************/ -bool HP303B_Read(uint8_t hp303b_idx) -{ +bool HP303B_Read(uint32_t hp303b_idx) { if (hp303b_sensor[hp303b_idx].valid) { hp303b_sensor[hp303b_idx].valid--; } float t; + if (HP303BSensor.measureTempOnce(t, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling) != 0) { + return false; + } + float p; - int16_t ret; - - ret = HP303BSensor.measureTempOnce(t, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling); - if (ret != 0) - return false; - - ret = HP303BSensor.measurePressureOnce(p, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling); - if (ret != 0) + if (HP303BSensor.measurePressureOnce(p, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling) != 0) { return false; + } hp303b_sensor[hp303b_idx].temperature = (float)ConvertTemp(t); - hp303b_sensor[hp303b_idx].pressure = (float)ConvertPressure(p) / 100; //conversion to hPa + hp303b_sensor[hp303b_idx].pressure = (float)ConvertPressure(p / 100); // Conversion to hPa hp303b_sensor[hp303b_idx].valid = SENSOR_MAX_MISS; return true; @@ -75,14 +74,11 @@ bool HP303B_Read(uint8_t hp303b_idx) /********************************************************************************************/ -void HP303B_Detect(void) -{ - for (uint32_t i = 0; i < HP303B_MAX_SENSORS; i++) - { - if (!I2cSetDevice(HP303B_START_ADDRESS + i )) { continue; } +void HP303B_Detect(void) { + for (uint32_t i = 0; i < HP303B_MAX_SENSORS; i++) { + if (!I2cSetDevice(HP303B_START_ADDRESS + i)) { continue; } - if (HP303BSensor.begin(HP303B_START_ADDRESS + i)) - { + if (HP303BSensor.begin(HP303B_START_ADDRESS + i)) { hp303b_sensor[hp303b_cfg.count].address = HP303B_START_ADDRESS + i; I2cSetActiveFound(hp303b_sensor[hp303b_cfg.count].address, hp303b_cfg.types); hp303b_cfg.count++; @@ -90,50 +86,58 @@ void HP303B_Detect(void) } } -void HP303B_EverySecond(void) -{ +void HP303B_EverySecond(void) { for (uint32_t i = 0; i < hp303b_cfg.count; i++) { if (uptime &1) { - if (!HP303B_Read(i)) { - AddLogMissed(hp303b_cfg.types, hp303b_sensor[i].valid); + if (!HP303B_Read(i)) { + AddLogMissed(hp303b_cfg.types, hp303b_sensor[i].valid); + } } } - } } -void HP303B_Show(bool json) -{ +void HP303B_Show(bool json) { for (uint32_t i = 0; i < hp303b_cfg.count; i++) { - char sensor_name[12]; - strlcpy(sensor_name, hp303b_cfg.types, sizeof(sensor_name)); - if (hp303b_cfg.count > 1) { - snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c0x%02X"), sensor_name, IndexSeparator(), hp303b_sensor[i].address); // HP303B-0x76, HP303B-0x77 - } + if (hp303b_sensor[i].valid) { + char sensor_name[12]; + strlcpy(sensor_name, hp303b_cfg.types, sizeof(sensor_name)); + if (hp303b_cfg.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%02X"), sensor_name, IndexSeparator(), hp303b_sensor[i].address); // HP303B-76, HP303B-77 + } + + float sealevel = 0.0; + if (hp303b_sensor[i].pressure != 0.0) { + sealevel = (hp303b_sensor[i].pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; + sealevel = ConvertPressure(sealevel); + } - if (hp303b_sensor[i].valid) - { char str_temperature[33]; dtostrfd(hp303b_sensor[i].temperature, Settings.flag2.temperature_resolution, str_temperature); char str_pressure[33]; dtostrfd(hp303b_sensor[i].pressure, Settings.flag2.pressure_resolution, str_pressure); + char sea_pressure[33]; + dtostrfd(sealevel, Settings.flag2.pressure_resolution, sea_pressure); - if (json) - { + if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), sensor_name, str_temperature, str_pressure); + if (Settings.altitude != 0) { + ResponseAppend_P(PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure); + } ResponseJsonEnd(); - #ifdef USE_DOMOTICZ +#ifdef USE_DOMOTICZ // Domoticz and knx only support one temp sensor if ((0 == tele_period) && (0 == i)) { DomoticzSensor(DZ_TEMP, hp303b_sensor[i].temperature); } - #endif // USE_DOMOTICZ - #ifdef USE_WEBSERVER - } - else - { +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, str_temperature, TempUnit()); WSContentSend_PD(HTTP_SNS_PRESSURE, sensor_name, str_pressure, PressureUnit().c_str()); - #endif // USE_WEBSERVER + if (Settings.altitude != 0) { + WSContentSend_PD(HTTP_SNS_SEAPRESSURE, sensor_name, sea_pressure, PressureUnit().c_str()); + } +#endif // USE_WEBSERVER } } } @@ -152,10 +156,8 @@ bool Xsns73(uint8_t function) if (FUNC_INIT == function) { HP303B_Detect(); } - else if (hp303b_cfg.count) - { - switch (function) - { + else if (hp303b_cfg.count) { + switch (function) { case FUNC_EVERY_SECOND: HP303B_EverySecond(); break; From a97f391f91491dda1751311a41d3dd0c78d2c3e4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 12 Jun 2020 12:40:42 +0200 Subject: [PATCH 207/581] Update I2CDEVICES.md --- I2CDEVICES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/I2CDEVICES.md b/I2CDEVICES.md index 4f6718b90..b67cc9029 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -72,4 +72,5 @@ Index | Define | Driver | Device | Address(es) | Description 48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor 49 | USE_VEML6075 | xsns_70 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor 50 | USE_VEML7700 | xsns_71 | VEML7700 | 0x10 | Ambient light intensity sensor - 51 | USE_MCP9808 | xsns_72 | MCP9808 | 0x18 - 0x1F | Temperature sensor \ No newline at end of file + 51 | USE_MCP9808 | xsns_72 | MCP9808 | 0x18 - 0x1F | Temperature sensor + 52 | USE_HP303B | xsns_73 | HP303B | 0x76 - 0x77 | Pressure and temperature sensor \ No newline at end of file From 4afbbca7732b0a6d627cb9e3de3c00391798186e Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 16:28:57 +0200 Subject: [PATCH 208/581] Added French Smart Meter Teleinformation --- tasmota/language/bg_BG.h | 2 ++ tasmota/language/cs_CZ.h | 2 ++ tasmota/language/de_DE.h | 2 ++ tasmota/language/el_GR.h | 2 ++ tasmota/language/en_GB.h | 2 ++ tasmota/language/es_ES.h | 2 ++ tasmota/language/fr_FR.h | 2 ++ tasmota/language/he_HE.h | 2 ++ tasmota/language/hu_HU.h | 2 ++ tasmota/language/it_IT.h | 2 ++ tasmota/language/ko_KO.h | 2 ++ tasmota/language/nl_NL.h | 2 ++ tasmota/language/pl_PL.h | 2 ++ tasmota/language/pt_BR.h | 2 ++ tasmota/language/pt_PT.h | 2 ++ tasmota/language/ro_RO.h | 2 ++ tasmota/language/ru_RU.h | 2 ++ tasmota/language/sk_SK.h | 2 ++ tasmota/language/sv_SE.h | 2 ++ tasmota/language/tr_TR.h | 2 ++ tasmota/language/uk_UA.h | 2 ++ tasmota/language/zh_CN.h | 2 ++ tasmota/language/zh_TW.h | 2 ++ 23 files changed, 46 insertions(+) diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 935704e74..769b9f66a 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index a04a6b16b..64d8e32b0 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 02464daa6..7cc9d6579 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 333458c72..92769256f 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 92637b350..e5fc07fa5 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 701f3e107..ff2eda915 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index f91bd7fbd..38c160831 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 3550a1abd..59f2db4cb 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 1a58472e4..d976eecb4 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index f1af3765f..6fa190eed 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL - TX" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "Velocità vento" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index a004ecec7..a3a032086 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index ab6a28485..8ce2fc338 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index aea969baf..676297b48 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 02c4b4ecc..3babc17ec 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 4507cecba..2a0ad139f 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 66e82ad55..e80dc8bc4 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 7c7fc770b..a037ff08f 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index e242f9bc1..c016a0c8e 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 1649b7f5f..ff119f953 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 8a1063d7a..e744e97e8 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index a16675ae4..4d4e25f44 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 0da3126fd..b5f54991a 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 1fb664d08..1d5ed6801 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -679,6 +679,8 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" From 9a5f410c463e50259f272ae3200bde9626ed5fdd Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 16:30:59 +0200 Subject: [PATCH 209/581] Added French Smart Meter Teleinformation --- tasmota/tasmota_template.h | 10 +++++++++- tasmota/tasmota_template_ESP32.h | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 8b44a547b..552696577 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -234,6 +234,8 @@ enum UserSelectablePins { GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin GPIO_WINDMETER_SPEED, // WindMeter speed counter pin GPIO_BL0940_RX, // BL0940 serial interface + GPIO_TELEINFO_RX, // BL0940 serial interface + GPIO_TELEINFO_ENABLE, // BL0940 serial interface GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -324,7 +326,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX "|" D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" D_SENSOR_WINDMETER_SPEED "|" - D_SENSOR_BL0940_RX + D_SENSOR_BL0940_RX "|" + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE ; const char kSensorNamesFixed[] PROGMEM = @@ -682,6 +685,11 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_AS3935 GPIO_AS3935, #endif +#ifdef USE_TELEINFO + GPIO_TELEINFO_RX, + GPIO_TELEINFO_ENABLE, +#endif + }; /********************************************************************************************/ diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index aea45ea6a..bcb2d0f3e 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -129,6 +129,8 @@ enum UserSelectablePins { GPIO_WINDMETER_SPEED, // WindMeter speed counter pin GPIO_KEY1_TC, // Touch pin as button GPIO_BL0940_RX, // BL0940 serial interface + GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin + GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -218,7 +220,8 @@ const char kSensorNames[] PROGMEM = D_GPIO_WEBCAM_PSRCS "|" D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BUTTON "_tc|" - D_SENSOR_BL0940_RX + D_SENSOR_BL0940_RX "|" + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE ; const char kSensorNamesFixed[] PROGMEM = @@ -523,6 +526,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_AS3935 AGPIO(GPIO_AS3935), #endif +#ifdef USE_TELEINFO + AGPIO(GPIO_TELEINFO_RX), + AGPIO(GPIO_TELEINFO_ENABLE), +#endif /* #ifndef USE_ADC_VCC AGPIO(ADC0_INPUT), // Analog input From e7dd3e17565ad2cf0f281f6cd1faa50593d464cc Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 16:31:23 +0200 Subject: [PATCH 210/581] Created French Smart Meter Teleinformation --- tasmota/xnrg_15_teleinfo.ino | 197 +++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 tasmota/xnrg_15_teleinfo.ino diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino new file mode 100644 index 000000000..4ea6c06b8 --- /dev/null +++ b/tasmota/xnrg_15_teleinfo.ino @@ -0,0 +1,197 @@ +/* + xnrg_15_Teleinfo.ino - Teleinfo support for Tasmota + + Copyright (C) 2020 Charles-Henri Hallard + + 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_ENERGY_SENSOR +#ifdef USE_TELEINFO +/*********************************************************************************************\ + * Teleinfo : French energy provider metering telemety data + * Source: http://hallard.me/category/tinfo/ + * + * Hardware Serial will be selected if GPIO1 = [TELEINFO_RX] +\*********************************************************************************************/ + +#define XNRG_15 15 + +#include "LibTeleinfo.h" +#include + +#define TINFO_READ_TIMEOUT 400 // us; enough for 6 bytes@9600bps + +TInfo tinfo; // Teleinfo object +TasmotaSerial *TInfoSerial = nullptr; +bool tinfo_found = false; + +/*********************************************************************************************/ + +/* ====================================================================== +Function: ADPSCallback +Purpose : called by library when we detected a ADPS on any phased +Input : phase number + 0 for ADPS (monophase) + 1 for ADIR1 triphase + 2 for ADIR2 triphase + 3 for ADIR3 triphase +Output : - +Comments: should have been initialised in the main sketch with a + tinfo.attachADPSCallback(ADPSCallback()) +====================================================================== */ +void ADPSCallback(uint8_t phase) +{ + // n = phase number 1 to 3 + if (phase == 0) + phase = 1; + + AddLog_P2(LOG_LEVEL_INFO, PSTR("ADPS on phase %d"), phase); +} + +/* ====================================================================== +Function: DataCallback +Purpose : callback when we detected new or modified data received +Input : linked list pointer on the concerned data + current flags value +Output : - +Comments: - +====================================================================== */ +void DataCallback(struct _ValueList * me, uint8_t flags) +{ + char c = ' '; + + if (flags & TINFO_FLAGS_ADDED) { c = '#'; } + if (flags & TINFO_FLAGS_UPDATED) { c = '*'; } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: %c %s=%s"),c , me->name, me->value); +} + +void TInfoDrvInit(void) { + if (PinUsed(GPIO_TELEINFO_RX)) { + energy_flg = XNRG_15; + } +} + +void TInfoInit(void) +{ + #ifdef USE_TELEINFO_STANDARD + #define TINFO_SPEED 9600 + #else + #define TINFO_SPEED 1200 + #endif + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: inferface speed %d bps"),TINFO_SPEED); + + tinfo_found = false; + if (PinUsed(GPIO_TELEINFO_RX)) + { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: enable receive on GPIO%d"), GPIO_TELEINFO_RX); + // Enable Teleinfo + if (PinUsed(GPIO_TELEINFO_ENABLE)) + { + pinMode(GPIO_TELEINFO_ENABLE, OUTPUT); + digitalWrite(GPIO_TELEINFO_ENABLE, HIGH); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: enable on GPIO%d"), GPIO_TELEINFO_ENABLE); + } + else + { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: always enabled")); + } + + TInfoSerial = new TasmotaSerial(Pin(GPIO_TELEINFO_RX), -1, 1); + // pinMode(GPIO_TELEINFO_RX, INPUT_PULLUP); + + if (TInfoSerial->begin(TINFO_SPEED, SERIAL_7E1)) + { + if (TInfoSerial->hardwareSerial()) + ClaimSerial(); + TInfoSerial->setTimeout(TINFO_READ_TIMEOUT); + + // Init teleinfo + tinfo.init(); + + // Attach needed callbacks + tinfo.attachADPS(ADPSCallback); + tinfo.attachData(DataCallback); + + tinfo_found = true; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Ready")); + } + } +} + +void TInfoEvery250ms(void) +{ + char c; + if (!tinfo_found) + return; + + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: received %d chars"), TInfoSerial->available()); + + // We received some data? + while (TInfoSerial->available()>8) + { + // get char + c = TInfoSerial->read(); + // data processing + tinfo.process(c); + } +} + +void TInfoShow(bool json) +{ + // TBD + if (json) + { +#ifdef USE_WEBSERVER + } + else + { +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xnrg15(uint8_t function) +{ + + switch (function) + { + case FUNC_EVERY_250_MSECOND: + if (uptime > 4) { TInfoEvery250ms(); } + break; + case FUNC_JSON_APPEND: + TInfoShow(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + TInfoShow(0); + break; +#endif // USE_WEBSERVER + case FUNC_INIT: + TInfoInit(); + break; + case FUNC_PRE_INIT: + TInfoDrvInit(); + break; + } + return false; +} + +#endif // USE_TELEINFO +#endif // USE_ENERGY_SENSOR From acc67b9e9f7cf8d03b26286425ebdc88ce755b0d Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 16:31:36 +0200 Subject: [PATCH 211/581] Fix Debug --- lib/LibTeleinfo/src/LibTeleinfo.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/LibTeleinfo/src/LibTeleinfo.h b/lib/LibTeleinfo/src/LibTeleinfo.h index 00b5495c4..a9725b26a 100755 --- a/lib/LibTeleinfo/src/LibTeleinfo.h +++ b/lib/LibTeleinfo/src/LibTeleinfo.h @@ -25,6 +25,8 @@ #ifndef LibTeleinfo_h #define LibTeleinfo_h +#include "Arduino.h" + // Define this if you want library to be verbose //#define TI_DEBUG @@ -44,10 +46,10 @@ #define TI_Debugflush Serial.flush #endif #else - #define TI_Debug(x) - #define TI_Debugln(x) - #define TI_Debugf(...) - #define TI_Debugflush + #define TI_Debug(x) {} + #define TI_Debugln(x) {} + #define TI_Debugf(...) {} + #define TI_Debugflush {} #endif // For 4 bytes Aligment boundaries @@ -61,14 +63,15 @@ typedef struct _ValueList ValueList; struct _ValueList { ValueList *next; // next element - char * name; // LABEL of value name - char * value; // value uint8_t checksum;// checksum uint8_t flags; // specific flags + char * name; // LABEL of value name + char * value; // value }; #pragma pack(pop) + // Library state machine enum _State_e { TINFO_INIT, // We're in init @@ -95,6 +98,11 @@ enum _State_e { #define TINFO_SGR '\n' // start of group #define TINFO_EGR '\r' // End of group +typedef void (*_fn_ADPS) (uint8_t); +typedef void (*_fn_data) (ValueList *, uint8_t); +typedef void (*_fn_new_frame) (ValueList *); +typedef void (*_fn_updated_frame) (ValueList *); + class TInfo { public: From dbf4a3a205cea0782eac8078ae9a6f8ae67fedee Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 16:32:32 +0200 Subject: [PATCH 212/581] Added French Smart Meter Teleinformation --- tasmota/my_user_config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 6e20a598e..ae9a66c66 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -589,6 +589,8 @@ #define USE_TASMOTA_SLAVE_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants #define USE_TASMOTA_SLAVE_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) +#define USE_TELEINFO // Add support for Teleinfo via serial RX interface + //#define USE_TELEINFO_STANDARD // Use standard mode (9600 bps) else it's historical mode (1200 bps) // -- Power monitoring sensors -------------------- #define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) From 941e45ef4c72606b7ae350463f7b9ed95c301902 Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 16:33:16 +0200 Subject: [PATCH 213/581] Added French Smart Meter Teleinformation --- tasmota/support_features.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 20bb9acf3..3fcd029bf 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -575,7 +575,9 @@ void GetFeatures(void) #ifdef USE_BL0940 feature6 |= 0x00004000; // xnrg_14_bl0940.ino #endif -// feature6 |= 0x00008000; +#ifdef USE_TELEINFO + feature6 |= 0x00008000; // xnrg_15_teleinfo.ino +#endif // feature6 |= 0x00010000; // feature6 |= 0x00020000; From d64c0a8179500c6a668d4018661e19138496c2b9 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Fri, 12 Jun 2020 16:33:19 +0200 Subject: [PATCH 214/581] Update Italian language --- tasmota/language/it_IT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index f1af3765f..22181a7be 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -672,7 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 - TX" #define D_SENSOR_LE01MR_RX "LE-01MR - RX" #define D_SENSOR_LE01MR_TX "LE-01MR - TX" -#define D_SENSOR_BL0940_RX "BL0940 Rx" +#define D_SENSOR_BL0940_RX "BL0940 - Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 - GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 - GDO2" #define D_SENSOR_HRXL_RX "HRXL - RX" From 481576c35380c8b39e9299dcc807165a74bf680f Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 16:34:19 +0200 Subject: [PATCH 215/581] Added Include --- lib/LibTeleinfo/src/LibTeleinfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/LibTeleinfo/src/LibTeleinfo.cpp b/lib/LibTeleinfo/src/LibTeleinfo.cpp index b2d597f28..77db56e54 100644 --- a/lib/LibTeleinfo/src/LibTeleinfo.cpp +++ b/lib/LibTeleinfo/src/LibTeleinfo.cpp @@ -22,6 +22,7 @@ // // ********************************************************************************** +#include "Arduino.h" #include "LibTeleinfo.h" /* ====================================================================== From 0abfcf1954fa6d60fab5a63d04cfde8d4477a32f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 12 Jun 2020 16:51:21 +0200 Subject: [PATCH 216/581] Fix global temperature - Fix global temperature use of float solving intermittend power off (#8175) - Fix BL0940 power monitoring when powered on but no load present --- tasmota/support.ino | 6 +++--- tasmota/support_command.ino | 2 +- tasmota/tasmota.ino | 6 +++--- tasmota/xdrv_03_energy.ino | 7 ++++++- tasmota/xnrg_14_bl0940.ino | 15 +++++++++------ tasmota/xsns_21_sgp30.ino | 8 ++++---- tasmota/xsns_31_ccs811.ino | 4 +++- tasmota/xsns_91_prometheus.ino | 2 +- 8 files changed, 30 insertions(+), 20 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index b27cb072d..879a91fb0 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -687,9 +687,9 @@ void ResetGlobalValues(void) { if ((uptime - global_update) > GLOBAL_VALUES_VALID) { // Reset after 5 minutes global_update = 0; - global_temperature = 9999; - global_humidity = 0; - global_pressure = 0; + global_temperature = NAN; + global_humidity = 0.0f; + global_pressure = 0.0f; } } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index abda76482..fe855ee92 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -626,7 +626,7 @@ void CmndGlobalTemp(void) if (!isnan(temperature) && Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit temperature = (temperature - 32) / 1.8; // Celsius } - if ((temperature >= -50.0) && (temperature <= 100.0)) { + if ((temperature >= -50.0f) && (temperature <= 100.0f)) { ConvertTemp(temperature); global_update = 1; // Keep global values just entered valid } diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 78c50edc3..7ee0c8316 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -111,9 +111,9 @@ uint32_t uptime = 0; // Counting every second until 42949 uint32_t loop_load_avg = 0; // Indicative loop load average uint32_t global_update = 0; // Timestamp of last global temperature and humidity update uint32_t web_log_index = 1; // Index in Web log buffer (should never be 0) -float global_temperature = 9999; // Provide a global temperature to be used by some sensors -float global_humidity = 0; // Provide a global humidity to be used by some sensors -float global_pressure = 0; // Provide a global pressure to be used by some sensors +float global_temperature = NAN; // Provide a global temperature to be used by some sensors +float global_humidity = 0.0f; // Provide a global humidity to be used by some sensors +float global_pressure = 0.0f; // Provide a global pressure to be used by some sensors uint16_t tele_period = 9999; // Tele period timer uint16_t blink_counter = 0; // Number of blink cycles uint16_t seriallog_timer = 0; // Timer to disable Seriallog diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index f5e4a729d..bf9515b6a 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -459,7 +459,12 @@ void EnergyEverySecond(void) { // Overtemp check if (global_update) { - if (power && (global_temperature != 9999) && (global_temperature > Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays + if (power && !isnan(global_temperature) && (global_temperature > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays + + char temperature[33]; + dtostrfd(global_temperature, 1, temperature); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %s"), temperature); + SetAllPower(POWER_ALL_OFF, SRC_OVERTEMP); } } diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index 655f3d8df..bfdbac232 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -83,17 +83,20 @@ void Bl0940Received(void) { return; } - Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10]; - Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4]; - Bl0940.power = Bl0940.rx_buffer[18] << 16 | Bl0940.rx_buffer[17] << 8 | Bl0940.rx_buffer[16]; -// Bl0940.cf_pulses = Bl0940.rx_buffer[24] << 16 | Bl0940.rx_buffer[23] << 8 | Bl0940.rx_buffer[22]; - uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; + Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10]; // V_RMS unsigned + Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4]; // I_RMS unsigned + int32_t power = Bl0940.rx_buffer[18] << 24 | Bl0940.rx_buffer[17] << 16 | Bl0940.rx_buffer[16] << 8; // WATT signed + Bl0940.power = abs(power) >> 8; // WATT unsigned +// Bl0940.cf_pulses = Bl0940.rx_buffer[24] << 16 | Bl0940.rx_buffer[23] << 8 | Bl0940.rx_buffer[22]; // CF_CNT unsigned + uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; // TPS1 unsigned float t = ((170.0f/448.0f)*(((float)tps1/2.0f)-32.0f))-45.0f; Bl0940.temperature = ConvertTemp(t); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: U %d, I %d, P %d, T %d"), Bl0940.voltage, Bl0940.current, Bl0940.power, tps1); + if (Energy.power_on) { // Powered on Energy.voltage[0] = (float)Bl0940.voltage / Settings.energy_voltage_calibration; - if (power != 0) { + if (power && (Bl0940.power > Settings.energy_power_calibration)) { // We need at least 1W Energy.active_power[0] = (float)Bl0940.power / Settings.energy_power_calibration; Energy.current[0] = (float)Bl0940.current / (Settings.energy_current_calibration * 100); } else { diff --git a/tasmota/xsns_21_sgp30.ino b/tasmota/xsns_21_sgp30.ino index ab417a8c3..ec1e85258 100644 --- a/tasmota/xsns_21_sgp30.ino +++ b/tasmota/xsns_21_sgp30.ino @@ -87,7 +87,7 @@ void Sgp30Update(void) // Perform every second to ensure proper operation of th if (!sgp.IAQmeasure()) { return; // Measurement failed } - if (global_update && (global_humidity > 0) && (global_temperature != 9999)) { + if (global_update && (global_humidity > 0) && !isnan(global_temperature)) { // abs hum in mg/m3 sgp30_abshum=sgp30_AbsoluteHumidity(global_temperature,global_humidity,TempUnit()); sgp.setHumidity(sgp30_abshum*1000); @@ -118,14 +118,14 @@ void Sgp30Show(bool json) { if (sgp30_ready) { char abs_hum[33]; - - if (global_update && global_humidity>0 && global_temperature!=9999) { + + if (global_update && (global_humidity > 0) && !isnan(global_temperature)) { // has humidity + temperature dtostrfd(sgp30_abshum,4,abs_hum); } if (json) { ResponseAppend_P(PSTR(",\"SGP30\":{\"" D_JSON_ECO2 "\":%d,\"" D_JSON_TVOC "\":%d"), sgp.eCO2, sgp.TVOC); - if (global_update && global_humidity>0 && global_temperature!=9999) { + if (global_update && global_humidity>0 && !isnan(global_temperature)) { ResponseAppend_P(PSTR(",\"" D_JSON_AHUM "\":%s"),abs_hum); } ResponseJsonEnd(); diff --git a/tasmota/xsns_31_ccs811.ino b/tasmota/xsns_31_ccs811.ino index a968319cb..aada03d04 100644 --- a/tasmota/xsns_31_ccs811.ino +++ b/tasmota/xsns_31_ccs811.ino @@ -65,7 +65,9 @@ void CCS811Update(void) // Perform every n second TVOC = ccs.getTVOC(); eCO2 = ccs.geteCO2(); CCS811_ready = 1; - if (global_update && global_humidity>0 && global_temperature!=9999) { ccs.setEnvironmentalData((uint8_t)global_humidity, global_temperature); } + if (global_update && (global_humidity > 0) && !isnan(global_temperature)) { + ccs.setEnvironmentalData((uint8_t)global_humidity, global_temperature); + } ecnt = 0; } } else { diff --git a/tasmota/xsns_91_prometheus.ino b/tasmota/xsns_91_prometheus.ino index f5b0eba9d..2a361b550 100644 --- a/tasmota/xsns_91_prometheus.ino +++ b/tasmota/xsns_91_prometheus.ino @@ -37,7 +37,7 @@ void HandleMetrics(void) char parameter[FLOATSZ]; - if (global_temperature != 9999) { + if (!isnan(global_temperature)) { dtostrfd(global_temperature, Settings.flag2.temperature_resolution, parameter); WSContentSend_P(PSTR("# TYPE global_temperature gauge\nglobal_temperature %s\n"), parameter); } From 2b327c96c99448850690ff16fe5126506ee89361 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 12 Jun 2020 17:42:04 +0200 Subject: [PATCH 217/581] Fix BL0940 invalid overtemp Fix BL0940 invalid overtemp (#8175) --- tasmota/xnrg_14_bl0940.ino | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index bfdbac232..61dd8b808 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -60,6 +60,7 @@ struct BL0940 { float temperature; int byte_counter = 0; + uint16_t tps1 = 0; uint8_t *rx_buffer = nullptr; bool received = false; } Bl0940; @@ -78,21 +79,25 @@ void Bl0940Received(void) { // 55 B9 33 00 DE 45 00 94 02 00 CF E4 70 63 02 00 6C 4C 00 13 01 00 09 00 00 00 00 00 E4 01 00 FE 03 00 72 // Hd IFRms--- Current- Reserved Voltage- Reserved Power--- Reserved CF------ Reserved TPS1---- TPS2---- Ck - if (Bl0940.rx_buffer[0] != BL0940_PACKET_HEADER) { + uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; // TPS1 unsigned + if ((Bl0940.rx_buffer[0] != BL0940_PACKET_HEADER) || // Bad header + (Bl0940.tps1 && ((tps1 < (Bl0940.tps1 -10)) || (tps1 > (Bl0940.tps1 +10)))) // Invalid temperature change + ) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: Invalid data")); return; } + Bl0940.tps1 = tps1; + float t = ((170.0f/448.0f)*(((float)Bl0940.tps1/2.0f)-32.0f))-45.0f; + Bl0940.temperature = ConvertTemp(t); + Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10]; // V_RMS unsigned Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4]; // I_RMS unsigned int32_t power = Bl0940.rx_buffer[18] << 24 | Bl0940.rx_buffer[17] << 16 | Bl0940.rx_buffer[16] << 8; // WATT signed Bl0940.power = abs(power) >> 8; // WATT unsigned // Bl0940.cf_pulses = Bl0940.rx_buffer[24] << 16 | Bl0940.rx_buffer[23] << 8 | Bl0940.rx_buffer[22]; // CF_CNT unsigned - uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; // TPS1 unsigned - float t = ((170.0f/448.0f)*(((float)tps1/2.0f)-32.0f))-45.0f; - Bl0940.temperature = ConvertTemp(t); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: U %d, I %d, P %d, T %d"), Bl0940.voltage, Bl0940.current, Bl0940.power, tps1); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: U %d, I %d, P %d, T %d"), Bl0940.voltage, Bl0940.current, Bl0940.power, Bl0940.tps1); if (Energy.power_on) { // Powered on Energy.voltage[0] = (float)Bl0940.voltage / Settings.energy_voltage_calibration; From 6cbae1fafe71049ecc331cb51e4343c657485d9e Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 21:53:12 +0200 Subject: [PATCH 218/581] Added French Metering Teleinfo --- BUILDS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILDS.md b/BUILDS.md index 7e642de4e..91bbd287e 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -68,6 +68,7 @@ | USE_DDSU666 | - | - | - | - | x | - | - | | USE_SOLAX_X1 | - | - | - | - | - | - | - | | USE_LE01MR | - | - | - | - | - | - | - | +| USE_TELEINFO | - | - | - | - | - | - | - | | | | | | | | | | | USE_ADC_VCC | x | x | - | - | - | - | - | | USE_COUNTER | - | - | x | x | x | x | x | From 4929d3c8e5b16347776bb338b6a99f824e554c39 Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 21:53:26 +0200 Subject: [PATCH 219/581] Added French Metering Teleinfo --- RELEASENOTES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index fdac7edde..fa35311dd 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -54,6 +54,8 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ### Version 8.3.1.2 +- Created Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff +- Added Library to be used for decoding Teleinfo (French Metering Smart Meter) - Change IRremoteESP8266 library updated to v2.7.7 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` From 6d38a67cdad5eb72eb94b4033e06a2b65fb5ad61 Mon Sep 17 00:00:00 2001 From: Charles Date: Fri, 12 Jun 2020 21:53:54 +0200 Subject: [PATCH 220/581] Added deviice Denky for French Metering Teleinfo --- tasmota/tasmota_template.h | 28 +++++++++++++++++++++++++--- tasmota/tasmota_template_ESP32.h | 7 ++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 552696577..a0146aece 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -777,8 +777,8 @@ enum SupportedModules { SUPLA1, WITTY, YUNSHAN, MAGICHOME, LUANIHVIO, KMC_70011, ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, ARILUX_LC06, SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH, OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4, - OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, - SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, + OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, + SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, DENKY, MAXMODULE}; #define USER_MODULE 255 @@ -791,7 +791,7 @@ const char kModuleNames[] PROGMEM = "Sonoff S31|Zengge WF017|Sonoff Pow R2|Sonoff iFan02|BlitzWolf SHP|Shelly 1|Shelly 2|Xiaomi Philips|Neo Coolcam|ESP Switch|" "OBI Socket|Teckin|AplicWDP303075|Tuya MCU|Gosund SP1 v23|ARMTR Dimmer|SK03 Outdoor|PS-16-DZ|Teckin US|Manzoku strip|" "OBI Socket 2|YTF IR Bridge|Digoo DG-SP202|KA10|Luminea ZX2820|Mi Desk Lamp|SP10|WAGA CHCZ02MB|SYF05|Sonoff L1|" - "Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1" + "Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1|Denky (Teleinfo)" ; const uint8_t kModuleNiceList[] PROGMEM = { @@ -2174,6 +2174,26 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_LED1_INV, // GPIO13 WiFi Blue Led - Link and Power status 0, 0, 0, 0 }, + { // Denky (Teleinfo) Any ESP8266 device + GPIO_WS2812, // GPIO00 WS2812 RGB LED + GPIO_USER, // GPIO01 TX Serial RXD + GPIO_USER, // GPIO02 D4 Wemos DHT Shield + GPIO_TELEINFO_RX, // GPIO03 Smart Meter RX Serial + GPIO_I2C_SDA, // GPIO04 D2 Wemos I2C SDA + GPIO_I2C_SCL, // GPIO05 D1 Wemos I2C SCL + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + GPIO_USER, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + GPIO_USER, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPIO_USER, // GPIO12 D6 + GPIO_USER, // GPIO13 D7 + GPIO_USER, // GPIO14 D5 + GPIO_USER, // GPIO15 D8 + GPIO_USER, // GPIO16 D0 Wemos Wake + ADC0_USER // ADC0 A0 Analog input + }, { // SONOFF_IFAN03 - Sonoff iFan03 (ESP8285) GPIO_KEY1, // GPIO00 WIFI_KEY0 Button 1 GPIO_TXD, // GPIO01 ESP_TXD Serial RXD connection to P0.5 of RF microcontroller @@ -2258,8 +2278,10 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_LED1_INV, // GPIO13 WiFi Blue Led - Link and Power status 0, 0, 0, 0 } + }; + #endif // ESP8266 #ifdef ESP32 diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index bcb2d0f3e..f6424bfbf 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -610,18 +610,19 @@ typedef struct MYTMPLT { /********************************************************************************************/ // Supported hardware modules enum SupportedModules { - WEMOS, ESP32_CAM_AITHINKER, + WEMOS, ESP32_CAM_AITHINKER, ESP32_DENKY, MAXMODULE}; #define USER_MODULE 255 const char kModuleNames[] PROGMEM = - "ESP32-DevKit|ESP32 Cam AiThinker"; + "ESP32-DevKit|ESP32 Cam AiThinker|Denky (Teleinfo)"; // Default module settings const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { WEMOS, - ESP32_CAM_AITHINKER + ESP32_CAM_AITHINKER, + ESP32_DENKY }; const mytmplt kModules PROGMEM = From 6fd972d7a80dd5a3f23836e98987265b8b11fe2c Mon Sep 17 00:00:00 2001 From: Charles Date: Sat, 13 Jun 2020 02:18:01 +0200 Subject: [PATCH 221/581] Bumped to version 1.1.1 --- lib/LibTeleinfo/library.json | 2 +- lib/LibTeleinfo/library.properties | 2 +- lib/LibTeleinfo/src/LibTeleinfo.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/LibTeleinfo/library.json b/lib/LibTeleinfo/library.json index 068618ce0..70f368653 100755 --- a/lib/LibTeleinfo/library.json +++ b/lib/LibTeleinfo/library.json @@ -1,6 +1,6 @@ { "name": "LibTeleinfo", - "version": "1.1.0", + "version": "1.1.1", "keywords": "teleinfo, french, meter, power, erdf, linky, tic", "description": "Decoder for Teleinfo (aka TIC) from French smart power meters", "repository": diff --git a/lib/LibTeleinfo/library.properties b/lib/LibTeleinfo/library.properties index 2420c5fc2..fdcee4a25 100755 --- a/lib/LibTeleinfo/library.properties +++ b/lib/LibTeleinfo/library.properties @@ -1,5 +1,5 @@ name=LibTeleinfo -version=1.1.0 +version=1.1.1 author=Charles-Henri Hallard maintainer=Charles-Henri Hallard sentence=Decoder for Teleinfo (aka TIC) from French smart power meters diff --git a/lib/LibTeleinfo/src/LibTeleinfo.cpp b/lib/LibTeleinfo/src/LibTeleinfo.cpp index 77db56e54..8d34e89d1 100644 --- a/lib/LibTeleinfo/src/LibTeleinfo.cpp +++ b/lib/LibTeleinfo/src/LibTeleinfo.cpp @@ -212,9 +212,9 @@ ValueList * TInfo::valueAdd(char * name, char * value, uint8_t checksum, uint8_t me = me->next; // Check if we already have this LABEL (same name AND same size) - if (lgname==strlen(me->name) && strncmp(me->name, name, lgname)==0) { + if (lgname==strlen(me->name) && strcmp(me->name, name)==0) { // Already got also this value return US - if (lgvalue==strlen(me->value) && strncmp(me->value, value, lgvalue) == 0) { + if (lgvalue==strlen(me->value) && strcmp(me->value, value) == 0) { *flags |= TINFO_FLAGS_EXIST; me->flags = *flags; return ( me ); @@ -225,7 +225,7 @@ ValueList * TInfo::valueAdd(char * name, char * value, uint8_t checksum, uint8_t // Do we have enought space to hold new value ? if (strlen(me->value) >= lgvalue ) { // Copy it - strlcpy(me->value, value , lgvalue ); + strlcpy(me->value, value , lgvalue + 1 ); me->checksum = checksum ; // That's all From 57ffd2715364015fd00c979206017bbe8b75d55a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 13 Jun 2020 12:26:55 +0200 Subject: [PATCH 222/581] Alternative method of calculating energy usage Alternative method of calculating energy usage (#8175) --- tasmota/xnrg_14_bl0940.ino | 58 ++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index 61dd8b808..d9bc51db8 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -33,6 +33,8 @@ #define BL0940_UREF 33000 #define BL0940_IREF 2750 +#define BL0940_PULSES_NOT_INITIALIZED -1 + #define BL0940_BUFFER_SIZE 36 #define BL0940_WRITE_COMMAND 0xA0 // 0xA8 according to documentation @@ -55,8 +57,11 @@ struct BL0940 { long voltage = 0; long current = 0; long power = 0; -// long power_cycle_first = 0; -// long cf_pulses = 0; + + long power_cycle_first = 0; + long cf_pulses = 0; + long cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; + float temperature; int byte_counter = 0; @@ -79,9 +84,9 @@ void Bl0940Received(void) { // 55 B9 33 00 DE 45 00 94 02 00 CF E4 70 63 02 00 6C 4C 00 13 01 00 09 00 00 00 00 00 E4 01 00 FE 03 00 72 // Hd IFRms--- Current- Reserved Voltage- Reserved Power--- Reserved CF------ Reserved TPS1---- TPS2---- Ck - uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; // TPS1 unsigned - if ((Bl0940.rx_buffer[0] != BL0940_PACKET_HEADER) || // Bad header - (Bl0940.tps1 && ((tps1 < (Bl0940.tps1 -10)) || (tps1 > (Bl0940.tps1 +10)))) // Invalid temperature change + uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; // TPS1 unsigned + if ((Bl0940.rx_buffer[0] != BL0940_PACKET_HEADER) || // Bad header + (Bl0940.tps1 && ((tps1 < (Bl0940.tps1 -10)) || (tps1 > (Bl0940.tps1 +10)))) // Invalid temperature change ) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: Invalid data")); return; @@ -91,17 +96,19 @@ void Bl0940Received(void) { float t = ((170.0f/448.0f)*(((float)Bl0940.tps1/2.0f)-32.0f))-45.0f; Bl0940.temperature = ConvertTemp(t); - Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10]; // V_RMS unsigned - Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4]; // I_RMS unsigned - int32_t power = Bl0940.rx_buffer[18] << 24 | Bl0940.rx_buffer[17] << 16 | Bl0940.rx_buffer[16] << 8; // WATT signed - Bl0940.power = abs(power) >> 8; // WATT unsigned -// Bl0940.cf_pulses = Bl0940.rx_buffer[24] << 16 | Bl0940.rx_buffer[23] << 8 | Bl0940.rx_buffer[22]; // CF_CNT unsigned + Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10]; // V_RMS unsigned + Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4]; // I_RMS unsigned + int32_t power = Bl0940.rx_buffer[18] << 24 | Bl0940.rx_buffer[17] << 16 | Bl0940.rx_buffer[16] << 8; // WATT signed + Bl0940.power = abs(power) >> 8; // WATT unsigned + int32_t cf_cnt = Bl0940.rx_buffer[24] << 24 | Bl0940.rx_buffer[23] << 16 | Bl0940.rx_buffer[22] << 8; // CF_CNT signed + Bl0940.cf_pulses = abs(cf_cnt) >> 8; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: U %d, I %d, P %d, T %d"), Bl0940.voltage, Bl0940.current, Bl0940.power, Bl0940.tps1); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: U %d, I %d, P %d, C %d, T %d"), + Bl0940.voltage, Bl0940.current, Bl0940.power, Bl0940.cf_pulses, Bl0940.tps1); if (Energy.power_on) { // Powered on Energy.voltage[0] = (float)Bl0940.voltage / Settings.energy_voltage_calibration; - if (power && (Bl0940.power > Settings.energy_power_calibration)) { // We need at least 1W + if (power && (Bl0940.power > Settings.energy_power_calibration)) { // We need at least 1W Energy.active_power[0] = (float)Bl0940.power / Settings.energy_power_calibration; Energy.current[0] = (float)Bl0940.current / (Settings.energy_current_calibration * 100); } else { @@ -163,10 +170,37 @@ void Bl0940EverySecond(void) { Bl0940.current = 0; Bl0940.power = 0; } else { +/* + // Calculate energy by using active power if (Energy.active_power[0]) { Energy.kWhtoday_delta += (Energy.active_power[0] * 1000) / 36; EnergyUpdateToday(); } +*/ + // Calculate energy by using active energy pulse count + if (BL0940_PULSES_NOT_INITIALIZED == Bl0940.cf_pulses_last_time) { + Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; // Init after restart + } else { + uint32_t cf_pulses = 0; + if (Bl0940.cf_pulses < Bl0940.cf_pulses_last_time) { // Rolled over after 0xFFFFFF (16777215) pulses + cf_pulses = (0x1000000 - Bl0940.cf_pulses_last_time) + Bl0940.cf_pulses; + } else { + cf_pulses = Bl0940.cf_pulses - Bl0940.cf_pulses_last_time; + } + if (cf_pulses && Energy.active_power[0]) { + if (cf_pulses < 16) { // max load for SHP10: 4.00kW (3.68kW) + uint32_t watt256 = (1638400 * 256) / Settings.energy_power_calibration; + uint32_t delta = (cf_pulses * watt256) / 36; + Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; + Energy.kWhtoday_delta += delta; + } else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: Overload")); + Bl0940.cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; + } + EnergyUpdateToday(); + } + } + } Bl0940Serial->flush(); From fcc0a29909779ab492a7c1ac34ac37dba1351e3b Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 13 Jun 2020 13:05:25 +0200 Subject: [PATCH 223/581] scripter support for global vars --- tasmota/xdrv_10_scripter.ino | 247 +++++++++++++++++++++++++++++++++-- 1 file changed, 236 insertions(+), 11 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 4d0bc1588..35427e67a 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -26,7 +26,6 @@ uses about 17 k of flash to do optimize code for space -g:var gloabal vars (via udp broadcast) remarks @@ -237,7 +236,11 @@ extern VButton *buttons[MAXBUTTONS]; #endif typedef union { +#ifdef USE_SCRIPT_GLOBVARS + uint16_t data; +#else uint8_t data; +#endif struct { uint8_t is_string : 1; // string or number uint8_t is_permanent : 1; @@ -247,6 +250,9 @@ typedef union { uint8_t settable : 1; uint8_t is_filter : 1; uint8_t constant : 1; +#ifdef USE_SCRIPT_GLOBVARS + uint8_t global : 1; +#endif }; } SCRIPT_TYPE; @@ -276,6 +282,32 @@ typedef union { }; } FILE_FLAGS; +typedef union { + uint8_t data; + struct { + uint8_t nutu8 : 1; + uint8_t nutu7 : 1; + uint8_t nutu6 : 1; + uint8_t nutu5 : 1; + uint8_t nutu4 : 1; + uint8_t nutu3 : 1; + uint8_t udp_connected : 1; + uint8_t udp_used : 1; + }; +} UDP_FLAGS; + + +#define NUM_RES 0xfe +#define STR_RES 0xfd +#define VAR_NV 0xff + +#define NTYPE 0 +#define STYPE 0x80 + +#ifndef FLT_MAX +#define FLT_MAX 99999999 +#endif + #define SFS_MAX 4 // global memory struct SCRIPT_MEM { @@ -308,12 +340,19 @@ struct SCRIPT_MEM { uint8_t script_sd_found; char flink[2][14]; #endif +#ifdef USE_SCRIPT_GLOBVARS + UDP_FLAGS udp_flags; +#endif } glob_script_mem; +#ifdef USE_SCRIPT_GLOBVARS +IPAddress last_udp_ip; +#endif int16_t last_findex; uint8_t tasm_cmd_activ=0; uint8_t fast_script=0; +uint8_t glob_script=0; uint32_t script_lastmillis; @@ -436,6 +475,16 @@ char *script; } else { vtypes[vars].bits.is_autoinc=0; } + +#ifdef USE_SCRIPT_GLOBVARS + if (*lp=='g' && *(lp+1)==':') { + lp+=2; + vtypes[vars].bits.global=1; + glob_script_mem.udp_flags.udp_used = 1; + } else { + vtypes[vars].bits.global=0; + } +#endif if ((*lp=='m' || *lp=='M') && *(lp+1)==':') { uint8_t flg=*lp; lp+=2; @@ -703,10 +752,112 @@ char *script; // store start of actual program here glob_script_mem.scriptptr=lp-1; glob_script_mem.scriptptr_bu=glob_script_mem.scriptptr; + +#ifdef USE_SCRIPT_GLOBVARS + if (glob_script_mem.udp_flags.udp_used) { + Script_Init_UDP(); + glob_script=Run_Scripter(">G",-2,0); + } +#endif + return 0; } +#ifdef USE_SCRIPT_GLOBVARS +#define SCRIPT_UDP_BUFFER_SIZE 128 +#define SCRIPT_UDP_PORT 1999 +IPAddress script_udp_remote_ip; + +void Script_Init_UDP() { + if (global_state.wifi_down) return; + if (glob_script_mem.udp_flags.udp_connected) return; + + if (PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), SCRIPT_UDP_PORT)) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP started")); + glob_script_mem.udp_flags.udp_connected = 1; + } else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP failed")); + glob_script_mem.udp_flags.udp_connected = 0; + } +} +void Script_PollUdp(void) { + if (!glob_script_mem.udp_flags.udp_used) return; + if (glob_script_mem.udp_flags.udp_connected ) { + while (PortUdp.parsePacket()) { + char packet_buffer[SCRIPT_UDP_BUFFER_SIZE]; + int32_t len = PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE -1); + packet_buffer[len] = 0; + script_udp_remote_ip = PortUdp.remoteIP(); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %s"), packet_buffer, len, script_udp_remote_ip.toString().c_str()); + char *lp=packet_buffer; + if (!strncmp(lp,"=>",2)) { + lp+=2; + char *cp=strchr(lp,'='); + if (cp) { + char vnam[32]; + for (uint32_t count=0; countG",2,0); + } + } + } + } + optimistic_yield(100); + } + } else { + Script_Init_UDP(); + } +} + +void script_udp_sendvar(char *vname,float *fp,char *sp) { + if (!glob_script_mem.udp_flags.udp_used) return; + if (!glob_script_mem.udp_flags.udp_connected) return; + + char sbuf[SCRIPT_MAXSSIZE+4]; + strcpy(sbuf,"=>"); + strcat(sbuf,vname); + strcat(sbuf,"="); + if (fp) { + char flstr[16]; + dtostrfd(*fp,8,flstr); + strcat(sbuf,flstr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("num var updated - %s"),sbuf); + } else { + strcat(sbuf,sp); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("string var updated - %s"),sbuf); + } + PortUdp.beginPacket(IPAddress(239,255,255,250), SCRIPT_UDP_PORT); + // Udp.print(String("RET UC: ") + String(recv_Packet)); + PortUdp.write((const uint8_t*)sbuf,strlen(sbuf)); + PortUdp.endPacket(); +} + +#endif + #ifdef USE_LIGHT #ifdef USE_WS2812 void ws2812_set_array(float *array ,uint32_t len, uint32_t offset) { @@ -723,16 +874,7 @@ void ws2812_set_array(float *array ,uint32_t len, uint32_t offset) { #endif #endif -#define NUM_RES 0xfe -#define STR_RES 0xfd -#define VAR_NV 0xff -#define NTYPE 0 -#define STYPE 0x80 - -#ifndef FLT_MAX -#define FLT_MAX 99999999 -#endif float median_array(float *array,uint8_t len) { uint8_t ind[len]; @@ -1011,6 +1153,37 @@ uint32_t MeasurePulseTime(int32_t in) { } #endif // USE_ANGLE_FUNC +#ifdef USE_SCRIPT_GLOBVARS +uint32_t match_vars(char *dvnam, float **fp, char **sp, uint32_t *ind) { + uint16_t olen=strlen(dvnam); + struct T_INDEX *vtp=glob_script_mem.type; + for (uint32_t count=0; count ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number // no flash strings here for performance reasons!!! char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,JsonObject *jo) { @@ -1765,12 +1938,40 @@ chknext: len=0; goto exit; } + if (!strncmp(vname,"is(",3)) { + lp=GetNumericResult(lp+3,OPER_EQU,&fvar,0); + SCRIPT_SKIP_SPACES + if (*lp!='"') { + break; + } + lp++; + char *sstr=lp; + for (uint32_t cnt=0; cnt<256; cnt++) { + if (lp[cnt]='\n' || lp[cnt]=='"') { + lp+=cnt+1; + break; + } + } + char str[SCRIPT_MAXSSIZE]; + GetTextIndexed(str, sizeof(str), fvar, sstr); + lp++; + if (sp) strlcpy(sp,str,glob_script_mem.max_ssize); + fvar=0; + len=0; + goto exit; + } break; case 'l': if (!strncmp(vname,"lip",3)) { if (sp) strlcpy(sp,(const char*)WiFi.localIP().toString().c_str(),glob_script_mem.max_ssize); goto strexit; } +#ifdef USE_SCRIPT_GLOBVARS + if (!strncmp(vname,"luip",4)) { + if (sp) strlcpy(sp,IPAddressToString(last_udp_ip),glob_script_mem.max_ssize); + goto strexit; + } +#endif if (!strncmp(vname,"loglvl",6)) { fvar=glob_script_mem.script_loglevel; tind->index=SCRIPT_LOGLEVEL; @@ -3167,7 +3368,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { if (!if_exe[ifstck] && if_state[ifstck]!=1) goto next_line; #ifdef IFTHEN_DEBUG - sprintf(tbuff,"stack=%d,exe=%d,state=%d,cmpres=%d execute line: ",ifstck,if_exe[ifstck],if_state[ifstck],if_result[ifstck]); + sdtoff(tbuff,"stack=%d,exe=%d,state=%d,cmpres=%d execute line: ",ifstck,if_exe[ifstck],if_state[ifstck],if_result[ifstck]); toLogEOL(tbuff,lp); #endif @@ -3382,8 +3583,16 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { } goto next_line; } else { + char *vnp=lp; lp=isvar(lp,&vtype,&ind,&sysvar,0,0); if (vtype!=VAR_NV) { +#ifdef USE_SCRIPT_GLOBVARS + char varname[16]; + uint32_t vnl=(uint32_t)lp-(uint32)vnp; + strncpy(varname,vnp,vnl); + varname[vnl]=0; +#endif + // found variable as result globvindex=ind.index; // save destination var index here globaindex=last_findex; @@ -3451,6 +3660,11 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { } // var was changed glob_script_mem.type[globvindex].bits.changed=1; +#ifdef USE_SCRIPT_GLOBVARS + if (glob_script_mem.type[globvindex].bits.global) { + script_udp_sendvar(varname,dfvar,0); + } +#endif if (glob_script_mem.type[globvindex].bits.is_filter) { if (globaindex>=0) { Set_MFVal(glob_script_mem.type[globvindex].index,globaindex,*dfvar); @@ -3492,6 +3706,11 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { if (!glob_script_mem.var_not_found) { // var was changed glob_script_mem.type[globvindex].bits.changed=1; +#ifdef USE_SCRIPT_GLOBVARS + if (glob_script_mem.type[globvindex].bits.global) { + script_udp_sendvar(varname,0,str); + } +#endif if (lastop==OPER_EQU) { strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); } else if (lastop==OPER_PLSEQU) { @@ -6136,6 +6355,12 @@ bool Xdrv10(uint8_t function) break; #endif +#ifdef USE_SCRIPT_GLOBVARS + case FUNC_LOOP: + Script_PollUdp(); + break; +#endif + } return result; } From 1e577a8213d6e7724624dcdbd41183d56e919a2b Mon Sep 17 00:00:00 2001 From: device111 <48546979+device111@users.noreply.github.com> Date: Sat, 13 Jun 2020 15:08:52 +0200 Subject: [PATCH 224/581] Fix VEML7700 lux measurement, add new command --- tasmota/xsns_71_veml7700.ino | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/tasmota/xsns_71_veml7700.ino b/tasmota/xsns_71_veml7700.ino index 3869e72d6..695e35824 100644 --- a/tasmota/xsns_71_veml7700.ino +++ b/tasmota/xsns_71_veml7700.ino @@ -40,27 +40,27 @@ const char JSON_SNS_VEML7700[] PROGMEM = ",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d #define D_CMND_VEML7700_PWR "power" #define D_CMND_VEML7700_GAIN "gain" #define D_CMND_VEML7700_INTTIME "inttime" +#define D_CMND_VEML7700_PERSIST "persist" const char S_JSON_VEML7700_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_VEML7700 "\":{\"%s\":%d}}"; -const char kVEML7700_Commands[] PROGMEM = D_CMND_VEML7700_PWR "|" D_CMND_VEML7700_GAIN "|" D_CMND_VEML7700_INTTIME; +const char kVEML7700_Commands[] PROGMEM = D_CMND_VEML7700_PWR "|" D_CMND_VEML7700_GAIN "|" D_CMND_VEML7700_INTTIME "|" D_CMND_VEML7700_PERSIST; enum VEML7700_Commands { // commands for Console CMND_VEML7700_PWR, CMND_VEML7700_GAIN, CMND_VEML7700_SET_IT, - }; + CMND_VEML7700_PERSIST, +}; struct VEML7700STRUCT { + bool active = 0; char types[9] = D_NAME_VEML7700; uint8_t address = VEML7700_I2CADDR_DEFAULT; - //uint16_t lux = 0; - //uint16_t white = 0; - uint16_t lux_normalized = 0; - uint16_t white_normalized = 0; + uint32_t lux_normalized = 0; + uint32_t white_normalized = 0; } veml7700_sensor; -uint8_t veml7700_active = 0; /********************************************************************************************/ @@ -68,7 +68,7 @@ void VEML7700Detect(void) { if (!I2cSetDevice(veml7700_sensor.address)) return; if (veml7700.begin()) { I2cSetActiveFound(veml7700_sensor.address, veml7700_sensor.types); - veml7700_active = 1; + veml7700_sensor.active = 1; } } @@ -97,10 +97,8 @@ uint8_t VEML7700TranslateItInt (uint16_t ittimems){ } void VEML7700EverySecond(void) { - veml7700_sensor.lux_normalized = (uint16_t) veml7700.readLuxNormalized(); - veml7700_sensor.white_normalized = (uint16_t) veml7700.readWhiteNormalized(); - //veml7700_sensor.lux = (uint16_t) veml7700.readLux(); - //veml7700_sensor.white = (uint16_t) veml7700.readWhite(); + veml7700_sensor.lux_normalized = (uint32_t) veml7700.readLuxNormalized(); + veml7700_sensor.white_normalized = (uint32_t) veml7700.readWhiteNormalized(); } void VEML7700Show(bool json) @@ -152,6 +150,14 @@ bool VEML7700Cmd(void) { Response_P(S_JSON_VEML7700_COMMAND_NVALUE, command, dataret); } break; + case CMND_VEML7700_PERSIST: + if (XdrvMailbox.data_len) { + if (4 >= XdrvMailbox.payload) { + veml7700.setPersistence(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML7700_COMMAND_NVALUE, command, veml7700.getPersistence()); + break; default: return false; } @@ -174,7 +180,7 @@ bool Xsns71(uint8_t function) if (FUNC_INIT == function) { VEML7700Detect(); } - else if (veml7700_active) { + else if (veml7700_sensor.active) { switch (function) { case FUNC_EVERY_SECOND: VEML7700EverySecond(); From f46d3751a01a112075e98ae5574a6b6a4ec3e1fc Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 13 Jun 2020 15:10:12 +0200 Subject: [PATCH 225/581] Refactor some energy monitoring --- tasmota/xdrv_03_energy.ino | 3 +++ tasmota/xnrg_02_cse7766.ino | 45 +++++++++++++++---------------------- tasmota/xnrg_14_bl0940.ino | 27 ++++++++++------------ 3 files changed, 33 insertions(+), 42 deletions(-) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index bf9515b6a..b84d69407 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -1142,6 +1142,9 @@ bool Xdrv03(uint8_t function) case FUNC_EVERY_250_MSECOND: XnrgCall(FUNC_EVERY_250_MSECOND); break; + case FUNC_EVERY_SECOND: + XnrgCall(FUNC_EVERY_SECOND); + break; case FUNC_SERIAL: result = XnrgCall(FUNC_SERIAL); break; diff --git a/tasmota/xnrg_02_cse7766.ino b/tasmota/xnrg_02_cse7766.ino index f0aa210d1..9c8417bc6 100644 --- a/tasmota/xnrg_02_cse7766.ino +++ b/tasmota/xnrg_02_cse7766.ino @@ -59,8 +59,7 @@ struct CSE { bool received = false; } Cse; -void CseReceived(void) -{ +void CseReceived(void) { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // F2 5A 02 F7 60 00 03 61 00 40 10 05 72 40 51 A6 58 63 10 1B E1 7F 4D 4E - F2 = Power cycle exceeds range - takes too long - No load // 55 5A 02 F7 60 00 03 5A 00 40 10 04 8B 9F 51 A6 58 18 72 75 61 AC A1 30 - 55 = Ok, 61 = Power not valid (load below 5W) @@ -69,7 +68,7 @@ void CseReceived(void) uint8_t header = Cse.rx_buffer[0]; if ((header & 0xFC) == 0xFC) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: Abnormal hardware")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CSE: Abnormal hardware")); return; } @@ -142,8 +141,7 @@ void CseReceived(void) } } -bool CseSerialInput(void) -{ +bool CseSerialInput(void) { while (CseSerial->available()) { yield(); uint8_t serial_in_byte = CseSerial->read(); @@ -162,12 +160,12 @@ bool CseSerialInput(void) Cse.received = false; return true; } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: " D_CHECKSUM_FAILURE)); do { // Sync buffer with data (issue #1907 and #3425) memmove(Cse.rx_buffer, Cse.rx_buffer +1, 24); Cse.byte_counter--; } while ((Cse.byte_counter > 2) && (0x5A != Cse.rx_buffer[1])); if (0x5A != Cse.rx_buffer[1]) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CSE: " D_CHECKSUM_FAILURE)); Cse.received = false; Cse.byte_counter = 0; } @@ -186,34 +184,31 @@ bool CseSerialInput(void) /********************************************************************************************/ -void CseEverySecond(void) -{ +void CseEverySecond(void) { if (Energy.data_valid[0] > ENERGY_WATCHDOG) { Cse.voltage_cycle = 0; Cse.current_cycle = 0; Cse.power_cycle = 0; } else { - long cf_frequency = 0; - if (CSE_PULSES_NOT_INITIALIZED == Cse.cf_pulses_last_time) { Cse.cf_pulses_last_time = Cse.cf_pulses; // Init after restart } else { - if (Cse.cf_pulses < Cse.cf_pulses_last_time) { // Rolled over after 65535 pulses - cf_frequency = (65536 - Cse.cf_pulses_last_time) + Cse.cf_pulses; + uint32_t cf_pulses = 0; + if (Cse.cf_pulses < Cse.cf_pulses_last_time) { // Rolled over after 0xFFFF (65535) pulses + cf_pulses = (0x10000 - Cse.cf_pulses_last_time) + Cse.cf_pulses; } else { - cf_frequency = Cse.cf_pulses - Cse.cf_pulses_last_time; + cf_pulses = Cse.cf_pulses - Cse.cf_pulses_last_time; } - if (cf_frequency && Energy.active_power[0]) { - unsigned long delta = (cf_frequency * Settings.energy_power_calibration) / 36; + if (cf_pulses && Energy.active_power[0]) { + uint32_t delta = (cf_pulses * Settings.energy_power_calibration) / 36; // prevent invalid load delta steps even checksum is valid (issue #5789): -// if (delta <= (3680*100/36) * 10 ) { // max load for S31/Pow R2: 3.68kW // prevent invalid load delta steps even checksum is valid but allow up to 4kW (issue #7155): - if (delta <= (4000*100/36) * 10 ) { // max load for S31/Pow R2: 4.00kW + if (delta <= (4000 * 1000 / 36)) { // max load for S31/Pow R2: 4.00kW Cse.cf_pulses_last_time = Cse.cf_pulses; Energy.kWhtoday_delta += delta; } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: Load overflow")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CSE: Overload")); Cse.cf_pulses_last_time = CSE_PULSES_NOT_INITIALIZED; } EnergyUpdateToday(); @@ -222,8 +217,7 @@ void CseEverySecond(void) } } -void CseSnsInit(void) -{ +void CseSnsInit(void) { // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions // CseSerial = new TasmotaSerial(Pin(GPIO_CSE7766_RX), Pin(GPIO_CSE7766_TX), 1); CseSerial = new TasmotaSerial(Pin(GPIO_CSE7766_RX), -1, 1); @@ -241,8 +235,7 @@ void CseSnsInit(void) } } -void CseDrvInit(void) -{ +void CseDrvInit(void) { // if (PinUsed(GPIO_CSE7766_RX) && PinUsed(GPIO_CSE7766_TX)) { if (PinUsed(GPIO_CSE7766_RX)) { Cse.rx_buffer = (uint8_t*)(malloc(CSE_BUFFER_SIZE)); @@ -252,8 +245,7 @@ void CseDrvInit(void) } } -bool CseCommand(void) -{ +bool CseCommand(void) { bool serviced = true; if (CMND_POWERSET == Energy.command_code) { @@ -280,15 +272,14 @@ bool CseCommand(void) * Interface \*********************************************************************************************/ -bool Xnrg02(uint8_t function) -{ +bool Xnrg02(uint8_t function) { bool result = false; switch (function) { case FUNC_LOOP: if (CseSerial) { CseSerialInput(); } break; - case FUNC_ENERGY_EVERY_SECOND: + case FUNC_EVERY_SECOND: CseEverySecond(); break; case FUNC_COMMAND: diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index d9bc51db8..fae36ea3a 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -57,11 +57,9 @@ struct BL0940 { long voltage = 0; long current = 0; long power = 0; - long power_cycle_first = 0; long cf_pulses = 0; long cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; - float temperature; int byte_counter = 0; @@ -88,7 +86,7 @@ void Bl0940Received(void) { if ((Bl0940.rx_buffer[0] != BL0940_PACKET_HEADER) || // Bad header (Bl0940.tps1 && ((tps1 < (Bl0940.tps1 -10)) || (tps1 > (Bl0940.tps1 +10)))) // Invalid temperature change ) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: Invalid data")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: Invalid data")); return; } @@ -146,13 +144,12 @@ bool Bl0940SerialInput(void) { Bl0940.received = false; return true; } else { -// AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); do { // Sync buffer with data (issue #1907 and #3425) memmove(Bl0940.rx_buffer, Bl0940.rx_buffer +1, BL0940_BUFFER_SIZE -1); Bl0940.byte_counter--; } while ((Bl0940.byte_counter > 1) && (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0])); if (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0]) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); Bl0940.received = false; Bl0940.byte_counter = 0; } @@ -188,13 +185,13 @@ void Bl0940EverySecond(void) { cf_pulses = Bl0940.cf_pulses - Bl0940.cf_pulses_last_time; } if (cf_pulses && Energy.active_power[0]) { - if (cf_pulses < 16) { // max load for SHP10: 4.00kW (3.68kW) - uint32_t watt256 = (1638400 * 256) / Settings.energy_power_calibration; - uint32_t delta = (cf_pulses * watt256) / 36; + uint32_t watt256 = (1638400 * 256) / Settings.energy_power_calibration; + uint32_t delta = (cf_pulses * watt256) / 36; + if (delta <= (4000 * 1000 / 36)) { // max load for SHP10: 4.00kW (3.68kW) Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; Energy.kWhtoday_delta += delta; } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("BL9: Overload")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: Overload")); Bl0940.cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; } EnergyUpdateToday(); @@ -203,6 +200,8 @@ void Bl0940EverySecond(void) { } +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: Poll")); + Bl0940Serial->flush(); Bl0940Serial->write(BL0940_READ_COMMAND); Bl0940Serial->write(BL0940_FULL_PACKET); @@ -211,7 +210,7 @@ void Bl0940EverySecond(void) { void Bl0940SnsInit(void) { // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions Bl0940Serial = new TasmotaSerial(Pin(GPIO_BL0940_RX), Pin(GPIO_TXD), 1); - if (Bl0940Serial->begin(4800, 2)) { + if (Bl0940Serial->begin(4800, 1)) { if (Bl0940Serial->hardwareSerial()) { ClaimSerial(); } @@ -268,8 +267,7 @@ bool Bl0940Command(void) { return serviced; } -void Bl0940Show(bool json) -{ +void Bl0940Show(bool json) { char temperature[33]; dtostrfd(Bl0940.temperature, Settings.flag2.temperature_resolution, temperature); @@ -294,15 +292,14 @@ void Bl0940Show(bool json) * Interface \*********************************************************************************************/ -bool Xnrg14(uint8_t function) -{ +bool Xnrg14(uint8_t function) { bool result = false; switch (function) { case FUNC_LOOP: if (Bl0940Serial) { Bl0940SerialInput(); } break; - case FUNC_ENERGY_EVERY_SECOND: + case FUNC_EVERY_SECOND: Bl0940EverySecond(); break; case FUNC_JSON_APPEND: From 4f108e05045d9a88685647cbdf2e3e56fcb58b51 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 14 Jun 2020 12:07:12 +0200 Subject: [PATCH 226/581] fix sml modbus raw mode --- tasmota/xsns_53_sml.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index cb51bcc82..18fd53bf5 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -2405,12 +2405,13 @@ void SML_Send_Seq(uint32_t meter,char *seq) { if (!rflg) { *ucp++=0; *ucp++=2; + slen+=2; } // append crc - uint16_t crc = MBUS_calculateCRC(sbuff,6); + uint16_t crc = MBUS_calculateCRC(sbuff,slen); *ucp++=lowByte(crc); *ucp++=highByte(crc); - slen+=4; + slen+=2; } if (script_meter_desc[meter].type=='o') { for (uint32_t cnt=0;cnt Date: Sun, 14 Jun 2020 12:36:44 +0200 Subject: [PATCH 227/581] Add rule trigger ``System#Init`` Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet (#8673) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/settings.h | 6 +++--- tasmota/tasmota.ino | 2 ++ tasmota/xdrv_10_rules.ino | 21 +++++++++++---------- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index c1637501c..2f9d95ed2 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -78,3 +78,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) - Add initial support for Telegram bot (#8619) - Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) +- Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 0c6ef82bd..73582dfb7 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -4,6 +4,7 @@ - Add initial support for Telegram bot (#8619) - Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) +- Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet ### 8.3.1.2 20200522 diff --git a/tasmota/settings.h b/tasmota/settings.h index 1b0cc0951..08175d7db 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -647,13 +647,14 @@ struct XDRVMAILBOX { } XdrvMailbox; #ifdef USE_SHUTTER -const uint8_t MAX_RULES_FLAG = 10; // Number of bits used in RulesBitfield (tricky I know...) +const uint8_t MAX_RULES_FLAG = 11; // Number of bits used in RulesBitfield (tricky I know...) #else -const uint8_t MAX_RULES_FLAG = 8; // Number of bits used in RulesBitfield (tricky I know...) +const uint8_t MAX_RULES_FLAG = 9; // Number of bits used in RulesBitfield (tricky I know...) #endif // USE_SHUTTER typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... uint16_t data; // Allow bit manipulation struct { + uint16_t system_init : 1; // Changing layout here needs adjustments in xdrv_10_rules.ino too uint16_t system_boot : 1; uint16_t time_init : 1; uint16_t time_set : 1; @@ -664,7 +665,6 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint16_t http_init : 1; uint16_t shutter_moved : 1; uint16_t shutter_moving : 1; - uint16_t spare10 : 1; uint16_t spare11 : 1; uint16_t spare12 : 1; uint16_t spare13 : 1; diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 7ee0c8316..06bd8d9e7 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -322,6 +322,8 @@ void setup(void) { XdrvCall(FUNC_INIT); XsnsCall(FUNC_INIT); + + rules_flag.system_init = 1; } void BacklogLoop(void) { diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 10c4c22e8..37300d03c 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -887,17 +887,18 @@ void RulesEvery50ms(void) rules_flag.data ^= mask; json_event[0] = '\0'; switch (i) { - case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(json_event)); break; - case 1: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Initialized\":%d}}"), MinutesPastMidnight()); break; - case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), MinutesPastMidnight()); break; - case 3: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break; - case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break; - case 5: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break; - case 6: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Disconnected\":1}}"), sizeof(json_event)); break; - case 7: strncpy_P(json_event, PSTR("{\"HTTP\":{\"Initialized\":1}}"), sizeof(json_event)); break; + case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Init\":1}}"), sizeof(json_event)); break; + case 1: strncpy_P(json_event, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(json_event)); break; + case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Initialized\":%d}}"), MinutesPastMidnight()); break; + case 3: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), MinutesPastMidnight()); break; + case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break; + case 5: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break; + case 6: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break; + case 7: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Disconnected\":1}}"), sizeof(json_event)); break; + case 8: strncpy_P(json_event, PSTR("{\"HTTP\":{\"Initialized\":1}}"), sizeof(json_event)); break; #ifdef USE_SHUTTER - case 8: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moved\":1}}"), sizeof(json_event)); break; - case 9: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moving\":1}}"), sizeof(json_event)); break; + case 9: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moved\":1}}"), sizeof(json_event)); break; + case 10: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moving\":1}}"), sizeof(json_event)); break; #endif // USE_SHUTTER } if (json_event[0]) { From 303b49f2fe09065c01ce691df542b10bcc58fcda Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 14 Jun 2020 15:18:38 +0200 Subject: [PATCH 228/581] use espressif8266@2.5.2 minor fixes in PlatformIO framework --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 04835d6c0..abb9d364d 100755 --- a/platformio.ini +++ b/platformio.ini @@ -128,6 +128,6 @@ build_flags = ${tasmota_core.build_flags} [tasmota_core] ; *** Esp8266 Arduino core 2.7.1 -platform = espressif8266@2.5.1 +platform = espressif8266@2.5.2 platform_packages = build_flags = ${esp82xx_defaults.build_flags} From cf518463c1da8c601a139922af0c2ca883bbfcfa Mon Sep 17 00:00:00 2001 From: Charles Date: Sun, 14 Jun 2020 22:04:19 +0200 Subject: [PATCH 229/581] Implemented serial into loop --- tasmota/xnrg_15_teleinfo.ino | 127 +++++++++++++++++++++++++++++------ 1 file changed, 107 insertions(+), 20 deletions(-) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index 4ea6c06b8..094f07bc8 100644 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -31,14 +31,59 @@ #include "LibTeleinfo.h" #include -#define TINFO_READ_TIMEOUT 400 // us; enough for 6 bytes@9600bps +#define TINFO_READ_TIMEOUT 400 + +enum TInfoContrat{ + CONTRAT_BAS = 1, // BASE => Option Base. + CONTRAT_HC, // HC.. => Option Heures Creuses. + CONTRAT_EJP, // EJP. => Option EJP. + CONTRAT_BBR // BBRx => Option Tempo +}; + +enum TInfoTarif{ + TARIF_TH = 1, // Toutes les Heures. + TARIF_HC, // Heures Creuses. + TARIF_HP, // Heures Pleines. + TARIF_HN // BBRx => Option Tempo +}; + +//const char kTARIF_TH[] PROGMEM = ""; +//const char kTARIF_HC[] PROGMEM = "Heures Creuses"; +//const char kTARIF_HP[] PROGMEM = "Heures Pleines"; +//const char kTARIF_HN[] PROGMEM = "Heures Normales"; + +//const char kTtarifNames[] PROGMEM = { kTARIF_TH, kTARIF_HC, kTARIF_HP, kTARIF_HN }; + +/* + strcpy_P(buffer, (char*)pgm_read_dword(&(kTtarifNames[i]))); + + if ( label == "PTEC") { + // La période tarifaire en cours (Groupe "PTEC"), est codée sur 4 caractères + // J'ai pris un nombre arbitraire codé dans l'ordre ci-dessous + if (value=="TH..") value= 1; + else if (value=="HC..") value= 2; + else if (value=="HP..") value= 3; / + else if (value=="HN..") value= 4; + else if (value=="PM..") value= 5; // Heures de Pointe Mobile. + else if (value=="HCJB") value= 6; // Heures Creuses Jours Bleus. + else if (value=="HCJW") value= 7; // Heures Creuses Jours Blancs (White). + else if (value=="HCJR") value= 8; // Heures Creuses Jours Rouges. + else if (value=="HPJB") value= 9; // Heures Pleines Jours Bleus. + else if (value=="HPJW") value= 10;// Heures Pleines Jours Blancs (White). + else if (value=="HPJR") value= 11;// Heures Pleines Jours Rouges. + else value = 0; + +*/ + TInfo tinfo; // Teleinfo object TasmotaSerial *TInfoSerial = nullptr; bool tinfo_found = false; +uint8_t contrat; +uint8_t tarif; /*********************************************************************************************/ - + /* ====================================================================== Function: ADPSCallback Purpose : called by library when we detected a ADPS on any phased @@ -70,12 +115,39 @@ Comments: - ====================================================================== */ void DataCallback(struct _ValueList * me, uint8_t flags) { - char c = ' '; - - if (flags & TINFO_FLAGS_ADDED) { c = '#'; } - if (flags & TINFO_FLAGS_UPDATED) { c = '*'; } + char c = ' '; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: %c %s=%s"),c , me->name, me->value); + // Does this value is new or changed? + if (flags & (TINFO_FLAGS_ADDED | TINFO_FLAGS_UPDATED) ) + { + if (flags & TINFO_FLAGS_ADDED) { c = '#'; } + if (flags & TINFO_FLAGS_UPDATED) { c = '*'; } + + // Current tarif + if (!strcmp("PTEC", me->name)) + { + if (!strcmp("TH..", me->name)) { tarif = TARIF_TH; } + if (!strcmp("HC..", me->name)) { tarif = TARIF_HC; } + if (!strcmp("HP..", me->name)) { tarif = TARIF_HP; } + if (!strcmp("HN..", me->name)) { tarif = TARIF_HN; } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Tarif changed, now '%s' (%d)"), me->value, tarif); + } + // Current I + else if (!strcmp("IINST", me->name)) + { + int i = atoi(me->value); + Energy.current[0] = (float) i; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Current changed %s, now %d"), me->value, i); + } + // Current P + else if (!strcmp("PAPP", me->name)) + { + int papp = atoi(me->value); + Energy.active_power[0] = (float) papp; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Power changed %s, now %d"), me->value, papp); + } + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: %c %s=%s"),c , me->name, me->value); } void TInfoDrvInit(void) { @@ -94,7 +166,6 @@ void TInfoInit(void) AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: inferface speed %d bps"),TINFO_SPEED); - tinfo_found = false; if (PinUsed(GPIO_TELEINFO_RX)) { AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: enable receive on GPIO%d"), GPIO_TELEINFO_RX); @@ -111,12 +182,16 @@ void TInfoInit(void) } TInfoSerial = new TasmotaSerial(Pin(GPIO_TELEINFO_RX), -1, 1); + // pinMode(GPIO_TELEINFO_RX, INPUT_PULLUP); if (TInfoSerial->begin(TINFO_SPEED, SERIAL_7E1)) { - if (TInfoSerial->hardwareSerial()) + if (TInfoSerial->hardwareSerial()) { + Serial.end(); + Serial.begin(TINFO_SPEED, SERIAL_7E1); ClaimSerial(); + } TInfoSerial->setTimeout(TINFO_READ_TIMEOUT); // Init teleinfo @@ -125,29 +200,36 @@ void TInfoInit(void) // Attach needed callbacks tinfo.attachADPS(ADPSCallback); tinfo.attachData(DataCallback); - + tinfo_found = true; AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Ready")); } } } -void TInfoEvery250ms(void) +void TInfoLoop(void) { char c; if (!tinfo_found) return; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: received %d chars"), TInfoSerial->available()); + if (TInfoSerial->available()) { + //AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: received %d chars"), TInfoSerial->available()); - // We received some data? - while (TInfoSerial->available()>8) - { - // get char - c = TInfoSerial->read(); - // data processing - tinfo.process(c); - } + // We received some data? + while (TInfoSerial->available()>8) + { + // get char + c = TInfoSerial->read(); + + // data processing + tinfo.process(c); + } + } +} + +void TInfoEvery250ms(void) +{ } void TInfoShow(bool json) @@ -155,6 +237,8 @@ void TInfoShow(bool json) // TBD if (json) { + ResponseAppend_P(PSTR(",\"Contrat\":%d,\"Tarif\":%d"),contrat, tarif); + #ifdef USE_WEBSERVER } else @@ -172,6 +256,9 @@ bool Xnrg15(uint8_t function) switch (function) { + case FUNC_LOOP: + if (TInfoSerial) { TInfoLoop(); } + break; case FUNC_EVERY_250_MSECOND: if (uptime > 4) { TInfoEvery250ms(); } break; From 5e5ebb002541fc2aa7530df3c6174774dd5e476f Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 15 Jun 2020 00:52:49 +0200 Subject: [PATCH 230/581] Added new tarif contract --- tasmota/xnrg_15_teleinfo.ino | 203 +++++++++++++++++++++++++++-------- 1 file changed, 158 insertions(+), 45 deletions(-) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index 094f07bc8..83a20648f 100644 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -34,47 +34,44 @@ #define TINFO_READ_TIMEOUT 400 enum TInfoContrat{ - CONTRAT_BAS = 1, // BASE => Option Base. - CONTRAT_HC, // HC.. => Option Heures Creuses. - CONTRAT_EJP, // EJP. => Option EJP. - CONTRAT_BBR // BBRx => Option Tempo + CONTRAT_BAS = 1, // BASE => Option Base. + CONTRAT_HC, // HC.. => Option Heures Creuses. + CONTRAT_EJP, // EJP. => Option EJP. + CONTRAT_BBR // BBRx => Option Tempo }; enum TInfoTarif{ - TARIF_TH = 1, // Toutes les Heures. - TARIF_HC, // Heures Creuses. - TARIF_HP, // Heures Pleines. - TARIF_HN // BBRx => Option Tempo + TARIF_TH = 1, // Toutes les Heures. + TARIF_HC, // Heures Creuses. + TARIF_HP, // Heures Pleines. + TARIF_HN, // BBRx => Option Tempo + TARIF_PM, // Heures de Pointe Mobile. + TARIF_CB, // Heures Creuses Jours Bleus. + TARIF_CW, // Heures Creuses Jours Blancs (White). + TARIF_CR, // Heures Creuses Jours Rouges. + TARIF_PB, // Heures Pleines Jours Bleus. + TARIF_PW, // Heures Pleines Jours Blancs (White). + TARIF_PR // Heures Pleines Jours Rouges. }; -//const char kTARIF_TH[] PROGMEM = ""; -//const char kTARIF_HC[] PROGMEM = "Heures Creuses"; -//const char kTARIF_HP[] PROGMEM = "Heures Pleines"; -//const char kTARIF_HN[] PROGMEM = "Heures Normales"; - -//const char kTtarifNames[] PROGMEM = { kTARIF_TH, kTARIF_HC, kTARIF_HP, kTARIF_HN }; - -/* - strcpy_P(buffer, (char*)pgm_read_dword(&(kTtarifNames[i]))); - - if ( label == "PTEC") { - // La période tarifaire en cours (Groupe "PTEC"), est codée sur 4 caractères - // J'ai pris un nombre arbitraire codé dans l'ordre ci-dessous - if (value=="TH..") value= 1; - else if (value=="HC..") value= 2; - else if (value=="HP..") value= 3; / - else if (value=="HN..") value= 4; - else if (value=="PM..") value= 5; // Heures de Pointe Mobile. - else if (value=="HCJB") value= 6; // Heures Creuses Jours Bleus. - else if (value=="HCJW") value= 7; // Heures Creuses Jours Blancs (White). - else if (value=="HCJR") value= 8; // Heures Creuses Jours Rouges. - else if (value=="HPJB") value= 9; // Heures Pleines Jours Bleus. - else if (value=="HPJW") value= 10;// Heures Pleines Jours Blancs (White). - else if (value=="HPJR") value= 11;// Heures Pleines Jours Rouges. - else value = 0; - -*/ +const char kTARIF_TH[] PROGMEM = "Toutes"; +const char kTARIF_HC[] PROGMEM = "Creuses"; +const char kTARIF_HP[] PROGMEM = "Pleines"; +const char kTARIF_HN[] PROGMEM = "Normales"; +const char kTARIF_PM[] PROGMEM = "Pointe Mobile"; +const char kTARIF_CB[] PROGMEM = "Creuses Bleu"; +const char kTARIF_CW[] PROGMEM = "Creuses Blanc"; +const char kTARIF_CR[] PROGMEM = "Creuses Rouge"; +const char kTARIF_PB[] PROGMEM = "Pleines Bleu"; +const char kTARIF_PW[] PROGMEM = "Pleines Blanc"; +const char kTARIF_PR[] PROGMEM = "Pleines Rouge"; +const char * kTtarifNames[] PROGMEM = { + kTARIF_TH, + kTARIF_HC, kTARIF_HP, + kTARIF_HN, kTARIF_PM, + kTARIF_CB, kTARIF_CW, kTARIF_CR, kTARIF_PB, kTARIF_PW, kTARIF_PR +}; TInfo tinfo; // Teleinfo object TasmotaSerial *TInfoSerial = nullptr; @@ -127,32 +124,112 @@ void DataCallback(struct _ValueList * me, uint8_t flags) if (!strcmp("PTEC", me->name)) { if (!strcmp("TH..", me->name)) { tarif = TARIF_TH; } - if (!strcmp("HC..", me->name)) { tarif = TARIF_HC; } - if (!strcmp("HP..", me->name)) { tarif = TARIF_HP; } - if (!strcmp("HN..", me->name)) { tarif = TARIF_HN; } + else if (!strcmp("HC..", me->name)) { tarif = TARIF_HC; } + else if (!strcmp("HP..", me->name)) { tarif = TARIF_HP; } + else if (!strcmp("HN..", me->name)) { tarif = TARIF_HN; } + else if (!strcmp("PM..", me->name)) { tarif = TARIF_PM; } + else if (!strcmp("HCJB", me->name)) { tarif = TARIF_CB; } + else if (!strcmp("HCJW", me->name)) { tarif = TARIF_CW; } + else if (!strcmp("HCJR", me->name)) { tarif = TARIF_CR; } + else if (!strcmp("HPJB", me->name)) { tarif = TARIF_PB; } + else if (!strcmp("HPJW", me->name)) { tarif = TARIF_PW; } + else if (!strcmp("HPJR", me->name)) { tarif = TARIF_PR; } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Tarif changed, now '%s' (%d)"), me->value, tarif); } + // Voltage V (not present on all Smart Meter) + else if (!strcmp("TENSION", me->name)) + { + Energy.voltage_available = true; + int i = atoi(me->value); + Energy.voltage[0] = (float) atoi(me->value); + + // Update current + if (Energy.voltage_available && Energy.voltage[0]) { + Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; + } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Voltage %s, now %d"), me->value, i); + } // Current I else if (!strcmp("IINST", me->name)) { - int i = atoi(me->value); - Energy.current[0] = (float) i; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Current changed %s, now %d"), me->value, i); + if (!Energy.voltage_available) { + int i = atoi(me->value); + Energy.current[0] = (float) atoi(me->value); + } else if (Energy.voltage[0]) { + Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; + } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Current %s, now %d"), me->value, (int) Energy.current[0]); } // Current P else if (!strcmp("PAPP", me->name)) { int papp = atoi(me->value); - Energy.active_power[0] = (float) papp; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Power changed %s, now %d"), me->value, papp); + Energy.active_power[0] = (float) atoi(me->value); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Power %s, now %d"), me->value, papp); + + // Update current + if (Energy.voltage_available && Energy.voltage[0]) { + Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; + } + } + // kWh indexes + else if (!strcmp("HCHC", me->name) || !strcmp("HCHP", me->name)) + { + char value[32]; + unsigned long hc = 0; + unsigned long hp = 0; + unsigned long total = 0; + + if ( tinfo.valueGet((char *)"HCHC", value) ) { hc = atol(value);} + if ( tinfo.valueGet((char *)"HCHP", value) ) { hp = atol(value);} + total = hc+hp; + + EnergyUpdateTotal(total/1000.0f, true); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%ld HP:%ld Total:%ld"), hc, hp, total); } } AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: %c %s=%s"),c , me->name, me->value); } +/* ====================================================================== +Function: NewFrameCallback +Purpose : callback when we received a complete Teleinfo frama +Input : linked list pointer on the concerned data +Output : - +Comments: - +====================================================================== */ +void NewFrameCallback(struct _ValueList * me) +{ + // Reset Energy Watchdog + Energy.data_valid[0] = 0; +} + +/* ====================================================================== +Function: NewFrameCallback +Purpose : callback when we received a complete Teleinfo frama +Input : label to search for +Output : value filled +Comments: - +====================================================================== */ +char * getDataValue(char * label, char * value) +{ + if (!tinfo.valueGet(label, value) ) { + *value = '\0'; + } + return value; +} + + + void TInfoDrvInit(void) { if (PinUsed(GPIO_TELEINFO_RX)) { energy_flg = XNRG_15; + Energy.voltage_available = false; + //Energy.current_available = false; + Energy.type_dc = true; } } @@ -188,6 +265,9 @@ void TInfoInit(void) if (TInfoSerial->begin(TINFO_SPEED, SERIAL_7E1)) { if (TInfoSerial->hardwareSerial()) { + // This is a dirty hack to bypass HW serial init when for Teleinfo + // This protocol needs 7E1 configuration so on ESP8266 this is + // working only on Serial RX pin (Hardware Serial) for now Serial.end(); Serial.begin(TINFO_SPEED, SERIAL_7E1); ClaimSerial(); @@ -200,6 +280,7 @@ void TInfoInit(void) // Attach needed callbacks tinfo.attachADPS(ADPSCallback); tinfo.attachData(DataCallback); + tinfo.attachNewFrame(NewFrameCallback); tinfo_found = true; AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Ready")); @@ -228,21 +309,52 @@ void TInfoLoop(void) } } + void TInfoEvery250ms(void) { } +#ifdef USE_WEBSERVER +const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_KILOWATTHOUR "{e}" ; +const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ; +const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "{m}%d " D_UNIT_AMPERE "{e}" ; +const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}Tarif{m}%s{e}" ; +#endif // USE_WEBSERVER + void TInfoShow(bool json) { + char value[32]; // TBD if (json) { - ResponseAppend_P(PSTR(",\"Contrat\":%d,\"Tarif\":%d"),contrat, tarif); - + if ( tinfo.valueGet((char *)"PTEC", value) ) { + ResponseAppend_P(PSTR(",\"" "TARIF" "\":%s"), value); + } + if ( tinfo.valueGet((char *)"IINST", value) ) { + ResponseAppend_P(PSTR(",\"" D_CURRENT "\":%s"), value); + } + if ( tinfo.valueGet((char *)"PAPP", value) ) { + ResponseAppend_P(PSTR(",\"" D_POWERUSAGE "\":%s"), value); + } + if ( tinfo.valueGet((char *)"HCHC", value) ) { + ResponseAppend_P(PSTR(",\"" "HC" "\":%s"), value); + } + if ( tinfo.valueGet((char *)"HCHP", value) ) { + ResponseAppend_P(PSTR(",\"" "HP" "\":%s"), value); + } #ifdef USE_WEBSERVER } else { + getDataValue("HCHC", value); + WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, kTARIF_HC, value); + getDataValue("HCHP", value); + WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, kTARIF_HP, value); + if (tarif) { + WSContentSend_PD(HTTP_ENERGY_TARIF_TELEINFO, kTtarifNames[tarif-1]); + } + + #endif // USE_WEBSERVER } } @@ -263,6 +375,7 @@ bool Xnrg15(uint8_t function) if (uptime > 4) { TInfoEvery250ms(); } break; case FUNC_JSON_APPEND: + TInfoShow(1); break; #ifdef USE_WEBSERVER From 32d82b3568dca410a4fa986292951b3ce083fb06 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 15 Jun 2020 01:20:49 +0200 Subject: [PATCH 231/581] Bump to v1.1.2 --- lib/LibTeleinfo/library.json | 2 +- lib/LibTeleinfo/library.properties | 2 +- lib/LibTeleinfo/src/LibTeleinfo.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/LibTeleinfo/library.json b/lib/LibTeleinfo/library.json index 70f368653..a93105e61 100755 --- a/lib/LibTeleinfo/library.json +++ b/lib/LibTeleinfo/library.json @@ -1,6 +1,6 @@ { "name": "LibTeleinfo", - "version": "1.1.1", + "version": "1.1.2", "keywords": "teleinfo, french, meter, power, erdf, linky, tic", "description": "Decoder for Teleinfo (aka TIC) from French smart power meters", "repository": diff --git a/lib/LibTeleinfo/library.properties b/lib/LibTeleinfo/library.properties index fdcee4a25..7cfc9a635 100755 --- a/lib/LibTeleinfo/library.properties +++ b/lib/LibTeleinfo/library.properties @@ -1,5 +1,5 @@ name=LibTeleinfo -version=1.1.1 +version=1.1.2 author=Charles-Henri Hallard maintainer=Charles-Henri Hallard sentence=Decoder for Teleinfo (aka TIC) from French smart power meters diff --git a/lib/LibTeleinfo/src/LibTeleinfo.cpp b/lib/LibTeleinfo/src/LibTeleinfo.cpp index 8d34e89d1..bb7b7119f 100644 --- a/lib/LibTeleinfo/src/LibTeleinfo.cpp +++ b/lib/LibTeleinfo/src/LibTeleinfo.cpp @@ -426,7 +426,7 @@ char * TInfo::valueGet(char * name, char * value) if (me->value) { // copy to dest buffer uint8_t lgvalue = strlen(me->value); - strlcpy(value, me->value , lgvalue ); + strlcpy(value, me->value , lgvalue + 1 ); return ( value ); } } @@ -661,7 +661,7 @@ ValueList * TInfo::checkLine(char * pline) return NULL; // Get our own working copy - strlcpy( buff, _recv_buff, len+1); + strlcpy( buff, pline, len+1); p = &buff[0]; ptok = p; // for sure we start with token name From 7d1a27560606fc0a0a83d0a0292d44d095d4b455 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 15 Jun 2020 07:25:39 +0200 Subject: [PATCH 232/581] fix chartofloat digit overflow --- tasmota/support.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 879a91fb0..0a5d26f10 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -167,6 +167,8 @@ float CharToFloat(const char *str) float right = 0; if (*pt == '.') { pt++; + // limit decimals to float max + pt[7]=0; right = atoi(pt); // Decimal part while (isdigit(*pt)) { pt++; @@ -1908,4 +1910,4 @@ String Decompress(const char * compressed, size_t uncompressed_size) { return content; } -#endif // USE_UNISHOX_COMPRESSION \ No newline at end of file +#endif // USE_UNISHOX_COMPRESSION From 5f7a32af4cfca2fbb9239a7c096190571e88df39 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 15 Jun 2020 08:20:43 +0200 Subject: [PATCH 233/581] update ibeacon to export UID --- tasmota/xsns_52_ibeacon.ino | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/tasmota/xsns_52_ibeacon.ino b/tasmota/xsns_52_ibeacon.ino index 5f9c0f3ba..6a33d94a0 100755 --- a/tasmota/xsns_52_ibeacon.ino +++ b/tasmota/xsns_52_ibeacon.ino @@ -87,6 +87,9 @@ struct IBEACON { struct IBEACON_UID { char MAC[12]; char RSSI[4]; + char UID[32]; + char MAJOR[4]; + char MINOR[4]; uint8_t FLAGS; uint8_t TIME; } ibeacons[MAX_IBEACONS]; @@ -132,7 +135,7 @@ void hm17_every_second(void) { ibeacons[cnt].TIME++; if (ibeacons[cnt].TIME>IB_TIMEOUT_TIME) { ibeacons[cnt].FLAGS=0; - ibeacon_mqtt(ibeacons[cnt].MAC,"0000"); + ibeacon_mqtt(ibeacons[cnt].MAC,"0000",ibeacons[cnt].UID,ibeacons[cnt].MAJOR,ibeacons[cnt].MINOR); } } } @@ -210,6 +213,9 @@ uint32_t ibeacon_add(struct IBEACON *ib) { if (!ibeacons[cnt].FLAGS) { memcpy(ibeacons[cnt].MAC,ib->MAC,12); memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); + memcpy(ibeacons[cnt].UID,ib->UID,32); + memcpy(ibeacons[cnt].MAJOR,ib->MAJOR,4); + memcpy(ibeacons[cnt].MINOR,ib->MINOR,4); ibeacons[cnt].FLAGS=1; ibeacons[cnt].TIME=0; return 1; @@ -400,7 +406,7 @@ hm17_v110: memcpy(ib.RSSI,&hm17_sbuffer[8+8+1+32+1+4+4+2+1+12+1],4); if (ibeacon_add(&ib)) { - ibeacon_mqtt(ib.MAC,ib.RSSI); + ibeacon_mqtt(ib.MAC,ib.RSSI,ib.UID,ib.MAJOR,ib.MINOR); } hm17_sbclr(); hm17_result=1; @@ -560,15 +566,30 @@ void ib_sendbeep(void) { hm17_sendcmd(HM17_CON); } -void ibeacon_mqtt(const char *mac,const char *rssi) { +void ibeacon_mqtt(const char *mac,const char *rssi,const char *uid,const char *major,const char *minor) { char s_mac[14]; + char s_uid[34]; + char s_major[6]; + char s_minor[6]; char s_rssi[6]; memcpy(s_mac,mac,12); s_mac[12]=0; + memcpy(s_uid,uid,32); + s_uid[32]=0; + memcpy(s_major,major,4); + s_major[4]=0; + memcpy(s_minor,minor,4); + s_minor[4]=0; memcpy(s_rssi,rssi,4); s_rssi[4]=0; int16_t n_rssi=atoi(s_rssi); - ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "_%s\":{\"RSSI\":%d}}"),s_mac,n_rssi); + // if uid == all zeros, take mac + if (!strncmp_P(s_uid,PSTR("00000000000000000000000000000000"),32)) { + ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "_%s\":{\"UID\":\"%s\",\"MAJOR\":\"%s\",\"MINOR\":\"%s\",\"RSSI\":%d}}"),s_mac,s_uid,s_major,s_minor,n_rssi); + } else { + ResponseTime_P(PSTR(",\"" D_CMND_IBEACON "_%s\":{\"MAJOR\":\"%s\",\"MINOR\":\"%s\",\"RSSI\":%d}}"),s_uid,s_major,s_minor,n_rssi); + } + MqttPublishTeleSensor(); } From 71b7b1632d96d047e44550110ea37a6281921c51 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 15 Jun 2020 11:52:51 +0200 Subject: [PATCH 234/581] cleaned Serial init (not perfect but better) --- tasmota/xnrg_15_teleinfo.ino | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index 83a20648f..97dfca314 100644 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -262,14 +262,16 @@ void TInfoInit(void) // pinMode(GPIO_TELEINFO_RX, INPUT_PULLUP); - if (TInfoSerial->begin(TINFO_SPEED, SERIAL_7E1)) + // Trick here even using SERIAL_7E1 or TS_SERIAL_7E1 + // this is not working, need to call SetSerialConfig after + if (TInfoSerial->begin(TINFO_SPEED, TS_SERIAL_7E1)) { + // This is a dirty hack, looks like begin does not take into account + // the TS_SERIAL_7E1 configuration so on ESP8266 this is + // working only on Serial RX pin (Hardware Serial) for now + SetSerialConfig(TS_SERIAL_7E1); + if (TInfoSerial->hardwareSerial()) { - // This is a dirty hack to bypass HW serial init when for Teleinfo - // This protocol needs 7E1 configuration so on ESP8266 this is - // working only on Serial RX pin (Hardware Serial) for now - Serial.end(); - Serial.begin(TINFO_SPEED, SERIAL_7E1); ClaimSerial(); } TInfoSerial->setTimeout(TINFO_READ_TIMEOUT); From b98fa03dd0a7902dd9131b03f17dcfbded1431f0 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 15 Jun 2020 14:44:32 +0200 Subject: [PATCH 235/581] Added valueGet_P option --- lib/LibTeleinfo/src/LibTeleinfo.cpp | 38 +++++++++++++++++++++++++++++ lib/LibTeleinfo/src/LibTeleinfo.h | 1 + 2 files changed, 39 insertions(+) diff --git a/lib/LibTeleinfo/src/LibTeleinfo.cpp b/lib/LibTeleinfo/src/LibTeleinfo.cpp index bb7b7119f..588555831 100644 --- a/lib/LibTeleinfo/src/LibTeleinfo.cpp +++ b/lib/LibTeleinfo/src/LibTeleinfo.cpp @@ -436,6 +436,44 @@ char * TInfo::valueGet(char * name, char * value) return ( NULL); } +/* ====================================================================== +Function: valueGet_P +Purpose : get value of one element +Input : Pointer to the label name + pointer to the value where we fill data +Output : pointer to the value where we filled data NULL is not found +====================================================================== */ +char * TInfo::valueGet_P(const char * name, char * value) +{ + // Get our linked list + ValueList * me = &_valueslist; + uint8_t lgname = strlen_P(name); + + // Got one and all seems good ? + if (me && lgname) { + + // Loop thru the node + while (me->next) { + + // go to next node + me = me->next; + + // Check if we match this LABEL + if (lgname==strlen(me->name) && strncmp_P(me->name, name, lgname)==0) { + // this one has a value ? + if (me->value) { + // copy to dest buffer + uint8_t lgvalue = strlen(me->value); + strlcpy(value, me->value , lgvalue + 1 ); + return ( value ); + } + } + } + } + // not found + return ( NULL); +} + /* ====================================================================== Function: getTopList Purpose : return a pointer on the top of the linked list diff --git a/lib/LibTeleinfo/src/LibTeleinfo.h b/lib/LibTeleinfo/src/LibTeleinfo.h index a9725b26a..5b43523c7 100755 --- a/lib/LibTeleinfo/src/LibTeleinfo.h +++ b/lib/LibTeleinfo/src/LibTeleinfo.h @@ -117,6 +117,7 @@ class TInfo ValueList * getList(void); uint8_t valuesDump(void); char * valueGet(char * name, char * value); + char * valueGet_P(const char * name, char * value); boolean listDelete(); unsigned char calcChecksum(char *etiquette, char *valeur) ; From b889a97bc1ccb8a128b809bbc19a6c7d93de2e2f Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 15 Jun 2020 14:47:39 +0200 Subject: [PATCH 236/581] Use PSTR for labels values --- tasmota/xnrg_15_teleinfo.ino | 97 ++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 37 deletions(-) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index 97dfca314..aefced128 100644 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -54,6 +54,17 @@ enum TInfoTarif{ TARIF_PR // Heures Pleines Jours Rouges. }; +// Label received +const char LABEL_HCHC[] PROGMEM = "HCHC"; +const char LABEL_HCHP[] PROGMEM = "HCHP"; +const char LABEL_PTEC[] PROGMEM = "PTEC"; +const char LABEL_PAPP[] PROGMEM = "PAPP"; +const char LABEL_IINST[] PROGMEM = "IINST"; +const char LABEL_TENSION[] PROGMEM = "TENSION"; + +// Some Values with string to compare to +const char VALUE_HCDD[] PROGMEM = "HC.."; + const char kTARIF_TH[] PROGMEM = "Toutes"; const char kTARIF_HC[] PROGMEM = "Creuses"; const char kTARIF_HP[] PROGMEM = "Pleines"; @@ -121,24 +132,24 @@ void DataCallback(struct _ValueList * me, uint8_t flags) if (flags & TINFO_FLAGS_UPDATED) { c = '*'; } // Current tarif - if (!strcmp("PTEC", me->name)) + if (!strcmp_P(LABEL_PTEC, me->name)) { - if (!strcmp("TH..", me->name)) { tarif = TARIF_TH; } - else if (!strcmp("HC..", me->name)) { tarif = TARIF_HC; } - else if (!strcmp("HP..", me->name)) { tarif = TARIF_HP; } - else if (!strcmp("HN..", me->name)) { tarif = TARIF_HN; } - else if (!strcmp("PM..", me->name)) { tarif = TARIF_PM; } - else if (!strcmp("HCJB", me->name)) { tarif = TARIF_CB; } - else if (!strcmp("HCJW", me->name)) { tarif = TARIF_CW; } - else if (!strcmp("HCJR", me->name)) { tarif = TARIF_CR; } - else if (!strcmp("HPJB", me->name)) { tarif = TARIF_PB; } - else if (!strcmp("HPJW", me->name)) { tarif = TARIF_PW; } - else if (!strcmp("HPJR", me->name)) { tarif = TARIF_PR; } + if (!strcmp_P("TH..", me->name)) { tarif = TARIF_TH; } + else if (!strcmp_P("HC..", me->name)) { tarif = TARIF_HC; } + else if (!strcmp_P("HP..", me->name)) { tarif = TARIF_HP; } + else if (!strcmp_P("HN..", me->name)) { tarif = TARIF_HN; } + else if (!strcmp_P("PM..", me->name)) { tarif = TARIF_PM; } + else if (!strcmp_P("HCJB", me->name)) { tarif = TARIF_CB; } + else if (!strcmp_P("HCJW", me->name)) { tarif = TARIF_CW; } + else if (!strcmp_P("HCJR", me->name)) { tarif = TARIF_CR; } + else if (!strcmp_P("HPJB", me->name)) { tarif = TARIF_PB; } + else if (!strcmp_P("HPJW", me->name)) { tarif = TARIF_PW; } + else if (!strcmp_P("HPJR", me->name)) { tarif = TARIF_PR; } AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Tarif changed, now '%s' (%d)"), me->value, tarif); } // Voltage V (not present on all Smart Meter) - else if (!strcmp("TENSION", me->name)) + else if (!strcmp_P(LABEL_TENSION, me->name)) { Energy.voltage_available = true; int i = atoi(me->value); @@ -152,7 +163,7 @@ void DataCallback(struct _ValueList * me, uint8_t flags) AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Voltage %s, now %d"), me->value, i); } // Current I - else if (!strcmp("IINST", me->name)) + else if (!strcmp_P(LABEL_IINST, me->name)) { if (!Energy.voltage_available) { int i = atoi(me->value); @@ -164,7 +175,7 @@ void DataCallback(struct _ValueList * me, uint8_t flags) AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Current %s, now %d"), me->value, (int) Energy.current[0]); } // Current P - else if (!strcmp("PAPP", me->name)) + else if (!strcmp_P(LABEL_PAPP, me->name)) { int papp = atoi(me->value); Energy.active_power[0] = (float) atoi(me->value); @@ -176,15 +187,15 @@ void DataCallback(struct _ValueList * me, uint8_t flags) } } // kWh indexes - else if (!strcmp("HCHC", me->name) || !strcmp("HCHP", me->name)) + else if (!strcmp_P(LABEL_HCHC, me->name) || !strcmp(LABEL_HCHP, me->name)) { char value[32]; unsigned long hc = 0; unsigned long hp = 0; unsigned long total = 0; - if ( tinfo.valueGet((char *)"HCHC", value) ) { hc = atol(value);} - if ( tinfo.valueGet((char *)"HCHP", value) ) { hp = atol(value);} + if ( tinfo.valueGet_P(LABEL_HCHC, value) ) { hc = atol(value);} + if ( tinfo.valueGet_P(LABEL_HCHP, value) ) { hp = atol(value);} total = hc+hp; EnergyUpdateTotal(total/1000.0f, true); @@ -214,9 +225,9 @@ Input : label to search for Output : value filled Comments: - ====================================================================== */ -char * getDataValue(char * label, char * value) +char * getDataValue_P(const char * label, char * value) { - if (!tinfo.valueGet(label, value) ) { + if (!tinfo.valueGet_P(label, value) ) { *value = '\0'; } return value; @@ -245,37 +256,49 @@ void TInfoInit(void) if (PinUsed(GPIO_TELEINFO_RX)) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: enable receive on GPIO%d"), GPIO_TELEINFO_RX); + uint8_t rx_pin = Pin(GPIO_TELEINFO_RX); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: RX on GPIO%d"), rx_pin); // Enable Teleinfo if (PinUsed(GPIO_TELEINFO_ENABLE)) { - pinMode(GPIO_TELEINFO_ENABLE, OUTPUT); - digitalWrite(GPIO_TELEINFO_ENABLE, HIGH); - AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: enable on GPIO%d"), GPIO_TELEINFO_ENABLE); + uint8_t en_pin = Pin(GPIO_TELEINFO_ENABLE); + pinMode(en_pin, OUTPUT); + digitalWrite(en_pin, HIGH); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Enable with GPIO%d"), en_pin); } else { AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: always enabled")); } - TInfoSerial = new TasmotaSerial(Pin(GPIO_TELEINFO_RX), -1, 1); + TInfoSerial = new TasmotaSerial(rx_pin, -1, 1); // pinMode(GPIO_TELEINFO_RX, INPUT_PULLUP); // Trick here even using SERIAL_7E1 or TS_SERIAL_7E1 // this is not working, need to call SetSerialConfig after - if (TInfoSerial->begin(TINFO_SPEED, TS_SERIAL_7E1)) + if (TInfoSerial->begin(TINFO_SPEED)) { + #if defined (ESP8266) + if (TInfoSerial->hardwareSerial() ) { + ClaimSerial(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using hardware serial")); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using software serial")); + } + // This is a dirty hack, looks like begin does not take into account // the TS_SERIAL_7E1 configuration so on ESP8266 this is // working only on Serial RX pin (Hardware Serial) for now SetSerialConfig(TS_SERIAL_7E1); - - if (TInfoSerial->hardwareSerial()) { - ClaimSerial(); - } + TInfoSerial->setTimeout(TINFO_READ_TIMEOUT); + #elif defined (ESP32) + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using ESP32 hardware serial")); + #endif + + // Init teleinfo tinfo.init(); @@ -329,28 +352,28 @@ void TInfoShow(bool json) // TBD if (json) { - if ( tinfo.valueGet((char *)"PTEC", value) ) { + if ( tinfo.valueGet_P(LABEL_PTEC, value) ) { ResponseAppend_P(PSTR(",\"" "TARIF" "\":%s"), value); } - if ( tinfo.valueGet((char *)"IINST", value) ) { + if ( tinfo.valueGet_P(LABEL_IINST, value) ) { ResponseAppend_P(PSTR(",\"" D_CURRENT "\":%s"), value); } - if ( tinfo.valueGet((char *)"PAPP", value) ) { + if ( tinfo.valueGet_P(LABEL_PAPP, value) ) { ResponseAppend_P(PSTR(",\"" D_POWERUSAGE "\":%s"), value); } - if ( tinfo.valueGet((char *)"HCHC", value) ) { + if ( tinfo.valueGet_P(LABEL_HCHC, value) ) { ResponseAppend_P(PSTR(",\"" "HC" "\":%s"), value); } - if ( tinfo.valueGet((char *)"HCHP", value) ) { + if ( tinfo.valueGet_P(LABEL_HCHP, value) ) { ResponseAppend_P(PSTR(",\"" "HP" "\":%s"), value); } #ifdef USE_WEBSERVER } else { - getDataValue("HCHC", value); + getDataValue_P(LABEL_HCHC, value); WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, kTARIF_HC, value); - getDataValue("HCHP", value); + getDataValue_P(LABEL_HCHP, value); WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, kTARIF_HP, value); if (tarif) { WSContentSend_PD(HTTP_ENERGY_TARIF_TELEINFO, kTtarifNames[tarif-1]); From dd6bce923245ec581cd40458a3a7f9835ab4fc81 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 15 Jun 2020 17:20:50 +0200 Subject: [PATCH 237/581] scripter fix hue, add ticker, add tesla json read --- tasmota/xdrv_10_scripter.ino | 136 +++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 35427e67a..163419cc8 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -67,6 +67,8 @@ keywords if then else endif, or, and are better readable for beginners (others m uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); + + // solve conficting defines // highest priority #ifdef USE_SCRIPT_FATFS @@ -118,6 +120,33 @@ uint32_t DecodeLightId(uint32_t hue_id); #endif #endif // USE_UNISHOX_COMPRESSION +#define USE_SCRIPT_TIMER + +#ifdef USE_SCRIPT_TIMER +#include +Ticker Script_ticker1; +Ticker Script_ticker2; +Ticker Script_ticker3; +Ticker Script_ticker4; + +void Script_ticker1_end(void) { + Script_ticker1.detach(); + Run_Scripter(">ti1", 4,0); +} +void Script_ticker2_end(void) { + Script_ticker2.detach(); + Run_Scripter(">ti2", 4,0); +} +void Script_ticker3_end(void) { + Script_ticker3.detach(); + Run_Scripter(">ti3", 4,0); +} +void Script_ticker4_end(void) { + Script_ticker4.detach(); + Run_Scripter(">ti4", 4,0); +} +#endif + #if defined(LITTLEFS_SCRIPT_SIZE) || (USE_SCRIPT_FATFS==-1) #ifdef ESP32 @@ -1876,6 +1905,20 @@ chknext: if (sp) strlcpy(sp,SettingsText(SET_MQTT_GRP_TOPIC),glob_script_mem.max_ssize); goto strexit; } + +#ifdef SCRIPT_GET_HTTPS_JP + if (!strncmp(vname,"gjp(",4)) { + char host[SCRIPT_MAXSSIZE]; + lp=GetStringResult(lp+4,OPER_EQU,host,0); + SCRIPT_SKIP_SPACES + char path[SCRIPT_MAXSSIZE]; + lp=GetStringResult(lp,OPER_EQU,path,0); + fvar=call2https(host,path); + lp++; + len=0; + goto exit; + } +#endif break; case 'h': if (!strncmp(vname,"hours",5)) { @@ -2410,6 +2453,41 @@ chknext: if (sp) strlcpy(sp,SettingsText(SET_MQTT_TOPIC),glob_script_mem.max_ssize); goto strexit; } +#ifdef USE_SCRIPT_TIMER + if (!strncmp(vname,"ts1(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + if (fvar<10) fvar=10; + Script_ticker1.attach_ms(fvar, Script_ticker1_end); + lp++; + len=0; + goto exit; + } + if (!strncmp(vname,"ts2(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + if (fvar<10) fvar=10; + Script_ticker2.attach_ms(fvar, Script_ticker2_end); + lp++; + len=0; + goto exit; + } + if (!strncmp(vname,"ts3(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + if (fvar<10) fvar=10; + Script_ticker3.attach_ms(fvar, Script_ticker3_end); + lp++; + len=0; + goto exit; + } + if (!strncmp(vname,"ts4(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + if (fvar<10) fvar=10; + Script_ticker4.attach_ms(fvar, Script_ticker4_end); + lp++; + len=0; + goto exit; + } +#endif // USE_SCRIPT_TIMER + #ifdef USE_DISPLAY #ifdef USE_TOUCH_BUTTONS if (!strncmp(vname,"tbut[",5)) { @@ -4817,9 +4895,11 @@ void Script_Check_Hue(String *response) { } else { if (hue_devs>0) *response+=",\""; + else *response+="\""; } *response+=String(EncodeLightId(hue_devs+devices_present+1))+"\":"; Script_HueStatus(response,hue_devs); + //AddLog_P2(LOG_LEVEL_INFO, PSTR("Hue: %s - %d "),response->c_str(), hue_devs); } hue_devs++; @@ -6118,6 +6198,62 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { #endif // USE_SCRIPT_TASK #endif // ESP32 + +#ifdef SCRIPT_GET_HTTPS_JP +#ifdef ESP8266 +#include "WiFiClientSecureLightBearSSL.h" +#else +#include +#endif + +// get tesla powerwall info page json string +uint32_t call2https(const char *host, const char *path) { + if (global_state.wifi_down) return 1; + uint32_t status=0; +#ifdef ESP32 + WiFiClientSecure *httpsClient; + httpsClient = new WiFiClientSecure; +#else + BearSSL::WiFiClientSecure_light *httpsClient; + httpsClient = new BearSSL::WiFiClientSecure_light(1024, 1024); +#endif + + httpsClient->setTimeout(1500); + + int retry = 0; + String result; + while ((!httpsClient->connect(host, 443)) && (retry < 5)) { + delay(100); + retry++; + } + if (retry == 5) { + return 2; + } + String request = String("GET ") + path + + " HTTP/1.1\r\n" + + "Host: " + host + + "\r\n" + "Connection: close\r\n\r\n"; + httpsClient->print(request); + + while (httpsClient->connected()) { + String line = httpsClient->readStringUntil('\n'); + if (line == "\r") { + break; + } + } + while (httpsClient->available()) { + String line = httpsClient->readStringUntil('\n'); + if (line!="") { + result += line; + } + } + httpsClient->stop(); + Run_Scripter(">jp",3,(char*)result.c_str()); + return 0; +} + +#endif // SCRIPT_GET_HTTPS_JP + /*********************************************************************************************\ * Interface \*********************************************************************************************/ From ef0b7976868990173c0d8f00249476e523f0a1ea Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 15 Jun 2020 18:27:04 +0200 Subject: [PATCH 238/581] Add basic support for ESP32 ethernet Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON (#8503) --- RELEASENOTES.md | 3 +- tasmota/CHANGELOG.md | 4 + tasmota/i18n.h | 2 + tasmota/settings.h | 10 +- tasmota/settings.ino | 8 ++ tasmota/support.ino | 13 +-- tasmota/support_command.ino | 17 +++- tasmota/support_tasmota.ino | 92 +++++++++++++++--- tasmota/support_wifi.ino | 146 ++++++++++++++++------------- tasmota/tasmota.ino | 4 +- tasmota/tasmota_globals.h | 10 ++ tasmota/tasmota_version.h | 2 +- tasmota/xdrv_01_webserver.ino | 45 ++++++--- tasmota/xdrv_02_mqtt.ino | 4 +- tasmota/xdrv_10_scripter.ino | 2 +- tasmota/xdrv_11_knx.ino | 2 +- tasmota/xdrv_12_home_assistant.ino | 4 +- tasmota/xdrv_13_display.ino | 8 +- tasmota/xdrv_82_ethernet.ino | 131 ++++++++++++++++++++++++++ tasmota/xdsp_04_ili9341.ino | 4 + tools/decode-status.py | 2 +- 21 files changed, 393 insertions(+), 120 deletions(-) create mode 100644 tasmota/xdrv_82_ethernet.ino diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2f9d95ed2..72fd4b113 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,7 +52,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.3.1.3 +### Version 8.3.1.4 - Change IRremoteESP8266 library updated to v2.7.7 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) @@ -79,3 +79,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add initial support for Telegram bot (#8619) - Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) - Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet +- Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 73582dfb7..02b4dc209 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased (development) +### 8.3.1.4 20200615 + +- Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON + ### 8.3.1.3 20200611 - Add initial support for Telegram bot (#8619) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 01122fabd..1a254bdfc 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -271,6 +271,8 @@ #define D_CMND_SSID "SSId" #define D_CMND_PASSWORD "Password" #define D_CMND_HOSTNAME "Hostname" +#define D_CMND_WIFI "Wifi" +#define D_CMND_ETHERNET "Ethernet" #define D_CMND_WIFICONFIG "WifiConfig" #define D_WCFG_0_RESTART "Restart" #define D_WCFG_2_WIFIMANAGER "WifiManager" diff --git a/tasmota/settings.h b/tasmota/settings.h index 08175d7db..afc2f5672 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -114,8 +114,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t pwm_ct_mode : 1; // bit 10 (v8.2.0.4) - SetOption92 - Set PWM Mode from regular PWM to ColorTemp control (Xiaomi Philips ...) uint32_t compress_rules_cpu : 1; // bit 11 (v8.2.0.6) - SetOption93 - Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick uint32_t max6675 : 1; // bit 12 (v8.3.1.2) - SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855 - uint32_t spare13 : 1; - uint32_t spare14 : 1; + uint32_t network_wifi : 1; // bit 13 (v8.3.1.3) - CMND_WIFI + uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) = CMND_ETHERNET uint32_t spare15 : 1; uint32_t spare16 : 1; uint32_t spare17 : 1; @@ -676,10 +676,10 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu typedef union { uint8_t data; struct { - uint8_t wifi_down : 1; + uint8_t network_down : 1; uint8_t mqtt_down : 1; - uint8_t spare02 : 1; - uint8_t spare03 : 1; + uint8_t wifi_down : 1; + uint8_t eth_down : 1; uint8_t spare04 : 1; uint8_t spare05 : 1; uint8_t spare06 : 1; diff --git a/tasmota/settings.ino b/tasmota/settings.ino index f8aa19ab9..1b2dca82d 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -798,7 +798,11 @@ void SettingsDefaultSet2(void) Settings.serial_delimiter = 0xff; Settings.seriallog_level = SERIAL_LOG_LEVEL; + // Ethernet + flag4.network_ethernet |= 1; + // Wifi + flag4.network_wifi |= 1; flag3.use_wifi_scan |= WIFI_SCAN_AT_RESTART; flag3.use_wifi_rescan |= WIFI_SCAN_REGULARLY; Settings.wifi_output_power = 170; @@ -1439,6 +1443,10 @@ void SettingsDelta(void) Settings.ledpwm_on = 255; Settings.ledpwm_mask = 0; } + if (Settings.version < 0x08030104) { + Settings.flag4.network_wifi = 1; + Settings.flag4.network_ethernet = 1; + } Settings.version = VERSION; SettingsSave(1); diff --git a/tasmota/support.ino b/tasmota/support.ino index 0a5d26f10..8b2c144f7 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -156,7 +156,7 @@ float CharToFloat(const char *str) signed char sign = 1; if (*pt == '-') { sign = -1; } - if (*pt == '-' || *pt=='+') { pt++; } // Skip any sign + if (*pt == '-' || *pt == '+') { pt++; } // Skip any sign float left = 0; if (*pt != '.') { @@ -167,8 +167,9 @@ float CharToFloat(const char *str) float right = 0; if (*pt == '.') { pt++; - // limit decimals to float max - pt[7]=0; + uint32_t max_decimals = 0; + while ((max_decimals < 8) && isdigit(pt[max_decimals])) { max_decimals++; } + pt[max_decimals] = '\0'; // Limit decimals to float max of 8 right = atoi(pt); // Decimal part while (isdigit(*pt)) { pt++; @@ -1740,7 +1741,7 @@ void Syslog(void) } if (PortUdp.beginPacket(syslog_host_addr, Settings.syslog_port)) { char syslog_preamble[64]; // Hostname + Id - snprintf_P(syslog_preamble, sizeof(syslog_preamble), PSTR("%s ESP-"), my_hostname); + snprintf_P(syslog_preamble, sizeof(syslog_preamble), PSTR("%s ESP-"), NetworkHostname()); memmove(log_data + strlen(syslog_preamble), log_data, sizeof(log_data) - strlen(syslog_preamble)); log_data[sizeof(log_data) -1] = '\0'; memcpy(log_data, syslog_preamble, strlen(syslog_preamble)); @@ -1787,7 +1788,7 @@ void AddLog(uint32_t loglevel) !global_state.mqtt_down && (loglevel <= Settings.mqttlog_level)) { MqttPublishLogging(mxtime); } - if (!global_state.wifi_down && + if (!global_state.network_down && (loglevel <= syslog_level)) { Syslog(); } prepped_loglevel = 0; @@ -1910,4 +1911,4 @@ String Decompress(const char * compressed, size_t uncompressed_size) { return content; } -#endif // USE_UNISHOX_COMPRESSION +#endif // USE_UNISHOX_COMPRESSION \ No newline at end of file diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index fe855ee92..5d0180005 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -27,7 +27,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_LEDPWM_ON "|" D_CMND_LEDPWM_OFF "|" D_CMND_LEDPWM_MODE "|" - D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" + D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_WIFI "|" #ifdef USE_I2C D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|" #endif @@ -54,7 +54,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode, - &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, + &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndWifi, #ifdef USE_I2C &CmndI2cScan, CmndI2cDriver, #endif @@ -499,8 +499,8 @@ void CmndStatus(void) Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_GATEWAY "\":\"%s\",\"" D_JSON_SUBNETMASK "\":\"%s\",\"" D_JSON_DNSSERVER "\":\"%s\",\"" D_JSON_MAC "\":\"%s\",\"" D_CMND_WEBSERVER "\":%d,\"" D_CMND_WIFICONFIG "\":%d,\"" D_CMND_WIFIPOWER "\":%s}}"), - my_hostname, WiFi.localIP().toString().c_str(), IPAddress(Settings.ip_address[1]).toString().c_str(), - IPAddress(Settings.ip_address[2]).toString().c_str(), IPAddress(Settings.ip_address[3]).toString().c_str(), WiFi.macAddress().c_str(), + NetworkHostname(), NetworkAddress().toString().c_str(), IPAddress(Settings.ip_address[1]).toString().c_str(), + IPAddress(Settings.ip_address[2]).toString().c_str(), IPAddress(Settings.ip_address[3]).toString().c_str(), NetworkMacAddress().c_str(), Settings.webserver, Settings.sta_config, WifiGetOutputPower().c_str()); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "5")); } @@ -1497,6 +1497,15 @@ void CmndWifiConfig(void) Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, Settings.sta_config, GetTextIndexed(stemp1, sizeof(stemp1), Settings.sta_config, kWifiConfig)); } +void CmndWifi(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings.flag4.network_wifi = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndStateText(Settings.flag4.network_wifi); +} + void CmndDevicename(void) { if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) { diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 3cbfb497c..a7430dfbb 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -684,10 +684,14 @@ void MqttShowState(void) MqttShowPWMState(); } - int32_t rssi = WiFi.RSSI(); - ResponseAppend_P(PSTR(",\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_RSSI "\":%d,\"" D_JSON_SIGNAL "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}}"), - Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WiFi.BSSIDstr().c_str(), WiFi.channel(), - WifiGetRssiAsQuality(rssi), rssi, WifiLinkCount(), WifiDowntime().c_str()); + if (!global_state.wifi_down) { + int32_t rssi = WiFi.RSSI(); + ResponseAppend_P(PSTR(",\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_RSSI "\":%d,\"" D_JSON_SIGNAL "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}"), + Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WiFi.BSSIDstr().c_str(), WiFi.channel(), + WifiGetRssiAsQuality(rssi), rssi, WifiLinkCount(), WifiDowntime().c_str()); + } + + ResponseJsonEnd(); } void MqttPublishTeleState(void) @@ -824,7 +828,7 @@ void PerformEverySecond(void) if (Settings.tele_period) { if (tele_period >= 9999) { - if (!global_state.wifi_down) { + if (!global_state.network_down) { tele_period = 0; // Allow teleperiod once wifi is connected } } else { @@ -916,10 +920,12 @@ void Every250mSeconds(void) state_250mS++; state_250mS &= 0x3; + global_state.network_down = (global_state.wifi_down && global_state.eth_down); + if (!Settings.flag.global_state) { // Problem blinkyblinky enabled - SetOption31 - Control link led blinking - if (global_state.data) { // Any problem + if (global_state.data &0x03) { // Any problem if (global_state.mqtt_down) { blinkinterval = 7; } // MQTT problem so blink every 2 seconds (slowest) - if (global_state.wifi_down) { blinkinterval = 3; } // Wifi problem so blink every second (slow) + if (global_state.network_down) { blinkinterval = 3; } // Network problem so blink every second (slow) blinks = 201; // Allow only a single blink in case the problem is solved } } @@ -1151,11 +1157,75 @@ void Every250mSeconds(void) } break; case 2: // Every x.5 second - WifiCheck(wifi_state_flag); - wifi_state_flag = WIFI_RESTART; + if (Settings.flag4.network_wifi) { + WifiCheck(wifi_state_flag); + wifi_state_flag = WIFI_RESTART; + } break; case 3: // Every x.75 second - if (!global_state.wifi_down) { MqttCheck(); } + if (!global_state.network_down) { +#ifdef FIRMWARE_MINIMAL + if (1 == RtcSettings.ota_loader) { + RtcSettings.ota_loader = 0; + ota_state_flag = 3; + } +#endif // FIRMWARE_MINIMAL + +#ifdef USE_DISCOVERY + StartMdns(); +#endif // USE_DISCOVERY + +#ifdef USE_WEBSERVER + if (Settings.webserver) { + +#ifdef ESP8266 + StartWebserver(Settings.webserver, WiFi.localIP()); +#else // ESP32 +#ifdef USE_ETHERNET + StartWebserver(Settings.webserver, (EthernetLocalIP()) ? EthernetLocalIP() : WiFi.localIP()); +#else + StartWebserver(Settings.webserver, WiFi.localIP()); +#endif +#endif + +#ifdef USE_DISCOVERY +#ifdef WEBSERVER_ADVERTISE + MdnsAddServiceHttp(); +#endif // WEBSERVER_ADVERTISE +#endif // USE_DISCOVERY + } else { + StopWebserver(); + } +#ifdef USE_EMULATION + if (Settings.flag2.emulation) { UdpConnect(); } +#endif // USE_EMULATION +#endif // USE_WEBSERVER + +#ifdef USE_DEVICE_GROUPS + DeviceGroupsStart(); +#endif // USE_DEVICE_GROUPS + +#ifdef USE_KNX + if (!knx_started && Settings.flag.knx_enabled) { // CMND_KNX_ENABLED + KNXStart(); + knx_started = true; + } +#endif // USE_KNX + + MqttCheck(); + } else { +#ifdef USE_EMULATION + UdpDisconnect(); +#endif // USE_EMULATION + +#ifdef USE_DEVICE_GROUPS + DeviceGroupsStop(); +#endif // USE_DEVICE_GROUPS + +#ifdef USE_KNX + knx_started = false; +#endif // USE_KNX + } break; } } @@ -1174,7 +1244,7 @@ uint16_t arduino_ota_progress_dot_count = 0; void ArduinoOTAInit(void) { ArduinoOTA.setPort(8266); - ArduinoOTA.setHostname(my_hostname); + ArduinoOTA.setHostname(NetworkHostname()); if (strlen(SettingsText(SET_WEBPWD))) { ArduinoOTA.setPassword(SettingsText(SET_WEBPWD)); } diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino index c42e1d49a..2829481f9 100644 --- a/tasmota/support_wifi.ino +++ b/tasmota/support_wifi.ino @@ -352,6 +352,9 @@ void WifiSetState(uint8_t state) } } global_state.wifi_down = state ^1; + if (!global_state.wifi_down) { + global_state.network_down = 0; + } } #if LWIP_IPV6 @@ -373,6 +376,39 @@ String WifiGetIPv6(void) return ""; } +#ifdef USE_DISCOVERY +void StartMdns(void) { + if (Settings.flag3.mdns_enabled) { // SetOption55 - Control mDNS service + if (!Wifi.mdns_begun) { +// if (mdns_delayed_start) { +// AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION)); +// mdns_delayed_start--; +// } else { +// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START]; + Wifi.mdns_begun = (uint8_t)MDNS.begin(my_hostname); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Wifi.mdns_begun) ? D_INITIALIZED : D_FAILED); +// } + } + } +} + +#ifdef WEBSERVER_ADVERTISE +void MdnsAddServiceHttp(void) { + if (1 == Wifi.mdns_begun) { + Wifi.mdns_begun = 2; + MDNS.addService("http", "tcp", WEB_PORT); + } +} + +void MdnsUpdate(void) { + if (2 == Wifi.mdns_begun) { + MDNS.update(); + AddLog_P(LOG_LEVEL_DEBUG_MORE, D_LOG_MDNS, "MDNS.update"); + } +} +#endif // WEBSERVER_ADVERTISE +#endif // USE_DISCOVERY + bool WifiCheckIPAddrStatus(void) // Return false for 169.254.x.x or fe80::/64 { bool ip_global=false; @@ -410,10 +446,7 @@ void WifiCheckIp(void) Wifi.status = WL_CONNECTED; #ifdef USE_DISCOVERY #ifdef WEBSERVER_ADVERTISE - if (2 == Wifi.mdns_begun) { - MDNS.update(); - AddLog_P(LOG_LEVEL_DEBUG_MORE, D_LOG_MDNS, "MDNS.update"); - } + MdnsUpdate(); #endif // USE_DISCOVERY #endif // WEBSERVER_ADVERTISE } else { @@ -529,75 +562,14 @@ void WifiCheck(uint8_t param) if ((WL_CONNECTED == WiFi.status()) && (static_cast(WiFi.localIP()) != 0) && !Wifi.config_type) { #endif // LWIP_IPV6=1 WifiSetState(1); - if (Settings.flag3.use_wifi_rescan) { // SetOption57 - Scan wifi network every 44 minutes for configured AP's if (!(uptime % (60 * WIFI_RESCAN_MINUTES))) { Wifi.scan_state = 2; } } - -#ifdef FIRMWARE_MINIMAL - if (1 == RtcSettings.ota_loader) { - RtcSettings.ota_loader = 0; - ota_state_flag = 3; - } -#endif // FIRMWARE_MINIMAL - -#ifdef USE_DISCOVERY - if (Settings.flag3.mdns_enabled) { // SetOption55 - Control mDNS service - if (!Wifi.mdns_begun) { -// if (mdns_delayed_start) { -// AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION)); -// mdns_delayed_start--; -// } else { -// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START]; - Wifi.mdns_begun = (uint8_t)MDNS.begin(my_hostname); - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Wifi.mdns_begun) ? D_INITIALIZED : D_FAILED); -// } - } - } -#endif // USE_DISCOVERY - -#ifdef USE_WEBSERVER - if (Settings.webserver) { - StartWebserver(Settings.webserver, WiFi.localIP()); -#ifdef USE_DISCOVERY -#ifdef WEBSERVER_ADVERTISE - if (1 == Wifi.mdns_begun) { - Wifi.mdns_begun = 2; - MDNS.addService("http", "tcp", WEB_PORT); - } -#endif // WEBSERVER_ADVERTISE -#endif // USE_DISCOVERY - } else { - StopWebserver(); - } -#ifdef USE_EMULATION - if (Settings.flag2.emulation) { UdpConnect(); } -#endif // USE_EMULATION -#endif // USE_WEBSERVER -#ifdef USE_DEVICE_GROUPS - DeviceGroupsStart(); -#endif // USE_DEVICE_GROUPS -#ifdef USE_KNX - if (!knx_started && Settings.flag.knx_enabled) { // CMND_KNX_ENABLED - KNXStart(); - knx_started = true; - } -#endif // USE_KNX - } else { WifiSetState(0); -#ifdef USE_EMULATION - UdpDisconnect(); -#endif // USE_EMULATION -#ifdef USE_DEVICE_GROUPS - DeviceGroupsStop(); -#endif // USE_DEVICE_GROUPS Wifi.mdns_begun = 0; -#ifdef USE_KNX - knx_started = false; -#endif // USE_KNX } } } @@ -652,6 +624,8 @@ RF_PRE_INIT() void WifiConnect(void) { + if (!Settings.flag4.network_wifi) { return; } + WifiSetState(0); WifiSetOutputPower(); WiFi.persistent(false); // Solve possible wifi init errors @@ -760,4 +734,44 @@ void wifiKeepAlive(void) { SetNextTimeInterval(wifiTimer, wifiTimerSec * 1000); } } -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 \ No newline at end of file +#endif // ARDUINO_ESP8266_RELEASE_2_3_0 + + +char* NetworkHostname(void) { + if (global_state.eth_down) { + return my_hostname; + } +#ifdef ESP32 +#ifdef USE_ETHERNET + else { + return EthernetHostname(); + } +#endif +#endif +} + +IPAddress NetworkAddress(void) { + if (global_state.eth_down) { + return WiFi.localIP(); + } +#ifdef ESP32 +#ifdef USE_ETHERNET + else { + return EthernetLocalIP(); + } +#endif +#endif +} + +String NetworkMacAddress(void) { + if (global_state.eth_down) { + return WiFi.macAddress(); + } +#ifdef ESP32 +#ifdef USE_ETHERNET + else { + return EthernetMacAddress(); + } +#endif +#endif +} diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 06bd8d9e7..4a35d4327 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -205,7 +205,7 @@ void setup(void) { #endif #endif - global_state.data = 3; // Init global state (wifi_down, mqtt_down) to solve possible network issues + global_state.data = 0xF; // Init global state (wifi_down, mqtt_down) to solve possible network issues RtcRebootLoad(); if (!RtcRebootValid()) { @@ -413,7 +413,7 @@ void loop(void) { if (my_activity < (uint32_t)ssleep) { SleepDelay((uint32_t)ssleep - my_activity); // Provide time for background tasks like wifi } else { - if (global_state.wifi_down) { + if (global_state.network_down) { SleepDelay(my_activity /2); // If wifi down and my_activity > setoption36 then force loop delay to 1/3 of my_activity period } } diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index f33024c45..c2acc6911 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -43,6 +43,16 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end); extern "C" void resetPins(); +#ifdef ESP32 + +#ifdef USE_ETHERNET +IPAddress EthernetLocalIP(void); +char* EthernetHostname(void); +String EthernetMacAddress(void); +#endif + +#endif // ESP32 + /*********************************************************************************************\ * Preconfigured configurations \*********************************************************************************************/ diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index f22a0288b..e01e1bcce 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08030103; +const uint32_t VERSION = 0x08030104; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 7fcd82a9f..52bdda713 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -868,10 +868,16 @@ void StartWebserver(int type, IPAddress ipweb) if (Web.state != type) { #if LWIP_IPV6 String ipv6_addr = WifiGetIPv6(); - if(ipv6_addr!="") AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s and IPv6 global address %s "), my_hostname, (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str(),ipv6_addr.c_str()); - else AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), my_hostname, (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str()); + if (ipv6_addr!="") { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s and IPv6 global address %s "), + NetworkHostname(), (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str(), ipv6_addr.c_str()); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), + NetworkHostname(), (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str()); + } #else - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), my_hostname, (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str()); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), + NetworkHostname(), (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str()); #endif // LWIP_IPV6 = 1 rules_flag.http_init = 1; } @@ -1151,7 +1157,7 @@ void WSContentSendStyle_P(const char* formatP, ...) bool lip = (static_cast(WiFi.localIP()) != 0); bool sip = (static_cast(WiFi.softAPIP()) != 0); WSContentSend_P(PSTR("

%s%s (%s%s%s)

"), // tasmota.local (192.168.2.12, 192.168.4.1) - my_hostname, + NetworkHostname(), (Wifi.mdns_begun) ? ".local" : "", (lip) ? WiFi.localIP().toString().c_str() : "", (lip && sip) ? ", " : "", @@ -2471,26 +2477,39 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1" D_FRIENDLY_NAME " %d}2%s"), i +1, SettingsText(SET_FRIENDLYNAME1 +i)); } WSContentSend_P(PSTR("}1}2 ")); // Empty line - int32_t rssi = WiFi.RSSI(); - WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WifiGetRssiAsQuality(rssi), rssi); - WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Wifi.mdns_begun) ? ".local" : ""); +#ifdef ESP32 +#ifdef USE_ETHERNET + if (static_cast(EthernetLocalIP()) != 0) { + WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Wifi.mdns_begun) ? ".local" : ""); + WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str()); + WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), EthernetLocalIP().toString().c_str()); + } +#endif +#endif + if (Settings.flag4.network_wifi) { + int32_t rssi = WiFi.RSSI(); + WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WifiGetRssiAsQuality(rssi), rssi); + WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Wifi.mdns_begun) ? ".local" : ""); #if LWIP_IPV6 String ipv6_addr = WifiGetIPv6(); - if(ipv6_addr != ""){ + if (ipv6_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Address }2%s"), ipv6_addr.c_str()); } #endif - if (static_cast(WiFi.localIP()) != 0) { - WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), WiFi.localIP().toString().c_str()); + if (static_cast(WiFi.localIP()) != 0) { + WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str()); + WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), WiFi.localIP().toString().c_str()); + } + } + if (!global_state.network_down) { WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), IPAddress(Settings.ip_address[1]).toString().c_str()); WSContentSend_P(PSTR("}1" D_SUBNET_MASK "}2%s"), IPAddress(Settings.ip_address[2]).toString().c_str()); WSContentSend_P(PSTR("}1" D_DNS_SERVER "}2%s"), IPAddress(Settings.ip_address[3]).toString().c_str()); - WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str()); } if (static_cast(WiFi.softAPIP()) != 0) { + WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), WiFi.softAPIP().toString().c_str()); WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), WiFi.softAPIP().toString().c_str()); - WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str()); } WSContentSend_P(PSTR("}1}2 ")); // Empty line if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT @@ -3288,7 +3307,7 @@ void CmndWebServer(void) } if (Settings.webserver) { Response_P(PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_JSON_ACTIVE_FOR " %s " D_JSON_ON_DEVICE " %s " D_JSON_WITH_IP_ADDRESS " %s\"}"), - (2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str()); + (2 == Settings.webserver) ? D_ADMIN : D_USER, NetworkHostname(), NetworkAddress().toString().c_str()); } else { ResponseCmndStateText(0); } diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 9e06f4e90..c06cb7dd1 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -539,10 +539,10 @@ void MqttConnected(void) if (Settings.webserver) { #if LWIP_IPV6 Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"IPv6Address\":\"%s\"}"), - (2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str(),WifiGetIPv6().c_str()); + (2 == Settings.webserver) ? D_ADMIN : D_USER, NetworkHostname(), NetworkAddress().toString().c_str(), WifiGetIPv6().c_str()); #else Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"), - (2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str()); + (2 == Settings.webserver) ? D_ADMIN : D_USER, NetworkHostname(), NetworkAddress().toString().c_str()); #endif // LWIP_IPV6 = 1 MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2")); } diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 163419cc8..7fc893ffc 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -799,7 +799,7 @@ char *script; IPAddress script_udp_remote_ip; void Script_Init_UDP() { - if (global_state.wifi_down) return; + if (global_state.network_down) return; if (glob_script_mem.udp_flags.udp_connected) return; if (PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), SCRIPT_UDP_PORT)) { diff --git a/tasmota/xdrv_11_knx.ino b/tasmota/xdrv_11_knx.ino index 47b62547d..f23e896fd 100644 --- a/tasmota/xdrv_11_knx.ino +++ b/tasmota/xdrv_11_knx.ino @@ -1208,7 +1208,7 @@ bool Xdrv11(uint8_t function) bool result = false; switch (function) { case FUNC_LOOP: - if (!global_state.wifi_down) { knx.loop(); } // Process knx events + if (!global_state.network_down) { knx.loop(); } // Process knx events break; case FUNC_EVERY_50_MSECOND: if (toggle_inhibit) { diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 7ede88b44..70ab6d620 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -201,7 +201,7 @@ void HAssAnnounceRelayLight(void) uint8_t max_lights = 1; #ifdef ESP8266 - if (PWM_DIMMER == my_module_type) { PwmMod = true; } + if (PWM_DIMMER == my_module_type) { PwmMod = true; } #endif //ESP8266 // If there is a special Light to be enabled and managed with SetOption68 or SetOption37 >= 128, Discovery calculates the maximum number of entities to be generated in advance @@ -719,7 +719,7 @@ void HAssPublishStatus(void) "\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_RSSI "\":\"%d\",\"" D_JSON_SIGNAL " (dBm)""\":\"%d\"," "\"WiFi " D_JSON_LINK_COUNT "\":%d,\"WiFi " D_JSON_DOWNTIME "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"LoadAvg\":%lu}"), my_version, my_image, GetBuildDateAndTime().c_str(), ModuleName().c_str(), GetResetReason().c_str(), - GetUptime().c_str(), my_hostname, WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()), + GetUptime().c_str(), NetworkHostname(), WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.RSSI(), WifiLinkCount(), WifiDowntime().c_str(), MqttConnectCount(), loop_load_avg); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_HASS_STATE)); } diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 43245c794..20e95eeb1 100644 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -1013,14 +1013,14 @@ void DisplayLogBufferInit(void) snprintf_P(buffer, sizeof(buffer), PSTR("Display mode %d"), Settings.display_mode); DisplayLogBufferAdd(buffer); - snprintf_P(buffer, sizeof(buffer), PSTR(D_CMND_HOSTNAME " %s"), my_hostname); + snprintf_P(buffer, sizeof(buffer), PSTR(D_CMND_HOSTNAME " %s"), NetworkHostname()); DisplayLogBufferAdd(buffer); - snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), SettingsText(SET_STASSID1 + Settings.sta_active)); + snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), NetworkMacAddress().c_str()); DisplayLogBufferAdd(buffer); - snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), WiFi.macAddress().c_str()); + snprintf_P(buffer, sizeof(buffer), PSTR("IP %s"), NetworkAddress().toString().c_str()); DisplayLogBufferAdd(buffer); if (!global_state.wifi_down) { - snprintf_P(buffer, sizeof(buffer), PSTR("IP %s"), WiFi.localIP().toString().c_str()); + snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), SettingsText(SET_STASSID1 + Settings.sta_active)); DisplayLogBufferAdd(buffer); snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_RSSI " %d%%"), WifiGetRssiAsQuality(WiFi.RSSI())); DisplayLogBufferAdd(buffer); diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino new file mode 100644 index 000000000..6d9725332 --- /dev/null +++ b/tasmota/xdrv_82_ethernet.ino @@ -0,0 +1,131 @@ +/* + xdrv_82_ethernet.ino - ESP32 (PoE) ethernet support for Tasmota + + Copyright (C) 2020 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 ESP32 +#ifdef USE_ETHERNET +/*********************************************************************************************\ + * Ethernet support for ESP32 +\*********************************************************************************************/ + +#define XDRV_82 82 + +// Olimex ESP32-PoE +#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT +#define ETH_PHY_POWER 12 + +#include + +struct { + char hostname[33]; +} Eth; + +void EthernetEvent(WiFiEvent_t event) { + switch (event) { + case SYSTEM_EVENT_ETH_START: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: " D_ATTEMPTING_CONNECTION)); + ETH.setHostname(Eth.hostname); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED)); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %s, Hostname %s"), + ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), Eth.hostname); +/* + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); +*/ + global_state.eth_down = 0; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: Disconnected")); + global_state.eth_down = 1; + break; + case SYSTEM_EVENT_ETH_STOP: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Stopped")); + global_state.eth_down = 1; + break; + default: + break; + } +} + +void EthernetInit(void) { + if (!Settings.flag4.network_ethernet) { return; } + + snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), my_hostname); + WiFi.onEvent(EthernetEvent); + ETH.begin(); +} + +IPAddress EthernetLocalIP(void) { + return ETH.localIP(); +} + +char* EthernetHostname(void) { + return Eth.hostname; +} + +String EthernetMacAddress(void) { + return ETH.macAddress(); +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +const char kEthernetCommands[] PROGMEM = "|" // No prefix + D_CMND_ETHERNET; + +void (* const EthernetCommand[])(void) PROGMEM = { + &CmndEthernet }; + +void CmndEthernet(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings.flag4.network_ethernet = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndStateText(Settings.flag4.network_ethernet); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv82(uint8_t function) { + bool result = false; + + switch (function) { + case FUNC_COMMAND: + result = DecodeCommand(kEthernetCommands, EthernetCommand); + break; + case FUNC_INIT: + EthernetInit(); + break; + } + return result; +} + +#endif // USE_ETHERNET +#endif // ESP32 diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index f755314c8..f5c485e6f 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -90,7 +90,11 @@ void Ili9341InitDriver(void) if (Settings.display_height != ILI9341_TFTHEIGHT) { Settings.display_height = ILI9341_TFTHEIGHT; } +#ifdef ESP8266 tft = new Adafruit_ILI9341(Pin(GPIO_SPI_CS), Pin(GPIO_SPI_DC)); +#else // ESP32 + tft = new Adafruit_ILI9341(Pin (GPIO_TFT_CS), Pin (GPIO_TFT_DC), Pin (GPIO_TFT_MOSI), Pin (GPIO_TFT_CLK), Pin (GPIO_TFT_RST), Pin(GPIO_TFT_MISO)); +#endif tft->begin(); #ifdef USE_DISPLAY_MODES1TO5 diff --git a/tools/decode-status.py b/tools/decode-status.py index 2ec5b472e..095e23e71 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -209,7 +209,7 @@ a_features = [[ "USE_HP303B","","","", "","","","", "","","","", - "","","","USE_WEBCAM" + "","","USE_ETHERNET","USE_WEBCAM" ]] usage = "usage: decode-status {-d | -f} arg" From 04e06df0ec0c51b5e31b8e463954ee2a70b0062b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 15 Jun 2020 18:36:26 +0200 Subject: [PATCH 239/581] Oops --- tasmota/my_user_config.h | 14 +++++++++++++- tasmota/support_features.ino | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index d6a140663..3bec4d347 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -589,7 +589,6 @@ //#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM) // #define USE_FLOG // Add support for GPS logging in OTA's Flash (Experimental) (+2k9 code, +8 bytes RAM) //#define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge (+9k3 code) -//#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) //#define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) //#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k6 code, 64 mem) #define USE_TASMOTA_SLAVE_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants @@ -720,6 +719,19 @@ // -- End of general directives ------------------- +/*********************************************************************************************\ + * ESP32 only features +\*********************************************************************************************/ + +#ifdef ESP32 + +//#define USE_ETHERNET // Add support for ethernet (Currently fixed for Olimex ESP32-PoE) +//#define USE_SPI // Add support for hardware SPI +//#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) +//#define USE_WEBCAM // Add support for webcam + +#endif + /*********************************************************************************************\ * Debug features \*********************************************************************************************/ diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index c973e30f5..1ff178eac 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -598,7 +598,9 @@ void GetFeatures(void) // feature6 |= 0x10000000; // feature6 |= 0x20000000; -// feature6 |= 0x40000000; +#ifdef USE_ETHERNET + feature6 |= 0x40000000; +#endif #ifdef USE_WEBCAM feature6 |= 0x80000000; #endif From 2181b0c1a4a676ea37e589f57e1a097857c69833 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 15 Jun 2020 19:22:56 +0200 Subject: [PATCH 240/581] Add serial to TCP bridge, ``TCPStart`` and ``TCPBaudRate`` (needs #define USE_TCP_BRIDGE) --- tasmota/CHANGELOG.md | 1 + tasmota/i18n.h | 1 + tasmota/language/bg_BG.h | 2 + tasmota/language/cs_CZ.h | 2 + tasmota/language/de_DE.h | 2 + tasmota/language/el_GR.h | 2 + tasmota/language/en_GB.h | 2 + tasmota/language/es_ES.h | 2 + tasmota/language/fr_FR.h | 2 + tasmota/language/he_HE.h | 2 + tasmota/language/hu_HU.h | 2 + tasmota/language/it_IT.h | 2 + tasmota/language/ko_KO.h | 2 + tasmota/language/nl_NL.h | 2 + tasmota/language/pl_PL.h | 2 + tasmota/language/pt_BR.h | 2 + tasmota/language/pt_PT.h | 2 + tasmota/language/ro_RO.h | 2 + tasmota/language/ru_RU.h | 2 + tasmota/language/sk_SK.h | 2 + tasmota/language/sv_SE.h | 2 + tasmota/language/tr_TR.h | 2 + tasmota/language/uk_UA.h | 2 + tasmota/language/zh_CN.h | 2 + tasmota/language/zh_TW.h | 2 + tasmota/my_user_config.h | 1 + tasmota/settings.h | 3 +- tasmota/tasmota_template.h | 9 +- tasmota/tasmota_template_ESP32.h | 8 +- tasmota/xdrv_41_tcp_bridge.ino | 205 +++++++++++++++++++++++++++++++ 30 files changed, 271 insertions(+), 3 deletions(-) create mode 100644 tasmota/xdrv_41_tcp_bridge.ino diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 02b4dc209..4e0cdc436 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -9,6 +9,7 @@ - Add initial support for Telegram bot (#8619) - Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) - Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet +- Add serial to TCP bridge, ``TCPStart`` and ``TCPBaudRate`` (needs #define USE_TCP_BRIDGE) ### 8.3.1.2 20200522 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 1a254bdfc..543a4c9b9 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -643,6 +643,7 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi #define D_LOG_ZIGBEE "ZIG: " // Zigbee +#define D_LOG_TCP "TCP: " // TCP bridge /********************************************************************************************/ diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 935704e74..62d48e0a4 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index a04a6b16b..cbbe58921 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 02464daa6..9c605da62 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 333458c72..ff5486540 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 92637b350..4f4180dd4 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 701f3e107..2447cdc05 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index f91bd7fbd..80cf87061 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 3550a1abd..e6af68ddc 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 1a58472e4..eb797bcab 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 22181a7be..75a1d4361 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index a004ecec7..4b7e8538a 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index ab6a28485..c9979814b 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index aea969baf..4827d26be 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 02c4b4ecc..450bea0d5 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 4507cecba..189b5ec3c 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 66e82ad55..aaea0a0b2 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 7c7fc770b..be28c69a2 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "Ð" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index e242f9bc1..4b667150a 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 1649b7f5f..edf7b3f1e 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 8a1063d7a..5089b6e15 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index a16675ae4..5f6b23754 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "Ð" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 0da3126fd..a86e2c7ee 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "安" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 1fb664d08..b1b4424cd 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -691,6 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "安" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 3bec4d347..1e57de3bb 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -577,6 +577,7 @@ #define STARTING_OFFSET 30 // Turn on NovaSDS XX-seconds before tele_period is reached //#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor (+1k4) #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code) +//#define USE_TCP_BRIDGE // Add support for Serial to TCP bridge (+1.3k code) //#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop #define MP3_VOLUME 10 // Set the startup volume on init, the range can be 0..30(max) //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) diff --git a/tasmota/settings.h b/tasmota/settings.h index afc2f5672..db19c1199 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -568,8 +568,9 @@ struct { uint8_t windmeter_tele_pchange; // F3E uint8_t ledpwm_on; // F3F uint8_t ledpwm_off; // F40 + uint8_t tcp_baudrate; // F41 - uint8_t free_f42[119]; // F41 - Decrement if adding new Setting variables just above and below + uint8_t free_f42[118]; // F42 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below uint16_t pulse_counter_debounce_low; // FB8 diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 8b44a547b..a87c39939 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -234,6 +234,8 @@ enum UserSelectablePins { GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin GPIO_WINDMETER_SPEED, // WindMeter speed counter pin GPIO_BL0940_RX, // BL0940 serial interface + GPIO_TCP_TX, // TCP Serial bridge + GPIO_TCP_RX, // TCP Serial bridge GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -324,7 +326,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX "|" D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" D_SENSOR_WINDMETER_SPEED "|" - D_SENSOR_BL0940_RX + D_SENSOR_BL0940_RX "|" + D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD ; const char kSensorNamesFixed[] PROGMEM = @@ -682,6 +685,10 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_AS3935 GPIO_AS3935, #endif +#ifdef USE_TCP_BRIDGE + AGPIO(GPIO_TCP_TX), // TCP Serial bridge + AGPIO(GPIO_TCP_RX), // TCP Serial bridge +#endif }; /********************************************************************************************/ diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index aea45ea6a..5457ed33a 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -129,6 +129,7 @@ enum UserSelectablePins { GPIO_WINDMETER_SPEED, // WindMeter speed counter pin GPIO_KEY1_TC, // Touch pin as button GPIO_BL0940_RX, // BL0940 serial interface + GPIO_TCP_TX, GPIO_TCP_RX, // TCP to serial bridge GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -218,7 +219,8 @@ const char kSensorNames[] PROGMEM = D_GPIO_WEBCAM_PSRCS "|" D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BUTTON "_tc|" - D_SENSOR_BL0940_RX + D_SENSOR_BL0940_RX "|" + D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD ; const char kSensorNamesFixed[] PROGMEM = @@ -547,6 +549,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_WEBCAM_PSCLK), AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD, AGPIO(GPIO_WEBCAM_PSRCS), +#endif +#ifdef USE_TCP_BRIDGE + AGPIO(GPIO_TCP_TX), // TCP Serial bridge + AGPIO(GPIO_TCP_RX), // TCP Serial bridge #endif AGPIO(GPIO_KEY1_TC) + MAX_KEYS }; diff --git a/tasmota/xdrv_41_tcp_bridge.ino b/tasmota/xdrv_41_tcp_bridge.ino new file mode 100644 index 000000000..a6513ec46 --- /dev/null +++ b/tasmota/xdrv_41_tcp_bridge.ino @@ -0,0 +1,205 @@ +/* + xdrv_41_tcp_bridge.ino - TCP to serial bridge + + Copyright (C) 2020 Theo Arends and Stephan Hadinger + + 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_TCP_BRIDGE + +#define XDRV_41 41 + +#ifndef TCP_BRIDGE_CONNECTIONS +#define TCP_BRIDGE_CONNECTIONS 2 // number of maximum parallel connections +#endif + +#ifndef TCP_BRIDGE_BUF_SIZE +#define TCP_BRIDGE_BUF_SIZE 255 // size of the buffer, above 132 required for efficient XMODEM +#endif + +//const uint16_t tcp_port = 8880; +WiFiServer *server_tcp = nullptr; +//WiFiClient client_tcp1, client_tcp2; +WiFiClient client_tcp[TCP_BRIDGE_CONNECTIONS]; +uint8_t client_next = 0; +uint8_t *tcp_buf = nullptr; // data transfer buffer + +#include +TasmotaSerial *TCPSerial = nullptr; + +const char kTCPCommands[] PROGMEM = "TCP" "|" // prefix + "Start" "|" "Baudrate" + ; + +void (* const TCPCommand[])(void) PROGMEM = { + &CmndTCPStart, &CmndTCPBaudrate + }; + +// +// Called at event loop, checks for incoming data from the CC2530 +// +void TCPLoop(void) +{ + uint8_t c; + bool busy; // did we transfer some data? + int32_t buf_len; + + if (!TCPSerial) return; + + // check for a new client connection + if ((server_tcp) && (server_tcp->hasClient())) { + // find an empty slot + uint32_t i; + for (i=0; iavailable(); + break; + } + } + if (i >= ARRAY_SIZE(client_tcp)) { + i = client_next++ % ARRAY_SIZE(client_tcp); + WiFiClient &client = client_tcp[i]; + client.stop(); + client = server_tcp->available(); + } + } + + do { + busy = false; // exit loop if no data was transferred + + // start reading the UART, this buffer can quickly overflow + buf_len = 0; + while ((buf_len < TCP_BRIDGE_BUF_SIZE) && (TCPSerial->available())) { + c = TCPSerial->read(); + if (c >= 0) { + tcp_buf[buf_len++] = c; + busy = true; + } + } + if (buf_len > 0) { + char hex_char[TCP_BRIDGE_BUF_SIZE+1]; + ToHex_P(tcp_buf, buf_len, hex_char, 256); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_TCP "from MCU: %s"), hex_char); + + for (uint32_t i=0; i= 0) { + tcp_buf[buf_len++] = c; + busy = true; + } + } + if (buf_len > 0) { + char hex_char[TCP_BRIDGE_BUF_SIZE+1]; + ToHex_P(tcp_buf, buf_len, hex_char, 256); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_TCP "to MCU/%d: %s"), i+1, hex_char); + TCPSerial->write(tcp_buf, buf_len); + } + } + + yield(); // avoid WDT if heavy traffic + } while (busy); +} + +/********************************************************************************************/ +void TCPInit(void) { + if (PinUsed(GPIO_TCP_RX) && PinUsed(GPIO_TCP_TX)) { + tcp_buf = (uint8_t*) malloc(TCP_BRIDGE_BUF_SIZE); + if (!tcp_buf) { AddLog_P2(LOG_LEVEL_ERROR, PSTR(D_LOG_TCP "could not allocate buffer")); return; } + + if (!Settings.tcp_baudrate) { Settings.tcp_baudrate = 115200 / 1200; } + TCPSerial = new TasmotaSerial(Pin(GPIO_TCP_RX), Pin(GPIO_TCP_TX), seriallog_level ? 1 : 2, 0, TCP_BRIDGE_BUF_SIZE); // set a receive buffer of 256 bytes + TCPSerial->begin(Settings.tcp_baudrate * 1200); + if (TCPSerial->hardwareSerial()) { + ClaimSerial(); + } + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +// +// Command `ZbConfig` +// +void CmndTCPStart(void) { + + if (!TCPSerial) { return; } + int32_t tcp_port = XdrvMailbox.payload; + + if (server_tcp) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_TCP "Stopping TCP server")); + server_tcp->stop(); + delete server_tcp; + server_tcp = nullptr; + + for (uint32_t i=0; i 0) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_TCP "Starting TCP server on port %d"), tcp_port); + server_tcp = new WiFiServer(tcp_port); + server_tcp->begin(); // start TCP server + server_tcp->setNoDelay(true); + } + + ResponseCmndDone(); +} + +void CmndTCPBaudrate(void) { + if ((XdrvMailbox.payload >= 1200) && (XdrvMailbox.payload <= 115200)) { + XdrvMailbox.payload /= 1200; // Make it a valid baudrate + Settings.tcp_baudrate = XdrvMailbox.payload; + TCPSerial->begin(Settings.tcp_baudrate * 1200); // Reinitialize serial port with new baud rate + } + ResponseCmndNumber(Settings.tcp_baudrate * 1200); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv41(uint8_t function) +{ + bool result = false; + + switch (function) { + case FUNC_LOOP: + TCPLoop(); + break; + case FUNC_PRE_INIT: + TCPInit(); + break; + case FUNC_COMMAND: + result = DecodeCommand(kTCPCommands, TCPCommand); + break; + } + return result; +} + +#endif // USE_TCP_BRIDGE From 44f9112545d4489a05d29fb11c3face162ea6c52 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 15 Jun 2020 20:13:05 +0200 Subject: [PATCH 241/581] Move Manuf/Model in defines --- tasmota/my_user_config.h | 2 ++ tasmota/xdrv_23_zigbee_8_parsers.ino | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 3bec4d347..d9a51ef41 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -660,6 +660,8 @@ #define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices #define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms) + #define USE_ZIGBEE_MODELID "Tasmota Z2T" // reported "ModelId" (cluster 0000 / attribute 0005) + #define USE_ZIGBEE_MANUFACTURER "Tasmota" // reported "Manufacturer" (cluster 0000 / attribute 0004) // -- Other sensors/drivers ----------------------- diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index aad2732ca..53590a4c4 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -835,8 +835,8 @@ void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const // responder switch (cluster) { case 0x0000: - if (HasKeyCaseInsensitive(json, PSTR("ModelId"))) { json_out[F("ModelId")] = F("Tasmota Z2T"); } - if (HasKeyCaseInsensitive(json, PSTR("Manufacturer"))) { json_out[F("Manufacturer")] = F("Tasmota"); } + if (HasKeyCaseInsensitive(json, PSTR("ModelId"))) { json_out[F("ModelId")] = F(USE_ZIGBEE_MODELID); } + if (HasKeyCaseInsensitive(json, PSTR("Manufacturer"))) { json_out[F("Manufacturer")] = F(USE_ZIGBEE_MANUFACTURER); } break; #ifdef USE_LIGHT case 0x0006: From 93a38e892c1b4f0096841ccc078deb12c4c195fe Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 15 Jun 2020 21:52:47 +0200 Subject: [PATCH 242/581] @s-hadinger requests before merging PR --- RELEASENOTES.md | 4 ++-- tasmota/tasmota_template.h | 24 ++---------------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 608cb67c9..af9be6756 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -54,8 +54,6 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ### Version 8.3.1.3 -- Created Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff -- Added Library to be used for decoding Teleinfo (French Metering Smart Meter) - Change IRremoteESP8266 library updated to v2.7.7 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` @@ -81,3 +79,5 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add initial support for Telegram bot (#8619) - Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) - Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet +- Created Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff +- Added Library to be used for decoding Teleinfo (French Metering Smart Meter) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index a0146aece..dab425f01 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -778,7 +778,7 @@ enum SupportedModules { SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH, OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4, OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, - SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, DENKY, + SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, MAXMODULE}; #define USER_MODULE 255 @@ -791,7 +791,7 @@ const char kModuleNames[] PROGMEM = "Sonoff S31|Zengge WF017|Sonoff Pow R2|Sonoff iFan02|BlitzWolf SHP|Shelly 1|Shelly 2|Xiaomi Philips|Neo Coolcam|ESP Switch|" "OBI Socket|Teckin|AplicWDP303075|Tuya MCU|Gosund SP1 v23|ARMTR Dimmer|SK03 Outdoor|PS-16-DZ|Teckin US|Manzoku strip|" "OBI Socket 2|YTF IR Bridge|Digoo DG-SP202|KA10|Luminea ZX2820|Mi Desk Lamp|SP10|WAGA CHCZ02MB|SYF05|Sonoff L1|" - "Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1|Denky (Teleinfo)" + "Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1" ; const uint8_t kModuleNiceList[] PROGMEM = { @@ -2174,26 +2174,6 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_LED1_INV, // GPIO13 WiFi Blue Led - Link and Power status 0, 0, 0, 0 }, - { // Denky (Teleinfo) Any ESP8266 device - GPIO_WS2812, // GPIO00 WS2812 RGB LED - GPIO_USER, // GPIO01 TX Serial RXD - GPIO_USER, // GPIO02 D4 Wemos DHT Shield - GPIO_TELEINFO_RX, // GPIO03 Smart Meter RX Serial - GPIO_I2C_SDA, // GPIO04 D2 Wemos I2C SDA - GPIO_I2C_SCL, // GPIO05 D1 Wemos I2C SCL - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - GPIO_USER, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - GPIO_USER, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPIO_USER, // GPIO12 D6 - GPIO_USER, // GPIO13 D7 - GPIO_USER, // GPIO14 D5 - GPIO_USER, // GPIO15 D8 - GPIO_USER, // GPIO16 D0 Wemos Wake - ADC0_USER // ADC0 A0 Analog input - }, { // SONOFF_IFAN03 - Sonoff iFan03 (ESP8285) GPIO_KEY1, // GPIO00 WIFI_KEY0 Button 1 GPIO_TXD, // GPIO01 ESP_TXD Serial RXD connection to P0.5 of RF microcontroller From 7a297d1828285b1c2500e201ee16e948b6f6a2e4 Mon Sep 17 00:00:00 2001 From: Charles Date: Mon, 15 Jun 2020 22:01:45 +0200 Subject: [PATCH 243/581] Added code size --- tasmota/tasmota_configurations.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index af10f9ce5..eb58d30e5 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -168,7 +168,7 @@ #define USE_DDSU666 // Add support for Chint DDSU666 Modbus energy monitor (+0k6 code) //#define USE_SOLAX_X1 // Add support for Solax X1 series Modbus log info (+3k1 code) //#define USE_LE01MR // Add support for F&F LE-01MR modbus energy meter (+2k code) -//#define USE_TELEINFO // Add support for French Energy Provider metering telemetry +//#define USE_TELEINFO // Add support for French Energy Provider metering telemetry (+5k2 code, +168 RAM + SmartMeter LinkedList Values RAM) #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #define USE_MAX31855 // Add support for MAX31855 K-Type thermocouple sensor using softSPI From c1d0d20996f4fc32863273f75b18a83005fe97b8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 15 Jun 2020 22:10:49 +0200 Subject: [PATCH 244/581] Fix mdns related compile error --- tasmota/support_network.ino | 128 ++++++++++++++++++++++++++++++++++ tasmota/support_wifi.ino | 76 +------------------- tasmota/xdrv_01_webserver.ino | 12 ++-- tasmota/xdrv_02_mqtt.ino | 28 -------- 4 files changed, 135 insertions(+), 109 deletions(-) create mode 100644 tasmota/support_network.ino diff --git a/tasmota/support_network.ino b/tasmota/support_network.ino new file mode 100644 index 000000000..4f6da4d88 --- /dev/null +++ b/tasmota/support_network.ino @@ -0,0 +1,128 @@ +/* + support_network.ino - Network support for Tasmota + + Copyright (C) 2020 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 . +*/ + +/*********************************************************************************************\ + * MDNS +\*********************************************************************************************/ + +struct { + uint8_t begun = 0; // mDNS active +} Mdns; + +#ifdef USE_DISCOVERY +void StartMdns(void) { + if (Settings.flag3.mdns_enabled) { // SetOption55 - Control mDNS service + if (!Mdns.begun) { +// if (mdns_delayed_start) { +// AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION)); +// mdns_delayed_start--; +// } else { +// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START]; + Mdns.begun = (uint8_t)MDNS.begin(my_hostname); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Mdns.begun) ? D_INITIALIZED : D_FAILED); +// } + } + } +} + +#ifdef MQTT_HOST_DISCOVERY +void MqttDiscoverServer(void) +{ + if (!Mdns.begun) { return; } + + int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service + + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n); + + if (n > 0) { + uint32_t i = 0; // If the hostname isn't set, use the first record found. +#ifdef MDNS_HOSTNAME + for (i = n; i > 0; i--) { // Search from last to first and use first if not found + if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) { + break; // Stop at matching record + } + } +#endif // MDNS_HOSTNAME + SettingsUpdateText(SET_MQTT_HOST, MDNS.IP(i).toString().c_str()); + Settings.mqtt_port = MDNS.port(i); + + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), SettingsText(SET_MQTT_HOST), Settings.mqtt_port); + } +} +#endif // MQTT_HOST_DISCOVERY + +#ifdef WEBSERVER_ADVERTISE +void MdnsAddServiceHttp(void) { + if (1 == Mdns.begun) { + Mdns.begun = 2; + MDNS.addService("http", "tcp", WEB_PORT); + } +} + +void MdnsUpdate(void) { + if (2 == Mdns.begun) { + MDNS.update(); + AddLog_P(LOG_LEVEL_DEBUG_MORE, D_LOG_MDNS, "MDNS.update"); + } +} +#endif // WEBSERVER_ADVERTISE +#endif // USE_DISCOVERY + +/*********************************************************************************************\ + * Global network parameters +\*********************************************************************************************/ + +char* NetworkHostname(void) { + if (global_state.eth_down) { + return my_hostname; + } +#ifdef ESP32 +#ifdef USE_ETHERNET + else { + return EthernetHostname(); + } +#endif +#endif +} + +IPAddress NetworkAddress(void) { + if (global_state.eth_down) { + return WiFi.localIP(); + } +#ifdef ESP32 +#ifdef USE_ETHERNET + else { + return EthernetLocalIP(); + } +#endif +#endif +} + +String NetworkMacAddress(void) { + if (global_state.eth_down) { + return WiFi.macAddress(); + } +#ifdef ESP32 +#ifdef USE_ETHERNET + else { + return EthernetMacAddress(); + } +#endif +#endif +} diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino index 2829481f9..75de2523f 100644 --- a/tasmota/support_wifi.ino +++ b/tasmota/support_wifi.ino @@ -52,7 +52,6 @@ struct WIFI { uint8_t status; uint8_t config_type = 0; uint8_t config_counter = 0; - uint8_t mdns_begun = 0; // mDNS active uint8_t scan_state; uint8_t bssid[6]; int8_t best_network_db; @@ -376,39 +375,6 @@ String WifiGetIPv6(void) return ""; } -#ifdef USE_DISCOVERY -void StartMdns(void) { - if (Settings.flag3.mdns_enabled) { // SetOption55 - Control mDNS service - if (!Wifi.mdns_begun) { -// if (mdns_delayed_start) { -// AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION)); -// mdns_delayed_start--; -// } else { -// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START]; - Wifi.mdns_begun = (uint8_t)MDNS.begin(my_hostname); - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Wifi.mdns_begun) ? D_INITIALIZED : D_FAILED); -// } - } - } -} - -#ifdef WEBSERVER_ADVERTISE -void MdnsAddServiceHttp(void) { - if (1 == Wifi.mdns_begun) { - Wifi.mdns_begun = 2; - MDNS.addService("http", "tcp", WEB_PORT); - } -} - -void MdnsUpdate(void) { - if (2 == Wifi.mdns_begun) { - MDNS.update(); - AddLog_P(LOG_LEVEL_DEBUG_MORE, D_LOG_MDNS, "MDNS.update"); - } -} -#endif // WEBSERVER_ADVERTISE -#endif // USE_DISCOVERY - bool WifiCheckIPAddrStatus(void) // Return false for 169.254.x.x or fe80::/64 { bool ip_global=false; @@ -569,7 +535,7 @@ void WifiCheck(uint8_t param) } } else { WifiSetState(0); - Wifi.mdns_begun = 0; + Mdns.begun = 0; } } } @@ -735,43 +701,3 @@ void wifiKeepAlive(void) { } } #endif // ARDUINO_ESP8266_RELEASE_2_3_0 - - -char* NetworkHostname(void) { - if (global_state.eth_down) { - return my_hostname; - } -#ifdef ESP32 -#ifdef USE_ETHERNET - else { - return EthernetHostname(); - } -#endif -#endif -} - -IPAddress NetworkAddress(void) { - if (global_state.eth_down) { - return WiFi.localIP(); - } -#ifdef ESP32 -#ifdef USE_ETHERNET - else { - return EthernetLocalIP(); - } -#endif -#endif -} - -String NetworkMacAddress(void) { - if (global_state.eth_down) { - return WiFi.macAddress(); - } -#ifdef ESP32 -#ifdef USE_ETHERNET - else { - return EthernetMacAddress(); - } -#endif -#endif -} diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 52bdda713..e21d3566b 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -870,14 +870,14 @@ void StartWebserver(int type, IPAddress ipweb) String ipv6_addr = WifiGetIPv6(); if (ipv6_addr!="") { AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s and IPv6 global address %s "), - NetworkHostname(), (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str(), ipv6_addr.c_str()); + NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str(), ipv6_addr.c_str()); } else { AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), - NetworkHostname(), (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str()); + NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str()); } #else AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"), - NetworkHostname(), (Wifi.mdns_begun) ? ".local" : "", ipweb.toString().c_str()); + NetworkHostname(), (Mdns.begun) ? ".local" : "", ipweb.toString().c_str()); #endif // LWIP_IPV6 = 1 rules_flag.http_init = 1; } @@ -1158,7 +1158,7 @@ void WSContentSendStyle_P(const char* formatP, ...) bool sip = (static_cast(WiFi.softAPIP()) != 0); WSContentSend_P(PSTR("

%s%s (%s%s%s)

"), // tasmota.local (192.168.2.12, 192.168.4.1) NetworkHostname(), - (Wifi.mdns_begun) ? ".local" : "", + (Mdns.begun) ? ".local" : "", (lip) ? WiFi.localIP().toString().c_str() : "", (lip && sip) ? ", " : "", (sip) ? WiFi.softAPIP().toString().c_str() : ""); @@ -2480,7 +2480,7 @@ void HandleInformation(void) #ifdef ESP32 #ifdef USE_ETHERNET if (static_cast(EthernetLocalIP()) != 0) { - WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Wifi.mdns_begun) ? ".local" : ""); + WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? ".local" : ""); WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), EthernetLocalIP().toString().c_str()); } @@ -2489,7 +2489,7 @@ void HandleInformation(void) if (Settings.flag4.network_wifi) { int32_t rssi = WiFi.RSSI(); WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WifiGetRssiAsQuality(rssi), rssi); - WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Wifi.mdns_begun) ? ".local" : ""); + WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Mdns.begun) ? ".local" : ""); #if LWIP_IPV6 String ipv6_addr = WifiGetIPv6(); if (ipv6_addr != "") { diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index c06cb7dd1..7a7eae075 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -123,34 +123,6 @@ void MakeValidMqtt(uint32_t option, char* str) } } -#ifdef USE_DISCOVERY -#ifdef MQTT_HOST_DISCOVERY -void MqttDiscoverServer(void) -{ - if (!Wifi.mdns_begun) { return; } - - int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service - - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n); - - if (n > 0) { - uint32_t i = 0; // If the hostname isn't set, use the first record found. -#ifdef MDNS_HOSTNAME - for (i = n; i > 0; i--) { // Search from last to first and use first if not found - if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) { - break; // Stop at matching record - } - } -#endif // MDNS_HOSTNAME - SettingsUpdateText(SET_MQTT_HOST, MDNS.IP(i).toString().c_str()); - Settings.mqtt_port = MDNS.port(i); - - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), SettingsText(SET_MQTT_HOST), Settings.mqtt_port); - } -} -#endif // MQTT_HOST_DISCOVERY -#endif // USE_DISCOVERY - /*********************************************************************************************\ * MQTT driver specific code need to provide the following functions: * From 1c7d923a8f745b1d161387c42054f452d4cc4cbf Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 15 Jun 2020 22:30:25 +0200 Subject: [PATCH 245/581] Fix ESP32 ILI9341 compilation --- tasmota/xdsp_04_ili9341.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index f5c485e6f..21981ff76 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -93,7 +93,7 @@ void Ili9341InitDriver(void) #ifdef ESP8266 tft = new Adafruit_ILI9341(Pin(GPIO_SPI_CS), Pin(GPIO_SPI_DC)); #else // ESP32 - tft = new Adafruit_ILI9341(Pin (GPIO_TFT_CS), Pin (GPIO_TFT_DC), Pin (GPIO_TFT_MOSI), Pin (GPIO_TFT_CLK), Pin (GPIO_TFT_RST), Pin(GPIO_TFT_MISO)); + tft = new Adafruit_ILI9341(Pin(GPIO_SPI_CS), Pin(GPIO_SPI_DC), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK), -1, Pin(GPIO_SPI_MISO)); #endif tft->begin(); From daef0a759dc7f4c4f44c354d32d975f530a3708c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 15 Jun 2020 22:40:15 +0200 Subject: [PATCH 246/581] Stop blinks when no network configured --- tasmota/support_tasmota.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index a7430dfbb..4843cd884 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -922,7 +922,7 @@ void Every250mSeconds(void) global_state.network_down = (global_state.wifi_down && global_state.eth_down); - if (!Settings.flag.global_state) { // Problem blinkyblinky enabled - SetOption31 - Control link led blinking + if (!Settings.flag.global_state && !global_state.network_down) { // SetOption31 - Control link led blinking if (global_state.data &0x03) { // Any problem if (global_state.mqtt_down) { blinkinterval = 7; } // MQTT problem so blink every 2 seconds (slowest) if (global_state.network_down) { blinkinterval = 3; } // Network problem so blink every second (slow) From 477a2c33bec4e44d0249323378c04774b938e792 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Tue, 16 Jun 2020 08:33:32 +0200 Subject: [PATCH 247/581] Update Italian language --- tasmota/language/it_IT.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 75a1d4361..f603cdb40 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -672,7 +672,7 @@ #define D_SENSOR_HM10_TX "HM10 - TX" #define D_SENSOR_LE01MR_RX "LE-01MR - RX" #define D_SENSOR_LE01MR_TX "LE-01MR - TX" -#define D_SENSOR_BL0940_RX "BL0940 - Rx" +#define D_SENSOR_BL0940_RX "BL0940 - RX" #define D_SENSOR_CC1101_GDO0 "CC1101 - GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 - GDO2" #define D_SENSOR_HRXL_RX "HRXL - RX" @@ -691,8 +691,8 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" -#define D_SENSOR_TCP_TXD "TCP Tx" -#define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_TCP_TXD "TCP - TX" +#define D_SENSOR_TCP_RXD "TCP - RX" // Units #define D_UNIT_AMPERE "A" From 865769767d009db11c15c81e2ef9147309e163c6 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Tue, 16 Jun 2020 10:36:16 +0200 Subject: [PATCH 248/581] scripter call >BS after sensor init --- tasmota/tasmota.ino | 3 +++ tasmota/xdrv_10_scripter.ino | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 4a35d4327..2c93f1b88 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -322,6 +322,9 @@ void setup(void) { XdrvCall(FUNC_INIT); XsnsCall(FUNC_INIT); +#ifdef USE_SCRIPT + Run_Scripter(">BS",3,0); +#endif rules_flag.system_init = 1; } diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 7fc893ffc..208f7211c 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -120,8 +120,6 @@ uint32_t DecodeLightId(uint32_t hue_id); #endif #endif // USE_UNISHOX_COMPRESSION -#define USE_SCRIPT_TIMER - #ifdef USE_SCRIPT_TIMER #include Ticker Script_ticker1; From b8ab5b3d4e4b44aeb8b062e4a8087bf44112b7ca Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 16 Jun 2020 14:57:00 +0200 Subject: [PATCH 249/581] Add IP address info Add IP address info (#8503) --- tasmota/xdrv_01_webserver.ino | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index e21d3566b..5313d8ffb 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2482,7 +2482,8 @@ void HandleInformation(void) if (static_cast(EthernetLocalIP()) != 0) { WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? ".local" : ""); WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str()); - WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), EthernetLocalIP().toString().c_str()); + WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (eth)}2%s"), EthernetLocalIP().toString().c_str()); + WSContentSend_P(PSTR("}1
}2
")); } #endif #endif @@ -2498,7 +2499,8 @@ void HandleInformation(void) #endif if (static_cast(WiFi.localIP()) != 0) { WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str()); - WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), WiFi.localIP().toString().c_str()); + WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (wifi)}2%s"), WiFi.localIP().toString().c_str()); + WSContentSend_P(PSTR("}1
}2
")); } } if (!global_state.network_down) { @@ -2507,8 +2509,9 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1" D_DNS_SERVER "}2%s"), IPAddress(Settings.ip_address[3]).toString().c_str()); } if (static_cast(WiFi.softAPIP()) != 0) { + WSContentSend_P(PSTR("}1
}2
")); WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str()); - WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), WiFi.softAPIP().toString().c_str()); + WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (AP)}2%s"), WiFi.softAPIP().toString().c_str()); WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), WiFi.softAPIP().toString().c_str()); } WSContentSend_P(PSTR("}1}2 ")); // Empty line From 715697cb32cd83549a40d7c6b8b7def4fa5492b4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 16 Jun 2020 18:36:49 +0200 Subject: [PATCH 250/581] Add ESP32 ethernet commands Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` (#8503) --- RELEASENOTES.md | 3 +- tasmota/CHANGELOG.md | 4 ++ tasmota/language/bg_BG.h | 3 ++ tasmota/language/cs_CZ.h | 3 ++ tasmota/language/de_DE.h | 3 ++ tasmota/language/el_GR.h | 3 ++ tasmota/language/en_GB.h | 3 ++ tasmota/language/es_ES.h | 3 ++ tasmota/language/fr_FR.h | 3 ++ tasmota/language/he_HE.h | 3 ++ tasmota/language/hu_HU.h | 3 ++ tasmota/language/it_IT.h | 3 ++ tasmota/language/ko_KO.h | 3 ++ tasmota/language/nl_NL.h | 3 ++ tasmota/language/pl_PL.h | 3 ++ tasmota/language/pt_BR.h | 3 ++ tasmota/language/pt_PT.h | 3 ++ tasmota/language/ro_RO.h | 3 ++ tasmota/language/ru_RU.h | 3 ++ tasmota/language/sk_SK.h | 3 ++ tasmota/language/sv_SE.h | 3 ++ tasmota/language/tr_TR.h | 3 ++ tasmota/language/uk_UA.h | 3 ++ tasmota/language/zh_CN.h | 3 ++ tasmota/language/zh_TW.h | 3 ++ tasmota/my_user_config.h | 13 +++-- tasmota/settings.h | 7 +-- tasmota/settings.ino | 12 +++++ tasmota/support_features.ino | 11 ++-- tasmota/tasmota_template.h | 8 +-- tasmota/tasmota_template_ESP32.h | 26 ++++++++-- tasmota/tasmota_version.h | 2 +- tasmota/xdrv_82_ethernet.ino | 87 ++++++++++++++++++++++++++++++-- tools/decode-status.py | 2 +- 34 files changed, 215 insertions(+), 29 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 72fd4b113..ba5980add 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,7 +52,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.3.1.4 +### Version 8.3.1.5 - Change IRremoteESP8266 library updated to v2.7.7 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) @@ -63,6 +63,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) +- Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` - Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) - Add more functionality to ``Switchmode`` 11 and 12 (#8450) - Add wildcard pattern ``?`` for JSON matching in rules diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 4e0cdc436..330a9f966 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased (development) +### 8.3.1.5 20200616 + +- Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` + ### 8.3.1.4 20200615 - Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 62d48e0a4..c5dd882f7 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index cbbe58921..5e8d59fa7 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 9c605da62..7912924c1 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index ff5486540..e08642ec3 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 4f4180dd4..d047a7157 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 2447cdc05..59fdf3fa3 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 80cf87061..4008c86bc 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index e6af68ddc..6ec86a0d9 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index eb797bcab..e8e527c2b 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index f603cdb40..ab76bae8a 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP - TX" #define D_SENSOR_TCP_RXD "TCP - RX" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 4b7e8538a..777368276 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index c9979814b..46325b506 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 4827d26be..9ec9a3680 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 450bea0d5..f5259933a 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 189b5ec3c..9c5228299 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index aaea0a0b2..ee5d51a9f 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index be28c69a2..e7d952035 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 4b667150a..cd829e91b 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index edf7b3f1e..08b5574c5 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 5089b6e15..3df1cae25 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 5f6b23754..a710581c5 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index a86e2c7ee..64a762b91 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index b1b4424cd..1fe8d2791 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -691,6 +691,9 @@ #define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" #define D_GPIO_WEBCAM_HSD "CAM_HSD" #define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 915b147f6..732432eb2 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -728,10 +728,15 @@ #ifdef ESP32 -//#define USE_ETHERNET // Add support for ethernet (Currently fixed for Olimex ESP32-PoE) -//#define USE_SPI // Add support for hardware SPI -//#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) -//#define USE_WEBCAM // Add support for webcam +//#define USE_ETHERNET // Add support for ethernet (Currently fixed for Olimex ESP32-PoE) + // Olimex ESP32-PoE + #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110 + #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 + #define ETH_CLKMODE 3 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT + +//#define USE_SPI // Add support for hardware SPI +//#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) +//#define USE_WEBCAM // Add support for webcam #endif diff --git a/tasmota/settings.h b/tasmota/settings.h index db19c1199..80507e97b 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -392,12 +392,13 @@ struct { #else // ESP32 myio my_gp; // 3AC - 2 x 40 bytes (ESP32) mytmplt user_template; // 3FC - 2 x 37 bytes (ESP32) + uint8_t eth_type; // 446 + uint8_t eth_clk_mode; // 447 - uint8_t free_esp32_446[6]; // 446 + uint8_t free_esp32_448[4]; // 448 WebCamCfg webcam_config; // 44C - - uint8_t free_esp32_450[1]; // 450 + uint8_t eth_address; // 450 #endif // ESP8266 - ESP32 char serial_delimiter; // 451 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 1b2dca82d..a294e2813 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -800,6 +800,11 @@ void SettingsDefaultSet2(void) // Ethernet flag4.network_ethernet |= 1; +#ifdef ESP32 + Settings.eth_type = ETH_TYPE; + Settings.eth_clk_mode = ETH_CLKMODE; + Settings.eth_address = ETH_ADDR; +#endif // Wifi flag4.network_wifi |= 1; @@ -1447,6 +1452,13 @@ void SettingsDelta(void) Settings.flag4.network_wifi = 1; Settings.flag4.network_ethernet = 1; } + if (Settings.version < 0x08030105) { +#ifdef ESP32 + Settings.eth_type = ETH_TYPE; + Settings.eth_clk_mode = ETH_CLKMODE; + Settings.eth_address = ETH_ADDR; +#endif + } Settings.version = VERSION; SettingsSave(1); diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 1ff178eac..a3001e0e9 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -579,10 +579,11 @@ void GetFeatures(void) feature6 |= 0x00008000; // xdrv_40_telegram.ino #endif #ifdef USE_HP303B - feature6 |= 0x00010000; // xsns_73_hp303b.ino + feature6 |= 0x00010000; // xsns_73_hp303b.ino +#endif +#ifdef USE_TCP_BRIDGE + feature6 |= 0x00020000; // xdrv_41_tcp_bridge.ino #endif - -// feature6 |= 0x00020000; // feature6 |= 0x00040000; // feature6 |= 0x00080000; @@ -599,9 +600,9 @@ void GetFeatures(void) // feature6 |= 0x10000000; // feature6 |= 0x20000000; #ifdef USE_ETHERNET - feature6 |= 0x40000000; + feature6 |= 0x40000000; // xdrv_82_ethernet.ino #endif #ifdef USE_WEBCAM - feature6 |= 0x80000000; + feature6 |= 0x80000000; // xdrv_81_webcam.ino #endif } diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index a87c39939..4e6efeb5a 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -577,6 +577,10 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_SBR_TX, // Serial Bridge Serial interface GPIO_SBR_RX, // Serial Bridge Serial interface #endif +#ifdef USE_TCP_BRIDGE + GPIO_TCP_TX, // TCP Serial bridge + GPIO_TCP_RX, // TCP Serial bridge +#endif #ifdef USE_ZIGBEE GPIO_ZIGBEE_TX, // Zigbee Serial interface GPIO_ZIGBEE_RX, // Zigbee Serial interface @@ -685,10 +689,6 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_AS3935 GPIO_AS3935, #endif -#ifdef USE_TCP_BRIDGE - AGPIO(GPIO_TCP_TX), // TCP Serial bridge - AGPIO(GPIO_TCP_RX), // TCP Serial bridge -#endif }; /********************************************************************************************/ diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 5457ed33a..0aa2d58c1 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -130,6 +130,7 @@ enum UserSelectablePins { GPIO_KEY1_TC, // Touch pin as button GPIO_BL0940_RX, // BL0940 serial interface GPIO_TCP_TX, GPIO_TCP_RX, // TCP to serial bridge + GPIO_ETH_PHY_POWER, GPIO_ETH_PHY_MDC, GPIO_ETH_PHY_MDIO, // Ethernet GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -220,7 +221,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BUTTON "_tc|" D_SENSOR_BL0940_RX "|" - D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD + D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" + D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO ; const char kSensorNamesFixed[] PROGMEM = @@ -235,6 +237,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_KEY1_NP) + MAX_KEYS, AGPIO(GPIO_KEY1_INV) + MAX_KEYS, AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS, + AGPIO(GPIO_KEY1_TC) + MAX_KEYS, // Touch button AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES, AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays @@ -417,6 +420,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface #endif +#ifdef USE_TCP_BRIDGE + AGPIO(GPIO_TCP_TX), // TCP Serial bridge + AGPIO(GPIO_TCP_RX), // TCP Serial bridge +#endif #ifdef USE_ZIGBEE AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface @@ -550,11 +557,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD, AGPIO(GPIO_WEBCAM_PSRCS), #endif -#ifdef USE_TCP_BRIDGE - AGPIO(GPIO_TCP_TX), // TCP Serial bridge - AGPIO(GPIO_TCP_RX), // TCP Serial bridge +#ifdef USE_ETHERNET + AGPIO(GPIO_ETH_PHY_POWER), + AGPIO(GPIO_ETH_PHY_MDC), + AGPIO(GPIO_ETH_PHY_MDIO), // Ethernet #endif - AGPIO(GPIO_KEY1_TC) + MAX_KEYS }; //******************************************************************************************** @@ -668,6 +675,15 @@ const mytmplt kModules PROGMEM = 0 // Flag }; +/*********************************************************************************************\ + Known templates + +{"NAME":"AITHINKER CAM","GPIO":[4992,65504,65504,65504,65504,5088,65504,65504,65504,65504,65504,65504,65504,65504,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,65504,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} +{"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} + +\*********************************************************************************************/ + + #endif // ESP32 #endif // _TASMOTA_TEMPLATE_ESP32_H_ diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index e01e1bcce..69146852c 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08030104; +const uint32_t VERSION = 0x08030105; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index 6d9725332..e20cde4e5 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -21,13 +21,53 @@ #ifdef USE_ETHERNET /*********************************************************************************************\ * Ethernet support for ESP32 + * + * Dedicated fixed Phy pins + * GPIO17 - EMAC_CLK_OUT_180 + * GPIO19 - EMAC_TXD0(RMII) + * GPIO21 - EMAC_TX_EN(RMII) + * GPIO22 - EMAC_TXD1(RMII) + * GPIO25 - EMAC_RXD0(RMII) + * GPIO26 - EMAC_RXD1(RMII) + * GPIO27 - EMAC_RX_CRS_DV + * + * {"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} + * \*********************************************************************************************/ #define XDRV_82 82 +/* // Olimex ESP32-PoE -#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT -#define ETH_PHY_POWER 12 +#define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT +#define ETH_POWER_PIN 12 + +//******************************************************************************************** + +#ifndef ETH_ADDR +#define ETH_ADDR 0 // esp_eth.h eth_phy_base_t: 0 = PHY0 .. 31 = PHY31 +#endif + +#ifndef ETH_TYPE +#define ETH_TYPE ETH_PHY_LAN8720 // ETH.h eth_phy_type_t: 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110 +#endif + +#ifndef ETH_CLKMODE +#define ETH_CLKMODE ETH_CLOCK_GPIO0_IN // esp_eth.h eth_clock_mode_t: 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT +#endif +*/ + +#ifndef ETH_POWER_PIN +#define ETH_POWER_PIN -1 +#endif + +#ifndef ETH_MDC_PIN +#define ETH_MDC_PIN 23 +#endif + +#ifndef ETH_MDIO_PIN +#define ETH_MDIO_PIN 18 +#endif #include @@ -75,7 +115,13 @@ void EthernetInit(void) { snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), my_hostname); WiFi.onEvent(EthernetEvent); - ETH.begin(); + + int eth_power = (PinUsed(GPIO_ETH_PHY_POWER)) ? Pin(GPIO_ETH_PHY_POWER) : ETH_POWER_PIN; + int eth_mdc = (PinUsed(GPIO_ETH_PHY_MDC)) ? Pin(GPIO_ETH_PHY_MDC) : ETH_MDC_PIN; + int eth_mdio = (PinUsed(GPIO_ETH_PHY_MDIO)) ? Pin(GPIO_ETH_PHY_MDIO) : ETH_MDIO_PIN; + if (!ETH.begin(Settings.eth_address, eth_power, eth_mdc, eth_mdio, (eth_phy_type_t)Settings.eth_type, (eth_clock_mode_t)Settings.eth_clk_mode)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Bad PHY type or init error")); + }; } IPAddress EthernetLocalIP(void) { @@ -94,11 +140,15 @@ String EthernetMacAddress(void) { * Commands \*********************************************************************************************/ +#define D_CMND_ETHADDRESS "EthAddress" +#define D_CMND_ETHTYPE "EthType" +#define D_CMND_ETHCLOCKMODE "EthClockMode" + const char kEthernetCommands[] PROGMEM = "|" // No prefix - D_CMND_ETHERNET; + D_CMND_ETHERNET "|" D_CMND_ETHADDRESS "|" D_CMND_ETHTYPE "|" D_CMND_ETHCLOCKMODE; void (* const EthernetCommand[])(void) PROGMEM = { - &CmndEthernet }; + &CmndEthernet, &CmndEthAddress, &CmndEthType, &CmndEthClockMode }; void CmndEthernet(void) { @@ -109,6 +159,33 @@ void CmndEthernet(void) ResponseCmndStateText(Settings.flag4.network_ethernet); } +void CmndEthAddress(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 31)) { + Settings.eth_address = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndNumber(Settings.eth_address); +} + +void CmndEthType(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings.eth_type = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndNumber(Settings.eth_type); +} + +void CmndEthClockMode(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) { + Settings.eth_clk_mode = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndNumber(Settings.eth_clk_mode); +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ diff --git a/tools/decode-status.py b/tools/decode-status.py index 095e23e71..d0be84459 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -206,7 +206,7 @@ a_features = [[ "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", "USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM", - "USE_HP303B","","","", + "USE_HP303B","USE_TCP_BRIDGE","","", "","","","", "","","","", "","","USE_ETHERNET","USE_WEBCAM" From a4e5b3e14ee6bb7b7ff9b5f1ab18eacfbc35020c Mon Sep 17 00:00:00 2001 From: Charles Date: Tue, 16 Jun 2020 18:58:56 +0200 Subject: [PATCH 251/581] Rebuild Travis CI --- tasmota/xnrg_15_teleinfo.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index aefced128..6a8362233 100644 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -296,6 +296,8 @@ void TInfoInit(void) #elif defined (ESP32) AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using ESP32 hardware serial")); + // Waiting TasmotaSerial PR merged to change that + //TInfoSerial->reconf(TINFO_SPEED, SERIAL_7E1); #endif From ee2bb0330a3534a59a297e9a92862b622fd020b6 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 16 Jun 2020 20:01:14 +0200 Subject: [PATCH 252/581] Add Zigbee initial support for EmberZNet protocol (raw send/receive only) --- tasmota/CHANGELOG.md | 1 + tasmota/i18n.h | 4 + tasmota/my_user_config.h | 3 + tasmota/xdrv_23_zigbee_0_constants.ino | 9 + tasmota/xdrv_23_zigbee_7_statemachine.ino | 28 ++ tasmota/xdrv_23_zigbee_8_parsers.ino | 31 ++ tasmota/xdrv_23_zigbee_9_impl.ino | 347 ++++++++++++++++++++-- 7 files changed, 396 insertions(+), 27 deletions(-) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 330a9f966..ec18a5d96 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,6 +3,7 @@ ### 8.3.1.5 20200616 - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` +- Add Zigbee initial support for EmberZNet protocol (raw send/receive only) ### 8.3.1.4 20200615 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 543a4c9b9..ccbb6b399 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -505,10 +505,14 @@ #define D_CMND_ZIGBEE_RESET "Reset" #define D_JSON_ZIGBEE_CC2530 "CC2530" #define D_CMND_ZIGBEEZNPRECEIVE "ZNPReceive" // only for debug +#define D_CMND_ZIGBEE_EZSP_RECEIVE "EZSPReceive" // only for debug #define D_CMND_ZIGBEEZNPSEND "ZNPSend" +#define D_CMND_ZIGBEE_EZSP_SEND "EZSPSend" #define D_JSON_ZIGBEE_STATE "ZbState" #define D_JSON_ZIGBEEZNPRECEIVED "ZbZNPReceived" + #define D_JSON_ZIGBEE_EZSP_RECEIVED "ZbEZSPReceived" #define D_JSON_ZIGBEEZNPSENT "ZbZNPSent" + #define D_JSON_ZIGBEE_EZSP_SENT "ZbEZSPSent" #define D_JSON_ZIGBEEZCL_RECEIVED "ZbZCLReceived" #define D_JSON_ZIGBEEZCL_RAW_RECEIVED "ZbZCLRawReceived" #define D_JSON_ZIGBEE_DEVICE "Device" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 732432eb2..05c30b6a5 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -652,6 +652,9 @@ // -- Zigbee interface ---------------------------- //#define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP (+49k code, +3k mem) + #define USE_ZIGBEE_ZNP // Enable ZNP protocol, needed for CC2530 based devices + // #define USE_ZIGBEE_EZSP // [EXPERIMENTAL - DO NOT USE] Enable EZSP protocol, needed for EFR32 EmberZNet based devices, like Sonoff Zigbee bridge + // Note: USE_ZIGBEE_ZNP and USE_ZIGBEE_EZSP are mutually incompatible, you must select exactly one #define USE_ZIGBEE_PANID 0x1A63 // arbitrary PAN ID for Zigbee network, must be unique in the home // if PANID == 0xFFFF, then the device will act as a Zigbee router, the parameters below are ignored // if PANID == 0xFFFE, then the device will act as a Zigbee end-device (non-router), the parameters below are ignored diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index 57bf22499..92e88c708 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -19,6 +19,13 @@ #ifdef USE_ZIGBEE +#if defined(USE_ZIGBEE_ZNP) && defined(USE_ZIGBEE_EZSP) + #error "#define USE_ZIGBEE_ZNP and #define USE_ZIGBEE_EZSP are mutually incompatible" +#endif +#if !defined(USE_ZIGBEE_ZNP) && !defined(USE_ZIGBEE_EZSP) + #error "You must select one of: #define USE_ZIGBEE_ZNP or #define USE_ZIGBEE_EZSP" +#endif + #define OCCUPANCY "Occupancy" // global define for Aqara typedef uint64_t Z_IEEEAddress; @@ -26,6 +33,7 @@ typedef uint16_t Z_ShortAddress; const uint16_t BAD_SHORTADDR = 0xFFFE; +#ifdef USE_ZIGBEE_ZNP enum ZnpCommandType { Z_POLL = 0x00, Z_SREQ = 0x20, @@ -45,6 +53,7 @@ enum ZnpSubsystem { Z_DEBUG = 0x08, Z_APP = 0x09 }; +#endif // USE_ZIGBEE_ZNP // Commands in the SYS subsystem enum SysCommand { diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index 4297a4375..cbfe822ab 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -168,6 +168,8 @@ SBuffer *zigbee_buffer = nullptr; #define USE_ZIGBEE_CHANNEL_MASK (1 << (USE_ZIGBEE_CHANNEL)) +#ifdef USE_ZIGBEE_ZNP + // ZBS_* Zigbee Send // ZBR_* Zigbee Recv ZBM(ZBS_RESET, Z_AREQ | Z_SYS, SYS_RESET, 0x00 ) // 410001 SYS_RESET_REQ Hardware reset @@ -611,6 +613,30 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_STOP(ZIGBEE_LABEL_ABORT) }; +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + +// Update the relevant commands with Settings +void Z_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h) { +} + + +static const Zigbee_Instruction zb_prog[] PROGMEM = { + ZI_LABEL(0) + ZI_NOOP() + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) + // ZI_ON_RECV_UNEXPECTED(&Z_Recv_Default) + // ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize + + ZI_LABEL(ZIGBEE_LABEL_MAIN_LOOP) + ZI_WAIT_FOREVER() + ZI_GOTO(ZIGBEE_LABEL_READY) +}; + +#endif // USE_ZIGBEE_EZSP + uint8_t ZigbeeGetInstructionSize(uint8_t instr) { // in Zigbee_Instruction lines (words) if (instr >= ZGB_INSTR_12_BYTES) { return 3; @@ -770,7 +796,9 @@ void ZigbeeStateMachine_Run(void) { } break; case ZGB_INSTR_SEND: +#ifdef USE_ZIGBEE_ZNP ZigbeeZNPSend((uint8_t*) cur_ptr1, cur_d8 /* len */); +#endif // USE_ZIGBEE_ZNP break; case ZGB_INSTR_WAIT_UNTIL: zigbee.recv_until = true; // and reuse ZGB_INSTR_WAIT_RECV diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 53590a4c4..7e9129d64 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -552,6 +552,7 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { return -1; } +#ifdef USE_ZIGBEE_ZNP /*********************************************************************************************\ * Send specific ZNP messages \*********************************************************************************************/ @@ -589,6 +590,32 @@ void Z_SendAFInfoRequest(uint16_t shortaddr) { ZigbeeZNPSend(AFInfoReq, sizeof(AFInfoReq)); } +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP +/*********************************************************************************************\ + * Send specific EZS¨ messages +\*********************************************************************************************/ + +// +// Send ZDO_IEEE_ADDR_REQ request to get IEEE long address +// +void Z_SendIEEEAddrReq(uint16_t shortaddr) { +} + +// +// Send ACTIVE_EP_REQ to collect active endpoints for this address +// +void Z_SendActiveEpReq(uint16_t shortaddr) { +} + +// +// Send AF Info Request +// +void Z_SendAFInfoRequest(uint16_t shortaddr) { +} + +#endif // USE_ZIGBEE_EZSP /*********************************************************************************************\ * Callbacks @@ -718,6 +745,8 @@ typedef struct Z_Dispatcher { ZB_RecvMsgFunc func; } Z_Dispatcher; +#ifdef USE_ZIGBEE_ZNP + // Ffilters based on ZNP frames ZBM(AREQ_AF_DATA_CONFIRM, Z_AREQ | Z_AF, AF_DATA_CONFIRM) // 4480 ZBM(AREQ_AF_INCOMING_MESSAGE, Z_AREQ | Z_AF, AF_INCOMING_MSG) // 4481 @@ -767,6 +796,8 @@ int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { } } +#endif // USE_ZIGBEE_ZNP + /*********************************************************************************************\ * Functions called by State Machine \*********************************************************************************************/ diff --git a/tasmota/xdrv_23_zigbee_9_impl.ino b/tasmota/xdrv_23_zigbee_9_impl.ino index 4da0a48f6..a28481277 100644 --- a/tasmota/xdrv_23_zigbee_9_impl.ino +++ b/tasmota/xdrv_23_zigbee_9_impl.ino @@ -21,18 +21,32 @@ #define XDRV_23 23 +#ifdef USE_ZIGBEE_ZNP const uint32_t ZIGBEE_BUFFER_SIZE = 256; // Max ZNP frame is SOF+LEN+CMD1+CMD2+250+FCS = 255 const uint8_t ZIGBEE_SOF = 0xFE; const uint8_t ZIGBEE_SOF_ALT = 0xFF; +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP +const uint32_t ZIGBEE_BUFFER_SIZE = 256; +const uint8_t ZIGBEE_EZSP_CANCEL = 0x1A; // cancel byte +const uint8_t ZIGBEE_EZSP_EOF = 0x7E; // end of frame +const uint8_t ZIGBEE_EZSP_ESCAPE = 0x7D; // escape byte +#endif // USE_ZIGBEE_EZSP #include TasmotaSerial *ZigbeeSerial = nullptr; const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix - D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEE_PERMITJOIN "|" - D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" - D_CMND_ZIGBEE_PROBE "|" D_CMND_ZIGBEEZNPRECEIVE "|" +#ifdef USE_ZIGBEE_ZNP + D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEEZNPRECEIVE "|" +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + D_CMND_ZIGBEE_EZSP_SEND "|" D_CMND_ZIGBEE_EZSP_RECEIVE "|" +#endif // USE_ZIGBEE_EZSP + D_CMND_ZIGBEE_PERMITJOIN "|" + D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" D_CMND_ZIGBEE_PROBE "|" D_CMND_ZIGBEE_FORGET "|" D_CMND_ZIGBEE_SAVE "|" D_CMND_ZIGBEE_NAME "|" D_CMND_ZIGBEE_BIND "|" D_CMND_ZIGBEE_UNBIND "|" D_CMND_ZIGBEE_PING "|" D_CMND_ZIGBEE_MODELID "|" D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" @@ -40,9 +54,14 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix ; void (* const ZigbeeCommand[])(void) PROGMEM = { - &CmndZbZNPSend, &CmndZbPermitJoin, - &CmndZbStatus, &CmndZbReset, &CmndZbSend, - &CmndZbProbe, &CmndZbZNPReceive, +#ifdef USE_ZIGBEE_ZNP + &CmndZbZNPSend, &CmndZbZNPReceive, +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + &CmndZbEZSPSend, &CmndZbEZSPReceive, +#endif // USE_ZIGBEE_EZSP + &CmndZbPermitJoin, + &CmndZbStatus, &CmndZbReset, &CmndZbSend, &CmndZbProbe, &CmndZbForget, &CmndZbSave, &CmndZbName, &CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId, &CmndZbLight, &CmndZbRestore, &CmndZbBindState, @@ -52,11 +71,12 @@ void (* const ZigbeeCommand[])(void) PROGMEM = { // // Called at event loop, checks for incoming data from the CC2530 // -void ZigbeeInputLoop(void) -{ - static uint32_t zigbee_polling_window = 0; +void ZigbeeInputLoop(void) { + +#ifdef USE_ZIGBEE_ZNP + static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte static uint8_t fcs = ZIGBEE_SOF; - static uint32_t zigbee_frame_len = 5; // minimal zigbee frame lenght, will be updated when buf[1] is read + static uint32_t zigbee_frame_len = 5; // minimal zigbee frame length, will be updated when buf[1] is read // Receive only valid ZNP frames: // 00 - SOF = 0xFE // 01 - Length of Data Field - 0..250 @@ -140,6 +160,132 @@ void ZigbeeInputLoop(void) } zigbee_buffer->setLen(0); // empty buffer } +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte + bool escape = false; // was the previous byte an escape? + bool frame_complete = false; // frame is ready and complete + // Receive only valid EZSP frames: + // 1A - Cancel - cancel all previous bytes + // 7D - Escape byte - following byte is escaped + // 7E - end of frame + + while (ZigbeeSerial->available()) { + yield(); + uint8_t zigbee_in_byte = ZigbeeSerial->read(); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len()); + + // if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized + // escape = false; + // frame_complete = false; + // } + + if ((0x11 == zigbee_in_byte) || (0x13 == zigbee_in_byte)) { + continue; // ignore reserved bytes XON/XOFF + } + + if (ZIGBEE_EZSP_ESCAPE == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Escape byte received")); + escape = true; + continue; + } + + if (ZIGBEE_EZSP_CANCEL == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x1A, cancel byte received, discarding %d bytes"), zigbee_buffer->len()); + zigbee_buffer->setLen(0); // empty buffer + escape = false; + frame_complete = false; + continue; // re-loop + } + + if (ZIGBEE_EZSP_EOF == zigbee_in_byte) { + // end of frame + frame_complete = true; + break; + } + + if (zigbee_buffer->len() < ZIGBEE_BUFFER_SIZE) { + // check if escape + if (ZIGBEE_EZSP_ESCAPE == zigbee_in_byte) { + escape = true; + continue; + } + if (escape) { + // invert bit 5 + zigbee_in_byte ^= 0x10; + escape = false; + } + + zigbee_buffer->add8(zigbee_in_byte); + zigbee_polling_window = millis(); // Wait for more data + } // adding bytes + } // while (ZigbeeSerial->available()) + + uint32_t frame_len = zigbee_buffer->len(); + if (frame_complete || (frame_len && (millis() > (zigbee_polling_window + ZIGBEE_POLLING)))) { + char hex_char[frame_len * 2 + 2]; + ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); + if ((frame_complete) && (frame_len >= 3)) { + // frame received and has at least 3 bytes (without EOF), checking CRC + // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": received raw frame %s"), hex_char); + uint16_t crc = 0xFFFF; // frame CRC + // compute CRC + for (uint32_t i=0; iget8(i) << 8); + for (uint32_t i=0; i<8; i++) { + if (crc & 0x8000) { + crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard + } else { + crc <<= 1; + } + } + } + + uint16_t crc_received = zigbee_buffer->get8(frame_len - 2) << 8 | zigbee_buffer->get8(frame_len - 1); + // remove 2 last bytes + + if (crc_received != crc) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %s"), crc_received, crc, hex_char); + } else { + // copy buffer + SBuffer ezsp_buffer = zigbee_buffer->subBuffer(0, frame_len - 2); // CRC + + // CRC is correct, apply de-stuffing if DATA frame + if (0 == (ezsp_buffer.get8(0) & 0x80)) { + // DATA frame + uint8_t rand = 0x42; + for (uint32_t i=1; i> 1) ^ 0xB8; } + else { rand = (rand >> 1); } + } + } + + ToHex_P((unsigned char*)ezsp_buffer.getBuffer(), ezsp_buffer.len(), hex_char, sizeof(hex_char)); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "\":\"%s\"}"), hex_char); + if (Settings.flag3.tuya_serial_mqtt_publish) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); + XdrvRulesProcess(); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable + } + // now process the message + ZigbeeProcessInput(ezsp_buffer); + } + } else { + // the buffer timed-out, print error and discard + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %d"), hex_char); + } + zigbee_buffer->setLen(0); // empty buffer + escape = false; + frame_complete = false; + } + +#endif // USE_ZIGBEE_EZSP + } /********************************************************************************************/ @@ -201,15 +347,20 @@ uint32_t strToUInt(const JsonVariant &val) { return 0; // couldn't parse anything } +#ifdef USE_ZIGBEE_ZNP // Do a factory reset of the CC2530 const unsigned char ZIGBEE_FACTORY_RESET[] PROGMEM = { Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x01 /* STARTOPT_CLEAR_CONFIG */}; //"2605030101"; // Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 len, 0x01 STARTOPT_CLEAR_CONFIG +#endif // USE_ZIGBEE_ZNP + void CmndZbReset(void) { if (ZigbeeSerial) { switch (XdrvMailbox.payload) { case 1: +#ifdef USE_ZIGBEE_ZNP ZigbeeZNPSend(ZIGBEE_FACTORY_RESET, sizeof(ZIGBEE_FACTORY_RESET)); +#endif // USE_ZIGBEE_ZNP eraseZigbeeDevices(); restart_flag = 2; ResponseCmndChar_P(PSTR(D_JSON_ZIGBEE_CC2530 " " D_JSON_RESET_AND_RESTARTING)); @@ -220,6 +371,38 @@ void CmndZbReset(void) { } } +#ifdef USE_ZIGBEE_ZNP + +void ZigbeeZNPSend(const uint8_t *msg, size_t len) { + if ((len < 2) || (len > 252)) { + // abort, message cannot be less than 2 bytes for CMD1 and CMD2 + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len); + return; + } + uint8_t data_len = len - 2; // removing CMD1 and CMD2 + + if (ZigbeeSerial) { + uint8_t fcs = data_len; + + ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF); + ZigbeeSerial->write(data_len); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len); + for (uint32_t i = 0; i < len; i++) { + uint8_t b = pgm_read_byte(msg + i); + ZigbeeSerial->write(b); + fcs ^= b; + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b); + } + ZigbeeSerial->write(fcs); // finally send fcs checksum byte + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs); + } + // Now send a MQTT message to report the sent message + char hex_char[(len * 2) + 2]; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"), + ToHex_P(msg, len, hex_char, sizeof(hex_char))); +} + // // Same code for `ZbZNPSend` and `ZbZNPReceive` // building the complete message (intro, length) @@ -264,36 +447,138 @@ void CmndZbZNPSend(void) CmndZbZNPSendOrReceive(true); } -void ZigbeeZNPSend(const uint8_t *msg, size_t len) { - if ((len < 2) || (len > 252)) { +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + +// internal function to output a byte, and escape it (stuffing) if needed +void ZigbeeEZSPSend_Out(uint8_t out_byte) { + switch (out_byte) { + case 0x7E: // Flag byte + case 0x11: // XON + case 0x13: // XOFF + case 0x18: // Substitute byte + case 0x1A: // Cancel byte + case 0x7D: // Escape byte + ZigbeeSerial->write(ZIGBEE_EZSP_ESCAPE); // send Escape byte 0x7D + ZigbeeSerial->write(out_byte ^ 0x10); // send with bit 5 inverted + break; + default: + ZigbeeSerial->write(out_byte); // send unchanged + break; + } +} +// Send low-level EZSP frames +// +// The frame should contain the Control Byte and Data Field +// The frame shouldn't be escaped, nor randomized +// +// Before sending: +// - send Cancel byte (0x1A) if requested +// - randomize Data Field if DATA Frame +// - compute CRC16 +// - escape (stuff) reserved bytes +// - add EOF (0x7E) +// - send frame +// send_cancel: should we first send a EZSP_CANCEL (0x1A) before the message to clear any leftover +void ZigbeeEZSPSend(const uint8_t *msg, size_t len, bool send_cancel = false) { + if ((len < 1) || (len > 252)) { // abort, message cannot be less than 2 bytes for CMD1 and CMD2 - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEE_EZSP_SENT ": bad message len %d"), len); return; } uint8_t data_len = len - 2; // removing CMD1 and CMD2 if (ZigbeeSerial) { - uint8_t fcs = data_len; + if (send_cancel) { + ZigbeeSerial->write(ZIGBEE_EZSP_CANCEL); // 0x1A + } - ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF); - ZigbeeSerial->write(data_len); - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len); - for (uint32_t i = 0; i < len; i++) { - uint8_t b = pgm_read_byte(msg + i); - ZigbeeSerial->write(b); - fcs ^= b; - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b); - } - ZigbeeSerial->write(fcs); // finally send fcs checksum byte - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs); + bool data_frame = (0 == (msg[0] & 0x80)); + uint8_t rand = 0x42; // pseudo-randomizer initial value + uint16_t crc = 0xFFFF; // CRC16 CCITT initialization + + for (uint32_t i=0; i 0)) { + out_byte ^= rand; + if (rand & 1) { rand = (rand >> 1) ^ 0xB8; } + else { rand = (rand >> 1); } + } + + // compute CRC + crc = crc ^ ((uint16_t)out_byte << 8); + for (uint32_t i=0; i<8; i++) { + if (crc & 0x8000) { + crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard + } else { + crc <<= 1; + } + } + + // output byte + ZigbeeEZSPSend_Out(out_byte); + } + // send CRC16 in big-endian + ZigbeeEZSPSend_Out(crc >> 8); + ZigbeeEZSPSend_Out(crc & 0xFF); + + // finally send End of Frame + ZigbeeSerial->write(ZIGBEE_EZSP_EOF); // 0x1A } // Now send a MQTT message to report the sent message char hex_char[(len * 2) + 2]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"), + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT " %s"), ToHex_P(msg, len, hex_char, sizeof(hex_char))); } +// +// Same code for `ZbZNPSend` and `ZbZNPReceive` +// building the complete message (intro, length) +// +void CmndZbEZSPSendOrReceive(bool send) +{ + if (ZigbeeSerial && (XdrvMailbox.data_len > 0)) { + uint8_t code; + + char *codes = RemoveSpace(XdrvMailbox.data); + int32_t size = strlen(XdrvMailbox.data); + + SBuffer buf((size+1)/2); + + while (size > 1) { + char stemp[3]; + strlcpy(stemp, codes, sizeof(stemp)); + code = strtol(stemp, nullptr, 16); + buf.add8(code); + size -= 2; + codes += 2; + } + if (send) { + // Command was `ZbEZSPSend` + ZigbeeEZSPSend(buf.getBuffer(), buf.len()); + } else { + // Command was `ZbEZSPReceive` + ZigbeeProcessInput(buf); + } + } + ResponseCmndDone(); +} + +// For debug purposes only, simulates a message received +void CmndZbEZSPReceive(void) +{ + CmndZbEZSPSendOrReceive(false); +} + +void CmndZbEZSPSend(void) +{ + CmndZbEZSPSendOrReceive(true); +} +#endif // USE_ZIGBEE_EZSP + // // Internal function, send the low-level frame // Input: @@ -311,6 +596,7 @@ void ZigbeeZNPSend(const uint8_t *msg, size_t len) { // void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, uint16_t manuf, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId) { +#ifdef USE_ZIGBEE_ZNP SBuffer buf(32+len); buf.add8(Z_SREQ | Z_AF); // 24 buf.add8(AF_DATA_REQUEST_EXT); // 02 @@ -342,6 +628,7 @@ void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterI } ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP } /********************************************************************************************/ @@ -914,6 +1201,7 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind if (&to_group && dstLongAddr) { ResponseCmndChar_P(PSTR("Cannot have both \"ToDevice\" and \"ToGroup\"")); return; } if (!&to_group && !dstLongAddr) { ResponseCmndChar_P(PSTR("Missing \"ToDevice\" or \"ToGroup\"")); return; } +#ifdef USE_ZIGBEE_ZNP SBuffer buf(34); buf.add8(Z_SREQ | Z_ZDO); if (unbind) { @@ -935,6 +1223,7 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind } ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP ResponseCmndDone(); } @@ -961,6 +1250,7 @@ void CmndZbBindState(void) { uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } +#ifdef USE_ZIGBEE_ZNP SBuffer buf(10); buf.add8(Z_SREQ | Z_ZDO); // 25 buf.add8(ZDO_MGMT_BIND_REQ); // 33 @@ -968,6 +1258,7 @@ void CmndZbBindState(void) { buf.add8(0); // StartIndex = 0 ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP ResponseCmndDone(); } @@ -1191,6 +1482,7 @@ void CmndZbPermitJoin(void) { duration = 0xFF; // unlimited time } +#ifdef USE_ZIGBEE_ZNP SBuffer buf(34); buf.add8(Z_SREQ | Z_ZDO); // 25 buf.add8(ZDO_MGMT_PERMIT_JOIN_REQ); // 36 @@ -1200,6 +1492,7 @@ void CmndZbPermitJoin(void) { buf.add8(0x00); // TCSignificance ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP ResponseCmndDone(); } From f1780d11c15b3df30c1cb5368b4b0322aa1c08b0 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Tue, 16 Jun 2020 15:06:23 -0300 Subject: [PATCH 253/581] KNX: Revert FastPrecisePowf due to lost precision --- lib/esp-knx-ip-0.5.2/esp-knx-ip.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h index ea711825f..7150706bb 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h @@ -398,7 +398,7 @@ typedef struct __callback_assignment } callback_assignment_t; // FastPrecisePowf from tasmota/support_float.ino -extern float FastPrecisePowf(const float x, const float y); +//extern float FastPrecisePowf(const float x, const float y); class ESPKNXIP { public: @@ -567,7 +567,7 @@ class ESPKNXIP { callback_assignment_id_t __callback_register_assignment(address_t address, callback_id_t id); void __callback_delete_assignment(callback_assignment_id_t id); - static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } + //static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } ESP8266WebServer *server; address_t physaddr; From bf6083ff1c0df61fccb26cea6fa04475755b2d5a Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 16 Jun 2020 20:17:47 +0200 Subject: [PATCH 254/581] Fix wrong escape bit --- tasmota/xdrv_23_zigbee_9_impl.ino | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_9_impl.ino b/tasmota/xdrv_23_zigbee_9_impl.ino index a28481277..1cc5f6efc 100644 --- a/tasmota/xdrv_23_zigbee_9_impl.ino +++ b/tasmota/xdrv_23_zigbee_9_impl.ino @@ -206,14 +206,9 @@ void ZigbeeInputLoop(void) { } if (zigbee_buffer->len() < ZIGBEE_BUFFER_SIZE) { - // check if escape - if (ZIGBEE_EZSP_ESCAPE == zigbee_in_byte) { - escape = true; - continue; - } if (escape) { // invert bit 5 - zigbee_in_byte ^= 0x10; + zigbee_in_byte ^= 0x20; escape = false; } @@ -461,7 +456,7 @@ void ZigbeeEZSPSend_Out(uint8_t out_byte) { case 0x1A: // Cancel byte case 0x7D: // Escape byte ZigbeeSerial->write(ZIGBEE_EZSP_ESCAPE); // send Escape byte 0x7D - ZigbeeSerial->write(out_byte ^ 0x10); // send with bit 5 inverted + ZigbeeSerial->write(out_byte ^ 0x20); // send with bit 5 inverted break; default: ZigbeeSerial->write(out_byte); // send unchanged From a1d8fa755cae970cc27a3fa6b0a04df3826c6253 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 10:39:05 +0200 Subject: [PATCH 255/581] Fix ESP32 AP information --- tasmota/xdrv_01_webserver.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 5313d8ffb..f98306015 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2508,7 +2508,7 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1" D_SUBNET_MASK "}2%s"), IPAddress(Settings.ip_address[2]).toString().c_str()); WSContentSend_P(PSTR("}1" D_DNS_SERVER "}2%s"), IPAddress(Settings.ip_address[3]).toString().c_str()); } - if (static_cast(WiFi.softAPIP()) != 0) { + if ((WiFi.getMode() >= WIFI_AP) && (static_cast(WiFi.softAPIP()) != 0)) { WSContentSend_P(PSTR("}1
}2
")); WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (AP)}2%s"), WiFi.softAPIP().toString().c_str()); From 29f7506dd67e29bd96aa79eed25067c193811bc6 Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 17 Jun 2020 12:09:36 +0200 Subject: [PATCH 256/581] Fixed after Theo's review --- tasmota/tasmota_template.h | 4 ---- tasmota/tasmota_template_ESP32.h | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 0543fc7cd..6be969043 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -692,10 +692,6 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_AS3935 GPIO_AS3935, #endif -#ifdef USE_TCP_BRIDGE - AGPIO(GPIO_TCP_TX), // TCP Serial bridge - AGPIO(GPIO_TCP_RX), // TCP Serial bridge -#endif #ifdef USE_TELEINFO GPIO_TELEINFO_RX, GPIO_TELEINFO_ENABLE, diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index d85ec1a6f..8f599c5b1 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -225,7 +225,6 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BL0940_RX "|" D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|" - D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE ; @@ -624,13 +623,13 @@ typedef struct MYTMPLT { /********************************************************************************************/ // Supported hardware modules enum SupportedModules { - WEMOS, ESP32_CAM_AITHINKER, ESP32_DENKY, + WEMOS, ESP32_CAM_AITHINKER, MAXMODULE}; #define USER_MODULE 255 const char kModuleNames[] PROGMEM = - "ESP32-DevKit|ESP32 Cam AiThinker|Denky (Teleinfo)"; + "ESP32-DevKit|ESP32 Cam AiThinker"; // Default module settings const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { From cf039ef7bf5c08e9bd6b1066f21f5b74c5bae04f Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 17 Jun 2020 12:42:08 +0200 Subject: [PATCH 257/581] Removed one denky reference --- tasmota/tasmota_template_ESP32.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 8f599c5b1..6571dec1c 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -634,8 +634,7 @@ const char kModuleNames[] PROGMEM = // Default module settings const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { WEMOS, - ESP32_CAM_AITHINKER, - ESP32_DENKY + ESP32_CAM_AITHINKER }; const mytmplt kModules PROGMEM = From 83bbe757dbdcc240f30cb939e890436a968dca8c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 14:06:46 +0200 Subject: [PATCH 258/581] Add command ``Module2`` Add command ``Module2`` to configure fallback module on fast reboot (#8464) --- RELEASENOTES.md | 3 ++- tasmota/CHANGELOG.md | 4 ++++ tasmota/settings.h | 7 ++++--- tasmota/settings.ino | 15 ++++++++++++++- tasmota/support_command.ino | 27 +++++++++++++++++++-------- tasmota/tasmota.ino | 8 ++------ tasmota/tasmota_version.h | 2 +- 7 files changed, 46 insertions(+), 20 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ba5980add..31b4b1164 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,7 +52,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.3.1.5 +### Version 8.3.1.6 - Change IRremoteESP8266 library updated to v2.7.7 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) @@ -62,6 +62,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``Rule0`` to change global rule parameters - Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) +- Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` - Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index ec18a5d96..ed8f2a37d 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased (development) +### 8.3.1.6 20200617 + +- Add command ``Module2`` to configure fallback module on fast reboot (#8464) + ### 8.3.1.5 20200616 - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` diff --git a/tasmota/settings.h b/tasmota/settings.h index 80507e97b..0704f426f 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -567,11 +567,12 @@ struct { uint16_t windmeter_pulse_debounce; // F3A int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E - uint8_t ledpwm_on; // F3F - uint8_t ledpwm_off; // F40 + uint8_t ledpwm_on; // F3F + uint8_t ledpwm_off; // F40 uint8_t tcp_baudrate; // F41 + uint8_t fallback_module; // F42 - uint8_t free_f42[118]; // F42 - Decrement if adding new Setting variables just above and below + uint8_t free_f43[117]; // F43 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below uint16_t pulse_counter_debounce_low; // FB8 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index a294e2813..dffd27964 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -768,6 +768,12 @@ void SettingsDefaultSet2(void) // flag.interlock |= 0; Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group Settings.module = MODULE; +#ifdef ESP8266 + Settings.fallback_module = SONOFF_BASIC; +#else // ESP32 + Settings.fallback_module = WEMOS; +#endif // ESP8266 - ESP32 + Settings.fallback_module = MODULE; ModuleDefault(WEMOS); // for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; } SettingsUpdateText(SET_FRIENDLYNAME1, PSTR(FRIENDLY_NAME)); @@ -1452,12 +1458,19 @@ void SettingsDelta(void) Settings.flag4.network_wifi = 1; Settings.flag4.network_ethernet = 1; } - if (Settings.version < 0x08030105) { #ifdef ESP32 + if (Settings.version < 0x08030105) { Settings.eth_type = ETH_TYPE; Settings.eth_clk_mode = ETH_CLKMODE; Settings.eth_address = ETH_ADDR; + } #endif + if (Settings.version < 0x08030106) { +#ifdef ESP8266 + Settings.fallback_module = SONOFF_BASIC; +#else // ESP32 + Settings.fallback_module = WEMOS; +#endif // ESP8266 - ESP32 } Settings.version = VERSION; diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 5d0180005..a901b380d 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1018,18 +1018,29 @@ void CmndModule(void) present = ValidTemplateModule(XdrvMailbox.payload); } if (present) { - Settings.last_module = Settings.module; - Settings.module = XdrvMailbox.payload; - SetModuleType(); - if (Settings.last_module != XdrvMailbox.payload) { - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { - Settings.my_gp.io[i] = GPIO_NONE; + if (XdrvMailbox.index == 2) { + Settings.fallback_module = XdrvMailbox.payload; + } else { + Settings.last_module = Settings.module; + Settings.module = XdrvMailbox.payload; + SetModuleType(); + if (Settings.last_module != XdrvMailbox.payload) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + Settings.my_gp.io[i] = GPIO_NONE; + } } + restart_flag = 2; } - restart_flag = 2; } } - Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, ModuleNr(), ModuleName().c_str()); + uint8_t module_real = Settings.module; + uint8_t module_number = ModuleNr(); + if (XdrvMailbox.index == 2) { + module_real = Settings.fallback_module; + module_number = (USER_MODULE == Settings.fallback_module) ? 0 : Settings.fallback_module +1; + strcat(XdrvMailbox.command, "2"); + } + Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, module_number, AnyModuleName(module_real).c_str()); } void CmndModules(void) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 2c93f1b88..abc95d5d9 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -278,12 +278,8 @@ void setup(void) { #endif } if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +4) { // Restarted 6 times -#ifdef ESP8266 - Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic - // Settings.last_module = SONOFF_BASIC; -#else // ESP32 - Settings.module = WEMOS; // Reset module to Wemos -#endif // ESP8266 - ESP32 + Settings.module = Settings.fallback_module; // Reset module to fallback module +// Settings.last_module = Settings.fallback_module; } AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count); } diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 69146852c..6b64471b0 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08030105; +const uint32_t VERSION = 0x08030106; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; From 5ec694b3f3484dd2e4bfdceead96dcda71ecde0f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 14:19:20 +0200 Subject: [PATCH 259/581] Make FALLBACK_MODULE configurable Make FALLBACK_MODULE configurable (#8464) --- tasmota/my_user_config.h | 7 ++++++- tasmota/settings.ino | 13 ++----------- tasmota/tasmota_globals.h | 6 ++++++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 05c30b6a5..a7f9c7d22 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -50,7 +50,12 @@ #define PROJECT "tasmota" // PROJECT is used as the default topic delimiter // If not selected the default will be SONOFF_BASIC -//#define MODULE SONOFF_BASIC // [Module] Select default model from tasmota_template.h +//#define MODULE SONOFF_BASIC // [Module] Select default module from tasmota_template.h +#ifdef ESP8266 +#define FALLBACK_MODULE SONOFF_BASIC // [Module2] Select default module on fast reboot where USER_MODULE is user template +#else // ESP32 +#define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template +#endif #define SAVE_DATA 1 // [SaveData] Save changed parameters to Flash (0 = disable, 1 - 3600 seconds) #define SAVE_STATE true // [SetOption0] Save changed power state to Flash (false = disable, true = enable) diff --git a/tasmota/settings.ino b/tasmota/settings.ino index dffd27964..d7ede5f25 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -768,12 +768,7 @@ void SettingsDefaultSet2(void) // flag.interlock |= 0; Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group Settings.module = MODULE; -#ifdef ESP8266 - Settings.fallback_module = SONOFF_BASIC; -#else // ESP32 - Settings.fallback_module = WEMOS; -#endif // ESP8266 - ESP32 - Settings.fallback_module = MODULE; + Settings.fallback_module = FALLBACK_MODULE; ModuleDefault(WEMOS); // for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; } SettingsUpdateText(SET_FRIENDLYNAME1, PSTR(FRIENDLY_NAME)); @@ -1466,11 +1461,7 @@ void SettingsDelta(void) } #endif if (Settings.version < 0x08030106) { -#ifdef ESP8266 - Settings.fallback_module = SONOFF_BASIC; -#else // ESP32 - Settings.fallback_module = WEMOS; -#endif // ESP8266 - ESP32 + Settings.fallback_module = FALLBACK_MODULE; } Settings.version = VERSION; diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index c2acc6911..363933095 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -287,6 +287,9 @@ const char kWebColors[] PROGMEM = #ifndef MODULE #define MODULE SONOFF_BASIC // [Module] Select default model #endif +#ifndef FALLBACK_MODULE +#define FALLBACK_MODULE SONOFF_BASIC // [Module2] Select default module on fast reboot where USER_MODULE is user template +#endif #ifndef ARDUINO_ESP8266_RELEASE #define ARDUINO_CORE_RELEASE "STAGE" @@ -301,6 +304,9 @@ const char kWebColors[] PROGMEM = #ifndef MODULE #define MODULE WEMOS // [Module] Select default model #endif +#ifndef FALLBACK_MODULE +#define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template +#endif #ifndef ARDUINO_ESP32_RELEASE #define ARDUINO_CORE_RELEASE "STAGE" From 019400d77dd1991a580d2b8f36f0ae3dd858a6f1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 14:32:48 +0200 Subject: [PATCH 260/581] Fix ESP32 ethernet gateway et al Fix ESP32 ethernet gateway et al (#8503) --- tasmota/xdrv_82_ethernet.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index e20cde4e5..e1d973c62 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -95,6 +95,9 @@ void EthernetEvent(WiFiEvent_t event) { Serial.print(ETH.linkSpeed()); Serial.println("Mbps"); */ + Settings.ip_address[1] = (uint32_t)ETH.gatewayIP(); + Settings.ip_address[2] = (uint32_t)ETH.subnetMask(); + Settings.ip_address[3] = (uint32_t)ETH.dnsIP(); global_state.eth_down = 0; break; case SYSTEM_EVENT_ETH_DISCONNECTED: From 7c785ab056b1fae96dbd5484817b65394c799dff Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 15:00:48 +0200 Subject: [PATCH 261/581] Add support for Energy sensor (Denky) Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers --- RELEASENOTES.md | 4 ++-- tasmota/CHANGELOG.md | 3 +++ tasmota/my_user_config.h | 4 ++-- tasmota/tasmota_template.h | 8 +++----- tasmota/tasmota_template_ESP32.h | 15 ++++----------- tools/decode-status.py | 2 +- 6 files changed, 15 insertions(+), 21 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 53863c027..235d6de6d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -81,6 +81,6 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add initial support for Telegram bot (#8619) - Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) - Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet -- Created Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff -- Added Library to be used for decoding Teleinfo (French Metering Smart Meter) +- Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff +- Add Library to be used for decoding Teleinfo (French Metering Smart Meter) - Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index ed8f2a37d..23dd2be10 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,6 +3,9 @@ ### 8.3.1.6 20200617 - Add command ``Module2`` to configure fallback module on fast reboot (#8464) +- Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff +- Add Library to be used for decoding Teleinfo (French Metering Smart Meter) + ### 8.3.1.5 20200616 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 6f6cf704d..0499353a2 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -600,8 +600,6 @@ #define USE_TASMOTA_SLAVE_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants #define USE_TASMOTA_SLAVE_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) -#define USE_TELEINFO // Add support for Teleinfo via serial RX interface - //#define USE_TELEINFO_STANDARD // Use standard mode (9600 bps) else it's historical mode (1200 bps) // -- Power monitoring sensors -------------------- #define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) @@ -625,6 +623,8 @@ #define LE01MR_SPEED 9600 // LE-01MR modbus baudrate (default: 9600) #define LE01MR_ADDR 1 // LE-01MR modbus address (default: 0x01) #define USE_BL0940 // Add support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code) +//#define USE_TELEINFO // Add support for Teleinfo via serial RX interface (+5k2 code, +168 RAM + SmartMeter LinkedList Values RAM) +// #define USE_TELEINFO_STANDARD // Use standard mode (9600 bps) else it's historical mode (1200 bps) // -- Low level interface devices ----------------- #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 6be969043..afd707a80 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -328,9 +328,9 @@ const char kSensorNames[] PROGMEM = D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX "|" D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" D_SENSOR_WINDMETER_SPEED "|" - D_SENSOR_BL0940_RX "|" + D_SENSOR_BL0940_RX "|" D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" - D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE ; const char kSensorNamesFixed[] PROGMEM = @@ -783,7 +783,7 @@ enum SupportedModules { SUPLA1, WITTY, YUNSHAN, MAGICHOME, LUANIHVIO, KMC_70011, ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, ARILUX_LC06, SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH, OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4, - OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, + OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, MAXMODULE}; @@ -2264,10 +2264,8 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_LED1_INV, // GPIO13 WiFi Blue Led - Link and Power status 0, 0, 0, 0 } - }; - #endif // ESP8266 #ifdef ESP32 diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 6571dec1c..f15a4f72d 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -225,7 +225,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BL0940_RX "|" D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|" - D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE ; const char kSensorNamesFixed[] PROGMEM = @@ -622,20 +622,14 @@ typedef struct MYTMPLT { /********************************************************************************************/ // Supported hardware modules -enum SupportedModules { - WEMOS, ESP32_CAM_AITHINKER, - MAXMODULE}; +enum SupportedModules { WEMOS, ESP32_CAM_AITHINKER, MAXMODULE }; #define USER_MODULE 255 -const char kModuleNames[] PROGMEM = - "ESP32-DevKit|ESP32 Cam AiThinker"; +const char kModuleNames[] PROGMEM = "ESP32-DevKit|ESP32 Cam AiThinker"; // Default module settings -const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { - WEMOS, - ESP32_CAM_AITHINKER -}; +const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { WEMOS, ESP32_CAM_AITHINKER }; const mytmplt kModules PROGMEM = { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) @@ -690,7 +684,6 @@ const mytmplt kModules PROGMEM = \*********************************************************************************************/ - #endif // ESP32 #endif // _TASMOTA_TEMPLATE_ESP32_H_ diff --git a/tools/decode-status.py b/tools/decode-status.py index d0be84459..bdd679be5 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -206,7 +206,7 @@ a_features = [[ "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", "USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM", - "USE_HP303B","USE_TCP_BRIDGE","","", + "USE_HP303B","USE_TCP_BRIDGE","USE_TELEINFO","", "","","","", "","","","", "","","USE_ETHERNET","USE_WEBCAM" From 1181a701ce37c4e020bc14e91e7f580ee19e9d28 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 15:03:09 +0200 Subject: [PATCH 262/581] Update BUILDS.md --- BUILDS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILDS.md b/BUILDS.md index 91bbd287e..18d0ab9ad 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -181,3 +181,4 @@ |-----------------------|---------|-------|--------|-----|---------|----|---------|--------|-------- | USE_MI_ESP32 | - | - | - | - | - | - | - | - | | USE_WEBCAM | - | - | - | - | - | - | - | x | +| USE_ETHERNET | - | - | - | - | - | - | - | - | From c4842b08f7a0678d756cdfa5ba32a1b5285e4ec1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 15:10:52 +0200 Subject: [PATCH 263/581] Add Esp32 wESP32 template --- tasmota/tasmota_template_ESP32.h | 1 + tasmota/xdrv_82_ethernet.ino | 1 + 2 files changed, 2 insertions(+) diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index f15a4f72d..93e58b932 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -681,6 +681,7 @@ const mytmplt kModules PROGMEM = {"NAME":"AITHINKER CAM","GPIO":[4992,65504,65504,65504,65504,5088,65504,65504,65504,65504,65504,65504,65504,65504,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,65504,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} {"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} +{"NAME":"wESP32","GPIO":[65504,65504,65504,65504,65504,65504,0,0,0,65504,65504,65504,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} \*********************************************************************************************/ diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index e1d973c62..17e952e08 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -32,6 +32,7 @@ * GPIO27 - EMAC_RX_CRS_DV * * {"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} + * {"NAME":"wESP32","GPIO":[65504,65504,65504,65504,65504,65504,0,0,0,65504,65504,65504,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} * \*********************************************************************************************/ From 1aa20baf92e2a8e21eaf43e5d1382e70bc516ba9 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 15:27:12 +0200 Subject: [PATCH 264/581] Add wESP32 config --- tasmota/my_user_config.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 0499353a2..689a440b5 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -743,6 +743,10 @@ #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110 #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 #define ETH_CLKMODE 3 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT + // wESP32-PoE +// #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110 +// #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 +// #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT //#define USE_SPI // Add support for hardware SPI //#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) From ad7c929d9be19a93b073357e203cb6e2144d3e5a Mon Sep 17 00:00:00 2001 From: Justifiably Date: Wed, 17 Jun 2020 14:53:38 +0100 Subject: [PATCH 265/581] Add support for LMT01 temperature sensor --- tasmota/language/en_GB.h | 1 + tasmota/my_user_config.h | 1 + tasmota/tasmota_configurations.h | 1 + tasmota/tasmota_template.h | 7 +- tasmota/tasmota_template_ESP32.h | 1 + tasmota/xsns_74_lmt01.ino | 146 +++++++++++++++++++++++++++++++ 6 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 tasmota/xsns_74_lmt01.ino diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 3011c2aa1..aade08f71 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 689a440b5..42cf596bd 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -635,6 +635,7 @@ #define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!) #define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000) #define MAX31865_PTD_BIAS 0 // To calibrate your not-so-good PTD +//#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) // -- IR Remote features - all protocols from IRremoteESP8266 -------------------------- // IR Full Protocols mode is activated through platform.io only. diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index eb58d30e5..fa49ce2c4 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -176,6 +176,7 @@ #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram) #define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram) +#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) #define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code) #define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code) #define USE_HX711 // Add support for HX711 load cell (+1k5 code) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index afd707a80..30a3d9d90 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -238,6 +238,7 @@ enum UserSelectablePins { GPIO_TCP_RX, // TCP Serial bridge GPIO_TELEINFO_RX, // TELEINFO serial interface GPIO_TELEINFO_ENABLE,// TELEINFO Enable PIN + GPIO_LMT01, // LMT01 input counting pin GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -330,7 +331,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BL0940_RX "|" D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" - D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" + D_SENSOR_LMT01_PULSE ; const char kSensorNamesFixed[] PROGMEM = @@ -696,6 +698,9 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_TELEINFO_RX, GPIO_TELEINFO_ENABLE, #endif +#ifdef USE_LMT01 // LMT01, count pulses on GPIO + GPIO_LMT01, +#endif }; /********************************************************************************************/ diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 93e58b932..9a67d6d02 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -133,6 +133,7 @@ enum UserSelectablePins { GPIO_ETH_PHY_POWER, GPIO_ETH_PHY_MDC, GPIO_ETH_PHY_MDIO, // Ethernet GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin + GPIO_LMT01, // LMT01 input counting pin GPIO_SENSOR_END }; enum ProgramSelectablePins { diff --git a/tasmota/xsns_74_lmt01.ino b/tasmota/xsns_74_lmt01.ino new file mode 100644 index 000000000..1b3f363c9 --- /dev/null +++ b/tasmota/xsns_74_lmt01.ino @@ -0,0 +1,146 @@ +/* + xns_74_lmt01.ino + + Copyright (C) 2020 Theo Arends, Justifiably + + 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_LMT01 +/*********************************************************************************************\ + * LMT01 - 0.5°C Accurate 2-Pin Digital Output Temperature Sensor With Pulse Count Interface + * + * Uses fragments of public domain code LMT01_Example.ino released by Texas Instruments, July 10th 2017. + * See https://training.ti.com/how-interface-lmt01-temperature-sensor-arduino + * +\*********************************************************************************************/ + +#define XSNS_74 74 + +#define LMT01_TIMEOUT 200 // ms timeout for a reading cycle + +bool lmt01_initialized = false; +float lmt01_temperature = NAN; + +void LMT01_Init(void) { + if (PinUsed(GPIO_LMT01)) { + pinMode(Pin(GPIO_LMT01), INPUT); + attachInterrupt(Pin(GPIO_LMT01), LMT01_countPulse, FALLING); + lmt01_initialized = true; + } +} + +#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception +void LMT01_countPulse(void) ICACHE_RAM_ATTR; +#endif // ARDUINO_ESP8266_RELEASE_2_3_0 + +volatile int lmt01_pulseCount = 0; + +void LMT01_countPulse(void) { + lmt01_pulseCount++; +} + +void LMT01_GetTemperature(void) { + int pulses = 0; + pulses = LMT01_getPulses(); + if (pulses >= 0) { + // simple linear conversion, datasheet has a look-up table alternative + // which is accurate over a wider temperature range + lmt01_temperature = ConvertTemp(0.0625 * pulses - 50); + } else { + lmt01_temperature = NAN; // Timeout + } +} + +int LMT01_getPulses(void) { + int timeout = LMT01_TIMEOUT; + int hold = -1; + // complete current pulse cycle (50ms max) + while(lmt01_pulseCount != hold && --timeout > 0) { + hold = lmt01_pulseCount; + delay(1); + } + lmt01_pulseCount = 0; + // wait for start of next (54ms max) + while(lmt01_pulseCount == 0 && --timeout > 0) { + delay(1); + } + hold = -1; + // take this count (up to 50ms) + while(lmt01_pulseCount != hold && --timeout > 0) { + hold = lmt01_pulseCount; + delay(1); + } + if (timeout > 0) { + return hold; + } + return -1; +} + + +void LMT01_Show(bool Json) { + char temp[33]; + dtostrfd(lmt01_temperature, Settings.flag2.temperature_resolution, temp); + + if (Json) { + ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), \ + "LMT01", temp); +#ifdef USE_DOMOTICZ + if (0 == tele_period) { + DomoticzSensor(DZ_TEMP, temp); + } +#endif // USE_DOMOTICZ +#ifdef USE_KNX + if (0 == tele_period) { + KnxSensor(KNX_TEMPERATURE, lmt01_temperature); + } +#endif // USE_KNX +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, "LMT01", temp, TempUnit()); +#endif // USE_WEBSERVER + } +} + + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns74(uint8_t function) +{ + bool result = false; + + if (FUNC_INIT == function) { + LMT01_Init(); + } + else if (lmt01_initialized) { + switch (function) { + case FUNC_EVERY_SECOND: + LMT01_GetTemperature(); + break; + case FUNC_JSON_APPEND: + LMT01_Show(true); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + LMT01_Show(false); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_LMT01 From a4846c10fdbe3040fe17b860fba22949de0c75d7 Mon Sep 17 00:00:00 2001 From: Justifiably Date: Wed, 17 Jun 2020 15:17:28 +0100 Subject: [PATCH 266/581] Add D_SENSOR_LMT01_PULSE to language files. --- tasmota/language/bg_BG.h | 1 + tasmota/language/cs_CZ.h | 1 + tasmota/language/de_DE.h | 1 + tasmota/language/el_GR.h | 1 + tasmota/language/es_ES.h | 1 + tasmota/language/fr_FR.h | 1 + tasmota/language/he_HE.h | 1 + tasmota/language/hu_HU.h | 1 + tasmota/language/it_IT.h | 1 + tasmota/language/ko_KO.h | 1 + tasmota/language/nl_NL.h | 1 + tasmota/language/pl_PL.h | 1 + tasmota/language/pt_BR.h | 1 + tasmota/language/pt_PT.h | 1 + tasmota/language/ro_RO.h | 1 + tasmota/language/ru_RU.h | 1 + tasmota/language/sk_SK.h | 1 + tasmota/language/sv_SE.h | 1 + tasmota/language/tr_TR.h | 1 + tasmota/language/uk_UA.h | 1 + tasmota/language/zh_CN.h | 1 + tasmota/language/zh_TW.h | 1 + 22 files changed, 22 insertions(+) diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 73fab1f70..1bdc58227 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 9eed4e08f..740f88851 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index b24d9679a..f5f093fa5 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 1533346fe..a347f16fe 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 430099098..258cd67ac 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index d4dbbb695..ee7d36481 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index cb3a83d7c..491dfcb13 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index d7aa3b36b..d6bbe794e 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index c82ca66f4..9ab850396 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "Velocità vento" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 55137c085..ec4abfb6a 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index faf3a35da..94116549b 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 28be27c64..c943babd5 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 9ee7e4066..e9114f2a5 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 424e7dd80..155b44a83 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index a45798e13..bb0ed7f6f 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 26e9064f1..5e00d1c2a 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 211f070dd..e913b307d 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index ffb393796..b4bb93ec5 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index f11bddaa0..12078174b 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index d6dea2da6..70664f813 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index e83253105..8af9df277 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index fbf7e3e4c..3589745ec 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -681,6 +681,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" From c18977f65508d8811b51a4d0e9a090ad00b17a76 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Wed, 17 Jun 2020 16:19:33 +0200 Subject: [PATCH 267/581] Update xdrv_10_scripter.ino --- tasmota/xdrv_10_scripter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 208f7211c..921433a6d 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -397,7 +397,7 @@ void ScriptEverySecond(void) { if (bitRead(Settings.rule_enabled, 0)) { struct T_INDEX *vtp=glob_script_mem.type; - float delta=(millis()-script_lastmillis)/1000; + float delta=(millis()-script_lastmillis)/1000.0; script_lastmillis=millis(); for (uint8_t count=0; count Date: Wed, 17 Jun 2020 17:22:41 +0200 Subject: [PATCH 268/581] Add support for single wire LMT01 Add support for single wire LMT01 temperature Sensor by justifiably (#8713) --- BUILDS.md | 1 + RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 4 ++-- tasmota/my_user_config.h | 2 +- tasmota/support_features.ino | 5 +++-- tasmota/tasmota_template.h | 6 +++--- tasmota/tasmota_template_ESP32.h | 8 ++++++-- tasmota/xsns_74_lmt01.ino | 12 ++++-------- tools/decode-status.py | 4 ++-- 9 files changed, 23 insertions(+), 20 deletions(-) diff --git a/BUILDS.md b/BUILDS.md index 18d0ab9ad..700407907 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -77,6 +77,7 @@ | USE_MAX31855 | - | - | - | - | x | - | - | | USE_MAX31865 | - | - | - | - | - | - | - | | USE_THERMOSTAT | - | - | - | - | - | - | - | +| USE_LMT01 | - | - | - | - | x | - | - | | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks | USE_I2C | - | - | x | x | x | - | x | diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 235d6de6d..193cc1ca9 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -84,3 +84,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff - Add Library to be used for decoding Teleinfo (French Metering Smart Meter) - Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON +- Add support for single wire LMT01 temperature Sensor by justifiably (#8713) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 23dd2be10..846088f6a 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -4,8 +4,8 @@ - Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff -- Add Library to be used for decoding Teleinfo (French Metering Smart Meter) - +- Add library to be used for decoding Teleinfo (French Metering Smart Meter) +- Add support for single wire LMT01 temperature Sensor by justifiably (#8713) ### 8.3.1.5 20200616 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 42cf596bd..b5b0e7cb0 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -635,7 +635,7 @@ #define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!) #define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000) #define MAX31865_PTD_BIAS 0 // To calibrate your not-so-good PTD -//#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) +//#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) // -- IR Remote features - all protocols from IRremoteESP8266 -------------------------- // IR Full Protocols mode is activated through platform.io only. diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 5e582b0f9..248de8e84 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -587,8 +587,9 @@ void GetFeatures(void) #ifdef USE_TELEINFO feature6 |= 0x00040000; // xnrg_15_teleinfo.ino #endif - -// feature6 |= 0x00080000; +#ifdef USE_LMT01 + feature6 |= 0x00080000; // xsns_74_lmt01.ino +#endif // feature6 |= 0x00100000; // feature6 |= 0x00200000; diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 30a3d9d90..7f65163f7 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -452,6 +452,9 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_DSB, // Single wire DS18B20 or DS18S20 GPIO_DSB_OUT, // Pseudo Single wire DS18B20 or DS18S20 #endif +#ifdef USE_LMT01 // LMT01, count pulses on GPIO + GPIO_LMT01, +#endif // Light #ifdef USE_LIGHT @@ -698,9 +701,6 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_TELEINFO_RX, GPIO_TELEINFO_ENABLE, #endif -#ifdef USE_LMT01 // LMT01, count pulses on GPIO - GPIO_LMT01, -#endif }; /********************************************************************************************/ diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 9a67d6d02..50686c741 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -133,7 +133,7 @@ enum UserSelectablePins { GPIO_ETH_PHY_POWER, GPIO_ETH_PHY_MDC, GPIO_ETH_PHY_MDIO, // Ethernet GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin - GPIO_LMT01, // LMT01 input counting pin + GPIO_LMT01, // LMT01 input counting pin GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -226,7 +226,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BL0940_RX "|" D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|" - D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" + D_SENSOR_LMT01_PULSE ; const char kSensorNamesFixed[] PROGMEM = @@ -294,6 +295,9 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20 AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20 #endif +#ifdef USE_LMT01 + AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO +#endif // Light #ifdef USE_LIGHT diff --git a/tasmota/xsns_74_lmt01.ino b/tasmota/xsns_74_lmt01.ino index 1b3f363c9..8bd23ca4a 100644 --- a/tasmota/xsns_74_lmt01.ino +++ b/tasmota/xsns_74_lmt01.ino @@ -1,5 +1,5 @@ /* - xns_74_lmt01.ino + xns_74_lmt01.ino - Support for single wire LMT01 Temperature Sensor Copyright (C) 2020 Theo Arends, Justifiably @@ -20,13 +20,12 @@ #ifdef USE_LMT01 /*********************************************************************************************\ * LMT01 - 0.5°C Accurate 2-Pin Digital Output Temperature Sensor With Pulse Count Interface - * + * * Uses fragments of public domain code LMT01_Example.ino released by Texas Instruments, July 10th 2017. * See https://training.ti.com/how-interface-lmt01-temperature-sensor-arduino - * \*********************************************************************************************/ -#define XSNS_74 74 +#define XSNS_74 74 #define LMT01_TIMEOUT 200 // ms timeout for a reading cycle @@ -88,14 +87,12 @@ int LMT01_getPulses(void) { return -1; } - void LMT01_Show(bool Json) { char temp[33]; dtostrfd(lmt01_temperature, Settings.flag2.temperature_resolution, temp); if (Json) { - ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), \ - "LMT01", temp); + ResponseAppend_P(JSON_SNS_TEMP, "LMT01", temp); #ifdef USE_DOMOTICZ if (0 == tele_period) { DomoticzSensor(DZ_TEMP, temp); @@ -113,7 +110,6 @@ void LMT01_Show(bool Json) { } } - /*********************************************************************************************\ * Interface \*********************************************************************************************/ diff --git a/tools/decode-status.py b/tools/decode-status.py index bdd679be5..cdceced48 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -206,7 +206,7 @@ a_features = [[ "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", "USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM", - "USE_HP303B","USE_TCP_BRIDGE","USE_TELEINFO","", + "USE_HP303B","USE_TCP_BRIDGE","USE_TELEINFO","USE_LMT01", "","","","", "","","","", "","","USE_ETHERNET","USE_WEBCAM" @@ -243,7 +243,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200611 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200617 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From 7853d8c8c400031c81288514420e9c871775fd24 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 18:14:50 +0200 Subject: [PATCH 269/581] ESP32 add support for ethernet phy IP101 ESP32 add support for ethernet phy IP101 (#8503) --- libesp32/ESP32-Ethernet/README.md | 4 + .../EthernetLAN_IP101/EthernetLAN_IP101.ino | 82 +++++ libesp32/ESP32-Ethernet/keywords.txt | 166 ++++++++++ libesp32/ESP32-Ethernet/library.properties | 17 + libesp32/ESP32-Ethernet/src/ETH.cpp | 299 ++++++++++++++++++ libesp32/ESP32-Ethernet/src/ETH.h | 95 ++++++ tasmota/my_user_config.h | 4 +- tasmota/xdrv_82_ethernet.ino | 4 +- 8 files changed, 667 insertions(+), 4 deletions(-) create mode 100644 libesp32/ESP32-Ethernet/README.md create mode 100644 libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino create mode 100644 libesp32/ESP32-Ethernet/keywords.txt create mode 100644 libesp32/ESP32-Ethernet/library.properties create mode 100644 libesp32/ESP32-Ethernet/src/ETH.cpp create mode 100644 libesp32/ESP32-Ethernet/src/ETH.h diff --git a/libesp32/ESP32-Ethernet/README.md b/libesp32/ESP32-Ethernet/README.md new file mode 100644 index 000000000..ac4d80fa4 --- /dev/null +++ b/libesp32/ESP32-Ethernet/README.md @@ -0,0 +1,4 @@ +# Ethernet Arduino Library for ESP32 + +See https://github.com/espressif/arduino-esp32/issues/3554#issuecomment-596902806 + diff --git a/libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino b/libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino new file mode 100644 index 000000000..3bbe837a1 --- /dev/null +++ b/libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino @@ -0,0 +1,82 @@ +#include + +#define ETH_ADDR 1 +#define ETH_POWER_PIN 5 +#define ETH_MDC_PIN 23 +#define ETH_MDIO_PIN 18 +#define ETH_TYPE ETH_PHY_IP101 + +static bool eth_connected = false; + +void WiFiEvent(WiFiEvent_t event) +{ + switch (event) { + case SYSTEM_EVENT_ETH_START: + Serial.println("ETH Started"); + //set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } +} + +void testClient(const char * host, uint16_t port) +{ + Serial.print("\nconnecting to "); + Serial.println(host); + + WiFiClient client; + if (!client.connect(host, port)) { + Serial.println("connection failed"); + return; + } + client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host); + while (client.connected() && !client.available()); + while (client.available()) { + Serial.write(client.read()); + } + + Serial.println("closing connection\n"); + client.stop(); +} + +void setup() +{ + Serial.begin(115200); + WiFi.onEvent(WiFiEvent); + ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE); +} + + +void loop() +{ + if (eth_connected) { + testClient("google.com", 80); + } + delay(10000); +} \ No newline at end of file diff --git a/libesp32/ESP32-Ethernet/keywords.txt b/libesp32/ESP32-Ethernet/keywords.txt new file mode 100644 index 000000000..81b7ee9b2 --- /dev/null +++ b/libesp32/ESP32-Ethernet/keywords.txt @@ -0,0 +1,166 @@ +####################################### +# Syntax Coloring Map ESP32-Mail-Client +####################################### + +####################################### +# Classes (KEYWORD1) +####################################### + +IMAPData KEYWORD1 +SMTPData KEYWORD1 +attachmentData KEYWORD1 +SendStatus KEYWORD1 +messageBodyData KEYWORD1 +DownloadProgress KEYWORD1 +MessageData KEYWORD1 + +TIME KEYWORD1 + + +################################## +# Methods and Functions (KEYWORD2) +################################## + +sendMail KEYWORD2 +readMail KEYWORD2 +smtpErrorReason KEYWORD2 +imapErrorReason KEYWORD2 +sdBegin KEYWORD2 +setFlag KEYWORD2 +addFlag KEYWORD2 +removeFlag KEYWORD2 + + +setClock KEYWORD2 +getUnixTime KEYWORD2 +getTimestamp KEYWORD2 +getYear KEYWORD2 +getMonth KEYWORD2 +getDay KEYWORD2 +getDayOfWeek KEYWORD2 +getDayOfWeekString KEYWORD2 +getHour KEYWORD2 +getMin KEYWORD2 +getSec KEYWORD2 +getNumberOfDayThisYear KEYWORD2 +getTotalDays KEYWORD2 +dayofweek KEYWORD2 +getCurrentSecond KEYWORD2 +getCurrentTimestamp KEYWORD2 +getTimeFromSec KEYWORD2 + +######################################### +# Methods for IMAP Data object (KEYWORD2) +######################################### + +setLogin KEYWORD2 +setSTARTTLS KEYWORD2 +setDebug KEYWORD2 +setFolder KEYWORD2 +setMessageBufferSize KEYWORD2 +setAttachmentSizeLimit KEYWORD2 +setSearchCriteria KEYWORD2 +setSaveFilePath KEYWORD2 +setFechUID KEYWORD2 +setDownloadAttachment KEYWORD2 +setHTMLMessage KEYWORD2 +setTextMessage KEYWORD2 +setSearchLimit KEYWORD2 +setRecentSort KEYWORD2 +setReadCallback KEYWORD2 +setDownloadReport KEYWORD2 +isHeaderOnly KEYWORD2 +getFrom KEYWORD2 +getFromCharset KEYWORD2 +getTo KEYWORD2 +getToCharset KEYWORD2 +getCC KEYWORD2 +getCCCharset KEYWORD2 +getSubject KEYWORD2 +getSubjectCharset KEYWORD2 +getHTMLMessage KEYWORD2 +getTextMessage KEYWORD2 +getHTMLMessgaeCharset KEYWORD2 +getTextMessgaeCharset KEYWORD2 +getDate KEYWORD2 +getUID KEYWORD2 +getNumber KEYWORD2 +getMessageID KEYWORD2 +getAcceptLanguage KEYWORD2 +getContentLanguage KEYWORD2 +isFetchMessageFailed KEYWORD2 +getFetchMessageFailedReason KEYWORD2 +isDownloadAttachmentFailed KEYWORD2 +getDownloadAttachmentFailedReason KEYWORD2 +isDownloadMessageFailed KEYWORD2 +getDownloadMessageFailedReason KEYWORD2 +saveHTMLMessage KEYWORD2 +saveTextMessage KEYWORD2 +getFolderCount KEYWORD2 +getFolder KEYWORD2 +getFlagCount KEYWORD2 +getFlag KEYWORD2 +totalMessages KEYWORD2 +searchCount KEYWORD2 +availableMessages KEYWORD2 +getAttachmentCount KEYWORD2 +getAttachmentFileName KEYWORD2 +getAttachmentName KEYWORD2 +getAttachmentFileSize KEYWORD2 +getAttachmentCreationDate KEYWORD2 +getAttachmentType KEYWORD2 +empty KEYWORD2 +clearMessageData KEYWORD2 + +######################################### +# Methods for SMTP Data object (KEYWORD2) +######################################### + +setSender KEYWORD2 +getFromName KEYWORD2 +getSenderEmail KEYWORD2 +setPriority KEYWORD2 +getPriority KEYWORD2 +addRecipient KEYWORD2 +removeRecipient KEYWORD2 +clearRecipient KEYWORD2 +getRecipient KEYWORD2 +recipientCount KEYWORD2 +setSubject KEYWORD2 +getSubject KEYWORD2 +setMessage KEYWORD2 +getMessage KEYWORD2 +htmlFormat KEYWORD2 +addCC KEYWORD2 +removeCC KEYWORD2 +clearCC KEYWORD2 +getCC KEYWORD2 +ccCount KEYWORD2 +addBCC KEYWORD2 +removeBCC KEYWORD2 +clearBCC KEYWORD2 +getBCC KEYWORD2 +bccCount KEYWORD2 +addAttachData KEYWORD2 +removeAttachData KEYWORD2 +attachDataCount KEYWORD2 +addAttachFile KEYWORD2 +removeAttachFile KEYWORD2 +clearAttachData KEYWORD2 +clearAttachFile KEYWORD2 +clearAttachment KEYWORD2 +attachFileCount KEYWORD2 +setSendCallback KEYWORD2 + + +############################################################ +# Functions for ReadStatus and SendStatus classes (KEYWORD2) +############################################################ + +SendStatus KEYWORD2 +info KEYWORD2 +success KEYWORD2 +ReadStatus KEYWORD2 +status KEYWORD2 + +clockReady KEYWORD3 \ No newline at end of file diff --git a/libesp32/ESP32-Ethernet/library.properties b/libesp32/ESP32-Ethernet/library.properties new file mode 100644 index 000000000..50c7b8ea1 --- /dev/null +++ b/libesp32/ESP32-Ethernet/library.properties @@ -0,0 +1,17 @@ +name=ESP32 Ethernet + +version=1.1.0 + +author=Espressif + +maintainer=Espressif + +sentence=Ethernet Library for ESP32 + +paragraph=This library allows ESP32 to use ethernet hardware + +category=Communication + +url= + +architectures=esp32 diff --git a/libesp32/ESP32-Ethernet/src/ETH.cpp b/libesp32/ESP32-Ethernet/src/ETH.cpp new file mode 100644 index 000000000..2b3dd4390 --- /dev/null +++ b/libesp32/ESP32-Ethernet/src/ETH.cpp @@ -0,0 +1,299 @@ +/* + ETH.h - espre ETH PHY support. + Based on WiFi.h from Arduino WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ETH.h" +#include "eth_phy/phy.h" +#include "eth_phy/phy_tlk110.h" +#include "eth_phy/phy_lan8720.h" +#include "eth_phy/phy_ip101.h" +#include "lwip/err.h" +#include "lwip/dns.h" + +extern void tcpipInit(); + +static int _eth_phy_mdc_pin = -1; +static int _eth_phy_mdio_pin = -1; +static int _eth_phy_power_pin = -1; +static eth_phy_power_enable_func _eth_phy_power_enable_orig = NULL; + +static void _eth_phy_config_gpio(void) +{ + if(_eth_phy_mdc_pin < 0 || _eth_phy_mdio_pin < 0){ + log_e("MDC and MDIO pins are not configured!"); + return; + } + phy_rmii_configure_data_interface_pins(); + phy_rmii_smi_configure_pins(_eth_phy_mdc_pin, _eth_phy_mdio_pin); +} + +static void _eth_phy_power_enable(bool enable) +{ + pinMode(_eth_phy_power_pin, OUTPUT); + digitalWrite(_eth_phy_power_pin, enable); + delay(1); +} + +ETHClass::ETHClass():initialized(false),started(false),staticIP(false) +{ +} + +ETHClass::~ETHClass() +{} + +bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode) +{ + esp_err_t err; + if(initialized){ + err = esp_eth_enable(); + if(err){ + log_e("esp_eth_enable error: %d", err); + return false; + } + started = true; + return true; + } + _eth_phy_mdc_pin = mdc; + _eth_phy_mdio_pin = mdio; + _eth_phy_power_pin = power; + + if(type == ETH_PHY_LAN8720) + { + eth_config_t config = phy_lan8720_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } + else if(type == ETH_PHY_TLK110) + { + eth_config_t config = phy_tlk110_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } + else if(type == ETH_PHY_IP101) + { + eth_config_t config = phy_ip101_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } + else + { + log_e("Bad ETH_PHY type: %u", (uint8_t)type); + return false; + } + + eth_config.phy_addr = (eth_phy_base_t)phy_addr; + eth_config.clock_mode = clock_mode; + eth_config.gpio_config = _eth_phy_config_gpio; + eth_config.tcpip_input = tcpip_adapter_eth_input; + if(_eth_phy_power_pin >= 0){ + _eth_phy_power_enable_orig = eth_config.phy_power_enable; + eth_config.phy_power_enable = _eth_phy_power_enable; + } + + tcpipInit(); + err = esp_eth_init(ð_config); + if(!err){ + initialized = true; + err = esp_eth_enable(); + if(err){ + log_e("esp_eth_enable error: %d", err); + } else { + started = true; + return true; + } + } else { + log_e("esp_eth_init error: %d", err); + } + return false; +} + +bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) +{ + esp_err_t err = ESP_OK; + tcpip_adapter_ip_info_t info; + + if(local_ip != (uint32_t)0x00000000){ + info.ip.addr = static_cast(local_ip); + info.gw.addr = static_cast(gateway); + info.netmask.addr = static_cast(subnet); + } else { + info.ip.addr = 0; + info.gw.addr = 0; + info.netmask.addr = 0; + } + + err = tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_ETH); + if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED){ + log_e("DHCP could not be stopped! Error: %d", err); + return false; + } + + err = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_ETH, &info); + if(err != ERR_OK){ + log_e("STA IP could not be configured! Error: %d", err); + return false; +} + if(info.ip.addr){ + staticIP = true; + } else { + err = tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH); + if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED){ + log_w("DHCP could not be started! Error: %d", err); + return false; + } + staticIP = false; + } + + ip_addr_t d; + d.type = IPADDR_TYPE_V4; + + if(dns1 != (uint32_t)0x00000000) { + // Set DNS1-Server + d.u_addr.ip4.addr = static_cast(dns1); + dns_setserver(0, &d); + } + + if(dns2 != (uint32_t)0x00000000) { + // Set DNS2-Server + d.u_addr.ip4.addr = static_cast(dns2); + dns_setserver(1, &d); + } + + return true; +} + +IPAddress ETHClass::localIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.ip.addr); +} + +IPAddress ETHClass::subnetMask() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.netmask.addr); +} + +IPAddress ETHClass::gatewayIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.gw.addr); +} + +IPAddress ETHClass::dnsIP(uint8_t dns_no) +{ + ip_addr_t dns_ip = dns_getserver(dns_no); + return IPAddress(dns_ip.u_addr.ip4.addr); +} + +IPAddress ETHClass::broadcastIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); +} + +IPAddress ETHClass::networkID() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); +} + +uint8_t ETHClass::subnetCIDR() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return (uint8_t)0; + } + return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr)); +} + +const char * ETHClass::getHostname() +{ + const char * hostname; + if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_ETH, &hostname)){ + return NULL; + } + return hostname; +} + +bool ETHClass::setHostname(const char * hostname) +{ + return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_ETH, hostname) == 0; +} + +bool ETHClass::fullDuplex() +{ + return eth_config.phy_get_duplex_mode(); +} + +bool ETHClass::linkUp() +{ + return eth_config.phy_check_link(); +} + +uint8_t ETHClass::linkSpeed() +{ + return eth_config.phy_get_speed_mode()?100:10; +} + +bool ETHClass::enableIpV6() +{ + return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_ETH) == 0; +} + +IPv6Address ETHClass::localIPv6() +{ + static ip6_addr_t addr; + if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_ETH, &addr)){ + return IPv6Address(); + } + return IPv6Address(addr.addr); +} + +uint8_t * macAddress(uint8_t* mac) +{ + if(!mac){ + return NULL; + } + esp_eth_get_mac(mac); + return mac; +} + +String ETHClass::macAddress(void) +{ + uint8_t mac[6]; + char macStr[18] = { 0 }; + esp_eth_get_mac(mac); + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + +ETHClass ETH; diff --git a/libesp32/ESP32-Ethernet/src/ETH.h b/libesp32/ESP32-Ethernet/src/ETH.h new file mode 100644 index 000000000..7f175e13f --- /dev/null +++ b/libesp32/ESP32-Ethernet/src/ETH.h @@ -0,0 +1,95 @@ +/* + ETH.h - espre ETH PHY support. + Based on WiFi.h from Ardiono WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ETH_H_ +#define _ETH_H_ + +#include "WiFi.h" +#include "esp_eth.h" + +#ifndef ETH_PHY_ADDR +#define ETH_PHY_ADDR 0 +#endif + +#ifndef ETH_PHY_TYPE +#define ETH_PHY_TYPE ETH_PHY_LAN8720 +#endif + +#ifndef ETH_PHY_POWER +#define ETH_PHY_POWER -1 +#endif + +#ifndef ETH_PHY_MDC +#define ETH_PHY_MDC 23 +#endif + +#ifndef ETH_PHY_MDIO +#define ETH_PHY_MDIO 18 +#endif + +#ifndef ETH_CLK_MODE +#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN +#endif + +typedef enum { ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_IP101, ETH_PHY_MAX } eth_phy_type_t; + +class ETHClass { + private: + bool initialized; + bool started; + bool staticIP; + eth_config_t eth_config; + public: + ETHClass(); + ~ETHClass(); + + bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, eth_phy_type_t type=ETH_PHY_TYPE, eth_clock_mode_t clk_mode=ETH_CLK_MODE); + + bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); + + const char * getHostname(); + bool setHostname(const char * hostname); + + bool fullDuplex(); + bool linkUp(); + uint8_t linkSpeed(); + + bool enableIpV6(); + IPv6Address localIPv6(); + + IPAddress localIP(); + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsIP(uint8_t dns_no = 0); + + IPAddress broadcastIP(); + IPAddress networkID(); + uint8_t subnetCIDR(); + + uint8_t * macAddress(uint8_t* mac); + String macAddress(); + + friend class WiFiClient; + friend class WiFiServer; +}; + +extern ETHClass ETH; + +#endif /* _ETH_H_ */ diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index b5b0e7cb0..f52175ad7 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -741,11 +741,11 @@ //#define USE_ETHERNET // Add support for ethernet (Currently fixed for Olimex ESP32-PoE) // Olimex ESP32-PoE - #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110 + #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 #define ETH_CLKMODE 3 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT // wESP32-PoE -// #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110 +// #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 // #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 // #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index 17e952e08..aed5095df 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -50,7 +50,7 @@ #endif #ifndef ETH_TYPE -#define ETH_TYPE ETH_PHY_LAN8720 // ETH.h eth_phy_type_t: 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110 +#define ETH_TYPE ETH_PHY_LAN8720 // ETH.h eth_phy_type_t: 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 #endif #ifndef ETH_CLKMODE @@ -174,7 +174,7 @@ void CmndEthAddress(void) void CmndEthType(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { Settings.eth_type = XdrvMailbox.payload; restart_flag = 2; } From 8414f73bf4fb3f81183f247f40dfefdeca177b68 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 17 Jun 2020 18:31:31 +0200 Subject: [PATCH 270/581] ESP32 check ethernet GPIO defined --- libesp32/ESP32-Ethernet/keywords.txt | 166 --------------------------- tasmota/xdrv_82_ethernet.ino | 22 ++-- 2 files changed, 7 insertions(+), 181 deletions(-) delete mode 100644 libesp32/ESP32-Ethernet/keywords.txt diff --git a/libesp32/ESP32-Ethernet/keywords.txt b/libesp32/ESP32-Ethernet/keywords.txt deleted file mode 100644 index 81b7ee9b2..000000000 --- a/libesp32/ESP32-Ethernet/keywords.txt +++ /dev/null @@ -1,166 +0,0 @@ -####################################### -# Syntax Coloring Map ESP32-Mail-Client -####################################### - -####################################### -# Classes (KEYWORD1) -####################################### - -IMAPData KEYWORD1 -SMTPData KEYWORD1 -attachmentData KEYWORD1 -SendStatus KEYWORD1 -messageBodyData KEYWORD1 -DownloadProgress KEYWORD1 -MessageData KEYWORD1 - -TIME KEYWORD1 - - -################################## -# Methods and Functions (KEYWORD2) -################################## - -sendMail KEYWORD2 -readMail KEYWORD2 -smtpErrorReason KEYWORD2 -imapErrorReason KEYWORD2 -sdBegin KEYWORD2 -setFlag KEYWORD2 -addFlag KEYWORD2 -removeFlag KEYWORD2 - - -setClock KEYWORD2 -getUnixTime KEYWORD2 -getTimestamp KEYWORD2 -getYear KEYWORD2 -getMonth KEYWORD2 -getDay KEYWORD2 -getDayOfWeek KEYWORD2 -getDayOfWeekString KEYWORD2 -getHour KEYWORD2 -getMin KEYWORD2 -getSec KEYWORD2 -getNumberOfDayThisYear KEYWORD2 -getTotalDays KEYWORD2 -dayofweek KEYWORD2 -getCurrentSecond KEYWORD2 -getCurrentTimestamp KEYWORD2 -getTimeFromSec KEYWORD2 - -######################################### -# Methods for IMAP Data object (KEYWORD2) -######################################### - -setLogin KEYWORD2 -setSTARTTLS KEYWORD2 -setDebug KEYWORD2 -setFolder KEYWORD2 -setMessageBufferSize KEYWORD2 -setAttachmentSizeLimit KEYWORD2 -setSearchCriteria KEYWORD2 -setSaveFilePath KEYWORD2 -setFechUID KEYWORD2 -setDownloadAttachment KEYWORD2 -setHTMLMessage KEYWORD2 -setTextMessage KEYWORD2 -setSearchLimit KEYWORD2 -setRecentSort KEYWORD2 -setReadCallback KEYWORD2 -setDownloadReport KEYWORD2 -isHeaderOnly KEYWORD2 -getFrom KEYWORD2 -getFromCharset KEYWORD2 -getTo KEYWORD2 -getToCharset KEYWORD2 -getCC KEYWORD2 -getCCCharset KEYWORD2 -getSubject KEYWORD2 -getSubjectCharset KEYWORD2 -getHTMLMessage KEYWORD2 -getTextMessage KEYWORD2 -getHTMLMessgaeCharset KEYWORD2 -getTextMessgaeCharset KEYWORD2 -getDate KEYWORD2 -getUID KEYWORD2 -getNumber KEYWORD2 -getMessageID KEYWORD2 -getAcceptLanguage KEYWORD2 -getContentLanguage KEYWORD2 -isFetchMessageFailed KEYWORD2 -getFetchMessageFailedReason KEYWORD2 -isDownloadAttachmentFailed KEYWORD2 -getDownloadAttachmentFailedReason KEYWORD2 -isDownloadMessageFailed KEYWORD2 -getDownloadMessageFailedReason KEYWORD2 -saveHTMLMessage KEYWORD2 -saveTextMessage KEYWORD2 -getFolderCount KEYWORD2 -getFolder KEYWORD2 -getFlagCount KEYWORD2 -getFlag KEYWORD2 -totalMessages KEYWORD2 -searchCount KEYWORD2 -availableMessages KEYWORD2 -getAttachmentCount KEYWORD2 -getAttachmentFileName KEYWORD2 -getAttachmentName KEYWORD2 -getAttachmentFileSize KEYWORD2 -getAttachmentCreationDate KEYWORD2 -getAttachmentType KEYWORD2 -empty KEYWORD2 -clearMessageData KEYWORD2 - -######################################### -# Methods for SMTP Data object (KEYWORD2) -######################################### - -setSender KEYWORD2 -getFromName KEYWORD2 -getSenderEmail KEYWORD2 -setPriority KEYWORD2 -getPriority KEYWORD2 -addRecipient KEYWORD2 -removeRecipient KEYWORD2 -clearRecipient KEYWORD2 -getRecipient KEYWORD2 -recipientCount KEYWORD2 -setSubject KEYWORD2 -getSubject KEYWORD2 -setMessage KEYWORD2 -getMessage KEYWORD2 -htmlFormat KEYWORD2 -addCC KEYWORD2 -removeCC KEYWORD2 -clearCC KEYWORD2 -getCC KEYWORD2 -ccCount KEYWORD2 -addBCC KEYWORD2 -removeBCC KEYWORD2 -clearBCC KEYWORD2 -getBCC KEYWORD2 -bccCount KEYWORD2 -addAttachData KEYWORD2 -removeAttachData KEYWORD2 -attachDataCount KEYWORD2 -addAttachFile KEYWORD2 -removeAttachFile KEYWORD2 -clearAttachData KEYWORD2 -clearAttachFile KEYWORD2 -clearAttachment KEYWORD2 -attachFileCount KEYWORD2 -setSendCallback KEYWORD2 - - -############################################################ -# Functions for ReadStatus and SendStatus classes (KEYWORD2) -############################################################ - -SendStatus KEYWORD2 -info KEYWORD2 -success KEYWORD2 -ReadStatus KEYWORD2 -status KEYWORD2 - -clockReady KEYWORD3 \ No newline at end of file diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index aed5095df..a24d688c1 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -58,18 +58,6 @@ #endif */ -#ifndef ETH_POWER_PIN -#define ETH_POWER_PIN -1 -#endif - -#ifndef ETH_MDC_PIN -#define ETH_MDC_PIN 23 -#endif - -#ifndef ETH_MDIO_PIN -#define ETH_MDIO_PIN 18 -#endif - #include struct { @@ -116,13 +104,17 @@ void EthernetEvent(WiFiEvent_t event) { void EthernetInit(void) { if (!Settings.flag4.network_ethernet) { return; } + if (!PinUsed(GPIO_ETH_PHY_MDC) && !PinUsed(GPIO_ETH_PHY_MDIO)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: No ETH MDC and/or ETH MDIO GPIO defined")); + return; + } snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), my_hostname); WiFi.onEvent(EthernetEvent); - int eth_power = (PinUsed(GPIO_ETH_PHY_POWER)) ? Pin(GPIO_ETH_PHY_POWER) : ETH_POWER_PIN; - int eth_mdc = (PinUsed(GPIO_ETH_PHY_MDC)) ? Pin(GPIO_ETH_PHY_MDC) : ETH_MDC_PIN; - int eth_mdio = (PinUsed(GPIO_ETH_PHY_MDIO)) ? Pin(GPIO_ETH_PHY_MDIO) : ETH_MDIO_PIN; + int eth_power = (PinUsed(GPIO_ETH_PHY_POWER)) ? Pin(GPIO_ETH_PHY_POWER) : -1; + int eth_mdc = Pin(GPIO_ETH_PHY_MDC); + int eth_mdio = Pin(GPIO_ETH_PHY_MDIO); if (!ETH.begin(Settings.eth_address, eth_power, eth_mdc, eth_mdio, (eth_phy_type_t)Settings.eth_type, (eth_clock_mode_t)Settings.eth_clk_mode)) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Bad PHY type or init error")); }; From 748196dcd961402733c4598fce2fb0ca15568f9f Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 17 Jun 2020 19:54:40 +0200 Subject: [PATCH 271/581] massive use of GetTextIndexed, avoid long also --- tasmota/xnrg_15_teleinfo.ino | 488 ++++++++++++++++++++--------------- 1 file changed, 282 insertions(+), 206 deletions(-) mode change 100644 => 100755 tasmota/xnrg_15_teleinfo.ino diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino old mode 100644 new mode 100755 index 83a20648f..67fd0f158 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -23,64 +23,107 @@ * Teleinfo : French energy provider metering telemety data * Source: http://hallard.me/category/tinfo/ * - * Hardware Serial will be selected if GPIO1 = [TELEINFO_RX] + * Denky ESP32 Teleinfo Template + * {"NAME":"Denky (Teleinfo)","GPIO":[65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,0,65504,65504,65504,0,65504,65504,65504,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} + * + * Denky (aka WifInfo) ESP8266 Teleinfo Template + * {"NAME":"WifInfo","GPIO":[7,255,255,208,6,5,255,255,255,255,255,255,255],"FLAG":15,"BASE":18} + * \*********************************************************************************************/ -#define XNRG_15 15 +#define XNRG_15 15 #include "LibTeleinfo.h" #include #define TINFO_READ_TIMEOUT 400 +// All contract type enum TInfoContrat{ CONTRAT_BAS = 1, // BASE => Option Base. CONTRAT_HC, // HC.. => Option Heures Creuses. CONTRAT_EJP, // EJP. => Option EJP. - CONTRAT_BBR // BBRx => Option Tempo + CONTRAT_BBR, // BBRx => Option Tempo + CONTRAT_END }; +// contract displayed name +const char kContratName[] PROGMEM = + "|Base|Heures Creuses|EJP|Bleu Blanc Rouge" + ; + +// Received current contract value +const char kContratValue[] PROGMEM = + "|BASE|HC..|EJP.|BBR" + ; + +// all tariff type enum TInfoTarif{ - TARIF_TH = 1, // Toutes les Heures. - TARIF_HC, // Heures Creuses. - TARIF_HP, // Heures Pleines. - TARIF_HN, // BBRx => Option Tempo - TARIF_PM, // Heures de Pointe Mobile. - TARIF_CB, // Heures Creuses Jours Bleus. - TARIF_CW, // Heures Creuses Jours Blancs (White). - TARIF_CR, // Heures Creuses Jours Rouges. - TARIF_PB, // Heures Pleines Jours Bleus. - TARIF_PW, // Heures Pleines Jours Blancs (White). - TARIF_PR // Heures Pleines Jours Rouges. + TARIF_TH = 1, + TARIF_HC, TARIF_HP, + TARIF_HN, TARIF_PM, + TARIF_CB, TARIF_CW, TARIF_CR, + TARIF_PB, TARIF_PW, TARIF_PR, + TARIF_END }; -const char kTARIF_TH[] PROGMEM = "Toutes"; -const char kTARIF_HC[] PROGMEM = "Creuses"; -const char kTARIF_HP[] PROGMEM = "Pleines"; -const char kTARIF_HN[] PROGMEM = "Normales"; -const char kTARIF_PM[] PROGMEM = "Pointe Mobile"; -const char kTARIF_CB[] PROGMEM = "Creuses Bleu"; -const char kTARIF_CW[] PROGMEM = "Creuses Blanc"; -const char kTARIF_CR[] PROGMEM = "Creuses Rouge"; -const char kTARIF_PB[] PROGMEM = "Pleines Bleu"; -const char kTARIF_PW[] PROGMEM = "Pleines Blanc"; -const char kTARIF_PR[] PROGMEM = "Pleines Rouge"; +// Received current tariff values +const char kTarifValue[] PROGMEM = + "|TH..|HC..|HP.." + "|HN..|PM.." + "|HCJB|HCJW|HCJR" + "|HPJB|HPJW|HPJR" + ; -const char * kTtarifNames[] PROGMEM = { - kTARIF_TH, - kTARIF_HC, kTARIF_HP, - kTARIF_HN, kTARIF_PM, - kTARIF_CB, kTARIF_CW, kTARIF_CR, kTARIF_PB, kTARIF_PW, kTARIF_PR +// tariff displayed name +const char kTarifName[] PROGMEM = + "|Toutes|Creuses|Pleines" + "|Normales|Pointe Mobile" + "|Creuses Bleu|Creuses Blanc|Creuse Rouges" + "|Pleines Bleu|Pleines Blanc|Pleines Rouges" + ; + +enum TInfoLabel{ + LABEL_BASE = 1, + LABEL_HCHC, LABEL_HCHP, + LABEL_OPTARIF, LABEL_ISOUSC, LABEL_PTEC, + LABEL_PAPP, LABEL_IINST, LABEL_IMAX, LABEL_TENSION, + LABEL_DEMAIN, + LABEL_END }; +const char kLabel[] PROGMEM = + "|BASE|HCHC|HCHP" + "|OPTARIF|ISOUSC|PTEC" + "|PAPP|IINST|IMAX|TENSION" + "|DEMAIN" + ; + TInfo tinfo; // Teleinfo object TasmotaSerial *TInfoSerial = nullptr; bool tinfo_found = false; uint8_t contrat; uint8_t tarif; +uint8_t isousc; /*********************************************************************************************/ +/* ====================================================================== +Function: getValueFromLabelIndex +Purpose : return label value from label index +Input : label index to search for +Output : value filled +Comments: - +====================================================================== */ +char * getValueFromLabelIndex(int labelIndex, char * value) +{ + char labelName[16]; + // Get the label name + GetTextIndexed(labelName, sizeof(labelName), labelIndex, kLabel); + // Get value of label name + return tinfo.valueGet(labelName, value) ; +} + /* ====================================================================== Function: ADPSCallback Purpose : called by library when we detected a ADPS on any phased @@ -96,9 +139,9 @@ Comments: should have been initialised in the main sketch with a void ADPSCallback(uint8_t phase) { // n = phase number 1 to 3 - if (phase == 0) + if (phase == 0){ phase = 1; - + } AddLog_P2(LOG_LEVEL_INFO, PSTR("ADPS on phase %d"), phase); } @@ -113,85 +156,102 @@ Comments: - void DataCallback(struct _ValueList * me, uint8_t flags) { char c = ' '; + int ilabel ; // Does this value is new or changed? - if (flags & (TINFO_FLAGS_ADDED | TINFO_FLAGS_UPDATED) ) - { - if (flags & TINFO_FLAGS_ADDED) { c = '#'; } - if (flags & TINFO_FLAGS_UPDATED) { c = '*'; } + if (flags & (TINFO_FLAGS_ADDED | TINFO_FLAGS_UPDATED) ) { + char labelName[16]; + // Find the label index + for ( ilabel = 1 ; ilabel < LABEL_END ; ilabel++) { + GetTextIndexed(labelName, sizeof(labelName), ilabel, kLabel); + if (!strcmp(labelName, me->name)) { + break; + } + } - // Current tarif - if (!strcmp("PTEC", me->name)) + // Current tariff + if (ilabel == LABEL_PTEC) { - if (!strcmp("TH..", me->name)) { tarif = TARIF_TH; } - else if (!strcmp("HC..", me->name)) { tarif = TARIF_HC; } - else if (!strcmp("HP..", me->name)) { tarif = TARIF_HP; } - else if (!strcmp("HN..", me->name)) { tarif = TARIF_HN; } - else if (!strcmp("PM..", me->name)) { tarif = TARIF_PM; } - else if (!strcmp("HCJB", me->name)) { tarif = TARIF_CB; } - else if (!strcmp("HCJW", me->name)) { tarif = TARIF_CW; } - else if (!strcmp("HCJR", me->name)) { tarif = TARIF_CR; } - else if (!strcmp("HPJB", me->name)) { tarif = TARIF_PB; } - else if (!strcmp("HPJW", me->name)) { tarif = TARIF_PW; } - else if (!strcmp("HPJR", me->name)) { tarif = TARIF_PR; } - + char tarif_value[] = " "; // 4 spaces + // Find the tariff index + for (tarif = TARIF_TH ; tarif < TARIF_END ; tarif++) { + GetTextIndexed(tarif_value, sizeof(tarif_value), tarif-1, kTarifValue); + if (!strcmp(tarif_value, me->value)) { + break; + } + } AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Tarif changed, now '%s' (%d)"), me->value, tarif); } + // Voltage V (not present on all Smart Meter) - else if (!strcmp("TENSION", me->name)) + else if ( ilabel == LABEL_TENSION) { - Energy.voltage_available = true; - int i = atoi(me->value); - Energy.voltage[0] = (float) atoi(me->value); - + Energy.voltage_available = true; + Energy.voltage[0] = (float) atoi(me->value); // Update current if (Energy.voltage_available && Energy.voltage[0]) { Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; } - - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Voltage %s, now %d"), me->value, i); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Voltage %s, now %d"), me->value, (int) Energy.voltage[0]); } + // Current I - else if (!strcmp("IINST", me->name)) + else if (ilabel == LABEL_IINST) { - if (!Energy.voltage_available) { - int i = atoi(me->value); + if (!Energy.voltage_available) { Energy.current[0] = (float) atoi(me->value); - } else if (Energy.voltage[0]) { - Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; - } - - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Current %s, now %d"), me->value, (int) Energy.current[0]); - } - // Current P - else if (!strcmp("PAPP", me->name)) - { - int papp = atoi(me->value); - Energy.active_power[0] = (float) atoi(me->value); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Power %s, now %d"), me->value, papp); - - // Update current - if (Energy.voltage_available && Energy.voltage[0]) { + } else if (Energy.voltage[0]) { Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Current %s, now %d"), me->value, (int) Energy.current[0]); } - // kWh indexes - else if (!strcmp("HCHC", me->name) || !strcmp("HCHP", me->name)) + + // Power P + else if (ilabel == LABEL_PAPP) + { + int papp = atoi(me->value); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Power %s, now %d"), me->value, papp); + Energy.active_power[0] = (float) atoi(me->value); + // Update current + if (Energy.voltage_available && Energy.voltage[0]) { + Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; + } + } + + // Wh indexes + else if ( ilabel == LABEL_HCHC || ilabel == LABEL_HCHP) { char value[32]; - unsigned long hc = 0; - unsigned long hp = 0; - unsigned long total = 0; + uint32_t hc = 0; + uint32_t hp = 0; + uint32_t total = 0; - if ( tinfo.valueGet((char *)"HCHC", value) ) { hc = atol(value);} - if ( tinfo.valueGet((char *)"HCHP", value) ) { hp = atol(value);} - total = hc+hp; - + if ( getValueFromLabelIndex(LABEL_HCHC, value) ) { hc = atoi(value);} + if ( getValueFromLabelIndex(LABEL_HCHP, value) ) { hp = atoi(value);} + total = hc + hp; EnergyUpdateTotal(total/1000.0f, true); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%ld HP:%ld Total:%ld"), hc, hp, total); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%u HP:%u Total:%u"), hc, hp, total); } + + // Contract subscribed + else if (ilabel == LABEL_OPTARIF) + { + char contrat_value[] = " "; // 4 spaces + // Find the contract index + for (contrat = CONTRAT_BAS ; contrat < CONTRAT_END ; contrat++) { + GetTextIndexed(contrat_value, sizeof(contrat_value), contrat, kContratValue); + if (!strcmp(contrat_value, me->value)) { + break; + } + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Contract changed, now '%s' (%d)"), me->value, contrat); + } + } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: %c %s=%s"),c , me->name, me->value); + + if (flags & TINFO_FLAGS_ADDED) { c = '#'; } + if (flags & TINFO_FLAGS_UPDATED) { c = '*'; } + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TIC: %c %s=%s"),c , me->name, me->value); } /* ====================================================================== @@ -207,23 +267,14 @@ void NewFrameCallback(struct _ValueList * me) Energy.data_valid[0] = 0; } + /* ====================================================================== -Function: NewFrameCallback -Purpose : callback when we received a complete Teleinfo frama -Input : label to search for -Output : value filled +Function: TInfoDrvInit +Purpose : Tasmota core driver init +Input : - +Output : - Comments: - ====================================================================== */ -char * getDataValue(char * label, char * value) -{ - if (!tinfo.valueGet(label, value) ) { - *value = '\0'; - } - return value; -} - - - void TInfoDrvInit(void) { if (PinUsed(GPIO_TELEINFO_RX)) { energy_flg = XNRG_15; @@ -233,6 +284,13 @@ void TInfoDrvInit(void) { } } +/* ====================================================================== +Function: TInfoInit +Purpose : Tasmota core device init +Input : - +Output : - +Comments: - +====================================================================== */ void TInfoInit(void) { #ifdef USE_TELEINFO_STANDARD @@ -243,155 +301,173 @@ void TInfoInit(void) AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: inferface speed %d bps"),TINFO_SPEED); - if (PinUsed(GPIO_TELEINFO_RX)) - { - AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: enable receive on GPIO%d"), GPIO_TELEINFO_RX); - // Enable Teleinfo - if (PinUsed(GPIO_TELEINFO_ENABLE)) - { - pinMode(GPIO_TELEINFO_ENABLE, OUTPUT); - digitalWrite(GPIO_TELEINFO_ENABLE, HIGH); - AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: enable on GPIO%d"), GPIO_TELEINFO_ENABLE); - } - else - { + if (PinUsed(GPIO_TELEINFO_RX)) { + uint8_t rx_pin = Pin(GPIO_TELEINFO_RX); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: RX on GPIO%d"), rx_pin); + + // Enable Teleinfo pin used, control it + if (PinUsed(GPIO_TELEINFO_ENABLE)) { + uint8_t en_pin = Pin(GPIO_TELEINFO_ENABLE); + pinMode(en_pin, OUTPUT); + digitalWrite(en_pin, HIGH); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Enable with GPIO%d"), en_pin); + } else { AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: always enabled")); } - TInfoSerial = new TasmotaSerial(Pin(GPIO_TELEINFO_RX), -1, 1); - + TInfoSerial = new TasmotaSerial(rx_pin, -1, 1); // pinMode(GPIO_TELEINFO_RX, INPUT_PULLUP); - if (TInfoSerial->begin(TINFO_SPEED, SERIAL_7E1)) - { - if (TInfoSerial->hardwareSerial()) { - // This is a dirty hack to bypass HW serial init when for Teleinfo - // This protocol needs 7E1 configuration so on ESP8266 this is - // working only on Serial RX pin (Hardware Serial) for now - Serial.end(); - Serial.begin(TINFO_SPEED, SERIAL_7E1); - ClaimSerial(); - } + // Trick here even using SERIAL_7E1 or TS_SERIAL_7E1 + // this is not working, need to call SetSerialConfig after + if (TInfoSerial->begin(TINFO_SPEED)) { + // This is a hack, looks like begin does not take into account + // the TS_SERIAL_7E1 configuration so on ESP8266 this is + // working only on Serial RX pin (Hardware Serial) for now + SetSerialConfig(TS_SERIAL_7E1); TInfoSerial->setTimeout(TINFO_READ_TIMEOUT); +#if defined (ESP8266) + if (TInfoSerial->hardwareSerial() ) { + ClaimSerial(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using hardware serial")); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using software serial")); + } + +#elif defined (ESP32) + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using ESP32 hardware serial")); +#endif // Init teleinfo tinfo.init(); - // Attach needed callbacks tinfo.attachADPS(ADPSCallback); tinfo.attachData(DataCallback); tinfo.attachNewFrame(NewFrameCallback); - tinfo_found = true; AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Ready")); } } } -void TInfoLoop(void) -{ - char c; - if (!tinfo_found) - return; - - if (TInfoSerial->available()) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: received %d chars"), TInfoSerial->available()); - - // We received some data? - while (TInfoSerial->available()>8) - { - // get char - c = TInfoSerial->read(); - - // data processing - tinfo.process(c); - } - } -} - - +/* ====================================================================== +Function: TInfoEvery250ms +Purpose : Tasmota callback executed every 250ms +Input : - +Output : - +Comments: - +====================================================================== */ void TInfoEvery250ms(void) { + char c; + if (!tinfo_found) + return; + + if (TInfoSerial->available()) { + //AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: received %d chars"), TInfoSerial->available()); + // We received some data? + while (TInfoSerial->available()>8) { + // get char + c = TInfoSerial->read(); + // data processing + tinfo.process(c); + } + } } +/* ====================================================================== +Function: TInfoShow +Purpose : Tasmota callback executed to send telemetry or WEB display +Input : - +Output : - +Comments: - +====================================================================== */ #ifdef USE_WEBSERVER -const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_KILOWATTHOUR "{e}" ; +const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "{e}" ; const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ; const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "{m}%d " D_UNIT_AMPERE "{e}" ; -const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}Tarif{m}%s{e}" ; +const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}Tarif en cours{m}Heures %s{e}" ; +const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}Contrat{m}%s %d" D_UNIT_AMPERE "{e}" ; #endif // USE_WEBSERVER void TInfoShow(bool json) { - char value[32]; - // TBD - if (json) - { - if ( tinfo.valueGet((char *)"PTEC", value) ) { - ResponseAppend_P(PSTR(",\"" "TARIF" "\":%s"), value); + char name[32]; + char value[32]; + + // Since it's an Energy device , current, voltage and power are + // already present on the telemetry frame. No need to add here + // Just add the specific and missing ones there + if (json) + { + if ( getValueFromLabelIndex(LABEL_PTEC, value) ) { + ResponseAppend_P(PSTR(",\"" "TARIF" "\":\"%s\""), value); } - if ( tinfo.valueGet((char *)"IINST", value) ) { - ResponseAppend_P(PSTR(",\"" D_CURRENT "\":%s"), value); + if ( getValueFromLabelIndex(LABEL_ISOUSC, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_ISOUSC, kLabel); + ResponseAppend_P(PSTR(",\"%s\":%d"), name, atoi(value)); } - if ( tinfo.valueGet((char *)"PAPP", value) ) { - ResponseAppend_P(PSTR(",\"" D_POWERUSAGE "\":%s"), value); + if ( getValueFromLabelIndex(LABEL_HCHC, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel); + ResponseAppend_P(PSTR(",\"%s\":\"%u\""), name, atoi(value)); } - if ( tinfo.valueGet((char *)"HCHC", value) ) { - ResponseAppend_P(PSTR(",\"" "HC" "\":%s"), value); - } - if ( tinfo.valueGet((char *)"HCHP", value) ) { - ResponseAppend_P(PSTR(",\"" "HP" "\":%s"), value); + if ( getValueFromLabelIndex(LABEL_HCHP, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHP, kLabel); + ResponseAppend_P(PSTR(",\"%s\":\"%u\""),name , atoi(value)); } #ifdef USE_WEBSERVER - } - else - { - getDataValue("HCHC", value); - WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, kTARIF_HC, value); - getDataValue("HCHP", value); - WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, kTARIF_HP, value); - if (tarif) { - WSContentSend_PD(HTTP_ENERGY_TARIF_TELEINFO, kTtarifNames[tarif-1]); - } - - + } + else + { + if (getValueFromLabelIndex(LABEL_HCHC, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel); + WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_HCHP, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHP, kLabel); + WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (tarif) { + GetTextIndexed(name, sizeof(name), tarif-1, kTarifName); + WSContentSend_PD(HTTP_ENERGY_TARIF_TELEINFO, name,value); + } + if (contrat) { + GetTextIndexed(name, sizeof(name), contrat, kContratName); + if (getValueFromLabelIndex(LABEL_ISOUSC, value) ) { + WSContentSend_PD(HTTP_ENERGY_CONTRAT_TELEINFO, name, atoi(value)); + } + } #endif // USE_WEBSERVER - } + } } /*********************************************************************************************\ * Interface \*********************************************************************************************/ - bool Xnrg15(uint8_t function) { - - switch (function) - { - case FUNC_LOOP: - if (TInfoSerial) { TInfoLoop(); } - break; - case FUNC_EVERY_250_MSECOND: - if (uptime > 4) { TInfoEvery250ms(); } - break; - case FUNC_JSON_APPEND: - - TInfoShow(1); - break; -#ifdef USE_WEBSERVER - case FUNC_WEB_SENSOR: - TInfoShow(0); - break; -#endif // USE_WEBSERVER - case FUNC_INIT: - TInfoInit(); - break; - case FUNC_PRE_INIT: - TInfoDrvInit(); - break; - } - return false; + switch (function) + { + case FUNC_EVERY_250_MSECOND: + if (uptime > 4) { TInfoEvery250ms(); } + break; + case FUNC_JSON_APPEND: + TInfoShow(1); + break; + #ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + TInfoShow(0); + break; + #endif // USE_WEBSERVER + case FUNC_INIT: + TInfoInit(); + break; + case FUNC_PRE_INIT: + TInfoDrvInit(); + break; + } + return false; } #endif // USE_TELEINFO -#endif // USE_ENERGY_SENSOR +#endif // USE_ENERGY_SENSOR \ No newline at end of file From 63f8a2aafdc70a31dbe099b38a74e4dc51499508 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 18 Jun 2020 10:18:49 +0200 Subject: [PATCH 272/581] Fix ESP32 network checks Fix ESP32 network checks (#8503) --- tasmota/support_rtc.ino | 2 +- tasmota/xdrv_40_telegram.ino | 2 +- tasmota/xdrv_81_webcam.ino | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino index 445976eb3..25ad82435 100644 --- a/tasmota/support_rtc.ino +++ b/tasmota/support_rtc.ino @@ -379,7 +379,7 @@ void RtcSecond(void) Rtc.millis = millis(); if (!Rtc.user_time_entry) { - if (!global_state.wifi_down) { + if (!global_state.network_down) { uint8_t uptime_minute = (uptime / 60) % 60; // 0 .. 59 if ((Rtc.ntp_sync_minute > 59) && (uptime_minute > 2)) { Rtc.ntp_sync_minute = 1; // If sync prepare for a new cycle diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino index 97c5aa453..a7beb5005 100644 --- a/tasmota/xdrv_40_telegram.ino +++ b/tasmota/xdrv_40_telegram.ino @@ -322,7 +322,7 @@ String TelegramExecuteCommand(const char *svalue) { } void TelegramLoop(void) { - if (!global_state.wifi_down && (Telegram.recv_enable || Telegram.echo_enable)) { + if (!global_state.network_down && (Telegram.recv_enable || Telegram.echo_enable)) { switch (Telegram.state) { case 0: TelegramInit(); diff --git a/tasmota/xdrv_81_webcam.ino b/tasmota/xdrv_81_webcam.ino index 9cbeb4133..71d81d2ac 100644 --- a/tasmota/xdrv_81_webcam.ino +++ b/tasmota/xdrv_81_webcam.ino @@ -792,7 +792,7 @@ void HandleWebcamRoot(void) { /*********************************************************************************************/ uint32_t WcSetStreamserver(uint32_t flag) { - if (global_state.wifi_down) { return 0; } + if (global_state.network_down) { return 0; } Wc.stream_active = 0; From 2af506e48b62812d8b30b474c74854c7afc31d03 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 18 Jun 2020 12:55:10 +0200 Subject: [PATCH 273/581] Change ESP32 USER GPIO template representation decreasing template message size Change ESP32 USER GPIO template representation decreasing template message size --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/support.ino | 16 ++++++++++++++++ tasmota/tasmota_template_ESP32.h | 4 ++++ tasmota/xdrv_01_webserver.ino | 16 ---------------- tasmota/xdrv_82_ethernet.ino | 4 ++-- 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 193cc1ca9..543b5a0f3 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -58,6 +58,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` +- Change ESP32 USER GPIO template representation decreasing template message size - Fix escape of non-JSON received serial data (#8329) - Add command ``Rule0`` to change global rule parameters - Add command ``Time 4`` to display timestamp using milliseconds (#8537) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 846088f6a..6ab9667e1 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -6,6 +6,7 @@ - Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff - Add library to be used for decoding Teleinfo (French Metering Smart Meter) - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) +- Change ESP32 USER GPIO template representation decreasing template message size ### 8.3.1.5 20200616 diff --git a/tasmota/support.ino b/tasmota/support.ino index 8b2c144f7..2d8389b90 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1359,7 +1359,15 @@ bool JsonTemplate(const char* dataBuf) } if (obj[D_JSON_GPIO].success()) { for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { +#ifdef ESP8266 Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0; +#else // ESP32 + uint16_t gpio = obj[D_JSON_GPIO][i] | 0; + if (gpio == (AGPIO(GPIO_NONE) +1)) { + gpio = AGPIO(GPIO_USER); + } + Settings.user_template.gp.io[i] = gpio; +#endif } } if (obj[D_JSON_FLAG].success()) { @@ -1378,7 +1386,15 @@ void TemplateJson(void) { Response_P(PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), SettingsText(SET_TEMPLATE_NAME)); for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { +#ifdef ESP8266 ResponseAppend_P(PSTR("%s%d"), (i>0)?",":"", Settings.user_template.gp.io[i]); +#else // ESP32 + uint16_t gpio = Settings.user_template.gp.io[i]; + if (gpio == AGPIO(GPIO_USER)) { + gpio = AGPIO(GPIO_NONE) +1; + } + ResponseAppend_P(PSTR("%s%d"), (i>0)?",":"", gpio); +#endif } ResponseAppend_P(PSTR("],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), Settings.user_template.flag, Settings.user_template_base +1); } diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 50686c741..b405facfa 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -688,6 +688,10 @@ const mytmplt kModules PROGMEM = {"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} {"NAME":"wESP32","GPIO":[65504,65504,65504,65504,65504,65504,0,0,0,65504,65504,65504,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} +{"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} +{"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} +{"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + \*********************************************************************************************/ #endif // ESP32 diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index f98306015..d545dfcb7 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2327,22 +2327,6 @@ void OtherSaveSettings(void) } AddLog_P(LOG_LEVEL_INFO, message); -/* - // This sometimes provides intermittent watchdog - bool template_activate = Webserver->hasArg("t2"); // Try this to tackle intermittent watchdog after execution of Template command - WebGetArg("t1", tmp, sizeof(tmp)); - if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255} - char svalue[128]; - snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " %s"), tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); - - if (template_activate) { - snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_MODULE " 0")); - ExecuteWebCommand(svalue, SRC_WEBGUI); - } - } - // Try async execution of commands -*/ WebGetArg("t1", tmp, sizeof(tmp)); if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255} snprintf_P(message, sizeof(message), PSTR(D_CMND_BACKLOG " " D_CMND_TEMPLATE " %s%s"), tmp, (Webserver->hasArg("t2")) ? "; " D_CMND_MODULE " 0" : ""); diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index a24d688c1..034c72636 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -31,8 +31,8 @@ * GPIO26 - EMAC_RXD1(RMII) * GPIO27 - EMAC_RX_CRS_DV * - * {"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} - * {"NAME":"wESP32","GPIO":[65504,65504,65504,65504,65504,65504,0,0,0,65504,65504,65504,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} + * {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + * {"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} * \*********************************************************************************************/ From 4e3b547657b6a74bc87ec7671f4cf49c13783e64 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 18 Jun 2020 14:24:15 +0200 Subject: [PATCH 274/581] BLM certify part 1 --- tasmota/xsns_54_ina226.ino | 62 +++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/tasmota/xsns_54_ina226.ino b/tasmota/xsns_54_ina226.ino index 725a63bb3..81c4bafc3 100644 --- a/tasmota/xsns_54_ina226.ino +++ b/tasmota/xsns_54_ina226.ino @@ -26,7 +26,7 @@ * 2. Configure the module to use I2C on the correct pins. * 3. Connect your ina226 module(s) to the I2C pins. * 4. Use the i2cscan console command to probe the modules and check they are present. -* 5. Enable the first device at I2C slave address 0x40 using the following console commands: +* 5. Enable the first device at I2C address 0x40 using the following console commands: * a. Sensor54 11 [shunt resistance in ohms] e.g. Sensor54 11 0.1 * b. Sensor54 12 [full scale current in amperes] e.g. Sensor54 12 3.0 * c. Sensor54 2 saves the settings and restarts Tasmota. The device should show up after the system boots again. @@ -35,7 +35,7 @@ * This driver will not probe I2C bus for INA226 devices unless the full scale current is set for a device number. * It will map device numbers as follows: * -* Device number to I2C slave address mapping +* Device number to I2C address mapping * * 1 - 0x40 * 2 - 0x41 @@ -59,7 +59,7 @@ * * Other commands * -* Sensor54 1 Rescan for devices and return the number of slaves found. +* Sensor54 1 Rescan for devices and return the number of INA226 found. * Sensor54 2 Save the configuration and restart * * @@ -88,13 +88,13 @@ #define INA226_REG_CALIBRATION (0x05) -typedef struct Ina226SlaveInfo_tag { +typedef struct Ina226Info_tag { uint8_t address; uint16_t calibrationValue; uint16_t config; uint8_t present : 1; float i_lsb; -} Ina226SlaveInfo_t; +} Ina226Info_t; /* * Program memory constants @@ -108,9 +108,9 @@ static const uint8_t PROGMEM probeAddresses[INA226_MAX_ADDRESSES] = {INA226_ADDR static char Ina226Str[] = "INA226"; -static uint8_t slavesFound = 0; +static uint8_t Ina226sFound = 0; static uint8_t schedule_reinit = 0; -static Ina226SlaveInfo_t slaveInfo[4] = {0}; +static Ina226Info_t Ina226Info[4] = {0}; //static uint16_t reinit_count[4]; static float voltages[4]; static float currents[4]; @@ -148,10 +148,10 @@ static uint32_t _expand_r_shunt(uint16_t compact_r_shunt) * Set calibration value for Ina226 */ -void Ina226SetCalibration(uint8_t slaveIndex) +void Ina226SetCalibration(uint8_t Ina226Index) { -Ina226SlaveInfo_t *si = slaveInfo + slaveIndex; +Ina226Info_t *si = Ina226Info + Ina226Index; I2cWrite16( si->address, INA226_REG_CALIBRATION, si->calibrationValue); @@ -167,10 +167,10 @@ bool Ina226TestPresence(uint8_t device) // Read config - uint16_t config = I2cRead16( slaveInfo[device].address, INA226_REG_CONFIG ); + uint16_t config = I2cRead16( Ina226Info[device].address, INA226_REG_CONFIG ); //AddLog_P2( LOG_LEVEL_NONE, PSTR("Config register %04x" ), config); - if (config != slaveInfo[device].config) + if (config != Ina226Info[device].config) return false; return true; @@ -179,10 +179,10 @@ bool Ina226TestPresence(uint8_t device) void Ina226ResetActive(void) { - Ina226SlaveInfo_t *p = slaveInfo; + Ina226Info_t *p = Ina226Info; for (uint32_t i = 0; i < INA226_MAX_ADDRESSES; i++) { - p = &slaveInfo[i]; + p = &Ina226Info[i]; // Address uint8_t addr = p->address; if (addr) { @@ -199,9 +199,9 @@ void Ina226Init() { uint32_t i; - slavesFound = 0; + Ina226sFound = 0; - Ina226SlaveInfo_t *p = slaveInfo; + Ina226Info_t *p = Ina226Info; //AddLog_P2( LOG_LEVEL_NONE, "Ina226Init"); // AddLog_P2( LOG_LEVEL_NONE, "Size of Settings: %d bytes", sizeof(Settings)); @@ -210,7 +210,7 @@ void Ina226Init() // AddLog_P2(LOG_LEVEL_DEBUG, "INA226: Initialization failed: No I2C support"); - // Clear slave info data + // Clear Ina226 info data for (i = 0; i < 4; i++){ *p = {0}; @@ -232,7 +232,7 @@ void Ina226Init() continue; - //AddLog_P2( LOG_LEVEL_NONE, PSTR("INA226 trying slave address %02x" ), addr ); + //AddLog_P2( LOG_LEVEL_NONE, PSTR("INA226 trying address %02x" ), addr ); // Try Resetting the device @@ -257,8 +257,8 @@ void Ina226Init() if (!I2cWrite16( addr, INA226_REG_CONFIG, config)) continue; // No device - // store data in slave info struct. - p = &slaveInfo[i]; + // store data in info struct. + p = &Ina226Info[i]; // Address p->address = addr; // Configuration @@ -282,7 +282,7 @@ void Ina226Init() I2cSetActiveFound(addr, Ina226Str); - slavesFound++; + Ina226sFound++; } } @@ -292,7 +292,7 @@ void Ina226Init() float Ina226ReadBus_v(uint8_t device) { - uint8_t addr = slaveInfo[device].address; + uint8_t addr = Ina226Info[device].address; int16_t reg_bus_v = I2cReadS16( addr, INA226_REG_BUSVOLTAGE); float result = ((float) reg_bus_v) * 0.00125f; @@ -307,10 +307,10 @@ float Ina226ReadBus_v(uint8_t device) float Ina226ReadShunt_i(uint8_t device) { - uint8_t addr = slaveInfo[device].address; + uint8_t addr = Ina226Info[device].address; int16_t reg_shunt_i = I2cReadS16( addr, INA226_REG_CURRENT); - float result = ((float) reg_shunt_i) * slaveInfo[device].i_lsb; + float result = ((float) reg_shunt_i) * Ina226Info[device].i_lsb; return result; } @@ -321,10 +321,10 @@ float Ina226ReadShunt_i(uint8_t device) float Ina226ReadPower_w(uint8_t device) { - uint8_t addr = slaveInfo[device].address; + uint8_t addr = Ina226Info[device].address; int16_t reg_shunt_i = I2cReadS16( addr, INA226_REG_POWER); - float result = ((float) reg_shunt_i) * (slaveInfo[device].i_lsb * 25.0); + float result = ((float) reg_shunt_i) * (Ina226Info[device].i_lsb * 25.0); return result; } @@ -354,19 +354,19 @@ void Ina226EverySecond() { //AddLog_P2( LOG_LEVEL_NONE, "Ina226EverySecond"); for (uint8_t device = 0; device < INA226_MAX_ADDRESSES; device++){ - // If there are slaves, and the device was present, and the device still is present, read its registers - if (slavesFound && slaveInfo[device].present && Ina226TestPresence(device)){ + // If there are Ina226s, and the device was present, and the device still is present, read its registers + if (Ina226sFound && Ina226Info[device].present && Ina226TestPresence(device)){ Ina226Read(device); } else { powers[device] = currents[device] = voltages[device] = 0.0f; // If device was present, note that it dropped off here - //if(slaveInfo[device].present){ + //if(Ina226Info[device].present){ //reinit_count[device]++; //AddLog_P2( LOG_LEVEL_DEBUG, "INA226 Device %d dropped off, count: %d", device, reinit_count[device]); //} // Device no longer present - slaveInfo[device].present = false; + Ina226Info[device].present = false; } } } @@ -413,7 +413,7 @@ bool Ina226CommandSensor() case 1: // Rerun init Ina226ResetActive(); Ina226Init(); - Response_P(PSTR("{\"Sensor54-Command-Result\":{\"SlavesFound\":%d}}"),slavesFound); + Response_P(PSTR("{\"Sensor54-Command-Result\":{\"Ina226sFound\":%d}}"),Ina226sFound); break; case 2: // Save and restart @@ -497,7 +497,7 @@ void Ina226Show(bool json) int i, num_found; for (num_found = 0, i = 0; i < INA226_MAX_ADDRESSES; i++) { // Skip uninstalled sensors - if (!slaveInfo[i].present) + if (!Ina226Info[i].present) continue; num_found++; From c533eb11869ddd18962aac4408b87cedb4d7e58a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 18 Jun 2020 16:05:55 +0200 Subject: [PATCH 275/581] BLM certify part 2 - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT - Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` --- RELEASENOTES.md | 2 + tasmota/CHANGELOG.md | 2 + tasmota/language/bg_BG.h | 6 +- tasmota/language/cs_CZ.h | 6 +- tasmota/language/de_DE.h | 6 +- tasmota/language/el_GR.h | 6 +- tasmota/language/en_GB.h | 6 +- tasmota/language/es_ES.h | 6 +- tasmota/language/fr_FR.h | 6 +- tasmota/language/he_HE.h | 6 +- tasmota/language/hu_HU.h | 6 +- tasmota/language/it_IT.h | 6 +- tasmota/language/ko_KO.h | 6 +- tasmota/language/nl_NL.h | 6 +- tasmota/language/pl_PL.h | 6 +- tasmota/language/pt_BR.h | 6 +- tasmota/language/pt_PT.h | 6 +- tasmota/language/ro_RO.h | 6 +- tasmota/language/ru_RU.h | 6 +- tasmota/language/sk_SK.h | 6 +- tasmota/language/sv_SE.h | 6 +- tasmota/language/tr_TR.h | 6 +- tasmota/language/uk_UA.h | 6 +- tasmota/language/zh_CN.h | 6 +- tasmota/language/zh_TW.h | 6 +- tasmota/my_user_config.h | 6 +- tasmota/support.ino | 4 +- tasmota/support_features.ino | 4 +- tasmota/tasmota_configurations.h | 8 +- tasmota/tasmota_globals.h | 12 + tasmota/tasmota_template.h | 28 +- tasmota/tasmota_template_ESP32.h | 20 +- tasmota/xdrv_01_webserver.ino | 32 +- tasmota/xdrv_31_tasmota_client.ino | 585 +++++++++++++++++++++++++++ tasmota/xdrv_31_tasmota_slave.ino | 615 ----------------------------- tasmota/xnrg_13_fif_le01mr.ino | 6 +- 36 files changed, 724 insertions(+), 738 deletions(-) create mode 100644 tasmota/xdrv_31_tasmota_client.ino delete mode 100644 tasmota/xdrv_31_tasmota_slave.ino diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 543b5a0f3..410ecc1d1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -59,6 +59,8 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` - Change ESP32 USER GPIO template representation decreasing template message size +- Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT +- Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` - Fix escape of non-JSON received serial data (#8329) - Add command ``Rule0`` to change global rule parameters - Add command ``Time 4`` to display timestamp using milliseconds (#8537) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 6ab9667e1..3ba3a1d38 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -7,6 +7,8 @@ - Add library to be used for decoding Teleinfo (French Metering Smart Meter) - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) - Change ESP32 USER GPIO template representation decreasing template message size +- Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT +- Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` ### 8.3.1.5 20200616 diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 1bdc58227..17b267290 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 740f88851..f123481dd 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index f5f093fa5..8c2fa8645 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index a347f16fe..44e812b35 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index aade08f71..b3e06b94a 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 258cd67ac..471c0d449 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index ee7d36481..b45b9b1a2 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "Hibernation" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Esclave TX" -#define D_SENSOR_SLAVE_RX "Esclave RX" -#define D_SENSOR_SLAVE_RESET "Esclave Rst" +#define D_SENSOR_CLIENT_TX "Esclave TX" +#define D_SENSOR_CLIENT_RX "Esclave RX" +#define D_SENSOR_CLIENT_RESET "Esclave Rst" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 491dfcb13..acf642ce3 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index d6bbe794e..26e0ced62 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 9ab850396..924105509 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 - DATI" #define D_SENSOR_DEEPSLEEP "Deep sleep" #define D_SENSOR_EXS_ENABLE "EXS - Abilita" -#define D_SENSOR_SLAVE_TX "Slave - TX" -#define D_SENSOR_SLAVE_RX "Slave - RX" -#define D_SENSOR_SLAVE_RESET "Slave - RST" +#define D_SENSOR_CLIENT_TX "Client - TX" +#define D_SENSOR_CLIENT_RX "Client - RX" +#define D_SENSOR_CLIENT_RESET "Client - RST" #define D_SENSOR_GPS_RX "GPS - RX" #define D_SENSOR_GPS_TX "GPS - TX" #define D_SENSOR_HM10_RX "HM10 - RX" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index ec4abfb6a..3fd602224 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 94116549b..d48d02988 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index c943babd5..6ca24f165 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "Głęboko uÅ›piony" #define D_SENSOR_EXS_ENABLE "Załącz EXS" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index e9114f2a5..8eb4381d0 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 155b44a83..9defb5975 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index bb0ed7f6f..b41cfef2f 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 5e00d1c2a..8c0a54b19 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index e913b307d..0bd2d2016 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index b4bb93ec5..b846fdb82 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 12078174b..7778459fa 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 70664f813..9d153c732 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 8af9df277..37d280fc3 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 3589745ec..f0696fc01 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -663,9 +663,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index f52175ad7..87647a98d 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -596,9 +596,9 @@ // #define USE_FLOG // Add support for GPS logging in OTA's Flash (Experimental) (+2k9 code, +8 bytes RAM) //#define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge (+9k3 code) //#define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -//#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k6 code, 64 mem) - #define USE_TASMOTA_SLAVE_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants - #define USE_TASMOTA_SLAVE_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini +//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k6 code, 64 mem) + #define USE_TASMOTA_CLIENT_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants + #define USE_TASMOTA_CLIENT_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) // -- Power monitoring sensors -------------------- diff --git a/tasmota/support.ino b/tasmota/support.ino index 2d8389b90..87cd0ce5e 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1620,8 +1620,8 @@ void I2cScan(char *devs, unsigned int devs_len) // Return error codes defined in twi.h and core_esp8266_si2c.c // I2C_OK 0 // I2C_SCL_HELD_LOW 1 = SCL held low by another device, no procedure available to recover - // I2C_SCL_HELD_LOW_AFTER_READ 2 = I2C bus error. SCL held low beyond slave clock stretch time - // I2C_SDA_HELD_LOW 3 = I2C bus error. SDA line held low by slave/another_master after n bits + // I2C_SCL_HELD_LOW_AFTER_READ 2 = I2C bus error. SCL held low beyond client clock stretch time + // I2C_SDA_HELD_LOW 3 = I2C bus error. SDA line held low by client/another_master after n bits // I2C_SDA_HELD_LOW_AFTER_INIT 4 = line busy. SDA again held low by another device. 2nd master? uint8_t error = 0; diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 248de8e84..abd5f4236 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -477,8 +477,8 @@ void GetFeatures(void) #ifdef USE_EXS_DIMMER feature5 |= 0x00008000; // xdrv_30_exs_dimmer.ino #endif -#ifdef USE_TASMOTA_SLAVE - feature5 |= 0x00010000; // xdrv_31_arduino_slave.ino +#ifdef USE_TASMOTA_CLIENT + feature5 |= 0x00010000; // xdrv_31_tasmota_client.ino #endif #ifdef USE_HIH6 feature5 |= 0x00020000; // xsns_55_hih_series.ino diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index fa49ce2c4..10f183ec5 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -152,7 +152,7 @@ #define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) //#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -//#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) //#define USE_MCP9808 // Add support for MCP9808 temperature sensor (+0k9 code) //#define USE_HP303B // Add support for HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) @@ -383,7 +383,7 @@ #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -#undef USE_TASMOTA_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) //#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor @@ -488,7 +488,7 @@ #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -#undef USE_TASMOTA_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) //#undef USE_ENERGY_SENSOR // Disable energy sensors @@ -615,7 +615,7 @@ #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -#undef USE_TASMOTA_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_ENERGY_SENSOR // Disable energy sensors diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 363933095..620c6ff68 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -69,6 +69,18 @@ String EthernetMacAddress(void); #ifdef USE_EMULATION_WEMO #define USE_EMULATION #endif + +// Convert legacy slave to client +#ifdef USE_TASMOTA_SLAVE +#define USE_TASMOTA_CLIENT +#endif +#ifdef USE_TASMOTA_SLAVE_FLASH_SPEED +#define USE_TASMOTA_CLIENT_FLASH_SPEED USE_TASMOTA_SLAVE_FLASH_SPEED +#endif +#ifdef USE_TASMOTA_SLAVE_SERIAL_SPEED +#define USE_TASMOTA_CLIENT_SERIAL_SPEED USE_TASMOTA_SLAVE_SERIAL_SPEED +#endif + // See https://github.com/esp8266/Arduino/pull/4889 #undef NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 7f65163f7..bd1c009de 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -137,8 +137,8 @@ enum UserSelectablePins { GPIO_TUYA_RX, // Tuya Serial interface GPIO_MGC3130_XFER, // MGC3130 Transfer GPIO_MGC3130_RESET, // MGC3130 Reset - GPIO_SSPI_MISO, // Software SPI Master Input Slave Output - GPIO_SSPI_MOSI, // Software SPI Master Output Slave Input + GPIO_SSPI_MISO, // Software SPI Master Input Client Output + GPIO_SSPI_MOSI, // Software SPI Master Output Client Input GPIO_SSPI_SCLK, // Software SPI Serial Clock GPIO_SSPI_CS, // Software SPI Chip Select GPIO_SSPI_DC, // Software SPI Data or Command @@ -210,10 +210,10 @@ enum UserSelectablePins { GPIO_SM2135_DAT, // SM2135 Dat GPIO_DEEPSLEEP, // Kill switch for deepsleep GPIO_EXS_ENABLE, // EXS MCU Enable - GPIO_TASMOTASLAVE_TXD, // Slave TX - GPIO_TASMOTASLAVE_RXD, // Slave RX - GPIO_TASMOTASLAVE_RST, // Slave Reset Pin - GPIO_TASMOTASLAVE_RST_INV, // Slave Reset Inverted + GPIO_TASMOTACLIENT_TXD, // Client TX + GPIO_TASMOTACLIENT_RXD, // Client RX + GPIO_TASMOTACLIENT_RST, // Client Reset Pin + GPIO_TASMOTACLIENT_RST_INV, // Client Reset Inverted GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface GPIO_GPS_RX, // GPS serial interface @@ -317,7 +317,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" - D_SENSOR_SLAVE_TX "|" D_SENSOR_SLAVE_RX "|" D_SENSOR_SLAVE_RESET "|" D_SENSOR_SLAVE_RESET "i|" + D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "i|" D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|" D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|" D_SENSOR_DS18X20 "o|" D_SENSOR_DHT11 "o|" @@ -432,8 +432,8 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_SPI GPIO_SPI_CS, // SPI Chip Select GPIO_SPI_DC, // SPI Data Direction - GPIO_SSPI_MISO, // Software SPI Master Input Slave Output - GPIO_SSPI_MOSI, // Software SPI Master Output Slave Input + GPIO_SSPI_MISO, // Software SPI Master Input Client Output + GPIO_SSPI_MOSI, // Software SPI Master Output Client Input GPIO_SSPI_SCLK, // Software SPI Serial Clock GPIO_SSPI_CS, // Software SPI Chip Select GPIO_SSPI_DC, // Software SPI Data or Command @@ -630,11 +630,11 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_PN532_TXD, // PN532 HSU Tx GPIO_PN532_RXD, // PN532 HSU Rx #endif -#ifdef USE_TASMOTA_SLAVE - GPIO_TASMOTASLAVE_TXD, // Tasmota Slave TX - GPIO_TASMOTASLAVE_RXD, // Tasmota Slave RX - GPIO_TASMOTASLAVE_RST, // Tasmota Slave Reset - GPIO_TASMOTASLAVE_RST_INV, // Tasmota Slave Reset Inverted +#ifdef USE_TASMOTA_CLIENT + GPIO_TASMOTACLIENT_TXD, // Tasmota Client TX + GPIO_TASMOTACLIENT_RXD, // Tasmota Client RX + GPIO_TASMOTACLIENT_RST, // Tasmota Client Reset + GPIO_TASMOTACLIENT_RST_INV, // Tasmota Client Reset Inverted #endif #ifdef USE_RDM6300 GPIO_RDM6300_RX, diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index b405facfa..1eb5f02a7 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -102,8 +102,8 @@ enum UserSelectablePins { GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller GPIO_DEEPSLEEP, // Kill switch for deepsleep GPIO_EXS_ENABLE, // EXS MCU Enable - GPIO_TASMOTASLAVE_TXD, GPIO_TASMOTASLAVE_RXD, // Slave Serial interface - GPIO_TASMOTASLAVE_RST, GPIO_TASMOTASLAVE_RST_INV, // Slave Reset + GPIO_TASMOTACLIENT_TXD, GPIO_TASMOTACLIENT_RXD, // Client Serial interface + GPIO_TASMOTACLIENT_RST, GPIO_TASMOTACLIENT_RST_INV, // Client Reset GPIO_HPMA_RX, GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface GPIO_GPS_RX, GPIO_GPS_TX, // GPS Serial interface GPIO_HM10_RX, GPIO_HM10_TX, // HM10-BLE-Mijia-bridge Serial interface @@ -200,7 +200,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" - D_SENSOR_SLAVE_TX "|" D_SENSOR_SLAVE_RX "|" D_SENSOR_SLAVE_RESET "|" D_SENSOR_SLAVE_RESET "_i|" + D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "_i|" D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|" D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|" D_SENSOR_HM10_RX "|" D_SENSOR_HM10_TX "|" @@ -271,8 +271,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SPI_CLK), // SPI Clk AGPIO(GPIO_SPI_CS), // SPI Chip Select AGPIO(GPIO_SPI_DC), // SPI Data Direction - AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Slave Output - AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Slave Input + AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output + AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command @@ -473,11 +473,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx #endif -#ifdef USE_TASMOTA_SLAVE - AGPIO(GPIO_TASMOTASLAVE_TXD), // Tasmota Slave TX - AGPIO(GPIO_TASMOTASLAVE_RXD), // Tasmota Slave RX - AGPIO(GPIO_TASMOTASLAVE_RST), // Tasmota Slave Reset - AGPIO(GPIO_TASMOTASLAVE_RST_INV), // Tasmota Slave Reset Inverted +#ifdef USE_TASMOTA_CLIENT + AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX + AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX + AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset + AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted #endif #ifdef USE_RDM6300 AGPIO(GPIO_RDM6300_RX), diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index d545dfcb7..b9055e638 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -44,7 +44,7 @@ const uint16_t HTTP_OTA_RESTART_RECONNECT_TIME = 28000; // milliseconds - Allow uint8_t *efm8bb1_update = nullptr; #endif // USE_RF_FLASH -enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTASLAVE }; +enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT }; static const char * HEADER_KEYS[] = { "User-Agent", }; @@ -2651,8 +2651,8 @@ void HandleUploadDone(void) WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "

"), WebColor(COL_TEXT_SUCCESS)); WSContentSend_P(HTTP_MSG_RSTRT); ShowWebSource(SRC_WEBGUI); -#ifdef USE_TASMOTA_SLAVE - if (TasmotaSlave_GetFlagFlashing()) { +#ifdef USE_TASMOTA_CLIENT + if (TasmotaClient_GetFlagFlashing()) { restart_flag = 0; } else { // It was a normal firmware file, or we are ready to restart device restart_flag = 2; @@ -2665,9 +2665,9 @@ void HandleUploadDone(void) WSContentSend_P(PSTR("
")); WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); -#ifdef USE_TASMOTA_SLAVE - if (TasmotaSlave_GetFlagFlashing()) { - TasmotaSlave_Flash(); +#ifdef USE_TASMOTA_CLIENT + if (TasmotaClient_GetFlagFlashing()) { + TasmotaClient_Flash(); } #endif } @@ -2737,11 +2737,11 @@ void HandleUploadLoop(void) if (Web.upload_error != 0) { return; } } else #endif // USE_RF_FLASH -#ifdef USE_TASMOTA_SLAVE - if ((WEMOS == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a ARDUINO SLAVE hex file +#ifdef USE_TASMOTA_CLIENT + if ((WEMOS == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a ARDUINO CLIENT hex file Update.end(); // End esp8266 update session - Web.upload_file_type = UPL_TASMOTASLAVE; - Web.upload_error = TasmotaSlave_UpdateInit(); // 0 + Web.upload_file_type = UPL_TASMOTACLIENT; + Web.upload_error = TasmotaClient_UpdateInit(); // 0 if (Web.upload_error != 0) { return; } } else #endif @@ -2805,9 +2805,9 @@ void HandleUploadLoop(void) } } #endif // USE_RF_FLASH -#ifdef USE_TASMOTA_SLAVE - else if (UPL_TASMOTASLAVE == Web.upload_file_type) { - TasmotaSlave_WriteBuffer(upload.buf, upload.currentSize); +#ifdef USE_TASMOTA_CLIENT + else if (UPL_TASMOTACLIENT == Web.upload_file_type) { + TasmotaClient_WriteBuffer(upload.buf, upload.currentSize); } #endif else { // firmware @@ -2871,10 +2871,10 @@ void HandleUploadLoop(void) Web.upload_file_type = UPL_TASMOTA; } #endif // USE_RF_FLASH -#ifdef USE_TASMOTA_SLAVE - else if (UPL_TASMOTASLAVE == Web.upload_file_type) { +#ifdef USE_TASMOTA_CLIENT + else if (UPL_TASMOTACLIENT == Web.upload_file_type) { // Done writing the hex to SPI flash - TasmotaSlave_SetFlagFlashing(true); // So we know on upload success page if it needs to flash hex or do a normal restart + TasmotaClient_SetFlagFlashing(true); // So we know on upload success page if it needs to flash hex or do a normal restart Web.upload_file_type = UPL_TASMOTA; } #endif diff --git a/tasmota/xdrv_31_tasmota_client.ino b/tasmota/xdrv_31_tasmota_client.ino new file mode 100644 index 000000000..27e289373 --- /dev/null +++ b/tasmota/xdrv_31_tasmota_client.ino @@ -0,0 +1,585 @@ +/* + xdrv_31_tasmota_client.ino - Support for external microcontroller on serial + + Copyright (C) 2020 Andre Thomas and 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_TASMOTA_CLIENT +/*********************************************************************************************\ + * Tasmota to microcontroller +\*********************************************************************************************/ + +#define XDRV_31 31 + +#define CONST_STK_CRC_EOP 0x20 + +#define CMND_STK_GET_SYNC 0x30 +#define CMND_STK_SET_DEVICE 0x42 +#define CMND_STK_SET_DEVICE_EXT 0x45 +#define CMND_STK_ENTER_PROGMODE 0x50 +#define CMND_STK_LEAVE_PROGMODE 0x51 +#define CMND_STK_LOAD_ADDRESS 0x55 +#define CMND_STK_PROG_PAGE 0x64 + +/*************************************************\ + * Tasmota Client Specific Commands +\*************************************************/ + +#define CMND_START 0xFC +#define CMND_END 0xFD + +#define CMND_FEATURES 0x01 +#define CMND_JSON 0x02 +#define CMND_FUNC_EVERY_SECOND 0x03 +#define CMND_FUNC_EVERY_100_MSECOND 0x04 +#define CMND_CLIENT_SEND 0x05 +#define CMND_PUBLISH_TELE 0x06 +#define CMND_EXECUTE_CMND 0x07 + +#define PARAM_DATA_START 0xFE +#define PARAM_DATA_END 0xFF + +#include + +/* + * Embedding class in here since its rather specific to Arduino bootloader + */ + +class SimpleHexParse { + public: + SimpleHexParse(void); + uint8_t parseLine(char *hexline); + uint8_t ptr_l = 0; + uint8_t ptr_h = 0; + bool PageIsReady = false; + bool firstrun = true; + bool EndOfFile = false; + uint8_t FlashPage[128]; + uint8_t FlashPageIdx = 0; + uint8_t layoverBuffer[16]; + uint8_t layoverIdx = 0; + uint8_t getByte(char *hexline, uint8_t idx); +}; + +SimpleHexParse::SimpleHexParse(void) { + +} + +uint8_t SimpleHexParse::parseLine(char *hexline) { + if (layoverIdx) { + memcpy(&FlashPage[0], &layoverBuffer[0], layoverIdx); + FlashPageIdx = layoverIdx; + layoverIdx = 0; + } + uint8_t len = getByte(hexline, 1); + uint8_t addr_h = getByte(hexline, 2); + uint8_t addr_l = getByte(hexline, 3); + uint8_t rectype = getByte(hexline, 4); + for (uint8_t idx = 0; idx < len; idx++) { + if (FlashPageIdx < 128) { + FlashPage[FlashPageIdx] = getByte(hexline, idx+5); + FlashPageIdx++; + } else { // We have layover bytes + layoverBuffer[layoverIdx] = getByte(hexline, idx+5); + layoverIdx++; + } + } + if (1 == rectype) { + EndOfFile = true; + while (FlashPageIdx < 128) { + FlashPage[FlashPageIdx] = 0xFF; + FlashPageIdx++; + } + } + if (FlashPageIdx == 128) { + if (firstrun) { + firstrun = false; + } else { + ptr_l += 0x40; + if (ptr_l == 0) { + ptr_l = 0; + ptr_h++; + } + } + firstrun = false; + PageIsReady = true; + } + return 0; +} + +uint8_t SimpleHexParse::getByte(char* hexline, uint8_t idx) { + char buff[3]; + buff[3] = '\0'; + memcpy(&buff, &hexline[(idx*2)-1], 2); + return strtol(buff, 0, 16); +} + +/* + * End of embedded class SimpleHexParse + */ + +struct TCLIENT { + uint32_t spi_hex_size = 0; + uint32_t spi_sector_counter = 0; + uint8_t spi_sector_cursor = 0; + uint8_t inverted = LOW; + bool type = false; + bool flashing = false; + bool SerialEnabled = false; + uint8_t waitstate = 0; // We use this so that features detection does not slow down other stuff on startup + bool unsupported = false; +} TClient; + +typedef union { + uint32_t data; + struct { + uint32_t func_json_append : 1; // Client supports providing a JSON for TELEPERIOD + uint32_t func_every_second : 1; // Client supports receiving a FUNC_EVERY_SECOND callback with no response + uint32_t func_every_100_msecond : 1; // Client supports receiving a FUNC_EVERY_100_MSECOND callback with no response + uint32_t func_client_send : 1; // Client supports receiving commands with "client send xxx" + uint32_t spare4 : 1; + uint32_t spare5 : 1; + uint32_t spare6 : 1; + uint32_t spare7 : 1; + uint32_t spare8 : 1; + uint32_t spare9 : 1; + uint32_t spare10 : 1; + uint32_t spare11 : 1; + uint32_t spare12 : 1; + uint32_t spare13 : 1; + uint32_t spare14 : 1; + uint32_t spare15 : 1; + uint32_t spare16 : 1; + uint32_t spare17 : 1; + uint32_t spare18 : 1; + uint32_t spare19 : 1; + uint32_t spare20 : 1; + uint32_t spare21 : 1; + uint32_t spare22 : 1; + uint32_t spare23 : 1; + uint32_t spare24 : 1; + uint32_t spare25 : 1; + uint32_t spare26 : 1; + uint32_t spare27 : 1; + uint32_t spare28 : 1; + uint32_t spare29 : 1; + uint32_t spare30 : 1; + uint32_t spare31 : 1; + }; +} TClientFeatureCfg; + +/* + * The structure below must remain 4 byte aligned to be compatible with + * Tasmota as master + */ + +struct TCLIENT_FEATURES { + uint32_t features_version; + TClientFeatureCfg features; +} TClientSettings; + +struct TCLIENT_COMMAND { + uint8_t command; + uint8_t parameter; + uint8_t unused2; + uint8_t unused3; +} TClientCommand; + +TasmotaSerial *TasmotaClient_Serial; + +uint32_t TasmotaClient_FlashStart(void) { + return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side +} + +uint8_t TasmotaClient_UpdateInit(void) { + TClient.spi_hex_size = 0; + TClient.spi_sector_counter = TasmotaClient_FlashStart(); // Reset the pre-defined write address where firmware will temporarily be stored + TClient.spi_sector_cursor = 0; + return 0; +} + +void TasmotaClient_Reset(void) { + if (TClient.SerialEnabled) { + digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), !TClient.inverted); + delay(1); + digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), TClient.inverted); + delay(1); + digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), !TClient.inverted); + delay(5); + } +} + +uint8_t TasmotaClient_waitForSerialData(int dataCount, int timeout) { + int timer = 0; + while (timer < timeout) { + if (TasmotaClient_Serial->available() >= dataCount) { + return 1; + } + delay(1); + timer++; + } + return 0; +} + +uint8_t TasmotaClient_sendBytes(uint8_t* bytes, int count) { + TasmotaClient_Serial->write(bytes, count); + TasmotaClient_waitForSerialData(2, 250); + uint8_t sync = TasmotaClient_Serial->read(); + uint8_t ok = TasmotaClient_Serial->read(); + if ((sync == 0x14) && (ok == 0x10)) { + return 1; + } + return 0; +} + +uint8_t TasmotaClient_execCmd(uint8_t cmd) { + uint8_t bytes[] = { cmd, CONST_STK_CRC_EOP }; + return TasmotaClient_sendBytes(bytes, 2); +} + +uint8_t TasmotaClient_execParam(uint8_t cmd, uint8_t* params, int count) { + uint8_t bytes[32]; + bytes[0] = cmd; + int i = 0; + while (i < count) { + bytes[i + 1] = params[i]; + i++; + } + bytes[i + 1] = CONST_STK_CRC_EOP; + return TasmotaClient_sendBytes(bytes, i + 2); +} + +uint8_t TasmotaClient_exitProgMode(void) { + return TasmotaClient_execCmd(CMND_STK_LEAVE_PROGMODE); // Exit programming mode +} + +uint8_t TasmotaClient_SetupFlash(void) { + uint8_t ProgParams[] = {0x86, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00}; + uint8_t ExtProgParams[] = {0x05, 0x04, 0xd7, 0xc2, 0x00}; + TasmotaClient_Serial->begin(USE_TASMOTA_CLIENT_FLASH_SPEED); + if (TasmotaClient_Serial->hardwareSerial()) { + ClaimSerial(); + } + + TasmotaClient_Reset(); + + uint8_t timeout = 0; + uint8_t no_error = 0; + while (50 > timeout) { + if (TasmotaClient_execCmd(CMND_STK_GET_SYNC)) { + timeout = 200; + no_error = 1; + } + timeout++; + delay(1); + } + if (no_error) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Found bootloader")); + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Bootloader could not be found")); + } + if (no_error) { + if (TasmotaClient_execParam(CMND_STK_SET_DEVICE, ProgParams, sizeof(ProgParams))) { + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Could not configure device for programming (1)")); + } + } + if (no_error) { + if (TasmotaClient_execParam(CMND_STK_SET_DEVICE_EXT, ExtProgParams, sizeof(ExtProgParams))) { + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Could not configure device for programming (2)")); + } + } + if (no_error) { + if (TasmotaClient_execCmd(CMND_STK_ENTER_PROGMODE)) { + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Failed to put bootloader into programming mode")); + } + } + return no_error; +} + +uint8_t TasmotaClient_loadAddress(uint8_t adrHi, uint8_t adrLo) { + uint8_t params[] = { adrLo, adrHi }; + return TasmotaClient_execParam(CMND_STK_LOAD_ADDRESS, params, sizeof(params)); +} + +void TasmotaClient_FlashPage(uint8_t addr_h, uint8_t addr_l, uint8_t* data) { + uint8_t Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46}; + TasmotaClient_loadAddress(addr_h, addr_l); + TasmotaClient_Serial->write(Header, 4); + for (int i = 0; i < 128; i++) { + TasmotaClient_Serial->write(data[i]); + } + TasmotaClient_Serial->write(CONST_STK_CRC_EOP); + TasmotaClient_waitForSerialData(2, 250); + TasmotaClient_Serial->read(); + TasmotaClient_Serial->read(); +} + +void TasmotaClient_Flash(void) { + bool reading = true; + uint32_t read = 0; + uint32_t processed = 0; + char thishexline[50]; + uint8_t position = 0; + char* flash_buffer; + + SimpleHexParse hexParse = SimpleHexParse(); + + if (!TasmotaClient_SetupFlash()) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flashing aborted!")); + TClient.flashing = false; + restart_flag = 2; + return; + } + + flash_buffer = new char[SPI_FLASH_SEC_SIZE]; + uint32_t flash_start = TasmotaClient_FlashStart() * SPI_FLASH_SEC_SIZE; + while (reading) { + ESP.flashRead(flash_start + read, (uint32_t*)flash_buffer, SPI_FLASH_SEC_SIZE); + read = read + SPI_FLASH_SEC_SIZE; + if (read >= TClient.spi_hex_size) { + reading = false; + } + for (uint32_t ca = 0; ca < SPI_FLASH_SEC_SIZE; ca++) { + processed++; + if ((processed <= TClient.spi_hex_size) && (!hexParse.EndOfFile)) { + if (':' == flash_buffer[ca]) { + position = 0; + } + if (0x0D == flash_buffer[ca]) { + thishexline[position] = 0; + hexParse.parseLine(thishexline); + if (hexParse.PageIsReady) { + TasmotaClient_FlashPage(hexParse.ptr_h, hexParse.ptr_l, hexParse.FlashPage); + hexParse.PageIsReady = false; + hexParse.FlashPageIdx = 0; + } + } else { + if (0x0A != flash_buffer[ca]) { + thishexline[position] = flash_buffer[ca]; + position++; + } + } + } + } + } + TasmotaClient_exitProgMode(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flash done!")); + TClient.flashing = false; + restart_flag = 2; +} + +void TasmotaClient_SetFlagFlashing(bool value) { + TClient.flashing = value; +} + +bool TasmotaClient_GetFlagFlashing(void) { + return TClient.flashing; +} + +void TasmotaClient_WriteBuffer(uint8_t *buf, size_t size) { + if (0 == TClient.spi_sector_cursor) { // Starting a new sector write so we need to erase it first + ESP.flashEraseSector(TClient.spi_sector_counter); + } + TClient.spi_sector_cursor++; + ESP.flashWrite((TClient.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((TClient.spi_sector_cursor-1)*2048), (uint32_t*)buf, size); + TClient.spi_hex_size = TClient.spi_hex_size + size; + if (2 == TClient.spi_sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase + TClient.spi_sector_cursor = 0; + TClient.spi_sector_counter++; + } +} + +void TasmotaClient_Init(void) { + if (TClient.type) { + return; + } + if (10 > TClient.waitstate) { + TClient.waitstate++; + return; + } + if (!TClient.SerialEnabled) { + if (PinUsed(GPIO_TASMOTACLIENT_RXD) && PinUsed(GPIO_TASMOTACLIENT_TXD) && + (PinUsed(GPIO_TASMOTACLIENT_RST) || PinUsed(GPIO_TASMOTACLIENT_RST_INV))) { + TasmotaClient_Serial = new TasmotaSerial(Pin(GPIO_TASMOTACLIENT_RXD), Pin(GPIO_TASMOTACLIENT_TXD), 1, 0, 200); + if (TasmotaClient_Serial->begin(USE_TASMOTA_CLIENT_SERIAL_SPEED)) { + if (TasmotaClient_Serial->hardwareSerial()) { + ClaimSerial(); + } + TasmotaClient_Serial->setTimeout(100); // Theo 20200502 - increase from 50 + if (PinUsed(GPIO_TASMOTACLIENT_RST_INV)) { + SetPin(Pin(GPIO_TASMOTACLIENT_RST_INV), GPIO_TASMOTACLIENT_RST); + TClient.inverted = HIGH; + } + pinMode(Pin(GPIO_TASMOTACLIENT_RST), OUTPUT); + TClient.SerialEnabled = true; + TasmotaClient_Reset(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Enabled")); + } + } + } + if (TClient.SerialEnabled) { // All go for hardware now we need to detect features if there are any + TasmotaClient_sendCmnd(CMND_FEATURES, 0); + char buffer[32] = { 0 }; + TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)); + uint8_t len = TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)); + + if (len) { AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)buffer, len); } // Theo 20200502 - DMP: 99 17 34 01 02 00 00 00 + + memcpy(&TClientSettings, &buffer, sizeof(TClientSettings)); + if (20191129 == TClientSettings.features_version) { + TClient.type = true; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Version %u"), TClientSettings.features_version); + } else { + if ((!TClient.unsupported) && (TClientSettings.features_version > 0)) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Version %u not supported!"), TClientSettings.features_version); + TClient.unsupported = true; + } + } + } +} + +void TasmotaClient_Show(void) { + if ((TClient.type) && (TClientSettings.features.func_json_append)) { + char buffer[100]; + TasmotaClient_sendCmnd(CMND_JSON, 0); + TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)-1); + uint8_t len = TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)-1); + buffer[len] = '\0'; + ResponseAppend_P(PSTR(",\"TasmotaClient\":%s"), buffer); + } +} + +void TasmotaClient_sendCmnd(uint8_t cmnd, uint8_t param) { + TClientCommand.command = cmnd; + TClientCommand.parameter = param; + char buffer[sizeof(TClientCommand)+2]; + buffer[0] = CMND_START; + memcpy(&buffer[1], &TClientCommand, sizeof(TClientCommand)); + buffer[sizeof(TClientCommand)+1] = CMND_END; + + TasmotaClient_Serial->flush(); // Theo 20200502 + + for (uint8_t ca = 0; ca < sizeof(buffer); ca++) { + TasmotaClient_Serial->write(buffer[ca]); + } +} + +#define D_PRFX_CLIENT "Client" +#define D_CMND_CLIENT_RESET "Reset" +#define D_CMND_CLIENT_SEND "Send" + +const char kTasmotaClientCommands[] PROGMEM = D_PRFX_CLIENT "|" + D_CMND_CLIENT_RESET "|" D_CMND_CLIENT_SEND; + +void (* const TasmotaClientCommand[])(void) PROGMEM = { + &CmndClientReset, &CmndClientSend }; + +void CmndClientReset(void) { + TasmotaClient_Reset(); + TClient.type = false; // Force redetection + TClient.waitstate = 7; // give it at least 3 seconds to restart from bootloader + TClient.unsupported = false; // Reset unsupported flag + ResponseCmndDone(); +} + +void CmndClientSend(void) { + if (0 < XdrvMailbox.data_len) { + TasmotaClient_sendCmnd(CMND_CLIENT_SEND, XdrvMailbox.data_len); + TasmotaClient_Serial->write(char(PARAM_DATA_START)); + for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) { + TasmotaClient_Serial->write(XdrvMailbox.data[idx]); + } + TasmotaClient_Serial->write(char(PARAM_DATA_END)); + } + ResponseCmndDone(); +} + +void TasmotaClient_ProcessIn(void) { + uint8_t cmnd = TasmotaClient_Serial->read(); + if (CMND_START == cmnd) { + TasmotaClient_waitForSerialData(sizeof(TClientCommand),50); + uint8_t buffer[sizeof(TClientCommand)]; + for (uint8_t idx = 0; idx < sizeof(TClientCommand); idx++) { + buffer[idx] = TasmotaClient_Serial->read(); + } + TasmotaClient_Serial->read(); // read trailing byte of command + memcpy(&TClientCommand, &buffer, sizeof(TClientCommand)); + char inbuf[TClientCommand.parameter+1]; + TasmotaClient_waitForSerialData(TClientCommand.parameter, 50); + TasmotaClient_Serial->read(); // Read leading byte + for (uint8_t idx = 0; idx < TClientCommand.parameter; idx++) { + inbuf[idx] = TasmotaClient_Serial->read(); + } + TasmotaClient_Serial->read(); // Read trailing byte + inbuf[TClientCommand.parameter] = '\0'; + + if (CMND_PUBLISH_TELE == TClientCommand.command) { // We need to publish stat/ with incoming stream as content + Response_P(PSTR("{\"TasmotaClient\":")); + ResponseAppend_P("%s", inbuf); + ResponseJsonEnd(); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); + XdrvRulesProcess(); + } + if (CMND_EXECUTE_CMND == TClientCommand.command) { // We need to execute the incoming command + ExecuteCommand(inbuf, SRC_IGNORE); + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv31(uint8_t function) { + bool result = false; + + switch (function) { + case FUNC_EVERY_100_MSECOND: + if (TClient.type) { + if (TasmotaClient_Serial->available()) { + TasmotaClient_ProcessIn(); + } + if (TClientSettings.features.func_every_100_msecond) { + TasmotaClient_sendCmnd(CMND_FUNC_EVERY_100_MSECOND, 0); + } + } + break; + case FUNC_EVERY_SECOND: + if ((TClient.type) && (TClientSettings.features.func_every_second)) { + TasmotaClient_sendCmnd(CMND_FUNC_EVERY_SECOND, 0); + } + TasmotaClient_Init(); + break; + case FUNC_JSON_APPEND: + if ((TClient.type) && (TClientSettings.features.func_json_append)) { + TasmotaClient_Show(); + } + break; + case FUNC_COMMAND: + result = DecodeCommand(kTasmotaClientCommands, TasmotaClientCommand); + break; + } + return result; +} + +#endif // USE_TASMOTA_CLIENT diff --git a/tasmota/xdrv_31_tasmota_slave.ino b/tasmota/xdrv_31_tasmota_slave.ino deleted file mode 100644 index 38306a791..000000000 --- a/tasmota/xdrv_31_tasmota_slave.ino +++ /dev/null @@ -1,615 +0,0 @@ -/* - xdrv_31_tasmota_slave.ino - Support for external microcontroller slave on serial - - Copyright (C) 2020 Andre Thomas and 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_TASMOTA_SLAVE -/*********************************************************************************************\ - * Tasmota slave -\*********************************************************************************************/ - -#define XDRV_31 31 - -#define CONST_STK_CRC_EOP 0x20 - -#define CMND_STK_GET_SYNC 0x30 -#define CMND_STK_SET_DEVICE 0x42 -#define CMND_STK_SET_DEVICE_EXT 0x45 -#define CMND_STK_ENTER_PROGMODE 0x50 -#define CMND_STK_LEAVE_PROGMODE 0x51 -#define CMND_STK_LOAD_ADDRESS 0x55 -#define CMND_STK_PROG_PAGE 0x64 - -/*************************************************\ - * Tasmota Slave Specific Commands -\*************************************************/ - -#define CMND_START 0xFC -#define CMND_END 0xFD - -#define CMND_FEATURES 0x01 -#define CMND_JSON 0x02 -#define CMND_FUNC_EVERY_SECOND 0x03 -#define CMND_FUNC_EVERY_100_MSECOND 0x04 -#define CMND_SLAVE_SEND 0x05 -#define CMND_PUBLISH_TELE 0x06 -#define CMND_EXECUTE_CMND 0x07 - -#define PARAM_DATA_START 0xFE -#define PARAM_DATA_END 0xFF - -#include - -/* - * Embedding class in here since its rather specific to Arduino bootloader - */ - -class SimpleHexParse { - public: - SimpleHexParse(void); - uint8_t parseLine(char *hexline); - uint8_t ptr_l = 0; - uint8_t ptr_h = 0; - bool PageIsReady = false; - bool firstrun = true; - bool EndOfFile = false; - uint8_t FlashPage[128]; - uint8_t FlashPageIdx = 0; - uint8_t layoverBuffer[16]; - uint8_t layoverIdx = 0; - uint8_t getByte(char *hexline, uint8_t idx); -}; - -SimpleHexParse::SimpleHexParse(void) -{ - -} - -uint8_t SimpleHexParse::parseLine(char *hexline) -{ - if (layoverIdx) { - memcpy(&FlashPage[0], &layoverBuffer[0], layoverIdx); - FlashPageIdx = layoverIdx; - layoverIdx = 0; - } - uint8_t len = getByte(hexline, 1); - uint8_t addr_h = getByte(hexline, 2); - uint8_t addr_l = getByte(hexline, 3); - uint8_t rectype = getByte(hexline, 4); - for (uint8_t idx = 0; idx < len; idx++) { - if (FlashPageIdx < 128) { - FlashPage[FlashPageIdx] = getByte(hexline, idx+5); - FlashPageIdx++; - } else { // We have layover bytes - layoverBuffer[layoverIdx] = getByte(hexline, idx+5); - layoverIdx++; - } - } - if (1 == rectype) { - EndOfFile = true; - while (FlashPageIdx < 128) { - FlashPage[FlashPageIdx] = 0xFF; - FlashPageIdx++; - } - } - if (FlashPageIdx == 128) { - if (firstrun) { - firstrun = false; - } else { - ptr_l += 0x40; - if (ptr_l == 0) { - ptr_l = 0; - ptr_h++; - } - } - firstrun = false; - PageIsReady = true; - } - return 0; -} - -uint8_t SimpleHexParse::getByte(char* hexline, uint8_t idx) -{ - char buff[3]; - buff[3] = '\0'; - memcpy(&buff, &hexline[(idx*2)-1], 2); - return strtol(buff, 0, 16); -} - -/* - * End of embedded class SimpleHexParse - */ - -struct TSLAVE { - uint32_t spi_hex_size = 0; - uint32_t spi_sector_counter = 0; - uint8_t spi_sector_cursor = 0; - uint8_t inverted = LOW; - bool type = false; - bool flashing = false; - bool SerialEnabled = false; - uint8_t waitstate = 0; // We use this so that features detection does not slow down other stuff on startup - bool unsupported = false; -} TSlave; - -typedef union { - uint32_t data; - struct { - uint32_t func_json_append : 1; // Slave supports providing a JSON for TELEPERIOD - uint32_t func_every_second : 1; // Slave supports receiving a FUNC_EVERY_SECOND callback with no response - uint32_t func_every_100_msecond : 1; // Slave supports receiving a FUNC_EVERY_100_MSECOND callback with no response - uint32_t func_slave_send : 1; // Slave supports receiving commands with "slave send xxx" - uint32_t spare4 : 1; - uint32_t spare5 : 1; - uint32_t spare6 : 1; - uint32_t spare7 : 1; - uint32_t spare8 : 1; - uint32_t spare9 : 1; - uint32_t spare10 : 1; - uint32_t spare11 : 1; - uint32_t spare12 : 1; - uint32_t spare13 : 1; - uint32_t spare14 : 1; - uint32_t spare15 : 1; - uint32_t spare16 : 1; - uint32_t spare17 : 1; - uint32_t spare18 : 1; - uint32_t spare19 : 1; - uint32_t spare20 : 1; - uint32_t spare21 : 1; - uint32_t spare22 : 1; - uint32_t spare23 : 1; - uint32_t spare24 : 1; - uint32_t spare25 : 1; - uint32_t spare26 : 1; - uint32_t spare27 : 1; - uint32_t spare28 : 1; - uint32_t spare29 : 1; - uint32_t spare30 : 1; - uint32_t spare31 : 1; - }; -} TSlaveFeatureCfg; - -/* - * The structure below must remain 4 byte aligned to be compatible with - * Tasmota as master - */ - -struct TSLAVE_FEATURES { - uint32_t features_version; - TSlaveFeatureCfg features; -} TSlaveSettings; - -struct TSLAVE_COMMAND { - uint8_t command; - uint8_t parameter; - uint8_t unused2; - uint8_t unused3; -} TSlaveCommand; - -TasmotaSerial *TasmotaSlave_Serial; - -uint32_t TasmotaSlave_FlashStart(void) -{ - return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side -} - -uint8_t TasmotaSlave_UpdateInit(void) -{ - TSlave.spi_hex_size = 0; - TSlave.spi_sector_counter = TasmotaSlave_FlashStart(); // Reset the pre-defined write address where firmware will temporarily be stored - TSlave.spi_sector_cursor = 0; - return 0; -} - -void TasmotaSlave_Reset(void) -{ - if (TSlave.SerialEnabled) { - digitalWrite(Pin(GPIO_TASMOTASLAVE_RST), !TSlave.inverted); - delay(1); - digitalWrite(Pin(GPIO_TASMOTASLAVE_RST), TSlave.inverted); - delay(1); - digitalWrite(Pin(GPIO_TASMOTASLAVE_RST), !TSlave.inverted); - delay(5); - } -} - -uint8_t TasmotaSlave_waitForSerialData(int dataCount, int timeout) -{ - int timer = 0; - while (timer < timeout) { - if (TasmotaSlave_Serial->available() >= dataCount) { - return 1; - } - delay(1); - timer++; - } - return 0; -} - -uint8_t TasmotaSlave_sendBytes(uint8_t* bytes, int count) -{ - TasmotaSlave_Serial->write(bytes, count); - TasmotaSlave_waitForSerialData(2, 250); - uint8_t sync = TasmotaSlave_Serial->read(); - uint8_t ok = TasmotaSlave_Serial->read(); - if ((sync == 0x14) && (ok == 0x10)) { - return 1; - } - return 0; -} - -uint8_t TasmotaSlave_execCmd(uint8_t cmd) -{ - uint8_t bytes[] = { cmd, CONST_STK_CRC_EOP }; - return TasmotaSlave_sendBytes(bytes, 2); -} - -uint8_t TasmotaSlave_execParam(uint8_t cmd, uint8_t* params, int count) -{ - uint8_t bytes[32]; - bytes[0] = cmd; - int i = 0; - while (i < count) { - bytes[i + 1] = params[i]; - i++; - } - bytes[i + 1] = CONST_STK_CRC_EOP; - return TasmotaSlave_sendBytes(bytes, i + 2); -} - -uint8_t TasmotaSlave_exitProgMode(void) -{ - return TasmotaSlave_execCmd(CMND_STK_LEAVE_PROGMODE); // Exit programming mode -} - -uint8_t TasmotaSlave_SetupFlash(void) -{ - uint8_t ProgParams[] = {0x86, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00}; - uint8_t ExtProgParams[] = {0x05, 0x04, 0xd7, 0xc2, 0x00}; - TasmotaSlave_Serial->begin(USE_TASMOTA_SLAVE_FLASH_SPEED); - if (TasmotaSlave_Serial->hardwareSerial()) { - ClaimSerial(); - } - - TasmotaSlave_Reset(); - - uint8_t timeout = 0; - uint8_t no_error = 0; - while (50 > timeout) { - if (TasmotaSlave_execCmd(CMND_STK_GET_SYNC)) { - timeout = 200; - no_error = 1; - } - timeout++; - delay(1); - } - if (no_error) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Found bootloader")); - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Bootloader could not be found")); - } - if (no_error) { - if (TasmotaSlave_execParam(CMND_STK_SET_DEVICE, ProgParams, sizeof(ProgParams))) { - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Could not configure device for programming (1)")); - } - } - if (no_error) { - if (TasmotaSlave_execParam(CMND_STK_SET_DEVICE_EXT, ExtProgParams, sizeof(ExtProgParams))) { - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Could not configure device for programming (2)")); - } - } - if (no_error) { - if (TasmotaSlave_execCmd(CMND_STK_ENTER_PROGMODE)) { - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Failed to put bootloader into programming mode")); - } - } - return no_error; -} - -uint8_t TasmotaSlave_loadAddress(uint8_t adrHi, uint8_t adrLo) -{ - uint8_t params[] = { adrLo, adrHi }; - return TasmotaSlave_execParam(CMND_STK_LOAD_ADDRESS, params, sizeof(params)); -} - -void TasmotaSlave_FlashPage(uint8_t addr_h, uint8_t addr_l, uint8_t* data) -{ - uint8_t Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46}; - TasmotaSlave_loadAddress(addr_h, addr_l); - TasmotaSlave_Serial->write(Header, 4); - for (int i = 0; i < 128; i++) { - TasmotaSlave_Serial->write(data[i]); - } - TasmotaSlave_Serial->write(CONST_STK_CRC_EOP); - TasmotaSlave_waitForSerialData(2, 250); - TasmotaSlave_Serial->read(); - TasmotaSlave_Serial->read(); -} - -void TasmotaSlave_Flash(void) -{ - bool reading = true; - uint32_t read = 0; - uint32_t processed = 0; - char thishexline[50]; - uint8_t position = 0; - char* flash_buffer; - - SimpleHexParse hexParse = SimpleHexParse(); - - if (!TasmotaSlave_SetupFlash()) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Flashing aborted!")); - TSlave.flashing = false; - restart_flag = 2; - return; - } - - flash_buffer = new char[SPI_FLASH_SEC_SIZE]; - uint32_t flash_start = TasmotaSlave_FlashStart() * SPI_FLASH_SEC_SIZE; - while (reading) { - ESP.flashRead(flash_start + read, (uint32_t*)flash_buffer, SPI_FLASH_SEC_SIZE); - read = read + SPI_FLASH_SEC_SIZE; - if (read >= TSlave.spi_hex_size) { - reading = false; - } - for (uint32_t ca = 0; ca < SPI_FLASH_SEC_SIZE; ca++) { - processed++; - if ((processed <= TSlave.spi_hex_size) && (!hexParse.EndOfFile)) { - if (':' == flash_buffer[ca]) { - position = 0; - } - if (0x0D == flash_buffer[ca]) { - thishexline[position] = 0; - hexParse.parseLine(thishexline); - if (hexParse.PageIsReady) { - TasmotaSlave_FlashPage(hexParse.ptr_h, hexParse.ptr_l, hexParse.FlashPage); - hexParse.PageIsReady = false; - hexParse.FlashPageIdx = 0; - } - } else { - if (0x0A != flash_buffer[ca]) { - thishexline[position] = flash_buffer[ca]; - position++; - } - } - } - } - } - TasmotaSlave_exitProgMode(); - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Flash done!")); - TSlave.flashing = false; - restart_flag = 2; -} - -void TasmotaSlave_SetFlagFlashing(bool value) -{ - TSlave.flashing = value; -} - -bool TasmotaSlave_GetFlagFlashing(void) -{ - return TSlave.flashing; -} - -void TasmotaSlave_WriteBuffer(uint8_t *buf, size_t size) -{ - if (0 == TSlave.spi_sector_cursor) { // Starting a new sector write so we need to erase it first - ESP.flashEraseSector(TSlave.spi_sector_counter); - } - TSlave.spi_sector_cursor++; - ESP.flashWrite((TSlave.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((TSlave.spi_sector_cursor-1)*2048), (uint32_t*)buf, size); - TSlave.spi_hex_size = TSlave.spi_hex_size + size; - if (2 == TSlave.spi_sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase - TSlave.spi_sector_cursor = 0; - TSlave.spi_sector_counter++; - } -} - -void TasmotaSlave_Init(void) -{ - if (TSlave.type) { - return; - } - if (10 > TSlave.waitstate) { - TSlave.waitstate++; - return; - } - if (!TSlave.SerialEnabled) { - if (PinUsed(GPIO_TASMOTASLAVE_RXD) && PinUsed(GPIO_TASMOTASLAVE_TXD) && - (PinUsed(GPIO_TASMOTASLAVE_RST) || PinUsed(GPIO_TASMOTASLAVE_RST_INV))) { - TasmotaSlave_Serial = new TasmotaSerial(Pin(GPIO_TASMOTASLAVE_RXD), Pin(GPIO_TASMOTASLAVE_TXD), 1, 0, 200); - if (TasmotaSlave_Serial->begin(USE_TASMOTA_SLAVE_SERIAL_SPEED)) { - if (TasmotaSlave_Serial->hardwareSerial()) { - ClaimSerial(); - } - TasmotaSlave_Serial->setTimeout(100); // Theo 20200502 - increase from 50 - if (PinUsed(GPIO_TASMOTASLAVE_RST_INV)) { - SetPin(Pin(GPIO_TASMOTASLAVE_RST_INV), GPIO_TASMOTASLAVE_RST); - TSlave.inverted = HIGH; - } - pinMode(Pin(GPIO_TASMOTASLAVE_RST), OUTPUT); - TSlave.SerialEnabled = true; - TasmotaSlave_Reset(); - AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Enabled")); - } - } - } - if (TSlave.SerialEnabled) { // All go for hardware now we need to detect features if there are any - TasmotaSlave_sendCmnd(CMND_FEATURES, 0); - char buffer[32] = { 0 }; - TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)); - uint8_t len = TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)); - - if (len) { AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)buffer, len); } // Theo 20200502 - DMP: 99 17 34 01 02 00 00 00 - - memcpy(&TSlaveSettings, &buffer, sizeof(TSlaveSettings)); - if (20191129 == TSlaveSettings.features_version) { - TSlave.type = true; - AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Version %u"), TSlaveSettings.features_version); - } else { - if ((!TSlave.unsupported) && (TSlaveSettings.features_version > 0)) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Version %u not supported!"), TSlaveSettings.features_version); - TSlave.unsupported = true; - } - } - } -} - -void TasmotaSlave_Show(void) -{ - if ((TSlave.type) && (TSlaveSettings.features.func_json_append)) { - char buffer[100]; - TasmotaSlave_sendCmnd(CMND_JSON, 0); - TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)-1); - uint8_t len = TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)-1); - buffer[len] = '\0'; - ResponseAppend_P(PSTR(",\"TasmotaSlave\":%s"), buffer); - } -} - -void TasmotaSlave_sendCmnd(uint8_t cmnd, uint8_t param) -{ - TSlaveCommand.command = cmnd; - TSlaveCommand.parameter = param; - char buffer[sizeof(TSlaveCommand)+2]; - buffer[0] = CMND_START; - memcpy(&buffer[1], &TSlaveCommand, sizeof(TSlaveCommand)); - buffer[sizeof(TSlaveCommand)+1] = CMND_END; - - TasmotaSlave_Serial->flush(); // Theo 20200502 - - for (uint8_t ca = 0; ca < sizeof(buffer); ca++) { - TasmotaSlave_Serial->write(buffer[ca]); - } -} - -#define D_PRFX_SLAVE "Slave" -#define D_CMND_SLAVE_RESET "Reset" -#define D_CMND_SLAVE_SEND "Send" - -const char kTasmotaSlaveCommands[] PROGMEM = D_PRFX_SLAVE "|" - D_CMND_SLAVE_RESET "|" D_CMND_SLAVE_SEND; - -void (* const TasmotaSlaveCommand[])(void) PROGMEM = { - &CmndTasmotaSlaveReset, &CmndTasmotaSlaveSend }; - -void CmndTasmotaSlaveReset(void) -{ - TasmotaSlave_Reset(); - TSlave.type = false; // Force redetection - TSlave.waitstate = 7; // give it at least 3 seconds to restart from bootloader - TSlave.unsupported = false; // Reset unsupported flag - ResponseCmndDone(); -} - -void CmndTasmotaSlaveSend(void) -{ - if (0 < XdrvMailbox.data_len) { - TasmotaSlave_sendCmnd(CMND_SLAVE_SEND, XdrvMailbox.data_len); - TasmotaSlave_Serial->write(char(PARAM_DATA_START)); - for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) { - TasmotaSlave_Serial->write(XdrvMailbox.data[idx]); - } - TasmotaSlave_Serial->write(char(PARAM_DATA_END)); - } - ResponseCmndDone(); -} - -void TasmotaSlave_ProcessIn(void) -{ - uint8_t cmnd = TasmotaSlave_Serial->read(); - switch (cmnd) { - case CMND_START: - TasmotaSlave_waitForSerialData(sizeof(TSlaveCommand),50); - uint8_t buffer[sizeof(TSlaveCommand)]; - for (uint8_t idx = 0; idx < sizeof(TSlaveCommand); idx++) { - buffer[idx] = TasmotaSlave_Serial->read(); - } - TasmotaSlave_Serial->read(); // read trailing byte of command - memcpy(&TSlaveCommand, &buffer, sizeof(TSlaveCommand)); - char inbuf[TSlaveCommand.parameter+1]; - TasmotaSlave_waitForSerialData(TSlaveCommand.parameter, 50); - TasmotaSlave_Serial->read(); // Read leading byte - for (uint8_t idx = 0; idx < TSlaveCommand.parameter; idx++) { - inbuf[idx] = TasmotaSlave_Serial->read(); - } - TasmotaSlave_Serial->read(); // Read trailing byte - inbuf[TSlaveCommand.parameter] = '\0'; - - if (CMND_PUBLISH_TELE == TSlaveCommand.command) { // We need to publish stat/ with incoming stream as content - Response_P(PSTR("{\"TasmotaSlave\":")); - ResponseAppend_P("%s", inbuf); - ResponseJsonEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); - XdrvRulesProcess(); - } - if (CMND_EXECUTE_CMND == TSlaveCommand.command) { // We need to execute the incoming command - ExecuteCommand(inbuf, SRC_IGNORE); - } - break; - default: - break; - } -} - - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xdrv31(uint8_t function) -{ - bool result = false; - - switch (function) { - case FUNC_EVERY_100_MSECOND: - if (TSlave.type) { - if (TasmotaSlave_Serial->available()) { - TasmotaSlave_ProcessIn(); - } - if (TSlaveSettings.features.func_every_100_msecond) { - TasmotaSlave_sendCmnd(CMND_FUNC_EVERY_100_MSECOND, 0); - } - } - break; - case FUNC_EVERY_SECOND: - if ((TSlave.type) && (TSlaveSettings.features.func_every_second)) { - TasmotaSlave_sendCmnd(CMND_FUNC_EVERY_SECOND, 0); - } - TasmotaSlave_Init(); - break; - case FUNC_JSON_APPEND: - if ((TSlave.type) && (TSlaveSettings.features.func_json_append)) { - TasmotaSlave_Show(); - } - break; - case FUNC_COMMAND: - result = DecodeCommand(kTasmotaSlaveCommands, TasmotaSlaveCommand); - break; - } - return result; -} - -#endif // USE_TASMOTA_SLAVE diff --git a/tasmota/xnrg_13_fif_le01mr.ino b/tasmota/xnrg_13_fif_le01mr.ino index 71e77793a..f8d25e06f 100644 --- a/tasmota/xnrg_13_fif_le01mr.ino +++ b/tasmota/xnrg_13_fif_le01mr.ino @@ -127,15 +127,15 @@ void FifLEEvery250ms(void) } else { Energy.data_valid[0] = 0; - // SA=Slave Address, FC=Function Code, BC=Byte Count, B3..B0=Data byte, Ch Cl = crc16 checksum + // CA=Client Address, FC=Function Code, BC=Byte Count, B3..B0=Data byte, Ch Cl = crc16 checksum // U32 registers: // 00 01 02 03 04 05 06 07 08 - // SA FC BC B3 B2 B1 B0 Cl Ch + // CA FC BC B3 B2 B1 B0 Cl Ch // 01 03 04 00 00 00 72 7A 16 = REG[B3..B2=0x0139,B1..B0=0x013A] 114 = 0.114 A // 01 03 04 00 00 00 B0 FB 87 = REG[B3..B2=0xA01E,B1..B0=0xA01F] 176 = 1.76 kvarh // U16/S16 registers: // 00 01 02 03 04 05 06 - // SA FC BC B1 B0 Cl Ch + // CA FC BC B1 B0 Cl Ch // 01 03 02 5B 02 02 B5 = REG[B1..B0=0x0131] 23298 = 232.98 V // 01 03 02 03 E8 B8 FA = REG[B1..B0=0x0158] 1000 = 1.000 (power factor) // there are 3 data types used: From 0c48aa3de3273cc5bae00efed39c74e172073996 Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 18 Jun 2020 16:10:48 +0200 Subject: [PATCH 276/581] Used ISOUSC for power contract --- tasmota/xnrg_15_teleinfo.ino | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index 67fd0f158..316e567e8 100755 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -247,6 +247,13 @@ void DataCallback(struct _ValueList * me, uint8_t flags) AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Contract changed, now '%s' (%d)"), me->value, contrat); } + // Contract subscribed (Power) + else if (ilabel == LABEL_ISOUSC) + { + isousc = atoi( me->value); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: ISousc set to %d"), isousc); + } + } if (flags & TINFO_FLAGS_ADDED) { c = '#'; } @@ -388,6 +395,7 @@ const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_ const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "{m}%d " D_UNIT_AMPERE "{e}" ; const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}Tarif en cours{m}Heures %s{e}" ; const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}Contrat{m}%s %d" D_UNIT_AMPERE "{e}" ; +const char HTTP_ENERGY_LOAD_TELEINFO[] PROGMEM = "{s}Charge actuelle{m}%d" D_UNIT_PERCENT "{e}" ; #endif // USE_WEBSERVER void TInfoShow(bool json) @@ -403,10 +411,10 @@ void TInfoShow(bool json) if ( getValueFromLabelIndex(LABEL_PTEC, value) ) { ResponseAppend_P(PSTR(",\"" "TARIF" "\":\"%s\""), value); } - if ( getValueFromLabelIndex(LABEL_ISOUSC, value) ) { - GetTextIndexed(name, sizeof(name), LABEL_ISOUSC, kLabel); - ResponseAppend_P(PSTR(",\"%s\":%d"), name, atoi(value)); - } + + GetTextIndexed(name, sizeof(name), LABEL_ISOUSC, kLabel); + ResponseAppend_P(PSTR(",\"%s\":%d"), name, isousc); + if ( getValueFromLabelIndex(LABEL_HCHC, value) ) { GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel); ResponseAppend_P(PSTR(",\"%s\":\"%u\""), name, atoi(value)); @@ -433,8 +441,10 @@ void TInfoShow(bool json) } if (contrat) { GetTextIndexed(name, sizeof(name), contrat, kContratName); - if (getValueFromLabelIndex(LABEL_ISOUSC, value) ) { - WSContentSend_PD(HTTP_ENERGY_CONTRAT_TELEINFO, name, atoi(value)); + WSContentSend_PD(HTTP_ENERGY_CONTRAT_TELEINFO, name, isousc); + if (isousc) { + int percent = (int) ((Energy.current[0]*100.0f) / isousc) ; + WSContentSend_PD(HTTP_ENERGY_LOAD_TELEINFO, percent); } } #endif // USE_WEBSERVER From c9c98a8ce3e765a7fcdf3d5d5de666189e64bfe0 Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 18 Jun 2020 17:12:23 +0200 Subject: [PATCH 277/581] Added Load on Telemetry --- tasmota/xnrg_15_teleinfo.ino | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index 316e567e8..a57020967 100755 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -423,6 +423,11 @@ void TInfoShow(bool json) GetTextIndexed(name, sizeof(name), LABEL_HCHP, kLabel); ResponseAppend_P(PSTR(",\"%s\":\"%u\""),name , atoi(value)); } + + if (isousc) { + ResponseAppend_P(PSTR(",\"Load\":\"%d\""),(int) ((Energy.current[0]*100.0f) / isousc)); + } + #ifdef USE_WEBSERVER } else From da87918d51a8013323ef58cd3881de48fbdac18c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 18 Jun 2020 17:47:29 +0200 Subject: [PATCH 278/581] Fix ESP32 ethernet hostname --- tasmota/tasmota_template_ESP32.h | 4 ---- tasmota/xdrv_81_webcam.ino | 2 +- tasmota/xdrv_82_ethernet.ino | 15 ++++++++------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 1eb5f02a7..80a015675 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -684,10 +684,6 @@ const mytmplt kModules PROGMEM = /*********************************************************************************************\ Known templates -{"NAME":"AITHINKER CAM","GPIO":[4992,65504,65504,65504,65504,5088,65504,65504,65504,65504,65504,65504,65504,65504,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,65504,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} -{"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} -{"NAME":"wESP32","GPIO":[65504,65504,65504,65504,65504,65504,0,0,0,65504,65504,65504,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} - {"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} {"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} diff --git a/tasmota/xdrv_81_webcam.ino b/tasmota/xdrv_81_webcam.ino index 71d81d2ac..b0dab47b7 100644 --- a/tasmota/xdrv_81_webcam.ino +++ b/tasmota/xdrv_81_webcam.ino @@ -23,7 +23,7 @@ * ESP32 webcam based on example in Arduino-ESP32 library * * Template as used on ESP32-CAM WiFi + bluetooth Camera Module Development Board ESP32 With Camera Module OV2640 Geekcreit for Arduino - * {"NAME":"AITHINKER CAM No SPI","GPIO":[4992,65504,65504,65504,65504,5088,65504,65504,65504,65504,65504,65504,65504,65504,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,65504,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} + * {"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} * * Supported commands: * WcStream = Control streaming, 0 = stop, 1 = start diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index 034c72636..cccac57b7 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -60,22 +60,20 @@ #include -struct { - char hostname[33]; -} Eth; +char eth_hostname[sizeof(my_hostname)]; void EthernetEvent(WiFiEvent_t event) { switch (event) { case SYSTEM_EVENT_ETH_START: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: " D_ATTEMPTING_CONNECTION)); - ETH.setHostname(Eth.hostname); + ETH.setHostname(eth_hostname); break; case SYSTEM_EVENT_ETH_CONNECTED: AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED)); break; case SYSTEM_EVENT_ETH_GOT_IP: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %s, Hostname %s"), - ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), Eth.hostname); + ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), eth_hostname); /* if (ETH.fullDuplex()) { Serial.print(", FULL_DUPLEX"); @@ -109,7 +107,10 @@ void EthernetInit(void) { return; } - snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), my_hostname); +// snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), my_hostname); + strlcpy(eth_hostname, my_hostname, sizeof(eth_hostname) -5); // Make sure there is room for "_eth" + strcat(eth_hostname, "_eth"); + WiFi.onEvent(EthernetEvent); int eth_power = (PinUsed(GPIO_ETH_PHY_POWER)) ? Pin(GPIO_ETH_PHY_POWER) : -1; @@ -125,7 +126,7 @@ IPAddress EthernetLocalIP(void) { } char* EthernetHostname(void) { - return Eth.hostname; + return eth_hostname; } String EthernetMacAddress(void) { From b71a5ae9e4ab343f992ce17db6e590775b227c86 Mon Sep 17 00:00:00 2001 From: Staars Date: Thu, 18 Jun 2020 17:57:16 +0200 Subject: [PATCH 279/581] add decryption to xsns_61_MI_NRF24.ino --- tasmota/xsns_61_MI_NRF24.ino | 165 +++++++++++++++++++++++++++++------ 1 file changed, 139 insertions(+), 26 deletions(-) diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index 5dd82f3a5..4fb261751 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -21,6 +21,8 @@ Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.6.0 20200618 integrate - add decryption for LYWSD03 + --- 0.9.5.0 20200328 integrate - add dew point, multi-page-web ui, refactoring, command interface, simple beacon --- @@ -62,6 +64,7 @@ #define XSNS_61 61 #include +#include #define FLORA 1 #define MJ_HT_V1 2 @@ -74,14 +77,15 @@ const char S_JSON_NRF_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_NRF "%s\":%d}"; const char S_JSON_NRF_COMMAND[] PROGMEM = "{\"" D_CMND_NRF "%s\":\"%s\"}"; -const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan"; +const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan|Key"; enum NRF_Commands { // commands useable in console or rules CMND_NRF_IGNORE, // ignore specific sensor type (1-6) CMND_NRF_PAGE, // sensor entries per web page, which will be shown alternated CMND_NRF_SCAN, // simplified passive BLE adv scan CMND_NRF_BEACON, // even more simplified Beacon, reports time since last sighting - CMND_NRF_CHAN // ignore channel 0-2 (translates to 37-39) + CMND_NRF_CHAN, // ignore channel 0-2 (translates to 37-39) + CMND_NRF_KEY // add bind_key to a MAC for payload decryption }; const uint16_t kMINRFSlaveID[6]={ 0x0098, // Flora @@ -104,8 +108,8 @@ const char * kMINRFSlaveType[] PROGMEM = {kMINRFSlaveType1,kMINRFSlaveType2,kMIN const uint32_t kMINRFFloPDU[3] = {0x3eaa857d,0xef3b8730,0x71da7b46}; const uint32_t kMINRFMJPDU[3] = {0x4760cd66,0xdbcc0cd3,0x33048df5}; const uint32_t kMINRFL2PDU[3] = {0x3eaa057d,0xef3b0730,0x71dafb46}; -// const uint32_t kMINRFL3PDU[3] = {0x4760dd78,0xdbcc1ccd,0xffffffff}; //encrypted - 58 58 -const uint32_t kMINRFL3PDU[3] = {0x4760cb78,0xdbcc0acd,0x33048beb}; //unencrypted - 30 58 +const uint32_t kMINRFL3PDU[3] = {0x4760dd78,0xdbcc1ccd,0x33049deb}; //encrypted - 58 58 +// const uint32_t kMINRFL3PDU[3] = {0x4760cb78,0xdbcc0acd,0x33048beb}; //unencrypted - 30 58 const uint32_t kMINRFCGGPDU[3] = {0x4760cd6e,0xdbcc0cdb,0x33048dfd}; const uint32_t kMINRFCGDPDU[3] = {0x5da0d752,0xc10c16e7,0x29c497c1}; @@ -155,6 +159,28 @@ struct bleAdvPacket_t { // for nRF24L01 max 32 bytes = 2+6+24 uint8_t mac[6]; }; +struct encPayload_t { + uint8_t cipher[5]; + uint8_t ExtCnt[3]; + uint8_t tag[4]; +}; + +struct encPacket_t{ + // the packet is longer, but this part is enough to decrypt + uint16_t PID; + uint8_t frameCnt; + uint8_t MAC[6]; + encPayload_t payload; +}; + +union mi_bindKey_t{ + struct{ + uint8_t key[16]; + uint8_t MAC[6]; + }; + uint8_t buf[22]; +}; + union FIFO_t{ bleAdvPacket_t bleAdv; mi_beacon_t miBeacon; @@ -223,6 +249,7 @@ struct scan_entry_t { std::vector MIBLEsensors; std::vector MINRFscanResult; +std::vector MIBLEbindKeys; static union{ scan_entry_t MINRFdummyEntry; @@ -564,6 +591,61 @@ void MINRFcomputeBeaconPDU(void){ } } +int MINRFdecryptPacket(char *_buf){ + encPacket_t *packet = (encPacket_t*)_buf; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("to decrypt: %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + + int ret = 0; + unsigned char output[10] = {0}; + uint8_t nonce[12]; + const unsigned char authData[1] = {0x11}; + + // nonce: device MAC, device type, frame cnt, ext. cnt + for (uint32_t i = 0; i<6; i++){ + nonce[i] = packet->MAC[5-i]; + } + memcpy((uint8_t*)&nonce+6,(uint8_t*)&packet->PID,2); + nonce[8] = packet->frameCnt; + memcpy((uint8_t*)&nonce+9,(uint8_t*)&packet->payload.ExtCnt,3); + + uint8_t _bindkey[16] = {0x0}; + for(uint32_t i=0; iMAC,MIBLEbindKeys[i].MAC,sizeof(packet->MAC))==0){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("have key")); + memcpy(_bindkey,MIBLEbindKeys[i].key,sizeof(_bindkey)); + break; + } + // else{ + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mac in packet: %02x %02x %02x %02x %02x %02x"), packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mac in vector: %02x %02x %02x %02x %02x %02x"), MIBLEbindKeys[i].MAC[0], MIBLEbindKeys[i].MAC[1], MIBLEbindKeys[i].MAC[2], MIBLEbindKeys[i].MAC[3], MIBLEbindKeys[i].MAC[4], MIBLEbindKeys[i].MAC[5]); + // } + } + // init + mbedtls_ccm_context ctx; + mbedtls_ccm_init(&ctx); + + // set bind key + ret = mbedtls_ccm_setkey(&ctx, + MBEDTLS_CIPHER_ID_AES, + _bindkey, + 16 * 8 //bits + ); + + ret = mbedtls_ccm_auth_decrypt(&ctx,5, + (const unsigned char*)&nonce, sizeof(nonce), + authData, sizeof(authData), + packet->payload.cipher, output, + packet->payload.tag,sizeof(packet->payload.tag)); + + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, output[0],output[1],output[2],output[3],output[4]); + // put decrypted data in place + memcpy((uint8_t*)(packet->payload.cipher)+1,output,sizeof(packet->payload.cipher)); + // clean up + mbedtls_ccm_free(&ctx); + return ret; +} + + /*********************************************************************************************\ * helper functions \*********************************************************************************************/ @@ -581,6 +663,46 @@ void MINRFreverseMAC(uint8_t _mac[]){ memcpy(_mac,_reversedMAC, sizeof(_reversedMAC)); } +void MINRFAddKey(char* payload){ + mi_bindKey_t keyMAC; + memset(keyMAC.buf,0,sizeof(keyMAC)); + MINRFKeyMACStringToBytes(payload,keyMAC.buf); + bool unknownKey = true; + for(uint32_t i=0; i= '0' && c <= '9') + value = (c - '0'); + else if (c >= 'A' && c <= 'F') + value = (10 + (c - 'A')); + _keyMac[(index/2)] += value << (((index + 1) % 2) * 4); + index++; + } + DEBUG_SENSOR_LOG(PSTR("MINRF: %s to:"),_string); + DEBUG_SENSOR_LOG(PSTR("MINRF: key-array: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"),_keyMac[0],_keyMac[1],_keyMac[2],_keyMac[3],_keyMac[4],_keyMac[5],_keyMac[6],_keyMac[7],_keyMac[8],_keyMac[9],_keyMac[10],_keyMac[11],_keyMac[12],_keyMac[13],_keyMac[14],_keyMac[15]); + DEBUG_SENSOR_LOG(PSTR("MINRF: MAC-array: %02X%02X%02X%02X%02X%02X"),_keyMac[16],_keyMac[17],_keyMac[18],_keyMac[19],_keyMac[20],_keyMac[21]); +} + /** * @brief * @@ -754,14 +876,19 @@ void MINRFhandleMiBeaconPacket(void){ uint32_t _slot = MINRFgetSensorSlot(MINRF.buffer.miBeacon.Mac, MINRF.buffer.miBeacon.productID); if(_slot==0xff) return; DEBUG_SENSOR_LOG(PSTR("MINRF: slot %u, size vector: %u %u"),_slot,MIBLEsensors.size()); - mi_sensor_t *_sensorVec = &MIBLEsensors.at(_slot); + DEBUG_SENSOR_LOG(PSTR("MINRF: %u %u %u"),_slot,_sensorVec->type,MINRF.buffer.miBeacon.type); float _tempFloat; if (_sensorVec->type==MJ_HT_V1 || _sensorVec->type==CGG1){ memcpy(MINRFtempBuf,(uint8_t*)&MINRF.buffer.miBeacon.spare, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 memcpy((uint8_t*)&MINRF.buffer.miBeacon.type,MINRFtempBuf, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 } + if(_sensorVec->type==LYWSD03){ + int decryptRet = -1; + decryptRet = MINRFdecryptPacket((char*)&MINRF.buffer); //start with PID + if(decryptRet==0) _sensorVec->showedUp=255; // if decryption worked, this must be a valid sensor + } DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kNRFSlaveType[_sensorVec->type-1],_slot); switch(MINRF.buffer.miBeacon.type){ @@ -823,21 +950,6 @@ void MINRFhandleMiBeaconPacket(void){ break; } } -/** - * @brief more or less a placeholder, at least it is technically possible to really decrypt data, but - * the bind_key must be retrieved with 3rd-party-tools -> TODO - */ -void MINRFhandleLYWSD03Packet(void){ - // not much to do ATM, just show the sensor without data - MINRFreverseMAC(MINRF.buffer.miBeacon.Mac); - uint32_t _slot = MINRFgetSensorSlot(MINRF.buffer.miBeacon.Mac, MINRF.buffer.miBeacon.productID); - DEBUG_SENSOR_LOG(PSTR("MINRF: Sensor slot: %u"), _slot); - if(_slot==0xff) return; - - MINRF_LOG_BUFFER(MINRF.streamBuffer); - MINRF_LOG_BUFFER(MINRF.lsfrBuffer); - MINRF_LOG_BUFFER(MINRF.buffer.raw); -} /** * @brief parse the Cleargrass-packet @@ -901,12 +1013,9 @@ void MINRF_EVERY_50_MSECOND() { // Every 50mseconds } else MINRFhandleScan(); break; - case FLORA: case MJ_HT_V1: case LYWSD02: case CGG1: + case FLORA: case MJ_HT_V1: case LYWSD02: case CGG1: case LYWSD03: MINRFhandleMiBeaconPacket(); break; - case LYWSD03: - MINRFhandleLYWSD03Packet(); - break; case CGD1: MINRFhandleCGD1Packet(); break; @@ -1026,6 +1135,12 @@ bool NRFCmd(void) { } Response_P(S_JSON_NRF_COMMAND_NVALUE, command, MINRF.channelIgnore); break; + case CMND_NRF_KEY: + if (XdrvMailbox.data_len==44){ // a KEY-MAC-string + MINRFAddKey(XdrvMailbox.data); + Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); + } + break; default: // else for Unknown command serviced = false; @@ -1191,5 +1306,3 @@ bool Xsns61(uint8_t function) #endif // USE_MIBLE #endif // USE_NRF24 #endif // USE_SPI - - From 37028ce74f632e69dc4e53a96393edb300d8ae1f Mon Sep 17 00:00:00 2001 From: Staars Date: Thu, 18 Jun 2020 17:58:06 +0200 Subject: [PATCH 280/581] add stripped down mbedtls-lib --- lib/mbedtls/README.md | 1 + lib/mbedtls/include/mbedtls/aes.h | 297 ++ lib/mbedtls/include/mbedtls/ccm.h | 141 + lib/mbedtls/include/mbedtls/check_config.h | 628 ++++ lib/mbedtls/include/mbedtls/cipher.h | 709 +++++ lib/mbedtls/include/mbedtls/cipher_internal.h | 109 + lib/mbedtls/include/mbedtls/config.h | 2600 +++++++++++++++++ lib/mbedtls/include/mbedtls/platform.h | 295 ++ lib/mbedtls/include/mbedtls/platform_time.h | 81 + lib/mbedtls/src/aes.c | 1492 ++++++++++ lib/mbedtls/src/ccm.c | 464 +++ lib/mbedtls/src/cipher.c | 917 ++++++ lib/mbedtls/src/cipher_wrap.c | 1451 +++++++++ 13 files changed, 9185 insertions(+) create mode 100644 lib/mbedtls/README.md create mode 100644 lib/mbedtls/include/mbedtls/aes.h create mode 100644 lib/mbedtls/include/mbedtls/ccm.h create mode 100644 lib/mbedtls/include/mbedtls/check_config.h create mode 100644 lib/mbedtls/include/mbedtls/cipher.h create mode 100644 lib/mbedtls/include/mbedtls/cipher_internal.h create mode 100644 lib/mbedtls/include/mbedtls/config.h create mode 100644 lib/mbedtls/include/mbedtls/platform.h create mode 100644 lib/mbedtls/include/mbedtls/platform_time.h create mode 100644 lib/mbedtls/src/aes.c create mode 100644 lib/mbedtls/src/ccm.c create mode 100644 lib/mbedtls/src/cipher.c create mode 100644 lib/mbedtls/src/cipher_wrap.c diff --git a/lib/mbedtls/README.md b/lib/mbedtls/README.md new file mode 100644 index 000000000..f5df7f0c8 --- /dev/null +++ b/lib/mbedtls/README.md @@ -0,0 +1 @@ +Stripped down library for aes-ccm-decryption in the MI_NRF24.ino. \ No newline at end of file diff --git a/lib/mbedtls/include/mbedtls/aes.h b/lib/mbedtls/include/mbedtls/aes.h new file mode 100644 index 000000000..a36e825a2 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/aes.h @@ -0,0 +1,297 @@ +/** + * \file aes.h + * + * \brief AES block cipher + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_AES_H +#define MBEDTLS_AES_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include + +/* padlock.c and aesni.c rely on these values! */ +#define MBEDTLS_AES_ENCRYPT 1 +#define MBEDTLS_AES_DECRYPT 0 + +#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ +#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ + +#if !defined(MBEDTLS_AES_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief AES context structure + * + * \note buf is able to hold 32 extra bytes, which can be used: + * - for alignment purposes if VIA padlock is used, and/or + * - to simplify key expansion in the 256-bit case by + * generating an extra round key + */ +typedef struct +{ + int nr; /*!< number of rounds */ + uint32_t *rk; /*!< AES round keys */ + uint32_t buf[68]; /*!< unaligned data */ +} +mbedtls_aes_context; + +/** + * \brief Initialize AES context + * + * \param ctx AES context to be initialized + */ +void mbedtls_aes_init( mbedtls_aes_context *ctx ); + +/** + * \brief Clear AES context + * + * \param ctx AES context to be cleared + */ +void mbedtls_aes_free( mbedtls_aes_context *ctx ); + +/** + * \brief AES key schedule (encryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief AES key schedule (decryption) + * + * \param ctx AES context to be initialized + * \param key decryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief AES-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/** + * \brief AES-CFB128 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CFB8 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/** + * \brief AES-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * Note: Due to the nature of CTR you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \param ctx AES context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/** + * \brief Internal AES block encryption function + * (Only exposed to allow overriding it, + * see MBEDTLS_AES_ENCRYPT_ALT) + * + * \param ctx AES context + * \param input Plaintext block + * \param output Output (ciphertext) block + */ +void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief Internal AES block decryption function + * (Only exposed to allow overriding it, + * see MBEDTLS_AES_DECRYPT_ALT) + * + * \param ctx AES context + * \param input Ciphertext block + * \param output Output (plaintext) block + */ +void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_AES_ALT */ +#include "aes_alt.h" +#endif /* MBEDTLS_AES_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_aes_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* aes.h */ diff --git a/lib/mbedtls/include/mbedtls/ccm.h b/lib/mbedtls/include/mbedtls/ccm.h new file mode 100644 index 000000000..ef75839ba --- /dev/null +++ b/lib/mbedtls/include/mbedtls/ccm.h @@ -0,0 +1,141 @@ +/** + * \file ccm.h + * + * \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_CCM_H +#define MBEDTLS_CCM_H + +#include "cipher.h" + +#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to function. */ +#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief CCM context structure + */ +typedef struct { + mbedtls_cipher_context_t cipher_ctx; /*!< cipher context used */ +} +mbedtls_ccm_context; + +/** + * \brief Initialize CCM context (just makes references valid) + * Makes the context ready for mbedtls_ccm_setkey() or + * mbedtls_ccm_free(). + * + * \param ctx CCM context to initialize + */ +void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); + +/** + * \brief CCM initialization (encryption and decryption) + * + * \param ctx CCM context to be initialized + * \param cipher cipher to use (a 128-bit block cipher) + * \param key encryption key + * \param keybits key size in bits (must be acceptable by the cipher) + * + * \return 0 if successful, or a cipher specific error code + */ +int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief Free a CCM context and underlying cipher sub-context + * + * \param ctx CCM context to free + */ +void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); + +/** + * \brief CCM buffer encryption + * + * \param ctx CCM context + * \param length length of the input data in bytes + * \param iv nonce (initialization vector) + * \param iv_len length of IV in bytes + * must be 2, 3, 4, 5, 6, 7 or 8 + * \param add additional data + * \param add_len length of additional data in bytes + * must be less than 2^16 - 2^8 + * \param input buffer holding the input data + * \param output buffer for holding the output data + * must be at least 'length' bytes wide + * \param tag buffer for holding the tag + * \param tag_len length of the tag to generate in bytes + * must be 4, 6, 8, 10, 14 or 16 + * + * \note The tag is written to a separate buffer. To get the tag + * concatenated with the output as in the CCM spec, use + * tag = output + length and make sure the output buffer is + * at least length + tag_len wide. + * + * \return 0 if successful + */ +int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ); + +/** + * \brief CCM buffer authenticated decryption + * + * \param ctx CCM context + * \param length length of the input data + * \param iv initialization vector + * \param iv_len length of IV + * \param add additional data + * \param add_len length of additional data + * \param input buffer holding the input data + * \param output buffer for holding the output data + * \param tag buffer holding the tag + * \param tag_len length of the tag + * + * \return 0 if successful and authenticated, + * MBEDTLS_ERR_CCM_AUTH_FAILED if tag does not match + */ +int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ); + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_ccm_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CCM_H */ diff --git a/lib/mbedtls/include/mbedtls/check_config.h b/lib/mbedtls/include/mbedtls/check_config.h new file mode 100644 index 000000000..fe86c1e8d --- /dev/null +++ b/lib/mbedtls/include/mbedtls/check_config.h @@ -0,0 +1,628 @@ +/** + * \file check_config.h + * + * \brief Consistency checks for configuration options + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * It is recommended to include this file from your config.h + * in order to catch dependency issues early. + */ + +#ifndef MBEDTLS_CHECK_CONFIG_H +#define MBEDTLS_CHECK_CONFIG_H + +/* + * We assume CHAR_BIT is 8 in many places. In practice, this is true on our + * target platforms, so not an issue, but let's just be extra sure. + */ +#include +#if CHAR_BIT != 8 +#error "mbed TLS requires a platform with 8-bit chars" +#endif + +#if defined(_WIN32) +#if !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_C is required on Windows" +#endif + +/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as + * it would confuse config.pl. */ +#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \ + !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) +#define MBEDTLS_PLATFORM_SNPRINTF_ALT +#endif +#endif /* _WIN32 */ + +#if defined(TARGET_LIKE_MBED) && \ + ( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) ) +#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS" +#endif + +#if defined(MBEDTLS_DEPRECATED_WARNING) && \ + !defined(__GNUC__) && !defined(__clang__) +#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" +#endif + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME) +#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" +#endif + +#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_AESNI_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) +#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) +#error "MBEDTLS_DHM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CMAC_C) && \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) +#error "MBEDTLS_CMAC_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) +#error "MBEDTLS_ECDH_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDSA_C) && \ + ( !defined(MBEDTLS_ECP_C) || \ + !defined(MBEDTLS_ASN1_PARSE_C) || \ + !defined(MBEDTLS_ASN1_WRITE_C) ) +#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECJPAKE_C) && \ + ( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) ) +#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) +#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ + !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) ) +#error "MBEDTLS_ECP_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \ + !defined(MBEDTLS_SHA256_C)) +#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites" +#endif +#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \ + defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64) +#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(MBEDTLS_ENTROPY_C) && \ + ( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \ + && defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32) +#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C) +#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ + ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) ) +#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites" +#endif +#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ + ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ + defined(MBEDTLS_HAVEGE_C) ) +#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too" +#endif + +#if defined(MBEDTLS_GCM_C) && ( \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) ) +#error "MBEDTLS_GCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C) +#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) +#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C) +#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ + !defined(MBEDTLS_ECDH_C) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + ( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \ + !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ) +#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C) +#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C) +#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_C) && \ + ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) ) +#error "MBEDTLS_PK_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PKCS11_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\ + defined(MBEDTLS_PLATFORM_EXIT_ALT) ) +#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\ + defined(MBEDTLS_PLATFORM_FPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ + defined(MBEDTLS_PLATFORM_STD_FREE) +#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ + defined(MBEDTLS_PLATFORM_STD_CALLOC) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO) +#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is" +#endif + +#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\ + defined(MBEDTLS_PLATFORM_PRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ + defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ + !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) +#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\ + !defined(MBEDTLS_PLATFORM_EXIT_ALT) +#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ + ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ + !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\ + !defined(MBEDTLS_PLATFORM_PRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\ + !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) ) +#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\ + !defined(MBEDTLS_ENTROPY_NV_SEED) +#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) ) +#error "MBEDTLS_RSA_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled" +#endif + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) +#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \ + !defined(MBEDTLS_SHA1_C) ) +#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \ + !defined(MBEDTLS_SHA1_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \ + !defined(MBEDTLS_SHA1_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \ + !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C) +#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \ + !defined(MBEDTLS_MD_C) ) +#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C) +#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2)) +#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1)) +#error "Illegal protocol selection" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1)) +#error "Illegal protocol selection" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1))) +#error "Illegal protocol selection" +#endif + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS) +#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ + !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) +#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites" +#endif + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites" +#endif + +#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \ + !defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1) +#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ + !defined(MBEDTLS_X509_CRT_PARSE_C) +#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_THREADING_PTHREAD) +#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" +#endif +#define MBEDTLS_THREADING_IMPL +#endif + +#if defined(MBEDTLS_THREADING_ALT) +#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" +#endif +#define MBEDTLS_THREADING_IMPL +#endif + +#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_C defined, single threading implementation required" +#endif +#undef MBEDTLS_THREADING_IMPL + +#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C) +#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ + !defined(MBEDTLS_PK_PARSE_C) ) +#error "MBEDTLS_X509_USE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \ + !defined(MBEDTLS_PK_WRITE_C) ) +#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) +#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) +#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" +#endif + +/* + * Avoid warning from -pedantic. This is a convenient place for this + * workaround since this is included by every single file before the + * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units. + */ +typedef int mbedtls_iso_c_forbids_empty_translation_units; + +#endif /* MBEDTLS_CHECK_CONFIG_H */ diff --git a/lib/mbedtls/include/mbedtls/cipher.h b/lib/mbedtls/include/mbedtls/cipher.h new file mode 100644 index 000000000..b12e38843 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/cipher.h @@ -0,0 +1,709 @@ +/** + * \file cipher.h + * + * \brief Generic cipher wrapper. + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CIPHER_H +#define MBEDTLS_CIPHER_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) +#define MBEDTLS_CIPHER_MODE_AEAD +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#define MBEDTLS_CIPHER_MODE_WITH_PADDING +#endif + +#if defined(MBEDTLS_ARC4_C) +#define MBEDTLS_CIPHER_MODE_STREAM +#endif + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */ +#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters to function. */ +#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */ +#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ +#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ +#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ +#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid, eg because it was free()ed. */ + +#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */ +#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MBEDTLS_CIPHER_ID_NONE = 0, + MBEDTLS_CIPHER_ID_NULL, + MBEDTLS_CIPHER_ID_AES, + MBEDTLS_CIPHER_ID_DES, + MBEDTLS_CIPHER_ID_3DES, + MBEDTLS_CIPHER_ID_CAMELLIA, + MBEDTLS_CIPHER_ID_BLOWFISH, + MBEDTLS_CIPHER_ID_ARC4, +} mbedtls_cipher_id_t; + +typedef enum { + MBEDTLS_CIPHER_NONE = 0, + MBEDTLS_CIPHER_NULL, + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_CIPHER_AES_128_CBC, + MBEDTLS_CIPHER_AES_192_CBC, + MBEDTLS_CIPHER_AES_256_CBC, + MBEDTLS_CIPHER_AES_128_CFB128, + MBEDTLS_CIPHER_AES_192_CFB128, + MBEDTLS_CIPHER_AES_256_CFB128, + MBEDTLS_CIPHER_AES_128_CTR, + MBEDTLS_CIPHER_AES_192_CTR, + MBEDTLS_CIPHER_AES_256_CTR, + MBEDTLS_CIPHER_AES_128_GCM, + MBEDTLS_CIPHER_AES_192_GCM, + MBEDTLS_CIPHER_AES_256_GCM, + MBEDTLS_CIPHER_CAMELLIA_128_ECB, + MBEDTLS_CIPHER_CAMELLIA_192_ECB, + MBEDTLS_CIPHER_CAMELLIA_256_ECB, + MBEDTLS_CIPHER_CAMELLIA_128_CBC, + MBEDTLS_CIPHER_CAMELLIA_192_CBC, + MBEDTLS_CIPHER_CAMELLIA_256_CBC, + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, + MBEDTLS_CIPHER_CAMELLIA_128_CTR, + MBEDTLS_CIPHER_CAMELLIA_192_CTR, + MBEDTLS_CIPHER_CAMELLIA_256_CTR, + MBEDTLS_CIPHER_CAMELLIA_128_GCM, + MBEDTLS_CIPHER_CAMELLIA_192_GCM, + MBEDTLS_CIPHER_CAMELLIA_256_GCM, + MBEDTLS_CIPHER_DES_ECB, + MBEDTLS_CIPHER_DES_CBC, + MBEDTLS_CIPHER_DES_EDE_ECB, + MBEDTLS_CIPHER_DES_EDE_CBC, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_CIPHER_DES_EDE3_CBC, + MBEDTLS_CIPHER_BLOWFISH_ECB, + MBEDTLS_CIPHER_BLOWFISH_CBC, + MBEDTLS_CIPHER_BLOWFISH_CFB64, + MBEDTLS_CIPHER_BLOWFISH_CTR, + MBEDTLS_CIPHER_ARC4_128, + MBEDTLS_CIPHER_AES_128_CCM, + MBEDTLS_CIPHER_AES_192_CCM, + MBEDTLS_CIPHER_AES_256_CCM, + MBEDTLS_CIPHER_CAMELLIA_128_CCM, + MBEDTLS_CIPHER_CAMELLIA_192_CCM, + MBEDTLS_CIPHER_CAMELLIA_256_CCM, +} mbedtls_cipher_type_t; + +typedef enum { + MBEDTLS_MODE_NONE = 0, + MBEDTLS_MODE_ECB, + MBEDTLS_MODE_CBC, + MBEDTLS_MODE_CFB, + MBEDTLS_MODE_OFB, /* Unused! */ + MBEDTLS_MODE_CTR, + MBEDTLS_MODE_GCM, + MBEDTLS_MODE_STREAM, + MBEDTLS_MODE_CCM, +} mbedtls_cipher_mode_t; + +typedef enum { + MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default) */ + MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding */ + MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding */ + MBEDTLS_PADDING_ZEROS, /**< zero padding (not reversible!) */ + MBEDTLS_PADDING_NONE, /**< never pad (full blocks only) */ +} mbedtls_cipher_padding_t; + +typedef enum { + MBEDTLS_OPERATION_NONE = -1, + MBEDTLS_DECRYPT = 0, + MBEDTLS_ENCRYPT, +} mbedtls_operation_t; + +enum { + /** Undefined key length */ + MBEDTLS_KEY_LENGTH_NONE = 0, + /** Key length, in bits (including parity), for DES keys */ + MBEDTLS_KEY_LENGTH_DES = 64, + /** Key length, in bits (including parity), for DES in two key EDE */ + MBEDTLS_KEY_LENGTH_DES_EDE = 128, + /** Key length, in bits (including parity), for DES in three-key EDE */ + MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, +}; + +/** Maximum length of any IV, in bytes */ +#define MBEDTLS_MAX_IV_LENGTH 16 +/** Maximum block size of any cipher, in bytes */ +#define MBEDTLS_MAX_BLOCK_LENGTH 16 + +/** + * Base cipher information (opaque struct). + */ +typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; + +/** + * CMAC context (opaque struct). + */ +typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; + +/** + * Cipher information. Allows cipher functions to be called in a generic way. + */ +typedef struct { + /** Full cipher identifier (e.g. MBEDTLS_CIPHER_AES_256_CBC) */ + mbedtls_cipher_type_t type; + + /** Cipher mode (e.g. MBEDTLS_MODE_CBC) */ + mbedtls_cipher_mode_t mode; + + /** Cipher key length, in bits (default length for variable sized ciphers) + * (Includes parity bits for ciphers like DES) */ + unsigned int key_bitlen; + + /** Name of the cipher */ + const char * name; + + /** IV/NONCE size, in bytes. + * For cipher that accept many sizes: recommended size */ + unsigned int iv_size; + + /** Flags for variable IV size, variable key size, etc. */ + int flags; + + /** block size, in bytes */ + unsigned int block_size; + + /** Base cipher information and functions */ + const mbedtls_cipher_base_t *base; + +} mbedtls_cipher_info_t; + +/** + * Generic cipher context. + */ +typedef struct { + /** Information about the associated cipher */ + const mbedtls_cipher_info_t *cipher_info; + + /** Key length to use */ + int key_bitlen; + + /** Operation that the context's key has been initialised for */ + mbedtls_operation_t operation; + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /** Padding functions to use, if relevant for cipher mode */ + void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); + int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); +#endif + + /** Buffer for data that hasn't been encrypted yet */ + unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; + + /** Number of bytes that still need processing */ + size_t unprocessed_len; + + /** Current IV or NONCE_COUNTER for CTR-mode */ + unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; + + /** IV size in bytes (for ciphers with variable-length IVs) */ + size_t iv_size; + + /** Cipher-specific context */ + void *cipher_ctx; + +#if defined(MBEDTLS_CMAC_C) + /** CMAC Specific context */ + mbedtls_cmac_context_t *cmac_ctx; +#endif +} mbedtls_cipher_context_t; + +/** + * \brief Returns the list of ciphers supported by the generic cipher module. + * + * \return a statically allocated array of ciphers, the last entry + * is 0. + */ +const int *mbedtls_cipher_list( void ); + +/** + * \brief Returns the cipher information structure associated + * with the given cipher name. + * + * \param cipher_name Name of the cipher to search for. + * + * \return the cipher information structure associated with the + * given cipher_name, or NULL if not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ); + +/** + * \brief Returns the cipher information structure associated + * with the given cipher type. + * + * \param cipher_type Type of the cipher to search for. + * + * \return the cipher information structure associated with the + * given cipher_type, or NULL if not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ); + +/** + * \brief Returns the cipher information structure associated + * with the given cipher id, key size and mode. + * + * \param cipher_id Id of the cipher to search for + * (e.g. MBEDTLS_CIPHER_ID_AES) + * \param key_bitlen Length of the key in bits + * \param mode Cipher mode (e.g. MBEDTLS_MODE_CBC) + * + * \return the cipher information structure associated with the + * given cipher_type, or NULL if not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode ); + +/** + * \brief Initialize a cipher_context (as NONE) + */ +void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); + +/** + * \brief Free and clear the cipher-specific context of ctx. + * Freeing ctx itself remains the responsibility of the + * caller. + */ +void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); + +/** + * \brief Initialises and fills the cipher context structure with + * the appropriate values. + * + * \note Currently also clears structure. In future versions you + * will be required to call mbedtls_cipher_init() on the structure + * first. + * + * \param ctx context to initialise. May not be NULL. + * \param cipher_info cipher to use. + * + * \return 0 on success, + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure, + * MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the + * cipher-specific context failed. + */ +int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ); + +/** + * \brief Returns the block size of the given cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return size of the cipher's blocks, or 0 if ctx has not been + * initialised. + */ +static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return 0; + + return ctx->cipher_info->block_size; +} + +/** + * \brief Returns the mode of operation for the cipher. + * (e.g. MBEDTLS_MODE_CBC) + * + * \param ctx cipher's context. Must have been initialised. + * + * \return mode of operation, or MBEDTLS_MODE_NONE if ctx + * has not been initialised. + */ +static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return MBEDTLS_MODE_NONE; + + return ctx->cipher_info->mode; +} + +/** + * \brief Returns the size of the cipher's IV/NONCE in bytes. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return If IV has not been set yet: (recommended) IV size + * (0 for ciphers not using IV/NONCE). + * If IV has already been set: actual size. + */ +static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return 0; + + if( ctx->iv_size != 0 ) + return (int) ctx->iv_size; + + return (int) ctx->cipher_info->iv_size; +} + +/** + * \brief Returns the type of the given cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return type of the cipher, or MBEDTLS_CIPHER_NONE if ctx has + * not been initialised. + */ +static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return MBEDTLS_CIPHER_NONE; + + return ctx->cipher_info->type; +} + +/** + * \brief Returns the name of the given cipher, as a string. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return name of the cipher, or NULL if ctx was not initialised. + */ +static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return 0; + + return ctx->cipher_info->name; +} + +/** + * \brief Returns the key length of the cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return cipher's key length, in bits, or + * MBEDTLS_KEY_LENGTH_NONE if ctx has not been + * initialised. + */ +static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return MBEDTLS_KEY_LENGTH_NONE; + + return (int) ctx->cipher_info->key_bitlen; +} + +/** + * \brief Returns the operation of the given cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return operation (MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT), + * or MBEDTLS_OPERATION_NONE if ctx has not been + * initialised. + */ +static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return MBEDTLS_OPERATION_NONE; + + return ctx->operation; +} + +/** + * \brief Set the key to use with the given context. + * + * \param ctx generic cipher context. May not be NULL. Must have been + * initialised using cipher_context_from_type or + * cipher_context_from_string. + * \param key The key to use. + * \param key_bitlen key length to use, in bits. + * \param operation Operation that the key will be used for, either + * MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT. + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails or a cipher specific + * error code. + */ +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, + int key_bitlen, const mbedtls_operation_t operation ); + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +/** + * \brief Set padding mode, for cipher modes that use padding. + * (Default: PKCS7 padding.) + * + * \param ctx generic cipher context + * \param mode padding mode + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE + * if selected padding mode is not supported, or + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode + * does not support padding. + */ +int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ); +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +/** + * \brief Set the initialization vector (IV) or nonce + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * + * \returns 0 on success, or MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA + * + * \note Some ciphers don't use IVs nor NONCE. For these + * ciphers, this function has no effect. + */ +int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len ); + +/** + * \brief Finish preparation of the given context + * + * \param ctx generic cipher context + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA + * if parameter verification fails. + */ +int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); + +#if defined(MBEDTLS_GCM_C) +/** + * \brief Add additional data (for AEAD ciphers). + * Currently only supported with GCM. + * Must be called exactly once, after mbedtls_cipher_reset(). + * + * \param ctx generic cipher context + * \param ad Additional data to use. + * \param ad_len Length of ad. + * + * \return 0 on success, or a specific error code. + */ +int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ); +#endif /* MBEDTLS_GCM_C */ + +/** + * \brief Generic cipher update function. Encrypts/decrypts + * using the given cipher context. Writes as many block + * size'd blocks of data as possible to output. Any data + * that cannot be written immediately will either be added + * to the next block, or flushed when cipher_final is + * called. + * Exception: for MBEDTLS_MODE_ECB, expects single block + * in size (e.g. 16 bytes for AES) + * + * \param ctx generic cipher context + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. Should be able to hold at + * least ilen + block_size. Cannot be the same buffer as + * input! + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails, + * MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an + * unsupported mode for a cipher or a cipher specific + * error code. + * + * \note If the underlying cipher is GCM, all calls to this + * function, except the last one before mbedtls_cipher_finish(), + * must have ilen a multiple of the block size. + */ +int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ); + +/** + * \brief Generic cipher finalisation function. If data still + * needs to be flushed from an incomplete block, data + * contained within it will be padded with the size of + * the last block, and written to the output buffer. + * + * \param ctx Generic cipher context + * \param output buffer to write data to. Needs block_size available. + * \param olen length of the data written to the output buffer. + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails, + * MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption + * expected a full block but was not provided one, + * MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting or a cipher specific error code. + */ +int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen ); + +#if defined(MBEDTLS_GCM_C) +/** + * \brief Write tag for AEAD ciphers. + * Currently only supported with GCM. + * Must be called after mbedtls_cipher_finish(). + * + * \param ctx Generic cipher context + * \param tag buffer to write the tag + * \param tag_len Length of the tag to write + * + * \return 0 on success, or a specific error code. + */ +int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ); + +/** + * \brief Check tag for AEAD ciphers. + * Currently only supported with GCM. + * Must be called after mbedtls_cipher_finish(). + * + * \param ctx Generic cipher context + * \param tag Buffer holding the tag + * \param tag_len Length of the tag to check + * + * \return 0 on success, or a specific error code. + */ +int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ); +#endif /* MBEDTLS_GCM_C */ + +/** + * \brief Generic all-in-one encryption/decryption + * (for all ciphers except AEAD constructs). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. Should be able to hold at + * least ilen + block_size. Cannot be the same buffer as + * input! + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * + * \note Some ciphers don't use IVs nor NONCE. For these + * ciphers, use iv = NULL and iv_len = 0. + * + * \returns 0 on success, or + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or + * MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption + * expected a full block but was not provided one, or + * MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting, or + * a cipher specific error code. + */ +int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ); + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) +/** + * \brief Generic autenticated encryption (AEAD ciphers). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param ad Additional data to authenticate. + * \param ad_len Length of ad. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. + * Should be able to hold at least ilen. + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * \param tag buffer for the authentication tag + * \param tag_len desired tag length + * + * \returns 0 on success, or + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or + * a cipher specific error code. + */ +int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ); + +/** + * \brief Generic autenticated decryption (AEAD ciphers). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param ad Additional data to be authenticated. + * \param ad_len Length of ad. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. + * Should be able to hold at least ilen. + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * \param tag buffer holding the authentication tag + * \param tag_len length of the authentication tag + * + * \returns 0 on success, or + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or + * MBEDTLS_ERR_CIPHER_AUTH_FAILED if data isn't authentic, + * or a cipher specific error code. + * + * \note If the data is not authentic, then the output buffer + * is zeroed out to prevent the unauthentic plaintext to + * be used by mistake, making this interface safer. + */ +int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ); +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CIPHER_H */ diff --git a/lib/mbedtls/include/mbedtls/cipher_internal.h b/lib/mbedtls/include/mbedtls/cipher_internal.h new file mode 100644 index 000000000..6c58bcc52 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/cipher_internal.h @@ -0,0 +1,109 @@ +/** + * \file cipher_internal.h + * + * \brief Cipher wrappers. + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_CIPHER_WRAP_H +#define MBEDTLS_CIPHER_WRAP_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "cipher.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Base cipher information. The non-mode specific functions and values. + */ +struct mbedtls_cipher_base_t +{ + /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ + mbedtls_cipher_id_t cipher; + + /** Encrypt using ECB */ + int (*ecb_func)( void *ctx, mbedtls_operation_t mode, + const unsigned char *input, unsigned char *output ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /** Encrypt using CBC */ + int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length, + unsigned char *iv, const unsigned char *input, + unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + /** Encrypt using CFB (Full length) */ + int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, + unsigned char *iv, const unsigned char *input, + unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /** Encrypt using CTR */ + int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + /** Encrypt using STREAM */ + int (*stream_func)( void *ctx, size_t length, + const unsigned char *input, unsigned char *output ); +#endif + + /** Set key for encryption purposes */ + int (*setkey_enc_func)( void *ctx, const unsigned char *key, + unsigned int key_bitlen ); + + /** Set key for decryption purposes */ + int (*setkey_dec_func)( void *ctx, const unsigned char *key, + unsigned int key_bitlen); + + /** Allocate a new context */ + void * (*ctx_alloc_func)( void ); + + /** Free the given context */ + void (*ctx_free_func)( void *ctx ); + +}; + +typedef struct +{ + mbedtls_cipher_type_t type; + const mbedtls_cipher_info_t *info; +} mbedtls_cipher_definition_t; + +extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; + +extern int mbedtls_cipher_supported[]; + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CIPHER_WRAP_H */ diff --git a/lib/mbedtls/include/mbedtls/config.h b/lib/mbedtls/include/mbedtls/config.h new file mode 100644 index 000000000..0a3e1bb44 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/config.h @@ -0,0 +1,2600 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CONFIG_H +#define MBEDTLS_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/timing.c + * library/padlock.c + * include/mbedtls/bn_mul.h + * + * Comment to disable the use of assembly code. + */ +#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * + * Comment if your system does not support time functions + */ +// #define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h and time(), gmtime() and the clock is correct. + * The time needs to be correct (not necesarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + */ +// #define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def MBEDTLS_PLATFORM_EXIT_ALT + * + * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the + * function in the platform abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_NV_SEED_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions so that they generate a warning if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions so that they generate an error if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * Uncomment to get errors on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_REMOVED + +/* \} name SECTION: System support */ + +/** + * \name SECTION: mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS_AES_ALT + * + * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternate core implementation of a symmetric crypto or hash module (e.g. + * platform specific assembly optimized implementations). Keep in mind that + * the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base function + * declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARC4_ALT +//#define MBEDTLS_BLOWFISH_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_XTEA_ALT +//#define MBEDTLS_MD2_ALT +//#define MBEDTLS_MD4_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_SHA1_ALT +//#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT + +/** + * \def MBEDTLS_MD2_PROCESS_ALT + * + * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you + * alternate core implementation of symmetric crypto or hash function. Keep in + * mind that function prototypes should remain the same. + * + * This replaces only one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * Note: if you use the AES_xxx_ALT macros, then is is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +//#define MBEDTLS_MD2_PROCESS_ALT +//#define MBEDTLS_MD4_PROCESS_ALT +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT + +/** + * \def MBEDTLS_TEST_NULL_ENTROPY + * + * Enables testing and use of mbed TLS without any configured entropy sources. + * This permits use of the library on platforms before an entropy source has + * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the + * MBEDTLS_ENTROPY_NV_SEED switches). + * + * WARNING! This switch MUST be disabled in production builds, and is suitable + * only for development. + * Enabling the switch negates any security provided by the library. + * + * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + */ +//#define MBEDTLS_TEST_NULL_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * + * Uncomment to use your own hardware entropy collector. + */ +//#define MBEDTLS_ENTROPY_HARDWARE_ALT + +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Store the AES tables in ROM. + * + * Uncomment this macro to store the AES tables in ROM. + */ +//#define MBEDTLS_AES_ROM_TABLES + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +// #define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +// #define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CTR + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable + * the following ciphersuites: + * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_PKCS7 + * + * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for + * specific padding modes in the cipher layer with cipher modes that support + * padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +#define MBEDTLS_CIPHER_PADDING_ZEROS + +/** + * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES + * + * Enable weak ciphersuites in SSL / TLS. + * Warning: Only do so when you know what you are doing. This allows for + * channels with virtually no security at all! + * + * This enables the following ciphersuites: + * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA + * + * Uncomment this macro to enable weak ciphersuites + */ +//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES + +/** + * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES + * + * Remove RC4 ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on RC4 from the default list as + * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to + * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them + * explicitly. + * + * Uncomment this macro to remove RC4 ciphersuites by default. + */ +#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES + +/** + * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED + * + * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve + * module. By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +// #define MBEDTLS_ECP_DP_SECP192R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP224R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP256R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP384R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP521R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP192K1_ENABLED +// #define MBEDTLS_ECP_DP_SECP224K1_ENABLED +// #define MBEDTLS_ECP_DP_SECP256K1_ENABLED +// #define MBEDTLS_ECP_DP_BP256R1_ENABLED +// #define MBEDTLS_ECP_DP_BP384R1_ENABLED +// #define MBEDTLS_ECP_DP_BP512R1_ENABLED +// #define MBEDTLS_ECP_DP_CURVE25519_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +// #define MBEDTLS_ECP_NIST_OPTIM + +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +// #define MBEDTLS_ECDSA_DETERMINISTIC + +/** + * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 + */ +// #define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + * + * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Requires: MBEDTLS_ECJPAKE_C + * MBEDTLS_SHA256_C + * MBEDTLS_ECP_DP_SECP256R1_ENABLED + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +// #define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +// #define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +// #define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * mbedtls_timing_hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +// #define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +//#define MBEDTLS_ENTROPY_NV_SEED + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +// #define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +// #define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +// #define MBEDTLS_PKCS1_V21 + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +// #define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonnable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +//#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, mbed TLS can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +// #define MBEDTLS_SSL_ALL_ALERT_MESSAGES + +/** + * \def MBEDTLS_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define MBEDTLS_SSL_DEBUG_ALL + +/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC + * + * Enable support for Encrypt-then-MAC, RFC 7366. + * + * This allows peers that both support it to use a more robust protection for + * ciphersuites using CBC, providing deep resistance against timing attacks + * on the padding or underlying cipher. + * + * This only affects CBC ciphersuites, and is useless if none is defined. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1 or + * MBEDTLS_SSL_PROTO_TLS1_1 or + * MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Encrypt-then-MAC + */ +// #define MBEDTLS_SSL_ENCRYPT_THEN_MAC + +/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET + * + * Enable support for Extended Master Secret, aka Session Hash + * (draft-ietf-tls-session-hash-02). + * + * This was introduced as "the proper fix" to the Triple Handshake familiy of + * attacks, but it is recommended to always use it (even if you disable + * renegotiation), since it actually fixes a more fundamental issue in the + * original SSL/TLS design, and has implications beyond Triple Handshake. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1 or + * MBEDTLS_SSL_PROTO_TLS1_1 or + * MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Extended Master Secret. + */ +// #define MBEDTLS_SSL_EXTENDED_MASTER_SECRET + +/** + * \def MBEDTLS_SSL_FALLBACK_SCSV + * + * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00). + * + * For servers, it is recommended to always enable this, unless you support + * only one version of TLS, or know for sure that none of your clients + * implements a fallback strategy. + * + * For clients, you only need this if you're using a fallback strategy, which + * is not recommended in the first place, unless you absolutely need it to + * interoperate with buggy (version-intolerant) servers. + * + * Comment this macro to disable support for FALLBACK_SCSV + */ +// #define MBEDTLS_SSL_FALLBACK_SCSV + +/** + * \def MBEDTLS_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * Uncomment this macro to enable hooking functions. + */ +//#define MBEDTLS_SSL_HW_RECORD_ACCEL + +/** + * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING + * + * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. + * + * This is a countermeasure to the BEAST attack, which also minimizes the risk + * of interoperability issues compared to sending 0-length records. + * + * Comment this macro to disable 1/n-1 record splitting. + */ +// #define MBEDTLS_SSL_CBC_RECORD_SPLITTING + +/** + * \def MBEDTLS_SSL_RENEGOTIATION + * + * Disable support for TLS renegotiation. + * + * The two main uses of renegotiation are (1) refresh keys on long-lived + * connections and (2) client authentication after the initial handshake. + * If you don't need renegotiation, it's probably better to disable it, since + * it has been associated with security issues in the past and is easy to + * misuse/misunderstand. + * + * Comment this to disable support for renegotiation. + */ +// #define MBEDTLS_SSL_RENEGOTIATION + +/** + * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + * + * Enable support for receiving and parsing SSLv2 Client Hello messages for the + * SSL Server module (MBEDTLS_SSL_SRV_C). + * + * Uncomment this macro to enable support for SSLv2 Client Hello messages. + */ +//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + +/** + * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE + * + * Pick the ciphersuite according to the client's preferences rather than ours + * in the SSL Server module (MBEDTLS_SSL_SRV_C). + * + * Uncomment this macro to respect client's ciphersuite order + */ +//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE + +/** + * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +// #define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def MBEDTLS_SSL_PROTO_SSL3 + * + * Enable support for SSL 3.0. + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for SSL 3.0 + */ +//#define MBEDTLS_SSL_PROTO_SSL3 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1 + * + * Enable support for TLS 1.0. + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for TLS 1.0 + */ +// #define MBEDTLS_SSL_PROTO_TLS1 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_1 + * + * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for TLS 1.1 / DTLS 1.0 + */ +// #define MBEDTLS_SSL_PROTO_TLS1_1 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). + * + * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C + * (Depends on ciphersuites) + * + * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 + */ +// #define MBEDTLS_SSL_PROTO_TLS1_2 + +/** + * \def MBEDTLS_SSL_PROTO_DTLS + * + * Enable support for DTLS (all available versions). + * + * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, + * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_1 + * or MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for DTLS + */ +// #define MBEDTLS_SSL_PROTO_DTLS + +/** + * \def MBEDTLS_SSL_ALPN + * + * Enable support for RFC 7301 Application Layer Protocol Negotiation. + * + * Comment this macro to disable support for ALPN. + */ +// #define MBEDTLS_SSL_ALPN + +/** + * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY + * + * Enable support for the anti-replay mechanism in DTLS. + * + * Requires: MBEDTLS_SSL_TLS_C + * MBEDTLS_SSL_PROTO_DTLS + * + * \warning Disabling this is often a security risk! + * See mbedtls_ssl_conf_dtls_anti_replay() for details. + * + * Comment this to disable anti-replay in DTLS. + */ +// #define MBEDTLS_SSL_DTLS_ANTI_REPLAY + +/** + * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Enable support for HelloVerifyRequest on DTLS servers. + * + * This feature is highly recommended to prevent DTLS servers being used as + * amplifiers in DoS attacks against other hosts. It should always be enabled + * unless you know for sure amplification cannot be a problem in the + * environment in which your server operates. + * + * \warning Disabling this can ba a security risk! (see above) + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Comment this to disable support for HelloVerifyRequest. + */ +// #define MBEDTLS_SSL_DTLS_HELLO_VERIFY + +/** + * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + * + * Enable server-side support for clients that reconnect from the same port. + * + * Some clients unexpectedly close the connection and try to reconnect using the + * same source port. This needs special support from the server to handle the + * new connection securely, as described in section 4.2.8 of RFC 6347. This + * flag enables that support. + * + * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Comment this to disable support for clients reusing the source port. + */ +// #define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + +/** + * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT + * + * Enable support for a limit of records with bad MAC. + * + * See mbedtls_ssl_conf_dtls_badmac_limit(). + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + */ +// #define MBEDTLS_SSL_DTLS_BADMAC_LIMIT + +/** + * \def MBEDTLS_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * Client-side, provides full support for session tickets (maintainance of a + * session store remains the responsibility of the application, though). + * Server-side, you also need to provide callbacks for writing and parsing + * tickets, including authenticated encryption and key management. Example + * callbacks are provided by MBEDTLS_SSL_TICKET_C. + * + * Comment this macro to disable support for SSL session tickets + */ +// #define MBEDTLS_SSL_SESSION_TICKETS + +/** + * \def MBEDTLS_SSL_EXPORT_KEYS + * + * Enable support for exporting key block and master secret. + * This is required for certain users of TLS, e.g. EAP-TLS. + * + * Comment this macro to disable support for key export + */ +// #define MBEDTLS_SSL_EXPORT_KEYS + +/** + * \def MBEDTLS_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + * + * Comment this macro to disable support for server name indication in SSL + */ +// #define MBEDTLS_SSL_SERVER_NAME_INDICATION + +/** + * \def MBEDTLS_SSL_TRUNCATED_HMAC + * + * Enable support for RFC 6066 truncated HMAC in SSL. + * + * Comment this macro to disable support for truncated HMAC in SSL + */ +// #define MBEDTLS_SSL_TRUNCATED_HMAC + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +// #define MBEDTLS_VERSION_FEATURES + +/** + * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an extension in a v1 or v2 certificate. + * + * Uncomment to prevent an error. + */ +//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 + +/** + * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * \warning Depending on your PKI use, enabling this can be a security risk! + * + * Uncomment to prevent an error. + */ +//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + +/** + * \def MBEDTLS_X509_CHECK_KEY_USAGE + * + * Enable verification of the keyUsage extension (CA and leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused + * (intermediate) CA and leaf certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip keyUsage checking for both CA and leaf certificates. + */ +// #define MBEDTLS_X509_CHECK_KEY_USAGE + +/** + * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + * + * Enable verification of the extendedKeyUsage extension (leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip extendedKeyUsage checking for certificates. + */ +// #define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + +/** + * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +// #define MBEDTLS_X509_RSASSA_PSS_SUPPORT + +/** + * \def MBEDTLS_ZLIB_SUPPORT + * + * If set, the SSL/TLS module uses ZLIB to support compression and + * decompression of packet data. + * + * \warning TLS-level compression MAY REDUCE SECURITY! See for example the + * CRIME attack. Before enabling this option, you should examine with care if + * CRIME or similar exploits may be a applicable to your use case. + * + * \note Currently compression can't be used with DTLS. + * + * Used in: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This feature requires zlib library and headers to be present. + * + * Uncomment to enable use of ZLIB + */ +//#define MBEDTLS_ZLIB_SUPPORT +/* \} name SECTION: mbed TLS feature support */ + +/** + * \name SECTION: mbed TLS modules + * + * This section enables or disables entire modules in mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +// #define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/ssl_tls.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_ARC4_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +// #define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/x509write_csr.c + */ +// #define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +// #define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +// #define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +// #define MBEDTLS_BLOWFISH_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +// #define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * This module is used for testing (ssl_client/server). + */ +// #define MBEDTLS_CERTS_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ssl_tls.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +//#define MBEDTLS_CMAC_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-256-based random generator. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C + * + * This module provides the CTR_DRBG AES-256 random number generator. + */ +// #define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +// #define MBEDTLS_DEBUG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + */ +// #define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + */ +// #define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +// #define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C + */ +// #define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECJPAKE_C + * + * Enable the elliptic curve J-PAKE library. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Module: library/ecjpake.c + * Caller: + * + * This module is used by the following key exchanges: + * ECJPAKE + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C + */ +//#define MBEDTLS_ECJPAKE_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * library/ecjpake.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +// #define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +// #define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +// #define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +// #define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: MBEDTLS_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define MBEDTLS_HAVEGE_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +// #define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +// #define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + */ +//#define MBEDTLS_MD2_C + +/** + * \def MBEDTLS_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + */ +//#define MBEDTLS_MD4_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for SSL/TLS and X.509. + * PEM_PARSE uses MD5 for decrypting encrypted keys. + */ +// #define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_NET_C + * + * Enable the TCP and UDP over IPv6/IPv4 networking routines. + * + * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) + * and Windows. For other platforms, you'll want to disable it, and write your + * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/net_sockets.c + * + * This module provides networking routines. + */ +//#define MBEDTLS_NET_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +// #define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +// #define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +// // #define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * Caller: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +// #define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +// #define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +// #define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +// #define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS11_C + * + * Enable wrapper for PKCS#11 smartcard support. + * + * Module: library/pkcs11.c + * Caller: library/pk.c + * + * Requires: MBEDTLS_PK_C + * + * This module enables SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) + */ +//#define MBEDTLS_PKCS11_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * Can use: MBEDTLS_ARC4_C + * + * This module enables PKCS#12 functions. + */ +// #define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other module rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +// #define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +// #define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +// #define MBEDTLS_RSA_C + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509write_crt.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. + */ +// #define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +// #define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This module adds support for SHA-384 and SHA-512. + */ +// #define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: MBEDTLS_SSL_CACHE_C + */ +// #define MBEDTLS_SSL_CACHE_C + +/** + * \def MBEDTLS_SSL_COOKIE_C + * + * Enable basic implementation of DTLS cookies for hello verification. + * + * Module: library/ssl_cookie.c + * Caller: + */ +// #define MBEDTLS_SSL_COOKIE_C + +/** + * \def MBEDTLS_SSL_TICKET_C + * + * Enable an implementation of TLS server-side callbacks for session tickets. + * + * Module: library/ssl_ticket.c + * Caller: + * + * Requires: MBEDTLS_CIPHER_C + */ +// #define MBEDTLS_SSL_TICKET_C + +/** + * \def MBEDTLS_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +// #define MBEDTLS_SSL_CLI_C + +/** + * \def MBEDTLS_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +// #define MBEDTLS_SSL_SRV_C + +/** + * \def MBEDTLS_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * and at least one of the MBEDTLS_SSL_PROTO_XXX defines + * + * This module is required for SSL/TLS. + */ +// #define MBEDTLS_SSL_TLS_C + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within mbed TLS + */ +//#define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by + * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide + * your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +// #define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, + * MBEDTLS_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +// #define MBEDTLS_X509_USE_C + +/** + * \def MBEDTLS_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ +// #define MBEDTLS_X509_CRT_PARSE_C + +/** + * \def MBEDTLS_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/x509_crl.c + * Caller: library/x509_crt.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +// #define MBEDTLS_X509_CRL_PARSE_C + +/** + * \def MBEDTLS_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +// #define MBEDTLS_X509_CSR_PARSE_C + +/** + * \def MBEDTLS_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +// #define MBEDTLS_X509_CREATE_C + +/** + * \def MBEDTLS_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +// #define MBEDTLS_X509_CRT_WRITE_C + +/** + * \def MBEDTLS_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ +// #define MBEDTLS_X509_CSR_WRITE_C + +/** + * \def MBEDTLS_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +// #define MBEDTLS_XTEA_C + +/* \} name SECTION: mbed TLS modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ + +/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ + +/* SSL Cache options */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ +//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ +//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ +//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/* X509 options */ +//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ +//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ + +/* \} name SECTION: Customisation configuration options */ + +/* Target and application specific configurations */ +//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h" + +#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE) +#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE +#endif + +/* + * Allow user to override any previous default. + * + * Use two macro names for that, as: + * - with yotta the prefix YOTTA_CFG_ is forced + * - without yotta is looks weird to have a YOTTA prefix. + */ +#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE) +#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE +#elif defined(MBEDTLS_USER_CONFIG_FILE) +#include MBEDTLS_USER_CONFIG_FILE +#endif + +#include "check_config.h" + +#endif /* MBEDTLS_CONFIG_H */ diff --git a/lib/mbedtls/include/mbedtls/platform.h b/lib/mbedtls/include/mbedtls/platform.h new file mode 100644 index 000000000..b1b019e55 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/platform.h @@ -0,0 +1,295 @@ +/** + * \file platform.h + * + * \brief mbed TLS Platform abstraction layer + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_PLATFORM_H +#define MBEDTLS_PLATFORM_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) +#include +#include +#include +#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +#if defined(_WIN32) +#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */ +#else +#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use */ +#endif +#endif +#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) +#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) +#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) +#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_FREE) +#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT) +#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< Default exit value to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< Default exit value to use */ +#endif +#if defined(MBEDTLS_FS_IO) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" +#endif +#endif /* MBEDTLS_FS_IO */ +#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) +#include MBEDTLS_PLATFORM_STD_MEM_HDR +#endif +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + + +/* \} name SECTION: Module settings */ + +/* + * The function pointers for calloc and free + */ +#if defined(MBEDTLS_PLATFORM_MEMORY) +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ + defined(MBEDTLS_PLATFORM_CALLOC_MACRO) +#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO +#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO +#else +/* For size_t */ +#include +extern void * (*mbedtls_calloc)( size_t n, size_t size ); +extern void (*mbedtls_free)( void *ptr ); + +/** + * \brief Set your own memory implementation function pointers + * + * \param calloc_func the calloc function implementation + * \param free_func the free function implementation + * + * \return 0 if successful + */ +int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), + void (*free_func)( void * ) ); +#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ +#else /* !MBEDTLS_PLATFORM_MEMORY */ +#define mbedtls_free free +#define mbedtls_calloc calloc +#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ + +/* + * The function pointers for fprintf + */ +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +/* We need FILE * */ +#include +extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... ); + +/** + * \brief Set your own fprintf function pointer + * + * \param fprintf_func the fprintf function implementation + * + * \return 0 + */ +int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, + ... ) ); +#else +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) +#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO +#else +#define mbedtls_fprintf fprintf +#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ + +/* + * The function pointers for printf + */ +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) +extern int (*mbedtls_printf)( const char *format, ... ); + +/** + * \brief Set your own printf function pointer + * + * \param printf_func the printf function implementation + * + * \return 0 + */ +int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); +#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) +#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO +#else +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ + +/* + * The function pointers for snprintf + * + * The snprintf implementation should conform to C99: + * - it *must* always correctly zero-terminate the buffer + * (except when n == 0, then it must leave the buffer untouched) + * - however it is acceptable to return -1 instead of the required length when + * the destination buffer is too short. + */ +#if defined(_WIN32) +/* For Windows (inc. MSYS2), we provide our own fixed implementation */ +int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); + +/** + * \brief Set your own snprintf function pointer + * + * \param snprintf_func the snprintf function implementation + * + * \return 0 + */ +int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, + const char * format, ... ) ); +#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) +#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO +#else +#define mbedtls_snprintf snprintf +#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ + +/* + * The function pointers for exit + */ +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) +extern void (*mbedtls_exit)( int status ); + +/** + * \brief Set your own exit function pointer + * + * \param exit_func the exit function implementation + * + * \return 0 + */ +int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); +#else +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) +#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO +#else +#define mbedtls_exit exit +#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ + +/* + * The default exit values + */ +#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS +#else +#define MBEDTLS_EXIT_SUCCESS 0 +#endif +#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE +#else +#define MBEDTLS_EXIT_FAILURE 1 +#endif + +/* + * The function pointers for reading from and writing a seed file to + * Non-Volatile storage (NV) in a platform-independent way + * + * Only enabled when the NV seed entropy source is enabled + */ +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Internal standard platform definitions */ +int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ); +int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ); +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ); +extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ); + +/** + * \brief Set your own seed file writing/reading functions + * + * \param nv_seed_read_func the seed reading function implementation + * \param nv_seed_write_func the seed writing function implementation + * + * \return 0 + */ +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), + int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) + ); +#else +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ + defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) +#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO +#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO +#else +#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read +#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write +#endif +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#ifdef __cplusplus +} +#endif + +#endif /* platform.h */ diff --git a/lib/mbedtls/include/mbedtls/platform_time.h b/lib/mbedtls/include/mbedtls/platform_time.h new file mode 100644 index 000000000..abb343142 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/platform_time.h @@ -0,0 +1,81 @@ +/** + * \file platform_time.h + * + * \brief mbed TLS Platform time abstraction + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_PLATFORM_TIME_H +#define MBEDTLS_PLATFORM_TIME_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +/* + * The time_t datatype + */ +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) +typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; +#else +/* For time_t */ +#include +typedef time_t mbedtls_time_t; +#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ + +/* + * The function pointers for time + */ +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); + +/** + * \brief Set your own time function pointer + * + * \param time_func the time function implementation + * + * \return 0 + */ +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); +#else +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) +#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO +#else +#define mbedtls_time time +#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* platform_time.h */ diff --git a/lib/mbedtls/src/aes.c b/lib/mbedtls/src/aes.c new file mode 100644 index 000000000..a186dee98 --- /dev/null +++ b/lib/mbedtls/src/aes.c @@ -0,0 +1,1492 @@ +/* + * FIPS-197 compliant AES implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_AES_C) + +#include + +#include "mbedtls/aes.h" +#if defined(MBEDTLS_PADLOCK_C) +#include "mbedtls/padlock.h" +#endif +#if defined(MBEDTLS_AESNI_C) +#include "mbedtls/aesni.h" +#endif + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_AES_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +#if defined(MBEDTLS_PADLOCK_C) && \ + ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) +static int aes_padlock_ace = -1; +#endif + +#if defined(MBEDTLS_AES_ROM_TABLES) +/* + * Forward S-box + */ +static const unsigned char FSb[256] = +{ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +/* + * Forward tables + */ +#define FT \ +\ + V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ + V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ + V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ + V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ + V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ + V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ + V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ + V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ + V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ + V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ + V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ + V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ + V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ + V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ + V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ + V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ + V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ + V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ + V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ + V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ + V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ + V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ + V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ + V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ + V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ + V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ + V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ + V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ + V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ + V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ + V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ + V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ + V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ + V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ + V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ + V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ + V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ + V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ + V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ + V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ + V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ + V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ + V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ + V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ + V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ + V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ + V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ + V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ + V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ + V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ + V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ + V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ + V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ + V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ + V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ + V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ + V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ + V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ + V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ + V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ + V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ + V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ + V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ + V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t FT0[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t FT1[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t FT2[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t FT3[256] = { FT }; +#undef V + +#undef FT + +/* + * Reverse S-box + */ +static const unsigned char RSb[256] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* + * Reverse tables + */ +#define RT \ +\ + V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ + V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ + V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ + V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ + V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ + V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ + V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ + V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ + V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ + V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ + V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ + V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ + V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ + V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ + V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ + V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ + V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ + V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ + V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ + V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ + V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ + V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ + V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ + V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ + V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ + V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ + V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ + V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ + V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ + V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ + V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ + V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ + V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ + V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ + V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ + V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ + V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ + V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ + V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ + V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ + V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ + V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ + V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ + V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ + V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ + V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ + V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ + V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ + V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ + V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ + V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ + V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ + V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ + V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ + V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ + V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ + V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ + V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ + V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ + V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ + V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ + V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ + V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ + V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t RT0[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t RT1[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t RT2[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t RT3[256] = { RT }; +#undef V + +#undef RT + +/* + * Round constants + */ +static const uint32_t RCON[10] = +{ + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x0000001B, 0x00000036 +}; + +#else /* MBEDTLS_AES_ROM_TABLES */ + +/* + * Forward S-box & tables + */ +static unsigned char FSb[256]; +static uint32_t FT0[256]; +static uint32_t FT1[256]; +static uint32_t FT2[256]; +static uint32_t FT3[256]; + +/* + * Reverse S-box & tables + */ +static unsigned char RSb[256]; +static uint32_t RT0[256]; +static uint32_t RT1[256]; +static uint32_t RT2[256]; +static uint32_t RT3[256]; + +/* + * Round constants + */ +static uint32_t RCON[10]; + +/* + * Tables generation code + */ +#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) +#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) +#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) + +static int aes_init_done = 0; + +static void aes_gen_tables( void ) +{ + int i, x, y, z; + int pow[256]; + int log[256]; + + /* + * compute pow and log tables over GF(2^8) + */ + for( i = 0, x = 1; i < 256; i++ ) + { + pow[i] = x; + log[x] = i; + x = ( x ^ XTIME( x ) ) & 0xFF; + } + + /* + * calculate the round constants + */ + for( i = 0, x = 1; i < 10; i++ ) + { + RCON[i] = (uint32_t) x; + x = XTIME( x ) & 0xFF; + } + + /* + * generate the forward and reverse S-boxes + */ + FSb[0x00] = 0x63; + RSb[0x63] = 0x00; + + for( i = 1; i < 256; i++ ) + { + x = pow[255 - log[i]]; + + y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y ^ 0x63; + + FSb[i] = (unsigned char) x; + RSb[x] = (unsigned char) i; + } + + /* + * generate the forward and reverse tables + */ + for( i = 0; i < 256; i++ ) + { + x = FSb[i]; + y = XTIME( x ) & 0xFF; + z = ( y ^ x ) & 0xFF; + + FT0[i] = ( (uint32_t) y ) ^ + ( (uint32_t) x << 8 ) ^ + ( (uint32_t) x << 16 ) ^ + ( (uint32_t) z << 24 ); + + FT1[i] = ROTL8( FT0[i] ); + FT2[i] = ROTL8( FT1[i] ); + FT3[i] = ROTL8( FT2[i] ); + + x = RSb[i]; + + RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ + ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ + ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ + ( (uint32_t) MUL( 0x0B, x ) << 24 ); + + RT1[i] = ROTL8( RT0[i] ); + RT2[i] = ROTL8( RT1[i] ); + RT3[i] = ROTL8( RT2[i] ); + } +} + +#endif /* MBEDTLS_AES_ROM_TABLES */ + +void mbedtls_aes_init( mbedtls_aes_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_aes_context ) ); +} + +void mbedtls_aes_free( mbedtls_aes_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_aes_context ) ); +} + +/* + * AES key schedule (encryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + unsigned int i; + uint32_t *RK; + +#if !defined(MBEDTLS_AES_ROM_TABLES) + if( aes_init_done == 0 ) + { + aes_gen_tables(); + aes_init_done = 1; + + } +#endif + + switch( keybits ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + } + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); +#endif + + for( i = 0; i < ( keybits >> 5 ); i++ ) + { + GET_UINT32_LE( RK[i], key, i << 2 ); + } + + switch( ctx->nr ) + { + case 10: + + for( i = 0; i < 10; i++, RK += 4 ) + { + RK[4] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); + + RK[5] = RK[1] ^ RK[4]; + RK[6] = RK[2] ^ RK[5]; + RK[7] = RK[3] ^ RK[6]; + } + break; + + case 12: + + for( i = 0; i < 8; i++, RK += 6 ) + { + RK[6] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); + + RK[7] = RK[1] ^ RK[6]; + RK[8] = RK[2] ^ RK[7]; + RK[9] = RK[3] ^ RK[8]; + RK[10] = RK[4] ^ RK[9]; + RK[11] = RK[5] ^ RK[10]; + } + break; + + case 14: + + for( i = 0; i < 7; i++, RK += 8 ) + { + RK[8] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); + + RK[9] = RK[1] ^ RK[8]; + RK[10] = RK[2] ^ RK[9]; + RK[11] = RK[3] ^ RK[10]; + + RK[12] = RK[4] ^ + ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); + + RK[13] = RK[5] ^ RK[12]; + RK[14] = RK[6] ^ RK[13]; + RK[15] = RK[7] ^ RK[14]; + } + break; + } + + return( 0 ); +} +#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ + +/* + * AES key schedule (decryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + int i, j, ret; + mbedtls_aes_context cty; + uint32_t *RK; + uint32_t *SK; + + mbedtls_aes_init( &cty ); + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + + /* Also checks keybits */ + if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) + goto exit; + + ctx->nr = cty.nr; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + { + mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, + (const unsigned char *) cty.rk, ctx->nr ); + goto exit; + } +#endif + + SK = cty.rk + cty.nr * 4; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) + { + for( j = 0; j < 4; j++, SK++ ) + { + *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ + RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ + RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ + RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; + } + } + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + +exit: + mbedtls_aes_free( &cty ); + + return( ret ); +} +#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ + +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ + FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ + FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y0 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ + FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ + FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y2 >> 24 ) & 0xFF ]; \ +} + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ + RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ + RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y2 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ + RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ + RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y0 >> 24 ) & 0xFF ]; \ +} + +/* + * AES-ECB block encryption + */ +#if !defined(MBEDTLS_AES_ENCRYPT_ALT) +void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); +} +#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ + +/* + * AES-ECB block decryption + */ +#if !defined(MBEDTLS_AES_DECRYPT_ALT) +void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); +} +#endif /* !MBEDTLS_AES_DECRYPT_ALT */ + +/* + * AES-ECB block encryption/decryption + */ +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); +#endif + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) + if( aes_padlock_ace ) + { + if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == MBEDTLS_AES_ENCRYPT ) + mbedtls_aes_encrypt( ctx, input, output ); + else + mbedtls_aes_decrypt( ctx, input, output ); + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * AES-CBC buffer encryption/decryption + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[16]; + + if( length % 16 ) + return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) + if( aes_padlock_ace ) + { + if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == MBEDTLS_AES_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + mbedtls_aes_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_aes_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == MBEDTLS_AES_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} + +/* + * AES-CFB8 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + unsigned char c; + unsigned char ov[17]; + + while( length-- ) + { + memcpy( ov, iv, 16 ); + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + if( mode == MBEDTLS_AES_DECRYPT ) + ov[16] = *input; + + c = *output++ = (unsigned char)( iv[0] ^ *input++ ); + + if( mode == MBEDTLS_AES_ENCRYPT ) + ov[16] = c; + + memcpy( iv, ov + 1, 16 ); + } + + return( 0 ); +} +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR buffer encryption/decryption + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block ); + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#endif /* !MBEDTLS_AES_ALT */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * AES test vectors from: + * + * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip + */ +static const unsigned char aes_test_ecb_dec[3][16] = +{ + { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, + 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, + { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, + 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, + { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, + 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } +}; + +static const unsigned char aes_test_ecb_enc[3][16] = +{ + { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, + 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, + { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, + 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, + { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, + 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const unsigned char aes_test_cbc_dec[3][16] = +{ + { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, + 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, + { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, + 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, + { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, + 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } +}; + +static const unsigned char aes_test_cbc_enc[3][16] = +{ + { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, + 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, + { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, + 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, + { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, + 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 test vectors from: + * + * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + */ +static const unsigned char aes_test_cfb128_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_cfb128_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_cfb128_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_cfb128_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, + 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, + 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, + 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, + 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, + 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, + 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, + 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, + 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, + 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, + 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, + 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, + 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, + 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, + 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc3686.html + */ + +static const unsigned char aes_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char aes_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char aes_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char aes_test_ctr_ct[3][48] = +{ + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } +}; + +static const int aes_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int mbedtls_aes_self_test( int verbose ) +{ + int ret = 0, i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; +#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) + unsigned char iv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char prv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) + size_t offset; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + int len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + mbedtls_aes_context ctx; + + memset( key, 0, 32 ); + mbedtls_aes_init( &ctx ); + + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( buf, 0, 16 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( iv , 0, 16 ); + memset( prv, 0, 16 ); + memset( buf, 0, 16 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[16]; + + mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + memcpy( tmp, prv, 16 ); + memcpy( prv, buf, 16 ); + memcpy( buf, tmp, 16 ); + } + + if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + /* + * CFB128 mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_cfb128_iv, 16 ); + memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); + + offset = 0; + mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + memcpy( buf, aes_test_cfb128_ct[u], 64 ); + mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + memcpy( buf, aes_test_cfb128_pt, 64 ); + mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CTR-128 (%s): ", + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); + memcpy( key, aes_test_ctr_key[u], 16 ); + + offset = 0; + mbedtls_aes_setkey_enc( &ctx, key, 128 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_ct[u], len ); + + mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_pt[u], len ); + + mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + + ret = 0; + +exit: + mbedtls_aes_free( &ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_AES_C */ diff --git a/lib/mbedtls/src/ccm.c b/lib/mbedtls/src/ccm.c new file mode 100644 index 000000000..13a8fd1a2 --- /dev/null +++ b/lib/mbedtls/src/ccm.c @@ -0,0 +1,464 @@ +/* + * NIST SP800-38C compliant CCM implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CCM_C) + +#include "mbedtls/ccm.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +/* + * Initialize context + */ +void mbedtls_ccm_init( mbedtls_ccm_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ccm_context ) ); +} + +int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + mbedtls_cipher_free( &ctx->cipher_ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Free context + */ +void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) +{ + mbedtls_cipher_free( &ctx->cipher_ctx ); + mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); +} + +/* + * Macros for common operations. + * Results in smaller compiled code than static inline functions. + */ + +/* + * Update the CBC-MAC state in y using a block in b + * (Always using b as the source helps the compiler optimise a bit better.) + */ +#define UPDATE_CBC_MAC \ + for( i = 0; i < 16; i++ ) \ + y[i] ^= b[i]; \ + \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ + return( ret ); + +/* + * Encrypt or decrypt a partial block with CTR + * Warning: using b for temporary storage! src and dst must not be b! + * This avoids allocating one more 16 bytes buffer while allowing src == dst. + */ +#define CTR_CRYPT( dst, src, len ) \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ + return( ret ); \ + \ + for( i = 0; i < len; i++ ) \ + dst[i] = src[i] ^ b[i]; + +/* + * Authenticated encryption or decryption + */ +static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char i; + unsigned char q; + size_t len_left, olen; + unsigned char b[16]; + unsigned char y[16]; + unsigned char ctr[16]; + const unsigned char *src; + unsigned char *dst; + + /* + * Check length requirements: SP800-38C A.1 + * Additional requirement: a < 2^16 - 2^8 to simplify the code. + * 'length' checked later (when writing it to the first block) + */ + if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + /* Also implies q is within bounds */ + if( iv_len < 7 || iv_len > 13 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + if( add_len > 0xFF00 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + q = 16 - 1 - (unsigned char) iv_len; + + /* + * First block B_0: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 length + * + * With flags as (bits): + * 7 0 + * 6 add present? + * 5 .. 3 (t - 2) / 2 + * 2 .. 0 q - 1 + */ + b[0] = 0; + b[0] |= ( add_len > 0 ) << 6; + b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; + b[0] |= q - 1; + + memcpy( b + 1, iv, iv_len ); + + for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) + b[15-i] = (unsigned char)( len_left & 0xFF ); + + if( len_left > 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + + /* Start CBC-MAC with first block */ + memset( y, 0, 16 ); + UPDATE_CBC_MAC; + + /* + * If there is additional data, update CBC-MAC with + * add_len, add, 0 (padding to a block boundary) + */ + if( add_len > 0 ) + { + size_t use_len; + len_left = add_len; + src = add; + + memset( b, 0, 16 ); + b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); + b[1] = (unsigned char)( ( add_len ) & 0xFF ); + + use_len = len_left < 16 - 2 ? len_left : 16 - 2; + memcpy( b + 2, src, use_len ); + len_left -= use_len; + src += use_len; + + UPDATE_CBC_MAC; + + while( len_left > 0 ) + { + use_len = len_left > 16 ? 16 : len_left; + + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + + len_left -= use_len; + src += use_len; + } + } + + /* + * Prepare counter block for encryption: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 counter (initially 1) + * + * With flags as (bits): + * 7 .. 3 0 + * 2 .. 0 q - 1 + */ + ctr[0] = q - 1; + memcpy( ctr + 1, iv, iv_len ); + memset( ctr + 1 + iv_len, 0, q ); + ctr[15] = 1; + + /* + * Authenticate and {en,de}crypt the message. + * + * The only difference between encryption and decryption is + * the respective order of authentication and {en,de}cryption. + */ + len_left = length; + src = input; + dst = output; + + while( len_left > 0 ) + { + size_t use_len = len_left > 16 ? 16 : len_left; + + if( mode == CCM_ENCRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + } + + CTR_CRYPT( dst, src, use_len ); + + if( mode == CCM_DECRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, dst, use_len ); + UPDATE_CBC_MAC; + } + + dst += use_len; + src += use_len; + len_left -= use_len; + + /* + * Increment counter. + * No need to check for overflow thanks to the length check above. + */ + for( i = 0; i < q; i++ ) + if( ++ctr[15-i] != 0 ) + break; + } + + /* + * Authentication: reset counter and crypt/mask internal tag + */ + for( i = 0; i < q; i++ ) + ctr[15-i] = 0; + + CTR_CRYPT( y, y, 16 ); + memcpy( tag, y, tag_len ); + + return( 0 ); +} + +/* + * Authenticated encryption + */ +int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, + add, add_len, input, output, tag, tag_len ) ); +} + +/* + * Authenticated decryption + */ +int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char check_tag[16]; + unsigned char i; + int diff; + + if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, check_tag, tag_len ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + mbedtls_zeroize( output, length ); + return( MBEDTLS_ERR_CCM_AUTH_FAILED ); + } + + return( 0 ); +} + + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/* + * Examples 1 to 3 from SP800-38C Appendix C + */ + +#define NB_TESTS 3 + +/* + * The data is the same for all tests, only the used length changes + */ +static const unsigned char key[] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f +}; + +static const unsigned char iv[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b +}; + +static const unsigned char ad[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 +}; + +static const unsigned char msg[] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +}; + +static const size_t iv_len [NB_TESTS] = { 7, 8, 12 }; +static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; +static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; +static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; + +static const unsigned char res[NB_TESTS][32] = { + { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, + { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, + 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, + 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, + { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, + 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, + 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, + 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } +}; + +int mbedtls_ccm_self_test( int verbose ) +{ + mbedtls_ccm_context ctx; + unsigned char out[32]; + size_t i; + int ret; + + mbedtls_ccm_init( &ctx ); + + if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( " CCM: setup failed" ); + + return( 1 ); + } + + for( i = 0; i < NB_TESTS; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); + + ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + msg, out, + out + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + res[i], out, + res[i] + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, msg, msg_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + mbedtls_ccm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#endif /* MBEDTLS_CCM_C */ diff --git a/lib/mbedtls/src/cipher.c b/lib/mbedtls/src/cipher.c new file mode 100644 index 000000000..a88343869 --- /dev/null +++ b/lib/mbedtls/src/cipher.c @@ -0,0 +1,917 @@ +/** + * \file cipher.c + * + * \brief Generic cipher wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CIPHER_C) + +#include "mbedtls/cipher.h" +#include "mbedtls/cipher_internal.h" + +#include +#include + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CMAC_C) +#include "mbedtls/cmac.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) +#define MBEDTLS_CIPHER_MODE_STREAM +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +static int supported_init = 0; + +const int *mbedtls_cipher_list( void ) +{ + const mbedtls_cipher_definition_t *def; + int *type; + + if( ! supported_init ) + { + def = mbedtls_cipher_definitions; + type = mbedtls_cipher_supported; + + while( def->type != 0 ) + *type++ = (*def++).type; + + *type = 0; + + supported_init = 1; + } + + return( mbedtls_cipher_supported ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ) +{ + const mbedtls_cipher_definition_t *def; + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( def->type == cipher_type ) + return( def->info ); + + return( NULL ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ) +{ + const mbedtls_cipher_definition_t *def; + + if( NULL == cipher_name ) + return( NULL ); + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( ! strcmp( def->info->name, cipher_name ) ) + return( def->info ); + + return( NULL ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode ) +{ + const mbedtls_cipher_definition_t *def; + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( def->info->base->cipher == cipher_id && + def->info->key_bitlen == (unsigned) key_bitlen && + def->info->mode == mode ) + return( def->info ); + + return( NULL ); +} + +void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); +} + +void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) +{ + if( ctx == NULL ) + return; + +#if defined(MBEDTLS_CMAC_C) + if( ctx->cmac_ctx ) + { + mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) ); + mbedtls_free( ctx->cmac_ctx ); + } +#endif + + if( ctx->cipher_ctx ) + ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); + + mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); +} + +int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) +{ + if( NULL == cipher_info || NULL == ctx ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); + + if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) + return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); + + ctx->cipher_info = cipher_info; + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /* + * Ignore possible errors caused by a cipher mode that doesn't use padding + */ +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); +#else + (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); +#endif +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + + return( 0 ); +} + +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, + int key_bitlen, const mbedtls_operation_t operation ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && + (int) ctx->cipher_info->key_bitlen != key_bitlen ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + ctx->key_bitlen = key_bitlen; + ctx->operation = operation; + + /* + * For CFB and CTR mode always use the encryption key schedule + */ + if( MBEDTLS_ENCRYPT == operation || + MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) + { + return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, + ctx->key_bitlen ); + } + + if( MBEDTLS_DECRYPT == operation ) + return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, + ctx->key_bitlen ); + + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); +} + +int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len ) +{ + size_t actual_iv_size; + + if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + /* avoid buffer overflow in ctx->iv */ + if( iv_len > MBEDTLS_MAX_IV_LENGTH ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) + actual_iv_size = iv_len; + else + { + actual_iv_size = ctx->cipher_info->iv_size; + + /* avoid reading past the end of input buffer */ + if( actual_iv_size > iv_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + memcpy( ctx->iv, iv, actual_iv_size ); + ctx->iv_size = actual_iv_size; + + return( 0 ); +} + +int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + ctx->unprocessed_len = 0; + + return( 0 ); +} + +#if defined(MBEDTLS_GCM_C) +int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, + ctx->iv, ctx->iv_size, ad, ad_len ); + } + + return( 0 ); +} +#endif /* MBEDTLS_GCM_C */ + +int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ) +{ + int ret; + size_t block_size = 0; + + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + *olen = 0; + block_size = mbedtls_cipher_get_block_size( ctx ); + + if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) + { + if( ilen != block_size ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + *olen = ilen; + + if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, + ctx->operation, input, output ) ) ) + { + return( ret ); + } + + return( 0 ); + } + +#if defined(MBEDTLS_GCM_C) + if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) + { + *olen = ilen; + return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, + output ); + } +#endif + + if ( 0 == block_size ) + { + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; + } + + if( input == output && + ( ctx->unprocessed_len != 0 || ilen % block_size ) ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) + { + size_t copy_len = 0; + + /* + * If there is not enough data for a full block, cache it. + */ + if( ( ctx->operation == MBEDTLS_DECRYPT && + ilen + ctx->unprocessed_len <= block_size ) || + ( ctx->operation == MBEDTLS_ENCRYPT && + ilen + ctx->unprocessed_len < block_size ) ) + { + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + ilen ); + + ctx->unprocessed_len += ilen; + return( 0 ); + } + + /* + * Process cached data first + */ + if( 0 != ctx->unprocessed_len ) + { + copy_len = block_size - ctx->unprocessed_len; + + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + copy_len ); + + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, block_size, ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + *olen += block_size; + output += block_size; + ctx->unprocessed_len = 0; + + input += copy_len; + ilen -= copy_len; + } + + /* + * Cache final, incomplete block + */ + if( 0 != ilen ) + { + if( 0 == block_size ) + { + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; + } + + copy_len = ilen % block_size; + if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT ) + copy_len = block_size; + + memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), + copy_len ); + + ctx->unprocessed_len += copy_len; + ilen -= copy_len; + } + + /* + * Process remaining full blocks + */ + if( ilen ) + { + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, ilen, ctx->iv, input, output ) ) ) + { + return( ret ); + } + + *olen += ilen; + } + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) + { + if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, + ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, + input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) + { + if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, + ilen, &ctx->unprocessed_len, ctx->iv, + ctx->unprocessed_data, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) + { + if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, + ilen, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_STREAM */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) +/* + * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len + */ +static void add_pkcs_padding( unsigned char *output, size_t output_len, + size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i; + + for( i = 0; i < padding_len; i++ ) + output[data_len + i] = (unsigned char) padding_len; +} + +static int get_pkcs_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len, + * so pick input_len, which is usually 8 or 16 (one block) */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len; i++ ) + bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ + +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) +/* + * One and zeros padding: fill with 80 00 ... 00 + */ +static void add_one_and_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + output[data_len] = 0x80; + for( i = 1; i < padding_len; i++ ) + output[data_len + i] = 0x00; +} + +static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done, bad; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + bad = 0xFF; + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i-1] != 0 ); + *data_len |= ( i - 1 ) * ( done != prev_done ); + bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); + } + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); + +} +#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) +/* + * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length + */ +static void add_zeros_and_len_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + for( i = 1; i < padding_len; i++ ) + output[data_len + i - 1] = 0x00; + output[output_len - 1] = (unsigned char) padding_len; +} + +static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len - 1; i++ ) + bad |= input[i] * ( i >= pad_idx ); + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) +/* + * Zero padding: fill with 00 ... 00 + */ +static void add_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t i; + + for( i = data_len; i < output_len; i++ ) + output[i] = 0x00; +} + +static int get_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i-1] != 0 ); + *data_len |= i * ( done != prev_done ); + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ + +/* + * No padding: don't pad :) + * + * There is no add_padding function (check for NULL in mbedtls_cipher_finish) + * but a trivial get_padding function + */ +static int get_no_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = input_len; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen ) +{ + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *olen = 0; + + if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_CTR == ctx->cipher_info->mode || + MBEDTLS_MODE_GCM == ctx->cipher_info->mode || + MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) + { + return( 0 ); + } + + if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) + { + if( ctx->unprocessed_len != 0 ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) + { + int ret = 0; + + if( MBEDTLS_ENCRYPT == ctx->operation ) + { + /* check for 'no padding' mode */ + if( NULL == ctx->add_padding ) + { + if( 0 != ctx->unprocessed_len ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + + ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), + ctx->unprocessed_len ); + } + else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) + { + /* + * For decrypt operations, expect a full block, + * or an empty block if no padding + */ + if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) + return( 0 ); + + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + } + + /* cipher block */ + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + /* Set output size for decryption */ + if( MBEDTLS_DECRYPT == ctx->operation ) + return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), + olen ); + + /* Set output size for encryption */ + *olen = mbedtls_cipher_get_block_size( ctx ); + return( 0 ); + } +#else + ((void) output); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ) +{ + if( NULL == ctx || + MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + switch( mode ) + { +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + case MBEDTLS_PADDING_PKCS7: + ctx->add_padding = add_pkcs_padding; + ctx->get_padding = get_pkcs_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) + case MBEDTLS_PADDING_ONE_AND_ZEROS: + ctx->add_padding = add_one_and_zeros_padding; + ctx->get_padding = get_one_and_zeros_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) + case MBEDTLS_PADDING_ZEROS_AND_LEN: + ctx->add_padding = add_zeros_and_len_padding; + ctx->get_padding = get_zeros_and_len_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) + case MBEDTLS_PADDING_ZEROS: + ctx->add_padding = add_zeros_padding; + ctx->get_padding = get_zeros_padding; + break; +#endif + case MBEDTLS_PADDING_NONE: + ctx->add_padding = NULL; + ctx->get_padding = get_no_padding; + break; + + default: + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +#if defined(MBEDTLS_GCM_C) +int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ) +{ + if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_ENCRYPT != ctx->operation ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); + + return( 0 ); +} + +int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + + if( NULL == ctx || NULL == ctx->cipher_info || + MBEDTLS_DECRYPT != ctx->operation ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + unsigned char check_tag[16]; + size_t i; + int diff; + + if( tag_len > sizeof( check_tag ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, + check_tag, tag_len ) ) ) + { + return( ret ); + } + + /* Check the tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); + + return( 0 ); + } + + return( 0 ); +} +#endif /* MBEDTLS_GCM_C */ + +/* + * Packet-oriented wrapper for non-AEAD modes + */ +int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ) +{ + int ret; + size_t finish_olen; + + if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) + return( ret ); + + *olen += finish_olen; + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) +/* + * Packet-oriented encryption for AEAD modes + */ +int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ) +{ +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, + iv, iv_len, ad, ad_len, input, output, + tag_len, tag ) ); + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, input, output, + tag, tag_len ) ); + } +#endif /* MBEDTLS_CCM_C */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +/* + * Packet-oriented decryption for AEAD modes + */ +int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ) +{ +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + tag, tag_len, input, output ); + + if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + input, output, tag, tag_len ); + + if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_CCM_C */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/lib/mbedtls/src/cipher_wrap.c b/lib/mbedtls/src/cipher_wrap.c new file mode 100644 index 000000000..dc76af8ff --- /dev/null +++ b/lib/mbedtls/src/cipher_wrap.c @@ -0,0 +1,1451 @@ +/** + * \file cipher_wrap.c + * + * \brief Generic cipher wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CIPHER_C) + +#include "mbedtls/cipher_internal.h" + +#if defined(MBEDTLS_AES_C) +#include "mbedtls/aes.h" +#endif + +#if defined(MBEDTLS_ARC4_C) +#include "mbedtls/arc4.h" +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#include "mbedtls/camellia.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "mbedtls/des.h" +#endif + +#if defined(MBEDTLS_BLOWFISH_C) +#include "mbedtls/blowfish.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#include +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_GCM_C) +/* shared by all GCM ciphers */ +static void *gcm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); + + if( ctx != NULL ) + mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); + + return( ctx ); +} + +static void gcm_ctx_free( void *ctx ) +{ + mbedtls_gcm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +/* shared by all CCM ciphers */ +static void *ccm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); + + if( ctx != NULL ) + mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); + + return( ctx ); +} + +static void ccm_ctx_free( void *ctx ) +{ + mbedtls_ccm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_CCM_C */ + +#if defined(MBEDTLS_AES_C) + +static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, + stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static void * aes_ctx_alloc( void ) +{ + mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); + + if( aes == NULL ) + return( NULL ); + + mbedtls_aes_init( aes ); + + return( aes ); +} + +static void aes_ctx_free( void *ctx ) +{ + mbedtls_aes_free( (mbedtls_aes_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t aes_info = { + MBEDTLS_CIPHER_ID_AES, + aes_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + aes_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + aes_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + aes_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + aes_setkey_enc_wrap, + aes_setkey_dec_wrap, + aes_ctx_alloc, + aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_ecb_info = { + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "AES-128-ECB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ecb_info = { + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "AES-192-ECB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ecb_info = { + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "AES-256-ECB", + 16, + 0, + 16, + &aes_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t aes_128_cbc_info = { + MBEDTLS_CIPHER_AES_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "AES-128-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cbc_info = { + MBEDTLS_CIPHER_AES_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "AES-192-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cbc_info = { + MBEDTLS_CIPHER_AES_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "AES-256-CBC", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t aes_128_cfb128_info = { + MBEDTLS_CIPHER_AES_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "AES-128-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cfb128_info = { + MBEDTLS_CIPHER_AES_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "AES-192-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cfb128_info = { + MBEDTLS_CIPHER_AES_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "AES-256-CFB128", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t aes_128_ctr_info = { + MBEDTLS_CIPHER_AES_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "AES-128-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ctr_info = { + MBEDTLS_CIPHER_AES_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "AES-192-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ctr_info = { + MBEDTLS_CIPHER_AES_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "AES-256-CTR", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_aes_setkey_wrap, + gcm_aes_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_gcm_info = { + MBEDTLS_CIPHER_AES_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "AES-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_gcm_info = { + MBEDTLS_CIPHER_AES_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "AES-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_gcm_info = { + MBEDTLS_CIPHER_AES_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "AES-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_aes_setkey_wrap, + ccm_aes_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_ccm_info = { + MBEDTLS_CIPHER_AES_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "AES-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ccm_info = { + MBEDTLS_CIPHER_AES_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "AES-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ccm_info = { + MBEDTLS_CIPHER_AES_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "AES-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + +static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static void * camellia_ctx_alloc( void ) +{ + mbedtls_camellia_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_camellia_init( ctx ); + + return( ctx ); +} + +static void camellia_ctx_free( void *ctx ) +{ + mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + camellia_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + camellia_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + camellia_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + camellia_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + camellia_setkey_enc_wrap, + camellia_setkey_dec_wrap, + camellia_ctx_alloc, + camellia_ctx_free +}; + +static const mbedtls_cipher_info_t camellia_128_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "CAMELLIA-128-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "CAMELLIA-192-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "CAMELLIA-256-ECB", + 16, + 0, + 16, + &camellia_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t camellia_128_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "CAMELLIA-128-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "CAMELLIA-192-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "CAMELLIA-256-CBC", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t camellia_128_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "CAMELLIA-128-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "CAMELLIA-192-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "CAMELLIA-256-CFB128", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t camellia_128_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "CAMELLIA-128-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "CAMELLIA-192-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "CAMELLIA-256-CTR", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_camellia_setkey_wrap, + gcm_camellia_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "CAMELLIA-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "CAMELLIA-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "CAMELLIA-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_camellia_setkey_wrap, + ccm_camellia_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "CAMELLIA-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "CAMELLIA-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "CAMELLIA-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) + +static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); +} + +static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); +} + +static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); +} + +static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static void * des_ctx_alloc( void ) +{ + mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); + + if( des == NULL ) + return( NULL ); + + mbedtls_des_init( des ); + + return( des ); +} + +static void des_ctx_free( void *ctx ) +{ + mbedtls_des_free( (mbedtls_des_context *) ctx ); + mbedtls_free( ctx ); +} + +static void * des3_ctx_alloc( void ) +{ + mbedtls_des3_context *des3; + des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); + + if( des3 == NULL ) + return( NULL ); + + mbedtls_des3_init( des3 ); + + return( des3 ); +} + +static void des3_ctx_free( void *ctx ) +{ + mbedtls_des3_free( (mbedtls_des3_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t des_info = { + MBEDTLS_CIPHER_ID_DES, + des_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des_setkey_enc_wrap, + des_setkey_dec_wrap, + des_ctx_alloc, + des_ctx_free +}; + +static const mbedtls_cipher_info_t des_ecb_info = { + MBEDTLS_CIPHER_DES_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES, + "DES-ECB", + 8, + 0, + 8, + &des_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_cbc_info = { + MBEDTLS_CIPHER_DES_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES, + "DES-CBC", + 8, + 0, + 8, + &des_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede_info = { + MBEDTLS_CIPHER_ID_DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set2key_enc_wrap, + des3_set2key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede_ecb_info = { + MBEDTLS_CIPHER_DES_EDE_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-ECB", + 8, + 0, + 8, + &des_ede_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede_cbc_info = { + MBEDTLS_CIPHER_DES_EDE_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-CBC", + 8, + 0, + 8, + &des_ede_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede3_info = { + MBEDTLS_CIPHER_ID_3DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set3key_enc_wrap, + des3_set3key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede3_ecb_info = { + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-ECB", + 8, + 0, + 8, + &des_ede3_info +}; +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede3_cbc_info = { + MBEDTLS_CIPHER_DES_EDE3_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-CBC", + 8, + 0, + 8, + &des_ede3_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_BLOWFISH_C) + +static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, const unsigned char *input, + unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); +} + +static void * blowfish_ctx_alloc( void ) +{ + mbedtls_blowfish_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_blowfish_init( ctx ); + + return( ctx ); +} + +static void blowfish_ctx_free( void *ctx ) +{ + mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t blowfish_info = { + MBEDTLS_CIPHER_ID_BLOWFISH, + blowfish_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + blowfish_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + blowfish_crypt_cfb64_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + blowfish_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + blowfish_setkey_wrap, + blowfish_setkey_wrap, + blowfish_ctx_alloc, + blowfish_ctx_free +}; + +static const mbedtls_cipher_info_t blowfish_ecb_info = { + MBEDTLS_CIPHER_BLOWFISH_ECB, + MBEDTLS_MODE_ECB, + 128, + "BLOWFISH-ECB", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t blowfish_cbc_info = { + MBEDTLS_CIPHER_BLOWFISH_CBC, + MBEDTLS_MODE_CBC, + 128, + "BLOWFISH-CBC", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t blowfish_cfb64_info = { + MBEDTLS_CIPHER_BLOWFISH_CFB64, + MBEDTLS_MODE_CFB, + 128, + "BLOWFISH-CFB64", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t blowfish_ctr_info = { + MBEDTLS_CIPHER_BLOWFISH_CTR, + MBEDTLS_MODE_CTR, + 128, + "BLOWFISH-CTR", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_ARC4_C) +static int arc4_crypt_stream_wrap( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); +} + +static int arc4_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + /* we get key_bitlen in bits, arc4 expects it in bytes */ + if( key_bitlen % 8 != 0 ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); + return( 0 ); +} + +static void * arc4_ctx_alloc( void ) +{ + mbedtls_arc4_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_arc4_init( ctx ); + + return( ctx ); +} + +static void arc4_ctx_free( void *ctx ) +{ + mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t arc4_base_info = { + MBEDTLS_CIPHER_ID_ARC4, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + arc4_crypt_stream_wrap, +#endif + arc4_setkey_wrap, + arc4_setkey_wrap, + arc4_ctx_alloc, + arc4_ctx_free +}; + +static const mbedtls_cipher_info_t arc4_128_info = { + MBEDTLS_CIPHER_ARC4_128, + MBEDTLS_MODE_STREAM, + 128, + "ARC4-128", + 0, + 0, + 1, + &arc4_base_info +}; +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +static int null_crypt_stream( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + ((void) ctx); + memmove( output, input, length ); + return( 0 ); +} + +static int null_setkey( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) ctx); + ((void) key); + ((void) key_bitlen); + + return( 0 ); +} + +static void * null_ctx_alloc( void ) +{ + return( (void *) 1 ); +} + +static void null_ctx_free( void *ctx ) +{ + ((void) ctx); +} + +static const mbedtls_cipher_base_t null_base_info = { + MBEDTLS_CIPHER_ID_NULL, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + null_crypt_stream, +#endif + null_setkey, + null_setkey, + null_ctx_alloc, + null_ctx_free +}; + +static const mbedtls_cipher_info_t null_cipher_info = { + MBEDTLS_CIPHER_NULL, + MBEDTLS_MODE_STREAM, + 0, + "NULL", + 0, + 0, + 1, + &null_base_info +}; +#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ + +const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = +{ +#if defined(MBEDTLS_AES_C) + { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, + { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, + { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, + { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, + { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, + { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, + { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, + { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, + { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, + { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, + { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, + { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, + { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, +#endif +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_ARC4_C) + { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, +#endif + +#if defined(MBEDTLS_BLOWFISH_C) + { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, +#endif +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, +#endif +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) + { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, +#endif +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + { MBEDTLS_CIPHER_NULL, &null_cipher_info }, +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ + + { MBEDTLS_CIPHER_NONE, NULL } +}; + +#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0] +int mbedtls_cipher_supported[NUM_CIPHERS]; + +#endif /* MBEDTLS_CIPHER_C */ From 6da439c67cc5145400fbbba5f61a1cb953679bac Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 18 Jun 2020 18:14:06 +0200 Subject: [PATCH 281/581] ESP32 template 65504 -> 1 --- tasmota/xnrg_15_teleinfo.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino index a57020967..8d552d771 100755 --- a/tasmota/xnrg_15_teleinfo.ino +++ b/tasmota/xnrg_15_teleinfo.ino @@ -24,7 +24,7 @@ * Source: http://hallard.me/category/tinfo/ * * Denky ESP32 Teleinfo Template - * {"NAME":"Denky (Teleinfo)","GPIO":[65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,65504,0,65504,65504,65504,0,65504,65504,65504,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} + * {"NAME":"Denky (Teleinfo)","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} * * Denky (aka WifInfo) ESP8266 Teleinfo Template * {"NAME":"WifInfo","GPIO":[7,255,255,208,6,5,255,255,255,255,255,255,255],"FLAG":15,"BASE":18} From fc3d38bbe7ff3a380111e696002c0b538ece18df Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Thu, 18 Jun 2020 18:16:16 +0200 Subject: [PATCH 282/581] Add info display Ssid escape --- tasmota/xdrv_01_webserver.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index b9055e638..d18368431 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2022,8 +2022,8 @@ void ModuleSaveSettings(void) /*-------------------------------------------------------------------------------------------*/ -const char kUnescapeCode[] = "&><\"\'"; -const char kEscapeCode[] PROGMEM = "&|>|<|"|'"; +const char kUnescapeCode[] = "&><\"\'\\"; +const char kEscapeCode[] PROGMEM = "&|>|<|"|'|\"; String HtmlEscape(const String unescaped) { char escaped[10]; @@ -2473,7 +2473,7 @@ void HandleInformation(void) #endif if (Settings.flag4.network_wifi) { int32_t rssi = WiFi.RSSI(); - WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WifiGetRssiAsQuality(rssi), rssi); + WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, HtmlEscape(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str(), WifiGetRssiAsQuality(rssi), rssi); WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Mdns.begun) ? ".local" : ""); #if LWIP_IPV6 String ipv6_addr = WifiGetIPv6(); From 0d6aaa64b5c21f8704ca390bc369f39bb4a49d25 Mon Sep 17 00:00:00 2001 From: Federico Leoni Date: Thu, 18 Jun 2020 14:43:18 -0300 Subject: [PATCH 283/581] Discovery Update --- tasmota/my_user_config.h | 2 + tasmota/xdrv_12_home_assistant.ino | 141 ++++++++++++++++++----------- 2 files changed, 91 insertions(+), 52 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 87647a98d..4f5623de1 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -140,6 +140,8 @@ // -- MQTT - Home Assistant Discovery ------------- #define HOME_ASSISTANT_DISCOVERY_ENABLE false // [SetOption19] Home Assistant Discovery (false = Disable, true = Enable) #define HASS_AS_LIGHT false // [SetOption30] Enforce HAss autodiscovery as light +//#define DEEPSLEEP_LWT_HA_DISCOVERY // Enable LWT topic and its payloads for read-only sensors (Status sensor not included) and binary_sensors on HAss Discovery (Commented out: all read-only sensors and binary_sensors + // won't be shown as OFFLINE on Home Assistant when the device is DeepSleeping - NOTE: This is only for read-only sensors and binary_sensors, relays will be shown as OFFLINE) // -- MQTT - Options ------------------------------ #define MQTT_RESULT_COMMAND false // [SetOption4] Switch between MQTT RESULT or COMMAND diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 70ab6d620..476d45765 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -27,14 +27,14 @@ const char kHAssJsonSensorTypes[] PROGMEM = D_JSON_APPARENT_POWERUSAGE "|Battery|" D_JSON_CURRENT "|" D_JSON_DISTANCE "|" D_JSON_FREQUENCY "|" D_JSON_HUMIDITY "|" D_JSON_ILLUMINANCE "|" D_JSON_MOISTURE "|PB0.3|PB0.5|PB1|PB2.5|PB5|PB10|PM1|PM2.5|PM10|" D_JSON_POWERFACTOR "|" D_JSON_POWERUSAGE "|" D_JSON_TOTAL_START_TIME "|" D_JSON_REACTIVE_POWERUSAGE "|" D_JSON_TODAY "|" D_JSON_TOTAL "|" D_JSON_VOLTAGE "|" D_JSON_WEIGHT "|" D_JSON_YESTERDAY "|" - D_JSON_CO2 "|" D_JSON_ECO2 "|" D_JSON_TVOC "|"; + D_JSON_CO2 "|" D_JSON_ECO2 "|" D_JSON_TVOC "|" D_COLOR_RED "|" D_COLOR_GREEN "|" D_COLOR_BLUE"|" D_CCT "|" D_PROXIMITY "|Ambient|"; const char kHAssJsonSensorUnits[] PROGMEM = "||||" "VA|%|A|Cm|Hz|%|LX|" "%|ppd|ppd|ppd|ppd|ppd|ppd|µg/m³|µg/m³|µg/m³|Cos φ|W| |" "VAr|kWh|kWh|V|Kg|kWh|" - "ppm|ppm|ppb|"; + "ppm|ppm|ppb|R|G|B|" D_UNIT_KELVIN "| |LX|"; const char kHAssJsonSensorDevCla[] PROGMEM = "dev_cla\":\"temperature|ic\":\"mdi:weather-rainy|dev_cla\":\"pressure|dev_cla\":\"pressure|" @@ -42,61 +42,64 @@ const char kHAssJsonSensorDevCla[] PROGMEM = "ic\":\"mdi:cup-water|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|" "ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:alpha-f-circle-outline|dev_cla\":\"power|ic\":\"mdi:progress-clock|" "dev_cla\":\"power|dev_cla\":\"power|dev_cla\":\"power|ic\":\"mdi:alpha-v-circle-outline|ic\":\"mdi:scale|dev_cla\":\"power|" - "ic\":\"mdi:periodic-table-co2|ic\":\"mdi:air-filter|ic\":\"mdi:periodic-table-co2|"; + "ic\":\"mdi:periodic-table-co2|ic\":\"mdi:air-filter|ic\":\"mdi:periodic-table-co2|" + "ic\":\"mdi:palette|ic\":\"mdi:palette|ic\":\"mdi:palette|ic\":\"mdi:temperature-kelvin|ic\":\"mdi:ruler|dev_cla\":\"illuminance|"; //"ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|" // List of sensors ready for discovery -const char HASS_DISCOVER_SENSOR[] PROGMEM = - ",\"unit_of_meas\":\"%s\",\"%s\"," // unit of measure and class (or icon) - "\"frc_upd\":true," // force update for better graph representation - "\"val_tpl\":\"{{value_json['%s']['%s']"; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER']['C1'] - const char HASS_DISCOVER_BASE[] PROGMEM = - "{\"name\":\"%s\"," // dualr2 1 - "\"stat_t\":\"%s\"," // stat/dualr2/RESULT (implies "\"optimistic\":\"false\",") - "\"avty_t\":\"%s\"," // tele/dualr2/LWT - "\"pl_avail\":\"" D_ONLINE "\"," // Online - "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline + "{\"name\":\"%s\"," // dualr2 1 + "\"stat_t\":\"%s\""; // stat/dualr2/RESULT (implies "\"optimistic\":\"false\",") + +const char HASS_DISCOVER_SENSOR[] PROGMEM = + ",\"unit_of_meas\":\"%s\",\"%s\"," // unit of measure and class (or icon) + "\"frc_upd\":true," // force update for better graph representation + "\"val_tpl\":\"{{value_json['%s']['%s']"; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER']['C1'] + +const char HASS_DISCOVER_SENSOR_LWT[] PROGMEM = + ",\"avty_t\":\"%s\"," // tele/dualr2/LWT + "\"pl_avail\":\"" D_ONLINE "\"," // Online + "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline const char HASS_DISCOVER_RELAY[] PROGMEM = - ",\"cmd_t\":\"%s\"," // cmnd/dualr2/POWER2 - "\"val_tpl\":\"{{value_json.%s}}\"," // POWER2 - "\"pl_off\":\"%s\"," // OFF - "\"pl_on\":\"%s\""; // ON + ",\"cmd_t\":\"%s\"," // cmnd/dualr2/POWER2 + "\"val_tpl\":\"{{value_json.%s}}\"," // POWER2 + "\"pl_off\":\"%s\"," // OFF + "\"pl_on\":\"%s\""; // ON const char HASS_DISCOVER_BIN_SWITCH[] PROGMEM = - ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE - "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work - "\"pl_on\":\"%s\"," // ON - "\"pl_off\":\"%s\""; // OFF + ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE + "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work + "\"pl_on\":\"%s\"," // ON + "\"pl_off\":\"%s\""; // OFF const char HASS_DISCOVER_BIN_PIR[] PROGMEM = - ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE - "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work - "\"pl_on\":\"%s\"," // ON - "\"off_dly\":1"; // Switchmode13 and Switchmode14 doesn't transmit an OFF state. + ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE + "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work + "\"pl_on\":\"%s\"," // ON + "\"off_dly\":1"; // Switchmode13 and Switchmode14 doesn't transmit an OFF state. const char HASS_DISCOVER_BASE_LIGHT[] PROGMEM = - ",\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer - "\"bri_stat_t\":\"%s\"," // stat/led2/RESULT - "\"bri_scl\":100," // 100% - "\"on_cmd_type\":\"%s\"," // power on (first), power on (last), no power on (brightness) + ",\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer + "\"bri_stat_t\":\"%s\"," // stat/led2/RESULT + "\"bri_scl\":100," // 100% + "\"on_cmd_type\":\"%s\"," // power on (first), power on (last), no power on (brightness) "\"bri_val_tpl\":\"{{value_json.%s}}\""; const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM = - ",\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2 - "\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT + ",\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2 + "\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT "\"rgb_val_tpl\":\"{{value_json." D_CMND_COLOR ".split(',')[0:3]|join(',')}}\""; const char HASS_DISCOVER_LIGHT_WHITE[] PROGMEM = - ",\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White - "\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT + ",\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White + "\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT "\"whit_val_scl\":100," "\"whit_val_tpl\":\"{{value_json.Channel[3]}}\""; const char HASS_DISCOVER_LIGHT_CT[] PROGMEM = - ",\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT - "\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT + ",\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT + "\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT "\"clr_temp_val_tpl\":\"{{value_json." D_CMND_COLORTEMPERATURE "}}\""; const char HASS_DISCOVER_LIGHT_SCHEME[] PROGMEM = @@ -141,7 +144,7 @@ const char kHAssTriggerStringButtons[] PROGMEM = "|SINGLE|DOUBLE|TRIPLE|QUAD|PENTA|HOLD|"; const char kHAssError1[] PROGMEM = - "HASS: MQTT discovery failed due to too long topic or friendly name. Please shorten topic and/or friendly name. Failed to format"; + "HASS: MQTT discovery failed due to too long topic or device/friendly name. Please shorten topic and/or device/friendly name. Failed to format"; const char kHAssError2[] PROGMEM = "HASS: The configuration of the Relays is wrong, there is a Light that is using an index higher than the number of the validated relay.\n " @@ -195,13 +198,22 @@ void HAssAnnounceRelayLight(void) bool ct_light = false; // Controls a CT Light when SetOption37 is >= 128 bool wt_light = false; // Controls a White Light when SetOption37 is >= 128 bool err_flag = false; // When true it blocks the creation of entities if the order of the Relays is not correct to avoid issue with Lights + bool TuyaMod = false; // Controls Tuya MCU modules bool PwmMod = false; // Controls PWM_DIMMER module + bool FanMod = false; // Controls SONOFF_IFAN0X modules uint8_t dimmer = 1; + uint8_t valid_relay = 0; uint8_t max_lights = 1; + uint8_t TuyaRel = 0; + uint8_t TuyaRelInv = 0; + uint8_t TuyaDim = 0; #ifdef ESP8266 - if (PWM_DIMMER == my_module_type) { PwmMod = true; } + if (PWM_DIMMER == my_module_type ) { PwmMod = true; } // + if (SONOFF_IFAN02 == my_module_type || SONOFF_IFAN03 == my_module_type) { FanMod = true; } + if (SONOFF_DUAL == my_module_type) { valid_relay = 2; } + if (TUYA_DIMMER == my_module_type || SK03_TUYA == my_module_type) { TuyaMod = true; } #endif //ESP8266 // If there is a special Light to be enabled and managed with SetOption68 or SetOption37 >= 128, Discovery calculates the maximum number of entities to be generated in advance @@ -209,17 +221,21 @@ void HAssAnnounceRelayLight(void) if (PwmMulti) { max_lights = Light.subtype; } if (!LightControl) { - ind_light = 1; + ind_light = true; if (!PwmMulti) { max_lights = 2;} } - // Lights types: 0 = LST_NONE / 1 = LST_SINGLE / 2 = LST_COLDWARM / 3 = LST_RGB / 4 = LST_RGBW / 5 = LST_RGBCW - for (uint32_t i = 1; i <= MAX_RELAYS; i++) { - bool RelayX = PinUsed(GPIO_REL1 +i-1); - is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX || PwmMod; // SetOption30 - Enforce HAss autodiscovery as light +#ifdef USE_TUYA_MCU + TuyaRel = TuyaGetDpId((TUYA_MCU_FUNC_REL1+ i-1) + active_device - 1); + TuyaRelInv = TuyaGetDpId((TUYA_MCU_FUNC_REL1_INV+ i-1) + active_device - 1); + TuyaDim = TuyaGetDpId((TUYA_MCU_FUNC_DIMMER) + active_device - 1); +#endif //USE_TUYA_MCU + + bool RelayX = PinUsed(GPIO_REL1 +i-1) || (valid_relay >= i) || (TuyaRel > 0 && TuyaMod) || (TuyaRelInv > 0 && TuyaMod); // Check if the gpio is configured as Relay or force it for Sonoff DUAL R1 with MCU and Tuya MCU + is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX || PwmMod || (TuyaDim > 0 && TuyaMod); // SetOption30 - Enforce HAss autodiscovery as light mqtt_data[0] = '\0'; // Clear retained message // Clear "other" topic first in case the device has been reconfigured from light to switch or vice versa @@ -255,13 +271,14 @@ void HAssAnnounceRelayLight(void) GetTopic_P(command_topic, CMND, mqtt_topic, value_template); GetTopic_P(state_topic, TELE, mqtt_topic, D_RSLT_STATE); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); + Response_P(HASS_DISCOVER_BASE, name, state_topic); + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); TryResponseAppend_P(HASS_DISCOVER_RELAY, command_topic, value_template, SettingsText(SET_STATE_TXT1), SettingsText(SET_STATE_TXT2)); TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); #ifdef USE_LIGHT if (i >= Light.device) { - if (!RelayX || PwmMod) { + if (!RelayX || PwmMod || (TuyaDim > 0 && TuyaMod)) { char *brightness_command_topic = stemp1; strncpy_P(stemp3, Settings.flag.not_power_linked ? PSTR("last") : PSTR("brightness"), sizeof(stemp3)); // SetOption20 - Control power in relation to Dimmer/Color/Ct changes char channel_num[9]; @@ -411,6 +428,14 @@ void HAssAnnouncerBinSensors(uint8_t device, uint8_t present, uint8_t dual, uint TryResponseAppend_P(HASS_DISCOVER_BIN_PIR, PSTR(D_RSLT_STATE), SettingsText(SET_STATE_TXT2)); } TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); +#ifdef DEEPSLEEP_LWT_HA_DISCOVERY + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); +#else + if (Settings.deepsleep == 0) + { + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); + } +#endif //DEEPSLEEP_LWT_HA_DISCOVERY TryResponseAppend_P(PSTR("}")); } } @@ -505,7 +530,7 @@ void HAssAnnounceButtons(void) { button_present = 1; } else -#endif +#endif // ESP8266 { if (PinUsed(GPIO_KEY1, button_index)) { button_present = 1; @@ -557,12 +582,21 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const char prefix[TOPSZ]; char *state_topic = stemp1; char *availability_topic = stemp2; + //bool LwtSensor = MQTT_LWT_DISCOVERY; GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_SENSOR)); snprintf_P(name, sizeof(name), PSTR("%s %s %s"), SettingsText(SET_DEVICENAME), sensorname, MultiSubName); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); + Response_P(HASS_DISCOVER_BASE, name, state_topic); + #ifdef DEEPSLEEP_LWT_HA_DISCOVERY + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); +#else + if (Settings.deepsleep == 0) + { + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); + } +#endif //DEEPSLEEP_LWT_HA_DISCOVERY TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); @@ -629,8 +663,8 @@ void HAssAnnounceSensors(void) sensordata[0] = '{'; snprintf_P(sensordata, sizeof(sensordata), PSTR("%s}"), sensordata); // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} // USE THE FOLLOWING LINE TO TEST JSON - //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"HX711\":{\"Weight\":[22,34,1023.4]}}")); - + //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"APDS9960\":{\"Red\":282,\"Green\":252,\"Blue\":196,\"Ambient\":169,\"CCT\":4217,\"Proximity\":9}}")); + //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"ENERGY\":{\"TotalStartTime\":\"2018-11-23T15:33:47\",\"Total\":0.017,\"TotalTariff\":[0.000,0.017],\"Yesterday\":0.000,\"Today\":0.002,\"ExportActive\":0.000,\"ExportTariff\":[0.000,0.000],\"Period\":0.00,\"Power\":0.00,\"ApparentPower\":7.84,\"ReactivePower\":-7.21,\"Factor\":0.39,\"Frequency\":50.0,\"Voltage\":234.31,\"Current\":0.039,\"ImportActive\":12.580,\"ImportReactive\":0.002,\"ExportReactive\":39.131,\"PhaseAngle\":290.45}}")); StaticJsonBuffer<500> jsonBuffer; JsonObject &root = jsonBuffer.parseObject(sensordata); @@ -703,7 +737,8 @@ void HAssAnnounceDeviceInfoAndStatusSensor(void) GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_HASS_STATE)); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); + Response_P(HASS_DISCOVER_BASE, name, state_topic); + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); TryResponseAppend_P(HASS_DISCOVER_SENSOR_HASS_STATUS, state_topic); TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO, unique_id, ESP_getChipId(), SettingsText(SET_DEVICENAME), ModuleName().c_str(), my_version, my_image); @@ -719,7 +754,7 @@ void HAssPublishStatus(void) "\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_RSSI "\":\"%d\",\"" D_JSON_SIGNAL " (dBm)""\":\"%d\"," "\"WiFi " D_JSON_LINK_COUNT "\":%d,\"WiFi " D_JSON_DOWNTIME "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"LoadAvg\":%lu}"), my_version, my_image, GetBuildDateAndTime().c_str(), ModuleName().c_str(), GetResetReason().c_str(), - GetUptime().c_str(), NetworkHostname(), WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()), + GetUptime().c_str(), my_hostname, WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.RSSI(), WifiLinkCount(), WifiDowntime().c_str(), MqttConnectCount(), loop_load_avg); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_HASS_STATE)); } @@ -812,7 +847,6 @@ void HAssAnyKey(void) bool Xdrv12(uint8_t function) { bool result = false; - if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT switch (function) @@ -844,10 +878,13 @@ bool Xdrv12(uint8_t function) case FUNC_MQTT_INIT: hass_mode = 0; // Discovery only if Settings.flag.hass_discovery is set hass_init_step = 2; // Delayed discovery + // if (!Settings.flag.hass_discovery) { + // AddLog_P2(LOG_LEVEL_INFO, PSTR("MQT: homeassistant/49A3BC/Discovery = {\"dev\":{\"ids\":[\"49A3BC\"]},\"cmd_t\":\"cmnd/test1/\",\"Discovery\":0}")); + // } break; } } return result; } -#endif // USE_HOME_ASSISTANT +#endif // USE_HOME_ASSISTANT \ No newline at end of file From ae1bb588bc2c88840d1b050e1fb80283631c71b5 Mon Sep 17 00:00:00 2001 From: Adrian Scillato Date: Thu, 18 Jun 2020 15:07:01 -0300 Subject: [PATCH 284/581] KNX: Add Scenes Support --- tasmota/xdrv_11_knx.ino | 53 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_11_knx.ino b/tasmota/xdrv_11_knx.ino index f23e896fd..d6fef25fe 100644 --- a/tasmota/xdrv_11_knx.ino +++ b/tasmota/xdrv_11_knx.ino @@ -114,6 +114,7 @@ device_parameters_t device_param[] = { { KNX_SLOT3 , false, false, KNX_Empty }, { KNX_SLOT4 , false, false, KNX_Empty }, { KNX_SLOT5 , false, false, KNX_Empty }, + { KNX_SCENE , false, false, KNX_Empty }, { KNX_Empty, false, false, KNX_Empty} }; @@ -149,6 +150,7 @@ const char * device_param_ga[] = { D_KNX_TX_SLOT " 3", D_KNX_TX_SLOT " 4", D_KNX_TX_SLOT " 5", + D_KNX_TX_SCENE , nullptr }; @@ -184,6 +186,7 @@ const char *device_param_cb[] = { D_KNX_RX_SLOT " 3", D_KNX_RX_SLOT " 4", D_KNX_RX_SLOT " 5", + D_KNX_RX_SCENE , nullptr }; @@ -196,12 +199,14 @@ const char *device_param_cb[] = { #define D_CMND_KNX_PA "_PA" #define D_CMND_KNX_GA "_GA" #define D_CMND_KNX_CB "_CB" +#define D_CMND_KNXTXSCENE "Tx_Scene" + const char kKnxCommands[] PROGMEM = D_PRFX_KNX "|" // Prefix - D_CMND_KNXTXCMND "|" D_CMND_KNXTXVAL "|" D_CMND_KNX_ENABLED "|" D_CMND_KNX_ENHANCED "|" D_CMND_KNX_PA "|" D_CMND_KNX_GA "|" D_CMND_KNX_CB ; + D_CMND_KNXTXCMND "|" D_CMND_KNXTXVAL "|" D_CMND_KNX_ENABLED "|" D_CMND_KNX_ENHANCED "|" D_CMND_KNX_PA "|" D_CMND_KNX_GA "|" D_CMND_KNX_CB "|" D_CMND_KNXTXSCENE ; void (* const KnxCommand[])(void) PROGMEM = { - &CmndKnxTxCmnd, &CmndKnxTxVal, &CmndKnxEnabled, &CmndKnxEnhanced, &CmndKnxPa, &CmndKnxGa, &CmndKnxCb }; + &CmndKnxTxCmnd, &CmndKnxTxVal, &CmndKnxEnabled, &CmndKnxEnhanced, &CmndKnxPa, &CmndKnxGa, &CmndKnxCb, &CmndKnxTxScene }; uint8_t KNX_GA_Search( uint8_t param, uint8_t start = 0 ) { @@ -518,6 +523,7 @@ void KNX_INIT(void) device_param[KNX_SLOT3-1].show = true; device_param[KNX_SLOT4-1].show = true; device_param[KNX_SLOT5-1].show = true; + device_param[KNX_SCENE-1].show = true; #endif // Delete from KNX settings all configuration is not anymore related to this device @@ -557,7 +563,11 @@ void KNX_CB_Action(message_t const &msg, void *arg) if (msg.data_len == 1) { // COMMAND sprintf(tempchar,"%d",msg.data[0]); - } else { + } else if (chan->type == KNX_SCENE) { + // VALUE + uint8_t tempvar = knx.data_to_1byte_uint(msg.data); + dtostrfd(tempvar,2,tempchar); + } else { // VALUE float tempvar = knx.data_to_2byte_float(msg.data); dtostrfd(tempvar,2,tempchar); @@ -602,6 +612,18 @@ void KNX_CB_Action(message_t const &msg, void *arg) } } } + else if (chan->type == KNX_SCENE) // KNX RX SCENE SLOT (write command) + { + if (!toggle_inhibit) { + char command[25]; + // Value received + snprintf_P(command, sizeof(command), PSTR("event KNX_SCENE=%s"), tempchar); + ExecuteCommand(command, SRC_KNX); + if (Settings.flag.knx_enable_enhancement) { + toggle_inhibit = TOGGLE_INHIBIT_TIME; + } + } + } #endif break; @@ -1054,6 +1076,31 @@ void CmndKnxTxVal(void) } } +void CmndKnxTxScene(void) +{ + if ( (XdrvMailbox.data_len > 0) && Settings.flag.knx_enabled ) { + // XdrvMailbox.payload <- scene number to send + uint8_t i = KNX_GA_Search(KNX_SCENE); + if ( i != KNX_Empty ) { + KNX_addr.value = Settings.knx_GA_addr[i]; + + uint8_t tempvar = TextToInt(XdrvMailbox.data); + dtostrfd(tempvar,0,XdrvMailbox.data); + + knx.write_1byte_uint(KNX_addr, tempvar); + if (Settings.flag.knx_enable_enhancement) { + knx.write_1byte_uint(KNX_addr, tempvar); + knx.write_1byte_uint(KNX_addr, tempvar); + } + + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d.%d.%d"), + device_param_ga[KNX_SCENE-1], XdrvMailbox.data, + KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); + ResponseCmndIdxChar (XdrvMailbox.data); + } + } +} + void CmndKnxEnabled(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { From bd011493e5f67c08cccc157049f82b5ddf65f172 Mon Sep 17 00:00:00 2001 From: Adrian Scillato Date: Thu, 18 Jun 2020 15:23:58 -0300 Subject: [PATCH 285/581] KNX: Add Scenes Slot --- tasmota/tasmota.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 3d3811c89..4eceddb5c 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -203,7 +203,8 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to #define KNX_SLOT3 28 #define KNX_SLOT4 29 #define KNX_SLOT5 30 -#define KNX_MAX_device_param 30 +#define KNX_SCENE 31 +#define KNX_MAX_device_param 31 #define MAX_KNXTX_CMNDS 5 /*********************************************************************************************\ From 98798d4c11d3ef5605506c12323a2cee33b92949 Mon Sep 17 00:00:00 2001 From: ascillato Date: Thu, 18 Jun 2020 15:25:59 -0300 Subject: [PATCH 286/581] KNX: Add Scene Translation Keys --- tasmota/language/bg_BG.h | 2 ++ tasmota/language/cs_CZ.h | 2 ++ tasmota/language/de_DE.h | 2 ++ tasmota/language/el_GR.h | 2 ++ tasmota/language/en_GB.h | 2 ++ tasmota/language/es_ES.h | 2 ++ tasmota/language/fr_FR.h | 2 ++ tasmota/language/he_HE.h | 2 ++ tasmota/language/hu_HU.h | 2 ++ tasmota/language/it_IT.h | 2 ++ tasmota/language/ko_KO.h | 2 ++ tasmota/language/nl_NL.h | 2 ++ tasmota/language/pl_PL.h | 2 ++ tasmota/language/pt_BR.h | 2 ++ tasmota/language/pt_PT.h | 2 ++ tasmota/language/ro_RO.h | 2 ++ tasmota/language/ru_RU.h | 2 ++ tasmota/language/sk_SK.h | 2 ++ tasmota/language/sv_SE.h | 2 ++ tasmota/language/tr_TR.h | 2 ++ tasmota/language/uk_UA.h | 2 ++ tasmota/language/zh_CN.h | 2 ++ tasmota/language/zh_TW.h | 2 ++ 23 files changed, 46 insertions(+) diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 17b267290..165e4f82a 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Подобрена комуникациÑ" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Използвана ÐµÐ½ÐµÑ€Ð³Ð¸Ñ Ð´Ð½ÐµÑ" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index f123481dd..7b53e6274 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "SpotÅ™eba Dnes" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 8c2fa8645..4804ea7ba 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Erweiterte Kommunikation" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energie heute" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 44e812b35..3efac89e8 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Βελτίωση επικοινωνίας" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "ΕνέÏγεια σήμεÏα" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index b3e06b94a..1dd0429d8 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energy Today" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 471c0d449..e0141cf83 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Mejora de Comunicación" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX ESCENA TX" +#define D_KNX_RX_SCENE "KNX ESCENA RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energía Hoy" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index b45b9b1a2..28e9e28b9 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Amélioration de la communication" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX Scène TX" +#define D_KNX_RX_SCENE "KNX Scène RX" // xsns_03_energy.ino #define D_ENERGY_TODAY "Énergie aujourd'hui" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index acf642ce3..7cbc64acf 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "שיפור התקשורת" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "צריכה יומית" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 26e0ced62..07dfe6349 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Mai energia" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 924105509..ebd7addfe 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Miglioramento comunicazione" #define D_KNX_TX_SLOT "KNX - TX" #define D_KNX_RX_SLOT "KNX - RX" +#define D_KNX_TX_SCENE "Scena - TX" +#define D_KNX_RX_SCENE "Scena - RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia - oggi" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 3fd602224..0a4cb7633 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "커뮤니케ì´ì…˜ ê°•í™”" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "ê¸ˆì¼ ì „ë ¥ 사용량" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index d48d02988..819b39045 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Verbeter verbinding" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Verbruik vandaag" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 6ca24f165..2cb92290e 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Rozszerzenia" #define D_KNX_TX_SLOT "Gniazdo TX" #define D_KNX_RX_SLOT "Gniazdo RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia dzisiaj" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 8eb4381d0..5e866f809 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Melhoria da comunicação" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Consumo energético de hoje" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 9defb5975..af5e2f7aa 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Melhoria de Comunicação" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Consumo energético de hoje" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index b41cfef2f..3e8418960 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "ÃŽmbunătățire CommunicaÈ›ie" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia de Azi" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 8c0a54b19..af5ef942d 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Ð­Ð½ÐµÑ€Ð³Ð¸Ñ Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 0bd2d2016..06251277c 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Spotreba dnes" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index b846fdb82..74c30ef32 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Kommuniceringsförbättring" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energi idag" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 7778459fa..97a03b15b 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energy Today" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 9d153c732..07a60ee5b 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "ÐŸÑ–Ð´Ð²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð·Ð²'Ñзку" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Ð•Ð½ÐµÑ€Ð³Ñ–Ñ Ð¡ÑŒÐ¾Ð³Ð¾Ð´Ð½Ñ–" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 37d280fc3..92dc25766 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "通讯增强" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "今日用电é‡" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index f0696fc01..91339b304 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "今日用電é‡" From 09871f8668da020a9fb1017eb805fdce9da0847d Mon Sep 17 00:00:00 2001 From: Adrian Scillato Date: Fri, 19 Jun 2020 02:12:05 -0300 Subject: [PATCH 287/581] Fix bug on rule variable %topic% --- tasmota/xdrv_10_rules.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 37300d03c..49762ad85 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -711,7 +711,7 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved) RulesVarReplace(commands, F("%UTCTIME%"), String(UtcTime())); RulesVarReplace(commands, F("%UPTIME%"), String(MinutesUptime())); RulesVarReplace(commands, F("%TIMESTAMP%"), GetDateAndTime(DT_LOCAL)); - RulesVarReplace(commands, F("%TOPIC%"), SettingsText(SET_MQTT_TOPIC)); + RulesVarReplace(commands, F("%TOPIC%"), mqtt_topic); #if defined(USE_TIMERS) && defined(USE_SUNRISE) RulesVarReplace(commands, F("%SUNRISE%"), String(SunMinutes(0))); RulesVarReplace(commands, F("%SUNSET%"), String(SunMinutes(1))); From 9b44a369d8d4b2fda4c12c0ed8b473890129ed1f Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Fri, 19 Jun 2020 12:33:31 +0200 Subject: [PATCH 288/581] Fix some json unescapes --- tasmota/support_command.ino | 18 +++++++++--------- tasmota/support_tasmota.ino | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index a901b380d..565fd8fcd 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -100,7 +100,7 @@ void ResponseCmndChar_P(const char* value) void ResponseCmndChar(const char* value) { - Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, value); + Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, EscapeJSONString(value).c_str()); } void ResponseCmndStateText(uint32_t value) @@ -115,7 +115,7 @@ void ResponseCmndDone(void) void ResponseCmndIdxChar(const char* value) { - Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, value); + Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, EscapeJSONString(value).c_str()); } void ResponseCmndAll(uint32_t text_index, uint32_t count) @@ -124,7 +124,7 @@ void ResponseCmndAll(uint32_t text_index, uint32_t count) mqtt_data[0] = '\0'; for (uint32_t i = 0; i < count; i++) { if ((SET_MQTT_GRP_TOPIC == text_index) && (1 == i)) { real_index = SET_MQTT_GRP_TOPIC2 -1; } - ResponseAppend_P(PSTR("%c\"%s%d\":\"%s\""), (i) ? ',' : '{', XdrvMailbox.command, i +1, SettingsText(real_index +i)); + ResponseAppend_P(PSTR("%c\"%s%d\":\"%s\""), (i) ? ',' : '{', XdrvMailbox.command, i +1, EscapeJSONString(SettingsText(real_index +i)).c_str()); } ResponseJsonEnd(); } @@ -397,7 +397,7 @@ void CmndStatus(void) #endif // USE_SONOFF_IFAN stemp[0] = '\0'; for (uint32_t i = 0; i < maxfn; i++) { - snprintf_P(stemp, sizeof(stemp), PSTR("%s%s\"%s\"" ), stemp, (i > 0 ? "," : ""), SettingsText(SET_FRIENDLYNAME1 +i)); + snprintf_P(stemp, sizeof(stemp), PSTR("%s%s\"%s\"" ), stemp, (i > 0 ? "," : ""), EscapeJSONString(SettingsText(SET_FRIENDLYNAME1 +i)).c_str()); } stemp2[0] = '\0'; for (uint32_t i = 0; i < MAX_SWITCHES; i++) { @@ -407,7 +407,7 @@ void CmndStatus(void) D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_LEDMASK "\":\"%04X\",\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_SWITCHTOPIC "\":\"%s\",\"" D_CMND_SWITCHMODE "\":[%s],\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_SWITCHRETAIN "\":%d,\"" D_CMND_SENSORRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"), - ModuleNr(), SettingsText(SET_DEVICENAME), stemp, mqtt_topic, + ModuleNr(), EscapeJSONString(SettingsText(SET_DEVICENAME)).c_str(), stemp, mqtt_topic, SettingsText(SET_MQTT_BUTTON_TOPIC), power, Settings.poweronstate, Settings.ledstate, Settings.ledmask, Settings.save_data, Settings.flag.save_state, // SetOption0 - Save power state and use after restart @@ -461,7 +461,7 @@ void CmndStatus(void) D_CMND_LOGHOST "\":\"%s\",\"" D_CMND_LOGPORT "\":%d,\"" D_CMND_SSID "\":[\"%s\",\"%s\"],\"" D_CMND_TELEPERIOD "\":%d,\"" D_JSON_RESOLUTION "\":\"%08X\",\"" D_CMND_SETOPTION "\":[\"%08X\",\"%s\",\"%08X\",\"%08X\"]}}"), Settings.seriallog_level, Settings.weblog_level, Settings.mqttlog_level, Settings.syslog_level, - SettingsText(SET_SYSLOG_HOST), Settings.syslog_port, SettingsText(SET_STASSID1), SettingsText(SET_STASSID2), Settings.tele_period, + SettingsText(SET_SYSLOG_HOST), Settings.syslog_port, EscapeJSONString(SettingsText(SET_STASSID1)).c_str(), EscapeJSONString(SettingsText(SET_STASSID2)).c_str(), Settings.tele_period, Settings.flag2.data, Settings.flag.data, ToHex_P((unsigned char*)Settings.param, PARAM8_SIZE, stemp2, sizeof(stemp2)), Settings.flag3.data, Settings.flag4.data); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "3")); @@ -508,8 +508,8 @@ void CmndStatus(void) if (((0 == payload) || (6 == payload)) && Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\",\"" D_CMND_MQTTPORT "\":%d,\"" D_CMND_MQTTCLIENT D_JSON_MASK "\":\"%s\",\"" D_CMND_MQTTCLIENT "\":\"%s\",\"" D_CMND_MQTTUSER "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"MAX_PACKET_SIZE\":%d,\"KEEPALIVE\":%d}}"), - SettingsText(SET_MQTT_HOST), Settings.mqtt_port, SettingsText(SET_MQTT_CLIENT), - mqtt_client, SettingsText(SET_MQTT_USER), MqttConnectCount(), MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE); + SettingsText(SET_MQTT_HOST), Settings.mqtt_port, EscapeJSONString(SettingsText(SET_MQTT_CLIENT)).c_str(), + mqtt_client, EscapeJSONString(SettingsText(SET_MQTT_USER)).c_str(), MqttConnectCount(), MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "6")); } @@ -1445,7 +1445,7 @@ void CmndAp(void) Settings.wifi_channel = 0; // Disable stored AP restart_flag = 2; } - Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active)); + Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, Settings.sta_active +1, EscapeJSONString(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str()); } void CmndSsid(void) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 4843cd884..ae32ea34b 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -687,7 +687,7 @@ void MqttShowState(void) if (!global_state.wifi_down) { int32_t rssi = WiFi.RSSI(); ResponseAppend_P(PSTR(",\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_RSSI "\":%d,\"" D_JSON_SIGNAL "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}"), - Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WiFi.BSSIDstr().c_str(), WiFi.channel(), + Settings.sta_active +1, EscapeJSONString(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str(), WiFi.BSSIDstr().c_str(), WiFi.channel(), WifiGetRssiAsQuality(rssi), rssi, WifiLinkCount(), WifiDowntime().c_str()); } From 750e28d13570b6a52ad970175442a24afdf8c74f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:16:55 +0200 Subject: [PATCH 289/581] Better placing for -DUSE_CONFIG_OVERRIDE... update to espressif8266@2.5.3 (minor fixes) --- platformio.ini | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/platformio.ini b/platformio.ini index abb9d364d..4a1a5777d 100755 --- a/platformio.ini +++ b/platformio.ini @@ -65,11 +65,6 @@ platform = ${core_active.platform} platform_packages = ${core_active.platform_packages} build_flags = ${core_active.build_flags} -; ********************************************************************* -; *** Use custom settings from file user_config_override.h - -DUSE_CONFIG_OVERRIDE -; ********************************************************************* - ; *** Fix espressif8266@1.7.0 induced undesired all warnings build_unflags = -Wall @@ -93,6 +88,8 @@ build_flags = -D_IR_ENABLE_DEFAULT_=false -DDECODE_HASH=true -DDECODE_NEC=true -DSEND_NEC=true -DDECODE_RC5=true -DSEND_RC5=true -DDECODE_RC6=true -DSEND_RC6=true ; new mechanism to set the IRremoteESP8266 supported protocols: none except HASH, NEC, RC5, RC6 +; *** Use custom settings from file user_config_override.h + -DUSE_CONFIG_OVERRIDE [esp82xx_defaults] build_flags = ${esp_defaults.build_flags} @@ -128,6 +125,6 @@ build_flags = ${tasmota_core.build_flags} [tasmota_core] ; *** Esp8266 Arduino core 2.7.1 -platform = espressif8266@2.5.2 +platform = espressif8266@2.5.3 platform_packages = build_flags = ${esp82xx_defaults.build_flags} From dd4642c5baf67561832579d7e5decb36a877d30b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:19:47 +0200 Subject: [PATCH 290/581] remove redundant -DUSE_CONFIG_OVERRIDE since use of user_config_override.h is always enabled (by default) in platformio.ini --- platformio_override_sample.ini | 2 -- 1 file changed, 2 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 2becf05f7..2c5286a55 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -41,8 +41,6 @@ default_envs = platform = ${core_active.platform} platform_packages = ${core_active.platform_packages} build_flags = ${core_active.build_flags} -; *** Use settings from file user_config_override.h - -DUSE_CONFIG_OVERRIDE ; *** Optional Debug messages ; -DDEBUG_TASMOTA_CORE From fabb60f90543feafbaf61922b5cee6eb1f778328 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:26:41 +0200 Subject: [PATCH 291/581] Fix missing build_flags entry... and prepare for possible needed build_unflags --- platformio_override_sample.ini | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 2c5286a55..81cf0dec0 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -40,6 +40,7 @@ default_envs = [common] platform = ${core_active.platform} platform_packages = ${core_active.platform_packages} +build_unflags = ${core_active.build_unflags} build_flags = ${core_active.build_flags} ; *** Optional Debug messages @@ -78,10 +79,12 @@ extra_scripts = ${scripts_defaults.extra_scripts} ;platform = ${tasmota_stage.platform} ;platform_packages = ${tasmota_stage.platform_packages} +;build_unflags = ${tasmota_stage.build_unflags} ;build_flags = ${tasmota_stage.build_flags} ;platform = ${core_stage.platform} ;platform_packages = ${core_stage.platform_packages} +;build_unflags = ${core_stage.build_unflags} ;build_flags = ${core_stage.build_flags} @@ -89,6 +92,8 @@ extra_scripts = ${scripts_defaults.extra_scripts} ; *** Esp8266 core for Arduino version Tasmota stage extends = tasmota_core platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#52b3e5b7b3ccedcede665682f7896b637b64dbf5 +build_unflags = -Wall +build_flags = ${esp82xx_defaults.build_flags} ; *********** Alternative Options, enable only if you know exactly what you do ******** ; NONOSDK221 ; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221 @@ -122,7 +127,9 @@ platform_packages = framework-arduinoespressif8266 @ https://github.com/ ; *** Esp8266 core for Arduino version latest development version extends = tasmota_core platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git -; +build_unflags = -Wall +build_flags = ${esp82xx_defaults.build_flags} + ; *********** Alternative Options, enable only if you know exactly what you do ******** ; NONOSDK221 ; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221 From 39ee974f720ae920683c7eefa8ecd5658f23fe7a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:29:15 +0200 Subject: [PATCH 292/581] Fix ILI9341 system crash --- tasmota/xdsp_04_ili9341.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index 21981ff76..48c486681 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -197,6 +197,10 @@ void Ili9341PrintLog(void) void Ili9341Refresh(void) // Every second { if (Settings.display_mode) { // Mode 0 is User text + if (Settings.display_cols[0] < 19) { + Settings.display_cols[0] = 19; + } + char tftdt[Settings.display_cols[0] +1]; char date4[11]; // 24-04-2017 char space[Settings.display_cols[0] - 17]; From 3d2914bf8e2d4929af06d36480696d7fc4eb3c7d Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 19 Jun 2020 20:14:59 +0200 Subject: [PATCH 293/581] Refactor PlatformIO.ini Deleting uneeded entrys. Moving and adding some entrys. --- platformio.ini | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/platformio.ini b/platformio.ini index 4a1a5777d..d03de291d 100755 --- a/platformio.ini +++ b/platformio.ini @@ -61,12 +61,10 @@ board = esp01_1m board_build.flash_mode = dout board_build.ldscript = eagle.flash.1m.ld -platform = ${core_active.platform} -platform_packages = ${core_active.platform_packages} -build_flags = ${core_active.build_flags} - -; *** Fix espressif8266@1.7.0 induced undesired all warnings -build_unflags = -Wall +platform = ${core.platform} +platform_packages = ${core.platform_packages} +build_unflags = ${core.build_unflags} +build_flags = ${core.build_flags} board_build.f_cpu = 80000000L board_build.f_flash = 40000000L @@ -84,12 +82,17 @@ extra_scripts = pio/strip-floats.py pio/override_copy.py [esp_defaults] +; *** Fix espressif8266@1.7.0 induced undesired all warnings +build_unflags = -Wall build_flags = -D_IR_ENABLE_DEFAULT_=false -DDECODE_HASH=true -DDECODE_NEC=true -DSEND_NEC=true -DDECODE_RC5=true -DSEND_RC5=true -DDECODE_RC6=true -DSEND_RC6=true ; new mechanism to set the IRremoteESP8266 supported protocols: none except HASH, NEC, RC5, RC6 +; ********************************************************************* ; *** Use custom settings from file user_config_override.h -DUSE_CONFIG_OVERRIDE +; ********************************************************************* + [esp82xx_defaults] build_flags = ${esp_defaults.build_flags} @@ -118,13 +121,10 @@ build_flags = -DUSE_IR_REMOTE_FULL -U_IR_ENABLE_DEFAULT_ -DDECODE_PRONTO=false -DSEND_PRONTO=false -[core_active] -platform = ${tasmota_core.platform} -platform_packages = ${tasmota_core.platform_packages} -build_flags = ${tasmota_core.build_flags} -[tasmota_core] +[core] ; *** Esp8266 Arduino core 2.7.1 platform = espressif8266@2.5.3 platform_packages = +build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From 34d5e8bc50f112264e288bde7972d64c54a5c76b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 19 Jun 2020 20:25:02 +0200 Subject: [PATCH 294/581] Refactor... and add missing entrys --- platformio_override_sample.ini | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 81cf0dec0..1c8745c50 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -7,8 +7,6 @@ ; ; Please visit documentation for the options and examples ; http://docs.platformio.org/en/stable/projectconf.html -; - [platformio] extra_configs = platformio_tasmota_env32.ini @@ -42,7 +40,6 @@ platform = ${core_active.platform} platform_packages = ${core_active.platform_packages} build_unflags = ${core_active.build_unflags} build_flags = ${core_active.build_flags} - ; *** Optional Debug messages ; -DDEBUG_TASMOTA_CORE ; -DDEBUG_TASMOTA_DRIVER @@ -90,10 +87,11 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage -extends = tasmota_core +extends = core platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#52b3e5b7b3ccedcede665682f7896b637b64dbf5 -build_unflags = -Wall +build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} + ; *********** Alternative Options, enable only if you know exactly what you do ******** ; NONOSDK221 ; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK221 @@ -125,9 +123,9 @@ build_flags = ${esp82xx_defaults.build_flags} [core_stage] ; *** Esp8266 core for Arduino version latest development version -extends = tasmota_core +extends = core platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git -build_unflags = -Wall +build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} ; *********** Alternative Options, enable only if you know exactly what you do ******** @@ -162,7 +160,10 @@ build_flags = ${esp82xx_defaults.build_flags} ; *** Debug version used for PlatformIO Home Project Inspection [env:tasmota-debug] -build_type = debug +extends = core +build_type = debug +build_unflags = ${esp_defaults.build_unflags} +build_flags = ${esp82xx_defaults.build_flags} ; *** Experimental ESP32 Tasmota version *** @@ -177,7 +178,7 @@ board_build.partitions = esp32_partition_app1984k_spiffs64k.csv board_build.flash_mode = ${common.board_build.flash_mode} board_build.f_flash = ${common.board_build.f_flash} board_build.f_cpu = ${common.board_build.f_cpu} -build_unflags = ${common.build_unflags} +build_unflags = ${esp_defaults.build_unflags} -Wpointer-arith monitor_speed = ${common.monitor_speed} upload_port = ${common.upload_port} From ca38d81b22e82de5010e8b66dfdb3765644dc3d9 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Fri, 19 Jun 2020 20:54:37 +0200 Subject: [PATCH 295/581] EZSP milestone 2 --- tasmota/i18n.h | 3 + tasmota/xdrv_23_zigbee_0_constants.ino | 503 +++++++++++++ tasmota/xdrv_23_zigbee_7_statemachine.ino | 114 ++- tasmota/xdrv_23_zigbee_8_parsers.ino | 84 +++ tasmota/xdrv_23_zigbee_9_serial.ino | 696 ++++++++++++++++++ ...e_9_impl.ino => xdrv_23_zigbee_A_impl.ino} | 515 +------------ 6 files changed, 1399 insertions(+), 516 deletions(-) create mode 100644 tasmota/xdrv_23_zigbee_9_serial.ino rename tasmota/{xdrv_23_zigbee_9_impl.ino => xdrv_23_zigbee_A_impl.ino} (70%) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index ccbb6b399..b3537b59c 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -506,13 +506,16 @@ #define D_JSON_ZIGBEE_CC2530 "CC2530" #define D_CMND_ZIGBEEZNPRECEIVE "ZNPReceive" // only for debug #define D_CMND_ZIGBEE_EZSP_RECEIVE "EZSPReceive" // only for debug +#define D_CMND_ZIGBEE_EZSP_RECEIVE_RAW "EZSPReceiveRaw" // only for debug #define D_CMND_ZIGBEEZNPSEND "ZNPSend" #define D_CMND_ZIGBEE_EZSP_SEND "EZSPSend" +#define D_CMND_ZIGBEE_EZSP_SEND_RAW "EZSPSendRaw" #define D_JSON_ZIGBEE_STATE "ZbState" #define D_JSON_ZIGBEEZNPRECEIVED "ZbZNPReceived" #define D_JSON_ZIGBEE_EZSP_RECEIVED "ZbEZSPReceived" #define D_JSON_ZIGBEEZNPSENT "ZbZNPSent" #define D_JSON_ZIGBEE_EZSP_SENT "ZbEZSPSent" + #define D_JSON_ZIGBEE_EZSP_SENT_RAW "ZbEZSPSentRaw" #define D_JSON_ZIGBEEZCL_RECEIVED "ZbZCLReceived" #define D_JSON_ZIGBEEZCL_RAW_RECEIVED "ZbZCLRawReceived" #define D_JSON_ZIGBEE_DEVICE "Device" diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index 92e88c708..467f70e35 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -55,6 +55,509 @@ enum ZnpSubsystem { }; #endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + +enum EZSPCondigId { + EZSP_CONFIG_PACKET_BUFFER_COUNT = 0x01, + EZSP_CONFIG_NEIGHBOR_TABLE_SIZE = 0x02, + EZSP_CONFIG_APS_UNICAST_MESSAGE_COUNT = 0x03, + EZSP_CONFIG_BINDING_TABLE_SIZE = 0x04, + EZSP_CONFIG_ADDRESS_TABLE_SIZE = 0x05, + EZSP_CONFIG_MULTICAST_TABLE_SIZE = 0x06, + EZSP_CONFIG_ROUTE_TABLE_SIZE = 0x07, + EZSP_CONFIG_DISCOVERY_TABLE_SIZE = 0x08, + EZSP_CONFIG_STACK_PROFILE = 0x0C, + EZSP_CONFIG_SECURITY_LEVEL = 0x0D, + EZSP_CONFIG_MAX_HOPS = 0x10, + EZSP_CONFIG_MAX_END_DEVICE_CHILDREN = 0x11, + EZSP_CONFIG_INDIRECT_TRANSMISSION_TIMEOUT = 0x12, + EZSP_CONFIG_END_DEVICE_POLL_TIMEOUT = 0x13, + EZSP_CONFIG_TX_POWER_MODE = 0x17, + EZSP_CONFIG_DISABLE_RELAY = 0x18, + EZSP_CONFIG_TRUST_CENTER_ADDRESS_CACHE_SIZE = 0x19, + EZSP_CONFIG_SOURCE_ROUTE_TABLE_SIZE = 0x1A, + EZSP_CONFIG_FRAGMENT_WINDOW_SIZE = 0x1C, + EZSP_CONFIG_FRAGMENT_DELAY_MS = 0x1D, + EZSP_CONFIG_KEY_TABLE_SIZE = 0x1E, + EZSP_CONFIG_APS_ACK_TIMEOUT = 0x1F, + EZSP_CONFIG_BEACON_JITTER_DURATION = 0x20, + EZSP_CONFIG_END_DEVICE_BIND_TIMEOUT = 0x21, + EZSP_CONFIG_PAN_ID_CONFLICT_REPORT_THRESHOLD = 0x22, + EZSP_CONFIG_REQUEST_KEY_TIMEOUT = 0x24, + EZSP_CONFIG_CERTIFICATE_TABLE_SIZE = 0x29, + EZSP_CONFIG_APPLICATION_ZDO_FLAGS = 0x2A, + EZSP_CONFIG_BROADCAST_TABLE_SIZE = 0x2B, + EZSP_CONFIG_MAC_FILTER_TABLE_SIZE = 0x2C, + EZSP_CONFIG_SUPPORTED_NETWORKS = 0x2D, + EZSP_CONFIG_SEND_MULTICASTS_TO_SLEEPY_ADDRESS = 0x2E, + EZSP_CONFIG_ZLL_GROUP_ADDRESSES = 0x2F, + EZSP_CONFIG_ZLL_RSSI_THRESHOLD = 0x30, + EZSP_CONFIG_MTORR_FLOW_CONTROL = 0x33, + EZSP_CONFIG_RETRY_QUEUE_SIZE = 0x34, + EZSP_CONFIG_NEW_BROADCAST_ENTRY_THRESHOLD = 0x35, + EZSP_CONFIG_BROADCAST_MIN_ACKS_NEEDED = 0x37, + EZSP_CONFIG_TC_REJOINS_USING_WELL_KNOWN_KEY_TIMEOUT_S = 0x38, + EZSP_CONFIG_CTUNE_VALUE = 0x39 +}; + +enum EZSPValueId { + EZSP_VALUE_TOKEN_STACK_NODE_DATA = 0x00, + EZSP_VALUE_MAC_PASSTHROUGH_FLAGS = 0x01, + EZSP_VALUE_EMBERNET_PASSTHROUGH_SOURCE_ADDRESS = 0x02, + EZSP_VALUE_FREE_BUFFERS = 0x03, + EZSP_VALUE_UART_SYNCH_CALLBACKS = 0x04, + EZSP_VALUE_MAXIMUM_INCOMING_TRANSFER_SIZE = 0x05, + EZSP_VALUE_MAXIMUM_OUTGOING_TRANSFER_SIZE = 0x06, + EZSP_VALUE_STACK_TOKEN_WRITING = 0x07, + EZSP_VALUE_STACK_IS_PERFORMING_REJOIN = 0x08, + EZSP_VALUE_MAC_FILTER_LIST = 0x09, + EZSP_VALUE_EXTENDED_SECURITY_BITMASK = 0x0A, + EZSP_VALUE_NODE_SHORT_ID = 0x0B, + EZSP_VALUE_DESCRIPTOR_CAPABILITY = 0x0C, + EZSP_VALUE_STACK_DEVICE_REQUEST_SEQUENCE_NUMBER = 0x0D, + EZSP_VALUE_RADIO_HOLD_OFF = 0x0E, + EZSP_VALUE_ENDPOINT_FLAGS = 0x0F, + EZSP_VALUE_MFG_SECURITY_CONFIG = 0x10, + EZSP_VALUE_VERSION_INFO = 0x11, + EZSP_VALUE_NEXT_HOST_REJOIN_REASON = 0x12, + EZSP_VALUE_LAST_REJOIN_REASON = 0x13, + EZSP_VALUE_NEXT_ZIGBEE_SEQUENCE_NUMBER = 0x14, + EZSP_VALUE_CCA_THRESHOLD = 0x15, + EZSP_VALUE_SET_COUNTER_THRESHOLD = 0x17, + EZSP_VALUE_RESET_COUNTER_THRESHOLDS = 0x18, + EZSP_VALUE_CLEAR_COUNTERS = 0x19, + EZSP_VALUE_CERTIFICATE_283K1 = 0x1A, + EZSP_VALUE_PUBLIC_KEY_283K1 = 0x1B, + EZSP_VALUE_PRIVATE_KEY_283K1 = 0x1C, + EZSP_VALUE_NWK_FRAME_COUNTER = 0x23, + EZSP_VALUE_APS_FRAME_COUNTER = 0x24, + EZSP_VALUE_RETRY_DEVICE_TYPE = 0x25, + EZSP_VALUE_ENABLE_R21_BEHAVIOR = 0x29, + EZSP_VALUE_ANTENNA_MODE = 0x30, + EZSP_VALUE_ENABLE_PTA = 0x31, + EZSP_VALUE_PTA_OPTIONS = 0x32, + EZSP_VALUE_MFGLIB_OPTIONS = 0x33, + EZSP_VALUE_USE_NEGOTIATED_POWER_BY_LPD = 0x34, + EZSP_VALUE_PTA_PWM_OPTIONS = 0x35, + EZSP_VALUE_PTA_DIRECTIONAL_PRIORITY_PULSE_WIDTH = 0x36, + EZSP_VALUE_PTA_PHY_SELECT_TIMEOUT = 0x37, + EZSP_VALUE_ANTENNA_RX_MODE = 0x38, + EZSP_VALUE_NWK_KEY_TIMEOUT = 0x39, + EZSP_VALUE_FORCE_TX_AFTER_FAILED_CCA_ATTEMPTS = 0x3A, + EZSP_VALUE_TRANSIENT_KEY_TIMEOUT_S = 0x3B, + ZSP_VALUE_COULOMB_COUNTER_USAGE = 0x3C, + EZSP_VALUE_MAX_BEACONS_TO_STORE = 0x3D, + EZSP_VALUE_END_DEVICE_TIMEOUT_OPTIONS_MASK = 0x3E, + EZSP_VALUE_END_DEVICE_KEEP_ALIVE_SUPPORT_MODE = 0x3F, + EZSP_VALUE_GPIO_RADIO_POWER_MASK = 0x40, + EZSP_VALUE_ACTIVE_RADIO_CONFIG = 0x41 +}; + +enum EZSPEmberStatusId { + EMBER_SUCCESS = 0x00, + EMBER_ERR_FATAL = 0x01, + EMBER_BAD_ARGUMENT = 0x02, + EMBER_EEPROM_MFG_STACK_VERSION_MISMATCH = 0x04, + EMBER_INCOMPATIBLE_STATIC_MEMORY_DEFINITIONS = 0x05, + EMBER_EEPROM_MFG_VERSION_MISMATCH = 0x06, + EMBER_EEPROM_STACK_VERSION_MISMATCH = 0x07, + EMBER_NO_BUFFERS = 0x18, + EMBER_SERIAL_INVALID_BAUD_RATE = 0x20, + EMBER_SERIAL_INVALID_PORT = 0x21, + EMBER_SERIAL_TX_OVERFLOW = 0x22, + EMBER_SERIAL_RX_OVERFLOW = 0x23, + EMBER_SERIAL_RX_FRAME_ERROR = 0x24, + EMBER_SERIAL_RX_PARITY_ERROR = 0x25, + EMBER_SERIAL_RX_EMPTY = 0x26, + EMBER_SERIAL_RX_OVERRUN_ERROR = 0x27, + EMBER_MAC_TRANSMIT_QUEUE_FULL = 0x39, + EMBER_MAC_UNKNOWN_HEADER_TYPE = 0x3A, + EMBER_MAC_SCANNING = 0x3D, + EMBER_MAC_NO_DATA = 0x31, + EMBER_MAC_JOINED_NETWORK = 0x32, + EMBER_MAC_BAD_SCAN_DURATION = 0x33, + EMBER_MAC_INCORRECT_SCAN_TYPE = 0x34, + EMBER_MAC_INVALID_CHANNEL_MASK = 0x35, + EMBER_MAC_COMMAND_TRANSMIT_FAILURE = 0x36, + EMBER_MAC_NO_ACK_RECEIVED = 0x40, + EMBER_MAC_INDIRECT_TIMEOUT = 0x42, + EMBER_SIM_EEPROM_ERASE_PAGE_GREEN = 0x43, + EMBER_SIM_EEPROM_ERASE_PAGE_RED = 0x44, + EMBER_SIM_EEPROM_FULL = 0x45, + EMBER_ERR_FLASH_WRITE_INHIBITED = 0x46, + EMBER_ERR_FLASH_VERIFY_FAILED = 0x47, + EMBER_SIM_EEPROM_INIT_1_FAILED = 0x48, + EMBER_SIM_EEPROM_INIT_2_FAILED = 0x49, + EMBER_SIM_EEPROM_INIT_3_FAILED = 0x4A, + EMBER_ERR_FLASH_PROG_FAIL = 0x4B, + EMBER_ERR_FLASH_ERASE_FAIL = 0x4C, + EMBER_ERR_BOOTLOADER_TRAP_TABLE_BAD = 0x58, + EMBER_ERR_BOOTLOADER_TRAP_UNKNOWN = 0x59, + EMBER_ERR_BOOTLOADER_NO_IMAGE = 0x5A, + EMBER_DELIVERY_FAILED = 0x66, + EMBER_BINDING_INDEX_OUT_OF_RANGE = 0x69, + EMBER_ADDRESS_TABLE_INDEX_OUT_OF_RANGE = 0x6A, + EMBER_INVALID_BINDING_INDEX = 0x6C, + EMBER_INVALID_CALL = 0x70, + EMBER_COST_NOT_KNOWN = 0x71, + EMBER_MAX_MESSAGE_LIMIT_REACHED = 0x72, + EMBER_MESSAGE_TOO_LONG = 0x74, + EMBER_BINDING_IS_ACTIVE = 0x75, + EMBER_ADDRESS_TABLE_ENTRY_IS_ACTIVE = 0x76, + EMBER_ADC_CONVERSION_DONE = 0x80, + EMBER_ADC_CONVERSION_BUSY = 0x81, + EMBER_ADC_CONVERSION_DEFERRED = 0x82, + EMBER_ADC_NO_CONVERSION_PENDING = 0x84, + EMBER_SLEEP_INTERRUPTED = 0x85, + EMBER_PHY_TX_UNDERFLOW = 0x88, + EMBER_PHY_TX_INCOMPLETE = 0x89, + EMBER_PHY_INVALID_CHANNEL = 0x8A, + EMBER_PHY_INVALID_POWER = 0x8B, + EMBER_PHY_TX_BUSY = 0x8C, + EMBER_PHY_TX_CCA_FAIL = 0x8D, + EMBER_PHY_OSCILLATOR_CHECK_FAILED = 0x8E, + EMBER_PHY_ACK_RECEIVED = 0x8F, + EMBER_NETWORK_UP = 0x90, + EMBER_NETWORK_DOWN = 0x91, + EMBER_JOIN_FAILED = 0x94, + EMBER_MOVE_FAILED = 0x96, + EMBER_CANNOT_JOIN_AS_ROUTER = 0x98, + EMBER_NODE_ID_CHANGED = 0x99, + EMBER_PAN_ID_CHANGED = 0x9A, + EMBER_NO_BEACONS = 0xAB, + EMBER_RECEIVED_KEY_IN_THE_CLEAR = 0xAC, + EMBER_NO_NETWORK_KEY_RECEIVED = 0xAD, + EMBER_NO_LINK_KEY_RECEIVED = 0xAE, + EMBER_PRECONFIGURED_KEY_REQUIRED = 0xAF, + EMBER_NOT_JOINED = 0x93, + EMBER_INVALID_SECURITY_LEVEL = 0x95, + EMBER_NETWORK_BUSY = 0xA1, + EMBER_INVALID_ENDPOINT = 0xA3, + EMBER_BINDING_HAS_CHANGED = 0xA4, + EMBER_INSUFFICIENT_RANDOM_DATA = 0xA5, + EMBER_APS_ENCRYPTION_ERROR = 0xA6, + EMBER_SECURITY_STATE_NOT_SET = 0xA8, + EMBER_KEY_TABLE_INVALID_ADDRESS = 0xB3, + EMBER_SECURITY_CONFIGURATION_INVALID = 0xB7, + EMBER_TOO_SOON_FOR_SWITCH_KEY = 0xB8, + EMBER_KEY_NOT_AUTHORIZED = 0xBB, + EMBER_SECURITY_DATA_INVALID = 0xBD, + EMBER_SOURCE_ROUTE_FAILURE = 0xA9, + EMBER_MANY_TO_ONE_ROUTE_FAILURE = 0xAA, + EMBER_STACK_AND_HARDWARE_MISMATCH = 0xB0, + EMBER_INDEX_OUT_OF_RANGE = 0xB1, + EMBER_TABLE_FULL = 0xB4, + EMBER_TABLE_ENTRY_ERASED = 0xB6, + EMBER_LIBRARY_NOT_PRESENT = 0xB5, + EMBER_OPERATION_IN_PROGRESS = 0xBA, +}; + +enum EZSPStatusId { + EZSP_SUCCESS = 0x00, + EZSP_SPI_ERR_FATAL = 0x10, + EZSP_SPI_ERR_NCP_RESET = 0x11, + EZSP_SPI_ERR_OVERSIZED_EZSP_FRAME = 0x12, + EZSP_SPI_ERR_ABORTED_TRANSACTION = 0x13, + EZSP_SPI_ERR_MISSING_FRAME_TERMINATOR = 0x14, + EZSP_SPI_ERR_WAIT_SECTION_TIMEOUT = 0x15, + EZSP_SPI_ERR_NO_FRAME_TERMINATOR = 0x16, + EZSP_SPI_ERR_EZSP_COMMAND_OVERSIZED = 0x17, + EZSP_SPI_ERR_EZSP_RESPONSE_OVERSIZED = 0x18, + EZSP_SPI_WAITING_FOR_RESPONSE = 0x19, + EZSP_SPI_ERR_HANDSHAKE_TIMEOUT = 0x1A, + EZSP_SPI_ERR_STARTUP_TIMEOUT = 0x1B, + EZSP_SPI_ERR_STARTUP_FAIL = 0x1C, + EZSP_SPI_ERR_UNSUPPORTED_SPI_COMMAND = 0x1D, + EZSP_ASH_IN_PROGRESS = 0x20, + EZSP_HOST_FATAL_ERROR = 0x21, + EZSP_ASH_NCP_FATAL_ERROR = 0x22, + EZSP_DATA_FRAME_TOO_LONG = 0x23, + EZSP_DATA_FRAME_TOO_SHORT = 0x24, + EZSP_NO_TX_SPACE = 0x25, + EZSP_NO_RX_SPACE = 0x26, + EZSP_NO_RX_DATA = 0x27, + EZSP_NOT_CONNECTED = 0x28, + EZSP_ERROR_VERSION_NOT_SET = 0x30, + EZSP_ERROR_INVALID_FRAME_ID = 0x31, + EZSP_ERROR_WRONG_DIRECTION = 0x32, + EZSP_ERROR_TRUNCATED = 0x33, + EZSP_ERROR_OVERFLOW = 0x34, + EZSP_ERROR_OUT_OF_MEMORY = 0x35, + EZSP_ERROR_INVALID_VALUE = 0x36, + EZSP_ERROR_INVALID_ID = 0x37, + EZSP_ERROR_INVALID_CALL = 0x38, + EZSP_ERROR_NO_RESPONSE = 0x39, + EZSP_ERROR_COMMAND_TOO_LONG = 0x40, + EZSP_ERROR_QUEUE_FULL = 0x41, + EZSP_ERROR_COMMAND_FILTERED = 0x42, + EZSP_ERROR_SECURITY_KEY_ALREADY_SET = 0x43, + EZSP_ERROR_SECURITY_TYPE_INVALID = 0x44, + EZSP_ERROR_SECURITY_PARAMETERS_INVALID = 0x45, + EZSP_ERROR_SECURITY_PARAMETERS_ALREADY_SET = 0x46, + EZSP_ERROR_SECURITY_KEY_NOT_SET = 0x47, + EZSP_ERROR_SECURITY_PARAMETERS_NOT_SET = 0x48, + EZSP_ERROR_UNSUPPORTED_CONTROL = 0x49, + EZSP_ERROR_UNSECURE_FRAME = 0x4A, + EZSP_NO_ERROR = 0xFF +}; + +enum EZSP_Commands { + EZSP_version = 0x0000, + EZSP_getLibraryStatus = 0x0001, + EZSP_addEndpoint = 0x0002, + EZSP_getExtendedValue = 0x0003, + EZSP_getNextBeacon = 0x0004, + EZSP_nop = 0x0005, + EZSP_callback = 0x0006, + EZSP_noCallbacks = 0x0007, + EZSP_getNumStoredBeacons = 0x0008, + EZSP_setToken = 0x0009, + EZSP_getToken = 0x000A, + EZSP_getMfgToken = 0x000B, + EZSP_setMfgToken = 0x000C, + EZSP_stackTokenChangedHandler = 0x000D, + EZSP_setTimer = 0x000E, + EZSP_timerHandler = 0x000F, + EZSP_setConcentrator = 0x0010, + EZSP_setBrokenRouteErrorCode = 0x0011, + EZSP_debugWrite = 0x0012, + EZSP_getXncpInfo = 0x0013, + EZSP_requestLinkKey = 0x0014, + EZSP_setManufacturerCode = 0x0015, + EZSP_setPowerDescriptor = 0x0016, + EZSP_networkInit = 0x0017, + EZSP_networkState = 0x0018, + EZSP_stackStatusHandler = 0x0019, + EZSP_startScan = 0x001A, + EZSP_networkFoundHandler = 0x001B, + EZSP_scanCompleteHandler = 0x001C, + EZSP_stopScan = 0x001D, + EZSP_formNetwork = 0x001E, + EZSP_joinNetwork = 0x001F, + EZSP_leaveNetwork = 0x0020, + EZSP_findAndRejoinNetwork = 0x0021, + EZSP_permitJoining = 0x0022, + EZSP_childJoinHandler = 0x0023, + EZSP_trustCenterJoinHandler = 0x0024, + EZSP_zllClearTokens = 0x0025, + EZSP_getEui64 = 0x0026, + EZSP_getNodeId = 0x0027, + EZSP_getNetworkParameters = 0x0028, + EZSP_getParentChildParameters = 0x0029, + EZSP_clearBindingTable = 0x002A, + EZSP_setBinding = 0x002B, + EZSP_getBinding = 0x002C, + EZSP_deleteBinding = 0x002D, + EZSP_bindingIsActive = 0x002E, + EZSP_getBindingRemoteNodeId = 0x002F, + EZSP_setBindingRemoteNodeId = 0x0030, + EZSP_remoteSetBindingHandler = 0x0031, + EZSP_remoteDeleteBindingHandler = 0x0032, + EZSP_maximumPayloadLength = 0x0033, + EZSP_sendUnicast = 0x0034, + EZSP_getDutyCycleState = 0x0035, + EZSP_sendBroadcast = 0x0036, + EZSP_proxyBroadcast = 0x0037, + EZSP_sendMulticast = 0x0038, + EZSP_sendReply = 0x0039, + EZSP_sendMulticastWithAlias = 0x003A, + EZSP_joinNetworkDirectly = 0x003B, + EZSP_clearStoredBeacons = 0x003C, + EZSP_getFirstBeacon = 0x003D, + EZSP_getNeighborFrameCounter = 0x003E, + EZSP_messageSentHandler = 0x003F, + EZSP_setDutyCycleLimitsInStack = 0x0040, + EZSP_sendManyToOneRouteRequest = 0x0041, + EZSP_pollForData = 0x0042, + EZSP_pollCompleteHandler = 0x0043, + EZSP_pollHandler = 0x0044, + EZSP_incomingMessageHandler = 0x0045, + EZSP_macFilterMatchMessageHandler = 0x0046, + EZSP_customFrame = 0x0047, + EZSP_energyScanResultHandler = 0x0048, + EZSP_getRandomNumber = 0x0049, + EZSP_getChildData = 0x004A, + EZSP_getDutyCycleLimits = 0x004B, + EZSP_getCurrentDutyCycle = 0x004C, + EZSP_dutyCycleHandler = 0x004D, + EZSP_getTimer = 0x004E, + EZSP_getTrueRandomEntropySource = 0x004F, + EZSP_unicastCurrentNetworkKey = 0x0050, + EZSP_sendRawMessageExtended = 0x0051, + EZSP_getConfigurationValue = 0x0052, + EZSP_setConfigurationValue = 0x0053, + EZSP_customFrameHandler = 0x0054, + EZSP_setPolicy = 0x0055, + EZSP_getPolicy = 0x0056, + EZSP_invalidCommand = 0x0058, + EZSP_setSourceRouteDiscoveryMode = 0x005A, + EZSP_addressTableEntryIsActive = 0x005B, + EZSP_setAddressTableRemoteEui64 = 0x005C, + EZSP_setAddressTableRemoteNodeId = 0x005D, + EZSP_getAddressTableRemoteEui64 = 0x005E, + EZSP_getAddressTableRemoteNodeId = 0x005F, + EZSP_lookupNodeIdByEui64 = 0x0060, + EZSP_lookupEui64ByNodeId = 0x0061, + EZSP_incomingSenderEui64Handler = 0x0062, + EZSP_getMulticastTableEntry = 0x0063, + EZSP_setMulticastTableEntry = 0x0064, + EZSP_readAndClearCounters = 0x0065, + EZSP_addOrUpdateKeyTableEntry = 0x0066, + EZSP_sendTrustCenterLinkKey = 0x0067, + EZSP_setInitialSecurityState = 0x0068, + EZSP_getCurrentSecurityState = 0x0069, + EZSP_getKey = 0x006A, + EZSP_clearTransientLinkKeys = 0x006B, + EZSP_updateTcLinkKey = 0x006C, + EZSP_getTransientKeyTableEntry = 0x006D, + EZSP_switchNetworkKeyHandler = 0x006E, + EZSP_aesMmoHash = 0x006F, + EZSP_gpSinkTableInit = 0x0070, + EZSP_getKeyTableEntry = 0x0071, + EZSP_setKeyTableEntry = 0x0072, + EZSP_broadcastNextNetworkKey = 0x0073, + EZSP_broadcastNetworkKeySwitch = 0x0074, + EZSP_findKeyTableEntry = 0x0075, + EZSP_eraseKeyTableEntry = 0x0076, + EZSP_becomeTrustCenter = 0x0077, + EZSP_dsaVerifyHandler = 0x0078, + EZSP_getNeighbor = 0x0079, + EZSP_neighborCount = 0x007A, + EZSP_getRouteTableEntry = 0x007B, + EZSP_idConflictHandler = 0x007C, + EZSP_incomingManyToOneRouteRequestHandler = 0x007D, + EZSP_setExtendedTimeout = 0x007E, + EZSP_getExtendedTimeout = 0x007F, + EZSP_incomingRouteErrorHandler = 0x0080, + EZSP_echo = 0x0081, + EZSP_replaceAddressTableEntry = 0x0082, + EZSP_mfglibStart = 0x0083, + EZSP_mfglibEnd = 0x0084, + EZSP_mfglibStartTone = 0x0085, + EZSP_mfglibStopTone = 0x0086, + EZSP_mfglibStartStream = 0x0087, + EZSP_mfglibStopStream = 0x0088, + EZSP_mfglibSendPacket = 0x0089, + EZSP_mfglibSetChannel = 0x008A, + EZSP_mfglibGetChannel = 0x008B, + EZSP_mfglibSetPower = 0x008C, + EZSP_mfglibGetPower = 0x008D, + EZSP_mfglibRxHandler = 0x008E, + EZSP_launchStandaloneBootloader = 0x008F, + EZSP_sendBootloadMessage = 0x0090, + EZSP_getStandaloneBootloaderVersionPlatMicroPhy = 0x0091, + EZSP_incomingBootloadMessageHandler = 0x0092, + EZSP_bootloadTransmitCompleteHandler = 0x0093, + EZSP_aesEncrypt = 0x0094, + EZSP_overrideCurrentChannel = 0x0095, + EZSP_sendRawMessage = 0x0096, + EZSP_macPassthroughMessageHandler = 0x0097, + EZSP_rawTransmitCompleteHandler = 0x0098, + EZSP_setRadioPower = 0x0099, + EZSP_setRadioChannel = 0x009A, + EZSP_zigbeeKeyEstablishmentHandler = 0x009B, + EZSP_energyScanRequest = 0x009C, + EZSP_delayTest = 0x009D, + EZSP_generateCbkeKeysHandler = 0x009E, + EZSP_calculateSmacs = 0x009F, + EZSP_calculateSmacsHandler = 0x00A0, + EZSP_clearTemporaryDataMaybeStoreLinkKey = 0x00A1, + EZSP_setPreinstalledCbkeData = 0x00A2, + EZSP_dsaVerify = 0x00A3, + EZSP_generateCbkeKeys = 0x00A4, + EZSP_getCertificate = 0x00A5, + EZSP_dsaSign = 0x00A6, + EZSP_dsaSignHandler = 0x00A7, + EZSP_removeDevice = 0x00A8, + EZSP_unicastNwkKeyUpdate = 0x00A9, + EZSP_getValue = 0x00AA, + EZSP_setValue = 0x00AB, + EZSP_setGpioCurrentConfiguration = 0x00AC, + EZSP_setGpioPowerUpDownConfiguration = 0x00AD, + EZSP_setGpioRadioPowerMask = 0x00AE, + EZSP_addTransientLinkKey = 0x00AF, + EZSP_dsaVerify283k1 = 0x00B0, + EZSP_clearKeyTable = 0x00B1, + EZSP_zllNetworkOps = 0x00B2, + EZSP_zllSetInitialSecurityState = 0x00B3, + EZSP_zllStartScan = 0x00B4, + EZSP_zllSetRxOnWhenIdle = 0x00B5, + EZSP_zllNetworkFoundHandler = 0x00B6, + EZSP_zllScanCompleteHandler = 0x00B7, + EZSP_zllAddressAssignmentHandler = 0x00B8, + EZSP_setLogicalAndRadioChannel = 0x00B9, + EZSP_getLogicalChannel = 0x00BA, + EZSP_zllTouchLinkTargetHandler = 0x00BB, + EZSP_zllGetTokens = 0x00BC, + EZSP_zllSetDataToken = 0x00BD, + EZSP_isZllNetwork = 0x00BE, + EZSP_zllSetNonZllNetwork = 0x00BF, + EZSP_gpProxyTableLookup = 0x00C0, + EZSP_getSourceRouteTableEntry = 0x00C1, + EZSP_getSourceRouteTableFilledSize = 0x00C2, + EZSP_getSourceRouteTableTotalSize = 0x00C3, + EZSP_gpepIncomingMessageHandler = 0x00C5, + EZSP_dGpSend = 0x00C6, + EZSP_dGpSentHandler = 0x00C7, + EZSP_gpProxyTableGetEntry = 0x00C8, + EZSP_gpProxyTableProcessGpPairing = 0x00C9, + EZSP_setSecurityKey = 0x00CA, + EZSP_setSecurityParameters = 0x00CB, + EZSP_resetToFactoryDefaults = 0x00CC, + EZSP_getSecurityKeyStatus = 0x00CD, + EZSP_getTransientLinkKey = 0x00CE, + EZSP_zllSetSecurityStateWithoutKey = 0x00CF, + EZSP_setRoutingShortcutThreshold = 0x00D0, + EZSP_getRoutingShortcutThreshold = 0x00D1, + EZSP_unusedPanIdFoundHandler = 0x00D2, + EZSP_findUnusedPanId = 0x00D3, + EZSP_zllSetRadioIdleMode = 0x00D4, + EZSP_setZllNodeType = 0x00D5, + EZSP_setZllAdditionalState = 0x00D6, + EZSP_zllOperationInProgress = 0x00D7, + EZSP_zllRxOnWhenIdleGetActive = 0x00D8, + EZSP_getZllPrimaryChannelMask = 0x00D9, + EZSP_getZllSecondaryChannelMask = 0x00DA, + EZSP_setZllPrimaryChannelMask = 0x00DB, + EZSP_setZllSecondaryChannelMask = 0x00DC, + EZSP_gpSinkTableGetEntry = 0x00DD, + EZSP_gpSinkTableLookup = 0x00DE, + EZSP_gpSinkTableSetEntry = 0x00DF, + EZSP_gpSinkTableRemoveEntry = 0x00E0, + EZSP_gpSinkTableFindOrAllocateEntry = 0x00E1, + EZSP_gpSinkTableClearAll = 0x00E2, + EZSP_setLongUpTime = 0x00E3, + EZSP_setHubConnectivity = 0x00E4, + EZSP_isUpTimeLong = 0x00E5, + EZSP_isHubConnected = 0x00E6, + EZSP_setParentClassificationEnabled = 0x00E7, + EZSP_generateCbkeKeys283k1 = 0x00E8, + EZSP_generateCbkeKeysHandler283k1 = 0x00E9, + EZSP_calculateSmacs283k1 = 0x00EA, + EZSP_calculateSmacsHandler283k1 = 0x00EB, + EZSP_getCertificate283k1 = 0x00EC, + EZSP_savePreinstalledCbkeData283k1 = 0x00ED, + EZSP_clearTemporaryDataMaybeStoreLinkKey283k1 = 0x00EE, + EZSP_setBeaconClassificationParams = 0x00EF, + EZSP_getParentClassificationEnabled = 0x00F0, + EZSP_readCounters = 0x00F1, + EZSP_counterRolloverHandler = 0x00F2, + EZSP_getBeaconClassificationParams = 0x00F3, + EZSP_setMacPollFailureWaitTime = 0x00F4, + EZSP_sendLinkPowerDeltaRequest = 0x00F7, + EZSP_multiPhyStart = 0x00F8, + EZSP_multiPhyStop = 0x00F9, + EZSP_multiPhySetRadioPower = 0x00FA, + EZSP_multiPhySetRadioChannel = 0x00FB, + EZSP_getPhyInterfaceCount = 0x00FC, + EZSP_getRadioParameters = 0x00FD, + EZSP_writeNodeData = 0x00FE, + // Tasmota specifics + EZSP_rstAck = 0xFFFE, +}; + +#endif // USE_ZIGBEE_EZSP + // Commands in the SYS subsystem enum SysCommand { SYS_RESET = 0x00, diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index cbfe822ab..16896fd0c 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -622,17 +622,124 @@ void Z_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_pani } +// patterns for EZSP + +// wait for RSTACK, meaning the device booted +ZBM(ZBR_RSTACK, Z_B0(EZSP_rstAck), Z_B1(EZSP_rstAck)) // FEFF - internal code for RSTACK + +// call version() and ask for EZSP v8 +ZBM(ZBS_VERSION, EZSP_version, 0x00, 0x08) // 000008 +ZBM(ZBR_VERSION, EZSP_version, 0x00, 0x08, 0x02) // 00000802 - expect v8, proto v2 + +// general configuration +// inspired from bellows: https://github.com/zigpy/bellows/blob/dev/bellows/config/ezsp.py +ZBM(ZBS_SET_ADDR_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_KEY_TABLE_SIZE, 0x04, 0x00) // 53001E0400 +ZBM(ZBS_SET_MCAST_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MULTICAST_TABLE_SIZE, 0x10, 0x00) // 5300061000 +ZBM(ZBS_SET_STK_PROF, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_STACK_PROFILE, 0x02, 0x00) // 53000C0200 +ZBM(ZBS_SET_SEC_LEVEL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SECURITY_LEVEL, 0x05, 0x00) // 53000D0500 +ZBM(ZBS_SET_MAX_DEVICES, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MAX_END_DEVICE_CHILDREN, 0x18, 0x00) // 5300111800 +ZBM(ZBS_SET_INDIRECT_TMO, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_INDIRECT_TRANSMISSION_TIMEOUT, 0x00, 0x1E) // 530012001E +ZBM(ZBS_SET_TC_CACHE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_TRUST_CENTER_ADDRESS_CACHE_SIZE, 0x02, 0x00) // 5300190200 +ZBM(ZBS_SET_ROUTE_TBL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SOURCE_ROUTE_TABLE_SIZE, 0x10, 0x00) // 53001A1000 +ZBM(ZBS_SET_KEY_TBL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_KEY_TABLE_SIZE, 0x04, 0x00) // 53001E0400 +ZBM(ZBS_SET_PANID_CNFLCT, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_PAN_ID_CONFLICT_REPORT_THRESHOLD, 0x02, 0x00)// 5300220200 +// TODO APP_RECEIVES_SUPPORTED_ZDO_REQUESTS +ZBM(ZBS_SET_ZDO_REQ, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_APPLICATION_ZDO_FLAGS, 0x03, 0x00) // 53002A0300 +ZBM(ZBS_SET_NETWORKS, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SUPPORTED_NETWORKS, 0x01, 0x00) // 53002D0100 +ZBM(ZBS_SET_PACKET_BUF, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_PACKET_BUFFER_COUNT, 0xFF, 0x00) // 530001FF00 + +ZBM(ZBR_SET_OK, EZSP_setConfigurationValue, 0x00 /*high*/, 0x00 /*ok*/) // 530000 +ZBM(ZBR_SET_OK2, 0x00, 0x00 /*high*/, 0x00 /*ok*/) // 000000 - TODO why does setting EZSP_CONFIG_PACKET_BUFFER_COUNT has a different response? + +// Read some configuration values +ZBM(ZBS_GET_APS_UNI, EZSP_getConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_APS_UNICAST_MESSAGE_COUNT) // 520003 +ZBM(ZBR_GET_OK, EZSP_getConfigurationValue, 0x00 /*high*/, 0x00 /*ok*/) // 5200 - followed by the value + +// Add Endpoints +// ZBM(ZBS_ADD_ENDPOINT1, EZSP_addEndpoint, 0x00 /*high*/, 0x01 /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), +// 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, +// 0x0E /* inputClusterCount */, // actually all clusters will be received +// 0X00 /* outputClusterCount */, +// 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 +// 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 +// 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 +// 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 +// ) +ZBM(ZBS_ADD_ENDPOINT1, EZSP_addEndpoint, 0x00 /*high*/, 0x01 /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), + 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, + 0x00 /* inputClusterCount */, // actually all clusters will be received + 0X00 /* outputClusterCount */ ) // 02000104010500000000 +ZBM(ZBS_ADD_ENDPOINTB, EZSP_addEndpoint, 0x00 /*high*/, 0x0B /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), + 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, + 0x00 /* inputClusterCount */, // actually all clusters will be received + 0X00 /* outputClusterCount */ ) // 02000B04010500000000 +ZBM(ZBR_ADD_ENDPOINT, EZSP_addEndpoint, 0x00 /*high*/, 0x00 /*ok*/) // 020000 + +// set concentrator false +ZBM(ZBS_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*false*/, 0xF9,0xFF /*HIGH_RAM_CONCENTRATOR*/, + 0x58,0x02 /*minTime*/, 0x08,0x07 /*maxTime*/, 0x02 /*errThr*/, 0x05 /*failThr*/, 0x00 /*maxHops*/) // 100000F9FF58020807020500 +ZBM(ZBR_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*ok*/) // 100000 + +//False, , 600, 1800, 2, 5, 0) + +const char kResetingDevice[] PROGMEM = D_LOG_ZIGBEE "resetting EZSP device"; +const char kAbort[] PROGMEM = "Abort"; +const char kZigbeeAbort[] PROGMEM = D_LOG_ZIGBEE "Abort"; + static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_LABEL(0) ZI_NOOP() ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) - // ZI_ON_RECV_UNEXPECTED(&Z_Recv_Default) - // ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize + ZI_ON_RECV_UNEXPECTED(&Z_Recv_Default) + ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize + + // Hardware reset + ZI_LOG(LOG_LEVEL_INFO, kResetingDevice) // Log Debug: resetting EZSP device + ZI_CALL(&Z_Reset_Device, 0) // LOW = reset + ZI_WAIT(100) // wait for .1 second + ZI_CALL(&Z_Reset_Device, 1) // HIGH = release reset + + // wait for device to start + ZI_WAIT_UNTIL(5000, ZBR_RSTACK) // wait for RSTACK message + + // Init device and probe version + ZI_SEND(ZBS_VERSION) ZI_WAIT_RECV(1000, ZBR_VERSION) // check EXT PAN ID + + // configure EFR32 + ZI_SEND(ZBS_SET_ADDR_TABLE) ZI_WAIT_RECV(500, ZBR_SET_OK) // Address table size + ZI_SEND(ZBS_SET_MCAST_TABLE) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_STK_PROF) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_SEC_LEVEL) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_MAX_DEVICES) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_INDIRECT_TMO) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_TC_CACHE) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_ROUTE_TBL) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_KEY_TBL) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_PANID_CNFLCT) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_ZDO_REQ) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_NETWORKS) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_PACKET_BUF) ZI_WAIT_RECV(500, ZBR_SET_OK2) + + // read configuration + ZI_SEND(ZBS_GET_APS_UNI) ZI_WAIT_RECV_FUNC(500, ZBR_GET_OK, &Z_ReadAPSUnicastMessage) + + // add endpoint 0x01 and 0x0B + ZI_SEND(ZBS_ADD_ENDPOINT1) ZI_WAIT_RECV(500, ZBR_ADD_ENDPOINT) + ZI_SEND(ZBS_ADD_ENDPOINTB) ZI_WAIT_RECV(500, ZBR_ADD_ENDPOINT) + + // set Concentrator + ZI_SEND(ZBS_SET_CONCENTRATOR) ZI_WAIT_RECV(500, ZBR_SET_CONCENTRATOR) ZI_LABEL(ZIGBEE_LABEL_MAIN_LOOP) ZI_WAIT_FOREVER() ZI_GOTO(ZIGBEE_LABEL_READY) + + // Abort state machine, general error + ZI_LABEL(ZIGBEE_LABEL_ABORT) // Label 99: abort + ZI_MQTT_STATE(ZIGBEE_STATUS_ABORT, kAbort) + ZI_LOG(LOG_LEVEL_ERROR, kZigbeeAbort) + ZI_STOP(ZIGBEE_LABEL_ABORT) }; #endif // USE_ZIGBEE_EZSP @@ -799,6 +906,9 @@ void ZigbeeStateMachine_Run(void) { #ifdef USE_ZIGBEE_ZNP ZigbeeZNPSend((uint8_t*) cur_ptr1, cur_d8 /* len */); #endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + ZigbeeEZSPSendCmd((uint8_t*) cur_ptr1, cur_d8 /* len */, true); // send cancel byte +#endif // USE_ZIGBEE_EZSP break; case ZGB_INSTR_WAIT_UNTIL: zigbee.recv_until = true; // and reuse ZGB_INSTR_WAIT_RECV diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 7e9129d64..d7e1ba565 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -19,6 +19,81 @@ #ifdef USE_ZIGBEE +#ifdef USE_ZIGBEE_EZSP +/*********************************************************************************************\ + * Parsers for incoming EZSP messages +\*********************************************************************************************/ + +// EZSP: received ASH RSTACK frame, indicating that the MCU finished boot +int32_t Z_EZSP_RSTACK(uint8_t reset_code) { + const char *reason_str; + + switch (reset_code) { + case 0x01: reason_str = PSTR("External"); break; + case 0x02: reason_str = PSTR("Power-on"); break; + case 0x03: reason_str = PSTR("Watchdog"); break; + case 0x06: reason_str = PSTR("Assert"); break; + case 0x09: reason_str = PSTR("Bootloader"); break; + case 0x0B: reason_str = PSTR("Software"); break; + case 0x00: + default: reason_str = PSTR("Unknown"); break; + } + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"Message\":\"EFR32 booted\",\"RestartReason\":\"%s\"" + ",\"Code\":%d}}"), + ZIGBEE_STATUS_BOOT, reason_str, reset_code); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); +} + +// EZSP: received ASH ERROR frame, indicating that the MCU finished boot +int32_t Z_EZSP_ERROR(uint8_t error_code) { + const char *reason_str; + + switch (error_code) { + case 0x51: reason_str = PSTR("ACK timeout"); break; + default: reason_str = PSTR("Unknown"); break; + } + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"Message\":\"Failed state\",\"Error\":\"%s\"" + ",\"Code\":%d}}"), + ZIGBEE_STATUS_ABORT, reason_str, error_code); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); +} + +/*********************************************************************************************\ + * Default resolver +\*********************************************************************************************/ + +int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { + // Default message handler for new messages + if (zigbee.init_phase) { + // if still during initialization phase, ignore any unexpected message + return -1; // ignore message + } else { + // TODO + // for (uint32_t i = 0; i < sizeof(Z_DispatchTable)/sizeof(Z_Dispatcher); i++) { + // if (Z_ReceiveMatchPrefix(buf, Z_DispatchTable[i].match)) { + // (*Z_DispatchTable[i].func)(res, buf); + // } + // } + return -1; + } +} + +int32_t Z_ReadAPSUnicastMessage(int32_t res, class SBuffer &buf) { + // Called when receiving a response from getConfigurationValue + // Value is in bytes 2+3 + uint16_t value = buf.get16(2); + return res; +} + + +#endif // USE_ZIGBEE_EZSP + /*********************************************************************************************\ * Parsers for incoming ZNP messages \*********************************************************************************************/ @@ -597,6 +672,15 @@ void Z_SendAFInfoRequest(uint16_t shortaddr) { * Send specific EZS¨ messages \*********************************************************************************************/ +// +// Callback for loading Zigbee configuration from Flash, called by the state machine +// +int32_t Z_Reset_Device(uint8_t value) { + // TODO - GPIO is hardwired to GPIO4 + digitalWrite(4, value ? HIGH : LOW); + return 0; // continue +} + // // Send ZDO_IEEE_ADDR_REQ request to get IEEE long address // diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino new file mode 100644 index 000000000..5c492e007 --- /dev/null +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -0,0 +1,696 @@ +/* + xdrv_23_zigbee_9_serial.ino - zigbee: serial communication with MCU + + Copyright (C) 2020 Theo Arends and Stephan Hadinger + + 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_ZIGBEE + +#ifdef USE_ZIGBEE_ZNP +const uint32_t ZIGBEE_BUFFER_SIZE = 256; // Max ZNP frame is SOF+LEN+CMD1+CMD2+250+FCS = 255 +const uint8_t ZIGBEE_SOF = 0xFE; +const uint8_t ZIGBEE_SOF_ALT = 0xFF; +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP +const uint32_t ZIGBEE_BUFFER_SIZE = 256; +const uint8_t ZIGBEE_EZSP_CANCEL = 0x1A; // cancel byte +const uint8_t ZIGBEE_EZSP_EOF = 0x7E; // end of frame +const uint8_t ZIGBEE_EZSP_ESCAPE = 0x7D; // escape byte + +class EZSP_Serial_t { +public: + uint8_t to_ack = 0; // 0..7, frame number of next id to send + uint8_t from_ack = 0; // 0..7, frame to ack + uint8_t ezsp_seq = 0; // 0..255, EZSP sequence number +}; + +EZSP_Serial_t EZSP_Serial; + +#endif // USE_ZIGBEE_EZSP + +#include +TasmotaSerial *ZigbeeSerial = nullptr; + +/********************************************************************************************/ +// +// Called at event loop, checks for incoming data from the CC2530 +// +void ZigbeeInputLoop(void) { + +#ifdef USE_ZIGBEE_ZNP + static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte + static uint8_t fcs = ZIGBEE_SOF; + static uint32_t zigbee_frame_len = 5; // minimal zigbee frame length, will be updated when buf[1] is read + // Receive only valid ZNP frames: + // 00 - SOF = 0xFE + // 01 - Length of Data Field - 0..250 + // 02 - CMD1 - first byte of command + // 03 - CMD2 - second byte of command + // 04..FD - Data Field + // FE (or last) - FCS Checksum + + while (ZigbeeSerial->available()) { + yield(); + uint8_t zigbee_in_byte = ZigbeeSerial->read(); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZbInput byte=%d len=%d"), zigbee_in_byte, zigbee_buffer->len()); + + if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized + zigbee_frame_len = 5; + fcs = ZIGBEE_SOF; + // there is a rare race condition when an interrupt occurs when receiving the first byte + // in this case the first bit (lsb) is missed and Tasmota receives 0xFF instead of 0xFE + // We forgive this mistake, and next bytes are automatically resynchronized + if (ZIGBEE_SOF_ALT == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbInput forgiven first byte %02X (only for statistics)"), zigbee_in_byte); + zigbee_in_byte = ZIGBEE_SOF; + } + } + + if ((0 == zigbee_buffer->len()) && (ZIGBEE_SOF != zigbee_in_byte)) { + // waiting for SOF (Start Of Frame) byte, discard anything else + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbInput discarding byte %02X"), zigbee_in_byte); + continue; // discard + } + + if (zigbee_buffer->len() < zigbee_frame_len) { + zigbee_buffer->add8(zigbee_in_byte); + zigbee_polling_window = millis(); // Wait for more data + fcs ^= zigbee_in_byte; + } + + if (zigbee_buffer->len() >= zigbee_frame_len) { + zigbee_polling_window = 0; // Publish now + break; + } + + // recalculate frame length + if (02 == zigbee_buffer->len()) { + // We just received the Lenght byte + uint8_t len_byte = zigbee_buffer->get8(1); + if (len_byte > 250) len_byte = 250; // ZNP spec says len is 250 max + + zigbee_frame_len = len_byte + 5; // SOF + LEN + CMD1 + CMD2 + FCS = 5 bytes overhead + } + } + + if (zigbee_buffer->len() && (millis() > (zigbee_polling_window + ZIGBEE_POLLING))) { + char hex_char[(zigbee_buffer->len() * 2) + 2]; + ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); + // buffer received, now check integrity + if (zigbee_buffer->len() != zigbee_frame_len) { + // Len is not correct, log and reject frame + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received frame of wrong size %s, len %d, expected %d"), hex_char, zigbee_buffer->len(), zigbee_frame_len); + } else if (0x00 != fcs) { + // FCS is wrong, packet is corrupt, log and reject frame + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received bad FCS frame %s, %d"), hex_char, fcs); + } else { + // frame is correct + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received correct frame %s"), hex_char); + + SBuffer znp_buffer = zigbee_buffer->subBuffer(2, zigbee_frame_len - 3); // remove SOF, LEN and FCS + + ToHex_P((unsigned char*)znp_buffer.getBuffer(), znp_buffer.len(), hex_char, sizeof(hex_char)); + Response_P(PSTR("{\"" D_JSON_ZIGBEEZNPRECEIVED "\":\"%s\"}"), hex_char); + if (Settings.flag3.tuya_serial_mqtt_publish) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); + XdrvRulesProcess(); + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); + } + // now process the message + ZigbeeProcessInput(znp_buffer); + } + zigbee_buffer->setLen(0); // empty buffer + } +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte + static bool escape = false; // was the previous byte an escape? + bool frame_complete = false; // frame is ready and complete + // Receive only valid EZSP frames: + // 1A - Cancel - cancel all previous bytes + // 7D - Escape byte - following byte is escaped + // 7E - end of frame + + while (ZigbeeSerial->available()) { + yield(); + uint8_t zigbee_in_byte = ZigbeeSerial->read(); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len()); + + // if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized + // escape = false; + // frame_complete = false; + // } + + if ((0x11 == zigbee_in_byte) || (0x13 == zigbee_in_byte)) { + continue; // ignore reserved bytes XON/XOFF + } + + if (ZIGBEE_EZSP_ESCAPE == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Escape byte received")); + escape = true; + continue; + } + + if (ZIGBEE_EZSP_CANCEL == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x1A, cancel byte received, discarding %d bytes"), zigbee_buffer->len()); + zigbee_buffer->setLen(0); // empty buffer + escape = false; + frame_complete = false; + continue; // re-loop + } + + if (ZIGBEE_EZSP_EOF == zigbee_in_byte) { + // end of frame + frame_complete = true; + break; + } + + if (zigbee_buffer->len() < ZIGBEE_BUFFER_SIZE) { + if (escape) { + // invert bit 5 + zigbee_in_byte ^= 0x20; + escape = false; + } + + zigbee_buffer->add8(zigbee_in_byte); + zigbee_polling_window = millis(); // Wait for more data + } // adding bytes + } // while (ZigbeeSerial->available()) + + uint32_t frame_len = zigbee_buffer->len(); + if (frame_complete || (frame_len && (millis() > (zigbee_polling_window + ZIGBEE_POLLING)))) { + char hex_char[frame_len * 2 + 2]; + ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); + if ((frame_complete) && (frame_len >= 3)) { + // frame received and has at least 3 bytes (without EOF), checking CRC + // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": received raw frame %s"), hex_char); + uint16_t crc = 0xFFFF; // frame CRC + // compute CRC + for (uint32_t i=0; iget8(i) << 8); + for (uint32_t i=0; i<8; i++) { + if (crc & 0x8000) { + crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard + } else { + crc <<= 1; + } + } + } + + uint16_t crc_received = zigbee_buffer->get8(frame_len - 2) << 8 | zigbee_buffer->get8(frame_len - 1); + // remove 2 last bytes + + if (crc_received != crc) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %s"), crc_received, crc, hex_char); + } else { + // copy buffer + SBuffer ezsp_buffer = zigbee_buffer->subBuffer(0, frame_len - 2); // CRC + + // CRC is correct, apply de-stuffing if DATA frame + if (0 == (ezsp_buffer.get8(0) & 0x80)) { + // DATA frame + uint8_t rand = 0x42; + for (uint32_t i=1; i> 1) ^ 0xB8; } + else { rand = (rand >> 1); } + } + } + + ToHex_P((unsigned char*)ezsp_buffer.getBuffer(), ezsp_buffer.len(), hex_char, sizeof(hex_char)); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "2\":\"%s\"}"), hex_char); + if (Settings.flag3.tuya_serial_mqtt_publish) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); + XdrvRulesProcess(); + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable + } + // now process the message + ZigbeeProcessInputRaw(ezsp_buffer); + } + } else { + // the buffer timed-out, print error and discard + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %d"), hex_char); + } + zigbee_buffer->setLen(0); // empty buffer + escape = false; + frame_complete = false; + } + +#endif // USE_ZIGBEE_EZSP + +} + +/********************************************************************************************/ + +// Initialize internal structures +void ZigbeeInitSerial(void) +{ +// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem1 = %d"), ESP_getFreeHeap()); + zigbee.active = false; + if (PinUsed(GPIO_ZIGBEE_RX) && PinUsed(GPIO_ZIGBEE_TX)) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "GPIOs Rx:%d Tx:%d"), Pin(GPIO_ZIGBEE_RX), Pin(GPIO_ZIGBEE_TX)); + // if seriallog_level is 0, we allow GPIO 13/15 to switch to Hardware Serial + ZigbeeSerial = new TasmotaSerial(Pin(GPIO_ZIGBEE_RX), Pin(GPIO_ZIGBEE_TX), seriallog_level ? 1 : 2, 0, 256); // set a receive buffer of 256 bytes + ZigbeeSerial->begin(115200); + if (ZigbeeSerial->hardwareSerial()) { + ClaimSerial(); + uint32_t aligned_buffer = ((uint32_t)serial_in_buffer + 3) & ~3; + zigbee_buffer = new PreAllocatedSBuffer(sizeof(serial_in_buffer) - 3, (char*) aligned_buffer); + } else { +// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem2 = %d"), ESP_getFreeHeap()); + zigbee_buffer = new SBuffer(ZIGBEE_BUFFER_SIZE); +// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem3 = %d"), ESP_getFreeHeap()); + } + zigbee.active = true; + zigbee.init_phase = true; // start the state machine + zigbee.state_machine = true; // start the state machine + ZigbeeSerial->flush(); + } +// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem9 = %d"), ESP_getFreeHeap()); +} + +#ifdef USE_ZIGBEE_ZNP + +void ZigbeeZNPSend(const uint8_t *msg, size_t len) { + if ((len < 2) || (len > 252)) { + // abort, message cannot be less than 2 bytes for CMD1 and CMD2 + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len); + return; + } + uint8_t data_len = len - 2; // removing CMD1 and CMD2 + + if (ZigbeeSerial) { + uint8_t fcs = data_len; + + ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF); + ZigbeeSerial->write(data_len); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len); + for (uint32_t i = 0; i < len; i++) { + uint8_t b = pgm_read_byte(msg + i); + ZigbeeSerial->write(b); + fcs ^= b; + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b); + } + ZigbeeSerial->write(fcs); // finally send fcs checksum byte + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs); + } + // Now send a MQTT message to report the sent message + char hex_char[(len * 2) + 2]; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"), + ToHex_P(msg, len, hex_char, sizeof(hex_char))); +} + +// +// Same code for `ZbZNPSend` and `ZbZNPReceive` +// building the complete message (intro, length) +// +void CmndZbZNPSendOrReceive(bool send) +{ + if (ZigbeeSerial && (XdrvMailbox.data_len > 0)) { + uint8_t code; + + char *codes = RemoveSpace(XdrvMailbox.data); + int32_t size = strlen(XdrvMailbox.data); + + SBuffer buf((size+1)/2); + + while (size > 1) { + char stemp[3]; + strlcpy(stemp, codes, sizeof(stemp)); + code = strtol(stemp, nullptr, 16); + buf.add8(code); + size -= 2; + codes += 2; + } + if (send) { + // Command was `ZbZNPSend` + ZigbeeZNPSend(buf.getBuffer(), buf.len()); + } else { + // Command was `ZbZNPReceive` + ZigbeeProcessInput(buf); + } + } + ResponseCmndDone(); +} + +// For debug purposes only, simulates a message received +void CmndZbZNPReceive(void) +{ + CmndZbZNPSendOrReceive(false); +} + +void CmndZbZNPSend(void) +{ + CmndZbZNPSendOrReceive(true); +} + +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + +// internal function to output a byte, and escape it (stuffing) if needed +void ZigbeeEZSPSend_Out(uint8_t out_byte) { + switch (out_byte) { + case 0x7E: // Flag byte + case 0x11: // XON + case 0x13: // XOFF + case 0x18: // Substitute byte + case 0x1A: // Cancel byte + case 0x7D: // Escape byte + // case 0xFF: // special wake-up + ZigbeeSerial->write(ZIGBEE_EZSP_ESCAPE); // send Escape byte 0x7D + ZigbeeSerial->write(out_byte ^ 0x20); // send with bit 5 inverted + break; + default: + ZigbeeSerial->write(out_byte); // send unchanged + break; + } +} +// Send low-level EZSP frames +// +// The frame should contain the Control Byte and Data Field +// The frame shouldn't be escaped, nor randomized +// +// Before sending: +// - send Cancel byte (0x1A) if requested +// - randomize Data Field if DATA Frame +// - compute CRC16 +// - escape (stuff) reserved bytes +// - add EOF (0x7E) +// - send frame +// send_cancel: should we first send a EZSP_CANCEL (0x1A) before the message to clear any leftover +void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { + if ((len < 1) || (len > 252)) { + // abort, message cannot be less than 2 bytes for CMD1 and CMD2 + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEE_EZSP_SENT ": bad message len %d"), len); + return; + } + uint8_t data_len = len - 2; // removing CMD1 and CMD2 + + if (ZigbeeSerial) { + if (send_cancel) { + ZigbeeSerial->write(ZIGBEE_EZSP_CANCEL); // 0x1A + } + + bool data_frame = (0 == (msg[0] & 0x80)); + uint8_t rand = 0x42; // pseudo-randomizer initial value + uint16_t crc = 0xFFFF; // CRC16 CCITT initialization + + for (uint32_t i=0; i 0)) { + out_byte ^= rand; + if (rand & 1) { rand = (rand >> 1) ^ 0xB8; } + else { rand = (rand >> 1); } + } + + // compute CRC + crc = crc ^ ((uint16_t)out_byte << 8); + for (uint32_t i=0; i<8; i++) { + if (crc & 0x8000) { + crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard + } else { + crc <<= 1; + } + } + + // output byte + ZigbeeEZSPSend_Out(out_byte); + } + // send CRC16 in big-endian + ZigbeeEZSPSend_Out(crc >> 8); + ZigbeeEZSPSend_Out(crc & 0xFF); + + // finally send End of Frame + ZigbeeSerial->write(ZIGBEE_EZSP_EOF); // 0x1A + } + // Now send a MQTT message to report the sent message + char hex_char[(len * 2) + 2]; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT_RAW " %s"), + ToHex_P(msg, len, hex_char, sizeof(hex_char))); +} + +// Send an EZSP command and data +// Ex: Version with min v8 = 000008 +void ZigbeeEZSPSendCmd(const uint8_t *msg, size_t len, bool send_cancel) { + char hex_char[len*2 + 2]; + ToHex_P(msg, len, hex_char, sizeof(hex_char)); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZbEZSPSend %s"), hex_char); + + SBuffer cmd(len+3); // prefix with seq number (1 byte) and frame control bytes (2 bytes) + + cmd.add8(EZSP_Serial.ezsp_seq++); + cmd.add8(0x00); // Low byte of Frame Control + cmd.add8(0x01); // High byte of Frame Control, frameFormatVersion = 1 + cmd.addBuffer(msg, len); + + // send + ZigbeeEZSPSendDATA(cmd.getBuffer(), cmd.len(), send_cancel); +} + +// Send an EZSP DATA frame, automatically calculating the correct frame numbers +void ZigbeeEZSPSendDATA(const uint8_t *msg, size_t len, bool send_cancel) { + uint8_t control_byte = ((EZSP_Serial.to_ack & 0x07) << 4) + (EZSP_Serial.from_ack & 0x07); + // increment to_ack + EZSP_Serial.to_ack = (EZSP_Serial.to_ack + 1) & 0x07; + // build complete frame + SBuffer buf(len+1); + buf.add8(control_byte); + buf.addBuffer(msg, len); + // send + ZigbeeEZSPSendRaw(buf.getBuffer(), buf.len(), send_cancel); +} + +// Receive a high-level EZSP command/response, starting with 16-bits frame ID +int32_t ZigbeeProcessInputEZSP(class SBuffer &buf) { + // verify errors in first 2 bytes. + // TODO + // uint8_t sequence_num = buf.get8(0); + uint16_t frame_control = buf.get16(1); + bool truncated = frame_control & 0x02; + bool overflow = frame_control & 0x01; + bool callbackPending = frame_control & 0x04; + bool security_enabled = frame_control & 0x8000; + if (frame_control != 0x0180) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: specific frame_control 0x%04X"), frame_control); + } + + // remove first 2 bytes, be + for (uint32_t i=0; i> 4) + 1) & 0x07; + uint8_t ack_byte = 0x80 | EZSP_Serial.from_ack; + ZigbeeEZSPSendRaw(&ack_byte, 1, false); // send a 1-byte ACK + + // build the EZSP frame + // remove first byte + for (uint8_t i=0; i 0)) { + uint8_t code; + + char *codes = RemoveSpace(XdrvMailbox.data); + int32_t size = strlen(XdrvMailbox.data); + + SBuffer buf((size+1)/2); + + while (size > 1) { + char stemp[3]; + strlcpy(stemp, codes, sizeof(stemp)); + code = strtol(stemp, nullptr, 16); + buf.add8(code); + size -= 2; + codes += 2; + } + if (send) { + // Command was `ZbEZSPSend` + if (2 == XdrvMailbox.index) { ZigbeeEZSPSendDATA(buf.getBuffer(), buf.len(), true); } + else if (3 == XdrvMailbox.index) { ZigbeeEZSPSendRaw(buf.getBuffer(), buf.len(), true); } + else { ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); } + + } else { + // Command was `ZbEZSPReceive` + if (2 == XdrvMailbox.index) { ZigbeeProcessInput(buf); } + else if (3 == XdrvMailbox.index) { ZigbeeProcessInputRaw(buf); } + else { ZigbeeProcessInputEZSP(buf); } // TODO + } + } + ResponseCmndDone(); +} +// Variants with managed ASH frame numbers +// For debug purposes only, simulates a message received +void CmndZbEZSPReceive(void) +{ + CmndZbEZSPSendOrReceive(false); +} + +void CmndZbEZSPSend(void) +{ + CmndZbEZSPSendOrReceive(true); +} +#endif // USE_ZIGBEE_EZSP + +// +// Internal function, send the low-level frame +// Input: +// - shortaddr: 16-bits short address, or 0x0000 if group address +// - groupaddr: 16-bits group address, or 0x0000 if unicast using shortaddr +// - clusterIf: 16-bits cluster number +// - endpoint: 8-bits target endpoint (source is always 0x01), unused for group addresses. Should not be 0x00 except when sending to group address. +// - cmdId: 8-bits ZCL command number +// - clusterSpecific: boolean, is the message general cluster or cluster specific, used to create the FC byte of ZCL +// - msg: pointer to byte array, payload of ZCL message (len is following), ignored if nullptr +// - len: length of the 'msg' payload +// - needResponse: boolean, true = we ask the target to respond, false = the target should not respond +// - transacId: 8-bits, transation id of message (should be incremented at each message), used both for Zigbee message number and ZCL message number +// Returns: None +// +void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, uint16_t manuf, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId) { + +#ifdef USE_ZIGBEE_ZNP + SBuffer buf(32+len); + buf.add8(Z_SREQ | Z_AF); // 24 + buf.add8(AF_DATA_REQUEST_EXT); // 02 + if (BAD_SHORTADDR == shortaddr) { // if no shortaddr we assume group address + buf.add8(Z_Addr_Group); // 01 + buf.add64(groupaddr); // group address, only 2 LSB, upper 6 MSB are discarded + buf.add8(0xFF); // dest endpoint is not used for group addresses + } else { + buf.add8(Z_Addr_ShortAddress); // 02 + buf.add64(shortaddr); // dest address, only 2 LSB, upper 6 MSB are discarded + buf.add8(endpoint); // dest endpoint + } + buf.add16(0x0000); // dest Pan ID, 0x0000 = intra-pan + buf.add8(0x01); // source endpoint + buf.add16(clusterId); + buf.add8(transacId); // transacId + buf.add8(0x30); // 30 options + buf.add8(0x1E); // 1E radius + + buf.add16(3 + len + (manuf ? 2 : 0)); + buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field + if (manuf) { + buf.add16(manuf); // add Manuf Id if not null + } + buf.add8(transacId); // Transaction Sequance Number + buf.add8(cmdId); + if (len > 0) { + buf.addBuffer(msg, len); // add the payload + } + + ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP +} + +#endif // USE_ZIGBEE diff --git a/tasmota/xdrv_23_zigbee_9_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino similarity index 70% rename from tasmota/xdrv_23_zigbee_9_impl.ino rename to tasmota/xdrv_23_zigbee_A_impl.ino index 1cc5f6efc..bfb3015d4 100644 --- a/tasmota/xdrv_23_zigbee_9_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -21,23 +21,6 @@ #define XDRV_23 23 -#ifdef USE_ZIGBEE_ZNP -const uint32_t ZIGBEE_BUFFER_SIZE = 256; // Max ZNP frame is SOF+LEN+CMD1+CMD2+250+FCS = 255 -const uint8_t ZIGBEE_SOF = 0xFE; -const uint8_t ZIGBEE_SOF_ALT = 0xFF; -#endif // USE_ZIGBEE_ZNP - -#ifdef USE_ZIGBEE_EZSP -const uint32_t ZIGBEE_BUFFER_SIZE = 256; -const uint8_t ZIGBEE_EZSP_CANCEL = 0x1A; // cancel byte -const uint8_t ZIGBEE_EZSP_EOF = 0x7E; // end of frame -const uint8_t ZIGBEE_EZSP_ESCAPE = 0x7D; // escape byte -#endif // USE_ZIGBEE_EZSP - -#include -TasmotaSerial *ZigbeeSerial = nullptr; - - const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix #ifdef USE_ZIGBEE_ZNP D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEEZNPRECEIVE "|" @@ -68,221 +51,6 @@ void (* const ZigbeeCommand[])(void) PROGMEM = { &CmndZbConfig, }; -// -// Called at event loop, checks for incoming data from the CC2530 -// -void ZigbeeInputLoop(void) { - -#ifdef USE_ZIGBEE_ZNP - static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte - static uint8_t fcs = ZIGBEE_SOF; - static uint32_t zigbee_frame_len = 5; // minimal zigbee frame length, will be updated when buf[1] is read - // Receive only valid ZNP frames: - // 00 - SOF = 0xFE - // 01 - Length of Data Field - 0..250 - // 02 - CMD1 - first byte of command - // 03 - CMD2 - second byte of command - // 04..FD - Data Field - // FE (or last) - FCS Checksum - - while (ZigbeeSerial->available()) { - yield(); - uint8_t zigbee_in_byte = ZigbeeSerial->read(); - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZbInput byte=%d len=%d"), zigbee_in_byte, zigbee_buffer->len()); - - if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized - zigbee_frame_len = 5; - fcs = ZIGBEE_SOF; - // there is a rare race condition when an interrupt occurs when receiving the first byte - // in this case the first bit (lsb) is missed and Tasmota receives 0xFF instead of 0xFE - // We forgive this mistake, and next bytes are automatically resynchronized - if (ZIGBEE_SOF_ALT == zigbee_in_byte) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbInput forgiven first byte %02X (only for statistics)"), zigbee_in_byte); - zigbee_in_byte = ZIGBEE_SOF; - } - } - - if ((0 == zigbee_buffer->len()) && (ZIGBEE_SOF != zigbee_in_byte)) { - // waiting for SOF (Start Of Frame) byte, discard anything else - AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbInput discarding byte %02X"), zigbee_in_byte); - continue; // discard - } - - if (zigbee_buffer->len() < zigbee_frame_len) { - zigbee_buffer->add8(zigbee_in_byte); - zigbee_polling_window = millis(); // Wait for more data - fcs ^= zigbee_in_byte; - } - - if (zigbee_buffer->len() >= zigbee_frame_len) { - zigbee_polling_window = 0; // Publish now - break; - } - - // recalculate frame length - if (02 == zigbee_buffer->len()) { - // We just received the Lenght byte - uint8_t len_byte = zigbee_buffer->get8(1); - if (len_byte > 250) len_byte = 250; // ZNP spec says len is 250 max - - zigbee_frame_len = len_byte + 5; // SOF + LEN + CMD1 + CMD2 + FCS = 5 bytes overhead - } - } - - if (zigbee_buffer->len() && (millis() > (zigbee_polling_window + ZIGBEE_POLLING))) { - char hex_char[(zigbee_buffer->len() * 2) + 2]; - ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); - - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); - // buffer received, now check integrity - if (zigbee_buffer->len() != zigbee_frame_len) { - // Len is not correct, log and reject frame - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received frame of wrong size %s, len %d, expected %d"), hex_char, zigbee_buffer->len(), zigbee_frame_len); - } else if (0x00 != fcs) { - // FCS is wrong, packet is corrupt, log and reject frame - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received bad FCS frame %s, %d"), hex_char, fcs); - } else { - // frame is correct - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received correct frame %s"), hex_char); - - SBuffer znp_buffer = zigbee_buffer->subBuffer(2, zigbee_frame_len - 3); // remove SOF, LEN and FCS - - ToHex_P((unsigned char*)znp_buffer.getBuffer(), znp_buffer.len(), hex_char, sizeof(hex_char)); - Response_P(PSTR("{\"" D_JSON_ZIGBEEZNPRECEIVED "\":\"%s\"}"), hex_char); - if (Settings.flag3.tuya_serial_mqtt_publish) { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); - XdrvRulesProcess(); - } else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); - } - // now process the message - ZigbeeProcessInput(znp_buffer); - } - zigbee_buffer->setLen(0); // empty buffer - } -#endif // USE_ZIGBEE_ZNP - -#ifdef USE_ZIGBEE_EZSP - static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte - bool escape = false; // was the previous byte an escape? - bool frame_complete = false; // frame is ready and complete - // Receive only valid EZSP frames: - // 1A - Cancel - cancel all previous bytes - // 7D - Escape byte - following byte is escaped - // 7E - end of frame - - while (ZigbeeSerial->available()) { - yield(); - uint8_t zigbee_in_byte = ZigbeeSerial->read(); - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len()); - - // if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized - // escape = false; - // frame_complete = false; - // } - - if ((0x11 == zigbee_in_byte) || (0x13 == zigbee_in_byte)) { - continue; // ignore reserved bytes XON/XOFF - } - - if (ZIGBEE_EZSP_ESCAPE == zigbee_in_byte) { - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Escape byte received")); - escape = true; - continue; - } - - if (ZIGBEE_EZSP_CANCEL == zigbee_in_byte) { - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x1A, cancel byte received, discarding %d bytes"), zigbee_buffer->len()); - zigbee_buffer->setLen(0); // empty buffer - escape = false; - frame_complete = false; - continue; // re-loop - } - - if (ZIGBEE_EZSP_EOF == zigbee_in_byte) { - // end of frame - frame_complete = true; - break; - } - - if (zigbee_buffer->len() < ZIGBEE_BUFFER_SIZE) { - if (escape) { - // invert bit 5 - zigbee_in_byte ^= 0x20; - escape = false; - } - - zigbee_buffer->add8(zigbee_in_byte); - zigbee_polling_window = millis(); // Wait for more data - } // adding bytes - } // while (ZigbeeSerial->available()) - - uint32_t frame_len = zigbee_buffer->len(); - if (frame_complete || (frame_len && (millis() > (zigbee_polling_window + ZIGBEE_POLLING)))) { - char hex_char[frame_len * 2 + 2]; - ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); - - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); - if ((frame_complete) && (frame_len >= 3)) { - // frame received and has at least 3 bytes (without EOF), checking CRC - // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": received raw frame %s"), hex_char); - uint16_t crc = 0xFFFF; // frame CRC - // compute CRC - for (uint32_t i=0; iget8(i) << 8); - for (uint32_t i=0; i<8; i++) { - if (crc & 0x8000) { - crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard - } else { - crc <<= 1; - } - } - } - - uint16_t crc_received = zigbee_buffer->get8(frame_len - 2) << 8 | zigbee_buffer->get8(frame_len - 1); - // remove 2 last bytes - - if (crc_received != crc) { - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %s"), crc_received, crc, hex_char); - } else { - // copy buffer - SBuffer ezsp_buffer = zigbee_buffer->subBuffer(0, frame_len - 2); // CRC - - // CRC is correct, apply de-stuffing if DATA frame - if (0 == (ezsp_buffer.get8(0) & 0x80)) { - // DATA frame - uint8_t rand = 0x42; - for (uint32_t i=1; i> 1) ^ 0xB8; } - else { rand = (rand >> 1); } - } - } - - ToHex_P((unsigned char*)ezsp_buffer.getBuffer(), ezsp_buffer.len(), hex_char, sizeof(hex_char)); - Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "\":\"%s\"}"), hex_char); - if (Settings.flag3.tuya_serial_mqtt_publish) { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); - XdrvRulesProcess(); - } else { - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable - } - // now process the message - ZigbeeProcessInput(ezsp_buffer); - } - } else { - // the buffer timed-out, print error and discard - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %d"), hex_char); - } - zigbee_buffer->setLen(0); // empty buffer - escape = false; - frame_complete = false; - } - -#endif // USE_ZIGBEE_EZSP - -} - /********************************************************************************************/ // Initialize internal structures @@ -301,28 +69,7 @@ void ZigbeeInit(void) // update commands with the current settings Z_UpdateConfig(Settings.zb_channel, Settings.zb_pan_id, Settings.zb_ext_panid, Settings.zb_precfgkey_l, Settings.zb_precfgkey_h); -// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem1 = %d"), ESP_getFreeHeap()); - zigbee.active = false; - if (PinUsed(GPIO_ZIGBEE_RX) && PinUsed(GPIO_ZIGBEE_TX)) { - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "GPIOs Rx:%d Tx:%d"), Pin(GPIO_ZIGBEE_RX), Pin(GPIO_ZIGBEE_TX)); - // if seriallog_level is 0, we allow GPIO 13/15 to switch to Hardware Serial - ZigbeeSerial = new TasmotaSerial(Pin(GPIO_ZIGBEE_RX), Pin(GPIO_ZIGBEE_TX), seriallog_level ? 1 : 2, 0, 256); // set a receive buffer of 256 bytes - ZigbeeSerial->begin(115200); - if (ZigbeeSerial->hardwareSerial()) { - ClaimSerial(); - uint32_t aligned_buffer = ((uint32_t)serial_in_buffer + 3) & ~3; - zigbee_buffer = new PreAllocatedSBuffer(sizeof(serial_in_buffer) - 3, (char*) aligned_buffer); - } else { -// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem2 = %d"), ESP_getFreeHeap()); - zigbee_buffer = new SBuffer(ZIGBEE_BUFFER_SIZE); -// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem3 = %d"), ESP_getFreeHeap()); - } - zigbee.active = true; - zigbee.init_phase = true; // start the state machine - zigbee.state_machine = true; // start the state machine - ZigbeeSerial->flush(); - } -// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem9 = %d"), ESP_getFreeHeap()); + ZigbeeInitSerial(); } /*********************************************************************************************\ @@ -366,266 +113,6 @@ void CmndZbReset(void) { } } -#ifdef USE_ZIGBEE_ZNP - -void ZigbeeZNPSend(const uint8_t *msg, size_t len) { - if ((len < 2) || (len > 252)) { - // abort, message cannot be less than 2 bytes for CMD1 and CMD2 - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len); - return; - } - uint8_t data_len = len - 2; // removing CMD1 and CMD2 - - if (ZigbeeSerial) { - uint8_t fcs = data_len; - - ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF); - ZigbeeSerial->write(data_len); - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len); - for (uint32_t i = 0; i < len; i++) { - uint8_t b = pgm_read_byte(msg + i); - ZigbeeSerial->write(b); - fcs ^= b; - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b); - } - ZigbeeSerial->write(fcs); // finally send fcs checksum byte - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs); - } - // Now send a MQTT message to report the sent message - char hex_char[(len * 2) + 2]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"), - ToHex_P(msg, len, hex_char, sizeof(hex_char))); -} - -// -// Same code for `ZbZNPSend` and `ZbZNPReceive` -// building the complete message (intro, length) -// -void CmndZbZNPSendOrReceive(bool send) -{ - if (ZigbeeSerial && (XdrvMailbox.data_len > 0)) { - uint8_t code; - - char *codes = RemoveSpace(XdrvMailbox.data); - int32_t size = strlen(XdrvMailbox.data); - - SBuffer buf((size+1)/2); - - while (size > 1) { - char stemp[3]; - strlcpy(stemp, codes, sizeof(stemp)); - code = strtol(stemp, nullptr, 16); - buf.add8(code); - size -= 2; - codes += 2; - } - if (send) { - // Command was `ZbZNPSend` - ZigbeeZNPSend(buf.getBuffer(), buf.len()); - } else { - // Command was `ZbZNPReceive` - ZigbeeProcessInput(buf); - } - } - ResponseCmndDone(); -} - -// For debug purposes only, simulates a message received -void CmndZbZNPReceive(void) -{ - CmndZbZNPSendOrReceive(false); -} - -void CmndZbZNPSend(void) -{ - CmndZbZNPSendOrReceive(true); -} - -#endif // USE_ZIGBEE_ZNP - -#ifdef USE_ZIGBEE_EZSP - -// internal function to output a byte, and escape it (stuffing) if needed -void ZigbeeEZSPSend_Out(uint8_t out_byte) { - switch (out_byte) { - case 0x7E: // Flag byte - case 0x11: // XON - case 0x13: // XOFF - case 0x18: // Substitute byte - case 0x1A: // Cancel byte - case 0x7D: // Escape byte - ZigbeeSerial->write(ZIGBEE_EZSP_ESCAPE); // send Escape byte 0x7D - ZigbeeSerial->write(out_byte ^ 0x20); // send with bit 5 inverted - break; - default: - ZigbeeSerial->write(out_byte); // send unchanged - break; - } -} -// Send low-level EZSP frames -// -// The frame should contain the Control Byte and Data Field -// The frame shouldn't be escaped, nor randomized -// -// Before sending: -// - send Cancel byte (0x1A) if requested -// - randomize Data Field if DATA Frame -// - compute CRC16 -// - escape (stuff) reserved bytes -// - add EOF (0x7E) -// - send frame -// send_cancel: should we first send a EZSP_CANCEL (0x1A) before the message to clear any leftover -void ZigbeeEZSPSend(const uint8_t *msg, size_t len, bool send_cancel = false) { - if ((len < 1) || (len > 252)) { - // abort, message cannot be less than 2 bytes for CMD1 and CMD2 - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEE_EZSP_SENT ": bad message len %d"), len); - return; - } - uint8_t data_len = len - 2; // removing CMD1 and CMD2 - - if (ZigbeeSerial) { - if (send_cancel) { - ZigbeeSerial->write(ZIGBEE_EZSP_CANCEL); // 0x1A - } - - bool data_frame = (0 == (msg[0] & 0x80)); - uint8_t rand = 0x42; // pseudo-randomizer initial value - uint16_t crc = 0xFFFF; // CRC16 CCITT initialization - - for (uint32_t i=0; i 0)) { - out_byte ^= rand; - if (rand & 1) { rand = (rand >> 1) ^ 0xB8; } - else { rand = (rand >> 1); } - } - - // compute CRC - crc = crc ^ ((uint16_t)out_byte << 8); - for (uint32_t i=0; i<8; i++) { - if (crc & 0x8000) { - crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard - } else { - crc <<= 1; - } - } - - // output byte - ZigbeeEZSPSend_Out(out_byte); - } - // send CRC16 in big-endian - ZigbeeEZSPSend_Out(crc >> 8); - ZigbeeEZSPSend_Out(crc & 0xFF); - - // finally send End of Frame - ZigbeeSerial->write(ZIGBEE_EZSP_EOF); // 0x1A - } - // Now send a MQTT message to report the sent message - char hex_char[(len * 2) + 2]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT " %s"), - ToHex_P(msg, len, hex_char, sizeof(hex_char))); -} - -// -// Same code for `ZbZNPSend` and `ZbZNPReceive` -// building the complete message (intro, length) -// -void CmndZbEZSPSendOrReceive(bool send) -{ - if (ZigbeeSerial && (XdrvMailbox.data_len > 0)) { - uint8_t code; - - char *codes = RemoveSpace(XdrvMailbox.data); - int32_t size = strlen(XdrvMailbox.data); - - SBuffer buf((size+1)/2); - - while (size > 1) { - char stemp[3]; - strlcpy(stemp, codes, sizeof(stemp)); - code = strtol(stemp, nullptr, 16); - buf.add8(code); - size -= 2; - codes += 2; - } - if (send) { - // Command was `ZbEZSPSend` - ZigbeeEZSPSend(buf.getBuffer(), buf.len()); - } else { - // Command was `ZbEZSPReceive` - ZigbeeProcessInput(buf); - } - } - ResponseCmndDone(); -} - -// For debug purposes only, simulates a message received -void CmndZbEZSPReceive(void) -{ - CmndZbEZSPSendOrReceive(false); -} - -void CmndZbEZSPSend(void) -{ - CmndZbEZSPSendOrReceive(true); -} -#endif // USE_ZIGBEE_EZSP - -// -// Internal function, send the low-level frame -// Input: -// - shortaddr: 16-bits short address, or 0x0000 if group address -// - groupaddr: 16-bits group address, or 0x0000 if unicast using shortaddr -// - clusterIf: 16-bits cluster number -// - endpoint: 8-bits target endpoint (source is always 0x01), unused for group addresses. Should not be 0x00 except when sending to group address. -// - cmdId: 8-bits ZCL command number -// - clusterSpecific: boolean, is the message general cluster or cluster specific, used to create the FC byte of ZCL -// - msg: pointer to byte array, payload of ZCL message (len is following), ignored if nullptr -// - len: length of the 'msg' payload -// - needResponse: boolean, true = we ask the target to respond, false = the target should not respond -// - transacId: 8-bits, transation id of message (should be incremented at each message), used both for Zigbee message number and ZCL message number -// Returns: None -// -void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, uint16_t manuf, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId) { - -#ifdef USE_ZIGBEE_ZNP - SBuffer buf(32+len); - buf.add8(Z_SREQ | Z_AF); // 24 - buf.add8(AF_DATA_REQUEST_EXT); // 02 - if (BAD_SHORTADDR == shortaddr) { // if no shortaddr we assume group address - buf.add8(Z_Addr_Group); // 01 - buf.add64(groupaddr); // group address, only 2 LSB, upper 6 MSB are discarded - buf.add8(0xFF); // dest endpoint is not used for group addresses - } else { - buf.add8(Z_Addr_ShortAddress); // 02 - buf.add64(shortaddr); // dest address, only 2 LSB, upper 6 MSB are discarded - buf.add8(endpoint); // dest endpoint - } - buf.add16(0x0000); // dest Pan ID, 0x0000 = intra-pan - buf.add8(0x01); // source endpoint - buf.add16(clusterId); - buf.add8(transacId); // transacId - buf.add8(0x30); // 30 options - buf.add8(0x1E); // 1E radius - - buf.add16(3 + len + (manuf ? 2 : 0)); - buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field - if (manuf) { - buf.add16(manuf); // add Manuf Id if not null - } - buf.add8(transacId); // Transaction Sequance Number - buf.add8(cmdId); - if (len > 0) { - buf.addBuffer(msg, len); // add the payload - } - - ZigbeeZNPSend(buf.getBuffer(), buf.len()); -#endif // USE_ZIGBEE_ZNP -} - /********************************************************************************************/ // // High-level function From 37886f33c87d401d0eef98de9a6306ec5764793d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 20 Jun 2020 12:00:40 +0200 Subject: [PATCH 296/581] Fix ESP32 wESP32 template Fix ESP32 wESP32 template (#8503) --- tasmota/tasmota_template_ESP32.h | 2 +- tasmota/xdrv_82_ethernet.ino | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 80a015675..e5b30a5b1 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -686,7 +686,7 @@ const mytmplt kModules PROGMEM = {"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} -{"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} +{"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} \*********************************************************************************************/ diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index cccac57b7..dcaa5fde8 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -32,8 +32,7 @@ * GPIO27 - EMAC_RX_CRS_DV * * {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} - * {"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} - * + * {"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} \*********************************************************************************************/ #define XDRV_82 82 From 54e8e633e960b2222fd9f7d63f97f333806829ac Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 20 Jun 2020 13:18:33 +0200 Subject: [PATCH 297/581] Fix ESP32 ILI9341 using hardware SPI --- tasmota/xdsp_04_ili9341.ino | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index 48c486681..ba3fc377e 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -90,11 +90,8 @@ void Ili9341InitDriver(void) if (Settings.display_height != ILI9341_TFTHEIGHT) { Settings.display_height = ILI9341_TFTHEIGHT; } -#ifdef ESP8266 + tft = new Adafruit_ILI9341(Pin(GPIO_SPI_CS), Pin(GPIO_SPI_DC)); -#else // ESP32 - tft = new Adafruit_ILI9341(Pin(GPIO_SPI_CS), Pin(GPIO_SPI_DC), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK), -1, Pin(GPIO_SPI_MISO)); -#endif tft->begin(); #ifdef USE_DISPLAY_MODES1TO5 From 0d1dd103143d7922aaa9b4ff5daa6e7dac8659f5 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 20 Jun 2020 15:04:38 +0200 Subject: [PATCH 298/581] Update to ESP framework 1.12.4 and remove obsolete and redundant entry --- platformio_override_sample.ini | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 1c8745c50..0311c6280 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -170,7 +170,7 @@ build_flags = ${esp82xx_defaults.build_flags} ; *** expect the unexpected. Many features not working!!! *** [common32] -platform = espressif32@1.12.2 +platform = espressif32@1.12.4 platform_packages = tool-esptoolpy@1.20800.0 board = esp32dev board_build.ldscript = esp32_out.ld @@ -198,12 +198,9 @@ build_flags = ${esp_defaults.build_flags} -D sint16_t=int16_t -D memcpy_P=memcpy -D memcmp_P=memcmp - -D USE_CONFIG_OVERRIDE lib_extra_dirs = libesp32 lib_ignore = - ; ILI9488 - ; SSD3115 cc1101 From 0e2104c4ad46b30a5e8d719a41f5993d8ab6127b Mon Sep 17 00:00:00 2001 From: Federico Leoni Date: Sat, 20 Jun 2020 10:38:17 -0300 Subject: [PATCH 299/581] ESP32 fix --- tasmota/xdrv_12_home_assistant.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 476d45765..df53084a8 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -234,7 +234,7 @@ void HAssAnnounceRelayLight(void) TuyaDim = TuyaGetDpId((TUYA_MCU_FUNC_DIMMER) + active_device - 1); #endif //USE_TUYA_MCU - bool RelayX = PinUsed(GPIO_REL1 +i-1) || (valid_relay >= i) || (TuyaRel > 0 && TuyaMod) || (TuyaRelInv > 0 && TuyaMod); // Check if the gpio is configured as Relay or force it for Sonoff DUAL R1 with MCU and Tuya MCU + bool RelayX = PinUsed(GPIO_REL1, i-1) || (valid_relay >= i) || (TuyaRel > 0 && TuyaMod) || (TuyaRelInv > 0 && TuyaMod); // Check if the gpio is configured as Relay or force it for Sonoff DUAL R1 with MCU and Tuya MCU is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX || PwmMod || (TuyaDim > 0 && TuyaMod); // SetOption30 - Enforce HAss autodiscovery as light mqtt_data[0] = '\0'; // Clear retained message @@ -887,4 +887,4 @@ bool Xdrv12(uint8_t function) return result; } -#endif // USE_HOME_ASSISTANT \ No newline at end of file +#endif // USE_HOME_ASSISTANT From b5f45aa295f2e152f1d74e0d8f9cddb12572af39 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 20 Jun 2020 17:58:21 +0200 Subject: [PATCH 300/581] Fix ESP32 SPI config --- tasmota/i18n.h | 2 ++ tasmota/support.ino | 12 +++++-- tasmota/support_command.ino | 12 +++++-- tasmota/support_tasmota.ino | 53 ++++++++++++++++++++++++++++-- tasmota/xdrv_16_tuyamcu.ino | 16 ++++----- tasmota/xdrv_31_tasmota_client.ino | 2 +- tasmota/xnrg_01_hlw8012.ino | 4 +-- 7 files changed, 84 insertions(+), 17 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index b3537b59c..194ff4bc6 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -322,10 +322,12 @@ #define D_CMND_HUMOFFSET "HumOffset" #define D_CMND_GLOBAL_TEMP "GlobalTemp" #define D_CMND_GLOBAL_HUM "GlobalHum" + #ifdef ESP32 #define D_CMND_TOUCH_CAL "TouchCal" #define D_CMND_TOUCH_THRES "TouchThres" #define D_CMND_TOUCH_NUM "TouchNum" +#define D_CMND_CPU_FREQUENCY "CpuFrequency" #endif //ESP32 // Commands xdrv_01_mqtt.ino diff --git a/tasmota/support.ino b/tasmota/support.ino index 87cd0ce5e..cdd1b3cd6 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1099,11 +1099,19 @@ uint32_t Pin(uint32_t gpio, uint32_t index) { return 99; // No pin used for gpio } -boolean PinUsed(uint32_t gpio, uint32_t index = 0); -boolean PinUsed(uint32_t gpio, uint32_t index) { +bool PinUsed(uint32_t gpio, uint32_t index = 0); +bool PinUsed(uint32_t gpio, uint32_t index) { return (Pin(gpio, index) < 99); } +uint32_t GetPin(uint32_t lpin) { + if (lpin < ARRAY_SIZE(gpio_pin)) { + return gpio_pin[lpin]; + } else { + return GPIO_NONE; + } +} + void SetPin(uint32_t lpin, uint32_t gpio) { gpio_pin[lpin] = gpio; } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 565fd8fcd..76c5252a0 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -40,7 +40,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix #endif // USE_DEVICE_GROUPS D_CMND_SENSOR "|" D_CMND_DRIVER #ifdef ESP32 - "|" D_CMND_TOUCH_CAL "|" D_CMND_TOUCH_THRES "|" D_CMND_TOUCH_NUM + "|" D_CMND_TOUCH_CAL "|" D_CMND_TOUCH_THRES "|" D_CMND_TOUCH_NUM "|" D_CMND_CPU_FREQUENCY #endif //ESP32 ; @@ -67,7 +67,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { #endif // USE_DEVICE_GROUPS &CmndSensor, &CmndDriver #ifdef ESP32 - ,&CmndTouchCal, &CmndTouchThres, &CmndTouchNum + ,&CmndTouchCal, &CmndTouchThres, &CmndTouchNum, &CmndCpuFrequency #endif //ESP32 }; @@ -1977,6 +1977,14 @@ void CmndDriver(void) } #ifdef ESP32 + +void CmndCpuFrequency(void) { + if ((80 == XdrvMailbox.payload) || (160 == XdrvMailbox.payload) || (240 == XdrvMailbox.payload)) { + setCpuFrequencyMhz(XdrvMailbox.payload); + } + ResponseCmndNumber(getCpuFrequencyMhz()); +} + void CmndTouchCal(void) { if (XdrvMailbox.payload >= 0) { diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index ae32ea34b..68edd6a7a 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1591,6 +1591,7 @@ void GpioInit(void) SetPin(13, GPIO_SPI_MOSI); my_module.io[14] = GPIO_SPI_CLK; SetPin(14, GPIO_SPI_CLK); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK)")); } soft_spi_flg = (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); #endif // USE_SPI @@ -1598,7 +1599,55 @@ void GpioInit(void) analogWriteFreqRange(0, Settings.pwm_frequency, Settings.pwm_range); #ifdef USE_SPI - spi_flg = (PinUsed(GPIO_SPI_CLK) && (PinUsed(GPIO_SPI_MOSI) || PinUsed(GPIO_SPI_MISO))); + if (PinUsed(GPIO_SPI_CS) || PinUsed(GPIO_SPI_DC)) { + if ((15 == Pin(GPIO_SPI_CS)) && (!GetPin(12) && !GetPin(13) && !GetPin(14))) { // HSPI + my_module.io[12] = AGPIO(GPIO_SPI_MISO); + SetPin(12, AGPIO(GPIO_SPI_MISO)); + my_module.io[13] = AGPIO(GPIO_SPI_MOSI); + SetPin(13, AGPIO(GPIO_SPI_MOSI)); + my_module.io[14] = AGPIO(GPIO_SPI_CLK); + SetPin(14, AGPIO(GPIO_SPI_CLK)); + } + else if ((5 == Pin(GPIO_SPI_CS)) && (!GetPin(19) && !GetPin(23) && !GetPin(18))) { // VSPI + my_module.io[19] = AGPIO(GPIO_SPI_MISO); + SetPin(19, AGPIO(GPIO_SPI_MISO)); + my_module.io[23] = AGPIO(GPIO_SPI_MOSI); + SetPin(23, AGPIO(GPIO_SPI_MOSI)); + my_module.io[18] = AGPIO(GPIO_SPI_CLK); + SetPin(18, AGPIO(GPIO_SPI_CLK)); + } + else if ((12 == Pin(GPIO_SPI_MISO)) || (13 == Pin(GPIO_SPI_MOSI)) || (14 == Pin(GPIO_SPI_CLK))) { // HSPI + my_module.io[12] = AGPIO(GPIO_SPI_MISO); + SetPin(12, AGPIO(GPIO_SPI_MISO)); + my_module.io[13] = AGPIO(GPIO_SPI_MOSI); + SetPin(13, AGPIO(GPIO_SPI_MOSI)); + my_module.io[14] = AGPIO(GPIO_SPI_CLK); + SetPin(14, AGPIO(GPIO_SPI_CLK)); + } + else if ((19 == Pin(GPIO_SPI_MISO)) || (23 == Pin(GPIO_SPI_MOSI)) || (18 == Pin(GPIO_SPI_CLK))) { // VSPI + my_module.io[19] = AGPIO(GPIO_SPI_MISO); + SetPin(19, AGPIO(GPIO_SPI_MISO)); + my_module.io[23] = AGPIO(GPIO_SPI_MOSI); + SetPin(23, AGPIO(GPIO_SPI_MOSI)); + my_module.io[18] = AGPIO(GPIO_SPI_CLK); + SetPin(18, AGPIO(GPIO_SPI_CLK)); + } + spi_flg = (PinUsed(GPIO_SPI_CLK) && (PinUsed(GPIO_SPI_MOSI) || PinUsed(GPIO_SPI_MISO))); + if (spi_flg) { + if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO), GPIO%02d(MOSI) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + } + else if (PinUsed(GPIO_SPI_MOSI)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MOSI) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + } + else if (PinUsed(GPIO_SPI_MISO)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK)); + } + } + } soft_spi_flg = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); #endif // USE_SPI #endif // ESP8266 - ESP32 @@ -1682,7 +1731,7 @@ void GpioInit(void) if (PinUsed(GPIO_LED1, i)) { #ifdef USE_ARILUX_RF if ((3 == i) && (leds_present < 2) && !PinUsed(GPIO_ARIRFSEL)) { - SetPin(Pin(GPIO_LED1, i), GPIO_ARIRFSEL); // Legacy support where LED4 was Arilux RF enable + SetPin(Pin(GPIO_LED1, i), AGPIO(GPIO_ARIRFSEL)); // Legacy support where LED4 was Arilux RF enable } else { #endif pinMode(Pin(GPIO_LED1, i), OUTPUT); diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 5c5b1a120..8b19e1259 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -570,15 +570,15 @@ void TuyaNormalPowerModePacketProcess(void) bool key1_set = false; bool led1_set = false; for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { - if (Settings.my_gp.io[i] == GPIO_LED1) led1_set = true; - else if (Settings.my_gp.io[i] == GPIO_KEY1) key1_set = true; + if (Settings.my_gp.io[i] == AGPIO(GPIO_LED1)) led1_set = true; + else if (Settings.my_gp.io[i] == AGPIO(GPIO_KEY1)) key1_set = true; } if (!Settings.my_gp.io[led1_gpio] && !led1_set) { - Settings.my_gp.io[led1_gpio] = GPIO_LED1; + Settings.my_gp.io[led1_gpio] = AGPIO(GPIO_LED1); restart_flag = 2; } if (!Settings.my_gp.io[key1_gpio] && !key1_set) { - Settings.my_gp.io[key1_gpio] = GPIO_KEY1; + Settings.my_gp.io[key1_gpio] = AGPIO(GPIO_KEY1); restart_flag = 2; } } @@ -597,10 +597,10 @@ void TuyaNormalPowerModePacketProcess(void) bool TuyaModuleSelected(void) { if (!PinUsed(GPIO_TUYA_RX) || !PinUsed(GPIO_TUYA_TX)) { // fallback to hardware-serial if not explicitly selected - SetPin(1, GPIO_TUYA_TX); - SetPin(3, GPIO_TUYA_RX); - Settings.my_gp.io[1] = GPIO_TUYA_TX; - Settings.my_gp.io[3] = GPIO_TUYA_RX; + SetPin(1, AGPIO(GPIO_TUYA_TX)); + SetPin(3, AGPIO(GPIO_TUYA_RX)); + Settings.my_gp.io[1] = AGPIO(GPIO_TUYA_TX); + Settings.my_gp.io[3] = AGPIO(GPIO_TUYA_RX); restart_flag = 2; } diff --git a/tasmota/xdrv_31_tasmota_client.ino b/tasmota/xdrv_31_tasmota_client.ino index 27e289373..1708df44f 100644 --- a/tasmota/xdrv_31_tasmota_client.ino +++ b/tasmota/xdrv_31_tasmota_client.ino @@ -427,7 +427,7 @@ void TasmotaClient_Init(void) { } TasmotaClient_Serial->setTimeout(100); // Theo 20200502 - increase from 50 if (PinUsed(GPIO_TASMOTACLIENT_RST_INV)) { - SetPin(Pin(GPIO_TASMOTACLIENT_RST_INV), GPIO_TASMOTACLIENT_RST); + SetPin(Pin(GPIO_TASMOTACLIENT_RST_INV), AGPIO(GPIO_TASMOTACLIENT_RST)); TClient.inverted = HIGH; } pinMode(Pin(GPIO_TASMOTACLIENT_RST), OUTPUT); diff --git a/tasmota/xnrg_01_hlw8012.ino b/tasmota/xnrg_01_hlw8012.ino index d0c17353a..3a0873dd1 100644 --- a/tasmota/xnrg_01_hlw8012.ino +++ b/tasmota/xnrg_01_hlw8012.ino @@ -249,7 +249,7 @@ void HlwDrvInit(void) { Hlw.model_type = 0; // HLW8012 if (PinUsed(GPIO_HJL_CF)) { - SetPin(Pin(GPIO_HJL_CF), GPIO_HLW_CF); + SetPin(Pin(GPIO_HJL_CF), AGPIO(GPIO_HLW_CF)); Hlw.model_type = 1; // HJL-01/BL0937 } @@ -257,7 +257,7 @@ void HlwDrvInit(void) Hlw.ui_flag = true; // Voltage on high if (PinUsed(GPIO_NRG_SEL_INV)) { - SetPin(Pin(GPIO_NRG_SEL_INV), GPIO_NRG_SEL); + SetPin(Pin(GPIO_NRG_SEL_INV), AGPIO(GPIO_NRG_SEL)); Hlw.ui_flag = false; // Voltage on low } From 898646a07cf7ac447fb12fc50b555df976fec29a Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 21 Jun 2020 09:13:51 +0200 Subject: [PATCH 301/581] fixed global vars upd[x], use own udp instance --- tasmota/xdrv_10_scripter.ino | 49 +++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 921433a6d..951730785 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -374,6 +374,7 @@ struct SCRIPT_MEM { #ifdef USE_SCRIPT_GLOBVARS IPAddress last_udp_ip; +WiFiUDP Script_PortUdp; #endif int16_t last_findex; @@ -796,11 +797,17 @@ char *script; #define SCRIPT_UDP_PORT 1999 IPAddress script_udp_remote_ip; +void Script_Stop_UDP(void) { + Script_PortUdp.flush(); + Script_PortUdp.stop(); + glob_script_mem.udp_flags.udp_connected = 0; +} + void Script_Init_UDP() { if (global_state.network_down) return; if (glob_script_mem.udp_flags.udp_connected) return; - if (PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), SCRIPT_UDP_PORT)) { + if (Script_PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), SCRIPT_UDP_PORT)) { AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP started")); glob_script_mem.udp_flags.udp_connected = 1; } else { @@ -809,13 +816,14 @@ void Script_Init_UDP() { } } void Script_PollUdp(void) { + if (global_state.network_down) return; if (!glob_script_mem.udp_flags.udp_used) return; if (glob_script_mem.udp_flags.udp_connected ) { - while (PortUdp.parsePacket()) { + while (Script_PortUdp.parsePacket()) { char packet_buffer[SCRIPT_UDP_BUFFER_SIZE]; - int32_t len = PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE -1); + int32_t len = Script_PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE -1); packet_buffer[len] = 0; - script_udp_remote_ip = PortUdp.remoteIP(); + script_udp_remote_ip = Script_PortUdp.remoteIP(); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %s"), packet_buffer, len, script_udp_remote_ip.toString().c_str()); char *lp=packet_buffer; if (!strncmp(lp,"=>",2)) { @@ -835,17 +843,17 @@ void Script_PollUdp(void) { uint32_t index; uint32_t res=match_vars(vnam, &fp, &sp, &index); if (res==NUM_RES) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("num var found - %s - %d"),vnam,res); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("num var found - %s - %d - %d"),vnam,res,index); *fp=CharToFloat(cp+1); } else if (res==STR_RES) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("string var found - %s - %d"),vnam,res); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("string var found - %s - %d - %d"),vnam,res,index); strlcpy(sp,cp+1,SCRIPT_MAXSSIZE); } else { // error var not found } if (res) { // mark changed - last_udp_ip=PortUdp.remoteIP(); + last_udp_ip=Script_PortUdp.remoteIP(); glob_script_mem.type[index].bits.changed=1; if (glob_script==99) { Run_Scripter(">G",2,0); @@ -877,10 +885,10 @@ void script_udp_sendvar(char *vname,float *fp,char *sp) { strcat(sbuf,sp); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("string var updated - %s"),sbuf); } - PortUdp.beginPacket(IPAddress(239,255,255,250), SCRIPT_UDP_PORT); + Script_PortUdp.beginPacket(IPAddress(239,255,255,250), SCRIPT_UDP_PORT); // Udp.print(String("RET UC: ") + String(recv_Packet)); - PortUdp.write((const uint8_t*)sbuf,strlen(sbuf)); - PortUdp.endPacket(); + Script_PortUdp.write((const uint8_t*)sbuf,strlen(sbuf)); + Script_PortUdp.endPacket(); } #endif @@ -1196,12 +1204,12 @@ uint32_t match_vars(char *dvnam, float **fp, char **sp, uint32_t *ind) { return 0; } else { *fp=&glob_script_mem.fvars[index]; - *ind=index; + *ind=count; return NUM_RES; } } else { *sp=glob_script_mem.glob_snp+(index*glob_script_mem.max_ssize); - *ind=index; + *ind=count; return STR_RES; } } @@ -4956,14 +4964,12 @@ void Script_Handle_Hue(String *path) { response.replace("{cm", "on"); bool on = hue_json["on"]; - switch(on) - { - case false : glob_script_mem.fvars[hue_script[index].index[0]-1]=0; - response.replace("{re", "false"); - break; - case true : glob_script_mem.fvars[hue_script[index].index[0]-1]=1; - response.replace("{re", "true"); - break; + if (on==false) { + glob_script_mem.fvars[hue_script[index].index[0]-1]=0; + response.replace("{re", "false"); + } else { + glob_script_mem.fvars[hue_script[index].index[0]-1]=1; + response.replace("{re", "true"); } glob_script_mem.type[hue_script[index].vindex[0]].bits.changed=1; resp = true; @@ -6454,6 +6460,9 @@ bool Xdrv10(uint8_t function) Run_Scripter(">R",2,0); Scripter_save_pvars(); } +#ifdef USE_SCRIPT_GLOBVARS + Script_Stop_UDP(); +#endif break; #ifdef SUPPORT_MQTT_EVENT case FUNC_MQTT_DATA: From bb30044ae65ab747d9004e8026b591d392da81b6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 21 Jun 2020 12:11:40 +0200 Subject: [PATCH 302/581] Add more user control over ILI9341 --- tasmota/xdrv_13_display.ino | 4 +-- tasmota/xdsp_04_ili9341.ino | 68 +++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 20e95eeb1..d1fc01832 100644 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -45,8 +45,8 @@ uint8_t color_type = COLOR_BW; uint8_t auto_draw=1; const uint8_t DISPLAY_MAX_DRIVERS = 16; // Max number of display drivers/models supported by xdsp_interface.ino -const uint8_t DISPLAY_MAX_COLS = 44; // Max number of columns allowed with command DisplayCols -const uint8_t DISPLAY_MAX_ROWS = 32; // Max number of lines allowed with command DisplayRows +const uint8_t DISPLAY_MAX_COLS = 64; // Max number of columns allowed with command DisplayCols +const uint8_t DISPLAY_MAX_ROWS = 64; // Max number of lines allowed with command DisplayRows const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log buffer diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index ba3fc377e..813fe22ff 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -34,7 +34,9 @@ Adafruit_ILI9341 *tft; -uint16_t tft_scroll; +uint16_t tft_scroll = TFT_TOP; +uint16_t tft_top = TFT_TOP; +uint16_t tft_bottom = TFT_BOTTOM; /*********************************************************************************************/ @@ -50,13 +52,15 @@ void Ili9341InitMode(void) tft->setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft->setTextSize(1); } else { - tft->setScrollMargins(TFT_TOP, TFT_BOTTOM); + tft_top = TFT_TOP; + tft_bottom = TFT_BOTTOM; + tft->setScrollMargins(tft_top, tft_bottom); tft->setCursor(0, 0); tft->setTextColor(ILI9341_YELLOW, ILI9341_BLACK); tft->setTextSize(2); // tft->println("HEADER"); - tft_scroll = TFT_TOP; + tft_scroll = tft_top; } } @@ -164,15 +168,15 @@ void Ili9341PrintLog(void) tft->setCursor(0, tft_scroll); tft->fillRect(0, tft_scroll, tft->width(), theight, ILI9341_BLACK); // Erase line tft->print(txt); - tft_scroll += theight; - if (tft_scroll >= (tft->height() - TFT_BOTTOM)) { - tft_scroll = TFT_TOP; + if (tft_top) { tft_scroll += theight; } + if (tft_scroll >= (tft->height() - tft_bottom)) { + tft_scroll = tft_top; } tft->scrollTo(tft_scroll); } else { uint8_t last_row = Settings.display_rows -1; - tft_scroll = theight; // Start below header + tft_scroll = (tft_top) ? theight : 0; // Start below header tft->setCursor(0, tft_scroll); for (uint32_t i = 0; i < last_row; i++) { strlcpy(disp_screen_buffer[i], disp_screen_buffer[i +1], disp_screen_buffer_cols); @@ -194,27 +198,39 @@ void Ili9341PrintLog(void) void Ili9341Refresh(void) // Every second { if (Settings.display_mode) { // Mode 0 is User text - if (Settings.display_cols[0] < 19) { - Settings.display_cols[0] = 19; + // 24-04-2017 13:45:43 = 19 + 1 ('\0') = 20 + // 24-04-2017 13:45 = 16 + 1 ('\0') = 17 + + if (Settings.display_cols[0] > 17) { + char tftdt[Settings.display_cols[0] +1]; + char date4[11]; // 24-04-2017 + uint8_t time_size = (Settings.display_cols[0] >= 20) ? 9 : 6; // 13:45:43 or 13:45 + char spaces[Settings.display_cols[0] - (8 + time_size)]; + char time[time_size]; // 13:45:43 + + tft_top = TFT_TOP; + tft_bottom = TFT_BOTTOM; + tft_scroll = tft_top; + tft->setScrollMargins(tft_top, tft_bottom); + tft->setTextSize(Settings.display_size); + tft->setTextColor(ILI9341_YELLOW, ILI9341_RED); // Add background color to solve flicker + tft->setCursor(0, 0); + + snprintf_P(date4, sizeof(date4), PSTR("%02d" D_MONTH_DAY_SEPARATOR "%02d" D_YEAR_MONTH_SEPARATOR "%04d"), RtcTime.day_of_month, RtcTime.month, RtcTime.year); + memset(spaces, 0x20, sizeof(spaces)); + spaces[sizeof(spaces) -1] = '\0'; + snprintf_P(time, sizeof(time), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second); + snprintf_P(tftdt, sizeof(tftdt), PSTR("%s%s%s"), date4, spaces, time); + + tft->print(tftdt); + } else { + tft_top = 0; + tft_bottom = 0; + tft_scroll = tft_top; + tft->setScrollMargins(tft_top, tft_bottom); + tft->setCursor(0, 0); } - char tftdt[Settings.display_cols[0] +1]; - char date4[11]; // 24-04-2017 - char space[Settings.display_cols[0] - 17]; - char time[9]; // 13:45:43 - - tft->setTextSize(2); - tft->setTextColor(ILI9341_YELLOW, ILI9341_RED); // Add background color to solve flicker - tft->setCursor(0, 0); - - snprintf_P(date4, sizeof(date4), PSTR("%02d" D_MONTH_DAY_SEPARATOR "%02d" D_YEAR_MONTH_SEPARATOR "%04d"), RtcTime.day_of_month, RtcTime.month, RtcTime.year); - memset(space, 0x20, sizeof(space)); - space[sizeof(space) -1] = '\0'; - snprintf_P(time, sizeof(time), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second); - snprintf_P(tftdt, sizeof(tftdt), PSTR("%s%s%s"), date4, space, time); - - tft->print(tftdt); - switch (Settings.display_mode) { case 1: // Text case 2: // Local From 279715c85e5e59154e90917329c19602c624c86c Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 21 Jun 2020 16:20:14 +0200 Subject: [PATCH 303/581] ibeacon json path --- tasmota/xsns_52_ibeacon.ino | 46 +++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/tasmota/xsns_52_ibeacon.ino b/tasmota/xsns_52_ibeacon.ino index 6a33d94a0..8efcc1b0a 100755 --- a/tasmota/xsns_52_ibeacon.ino +++ b/tasmota/xsns_52_ibeacon.ino @@ -25,7 +25,7 @@ #include -#define TMSBSIZ 256 +#define TMSBSIZ 512 #define HM17_BAUDRATE 9600 @@ -197,15 +197,32 @@ void hm17_sendcmd(uint8_t cmd) { } uint32_t ibeacon_add(struct IBEACON *ib) { +/* if (!strncmp(ib->MAJOR,"4B1C",4)) { + return 0; + } + */ + if (!strncmp(ib->RSSI,"0",1)) { + return 0; + } + // keyfob starts with ffff, ibeacon has valid facid if (!strncmp(ib->MAC,"FFFF",4) || strncmp(ib->FACID,"00000000",8)) { for (uint32_t cnt=0;cntMAC,12)) { - // exists - memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); - ibeacons[cnt].TIME=0; - return 1; + if (!strncmp_P(ib->UID,PSTR("00000000000000000000000000000000"),32)) { + if (!strncmp(ibeacons[cnt].MAC,ib->MAC,12)) { + // exists + memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); + ibeacons[cnt].TIME=0; + return 1; + } + } else { + if (!strncmp(ibeacons[cnt].UID,ib->UID,32)) { + // exists + memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); + ibeacons[cnt].TIME=0; + return 1; + } } } } @@ -450,12 +467,15 @@ uint32_t difftime=millis()-hm17_lastms; } #ifdef USE_WEBSERVER -const char HTTP_IBEACON[] PROGMEM = +const char HTTP_IBEACON_mac[] PROGMEM = + "{s}IBEACON-MAC : %s" " - RSSI : %s" "{m}{e}"; +const char HTTP_IBEACON_uid[] PROGMEM = "{s}IBEACON-UID : %s" " - RSSI : %s" "{m}{e}"; void IBEACON_Show(void) { char mac[14]; char rssi[6]; +char uid[34]; for (uint32_t cnt=0;cnt Date: Sun, 21 Jun 2020 20:46:37 +0200 Subject: [PATCH 304/581] SwitchDebounce flags should be added to every valid imeout values --- tasmota/support_command.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 76c5252a0..e23fda355 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1275,7 +1275,7 @@ void CmndButtonDebounce(void) void CmndSwitchDebounce(void) { - if ((XdrvMailbox.payload > 39) && (XdrvMailbox.payload < 1001)) { + if ((XdrvMailbox.payload > 39) && (XdrvMailbox.payload < 1010)) { Settings.switch_debounce = XdrvMailbox.payload; } ResponseCmndNumber(Settings.switch_debounce); From 252dddef7cd1a30e8b2d9cb9a07bf2f4cc7ade83 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 22 Jun 2020 11:12:46 +0200 Subject: [PATCH 305/581] Change delay(2) to delayMicroseconds(2000) Change delay(2) to delayMicroseconds(2000) and see if it helps (#7568) --- tasmota/xsns_06_dht.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_06_dht.ino b/tasmota/xsns_06_dht.ino index 46fb69fa5..7bb1a3513 100644 --- a/tasmota/xsns_06_dht.ino +++ b/tasmota/xsns_06_dht.ino @@ -77,7 +77,8 @@ bool DhtRead(uint32_t sensor) delay(19); // minimum 18ms break; case GPIO_DHT22: // DHT21, DHT22, AM2301, AM2302, AM2321 - delay(2); // minimum 1ms +// delay(2); // minimum 1ms + delayMicroseconds(2000); // See https://github.com/arendst/Tasmota/pull/7468#issuecomment-647067015 break; case GPIO_SI7021: // iTead SI7021 delayMicroseconds(500); From 58435fb0c97d9a36b6ece095c4f5fc8df458ec41 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 22 Jun 2020 11:13:31 +0200 Subject: [PATCH 306/581] Revert "Change delay(2) to delayMicroseconds(2000)" This reverts commit 252dddef7cd1a30e8b2d9cb9a07bf2f4cc7ade83. --- tasmota/xsns_06_dht.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasmota/xsns_06_dht.ino b/tasmota/xsns_06_dht.ino index 7bb1a3513..46fb69fa5 100644 --- a/tasmota/xsns_06_dht.ino +++ b/tasmota/xsns_06_dht.ino @@ -77,8 +77,7 @@ bool DhtRead(uint32_t sensor) delay(19); // minimum 18ms break; case GPIO_DHT22: // DHT21, DHT22, AM2301, AM2302, AM2321 -// delay(2); // minimum 1ms - delayMicroseconds(2000); // See https://github.com/arendst/Tasmota/pull/7468#issuecomment-647067015 + delay(2); // minimum 1ms break; case GPIO_SI7021: // iTead SI7021 delayMicroseconds(500); From 9d70a194d97e016349ff71f59355c4e1e42b91f6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 22 Jun 2020 11:14:12 +0200 Subject: [PATCH 307/581] Change delay(2) to delayMicroseconds(2000) Change delay(2) to delayMicroseconds(2000) and see if it helps (#7468) --- tasmota/xsns_06_dht.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_06_dht.ino b/tasmota/xsns_06_dht.ino index 46fb69fa5..7bb1a3513 100644 --- a/tasmota/xsns_06_dht.ino +++ b/tasmota/xsns_06_dht.ino @@ -77,7 +77,8 @@ bool DhtRead(uint32_t sensor) delay(19); // minimum 18ms break; case GPIO_DHT22: // DHT21, DHT22, AM2301, AM2302, AM2321 - delay(2); // minimum 1ms +// delay(2); // minimum 1ms + delayMicroseconds(2000); // See https://github.com/arendst/Tasmota/pull/7468#issuecomment-647067015 break; case GPIO_SI7021: // iTead SI7021 delayMicroseconds(500); From 7a01aee0c3b302f1ca6fdba12c58541b57e762f6 Mon Sep 17 00:00:00 2001 From: Staars Date: Mon, 22 Jun 2020 11:23:06 +0200 Subject: [PATCH 308/581] NRF: use BEARSSL for decryption, make it optional --- tasmota/xsns_61_MI_NRF24.ino | 67 ++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index 4fb261751..685c643ef 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -21,6 +21,8 @@ Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.6.1 20200622 integrate - use BEARSSL-lib for decryption as default, make decryption optional + --- 0.9.6.0 20200618 integrate - add decryption for LYWSD03 --- 0.9.5.0 20200328 integrate - add dew point, multi-page-web ui, refactoring, command interface, @@ -53,7 +55,8 @@ #define MINRF_LOG_BUFFER(x) #endif - +#define USE_MI_DECRYPTION +// #define USE_MBEDTLS /*********************************************************************************************\ * MINRF * BLE-Sniffer/Bridge for MIJIA/XIAOMI Temperatur/Humidity-Sensor, Mi Flora, LYWSD02, GCx @@ -64,7 +67,14 @@ #define XSNS_61 61 #include +#ifdef USE_MI_DECRYPTION +#ifdef USE_MBEDTLS #include +#else +#include +#include +#endif // USE_MBEDTLS +#endif //USE_MI_DECRYPTION #define FLORA 1 #define MJ_HT_V1 2 @@ -77,15 +87,21 @@ const char S_JSON_NRF_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_NRF "%s\":%d}"; const char S_JSON_NRF_COMMAND[] PROGMEM = "{\"" D_CMND_NRF "%s\":\"%s\"}"; -const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan|Key"; +const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan" +#ifdef USE_MI_DECRYPTION + "|Key" +#endif //USE_MI_DECRYPTION + ; enum NRF_Commands { // commands useable in console or rules CMND_NRF_IGNORE, // ignore specific sensor type (1-6) CMND_NRF_PAGE, // sensor entries per web page, which will be shown alternated CMND_NRF_SCAN, // simplified passive BLE adv scan CMND_NRF_BEACON, // even more simplified Beacon, reports time since last sighting - CMND_NRF_CHAN, // ignore channel 0-2 (translates to 37-39) - CMND_NRF_KEY // add bind_key to a MAC for payload decryption + CMND_NRF_CHAN // ignore channel 0-2 (translates to 37-39) +#ifdef USE_MI_DECRYPTION + , CMND_NRF_KEY // add bind_key to a MAC for payload decryption +#endif //USE_MI_DECRYPTION }; const uint16_t kMINRFSlaveID[6]={ 0x0098, // Flora @@ -159,6 +175,7 @@ struct bleAdvPacket_t { // for nRF24L01 max 32 bytes = 2+6+24 uint8_t mac[6]; }; +#ifdef USE_MI_DECRYPTION struct encPayload_t { uint8_t cipher[5]; uint8_t ExtCnt[3]; @@ -180,7 +197,7 @@ union mi_bindKey_t{ }; uint8_t buf[22]; }; - +#endif //USE_MI_DECRYPTION union FIFO_t{ bleAdvPacket_t bleAdv; mi_beacon_t miBeacon; @@ -249,7 +266,9 @@ struct scan_entry_t { std::vector MIBLEsensors; std::vector MINRFscanResult; +#ifdef USE_MI_DECRYPTION std::vector MIBLEbindKeys; +#endif //USE_MI_DECRYPTION static union{ scan_entry_t MINRFdummyEntry; @@ -590,7 +609,7 @@ void MINRFcomputeBeaconPDU(void){ MINRF.beacon.PDU[i] = pdu; } } - +#ifdef USE_MI_DECRYPTION int MINRFdecryptPacket(char *_buf){ encPacket_t *packet = (encPacket_t*)_buf; // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("to decrypt: %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); @@ -620,6 +639,8 @@ int MINRFdecryptPacket(char *_buf){ // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mac in vector: %02x %02x %02x %02x %02x %02x"), MIBLEbindKeys[i].MAC[0], MIBLEbindKeys[i].MAC[1], MIBLEbindKeys[i].MAC[2], MIBLEbindKeys[i].MAC[3], MIBLEbindKeys[i].MAC[4], MIBLEbindKeys[i].MAC[5]); // } } + + #ifdef USE_MBEDTLS // init mbedtls_ccm_context ctx; mbedtls_ccm_init(&ctx); @@ -637,14 +658,35 @@ int MINRFdecryptPacket(char *_buf){ packet->payload.cipher, output, packet->payload.tag,sizeof(packet->payload.tag)); - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, output[0],output[1],output[2],output[3],output[4]); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MBEDTLS: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, output[0],output[1],output[2],output[3],output[4]); // put decrypted data in place memcpy((uint8_t*)(packet->payload.cipher)+1,output,sizeof(packet->payload.cipher)); // clean up mbedtls_ccm_free(&ctx); return ret; -} + #else // BearSSL + + memcpy(output,packet->payload.cipher, sizeof(packet->payload.cipher)); + + br_aes_small_ctrcbc_keys keyCtx; + br_aes_small_ctrcbc_init(&keyCtx, _bindkey, sizeof(_bindkey)); + + br_ccm_context ctx; + br_ccm_init(&ctx, &keyCtx.vtable); + br_ccm_reset(&ctx, nonce, sizeof(nonce), sizeof(packet->payload.cipher), sizeof(authData), sizeof(packet->payload.tag)); + br_ccm_aad_inject(&ctx, authData, sizeof(authData)); + br_ccm_flip(&ctx); + br_ccm_run(&ctx, 0, output, sizeof(packet->payload.cipher)); + + ret = br_ccm_check_tag(&ctx, packet->payload.tag); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("BEARSSL: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, output[0],output[1],output[2],output[3],output[4]); + memcpy((uint8_t*)(packet->payload.cipher)+1,output,sizeof(packet->payload.cipher)); + return ret; + #endif //USE_MBEDTLS + +} +#endif //USE_MI_DECRYPTION /*********************************************************************************************\ * helper functions @@ -662,7 +704,7 @@ void MINRFreverseMAC(uint8_t _mac[]){ } memcpy(_mac,_reversedMAC, sizeof(_reversedMAC)); } - +#ifdef USE_MI_DECRYPTION void MINRFAddKey(char* payload){ mi_bindKey_t keyMAC; memset(keyMAC.buf,0,sizeof(keyMAC)); @@ -702,7 +744,7 @@ void MINRFKeyMACStringToBytes(char* _string,uint8_t _keyMac[]) { //uppercase DEBUG_SENSOR_LOG(PSTR("MINRF: key-array: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"),_keyMac[0],_keyMac[1],_keyMac[2],_keyMac[3],_keyMac[4],_keyMac[5],_keyMac[6],_keyMac[7],_keyMac[8],_keyMac[9],_keyMac[10],_keyMac[11],_keyMac[12],_keyMac[13],_keyMac[14],_keyMac[15]); DEBUG_SENSOR_LOG(PSTR("MINRF: MAC-array: %02X%02X%02X%02X%02X%02X"),_keyMac[16],_keyMac[17],_keyMac[18],_keyMac[19],_keyMac[20],_keyMac[21]); } - +#endif //USE_MI_DECRYPTION /** * @brief * @@ -884,12 +926,13 @@ void MINRFhandleMiBeaconPacket(void){ memcpy(MINRFtempBuf,(uint8_t*)&MINRF.buffer.miBeacon.spare, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 memcpy((uint8_t*)&MINRF.buffer.miBeacon.type,MINRFtempBuf, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 } +#ifdef USE_MI_DECRYPTION if(_sensorVec->type==LYWSD03){ int decryptRet = -1; decryptRet = MINRFdecryptPacket((char*)&MINRF.buffer); //start with PID if(decryptRet==0) _sensorVec->showedUp=255; // if decryption worked, this must be a valid sensor } - +#endif //USE_MI_DECRYPTION DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kNRFSlaveType[_sensorVec->type-1],_slot); switch(MINRF.buffer.miBeacon.type){ case 0x04: @@ -1135,12 +1178,14 @@ bool NRFCmd(void) { } Response_P(S_JSON_NRF_COMMAND_NVALUE, command, MINRF.channelIgnore); break; +#ifdef USE_MI_DECRYPTION case CMND_NRF_KEY: if (XdrvMailbox.data_len==44){ // a KEY-MAC-string MINRFAddKey(XdrvMailbox.data); Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); } break; +#endif //USE_MI_DECRYPTION default: // else for Unknown command serviced = false; From 252100704cb35a30b5e8581f53d3b13b978d912b Mon Sep 17 00:00:00 2001 From: stefanbode Date: Mon, 22 Jun 2020 13:21:13 +0200 Subject: [PATCH 309/581] 8.3 fixes for Shutters (Stepper Motors) #8721 PWM control has changed in SDK. CHanged shutter functionality takes into consideration that physically the PWM frequency is minimum 40Hz --- tasmota/xdrv_27_shutter.ino | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index 22cee4fe0..157ed7fca 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -206,7 +206,7 @@ void ShutterInit(void) Shutter.pwm_frequency[i] = 0; Shutter.accelerator[i] = 0; analogWriteFreq(Shutter.pwm_frequency[i]); - analogWrite(Pin(GPIO_PWM1, i), 50); + ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); } } @@ -358,13 +358,14 @@ void ShutterUpdatePosition(void) Shutter.accelerator[i] = 0; Shutter.pwm_frequency[i] = Shutter.pwm_frequency[i] > 250 ? 250 : Shutter.pwm_frequency[i]; analogWriteFreq(Shutter.pwm_frequency[i]); - analogWrite(Pin(GPIO_PWM1, i), 50); + analogWrite(Pin(GPIO_PWM1, i), 1); Shutter.pwm_frequency[i] = 0; analogWriteFreq(Shutter.pwm_frequency[i]); while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) { delay(1); } - analogWrite(Pin(GPIO_PWM1, i), 0); + //analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8. because of reset + ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); Shutter.real_position[i] = ShutterCounterBasedPosition(i); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Real %d, pulsecount %d, start %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i]); @@ -428,6 +429,7 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) Shutter.pwm_frequency[i] = 0; analogWriteFreq(Shutter.pwm_frequency[i]); analogWrite(Pin(GPIO_PWM1, i), 0); + //ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 1, SRC_SHUTTER); RtcSettings.pulse_counter[i] = 0; Shutter.accelerator[i] = Shutter.max_pwm_frequency / (Shutter.motordelay[i]>0 ? Shutter.motordelay[i] : 1); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Ramp up: %d"), Shutter.accelerator[i]); @@ -460,6 +462,7 @@ void ShutterWaitForMotorStop(uint32_t i) delay(50); } analogWrite(Pin(GPIO_PWM1, i), 0); + ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); Shutter.real_position[i] = ShutterCounterBasedPosition(i); } else { ExecuteCommandPower(Settings.shutter_startrelay[i], 0, SRC_SHUTTER); @@ -902,6 +905,9 @@ void CmndShutterPosition(void) ExecuteCommandPower(Settings.shutter_startrelay[index] +1, new_shutterdirection == 1 ? 0 : 1, SRC_SHUTTER); // power on ExecuteCommandPower(Settings.shutter_startrelay[index], 1, SRC_SHUTTER); + if (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode) { + ExecuteCommandPower(Settings.shutter_startrelay[index]+2, 1, SRC_SHUTTER); + } } } else { // now start the motor for the right direction, work for momentary and normal shutters. From fba98d9839f2ad070e4e4bcb2d80cfe2658f910f Mon Sep 17 00:00:00 2001 From: stefanbode Date: Mon, 22 Jun 2020 13:24:36 +0200 Subject: [PATCH 310/581] Update xdrv_27_shutter.ino --- tasmota/xdrv_27_shutter.ino | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index 157ed7fca..71b3374f2 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -358,13 +358,13 @@ void ShutterUpdatePosition(void) Shutter.accelerator[i] = 0; Shutter.pwm_frequency[i] = Shutter.pwm_frequency[i] > 250 ? 250 : Shutter.pwm_frequency[i]; analogWriteFreq(Shutter.pwm_frequency[i]); - analogWrite(Pin(GPIO_PWM1, i), 1); + analogWrite(Pin(GPIO_PWM1, i), 50); Shutter.pwm_frequency[i] = 0; analogWriteFreq(Shutter.pwm_frequency[i]); while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) { delay(1); } - //analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8. because of reset + //analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8.3 because of reset caused by watchog ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); Shutter.real_position[i] = ShutterCounterBasedPosition(i); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Real %d, pulsecount %d, start %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i]); @@ -429,7 +429,6 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) Shutter.pwm_frequency[i] = 0; analogWriteFreq(Shutter.pwm_frequency[i]); analogWrite(Pin(GPIO_PWM1, i), 0); - //ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 1, SRC_SHUTTER); RtcSettings.pulse_counter[i] = 0; Shutter.accelerator[i] = Shutter.max_pwm_frequency / (Shutter.motordelay[i]>0 ? Shutter.motordelay[i] : 1); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Ramp up: %d"), Shutter.accelerator[i]); From 04ec0832fc06a2027dae2f4dc2ecf701434432e8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 22 Jun 2020 17:36:39 +0200 Subject: [PATCH 311/581] Fix ILI9341 hardware scroll --- tasmota/xdsp_04_ili9341.ino | 38 ++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index 813fe22ff..191c074bb 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -34,12 +34,29 @@ Adafruit_ILI9341 *tft; -uint16_t tft_scroll = TFT_TOP; uint16_t tft_top = TFT_TOP; uint16_t tft_bottom = TFT_BOTTOM; +uint16_t tft_scroll = TFT_TOP; +uint16_t tft_cols = 0; /*********************************************************************************************/ +bool Ili9341Header(void) { + if (Settings.display_cols[0] != tft_cols) { + tft_cols = Settings.display_cols[0]; + if (tft_cols > 17) { + tft_top = TFT_TOP; + tft_bottom = TFT_BOTTOM; + } else { + tft_top = 0; + tft_bottom = 0; + } + tft_scroll = tft_top; + tft->setScrollMargins(tft_top, tft_bottom); + } + return (tft_cols > 17); +} + void Ili9341InitMode(void) { tft->setRotation(Settings.display_rotate); // 0 @@ -52,15 +69,12 @@ void Ili9341InitMode(void) tft->setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft->setTextSize(1); } else { - tft_top = TFT_TOP; - tft_bottom = TFT_BOTTOM; - tft->setScrollMargins(tft_top, tft_bottom); + Ili9341Header(); tft->setCursor(0, 0); tft->setTextColor(ILI9341_YELLOW, ILI9341_BLACK); tft->setTextSize(2); // tft->println("HEADER"); - tft_scroll = tft_top; } } @@ -105,6 +119,8 @@ void Ili9341InitDriver(void) #endif // USE_DISPLAY_MODES1TO5 Ili9341InitMode(); + + AddLog_P2(LOG_LEVEL_INFO, PSTR("DSP: ILI9341")); } } @@ -168,7 +184,7 @@ void Ili9341PrintLog(void) tft->setCursor(0, tft_scroll); tft->fillRect(0, tft_scroll, tft->width(), theight, ILI9341_BLACK); // Erase line tft->print(txt); - if (tft_top) { tft_scroll += theight; } + tft_scroll += theight; if (tft_scroll >= (tft->height() - tft_bottom)) { tft_scroll = tft_top; } @@ -201,17 +217,13 @@ void Ili9341Refresh(void) // Every second // 24-04-2017 13:45:43 = 19 + 1 ('\0') = 20 // 24-04-2017 13:45 = 16 + 1 ('\0') = 17 - if (Settings.display_cols[0] > 17) { + if (Ili9341Header()) { char tftdt[Settings.display_cols[0] +1]; char date4[11]; // 24-04-2017 uint8_t time_size = (Settings.display_cols[0] >= 20) ? 9 : 6; // 13:45:43 or 13:45 char spaces[Settings.display_cols[0] - (8 + time_size)]; char time[time_size]; // 13:45:43 - tft_top = TFT_TOP; - tft_bottom = TFT_BOTTOM; - tft_scroll = tft_top; - tft->setScrollMargins(tft_top, tft_bottom); tft->setTextSize(Settings.display_size); tft->setTextColor(ILI9341_YELLOW, ILI9341_RED); // Add background color to solve flicker tft->setCursor(0, 0); @@ -224,10 +236,6 @@ void Ili9341Refresh(void) // Every second tft->print(tftdt); } else { - tft_top = 0; - tft_bottom = 0; - tft_scroll = tft_top; - tft->setScrollMargins(tft_top, tft_bottom); tft->setCursor(0, 0); } From b2d2226d5db999f70bf0b09b2a03d4db9637a2ee Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 22 Jun 2020 17:54:42 +0200 Subject: [PATCH 312/581] Fix compile error Fix compile error (#8758) --- tasmota/xsns_61_MI_NRF24.ino | 12 ++++++++---- tasmota/xsns_62_MI_HM10.ino | 6 +++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index 685c643ef..e6a504826 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -584,13 +584,17 @@ bool MINRFhandleBeacon(scan_entry_t * entry, uint32_t offset){ * @brief increase beacon timer every second and process the result * */ -void MINRFbeaconCounter(void){ - if(MINRF.beacon.active) { +void MINRFbeaconCounter(void) { + if (MINRF.beacon.active) { MINRF.beacon.time++; +/* char stemp[20]; snprintf_P(stemp, sizeof(stemp),PSTR("{%s:{\"Beacon\": %u}}"),D_CMND_NRF, MINRF.beacon.time); AddLog_P2(LOG_LEVEL_DEBUG, stemp); RulesProcessEvent(stemp); +*/ + Response_P(PSTR("{%s:{\"Beacon\":%u}}"), D_CMND_NRF, MINRF.beacon.time); + XdrvRulesProcess(); } } @@ -723,10 +727,10 @@ void MINRFAddKey(char* payload){ } /** - * @brief Convert combined key-MAC-string to + * @brief Convert combined key-MAC-string to * * @param _string input string in format: AABBCCDDEEFF... (upper case!), must be 44 chars!! - * @param _mac target byte array with fixed size of 16 + 6 + * @param _mac target byte array with fixed size of 16 + 6 */ void MINRFKeyMACStringToBytes(char* _string,uint8_t _keyMac[]) { //uppercase uint32_t index = 0; diff --git a/tasmota/xsns_62_MI_HM10.ino b/tasmota/xsns_62_MI_HM10.ino index 6655a0c87..6b5a797eb 100644 --- a/tasmota/xsns_62_MI_HM10.ino +++ b/tasmota/xsns_62_MI_HM10.ino @@ -977,11 +977,15 @@ void HM10_TaskEvery100ms(){ } } -void HM10StatusInfo(){ +void HM10StatusInfo() { +/* char stemp[20]; snprintf_P(stemp, sizeof(stemp),PSTR("{%s:{\"found\": %u}}"),D_CMND_HM10, MIBLEsensors.size()); AddLog_P2(LOG_LEVEL_INFO, stemp); RulesProcessEvent(stemp); +*/ + Response_P(PSTR("{%s:{\"found\":%u}}"), D_CMND_HM10, MIBLEsensors.size()); + XdrvRulesProcess(); } /** From 230d88c124a8cbca5196b3e36693285c69c65b2c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 22 Jun 2020 20:33:53 +0200 Subject: [PATCH 313/581] Fix warning redefine in driver xsns_52 --- tasmota/xsns_52_ibeacon.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xsns_52_ibeacon.ino b/tasmota/xsns_52_ibeacon.ino index 8efcc1b0a..5c8b0afd4 100755 --- a/tasmota/xsns_52_ibeacon.ino +++ b/tasmota/xsns_52_ibeacon.ino @@ -25,7 +25,7 @@ #include -#define TMSBSIZ 512 +#define TMSBSIZ52 512 #define HM17_BAUDRATE 9600 @@ -101,7 +101,7 @@ void IBEACON_Init() { // actually doesnt work reliably with software serial if (PinUsed(GPIO_IBEACON_RX) && PinUsed(GPIO_IBEACON_TX)) { - IBEACON_Serial = new TasmotaSerial(Pin(GPIO_IBEACON_RX), Pin(GPIO_IBEACON_TX),1,0,TMSBSIZ); + IBEACON_Serial = new TasmotaSerial(Pin(GPIO_IBEACON_RX), Pin(GPIO_IBEACON_TX),1,0,TMSBSIZ52); if (IBEACON_Serial->begin(HM17_BAUDRATE)) { if (IBEACON_Serial->hardwareSerial()) { ClaimSerial(); From 610f1cef00fa55f1f47029fbb4f99959409bb6b2 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 22 Jun 2020 21:47:40 +0200 Subject: [PATCH 314/581] Fix rules related exception or watchdog Fix rules related exception or watchdog by adding a rules mutex solving possible rule loops as in case of Var/Mem/Add/Sub/Mult and Scale (#8757) --- tasmota/xdrv_10_rules.ino | 44 ++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 49762ad85..ce81f586b 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -168,6 +168,7 @@ struct RULES { uint16_t vars_event = 0; uint8_t mems_event = 0; bool teleperiod = false; + bool busy = false; char event_data[100]; } Rules; @@ -564,7 +565,6 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Match 1 %d"), match); - if (bitRead(Settings.rule_once, rule_set)) { if (match) { // Only allow match state changes if (!bitRead(Rules.triggers[rule_set], Rules.trigger_count[rule_set])) { @@ -751,28 +751,34 @@ bool RulesProcessEvent(char *json_event) { bool serviced = false; + if (!Rules.busy) { + Rules.busy = true; + #ifdef USE_DEBUG_DRIVER - ShowFreeMem(PSTR("RulesProcessEvent")); + ShowFreeMem(PSTR("RulesProcessEvent")); #endif - String event_saved = json_event; - // json_event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} - // json_event = {"System":{"Boot":1}} - // json_event = {"SerialReceived":"on"} - invalid but will be expanded to {"SerialReceived":{"Data":"on"}} - char *p = strchr(json_event, ':'); - if ((p != NULL) && !(strchr(++p, ':'))) { // Find second colon - event_saved.replace(F(":"), F(":{\"Data\":")); - event_saved += F("}"); - // event_saved = {"SerialReceived":{"Data":"on"}} - } - event_saved.toUpperCase(); + String event_saved = json_event; + // json_event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} + // json_event = {"System":{"Boot":1}} + // json_event = {"SerialReceived":"on"} - invalid but will be expanded to {"SerialReceived":{"Data":"on"}} + char *p = strchr(json_event, ':'); + if ((p != NULL) && !(strchr(++p, ':'))) { // Find second colon + event_saved.replace(F(":"), F(":{\"Data\":")); + event_saved += F("}"); + // event_saved = {"SerialReceived":{"Data":"on"}} + } + event_saved.toUpperCase(); //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Event %s"), event_saved.c_str()); - for (uint32_t i = 0; i < MAX_RULE_SETS; i++) { - if (GetRuleLen(i) && bitRead(Settings.rule_enabled, i)) { - if (RuleSetProcess(i, event_saved)) { serviced = true; } + for (uint32_t i = 0; i < MAX_RULE_SETS; i++) { + if (GetRuleLen(i) && bitRead(Settings.rule_enabled, i)) { + if (RuleSetProcess(i, event_saved)) { serviced = true; } + } } + + Rules.busy = false; } return serviced; } @@ -796,7 +802,7 @@ void RulesInit(void) void RulesEvery50ms(void) { - if (Settings.rule_enabled) { // Any rule enabled + if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled char json_event[120]; if (-1 == Rules.new_power) { Rules.new_power = power; } @@ -932,7 +938,7 @@ void RulesEvery100ms(void) void RulesEverySecond(void) { - if (Settings.rule_enabled) { // Any rule enabled + if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled char json_event[120]; if (RtcTime.valid) { @@ -956,7 +962,7 @@ void RulesEverySecond(void) void RulesSaveBeforeRestart(void) { - if (Settings.rule_enabled) { // Any rule enabled + if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled char json_event[32]; strncpy_P(json_event, PSTR("{\"System\":{\"Save\":1}}"), sizeof(json_event)); From c8e08d7f8a35ac0037105407d6ee7b3f0c47bd16 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 22 Jun 2020 22:08:03 +0200 Subject: [PATCH 315/581] Add rule busy friendly loop --- tasmota/xdrv_10_rules.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index ce81f586b..ddeb82403 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -922,7 +922,7 @@ uint8_t rules_xsns_index = 0; void RulesEvery100ms(void) { - if (Settings.rule_enabled && (uptime > 4)) { // Any rule enabled and allow 4 seconds start-up time for sensors (#3811) + if (Settings.rule_enabled && !Rules.busy && (uptime > 4)) { // Any rule enabled and allow 4 seconds start-up time for sensors (#3811) mqtt_data[0] = '\0'; int tele_period_save = tele_period; tele_period = 2; // Do not allow HA updates during next function call @@ -931,7 +931,7 @@ void RulesEvery100ms(void) if (strlen(mqtt_data)) { mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089} ResponseJsonEnd(); - RulesProcess(); + RulesProcessEvent(mqtt_data); } } } From 7c8b06ce164abd7bff430486fb2de0e22e7caedf Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 22 Jun 2020 22:36:54 +0200 Subject: [PATCH 316/581] Add compile time interlock parameters Add compile time interlock parameters (#8759) --- RELEASENOTES.md | 2 ++ tasmota/CHANGELOG.md | 2 ++ tasmota/my_user_config.h | 6 ++++++ tasmota/settings.ino | 14 ++++++++++---- tasmota/support_command.ino | 3 ++- tasmota/tasmota_globals.h | 16 ++++++++++++++++ 6 files changed, 38 insertions(+), 5 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 410ecc1d1..121e9e428 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -62,6 +62,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT - Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` - Fix escape of non-JSON received serial data (#8329) +- Fix exception or watchdog on rule re-entry (#8757) - Add command ``Rule0`` to change global rule parameters - Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) @@ -88,3 +89,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add Library to be used for decoding Teleinfo (French Metering Smart Meter) - Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) +- Add compile time interlock parameters (#8759) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 3ba3a1d38..2a2a822f7 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -6,6 +6,8 @@ - Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff - Add library to be used for decoding Teleinfo (French Metering Smart Meter) - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) +- Add compile time interlock parameters (#8759) +- Fix exception or watchdog on rule re-entry (#8757) - Change ESP32 USER GPIO template representation decreasing template message size - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT - Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 4f5623de1..e0de6bbf3 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -280,6 +280,12 @@ #define APP_DISABLE_POWERCYCLE false // [SetOption65] Disable fast power cycle detection for device reset #define DEEPSLEEP_BOOTCOUNT false // [SetOption76] Enable incrementing bootcount when deepsleep is enabled +#define APP_INTERLOCK_MODE false // [Interlock] Relay interlock mode +#define APP_INTERLOCK_GROUP_1 0xFF // [Interlock] Relay bitmask for interlock group 1 (0xFF if undef) +//#define APP_INTERLOCK_GROUP_2 0x00 // [Interlock] Relay bitmask for interlock group 2 (0x00 if undef) +//#define APP_INTERLOCK_GROUP_3 0x00 // [Interlock] Relay bitmask for interlock group 3 (0x00 if undef) +//#define APP_INTERLOCK_GROUP_4 0x00 // [Interlock] Relay bitmask for interlock group 4 (0x00 if undef) + // -- Lights -------------------------------------- #define WS2812_LEDS 30 // [Pixels] Number of WS2812 LEDs to start with (max is 512) #define LIGHT_MODE true // [SetOption15] Switch between commands PWM or COLOR/DIMMER/CT/CHANNEL diff --git a/tasmota/settings.ino b/tasmota/settings.ino index d7ede5f25..e7a43b70a 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -765,8 +765,11 @@ void SettingsDefaultSet2(void) } // Module -// flag.interlock |= 0; - Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group + flag.interlock |= APP_INTERLOCK_MODE; + Settings.interlock[0] = APP_INTERLOCK_GROUP_1; + Settings.interlock[1] = APP_INTERLOCK_GROUP_2; + Settings.interlock[2] = APP_INTERLOCK_GROUP_3; + Settings.interlock[3] = APP_INTERLOCK_GROUP_4; Settings.module = MODULE; Settings.fallback_module = FALLBACK_MODULE; ModuleDefault(WEMOS); @@ -1188,8 +1191,11 @@ void SettingsDelta(void) Settings.param[P_MDNS_DELAYED_START] = 0; } if (Settings.version < 0x0604010B) { - Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group - for (uint32_t i = 1; i < MAX_INTERLOCKS; i++) { Settings.interlock[i] = 0; } + Settings.flag.interlock = APP_INTERLOCK_MODE; + Settings.interlock[0] = APP_INTERLOCK_GROUP_1; + Settings.interlock[1] = APP_INTERLOCK_GROUP_2; + Settings.interlock[2] = APP_INTERLOCK_GROUP_3; + Settings.interlock[3] = APP_INTERLOCK_GROUP_4; } if (Settings.version < 0x0604010D) { Settings.param[P_BOOT_LOOP_OFFSET] = BOOT_LOOP_OFFSET; // SetOption36 diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index e23fda355..612f4dbce 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1627,7 +1627,8 @@ void CmndInterlock(void) } ResponseAppend_P(PSTR("\"}")); } else { - Settings.flag.interlock = 0; // CMND_INTERLOCK - Enable/disable interlock + // never ever reset interlock mode inadvertently if we forced it upon compilation + Settings.flag.interlock = APP_INTERLOCK_MODE; // CMND_INTERLOCK - Enable/disable interlock ResponseCmndStateText(Settings.flag.interlock); } } diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 620c6ff68..f52f7a218 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -88,6 +88,22 @@ String EthernetMacAddress(void); #undef USE_RF_FLASH // Disable RF firmware flash when Sonoff Rf is disabled #endif +#ifndef APP_INTERLOCK_MODE +#define APP_INTERLOCK_MODE false // [Interlock] Relay interlock mode +#endif +#ifndef APP_INTERLOCK_GROUP_1 +#define APP_INTERLOCK_GROUP_1 0xFF // [Interlock] Relay bitmask for interlock group 1 - Legacy support using all relays in one interlock group +#endif +#ifndef APP_INTERLOCK_GROUP_2 +#define APP_INTERLOCK_GROUP_2 0x00 // [Interlock] Relay bitmask for interlock group 2 +#endif +#ifndef APP_INTERLOCK_GROUP_3 +#define APP_INTERLOCK_GROUP_3 0x00 // [Interlock] Relay bitmask for interlock group 3 +#endif +#ifndef APP_INTERLOCK_GROUP_4 +#define APP_INTERLOCK_GROUP_4 0x00 // [Interlock] Relay bitmask for interlock group 4 +#endif + #ifndef SWITCH_MODE #define SWITCH_MODE TOGGLE // TOGGLE, FOLLOW or FOLLOW_INV (the wall switch state) #endif From 778415637634f9b1cb304f5fa503fc6e92fde70f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 22 Jun 2020 22:52:25 +0200 Subject: [PATCH 317/581] Fix TasmotaClient exception Fix TasmotaClient exception (#8734) --- tasmota/xdrv_31_tasmota_client.ino | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tasmota/xdrv_31_tasmota_client.ino b/tasmota/xdrv_31_tasmota_client.ino index 1708df44f..3fdbad076 100644 --- a/tasmota/xdrv_31_tasmota_client.ino +++ b/tasmota/xdrv_31_tasmota_client.ino @@ -503,15 +503,17 @@ void CmndClientReset(void) { } void CmndClientSend(void) { - if (0 < XdrvMailbox.data_len) { - TasmotaClient_sendCmnd(CMND_CLIENT_SEND, XdrvMailbox.data_len); - TasmotaClient_Serial->write(char(PARAM_DATA_START)); - for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) { - TasmotaClient_Serial->write(XdrvMailbox.data[idx]); + if (TClient.SerialEnabled) { + if (0 < XdrvMailbox.data_len) { + TasmotaClient_sendCmnd(CMND_CLIENT_SEND, XdrvMailbox.data_len); + TasmotaClient_Serial->write(char(PARAM_DATA_START)); + for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) { + TasmotaClient_Serial->write(XdrvMailbox.data[idx]); + } + TasmotaClient_Serial->write(char(PARAM_DATA_END)); } - TasmotaClient_Serial->write(char(PARAM_DATA_END)); + ResponseCmndDone(); } - ResponseCmndDone(); } void TasmotaClient_ProcessIn(void) { From 6e8928b8a1106422153a672f2de9791d65286966 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 23 Jun 2020 17:28:15 +0200 Subject: [PATCH 318/581] Fix PWM software watchdogs Fix PWM software watchdogs by correctly initializing variables (#8721) --- tasmota/core_esp8266_waveform.cpp | 8 ++++---- tasmota/core_esp8266_wiring_digital.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tasmota/core_esp8266_waveform.cpp b/tasmota/core_esp8266_waveform.cpp index 1ff0a3687..29a485874 100644 --- a/tasmota/core_esp8266_waveform.cpp +++ b/tasmota/core_esp8266_waveform.cpp @@ -133,9 +133,9 @@ constexpr int maxPWMs = 8; // PWM machine state typedef struct PWMState { - uint32_t mask; // Bitmask of active pins - uint32_t cnt; // How many entries - uint32_t idx; // Where the state machine is along the list + uint32_t mask = 0; // Bitmask of active pins + uint32_t cnt = 0; // How many entries + uint32_t idx = 0; // Where the state machine is along the list uint8_t pin[maxPWMs + 1]; uint32_t delta[maxPWMs + 1]; uint32_t nextServiceCycle; // Clock cycle for next step @@ -528,7 +528,7 @@ static ICACHE_RAM_ATTR void timer1Interrupt() { // Done, remove! if (i == 16) { GP16O = 0; - } + } GPOC = mask; wvfState.waveformEnabled &= ~mask; continue; diff --git a/tasmota/core_esp8266_wiring_digital.cpp b/tasmota/core_esp8266_wiring_digital.cpp index 199fbabd8..7fb3ccb00 100644 --- a/tasmota/core_esp8266_wiring_digital.cpp +++ b/tasmota/core_esp8266_wiring_digital.cpp @@ -153,8 +153,8 @@ void ICACHE_RAM_ATTR interrupt_handler(void*) while(!(changedbits & (1 << i))) i++; changedbits &= ~(1 << i); interrupt_handler_t *handler = &interrupt_handlers[i]; - if (handler->fn && - (handler->mode == CHANGE || + if (handler->fn && + (handler->mode == CHANGE || (handler->mode & 1) == !!(levels & (1 << i)))) { // to make ISR compatible to Arduino AVR model where interrupts are disabled // we disable them before we call the client ISR From 1f80336ae48d5e9fecd77f3248c676134781772b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 23 Jun 2020 17:30:06 +0200 Subject: [PATCH 319/581] Fix shutter watchdogs Fix shutter watchdogs (#8721) --- tasmota/xdrv_27_shutter.ino | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index 71b3374f2..d4a384672 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -206,7 +206,8 @@ void ShutterInit(void) Shutter.pwm_frequency[i] = 0; Shutter.accelerator[i] = 0; analogWriteFreq(Shutter.pwm_frequency[i]); - ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); + analogWrite(Pin(GPIO_PWM1, i), 0); +// ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); } } @@ -364,8 +365,8 @@ void ShutterUpdatePosition(void) while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) { delay(1); } - //analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8.3 because of reset caused by watchog - ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); + analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8.3 because of reset caused by watchog +// ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); Shutter.real_position[i] = ShutterCounterBasedPosition(i); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Real %d, pulsecount %d, start %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i]); @@ -461,7 +462,7 @@ void ShutterWaitForMotorStop(uint32_t i) delay(50); } analogWrite(Pin(GPIO_PWM1, i), 0); - ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); +// ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); Shutter.real_position[i] = ShutterCounterBasedPosition(i); } else { ExecuteCommandPower(Settings.shutter_startrelay[i], 0, SRC_SHUTTER); From 454e09f575e272c59cb38ff1ed8785135631f673 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:16:30 +0200 Subject: [PATCH 320/581] Delete core_esp8266_waveform.cpp --- tasmota/core_esp8266_waveform.cpp | 615 ------------------------------ 1 file changed, 615 deletions(-) delete mode 100644 tasmota/core_esp8266_waveform.cpp diff --git a/tasmota/core_esp8266_waveform.cpp b/tasmota/core_esp8266_waveform.cpp deleted file mode 100644 index 29a485874..000000000 --- a/tasmota/core_esp8266_waveform.cpp +++ /dev/null @@ -1,615 +0,0 @@ -/* - esp8266_waveform - General purpose waveform generation and control, - supporting outputs on all pins in parallel. - - Copyright (c) 2018 Earle F. Philhower, III. All rights reserved. - - The core idea is to have a programmable waveform generator with a unique - high and low period (defined in microseconds or CPU clock cycles). TIMER1 - is set to 1-shot mode and is always loaded with the time until the next - edge of any live waveforms. - - Up to one waveform generator per pin supported. - - Each waveform generator is synchronized to the ESP clock cycle counter, not - the timer. This allows for removing interrupt jitter and delay as the - counter always increments once per 80MHz clock. Changes to a waveform are - contiguous and only take effect on the next waveform transition, - allowing for smooth transitions. - - This replaces older tone(), analogWrite(), and the Servo classes. - - Everywhere in the code where "cycles" is used, it means ESP.getCycleCount() - clock cycle count, or an interval measured in CPU clock cycles, but not - TIMER1 cycles (which may be 2 CPU clock cycles @ 160MHz). - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef ESP8266 - -#include -#include "ets_sys.h" -#include "core_esp8266_waveform.h" -#include "user_interface.h" -extern "C" { - -// Internal-only calls, not for applications -extern void _setPWMFreq(uint32_t freq); -extern bool _stopPWM(int pin); -extern bool _setPWM(int pin, uint32_t val, uint32_t range); -extern int startWaveformClockCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles); - -// Maximum delay between IRQs -#define MAXIRQUS (10000) - -// Waveform generator can create tones, PWM, and servos -typedef struct { - uint32_t nextServiceCycle; // ESP cycle timer when a transition required - uint32_t expiryCycle; // For time-limited waveform, the cycle when this waveform must stop - uint32_t timeHighCycles; // Actual running waveform period (adjusted using desiredCycles) - uint32_t timeLowCycles; // - uint32_t desiredHighCycles; // Ideal waveform period to drive the error signal - uint32_t desiredLowCycles; // - uint32_t lastEdge; // Cycle when this generator last changed -} Waveform; - -class WVFState { -public: - Waveform waveform[17]; // State of all possible pins - uint32_t waveformState = 0; // Is the pin high or low, updated in NMI so no access outside the NMI code - uint32_t waveformEnabled = 0; // Is it actively running, updated in NMI so no access outside the NMI code - - // Enable lock-free by only allowing updates to waveformState and waveformEnabled from IRQ service routine - uint32_t waveformToEnable = 0; // Message to the NMI handler to start a waveform on a inactive pin - uint32_t waveformToDisable = 0; // Message to the NMI handler to disable a pin from waveform generation - - uint32_t waveformToChange = 0; // Mask of pin to change. One bit set in main app, cleared when effected in the NMI - uint32_t waveformNewHigh = 0; - uint32_t waveformNewLow = 0; - - uint32_t (*timer1CB)() = NULL; - - // Optimize the NMI inner loop by keeping track of the min and max GPIO that we - // are generating. In the common case (1 PWM) these may be the same pin and - // we can avoid looking at the other pins. - uint16_t startPin = 0; - uint16_t endPin = 0; -}; -static WVFState wvfState; - - -// Ensure everything is read/written to RAM -#define MEMBARRIER() { __asm__ volatile("" ::: "memory"); } - -// Non-speed critical bits -#pragma GCC optimize ("Os") - -// Interrupt on/off control -static ICACHE_RAM_ATTR void timer1Interrupt(); -static bool timerRunning = false; - -static __attribute__((noinline)) void initTimer() { - if (!timerRunning) { - timer1_disable(); - ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL); - ETS_FRC_TIMER1_NMI_INTR_ATTACH(timer1Interrupt); - timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE); - timerRunning = true; - timer1_write(microsecondsToClockCycles(10)); - } -} - -static ICACHE_RAM_ATTR void forceTimerInterrupt() { - if (T1L > microsecondsToClockCycles(10)) { - T1L = microsecondsToClockCycles(10); - } -} - -// PWM implementation using special purpose state machine -// -// Keep an ordered list of pins with the delta in cycles between each -// element, with a terminal entry making up the remainder of the PWM -// period. With this method sum(all deltas) == PWM period clock cycles. -// -// At t=0 set all pins high and set the timeout for the 1st edge. -// On interrupt, if we're at the last element reset to t=0 state -// Otherwise, clear that pin down and set delay for next element -// and so forth. - -constexpr int maxPWMs = 8; - -// PWM machine state -typedef struct PWMState { - uint32_t mask = 0; // Bitmask of active pins - uint32_t cnt = 0; // How many entries - uint32_t idx = 0; // Where the state machine is along the list - uint8_t pin[maxPWMs + 1]; - uint32_t delta[maxPWMs + 1]; - uint32_t nextServiceCycle; // Clock cycle for next step - struct PWMState *pwmUpdate; // Set by main code, cleared by ISR -} PWMState; - -static PWMState pwmState; -static uint32_t _pwmPeriod = microsecondsToClockCycles(1000000UL) / 1000; - - -// If there are no more scheduled activities, shut down Timer 1. -// Otherwise, do nothing. -static ICACHE_RAM_ATTR void disableIdleTimer() { - if (timerRunning && !wvfState.waveformEnabled && !pwmState.cnt && !wvfState.timer1CB) { - ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); - timer1_disable(); - timer1_isr_init(); - timerRunning = false; - } -} - -// Notify the NMI that a new PWM state is available through the mailbox. -// Wait for mailbox to be emptied (either busy or delay() as needed) -static ICACHE_RAM_ATTR void _notifyPWM(PWMState *p, bool idle) { - p->pwmUpdate = nullptr; - pwmState.pwmUpdate = p; - MEMBARRIER(); - forceTimerInterrupt(); - while (pwmState.pwmUpdate) { - if (idle) { - delay(0); - } - MEMBARRIER(); - } -} - -static void _addPWMtoList(PWMState &p, int pin, uint32_t val, uint32_t range); - -// Called when analogWriteFreq() changed to update the PWM total period -void _setPWMFreq(uint32_t freq) { - // Convert frequency into clock cycles - uint32_t cc = microsecondsToClockCycles(1000000UL) / freq; - - // Simple static adjustment to bring period closer to requested due to overhead -#if F_CPU == 80000000 - cc -= microsecondsToClockCycles(2); -#else - cc -= microsecondsToClockCycles(1); -#endif - - if (cc == _pwmPeriod) { - return; // No change - } - - _pwmPeriod = cc; - - if (pwmState.cnt) { - PWMState p; // The working copy since we can't edit the one in use - p.cnt = 0; - for (uint32_t i = 0; i < pwmState.cnt; i++) { - auto pin = pwmState.pin[i]; - _addPWMtoList(p, pin, wvfState.waveform[pin].desiredHighCycles, wvfState.waveform[pin].desiredLowCycles); - } - // Update and wait for mailbox to be emptied - initTimer(); - _notifyPWM(&p, true); - disableIdleTimer(); - } -} - -// Helper routine to remove an entry from the state machine -// and clean up any marked-off entries -static void _cleanAndRemovePWM(PWMState *p, int pin) { - uint32_t leftover = 0; - uint32_t in, out; - for (in = 0, out = 0; in < p->cnt; in++) { - if ((p->pin[in] != pin) && (p->mask & (1<pin[in]))) { - p->pin[out] = p->pin[in]; - p->delta[out] = p->delta[in] + leftover; - leftover = 0; - out++; - } else { - leftover += p->delta[in]; - p->mask &= ~(1<pin[in]); - } - } - p->cnt = out; - // Final pin is never used: p->pin[out] = 0xff; - p->delta[out] = p->delta[in] + leftover; -} - - -// Disable PWM on a specific pin (i.e. when a digitalWrite or analogWrite(0%/100%)) -ICACHE_RAM_ATTR bool _stopPWM(int pin) { - if (!((1<= _pwmPeriod) { - _stopPWM(pin); - digitalWrite(pin, HIGH); - return; - } - - if (p.cnt == 0) { - // Starting up from scratch, special case 1st element and PWM period - p.pin[0] = pin; - p.delta[0] = cc; - // Final pin is never used: p.pin[1] = 0xff; - p.delta[1] = _pwmPeriod - cc; - } else { - uint32_t ttl = 0; - uint32_t i; - // Skip along until we're at the spot to insert - for (i=0; (i <= p.cnt) && (ttl + p.delta[i] < cc); i++) { - ttl += p.delta[i]; - } - // Shift everything out by one to make space for new edge - for (int32_t j = p.cnt; j >= (int)i; j--) { - p.pin[j + 1] = p.pin[j]; - p.delta[j + 1] = p.delta[j]; - } - int off = cc - ttl; // The delta from the last edge to the one we're inserting - p.pin[i] = pin; - p.delta[i] = off; // Add the delta to this new pin - p.delta[i + 1] -= off; // And subtract it from the follower to keep sum(deltas) constant - } - p.cnt++; - p.mask |= 1<= maxPWMs) { - return false; // No space left - } - - _addPWMtoList(p, pin, val, range); - - // Set mailbox and wait for ISR to copy it over - initTimer(); - _notifyPWM(&p, true); - disableIdleTimer(); - return true; -} - -// Start up a waveform on a pin, or change the current one. Will change to the new -// waveform smoothly on next low->high transition. For immediate change, stopWaveform() -// first, then it will immediately begin. -int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS) { - return startWaveformClockCycles(pin, microsecondsToClockCycles(timeHighUS), microsecondsToClockCycles(timeLowUS), microsecondsToClockCycles(runTimeUS)); -} - -int startWaveformClockCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles) { - if ((pin > 16) || isFlashInterfacePin(pin)) { - return false; - } - Waveform *wave = &wvfState.waveform[pin]; - wave->expiryCycle = runTimeCycles ? ESP.getCycleCount() + runTimeCycles : 0; - if (runTimeCycles && !wave->expiryCycle) { - wave->expiryCycle = 1; // expiryCycle==0 means no timeout, so avoid setting it - } - - _stopPWM(pin); // Make sure there's no PWM live here - - uint32_t mask = 1<timeHighCycles = timeHighCycles; - wave->desiredHighCycles = timeHighCycles; - wave->timeLowCycles = timeLowCycles; - wave->desiredLowCycles = timeLowCycles; - wave->lastEdge = 0; - wave->nextServiceCycle = ESP.getCycleCount() + microsecondsToClockCycles(1); - wvfState.waveformToEnable |= mask; - MEMBARRIER(); - initTimer(); - forceTimerInterrupt(); - while (wvfState.waveformToEnable) { - delay(0); // Wait for waveform to update - // No mem barrier here, the call to a global function implies global state updated - } - } - - return true; -} - - -// Set a callback. Pass in NULL to stop it -void setTimer1Callback(uint32_t (*fn)()) { - wvfState.timer1CB = fn; - if (fn) { - initTimer(); - forceTimerInterrupt(); - } - disableIdleTimer(); -} - - -// Speed critical bits -#pragma GCC optimize ("O2") - -// Normally would not want two copies like this, but due to different -// optimization levels the inline attribute gets lost if we try the -// other version. -static inline ICACHE_RAM_ATTR uint32_t GetCycleCountIRQ() { - uint32_t ccount; - __asm__ __volatile__("rsr %0,ccount":"=a"(ccount)); - return ccount; -} - -static inline ICACHE_RAM_ATTR uint32_t min_u32(uint32_t a, uint32_t b) { - if (a < b) { - return a; - } - return b; -} - -// Stops a waveform on a pin -int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) { - // Can't possibly need to stop anything if there is no timer active - if (!timerRunning) { - return false; - } - // If user sends in a pin >16 but <32, this will always point to a 0 bit - // If they send >=32, then the shift will result in 0 and it will also return false - uint32_t mask = 1<> (turbo ? 0 : 1)) -#endif - - -static ICACHE_RAM_ATTR void timer1Interrupt() { - // Flag if the core is at 160 MHz, for use by adjust() - bool turbo = (*(uint32_t*)0x3FF00014) & 1 ? true : false; - - uint32_t nextEventCycles = microsecondsToClockCycles(MAXIRQUS); - uint32_t timeoutCycle = GetCycleCountIRQ() + microsecondsToClockCycles(14); - - if (wvfState.waveformToEnable || wvfState.waveformToDisable) { - // Handle enable/disable requests from main app - wvfState.waveformEnabled = (wvfState.waveformEnabled & ~wvfState.waveformToDisable) | wvfState.waveformToEnable; // Set the requested waveforms on/off - wvfState.waveformState &= ~wvfState.waveformToEnable; // And clear the state of any just started - wvfState.waveformToEnable = 0; - wvfState.waveformToDisable = 0; - // No mem barrier. Globals must be written to RAM on ISR exit. - // Find the first GPIO being generated by checking GCC's find-first-set (returns 1 + the bit of the first 1 in an int32_t) - wvfState.startPin = __builtin_ffs(wvfState.waveformEnabled) - 1; - // Find the last bit by subtracting off GCC's count-leading-zeros (no offset in this one) - wvfState.endPin = 32 - __builtin_clz(wvfState.waveformEnabled); - } else if (!pwmState.cnt && pwmState.pwmUpdate) { - // Start up the PWM generator by copying from the mailbox - pwmState.cnt = 1; - pwmState.idx = 1; // Ensure copy this cycle, cause it to start at t=0 - pwmState.nextServiceCycle = GetCycleCountIRQ(); // Do it this loop! - // No need for mem barrier here. Global must be written by IRQ exit - } - - bool done = false; - if (wvfState.waveformEnabled || pwmState.cnt) { - do { - nextEventCycles = microsecondsToClockCycles(MAXIRQUS); - - // PWM state machine implementation - if (pwmState.cnt) { - int32_t cyclesToGo = pwmState.nextServiceCycle - GetCycleCountIRQ(); - if (cyclesToGo < 0) { - if (pwmState.idx == pwmState.cnt) { // Start of pulses, possibly copy new - if (pwmState.pwmUpdate) { - // Do the memory copy from temp to global and clear mailbox - pwmState = *(PWMState*)pwmState.pwmUpdate; - } - GPOS = pwmState.mask; // Set all active pins high - if (pwmState.mask & (1<<16)) { - GP16O = 1; - } - pwmState.idx = 0; - } else { - do { - // Drop the pin at this edge - if (pwmState.mask & (1<expiryCycle) { - int32_t expiryToGo = wave->expiryCycle - now; - if (expiryToGo < 0) { - // Done, remove! - if (i == 16) { - GP16O = 0; - } - GPOC = mask; - wvfState.waveformEnabled &= ~mask; - continue; - } - } - - // Check for toggles - int32_t cyclesToGo = wave->nextServiceCycle - now; - if (cyclesToGo < 0) { - uint32_t nextEdgeCycles; - uint32_t desired = 0; - uint32_t *timeToUpdate; - wvfState.waveformState ^= mask; - if (wvfState.waveformState & mask) { - if (i == 16) { - GP16O = 1; - } - GPOS = mask; - - if (wvfState.waveformToChange & mask) { - // Copy over next full-cycle timings - wave->timeHighCycles = wvfState.waveformNewHigh; - wave->desiredHighCycles = wvfState.waveformNewHigh; - wave->timeLowCycles = wvfState.waveformNewLow; - wave->desiredLowCycles = wvfState.waveformNewLow; - wave->lastEdge = 0; - wvfState.waveformToChange = 0; - } - if (wave->lastEdge) { - desired = wave->desiredLowCycles; - timeToUpdate = &wave->timeLowCycles; - } - nextEdgeCycles = wave->timeHighCycles; - } else { - if (i == 16) { - GP16O = 0; - } - GPOC = mask; - desired = wave->desiredHighCycles; - timeToUpdate = &wave->timeHighCycles; - nextEdgeCycles = wave->timeLowCycles; - } - if (desired) { - desired = adjust(desired); - int32_t err = desired - (now - wave->lastEdge); - if (abs(err) < desired) { // If we've lost > the entire phase, ignore this error signal - err /= 2; - *timeToUpdate += err; - } - } - nextEdgeCycles = adjust(nextEdgeCycles); - wave->nextServiceCycle = now + nextEdgeCycles; - nextEventCycles = min_u32(nextEventCycles, nextEdgeCycles); - wave->lastEdge = now; - } else { - uint32_t deltaCycles = wave->nextServiceCycle - now; - nextEventCycles = min_u32(nextEventCycles, deltaCycles); - } - } - - // Exit the loop if we've hit the fixed runtime limit or the next event is known to be after that timeout would occur - uint32_t now = GetCycleCountIRQ(); - int32_t cycleDeltaNextEvent = timeoutCycle - (now + nextEventCycles); - int32_t cyclesLeftTimeout = timeoutCycle - now; - done = (cycleDeltaNextEvent < 0) || (cyclesLeftTimeout < 0); - } while (!done); - } // if (wvfState.waveformEnabled) - - if (wvfState.timer1CB) { - nextEventCycles = min_u32(nextEventCycles, wvfState.timer1CB()); - } - - if (nextEventCycles < microsecondsToClockCycles(5)) { - nextEventCycles = microsecondsToClockCycles(5); - } - nextEventCycles -= DELTAIRQ; - - // Do it here instead of global function to save time and because we know it's edge-IRQ - T1L = nextEventCycles >> (turbo ? 1 : 0); -} - -}; - -#endif // ESP8266 \ No newline at end of file From 187809300b9d1d2c7b2bf55958249251602fccd0 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:17:37 +0200 Subject: [PATCH 321/581] Delete core_esp8266_wiring_digital.cpp --- tasmota/core_esp8266_wiring_digital.cpp | 274 ------------------------ 1 file changed, 274 deletions(-) delete mode 100644 tasmota/core_esp8266_wiring_digital.cpp diff --git a/tasmota/core_esp8266_wiring_digital.cpp b/tasmota/core_esp8266_wiring_digital.cpp deleted file mode 100644 index 7fb3ccb00..000000000 --- a/tasmota/core_esp8266_wiring_digital.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/* - digital.c - wiring digital implementation for esp8266 - - Copyright (c) 2015 Hristo Gochkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef ESP8266 - -#define ARDUINO_MAIN -#include "wiring_private.h" -#include "pins_arduino.h" -#include "c_types.h" -#include "eagle_soc.h" -#include "ets_sys.h" -#include "user_interface.h" -#include "core_esp8266_waveform.h" -#include "interrupts.h" - -extern "C" { - -// Internal-only calls, not for applications -extern void _setPWMFreq(uint32_t freq); -extern bool _stopPWM(int pin); -extern bool _setPWM(int pin, uint32_t val, uint32_t range); -extern void resetPins(); - -volatile uint32_t* const esp8266_gpioToFn[16] PROGMEM = { &GPF0, &GPF1, &GPF2, &GPF3, &GPF4, &GPF5, &GPF6, &GPF7, &GPF8, &GPF9, &GPF10, &GPF11, &GPF12, &GPF13, &GPF14, &GPF15 }; - -extern void __pinMode(uint8_t pin, uint8_t mode) { - if(pin < 16){ - if(mode == SPECIAL){ - GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) - GPEC = (1 << pin); //Disable - GPF(pin) = GPFFS(GPFFS_BUS(pin));//Set mode to BUS (RX0, TX0, TX1, SPI, HSPI or CLK depending in the pin) - if(pin == 3) GPF(pin) |= (1 << GPFPU);//enable pullup on RX - } else if(mode & FUNCTION_0){ - GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) - GPEC = (1 << pin); //Disable - GPF(pin) = GPFFS((mode >> 4) & 0x07); - if(pin == 13 && mode == FUNCTION_4) GPF(pin) |= (1 << GPFPU);//enable pullup on RX - } else if(mode == OUTPUT || mode == OUTPUT_OPEN_DRAIN){ - GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO - GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) - if(mode == OUTPUT_OPEN_DRAIN) GPC(pin) |= (1 << GPCD); - GPES = (1 << pin); //Enable - } else if(mode == INPUT || mode == INPUT_PULLUP){ - GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO - GPEC = (1 << pin); //Disable - GPC(pin) = (GPC(pin) & (0xF << GPCI)) | (1 << GPCD); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) - if(mode == INPUT_PULLUP) { - GPF(pin) |= (1 << GPFPU); // Enable Pullup - } - } else if(mode == WAKEUP_PULLUP || mode == WAKEUP_PULLDOWN){ - GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO - GPEC = (1 << pin); //Disable - if(mode == WAKEUP_PULLUP) { - GPF(pin) |= (1 << GPFPU); // Enable Pullup - GPC(pin) = (1 << GPCD) | (4 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(LOW) | WAKEUP_ENABLE(ENABLED) - } else { - GPF(pin) |= (1 << GPFPD); // Enable Pulldown - GPC(pin) = (1 << GPCD) | (5 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(HIGH) | WAKEUP_ENABLE(ENABLED) - } - } - } else if(pin == 16){ - GPF16 = GP16FFS(GPFFS_GPIO(pin));//Set mode to GPIO - GPC16 = 0; - if(mode == INPUT || mode == INPUT_PULLDOWN_16){ - if(mode == INPUT_PULLDOWN_16){ - GPF16 |= (1 << GP16FPD);//Enable Pulldown - } - GP16E &= ~1; - } else if(mode == OUTPUT){ - GP16E |= 1; - } - } -} - -extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) { - stopWaveform(pin); // Disable any tone - _stopPWM(pin); // ...and any analogWrite - if(pin < 16){ - if(val) GPOS = (1 << pin); - else GPOC = (1 << pin); - } else if(pin == 16){ - if(val) GP16O |= 1; - else GP16O &= ~1; - } -} - -extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) { - if(pin < 16){ - return GPIP(pin); - } else if(pin == 16){ - return GP16I & 0x01; - } - return 0; -} - -/* - GPIO INTERRUPTS -*/ - -typedef void (*voidFuncPtr)(void); -typedef void (*voidFuncPtrArg)(void*); - -typedef struct { - uint8_t mode; - voidFuncPtr fn; - void * arg; - bool functional; -} interrupt_handler_t; - -//duplicate from functionalInterrupt.h keep in sync -typedef struct InterruptInfo { - uint8_t pin; - uint8_t value; - uint32_t micro; -} InterruptInfo; - -typedef struct { - InterruptInfo* interruptInfo; - void* functionInfo; -} ArgStructure; - -static interrupt_handler_t interrupt_handlers[16] = { {0, 0, 0, 0}, }; -static uint32_t interrupt_reg = 0; - -void ICACHE_RAM_ATTR interrupt_handler(void*) -{ - uint32_t status = GPIE; - GPIEC = status;//clear them interrupts - uint32_t levels = GPI; - if(status == 0 || interrupt_reg == 0) return; - ETS_GPIO_INTR_DISABLE(); - int i = 0; - uint32_t changedbits = status & interrupt_reg; - while(changedbits){ - while(!(changedbits & (1 << i))) i++; - changedbits &= ~(1 << i); - interrupt_handler_t *handler = &interrupt_handlers[i]; - if (handler->fn && - (handler->mode == CHANGE || - (handler->mode & 1) == !!(levels & (1 << i)))) { - // to make ISR compatible to Arduino AVR model where interrupts are disabled - // we disable them before we call the client ISR - esp8266::InterruptLock irqLock; // stop other interrupts - if (handler->functional) - { - ArgStructure* localArg = (ArgStructure*)handler->arg; - if (localArg && localArg->interruptInfo) - { - localArg->interruptInfo->pin = i; - localArg->interruptInfo->value = __digitalRead(i); - localArg->interruptInfo->micro = micros(); - } - } - if (handler->arg) - { - ((voidFuncPtrArg)handler->fn)(handler->arg); - } - else - { - handler->fn(); - } - } - } - ETS_GPIO_INTR_ENABLE(); -} - -extern void cleanupFunctional(void* arg); - -static void set_interrupt_handlers(uint8_t pin, voidFuncPtr userFunc, void* arg, uint8_t mode, bool functional) -{ - interrupt_handler_t* handler = &interrupt_handlers[pin]; - handler->mode = mode; - handler->fn = userFunc; - if (handler->functional && handler->arg) // Clean when new attach without detach - { - cleanupFunctional(handler->arg); - } - handler->arg = arg; - handler->functional = functional; -} - -extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void* arg, int mode, bool functional) -{ - // #5780 - // https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map - if ((uint32_t)userFunc >= 0x40200000) - { - // ISR not in IRAM - ::printf((PGM_P)F("ISR not in IRAM!\r\n")); - abort(); - } - - if(pin < 16) { - ETS_GPIO_INTR_DISABLE(); - set_interrupt_handlers(pin, (voidFuncPtr)userFunc, arg, mode, functional); - interrupt_reg |= (1 << pin); - GPC(pin) &= ~(0xF << GPCI);//INT mode disabled - GPIEC = (1 << pin); //Clear Interrupt for this pin - GPC(pin) |= ((mode & 0xF) << GPCI);//INT mode "mode" - ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg); - ETS_GPIO_INTR_ENABLE(); - } -} - -extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void* arg, int mode) -{ - __attachInterruptFunctionalArg(pin, userFunc, arg, mode, false); -} - -extern void ICACHE_RAM_ATTR __detachInterrupt(uint8_t pin) { - if (pin < 16) - { - ETS_GPIO_INTR_DISABLE(); - GPC(pin) &= ~(0xF << GPCI);//INT mode disabled - GPIEC = (1 << pin); //Clear Interrupt for this pin - interrupt_reg &= ~(1 << pin); - set_interrupt_handlers(pin, nullptr, nullptr, 0, false); - if (interrupt_reg) - { - ETS_GPIO_INTR_ENABLE(); - } - } -} - -extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int mode) -{ - __attachInterruptFunctionalArg(pin, (voidFuncPtrArg)userFunc, 0, mode, false); -} - -extern void __resetPins() { - for (int i = 0; i <= 16; ++i) { - if (!isFlashInterfacePin(i)) - pinMode(i, INPUT); - } -} - -extern void initPins() { - //Disable UART interrupts - system_set_os_print(0); - U0IE = 0; - U1IE = 0; - - resetPins(); -} - -extern void resetPins() __attribute__ ((weak, alias("__resetPins"))); -extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pinMode"))); -extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite"))); -extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead"), nothrow)); -extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt"))); -extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void* arg, int mode) __attribute__((weak, alias("__attachInterruptArg"))); -extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt"))); - -}; - -#endif // ESP8266 \ No newline at end of file From a987a60c507d90db0456c34fcd96efd1a9bc38a4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:17:50 +0200 Subject: [PATCH 322/581] Delete core_esp8266_wiring_pwm.cpp --- tasmota/core_esp8266_wiring_pwm.cpp | 76 ----------------------------- 1 file changed, 76 deletions(-) delete mode 100644 tasmota/core_esp8266_wiring_pwm.cpp diff --git a/tasmota/core_esp8266_wiring_pwm.cpp b/tasmota/core_esp8266_wiring_pwm.cpp deleted file mode 100644 index 5189fa8f5..000000000 --- a/tasmota/core_esp8266_wiring_pwm.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - pwm.c - analogWrite implementation for esp8266 - - Use the shared TIMER1 utilities to generate PWM signals - - Original Copyright (c) 2015 Hristo Gochkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifdef ESP8266 - -#include -#include "core_esp8266_waveform.h" - -extern "C" { - -// Internal-only calls, not for applications -extern void _setPWMFreq(uint32_t freq); -extern bool _stopPWM(int pin); -extern bool _setPWM(int pin, uint32_t val, uint32_t range); - -static int32_t analogScale = PWMRANGE; - -extern void __analogWriteRange(uint32_t range) { - if (range > 0) { - analogScale = range; - } -} - -extern void __analogWriteFreq(uint32_t freq) { - if (freq < 40) { - freq = 40; - } else if (freq > 60000) { - freq = 60000; - } else { - freq = freq; - } - _setPWMFreq(freq); -} - -extern void __analogWrite(uint8_t pin, int val) { - if (pin > 16) { - return; - } - - if (val < 0) { - val = 0; - } else if (val > analogScale) { - val = analogScale; - } - - pinMode(pin, OUTPUT); - _setPWM(pin, val, analogScale); -} - -extern void analogWrite(uint8_t pin, int val) __attribute__((weak, alias("__analogWrite"))); -extern void analogWriteFreq(uint32_t freq) __attribute__((weak, alias("__analogWriteFreq"))); -extern void analogWriteRange(uint32_t range) __attribute__((weak, alias("__analogWriteRange"))); - -}; - -#endif // ESP8266 \ No newline at end of file From e7c6f4645f1761bffac6d606e5ce01bcf0f59702 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:21:48 +0200 Subject: [PATCH 323/581] Use PWM files from Arduino PR 7022 --- tasmota/core_esp8266_waveform.cpp | 436 ++++++++++++++++++++++++ tasmota/core_esp8266_wiring_digital.cpp | 264 ++++++++++++++ tasmota/core_esp8266_wiring_pwm.cpp | 79 +++++ 3 files changed, 779 insertions(+) create mode 100644 tasmota/core_esp8266_waveform.cpp create mode 100644 tasmota/core_esp8266_wiring_digital.cpp create mode 100644 tasmota/core_esp8266_wiring_pwm.cpp diff --git a/tasmota/core_esp8266_waveform.cpp b/tasmota/core_esp8266_waveform.cpp new file mode 100644 index 000000000..952e1fd19 --- /dev/null +++ b/tasmota/core_esp8266_waveform.cpp @@ -0,0 +1,436 @@ +/* + esp8266_waveform - General purpose waveform generation and control, + supporting outputs on all pins in parallel. + + Copyright (c) 2018 Earle F. Philhower, III. All rights reserved. + Copyright (c) 2020 Dirk O. Kaar. + + The core idea is to have a programmable waveform generator with a unique + high and low period (defined in microseconds or CPU clock cycles). TIMER1 is + set to 1-shot mode and is always loaded with the time until the next edge + of any live waveforms. + + Up to one waveform generator per pin supported. + + Each waveform generator is synchronized to the ESP clock cycle counter, not the + timer. This allows for removing interrupt jitter and delay as the counter + always increments once per 80MHz clock. Changes to a waveform are + contiguous and only take effect on the next waveform transition, + allowing for smooth transitions. + + This replaces older tone(), analogWrite(), and the Servo classes. + + Everywhere in the code where "ccy" or "ccys" is used, it means ESP.getCycleCount() + clock cycle time, or an interval measured in clock cycles, but not TIMER1 + cycles (which may be 2 CPU clock cycles @ 160MHz). + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "core_esp8266_waveform.h" +#include +#include "ets_sys.h" +#include + +// Timer is 80MHz fixed. 160MHz CPU frequency need scaling. +constexpr bool ISCPUFREQ160MHZ = clockCyclesPerMicrosecond() == 160; +// Maximum delay between IRQs, Timer1, <= 2^23 / 80MHz +constexpr int32_t MAXIRQTICKSCCYS = microsecondsToClockCycles(10000); +// Maximum servicing time for any single IRQ +constexpr uint32_t ISRTIMEOUTCCYS = microsecondsToClockCycles(18); +// The latency between in-ISR rearming of the timer and the earliest firing +constexpr int32_t IRQLATENCYCCYS = microsecondsToClockCycles(2); +// The SDK and hardware take some time to actually get to our NMI code +constexpr int32_t DELTAIRQCCYS = ISCPUFREQ160MHZ ? + microsecondsToClockCycles(2) >> 1 : microsecondsToClockCycles(2); + +// for INFINITE, the NMI proceeds on the waveform without expiry deadline. +// for EXPIRES, the NMI expires the waveform automatically on the expiry ccy. +// for UPDATEEXPIRY, the NMI recomputes the exact expiry ccy and transitions to EXPIRES. +// for INIT, the NMI initializes nextPeriodCcy, and if expiryCcy != 0 includes UPDATEEXPIRY. +enum class WaveformMode : uint8_t {INFINITE = 0, EXPIRES = 1, UPDATEEXPIRY = 2, INIT = 3}; + +// Waveform generator can create tones, PWM, and servos +typedef struct { + uint32_t nextPeriodCcy; // ESP clock cycle when a period begins. If WaveformMode::INIT, temporarily holds positive phase offset ccy count + uint32_t endDutyCcy; // ESP clock cycle when going from duty to off + int32_t dutyCcys; // Set next off cycle at low->high to maintain phase + int32_t adjDutyCcys; // Temporary correction for next period + int32_t periodCcys; // Set next phase cycle at low->high to maintain phase + uint32_t expiryCcy; // For time-limited waveform, the CPU clock cycle when this waveform must stop. If WaveformMode::UPDATE, temporarily holds relative ccy count + WaveformMode mode; + int8_t alignPhase; // < 0 no phase alignment, otherwise starts waveform in relative phase offset to given pin + bool autoPwm; // perform PWM duty to idle cycle ratio correction under high load at the expense of precise timings +} Waveform; + +namespace { + + static struct { + Waveform pins[17]; // State of all possible pins + uint32_t states = 0; // Is the pin high or low, updated in NMI so no access outside the NMI code + uint32_t enabled = 0; // Is it actively running, updated in NMI so no access outside the NMI code + + // Enable lock-free by only allowing updates to waveform.states and waveform.enabled from IRQ service routine + int32_t toSetBits = 0; // Message to the NMI handler to start/modify exactly one waveform + int32_t toDisableBits = 0; // Message to the NMI handler to disable exactly one pin from waveform generation + + uint32_t(*timer1CB)() = nullptr; + + bool timer1Running = false; + + uint32_t nextEventCcy; + } waveform; + +} + +// Interrupt on/off control +static ICACHE_RAM_ATTR void timer1Interrupt(); + +// Non-speed critical bits +#pragma GCC optimize ("Os") + +static void initTimer() { + timer1_disable(); + ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL); + ETS_FRC_TIMER1_NMI_INTR_ATTACH(timer1Interrupt); + timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE); + waveform.timer1Running = true; + timer1_write(IRQLATENCYCCYS); // Cause an interrupt post-haste +} + +static void ICACHE_RAM_ATTR deinitTimer() { + ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); + timer1_disable(); + timer1_isr_init(); + waveform.timer1Running = false; +} + +extern "C" { + +// Set a callback. Pass in NULL to stop it +void setTimer1Callback(uint32_t (*fn)()) { + waveform.timer1CB = fn; + std::atomic_thread_fence(std::memory_order_acq_rel); + if (!waveform.timer1Running && fn) { + initTimer(); + } else if (waveform.timer1Running && !fn && !waveform.enabled) { + deinitTimer(); + } +} + +int startWaveform(uint8_t pin, uint32_t highUS, uint32_t lowUS, + uint32_t runTimeUS, int8_t alignPhase, uint32_t phaseOffsetUS, bool autoPwm) { + return startWaveformClockCycles(pin, + microsecondsToClockCycles(highUS), microsecondsToClockCycles(lowUS), + microsecondsToClockCycles(runTimeUS), alignPhase, microsecondsToClockCycles(phaseOffsetUS), autoPwm); +} + +// Start up a waveform on a pin, or change the current one. Will change to the new +// waveform smoothly on next low->high transition. For immediate change, stopWaveform() +// first, then it will immediately begin. +int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys, + uint32_t runTimeCcys, int8_t alignPhase, uint32_t phaseOffsetCcys, bool autoPwm) { + uint32_t periodCcys = highCcys + lowCcys; + if (periodCcys < MAXIRQTICKSCCYS) { + if (!highCcys) { + periodCcys = (MAXIRQTICKSCCYS / periodCcys) * periodCcys; + } + else if (!lowCcys) { + highCcys = periodCcys = (MAXIRQTICKSCCYS / periodCcys) * periodCcys; + } + } + // sanity checks, including mixed signed/unsigned arithmetic safety + if ((pin > 16) || isFlashInterfacePin(pin) || (alignPhase > 16) || + static_cast(periodCcys) <= 0 || + static_cast(highCcys) < 0 || static_cast(lowCcys) < 0) { + return false; + } + Waveform& wave = waveform.pins[pin]; + wave.dutyCcys = highCcys; + wave.adjDutyCcys = 0; + wave.periodCcys = periodCcys; + wave.autoPwm = autoPwm; + + std::atomic_thread_fence(std::memory_order_acquire); + const uint32_t pinBit = 1UL << pin; + if (!(waveform.enabled & pinBit)) { + // wave.nextPeriodCcy and wave.endDutyCcy are initialized by the ISR + wave.nextPeriodCcy = phaseOffsetCcys; + wave.expiryCcy = runTimeCcys; // in WaveformMode::INIT, temporarily hold relative cycle count + wave.mode = WaveformMode::INIT; + wave.alignPhase = (alignPhase < 0) ? -1 : alignPhase; + if (!wave.dutyCcys) { + // If initially at zero duty cycle, force GPIO off + if (pin == 16) { + GP16O = 0; + } + else { + GPOC = pinBit; + } + } + std::atomic_thread_fence(std::memory_order_release); + waveform.toSetBits = 1UL << pin; + std::atomic_thread_fence(std::memory_order_release); + if (!waveform.timer1Running) { + initTimer(); + } + else if (T1V > IRQLATENCYCCYS) { + // Must not interfere if Timer is due shortly + timer1_write(IRQLATENCYCCYS); + } + } + else { + wave.mode = WaveformMode::INFINITE; // turn off possible expiry to make update atomic from NMI + std::atomic_thread_fence(std::memory_order_release); + wave.expiryCcy = runTimeCcys; // in WaveformMode::UPDATEEXPIRY, temporarily hold relative cycle count + if (runTimeCcys) { + wave.mode = WaveformMode::UPDATEEXPIRY; + std::atomic_thread_fence(std::memory_order_release); + waveform.toSetBits = 1UL << pin; + } + } + std::atomic_thread_fence(std::memory_order_acq_rel); + while (waveform.toSetBits) { + delay(0); // Wait for waveform to update + std::atomic_thread_fence(std::memory_order_acquire); + } + return true; +} + +// Stops a waveform on a pin +int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) { + // Can't possibly need to stop anything if there is no timer active + if (!waveform.timer1Running) { + return false; + } + // If user sends in a pin >16 but <32, this will always point to a 0 bit + // If they send >=32, then the shift will result in 0 and it will also return false + std::atomic_thread_fence(std::memory_order_acquire); + const uint32_t pinBit = 1UL << pin; + if (waveform.enabled & pinBit) { + waveform.toDisableBits = 1UL << pin; + std::atomic_thread_fence(std::memory_order_release); + // Must not interfere if Timer is due shortly + if (T1V > IRQLATENCYCCYS) { + timer1_write(IRQLATENCYCCYS); + } + while (waveform.toDisableBits) { + /* no-op */ // Can't delay() since stopWaveform may be called from an IRQ + std::atomic_thread_fence(std::memory_order_acquire); + } + } + if (!waveform.enabled && !waveform.timer1CB) { + deinitTimer(); + } + return true; +} + +}; + +// Speed critical bits +#pragma GCC optimize ("O2") + +// For dynamic CPU clock frequency switch in loop the scaling logic would have to be adapted. +// Using constexpr makes sure that the CPU clock frequency is compile-time fixed. +static inline ICACHE_RAM_ATTR int32_t scaleCcys(const int32_t ccys, const bool isCPU2X) { + if (ISCPUFREQ160MHZ) { + return isCPU2X ? ccys : (ccys >> 1); + } + else { + return isCPU2X ? (ccys << 1) : ccys; + } +} + +static ICACHE_RAM_ATTR void timer1Interrupt() { + const uint32_t isrStartCcy = ESP.getCycleCount(); + int32_t clockDrift = isrStartCcy - waveform.nextEventCcy; + const bool isCPU2X = CPU2X & 1; + if ((waveform.toSetBits && !(waveform.enabled & waveform.toSetBits)) || waveform.toDisableBits) { + // Handle enable/disable requests from main app. + waveform.enabled = (waveform.enabled & ~waveform.toDisableBits) | waveform.toSetBits; // Set the requested waveforms on/off + // Find the first GPIO being generated by checking GCC's find-first-set (returns 1 + the bit of the first 1 in an int32_t) + waveform.toDisableBits = 0; + } + + if (waveform.toSetBits) { + const int toSetPin = __builtin_ffs(waveform.toSetBits) - 1; + Waveform& wave = waveform.pins[toSetPin]; + switch (wave.mode) { + case WaveformMode::INIT: + waveform.states &= ~waveform.toSetBits; // Clear the state of any just started + if (wave.alignPhase >= 0 && waveform.enabled & (1UL << wave.alignPhase)) { + wave.nextPeriodCcy = waveform.pins[wave.alignPhase].nextPeriodCcy + wave.nextPeriodCcy; + } + else { + wave.nextPeriodCcy = waveform.nextEventCcy; + } + if (!wave.expiryCcy) { + wave.mode = WaveformMode::INFINITE; + break; + } + // fall through + case WaveformMode::UPDATEEXPIRY: + // in WaveformMode::UPDATEEXPIRY, expiryCcy temporarily holds relative CPU cycle count + wave.expiryCcy = wave.nextPeriodCcy + scaleCcys(wave.expiryCcy, isCPU2X); + wave.mode = WaveformMode::EXPIRES; + break; + default: + break; + } + waveform.toSetBits = 0; + } + + // Exit the loop if the next event, if any, is sufficiently distant. + const uint32_t isrTimeoutCcy = isrStartCcy + ISRTIMEOUTCCYS; + uint32_t busyPins = waveform.enabled; + waveform.nextEventCcy = isrStartCcy + MAXIRQTICKSCCYS; + + uint32_t now = ESP.getCycleCount(); + uint32_t isrNextEventCcy = now; + while (busyPins) { + if (static_cast(isrNextEventCcy - now) > IRQLATENCYCCYS) { + waveform.nextEventCcy = isrNextEventCcy; + break; + } + isrNextEventCcy = waveform.nextEventCcy; + uint32_t loopPins = busyPins; + while (loopPins) { + const int pin = __builtin_ffsl(loopPins) - 1; + const uint32_t pinBit = 1UL << pin; + loopPins ^= pinBit; + + Waveform& wave = waveform.pins[pin]; + + if (clockDrift) { + wave.endDutyCcy += clockDrift; + wave.nextPeriodCcy += clockDrift; + wave.expiryCcy += clockDrift; + } + + uint32_t waveNextEventCcy = (waveform.states & pinBit) ? wave.endDutyCcy : wave.nextPeriodCcy; + if (WaveformMode::EXPIRES == wave.mode && + static_cast(waveNextEventCcy - wave.expiryCcy) >= 0 && + static_cast(now - wave.expiryCcy) >= 0) { + // Disable any waveforms that are done + waveform.enabled ^= pinBit; + busyPins ^= pinBit; + } + else { + const int32_t overshootCcys = now - waveNextEventCcy; + if (overshootCcys >= 0) { + const int32_t periodCcys = scaleCcys(wave.periodCcys, isCPU2X); + if (waveform.states & pinBit) { + // active configuration and forward are 100% duty + if (wave.periodCcys == wave.dutyCcys) { + wave.nextPeriodCcy += periodCcys; + wave.endDutyCcy = wave.nextPeriodCcy; + } + else { + if (wave.autoPwm) { + wave.adjDutyCcys += overshootCcys; + } + waveform.states ^= pinBit; + if (16 == pin) { + GP16O = 0; + } + else { + GPOC = pinBit; + } + } + waveNextEventCcy = wave.nextPeriodCcy; + } + else { + wave.nextPeriodCcy += periodCcys; + if (!wave.dutyCcys) { + wave.endDutyCcy = wave.nextPeriodCcy; + } + else { + int32_t dutyCcys = scaleCcys(wave.dutyCcys, isCPU2X); + if (dutyCcys <= wave.adjDutyCcys) { + dutyCcys >>= 1; + wave.adjDutyCcys -= dutyCcys; + } + else if (wave.adjDutyCcys) { + dutyCcys -= wave.adjDutyCcys; + wave.adjDutyCcys = 0; + } + wave.endDutyCcy = now + dutyCcys; + if (static_cast(wave.endDutyCcy - wave.nextPeriodCcy) > 0) { + wave.endDutyCcy = wave.nextPeriodCcy; + } + waveform.states |= pinBit; + if (16 == pin) { + GP16O = 1; + } + else { + GPOS = pinBit; + } + } + waveNextEventCcy = wave.endDutyCcy; + } + + if (WaveformMode::EXPIRES == wave.mode && static_cast(waveNextEventCcy - wave.expiryCcy) > 0) { + waveNextEventCcy = wave.expiryCcy; + } + } + + if (static_cast(waveNextEventCcy - isrTimeoutCcy) >= 0) { + busyPins ^= pinBit; + if (static_cast(waveform.nextEventCcy - waveNextEventCcy) > 0) { + waveform.nextEventCcy = waveNextEventCcy; + } + } + else if (static_cast(isrNextEventCcy - waveNextEventCcy) > 0) { + isrNextEventCcy = waveNextEventCcy; + } + } + now = ESP.getCycleCount(); + } + clockDrift = 0; + } + + int32_t callbackCcys = 0; + if (waveform.timer1CB) { + callbackCcys = scaleCcys(microsecondsToClockCycles(waveform.timer1CB()), isCPU2X); + } + now = ESP.getCycleCount(); + int32_t nextEventCcys = waveform.nextEventCcy - now; + // Account for unknown duration of timer1CB(). + if (waveform.timer1CB && nextEventCcys > callbackCcys) { + waveform.nextEventCcy = now + callbackCcys; + nextEventCcys = callbackCcys; + } + + // Timer is 80MHz fixed. 160MHz CPU frequency need scaling. + int32_t deltaIrqCcys = DELTAIRQCCYS; + int32_t irqLatencyCcys = IRQLATENCYCCYS; + if (isCPU2X) { + nextEventCcys >>= 1; + deltaIrqCcys >>= 1; + irqLatencyCcys >>= 1; + } + + // Firing timer too soon, the NMI occurs before ISR has returned. + if (nextEventCcys < irqLatencyCcys + deltaIrqCcys) { + waveform.nextEventCcy = now + IRQLATENCYCCYS + DELTAIRQCCYS; + nextEventCcys = irqLatencyCcys; + } + else { + nextEventCcys -= deltaIrqCcys; + } + + // Register access is fast and edge IRQ was configured before. + T1L = nextEventCcys; +} diff --git a/tasmota/core_esp8266_wiring_digital.cpp b/tasmota/core_esp8266_wiring_digital.cpp new file mode 100644 index 000000000..9c15703e0 --- /dev/null +++ b/tasmota/core_esp8266_wiring_digital.cpp @@ -0,0 +1,264 @@ +/* + digital.c - wiring digital implementation for esp8266 + + Copyright (c) 2015 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#define ARDUINO_MAIN +#include "wiring_private.h" +#include "pins_arduino.h" +#include "c_types.h" +#include "eagle_soc.h" +#include "ets_sys.h" +#include "user_interface.h" +#include "core_esp8266_waveform.h" +#include "interrupts.h" + +extern "C" { + +volatile uint32_t* const esp8266_gpioToFn[16] PROGMEM = { &GPF0, &GPF1, &GPF2, &GPF3, &GPF4, &GPF5, &GPF6, &GPF7, &GPF8, &GPF9, &GPF10, &GPF11, &GPF12, &GPF13, &GPF14, &GPF15 }; + +extern void __pinMode(uint8_t pin, uint8_t mode) { + if(pin < 16){ + if(mode == SPECIAL){ + GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) + GPEC = (1 << pin); //Disable + GPF(pin) = GPFFS(GPFFS_BUS(pin));//Set mode to BUS (RX0, TX0, TX1, SPI, HSPI or CLK depending in the pin) + if(pin == 3) GPF(pin) |= (1 << GPFPU);//enable pullup on RX + } else if(mode & FUNCTION_0){ + GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) + GPEC = (1 << pin); //Disable + GPF(pin) = GPFFS((mode >> 4) & 0x07); + if(pin == 13 && mode == FUNCTION_4) GPF(pin) |= (1 << GPFPU);//enable pullup on RX + } else if(mode == OUTPUT || mode == OUTPUT_OPEN_DRAIN){ + GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO + GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) + if(mode == OUTPUT_OPEN_DRAIN) GPC(pin) |= (1 << GPCD); + GPES = (1 << pin); //Enable + } else if(mode == INPUT || mode == INPUT_PULLUP){ + GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO + GPEC = (1 << pin); //Disable + GPC(pin) = (GPC(pin) & (0xF << GPCI)) | (1 << GPCD); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED) + if(mode == INPUT_PULLUP) { + GPF(pin) |= (1 << GPFPU); // Enable Pullup + } + } else if(mode == WAKEUP_PULLUP || mode == WAKEUP_PULLDOWN){ + GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO + GPEC = (1 << pin); //Disable + if(mode == WAKEUP_PULLUP) { + GPF(pin) |= (1 << GPFPU); // Enable Pullup + GPC(pin) = (1 << GPCD) | (4 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(LOW) | WAKEUP_ENABLE(ENABLED) + } else { + GPF(pin) |= (1 << GPFPD); // Enable Pulldown + GPC(pin) = (1 << GPCD) | (5 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(HIGH) | WAKEUP_ENABLE(ENABLED) + } + } + } else if(pin == 16){ + GPF16 = GP16FFS(GPFFS_GPIO(pin));//Set mode to GPIO + GPC16 = 0; + if(mode == INPUT || mode == INPUT_PULLDOWN_16){ + if(mode == INPUT_PULLDOWN_16){ + GPF16 |= (1 << GP16FPD);//Enable Pulldown + } + GP16E &= ~1; + } else if(mode == OUTPUT){ + GP16E |= 1; + } + } +} + +extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) { + stopWaveform(pin); + if(pin < 16){ + if(val) GPOS = (1 << pin); + else GPOC = (1 << pin); + } else if(pin == 16){ + if(val) GP16O |= 1; + else GP16O &= ~1; + } +} + +extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) { + if(pin < 16){ + return GPIP(pin); + } else if(pin == 16){ + return GP16I & 0x01; + } + return 0; +} + +/* + GPIO INTERRUPTS +*/ + +typedef void (*voidFuncPtr)(void); +typedef void (*voidFuncPtrArg)(void*); + +typedef struct { + uint8_t mode; + voidFuncPtr fn; + void * arg; + bool functional; +} interrupt_handler_t; + +//duplicate from functionalInterrupt.h keep in sync +typedef struct InterruptInfo { + uint8_t pin; + uint8_t value; + uint32_t micro; +} InterruptInfo; + +typedef struct { + InterruptInfo* interruptInfo; + void* functionInfo; +} ArgStructure; + +static interrupt_handler_t interrupt_handlers[16] = { {0, 0, 0, 0}, }; +static uint32_t interrupt_reg = 0; + +void ICACHE_RAM_ATTR interrupt_handler(void *arg, void *frame) +{ + (void) arg; + (void) frame; + uint32_t status = GPIE; + GPIEC = status;//clear them interrupts + uint32_t levels = GPI; + if(status == 0 || interrupt_reg == 0) return; + ETS_GPIO_INTR_DISABLE(); + int i = 0; + uint32_t changedbits = status & interrupt_reg; + while(changedbits){ + while(!(changedbits & (1 << i))) i++; + changedbits &= ~(1 << i); + interrupt_handler_t *handler = &interrupt_handlers[i]; + if (handler->fn && + (handler->mode == CHANGE || + (handler->mode & 1) == !!(levels & (1 << i)))) { + // to make ISR compatible to Arduino AVR model where interrupts are disabled + // we disable them before we call the client ISR + esp8266::InterruptLock irqLock; // stop other interrupts + if (handler->functional) + { + ArgStructure* localArg = (ArgStructure*)handler->arg; + if (localArg && localArg->interruptInfo) + { + localArg->interruptInfo->pin = i; + localArg->interruptInfo->value = __digitalRead(i); + localArg->interruptInfo->micro = micros(); + } + } + if (handler->arg) + { + ((voidFuncPtrArg)handler->fn)(handler->arg); + } + else + { + handler->fn(); + } + } + } + ETS_GPIO_INTR_ENABLE(); +} + +extern void cleanupFunctional(void* arg); + +static void set_interrupt_handlers(uint8_t pin, voidFuncPtr userFunc, void* arg, uint8_t mode, bool functional) +{ + interrupt_handler_t* handler = &interrupt_handlers[pin]; + handler->mode = mode; + handler->fn = userFunc; + if (handler->functional && handler->arg) // Clean when new attach without detach + { + cleanupFunctional(handler->arg); + } + handler->arg = arg; + handler->functional = functional; +} + +extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void* arg, int mode, bool functional) +{ + // #5780 + // https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map + if ((uint32_t)userFunc >= 0x40200000) + { + // ISR not in IRAM + ::printf((PGM_P)F("ISR not in IRAM!\r\n")); + abort(); + } + + if(pin < 16) { + ETS_GPIO_INTR_DISABLE(); + set_interrupt_handlers(pin, (voidFuncPtr)userFunc, arg, mode, functional); + interrupt_reg |= (1 << pin); + GPC(pin) &= ~(0xF << GPCI);//INT mode disabled + GPIEC = (1 << pin); //Clear Interrupt for this pin + GPC(pin) |= ((mode & 0xF) << GPCI);//INT mode "mode" + ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg); + ETS_GPIO_INTR_ENABLE(); + } +} + +extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void* arg, int mode) +{ + __attachInterruptFunctionalArg(pin, userFunc, arg, mode, false); +} + +extern void ICACHE_RAM_ATTR __detachInterrupt(uint8_t pin) { + if (pin < 16) + { + ETS_GPIO_INTR_DISABLE(); + GPC(pin) &= ~(0xF << GPCI);//INT mode disabled + GPIEC = (1 << pin); //Clear Interrupt for this pin + interrupt_reg &= ~(1 << pin); + set_interrupt_handlers(pin, nullptr, nullptr, 0, false); + if (interrupt_reg) + { + ETS_GPIO_INTR_ENABLE(); + } + } +} + +extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int mode) +{ + __attachInterruptFunctionalArg(pin, (voidFuncPtrArg)userFunc, 0, mode, false); +} + +extern void __resetPins() { + for (int i = 0; i <= 16; ++i) { + if (!isFlashInterfacePin(i)) + pinMode(i, INPUT); + } +} + +extern void initPins() { + //Disable UART interrupts + system_set_os_print(0); + U0IE = 0; + U1IE = 0; + + resetPins(); +} + +extern void resetPins() __attribute__ ((weak, alias("__resetPins"))); +extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pinMode"))); +extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite"))); +extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead"), nothrow)); +extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt"))); +extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void* arg, int mode) __attribute__((weak, alias("__attachInterruptArg"))); +extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt"))); + +}; diff --git a/tasmota/core_esp8266_wiring_pwm.cpp b/tasmota/core_esp8266_wiring_pwm.cpp new file mode 100644 index 000000000..608e06bda --- /dev/null +++ b/tasmota/core_esp8266_wiring_pwm.cpp @@ -0,0 +1,79 @@ +/* + pwm.c - analogWrite implementation for esp8266 + + Use the shared TIMER1 utilities to generate PWM signals + + Original Copyright (c) 2015 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include "core_esp8266_waveform.h" + +extern "C" { + +static uint32_t analogMap = 0; +static int32_t analogScale = PWMRANGE; +static uint16_t analogFreq = 1000; + +extern void __analogWriteRange(uint32_t range) { + if (range > 0) { + analogScale = range; + } +} + +extern void __analogWriteFreq(uint32_t freq) { + if (freq < 100) { + analogFreq = 100; + } else if (freq > 60000) { + analogFreq = 60000; + } else { + analogFreq = freq; + } +} + +extern void __analogWrite(uint8_t pin, int val) { + if (pin > 16) { + return; + } + uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq; + if (val < 0) { + val = 0; + } else if (val > analogScale) { + val = analogScale; + } + + if (analogMap & 1UL << pin) { + analogMap &= ~(1 << pin); + } + else { + pinMode(pin, OUTPUT); + } + uint32_t high = (analogPeriod * val) / analogScale; + uint32_t low = analogPeriod - high; + // Find the first GPIO being generated by checking GCC's find-first-set (returns 1 + the bit of the first 1 in an int32_t) + int phaseReference = __builtin_ffs(analogMap) - 1; + if (startWaveformClockCycles(pin, high, low, 0, phaseReference, 0, true)) { + analogMap |= (1 << pin); + } +} + +extern void analogWrite(uint8_t pin, int val) __attribute__((weak, alias("__analogWrite"))); +extern void analogWriteFreq(uint32_t freq) __attribute__((weak, alias("__analogWriteFreq"))); +extern void analogWriteRange(uint32_t range) __attribute__((weak, alias("__analogWriteRange"))); + +}; From 029a6d165e5868c743ccdea90c9bd316ab8c9d10 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:35:58 +0200 Subject: [PATCH 324/581] Add files via upload From ee2fea9e25e0a9b1d1e1c7c2d43a62ed58c3ecc8 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:39:14 +0200 Subject: [PATCH 325/581] Add files via upload --- tasmota/core_esp8266_waveform.h | 89 +++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 tasmota/core_esp8266_waveform.h diff --git a/tasmota/core_esp8266_waveform.h b/tasmota/core_esp8266_waveform.h new file mode 100644 index 000000000..61cb99966 --- /dev/null +++ b/tasmota/core_esp8266_waveform.h @@ -0,0 +1,89 @@ +/* + esp8266_waveform - General purpose waveform generation and control, + supporting outputs on all pins in parallel. + + Copyright (c) 2018 Earle F. Philhower, III. All rights reserved. + Copyright (c) 2020 Dirk O. Kaar. + + The core idea is to have a programmable waveform generator with a unique + high and low period (defined in microseconds or CPU clock cycles). TIMER1 is + set to 1-shot mode and is always loaded with the time until the next edge + of any live waveforms. + + Up to one waveform generator per pin supported. + + Each waveform generator is synchronized to the ESP clock cycle counter, not the + timer. This allows for removing interrupt jitter and delay as the counter + always increments once per 80MHz clock. Changes to a waveform are + contiguous and only take effect on the next waveform transition, + allowing for smooth transitions. + + This replaces older tone(), analogWrite(), and the Servo classes. + + Everywhere in the code where "ccy" or "ccys" is used, it means ESP.getCycleCount() + clock cycle count, or an interval measured in CPU clock cycles, but not TIMER1 + cycles (which may be 2 CPU clock cycles @ 160MHz). + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#ifndef __ESP8266_WAVEFORM_H +#define __ESP8266_WAVEFORM_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Start or change a waveform of the specified high and low times on specific pin. +// If runtimeUS > 0 then automatically stop it after that many usecs, relative to the next +// full period. +// If waveform is not yet started on pin, and on pin == alignPhase a waveform is running, +// the new waveform is started at phaseOffsetUS phase offset, in microseconds, to that. +// Setting autoPwm to true allows the wave generator to maintain PWM duty to idle cycle ratio +// under load, for applications where frequency or duty cycle must not change, leave false. +// Returns true or false on success or failure. +int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, + uint32_t runTimeUS = 0, int8_t alignPhase = -1, uint32_t phaseOffsetUS = 0, bool autoPwm = false); +// Start or change a waveform of the specified high and low CPU clock cycles on specific pin. +// If runtimeCycles > 0 then automatically stop it after that many CPU clock cycles, relative to the next +// full period. +// If waveform is not yet started on pin, and on pin == alignPhase a waveform is running, +// the new waveform is started at phaseOffsetCcys phase offset, in CPU clock cycles, to that. +// Setting autoPwm to true allows the wave generator to maintain PWM duty to idle cycle ratio +// under load, for applications where frequency or duty cycle must not change, leave false. +// Returns true or false on success or failure. +int startWaveformClockCycles(uint8_t pin, uint32_t timeHighCcys, uint32_t timeLowCcys, + uint32_t runTimeCcys = 0, int8_t alignPhase = -1, uint32_t phaseOffsetCcys = 0, bool autoPwm = false); +// Stop a waveform, if any, on the specified pin. +// Returns true or false on success or failure. +int stopWaveform(uint8_t pin); + +// Add a callback function to be called on *EVERY* timer1 trigger. The +// callback returns the number of microseconds until the next desired call. +// However, since it is called every timer1 interrupt, it may be called +// again before this period. It should therefore use the ESP Cycle Counter +// to determine whether or not to perform an operation. +// Pass in NULL to disable the callback and, if no other waveforms being +// generated, stop the timer as well. +// Make sure the CB function has the ICACHE_RAM_ATTR decorator. +void setTimer1Callback(uint32_t (*fn)()); + +#ifdef __cplusplus +} +#endif + +#endif From bcc9145a91c394ee09e33a0356a9514eb480e9ae Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 20:01:26 +0200 Subject: [PATCH 326/581] Update core_esp8266_waveform.h --- tasmota/core_esp8266_waveform.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/core_esp8266_waveform.h b/tasmota/core_esp8266_waveform.h index 61cb99966..ff5a0f56f 100644 --- a/tasmota/core_esp8266_waveform.h +++ b/tasmota/core_esp8266_waveform.h @@ -39,6 +39,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef ESP8266 + #include #ifndef __ESP8266_WAVEFORM_H @@ -87,3 +89,5 @@ void setTimer1Callback(uint32_t (*fn)()); #endif #endif + +#endif // ESP8266 From e893f8d97d0f459d24d153394277a018936f96e8 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 20:02:15 +0200 Subject: [PATCH 327/581] Update core_esp8266_waveform.cpp --- tasmota/core_esp8266_waveform.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/core_esp8266_waveform.cpp b/tasmota/core_esp8266_waveform.cpp index 952e1fd19..371e9e554 100644 --- a/tasmota/core_esp8266_waveform.cpp +++ b/tasmota/core_esp8266_waveform.cpp @@ -39,6 +39,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef ESP8266 + #include "core_esp8266_waveform.h" #include #include "ets_sys.h" @@ -434,3 +436,5 @@ static ICACHE_RAM_ATTR void timer1Interrupt() { // Register access is fast and edge IRQ was configured before. T1L = nextEventCcys; } + +#endif // ESP8266 From 5322238d565028ec7f7f3a659c01100e6d646b63 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 20:02:55 +0200 Subject: [PATCH 328/581] Update core_esp8266_wiring_digital.cpp --- tasmota/core_esp8266_wiring_digital.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tasmota/core_esp8266_wiring_digital.cpp b/tasmota/core_esp8266_wiring_digital.cpp index 9c15703e0..982e1c6bf 100644 --- a/tasmota/core_esp8266_wiring_digital.cpp +++ b/tasmota/core_esp8266_wiring_digital.cpp @@ -18,6 +18,9 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifdef ESP8266 + #define ARDUINO_MAIN #include "wiring_private.h" #include "pins_arduino.h" @@ -262,3 +265,5 @@ extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void* arg, i extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt"))); }; + +#endif // ESP8266 From 526593d9c91193f38a34b1eaf863a8d569262a16 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 23 Jun 2020 20:03:41 +0200 Subject: [PATCH 329/581] Update core_esp8266_wiring_pwm.cpp --- tasmota/core_esp8266_wiring_pwm.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tasmota/core_esp8266_wiring_pwm.cpp b/tasmota/core_esp8266_wiring_pwm.cpp index 608e06bda..f74334e43 100644 --- a/tasmota/core_esp8266_wiring_pwm.cpp +++ b/tasmota/core_esp8266_wiring_pwm.cpp @@ -21,6 +21,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef ESP8266 + #include #include "core_esp8266_waveform.h" @@ -37,8 +39,8 @@ extern void __analogWriteRange(uint32_t range) { } extern void __analogWriteFreq(uint32_t freq) { - if (freq < 100) { - analogFreq = 100; + if (freq < 40) { + analogFreq = 40; } else if (freq > 60000) { analogFreq = 60000; } else { @@ -77,3 +79,5 @@ extern void analogWriteFreq(uint32_t freq) __attribute__((weak, alias("__analogW extern void analogWriteRange(uint32_t range) __attribute__((weak, alias("__analogWriteRange"))); }; + +#endif // ESP8266 From 100805ff26df647302ea8e2c3dc2da6882216776 Mon Sep 17 00:00:00 2001 From: Alain Turbide Date: Tue, 23 Jun 2020 18:09:44 -0400 Subject: [PATCH 330/581] Add support for GlobalCache codes using the same format as irsend raw. Use irsend gc,xxx,xxx --- tasmota/xdrv_05_irremote_full.ino | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index 60e16b30d..3f43c364a 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -470,6 +470,29 @@ uint32_t IrRemoteCmndIrSendRaw(void) return IE_INVALID_RAWDATA; } // Parameters must be at least 3 + +#ifdef IR_GC +//ir_gc + + if (strcmp(str, "gc") == 0) { //if first parameter is gc then we process global cache data else it is raw + + uint16_t GC[count+1]; + for (uint32_t i = 0; i <= count; i++) { + GC[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); + if (!GC[i]) { + return IE_INVALID_RAWDATA; + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: GC value %d"), GC[i]); + } + irsend->sendGC(GC, count+1); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: GC sent count %d"), count); + return IE_NO_ERROR; + } +//end ir_gc +#endif + + + uint16_t parm[count]; for (uint32_t i = 0; i < count; i++) { parm[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); From 2b1d251b85de0f6f9af1a67ce277a9850bdcc1be Mon Sep 17 00:00:00 2001 From: Alain Turbide Date: Tue, 23 Jun 2020 19:46:55 -0400 Subject: [PATCH 331/581] - Added case insensitivity for GC/gc - Added repeat support - removed debug messages --- tasmota/xdrv_05_irremote_full.ino | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index 3f43c364a..ba132b9be 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -472,23 +472,19 @@ uint32_t IrRemoteCmndIrSendRaw(void) #ifdef IR_GC -//ir_gc - - if (strcmp(str, "gc") == 0) { //if first parameter is gc then we process global cache data else it is raw - + if (strcmp(str, "gc") == 0 ||strcmp(str, "GC") == 0) { //if first parameter is gc then we process global cache data else it is raw uint16_t GC[count+1]; for (uint32_t i = 0; i <= count; i++) { GC[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); if (!GC[i]) { - return IE_INVALID_RAWDATA; + return IE_INVALID_RAWDATA; } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: GC value %d"), GC[i]); } - irsend->sendGC(GC, count+1); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: GC sent count %d"), count); - return IE_NO_ERROR; + for (uint32_t r = 0; r <= repeat; r++) { + irsend->sendGC(GC, count+1); + } + return IE_NO_ERROR; } -//end ir_gc #endif From 0c02d1ae3e6dae5b037575ca04ef60c230e96103 Mon Sep 17 00:00:00 2001 From: Alain Turbide Date: Tue, 23 Jun 2020 20:13:09 -0400 Subject: [PATCH 332/581] add missing irsend_active flag to block ir receive during send --- tasmota/xdrv_05_irremote_full.ino | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index ba132b9be..d4f289c0a 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -470,9 +470,8 @@ uint32_t IrRemoteCmndIrSendRaw(void) return IE_INVALID_RAWDATA; } // Parameters must be at least 3 - #ifdef IR_GC - if (strcmp(str, "gc") == 0 ||strcmp(str, "GC") == 0) { //if first parameter is gc then we process global cache data else it is raw + if (strcmp(str, "gc") == 0 || strcmp(str, "GC") == 0) { //if first parameter is gc then we process global cache data else it is raw uint16_t GC[count+1]; for (uint32_t i = 0; i <= count; i++) { GC[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); @@ -480,6 +479,7 @@ uint32_t IrRemoteCmndIrSendRaw(void) return IE_INVALID_RAWDATA; } } + irsend_active = true; for (uint32_t r = 0; r <= repeat; r++) { irsend->sendGC(GC, count+1); } @@ -487,8 +487,6 @@ uint32_t IrRemoteCmndIrSendRaw(void) } #endif - - uint16_t parm[count]; for (uint32_t i = 0; i < count; i++) { parm[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); From 59a433fe77af8acc22207a239f94212441f05157 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 24 Jun 2020 12:01:13 +0200 Subject: [PATCH 333/581] Fix regression from latest Platformio optimization when Platformio_override.ini is activated and no other core is choosen as the selected in platformio.ini --- platformio_override_sample.ini | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 0311c6280..902675fe4 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -36,10 +36,10 @@ default_envs = [common] -platform = ${core_active.platform} -platform_packages = ${core_active.platform_packages} -build_unflags = ${core_active.build_unflags} -build_flags = ${core_active.build_flags} +platform = ${core.platform} +platform_packages = ${core.platform_packages} +build_unflags = ${core.build_unflags} +build_flags = ${core.build_flags} ; *** Optional Debug messages ; -DDEBUG_TASMOTA_CORE ; -DDEBUG_TASMOTA_DRIVER @@ -71,7 +71,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} ; pio/strip-floats.py ; pio/http-uploader.py -[core_active] +[core] ; Activate only (one set) if you want to override the standard core defined in platformio.ini !!! ;platform = ${tasmota_stage.platform} @@ -87,7 +87,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage -extends = core +platform = espressif8266@2.5.3 platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#52b3e5b7b3ccedcede665682f7896b637b64dbf5 build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} @@ -123,7 +123,7 @@ build_flags = ${esp82xx_defaults.build_flags} [core_stage] ; *** Esp8266 core for Arduino version latest development version -extends = core +platform = espressif8266@2.5.3 platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} @@ -160,7 +160,6 @@ build_flags = ${esp82xx_defaults.build_flags} ; *** Debug version used for PlatformIO Home Project Inspection [env:tasmota-debug] -extends = core build_type = debug build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From 076d1521e33b6cabb10c10d17bd0315c966b2e7e Mon Sep 17 00:00:00 2001 From: Alain Turbide Date: Wed, 24 Jun 2020 07:09:22 -0400 Subject: [PATCH 334/581] - switched to strcasecmp for compare - removed ifdef/endif --- tasmota/xdrv_05_irremote_full.ino | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index d4f289c0a..457ff63f4 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -470,8 +470,7 @@ uint32_t IrRemoteCmndIrSendRaw(void) return IE_INVALID_RAWDATA; } // Parameters must be at least 3 -#ifdef IR_GC - if (strcmp(str, "gc") == 0 || strcmp(str, "GC") == 0) { //if first parameter is gc then we process global cache data else it is raw + if (strcasecmp(str, "gc") == 0) { //if first parameter is gc then we process global cache data else it is raw uint16_t GC[count+1]; for (uint32_t i = 0; i <= count; i++) { GC[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); @@ -485,7 +484,6 @@ uint32_t IrRemoteCmndIrSendRaw(void) } return IE_NO_ERROR; } -#endif uint16_t parm[count]; for (uint32_t i = 0; i < count; i++) { From f4adce5fb15c4aa2375b8558ee66a73087a0d0b4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 24 Jun 2020 15:36:54 +0200 Subject: [PATCH 335/581] Add ESP32 DHT support Add ESP32 DHT support (#8503) --- tasmota/tasmota_globals.h | 2 ++ tasmota/xsns_06_dht.ino | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index f52f7a218..791896ac3 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -372,8 +372,10 @@ const char kWebColors[] PROGMEM = #ifdef ESP8266 #define AGPIO(x) (x) +#define BGPIO(x) (x) #else // ESP32 #define AGPIO(x) (x<<5) +#define BGPIO(x) (x>>5) #endif // ESP8266 - ESP32 #ifdef USE_DEVICE_GROUPS diff --git a/tasmota/xsns_06_dht.ino b/tasmota/xsns_06_dht.ino index 7bb1a3513..d2e47fe17 100644 --- a/tasmota/xsns_06_dht.ino +++ b/tasmota/xsns_06_dht.ino @@ -188,12 +188,12 @@ bool DhtRead(uint32_t sensor) bool DhtPinState() { - if ((XdrvMailbox.index >= GPIO_DHT11) && (XdrvMailbox.index <= GPIO_SI7021)) { + if ((XdrvMailbox.index >= AGPIO(GPIO_DHT11)) && (XdrvMailbox.index <= AGPIO(GPIO_SI7021))) { if (dht_sensors < DHT_MAX_SENSORS) { Dht[dht_sensors].pin = XdrvMailbox.payload; - Dht[dht_sensors].type = XdrvMailbox.index; + Dht[dht_sensors].type = BGPIO(XdrvMailbox.index); dht_sensors++; - XdrvMailbox.index = GPIO_DHT11; + XdrvMailbox.index = AGPIO(GPIO_DHT11); } else { XdrvMailbox.index = 0; } From 5631415acddf98b5d72713656a25b73060380677 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 24 Jun 2020 15:49:18 +0200 Subject: [PATCH 336/581] Add ESP32 inverted buzzer support --- tasmota/xdrv_24_buzzer.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_24_buzzer.ino b/tasmota/xdrv_24_buzzer.ino index f158f3cd9..10232cc52 100644 --- a/tasmota/xdrv_24_buzzer.ino +++ b/tasmota/xdrv_24_buzzer.ino @@ -101,9 +101,9 @@ void BuzzerEnabledBeep(uint32_t count, uint32_t duration) bool BuzzerPinState(void) { - if (XdrvMailbox.index == GPIO_BUZZER_INV) { + if (XdrvMailbox.index == AGPIO(GPIO_BUZZER_INV)) { Buzzer.inverted = 1; - XdrvMailbox.index -= (GPIO_BUZZER_INV - GPIO_BUZZER); + XdrvMailbox.index -= (AGPIO(GPIO_BUZZER_INV) - AGPIO(GPIO_BUZZER)); return true; } return false; From 7600a81c8ed077c42d319ae81e706f71845c81ec Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 24 Jun 2020 15:50:14 +0200 Subject: [PATCH 337/581] Add ESP32 counter support --- tasmota/xsns_01_counter.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index fec5791f7..3dfbdfaaf 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -113,9 +113,9 @@ void CounterUpdate4(void) bool CounterPinState(void) { - if ((XdrvMailbox.index >= GPIO_CNTR1_NP) && (XdrvMailbox.index < (GPIO_CNTR1_NP + MAX_COUNTERS))) { - bitSet(Counter.no_pullup, XdrvMailbox.index - GPIO_CNTR1_NP); - XdrvMailbox.index -= (GPIO_CNTR1_NP - GPIO_CNTR1); + if ((XdrvMailbox.index >= AGPIO(GPIO_CNTR1_NP)) && (XdrvMailbox.index < (AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS))) { + bitSet(Counter.no_pullup, XdrvMailbox.index - AGPIO(GPIO_CNTR1_NP)); + XdrvMailbox.index -= (AGPIO(GPIO_CNTR1_NP) - AGPIO(GPIO_CNTR1)); return true; } return false; From ff327106be279d51fdb3d1785de05ec22d208348 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 24 Jun 2020 15:58:56 +0200 Subject: [PATCH 338/581] Refactor ESP32 support --- tasmota/support.ino | 6 +----- tasmota/support_command.ino | 10 ++++------ tasmota/xdrv_01_webserver.ino | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index cdd1b3cd6..427a47dcf 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1265,11 +1265,7 @@ uint32_t ValidPin(uint32_t pin, uint32_t gpio) bool ValidGPIO(uint32_t pin, uint32_t gpio) { -#ifdef ESP8266 - return (GPIO_USER == ValidPin(pin, gpio)); // Only allow GPIO_USER pins -#else // ESP32 - return (GPIO_USER == ValidPin(pin, gpio >> 5)); // Only allow GPIO_USER pins -#endif // ESP8266 - ESP32 + return (GPIO_USER == ValidPin(pin, BGPIO(gpio))); // Only allow GPIO_USER pins } #ifdef ESP8266 diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 612f4dbce..9c4c858cc 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1113,10 +1113,8 @@ void CmndGpio(void) } } char sindex[4] = { 0 }; -#ifdef ESP8266 - uint32_t sensor_name_idx = sensor_type; -#else // ESP32 - uint32_t sensor_name_idx = sensor_type >> 5; + uint32_t sensor_name_idx = BGPIO(sensor_type); +#ifdef ESP32 uint32_t nice_list_search = sensor_type & 0xFFE0; for (uint32_t j = 0; j < ARRAY_SIZE(kGpioNiceList); j++) { uint32_t nls_idx = pgm_read_word(kGpioNiceList + j); @@ -1125,7 +1123,7 @@ void CmndGpio(void) break; } } -#endif // ESP8266 - ESP32 +#endif // ESP32 const char *sensor_names = kSensorNames; if (sensor_name_idx > GPIO_FIX_START) { sensor_name_idx = sensor_name_idx - GPIO_FIX_START -1; @@ -1156,7 +1154,7 @@ void CmndGpios(void) uint32_t ridx = midx; #else // ESP32 uint32_t ridx = pgm_read_word(kGpioNiceList + i) & 0xFFE0; - uint32_t midx = ridx >> 5; + uint32_t midx = BGPIO(ridx); #endif // ESP8266 - ESP32 if ((XdrvMailbox.payload != 255) && GetUsedInModule(midx, cmodule.io)) { continue; } if (!jsflg) { diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index d18368431..b5e5c9571 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1728,7 +1728,7 @@ void HandleTemplateConfiguration(void) WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, AGPIO(GPIO_USER), D_SENSOR_USER); // }2'255'>User}3 } uint32_t ridx = pgm_read_word(kGpioNiceList + i) & 0xFFE0; - uint32_t midx = ridx >> 5; + uint32_t midx = BGPIO(ridx); WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, ridx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames)); #endif // ESP8266 - ESP32 } @@ -1905,7 +1905,7 @@ void HandleModuleConfiguration(void) } #else // ESP32 uint32_t ridx = pgm_read_word(kGpioNiceList + i) & 0xFFE0; - midx = ridx >> 5; + midx = BGPIO(ridx); if (!GetUsedInModule(midx, cmodule.io)) { WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, ridx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames)); } From 642f679a5dddea31207c2b13e338e199f6661ce2 Mon Sep 17 00:00:00 2001 From: Staars Date: Wed, 24 Jun 2020 16:19:37 +0200 Subject: [PATCH 339/581] remove library, because BEARSSL is so much smaller --- lib/mbedtls/README.md | 1 - lib/mbedtls/include/mbedtls/aes.h | 297 -- lib/mbedtls/include/mbedtls/ccm.h | 141 - lib/mbedtls/include/mbedtls/check_config.h | 628 ---- lib/mbedtls/include/mbedtls/cipher.h | 709 ----- lib/mbedtls/include/mbedtls/cipher_internal.h | 109 - lib/mbedtls/include/mbedtls/config.h | 2600 ----------------- lib/mbedtls/include/mbedtls/platform.h | 295 -- lib/mbedtls/include/mbedtls/platform_time.h | 81 - lib/mbedtls/src/aes.c | 1492 ---------- lib/mbedtls/src/ccm.c | 464 --- lib/mbedtls/src/cipher.c | 917 ------ lib/mbedtls/src/cipher_wrap.c | 1451 --------- 13 files changed, 9185 deletions(-) delete mode 100644 lib/mbedtls/README.md delete mode 100644 lib/mbedtls/include/mbedtls/aes.h delete mode 100644 lib/mbedtls/include/mbedtls/ccm.h delete mode 100644 lib/mbedtls/include/mbedtls/check_config.h delete mode 100644 lib/mbedtls/include/mbedtls/cipher.h delete mode 100644 lib/mbedtls/include/mbedtls/cipher_internal.h delete mode 100644 lib/mbedtls/include/mbedtls/config.h delete mode 100644 lib/mbedtls/include/mbedtls/platform.h delete mode 100644 lib/mbedtls/include/mbedtls/platform_time.h delete mode 100644 lib/mbedtls/src/aes.c delete mode 100644 lib/mbedtls/src/ccm.c delete mode 100644 lib/mbedtls/src/cipher.c delete mode 100644 lib/mbedtls/src/cipher_wrap.c diff --git a/lib/mbedtls/README.md b/lib/mbedtls/README.md deleted file mode 100644 index f5df7f0c8..000000000 --- a/lib/mbedtls/README.md +++ /dev/null @@ -1 +0,0 @@ -Stripped down library for aes-ccm-decryption in the MI_NRF24.ino. \ No newline at end of file diff --git a/lib/mbedtls/include/mbedtls/aes.h b/lib/mbedtls/include/mbedtls/aes.h deleted file mode 100644 index a36e825a2..000000000 --- a/lib/mbedtls/include/mbedtls/aes.h +++ /dev/null @@ -1,297 +0,0 @@ -/** - * \file aes.h - * - * \brief AES block cipher - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_AES_H -#define MBEDTLS_AES_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include -#include - -/* padlock.c and aesni.c rely on these values! */ -#define MBEDTLS_AES_ENCRYPT 1 -#define MBEDTLS_AES_DECRYPT 0 - -#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ -#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ - -#if !defined(MBEDTLS_AES_ALT) -// Regular implementation -// - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief AES context structure - * - * \note buf is able to hold 32 extra bytes, which can be used: - * - for alignment purposes if VIA padlock is used, and/or - * - to simplify key expansion in the 256-bit case by - * generating an extra round key - */ -typedef struct -{ - int nr; /*!< number of rounds */ - uint32_t *rk; /*!< AES round keys */ - uint32_t buf[68]; /*!< unaligned data */ -} -mbedtls_aes_context; - -/** - * \brief Initialize AES context - * - * \param ctx AES context to be initialized - */ -void mbedtls_aes_init( mbedtls_aes_context *ctx ); - -/** - * \brief Clear AES context - * - * \param ctx AES context to be cleared - */ -void mbedtls_aes_free( mbedtls_aes_context *ctx ); - -/** - * \brief AES key schedule (encryption) - * - * \param ctx AES context to be initialized - * \param key encryption key - * \param keybits must be 128, 192 or 256 - * - * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH - */ -int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ); - -/** - * \brief AES key schedule (decryption) - * - * \param ctx AES context to be initialized - * \param key decryption key - * \param keybits must be 128, 192 or 256 - * - * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH - */ -int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ); - -/** - * \brief AES-ECB block encryption/decryption - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param input 16-byte input block - * \param output 16-byte output block - * - * \return 0 if successful - */ -int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/** - * \brief AES-CBC buffer encryption/decryption - * Length should be a multiple of the block - * size (16 bytes) - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH - */ -int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/** - * \brief AES-CFB128 buffer encryption/decryption. - * - * Note: Due to the nature of CFB you should use the same key schedule for - * both encryption and decryption. So a context initialized with - * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param length length of the input data - * \param iv_off offset in IV (updated after use) - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if successful - */ -int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); - -/** - * \brief AES-CFB8 buffer encryption/decryption. - * - * Note: Due to the nature of CFB you should use the same key schedule for - * both encryption and decryption. So a context initialized with - * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. - * - * \note Upon exit, the content of the IV is updated so that you can - * call the function same function again on the following - * block(s) of data and get the same result as if it was - * encrypted in one call. This allows a "streaming" usage. - * If on the other hand you need to retain the contents of the - * IV, you should either save it manually or use the cipher - * module instead. - * - * \param ctx AES context - * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT - * \param length length of the input data - * \param iv initialization vector (updated after use) - * \param input buffer holding the input data - * \param output buffer holding the output data - * - * \return 0 if successful - */ -int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); -#endif /*MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/** - * \brief AES-CTR buffer encryption/decryption - * - * Warning: You have to keep the maximum use of your counter in mind! - * - * Note: Due to the nature of CTR you should use the same key schedule for - * both encryption and decryption. So a context initialized with - * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. - * - * \param ctx AES context - * \param length The length of the data - * \param nc_off The offset in the current stream_block (for resuming - * within current cipher stream). The offset pointer to - * should be 0 at the start of a stream. - * \param nonce_counter The 128-bit nonce and counter. - * \param stream_block The saved stream-block for resuming. Is overwritten - * by the function. - * \param input The input data stream - * \param output The output data stream - * - * \return 0 if successful - */ -int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -/** - * \brief Internal AES block encryption function - * (Only exposed to allow overriding it, - * see MBEDTLS_AES_ENCRYPT_ALT) - * - * \param ctx AES context - * \param input Plaintext block - * \param output Output (ciphertext) block - */ -void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -/** - * \brief Internal AES block decryption function - * (Only exposed to allow overriding it, - * see MBEDTLS_AES_DECRYPT_ALT) - * - * \param ctx AES context - * \param input Ciphertext block - * \param output Output (plaintext) block - */ -void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); - -#ifdef __cplusplus -} -#endif - -#else /* MBEDTLS_AES_ALT */ -#include "aes_alt.h" -#endif /* MBEDTLS_AES_ALT */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_aes_self_test( int verbose ); - -#ifdef __cplusplus -} -#endif - -#endif /* aes.h */ diff --git a/lib/mbedtls/include/mbedtls/ccm.h b/lib/mbedtls/include/mbedtls/ccm.h deleted file mode 100644 index ef75839ba..000000000 --- a/lib/mbedtls/include/mbedtls/ccm.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * \file ccm.h - * - * \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_CCM_H -#define MBEDTLS_CCM_H - -#include "cipher.h" - -#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief CCM context structure - */ -typedef struct { - mbedtls_cipher_context_t cipher_ctx; /*!< cipher context used */ -} -mbedtls_ccm_context; - -/** - * \brief Initialize CCM context (just makes references valid) - * Makes the context ready for mbedtls_ccm_setkey() or - * mbedtls_ccm_free(). - * - * \param ctx CCM context to initialize - */ -void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); - -/** - * \brief CCM initialization (encryption and decryption) - * - * \param ctx CCM context to be initialized - * \param cipher cipher to use (a 128-bit block cipher) - * \param key encryption key - * \param keybits key size in bits (must be acceptable by the cipher) - * - * \return 0 if successful, or a cipher specific error code - */ -int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ); - -/** - * \brief Free a CCM context and underlying cipher sub-context - * - * \param ctx CCM context to free - */ -void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); - -/** - * \brief CCM buffer encryption - * - * \param ctx CCM context - * \param length length of the input data in bytes - * \param iv nonce (initialization vector) - * \param iv_len length of IV in bytes - * must be 2, 3, 4, 5, 6, 7 or 8 - * \param add additional data - * \param add_len length of additional data in bytes - * must be less than 2^16 - 2^8 - * \param input buffer holding the input data - * \param output buffer for holding the output data - * must be at least 'length' bytes wide - * \param tag buffer for holding the tag - * \param tag_len length of the tag to generate in bytes - * must be 4, 6, 8, 10, 14 or 16 - * - * \note The tag is written to a separate buffer. To get the tag - * concatenated with the output as in the CCM spec, use - * tag = output + length and make sure the output buffer is - * at least length + tag_len wide. - * - * \return 0 if successful - */ -int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ); - -/** - * \brief CCM buffer authenticated decryption - * - * \param ctx CCM context - * \param length length of the input data - * \param iv initialization vector - * \param iv_len length of IV - * \param add additional data - * \param add_len length of additional data - * \param input buffer holding the input data - * \param output buffer for holding the output data - * \param tag buffer holding the tag - * \param tag_len length of the tag - * - * \return 0 if successful and authenticated, - * MBEDTLS_ERR_CCM_AUTH_FAILED if tag does not match - */ -int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len ); - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int mbedtls_ccm_self_test( int verbose ); -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CCM_H */ diff --git a/lib/mbedtls/include/mbedtls/check_config.h b/lib/mbedtls/include/mbedtls/check_config.h deleted file mode 100644 index fe86c1e8d..000000000 --- a/lib/mbedtls/include/mbedtls/check_config.h +++ /dev/null @@ -1,628 +0,0 @@ -/** - * \file check_config.h - * - * \brief Consistency checks for configuration options - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * It is recommended to include this file from your config.h - * in order to catch dependency issues early. - */ - -#ifndef MBEDTLS_CHECK_CONFIG_H -#define MBEDTLS_CHECK_CONFIG_H - -/* - * We assume CHAR_BIT is 8 in many places. In practice, this is true on our - * target platforms, so not an issue, but let's just be extra sure. - */ -#include -#if CHAR_BIT != 8 -#error "mbed TLS requires a platform with 8-bit chars" -#endif - -#if defined(_WIN32) -#if !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_C is required on Windows" -#endif - -/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as - * it would confuse config.pl. */ -#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \ - !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) -#define MBEDTLS_PLATFORM_SNPRINTF_ALT -#endif -#endif /* _WIN32 */ - -#if defined(TARGET_LIKE_MBED) && \ - ( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) ) -#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS" -#endif - -#if defined(MBEDTLS_DEPRECATED_WARNING) && \ - !defined(__GNUC__) && !defined(__clang__) -#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" -#endif - -#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME) -#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" -#endif - -#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_AESNI_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) -#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) -#error "MBEDTLS_DHM_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_CMAC_C) && \ - !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) -#error "MBEDTLS_CMAC_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) -#error "MBEDTLS_ECDH_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDSA_C) && \ - ( !defined(MBEDTLS_ECP_C) || \ - !defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_ASN1_WRITE_C) ) -#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECJPAKE_C) && \ - ( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) ) -#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) -#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ - !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ - !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) ) -#error "MBEDTLS_ECP_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \ - !defined(MBEDTLS_SHA256_C)) -#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites" -#endif -#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \ - defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64) -#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" -#endif -#if defined(MBEDTLS_ENTROPY_C) && \ - ( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \ - && defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32) -#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" -#endif -#if defined(MBEDTLS_ENTROPY_C) && \ - defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C) -#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ - ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) ) -#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites" -#endif -#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ - ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ - defined(MBEDTLS_HAVEGE_C) ) -#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too" -#endif - -#if defined(MBEDTLS_GCM_C) && ( \ - !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) ) -#error "MBEDTLS_GCM_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C) -#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) -#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C) -#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ - !defined(MBEDTLS_ECDH_C) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ - ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \ - !defined(MBEDTLS_X509_CRT_PARSE_C) ) -#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ - ( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \ - !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ) -#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM) -#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C) -#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C) -#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_C) && \ - ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) ) -#error "MBEDTLS_PK_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C) -#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C) -#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C) -#error "MBEDTLS_PKCS11_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\ - defined(MBEDTLS_PLATFORM_EXIT_ALT) ) -#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ - ( !defined(MBEDTLS_PLATFORM_C) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ - defined(MBEDTLS_PLATFORM_TIME_ALT) ) -#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ - defined(MBEDTLS_PLATFORM_TIME_ALT) ) -#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\ - defined(MBEDTLS_PLATFORM_FPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ - defined(MBEDTLS_PLATFORM_STD_FREE) -#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ - defined(MBEDTLS_PLATFORM_STD_CALLOC) -#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO) -#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is" -#endif - -#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\ - defined(MBEDTLS_PLATFORM_PRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) -#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ - defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) -#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ - !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) -#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY) -#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\ - !defined(MBEDTLS_PLATFORM_EXIT_ALT) -#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ - ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ - !defined(MBEDTLS_HAVE_TIME) ) -#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ - !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\ - !defined(MBEDTLS_PLATFORM_PRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\ - !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\ - ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) ) -#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\ - !defined(MBEDTLS_ENTROPY_NV_SEED) -#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\ - !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\ - !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\ - defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) -#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\ - ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\ - defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) -#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" -#endif - -#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) ) -#error "MBEDTLS_RSA_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \ - !defined(MBEDTLS_PKCS1_V15) ) -#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled" -#endif - -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ - ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) -#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \ - !defined(MBEDTLS_SHA1_C) ) -#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \ - !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) ) -#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C) -#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \ - !defined(MBEDTLS_MD_C) ) -#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C) -#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2)) -#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1)) -#error "Illegal protocol selection" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1)) -#error "Illegal protocol selection" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ - defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1))) -#error "Illegal protocol selection" -#endif - -#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS) -#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ - !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) -#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ - ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ - ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) -#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites" -#endif - -#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ - !defined(MBEDTLS_SSL_PROTO_TLS1_2) -#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites" -#endif - -#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C) -#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \ - !defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1) -#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ - !defined(MBEDTLS_X509_CRT_PARSE_C) -#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_THREADING_PTHREAD) -#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" -#endif -#define MBEDTLS_THREADING_IMPL -#endif - -#if defined(MBEDTLS_THREADING_ALT) -#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" -#endif -#define MBEDTLS_THREADING_IMPL -#endif - -#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL) -#error "MBEDTLS_THREADING_C defined, single threading implementation required" -#endif -#undef MBEDTLS_THREADING_IMPL - -#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C) -#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ - !defined(MBEDTLS_PK_PARSE_C) ) -#error "MBEDTLS_X509_USE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ - !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \ - !defined(MBEDTLS_PK_WRITE_C) ) -#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) -#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) -#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites" -#endif - -#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) -#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" -#endif - -/* - * Avoid warning from -pedantic. This is a convenient place for this - * workaround since this is included by every single file before the - * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units. - */ -typedef int mbedtls_iso_c_forbids_empty_translation_units; - -#endif /* MBEDTLS_CHECK_CONFIG_H */ diff --git a/lib/mbedtls/include/mbedtls/cipher.h b/lib/mbedtls/include/mbedtls/cipher.h deleted file mode 100644 index b12e38843..000000000 --- a/lib/mbedtls/include/mbedtls/cipher.h +++ /dev/null @@ -1,709 +0,0 @@ -/** - * \file cipher.h - * - * \brief Generic cipher wrapper. - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_CIPHER_H -#define MBEDTLS_CIPHER_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include - -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) -#define MBEDTLS_CIPHER_MODE_AEAD -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -#define MBEDTLS_CIPHER_MODE_WITH_PADDING -#endif - -#if defined(MBEDTLS_ARC4_C) -#define MBEDTLS_CIPHER_MODE_STREAM -#endif - -#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ - !defined(inline) && !defined(__cplusplus) -#define inline __inline -#endif - -#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */ -#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters to function. */ -#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */ -#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ -#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ -#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ -#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid, eg because it was free()ed. */ - -#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */ -#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - MBEDTLS_CIPHER_ID_NONE = 0, - MBEDTLS_CIPHER_ID_NULL, - MBEDTLS_CIPHER_ID_AES, - MBEDTLS_CIPHER_ID_DES, - MBEDTLS_CIPHER_ID_3DES, - MBEDTLS_CIPHER_ID_CAMELLIA, - MBEDTLS_CIPHER_ID_BLOWFISH, - MBEDTLS_CIPHER_ID_ARC4, -} mbedtls_cipher_id_t; - -typedef enum { - MBEDTLS_CIPHER_NONE = 0, - MBEDTLS_CIPHER_NULL, - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_CIPHER_AES_128_CBC, - MBEDTLS_CIPHER_AES_192_CBC, - MBEDTLS_CIPHER_AES_256_CBC, - MBEDTLS_CIPHER_AES_128_CFB128, - MBEDTLS_CIPHER_AES_192_CFB128, - MBEDTLS_CIPHER_AES_256_CFB128, - MBEDTLS_CIPHER_AES_128_CTR, - MBEDTLS_CIPHER_AES_192_CTR, - MBEDTLS_CIPHER_AES_256_CTR, - MBEDTLS_CIPHER_AES_128_GCM, - MBEDTLS_CIPHER_AES_192_GCM, - MBEDTLS_CIPHER_AES_256_GCM, - MBEDTLS_CIPHER_CAMELLIA_128_ECB, - MBEDTLS_CIPHER_CAMELLIA_192_ECB, - MBEDTLS_CIPHER_CAMELLIA_256_ECB, - MBEDTLS_CIPHER_CAMELLIA_128_CBC, - MBEDTLS_CIPHER_CAMELLIA_192_CBC, - MBEDTLS_CIPHER_CAMELLIA_256_CBC, - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, - MBEDTLS_CIPHER_CAMELLIA_128_CTR, - MBEDTLS_CIPHER_CAMELLIA_192_CTR, - MBEDTLS_CIPHER_CAMELLIA_256_CTR, - MBEDTLS_CIPHER_CAMELLIA_128_GCM, - MBEDTLS_CIPHER_CAMELLIA_192_GCM, - MBEDTLS_CIPHER_CAMELLIA_256_GCM, - MBEDTLS_CIPHER_DES_ECB, - MBEDTLS_CIPHER_DES_CBC, - MBEDTLS_CIPHER_DES_EDE_ECB, - MBEDTLS_CIPHER_DES_EDE_CBC, - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_CIPHER_DES_EDE3_CBC, - MBEDTLS_CIPHER_BLOWFISH_ECB, - MBEDTLS_CIPHER_BLOWFISH_CBC, - MBEDTLS_CIPHER_BLOWFISH_CFB64, - MBEDTLS_CIPHER_BLOWFISH_CTR, - MBEDTLS_CIPHER_ARC4_128, - MBEDTLS_CIPHER_AES_128_CCM, - MBEDTLS_CIPHER_AES_192_CCM, - MBEDTLS_CIPHER_AES_256_CCM, - MBEDTLS_CIPHER_CAMELLIA_128_CCM, - MBEDTLS_CIPHER_CAMELLIA_192_CCM, - MBEDTLS_CIPHER_CAMELLIA_256_CCM, -} mbedtls_cipher_type_t; - -typedef enum { - MBEDTLS_MODE_NONE = 0, - MBEDTLS_MODE_ECB, - MBEDTLS_MODE_CBC, - MBEDTLS_MODE_CFB, - MBEDTLS_MODE_OFB, /* Unused! */ - MBEDTLS_MODE_CTR, - MBEDTLS_MODE_GCM, - MBEDTLS_MODE_STREAM, - MBEDTLS_MODE_CCM, -} mbedtls_cipher_mode_t; - -typedef enum { - MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default) */ - MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding */ - MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding */ - MBEDTLS_PADDING_ZEROS, /**< zero padding (not reversible!) */ - MBEDTLS_PADDING_NONE, /**< never pad (full blocks only) */ -} mbedtls_cipher_padding_t; - -typedef enum { - MBEDTLS_OPERATION_NONE = -1, - MBEDTLS_DECRYPT = 0, - MBEDTLS_ENCRYPT, -} mbedtls_operation_t; - -enum { - /** Undefined key length */ - MBEDTLS_KEY_LENGTH_NONE = 0, - /** Key length, in bits (including parity), for DES keys */ - MBEDTLS_KEY_LENGTH_DES = 64, - /** Key length, in bits (including parity), for DES in two key EDE */ - MBEDTLS_KEY_LENGTH_DES_EDE = 128, - /** Key length, in bits (including parity), for DES in three-key EDE */ - MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, -}; - -/** Maximum length of any IV, in bytes */ -#define MBEDTLS_MAX_IV_LENGTH 16 -/** Maximum block size of any cipher, in bytes */ -#define MBEDTLS_MAX_BLOCK_LENGTH 16 - -/** - * Base cipher information (opaque struct). - */ -typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; - -/** - * CMAC context (opaque struct). - */ -typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; - -/** - * Cipher information. Allows cipher functions to be called in a generic way. - */ -typedef struct { - /** Full cipher identifier (e.g. MBEDTLS_CIPHER_AES_256_CBC) */ - mbedtls_cipher_type_t type; - - /** Cipher mode (e.g. MBEDTLS_MODE_CBC) */ - mbedtls_cipher_mode_t mode; - - /** Cipher key length, in bits (default length for variable sized ciphers) - * (Includes parity bits for ciphers like DES) */ - unsigned int key_bitlen; - - /** Name of the cipher */ - const char * name; - - /** IV/NONCE size, in bytes. - * For cipher that accept many sizes: recommended size */ - unsigned int iv_size; - - /** Flags for variable IV size, variable key size, etc. */ - int flags; - - /** block size, in bytes */ - unsigned int block_size; - - /** Base cipher information and functions */ - const mbedtls_cipher_base_t *base; - -} mbedtls_cipher_info_t; - -/** - * Generic cipher context. - */ -typedef struct { - /** Information about the associated cipher */ - const mbedtls_cipher_info_t *cipher_info; - - /** Key length to use */ - int key_bitlen; - - /** Operation that the context's key has been initialised for */ - mbedtls_operation_t operation; - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - /** Padding functions to use, if relevant for cipher mode */ - void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); - int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); -#endif - - /** Buffer for data that hasn't been encrypted yet */ - unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; - - /** Number of bytes that still need processing */ - size_t unprocessed_len; - - /** Current IV or NONCE_COUNTER for CTR-mode */ - unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; - - /** IV size in bytes (for ciphers with variable-length IVs) */ - size_t iv_size; - - /** Cipher-specific context */ - void *cipher_ctx; - -#if defined(MBEDTLS_CMAC_C) - /** CMAC Specific context */ - mbedtls_cmac_context_t *cmac_ctx; -#endif -} mbedtls_cipher_context_t; - -/** - * \brief Returns the list of ciphers supported by the generic cipher module. - * - * \return a statically allocated array of ciphers, the last entry - * is 0. - */ -const int *mbedtls_cipher_list( void ); - -/** - * \brief Returns the cipher information structure associated - * with the given cipher name. - * - * \param cipher_name Name of the cipher to search for. - * - * \return the cipher information structure associated with the - * given cipher_name, or NULL if not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ); - -/** - * \brief Returns the cipher information structure associated - * with the given cipher type. - * - * \param cipher_type Type of the cipher to search for. - * - * \return the cipher information structure associated with the - * given cipher_type, or NULL if not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ); - -/** - * \brief Returns the cipher information structure associated - * with the given cipher id, key size and mode. - * - * \param cipher_id Id of the cipher to search for - * (e.g. MBEDTLS_CIPHER_ID_AES) - * \param key_bitlen Length of the key in bits - * \param mode Cipher mode (e.g. MBEDTLS_MODE_CBC) - * - * \return the cipher information structure associated with the - * given cipher_type, or NULL if not found. - */ -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, - int key_bitlen, - const mbedtls_cipher_mode_t mode ); - -/** - * \brief Initialize a cipher_context (as NONE) - */ -void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); - -/** - * \brief Free and clear the cipher-specific context of ctx. - * Freeing ctx itself remains the responsibility of the - * caller. - */ -void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); - -/** - * \brief Initialises and fills the cipher context structure with - * the appropriate values. - * - * \note Currently also clears structure. In future versions you - * will be required to call mbedtls_cipher_init() on the structure - * first. - * - * \param ctx context to initialise. May not be NULL. - * \param cipher_info cipher to use. - * - * \return 0 on success, - * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure, - * MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the - * cipher-specific context failed. - */ -int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ); - -/** - * \brief Returns the block size of the given cipher. - * - * \param ctx cipher's context. Must have been initialised. - * - * \return size of the cipher's blocks, or 0 if ctx has not been - * initialised. - */ -static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return 0; - - return ctx->cipher_info->block_size; -} - -/** - * \brief Returns the mode of operation for the cipher. - * (e.g. MBEDTLS_MODE_CBC) - * - * \param ctx cipher's context. Must have been initialised. - * - * \return mode of operation, or MBEDTLS_MODE_NONE if ctx - * has not been initialised. - */ -static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return MBEDTLS_MODE_NONE; - - return ctx->cipher_info->mode; -} - -/** - * \brief Returns the size of the cipher's IV/NONCE in bytes. - * - * \param ctx cipher's context. Must have been initialised. - * - * \return If IV has not been set yet: (recommended) IV size - * (0 for ciphers not using IV/NONCE). - * If IV has already been set: actual size. - */ -static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return 0; - - if( ctx->iv_size != 0 ) - return (int) ctx->iv_size; - - return (int) ctx->cipher_info->iv_size; -} - -/** - * \brief Returns the type of the given cipher. - * - * \param ctx cipher's context. Must have been initialised. - * - * \return type of the cipher, or MBEDTLS_CIPHER_NONE if ctx has - * not been initialised. - */ -static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return MBEDTLS_CIPHER_NONE; - - return ctx->cipher_info->type; -} - -/** - * \brief Returns the name of the given cipher, as a string. - * - * \param ctx cipher's context. Must have been initialised. - * - * \return name of the cipher, or NULL if ctx was not initialised. - */ -static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return 0; - - return ctx->cipher_info->name; -} - -/** - * \brief Returns the key length of the cipher. - * - * \param ctx cipher's context. Must have been initialised. - * - * \return cipher's key length, in bits, or - * MBEDTLS_KEY_LENGTH_NONE if ctx has not been - * initialised. - */ -static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return MBEDTLS_KEY_LENGTH_NONE; - - return (int) ctx->cipher_info->key_bitlen; -} - -/** - * \brief Returns the operation of the given cipher. - * - * \param ctx cipher's context. Must have been initialised. - * - * \return operation (MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT), - * or MBEDTLS_OPERATION_NONE if ctx has not been - * initialised. - */ -static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return MBEDTLS_OPERATION_NONE; - - return ctx->operation; -} - -/** - * \brief Set the key to use with the given context. - * - * \param ctx generic cipher context. May not be NULL. Must have been - * initialised using cipher_context_from_type or - * cipher_context_from_string. - * \param key The key to use. - * \param key_bitlen key length to use, in bits. - * \param operation Operation that the key will be used for, either - * MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT. - * - * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if - * parameter verification fails or a cipher specific - * error code. - */ -int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, - int key_bitlen, const mbedtls_operation_t operation ); - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -/** - * \brief Set padding mode, for cipher modes that use padding. - * (Default: PKCS7 padding.) - * - * \param ctx generic cipher context - * \param mode padding mode - * - * \returns 0 on success, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE - * if selected padding mode is not supported, or - * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode - * does not support padding. - */ -int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ); -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -/** - * \brief Set the initialization vector (IV) or nonce - * - * \param ctx generic cipher context - * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) - * \param iv_len IV length for ciphers with variable-size IV; - * discarded by ciphers with fixed-size IV. - * - * \returns 0 on success, or MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA - * - * \note Some ciphers don't use IVs nor NONCE. For these - * ciphers, this function has no effect. - */ -int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len ); - -/** - * \brief Finish preparation of the given context - * - * \param ctx generic cipher context - * - * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA - * if parameter verification fails. - */ -int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); - -#if defined(MBEDTLS_GCM_C) -/** - * \brief Add additional data (for AEAD ciphers). - * Currently only supported with GCM. - * Must be called exactly once, after mbedtls_cipher_reset(). - * - * \param ctx generic cipher context - * \param ad Additional data to use. - * \param ad_len Length of ad. - * - * \return 0 on success, or a specific error code. - */ -int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, - const unsigned char *ad, size_t ad_len ); -#endif /* MBEDTLS_GCM_C */ - -/** - * \brief Generic cipher update function. Encrypts/decrypts - * using the given cipher context. Writes as many block - * size'd blocks of data as possible to output. Any data - * that cannot be written immediately will either be added - * to the next block, or flushed when cipher_final is - * called. - * Exception: for MBEDTLS_MODE_ECB, expects single block - * in size (e.g. 16 bytes for AES) - * - * \param ctx generic cipher context - * \param input buffer holding the input data - * \param ilen length of the input data - * \param output buffer for the output data. Should be able to hold at - * least ilen + block_size. Cannot be the same buffer as - * input! - * \param olen length of the output data, will be filled with the - * actual number of bytes written. - * - * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if - * parameter verification fails, - * MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an - * unsupported mode for a cipher or a cipher specific - * error code. - * - * \note If the underlying cipher is GCM, all calls to this - * function, except the last one before mbedtls_cipher_finish(), - * must have ilen a multiple of the block size. - */ -int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, - size_t ilen, unsigned char *output, size_t *olen ); - -/** - * \brief Generic cipher finalisation function. If data still - * needs to be flushed from an incomplete block, data - * contained within it will be padded with the size of - * the last block, and written to the output buffer. - * - * \param ctx Generic cipher context - * \param output buffer to write data to. Needs block_size available. - * \param olen length of the data written to the output buffer. - * - * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if - * parameter verification fails, - * MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption - * expected a full block but was not provided one, - * MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting or a cipher specific error code. - */ -int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen ); - -#if defined(MBEDTLS_GCM_C) -/** - * \brief Write tag for AEAD ciphers. - * Currently only supported with GCM. - * Must be called after mbedtls_cipher_finish(). - * - * \param ctx Generic cipher context - * \param tag buffer to write the tag - * \param tag_len Length of the tag to write - * - * \return 0 on success, or a specific error code. - */ -int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, - unsigned char *tag, size_t tag_len ); - -/** - * \brief Check tag for AEAD ciphers. - * Currently only supported with GCM. - * Must be called after mbedtls_cipher_finish(). - * - * \param ctx Generic cipher context - * \param tag Buffer holding the tag - * \param tag_len Length of the tag to check - * - * \return 0 on success, or a specific error code. - */ -int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, - const unsigned char *tag, size_t tag_len ); -#endif /* MBEDTLS_GCM_C */ - -/** - * \brief Generic all-in-one encryption/decryption - * (for all ciphers except AEAD constructs). - * - * \param ctx generic cipher context - * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) - * \param iv_len IV length for ciphers with variable-size IV; - * discarded by ciphers with fixed-size IV. - * \param input buffer holding the input data - * \param ilen length of the input data - * \param output buffer for the output data. Should be able to hold at - * least ilen + block_size. Cannot be the same buffer as - * input! - * \param olen length of the output data, will be filled with the - * actual number of bytes written. - * - * \note Some ciphers don't use IVs nor NONCE. For these - * ciphers, use iv = NULL and iv_len = 0. - * - * \returns 0 on success, or - * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or - * MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption - * expected a full block but was not provided one, or - * MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding - * while decrypting, or - * a cipher specific error code. - */ -int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen ); - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) -/** - * \brief Generic autenticated encryption (AEAD ciphers). - * - * \param ctx generic cipher context - * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) - * \param iv_len IV length for ciphers with variable-size IV; - * discarded by ciphers with fixed-size IV. - * \param ad Additional data to authenticate. - * \param ad_len Length of ad. - * \param input buffer holding the input data - * \param ilen length of the input data - * \param output buffer for the output data. - * Should be able to hold at least ilen. - * \param olen length of the output data, will be filled with the - * actual number of bytes written. - * \param tag buffer for the authentication tag - * \param tag_len desired tag length - * - * \returns 0 on success, or - * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or - * a cipher specific error code. - */ -int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - unsigned char *tag, size_t tag_len ); - -/** - * \brief Generic autenticated decryption (AEAD ciphers). - * - * \param ctx generic cipher context - * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) - * \param iv_len IV length for ciphers with variable-size IV; - * discarded by ciphers with fixed-size IV. - * \param ad Additional data to be authenticated. - * \param ad_len Length of ad. - * \param input buffer holding the input data - * \param ilen length of the input data - * \param output buffer for the output data. - * Should be able to hold at least ilen. - * \param olen length of the output data, will be filled with the - * actual number of bytes written. - * \param tag buffer holding the authentication tag - * \param tag_len length of the authentication tag - * - * \returns 0 on success, or - * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or - * MBEDTLS_ERR_CIPHER_AUTH_FAILED if data isn't authentic, - * or a cipher specific error code. - * - * \note If the data is not authentic, then the output buffer - * is zeroed out to prevent the unauthentic plaintext to - * be used by mistake, making this interface safer. - */ -int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - const unsigned char *tag, size_t tag_len ); -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CIPHER_H */ diff --git a/lib/mbedtls/include/mbedtls/cipher_internal.h b/lib/mbedtls/include/mbedtls/cipher_internal.h deleted file mode 100644 index 6c58bcc52..000000000 --- a/lib/mbedtls/include/mbedtls/cipher_internal.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * \file cipher_internal.h - * - * \brief Cipher wrappers. - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_CIPHER_WRAP_H -#define MBEDTLS_CIPHER_WRAP_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "cipher.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Base cipher information. The non-mode specific functions and values. - */ -struct mbedtls_cipher_base_t -{ - /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ - mbedtls_cipher_id_t cipher; - - /** Encrypt using ECB */ - int (*ecb_func)( void *ctx, mbedtls_operation_t mode, - const unsigned char *input, unsigned char *output ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /** Encrypt using CBC */ - int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length, - unsigned char *iv, const unsigned char *input, - unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - /** Encrypt using CFB (Full length) */ - int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, - unsigned char *iv, const unsigned char *input, - unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /** Encrypt using CTR */ - int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ); -#endif - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - /** Encrypt using STREAM */ - int (*stream_func)( void *ctx, size_t length, - const unsigned char *input, unsigned char *output ); -#endif - - /** Set key for encryption purposes */ - int (*setkey_enc_func)( void *ctx, const unsigned char *key, - unsigned int key_bitlen ); - - /** Set key for decryption purposes */ - int (*setkey_dec_func)( void *ctx, const unsigned char *key, - unsigned int key_bitlen); - - /** Allocate a new context */ - void * (*ctx_alloc_func)( void ); - - /** Free the given context */ - void (*ctx_free_func)( void *ctx ); - -}; - -typedef struct -{ - mbedtls_cipher_type_t type; - const mbedtls_cipher_info_t *info; -} mbedtls_cipher_definition_t; - -extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; - -extern int mbedtls_cipher_supported[]; - -#ifdef __cplusplus -} -#endif - -#endif /* MBEDTLS_CIPHER_WRAP_H */ diff --git a/lib/mbedtls/include/mbedtls/config.h b/lib/mbedtls/include/mbedtls/config.h deleted file mode 100644 index 0a3e1bb44..000000000 --- a/lib/mbedtls/include/mbedtls/config.h +++ /dev/null @@ -1,2600 +0,0 @@ -/** - * \file config.h - * - * \brief Configuration options (set of defines) - * - * This set of compile-time options may be used to enable - * or disable features selectively, and reduce the global - * memory footprint. - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#ifndef MBEDTLS_CONFIG_H -#define MBEDTLS_CONFIG_H - -#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - -/** - * \name SECTION: System support - * - * This section sets system specific settings. - * \{ - */ - -/** - * \def MBEDTLS_HAVE_ASM - * - * The compiler has support for asm(). - * - * Requires support for asm() in compiler. - * - * Used in: - * library/timing.c - * library/padlock.c - * include/mbedtls/bn_mul.h - * - * Comment to disable the use of assembly code. - */ -#define MBEDTLS_HAVE_ASM - -/** - * \def MBEDTLS_HAVE_SSE2 - * - * CPU supports SSE2 instruction set. - * - * Uncomment if the CPU supports SSE2 (IA-32 specific). - */ -//#define MBEDTLS_HAVE_SSE2 - -/** - * \def MBEDTLS_HAVE_TIME - * - * System has time.h and time(). - * The time does not need to be correct, only time differences are used, - * by contrast with MBEDTLS_HAVE_TIME_DATE - * - * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, - * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and - * MBEDTLS_PLATFORM_STD_TIME. - * - * Comment if your system does not support time functions - */ -// #define MBEDTLS_HAVE_TIME - -/** - * \def MBEDTLS_HAVE_TIME_DATE - * - * System has time.h and time(), gmtime() and the clock is correct. - * The time needs to be correct (not necesarily very accurate, but at least - * the date should be correct). This is used to verify the validity period of - * X.509 certificates. - * - * Comment if your system does not have a correct clock. - */ -// #define MBEDTLS_HAVE_TIME_DATE - -/** - * \def MBEDTLS_PLATFORM_MEMORY - * - * Enable the memory allocation layer. - * - * By default mbed TLS uses the system-provided calloc() and free(). - * This allows different allocators (self-implemented or provided) to be - * provided to the platform abstraction layer. - * - * Enabling MBEDTLS_PLATFORM_MEMORY without the - * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide - * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and - * free() function pointer at runtime. - * - * Enabling MBEDTLS_PLATFORM_MEMORY and specifying - * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the - * alternate function at compile time. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Enable this layer to allow use of alternative memory allocators. - */ -//#define MBEDTLS_PLATFORM_MEMORY - -/** - * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - * - * Do not assign standard functions in the platform layer (e.g. calloc() to - * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) - * - * This makes sure there are no linking errors on platforms that do not support - * these functions. You will HAVE to provide alternatives, either at runtime - * via the platform_set_xxx() functions or at compile time by setting - * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a - * MBEDTLS_PLATFORM_XXX_MACRO. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Uncomment to prevent default assignment of standard functions in the - * platform layer. - */ -//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - -/** - * \def MBEDTLS_PLATFORM_EXIT_ALT - * - * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the - * function in the platform abstraction layer. - * - * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will - * provide a function "mbedtls_platform_set_printf()" that allows you to set an - * alternative printf function pointer. - * - * All these define require MBEDTLS_PLATFORM_C to be defined! - * - * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; - * it will be enabled automatically by check_config.h - * - * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as - * MBEDTLS_PLATFORM_XXX_MACRO! - * - * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME - * - * Uncomment a macro to enable alternate implementation of specific base - * platform function - */ -//#define MBEDTLS_PLATFORM_EXIT_ALT -//#define MBEDTLS_PLATFORM_TIME_ALT -//#define MBEDTLS_PLATFORM_FPRINTF_ALT -//#define MBEDTLS_PLATFORM_PRINTF_ALT -//#define MBEDTLS_PLATFORM_SNPRINTF_ALT -//#define MBEDTLS_PLATFORM_NV_SEED_ALT - -/** - * \def MBEDTLS_DEPRECATED_WARNING - * - * Mark deprecated functions so that they generate a warning if used. - * Functions deprecated in one version will usually be removed in the next - * version. You can enable this to help you prepare the transition to a new - * major version by making sure your code is not using these functions. - * - * This only works with GCC and Clang. With other compilers, you may want to - * use MBEDTLS_DEPRECATED_REMOVED - * - * Uncomment to get warnings on using deprecated functions. - */ -//#define MBEDTLS_DEPRECATED_WARNING - -/** - * \def MBEDTLS_DEPRECATED_REMOVED - * - * Remove deprecated functions so that they generate an error if used. - * Functions deprecated in one version will usually be removed in the next - * version. You can enable this to help you prepare the transition to a new - * major version by making sure your code is not using these functions. - * - * Uncomment to get errors on using deprecated functions. - */ -//#define MBEDTLS_DEPRECATED_REMOVED - -/* \} name SECTION: System support */ - -/** - * \name SECTION: mbed TLS feature support - * - * This section sets support for features that are or are not needed - * within the modules that are enabled. - * \{ - */ - -/** - * \def MBEDTLS_TIMING_ALT - * - * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), - * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() - * - * Only works if you have MBEDTLS_TIMING_C enabled. - * - * You will need to provide a header "timing_alt.h" and an implementation at - * compile time. - */ -//#define MBEDTLS_TIMING_ALT - -/** - * \def MBEDTLS_AES_ALT - * - * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your - * alternate core implementation of a symmetric crypto or hash module (e.g. - * platform specific assembly optimized implementations). Keep in mind that - * the function prototypes should remain the same. - * - * This replaces the whole module. If you only want to replace one of the - * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer - * provide the "struct mbedtls_aes_context" definition and omit the base function - * declarations and implementations. "aes_alt.h" will be included from - * "aes.h" to include the new function definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * module. - */ -//#define MBEDTLS_AES_ALT -//#define MBEDTLS_ARC4_ALT -//#define MBEDTLS_BLOWFISH_ALT -//#define MBEDTLS_CAMELLIA_ALT -//#define MBEDTLS_DES_ALT -//#define MBEDTLS_XTEA_ALT -//#define MBEDTLS_MD2_ALT -//#define MBEDTLS_MD4_ALT -//#define MBEDTLS_MD5_ALT -//#define MBEDTLS_RIPEMD160_ALT -//#define MBEDTLS_SHA1_ALT -//#define MBEDTLS_SHA256_ALT -//#define MBEDTLS_SHA512_ALT - -/** - * \def MBEDTLS_MD2_PROCESS_ALT - * - * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you - * alternate core implementation of symmetric crypto or hash function. Keep in - * mind that function prototypes should remain the same. - * - * This replaces only one function. The header file from mbed TLS is still - * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will - * no longer provide the mbedtls_sha1_process() function, but it will still provide - * the other function (using your mbedtls_sha1_process() function) and the definition - * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible - * with this definition. - * - * Note: if you use the AES_xxx_ALT macros, then is is recommended to also set - * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES - * tables. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - */ -//#define MBEDTLS_MD2_PROCESS_ALT -//#define MBEDTLS_MD4_PROCESS_ALT -//#define MBEDTLS_MD5_PROCESS_ALT -//#define MBEDTLS_RIPEMD160_PROCESS_ALT -//#define MBEDTLS_SHA1_PROCESS_ALT -//#define MBEDTLS_SHA256_PROCESS_ALT -//#define MBEDTLS_SHA512_PROCESS_ALT -//#define MBEDTLS_DES_SETKEY_ALT -//#define MBEDTLS_DES_CRYPT_ECB_ALT -//#define MBEDTLS_DES3_CRYPT_ECB_ALT -//#define MBEDTLS_AES_SETKEY_ENC_ALT -//#define MBEDTLS_AES_SETKEY_DEC_ALT -//#define MBEDTLS_AES_ENCRYPT_ALT -//#define MBEDTLS_AES_DECRYPT_ALT - -/** - * \def MBEDTLS_TEST_NULL_ENTROPY - * - * Enables testing and use of mbed TLS without any configured entropy sources. - * This permits use of the library on platforms before an entropy source has - * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the - * MBEDTLS_ENTROPY_NV_SEED switches). - * - * WARNING! This switch MUST be disabled in production builds, and is suitable - * only for development. - * Enabling the switch negates any security provided by the library. - * - * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - */ -//#define MBEDTLS_TEST_NULL_ENTROPY - -/** - * \def MBEDTLS_ENTROPY_HARDWARE_ALT - * - * Uncomment this macro to let mbed TLS use your own implementation of a - * hardware entropy collector. - * - * Your function must be called \c mbedtls_hardware_poll(), have the same - * prototype as declared in entropy_poll.h, and accept NULL as first argument. - * - * Uncomment to use your own hardware entropy collector. - */ -//#define MBEDTLS_ENTROPY_HARDWARE_ALT - -/** - * \def MBEDTLS_AES_ROM_TABLES - * - * Store the AES tables in ROM. - * - * Uncomment this macro to store the AES tables in ROM. - */ -//#define MBEDTLS_AES_ROM_TABLES - -/** - * \def MBEDTLS_CAMELLIA_SMALL_MEMORY - * - * Use less ROM for the Camellia implementation (saves about 768 bytes). - * - * Uncomment this macro to use less memory for Camellia. - */ -//#define MBEDTLS_CAMELLIA_SMALL_MEMORY - -/** - * \def MBEDTLS_CIPHER_MODE_CBC - * - * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. - */ -// #define MBEDTLS_CIPHER_MODE_CBC - -/** - * \def MBEDTLS_CIPHER_MODE_CFB - * - * Enable Cipher Feedback mode (CFB) for symmetric ciphers. - */ -// #define MBEDTLS_CIPHER_MODE_CFB - -/** - * \def MBEDTLS_CIPHER_MODE_CTR - * - * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CTR - -/** - * \def MBEDTLS_CIPHER_NULL_CIPHER - * - * Enable NULL cipher. - * Warning: Only do so when you know what you are doing. This allows for - * encryption or channels without any security! - * - * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable - * the following ciphersuites: - * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA - * - * Uncomment this macro to enable the NULL cipher and ciphersuites - */ -//#define MBEDTLS_CIPHER_NULL_CIPHER - -/** - * \def MBEDTLS_CIPHER_PADDING_PKCS7 - * - * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for - * specific padding modes in the cipher layer with cipher modes that support - * padding (e.g. CBC) - * - * If you disable all padding modes, only full blocks can be used with CBC. - * - * Enable padding modes in the cipher layer. - */ -#define MBEDTLS_CIPHER_PADDING_PKCS7 -#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#define MBEDTLS_CIPHER_PADDING_ZEROS - -/** - * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES - * - * Enable weak ciphersuites in SSL / TLS. - * Warning: Only do so when you know what you are doing. This allows for - * channels with virtually no security at all! - * - * This enables the following ciphersuites: - * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA - * - * Uncomment this macro to enable weak ciphersuites - */ -//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES - -/** - * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES - * - * Remove RC4 ciphersuites by default in SSL / TLS. - * This flag removes the ciphersuites based on RC4 from the default list as - * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to - * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them - * explicitly. - * - * Uncomment this macro to remove RC4 ciphersuites by default. - */ -#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES - -/** - * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED - * - * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve - * module. By default all supported curves are enabled. - * - * Comment macros to disable the curve and functions for it - */ -// #define MBEDTLS_ECP_DP_SECP192R1_ENABLED -// #define MBEDTLS_ECP_DP_SECP224R1_ENABLED -// #define MBEDTLS_ECP_DP_SECP256R1_ENABLED -// #define MBEDTLS_ECP_DP_SECP384R1_ENABLED -// #define MBEDTLS_ECP_DP_SECP521R1_ENABLED -// #define MBEDTLS_ECP_DP_SECP192K1_ENABLED -// #define MBEDTLS_ECP_DP_SECP224K1_ENABLED -// #define MBEDTLS_ECP_DP_SECP256K1_ENABLED -// #define MBEDTLS_ECP_DP_BP256R1_ENABLED -// #define MBEDTLS_ECP_DP_BP384R1_ENABLED -// #define MBEDTLS_ECP_DP_BP512R1_ENABLED -// #define MBEDTLS_ECP_DP_CURVE25519_ENABLED - -/** - * \def MBEDTLS_ECP_NIST_OPTIM - * - * Enable specific 'modulo p' routines for each NIST prime. - * Depending on the prime and architecture, makes operations 4 to 8 times - * faster on the corresponding curve. - * - * Comment this macro to disable NIST curves optimisation. - */ -// #define MBEDTLS_ECP_NIST_OPTIM - -/** - * \def MBEDTLS_ECDSA_DETERMINISTIC - * - * Enable deterministic ECDSA (RFC 6979). - * Standard ECDSA is "fragile" in the sense that lack of entropy when signing - * may result in a compromise of the long-term signing key. This is avoided by - * the deterministic variant. - * - * Requires: MBEDTLS_HMAC_DRBG_C - * - * Comment this macro to disable deterministic ECDSA. - */ -// #define MBEDTLS_ECDSA_DETERMINISTIC - -/** - * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - * - * Enable the PSK based ciphersuite modes in SSL / TLS. - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA - */ -// #define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - * - * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA - */ -// #define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - * - * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA - */ -// #define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - * - * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA - */ -// #define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - * - * Enable the RSA-only based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 - */ -// #define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - * - * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - */ -// #define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - * - * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA - */ -// #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - * - * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - */ -// #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - * - * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -// #define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - * - * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -// #define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - * - * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Requires: MBEDTLS_ECJPAKE_C - * MBEDTLS_SHA256_C - * MBEDTLS_ECP_DP_SECP256R1_ENABLED - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 - */ -//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - -/** - * \def MBEDTLS_PK_PARSE_EC_EXTENDED - * - * Enhance support for reading EC keys using variants of SEC1 not allowed by - * RFC 5915 and RFC 5480. - * - * Currently this means parsing the SpecifiedECDomain choice of EC - * parameters (only known groups are supported, not arbitrary domains, to - * avoid validation issues). - * - * Disable if you only need to support RFC 5915 + 5480 key formats. - */ -// #define MBEDTLS_PK_PARSE_EC_EXTENDED - -/** - * \def MBEDTLS_ERROR_STRERROR_DUMMY - * - * Enable a dummy error function to make use of mbedtls_strerror() in - * third party libraries easier when MBEDTLS_ERROR_C is disabled - * (no effect when MBEDTLS_ERROR_C is enabled). - * - * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're - * not using mbedtls_strerror() or error_strerror() in your application. - * - * Disable if you run into name conflicts and want to really remove the - * mbedtls_strerror() - */ -// #define MBEDTLS_ERROR_STRERROR_DUMMY - -/** - * \def MBEDTLS_GENPRIME - * - * Enable the prime-number generation code. - * - * Requires: MBEDTLS_BIGNUM_C - */ -// #define MBEDTLS_GENPRIME - -/** - * \def MBEDTLS_FS_IO - * - * Enable functions that use the filesystem. - */ -//#define MBEDTLS_FS_IO - -/** - * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - * Do not add default entropy sources. These are the platform specific, - * mbedtls_timing_hardclock and HAVEGE based poll functions. - * - * This is useful to have more control over the added entropy sources in an - * application. - * - * Uncomment this macro to prevent loading of default entropy functions. - */ -//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - -/** - * \def MBEDTLS_NO_PLATFORM_ENTROPY - * - * Do not use built-in platform entropy functions. - * This is useful if your platform does not support - * standards like the /dev/urandom or Windows CryptoAPI. - * - * Uncomment this macro to disable the built-in platform entropy functions. - */ -// #define MBEDTLS_NO_PLATFORM_ENTROPY - -/** - * \def MBEDTLS_ENTROPY_FORCE_SHA256 - * - * Force the entropy accumulator to use a SHA-256 accumulator instead of the - * default SHA-512 based one (if both are available). - * - * Requires: MBEDTLS_SHA256_C - * - * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option - * if you have performance concerns. - * - * This option is only useful if both MBEDTLS_SHA256_C and - * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. - */ -//#define MBEDTLS_ENTROPY_FORCE_SHA256 - -/** - * \def MBEDTLS_ENTROPY_NV_SEED - * - * Enable the non-volatile (NV) seed file-based entropy source. - * (Also enables the NV seed read/write functions in the platform layer) - * - * This is crucial (if not required) on systems that do not have a - * cryptographic entropy source (in hardware or kernel) available. - * - * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C - * - * \note The read/write functions that are used by the entropy source are - * determined in the platform layer, and can be modified at runtime and/or - * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. - * - * \note If you use the default implementation functions that read a seedfile - * with regular fopen(), please make sure you make a seedfile with the - * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at - * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from - * and written to or you will get an entropy source error! The default - * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE - * bytes from the file. - * - * \note The entropy collector will write to the seed file before entropy is - * given to an external source, to update it. - */ -//#define MBEDTLS_ENTROPY_NV_SEED - -/** - * \def MBEDTLS_MEMORY_DEBUG - * - * Enable debugging of buffer allocator memory issues. Automatically prints - * (to stderr) all (fatal) messages on memory allocation issues. Enables - * function for 'debug output' of allocated memory. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Uncomment this macro to let the buffer allocator print out error messages. - */ -//#define MBEDTLS_MEMORY_DEBUG - -/** - * \def MBEDTLS_MEMORY_BACKTRACE - * - * Include backtrace information with each allocated block. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * GLIBC-compatible backtrace() an backtrace_symbols() support - * - * Uncomment this macro to include backtrace information - */ -//#define MBEDTLS_MEMORY_BACKTRACE - -/** - * \def MBEDTLS_PK_RSA_ALT_SUPPORT - * - * Support external private RSA keys (eg from a HSM) in the PK layer. - * - * Comment this macro to disable support for external private RSA keys. - */ -// #define MBEDTLS_PK_RSA_ALT_SUPPORT - -/** - * \def MBEDTLS_PKCS1_V15 - * - * Enable support for PKCS#1 v1.5 encoding. - * - * Requires: MBEDTLS_RSA_C - * - * This enables support for PKCS#1 v1.5 operations. - */ -// #define MBEDTLS_PKCS1_V15 - -/** - * \def MBEDTLS_PKCS1_V21 - * - * Enable support for PKCS#1 v2.1 encoding. - * - * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C - * - * This enables support for RSAES-OAEP and RSASSA-PSS operations. - */ -// #define MBEDTLS_PKCS1_V21 - -/** - * \def MBEDTLS_RSA_NO_CRT - * - * Do not use the Chinese Remainder Theorem for the RSA private operation. - * - * Uncomment this macro to disable the use of CRT in RSA. - * - */ -//#define MBEDTLS_RSA_NO_CRT - -/** - * \def MBEDTLS_SELF_TEST - * - * Enable the checkup functions (*_self_test). - */ -// #define MBEDTLS_SELF_TEST - -/** - * \def MBEDTLS_SHA256_SMALLER - * - * Enable an implementation of SHA-256 that has lower ROM footprint but also - * lower performance. - * - * The default implementation is meant to be a reasonnable compromise between - * performance and size. This version optimizes more aggressively for size at - * the expense of performance. Eg on Cortex-M4 it reduces the size of - * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about - * 30%. - * - * Uncomment to enable the smaller implementation of SHA256. - */ -//#define MBEDTLS_SHA256_SMALLER - -/** - * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES - * - * Enable sending of alert messages in case of encountered errors as per RFC. - * If you choose not to send the alert messages, mbed TLS can still communicate - * with other servers, only debugging of failures is harder. - * - * The advantage of not sending alert messages, is that no information is given - * about reasons for failures thus preventing adversaries of gaining intel. - * - * Enable sending of all alert messages - */ -// #define MBEDTLS_SSL_ALL_ALERT_MESSAGES - -/** - * \def MBEDTLS_SSL_DEBUG_ALL - * - * Enable the debug messages in SSL module for all issues. - * Debug messages have been disabled in some places to prevent timing - * attacks due to (unbalanced) debugging function calls. - * - * If you need all error reporting you should enable this during debugging, - * but remove this for production servers that should log as well. - * - * Uncomment this macro to report all debug messages on errors introducing - * a timing side-channel. - * - */ -//#define MBEDTLS_SSL_DEBUG_ALL - -/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC - * - * Enable support for Encrypt-then-MAC, RFC 7366. - * - * This allows peers that both support it to use a more robust protection for - * ciphersuites using CBC, providing deep resistance against timing attacks - * on the padding or underlying cipher. - * - * This only affects CBC ciphersuites, and is useless if none is defined. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Encrypt-then-MAC - */ -// #define MBEDTLS_SSL_ENCRYPT_THEN_MAC - -/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET - * - * Enable support for Extended Master Secret, aka Session Hash - * (draft-ietf-tls-session-hash-02). - * - * This was introduced as "the proper fix" to the Triple Handshake familiy of - * attacks, but it is recommended to always use it (even if you disable - * renegotiation), since it actually fixes a more fundamental issue in the - * original SSL/TLS design, and has implications beyond Triple Handshake. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1 or - * MBEDTLS_SSL_PROTO_TLS1_1 or - * MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Extended Master Secret. - */ -// #define MBEDTLS_SSL_EXTENDED_MASTER_SECRET - -/** - * \def MBEDTLS_SSL_FALLBACK_SCSV - * - * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00). - * - * For servers, it is recommended to always enable this, unless you support - * only one version of TLS, or know for sure that none of your clients - * implements a fallback strategy. - * - * For clients, you only need this if you're using a fallback strategy, which - * is not recommended in the first place, unless you absolutely need it to - * interoperate with buggy (version-intolerant) servers. - * - * Comment this macro to disable support for FALLBACK_SCSV - */ -// #define MBEDTLS_SSL_FALLBACK_SCSV - -/** - * \def MBEDTLS_SSL_HW_RECORD_ACCEL - * - * Enable hooking functions in SSL module for hardware acceleration of - * individual records. - * - * Uncomment this macro to enable hooking functions. - */ -//#define MBEDTLS_SSL_HW_RECORD_ACCEL - -/** - * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING - * - * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. - * - * This is a countermeasure to the BEAST attack, which also minimizes the risk - * of interoperability issues compared to sending 0-length records. - * - * Comment this macro to disable 1/n-1 record splitting. - */ -// #define MBEDTLS_SSL_CBC_RECORD_SPLITTING - -/** - * \def MBEDTLS_SSL_RENEGOTIATION - * - * Disable support for TLS renegotiation. - * - * The two main uses of renegotiation are (1) refresh keys on long-lived - * connections and (2) client authentication after the initial handshake. - * If you don't need renegotiation, it's probably better to disable it, since - * it has been associated with security issues in the past and is easy to - * misuse/misunderstand. - * - * Comment this to disable support for renegotiation. - */ -// #define MBEDTLS_SSL_RENEGOTIATION - -/** - * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - * - * Enable support for receiving and parsing SSLv2 Client Hello messages for the - * SSL Server module (MBEDTLS_SSL_SRV_C). - * - * Uncomment this macro to enable support for SSLv2 Client Hello messages. - */ -//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO - -/** - * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - * - * Pick the ciphersuite according to the client's preferences rather than ours - * in the SSL Server module (MBEDTLS_SSL_SRV_C). - * - * Uncomment this macro to respect client's ciphersuite order - */ -//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - -/** - * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - * - * Enable support for RFC 6066 max_fragment_length extension in SSL. - * - * Comment this macro to disable support for the max_fragment_length extension - */ -// #define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - -/** - * \def MBEDTLS_SSL_PROTO_SSL3 - * - * Enable support for SSL 3.0. - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for SSL 3.0 - */ -//#define MBEDTLS_SSL_PROTO_SSL3 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1 - * - * Enable support for TLS 1.0. - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for TLS 1.0 - */ -// #define MBEDTLS_SSL_PROTO_TLS1 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_1 - * - * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). - * - * Requires: MBEDTLS_MD5_C - * MBEDTLS_SHA1_C - * - * Comment this macro to disable support for TLS 1.1 / DTLS 1.0 - */ -// #define MBEDTLS_SSL_PROTO_TLS1_1 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_2 - * - * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). - * - * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C - * (Depends on ciphersuites) - * - * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 - */ -// #define MBEDTLS_SSL_PROTO_TLS1_2 - -/** - * \def MBEDTLS_SSL_PROTO_DTLS - * - * Enable support for DTLS (all available versions). - * - * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, - * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_1 - * or MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for DTLS - */ -// #define MBEDTLS_SSL_PROTO_DTLS - -/** - * \def MBEDTLS_SSL_ALPN - * - * Enable support for RFC 7301 Application Layer Protocol Negotiation. - * - * Comment this macro to disable support for ALPN. - */ -// #define MBEDTLS_SSL_ALPN - -/** - * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY - * - * Enable support for the anti-replay mechanism in DTLS. - * - * Requires: MBEDTLS_SSL_TLS_C - * MBEDTLS_SSL_PROTO_DTLS - * - * \warning Disabling this is often a security risk! - * See mbedtls_ssl_conf_dtls_anti_replay() for details. - * - * Comment this to disable anti-replay in DTLS. - */ -// #define MBEDTLS_SSL_DTLS_ANTI_REPLAY - -/** - * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Enable support for HelloVerifyRequest on DTLS servers. - * - * This feature is highly recommended to prevent DTLS servers being used as - * amplifiers in DoS attacks against other hosts. It should always be enabled - * unless you know for sure amplification cannot be a problem in the - * environment in which your server operates. - * - * \warning Disabling this can ba a security risk! (see above) - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Comment this to disable support for HelloVerifyRequest. - */ -// #define MBEDTLS_SSL_DTLS_HELLO_VERIFY - -/** - * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - * - * Enable server-side support for clients that reconnect from the same port. - * - * Some clients unexpectedly close the connection and try to reconnect using the - * same source port. This needs special support from the server to handle the - * new connection securely, as described in section 4.2.8 of RFC 6347. This - * flag enables that support. - * - * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Comment this to disable support for clients reusing the source port. - */ -// #define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - -/** - * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT - * - * Enable support for a limit of records with bad MAC. - * - * See mbedtls_ssl_conf_dtls_badmac_limit(). - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - */ -// #define MBEDTLS_SSL_DTLS_BADMAC_LIMIT - -/** - * \def MBEDTLS_SSL_SESSION_TICKETS - * - * Enable support for RFC 5077 session tickets in SSL. - * Client-side, provides full support for session tickets (maintainance of a - * session store remains the responsibility of the application, though). - * Server-side, you also need to provide callbacks for writing and parsing - * tickets, including authenticated encryption and key management. Example - * callbacks are provided by MBEDTLS_SSL_TICKET_C. - * - * Comment this macro to disable support for SSL session tickets - */ -// #define MBEDTLS_SSL_SESSION_TICKETS - -/** - * \def MBEDTLS_SSL_EXPORT_KEYS - * - * Enable support for exporting key block and master secret. - * This is required for certain users of TLS, e.g. EAP-TLS. - * - * Comment this macro to disable support for key export - */ -// #define MBEDTLS_SSL_EXPORT_KEYS - -/** - * \def MBEDTLS_SSL_SERVER_NAME_INDICATION - * - * Enable support for RFC 6066 server name indication (SNI) in SSL. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - * - * Comment this macro to disable support for server name indication in SSL - */ -// #define MBEDTLS_SSL_SERVER_NAME_INDICATION - -/** - * \def MBEDTLS_SSL_TRUNCATED_HMAC - * - * Enable support for RFC 6066 truncated HMAC in SSL. - * - * Comment this macro to disable support for truncated HMAC in SSL - */ -// #define MBEDTLS_SSL_TRUNCATED_HMAC - -/** - * \def MBEDTLS_THREADING_ALT - * - * Provide your own alternate threading implementation. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to allow your own alternate threading implementation. - */ -//#define MBEDTLS_THREADING_ALT - -/** - * \def MBEDTLS_THREADING_PTHREAD - * - * Enable the pthread wrapper layer for the threading layer. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to enable pthread mutexes. - */ -//#define MBEDTLS_THREADING_PTHREAD - -/** - * \def MBEDTLS_VERSION_FEATURES - * - * Allow run-time checking of compile-time enabled features. Thus allowing users - * to check at run-time if the library is for instance compiled with threading - * support via mbedtls_version_check_feature(). - * - * Requires: MBEDTLS_VERSION_C - * - * Comment this to disable run-time checking and save ROM space - */ -// #define MBEDTLS_VERSION_FEATURES - -/** - * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an extension in a v1 or v2 certificate. - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 - -/** - * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - * - * If set, the X509 parser will not break-off when parsing an X509 certificate - * and encountering an unknown critical extension. - * - * \warning Depending on your PKI use, enabling this can be a security risk! - * - * Uncomment to prevent an error. - */ -//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - -/** - * \def MBEDTLS_X509_CHECK_KEY_USAGE - * - * Enable verification of the keyUsage extension (CA and leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused - * (intermediate) CA and leaf certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip keyUsage checking for both CA and leaf certificates. - */ -// #define MBEDTLS_X509_CHECK_KEY_USAGE - -/** - * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE - * - * Enable verification of the extendedKeyUsage extension (leaf certificates). - * - * Disabling this avoids problems with mis-issued and/or misused certificates. - * - * \warning Depending on your PKI use, disabling this can be a security risk! - * - * Comment to skip extendedKeyUsage checking for certificates. - */ -// #define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE - -/** - * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT - * - * Enable parsing and verification of X.509 certificates, CRLs and CSRS - * signed with RSASSA-PSS (aka PKCS#1 v2.1). - * - * Comment this macro to disallow using RSASSA-PSS in certificates. - */ -// #define MBEDTLS_X509_RSASSA_PSS_SUPPORT - -/** - * \def MBEDTLS_ZLIB_SUPPORT - * - * If set, the SSL/TLS module uses ZLIB to support compression and - * decompression of packet data. - * - * \warning TLS-level compression MAY REDUCE SECURITY! See for example the - * CRIME attack. Before enabling this option, you should examine with care if - * CRIME or similar exploits may be a applicable to your use case. - * - * \note Currently compression can't be used with DTLS. - * - * Used in: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This feature requires zlib library and headers to be present. - * - * Uncomment to enable use of ZLIB - */ -//#define MBEDTLS_ZLIB_SUPPORT -/* \} name SECTION: mbed TLS feature support */ - -/** - * \name SECTION: mbed TLS modules - * - * This section enables or disables entire modules in mbed TLS - * \{ - */ - -/** - * \def MBEDTLS_AESNI_C - * - * Enable AES-NI support on x86-64. - * - * Module: library/aesni.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM - * - * This modules adds support for the AES-NI instructions on x86-64 - */ -// #define MBEDTLS_AESNI_C - -/** - * \def MBEDTLS_AES_C - * - * Enable the AES block cipher. - * - * Module: library/aes.c - * Caller: library/ssl_tls.c - * library/pem.c - * library/ctr_drbg.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * - * PEM_PARSE uses AES for decrypting encrypted keys. - */ -#define MBEDTLS_AES_C - -/** - * \def MBEDTLS_ARC4_C - * - * Enable the ARCFOUR stream cipher. - * - * Module: library/arc4.c - * Caller: library/ssl_tls.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA - * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA - * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA - */ -// #define MBEDTLS_ARC4_C - -/** - * \def MBEDTLS_ASN1_PARSE_C - * - * Enable the generic ASN1 parser. - * - * Module: library/asn1.c - * Caller: library/x509.c - * library/dhm.c - * library/pkcs12.c - * library/pkcs5.c - * library/pkparse.c - */ -// #define MBEDTLS_ASN1_PARSE_C - -/** - * \def MBEDTLS_ASN1_WRITE_C - * - * Enable the generic ASN1 writer. - * - * Module: library/asn1write.c - * Caller: library/ecdsa.c - * library/pkwrite.c - * library/x509_create.c - * library/x509write_crt.c - * library/x509write_csr.c - */ -// #define MBEDTLS_ASN1_WRITE_C - -/** - * \def MBEDTLS_BASE64_C - * - * Enable the Base64 module. - * - * Module: library/base64.c - * Caller: library/pem.c - * - * This module is required for PEM support (required by X.509). - */ -// #define MBEDTLS_BASE64_C - -/** - * \def MBEDTLS_BIGNUM_C - * - * Enable the multi-precision integer library. - * - * Module: library/bignum.c - * Caller: library/dhm.c - * library/ecp.c - * library/ecdsa.c - * library/rsa.c - * library/ssl_tls.c - * - * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. - */ -// #define MBEDTLS_BIGNUM_C - -/** - * \def MBEDTLS_BLOWFISH_C - * - * Enable the Blowfish block cipher. - * - * Module: library/blowfish.c - */ -// #define MBEDTLS_BLOWFISH_C - -/** - * \def MBEDTLS_CAMELLIA_C - * - * Enable the Camellia block cipher. - * - * Module: library/camellia.c - * Caller: library/ssl_tls.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -// #define MBEDTLS_CAMELLIA_C - -/** - * \def MBEDTLS_CCM_C - * - * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. - * - * Module: library/ccm.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C - * - * This module enables the AES-CCM ciphersuites, if other requisites are - * enabled as well. - */ -#define MBEDTLS_CCM_C - -/** - * \def MBEDTLS_CERTS_C - * - * Enable the test certificates. - * - * Module: library/certs.c - * Caller: - * - * This module is used for testing (ssl_client/server). - */ -// #define MBEDTLS_CERTS_C - -/** - * \def MBEDTLS_CIPHER_C - * - * Enable the generic cipher layer. - * - * Module: library/cipher.c - * Caller: library/ssl_tls.c - * - * Uncomment to enable generic cipher wrappers. - */ -#define MBEDTLS_CIPHER_C - -/** - * \def MBEDTLS_CMAC_C - * - * Enable the CMAC (Cipher-based Message Authentication Code) mode for block - * ciphers. - * - * Module: library/cmac.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C - * - */ -//#define MBEDTLS_CMAC_C - -/** - * \def MBEDTLS_CTR_DRBG_C - * - * Enable the CTR_DRBG AES-256-based random generator. - * - * Module: library/ctr_drbg.c - * Caller: - * - * Requires: MBEDTLS_AES_C - * - * This module provides the CTR_DRBG AES-256 random number generator. - */ -// #define MBEDTLS_CTR_DRBG_C - -/** - * \def MBEDTLS_DEBUG_C - * - * Enable the debug functions. - * - * Module: library/debug.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module provides debugging functions. - */ -// #define MBEDTLS_DEBUG_C - -/** - * \def MBEDTLS_DES_C - * - * Enable the DES block cipher. - * - * Module: library/des.c - * Caller: library/pem.c - * library/ssl_tls.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA - * - * PEM_PARSE uses DES/3DES for decrypting encrypted keys. - */ -// #define MBEDTLS_DES_C - -/** - * \def MBEDTLS_DHM_C - * - * Enable the Diffie-Hellman-Merkle module. - * - * Module: library/dhm.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * DHE-RSA, DHE-PSK - */ -// #define MBEDTLS_DHM_C - -/** - * \def MBEDTLS_ECDH_C - * - * Enable the elliptic curve Diffie-Hellman library. - * - * Module: library/ecdh.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK - * - * Requires: MBEDTLS_ECP_C - */ -// #define MBEDTLS_ECDH_C - -/** - * \def MBEDTLS_ECDSA_C - * - * Enable the elliptic curve DSA library. - * - * Module: library/ecdsa.c - * Caller: - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C - */ -// #define MBEDTLS_ECDSA_C - -/** - * \def MBEDTLS_ECJPAKE_C - * - * Enable the elliptic curve J-PAKE library. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Module: library/ecjpake.c - * Caller: - * - * This module is used by the following key exchanges: - * ECJPAKE - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C - */ -//#define MBEDTLS_ECJPAKE_C - -/** - * \def MBEDTLS_ECP_C - * - * Enable the elliptic curve over GF(p) library. - * - * Module: library/ecp.c - * Caller: library/ecdh.c - * library/ecdsa.c - * library/ecjpake.c - * - * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED - */ -// #define MBEDTLS_ECP_C - -/** - * \def MBEDTLS_ENTROPY_C - * - * Enable the platform-specific entropy code. - * - * Module: library/entropy.c - * Caller: - * - * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C - * - * This module provides a generic entropy pool - */ -// #define MBEDTLS_ENTROPY_C - -/** - * \def MBEDTLS_ERROR_C - * - * Enable error code to error string conversion. - * - * Module: library/error.c - * Caller: - * - * This module enables mbedtls_strerror(). - */ -// #define MBEDTLS_ERROR_C - -/** - * \def MBEDTLS_GCM_C - * - * Enable the Galois/Counter Mode (GCM) for AES. - * - * Module: library/gcm.c - * - * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C - * - * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other - * requisites are enabled as well. - */ -// #define MBEDTLS_GCM_C - -/** - * \def MBEDTLS_HAVEGE_C - * - * Enable the HAVEGE random generator. - * - * Warning: the HAVEGE random generator is not suitable for virtualized - * environments - * - * Warning: the HAVEGE random generator is dependent on timing and specific - * processor traits. It is therefore not advised to use HAVEGE as - * your applications primary random generator or primary entropy pool - * input. As a secondary input to your entropy pool, it IS able add - * the (limited) extra entropy it provides. - * - * Module: library/havege.c - * Caller: - * - * Requires: MBEDTLS_TIMING_C - * - * Uncomment to enable the HAVEGE random generator. - */ -//#define MBEDTLS_HAVEGE_C - -/** - * \def MBEDTLS_HMAC_DRBG_C - * - * Enable the HMAC_DRBG random generator. - * - * Module: library/hmac_drbg.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * Uncomment to enable the HMAC_DRBG random number geerator. - */ -// #define MBEDTLS_HMAC_DRBG_C - -/** - * \def MBEDTLS_MD_C - * - * Enable the generic message digest layer. - * - * Module: library/md.c - * Caller: - * - * Uncomment to enable generic message digest wrappers. - */ -// #define MBEDTLS_MD_C - -/** - * \def MBEDTLS_MD2_C - * - * Enable the MD2 hash algorithm. - * - * Module: library/md2.c - * Caller: - * - * Uncomment to enable support for (rare) MD2-signed X.509 certs. - */ -//#define MBEDTLS_MD2_C - -/** - * \def MBEDTLS_MD4_C - * - * Enable the MD4 hash algorithm. - * - * Module: library/md4.c - * Caller: - * - * Uncomment to enable support for (rare) MD4-signed X.509 certs. - */ -//#define MBEDTLS_MD4_C - -/** - * \def MBEDTLS_MD5_C - * - * Enable the MD5 hash algorithm. - * - * Module: library/md5.c - * Caller: library/md.c - * library/pem.c - * library/ssl_tls.c - * - * This module is required for SSL/TLS and X.509. - * PEM_PARSE uses MD5 for decrypting encrypted keys. - */ -// #define MBEDTLS_MD5_C - -/** - * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Enable the buffer allocator implementation that makes use of a (stack) - * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() - * calls) - * - * Module: library/memory_buffer_alloc.c - * - * Requires: MBEDTLS_PLATFORM_C - * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) - * - * Enable this module to enable the buffer memory allocator. - */ -//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C - -/** - * \def MBEDTLS_NET_C - * - * Enable the TCP and UDP over IPv6/IPv4 networking routines. - * - * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) - * and Windows. For other platforms, you'll want to disable it, and write your - * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/net_sockets.c - * - * This module provides networking routines. - */ -//#define MBEDTLS_NET_C - -/** - * \def MBEDTLS_OID_C - * - * Enable the OID database. - * - * Module: library/oid.c - * Caller: library/asn1write.c - * library/pkcs5.c - * library/pkparse.c - * library/pkwrite.c - * library/rsa.c - * library/x509.c - * library/x509_create.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * This modules translates between OIDs and internal values. - */ -#define MBEDTLS_OID_C - -/** - * \def MBEDTLS_PADLOCK_C - * - * Enable VIA Padlock support on x86. - * - * Module: library/padlock.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM - * - * This modules adds support for the VIA PadLock on x86. - */ -// #define MBEDTLS_PADLOCK_C - -/** - * \def MBEDTLS_PEM_PARSE_C - * - * Enable PEM decoding / parsing. - * - * Module: library/pem.c - * Caller: library/dhm.c - * library/pkparse.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for decoding / parsing PEM files. - */ -// #define MBEDTLS_PEM_PARSE_C - -/** - * \def MBEDTLS_PEM_WRITE_C - * - * Enable PEM encoding / writing. - * - * Module: library/pem.c - * Caller: library/pkwrite.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for encoding / writing PEM files. - */ -// // #define MBEDTLS_PEM_WRITE_C - -/** - * \def MBEDTLS_PK_C - * - * Enable the generic public (asymetric) key layer. - * - * Module: library/pk.c - * Caller: library/ssl_tls.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C - * - * Uncomment to enable generic public key wrappers. - */ -// #define MBEDTLS_PK_C - -/** - * \def MBEDTLS_PK_PARSE_C - * - * Enable the generic public (asymetric) key parser. - * - * Module: library/pkparse.c - * Caller: library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key parse functions. - */ -// #define MBEDTLS_PK_PARSE_C - -/** - * \def MBEDTLS_PK_WRITE_C - * - * Enable the generic public (asymetric) key writer. - * - * Module: library/pkwrite.c - * Caller: library/x509write.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key write functions. - */ -// #define MBEDTLS_PK_WRITE_C - -/** - * \def MBEDTLS_PKCS5_C - * - * Enable PKCS#5 functions. - * - * Module: library/pkcs5.c - * - * Requires: MBEDTLS_MD_C - * - * This module adds support for the PKCS#5 functions. - */ -// #define MBEDTLS_PKCS5_C - -/** - * \def MBEDTLS_PKCS11_C - * - * Enable wrapper for PKCS#11 smartcard support. - * - * Module: library/pkcs11.c - * Caller: library/pk.c - * - * Requires: MBEDTLS_PK_C - * - * This module enables SSL/TLS PKCS #11 smartcard support. - * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) - */ -//#define MBEDTLS_PKCS11_C - -/** - * \def MBEDTLS_PKCS12_C - * - * Enable PKCS#12 PBE functions. - * Adds algorithms for parsing PKCS#8 encrypted private keys - * - * Module: library/pkcs12.c - * Caller: library/pkparse.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * Can use: MBEDTLS_ARC4_C - * - * This module enables PKCS#12 functions. - */ -// #define MBEDTLS_PKCS12_C - -/** - * \def MBEDTLS_PLATFORM_C - * - * Enable the platform abstraction layer that allows you to re-assign - * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). - * - * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT - * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned - * above to be specified at runtime or compile time respectively. - * - * \note This abstraction layer must be enabled on Windows (including MSYS2) - * as other module rely on it for a fixed snprintf implementation. - * - * Module: library/platform.c - * Caller: Most other .c files - * - * This module enables abstraction of common (libc) functions. - */ -// #define MBEDTLS_PLATFORM_C - -/** - * \def MBEDTLS_RIPEMD160_C - * - * Enable the RIPEMD-160 hash algorithm. - * - * Module: library/ripemd160.c - * Caller: library/md.c - * - */ -// #define MBEDTLS_RIPEMD160_C - -/** - * \def MBEDTLS_RSA_C - * - * Enable the RSA public-key cryptosystem. - * - * Module: library/rsa.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509.c - * - * This module is used by the following key exchanges: - * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C - */ -// #define MBEDTLS_RSA_C - -/** - * \def MBEDTLS_SHA1_C - * - * Enable the SHA1 cryptographic hash algorithm. - * - * Module: library/sha1.c - * Caller: library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * library/x509write_crt.c - * - * This module is required for SSL/TLS and SHA1-signed certificates. - */ -// #define MBEDTLS_SHA1_C - -/** - * \def MBEDTLS_SHA256_C - * - * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. - * - * Module: library/sha256.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * This module adds support for SHA-224 and SHA-256. - * This module is required for the SSL/TLS 1.2 PRF function. - */ -// #define MBEDTLS_SHA256_C - -/** - * \def MBEDTLS_SHA512_C - * - * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. - * - * Module: library/sha512.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_cli.c - * library/ssl_srv.c - * - * This module adds support for SHA-384 and SHA-512. - */ -// #define MBEDTLS_SHA512_C - -/** - * \def MBEDTLS_SSL_CACHE_C - * - * Enable simple SSL cache implementation. - * - * Module: library/ssl_cache.c - * Caller: - * - * Requires: MBEDTLS_SSL_CACHE_C - */ -// #define MBEDTLS_SSL_CACHE_C - -/** - * \def MBEDTLS_SSL_COOKIE_C - * - * Enable basic implementation of DTLS cookies for hello verification. - * - * Module: library/ssl_cookie.c - * Caller: - */ -// #define MBEDTLS_SSL_COOKIE_C - -/** - * \def MBEDTLS_SSL_TICKET_C - * - * Enable an implementation of TLS server-side callbacks for session tickets. - * - * Module: library/ssl_ticket.c - * Caller: - * - * Requires: MBEDTLS_CIPHER_C - */ -// #define MBEDTLS_SSL_TICKET_C - -/** - * \def MBEDTLS_SSL_CLI_C - * - * Enable the SSL/TLS client code. - * - * Module: library/ssl_cli.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS client support. - */ -// #define MBEDTLS_SSL_CLI_C - -/** - * \def MBEDTLS_SSL_SRV_C - * - * Enable the SSL/TLS server code. - * - * Module: library/ssl_srv.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS server support. - */ -// #define MBEDTLS_SSL_SRV_C - -/** - * \def MBEDTLS_SSL_TLS_C - * - * Enable the generic SSL/TLS code. - * - * Module: library/ssl_tls.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * and at least one of the MBEDTLS_SSL_PROTO_XXX defines - * - * This module is required for SSL/TLS. - */ -// #define MBEDTLS_SSL_TLS_C - -/** - * \def MBEDTLS_THREADING_C - * - * Enable the threading abstraction layer. - * By default mbed TLS assumes it is used in a non-threaded environment or that - * contexts are not shared between threads. If you do intend to use contexts - * between threads, you will need to enable this layer to prevent race - * conditions. See also our Knowledge Base article about threading: - * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading - * - * Module: library/threading.c - * - * This allows different threading implementations (self-implemented or - * provided). - * - * You will have to enable either MBEDTLS_THREADING_ALT or - * MBEDTLS_THREADING_PTHREAD. - * - * Enable this layer to allow use of mutexes within mbed TLS - */ -//#define MBEDTLS_THREADING_C - -/** - * \def MBEDTLS_TIMING_C - * - * Enable the semi-portable timing interface. - * - * \note The provided implementation only works on POSIX/Unix (including Linux, - * BSD and OS X) and Windows. On other platforms, you can either disable that - * module and provide your own implementations of the callbacks needed by - * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide - * your own implementation of the whole module by setting - * \c MBEDTLS_TIMING_ALT in the current file. - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/timing.c - * Caller: library/havege.c - * - * This module is used by the HAVEGE random number generator. - */ -//#define MBEDTLS_TIMING_C - -/** - * \def MBEDTLS_VERSION_C - * - * Enable run-time version information. - * - * Module: library/version.c - * - * This module provides run-time version information. - */ -// #define MBEDTLS_VERSION_C - -/** - * \def MBEDTLS_X509_USE_C - * - * Enable X.509 core for using certificates. - * - * Module: library/x509.c - * Caller: library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, - * MBEDTLS_PK_PARSE_C - * - * This module is required for the X.509 parsing modules. - */ -// #define MBEDTLS_X509_USE_C - -/** - * \def MBEDTLS_X509_CRT_PARSE_C - * - * Enable X.509 certificate parsing. - * - * Module: library/x509_crt.c - * Caller: library/ssl_cli.c - * library/ssl_srv.c - * library/ssl_tls.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 certificate parsing. - */ -// #define MBEDTLS_X509_CRT_PARSE_C - -/** - * \def MBEDTLS_X509_CRL_PARSE_C - * - * Enable X.509 CRL parsing. - * - * Module: library/x509_crl.c - * Caller: library/x509_crt.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 CRL parsing. - */ -// #define MBEDTLS_X509_CRL_PARSE_C - -/** - * \def MBEDTLS_X509_CSR_PARSE_C - * - * Enable X.509 Certificate Signing Request (CSR) parsing. - * - * Module: library/x509_csr.c - * Caller: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is used for reading X.509 certificate request. - */ -// #define MBEDTLS_X509_CSR_PARSE_C - -/** - * \def MBEDTLS_X509_CREATE_C - * - * Enable X.509 core for creating certificates. - * - * Module: library/x509_create.c - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C - * - * This module is the basis for creating X.509 certificates and CSRs. - */ -// #define MBEDTLS_X509_CREATE_C - -/** - * \def MBEDTLS_X509_CRT_WRITE_C - * - * Enable creating X.509 certificates. - * - * Module: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate creation. - */ -// #define MBEDTLS_X509_CRT_WRITE_C - -/** - * \def MBEDTLS_X509_CSR_WRITE_C - * - * Enable creating X.509 Certificate Signing Requests (CSR). - * - * Module: library/x509_csr_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate request writing. - */ -// #define MBEDTLS_X509_CSR_WRITE_C - -/** - * \def MBEDTLS_XTEA_C - * - * Enable the XTEA block cipher. - * - * Module: library/xtea.c - * Caller: - */ -// #define MBEDTLS_XTEA_C - -/* \} name SECTION: mbed TLS modules */ - -/** - * \name SECTION: Module configuration options - * - * This section allows for the setting of module specific sizes and - * configuration options. The default values are already present in the - * relevant header files and should suffice for the regular use cases. - * - * Our advice is to enable options and change their values here - * only if you have a good reason and know the consequences. - * - * Please check the respective header file for documentation on these - * parameters (to prevent duplicate documentation). - * \{ - */ - -/* MPI / BIGNUM options */ -//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ -//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ - -/* CTR_DRBG options */ -//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ -//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* HMAC_DRBG options */ -//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* ECP options */ -//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ -//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ -//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ - -/* Entropy options */ -//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ - -/* Memory buffer allocator options */ -//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ - -/* Platform options */ -//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ -//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ -/* Note: your snprintf must correclty zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ - -/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ -/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ -//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ -//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ -/* Note: your snprintf must correclty zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ - -/* SSL Cache options */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ - -/* SSL options */ -//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ -//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ -//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ -//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ - -/** - * Complete list of ciphersuites to use, in order of preference. - * - * \warning No dependency checking is done on that field! This option can only - * be used to restrict the set of available ciphersuites. It is your - * responsibility to make sure the needed modules are active. - * - * Use this to save a few hundred bytes of ROM (default ordering of all - * available ciphersuites) and a few to a few hundred bytes of RAM. - * - * The value below is only an example, not the default. - */ -//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - -/* X509 options */ -//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ -//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ - -/* \} name SECTION: Customisation configuration options */ - -/* Target and application specific configurations */ -//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h" - -#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE) -#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE -#endif - -/* - * Allow user to override any previous default. - * - * Use two macro names for that, as: - * - with yotta the prefix YOTTA_CFG_ is forced - * - without yotta is looks weird to have a YOTTA prefix. - */ -#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE) -#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE -#elif defined(MBEDTLS_USER_CONFIG_FILE) -#include MBEDTLS_USER_CONFIG_FILE -#endif - -#include "check_config.h" - -#endif /* MBEDTLS_CONFIG_H */ diff --git a/lib/mbedtls/include/mbedtls/platform.h b/lib/mbedtls/include/mbedtls/platform.h deleted file mode 100644 index b1b019e55..000000000 --- a/lib/mbedtls/include/mbedtls/platform.h +++ /dev/null @@ -1,295 +0,0 @@ -/** - * \file platform.h - * - * \brief mbed TLS Platform abstraction layer - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_PLATFORM_H -#define MBEDTLS_PLATFORM_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) -#include -#include -#include -#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) -#if defined(_WIN32) -#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */ -#else -#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use */ -#endif -#endif -#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) -#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) -#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_FREE) -#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT) -#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_TIME) -#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) -#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< Default exit value to use */ -#endif -#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) -#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< Default exit value to use */ -#endif -#if defined(MBEDTLS_FS_IO) -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) -#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read -#endif -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) -#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write -#endif -#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) -#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" -#endif -#endif /* MBEDTLS_FS_IO */ -#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ -#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) -#include MBEDTLS_PLATFORM_STD_MEM_HDR -#endif -#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ - - -/* \} name SECTION: Module settings */ - -/* - * The function pointers for calloc and free - */ -#if defined(MBEDTLS_PLATFORM_MEMORY) -#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ - defined(MBEDTLS_PLATFORM_CALLOC_MACRO) -#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO -#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO -#else -/* For size_t */ -#include -extern void * (*mbedtls_calloc)( size_t n, size_t size ); -extern void (*mbedtls_free)( void *ptr ); - -/** - * \brief Set your own memory implementation function pointers - * - * \param calloc_func the calloc function implementation - * \param free_func the free function implementation - * - * \return 0 if successful - */ -int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), - void (*free_func)( void * ) ); -#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ -#else /* !MBEDTLS_PLATFORM_MEMORY */ -#define mbedtls_free free -#define mbedtls_calloc calloc -#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ - -/* - * The function pointers for fprintf - */ -#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) -/* We need FILE * */ -#include -extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... ); - -/** - * \brief Set your own fprintf function pointer - * - * \param fprintf_func the fprintf function implementation - * - * \return 0 - */ -int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, - ... ) ); -#else -#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) -#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO -#else -#define mbedtls_fprintf fprintf -#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ - -/* - * The function pointers for printf - */ -#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) -extern int (*mbedtls_printf)( const char *format, ... ); - -/** - * \brief Set your own printf function pointer - * - * \param printf_func the printf function implementation - * - * \return 0 - */ -int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); -#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) -#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO -#else -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ - -/* - * The function pointers for snprintf - * - * The snprintf implementation should conform to C99: - * - it *must* always correctly zero-terminate the buffer - * (except when n == 0, then it must leave the buffer untouched) - * - however it is acceptable to return -1 instead of the required length when - * the destination buffer is too short. - */ -#if defined(_WIN32) -/* For Windows (inc. MSYS2), we provide our own fixed implementation */ -int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); -#endif - -#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) -extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); - -/** - * \brief Set your own snprintf function pointer - * - * \param snprintf_func the snprintf function implementation - * - * \return 0 - */ -int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, - const char * format, ... ) ); -#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ -#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) -#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO -#else -#define mbedtls_snprintf snprintf -#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ -#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ - -/* - * The function pointers for exit - */ -#if defined(MBEDTLS_PLATFORM_EXIT_ALT) -extern void (*mbedtls_exit)( int status ); - -/** - * \brief Set your own exit function pointer - * - * \param exit_func the exit function implementation - * - * \return 0 - */ -int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); -#else -#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) -#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO -#else -#define mbedtls_exit exit -#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ -#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ - -/* - * The default exit values - */ -#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) -#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS -#else -#define MBEDTLS_EXIT_SUCCESS 0 -#endif -#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) -#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE -#else -#define MBEDTLS_EXIT_FAILURE 1 -#endif - -/* - * The function pointers for reading from and writing a seed file to - * Non-Volatile storage (NV) in a platform-independent way - * - * Only enabled when the NV seed entropy source is enabled - */ -#if defined(MBEDTLS_ENTROPY_NV_SEED) -#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) -/* Internal standard platform definitions */ -int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ); -int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ); -#endif - -#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) -extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ); -extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ); - -/** - * \brief Set your own seed file writing/reading functions - * - * \param nv_seed_read_func the seed reading function implementation - * \param nv_seed_write_func the seed writing function implementation - * - * \return 0 - */ -int mbedtls_platform_set_nv_seed( - int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), - int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) - ); -#else -#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ - defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) -#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO -#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO -#else -#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read -#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write -#endif -#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ -#endif /* MBEDTLS_ENTROPY_NV_SEED */ - -#ifdef __cplusplus -} -#endif - -#endif /* platform.h */ diff --git a/lib/mbedtls/include/mbedtls/platform_time.h b/lib/mbedtls/include/mbedtls/platform_time.h deleted file mode 100644 index abb343142..000000000 --- a/lib/mbedtls/include/mbedtls/platform_time.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * \file platform_time.h - * - * \brief mbed TLS Platform time abstraction - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -#ifndef MBEDTLS_PLATFORM_TIME_H -#define MBEDTLS_PLATFORM_TIME_H - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h or define them on the compiler command line. - * \{ - */ - -/* - * The time_t datatype - */ -#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) -typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; -#else -/* For time_t */ -#include -typedef time_t mbedtls_time_t; -#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ - -/* - * The function pointers for time - */ -#if defined(MBEDTLS_PLATFORM_TIME_ALT) -extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); - -/** - * \brief Set your own time function pointer - * - * \param time_func the time function implementation - * - * \return 0 - */ -int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); -#else -#if defined(MBEDTLS_PLATFORM_TIME_MACRO) -#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO -#else -#define mbedtls_time time -#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ -#endif /* MBEDTLS_PLATFORM_TIME_ALT */ - -#ifdef __cplusplus -} -#endif - -#endif /* platform_time.h */ diff --git a/lib/mbedtls/src/aes.c b/lib/mbedtls/src/aes.c deleted file mode 100644 index a186dee98..000000000 --- a/lib/mbedtls/src/aes.c +++ /dev/null @@ -1,1492 +0,0 @@ -/* - * FIPS-197 compliant AES implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ -/* - * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. - * - * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf - * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_AES_C) - -#include - -#include "mbedtls/aes.h" -#if defined(MBEDTLS_PADLOCK_C) -#include "mbedtls/padlock.h" -#endif -#if defined(MBEDTLS_AESNI_C) -#include "mbedtls/aesni.h" -#endif - -#if defined(MBEDTLS_SELF_TEST) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST */ - -#if !defined(MBEDTLS_AES_ALT) - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; -} - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_UINT32_LE -#define GET_UINT32_LE(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_UINT32_LE -#define PUT_UINT32_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ - (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ - (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ - (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ -} -#endif - -#if defined(MBEDTLS_PADLOCK_C) && \ - ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) -static int aes_padlock_ace = -1; -#endif - -#if defined(MBEDTLS_AES_ROM_TABLES) -/* - * Forward S-box - */ -static const unsigned char FSb[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, - 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, - 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, - 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, - 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, - 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, - 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, - 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, - 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, - 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, - 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, - 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 -}; - -/* - * Forward tables - */ -#define FT \ -\ - V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ - V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ - V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ - V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ - V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ - V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ - V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ - V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ - V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ - V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ - V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ - V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ - V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ - V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ - V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ - V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ - V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ - V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ - V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ - V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ - V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ - V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ - V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ - V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ - V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ - V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ - V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ - V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ - V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ - V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ - V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ - V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ - V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ - V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ - V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ - V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ - V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ - V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ - V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ - V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ - V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ - V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ - V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ - V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ - V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ - V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ - V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ - V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ - V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ - V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ - V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ - V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ - V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ - V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ - V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ - V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ - V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ - V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ - V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ - V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ - V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ - V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ - V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ - V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) - -#define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t FT0[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t FT1[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t FT2[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t FT3[256] = { FT }; -#undef V - -#undef FT - -/* - * Reverse S-box - */ -static const unsigned char RSb[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, - 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, - 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, - 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, - 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, - 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, - 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, - 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, - 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, - 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, - 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, - 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D -}; - -/* - * Reverse tables - */ -#define RT \ -\ - V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ - V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ - V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ - V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ - V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ - V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ - V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ - V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ - V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ - V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ - V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ - V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ - V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ - V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ - V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ - V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ - V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ - V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ - V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ - V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ - V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ - V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ - V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ - V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ - V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ - V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ - V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ - V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ - V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ - V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ - V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ - V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ - V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ - V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ - V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ - V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ - V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ - V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ - V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ - V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ - V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ - V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ - V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ - V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ - V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ - V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ - V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ - V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ - V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ - V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ - V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ - V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ - V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ - V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ - V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ - V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ - V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ - V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ - V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ - V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ - V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ - V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ - V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ - V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) - -#define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t RT0[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t RT1[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t RT2[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t RT3[256] = { RT }; -#undef V - -#undef RT - -/* - * Round constants - */ -static const uint32_t RCON[10] = -{ - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x0000001B, 0x00000036 -}; - -#else /* MBEDTLS_AES_ROM_TABLES */ - -/* - * Forward S-box & tables - */ -static unsigned char FSb[256]; -static uint32_t FT0[256]; -static uint32_t FT1[256]; -static uint32_t FT2[256]; -static uint32_t FT3[256]; - -/* - * Reverse S-box & tables - */ -static unsigned char RSb[256]; -static uint32_t RT0[256]; -static uint32_t RT1[256]; -static uint32_t RT2[256]; -static uint32_t RT3[256]; - -/* - * Round constants - */ -static uint32_t RCON[10]; - -/* - * Tables generation code - */ -#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) -#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) -#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) - -static int aes_init_done = 0; - -static void aes_gen_tables( void ) -{ - int i, x, y, z; - int pow[256]; - int log[256]; - - /* - * compute pow and log tables over GF(2^8) - */ - for( i = 0, x = 1; i < 256; i++ ) - { - pow[i] = x; - log[x] = i; - x = ( x ^ XTIME( x ) ) & 0xFF; - } - - /* - * calculate the round constants - */ - for( i = 0, x = 1; i < 10; i++ ) - { - RCON[i] = (uint32_t) x; - x = XTIME( x ) & 0xFF; - } - - /* - * generate the forward and reverse S-boxes - */ - FSb[0x00] = 0x63; - RSb[0x63] = 0x00; - - for( i = 1; i < 256; i++ ) - { - x = pow[255 - log[i]]; - - y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; - x ^= y ^ 0x63; - - FSb[i] = (unsigned char) x; - RSb[x] = (unsigned char) i; - } - - /* - * generate the forward and reverse tables - */ - for( i = 0; i < 256; i++ ) - { - x = FSb[i]; - y = XTIME( x ) & 0xFF; - z = ( y ^ x ) & 0xFF; - - FT0[i] = ( (uint32_t) y ) ^ - ( (uint32_t) x << 8 ) ^ - ( (uint32_t) x << 16 ) ^ - ( (uint32_t) z << 24 ); - - FT1[i] = ROTL8( FT0[i] ); - FT2[i] = ROTL8( FT1[i] ); - FT3[i] = ROTL8( FT2[i] ); - - x = RSb[i]; - - RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ - ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ - ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ - ( (uint32_t) MUL( 0x0B, x ) << 24 ); - - RT1[i] = ROTL8( RT0[i] ); - RT2[i] = ROTL8( RT1[i] ); - RT3[i] = ROTL8( RT2[i] ); - } -} - -#endif /* MBEDTLS_AES_ROM_TABLES */ - -void mbedtls_aes_init( mbedtls_aes_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_aes_context ) ); -} - -void mbedtls_aes_free( mbedtls_aes_context *ctx ) -{ - if( ctx == NULL ) - return; - - mbedtls_zeroize( ctx, sizeof( mbedtls_aes_context ) ); -} - -/* - * AES key schedule (encryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) -int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ) -{ - unsigned int i; - uint32_t *RK; - -#if !defined(MBEDTLS_AES_ROM_TABLES) - if( aes_init_done == 0 ) - { - aes_gen_tables(); - aes_init_done = 1; - - } -#endif - - switch( keybits ) - { - case 128: ctx->nr = 10; break; - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; - default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); - } - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) - if( aes_padlock_ace == -1 ) - aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); - - if( aes_padlock_ace ) - ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); - else -#endif - ctx->rk = RK = ctx->buf; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); -#endif - - for( i = 0; i < ( keybits >> 5 ); i++ ) - { - GET_UINT32_LE( RK[i], key, i << 2 ); - } - - switch( ctx->nr ) - { - case 10: - - for( i = 0; i < 10; i++, RK += 4 ) - { - RK[4] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); - - RK[5] = RK[1] ^ RK[4]; - RK[6] = RK[2] ^ RK[5]; - RK[7] = RK[3] ^ RK[6]; - } - break; - - case 12: - - for( i = 0; i < 8; i++, RK += 6 ) - { - RK[6] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); - - RK[7] = RK[1] ^ RK[6]; - RK[8] = RK[2] ^ RK[7]; - RK[9] = RK[3] ^ RK[8]; - RK[10] = RK[4] ^ RK[9]; - RK[11] = RK[5] ^ RK[10]; - } - break; - - case 14: - - for( i = 0; i < 7; i++, RK += 8 ) - { - RK[8] = RK[0] ^ RCON[i] ^ - ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); - - RK[9] = RK[1] ^ RK[8]; - RK[10] = RK[2] ^ RK[9]; - RK[11] = RK[3] ^ RK[10]; - - RK[12] = RK[4] ^ - ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); - - RK[13] = RK[5] ^ RK[12]; - RK[14] = RK[6] ^ RK[13]; - RK[15] = RK[7] ^ RK[14]; - } - break; - } - - return( 0 ); -} -#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ - -/* - * AES key schedule (decryption) - */ -#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) -int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, - unsigned int keybits ) -{ - int i, j, ret; - mbedtls_aes_context cty; - uint32_t *RK; - uint32_t *SK; - - mbedtls_aes_init( &cty ); - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) - if( aes_padlock_ace == -1 ) - aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); - - if( aes_padlock_ace ) - ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); - else -#endif - ctx->rk = RK = ctx->buf; - - /* Also checks keybits */ - if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) - goto exit; - - ctx->nr = cty.nr; - -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - { - mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, - (const unsigned char *) cty.rk, ctx->nr ); - goto exit; - } -#endif - - SK = cty.rk + cty.nr * 4; - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - - for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) - { - for( j = 0; j < 4; j++, SK++ ) - { - *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ - RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ - RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ - RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; - } - } - - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - *RK++ = *SK++; - -exit: - mbedtls_aes_free( &cty ); - - return( ret ); -} -#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ - -#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ - FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ - FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ - FT3[ ( Y3 >> 24 ) & 0xFF ]; \ - \ - X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ - FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ - FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ - FT3[ ( Y0 >> 24 ) & 0xFF ]; \ - \ - X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ - FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ - FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ - FT3[ ( Y1 >> 24 ) & 0xFF ]; \ - \ - X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ - FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ - FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ - FT3[ ( Y2 >> 24 ) & 0xFF ]; \ -} - -#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ - RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ - RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ - RT3[ ( Y1 >> 24 ) & 0xFF ]; \ - \ - X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ - RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ - RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ - RT3[ ( Y2 >> 24 ) & 0xFF ]; \ - \ - X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ - RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ - RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ - RT3[ ( Y3 >> 24 ) & 0xFF ]; \ - \ - X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ - RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ - RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ - RT3[ ( Y0 >> 24 ) & 0xFF ]; \ -} - -/* - * AES-ECB block encryption - */ -#if !defined(MBEDTLS_AES_ENCRYPT_ALT) -void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i; - uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->rk; - - GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; - GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; - GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; - GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; - - for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) - { - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); - } - - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ - ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( X0, output, 0 ); - PUT_UINT32_LE( X1, output, 4 ); - PUT_UINT32_LE( X2, output, 8 ); - PUT_UINT32_LE( X3, output, 12 ); -} -#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ - -/* - * AES-ECB block decryption - */ -#if !defined(MBEDTLS_AES_DECRYPT_ALT) -void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) -{ - int i; - uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->rk; - - GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; - GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; - GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; - GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; - - for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) - { - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); - } - - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); - - X0 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); - - X1 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); - - X2 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); - - X3 = *RK++ ^ \ - ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ - ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ - ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); - - PUT_UINT32_LE( X0, output, 0 ); - PUT_UINT32_LE( X1, output, 4 ); - PUT_UINT32_LE( X2, output, 8 ); - PUT_UINT32_LE( X3, output, 12 ); -} -#endif /* !MBEDTLS_AES_DECRYPT_ALT */ - -/* - * AES-ECB block encryption/decryption - */ -int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, - int mode, - const unsigned char input[16], - unsigned char output[16] ) -{ -#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) - if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) - return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); -#endif - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) - if( aes_padlock_ace ) - { - if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - if( mode == MBEDTLS_AES_ENCRYPT ) - mbedtls_aes_encrypt( ctx, input, output ); - else - mbedtls_aes_decrypt( ctx, input, output ); - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -/* - * AES-CBC buffer encryption/decryption - */ -int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int i; - unsigned char temp[16]; - - if( length % 16 ) - return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); - -#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) - if( aes_padlock_ace ) - { - if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) - return( 0 ); - - // If padlock data misaligned, we just fall back to - // unaccelerated mode - // - } -#endif - - if( mode == MBEDTLS_AES_DECRYPT ) - { - while( length > 0 ) - { - memcpy( temp, input, 16 ); - mbedtls_aes_crypt_ecb( ctx, mode, input, output ); - - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( output[i] ^ iv[i] ); - - memcpy( iv, temp, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - else - { - while( length > 0 ) - { - for( i = 0; i < 16; i++ ) - output[i] = (unsigned char)( input[i] ^ iv[i] ); - - mbedtls_aes_crypt_ecb( ctx, mode, output, output ); - memcpy( iv, output, 16 ); - - input += 16; - output += 16; - length -= 16; - } - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, - int mode, - size_t length, - size_t *iv_off, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - int c; - size_t n = *iv_off; - - if( mode == MBEDTLS_AES_DECRYPT ) - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - c = *input++; - *output++ = (unsigned char)( c ^ iv[n] ); - iv[n] = (unsigned char) c; - - n = ( n + 1 ) & 0x0F; - } - } - else - { - while( length-- ) - { - if( n == 0 ) - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); - - n = ( n + 1 ) & 0x0F; - } - } - - *iv_off = n; - - return( 0 ); -} - -/* - * AES-CFB8 buffer encryption/decryption - */ -int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, - int mode, - size_t length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ) -{ - unsigned char c; - unsigned char ov[17]; - - while( length-- ) - { - memcpy( ov, iv, 16 ); - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); - - if( mode == MBEDTLS_AES_DECRYPT ) - ov[16] = *input; - - c = *output++ = (unsigned char)( iv[0] ^ *input++ ); - - if( mode == MBEDTLS_AES_ENCRYPT ) - ov[16] = c; - - memcpy( iv, ov + 1, 16 ); - } - - return( 0 ); -} -#endif /*MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR buffer encryption/decryption - */ -int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, - size_t length, - size_t *nc_off, - unsigned char nonce_counter[16], - unsigned char stream_block[16], - const unsigned char *input, - unsigned char *output ) -{ - int c, i; - size_t n = *nc_off; - - while( length-- ) - { - if( n == 0 ) { - mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block ); - - for( i = 16; i > 0; i-- ) - if( ++nonce_counter[i - 1] != 0 ) - break; - } - c = *input++; - *output++ = (unsigned char)( c ^ stream_block[n] ); - - n = ( n + 1 ) & 0x0F; - } - - *nc_off = n; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#endif /* !MBEDTLS_AES_ALT */ - -#if defined(MBEDTLS_SELF_TEST) -/* - * AES test vectors from: - * - * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip - */ -static const unsigned char aes_test_ecb_dec[3][16] = -{ - { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, - 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, - { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, - 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, - { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, - 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } -}; - -static const unsigned char aes_test_ecb_enc[3][16] = -{ - { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, - 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, - { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, - 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, - { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, - 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const unsigned char aes_test_cbc_dec[3][16] = -{ - { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, - 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, - { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, - 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, - { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, - 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } -}; - -static const unsigned char aes_test_cbc_enc[3][16] = -{ - { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, - 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, - { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, - 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, - { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, - 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -/* - * AES-CFB128 test vectors from: - * - * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf - */ -static const unsigned char aes_test_cfb128_key[3][32] = -{ - { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, - { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, - 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, - 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, - { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, - 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, - 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, - 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } -}; - -static const unsigned char aes_test_cfb128_iv[16] = -{ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F -}; - -static const unsigned char aes_test_cfb128_pt[64] = -{ - 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, - 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, - 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, - 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, - 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, - 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, - 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, - 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 -}; - -static const unsigned char aes_test_cfb128_ct[3][64] = -{ - { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, - 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, - 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, - 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, - 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, - 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, - 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, - 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, - { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, - 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, - 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, - 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, - 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, - 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, - 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, - 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, - { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, - 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, - 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, - 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, - 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, - 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, - 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, - 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -/* - * AES-CTR test vectors from: - * - * http://www.faqs.org/rfcs/rfc3686.html - */ - -static const unsigned char aes_test_ctr_key[3][16] = -{ - { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, - 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, - { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, - 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, - { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, - 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } -}; - -static const unsigned char aes_test_ctr_nonce_counter[3][16] = -{ - { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, - 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, - { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, - 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } -}; - -static const unsigned char aes_test_ctr_pt[3][48] = -{ - { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, - 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, - - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23 } -}; - -static const unsigned char aes_test_ctr_ct[3][48] = -{ - { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, - 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, - { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, - 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, - 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, - 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, - { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, - 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, - 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, - 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, - 0x25, 0xB2, 0x07, 0x2F } -}; - -static const int aes_test_ctr_len[3] = - { 16, 32, 36 }; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -/* - * Checkup routine - */ -int mbedtls_aes_self_test( int verbose ) -{ - int ret = 0, i, j, u, v; - unsigned char key[32]; - unsigned char buf[64]; -#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) - unsigned char iv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CBC) - unsigned char prv[16]; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) - size_t offset; -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - int len; - unsigned char nonce_counter[16]; - unsigned char stream_block[16]; -#endif - mbedtls_aes_context ctx; - - memset( key, 0, 32 ); - mbedtls_aes_init( &ctx ); - - /* - * ECB mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, - ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( buf, 0, 16 ); - - if( v == MBEDTLS_AES_DECRYPT ) - { - mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); - - for( j = 0; j < 10000; j++ ) - mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); - - if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - } - else - { - mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); - - for( j = 0; j < 10000; j++ ) - mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); - - if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - /* - * CBC mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, - ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memset( iv , 0, 16 ); - memset( prv, 0, 16 ); - memset( buf, 0, 16 ); - - if( v == MBEDTLS_AES_DECRYPT ) - { - mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); - - for( j = 0; j < 10000; j++ ) - mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); - - if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - } - else - { - mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); - - for( j = 0; j < 10000; j++ ) - { - unsigned char tmp[16]; - - mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); - - memcpy( tmp, prv, 16 ); - memcpy( prv, buf, 16 ); - memcpy( buf, tmp, 16 ); - } - - if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - /* - * CFB128 mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, - ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( iv, aes_test_cfb128_iv, 16 ); - memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); - - offset = 0; - mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); - - if( v == MBEDTLS_AES_DECRYPT ) - { - memcpy( buf, aes_test_cfb128_ct[u], 64 ); - mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); - - if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - } - else - { - memcpy( buf, aes_test_cfb128_pt, 64 ); - mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); - - if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - /* - * CTR mode - */ - for( i = 0; i < 6; i++ ) - { - u = i >> 1; - v = i & 1; - - if( verbose != 0 ) - mbedtls_printf( " AES-CTR-128 (%s): ", - ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); - - memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); - memcpy( key, aes_test_ctr_key[u], 16 ); - - offset = 0; - mbedtls_aes_setkey_enc( &ctx, key, 128 ); - - if( v == MBEDTLS_AES_DECRYPT ) - { - len = aes_test_ctr_len[u]; - memcpy( buf, aes_test_ctr_ct[u], len ); - - mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, - buf, buf ); - - if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - } - else - { - len = aes_test_ctr_len[u]; - memcpy( buf, aes_test_ctr_pt[u], len ); - - mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, - buf, buf ); - - if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - ret = 1; - goto exit; - } - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - if( verbose != 0 ) - mbedtls_printf( "\n" ); -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - - ret = 0; - -exit: - mbedtls_aes_free( &ctx ); - - return( ret ); -} - -#endif /* MBEDTLS_SELF_TEST */ - -#endif /* MBEDTLS_AES_C */ diff --git a/lib/mbedtls/src/ccm.c b/lib/mbedtls/src/ccm.c deleted file mode 100644 index 13a8fd1a2..000000000 --- a/lib/mbedtls/src/ccm.c +++ /dev/null @@ -1,464 +0,0 @@ -/* - * NIST SP800-38C compliant CCM implementation - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -/* - * Definition of CCM: - * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf - * RFC 3610 "Counter with CBC-MAC (CCM)" - * - * Related: - * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CCM_C) - -#include "mbedtls/ccm.h" - -#include - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_printf printf -#endif /* MBEDTLS_PLATFORM_C */ -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; -} - -#define CCM_ENCRYPT 0 -#define CCM_DECRYPT 1 - -/* - * Initialize context - */ -void mbedtls_ccm_init( mbedtls_ccm_context *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_ccm_context ) ); -} - -int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, - mbedtls_cipher_id_t cipher, - const unsigned char *key, - unsigned int keybits ) -{ - int ret; - const mbedtls_cipher_info_t *cipher_info; - - cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); - if( cipher_info == NULL ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - if( cipher_info->block_size != 16 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - mbedtls_cipher_free( &ctx->cipher_ctx ); - - if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, - MBEDTLS_ENCRYPT ) ) != 0 ) - { - return( ret ); - } - - return( 0 ); -} - -/* - * Free context - */ -void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) -{ - mbedtls_cipher_free( &ctx->cipher_ctx ); - mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); -} - -/* - * Macros for common operations. - * Results in smaller compiled code than static inline functions. - */ - -/* - * Update the CBC-MAC state in y using a block in b - * (Always using b as the source helps the compiler optimise a bit better.) - */ -#define UPDATE_CBC_MAC \ - for( i = 0; i < 16; i++ ) \ - y[i] ^= b[i]; \ - \ - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ - return( ret ); - -/* - * Encrypt or decrypt a partial block with CTR - * Warning: using b for temporary storage! src and dst must not be b! - * This avoids allocating one more 16 bytes buffer while allowing src == dst. - */ -#define CTR_CRYPT( dst, src, len ) \ - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ - return( ret ); \ - \ - for( i = 0; i < len; i++ ) \ - dst[i] = src[i] ^ b[i]; - -/* - * Authenticated encryption or decryption - */ -static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ) -{ - int ret; - unsigned char i; - unsigned char q; - size_t len_left, olen; - unsigned char b[16]; - unsigned char y[16]; - unsigned char ctr[16]; - const unsigned char *src; - unsigned char *dst; - - /* - * Check length requirements: SP800-38C A.1 - * Additional requirement: a < 2^16 - 2^8 to simplify the code. - * 'length' checked later (when writing it to the first block) - */ - if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - /* Also implies q is within bounds */ - if( iv_len < 7 || iv_len > 13 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - if( add_len > 0xFF00 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - q = 16 - 1 - (unsigned char) iv_len; - - /* - * First block B_0: - * 0 .. 0 flags - * 1 .. iv_len nonce (aka iv) - * iv_len+1 .. 15 length - * - * With flags as (bits): - * 7 0 - * 6 add present? - * 5 .. 3 (t - 2) / 2 - * 2 .. 0 q - 1 - */ - b[0] = 0; - b[0] |= ( add_len > 0 ) << 6; - b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; - b[0] |= q - 1; - - memcpy( b + 1, iv, iv_len ); - - for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) - b[15-i] = (unsigned char)( len_left & 0xFF ); - - if( len_left > 0 ) - return( MBEDTLS_ERR_CCM_BAD_INPUT ); - - - /* Start CBC-MAC with first block */ - memset( y, 0, 16 ); - UPDATE_CBC_MAC; - - /* - * If there is additional data, update CBC-MAC with - * add_len, add, 0 (padding to a block boundary) - */ - if( add_len > 0 ) - { - size_t use_len; - len_left = add_len; - src = add; - - memset( b, 0, 16 ); - b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); - b[1] = (unsigned char)( ( add_len ) & 0xFF ); - - use_len = len_left < 16 - 2 ? len_left : 16 - 2; - memcpy( b + 2, src, use_len ); - len_left -= use_len; - src += use_len; - - UPDATE_CBC_MAC; - - while( len_left > 0 ) - { - use_len = len_left > 16 ? 16 : len_left; - - memset( b, 0, 16 ); - memcpy( b, src, use_len ); - UPDATE_CBC_MAC; - - len_left -= use_len; - src += use_len; - } - } - - /* - * Prepare counter block for encryption: - * 0 .. 0 flags - * 1 .. iv_len nonce (aka iv) - * iv_len+1 .. 15 counter (initially 1) - * - * With flags as (bits): - * 7 .. 3 0 - * 2 .. 0 q - 1 - */ - ctr[0] = q - 1; - memcpy( ctr + 1, iv, iv_len ); - memset( ctr + 1 + iv_len, 0, q ); - ctr[15] = 1; - - /* - * Authenticate and {en,de}crypt the message. - * - * The only difference between encryption and decryption is - * the respective order of authentication and {en,de}cryption. - */ - len_left = length; - src = input; - dst = output; - - while( len_left > 0 ) - { - size_t use_len = len_left > 16 ? 16 : len_left; - - if( mode == CCM_ENCRYPT ) - { - memset( b, 0, 16 ); - memcpy( b, src, use_len ); - UPDATE_CBC_MAC; - } - - CTR_CRYPT( dst, src, use_len ); - - if( mode == CCM_DECRYPT ) - { - memset( b, 0, 16 ); - memcpy( b, dst, use_len ); - UPDATE_CBC_MAC; - } - - dst += use_len; - src += use_len; - len_left -= use_len; - - /* - * Increment counter. - * No need to check for overflow thanks to the length check above. - */ - for( i = 0; i < q; i++ ) - if( ++ctr[15-i] != 0 ) - break; - } - - /* - * Authentication: reset counter and crypt/mask internal tag - */ - for( i = 0; i < q; i++ ) - ctr[15-i] = 0; - - CTR_CRYPT( y, y, 16 ); - memcpy( tag, y, tag_len ); - - return( 0 ); -} - -/* - * Authenticated encryption - */ -int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - unsigned char *tag, size_t tag_len ) -{ - return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, - add, add_len, input, output, tag, tag_len ) ); -} - -/* - * Authenticated decryption - */ -int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, - const unsigned char *iv, size_t iv_len, - const unsigned char *add, size_t add_len, - const unsigned char *input, unsigned char *output, - const unsigned char *tag, size_t tag_len ) -{ - int ret; - unsigned char check_tag[16]; - unsigned char i; - int diff; - - if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, - iv, iv_len, add, add_len, - input, output, check_tag, tag_len ) ) != 0 ) - { - return( ret ); - } - - /* Check tag in "constant-time" */ - for( diff = 0, i = 0; i < tag_len; i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) - { - mbedtls_zeroize( output, length ); - return( MBEDTLS_ERR_CCM_AUTH_FAILED ); - } - - return( 0 ); -} - - -#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) -/* - * Examples 1 to 3 from SP800-38C Appendix C - */ - -#define NB_TESTS 3 - -/* - * The data is the same for all tests, only the used length changes - */ -static const unsigned char key[] = { - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f -}; - -static const unsigned char iv[] = { - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b -}; - -static const unsigned char ad[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13 -}; - -static const unsigned char msg[] = { - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -}; - -static const size_t iv_len [NB_TESTS] = { 7, 8, 12 }; -static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; -static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; -static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; - -static const unsigned char res[NB_TESTS][32] = { - { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, - { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, - 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, - 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, - { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, - 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, - 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, - 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } -}; - -int mbedtls_ccm_self_test( int verbose ) -{ - mbedtls_ccm_context ctx; - unsigned char out[32]; - size_t i; - int ret; - - mbedtls_ccm_init( &ctx ); - - if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( " CCM: setup failed" ); - - return( 1 ); - } - - for( i = 0; i < NB_TESTS; i++ ) - { - if( verbose != 0 ) - mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); - - ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i], - iv, iv_len[i], ad, add_len[i], - msg, out, - out + msg_len[i], tag_len[i] ); - - if( ret != 0 || - memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i], - iv, iv_len[i], ad, add_len[i], - res[i], out, - res[i] + msg_len[i], tag_len[i] ); - - if( ret != 0 || - memcmp( out, msg, msg_len[i] ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - mbedtls_printf( "passed\n" ); - } - - mbedtls_ccm_free( &ctx ); - - if( verbose != 0 ) - mbedtls_printf( "\n" ); - - return( 0 ); -} - -#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ - -#endif /* MBEDTLS_CCM_C */ diff --git a/lib/mbedtls/src/cipher.c b/lib/mbedtls/src/cipher.c deleted file mode 100644 index a88343869..000000000 --- a/lib/mbedtls/src/cipher.c +++ /dev/null @@ -1,917 +0,0 @@ -/** - * \file cipher.c - * - * \brief Generic cipher wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CIPHER_C) - -#include "mbedtls/cipher.h" -#include "mbedtls/cipher_internal.h" - -#include -#include - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CMAC_C) -#include "mbedtls/cmac.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) -#define MBEDTLS_CIPHER_MODE_STREAM -#endif - -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; -} - -static int supported_init = 0; - -const int *mbedtls_cipher_list( void ) -{ - const mbedtls_cipher_definition_t *def; - int *type; - - if( ! supported_init ) - { - def = mbedtls_cipher_definitions; - type = mbedtls_cipher_supported; - - while( def->type != 0 ) - *type++ = (*def++).type; - - *type = 0; - - supported_init = 1; - } - - return( mbedtls_cipher_supported ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ) -{ - const mbedtls_cipher_definition_t *def; - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( def->type == cipher_type ) - return( def->info ); - - return( NULL ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ) -{ - const mbedtls_cipher_definition_t *def; - - if( NULL == cipher_name ) - return( NULL ); - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( ! strcmp( def->info->name, cipher_name ) ) - return( def->info ); - - return( NULL ); -} - -const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, - int key_bitlen, - const mbedtls_cipher_mode_t mode ) -{ - const mbedtls_cipher_definition_t *def; - - for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) - if( def->info->base->cipher == cipher_id && - def->info->key_bitlen == (unsigned) key_bitlen && - def->info->mode == mode ) - return( def->info ); - - return( NULL ); -} - -void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) -{ - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); -} - -void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) -{ - if( ctx == NULL ) - return; - -#if defined(MBEDTLS_CMAC_C) - if( ctx->cmac_ctx ) - { - mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) ); - mbedtls_free( ctx->cmac_ctx ); - } -#endif - - if( ctx->cipher_ctx ) - ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); - - mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); -} - -int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) -{ - if( NULL == cipher_info || NULL == ctx ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); - - if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) - return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); - - ctx->cipher_info = cipher_info; - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) - /* - * Ignore possible errors caused by a cipher mode that doesn't use padding - */ -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); -#else - (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); -#endif -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - - return( 0 ); -} - -int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, - int key_bitlen, const mbedtls_operation_t operation ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && - (int) ctx->cipher_info->key_bitlen != key_bitlen ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - ctx->key_bitlen = key_bitlen; - ctx->operation = operation; - - /* - * For CFB and CTR mode always use the encryption key schedule - */ - if( MBEDTLS_ENCRYPT == operation || - MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) - { - return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, - ctx->key_bitlen ); - } - - if( MBEDTLS_DECRYPT == operation ) - return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, - ctx->key_bitlen ); - - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -} - -int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len ) -{ - size_t actual_iv_size; - - if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - /* avoid buffer overflow in ctx->iv */ - if( iv_len > MBEDTLS_MAX_IV_LENGTH ) - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - - if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) - actual_iv_size = iv_len; - else - { - actual_iv_size = ctx->cipher_info->iv_size; - - /* avoid reading past the end of input buffer */ - if( actual_iv_size > iv_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - memcpy( ctx->iv, iv, actual_iv_size ); - ctx->iv_size = actual_iv_size; - - return( 0 ); -} - -int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - ctx->unprocessed_len = 0; - - return( 0 ); -} - -#if defined(MBEDTLS_GCM_C) -int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, - const unsigned char *ad, size_t ad_len ) -{ - if( NULL == ctx || NULL == ctx->cipher_info ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, - ctx->iv, ctx->iv_size, ad, ad_len ); - } - - return( 0 ); -} -#endif /* MBEDTLS_GCM_C */ - -int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, - size_t ilen, unsigned char *output, size_t *olen ) -{ - int ret; - size_t block_size = 0; - - if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - *olen = 0; - block_size = mbedtls_cipher_get_block_size( ctx ); - - if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) - { - if( ilen != block_size ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - *olen = ilen; - - if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, - ctx->operation, input, output ) ) ) - { - return( ret ); - } - - return( 0 ); - } - -#if defined(MBEDTLS_GCM_C) - if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) - { - *olen = ilen; - return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, - output ); - } -#endif - - if ( 0 == block_size ) - { - return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; - } - - if( input == output && - ( ctx->unprocessed_len != 0 || ilen % block_size ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) - { - size_t copy_len = 0; - - /* - * If there is not enough data for a full block, cache it. - */ - if( ( ctx->operation == MBEDTLS_DECRYPT && - ilen + ctx->unprocessed_len <= block_size ) || - ( ctx->operation == MBEDTLS_ENCRYPT && - ilen + ctx->unprocessed_len < block_size ) ) - { - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, - ilen ); - - ctx->unprocessed_len += ilen; - return( 0 ); - } - - /* - * Process cached data first - */ - if( 0 != ctx->unprocessed_len ) - { - copy_len = block_size - ctx->unprocessed_len; - - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, - copy_len ); - - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, block_size, ctx->iv, - ctx->unprocessed_data, output ) ) ) - { - return( ret ); - } - - *olen += block_size; - output += block_size; - ctx->unprocessed_len = 0; - - input += copy_len; - ilen -= copy_len; - } - - /* - * Cache final, incomplete block - */ - if( 0 != ilen ) - { - if( 0 == block_size ) - { - return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; - } - - copy_len = ilen % block_size; - if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT ) - copy_len = block_size; - - memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), - copy_len ); - - ctx->unprocessed_len += copy_len; - ilen -= copy_len; - } - - /* - * Process remaining full blocks - */ - if( ilen ) - { - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, ilen, ctx->iv, input, output ) ) ) - { - return( ret ); - } - - *olen += ilen; - } - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) - { - if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, - ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, - input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) - if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) - { - if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, - ilen, &ctx->unprocessed_len, ctx->iv, - ctx->unprocessed_data, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) - { - if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, - ilen, input, output ) ) ) - { - return( ret ); - } - - *olen = ilen; - - return( 0 ); - } -#endif /* MBEDTLS_CIPHER_MODE_STREAM */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) -/* - * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len - */ -static void add_pkcs_padding( unsigned char *output, size_t output_len, - size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i; - - for( i = 0; i < padding_len; i++ ) - output[data_len + i] = (unsigned char) padding_len; -} - -static int get_pkcs_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i, pad_idx; - unsigned char padding_len, bad = 0; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - padding_len = input[input_len - 1]; - *data_len = input_len - padding_len; - - /* Avoid logical || since it results in a branch */ - bad |= padding_len > input_len; - bad |= padding_len == 0; - - /* The number of bytes checked must be independent of padding_len, - * so pick input_len, which is usually 8 or 16 (one block) */ - pad_idx = input_len - padding_len; - for( i = 0; i < input_len; i++ ) - bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); -} -#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ - -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) -/* - * One and zeros padding: fill with 80 00 ... 00 - */ -static void add_one_and_zeros_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - output[data_len] = 0x80; - for( i = 1; i < padding_len; i++ ) - output[data_len + i] = 0x00; -} - -static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i; - unsigned char done = 0, prev_done, bad; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - bad = 0xFF; - *data_len = 0; - for( i = input_len; i > 0; i-- ) - { - prev_done = done; - done |= ( input[i-1] != 0 ); - *data_len |= ( i - 1 ) * ( done != prev_done ); - bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); - } - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); - -} -#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) -/* - * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length - */ -static void add_zeros_and_len_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t padding_len = output_len - data_len; - unsigned char i = 0; - - for( i = 1; i < padding_len; i++ ) - output[data_len + i - 1] = 0x00; - output[output_len - 1] = (unsigned char) padding_len; -} - -static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i, pad_idx; - unsigned char padding_len, bad = 0; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - padding_len = input[input_len - 1]; - *data_len = input_len - padding_len; - - /* Avoid logical || since it results in a branch */ - bad |= padding_len > input_len; - bad |= padding_len == 0; - - /* The number of bytes checked must be independent of padding_len */ - pad_idx = input_len - padding_len; - for( i = 0; i < input_len - 1; i++ ) - bad |= input[i] * ( i >= pad_idx ); - - return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ - -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) -/* - * Zero padding: fill with 00 ... 00 - */ -static void add_zeros_padding( unsigned char *output, - size_t output_len, size_t data_len ) -{ - size_t i; - - for( i = data_len; i < output_len; i++ ) - output[i] = 0x00; -} - -static int get_zeros_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - size_t i; - unsigned char done = 0, prev_done; - - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *data_len = 0; - for( i = input_len; i > 0; i-- ) - { - prev_done = done; - done |= ( input[i-1] != 0 ); - *data_len |= i * ( done != prev_done ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ - -/* - * No padding: don't pad :) - * - * There is no add_padding function (check for NULL in mbedtls_cipher_finish) - * but a trivial get_padding function - */ -static int get_no_padding( unsigned char *input, size_t input_len, - size_t *data_len ) -{ - if( NULL == input || NULL == data_len ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *data_len = input_len; - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, - unsigned char *output, size_t *olen ) -{ - if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - *olen = 0; - - if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || - MBEDTLS_MODE_CTR == ctx->cipher_info->mode || - MBEDTLS_MODE_GCM == ctx->cipher_info->mode || - MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) - { - return( 0 ); - } - - if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) - { - if( ctx->unprocessed_len != 0 ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - return( 0 ); - } - -#if defined(MBEDTLS_CIPHER_MODE_CBC) - if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) - { - int ret = 0; - - if( MBEDTLS_ENCRYPT == ctx->operation ) - { - /* check for 'no padding' mode */ - if( NULL == ctx->add_padding ) - { - if( 0 != ctx->unprocessed_len ) - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - - return( 0 ); - } - - ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), - ctx->unprocessed_len ); - } - else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) - { - /* - * For decrypt operations, expect a full block, - * or an empty block if no padding - */ - if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) - return( 0 ); - - return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); - } - - /* cipher block */ - if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, - ctx->unprocessed_data, output ) ) ) - { - return( ret ); - } - - /* Set output size for decryption */ - if( MBEDTLS_DECRYPT == ctx->operation ) - return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), - olen ); - - /* Set output size for encryption */ - *olen = mbedtls_cipher_get_block_size( ctx ); - return( 0 ); - } -#else - ((void) output); -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) -int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ) -{ - if( NULL == ctx || - MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - switch( mode ) - { -#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) - case MBEDTLS_PADDING_PKCS7: - ctx->add_padding = add_pkcs_padding; - ctx->get_padding = get_pkcs_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) - case MBEDTLS_PADDING_ONE_AND_ZEROS: - ctx->add_padding = add_one_and_zeros_padding; - ctx->get_padding = get_one_and_zeros_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) - case MBEDTLS_PADDING_ZEROS_AND_LEN: - ctx->add_padding = add_zeros_and_len_padding; - ctx->get_padding = get_zeros_and_len_padding; - break; -#endif -#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) - case MBEDTLS_PADDING_ZEROS: - ctx->add_padding = add_zeros_padding; - ctx->get_padding = get_zeros_padding; - break; -#endif - case MBEDTLS_PADDING_NONE: - ctx->add_padding = NULL; - ctx->get_padding = get_no_padding; - break; - - default: - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); - } - - return( 0 ); -} -#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ - -#if defined(MBEDTLS_GCM_C) -int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, - unsigned char *tag, size_t tag_len ) -{ - if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_ENCRYPT != ctx->operation ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); - - return( 0 ); -} - -int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, - const unsigned char *tag, size_t tag_len ) -{ - int ret; - - if( NULL == ctx || NULL == ctx->cipher_info || - MBEDTLS_DECRYPT != ctx->operation ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - unsigned char check_tag[16]; - size_t i; - int diff; - - if( tag_len > sizeof( check_tag ) ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, - check_tag, tag_len ) ) ) - { - return( ret ); - } - - /* Check the tag in "constant-time" */ - for( diff = 0, i = 0; i < tag_len; i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - - return( 0 ); - } - - return( 0 ); -} -#endif /* MBEDTLS_GCM_C */ - -/* - * Packet-oriented wrapper for non-AEAD modes - */ -int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen ) -{ - int ret; - size_t finish_olen; - - if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) - return( ret ); - - if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) - return( ret ); - - *olen += finish_olen; - - return( 0 ); -} - -#if defined(MBEDTLS_CIPHER_MODE_AEAD) -/* - * Packet-oriented encryption for AEAD modes - */ -int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - unsigned char *tag, size_t tag_len ) -{ -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - *olen = ilen; - return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, - iv, iv_len, ad, ad_len, input, output, - tag_len, tag ) ); - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) - { - *olen = ilen; - return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, input, output, - tag, tag_len ) ); - } -#endif /* MBEDTLS_CCM_C */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} - -/* - * Packet-oriented decryption for AEAD modes - */ -int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, - const unsigned char *iv, size_t iv_len, - const unsigned char *ad, size_t ad_len, - const unsigned char *input, size_t ilen, - unsigned char *output, size_t *olen, - const unsigned char *tag, size_t tag_len ) -{ -#if defined(MBEDTLS_GCM_C) - if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) - { - int ret; - - *olen = ilen; - ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - tag, tag_len, input, output ); - - if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_CCM_C) - if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) - { - int ret; - - *olen = ilen; - ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, - iv, iv_len, ad, ad_len, - input, output, tag, tag_len ); - - if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) - ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - - return( ret ); - } -#endif /* MBEDTLS_CCM_C */ - - return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); -} -#endif /* MBEDTLS_CIPHER_MODE_AEAD */ - -#endif /* MBEDTLS_CIPHER_C */ diff --git a/lib/mbedtls/src/cipher_wrap.c b/lib/mbedtls/src/cipher_wrap.c deleted file mode 100644 index dc76af8ff..000000000 --- a/lib/mbedtls/src/cipher_wrap.c +++ /dev/null @@ -1,1451 +0,0 @@ -/** - * \file cipher_wrap.c - * - * \brief Generic cipher wrapper for mbed TLS - * - * \author Adriaan de Jong - * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * This file is part of mbed TLS (https://tls.mbed.org) - */ - -#if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#if defined(MBEDTLS_CIPHER_C) - -#include "mbedtls/cipher_internal.h" - -#if defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" -#endif - -#if defined(MBEDTLS_ARC4_C) -#include "mbedtls/arc4.h" -#endif - -#if defined(MBEDTLS_CAMELLIA_C) -#include "mbedtls/camellia.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_BLOWFISH_C) -#include "mbedtls/blowfish.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -#include -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - -#if defined(MBEDTLS_GCM_C) -/* shared by all GCM ciphers */ -static void *gcm_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); - - if( ctx != NULL ) - mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); - - return( ctx ); -} - -static void gcm_ctx_free( void *ctx ) -{ - mbedtls_gcm_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -/* shared by all CCM ciphers */ -static void *ccm_ctx_alloc( void ) -{ - void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); - - if( ctx != NULL ) - mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); - - return( ctx ); -} - -static void ccm_ctx_free( void *ctx ) -{ - mbedtls_ccm_free( ctx ); - mbedtls_free( ctx ); -} -#endif /* MBEDTLS_CCM_C */ - -#if defined(MBEDTLS_AES_C) - -static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, - stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); -} - -static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); -} - -static void * aes_ctx_alloc( void ) -{ - mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); - - if( aes == NULL ) - return( NULL ); - - mbedtls_aes_init( aes ); - - return( aes ); -} - -static void aes_ctx_free( void *ctx ) -{ - mbedtls_aes_free( (mbedtls_aes_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t aes_info = { - MBEDTLS_CIPHER_ID_AES, - aes_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - aes_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - aes_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - aes_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - aes_setkey_enc_wrap, - aes_setkey_dec_wrap, - aes_ctx_alloc, - aes_ctx_free -}; - -static const mbedtls_cipher_info_t aes_128_ecb_info = { - MBEDTLS_CIPHER_AES_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "AES-128-ECB", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ecb_info = { - MBEDTLS_CIPHER_AES_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "AES-192-ECB", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ecb_info = { - MBEDTLS_CIPHER_AES_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "AES-256-ECB", - 16, - 0, - 16, - &aes_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aes_128_cbc_info = { - MBEDTLS_CIPHER_AES_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "AES-128-CBC", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_cbc_info = { - MBEDTLS_CIPHER_AES_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "AES-192-CBC", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_cbc_info = { - MBEDTLS_CIPHER_AES_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "AES-256-CBC", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aes_128_cfb128_info = { - MBEDTLS_CIPHER_AES_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "AES-128-CFB128", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_cfb128_info = { - MBEDTLS_CIPHER_AES_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "AES-192-CFB128", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_cfb128_info = { - MBEDTLS_CIPHER_AES_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "AES-256-CFB128", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aes_128_ctr_info = { - MBEDTLS_CIPHER_AES_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "AES-128-CTR", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ctr_info = { - MBEDTLS_CIPHER_AES_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "AES-192-CTR", - 16, - 0, - 16, - &aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ctr_info = { - MBEDTLS_CIPHER_AES_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "AES-256-CTR", - 16, - 0, - 16, - &aes_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_aes_setkey_wrap, - gcm_aes_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_gcm_info = { - MBEDTLS_CIPHER_AES_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "AES-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_gcm_info = { - MBEDTLS_CIPHER_AES_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "AES-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_gcm_info = { - MBEDTLS_CIPHER_AES_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "AES-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_aes_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_aes_info = { - MBEDTLS_CIPHER_ID_AES, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_aes_setkey_wrap, - ccm_aes_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t aes_128_ccm_info = { - MBEDTLS_CIPHER_AES_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "AES-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const mbedtls_cipher_info_t aes_192_ccm_info = { - MBEDTLS_CIPHER_AES_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "AES-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; - -static const mbedtls_cipher_info_t aes_256_ccm_info = { - MBEDTLS_CIPHER_AES_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "AES-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_aes_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - -static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); -} - -static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); -} - -static void * camellia_ctx_alloc( void ) -{ - mbedtls_camellia_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_camellia_init( ctx ); - - return( ctx ); -} - -static void camellia_ctx_free( void *ctx ) -{ - mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - camellia_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - camellia_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - camellia_crypt_cfb128_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - camellia_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - camellia_setkey_enc_wrap, - camellia_setkey_dec_wrap, - camellia_ctx_alloc, - camellia_ctx_free -}; - -static const mbedtls_cipher_info_t camellia_128_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_128_ECB, - MBEDTLS_MODE_ECB, - 128, - "CAMELLIA-128-ECB", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_192_ECB, - MBEDTLS_MODE_ECB, - 192, - "CAMELLIA-192-ECB", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ecb_info = { - MBEDTLS_CIPHER_CAMELLIA_256_ECB, - MBEDTLS_MODE_ECB, - 256, - "CAMELLIA-256-ECB", - 16, - 0, - 16, - &camellia_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t camellia_128_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CBC, - MBEDTLS_MODE_CBC, - 128, - "CAMELLIA-128-CBC", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CBC, - MBEDTLS_MODE_CBC, - 192, - "CAMELLIA-192-CBC", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_cbc_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CBC, - MBEDTLS_MODE_CBC, - 256, - "CAMELLIA-256-CBC", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t camellia_128_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CFB128, - MBEDTLS_MODE_CFB, - 128, - "CAMELLIA-128-CFB128", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CFB128, - MBEDTLS_MODE_CFB, - 192, - "CAMELLIA-192-CFB128", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_cfb128_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CFB128, - MBEDTLS_MODE_CFB, - 256, - "CAMELLIA-256-CFB128", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t camellia_128_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CTR, - MBEDTLS_MODE_CTR, - 128, - "CAMELLIA-128-CTR", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CTR, - MBEDTLS_MODE_CTR, - 192, - "CAMELLIA-192-CTR", - 16, - 0, - 16, - &camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ctr_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CTR, - MBEDTLS_MODE_CTR, - 256, - "CAMELLIA-256-CTR", - 16, - 0, - 16, - &camellia_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -#if defined(MBEDTLS_GCM_C) -static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t gcm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - gcm_camellia_setkey_wrap, - gcm_camellia_setkey_wrap, - gcm_ctx_alloc, - gcm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_128_GCM, - MBEDTLS_MODE_GCM, - 128, - "CAMELLIA-128-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_192_GCM, - MBEDTLS_MODE_GCM, - 192, - "CAMELLIA-192-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_gcm_info = { - MBEDTLS_CIPHER_CAMELLIA_256_GCM, - MBEDTLS_MODE_GCM, - 256, - "CAMELLIA-256-GCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &gcm_camellia_info -}; -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_CCM_C) -static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, - key, key_bitlen ); -} - -static const mbedtls_cipher_base_t ccm_camellia_info = { - MBEDTLS_CIPHER_ID_CAMELLIA, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - ccm_camellia_setkey_wrap, - ccm_camellia_setkey_wrap, - ccm_ctx_alloc, - ccm_ctx_free, -}; - -static const mbedtls_cipher_info_t camellia_128_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_128_CCM, - MBEDTLS_MODE_CCM, - 128, - "CAMELLIA-128-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_192_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_192_CCM, - MBEDTLS_MODE_CCM, - 192, - "CAMELLIA-192-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; - -static const mbedtls_cipher_info_t camellia_256_ccm_info = { - MBEDTLS_CIPHER_CAMELLIA_256_CCM, - MBEDTLS_MODE_CCM, - 256, - "CAMELLIA-256-CCM", - 12, - MBEDTLS_CIPHER_VARIABLE_IV_LEN, - 16, - &ccm_camellia_info -}; -#endif /* MBEDTLS_CCM_C */ - -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) - -static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - ((void) operation); - return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); -} - -static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - ((void) operation); - return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, - unsigned char *iv, const unsigned char *input, unsigned char *output ) -{ - return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, - output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); -} - -static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); -} - -static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); -} - -static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) key_bitlen); - - return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); -} - -static void * des_ctx_alloc( void ) -{ - mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); - - if( des == NULL ) - return( NULL ); - - mbedtls_des_init( des ); - - return( des ); -} - -static void des_ctx_free( void *ctx ) -{ - mbedtls_des_free( (mbedtls_des_context *) ctx ); - mbedtls_free( ctx ); -} - -static void * des3_ctx_alloc( void ) -{ - mbedtls_des3_context *des3; - des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); - - if( des3 == NULL ) - return( NULL ); - - mbedtls_des3_init( des3 ); - - return( des3 ); -} - -static void des3_ctx_free( void *ctx ) -{ - mbedtls_des3_free( (mbedtls_des3_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t des_info = { - MBEDTLS_CIPHER_ID_DES, - des_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des_setkey_enc_wrap, - des_setkey_dec_wrap, - des_ctx_alloc, - des_ctx_free -}; - -static const mbedtls_cipher_info_t des_ecb_info = { - MBEDTLS_CIPHER_DES_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES, - "DES-ECB", - 8, - 0, - 8, - &des_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_cbc_info = { - MBEDTLS_CIPHER_DES_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES, - "DES-CBC", - 8, - 0, - 8, - &des_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede_info = { - MBEDTLS_CIPHER_ID_DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set2key_enc_wrap, - des3_set2key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede_ecb_info = { - MBEDTLS_CIPHER_DES_EDE_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES_EDE, - "DES-EDE-ECB", - 8, - 0, - 8, - &des_ede_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede_cbc_info = { - MBEDTLS_CIPHER_DES_EDE_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES_EDE, - "DES-EDE-CBC", - 8, - 0, - 8, - &des_ede_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -static const mbedtls_cipher_base_t des_ede3_info = { - MBEDTLS_CIPHER_ID_3DES, - des3_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - des3_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - des3_set3key_enc_wrap, - des3_set3key_dec_wrap, - des3_ctx_alloc, - des3_ctx_free -}; - -static const mbedtls_cipher_info_t des_ede3_ecb_info = { - MBEDTLS_CIPHER_DES_EDE3_ECB, - MBEDTLS_MODE_ECB, - MBEDTLS_KEY_LENGTH_DES_EDE3, - "DES-EDE3-ECB", - 8, - 0, - 8, - &des_ede3_info -}; -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede3_cbc_info = { - MBEDTLS_CIPHER_DES_EDE3_CBC, - MBEDTLS_MODE_CBC, - MBEDTLS_KEY_LENGTH_DES_EDE3, - "DES-EDE3-CBC", - 8, - 0, - 8, - &des_ede3_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_BLOWFISH_C) - -static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, - output ); -} - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, unsigned char *iv, const unsigned char *input, - unsigned char *output ) -{ - return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, - input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, - size_t length, size_t *iv_off, unsigned char *iv, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, - iv_off, iv, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, - unsigned char *nonce_counter, unsigned char *stream_block, - const unsigned char *input, unsigned char *output ) -{ - return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, - nonce_counter, stream_block, input, output ); -} -#endif /* MBEDTLS_CIPHER_MODE_CTR */ - -static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); -} - -static void * blowfish_ctx_alloc( void ) -{ - mbedtls_blowfish_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_blowfish_init( ctx ); - - return( ctx ); -} - -static void blowfish_ctx_free( void *ctx ) -{ - mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t blowfish_info = { - MBEDTLS_CIPHER_ID_BLOWFISH, - blowfish_crypt_ecb_wrap, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - blowfish_crypt_cbc_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - blowfish_crypt_cfb64_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - blowfish_crypt_ctr_wrap, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, -#endif - blowfish_setkey_wrap, - blowfish_setkey_wrap, - blowfish_ctx_alloc, - blowfish_ctx_free -}; - -static const mbedtls_cipher_info_t blowfish_ecb_info = { - MBEDTLS_CIPHER_BLOWFISH_ECB, - MBEDTLS_MODE_ECB, - 128, - "BLOWFISH-ECB", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; - -#if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t blowfish_cbc_info = { - MBEDTLS_CIPHER_BLOWFISH_CBC, - MBEDTLS_MODE_CBC, - 128, - "BLOWFISH-CBC", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CBC */ - -#if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t blowfish_cfb64_info = { - MBEDTLS_CIPHER_BLOWFISH_CFB64, - MBEDTLS_MODE_CFB, - 128, - "BLOWFISH-CFB64", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CFB */ - -#if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t blowfish_ctr_info = { - MBEDTLS_CIPHER_BLOWFISH_CTR, - MBEDTLS_MODE_CTR, - 128, - "BLOWFISH-CTR", - 8, - MBEDTLS_CIPHER_VARIABLE_KEY_LEN, - 8, - &blowfish_info -}; -#endif /* MBEDTLS_CIPHER_MODE_CTR */ -#endif /* MBEDTLS_BLOWFISH_C */ - -#if defined(MBEDTLS_ARC4_C) -static int arc4_crypt_stream_wrap( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); -} - -static int arc4_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - /* we get key_bitlen in bits, arc4 expects it in bytes */ - if( key_bitlen % 8 != 0 ) - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - - mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); - return( 0 ); -} - -static void * arc4_ctx_alloc( void ) -{ - mbedtls_arc4_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); - - if( ctx == NULL ) - return( NULL ); - - mbedtls_arc4_init( ctx ); - - return( ctx ); -} - -static void arc4_ctx_free( void *ctx ) -{ - mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); - mbedtls_free( ctx ); -} - -static const mbedtls_cipher_base_t arc4_base_info = { - MBEDTLS_CIPHER_ID_ARC4, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - arc4_crypt_stream_wrap, -#endif - arc4_setkey_wrap, - arc4_setkey_wrap, - arc4_ctx_alloc, - arc4_ctx_free -}; - -static const mbedtls_cipher_info_t arc4_128_info = { - MBEDTLS_CIPHER_ARC4_128, - MBEDTLS_MODE_STREAM, - 128, - "ARC4-128", - 0, - 0, - 1, - &arc4_base_info -}; -#endif /* MBEDTLS_ARC4_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) -static int null_crypt_stream( void *ctx, size_t length, - const unsigned char *input, - unsigned char *output ) -{ - ((void) ctx); - memmove( output, input, length ); - return( 0 ); -} - -static int null_setkey( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) -{ - ((void) ctx); - ((void) key); - ((void) key_bitlen); - - return( 0 ); -} - -static void * null_ctx_alloc( void ) -{ - return( (void *) 1 ); -} - -static void null_ctx_free( void *ctx ) -{ - ((void) ctx); -} - -static const mbedtls_cipher_base_t null_base_info = { - MBEDTLS_CIPHER_ID_NULL, - NULL, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - NULL, -#endif -#if defined(MBEDTLS_CIPHER_MODE_STREAM) - null_crypt_stream, -#endif - null_setkey, - null_setkey, - null_ctx_alloc, - null_ctx_free -}; - -static const mbedtls_cipher_info_t null_cipher_info = { - MBEDTLS_CIPHER_NULL, - MBEDTLS_MODE_STREAM, - 0, - "NULL", - 0, - 0, - 1, - &null_base_info -}; -#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ - -const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = -{ -#if defined(MBEDTLS_AES_C) - { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, - { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, - { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, - { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, - { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, - { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, - { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, - { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, - { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, - { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, - { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, - { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, - { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, -#endif -#endif /* MBEDTLS_AES_C */ - -#if defined(MBEDTLS_ARC4_C) - { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, -#endif - -#if defined(MBEDTLS_BLOWFISH_C) - { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, -#endif -#endif /* MBEDTLS_BLOWFISH_C */ - -#if defined(MBEDTLS_CAMELLIA_C) - { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CFB) - { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, -#endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) - { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, -#endif -#if defined(MBEDTLS_GCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, -#endif -#if defined(MBEDTLS_CCM_C) - { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, - { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, -#endif -#endif /* MBEDTLS_CAMELLIA_C */ - -#if defined(MBEDTLS_DES_C) - { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, - { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, -#if defined(MBEDTLS_CIPHER_MODE_CBC) - { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, - { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, -#endif -#endif /* MBEDTLS_DES_C */ - -#if defined(MBEDTLS_CIPHER_NULL_CIPHER) - { MBEDTLS_CIPHER_NULL, &null_cipher_info }, -#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ - - { MBEDTLS_CIPHER_NONE, NULL } -}; - -#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0] -int mbedtls_cipher_supported[NUM_CIPHERS]; - -#endif /* MBEDTLS_CIPHER_C */ From 6363e2fa96764c5d608a7377b414f04e9aa18c20 Mon Sep 17 00:00:00 2001 From: Staars Date: Wed, 24 Jun 2020 16:20:07 +0200 Subject: [PATCH 340/581] remove legacy code --- tasmota/xdrv_33_nrf24l01.ino | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tasmota/xdrv_33_nrf24l01.ino b/tasmota/xdrv_33_nrf24l01.ino index 442bcb4db..7b8f173f9 100644 --- a/tasmota/xdrv_33_nrf24l01.ino +++ b/tasmota/xdrv_33_nrf24l01.ino @@ -21,6 +21,7 @@ Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.0.1 20200624 changes - removed unused legacy code --- 0.9.0.0 20191127 started - further development by Christian Baars forked - from arendst/tasmota - https://github.com/arendst/Tasmota @@ -38,18 +39,10 @@ #define XDRV_33 33 -#define MOSI 13 -#define MISO 12 -#define SCK 14 - -#include #include const char NRF24type[] PROGMEM = "NRF24"; -const char HTTP_NRF24[] PROGMEM = - "{s}%sL01%c: " "{m}started{e}"; - struct { uint8_t chipType = 0; // NRF24l01 active: 32 - NRF24L01 , 43- NRF24L01+ ... we mis-use ascii-codes } NRF24; @@ -74,7 +67,6 @@ bool NRF24initRadio() bool NRF24Detect(void) { if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC)) { - SPI.pins(SCK,MOSI,MISO,-1); if(NRF24initRadio()){ NRF24.chipType = 32; // SPACE AddLog_P2(LOG_LEVEL_INFO,PSTR("NRF24L01 initialized")); From 80729a85ad211a3abe28db6a49ef284573382c62 Mon Sep 17 00:00:00 2001 From: Staars Date: Wed, 24 Jun 2020 16:21:09 +0200 Subject: [PATCH 341/581] fix BEARSSL-decryption, remove MBEDTLS, prepare night light sensors --- tasmota/xsns_61_MI_NRF24.ino | 183 ++++++++++++++++++++++++----------- 1 file changed, 126 insertions(+), 57 deletions(-) diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index 685c643ef..c1aa1f4b4 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -21,6 +21,8 @@ Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.7.0 20200624 integrate - use BEARSSL-lib for decryption as default, make decryption optional + --- 0.9.6.1 20200622 integrate - use BEARSSL-lib for decryption as default, make decryption optional --- 0.9.6.0 20200618 integrate - add decryption for LYWSD03 @@ -56,7 +58,6 @@ #endif #define USE_MI_DECRYPTION -// #define USE_MBEDTLS /*********************************************************************************************\ * MINRF * BLE-Sniffer/Bridge for MIJIA/XIAOMI Temperatur/Humidity-Sensor, Mi Flora, LYWSD02, GCx @@ -68,12 +69,7 @@ #include #ifdef USE_MI_DECRYPTION -#ifdef USE_MBEDTLS -#include -#else #include -#include -#endif // USE_MBEDTLS #endif //USE_MI_DECRYPTION #define FLORA 1 @@ -82,12 +78,16 @@ #define LYWSD03 4 #define CGG1 5 #define CGD1 6 +#define NLIGHT 7 +#define MJYD2S 8 + +#define MI_TYPES 8 //count this manually #define D_CMND_NRF "NRF" const char S_JSON_NRF_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_NRF "%s\":%d}"; const char S_JSON_NRF_COMMAND[] PROGMEM = "{\"" D_CMND_NRF "%s\":\"%s\"}"; -const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan" +const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan|Nlight" #ifdef USE_MI_DECRYPTION "|Key" #endif //USE_MI_DECRYPTION @@ -98,18 +98,21 @@ enum NRF_Commands { // commands useable in console or rules CMND_NRF_PAGE, // sensor entries per web page, which will be shown alternated CMND_NRF_SCAN, // simplified passive BLE adv scan CMND_NRF_BEACON, // even more simplified Beacon, reports time since last sighting - CMND_NRF_CHAN // ignore channel 0-2 (translates to 37-39) + CMND_NRF_CHAN, // ignore channel 0-2 (translates to 37-39) + CMND_NRF_NLIGHT // add Philips night light via MAC #ifdef USE_MI_DECRYPTION , CMND_NRF_KEY // add bind_key to a MAC for payload decryption #endif //USE_MI_DECRYPTION }; -const uint16_t kMINRFSlaveID[6]={ 0x0098, // Flora +const uint16_t kMINRFSlaveID[8]={ 0x0098, // Flora 0x01aa, // MJ_HT_V1 0x045b, // LYWSD02 0x055b, // LYWSD03 0x0347, // CGG1 - 0x0576 // CGD1 + 0x0576, // CGD1 + 0x03dd, // NLIGHT + 0x07f6 // MJYD2S }; const char kMINRFSlaveType1[] PROGMEM = "Flora"; @@ -118,7 +121,9 @@ const char kMINRFSlaveType3[] PROGMEM = "LYWSD02"; const char kMINRFSlaveType4[] PROGMEM = "LYWSD03"; const char kMINRFSlaveType5[] PROGMEM = "CGG1"; const char kMINRFSlaveType6[] PROGMEM = "CGD1"; -const char * kMINRFSlaveType[] PROGMEM = {kMINRFSlaveType1,kMINRFSlaveType2,kMINRFSlaveType3,kMINRFSlaveType4,kMINRFSlaveType5,kMINRFSlaveType6}; +const char kMINRFSlaveType7[] PROGMEM = "NLIGHT"; +const char kMINRFSlaveType8[] PROGMEM = "MJYD2S"; +const char * kMINRFSlaveType[] PROGMEM = {kMINRFSlaveType1,kMINRFSlaveType2,kMINRFSlaveType3,kMINRFSlaveType4,kMINRFSlaveType5,kMINRFSlaveType6,kMINRFSlaveType7,kMINRFSlaveType8}; // PDU's or different channels 37-39 const uint32_t kMINRFFloPDU[3] = {0x3eaa857d,0xef3b8730,0x71da7b46}; @@ -128,6 +133,7 @@ const uint32_t kMINRFL3PDU[3] = {0x4760dd78,0xdbcc1ccd,0x33049deb}; //encrypted // const uint32_t kMINRFL3PDU[3] = {0x4760cb78,0xdbcc0acd,0x33048beb}; //unencrypted - 30 58 const uint32_t kMINRFCGGPDU[3] = {0x4760cd6e,0xdbcc0cdb,0x33048dfd}; const uint32_t kMINRFCGDPDU[3] = {0x5da0d752,0xc10c16e7,0x29c497c1}; +// const uint32_t kMINRFNLIPDU[3] = {0x4760C56E,0xDBCC04DB,0x0330485FD}; //NLIGHT // start-LSFR for different channels 37-39 const uint8_t kMINRFlsfrList_A[3] = {0x4b,0x17,0x23}; // Flora, LYWSD02 @@ -212,13 +218,14 @@ struct { const uint8_t frequency[3] = { 2,26,80}; // real frequency (2400+x MHz) uint16_t timer; + uint16_t ignore = 0; //bitfield: 2^sensor type uint8_t currentChan=0; - uint8_t ignore = 0; //bitfield: 2^sensor type uint8_t channelIgnore = 0; //bitfield: 2^channel (0=37,1=38,2=39) uint8_t confirmedSensors = 0; uint8_t packetMode; // 0 - normal BLE-advertisements, 1 - 6 "special" sensor packets uint8_t perPage = 4; uint8_t firstUsedPacketMode = 1; + uint8_t activeNlight = 0; FIFO_t buffer; @@ -256,6 +263,17 @@ struct mi_sensor_t{ }; }; +struct mi_nlight_t{ + uint8_t MAC[6]; + uint32_t PDU[3]; + uint8_t type; // NLIGHT=7 + struct { + uint16_t events; //"alarms" since boot + uint8_t lastCnt; //device generated counter of the packet + }; +}; + + struct scan_entry_t { uint8_t mac[6]; uint16_t cid; @@ -269,6 +287,7 @@ std::vector MINRFscanResult; #ifdef USE_MI_DECRYPTION std::vector MIBLEbindKeys; #endif //USE_MI_DECRYPTION +std::vector MIBLEnlights; static union{ scan_entry_t MINRFdummyEntry; @@ -370,6 +389,9 @@ bool MINRFreceivePacket(void) case 6: MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "CGD1" mode break; + case 7: + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); // "NLIGHT" mode + break; } // DEBUG_SENSOR_LOG(PSTR("MINRF: LSFR:%x"),_lsfr); // if (_lsfr>254) _lsfr=0; @@ -598,24 +620,29 @@ void MINRFbeaconCounter(void){ * @brief compute "PDU" from MAC for each possible channel and store it globally * */ -void MINRFcomputeBeaconPDU(void){ +void MINRFcomputeBeaconPDU(uint8_t (&_mac)[6], uint32_t (&PDU)[3]){ + uint32_t _PDU[3]; for (uint32_t i = 0; i<3; i++){ bleAdvPacket_t packet; - memcpy((uint8_t *)&packet.mac, (uint8_t *)&MINRF.beacon.mac, sizeof(packet.mac)); + memcpy((uint8_t *)&packet.mac, (uint8_t *)&_mac, sizeof(packet.mac)); MINRFreverseMAC(packet.mac); MINRFwhiten((uint8_t *)&packet, sizeof(packet), MINRF.channel[i] | 0x40); MINRFswapbuf((uint8_t*)&packet,sizeof(packet)); uint32_t pdu = packet.mac[0]<<24 | packet.mac[1]<<16 | packet.mac[2]<<8 | packet.mac[3]; - MINRF.beacon.PDU[i] = pdu; + _PDU[i] = pdu; } + memcpy(PDU,_PDU,sizeof(_PDU)); } + #ifdef USE_MI_DECRYPTION int MINRFdecryptPacket(char *_buf){ encPacket_t *packet = (encPacket_t*)_buf; // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("to decrypt: %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" : %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" : %02x %02x %02x %02x %02x "),(uint8_t)_buf[16],(uint8_t)_buf[17],(uint8_t)_buf[18],(uint8_t)_buf[19],(uint8_t)_buf[20]); int ret = 0; - unsigned char output[10] = {0}; + unsigned char output[16] = {0}; uint8_t nonce[12]; const unsigned char authData[1] = {0x11}; @@ -640,33 +667,6 @@ int MINRFdecryptPacket(char *_buf){ // } } - #ifdef USE_MBEDTLS - // init - mbedtls_ccm_context ctx; - mbedtls_ccm_init(&ctx); - - // set bind key - ret = mbedtls_ccm_setkey(&ctx, - MBEDTLS_CIPHER_ID_AES, - _bindkey, - 16 * 8 //bits - ); - - ret = mbedtls_ccm_auth_decrypt(&ctx,5, - (const unsigned char*)&nonce, sizeof(nonce), - authData, sizeof(authData), - packet->payload.cipher, output, - packet->payload.tag,sizeof(packet->payload.tag)); - - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MBEDTLS: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, output[0],output[1],output[2],output[3],output[4]); - // put decrypted data in place - memcpy((uint8_t*)(packet->payload.cipher)+1,output,sizeof(packet->payload.cipher)); - // clean up - mbedtls_ccm_free(&ctx); - return ret; - - #else // BearSSL - memcpy(output,packet->payload.cipher, sizeof(packet->payload.cipher)); br_aes_small_ctrcbc_keys keyCtx; @@ -674,17 +674,15 @@ int MINRFdecryptPacket(char *_buf){ br_ccm_context ctx; br_ccm_init(&ctx, &keyCtx.vtable); - br_ccm_reset(&ctx, nonce, sizeof(nonce), sizeof(packet->payload.cipher), sizeof(authData), sizeof(packet->payload.tag)); + br_ccm_reset(&ctx, nonce, sizeof(nonce), sizeof(authData),sizeof(packet->payload.cipher),sizeof(packet->payload.tag)); br_ccm_aad_inject(&ctx, authData, sizeof(authData)); br_ccm_flip(&ctx); - br_ccm_run(&ctx, 0, output, sizeof(packet->payload.cipher)); + br_ccm_run(&ctx, 0, output, sizeof(packet->payload.cipher)); ret = br_ccm_check_tag(&ctx, packet->payload.tag); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("BEARSSL: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, output[0],output[1],output[2],output[3],output[4]); memcpy((uint8_t*)(packet->payload.cipher)+1,output,sizeof(packet->payload.cipher)); - return ret; - #endif //USE_MBEDTLS - + return (ret-1); } #endif //USE_MI_DECRYPTION @@ -771,11 +769,11 @@ void MINRFMACStringToBytes(char* _string, uint8_t _mac[]) { //uppercase * */ void MINRFcomputefirstUsedPacketMode(void){ - for (uint32_t i = 0; iCGD1) MINRF.firstUsedPacketMode=0; + if(MINRF.firstUsedPacketMode>MI_TYPES) MINRF.firstUsedPacketMode=0; break; } } @@ -812,6 +810,11 @@ void MINRFchangePacketModeTo(uint8_t _mode) { case 6: // special CGD1 packet NRF24radio.openReadingPipe(0,kMINRFCGDPDU[_nextchannel]); // cd fd 08 0c -> CGD1 break; + case 7: // MAC based NLIGHT packet + if (MIBLEnlights.size()==0) break; + NRF24radio.openReadingPipe(0,MIBLEnlights[MINRF.activeNlight].PDU[_nextchannel]); // computed from MAC -> NLIGHT + MINRF.activeNlight++; + break; } // DEBUG_SENSOR_LOG(PSTR("MINRF: Change Mode to %u"),_mode); MINRF.packetMode = _mode; @@ -1031,6 +1034,44 @@ void MINRFhandleCGD1Packet(void){ // no MiBeacon } } +void MINRFhandleNlightPacket(void){ // no MiBeacon + uint32_t offset = 6; + uint8_t _buf[32+offset]; + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); + MINRFswapbuf((uint8_t*)&MINRF.buffer,sizeof(MINRF.buffer)); + memcpy((uint8_t*)&_buf+offset,MINRF.buffer.raw,32); + MINRFswapbuf((uint8_t*)&_buf,sizeof(_buf)); + MINRFwhiten((uint8_t *)&_buf, sizeof(_buf), MINRF.channel[MINRF.currentChan] | 0x40); + if (offset == 6) MINRFreverseMAC((uint8_t*)&_buf[2]); + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"),_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6],_buf[7],_buf[8],_buf[9],_buf[10],_buf[11],_buf[12],_buf[13],_buf[14],_buf[15],_buf[16],_buf[17],_buf[18]); + uint32_t _frame_PID = _buf[15]<<24 | _buf[16]<<16 | _buf[17]<<8 | _buf[18]; + if(_frame_PID!=0x4030dd03) return; + AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT:%x"),_frame_PID); + uint32_t _idx = MINRF.activeNlight-1; + if(_buf[19]!=MIBLEnlights[_idx].lastCnt){ + MIBLEnlights[_idx].lastCnt = _buf[19]; + MIBLEnlights[_idx].events++; + AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT %u: events: %u, Cnt:%u"), _idx,MIBLEnlights[_idx].events, MIBLEnlights[_idx].lastCnt); + } +} + +void MINRFaddNlight(uint8_t _mac[]){ // no MiBeacon + for(uint32_t i=0; iCGD1) ? MINRF.firstUsedPacketMode : MINRF.packetMode+1; - for (uint32_t i = MINRF.packetMode; iMIBLEnlights.size()){ + MINRF.activeNlight=0; + MINRF.packetMode=MINRF.firstUsedPacketMode; + } + } + else{ + MINRF.packetMode = (MINRF.packetMode+1>MI_TYPES) ? MINRF.firstUsedPacketMode : MINRF.packetMode+1; + for (uint32_t i = MINRF.packetMode; i 0) { + if (XdrvMailbox.data_len==12){ // a MAC-string + uint8_t _mac[6] = {0}; + MINRFMACStringToBytes(XdrvMailbox.data, _mac); + Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); + MINRFaddNlight(_mac); + } } break; case CMND_NRF_CHAN: @@ -1302,6 +1364,13 @@ void MINRFShow(bool json) WSContentSend_PD(HTTP_MINRF_MAC, F("Beacon"), D_MAC_ADDRESS, MINRF.beacon.mac[0], MINRF.beacon.mac[1],MINRF.beacon.mac[2],MINRF.beacon.mac[3],MINRF.beacon.mac[4],MINRF.beacon.mac[5]); WSContentSend_PD(PSTR("{s}Beacon Time{m}%u seconds{e}"),MINRF.beacon.time); } + + for(uint32_t i=0; i3) { _page++; counter = 0; From faecd38006836018926186a7a6f39adadfe845f9 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 24 Jun 2020 16:37:02 +0200 Subject: [PATCH 342/581] Add compile time User Template Add compile time User Template (#8766) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/my_user_config.h | 2 ++ tasmota/settings.ino | 4 ++++ 4 files changed, 8 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 121e9e428..d8c865fdb 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -90,3 +90,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) - Add compile time interlock parameters (#8759) +- Add compile time user template (#8766) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 2a2a822f7..ce16e0478 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -7,6 +7,7 @@ - Add library to be used for decoding Teleinfo (French Metering Smart Meter) - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) - Add compile time interlock parameters (#8759) +- Add compile time user template (#8766) - Fix exception or watchdog on rule re-entry (#8757) - Change ESP32 USER GPIO template representation decreasing template message size - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index e0de6bbf3..45345c771 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -53,8 +53,10 @@ //#define MODULE SONOFF_BASIC // [Module] Select default module from tasmota_template.h #ifdef ESP8266 #define FALLBACK_MODULE SONOFF_BASIC // [Module2] Select default module on fast reboot where USER_MODULE is user template +//#define USER_TEMPLATE "{\"NAME\":\"Generic\",\"GPIO\":[255,255,255,255,255,255,255,255,255,255,255,255,255],\"FLAG\":15,\"BASE\":18}" // [Template] Set JSON template #else // ESP32 #define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template +//#define USER_TEMPLATE "{\"NAME\":\"ESP32-DevKit\",\"GPIO\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],\"FLAG\":0,\"BASE\":1}" // [Template] Set JSON template #endif #define SAVE_DATA 1 // [SaveData] Save changed parameters to Flash (0 = disable, 1 - 3600 seconds) diff --git a/tasmota/settings.ino b/tasmota/settings.ino index e7a43b70a..1d7ab6d04 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1087,6 +1087,10 @@ void SettingsDefaultSet2(void) flag3.pcf8574_ports_inverted |= PCF8574_INVERT_PORTS; flag4.zigbee_use_names |= ZIGBEE_FRIENDLY_NAMES; +#ifdef USER_TEMPLATE + JsonTemplate(USER_TEMPLATE); +#endif + Settings.flag = flag; Settings.flag2 = flag2; Settings.flag3 = flag3; From 4a69bb2a13a14b82ef7b69c546008a4d17ea4aad Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 24 Jun 2020 21:41:04 +0200 Subject: [PATCH 343/581] Fix wrong CT range when Alexa mode #8694 --- tasmota/xdrv_04_light.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index a8eaf9629..a47787f90 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -650,7 +650,7 @@ class LightStateClass { _ww = changeUIntScale(w, 0, max, 0, 255); _wc = changeUIntScale(c, 0, max, 0, 255); } - _ct = changeUIntScale(w, 0, sum, _ct_min_range, _ct_max_range); + _ct = changeUIntScale(w, 0, sum, CT_MIN, CT_MAX); addCTMode(); // activate CT mode if needed if (_color_mode & LCM_CT) { _briCT = free_range ? max : (sum > 255 ? 255 : sum); } } From 4503cd44edd02b7f2f7ca94f3188ad354e106491 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 24 Jun 2020 21:48:33 +0200 Subject: [PATCH 344/581] Change IRremoteESP8266 library updated to v2.7.8 --- lib/IRremoteESP8266-2.7.7/docs/README.md | 1 - .../examples/IRGCTCPServer/platformio.ini | 17 - .../examples/IRServer/platformio.ini | 17 - .../examples/IRrecvDemo/platformio.ini | 17 - .../examples/IRrecvDump/platformio.ini | 17 - .../examples/IRsendDemo/platformio.ini | 17 - .../examples/IRsendProntoDemo/platformio.ini | 17 - .../JVCPanasonicSendDemo/platformio.ini | 17 - .../examples/LGACSend/platformio.ini | 17 - .../examples/SmartIRRepeater/platformio.ini | 17 - .../examples/TurnOnArgoAC/platformio.ini | 17 - .../examples/TurnOnDaikinAC/platformio.ini | 17 - .../examples/TurnOnFujitsuAC/platformio.ini | 17 - .../examples/TurnOnGreeAC/platformio.ini | 17 - .../TurnOnKelvinatorAC/platformio.ini | 17 - .../TurnOnMitsubishiAC/platformio.ini | 17 - .../TurnOnMitsubishiHeavyAc/platformio.ini | 17 - .../examples/TurnOnPanasonicAC/platformio.ini | 17 - .../examples/TurnOnToshibaAC/platformio.ini | 17 - .../examples/TurnOnTrotecAC/platformio.ini | 17 - lib/IRremoteESP8266-2.7.7/src/IRtext.cpp | 261 - lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp | 217 - lib/IRremoteESP8266-2.7.7/src/ir_Sherwood.cpp | 28 - .../CPPLINT.cfg | 0 lib/IRremoteESP8266-2.7.8/Doxyfile | 15 + .../LICENSE.txt | 0 .../README.md | 10 +- .../README_fr.md | 13 +- .../ReleaseNotes.md | 44 + .../SupportedProtocols.md | 84 +- lib/IRremoteESP8266-2.7.8/docs/README.md | 61 + lib/IRremoteESP8266-2.7.8/docs/README_fr.md | 64 + .../docs/_config.yml | 0 .../docs/doxygen/html/IRac_8cpp.html | 98 + .../docs/doxygen/html/IRac_8h.html | 127 + .../docs/doxygen/html/IRac_8h_source.html | 652 ++ .../docs/doxygen/html/IRrecv_8cpp.html | 135 + .../docs/doxygen/html/IRrecv_8h.html | 425 + .../docs/doxygen/html/IRrecv_8h_source.html | 972 ++ .../docs/doxygen/html/IRremoteESP8266_8h.html | 3515 ++++++++ .../html/IRremoteESP8266_8h_source.html | 1463 +++ .../docs/doxygen/html/IRsend_8cpp.html | 80 + .../docs/doxygen/html/IRsend_8h.html | 419 + .../docs/doxygen/html/IRsend_8h_source.html | 1078 +++ .../docs/doxygen/html/IRtext_8cpp.html | 2807 ++++++ .../docs/doxygen/html/IRtext_8h.html | 2807 ++++++ .../docs/doxygen/html/IRtext_8h_source.html | 383 + .../docs/doxygen/html/IRtimer_8cpp.html | 119 + .../docs/doxygen/html/IRtimer_8h.html | 94 + .../docs/doxygen/html/IRtimer_8h_source.html | 128 + .../docs/doxygen/html/IRutils_8cpp.html | 871 ++ .../docs/doxygen/html/IRutils_8h.html | 942 ++ .../docs/doxygen/html/IRutils_8h_source.html | 235 + .../docs/doxygen/html/README_8md.html | 76 + .../docs/doxygen/html/annotated.html | 134 + .../docs/doxygen/html/bc_s.png | Bin 0 -> 676 bytes .../docs/doxygen/html/bdwn.png | Bin 0 -> 147 bytes .../doxygen/html/classIRAmcorAc-members.html | 109 + .../docs/doxygen/html/classIRAmcorAc.html | 997 +++ .../html/classIRAmcorAc__coll__graph.map | 4 + .../html/classIRAmcorAc__coll__graph.md5 | 1 + .../html/classIRAmcorAc__coll__graph.png | Bin 0 -> 3009 bytes .../doxygen/html/classIRArgoAC-members.html | 122 + .../docs/doxygen/html/classIRArgoAC.html | 1381 +++ .../html/classIRArgoAC__coll__graph.map | 4 + .../html/classIRArgoAC__coll__graph.md5 | 1 + .../html/classIRArgoAC__coll__graph.png | Bin 0 -> 3164 bytes .../html/classIRCarrierAc64-members.html | 117 + .../docs/doxygen/html/classIRCarrierAc64.html | 1206 +++ .../html/classIRCarrierAc64__coll__graph.map | 4 + .../html/classIRCarrierAc64__coll__graph.md5 | 1 + .../html/classIRCarrierAc64__coll__graph.png | Bin 0 -> 3653 bytes .../doxygen/html/classIRCoolixAC-members.html | 137 + .../docs/doxygen/html/classIRCoolixAC.html | 1710 ++++ .../html/classIRCoolixAC__coll__graph.map | 4 + .../html/classIRCoolixAC__coll__graph.md5 | 1 + .../html/classIRCoolixAC__coll__graph.png | Bin 0 -> 3102 bytes .../doxygen/html/classIRCoronaAc-members.html | 120 + .../docs/doxygen/html/classIRCoronaAc.html | 1360 +++ .../html/classIRCoronaAc__coll__graph.map | 4 + .../html/classIRCoronaAc__coll__graph.md5 | 1 + .../html/classIRCoronaAc__coll__graph.png | Bin 0 -> 3290 bytes .../html/classIRDaikin128-members.html | 132 + .../docs/doxygen/html/classIRDaikin128.html | 1669 ++++ .../html/classIRDaikin128__coll__graph.map | 4 + .../html/classIRDaikin128__coll__graph.md5 | 1 + .../html/classIRDaikin128__coll__graph.png | Bin 0 -> 3291 bytes .../html/classIRDaikin152-members.html | 116 + .../docs/doxygen/html/classIRDaikin152.html | 1172 +++ .../html/classIRDaikin152__coll__graph.map | 4 + .../html/classIRDaikin152__coll__graph.md5 | 1 + .../html/classIRDaikin152__coll__graph.png | Bin 0 -> 3202 bytes .../html/classIRDaikin160-members.html | 108 + .../docs/doxygen/html/classIRDaikin160.html | 983 +++ .../html/classIRDaikin160__coll__graph.map | 4 + .../html/classIRDaikin160__coll__graph.md5 | 1 + .../html/classIRDaikin160__coll__graph.png | Bin 0 -> 3302 bytes .../html/classIRDaikin176-members.html | 111 + .../docs/doxygen/html/classIRDaikin176.html | 1083 +++ .../html/classIRDaikin176__coll__graph.map | 4 + .../html/classIRDaikin176__coll__graph.md5 | 1 + .../html/classIRDaikin176__coll__graph.png | Bin 0 -> 3228 bytes .../doxygen/html/classIRDaikin2-members.html | 152 + .../docs/doxygen/html/classIRDaikin2.html | 2133 +++++ .../html/classIRDaikin216-members.html | 112 + .../docs/doxygen/html/classIRDaikin216.html | 1068 +++ .../html/classIRDaikin216__coll__graph.map | 4 + .../html/classIRDaikin216__coll__graph.md5 | 1 + .../html/classIRDaikin216__coll__graph.png | Bin 0 -> 3277 bytes .../html/classIRDaikin2__coll__graph.map | 4 + .../html/classIRDaikin2__coll__graph.md5 | 1 + .../html/classIRDaikin2__coll__graph.png | Bin 0 -> 3012 bytes .../doxygen/html/classIRDaikin64-members.html | 123 + .../docs/doxygen/html/classIRDaikin64.html | 1393 +++ .../html/classIRDaikin64__coll__graph.map | 4 + .../html/classIRDaikin64__coll__graph.md5 | 1 + .../html/classIRDaikin64__coll__graph.png | Bin 0 -> 3190 bytes .../html/classIRDaikinESP-members.html | 136 + .../docs/doxygen/html/classIRDaikinESP.html | 1729 ++++ .../html/classIRDaikinESP__coll__graph.map | 4 + .../html/classIRDaikinESP__coll__graph.md5 | 1 + .../html/classIRDaikinESP__coll__graph.png | Bin 0 -> 3212 bytes .../html/classIRDelonghiAc-members.html | 123 + .../docs/doxygen/html/classIRDelonghiAc.html | 1370 +++ .../html/classIRDelonghiAc__coll__graph.map | 4 + .../html/classIRDelonghiAc__coll__graph.md5 | 1 + .../html/classIRDelonghiAc__coll__graph.png | Bin 0 -> 3457 bytes .../html/classIRElectraAc-members.html | 117 + .../docs/doxygen/html/classIRElectraAc.html | 1242 +++ .../html/classIRElectraAc__coll__graph.map | 4 + .../html/classIRElectraAc__coll__graph.md5 | 1 + .../html/classIRElectraAc__coll__graph.png | Bin 0 -> 3217 bytes .../html/classIRFujitsuAC-members.html | 135 + .../docs/doxygen/html/classIRFujitsuAC.html | 1707 ++++ .../html/classIRFujitsuAC__coll__graph.map | 4 + .../html/classIRFujitsuAC__coll__graph.md5 | 1 + .../html/classIRFujitsuAC__coll__graph.png | Bin 0 -> 3164 bytes .../html/classIRGoodweatherAc-members.html | 115 + .../doxygen/html/classIRGoodweatherAc.html | 1119 +++ .../classIRGoodweatherAc__coll__graph.map | 4 + .../classIRGoodweatherAc__coll__graph.md5 | 1 + .../classIRGoodweatherAc__coll__graph.png | Bin 0 -> 4102 bytes .../doxygen/html/classIRGreeAC-members.html | 135 + .../docs/doxygen/html/classIRGreeAC.html | 1751 ++++ .../html/classIRGreeAC__coll__graph.map | 4 + .../html/classIRGreeAC__coll__graph.md5 | 1 + .../html/classIRGreeAC__coll__graph.png | Bin 0 -> 3146 bytes .../doxygen/html/classIRHaierAC-members.html | 121 + .../docs/doxygen/html/classIRHaierAC.html | 1370 +++ .../html/classIRHaierACYRW02-members.html | 118 + .../doxygen/html/classIRHaierACYRW02.html | 1252 +++ .../html/classIRHaierACYRW02__coll__graph.map | 4 + .../html/classIRHaierACYRW02__coll__graph.md5 | 1 + .../html/classIRHaierACYRW02__coll__graph.png | Bin 0 -> 4003 bytes .../html/classIRHaierAC__coll__graph.map | 4 + .../html/classIRHaierAC__coll__graph.md5 | 1 + .../html/classIRHaierAC__coll__graph.png | Bin 0 -> 3157 bytes .../html/classIRHitachiAc-members.html | 112 + .../docs/doxygen/html/classIRHitachiAc.html | 1107 +++ .../html/classIRHitachiAc1-members.html | 123 + .../docs/doxygen/html/classIRHitachiAc1.html | 1414 +++ .../html/classIRHitachiAc1__coll__graph.map | 4 + .../html/classIRHitachiAc1__coll__graph.md5 | 1 + .../html/classIRHitachiAc1__coll__graph.png | Bin 0 -> 3046 bytes .../html/classIRHitachiAc3-members.html | 91 + .../docs/doxygen/html/classIRHitachiAc3.html | 498 ++ .../html/classIRHitachiAc344-members.html | 118 + .../doxygen/html/classIRHitachiAc344.html | 607 ++ .../html/classIRHitachiAc344__coll__graph.map | 5 + .../html/classIRHitachiAc344__coll__graph.md5 | 1 + .../html/classIRHitachiAc344__coll__graph.png | Bin 0 -> 5244 bytes .../classIRHitachiAc344__inherit__graph.map | 4 + .../classIRHitachiAc344__inherit__graph.md5 | 1 + .../classIRHitachiAc344__inherit__graph.png | Bin 0 -> 3189 bytes .../html/classIRHitachiAc3__coll__graph.map | 4 + .../html/classIRHitachiAc3__coll__graph.md5 | 1 + .../html/classIRHitachiAc3__coll__graph.png | Bin 0 -> 3209 bytes .../html/classIRHitachiAc424-members.html | 112 + .../doxygen/html/classIRHitachiAc424.html | 1125 +++ .../html/classIRHitachiAc424__coll__graph.map | 4 + .../html/classIRHitachiAc424__coll__graph.md5 | 1 + .../html/classIRHitachiAc424__coll__graph.png | Bin 0 -> 3350 bytes .../classIRHitachiAc424__inherit__graph.map | 4 + .../classIRHitachiAc424__inherit__graph.md5 | 1 + .../classIRHitachiAc424__inherit__graph.png | Bin 0 -> 3162 bytes .../html/classIRHitachiAc__coll__graph.map | 4 + .../html/classIRHitachiAc__coll__graph.md5 | 1 + .../html/classIRHitachiAc__coll__graph.png | Bin 0 -> 3005 bytes .../html/classIRKelvinatorAC-members.html | 121 + .../doxygen/html/classIRKelvinatorAC.html | 1340 +++ .../html/classIRKelvinatorAC__coll__graph.map | 4 + .../html/classIRKelvinatorAC__coll__graph.md5 | 1 + .../html/classIRKelvinatorAC__coll__graph.png | Bin 0 -> 3684 bytes .../doxygen/html/classIRLgAc-members.html | 113 + .../docs/doxygen/html/classIRLgAc.html | 1108 +++ .../doxygen/html/classIRLgAc__coll__graph.map | 4 + .../doxygen/html/classIRLgAc__coll__graph.md5 | 1 + .../doxygen/html/classIRLgAc__coll__graph.png | Bin 0 -> 2873 bytes .../doxygen/html/classIRMideaAC-members.html | 115 + .../docs/doxygen/html/classIRMideaAC.html | 1169 +++ .../html/classIRMideaAC__coll__graph.map | 4 + .../html/classIRMideaAC__coll__graph.md5 | 1 + .../html/classIRMideaAC__coll__graph.png | Bin 0 -> 3328 bytes .../html/classIRMitsubishi112-members.html | 115 + .../doxygen/html/classIRMitsubishi112.html | 1185 +++ .../classIRMitsubishi112__coll__graph.map | 4 + .../classIRMitsubishi112__coll__graph.md5 | 1 + .../classIRMitsubishi112__coll__graph.png | Bin 0 -> 3407 bytes .../html/classIRMitsubishi136-members.html | 112 + .../doxygen/html/classIRMitsubishi136.html | 1108 +++ .../classIRMitsubishi136__coll__graph.map | 4 + .../classIRMitsubishi136__coll__graph.md5 | 1 + .../classIRMitsubishi136__coll__graph.png | Bin 0 -> 3648 bytes .../html/classIRMitsubishiAC-members.html | 123 + .../doxygen/html/classIRMitsubishiAC.html | 1437 +++ .../html/classIRMitsubishiAC__coll__graph.map | 4 + .../html/classIRMitsubishiAC__coll__graph.md5 | 1 + .../html/classIRMitsubishiAC__coll__graph.png | Bin 0 -> 3489 bytes .../classIRMitsubishiHeavy152Ac-members.html | 129 + .../html/classIRMitsubishiHeavy152Ac.html | 1593 ++++ ...assIRMitsubishiHeavy152Ac__coll__graph.map | 4 + ...assIRMitsubishiHeavy152Ac__coll__graph.md5 | 1 + ...assIRMitsubishiHeavy152Ac__coll__graph.png | Bin 0 -> 4959 bytes .../classIRMitsubishiHeavy88Ac-members.html | 122 + .../html/classIRMitsubishiHeavy88Ac.html | 1396 +++ ...lassIRMitsubishiHeavy88Ac__coll__graph.map | 4 + ...lassIRMitsubishiHeavy88Ac__coll__graph.md5 | 1 + ...lassIRMitsubishiHeavy88Ac__coll__graph.png | Bin 0 -> 4835 bytes .../html/classIRNeoclimaAc-members.html | 130 + .../docs/doxygen/html/classIRNeoclimaAc.html | 1584 ++++ .../html/classIRNeoclimaAc__coll__graph.map | 4 + .../html/classIRNeoclimaAc__coll__graph.md5 | 1 + .../html/classIRNeoclimaAc__coll__graph.png | Bin 0 -> 3405 bytes .../html/classIRPanasonicAc-members.html | 138 + .../docs/doxygen/html/classIRPanasonicAc.html | 1936 ++++ .../html/classIRPanasonicAc__coll__graph.map | 4 + .../html/classIRPanasonicAc__coll__graph.md5 | 1 + .../html/classIRPanasonicAc__coll__graph.png | Bin 0 -> 3434 bytes .../html/classIRSamsungAc-members.html | 128 + .../docs/doxygen/html/classIRSamsungAc.html | 1585 ++++ .../html/classIRSamsungAc__coll__graph.map | 4 + .../html/classIRSamsungAc__coll__graph.md5 | 1 + .../html/classIRSamsungAc__coll__graph.png | Bin 0 -> 3730 bytes .../doxygen/html/classIRSharpAc-members.html | 130 + .../docs/doxygen/html/classIRSharpAc.html | 1688 ++++ .../html/classIRSharpAc__coll__graph.map | 4 + .../html/classIRSharpAc__coll__graph.md5 | 1 + .../html/classIRSharpAc__coll__graph.png | Bin 0 -> 3360 bytes .../doxygen/html/classIRTcl112Ac-members.html | 119 + .../docs/doxygen/html/classIRTcl112Ac.html | 1298 +++ .../html/classIRTcl112Ac__coll__graph.map | 4 + .../html/classIRTcl112Ac__coll__graph.md5 | 1 + .../html/classIRTcl112Ac__coll__graph.png | Bin 0 -> 2945 bytes .../doxygen/html/classIRTecoAc-members.html | 117 + .../docs/doxygen/html/classIRTecoAc.html | 1182 +++ .../html/classIRTecoAc__coll__graph.map | 4 + .../html/classIRTecoAc__coll__graph.md5 | 1 + .../html/classIRTecoAc__coll__graph.png | Bin 0 -> 3054 bytes .../html/classIRToshibaAC-members.html | 108 + .../docs/doxygen/html/classIRToshibaAC.html | 1001 +++ .../html/classIRToshibaAC__coll__graph.map | 4 + .../html/classIRToshibaAC__coll__graph.md5 | 1 + .../html/classIRToshibaAC__coll__graph.png | Bin 0 -> 3399 bytes .../html/classIRTrotecESP-members.html | 111 + .../docs/doxygen/html/classIRTrotecESP.html | 1069 +++ .../html/classIRTrotecESP__coll__graph.map | 4 + .../html/classIRTrotecESP__coll__graph.md5 | 1 + .../html/classIRTrotecESP__coll__graph.png | Bin 0 -> 3270 bytes .../doxygen/html/classIRVestelAc-members.html | 136 + .../docs/doxygen/html/classIRVestelAc.html | 1758 ++++ .../html/classIRVestelAc__coll__graph.map | 4 + .../html/classIRVestelAc__coll__graph.md5 | 1 + .../html/classIRVestelAc__coll__graph.png | Bin 0 -> 3288 bytes .../html/classIRWhirlpoolAc-members.html | 134 + .../docs/doxygen/html/classIRWhirlpoolAc.html | 1799 ++++ .../html/classIRWhirlpoolAc__coll__graph.map | 4 + .../html/classIRWhirlpoolAc__coll__graph.md5 | 1 + .../html/classIRWhirlpoolAc__coll__graph.png | Bin 0 -> 3386 bytes .../docs/doxygen/html/classIRac-members.html | 151 + .../docs/doxygen/html/classIRac.html | 5644 ++++++++++++ .../doxygen/html/classIRac__coll__graph.map | 4 + .../doxygen/html/classIRac__coll__graph.md5 | 1 + .../doxygen/html/classIRac__coll__graph.png | Bin 0 -> 3252 bytes .../doxygen/html/classIRrecv-members.html | 189 + .../docs/doxygen/html/classIRrecv.html | 7184 +++++++++++++++ .../doxygen/html/classIRrecv__coll__graph.map | 4 + .../doxygen/html/classIRrecv__coll__graph.md5 | 1 + .../doxygen/html/classIRrecv__coll__graph.png | Bin 0 -> 3293 bytes .../doxygen/html/classIRsend-members.html | 213 + .../docs/doxygen/html/classIRsend.html | 6599 ++++++++++++++ .../doxygen/html/classIRtimer-members.html | 84 + .../docs/doxygen/html/classIRtimer.html | 235 + .../doxygen/html/classTimerMs-members.html | 84 + .../docs/doxygen/html/classTimerMs.html | 235 + .../html/classdecode__results-members.html | 89 + .../doxygen/html/classdecode__results.html | 274 + .../docs/doxygen/html/classes.html | 157 + .../docs/doxygen/html/closed.png | Bin 0 -> 132 bytes .../docs/doxygen/html/de-CH_8h.html | 82 + .../docs/doxygen/html/de-CH_8h_source.html | 239 + .../docs/doxygen/html/de-DE_8h.html | 82 + .../docs/doxygen/html/de-DE_8h_source.html | 206 + .../docs/doxygen/html/defaults_8h.html | 82 + .../docs/doxygen/html/defaults_8h_source.html | 838 ++ .../docs/doxygen/html/deprecated.html | 85 + .../dir_49e56c817e5e54854c35e136979f97ca.html | 80 + .../dir_68267d1309a1af8e8297ef4c3efbcdba.html | 373 + .../dir_84fe998d1eb06414cc389ad334e77e63.html | 106 + .../docs/doxygen/html/doc.png | Bin 0 -> 746 bytes .../docs/doxygen/html/doxygen.css | 1771 ++++ .../docs/doxygen/html/doxygen.png | Bin 0 -> 3779 bytes .../docs/doxygen/html/doxygen__index_8md.html | 76 + .../docs/doxygen/html/dynsections.js | 120 + .../docs/doxygen/html/en-AU_8h.html | 82 + .../docs/doxygen/html/en-AU_8h_source.html | 88 + .../docs/doxygen/html/en-IE_8h.html | 82 + .../docs/doxygen/html/en-IE_8h_source.html | 88 + .../docs/doxygen/html/en-UK_8h.html | 82 + .../docs/doxygen/html/en-UK_8h_source.html | 88 + .../docs/doxygen/html/en-US_8h.html | 82 + .../docs/doxygen/html/en-US_8h_source.html | 93 + .../docs/doxygen/html/es-ES_8h.html | 82 + .../docs/doxygen/html/es-ES_8h_source.html | 216 + .../docs/doxygen/html/files.html | 194 + .../docs/doxygen/html/folderclosed.png | Bin 0 -> 616 bytes .../docs/doxygen/html/folderopen.png | Bin 0 -> 597 bytes .../docs/doxygen/html/fr-FR_8h.html | 82 + .../docs/doxygen/html/fr-FR_8h_source.html | 197 + .../docs/doxygen/html/functions.html | 262 + .../docs/doxygen/html/functions_a.html | 90 + .../docs/doxygen/html/functions_b.html | 142 + .../docs/doxygen/html/functions_c.html | 377 + .../docs/doxygen/html/functions_d.html | 360 + .../docs/doxygen/html/functions_e.html | 153 + .../docs/doxygen/html/functions_f.html | 98 + .../docs/doxygen/html/functions_func.html | 121 + .../docs/doxygen/html/functions_func_a.html | 86 + .../docs/doxygen/html/functions_func_b.html | 130 + .../docs/doxygen/html/functions_func_c.html | 356 + .../docs/doxygen/html/functions_func_d.html | 351 + .../docs/doxygen/html/functions_func_e.html | 150 + .../docs/doxygen/html/functions_func_f.html | 89 + .../docs/doxygen/html/functions_func_g.html | 777 ++ .../docs/doxygen/html/functions_func_h.html | 106 + .../docs/doxygen/html/functions_func_i.html | 258 + .../docs/doxygen/html/functions_func_k.html | 79 + .../docs/doxygen/html/functions_func_l.html | 85 + .../docs/doxygen/html/functions_func_m.html | 133 + .../docs/doxygen/html/functions_func_n.html | 79 + .../docs/doxygen/html/functions_func_o.html | 157 + .../docs/doxygen/html/functions_func_p.html | 79 + .../docs/doxygen/html/functions_func_r.html | 86 + .../docs/doxygen/html/functions_func_s.html | 1156 +++ .../docs/doxygen/html/functions_func_t.html | 297 + .../docs/doxygen/html/functions_func_u.html | 79 + .../docs/doxygen/html/functions_func_v.html | 119 + .../docs/doxygen/html/functions_func_w.html | 79 + .../docs/doxygen/html/functions_func_~.html | 79 + .../docs/doxygen/html/functions_g.html | 777 ++ .../docs/doxygen/html/functions_h.html | 109 + .../docs/doxygen/html/functions_i.html | 265 + .../docs/doxygen/html/functions_k.html | 79 + .../docs/doxygen/html/functions_l.html | 97 + .../docs/doxygen/html/functions_m.html | 148 + .../docs/doxygen/html/functions_n.html | 82 + .../docs/doxygen/html/functions_o.html | 173 + .../docs/doxygen/html/functions_p.html | 94 + .../docs/doxygen/html/functions_q.html | 79 + .../docs/doxygen/html/functions_r.html | 151 + .../docs/doxygen/html/functions_rela.html | 77 + .../docs/doxygen/html/functions_s.html | 1193 +++ .../docs/doxygen/html/functions_t.html | 309 + .../docs/doxygen/html/functions_u.html | 85 + .../docs/doxygen/html/functions_v.html | 122 + .../docs/doxygen/html/functions_vars.html | 563 ++ .../docs/doxygen/html/functions_vars_a.html | 82 + .../docs/doxygen/html/functions_vars_b.html | 88 + .../docs/doxygen/html/functions_vars_c.html | 97 + .../docs/doxygen/html/functions_vars_d.html | 85 + .../docs/doxygen/html/functions_vars_e.html | 79 + .../docs/doxygen/html/functions_vars_f.html | 85 + .../docs/doxygen/html/functions_vars_h.html | 79 + .../docs/doxygen/html/functions_vars_i.html | 82 + .../docs/doxygen/html/functions_vars_l.html | 88 + .../docs/doxygen/html/functions_vars_m.html | 91 + .../docs/doxygen/html/functions_vars_n.html | 79 + .../docs/doxygen/html/functions_vars_o.html | 92 + .../docs/doxygen/html/functions_vars_p.html | 91 + .../docs/doxygen/html/functions_vars_q.html | 79 + .../docs/doxygen/html/functions_vars_r.html | 140 + .../docs/doxygen/html/functions_vars_s.html | 113 + .../docs/doxygen/html/functions_vars_t.html | 88 + .../docs/doxygen/html/functions_vars_u.html | 82 + .../docs/doxygen/html/functions_vars_v.html | 79 + .../docs/doxygen/html/functions_vars_w.html | 79 + .../docs/doxygen/html/functions_vars_z.html | 79 + .../docs/doxygen/html/functions_w.html | 82 + .../docs/doxygen/html/functions_z.html | 79 + .../docs/doxygen/html/functions_~.html | 79 + .../docs/doxygen/html/globals.html | 82 + .../docs/doxygen/html/globals_a.html | 106 + .../docs/doxygen/html/globals_c.html | 100 + .../docs/doxygen/html/globals_d.html | 121 + .../docs/doxygen/html/globals_e.html | 82 + .../docs/doxygen/html/globals_enum.html | 95 + .../docs/doxygen/html/globals_eval.html | 493 ++ .../docs/doxygen/html/globals_f.html | 86 + .../docs/doxygen/html/globals_func.html | 184 + .../docs/doxygen/html/globals_g.html | 98 + .../docs/doxygen/html/globals_h.html | 107 + .../docs/doxygen/html/globals_i.html | 92 + .../docs/doxygen/html/globals_j.html | 79 + .../docs/doxygen/html/globals_k.html | 7825 +++++++++++++++++ .../docs/doxygen/html/globals_l.html | 94 + .../docs/doxygen/html/globals_m.html | 112 + .../docs/doxygen/html/globals_n.html | 88 + .../docs/doxygen/html/globals_p.html | 91 + .../docs/doxygen/html/globals_r.html | 121 + .../docs/doxygen/html/globals_s.html | 124 + .../docs/doxygen/html/globals_t.html | 92 + .../docs/doxygen/html/globals_type.html | 77 + .../docs/doxygen/html/globals_u.html | 86 + .../docs/doxygen/html/globals_v.html | 79 + .../docs/doxygen/html/globals_vars.html | 82 + .../docs/doxygen/html/globals_vars_i.html | 85 + .../docs/doxygen/html/globals_vars_k.html | 7798 ++++++++++++++++ .../docs/doxygen/html/globals_w.html | 85 + .../docs/doxygen/html/globals_x.html | 80 + .../docs/doxygen/html/globals_y.html | 82 + .../docs/doxygen/html/globals_z.html | 79 + .../docs/doxygen/html/graph_legend.html | 136 + .../docs/doxygen/html/graph_legend.md5 | 1 + .../docs/doxygen/html/graph_legend.png | Bin 0 -> 20615 bytes .../docs/doxygen/html/hierarchy.html | 135 + .../docs/doxygen/html/i18n_8h.html | 82 + .../docs/doxygen/html/i18n_8h_source.html | 107 + .../docs/doxygen/html/index.html | 104 + .../docs/doxygen/html/inherit_graph_0.map | 3 + .../docs/doxygen/html/inherit_graph_0.md5 | 1 + .../docs/doxygen/html/inherit_graph_0.png | Bin 0 -> 1406 bytes .../docs/doxygen/html/inherit_graph_1.map | 3 + .../docs/doxygen/html/inherit_graph_1.md5 | 1 + .../docs/doxygen/html/inherit_graph_1.png | Bin 0 -> 674 bytes .../docs/doxygen/html/inherit_graph_10.map | 3 + .../docs/doxygen/html/inherit_graph_10.md5 | 1 + .../docs/doxygen/html/inherit_graph_10.png | Bin 0 -> 1281 bytes .../docs/doxygen/html/inherit_graph_11.map | 3 + .../docs/doxygen/html/inherit_graph_11.md5 | 1 + .../docs/doxygen/html/inherit_graph_11.png | Bin 0 -> 1088 bytes .../docs/doxygen/html/inherit_graph_12.map | 3 + .../docs/doxygen/html/inherit_graph_12.md5 | 1 + .../docs/doxygen/html/inherit_graph_12.png | Bin 0 -> 1317 bytes .../docs/doxygen/html/inherit_graph_13.map | 3 + .../docs/doxygen/html/inherit_graph_13.md5 | 1 + .../docs/doxygen/html/inherit_graph_13.png | Bin 0 -> 1237 bytes .../docs/doxygen/html/inherit_graph_14.map | 3 + .../docs/doxygen/html/inherit_graph_14.md5 | 1 + .../docs/doxygen/html/inherit_graph_14.png | Bin 0 -> 1264 bytes .../docs/doxygen/html/inherit_graph_15.map | 3 + .../docs/doxygen/html/inherit_graph_15.md5 | 1 + .../docs/doxygen/html/inherit_graph_15.png | Bin 0 -> 1482 bytes .../docs/doxygen/html/inherit_graph_16.map | 3 + .../docs/doxygen/html/inherit_graph_16.md5 | 1 + .../docs/doxygen/html/inherit_graph_16.png | Bin 0 -> 1334 bytes .../docs/doxygen/html/inherit_graph_17.map | 3 + .../docs/doxygen/html/inherit_graph_17.md5 | 1 + .../docs/doxygen/html/inherit_graph_17.png | Bin 0 -> 1280 bytes .../docs/doxygen/html/inherit_graph_18.map | 3 + .../docs/doxygen/html/inherit_graph_18.md5 | 1 + .../docs/doxygen/html/inherit_graph_18.png | Bin 0 -> 1904 bytes .../docs/doxygen/html/inherit_graph_19.map | 3 + .../docs/doxygen/html/inherit_graph_19.md5 | 1 + .../docs/doxygen/html/inherit_graph_19.png | Bin 0 -> 1214 bytes .../docs/doxygen/html/inherit_graph_2.map | 3 + .../docs/doxygen/html/inherit_graph_2.md5 | 1 + .../docs/doxygen/html/inherit_graph_2.png | Bin 0 -> 1068 bytes .../docs/doxygen/html/inherit_graph_20.map | 3 + .../docs/doxygen/html/inherit_graph_20.md5 | 1 + .../docs/doxygen/html/inherit_graph_20.png | Bin 0 -> 1300 bytes .../docs/doxygen/html/inherit_graph_21.map | 3 + .../docs/doxygen/html/inherit_graph_21.md5 | 1 + .../docs/doxygen/html/inherit_graph_21.png | Bin 0 -> 1924 bytes .../docs/doxygen/html/inherit_graph_22.map | 3 + .../docs/doxygen/html/inherit_graph_22.md5 | 1 + .../docs/doxygen/html/inherit_graph_22.png | Bin 0 -> 1089 bytes .../docs/doxygen/html/inherit_graph_23.map | 3 + .../docs/doxygen/html/inherit_graph_23.md5 | 1 + .../docs/doxygen/html/inherit_graph_23.png | Bin 0 -> 1144 bytes .../docs/doxygen/html/inherit_graph_24.map | 3 + .../docs/doxygen/html/inherit_graph_24.md5 | 1 + .../docs/doxygen/html/inherit_graph_24.png | Bin 0 -> 1273 bytes .../docs/doxygen/html/inherit_graph_25.map | 4 + .../docs/doxygen/html/inherit_graph_25.md5 | 1 + .../docs/doxygen/html/inherit_graph_25.png | Bin 0 -> 2195 bytes .../docs/doxygen/html/inherit_graph_26.map | 3 + .../docs/doxygen/html/inherit_graph_26.md5 | 1 + .../docs/doxygen/html/inherit_graph_26.png | Bin 0 -> 1725 bytes .../docs/doxygen/html/inherit_graph_27.map | 3 + .../docs/doxygen/html/inherit_graph_27.md5 | 1 + .../docs/doxygen/html/inherit_graph_27.png | Bin 0 -> 911 bytes .../docs/doxygen/html/inherit_graph_28.map | 3 + .../docs/doxygen/html/inherit_graph_28.md5 | 1 + .../docs/doxygen/html/inherit_graph_28.png | Bin 0 -> 1369 bytes .../docs/doxygen/html/inherit_graph_29.map | 3 + .../docs/doxygen/html/inherit_graph_29.md5 | 1 + .../docs/doxygen/html/inherit_graph_29.png | Bin 0 -> 1340 bytes .../docs/doxygen/html/inherit_graph_3.map | 3 + .../docs/doxygen/html/inherit_graph_3.md5 | 1 + .../docs/doxygen/html/inherit_graph_3.png | Bin 0 -> 1161 bytes .../docs/doxygen/html/inherit_graph_30.map | 3 + .../docs/doxygen/html/inherit_graph_30.md5 | 1 + .../docs/doxygen/html/inherit_graph_30.png | Bin 0 -> 1573 bytes .../docs/doxygen/html/inherit_graph_31.map | 3 + .../docs/doxygen/html/inherit_graph_31.md5 | 1 + .../docs/doxygen/html/inherit_graph_31.png | Bin 0 -> 1583 bytes .../docs/doxygen/html/inherit_graph_32.map | 3 + .../docs/doxygen/html/inherit_graph_32.md5 | 1 + .../docs/doxygen/html/inherit_graph_32.png | Bin 0 -> 2616 bytes .../docs/doxygen/html/inherit_graph_33.map | 3 + .../docs/doxygen/html/inherit_graph_33.md5 | 1 + .../docs/doxygen/html/inherit_graph_33.png | Bin 0 -> 2503 bytes .../docs/doxygen/html/inherit_graph_34.map | 3 + .../docs/doxygen/html/inherit_graph_34.md5 | 1 + .../docs/doxygen/html/inherit_graph_34.png | Bin 0 -> 1440 bytes .../docs/doxygen/html/inherit_graph_35.map | 3 + .../docs/doxygen/html/inherit_graph_35.md5 | 1 + .../docs/doxygen/html/inherit_graph_35.png | Bin 0 -> 1494 bytes .../docs/doxygen/html/inherit_graph_36.map | 3 + .../docs/doxygen/html/inherit_graph_36.md5 | 1 + .../docs/doxygen/html/inherit_graph_36.png | Bin 0 -> 1122 bytes .../docs/doxygen/html/inherit_graph_37.map | 3 + .../docs/doxygen/html/inherit_graph_37.md5 | 1 + .../docs/doxygen/html/inherit_graph_37.png | Bin 0 -> 878 bytes .../docs/doxygen/html/inherit_graph_38.map | 3 + .../docs/doxygen/html/inherit_graph_38.md5 | 1 + .../docs/doxygen/html/inherit_graph_38.png | Bin 0 -> 1648 bytes .../docs/doxygen/html/inherit_graph_39.map | 3 + .../docs/doxygen/html/inherit_graph_39.md5 | 1 + .../docs/doxygen/html/inherit_graph_39.png | Bin 0 -> 925 bytes .../docs/doxygen/html/inherit_graph_4.map | 3 + .../docs/doxygen/html/inherit_graph_4.md5 | 1 + .../docs/doxygen/html/inherit_graph_4.png | Bin 0 -> 1579 bytes .../docs/doxygen/html/inherit_graph_40.map | 3 + .../docs/doxygen/html/inherit_graph_40.md5 | 1 + .../docs/doxygen/html/inherit_graph_40.png | Bin 0 -> 1459 bytes .../docs/doxygen/html/inherit_graph_41.map | 3 + .../docs/doxygen/html/inherit_graph_41.md5 | 1 + .../docs/doxygen/html/inherit_graph_41.png | Bin 0 -> 1014 bytes .../docs/doxygen/html/inherit_graph_42.map | 3 + .../docs/doxygen/html/inherit_graph_42.md5 | 1 + .../docs/doxygen/html/inherit_graph_42.png | Bin 0 -> 1059 bytes .../docs/doxygen/html/inherit_graph_43.map | 3 + .../docs/doxygen/html/inherit_graph_43.md5 | 1 + .../docs/doxygen/html/inherit_graph_43.png | Bin 0 -> 869 bytes .../docs/doxygen/html/inherit_graph_44.map | 3 + .../docs/doxygen/html/inherit_graph_44.md5 | 1 + .../docs/doxygen/html/inherit_graph_44.png | Bin 0 -> 1428 bytes .../docs/doxygen/html/inherit_graph_45.map | 3 + .../docs/doxygen/html/inherit_graph_45.md5 | 1 + .../docs/doxygen/html/inherit_graph_45.png | Bin 0 -> 1328 bytes .../docs/doxygen/html/inherit_graph_46.map | 3 + .../docs/doxygen/html/inherit_graph_46.md5 | 1 + .../docs/doxygen/html/inherit_graph_46.png | Bin 0 -> 1310 bytes .../docs/doxygen/html/inherit_graph_47.map | 3 + .../docs/doxygen/html/inherit_graph_47.md5 | 1 + .../docs/doxygen/html/inherit_graph_47.png | Bin 0 -> 1480 bytes .../docs/doxygen/html/inherit_graph_48.map | 3 + .../docs/doxygen/html/inherit_graph_48.md5 | 1 + .../docs/doxygen/html/inherit_graph_48.png | Bin 0 -> 1310 bytes .../docs/doxygen/html/inherit_graph_49.map | 3 + .../docs/doxygen/html/inherit_graph_49.md5 | 1 + .../docs/doxygen/html/inherit_graph_49.png | Bin 0 -> 1308 bytes .../docs/doxygen/html/inherit_graph_5.map | 3 + .../docs/doxygen/html/inherit_graph_5.md5 | 1 + .../docs/doxygen/html/inherit_graph_5.png | Bin 0 -> 1141 bytes .../docs/doxygen/html/inherit_graph_50.map | 3 + .../docs/doxygen/html/inherit_graph_50.md5 | 1 + .../docs/doxygen/html/inherit_graph_50.png | Bin 0 -> 1307 bytes .../docs/doxygen/html/inherit_graph_51.map | 3 + .../docs/doxygen/html/inherit_graph_51.md5 | 1 + .../docs/doxygen/html/inherit_graph_51.png | Bin 0 -> 985 bytes .../docs/doxygen/html/inherit_graph_6.map | 3 + .../docs/doxygen/html/inherit_graph_6.md5 | 1 + .../docs/doxygen/html/inherit_graph_6.png | Bin 0 -> 1277 bytes .../docs/doxygen/html/inherit_graph_7.map | 3 + .../docs/doxygen/html/inherit_graph_7.md5 | 1 + .../docs/doxygen/html/inherit_graph_7.png | Bin 0 -> 1330 bytes .../docs/doxygen/html/inherit_graph_8.map | 3 + .../docs/doxygen/html/inherit_graph_8.md5 | 1 + .../docs/doxygen/html/inherit_graph_8.png | Bin 0 -> 1257 bytes .../docs/doxygen/html/inherit_graph_9.map | 3 + .../docs/doxygen/html/inherit_graph_9.md5 | 1 + .../docs/doxygen/html/inherit_graph_9.png | Bin 0 -> 1371 bytes .../docs/doxygen/html/inherits.html | 341 + .../docs/doxygen/html/ir__Airwell_8cpp.html | 172 + .../docs/doxygen/html/ir__Aiwa_8cpp.html | 157 + .../docs/doxygen/html/ir__Amcor_8cpp.html | 239 + .../docs/doxygen/html/ir__Amcor_8h.html | 615 ++ .../doxygen/html/ir__Amcor_8h_source.html | 274 + .../docs/doxygen/html/ir__Argo_8cpp.html | 188 + .../docs/doxygen/html/ir__Argo_8h.html | 747 ++ .../docs/doxygen/html/ir__Argo_8h_source.html | 373 + .../docs/doxygen/html/ir__Carrier_8cpp.html | 400 + .../docs/doxygen/html/ir__Carrier_8h.html | 568 ++ .../doxygen/html/ir__Carrier_8h_source.html | 275 + .../docs/doxygen/html/ir__Coolix_8cpp.html | 301 + .../docs/doxygen/html/ir__Coolix_8h.html | 768 ++ .../doxygen/html/ir__Coolix_8h_source.html | 365 + .../docs/doxygen/html/ir__Corona_8cpp.html | 256 + .../docs/doxygen/html/ir__Corona_8h.html | 730 ++ .../doxygen/html/ir__Corona_8h_source.html | 319 + .../docs/doxygen/html/ir__Daikin_8cpp.html | 114 + .../docs/doxygen/html/ir__Daikin_8h.html | 5674 ++++++++++++ .../doxygen/html/ir__Daikin_8h_source.html | 1801 ++++ .../docs/doxygen/html/ir__Delonghi_8cpp.html | 220 + .../docs/doxygen/html/ir__Delonghi_8h.html | 695 ++ .../doxygen/html/ir__Delonghi_8h_source.html | 323 + .../docs/doxygen/html/ir__Denon_8cpp.html | 346 + .../docs/doxygen/html/ir__Dish_8cpp.html | 305 + .../docs/doxygen/html/ir__Doshisha_8cpp.html | 429 + .../docs/doxygen/html/ir__Electra_8cpp.html | 195 + .../docs/doxygen/html/ir__Electra_8h.html | 550 ++ .../doxygen/html/ir__Electra_8h_source.html | 286 + .../docs/doxygen/html/ir__Epson_8cpp.html | 86 + .../docs/doxygen/html/ir__Fujitsu_8cpp.html | 188 + .../docs/doxygen/html/ir__Fujitsu_8h.html | 581 ++ .../doxygen/html/ir__Fujitsu_8h_source.html | 350 + .../docs/doxygen/html/ir__GICable_8cpp.html | 233 + .../doxygen/html/ir__GlobalCache_8cpp.html | 189 + .../doxygen/html/ir__Goodweather_8cpp.html | 86 + .../docs/doxygen/html/ir__Goodweather_8h.html | 886 ++ .../html/ir__Goodweather_8h_source.html | 310 + .../docs/doxygen/html/ir__Gree_8cpp.html | 224 + .../docs/doxygen/html/ir__Gree_8h.html | 934 ++ .../docs/doxygen/html/ir__Gree_8h_source.html | 387 + .../docs/doxygen/html/ir__Haier_8cpp.html | 199 + .../docs/doxygen/html/ir__Haier_8h.html | 1363 +++ .../doxygen/html/ir__Haier_8h_source.html | 587 ++ .../docs/doxygen/html/ir__Hitachi_8cpp.html | 423 + .../docs/doxygen/html/ir__Hitachi_8h.html | 2028 +++++ .../doxygen/html/ir__Hitachi_8h_source.html | 734 ++ .../docs/doxygen/html/ir__Inax_8cpp.html | 207 + .../docs/doxygen/html/ir__JVC_8cpp.html | 343 + .../doxygen/html/ir__Kelvinator_8cpp.html | 569 ++ .../docs/doxygen/html/ir__Kelvinator_8h.html | 293 + .../html/ir__Kelvinator_8h_source.html | 336 + .../docs/doxygen/html/ir__LG_8cpp.html | 557 ++ .../docs/doxygen/html/ir__LG_8h.html | 550 ++ .../docs/doxygen/html/ir__LG_8h_source.html | 262 + .../docs/doxygen/html/ir__Lasertag_8cpp.html | 221 + .../docs/doxygen/html/ir__Lego_8cpp.html | 176 + .../docs/doxygen/html/ir__Lutron_8cpp.html | 144 + .../docs/doxygen/html/ir__MWM_8cpp.html | 237 + .../docs/doxygen/html/ir__Magiquest_8cpp.html | 88 + .../docs/doxygen/html/ir__Magiquest_8h.html | 232 + .../doxygen/html/ir__Magiquest_8h_source.html | 137 + .../docs/doxygen/html/ir__Midea_8cpp.html | 341 + .../docs/doxygen/html/ir__Midea_8h.html | 454 + .../doxygen/html/ir__Midea_8h_source.html | 264 + .../html/ir__MitsubishiHeavy_8cpp.html | 194 + .../doxygen/html/ir__MitsubishiHeavy_8h.html | 1314 +++ .../html/ir__MitsubishiHeavy_8h_source.html | 536 ++ .../doxygen/html/ir__Mitsubishi_8cpp.html | 722 ++ .../docs/doxygen/html/ir__Mitsubishi_8h.html | 1609 ++++ .../html/ir__Mitsubishi_8h_source.html | 612 ++ .../doxygen/html/ir__Multibrackets_8cpp.html | 175 + .../docs/doxygen/html/ir__NEC_8cpp.html | 86 + .../docs/doxygen/html/ir__NEC_8h.html | 642 ++ .../docs/doxygen/html/ir__NEC_8h_source.html | 189 + .../docs/doxygen/html/ir__Neoclima_8cpp.html | 191 + .../docs/doxygen/html/ir__Neoclima_8h.html | 888 ++ .../doxygen/html/ir__Neoclima_8h_source.html | 340 + .../docs/doxygen/html/ir__Nikai_8cpp.html | 301 + .../docs/doxygen/html/ir__Panasonic_8cpp.html | 416 + .../docs/doxygen/html/ir__Panasonic_8h.html | 826 ++ .../doxygen/html/ir__Panasonic_8h_source.html | 368 + .../docs/doxygen/html/ir__Pioneer_8cpp.html | 341 + .../docs/doxygen/html/ir__Pronto_8cpp.html | 195 + .../docs/doxygen/html/ir__RC5__RC6_8cpp.html | 361 + .../docs/doxygen/html/ir__RCMM_8cpp.html | 429 + .../docs/doxygen/html/ir__Samsung_8cpp.html | 529 ++ .../docs/doxygen/html/ir__Samsung_8h.html | 748 ++ .../doxygen/html/ir__Samsung_8h_source.html | 335 + .../docs/doxygen/html/ir__Sanyo_8cpp.html | 352 + .../docs/doxygen/html/ir__Sharp_8cpp.html | 301 + .../docs/doxygen/html/ir__Sharp_8h.html | 1074 +++ .../doxygen/html/ir__Sharp_8h_source.html | 373 + .../docs/doxygen/html/ir__Sherwood_8cpp.html | 85 + .../docs/doxygen/html/ir__Sony_8cpp.html | 335 + .../docs/doxygen/html/ir__Symphony_8cpp.html | 181 + .../docs/doxygen/html/ir__Tcl_8cpp.html | 86 + .../docs/doxygen/html/ir__Tcl_8h.html | 613 ++ .../docs/doxygen/html/ir__Tcl_8h_source.html | 281 + .../docs/doxygen/html/ir__Teco_8cpp.html | 188 + .../docs/doxygen/html/ir__Teco_8h.html | 565 ++ .../docs/doxygen/html/ir__Teco_8h_source.html | 324 + .../docs/doxygen/html/ir__Toshiba_8cpp.html | 191 + .../docs/doxygen/html/ir__Toshiba_8h.html | 376 + .../doxygen/html/ir__Toshiba_8h_source.html | 238 + .../docs/doxygen/html/ir__Trotec_8cpp.html | 207 + .../docs/doxygen/html/ir__Trotec_8h.html | 456 + .../doxygen/html/ir__Trotec_8h_source.html | 270 + .../docs/doxygen/html/ir__Vestel_8cpp.html | 85 + .../docs/doxygen/html/ir__Vestel_8h.html | 905 ++ .../doxygen/html/ir__Vestel_8h_source.html | 378 + .../docs/doxygen/html/ir__Whirlpool_8cpp.html | 224 + .../docs/doxygen/html/ir__Whirlpool_8h.html | 937 ++ .../doxygen/html/ir__Whirlpool_8h_source.html | 353 + .../docs/doxygen/html/ir__Whynter_8cpp.html | 344 + .../docs/doxygen/html/ir__Zepeal_8cpp.html | 333 + .../docs/doxygen/html/it-IT_8h.html | 82 + .../docs/doxygen/html/it-IT_8h_source.html | 239 + .../docs/doxygen/html/jquery.js | 35 + .../doxygen/html/md_src_locale_README.html | 135 + .../docs/doxygen/html/menu.js | 50 + .../docs/doxygen/html/menudata.js | 189 + .../docs/doxygen/html/namespaceIRAcUtils.html | 161 + .../docs/doxygen/html/namespaceirutils.html | 1303 +++ .../docs/doxygen/html/namespacemembers.html | 188 + .../doxygen/html/namespacemembers_enum.html | 86 + .../doxygen/html/namespacemembers_func.html | 134 + .../docs/doxygen/html/namespaces.html | 83 + .../docs/doxygen/html/namespacestdAc.html | 286 + .../docs/doxygen/html/nav_f.png | Bin 0 -> 153 bytes .../docs/doxygen/html/nav_g.png | Bin 0 -> 95 bytes .../docs/doxygen/html/nav_h.png | Bin 0 -> 98 bytes .../docs/doxygen/html/open.png | Bin 0 -> 123 bytes .../docs/doxygen/html/pages.html | 83 + .../docs/doxygen/html/search/all_0.html | 30 + .../docs/doxygen/html/search/all_0.js | 50 + .../docs/doxygen/html/search/all_1.html | 30 + .../docs/doxygen/html/search/all_1.js | 23 + .../docs/doxygen/html/search/all_10.html | 30 + .../docs/doxygen/html/search/all_10.js | 13 + .../docs/doxygen/html/search/all_11.html | 30 + .../docs/doxygen/html/search/all_11.js | 4 + .../docs/doxygen/html/search/all_12.html | 30 + .../docs/doxygen/html/search/all_12.js | 29 + .../docs/doxygen/html/search/all_13.html | 30 + .../docs/doxygen/html/search/all_13.js | 244 + .../docs/doxygen/html/search/all_14.html | 30 + .../docs/doxygen/html/search/all_14.js | 28 + .../docs/doxygen/html/search/all_15.html | 30 + .../docs/doxygen/html/search/all_15.js | 10 + .../docs/doxygen/html/search/all_16.html | 30 + .../docs/doxygen/html/search/all_16.js | 8 + .../docs/doxygen/html/search/all_17.html | 30 + .../docs/doxygen/html/search/all_17.js | 8 + .../docs/doxygen/html/search/all_18.html | 30 + .../docs/doxygen/html/search/all_18.js | 4 + .../docs/doxygen/html/search/all_19.html | 30 + .../docs/doxygen/html/search/all_19.js | 5 + .../docs/doxygen/html/search/all_1a.html | 30 + .../docs/doxygen/html/search/all_1a.js | 6 + .../docs/doxygen/html/search/all_1b.html | 30 + .../docs/doxygen/html/search/all_1b.js | 4 + .../docs/doxygen/html/search/all_2.html | 30 + .../docs/doxygen/html/search/all_2.js | 12 + .../docs/doxygen/html/search/all_3.html | 30 + .../docs/doxygen/html/search/all_3.js | 45 + .../docs/doxygen/html/search/all_4.html | 30 + .../docs/doxygen/html/search/all_4.js | 111 + .../docs/doxygen/html/search/all_5.html | 30 + .../docs/doxygen/html/search/all_5.js | 34 + .../docs/doxygen/html/search/all_6.html | 30 + .../docs/doxygen/html/search/all_6.js | 15 + .../docs/doxygen/html/search/all_7.html | 30 + .../docs/doxygen/html/search/all_7.js | 118 + .../docs/doxygen/html/search/all_8.html | 30 + .../docs/doxygen/html/search/all_8.js | 25 + .../docs/doxygen/html/search/all_9.html | 30 + .../docs/doxygen/html/search/all_9.js | 175 + .../docs/doxygen/html/search/all_a.html | 30 + .../docs/doxygen/html/search/all_a.js | 4 + .../docs/doxygen/html/search/all_b.html | 30 + .../docs/doxygen/html/search/all_b.js | 2560 ++++++ .../docs/doxygen/html/search/all_c.html | 30 + .../docs/doxygen/html/search/all_c.js | 15 + .../docs/doxygen/html/search/all_d.html | 30 + .../docs/doxygen/html/search/all_d.js | 39 + .../docs/doxygen/html/search/all_e.html | 30 + .../docs/doxygen/html/search/all_e.js | 8 + .../docs/doxygen/html/search/all_f.html | 30 + .../docs/doxygen/html/search/all_f.js | 12 + .../docs/doxygen/html/search/classes_0.html | 30 + .../docs/doxygen/html/search/classes_0.js | 4 + .../docs/doxygen/html/search/classes_1.html | 30 + .../docs/doxygen/html/search/classes_1.js | 51 + .../docs/doxygen/html/search/classes_2.html | 30 + .../docs/doxygen/html/search/classes_2.js | 5 + .../docs/doxygen/html/search/classes_3.html | 30 + .../docs/doxygen/html/search/classes_3.js | 4 + .../docs/doxygen/html/search/classes_4.html | 30 + .../docs/doxygen/html/search/classes_4.js | 4 + .../docs/doxygen/html/search/close.png | Bin 0 -> 273 bytes .../docs/doxygen/html/search/enums_0.html | 30 + .../docs/doxygen/html/search/enums_0.js | 4 + .../docs/doxygen/html/search/enums_1.html | 30 + .../docs/doxygen/html/search/enums_1.js | 5 + .../docs/doxygen/html/search/enums_2.html | 30 + .../docs/doxygen/html/search/enums_2.js | 4 + .../docs/doxygen/html/search/enums_3.html | 30 + .../docs/doxygen/html/search/enums_3.js | 4 + .../docs/doxygen/html/search/enums_4.html | 30 + .../docs/doxygen/html/search/enums_4.js | 4 + .../docs/doxygen/html/search/enums_5.html | 30 + .../docs/doxygen/html/search/enums_5.js | 4 + .../docs/doxygen/html/search/enums_6.html | 30 + .../docs/doxygen/html/search/enums_6.js | 4 + .../docs/doxygen/html/search/enums_7.html | 30 + .../docs/doxygen/html/search/enums_7.js | 5 + .../docs/doxygen/html/search/enums_8.html | 30 + .../docs/doxygen/html/search/enums_8.js | 4 + .../doxygen/html/search/enumvalues_0.html | 30 + .../docs/doxygen/html/search/enumvalues_0.js | 13 + .../doxygen/html/search/enumvalues_1.html | 30 + .../docs/doxygen/html/search/enumvalues_1.js | 8 + .../doxygen/html/search/enumvalues_10.html | 30 + .../docs/doxygen/html/search/enumvalues_10.js | 7 + .../doxygen/html/search/enumvalues_11.html | 30 + .../docs/doxygen/html/search/enumvalues_11.js | 5 + .../doxygen/html/search/enumvalues_12.html | 30 + .../docs/doxygen/html/search/enumvalues_12.js | 4 + .../doxygen/html/search/enumvalues_13.html | 30 + .../docs/doxygen/html/search/enumvalues_13.js | 5 + .../doxygen/html/search/enumvalues_14.html | 30 + .../docs/doxygen/html/search/enumvalues_14.js | 5 + .../doxygen/html/search/enumvalues_15.html | 30 + .../docs/doxygen/html/search/enumvalues_15.js | 4 + .../doxygen/html/search/enumvalues_2.html | 30 + .../docs/doxygen/html/search/enumvalues_2.js | 17 + .../doxygen/html/search/enumvalues_3.html | 30 + .../docs/doxygen/html/search/enumvalues_3.js | 5 + .../doxygen/html/search/enumvalues_4.html | 30 + .../docs/doxygen/html/search/enumvalues_4.js | 4 + .../doxygen/html/search/enumvalues_5.html | 30 + .../docs/doxygen/html/search/enumvalues_5.js | 8 + .../doxygen/html/search/enumvalues_6.html | 30 + .../docs/doxygen/html/search/enumvalues_6.js | 11 + .../doxygen/html/search/enumvalues_7.html | 30 + .../docs/doxygen/html/search/enumvalues_7.js | 4 + .../doxygen/html/search/enumvalues_8.html | 30 + .../docs/doxygen/html/search/enumvalues_8.js | 4 + .../doxygen/html/search/enumvalues_9.html | 30 + .../docs/doxygen/html/search/enumvalues_9.js | 35 + .../doxygen/html/search/enumvalues_a.html | 30 + .../docs/doxygen/html/search/enumvalues_a.js | 8 + .../doxygen/html/search/enumvalues_b.html | 30 + .../docs/doxygen/html/search/enumvalues_b.js | 15 + .../doxygen/html/search/enumvalues_c.html | 30 + .../docs/doxygen/html/search/enumvalues_c.js | 7 + .../doxygen/html/search/enumvalues_d.html | 30 + .../docs/doxygen/html/search/enumvalues_d.js | 7 + .../doxygen/html/search/enumvalues_e.html | 30 + .../docs/doxygen/html/search/enumvalues_e.js | 10 + .../doxygen/html/search/enumvalues_f.html | 30 + .../docs/doxygen/html/search/enumvalues_f.js | 14 + .../docs/doxygen/html/search/files_0.html | 30 + .../docs/doxygen/html/search/files_0.js | 7 + .../docs/doxygen/html/search/files_1.html | 30 + .../docs/doxygen/html/search/files_1.js | 8 + .../docs/doxygen/html/search/files_2.html | 30 + .../docs/doxygen/html/search/files_2.js | 4 + .../docs/doxygen/html/search/files_3.html | 30 + .../docs/doxygen/html/search/files_3.js | 104 + .../docs/doxygen/html/search/files_4.html | 30 + .../docs/doxygen/html/search/files_4.js | 4 + .../docs/doxygen/html/search/files_5.html | 30 + .../docs/doxygen/html/search/files_5.js | 4 + .../docs/doxygen/html/search/functions_0.html | 30 + .../docs/doxygen/html/search/functions_0.js | 17 + .../docs/doxygen/html/search/functions_1.html | 30 + .../docs/doxygen/html/search/functions_1.js | 14 + .../doxygen/html/search/functions_10.html | 30 + .../docs/doxygen/html/search/functions_10.js | 13 + .../doxygen/html/search/functions_11.html | 30 + .../docs/doxygen/html/search/functions_11.js | 218 + .../doxygen/html/search/functions_12.html | 30 + .../docs/doxygen/html/search/functions_12.js | 21 + .../doxygen/html/search/functions_13.html | 30 + .../docs/doxygen/html/search/functions_13.js | 6 + .../doxygen/html/search/functions_14.html | 30 + .../docs/doxygen/html/search/functions_14.js | 6 + .../doxygen/html/search/functions_15.html | 30 + .../docs/doxygen/html/search/functions_15.js | 4 + .../doxygen/html/search/functions_16.html | 30 + .../docs/doxygen/html/search/functions_16.js | 4 + .../doxygen/html/search/functions_17.html | 30 + .../docs/doxygen/html/search/functions_17.js | 4 + .../docs/doxygen/html/search/functions_2.html | 30 + .../docs/doxygen/html/search/functions_2.js | 8 + .../docs/doxygen/html/search/functions_3.html | 30 + .../docs/doxygen/html/search/functions_3.js | 34 + .../docs/doxygen/html/search/functions_4.html | 30 + .../docs/doxygen/html/search/functions_4.js | 95 + .../docs/doxygen/html/search/functions_5.html | 30 + .../docs/doxygen/html/search/functions_5.js | 26 + .../docs/doxygen/html/search/functions_6.html | 30 + .../docs/doxygen/html/search/functions_6.js | 8 + .../docs/doxygen/html/search/functions_7.html | 30 + .../docs/doxygen/html/search/functions_7.js | 114 + .../docs/doxygen/html/search/functions_8.html | 30 + .../docs/doxygen/html/search/functions_8.js | 15 + .../docs/doxygen/html/search/functions_9.html | 30 + .../docs/doxygen/html/search/functions_9.js | 64 + .../docs/doxygen/html/search/functions_a.html | 30 + .../docs/doxygen/html/search/functions_a.js | 4 + .../docs/doxygen/html/search/functions_b.html | 30 + .../docs/doxygen/html/search/functions_b.js | 6 + .../docs/doxygen/html/search/functions_c.html | 30 + .../docs/doxygen/html/search/functions_c.js | 25 + .../docs/doxygen/html/search/functions_d.html | 30 + .../docs/doxygen/html/search/functions_d.js | 4 + .../docs/doxygen/html/search/functions_e.html | 30 + .../docs/doxygen/html/search/functions_e.js | 6 + .../docs/doxygen/html/search/functions_f.html | 30 + .../docs/doxygen/html/search/functions_f.js | 4 + .../docs/doxygen/html/search/mag_sel.png | Bin 0 -> 465 bytes .../doxygen/html/search/namespaces_0.html | 30 + .../docs/doxygen/html/search/namespaces_0.js | 5 + .../doxygen/html/search/namespaces_1.html | 30 + .../docs/doxygen/html/search/namespaces_1.js | 4 + .../docs/doxygen/html/search/nomatches.html | 12 + .../docs/doxygen/html/search/pages_0.html | 30 + .../docs/doxygen/html/search/pages_0.js | 4 + .../docs/doxygen/html/search/pages_1.html | 30 + .../docs/doxygen/html/search/pages_1.js | 5 + .../docs/doxygen/html/search/pages_2.html | 30 + .../docs/doxygen/html/search/pages_2.js | 4 + .../docs/doxygen/html/search/related_0.html | 30 + .../docs/doxygen/html/search/related_0.js | 4 + .../docs/doxygen/html/search/search.css | 271 + .../docs/doxygen/html/search/search.js | 814 ++ .../docs/doxygen/html/search/search_l.png | Bin 0 -> 567 bytes .../docs/doxygen/html/search/search_m.png | Bin 0 -> 158 bytes .../docs/doxygen/html/search/search_r.png | Bin 0 -> 553 bytes .../docs/doxygen/html/search/searchdata.js | 45 + .../docs/doxygen/html/search/typedefs_0.html | 30 + .../docs/doxygen/html/search/typedefs_0.js | 4 + .../docs/doxygen/html/search/variables_0.html | 30 + .../docs/doxygen/html/search/variables_0.js | 36 + .../docs/doxygen/html/search/variables_1.html | 30 + .../docs/doxygen/html/search/variables_1.js | 5 + .../doxygen/html/search/variables_10.html | 30 + .../docs/doxygen/html/search/variables_10.js | 11 + .../doxygen/html/search/variables_11.html | 30 + .../docs/doxygen/html/search/variables_11.js | 15 + .../doxygen/html/search/variables_12.html | 30 + .../docs/doxygen/html/search/variables_12.js | 7 + .../doxygen/html/search/variables_13.html | 30 + .../docs/doxygen/html/search/variables_13.js | 5 + .../doxygen/html/search/variables_14.html | 30 + .../docs/doxygen/html/search/variables_14.js | 4 + .../doxygen/html/search/variables_15.html | 30 + .../docs/doxygen/html/search/variables_15.js | 4 + .../doxygen/html/search/variables_16.html | 30 + .../docs/doxygen/html/search/variables_16.js | 4 + .../docs/doxygen/html/search/variables_2.html | 30 + .../docs/doxygen/html/search/variables_2.js | 7 + .../docs/doxygen/html/search/variables_3.html | 30 + .../docs/doxygen/html/search/variables_3.js | 10 + .../docs/doxygen/html/search/variables_4.html | 30 + .../docs/doxygen/html/search/variables_4.js | 6 + .../docs/doxygen/html/search/variables_5.html | 30 + .../docs/doxygen/html/search/variables_5.js | 4 + .../docs/doxygen/html/search/variables_6.html | 30 + .../docs/doxygen/html/search/variables_6.js | 6 + .../docs/doxygen/html/search/variables_7.html | 30 + .../docs/doxygen/html/search/variables_7.js | 4 + .../docs/doxygen/html/search/variables_8.html | 30 + .../docs/doxygen/html/search/variables_8.js | 7 + .../docs/doxygen/html/search/variables_9.html | 30 + .../docs/doxygen/html/search/variables_9.js | 2528 ++++++ .../docs/doxygen/html/search/variables_a.html | 30 + .../docs/doxygen/html/search/variables_a.js | 7 + .../docs/doxygen/html/search/variables_b.html | 30 + .../docs/doxygen/html/search/variables_b.js | 8 + .../docs/doxygen/html/search/variables_c.html | 30 + .../docs/doxygen/html/search/variables_c.js | 4 + .../docs/doxygen/html/search/variables_d.html | 30 + .../docs/doxygen/html/search/variables_d.js | 8 + .../docs/doxygen/html/search/variables_e.html | 30 + .../docs/doxygen/html/search/variables_e.js | 8 + .../docs/doxygen/html/search/variables_f.html | 30 + .../docs/doxygen/html/search/variables_f.js | 4 + .../docs/doxygen/html/splitbar.png | Bin 0 -> 314 bytes .../html/structirparams__t-members.html | 87 + .../docs/doxygen/html/structirparams__t.html | 222 + .../html/structmatch__result__t-members.html | 82 + .../doxygen/html/structmatch__result__t.html | 142 + .../html/structstdAc_1_1state__t-members.html | 101 + .../doxygen/html/structstdAc_1_1state__t.html | 386 + .../docs/doxygen/html/sync_off.png | Bin 0 -> 853 bytes .../docs/doxygen/html/sync_on.png | Bin 0 -> 845 bytes .../docs/doxygen/html/tab_a.png | Bin 0 -> 142 bytes .../docs/doxygen/html/tab_b.png | Bin 0 -> 169 bytes .../docs/doxygen/html/tab_h.png | Bin 0 -> 177 bytes .../docs/doxygen/html/tab_s.png | Bin 0 -> 184 bytes .../docs/doxygen/html/tabs.css | 1 + .../docs/doxygen/html/todo.html | 99 + .../doxygen/html/unionmagiquest-members.html | 87 + .../docs/doxygen/html/unionmagiquest.html | 223 + .../docs/doxygen/html/zh-CN_8h.html | 82 + .../docs/doxygen/html/zh-CN_8h_source.html | 545 ++ .../docs/doxygen_index.md | 60 + .../examples/BlynkIrRemote/BlynkIrRemote.ino | 0 .../examples/BlynkIrRemote/platformio.ini | 1 + .../CommonAcControl/CommonAcControl.ino | 0 .../examples/CommonAcControl/platformio.ini | 26 + .../ControlSamsungAC/ControlSamsungAC.ino | 0 .../examples/ControlSamsungAC}/platformio.ini | 1 + .../DumbIRRepeater/DumbIRRepeater.ino | 0 .../examples/DumbIRRepeater}/platformio.ini | 1 + .../examples/IRGCSendDemo/IRGCSendDemo.ino | 0 .../examples/IRGCSendDemo}/platformio.ini | 1 + .../examples/IRGCTCPServer/IRGCTCPServer.ino | 0 .../examples/IRGCTCPServer}/platformio.ini | 1 + .../examples/IRMQTTServer/IRMQTTServer.h | 0 .../examples/IRMQTTServer/IRMQTTServer.ino | 0 .../examples/IRMQTTServer/platformio.ini | 1 + .../examples/IRServer/IRServer.ino | 0 .../examples/IRServer/platformio.ini | 18 + .../examples/IRrecvDemo/IRrecvDemo.ino | 2 +- .../examples/IRrecvDemo/platformio.ini | 18 + .../examples/IRrecvDump/IRrecvDump.ino | 0 .../examples/IRrecvDump/platformio.ini | 18 + .../examples/IRrecvDumpV2/IRrecvDumpV2.ino | 0 .../examples/IRrecvDumpV2}/platformio.ini | 6 + .../examples/IRrecvDumpV3/BaseOTA.h | 0 .../examples/IRrecvDumpV3/IRrecvDumpV3.ino | 0 .../examples/IRrecvDumpV3}/platformio.ini | 1 + .../examples/IRsendDemo/IRsendDemo.ino | 0 .../examples/IRsendDemo/platformio.ini | 18 + .../IRsendProntoDemo/IRsendProntoDemo.ino | 0 .../examples/IRsendProntoDemo/platformio.ini | 18 + .../JVCPanasonicSendDemo.ino | 0 .../JVCPanasonicSendDemo/platformio.ini | 18 + .../examples/LGACSend/LGACSend.ino | 0 .../examples/LGACSend/platformio.ini | 18 + .../SmartIRRepeater/SmartIRRepeater.ino | 2 + .../examples/SmartIRRepeater/platformio.ini | 36 + .../examples/TurnOnArgoAC/TurnOnArgoAC.ino | 0 .../examples/TurnOnArgoAC/platformio.ini | 18 + .../TurnOnDaikinAC/TurnOnDaikinAC.ino | 0 .../examples/TurnOnDaikinAC/platformio.ini | 18 + .../TurnOnFujitsuAC/TurnOnFujitsuAC.ino | 0 .../examples/TurnOnFujitsuAC/platformio.ini | 18 + .../examples/TurnOnGreeAC/TurnOnGreeAC.ino | 0 .../examples/TurnOnGreeAC/platformio.ini | 18 + .../TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino | 0 .../TurnOnKelvinatorAC/platformio.ini | 18 + .../TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino | 0 .../TurnOnMitsubishiAC/platformio.ini | 18 + .../TurnOnMitsubishiHeavyAc.ino | 0 .../TurnOnMitsubishiHeavyAc/platformio.ini | 18 + .../TurnOnPanasonicAC/TurnOnPanasonicAC.ino | 0 .../examples/TurnOnPanasonicAC/platformio.ini | 18 + .../TurnOnToshibaAC/TurnOnToshibaAC.ino | 0 .../examples/TurnOnToshibaAC/platformio.ini | 18 + .../TurnOnTrotecAC/TurnOnTrotecAC.ino | 0 .../examples/TurnOnTrotecAC/platformio.ini | 18 + .../examples/Web-AC-control/README.md | 0 .../Web-AC-control/Web-AC-control.ino | 0 .../examples/Web-AC-control/platformio.ini | 1 + .../examples/Web-AC-control/printscreen.png | Bin .../Web-AC-control/upload/favicon.ico | Bin .../Web-AC-control/upload/level_1_off.svg | 0 .../Web-AC-control/upload/level_1_on.svg | 0 .../Web-AC-control/upload/level_2_off.svg | 0 .../Web-AC-control/upload/level_2_on.svg | 0 .../Web-AC-control/upload/level_3_off.svg | 0 .../Web-AC-control/upload/level_3_on.svg | 0 .../Web-AC-control/upload/level_4_off.svg | 0 .../Web-AC-control/upload/level_4_on.svg | 0 .../examples/Web-AC-control/upload/ui.html | 0 .../examples/Web-AC-control/upload/ui.js | 0 .../keywords.txt | 177 +- .../library.json | 2 +- .../library.properties | 2 +- .../platformio.ini | 1 + .../pylintrc | 0 .../src/CPPLINT.cfg | 0 .../src/IRac.cpp | 828 +- .../src/IRac.h | 23 +- .../src/IRrecv.cpp | 902 +- .../src/IRrecv.h | 48 +- .../src/IRremoteESP8266.h | 63 +- .../src/IRsend.cpp | 517 +- .../src/IRsend.h | 105 +- lib/IRremoteESP8266-2.7.8/src/IRtext.cpp | 268 + .../src/IRtext.h | 1 + .../src/IRtimer.cpp | 20 +- .../src/IRtimer.h | 5 + .../src/IRutils.cpp | 426 +- .../src/IRutils.h | 4 + .../src/i18n.h | 0 .../src/ir_Airwell.cpp | 59 +- .../src/ir_Aiwa.cpp | 71 +- .../src/ir_Amcor.cpp | 116 +- .../src/ir_Amcor.h | 28 +- .../src/ir_Argo.cpp | 144 +- .../src/ir_Argo.h | 14 +- lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp | 545 ++ lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h | 131 + .../src/ir_Coolix.cpp | 166 +- .../src/ir_Coolix.h | 35 +- lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp | 598 ++ lib/IRremoteESP8266-2.7.8/src/ir_Corona.h | 155 + .../src/ir_Daikin.cpp | 1290 ++- .../src/ir_Daikin.h | 174 +- .../src/ir_Delonghi.cpp | 152 +- .../src/ir_Delonghi.h | 38 +- .../src/ir_Denon.cpp | 60 +- .../src/ir_Dish.cpp | 88 +- .../src/ir_Doshisha.cpp | 80 +- .../src/ir_Electra.cpp | 147 +- .../src/ir_Electra.h | 35 +- .../src/ir_Epson.cpp | 56 +- .../src/ir_Fujitsu.cpp | 193 +- .../src/ir_Fujitsu.h | 26 +- .../src/ir_GICable.cpp | 50 +- .../src/ir_GlobalCache.cpp | 37 +- .../src/ir_Goodweather.cpp | 130 +- .../src/ir_Goodweather.h | 27 +- .../src/ir_Gree.cpp | 219 +- .../src/ir_Gree.h | 22 +- .../src/ir_Haier.cpp | 278 +- .../src/ir_Haier.h | 61 +- .../src/ir_Hitachi.cpp | 687 +- .../src/ir_Hitachi.h | 168 +- .../src/ir_Inax.cpp | 61 +- .../src/ir_JVC.cpp | 80 +- .../src/ir_Kelvinator.cpp | 170 +- .../src/ir_Kelvinator.h | 23 +- .../src/ir_LG.cpp | 222 +- .../src/ir_LG.h | 30 +- .../src/ir_Lasertag.cpp | 56 +- .../src/ir_Lego.cpp | 53 +- .../src/ir_Lutron.cpp | 73 +- .../src/ir_MWM.cpp | 51 +- .../src/ir_Magiquest.cpp | 87 +- .../src/ir_Magiquest.h | 10 +- .../src/ir_Midea.cpp | 283 +- .../src/ir_Midea.h | 39 +- .../src/ir_Mitsubishi.cpp | 637 +- .../src/ir_Mitsubishi.h | 85 +- .../src/ir_MitsubishiHeavy.cpp | 296 +- .../src/ir_MitsubishiHeavy.h | 58 +- .../src/ir_Multibrackets.cpp | 55 +- .../src/ir_NEC.cpp | 90 +- .../src/ir_NEC.h | 22 +- .../src/ir_Neoclima.cpp | 181 +- .../src/ir_Neoclima.h | 39 +- .../src/ir_Nikai.cpp | 49 +- .../src/ir_Panasonic.cpp | 361 +- .../src/ir_Panasonic.h | 68 +- .../src/ir_Pioneer.cpp | 78 +- .../src/ir_Pronto.cpp | 79 +- .../src/ir_RC5_RC6.cpp | 316 +- .../src/ir_RCMM.cpp | 49 +- .../src/ir_Samsung.cpp | 322 +- .../src/ir_Samsung.h | 59 +- .../src/ir_Sanyo.cpp | 156 +- .../src/ir_Sharp.cpp | 359 +- .../src/ir_Sharp.h | 38 +- lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp | 24 + .../src/ir_Sony.cpp | 143 +- .../src/ir_Symphony.cpp | 51 +- .../src/ir_Tcl.cpp | 145 +- .../src/ir_Tcl.h | 25 +- .../src/ir_Teco.cpp | 126 +- .../src/ir_Teco.h | 31 +- .../src/ir_Toshiba.cpp | 164 +- .../src/ir_Toshiba.h | 24 +- .../src/ir_Trotec.cpp | 112 +- .../src/ir_Trotec.h | 32 +- .../src/ir_Vestel.cpp | 222 +- .../src/ir_Vestel.h | 28 +- .../src/ir_Whirlpool.cpp | 199 +- .../src/ir_Whirlpool.h | 38 +- .../src/ir_Whynter.cpp | 55 +- lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp | 94 + .../src/locale/README.md | 36 +- .../src/locale/de-CH.h | 4 +- .../src/locale/de-DE.h | 4 +- .../src/locale/defaults.h | 19 +- .../src/locale/en-AU.h | 0 .../src/locale/en-IE.h | 0 .../src/locale/en-UK.h | 0 .../src/locale/en-US.h | 0 .../src/locale/es-ES.h | 4 +- .../src/locale/fr-FR.h | 4 +- .../src/locale/it-IT.h | 4 +- .../src/locale/zh-CN.h | 6 +- .../test/IRac_test.cpp | 134 +- .../test/IRrecv_test.cpp | 235 +- .../test/IRrecv_test.h | 0 .../test/IRsend_test.cpp | 26 +- .../test/IRsend_test.h | 0 .../test/IRutils_test.cpp | 25 + .../test/Makefile | 2 +- .../test/ir_Airwell_test.cpp | 105 +- .../test/ir_Aiwa_test.cpp | 0 .../test/ir_Amcor_test.cpp | 0 .../test/ir_Argo_test.cpp | 0 .../test/ir_Carrier_test.cpp | 217 +- .../test/ir_Coolix_test.cpp | 0 .../test/ir_Corona_test.cpp | 1690 ++++ .../test/ir_Daikin_test.cpp | 0 .../test/ir_Delonghi_test.cpp | 0 .../test/ir_Denon_test.cpp | 0 .../test/ir_Dish_test.cpp | 0 .../test/ir_Doshisha_test.cpp | 0 .../test/ir_Electra_test.cpp | 0 .../test/ir_Epson_test.cpp | 0 .../test/ir_Fujitsu_test.cpp | 0 .../test/ir_GICable_test.cpp | 0 .../test/ir_GlobalCache_test.cpp | 0 .../test/ir_Goodweather_test.cpp | 0 .../test/ir_Gree_test.cpp | 0 .../test/ir_Haier_test.cpp | 0 .../test/ir_Hitachi_test.cpp | 195 +- .../test/ir_Inax_test.cpp | 0 .../test/ir_JVC_test.cpp | 0 .../test/ir_Kelvinator_test.cpp | 0 .../test/ir_LG_test.cpp | 23 +- .../test/ir_Lasertag_test.cpp | 0 .../test/ir_Lego_test.cpp | 0 .../test/ir_Lutron_test.cpp | 0 .../test/ir_MWM_test.cpp | 0 .../test/ir_Magiquest_test.cpp | 0 .../test/ir_Midea_test.cpp | 162 + .../test/ir_MitsubishiHeavy_test.cpp | 0 .../test/ir_Mitsubishi_test.cpp | 0 .../test/ir_Multibrackets_test.cpp | 0 .../test/ir_NEC_test.cpp | 0 .../test/ir_Neoclima_test.cpp | 0 .../test/ir_Nikai_test.cpp | 0 .../test/ir_Panasonic_test.cpp | 0 .../test/ir_Pioneer_test.cpp | 0 .../test/ir_Pronto_test.cpp | 0 .../test/ir_RC5_RC6_test.cpp | 0 .../test/ir_RCMM_test.cpp | 0 .../test/ir_Samsung_test.cpp | 0 .../test/ir_Sanyo_test.cpp | 0 .../test/ir_Sharp_test.cpp | 0 .../test/ir_Sherwood_test.cpp | 0 .../test/ir_Sony_test.cpp | 0 .../test/ir_Symphony_test.cpp | 0 .../test/ir_Tcl_test.cpp | 0 .../test/ir_Teco_test.cpp | 0 .../test/ir_Toshiba_test.cpp | 0 .../test/ir_Trotec_test.cpp | 0 .../test/ir_Vestel_test.cpp | 0 .../test/ir_Whirlpool_test.cpp | 0 .../test/ir_Whynter_test.cpp | 0 .../test/ir_Zepeal_test.cpp | 312 + .../tools/Makefile | 0 .../tools/RawToGlobalCache.sh | 0 .../tools/auto_analyse_raw_data.py | 130 +- .../tools/auto_analyse_raw_data_test.py | 89 +- .../tools/gc_decode.cpp | 0 .../tools/generate_irtext_h.sh | 0 .../tools/mkkeywords | 0 .../tools/mode2_decode.cpp | 0 .../tools/raw_to_pronto_code.py | 0 .../tools/raw_to_pronto_code_test.py | 0 .../tools/scrape_supported_devices.py | 207 +- tasmota/CHANGELOG.md | 1 + 1269 files changed, 227450 insertions(+), 6389 deletions(-) delete mode 100644 lib/IRremoteESP8266-2.7.7/docs/README.md delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/IRServer/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/LGACSend/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/platformio.ini delete mode 100644 lib/IRremoteESP8266-2.7.7/src/IRtext.cpp delete mode 100644 lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp delete mode 100644 lib/IRremoteESP8266-2.7.7/src/ir_Sherwood.cpp rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/CPPLINT.cfg (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/Doxyfile rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/LICENSE.txt (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/README.md (90%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/README_fr.md (84%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/ReleaseNotes.md (93%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/SupportedProtocols.md (67%) create mode 100644 lib/IRremoteESP8266-2.7.8/docs/README.md create mode 100644 lib/IRremoteESP8266-2.7.8/docs/README_fr.md rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/docs/_config.yml (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/README_8md.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/annotated.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bc_s.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bdwn.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classes.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/closed.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/deprecated.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doc.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.css create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen__index_8md.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dynsections.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/files.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderclosed.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderopen.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_a.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_b.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_c.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_d.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_e.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_f.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_a.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_b.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_c.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_d.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_e.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_f.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_g.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_i.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_k.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_l.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_m.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_n.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_o.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_p.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_r.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_s.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_t.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_u.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_v.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_w.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_~.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_g.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_i.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_k.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_l.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_m.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_n.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_o.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_p.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_q.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_r.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_rela.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_s.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_t.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_u.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_v.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_a.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_b.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_c.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_d.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_e.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_f.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_i.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_l.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_m.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_n.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_o.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_p.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_q.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_r.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_s.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_t.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_u.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_v.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_w.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_z.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_w.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_z.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_~.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_a.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_c.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_d.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_e.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_enum.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_eval.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_f.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_func.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_g.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_i.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_j.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_k.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_l.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_m.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_n.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_p.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_r.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_s.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_t.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_type.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_u.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_v.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_i.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_k.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_w.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_x.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_y.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_z.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/hierarchy.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/index.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.map create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.md5 create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherits.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Airwell_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Aiwa_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Denon_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Dish_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Doshisha_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Epson_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GICable_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GlobalCache_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Inax_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__JVC_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lasertag_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lego_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lutron_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MWM_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Multibrackets_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Nikai_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pioneer_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pronto_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RC5__RC6_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RCMM_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sanyo_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sherwood_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sony_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Symphony_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whynter_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Zepeal_8cpp.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/jquery.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/md_src_locale_README.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menu.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menudata.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceIRAcUtils.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceirutils.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_enum.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_func.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaces.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacestdAc.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_f.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_g.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_h.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/open.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/pages.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/close.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/mag_sel.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/nomatches.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.css create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_l.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_m.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_r.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/searchdata.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.js create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/splitbar.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_off.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_on.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_a.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_b.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_h.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_s.png create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tabs.css create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/todo.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest-members.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h_source.html create mode 100644 lib/IRremoteESP8266-2.7.8/docs/doxygen_index.md rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/BlynkIrRemote/BlynkIrRemote.ino (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/BlynkIrRemote/platformio.ini (96%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/CommonAcControl/CommonAcControl.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/ControlSamsungAC/ControlSamsungAC.ino (100%) rename lib/{IRremoteESP8266-2.7.7/examples/IRGCSendDemo => IRremoteESP8266-2.7.8/examples/ControlSamsungAC}/platformio.ini (92%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/DumbIRRepeater/DumbIRRepeater.ino (100%) rename lib/{IRremoteESP8266-2.7.7/examples/CommonAcControl => IRremoteESP8266-2.7.8/examples/DumbIRRepeater}/platformio.ini (92%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRGCSendDemo/IRGCSendDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.7/examples/ControlSamsungAC => IRremoteESP8266-2.7.8/examples/IRGCSendDemo}/platformio.ini (92%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRGCTCPServer/IRGCTCPServer.ino (100%) rename lib/{IRremoteESP8266-2.7.7/examples/DumbIRRepeater => IRremoteESP8266-2.7.8/examples/IRGCTCPServer}/platformio.ini (92%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRMQTTServer/IRMQTTServer.h (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRMQTTServer/IRMQTTServer.ino (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRMQTTServer/platformio.ini (97%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRServer/IRServer.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/IRServer/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRrecvDemo/IRrecvDemo.ino (95%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRrecvDump/IRrecvDump.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRrecvDumpV2/IRrecvDumpV2.ino (100%) rename lib/{IRremoteESP8266-2.7.7/examples/IRrecvDumpV3 => IRremoteESP8266-2.7.8/examples/IRrecvDumpV2}/platformio.ini (81%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRrecvDumpV3/BaseOTA.h (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRrecvDumpV3/IRrecvDumpV3.ino (100%) rename lib/{IRremoteESP8266-2.7.7/examples/IRrecvDumpV2 => IRremoteESP8266-2.7.8/examples/IRrecvDumpV3}/platformio.ini (97%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRsendDemo/IRsendDemo.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/IRsendProntoDemo/IRsendProntoDemo.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/LGACSend/LGACSend.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/LGACSend/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/SmartIRRepeater/SmartIRRepeater.ino (99%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnArgoAC/TurnOnArgoAC.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnGreeAC/TurnOnGreeAC.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/platformio.ini rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/README.md (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/Web-AC-control.ino (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/platformio.ini (96%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/printscreen.png (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/favicon.ico (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/level_1_off.svg (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/level_1_on.svg (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/level_2_off.svg (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/level_2_on.svg (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/level_3_off.svg (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/level_3_on.svg (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/level_4_off.svg (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/level_4_on.svg (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/ui.html (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/examples/Web-AC-control/upload/ui.js (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/keywords.txt (95%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/library.json (98%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/library.properties (97%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/platformio.ini (94%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/pylintrc (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/CPPLINT.cfg (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRac.cpp (68%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRac.h (94%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRrecv.cpp (61%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRrecv.h (93%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRremoteESP8266.h (94%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRsend.cpp (65%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRsend.h (87%) create mode 100644 lib/IRremoteESP8266-2.7.8/src/IRtext.cpp rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRtext.h (99%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRtimer.cpp (69%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRtimer.h (65%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRutils.cpp (61%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/IRutils.h (95%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/i18n.h (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Airwell.cpp (55%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Aiwa.cpp (63%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Amcor.cpp (68%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Amcor.h (85%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Argo.cpp (69%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Argo.h (91%) create mode 100644 lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp create mode 100644 lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Coolix.cpp (75%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Coolix.h (88%) create mode 100644 lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp create mode 100644 lib/IRremoteESP8266-2.7.8/src/ir_Corona.h rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Daikin.cpp (70%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Daikin.h (84%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Delonghi.cpp (69%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Delonghi.h (85%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Denon.cpp (71%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Dish.cpp (56%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Doshisha.cpp (66%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Electra.cpp (65%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Electra.h (85%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Epson.cpp (70%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Fujitsu.cpp (79%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Fujitsu.h (86%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_GICable.cpp (71%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_GlobalCache.cpp (65%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Goodweather.cpp (74%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Goodweather.h (85%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Gree.cpp (72%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Gree.h (89%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Haier.cpp (71%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Haier.h (83%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Hitachi.cpp (60%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Hitachi.h (62%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Inax.cpp (57%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_JVC.cpp (70%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Kelvinator.cpp (75%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Kelvinator.h (89%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_LG.cpp (70%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_LG.h (78%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Lasertag.cpp (67%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Lego.cpp (72%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Lutron.cpp (69%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_MWM.cpp (80%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Magiquest.cpp (63%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Magiquest.h (73%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Midea.cpp (58%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Midea.h (76%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Mitsubishi.cpp (71%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Mitsubishi.h (77%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_MitsubishiHeavy.cpp (73%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_MitsubishiHeavy.h (82%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Multibrackets.cpp (74%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_NEC.cpp (65%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_NEC.h (88%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Neoclima.cpp (68%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Neoclima.h (84%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Nikai.cpp (66%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Panasonic.cpp (69%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Panasonic.h (73%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Pioneer.cpp (70%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Pronto.cpp (54%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_RC5_RC6.cpp (59%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_RCMM.cpp (80%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Samsung.cpp (70%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Samsung.h (76%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Sanyo.cpp (55%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Sharp.cpp (64%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Sharp.h (82%) create mode 100644 lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Sony.cpp (57%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Symphony.cpp (62%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Tcl.cpp (64%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Tcl.h (84%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Teco.cpp (65%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Teco.h (85%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Toshiba.cpp (68%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Toshiba.h (78%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Trotec.cpp (65%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Trotec.h (75%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Vestel.cpp (67%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Vestel.h (87%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Whirlpool.cpp (71%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Whirlpool.h (83%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/ir_Whynter.cpp (70%) create mode 100644 lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/README.md (68%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/de-CH.h (98%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/de-DE.h (97%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/defaults.h (97%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/en-AU.h (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/en-IE.h (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/en-UK.h (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/en-US.h (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/es-ES.h (97%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/fr-FR.h (97%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/it-IT.h (98%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/src/locale/zh-CN.h (99%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/IRac_test.cpp (93%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/IRrecv_test.cpp (85%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/IRrecv_test.h (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/IRsend_test.cpp (96%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/IRsend_test.h (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/IRutils_test.cpp (95%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/Makefile (99%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Airwell_test.cpp (72%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Aiwa_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Amcor_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Argo_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Carrier_test.cpp (75%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Coolix_test.cpp (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/test/ir_Corona_test.cpp rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Daikin_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Delonghi_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Denon_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Dish_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Doshisha_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Electra_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Epson_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Fujitsu_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_GICable_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_GlobalCache_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Goodweather_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Gree_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Haier_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Hitachi_test.cpp (89%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Inax_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_JVC_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Kelvinator_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_LG_test.cpp (97%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Lasertag_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Lego_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Lutron_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_MWM_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Magiquest_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Midea_test.cpp (79%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_MitsubishiHeavy_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Mitsubishi_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Multibrackets_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_NEC_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Neoclima_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Nikai_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Panasonic_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Pioneer_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Pronto_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_RC5_RC6_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_RCMM_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Samsung_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Sanyo_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Sharp_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Sherwood_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Sony_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Symphony_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Tcl_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Teco_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Toshiba_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Trotec_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Vestel_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Whirlpool_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/test/ir_Whynter_test.cpp (100%) create mode 100644 lib/IRremoteESP8266-2.7.8/test/ir_Zepeal_test.cpp rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/Makefile (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/RawToGlobalCache.sh (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/auto_analyse_raw_data.py (92%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/auto_analyse_raw_data_test.py (97%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/gc_decode.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/generate_irtext_h.sh (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/mkkeywords (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/mode2_decode.cpp (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/raw_to_pronto_code.py (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/raw_to_pronto_code_test.py (100%) rename lib/{IRremoteESP8266-2.7.7 => IRremoteESP8266-2.7.8}/tools/scrape_supported_devices.py (57%) diff --git a/lib/IRremoteESP8266-2.7.7/docs/README.md b/lib/IRremoteESP8266-2.7.7/docs/README.md deleted file mode 100644 index fea1f636f..000000000 --- a/lib/IRremoteESP8266-2.7.7/docs/README.md +++ /dev/null @@ -1 +0,0 @@ -Documentation goes here. diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRServer/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRServer/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/IRServer/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/LGACSend/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/LGACSend/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/LGACSend/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/platformio.ini b/lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/src/IRtext.cpp b/lib/IRremoteESP8266-2.7.7/src/IRtext.cpp deleted file mode 100644 index f612ed8d1..000000000 --- a/lib/IRremoteESP8266-2.7.7/src/IRtext.cpp +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2019-2020 - David Conran (@crankyoldgit) - -/// @warn If you add or remove an entry in this file, you should run: -/// '../tools/generate_irtext_h.sh' to rebuild the `IRtext.h` file. - -#ifndef UNIT_TEST -#include -#endif // UNIT_TEST -#include "IRremoteESP8266.h" -#include "i18n.h" - -#ifndef PROGMEM -#define PROGMEM // Pretend we have the PROGMEM macro even if we really don't. -#endif - -// Common - -const PROGMEM char* kUnknownStr = D_STR_UNKNOWN; -const PROGMEM char* kProtocolStr = D_STR_PROTOCOL; -const PROGMEM char* kPowerStr = D_STR_POWER; -const PROGMEM char* kOnStr = D_STR_ON; -const PROGMEM char* kOffStr = D_STR_OFF; -const PROGMEM char* kModeStr = D_STR_MODE; -const PROGMEM char* kToggleStr = D_STR_TOGGLE; -const PROGMEM char* kTurboStr = D_STR_TURBO; -const PROGMEM char* kSuperStr = D_STR_SUPER; -const PROGMEM char* kSleepStr = D_STR_SLEEP; -const PROGMEM char* kLightStr = D_STR_LIGHT; -const PROGMEM char* kPowerfulStr = D_STR_POWERFUL; -const PROGMEM char* kQuietStr = D_STR_QUIET; -const PROGMEM char* kEconoStr = D_STR_ECONO; -const PROGMEM char* kSwingStr = D_STR_SWING; -const PROGMEM char* kSwingHStr = D_STR_SWINGH; -const PROGMEM char* kSwingVStr = D_STR_SWINGV; -const PROGMEM char* kBeepStr = D_STR_BEEP; -const PROGMEM char* kZoneFollowStr = D_STR_ZONEFOLLOW; -const PROGMEM char* kFixedStr = D_STR_FIXED; -const PROGMEM char* kMouldStr = D_STR_MOULD; -const PROGMEM char* kCleanStr = D_STR_CLEAN; -const PROGMEM char* kPurifyStr = D_STR_PURIFY; -const PROGMEM char* kTimerStr = D_STR_TIMER; -const PROGMEM char* kOnTimerStr = D_STR_ONTIMER; -const PROGMEM char* kOffTimerStr = D_STR_OFFTIMER; -const PROGMEM char* kClockStr = D_STR_CLOCK; -const PROGMEM char* kCommandStr = D_STR_COMMAND; -const PROGMEM char* kXFanStr = D_STR_XFAN; -const PROGMEM char* kHealthStr = D_STR_HEALTH; -const PROGMEM char* kModelStr = D_STR_MODEL; -const PROGMEM char* kTempStr = D_STR_TEMP; -const PROGMEM char* kIFeelStr = D_STR_IFEEL; -const PROGMEM char* kHumidStr = D_STR_HUMID; -const PROGMEM char* kSaveStr = D_STR_SAVE; -const PROGMEM char* kEyeStr = D_STR_EYE; -const PROGMEM char* kFollowStr = D_STR_FOLLOW; -const PROGMEM char* kIonStr = D_STR_ION; -const PROGMEM char* kFreshStr = D_STR_FRESH; -const PROGMEM char* kHoldStr = D_STR_HOLD; -const PROGMEM char* kButtonStr = D_STR_BUTTON; -const PROGMEM char* k8CHeatStr = D_STR_8C_HEAT; -const PROGMEM char* kNightStr = D_STR_NIGHT; -const PROGMEM char* kSilentStr = D_STR_SILENT; -const PROGMEM char* kFilterStr = D_STR_FILTER; -const PROGMEM char* k3DStr = D_STR_3D; -const PROGMEM char* kCelsiusStr = D_STR_CELSIUS; -const PROGMEM char* kTempUpStr = D_STR_TEMPUP; -const PROGMEM char* kTempDownStr = D_STR_TEMPDOWN; -const PROGMEM char* kStartStr = D_STR_START; -const PROGMEM char* kStopStr = D_STR_STOP; -const PROGMEM char* kMoveStr = D_STR_MOVE; -const PROGMEM char* kSetStr = D_STR_SET; -const PROGMEM char* kCancelStr = D_STR_CANCEL; -const PROGMEM char* kUpStr = D_STR_UP; -const PROGMEM char* kDownStr = D_STR_DOWN; -const PROGMEM char* kChangeStr = D_STR_CHANGE; -const PROGMEM char* kComfortStr = D_STR_COMFORT; -const PROGMEM char* kSensorStr = D_STR_SENSOR; -const PROGMEM char* kWeeklyTimerStr = D_STR_WEEKLYTIMER; -const PROGMEM char* kWifiStr = D_STR_WIFI; -const PROGMEM char* kLastStr = D_STR_LAST; -const PROGMEM char* kFastStr = D_STR_FAST; -const PROGMEM char* kSlowStr = D_STR_SLOW; -const PROGMEM char* kAirFlowStr = D_STR_AIRFLOW; -const PROGMEM char* kStepStr = D_STR_STEP; -const PROGMEM char* kNAStr = D_STR_NA; -const PROGMEM char* kInsideStr = D_STR_INSIDE; -const PROGMEM char* kOutsideStr = D_STR_OUTSIDE; -const PROGMEM char* kLoudStr = D_STR_LOUD; -const PROGMEM char* kLowerStr = D_STR_LOWER; -const PROGMEM char* kUpperStr = D_STR_UPPER; -const PROGMEM char* kBreezeStr = D_STR_BREEZE; -const PROGMEM char* kCirculateStr = D_STR_CIRCULATE; -const PROGMEM char* kCeilingStr = D_STR_CEILING; -const PROGMEM char* kWallStr = D_STR_WALL; -const PROGMEM char* kRoomStr = D_STR_ROOM; -const PROGMEM char* k6thSenseStr = D_STR_6THSENSE; - -const PROGMEM char* kAutoStr = D_STR_AUTO; -const PROGMEM char* kAutomaticStr = D_STR_AUTOMATIC; -const PROGMEM char* kManualStr = D_STR_MANUAL; -const PROGMEM char* kCoolStr = D_STR_COOL; -const PROGMEM char* kHeatStr = D_STR_HEAT; -const PROGMEM char* kFanStr = D_STR_FAN; -const PROGMEM char* kDryStr = D_STR_DRY; -const PROGMEM char* kFanOnlyStr = D_STR_FANONLY; - -const PROGMEM char* kMaxStr = D_STR_MAX; -const PROGMEM char* kMaximumStr = D_STR_MAXIMUM; -const PROGMEM char* kMinStr = D_STR_MIN; -const PROGMEM char* kMinimumStr = D_STR_MINIMUM; -const PROGMEM char* kMedStr = D_STR_MED; -const PROGMEM char* kMediumStr = D_STR_MEDIUM; - -const PROGMEM char* kHighestStr = D_STR_HIGHEST; -const PROGMEM char* kHighStr = D_STR_HIGH; -const PROGMEM char* kHiStr = D_STR_HI; -const PROGMEM char* kMidStr = D_STR_MID; -const PROGMEM char* kMiddleStr = D_STR_MIDDLE; -const PROGMEM char* kLowStr = D_STR_LOW; -const PROGMEM char* kLoStr = D_STR_LO; -const PROGMEM char* kLowestStr = D_STR_LOWEST; -const PROGMEM char* kMaxRightStr = D_STR_MAXRIGHT; -const PROGMEM char* kRightMaxStr = D_STR_RIGHTMAX_NOSPACE; -const PROGMEM char* kRightStr = D_STR_RIGHT; -const PROGMEM char* kLeftStr = D_STR_LEFT; -const PROGMEM char* kMaxLeftStr = D_STR_MAXLEFT; -const PROGMEM char* kLeftMaxStr = D_STR_LEFTMAX_NOSPACE; -const PROGMEM char* kWideStr = D_STR_WIDE; -const PROGMEM char* kCentreStr = D_STR_CENTRE; -const PROGMEM char* kTopStr = D_STR_TOP; -const PROGMEM char* kBottomStr = D_STR_BOTTOM; - -// Compound words/phrases/descriptions from pre-defined words. -const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO; -const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE; -const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET; -const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE; -const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER; -const PROGMEM char* kDisplayTempStr = D_STR_DISPLAYTEMP; -const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP; -const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER; -const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE; -const PROGMEM char* kSwingVToggleStr = D_STR_SWINGVTOGGLE; - -// Separators -char kTimeSep = D_CHR_TIME_SEP; -const PROGMEM char* kSpaceLBraceStr = D_STR_SPACELBRACE; -const PROGMEM char* kCommaSpaceStr = D_STR_COMMASPACE; -const PROGMEM char* kColonSpaceStr = D_STR_COLONSPACE; - -// IRutils -// - Time -const PROGMEM char* kDayStr = D_STR_DAY; -const PROGMEM char* kDaysStr = D_STR_DAYS; -const PROGMEM char* kHourStr = D_STR_HOUR; -const PROGMEM char* kHoursStr = D_STR_HOURS; -const PROGMEM char* kMinuteStr = D_STR_MINUTE; -const PROGMEM char* kMinutesStr = D_STR_MINUTES; -const PROGMEM char* kSecondStr = D_STR_SECOND; -const PROGMEM char* kSecondsStr = D_STR_SECONDS; -const PROGMEM char* kNowStr = D_STR_NOW; -const PROGMEM char* kThreeLetterDayOfWeekStr = D_STR_THREELETTERDAYS; - -const PROGMEM char* kYesStr = D_STR_YES; -const PROGMEM char* kNoStr = D_STR_NO; -const PROGMEM char* kTrueStr = D_STR_TRUE; -const PROGMEM char* kFalseStr = D_STR_FALSE; - -const PROGMEM char* kRepeatStr = D_STR_REPEAT; -const PROGMEM char* kCodeStr = D_STR_CODE; -const PROGMEM char* kBitsStr = D_STR_BITS; - -// Protocol Names -// Needs to be in decode_type_t order. -const PROGMEM char *kAllProtocolNamesStr = - D_STR_UNUSED "\x0" - D_STR_RC5 "\x0" - D_STR_RC6 "\x0" - D_STR_NEC "\x0" - D_STR_SONY "\x0" - D_STR_PANASONIC "\x0" - D_STR_JVC "\x0" - D_STR_SAMSUNG "\x0" - D_STR_WHYNTER "\x0" - D_STR_AIWA_RC_T501 "\x0" - D_STR_LG "\x0" - D_STR_SANYO "\x0" - D_STR_MITSUBISHI "\x0" - D_STR_DISH "\x0" - D_STR_SHARP "\x0" - D_STR_COOLIX "\x0" - D_STR_DAIKIN "\x0" - D_STR_DENON "\x0" - D_STR_KELVINATOR "\x0" - D_STR_SHERWOOD "\x0" - D_STR_MITSUBISHI_AC "\x0" - D_STR_RCMM "\x0" - D_STR_SANYO_LC7461 "\x0" - D_STR_RC5X "\x0" - D_STR_GREE "\x0" - D_STR_PRONTO "\x0" - D_STR_NEC_LIKE "\x0" - D_STR_ARGO "\x0" - D_STR_TROTEC "\x0" - D_STR_NIKAI "\x0" - D_STR_RAW "\x0" - D_STR_GLOBALCACHE "\x0" - D_STR_TOSHIBA_AC "\x0" - D_STR_FUJITSU_AC "\x0" - D_STR_MIDEA "\x0" - D_STR_MAGIQUEST "\x0" - D_STR_LASERTAG "\x0" - D_STR_CARRIER_AC "\x0" - D_STR_HAIER_AC "\x0" - D_STR_MITSUBISHI2 "\x0" - D_STR_HITACHI_AC "\x0" - D_STR_HITACHI_AC1 "\x0" - D_STR_HITACHI_AC2 "\x0" - D_STR_GICABLE "\x0" - D_STR_HAIER_AC_YRW02 "\x0" - D_STR_WHIRLPOOL_AC "\x0" - D_STR_SAMSUNG_AC "\x0" - D_STR_LUTRON "\x0" - D_STR_ELECTRA_AC "\x0" - D_STR_PANASONIC_AC "\x0" - D_STR_PIONEER "\x0" - D_STR_LG2 "\x0" - D_STR_MWM "\x0" - D_STR_DAIKIN2 "\x0" - D_STR_VESTEL_AC "\x0" - D_STR_TECO "\x0" - D_STR_SAMSUNG36 "\x0" - D_STR_TCL112AC "\x0" - D_STR_LEGOPF "\x0" - D_STR_MITSUBISHI_HEAVY_88 "\x0" - D_STR_MITSUBISHI_HEAVY_152 "\x0" - D_STR_DAIKIN216 "\x0" - D_STR_SHARP_AC "\x0" - D_STR_GOODWEATHER "\x0" - D_STR_INAX "\x0" - D_STR_DAIKIN160 "\x0" - D_STR_NEOCLIMA "\x0" - D_STR_DAIKIN176 "\x0" - D_STR_DAIKIN128 "\x0" - D_STR_AMCOR "\x0" - D_STR_DAIKIN152 "\x0" - D_STR_MITSUBISHI136 "\x0" - D_STR_MITSUBISHI112 "\x0" - D_STR_HITACHI_AC424 "\x0" - D_STR_SONY_38K "\x0" - D_STR_EPSON "\x0" - D_STR_SYMPHONY "\x0" - D_STR_HITACHI_AC3 "\x0" - D_STR_DAIKIN64 "\x0" - D_STR_AIRWELL "\x0" - D_STR_DELONGHI_AC "\x0" - D_STR_DOSHISHA "\x0" - D_STR_MULTIBRACKETS "\x0" - D_STR_CARRIER_AC40 "\x0" - D_STR_CARRIER_AC64 "\x0" - // New protocol strings should be added just above this line. - "\x0"; // This string requires double null termination. diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp deleted file mode 100644 index f0d7f4317..000000000 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Carrier.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2018, 2020 David Conran - -// Supports: -// Brand: Carrier/Surrey, Model: 42QG5A55970 remote -// Brand: Carrier/Surrey, Model: 619EGX0090E0 A/C -// Brand: Carrier/Surrey, Model: 619EGX0120E0 A/C -// Brand: Carrier/Surrey, Model: 619EGX0180E0 A/C -// Brand: Carrier/Surrey, Model: 619EGX0220E0 A/C -// Brand: Carrier/Surrey, Model: 53NGK009/012 Inverter - -#include "IRrecv.h" -#include "IRsend.h" -#include "IRutils.h" - -// Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/385 -const uint16_t kCarrierAcHdrMark = 8532; -const uint16_t kCarrierAcHdrSpace = 4228; -const uint16_t kCarrierAcBitMark = 628; -const uint16_t kCarrierAcOneSpace = 1320; -const uint16_t kCarrierAcZeroSpace = 532; -const uint16_t kCarrierAcGap = 20000; -const uint16_t kCarrierAcFreq = 38; // kHz. (An educated guess) - -const uint16_t kCarrierAc40HdrMark = 8402; -const uint16_t kCarrierAc40HdrSpace = 4166; -const uint16_t kCarrierAc40BitMark = 547; -const uint16_t kCarrierAc40OneSpace = 1540; -const uint16_t kCarrierAc40ZeroSpace = 497; - -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1127 -const uint16_t kCarrierAc64HdrMark = 8940; -const uint16_t kCarrierAc64HdrSpace = 4556; -const uint16_t kCarrierAc64BitMark = 503; -const uint16_t kCarrierAc64OneSpace = 1736; -const uint16_t kCarrierAc64ZeroSpace = 615; -const uint32_t kCarrierAc64Gap = kDefaultMessageGap; // A guess. - - -#if SEND_CARRIER_AC -// Send a Carrier HVAC formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kCarrierAcBits. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Work on real devices. -// -void IRsend::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) { - for (uint16_t r = 0; r <= repeat; r++) { - uint64_t temp_data = data; - // Carrier sends the data block three times. normal + inverted + normal. - for (uint16_t i = 0; i < 3; i++) { - sendGeneric(kCarrierAcHdrMark, kCarrierAcHdrSpace, kCarrierAcBitMark, - kCarrierAcOneSpace, kCarrierAcBitMark, kCarrierAcZeroSpace, - kCarrierAcBitMark, kCarrierAcGap, temp_data, nbits, 38, true, - 0, kDutyDefault); - temp_data = invertBits(temp_data, nbits); - } - } -} -#endif - -#if DECODE_CARRIER_AC -// Decode the supplied Carrier HVAC message. -// Carrier HVAC messages contain only 32 bits, but it is sent three(3) times. -// i.e. normal + inverted + normal -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kCarrierAcBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works. -// -bool IRrecv::decodeCarrierAC(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict) { - if (results->rawlen < ((2 * nbits + kHeader + kFooter) * 3) - 1 + offset) - return false; // Can't possibly be a valid Carrier message. - if (strict && nbits != kCarrierAcBits) - return false; // We expect Carrier to be 32 bits of message. - - uint64_t data = 0; - uint64_t prev_data = 0; - - for (uint8_t i = 0; i < 3; i++) { - prev_data = data; - // Match Header + Data + Footer - uint16_t used; - used = matchGeneric(results->rawbuf + offset, &data, - results->rawlen - offset, nbits, - kCarrierAcHdrMark, kCarrierAcHdrSpace, - kCarrierAcBitMark, kCarrierAcOneSpace, - kCarrierAcBitMark, kCarrierAcZeroSpace, - kCarrierAcBitMark, kCarrierAcGap, true); - if (!used) return false; - offset += used; - // Compliance. - if (strict) { - // Check if the data is an inverted copy of the previous data. - if (i > 0 && prev_data != invertBits(data, nbits)) return false; - } - } - - // Success - results->bits = nbits; - results->value = data; - results->decode_type = CARRIER_AC; - results->address = data >> 16; - results->command = data & 0xFFFF; - return true; -} -#endif // DECODE_CARRIER_AC - -#if SEND_CARRIER_AC40 -/// Send a Carrier 40bit HVAC formatted message. -/// Status: Alpha / Yet to be tested against a real device. -/// @param[in] data The message to be sent. -/// @param[in] nbits The bit size of the message being sent. -/// @param[in] repeat The number of times the message is to be repeated. -void IRsend::sendCarrierAC40(const uint64_t data, const uint16_t nbits, - const uint16_t repeat) { - sendGeneric(kCarrierAc40HdrMark, kCarrierAc40HdrSpace, kCarrierAc40BitMark, - kCarrierAc40OneSpace, kCarrierAc40BitMark, kCarrierAc40ZeroSpace, - kCarrierAc40BitMark, kCarrierAcGap, - data, nbits, kCarrierAcFreq, true, repeat, kDutyDefault); -} -#endif // SEND_CARRIER_AC40 - -#if DECODE_CARRIER_AC40 -/// Decode the supplied Carrier 40-bit HVAC message. -/// Carrier HVAC messages contain only 40 bits, but it is sent three(3) times. -/// Status: BETA / Probably works. -/// @param[in,out] results Ptr to the data to decode & where to store the decode -/// result. -/// @param[in] offset The starting index to use when attempting to decode the -/// raw data. Typically/Defaults to kStartOffset. -/// @param[in] nbits The number of data bits to expect. -/// @param[in] strict Flag indicating if we should perform strict matching. -/// @return A boolean. True if it can decode it, false if it can't. -bool IRrecv::decodeCarrierAC40(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict) { - if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) - return false; // Can't possibly be a valid Carrier message. - if (strict && nbits != kCarrierAc40Bits) - return false; // We expect Carrier to be 40 bits of message. - - if (!matchGeneric(results->rawbuf + offset, &(results->value), - results->rawlen - offset, nbits, - kCarrierAc40HdrMark, kCarrierAc40HdrSpace, - kCarrierAc40BitMark, kCarrierAc40OneSpace, - kCarrierAc40BitMark, kCarrierAc40ZeroSpace, - kCarrierAc40BitMark, kCarrierAcGap, true)) return false; - - // Success - results->bits = nbits; - results->decode_type = CARRIER_AC40; - results->address = 0; - results->command = 0; - return true; -} -#endif // DECODE_CARRIER_AC40 - -#if SEND_CARRIER_AC64 -/// Send a Carrier 64bit HVAC formatted message. -/// Status: Alpha / Yet to be tested against a real device. -/// @param[in] data The message to be sent. -/// @param[in] nbits The bit size of the message being sent. -/// @param[in] repeat The number of times the message is to be repeated. -void IRsend::sendCarrierAC64(const uint64_t data, const uint16_t nbits, - const uint16_t repeat) { - sendGeneric(kCarrierAc64HdrMark, kCarrierAc64HdrSpace, kCarrierAc64BitMark, - kCarrierAc64OneSpace, kCarrierAc64BitMark, kCarrierAc64ZeroSpace, - kCarrierAc64BitMark, kCarrierAc64Gap, - data, nbits, kCarrierAcFreq, false, repeat, kDutyDefault); -} -#endif // SEND_CARRIER_AC64 - -#if DECODE_CARRIER_AC64 -/// Decode the supplied Carrier 64-bit HVAC message. -/// Status: BETA / Probably works. -/// @param[in,out] results Ptr to the data to decode & where to store the decode -/// result. -/// @param[in] offset The starting index to use when attempting to decode the -/// raw data. Typically/Defaults to kStartOffset. -/// @param[in] nbits The number of data bits to expect. -/// @param[in] strict Flag indicating if we should perform strict matching. -/// @return A boolean. True if it can decode it, false if it can't. -bool IRrecv::decodeCarrierAC64(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict) { - if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) - return false; // Can't possibly be a valid Carrier message. - if (strict && nbits != kCarrierAc64Bits) - return false; // We expect Carrier to be 64 bits of message. - - if (!matchGeneric(results->rawbuf + offset, &(results->value), - results->rawlen - offset, nbits, - kCarrierAc64HdrMark, kCarrierAc64HdrSpace, - kCarrierAc64BitMark, kCarrierAc64OneSpace, - kCarrierAc64BitMark, kCarrierAc64ZeroSpace, - kCarrierAc64BitMark, kCarrierAc64Gap, true, - kUseDefTol, kMarkExcess, false)) return false; - - // Success - results->bits = nbits; - results->decode_type = CARRIER_AC64; - results->address = 0; - results->command = 0; - return true; -} -#endif // DECODE_CARRIER_AC64 diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Sherwood.cpp b/lib/IRremoteESP8266-2.7.7/src/ir_Sherwood.cpp deleted file mode 100644 index 47c6790de..000000000 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Sherwood.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 David Conran - -// Sherwood IR remote emulation - -// Supports: -// Brand: Sherwood, Model: RC-138 remote -// Brand: Sherwood, Model: RD6505(B) Receiver - -#include -#include "IRsend.h" - -#if SEND_SHERWOOD -// Send an IR command to a Sherwood device. -// -// Args: -// data: The contents of the command you want to send. -// nbits: The bit size of the command being sent. (kSherwoodBits) -// repeat: The nr. of times you want the command to be repeated. (Default: 1) -// -// Status: STABLE / Known working. -// -// Note: -// Sherwood remote codes appear to be NEC codes with a manditory repeat code. -// i.e. repeat should be >= kSherwoodMinRepeat (1). -void IRsend::sendSherwood(uint64_t data, uint16_t nbits, uint16_t repeat) { - sendNEC(data, nbits, std::max((uint16_t)kSherwoodMinRepeat, repeat)); -} -#endif diff --git a/lib/IRremoteESP8266-2.7.7/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.8/CPPLINT.cfg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/CPPLINT.cfg rename to lib/IRremoteESP8266-2.7.8/CPPLINT.cfg diff --git a/lib/IRremoteESP8266-2.7.8/Doxyfile b/lib/IRremoteESP8266-2.7.8/Doxyfile new file mode 100644 index 000000000..224c07315 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/Doxyfile @@ -0,0 +1,15 @@ +PROJECT_NAME = "IRremoteESP8266" +OUTPUT_DIRECTORY = docs/doxygen +INPUT = src +INPUT += docs/doxygen_index.md +RECURSIVE = YES +EXCLUDE = examples +MULTILINE_CPP_IS_BRIEF = YES +TAB_SIZE = 2 +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_LOCAL_CLASSES = NO +GENERATE_LATEX = NO +ENABLE_PREPROCESSING = NO +QUIET = YES +WARN_NO_PARAMDOC = YES diff --git a/lib/IRremoteESP8266-2.7.7/LICENSE.txt b/lib/IRremoteESP8266-2.7.8/LICENSE.txt similarity index 100% rename from lib/IRremoteESP8266-2.7.7/LICENSE.txt rename to lib/IRremoteESP8266-2.7.8/LICENSE.txt diff --git a/lib/IRremoteESP8266-2.7.7/README.md b/lib/IRremoteESP8266-2.7.8/README.md similarity index 90% rename from lib/IRremoteESP8266-2.7.7/README.md rename to lib/IRremoteESP8266-2.7.8/README.md index b3fa60ece..c8ad07ee3 100644 --- a/lib/IRremoteESP8266-2.7.7/README.md +++ b/lib/IRremoteESP8266-2.7.8/README.md @@ -1,4 +1,4 @@ -# IRremote ESP8266 Library +# IRremoteESP8266 Library [![Build Status](https://travis-ci.org/crankyoldgit/IRremoteESP8266.svg?branch=master)](https://travis-ci.org/crankyoldgit/IRremoteESP8266) [![arduino-library-badge](https://www.ardu-badge.com/badge/IRremoteESP8266.svg?)](https://www.ardu-badge.com/IRremoteESP8266) @@ -9,8 +9,8 @@ This library enables you to **send _and_ receive** infra-red signals on an [ESP8266](https://github.com/esp8266/Arduino) or an [ESP32](https://github.com/espressif/arduino-esp32) using the [Arduino framework](https://www.arduino.cc/) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* demodulators etc. -## v2.7.7 Now Available -Version 2.7.7 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes. +## v2.7.8 Now Available +Version 2.7.8 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes. #### Upgrading from pre-v2.0 Usage of the library has been slightly changed in v2.0. You will need to change your usage to work with v2.0 and beyond. You can read more about the changes required on our [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page. @@ -40,6 +40,10 @@ Before reporting an issue or asking for help, please try to follow our [Troubles ## Frequently Asked Questions Some common answers to common questions and problems are on our [F.A.Q. wiki page](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions). +## Library API Documentation +This library uses [Doxygen](https://www.doxygen.nl/index.html) to [automatically document](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) the [library's](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [API](https://en.wikipedia.org/wiki/Application_programming_interface). +You can find it [here](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + ## Installation ##### Official releases via the Arduino IDE v1.8+ (Windows & Linux) 1. Click the _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items. diff --git a/lib/IRremoteESP8266-2.7.7/README_fr.md b/lib/IRremoteESP8266-2.7.8/README_fr.md similarity index 84% rename from lib/IRremoteESP8266-2.7.7/README_fr.md rename to lib/IRremoteESP8266-2.7.8/README_fr.md index 9ff560fe8..1e983ba35 100644 --- a/lib/IRremoteESP8266-2.7.7/README_fr.md +++ b/lib/IRremoteESP8266-2.7.8/README_fr.md @@ -1,4 +1,4 @@ -# IRremote ESP8266 Library +# IRremoteESP8266 Library [![Build Status](https://travis-ci.org/crankyoldgit/IRremoteESP8266.svg?branch=master)](https://travis-ci.org/crankyoldgit/IRremoteESP8266) [![arduino-library-badge](https://www.ardu-badge.com/badge/IRremoteESP8266.svg?)](https://www.ardu-badge.com/IRremoteESP8266) @@ -9,8 +9,8 @@ Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole [ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc. -## v2.7.7 disponible -Version 2.7.7 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants. +## v2.7.8 disponible +Version 2.7.8 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants. #### mise à jour depuis pre-v2.0 L'utilisation de la librairie à un peu changer depuis la version in v2.0. Si vous voulez l'utiliser vous devrez changer votre utilisation aussi. Vous pouvez vous renseigner sur les précondition d'utilisation ici : [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page. @@ -39,6 +39,9 @@ Avant de reporter un probème ou de demander de l'aide, essayez de suivre notre ## Questions fréquentes Les questions les plus fréquentes sont ici, avec des réponses [F.A.Q. wiki page](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions). +## Documentation API de la bibliothèque +Cette bibliothèque utilise [Doxygen](https://www.doxygen.nl/index.html) pour [documenter automatiquement](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [l'API](https://en.wikipedia.org/wiki/Application_programming_interface) de la [bibliothèque](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). Vous pouvez le trouver [ici](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + ## Installation ##### Officiel releases avec l'Arduino IDE v1.8+ (Windows & Linux) 1. Cliquez sur _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items. @@ -46,6 +49,10 @@ Les questions les plus fréquentes sont ici, avec des réponses [F.A.Q. wiki pag 1. Cliquez sur le IRremoteESP8266 pour avoir les résultats de la recherche. 1. Selectionnez la version que vous voulez installer et cliquez sur _"Install"_. +## Library API Documentation +This library uses [Doxygen](https://www.doxygen.nl/index.html) to [automatically document](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) the [library's](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [API](https://en.wikipedia.org/wiki/Application_programming_interface). +You can find it [here](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + ##### Installation manuelle pour Windows 1. cliquez le boutton sur _"Clone or Download"_ , et _"[Download ZIP](https://github.com/crankyoldgit/IRremoteESP8266/archive->master.zip)"_ on the page. 1. Extraire l'archive. diff --git a/lib/IRremoteESP8266-2.7.7/ReleaseNotes.md b/lib/IRremoteESP8266-2.7.8/ReleaseNotes.md similarity index 93% rename from lib/IRremoteESP8266-2.7.7/ReleaseNotes.md rename to lib/IRremoteESP8266-2.7.8/ReleaseNotes.md index 0e7bc7bc5..4b757f710 100644 --- a/lib/IRremoteESP8266-2.7.7/ReleaseNotes.md +++ b/lib/IRremoteESP8266-2.7.8/ReleaseNotes.md @@ -1,5 +1,49 @@ # Release Notes +## _v2.7.8 (20200622)_ + +**[BREAKING CHANGES]** +- Fix Manchester code handling; Increase Airwell to `34` bits. (#1200) + +**[Bug Fixes]** +- Carrier40: Use correct gap value. (#1193) + +**[Features]** +- CarrierAc64: Add detailed support. (#1133) +- Add experimental support for Hitachi A/C 344 bit protocol (#1139) +- Automatic & full library code/API documentation via Doxygen (#1150 #1154 #1155 #1156 #1158 #1165 #1167 #1169 #1180 #1184 #1189 #1191 #1194 #1195 #1197 #1198) +- Hitachi344: Add detailed support and change bit ordering. (#1147) +- Add Corona AC Protocol (#1152) +- Hitachi344: Add Swing(H) and improve Swing(V) (#1148) +- Update auto_analyse_raw_data.py with better code comment sections (#1164) +- Add support for Midea24 protocol. (#1171) +- Add basic Zepeal protocol support (#1178) + +**[Misc]** +- scrape_supported_devices.py: avoid changes to SupportedProtocols.md (#1140) +- auto_analyze nice exit on empty rawdata input (#1141) +- Comments update + cleanup (#1143) +- Update D_STR_IRRECVDUMP_STARTUP text and comments. (#1144) +- Minor code cleanups (#1149) +- Update `README.md`'s to point to new API docs. (#1151) +- Update "Supports" sections (#1160) +- Add a `doxygen` check to CI/Travis. (#1161) +- scrape_supported_devices: warn about misplaced or legacy supports sections (#1159) +- Add Supports sections to some files (#1163 #1166) +- Fix compile error when `DEBUG` is enabled. +- Add no-output option and return code on error to scrape_supported_devices +- Travis: Add scrape_supported_devices error check +- Update auto_analyse_raw_data.py to have a default Supports: section +- Treat compiler warnings as errors. (#1174) +- Remove `calcLGChecksum()` and use new generic `sumNibbles()` (#1175) +- Suppress more potential compiler warnings. (#1179) +- Load balance travis tasks to reduce wall clock time. (#1183) +- Set PlatformIO's default baudrate to 115200 (#1188) +- Some fixes to Doshisha protocol handler +- Minor cleanups of Corona and Zepeal +- Enable Doxygen warning when the parameters for a function/method/procedure are wrong/missing. (#1196) + + ## _v2.7.7 (20200519)_ **[BREAKING CHANGES]** diff --git a/lib/IRremoteESP8266-2.7.7/SupportedProtocols.md b/lib/IRremoteESP8266-2.7.8/SupportedProtocols.md similarity index 67% rename from lib/IRremoteESP8266-2.7.7/SupportedProtocols.md rename to lib/IRremoteESP8266-2.7.8/SupportedProtocols.md index 457da38bb..7dab7ccb7 100644 --- a/lib/IRremoteESP8266-2.7.7/SupportedProtocols.md +++ b/lib/IRremoteESP8266-2.7.8/SupportedProtocols.md @@ -1,70 +1,74 @@ + Last generated: Mon 22 Jun 2020 09:51:06 +0000 ---> # IR Protocols supported by this library | Protocol | Brand | Model | A/C Model | Detailed A/C Support | | --- | --- | --- | --- | --- | -| [Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Airwell.cpp) | **Airwell** | RC08W remote | | - | +| [Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Airwell.cpp) | **Airwell** | DLS 21 DCI R410 AW A/C
RC04 remote
RC08W remote | | - | | [Aiwa](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Aiwa.cpp) | **Aiwa** | RC-T501 RCU | | - | -| [Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.cpp) | **[Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.h)** | ADR-853H A/C
ADR-853H A/C
TAC-444 remote
TAC-444 remote
TAC-495 remote
TAC-495 remote | | Yes | +| [Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.cpp) | **[Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.h)** | ADR-853H A/C
TAC-444 remote
TAC-495 remote | | Yes | | [Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.cpp) | **[Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.h)** | Ulisse 13 DCI Mobile Split A/C | | Yes | -| [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **Carrier/Surrey** | 42QG5A55970 remote
53NGK009/012 Inverter
619EGX0090E0 A/C
619EGX0120E0 A/C
619EGX0180E0 A/C
619EGX0220E0 A/C | | - | +| [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **[Carrier/Surrey](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.h)** | 42QG5A55970 remote
53NGK009/012 Inverter
619EGX0090E0 A/C
619EGX0120E0 A/C
619EGX0180E0 A/C
619EGX0220E0 A/C | | Yes | | [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | RC08B remote | | Yes | -| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Beko](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | BINR 070/071 split-type A/C
BINR 070/071 split-type A/C
RG57K7(B)/BGEF Remote
RG57K7(B)/BGEF Remote | | Yes | -| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | MS12FU-10HRDN1-QRD0GW(B) A/C
MS12FU-10HRDN1-QRD0GW(B) A/C
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
RG52D/BGE Remote
RG52D/BGE Remote | | Yes | -| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Tokio](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote
AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote | | Yes | -| [Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.cpp) | **[Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.h)** | 17 Series A/C (DAIKIN128)
ARC423A5 remote
ARC433** remote
ARC433B69 remote
ARC466A33 remote (DAIKIN)
ARC477A1 remote
ARC480A5 remote (DAIKIN152)
BRC4C153 remote
BRC52B63 remote (DAIKIN128)
DGS01 remote (DAIKIN64)
FFN-C/FCN-F Series A/C (DAIKIN64)
FTE12HV2S A/C
FTXB09AXVJU A/C (DAIKIN128)
FTXB12AXVJU A/C (DAIKIN128)
FTXM-M A/C (DAIKIN)
FTXZ25NV1B A/C
FTXZ35NV1B A/C
FTXZ50NV1B A/C
M Series A/C (DAIKIN) | | Yes | +| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Beko](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | BINR 070/071 split-type A/C
RG57K7(B)/BGEF Remote | | Yes | +| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | MS12FU-10HRDN1-QRD0GW(B) A/C
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
RG52D/BGE Remote | | Yes | +| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Tokio](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote | | Yes | +| [Corona](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Corona.cpp) | **[Corona](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Corona.h)** | AR-01 remote
CSH-N2211 A/C
CSH-N2511 A/C
CSH-N2811 A/C
CSH-N4011 A/C | | Yes | +| [Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.cpp) | **[Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.h)** | 17 Series A/C (DAIKIN128)
ARC423A5 remote (DAIKIN160)
ARC433** remote (DAIKIN)
ARC433B69 remote (DAIKIN216)
ARC466A33 remote (DAIKIN)
ARC477A1 remote (DAIKIN2)
ARC480A5 remote (DAIKIN152)
BRC4C153 remote (DAIKIN176)
BRC52B63 remote (DAIKIN128)
DGS01 remote (DAIKIN64)
FFN-C/FCN-F Series A/C (DAIKIN64)
FTE12HV2S A/C
FTXB09AXVJU A/C (DAIKIN128)
FTXB12AXVJU A/C (DAIKIN128)
FTXM-M A/C (DAIKIN)
FTXZ25NV1B A/C (DAIKIN2)
FTXZ35NV1B A/C (DAIKIN2)
FTXZ50NV1B A/C (DAIKIN2)
M Series A/C (DAIKIN) | | Yes | | [Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.cpp) | **[Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.h)** | PAC A95 | | Yes | -| [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Unknown** | | | - | +| [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Denon** | AVR-3801 A/V Receiver (probably) | | - | | [Dish](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Dish.cpp) | **DISH NETWORK** | echostar 301 | | - | | [Doshisha](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Doshisha.cpp) | **Doshisha** | CZ-S32D LED Light
CZ-S38D LED Light
CZ-S50D LED Light
RCZ01 remote | | - | | [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[AUX](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | KFR-35GW/BpNFW=3 A/C
YKR-T/011 remote | | Yes | | [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | Classic INV 17 / AXW12DCS A/C
YKR-M/003E remote | | Yes | -| [Epson](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Epson.cpp) | **Unknown** | | | - | -| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AGTV14LAC A/C
AR-DB1 remote
AR-DL10 remote
AR-RAC1E remote
AR-RAE1E remote
AR-RAH2E remote
AR-REB1E remote
AR-RY4 remote
AST9RSGCW A/C
ASTB09LBC A/C
ASU30C1 A/C
ASYG30LFCA A/C
ASYG7LMCA A/C | ARDB1
ARJW2
ARRAH2E
ARREB1E
ARRY4 | Yes | +| [Epson](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Epson.cpp) | **Epson** | EN-TW9100W Projector | | - | +| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AGTV14LAC A/C
AR-DB1 remote
AR-DL10 remote
AR-RAC1E remote
AR-RAE1E remote
AR-RAH2E remote
AR-REB1E remote
AR-RY4 remote
AST9RSGCW A/C (ARDB1)
ASTB09LBC A/C
ASU30C1 A/C
ASYG30LFCA A/C (ARRAH2E)
ASYG7LMCA A/C (ARREB1E) | ARDB1
ARJW2
ARRAH2E
ARREB1E
ARRY4 | Yes | | [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu General](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AR-JW2 remote | ARDB1
ARJW2
ARRAH2E
ARREB1E
ARRY4 | Yes | -| [GICable](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GICable.cpp) | **Unknown** | | | - | -| [GlobalCache](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GlobalCache.cpp) | **Unknown** | | | - | +| [GICable](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GICable.cpp) | **G.I. Cable** | XRC-200 remote | | - | +| [GlobalCache](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GlobalCache.cpp) | **Global Cache** | Control Tower IR DB | | - | | [Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.cpp) | **[Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.h)** | ZH/JT-03 remote | | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[EKOKAI](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | A/C | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | YAA1FBF remote
YB1F2F remote | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | YBOFB remote
YBOFB2 remote | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[RusClimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | EACS/I-09HAR_X/N3 A/C
YAW1F remote | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Ultimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | Heat Pump | YAW1F
YBOFB | Yes | -| [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | HSU-09HMC203 A/C
HSU07-HEA03 remote
YR-W02 remote | | Yes | -| [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | KAZE-312KSDP A/C (HITACHI_AC1)
LT0541-HTA remote
PC-LH3B (HITACHI_AC3)
R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
RAR-8P2 remote
RAS-35THA6 remote
RAS-AJ25H A/C
Series VI A/C (Circa 2007) | | Yes | +| [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | HSU-09HMC203 A/C (HAIER_AC_YRW02)
HSU07-HEA03 remote (HAIER_AC)
YR-W02 remote (HAIER_AC_YRW02) | | Yes | +| [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | KAZE-312KSDP A/C (HITACHI_AC1)
LT0541-HTA remote (HITACHI_AC1)
PC-LH3B (HITACHI_AC3)
R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
RAR-8P2 remote (HITACHI_AC424)
RAS-22NK A/C (HITACHI_AC344)
RAS-35THA6 remote
RAS-AJ25H A/C (HITACHI_AC424)
RF11T1 remote (HITACHI_AC344)
Series VI A/C (Circa 2007) (HITACHI_AC1) | | Yes | | [Inax](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Inax.cpp) | **Lixil** | Inax DT-BA283 Toilet | | - | -| [JVC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_JVC.cpp) | **Unknown** | | | - | +| [JVC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_JVC.cpp) | **JVC** | PTU94023B remote | | - | | [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | YAPOF3 remote | | Yes | | [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | KSV26CRC A/C
KSV26HRC A/C
KSV35CRC A/C
KSV35HRC A/C
KSV53HRC A/C
KSV62HRC A/C
KSV70CRC A/C
KSV70HRC A/C
KSV80HRC A/C
YALIF Remote | | Yes | | [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[General Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711AR2853M A/C Remote
AG1BH09AW101 Split A/C | | Yes | -| [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711A20083V remote
6711A20083V remote
AKB74395308 remote
AKB74395308 remote
AKB75215403 remote (LG2)
S4-W12JA3AA A/C (LG2) | | Yes | -| [Lasertag](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lasertag.cpp) | **Unknown** | | | - | +| [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711A20083V remote (LG)
AKB74395308 remote (LG2)
AKB75215403 remote (LG2)
S4-W12JA3AA A/C (LG2) | | Yes | +| [Lasertag](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lasertag.cpp) | **Lasertag** | Phaser emitters | | - | | [Lego](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lego.cpp) | **LEGO Power Functions** | IR Receiver | | - | -| [Lutron](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lutron.cpp) | **Unknown** | | | - | -| [MWM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MWM.cpp) | **Unknown** | | | - | -| [Magiquest](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.cpp) | **[Unknown](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.h)** | | | - | -| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Comfee](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | MPD1-12CRN7 A/C | | Yes | -| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Keystone](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RG57H4(B)BGEF remote | | Yes | -| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Pioneer System](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RUBO18GMFILCAD A/C (18K BTU)
RYBO12GMFILCAD A/C (12K BTU) | | Yes | -| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | HC3000 Projector
KM14A 0179213 remote
MS-GK24VA A/C
TV | | Yes | -| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | 001CP T7WE10714 remote
KPOA remote
MSH-A24WV / MUH-A24WV A/C
PEAD-RP71JAA Ducted A/C | | Yes | -| [MitsubishiHeavy](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.cpp) | **[Mitsubishi Heavy Industries](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.h)** | RKX502A001C remote
RLA502A700B remote
SRKxxZJ-S A/C
SRKxxZM-S A/C
SRKxxZMXA-S A/C | | Yes | +| [Lutron](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lutron.cpp) | **Lutron** | MIR-ITFS remote
MIR-ITFS-F remote
MIR-ITFS-LF remote
SP-HT remote | | - | +| [MWM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MWM.cpp) | **Disney** | Made With Magic (Glow With The Show) wand | | - | +| [Magiquest](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.cpp) | **[MagiQuest](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.h)** | Wand | | - | +| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Comfee](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | MPD1-12CRN7 A/C (MIDEA) | | Yes | +| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Keystone](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RG57H4(B)BGEF remote (MIDEA) | | Yes | +| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | FS40-7AR Stand Fan (MIDEA24) | | Yes | +| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Pioneer System](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RUBO18GMFILCAD A/C (18K BTU) (MIDEA)
RYBO12GMFILCAD A/C (12K BTU) (MIDEA) | | Yes | +| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | HC3000 Projector (MITSUBISHI2)
KM14A 0179213 remote
MS-GK24VA A/C
TV (MITSUBISHI) | | Yes | +| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | 001CP T7WE10714 remote (MITSUBISHI136)
KPOA remote (MITSUBISHI112)
MSH-A24WV A/C (MITSUBISHI112)
MUH-A24WV A/C (MITSUBISHI112)
PEAD-RP71JAA Ducted A/C (MITSUBISHI136) | | Yes | +| [MitsubishiHeavy](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.cpp) | **[Mitsubishi Heavy Industries](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.h)** | RKX502A001C remote (88 bit)
RLA502A700B remote (152 bit)
SRKxxZJ-S A/C (88 bit)
SRKxxZM-S A/C (152 bit)
SRKxxZMXA-S A/C (152 bit) | | Yes | | [Multibrackets](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Multibrackets.cpp) | **Multibrackets** | Motorized Swing mount large - 4500 | | - | | [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Aloka](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | SleepyLights LED Lamp | | - | +| [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Duux](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | Blizzard Smart 10K / DXMA04 A/C
YJ-A081 TR Remote | | - | +| [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Silan Microelectronics](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | SC6121-001 IC | | - | | [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | 42TL838 LCD TV | | - | | [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Yamaha](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | RAV561 remote
RXV585B A/V Receiver | | - | -| [Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.cpp) | **[Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.h)** | NS-09AHTI A/C
NS-09AHTI A/C
ZH/TY-01 remote
ZH/TY-01 remote | | Yes | -| [Nikai](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Nikai.cpp) | **Unknown** | | | - | -| [Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.cpp) | **[Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.h)** | A75C2311 remote (CKP)
A75C2616-1 remote (DKE)
A75C3704 remote
A75C3747 remote
CKP series A/C
CS-E7PKR A/C (DKE)
CS-ME10CKPG A/C
CS-ME12CKPG A/C
CS-ME14CKPG A/C
CS-YW9MKD A/C
CS-Z9RKR A/C
DKE series A/C
DKW series A/C (DKE)
JKE series A/C
NKE series A/C
PKR series A/C (DKE)
RKR series A/C
TV | CKP
DKE
JKE
LKE
NKE
RKR | Yes | -| [Pioneer](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pioneer.cpp) | **Unknown** | | | - | -| [Pronto](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pronto.cpp) | **Unknown** | | | - | -| [RC5_RC6](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RC5_RC6.cpp) | **Unknown** | | | - | +| [Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.cpp) | **[Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.h)** | NS-09AHTI A/C
ZH/TY-01 remote | | Yes | +| [Nikai](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Nikai.cpp) | **Nikai** | Unknown LCD TV | | - | +| [Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.cpp) | **[Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.h)** | A75C2311 remote (PANASONIC_AC CKP/5)
A75C2616-1 remote (PANASONIC_AC DKE/3)
A75C3704 remote (PANASONIC_AC DKE/3)
A75C3747 remote (PANASONIC_AC JKE/4)
CKP series A/C (PANASONIC_AC CKP/5)
CS-E7PKR A/C (PANASONIC_AC DKE/2)
CS-ME10CKPG A/C (PANASONIC_AC CKP/5)
CS-ME12CKPG A/C (PANASONIC_AC CKP/5)
CS-ME14CKPG A/C (PANASONIC_AC CKP/5)
CS-YW9MKD A/C (PANASONIC_AC JKE/4)
CS-Z9RKR A/C (PANASONIC_AC RKR/6)
DKE series A/C (PANASONIC_AC DKE/3)
DKW series A/C (PANASONIC_AC DKE/3)
JKE series A/C (PANASONIC_AC JKE/4)
NKE series A/C (PANASONIC_AC NKE/2)
PKR series A/C (PANASONIC_AC DKE/3)
RKR series A/C (PANASONIC_AC RKR/6)
TV (PANASONIC) | CKP
DKE
JKE
LKE
NKE
RKR | Yes | +| [Pioneer](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pioneer.cpp) | **Pioneer** | AV Receivers | | - | +| [Pronto](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pronto.cpp) | **Pronto** | Pronto Hex | | - | +| [RC5_RC6](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RC5_RC6.cpp) | **Philips** | RC-5X (RC5X)
Standard RC-5 (RC5)
Standard RC-6 (RC6) | | - | | [RCMM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RCMM.cpp) | **Microsoft** | XBOX 360 | | - | -| [Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.cpp) | **[Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.h)** | AR09FSSDAWKNFA A/C
AR12HSSDBWKNEU A/C
AR12KSFPEWQNET A/C
AR12NXCXAWKXEU A/C
DB63-03556X003 remote
DB93-16761C remote
IEC-R03 remote
UA55H6300 TV | | Yes | -| [Sanyo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sanyo.cpp) | **Unknown** | | | - | -| [Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.h)** | AH-AxSAY A/C
AH-XP10NRY A/C
AY-ZP40KR A/C
CRMC-820JBEZ remote
LC-52D62U TV | | Yes | +| [Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.cpp) | **[Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.h)** | AK59-00167A Bluray remote (SAMSUNG36)
AR09FSSDAWKNFA A/C (SAMSUNG_AC)
AR12HSSDBWKNEU A/C (SAMSUNG_AC)
AR12KSFPEWQNET A/C (SAMSUNG_AC)
AR12NXCXAWKXEU A/C (SAMSUNG_AC)
BN59-01178B TV remote (SAMSUNG)
DB63-03556X003 remote
DB93-16761C remote
IEC-R03 remote
UA55H6300 TV (SAMSUNG) | | Yes | +| [Sanyo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sanyo.cpp) | **Sanyo** | LC7461 transmitter IC (SANYO_LC7461)
SA 8650B - disabled | | - | +| [Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.h)** | AH-AxSAY A/C
AH-XP10NRY A/C
AY-ZP40KR A/C
CRMC-820JBEZ remote
CRMC-A907 JBEZ remote
LC-52D62U TV | | Yes | | [Sherwood](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sherwood.cpp) | **Sherwood** | RC-138 remote
RD6505(B) Receiver | | - | | [Sony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sony.cpp) | **Sony** | HT-CT380 Soundbar (Uses 38kHz & 3 repeats) | | - | | [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Blyss** | Owen-SW-5 3 Fan
WP-YK8 090218 remote | | - | @@ -75,10 +79,12 @@ | [Tcl](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.cpp) | **[Leberg](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.h)** | LBS-TOR07 A/C | | Yes | | [Teco](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.cpp) | **[Alaska](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.h)** | SAC9010QC A/C
SAC9010QC remote | | Yes | | [Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.h)** | Akita EVO II
RAS 18SKP-ES
RAS-B13N3KV2
RAS-B13N3KVP-E
WC-L03SE
WH-TA04NE | | Yes | -| [Trotec](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.cpp) | **[Unknown](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.h)** | | | Yes | +| [Trotec](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.cpp) | **[Duux](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.h)** | Blizzard Smart 10K / DXMA04 A/C | | Yes | +| [Trotec](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.cpp) | **[Trotec](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.h)** | PAC 3200 A/C | | Yes | | [Vestel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Vestel.cpp) | **[Vestel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Vestel.h)** | BIOX CXP-9 A/C (9K BTU) | | Yes | | [Whirlpool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whirlpool.cpp) | **[Whirlpool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whirlpool.h)** | DG11J1-04 remote
DG11J1-3A remote
DG11J1-91 remote
SPIS409L A/C
SPIS412L A/C
SPIW409L A/C
SPIW412L A/C
SPIW418L A/C | DG11J13A
DG11J191 | Yes | | [Whynter](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whynter.cpp) | **Whynter** | ARC-110WD A/C | | - | +| [Zepeal](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Zepeal.cpp) | **Zepeal** | DRT-A3311(BG) 5 button remote
DRT-A3311(BG) floor fan | | - | ## Send only protocols: @@ -100,6 +106,7 @@ - CARRIER_AC40 - CARRIER_AC64 - COOLIX +- CORONA_AC - DAIKIN - DAIKIN128 - DAIKIN152 @@ -124,6 +131,7 @@ - HITACHI_AC1 - HITACHI_AC2 - HITACHI_AC3 +- HITACHI_AC344 - HITACHI_AC424 - INAX - JVC @@ -135,6 +143,7 @@ - LUTRON - MAGIQUEST - MIDEA +- MIDEA24 - MITSUBISHI - MITSUBISHI112 - MITSUBISHI136 @@ -171,3 +180,4 @@ - VESTEL_AC - WHIRLPOOL_AC - WHYNTER +- ZEPEAL diff --git a/lib/IRremoteESP8266-2.7.8/docs/README.md b/lib/IRremoteESP8266-2.7.8/docs/README.md new file mode 100644 index 000000000..262e82b62 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/README.md @@ -0,0 +1,61 @@ +# IRremoteESP8266 Library + +This library enables you to **send _and_ receive** infra-red signals on an [ESP8266](https://github.com/esp8266/Arduino) or an +[ESP32](https://github.com/espressif/arduino-esp32) using the [Arduino framework](https://www.arduino.cc/) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* demodulators etc. + +## Supported Protocols +You can find the details of which protocols & devices are supported +[here](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md). + +## Troubleshooting +Before reporting an issue or asking for help, please try to follow our [Troubleshooting Guide](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide) first. + +## Frequently Asked Questions +Some common answers to common questions and problems are on our [F.A.Q. wiki page](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions). + +## Library API Documentation +This library uses [Doxygen](https://www.doxygen.nl/index.html) to [automatically document](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) the [library's](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [API](https://en.wikipedia.org/wiki/Application_programming_interface). +You can find it [here](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + +## Installation +##### Official releases via the Arduino IDE v1.8+ (Windows & Linux) +1. Click the _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items. +1. Enter `IRremoteESP8266` into the _"Filter your search..."_ top right search box. +1. Click on the IRremoteESP8266 result of the search. +1. Select the version you wish to install and click _"Install"_. + +##### Manual Installation for Windows +1. Click on _"Clone or Download"_ button, then _"[Download ZIP](https://github.com/crankyoldgit/IRremoteESP8266/archive->master.zip)"_ on the page. +1. Extract the contents of the downloaded zip file. +1. Rename the extracted folder to _"IRremoteESP8266"_. +1. Move this folder to your libraries directory. (under windows: `C:\Users\YOURNAME\Documents\Arduino\libraries\`) +1. Restart your Arduino IDE. +1. Check out the examples. + +##### Using Git to install the library ( Linux ) +``` +cd ~/Arduino/libraries +git clone https://github.com/crankyoldgit/IRremoteESP8266.git +``` +###### To update to the latest version of the library +``` +cd ~/Arduino/libraries/IRremoteESP8266 && git pull +``` + +## Contributing +If you want to [contribute](.github/CONTRIBUTING.md#how-can-i-contribute) to this project, consider: +- [Reporting](.github/CONTRIBUTING.md#reporting-bugs) bugs and errors +- Ask for enhancements +- Improve our documentation +- [Creating issues](.github/CONTRIBUTING.md#reporting-bugs) and [pull requests](.github/CONTRIBUTING.md#pull-requests) +- Tell other people about this library + +## Contributors +Available [here](.github/Contributors.md) + +## Library History +This library was originally based on Ken Shirriff's work (https://github.com/shirriff/Arduino-IRremote/) + +[Mark Szabo](https://github.com/crankyoldgit/IRremoteESP8266) has updated the IRsend class to work on ESP8266 and [Sebastien Warin](https://github.com/sebastienwarin/IRremoteESP8266) the receiving & decoding part (IRrecv class). + +As of v2.0, the library was almost entirely re-written with the ESP8266's resources in mind. diff --git a/lib/IRremoteESP8266-2.7.8/docs/README_fr.md b/lib/IRremoteESP8266-2.7.8/docs/README_fr.md new file mode 100644 index 000000000..3ff81c5d8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/README_fr.md @@ -0,0 +1,64 @@ +# IRremoteESP8266 Library + +Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole +[ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc. + +## Protocoles supportés +Vous pouvez trouver le détails des protocoles et machines supportés +[here](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md). + +## Dépannage +Avant de reporter un probème ou de demander de l'aide, essayez de suivre notre [guide de dépannage](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide) first. + +## Questions fréquentes +Les questions les plus fréquentes sont ici, avec des réponses [F.A.Q. wiki page](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions). + +## Documentation API de la bibliothèque +Cette bibliothèque utilise [Doxygen](https://www.doxygen.nl/index.html) pour [documenter automatiquement](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [l'API](https://en.wikipedia.org/wiki/Application_programming_interface) de la [bibliothèque](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). Vous pouvez le trouver [ici](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + +## Installation +##### Officiel releases avec l'Arduino IDE v1.8+ (Windows & Linux) +1. Cliquez sur _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items. +1. Entrez `IRremoteESP8266` dans le _"Filter your search..."_ barre de recherche en haut à droite. +1. Cliquez sur le IRremoteESP8266 pour avoir les résultats de la recherche. +1. Selectionnez la version que vous voulez installer et cliquez sur _"Install"_. + +## Library API Documentation +This library uses [Doxygen](https://www.doxygen.nl/index.html) to [automatically document](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) the [library's](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [API](https://en.wikipedia.org/wiki/Application_programming_interface). +You can find it [here](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + +##### Installation manuelle pour Windows +1. cliquez le boutton sur _"Clone or Download"_ , et _"[Download ZIP](https://github.com/crankyoldgit/IRremoteESP8266/archive->master.zip)"_ on the page. +1. Extraire l'archive. +1. renommez le fichier par _"IRremoteESP8266"_. +1. déplacer le fichier dans votre fichier de bibliothèques. (Pour windows : `C:\Users\VOTRE_NOM\Documents\Arduino\libraries\`) +1. Redemarrez arduino IDE. +1. Regardez les exemples. + +##### En utilisant GIT ( Linux ) +``` +cd ~/Arduino/libraries +git clone https://github.com/crankyoldgit/IRremoteESP8266.git +``` +###### Pour se mettre à jour +``` +cd ~/Arduino/libraries/IRremoteESP8266 && git pull +``` + +## Contribution +Si vous voulez [contribuer](.github/CONTRIBUTING.md#how-can-i-contribute) au projet, pour les erreurs: +- [Reporting](.github/CONTRIBUTING.md#reporting-bugs) bug et erreurs +- Demander des améliorations +- Améliorer notre documentation +- [Création d'issues](.github/CONTRIBUTING.md#reporting-bugs) et [pull requests](.github/CONTRIBUTING.md#pull-requests) +- Parlez de cettre librairie à d'autres personnes + +## Contributeurs +disponible [ici](.github/Contributors.md) + +## Historique de la bibliothèque +Elle est basée sur le travail de Shirriff (https://github.com/shirriff/Arduino-IRremote/) + +[Mark Szabo](https://github.com/crankyoldgit/IRremoteESP8266) à mis a jour la IRsend class pour qu'elle soit fonctionnelle sur ESP8266 et [Sebastien Warin](https://github.com/sebastienwarin/IRremoteESP8266) s'est occupé de la partie réception et décodage (IRrecv class). + +Comme pour la version 2.0, la bibliothèque à été completement réécrite avec les ressources sur ESP8266. diff --git a/lib/IRremoteESP8266-2.7.7/docs/_config.yml b/lib/IRremoteESP8266-2.7.8/docs/_config.yml similarity index 100% rename from lib/IRremoteESP8266-2.7.7/docs/_config.yml rename to lib/IRremoteESP8266-2.7.8/docs/_config.yml diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8cpp.html new file mode 100644 index 000000000..2cd303da8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8cpp.html @@ -0,0 +1,98 @@ + + + + + + + +IRremoteESP8266: src/IRac.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRac.cpp File Reference
+
+
+ + + + +

+Namespaces

 IRAcUtils
 
+ + + + + + + +

+Functions

String IRAcUtils::resultAcToString (const decode_results *const result)
 Display the human readable state of an A/C message if we can. More...
 
bool IRAcUtils::decodeToState (const decode_results *decode, stdAc::state_t *result, const stdAc::state_t *prev)
 Convert a valid IR A/C remote message that we understand enough into a Common A/C state. More...
 
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h.html new file mode 100644 index 000000000..8a58a1eee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h.html @@ -0,0 +1,127 @@ + + + + + + + +IRremoteESP8266: src/IRac.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRac.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + +

+Classes

class  IRac
 
+ + + +

+Namespaces

 IRAcUtils
 
+ + + + + + + +

+Functions

String IRAcUtils::resultAcToString (const decode_results *const result)
 Display the human readable state of an A/C message if we can. More...
 
bool IRAcUtils::decodeToState (const decode_results *decode, stdAc::state_t *result, const stdAc::state_t *prev)
 Convert a valid IR A/C remote message that we understand enough into a Common A/C state. More...
 
+ + + +

+Variables

const int8_t kGpioUnused = -1
 
+

Variable Documentation

+ +

◆ kGpioUnused

+ +
+
+ + + + +
const int8_t kGpioUnused = -1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h_source.html new file mode 100644 index 000000000..00c94ee20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h_source.html @@ -0,0 +1,652 @@ + + + + + + + +IRremoteESP8266: src/IRac.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRac.h
+
+
+Go to the documentation of this file.
1 #ifndef IRAC_H_
+
2 #define IRAC_H_
+
3 
+
4 // Copyright 2019 David Conran
+
5 
+
6 #ifndef UNIT_TEST
+
7 #include <Arduino.h>
+
8 #endif
+
9 #include "IRremoteESP8266.h"
+
10 #include "ir_Amcor.h"
+
11 #include "ir_Argo.h"
+
12 #include "ir_Carrier.h"
+
13 #include "ir_Coolix.h"
+
14 #include "ir_Corona.h"
+
15 #include "ir_Daikin.h"
+
16 #include "ir_Delonghi.h"
+
17 #include "ir_Fujitsu.h"
+
18 #include "ir_Electra.h"
+
19 #include "ir_Goodweather.h"
+
20 #include "ir_Gree.h"
+
21 #include "ir_Haier.h"
+
22 #include "ir_Hitachi.h"
+
23 #include "ir_Kelvinator.h"
+
24 #include "ir_LG.h"
+
25 #include "ir_Midea.h"
+
26 #include "ir_Mitsubishi.h"
+
27 #include "ir_MitsubishiHeavy.h"
+
28 #include "ir_Neoclima.h"
+
29 #include "ir_Panasonic.h"
+
30 #include "ir_Samsung.h"
+
31 #include "ir_Sharp.h"
+
32 #include "ir_Tcl.h"
+
33 #include "ir_Teco.h"
+
34 #include "ir_Toshiba.h"
+
35 #include "ir_Trotec.h"
+
36 #include "ir_Vestel.h"
+
37 #include "ir_Whirlpool.h"
+
38 
+
39 // Constants
+
40 const int8_t kGpioUnused = -1;
+
41 
+
42 // Class
+
43 class IRac {
+
44  public:
+
45  explicit IRac(const uint16_t pin, const bool inverted = false,
+
46  const bool use_modulation = true);
+
47  static bool isProtocolSupported(const decode_type_t protocol);
+
48  static void initState(stdAc::state_t *state,
+
49  const decode_type_t vendor, const int16_t model,
+
50  const bool power, const stdAc::opmode_t mode,
+
51  const float degrees, const bool celsius,
+
52  const stdAc::fanspeed_t fan,
+
53  const stdAc::swingv_t swingv,
+
54  const stdAc::swingh_t swingh,
+
55  const bool quiet, const bool turbo, const bool econo,
+
56  const bool light, const bool filter, const bool clean,
+
57  const bool beep, const int16_t sleep,
+
58  const int16_t clock);
+
59  static void initState(stdAc::state_t *state);
+
60  void markAsSent(void);
+
61  bool sendAc(void);
+
62  bool sendAc(const stdAc::state_t desired, const stdAc::state_t *prev = NULL);
+
63  bool sendAc(const decode_type_t vendor, const int16_t model,
+
64  const bool power, const stdAc::opmode_t mode, const float degrees,
+
65  const bool celsius, const stdAc::fanspeed_t fan,
+
66  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
67  const bool quiet, const bool turbo, const bool econo,
+
68  const bool light, const bool filter, const bool clean,
+
69  const bool beep, const int16_t sleep = -1,
+
70  const int16_t clock = -1);
+
71  static bool cmpStates(const stdAc::state_t a, const stdAc::state_t b);
+
72  static bool strToBool(const char *str, const bool def = false);
+
73  static int16_t strToModel(const char *str, const int16_t def = -1);
+ +
75  const char *str, const stdAc::opmode_t def = stdAc::opmode_t::kAuto);
+ +
77  const char *str,
+ + +
80  const char *str, const stdAc::swingv_t def = stdAc::swingv_t::kOff);
+ +
82  const char *str, const stdAc::swingh_t def = stdAc::swingh_t::kOff);
+
83  static String boolToString(const bool value);
+
84  static String opmodeToString(const stdAc::opmode_t mode);
+
85  static String fanspeedToString(const stdAc::fanspeed_t speed);
+
86  static String swingvToString(const stdAc::swingv_t swingv);
+
87  static String swinghToString(const stdAc::swingh_t swingh);
+ + +
90  bool hasStateChanged(void);
+ +
92 #ifndef UNIT_TEST
+
93 
+
94  private:
+
95 #endif
+
96  uint16_t _pin;
+
97  bool _inverted;
+ +
99  stdAc::state_t _prev; // The state we expect the device to currently be in.
+
100 #if SEND_AMCOR
+
101  void amcor(IRAmcorAc *ac,
+
102  const bool on, const stdAc::opmode_t mode, const float degrees,
+
103  const stdAc::fanspeed_t fan);
+
104 #endif // SEND_AMCOR
+
105 #if SEND_ARGO
+
106  void argo(IRArgoAC *ac,
+
107  const bool on, const stdAc::opmode_t mode, const float degrees,
+
108  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
109  const bool turbo, const int16_t sleep = -1);
+
110 #endif // SEND_ARGO
+
111 #if SEND_CARRIER_AC64
+
112 void carrier64(IRCarrierAc64 *ac,
+
113  const bool on, const stdAc::opmode_t mode,
+
114  const float degrees, const stdAc::fanspeed_t fan,
+
115  const stdAc::swingv_t swingv, const int16_t sleep = -1);
+
116 #endif // SEND_CARRIER_AC64
+
117 #if SEND_COOLIX
+
118  void coolix(IRCoolixAC *ac,
+
119  const bool on, const stdAc::opmode_t mode, const float degrees,
+
120  const stdAc::fanspeed_t fan,
+
121  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
122  const bool turbo, const bool light, const bool clean,
+
123  const int16_t sleep = -1);
+
124 #endif // SEND_COOLIX
+
125 #if SEND_CORONA_AC
+
126  void corona(IRCoronaAc *ac,
+
127  const bool on, const stdAc::opmode_t mode,
+
128  const float degrees, const stdAc::fanspeed_t fan,
+
129  const stdAc::swingv_t swingv, const bool econo);
+
130 #endif // SEND_CORONA_AC
+
131 #if SEND_DAIKIN
+
132  void daikin(IRDaikinESP *ac,
+
133  const bool on, const stdAc::opmode_t mode, const float degrees,
+
134  const stdAc::fanspeed_t fan,
+
135  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
136  const bool quiet, const bool turbo, const bool econo,
+
137  const bool clean);
+
138 #endif // SEND_DAIKIN
+
139 #if SEND_DAIKIN128
+
140  void daikin128(IRDaikin128 *ac,
+
141  const bool on, const stdAc::opmode_t mode,
+
142  const float degrees, const stdAc::fanspeed_t fan,
+
143  const stdAc::swingv_t swingv,
+
144  const bool quiet, const bool turbo, const bool light,
+
145  const bool econo, const int16_t sleep = -1,
+
146  const int16_t clock = -1);
+
147 #endif // SEND_DAIKIN128
+
148 #if SEND_DAIKIN152
+
149  void daikin152(IRDaikin152 *ac,
+
150  const bool on, const stdAc::opmode_t mode,
+
151  const float degrees, const stdAc::fanspeed_t fan,
+
152  const stdAc::swingv_t swingv,
+
153  const bool quiet, const bool turbo, const bool econo);
+
154 #endif // SEND_DAIKIN152
+
155 #if SEND_DAIKIN160
+
156  void daikin160(IRDaikin160 *ac,
+
157  const bool on, const stdAc::opmode_t mode,
+
158  const float degrees, const stdAc::fanspeed_t fan,
+
159  const stdAc::swingv_t swingv);
+
160 #endif // SEND_DAIKIN160
+
161 #if SEND_DAIKIN176
+
162  void daikin176(IRDaikin176 *ac,
+
163  const bool on, const stdAc::opmode_t mode,
+
164  const float degrees, const stdAc::fanspeed_t fan,
+
165  const stdAc::swingh_t swingh);
+
166 #endif // SEND_DAIKIN176
+
167 #if SEND_DAIKIN2
+
168  void daikin2(IRDaikin2 *ac,
+
169  const bool on, const stdAc::opmode_t mode,
+
170  const float degrees, const stdAc::fanspeed_t fan,
+
171  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
172  const bool quiet, const bool turbo, const bool light,
+
173  const bool econo, const bool filter, const bool clean,
+
174  const bool beep, const int16_t sleep = -1,
+
175  const int16_t clock = -1);
+
176 #endif // SEND_DAIKIN2
+
177 #if SEND_DAIKIN216
+
178 void daikin216(IRDaikin216 *ac,
+
179  const bool on, const stdAc::opmode_t mode,
+
180  const float degrees, const stdAc::fanspeed_t fan,
+
181  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
182  const bool quiet, const bool turbo);
+
183 #endif // SEND_DAIKIN216
+
184 #if SEND_DAIKIN64
+
185  void daikin64(IRDaikin64 *ac,
+
186  const bool on, const stdAc::opmode_t mode,
+
187  const float degrees, const stdAc::fanspeed_t fan,
+
188  const stdAc::swingv_t swingv,
+
189  const bool quiet, const bool turbo,
+
190  const int16_t sleep = -1, const int16_t clock = -1);
+
191 #endif // SEND_DAIKIN64
+
192 #if SEND_DELONGHI_AC
+
193  void delonghiac(IRDelonghiAc *ac,
+
194  const bool on, const stdAc::opmode_t mode, const bool celsius,
+
195  const float degrees, const stdAc::fanspeed_t fan,
+
196  const bool turbo, const int16_t sleep = -1);
+
197 #endif // SEND_DELONGHI_AC
+
198 #if SEND_ELECTRA_AC
+
199 void electra(IRElectraAc *ac,
+
200  const bool on, const stdAc::opmode_t mode,
+
201  const float degrees, const stdAc::fanspeed_t fan,
+
202  const stdAc::swingv_t swingv,
+
203  const stdAc::swingh_t swingh, const bool turbo,
+
204  const bool lighttoggle, const bool clean);
+
205 #endif // SEND_ELECTRA_AC
+
206 #if SEND_FUJITSU_AC
+
207  void fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model,
+
208  const bool on, const stdAc::opmode_t mode, const float degrees,
+
209  const stdAc::fanspeed_t fan,
+
210  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
211  const bool quiet, const bool turbo, const bool econo,
+
212  const bool filter, const bool clean);
+
213 #endif // SEND_FUJITSU_AC
+
214 #if SEND_GOODWEATHER
+
215  void goodweather(IRGoodweatherAc *ac,
+
216  const bool on, const stdAc::opmode_t mode,
+
217  const float degrees,
+
218  const stdAc::fanspeed_t fan,
+
219  const stdAc::swingv_t swingv,
+
220  const bool turbo, const bool light,
+
221  const int16_t sleep = -1);
+
222 #endif // SEND_GOODWEATHER
+
223 #if SEND_GREE
+
224  void gree(IRGreeAC *ac, const gree_ac_remote_model_t model,
+
225  const bool on, const stdAc::opmode_t mode, const bool celsius,
+
226  const float degrees, const stdAc::fanspeed_t fan,
+
227  const stdAc::swingv_t swingv, const bool turbo, const bool light,
+
228  const bool clean, const int16_t sleep = -1);
+
229 #endif // SEND_GREE
+
230 #if SEND_HAIER_AC
+
231  void haier(IRHaierAC *ac,
+
232  const bool on, const stdAc::opmode_t mode, const float degrees,
+
233  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
234  const bool filter, const int16_t sleep = -1,
+
235  const int16_t clock = -1);
+
236 #endif // SEND_HAIER_AC
+
237 #if SEND_HAIER_AC_YRW02
+
238  void haierYrwo2(IRHaierACYRW02 *ac,
+
239  const bool on, const stdAc::opmode_t mode,
+
240  const float degrees, const stdAc::fanspeed_t fan,
+
241  const stdAc::swingv_t swingv,
+
242  const bool turbo, const bool filter,
+
243  const int16_t sleep = -1);
+
244 #endif // SEND_HAIER_AC_YRW02
+
245 #if SEND_HITACHI_AC
+
246  void hitachi(IRHitachiAc *ac,
+
247  const bool on, const stdAc::opmode_t mode,
+
248  const float degrees, const stdAc::fanspeed_t fan,
+
249  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh);
+
250 #endif // SEND_HITACHI_AC
+
251 #if SEND_HITACHI_AC1
+
252  void hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model,
+
253  const bool on, const bool power_toggle,
+
254  const stdAc::opmode_t mode,
+
255  const float degrees, const stdAc::fanspeed_t fan,
+
256  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
257  const bool swing_toggle, const int16_t sleep = -1);
+
258 #endif // SEND_HITACHI_AC1
+
259 #if SEND_HITACHI_AC344
+
260  void hitachi344(IRHitachiAc344 *ac,
+
261  const bool on, const stdAc::opmode_t mode,
+
262  const float degrees, const stdAc::fanspeed_t fan,
+
263  const stdAc::swingv_t swingv,
+
264  const stdAc::swingh_t swingh);
+
265 #endif // SEND_HITACHI_AC344
+
266 #if SEND_HITACHI_AC424
+
267  void hitachi424(IRHitachiAc424 *ac,
+
268  const bool on, const stdAc::opmode_t mode,
+
269  const float degrees, const stdAc::fanspeed_t fan,
+
270  const stdAc::swingv_t swingv);
+
271 #endif // SEND_HITACHI_AC424
+
272 #if SEND_KELVINATOR
+
273  void kelvinator(IRKelvinatorAC *ac,
+
274  const bool on, const stdAc::opmode_t mode,
+
275  const float degrees, const stdAc::fanspeed_t fan,
+
276  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
277  const bool quiet, const bool turbo, const bool light,
+
278  const bool filter, const bool clean);
+
279 #endif // SEND_KELVINATOR
+
280 #if SEND_LG
+
281  void lg(IRLgAc *ac, const lg_ac_remote_model_t model,
+
282  const bool on, const stdAc::opmode_t mode,
+
283  const float degrees, const stdAc::fanspeed_t fan);
+
284 #endif // SEND_LG
+
285 #if SEND_MIDEA
+
286  void midea(IRMideaAC *ac,
+
287  const bool on, const stdAc::opmode_t mode, const bool celsius,
+
288  const float degrees, const stdAc::fanspeed_t fan,
+
289  const stdAc::swingv_t swingv, const int16_t sleep = -1);
+
290 #endif // SEND_MIDEA
+
291 #if SEND_MITSUBISHI_AC
+
292  void mitsubishi(IRMitsubishiAC *ac,
+
293  const bool on, const stdAc::opmode_t mode,
+
294  const float degrees,
+
295  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
296  const stdAc::swingh_t swingh,
+
297  const bool quiet, const int16_t clock = -1);
+
298 #endif // SEND_MITSUBISHI_AC
+
299 #if SEND_MITSUBISHI112
+ +
301  const bool on, const stdAc::opmode_t mode,
+
302  const float degrees, const stdAc::fanspeed_t fan,
+
303  const stdAc::swingv_t swingv,
+
304  const stdAc::swingh_t swingh,
+
305  const bool quiet);
+
306 #endif // SEND_MITSUBISHI112
+
307 #if SEND_MITSUBISHI136
+ +
309  const bool on, const stdAc::opmode_t mode,
+
310  const float degrees, const stdAc::fanspeed_t fan,
+
311  const stdAc::swingv_t swingv, const bool quiet);
+
312 #endif // SEND_MITSUBISHI136
+
313 #if SEND_MITSUBISHIHEAVY
+ +
315  const bool on, const stdAc::opmode_t mode,
+
316  const float degrees, const stdAc::fanspeed_t fan,
+
317  const stdAc::swingv_t swingv,
+
318  const stdAc::swingh_t swingh,
+
319  const bool turbo, const bool econo, const bool clean);
+ +
321  const bool on, const stdAc::opmode_t mode,
+
322  const float degrees, const stdAc::fanspeed_t fan,
+
323  const stdAc::swingv_t swingv,
+
324  const stdAc::swingh_t swingh,
+
325  const bool quiet, const bool turbo, const bool econo,
+
326  const bool filter, const bool clean,
+
327  const int16_t sleep = -1);
+
328 #endif // SEND_MITSUBISHIHEAVY
+
329 #if SEND_NEOCLIMA
+
330  void neoclima(IRNeoclimaAc *ac, const bool on, const stdAc::opmode_t mode,
+
331  const float degrees, const stdAc::fanspeed_t fan,
+
332  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
333  const bool turbo, const bool light, const bool filter,
+
334  const int16_t sleep = -1);
+
335 #endif // SEND_NEOCLIMA
+
336 #if SEND_PANASONIC_AC
+ +
338  const bool on, const stdAc::opmode_t mode, const float degrees,
+
339  const stdAc::fanspeed_t fan,
+
340  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
341  const bool quiet, const bool turbo, const bool filter,
+
342  const int16_t clock = -1);
+
343 #endif // SEND_PANASONIC_AC
+
344 #if SEND_SAMSUNG_AC
+
345  void samsung(IRSamsungAc *ac,
+
346  const bool on, const stdAc::opmode_t mode, const float degrees,
+
347  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
348  const bool quiet, const bool turbo, const bool light,
+
349  const bool filter, const bool clean,
+
350  const bool beep, const bool prevpower = true,
+
351  const bool forcepower = true);
+
352 #endif // SEND_SAMSUNG_AC
+
353 #if SEND_SHARP_AC
+
354  void sharp(IRSharpAc *ac,
+
355  const bool on, const bool prev_power, const stdAc::opmode_t mode,
+
356  const float degrees, const stdAc::fanspeed_t fan,
+
357  const stdAc::swingv_t swingv, const bool turbo, const bool filter,
+
358  const bool clean);
+
359 #endif // SEND_SHARP_AC
+
360 #if SEND_TCL112AC
+
361  void tcl112(IRTcl112Ac *ac,
+
362  const bool on, const stdAc::opmode_t mode, const float degrees,
+
363  const stdAc::fanspeed_t fan,
+
364  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
365  const bool turbo, const bool light, const bool econo,
+
366  const bool filter);
+
367 #endif // SEND_TCL112AC
+
368 #if SEND_TECO
+
369  void teco(IRTecoAc *ac,
+
370  const bool on, const stdAc::opmode_t mode, const float degrees,
+
371  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
372  const bool light, const int16_t sleep = -1);
+
373 #endif // SEND_TECO
+
374 #if SEND_TOSHIBA_AC
+
375  void toshiba(IRToshibaAC *ac,
+
376  const bool on, const stdAc::opmode_t mode, const float degrees,
+
377  const stdAc::fanspeed_t fan);
+
378 #endif // SEND_TOSHIBA_AC
+
379 #if SEND_TROTEC
+
380  void trotec(IRTrotecESP *ac,
+
381  const bool on, const stdAc::opmode_t mode, const float degrees,
+
382  const stdAc::fanspeed_t fan, const int16_t sleep = -1);
+
383 #endif // SEND_TROTEC
+
384 #if SEND_VESTEL_AC
+
385  void vestel(IRVestelAc *ac,
+
386  const bool on, const stdAc::opmode_t mode, const float degrees,
+
387  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
388  const bool turbo, const bool filter,
+
389  const int16_t sleep = -1, const int16_t clock = -1,
+
390  const bool sendNormal = true);
+
391 #endif // SEND_VESTEL_AC
+
392 #if SEND_WHIRLPOOL_AC
+ +
394  const bool on, const stdAc::opmode_t mode, const float degrees,
+
395  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
396  const bool turbo, const bool light,
+
397  const int16_t sleep = -1, const int16_t clock = -1);
+
398 #endif // SEND_WHIRLPOOL_AC
+
399 static stdAc::state_t cleanState(const stdAc::state_t state);
+
400 static stdAc::state_t handleToggles(const stdAc::state_t desired,
+
401  const stdAc::state_t *prev = NULL);
+
402 }; // IRac class
+
403 
+
404 namespace IRAcUtils {
+
405  String resultAcToString(const decode_results * const results);
+
406  bool decodeToState(const decode_results *decode, stdAc::state_t *result,
+
407  const stdAc::state_t *prev = NULL);
+
408 } // namespace IRAcUtils
+
409 #endif // IRAC_H_
+
+
Class for handling detailed Panasonic A/C messages.
Definition: ir_Panasonic.h:98
+
Support for Kelvinator A/C protocols.
+
Class for handling detailed Samsung A/C messages.
Definition: ir_Samsung.h:95
+
void hitachi(IRHitachiAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh)
Send a Hitachi A/C message with the supplied settings.
Definition: IRac.cpp:1020
+
Class for handling detailed Toshiba A/C messages.
Definition: ir_Toshiba.h:62
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
stdAc::state_t getStatePrev(void)
Get the previous internal A/C climate state that should have already been sent to the device....
Definition: IRac.cpp:128
+
stdAc::state_t getState(void)
Get the current internal A/C climate state.
Definition: IRac.cpp:123
+
Class for handling detailed Mitsubishi Heavy 152-bit A/C messages.
Definition: ir_MitsubishiHeavy.h:133
+
static stdAc::swingh_t strToSwingH(const char *str, const stdAc::swingh_t def=stdAc::swingh_t::kOff)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2499
+
void hitachi344(IRHitachiAc344 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh)
Send a Hitachi 344-bit A/C message with the supplied settings.
Definition: IRac.cpp:1096
+ +
Support for Electra A/C protocols.
+
void markAsSent(void)
Update the previous state to the current one.
Definition: IRac.cpp:2362
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
void daikin2(IRDaikin2 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool econo, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)
Send a Daikin2 A/C message with the supplied settings.
Definition: IRac.cpp:640
+
Support for Trotec protocols.
+
Class for handling detailed Daikin 280-bit A/C messages.
Definition: ir_Daikin.h:520
+
void lg(IRLgAc *ac, const lg_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
Send a LG A/C message with the supplied settings.
Definition: IRac.cpp:1202
+
Class for handling detailed Delonghi A/C messages.
Definition: ir_Delonghi.h:102
+
Class for handling detailed Corona A/C messages.
Definition: ir_Corona.h:93
+
void kelvinator(IRKelvinatorAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean)
Send a Kelvinator A/C message with the supplied settings.
Definition: IRac.cpp:1168
+
Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering an...
Definition: ir_Daikin.h:602
+
Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy.
+
Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Ven...
Definition: ir_Daikin.h:864
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
Support for Sharp protocols.
+
static String fanspeedToString(const stdAc::fanspeed_t speed)
Convert the supplied fan speed enum into the appropriate String.
Definition: IRac.cpp:2641
+
whirlpool_ac_remote_model_t
Whirlpool A/C model numbers.
Definition: IRsend.h:152
+
Carrier A/C.
+
void whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const int16_t sleep=-1, const int16_t clock=-1)
Send a Whirlpool A/C message with the supplied settings.
Definition: IRac.cpp:1814
+
Results returned from the decoder.
Definition: IRrecv.h:92
+
void daikin64(IRDaikin64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const int16_t sleep=-1, const int16_t clock=-1)
Send a Daikin 64-bit A/C message with the supplied settings.
Definition: IRac.cpp:709
+
void tcl112(IRTcl112Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool light, const bool econo, const bool filter)
Send a TCL 112-bit A/C message with the supplied settings.
Definition: IRac.cpp:1640
+
bool sendAc(void)
Send an A/C message based soley on our internal state.
Definition: IRac.cpp:2368
+
static bool cmpStates(const stdAc::state_t a, const stdAc::state_t b)
Compare two AirCon states.
Definition: IRac.cpp:2379
+
Support for Midea protocols. Midea added by crankyoldgit & bwze.
+
Support for Daikin A/C protocols.
+
gree_ac_remote_model_t
Gree A/C model numbers.
Definition: IRsend.h:129
+
Class for handling detailed Daikin 64-bit A/C messages.
Definition: ir_Daikin.h:998
+ +
void vestel(IRVestelAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const int16_t sleep=-1, const int16_t clock=-1, const bool sendNormal=true)
Send a Vestel A/C message with the supplied settings.
Definition: IRac.cpp:1773
+
Class for handling detailed Hitachi 53-byte/424-bit A/C messages.
Definition: ir_Hitachi.h:313
+
void daikin(IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool clean)
Send a Daikin A/C message with the supplied settings.
Definition: IRac.cpp:476
+
IRac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: IRac.cpp:49
+
Class for handling detailed Daikin 216-bit A/C messages.
Definition: ir_Daikin.h:698
+
hitachi_ac1_remote_model_t
HITACHI_AC1 A/C model numbers.
Definition: IRsend.h:135
+
void samsung(IRSamsungAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean, const bool beep, const bool prevpower=true, const bool forcepower=true)
Send a Samsung A/C message with the supplied settings.
Definition: IRac.cpp:1544
+
void daikin128(IRDaikin128 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool econo, const int16_t sleep=-1, const int16_t clock=-1)
Send a Daikin 128-bit A/C message with the supplied settings.
Definition: IRac.cpp:516
+
Class for handling detailed Hitachi 224-bit A/C messages.
Definition: ir_Hitachi.h:188
+
const int8_t kGpioUnused
Definition: IRac.h:40
+
Definition: IRac.cpp:2710
+
void haier(IRHaierAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool filter, const int16_t sleep=-1, const int16_t clock=-1)
Send a Haier A/C message with the supplied settings.
Definition: IRac.cpp:951
+
Class for handling detailed Whirlpool A/C messages.
Definition: ir_Whirlpool.h:91
+
Class for handling detailed Hitachi 344-bit A/C messages.
Definition: ir_Hitachi.h:401
+
static String boolToString(const bool value)
Convert the supplied boolean into the appropriate String.
Definition: IRac.cpp:2612
+
stdAc::state_t next
The state we want the device to be in after we send.
Definition: IRac.h:91
+
std::string String
Definition: IRremoteESP8266.h:1093
+
Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done ...
Definition: ir_Mitsubishi.h:168
+
void trotec(IRTrotecESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const int16_t sleep=-1)
Send a Trotec A/C message with the supplied settings.
Definition: IRac.cpp:1736
+
static int16_t strToModel(const char *str, const int16_t def=-1)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2539
+
Class for handling detailed Amcor A/C messages.
Definition: ir_Amcor.h:81
+
Definition: ir_Mitsubishi.h:286
+
Class for handling detailed TCL A/C messages.
Definition: ir_Tcl.h:63
+
void daikin176(IRDaikin176 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingh_t swingh)
Send a Daikin 176-bit A/C message with the supplied settings.
Definition: IRac.cpp:608
+
Class for handling detailed Electra A/C messages.
Definition: ir_Electra.h:80
+
Support for TCL protocols.
+
bool hasStateChanged(void)
Check if the internal state has changed from what was previously sent.
Definition: IRac.cpp:2391
+
void haierYrwo2(IRHaierACYRW02 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const int16_t sleep=-1)
Send a Haier YRWO2 A/C message with the supplied settings.
Definition: IRac.cpp:988
+
void daikin216(IRDaikin216 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo)
Send a Daikin 216-bit A/C message with the supplied settings.
Definition: IRac.cpp:679
+
Support for Hitachi A/C protocols.
+
Support for Panasonic protocols.
+
static stdAc::state_t handleToggles(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)
Create a new state base on desired & previous states but handle any state changes for options that ne...
Definition: IRac.cpp:1858
+
Class for handling detailed Mitsubishi 136-bit A/C messages.
Definition: ir_Mitsubishi.h:232
+
panasonic_ac_remote_model_t
Panasonic A/C model numbers.
Definition: IRsend.h:141
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
void mitsubishi112(IRMitsubishi112 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet)
Send a Mitsubishi 112-bit A/C message with the supplied settings.
Definition: IRac.cpp:1306
+
bool decodeToState(const decode_results *decode, stdAc::state_t *result, const stdAc::state_t *prev)
Convert a valid IR A/C remote message that we understand enough into a Common A/C state.
Definition: IRac.cpp:3033
+
Class for handling detailed Hitachi 104-bit A/C messages.
Definition: ir_Hitachi.h:245
+
void hitachi424(IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)
Send a Hitachi 424-bit A/C message with the supplied settings.
Definition: IRac.cpp:1130
+
Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRre...
+
String resultAcToString(const decode_results *const result)
Display the human readable state of an A/C message if we can.
Definition: IRac.cpp:2716
+
void daikin152(IRDaikin152 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool econo)
Send a Daikin 152-bit A/C message with the supplied settings.
Definition: IRac.cpp:553
+
fujitsu_ac_remote_model_t
Fujitsu A/C model numbers.
Definition: IRsend.h:120
+
Support for Gree A/C protocols.
+
Class for handling detailed Carrier 64 bit A/C messages.
Definition: ir_Carrier.h:74
+
Class for handling detailed Midea A/C messages.
Definition: ir_Midea.h:73
+
Class for handling detailed Kelvinator A/C messages.
Definition: ir_Kelvinator.h:137
+
bool _inverted
Definition: IRac.h:97
+
Class for handling detailed Fujitsu A/C messages.
Definition: ir_Fujitsu.h:101
+
Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR r...
+
Class for handling detailed Coolix A/C messages.
Definition: ir_Coolix.h:105
+
void panasonic(IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool filter, const int16_t clock=-1)
Send a Panasonic A/C message with the supplied settings.
Definition: IRac.cpp:1500
+
static String swingvToString(const stdAc::swingv_t swingv)
Convert the supplied enum into the appropriate String.
Definition: IRac.cpp:2663
+
Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github....
+
void midea(IRMideaAC *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const int16_t sleep=-1)
Send a Midea A/C message with the supplied settings.
Definition: IRac.cpp:1235
+
Definition: IRac.h:43
+
Support for Teco protocols.
+
void gree(IRGreeAC *ac, const gree_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const bool clean, const int16_t sleep=-1)
Send a Gree A/C message with the supplied settings.
Definition: IRac.cpp:913
+
Delonghi A/C.
+
void electra(IRElectraAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool lighttoggle, const bool clean)
Send an Electra A/C message with the supplied settings.
Definition: IRac.cpp:766
+
static stdAc::state_t cleanState(const stdAc::state_t state)
Create a new state base on the provided state that has been suitably fixed.
Definition: IRac.cpp:1845
+
Support for Argo Ulisse 13 DCI Mobile Split ACs.
+
void mitsubishi(IRMitsubishiAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const int16_t clock=-1)
Send a Mitsubishi A/C message with the supplied settings.
Definition: IRac.cpp:1271
+
void amcor(IRAmcorAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
Send an Amcor A/C message with the supplied settings.
Definition: IRac.cpp:279
+
Class for handling detailed Daikin 152-bit A/C messages.
Definition: ir_Daikin.h:938
+
Class for handling detailed LG A/C messages.
Definition: ir_LG.h:63
+
Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham.
+
Class for handling detailed Haier A/C messages.
Definition: ir_Haier.h:217
+
Class for handling detailed Daikin 160-bit A/C messages.
Definition: ir_Daikin.h:754
+
static String opmodeToString(const stdAc::opmode_t mode)
Convert the supplied operation mode into the appropriate String.
Definition: IRac.cpp:2619
+
Class for handling detailed Sharp A/C messages.
Definition: ir_Sharp.h:108
+
Support for Goodweather compatible HVAC protocols.
+
void argo(IRArgoAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const int16_t sleep=-1)
Send an Argo A/C message with the supplied settings.
Definition: IRac.cpp:311
+
lg_ac_remote_model_t
LG A/C model numbers.
Definition: IRsend.h:158
+
void mitsubishi136(IRMitsubishi136 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet)
Send a Mitsubishi 136-bit A/C message with the supplied settings.
Definition: IRac.cpp:1342
+ +
bool _modulation
Definition: IRac.h:98
+
void teco(IRTecoAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool light, const int16_t sleep=-1)
Send a Teco A/C message with the supplied settings.
Definition: IRac.cpp:1676
+
static stdAc::opmode_t strToOpmode(const char *str, const stdAc::opmode_t def=stdAc::opmode_t::kAuto)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2397
+
void hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, const bool on, const bool power_toggle, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool swing_toggle, const int16_t sleep=-1)
Send a Hitachi1 A/C message with the supplied settings.
Definition: IRac.cpp:1057
+ +
Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.
+
static bool strToBool(const char *str, const bool def=false)
Convert the supplied str into the appropriate boolean value.
Definition: IRac.cpp:2594
+
void toshiba(IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
Send a Toshiba A/C message with the supplied settings.
Definition: IRac.cpp:1706
+
void mitsubishiHeavy88(IRMitsubishiHeavy88Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool econo, const bool clean)
Send a Mitsubishi Heavy 88-bit A/C message with the supplied settings.
Definition: IRac.cpp:1377
+
static stdAc::swingv_t strToSwingV(const char *str, const stdAc::swingv_t def=stdAc::swingv_t::kOff)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2458
+
Class for handling detailed Vestel A/C messages.
Definition: ir_Vestel.h:116
+
void neoclima(IRNeoclimaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool light, const bool filter, const int16_t sleep=-1)
Send a Neoclima A/C message with the supplied settings.
Definition: IRac.cpp:1460
+
Class for handling detailed Trotec A/C messages.
Definition: ir_Trotec.h:76
+
Class for handling detailed Teco A/C messages.
Definition: ir_Teco.h:107
+
static String swinghToString(const stdAc::swingh_t swingh)
Convert the supplied enum into the appropriate String.
Definition: IRac.cpp:2687
+
void delonghiac(IRDelonghiAc *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const bool turbo, const int16_t sleep=-1)
Send a Delonghi A/C message with the supplied settings.
Definition: IRac.cpp:739
+
stdAc::state_t _prev
Definition: IRac.h:99
+
Class for handling detailed Haier ACYRW02 A/C messages.
Definition: ir_Haier.h:289
+
void daikin160(IRDaikin160 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)
Send a Daikin 160-bit A/C message with the supplied settings.
Definition: IRac.cpp:586
+
void corona(IRCoronaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool econo)
Send a Corona A/C message with the supplied settings.
Definition: IRac.cpp:441
+
static void initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)
Initialse the given state with the supplied settings.
Definition: IRac.cpp:80
+
void mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean, const int16_t sleep=-1)
Send a Mitsubishi Heavy 152-bit A/C message with the supplied settings.
Definition: IRac.cpp:1418
+ +
Support for Haier A/C protocols. The specifics of reverse engineering the protocols details:
+
Class for handling detailed Mitsubishi Heavy 88-bit A/C messages.
Definition: ir_MitsubishiHeavy.h:220
+
Class for handling detailed Gree A/C messages.
Definition: ir_Gree.h:117
+
void coolix(IRCoolixAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool light, const bool clean, const int16_t sleep=-1)
Send a Coolix A/C message with the supplied settings.
Definition: IRac.cpp:380
+
static stdAc::fanspeed_t strToFanspeed(const char *str, const stdAc::fanspeed_t def=stdAc::fanspeed_t::kAuto)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2427
+
Support for Toshiba protocols.
+
void sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const bool clean)
Send a Sharp A/C message with the supplied settings.
Definition: IRac.cpp:1588
+
void goodweather(IRGoodweatherAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const int16_t sleep=-1)
Send a Goodweather A/C message with the supplied settings.
Definition: IRac.cpp:871
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
Class for handling detailed Goodweather A/C messages.
Definition: ir_Goodweather.h:90
+
Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.
+ +
Class for handling detailed Argo A/C messages.
Definition: ir_Argo.h:129
+
void fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean)
Send a Fujitsu A/C message with the supplied settings.
Definition: IRac.cpp:808
+
Class for handling detailed Neoclima A/C messages.
Definition: ir_Neoclima.h:86
+
static bool isProtocolSupported(const decode_type_t protocol)
Is the given protocol supported by the IRac class?
Definition: IRac.cpp:133
+
Class for handling detailed Daikin 176-bit A/C messages.
Definition: ir_Daikin.h:806
+
Amcor A/C protocol.
+
uint16_t _pin
Definition: IRac.h:96
+
Support for LG protocols.
+
void carrier64(IRCarrierAc64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const int16_t sleep=-1)
Send a Carrier 64-bit A/C message with the supplied settings.
Definition: IRac.cpp:343
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8cpp.html new file mode 100644 index 000000000..405dbd5b5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8cpp.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: src/IRrecv.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRrecv.cpp File Reference
+
+
+ + + + + + + + +

+Variables

portMUX_TYPE irremote_mux = portMUX_INITIALIZER_UNLOCKED
 
volatile irparams_t irparams
 
irparams_tirparams_save
 
+

Variable Documentation

+ +

◆ irparams

+ +
+
+ + + + +
volatile irparams_t irparams
+
+ +
+
+ +

◆ irparams_save

+ +
+
+ + + + +
irparams_t* irparams_save
+
+ +
+
+ +

◆ irremote_mux

+ +
+
+ + + + +
portMUX_TYPE irremote_mux = portMUX_INITIALIZER_UNLOCKED
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h.html new file mode 100644 index 000000000..726b05484 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h.html @@ -0,0 +1,425 @@ + + + + + + + +IRremoteESP8266: src/IRrecv.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRrecv.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + +

+Classes

struct  irparams_t
 Information for the interrupt handler. More...
 
struct  match_result_t
 Results from a data match. More...
 
class  decode_results
 Results returned from the decoder. More...
 
class  IRrecv
 Class for receiving IR messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kHeader = 2
 
const uint16_t kFooter = 2
 
const uint16_t kStartOffset = 1
 
const uint16_t kMarkExcess = 50
 
const uint16_t kRawBuf = 100
 
const uint64_t kRepeat = UINT64_MAX
 
const uint16_t kUnknownThreshold = 6
 
const uint8_t kIdleState = 2
 
const uint8_t kMarkState = 3
 
const uint8_t kSpaceState = 4
 
const uint8_t kStopState = 5
 
const uint8_t kTolerance = 25
 
const uint8_t kUseDefTol = 255
 
const uint16_t kRawTick = 2
 
const uint8_t kTimeoutMs = 15
 
const uint16_t kMaxTimeoutMs = kRawTick * (UINT16_MAX / MS_TO_USEC(1))
 
const uint32_t kFnvPrime32 = 16777619UL
 
const uint32_t kFnvBasis32 = 2166136261UL
 
const uint8_t kDefaultESP32Timer = 3
 
const uint16_t kStateSizeMax = kHitachiAc2StateLength
 
+

Variable Documentation

+ +

◆ kDefaultESP32Timer

+ +
+
+ + + + +
const uint8_t kDefaultESP32Timer = 3
+
+ +
+
+ +

◆ kFnvBasis32

+ +
+
+ + + + +
const uint32_t kFnvBasis32 = 2166136261UL
+
+ +
+
+ +

◆ kFnvPrime32

+ +
+
+ + + + +
const uint32_t kFnvPrime32 = 16777619UL
+
+ +
+
+ +

◆ kFooter

+ +
+
+ + + + +
const uint16_t kFooter = 2
+
+ +
+
+ +

◆ kHeader

+ +
+
+ + + + +
const uint16_t kHeader = 2
+
+ +
+
+ +

◆ kIdleState

+ +
+
+ + + + +
const uint8_t kIdleState = 2
+
+ +
+
+ +

◆ kMarkExcess

+ +
+
+ + + + +
const uint16_t kMarkExcess = 50
+
+ +
+
+ +

◆ kMarkState

+ +
+
+ + + + +
const uint8_t kMarkState = 3
+
+ +
+
+ +

◆ kMaxTimeoutMs

+ +
+
+ + + + +
const uint16_t kMaxTimeoutMs = kRawTick * (UINT16_MAX / MS_TO_USEC(1))
+
+ +
+
+ +

◆ kRawBuf

+ +
+
+ + + + +
const uint16_t kRawBuf = 100
+
+ +
+
+ +

◆ kRawTick

+ +
+
+ + + + +
const uint16_t kRawTick = 2
+
+ +
+
+ +

◆ kRepeat

+ +
+
+ + + + +
const uint64_t kRepeat = UINT64_MAX
+
+ +
+
+ +

◆ kSpaceState

+ +
+
+ + + + +
const uint8_t kSpaceState = 4
+
+ +
+
+ +

◆ kStartOffset

+ +
+
+ + + + +
const uint16_t kStartOffset = 1
+
+ +
+
+ +

◆ kStateSizeMax

+ +
+
+ + + + +
const uint16_t kStateSizeMax = kHitachiAc2StateLength
+
+ +
+
+ +

◆ kStopState

+ +
+
+ + + + +
const uint8_t kStopState = 5
+
+ +
+
+ +

◆ kTimeoutMs

+ +
+
+ + + + +
const uint8_t kTimeoutMs = 15
+
+ +
+
+ +

◆ kTolerance

+ +
+
+ + + + +
const uint8_t kTolerance = 25
+
+ +
+
+ +

◆ kUnknownThreshold

+ +
+
+ + + + +
const uint16_t kUnknownThreshold = 6
+
+ +
+
+ +

◆ kUseDefTol

+ +
+
+ + + + +
const uint8_t kUseDefTol = 255
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h_source.html new file mode 100644 index 000000000..65256af77 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h_source.html @@ -0,0 +1,972 @@ + + + + + + + +IRremoteESP8266: src/IRrecv.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRrecv.h
+
+
+Go to the documentation of this file.
1 // Copyright 2009 Ken Shirriff
+
2 // Copyright 2015 Mark Szabo
+
3 // Copyright 2015 Sebastien Warin
+
4 // Copyright 2017 David Conran
+
5 
+
6 #ifndef IRRECV_H_
+
7 #define IRRECV_H_
+
8 
+
9 #ifndef UNIT_TEST
+
10 #include <Arduino.h>
+
11 #endif
+
12 #include <stddef.h>
+
13 #define __STDC_LIMIT_MACROS
+
14 #include <stdint.h>
+
15 #include "IRremoteESP8266.h"
+
16 
+
17 // Constants
+
18 const uint16_t kHeader = 2; // Usual nr. of header entries.
+
19 const uint16_t kFooter = 2; // Usual nr. of footer (stop bits) entries.
+
20 const uint16_t kStartOffset = 1; // Usual rawbuf entry to start from.
+
21 #define MS_TO_USEC(x) (x * 1000U) // Convert milli-Seconds to micro-Seconds.
+
22 // Marks tend to be 100us too long, and spaces 100us too short
+
23 // when received due to sensor lag.
+
24 const uint16_t kMarkExcess = 50;
+
25 const uint16_t kRawBuf = 100; // Default length of raw capture buffer
+
26 const uint64_t kRepeat = UINT64_MAX;
+
27 // Default min size of reported UNKNOWN messages.
+
28 const uint16_t kUnknownThreshold = 6;
+
29 
+
30 // receiver states
+
31 const uint8_t kIdleState = 2;
+
32 const uint8_t kMarkState = 3;
+
33 const uint8_t kSpaceState = 4;
+
34 const uint8_t kStopState = 5;
+
35 const uint8_t kTolerance = 25; // default percent tolerance in measurements.
+
36 const uint8_t kUseDefTol = 255; // Indicate to use the class default tolerance.
+
37 const uint16_t kRawTick = 2; // Capture tick to uSec factor.
+
38 #define RAWTICK kRawTick // Deprecated. For legacy user code support only.
+
39 // How long (ms) before we give up wait for more data?
+
40 // Don't exceed kMaxTimeoutMs without a good reason.
+
41 // That is the capture buffers maximum value size. (UINT16_MAX / kRawTick)
+
42 // Typically messages/protocols tend to repeat around the 100ms timeframe,
+
43 // thus we should timeout before that to give us some time to try to decode
+
44 // before we need to start capturing a possible new message.
+
45 // Typically 15ms suits most applications. However, some protocols demand a
+
46 // higher value. e.g. 90ms for XMP-1 and some aircon units.
+
47 const uint8_t kTimeoutMs = 15; // In MilliSeconds.
+
48 #define TIMEOUT_MS kTimeoutMs // For legacy documentation.
+
49 const uint16_t kMaxTimeoutMs = kRawTick * (UINT16_MAX / MS_TO_USEC(1));
+
50 
+
51 // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
+
52 const uint32_t kFnvPrime32 = 16777619UL;
+
53 const uint32_t kFnvBasis32 = 2166136261UL;
+
54 
+
55 // Which of the ESP32 timers to use by default. (0-3)
+
56 const uint8_t kDefaultESP32Timer = 3;
+
57 
+
58 #if DECODE_AC
+
59 // Hitachi AC is the current largest state size.
+ +
61 #else
+
62 // Just define something
+
63 const uint16_t kStateSizeMax = 0;
+
64 #endif
+
65 
+
66 // Types
+
67 
+
69 typedef struct {
+
70  uint8_t recvpin; // pin for IR data from detector
+
71  uint8_t rcvstate; // state machine
+
72  uint16_t timer; // state timer, counts 50uS ticks.
+
73  uint16_t bufsize; // max. nr. of entries in the capture buffer.
+
74  uint16_t *rawbuf; // raw data
+
75  // uint16_t is used for rawlen as it saves 3 bytes of iram in the interrupt
+
76  // handler. Don't ask why, I don't know. It just does.
+
77  uint16_t rawlen; // counter of entries in rawbuf.
+
78  uint8_t overflow; // Buffer overflow indicator.
+
79  uint8_t timeout; // Nr. of milliSeconds before we give up.
+
80 } irparams_t;
+
81 
+
83 typedef struct {
+
84  bool success; // Was the match successful?
+
85  uint64_t data; // The data found.
+
86  uint16_t used; // How many buffer positions were used.
+ +
88 
+
89 // Classes
+
90 
+ +
93  public:
+
94  decode_type_t decode_type; // NEC, SONY, RC5, UNKNOWN
+
95  // value, address, & command are all mutually exclusive with state.
+
96  // i.e. They MUST NOT be used at the same time as state, so we can use a union
+
97  // structure to save us a handful of valuable bytes of memory.
+
98  union {
+
99  struct {
+
100  uint64_t value; // Decoded value
+
101  uint32_t address; // Decoded device address.
+
102  uint32_t command; // Decoded command.
+
103  };
+
104  uint8_t state[kStateSizeMax]; // Multi-byte results.
+
105  };
+
106  uint16_t bits; // Number of bits in decoded value
+
107  volatile uint16_t *rawbuf; // Raw intervals in .5 us ticks
+
108  uint16_t rawlen; // Number of records in rawbuf.
+
109  bool overflow;
+
110  bool repeat; // Is the result a repeat code?
+
111 };
+
112 
+
114 class IRrecv {
+
115  public:
+
116 #if defined(ESP32)
+
117  explicit IRrecv(const uint16_t recvpin, const uint16_t bufsize = kRawBuf,
+
118  const uint8_t timeout = kTimeoutMs,
+
119  const bool save_buffer = false,
+
120  const uint8_t timer_num = kDefaultESP32Timer); // Constructor
+
121 #else // ESP32
+
122  explicit IRrecv(const uint16_t recvpin, const uint16_t bufsize = kRawBuf,
+
123  const uint8_t timeout = kTimeoutMs,
+
124  const bool save_buffer = false); // Constructor
+
125 #endif // ESP32
+
126  ~IRrecv(void); // Destructor
+
127  void setTolerance(const uint8_t percent = kTolerance);
+
128  uint8_t getTolerance(void);
+
129  bool decode(decode_results *results, irparams_t *save = NULL,
+
130  uint8_t max_skip = 0, uint16_t noise_floor = 0);
+
131  void enableIRIn(const bool pullup = false);
+
132  void disableIRIn(void);
+
133  void resume(void);
+
134  uint16_t getBufSize(void);
+
135 #if DECODE_HASH
+
136  void setUnknownThreshold(const uint16_t length);
+
137 #endif
+
138  bool match(const uint32_t measured, const uint32_t desired,
+
139  const uint8_t tolerance = kUseDefTol,
+
140  const uint16_t delta = 0);
+
141  bool matchMark(const uint32_t measured, const uint32_t desired,
+
142  const uint8_t tolerance = kUseDefTol,
+
143  const int16_t excess = kMarkExcess);
+
144  bool matchSpace(const uint32_t measured, const uint32_t desired,
+
145  const uint8_t tolerance = kUseDefTol,
+
146  const int16_t excess = kMarkExcess);
+
147 #ifndef UNIT_TEST
+
148 
+
149  private:
+
150 #endif
+ +
152  uint8_t _tolerance;
+
153 #if defined(ESP32)
+
154  uint8_t _timer_num;
+
155 #endif // defined(ESP32)
+
156 #if DECODE_HASH
+ +
158 #endif
+
159  // These are called by decode
+
160  uint8_t _validTolerance(const uint8_t percentage);
+
161  void copyIrParams(volatile irparams_t *src, irparams_t *dst);
+
162  uint16_t compare(const uint16_t oldval, const uint16_t newval);
+
163  uint32_t ticksLow(const uint32_t usecs,
+
164  const uint8_t tolerance = kUseDefTol,
+
165  const uint16_t delta = 0);
+
166  uint32_t ticksHigh(const uint32_t usecs,
+
167  const uint8_t tolerance = kUseDefTol,
+
168  const uint16_t delta = 0);
+
169  bool matchAtLeast(const uint32_t measured, const uint32_t desired,
+
170  const uint8_t tolerance = kUseDefTol,
+
171  const uint16_t delta = 0);
+
172  uint16_t _matchGeneric(volatile uint16_t *data_ptr,
+
173  uint64_t *result_bits_ptr,
+
174  uint8_t *result_ptr,
+
175  const bool use_bits,
+
176  const uint16_t remaining,
+
177  const uint16_t required,
+
178  const uint16_t hdrmark,
+
179  const uint32_t hdrspace,
+
180  const uint16_t onemark,
+
181  const uint32_t onespace,
+
182  const uint16_t zeromark,
+
183  const uint32_t zerospace,
+
184  const uint16_t footermark,
+
185  const uint32_t footerspace,
+
186  const bool atleast = false,
+
187  const uint8_t tolerance = kUseDefTol,
+
188  const int16_t excess = kMarkExcess,
+
189  const bool MSBfirst = true);
+
190  match_result_t matchData(volatile uint16_t *data_ptr, const uint16_t nbits,
+
191  const uint16_t onemark, const uint32_t onespace,
+
192  const uint16_t zeromark, const uint32_t zerospace,
+
193  const uint8_t tolerance = kUseDefTol,
+
194  const int16_t excess = kMarkExcess,
+
195  const bool MSBfirst = true);
+
196  uint16_t matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr,
+
197  const uint16_t remaining, const uint16_t nbytes,
+
198  const uint16_t onemark, const uint32_t onespace,
+
199  const uint16_t zeromark, const uint32_t zerospace,
+
200  const uint8_t tolerance = kUseDefTol,
+
201  const int16_t excess = kMarkExcess,
+
202  const bool MSBfirst = true);
+
203  uint16_t matchGeneric(volatile uint16_t *data_ptr,
+
204  uint64_t *result_ptr,
+
205  const uint16_t remaining, const uint16_t nbits,
+
206  const uint16_t hdrmark, const uint32_t hdrspace,
+
207  const uint16_t onemark, const uint32_t onespace,
+
208  const uint16_t zeromark, const uint32_t zerospace,
+
209  const uint16_t footermark, const uint32_t footerspace,
+
210  const bool atleast = false,
+
211  const uint8_t tolerance = kUseDefTol,
+
212  const int16_t excess = kMarkExcess,
+
213  const bool MSBfirst = true);
+
214  uint16_t matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr,
+
215  const uint16_t remaining, const uint16_t nbits,
+
216  const uint16_t hdrmark, const uint32_t hdrspace,
+
217  const uint16_t onemark, const uint32_t onespace,
+
218  const uint16_t zeromark, const uint32_t zerospace,
+
219  const uint16_t footermark,
+
220  const uint32_t footerspace,
+
221  const bool atleast = false,
+
222  const uint8_t tolerance = kUseDefTol,
+
223  const int16_t excess = kMarkExcess,
+
224  const bool MSBfirst = true);
+
225  uint16_t matchGenericConstBitTime(volatile uint16_t *data_ptr,
+
226  uint64_t *result_ptr,
+
227  const uint16_t remaining,
+
228  const uint16_t nbits,
+
229  const uint16_t hdrmark,
+
230  const uint32_t hdrspace,
+
231  const uint16_t one,
+
232  const uint32_t zero,
+
233  const uint16_t footermark,
+
234  const uint32_t footerspace,
+
235  const bool atleast = false,
+
236  const uint8_t tolerance = kUseDefTol,
+
237  const int16_t excess = kMarkExcess,
+
238  const bool MSBfirst = true);
+
239  uint16_t matchManchesterData(volatile const uint16_t *data_ptr,
+
240  uint64_t *result_ptr,
+
241  const uint16_t remaining,
+
242  const uint16_t nbits,
+
243  const uint16_t half_period,
+
244  const uint16_t starting_balance = 0,
+
245  const uint8_t tolerance = kUseDefTol,
+
246  const int16_t excess = kMarkExcess,
+
247  const bool MSBfirst = true,
+
248  const bool GEThomas = true);
+
249  uint16_t matchManchester(volatile const uint16_t *data_ptr,
+
250  uint64_t *result_ptr,
+
251  const uint16_t remaining,
+
252  const uint16_t nbits,
+
253  const uint16_t hdrmark,
+
254  const uint32_t hdrspace,
+
255  const uint16_t clock_period,
+
256  const uint16_t footermark,
+
257  const uint32_t footerspace,
+
258  const bool atleast = false,
+
259  const uint8_t tolerance = kUseDefTol,
+
260  const int16_t excess = kMarkExcess,
+
261  const bool MSBfirst = true,
+
262  const bool GEThomas = true);
+
263  void crudeNoiseFilter(decode_results *results, const uint16_t floor = 0);
+
264  bool decodeHash(decode_results *results);
+
265 #if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || DECODE_SANYO)
+
266  bool decodeNEC(decode_results *results, uint16_t offset = kStartOffset,
+
267  const uint16_t nbits = kNECBits, const bool strict = true);
+
268 #endif
+
269 #if DECODE_ARGO
+
270  bool decodeArgo(decode_results *results, uint16_t offset = kStartOffset,
+
271  const uint16_t nbits = kArgoBits, const bool strict = true);
+
272 #endif // DECODE_ARGO
+
273 #if DECODE_SONY
+
274  bool decodeSony(decode_results *results, uint16_t offset = kStartOffset,
+
275  const uint16_t nbits = kSonyMinBits,
+
276  const bool strict = false);
+
277 #endif
+
278 #if DECODE_SANYO
+
279  // DISABLED due to poor quality.
+
280  // bool decodeSanyo(decode_results *results, uint16_t offset = kStartOffset,
+
281  // uint16_t nbits = kSanyoSA8650BBits,
+
282  // bool strict = false);
+
283  bool decodeSanyoLC7461(decode_results *results,
+
284  uint16_t offset = kStartOffset,
+
285  const uint16_t nbits = kSanyoLC7461Bits,
+
286  bool strict = true);
+
287 #endif
+
288 #if DECODE_MITSUBISHI
+
289  bool decodeMitsubishi(decode_results *results, uint16_t offset = kStartOffset,
+
290  const uint16_t nbits = kMitsubishiBits,
+
291  const bool strict = true);
+
292 #endif
+
293 #if DECODE_MITSUBISHI2
+
294  bool decodeMitsubishi2(decode_results *results,
+
295  uint16_t offset = kStartOffset,
+
296  const uint16_t nbits = kMitsubishiBits,
+
297  const bool strict = true);
+
298 #endif
+
299 #if DECODE_MITSUBISHI_AC
+
300  bool decodeMitsubishiAC(decode_results *results,
+
301  uint16_t offset = kStartOffset,
+
302  const uint16_t nbits = kMitsubishiACBits,
+
303  const bool strict = false);
+
304 #endif
+
305 #if DECODE_MITSUBISHI136
+
306  bool decodeMitsubishi136(decode_results *results,
+
307  uint16_t offset = kStartOffset,
+
308  const uint16_t nbits = kMitsubishi136Bits,
+
309  const bool strict = true);
+
310 #endif
+
311 #if DECODE_MITSUBISHI112
+
312  bool decodeMitsubishi112(decode_results *results,
+
313  uint16_t offset = kStartOffset,
+
314  const uint16_t nbits = kMitsubishi112Bits,
+
315  const bool strict = true);
+
316 #endif
+
317 #if DECODE_MITSUBISHIHEAVY
+ +
319  uint16_t offset = kStartOffset,
+
320  const uint16_t nbits = kMitsubishiHeavy152Bits,
+
321  const bool strict = true);
+
322 #endif
+
323 #if (DECODE_RC5 || DECODE_R6 || DECODE_LASERTAG || DECODE_MWM)
+
324  int16_t getRClevel(decode_results *results, uint16_t *offset, uint16_t *used,
+
325  uint16_t bitTime, const uint8_t tolerance = kUseDefTol,
+
326  const int16_t excess = kMarkExcess,
+
327  const uint16_t delta = 0, const uint8_t maxwidth = 3);
+
328 #endif
+
329 #if DECODE_RC5
+
330  bool decodeRC5(decode_results *results, uint16_t offset = kStartOffset,
+
331  const uint16_t nbits = kRC5XBits,
+
332  const bool strict = true);
+
333 #endif
+
334 #if DECODE_RC6
+
335  bool decodeRC6(decode_results *results, uint16_t offset = kStartOffset,
+
336  const uint16_t nbits = kRC6Mode0Bits,
+
337  const bool strict = false);
+
338 #endif
+
339 #if DECODE_RCMM
+
340  bool decodeRCMM(decode_results *results, uint16_t offset = kStartOffset,
+
341  const uint16_t nbits = kRCMMBits,
+
342  const bool strict = false);
+
343 #endif
+
344 #if (DECODE_PANASONIC || DECODE_DENON)
+
345  bool decodePanasonic(decode_results *results, uint16_t offset = kStartOffset,
+
346  const uint16_t nbits = kPanasonicBits,
+
347  const bool strict = false,
+
348  const uint32_t manufacturer = kPanasonicManufacturer);
+
349 #endif
+
350 #if DECODE_LG
+
351  bool decodeLG(decode_results *results, uint16_t offset = kStartOffset,
+
352  const uint16_t nbits = kLgBits,
+
353  const bool strict = false);
+
354 #endif
+
355 #if DECODE_INAX
+
356  bool decodeInax(decode_results *results, uint16_t offset = kStartOffset,
+
357  const uint16_t nbits = kInaxBits,
+
358  const bool strict = true);
+
359 #endif // DECODE_INAX
+
360 #if DECODE_JVC
+
361  bool decodeJVC(decode_results *results, uint16_t offset = kStartOffset,
+
362  const uint16_t nbits = kJvcBits,
+
363  const bool strict = true);
+
364 #endif
+
365 #if DECODE_SAMSUNG
+
366  bool decodeSAMSUNG(decode_results *results, uint16_t offset = kStartOffset,
+
367  const uint16_t nbits = kSamsungBits,
+
368  const bool strict = true);
+
369 #endif
+
370 #if DECODE_SAMSUNG
+
371  bool decodeSamsung36(decode_results *results, uint16_t offset = kStartOffset,
+
372  const uint16_t nbits = kSamsung36Bits,
+
373  const bool strict = true);
+
374 #endif
+
375 #if DECODE_SAMSUNG_AC
+
376  bool decodeSamsungAC(decode_results *results, uint16_t offset = kStartOffset,
+
377  const uint16_t nbits = kSamsungAcBits,
+
378  const bool strict = true);
+
379 #endif
+
380 #if DECODE_WHYNTER
+
381  bool decodeWhynter(decode_results *results, uint16_t offset = kStartOffset,
+
382  const uint16_t nbits = kWhynterBits,
+
383  const bool strict = true);
+
384 #endif
+
385 #if DECODE_COOLIX
+
386  bool decodeCOOLIX(decode_results *results, uint16_t offset = kStartOffset,
+
387  const uint16_t nbits = kCoolixBits,
+
388  const bool strict = true);
+
389 #endif
+
390 #if DECODE_DENON
+
391  bool decodeDenon(decode_results *results, uint16_t offset = kStartOffset,
+
392  const uint16_t nbits = kDenonBits,
+
393  const bool strict = true);
+
394 #endif
+
395 #if DECODE_DISH
+
396  bool decodeDISH(decode_results *results, uint16_t offset = kStartOffset,
+
397  const uint16_t nbits = kDishBits,
+
398  const bool strict = true);
+
399 #endif
+
400 #if (DECODE_SHARP || DECODE_DENON)
+
401  bool decodeSharp(decode_results *results, uint16_t offset = kStartOffset,
+
402  const uint16_t nbits = kSharpBits,
+
403  const bool strict = true, const bool expansion = true);
+
404 #endif
+
405 #if DECODE_SHARP_AC
+
406  bool decodeSharpAc(decode_results *results, uint16_t offset = kStartOffset,
+
407  const uint16_t nbits = kSharpAcBits,
+
408  const bool strict = true);
+
409 #endif
+
410 #if DECODE_AIWA_RC_T501
+
411  bool decodeAiwaRCT501(decode_results *results, uint16_t offset = kStartOffset,
+
412  const uint16_t nbits = kAiwaRcT501Bits,
+
413  const bool strict = true);
+
414 #endif
+
415 #if DECODE_NIKAI
+
416  bool decodeNikai(decode_results *results, uint16_t offset = kStartOffset,
+
417  const uint16_t nbits = kNikaiBits,
+
418  const bool strict = true);
+
419 #endif
+
420 #if DECODE_MAGIQUEST
+
421  bool decodeMagiQuest(decode_results *results, uint16_t offset = kStartOffset,
+
422  const uint16_t nbits = kMagiquestBits,
+
423  const bool strict = true);
+
424 #endif
+
425 #if DECODE_KELVINATOR
+
426  bool decodeKelvinator(decode_results *results, uint16_t offset = kStartOffset,
+
427  const uint16_t nbits = kKelvinatorBits,
+
428  const bool strict = true);
+
429 #endif
+
430 #if DECODE_DAIKIN
+
431  bool decodeDaikin(decode_results *results, uint16_t offset = kStartOffset,
+
432  const uint16_t nbits = kDaikinBits,
+
433  const bool strict = true);
+
434 #endif
+
435 #if DECODE_DAIKIN64
+
436  bool decodeDaikin64(decode_results *results, uint16_t offset = kStartOffset,
+
437  const uint16_t nbits = kDaikin64Bits,
+
438  const bool strict = true);
+
439 #endif // DECODE_DAIKIN64
+
440 #if DECODE_DAIKIN128
+
441  bool decodeDaikin128(decode_results *results, uint16_t offset = kStartOffset,
+
442  const uint16_t nbits = kDaikin128Bits,
+
443  const bool strict = true);
+
444 #endif // DECODE_DAIKIN128
+
445 #if DECODE_DAIKIN152
+
446  bool decodeDaikin152(decode_results *results, uint16_t offset = kStartOffset,
+
447  const uint16_t nbits = kDaikin152Bits,
+
448  const bool strict = true);
+
449 #endif // DECODE_DAIKIN152
+
450 #if DECODE_DAIKIN160
+
451  bool decodeDaikin160(decode_results *results, uint16_t offset = kStartOffset,
+
452  const uint16_t nbits = kDaikin160Bits,
+
453  const bool strict = true);
+
454 #endif // DECODE_DAIKIN160
+
455 #if DECODE_DAIKIN176
+
456  bool decodeDaikin176(decode_results *results, uint16_t offset = kStartOffset,
+
457  const uint16_t nbits = kDaikin176Bits,
+
458  const bool strict = true);
+
459 #endif // DECODE_DAIKIN176
+
460 #if DECODE_DAIKIN2
+
461  bool decodeDaikin2(decode_results *results, uint16_t offset = kStartOffset,
+
462  const uint16_t nbits = kDaikin2Bits,
+
463  const bool strict = true);
+
464 #endif
+
465 #if DECODE_DAIKIN216
+
466  bool decodeDaikin216(decode_results *results, uint16_t offset = kStartOffset,
+
467  const uint16_t nbits = kDaikin216Bits,
+
468  const bool strict = true);
+
469 #endif
+
470 #if DECODE_TOSHIBA_AC
+
471  bool decodeToshibaAC(decode_results *results, uint16_t offset = kStartOffset,
+
472  const uint16_t nbytes = kToshibaACBits,
+
473  const bool strict = true);
+
474 #endif
+
475 #if DECODE_TROTEC
+
476  bool decodeTrotec(decode_results *results, uint16_t offset = kStartOffset,
+
477  const uint16_t nbits = kTrotecBits,
+
478  const bool strict = true);
+
479 #endif // DECODE_TROTEC
+
480 #if DECODE_MIDEA
+
481  bool decodeMidea(decode_results *results, uint16_t offset = kStartOffset,
+
482  const uint16_t nbits = kMideaBits,
+
483  const bool strict = true);
+
484 #endif // DECODE_MIDEA
+
485 #if DECODE_MIDEA24
+
486  bool decodeMidea24(decode_results *results, uint16_t offset = kStartOffset,
+
487  const uint16_t nbits = kMidea24Bits,
+
488  const bool strict = true);
+
489 #endif // DECODE_MIDEA24
+
490 #if DECODE_FUJITSU_AC
+
491  bool decodeFujitsuAC(decode_results *results, uint16_t offset = kStartOffset,
+
492  const uint16_t nbits = kFujitsuAcBits,
+
493  const bool strict = false);
+
494 #endif
+
495 #if DECODE_LASERTAG
+
496  bool decodeLasertag(decode_results *results, uint16_t offset = kStartOffset,
+
497  const uint16_t nbits = kLasertagBits,
+
498  const bool strict = true);
+
499 #endif
+
500 #if DECODE_CARRIER_AC
+
501  bool decodeCarrierAC(decode_results *results, uint16_t offset = kStartOffset,
+
502  const uint16_t nbits = kCarrierAcBits,
+
503  const bool strict = true);
+
504 #endif // DECODE_CARRIER_AC
+
505 #if DECODE_CARRIER_AC40
+
506  bool decodeCarrierAC40(decode_results *results,
+
507  uint16_t offset = kStartOffset,
+
508  const uint16_t nbits = kCarrierAc40Bits,
+
509  const bool strict = true);
+
510 #endif // DECODE_CARRIER_AC40
+
511 #if DECODE_CARRIER_AC64
+
512  bool decodeCarrierAC64(decode_results *results,
+
513  uint16_t offset = kStartOffset,
+
514  const uint16_t nbits = kCarrierAc64Bits,
+
515  const bool strict = true);
+
516 #endif // DECODE_CARRIER_AC64
+
517 #if DECODE_GOODWEATHER
+
518  bool decodeGoodweather(decode_results *results,
+
519  uint16_t offset = kStartOffset,
+
520  const uint16_t nbits = kGoodweatherBits,
+
521  const bool strict = true);
+
522 #endif // DECODE_GOODWEATHER
+
523 #if DECODE_GREE
+
524  bool decodeGree(decode_results *results, uint16_t offset = kStartOffset,
+
525  const uint16_t nbits = kGreeBits,
+
526  const bool strict = true);
+
527 #endif
+
528 #if (DECODE_HAIER_AC | DECODE_HAIER_AC_YRW02)
+
529  bool decodeHaierAC(decode_results *results, uint16_t offset = kStartOffset,
+
530  const uint16_t nbits = kHaierACBits,
+
531  const bool strict = true);
+
532 #endif
+
533 #if DECODE_HAIER_AC_YRW02
+
534  bool decodeHaierACYRW02(decode_results *results,
+
535  uint16_t offset = kStartOffset,
+
536  const uint16_t nbits = kHaierACYRW02Bits,
+
537  const bool strict = true);
+
538 #endif
+
539 #if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC344)
+
540  bool decodeHitachiAC(decode_results *results, uint16_t offset = kStartOffset,
+
541  const uint16_t nbits = kHitachiAcBits,
+
542  const bool strict = true, const bool MSBfirst = true);
+
543 #endif
+
544 #if DECODE_HITACHI_AC1
+
545  bool decodeHitachiAC1(decode_results *results, uint16_t offset = kStartOffset,
+
546  const uint16_t nbits = kHitachiAc1Bits,
+
547  const bool strict = true);
+
548 #endif
+
549 #if DECODE_HITACHI_AC3
+
550  bool decodeHitachiAc3(decode_results *results,
+
551  uint16_t offset = kStartOffset,
+
552  const uint16_t nbits = kHitachiAc3Bits,
+
553  const bool strict = true);
+
554 #endif // DECODE_HITACHI_AC3
+
555 #if DECODE_HITACHI_AC424
+
556  bool decodeHitachiAc424(decode_results *results,
+
557  uint16_t offset = kStartOffset,
+
558  const uint16_t nbits = kHitachiAc424Bits,
+
559  const bool strict = true);
+
560 #endif // DECODE_HITACHI_AC424
+
561 #if DECODE_GICABLE
+
562  bool decodeGICable(decode_results *results, uint16_t offset = kStartOffset,
+
563  const uint16_t nbits = kGicableBits,
+
564  const bool strict = true);
+
565 #endif
+
566 #if DECODE_WHIRLPOOL_AC
+
567  bool decodeWhirlpoolAC(decode_results *results,
+
568  uint16_t offset = kStartOffset,
+
569  const uint16_t nbits = kWhirlpoolAcBits,
+
570  const bool strict = true);
+
571 #endif
+
572 #if DECODE_LUTRON
+
573  bool decodeLutron(decode_results *results, uint16_t offset = kStartOffset,
+
574  const uint16_t nbits = kLutronBits,
+
575  const bool strict = true);
+
576 #endif
+
577 #if DECODE_ELECTRA_AC
+
578  bool decodeElectraAC(decode_results *results, uint16_t offset = kStartOffset,
+
579  const uint16_t nbits = kElectraAcBits,
+
580  const bool strict = true);
+
581 #endif
+
582 #if DECODE_PANASONIC_AC
+
583  bool decodePanasonicAC(decode_results *results,
+
584  uint16_t offset = kStartOffset,
+
585  const uint16_t nbits = kPanasonicAcBits,
+
586  const bool strict = true);
+
587 #endif
+
588 #if DECODE_PIONEER
+
589  bool decodePioneer(decode_results *results, uint16_t offset = kStartOffset,
+
590  const uint16_t nbits = kPioneerBits,
+
591  const bool strict = true);
+
592 #endif
+
593 #if DECODE_MWM
+
594  bool decodeMWM(decode_results *results, uint16_t offset = kStartOffset,
+
595  const uint16_t nbits = 24,
+
596  const bool strict = true);
+
597 #endif
+
598 #if DECODE_VESTEL_AC
+
599  bool decodeVestelAc(decode_results *results, uint16_t offset = kStartOffset,
+
600  const uint16_t nbits = kVestelAcBits,
+
601  const bool strict = true);
+
602 #endif
+
603 #if DECODE_TECO
+
604  bool decodeTeco(decode_results *results, uint16_t offset = kStartOffset,
+
605  const uint16_t nbits = kTecoBits,
+
606  const bool strict = false);
+
607 #endif
+
608 #if DECODE_LEGOPF
+
609  bool decodeLegoPf(decode_results *results, uint16_t offset = kStartOffset,
+
610  const uint16_t nbits = kLegoPfBits,
+
611  const bool strict = true);
+
612 #endif
+
613 #if DECODE_NEOCLIMA
+
614  bool decodeNeoclima(decode_results *results, uint16_t offset = kStartOffset,
+
615  const uint16_t nbits = kNeoclimaBits,
+
616  const bool strict = true);
+
617 #endif // DECODE_NEOCLIMA
+
618 #if DECODE_AMCOR
+
619  bool decodeAmcor(decode_results *results, uint16_t offset = kStartOffset,
+
620  const uint16_t nbits = kAmcorBits,
+
621  const bool strict = true);
+
622 #endif // DECODE_AMCOR
+
623 #if DECODE_EPSON
+
624  bool decodeEpson(decode_results *results, uint16_t offset = kStartOffset,
+
625  const uint16_t nbits = kEpsonBits,
+
626  const bool strict = true);
+
627 #endif // DECODE_EPSON
+
628 #if DECODE_SYMPHONY
+
629  bool decodeSymphony(decode_results *results, uint16_t offset = kStartOffset,
+
630  const uint16_t nbits = kSymphonyBits,
+
631  const bool strict = true);
+
632 #endif // DECODE_SYMPHONY
+
633 #if DECODE_AIRWELL
+
634  bool decodeAirwell(decode_results *results, uint16_t offset = kStartOffset,
+
635  const uint16_t nbits = kAirwellBits,
+
636  const bool strict = true);
+
637 #endif // DECODE_AIRWELL
+
638 #if DECODE_DELONGHI_AC
+
639  bool decodeDelonghiAc(decode_results *results, uint16_t offset = kStartOffset,
+
640  const uint16_t nbits = kDelonghiAcBits,
+
641  const bool strict = true);
+
642 #endif // DECODE_DELONGHI_AC
+
643 #if DECODE_DOSHISHA
+
644  bool decodeDoshisha(decode_results *results, uint16_t offset = kStartOffset,
+
645  const uint16_t nbits = kDoshishaBits,
+
646  const bool strict = true);
+
647 #endif // DECODE_DOSHISHA
+
648 #if DECODE_MULTIBRACKETS
+
649  bool decodeMultibrackets(decode_results *results,
+
650  uint16_t offset = kStartOffset,
+
651  const uint16_t nbits = kMultibracketsBits,
+
652  const bool strict = true);
+
653 #endif // DECODE_MULTIBRACKETS
+
654 #if DECODE_CORONA_AC
+
655  bool decodeCoronaAc(decode_results *results, uint16_t offset = kStartOffset,
+
656  const uint16_t nbits = kCoronaAcBitsShort,
+
657  const bool strict = true);
+
658 #endif // DECODE_CORONA_AC
+
659 #if DECODE_ZEPEAL
+
660 bool decodeZepeal(decode_results *results, uint16_t offset = kStartOffset,
+
661  const uint16_t nbits = kZepealBits,
+
662  const bool strict = true);
+
663 #endif // DECODE_ZEPEAL
+
664 };
+
665 
+
666 #endif // IRRECV_H_
+
+
bool decodeMultibrackets(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMultibracketsBits, const bool strict=true)
Decode the Multibrackets message. Status: BETA / Appears to be working.
Definition: ir_Multibrackets.cpp:59
+
const uint16_t kDelonghiAcBits
Definition: IRremoteESP8266.h:861
+
bool decodeMitsubishi(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)
Decode the supplied Mitsubishi 16-bit message. Status: STABLE / Working.
Definition: ir_Mitsubishi.cpp:123
+
bool decodeHaierAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACBits, const bool strict=true)
Decode the supplied Haier HSU07-HEA03 remote message. Status: STABLE / Known to be working.
Definition: ir_Haier.cpp:993
+
bool decodeNEC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNECBits, const bool strict=true)
Decode the supplied NEC (Renesas) message. Status: STABLE / Known good.
Definition: ir_NEC.cpp:81
+
const uint32_t kFnvPrime32
Definition: IRrecv.h:52
+
bool overflow
Definition: IRrecv.h:109
+
bool decodeDaikin128(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin128Bits, const bool strict=true)
Decode the supplied Daikin 128-bit message. (DAIKIN128) Status: STABLE / Known Working.
Definition: ir_Daikin.cpp:3109
+
const uint16_t kGicableBits
Definition: IRremoteESP8266.h:879
+
uint16_t matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode a generic/typical <= 64bit IR message. The data is stored at result_ptr.
Definition: IRrecv.cpp:1268
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
const uint16_t kCarrierAcBits
Definition: IRremoteESP8266.h:826
+
int16_t getRClevel(decode_results *results, uint16_t *offset, uint16_t *used, uint16_t bitTime, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const uint16_t delta=0, const uint8_t maxwidth=3)
Gets one undecoded level at a time from the raw buffer. The RC5/6 decoding is easier if the data is b...
Definition: ir_RC5_RC6.cpp:243
+
const uint16_t kMultibracketsBits
Definition: IRremoteESP8266.h:945
+
const uint16_t kSharpAcBits
Definition: IRremoteESP8266.h:983
+
const uint16_t kWhynterBits
Definition: IRremoteESP8266.h:1008
+
uint8_t overflow
Definition: IRrecv.h:78
+
bool decodeMitsubishi2(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)
Decode the supplied second variation of a Mitsubishi 16-bit message. Status: STABLE / Working.
Definition: ir_Mitsubishi.cpp:188
+
bool decodeGree(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGreeBits, const bool strict=true)
Decode the supplied Gree HVAC message. Status: STABLE / Working.
Definition: ir_Gree.cpp:673
+
const uint16_t kAirwellBits
Definition: IRremoteESP8266.h:813
+
irparams_t * irparams_save
Definition: IRrecv.h:151
+
const uint16_t kMitsubishiACBits
Definition: IRremoteESP8266.h:931
+
bool decodeFujitsuAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kFujitsuAcBits, const bool strict=false)
Decode the supplied Fujitsu AC IR message if possible. Status: STABLE / Working.
Definition: ir_Fujitsu.cpp:745
+
bool decodeTrotec(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTrotecBits, const bool strict=true)
Decode the supplied Trotec message. Status: STABLE / Works. Untested on real devices.
Definition: ir_Trotec.cpp:313
+
bool decodeNeoclima(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNeoclimaBits, const bool strict=true)
Decode the supplied Neoclima message. Status: STABLE / Known working.
Definition: ir_Neoclima.cpp:548
+
bool decodeMitsubishi112(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi112Bits, const bool strict=true)
Decode the supplied Mitsubishi/TCL 112-bit A/C message. (MITSUBISHI112, TCL112AC) Status: STABLE / Re...
Definition: ir_Mitsubishi.cpp:1216
+
bool decodeSamsungAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungAcBits, const bool strict=true)
Decode the supplied Samsung A/C message. Status: Stable / Known to be working.
Definition: ir_Samsung.cpp:781
+
bool decodeAirwell(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAirwellBits, const bool strict=true)
Decode the supplied Airwell "Manchester code" message.
Definition: ir_Airwell.cpp:50
+
const uint16_t kRC5XBits
Definition: IRremoteESP8266.h:963
+
bool decodeMagiQuest(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMagiquestBits, const bool strict=true)
Decode the supplied MagiQuest message. Status: Beta / Should work.
Definition: ir_Magiquest.cpp:69
+
uint16_t rawlen
Definition: IRrecv.h:77
+
const uint8_t kUseDefTol
Definition: IRrecv.h:36
+
bool decodeDelonghiAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDelonghiAcBits, const bool strict=true)
Decode the supplied Delonghi A/C message. Status: STABLE / Expected to be working.
Definition: ir_Delonghi.cpp:60
+
Class for receiving IR messages.
Definition: IRrecv.h:114
+
uint16_t bufsize
Definition: IRrecv.h:73
+
Results returned from the decoder.
Definition: IRrecv.h:92
+
uint16_t matchGenericConstBitTime(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t one, const uint32_t zero, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode a generic/typical constant bit time <= 64bit IR message. The data is stored at result_...
Definition: IRrecv.cpp:1362
+
bool decodeCarrierAC64(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc64Bits, const bool strict=true)
Decode the supplied Carrier 64-bit HVAC message. Status: STABLE / Known to be working.
Definition: ir_Carrier.cpp:197
+
const uint16_t kCoolixBits
Definition: IRremoteESP8266.h:824
+
bool decodeArgo(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kArgoBits, const bool strict=true)
Decode the supplied Argo message. Status: BETA / Probably works.
Definition: ir_Argo.cpp:459
+
const uint16_t kCoronaAcBitsShort
Definition: IRremoteESP8266.h:834
+
uint64_t data
Definition: IRrecv.h:85
+
const uint16_t kSamsung36Bits
Definition: IRremoteESP8266.h:968
+
const uint16_t kMagiquestBits
Definition: IRremoteESP8266.h:921
+
uint16_t * rawbuf
Definition: IRrecv.h:74
+
Information for the interrupt handler.
Definition: IRrecv.h:69
+
uint16_t getBufSize(void)
Obtain the maximum number of entries possible in the capture buffer. i.e. It's size.
Definition: IRrecv.cpp:319
+
const uint16_t kSanyoLC7461Bits
Definition: IRremoteESP8266.h:977
+
bool decodeToshibaAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbytes=kToshibaACBits, const bool strict=true)
Decode the supplied Toshiba A/C message. Status: STABLE / Working.
Definition: ir_Toshiba.cpp:322
+
bool repeat
Definition: IRrecv.h:110
+
bool decodeHitachiAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAcBits, const bool strict=true, const bool MSBfirst=true)
Decode the supplied Hitachi A/C message. Status: STABLE / Expected to work.
Definition: ir_Hitachi.cpp:868
+
const uint16_t kTrotecBits
Definition: IRremoteESP8266.h:1003
+
bool decodeVestelAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kVestelAcBits, const bool strict=true)
Decode the supplied Vestel message. Status: Alpha / Needs testing against a real device.
Definition: ir_Vestel.cpp:572
+
const uint8_t kIdleState
Definition: IRrecv.h:31
+
bool decodeAmcor(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAmcorBits, const bool strict=true)
Decode the supplied Amcor HVAC message. Status: STABLE / Reported as working.
Definition: ir_Amcor.cpp:59
+
bool decodeDaikin(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikinBits, const bool strict=true)
Decode the supplied Daikin 280-bit message. (DAIKIN) Status: STABLE / Reported as working.
Definition: ir_Daikin.cpp:619
+
uint8_t recvpin
Definition: IRrecv.h:70
+
uint16_t timer
Definition: IRrecv.h:72
+
bool decodeDaikin64(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin64Bits, const bool strict=true)
Decode the supplied Daikin 64-bit message. (DAIKIN64) Status: Beta / Probably Working.
Definition: ir_Daikin.cpp:3591
+
bool success
Definition: IRrecv.h:84
+
bool decodeDaikin2(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin2Bits, const bool strict=true)
Decode the supplied Daikin 312-bit message. (DAIKIN2) Status: STABLE / Works as expected.
Definition: ir_Daikin.cpp:1415
+
const uint16_t kElectraAcBits
Definition: IRremoteESP8266.h:872
+
bool matchSpace(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)
Check if we match a space signal(measured) with the desired within +/-tolerance percent,...
Definition: IRrecv.cpp:1000
+
const uint16_t kSonyMinBits
Definition: IRremoteESP8266.h:990
+
const uint8_t kStopState
Definition: IRrecv.h:34
+
uint16_t rawlen
Definition: IRrecv.h:108
+
const uint16_t kMaxTimeoutMs
Definition: IRrecv.h:49
+
const uint16_t kDaikin2Bits
Definition: IRremoteESP8266.h:842
+
bool decodePanasonic(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicBits, const bool strict=false, const uint32_t manufacturer=kPanasonicManufacturer)
Decode the supplied Panasonic message. Status: STABLE / Should be working.
Definition: ir_Panasonic.cpp:130
+
const uint16_t kHitachiAc1Bits
Definition: IRremoteESP8266.h:896
+
bool decodeElectraAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kElectraAcBits, const bool strict=true)
Decode the supplied Electra A/C message. Status: STABLE / Known working.
Definition: ir_Electra.cpp:377
+
bool decodeDaikin216(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin216Bits, const bool strict=true)
Decode the supplied Daikin 216-bit message. (DAIKIN216) Status: STABLE / Should be working.
Definition: ir_Daikin.cpp:1789
+
bool decodeDaikin152(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin152Bits, const bool strict=true)
Decode the supplied Daikin 152-bit message. (DAIKIN152) Status: STABLE / Known Working.
Definition: ir_Daikin.cpp:3198
+
bool decodeDenon(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDenonBits, const bool strict=true)
Decode the supplied Delonghi A/C message. Status: STABLE / Should work fine.
Definition: ir_Denon.cpp:70
+
const uint16_t kPanasonicBits
Definition: IRremoteESP8266.h:952
+
bool decodeSanyoLC7461(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSanyoLC7461Bits, bool strict=true)
Decode the supplied SANYO LC7461 message. Status: BETA / Probably works.
Definition: ir_Sanyo.cpp:117
+
decode_type_t decode_type
Definition: IRrecv.h:94
+
const uint16_t kPanasonicAcBits
Definition: IRremoteESP8266.h:956
+
const uint64_t kRepeat
Definition: IRrecv.h:26
+
void setTolerance(const uint8_t percent=kTolerance)
Set the base tolerance percentage for matching incoming IR messages.
Definition: IRrecv.cpp:332
+
bool decodeMidea(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMideaBits, const bool strict=true)
Decode the supplied Midea message. Status: Alpha / Needs testing against a real device.
Definition: ir_Midea.cpp:415
+
const uint16_t kDaikin160Bits
Definition: IRremoteESP8266.h:847
+
void copyIrParams(volatile irparams_t *src, irparams_t *dst)
Make a copy of the interrupt state & buffer data. Needed because irparams is marked as volatile,...
Definition: IRrecv.cpp:295
+
bool decodeKelvinator(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kKelvinatorBits, const bool strict=true)
Decode the supplied Kelvinator message. Status: STABLE / Known working.
Definition: ir_Kelvinator.cpp:489
+
const uint16_t kGoodweatherBits
Definition: IRremoteESP8266.h:881
+
bool decodeMWM(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=24, const bool strict=true)
Decode the supplied MWM message. Status: Implemented.
Definition: ir_MWM.cpp:81
+
void enableIRIn(const bool pullup=false)
Set up and (re)start the IR capture mechanism.
Definition: IRrecv.cpp:228
+
const uint16_t kDaikin152Bits
Definition: IRremoteESP8266.h:853
+
bool decodePanasonicAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicAcBits, const bool strict=true)
Decode the supplied Panasonic AC message. Status: STABLE / Works with real device(s).
Definition: ir_Panasonic.cpp:879
+
bool decodeDoshisha(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDoshishaBits, const bool strict=true)
Decode the supplied Doshisha message. Status: STABLE / Works on real device.
Definition: ir_Doshisha.cpp:85
+
bool decodeZepeal(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kZepealBits, const bool strict=true)
Decode the supplied Zepeal message. Status: STABLE / Works on real device.
Definition: ir_Zepeal.cpp:67
+
bool decodeDaikin160(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin160Bits, const bool strict=true)
Decode the supplied Daikin 160-bit message. (DAIKIN160) Status: STABLE / Confirmed working.
Definition: ir_Daikin.cpp:2162
+
bool decodeLasertag(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLasertagBits, const bool strict=true)
Decode the supplied Lasertag message. Status: BETA / Appears to be working 90% of the time.
Definition: ir_Lasertag.cpp:70
+ +
const uint8_t kTimeoutMs
Definition: IRrecv.h:47
+
uint16_t _matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_ptr, const bool use_bits, const uint16_t remaining, const uint16_t required, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode a generic/typical IR message. The data is stored in result_bits_ptr or result_bytes_pt...
Definition: IRrecv.cpp:1168
+
const uint8_t kMarkState
Definition: IRrecv.h:32
+
void setUnknownThreshold(const uint16_t length)
Set the minimum length we will consider for reporting UNKNOWN message types.
Definition: IRrecv.cpp:324
+
const uint16_t kSymphonyBits
Definition: IRremoteESP8266.h:992
+
const uint16_t kRC6Mode0Bits
Definition: IRremoteESP8266.h:964
+
const uint16_t kStateSizeMax
Definition: IRrecv.h:60
+
Results from a data match.
Definition: IRrecv.h:83
+
uint8_t rcvstate
Definition: IRrecv.h:71
+
bool decodeRC6(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC6Mode0Bits, const bool strict=false)
Decode the supplied RC6 message. Status: Stable.
Definition: ir_RC5_RC6.cpp:383
+
bool decodeRC5(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC5XBits, const bool strict=true)
Decode the supplied RC-5/RC5X message. Status: RC-5 (stable), RC-5X (alpha)
Definition: ir_RC5_RC6.cpp:309
+
~IRrecv(void)
Class destructor Cleans up after the object is no longer needed. e.g. Frees up all memory used by the...
Definition: IRrecv.cpp:213
+
bool decodeHitachiAc3(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc3Bits, const bool strict=true)
Decode the supplied Hitachi 15to27-byte/120to216-bit A/C message. Status: STABLE / Works fine.
Definition: ir_Hitachi.cpp:1456
+
bool decodeWhynter(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhynterBits, const bool strict=true)
Decode the supplied Whynter message. Status: STABLE / Working. Strict mode is ALPHA.
Definition: ir_Whynter.cpp:74
+
bool decodeCarrierAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAcBits, const bool strict=true)
Decode the supplied Carrier HVAC message.
Definition: ir_Carrier.cpp:84
+
match_result_t matchData(volatile uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode the typical data section of an IR message. The data value is stored in the least signi...
Definition: IRrecv.cpp:1076
+
const uint16_t kMitsubishiHeavy152Bits
Definition: IRremoteESP8266.h:943
+
const uint16_t kDoshishaBits
Definition: IRremoteESP8266.h:868
+
const uint16_t kCarrierAc40Bits
Definition: IRremoteESP8266.h:828
+
const uint16_t kStartOffset
Definition: IRrecv.h:20
+
const uint16_t kAmcorBits
Definition: IRremoteESP8266.h:819
+
bool decodeRCMM(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRCMMBits, const bool strict=false)
Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. Status: STABLE / Should be working.
Definition: ir_RCMM.cpp:96
+
IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)
Class constructor Args:
Definition: IRrecv.cpp:152
+
bool decodeMitsubishi136(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi136Bits, const bool strict=true)
Decode the supplied Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: STABLE / Reported as work...
Definition: ir_Mitsubishi.cpp:835
+
volatile uint16_t * rawbuf
Definition: IRrecv.h:107
+
const uint8_t kTolerance
Definition: IRrecv.h:35
+
bool decodeSharp(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpBits, const bool strict=true, const bool expansion=true)
Decode the supplied Sharp message. Status: STABLE / Working fine.
Definition: ir_Sharp.cpp:156
+
uint16_t used
Definition: IRrecv.h:86
+
const uint32_t kPanasonicManufacturer
Definition: IRremoteESP8266.h:953
+
uint32_t address
Definition: IRrecv.h:101
+
bool decodeNikai(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNikaiBits, const bool strict=true)
Decode the supplied Nikai message. Status: STABLE / Working.
Definition: ir_Nikai.cpp:52
+
const uint16_t kMitsubishiBits
Definition: IRremoteESP8266.h:926
+
bool match(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
Check if we match a pulse(measured) with the desired within +/-tolerance percent and/or +/- a fixed d...
Definition: IRrecv.cpp:908
+
bool decodeSymphony(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSymphonyBits, const bool strict=true)
Decode the supplied Symphony packet/message. Status: STABLE / Should be working.
Definition: ir_Symphony.cpp:60
+
const uint16_t kSamsungAcBits
Definition: IRremoteESP8266.h:970
+
const uint16_t kUnknownThreshold
Definition: IRrecv.h:28
+
const uint16_t kMideaBits
Definition: IRremoteESP8266.h:922
+
bool decodeAiwaRCT501(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAiwaRcT501Bits, const bool strict=true)
Decode the supplied Aiwa RC T501 message. Status: BETA / Should work.
Definition: ir_Aiwa.cpp:61
+
const uint16_t kKelvinatorBits
Definition: IRremoteESP8266.h:911
+
bool decodeGICable(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGicableBits, const bool strict=true)
Decode the supplied G.I. Cable message. Status: Alpha / Not tested against a real device.
Definition: ir_GICable.cpp:63
+
bool decodeTeco(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTecoBits, const bool strict=false)
Decode the supplied Teco message. Status: STABLE / Tested.
Definition: ir_Teco.cpp:365
+
bool decodeCarrierAC40(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc40Bits, const bool strict=true)
Decode the supplied Carrier 40-bit HVAC message. Carrier HVAC messages contain only 40 bits,...
Definition: ir_Carrier.cpp:149
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint16_t kDenonBits
Definition: IRremoteESP8266.h:863
+
const uint16_t kHaierACBits
Definition: IRremoteESP8266.h:887
+
bool matchAtLeast(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
Check if we match a pulse(measured) of at least desired within tolerance percent and/or a fixed delta...
Definition: IRrecv.cpp:939
+
const uint16_t kZepealBits
Definition: IRremoteESP8266.h:1010
+
const uint16_t kMidea24Bits
Definition: IRremoteESP8266.h:924
+
bool decodeDaikin176(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin176Bits, const bool strict=true)
Decode the supplied Daikin 176-bit message. (DAIKIN176) Status: STABLE / Expected to work.
Definition: ir_Daikin.cpp:2553
+
const uint16_t kNeoclimaBits
Definition: IRremoteESP8266.h:950
+
const uint16_t kWhirlpoolAcBits
Definition: IRremoteESP8266.h:1006
+
bool decodeSharpAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpAcBits, const bool strict=true)
Decode the supplied Sharp A/C message. Status: STABLE / Known working.
Definition: ir_Sharp.cpp:723
+
bool decodeJVC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kJvcBits, const bool strict=true)
Decode the supplied JVC message. Status: Stable / Known working.
Definition: ir_JVC.cpp:94
+
bool decodeMitsubishiAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiACBits, const bool strict=false)
Decode the supplied Mitsubish 144-bit A/C message. Status: BETA / Probably works.
Definition: ir_Mitsubishi.cpp:254
+
const uint16_t kCarrierAc64Bits
Definition: IRremoteESP8266.h:830
+
const uint16_t kPioneerBits
Definition: IRremoteESP8266.h:959
+
uint16_t bits
Definition: IRrecv.h:106
+
const uint16_t kGreeBits
Definition: IRremoteESP8266.h:884
+
const uint16_t kJvcBits
Definition: IRremoteESP8266.h:909
+
const uint16_t kLasertagBits
Definition: IRremoteESP8266.h:913
+
const uint16_t kDaikin128Bits
Definition: IRremoteESP8266.h:850
+
const uint16_t kAiwaRcT501Bits
Definition: IRremoteESP8266.h:815
+
uint32_t ticksLow(const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
Calculate the lower bound of the nr. of ticks.
Definition: IRrecv.cpp:882
+
const uint16_t kTecoBits
Definition: IRremoteESP8266.h:997
+
bool decodeEpson(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kEpsonBits, const bool strict=true)
Decode the supplied Epson message. Status: Beta / Probably works.
Definition: ir_Epson.cpp:45
+
const uint16_t kToshibaACBits
Definition: IRremoteESP8266.h:1000
+
bool decodeSony(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSonyMinBits, const bool strict=false)
Decode the supplied Sony/SIRC message. Status: STABLE / Should be working. strict mode is ALPHA / Unt...
Definition: ir_Sony.cpp:121
+
const uint16_t kDaikinBits
Definition: IRremoteESP8266.h:837
+
bool matchMark(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)
Check if we match a mark signal(measured) with the desired within +/-tolerance percent,...
Definition: IRrecv.cpp:981
+
const uint16_t kHitachiAcBits
Definition: IRremoteESP8266.h:893
+
const uint16_t kHitachiAc3Bits
Definition: IRremoteESP8266.h:900
+
const uint16_t kRawBuf
Definition: IRrecv.h:25
+
bool decode(decode_results *results, irparams_t *save=NULL, uint8_t max_skip=0, uint16_t noise_floor=0)
Decodes the received IR message. If the interrupt state is saved, we will immediately resume waiting ...
Definition: IRrecv.cpp:409
+
bool decodePioneer(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPioneerBits, const bool strict=true)
Decode the supplied Pioneer message. Status: STABLE / Should be working. (Self decodes & real example...
Definition: ir_Pioneer.cpp:96
+
uint8_t getTolerance(void)
Get the base tolerance percentage for matching incoming IR messages.
Definition: IRrecv.cpp:338
+
const uint16_t kDishBits
Definition: IRremoteESP8266.h:866
+
uint16_t compare(const uint16_t oldval, const uint16_t newval)
Compare two tick values.
Definition: IRrecv.cpp:1018
+
uint32_t command
Definition: IRrecv.h:102
+
const uint16_t kFujitsuAcBits
Definition: IRremoteESP8266.h:877
+
uint64_t value
Definition: IRrecv.h:100
+
const uint16_t kArgoBits
Definition: IRremoteESP8266.h:822
+
const uint16_t kHitachiAc2StateLength
Definition: IRremoteESP8266.h:897
+
bool decodeSamsung36(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsung36Bits, const bool strict=true)
Decode the supplied Samsung36 message. Status: Alpha / Experimental.
Definition: ir_Samsung.cpp:186
+
const uint16_t kFooter
Definition: IRrecv.h:19
+
const uint16_t kNikaiBits
Definition: IRremoteESP8266.h:947
+
const uint16_t kLutronBits
Definition: IRremoteESP8266.h:920
+
uint8_t timeout
Definition: IRrecv.h:79
+
bool decodeCoronaAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoronaAcBitsShort, const bool strict=true)
Decode the supplied CoronaAc message. Status: STABLE / Appears to be working.
Definition: ir_Corona.cpp:89
+
bool decodeLutron(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLutronBits, const bool strict=true)
Decode the supplied Lutron message. Status: STABLE / Working.
Definition: ir_Lutron.cpp:65
+
bool decodeDISH(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDishBits, const bool strict=true)
Decode the supplied DISH NETWORK message. Status: ALPHA (untested and unconfirmed....
Definition: ir_Dish.cpp:77
+
const uint16_t kRawTick
Definition: IRrecv.h:37
+
uint16_t matchManchesterData(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t half_period, const uint16_t starting_balance=0, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
Match & decode a Manchester Code data (<= 64bits.
Definition: IRrecv.cpp:1556
+
void resume(void)
Resume collection of received IR data.
Definition: IRrecv.cpp:280
+
const uint16_t kHaierACYRW02Bits
Definition: IRremoteESP8266.h:890
+
const uint16_t kHitachiAc424Bits
Definition: IRremoteESP8266.h:906
+
bool decodeWhirlpoolAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhirlpoolAcBits, const bool strict=true)
Decode the supplied Whirlpool A/C message. Status: STABLE / Working as intended.
Definition: ir_Whirlpool.cpp:642
+
const uint16_t kMarkExcess
Definition: IRrecv.h:24
+
bool decodeHaierACYRW02(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACYRW02Bits, const bool strict=true)
Decode the supplied Haier YR-W02 remote A/C message. Status: BETA / Appears to be working.
Definition: ir_Haier.cpp:1039
+
bool decodeLG(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLgBits, const bool strict=false)
Decode the supplied LG message. Status: STABLE / Working.
Definition: ir_LG.cpp:154
+
bool decodeCOOLIX(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoolixBits, const bool strict=true)
Decode the supplied Coolix A/C message. Status: STABLE / Known Working.
Definition: ir_Coolix.cpp:650
+
const uint16_t kLegoPfBits
Definition: IRremoteESP8266.h:915
+
const uint16_t kSharpBits
Definition: IRremoteESP8266.h:981
+
bool decodeGoodweather(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGoodweatherBits, const bool strict=true)
Decode the supplied Goodweather message. Status: BETA / Probably works.
Definition: ir_Goodweather.cpp:429
+
uint8_t _tolerance
Definition: IRrecv.h:152
+
const uint8_t kDefaultESP32Timer
Definition: IRrecv.h:56
+
uint16_t matchManchester(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t clock_period, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
Match & decode a Manchester Code <= 64bit IR message. The data is stored at result_ptr.
Definition: IRrecv.cpp:1449
+
bool decodeInax(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kInaxBits, const bool strict=true)
Decode the supplied Inax Toilet message. Status: Stable / Known working.
Definition: ir_Inax.cpp:51
+
void crudeNoiseFilter(decode_results *results, const uint16_t floor=0)
Remove or merge pulses in the capture buffer that are too short.
Definition: IRrecv.cpp:345
+
bool decodeHitachiAC1(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc1Bits, const bool strict=true)
+
bool decodeSAMSUNG(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungBits, const bool strict=true)
Decode the supplied Samsung 32-bit message. Status: STABLE.
Definition: ir_Samsung.cpp:112
+
bool decodeLegoPf(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLegoPfBits, const bool strict=true)
Decode the supplied LEGO Power Functions message. Status: STABLE / Appears to work.
Definition: ir_Lego.cpp:71
+
const uint16_t kRCMMBits
Definition: IRremoteESP8266.h:966
+
const uint8_t kVestelAcBits
Definition: IRremoteESP8266.h:1009
+
const uint16_t kInaxBits
Definition: IRremoteESP8266.h:907
+
bool decodeMitsubishiHeavy(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiHeavy152Bits, const bool strict=true)
Decode the supplied Mitsubishi Heavy Industries A/C message. Status: BETA / Appears to be working....
Definition: ir_MitsubishiHeavy.cpp:1121
+
uint16_t _unknown_threshold
Definition: IRrecv.h:157
+
const uint16_t kDaikin176Bits
Definition: IRremoteESP8266.h:856
+
bool decodeMidea24(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMidea24Bits, const bool strict=true)
Decode the supplied Midea24 message. Status: STABLE / Confirmed working on a real device.
Definition: ir_Midea.cpp:506
+
void disableIRIn(void)
Stop collection of any received IR data. Disable any timers and interrupts.
Definition: IRrecv.cpp:264
+
bool decodeHitachiAc424(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc424Bits, const bool strict=true)
Decode the supplied Hitachi 53-byte/424-bit A/C message. Status: STABLE / Reported as working.
Definition: ir_Hitachi.cpp:981
+
uint32_t ticksHigh(const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
Calculate the upper bound of the nr. of ticks.
Definition: IRrecv.cpp:895
+
const uint16_t kSamsungBits
Definition: IRremoteESP8266.h:967
+
uint8_t _timer_num
Definition: IRrecv.h:154
+
const uint16_t kDaikin64Bits
Definition: IRremoteESP8266.h:844
+
const uint16_t kDaikin216Bits
Definition: IRremoteESP8266.h:859
+
const uint16_t kMitsubishi136Bits
Definition: IRremoteESP8266.h:934
+
uint16_t matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode the typical data section of an IR message. The bytes are stored at result_ptr....
Definition: IRrecv.cpp:1118
+
const uint16_t kMitsubishi112Bits
Definition: IRremoteESP8266.h:937
+
const uint16_t kEpsonBits
Definition: IRremoteESP8266.h:869
+
uint8_t state[kStateSizeMax]
Definition: IRrecv.h:104
+
bool decodeHash(decode_results *results)
Decode any arbitrary IR message into a 32-bit code value. Instead of decoding using a standard encodi...
Definition: IRrecv.cpp:1039
+
const uint8_t kSpaceState
Definition: IRrecv.h:33
+
const uint16_t kLgBits
Definition: IRremoteESP8266.h:917
+
uint8_t _validTolerance(const uint8_t percentage)
Convert the tolerance percentage into something valid.
Definition: IRrecv.cpp:873
+
const uint16_t kHeader
Definition: IRrecv.h:18
+
const uint32_t kFnvBasis32
Definition: IRrecv.h:53
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h.html new file mode 100644 index 000000000..a8a3d1f05 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h.html @@ -0,0 +1,3515 @@ + + + + + + + +IRremoteESP8266: src/IRremoteESP8266.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRremoteESP8266.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + +

+Typedefs

typedef std::string String
 
+ + + + +

+Enumerations

enum  decode_type_t {
+  UNKNOWN = -1, +UNUSED = 0, +RC5, +RC6, +
+  NEC, +SONY, +PANASONIC, +JVC, +
+  SAMSUNG, +WHYNTER, +AIWA_RC_T501, +LG, +
+  SANYO, +MITSUBISHI, +DISH, +SHARP, +
+  COOLIX, +DAIKIN, +DENON, +KELVINATOR, +
+  SHERWOOD, +MITSUBISHI_AC, +RCMM, +SANYO_LC7461, +
+  RC5X, +GREE, +PRONTO, +NEC_LIKE, +
+  ARGO, +TROTEC, +NIKAI, +RAW, +
+  GLOBALCACHE, +TOSHIBA_AC, +FUJITSU_AC, +MIDEA, +
+  MAGIQUEST, +LASERTAG, +CARRIER_AC, +HAIER_AC, +
+  MITSUBISHI2, +HITACHI_AC, +HITACHI_AC1, +HITACHI_AC2, +
+  GICABLE, +HAIER_AC_YRW02, +WHIRLPOOL_AC, +SAMSUNG_AC, +
+  LUTRON, +ELECTRA_AC, +PANASONIC_AC, +PIONEER, +
+  LG2, +MWM, +DAIKIN2, +VESTEL_AC, +
+  TECO, +SAMSUNG36, +TCL112AC, +LEGOPF, +
+  MITSUBISHI_HEAVY_88, +MITSUBISHI_HEAVY_152, +DAIKIN216, +SHARP_AC, +
+  GOODWEATHER, +INAX, +DAIKIN160, +NEOCLIMA, +
+  DAIKIN176, +DAIKIN128, +AMCOR, +DAIKIN152, +
+  MITSUBISHI136, +MITSUBISHI112, +HITACHI_AC424, +SONY_38K, +
+  EPSON, +SYMPHONY, +HITACHI_AC3, +DAIKIN64, +
+  AIRWELL, +DELONGHI_AC, +DOSHISHA, +MULTIBRACKETS, +
+  CARRIER_AC40, +CARRIER_AC64, +HITACHI_AC344, +CORONA_AC, +
+  MIDEA24, +ZEPEAL, +kLastDecodeType = ZEPEAL +
+ }
 Enumerator for defining and numbering of supported IR protocol. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kNoRepeat = 0
 
const uint16_t kSingleRepeat = 1
 
const uint16_t kAirwellBits = 34
 
const uint16_t kAirwellMinRepeats = 2
 
const uint16_t kAiwaRcT501Bits = 15
 
const uint16_t kAiwaRcT501MinRepeats = kSingleRepeat
 
const uint16_t kAlokaBits = 32
 
const uint16_t kAmcorStateLength = 8
 
const uint16_t kAmcorBits = kAmcorStateLength * 8
 
const uint16_t kAmcorDefaultRepeat = kSingleRepeat
 
const uint16_t kArgoStateLength = 12
 
const uint16_t kArgoBits = kArgoStateLength * 8
 
const uint16_t kArgoDefaultRepeat = kNoRepeat
 
const uint16_t kCoolixBits = 24
 
const uint16_t kCoolixDefaultRepeat = kSingleRepeat
 
const uint16_t kCarrierAcBits = 32
 
const uint16_t kCarrierAcMinRepeat = kNoRepeat
 
const uint16_t kCarrierAc40Bits = 40
 
const uint16_t kCarrierAc40MinRepeat = 2
 
const uint16_t kCarrierAc64Bits = 64
 
const uint16_t kCarrierAc64MinRepeat = kNoRepeat
 
const uint16_t kCoronaAcStateLengthShort = 7
 
const uint16_t kCoronaAcStateLength = kCoronaAcStateLengthShort * 3
 
const uint16_t kCoronaAcBitsShort = kCoronaAcStateLengthShort * 8
 
const uint16_t kCoronaAcBits = kCoronaAcStateLength * 8
 
const uint16_t kDaikinStateLength = 35
 
const uint16_t kDaikinBits = kDaikinStateLength * 8
 
const uint16_t kDaikinStateLengthShort = kDaikinStateLength - 8
 
const uint16_t kDaikinBitsShort = kDaikinStateLengthShort * 8
 
const uint16_t kDaikinDefaultRepeat = kNoRepeat
 
const uint16_t kDaikin2StateLength = 39
 
const uint16_t kDaikin2Bits = kDaikin2StateLength * 8
 
const uint16_t kDaikin2DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin64Bits = 64
 
const uint16_t kDaikin64DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin160StateLength = 20
 
const uint16_t kDaikin160Bits = kDaikin160StateLength * 8
 
const uint16_t kDaikin160DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin128StateLength = 16
 
const uint16_t kDaikin128Bits = kDaikin128StateLength * 8
 
const uint16_t kDaikin128DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin152StateLength = 19
 
const uint16_t kDaikin152Bits = kDaikin152StateLength * 8
 
const uint16_t kDaikin152DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin176StateLength = 22
 
const uint16_t kDaikin176Bits = kDaikin176StateLength * 8
 
const uint16_t kDaikin176DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin216StateLength = 27
 
const uint16_t kDaikin216Bits = kDaikin216StateLength * 8
 
const uint16_t kDaikin216DefaultRepeat = kNoRepeat
 
const uint16_t kDelonghiAcBits = 64
 
const uint16_t kDelonghiAcDefaultRepeat = kNoRepeat
 
const uint16_t kDenonBits = 15
 
const uint16_t kDenon48Bits = 48
 
const uint16_t kDenonLegacyBits = 14
 
const uint16_t kDishBits = 16
 
const uint16_t kDishMinRepeat = 3
 
const uint16_t kDoshishaBits = 40
 
const uint16_t kEpsonBits = 32
 
const uint16_t kEpsonMinRepeat = 2
 
const uint16_t kElectraAcStateLength = 13
 
const uint16_t kElectraAcBits = kElectraAcStateLength * 8
 
const uint16_t kElectraAcMinRepeat = kNoRepeat
 
const uint16_t kFujitsuAcMinRepeat = kNoRepeat
 
const uint16_t kFujitsuAcStateLength = 16
 
const uint16_t kFujitsuAcStateLengthShort = 7
 
const uint16_t kFujitsuAcBits = kFujitsuAcStateLength * 8
 
const uint16_t kFujitsuAcMinBits = (kFujitsuAcStateLengthShort - 1) * 8
 
const uint16_t kGicableBits = 16
 
const uint16_t kGicableMinRepeat = kSingleRepeat
 
const uint16_t kGoodweatherBits = 48
 
const uint16_t kGoodweatherMinRepeat = kNoRepeat
 
const uint16_t kGreeStateLength = 8
 
const uint16_t kGreeBits = kGreeStateLength * 8
 
const uint16_t kGreeDefaultRepeat = kNoRepeat
 
const uint16_t kHaierACStateLength = 9
 
const uint16_t kHaierACBits = kHaierACStateLength * 8
 
const uint16_t kHaierAcDefaultRepeat = kNoRepeat
 
const uint16_t kHaierACYRW02StateLength = 14
 
const uint16_t kHaierACYRW02Bits = kHaierACYRW02StateLength * 8
 
const uint16_t kHaierAcYrw02DefaultRepeat = kNoRepeat
 
const uint16_t kHitachiAcStateLength = 28
 
const uint16_t kHitachiAcBits = kHitachiAcStateLength * 8
 
const uint16_t kHitachiAcDefaultRepeat = kNoRepeat
 
const uint16_t kHitachiAc1StateLength = 13
 
const uint16_t kHitachiAc1Bits = kHitachiAc1StateLength * 8
 
const uint16_t kHitachiAc2StateLength = 53
 
const uint16_t kHitachiAc2Bits = kHitachiAc2StateLength * 8
 
const uint16_t kHitachiAc3StateLength = 27
 
const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8
 
const uint16_t kHitachiAc3MinStateLength = 15
 
const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8
 
const uint16_t kHitachiAc344StateLength = 43
 
const uint16_t kHitachiAc344Bits = kHitachiAc344StateLength * 8
 
const uint16_t kHitachiAc424StateLength = 53
 
const uint16_t kHitachiAc424Bits = kHitachiAc424StateLength * 8
 
const uint16_t kInaxBits = 24
 
const uint16_t kInaxMinRepeat = kSingleRepeat
 
const uint16_t kJvcBits = 16
 
const uint16_t kKelvinatorStateLength = 16
 
const uint16_t kKelvinatorBits = kKelvinatorStateLength * 8
 
const uint16_t kKelvinatorDefaultRepeat = kNoRepeat
 
const uint16_t kLasertagBits = 13
 
const uint16_t kLasertagMinRepeat = kNoRepeat
 
const uint16_t kLegoPfBits = 16
 
const uint16_t kLegoPfMinRepeat = kNoRepeat
 
const uint16_t kLgBits = 28
 
const uint16_t kLg32Bits = 32
 
const uint16_t kLgDefaultRepeat = kNoRepeat
 
const uint16_t kLutronBits = 35
 
const uint16_t kMagiquestBits = 56
 
const uint16_t kMideaBits = 48
 
const uint16_t kMideaMinRepeat = kNoRepeat
 
const uint16_t kMidea24Bits = 24
 
const uint16_t kMidea24MinRepeat = kSingleRepeat
 
const uint16_t kMitsubishiBits = 16
 
const uint16_t kMitsubishiMinRepeat = kSingleRepeat
 
const uint16_t kMitsubishiACStateLength = 18
 
const uint16_t kMitsubishiACBits = kMitsubishiACStateLength * 8
 
const uint16_t kMitsubishiACMinRepeat = kSingleRepeat
 
const uint16_t kMitsubishi136StateLength = 17
 
const uint16_t kMitsubishi136Bits = kMitsubishi136StateLength * 8
 
const uint16_t kMitsubishi136MinRepeat = kNoRepeat
 
const uint16_t kMitsubishi112StateLength = 14
 
const uint16_t kMitsubishi112Bits = kMitsubishi112StateLength * 8
 
const uint16_t kMitsubishi112MinRepeat = kNoRepeat
 
const uint16_t kMitsubishiHeavy88StateLength = 11
 
const uint16_t kMitsubishiHeavy88Bits = kMitsubishiHeavy88StateLength * 8
 
const uint16_t kMitsubishiHeavy88MinRepeat = kNoRepeat
 
const uint16_t kMitsubishiHeavy152StateLength = 19
 
const uint16_t kMitsubishiHeavy152Bits = kMitsubishiHeavy152StateLength * 8
 
const uint16_t kMitsubishiHeavy152MinRepeat = kNoRepeat
 
const uint16_t kMultibracketsBits = 8
 
const uint16_t kMultibracketsDefaultRepeat = kSingleRepeat
 
const uint16_t kNikaiBits = 24
 
const uint16_t kNECBits = 32
 
const uint16_t kNeoclimaStateLength = 12
 
const uint16_t kNeoclimaBits = kNeoclimaStateLength * 8
 
const uint16_t kNeoclimaMinRepeat = kNoRepeat
 
const uint16_t kPanasonicBits = 48
 
const uint32_t kPanasonicManufacturer = 0x4004
 
const uint16_t kPanasonicAcStateLength = 27
 
const uint16_t kPanasonicAcStateShortLength = 16
 
const uint16_t kPanasonicAcBits = kPanasonicAcStateLength * 8
 
const uint16_t kPanasonicAcShortBits = kPanasonicAcStateShortLength * 8
 
const uint16_t kPanasonicAcDefaultRepeat = kNoRepeat
 
const uint16_t kPioneerBits = 64
 
const uint16_t kProntoMinLength = 6
 
const uint16_t kRC5RawBits = 14
 
const uint16_t kRC5Bits = kRC5RawBits - 2
 
const uint16_t kRC5XBits = kRC5RawBits - 1
 
const uint16_t kRC6Mode0Bits = 20
 
const uint16_t kRC6_36Bits = 36
 
const uint16_t kRCMMBits = 24
 
const uint16_t kSamsungBits = 32
 
const uint16_t kSamsung36Bits = 36
 
const uint16_t kSamsungAcStateLength = 14
 
const uint16_t kSamsungAcBits = kSamsungAcStateLength * 8
 
const uint16_t kSamsungAcExtendedStateLength = 21
 
const uint16_t kSamsungAcExtendedBits = kSamsungAcExtendedStateLength * 8
 
const uint16_t kSamsungAcDefaultRepeat = kNoRepeat
 
const uint16_t kSanyoSA8650BBits = 12
 
const uint16_t kSanyoLC7461AddressBits = 13
 
const uint16_t kSanyoLC7461CommandBits = 8
 
const uint16_t kSanyoLC7461Bits
 
const uint8_t kSharpAddressBits = 5
 
const uint8_t kSharpCommandBits = 8
 
const uint16_t kSharpBits = kSharpAddressBits + kSharpCommandBits + 2
 
const uint16_t kSharpAcStateLength = 13
 
const uint16_t kSharpAcBits = kSharpAcStateLength * 8
 
const uint16_t kSharpAcDefaultRepeat = kNoRepeat
 
const uint8_t kSherwoodBits = kNECBits
 
const uint16_t kSherwoodMinRepeat = kSingleRepeat
 
const uint16_t kSony12Bits = 12
 
const uint16_t kSony15Bits = 15
 
const uint16_t kSony20Bits = 20
 
const uint16_t kSonyMinBits = 12
 
const uint16_t kSonyMinRepeat = 2
 
const uint16_t kSymphonyBits = 12
 
const uint16_t kSymphonyDefaultRepeat = 3
 
const uint16_t kTcl112AcStateLength = 14
 
const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8
 
const uint16_t kTcl112AcDefaultRepeat = kNoRepeat
 
const uint16_t kTecoBits = 35
 
const uint16_t kTecoDefaultRepeat = kNoRepeat
 
const uint16_t kToshibaACStateLength = 9
 
const uint16_t kToshibaACBits = kToshibaACStateLength * 8
 
const uint16_t kToshibaACMinRepeat = kSingleRepeat
 
const uint16_t kTrotecStateLength = 9
 
const uint16_t kTrotecBits = kTrotecStateLength * 8
 
const uint16_t kTrotecDefaultRepeat = kNoRepeat
 
const uint16_t kWhirlpoolAcStateLength = 21
 
const uint16_t kWhirlpoolAcBits = kWhirlpoolAcStateLength * 8
 
const uint16_t kWhirlpoolAcDefaultRepeat = kNoRepeat
 
const uint16_t kWhynterBits = 32
 
const uint8_t kVestelAcBits = 56
 
const uint16_t kZepealBits = 16
 
const uint16_t kZepealMinRepeat = 4
 
+

Typedef Documentation

+ +

◆ String

+ +
+
+ + + + +
typedef std::string String
+
+ +
+
+

Enumeration Type Documentation

+ +

◆ decode_type_t

+ +
+
+ + + + +
enum decode_type_t
+
+ +

Enumerator for defining and numbering of supported IR protocol.

+
Note
Always add to the end of the list and should never remove entries or change order. Projects may save the type number for later usage so numbering should always stay the same.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerator
UNKNOWN 
UNUSED 
RC5 
RC6 
NEC 
SONY 
PANASONIC 
JVC 
SAMSUNG 
WHYNTER 
AIWA_RC_T501 
LG 
SANYO 
MITSUBISHI 
DISH 
SHARP 
COOLIX 
DAIKIN 
DENON 
KELVINATOR 
SHERWOOD 
MITSUBISHI_AC 
RCMM 
SANYO_LC7461 
RC5X 
GREE 
PRONTO 
NEC_LIKE 
ARGO 
TROTEC 
NIKAI 
RAW 
GLOBALCACHE 
TOSHIBA_AC 
FUJITSU_AC 
MIDEA 
MAGIQUEST 
LASERTAG 
CARRIER_AC 
HAIER_AC 
MITSUBISHI2 
HITACHI_AC 
HITACHI_AC1 
HITACHI_AC2 
GICABLE 
HAIER_AC_YRW02 
WHIRLPOOL_AC 
SAMSUNG_AC 
LUTRON 
ELECTRA_AC 
PANASONIC_AC 
PIONEER 
LG2 
MWM 
DAIKIN2 
VESTEL_AC 
TECO 
SAMSUNG36 
TCL112AC 
LEGOPF 
MITSUBISHI_HEAVY_88 
MITSUBISHI_HEAVY_152 
DAIKIN216 
SHARP_AC 
GOODWEATHER 
INAX 
DAIKIN160 
NEOCLIMA 
DAIKIN176 
DAIKIN128 
AMCOR 
DAIKIN152 
MITSUBISHI136 
MITSUBISHI112 
HITACHI_AC424 
SONY_38K 
EPSON 
SYMPHONY 
HITACHI_AC3 
DAIKIN64 
AIRWELL 
DELONGHI_AC 
DOSHISHA 
MULTIBRACKETS 
CARRIER_AC40 
CARRIER_AC64 
HITACHI_AC344 
CORONA_AC 
MIDEA24 
ZEPEAL 
kLastDecodeType 
+ +
+
+

Variable Documentation

+ +

◆ kAirwellBits

+ +
+
+ + + + +
const uint16_t kAirwellBits = 34
+
+ +
+
+ +

◆ kAirwellMinRepeats

+ +
+
+ + + + +
const uint16_t kAirwellMinRepeats = 2
+
+ +
+
+ +

◆ kAiwaRcT501Bits

+ +
+
+ + + + +
const uint16_t kAiwaRcT501Bits = 15
+
+ +
+
+ +

◆ kAiwaRcT501MinRepeats

+ +
+
+ + + + +
const uint16_t kAiwaRcT501MinRepeats = kSingleRepeat
+
+ +
+
+ +

◆ kAlokaBits

+ +
+
+ + + + +
const uint16_t kAlokaBits = 32
+
+ +
+
+ +

◆ kAmcorBits

+ +
+
+ + + + +
const uint16_t kAmcorBits = kAmcorStateLength * 8
+
+ +
+
+ +

◆ kAmcorDefaultRepeat

+ +
+
+ + + + +
const uint16_t kAmcorDefaultRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kAmcorStateLength

+ +
+
+ + + + +
const uint16_t kAmcorStateLength = 8
+
+ +
+
+ +

◆ kArgoBits

+ +
+
+ + + + +
const uint16_t kArgoBits = kArgoStateLength * 8
+
+ +
+
+ +

◆ kArgoDefaultRepeat

+ +
+
+ + + + +
const uint16_t kArgoDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kArgoStateLength

+ +
+
+ + + + +
const uint16_t kArgoStateLength = 12
+
+ +
+
+ +

◆ kCarrierAc40Bits

+ +
+
+ + + + +
const uint16_t kCarrierAc40Bits = 40
+
+ +
+
+ +

◆ kCarrierAc40MinRepeat

+ +
+
+ + + + +
const uint16_t kCarrierAc40MinRepeat = 2
+
+ +
+
+ +

◆ kCarrierAc64Bits

+ +
+
+ + + + +
const uint16_t kCarrierAc64Bits = 64
+
+ +
+
+ +

◆ kCarrierAc64MinRepeat

+ +
+
+ + + + +
const uint16_t kCarrierAc64MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kCarrierAcBits

+ +
+
+ + + + +
const uint16_t kCarrierAcBits = 32
+
+ +
+
+ +

◆ kCarrierAcMinRepeat

+ +
+
+ + + + +
const uint16_t kCarrierAcMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kCoolixBits

+ +
+
+ + + + +
const uint16_t kCoolixBits = 24
+
+ +
+
+ +

◆ kCoolixDefaultRepeat

+ +
+
+ + + + +
const uint16_t kCoolixDefaultRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kCoronaAcBits

+ +
+
+ + + + +
const uint16_t kCoronaAcBits = kCoronaAcStateLength * 8
+
+ +
+
+ +

◆ kCoronaAcBitsShort

+ +
+
+ + + + +
const uint16_t kCoronaAcBitsShort = kCoronaAcStateLengthShort * 8
+
+ +
+
+ +

◆ kCoronaAcStateLength

+ +
+
+ + + + +
const uint16_t kCoronaAcStateLength = kCoronaAcStateLengthShort * 3
+
+ +
+
+ +

◆ kCoronaAcStateLengthShort

+ +
+
+ + + + +
const uint16_t kCoronaAcStateLengthShort = 7
+
+ +
+
+ +

◆ kDaikin128Bits

+ +
+
+ + + + +
const uint16_t kDaikin128Bits = kDaikin128StateLength * 8
+
+ +
+
+ +

◆ kDaikin128DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin128DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin128StateLength

+ +
+
+ + + + +
const uint16_t kDaikin128StateLength = 16
+
+ +
+
+ +

◆ kDaikin152Bits

+ +
+
+ + + + +
const uint16_t kDaikin152Bits = kDaikin152StateLength * 8
+
+ +
+
+ +

◆ kDaikin152DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin152DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin152StateLength

+ +
+
+ + + + +
const uint16_t kDaikin152StateLength = 19
+
+ +
+
+ +

◆ kDaikin160Bits

+ +
+
+ + + + +
const uint16_t kDaikin160Bits = kDaikin160StateLength * 8
+
+ +
+
+ +

◆ kDaikin160DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin160DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin160StateLength

+ +
+
+ + + + +
const uint16_t kDaikin160StateLength = 20
+
+ +
+
+ +

◆ kDaikin176Bits

+ +
+
+ + + + +
const uint16_t kDaikin176Bits = kDaikin176StateLength * 8
+
+ +
+
+ +

◆ kDaikin176DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin176DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin176StateLength

+ +
+
+ + + + +
const uint16_t kDaikin176StateLength = 22
+
+ +
+
+ +

◆ kDaikin216Bits

+ +
+
+ + + + +
const uint16_t kDaikin216Bits = kDaikin216StateLength * 8
+
+ +
+
+ +

◆ kDaikin216DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin216DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin216StateLength

+ +
+
+ + + + +
const uint16_t kDaikin216StateLength = 27
+
+ +
+
+ +

◆ kDaikin2Bits

+ +
+
+ + + + +
const uint16_t kDaikin2Bits = kDaikin2StateLength * 8
+
+ +
+
+ +

◆ kDaikin2DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin2DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin2StateLength

+ +
+
+ + + + +
const uint16_t kDaikin2StateLength = 39
+
+ +
+
+ +

◆ kDaikin64Bits

+ +
+
+ + + + +
const uint16_t kDaikin64Bits = 64
+
+ +
+
+ +

◆ kDaikin64DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin64DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikinBits

+ +
+
+ + + + +
const uint16_t kDaikinBits = kDaikinStateLength * 8
+
+ +
+
+ +

◆ kDaikinBitsShort

+ +
+
+ + + + +
const uint16_t kDaikinBitsShort = kDaikinStateLengthShort * 8
+
+ +
+
+ +

◆ kDaikinDefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikinDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikinStateLength

+ +
+
+ + + + +
const uint16_t kDaikinStateLength = 35
+
+ +
+
+ +

◆ kDaikinStateLengthShort

+ +
+
+ + + + +
const uint16_t kDaikinStateLengthShort = kDaikinStateLength - 8
+
+ +
+
+ +

◆ kDelonghiAcBits

+ +
+
+ + + + +
const uint16_t kDelonghiAcBits = 64
+
+ +
+
+ +

◆ kDelonghiAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kDelonghiAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDenon48Bits

+ +
+
+ + + + +
const uint16_t kDenon48Bits = 48
+
+ +
+
+ +

◆ kDenonBits

+ +
+
+ + + + +
const uint16_t kDenonBits = 15
+
+ +
+
+ +

◆ kDenonLegacyBits

+ +
+
+ + + + +
const uint16_t kDenonLegacyBits = 14
+
+ +
+
+ +

◆ kDishBits

+ +
+
+ + + + +
const uint16_t kDishBits = 16
+
+ +
+
+ +

◆ kDishMinRepeat

+ +
+
+ + + + +
const uint16_t kDishMinRepeat = 3
+
+ +
+
+ +

◆ kDoshishaBits

+ +
+
+ + + + +
const uint16_t kDoshishaBits = 40
+
+ +
+
+ +

◆ kElectraAcBits

+ +
+
+ + + + +
const uint16_t kElectraAcBits = kElectraAcStateLength * 8
+
+ +
+
+ +

◆ kElectraAcMinRepeat

+ +
+
+ + + + +
const uint16_t kElectraAcMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kElectraAcStateLength

+ +
+
+ + + + +
const uint16_t kElectraAcStateLength = 13
+
+ +
+
+ +

◆ kEpsonBits

+ +
+
+ + + + +
const uint16_t kEpsonBits = 32
+
+ +
+
+ +

◆ kEpsonMinRepeat

+ +
+
+ + + + +
const uint16_t kEpsonMinRepeat = 2
+
+ +
+
+ +

◆ kFujitsuAcBits

+ +
+
+ + + + +
const uint16_t kFujitsuAcBits = kFujitsuAcStateLength * 8
+
+ +
+
+ +

◆ kFujitsuAcMinBits

+ +
+
+ + + + +
const uint16_t kFujitsuAcMinBits = (kFujitsuAcStateLengthShort - 1) * 8
+
+ +
+
+ +

◆ kFujitsuAcMinRepeat

+ +
+
+ + + + +
const uint16_t kFujitsuAcMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kFujitsuAcStateLength

+ +
+
+ + + + +
const uint16_t kFujitsuAcStateLength = 16
+
+ +
+
+ +

◆ kFujitsuAcStateLengthShort

+ +
+
+ + + + +
const uint16_t kFujitsuAcStateLengthShort = 7
+
+ +
+
+ +

◆ kGicableBits

+ +
+
+ + + + +
const uint16_t kGicableBits = 16
+
+ +
+
+ +

◆ kGicableMinRepeat

+ +
+
+ + + + +
const uint16_t kGicableMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kGoodweatherBits

+ +
+
+ + + + +
const uint16_t kGoodweatherBits = 48
+
+ +
+
+ +

◆ kGoodweatherMinRepeat

+ +
+
+ + + + +
const uint16_t kGoodweatherMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kGreeBits

+ +
+
+ + + + +
const uint16_t kGreeBits = kGreeStateLength * 8
+
+ +
+
+ +

◆ kGreeDefaultRepeat

+ +
+
+ + + + +
const uint16_t kGreeDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kGreeStateLength

+ +
+
+ + + + +
const uint16_t kGreeStateLength = 8
+
+ +
+
+ +

◆ kHaierACBits

+ +
+
+ + + + +
const uint16_t kHaierACBits = kHaierACStateLength * 8
+
+ +
+
+ +

◆ kHaierAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kHaierAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kHaierACStateLength

+ +
+
+ + + + +
const uint16_t kHaierACStateLength = 9
+
+ +
+
+ +

◆ kHaierACYRW02Bits

+ +
+
+ + + + +
const uint16_t kHaierACYRW02Bits = kHaierACYRW02StateLength * 8
+
+ +
+
+ +

◆ kHaierAcYrw02DefaultRepeat

+ +
+
+ + + + +
const uint16_t kHaierAcYrw02DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kHaierACYRW02StateLength

+ +
+
+ + + + +
const uint16_t kHaierACYRW02StateLength = 14
+
+ +
+
+ +

◆ kHitachiAc1Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc1Bits = kHitachiAc1StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc1StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc1StateLength = 13
+
+ +
+
+ +

◆ kHitachiAc2Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc2Bits = kHitachiAc2StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc2StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc2StateLength = 53
+
+ +
+
+ +

◆ kHitachiAc344Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc344Bits = kHitachiAc344StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc344StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc344StateLength = 43
+
+ +
+
+ +

◆ kHitachiAc3Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc3MinBits

+ +
+
+ + + + +
const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8
+
+ +
+
+ +

◆ kHitachiAc3MinStateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc3MinStateLength = 15
+
+ +
+
+ +

◆ kHitachiAc3StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc3StateLength = 27
+
+ +
+
+ +

◆ kHitachiAc424Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc424Bits = kHitachiAc424StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc424StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc424StateLength = 53
+
+ +
+
+ +

◆ kHitachiAcBits

+ +
+
+ + + + +
const uint16_t kHitachiAcBits = kHitachiAcStateLength * 8
+
+ +
+
+ +

◆ kHitachiAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kHitachiAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kHitachiAcStateLength

+ +
+
+ + + + +
const uint16_t kHitachiAcStateLength = 28
+
+ +
+
+ +

◆ kInaxBits

+ +
+
+ + + + +
const uint16_t kInaxBits = 24
+
+ +
+
+ +

◆ kInaxMinRepeat

+ +
+
+ + + + +
const uint16_t kInaxMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kJvcBits

+ +
+
+ + + + +
const uint16_t kJvcBits = 16
+
+ +
+
+ +

◆ kKelvinatorBits

+ +
+
+ + + + +
const uint16_t kKelvinatorBits = kKelvinatorStateLength * 8
+
+ +
+
+ +

◆ kKelvinatorDefaultRepeat

+ +
+
+ + + + +
const uint16_t kKelvinatorDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kKelvinatorStateLength

+ +
+
+ + + + +
const uint16_t kKelvinatorStateLength = 16
+
+ +
+
+ +

◆ kLasertagBits

+ +
+
+ + + + +
const uint16_t kLasertagBits = 13
+
+ +
+
+ +

◆ kLasertagMinRepeat

+ +
+
+ + + + +
const uint16_t kLasertagMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kLegoPfBits

+ +
+
+ + + + +
const uint16_t kLegoPfBits = 16
+
+ +
+
+ +

◆ kLegoPfMinRepeat

+ +
+
+ + + + +
const uint16_t kLegoPfMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kLg32Bits

+ +
+
+ + + + +
const uint16_t kLg32Bits = 32
+
+ +
+
+ +

◆ kLgBits

+ +
+
+ + + + +
const uint16_t kLgBits = 28
+
+ +
+
+ +

◆ kLgDefaultRepeat

+ +
+
+ + + + +
const uint16_t kLgDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kLutronBits

+ +
+
+ + + + +
const uint16_t kLutronBits = 35
+
+ +
+
+ +

◆ kMagiquestBits

+ +
+
+ + + + +
const uint16_t kMagiquestBits = 56
+
+ +
+
+ +

◆ kMidea24Bits

+ +
+
+ + + + +
const uint16_t kMidea24Bits = 24
+
+ +
+
+ +

◆ kMidea24MinRepeat

+ +
+
+ + + + +
const uint16_t kMidea24MinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kMideaBits

+ +
+
+ + + + +
const uint16_t kMideaBits = 48
+
+ +
+
+ +

◆ kMideaMinRepeat

+ +
+
+ + + + +
const uint16_t kMideaMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishi112Bits

+ +
+
+ + + + +
const uint16_t kMitsubishi112Bits = kMitsubishi112StateLength * 8
+
+ +
+
+ +

◆ kMitsubishi112MinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishi112MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishi112StateLength

+ +
+
+ + + + +
const uint16_t kMitsubishi112StateLength = 14
+
+ +
+
+ +

◆ kMitsubishi136Bits

+ +
+
+ + + + +
const uint16_t kMitsubishi136Bits = kMitsubishi136StateLength * 8
+
+ +
+
+ +

◆ kMitsubishi136MinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishi136MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishi136StateLength

+ +
+
+ + + + +
const uint16_t kMitsubishi136StateLength = 17
+
+ +
+
+ +

◆ kMitsubishiACBits

+ +
+
+ + + + +
const uint16_t kMitsubishiACBits = kMitsubishiACStateLength * 8
+
+ +
+
+ +

◆ kMitsubishiACMinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishiACMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kMitsubishiACStateLength

+ +
+
+ + + + +
const uint16_t kMitsubishiACStateLength = 18
+
+ +
+
+ +

◆ kMitsubishiBits

+ +
+
+ + + + +
const uint16_t kMitsubishiBits = 16
+
+ +
+
+ +

◆ kMitsubishiHeavy152Bits

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy152Bits = kMitsubishiHeavy152StateLength * 8
+
+ +
+
+ +

◆ kMitsubishiHeavy152MinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy152MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishiHeavy152StateLength

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy152StateLength = 19
+
+ +
+
+ +

◆ kMitsubishiHeavy88Bits

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy88Bits = kMitsubishiHeavy88StateLength * 8
+
+ +
+
+ +

◆ kMitsubishiHeavy88MinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy88MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishiHeavy88StateLength

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy88StateLength = 11
+
+ +
+
+ +

◆ kMitsubishiMinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishiMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kMultibracketsBits

+ +
+
+ + + + +
const uint16_t kMultibracketsBits = 8
+
+ +
+
+ +

◆ kMultibracketsDefaultRepeat

+ +
+
+ + + + +
const uint16_t kMultibracketsDefaultRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kNECBits

+ +
+
+ + + + +
const uint16_t kNECBits = 32
+
+ +
+
+ +

◆ kNeoclimaBits

+ +
+
+ + + + +
const uint16_t kNeoclimaBits = kNeoclimaStateLength * 8
+
+ +
+
+ +

◆ kNeoclimaMinRepeat

+ +
+
+ + + + +
const uint16_t kNeoclimaMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kNeoclimaStateLength

+ +
+
+ + + + +
const uint16_t kNeoclimaStateLength = 12
+
+ +
+
+ +

◆ kNikaiBits

+ +
+
+ + + + +
const uint16_t kNikaiBits = 24
+
+ +
+
+ +

◆ kNoRepeat

+ +
+
+ + + + +
const uint16_t kNoRepeat = 0
+
+ +
+
+ +

◆ kPanasonicAcBits

+ +
+
+ + + + +
const uint16_t kPanasonicAcBits = kPanasonicAcStateLength * 8
+
+ +
+
+ +

◆ kPanasonicAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kPanasonicAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kPanasonicAcShortBits

+ +
+
+ + + + +
const uint16_t kPanasonicAcShortBits = kPanasonicAcStateShortLength * 8
+
+ +
+
+ +

◆ kPanasonicAcStateLength

+ +
+
+ + + + +
const uint16_t kPanasonicAcStateLength = 27
+
+ +
+
+ +

◆ kPanasonicAcStateShortLength

+ +
+
+ + + + +
const uint16_t kPanasonicAcStateShortLength = 16
+
+ +
+
+ +

◆ kPanasonicBits

+ +
+
+ + + + +
const uint16_t kPanasonicBits = 48
+
+ +
+
+ +

◆ kPanasonicManufacturer

+ +
+
+ + + + +
const uint32_t kPanasonicManufacturer = 0x4004
+
+ +
+
+ +

◆ kPioneerBits

+ +
+
+ + + + +
const uint16_t kPioneerBits = 64
+
+ +
+
+ +

◆ kProntoMinLength

+ +
+
+ + + + +
const uint16_t kProntoMinLength = 6
+
+ +
+
+ +

◆ kRC5Bits

+ +
+
+ + + + +
const uint16_t kRC5Bits = kRC5RawBits - 2
+
+ +
+
+ +

◆ kRC5RawBits

+ +
+
+ + + + +
const uint16_t kRC5RawBits = 14
+
+ +
+
+ +

◆ kRC5XBits

+ +
+
+ + + + +
const uint16_t kRC5XBits = kRC5RawBits - 1
+
+ +
+
+ +

◆ kRC6_36Bits

+ +
+
+ + + + +
const uint16_t kRC6_36Bits = 36
+
+ +
+
+ +

◆ kRC6Mode0Bits

+ +
+
+ + + + +
const uint16_t kRC6Mode0Bits = 20
+
+ +
+
+ +

◆ kRCMMBits

+ +
+
+ + + + +
const uint16_t kRCMMBits = 24
+
+ +
+
+ +

◆ kSamsung36Bits

+ +
+
+ + + + +
const uint16_t kSamsung36Bits = 36
+
+ +
+
+ +

◆ kSamsungAcBits

+ +
+
+ + + + +
const uint16_t kSamsungAcBits = kSamsungAcStateLength * 8
+
+ +
+
+ +

◆ kSamsungAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kSamsungAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kSamsungAcExtendedBits

+ +
+
+ + + + +
const uint16_t kSamsungAcExtendedBits = kSamsungAcExtendedStateLength * 8
+
+ +
+
+ +

◆ kSamsungAcExtendedStateLength

+ +
+
+ + + + +
const uint16_t kSamsungAcExtendedStateLength = 21
+
+ +
+
+ +

◆ kSamsungAcStateLength

+ +
+
+ + + + +
const uint16_t kSamsungAcStateLength = 14
+
+ +
+
+ +

◆ kSamsungBits

+ +
+
+ + + + +
const uint16_t kSamsungBits = 32
+
+ +
+
+ +

◆ kSanyoLC7461AddressBits

+ +
+
+ + + + +
const uint16_t kSanyoLC7461AddressBits = 13
+
+ +
+
+ +

◆ kSanyoLC7461Bits

+ +
+
+ + + + +
const uint16_t kSanyoLC7461Bits
+
+Initial value: +
+
+ +

◆ kSanyoLC7461CommandBits

+ +
+
+ + + + +
const uint16_t kSanyoLC7461CommandBits = 8
+
+ +
+
+ +

◆ kSanyoSA8650BBits

+ +
+
+ + + + +
const uint16_t kSanyoSA8650BBits = 12
+
+ +
+
+ +

◆ kSharpAcBits

+ +
+
+ + + + +
const uint16_t kSharpAcBits = kSharpAcStateLength * 8
+
+ +
+
+ +

◆ kSharpAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kSharpAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kSharpAcStateLength

+ +
+
+ + + + +
const uint16_t kSharpAcStateLength = 13
+
+ +
+
+ +

◆ kSharpAddressBits

+ +
+
+ + + + +
const uint8_t kSharpAddressBits = 5
+
+ +
+
+ +

◆ kSharpBits

+ +
+
+ + + + +
const uint16_t kSharpBits = kSharpAddressBits + kSharpCommandBits + 2
+
+ +
+
+ +

◆ kSharpCommandBits

+ +
+
+ + + + +
const uint8_t kSharpCommandBits = 8
+
+ +
+
+ +

◆ kSherwoodBits

+ +
+
+ + + + +
const uint8_t kSherwoodBits = kNECBits
+
+ +
+
+ +

◆ kSherwoodMinRepeat

+ +
+
+ + + + +
const uint16_t kSherwoodMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kSingleRepeat

+ +
+
+ + + + +
const uint16_t kSingleRepeat = 1
+
+ +
+
+ +

◆ kSony12Bits

+ +
+
+ + + + +
const uint16_t kSony12Bits = 12
+
+ +
+
+ +

◆ kSony15Bits

+ +
+
+ + + + +
const uint16_t kSony15Bits = 15
+
+ +
+
+ +

◆ kSony20Bits

+ +
+
+ + + + +
const uint16_t kSony20Bits = 20
+
+ +
+
+ +

◆ kSonyMinBits

+ +
+
+ + + + +
const uint16_t kSonyMinBits = 12
+
+ +
+
+ +

◆ kSonyMinRepeat

+ +
+
+ + + + +
const uint16_t kSonyMinRepeat = 2
+
+ +
+
+ +

◆ kSymphonyBits

+ +
+
+ + + + +
const uint16_t kSymphonyBits = 12
+
+ +
+
+ +

◆ kSymphonyDefaultRepeat

+ +
+
+ + + + +
const uint16_t kSymphonyDefaultRepeat = 3
+
+ +
+
+ +

◆ kTcl112AcBits

+ +
+
+ + + + +
const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8
+
+ +
+
+ +

◆ kTcl112AcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kTcl112AcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kTcl112AcStateLength

+ +
+
+ + + + +
const uint16_t kTcl112AcStateLength = 14
+
+ +
+
+ +

◆ kTecoBits

+ +
+
+ + + + +
const uint16_t kTecoBits = 35
+
+ +
+
+ +

◆ kTecoDefaultRepeat

+ +
+
+ + + + +
const uint16_t kTecoDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kToshibaACBits

+ +
+
+ + + + +
const uint16_t kToshibaACBits = kToshibaACStateLength * 8
+
+ +
+
+ +

◆ kToshibaACMinRepeat

+ +
+
+ + + + +
const uint16_t kToshibaACMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kToshibaACStateLength

+ +
+
+ + + + +
const uint16_t kToshibaACStateLength = 9
+
+ +
+
+ +

◆ kTrotecBits

+ +
+
+ + + + +
const uint16_t kTrotecBits = kTrotecStateLength * 8
+
+ +
+
+ +

◆ kTrotecDefaultRepeat

+ +
+
+ + + + +
const uint16_t kTrotecDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kTrotecStateLength

+ +
+
+ + + + +
const uint16_t kTrotecStateLength = 9
+
+ +
+
+ +

◆ kVestelAcBits

+ +
+
+ + + + +
const uint8_t kVestelAcBits = 56
+
+ +
+
+ +

◆ kWhirlpoolAcBits

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcBits = kWhirlpoolAcStateLength * 8
+
+ +
+
+ +

◆ kWhirlpoolAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kWhirlpoolAcStateLength

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcStateLength = 21
+
+ +
+
+ +

◆ kWhynterBits

+ +
+
+ + + + +
const uint16_t kWhynterBits = 32
+
+ +
+
+ +

◆ kZepealBits

+ +
+
+ + + + +
const uint16_t kZepealBits = 16
+
+ +
+
+ +

◆ kZepealMinRepeat

+ +
+
+ + + + +
const uint16_t kZepealMinRepeat = 4
+
+ +
+
+
+
const uint16_t kSanyoLC7461CommandBits
Definition: IRremoteESP8266.h:976
+
const uint16_t kSanyoLC7461AddressBits
Definition: IRremoteESP8266.h:975
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h_source.html new file mode 100644 index 000000000..42c1af80b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h_source.html @@ -0,0 +1,1463 @@ + + + + + + + +IRremoteESP8266: src/IRremoteESP8266.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRremoteESP8266.h
+
+
+Go to the documentation of this file.
1  /***************************************************
+
2  * IRremote for ESP8266
+
3  *
+
4  * Based on the IRremote library for Arduino by Ken Shirriff
+
5  * Version 0.11 August, 2009
+
6  * Copyright 2009 Ken Shirriff
+
7  * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
+
8  *
+
9  * Edited by Mitra to add new controller SANYO
+
10  *
+
11  * Interrupt code based on NECIRrcv by Joe Knapp
+
12  * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
+
13  * Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
+
14  *
+
15  * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
+
16  * LG added by Darryl Smith (based on the JVC protocol)
+
17  * Whynter A/C ARC-110WD added by Francesco Meschia
+
18  * Coolix A/C / heatpump added by (send) bakrus & (decode) crankyoldgit
+
19  * Denon: sendDenon, decodeDenon added by Massimiliano Pinto
+
20  (from https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp)
+
21  * Kelvinator A/C and Sherwood added by crankyoldgit
+
22  * Mitsubishi (TV) sending added by crankyoldgit
+
23  * Pronto code sending added by crankyoldgit
+
24  * Mitsubishi & Toshiba A/C added by crankyoldgit
+
25  * (derived from https://github.com/r45635/HVAC-IR-Control)
+
26  * DISH decode by marcosamarinho
+
27  * Gree Heatpump sending added by Ville Skyttä (scop)
+
28  * (derived from https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp)
+
29  * Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for sending IR code on ESP8266
+
30  * Updated by Sebastien Warin (http://sebastien.warin.fr) for receiving IR code on ESP8266
+
31  *
+
32  * Updated by sillyfrog for Daikin, adopted from
+
33  * (https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/)
+
34  * Fujitsu A/C code added by jonnygraham
+
35  * Trotec AC code by stufisher
+
36  * Carrier & Haier AC code by crankyoldgit
+
37  * Vestel AC code by Erdem U. Altınyurt
+
38  * Teco AC code by Fabien Valthier (hcoohb)
+
39  * Mitsubishi 112 AC Code by kuchel77
+
40  *
+
41  * GPL license, all text above must be included in any redistribution
+
42  ****************************************************/
+
43 
+
44 #ifndef IRREMOTEESP8266_H_
+
45 #define IRREMOTEESP8266_H_
+
46 
+
47 #define __STDC_LIMIT_MACROS
+
48 #include <stdint.h>
+
49 #ifdef UNIT_TEST
+
50 #include <iostream>
+
51 #include <string>
+
52 #endif // UNIT_TEST
+
53 
+
54 // Library Version
+
55 #define _IRREMOTEESP8266_VERSION_ "2.7.7"
+
56 
+
57 // Set the language & locale for the library. See the `locale` dir for options.
+
58 #ifndef _IR_LOCALE_
+
59 #define _IR_LOCALE_ en-AU
+
60 #endif // _IR_LOCALE_
+
61 
+
62 // Do we enable all the protocols by default (true), or disable them (false)?
+
63 // This allows users of the library to disable or enable all protocols at
+
64 // compile-time with `-D_IR_ENABLE_DEFAULT_=true` or
+
65 // `-D_IR_ENABLE_DEFAULT_=false` compiler flags respectively.
+
66 // Everything is included by default.
+
67 // e.g. If you only want to enable use of he NEC protocol to save program space,
+
68 // you would use something like:
+
69 // `-D_IR_ENABLE_DEFAULT_=false -DDECODE_NEC=true -DSEND_NEC=true`
+
70 //
+
71 // or alter your 'platform.ini' file accordingly:
+
72 // ```
+
73 // build_flags = -D_IR_ENABLE_DEFAULT_=false
+
74 // -DDECODE_NEC=true
+
75 // -DSEND_NEC=true
+
76 // ```
+
77 // If you want to enable support for every protocol *except* _decoding_ the
+
78 // Kelvinator protocol, you would use:
+
79 // `-DDECODE_KELVINATOR=false`
+
80 #ifndef _IR_ENABLE_DEFAULT_
+
81 #define _IR_ENABLE_DEFAULT_ true // Unless set externally, the default is on.
+
82 #endif // _IR_ENABLE_DEFAULT_
+
83 
+
84 // Supported IR protocols
+
85 // Each protocol you include costs memory and, during decode, costs time
+
86 // Disable (set to false) all the protocols you do not need/want!
+
87 // The Air Conditioner protocols are the most expensive memory-wise.
+
88 //
+
89 
+
90 // Semi-unique code for unknown messages
+
91 #ifndef DECODE_HASH
+
92 #define DECODE_HASH _IR_ENABLE_DEFAULT_
+
93 #endif // DECODE_HASH
+
94 
+
95 #ifndef SEND_RAW
+
96 #define SEND_RAW _IR_ENABLE_DEFAULT_
+
97 #endif // SEND_RAW
+
98 
+
99 #ifndef DECODE_NEC
+
100 #define DECODE_NEC _IR_ENABLE_DEFAULT_
+
101 #endif // DECODE_NEC
+
102 #ifndef SEND_NEC
+
103 #define SEND_NEC _IR_ENABLE_DEFAULT_
+
104 #endif // SEND_NEC
+
105 
+
106 #ifndef DECODE_SHERWOOD
+
107 #define DECODE_SHERWOOD false // Not applicable. Actually is DECODE_NEC
+
108 #endif // DECODE_SHERWOOD
+
109 #ifndef SEND_SHERWOOD
+
110 #define SEND_SHERWOOD _IR_ENABLE_DEFAULT_
+
111 #endif // SEND_SHERWOOD
+
112 
+
113 #ifndef DECODE_RC5
+
114 #define DECODE_RC5 _IR_ENABLE_DEFAULT_
+
115 #endif // DECODE_RC5
+
116 #ifndef SEND_RC5
+
117 #define SEND_RC5 _IR_ENABLE_DEFAULT_
+
118 #endif // SEND_RC5
+
119 
+
120 #ifndef DECODE_RC6
+
121 #define DECODE_RC6 _IR_ENABLE_DEFAULT_
+
122 #endif // DECODE_RC6
+
123 #ifndef SEND_RC6
+
124 #define SEND_RC6 _IR_ENABLE_DEFAULT_
+
125 #endif // SEND_RC6
+
126 
+
127 #ifndef DECODE_RCMM
+
128 #define DECODE_RCMM _IR_ENABLE_DEFAULT_
+
129 #endif // DECODE_RCMM
+
130 #ifndef SEND_RCMM
+
131 #define SEND_RCMM _IR_ENABLE_DEFAULT_
+
132 #endif // SEND_RCMM
+
133 
+
134 #ifndef DECODE_SONY
+
135 #define DECODE_SONY _IR_ENABLE_DEFAULT_
+
136 #endif // DECODE_SONY
+
137 #ifndef SEND_SONY
+
138 #define SEND_SONY _IR_ENABLE_DEFAULT_
+
139 #endif // SEND_SONY
+
140 
+
141 #ifndef DECODE_PANASONIC
+
142 #define DECODE_PANASONIC _IR_ENABLE_DEFAULT_
+
143 #endif // DECODE_PANASONIC
+
144 #ifndef SEND_PANASONIC
+
145 #define SEND_PANASONIC _IR_ENABLE_DEFAULT_
+
146 #endif // SEND_PANASONIC
+
147 
+
148 #ifndef DECODE_JVC
+
149 #define DECODE_JVC _IR_ENABLE_DEFAULT_
+
150 #endif // DECODE_JVC
+
151 #ifndef SEND_JVC
+
152 #define SEND_JVC _IR_ENABLE_DEFAULT_
+
153 #endif // SEND_JVC
+
154 
+
155 #ifndef DECODE_SAMSUNG
+
156 #define DECODE_SAMSUNG _IR_ENABLE_DEFAULT_
+
157 #endif // DECODE_SAMSUNG
+
158 #ifndef SEND_SAMSUNG
+
159 #define SEND_SAMSUNG _IR_ENABLE_DEFAULT_
+
160 #endif // SEND_SAMSUNG
+
161 
+
162 #ifndef DECODE_SAMSUNG36
+
163 #define DECODE_SAMSUNG36 _IR_ENABLE_DEFAULT_
+
164 #endif // DECODE_SAMSUNG36
+
165 #ifndef SEND_SAMSUNG36
+
166 #define SEND_SAMSUNG36 _IR_ENABLE_DEFAULT_
+
167 #endif // SEND_SAMSUNG36
+
168 
+
169 #ifndef DECODE_SAMSUNG_AC
+
170 #define DECODE_SAMSUNG_AC _IR_ENABLE_DEFAULT_
+
171 #endif // DECODE_SAMSUNG_AC
+
172 #ifndef SEND_SAMSUNG_AC
+
173 #define SEND_SAMSUNG_AC _IR_ENABLE_DEFAULT_
+
174 #endif // SEND_SAMSUNG_AC
+
175 
+
176 #ifndef DECODE_WHYNTER
+
177 #define DECODE_WHYNTER _IR_ENABLE_DEFAULT_
+
178 #endif // DECODE_WHYNTER
+
179 #ifndef SEND_WHYNTER
+
180 #define SEND_WHYNTER _IR_ENABLE_DEFAULT_
+
181 #endif // SEND_WHYNTER
+
182 
+
183 #ifndef DECODE_AIWA_RC_T501
+
184 #define DECODE_AIWA_RC_T501 _IR_ENABLE_DEFAULT_
+
185 #endif // DECODE_AIWA_RC_T501
+
186 #ifndef SEND_AIWA_RC_T501
+
187 #define SEND_AIWA_RC_T501 _IR_ENABLE_DEFAULT_
+
188 #endif // SEND_AIWA_RC_T501
+
189 
+
190 #ifndef DECODE_LG
+
191 #define DECODE_LG _IR_ENABLE_DEFAULT_
+
192 #endif // DECODE_LG
+
193 #ifndef SEND_LG
+
194 #define SEND_LG _IR_ENABLE_DEFAULT_
+
195 #endif // SEND_LG
+
196 
+
197 #ifndef DECODE_SANYO
+
198 #define DECODE_SANYO _IR_ENABLE_DEFAULT_
+
199 #endif // DECODE_SANYO
+
200 #ifndef SEND_SANYO
+
201 #define SEND_SANYO _IR_ENABLE_DEFAULT_
+
202 #endif // SEND_SANYO
+
203 
+
204 #ifndef DECODE_MITSUBISHI
+
205 #define DECODE_MITSUBISHI _IR_ENABLE_DEFAULT_
+
206 #endif // DECODE_MITSUBISHI
+
207 #ifndef SEND_MITSUBISHI
+
208 #define SEND_MITSUBISHI _IR_ENABLE_DEFAULT_
+
209 #endif // SEND_MITSUBISHI
+
210 
+
211 #ifndef DECODE_MITSUBISHI2
+
212 #define DECODE_MITSUBISHI2 _IR_ENABLE_DEFAULT_
+
213 #endif // DECODE_MITSUBISHI2
+
214 #ifndef SEND_MITSUBISHI2
+
215 #define SEND_MITSUBISHI2 _IR_ENABLE_DEFAULT_
+
216 #endif // SEND_MITSUBISHI2
+
217 
+
218 #ifndef DECODE_DISH
+
219 #define DECODE_DISH _IR_ENABLE_DEFAULT_
+
220 #endif // DECODE_DISH
+
221 #ifndef SEND_DISH
+
222 #define SEND_DISH _IR_ENABLE_DEFAULT_
+
223 #endif // SEND_DISH
+
224 
+
225 #ifndef DECODE_SHARP
+
226 #define DECODE_SHARP _IR_ENABLE_DEFAULT_
+
227 #endif // DECODE_SHARP
+
228 #ifndef SEND_SHARP
+
229 #define SEND_SHARP _IR_ENABLE_DEFAULT_
+
230 #endif // SEND_SHARP
+
231 
+
232 #ifndef DECODE_SHARP_AC
+
233 #define DECODE_SHARP_AC _IR_ENABLE_DEFAULT_
+
234 #endif // DECODE_SHARP_AC
+
235 #ifndef SEND_SHARP_AC
+
236 #define SEND_SHARP_AC _IR_ENABLE_DEFAULT_
+
237 #endif // SEND_SHARP_AC
+
238 
+
239 #ifndef DECODE_DENON
+
240 #define DECODE_DENON _IR_ENABLE_DEFAULT_
+
241 #endif // DECODE_DENON
+
242 #ifndef SEND_DENON
+
243 #define SEND_DENON _IR_ENABLE_DEFAULT_
+
244 #endif // SEND_DENON
+
245 
+
246 #ifndef DECODE_KELVINATOR
+
247 #define DECODE_KELVINATOR _IR_ENABLE_DEFAULT_
+
248 #endif // DECODE_KELVINATOR
+
249 #ifndef SEND_KELVINATOR
+
250 #define SEND_KELVINATOR _IR_ENABLE_DEFAULT_
+
251 #endif // SEND_KELVINATOR
+
252 
+
253 #ifndef DECODE_MITSUBISHI_AC
+
254 #define DECODE_MITSUBISHI_AC _IR_ENABLE_DEFAULT_
+
255 #endif // DECODE_MITSUBISHI_AC
+
256 #ifndef SEND_MITSUBISHI_AC
+
257 #define SEND_MITSUBISHI_AC _IR_ENABLE_DEFAULT_
+
258 #endif // SEND_MITSUBISHI_AC
+
259 
+
260 #ifndef DECODE_MITSUBISHI136
+
261 #define DECODE_MITSUBISHI136 _IR_ENABLE_DEFAULT_
+
262 #endif // DECODE_MITSUBISHI136
+
263 #ifndef SEND_MITSUBISHI136
+
264 #define SEND_MITSUBISHI136 _IR_ENABLE_DEFAULT_
+
265 #endif // SEND_MITSUBISHI136
+
266 
+
267 #ifndef DECODE_MITSUBISHI112
+
268 #define DECODE_MITSUBISHI112 _IR_ENABLE_DEFAULT_
+
269 #endif // DECODE_MITSUBISHI112
+
270 #ifndef SEND_MITSUBISHI112
+
271 #define SEND_MITSUBISHI112 _IR_ENABLE_DEFAULT_
+
272 #endif // SEND_MITSUBISHI112
+
273 
+
274 #ifndef DECODE_FUJITSU_AC
+
275 #define DECODE_FUJITSU_AC _IR_ENABLE_DEFAULT_
+
276 #endif // DECODE_FUJITSU_AC
+
277 #ifndef SEND_FUJITSU_AC
+
278 #define SEND_FUJITSU_AC _IR_ENABLE_DEFAULT_
+
279 #endif // SEND_FUJITSU_AC
+
280 
+
281 #ifndef DECODE_INAX
+
282 #define DECODE_INAX _IR_ENABLE_DEFAULT_
+
283 #endif // DECODE_INAX
+
284 #ifndef SEND_INAX
+
285 #define SEND_INAX _IR_ENABLE_DEFAULT_
+
286 #endif // SEND_INAX
+
287 
+
288 #ifndef DECODE_DAIKIN
+
289 #define DECODE_DAIKIN _IR_ENABLE_DEFAULT_
+
290 #endif // DECODE_DAIKIN
+
291 #ifndef SEND_DAIKIN
+
292 #define SEND_DAIKIN _IR_ENABLE_DEFAULT_
+
293 #endif // SEND_DAIKIN
+
294 
+
295 #ifndef DECODE_COOLIX
+
296 #define DECODE_COOLIX _IR_ENABLE_DEFAULT_
+
297 #endif // DECODE_COOLIX
+
298 #ifndef SEND_COOLIX
+
299 #define SEND_COOLIX _IR_ENABLE_DEFAULT_
+
300 #endif // SEND_COOLIX
+
301 
+
302 #ifndef DECODE_GLOBALCACHE
+
303 #define DECODE_GLOBALCACHE false // Not applicable.
+
304 #endif // DECODE_GLOBALCACHE
+
305 #ifndef SEND_GLOBALCACHE
+
306 #define SEND_GLOBALCACHE _IR_ENABLE_DEFAULT_
+
307 #endif // SEND_GLOBALCACHE
+
308 
+
309 #ifndef DECODE_GOODWEATHER
+
310 #define DECODE_GOODWEATHER _IR_ENABLE_DEFAULT_
+
311 #endif // DECODE_GOODWEATHER
+
312 #ifndef SEND_GOODWEATHER
+
313 #define SEND_GOODWEATHER _IR_ENABLE_DEFAULT_
+
314 #endif // SEND_GOODWEATHER
+
315 
+
316 #ifndef DECODE_GREE
+
317 #define DECODE_GREE _IR_ENABLE_DEFAULT_
+
318 #endif // DECODE_GREE
+
319 #ifndef SEND_GREE
+
320 #define SEND_GREE _IR_ENABLE_DEFAULT_
+
321 #endif // SEND_GREE
+
322 
+
323 #ifndef DECODE_PRONTO
+
324 #define DECODE_PRONTO false // Not applicable.
+
325 #endif // DECODE_PRONTO
+
326 #ifndef SEND_PRONTO
+
327 #define SEND_PRONTO _IR_ENABLE_DEFAULT_
+
328 #endif // SEND_PRONTO
+
329 
+
330 #ifndef DECODE_ARGO
+
331 #define DECODE_ARGO _IR_ENABLE_DEFAULT_
+
332 #endif // DECODE_ARGO
+
333 #ifndef SEND_ARGO
+
334 #define SEND_ARGO _IR_ENABLE_DEFAULT_
+
335 #endif // SEND_ARGO
+
336 
+
337 #ifndef DECODE_TROTEC
+
338 #define DECODE_TROTEC _IR_ENABLE_DEFAULT_
+
339 #endif // DECODE_TROTEC
+
340 #ifndef SEND_TROTEC
+
341 #define SEND_TROTEC _IR_ENABLE_DEFAULT_
+
342 #endif // SEND_TROTEC
+
343 
+
344 #ifndef DECODE_NIKAI
+
345 #define DECODE_NIKAI _IR_ENABLE_DEFAULT_
+
346 #endif // DECODE_NIKAI
+
347 #ifndef SEND_NIKAI
+
348 #define SEND_NIKAI _IR_ENABLE_DEFAULT_
+
349 #endif // SEND_NIKAI
+
350 
+
351 #ifndef DECODE_TOSHIBA_AC
+
352 #define DECODE_TOSHIBA_AC _IR_ENABLE_DEFAULT_
+
353 #endif // DECODE_TOSHIBA_AC
+
354 #ifndef SEND_TOSHIBA_AC
+
355 #define SEND_TOSHIBA_AC _IR_ENABLE_DEFAULT_
+
356 #endif // SEND_TOSHIBA_AC
+
357 
+
358 #ifndef DECODE_MAGIQUEST
+
359 #define DECODE_MAGIQUEST _IR_ENABLE_DEFAULT_
+
360 #endif // DECODE_MAGIQUEST
+
361 #ifndef SEND_MAGIQUEST
+
362 #define SEND_MAGIQUEST _IR_ENABLE_DEFAULT_
+
363 #endif // SEND_MAGIQUEST
+
364 
+
365 #ifndef DECODE_MIDEA
+
366 #define DECODE_MIDEA _IR_ENABLE_DEFAULT_
+
367 #endif // DECODE_MIDEA
+
368 #ifndef SEND_MIDEA
+
369 #define SEND_MIDEA _IR_ENABLE_DEFAULT_
+
370 #endif // SEND_MIDEA
+
371 
+
372 #ifndef DECODE_MIDEA24
+
373 #define DECODE_MIDEA24 _IR_ENABLE_DEFAULT_
+
374 #endif // DECODE_MIDEA24
+
375 #ifndef SEND_MIDEA24
+
376 #define SEND_MIDEA24 _IR_ENABLE_DEFAULT_
+
377 #endif // SEND_MIDEA24
+
378 
+
379 #ifndef DECODE_LASERTAG
+
380 #define DECODE_LASERTAG _IR_ENABLE_DEFAULT_
+
381 #endif // DECODE_LASERTAG
+
382 #ifndef SEND_LASERTAG
+
383 #define SEND_LASERTAG _IR_ENABLE_DEFAULT_
+
384 #endif // SEND_LASERTAG
+
385 
+
386 #ifndef DECODE_CARRIER_AC
+
387 #define DECODE_CARRIER_AC _IR_ENABLE_DEFAULT_
+
388 #endif // DECODE_CARRIER_AC
+
389 #ifndef SEND_CARRIER_AC
+
390 #define SEND_CARRIER_AC _IR_ENABLE_DEFAULT_
+
391 #endif // SEND_CARRIER_AC
+
392 
+
393 #ifndef DECODE_CARRIER_AC40
+
394 #define DECODE_CARRIER_AC40 _IR_ENABLE_DEFAULT_
+
395 #endif // DECODE_CARRIER_AC40
+
396 #ifndef SEND_CARRIER_AC40
+
397 #define SEND_CARRIER_AC40 _IR_ENABLE_DEFAULT_
+
398 #endif // SEND_CARRIER_AC40
+
399 
+
400 #ifndef DECODE_CARRIER_AC64
+
401 #define DECODE_CARRIER_AC64 _IR_ENABLE_DEFAULT_
+
402 #endif // DECODE_CARRIER_AC64
+
403 #ifndef SEND_CARRIER_AC64
+
404 #define SEND_CARRIER_AC64 _IR_ENABLE_DEFAULT_
+
405 #endif // SEND_CARRIER_AC64
+
406 
+
407 #ifndef DECODE_HAIER_AC
+
408 #define DECODE_HAIER_AC _IR_ENABLE_DEFAULT_
+
409 #endif // DECODE_HAIER_AC
+
410 #ifndef SEND_HAIER_AC
+
411 #define SEND_HAIER_AC _IR_ENABLE_DEFAULT_
+
412 #endif // SEND_HAIER_AC
+
413 
+
414 #ifndef DECODE_HITACHI_AC
+
415 #define DECODE_HITACHI_AC _IR_ENABLE_DEFAULT_
+
416 #endif // DECODE_HITACHI_AC
+
417 #ifndef SEND_HITACHI_AC
+
418 #define SEND_HITACHI_AC _IR_ENABLE_DEFAULT_
+
419 #endif // SEND_HITACHI_AC
+
420 
+
421 #ifndef DECODE_HITACHI_AC1
+
422 #define DECODE_HITACHI_AC1 _IR_ENABLE_DEFAULT_
+
423 #endif // DECODE_HITACHI_AC1
+
424 #ifndef SEND_HITACHI_AC1
+
425 #define SEND_HITACHI_AC1 _IR_ENABLE_DEFAULT_
+
426 #endif // SEND_HITACHI_AC1
+
427 
+
428 #ifndef DECODE_HITACHI_AC2
+
429 #define DECODE_HITACHI_AC2 _IR_ENABLE_DEFAULT_
+
430 #endif // DECODE_HITACHI_AC2
+
431 #ifndef SEND_HITACHI_AC2
+
432 #define SEND_HITACHI_AC2 _IR_ENABLE_DEFAULT_
+
433 #endif // SEND_HITACHI_AC2
+
434 
+
435 #ifndef DECODE_HITACHI_AC3
+
436 #define DECODE_HITACHI_AC3 _IR_ENABLE_DEFAULT_
+
437 #endif // DECODE_HITACHI_AC3
+
438 #ifndef SEND_HITACHI_AC3
+
439 #define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_
+
440 #endif // SEND_HITACHI_AC3
+
441 
+
442 #ifndef DECODE_HITACHI_AC344
+
443 #define DECODE_HITACHI_AC344 _IR_ENABLE_DEFAULT_
+
444 #endif // DECODE_HITACHI_AC344
+
445 #ifndef SEND_HITACHI_AC344
+
446 #define SEND_HITACHI_AC344 _IR_ENABLE_DEFAULT_
+
447 #endif // SEND_HITACHI_AC344
+
448 
+
449 #ifndef DECODE_HITACHI_AC424
+
450 #define DECODE_HITACHI_AC424 _IR_ENABLE_DEFAULT_
+
451 #endif // DECODE_HITACHI_AC424
+
452 #ifndef SEND_HITACHI_AC424
+
453 #define SEND_HITACHI_AC424 _IR_ENABLE_DEFAULT_
+
454 #endif // SEND_HITACHI_AC424
+
455 
+
456 #ifndef DECODE_GICABLE
+
457 #define DECODE_GICABLE _IR_ENABLE_DEFAULT_
+
458 #endif // DECODE_GICABLE
+
459 #ifndef SEND_GICABLE
+
460 #define SEND_GICABLE _IR_ENABLE_DEFAULT_
+
461 #endif // SEND_GICABLE
+
462 
+
463 #ifndef DECODE_HAIER_AC_YRW02
+
464 #define DECODE_HAIER_AC_YRW02 _IR_ENABLE_DEFAULT_
+
465 #endif // DECODE_HAIER_AC_YRW02
+
466 #ifndef SEND_HAIER_AC_YRW02
+
467 #define SEND_HAIER_AC_YRW02 _IR_ENABLE_DEFAULT_
+
468 #endif // SEND_HAIER_AC_YRW02
+
469 
+
470 #ifndef DECODE_WHIRLPOOL_AC
+
471 #define DECODE_WHIRLPOOL_AC _IR_ENABLE_DEFAULT_
+
472 #endif // DECODE_WHIRLPOOL_AC
+
473 #ifndef SEND_WHIRLPOOL_AC
+
474 #define SEND_WHIRLPOOL_AC _IR_ENABLE_DEFAULT_
+
475 #endif // SEND_WHIRLPOOL_AC
+
476 
+
477 #ifndef DECODE_LUTRON
+
478 #define DECODE_LUTRON _IR_ENABLE_DEFAULT_
+
479 #endif // DECODE_LUTRON
+
480 #ifndef SEND_LUTRON
+
481 #define SEND_LUTRON _IR_ENABLE_DEFAULT_
+
482 #endif // SEND_LUTRON
+
483 
+
484 #ifndef DECODE_ELECTRA_AC
+
485 #define DECODE_ELECTRA_AC _IR_ENABLE_DEFAULT_
+
486 #endif // DECODE_ELECTRA_AC
+
487 #ifndef SEND_ELECTRA_AC
+
488 #define SEND_ELECTRA_AC _IR_ENABLE_DEFAULT_
+
489 #endif // SEND_ELECTRA_AC
+
490 
+
491 #ifndef DECODE_PANASONIC_AC
+
492 #define DECODE_PANASONIC_AC _IR_ENABLE_DEFAULT_
+
493 #endif // DECODE_PANASONIC_AC
+
494 #ifndef SEND_PANASONIC_AC
+
495 #define SEND_PANASONIC_AC _IR_ENABLE_DEFAULT_
+
496 #endif // SEND_PANASONIC_AC
+
497 
+
498 #ifndef DECODE_MWM
+
499 #define DECODE_MWM _IR_ENABLE_DEFAULT_
+
500 #endif // DECODE_MWM
+
501 #ifndef SEND_MWM
+
502 #define SEND_MWM _IR_ENABLE_DEFAULT_
+
503 #endif // SEND_MWM
+
504 
+
505 #ifndef DECODE_PIONEER
+
506 #define DECODE_PIONEER _IR_ENABLE_DEFAULT_
+
507 #endif // DECODE_PIONEER
+
508 #ifndef SEND_PIONEER
+
509 #define SEND_PIONEER _IR_ENABLE_DEFAULT_
+
510 #endif // SEND_PIONEER
+
511 
+
512 #ifndef DECODE_DAIKIN2
+
513 #define DECODE_DAIKIN2 _IR_ENABLE_DEFAULT_
+
514 #endif // DECODE_DAIKIN2
+
515 #ifndef SEND_DAIKIN2
+
516 #define SEND_DAIKIN2 _IR_ENABLE_DEFAULT_
+
517 #endif // SEND_DAIKIN2
+
518 
+
519 #ifndef DECODE_VESTEL_AC
+
520 #define DECODE_VESTEL_AC _IR_ENABLE_DEFAULT_
+
521 #endif // DECODE_VESTEL_AC
+
522 #ifndef SEND_VESTEL_AC
+
523 #define SEND_VESTEL_AC _IR_ENABLE_DEFAULT_
+
524 #endif // SEND_VESTEL_AC
+
525 
+
526 #ifndef DECODE_TECO
+
527 #define DECODE_TECO _IR_ENABLE_DEFAULT_
+
528 #endif // DECODE_TECO
+
529 #ifndef SEND_TECO
+
530 #define SEND_TECO _IR_ENABLE_DEFAULT_
+
531 #endif // SEND_TECO
+
532 
+
533 #ifndef DECODE_TCL112AC
+
534 #define DECODE_TCL112AC _IR_ENABLE_DEFAULT_
+
535 #endif // DECODE_TCL112AC
+
536 #ifndef SEND_TCL112AC
+
537 #define SEND_TCL112AC _IR_ENABLE_DEFAULT_
+
538 #endif // SEND_TCL112AC
+
539 
+
540 #ifndef DECODE_LEGOPF
+
541 #define DECODE_LEGOPF _IR_ENABLE_DEFAULT_
+
542 #endif // DECODE_LEGOPF
+
543 #ifndef SEND_LEGOPF
+
544 #define SEND_LEGOPF _IR_ENABLE_DEFAULT_
+
545 #endif // SEND_LEGOPF
+
546 
+
547 #ifndef DECODE_MITSUBISHIHEAVY
+
548 #define DECODE_MITSUBISHIHEAVY _IR_ENABLE_DEFAULT_
+
549 #endif // DECODE_MITSUBISHIHEAVY
+
550 #ifndef SEND_MITSUBISHIHEAVY
+
551 #define SEND_MITSUBISHIHEAVY _IR_ENABLE_DEFAULT_
+
552 #endif // SEND_MITSUBISHIHEAVY
+
553 
+
554 #ifndef DECODE_DAIKIN216
+
555 #define DECODE_DAIKIN216 _IR_ENABLE_DEFAULT_
+
556 #endif // DECODE_DAIKIN216
+
557 #ifndef SEND_DAIKIN216
+
558 #define SEND_DAIKIN216 _IR_ENABLE_DEFAULT_
+
559 #endif // SEND_DAIKIN216
+
560 
+
561 #ifndef DECODE_DAIKIN160
+
562 #define DECODE_DAIKIN160 _IR_ENABLE_DEFAULT_
+
563 #endif // DECODE_DAIKIN160
+
564 #ifndef SEND_DAIKIN160
+
565 #define SEND_DAIKIN160 _IR_ENABLE_DEFAULT_
+
566 #endif // SEND_DAIKIN160
+
567 
+
568 #ifndef DECODE_NEOCLIMA
+
569 #define DECODE_NEOCLIMA _IR_ENABLE_DEFAULT_
+
570 #endif // DECODE_NEOCLIMA
+
571 #ifndef SEND_NEOCLIMA
+
572 #define SEND_NEOCLIMA _IR_ENABLE_DEFAULT_
+
573 #endif // SEND_NEOCLIMA
+
574 
+
575 #ifndef DECODE_DAIKIN176
+
576 #define DECODE_DAIKIN176 _IR_ENABLE_DEFAULT_
+
577 #endif // DECODE_DAIKIN176
+
578 #ifndef SEND_DAIKIN176
+
579 #define SEND_DAIKIN176 _IR_ENABLE_DEFAULT_
+
580 #endif // SEND_DAIKIN176
+
581 
+
582 #ifndef DECODE_DAIKIN128
+
583 #define DECODE_DAIKIN128 _IR_ENABLE_DEFAULT_
+
584 #endif // DECODE_DAIKIN128
+
585 #ifndef SEND_DAIKIN128
+
586 #define SEND_DAIKIN128 _IR_ENABLE_DEFAULT_
+
587 #endif // SEND_DAIKIN128
+
588 
+
589 #ifndef DECODE_AMCOR
+
590 #define DECODE_AMCOR _IR_ENABLE_DEFAULT_
+
591 #endif // DECODE_AMCOR
+
592 #ifndef SEND_AMCOR
+
593 #define SEND_AMCOR _IR_ENABLE_DEFAULT_
+
594 #endif // SEND_AMCOR
+
595 
+
596 #ifndef DECODE_DAIKIN152
+
597 #define DECODE_DAIKIN152 _IR_ENABLE_DEFAULT_
+
598 #endif // DECODE_DAIKIN152
+
599 #ifndef SEND_DAIKIN152
+
600 #define SEND_DAIKIN152 _IR_ENABLE_DEFAULT_
+
601 #endif // SEND_DAIKIN152
+
602 
+
603 #ifndef DECODE_EPSON
+
604 #define DECODE_EPSON _IR_ENABLE_DEFAULT_
+
605 #endif // DECODE_EPSON
+
606 #ifndef SEND_EPSON
+
607 #define SEND_EPSON _IR_ENABLE_DEFAULT_
+
608 #endif // SEND_EPSON
+
609 
+
610 #ifndef DECODE_SYMPHONY
+
611 #define DECODE_SYMPHONY _IR_ENABLE_DEFAULT_
+
612 #endif // DECODE_SYMPHONY
+
613 #ifndef SEND_SYMPHONY
+
614 #define SEND_SYMPHONY _IR_ENABLE_DEFAULT_
+
615 #endif // SEND_SYMPHONY
+
616 
+
617 #ifndef DECODE_DAIKIN64
+
618 #define DECODE_DAIKIN64 _IR_ENABLE_DEFAULT_
+
619 #endif // DECODE_DAIKIN64
+
620 #ifndef SEND_DAIKIN64
+
621 #define SEND_DAIKIN64 _IR_ENABLE_DEFAULT_
+
622 #endif // SEND_DAIKIN64
+
623 
+
624 #ifndef DECODE_AIRWELL
+
625 #define DECODE_AIRWELL _IR_ENABLE_DEFAULT_
+
626 #endif // DECODE_AIRWELL
+
627 #ifndef SEND_AIRWELL
+
628 #define SEND_AIRWELL _IR_ENABLE_DEFAULT_
+
629 #endif // SEND_AIRWELL
+
630 
+
631 #ifndef DECODE_DELONGHI_AC
+
632 #define DECODE_DELONGHI_AC _IR_ENABLE_DEFAULT_
+
633 #endif // DECODE_DELONGHI_AC
+
634 #ifndef SEND_DELONGHI_AC
+
635 #define SEND_DELONGHI_AC _IR_ENABLE_DEFAULT_
+
636 #endif // SEND_DELONGHI_AC
+
637 
+
638 #ifndef DECODE_DOSHISHA
+
639 #define DECODE_DOSHISHA _IR_ENABLE_DEFAULT_
+
640 #endif // DECODE_DOSHISHA
+
641 #ifndef SEND_DOSHISHA
+
642 #define SEND_DOSHISHA _IR_ENABLE_DEFAULT_
+
643 #endif // SEND_DOSHISHA
+
644 
+
645 #ifndef DECODE_MULTIBRACKETS
+
646 #define DECODE_MULTIBRACKETS _IR_ENABLE_DEFAULT_
+
647 #endif // DECODE_MULTIBRACKETS
+
648 #ifndef SEND_MULTIBRACKETS
+
649 #define SEND_MULTIBRACKETS _IR_ENABLE_DEFAULT_
+
650 #endif // SEND_MULTIBRACKETS
+
651 
+
652 #ifndef DECODE_CORONA_AC
+
653 #define DECODE_CORONA_AC _IR_ENABLE_DEFAULT_
+
654 #endif // DECODE_CORONA_AC
+
655 #ifndef SEND_CORONA_AC
+
656 #define SEND_CORONA_AC _IR_ENABLE_DEFAULT_
+
657 #endif // SEND_CORONA_AC
+
658 
+
659 #ifndef DECODE_ZEPEAL
+
660 #define DECODE_ZEPEAL _IR_ENABLE_DEFAULT_
+
661 #endif // DECODE_ZEPEAL
+
662 #ifndef SEND_ZEPEAL
+
663 #define SEND_ZEPEAL _IR_ENABLE_DEFAULT_
+
664 #endif // SEND_ZEPEAL
+
665 
+
666 #if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \
+
667  DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \
+
668  DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \
+
669  DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || DECODE_HAIER_AC_YRW02 || \
+
670  DECODE_WHIRLPOOL_AC || DECODE_SAMSUNG_AC || DECODE_ELECTRA_AC || \
+
671  DECODE_PANASONIC_AC || DECODE_MWM || DECODE_DAIKIN2 || \
+
672  DECODE_VESTEL_AC || DECODE_TCL112AC || DECODE_MITSUBISHIHEAVY || \
+
673  DECODE_DAIKIN216 || DECODE_SHARP_AC || DECODE_DAIKIN160 || \
+
674  DECODE_NEOCLIMA || DECODE_DAIKIN176 || DECODE_DAIKIN128 || \
+
675  DECODE_AMCOR || DECODE_DAIKIN152 || DECODE_MITSUBISHI136 || \
+
676  DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3 || \
+
677  DECODE_HITACHI_AC344 || DECODE_CORONA_AC)
+
678  // Add any DECODE to the above if it uses result->state (see kStateSizeMax)
+
679  // you might also want to add the protocol to hasACState function
+
680 #define DECODE_AC true // We need some common infrastructure for decoding A/Cs.
+
681 #else
+
682 #define DECODE_AC false // We don't need that infrastructure.
+
683 #endif
+
684 
+
685 // Use millisecond 'delay()' calls where we can to avoid tripping the WDT.
+
686 // Note: If you plan to send IR messages in the callbacks of the AsyncWebserver
+
687 // library, you need to set ALLOW_DELAY_CALLS to false.
+
688 // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/430
+
689 #ifndef ALLOW_DELAY_CALLS
+
690 #define ALLOW_DELAY_CALLS true
+
691 #endif // ALLOW_DELAY_CALLS
+
692 
+
693 // Enable a run-time settable high-pass filter on captured data **before**
+
694 // trying any protocol decoding.
+
695 // i.e. Try to remove/merge any really short pulses detected in the raw data.
+
696 // Note: Even when this option is enabled, it is _off_ by default, and requires
+
697 // a user who knows what they are doing to enable it.
+
698 // The option to disable this feature is here if your project is _really_
+
699 // tight on resources. i.e. Saves a small handful of bytes and cpu time.
+
700 // WARNING: If you use this feature at runtime, you can no longer trust the
+
701 // **raw** data captured. It will now have been slightly **cooked**!
+
702 // DANGER: If you set the `noise_floor` value too high, it **WILL** break
+
703 // decoding of some protocols. You have been warned. Here Be Dragons!
+
704 //
+
705 // See: `irrecv::decode()` in IRrecv.cpp for more info.
+
706 #ifndef ENABLE_NOISE_FILTER_OPTION
+
707 #define ENABLE_NOISE_FILTER_OPTION true
+
708 #endif // ENABLE_NOISE_FILTER_OPTION
+
709 
+ +
715  UNKNOWN = -1,
+
716  UNUSED = 0,
+ + + + +
721  PANASONIC, // (5)
+ + + + +
726  LG, // (10)
+ + + + +
731  COOLIX, // (15)
+ + + + +
736  MITSUBISHI_AC, // (20)
+ + + + +
741  PRONTO, // Technically not a protocol, but an encoding. (25)
+ + + + +
746  RAW, // Technically not a protocol, but an encoding. (30)
+
747  GLOBALCACHE, // Technically not a protocol, but an encoding.
+ + + +
751  MAGIQUEST, // (35)
+ + + + +
756  HITACHI_AC, // (40)
+ + + + +
761  WHIRLPOOL_AC, // (45)
+ + + + +
766  PIONEER, // (50)
+ + + + +
771  TECO, // (55)
+ + + + + + + + + +
781  DAIKIN160, // 65
+ + + + +
786  DAIKIN152, // 70
+ + + + +
791  EPSON, // 75
+ + + + +
796  DELONGHI_AC, // 80
+ + + + + + + + +
805  // Add new entries before this one, and update it to point to the last entry.
+ +
807 };
+
808 
+
809 // Message lengths & required repeat values
+
810 const uint16_t kNoRepeat = 0;
+
811 const uint16_t kSingleRepeat = 1;
+
812 
+
813 const uint16_t kAirwellBits = 34;
+
814 const uint16_t kAirwellMinRepeats = 2;
+
815 const uint16_t kAiwaRcT501Bits = 15;
+ +
817 const uint16_t kAlokaBits = 32;
+
818 const uint16_t kAmcorStateLength = 8;
+
819 const uint16_t kAmcorBits = kAmcorStateLength * 8;
+ +
821 const uint16_t kArgoStateLength = 12;
+
822 const uint16_t kArgoBits = kArgoStateLength * 8;
+
823 const uint16_t kArgoDefaultRepeat = kNoRepeat;
+
824 const uint16_t kCoolixBits = 24;
+ +
826 const uint16_t kCarrierAcBits = 32;
+ +
828 const uint16_t kCarrierAc40Bits = 40;
+
829 const uint16_t kCarrierAc40MinRepeat = 2;
+
830 const uint16_t kCarrierAc64Bits = 64;
+ +
832 const uint16_t kCoronaAcStateLengthShort = 7;
+ + +
835 const uint16_t kCoronaAcBits = kCoronaAcStateLength * 8;
+
836 const uint16_t kDaikinStateLength = 35;
+
837 const uint16_t kDaikinBits = kDaikinStateLength * 8;
+ + + +
841 const uint16_t kDaikin2StateLength = 39;
+
842 const uint16_t kDaikin2Bits = kDaikin2StateLength * 8;
+ +
844 const uint16_t kDaikin64Bits = 64;
+ +
846 const uint16_t kDaikin160StateLength = 20;
+ + +
849 const uint16_t kDaikin128StateLength = 16;
+ + +
852 const uint16_t kDaikin152StateLength = 19;
+ + +
855 const uint16_t kDaikin176StateLength = 22;
+ + +
858 const uint16_t kDaikin216StateLength = 27;
+ + +
861 const uint16_t kDelonghiAcBits = 64;
+ +
863 const uint16_t kDenonBits = 15;
+
864 const uint16_t kDenon48Bits = 48;
+
865 const uint16_t kDenonLegacyBits = 14;
+
866 const uint16_t kDishBits = 16;
+
867 const uint16_t kDishMinRepeat = 3;
+
868 const uint16_t kDoshishaBits = 40;
+
869 const uint16_t kEpsonBits = 32;
+
870 const uint16_t kEpsonMinRepeat = 2;
+
871 const uint16_t kElectraAcStateLength = 13;
+ + + +
875 const uint16_t kFujitsuAcStateLength = 16;
+
876 const uint16_t kFujitsuAcStateLengthShort = 7;
+ + +
879 const uint16_t kGicableBits = 16;
+ +
881 const uint16_t kGoodweatherBits = 48;
+ +
883 const uint16_t kGreeStateLength = 8;
+
884 const uint16_t kGreeBits = kGreeStateLength * 8;
+
885 const uint16_t kGreeDefaultRepeat = kNoRepeat;
+
886 const uint16_t kHaierACStateLength = 9;
+
887 const uint16_t kHaierACBits = kHaierACStateLength * 8;
+ +
889 const uint16_t kHaierACYRW02StateLength = 14;
+ + +
892 const uint16_t kHitachiAcStateLength = 28;
+ + +
895 const uint16_t kHitachiAc1StateLength = 13;
+ +
897 const uint16_t kHitachiAc2StateLength = 53;
+ +
899 const uint16_t kHitachiAc3StateLength = 27;
+ +
901 const uint16_t kHitachiAc3MinStateLength = 15;
+ +
903 const uint16_t kHitachiAc344StateLength = 43;
+ +
905 const uint16_t kHitachiAc424StateLength = 53;
+ +
907 const uint16_t kInaxBits = 24;
+
908 const uint16_t kInaxMinRepeat = kSingleRepeat;
+
909 const uint16_t kJvcBits = 16;
+
910 const uint16_t kKelvinatorStateLength = 16;
+ + +
913 const uint16_t kLasertagBits = 13;
+
914 const uint16_t kLasertagMinRepeat = kNoRepeat;
+
915 const uint16_t kLegoPfBits = 16;
+
916 const uint16_t kLegoPfMinRepeat = kNoRepeat;
+
917 const uint16_t kLgBits = 28;
+
918 const uint16_t kLg32Bits = 32;
+
919 const uint16_t kLgDefaultRepeat = kNoRepeat;
+
920 const uint16_t kLutronBits = 35;
+
921 const uint16_t kMagiquestBits = 56;
+
922 const uint16_t kMideaBits = 48;
+
923 const uint16_t kMideaMinRepeat = kNoRepeat;
+
924 const uint16_t kMidea24Bits = 24;
+ +
926 const uint16_t kMitsubishiBits = 16;
+
927 // TODO(anyone): Verify that the Mitsubishi repeat is really needed.
+
928 // Based on marcosamarinho's code.
+ +
930 const uint16_t kMitsubishiACStateLength = 18;
+ + +
933 const uint16_t kMitsubishi136StateLength = 17;
+ + +
936 const uint16_t kMitsubishi112StateLength = 14;
+ + +
939 const uint16_t kMitsubishiHeavy88StateLength = 11;
+ + +
942 const uint16_t kMitsubishiHeavy152StateLength = 19;
+ + +
945 const uint16_t kMultibracketsBits = 8;
+ +
947 const uint16_t kNikaiBits = 24;
+
948 const uint16_t kNECBits = 32;
+
949 const uint16_t kNeoclimaStateLength = 12;
+
950 const uint16_t kNeoclimaBits = kNeoclimaStateLength * 8;
+
951 const uint16_t kNeoclimaMinRepeat = kNoRepeat;
+
952 const uint16_t kPanasonicBits = 48;
+
953 const uint32_t kPanasonicManufacturer = 0x4004;
+
954 const uint16_t kPanasonicAcStateLength = 27;
+
955 const uint16_t kPanasonicAcStateShortLength = 16;
+ + + +
959 const uint16_t kPioneerBits = 64;
+
960 const uint16_t kProntoMinLength = 6;
+
961 const uint16_t kRC5RawBits = 14;
+
962 const uint16_t kRC5Bits = kRC5RawBits - 2;
+
963 const uint16_t kRC5XBits = kRC5RawBits - 1;
+
964 const uint16_t kRC6Mode0Bits = 20; // Excludes the 'start' bit.
+
965 const uint16_t kRC6_36Bits = 36; // Excludes the 'start' bit.
+
966 const uint16_t kRCMMBits = 24;
+
967 const uint16_t kSamsungBits = 32;
+
968 const uint16_t kSamsung36Bits = 36;
+
969 const uint16_t kSamsungAcStateLength = 14;
+ +
971 const uint16_t kSamsungAcExtendedStateLength = 21;
+ + +
974 const uint16_t kSanyoSA8650BBits = 12;
+
975 const uint16_t kSanyoLC7461AddressBits = 13;
+
976 const uint16_t kSanyoLC7461CommandBits = 8;
+ + +
979 const uint8_t kSharpAddressBits = 5;
+
980 const uint8_t kSharpCommandBits = 8;
+
981 const uint16_t kSharpBits = kSharpAddressBits + kSharpCommandBits + 2; // 15
+
982 const uint16_t kSharpAcStateLength = 13;
+
983 const uint16_t kSharpAcBits = kSharpAcStateLength * 8; // 104
+ +
985 const uint8_t kSherwoodBits = kNECBits;
+ +
987 const uint16_t kSony12Bits = 12;
+
988 const uint16_t kSony15Bits = 15;
+
989 const uint16_t kSony20Bits = 20;
+
990 const uint16_t kSonyMinBits = 12;
+
991 const uint16_t kSonyMinRepeat = 2;
+
992 const uint16_t kSymphonyBits = 12;
+
993 const uint16_t kSymphonyDefaultRepeat = 3;
+
994 const uint16_t kTcl112AcStateLength = 14;
+
995 const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8;
+ +
997 const uint16_t kTecoBits = 35;
+
998 const uint16_t kTecoDefaultRepeat = kNoRepeat;
+
999 const uint16_t kToshibaACStateLength = 9;
+ + +
1002 const uint16_t kTrotecStateLength = 9;
+
1003 const uint16_t kTrotecBits = kTrotecStateLength * 8;
+ +
1005 const uint16_t kWhirlpoolAcStateLength = 21;
+ + +
1008 const uint16_t kWhynterBits = 32;
+
1009 const uint8_t kVestelAcBits = 56;
+
1010 const uint16_t kZepealBits = 16;
+
1011 const uint16_t kZepealMinRepeat = 4;
+
1012 
+
1013 
+
1014 // Legacy defines. (Deprecated)
+
1015 #define AIWA_RC_T501_BITS kAiwaRcT501Bits
+
1016 #define ARGO_COMMAND_LENGTH kArgoStateLength
+
1017 #define COOLIX_BITS kCoolixBits
+
1018 #define CARRIER_AC_BITS kCarrierAcBits
+
1019 #define DAIKIN_COMMAND_LENGTH kDaikinStateLength
+
1020 #define DENON_BITS kDenonBits
+
1021 #define DENON_48_BITS kDenon48Bits
+
1022 #define DENON_LEGACY_BITS kDenonLegacyBits
+
1023 #define DISH_BITS kDishBits
+
1024 #define FUJITSU_AC_MIN_REPEAT kFujitsuAcMinRepeat
+
1025 #define FUJITSU_AC_STATE_LENGTH kFujitsuAcStateLength
+
1026 #define FUJITSU_AC_STATE_LENGTH_SHORT kFujitsuAcStateLengthShort
+
1027 #define FUJITSU_AC_BITS kFujitsuAcBits
+
1028 #define FUJITSU_AC_MIN_BITS kFujitsuAcMinBits
+
1029 #define GICABLE_BITS kGicableBits
+
1030 #define GREE_STATE_LENGTH kGreeStateLength
+
1031 #define HAIER_AC_STATE_LENGTH kHaierACStateLength
+
1032 #define HAIER_AC_YRW02_STATE_LENGTH kHaierACYRW02StateLength
+
1033 #define HITACHI_AC_STATE_LENGTH kHitachiAcStateLength
+
1034 #define HITACHI_AC_BITS kHitachiAcBits
+
1035 #define HITACHI_AC1_STATE_LENGTH kHitachiAc1StateLength
+
1036 #define HITACHI_AC1_BITS kHitachiAc1Bits
+
1037 #define HITACHI_AC2_STATE_LENGTH kHitachiAc2StateLength
+
1038 #define HITACHI_AC2_BITS kHitachiAc2Bits
+
1039 #define JVC_BITS kJvcBits
+
1040 #define KELVINATOR_STATE_LENGTH kKelvinatorStateLength
+
1041 #define LASERTAG_BITS kLasertagBits
+
1042 #define LG_BITS kLgBits
+
1043 #define LG32_BITS kLg32Bits
+
1044 #define MAGIQUEST_BITS kMagiquestBits
+
1045 #define MIDEA_BITS kMideaBits
+
1046 #define MITSUBISHI_BITS kMitsubishiBits
+
1047 #define MITSUBISHI_AC_STATE_LENGTH kMitsubishiACStateLength
+
1048 #define NEC_BITS kNECBits
+
1049 #define NIKAI_BITS kNikaiBits
+
1050 #define PANASONIC_BITS kPanasonicBits
+
1051 #define RC5_BITS kRC5Bits
+
1052 #define RC5X_BITS kRC5XBits
+
1053 #define RC6_MODE0_BITS kRC6Mode0Bits
+
1054 #define RC6_36_BITS kRC6_36Bits
+
1055 #define RCMM_BITS kRCMMBits
+
1056 #define SANYO_LC7461_BITS kSanyoLC7461Bits
+
1057 #define SAMSUNG_BITS kSamsungBits
+
1058 #define SANYO_SA8650B_BITS kSanyoSA8650BBits
+
1059 #define SHARP_BITS kSharpBits
+
1060 #define SHERWOOD_BITS kSherwoodBits
+
1061 #define SONY_12_BITS kSony12Bits
+
1062 #define SONY_15_BITS kSony15Bits
+
1063 #define SONY_20_BITS kSony20Bits
+
1064 #define TOSHIBA_AC_STATE_LENGTH kToshibaACStateLength
+
1065 #define TROTEC_COMMAND_LENGTH kTrotecStateLength
+
1066 #define WHYNTER_BITS kWhynterBits
+
1067 
+
1068 // Turn on Debugging information by uncommenting the following line.
+
1069 // #define DEBUG 1
+
1070 
+
1071 #ifdef DEBUG
+
1072 #ifdef UNIT_TEST
+
1073 #define DPRINT(x) do { std::cout << x; } while (0)
+
1074 #define DPRINTLN(x) do { std::cout << x << std::endl; } while (0)
+
1075 #endif // UNIT_TEST
+
1076 #ifdef ARDUINO
+
1077 #define DPRINT(x) do { Serial.print(x); } while (0)
+
1078 #define DPRINTLN(x) do { Serial.println(x); } while (0)
+
1079 #endif // ARDUINO
+
1080 #else // DEBUG
+
1081 #define DPRINT(x)
+
1082 #define DPRINTLN(x)
+
1083 #endif // DEBUG
+
1084 
+
1085 #ifdef UNIT_TEST
+
1086 #ifndef F
+
1087 // Create a no-op F() macro so the code base still compiles outside of the
+
1088 // Arduino framework. Thus we can safely use the Arduino 'F()' macro through-out
+
1089 // the code base. That macro stores constants in Flash (PROGMEM) memory.
+
1090 // See: https://github.com/crankyoldgit/IRremoteESP8266/issues/667
+
1091 #define F(x) x
+
1092 #endif // F
+
1093 typedef std::string String;
+
1094 #endif // UNIT_TEST
+
1095 
+
1096 #endif // IRREMOTEESP8266_H_
+
+
@ ARGO
Definition: IRremoteESP8266.h:743
+
const uint16_t kDaikin152DefaultRepeat
Definition: IRremoteESP8266.h:854
+
const uint16_t kSanyoSA8650BBits
Definition: IRremoteESP8266.h:974
+
const uint16_t kDelonghiAcBits
Definition: IRremoteESP8266.h:861
+
const uint16_t kHaierAcYrw02DefaultRepeat
Definition: IRremoteESP8266.h:891
+
const uint16_t kHitachiAc3MinStateLength
Definition: IRremoteESP8266.h:901
+
const uint16_t kMitsubishiACStateLength
Definition: IRremoteESP8266.h:930
+
const uint16_t kMitsubishiHeavy152StateLength
Definition: IRremoteESP8266.h:942
+
const uint16_t kAirwellMinRepeats
Definition: IRremoteESP8266.h:814
+
const uint16_t kMideaMinRepeat
Definition: IRremoteESP8266.h:923
+
const uint16_t kGicableBits
Definition: IRremoteESP8266.h:879
+
const uint16_t kGreeStateLength
Definition: IRremoteESP8266.h:883
+
@ DISH
Definition: IRremoteESP8266.h:729
+
@ UNUSED
Definition: IRremoteESP8266.h:716
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
const uint16_t kCarrierAcBits
Definition: IRremoteESP8266.h:826
+
const uint16_t kDenonLegacyBits
Definition: IRremoteESP8266.h:865
+
@ SHERWOOD
Definition: IRremoteESP8266.h:735
+
const uint16_t kSingleRepeat
Definition: IRremoteESP8266.h:811
+
const uint16_t kDaikin2DefaultRepeat
Definition: IRremoteESP8266.h:843
+
const uint16_t kMultibracketsBits
Definition: IRremoteESP8266.h:945
+
const uint16_t kSharpAcBits
Definition: IRremoteESP8266.h:983
+
const uint16_t kWhynterBits
Definition: IRremoteESP8266.h:1008
+
@ CARRIER_AC
Definition: IRremoteESP8266.h:753
+
@ TOSHIBA_AC
Definition: IRremoteESP8266.h:748
+
@ AIRWELL
Definition: IRremoteESP8266.h:795
+
const uint16_t kAirwellBits
Definition: IRremoteESP8266.h:813
+
const uint16_t kHaierAcDefaultRepeat
Definition: IRremoteESP8266.h:888
+
@ PRONTO
Definition: IRremoteESP8266.h:741
+
const uint16_t kTrotecDefaultRepeat
Definition: IRremoteESP8266.h:1004
+
const uint16_t kFujitsuAcMinRepeat
Definition: IRremoteESP8266.h:874
+
const uint16_t kCoronaAcBits
Definition: IRremoteESP8266.h:835
+
const uint16_t kMitsubishiACBits
Definition: IRremoteESP8266.h:931
+
const uint16_t kMitsubishi136MinRepeat
Definition: IRremoteESP8266.h:935
+
@ UNKNOWN
Definition: IRremoteESP8266.h:715
+
const uint16_t kArgoDefaultRepeat
Definition: IRremoteESP8266.h:823
+
const uint16_t kHaierACStateLength
Definition: IRremoteESP8266.h:886
+
const uint16_t kHitachiAcStateLength
Definition: IRremoteESP8266.h:892
+
@ MITSUBISHI112
Definition: IRremoteESP8266.h:788
+
const uint16_t kDaikin176StateLength
Definition: IRremoteESP8266.h:855
+
const uint16_t kRC5XBits
Definition: IRremoteESP8266.h:963
+
const uint16_t kEpsonMinRepeat
Definition: IRremoteESP8266.h:870
+
const uint16_t kAmcorStateLength
Definition: IRremoteESP8266.h:818
+
@ DAIKIN128
Definition: IRremoteESP8266.h:784
+
const uint16_t kAlokaBits
Definition: IRremoteESP8266.h:817
+
@ JVC
Definition: IRremoteESP8266.h:722
+
@ SONY
Definition: IRremoteESP8266.h:720
+
@ HITACHI_AC2
Definition: IRremoteESP8266.h:758
+
const uint16_t kHitachiAc1StateLength
Definition: IRremoteESP8266.h:895
+
const uint16_t kCoolixBits
Definition: IRremoteESP8266.h:824
+
const uint16_t kMitsubishi112MinRepeat
Definition: IRremoteESP8266.h:938
+
const uint16_t kCoronaAcBitsShort
Definition: IRremoteESP8266.h:834
+
const uint16_t kSamsung36Bits
Definition: IRremoteESP8266.h:968
+
const uint16_t kMagiquestBits
Definition: IRremoteESP8266.h:921
+
@ LUTRON
Definition: IRremoteESP8266.h:763
+
const uint8_t kSharpCommandBits
Definition: IRremoteESP8266.h:980
+
const uint16_t kNeoclimaStateLength
Definition: IRremoteESP8266.h:949
+
@ RCMM
Definition: IRremoteESP8266.h:737
+
@ SANYO_LC7461
Definition: IRremoteESP8266.h:738
+
@ TROTEC
Definition: IRremoteESP8266.h:744
+
const uint16_t kFujitsuAcMinBits
Definition: IRremoteESP8266.h:878
+
const uint16_t kSamsungAcDefaultRepeat
Definition: IRremoteESP8266.h:973
+
const uint16_t kSanyoLC7461Bits
Definition: IRremoteESP8266.h:977
+
@ DAIKIN160
Definition: IRremoteESP8266.h:781
+
@ CORONA_AC
Definition: IRremoteESP8266.h:802
+
const uint16_t kSanyoLC7461CommandBits
Definition: IRremoteESP8266.h:976
+
const uint16_t kTrotecBits
Definition: IRremoteESP8266.h:1003
+
@ PANASONIC
Definition: IRremoteESP8266.h:721
+
const uint16_t kZepealMinRepeat
Definition: IRremoteESP8266.h:1011
+
const uint16_t kDenon48Bits
Definition: IRremoteESP8266.h:864
+
@ DAIKIN2
Definition: IRremoteESP8266.h:769
+
const uint16_t kHitachiAc2Bits
Definition: IRremoteESP8266.h:898
+
const uint16_t kElectraAcMinRepeat
Definition: IRremoteESP8266.h:873
+
@ MITSUBISHI_AC
Definition: IRremoteESP8266.h:736
+
@ MAGIQUEST
Definition: IRremoteESP8266.h:751
+
const uint16_t kHitachiAc3StateLength
Definition: IRremoteESP8266.h:899
+
const uint16_t kLg32Bits
Definition: IRremoteESP8266.h:918
+
@ DOSHISHA
Definition: IRremoteESP8266.h:797
+
const uint16_t kCoronaAcStateLengthShort
Definition: IRremoteESP8266.h:832
+
const uint16_t kElectraAcBits
Definition: IRremoteESP8266.h:872
+
const uint16_t kSonyMinBits
Definition: IRremoteESP8266.h:990
+
@ HAIER_AC_YRW02
Definition: IRremoteESP8266.h:760
+
const uint16_t kAiwaRcT501MinRepeats
Definition: IRremoteESP8266.h:816
+
@ HITACHI_AC424
Definition: IRremoteESP8266.h:789
+
const uint16_t kDaikin2Bits
Definition: IRremoteESP8266.h:842
+
const uint16_t kHitachiAc1Bits
Definition: IRremoteESP8266.h:896
+
@ CARRIER_AC64
Definition: IRremoteESP8266.h:800
+
@ NEC
Definition: IRremoteESP8266.h:719
+
@ FUJITSU_AC
Definition: IRremoteESP8266.h:749
+
const uint16_t kMitsubishiMinRepeat
Definition: IRremoteESP8266.h:929
+
@ GOODWEATHER
Definition: IRremoteESP8266.h:779
+
@ HITACHI_AC3
Definition: IRremoteESP8266.h:793
+
@ INAX
Definition: IRremoteESP8266.h:780
+
const uint16_t kArgoStateLength
Definition: IRremoteESP8266.h:821
+
@ SYMPHONY
Definition: IRremoteESP8266.h:792
+
const uint16_t kPanasonicBits
Definition: IRremoteESP8266.h:952
+
std::string String
Definition: IRremoteESP8266.h:1093
+
@ HAIER_AC
Definition: IRremoteESP8266.h:754
+
const uint16_t kDaikinStateLengthShort
Definition: IRremoteESP8266.h:838
+
const uint16_t kRC5Bits
Definition: IRremoteESP8266.h:962
+
const uint16_t kLgDefaultRepeat
Definition: IRremoteESP8266.h:919
+
const uint16_t kDaikin152StateLength
Definition: IRremoteESP8266.h:852
+
const uint16_t kPanasonicAcBits
Definition: IRremoteESP8266.h:956
+
const uint16_t kRC5RawBits
Definition: IRremoteESP8266.h:961
+
const uint16_t kHaierACYRW02StateLength
Definition: IRremoteESP8266.h:889
+
const uint16_t kSanyoLC7461AddressBits
Definition: IRremoteESP8266.h:975
+
const uint16_t kMultibracketsDefaultRepeat
Definition: IRremoteESP8266.h:946
+
@ LG
Definition: IRremoteESP8266.h:726
+
const uint16_t kDaikin160Bits
Definition: IRremoteESP8266.h:847
+
@ HITACHI_AC344
Definition: IRremoteESP8266.h:801
+
@ MIDEA
Definition: IRremoteESP8266.h:750
+
const uint16_t kGoodweatherBits
Definition: IRremoteESP8266.h:881
+
const uint16_t kGicableMinRepeat
Definition: IRremoteESP8266.h:880
+
@ GLOBALCACHE
Definition: IRremoteESP8266.h:747
+
const uint16_t kDaikin152Bits
Definition: IRremoteESP8266.h:853
+
const uint16_t kDaikin216StateLength
Definition: IRremoteESP8266.h:858
+
@ GICABLE
Definition: IRremoteESP8266.h:759
+
const uint16_t kSamsungAcStateLength
Definition: IRremoteESP8266.h:969
+
@ COOLIX
Definition: IRremoteESP8266.h:731
+
@ MIDEA24
Definition: IRremoteESP8266.h:803
+
const uint16_t kSymphonyBits
Definition: IRremoteESP8266.h:992
+
const uint16_t kDaikin128StateLength
Definition: IRremoteESP8266.h:849
+
const uint16_t kRC6Mode0Bits
Definition: IRremoteESP8266.h:964
+
@ NEOCLIMA
Definition: IRremoteESP8266.h:782
+
const uint16_t kDaikin176DefaultRepeat
Definition: IRremoteESP8266.h:857
+
const uint16_t kMitsubishiHeavy152MinRepeat
Definition: IRremoteESP8266.h:944
+
const uint16_t kSony12Bits
Definition: IRremoteESP8266.h:987
+
const uint16_t kNoRepeat
Definition: IRremoteESP8266.h:810
+
const uint16_t kSony20Bits
Definition: IRremoteESP8266.h:989
+
const uint16_t kMitsubishiACMinRepeat
Definition: IRremoteESP8266.h:932
+
@ MULTIBRACKETS
Definition: IRremoteESP8266.h:798
+
const uint16_t kHitachiAc3MinBits
Definition: IRremoteESP8266.h:902
+
const uint16_t kPanasonicAcDefaultRepeat
Definition: IRremoteESP8266.h:958
+
const uint16_t kSymphonyDefaultRepeat
Definition: IRremoteESP8266.h:993
+
const uint16_t kSamsungAcExtendedStateLength
Definition: IRremoteESP8266.h:971
+
const uint16_t kCoolixDefaultRepeat
Definition: IRremoteESP8266.h:825
+
@ DENON
Definition: IRremoteESP8266.h:733
+
const uint16_t kTcl112AcDefaultRepeat
Definition: IRremoteESP8266.h:996
+
const uint16_t kDelonghiAcDefaultRepeat
Definition: IRremoteESP8266.h:862
+
const uint16_t kCoronaAcStateLength
Definition: IRremoteESP8266.h:833
+
@ SANYO
Definition: IRremoteESP8266.h:727
+
const uint16_t kTecoDefaultRepeat
Definition: IRremoteESP8266.h:998
+
const uint16_t kMitsubishiHeavy152Bits
Definition: IRremoteESP8266.h:943
+
const uint16_t kDoshishaBits
Definition: IRremoteESP8266.h:868
+
const uint16_t kCarrierAc40Bits
Definition: IRremoteESP8266.h:828
+
const uint16_t kAmcorBits
Definition: IRremoteESP8266.h:819
+
const uint16_t kTrotecStateLength
Definition: IRremoteESP8266.h:1002
+
@ LG2
Definition: IRremoteESP8266.h:767
+
const uint16_t kWhirlpoolAcDefaultRepeat
Definition: IRremoteESP8266.h:1007
+
const uint16_t kHitachiAc424StateLength
Definition: IRremoteESP8266.h:905
+
const uint16_t kMitsubishiHeavy88StateLength
Definition: IRremoteESP8266.h:939
+
@ RC5X
Definition: IRremoteESP8266.h:739
+
@ LASERTAG
Definition: IRremoteESP8266.h:752
+
const uint16_t kFujitsuAcStateLengthShort
Definition: IRremoteESP8266.h:876
+
const uint32_t kPanasonicManufacturer
Definition: IRremoteESP8266.h:953
+
@ RAW
Definition: IRremoteESP8266.h:746
+
const uint16_t kMitsubishiBits
Definition: IRremoteESP8266.h:926
+
@ SONY_38K
Definition: IRremoteESP8266.h:790
+
@ RC6
Definition: IRremoteESP8266.h:718
+
@ PIONEER
Definition: IRremoteESP8266.h:766
+
const uint16_t kPanasonicAcStateLength
Definition: IRremoteESP8266.h:954
+
@ MITSUBISHI2
Definition: IRremoteESP8266.h:755
+
const uint16_t kFujitsuAcStateLength
Definition: IRremoteESP8266.h:875
+
const uint16_t kSamsungAcBits
Definition: IRremoteESP8266.h:970
+
const uint16_t kMideaBits
Definition: IRremoteESP8266.h:922
+
const uint16_t kKelvinatorStateLength
Definition: IRremoteESP8266.h:910
+
const uint16_t kKelvinatorBits
Definition: IRremoteESP8266.h:911
+
@ LEGOPF
Definition: IRremoteESP8266.h:774
+
@ WHYNTER
Definition: IRremoteESP8266.h:724
+
const uint16_t kDaikin216DefaultRepeat
Definition: IRremoteESP8266.h:860
+
@ AMCOR
Definition: IRremoteESP8266.h:785
+
const uint16_t kWhirlpoolAcStateLength
Definition: IRremoteESP8266.h:1005
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint16_t kDenonBits
Definition: IRremoteESP8266.h:863
+
const uint16_t kHaierACBits
Definition: IRremoteESP8266.h:887
+
const uint16_t kZepealBits
Definition: IRremoteESP8266.h:1010
+
@ TCL112AC
Definition: IRremoteESP8266.h:773
+
const uint16_t kSony15Bits
Definition: IRremoteESP8266.h:988
+
const uint16_t kCarrierAc40MinRepeat
Definition: IRremoteESP8266.h:829
+
const uint16_t kMidea24Bits
Definition: IRremoteESP8266.h:924
+
const uint16_t kDaikin160DefaultRepeat
Definition: IRremoteESP8266.h:848
+
const uint16_t kToshibaACMinRepeat
Definition: IRremoteESP8266.h:1001
+
const uint16_t kSamsungAcExtendedBits
Definition: IRremoteESP8266.h:972
+
const uint16_t kHitachiAc344StateLength
Definition: IRremoteESP8266.h:903
+
const uint16_t kNeoclimaBits
Definition: IRremoteESP8266.h:950
+
const uint16_t kWhirlpoolAcBits
Definition: IRremoteESP8266.h:1006
+
const uint16_t kHitachiAc344Bits
Definition: IRremoteESP8266.h:904
+
const uint16_t kRC6_36Bits
Definition: IRremoteESP8266.h:965
+
@ DAIKIN176
Definition: IRremoteESP8266.h:783
+
const uint16_t kCarrierAc64Bits
Definition: IRremoteESP8266.h:830
+
const uint16_t kDaikin128DefaultRepeat
Definition: IRremoteESP8266.h:851
+
const uint16_t kPioneerBits
Definition: IRremoteESP8266.h:959
+
const uint16_t kSharpAcStateLength
Definition: IRremoteESP8266.h:982
+
@ MITSUBISHI_HEAVY_88
Definition: IRremoteESP8266.h:775
+
const uint16_t kGreeBits
Definition: IRremoteESP8266.h:884
+
const uint16_t kJvcBits
Definition: IRremoteESP8266.h:909
+
const uint16_t kDaikinStateLength
Definition: IRremoteESP8266.h:836
+
const uint16_t kLasertagBits
Definition: IRremoteESP8266.h:913
+
const uint16_t kDaikin128Bits
Definition: IRremoteESP8266.h:850
+
const uint16_t kAiwaRcT501Bits
Definition: IRremoteESP8266.h:815
+
const uint16_t kToshibaACStateLength
Definition: IRremoteESP8266.h:999
+
const uint16_t kTecoBits
Definition: IRremoteESP8266.h:997
+
const uint16_t kInaxMinRepeat
Definition: IRremoteESP8266.h:908
+
const uint16_t kPanasonicAcStateShortLength
Definition: IRremoteESP8266.h:955
+
@ CARRIER_AC40
Definition: IRremoteESP8266.h:799
+
const uint16_t kToshibaACBits
Definition: IRremoteESP8266.h:1000
+
const uint8_t kSherwoodBits
Definition: IRremoteESP8266.h:985
+
@ DAIKIN152
Definition: IRremoteESP8266.h:786
+
@ NEC_LIKE
Definition: IRremoteESP8266.h:742
+
const uint16_t kDaikinDefaultRepeat
Definition: IRremoteESP8266.h:840
+
const uint16_t kDaikin64DefaultRepeat
Definition: IRremoteESP8266.h:845
+
@ SAMSUNG
Definition: IRremoteESP8266.h:723
+
@ AIWA_RC_T501
Definition: IRremoteESP8266.h:725
+
@ MITSUBISHI_HEAVY_152
Definition: IRremoteESP8266.h:776
+
@ VESTEL_AC
Definition: IRremoteESP8266.h:770
+
const uint16_t kDaikinBits
Definition: IRremoteESP8266.h:837
+
@ GREE
Definition: IRremoteESP8266.h:740
+
const uint16_t kHitachiAcBits
Definition: IRremoteESP8266.h:893
+
const uint16_t kMitsubishiHeavy88MinRepeat
Definition: IRremoteESP8266.h:941
+
const uint16_t kHitachiAc3Bits
Definition: IRremoteESP8266.h:900
+
const uint16_t kHitachiAcDefaultRepeat
Definition: IRremoteESP8266.h:894
+
@ NIKAI
Definition: IRremoteESP8266.h:745
+
const uint16_t kMidea24MinRepeat
Definition: IRremoteESP8266.h:925
+
const uint16_t kDishBits
Definition: IRremoteESP8266.h:866
+
@ WHIRLPOOL_AC
Definition: IRremoteESP8266.h:761
+
const uint16_t kDishMinRepeat
Definition: IRremoteESP8266.h:867
+
const uint16_t kFujitsuAcBits
Definition: IRremoteESP8266.h:877
+
const uint16_t kArgoBits
Definition: IRremoteESP8266.h:822
+
@ RC5
Definition: IRremoteESP8266.h:717
+
const uint16_t kHitachiAc2StateLength
Definition: IRremoteESP8266.h:897
+
@ HITACHI_AC
Definition: IRremoteESP8266.h:756
+
@ SHARP_AC
Definition: IRremoteESP8266.h:778
+
@ HITACHI_AC1
Definition: IRremoteESP8266.h:757
+
const uint16_t kMitsubishiHeavy88Bits
Definition: IRremoteESP8266.h:940
+
const uint16_t kCarrierAcMinRepeat
Definition: IRremoteESP8266.h:827
+
@ ZEPEAL
Definition: IRremoteESP8266.h:804
+
const uint16_t kNikaiBits
Definition: IRremoteESP8266.h:947
+
const uint16_t kKelvinatorDefaultRepeat
Definition: IRremoteESP8266.h:912
+
const uint16_t kLutronBits
Definition: IRremoteESP8266.h:920
+
const uint16_t kSharpAcDefaultRepeat
Definition: IRremoteESP8266.h:984
+
@ MITSUBISHI136
Definition: IRremoteESP8266.h:787
+
const uint16_t kTcl112AcStateLength
Definition: IRremoteESP8266.h:994
+
const uint16_t kDaikin160StateLength
Definition: IRremoteESP8266.h:846
+
const uint16_t kDaikin2StateLength
Definition: IRremoteESP8266.h:841
+
const uint16_t kHaierACYRW02Bits
Definition: IRremoteESP8266.h:890
+
const uint16_t kSherwoodMinRepeat
Definition: IRremoteESP8266.h:986
+
const uint16_t kCarrierAc64MinRepeat
Definition: IRremoteESP8266.h:831
+
@ MWM
Definition: IRremoteESP8266.h:768
+
const uint16_t kHitachiAc424Bits
Definition: IRremoteESP8266.h:906
+
const uint16_t kPanasonicAcShortBits
Definition: IRremoteESP8266.h:957
+
@ DAIKIN
Definition: IRremoteESP8266.h:732
+
@ DELONGHI_AC
Definition: IRremoteESP8266.h:796
+
@ EPSON
Definition: IRremoteESP8266.h:791
+
const uint16_t kLegoPfBits
Definition: IRremoteESP8266.h:915
+
const uint16_t kSharpBits
Definition: IRremoteESP8266.h:981
+
@ kLastDecodeType
Definition: IRremoteESP8266.h:806
+
@ SAMSUNG_AC
Definition: IRremoteESP8266.h:762
+
const uint16_t kDaikinBitsShort
Definition: IRremoteESP8266.h:839
+
@ DAIKIN216
Definition: IRremoteESP8266.h:777
+
@ PANASONIC_AC
Definition: IRremoteESP8266.h:765
+
const uint16_t kProntoMinLength
Definition: IRremoteESP8266.h:960
+
const uint16_t kMitsubishi136StateLength
Definition: IRremoteESP8266.h:933
+
@ DAIKIN64
Definition: IRremoteESP8266.h:794
+
const uint16_t kRCMMBits
Definition: IRremoteESP8266.h:966
+
const uint8_t kVestelAcBits
Definition: IRremoteESP8266.h:1009
+
@ SAMSUNG36
Definition: IRremoteESP8266.h:772
+
const uint8_t kSharpAddressBits
Definition: IRremoteESP8266.h:979
+
const uint16_t kInaxBits
Definition: IRremoteESP8266.h:907
+
const uint16_t kLegoPfMinRepeat
Definition: IRremoteESP8266.h:916
+
const uint16_t kDaikin176Bits
Definition: IRremoteESP8266.h:856
+
const uint16_t kAmcorDefaultRepeat
Definition: IRremoteESP8266.h:820
+
@ KELVINATOR
Definition: IRremoteESP8266.h:734
+
const uint16_t kSamsungBits
Definition: IRremoteESP8266.h:967
+
const uint16_t kDaikin64Bits
Definition: IRremoteESP8266.h:844
+
const uint16_t kTcl112AcBits
Definition: IRremoteESP8266.h:995
+
@ TECO
Definition: IRremoteESP8266.h:771
+
const uint16_t kLasertagMinRepeat
Definition: IRremoteESP8266.h:914
+
@ SHARP
Definition: IRremoteESP8266.h:730
+
@ MITSUBISHI
Definition: IRremoteESP8266.h:728
+
@ ELECTRA_AC
Definition: IRremoteESP8266.h:764
+
const uint16_t kDaikin216Bits
Definition: IRremoteESP8266.h:859
+
const uint16_t kMitsubishi136Bits
Definition: IRremoteESP8266.h:934
+
const uint16_t kNeoclimaMinRepeat
Definition: IRremoteESP8266.h:951
+
const uint16_t kMitsubishi112StateLength
Definition: IRremoteESP8266.h:936
+
const uint16_t kMitsubishi112Bits
Definition: IRremoteESP8266.h:937
+
const uint16_t kSonyMinRepeat
Definition: IRremoteESP8266.h:991
+
const uint16_t kEpsonBits
Definition: IRremoteESP8266.h:869
+
const uint16_t kLgBits
Definition: IRremoteESP8266.h:917
+
const uint16_t kGoodweatherMinRepeat
Definition: IRremoteESP8266.h:882
+
const uint16_t kElectraAcStateLength
Definition: IRremoteESP8266.h:871
+
const uint16_t kGreeDefaultRepeat
Definition: IRremoteESP8266.h:885
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8cpp.html new file mode 100644 index 000000000..33a3b4df7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8cpp.html @@ -0,0 +1,80 @@ + + + + + + + +IRremoteESP8266: src/IRsend.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRsend.cpp File Reference
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h.html new file mode 100644 index 000000000..1d8ef27da --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h.html @@ -0,0 +1,419 @@ + + + + + + + +IRremoteESP8266: src/IRsend.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRsend.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

struct  stdAc::state_t
 Structure to hold a common A/C state. More...
 
class  IRsend
 Class for sending all basic IR protocols. More...
 
+ + + + +

+Namespaces

 stdAc
 Enumerators and Structures for the Common A/C API.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Enumerations

enum  stdAc::opmode_t {
+  stdAc::opmode_t::kOff = -1, +stdAc::opmode_t::kAuto = 0, +stdAc::opmode_t::kCool = 1, +stdAc::opmode_t::kHeat = 2, +
+  stdAc::opmode_t::kDry = 3, +stdAc::opmode_t::kFan = 4, +stdAc::opmode_t::kLastOpmodeEnum = kFan +
+ }
 Common A/C settings for A/C operating modes. More...
 
enum  stdAc::fanspeed_t {
+  stdAc::fanspeed_t::kAuto = 0, +stdAc::fanspeed_t::kMin = 1, +stdAc::fanspeed_t::kLow = 2, +stdAc::fanspeed_t::kMedium = 3, +
+  stdAc::fanspeed_t::kHigh = 4, +stdAc::fanspeed_t::kMax = 5, +stdAc::fanspeed_t::kLastFanspeedEnum = kMax +
+ }
 Common A/C settings for Fan Speeds. More...
 
enum  stdAc::swingv_t {
+  stdAc::swingv_t::kOff = -1, +stdAc::swingv_t::kAuto = 0, +stdAc::swingv_t::kHighest = 1, +stdAc::swingv_t::kHigh = 2, +
+  stdAc::swingv_t::kMiddle = 3, +stdAc::swingv_t::kLow = 4, +stdAc::swingv_t::kLowest = 5, +stdAc::swingv_t::kLastSwingvEnum = kLowest +
+ }
 Common A/C settings for Vertical Swing. More...
 
enum  stdAc::swingh_t {
+  stdAc::swingh_t::kOff = -1, +stdAc::swingh_t::kAuto = 0, +stdAc::swingh_t::kLeftMax = 1, +stdAc::swingh_t::kLeft = 2, +
+  stdAc::swingh_t::kMiddle = 3, +stdAc::swingh_t::kRight = 4, +stdAc::swingh_t::kRightMax = 5, +stdAc::swingh_t::kWide = 6, +
+  stdAc::swingh_t::kLastSwinghEnum = kWide +
+ }
 Common A/C settings for Horizontal Swing. More...
 
enum  fujitsu_ac_remote_model_t {
+  ARRAH2E = 1, +ARDB1, +ARREB1E, +ARJW2, +
+  ARRY4 +
+ }
 Fujitsu A/C model numbers. More...
 
enum  gree_ac_remote_model_t { YAW1F = 1, +YBOFB + }
 Gree A/C model numbers. More...
 
enum  hitachi_ac1_remote_model_t { R_LT0541_HTA_A = 1, +R_LT0541_HTA_B + }
 HITACHI_AC1 A/C model numbers. More...
 
enum  panasonic_ac_remote_model_t {
+  kPanasonicUnknown = 0, +kPanasonicLke = 1, +kPanasonicNke = 2, +kPanasonicDke = 3, +
+  kPanasonicJke = 4, +kPanasonicCkp = 5, +kPanasonicRkr = 6 +
+ }
 Panasonic A/C model numbers. More...
 
enum  whirlpool_ac_remote_model_t { DG11J13A = 1, +DG11J191 + }
 Whirlpool A/C model numbers. More...
 
enum  lg_ac_remote_model_t { GE6711AR2853M = 1, +AKB75215403 + }
 LG A/C model numbers. More...
 
+ + + + + + + + + + + +

+Variables

const int8_t kPeriodOffset = -2
 
const uint8_t kDutyDefault = 50
 
const uint8_t kDutyMax = 100
 
const uint16_t kMaxAccurateUsecDelay = 16383
 
const uint32_t kDefaultMessageGap = 100000
 
+

Enumeration Type Documentation

+ +

◆ fujitsu_ac_remote_model_t

+ +
+
+ + + + +
enum fujitsu_ac_remote_model_t
+
+ +

Fujitsu A/C model numbers.

+ + + + + + +
Enumerator
ARRAH2E 
ARDB1 
ARREB1E 
ARJW2 
ARRY4 
+ +
+
+ +

◆ gree_ac_remote_model_t

+ +
+
+ + + + +
enum gree_ac_remote_model_t
+
+ +

Gree A/C model numbers.

+ + + +
Enumerator
YAW1F 
YBOFB 
+ +
+
+ +

◆ hitachi_ac1_remote_model_t

+ +
+
+ + + + +
enum hitachi_ac1_remote_model_t
+
+ +

HITACHI_AC1 A/C model numbers.

+ + + +
Enumerator
R_LT0541_HTA_A 
R_LT0541_HTA_B 
+ +
+
+ +

◆ lg_ac_remote_model_t

+ +
+
+ + + + +
enum lg_ac_remote_model_t
+
+ +

LG A/C model numbers.

+ + + +
Enumerator
GE6711AR2853M 
AKB75215403 
+ +
+
+ +

◆ panasonic_ac_remote_model_t

+ +
+
+ + + + +
enum panasonic_ac_remote_model_t
+
+ +

Panasonic A/C model numbers.

+ + + + + + + + +
Enumerator
kPanasonicUnknown 
kPanasonicLke 
kPanasonicNke 
kPanasonicDke 
kPanasonicJke 
kPanasonicCkp 
kPanasonicRkr 
+ +
+
+ +

◆ whirlpool_ac_remote_model_t

+ +
+
+ + + + +
enum whirlpool_ac_remote_model_t
+
+ +

Whirlpool A/C model numbers.

+ + + +
Enumerator
DG11J13A 
DG11J191 
+ +
+
+

Variable Documentation

+ +

◆ kDefaultMessageGap

+ +
+
+ + + + +
const uint32_t kDefaultMessageGap = 100000
+
+ +
+
+ +

◆ kDutyDefault

+ +
+
+ + + + +
const uint8_t kDutyDefault = 50
+
+ +
+
+ +

◆ kDutyMax

+ +
+
+ + + + +
const uint8_t kDutyMax = 100
+
+ +
+
+ +

◆ kMaxAccurateUsecDelay

+ +
+
+ + + + +
const uint16_t kMaxAccurateUsecDelay = 16383
+
+ +
+
+ +

◆ kPeriodOffset

+ +
+
+ + + + +
const int8_t kPeriodOffset = -2
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h_source.html new file mode 100644 index 000000000..5afbc44c9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h_source.html @@ -0,0 +1,1078 @@ + + + + + + + +IRremoteESP8266: src/IRsend.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRsend.h
+
+
+Go to the documentation of this file.
1 // Copyright 2009 Ken Shirriff
+
2 // Copyright 2015 Mark Szabo
+
3 // Copyright 2017 David Conran
+
4 #ifndef IRSEND_H_
+
5 #define IRSEND_H_
+
6 
+
7 #define __STDC_LIMIT_MACROS
+
8 #include <stdint.h>
+
9 #include "IRremoteESP8266.h"
+
10 
+
11 // Originally from https://github.com/shirriff/Arduino-IRremote/
+
12 // Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for
+
13 // sending IR code on ESP8266
+
14 
+
15 #if TEST || UNIT_TEST
+
16 #define VIRTUAL virtual
+
17 #else
+
18 #define VIRTUAL
+
19 #endif
+
20 
+
21 // Constants
+
22 // Offset (in microseconds) to use in Period time calculations to account for
+
23 // code excution time in producing the software PWM signal.
+
24 #if defined(ESP32)
+
25 // Calculated on a generic ESP-WROOM-32 board with v3.2-18 SDK @ 240MHz
+
26 const int8_t kPeriodOffset = -2;
+
27 #elif (defined(ESP8266) && F_CPU == 160000000L) // NOLINT(whitespace/parens)
+
28 // Calculated on an ESP8266 NodeMCU v2 board using:
+
29 // v2.6.0 with v2.5.2 ESP core @ 160MHz
+
30 const int8_t kPeriodOffset = -2;
+
31 #else // (defined(ESP8266) && F_CPU == 160000000L)
+
32 // Calculated on ESP8266 Wemos D1 mini using v2.4.1 with v2.4.0 ESP core @ 40MHz
+
33 const int8_t kPeriodOffset = -5;
+
34 #endif // (defined(ESP8266) && F_CPU == 160000000L)
+
35 const uint8_t kDutyDefault = 50; // Percentage
+
36 const uint8_t kDutyMax = 100; // Percentage
+
37 // delayMicroseconds() is only accurate to 16383us.
+
38 // Ref: https://www.arduino.cc/en/Reference/delayMicroseconds
+
39 const uint16_t kMaxAccurateUsecDelay = 16383;
+
40 // Usecs to wait between messages we don't know the proper gap time.
+
41 const uint32_t kDefaultMessageGap = 100000;
+
42 
+
44 namespace stdAc {
+
46  enum class opmode_t {
+
47  kOff = -1,
+
48  kAuto = 0,
+
49  kCool = 1,
+
50  kHeat = 2,
+
51  kDry = 3,
+
52  kFan = 4,
+
53  // Add new entries before this one, and update it to point to the last entry
+ +
55  };
+
56 
+
58  enum class fanspeed_t {
+
59  kAuto = 0,
+
60  kMin = 1,
+
61  kLow = 2,
+
62  kMedium = 3,
+
63  kHigh = 4,
+
64  kMax = 5,
+
65  // Add new entries before this one, and update it to point to the last entry
+ +
67  };
+
68 
+
70  enum class swingv_t {
+
71  kOff = -1,
+
72  kAuto = 0,
+
73  kHighest = 1,
+
74  kHigh = 2,
+
75  kMiddle = 3,
+
76  kLow = 4,
+
77  kLowest = 5,
+
78  // Add new entries before this one, and update it to point to the last entry
+ +
80  };
+
81 
+
83  enum class swingh_t {
+
84  kOff = -1,
+
85  kAuto = 0, // a.k.a. On.
+
86  kLeftMax = 1,
+
87  kLeft = 2,
+
88  kMiddle = 3,
+
89  kRight = 4,
+
90  kRightMax = 5,
+
91  kWide = 6, // a.k.a. left & right at the same time.
+
92  // Add new entries before this one, and update it to point to the last entry
+ +
94  };
+
95 
+
97  typedef struct {
+ +
99  int16_t model;
+
100  bool power;
+ +
102  float degrees;
+
103  bool celsius;
+ + + +
107  bool quiet;
+
108  bool turbo;
+
109  bool econo;
+
110  bool light;
+
111  bool filter;
+
112  bool clean;
+
113  bool beep;
+
114  int16_t sleep;
+
115  int16_t clock;
+
116  } state_t;
+
117 }; // namespace stdAc
+
118 
+ +
121  ARRAH2E = 1, // (1) AR-RAH2E, AR-RAC1E, AR-RAE1E (Default)
+
122  ARDB1, // (2) AR-DB1, AR-DL10 (AR-DL10 swing doesn't work)
+
123  ARREB1E, // (3) AR-REB1E
+
124  ARJW2, // (4) AR-JW2 (Same as ARDB1 but with horiz control)
+
125  ARRY4, // (5) AR-RY4 (Same as AR-RAH2E but with clean & filter)
+
126 };
+
127 
+ +
130  YAW1F = 1, // (1) Ultimate, EKOKAI, RusClimate (Default)
+
131  YBOFB, // (2) Green, YBOFB2, YAPOF3
+
132 };
+
133 
+ +
136  R_LT0541_HTA_A = 1, // (1) R-LT0541-HTA Remote in "A" setting. (Default)
+
137  R_LT0541_HTA_B, // (2) R-LT0541-HTA Remote in "B" setting.
+
138 };
+
139 
+ + + + +
145  kPanasonicDke = 3, // PKR too.
+ + + +
149 };
+
150 
+ +
153  DG11J13A = 1, // DG11J1-04 too
+ +
155 };
+
156 
+ +
159  GE6711AR2853M = 1, // (1) LG 28-bit Protocol (default)
+
160  AKB75215403, // (2) LG2 28-bit Protocol
+
161 };
+
162 
+
163 
+
164 // Classes
+
165 
+
170 class IRsend {
+
171  public:
+
172  explicit IRsend(uint16_t IRsendPin, bool inverted = false,
+
173  bool use_modulation = true);
+
174  void begin();
+
175  void enableIROut(uint32_t freq, uint8_t duty = kDutyDefault);
+
176  VIRTUAL void _delayMicroseconds(uint32_t usec);
+
177  VIRTUAL uint16_t mark(uint16_t usec);
+
178  VIRTUAL void space(uint32_t usec);
+
179  int8_t calibrate(uint16_t hz = 38000U);
+
180  void sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz);
+
181  void sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark,
+
182  uint32_t zerospace, uint64_t data, uint16_t nbits,
+
183  bool MSBfirst = true);
+
184  void sendManchesterData(const uint16_t half_period, const uint64_t data,
+
185  const uint16_t nbits, const bool MSBfirst = true,
+
186  const bool GEThomas = true);
+
187  void sendManchester(const uint16_t headermark, const uint32_t headerspace,
+
188  const uint16_t half_period, const uint16_t footermark,
+
189  const uint32_t gap, const uint64_t data,
+
190  const uint16_t nbits, const uint16_t frequency = 38,
+
191  const bool MSBfirst = true,
+
192  const uint16_t repeat = kNoRepeat,
+
193  const uint8_t dutycycle = kDutyDefault,
+
194  const bool GEThomas = true);
+
195  void sendGeneric(const uint16_t headermark, const uint32_t headerspace,
+
196  const uint16_t onemark, const uint32_t onespace,
+
197  const uint16_t zeromark, const uint32_t zerospace,
+
198  const uint16_t footermark, const uint32_t gap,
+
199  const uint64_t data, const uint16_t nbits,
+
200  const uint16_t frequency, const bool MSBfirst,
+
201  const uint16_t repeat, const uint8_t dutycycle);
+
202  void sendGeneric(const uint16_t headermark, const uint32_t headerspace,
+
203  const uint16_t onemark, const uint32_t onespace,
+
204  const uint16_t zeromark, const uint32_t zerospace,
+
205  const uint16_t footermark, const uint32_t gap,
+
206  const uint32_t mesgtime, const uint64_t data,
+
207  const uint16_t nbits, const uint16_t frequency,
+
208  const bool MSBfirst, const uint16_t repeat,
+
209  const uint8_t dutycycle);
+
210  void sendGeneric(const uint16_t headermark, const uint32_t headerspace,
+
211  const uint16_t onemark, const uint32_t onespace,
+
212  const uint16_t zeromark, const uint32_t zerospace,
+
213  const uint16_t footermark, const uint32_t gap,
+
214  const uint8_t *dataptr, const uint16_t nbytes,
+
215  const uint16_t frequency, const bool MSBfirst,
+
216  const uint16_t repeat, const uint8_t dutycycle);
+
217  static uint16_t minRepeats(const decode_type_t protocol);
+
218  static uint16_t defaultBits(const decode_type_t protocol);
+
219  bool send(const decode_type_t type, const uint64_t data,
+
220  const uint16_t nbits, const uint16_t repeat = kNoRepeat);
+
221  bool send(const decode_type_t type, const uint8_t *state,
+
222  const uint16_t nbytes);
+
223 #if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO || \
+
224  SEND_MIDEA24)
+
225  void sendNEC(uint64_t data, uint16_t nbits = kNECBits,
+
226  uint16_t repeat = kNoRepeat);
+
227  uint32_t encodeNEC(uint16_t address, uint16_t command);
+
228 #endif
+
229 #if SEND_SONY
+
230  // sendSony() should typically be called with repeat=2 as Sony devices
+
231  // expect the code to be sent at least 3 times. (code + 2 repeats = 3 codes)
+
232  // Legacy use of this procedure was to only send a single code so call it with
+
233  // repeat=0 for backward compatibility. As of v2.0 it defaults to sending
+
234  // a Sony command that will be accepted be a device.
+
235  void sendSony(const uint64_t data, const uint16_t nbits = kSony20Bits,
+
236  const uint16_t repeat = kSonyMinRepeat);
+
237  void sendSony38(const uint64_t data, const uint16_t nbits = kSony20Bits,
+
238  const uint16_t repeat = kSonyMinRepeat + 1);
+
239  uint32_t encodeSony(const uint16_t nbits, const uint16_t command,
+
240  const uint16_t address, const uint16_t extended = 0);
+
241 #endif // SEND_SONY
+
242 #if SEND_SHERWOOD
+
243  void sendSherwood(uint64_t data, uint16_t nbits = kSherwoodBits,
+
244  uint16_t repeat = kSherwoodMinRepeat);
+
245 #endif
+
246 #if SEND_SAMSUNG
+
247  void sendSAMSUNG(const uint64_t data, const uint16_t nbits = kSamsungBits,
+
248  const uint16_t repeat = kNoRepeat);
+
249  uint32_t encodeSAMSUNG(const uint8_t customer, const uint8_t command);
+
250 #endif
+
251 #if SEND_SAMSUNG36
+
252  void sendSamsung36(const uint64_t data, const uint16_t nbits = kSamsung36Bits,
+
253  const uint16_t repeat = kNoRepeat);
+
254 #endif
+
255 #if SEND_SAMSUNG_AC
+
256  void sendSamsungAC(const unsigned char data[],
+
257  const uint16_t nbytes = kSamsungAcStateLength,
+
258  const uint16_t repeat = kSamsungAcDefaultRepeat);
+
259 #endif
+
260 #if SEND_LG
+
261  void sendLG(uint64_t data, uint16_t nbits = kLgBits,
+
262  uint16_t repeat = kNoRepeat);
+
263  void sendLG2(uint64_t data, uint16_t nbits = kLgBits,
+
264  uint16_t repeat = kNoRepeat);
+
265  uint32_t encodeLG(uint16_t address, uint16_t command);
+
266 #endif
+
267 #if (SEND_SHARP || SEND_DENON)
+
268  uint32_t encodeSharp(const uint16_t address, const uint16_t command,
+
269  const uint16_t expansion = 1, const uint16_t check = 0,
+
270  const bool MSBfirst = false);
+
271  void sendSharp(const uint16_t address, const uint16_t command,
+
272  const uint16_t nbits = kSharpBits,
+
273  const uint16_t repeat = kNoRepeat);
+
274  void sendSharpRaw(const uint64_t data, const uint16_t nbits = kSharpBits,
+
275  const uint16_t repeat = kNoRepeat);
+
276 #endif
+
277 #if SEND_SHARP_AC
+
278  void sendSharpAc(const unsigned char data[],
+
279  const uint16_t nbytes = kSharpAcStateLength,
+
280  const uint16_t repeat = kSharpAcDefaultRepeat);
+
281 #endif // SEND_SHARP_AC
+
282 #if SEND_JVC
+
283  void sendJVC(uint64_t data, uint16_t nbits = kJvcBits,
+
284  uint16_t repeat = kNoRepeat);
+
285  uint16_t encodeJVC(uint8_t address, uint8_t command);
+
286 #endif
+
287 #if SEND_DENON
+
288  void sendDenon(uint64_t data, uint16_t nbits = kDenonBits,
+
289  uint16_t repeat = kNoRepeat);
+
290 #endif
+
291 #if SEND_SANYO
+
292  uint64_t encodeSanyoLC7461(uint16_t address, uint8_t command);
+
293  void sendSanyoLC7461(const uint64_t data,
+
294  const uint16_t nbits = kSanyoLC7461Bits,
+
295  const uint16_t repeat = kNoRepeat);
+
296 #endif
+
297 #if SEND_DISH
+
298  // sendDISH() should typically be called with repeat=3 as DISH devices
+
299  // expect the code to be sent at least 4 times. (code + 3 repeats = 4 codes)
+
300  // Legacy use of this procedure was only to send a single code
+
301  // so use repeat=0 for backward compatibility.
+
302  void sendDISH(uint64_t data, uint16_t nbits = kDishBits,
+
303  uint16_t repeat = kDishMinRepeat);
+
304 #endif
+
305 #if (SEND_PANASONIC || SEND_DENON)
+
306  void sendPanasonic64(const uint64_t data,
+
307  const uint16_t nbits = kPanasonicBits,
+
308  const uint16_t repeat = kNoRepeat);
+
309  void sendPanasonic(const uint16_t address, const uint32_t data,
+
310  const uint16_t nbits = kPanasonicBits,
+
311  const uint16_t repeat = kNoRepeat);
+
312  uint64_t encodePanasonic(const uint16_t manufacturer, const uint8_t device,
+
313  const uint8_t subdevice, const uint8_t function);
+
314 #endif
+
315 #if SEND_RC5
+
316  void sendRC5(const uint64_t data, uint16_t nbits = kRC5XBits,
+
317  const uint16_t repeat = kNoRepeat);
+
318  uint16_t encodeRC5(const uint8_t address, const uint8_t command,
+
319  const bool key_released = false);
+
320  uint16_t encodeRC5X(const uint8_t address, const uint8_t command,
+
321  const bool key_released = false);
+
322  uint64_t toggleRC5(const uint64_t data);
+
323 #endif
+
324 #if SEND_RC6
+
325  void sendRC6(const uint64_t data, const uint16_t nbits = kRC6Mode0Bits,
+
326  const uint16_t repeat = kNoRepeat);
+
327  uint64_t encodeRC6(const uint32_t address, const uint8_t command,
+
328  const uint16_t mode = kRC6Mode0Bits);
+
329  uint64_t toggleRC6(const uint64_t data, const uint16_t nbits = kRC6Mode0Bits);
+
330 #endif
+
331 #if SEND_RCMM
+
332  void sendRCMM(uint64_t data, uint16_t nbits = kRCMMBits,
+
333  uint16_t repeat = kNoRepeat);
+
334 #endif
+
335 #if SEND_COOLIX
+
336  void sendCOOLIX(uint64_t data, uint16_t nbits = kCoolixBits,
+
337  uint16_t repeat = kCoolixDefaultRepeat);
+
338 #endif
+
339 #if SEND_WHYNTER
+
340  void sendWhynter(const uint64_t data, const uint16_t nbits = kWhynterBits,
+
341  const uint16_t repeat = kNoRepeat);
+
342 #endif
+
343 #if SEND_MITSUBISHI
+
344  void sendMitsubishi(uint64_t data, uint16_t nbits = kMitsubishiBits,
+
345  uint16_t repeat = kMitsubishiMinRepeat);
+
346 #endif
+
347 #if SEND_MITSUBISHI136
+
348  void sendMitsubishi136(const unsigned char data[],
+
349  const uint16_t nbytes = kMitsubishi136StateLength,
+
350  const uint16_t repeat = kMitsubishi136MinRepeat);
+
351 #endif
+
352 #if SEND_MITSUBISHI112
+
353  void sendMitsubishi112(const unsigned char data[],
+
354  const uint16_t nbytes = kMitsubishi112StateLength,
+
355  const uint16_t repeat = kMitsubishi112MinRepeat);
+
356 #endif
+
357 #if SEND_MITSUBISHI2
+
358  void sendMitsubishi2(uint64_t data, uint16_t nbits = kMitsubishiBits,
+
359  uint16_t repeat = kMitsubishiMinRepeat);
+
360 #endif
+
361 #if SEND_MITSUBISHI_AC
+
362  void sendMitsubishiAC(const unsigned char data[],
+
363  const uint16_t nbytes = kMitsubishiACStateLength,
+
364  const uint16_t repeat = kMitsubishiACMinRepeat);
+
365 #endif
+
366 #if SEND_MITSUBISHIHEAVY
+ +
368  const unsigned char data[],
+
369  const uint16_t nbytes = kMitsubishiHeavy88StateLength,
+
370  const uint16_t repeat = kMitsubishiHeavy88MinRepeat);
+ +
372  const unsigned char data[],
+
373  const uint16_t nbytes = kMitsubishiHeavy152StateLength,
+
374  const uint16_t repeat = kMitsubishiHeavy152MinRepeat);
+
375 #endif
+
376 #if SEND_FUJITSU_AC
+
377  void sendFujitsuAC(const unsigned char data[], const uint16_t nbytes,
+
378  const uint16_t repeat = kFujitsuAcMinRepeat);
+
379 #endif
+
380 #if SEND_INAX
+
381  void sendInax(const uint64_t data, const uint16_t nbits = kInaxBits,
+
382  const uint16_t repeat = kInaxMinRepeat);
+
383 #endif // SEND_INAX
+
384 #if SEND_GLOBALCACHE
+
385  void sendGC(uint16_t buf[], uint16_t len);
+
386 #endif
+
387 #if SEND_KELVINATOR
+
388  void sendKelvinator(const unsigned char data[],
+
389  const uint16_t nbytes = kKelvinatorStateLength,
+
390  const uint16_t repeat = kKelvinatorDefaultRepeat);
+
391 #endif
+
392 #if SEND_DAIKIN
+
393  void sendDaikin(const unsigned char data[],
+
394  const uint16_t nbytes = kDaikinStateLength,
+
395  const uint16_t repeat = kDaikinDefaultRepeat);
+
396 #endif
+
397 #if SEND_DAIKIN64
+
398  void sendDaikin64(const uint64_t data, const uint16_t nbits = kDaikin64Bits,
+
399  const uint16_t repeat = kDaikin64DefaultRepeat);
+
400 #endif // SEND_DAIKIN64
+
401 #if SEND_DAIKIN128
+
402  void sendDaikin128(const unsigned char data[],
+
403  const uint16_t nbytes = kDaikin128StateLength,
+
404  const uint16_t repeat = kDaikin128DefaultRepeat);
+
405 #endif // SEND_DAIKIN128
+
406 #if SEND_DAIKIN152
+
407  void sendDaikin152(const unsigned char data[],
+
408  const uint16_t nbytes = kDaikin152StateLength,
+
409  const uint16_t repeat = kDaikin152DefaultRepeat);
+
410 #endif // SEND_DAIKIN152
+
411 #if SEND_DAIKIN160
+
412  void sendDaikin160(const unsigned char data[],
+
413  const uint16_t nbytes = kDaikin160StateLength,
+
414  const uint16_t repeat = kDaikin160DefaultRepeat);
+
415 #endif // SEND_DAIKIN160
+
416 #if SEND_DAIKIN176
+
417  void sendDaikin176(const unsigned char data[],
+
418  const uint16_t nbytes = kDaikin176StateLength,
+
419  const uint16_t repeat = kDaikin176DefaultRepeat);
+
420 #endif // SEND_DAIKIN176
+
421 #if SEND_DAIKIN2
+
422  void sendDaikin2(const unsigned char data[],
+
423  const uint16_t nbytes = kDaikin2StateLength,
+
424  const uint16_t repeat = kDaikin2DefaultRepeat);
+
425 #endif
+
426 #if SEND_DAIKIN216
+
427  void sendDaikin216(const unsigned char data[],
+
428  const uint16_t nbytes = kDaikin216StateLength,
+
429  const uint16_t repeat = kDaikin216DefaultRepeat);
+
430 #endif
+
431 #if SEND_AIWA_RC_T501
+
432  void sendAiwaRCT501(uint64_t data, uint16_t nbits = kAiwaRcT501Bits,
+
433  uint16_t repeat = kAiwaRcT501MinRepeats);
+
434 #endif
+
435 #if SEND_GREE
+
436  void sendGree(const uint64_t data, const uint16_t nbits = kGreeBits,
+
437  const uint16_t repeat = kGreeDefaultRepeat);
+
438  void sendGree(const uint8_t data[], const uint16_t nbytes = kGreeStateLength,
+
439  const uint16_t repeat = kGreeDefaultRepeat);
+
440 #endif
+
441 #if SEND_GOODWEATHER
+
442  void sendGoodweather(const uint64_t data,
+
443  const uint16_t nbits = kGoodweatherBits,
+
444  const uint16_t repeat = kGoodweatherMinRepeat);
+
445 #endif // SEND_GOODWEATHER
+
446 #if SEND_PRONTO
+
447  void sendPronto(uint16_t data[], uint16_t len, uint16_t repeat = kNoRepeat);
+
448 #endif
+
449 #if SEND_ARGO
+
450  void sendArgo(const unsigned char data[],
+
451  const uint16_t nbytes = kArgoStateLength,
+
452  const uint16_t repeat = kArgoDefaultRepeat);
+
453 #endif
+
454 #if SEND_TROTEC
+
455  void sendTrotec(const unsigned char data[],
+
456  const uint16_t nbytes = kTrotecStateLength,
+
457  const uint16_t repeat = kTrotecDefaultRepeat);
+
458 #endif
+
459 #if SEND_NIKAI
+
460  void sendNikai(uint64_t data, uint16_t nbits = kNikaiBits,
+
461  uint16_t repeat = kNoRepeat);
+
462 #endif
+
463 #if SEND_TOSHIBA_AC
+
464  void sendToshibaAC(const unsigned char data[],
+
465  const uint16_t nbytes = kToshibaACStateLength,
+
466  const uint16_t repeat = kToshibaACMinRepeat);
+
467 #endif
+
468 #if SEND_MIDEA
+
469  void sendMidea(uint64_t data, uint16_t nbits = kMideaBits,
+
470  uint16_t repeat = kMideaMinRepeat);
+
471 #endif // SEND_MIDEA
+
472 #if SEND_MIDEA24
+
473  void sendMidea24(const uint64_t data, const uint16_t nbits = kMidea24Bits,
+
474  const uint16_t repeat = kMidea24MinRepeat);
+
475 #endif // SEND_MIDEA24
+
476 #if SEND_MAGIQUEST
+
477  void sendMagiQuest(const uint64_t data, const uint16_t nbits = kMagiquestBits,
+
478  const uint16_t repeat = kNoRepeat);
+
479  uint64_t encodeMagiQuest(const uint32_t wand_id, const uint16_t magnitude);
+
480 #endif
+
481 #if SEND_LASERTAG
+
482  void sendLasertag(uint64_t data, uint16_t nbits = kLasertagBits,
+
483  uint16_t repeat = kLasertagMinRepeat);
+
484 #endif
+
485 #if SEND_CARRIER_AC
+
486  void sendCarrierAC(uint64_t data, uint16_t nbits = kCarrierAcBits,
+
487  uint16_t repeat = kCarrierAcMinRepeat);
+
488 #endif
+
489 #if SEND_CARRIER_AC40
+
490  void sendCarrierAC40(uint64_t data, uint16_t nbits = kCarrierAc40Bits,
+
491  uint16_t repeat = kCarrierAc40MinRepeat);
+
492 #endif
+
493 #if SEND_CARRIER_AC64
+
494  void sendCarrierAC64(uint64_t data, uint16_t nbits = kCarrierAc64Bits,
+
495  uint16_t repeat = kCarrierAc64MinRepeat);
+
496 #endif
+
497 #if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02)
+
498  void sendHaierAC(const unsigned char data[],
+
499  const uint16_t nbytes = kHaierACStateLength,
+
500  const uint16_t repeat = kHaierAcDefaultRepeat);
+
501 #endif
+
502 #if SEND_HAIER_AC_YRW02
+
503  void sendHaierACYRW02(const unsigned char data[],
+
504  const uint16_t nbytes = kHaierACYRW02StateLength,
+
505  const uint16_t repeat = kHaierAcYrw02DefaultRepeat);
+
506 #endif
+
507 #if SEND_HITACHI_AC
+
508  void sendHitachiAC(const unsigned char data[],
+
509  const uint16_t nbytes = kHitachiAcStateLength,
+
510  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
511 #endif
+
512 #if SEND_HITACHI_AC1
+
513  void sendHitachiAC1(const unsigned char data[],
+
514  const uint16_t nbytes = kHitachiAc1StateLength,
+
515  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
516 #endif
+
517 #if SEND_HITACHI_AC2
+
518  void sendHitachiAC2(const unsigned char data[],
+
519  const uint16_t nbytes = kHitachiAc2StateLength,
+
520  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
521 #endif
+
522 #if SEND_HITACHI_AC3
+
523  void sendHitachiAc3(const unsigned char data[],
+
524  const uint16_t nbytes, // No default as there as so many
+
525  // different sizes
+
526  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
527 #endif // SEND_HITACHI_AC3
+
528 #if SEND_HITACHI_AC344
+
529  void sendHitachiAc344(const unsigned char data[],
+
530  const uint16_t nbytes = kHitachiAc344StateLength,
+
531  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
532 #endif // SEND_HITACHI_AC344
+
533 #if SEND_HITACHI_AC424
+
534  void sendHitachiAc424(const unsigned char data[],
+
535  const uint16_t nbytes = kHitachiAc424StateLength,
+
536  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
537 #endif // SEND_HITACHI_AC424
+
538 #if SEND_GICABLE
+
539  void sendGICable(uint64_t data, uint16_t nbits = kGicableBits,
+
540  uint16_t repeat = kGicableMinRepeat);
+
541 #endif
+
542 #if SEND_WHIRLPOOL_AC
+
543  void sendWhirlpoolAC(const unsigned char data[],
+
544  const uint16_t nbytes = kWhirlpoolAcStateLength,
+
545  const uint16_t repeat = kWhirlpoolAcDefaultRepeat);
+
546 #endif
+
547 #if SEND_LUTRON
+
548  void sendLutron(uint64_t data, uint16_t nbits = kLutronBits,
+
549  uint16_t repeat = kNoRepeat);
+
550 #endif
+
551 #if SEND_ELECTRA_AC
+
552  void sendElectraAC(const unsigned char data[],
+
553  const uint16_t nbytes = kElectraAcStateLength,
+
554  const uint16_t repeat = kNoRepeat);
+
555 #endif
+
556 #if SEND_PANASONIC_AC
+
557  void sendPanasonicAC(const unsigned char data[],
+
558  const uint16_t nbytes = kPanasonicAcStateLength,
+
559  const uint16_t repeat = kPanasonicAcDefaultRepeat);
+
560 #endif
+
561 #if SEND_PIONEER
+
562  void sendPioneer(const uint64_t data, const uint16_t nbits = kPioneerBits,
+
563  const uint16_t repeat = kNoRepeat);
+
564  uint64_t encodePioneer(uint16_t address, uint16_t command);
+
565 #endif
+
566 #if SEND_MWM
+
567  void sendMWM(const unsigned char data[], const uint16_t nbytes,
+
568  const uint16_t repeat = kNoRepeat);
+
569 #endif
+
570 #if SEND_VESTEL_AC
+
571  void sendVestelAc(const uint64_t data, const uint16_t nbits = kVestelAcBits,
+
572  const uint16_t repeat = kNoRepeat);
+
573 #endif
+
574 #if SEND_TCL112AC
+
575  void sendTcl112Ac(const unsigned char data[],
+
576  const uint16_t nbytes = kTcl112AcStateLength,
+
577  const uint16_t repeat = kTcl112AcDefaultRepeat);
+
578 #endif
+
579 #if SEND_TECO
+
580  void sendTeco(const uint64_t data, const uint16_t nbits = kTecoBits,
+
581  const uint16_t repeat = kNoRepeat);
+
582 #endif
+
583 #if SEND_LEGOPF
+
584  void sendLegoPf(const uint64_t data, const uint16_t nbits = kLegoPfBits,
+
585  const uint16_t repeat = kLegoPfMinRepeat);
+
586 #endif
+
587 #if SEND_NEOCLIMA
+
588  void sendNeoclima(const unsigned char data[],
+
589  const uint16_t nbytes = kNeoclimaStateLength,
+
590  const uint16_t repeat = kNeoclimaMinRepeat);
+
591 #endif // SEND_NEOCLIMA
+
592 #if SEND_AMCOR
+
593  void sendAmcor(const unsigned char data[],
+
594  const uint16_t nbytes = kAmcorStateLength,
+
595  const uint16_t repeat = kAmcorDefaultRepeat);
+
596 #endif // SEND_AMCOR
+
597 #if SEND_EPSON
+
598  void sendEpson(uint64_t data, uint16_t nbits = kEpsonBits,
+
599  uint16_t repeat = kEpsonMinRepeat);
+
600 #endif
+
601 #if SEND_SYMPHONY
+
602  void sendSymphony(uint64_t data, uint16_t nbits = kSymphonyBits,
+
603  uint16_t repeat = kSymphonyDefaultRepeat);
+
604 #endif
+
605 #if SEND_AIRWELL
+
606  void sendAirwell(uint64_t data, uint16_t nbits = kAirwellBits,
+
607  uint16_t repeat = kAirwellMinRepeats);
+
608 #endif
+
609 #if SEND_DELONGHI_AC
+
610  void sendDelonghiAc(uint64_t data, uint16_t nbits = kDelonghiAcBits,
+
611  uint16_t repeat = kDelonghiAcDefaultRepeat);
+
612 #endif
+
613 #if SEND_DOSHISHA
+
614  void sendDoshisha(const uint64_t data, uint16_t nbits = kDoshishaBits,
+
615  const uint16_t repeat = kNoRepeat);
+
616  uint64_t encodeDoshisha(const uint8_t command, const uint8_t channel = 0);
+
617 #endif // SEND_DOSHISHA
+
618 #if SEND_MULTIBRACKETS
+
619  void sendMultibrackets(const uint64_t data,
+
620  const uint16_t nbits = kMultibracketsBits,
+
621  const uint16_t repeat = kMultibracketsDefaultRepeat);
+
622 #endif
+
623 #if SEND_CORONA_AC
+
624  void sendCoronaAc(const uint8_t data[],
+
625  const uint16_t nbytes = kCoronaAcStateLength,
+
626  const uint16_t repeat = kNoRepeat);
+
627 #endif // SEND_CORONA_AC
+
628 #if SEND_ZEPEAL
+
629  void sendZepeal(const uint64_t data,
+
630  const uint16_t nbits = kZepealBits,
+
631  const uint16_t repeat = kZepealMinRepeat);
+
632 #endif
+
633 
+
634  protected:
+
635 #ifdef UNIT_TEST
+
636 #ifndef HIGH
+
637 #define HIGH 0x1
+
638 #endif
+
639 #ifndef LOW
+
640 #define LOW 0x0
+
641 #endif
+
642 #endif // UNIT_TEST
+
643  uint8_t outputOn;
+
644  uint8_t outputOff;
+
645  VIRTUAL void ledOff();
+
646  VIRTUAL void ledOn();
+
647 #ifndef UNIT_TEST
+
648 
+
649  private:
+
650 #else
+
651  uint32_t _freq_unittest;
+
652 #endif // UNIT_TEST
+
653  uint16_t onTimePeriod;
+
654  uint16_t offTimePeriod;
+
655  uint16_t IRpin;
+
656  int8_t periodOffset;
+
657  uint8_t _dutycycle;
+ +
659  uint32_t calcUSecPeriod(uint32_t hz, bool use_offset = true);
+
660 #if SEND_SONY
+
661  void _sendSony(const uint64_t data, const uint16_t nbits,
+
662  const uint16_t repeat, const uint16_t freq);
+
663 #endif // SEND_SONY
+
664 };
+
665 
+
666 #endif // IRSEND_H_
+
+
uint32_t calcUSecPeriod(uint32_t hz, bool use_offset=true)
Calculate the period for a given frequency.
Definition: IRsend.cpp:71
+
const uint16_t kDaikin152DefaultRepeat
Definition: IRremoteESP8266.h:854
+
void sendZepeal(const uint64_t data, const uint16_t nbits=kZepealBits, const uint16_t repeat=kZepealMinRepeat)
Send a Zepeal formatted message. Status: STABLE / Works on real device.
Definition: ir_Zepeal.cpp:47
+
const uint16_t kDelonghiAcBits
Definition: IRremoteESP8266.h:861
+
void sendHaierACYRW02(const unsigned char data[], const uint16_t nbytes=kHaierACYRW02StateLength, const uint16_t repeat=kHaierAcYrw02DefaultRepeat)
Send a Haier YR-W02 remote A/C formatted message. Status: Alpha / Untested on a real device.
Definition: ir_Haier.cpp:68
+
const uint16_t kHaierAcYrw02DefaultRepeat
Definition: IRremoteESP8266.h:891
+
void sendPronto(uint16_t data[], uint16_t len, uint16_t repeat=kNoRepeat)
Send a Pronto Code formatted message. Status: STABLE / Known working.
Definition: ir_Pronto.cpp:56
+
uint8_t outputOff
Definition: IRsend.h:644
+
int8_t periodOffset
Definition: IRsend.h:656
+
const uint16_t kMitsubishiACStateLength
Definition: IRremoteESP8266.h:930
+
const uint16_t kMitsubishiHeavy152StateLength
Definition: IRremoteESP8266.h:942
+
const uint16_t kAirwellMinRepeats
Definition: IRremoteESP8266.h:814
+
const uint16_t kMideaMinRepeat
Definition: IRremoteESP8266.h:923
+
int16_t clock
Definition: IRsend.h:115
+
const uint16_t kGicableBits
Definition: IRremoteESP8266.h:879
+
const uint16_t kGreeStateLength
Definition: IRremoteESP8266.h:883
+
uint32_t encodeNEC(uint16_t address, uint16_t command)
Calculate the raw NEC data based on address and command. Status: STABLE / Expected to work.
Definition: ir_NEC.cpp:48
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
uint64_t encodeDoshisha(const uint8_t command, const uint8_t channel=0)
Encode Doshisha combining constant values with command and channel. Status: STABLE / Working.
Definition: ir_Doshisha.cpp:67
+
const uint16_t kCarrierAcBits
Definition: IRremoteESP8266.h:826
+ +
void sendHitachiAc344(const unsigned char data[], const uint16_t nbytes=kHitachiAc344StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) Basically the same as sendHitatchiAC() ex...
Definition: ir_Hitachi.cpp:121
+
const uint16_t kDaikin2DefaultRepeat
Definition: IRremoteESP8266.h:843
+
const uint16_t kMultibracketsBits
Definition: IRremoteESP8266.h:945
+
const uint16_t kWhynterBits
Definition: IRremoteESP8266.h:1008
+ +
const uint16_t kAirwellBits
Definition: IRremoteESP8266.h:813
+
const uint16_t kHaierAcDefaultRepeat
Definition: IRremoteESP8266.h:888
+
void sendMidea(uint64_t data, uint16_t nbits=kMideaBits, uint16_t repeat=kMideaMinRepeat)
Send a Midea message Status: Alpha / Needs testing against a real device.
Definition: ir_Midea.cpp:52
+
const uint16_t kTrotecDefaultRepeat
Definition: IRremoteESP8266.h:1004
+
const uint16_t kFujitsuAcMinRepeat
Definition: IRremoteESP8266.h:874
+
void sendLG(uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)
Send an LG formatted message. (LG) Status: Beta / Should be working.
Definition: ir_LG.cpp:69
+
@ kPanasonicRkr
Definition: IRsend.h:148
+
const uint16_t kMitsubishi136MinRepeat
Definition: IRremoteESP8266.h:935
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
VIRTUAL void _delayMicroseconds(uint32_t usec)
An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds().
Definition: IRsend.cpp:114
+
bool clean
Definition: IRsend.h:112
+
void sendLegoPf(const uint64_t data, const uint16_t nbits=kLegoPfBits, const uint16_t repeat=kLegoPfMinRepeat)
Send a LEGO Power Functions message. Status: Beta / Should work.
Definition: ir_Lego.cpp:33
+
const uint16_t kArgoDefaultRepeat
Definition: IRremoteESP8266.h:823
+
uint8_t outputOn
Definition: IRsend.h:643
+
const uint16_t kHaierACStateLength
Definition: IRremoteESP8266.h:886
+
const uint16_t kHitachiAcStateLength
Definition: IRremoteESP8266.h:892
+ +
const uint16_t kDaikin176StateLength
Definition: IRremoteESP8266.h:855
+
const uint16_t kRC5XBits
Definition: IRremoteESP8266.h:963
+
const uint16_t kEpsonMinRepeat
Definition: IRremoteESP8266.h:870
+
const uint16_t kAmcorStateLength
Definition: IRremoteESP8266.h:818
+
bool send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)
Send a simple (up to 64 bits) IR message of a given type. An unknown/unsupported type will send nothi...
Definition: IRsend.cpp:749
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
@ R_LT0541_HTA_B
Definition: IRsend.h:137
+
void sendWhynter(const uint64_t data, const uint16_t nbits=kWhynterBits, const uint16_t repeat=kNoRepeat)
Send a Whynter message. Status: STABLE.
Definition: ir_Whynter.cpp:45
+
whirlpool_ac_remote_model_t
Whirlpool A/C model numbers.
Definition: IRsend.h:152
+
void sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes=kMitsubishiACStateLength, const uint16_t repeat=kMitsubishiACMinRepeat)
Send a Mitsubishi 144-bit A/C formatted message. (MITSUBISHI_AC) Status: STABLE / Working.
Definition: ir_Mitsubishi.cpp:233
+
void sendNikai(uint64_t data, uint16_t nbits=kNikaiBits, uint16_t repeat=kNoRepeat)
Send a Nikai formatted message. Status: STABLE / Working.
Definition: ir_Nikai.cpp:37
+
const uint32_t kDefaultMessageGap
Definition: IRsend.h:41
+
const uint16_t kMaxAccurateUsecDelay
Definition: IRsend.h:39
+
uint16_t encodeJVC(uint8_t address, uint8_t command)
Calculate the raw JVC data based on address and command. Status: STABLE / Works fine.
Definition: ir_JVC.cpp:78
+
uint16_t onTimePeriod
Definition: IRsend.h:653
+
void sendAiwaRCT501(uint64_t data, uint16_t nbits=kAiwaRcT501Bits, uint16_t repeat=kAiwaRcT501MinRepeats)
Send an Aiwa RC T501 formatted message. Status: BETA / Should work.
Definition: ir_Aiwa.cpp:30
+
uint16_t IRpin
Definition: IRsend.h:655
+
const uint16_t kHitachiAc1StateLength
Definition: IRremoteESP8266.h:895
+
const uint16_t kCoolixBits
Definition: IRremoteESP8266.h:824
+
const uint16_t kMitsubishi112MinRepeat
Definition: IRremoteESP8266.h:938
+
void sendSymphony(uint64_t data, uint16_t nbits=kSymphonyBits, uint16_t repeat=kSymphonyDefaultRepeat)
Send a Symphony packet. Status: STABLE / Should be working.
Definition: ir_Symphony.cpp:42
+
void sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)
Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits i...
Definition: IRsend.cpp:307
+ +
const uint16_t kSamsung36Bits
Definition: IRremoteESP8266.h:968
+
const uint16_t kMagiquestBits
Definition: IRremoteESP8266.h:921
+
static uint16_t minRepeats(const decode_type_t protocol)
Get the minimum number of repeats for a given protocol.
Definition: IRsend.cpp:557
+
const uint16_t kNeoclimaStateLength
Definition: IRremoteESP8266.h:949
+
gree_ac_remote_model_t
Gree A/C model numbers.
Definition: IRsend.h:129
+
const uint16_t kSamsungAcDefaultRepeat
Definition: IRremoteESP8266.h:973
+
const uint16_t kSanyoLC7461Bits
Definition: IRremoteESP8266.h:977
+
float degrees
Definition: IRsend.h:102
+
uint8_t _dutycycle
Definition: IRsend.h:657
+
bool celsius
Definition: IRsend.h:103
+
void sendLG2(uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)
Send an LG Variant-2 formatted message. (LG2) Status: Beta / Should be working.
Definition: ir_LG.cpp:103
+
const uint16_t kZepealMinRepeat
Definition: IRremoteESP8266.h:1011
+
VIRTUAL uint16_t mark(uint16_t usec)
Modulate the IR LED for the given period (usec) and at the duty cycle set.
Definition: IRsend.cpp:157
+
@ ARRY4
Definition: IRsend.h:125
+
@ ARDB1
Definition: IRsend.h:122
+ +
void sendDaikin152(const unsigned char data[], const uint16_t nbytes=kDaikin152StateLength, const uint16_t repeat=kDaikin152DefaultRepeat)
Send a Daikin152 (152-bit) A/C formatted message. Status: STABLE / Known Working.
Definition: ir_Daikin.cpp:3169
+
void sendAmcor(const unsigned char data[], const uint16_t nbytes=kAmcorStateLength, const uint16_t repeat=kAmcorDefaultRepeat)
Send a Amcor HVAC formatted message. Status: STABLE / Reported as working.
Definition: ir_Amcor.cpp:39
+
stdAc::swingv_t swingv
Definition: IRsend.h:105
+
void sendLasertag(uint64_t data, uint16_t nbits=kLasertagBits, uint16_t repeat=kLasertagMinRepeat)
Send a Lasertag packet/message. Status: STABLE / Working.
Definition: ir_Lasertag.cpp:33
+
hitachi_ac1_remote_model_t
HITACHI_AC1 A/C model numbers.
Definition: IRsend.h:135
+
void sendEpson(uint64_t data, uint16_t nbits=kEpsonBits, uint16_t repeat=kEpsonMinRepeat)
Send an Epson formatted message. Status: Beta / Probably works.
Definition: ir_Epson.cpp:24
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void sendManchesterData(const uint16_t half_period, const uint64_t data, const uint16_t nbits, const bool MSBfirst=true, const bool GEThomas=true)
Generic method for sending Manchester code data. Will send leading or trailing 0's if the nbits is la...
Definition: IRsend.cpp:445
+
const uint16_t kAiwaRcT501MinRepeats
Definition: IRremoteESP8266.h:816
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+ +
const uint16_t kMitsubishiMinRepeat
Definition: IRremoteESP8266.h:929
+
uint64_t encodeSanyoLC7461(uint16_t address, uint8_t command)
Construct a Sanyo LC7461 message.
Definition: ir_Sanyo.cpp:61
+
@ ARJW2
Definition: IRsend.h:124
+
const uint16_t kArgoStateLength
Definition: IRremoteESP8266.h:821
+ +
uint32_t encodeSAMSUNG(const uint8_t customer, const uint8_t command)
Construct a raw Samsung message from the supplied customer(address) & command. Status: STABLE / Shoul...
Definition: ir_Samsung.cpp:89
+
const uint16_t kPanasonicBits
Definition: IRremoteESP8266.h:952
+
int16_t model
Definition: IRsend.h:99
+
uint64_t toggleRC6(const uint64_t data, const uint16_t nbits=kRC6Mode0Bits)
Flip the toggle bit of a Philips RC-6 data message. Used to indicate a change of remote button's stat...
Definition: ir_RC5_RC6.cpp:157
+
void sendSony(const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat)
Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) Status: STABLE / Known working.
Definition: ir_Sony.cpp:46
+
const uint8_t kDutyMax
Definition: IRsend.h:36
+
uint32_t _freq_unittest
Definition: IRsend.h:651
+
const uint16_t kDaikin152StateLength
Definition: IRremoteESP8266.h:852
+
uint32_t encodeLG(uint16_t address, uint16_t command)
Construct a raw 28-bit LG message code from the supplied address & command. Status: STABLE / Works.
Definition: ir_LG.cpp:131
+
void sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz)
Send a raw IRremote message.
Definition: IRsend.cpp:539
+
void sendMultibrackets(const uint64_t data, const uint16_t nbits=kMultibracketsBits, const uint16_t repeat=kMultibracketsDefaultRepeat)
Send a Multibrackets formatted message. Status: BETA / Appears to be working.
Definition: ir_Multibrackets.cpp:26
+ +
const uint16_t kHaierACYRW02StateLength
Definition: IRremoteESP8266.h:889
+
uint64_t encodeRC6(const uint32_t address, const uint8_t command, const uint16_t mode=kRC6Mode0Bits)
Encode a Philips RC-6 data message. Status: Beta / Should be working.
Definition: ir_RC5_RC6.cpp:171
+
const uint16_t kMultibracketsDefaultRepeat
Definition: IRremoteESP8266.h:946
+
void sendMitsubishi112(const unsigned char data[], const uint16_t nbytes=kMitsubishi112StateLength, const uint16_t repeat=kMitsubishi112MinRepeat)
Send a Mitsubishi 112-bit A/C formatted message. (MITSUBISHI112) Status: Stable / Reported as working...
Definition: ir_Mitsubishi.cpp:1184
+
@ kPanasonicCkp
Definition: IRsend.h:147
+
void sendWhirlpoolAC(const unsigned char data[], const uint16_t nbytes=kWhirlpoolAcStateLength, const uint16_t repeat=kWhirlpoolAcDefaultRepeat)
Send a Whirlpool A/C message. Status: BETA / Probably works.
Definition: ir_Whirlpool.cpp:50
+ +
void sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark, uint32_t zerospace, uint64_t data, uint16_t nbits, bool MSBfirst=true)
Generic method for sending data that is common to most protocols. Will send leading or trailing 0's i...
Definition: IRsend.cpp:246
+
const uint16_t kGoodweatherBits
Definition: IRremoteESP8266.h:881
+
void sendKelvinator(const unsigned char data[], const uint16_t nbytes=kKelvinatorStateLength, const uint16_t repeat=kKelvinatorDefaultRepeat)
Send a Kelvinator A/C message. Status: STABLE / Known working.
Definition: ir_Kelvinator.cpp:78
+
VIRTUAL void ledOn()
Turn on the IR LED.
Definition: IRsend.cpp:60
+
const uint16_t kGicableMinRepeat
Definition: IRremoteESP8266.h:880
+
void sendHitachiAC1(const unsigned char data[], const uint16_t nbytes=kHitachiAc1StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) Status: STABLE / Confirmed Workin...
Definition: ir_Hitachi.cpp:87
+
const uint16_t kDaikin216StateLength
Definition: IRremoteESP8266.h:858
+
void sendGICable(uint64_t data, uint16_t nbits=kGicableBits, uint16_t repeat=kGicableMinRepeat)
Send a raw G.I. Cable formatted message. Status: Alpha / Untested.
Definition: ir_GICable.cpp:37
+
const uint16_t kSamsungAcStateLength
Definition: IRremoteESP8266.h:969
+
@ DG11J13A
Definition: IRsend.h:153
+
void sendSharp(const uint16_t address, const uint16_t command, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
Send a Sharp message Status: DEPRECATED / Previously working fine.
Definition: ir_Sharp.cpp:134
+
panasonic_ac_remote_model_t
Panasonic A/C model numbers.
Definition: IRsend.h:141
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+ +
@ AKB75215403
Definition: IRsend.h:160
+
void sendDenon(uint64_t data, uint16_t nbits=kDenonBits, uint16_t repeat=kNoRepeat)
Send a Denon formatted message. Status: STABLE / Should be working.
Definition: ir_Denon.cpp:48
+
void sendCarrierAC64(uint64_t data, uint16_t nbits=kCarrierAc64Bits, uint16_t repeat=kCarrierAc64MinRepeat)
Send a Carrier 64bit HVAC formatted message. Status: STABLE / Known to be working.
Definition: ir_Carrier.cpp:178
+
void sendPioneer(const uint64_t data, const uint16_t nbits=kPioneerBits, const uint16_t repeat=kNoRepeat)
Send a raw Pioneer formatted message. Status: STABLE / Expected to be working.
Definition: ir_Pioneer.cpp:46
+
@ YAW1F
Definition: IRsend.h:130
+
const uint16_t kSymphonyBits
Definition: IRremoteESP8266.h:992
+ +
const uint16_t kDaikin128StateLength
Definition: IRremoteESP8266.h:849
+
const uint16_t kRC6Mode0Bits
Definition: IRremoteESP8266.h:964
+
const uint16_t kDaikin176DefaultRepeat
Definition: IRremoteESP8266.h:857
+
void sendPanasonic64(const uint64_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
Send a Panasonic formatted message. Status: STABLE / Should be working.
Definition: ir_Panasonic.cpp:74
+
const uint16_t kMitsubishiHeavy152MinRepeat
Definition: IRremoteESP8266.h:944
+
void sendHaierAC(const unsigned char data[], const uint16_t nbytes=kHaierACStateLength, const uint16_t repeat=kHaierAcDefaultRepeat)
Send a Haier A/C formatted message. (HSU07-HEA03 remote) Status: STABLE / Known to be working.
Definition: ir_Haier.cpp:45
+
void sendSamsung36(const uint64_t data, const uint16_t nbits=kSamsung36Bits, const uint16_t repeat=kNoRepeat)
Send a Samsung 36-bit formatted message. Status: Alpha / Experimental.
Definition: ir_Samsung.cpp:154
+
const uint16_t kNoRepeat
Definition: IRremoteESP8266.h:810
+
uint16_t offTimePeriod
Definition: IRsend.h:654
+
const uint16_t kSony20Bits
Definition: IRremoteESP8266.h:989
+
const uint16_t kMitsubishiACMinRepeat
Definition: IRremoteESP8266.h:932
+
void sendSony38(const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat+1)
Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. Status: STABLE / Known working...
Definition: ir_Sony.cpp:62
+
uint32_t encodeSony(const uint16_t nbits, const uint16_t command, const uint16_t address, const uint16_t extended=0)
Convert Sony/SIRC command, address, & extended bits into sendSony format. Status: STABLE / Should be ...
Definition: ir_Sony.cpp:88
+ +
@ kPanasonicUnknown
Definition: IRsend.h:142
+
fujitsu_ac_remote_model_t
Fujitsu A/C model numbers.
Definition: IRsend.h:120
+
const uint16_t kPanasonicAcDefaultRepeat
Definition: IRremoteESP8266.h:958
+
const uint16_t kSymphonyDefaultRepeat
Definition: IRremoteESP8266.h:993
+
@ ARREB1E
Definition: IRsend.h:123
+
void sendPanasonicAC(const unsigned char data[], const uint16_t nbytes=kPanasonicAcStateLength, const uint16_t repeat=kPanasonicAcDefaultRepeat)
Send a Panasonic A/C message. Status: STABLE / Work with real device(s).
Definition: ir_Panasonic.cpp:173
+
stdAc::swingh_t swingh
Definition: IRsend.h:106
+
const uint16_t kCoolixDefaultRepeat
Definition: IRremoteESP8266.h:825
+
@ kPanasonicNke
Definition: IRsend.h:144
+
@ GE6711AR2853M
Definition: IRsend.h:159
+
void sendHitachiAc3(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi(3) A/C formatted message. (HITACHI_AC3) Status: STABLE / Working fine.
Definition: ir_Hitachi.cpp:1361
+
const uint16_t kTcl112AcDefaultRepeat
Definition: IRremoteESP8266.h:996
+
const uint16_t kDelonghiAcDefaultRepeat
Definition: IRremoteESP8266.h:862
+
void sendToshibaAC(const unsigned char data[], const uint16_t nbytes=kToshibaACStateLength, const uint16_t repeat=kToshibaACMinRepeat)
Send a Toshiba A/C message. Status: STABLE / Working.
Definition: ir_Toshiba.cpp:44
+
const uint16_t kCoronaAcStateLength
Definition: IRremoteESP8266.h:833
+
void sendRC5(const uint64_t data, uint16_t nbits=kRC5XBits, const uint16_t repeat=kNoRepeat)
Send a Philips RC-5/RC-5X packet. Status: RC-5 (stable), RC-5X (alpha)
Definition: ir_RC5_RC6.cpp:61
+
void sendMitsubishi(uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)
Send the supplied Mitsubishi 16-bit message. Status: STABLE / Working.
Definition: ir_Mitsubishi.cpp:104
+
void sendAirwell(uint64_t data, uint16_t nbits=kAirwellBits, uint16_t repeat=kAirwellMinRepeats)
Send an Airwell Manchester Code formatted message. Status: BETA / Appears to be working.
Definition: ir_Airwell.cpp:28
+
const uint16_t kDoshishaBits
Definition: IRremoteESP8266.h:868
+
const uint16_t kCarrierAc40Bits
Definition: IRremoteESP8266.h:828
+ +
const uint16_t kTrotecStateLength
Definition: IRremoteESP8266.h:1002
+
const uint16_t kWhirlpoolAcDefaultRepeat
Definition: IRremoteESP8266.h:1007
+
void sendSAMSUNG(const uint64_t data, const uint16_t nbits=kSamsungBits, const uint16_t repeat=kNoRepeat)
Send a 32-bit Samsung formatted message. Status: STABLE / Should be working.
Definition: ir_Samsung.cpp:75
+
const uint16_t kHitachiAc424StateLength
Definition: IRremoteESP8266.h:905
+
const uint16_t kMitsubishiHeavy88StateLength
Definition: IRremoteESP8266.h:939
+
void sendNeoclima(const unsigned char data[], const uint16_t nbytes=kNeoclimaStateLength, const uint16_t repeat=kNeoclimaMinRepeat)
Send a Neoclima message. Status: STABLE / Known to be working.
Definition: ir_Neoclima.cpp:41
+
void sendSharpRaw(const uint64_t data, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
Send a (raw) Sharp message.
Definition: ir_Sharp.cpp:64
+ +
void sendGree(const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)
Send a Gree Heat Pump formatted message. Status: STABLE / Working.
Definition: ir_Gree.cpp:76
+ +
const uint16_t kMitsubishiBits
Definition: IRremoteESP8266.h:926
+
void sendMitsubishi136(const unsigned char data[], const uint16_t nbytes=kMitsubishi136StateLength, const uint16_t repeat=kMitsubishi136MinRepeat)
Send a Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: BETA / Probably working....
Definition: ir_Mitsubishi.cpp:812
+
Enumerators and Structures for the Common A/C API.
Definition: IRsend.h:44
+
@ R_LT0541_HTA_A
Definition: IRsend.h:136
+
const uint16_t kPanasonicAcStateLength
Definition: IRremoteESP8266.h:954
+
void sendMitsubishiHeavy88(const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy88StateLength, const uint16_t repeat=kMitsubishiHeavy88MinRepeat)
Send a MitsubishiHeavy 88-bit A/C message. Status: BETA / Appears to be working. Needs testing agains...
Definition: ir_MitsubishiHeavy.cpp:45
+
void sendVestelAc(const uint64_t data, const uint16_t nbits=kVestelAcBits, const uint16_t repeat=kNoRepeat)
Send a Vestel message Status: STABLE / Working.
Definition: ir_Vestel.cpp:38
+
const uint16_t kMideaBits
Definition: IRremoteESP8266.h:922
+
const uint16_t kKelvinatorStateLength
Definition: IRremoteESP8266.h:910
+
void sendMidea24(const uint64_t data, const uint16_t nbits=kMidea24Bits, const uint16_t repeat=kMidea24MinRepeat)
Send a Midea24 formatted message. Status: STABLE / Confirmed working on a real device.
Definition: ir_Midea.cpp:479
+
static uint16_t defaultBits(const decode_type_t protocol)
Get the default number of bits for a given protocol.
Definition: IRsend.cpp:598
+
decode_type_t protocol
Definition: IRsend.h:98
+ +
const uint16_t kDaikin216DefaultRepeat
Definition: IRremoteESP8266.h:860
+ +
bool beep
Definition: IRsend.h:113
+
const uint16_t kWhirlpoolAcStateLength
Definition: IRremoteESP8266.h:1005
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint16_t kDenonBits
Definition: IRremoteESP8266.h:863
+
const uint16_t kZepealBits
Definition: IRremoteESP8266.h:1010
+
bool filter
Definition: IRsend.h:111
+
const uint16_t kCarrierAc40MinRepeat
Definition: IRremoteESP8266.h:829
+
const uint16_t kMidea24Bits
Definition: IRremoteESP8266.h:924
+
void sendDelonghiAc(uint64_t data, uint16_t nbits=kDelonghiAcBits, uint16_t repeat=kDelonghiAcDefaultRepeat)
Send a Delonghi A/C formatted message. Status: STABLE / Reported as working on a real device.
Definition: ir_Delonghi.cpp:38
+
const uint16_t kDaikin160DefaultRepeat
Definition: IRremoteESP8266.h:848
+
void _sendSony(const uint64_t data, const uint16_t nbits, const uint16_t repeat, const uint16_t freq)
Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message Status: STABLE / Known w...
Definition: ir_Sony.cpp:73
+
const uint16_t kToshibaACMinRepeat
Definition: IRremoteESP8266.h:1001
+
void enableIROut(uint32_t freq, uint8_t duty=kDutyDefault)
Set the output frequency modulation and duty cycle.
Definition: IRsend.cpp:92
+ +
const uint16_t kHitachiAc344StateLength
Definition: IRremoteESP8266.h:903
+
@ kPanasonicDke
Definition: IRsend.h:145
+
const uint16_t kCarrierAc64Bits
Definition: IRremoteESP8266.h:830
+
const uint16_t kDaikin128DefaultRepeat
Definition: IRremoteESP8266.h:851
+
const uint16_t kPioneerBits
Definition: IRremoteESP8266.h:959
+
const uint16_t kSharpAcStateLength
Definition: IRremoteESP8266.h:982
+
void sendSharpAc(const unsigned char data[], const uint16_t nbytes=kSharpAcStateLength, const uint16_t repeat=kSharpAcDefaultRepeat)
Send a Sharp A/C message. Status: Alpha / Untested.
Definition: ir_Sharp.cpp:227
+
@ kPanasonicLke
Definition: IRsend.h:143
+
const uint16_t kGreeBits
Definition: IRremoteESP8266.h:884
+
void sendCarrierAC(uint64_t data, uint16_t nbits=kCarrierAcBits, uint16_t repeat=kCarrierAcMinRepeat)
Send a Carrier HVAC formatted message. Status: STABLE / Works on real devices.
Definition: ir_Carrier.cpp:57
+
const uint16_t kJvcBits
Definition: IRremoteESP8266.h:909
+
const uint16_t kDaikinStateLength
Definition: IRremoteESP8266.h:836
+
const uint16_t kLasertagBits
Definition: IRremoteESP8266.h:913
+
void sendDaikin160(const unsigned char data[], const uint16_t nbytes=kDaikin160StateLength, const uint16_t repeat=kDaikin160DefaultRepeat)
Send a Daikin160 (160-bit) A/C formatted message. Status: STABLE / Confirmed working.
Definition: ir_Daikin.cpp:1840
+
const uint16_t kAiwaRcT501Bits
Definition: IRremoteESP8266.h:815
+
void sendDaikin2(const unsigned char data[], const uint16_t nbytes=kDaikin2StateLength, const uint16_t repeat=kDaikin2DefaultRepeat)
Send a Daikin2 (312-bit) A/C formatted message. Status: STABLE / Expected to work.
Definition: ir_Daikin.cpp:689
+
@ ARRAH2E
Definition: IRsend.h:121
+
const uint16_t kToshibaACStateLength
Definition: IRremoteESP8266.h:999
+
const uint16_t kTecoBits
Definition: IRremoteESP8266.h:997
+
void sendMitsubishi2(uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)
Send a supplied second variant Mitsubishi 16-bit message. Status: BETA / Probably works.
Definition: ir_Mitsubishi.cpp:161
+
const uint16_t kInaxMinRepeat
Definition: IRremoteESP8266.h:908
+
VIRTUAL void ledOff()
Turn off the IR LED.
Definition: IRsend.cpp:53
+ +
const uint8_t kSherwoodBits
Definition: IRremoteESP8266.h:985
+
stdAc::opmode_t mode
Definition: IRsend.h:101
+
const uint16_t kDaikinDefaultRepeat
Definition: IRremoteESP8266.h:840
+
const uint16_t kDaikin64DefaultRepeat
Definition: IRremoteESP8266.h:845
+
void sendInax(const uint64_t data, const uint16_t nbits=kInaxBits, const uint16_t repeat=kInaxMinRepeat)
Send a Inax Toilet formatted message. Status: STABLE / Working.
Definition: ir_Inax.cpp:31
+
lg_ac_remote_model_t
LG A/C model numbers.
Definition: IRsend.h:158
+
const uint16_t kMitsubishiHeavy88MinRepeat
Definition: IRremoteESP8266.h:941
+ +
const uint16_t kHitachiAcDefaultRepeat
Definition: IRremoteESP8266.h:894
+
bool econo
Definition: IRsend.h:109
+
void sendSherwood(uint64_t data, uint16_t nbits=kSherwoodBits, uint16_t repeat=kSherwoodMinRepeat)
Send an IR command to a Sherwood device. Status: STABLE / Known working.
Definition: ir_Sherwood.cpp:21
+
const uint16_t kMidea24MinRepeat
Definition: IRremoteESP8266.h:925
+
void sendMitsubishiHeavy152(const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy152StateLength, const uint16_t repeat=kMitsubishiHeavy152MinRepeat)
Send a MitsubishiHeavy 152-bit A/C message. Status: BETA / Appears to be working. Needs testing again...
Definition: ir_MitsubishiHeavy.cpp:62
+
const uint16_t kDishBits
Definition: IRremoteESP8266.h:866
+
const uint16_t kDishMinRepeat
Definition: IRremoteESP8266.h:867
+ +
void sendPanasonic(const uint16_t address, const uint32_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
Send a Panasonic formatted message. Status: STABLE, but DEPRECATED.
Definition: ir_Panasonic.cpp:91
+
VIRTUAL void space(uint32_t usec)
Turn the pin (LED) off for a given time. Sends an IR space for the specified number of microseconds....
Definition: IRsend.cpp:194
+
const uint16_t kHitachiAc2StateLength
Definition: IRremoteESP8266.h:897
+
void sendGC(uint16_t buf[], uint16_t len)
Send a shortened GlobalCache (GC) IRdb/control tower formatted message. Status: STABLE / Known workin...
Definition: ir_GlobalCache.cpp:35
+
uint16_t encodeRC5(const uint8_t address, const uint8_t command, const bool key_released=false)
Encode a Philips RC-5 data message. Status: Beta / Should be working.
Definition: ir_RC5_RC6.cpp:115
+
void sendJVC(uint64_t data, uint16_t nbits=kJvcBits, uint16_t repeat=kNoRepeat)
Send a JVC formatted message. Status: STABLE / Working.
Definition: ir_JVC.cpp:46
+
void sendDoshisha(const uint64_t data, uint16_t nbits=kDoshishaBits, const uint16_t repeat=kNoRepeat)
Send a Doshisha formatted message. Status: STABLE / Works on real device.
Definition: ir_Doshisha.cpp:53
+ +
uint64_t toggleRC5(const uint64_t data)
Flip the toggle bit of a Philips RC-5/RC-5X data message. Used to indicate a change of remote button'...
Definition: ir_RC5_RC6.cpp:142
+
void sendDaikin(const unsigned char data[], const uint16_t nbytes=kDaikinStateLength, const uint16_t repeat=kDaikinDefaultRepeat)
Send a Daikin 280-bit A/C formatted message. Status: STABLE.
Definition: ir_Daikin.cpp:61
+
const uint16_t kCarrierAcMinRepeat
Definition: IRremoteESP8266.h:827
+
const uint16_t kNikaiBits
Definition: IRremoteESP8266.h:947
+
uint64_t encodeMagiQuest(const uint32_t wand_id, const uint16_t magnitude)
Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. (Only 48 bits of real data + 8...
Definition: ir_Magiquest.cpp:42
+ +
const uint16_t kKelvinatorDefaultRepeat
Definition: IRremoteESP8266.h:912
+
void sendHitachiAC2(const unsigned char data[], const uint16_t nbytes=kHitachiAc2StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) Basically the same as sendHitatch...
Definition: ir_Hitachi.cpp:105
+
const uint16_t kLutronBits
Definition: IRremoteESP8266.h:920
+
void sendDaikin128(const unsigned char data[], const uint16_t nbytes=kDaikin128StateLength, const uint16_t repeat=kDaikin128DefaultRepeat)
Send a Daikin128 (128-bit) A/C formatted message. Status: STABLE / Known Working.
Definition: ir_Daikin.cpp:2605
+
void sendCarrierAC40(uint64_t data, uint16_t nbits=kCarrierAc40Bits, uint16_t repeat=kCarrierAc40MinRepeat)
Send a Carrier 40bit HVAC formatted message. Status: STABLE / Tested against a real device.
Definition: ir_Carrier.cpp:129
+
const uint16_t kSharpAcDefaultRepeat
Definition: IRremoteESP8266.h:984
+ +
void sendTrotec(const unsigned char data[], const uint16_t nbytes=kTrotecStateLength, const uint16_t repeat=kTrotecDefaultRepeat)
Send a Trotec message. Status: Beta / Probably Working.
Definition: ir_Trotec.cpp:43
+
void sendCoronaAc(const uint8_t data[], const uint16_t nbytes=kCoronaAcStateLength, const uint16_t repeat=kNoRepeat)
Send a CoronaAc formatted message. Status: STABLE / Working on real device.
Definition: ir_Corona.cpp:51
+
bool light
Definition: IRsend.h:110
+
stdAc::fanspeed_t fanspeed
Definition: IRsend.h:104
+
const uint16_t kTcl112AcStateLength
Definition: IRremoteESP8266.h:994
+
void sendRCMM(uint64_t data, uint16_t nbits=kRCMMBits, uint16_t repeat=kNoRepeat)
Send a Philips RC-MM packet. Status: STABLE / Should be working.
Definition: ir_RCMM.cpp:46
+
void sendManchester(const uint16_t headermark, const uint32_t headerspace, const uint16_t half_period, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency=38, const bool MSBfirst=true, const uint16_t repeat=kNoRepeat, const uint8_t dutycycle=kDutyDefault, const bool GEThomas=true)
Generic method for sending Manchester code messages. Will send leading or trailing 0's if the nbits i...
Definition: IRsend.cpp:506
+
const uint16_t kDaikin160StateLength
Definition: IRremoteESP8266.h:846
+
void sendHitachiAC(const unsigned char data[], const uint16_t nbytes=kHitachiAcStateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) Status: STABLE / Working.
Definition: ir_Hitachi.cpp:66
+
const uint16_t kDaikin2StateLength
Definition: IRremoteESP8266.h:841
+
void sendElectraAC(const unsigned char data[], const uint16_t nbytes=kElectraAcStateLength, const uint16_t repeat=kNoRepeat)
Send a Electra A/C formatted message. Status: Alpha / Needs testing against a real device.
Definition: ir_Electra.cpp:41
+ +
const uint16_t kSherwoodMinRepeat
Definition: IRremoteESP8266.h:986
+
const uint16_t kCarrierAc64MinRepeat
Definition: IRremoteESP8266.h:831
+
@ DG11J191
Definition: IRsend.h:154
+
void begin()
Enable the pin for output.
Definition: IRsend.cpp:45
+
void sendFujitsuAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kFujitsuAcMinRepeat)
Send a Fujitsu A/C formatted message. Status: STABLE / Known Good.
Definition: ir_Fujitsu.cpp:47
+ +
uint32_t encodeSharp(const uint16_t address, const uint16_t command, const uint16_t expansion=1, const uint16_t check=0, const bool MSBfirst=false)
Encode a (raw) Sharp message from it's components. Status: STABLE / Works okay.
Definition: ir_Sharp.cpp:99
+ +
const uint16_t kLegoPfBits
Definition: IRremoteESP8266.h:915
+
const uint16_t kSharpBits
Definition: IRremoteESP8266.h:981
+
int16_t sleep
Definition: IRsend.h:114
+
bool power
Definition: IRsend.h:100
+ +
void sendHitachiAc424(const unsigned char data[], const uint16_t nbytes=kHitachiAc424StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) Status: STABLE / Reported as wo...
Definition: ir_Hitachi.cpp:949
+
void sendTeco(const uint64_t data, const uint16_t nbits=kTecoBits, const uint16_t repeat=kNoRepeat)
Send a Teco A/C message. Status: Beta / Probably working.
Definition: ir_Teco.cpp:39
+ +
const uint16_t kMitsubishi136StateLength
Definition: IRremoteESP8266.h:933
+
void sendLutron(uint64_t data, uint16_t nbits=kLutronBits, uint16_t repeat=kNoRepeat)
Send a Lutron formatted message. Status: Stable / Appears to be working for real devices.
Definition: ir_Lutron.cpp:41
+
void sendSamsungAC(const unsigned char data[], const uint16_t nbytes=kSamsungAcStateLength, const uint16_t repeat=kSamsungAcDefaultRepeat)
Send a Samsung A/C message. Status: Stable / Known working.
Definition: ir_Samsung.cpp:235
+
uint64_t encodePanasonic(const uint16_t manufacturer, const uint8_t device, const uint8_t subdevice, const uint8_t function)
Calculate the raw Panasonic data based on device, subdevice, & function. Status: STABLE / Should be w...
Definition: ir_Panasonic.cpp:105
+
void sendSanyoLC7461(const uint64_t data, const uint16_t nbits=kSanyoLC7461Bits, const uint16_t repeat=kNoRepeat)
Send a Sanyo LC7461 message. Status: BETA / Probably works.
Definition: ir_Sanyo.cpp:93
+
IRsend(uint16_t IRsendPin, bool inverted=false, bool use_modulation=true)
Constructor for an IRsend object.
Definition: IRsend.cpp:28
+
void sendDISH(uint64_t data, uint16_t nbits=kDishBits, uint16_t repeat=kDishMinRepeat)
Send a DISH NETWORK formatted message. Status: STABLE / Working.
Definition: ir_Dish.cpp:48
+
const uint16_t kRCMMBits
Definition: IRremoteESP8266.h:966
+
const uint8_t kVestelAcBits
Definition: IRremoteESP8266.h:1009
+
const uint16_t kInaxBits
Definition: IRremoteESP8266.h:907
+
@ YBOFB
Definition: IRsend.h:131
+
const uint16_t kLegoPfMinRepeat
Definition: IRremoteESP8266.h:916
+
const uint16_t kAmcorDefaultRepeat
Definition: IRremoteESP8266.h:820
+
void sendDaikin216(const unsigned char data[], const uint16_t nbytes=kDaikin216StateLength, const uint16_t repeat=kDaikin216DefaultRepeat)
Send a Daikin216 (216-bit) A/C formatted message. Status: Alpha / Untested on a real device.
Definition: ir_Daikin.cpp:1476
+
const uint16_t kSamsungBits
Definition: IRremoteESP8266.h:967
+
uint64_t encodePioneer(uint16_t address, uint16_t command)
Calculate the raw Pioneer data code based on two NEC sub-codes Status: STABLE / Expected to work.
Definition: ir_Pioneer.cpp:81
+
const uint16_t kDaikin64Bits
Definition: IRremoteESP8266.h:844
+
bool quiet
Definition: IRsend.h:107
+
uint16_t encodeRC5X(const uint8_t address, const uint8_t command, const bool key_released=false)
Encode a Philips RC-5X data message. Status: Beta / Should be working.
Definition: ir_RC5_RC6.cpp:127
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint16_t kLasertagMinRepeat
Definition: IRremoteESP8266.h:914
+
const uint8_t kDutyDefault
Definition: IRsend.h:35
+
bool turbo
Definition: IRsend.h:108
+
void sendMagiQuest(const uint64_t data, const uint16_t nbits=kMagiquestBits, const uint16_t repeat=kNoRepeat)
Send a MagiQuest formatted message. Status: Beta / Should be working.
Definition: ir_Magiquest.cpp:25
+
bool modulation
Definition: IRsend.h:658
+
const uint16_t kNeoclimaMinRepeat
Definition: IRremoteESP8266.h:951
+
const uint16_t kMitsubishi112StateLength
Definition: IRremoteESP8266.h:936
+ +
void sendArgo(const unsigned char data[], const uint16_t nbytes=kArgoStateLength, const uint16_t repeat=kArgoDefaultRepeat)
Send a Argo A/C formatted message. Status: BETA / Probably works.
Definition: ir_Argo.cpp:40
+
void sendTcl112Ac(const unsigned char data[], const uint16_t nbytes=kTcl112AcStateLength, const uint16_t repeat=kTcl112AcDefaultRepeat)
Send a TCL 112-bit A/C message. Status: Beta / Probably working.
Definition: ir_Tcl.cpp:33
+
@ kPanasonicJke
Definition: IRsend.h:146
+ +
const uint16_t kSonyMinRepeat
Definition: IRremoteESP8266.h:991
+
void sendCOOLIX(uint64_t data, uint16_t nbits=kCoolixBits, uint16_t repeat=kCoolixDefaultRepeat)
Send a Coolix message Status: STABLE / Confirmed Working.
Definition: ir_Coolix.cpp:51
+
const uint16_t kEpsonBits
Definition: IRremoteESP8266.h:869
+
void sendNEC(uint64_t data, uint16_t nbits=kNECBits, uint16_t repeat=kNoRepeat)
Send a raw NEC(Renesas) formatted message. Status: STABLE / Known working.
Definition: ir_NEC.cpp:28
+
void sendMWM(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kNoRepeat)
Send a MWM packet/message. Status: Implemented.
Definition: ir_MWM.cpp:37
+
void sendDaikin64(const uint64_t data, const uint16_t nbits=kDaikin64Bits, const uint16_t repeat=kDaikin64DefaultRepeat)
Send a Daikin64 (64-bit) A/C formatted message. Status: Beta / Probably Working.
Definition: ir_Daikin.cpp:3558
+
void sendRC6(const uint64_t data, const uint16_t nbits=kRC6Mode0Bits, const uint16_t repeat=kNoRepeat)
Send a Philips RC-6 packet. Status: Stable.
Definition: ir_RC5_RC6.cpp:190
+
const int8_t kPeriodOffset
Definition: IRsend.h:26
+
const uint16_t kLgBits
Definition: IRremoteESP8266.h:917
+
void sendDaikin176(const unsigned char data[], const uint16_t nbytes=kDaikin176StateLength, const uint16_t repeat=kDaikin176DefaultRepeat)
Send a Daikin176 (176-bit) A/C formatted message. Status: Alpha / Untested on a real device.
Definition: ir_Daikin.cpp:2212
+
const uint16_t kGoodweatherMinRepeat
Definition: IRremoteESP8266.h:882
+
const uint16_t kElectraAcStateLength
Definition: IRremoteESP8266.h:871
+
const uint16_t kGreeDefaultRepeat
Definition: IRremoteESP8266.h:885
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+
void sendGoodweather(const uint64_t data, const uint16_t nbits=kGoodweatherBits, const uint16_t repeat=kGoodweatherMinRepeat)
Send a Goodweather HVAC formatted message. Status: BETA / Needs testing on real device.
Definition: ir_Goodweather.cpp:33
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8cpp.html new file mode 100644 index 000000000..cbef4a002 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8cpp.html @@ -0,0 +1,2807 @@ + + + + + + + +IRremoteESP8266: src/IRtext.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRtext.cpp File Reference
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const PROGMEM char * kUnknownStr = D_STR_UNKNOWN
 "Unknown" More...
 
const PROGMEM char * kProtocolStr = D_STR_PROTOCOL
 "Protocol" More...
 
const PROGMEM char * kPowerStr = D_STR_POWER
 "Power" More...
 
const PROGMEM char * kOnStr = D_STR_ON
 "On" More...
 
const PROGMEM char * kOffStr = D_STR_OFF
 "Off" More...
 
const PROGMEM char * kModeStr = D_STR_MODE
 "Mode" More...
 
const PROGMEM char * kToggleStr = D_STR_TOGGLE
 "Toggle" More...
 
const PROGMEM char * kTurboStr = D_STR_TURBO
 "Turbo" More...
 
const PROGMEM char * kSuperStr = D_STR_SUPER
 "Super" More...
 
const PROGMEM char * kSleepStr = D_STR_SLEEP
 "Sleep" More...
 
const PROGMEM char * kLightStr = D_STR_LIGHT
 "Light" More...
 
const PROGMEM char * kPowerfulStr = D_STR_POWERFUL
 "Powerful" More...
 
const PROGMEM char * kQuietStr = D_STR_QUIET
 "Quiet" More...
 
const PROGMEM char * kEconoStr = D_STR_ECONO
 "Econo" More...
 
const PROGMEM char * kSwingStr = D_STR_SWING
 "Swing" More...
 
const PROGMEM char * kSwingHStr = D_STR_SWINGH
 "SwingH" More...
 
const PROGMEM char * kSwingVStr = D_STR_SWINGV
 "SwingV" More...
 
const PROGMEM char * kBeepStr = D_STR_BEEP
 "Beep" More...
 
const PROGMEM char * kZoneFollowStr = D_STR_ZONEFOLLOW
 "Zone Follow" More...
 
const PROGMEM char * kFixedStr = D_STR_FIXED
 "Fixed" More...
 
const PROGMEM char * kMouldStr = D_STR_MOULD
 "Mould" More...
 
const PROGMEM char * kCleanStr = D_STR_CLEAN
 "Clean" More...
 
const PROGMEM char * kPurifyStr = D_STR_PURIFY
 "Purify" More...
 
const PROGMEM char * kTimerStr = D_STR_TIMER
 "Timer" More...
 
const PROGMEM char * kOnTimerStr = D_STR_ONTIMER
 "OnTimer" More...
 
const PROGMEM char * kOffTimerStr = D_STR_OFFTIMER
 "OffTimer" More...
 
const PROGMEM char * kClockStr = D_STR_CLOCK
 "Clock" More...
 
const PROGMEM char * kCommandStr = D_STR_COMMAND
 "Command" More...
 
const PROGMEM char * kXFanStr = D_STR_XFAN
 "XFan" More...
 
const PROGMEM char * kHealthStr = D_STR_HEALTH
 "Health" More...
 
const PROGMEM char * kModelStr = D_STR_MODEL
 "Model" More...
 
const PROGMEM char * kTempStr = D_STR_TEMP
 "Temp" More...
 
const PROGMEM char * kIFeelStr = D_STR_IFEEL
 "IFeel" More...
 
const PROGMEM char * kHumidStr = D_STR_HUMID
 "Humid" More...
 
const PROGMEM char * kSaveStr = D_STR_SAVE
 "Save" More...
 
const PROGMEM char * kEyeStr = D_STR_EYE
 "Eye" More...
 
const PROGMEM char * kFollowStr = D_STR_FOLLOW
 "Follow" More...
 
const PROGMEM char * kIonStr = D_STR_ION
 "Ion" More...
 
const PROGMEM char * kFreshStr = D_STR_FRESH
 "Fresh" More...
 
const PROGMEM char * kHoldStr = D_STR_HOLD
 "Hold" More...
 
const PROGMEM char * kButtonStr = D_STR_BUTTON
 "Button" More...
 
const PROGMEM char * k8CHeatStr = D_STR_8C_HEAT
 "8CHeat" More...
 
const PROGMEM char * kNightStr = D_STR_NIGHT
 "Night" More...
 
const PROGMEM char * kSilentStr = D_STR_SILENT
 "Silent" More...
 
const PROGMEM char * kFilterStr = D_STR_FILTER
 "Filter" More...
 
const PROGMEM char * k3DStr = D_STR_3D
 "3D" More...
 
const PROGMEM char * kCelsiusStr = D_STR_CELSIUS
 "Celsius" More...
 
const PROGMEM char * kTempUpStr = D_STR_TEMPUP
 "Temp Up" More...
 
const PROGMEM char * kTempDownStr = D_STR_TEMPDOWN
 "Temp Down" More...
 
const PROGMEM char * kStartStr = D_STR_START
 "Start" More...
 
const PROGMEM char * kStopStr = D_STR_STOP
 "Stop" More...
 
const PROGMEM char * kMoveStr = D_STR_MOVE
 "Move" More...
 
const PROGMEM char * kSetStr = D_STR_SET
 "Set" More...
 
const PROGMEM char * kCancelStr = D_STR_CANCEL
 "Cancel" More...
 
const PROGMEM char * kUpStr = D_STR_UP
 "Up" More...
 
const PROGMEM char * kDownStr = D_STR_DOWN
 "Down" More...
 
const PROGMEM char * kChangeStr = D_STR_CHANGE
 "Change" More...
 
const PROGMEM char * kComfortStr = D_STR_COMFORT
 "Comfort" More...
 
const PROGMEM char * kSensorStr = D_STR_SENSOR
 "Sensor" More...
 
const PROGMEM char * kWeeklyTimerStr = D_STR_WEEKLYTIMER
 "WeeklyTimer" More...
 
const PROGMEM char * kWifiStr = D_STR_WIFI
 "Wifi" More...
 
const PROGMEM char * kLastStr = D_STR_LAST
 "Last" More...
 
const PROGMEM char * kFastStr = D_STR_FAST
 "Fast" More...
 
const PROGMEM char * kSlowStr = D_STR_SLOW
 "Slow" More...
 
const PROGMEM char * kAirFlowStr = D_STR_AIRFLOW
 "Air Flow" More...
 
const PROGMEM char * kStepStr = D_STR_STEP
 "Step" More...
 
const PROGMEM char * kNAStr = D_STR_NA
 "N/A" More...
 
const PROGMEM char * kInsideStr = D_STR_INSIDE
 "Inside" More...
 
const PROGMEM char * kOutsideStr = D_STR_OUTSIDE
 "Outside" More...
 
const PROGMEM char * kLoudStr = D_STR_LOUD
 "Loud" More...
 
const PROGMEM char * kLowerStr = D_STR_LOWER
 "Lower" More...
 
const PROGMEM char * kUpperStr = D_STR_UPPER
 "Upper" More...
 
const PROGMEM char * kBreezeStr = D_STR_BREEZE
 "Breeze" More...
 
const PROGMEM char * kCirculateStr = D_STR_CIRCULATE
 "Circulate" More...
 
const PROGMEM char * kCeilingStr = D_STR_CEILING
 "Ceiling" More...
 
const PROGMEM char * kWallStr = D_STR_WALL
 "Wall" More...
 
const PROGMEM char * kRoomStr = D_STR_ROOM
 "Room" More...
 
const PROGMEM char * k6thSenseStr = D_STR_6THSENSE
 "6th Sense" More...
 
const PROGMEM char * kAutoStr = D_STR_AUTO
 "Auto" More...
 
const PROGMEM char * kAutomaticStr = D_STR_AUTOMATIC
 "Automatic" More...
 
const PROGMEM char * kManualStr = D_STR_MANUAL
 "Manual" More...
 
const PROGMEM char * kCoolStr = D_STR_COOL
 "Cool" More...
 
const PROGMEM char * kHeatStr = D_STR_HEAT
 "Heat" More...
 
const PROGMEM char * kFanStr = D_STR_FAN
 "Fan" More...
 
const PROGMEM char * kDryStr = D_STR_DRY
 "Dry" More...
 
const PROGMEM char * kFanOnlyStr = D_STR_FANONLY
 "fan_only" More...
 
const PROGMEM char * kMaxStr = D_STR_MAX
 "Max" More...
 
const PROGMEM char * kMaximumStr = D_STR_MAXIMUM
 "Maximum" More...
 
const PROGMEM char * kMinStr = D_STR_MIN
 "Min" More...
 
const PROGMEM char * kMinimumStr = D_STR_MINIMUM
 "Minimum" More...
 
const PROGMEM char * kMedStr = D_STR_MED
 "Med" More...
 
const PROGMEM char * kMediumStr = D_STR_MEDIUM
 "Medium" More...
 
const PROGMEM char * kHighestStr = D_STR_HIGHEST
 "Highest" More...
 
const PROGMEM char * kHighStr = D_STR_HIGH
 "High" More...
 
const PROGMEM char * kHiStr = D_STR_HI
 "Hi" More...
 
const PROGMEM char * kMidStr = D_STR_MID
 "Mid" More...
 
const PROGMEM char * kMiddleStr = D_STR_MIDDLE
 "Middle" More...
 
const PROGMEM char * kLowStr = D_STR_LOW
 "Low" More...
 
const PROGMEM char * kLoStr = D_STR_LO
 "Lo" More...
 
const PROGMEM char * kLowestStr = D_STR_LOWEST
 "Lowest" More...
 
const PROGMEM char * kMaxRightStr = D_STR_MAXRIGHT
 "Max Right" More...
 
const PROGMEM char * kRightMaxStr = D_STR_RIGHTMAX_NOSPACE
 "RightMax" More...
 
const PROGMEM char * kRightStr = D_STR_RIGHT
 "Right" More...
 
const PROGMEM char * kLeftStr = D_STR_LEFT
 "Left" More...
 
const PROGMEM char * kMaxLeftStr = D_STR_MAXLEFT
 "Max Left" More...
 
const PROGMEM char * kLeftMaxStr = D_STR_LEFTMAX_NOSPACE
 "LeftMax" More...
 
const PROGMEM char * kWideStr = D_STR_WIDE
 "Wide" More...
 
const PROGMEM char * kCentreStr = D_STR_CENTRE
 "Centre" More...
 
const PROGMEM char * kTopStr = D_STR_TOP
 "Top" More...
 
const PROGMEM char * kBottomStr = D_STR_BOTTOM
 "Bottom" More...
 
const PROGMEM char * kEyeAutoStr = D_STR_EYEAUTO
 "Eye Auto" More...
 
const PROGMEM char * kLightToggleStr = D_STR_LIGHTTOGGLE
 "Light Toggle" More...
 
const PROGMEM char * kOutsideQuietStr = D_STR_OUTSIDEQUIET
 "Outside Quiet" More...
 
const PROGMEM char * kPowerToggleStr = D_STR_POWERTOGGLE
 "Power Toggle" More...
 
const PROGMEM char * kPowerButtonStr = D_STR_POWERBUTTON
 "Power Button" More...
 
const PROGMEM char * kPreviousPowerStr = D_STR_PREVIOUSPOWER
 "Previous Power" More...
 
const PROGMEM char * kDisplayTempStr = D_STR_DISPLAYTEMP
 "Display Temp" More...
 
const PROGMEM char * kSensorTempStr = D_STR_SENSORTEMP
 "Sensor Temp" More...
 
const PROGMEM char * kSleepTimerStr = D_STR_SLEEP_TIMER
 "Sleep Timer" More...
 
const PROGMEM char * kSwingVModeStr = D_STR_SWINGVMODE
 "Swing(V) Mode" More...
 
const PROGMEM char * kSwingVToggleStr = D_STR_SWINGVTOGGLE
 "Swing(V) Toggle" More...
 
char kTimeSep = D_CHR_TIME_SEP
 ':' More...
 
const PROGMEM char * kSpaceLBraceStr = D_STR_SPACELBRACE
 " (" More...
 
const PROGMEM char * kCommaSpaceStr = D_STR_COMMASPACE
 ", " More...
 
const PROGMEM char * kColonSpaceStr = D_STR_COLONSPACE
 ": " More...
 
const PROGMEM char * kDayStr = D_STR_DAY
 "Day" More...
 
const PROGMEM char * kDaysStr = D_STR_DAYS
 "Days" More...
 
const PROGMEM char * kHourStr = D_STR_HOUR
 "Hour" More...
 
const PROGMEM char * kHoursStr = D_STR_HOURS
 "Hours" More...
 
const PROGMEM char * kMinuteStr = D_STR_MINUTE
 "Minute" More...
 
const PROGMEM char * kMinutesStr = D_STR_MINUTES
 "Minutes" More...
 
const PROGMEM char * kSecondStr = D_STR_SECOND
 "Second" More...
 
const PROGMEM char * kSecondsStr = D_STR_SECONDS
 "Seconds" More...
 
const PROGMEM char * kNowStr = D_STR_NOW
 "Now" More...
 
const PROGMEM char * kThreeLetterDayOfWeekStr = D_STR_THREELETTERDAYS
 "SunMonTueWedThuFriSat" More...
 
const PROGMEM char * kYesStr = D_STR_YES
 "Yes" More...
 
const PROGMEM char * kNoStr = D_STR_NO
 "No" More...
 
const PROGMEM char * kTrueStr = D_STR_TRUE
 "True" More...
 
const PROGMEM char * kFalseStr = D_STR_FALSE
 "False" More...
 
const PROGMEM char * kRepeatStr = D_STR_REPEAT
 "Repeat" More...
 
const PROGMEM char * kCodeStr = D_STR_CODE
 "Code" More...
 
const PROGMEM char * kBitsStr = D_STR_BITS
 "Bits" More...
 
const PROGMEM char * kAllProtocolNamesStr
 New protocol strings should be added just above this line. More...
 
+

Detailed Description

+
Warning
If you add or remove an entry in this file, you should run: '../tools/generate_irtext_h.sh' to rebuild the IRtext.h file.
+

Variable Documentation

+ +

◆ k3DStr

+ +
+
+ + + + +
const PROGMEM char* k3DStr = D_STR_3D
+
+ +

"3D"

+ +
+
+ +

◆ k6thSenseStr

+ +
+
+ + + + +
const PROGMEM char* k6thSenseStr = D_STR_6THSENSE
+
+ +

"6th Sense"

+ +
+
+ +

◆ k8CHeatStr

+ +
+
+ + + + +
const PROGMEM char* k8CHeatStr = D_STR_8C_HEAT
+
+ +

"8CHeat"

+ +
+
+ +

◆ kAirFlowStr

+ +
+
+ + + + +
const PROGMEM char* kAirFlowStr = D_STR_AIRFLOW
+
+ +

"Air Flow"

+ +
+
+ +

◆ kAllProtocolNamesStr

+ +
+
+ + + + +
const PROGMEM char* kAllProtocolNamesStr
+
+ +

New protocol strings should be added just above this line.

+

This string requires double null termination.

+ +
+
+ +

◆ kAutomaticStr

+ +
+
+ + + + +
const PROGMEM char* kAutomaticStr = D_STR_AUTOMATIC
+
+ +

"Automatic"

+ +
+
+ +

◆ kAutoStr

+ +
+
+ + + + +
const PROGMEM char* kAutoStr = D_STR_AUTO
+
+ +

"Auto"

+ +
+
+ +

◆ kBeepStr

+ +
+
+ + + + +
const PROGMEM char* kBeepStr = D_STR_BEEP
+
+ +

"Beep"

+ +
+
+ +

◆ kBitsStr

+ +
+
+ + + + +
const PROGMEM char* kBitsStr = D_STR_BITS
+
+ +

"Bits"

+ +
+
+ +

◆ kBottomStr

+ +
+
+ + + + +
const PROGMEM char* kBottomStr = D_STR_BOTTOM
+
+ +

"Bottom"

+ +
+
+ +

◆ kBreezeStr

+ +
+
+ + + + +
const PROGMEM char* kBreezeStr = D_STR_BREEZE
+
+ +

"Breeze"

+ +
+
+ +

◆ kButtonStr

+ +
+
+ + + + +
const PROGMEM char* kButtonStr = D_STR_BUTTON
+
+ +

"Button"

+ +
+
+ +

◆ kCancelStr

+ +
+
+ + + + +
const PROGMEM char* kCancelStr = D_STR_CANCEL
+
+ +

"Cancel"

+ +
+
+ +

◆ kCeilingStr

+ +
+
+ + + + +
const PROGMEM char* kCeilingStr = D_STR_CEILING
+
+ +

"Ceiling"

+ +
+
+ +

◆ kCelsiusStr

+ +
+
+ + + + +
const PROGMEM char* kCelsiusStr = D_STR_CELSIUS
+
+ +

"Celsius"

+ +
+
+ +

◆ kCentreStr

+ +
+
+ + + + +
const PROGMEM char* kCentreStr = D_STR_CENTRE
+
+ +

"Centre"

+ +
+
+ +

◆ kChangeStr

+ +
+
+ + + + +
const PROGMEM char* kChangeStr = D_STR_CHANGE
+
+ +

"Change"

+ +
+
+ +

◆ kCirculateStr

+ +
+
+ + + + +
const PROGMEM char* kCirculateStr = D_STR_CIRCULATE
+
+ +

"Circulate"

+ +
+
+ +

◆ kCleanStr

+ +
+
+ + + + +
const PROGMEM char* kCleanStr = D_STR_CLEAN
+
+ +

"Clean"

+ +
+
+ +

◆ kClockStr

+ +
+
+ + + + +
const PROGMEM char* kClockStr = D_STR_CLOCK
+
+ +

"Clock"

+ +
+
+ +

◆ kCodeStr

+ +
+
+ + + + +
const PROGMEM char* kCodeStr = D_STR_CODE
+
+ +

"Code"

+ +
+
+ +

◆ kColonSpaceStr

+ +
+
+ + + + +
const PROGMEM char* kColonSpaceStr = D_STR_COLONSPACE
+
+ +

": "

+ +
+
+ +

◆ kComfortStr

+ +
+
+ + + + +
const PROGMEM char* kComfortStr = D_STR_COMFORT
+
+ +

"Comfort"

+ +
+
+ +

◆ kCommandStr

+ +
+
+ + + + +
const PROGMEM char* kCommandStr = D_STR_COMMAND
+
+ +

"Command"

+ +
+
+ +

◆ kCommaSpaceStr

+ +
+
+ + + + +
const PROGMEM char* kCommaSpaceStr = D_STR_COMMASPACE
+
+ +

", "

+ +
+
+ +

◆ kCoolStr

+ +
+
+ + + + +
const PROGMEM char* kCoolStr = D_STR_COOL
+
+ +

"Cool"

+ +
+
+ +

◆ kDaysStr

+ +
+
+ + + + +
const PROGMEM char* kDaysStr = D_STR_DAYS
+
+ +

"Days"

+ +
+
+ +

◆ kDayStr

+ +
+
+ + + + +
const PROGMEM char* kDayStr = D_STR_DAY
+
+ +

"Day"

+ +
+
+ +

◆ kDisplayTempStr

+ +
+
+ + + + +
const PROGMEM char* kDisplayTempStr = D_STR_DISPLAYTEMP
+
+ +

"Display Temp"

+ +
+
+ +

◆ kDownStr

+ +
+
+ + + + +
const PROGMEM char* kDownStr = D_STR_DOWN
+
+ +

"Down"

+ +
+
+ +

◆ kDryStr

+ +
+
+ + + + +
const PROGMEM char* kDryStr = D_STR_DRY
+
+ +

"Dry"

+ +
+
+ +

◆ kEconoStr

+ +
+
+ + + + +
const PROGMEM char* kEconoStr = D_STR_ECONO
+
+ +

"Econo"

+ +
+
+ +

◆ kEyeAutoStr

+ +
+
+ + + + +
const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO
+
+ +

"Eye Auto"

+ +
+
+ +

◆ kEyeStr

+ +
+
+ + + + +
const PROGMEM char* kEyeStr = D_STR_EYE
+
+ +

"Eye"

+ +
+
+ +

◆ kFalseStr

+ +
+
+ + + + +
const PROGMEM char* kFalseStr = D_STR_FALSE
+
+ +

"False"

+ +
+
+ +

◆ kFanOnlyStr

+ +
+
+ + + + +
const PROGMEM char* kFanOnlyStr = D_STR_FANONLY
+
+ +

"fan_only"

+ +
+
+ +

◆ kFanStr

+ +
+
+ + + + +
const PROGMEM char* kFanStr = D_STR_FAN
+
+ +

"Fan"

+ +
+
+ +

◆ kFastStr

+ +
+
+ + + + +
const PROGMEM char* kFastStr = D_STR_FAST
+
+ +

"Fast"

+ +
+
+ +

◆ kFilterStr

+ +
+
+ + + + +
const PROGMEM char* kFilterStr = D_STR_FILTER
+
+ +

"Filter"

+ +
+
+ +

◆ kFixedStr

+ +
+
+ + + + +
const PROGMEM char* kFixedStr = D_STR_FIXED
+
+ +

"Fixed"

+ +
+
+ +

◆ kFollowStr

+ +
+
+ + + + +
const PROGMEM char* kFollowStr = D_STR_FOLLOW
+
+ +

"Follow"

+ +
+
+ +

◆ kFreshStr

+ +
+
+ + + + +
const PROGMEM char* kFreshStr = D_STR_FRESH
+
+ +

"Fresh"

+ +
+
+ +

◆ kHealthStr

+ +
+
+ + + + +
const PROGMEM char* kHealthStr = D_STR_HEALTH
+
+ +

"Health"

+ +
+
+ +

◆ kHeatStr

+ +
+
+ + + + +
const PROGMEM char* kHeatStr = D_STR_HEAT
+
+ +

"Heat"

+ +
+
+ +

◆ kHighestStr

+ +
+
+ + + + +
const PROGMEM char* kHighestStr = D_STR_HIGHEST
+
+ +

"Highest"

+ +
+
+ +

◆ kHighStr

+ +
+
+ + + + +
const PROGMEM char* kHighStr = D_STR_HIGH
+
+ +

"High"

+ +
+
+ +

◆ kHiStr

+ +
+
+ + + + +
const PROGMEM char* kHiStr = D_STR_HI
+
+ +

"Hi"

+ +
+
+ +

◆ kHoldStr

+ +
+
+ + + + +
const PROGMEM char* kHoldStr = D_STR_HOLD
+
+ +

"Hold"

+ +
+
+ +

◆ kHoursStr

+ +
+
+ + + + +
const PROGMEM char* kHoursStr = D_STR_HOURS
+
+ +

"Hours"

+ +
+
+ +

◆ kHourStr

+ +
+
+ + + + +
const PROGMEM char* kHourStr = D_STR_HOUR
+
+ +

"Hour"

+ +
+
+ +

◆ kHumidStr

+ +
+
+ + + + +
const PROGMEM char* kHumidStr = D_STR_HUMID
+
+ +

"Humid"

+ +
+
+ +

◆ kIFeelStr

+ +
+
+ + + + +
const PROGMEM char* kIFeelStr = D_STR_IFEEL
+
+ +

"IFeel"

+ +
+
+ +

◆ kInsideStr

+ +
+
+ + + + +
const PROGMEM char* kInsideStr = D_STR_INSIDE
+
+ +

"Inside"

+ +
+
+ +

◆ kIonStr

+ +
+
+ + + + +
const PROGMEM char* kIonStr = D_STR_ION
+
+ +

"Ion"

+ +
+
+ +

◆ kLastStr

+ +
+
+ + + + +
const PROGMEM char* kLastStr = D_STR_LAST
+
+ +

"Last"

+ +
+
+ +

◆ kLeftMaxStr

+ +
+
+ + + + +
const PROGMEM char* kLeftMaxStr = D_STR_LEFTMAX_NOSPACE
+
+ +

"LeftMax"

+ +
+
+ +

◆ kLeftStr

+ +
+
+ + + + +
const PROGMEM char* kLeftStr = D_STR_LEFT
+
+ +

"Left"

+ +
+
+ +

◆ kLightStr

+ +
+
+ + + + +
const PROGMEM char* kLightStr = D_STR_LIGHT
+
+ +

"Light"

+ +
+
+ +

◆ kLightToggleStr

+ +
+
+ + + + +
const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE
+
+ +

"Light Toggle"

+ +
+
+ +

◆ kLoStr

+ +
+
+ + + + +
const PROGMEM char* kLoStr = D_STR_LO
+
+ +

"Lo"

+ +
+
+ +

◆ kLoudStr

+ +
+
+ + + + +
const PROGMEM char* kLoudStr = D_STR_LOUD
+
+ +

"Loud"

+ +
+
+ +

◆ kLowerStr

+ +
+
+ + + + +
const PROGMEM char* kLowerStr = D_STR_LOWER
+
+ +

"Lower"

+ +
+
+ +

◆ kLowestStr

+ +
+
+ + + + +
const PROGMEM char* kLowestStr = D_STR_LOWEST
+
+ +

"Lowest"

+ +
+
+ +

◆ kLowStr

+ +
+
+ + + + +
const PROGMEM char* kLowStr = D_STR_LOW
+
+ +

"Low"

+ +
+
+ +

◆ kManualStr

+ +
+
+ + + + +
const PROGMEM char* kManualStr = D_STR_MANUAL
+
+ +

"Manual"

+ +
+
+ +

◆ kMaximumStr

+ +
+
+ + + + +
const PROGMEM char* kMaximumStr = D_STR_MAXIMUM
+
+ +

"Maximum"

+ +
+
+ +

◆ kMaxLeftStr

+ +
+
+ + + + +
const PROGMEM char* kMaxLeftStr = D_STR_MAXLEFT
+
+ +

"Max Left"

+ +
+
+ +

◆ kMaxRightStr

+ +
+
+ + + + +
const PROGMEM char* kMaxRightStr = D_STR_MAXRIGHT
+
+ +

"Max Right"

+ +
+
+ +

◆ kMaxStr

+ +
+
+ + + + +
const PROGMEM char* kMaxStr = D_STR_MAX
+
+ +

"Max"

+ +
+
+ +

◆ kMediumStr

+ +
+
+ + + + +
const PROGMEM char* kMediumStr = D_STR_MEDIUM
+
+ +

"Medium"

+ +
+
+ +

◆ kMedStr

+ +
+
+ + + + +
const PROGMEM char* kMedStr = D_STR_MED
+
+ +

"Med"

+ +
+
+ +

◆ kMiddleStr

+ +
+
+ + + + +
const PROGMEM char* kMiddleStr = D_STR_MIDDLE
+
+ +

"Middle"

+ +
+
+ +

◆ kMidStr

+ +
+
+ + + + +
const PROGMEM char* kMidStr = D_STR_MID
+
+ +

"Mid"

+ +
+
+ +

◆ kMinimumStr

+ +
+
+ + + + +
const PROGMEM char* kMinimumStr = D_STR_MINIMUM
+
+ +

"Minimum"

+ +
+
+ +

◆ kMinStr

+ +
+
+ + + + +
const PROGMEM char* kMinStr = D_STR_MIN
+
+ +

"Min"

+ +
+
+ +

◆ kMinutesStr

+ +
+
+ + + + +
const PROGMEM char* kMinutesStr = D_STR_MINUTES
+
+ +

"Minutes"

+ +
+
+ +

◆ kMinuteStr

+ +
+
+ + + + +
const PROGMEM char* kMinuteStr = D_STR_MINUTE
+
+ +

"Minute"

+ +
+
+ +

◆ kModelStr

+ +
+
+ + + + +
const PROGMEM char* kModelStr = D_STR_MODEL
+
+ +

"Model"

+ +
+
+ +

◆ kModeStr

+ +
+
+ + + + +
const PROGMEM char* kModeStr = D_STR_MODE
+
+ +

"Mode"

+ +
+
+ +

◆ kMouldStr

+ +
+
+ + + + +
const PROGMEM char* kMouldStr = D_STR_MOULD
+
+ +

"Mould"

+ +
+
+ +

◆ kMoveStr

+ +
+
+ + + + +
const PROGMEM char* kMoveStr = D_STR_MOVE
+
+ +

"Move"

+ +
+
+ +

◆ kNAStr

+ +
+
+ + + + +
const PROGMEM char* kNAStr = D_STR_NA
+
+ +

"N/A"

+ +
+
+ +

◆ kNightStr

+ +
+
+ + + + +
const PROGMEM char* kNightStr = D_STR_NIGHT
+
+ +

"Night"

+ +
+
+ +

◆ kNoStr

+ +
+
+ + + + +
const PROGMEM char* kNoStr = D_STR_NO
+
+ +

"No"

+ +
+
+ +

◆ kNowStr

+ +
+
+ + + + +
const PROGMEM char* kNowStr = D_STR_NOW
+
+ +

"Now"

+ +
+
+ +

◆ kOffStr

+ +
+
+ + + + +
const PROGMEM char* kOffStr = D_STR_OFF
+
+ +

"Off"

+ +
+
+ +

◆ kOffTimerStr

+ +
+
+ + + + +
const PROGMEM char* kOffTimerStr = D_STR_OFFTIMER
+
+ +

"OffTimer"

+ +
+
+ +

◆ kOnStr

+ +
+
+ + + + +
const PROGMEM char* kOnStr = D_STR_ON
+
+ +

"On"

+ +
+
+ +

◆ kOnTimerStr

+ +
+
+ + + + +
const PROGMEM char* kOnTimerStr = D_STR_ONTIMER
+
+ +

"OnTimer"

+ +
+
+ +

◆ kOutsideQuietStr

+ +
+
+ + + + +
const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET
+
+ +

"Outside Quiet"

+ +
+
+ +

◆ kOutsideStr

+ +
+
+ + + + +
const PROGMEM char* kOutsideStr = D_STR_OUTSIDE
+
+ +

"Outside"

+ +
+
+ +

◆ kPowerButtonStr

+ +
+
+ + + + +
const PROGMEM char* kPowerButtonStr = D_STR_POWERBUTTON
+
+ +

"Power Button"

+ +
+
+ +

◆ kPowerfulStr

+ +
+
+ + + + +
const PROGMEM char* kPowerfulStr = D_STR_POWERFUL
+
+ +

"Powerful"

+ +
+
+ +

◆ kPowerStr

+ +
+
+ + + + +
const PROGMEM char* kPowerStr = D_STR_POWER
+
+ +

"Power"

+ +
+
+ +

◆ kPowerToggleStr

+ +
+
+ + + + +
const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE
+
+ +

"Power Toggle"

+ +
+
+ +

◆ kPreviousPowerStr

+ +
+
+ + + + +
const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER
+
+ +

"Previous Power"

+ +
+
+ +

◆ kProtocolStr

+ +
+
+ + + + +
const PROGMEM char* kProtocolStr = D_STR_PROTOCOL
+
+ +

"Protocol"

+ +
+
+ +

◆ kPurifyStr

+ +
+
+ + + + +
const PROGMEM char* kPurifyStr = D_STR_PURIFY
+
+ +

"Purify"

+ +
+
+ +

◆ kQuietStr

+ +
+
+ + + + +
const PROGMEM char* kQuietStr = D_STR_QUIET
+
+ +

"Quiet"

+ +
+
+ +

◆ kRepeatStr

+ +
+
+ + + + +
const PROGMEM char* kRepeatStr = D_STR_REPEAT
+
+ +

"Repeat"

+ +
+
+ +

◆ kRightMaxStr

+ +
+
+ + + + +
const PROGMEM char* kRightMaxStr = D_STR_RIGHTMAX_NOSPACE
+
+ +

"RightMax"

+ +
+
+ +

◆ kRightStr

+ +
+
+ + + + +
const PROGMEM char* kRightStr = D_STR_RIGHT
+
+ +

"Right"

+ +
+
+ +

◆ kRoomStr

+ +
+
+ + + + +
const PROGMEM char* kRoomStr = D_STR_ROOM
+
+ +

"Room"

+ +
+
+ +

◆ kSaveStr

+ +
+
+ + + + +
const PROGMEM char* kSaveStr = D_STR_SAVE
+
+ +

"Save"

+ +
+
+ +

◆ kSecondsStr

+ +
+
+ + + + +
const PROGMEM char* kSecondsStr = D_STR_SECONDS
+
+ +

"Seconds"

+ +
+
+ +

◆ kSecondStr

+ +
+
+ + + + +
const PROGMEM char* kSecondStr = D_STR_SECOND
+
+ +

"Second"

+ +
+
+ +

◆ kSensorStr

+ +
+
+ + + + +
const PROGMEM char* kSensorStr = D_STR_SENSOR
+
+ +

"Sensor"

+ +
+
+ +

◆ kSensorTempStr

+ +
+
+ + + + +
const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP
+
+ +

"Sensor Temp"

+ +
+
+ +

◆ kSetStr

+ +
+
+ + + + +
const PROGMEM char* kSetStr = D_STR_SET
+
+ +

"Set"

+ +
+
+ +

◆ kSilentStr

+ +
+
+ + + + +
const PROGMEM char* kSilentStr = D_STR_SILENT
+
+ +

"Silent"

+ +
+
+ +

◆ kSleepStr

+ +
+
+ + + + +
const PROGMEM char* kSleepStr = D_STR_SLEEP
+
+ +

"Sleep"

+ +
+
+ +

◆ kSleepTimerStr

+ +
+
+ + + + +
const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER
+
+ +

"Sleep Timer"

+ +
+
+ +

◆ kSlowStr

+ +
+
+ + + + +
const PROGMEM char* kSlowStr = D_STR_SLOW
+
+ +

"Slow"

+ +
+
+ +

◆ kSpaceLBraceStr

+ +
+
+ + + + +
const PROGMEM char* kSpaceLBraceStr = D_STR_SPACELBRACE
+
+ +

" ("

+ +
+
+ +

◆ kStartStr

+ +
+
+ + + + +
const PROGMEM char* kStartStr = D_STR_START
+
+ +

"Start"

+ +
+
+ +

◆ kStepStr

+ +
+
+ + + + +
const PROGMEM char* kStepStr = D_STR_STEP
+
+ +

"Step"

+ +
+
+ +

◆ kStopStr

+ +
+
+ + + + +
const PROGMEM char* kStopStr = D_STR_STOP
+
+ +

"Stop"

+ +
+
+ +

◆ kSuperStr

+ +
+
+ + + + +
const PROGMEM char* kSuperStr = D_STR_SUPER
+
+ +

"Super"

+ +
+
+ +

◆ kSwingHStr

+ +
+
+ + + + +
const PROGMEM char* kSwingHStr = D_STR_SWINGH
+
+ +

"SwingH"

+ +
+
+ +

◆ kSwingStr

+ +
+
+ + + + +
const PROGMEM char* kSwingStr = D_STR_SWING
+
+ +

"Swing"

+ +
+
+ +

◆ kSwingVModeStr

+ +
+
+ + + + +
const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE
+
+ +

"Swing(V) Mode"

+ +
+
+ +

◆ kSwingVStr

+ +
+
+ + + + +
const PROGMEM char* kSwingVStr = D_STR_SWINGV
+
+ +

"SwingV"

+ +
+
+ +

◆ kSwingVToggleStr

+ +
+
+ + + + +
const PROGMEM char* kSwingVToggleStr = D_STR_SWINGVTOGGLE
+
+ +

"Swing(V) Toggle"

+ +
+
+ +

◆ kTempDownStr

+ +
+
+ + + + +
const PROGMEM char* kTempDownStr = D_STR_TEMPDOWN
+
+ +

"Temp Down"

+ +
+
+ +

◆ kTempStr

+ +
+
+ + + + +
const PROGMEM char* kTempStr = D_STR_TEMP
+
+ +

"Temp"

+ +
+
+ +

◆ kTempUpStr

+ +
+
+ + + + +
const PROGMEM char* kTempUpStr = D_STR_TEMPUP
+
+ +

"Temp Up"

+ +
+
+ +

◆ kThreeLetterDayOfWeekStr

+ +
+
+ + + + +
const PROGMEM char* kThreeLetterDayOfWeekStr = D_STR_THREELETTERDAYS
+
+ +

"SunMonTueWedThuFriSat"

+ +
+
+ +

◆ kTimerStr

+ +
+
+ + + + +
const PROGMEM char* kTimerStr = D_STR_TIMER
+
+ +

"Timer"

+ +
+
+ +

◆ kTimeSep

+ +
+
+ + + + +
char kTimeSep = D_CHR_TIME_SEP
+
+ +

':'

+ +
+
+ +

◆ kToggleStr

+ +
+
+ + + + +
const PROGMEM char* kToggleStr = D_STR_TOGGLE
+
+ +

"Toggle"

+ +
+
+ +

◆ kTopStr

+ +
+
+ + + + +
const PROGMEM char* kTopStr = D_STR_TOP
+
+ +

"Top"

+ +
+
+ +

◆ kTrueStr

+ +
+
+ + + + +
const PROGMEM char* kTrueStr = D_STR_TRUE
+
+ +

"True"

+ +
+
+ +

◆ kTurboStr

+ +
+
+ + + + +
const PROGMEM char* kTurboStr = D_STR_TURBO
+
+ +

"Turbo"

+ +
+
+ +

◆ kUnknownStr

+ +
+
+ + + + +
const PROGMEM char* kUnknownStr = D_STR_UNKNOWN
+
+ +

"Unknown"

+ +
+
+ +

◆ kUpperStr

+ +
+
+ + + + +
const PROGMEM char* kUpperStr = D_STR_UPPER
+
+ +

"Upper"

+ +
+
+ +

◆ kUpStr

+ +
+
+ + + + +
const PROGMEM char* kUpStr = D_STR_UP
+
+ +

"Up"

+ +
+
+ +

◆ kWallStr

+ +
+
+ + + + +
const PROGMEM char* kWallStr = D_STR_WALL
+
+ +

"Wall"

+ +
+
+ +

◆ kWeeklyTimerStr

+ +
+
+ + + + +
const PROGMEM char* kWeeklyTimerStr = D_STR_WEEKLYTIMER
+
+ +

"WeeklyTimer"

+ +
+
+ +

◆ kWideStr

+ +
+
+ + + + +
const PROGMEM char* kWideStr = D_STR_WIDE
+
+ +

"Wide"

+ +
+
+ +

◆ kWifiStr

+ +
+
+ + + + +
const PROGMEM char* kWifiStr = D_STR_WIFI
+
+ +

"Wifi"

+ +
+
+ +

◆ kXFanStr

+ +
+
+ + + + +
const PROGMEM char* kXFanStr = D_STR_XFAN
+
+ +

"XFan"

+ +
+
+ +

◆ kYesStr

+ +
+
+ + + + +
const PROGMEM char* kYesStr = D_STR_YES
+
+ +

"Yes"

+ +
+
+ +

◆ kZoneFollowStr

+ +
+
+ + + + +
const PROGMEM char* kZoneFollowStr = D_STR_ZONEFOLLOW
+
+ +

"Zone Follow"

+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h.html new file mode 100644 index 000000000..e3c285532 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h.html @@ -0,0 +1,2807 @@ + + + + + + + +IRremoteESP8266: src/IRtext.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRtext.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

char kTimeSep
 ':' More...
 
const char * k3DStr
 "3D" More...
 
const char * k6thSenseStr
 "6th Sense" More...
 
const char * k8CHeatStr
 "8CHeat" More...
 
const char * kAirFlowStr
 "Air Flow" More...
 
const char * kAllProtocolNamesStr
 New protocol strings should be added just above this line. More...
 
const char * kAutomaticStr
 "Automatic" More...
 
const char * kAutoStr
 "Auto" More...
 
const char * kBeepStr
 "Beep" More...
 
const char * kBitsStr
 "Bits" More...
 
const char * kBottomStr
 "Bottom" More...
 
const char * kBreezeStr
 "Breeze" More...
 
const char * kButtonStr
 "Button" More...
 
const char * kCancelStr
 "Cancel" More...
 
const char * kCeilingStr
 "Ceiling" More...
 
const char * kCelsiusStr
 "Celsius" More...
 
const char * kCentreStr
 "Centre" More...
 
const char * kChangeStr
 "Change" More...
 
const char * kCirculateStr
 "Circulate" More...
 
const char * kCleanStr
 "Clean" More...
 
const char * kClockStr
 "Clock" More...
 
const char * kCodeStr
 "Code" More...
 
const char * kColonSpaceStr
 ": " More...
 
const char * kComfortStr
 "Comfort" More...
 
const char * kCommandStr
 "Command" More...
 
const char * kCommaSpaceStr
 ", " More...
 
const char * kCoolStr
 "Cool" More...
 
const char * kDaysStr
 "Days" More...
 
const char * kDayStr
 "Day" More...
 
const char * kDisplayTempStr
 "Display Temp" More...
 
const char * kDownStr
 "Down" More...
 
const char * kDryStr
 "Dry" More...
 
const char * kEconoStr
 "Econo" More...
 
const char * kEyeAutoStr
 "Eye Auto" More...
 
const char * kEyeStr
 "Eye" More...
 
const char * kFalseStr
 "False" More...
 
const char * kFanOnlyStr
 "fan_only" More...
 
const char * kFanStr
 "Fan" More...
 
const char * kFastStr
 "Fast" More...
 
const char * kFilterStr
 "Filter" More...
 
const char * kFixedStr
 "Fixed" More...
 
const char * kFollowStr
 "Follow" More...
 
const char * kFreshStr
 "Fresh" More...
 
const char * kHealthStr
 "Health" More...
 
const char * kHeatStr
 "Heat" More...
 
const char * kHighestStr
 "Highest" More...
 
const char * kHighStr
 "High" More...
 
const char * kHiStr
 "Hi" More...
 
const char * kHoldStr
 "Hold" More...
 
const char * kHoursStr
 "Hours" More...
 
const char * kHourStr
 "Hour" More...
 
const char * kHumidStr
 "Humid" More...
 
const char * kIFeelStr
 "IFeel" More...
 
const char * kInsideStr
 "Inside" More...
 
const char * kIonStr
 "Ion" More...
 
const char * kLastStr
 "Last" More...
 
const char * kLeftMaxStr
 "LeftMax" More...
 
const char * kLeftStr
 "Left" More...
 
const char * kLightStr
 "Light" More...
 
const char * kLightToggleStr
 "Light Toggle" More...
 
const char * kLoStr
 "Lo" More...
 
const char * kLoudStr
 "Loud" More...
 
const char * kLowerStr
 "Lower" More...
 
const char * kLowestStr
 "Lowest" More...
 
const char * kLowStr
 "Low" More...
 
const char * kManualStr
 "Manual" More...
 
const char * kMaximumStr
 "Maximum" More...
 
const char * kMaxLeftStr
 "Max Left" More...
 
const char * kMaxRightStr
 "Max Right" More...
 
const char * kMaxStr
 "Max" More...
 
const char * kMediumStr
 "Medium" More...
 
const char * kMedStr
 "Med" More...
 
const char * kMiddleStr
 "Middle" More...
 
const char * kMidStr
 "Mid" More...
 
const char * kMinimumStr
 "Minimum" More...
 
const char * kMinStr
 "Min" More...
 
const char * kMinutesStr
 "Minutes" More...
 
const char * kMinuteStr
 "Minute" More...
 
const char * kModelStr
 "Model" More...
 
const char * kModeStr
 "Mode" More...
 
const char * kMouldStr
 "Mould" More...
 
const char * kMoveStr
 "Move" More...
 
const char * kNAStr
 "N/A" More...
 
const char * kNightStr
 "Night" More...
 
const char * kNoStr
 "No" More...
 
const char * kNowStr
 "Now" More...
 
const char * kOffStr
 "Off" More...
 
const char * kOffTimerStr
 "OffTimer" More...
 
const char * kOnStr
 "On" More...
 
const char * kOnTimerStr
 "OnTimer" More...
 
const char * kOutsideQuietStr
 "Outside Quiet" More...
 
const char * kOutsideStr
 "Outside" More...
 
const char * kPowerfulStr
 "Powerful" More...
 
const char * kPowerStr
 "Power" More...
 
const char * kPowerToggleStr
 "Power Toggle" More...
 
const char * kPowerButtonStr
 "Power Button" More...
 
const char * kPreviousPowerStr
 "Previous Power" More...
 
const char * kProtocolStr
 "Protocol" More...
 
const char * kPurifyStr
 "Purify" More...
 
const char * kQuietStr
 "Quiet" More...
 
const char * kRepeatStr
 "Repeat" More...
 
const char * kRightMaxStr
 "RightMax" More...
 
const char * kRightStr
 "Right" More...
 
const char * kRoomStr
 "Room" More...
 
const char * kSaveStr
 "Save" More...
 
const char * kSecondsStr
 "Seconds" More...
 
const char * kSecondStr
 "Second" More...
 
const char * kSensorStr
 "Sensor" More...
 
const char * kSensorTempStr
 "Sensor Temp" More...
 
const char * kSetStr
 "Set" More...
 
const char * kSilentStr
 "Silent" More...
 
const char * kSleepStr
 "Sleep" More...
 
const char * kSleepTimerStr
 "Sleep Timer" More...
 
const char * kSlowStr
 "Slow" More...
 
const char * kSpaceLBraceStr
 " (" More...
 
const char * kStartStr
 "Start" More...
 
const char * kStepStr
 "Step" More...
 
const char * kStopStr
 "Stop" More...
 
const char * kSuperStr
 "Super" More...
 
const char * kSwingHStr
 "SwingH" More...
 
const char * kSwingStr
 "Swing" More...
 
const char * kSwingVModeStr
 "Swing(V) Mode" More...
 
const char * kSwingVStr
 "SwingV" More...
 
const char * kSwingVToggleStr
 "Swing(V) Toggle" More...
 
const char * kTempDownStr
 "Temp Down" More...
 
const char * kTempStr
 "Temp" More...
 
const char * kTempUpStr
 "Temp Up" More...
 
const char * kThreeLetterDayOfWeekStr
 "SunMonTueWedThuFriSat" More...
 
const char * kTimerStr
 "Timer" More...
 
const char * kToggleStr
 "Toggle" More...
 
const char * kTopStr
 "Top" More...
 
const char * kTrueStr
 "True" More...
 
const char * kTurboStr
 "Turbo" More...
 
const char * kUnknownStr
 "Unknown" More...
 
const char * kUpperStr
 "Upper" More...
 
const char * kUpStr
 "Up" More...
 
const char * kWallStr
 "Wall" More...
 
const char * kWeeklyTimerStr
 "WeeklyTimer" More...
 
const char * kWideStr
 "Wide" More...
 
const char * kWifiStr
 "Wifi" More...
 
const char * kXFanStr
 "XFan" More...
 
const char * kYesStr
 "Yes" More...
 
const char * kZoneFollowStr
 "Zone Follow" More...
 
+

Variable Documentation

+ +

◆ k3DStr

+ +
+
+ + + + +
const char* k3DStr
+
+ +

"3D"

+ +
+
+ +

◆ k6thSenseStr

+ +
+
+ + + + +
const char* k6thSenseStr
+
+ +

"6th Sense"

+ +
+
+ +

◆ k8CHeatStr

+ +
+
+ + + + +
const char* k8CHeatStr
+
+ +

"8CHeat"

+ +
+
+ +

◆ kAirFlowStr

+ +
+
+ + + + +
const char* kAirFlowStr
+
+ +

"Air Flow"

+ +
+
+ +

◆ kAllProtocolNamesStr

+ +
+
+ + + + +
const char* kAllProtocolNamesStr
+
+ +

New protocol strings should be added just above this line.

+

This string requires double null termination.

+ +
+
+ +

◆ kAutomaticStr

+ +
+
+ + + + +
const char* kAutomaticStr
+
+ +

"Automatic"

+ +
+
+ +

◆ kAutoStr

+ +
+
+ + + + +
const char* kAutoStr
+
+ +

"Auto"

+ +
+
+ +

◆ kBeepStr

+ +
+
+ + + + +
const char* kBeepStr
+
+ +

"Beep"

+ +
+
+ +

◆ kBitsStr

+ +
+
+ + + + +
const char* kBitsStr
+
+ +

"Bits"

+ +
+
+ +

◆ kBottomStr

+ +
+
+ + + + +
const char* kBottomStr
+
+ +

"Bottom"

+ +
+
+ +

◆ kBreezeStr

+ +
+
+ + + + +
const char* kBreezeStr
+
+ +

"Breeze"

+ +
+
+ +

◆ kButtonStr

+ +
+
+ + + + +
const char* kButtonStr
+
+ +

"Button"

+ +
+
+ +

◆ kCancelStr

+ +
+
+ + + + +
const char* kCancelStr
+
+ +

"Cancel"

+ +
+
+ +

◆ kCeilingStr

+ +
+
+ + + + +
const char* kCeilingStr
+
+ +

"Ceiling"

+ +
+
+ +

◆ kCelsiusStr

+ +
+
+ + + + +
const char* kCelsiusStr
+
+ +

"Celsius"

+ +
+
+ +

◆ kCentreStr

+ +
+
+ + + + +
const char* kCentreStr
+
+ +

"Centre"

+ +
+
+ +

◆ kChangeStr

+ +
+
+ + + + +
const char* kChangeStr
+
+ +

"Change"

+ +
+
+ +

◆ kCirculateStr

+ +
+
+ + + + +
const char* kCirculateStr
+
+ +

"Circulate"

+ +
+
+ +

◆ kCleanStr

+ +
+
+ + + + +
const char* kCleanStr
+
+ +

"Clean"

+ +
+
+ +

◆ kClockStr

+ +
+
+ + + + +
const char* kClockStr
+
+ +

"Clock"

+ +
+
+ +

◆ kCodeStr

+ +
+
+ + + + +
const char* kCodeStr
+
+ +

"Code"

+ +
+
+ +

◆ kColonSpaceStr

+ +
+
+ + + + +
const char* kColonSpaceStr
+
+ +

": "

+ +
+
+ +

◆ kComfortStr

+ +
+
+ + + + +
const char* kComfortStr
+
+ +

"Comfort"

+ +
+
+ +

◆ kCommandStr

+ +
+
+ + + + +
const char* kCommandStr
+
+ +

"Command"

+ +
+
+ +

◆ kCommaSpaceStr

+ +
+
+ + + + +
const char* kCommaSpaceStr
+
+ +

", "

+ +
+
+ +

◆ kCoolStr

+ +
+
+ + + + +
const char* kCoolStr
+
+ +

"Cool"

+ +
+
+ +

◆ kDaysStr

+ +
+
+ + + + +
const char* kDaysStr
+
+ +

"Days"

+ +
+
+ +

◆ kDayStr

+ +
+
+ + + + +
const char* kDayStr
+
+ +

"Day"

+ +
+
+ +

◆ kDisplayTempStr

+ +
+
+ + + + +
const char* kDisplayTempStr
+
+ +

"Display Temp"

+ +
+
+ +

◆ kDownStr

+ +
+
+ + + + +
const char* kDownStr
+
+ +

"Down"

+ +
+
+ +

◆ kDryStr

+ +
+
+ + + + +
const char* kDryStr
+
+ +

"Dry"

+ +
+
+ +

◆ kEconoStr

+ +
+
+ + + + +
const char* kEconoStr
+
+ +

"Econo"

+ +
+
+ +

◆ kEyeAutoStr

+ +
+
+ + + + +
const char* kEyeAutoStr
+
+ +

"Eye Auto"

+ +
+
+ +

◆ kEyeStr

+ +
+
+ + + + +
const char* kEyeStr
+
+ +

"Eye"

+ +
+
+ +

◆ kFalseStr

+ +
+
+ + + + +
const char* kFalseStr
+
+ +

"False"

+ +
+
+ +

◆ kFanOnlyStr

+ +
+
+ + + + +
const char* kFanOnlyStr
+
+ +

"fan_only"

+ +
+
+ +

◆ kFanStr

+ +
+
+ + + + +
const char* kFanStr
+
+ +

"Fan"

+ +
+
+ +

◆ kFastStr

+ +
+
+ + + + +
const char* kFastStr
+
+ +

"Fast"

+ +
+
+ +

◆ kFilterStr

+ +
+
+ + + + +
const char* kFilterStr
+
+ +

"Filter"

+ +
+
+ +

◆ kFixedStr

+ +
+
+ + + + +
const char* kFixedStr
+
+ +

"Fixed"

+ +
+
+ +

◆ kFollowStr

+ +
+
+ + + + +
const char* kFollowStr
+
+ +

"Follow"

+ +
+
+ +

◆ kFreshStr

+ +
+
+ + + + +
const char* kFreshStr
+
+ +

"Fresh"

+ +
+
+ +

◆ kHealthStr

+ +
+
+ + + + +
const char* kHealthStr
+
+ +

"Health"

+ +
+
+ +

◆ kHeatStr

+ +
+
+ + + + +
const char* kHeatStr
+
+ +

"Heat"

+ +
+
+ +

◆ kHighestStr

+ +
+
+ + + + +
const char* kHighestStr
+
+ +

"Highest"

+ +
+
+ +

◆ kHighStr

+ +
+
+ + + + +
const char* kHighStr
+
+ +

"High"

+ +
+
+ +

◆ kHiStr

+ +
+
+ + + + +
const char* kHiStr
+
+ +

"Hi"

+ +
+
+ +

◆ kHoldStr

+ +
+
+ + + + +
const char* kHoldStr
+
+ +

"Hold"

+ +
+
+ +

◆ kHoursStr

+ +
+
+ + + + +
const char* kHoursStr
+
+ +

"Hours"

+ +
+
+ +

◆ kHourStr

+ +
+
+ + + + +
const char* kHourStr
+
+ +

"Hour"

+ +
+
+ +

◆ kHumidStr

+ +
+
+ + + + +
const char* kHumidStr
+
+ +

"Humid"

+ +
+
+ +

◆ kIFeelStr

+ +
+
+ + + + +
const char* kIFeelStr
+
+ +

"IFeel"

+ +
+
+ +

◆ kInsideStr

+ +
+
+ + + + +
const char* kInsideStr
+
+ +

"Inside"

+ +
+
+ +

◆ kIonStr

+ +
+
+ + + + +
const char* kIonStr
+
+ +

"Ion"

+ +
+
+ +

◆ kLastStr

+ +
+
+ + + + +
const char* kLastStr
+
+ +

"Last"

+ +
+
+ +

◆ kLeftMaxStr

+ +
+
+ + + + +
const char* kLeftMaxStr
+
+ +

"LeftMax"

+ +
+
+ +

◆ kLeftStr

+ +
+
+ + + + +
const char* kLeftStr
+
+ +

"Left"

+ +
+
+ +

◆ kLightStr

+ +
+
+ + + + +
const char* kLightStr
+
+ +

"Light"

+ +
+
+ +

◆ kLightToggleStr

+ +
+
+ + + + +
const char* kLightToggleStr
+
+ +

"Light Toggle"

+ +
+
+ +

◆ kLoStr

+ +
+
+ + + + +
const char* kLoStr
+
+ +

"Lo"

+ +
+
+ +

◆ kLoudStr

+ +
+
+ + + + +
const char* kLoudStr
+
+ +

"Loud"

+ +
+
+ +

◆ kLowerStr

+ +
+
+ + + + +
const char* kLowerStr
+
+ +

"Lower"

+ +
+
+ +

◆ kLowestStr

+ +
+
+ + + + +
const char* kLowestStr
+
+ +

"Lowest"

+ +
+
+ +

◆ kLowStr

+ +
+
+ + + + +
const char* kLowStr
+
+ +

"Low"

+ +
+
+ +

◆ kManualStr

+ +
+
+ + + + +
const char* kManualStr
+
+ +

"Manual"

+ +
+
+ +

◆ kMaximumStr

+ +
+
+ + + + +
const char* kMaximumStr
+
+ +

"Maximum"

+ +
+
+ +

◆ kMaxLeftStr

+ +
+
+ + + + +
const char* kMaxLeftStr
+
+ +

"Max Left"

+ +
+
+ +

◆ kMaxRightStr

+ +
+
+ + + + +
const char* kMaxRightStr
+
+ +

"Max Right"

+ +
+
+ +

◆ kMaxStr

+ +
+
+ + + + +
const char* kMaxStr
+
+ +

"Max"

+ +
+
+ +

◆ kMediumStr

+ +
+
+ + + + +
const char* kMediumStr
+
+ +

"Medium"

+ +
+
+ +

◆ kMedStr

+ +
+
+ + + + +
const char* kMedStr
+
+ +

"Med"

+ +
+
+ +

◆ kMiddleStr

+ +
+
+ + + + +
const char* kMiddleStr
+
+ +

"Middle"

+ +
+
+ +

◆ kMidStr

+ +
+
+ + + + +
const char* kMidStr
+
+ +

"Mid"

+ +
+
+ +

◆ kMinimumStr

+ +
+
+ + + + +
const char* kMinimumStr
+
+ +

"Minimum"

+ +
+
+ +

◆ kMinStr

+ +
+
+ + + + +
const char* kMinStr
+
+ +

"Min"

+ +
+
+ +

◆ kMinutesStr

+ +
+
+ + + + +
const char* kMinutesStr
+
+ +

"Minutes"

+ +
+
+ +

◆ kMinuteStr

+ +
+
+ + + + +
const char* kMinuteStr
+
+ +

"Minute"

+ +
+
+ +

◆ kModelStr

+ +
+
+ + + + +
const char* kModelStr
+
+ +

"Model"

+ +
+
+ +

◆ kModeStr

+ +
+
+ + + + +
const char* kModeStr
+
+ +

"Mode"

+ +
+
+ +

◆ kMouldStr

+ +
+
+ + + + +
const char* kMouldStr
+
+ +

"Mould"

+ +
+
+ +

◆ kMoveStr

+ +
+
+ + + + +
const char* kMoveStr
+
+ +

"Move"

+ +
+
+ +

◆ kNAStr

+ +
+
+ + + + +
const char* kNAStr
+
+ +

"N/A"

+ +
+
+ +

◆ kNightStr

+ +
+
+ + + + +
const char* kNightStr
+
+ +

"Night"

+ +
+
+ +

◆ kNoStr

+ +
+
+ + + + +
const char* kNoStr
+
+ +

"No"

+ +
+
+ +

◆ kNowStr

+ +
+
+ + + + +
const char* kNowStr
+
+ +

"Now"

+ +
+
+ +

◆ kOffStr

+ +
+
+ + + + +
const char* kOffStr
+
+ +

"Off"

+ +
+
+ +

◆ kOffTimerStr

+ +
+
+ + + + +
const char* kOffTimerStr
+
+ +

"OffTimer"

+ +
+
+ +

◆ kOnStr

+ +
+
+ + + + +
const char* kOnStr
+
+ +

"On"

+ +
+
+ +

◆ kOnTimerStr

+ +
+
+ + + + +
const char* kOnTimerStr
+
+ +

"OnTimer"

+ +
+
+ +

◆ kOutsideQuietStr

+ +
+
+ + + + +
const char* kOutsideQuietStr
+
+ +

"Outside Quiet"

+ +
+
+ +

◆ kOutsideStr

+ +
+
+ + + + +
const char* kOutsideStr
+
+ +

"Outside"

+ +
+
+ +

◆ kPowerButtonStr

+ +
+
+ + + + +
const char* kPowerButtonStr
+
+ +

"Power Button"

+ +
+
+ +

◆ kPowerfulStr

+ +
+
+ + + + +
const char* kPowerfulStr
+
+ +

"Powerful"

+ +
+
+ +

◆ kPowerStr

+ +
+
+ + + + +
const char* kPowerStr
+
+ +

"Power"

+ +
+
+ +

◆ kPowerToggleStr

+ +
+
+ + + + +
const char* kPowerToggleStr
+
+ +

"Power Toggle"

+ +
+
+ +

◆ kPreviousPowerStr

+ +
+
+ + + + +
const char* kPreviousPowerStr
+
+ +

"Previous Power"

+ +
+
+ +

◆ kProtocolStr

+ +
+
+ + + + +
const char* kProtocolStr
+
+ +

"Protocol"

+ +
+
+ +

◆ kPurifyStr

+ +
+
+ + + + +
const char* kPurifyStr
+
+ +

"Purify"

+ +
+
+ +

◆ kQuietStr

+ +
+
+ + + + +
const char* kQuietStr
+
+ +

"Quiet"

+ +
+
+ +

◆ kRepeatStr

+ +
+
+ + + + +
const char* kRepeatStr
+
+ +

"Repeat"

+ +
+
+ +

◆ kRightMaxStr

+ +
+
+ + + + +
const char* kRightMaxStr
+
+ +

"RightMax"

+ +
+
+ +

◆ kRightStr

+ +
+
+ + + + +
const char* kRightStr
+
+ +

"Right"

+ +
+
+ +

◆ kRoomStr

+ +
+
+ + + + +
const char* kRoomStr
+
+ +

"Room"

+ +
+
+ +

◆ kSaveStr

+ +
+
+ + + + +
const char* kSaveStr
+
+ +

"Save"

+ +
+
+ +

◆ kSecondsStr

+ +
+
+ + + + +
const char* kSecondsStr
+
+ +

"Seconds"

+ +
+
+ +

◆ kSecondStr

+ +
+
+ + + + +
const char* kSecondStr
+
+ +

"Second"

+ +
+
+ +

◆ kSensorStr

+ +
+
+ + + + +
const char* kSensorStr
+
+ +

"Sensor"

+ +
+
+ +

◆ kSensorTempStr

+ +
+
+ + + + +
const char* kSensorTempStr
+
+ +

"Sensor Temp"

+ +
+
+ +

◆ kSetStr

+ +
+
+ + + + +
const char* kSetStr
+
+ +

"Set"

+ +
+
+ +

◆ kSilentStr

+ +
+
+ + + + +
const char* kSilentStr
+
+ +

"Silent"

+ +
+
+ +

◆ kSleepStr

+ +
+
+ + + + +
const char* kSleepStr
+
+ +

"Sleep"

+ +
+
+ +

◆ kSleepTimerStr

+ +
+
+ + + + +
const char* kSleepTimerStr
+
+ +

"Sleep Timer"

+ +
+
+ +

◆ kSlowStr

+ +
+
+ + + + +
const char* kSlowStr
+
+ +

"Slow"

+ +
+
+ +

◆ kSpaceLBraceStr

+ +
+
+ + + + +
const char* kSpaceLBraceStr
+
+ +

" ("

+ +
+
+ +

◆ kStartStr

+ +
+
+ + + + +
const char* kStartStr
+
+ +

"Start"

+ +
+
+ +

◆ kStepStr

+ +
+
+ + + + +
const char* kStepStr
+
+ +

"Step"

+ +
+
+ +

◆ kStopStr

+ +
+
+ + + + +
const char* kStopStr
+
+ +

"Stop"

+ +
+
+ +

◆ kSuperStr

+ +
+
+ + + + +
const char* kSuperStr
+
+ +

"Super"

+ +
+
+ +

◆ kSwingHStr

+ +
+
+ + + + +
const char* kSwingHStr
+
+ +

"SwingH"

+ +
+
+ +

◆ kSwingStr

+ +
+
+ + + + +
const char* kSwingStr
+
+ +

"Swing"

+ +
+
+ +

◆ kSwingVModeStr

+ +
+
+ + + + +
const char* kSwingVModeStr
+
+ +

"Swing(V) Mode"

+ +
+
+ +

◆ kSwingVStr

+ +
+
+ + + + +
const char* kSwingVStr
+
+ +

"SwingV"

+ +
+
+ +

◆ kSwingVToggleStr

+ +
+
+ + + + +
const char* kSwingVToggleStr
+
+ +

"Swing(V) Toggle"

+ +
+
+ +

◆ kTempDownStr

+ +
+
+ + + + +
const char* kTempDownStr
+
+ +

"Temp Down"

+ +
+
+ +

◆ kTempStr

+ +
+
+ + + + +
const char* kTempStr
+
+ +

"Temp"

+ +
+
+ +

◆ kTempUpStr

+ +
+
+ + + + +
const char* kTempUpStr
+
+ +

"Temp Up"

+ +
+
+ +

◆ kThreeLetterDayOfWeekStr

+ +
+
+ + + + +
const char* kThreeLetterDayOfWeekStr
+
+ +

"SunMonTueWedThuFriSat"

+ +
+
+ +

◆ kTimerStr

+ +
+
+ + + + +
const char* kTimerStr
+
+ +

"Timer"

+ +
+
+ +

◆ kTimeSep

+ +
+
+ + + + +
char kTimeSep
+
+ +

':'

+ +
+
+ +

◆ kToggleStr

+ +
+
+ + + + +
const char* kToggleStr
+
+ +

"Toggle"

+ +
+
+ +

◆ kTopStr

+ +
+
+ + + + +
const char* kTopStr
+
+ +

"Top"

+ +
+
+ +

◆ kTrueStr

+ +
+
+ + + + +
const char* kTrueStr
+
+ +

"True"

+ +
+
+ +

◆ kTurboStr

+ +
+
+ + + + +
const char* kTurboStr
+
+ +

"Turbo"

+ +
+
+ +

◆ kUnknownStr

+ +
+
+ + + + +
const char* kUnknownStr
+
+ +

"Unknown"

+ +
+
+ +

◆ kUpperStr

+ +
+
+ + + + +
const char* kUpperStr
+
+ +

"Upper"

+ +
+
+ +

◆ kUpStr

+ +
+
+ + + + +
const char* kUpStr
+
+ +

"Up"

+ +
+
+ +

◆ kWallStr

+ +
+
+ + + + +
const char* kWallStr
+
+ +

"Wall"

+ +
+
+ +

◆ kWeeklyTimerStr

+ +
+
+ + + + +
const char* kWeeklyTimerStr
+
+ +

"WeeklyTimer"

+ +
+
+ +

◆ kWideStr

+ +
+
+ + + + +
const char* kWideStr
+
+ +

"Wide"

+ +
+
+ +

◆ kWifiStr

+ +
+
+ + + + +
const char* kWifiStr
+
+ +

"Wifi"

+ +
+
+ +

◆ kXFanStr

+ +
+
+ + + + +
const char* kXFanStr
+
+ +

"XFan"

+ +
+
+ +

◆ kYesStr

+ +
+
+ + + + +
const char* kYesStr
+
+ +

"Yes"

+ +
+
+ +

◆ kZoneFollowStr

+ +
+
+ + + + +
const char* kZoneFollowStr
+
+ +

"Zone Follow"

+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h_source.html new file mode 100644 index 000000000..a4b704249 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h_source.html @@ -0,0 +1,383 @@ + + + + + + + +IRremoteESP8266: src/IRtext.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRtext.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // This header file is to be included in files **other than** 'IRtext.cpp'.
+
3 //
+
4 // WARNING: Do not edit this file! This file is automatically generated by
+
5 // 'tools/generate_irtext_h.sh'.
+
6 
+
7 #ifndef IRTEXT_H_
+
8 #define IRTEXT_H_
+
9 
+
10 #include "i18n.h"
+
11 
+
12 // Constant text to be shared across all object files.
+
13 // This means there is only one copy of the character/string/text etc.
+
14 
+
15 extern char kTimeSep;
+
16 extern const char* k3DStr;
+
17 extern const char* k6thSenseStr;
+
18 extern const char* k8CHeatStr;
+
19 extern const char* kAirFlowStr;
+
20 extern const char *kAllProtocolNamesStr;
+
21 extern const char* kAutomaticStr;
+
22 extern const char* kAutoStr;
+
23 extern const char* kBeepStr;
+
24 extern const char* kBitsStr;
+
25 extern const char* kBottomStr;
+
26 extern const char* kBreezeStr;
+
27 extern const char* kButtonStr;
+
28 extern const char* kCancelStr;
+
29 extern const char* kCeilingStr;
+
30 extern const char* kCelsiusStr;
+
31 extern const char* kCentreStr;
+
32 extern const char* kChangeStr;
+
33 extern const char* kCirculateStr;
+
34 extern const char* kCleanStr;
+
35 extern const char* kClockStr;
+
36 extern const char* kCodeStr;
+
37 extern const char* kColonSpaceStr;
+
38 extern const char* kComfortStr;
+
39 extern const char* kCommandStr;
+
40 extern const char* kCommaSpaceStr;
+
41 extern const char* kCoolStr;
+
42 extern const char* kDaysStr;
+
43 extern const char* kDayStr;
+
44 extern const char* kDisplayTempStr;
+
45 extern const char* kDownStr;
+
46 extern const char* kDryStr;
+
47 extern const char* kEconoStr;
+
48 extern const char* kEyeAutoStr;
+
49 extern const char* kEyeStr;
+
50 extern const char* kFalseStr;
+
51 extern const char* kFanOnlyStr;
+
52 extern const char* kFanStr;
+
53 extern const char* kFastStr;
+
54 extern const char* kFilterStr;
+
55 extern const char* kFixedStr;
+
56 extern const char* kFollowStr;
+
57 extern const char* kFreshStr;
+
58 extern const char* kHealthStr;
+
59 extern const char* kHeatStr;
+
60 extern const char* kHighestStr;
+
61 extern const char* kHighStr;
+
62 extern const char* kHiStr;
+
63 extern const char* kHoldStr;
+
64 extern const char* kHoursStr;
+
65 extern const char* kHourStr;
+
66 extern const char* kHumidStr;
+
67 extern const char* kIFeelStr;
+
68 extern const char* kInsideStr;
+
69 extern const char* kIonStr;
+
70 extern const char* kLastStr;
+
71 extern const char* kLeftMaxStr;
+
72 extern const char* kLeftStr;
+
73 extern const char* kLightStr;
+
74 extern const char* kLightToggleStr;
+
75 extern const char* kLoStr;
+
76 extern const char* kLoudStr;
+
77 extern const char* kLowerStr;
+
78 extern const char* kLowestStr;
+
79 extern const char* kLowStr;
+
80 extern const char* kManualStr;
+
81 extern const char* kMaximumStr;
+
82 extern const char* kMaxLeftStr;
+
83 extern const char* kMaxRightStr;
+
84 extern const char* kMaxStr;
+
85 extern const char* kMediumStr;
+
86 extern const char* kMedStr;
+
87 extern const char* kMiddleStr;
+
88 extern const char* kMidStr;
+
89 extern const char* kMinimumStr;
+
90 extern const char* kMinStr;
+
91 extern const char* kMinutesStr;
+
92 extern const char* kMinuteStr;
+
93 extern const char* kModelStr;
+
94 extern const char* kModeStr;
+
95 extern const char* kMouldStr;
+
96 extern const char* kMoveStr;
+
97 extern const char* kNAStr;
+
98 extern const char* kNightStr;
+
99 extern const char* kNoStr;
+
100 extern const char* kNowStr;
+
101 extern const char* kOffStr;
+
102 extern const char* kOffTimerStr;
+
103 extern const char* kOnStr;
+
104 extern const char* kOnTimerStr;
+
105 extern const char* kOutsideQuietStr;
+
106 extern const char* kOutsideStr;
+
107 extern const char* kPowerfulStr;
+
108 extern const char* kPowerStr;
+
109 extern const char* kPowerToggleStr;
+
110 extern const char* kPowerButtonStr;
+
111 extern const char* kPreviousPowerStr;
+
112 extern const char* kProtocolStr;
+
113 extern const char* kPurifyStr;
+
114 extern const char* kQuietStr;
+
115 extern const char* kRepeatStr;
+
116 extern const char* kRightMaxStr;
+
117 extern const char* kRightStr;
+
118 extern const char* kRoomStr;
+
119 extern const char* kSaveStr;
+
120 extern const char* kSecondsStr;
+
121 extern const char* kSecondStr;
+
122 extern const char* kSensorStr;
+
123 extern const char* kSensorTempStr;
+
124 extern const char* kSetStr;
+
125 extern const char* kSilentStr;
+
126 extern const char* kSleepStr;
+
127 extern const char* kSleepTimerStr;
+
128 extern const char* kSlowStr;
+
129 extern const char* kSpaceLBraceStr;
+
130 extern const char* kStartStr;
+
131 extern const char* kStepStr;
+
132 extern const char* kStopStr;
+
133 extern const char* kSuperStr;
+
134 extern const char* kSwingHStr;
+
135 extern const char* kSwingStr;
+
136 extern const char* kSwingVModeStr;
+
137 extern const char* kSwingVStr;
+
138 extern const char* kSwingVToggleStr;
+
139 extern const char* kTempDownStr;
+
140 extern const char* kTempStr;
+
141 extern const char* kTempUpStr;
+
142 extern const char* kThreeLetterDayOfWeekStr;
+
143 extern const char* kTimerStr;
+
144 extern const char* kToggleStr;
+
145 extern const char* kTopStr;
+
146 extern const char* kTrueStr;
+
147 extern const char* kTurboStr;
+
148 extern const char* kUnknownStr;
+
149 extern const char* kUpperStr;
+
150 extern const char* kUpStr;
+
151 extern const char* kWallStr;
+
152 extern const char* kWeeklyTimerStr;
+
153 extern const char* kWideStr;
+
154 extern const char* kWifiStr;
+
155 extern const char* kXFanStr;
+
156 extern const char* kYesStr;
+
157 extern const char* kZoneFollowStr;
+
158 
+
159 #endif // IRTEXT_H_
+
+
const char * kTrueStr
"True"
Definition: IRtext.cpp:168
+
const char * kHoldStr
"Hold"
Definition: IRtext.cpp:57
+
const char * kStopStr
"Stop"
Definition: IRtext.cpp:68
+
const char * kQuietStr
"Quiet"
Definition: IRtext.cpp:30
+
const char * kBitsStr
"Bits"
Definition: IRtext.cpp:173
+
const char * kPowerButtonStr
"Power Button"
Definition: IRtext.cpp:137
+
const char * kMediumStr
"Medium"
Definition: IRtext.cpp:111
+
const char * kStepStr
"Step"
Definition: IRtext.cpp:83
+
const char * kSilentStr
"Silent"
Definition: IRtext.cpp:61
+
const char * kOnTimerStr
"OnTimer"
Definition: IRtext.cpp:42
+
const char * kLoStr
"Lo"
Definition: IRtext.cpp:119
+
const char * kSwingStr
"Swing"
Definition: IRtext.cpp:32
+
const char * kCodeStr
"Code"
Definition: IRtext.cpp:172
+
const char * kSecondsStr
"Seconds"
Definition: IRtext.cpp:162
+
const char * kSetStr
"Set"
Definition: IRtext.cpp:70
+
const char * kHiStr
"Hi"
Definition: IRtext.cpp:115
+
const char * kRepeatStr
"Repeat"
Definition: IRtext.cpp:171
+
const char * kCeilingStr
"Ceiling"
Definition: IRtext.cpp:92
+
const char * kPowerToggleStr
"Power Toggle"
Definition: IRtext.cpp:136
+
const char * kInsideStr
"Inside"
Definition: IRtext.cpp:85
+
const char * kTempDownStr
"Temp Down"
Definition: IRtext.cpp:66
+
const char * kMoveStr
"Move"
Definition: IRtext.cpp:69
+
const char * kColonSpaceStr
": "
Definition: IRtext.cpp:151
+
const char * kWideStr
"Wide"
Definition: IRtext.cpp:127
+
const char * kRightMaxStr
"RightMax"
Definition: IRtext.cpp:122
+
const char * kDownStr
"Down"
Definition: IRtext.cpp:73
+
const char * kLightStr
"Light"
Definition: IRtext.cpp:28
+
const char * kCoolStr
"Cool"
Definition: IRtext.cpp:100
+
const char * kRightStr
"Right"
Definition: IRtext.cpp:123
+
const char * kMinuteStr
"Minute"
Definition: IRtext.cpp:159
+
const char * kMinutesStr
"Minutes"
Definition: IRtext.cpp:160
+
const char * kSleepStr
"Sleep"
Definition: IRtext.cpp:27
+
const char * kMinimumStr
"Minimum"
Definition: IRtext.cpp:109
+
const char * k3DStr
"3D"
Definition: IRtext.cpp:63
+
const char * kTempStr
"Temp"
Definition: IRtext.cpp:49
+
const char * kAutomaticStr
"Automatic"
Definition: IRtext.cpp:98
+
const char * kSecondStr
"Second"
Definition: IRtext.cpp:161
+
const char * kSwingVToggleStr
"Swing(V) Toggle"
Definition: IRtext.cpp:144
+
const char * k6thSenseStr
"6th Sense"
Definition: IRtext.cpp:95
+
const char * kFilterStr
"Filter"
Definition: IRtext.cpp:62
+
const char * kNightStr
"Night"
Definition: IRtext.cpp:60
+
const char * kSpaceLBraceStr
" ("
Definition: IRtext.cpp:149
+
const char * kSleepTimerStr
"Sleep Timer"
Definition: IRtext.cpp:142
+
const char * kSwingVModeStr
"Swing(V) Mode"
Definition: IRtext.cpp:143
+
const char * kTimerStr
"Timer"
Definition: IRtext.cpp:41
+
const char * kChangeStr
"Change"
Definition: IRtext.cpp:74
+
const char * kAllProtocolNamesStr
New protocol strings should be added just above this line.
Definition: IRtext.cpp:177
+
const char * kIFeelStr
"IFeel"
Definition: IRtext.cpp:50
+
const char * kFalseStr
"False"
Definition: IRtext.cpp:169
+
const char * kMaxLeftStr
"Max Left"
Definition: IRtext.cpp:125
+
const char * kHealthStr
"Health"
Definition: IRtext.cpp:47
+
const char * kCommandStr
"Command"
Definition: IRtext.cpp:45
+
const char * kXFanStr
"XFan"
Definition: IRtext.cpp:46
+
const char * kPurifyStr
"Purify"
Definition: IRtext.cpp:40
+
const char * kHighStr
"High"
Definition: IRtext.cpp:114
+
const char * kCommaSpaceStr
", "
Definition: IRtext.cpp:150
+
const char * kFanStr
"Fan"
Definition: IRtext.cpp:102
+
const char * kTopStr
"Top"
Definition: IRtext.cpp:129
+
const char * kNowStr
"Now"
Definition: IRtext.cpp:163
+
const char * kOffStr
"Off"
Definition: IRtext.cpp:22
+
const char * kMaximumStr
"Maximum"
Definition: IRtext.cpp:107
+
const char * kButtonStr
"Button"
Definition: IRtext.cpp:58
+ +
const char * kTempUpStr
"Temp Up"
Definition: IRtext.cpp:65
+
const char * kCleanStr
"Clean"
Definition: IRtext.cpp:39
+
const char * kIonStr
"Ion"
Definition: IRtext.cpp:55
+
const char * kProtocolStr
"Protocol"
Definition: IRtext.cpp:19
+
const char * kEyeStr
"Eye"
Definition: IRtext.cpp:53
+
const char * kMedStr
"Med"
Definition: IRtext.cpp:110
+
const char * kThreeLetterDayOfWeekStr
"SunMonTueWedThuFriSat"
Definition: IRtext.cpp:164
+
const char * kCancelStr
"Cancel"
Definition: IRtext.cpp:71
+
const char * kWallStr
"Wall"
Definition: IRtext.cpp:93
+
const char * kToggleStr
"Toggle"
Definition: IRtext.cpp:24
+
const char * kMouldStr
"Mould"
Definition: IRtext.cpp:38
+
const char * kBottomStr
"Bottom"
Definition: IRtext.cpp:130
+
const char * kBeepStr
"Beep"
Definition: IRtext.cpp:35
+
const char * kRoomStr
"Room"
Definition: IRtext.cpp:94
+
const char * kFastStr
"Fast"
Definition: IRtext.cpp:80
+
const char * kDryStr
"Dry"
Definition: IRtext.cpp:103
+
const char * kUpperStr
"Upper"
Definition: IRtext.cpp:89
+
const char * kMiddleStr
"Middle"
Definition: IRtext.cpp:117
+
const char * kAirFlowStr
"Air Flow"
Definition: IRtext.cpp:82
+
const char * kLoudStr
"Loud"
Definition: IRtext.cpp:87
+
const char * kUnknownStr
"Unknown"
Definition: IRtext.cpp:18
+
const char * kSuperStr
"Super"
Definition: IRtext.cpp:26
+
const char * kAutoStr
"Auto"
Definition: IRtext.cpp:97
+
const char * kMidStr
"Mid"
Definition: IRtext.cpp:116
+
const char * kYesStr
"Yes"
Definition: IRtext.cpp:166
+
const char * kSlowStr
"Slow"
Definition: IRtext.cpp:81
+
const char * k8CHeatStr
"8CHeat"
Definition: IRtext.cpp:59
+
const char * kClockStr
"Clock"
Definition: IRtext.cpp:44
+
const char * kLeftMaxStr
"LeftMax"
Definition: IRtext.cpp:126
+
const char * kMaxStr
"Max"
Definition: IRtext.cpp:106
+
const char * kSaveStr
"Save"
Definition: IRtext.cpp:52
+
const char * kLightToggleStr
"Light Toggle"
Definition: IRtext.cpp:134
+
const char * kDayStr
"Day"
Definition: IRtext.cpp:155
+
const char * kFreshStr
"Fresh"
Definition: IRtext.cpp:56
+
const char * kCentreStr
"Centre"
Definition: IRtext.cpp:128
+
const char * kManualStr
"Manual"
Definition: IRtext.cpp:99
+
const char * kHeatStr
"Heat"
Definition: IRtext.cpp:101
+
const char * kMaxRightStr
"Max Right"
Definition: IRtext.cpp:121
+
const char * kUpStr
"Up"
Definition: IRtext.cpp:72
+
const char * kCelsiusStr
"Celsius"
Definition: IRtext.cpp:64
+
const char * kOnStr
"On"
Definition: IRtext.cpp:21
+
const char * kHoursStr
"Hours"
Definition: IRtext.cpp:158
+
const char * kBreezeStr
"Breeze"
Definition: IRtext.cpp:90
+
const char * kPowerfulStr
"Powerful"
Definition: IRtext.cpp:29
+
const char * kEyeAutoStr
"Eye Auto"
Definition: IRtext.cpp:133
+
const char * kComfortStr
"Comfort"
Definition: IRtext.cpp:75
+
const char * kHighestStr
"Highest"
Definition: IRtext.cpp:113
+
const char * kFanOnlyStr
"fan_only"
Definition: IRtext.cpp:104
+
const char * kMinStr
"Min"
Definition: IRtext.cpp:108
+
const char * kFollowStr
"Follow"
Definition: IRtext.cpp:54
+
const char * kWeeklyTimerStr
"WeeklyTimer"
Definition: IRtext.cpp:77
+
const char * kOutsideQuietStr
"Outside Quiet"
Definition: IRtext.cpp:135
+
const char * kLowStr
"Low"
Definition: IRtext.cpp:118
+
const char * kFixedStr
"Fixed"
Definition: IRtext.cpp:37
+
const char * kStartStr
"Start"
Definition: IRtext.cpp:67
+
const char * kDaysStr
"Days"
Definition: IRtext.cpp:156
+
const char * kWifiStr
"Wifi"
Definition: IRtext.cpp:78
+
const char * kSwingHStr
"SwingH"
Definition: IRtext.cpp:33
+
const char * kLastStr
"Last"
Definition: IRtext.cpp:79
+
const char * kEconoStr
"Econo"
Definition: IRtext.cpp:31
+
const char * kNAStr
"N/A"
Definition: IRtext.cpp:84
+
char kTimeSep
':'
Definition: IRtext.cpp:148
+
const char * kModelStr
"Model"
Definition: IRtext.cpp:48
+
const char * kOutsideStr
"Outside"
Definition: IRtext.cpp:86
+
const char * kPowerStr
"Power"
Definition: IRtext.cpp:20
+
const char * kCirculateStr
"Circulate"
Definition: IRtext.cpp:91
+
const char * kLeftStr
"Left"
Definition: IRtext.cpp:124
+
const char * kSensorStr
"Sensor"
Definition: IRtext.cpp:76
+
const char * kPreviousPowerStr
"Previous Power"
Definition: IRtext.cpp:138
+
const char * kHumidStr
"Humid"
Definition: IRtext.cpp:51
+
const char * kZoneFollowStr
"Zone Follow"
Definition: IRtext.cpp:36
+
const char * kNoStr
"No"
Definition: IRtext.cpp:167
+
const char * kOffTimerStr
"OffTimer"
Definition: IRtext.cpp:43
+
const char * kLowerStr
"Lower"
Definition: IRtext.cpp:88
+
const char * kDisplayTempStr
"Display Temp"
Definition: IRtext.cpp:140
+
const char * kSwingVStr
"SwingV"
Definition: IRtext.cpp:34
+
const char * kLowestStr
"Lowest"
Definition: IRtext.cpp:120
+
const char * kTurboStr
"Turbo"
Definition: IRtext.cpp:25
+
const char * kHourStr
"Hour"
Definition: IRtext.cpp:157
+
const char * kModeStr
"Mode"
Definition: IRtext.cpp:23
+
const char * kSensorTempStr
"Sensor Temp"
Definition: IRtext.cpp:141
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8cpp.html new file mode 100644 index 000000000..8c3da0949 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8cpp.html @@ -0,0 +1,119 @@ + + + + + + + +IRremoteESP8266: src/IRtimer.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRtimer.cpp File Reference
+
+
+ + + + + + +

+Variables

uint32_t _IRtimer_unittest_now = 0
 
uint32_t _TimerMs_unittest_now = 0
 
+

Variable Documentation

+ +

◆ _IRtimer_unittest_now

+ +
+
+ + + + +
uint32_t _IRtimer_unittest_now = 0
+
+ +
+
+ +

◆ _TimerMs_unittest_now

+ +
+
+ + + + +
uint32_t _TimerMs_unittest_now = 0
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h.html new file mode 100644 index 000000000..333d009b4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h.html @@ -0,0 +1,94 @@ + + + + + + + +IRremoteESP8266: src/IRtimer.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRtimer.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

class  IRtimer
 This class performs a simple timer in useconds since instantiated. More...
 
class  TimerMs
 This class performs a simple timer in milli-seoncds since instantiated. More...
 
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h_source.html new file mode 100644 index 000000000..eaef1f0bc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h_source.html @@ -0,0 +1,128 @@ + + + + + + + +IRremoteESP8266: src/IRtimer.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRtimer.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 David Conran
+
2 
+
3 #ifndef IRTIMER_H_
+
4 #define IRTIMER_H_
+
5 
+
6 #define __STDC_LIMIT_MACROS
+
7 #include <stdint.h>
+
8 
+
9 // Classes
+
10 
+
13 class IRtimer {
+
14  public:
+
15  IRtimer();
+
16  void reset();
+
17  uint32_t elapsed();
+
18 #ifdef UNIT_TEST
+
19  static void add(uint32_t usecs);
+
20 #endif // UNIT_TEST
+
21 
+
22  private:
+
23  uint32_t start;
+
24 };
+
25 
+
28 class TimerMs {
+
29  public:
+
30  TimerMs();
+
31  void reset();
+
32  uint32_t elapsed();
+
33 #ifdef UNIT_TEST
+
34  static void add(uint32_t msecs);
+
35 #endif // UNIT_TEST
+
36 
+
37  private:
+
38  uint32_t start;
+
39 };
+
40 #endif // IRTIMER_H_
+
+
uint32_t start
Definition: IRtimer.h:38
+
This class performs a simple timer in useconds since instantiated.
Definition: IRtimer.h:13
+
static void add(uint32_t usecs)
Add time to the timer to simulate elapsed time.
Definition: IRtimer.cpp:44
+
void reset()
Resets the IRtimer object.
Definition: IRtimer.cpp:18
+
IRtimer()
Class constructor.
Definition: IRtimer.cpp:15
+
uint32_t elapsed()
Calculate how many microseconds have elapsed since the timer was started.
Definition: IRtimer.cpp:28
+
uint32_t elapsed()
Calculate how many milliseconds have elapsed since the timer was started.
Definition: IRtimer.cpp:61
+
void reset()
Resets the TimerMs object.
Definition: IRtimer.cpp:51
+
TimerMs()
Class constructor.
Definition: IRtimer.cpp:48
+
uint32_t start
Definition: IRtimer.h:23
+
static void add(uint32_t msecs)
Add time to the timer to simulate elapsed time.
Definition: IRtimer.cpp:77
+
This class performs a simple timer in milli-seoncds since instantiated.
Definition: IRtimer.h:28
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8cpp.html new file mode 100644 index 000000000..b0d65d3dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8cpp.html @@ -0,0 +1,871 @@ + + + + + + + +IRremoteESP8266: src/IRutils.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRutils.cpp File Reference
+
+
+ + + + + +

+Namespaces

 irutils
 Namespace for covering common functions & procedures for advancd protocol handlers.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

uint64_t reverseBits (uint64_t input, uint16_t nbits)
 Reverse the order of the requested least significant nr. of bits. More...
 
String uint64ToString (uint64_t input, uint8_t base)
 Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle printing 64 bit values. More...
 
void serialPrintUint64 (uint64_t input, uint8_t base)
 Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long longs. (uint64_t) More...
 
decode_type_t strToDecodeType (const char *const str)
 Convert a C-style string to a decode_type_t. More...
 
String typeToString (const decode_type_t protocol, const bool isRepeat)
 Convert a protocol type (enum etc) to a human readable string. More...
 
bool hasACState (const decode_type_t protocol)
 Does the given protocol use a complex state as part of the decode? More...
 
uint16_t getCorrectedRawLength (const decode_results *const results)
 Return the corrected length of a 'raw' format array structure after over-large values are converted into multiple entries. More...
 
String resultToSourceCode (const decode_results *const results)
 Return a String containing the key values of a decode_results structure in a C/C++ code style format. More...
 
String resultToTimingInfo (const decode_results *const results)
 Dump out the decode_results structure. More...
 
String resultToHexidecimal (const decode_results *const result)
 Convert the decode_results structure's value/state to simple hexadecimal. More...
 
String resultToHumanReadableBasic (const decode_results *const results)
 Dump out the decode_results structure into a human readable format. More...
 
uint16_t * resultToRawArray (const decode_results *const decode)
 Convert a decode_results into an array suitable for sendRaw(). More...
 
uint8_t sumBytes (const uint8_t *const start, const uint16_t length, const uint8_t init)
 Sum all the bytes of an array and return the least significant 8-bits of the result. More...
 
uint8_t xorBytes (const uint8_t *const start, const uint16_t length, const uint8_t init)
 Calculate a rolling XOR of all the bytes of an array. More...
 
uint16_t countBits (const uint8_t *const start, const uint16_t length, const bool ones, const uint16_t init)
 Count the number of bits of a certain type in an array. More...
 
uint16_t countBits (const uint64_t data, const uint8_t length, const bool ones, const uint16_t init)
 Count the number of bits of a certain type in an Integer. More...
 
uint64_t invertBits (const uint64_t data, const uint16_t nbits)
 Invert/Flip the bits in an Integer. More...
 
float celsiusToFahrenheit (const float deg)
 Convert degrees Celsius to degrees Fahrenheit. More...
 
float fahrenheitToCelsius (const float deg)
 Convert degrees Fahrenheit to degrees Celsius. More...
 
String irutils::addLabeledString (const String value, const String label, const bool precomma)
 Create a String with a colon separated "label: value" pair suitable for Humans. More...
 
String irutils::addBoolToString (const bool value, const String label, const bool precomma)
 Create a String with a colon separated flag suitable for Humans. e.g. "Power: On". More...
 
String irutils::addIntToString (const uint16_t value, const String label, const bool precomma)
 Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23". More...
 
String irutils::modelToStr (const decode_type_t protocol, const int16_t model)
 Generate the model string for a given Protocol/Model pair. More...
 
String irutils::addModelToString (const decode_type_t protocol, const int16_t model, const bool precomma)
 Create a String of human output for a given protocol model number. e.g. "Model: JKE". More...
 
String irutils::addTempToString (const uint16_t degrees, const bool celsius, const bool precomma)
 Create a String of human output for a given temperature. e.g. "Temp: 25C". More...
 
String irutils::addModeToString (const uint8_t mode, const uint8_t automatic, const uint8_t cool, const uint8_t heat, const uint8_t dry, const uint8_t fan)
 Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)". More...
 
String irutils::addDayToString (const uint8_t day_of_week, const int8_t offset, const bool precomma)
 Create a String of the 3-letter day of the week from a numerical day of the week. e.g. "Day: 1 (Mon)". More...
 
String irutils::addFanToString (const uint8_t speed, const uint8_t high, const uint8_t low, const uint8_t automatic, const uint8_t quiet, const uint8_t medium)
 Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)". More...
 
String irutils::htmlEscape (const String unescaped)
 Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS. More...
 
String irutils::msToString (uint32_t const msecs)
 Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds". More...
 
String irutils::minsToString (const uint16_t mins)
 Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59". More...
 
uint8_t irutils::sumNibbles (const uint8_t *const start, const uint16_t length, const uint8_t init)
 Sum all the nibbles together in a series of bytes. More...
 
uint8_t irutils::sumNibbles (const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)
 Sum all the nibbles together in an integer. More...
 
uint8_t irutils::bcdToUint8 (const uint8_t bcd)
 Convert a byte of Binary Coded Decimal(BCD) into an Integer. More...
 
uint8_t irutils::uint8ToBcd (const uint8_t integer)
 Convert an Integer into a byte of Binary Coded Decimal(BCD). More...
 
bool irutils::getBit (const uint64_t data, const uint8_t position, const uint8_t size)
 Return the value of positionth bit of an Integer. More...
 
bool irutils::getBit (const uint8_t data, const uint8_t position)
 Return the value of positionth bit of an Integer. More...
 
uint64_t irutils::setBit (const uint64_t data, const uint8_t position, const bool on, const uint8_t size)
 Return the value of an Integer with the positionth bit changed. More...
 
uint8_t irutils::setBit (const uint8_t data, const uint8_t position, const bool on)
 Return the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint8_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint32_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint64_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBits (uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)
 Alter an uint8_t value by overwriting an arbitary given number of bits. More...
 
void irutils::setBits (uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)
 Alter an uint32_t value by overwriting an arbitary given number of bits. More...
 
void irutils::setBits (uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)
 Alter an uint64_t value by overwriting an arbitary given number of bits. More...
 
+

Function Documentation

+ +

◆ celsiusToFahrenheit()

+ +
+
+ + + + + + + + +
float celsiusToFahrenheit (const float deg)
+
+ +

Convert degrees Celsius to degrees Fahrenheit.

+ +
+
+ +

◆ countBits() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t countBits (const uint64_t data,
const uint8_t length,
const bool ones,
const uint16_t init 
)
+
+ +

Count the number of bits of a certain type in an Integer.

+
Parameters
+ + + + + +
[in]dataThe value you want bits counted for. Starting from the LSB.
[in]lengthHow many bits to use in the calculation? Starts at the LSB
[in]onesCount the binary nr of 1 bits. False is count the 0s.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The nr. of bits found of the given type found in the Integer.
+ +
+
+ +

◆ countBits() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t countBits (const uint8_t *const start,
const uint16_t length,
const bool ones,
const uint16_t init 
)
+
+ +

Count the number of bits of a certain type in an array.

+
Parameters
+ + + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]onesCount the binary nr of 1 bits. False is count the 0s.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The nr. of bits found of the given type found in the array.
+ +
+
+ +

◆ fahrenheitToCelsius()

+ +
+
+ + + + + + + + +
float fahrenheitToCelsius (const float deg)
+
+ +

Convert degrees Fahrenheit to degrees Celsius.

+ +
+
+ +

◆ getCorrectedRawLength()

+ +
+
+ + + + + + + + +
uint16_t getCorrectedRawLength (const decode_results *const results)
+
+ +

Return the corrected length of a 'raw' format array structure after over-large values are converted into multiple entries.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
The corrected length.
+ +
+
+ +

◆ hasACState()

+ +
+
+ + + + + + + + +
bool hasACState (const decode_type_t protocol)
+
+ +

Does the given protocol use a complex state as part of the decode?

+
Parameters
+ + +
[in]protocolThe decode_type_t protocol we are enquiring about.
+
+
+
Returns
True if the protocol uses a state array. False if just an integer.
+ +
+
+ +

◆ invertBits()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t invertBits (const uint64_t data,
const uint16_t nbits 
)
+
+ +

Invert/Flip the bits in an Integer.

+
Parameters
+ + + +
[in]dataThe Integer that will be inverted.
[in]nbitsHow many bits are to be inverted. Starting from the LSB.
+
+
+
Returns
An Integer with the appropriate bits inverted/flipped.
+ +
+
+ +

◆ resultToHexidecimal()

+ +
+
+ + + + + + + + +
String resultToHexidecimal (const decode_results *const result)
+
+ +

Convert the decode_results structure's value/state to simple hexadecimal.

+
Parameters
+ + +
[in]resultA ptr to a decode_results structure.
+
+
+
Returns
A String containing the output.
+ +
+
+ +

◆ resultToHumanReadableBasic()

+ +
+
+ + + + + + + + +
String resultToHumanReadableBasic (const decode_results *const results)
+
+ +

Dump out the decode_results structure into a human readable format.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the output.
+ +
+
+ +

◆ resultToRawArray()

+ +
+
+ + + + + + + + +
uint16_t* resultToRawArray (const decode_results *const decode)
+
+ +

Convert a decode_results into an array suitable for sendRaw().

+
Parameters
+ + +
[in]decodeA ptr to a decode_results structure that contains a mesg.
+
+
+
Returns
A PTR to a dynamically allocated uint16_t sendRaw compatible array.
+
Note
The returned array needs to be delete[]'ed/free()'ed (deallocated) after use by caller.
+ +
+
+ +

◆ resultToSourceCode()

+ +
+
+ + + + + + + + +
String resultToSourceCode (const decode_results *const results)
+
+ +

Return a String containing the key values of a decode_results structure in a C/C++ code style format.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the code-ified result.
+ +
+
+ +

◆ resultToTimingInfo()

+ +
+
+ + + + + + + + +
String resultToTimingInfo (const decode_results *const results)
+
+ +

Dump out the decode_results structure.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the legacy information format.
+
Deprecated:
This is only for those that want this legacy format.
+ +
+
+ +

◆ reverseBits()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t reverseBits (uint64_t input,
uint16_t nbits 
)
+
+ +

Reverse the order of the requested least significant nr. of bits.

+
Parameters
+ + + +
[in]inputBit pattern/integer to reverse.
[in]nbitsNr. of bits to reverse. (LSB -> MSB)
+
+
+
Returns
The reversed bit pattern.
+ +
+
+ +

◆ serialPrintUint64()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void serialPrintUint64 (uint64_t input,
uint8_t base 
)
+
+ +

Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long longs. (uint64_t)

+
Parameters
+ + + +
[in]inputThe value to print
[in]baseThe output base.
+
+
+ +
+
+ +

◆ strToDecodeType()

+ +
+
+ + + + + + + + +
decode_type_t strToDecodeType (const char *const str)
+
+ +

Convert a C-style string to a decode_type_t.

+
Parameters
+ + +
[in]strA C-style string containing a protocol name or number.
+
+
+
Returns
A decode_type_t enum. (decode_type_t::UNKNOWN if no match.)
+ +
+
+ +

◆ sumBytes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t sumBytes (const uint8_t *const start,
const uint16_t length,
const uint8_t init 
)
+
+ +

Sum all the bytes of an array and return the least significant 8-bits of the result.

+
Parameters
+ + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The 8-bit calculated result of all the bytes and init value.
+ +
+
+ +

◆ typeToString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
String typeToString (const decode_type_t protocol,
const bool isRepeat 
)
+
+ +

Convert a protocol type (enum etc) to a human readable string.

+
Parameters
+ + + +
[in]protocolNr. (enum) of the protocol.
[in]isRepeatA flag indicating if it is a repeat message.
+
+
+
Returns
A String containing the protocol name. kUnknownStr if no match.
+ +
+
+ +

◆ uint64ToString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
String uint64ToString (uint64_t input,
uint8_t base 
)
+
+ +

Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle printing 64 bit values.

+
Parameters
+ + + +
[in]inputThe value to print
[in]baseThe output base.
+
+
+
Returns
A String representation of the integer.
+
Note
Based on Arduino's Print::printNumber()
+ +
+
+ +

◆ xorBytes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t xorBytes (const uint8_t *const start,
const uint16_t length,
const uint8_t init 
)
+
+ +

Calculate a rolling XOR of all the bytes of an array.

+
Parameters
+ + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The 8-bit calculated result of all the bytes and init value.
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h.html new file mode 100644 index 000000000..9c9c4cd28 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h.html @@ -0,0 +1,942 @@ + + + + + + + +IRremoteESP8266: src/IRutils.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRutils.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + +

+Namespaces

 irutils
 Namespace for covering common functions & procedures for advancd protocol handlers.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

uint64_t reverseBits (uint64_t input, uint16_t nbits)
 Reverse the order of the requested least significant nr. of bits. More...
 
String uint64ToString (uint64_t input, uint8_t base=10)
 Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle printing 64 bit values. More...
 
String typeToString (const decode_type_t protocol, const bool isRepeat=false)
 Convert a protocol type (enum etc) to a human readable string. More...
 
void serialPrintUint64 (uint64_t input, uint8_t base=10)
 Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long longs. (uint64_t) More...
 
String resultToSourceCode (const decode_results *const results)
 Return a String containing the key values of a decode_results structure in a C/C++ code style format. More...
 
String resultToTimingInfo (const decode_results *const results)
 Dump out the decode_results structure. More...
 
String resultToHumanReadableBasic (const decode_results *const results)
 Dump out the decode_results structure into a human readable format. More...
 
String resultToHexidecimal (const decode_results *const result)
 Convert the decode_results structure's value/state to simple hexadecimal. More...
 
bool hasACState (const decode_type_t protocol)
 Does the given protocol use a complex state as part of the decode? More...
 
uint16_t getCorrectedRawLength (const decode_results *const results)
 Return the corrected length of a 'raw' format array structure after over-large values are converted into multiple entries. More...
 
uint16_t * resultToRawArray (const decode_results *const decode)
 Convert a decode_results into an array suitable for sendRaw(). More...
 
uint8_t sumBytes (const uint8_t *const start, const uint16_t length, const uint8_t init=0)
 Sum all the bytes of an array and return the least significant 8-bits of the result. More...
 
uint8_t xorBytes (const uint8_t *const start, const uint16_t length, const uint8_t init=0)
 Calculate a rolling XOR of all the bytes of an array. More...
 
uint16_t countBits (const uint8_t *const start, const uint16_t length, const bool ones=true, const uint16_t init=0)
 Count the number of bits of a certain type in an array. More...
 
uint16_t countBits (const uint64_t data, const uint8_t length, const bool ones=true, const uint16_t init=0)
 Count the number of bits of a certain type in an Integer. More...
 
uint64_t invertBits (const uint64_t data, const uint16_t nbits)
 Invert/Flip the bits in an Integer. More...
 
decode_type_t strToDecodeType (const char *str)
 Convert a C-style string to a decode_type_t. More...
 
float celsiusToFahrenheit (const float deg)
 Convert degrees Celsius to degrees Fahrenheit. More...
 
float fahrenheitToCelsius (const float deg)
 Convert degrees Fahrenheit to degrees Celsius. More...
 
String irutils::addBoolToString (const bool value, const String label, const bool precomma)
 Create a String with a colon separated flag suitable for Humans. e.g. "Power: On". More...
 
String irutils::addIntToString (const uint16_t value, const String label, const bool precomma)
 Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23". More...
 
String irutils::modelToStr (const decode_type_t protocol, const int16_t model)
 Generate the model string for a given Protocol/Model pair. More...
 
String irutils::addModelToString (const decode_type_t protocol, const int16_t model, const bool precomma)
 Create a String of human output for a given protocol model number. e.g. "Model: JKE". More...
 
String irutils::addLabeledString (const String value, const String label, const bool precomma)
 Create a String with a colon separated "label: value" pair suitable for Humans. More...
 
String irutils::addTempToString (const uint16_t degrees, const bool celsius, const bool precomma)
 Create a String of human output for a given temperature. e.g. "Temp: 25C". More...
 
String irutils::addModeToString (const uint8_t mode, const uint8_t automatic, const uint8_t cool, const uint8_t heat, const uint8_t dry, const uint8_t fan)
 Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)". More...
 
String irutils::addFanToString (const uint8_t speed, const uint8_t high, const uint8_t low, const uint8_t automatic, const uint8_t quiet, const uint8_t medium)
 Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)". More...
 
String irutils::addDayToString (const uint8_t day_of_week, const int8_t offset, const bool precomma)
 Create a String of the 3-letter day of the week from a numerical day of the week. e.g. "Day: 1 (Mon)". More...
 
String irutils::htmlEscape (const String unescaped)
 Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS. More...
 
String irutils::msToString (uint32_t const msecs)
 Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds". More...
 
String irutils::minsToString (const uint16_t mins)
 Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59". More...
 
uint8_t irutils::sumNibbles (const uint8_t *const start, const uint16_t length, const uint8_t init)
 Sum all the nibbles together in a series of bytes. More...
 
uint8_t irutils::sumNibbles (const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)
 Sum all the nibbles together in an integer. More...
 
uint8_t irutils::bcdToUint8 (const uint8_t bcd)
 Convert a byte of Binary Coded Decimal(BCD) into an Integer. More...
 
uint8_t irutils::uint8ToBcd (const uint8_t integer)
 Convert an Integer into a byte of Binary Coded Decimal(BCD). More...
 
bool irutils::getBit (const uint64_t data, const uint8_t position, const uint8_t size)
 Return the value of positionth bit of an Integer. More...
 
bool irutils::getBit (const uint8_t data, const uint8_t position)
 Return the value of positionth bit of an Integer. More...
 
uint64_t irutils::setBit (const uint64_t data, const uint8_t position, const bool on, const uint8_t size)
 Return the value of an Integer with the positionth bit changed. More...
 
uint8_t irutils::setBit (const uint8_t data, const uint8_t position, const bool on)
 Return the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint8_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint32_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint64_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBits (uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)
 Alter an uint8_t value by overwriting an arbitary given number of bits. More...
 
void irutils::setBits (uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)
 Alter an uint32_t value by overwriting an arbitary given number of bits. More...
 
void irutils::setBits (uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)
 Alter an uint64_t value by overwriting an arbitary given number of bits. More...
 
+ + + + + + + + + +

+Variables

const uint8_t kNibbleSize = 4
 
const uint8_t kLowNibble = 0
 
const uint8_t kHighNibble = 4
 
const uint8_t kModeBitsSize = 3
 
+

Function Documentation

+ +

◆ celsiusToFahrenheit()

+ +
+
+ + + + + + + + +
float celsiusToFahrenheit (const float deg)
+
+ +

Convert degrees Celsius to degrees Fahrenheit.

+ +
+
+ +

◆ countBits() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t countBits (const uint64_t data,
const uint8_t length,
const bool ones,
const uint16_t init 
)
+
+ +

Count the number of bits of a certain type in an Integer.

+
Parameters
+ + + + + +
[in]dataThe value you want bits counted for. Starting from the LSB.
[in]lengthHow many bits to use in the calculation? Starts at the LSB
[in]onesCount the binary nr of 1 bits. False is count the 0s.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The nr. of bits found of the given type found in the Integer.
+ +
+
+ +

◆ countBits() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t countBits (const uint8_t *const start,
const uint16_t length,
const bool ones,
const uint16_t init 
)
+
+ +

Count the number of bits of a certain type in an array.

+
Parameters
+ + + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]onesCount the binary nr of 1 bits. False is count the 0s.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The nr. of bits found of the given type found in the array.
+ +
+
+ +

◆ fahrenheitToCelsius()

+ +
+
+ + + + + + + + +
float fahrenheitToCelsius (const float deg)
+
+ +

Convert degrees Fahrenheit to degrees Celsius.

+ +
+
+ +

◆ getCorrectedRawLength()

+ +
+
+ + + + + + + + +
uint16_t getCorrectedRawLength (const decode_results *const results)
+
+ +

Return the corrected length of a 'raw' format array structure after over-large values are converted into multiple entries.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
The corrected length.
+ +
+
+ +

◆ hasACState()

+ +
+
+ + + + + + + + +
bool hasACState (const decode_type_t protocol)
+
+ +

Does the given protocol use a complex state as part of the decode?

+
Parameters
+ + +
[in]protocolThe decode_type_t protocol we are enquiring about.
+
+
+
Returns
True if the protocol uses a state array. False if just an integer.
+ +
+
+ +

◆ invertBits()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t invertBits (const uint64_t data,
const uint16_t nbits 
)
+
+ +

Invert/Flip the bits in an Integer.

+
Parameters
+ + + +
[in]dataThe Integer that will be inverted.
[in]nbitsHow many bits are to be inverted. Starting from the LSB.
+
+
+
Returns
An Integer with the appropriate bits inverted/flipped.
+ +
+
+ +

◆ resultToHexidecimal()

+ +
+
+ + + + + + + + +
String resultToHexidecimal (const decode_results *const result)
+
+ +

Convert the decode_results structure's value/state to simple hexadecimal.

+
Parameters
+ + +
[in]resultA ptr to a decode_results structure.
+
+
+
Returns
A String containing the output.
+ +
+
+ +

◆ resultToHumanReadableBasic()

+ +
+
+ + + + + + + + +
String resultToHumanReadableBasic (const decode_results *const results)
+
+ +

Dump out the decode_results structure into a human readable format.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the output.
+ +
+
+ +

◆ resultToRawArray()

+ +
+
+ + + + + + + + +
uint16_t* resultToRawArray (const decode_results *const decode)
+
+ +

Convert a decode_results into an array suitable for sendRaw().

+
Parameters
+ + +
[in]decodeA ptr to a decode_results structure that contains a mesg.
+
+
+
Returns
A PTR to a dynamically allocated uint16_t sendRaw compatible array.
+
Note
The returned array needs to be delete[]'ed/free()'ed (deallocated) after use by caller.
+ +
+
+ +

◆ resultToSourceCode()

+ +
+
+ + + + + + + + +
String resultToSourceCode (const decode_results *const results)
+
+ +

Return a String containing the key values of a decode_results structure in a C/C++ code style format.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the code-ified result.
+ +
+
+ +

◆ resultToTimingInfo()

+ +
+
+ + + + + + + + +
String resultToTimingInfo (const decode_results *const results)
+
+ +

Dump out the decode_results structure.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the legacy information format.
+
Deprecated:
This is only for those that want this legacy format.
+ +
+
+ +

◆ reverseBits()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t reverseBits (uint64_t input,
uint16_t nbits 
)
+
+ +

Reverse the order of the requested least significant nr. of bits.

+
Parameters
+ + + +
[in]inputBit pattern/integer to reverse.
[in]nbitsNr. of bits to reverse. (LSB -> MSB)
+
+
+
Returns
The reversed bit pattern.
+ +
+
+ +

◆ serialPrintUint64()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void serialPrintUint64 (uint64_t input,
uint8_t base 
)
+
+ +

Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long longs. (uint64_t)

+
Parameters
+ + + +
[in]inputThe value to print
[in]baseThe output base.
+
+
+ +
+
+ +

◆ strToDecodeType()

+ +
+
+ + + + + + + + +
decode_type_t strToDecodeType (const char *const str)
+
+ +

Convert a C-style string to a decode_type_t.

+
Parameters
+ + +
[in]strA C-style string containing a protocol name or number.
+
+
+
Returns
A decode_type_t enum. (decode_type_t::UNKNOWN if no match.)
+ +
+
+ +

◆ sumBytes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t sumBytes (const uint8_t *const start,
const uint16_t length,
const uint8_t init 
)
+
+ +

Sum all the bytes of an array and return the least significant 8-bits of the result.

+
Parameters
+ + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The 8-bit calculated result of all the bytes and init value.
+ +
+
+ +

◆ typeToString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
String typeToString (const decode_type_t protocol,
const bool isRepeat 
)
+
+ +

Convert a protocol type (enum etc) to a human readable string.

+
Parameters
+ + + +
[in]protocolNr. (enum) of the protocol.
[in]isRepeatA flag indicating if it is a repeat message.
+
+
+
Returns
A String containing the protocol name. kUnknownStr if no match.
+ +
+
+ +

◆ uint64ToString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
String uint64ToString (uint64_t input,
uint8_t base 
)
+
+ +

Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle printing 64 bit values.

+
Parameters
+ + + +
[in]inputThe value to print
[in]baseThe output base.
+
+
+
Returns
A String representation of the integer.
+
Note
Based on Arduino's Print::printNumber()
+ +
+
+ +

◆ xorBytes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t xorBytes (const uint8_t *const start,
const uint16_t length,
const uint8_t init 
)
+
+ +

Calculate a rolling XOR of all the bytes of an array.

+
Parameters
+ + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The 8-bit calculated result of all the bytes and init value.
+ +
+
+

Variable Documentation

+ +

◆ kHighNibble

+ +
+
+ + + + +
const uint8_t kHighNibble = 4
+
+ +
+
+ +

◆ kLowNibble

+ +
+
+ + + + +
const uint8_t kLowNibble = 0
+
+ +
+
+ +

◆ kModeBitsSize

+ +
+
+ + + + +
const uint8_t kModeBitsSize = 3
+
+ +
+
+ +

◆ kNibbleSize

+ +
+
+ + + + +
const uint8_t kNibbleSize = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h_source.html new file mode 100644 index 000000000..74305e92d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h_source.html @@ -0,0 +1,235 @@ + + + + + + + +IRremoteESP8266: src/IRutils.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRutils.h
+
+
+Go to the documentation of this file.
1 #ifndef IRUTILS_H_
+
2 #define IRUTILS_H_
+
3 
+
4 // Copyright 2017 David Conran
+
5 
+
6 #ifndef UNIT_TEST
+
7 #include <Arduino.h>
+
8 #endif
+
9 #define __STDC_LIMIT_MACROS
+
10 #include <stdint.h>
+
11 #ifndef ARDUINO
+
12 #include <string>
+
13 #endif
+
14 #include "IRremoteESP8266.h"
+
15 #include "IRrecv.h"
+
16 
+
17 const uint8_t kNibbleSize = 4;
+
18 const uint8_t kLowNibble = 0;
+
19 const uint8_t kHighNibble = 4;
+
20 const uint8_t kModeBitsSize = 3;
+
21 uint64_t reverseBits(uint64_t input, uint16_t nbits);
+
22 String uint64ToString(uint64_t input, uint8_t base = 10);
+
23 String typeToString(const decode_type_t protocol,
+
24  const bool isRepeat = false);
+
25 void serialPrintUint64(uint64_t input, uint8_t base = 10);
+
26 String resultToSourceCode(const decode_results * const results);
+
27 String resultToTimingInfo(const decode_results * const results);
+
28 String resultToHumanReadableBasic(const decode_results * const results);
+
29 String resultToHexidecimal(const decode_results * const result);
+
30 bool hasACState(const decode_type_t protocol);
+
31 uint16_t getCorrectedRawLength(const decode_results * const results);
+
32 uint16_t *resultToRawArray(const decode_results * const decode);
+
33 uint8_t sumBytes(const uint8_t * const start, const uint16_t length,
+
34  const uint8_t init = 0);
+
35 uint8_t xorBytes(const uint8_t * const start, const uint16_t length,
+
36  const uint8_t init = 0);
+
37 uint16_t countBits(const uint8_t * const start, const uint16_t length,
+
38  const bool ones = true, const uint16_t init = 0);
+
39 uint16_t countBits(const uint64_t data, const uint8_t length,
+
40  const bool ones = true, const uint16_t init = 0);
+
41 uint64_t invertBits(const uint64_t data, const uint16_t nbits);
+
42 decode_type_t strToDecodeType(const char *str);
+
43 float celsiusToFahrenheit(const float deg);
+
44 float fahrenheitToCelsius(const float deg);
+
47 namespace irutils {
+
48  String addBoolToString(const bool value, const String label,
+
49  const bool precomma = true);
+
50  String addIntToString(const uint16_t value, const String label,
+
51  const bool precomma = true);
+
52  String modelToStr(const decode_type_t protocol, const int16_t model);
+
53  String addModelToString(const decode_type_t protocol, const int16_t model,
+
54  const bool precomma = true);
+
55  String addLabeledString(const String value, const String label,
+
56  const bool precomma = true);
+
57  String addTempToString(const uint16_t degrees, const bool celsius = true,
+
58  const bool precomma = true);
+
59  String addModeToString(const uint8_t mode, const uint8_t automatic,
+
60  const uint8_t cool, const uint8_t heat,
+
61  const uint8_t dry, const uint8_t fan);
+
62  String addFanToString(const uint8_t speed, const uint8_t high,
+
63  const uint8_t low, const uint8_t automatic,
+
64  const uint8_t quiet, const uint8_t medium);
+
65  String addDayToString(const uint8_t day_of_week, const int8_t offset = 0,
+
66  const bool precomma = true);
+
67  String htmlEscape(const String unescaped);
+
68  String msToString(uint32_t const msecs);
+
69  String minsToString(const uint16_t mins);
+
70  uint8_t sumNibbles(const uint8_t * const start, const uint16_t length,
+
71  const uint8_t init = 0);
+
72  uint8_t sumNibbles(const uint64_t data, const uint8_t count = 16,
+
73  const uint8_t init = 0, const bool nibbleonly = true);
+
74  uint8_t bcdToUint8(const uint8_t bcd);
+
75  uint8_t uint8ToBcd(const uint8_t integer);
+
76  bool getBit(const uint64_t data, const uint8_t position,
+
77  const uint8_t size = 64);
+
78  bool getBit(const uint8_t data, const uint8_t position);
+
79 #define GETBIT8(a, b) (a & ((uint8_t)1 << b))
+
80 #define GETBIT16(a, b) (a & ((uint16_t)1 << b))
+
81 #define GETBIT32(a, b) (a & ((uint32_t)1 << b))
+
82 #define GETBIT64(a, b) (a & ((uint64_t)1 << b))
+
83 #define GETBITS8(data, offset, size) \
+
84  (((data) & (((uint8_t)UINT8_MAX >> (8 - (size))) << (offset))) >> (offset))
+
85 #define GETBITS16(data, offset, size) \
+
86  (((data) & (((uint16_t)UINT16_MAX >> (16 - (size))) << (offset))) >> \
+
87  (offset))
+
88 #define GETBITS32(data, offset, size) \
+
89  (((data) & (((uint32_t)UINT32_MAX >> (32 - (size))) << (offset))) >> \
+
90  (offset))
+
91 #define GETBITS64(data, offset, size) \
+
92  (((data) & (((uint64_t)UINT64_MAX >> (64 - (size))) << (offset))) >> \
+
93  (offset))
+
94  uint64_t setBit(const uint64_t data, const uint8_t position,
+
95  const bool on = true, const uint8_t size = 64);
+
96  uint8_t setBit(const uint8_t data, const uint8_t position,
+
97  const bool on = true);
+
98  void setBit(uint8_t * const data, const uint8_t position,
+
99  const bool on = true);
+
100  void setBit(uint32_t * const data, const uint8_t position,
+
101  const bool on = true);
+
102  void setBit(uint64_t * const data, const uint8_t position,
+
103  const bool on = true);
+
104  void setBits(uint8_t * const dst, const uint8_t offset, const uint8_t nbits,
+
105  const uint8_t data);
+
106  void setBits(uint32_t * const dst, const uint8_t offset, const uint8_t nbits,
+
107  const uint32_t data);
+
108  void setBits(uint64_t * const dst, const uint8_t offset, const uint8_t nbits,
+
109  const uint64_t data);
+
110 } // namespace irutils
+
111 #endif // IRUTILS_H_
+
+
String addTempToString(const uint16_t degrees, const bool celsius, const bool precomma)
Create a String of human output for a given temperature. e.g. "Temp: 25C".
Definition: IRutils.cpp:577
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
String addDayToString(const uint8_t day_of_week, const int8_t offset, const bool precomma)
Create a String of the 3-letter day of the week from a numerical day of the week. e....
Definition: IRutils.cpp:616
+
uint16_t * resultToRawArray(const decode_results *const decode)
Convert a decode_results into an array suitable for sendRaw().
Definition: IRutils.cpp:351
+
void setBits(uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)
Alter an uint8_t value by overwriting an arbitary given number of bits.
Definition: IRutils.cpp:873
+
String resultToSourceCode(const decode_results *const results)
Return a String containing the key values of a decode_results structure in a C/C++ code style format.
Definition: IRutils.cpp:193
+
Results returned from the decoder.
Definition: IRrecv.h:92
+
uint16_t getCorrectedRawLength(const decode_results *const results)
Return the corrected length of a 'raw' format array structure after over-large values are converted i...
Definition: IRutils.cpp:179
+
String addModelToString(const decode_type_t protocol, const int16_t model, const bool precomma)
Create a String of human output for a given protocol model number. e.g. "Model: JKE".
Definition: IRutils.cpp:562
+
uint16_t countBits(const uint8_t *const start, const uint16_t length, const bool ones=true, const uint16_t init=0)
Count the number of bits of a certain type in an array.
Definition: IRutils.cpp:402
+
String msToString(uint32_t const msecs)
Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds...
Definition: IRutils.cpp:692
+
String addModeToString(const uint8_t mode, const uint8_t automatic, const uint8_t cool, const uint8_t heat, const uint8_t dry, const uint8_t fan)
Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)".
Definition: IRutils.cpp:593
+
String resultToHumanReadableBasic(const decode_results *const results)
Dump out the decode_results structure into a human readable format.
Definition: IRutils.cpp:324
+
String resultToTimingInfo(const decode_results *const results)
Dump out the decode_results structure.
Definition: IRutils.cpp:274
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kNibbleSize
Definition: IRutils.h:17
+
String modelToStr(const decode_type_t protocol, const int16_t model)
Generate the model string for a given Protocol/Model pair.
Definition: IRutils.cpp:498
+
const uint8_t kLowNibble
Definition: IRutils.h:18
+ +
uint8_t uint8ToBcd(const uint8_t integer)
Convert an Integer into a byte of Binary Coded Decimal(BCD).
Definition: IRutils.cpp:778
+
decode_type_t strToDecodeType(const char *str)
Convert a C-style string to a decode_type_t.
Definition: IRutils.cpp:83
+
const uint8_t kHighNibble
Definition: IRutils.h:19
+
uint8_t sumNibbles(const uint8_t *const start, const uint16_t length, const uint8_t init)
Sum all the nibbles together in a series of bytes.
Definition: IRutils.cpp:743
+
String uint64ToString(uint64_t input, uint8_t base=10)
Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle...
Definition: IRutils.cpp:44
+
float celsiusToFahrenheit(const float deg)
Convert degrees Celsius to degrees Fahrenheit.
Definition: IRutils.cpp:450
+
String addIntToString(const uint16_t value, const String label, const bool precomma)
Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23".
Definition: IRutils.cpp:489
+
uint8_t xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0)
Calculate a rolling XOR of all the bytes of an array.
Definition: IRutils.cpp:388
+
const uint8_t kModeBitsSize
Definition: IRutils.h:20
+
bool getBit(const uint64_t data, const uint8_t position, const uint8_t size)
Return the value of positionth bit of an Integer.
Definition: IRutils.cpp:788
+
float fahrenheitToCelsius(const float deg)
Convert degrees Fahrenheit to degrees Celsius.
Definition: IRutils.cpp:453
+ +
uint8_t sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0)
Sum all the bytes of an array and return the least significant 8-bits of the result.
Definition: IRutils.cpp:375
+
String typeToString(const decode_type_t protocol, const bool isRepeat=false)
Convert a protocol type (enum etc) to a human readable string.
Definition: IRutils.cpp:105
+
String addFanToString(const uint8_t speed, const uint8_t high, const uint8_t low, const uint8_t automatic, const uint8_t quiet, const uint8_t medium)
Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)".
Definition: IRutils.cpp:642
+
String resultToHexidecimal(const decode_results *const result)
Convert the decode_results structure's value/state to simple hexadecimal.
Definition: IRutils.cpp:304
+
String addBoolToString(const bool value, const String label, const bool precomma)
Create a String with a colon separated flag suitable for Humans. e.g. "Power: On".
Definition: IRutils.cpp:477
+
String minsToString(const uint16_t mins)
Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59".
Definition: IRutils.cpp:728
+
uint8_t bcdToUint8(const uint8_t bcd)
Convert a byte of Binary Coded Decimal(BCD) into an Integer.
Definition: IRutils.cpp:770
+
Namespace for covering common functions & procedures for advancd protocol handlers.
Definition: IRutils.cpp:455
+
uint64_t reverseBits(uint64_t input, uint16_t nbits)
Reverse the order of the requested least significant nr. of bits.
Definition: IRutils.cpp:24
+
String htmlEscape(const String unescaped)
Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS.
Definition: IRutils.cpp:660
+
bool hasACState(const decode_type_t protocol)
Does the given protocol use a complex state as part of the decode?
Definition: IRutils.cpp:130
+
uint64_t setBit(const uint64_t data, const uint8_t position, const bool on, const uint8_t size)
Return the value of an Integer with the positionth bit changed.
Definition: IRutils.cpp:808
+
void serialPrintUint64(uint64_t input, uint8_t base=10)
Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long long...
Definition: IRutils.cpp:75
+
String addLabeledString(const String value, const String label, const bool precomma)
Create a String with a colon separated "label: value" pair suitable for Humans.
Definition: IRutils.cpp:462
+
uint64_t invertBits(const uint64_t data, const uint16_t nbits)
Invert/Flip the bits in an Integer.
Definition: IRutils.cpp:439
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/README_8md.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/README_8md.html new file mode 100644 index 000000000..cf3677096 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/README_8md.html @@ -0,0 +1,76 @@ + + + + + + + +IRremoteESP8266: src/locale/README.md File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
src/locale/README.md File Reference
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/annotated.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/annotated.html new file mode 100644 index 000000000..b4f7fbce8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/annotated.html @@ -0,0 +1,134 @@ + + + + + + + +IRremoteESP8266: Class List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
[detail level 12]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 NstdAcEnumerators and Structures for the Common A/C API
 Cstate_tStructure to hold a common A/C state
 Cdecode_resultsResults returned from the decoder
 CIRac
 CIRAmcorAcClass for handling detailed Amcor A/C messages
 CIRArgoACClass for handling detailed Argo A/C messages
 CIRCarrierAc64Class for handling detailed Carrier 64 bit A/C messages
 CIRCoolixACClass for handling detailed Coolix A/C messages
 CIRCoronaAcClass for handling detailed Corona A/C messages
 CIRDaikin128Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena
 CIRDaikin152Class for handling detailed Daikin 152-bit A/C messages
 CIRDaikin160Class for handling detailed Daikin 160-bit A/C messages
 CIRDaikin176Class for handling detailed Daikin 176-bit A/C messages
 CIRDaikin2Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99
 CIRDaikin216Class for handling detailed Daikin 216-bit A/C messages
 CIRDaikin64Class for handling detailed Daikin 64-bit A/C messages
 CIRDaikinESPClass for handling detailed Daikin 280-bit A/C messages
 CIRDelonghiAcClass for handling detailed Delonghi A/C messages
 CIRElectraAcClass for handling detailed Electra A/C messages
 CIRFujitsuACClass for handling detailed Fujitsu A/C messages
 CIRGoodweatherAcClass for handling detailed Goodweather A/C messages
 CIRGreeACClass for handling detailed Gree A/C messages
 CIRHaierACClass for handling detailed Haier A/C messages
 CIRHaierACYRW02Class for handling detailed Haier ACYRW02 A/C messages
 CIRHitachiAcClass for handling detailed Hitachi 224-bit A/C messages
 CIRHitachiAc1Class for handling detailed Hitachi 104-bit A/C messages
 CIRHitachiAc3Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages
 CIRHitachiAc344Class for handling detailed Hitachi 344-bit A/C messages
 CIRHitachiAc424Class for handling detailed Hitachi 53-byte/424-bit A/C messages
 CIRKelvinatorACClass for handling detailed Kelvinator A/C messages
 CIRLgAcClass for handling detailed LG A/C messages
 CIRMideaACClass for handling detailed Midea A/C messages
 CIRMitsubishi112
 CIRMitsubishi136Class for handling detailed Mitsubishi 136-bit A/C messages
 CIRMitsubishiACClass for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control
 CIRMitsubishiHeavy152AcClass for handling detailed Mitsubishi Heavy 152-bit A/C messages
 CIRMitsubishiHeavy88AcClass for handling detailed Mitsubishi Heavy 88-bit A/C messages
 CIRNeoclimaAcClass for handling detailed Neoclima A/C messages
 CIRPanasonicAcClass for handling detailed Panasonic A/C messages
 Cirparams_tInformation for the interrupt handler
 CIRrecvClass for receiving IR messages
 CIRSamsungAcClass for handling detailed Samsung A/C messages
 CIRsendClass for sending all basic IR protocols
 CIRSharpAcClass for handling detailed Sharp A/C messages
 CIRTcl112AcClass for handling detailed TCL A/C messages
 CIRTecoAcClass for handling detailed Teco A/C messages
 CIRtimerThis class performs a simple timer in useconds since instantiated
 CIRToshibaACClass for handling detailed Toshiba A/C messages
 CIRTrotecESPClass for handling detailed Trotec A/C messages
 CIRVestelAcClass for handling detailed Vestel A/C messages
 CIRWhirlpoolAcClass for handling detailed Whirlpool A/C messages
 CmagiquestMagiQuest packet is both Wand ID and magnitude of swish and flick
 Cmatch_result_tResults from a data match
 CTimerMsThis class performs a simple timer in milli-seoncds since instantiated
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bc_s.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bdwn.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRAmcorAc Member List
+
+
+ +

This is the complete list of members for IRAmcorAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRAmcorAcprivate
begin()IRAmcorAc
calcChecksum(const uint8_t state[], const uint16_t length=kAmcorStateLength)IRAmcorAcstatic
calibrate(void)IRAmcorAcinline
checksum(void)IRAmcorAcprivate
convertFan(const stdAc::fanspeed_t speed)IRAmcorAc
convertMode(const stdAc::opmode_t mode)IRAmcorAc
getFan()IRAmcorAc
getMax(void)IRAmcorAc
getMode()IRAmcorAc
getPower()IRAmcorAc
getRaw()IRAmcorAc
getTemp()IRAmcorAc
IRAmcorAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRAmcorAcexplicit
off()IRAmcorAc
on()IRAmcorAc
remote_stateIRAmcorAcprivate
send(const uint16_t repeat=kAmcorDefaultRepeat)IRAmcorAc
setFan(const uint8_t speed)IRAmcorAc
setMax(const bool on)IRAmcorAc
setMode(const uint8_t mode)IRAmcorAc
setPower(const bool state)IRAmcorAc
setRaw(const uint8_t state[])IRAmcorAc
setTemp(const uint8_t temp)IRAmcorAc
stateReset()IRAmcorAc
toCommon(void)IRAmcorAc
toCommonFanSpeed(const uint8_t speed)IRAmcorAcstatic
toCommonMode(const uint8_t mode)IRAmcorAcstatic
toString()IRAmcorAc
validChecksum(const uint8_t state[], const uint16_t length=kAmcorStateLength)IRAmcorAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc.html new file mode 100644 index 000000000..8d4caf51c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc.html @@ -0,0 +1,997 @@ + + + + + + + +IRremoteESP8266: IRAmcorAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Amcor A/C messages. + More...

+ +

#include <ir_Amcor.h>

+
+Collaboration diagram for IRAmcorAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRAmcorAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset ()
 Reset the internals of the object to a known good state. More...
 
void send (const uint16_t repeat=kAmcorDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPower (const bool state)
 Set the internal state to have the desired power. More...
 
bool getPower ()
 Get the power setting from the internal state. More...
 
void on ()
 Set the internal state to have the power on. More...
 
void off ()
 Set the internal state to have the power off. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setMax (const bool on)
 Control the current Maximum Cooling or Heating setting. (i.e. Turbo) More...
 
bool getMax (void)
 Is the Maximum Cooling or Heating setting (i.e. Turbo) setting on? More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the desired operation mode. More...
 
uint8_t getMode ()
 Get the current operation mode setting. More...
 
uint8_t * getRaw ()
 Get the raw state of the object, suitable to be sent with the appropriate IRsend object method. More...
 
void setRaw (const uint8_t state[])
 Set the raw state of the object. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kAmcorStateLength)
 Calculate the checksum for the supplied state. More...
 
static bool validChecksum (const uint8_t state[], const uint16_t length=kAmcorStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Update the checksum value for the internal state. More...
 
+ + + + + +

+Private Attributes

IRsend _irsend
 
uint8_t remote_state [kAmcorStateLength]
 
+

Detailed Description

+

Class for handling detailed Amcor A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRAmcorAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRAmcorAc::IRAmcorAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRAmcorAc::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRAmcorAc::calcChecksum (const uint8_t state[],
const uint16_t length = kAmcorStateLength 
)
+
+static
+
+ +

Calculate the checksum for the supplied state.

+
Parameters
+ + + +
[in]stateThe source state to generate the checksum from.
[in]lengthLength of the supplied state to checksum.
+
+
+
Returns
The checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRAmcorAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRAmcorAc::checksum (void )
+
+private
+
+ +

Update the checksum value for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRAmcorAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRAmcorAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRAmcorAc::getFan ()
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMax()

+ +
+
+ + + + + + + + +
bool IRAmcorAc::getMax (void )
+
+ +

Is the Maximum Cooling or Heating setting (i.e. Turbo) setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRAmcorAc::getMode ()
+
+ +

Get the current operation mode setting.

+
Returns
The current operation mode.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRAmcorAc::getPower ()
+
+ +

Get the power setting from the internal state.

+
Returns
A boolean indicating the power setting.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRAmcorAc::getRaw ()
+
+ +

Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.

+
Returns
A PTR to the internal state.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRAmcorAc::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
Get current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRAmcorAc::off ()
+
+ +

Set the internal state to have the power off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRAmcorAc::on ()
+
+ +

Set the internal state to have the power on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRAmcorAc::send (const uint16_t repeat = kAmcorDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMax()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setMax (const bool on)
+
+ +

Control the current Maximum Cooling or Heating setting. (i.e. Turbo)

+
Note
Only allowed in Cool or Heat mode.
+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setMode (const uint8_t mode)
+
+ +

Set the desired operation mode.

+
Parameters
+ + +
[in]modeThe desired operation mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setPower (const bool on)
+
+ +

Set the internal state to have the desired power.

+
Parameters
+ + +
[in]onThe desired power state.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setRaw (const uint8_t state[])
+
+ +

Set the raw state of the object.

+
Parameters
+ + +
[in]stateThe raw state from the native IR message.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRAmcorAc::stateReset ()
+
+ +

Reset the internals of the object to a known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRAmcorAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRAmcorAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRAmcorAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRAmcorAc::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRAmcorAc::validChecksum (const uint8_t state[],
const uint16_t length = kAmcorStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe size of the state.
+
+
+
Returns
A boolean indicating if it's checksum is valid.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRAmcorAc::_irsend
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRAmcorAc::remote_state[kAmcorStateLength]
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.map new file mode 100644 index 000000000..4cebbf9a2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 new file mode 100644 index 000000000..7fde870f1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 @@ -0,0 +1 @@ +163192504ac8319807adb950a6186ac0 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..484d0b2520154ea6fff48d180b12ea8e0057cffc GIT binary patch literal 3009 zcmZXW2Q*yU8pns|y(L02LJC(z9p=esiC_p5L??O>Wn5(pqZ5Qgxk^SEB~cSS21yK& z7{*mb8H6Ev?=_<5oxHp5dhe~f&e~_MbJqUO`PR4p-~YGc3?9JQSp-=?AP~Ebw#GwX zMgk*@i2=CJFX)kgiNQe^t^xY_>w48xk_rN`qIERx8V6*r=OFd?h6Tg(=;@M^>?+bs zY16w9vQTbWjp_u`{fYX%NO2zBvBIdqlrzv%B=FI%dL@j#Wzq7^vAx#m z^z@YP!UY~M7-4RHad~+;TP4WU>XY3U+KJF(({Sa+uGiR{R~B7%*^X#kL6%ll zG#L<=L^Nb}b+zlIgxM2!_ksE=LPC`x9BgcKc3xh8Bqnl1MngNwV1ie!TnP*c;#MC)0Ex_g z`1~0pnyPc$^F$uzGU}&ccrJ|aJs&}kP9!OZNpAqc6aN=#Ke#)B%n}iyHHSkWF&21V4#d( zLgV2APHLo!Ky)mkDYt17e9_jjzdnXJ*=}cMWxXaTnE)hS<2|c|ULV!;@{;j76?NSB z_OY<2h+9agXJx3YgG|05ENrLlXJTyJH#w>A;c*L4%-r0ZqVMnqJKXxRVUlwcm(iA% zhOF#=6n|Yq=WqFM-*m0Fk3fzbPl|bu*qMaK#4x};Jt>crAm?&8PR`uCt=K9R892b@ zE1ssOMRegv*QOP$pOqK}}B zNX7Thnyuv5!b^0u;H?Q!ibSD6>G9eEl8J3-Voc+{G?@~Vz}n8pRd3}PiR=q$%%d4l z_(8v*QJ9WinB?zIsOSF#vvikkP!=*1Zj!%OM?JfBtk!b#N#)8VC-%c+%h8vKBHiSt z@uMojpMytR=6z>5*OJ-a7S#>zP0t1`Za{3+z%KhilT^|7wJV=wgT7Y~X^A#B$c{33 zLUTUH2Z+g+JtEyDjMiMqt6ob50%kk#MXs>Zc0IzTRQ(zA=kAQzW+)Ifd_qgze@|J}#Ixp%k-} zV$!&7kck=ESL?*3C2!x(tf`UneifmBtBsg(y` zT^mWK0+LmmlEQlH4TfJtt4NiB|mrkOF^ z*XJ~!>>`oKQS0$_BTvuDW7;NoV<{&4X24J;)Wm@DKTTjrx!zh<2$oo#F}Fx35WQeF zLtSD0TP1{hUd%Rr#fbC&=$cYEWaU&ox;;M&4iMxYpF&Ugt&z>$uTF*P^0 zXQu7N^2*9gYaDO61wO_C@9cV8Em272IW>4!-xdOaVCItHTie^22ES@@EBmXmvy+pd zfx+h@-Sm+U-q&n{x9MM8kfd;E`S~e`rpAfo2DErK0bBpj$f)kHx>{x(-`uQ5Lqmfm zCpI@Xqd^1$VS9Uf`t>s*LGGlE$1TId>9MgmD(6CX=D9oi`bk*P<*&*nym7weu$<_D zDpz}Z`*LdnmftowIplahIX5?vD{^JU4ZSvU7lo=dt$+JAZhh?im=2B&u$K`JXiuJ6 z74yft0Rf7pWkXV&CN3^wAiPWO*Us@Qe)p^1i6$j@ua3>ysVTb}Jf8Z|SByv`%0r>F zBVeZRgM)y0t=XuQzyvKI{sq7E!c$JwsWmE|jg8H~#6pzZ2g19Hy^FI+Y9tS+ zqg>{}-hjT&{re4$ay4&C1Qc^!0HmC@8Fr6VeL{3%Q+6PENG7wO`fL z>{PB=G>59l%F6Qb^Y6B>O80&Hrl+n>3)*bl<%o!gD7UP8Ze| + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRArgoAC Member List
+
+
+ +

This is the complete list of members for IRArgoAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRArgoACprivate
argoIRArgoACprivate
begin(void)IRArgoAC
calcChecksum(const uint8_t state[], const uint16_t length=kArgoStateLength)IRArgoACstatic
calibrate(void)IRArgoACinline
checksum(void)IRArgoACprivate
convertFan(const stdAc::fanspeed_t speed)IRArgoACstatic
convertMode(const stdAc::opmode_t mode)IRArgoACstatic
convertSwingV(const stdAc::swingv_t position)IRArgoACstatic
cool_modeIRArgoACprivate
flap_modeIRArgoACprivate
getFan(void)IRArgoAC
getFlap(void)IRArgoAC
getiFeel(void)IRArgoAC
getMax(void)IRArgoAC
getMode(void)IRArgoAC
getNight(void)IRArgoAC
getPower(void)IRArgoAC
getRaw(void)IRArgoAC
getRoomTemp(void)IRArgoAC
getTemp(void)IRArgoAC
heat_modeIRArgoACprivate
IRArgoAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRArgoACexplicit
off(void)IRArgoAC
on(void)IRArgoAC
send(const uint16_t repeat=kArgoDefaultRepeat)IRArgoAC
setFan(const uint8_t fan)IRArgoAC
setFlap(const uint8_t flap)IRArgoAC
setiFeel(const bool on)IRArgoAC
setMax(const bool on)IRArgoAC
setMode(const uint8_t mode)IRArgoAC
setNight(const bool on)IRArgoAC
setPower(const bool on)IRArgoAC
setRaw(const uint8_t state[])IRArgoAC
setRoomTemp(const uint8_t degrees)IRArgoAC
setTemp(const uint8_t degrees)IRArgoAC
setTime(void)IRArgoAC
stateReset(void)IRArgoACprivate
toCommon(void)IRArgoAC
toCommonFanSpeed(const uint8_t speed)IRArgoACstatic
toCommonMode(const uint8_t mode)IRArgoACstatic
toString()IRArgoAC
validChecksum(const uint8_t state[], const uint16_t length=kArgoStateLength)IRArgoACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC.html new file mode 100644 index 000000000..72244b98b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC.html @@ -0,0 +1,1381 @@ + + + + + + + +IRremoteESP8266: IRArgoAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Argo A/C messages. + More...

+ +

#include <ir_Argo.h>

+
+Collaboration diagram for IRArgoAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRArgoAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kArgoDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the internal state to have the power on. More...
 
void off (void)
 Set the internal state to have the power off. More...
 
void setPower (const bool on)
 Set the internal state to have the desired power. More...
 
bool getPower (void)
 Get the power setting from the internal state. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setFlap (const uint8_t flap)
 Set the flap position. i.e. Swing. More...
 
uint8_t getFlap (void)
 Get the flap position. i.e. Swing. More...
 
void setMode (const uint8_t mode)
 Set the desired operation mode. More...
 
uint8_t getMode (void)
 Get the current operation mode setting. More...
 
void setMax (const bool on)
 Control the current Max setting. (i.e. Turbo) More...
 
bool getMax (void)
 Is the Max (i.e. Turbo) setting on? More...
 
void setNight (const bool on)
 Turn on/off the Night mode. i.e. Sleep. More...
 
bool getNight (void)
 Get the status of Night mode. i.e. Sleep. More...
 
void setiFeel (const bool on)
 Turn on/off the iFeel mode. More...
 
bool getiFeel (void)
 Get the status of iFeel mode. More...
 
void setTime (void)
 Set the time for the A/C. More...
 
void setRoomTemp (const uint8_t degrees)
 Set the value for the current room temperature. More...
 
uint8_t getRoomTemp (void)
 Get the currently stored value for the room temperature setting. More...
 
uint8_t * getRaw (void)
 Get the raw state of the object, suitable to be sent with the appropriate IRsend object method. More...
 
void setRaw (const uint8_t state[])
 Set the raw state of the object. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kArgoStateLength)
 Verify the checksum is valid for a given state. More...
 
static bool validChecksum (const uint8_t state[], const uint16_t length=kArgoStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internals of the object to a known good state. More...
 
void checksum (void)
 Update the checksum for the internal state. More...
 
+ + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t argo [kArgoStateLength]
 
uint8_t flap_mode
 
uint8_t heat_mode
 
uint8_t cool_mode
 
+

Detailed Description

+

Class for handling detailed Argo A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRArgoAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRArgoAC::IRArgoAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRArgoAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRArgoAC::calcChecksum (const uint8_t state[],
const uint16_t length = kArgoStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe size of the state.
+
+
+
Returns
A boolean indicating if it's checksum is valid.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRArgoAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRArgoAC::checksum (void )
+
+private
+
+ +

Update the checksum for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRArgoAC::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRArgoAC::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRArgoAC::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getFlap()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getFlap (void )
+
+ +

Get the flap position. i.e. Swing.

+
Warning
Not yet working!
+
Returns
The current flap setting.
+ +
+
+ +

◆ getiFeel()

+ +
+
+ + + + + + + + +
bool IRArgoAC::getiFeel (void )
+
+ +

Get the status of iFeel mode.

+
Returns
true if on, false if off.
+ +
+
+ +

◆ getMax()

+ +
+
+ + + + + + + + +
bool IRArgoAC::getMax (void )
+
+ +

Is the Max (i.e. Turbo) setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getMode (void )
+
+ +

Get the current operation mode setting.

+
Returns
The current operation mode.
+ +
+
+ +

◆ getNight()

+ +
+
+ + + + + + + + +
bool IRArgoAC::getNight (void )
+
+ +

Get the status of Night mode. i.e. Sleep.

+
Returns
true if on, false if off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRArgoAC::getPower (void )
+
+ +

Get the power setting from the internal state.

+
Returns
A boolean indicating the power setting.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRArgoAC::getRaw (void )
+
+ +

Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.

+
Returns
A PTR to the internal state.
+ +
+
+ +

◆ getRoomTemp()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getRoomTemp (void )
+
+ +

Get the currently stored value for the room temperature setting.

+
Returns
The current setting for the room temp. in degrees celsius.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRArgoAC::off (void )
+
+ +

Set the internal state to have the power off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRArgoAC::on (void )
+
+ +

Set the internal state to have the power on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRArgoAC::send (const uint16_t repeat = kArgoDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRArgoAC::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+ +
+
+ +

◆ setFlap()

+ +
+
+ + + + + + + + +
void IRArgoAC::setFlap (const uint8_t flap)
+
+ +

Set the flap position. i.e. Swing.

+
Warning
Not yet working!
+
Parameters
+ + +
[in]flapThe desired setting.
+
+
+ +
+
+ +

◆ setiFeel()

+ +
+
+ + + + + + + + +
void IRArgoAC::setiFeel (const bool on)
+
+ +

Turn on/off the iFeel mode.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setMax()

+ +
+
+ + + + + + + + +
void IRArgoAC::setMax (const bool on)
+
+ +

Control the current Max setting. (i.e. Turbo)

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRArgoAC::setMode (const uint8_t mode)
+
+ +

Set the desired operation mode.

+
Parameters
+ + +
[in]modeThe desired operation mode.
+
+
+ +
+
+ +

◆ setNight()

+ +
+
+ + + + + + + + +
void IRArgoAC::setNight (const bool on)
+
+ +

Turn on/off the Night mode. i.e. Sleep.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRArgoAC::setPower (const bool on)
+
+ +

Set the internal state to have the desired power.

+
Parameters
+ + +
[in]onThe desired power state.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRArgoAC::setRaw (const uint8_t state[])
+
+ +

Set the raw state of the object.

+
Parameters
+ + +
[in]stateThe raw state from the native IR message.
+
+
+ +
+
+ +

◆ setRoomTemp()

+ +
+
+ + + + + + + + +
void IRArgoAC::setRoomTemp (const uint8_t degrees)
+
+ +

Set the value for the current room temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRArgoAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+
Note
Sending 0 equals +4
+ +
+
+ +

◆ setTime()

+ +
+
+ + + + + + + + +
void IRArgoAC::setTime (void )
+
+ +

Set the time for the A/C.

+
Warning
Not yet working!
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRArgoAC::stateReset (void )
+
+private
+
+ +

Reset the internals of the object to a known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRArgoAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRArgoAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRArgoAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRArgoAC::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRArgoAC::validChecksum (const uint8_t state[],
const uint16_t length = kArgoStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe size of the state.
+
+
+
Returns
A boolean indicating if it's checksum is valid.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRArgoAC::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ argo

+ +
+
+ + + + + +
+ + + + +
uint8_t IRArgoAC::argo[kArgoStateLength]
+
+private
+
+ +
+
+ +

◆ cool_mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRArgoAC::cool_mode
+
+private
+
+ +
+
+ +

◆ flap_mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRArgoAC::flap_mode
+
+private
+
+ +
+
+ +

◆ heat_mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRArgoAC::heat_mode
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.map new file mode 100644 index 000000000..d2a486ba8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.md5 new file mode 100644 index 000000000..e84f3b330 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.md5 @@ -0,0 +1 @@ +7d040225d2db5b4715532b7d4ba5268b \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..a7838e03d2748923e6be5065db7a353a8c9b0a2e GIT binary patch literal 3164 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64-members.html new file mode 100644 index 000000000..a681c9218 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64-members.html @@ -0,0 +1,117 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +

+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRCarrierAc64 Member List
+
+
+ +

This is the complete list of members for IRCarrierAc64, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_cancelOffTimer(void)IRCarrierAc64private
_cancelOnTimer(void)IRCarrierAc64private
_irsendIRCarrierAc64private
begin()IRCarrierAc64
calcChecksum(const uint64_t state)IRCarrierAc64static
calibrate(void)IRCarrierAc64inline
checksum(void)IRCarrierAc64private
convertFan(const stdAc::fanspeed_t speed)IRCarrierAc64
convertMode(const stdAc::opmode_t mode)IRCarrierAc64
getFan()IRCarrierAc64
getMode()IRCarrierAc64
getOffTimer(void)IRCarrierAc64
getOnTimer(void)IRCarrierAc64
getPower()IRCarrierAc64
getRaw()IRCarrierAc64
getSleep(void)IRCarrierAc64
getSwingV(void)IRCarrierAc64
getTemp()IRCarrierAc64
IRCarrierAc64(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRCarrierAc64explicit
off()IRCarrierAc64
on()IRCarrierAc64
remote_stateIRCarrierAc64private
send(const uint16_t repeat=kCarrierAc64MinRepeat)IRCarrierAc64
setFan(const uint8_t speed)IRCarrierAc64
setMode(const uint8_t mode)IRCarrierAc64
setOffTimer(const uint16_t nr_of_mins)IRCarrierAc64
setOnTimer(const uint16_t nr_of_mins)IRCarrierAc64
setPower(const bool on)IRCarrierAc64
setRaw(const uint64_t state)IRCarrierAc64
setSleep(const bool on)IRCarrierAc64
setSwingV(const bool on)IRCarrierAc64
setTemp(const uint8_t temp)IRCarrierAc64
stateReset()IRCarrierAc64
toCommon(void)IRCarrierAc64
toCommonFanSpeed(const uint8_t speed)IRCarrierAc64static
toCommonMode(const uint8_t mode)IRCarrierAc64static
toString()IRCarrierAc64
validChecksum(const uint64_t state)IRCarrierAc64static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64.html new file mode 100644 index 000000000..111037a52 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64.html @@ -0,0 +1,1206 @@ + + + + + + + +IRremoteESP8266: IRCarrierAc64 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Carrier 64 bit A/C messages. + More...

+ +

#include <ir_Carrier.h>

+
+Collaboration diagram for IRCarrierAc64:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRCarrierAc64 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kCarrierAc64MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower ()
 Get the value of the current power setting. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setTemp (const uint8_t temp)
 Set the temp in deg C. More...
 
uint8_t getTemp ()
 Get the current temperature from the internal state. More...
 
void setSwingV (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep mode of the A/C. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setOnTimer (const uint16_t nr_of_mins)
 Set the On Timer time. More...
 
uint16_t getOnTimer (void)
 Get the current On Timer time. More...
 
void setOffTimer (const uint16_t nr_of_mins)
 Set the Off Timer time. More...
 
uint16_t getOffTimer (void)
 Get the current Off Timer time. More...
 
uint64_t getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint64_t state)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a standard A/C mode into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the A/C state to it's common stdAc::state_t equivalent. More...
 
String toString ()
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode to it's common stdAc::opmode_t equivalent. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + +

+Private Member Functions

void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
void _cancelOnTimer (void)
 Clear the On Timer enable bit. More...
 
void _cancelOffTimer (void)
 Clear the Off Timer enable bit. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote_state
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Carrier 64 bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRCarrierAc64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRCarrierAc64::IRCarrierAc64 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _cancelOffTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCarrierAc64::_cancelOffTimer (void )
+
+private
+
+ +

Clear the Off Timer enable bit.

+ +
+
+ +

◆ _cancelOnTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCarrierAc64::_cancelOnTimer (void )
+
+private
+
+ +

Clear the On Timer enable bit.

+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRCarrierAc64::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRCarrierAc64::calcChecksum (const uint64_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
The 4-bit checksum stored in a uint_8.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRCarrierAc64::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCarrierAc64::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRCarrierAc64::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRCarrierAc64::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a standard A/C mode into its native mode.

+
Parameters
+ + +
[in]modeA stdAc::opmode_t to be converted to it's native equivalent.
+
+
+
Returns
The corresponding native mode.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRCarrierAc64::getFan ()
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRCarrierAc64::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRCarrierAc64::getOffTimer (void )
+
+ +

Get the current Off Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+
Note
The A/C protocol only supports one hour increments.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRCarrierAc64::getOnTimer (void )
+
+ +

Get the current On Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+
Note
The A/C protocol only supports one hour increments.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRCarrierAc64::getPower ()
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint64_t IRCarrierAc64::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRCarrierAc64::getSleep (void )
+
+ +

Get the Sleep mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRCarrierAc64::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRCarrierAc64::getTemp ()
+
+ +

Get the current temperature from the internal state.

+
Returns
The current temperature in Celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRCarrierAc64::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRCarrierAc64::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::send (const uint16_t repeat = kCarrierAc64MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setOffTimer (const uint16_t nr_of_mins)
+
+ +

Set the Off Timer time.

+
Parameters
+ + +
[in]nr_of_minsNumber of minutes to set the timer to. (< 60 is disable).
+
+
+
Note
The A/C protocol only supports one hour increments.
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setOnTimer (const uint16_t nr_of_mins)
+
+ +

Set the On Timer time.

+
Parameters
+ + +
[in]nr_of_minsNumber of minutes to set the timer to. (< 60 is disable).
+
+
+
Note
The A/C protocol only supports one hour increments.
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setRaw (const uint64_t state)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setSleep (const bool on)
+
+ +

Set the Sleep mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setSwingV (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setTemp (const uint8_t temp)
+
+ +

Set the temp in deg C.

+
Parameters
+ + +
[in]tempThe desired temperature in Celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRCarrierAc64::stateReset ()
+
+ +

Reset the internal state to a fixed known good state.

+
Note
The state is powered off.
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRCarrierAc64::toCommon (void )
+
+ +

Convert the A/C state to it's common stdAc::state_t equivalent.

+
Returns
A stdAc::state_t state.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRCarrierAc64::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRCarrierAc64::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode to it's common stdAc::opmode_t equivalent.

+
Parameters
+ + +
[in]modeA native operation mode to be converted.
+
+
+
Returns
The corresponding common stdAc::opmode_t mode.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRCarrierAc64::toString ()
+
+ +

Convert the internal state into a human readable string.

+
Returns
The current internal state expressed as a human readable String.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRCarrierAc64::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe array to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRCarrierAc64::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRCarrierAc64::remote_state
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.map new file mode 100644 index 000000000..d0c818960 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 new file mode 100644 index 000000000..fd7409742 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 @@ -0,0 +1 @@ +c88965083519dee20186a15bc2f69a8c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..72adeb220645a7fd55ba14e7ff519605fceedc3c GIT binary patch literal 3653 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 V%j5)Z@V^kEs;Hq*`1pC?{{WPlE;9fC literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC-members.html new file mode 100644 index 000000000..88e247857 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC-members.html @@ -0,0 +1,137 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRCoolixAC Member List
+
+
+ +

This is the complete list of members for IRCoolixAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRCoolixACprivate
begin()IRCoolixAC
calibrate(void)IRCoolixACinline
cleanFlagIRCoolixACprivate
clearSensorTemp()IRCoolixAC
convertFan(const stdAc::fanspeed_t speed)IRCoolixAC
convertMode(const stdAc::opmode_t mode)IRCoolixAC
getClean()IRCoolixAC
getFan()IRCoolixAC
getLed()IRCoolixAC
getMode()IRCoolixAC
getNormalState(void)IRCoolixACprivate
getPower()IRCoolixAC
getRaw()IRCoolixAC
getSensorTemp()IRCoolixAC
getSleep()IRCoolixAC
getSwing()IRCoolixAC
getTemp()IRCoolixAC
getTempRaw()IRCoolixACprivate
getTurbo()IRCoolixAC
getZoneFollow()IRCoolixAC
handleSpecialState(const uint32_t data)IRCoolixACprivate
IRCoolixAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRCoolixACexplicit
isSpecialState(void)IRCoolixACprivate
ledFlagIRCoolixACprivate
off()IRCoolixAC
on()IRCoolixAC
powerFlagIRCoolixACprivate
recoverSavedState(void)IRCoolixACprivate
remote_stateIRCoolixACprivate
saved_stateIRCoolixACprivate
send(const uint16_t repeat=kCoolixDefaultRepeat)IRCoolixAC
setClean()IRCoolixAC
setFan(const uint8_t speed, const bool modecheck=true)IRCoolixAC
setLed()IRCoolixAC
setMode(const uint8_t mode)IRCoolixAC
setPower(const bool state)IRCoolixAC
setRaw(const uint32_t new_code)IRCoolixAC
setSensorTemp(const uint8_t desired)IRCoolixAC
setSensorTempRaw(const uint8_t code)IRCoolixACprivate
setSleep()IRCoolixAC
setSwing()IRCoolixAC
setTemp(const uint8_t temp)IRCoolixAC
setTempRaw(const uint8_t code)IRCoolixACprivate
setTurbo()IRCoolixAC
setZoneFollow(const bool on)IRCoolixACprivate
sleepFlagIRCoolixACprivate
stateReset()IRCoolixAC
swingFlagIRCoolixACprivate
swingHFlagIRCoolixACprivate
swingVFlagIRCoolixACprivate
toCommon(const stdAc::state_t *prev=NULL)IRCoolixAC
toCommonFanSpeed(const uint8_t speed)IRCoolixACstatic
toCommonMode(const uint8_t mode)IRCoolixACstatic
toString()IRCoolixAC
turboFlagIRCoolixACprivate
updateSavedState(void)IRCoolixACprivate
zoneFollowFlagIRCoolixACprivate
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC.html new file mode 100644 index 000000000..75343d576 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC.html @@ -0,0 +1,1710 @@ + + + + + + + +IRremoteESP8266: IRCoolixAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Coolix A/C messages. + More...

+ +

#include <ir_Coolix.h>

+
+Collaboration diagram for IRCoolixAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRCoolixAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kCoolixDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setPower (const bool state)
 Change the power setting. More...
 
bool getPower ()
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setSensorTemp (const uint8_t desired)
 Set the sensor temperature. More...
 
uint8_t getSensorTemp ()
 Get the sensor temperature setting. More...
 
void clearSensorTemp ()
 Clear the Sensor Temperature setting.. More...
 
void setFan (const uint8_t speed, const bool modecheck=true)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setSwing ()
 Toggle the Swing mode of the A/C. More...
 
bool getSwing ()
 Get the Swing setting of the A/C. More...
 
void setSleep ()
 Toggle the Sleep mode of the A/C. More...
 
bool getSleep ()
 Get the Sleep setting of the A/C. More...
 
void setTurbo ()
 Toggle the Turbo mode of the A/C. More...
 
bool getTurbo ()
 Get the Turbo setting of the A/C. More...
 
void setLed ()
 Toggle the Led (light) mode of the A/C. More...
 
bool getLed ()
 Get the Led (light) setting of the A/C. More...
 
void setClean ()
 Toggle the Clean mode of the A/C. More...
 
bool getClean ()
 Get the Clean setting of the A/C. More...
 
bool getZoneFollow ()
 Get the Zone Follow setting of the A/C. More...
 
uint32_t getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint32_t new_code)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a standard A/C mode into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (const stdAc::state_t *prev=NULL)
 Convert the A/C state to it's common stdAc::state_t equivalent. More...
 
String toString ()
 Convert the internal state into a human readable string. More...
 
+ + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode to it's common stdAc::opmode_t equivalent. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

void setTempRaw (const uint8_t code)
 Set the raw (native) temperature value. More...
 
uint8_t getTempRaw ()
 Get the raw (native) temperature value. More...
 
void setSensorTempRaw (const uint8_t code)
 Set the raw (native) sensor temperature value. More...
 
void setZoneFollow (const bool on)
 Change the Zone Follow setting. More...
 
bool isSpecialState (void)
 Is the current state is a special state? More...
 
bool handleSpecialState (const uint32_t data)
 Adjust any internal settings based on the type of special state we are supplied. Does nothing if it isn't a special state. More...
 
void updateSavedState (void)
 Backup the current internal state as long as it isn't a special state. More...
 
void recoverSavedState (void)
 Restore the current internal state from backup as long as it isn't a special state. More...
 
uint32_t getNormalState (void)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
bool powerFlag
 
bool turboFlag
 
bool ledFlag
 
bool cleanFlag
 
bool sleepFlag
 
bool zoneFollowFlag
 
bool swingFlag
 
bool swingHFlag
 
bool swingVFlag
 
uint32_t remote_state
 The state of the IR remote in IR code form. More...
 
uint32_t saved_state
 Copy of the state if we required a special mode. More...
 
+

Detailed Description

+

Class for handling detailed Coolix A/C messages.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/484
+

Constructor & Destructor Documentation

+ +

◆ IRCoolixAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRCoolixAC::IRCoolixAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRCoolixAC::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRCoolixAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ clearSensorTemp()

+ +
+
+ + + + + + + +
void IRCoolixAC::clearSensorTemp ()
+
+ +

Clear the Sensor Temperature setting..

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRCoolixAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRCoolixAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a standard A/C mode into its native mode.

+
Parameters
+ + +
[in]modeA stdAc::opmode_t to be converted to it's native equivalent.
+
+
+
Returns
The corresponding native mode.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getClean ()
+
+ +

Get the Clean setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRCoolixAC::getFan ()
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getLed()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getLed ()
+
+ +

Get the Led (light) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRCoolixAC::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getNormalState()

+ +
+
+ + + + + +
+ + + + + + + + +
uint32_t IRCoolixAC::getNormalState (void )
+
+private
+
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getPower ()
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint32_t IRCoolixAC::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSensorTemp()

+ +
+
+ + + + + + + +
uint8_t IRCoolixAC::getSensorTemp ()
+
+ +

Get the sensor temperature setting.

+
Returns
The current setting for sensor temp. in degrees celsius.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getSleep ()
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getSwing ()
+
+ +

Get the Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRCoolixAC::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTempRaw()

+ +
+
+ + + + + +
+ + + + + + + +
uint8_t IRCoolixAC::getTempRaw ()
+
+private
+
+ +

Get the raw (native) temperature value.

+
Returns
The native temperature value.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getTurbo ()
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getZoneFollow()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getZoneFollow ()
+
+ +

Get the Zone Follow setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ handleSpecialState()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRCoolixAC::handleSpecialState (const uint32_t data)
+
+private
+
+ +

Adjust any internal settings based on the type of special state we are supplied. Does nothing if it isn't a special state.

+
Parameters
+ + +
[in]dataThe state we need to act upon.
+
+
+
Note
Special state means commands that are not affecting Temperature/Mode/Fan
+
Returns
true, if it is a special state. false if it isn't.
+ +
+
+ +

◆ isSpecialState()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRCoolixAC::isSpecialState (void )
+
+private
+
+ +

Is the current state is a special state?

+
Returns
true, if it is. false if it isn't.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRCoolixAC::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRCoolixAC::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ recoverSavedState()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::recoverSavedState (void )
+
+private
+
+ +

Restore the current internal state from backup as long as it isn't a special state.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRCoolixAC::send (const uint16_t repeat = kCoolixDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + +
void IRCoolixAC::setClean ()
+
+ +

Toggle the Clean mode of the A/C.

+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRCoolixAC::setFan (const uint8_t speed,
const bool modecheck = true 
)
+
+ +

Set the speed of the fan.

+
Parameters
+ + + +
[in]speedThe desired setting.
[in]modecheckDo we enforce any mode limitations before setting?
+
+
+ +
+
+ +

◆ setLed()

+ +
+
+ + + + + + + +
void IRCoolixAC::setLed ()
+
+ +

Toggle the Led (light) mode of the A/C.

+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setRaw (const uint32_t new_code)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSensorTemp()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setSensorTemp (const uint8_t desired)
+
+ +

Set the sensor temperature.

+
Parameters
+ + +
[in]desiredThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setSensorTempRaw()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::setSensorTempRaw (const uint8_t code)
+
+private
+
+ +

Set the raw (native) sensor temperature value.

+
Note
Bypasses any checks or additional actions.
+
Parameters
+ + +
[in]codeThe desired native sensor temperature.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + +
void IRCoolixAC::setSleep ()
+
+ +

Toggle the Sleep mode of the A/C.

+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + +
void IRCoolixAC::setSwing ()
+
+ +

Toggle the Swing mode of the A/C.

+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setTemp (const uint8_t desired)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]desiredThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTempRaw()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::setTempRaw (const uint8_t code)
+
+private
+
+ +

Set the raw (native) temperature value.

+
Note
Bypasses any checks.
+
Parameters
+ + +
[in]codeThe desired native temperature.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + +
void IRCoolixAC::setTurbo ()
+
+ +

Toggle the Turbo mode of the A/C.

+ +
+
+ +

◆ setZoneFollow()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::setZoneFollow (const bool on)
+
+private
+
+ +

Change the Zone Follow setting.

+
Note
Internal use only.
+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRCoolixAC::stateReset ()
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRCoolixAC::toCommon (const stdAc::state_tprev = NULL)
+
+ +

Convert the A/C state to it's common stdAc::state_t equivalent.

+
Parameters
+ + +
[in]prevPtr to the previous state if required.
+
+
+
Returns
A stdAc::state_t state.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRCoolixAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRCoolixAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode to it's common stdAc::opmode_t equivalent.

+
Parameters
+ + +
[in]modeA native operation mode to be converted.
+
+
+
Returns
The corresponding common stdAc::opmode_t mode.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRCoolixAC::toString ()
+
+ +

Convert the internal state into a human readable string.

+
Returns
The current internal state expressed as a human readable String.
+ +
+
+ +

◆ updateSavedState()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::updateSavedState (void )
+
+private
+
+ +

Backup the current internal state as long as it isn't a special state.

+
Note
: Must be called before every special state to make sure the remote_state is safe
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRCoolixAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ cleanFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::cleanFlag
+
+private
+
+ +
+
+ +

◆ ledFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::ledFlag
+
+private
+
+ +
+
+ +

◆ powerFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::powerFlag
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint32_t IRCoolixAC::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+ +

◆ saved_state

+ +
+
+ + + + + +
+ + + + +
uint32_t IRCoolixAC::saved_state
+
+private
+
+ +

Copy of the state if we required a special mode.

+ +
+
+ +

◆ sleepFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::sleepFlag
+
+private
+
+ +
+
+ +

◆ swingFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::swingFlag
+
+private
+
+ +
+
+ +

◆ swingHFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::swingHFlag
+
+private
+
+ +
+
+ +

◆ swingVFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::swingVFlag
+
+private
+
+ +
+
+ +

◆ turboFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::turboFlag
+
+private
+
+ +
+
+ +

◆ zoneFollowFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::zoneFollowFlag
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.map new file mode 100644 index 000000000..74e59be41 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 new file mode 100644 index 000000000..eb300fb90 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 @@ -0,0 +1 @@ +4ccbb54c1327fe4f53812f4cc284a8f1 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..76fd97accf66c1cc1bd189534eedf6d44c1c43dc GIT binary patch literal 3102 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc-members.html new file mode 100644 index 000000000..d6f9bac48 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc-members.html @@ -0,0 +1,120 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +

+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRCoronaAc Member List
+
+
+ +

This is the complete list of members for IRCoronaAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_getTimer(const uint8_t section)IRCoronaAcprivate
_irsendIRCoronaAcprivate
_setPower(const bool on)IRCoronaAcprivate
_setTimer(const uint8_t section, const uint16_t nr_of_mins)IRCoronaAcprivate
begin()IRCoronaAc
calibrate(void)IRCoronaAcinline
checksum(uint8_t *data)IRCoronaAcprivatestatic
convertFan(const stdAc::fanspeed_t speed)IRCoronaAc
convertMode(const stdAc::opmode_t mode)IRCoronaAc
getEcono(void)IRCoronaAc
getFan()IRCoronaAc
getMode()IRCoronaAc
getOffTimer(void)IRCoronaAc
getOnTimer(void)IRCoronaAc
getPower()IRCoronaAc
getPowerButton()IRCoronaAc
getRaw()IRCoronaAc
getSectionByte(const uint8_t section)IRCoronaAcprivatestatic
getSwingVToggle(void)IRCoronaAc
getTemp()IRCoronaAc
IRCoronaAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRCoronaAcexplicit
off()IRCoronaAc
on()IRCoronaAc
remote_stateIRCoronaAcprivate
send(const uint16_t repeat=kNoRepeat)IRCoronaAc
setEcono(const bool on)IRCoronaAc
setFan(const uint8_t speed)IRCoronaAc
setMode(const uint8_t mode)IRCoronaAc
setOffTimer(const uint16_t nr_of_mins)IRCoronaAc
setOnTimer(const uint16_t nr_of_mins)IRCoronaAc
setPower(const bool on)IRCoronaAc
setPowerButton(const bool on)IRCoronaAcprivate
setRaw(const uint8_t new_code[], const uint16_t length=kCoronaAcStateLength)IRCoronaAc
setSwingVToggle(const bool on)IRCoronaAc
setTemp(const uint8_t temp)IRCoronaAc
stateReset()IRCoronaAc
toCommon()IRCoronaAc
toCommonFanSpeed(const uint8_t speed)IRCoronaAcstatic
toCommonMode(const uint8_t mode)IRCoronaAcstatic
toString()IRCoronaAc
validSection(const uint8_t state[], const uint16_t pos, const uint8_t section)IRCoronaAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc.html new file mode 100644 index 000000000..7a9e4513c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc.html @@ -0,0 +1,1360 @@ + + + + + + + +IRremoteESP8266: IRCoronaAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Corona A/C messages. + More...

+ +

#include <ir_Corona.h>

+
+Collaboration diagram for IRCoronaAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRCoronaAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor for handling detailed Corona A/C messages. More...
 
void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kNoRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPower (const bool on)
 Change the power setting. (in practice Standby, remote power) More...
 
bool getPower ()
 Get the current power setting. (in practice Standby, remote power) More...
 
bool getPowerButton ()
 Get the value of the current power button setting. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setTemp (const uint8_t temp)
 Set the temp in deg C. More...
 
uint8_t getTemp ()
 Get the current temperature from the internal state. More...
 
void setSwingVToggle (const bool on)
 Set the Vertical Swing toggle setting. More...
 
bool getSwingVToggle (void)
 Get the Vertical Swing toggle setting. More...
 
void setFan (const uint8_t speed)
 Set the operating speed of the A/C Fan. More...
 
uint8_t getFan ()
 Get the operating speed of the A/C Fan. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setEcono (const bool on)
 Change the powersave setting. More...
 
bool getEcono (void)
 Get the value of the current powersave setting. More...
 
void setOnTimer (const uint16_t nr_of_mins)
 Set the On Timer time. More...
 
uint16_t getOnTimer (void)
 Get the current On Timer time. More...
 
void setOffTimer (const uint16_t nr_of_mins)
 Set the Off Timer time. More...
 
uint16_t getOffTimer (void)
 Get the current Off Timer time. More...
 
uint8_t * getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kCoronaAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a standard A/C mode into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a standard A/C Fan speed into its native fan speed. More...
 
stdAc::state_t toCommon ()
 Convert the A/C state to it's common stdAc::state_t equivalent. More...
 
String toString ()
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validSection (const uint8_t state[], const uint16_t pos, const uint8_t section)
 Check that a CoronaAc Section part is valid with section byte and inverted. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode to it's common stdAc::opmode_t equivalent. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed to it's common equivalent. More...
 
+ + + + + + + + + + + + + +

+Private Member Functions

void setPowerButton (const bool on)
 Change the power button setting. More...
 
void _setPower (const bool on)
 Change the power setting. (in practice Standby, remote power) More...
 
void _setTimer (const uint8_t section, const uint16_t nr_of_mins)
 Set the Timer time. More...
 
uint16_t _getTimer (const uint8_t section)
 Get the current Timer time. More...
 
+ + + + + + + +

+Static Private Member Functions

static uint8_t getSectionByte (const uint8_t section)
 Get the byte that identifies the section. More...
 
static void checksum (uint8_t *data)
 Calculate and set the check values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kCoronaAcStateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Corona A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRCoronaAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRCoronaAc::IRCoronaAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor for handling detailed Corona A/C messages.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _getTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRCoronaAc::_getTimer (const uint8_t section)
+
+private
+
+ +

Get the current Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+
Note
The A/C protocol supports 2 second increments
+ +
+
+ +

◆ _setPower()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoronaAc::_setPower (const bool on)
+
+private
+
+ +

Change the power setting. (in practice Standby, remote power)

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ _setTimer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRCoronaAc::_setTimer (const uint8_t section,
const uint16_t nr_of_mins 
)
+
+private
+
+ +

Set the Timer time.

+
Parameters
+ + + +
[in]sectionindex of section, used for offset.
[in]nr_of_minsNumber of minutes to set the timer to. (non in range value is disable). Valid is from 1 minute to 12 hours
+
+
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRCoronaAc::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRCoronaAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoronaAc::checksum (uint8_t * data)
+
+staticprivate
+
+ +

Calculate and set the check values for the internal state.

+
Parameters
+ + +
[in,out]dataThe array to be modified
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRCoronaAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a standard A/C Fan speed into its native fan speed.

+
Parameters
+ + +
[in]speedThe desired stdAc::fanspeed_t fan speed
+
+
+
Returns
The given fan speed in native format
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRCoronaAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a standard A/C mode into its native mode.

+
Parameters
+ + +
[in]modeA stdAc::opmode_t mode to be converted to it's native equivalent
+
+
+
Returns
The corresponding native mode.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRCoronaAc::getEcono (void )
+
+ +

Get the value of the current powersave setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRCoronaAc::getFan ()
+
+ +

Get the operating speed of the A/C Fan.

+
Returns
The current operating fan speed setting
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRCoronaAc::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRCoronaAc::getOffTimer (void )
+
+ +

Get the current Off Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRCoronaAc::getOnTimer (void )
+
+ +

Get the current On Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRCoronaAc::getPower ()
+
+ +

Get the current power setting. (in practice Standby, remote power)

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerButton()

+ +
+
+ + + + + + + +
bool IRCoronaAc::getPowerButton ()
+
+ +

Get the value of the current power button setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRCoronaAc::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A Ptr to a valid code for this protocol based on the current internal state.
+
Note
To get stable AC state, if no timers, send once without PowerButton set, and once with
+ +
+
+ +

◆ getSectionByte()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRCoronaAc::getSectionByte (const uint8_t section)
+
+staticprivate
+
+ +

Get the byte that identifies the section.

+
Parameters
+ + +
[in]sectionIndex of the section 0-2, 3 and above is used as the special case for short message
+
+
+
Returns
The byte used for the section
+ +
+
+ +

◆ getSwingVToggle()

+ +
+
+ + + + + + + + +
bool IRCoronaAc::getSwingVToggle (void )
+
+ +

Get the Vertical Swing toggle setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRCoronaAc::getTemp ()
+
+ +

Get the current temperature from the internal state.

+
Returns
The current temperature in Celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRCoronaAc::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRCoronaAc::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRCoronaAc::send (const uint16_t repeat = kNoRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setEcono (const bool on)
+
+ +

Change the powersave setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setFan (const uint8_t speed)
+
+ +

Set the operating speed of the A/C Fan.

+
Parameters
+ + +
[in]speedThe desired fan speed
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setOffTimer (const uint16_t nr_of_mins)
+
+ +

Set the Off Timer time.

+
Parameters
+ + +
[in]nr_of_minsNumber of minutes to set the timer to. (0 or kCoronaAcTimerOff is disable).
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setOnTimer (const uint16_t nr_of_mins)
+
+ +

Set the On Timer time.

+
Parameters
+ + +
[in]nr_of_minsNumber of minutes to set the timer to. (0 or kCoronaAcTimerOff is disable).
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setPower (const bool on)
+
+ +

Change the power setting. (in practice Standby, remote power)

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
If changed, setPowerButton is also needed, unless timer is or was active
+ +
+
+ +

◆ setPowerButton()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoronaAc::setPowerButton (const bool on)
+
+private
+
+ +

Change the power button setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
this sets that the AC should set power, use setPower to define if the AC should end up as on or off When no timer is active, the below is a truth table With AC On, a command with setPower and setPowerButton gives nothing With AC On, a command with setPower but not setPowerButton is ok With AC Off, a command with setPower but not setPowerButton gives nothing With AC Off, a command with setPower and setPowerButton is ok
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRCoronaAc::setRaw (const uint8_t new_code[],
const uint16_t length = kCoronaAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid state for this protocol.
[in]lengthof the new_code array.
+
+
+ +
+
+ +

◆ setSwingVToggle()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setSwingVToggle (const bool on)
+
+ +

Set the Vertical Swing toggle setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
This is a button press, and not a state after sending it once you should turn it off
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setTemp (const uint8_t temp)
+
+ +

Set the temp in deg C.

+
Parameters
+ + +
[in]tempThe desired temperature in Celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRCoronaAc::stateReset ()
+
+ +

Reset the internal state to a fixed known good state.

+
Note
The state is powered off.
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + +
stdAc::state_t IRCoronaAc::toCommon ()
+
+ +

Convert the A/C state to it's common stdAc::state_t equivalent.

+
Returns
A stdAc::state_t state.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRCoronaAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed to it's common equivalent.

+
Parameters
+ + +
[in]speedThe desired native fan speed
+
+
+
Returns
The given fan speed in stdAc::fanspeed_t format
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRCoronaAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode to it's common stdAc::opmode_t equivalent.

+
Parameters
+ + +
[in]modeA native operation mode to be converted.
+
+
+
Returns
The corresponding common stdAc::opmode_t mode.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRCoronaAc::toString ()
+
+ +

Convert the internal state into a human readable string.

+
Returns
The current internal state expressed as a human readable String.
+ +
+
+ +

◆ validSection()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool IRCoronaAc::validSection (const uint8_t state[],
const uint16_t pos,
const uint8_t section 
)
+
+static
+
+ +

Check that a CoronaAc Section part is valid with section byte and inverted.

+
Parameters
+ + + + +
[in]stateAn array of bytes containing the section
[in]posWhere to start in the state array
[in]sectionWhich section to work with Used to get the section byte, and is validated against pos
+
+
+
Returns
true if section is valid, otherwise false
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRCoronaAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRCoronaAc::remote_state[kCoronaAcStateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.map new file mode 100644 index 000000000..7b9921ac4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 new file mode 100644 index 000000000..fe237b80f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 @@ -0,0 +1 @@ +2a8dc27b8683799250ee74acb6173d8f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..b8c35c4704f46851e6dd4b588cd30cd3d0cee59d GIT binary patch literal 3290 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 G^1lH5h+|*? literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128-members.html new file mode 100644 index 000000000..a77e405ef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128-members.html @@ -0,0 +1,132 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin128 Member List
+
+
+ +

This is the complete list of members for IRDaikin128, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin128private
begin()IRDaikin128
calcFirstChecksum(const uint8_t state[])IRDaikin128privatestatic
calcSecondChecksum(const uint8_t state[])IRDaikin128privatestatic
calibrate(void)IRDaikin128inline
checksum(void)IRDaikin128private
clearOnTimerFlag(void)IRDaikin128private
clearSleepTimerFlag(void)IRDaikin128private
convertFan(const stdAc::fanspeed_t speed)IRDaikin128static
convertMode(const stdAc::opmode_t mode)IRDaikin128static
getClock(void)IRDaikin128
getEcono(void)IRDaikin128
getFan(void)IRDaikin128
getLightToggle(void)IRDaikin128
getMode(void)IRDaikin128
getOffTimer(void)IRDaikin128
getOffTimerEnabled(void)IRDaikin128
getOnTimer(void)IRDaikin128
getOnTimerEnabled(void)IRDaikin128
getPowerful(void)IRDaikin128
getPowerToggle(void)IRDaikin128
getQuiet(void)IRDaikin128
getRaw(void)IRDaikin128
getSleep(void)IRDaikin128
getSwingVertical()IRDaikin128
getTemp(void)IRDaikin128
getTimer(const uint8_t *ptr)IRDaikin128privatestatic
IRDaikin128(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin128explicit
remote_stateIRDaikin128private
send(const uint16_t repeat=kDaikin128DefaultRepeat)IRDaikin128
setClock(const uint16_t mins_since_midnight)IRDaikin128
setEcono(const bool on)IRDaikin128
setFan(const uint8_t fan)IRDaikin128
setLightToggle(const uint8_t unit_type)IRDaikin128
setMode(const uint8_t mode)IRDaikin128
setOffTimer(const uint16_t mins_since_midnight)IRDaikin128
setOffTimerEnabled(const bool on)IRDaikin128
setOnTimer(const uint16_t mins_since_midnight)IRDaikin128
setOnTimerEnabled(const bool on)IRDaikin128
setPowerful(const bool on)IRDaikin128
setPowerToggle(const bool toggle)IRDaikin128
setQuiet(const bool on)IRDaikin128
setRaw(const uint8_t new_code[])IRDaikin128
setSleep(const bool on)IRDaikin128
setSwingVertical(const bool on)IRDaikin128
setTemp(const uint8_t temp)IRDaikin128
setTimer(uint8_t *ptr, const uint16_t mins_since_midnight)IRDaikin128privatestatic
stateReset(void)IRDaikin128private
toCommon(const stdAc::state_t *prev=NULL)IRDaikin128
toCommonFanSpeed(const uint8_t speed)IRDaikin128static
toCommonMode(const uint8_t mode)IRDaikin128static
toString(void)IRDaikin128
validChecksum(uint8_t state[])IRDaikin128static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128.html new file mode 100644 index 000000000..e2522aa48 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128.html @@ -0,0 +1,1669 @@ + + + + + + + +IRremoteESP8266: IRDaikin128 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin128:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin128 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin128DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPowerToggle (const bool toggle)
 Set the Power toggle setting of the A/C. More...
 
bool getPowerToggle (void)
 Get the Power toggle setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVertical ()
 Get the Vertical Swing mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep mode of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) mode of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economy mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
void setOnTimer (const uint16_t mins_since_midnight)
 Set the On Timer time for the A/C unit. More...
 
uint16_t getOnTimer (void)
 Get the On Timer time to be sent to the A/C unit. More...
 
bool getOnTimerEnabled (void)
 Get the enable status of the On Timer. More...
 
void setOnTimerEnabled (const bool on)
 Set the enable status of the On Timer. More...
 
void setOffTimer (const uint16_t mins_since_midnight)
 Set the Off Timer time for the A/C unit. More...
 
uint16_t getOffTimer (void)
 Get the Off Timer time to be sent to the A/C unit. More...
 
bool getOffTimerEnabled (void)
 Get the enable status of the Off Timer. More...
 
void setOffTimerEnabled (const bool on)
 Set the enable status of the Off Timer. More...
 
void setClock (const uint16_t mins_since_midnight)
 Set the clock on the A/C unit. More...
 
uint16_t getClock (void)
 Get the clock time to be sent to the A/C unit. More...
 
void setLightToggle (const uint8_t unit_type)
 Set the Light toggle setting of the A/C. More...
 
uint8_t getLightToggle (void)
 Get the Light toggle setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (const stdAc::state_t *prev=NULL)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[])
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
void clearOnTimerFlag (void)
 
void clearSleepTimerFlag (void)
 
+ + + + + + + + + + + +

+Static Private Member Functions

static uint8_t calcFirstChecksum (const uint8_t state[])
 
static uint8_t calcSecondChecksum (const uint8_t state[])
 
static void setTimer (uint8_t *ptr, const uint16_t mins_since_midnight)
 Set the time for a timer at the given location. More...
 
static uint16_t getTimer (const uint8_t *ptr)
 Get the time for a timer at the given location. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin128StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin128()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin128::IRDaikin128 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin128::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcFirstChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin128::calcFirstChecksum (const uint8_t state[])
+
+staticprivate
+
+ +
+
+ +

◆ calcSecondChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin128::calcSecondChecksum (const uint8_t state[])
+
+staticprivate
+
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin128::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikin128::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ clearOnTimerFlag()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikin128::clearOnTimerFlag (void )
+
+private
+
+ +
+
+ +

◆ clearSleepTimerFlag()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikin128::clearSleepTimerFlag (void )
+
+private
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin128::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin128::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin128::getClock (void )
+
+ +

Get the clock time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin128::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getLightToggle()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin128::getLightToggle (void )
+
+ +

Get the Light toggle setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin128::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin128::getOffTimer (void )
+
+ +

Get the Off Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getOffTimerEnabled (void )
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin128::getOnTimer (void )
+
+ +

Get the On Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOnTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getOnTimerEnabled (void )
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getPowerful (void )
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerToggle()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getPowerToggle (void )
+
+ +

Get the Power toggle setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRDaikin128::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getSleep (void )
+
+ +

Get the Sleep mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + +
bool IRDaikin128::getSwingVertical ()
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin128::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRDaikin128::getTimer (const uint8_t * ptr)
+
+staticprivate
+
+ +

Get the time for a timer at the given location.

+
Parameters
+ + +
[in]ptrA Ptr to the byte containing the Timer value.
+
+
+
Returns
The number of minutes since midnight that the timer is set to.
+
Note
Timer is stored in nr. of half hours internally.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin128::send (const uint16_t repeat = kDaikin128DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRDaikin128::setClock (const uint16_t mins_since_midnight)
+
+ +

Set the clock on the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRDaikin128::setEcono (const bool on)
+
+ +

Set the Economy mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin128::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setLightToggle()

+ +
+
+ + + + + + + + +
void IRDaikin128::setLightToggle (const uint8_t unit)
+
+ +

Set the Light toggle setting of the A/C.

+
Parameters
+ + +
[in]unitDevice to show the LED (Light) Display info about.
+
+
+
Note
0 is off.
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin128::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRDaikin128::setOffTimer (const uint16_t mins_since_midnight)
+
+ +

Set the Off Timer time for the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setOffTimerEnabled()

+ +
+
+ + + + + + + + +
void IRDaikin128::setOffTimerEnabled (const bool on)
+
+ +

Set the enable status of the Off Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRDaikin128::setOnTimer (const uint16_t mins_since_midnight)
+
+ +

Set the On Timer time for the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setOnTimerEnabled()

+ +
+
+ + + + + + + + +
void IRDaikin128::setOnTimerEnabled (const bool on)
+
+ +

Set the enable status of the On Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikin128::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerToggle()

+ +
+
+ + + + + + + + +
void IRDaikin128::setPowerToggle (const bool toggle)
+
+ +

Set the Power toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin128::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin128::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRDaikin128::setSleep (const bool on)
+
+ +

Set the Sleep mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin128::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin128::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRDaikin128::setTimer (uint8_t * ptr,
const uint16_t mins_since_midnight 
)
+
+staticprivate
+
+ +

Set the time for a timer at the given location.

+
Parameters
+ + + +
[in,out]ptrPtr to the byte containing the Timer value to be updated.
[in]mins_since_midnightThe number of minutes the new timer should be set to.
+
+
+
Note
Timer is rounds down to the nearest half hour.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikin128::stateReset (void )
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin128::toCommon (const stdAc::state_tprev = NULL)
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Parameters
+ + +
[in]prevPtr to a previous state.
+
+
+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDaikin128::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDaikin128::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin128::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRDaikin128::validChecksum (uint8_t state[])
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe array to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin128::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin128::remote_state[kDaikin128StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.map new file mode 100644 index 000000000..409771223 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.md5 new file mode 100644 index 000000000..2f277b744 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.md5 @@ -0,0 +1 @@ +de983d342633022717e3dd59d86c22b1 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..aeb1a1b31d451748e867ddc96af558811b0b77a1 GIT binary patch literal 3291 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 Q{H=g=Q3hI7n)Z+X1z)*qQ2+n{ literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152-members.html new file mode 100644 index 000000000..7b47665d8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152-members.html @@ -0,0 +1,116 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin152 Member List
+
+
+ +

This is the complete list of members for IRDaikin152, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin152private
begin()IRDaikin152
calibrate(void)IRDaikin152inline
checksum()IRDaikin152private
convertFan(const stdAc::fanspeed_t speed)IRDaikin152static
convertMode(const stdAc::opmode_t mode)IRDaikin152static
getComfort(void)IRDaikin152
getEcono(void)IRDaikin152
getFan(void)IRDaikin152
getMode(void)IRDaikin152
getPower(void)IRDaikin152
getPowerful(void)IRDaikin152
getQuiet(void)IRDaikin152
getRaw()IRDaikin152
getSensor(void)IRDaikin152
getSwingV(void)IRDaikin152
getTemp()IRDaikin152
IRDaikin152(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin152explicit
off(void)IRDaikin152
on(void)IRDaikin152
remote_stateIRDaikin152private
send(const uint16_t repeat=kDaikin152DefaultRepeat)IRDaikin152
setComfort(const bool on)IRDaikin152
setEcono(const bool on)IRDaikin152
setFan(const uint8_t fan)IRDaikin152
setMode(const uint8_t mode)IRDaikin152
setPower(const bool on)IRDaikin152
setPowerful(const bool on)IRDaikin152
setQuiet(const bool on)IRDaikin152
setRaw(const uint8_t new_code[])IRDaikin152
setSensor(const bool on)IRDaikin152
setSwingV(const bool on)IRDaikin152
setTemp(const uint8_t temp)IRDaikin152
stateReset()IRDaikin152private
toCommon(void)IRDaikin152
toString(void)IRDaikin152
validChecksum(uint8_t state[], const uint16_t length=kDaikin152StateLength)IRDaikin152static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152.html new file mode 100644 index 000000000..a9d798e0b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152.html @@ -0,0 +1,1172 @@ + + + + + + + +IRremoteESP8266: IRDaikin152 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 152-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin152:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin152 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin152DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingV (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) mode of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
void setSensor (const bool on)
 Set the Sensor mode of the A/C. More...
 
bool getSensor (void)
 Get the Sensor mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economy mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
void setComfort (const bool on)
 Set the Comfort mode of the A/C. More...
 
bool getComfort (void)
 Get the Comfort mode of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin152StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin152StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 152-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin152()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin152::IRDaikin152 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin152::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin152::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin152::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin152::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin152::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getComfort()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getComfort (void )
+
+ +

Get the Comfort mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin152::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin152::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getPowerful (void )
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin152::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSensor()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getSensor (void )
+
+ +

Get the Sensor mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin152::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikin152::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikin152::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin152::send (const uint16_t repeat = kDaikin152DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setComfort()

+ +
+
+ + + + + + + + +
void IRDaikin152::setComfort (const bool on)
+
+ +

Set the Comfort mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRDaikin152::setEcono (const bool on)
+
+ +

Set the Economy mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin152::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin152::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin152::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikin152::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin152::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin152::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSensor()

+ +
+
+ + + + + + + + +
void IRDaikin152::setSensor (const bool on)
+
+ +

Set the Sensor mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRDaikin152::setSwingV (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin152::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin152::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin152::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin152::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin152::validChecksum (uint8_t state[],
const uint16_t length = kDaikin152StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin152::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin152::remote_state[kDaikin152StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.map new file mode 100644 index 000000000..e246fb533 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.md5 new file mode 100644 index 000000000..193be7839 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.md5 @@ -0,0 +1 @@ +3bbfb60d234bb57df5106a32f8aecca3 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..cf4e791ca999ab9af56e4d802b6433bf9edebeb9 GIT binary patch literal 3202 zcmY+H2{=@38^>qJ8e*~=q==L?46*~QG*5OnnCENCF5gFqZGxS^g6hOm|!W@S4x6_L+*nw`0WwH>aX zYC|MYgwE!gb4*#vx=si4^0OMxrX z@rj8q>gw=}EL=Y8Uo{vQ8RK!dR@aKlqUeWvE-9CPhS zFNnm)+96xtJEikE?&q?^Gz9Yq-bv|AlQJ_jH8oA~zl>^67Cqm%vmm0~P+E$pA(IoQ zv3qM(?^b9urc`R(kS`7MhL$*9qb8|~b)m2sOmsM0$;_!H3aGY6|{PObr z{5%7Vz|V?*vg8#PkS3`YikQ4 z=!6MJbf!zw1dKm_{`|hW+IOKxs3BBbT>RkY?~OU|(#p#7!a{Ih;I`N@7!2MjT}QbZ zn$^cwSHpsWf+)koKW1aaS0<8-&H$e*r+c)25lEC{EG)Oxazk8?b7`AEa;o(t( zJkoa=GDXq*g{P*#Q{whho585kI@zjXq`;cyjI zRivF=$74>B$Ay{UNysxir!+K#D#m&`#KU`@UrAIHtV znR_m!sQBdVTgA}OP!j~=td5SDo!tm{t^1BLdUM4Vm_9Bp?v%Xz=RDiJkWt#5#9&^j zM^*xA3E=1diU`Q_0-!^IJeXu~sNSa^AA9g!@nfMu?COos4>!yF4F;WhR4Q6r1e2#f zmPW^l_UaN{LEmSyN1#x)08uSZSbQ>Z51+LEMfOodO~M#XNP(VhFpkgN8{vBs&gwbB zwAlE8y5zH(@E-DdyQ)CLeWnQ6P}bHzJIZ%X%6_~=1-kOlm5=px!J!jN=9ZUn>|I#V zQ%oIInR*mEP{5{cE#aLm`&a8q+OQZ+?bwji54BeVa1|J8aUfiir%Lyh-^2_xymVj; zGl`BI<5`v*UjKj_b|@jJBC=3oTbRd;%aYf!-v82KKRV&eN7yA+W_jbVMQNi`PKEO} z0u2Eu)_WT63thE`ET&0nMQPV7%J`%g8_9cwj(e2Mu0WM8sq&)DWJ|d>lTj;W8Ld2K z-JSBKlK0*7j0 zto#B46Vs(F*#!gyHd;>T#sMjeUiu=Dnwd#lOu^xJot>SZ15&?P`|wKr{*P{#^{=(f z9+fNeJ3Bk^`Pf~!UqC#sHmvjTx*0! z{5*|jxU*ZQ7e<1`3keDB?wSw;tyD>jAN%?&kF+4t%rUqyoYsg1EaISeV^~T@X9^v8Xi?;apz{~$Kt)vO=Hm)hSFgHM@4twY z5DKir9t7|2@0*yK4veHgH5ejZzdjGd*LA)tLu=<-x^|=Q#lF$<+Z#WAPys(YtEq_x zXv2k>o~U{tV)G`tH$OeSWqpzi_Idb_N~Sl`QV-Y3^mhQH#3mpoPsS%FGZz#WCqzXt zAPDMBfbRzFZ*;&-Og{GZKCnW6Wh0BmBauj(YuA1Z*`avE#1O8oM4i6wk|2N|n7y@X z;Jv4nlv3#*#5G`x00)65)3US2-16>rXCiOhc%=YiV)(YWSmDyf&VKxOXIIyA;B5o~ zK_aPtz4sNcmekbLd-&l+!iC%IxYIKL8XC)5R4}Cv20dC65#wMYn@-*YT zU0QyA8L25Z$2hUAxjjiFXg|&3aw| zf%N=*%YXniV0}jgUF#>vFcNcgq(5yKeYhV4%r)VC2#~hEp_OF zl9CdTVS|&CVGhB8fw0ZZ&Cu^nEI=I62m~C_{rUy|N8CVVGe@O1(?1*`00aE6=Nk~P zP&wk*GCiG7q1cR%kFO%-Kxz-h4gLL9`4eMSRy-d1`ewtt^RT=N^Ya^pI}d?$9;@~i2du3IJ#|4=wz;j1NkKsY*y$@?UZq&Diu-_MUie|qz~JEW z(vnjUj`)Ne~d!r>?Gn5pNxf(S{IMUS8g# z*w~*_A#|jJLt>MYQ&SYvZmZF)Teo<5c|qJFBCoS%snmhnRkI(uA4JCnu8m(YH^&9@ zsx||90jlG2m$rn70i&?$9DVpxhW|s<-<_q3js?UVlwlK=3OF!%}^xsQ&;RS}P9# literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160-members.html new file mode 100644 index 000000000..70a4643d6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160-members.html @@ -0,0 +1,108 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin160 Member List
+
+
+ +

This is the complete list of members for IRDaikin160, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin160private
begin()IRDaikin160
calibrate(void)IRDaikin160inline
checksum()IRDaikin160private
convertFan(const stdAc::fanspeed_t speed)IRDaikin160static
convertMode(const stdAc::opmode_t mode)IRDaikin160static
convertSwingV(const stdAc::swingv_t position)IRDaikin160static
getFan(void)IRDaikin160
getMode(void)IRDaikin160
getPower(void)IRDaikin160
getRaw()IRDaikin160
getSwingVertical(void)IRDaikin160
getTemp()IRDaikin160
IRDaikin160(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin160explicit
off(void)IRDaikin160
on(void)IRDaikin160
remote_stateIRDaikin160private
send(const uint16_t repeat=kDaikin160DefaultRepeat)IRDaikin160
setFan(const uint8_t fan)IRDaikin160
setMode(const uint8_t mode)IRDaikin160
setPower(const bool on)IRDaikin160
setRaw(const uint8_t new_code[])IRDaikin160
setSwingVertical(const uint8_t position)IRDaikin160
setTemp(const uint8_t temp)IRDaikin160
stateReset()IRDaikin160private
toCommon(void)IRDaikin160
toCommonSwingV(const uint8_t setting)IRDaikin160static
toString(void)IRDaikin160
validChecksum(uint8_t state[], const uint16_t length=kDaikin160StateLength)IRDaikin160static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160.html new file mode 100644 index 000000000..b69401604 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160.html @@ -0,0 +1,983 @@ + + + + + + + +IRremoteESP8266: IRDaikin160 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 160-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin160:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin160 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin160DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingVertical (const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin160StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t setting)
 Convert a native vertical swing postion to it's common equivalent. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin160StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 160-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin160()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin160::IRDaikin160 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin160::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin160::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin160::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin160::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin160::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin160::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin160::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin160::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikin160::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin160::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin160::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin160::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikin160::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikin160::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin160::send (const uint16_t repeat = kDaikin160DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin160::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin160::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin160::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin160::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin160::setSwingVertical (const uint8_t position)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin160::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin160::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin160::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRDaikin160::toCommonSwingV (const uint8_t setting)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]settingA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin160::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin160::validChecksum (uint8_t state[],
const uint16_t length = kDaikin160StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin160::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin160::remote_state[kDaikin160StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.map new file mode 100644 index 000000000..0a46ed86a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.md5 new file mode 100644 index 000000000..dadb00bba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.md5 @@ -0,0 +1 @@ +fbc66f5a6991bf58f0872d9bbb55a5da \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..4646db8e9ce3904ada8b7ffab6b72aa73ecf3fbc GIT binary patch literal 3302 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 + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin176 Member List
+
+
+ +

This is the complete list of members for IRDaikin176, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin176private
_saved_tempIRDaikin176private
begin()IRDaikin176
calibrate(void)IRDaikin176inline
checksum()IRDaikin176private
convertFan(const stdAc::fanspeed_t speed)IRDaikin176static
convertMode(const stdAc::opmode_t mode)IRDaikin176static
convertSwingH(const stdAc::swingh_t position)IRDaikin176static
getFan(void)IRDaikin176
getMode(void)IRDaikin176
getPower(void)IRDaikin176
getRaw()IRDaikin176
getSwingHorizontal(void)IRDaikin176
getTemp()IRDaikin176
IRDaikin176(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin176explicit
off(void)IRDaikin176
on(void)IRDaikin176
remote_stateIRDaikin176private
send(const uint16_t repeat=kDaikin176DefaultRepeat)IRDaikin176
setFan(const uint8_t fan)IRDaikin176
setMode(const uint8_t mode)IRDaikin176
setPower(const bool on)IRDaikin176
setRaw(const uint8_t new_code[])IRDaikin176
setSwingHorizontal(const uint8_t position)IRDaikin176
setTemp(const uint8_t temp)IRDaikin176
stateReset()IRDaikin176private
toCommon(void)IRDaikin176
toCommonFanSpeed(const uint8_t speed)IRDaikin176static
toCommonMode(const uint8_t mode)IRDaikin176static
toCommonSwingH(const uint8_t setting)IRDaikin176static
toString(void)IRDaikin176
validChecksum(uint8_t state[], const uint16_t length=kDaikin176StateLength)IRDaikin176static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176.html new file mode 100644 index 000000000..739f5c3a3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176.html @@ -0,0 +1,1083 @@ + + + + + + + +IRremoteESP8266: IRDaikin176 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 176-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin176:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin176 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin176DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off.. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingHorizontal (const uint8_t position)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin176StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t setting)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin176StateLength]
 The state of the IR remote. More...
 
uint8_t _saved_temp
 
+

Detailed Description

+

Class for handling detailed Daikin 176-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin176()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin176::IRDaikin176 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin176::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin176::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin176::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin176::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin176::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin176::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin176::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin176::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikin176::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin176::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin176::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin176::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikin176::off (void )
+
+ +

Change the power setting to Off..

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikin176::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin176::send (const uint16_t repeat = kDaikin176DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin176::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1 for Min or 3 for Max
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin176::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin176::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin176::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRDaikin176::setSwingHorizontal (const uint8_t position)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin176::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin176::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin176::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDaikin176::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDaikin176::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRDaikin176::toCommonSwingH (const uint8_t setting)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]settingA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin176::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin176::validChecksum (uint8_t state[],
const uint16_t length = kDaikin176StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin176::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ _saved_temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin176::_saved_temp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin176::remote_state[kDaikin176StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.map new file mode 100644 index 000000000..f61dca56f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.md5 new file mode 100644 index 000000000..46c8fe910 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.md5 @@ -0,0 +1 @@ +e1b4fd7ddfe8c5ab5d5bb1cf9d344bc4 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..44469aecec9969597121cfc80b7b6396e9dce0ef GIT binary patch literal 3228 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 VUg(G0!0!ggK-Wm8Ow0Dqe*w_}U8w*7 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2-members.html new file mode 100644 index 000000000..2dd3582dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2-members.html @@ -0,0 +1,152 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin2 Member List
+
+
+ +

This is the complete list of members for IRDaikin2, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin2private
begin()IRDaikin2
calibrate(void)IRDaikin2inline
checksum()IRDaikin2private
clearOnTimerFlag()IRDaikin2private
clearSleepTimerFlag()IRDaikin2private
convertFan(const stdAc::fanspeed_t speed)IRDaikin2static
convertMode(const stdAc::opmode_t mode)IRDaikin2static
convertSwingH(const stdAc::swingh_t position)IRDaikin2static
convertSwingV(const stdAc::swingv_t position)IRDaikin2static
disableOffTimer()IRDaikin2
disableOnTimer()IRDaikin2
disableSleepTimer()IRDaikin2
enableOffTimer(const uint16_t endtime)IRDaikin2
enableOnTimer(const uint16_t starttime)IRDaikin2
enableSleepTimer(const uint16_t sleeptime)IRDaikin2
getBeep()IRDaikin2
getClean()IRDaikin2
getCurrentTime()IRDaikin2
getEcono()IRDaikin2
getEye()IRDaikin2
getEyeAuto()IRDaikin2
getFan()IRDaikin2
getFreshAir()IRDaikin2
getFreshAirHigh()IRDaikin2
getLight()IRDaikin2
getMode()IRDaikin2
getMold()IRDaikin2
getOffTime()IRDaikin2
getOffTimerEnabled()IRDaikin2
getOnTime()IRDaikin2
getOnTimerEnabled()IRDaikin2
getPower()IRDaikin2
getPowerful()IRDaikin2
getPurify()IRDaikin2
getQuiet()IRDaikin2
getRaw()IRDaikin2
getSleepTime()IRDaikin2
getSleepTimerEnabled()IRDaikin2
getSwingHorizontal()IRDaikin2
getSwingVertical()IRDaikin2
getTemp()IRDaikin2
IRDaikin2(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin2explicit
off()IRDaikin2
on()IRDaikin2
remote_stateIRDaikin2private
send(const uint16_t repeat=kDaikin2DefaultRepeat)IRDaikin2
setBeep(const uint8_t beep)IRDaikin2
setClean(const bool on)IRDaikin2
setCurrentTime(const uint16_t time)IRDaikin2
setEcono(const bool on)IRDaikin2
setEye(const bool on)IRDaikin2
setEyeAuto(const bool on)IRDaikin2
setFan(const uint8_t fan)IRDaikin2
setFreshAir(const bool on)IRDaikin2
setFreshAirHigh(const bool on)IRDaikin2
setLight(const uint8_t light)IRDaikin2
setMode(const uint8_t mode)IRDaikin2
setMold(const bool on)IRDaikin2
setPower(const bool state)IRDaikin2
setPowerful(const bool on)IRDaikin2
setPurify(const bool on)IRDaikin2
setQuiet(const bool on)IRDaikin2
setRaw(const uint8_t new_code[])IRDaikin2
setSwingHorizontal(const uint8_t position)IRDaikin2
setSwingVertical(const uint8_t position)IRDaikin2
setTemp(const uint8_t temp)IRDaikin2
stateReset()IRDaikin2private
toCommon(void)IRDaikin2
toCommonSwingH(const uint8_t setting)IRDaikin2static
toCommonSwingV(const uint8_t setting)IRDaikin2static
toString()IRDaikin2
validChecksum(uint8_t state[], const uint16_t length=kDaikin2StateLength)IRDaikin2static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2.html new file mode 100644 index 000000000..788948d02 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2.html @@ -0,0 +1,2133 @@ + + + + + + + +IRremoteESP8266: IRDaikin2 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin2:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin2 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin2DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setPower (const bool state)
 Change the power setting. More...
 
bool getPower ()
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current fan speed setting. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
void setSwingVertical (const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingVertical ()
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const uint8_t position)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingHorizontal ()
 Get the Horizontal Swing mode of the A/C. More...
 
bool getQuiet ()
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getPowerful ()
 Get the Powerful (Turbo) mode of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economy mode of the A/C. More...
 
bool getEcono ()
 Get the Economical mode of the A/C. More...
 
void setEye (const bool on)
 Set the Eye (Sensor) mode of the A/C. More...
 
bool getEye ()
 Get the Eye (Sensor) mode status of the A/C. More...
 
void setEyeAuto (const bool on)
 Set the Automatic Eye (Sensor) mode of the A/C. More...
 
bool getEyeAuto ()
 Get the Automaitc Eye (Sensor) mode status of the A/C. More...
 
void setPurify (const bool on)
 Set the Purify (Filter) mode of the A/C. More...
 
bool getPurify ()
 Get the Purify (Filter) mode status of the A/C. More...
 
void setMold (const bool on)
 Set the Mould (filter) mode of the A/C. More...
 
bool getMold ()
 Get the Mould (filter) mode status of the A/C. More...
 
void enableOnTimer (const uint16_t starttime)
 Set the enable status & time of the On Timer. More...
 
void disableOnTimer ()
 Disable the On timer. More...
 
uint16_t getOnTime ()
 Get the On Timer time to be sent to the A/C unit. More...
 
bool getOnTimerEnabled ()
 Get the enable status of the On Timer. More...
 
void enableSleepTimer (const uint16_t sleeptime)
 Set the enable status & time of the Sleep Timer. More...
 
void disableSleepTimer ()
 Disable the sleep timer. More...
 
uint16_t getSleepTime ()
 Get the Sleep Timer time to be sent to the A/C unit. More...
 
bool getSleepTimerEnabled ()
 Get the Sleep timer enabled status of the A/C. More...
 
void enableOffTimer (const uint16_t endtime)
 Set the enable status & time of the Off Timer. More...
 
void disableOffTimer ()
 Disable the Off timer. More...
 
uint16_t getOffTime ()
 Get the Off Timer time to be sent to the A/C unit. More...
 
bool getOffTimerEnabled ()
 Get the enable status of the Off Timer. More...
 
void setCurrentTime (const uint16_t time)
 Set the clock on the A/C unit. More...
 
uint16_t getCurrentTime ()
 Get the clock time to be sent to the A/C unit. More...
 
void setBeep (const uint8_t beep)
 Set the Beep mode of the A/C. More...
 
uint8_t getBeep ()
 Get the Beep status of the A/C. More...
 
void setLight (const uint8_t light)
 Set the Light (LED) mode of the A/C. More...
 
uint8_t getLight ()
 Get the Light status of the A/C. More...
 
void setClean (const bool on)
 Set the Auto clean mode of the A/C. More...
 
bool getClean ()
 Get the Auto Clean mode status of the A/C. More...
 
void setFreshAir (const bool on)
 Set the Fresh Air mode of the A/C. More...
 
bool getFreshAir ()
 Get the Fresh Air mode status of the A/C. More...
 
void setFreshAirHigh (const bool on)
 Set the (High) Fresh Air mode of the A/C. More...
 
bool getFreshAirHigh ()
 Get the (High) Fresh Air mode status of the A/C. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin2StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t setting)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t setting)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + + + + + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
void clearOnTimerFlag ()
 Clear the On Timer flag. More...
 
void clearSleepTimerFlag ()
 Clear the sleep timer flag. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin2StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin2::IRDaikin2 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin2::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin2::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin2::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ clearOnTimerFlag()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin2::clearOnTimerFlag ()
+
+private
+
+ +

Clear the On Timer flag.

+ +
+
+ +

◆ clearSleepTimerFlag()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin2::clearSleepTimerFlag ()
+
+private
+
+ +

Clear the sleep timer flag.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin2::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin2::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin2::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin2::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ disableOffTimer()

+ +
+
+ + + + + + + +
void IRDaikin2::disableOffTimer ()
+
+ +

Disable the Off timer.

+ +
+
+ +

◆ disableOnTimer()

+ +
+
+ + + + + + + +
void IRDaikin2::disableOnTimer ()
+
+ +

Disable the On timer.

+ +
+
+ +

◆ disableSleepTimer()

+ +
+
+ + + + + + + +
void IRDaikin2::disableSleepTimer ()
+
+ +

Disable the sleep timer.

+ +
+
+ +

◆ enableOffTimer()

+ +
+
+ + + + + + + + +
void IRDaikin2::enableOffTimer (const uint16_t endtime)
+
+ +

Set the enable status & time of the Off Timer.

+
Parameters
+ + +
[in]endtimeThe number of minutes past midnight.
+
+
+ +
+
+ +

◆ enableOnTimer()

+ +
+
+ + + + + + + + +
void IRDaikin2::enableOnTimer (const uint16_t starttime)
+
+ +

Set the enable status & time of the On Timer.

+
Parameters
+ + +
[in]starttimeThe number of minutes past midnight.
+
+
+
Note
Timer location is shared with sleep timer.
+ +
+
+ +

◆ enableSleepTimer()

+ +
+
+ + + + + + + + +
void IRDaikin2::enableSleepTimer (const uint16_t sleeptime)
+
+ +

Set the enable status & time of the Sleep Timer.

+
Parameters
+ + +
[in]sleeptimeThe number of minutes past midnight.
+
+
+
Note
The Timer location is shared with On Timer.
+ +
+
+ +

◆ getBeep()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getBeep ()
+
+ +

Get the Beep status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + +
bool IRDaikin2::getClean ()
+
+ +

Get the Auto Clean mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getCurrentTime()

+ +
+
+ + + + + + + +
uint16_t IRDaikin2::getCurrentTime ()
+
+ +

Get the clock time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + +
bool IRDaikin2::getEcono ()
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEye()

+ +
+
+ + + + + + + +
bool IRDaikin2::getEye ()
+
+ +

Get the Eye (Sensor) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEyeAuto()

+ +
+
+ + + + + + + +
bool IRDaikin2::getEyeAuto ()
+
+ +

Get the Automaitc Eye (Sensor) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getFan ()
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getFreshAir()

+ +
+
+ + + + + + + +
bool IRDaikin2::getFreshAir ()
+
+ +

Get the Fresh Air mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFreshAirHigh()

+ +
+
+ + + + + + + +
bool IRDaikin2::getFreshAirHigh ()
+
+ +

Get the (High) Fresh Air mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getLight ()
+
+ +

Get the Light status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getMold()

+ +
+
+ + + + + + + +
bool IRDaikin2::getMold ()
+
+ +

Get the Mould (filter) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOffTime()

+ +
+
+ + + + + + + +
uint16_t IRDaikin2::getOffTime ()
+
+ +

Get the Off Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOffTimerEnabled()

+ +
+
+ + + + + + + +
bool IRDaikin2::getOffTimerEnabled ()
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTime()

+ +
+
+ + + + + + + +
uint16_t IRDaikin2::getOnTime ()
+
+ +

Get the On Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOnTimerEnabled()

+ +
+
+ + + + + + + +
bool IRDaikin2::getOnTimerEnabled ()
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRDaikin2::getPower ()
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + +
bool IRDaikin2::getPowerful ()
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPurify()

+ +
+
+ + + + + + + +
bool IRDaikin2::getPurify ()
+
+ +

Get the Purify (Filter) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + +
bool IRDaikin2::getQuiet ()
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin2::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleepTime()

+ +
+
+ + + + + + + +
uint16_t IRDaikin2::getSleepTime ()
+
+ +

Get the Sleep Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getSleepTimerEnabled()

+ +
+
+ + + + + + + +
bool IRDaikin2::getSleepTimerEnabled ()
+
+ +

Get the Sleep timer enabled status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getSwingHorizontal ()
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getSwingVertical ()
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRDaikin2::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRDaikin2::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin2::send (const uint16_t repeat = kDaikin2DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setBeep()

+ +
+
+ + + + + + + + +
void IRDaikin2::setBeep (const uint8_t beep)
+
+ +

Set the Beep mode of the A/C.

+
Parameters
+ + +
[in]beeptrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRDaikin2::setClean (const bool on)
+
+ +

Set the Auto clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setCurrentTime()

+ +
+
+ + + + + + + + +
void IRDaikin2::setCurrentTime (const uint16_t numMins)
+
+ +

Set the clock on the A/C unit.

+
Parameters
+ + +
[in]numMinsNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRDaikin2::setEcono (const bool on)
+
+ +

Set the Economy mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEye()

+ +
+
+ + + + + + + + +
void IRDaikin2::setEye (const bool on)
+
+ +

Set the Eye (Sensor) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEyeAuto()

+ +
+
+ + + + + + + + +
void IRDaikin2::setEyeAuto (const bool on)
+
+ +

Set the Automatic Eye (Sensor) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin2::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setFreshAir()

+ +
+
+ + + + + + + + +
void IRDaikin2::setFreshAir (const bool on)
+
+ +

Set the Fresh Air mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFreshAirHigh()

+ +
+
+ + + + + + + + +
void IRDaikin2::setFreshAirHigh (const bool on)
+
+ +

Set the (High) Fresh Air mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRDaikin2::setLight (const uint8_t light)
+
+ +

Set the Light (LED) mode of the A/C.

+
Parameters
+ + +
[in]lighttrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin2::setMode (const uint8_t desired_mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]desired_modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setMold()

+ +
+
+ + + + + + + + +
void IRDaikin2::setMold (const bool on)
+
+ +

Set the Mould (filter) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin2::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikin2::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPurify()

+ +
+
+ + + + + + + + +
void IRDaikin2::setPurify (const bool on)
+
+ +

Set the Purify (Filter) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin2::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin2::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRDaikin2::setSwingHorizontal (const uint8_t position)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin2::setSwingVertical (const uint8_t position)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin2::setTemp (const uint8_t desired)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]desiredThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin2::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin2::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRDaikin2::toCommonSwingH (const uint8_t setting)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]settingA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRDaikin2::toCommonSwingV (const uint8_t setting)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]settingA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRDaikin2::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin2::validChecksum (uint8_t state[],
const uint16_t length = kDaikin2StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin2::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin2::remote_state[kDaikin2StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216-members.html new file mode 100644 index 000000000..5ee15e07e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216-members.html @@ -0,0 +1,112 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin216 Member List
+
+
+ +

This is the complete list of members for IRDaikin216, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin216private
begin()IRDaikin216
calibrate(void)IRDaikin216inline
checksum()IRDaikin216private
convertFan(const stdAc::fanspeed_t speed)IRDaikin216static
convertMode(const stdAc::opmode_t mode)IRDaikin216static
getFan(void)IRDaikin216
getMode(void)IRDaikin216
getPower(void)IRDaikin216
getPowerful(void)IRDaikin216
getQuiet(void)IRDaikin216
getRaw()IRDaikin216
getSwingHorizontal(void)IRDaikin216
getSwingVertical(void)IRDaikin216
getTemp()IRDaikin216
IRDaikin216(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin216explicit
off(void)IRDaikin216
on(void)IRDaikin216
remote_stateIRDaikin216private
send(const uint16_t repeat=kDaikin216DefaultRepeat)IRDaikin216
setFan(const uint8_t fan)IRDaikin216
setMode(const uint8_t mode)IRDaikin216
setPower(const bool on)IRDaikin216
setPowerful(const bool on)IRDaikin216
setQuiet(const bool on)IRDaikin216
setRaw(const uint8_t new_code[])IRDaikin216
setSwingHorizontal(const bool on)IRDaikin216
setSwingVertical(const bool on)IRDaikin216
setTemp(const uint8_t temp)IRDaikin216
stateReset()IRDaikin216private
toCommon(void)IRDaikin216
toString(void)IRDaikin216
validChecksum(uint8_t state[], const uint16_t length=kDaikin216StateLength)IRDaikin216static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216.html new file mode 100644 index 000000000..d4e05e872 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216.html @@ -0,0 +1,1068 @@ + + + + + + + +IRremoteESP8266: IRDaikin216 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 216-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin216:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin216 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class Constructor. More...
 
void send (const uint16_t repeat=kDaikin216DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const bool on)
 Set the Horizontal Swing mode of the A/C. More...
 
bool getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) mode of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin216StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin216StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 216-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin216()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin216::IRDaikin216 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class Constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin216::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin216::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin216::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin216::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin216::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin216::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin216::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getPowerful (void )
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+
Note
This is a horrible hack till someone works out the quiet mode bit.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin216::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin216::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikin216::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikin216::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin216::send (const uint16_t repeat = kDaikin216DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin216::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin216::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin216::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikin216::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin216::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
This is a horrible hack till someone works out the quiet mode bit.
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin216::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRDaikin216::setSwingHorizontal (const bool on)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin216::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin216::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin216::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin216::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin216::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin216::validChecksum (uint8_t state[],
const uint16_t length = kDaikin216StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin216::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin216::remote_state[kDaikin216StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.map new file mode 100644 index 000000000..a2be3b0a2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.md5 new file mode 100644 index 000000000..8b015e855 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.md5 @@ -0,0 +1 @@ +376e63c140c9b990fbd05013138184b0 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..40e2871efc17ef7d50bf67a62b4657900be91d65 GIT binary patch literal 3277 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 JTGRgFKLBqsI{E+r literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.map new file mode 100644 index 000000000..b57955f2c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.md5 new file mode 100644 index 000000000..73f0805f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.md5 @@ -0,0 +1 @@ +3ef4da6c50362fb01d8d40a3983c3439 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..a8a2b148e774f7449fb4f4e2ac0b56dc9dec73ea GIT binary patch literal 3012 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 + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin64 Member List
+
+
+ +

This is the complete list of members for IRDaikin64, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin64private
begin()IRDaikin64
calcChecksum(const uint64_t state)IRDaikin64static
calibrate(void)IRDaikin64inline
checksum()IRDaikin64private
convertFan(const stdAc::fanspeed_t speed)IRDaikin64static
convertMode(const stdAc::opmode_t mode)IRDaikin64static
getClock(void)IRDaikin64
getFan(void)IRDaikin64
getMode(void)IRDaikin64
getOffTime(void)IRDaikin64
getOffTimeEnabled(void)IRDaikin64
getOnTime(void)IRDaikin64
getOnTimeEnabled(void)IRDaikin64
getPowerToggle(void)IRDaikin64
getQuiet(void)IRDaikin64
getRaw()IRDaikin64
getSleep(void)IRDaikin64
getSwingVertical(void)IRDaikin64
getTemp()IRDaikin64
getTurbo(void)IRDaikin64
IRDaikin64(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin64explicit
remote_stateIRDaikin64private
send(const uint16_t repeat=kDaikin64DefaultRepeat)IRDaikin64
setClock(const uint16_t mins_since_midnight)IRDaikin64
setFan(const uint8_t fan)IRDaikin64
setMode(const uint8_t mode)IRDaikin64
setOffTime(const uint16_t mins_since_midnight)IRDaikin64
setOffTimeEnabled(const bool on)IRDaikin64
setOnTime(const uint16_t mins_since_midnight)IRDaikin64
setOnTimeEnabled(const bool on)IRDaikin64
setPowerToggle(const bool on)IRDaikin64
setQuiet(const bool on)IRDaikin64
setRaw(const uint64_t new_state)IRDaikin64
setSleep(const bool on)IRDaikin64
setSwingVertical(const bool on)IRDaikin64
setTemp(const uint8_t temp)IRDaikin64
setTurbo(const bool on)IRDaikin64
stateReset()IRDaikin64private
toCommon(const stdAc::state_t *prev=NULL)IRDaikin64
toCommonFanSpeed(const uint8_t speed)IRDaikin64static
toCommonMode(const uint8_t mode)IRDaikin64static
toString(void)IRDaikin64
validChecksum(const uint64_t state)IRDaikin64static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64.html new file mode 100644 index 000000000..b3a860c52 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64.html @@ -0,0 +1,1393 @@ + + + + + + + +IRremoteESP8266: IRDaikin64 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 64-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin64:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin64 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin64DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint64_t getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint64_t new_state)
 Set the internal state from a valid code for this protocol. More...
 
void setPowerToggle (const bool on)
 Set the Power toggle setting of the A/C. More...
 
bool getPowerToggle (void)
 Get the Power toggle setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo (Powerful) mode status of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo (Powerful) mode of the A/C. More...
 
void setClock (const uint16_t mins_since_midnight)
 Set the clock on the A/C unit. More...
 
uint16_t getClock (void)
 Get the clock time to be sent to the A/C unit. More...
 
void setOnTimeEnabled (const bool on)
 Set the enable status of the On Timer. More...
 
bool getOnTimeEnabled (void)
 Get the enable status of the On Timer. More...
 
void setOnTime (const uint16_t mins_since_midnight)
 Set the On Timer time for the A/C unit. More...
 
uint16_t getOnTime (void)
 Get the On Timer time to be sent to the A/C unit. More...
 
void setOffTimeEnabled (const bool on)
 Set the enable status of the Off Timer. More...
 
bool getOffTimeEnabled (void)
 Get the enable status of the Off Timer. More...
 
void setOffTime (const uint16_t mins_since_midnight)
 Set the Off Timer time for the A/C unit. More...
 
uint16_t getOffTime (void)
 Get the Off Timer time to be sent to the A/C unit. More...
 
stdAc::state_t toCommon (const stdAc::state_t *prev=NULL)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint64_t remote_state
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 64-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin64::IRDaikin64 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin64::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin64::calcChecksum (const uint64_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
The 4-bit checksum stored in a uint_8.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin64::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin64::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin64::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin64::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin64::getClock (void )
+
+ +

Get the clock time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin64::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin64::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin64::getOffTime (void )
+
+ +

Get the Off Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOffTimeEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getOffTimeEnabled (void )
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin64::getOnTime (void )
+
+ +

Get the On Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOnTimeEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getOnTimeEnabled (void )
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerToggle()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getPowerToggle (void )
+
+ +

Get the Power toggle setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint64_t IRDaikin64::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getSleep (void )
+
+ +

Get the Sleep mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin64::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getTurbo (void )
+
+ +

Get the Turbo (Powerful) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin64::send (const uint16_t repeat = kDaikin64DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRDaikin64::setClock (const uint16_t mins_since_midnight)
+
+ +

Set the clock on the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin64::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin64::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTime()

+ +
+
+ + + + + + + + +
void IRDaikin64::setOffTime (const uint16_t mins_since_midnight)
+
+ +

Set the Off Timer time for the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setOffTimeEnabled()

+ +
+
+ + + + + + + + +
void IRDaikin64::setOffTimeEnabled (const bool on)
+
+ +

Set the enable status of the Off Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setOnTime()

+ +
+
+ + + + + + + + +
void IRDaikin64::setOnTime (const uint16_t mins_since_midnight)
+
+ +

Set the On Timer time for the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setOnTimeEnabled()

+ +
+
+ + + + + + + + +
void IRDaikin64::setOnTimeEnabled (const bool on)
+
+ +

Set the enable status of the On Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerToggle()

+ +
+
+ + + + + + + + +
void IRDaikin64::setPowerToggle (const bool on)
+
+ +

Set the Power toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin64::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin64::setRaw (const uint64_t new_state)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRDaikin64::setSleep (const bool on)
+
+ +

Set the Sleep mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin64::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin64::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRDaikin64::setTurbo (const bool on)
+
+ +

Set the Turbo (Powerful) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin64::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin64::toCommon (const stdAc::state_tprev = NULL)
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Parameters
+ + +
[in]prevPtr to a previous state.
+
+
+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDaikin64::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDaikin64::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin64::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRDaikin64::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe state to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin64::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRDaikin64::remote_state
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.map new file mode 100644 index 000000000..ed3f71001 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.md5 new file mode 100644 index 000000000..40836ffaa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.md5 @@ -0,0 +1 @@ +b2bb54fe62558d21dee90dc29baf242d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..b66057e113bef90d50a81d4da26c623cae284898 GIT binary patch literal 3190 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 + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikinESP Member List
+
+
+ +

This is the complete list of members for IRDaikinESP, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikinESPprivate
begin(void)IRDaikinESP
calibrate(void)IRDaikinESPinline
checksum(void)IRDaikinESPprivate
convertFan(const stdAc::fanspeed_t speed)IRDaikinESPstatic
convertMode(const stdAc::opmode_t mode)IRDaikinESPstatic
disableOffTimer(void)IRDaikinESP
disableOnTimer(void)IRDaikinESP
enableOffTimer(const uint16_t endtime)IRDaikinESP
enableOnTimer(const uint16_t starttime)IRDaikinESP
getComfort(void)IRDaikinESP
getCurrentDay(void)IRDaikinESP
getCurrentTime(void)IRDaikinESP
getEcono(void)IRDaikinESP
getFan(void)IRDaikinESP
getMode(void)IRDaikinESP
getMold(void)IRDaikinESP
getOffTime(void)IRDaikinESP
getOffTimerEnabled(void)IRDaikinESP
getOnTime(void)IRDaikinESP
getOnTimerEnabled()IRDaikinESP
getPower(void)IRDaikinESP
getPowerful(void)IRDaikinESP
getQuiet(void)IRDaikinESP
getRaw(void)IRDaikinESP
getSensor(void)IRDaikinESP
getSwingHorizontal(void)IRDaikinESP
getSwingVertical(void)IRDaikinESP
getTemp()IRDaikinESP
getWeeklyTimerEnable(void)IRDaikinESP
IRDaikinESP(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikinESPexplicit
off(void)IRDaikinESP
on(void)IRDaikinESP
remoteIRDaikinESPprivate
send(const uint16_t repeat=kDaikinDefaultRepeat)IRDaikinESP
setComfort(const bool on)IRDaikinESP
setCurrentDay(const uint8_t day_of_week)IRDaikinESP
setCurrentTime(const uint16_t mins_since_midnight)IRDaikinESP
setEcono(const bool on)IRDaikinESP
setFan(const uint8_t fan)IRDaikinESP
setMode(const uint8_t mode)IRDaikinESP
setMold(const bool on)IRDaikinESP
setPower(const bool on)IRDaikinESP
setPowerful(const bool on)IRDaikinESP
setQuiet(const bool on)IRDaikinESP
setRaw(const uint8_t new_code[], const uint16_t length=kDaikinStateLength)IRDaikinESP
setSensor(const bool on)IRDaikinESP
setSwingHorizontal(const bool on)IRDaikinESP
setSwingVertical(const bool on)IRDaikinESP
setTemp(const uint8_t temp)IRDaikinESP
setWeeklyTimerEnable(const bool on)IRDaikinESP
stateReset(void)IRDaikinESPprivate
toCommon(void)IRDaikinESP
toCommonFanSpeed(const uint8_t speed)IRDaikinESPstatic
toCommonMode(const uint8_t mode)IRDaikinESPstatic
toString(void)IRDaikinESP
validChecksum(uint8_t state[], const uint16_t length=kDaikinStateLength)IRDaikinESPstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP.html new file mode 100644 index 000000000..a8aab02cd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP.html @@ -0,0 +1,1729 @@ + + + + + + + +IRremoteESP8266: IRDaikinESP Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 280-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikinESP:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikinESP (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikinDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const bool on)
 Set the Horizontal Swing mode of the A/C. More...
 
bool getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) mode of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
void setSensor (const bool on)
 Set the Sensor mode of the A/C. More...
 
bool getSensor (void)
 Get the Sensor mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economy mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
void setMold (const bool on)
 Set the Mould mode of the A/C. More...
 
bool getMold (void)
 Get the Mould mode status of the A/C. More...
 
void setComfort (const bool on)
 Set the Comfort mode of the A/C. More...
 
bool getComfort (void)
 Get the Comfort mode of the A/C. More...
 
void enableOnTimer (const uint16_t starttime)
 Set the enable status & time of the On Timer. More...
 
void disableOnTimer (void)
 Clear and disable the On timer. More...
 
uint16_t getOnTime (void)
 Get the On Timer time to be sent to the A/C unit. More...
 
bool getOnTimerEnabled ()
 Get the enable status of the On Timer. More...
 
void enableOffTimer (const uint16_t endtime)
 Set the enable status & time of the Off Timer. More...
 
void disableOffTimer (void)
 Clear and disable the Off timer. More...
 
uint16_t getOffTime (void)
 Get the Off Timer time to be sent to the A/C unit. More...
 
bool getOffTimerEnabled (void)
 Get the enable status of the Off Timer. More...
 
void setCurrentTime (const uint16_t mins_since_midnight)
 Set the clock on the A/C unit. More...
 
uint16_t getCurrentTime (void)
 Get the clock time to be sent to the A/C unit. More...
 
void setCurrentDay (const uint8_t day_of_week)
 Set the current day of the week to be sent to the A/C unit. More...
 
uint8_t getCurrentDay (void)
 Get the current day of the week to be sent to the A/C unit. More...
 
void setWeeklyTimerEnable (const bool on)
 Set the enable status of the Weekly Timer. More...
 
bool getWeeklyTimerEnable (void)
 Get the enable status of the Weekly Timer. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kDaikinStateLength)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikinStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote [kDaikinStateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 280-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikinESP()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikinESP::IRDaikinESP (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRDaikinESP::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikinESP::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikinESP::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikinESP::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikinESP::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ disableOffTimer()

+ +
+
+ + + + + + + + +
void IRDaikinESP::disableOffTimer (void )
+
+ +

Clear and disable the Off timer.

+ +
+
+ +

◆ disableOnTimer()

+ +
+
+ + + + + + + + +
void IRDaikinESP::disableOnTimer (void )
+
+ +

Clear and disable the On timer.

+ +
+
+ +

◆ enableOffTimer()

+ +
+
+ + + + + + + + +
void IRDaikinESP::enableOffTimer (const uint16_t endtime)
+
+ +

Set the enable status & time of the Off Timer.

+
Parameters
+ + +
[in]endtimeThe number of minutes past midnight.
+
+
+ +
+
+ +

◆ enableOnTimer()

+ +
+
+ + + + + + + + +
void IRDaikinESP::enableOnTimer (const uint16_t starttime)
+
+ +

Set the enable status & time of the On Timer.

+
Parameters
+ + +
[in]starttimeThe number of minutes past midnight.
+
+
+ +
+
+ +

◆ getComfort()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getComfort (void )
+
+ +

Get the Comfort mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getCurrentDay()

+ +
+
+ + + + + + + + +
uint8_t IRDaikinESP::getCurrentDay (void )
+
+ +

Get the current day of the week to be sent to the A/C unit.

+
Returns
The numerical representation of the day of the week.
+
Note
1 is SUN, 2 is MON, ..., 7 is SAT
+ +
+
+ +

◆ getCurrentTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikinESP::getCurrentTime (void )
+
+ +

Get the clock time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikinESP::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikinESP::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getMold()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getMold (void )
+
+ +

Get the Mould mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOffTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikinESP::getOffTime (void )
+
+ +

Get the Off Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getOffTimerEnabled (void )
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikinESP::getOnTime (void )
+
+ +

Get the On Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOnTimerEnabled()

+ +
+
+ + + + + + + +
bool IRDaikinESP::getOnTimerEnabled ()
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getPowerful (void )
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRDaikinESP::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSensor()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getSensor (void )
+
+ +

Get the Sensor mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikinESP::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getWeeklyTimerEnable()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getWeeklyTimerEnable (void )
+
+ +

Get the enable status of the Weekly Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikinESP::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikinESP::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikinESP::send (const uint16_t repeat = kDaikinDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setComfort()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setComfort (const bool on)
+
+ +

Set the Comfort mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setCurrentDay()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setCurrentDay (const uint8_t day_of_week)
+
+ +

Set the current day of the week to be sent to the A/C unit.

+
Parameters
+ + +
[in]day_of_weekThe numerical representation of the day of the week.
+
+
+
Note
1 is SUN, 2 is MON, ..., 7 is SAT
+ +
+
+ +

◆ setCurrentTime()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setCurrentTime (const uint16_t mins_since_midnight)
+
+ +

Set the clock on the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setEcono (const bool on)
+
+ +

Set the Economy mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setMold()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setMold (const bool on)
+
+ +

Set the Mould mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRDaikinESP::setRaw (const uint8_t new_code[],
const uint16_t length = kDaikinStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthLength of the code in bytes.
+
+
+ +
+
+ +

◆ setSensor()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setSensor (const bool on)
+
+ +

Set the Sensor mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setSwingHorizontal (const bool on)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setWeeklyTimerEnable()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setWeeklyTimerEnable (const bool on)
+
+ +

Set the enable status of the Weekly Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikinESP::stateReset (void )
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikinESP::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDaikinESP::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDaikinESP::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikinESP::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikinESP::validChecksum (uint8_t state[],
const uint16_t length = kDaikinStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikinESP::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikinESP::remote[kDaikinStateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.map new file mode 100644 index 000000000..6ae75bb13 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 new file mode 100644 index 000000000..108e7de33 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 @@ -0,0 +1 @@ +68cef74e6daf013f3d7f49c1a7c4d7f5 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..b2c21d84a3d16acdd9f876a6bd0f5045c3c04743 GIT binary patch literal 3212 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc-members.html new file mode 100644 index 000000000..3ad6d4a3a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc-members.html @@ -0,0 +1,123 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDelonghiAc Member List
+
+
+ +

This is the complete list of members for IRDelonghiAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDelonghiAcprivate
_saved_tempIRDelonghiAcprivate
_saved_temp_unitsIRDelonghiAcprivate
begin()IRDelonghiAc
calcChecksum(const uint64_t state)IRDelonghiAcstatic
calibrate(void)IRDelonghiAcinline
checksum(void)IRDelonghiAcprivate
convertFan(const stdAc::fanspeed_t speed)IRDelonghiAc
convertMode(const stdAc::opmode_t mode)IRDelonghiAc
getBoost()IRDelonghiAc
getFan()IRDelonghiAc
getMode()IRDelonghiAc
getOffTimer(void)IRDelonghiAc
getOffTimerEnabled(void)IRDelonghiAc
getOnTimer(void)IRDelonghiAc
getOnTimerEnabled(void)IRDelonghiAc
getPower()IRDelonghiAc
getRaw()IRDelonghiAc
getSleep()IRDelonghiAc
getTemp()IRDelonghiAc
getTempUnit(void)IRDelonghiAc
IRDelonghiAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDelonghiAcexplicit
off()IRDelonghiAc
on()IRDelonghiAc
remote_stateIRDelonghiAcprivate
send(const uint16_t repeat=kDelonghiAcDefaultRepeat)IRDelonghiAc
setBoost(const bool on)IRDelonghiAc
setFan(const uint8_t speed)IRDelonghiAc
setMode(const uint8_t mode)IRDelonghiAc
setOffTimer(const uint16_t nr_of_mins)IRDelonghiAc
setOffTimerEnabled(const bool on)IRDelonghiAc
setOnTimer(const uint16_t nr_of_mins)IRDelonghiAc
setOnTimerEnabled(const bool on)IRDelonghiAc
setPower(const bool on)IRDelonghiAc
setRaw(const uint64_t state)IRDelonghiAc
setSleep(const bool on)IRDelonghiAc
setTemp(const uint8_t temp, const bool fahrenheit=false, const bool force=false)IRDelonghiAc
setTempUnit(const bool celsius)IRDelonghiAc
stateReset()IRDelonghiAc
toCommon(void)IRDelonghiAc
toCommonFanSpeed(const uint8_t speed)IRDelonghiAcstatic
toCommonMode(const uint8_t mode)IRDelonghiAcstatic
toString()IRDelonghiAc
validChecksum(const uint64_t state)IRDelonghiAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc.html new file mode 100644 index 000000000..2657047f5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc.html @@ -0,0 +1,1370 @@ + + + + + + + +IRremoteESP8266: IRDelonghiAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Delonghi A/C messages. + More...

+ +

#include <ir_Delonghi.h>

+
+Collaboration diagram for IRDelonghiAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDelonghiAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kDelonghiAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower ()
 Get the value of the current power setting. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setTempUnit (const bool celsius)
 Change the temperature scale units. More...
 
bool getTempUnit (void)
 Get the temperature scale unit of measure currently in use. More...
 
void setTemp (const uint8_t temp, const bool fahrenheit=false, const bool force=false)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current native fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setBoost (const bool on)
 Set the Boost (Turbo) mode of the A/C. More...
 
bool getBoost ()
 Get the Boost (Turbo) mode of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep mode of the A/C. More...
 
bool getSleep ()
 Get the Sleep mode status of the A/C. More...
 
void setOnTimerEnabled (const bool on)
 Set the enable status of the On Timer. More...
 
bool getOnTimerEnabled (void)
 Get the enable status of the On Timer. More...
 
void setOnTimer (const uint16_t nr_of_mins)
 Set the On timer to activate in nr of minutes. More...
 
uint16_t getOnTimer (void)
 Get the On timer time. More...
 
void setOffTimerEnabled (const bool on)
 Set the enable status of the Off Timer. More...
 
bool getOffTimerEnabled (void)
 Get the enable status of the Off Timer. More...
 
void setOffTimer (const uint16_t nr_of_mins)
 Set the Off timer to activate in nr of minutes. More...
 
uint16_t getOffTimer (void)
 Get the Off timer time. More...
 
uint64_t getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint64_t state)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint64_t remote_state
 The state of the IR remote. More...
 
uint8_t _saved_temp
 The previously user requested temp value. More...
 
uint8_t _saved_temp_units
 The previously user requested temp units. More...
 
+

Detailed Description

+

Class for handling detailed Delonghi A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDelonghiAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDelonghiAc::IRDelonghiAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDelonghiAc::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDelonghiAc::calcChecksum (const uint64_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
A valid checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDelonghiAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDelonghiAc::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRDelonghiAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRDelonghiAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getBoost()

+ +
+
+ + + + + + + +
bool IRDelonghiAc::getBoost ()
+
+ +

Get the Boost (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRDelonghiAc::getFan ()
+
+ +

Get the current native fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRDelonghiAc::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRDelonghiAc::getOffTimer (void )
+
+ +

Get the Off timer time.

+
Returns
Total nr of mins before the device turns off.
+ +
+
+ +

◆ getOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDelonghiAc::getOffTimerEnabled (void )
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRDelonghiAc::getOnTimer (void )
+
+ +

Get the On timer time.

+
Returns
Total nr of mins before the device turns on.
+ +
+
+ +

◆ getOnTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDelonghiAc::getOnTimerEnabled (void )
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRDelonghiAc::getPower ()
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint64_t IRDelonghiAc::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + +
bool IRDelonghiAc::getSleep ()
+
+ +

Get the Sleep mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDelonghiAc::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in currently configured units/scale.
+ +
+
+ +

◆ getTempUnit()

+ +
+
+ + + + + + + + +
bool IRDelonghiAc::getTempUnit (void )
+
+ +

Get the temperature scale unit of measure currently in use.

+
Returns
true, is Fahrenheit. false, is Celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRDelonghiAc::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRDelonghiAc::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::send (const uint16_t repeat = kDelonghiAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setBoost()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setBoost (const bool on)
+
+ +

Set the Boost (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired native setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired native operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setOffTimer (const uint16_t nr_of_mins)
+
+ +

Set the Off timer to activate in nr of minutes.

+
Parameters
+ + +
[in]nr_of_minsTotal nr of mins to wait before turning off the device
+
+
+
Note
Max 23 hrs and 59 minutes. i.e. 1439 mins.
+ +
+
+ +

◆ setOffTimerEnabled()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setOffTimerEnabled (const bool on)
+
+ +

Set the enable status of the Off Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setOnTimer (const uint16_t nr_of_mins)
+
+ +

Set the On timer to activate in nr of minutes.

+
Parameters
+ + +
[in]nr_of_minsTotal nr of mins to wait before waking the device.
+
+
+
Note
Max 23 hrs and 59 minutes. i.e. 1439 mins.
+ +
+
+ +

◆ setOnTimerEnabled()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setOnTimerEnabled (const bool on)
+
+ +

Set the enable status of the On Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setRaw (const uint64_t state)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setSleep (const bool on)
+
+ +

Set the Sleep mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRDelonghiAc::setTemp (const uint8_t degrees,
const bool fahrenheit = false,
const bool force = false 
)
+
+ +

Set the temperature.

+
Parameters
+ + + + +
[in]degreesThe temperature in degrees.
[in]fahrenheitUse Fahrenheit as the temperature scale.
[in]forceDo we ignore any sanity checks?
+
+
+ +
+
+ +

◆ setTempUnit()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setTempUnit (const bool fahrenheit)
+
+ +

Change the temperature scale units.

+
Parameters
+ + +
[in]fahrenheittrue, use Fahrenheit. false, use Celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRDelonghiAc::stateReset ()
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDelonghiAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDelonghiAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDelonghiAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRDelonghiAc::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRDelonghiAc::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe state to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDelonghiAc::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ _saved_temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDelonghiAc::_saved_temp
+
+private
+
+ +

The previously user requested temp value.

+ +
+
+ +

◆ _saved_temp_units

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDelonghiAc::_saved_temp_units
+
+private
+
+ +

The previously user requested temp units.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRDelonghiAc::remote_state
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.map new file mode 100644 index 000000000..069782ed6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 new file mode 100644 index 000000000..58e961103 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 @@ -0,0 +1 @@ +e2babeacb4dc45c7ae998d66cca5b36e \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..1a0cb0d9fe80411bc3a29c02488ee3d95721d8b8 GIT binary patch literal 3457 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 RF5pZB(!QgI_^4qM`X3Ujkt6^B literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc-members.html new file mode 100644 index 000000000..b71c6923c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc-members.html @@ -0,0 +1,117 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRElectraAc Member List
+
+
+ +

This is the complete list of members for IRElectraAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRElectraAcprivate
begin(void)IRElectraAc
calcChecksum(const uint8_t state[], const uint16_t length=kElectraAcStateLength)IRElectraAcstatic
calibrate(void)IRElectraAcinline
checksum(const uint16_t length=kElectraAcStateLength)IRElectraAcprivate
convertFan(const stdAc::fanspeed_t speed)IRElectraAc
convertMode(const stdAc::opmode_t mode)IRElectraAc
getClean(void)IRElectraAc
getFan(void)IRElectraAc
getLightToggle(void)IRElectraAc
getMode(void)IRElectraAc
getPower(void)IRElectraAc
getRaw(void)IRElectraAc
getSwingH(void)IRElectraAc
getSwingV(void)IRElectraAc
getTemp(void)IRElectraAc
getTurbo(void)IRElectraAc
IRElectraAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRElectraAcexplicit
off(void)IRElectraAc
on(void)IRElectraAc
remote_stateIRElectraAcprivate
send(const uint16_t repeat=kElectraAcMinRepeat)IRElectraAc
setClean(const bool on)IRElectraAc
setFan(const uint8_t speed)IRElectraAc
setLightToggle(const bool on)IRElectraAc
setMode(const uint8_t mode)IRElectraAc
setPower(const bool on)IRElectraAc
setRaw(const uint8_t new_code[], const uint16_t length=kElectraAcStateLength)IRElectraAc
setSwingH(const bool on)IRElectraAc
setSwingV(const bool on)IRElectraAc
setTemp(const uint8_t temp)IRElectraAc
setTurbo(const bool on)IRElectraAc
stateReset(void)IRElectraAc
toCommon(void)IRElectraAc
toCommonFanSpeed(const uint8_t speed)IRElectraAcstatic
toCommonMode(const uint8_t mode)IRElectraAcstatic
toString(void)IRElectraAc
validChecksum(const uint8_t state[], const uint16_t length=kElectraAcStateLength)IRElectraAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc.html new file mode 100644 index 000000000..60c60c249 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc.html @@ -0,0 +1,1242 @@ + + + + + + + +IRremoteESP8266: IRElectraAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Electra A/C messages. + More...

+ +

#include <ir_Electra.h>

+
+Collaboration diagram for IRElectraAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRElectraAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kElectraAcMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingV (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingH (const bool on)
 Set the Horizontal Swing mode of the A/C. More...
 
bool getSwingH (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setClean (const bool on)
 Set the Clean mode of the A/C. More...
 
bool getClean (void)
 Get the Clean mode of the A/C. More...
 
void setLightToggle (const bool on)
 Set the Light (LED) Toggle mode of the A/C. More...
 
bool getLightToggle (void)
 Get the Light (LED) Toggle mode of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo mode of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kElectraAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kElectraAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kElectraAcStateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kElectraAcStateLength)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kElectraAcStateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Electra A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRElectraAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRElectraAc::IRElectraAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRElectraAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRElectraAc::calcChecksum (const uint8_t state[],
const uint16_t length = kElectraAcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe value to calc the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
The calculated checksum stored in a uint_8.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRElectraAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRElectraAc::checksum (const uint16_t length = kElectraAcStateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe length of the state array.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getClean (void )
+
+ +

Get the Clean mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getLightToggle()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getLightToggle (void )
+
+ +

Get the Light (LED) Toggle mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRElectraAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getSwingH (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getTurbo (void )
+
+ +

Get the Turbo mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRElectraAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRElectraAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRElectraAc::send (const uint16_t repeat = kElectraAcMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRElectraAc::setClean (const bool on)
+
+ +

Set the Clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRElectraAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+
Note
0 is auto, 1-3 is the speed
+ +
+
+ +

◆ setLightToggle()

+ +
+
+ + + + + + + + +
void IRElectraAc::setLightToggle (const bool on)
+
+ +

Set the Light (LED) Toggle mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRElectraAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRElectraAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRElectraAc::setRaw (const uint8_t new_code[],
const uint16_t length = kElectraAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the code array.
+
+
+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRElectraAc::setSwingH (const bool on)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRElectraAc::setSwingV (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRElectraAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRElectraAc::setTurbo (const bool on)
+
+ +

Set the Turbo mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRElectraAc::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRElectraAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRElectraAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRElectraAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRElectraAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRElectraAc::validChecksum (const uint8_t state[],
const uint16_t length = kElectraAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe state to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRElectraAc::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRElectraAc::remote_state[kElectraAcStateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.map new file mode 100644 index 000000000..2ca5c6051 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.md5 new file mode 100644 index 000000000..ec7416486 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.md5 @@ -0,0 +1 @@ +b6e5f96f14e5e22330cef83a09e5f30d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..e49f5d0ec77f1592c5866ed19cd0939087f865f4 GIT binary patch literal 3217 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 BVk!Ut literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC-members.html new file mode 100644 index 000000000..2c328bcf2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC-members.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRFujitsuAC Member List
+
+
+ +

This is the complete list of members for IRFujitsuAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_cleanIRFujitsuACprivate
_cmdIRFujitsuACprivate
_fanSpeedIRFujitsuACprivate
_filterIRFujitsuACprivate
_irsendIRFujitsuACprivate
_modeIRFujitsuACprivate
_modelIRFujitsuACprivate
_outsideQuietIRFujitsuACprivate
_state_lengthIRFujitsuACprivate
_state_length_shortIRFujitsuACprivate
_swingModeIRFujitsuACprivate
_tempIRFujitsuACprivate
begin(void)IRFujitsuAC
buildFromState(const uint16_t length)IRFujitsuACprivate
buildState(void)IRFujitsuACprivate
calibrate(void)IRFujitsuACinline
convertFan(stdAc::fanspeed_t speed)IRFujitsuAC
convertMode(const stdAc::opmode_t mode)IRFujitsuAC
getClean(const bool raw=false)IRFujitsuAC
getCmd(const bool raw=false)IRFujitsuAC
getFanSpeed(void)IRFujitsuAC
getFilter(const bool raw=false)IRFujitsuAC
getMode(void)IRFujitsuAC
getModel(void)IRFujitsuAC
getOutsideQuiet(const bool raw=false)IRFujitsuAC
getPower(void)IRFujitsuAC
getRaw(void)IRFujitsuAC
getStateLength(void)IRFujitsuAC
getSwing(const bool raw=false)IRFujitsuAC
getTemp(void)IRFujitsuAC
IRFujitsuAC(const uint16_t pin, const fujitsu_ac_remote_model_t model=ARRAH2E, const bool inverted=false, const bool use_modulation=true)IRFujitsuACexplicit
off(void)IRFujitsuAC
on(void)IRFujitsuAC
remote_stateIRFujitsuACprivate
send(const uint16_t repeat=kFujitsuAcMinRepeat)IRFujitsuAC
setClean(const bool on)IRFujitsuAC
setCmd(const uint8_t cmd)IRFujitsuAC
setFanSpeed(const uint8_t fan)IRFujitsuAC
setFilter(const bool on)IRFujitsuAC
setMode(const uint8_t mode)IRFujitsuAC
setModel(const fujitsu_ac_remote_model_t model)IRFujitsuAC
setOutsideQuiet(const bool on)IRFujitsuAC
setPower(const bool on)IRFujitsuAC
setRaw(const uint8_t newState[], const uint16_t length)IRFujitsuAC
setSwing(const uint8_t mode)IRFujitsuAC
setTemp(const uint8_t temp)IRFujitsuAC
stateReset(void)IRFujitsuAC
stepHoriz(void)IRFujitsuAC
stepVert(void)IRFujitsuAC
toCommon(void)IRFujitsuAC
toCommonFanSpeed(const uint8_t speed)IRFujitsuACstatic
toCommonMode(const uint8_t mode)IRFujitsuACstatic
toggleSwingHoriz(const bool update=true)IRFujitsuAC
toggleSwingVert(const bool update=true)IRFujitsuAC
toString(void)IRFujitsuAC
validChecksum(uint8_t *state, const uint16_t length)IRFujitsuACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC.html new file mode 100644 index 000000000..3259fb80e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC.html @@ -0,0 +1,1707 @@ + + + + + + + +IRremoteESP8266: IRFujitsuAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Fujitsu A/C messages. + More...

+ +

#include <ir_Fujitsu.h>

+
+Collaboration diagram for IRFujitsuAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRFujitsuAC (const uint16_t pin, const fujitsu_ac_remote_model_t model=ARRAH2E, const bool inverted=false, const bool use_modulation=true)
 Class Constructor. More...
 
void setModel (const fujitsu_ac_remote_model_t model)
 Set the currently emulated model of the A/C. More...
 
fujitsu_ac_remote_model_t getModel (void)
 Get the currently emulated/detected model of the A/C. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kFujitsuAcMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void stepHoriz (void)
 Request the A/C to step the Horizontal Swing. More...
 
void toggleSwingHoriz (const bool update=true)
 Request the A/C to toggle the Horizontal Swing mode. More...
 
void stepVert (void)
 Request the A/C to step the Vertical Swing. More...
 
void toggleSwingVert (const bool update=true)
 Request the A/C to toggle the Vertical Swing mode. More...
 
void setCmd (const uint8_t cmd)
 Set the requested (special) command part for the A/C message. More...
 
uint8_t getCmd (const bool raw=false)
 Set the requested (special) command part for the A/C message. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFanSpeed (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFanSpeed (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwing (const uint8_t mode)
 Set the requested swing operation mode of the A/C unit. More...
 
uint8_t getSwing (const bool raw=false)
 Get the requested swing operation mode of the A/C unit. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
bool setRaw (const uint8_t newState[], const uint16_t length)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t getStateLength (void)
 Get the length (size) of the state code for the current configuration. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setClean (const bool on)
 Set the Clean mode of the A/C. More...
 
bool getClean (const bool raw=false)
 Get the Clean mode status of the A/C. More...
 
void setFilter (const bool on)
 Set the Filter mode status of the A/C. More...
 
bool getFilter (const bool raw=false)
 Get the Filter mode status of the A/C. More...
 
void setOutsideQuiet (const bool on)
 Set the Outside Quiet mode of the A/C. More...
 
bool getOutsideQuiet (const bool raw=false)
 Get the Outside Quiet mode status of the A/C. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t *state, const uint16_t length)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void buildState (void)
 (Re)Build the state from the currently configured settings. More...
 
void buildFromState (const uint16_t length)
 Build the internal state/config from the current (raw) A/C message. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kFujitsuAcStateLength]
 The state of the IR remote. More...
 
uint8_t _temp
 
uint8_t _fanSpeed
 
uint8_t _mode
 
uint8_t _swingMode
 
uint8_t _cmd
 
fujitsu_ac_remote_model_t _model
 
uint8_t _state_length
 
uint8_t _state_length_short
 
bool _outsideQuiet
 
bool _clean
 
bool _filter
 
+

Detailed Description

+

Class for handling detailed Fujitsu A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRFujitsuAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IRFujitsuAC::IRFujitsuAC (const uint16_t pin,
const fujitsu_ac_remote_model_t model = ARRAH2E,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class Constructor.

+
Parameters
+ + + + + +
[in]pinGPIO to be used when sending.
[in]modelThe enum for the model of A/C to be emulated.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ buildFromState()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRFujitsuAC::buildFromState (const uint16_t length)
+
+private
+
+ +

Build the internal state/config from the current (raw) A/C message.

+
Parameters
+ + +
[in]lengthSize of the current/used (raw) A/C message array.
+
+
+ +
+
+ +

◆ buildState()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRFujitsuAC::buildState (void )
+
+private
+
+ +

(Re)Build the state from the currently configured settings.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRFujitsuAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::convertFan (stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRFujitsuAC::getClean (const bool raw = false)
+
+ +

Get the Clean mode status of the A/C.

+
Parameters
+ + +
[in]rawDo we get the result from base data?
+
+
+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getCmd()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getCmd (const bool raw = false)
+
+ +

Set the requested (special) command part for the A/C message.

+
Parameters
+ + +
[in]rawDo we need to get it from first principles from the raw data?
+
+
+
Returns
The special command code.
+ +
+
+ +

◆ getFanSpeed()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getFanSpeed (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getFilter()

+ +
+
+ + + + + + + + +
bool IRFujitsuAC::getFilter (const bool raw = false)
+
+ +

Get the Filter mode status of the A/C.

+
Parameters
+ + +
[in]rawDo we get the result from base data?
+
+
+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
fujitsu_ac_remote_model_t IRFujitsuAC::getModel (void )
+
+ +

Get the currently emulated/detected model of the A/C.

+
Returns
The enum representing the model of A/C.
+ +
+
+ +

◆ getOutsideQuiet()

+ +
+
+ + + + + + + + +
bool IRFujitsuAC::getOutsideQuiet (const bool raw = false)
+
+ +

Get the Outside Quiet mode status of the A/C.

+
Parameters
+ + +
[in]rawDo we get the result from base data?
+
+
+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRFujitsuAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRFujitsuAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getStateLength()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getStateLength (void )
+
+ +

Get the length (size) of the state code for the current configuration.

+
Returns
The length of the state array required for this config.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getSwing (const bool raw = false)
+
+ +

Get the requested swing operation mode of the A/C unit.

+
Parameters
+ + +
[in]rawDo we need to get it from first principles from the raw data?
+
+
+
Returns
The contents of the swing state/mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::send (const uint16_t repeat = kFujitsuAcMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setClean (const bool on)
+
+ +

Set the Clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setCmd()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setCmd (const uint8_t cmd)
+
+ +

Set the requested (special) command part for the A/C message.

+
Parameters
+ + +
[in]cmdThe special command code.
+
+
+ +
+
+ +

◆ setFanSpeed()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setFanSpeed (const uint8_t fanSpeed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanSpeedThe desired setting.
+
+
+ +
+
+ +

◆ setFilter()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setFilter (const bool on)
+
+ +

Set the Filter mode status of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setModel (const fujitsu_ac_remote_model_t model)
+
+ +

Set the currently emulated model of the A/C.

+
Parameters
+ + +
[in]modelAn enum representing the model to support/emulate.
+
+
+ +
+
+ +

◆ setOutsideQuiet()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setOutsideQuiet (const bool on)
+
+ +

Set the Outside Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
bool IRFujitsuAC::setRaw (const uint8_t newState[],
const uint16_t length 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]newStateA valid code for this protocol.
[in]lengthSize of the newState array.
+
+
+
Returns
true, if successful; Otherwise false. (i.e. size check)
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setSwing (const uint8_t swingMode)
+
+ +

Set the requested swing operation mode of the A/C unit.

+
Parameters
+ + +
[in]swingModeThe swingMode code for the A/C. Vertical, Horizon, or Both. See constants for details.
+
+
+
Note
Not all models support all possible swing modes.
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ stepHoriz()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::stepHoriz (void )
+
+ +

Request the A/C to step the Horizontal Swing.

+ +
+
+ +

◆ stepVert()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::stepVert (void )
+
+ +

Request the A/C to step the Vertical Swing.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRFujitsuAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRFujitsuAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRFujitsuAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toggleSwingHoriz()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::toggleSwingHoriz (const bool update = true)
+
+ +

Request the A/C to toggle the Horizontal Swing mode.

+
Parameters
+ + +
[in]updateDo we need to update the general swing config?
+
+
+ +
+
+ +

◆ toggleSwingVert()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::toggleSwingVert (const bool update = true)
+
+ +

Request the A/C to toggle the Vertical Swing mode.

+
Parameters
+ + +
[in]updateDo we need to update the general swing config?
+
+
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRFujitsuAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRFujitsuAC::validChecksum (uint8_t * state,
const uint16_t length 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _clean

+ +
+
+ + + + + +
+ + + + +
bool IRFujitsuAC::_clean
+
+private
+
+ +
+
+ +

◆ _cmd

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_cmd
+
+private
+
+ +
+
+ +

◆ _fanSpeed

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_fanSpeed
+
+private
+
+ +
+
+ +

◆ _filter

+ +
+
+ + + + + +
+ + + + +
bool IRFujitsuAC::_filter
+
+private
+
+ +
+
+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRFujitsuAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_mode
+
+private
+
+ +
+
+ +

◆ _model

+ +
+
+ + + + + +
+ + + + +
fujitsu_ac_remote_model_t IRFujitsuAC::_model
+
+private
+
+ +
+
+ +

◆ _outsideQuiet

+ +
+
+ + + + + +
+ + + + +
bool IRFujitsuAC::_outsideQuiet
+
+private
+
+ +
+
+ +

◆ _state_length

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_state_length
+
+private
+
+ +
+
+ +

◆ _state_length_short

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_state_length_short
+
+private
+
+ +
+
+ +

◆ _swingMode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_swingMode
+
+private
+
+ +
+
+ +

◆ _temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_temp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::remote_state[kFujitsuAcStateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.map new file mode 100644 index 000000000..3099d5f4a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 new file mode 100644 index 000000000..cbcc342bb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 @@ -0,0 +1 @@ +338c5a3ac726e2794d93445b33b8db6c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..595272976a81a342ff5b8756322a7fe06f26700a GIT binary patch literal 3164 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

+ + + + + + +IRremoteESP8266: Member List + + + + + + + + + +

+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRGoodweatherAc Member List
+
+
+ +

This is the complete list of members for IRGoodweatherAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRGoodweatherAcprivate
begin(void)IRGoodweatherAc
calibrate(void)IRGoodweatherAcinline
convertFan(const stdAc::fanspeed_t speed)IRGoodweatherAc
convertMode(const stdAc::opmode_t mode)IRGoodweatherAc
convertSwingV(const stdAc::swingv_t swingv)IRGoodweatherAc
getCommand(void)IRGoodweatherAc
getFan(void)IRGoodweatherAc
getLight(void)IRGoodweatherAc
getMode()IRGoodweatherAc
getPower(void)IRGoodweatherAc
getRaw(void)IRGoodweatherAc
getSleep(void)IRGoodweatherAc
getSwing(void)IRGoodweatherAc
getTemp(void)IRGoodweatherAc
getTurbo(void)IRGoodweatherAc
IRGoodweatherAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRGoodweatherAcexplicit
off(void)IRGoodweatherAc
on(void)IRGoodweatherAc
remoteIRGoodweatherAcprivate
send(const uint16_t repeat=kGoodweatherMinRepeat)IRGoodweatherAc
setCommand(const uint8_t cmd)IRGoodweatherAc
setFan(const uint8_t speed)IRGoodweatherAc
setLight(const bool toggle)IRGoodweatherAc
setMode(const uint8_t mode)IRGoodweatherAc
setPower(const bool on)IRGoodweatherAc
setRaw(const uint64_t state)IRGoodweatherAc
setSleep(const bool toggle)IRGoodweatherAc
setSwing(const uint8_t speed)IRGoodweatherAc
setTemp(const uint8_t temp)IRGoodweatherAc
setTurbo(const bool toggle)IRGoodweatherAc
stateReset(void)IRGoodweatherAc
toCommon(void)IRGoodweatherAc
toCommonFanSpeed(const uint8_t speed)IRGoodweatherAcstatic
toCommonMode(const uint8_t mode)IRGoodweatherAcstatic
toString()IRGoodweatherAc
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc.html new file mode 100644 index 000000000..d1d4643d4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc.html @@ -0,0 +1,1119 @@ + + + + + + + +IRremoteESP8266: IRGoodweatherAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Goodweather A/C messages. + More...

+ +

#include <ir_Goodweather.h>

+
+Collaboration diagram for IRGoodweatherAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRGoodweatherAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kGoodweatherMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setSwing (const uint8_t speed)
 Set the Vertical Swing speed of the A/C. More...
 
uint8_t getSwing (void)
 Get the Vertical Swing speed of the A/C. More...
 
void setSleep (const bool toggle)
 Set the Sleep Toggle setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep Toggle setting of the A/C. More...
 
void setTurbo (const bool toggle)
 Set the Turbo Toggle setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo Toggle setting of the A/C. More...
 
void setLight (const bool toggle)
 Set the Light (LED) Toggle setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED) Toggle setting of the A/C. More...
 
void setCommand (const uint8_t cmd)
 Set the remote Command type/button pressed. More...
 
uint8_t getCommand (void)
 Get the Command type/button pressed from the current settings. More...
 
uint64_t getRaw (void)
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint64_t state)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
uint8_t convertSwingV (const stdAc::swingv_t swingv)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote
 The state of the IR remote in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed Goodweather A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRGoodweatherAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRGoodweatherAc::IRGoodweatherAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRGoodweatherAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::convertSwingV (const stdAc::swingv_t swingv)
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]swingvThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getCommand()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::getCommand (void )
+
+ +

Get the Command type/button pressed from the current settings.

+
Returns
The command/button that was issued/pressed.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRGoodweatherAc::getLight (void )
+
+ +

Get the Light (LED) Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRGoodweatherAc::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRGoodweatherAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint64_t IRGoodweatherAc::getRaw (void )
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRGoodweatherAc::getSleep (void )
+
+ +

Get the Sleep Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::getSwing (void )
+
+ +

Get the Vertical Swing speed of the A/C.

+
Returns
The native swing speed setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRGoodweatherAc::getTurbo (void )
+
+ +

Get the Turbo Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::send (const uint16_t repeat = kGoodweatherMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setCommand()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setCommand (const uint8_t cmd)
+
+ +

Set the remote Command type/button pressed.

+
Parameters
+ + +
[in]cmdThe command/button that was issued/pressed.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setLight (const bool toggle)
+
+ +

Set the Light (LED) Toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setRaw (const uint64_t state)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setSleep (const bool toggle)
+
+ +

Set the Sleep Toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setSwing (const uint8_t speed)
+
+ +

Set the Vertical Swing speed of the A/C.

+
Parameters
+ + +
[in]speedThe speed to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setTurbo (const bool toggle)
+
+ +

Set the Turbo Toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRGoodweatherAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRGoodweatherAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRGoodweatherAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRGoodweatherAc::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRGoodweatherAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote

+ +
+
+ + + + + +
+ + + + +
uint64_t IRGoodweatherAc::remote
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map new file mode 100644 index 000000000..660cc0842 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 new file mode 100644 index 000000000..960e5d2a0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 @@ -0,0 +1 @@ +bce379f76240220988c09046a0d5f283 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..b9f6e66cbcbaa16378d20cb12863238be65e269d GIT binary patch literal 4102 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 M_q3HO6m5e41NUhA00000 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC-members.html new file mode 100644 index 000000000..7c4b5e991 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC-members.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRGreeAC Member List
+
+
+ +

This is the complete list of members for IRGreeAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRGreeACprivate
_modelIRGreeACprivate
begin(void)IRGreeAC
calibrate(void)IRGreeACinline
checksum(const uint16_t length=kGreeStateLength)IRGreeACprivate
convertFan(const stdAc::fanspeed_t speed)IRGreeAC
convertMode(const stdAc::opmode_t mode)IRGreeAC
convertSwingV(const stdAc::swingv_t swingv)IRGreeAC
fixup(void)IRGreeACprivate
getDisplayTempSource(void)IRGreeAC
getFan(void)IRGreeAC
getIFeel(void)IRGreeAC
getLight(void)IRGreeAC
getMode(void)IRGreeAC
getModel(void)IRGreeAC
getPower(void)IRGreeAC
getRaw(void)IRGreeAC
getSleep(void)IRGreeAC
getSwingVerticalAuto(void)IRGreeAC
getSwingVerticalPosition(void)IRGreeAC
getTemp(void)IRGreeAC
getTimer(void)IRGreeAC
getTimerEnabled(void)IRGreeACprivate
getTurbo(void)IRGreeAC
getUseFahrenheit(void)IRGreeAC
getWiFi(void)IRGreeAC
getXFan(void)IRGreeAC
IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model=gree_ac_remote_model_t::YAW1F, const bool inverted=false, const bool use_modulation=true)IRGreeACexplicit
off(void)IRGreeAC
on(void)IRGreeAC
remote_stateIRGreeACprivate
send(const uint16_t repeat=kGreeDefaultRepeat)IRGreeAC
setDisplayTempSource(const uint8_t mode)IRGreeAC
setFan(const uint8_t speed)IRGreeAC
setIFeel(const bool on)IRGreeAC
setLight(const bool on)IRGreeAC
setMode(const uint8_t new_mode)IRGreeAC
setModel(const gree_ac_remote_model_t model)IRGreeAC
setPower(const bool on)IRGreeAC
setRaw(const uint8_t new_code[])IRGreeAC
setSleep(const bool on)IRGreeAC
setSwingVertical(const bool automatic, const uint8_t position)IRGreeAC
setTemp(const uint8_t temp, const bool fahrenheit=false)IRGreeAC
setTimer(const uint16_t minutes)IRGreeAC
setTimerEnabled(const bool on)IRGreeACprivate
setTurbo(const bool on)IRGreeAC
setUseFahrenheit(const bool on)IRGreeAC
setWiFi(const bool on)IRGreeAC
setXFan(const bool on)IRGreeAC
stateReset(void)IRGreeAC
toCommon(void)IRGreeAC
toCommonFanSpeed(const uint8_t speed)IRGreeACstatic
toCommonMode(const uint8_t mode)IRGreeACstatic
toCommonSwingV(const uint8_t pos)IRGreeACstatic
toString(void)IRGreeAC
validChecksum(const uint8_t state[], const uint16_t length=kGreeStateLength)IRGreeACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC.html new file mode 100644 index 000000000..caaba0c2d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC.html @@ -0,0 +1,1751 @@ + + + + + + + +IRremoteESP8266: IRGreeAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Gree A/C messages. + More...

+ +

#include <ir_Gree.h>

+
+Collaboration diagram for IRGreeAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRGreeAC (const uint16_t pin, const gree_ac_remote_model_t model=gree_ac_remote_model_t::YAW1F, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kGreeDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setModel (const gree_ac_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
gree_ac_remote_model_t getModel (void)
 Get/Detect the model of the A/C. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp, const bool fahrenheit=false)
 Set the temp. in degrees. More...
 
uint8_t getTemp (void)
 Get the set temperature. More...
 
void setUseFahrenheit (const bool on)
 Set the default temperature units to use. More...
 
bool getUseFahrenheit (void)
 Get the default temperature units in use. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t new_mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light (LED) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED) setting of the A/C. More...
 
void setXFan (const bool on)
 Set the XFan (Mould) setting of the A/C. More...
 
bool getXFan (void)
 Get the XFan (Mould) setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setIFeel (const bool on)
 Set the IFeel setting of the A/C. More...
 
bool getIFeel (void)
 Get the IFeel setting of the A/C. More...
 
void setWiFi (const bool on)
 Set the Wifi (enabled) setting of the A/C. More...
 
bool getWiFi (void)
 Get the Wifi (enabled) setting of the A/C. More...
 
void setSwingVertical (const bool automatic, const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVerticalAuto (void)
 Get the Vertical Swing Automatic mode setting of the A/C. More...
 
uint8_t getSwingVerticalPosition (void)
 Get the Vertical Swing position setting of the A/C. More...
 
uint16_t getTimer (void)
 Get the timer time value from the A/C. More...
 
void setTimer (const uint16_t minutes)
 Set the A/C's timer to turn off in X many minutes. More...
 
void setDisplayTempSource (const uint8_t mode)
 Set temperature display mode. i.e. Internal, External temperature sensing. More...
 
uint8_t getDisplayTempSource (void)
 Get the temperature display mode. i.e. Internal, External temperature sensing. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
uint8_t convertSwingV (const stdAc::swingv_t swingv)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static bool validChecksum (const uint8_t state[], const uint16_t length=kGreeStateLength)
 Verify the checksum is valid for a given state. More...
 
+ + + + + + + + + + + + + +

+Private Member Functions

void checksum (const uint16_t length=kGreeStateLength)
 Calculate and set the checksum values for the internal state. More...
 
void fixup (void)
 Fix up the internal state so it is correct. More...
 
void setTimerEnabled (const bool on)
 Set the timer enable setting of the A/C. More...
 
bool getTimerEnabled (void)
 Get the timer enabled setting of the A/C. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kGreeStateLength]
 The state in native IR code form. More...
 
gree_ac_remote_model_t _model
 
+

Detailed Description

+

Class for handling detailed Gree A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRGreeAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IRGreeAC::IRGreeAC (const uint16_t pin,
const gree_ac_remote_model_t model = gree_ac_remote_model_t::YAW1F,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + + +
[in]pinGPIO to be used when sending.
[in]modelThe enum of the model to be emulated.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRGreeAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRGreeAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRGreeAC::checksum (const uint16_t length = kGreeStateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe size/length of the state array to fix the checksum of.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::convertSwingV (const stdAc::swingv_t swingv)
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]swingvThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ fixup()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRGreeAC::fixup (void )
+
+private
+
+ +

Fix up the internal state so it is correct.

+
Note
Internal use only.
+ +
+
+ +

◆ getDisplayTempSource()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getDisplayTempSource (void )
+
+ +

Get the temperature display mode. i.e. Internal, External temperature sensing.

+
Returns
The current temp source being displayed.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getIFeel()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getIFeel (void )
+
+ +

Get the IFeel setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getLight (void )
+
+ +

Get the Light (LED) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
gree_ac_remote_model_t IRGreeAC::getModel (void )
+
+ +

Get/Detect the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/814
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRGreeAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVerticalAuto()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getSwingVerticalAuto (void )
+
+ +

Get the Vertical Swing Automatic mode setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVerticalPosition()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getSwingVerticalPosition (void )
+
+ +

Get the Vertical Swing position setting of the A/C.

+
Returns
The native position/mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getTemp (void )
+
+ +

Get the set temperature.

+
Returns
The temperature in degrees in the current units (C/F) set.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint16_t IRGreeAC::getTimer (void )
+
+ +

Get the timer time value from the A/C.

+
Returns
The number of minutes the timer is set for.
+ +
+
+ +

◆ getTimerEnabled()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRGreeAC::getTimerEnabled (void )
+
+private
+
+ +

Get the timer enabled setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getUseFahrenheit()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getUseFahrenheit (void )
+
+ +

Get the default temperature units in use.

+
Returns
true is Fahrenheit, false is Celsius.
+ +
+
+ +

◆ getWiFi()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getWiFi (void )
+
+ +

Get the Wifi (enabled) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getXFan()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getXFan (void )
+
+ +

Get the XFan (Mould) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRGreeAC::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRGreeAC::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRGreeAC::send (const uint16_t repeat = kGreeDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setDisplayTempSource()

+ +
+
+ + + + + + + + +
void IRGreeAC::setDisplayTempSource (const uint8_t mode)
+
+ +

Set temperature display mode. i.e. Internal, External temperature sensing.

+
Parameters
+ + +
[in]modeThe desired temp source to display.
+
+
+
Note
In order for the A/C unit properly accept these settings. You must cycle (send) in the following order: kGreeDisplayTempOff(0) -> kGreeDisplayTempSet(1) -> kGreeDisplayTempInside(2) ->kGreeDisplayTempOutside(3) -> kGreeDisplayTempOff(0). The unit will no behave correctly if the changes of this setting are sent out of order.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1118#issuecomment-628242152
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRGreeAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting. 0 is auto, 1-3 is the speed.
+
+
+ +
+
+ +

◆ setIFeel()

+ +
+
+ + + + + + + + +
void IRGreeAC::setIFeel (const bool on)
+
+ +

Set the IFeel setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRGreeAC::setLight (const bool on)
+
+ +

Set the Light (LED) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRGreeAC::setMode (const uint8_t new_mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]new_modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRGreeAC::setModel (const gree_ac_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRGreeAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/814
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRGreeAC::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRGreeAC::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRGreeAC::setSwingVertical (const bool automatic,
const uint8_t position 
)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + + +
[in]automaticDo we use the automatic setting?
[in]positionThe position/mode to set the vanes to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRGreeAC::setTemp (const uint8_t temp,
const bool fahrenheit = false 
)
+
+ +

Set the temp. in degrees.

+
Parameters
+ + + +
[in]tempDesired temperature in Degrees.
[in]fahrenheitUse units of Fahrenheit and set that as units used. false is Celsius (Default), true is Fahrenheit.
+
+
+
Note
The unit actually works in Celsius with a special optional "extra degree" when sending Fahrenheit.
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRGreeAC::setTimer (const uint16_t minutes)
+
+ +

Set the A/C's timer to turn off in X many minutes.

+
Parameters
+ + +
[in]minutesThe number of minutes the timer should be set for.
+
+
+
Note
Stores time internally in 30 min units. e.g. 5 mins means 0 (& Off), 95 mins is 90 mins (& On). Max is 24 hours.
+ +
+
+ +

◆ setTimerEnabled()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRGreeAC::setTimerEnabled (const bool on)
+
+private
+
+ +

Set the timer enable setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRGreeAC::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setUseFahrenheit()

+ +
+
+ + + + + + + + +
void IRGreeAC::setUseFahrenheit (const bool on)
+
+ +

Set the default temperature units to use.

+
Parameters
+ + +
[in]onUse Fahrenheit as the units. true is Fahrenheit, false is Celsius.
+
+
+ +
+
+ +

◆ setWiFi()

+ +
+
+ + + + + + + + +
void IRGreeAC::setWiFi (const bool on)
+
+ +

Set the Wifi (enabled) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setXFan()

+ +
+
+ + + + + + + + +
void IRGreeAC::setXFan (const bool on)
+
+ +

Set the XFan (Mould) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRGreeAC::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRGreeAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRGreeAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRGreeAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRGreeAC::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]posThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRGreeAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRGreeAC::validChecksum (const uint8_t state[],
const uint16_t length = kGreeStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRGreeAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _model

+ +
+
+ + + + + +
+ + + + +
gree_ac_remote_model_t IRGreeAC::_model
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRGreeAC::remote_state[kGreeStateLength]
+
+private
+
+ +

The state in native IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.map new file mode 100644 index 000000000..71a32c740 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.md5 new file mode 100644 index 000000000..4d1a33b48 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.md5 @@ -0,0 +1 @@ +cef6b5570dcbcd982fca1b3f3abc0c0f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..c78390eebc51ee81105020d674027ec02a9bc1c0 GIT binary patch literal 3146 zcmZ8kcT`i^_6~!9Qbv$~AVn!A5R|4uNa#g~KvaejjR8cYH>C&(iawfj22|jMA{szI zgAhO<^b#R7DM1hhAp?Sh7J8`f&YSnvZ@u5T>)!p(Ugz%feP{3QJ8?JA=0f~u_(33$ z5X!>T28f=(8*!W$_$~@9)&qgp#nRjqboAHrx}hi?1QIwxnHt%KW-sMDzF{}p_%ttC zf~PZIS;YMk(WFO4?=nw_#53uOlFH}QMFhPeF`hw%U>H84l`W^Qr9>21%PDVJiaD4xco%F2J~p;^K*zg{^fAn-YusU z>WIIx@$qLd3W4oilOi5gNf6X8mr&?34?uHas<}8$!d3bwMej?l|pP<$AG`6yQj%3D4;AYrL@UP{PAz578dAjCk=W|JB4dFOj|_b zwn@Xowo$?x8yg>kS@vmZY41u)Dee}(#+gVj-@)O=8XqI$-vk`)hXwC8KHghhUvKN} zO=6TftPfo`D83&V8A&QEWU^QZMMY2z4UIcB0Y(>3^7G59s3fee2I%VQVyb;4q1SV5 zyO9XQ^SHQ{wzkNpPeIADdI)VPB)7Ej;FmAL91ce*-Z&sY9V8?qL@Fu@T%9t)69{2* zIgjAsJ0I(;Y-~;?B_-L~**#!0&0eWFq3_(0wlB5InOpBSfI^|MeSK)4^3X%h9EY-Z zK||wr>PjQAun=P-dWJRa2ufPWGTMkX)<;BR6#+3 zS8a>4u%DkFGsEdg)(r5U2>>pdj1O(9n15e7wBzkG?;4xVXY%i9S_7lk}#z z7zJVu7Fc?5ihnCQcCL;}EvmvjRf56(Iifj48kOrq;c&Qi8m+>;U-qiGITwK4pR3bt zuCA`a($YNwYW2eW_T3WB=|Z3x!4(=I1}l&zI}VL7D?JxKYCB!JNH4 ziWdWBV`DSFyi9XePtD5G;lt`&lD>MXIavlNapsK6(cyva*66)ZJpPoJSVzP5q@|yq zYDY&$4VB7$?=(+$h8h$G<5yEt3t1dBdiYRNRaNyCsa^aIWic(E9s4|d!k$(_{}(5~>XsI9;zg{wzL zw%;%#?w_Cgqy(i2LiuR9@jKjiqmv_qG$-84oo;AdMWB*q8;;YQQepfOu;mGpT-!9O z4D#S+!ifhslSl^4;{r9XY>kvQyr1&q1&{i4)kUs9j%1nJTgdf7dl*Wn;4#MkVbxNl zVSX*Mul{N3)j>m+*e)@48nUD?B4Tte4$?)w95J4fzCN>3R3g8kPWpWqGno+Vy5L6p z5wX#4bUCm)5!*7CmM<%iaP))5Y^p6DB5$O8`Tj7vAf+aS_-I)EK7mcL80YtUH$N9~ zSQ`DIDrFQ2#wxh0?1Y>AHJ<*5mZkGM0eR7lG?jT{@i8DR(DXKH{rHkTiuW=qWX3)n z-K&Di&(8-=`6x2cQ^AazPSfXd^RH6EJ2(-o8g3T z8&t+ZI?B%( z-mR37l@(_&81j00xEupjRkW#@*@?)Ob5Hh`wApl(vgcwd_Rj|fZdU0xII8vK>Zw>k z(mVV5#2pxkH9s4y&F-w(Vj%(h|{O{j9F9s^0 z#>U1LY9b*y75={{nH!dUEp3vy@^iSpu8u1573u`E@OdpQ@lpmo-y{}8aTAh}k?|TV zCX-c{fobMhHusJ6TSR;vgY?__lk0Wj=GKS;R2?r6&iitgZk>ydF_HT~Du{Rl-90$E z@fnN7GD^v;*qIsEJsyOB1)+v$?h%WW{J*~VOMk4>j#;P_zYR%U^G(|N^&UFaeh}bf zi_$cXOw=&~_&5P%{8wE5X0H+__H7S!COK*(Pm%k782xKO&-1-Sholq!b`nWfpX{^E z3GJE}FKjLg=4@84XlEC;_&$!^+SPs)A0JO^9G;$vOc>I0DNpEIelW2RAO-%uaX_Ne z>BM+OO>jv`$tcCW-6c_kx1|Uoa@WsZtm#d$w7an z^y_!m1+!=u9h{u{0UY5Ghq{pTxbv2;gu&qUAHBqZpFtFnZzQm|_}b5+ytJ&WF460{ z8u|5&jk&F@#tRDz>crmpAjHTA>}Oh%ls`vrY^>RhU=tp$`|{;WX=F%ZQ7%6I(D}FN$;m%<*nf)By}i6f zYXhPB`ua0-bAgMa8jcYM!B!Aa;Mi%Utlaj={oK;g5nWRQUt3?-kPzJAaO9$#S0)=w z&CMyk<66OvIp|n)kpc{MEvNc^x45y1NpWfETVND#Yy`EowkjzpO>O)f%Cv&W;^*ZC z2L~|~t|!!AO}JD%lt};RF(4nZ^sNKfzo(~XOMm}K3DHa<(K0CLvRcDNT3upZ-dSw5 zPx+>k78fxuy~pj6Q^diQ_%|PY#xy~yj`bGq?sGyXHME)SaiTtd)V&-Wv}tW?3)@@z zZh6_S z@#v7Csi}#n3sNSN$@M$Tgvw8!h6V>U@9P-)`>O%&U;#f;=F|^JbP=St=4SX-yIU-E zXD1ZUBnb(LbK2S&{rY=}FI60vGc!>|bEEDb33&W4SXD$s#MIRE1{Q0H$M4qEk$XQ6 z4GeG@8XLDp1&4%$Xu{!ePY(AFViqb#_kG z&gH(Xug}iRl-R)QO-@eQ+S&>W3#;Fk`TFCCy|s1qCb*IFLke(2ke+b{Gp%MCE<{Z$n>m7MvvDZ}{NSgf*=((95Ex_tygD2qZIOOnzCme6^?JO+}Jlbe~H z9hjU%U%SRXFficry)mb{T5B@m=m5o{_w<;SeWeh#{j_{Wn*m?=JTcLAx;6T@S7!~L zWT&R4o(M(&+`Dw}0}c#?seO1JXb`{~KJy)~W^W8#U#Cg=Pc1K_F__T{N67R`)6< + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHaierAC Member List
+
+
+ +

This is the complete list of members for IRHaierAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHaierACprivate
begin(void)IRHaierAC
calibrate(void)IRHaierACinline
cancelTimers(void)IRHaierAC
checksum(void)IRHaierACprivate
convertFan(const stdAc::fanspeed_t speed)IRHaierAC
convertMode(const stdAc::opmode_t mode)IRHaierAC
convertSwingV(const stdAc::swingv_t position)IRHaierAC
getCommand(void)IRHaierAC
getCurrTime(void)IRHaierAC
getFan(void)IRHaierAC
getHealth(void)IRHaierAC
getMode(void)IRHaierAC
getOffTimer(void)IRHaierAC
getOnTimer(void)IRHaierAC
getRaw(void)IRHaierAC
getSleep(void)IRHaierAC
getSwing(void)IRHaierAC
getTemp(void)IRHaierAC
getTime(const uint8_t ptr[])IRHaierACprivatestatic
IRHaierAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHaierACexplicit
remote_stateIRHaierACprivate
send(const uint16_t repeat=kHaierAcDefaultRepeat)IRHaierAC
setCommand(const uint8_t command)IRHaierAC
setCurrTime(const uint16_t mins)IRHaierAC
setFan(const uint8_t speed)IRHaierAC
setHealth(const bool on)IRHaierAC
setMode(const uint8_t mode)IRHaierAC
setOffTimer(const uint16_t mins)IRHaierAC
setOnTimer(const uint16_t mins)IRHaierAC
setRaw(const uint8_t new_code[])IRHaierAC
setSleep(const bool on)IRHaierAC
setSwing(const uint8_t state)IRHaierAC
setTemp(const uint8_t temp)IRHaierAC
setTime(uint8_t ptr[], const uint16_t nr_mins)IRHaierACprivatestatic
stateReset(void)IRHaierACprivate
toCommon(void)IRHaierAC
toCommonFanSpeed(const uint8_t speed)IRHaierACstatic
toCommonMode(const uint8_t mode)IRHaierACstatic
toCommonSwingV(const uint8_t pos)IRHaierACstatic
toString(void)IRHaierAC
validChecksum(uint8_t state[], const uint16_t length=kHaierACStateLength)IRHaierACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC.html new file mode 100644 index 000000000..cd27c878e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC.html @@ -0,0 +1,1370 @@ + + + + + + + +IRremoteESP8266: IRHaierAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Haier A/C messages. + More...

+ +

#include <ir_Haier.h>

+
+Collaboration diagram for IRHaierAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHaierAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kHaierAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void setCommand (const uint8_t command)
 Set the Command/Button setting of the A/C. More...
 
uint8_t getCommand (void)
 Get the Command/Button setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getHealth (void)
 Get the Health (filter) setting of the A/C. More...
 
void setHealth (const bool on)
 Set the Health (filter) setting of the A/C. More...
 
int16_t getOnTimer (void)
 Get the On Timer value/setting of the A/C. More...
 
void setOnTimer (const uint16_t mins)
 Set & enable the On Timer. More...
 
int16_t getOffTimer (void)
 Get the Off Timer value/setting of the A/C. More...
 
void setOffTimer (const uint16_t mins)
 Set & enable the Off Timer. More...
 
void cancelTimers (void)
 Cancel/disable the On & Off timers. More...
 
uint16_t getCurrTime (void)
 Get the clock value of the A/C. More...
 
void setCurrTime (const uint16_t mins)
 Set the clock value for the A/C. More...
 
uint8_t getSwing (void)
 Get the Vertical Swing position setting of the A/C. More...
 
void setSwing (const uint8_t state)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kHaierACStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Static Private Member Functions

static uint16_t getTime (const uint8_t ptr[])
 Get the Time value at the given pointer. More...
 
static void setTime (uint8_t ptr[], const uint16_t nr_mins)
 Set the Time value at the given pointer. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHaierACStateLength]
 The state in native code form. More...
 
+

Detailed Description

+

Class for handling detailed Haier A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHaierAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHaierAC::IRHaierAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHaierAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHaierAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ cancelTimers()

+ +
+
+ + + + + + + + +
void IRHaierAC::cancelTimers (void )
+
+ +

Cancel/disable the On & Off timers.

+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHaierAC::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::convertSwingV (const stdAc::swingv_t position)
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getCommand()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getCommand (void )
+
+ +

Get the Command/Button setting of the A/C.

+
Returns
The value of the command/button that was pressed.
+ +
+
+ +

◆ getCurrTime()

+ +
+
+ + + + + + + + +
uint16_t IRHaierAC::getCurrTime (void )
+
+ +

Get the clock value of the A/C.

+
Returns
The clock time, in Nr of minutes past midnight.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getHealth()

+ +
+
+ + + + + + + + +
bool IRHaierAC::getHealth (void )
+
+ +

Get the Health (filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
int16_t IRHaierAC::getOffTimer (void )
+
+ +

Get the Off Timer value/setting of the A/C.

+
Returns
Nr of minutes the timer is set to. -1 is Off/not set etc.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
int16_t IRHaierAC::getOnTimer (void )
+
+ +

Get the On Timer value/setting of the A/C.

+
Returns
Nr of minutes the timer is set to. -1 is Off/not set etc.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHaierAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRHaierAC::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getSwing (void )
+
+ +

Get the Vertical Swing position setting of the A/C.

+
Returns
The native swing mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTime()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRHaierAC::getTime (const uint8_t ptr[])
+
+staticprivate
+
+ +

Get the Time value at the given pointer.

+
Parameters
+ + +
[in]ptrA Ptr to a location in the internal state to get the time.
+
+
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHaierAC::send (const uint16_t repeat = kHaierAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setCommand()

+ +
+
+ + + + + + + + +
void IRHaierAC::setCommand (const uint8_t command)
+
+ +

Set the Command/Button setting of the A/C.

+
Parameters
+ + +
[in]commandThe value of the command/button that was pressed.
+
+
+ +
+
+ +

◆ setCurrTime()

+ +
+
+ + + + + + + + +
void IRHaierAC::setCurrTime (const uint16_t nr_mins)
+
+ +

Set the clock value for the A/C.

+
Parameters
+ + +
[in]nr_minsThe clock time, in Nr of minutes past midnight.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRHaierAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setHealth()

+ +
+
+ + + + + + + + +
void IRHaierAC::setHealth (const bool on)
+
+ +

Set the Health (filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHaierAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRHaierAC::setOffTimer (const uint16_t nr_mins)
+
+ +

Set & enable the Off Timer.

+
Parameters
+ + +
[in]nr_minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRHaierAC::setOnTimer (const uint16_t nr_mins)
+
+ +

Set & enable the On Timer.

+
Parameters
+ + +
[in]nr_minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRHaierAC::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRHaierAC::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRHaierAC::setSwing (const uint8_t cmd)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]cmdThe mode to set the vanes to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRHaierAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRHaierAC::setTime (uint8_t ptr[],
const uint16_t nr_mins 
)
+
+staticprivate
+
+ +

Set the Time value at the given pointer.

+
Parameters
+ + + +
[out]ptrA Ptr to a location in the internal state to set the time.
[in]nr_minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHaierAC::stateReset (void )
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRHaierAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHaierAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHaierAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRHaierAC::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]posThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHaierAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHaierAC::validChecksum (uint8_t state[],
const uint16_t length = kHaierACStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHaierAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHaierAC::remote_state[kHaierACStateLength]
+
+private
+
+ +

The state in native code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02-members.html new file mode 100644 index 000000000..2cd4356de --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02-members.html @@ -0,0 +1,118 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHaierACYRW02 Member List
+
+
+ +

This is the complete list of members for IRHaierACYRW02, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHaierACYRW02private
begin(void)IRHaierACYRW02
calibrate(void)IRHaierACYRW02inline
checksum(void)IRHaierACYRW02private
convertFan(const stdAc::fanspeed_t speed)IRHaierACYRW02
convertMode(const stdAc::opmode_t mode)IRHaierACYRW02
convertSwingV(const stdAc::swingv_t position)IRHaierACYRW02
getButton(void)IRHaierACYRW02
getFan(void)IRHaierACYRW02
getHealth(void)IRHaierACYRW02
getMode(void)IRHaierACYRW02
getPower(void)IRHaierACYRW02
getRaw(void)IRHaierACYRW02
getSleep(void)IRHaierACYRW02
getSwing(void)IRHaierACYRW02
getTemp(void)IRHaierACYRW02
getTurbo(void)IRHaierACYRW02
IRHaierACYRW02(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHaierACYRW02explicit
off(void)IRHaierACYRW02
on(void)IRHaierACYRW02
remote_stateIRHaierACYRW02private
send(const uint16_t repeat=kHaierAcYrw02DefaultRepeat)IRHaierACYRW02
setButton(const uint8_t button)IRHaierACYRW02
setFan(const uint8_t speed)IRHaierACYRW02
setHealth(const bool on)IRHaierACYRW02
setMode(const uint8_t mode)IRHaierACYRW02
setPower(const bool on)IRHaierACYRW02
setRaw(const uint8_t new_code[])IRHaierACYRW02
setSleep(const bool on)IRHaierACYRW02
setSwing(const uint8_t pos)IRHaierACYRW02
setTemp(const uint8_t temp)IRHaierACYRW02
setTurbo(const uint8_t speed)IRHaierACYRW02
stateReset(void)IRHaierACYRW02private
toCommon(void)IRHaierACYRW02
toCommonFanSpeed(const uint8_t speed)IRHaierACYRW02static
toCommonMode(const uint8_t mode)IRHaierACYRW02static
toCommonSwingV(const uint8_t pos)IRHaierACYRW02static
toString(void)IRHaierACYRW02
validChecksum(uint8_t state[], const uint16_t length=kHaierACYRW02StateLength)IRHaierACYRW02static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02.html new file mode 100644 index 000000000..0bde44c52 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02.html @@ -0,0 +1,1252 @@ + + + + + + + +IRremoteESP8266: IRHaierACYRW02 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Haier ACYRW02 A/C messages. + More...

+ +

#include <ir_Haier.h>

+
+Collaboration diagram for IRHaierACYRW02:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHaierACYRW02 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kHaierAcYrw02DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void setButton (const uint8_t button)
 Set the Button/Command setting of the A/C. More...
 
uint8_t getButton (void)
 Get the Button/Command setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getHealth (void)
 Get the Health (filter) setting of the A/C. More...
 
void setHealth (const bool on)
 Set the Health (filter) setting of the A/C. More...
 
uint8_t getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setTurbo (const uint8_t speed)
 Set the Turbo setting of the A/C. More...
 
uint8_t getSwing (void)
 Get the Vertical Swing position setting of the A/C. More...
 
void setSwing (const uint8_t pos)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kHaierACYRW02StateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHaierACYRW02StateLength]
 The state in native form. More...
 
+

Detailed Description

+

Class for handling detailed Haier ACYRW02 A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHaierACYRW02()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHaierACYRW02::IRHaierACYRW02 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHaierACYRW02::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHaierACYRW02::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::convertSwingV (const stdAc::swingv_t position)
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getButton()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getButton (void )
+
+ +

Get the Button/Command setting of the A/C.

+
Returns
The value of the button/command that was pressed.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getHealth()

+ +
+
+ + + + + + + + +
bool IRHaierACYRW02::getHealth (void )
+
+ +

Get the Health (filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRHaierACYRW02::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHaierACYRW02::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRHaierACYRW02::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getSwing (void )
+
+ +

Get the Vertical Swing position setting of the A/C.

+
Returns
The native position/mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
The current turbo speed setting.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::send (const uint16_t repeat = kHaierAcYrw02DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setButton()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setButton (const uint8_t button)
+
+ +

Set the Button/Command setting of the A/C.

+
Parameters
+ + +
[in]buttonThe value of the button/command that was pressed.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setHealth()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setHealth (const bool on)
+
+ +

Set the Health (filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setSwing (const uint8_t pos)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the vanes to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setTemp (const uint8_t celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setTurbo (const uint8_t speed)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]speedThe desired turbo speed setting.
+
+
+
Note
Valid speeds are kHaierAcYrw02TurboOff, kHaierAcYrw02TurboLow, & kHaierAcYrw02TurboHigh.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHaierACYRW02::stateReset (void )
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRHaierACYRW02::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHaierACYRW02::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHaierACYRW02::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRHaierACYRW02::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]posThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHaierACYRW02::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHaierACYRW02::validChecksum (uint8_t state[],
const uint16_t length = kHaierACYRW02StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHaierACYRW02::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHaierACYRW02::remote_state[kHaierACYRW02StateLength]
+
+private
+
+ +

The state in native form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map new file mode 100644 index 000000000..02f95a3ca --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 new file mode 100644 index 000000000..cb292bd5a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 @@ -0,0 +1 @@ +cb076b246ab80c7206b22b94a46f6e24 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..2075e7a09e203a551ee397c1e785d8788b9ea9ea GIT binary patch literal 4003 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 SkAYJ+MEj1Oda3H87ykoKu-#bz literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.map new file mode 100644 index 000000000..18c05ac08 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.md5 new file mode 100644 index 000000000..55ab50d1a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.md5 @@ -0,0 +1 @@ +92ecbd6eeb437ac717bd50570ccc4754 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..cfd0aef1ecd41ac268030bb20275a4fc36a94316 GIT binary patch literal 3157 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 E2RUCXivR!s literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc-members.html new file mode 100644 index 000000000..9ef04b870 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc-members.html @@ -0,0 +1,112 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc Member List
+
+
+ +

This is the complete list of members for IRHitachiAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHitachiAcprivate
_previoustempIRHitachiAcprivate
begin(void)IRHitachiAc
calcChecksum(const uint8_t state[], const uint16_t length=kHitachiAcStateLength)IRHitachiAcstatic
calibrate(void)IRHitachiAcinline
checksum(const uint16_t length=kHitachiAcStateLength)IRHitachiAcprivate
convertFan(const stdAc::fanspeed_t speed)IRHitachiAc
convertMode(const stdAc::opmode_t mode)IRHitachiAc
getFan(void)IRHitachiAc
getMode(void)IRHitachiAc
getPower(void)IRHitachiAc
getRaw(void)IRHitachiAc
getSwingHorizontal(void)IRHitachiAc
getSwingVertical(void)IRHitachiAc
getTemp(void)IRHitachiAc
IRHitachiAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAcexplicit
off(void)IRHitachiAc
on(void)IRHitachiAc
remote_stateIRHitachiAcprivate
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc
setFan(const uint8_t speed)IRHitachiAc
setMode(const uint8_t mode)IRHitachiAc
setPower(const bool on)IRHitachiAc
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAcStateLength)IRHitachiAc
setSwingHorizontal(const bool on)IRHitachiAc
setSwingVertical(const bool on)IRHitachiAc
setTemp(const uint8_t temp)IRHitachiAc
stateReset(void)IRHitachiAc
toCommon(void)IRHitachiAc
toCommonFanSpeed(const uint8_t speed)IRHitachiAcstatic
toCommonMode(const uint8_t mode)IRHitachiAcstatic
toString(void)IRHitachiAc
validChecksum(const uint8_t state[], const uint16_t length=kHitachiAcStateLength)IRHitachiAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc.html new file mode 100644 index 000000000..dacce3479 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc.html @@ -0,0 +1,1107 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Hitachi 224-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Collaboration diagram for IRHitachiAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing setting of the A/C. More...
 
bool getSwingVertical (void)
 Get the Vertical Swing setting of the A/C. More...
 
void setSwingHorizontal (const bool on)
 Set the Horizontal Swing setting of the A/C. More...
 
bool getSwingHorizontal (void)
 Get the Horizontal Swing setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kHitachiAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kHitachiAcStateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kHitachiAcStateLength)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHitachiAcStateLength]
 The state in native code. More...
 
uint8_t _previoustemp
 
+

Detailed Description

+

Class for handling detailed Hitachi 224-bit A/C messages.

+
See also
https://github.com/ToniA/arduino-heatpumpir/blob/master/HitachiHeatpumpIR.cpp
+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc::IRHitachiAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHitachiAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRHitachiAc::calcChecksum (const uint8_t state[],
const uint16_t length = kHitachiAcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe value to calc the checksum of.
[in]lengthThe size/length of the state.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHitachiAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc::checksum (const uint16_t length = kHitachiAcStateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe size/length of the state.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRHitachiAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHitachiAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRHitachiAc::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRHitachiAc::getSwingVertical (void )
+
+ +

Get the Vertical Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRHitachiAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRHitachiAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHitachiAc::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the new_code array.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setSwingHorizontal (const bool on)
+
+ +

Set the Horizontal Swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setTemp (const uint8_t celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRHitachiAc::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRHitachiAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHitachiAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHitachiAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHitachiAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHitachiAc::validChecksum (const uint8_t state[],
const uint16_t length = kHitachiAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHitachiAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _previoustemp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc::_previoustemp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc::remote_state[kHitachiAcStateLength]
+
+private
+
+ +

The state in native code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1-members.html new file mode 100644 index 000000000..dc9801cec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1-members.html @@ -0,0 +1,123 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc1 Member List
+
+
+ +

This is the complete list of members for IRHitachiAc1, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHitachiAc1private
begin(void)IRHitachiAc1
calcChecksum(const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)IRHitachiAc1static
calibrate(void)IRHitachiAc1inline
checksum(const uint16_t length=kHitachiAc1StateLength)IRHitachiAc1private
convertFan(const stdAc::fanspeed_t speed)IRHitachiAc1
convertMode(const stdAc::opmode_t mode)IRHitachiAc1
getFan(void)IRHitachiAc1
getMode(void)IRHitachiAc1
getModel(void)IRHitachiAc1
getOffTimer(void)IRHitachiAc1
getOnTimer(void)IRHitachiAc1
getPower(void)IRHitachiAc1
getPowerToggle(void)IRHitachiAc1
getRaw(void)IRHitachiAc1
getSleep(void)IRHitachiAc1
getSwingH(void)IRHitachiAc1
getSwingToggle(void)IRHitachiAc1
getSwingV(void)IRHitachiAc1
getTemp(void)IRHitachiAc1
IRHitachiAc1(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc1explicit
off(void)IRHitachiAc1
on(void)IRHitachiAc1
remote_stateIRHitachiAc1private
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc1
setFan(const uint8_t speed, const bool force=false)IRHitachiAc1
setMode(const uint8_t mode)IRHitachiAc1
setModel(const hitachi_ac1_remote_model_t model)IRHitachiAc1
setOffTimer(const uint16_t mins)IRHitachiAc1
setOnTimer(const uint16_t mins)IRHitachiAc1
setPower(const bool on)IRHitachiAc1
setPowerToggle(const bool on)IRHitachiAc1
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc1StateLength)IRHitachiAc1
setSleep(const uint8_t mode)IRHitachiAc1
setSwingH(const bool on)IRHitachiAc1
setSwingToggle(const bool toggle)IRHitachiAc1
setSwingV(const bool on)IRHitachiAc1
setTemp(const uint8_t temp)IRHitachiAc1
stateReset(void)IRHitachiAc1
toCommon(void)IRHitachiAc1
toCommonFanSpeed(const uint8_t speed)IRHitachiAc1static
toCommonMode(const uint8_t mode)IRHitachiAc1static
toString(void)IRHitachiAc1
validChecksum(const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)IRHitachiAc1static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1.html new file mode 100644 index 000000000..227b908d6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1.html @@ -0,0 +1,1414 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc1 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Hitachi 104-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Collaboration diagram for IRHitachiAc1:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc1 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setModel (const hitachi_ac1_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
hitachi_ac1_remote_model_t getModel (void)
 Get/Detect the model of the A/C. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setPowerToggle (const bool on)
 Change the power toggle setting. More...
 
bool getPowerToggle (void)
 Get the value of the current power toggle setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed, const bool force=false)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingToggle (const bool toggle)
 Set the Swing toggle setting of the A/C. More...
 
bool getSwingToggle (void)
 Get the Swing Toggle setting of the A/C. More...
 
void setSwingV (const bool on)
 Set the Vertical Swing setting of the A/C. More...
 
bool getSwingV (void)
 Get the Vertical Swing setting of the A/C. More...
 
void setSwingH (const bool on)
 Set the Horizontal Swing setting of the A/C. More...
 
bool getSwingH (void)
 Get the Horizontal Swing setting of the A/C. More...
 
void setSleep (const uint8_t mode)
 Set the Sleep setting of the A/C. More...
 
uint8_t getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setOnTimer (const uint16_t mins)
 Set the On Timer time. More...
 
uint16_t getOnTimer (void)
 Get the On Timer vtime of the A/C. More...
 
void setOffTimer (const uint16_t mins)
 Set the Off Timer time. More...
 
uint16_t getOffTimer (void)
 Get the Off Timer vtime of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAc1StateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kHitachiAc1StateLength)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHitachiAc1StateLength]
 The state in native code. More...
 
+

Detailed Description

+

Class for handling detailed Hitachi 104-bit A/C messages.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1056
+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc1()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc1::IRHitachiAc1 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRHitachiAc1::calcChecksum (const uint8_t state[],
const uint16_t length = kHitachiAc1StateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe value to calc the checksum of.
[in]lengthThe size/length of the state.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHitachiAc1::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc1::checksum (const uint16_t length = kHitachiAc1StateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe size/length of the state.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
hitachi_ac1_remote_model_t IRHitachiAc1::getModel (void )
+
+ +

Get/Detect the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRHitachiAc1::getOffTimer (void )
+
+ +

Get the Off Timer vtime of the A/C.

+
Returns
Nr of minutes the timer is set to.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRHitachiAc1::getOnTimer (void )
+
+ +

Get the On Timer vtime of the A/C.

+
Returns
Nr of minutes the timer is set to.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerToggle()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getPowerToggle (void )
+
+ +

Get the value of the current power toggle setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHitachiAc1::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
The currently configured sleep mode.
+
Note
Sleep modes only available in Auto & Cool modes, otherwise it's off.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getSwingH (void )
+
+ +

Get the Horizontal Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingToggle()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getSwingToggle (void )
+
+ +

Get the Swing Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getSwingV (void )
+
+ +

Get the Vertical Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc1::setFan (const uint8_t speed,
const bool force = false 
)
+
+ +

Set the speed of the fan.

+
Parameters
+ + + +
[in]speedThe desired setting.
[in]forceDo we allow setting the speed regardless of restrictions?
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setModel (const hitachi_ac1_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setOffTimer (const uint16_t mins)
+
+ +

Set the Off Timer time.

+
Parameters
+ + +
[in]minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setOnTimer (const uint16_t mins)
+
+ +

Set the On Timer time.

+
Parameters
+ + +
[in]minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerToggle()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setPowerToggle (const bool on)
+
+ +

Change the power toggle setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc1::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAc1StateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the new_code array.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setSleep (const uint8_t mode)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]modeThe mode of sleep to set the A/C to.
+
+
+
Note
Sleep modes only available in Auto & Cool modes, otherwise it's off.
+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setSwingH (const bool on)
+
+ +

Set the Horizontal Swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingToggle()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setSwingToggle (const bool toggle)
+
+ +

Set the Swing toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setSwingV (const bool on)
+
+ +

Set the Vertical Swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setTemp (const uint8_t celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRHitachiAc1::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHitachiAc1::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHitachiAc1::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHitachiAc1::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHitachiAc1::validChecksum (const uint8_t state[],
const uint16_t length = kHitachiAc1StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHitachiAc1::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc1::remote_state[kHitachiAc1StateLength]
+
+private
+
+ +

The state in native code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.map new file mode 100644 index 000000000..09fed2d72 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 new file mode 100644 index 000000000..74b080a45 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 @@ -0,0 +1 @@ +887e1bb9117f6436abfa2cfbb296e5b6 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..5fa4b63449446dea973d1bb5b232765499b6ca87 GIT binary patch literal 3046 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 + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc3 Member List
+
+
+ +

This is the complete list of members for IRHitachiAc3, including all inherited members.

+ + + + + + + + + + + + + +
_irsendIRHitachiAc3private
begin(void)IRHitachiAc3
calibrate(void)IRHitachiAc3inline
getMode(void)IRHitachiAc3
getRaw(void)IRHitachiAc3
hasInvertedStates(const uint8_t state[], const uint16_t length)IRHitachiAc3static
IRHitachiAc3(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc3explicit
remote_stateIRHitachiAc3private
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc3
setInvertedStates(const uint16_t length=kHitachiAc3StateLength)IRHitachiAc3private
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc3StateLength)IRHitachiAc3
stateReset(void)IRHitachiAc3
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3.html new file mode 100644 index 000000000..c19681754 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3.html @@ -0,0 +1,498 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc3 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Collaboration diagram for IRHitachiAc3:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc3 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
uint8_t getMode (void)
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAc3StateLength)
 Set the internal state from a valid code for this protocol. More...
 
+ + + + +

+Static Public Member Functions

static bool hasInvertedStates (const uint8_t state[], const uint16_t length)
 Check if every second byte of the state, after the fixed header is inverted to the previous byte. More...
 
+ + + + +

+Private Member Functions

void setInvertedStates (const uint16_t length=kHitachiAc3StateLength)
 Invert every second byte of the internal state, after the fixed header. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHitachiAc3StateLength]
 The state in native code. More...
 
+

Detailed Description

+

Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc3()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc3::IRHitachiAc3 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHitachiAc3::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHitachiAc3::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc3::getMode (void )
+
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHitachiAc3::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ hasInvertedStates()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHitachiAc3::hasInvertedStates (const uint8_t state[],
const uint16_t length 
)
+
+static
+
+ +

Check if every second byte of the state, after the fixed header is inverted to the previous byte.

+
Parameters
+ + + +
[in]stateThe state array to be checked.
[in]lengthThe size of the state array.
+
+
+
Note
This is this protocols integrity check.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHitachiAc3::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+ +
+
+ +

◆ setInvertedStates()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc3::setInvertedStates (const uint16_t length = kHitachiAc3StateLength)
+
+private
+
+ +

Invert every second byte of the internal state, after the fixed header.

+
Parameters
+ + +
[in]lengthThe size of the state array.
+
+
+
Note
This is this protocols integrity check.
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc3::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAc3StateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the new_code array.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRHitachiAc3::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+
Note
Reset to auto fan, cooling, 23° Celsius
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHitachiAc3::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc3::remote_state[kHitachiAc3StateLength]
+
+private
+
+ +

The state in native code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344-members.html new file mode 100644 index 000000000..29331de19 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344-members.html @@ -0,0 +1,118 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc344 Member List
+
+
+ +

This is the complete list of members for IRHitachiAc344, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHitachiAc424private
_previoustempIRHitachiAc424private
_toString(void)IRHitachiAc424private
begin(void)IRHitachiAc424
calibrate(void)IRHitachiAc424inline
convertFan(const stdAc::fanspeed_t speed)IRHitachiAc424
convertMode(const stdAc::opmode_t mode)IRHitachiAc424
convertSwingH(const stdAc::swingh_t position)IRHitachiAc344static
getButton(void)IRHitachiAc424
getFan(void)IRHitachiAc424
getMode(void)IRHitachiAc424
getPower(void)IRHitachiAc424
getRaw(void)IRHitachiAc424
getSwingH(void)IRHitachiAc344
getSwingV(void)IRHitachiAc344
getSwingVToggle(void)IRHitachiAc424
getTemp(void)IRHitachiAc424
IRHitachiAc344(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc344explicit
IRHitachiAc424(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc424explicit
off(void)IRHitachiAc424
on(void)IRHitachiAc424
remote_stateIRHitachiAc424private
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc344virtual
setButton(const uint8_t button)IRHitachiAc424
setFan(const uint8_t speed)IRHitachiAc424
setInvertedStates(void)IRHitachiAc424private
setMode(const uint8_t mode)IRHitachiAc424
setPower(const bool on)IRHitachiAc424
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc344StateLength)IRHitachiAc344virtual
setSwingH(const uint8_t position)IRHitachiAc344
setSwingV(const bool on)IRHitachiAc344
setSwingVToggle(const bool on)IRHitachiAc424
setTemp(const uint8_t temp, bool setPrevious=true)IRHitachiAc424
stateReset(void)IRHitachiAc344virtual
toCommon(void)IRHitachiAc344virtual
toCommonFanSpeed(const uint8_t speed)IRHitachiAc424static
toCommonMode(const uint8_t mode)IRHitachiAc424static
toCommonSwingH(const uint8_t pos)IRHitachiAc344static
toString(void)IRHitachiAc344
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344.html new file mode 100644 index 000000000..9e46d328c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344.html @@ -0,0 +1,607 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc344 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
IRHitachiAc344 Class Reference
+
+
+ +

Class for handling detailed Hitachi 344-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Inheritance diagram for IRHitachiAc344:
+
+
Inheritance graph
+ + + + +
[legend]
+
+Collaboration diagram for IRHitachiAc344:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc344 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor for handling detailed Hitachi_AC344 43 byte A/C messages. More...
 
void stateReset (void)
 Reset the internal state to auto fan, cooling, 23° Celsius. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAc344StateLength)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 Create and send the IR message to the A/C. More...
 
void setSwingV (const bool on)
 Control the vertical swing setting. More...
 
bool getSwingV (void)
 Get the current vertical swing setting. More...
 
void setSwingH (const uint8_t position)
 Control the horizontal swing setting. More...
 
uint8_t getSwingH (void)
 Get the current horizontal swing setting. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
- Public Member Functions inherited from IRHitachiAc424
 IRHitachiAc424 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp, bool setPrevious=true)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getButton (void)
 Get the Button/Command setting of the A/C. More...
 
void setButton (const uint8_t button)
 Set the Button/Command pressed setting of the A/C. More...
 
void setSwingVToggle (const bool on)
 Set the Vertical Swing toggle setting of the A/C. More...
 
bool getSwingVToggle (void)
 Get the Vertical Swing toggle setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a standard A/C horizontal swing into its native setting. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
- Static Public Member Functions inherited from IRHitachiAc424
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+

Detailed Description

+

Class for handling detailed Hitachi 344-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc344()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc344::IRHitachiAc344 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor for handling detailed Hitachi_AC344 43 byte A/C messages.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRHitachiAc344::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a standard A/C horizontal swing into its native setting.

+
Parameters
+ + +
[in]positionA stdAc::swingh_t position to convert.
+
+
+
Returns
The equivilent native horizontal swing position.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc344::getSwingH (void )
+
+ +

Get the current horizontal swing setting.

+
Returns
The current position horizontal swing is set to.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRHitachiAc344::getSwingV (void )
+
+ +

Get the current vertical swing setting.

+
Returns
True, if the setting is on. False, it is off.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc344::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+virtual
+
+ +

Create and send the IR message to the A/C.

+
Parameters
+ + +
[in]repeatNr. of times to repeat the message.
+
+
+ +

Reimplemented from IRHitachiAc424.

+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc344::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAc344StateLength 
)
+
+virtual
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthSize (in bytes) of the code for this protocol.
+
+
+ +

Reimplemented from IRHitachiAc424.

+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRHitachiAc344::setSwingH (const uint8_t position)
+
+ +

Control the horizontal swing setting.

+
Parameters
+ + +
[in]positionThe position to set the horizontal swing to.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRHitachiAc344::setSwingV (const bool on)
+
+ +

Control the vertical swing setting.

+
Parameters
+ + +
[in]onTrue, turns on the feature. False, turns off the feature.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc344::stateReset (void )
+
+virtual
+
+ +

Reset the internal state to auto fan, cooling, 23° Celsius.

+ +

Reimplemented from IRHitachiAc424.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::state_t IRHitachiAc344::toCommon (void )
+
+virtual
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +

Reimplemented from IRHitachiAc424.

+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRHitachiAc344::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHitachiAc344::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.map new file mode 100644 index 000000000..10cf25d5a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 new file mode 100644 index 000000000..0f6757465 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 @@ -0,0 +1 @@ +bc686b22e4ddf734f61a87c2609dac47 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba11bc4899b99824a53dc0e9d2191e99fba6556 GIT binary patch literal 5244 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 + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 new file mode 100644 index 000000000..5ccb815dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 @@ -0,0 +1 @@ +35cefb94d2f36be1ad5c9d511cbdbb17 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..85a663aa2ea2b6f2ee6de9c2abe4cdcaa64985c5 GIT binary patch literal 3189 zcmb`Ki91wnAIA@Q%g$qZh{=)|X+%hiWki%=YJ{?+EHhF`BYR_)LXt;9)?qZ3G(5;M zLnOPwSi+;2u{N@dn32ZTdwSpNdES5Ez0Y;-`?{~|ocsFS_xb+5pWlhMzH~uMSWXxK z05PP6nGHC`fVYnzKiFHVqJM(JUU#btX28#1SKhm#6aWxCiZnB^3(j87iLkSsgT5yi zxW*h(mfUw-w6ijWL{x~fEoo_S6OwC^vL~vgo)$Awk!ATCx_IlHHTtUY#B@^0xYFnB zzVX>~y%UGl;F3h{?*ebNRi`gRiK#6yRupUfvM`hFu#ln^R(TLTjNMWd7RaP&&NK>` zUyd}{lSYBQ-xf)Wl62T>>MASfM&?Zx5yJKH++vE;15qRjB`PTBs=x@scFwI$PfyF@ zzG{=|>KruFz0SW;gT=Q^XDqNP9xDlw1reS~0{>mdq2VdXDqUJyImT zMFoXieWo?a2dko@V!eNu$y9_w>pf^`aQm_YE<>|_sAQz1RE2GQ@99Aq1)T|8dYO}x zbJOg|{_t}~4Gl)0wc&dfU;1Z><5O(B9XLGaL0MWdnq5?dV z!&OMn#{8G4$2KL~(+OIF(GC^vk4y~0x0Y*Z>00#OUeb}*`T2Z+ijyaAVVKNs-#-h*Vm_OxoD0Z&7ZMUudv{C<0x95Voyf?@s1I7X zSv9u0y4sPX=sB(L^?G=Le63c&2=C7xr=(Pefj#(D2Qgu5>(PUG#l;qIV#?&CEB+3# z1Eqd4>tfS0$SLh5W)p$2z+$DRrkW?o%0hVDA#_1Of%+5b0}c%E_xHc0s^M5U+nIcr z8|>pF3E=Vgw+rz7!e}%-WP?30R1zB-Yg3X5b1h#Uh2jXGs-h$Oe0{0m zJJejBK3^n}sN5UZ)h8Pk7PdHAE+Z&#r`pL2@{m9vApX_nzFO%)TUuTging$@nE(2f zFA{p{o`a*K(biHGgmeA+^{;$J9!bxh-BF#Lo$Z|S1!I?tNl2i9yPdDi>C5!?_I3&9 zdEoJz*kw{tk(!zs!6+n+u^PqO#8lp1C@ISA?(1VOE%kJDY1avjG>Qn3S|9GCe)ri3~n>;_YeVb1(ty%WrrvAbNUwTokG5rmby?X}(WDfU4k! zi3xciG%RdmY3v;CqLr1^#fzz3*v7`j%~|MoeH4b!<>T)^Uge3lwCsKtvLX5jRLsuW z9F3cR(AT$oKAU~U@2|Uo=g#f%v&=S*2)}h}zQ+4=IG9sSyPI%0+)6ol-nOB#QVO^c zx@r!qyfgfIF3n#MZFAOAfdMC_GfP`kGibgYi1oR4K^@@v%zKZA=Zu*jA5M*O(8v)9fMTp4Vy|vy7K_B3rP<;9& zyNo4t5F<6|mi=D4ke_x|P-D-bKSg8S>qvr=xCj~L9I_*Zl6 z32nb1?EbW4Gg~X4&tJI04fgj(!L|qwwzQ>aX_uWob-FtaVBqi%gPuo4(zJDaYYV>| z<*03}-mj!?c7OYJofGIGDy>mKBnE_Le|%azjJ=Y2gZar6B9eC5#`pI0&#e72E;?4a zux1+%QPJ^|@)f17t!JXoUo9*efX>+Jd|fu4)O|z?x3?dm0RWMISUBCJLLqJ?I<3=I z`dXm5sY?G0`m&`hB&}Xh{kQCwS#wS46>H*u{8@Hj>r=Nw$aSpoh{Esa))Hp*}UHe4q-rN)*YZ> z=w`A%vj4%?s!rh2UzcrdF>FoL!!hhPUTBHk9m=}m-l62=7caOx7C{#y9@{eIQ|HY7 zzWkYV~9F9=&tdM;=pYzE^-Z*4+fW+>uk_2`YN+S;Ii z05KsUO5n0widH(UX^UO|<3}*LNY`;(2^DBBpK7U^YAF=$Q0J3xV!-}fi_W)>iH-H6 zIO{)8OWO;mAOiyfg$4K}B$BGVM)}WzR@K?r2~q~6tCyEoR#w&?etsbD^=nHd$>5NX zgtqAyFJ24|4#wBg48k_KS-8gA-rn-k(y(NUmwLWxrAXc5$E_V5dEM~xehK7rl$F&C zhgaoEAJITKj$5OY3SRwc0>B$G`H|_=5Zc)2KBT2P6~3-PbFat^VN>Gb;;2+A7|Zwd z_2JP`8ENUhtWy$z>A7_RR1}|#j7+c1o;`cy<>k2xqtKIg z{{k(vex(r%-N3xJySw{btTEGj`HEdLF{o* zT@g>rhz$)5sc?H8xXobJOB7xjuT))Kt%lBhL7U^gS{<~~;ya7OX@Ld9w{I_BuFTI{ zNX)BWBiYIy-aQp0gBp+!F0&|Me%Ypk+Zqp{8*)VDZ{NM!)7v}eOR*hQ5&SSV_JH%H*Tcg@ z_z|(Hs;a5U*w8Q=8JCziQFnhP`d=dc?aYuBqlcRULyY)d1_RVG6_g@v&gmM|daSFf zq_otEeD#{6V~O3-C&b*)H6#?8Ra0}a!eMD?Nfan6E92wiizn|QN1*wwB z*}^(E1pfvcfB=7DyPks&m6d5KDiY%LcDA>lr=&2!iigKxNr;Kfu~-IY&O87a{o}{+ zjuG&PuvqNXt0Q1wfNN!4{>vZdT+Ga3EJ?46i;v&ZQb^k1(2e))+sEOBo;p=qS62t3 zKVWgh1B-p*RQ&|`xjv{IOaU7ksiY1s9L_V1nv=P<=1U$ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 new file mode 100644 index 000000000..49092288c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 @@ -0,0 +1 @@ +83b1a000783b5409d1f40cfaae3aa3e3 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..f721b1bcda174f0244b7b19279679ecb0c70d95a GIT binary patch literal 3209 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424-members.html new file mode 100644 index 000000000..468c48f73 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424-members.html @@ -0,0 +1,112 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc424 Member List
+
+
+ +

This is the complete list of members for IRHitachiAc424, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHitachiAc424private
_previoustempIRHitachiAc424private
_toString(void)IRHitachiAc424private
begin(void)IRHitachiAc424
calibrate(void)IRHitachiAc424inline
convertFan(const stdAc::fanspeed_t speed)IRHitachiAc424
convertMode(const stdAc::opmode_t mode)IRHitachiAc424
getButton(void)IRHitachiAc424
getFan(void)IRHitachiAc424
getMode(void)IRHitachiAc424
getPower(void)IRHitachiAc424
getRaw(void)IRHitachiAc424
getSwingVToggle(void)IRHitachiAc424
getTemp(void)IRHitachiAc424
IRHitachiAc344 classIRHitachiAc424friend
IRHitachiAc424(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc424explicit
off(void)IRHitachiAc424
on(void)IRHitachiAc424
remote_stateIRHitachiAc424private
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc424virtual
setButton(const uint8_t button)IRHitachiAc424
setFan(const uint8_t speed)IRHitachiAc424
setInvertedStates(void)IRHitachiAc424private
setMode(const uint8_t mode)IRHitachiAc424
setPower(const bool on)IRHitachiAc424
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc424StateLength)IRHitachiAc424virtual
setSwingVToggle(const bool on)IRHitachiAc424
setTemp(const uint8_t temp, bool setPrevious=true)IRHitachiAc424
stateReset(void)IRHitachiAc424virtual
toCommon(void)IRHitachiAc424virtual
toCommonFanSpeed(const uint8_t speed)IRHitachiAc424static
toCommonMode(const uint8_t mode)IRHitachiAc424static
toString(void)IRHitachiAc424
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424.html new file mode 100644 index 000000000..ecdf66cef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424.html @@ -0,0 +1,1125 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc424 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Hitachi 53-byte/424-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Inheritance diagram for IRHitachiAc424:
+
+
Inheritance graph
+ + + + +
[legend]
+
+Collaboration diagram for IRHitachiAc424:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc424 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
virtual void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
virtual void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp, bool setPrevious=true)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getButton (void)
 Get the Button/Command setting of the A/C. More...
 
void setButton (const uint8_t button)
 Set the Button/Command pressed setting of the A/C. More...
 
void setSwingVToggle (const bool on)
 Set the Vertical Swing toggle setting of the A/C. More...
 
bool getSwingVToggle (void)
 Get the Vertical Swing toggle setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
virtual void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAc424StateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
virtual stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void setInvertedStates (void)
 Update the internal consistency check for the protocol. More...
 
String _toString (void)
 Convert the internal state into a human readable string for the settings that are common to protocols of this nature. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHitachiAc424StateLength]
 The state in native code. More...
 
uint8_t _previoustemp
 
+ + + +

+Friends

class IRHitachiAc344
 
+

Detailed Description

+

Class for handling detailed Hitachi 53-byte/424-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc424()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc424::IRHitachiAc424 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _toString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRHitachiAc424::_toString (void )
+
+private
+
+ +

Convert the internal state into a human readable string for the settings that are common to protocols of this nature.

+
Returns
A string containing the common settings in human-readable form.
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHitachiAc424::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getButton()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::getButton (void )
+
+ +

Get the Button/Command setting of the A/C.

+
Returns
The value of the button/command that was pressed.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRHitachiAc424::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHitachiAc424::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingVToggle()

+ +
+
+ + + + + + + + +
bool IRHitachiAc424::getSwingVToggle (void )
+
+ +

Get the Vertical Swing toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc424::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+virtual
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +

Reimplemented in IRHitachiAc344.

+ +
+
+ +

◆ setButton()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setButton (const uint8_t button)
+
+ +

Set the Button/Command pressed setting of the A/C.

+
Parameters
+ + +
[in]buttonThe value of the button/command that was pressed.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setInvertedStates()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc424::setInvertedStates (void )
+
+private
+
+ +

Update the internal consistency check for the protocol.

+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc424::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAc424StateLength 
)
+
+virtual
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the new_code array.
+
+
+ +

Reimplemented in IRHitachiAc344.

+ +
+
+ +

◆ setSwingVToggle()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setSwingVToggle (const bool on)
+
+ +

Set the Vertical Swing toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
The remote does not keep state of the vertical swing. A byte is sent indicating the swing button is pressed on the remote
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc424::setTemp (const uint8_t celsius,
bool setPrevious = true 
)
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]celsiusThe temperature in degrees celsius.
[in]setPrevioustrue, remember this if we change mode. false, don't.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc424::stateReset (void )
+
+virtual
+
+ +

Reset the internal state to a fixed known good state.

+
Note
Reset to auto fan, cooling, 23° Celsius
+ +

Reimplemented in IRHitachiAc344.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::state_t IRHitachiAc424::toCommon (void )
+
+virtual
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +

Reimplemented in IRHitachiAc344.

+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHitachiAc424::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHitachiAc424::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHitachiAc424::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+

Friends And Related Function Documentation

+ +

◆ IRHitachiAc344

+ +
+
+ + + + + +
+ + + + +
friend class IRHitachiAc344
+
+friend
+
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHitachiAc424::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _previoustemp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc424::_previoustemp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc424::remote_state[kHitachiAc424StateLength]
+
+private
+
+ +

The state in native code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.map new file mode 100644 index 000000000..7cbfa51cc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 new file mode 100644 index 000000000..1ac39cb1f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 @@ -0,0 +1 @@ +e27758fabb1539bba026d03c86a2d75d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..3bb4db79f7cf88a57187fa918a7b8b9560601024 GIT binary patch literal 3350 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 + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 new file mode 100644 index 000000000..8cc016c00 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 @@ -0,0 +1 @@ +83321b013f1eecd9a72546893407d4cc \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..df924b19fb3ac8606ffe1d78368ca87723f58820 GIT binary patch literal 3162 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.map new file mode 100644 index 000000000..dcb9d35cc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 new file mode 100644 index 000000000..16865578f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 @@ -0,0 +1 @@ +aeb4ec71968654b70565a578d510a768 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..3f092bb9a7e947787625a7b3fed71304a58484a2 GIT binary patch literal 3005 zcmZWrXH*m077kuTdJ(uNEl)r?0R*H-Cjlwa1O%msG^wG5CJ@C?G$3H;9cdz6P%upx8W}?r`z{3CnftU?$KrMh34%|pO zTHs0I$UOuW+WSWOP|)eGtFWyc0|GGy7(lfxLvvU19vX9w3Owr27LzbEyQ`DhSvsNj zhXU-vba7%Mx``e27UoHhyb(W=U5L_1=B4=Dl4$%flDSRN^fW{d3lwU66JHu!`q{UG0`KJ*BPwR|fP_1A>9w`DZoSP-Ta1@)QA|E*aO`BbZPB{A`Zjk1N zfPlDZ_l+iU0r+Is`&>V9;8`3 zrg_KBq4}a#YHDgT)~46o!a{Ijow5?wI`47upKQF*ySu@hu%hDP?!h7^Eg-u5?Bs^=Lns=VjGfYzwuUJpPQwYtw1#>z}W@T`M9a^kfQoN*r_w z<986RO~PYD8-iEvaKcDUQ&G1@kyLUy6bfZyW9#gSVN{8vHey$L5_xB5XW0YR+>V7}4E6Q(prPU6l$@NetHhT2JJk_K8@Od+%Wa}4P#TpQ{<^aAedvau zxw&~sNy*P3)nPS9XctvdS}Ny14dvnC5tETAfA#8taZ(tx znOaf6zFQ~d&}suzylwQ`(&lHOr1)pg7!WN4@84-?Xr@OUk^E-Xfq@MmsFznIwvXf& z-`T09hzts99K#|iv26_vw?HpTOJNEM3Upd_?Gd&_2U}ZlkpJA5G$$~IZKgS{bS>Mx z-bR)uadu&0#!nd(A0K~jZL+P(u_J$M%*MLL4o_%sr%^_psDT>XdM)7LBF34WZ@oqz zczRlVWo2QpM&>JcTmY%7t2Z__0w+BHf9T>;(!#n|v|$()skS@jygcz9)6=6Dyz-;8 zMu{hpPcH{`R3Me z_jxZ@=v%c%g@ykK2n-aLlA0Z!C zm)Pqz^Hru}_WeS>keFEf$B)pmn>ju2e8$I`;NV+j#x$!F2~Zd;B{TDepPwv&KyYz$ zn_gSftil=^8aDgS(59rM2#bnhQc_5Ly1e`~?eT(+^z@f|Hki>ap?~woB0n}|Qz0R> z+$l)BpCIYCyL5VZDT5Vz?o~yFzkYr9eDI75=eY=QQp*q6?M~7eP_W`L zt~=%Dh;|bsW5FXFt}6aq6U~MF{ne_~(3e$Flde_~z#gM9tF@)5r4}za=i}In0nCsfYZ% zXJfX~?41SrZ3=nAc0{~R8&+jdx@Nb(hZU$dCP8NHz3QE-DWrBH^O>pzZ@V_-ZIEzv z5n~wh`Rf~5vY|~AXB}gDgs9gKw=ee(9dtI)J$KMPjuP*u)a6r1o?8Pqr{7v%9|=@< zX8S%yO24h+jNh@oo^$q}|r0@k&>B zN;7w_QqIh!f23zn_U}eOz+9@lt7-|Rr{z)kM=x?WD&)eag-frzvEb4lJUp*g=r zw2H!^oJ&uc%~CRM_3u&@hi8TYsj$nL>AxilJ0wBoK2@N))U!7~CE>!~BGc@R=#_1pdY-uZiIK(y}rOE2~d?Q%F+_iwoe0^~b7?Pe<5w{C;-Qq)XX$og5#k{~kA@PR;-!L`BJy3Xqpji7(9zC=~1P02(+Ydwx3=FDl>Z1#gCkO32d**lVejTc~6*iNo z^Z*VAuj{K=M%Hw#bQ4#CuZv*lVdk0Y4|iXE3Ev}zc=-5SxpE~2g*uBkjsr*0JsKpJ z)YqpR9YwhH<>Ft$&>%5DyQw=A@5$CI08nQ3_Pts1?lyJzXh3nSU=dBtg7|nkLnEVK z65q1c&MW)W1Uxr4C*|1A=jiC@5Kg`#AtCX(ug|)P)vBP>o{R36b|2kpjKIU=COIHowYn zaB-dMM9Z{)uCZ^ayHl-3T`c}>33wSA9o?FIxJFYKM7H>4f?l<4u^kc z>@QdZWq+$*lkm=m*D-R3D{!Ij6AtIDmES`4V$jz?AQT_&E*HIjZ|jqvAHF31voEMa zLqp?Ru1es*@ssH2p@Kt^woBggf*3sN(|uA5x5Hvn`|H=wP$-ns@PfodR4*d~!~J9G zPUE|G0Y5t*n`eYHMLephfn4+X0oBu^b#-;+yB?eX`0zB~*>v>uAIL!gFh4}bLgGeOO@rb^@ zzVo#lxtv}|HC(J``En%TjqBJ-FpGei^6P*<1_xCTOPpwK84*cIbaFD=2mpD&P;K70 z(2qC4MIn%yDGgpFUtvMP=+;&>AiScoQbva>~#PD literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC-members.html new file mode 100644 index 000000000..9ecc5c43f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC-members.html @@ -0,0 +1,121 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRKelvinatorAC Member List
+
+
+ +

This is the complete list of members for IRKelvinatorAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRKelvinatorACprivate
begin(void)IRKelvinatorAC
calcBlockChecksum(const uint8_t *block, const uint16_t length=kKelvinatorStateLength/2)IRKelvinatorACstatic
calibrate(void)IRKelvinatorACinline
checksum(const uint16_t length=kKelvinatorStateLength)IRKelvinatorACprivate
convertMode(const stdAc::opmode_t mode)IRKelvinatorAC
fixup(void)IRKelvinatorACprivate
getFan(void)IRKelvinatorAC
getIonFilter(void)IRKelvinatorAC
getLight(void)IRKelvinatorAC
getMode(void)IRKelvinatorAC
getPower(void)IRKelvinatorAC
getQuiet(void)IRKelvinatorAC
getRaw(void)IRKelvinatorAC
getSwingHorizontal(void)IRKelvinatorAC
getSwingVertical(void)IRKelvinatorAC
getTemp(void)IRKelvinatorAC
getTurbo(void)IRKelvinatorAC
getXFan(void)IRKelvinatorAC
IRKelvinatorAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRKelvinatorACexplicit
off(void)IRKelvinatorAC
on(void)IRKelvinatorAC
remote_stateIRKelvinatorACprivate
send(const uint16_t repeat=kKelvinatorDefaultRepeat)IRKelvinatorAC
setFan(const uint8_t speed)IRKelvinatorAC
setIonFilter(const bool on)IRKelvinatorAC
setLight(const bool on)IRKelvinatorAC
setMode(const uint8_t mode)IRKelvinatorAC
setPower(const bool on)IRKelvinatorAC
setQuiet(const bool on)IRKelvinatorAC
setRaw(const uint8_t new_code[])IRKelvinatorAC
setSwingHorizontal(const bool on)IRKelvinatorAC
setSwingVertical(const bool on)IRKelvinatorAC
setTemp(const uint8_t degrees)IRKelvinatorAC
setTurbo(const bool on)IRKelvinatorAC
setXFan(const bool on)IRKelvinatorAC
stateReset(void)IRKelvinatorAC
toCommon(void)IRKelvinatorAC
toCommonFanSpeed(const uint8_t speed)IRKelvinatorACstatic
toCommonMode(const uint8_t mode)IRKelvinatorACstatic
toString(void)IRKelvinatorAC
validChecksum(const uint8_t state[], const uint16_t length=kKelvinatorStateLength)IRKelvinatorACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC.html new file mode 100644 index 000000000..1eb7ab15c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC.html @@ -0,0 +1,1340 @@ + + + + + + + +IRremoteESP8266: IRKelvinatorAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Kelvinator A/C messages. + More...

+ +

#include <ir_Kelvinator.h>

+
+Collaboration diagram for IRKelvinatorAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRKelvinatorAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internals of the object to a known good state. More...
 
void send (const uint16_t repeat=kKelvinatorDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the internal state to have the power on. More...
 
void off (void)
 Set the internal state to have the power off. More...
 
void setPower (const bool on)
 Set the internal state to have the desired power. More...
 
bool getPower (void)
 Get the power setting from the internal state. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature setting. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the desired operation mode. More...
 
uint8_t getMode (void)
 Get the current operation mode setting. More...
 
void setSwingVertical (const bool on)
 Control the current vertical swing setting. More...
 
bool getSwingVertical (void)
 Is the vertical swing setting on? More...
 
void setSwingHorizontal (const bool on)
 Control the current horizontal swing setting. More...
 
bool getSwingHorizontal (void)
 Is the horizontal swing setting on? More...
 
void setQuiet (const bool on)
 Control the current Quiet setting. More...
 
bool getQuiet (void)
 Is the Quiet setting on? More...
 
void setIonFilter (const bool on)
 Control the current Ion Filter setting. More...
 
bool getIonFilter (void)
 Is the Ion Filter setting on? More...
 
void setLight (const bool on)
 Control the current Light setting. i.e. The LED display on the A/C unit that shows the basic settings. More...
 
bool getLight (void)
 Is the Light (Display) setting on? More...
 
void setXFan (const bool on)
 Control the current XFan setting. This setting will cause the unit blow air after power off to dry out the A/C device. More...
 
bool getXFan (void)
 Is the XFan setting on? More...
 
void setTurbo (const bool on)
 Control the current Turbo setting. More...
 
bool getTurbo (void)
 Is the Turbo setting on? More...
 
uint8_t * getRaw (void)
 Get the raw state of the object, suitable to be sent with the appropriate IRsend object method. More...
 
void setRaw (const uint8_t new_code[])
 Set the raw state of the object. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a standard A/C mode (stdAc::opmode_t) into it a native mode. More...
 
stdAc::state_t toCommon (void)
 Convert the internal A/C object state to it's stdAc::state_t equivalent. More...
 
String toString (void)
 Convert the internal settings into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcBlockChecksum (const uint8_t *block, const uint16_t length=kKelvinatorStateLength/2)
 Calculate the checksum for a given block of state. More...
 
static bool validChecksum (const uint8_t state[], const uint16_t length=kKelvinatorStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode to it's stdAc::opmode_t equivalent. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed to it's stdAc::fanspeed_t equivalent. More...
 
+ + + + + + + +

+Private Member Functions

void checksum (const uint16_t length=kKelvinatorStateLength)
 Calculate the checksum for the internal state. More...
 
void fixup (void)
 Fix up any odd conditions for the current state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kKelvinatorStateLength]
 The state in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed Kelvinator A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRKelvinatorAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRKelvinatorAC::IRKelvinatorAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcBlockChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRKelvinatorAC::calcBlockChecksum (const uint8_t * block,
const uint16_t length = kKelvinatorStateLength / 2 
)
+
+static
+
+ +

Calculate the checksum for a given block of state.

+
Parameters
+ + + +
[in]blockA pointer to a block to calc the checksum of.
[in]lengthLength of the block array to checksum.
+
+
+
Returns
The calculated checksum value.
+
Note
Many Bothans died to bring us this information.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRKelvinatorAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRKelvinatorAC::checksum (const uint16_t length = kKelvinatorStateLength)
+
+private
+
+ +

Calculate the checksum for the internal state.

+
Parameters
+ + +
[in]lengthLength of the internal state to checksum.
+
+
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRKelvinatorAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a standard A/C mode (stdAc::opmode_t) into it a native mode.

+
Parameters
+ + +
[in]modeA stdAc::opmode_t operation mode.
+
+
+
Returns
The native mode equivilant.
+ +
+
+ +

◆ fixup()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRKelvinatorAC::fixup (void )
+
+private
+
+ +

Fix up any odd conditions for the current state.

+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRKelvinatorAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getIonFilter()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getIonFilter (void )
+
+ +

Is the Ion Filter setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getLight (void )
+
+ +

Is the Light (Display) setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRKelvinatorAC::getMode (void )
+
+ +

Get the current operation mode setting.

+
Returns
The current operation mode.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getPower (void )
+
+ +

Get the power setting from the internal state.

+
Returns
A boolean indicating if the power setting.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getQuiet (void )
+
+ +

Is the Quiet setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRKelvinatorAC::getRaw (void )
+
+ +

Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.

+
Returns
A PTR to the internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getSwingHorizontal (void )
+
+ +

Is the horizontal swing setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getSwingVertical (void )
+
+ +

Is the vertical swing setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRKelvinatorAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
Get current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getTurbo (void )
+
+ +

Is the Turbo setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getXFan()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getXFan (void )
+
+ +

Is the XFan setting on?

+
Returns
The current value.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::off (void )
+
+ +

Set the internal state to have the power off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::on (void )
+
+ +

Set the internal state to have the power on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::send (const uint16_t repeat = kKelvinatorDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speed0 is auto, 1-5 is the speed
+
+
+ +
+
+ +

◆ setIonFilter()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setIonFilter (const bool on)
+
+ +

Control the current Ion Filter setting.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setLight (const bool on)
+
+ +

Control the current Light setting. i.e. The LED display on the A/C unit that shows the basic settings.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setMode (const uint8_t mode)
+
+ +

Set the desired operation mode.

+
Parameters
+ + +
[in]modeThe desired operation mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setPower (const bool on)
+
+ +

Set the internal state to have the desired power.

+
Parameters
+ + +
[in]onThe desired power state.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setQuiet (const bool on)
+
+ +

Control the current Quiet setting.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setRaw (const uint8_t new_code[])
+
+ +

Set the raw state of the object.

+
Parameters
+ + +
[in]new_codeThe raw state from the native IR message.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setSwingHorizontal (const bool on)
+
+ +

Control the current horizontal swing setting.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setSwingVertical (const bool on)
+
+ +

Control the current vertical swing setting.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature setting.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setTurbo (const bool on)
+
+ +

Control the current Turbo setting.

+
Note
Turbo mode is turned off if the fan speed is changed.
+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setXFan()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setXFan (const bool on)
+
+ +

Control the current XFan setting. This setting will cause the unit blow air after power off to dry out the A/C device.

+
Note
XFan mode is only valid in Cool or Dry mode.
+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::stateReset (void )
+
+ +

Reset the internals of the object to a known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRKelvinatorAC::toCommon (void )
+
+ +

Convert the internal A/C object state to it's stdAc::state_t equivalent.

+
Returns
A stdAc::state_t containing the current settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRKelvinatorAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed to it's stdAc::fanspeed_t equivalent.

+
Parameters
+ + +
[in]speedA native fan speed value.
+
+
+
Returns
The stdAc::fanspeed_t equivilant.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRKelvinatorAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode to it's stdAc::opmode_t equivalent.

+
Parameters
+ + +
[in]modeA native operating mode value.
+
+
+
Returns
The stdAc::opmode_t equivilant.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRKelvinatorAC::toString (void )
+
+ +

Convert the internal settings into a human readable string.

+
Returns
A String.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRKelvinatorAC::validChecksum (const uint8_t state[],
const uint16_t length = kKelvinatorStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe size of the state.
+
+
+
Returns
A boolean indicating if it is valid.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRKelvinatorAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRKelvinatorAC::remote_state[kKelvinatorStateLength]
+
+private
+
+ +

The state in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map new file mode 100644 index 000000000..40f1acb8c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 new file mode 100644 index 000000000..5fe2723e9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 @@ -0,0 +1 @@ +bb0276d1879b23e51b948f404eb3a682 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..e06512959fbeb287bc910895091ed10d6fdbb38a GIT binary patch literal 3684 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc-members.html new file mode 100644 index 000000000..63a5286d7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc-members.html @@ -0,0 +1,113 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRLgAc Member List
+
+
+ +

This is the complete list of members for IRLgAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRLgAcprivate
_protocolIRLgAcprivate
_setTemp(const uint8_t value)IRLgAcprivate
_tempIRLgAcprivate
begin(void)IRLgAc
calcChecksum(const uint32_t state)IRLgAcstatic
calibrate(void)IRLgAcinline
checksum(void)IRLgAcprivate
convertFan(const stdAc::fanspeed_t speed)IRLgAcstatic
convertMode(const stdAc::opmode_t mode)IRLgAc
getFan(void)IRLgAc
getMode(void)IRLgAc
getModel(void)IRLgAc
getPower(void)IRLgAc
getRaw(void)IRLgAc
getTemp(void)IRLgAc
IRLgAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRLgAcexplicit
isValidLgAc(void)IRLgAc
off(void)IRLgAc
on(void)IRLgAc
remote_stateIRLgAcprivate
send(const uint16_t repeat=kLgDefaultRepeat)IRLgAc
setFan(const uint8_t speed)IRLgAc
setMode(const uint8_t mode)IRLgAc
setModel(const lg_ac_remote_model_t model)IRLgAc
setPower(const bool on)IRLgAc
setRaw(const uint32_t new_code)IRLgAc
setTemp(const uint8_t degrees)IRLgAc
stateReset(void)IRLgAc
toCommon(void)IRLgAc
toCommonFanSpeed(const uint8_t speed)IRLgAcstatic
toCommonMode(const uint8_t mode)IRLgAcstatic
toString(void)IRLgAc
validChecksum(const uint32_t state)IRLgAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc.html new file mode 100644 index 000000000..a65b6eeaf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc.html @@ -0,0 +1,1108 @@ + + + + + + + +IRremoteESP8266: IRLgAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed LG A/C messages. + More...

+ +

#include <ir_LG.h>

+
+Collaboration diagram for IRLgAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRLgAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internals of the object to a known good state. More...
 
bool isValidLgAc (void)
 Check if the internal state looks like a valud LG A/C message. More...
 
void send (const uint16_t repeat=kLgDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
uint32_t getRaw (void)
 Get a copy of the internal state/code for this protocol. More...
 
void setRaw (const uint32_t new_code)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
void setModel (const lg_ac_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
lg_ac_remote_model_t getModel (void)
 Get the model of the A/C. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint32_t state)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (const uint32_t state)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
+ + + + + + + +

+Private Member Functions

void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
void _setTemp (const uint8_t value)
 Set the temperature. More...
 
+ + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint32_t remote_state
 The state of the IR remote in IR code form. More...
 
uint8_t _temp
 
decode_type_t _protocol
 
+

Detailed Description

+

Class for handling detailed LG A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRLgAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRLgAc::IRLgAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _setTemp()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRLgAc::_setTemp (const uint8_t value)
+
+private
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]valueThe native temperature.
+
+
+
Note
Internal use only.
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRLgAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRLgAc::calcChecksum (const uint32_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRLgAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRLgAc::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRLgAc::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRLgAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRLgAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRLgAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
lg_ac_remote_model_t IRLgAc::getModel (void )
+
+ +

Get the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRLgAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint32_t IRLgAc::getRaw (void )
+
+ +

Get a copy of the internal state/code for this protocol.

+
Returns
The code for this protocol based on the current internal state.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRLgAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ isValidLgAc()

+ +
+
+ + + + + + + + +
bool IRLgAc::isValidLgAc (void )
+
+ +

Check if the internal state looks like a valud LG A/C message.

+
Returns
true, the internal state is a valid LG A/C mesg. Otherwise, false.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRLgAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRLgAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRLgAc::send (const uint16_t repeat = kLgDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRLgAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRLgAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRLgAc::setModel (const lg_ac_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRLgAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRLgAc::setRaw (const uint32_t new_code)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRLgAc::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRLgAc::stateReset (void )
+
+ +

Reset the internals of the object to a known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRLgAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRLgAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRLgAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRLgAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRLgAc::validChecksum (const uint32_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe value to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRLgAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _protocol

+ +
+
+ + + + + +
+ + + + +
decode_type_t IRLgAc::_protocol
+
+private
+
+ +
+
+ +

◆ _temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRLgAc::_temp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint32_t IRLgAc::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.map new file mode 100644 index 000000000..37558d8ac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.md5 new file mode 100644 index 000000000..0626aca74 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.md5 @@ -0,0 +1 @@ +56fb7c83360ef1487cea622f026510d6 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..3fabc33867e7704974b05da754ddbc8f565ffaa7 GIT binary patch literal 2873 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC-members.html new file mode 100644 index 000000000..59046578a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC-members.html @@ -0,0 +1,115 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMideaAC Member List
+
+
+ +

This is the complete list of members for IRMideaAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMideaACprivate
_SwingVToggleIRMideaACprivate
begin(void)IRMideaAC
calcChecksum(const uint64_t state)IRMideaACprivatestatic
calibrate(void)IRMideaACinline
checksum(void)IRMideaACprivate
convertFan(const stdAc::fanspeed_t speed)IRMideaAC
convertMode(const stdAc::opmode_t mode)IRMideaAC
getFan(void)IRMideaAC
getMode(void)IRMideaAC
getPower(void)IRMideaAC
getRaw(void)IRMideaAC
getSleep(void)IRMideaAC
getSwingVToggle(void)IRMideaAC
getTemp(const bool useCelsius=false)IRMideaAC
getUseCelsius(void)IRMideaAC
IRMideaAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMideaACexplicit
isSwingVToggle(void)IRMideaAC
off(void)IRMideaAC
on(void)IRMideaAC
remote_stateIRMideaACprivate
send(const uint16_t repeat=kMideaMinRepeat)IRMideaAC
setFan(const uint8_t fan)IRMideaAC
setMode(const uint8_t mode)IRMideaAC
setPower(const bool on)IRMideaAC
setRaw(const uint64_t newState)IRMideaAC
setSleep(const bool on)IRMideaAC
setSwingVToggle(const bool on)IRMideaAC
setTemp(const uint8_t temp, const bool useCelsius=false)IRMideaAC
setUseCelsius(const bool celsius)IRMideaAC
stateReset(void)IRMideaAC
toCommon(const stdAc::state_t *prev=NULL)IRMideaAC
toCommonFanSpeed(const uint8_t speed)IRMideaACstatic
toCommonMode(const uint8_t mode)IRMideaACstatic
toString(void)IRMideaAC
validChecksum(const uint64_t state)IRMideaACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC.html new file mode 100644 index 000000000..15c9dde37 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC.html @@ -0,0 +1,1169 @@ + + + + + + + +IRremoteESP8266: IRMideaAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Midea A/C messages. + More...

+ +

#include <ir_Midea.h>

+
+Collaboration diagram for IRMideaAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMideaAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMideaMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
bool getUseCelsius (void)
 Is the device currently using Celsius or the Fahrenheit temp scale? More...
 
void setUseCelsius (const bool celsius)
 Set the A/C unit to use Celsius natively. More...
 
void setTemp (const uint8_t temp, const bool useCelsius=false)
 Set the temperature. More...
 
uint8_t getTemp (const bool useCelsius=false)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setRaw (const uint64_t newState)
 Set the internal state from a valid code for this protocol. More...
 
uint64_t getRaw (void)
 Get a copy of the internal state/code for this protocol. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
bool isSwingVToggle (void)
 Is the current state a vertical swing toggle message? More...
 
void setSwingVToggle (const bool on)
 Set the A/C to toggle the vertical swing toggle for the next send. More...
 
bool getSwingVToggle (void)
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (const stdAc::state_t *prev=NULL)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate & set the checksum for the current internal state of the remote. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote_state
 The state of the IR remote in IR code form. More...
 
bool _SwingVToggle
 
+

Detailed Description

+

Class for handling detailed Midea A/C messages.

+
Warning
Consider this very alpha code.
+

Constructor & Destructor Documentation

+ +

◆ IRMideaAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMideaAC::IRMideaAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMideaAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMideaAC::calcChecksum (const uint64_t state)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMideaAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMideaAC::checksum (void )
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMideaAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint64_t IRMideaAC::getRaw (void )
+
+ +

Get a copy of the internal state/code for this protocol.

+
Returns
The code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRMideaAC::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVToggle()

+ +
+
+ + + + + + + + +
bool IRMideaAC::getSwingVToggle (void )
+
+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::getTemp (const bool celsius = false)
+
+ +

Get the current temperature setting.

+
Parameters
+ + +
[in]celsiustrue, the results are in Celsius. false, in Fahrenheit.
+
+
+
Returns
The current setting for temp. in the requested units/scale.
+ +
+
+ +

◆ getUseCelsius()

+ +
+
+ + + + + + + + +
bool IRMideaAC::getUseCelsius (void )
+
+ +

Is the device currently using Celsius or the Fahrenheit temp scale?

+
Returns
true, the A/C unit uses Celsius natively, false, is Fahrenheit.
+ +
+
+ +

◆ isSwingVToggle()

+ +
+
+ + + + + + + + +
bool IRMideaAC::isSwingVToggle (void )
+
+ +

Is the current state a vertical swing toggle message?

+
Returns
true, it is. false, it isn't.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMideaAC::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMideaAC::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMideaAC::send (const uint16_t repeat = kMideaMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMideaAC::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting. 1-3 set the speed, 0 for auto.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMideaAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMideaAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMideaAC::setRaw (const uint64_t newState)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]newStateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRMideaAC::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVToggle()

+ +
+
+ + + + + + + + +
void IRMideaAC::setSwingVToggle (const bool on)
+
+ +

Set the A/C to toggle the vertical swing toggle for the next send.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRMideaAC::setTemp (const uint8_t temp,
const bool useCelsius = false 
)
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]tempThe temperature in degrees celsius.
[in]useCelsiustrue, use the Celsius temp scale. false, is Fahrenheit
+
+
+ +
+
+ +

◆ setUseCelsius()

+ +
+
+ + + + + + + + +
void IRMideaAC::setUseCelsius (const bool on)
+
+ +

Set the A/C unit to use Celsius natively.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMideaAC::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMideaAC::toCommon (const stdAc::state_tprev = NULL)
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Parameters
+ + +
[in]prevA Ptr to the previous state.
+
+
+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMideaAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMideaAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMideaAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRMideaAC::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe state to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMideaAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _SwingVToggle

+ +
+
+ + + + + +
+ + + + +
bool IRMideaAC::_SwingVToggle
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRMideaAC::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.map new file mode 100644 index 000000000..7a5ecc57e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.md5 new file mode 100644 index 000000000..c12aeb84b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.md5 @@ -0,0 +1 @@ +7a6c2ec0b798d60bf8731cf20896a6a1 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..47fc1c6e93d49676bfb333e0a28a893eb1445a67 GIT binary patch literal 3328 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 q>i3NW|F!ci=Lqxk$ + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishi112 Member List
+
+
+ +

This is the complete list of members for IRMitsubishi112, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishi112private
begin(void)IRMitsubishi112
calibrate(void)IRMitsubishi112inline
checksum(void)IRMitsubishi112private
convertFan(const stdAc::fanspeed_t speed)IRMitsubishi112static
convertMode(const stdAc::opmode_t mode)IRMitsubishi112static
convertSwingH(const stdAc::swingh_t position)IRMitsubishi112static
convertSwingV(const stdAc::swingv_t position)IRMitsubishi112static
getFan(void)IRMitsubishi112
getMode(void)IRMitsubishi112
getPower(void)IRMitsubishi112
getQuiet(void)IRMitsubishi112
getRaw(void)IRMitsubishi112
getSwingH(void)IRMitsubishi112
getSwingV(void)IRMitsubishi112
getTemp(void)IRMitsubishi112
IRMitsubishi112(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishi112explicit
off(void)IRMitsubishi112
on(void)IRMitsubishi112
remote_stateIRMitsubishi112private
send(const uint16_t repeat=kMitsubishi112MinRepeat)IRMitsubishi112
setFan(const uint8_t speed)IRMitsubishi112
setMode(const uint8_t mode)IRMitsubishi112
setPower(const bool on)IRMitsubishi112
setQuiet(const bool on)IRMitsubishi112
setRaw(const uint8_t *data)IRMitsubishi112
setSwingH(const uint8_t position)IRMitsubishi112
setSwingV(const uint8_t position)IRMitsubishi112
setTemp(const uint8_t degrees)IRMitsubishi112
stateReset(void)IRMitsubishi112
toCommon(void)IRMitsubishi112
toCommonFanSpeed(const uint8_t speed)IRMitsubishi112static
toCommonMode(const uint8_t mode)IRMitsubishi112static
toCommonSwingH(const uint8_t pos)IRMitsubishi112static
toCommonSwingV(const uint8_t pos)IRMitsubishi112static
toString(void)IRMitsubishi112
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112.html new file mode 100644 index 000000000..601d1e36a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112.html @@ -0,0 +1,1185 @@ + + + + + + + +IRremoteESP8266: IRMitsubishi112 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

#include <ir_Mitsubishi.h>

+
+Collaboration diagram for IRMitsubishi112:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishi112 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishi112MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to off. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingV (const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingH (const uint8_t position)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingH (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate the checksum for the current internal state of the remote. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishi112StateLength]
 The state in code form. More...
 
+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishi112()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishi112::IRMitsubishi112 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishi112::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishi112::checksum (void )
+
+private
+
+ +

Calculate the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi112::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi112::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi112::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi112::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishi112::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRMitsubishi112::getQuiet (void )
+
+ +

Get the Quiet mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+
Note
There is no true quiet setting on this A/C.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishi112::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getSwingH (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::on (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::send (const uint16_t repeat = kMitsubishi112MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
There is no true quiet setting on this A/C.
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setSwingH (const uint8_t position)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setSwingV (const uint8_t position)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishi112::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishi112::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMitsubishi112::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRMitsubishi112::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishi112::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishi112::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishi112::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishi112::remote_state[kMitsubishi112StateLength]
+
+private
+
+ +

The state in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.map new file mode 100644 index 000000000..b03481d27 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 new file mode 100644 index 000000000..40fbd03d5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 @@ -0,0 +1 @@ +648b0b04c461ef09d8fa8c3efa7d7090 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..a75dab94b76a33c3e6843c32ff5e78447e511dfb GIT binary patch literal 3407 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 + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishi136 Member List
+
+
+ +

This is the complete list of members for IRMitsubishi136, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishi136private
begin(void)IRMitsubishi136
calibrate(void)IRMitsubishi136inline
checksum(void)IRMitsubishi136private
convertFan(const stdAc::fanspeed_t speed)IRMitsubishi136static
convertMode(const stdAc::opmode_t mode)IRMitsubishi136static
convertSwingV(const stdAc::swingv_t position)IRMitsubishi136static
getFan(void)IRMitsubishi136
getMode(void)IRMitsubishi136
getPower(void)IRMitsubishi136
getQuiet(void)IRMitsubishi136
getRaw(void)IRMitsubishi136
getSwingV(void)IRMitsubishi136
getTemp(void)IRMitsubishi136
IRMitsubishi136(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishi136explicit
off(void)IRMitsubishi136
on(void)IRMitsubishi136
remote_stateIRMitsubishi136private
send(const uint16_t repeat=kMitsubishi136MinRepeat)IRMitsubishi136
setFan(const uint8_t speed)IRMitsubishi136
setMode(const uint8_t mode)IRMitsubishi136
setPower(const bool on)IRMitsubishi136
setQuiet(const bool on)IRMitsubishi136
setRaw(const uint8_t *data)IRMitsubishi136
setSwingV(const uint8_t position)IRMitsubishi136
setTemp(const uint8_t degrees)IRMitsubishi136
stateReset(void)IRMitsubishi136
toCommon(void)IRMitsubishi136
toCommonFanSpeed(const uint8_t speed)IRMitsubishi136static
toCommonMode(const uint8_t mode)IRMitsubishi136static
toCommonSwingV(const uint8_t pos)IRMitsubishi136static
toString(void)IRMitsubishi136
validChecksum(const uint8_t *data, const uint16_t len=kMitsubishi136StateLength)IRMitsubishi136static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136.html new file mode 100644 index 000000000..456227963 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136.html @@ -0,0 +1,1108 @@ + + + + + + + +IRremoteESP8266: IRMitsubishi136 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Mitsubishi 136-bit A/C messages. + More...

+ +

#include <ir_Mitsubishi.h>

+
+Collaboration diagram for IRMitsubishi136:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishi136 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishi136MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingV (const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t *data, const uint16_t len=kMitsubishi136StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate the checksum for the current internal state of the remote. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishi136StateLength]
 The state in code form. More...
 
+

Detailed Description

+

Class for handling detailed Mitsubishi 136-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishi136()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishi136::IRMitsubishi136 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishi136::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishi136::checksum (void )
+
+private
+
+ +

Calculate the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi136::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi136::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi136::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi136::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi136::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishi136::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRMitsubishi136::getQuiet (void )
+
+ +

Get the Quiet mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishi136::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi136::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi136::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::send (const uint16_t repeat = kMitsubishi136MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setSwingV (const uint8_t position)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishi136::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishi136::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMitsubishi136::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishi136::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishi136::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRMitsubishi136::validChecksum (const uint8_t * data,
const uint16_t len = kMitsubishi136StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]dataThe array to verify the checksum of.
[in]lenThe length of the data array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishi136::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishi136::remote_state[kMitsubishi136StateLength]
+
+private
+
+ +

The state in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.map new file mode 100644 index 000000000..3775846f8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 new file mode 100644 index 000000000..213574ee0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 @@ -0,0 +1 @@ +de5d5156a942dd05dd10b0b63147e763 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..23af714aeb5cf0043042232b08859e4ac655bdeb GIT binary patch literal 3648 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 b;(c(kPie7|8HNuy5`vJL1{&ozZJzuKlwcKU literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC-members.html new file mode 100644 index 000000000..3696a31d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC-members.html @@ -0,0 +1,123 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishiAC Member List
+
+
+ +

This is the complete list of members for IRMitsubishiAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishiACprivate
begin(void)IRMitsubishiAC
calculateChecksum(const uint8_t *data)IRMitsubishiACprivatestatic
calibrate(void)IRMitsubishiACinline
checksum(void)IRMitsubishiACprivate
convertFan(const stdAc::fanspeed_t speed)IRMitsubishiACstatic
convertMode(const stdAc::opmode_t mode)IRMitsubishiACstatic
convertSwingH(const stdAc::swingh_t position)IRMitsubishiACstatic
convertSwingV(const stdAc::swingv_t position)IRMitsubishiACstatic
getClock(void)IRMitsubishiAC
getFan(void)IRMitsubishiAC
getMode(void)IRMitsubishiAC
getPower(void)IRMitsubishiAC
getRaw(void)IRMitsubishiAC
getStartClock(void)IRMitsubishiAC
getStopClock(void)IRMitsubishiAC
getTemp(void)IRMitsubishiAC
getTimer(void)IRMitsubishiAC
getVane(void)IRMitsubishiAC
getWideVane(void)IRMitsubishiAC
IRMitsubishiAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishiACexplicit
off(void)IRMitsubishiAC
on(void)IRMitsubishiAC
remote_stateIRMitsubishiACprivate
send(const uint16_t repeat=kMitsubishiACMinRepeat)IRMitsubishiAC
setClock(const uint8_t clock)IRMitsubishiAC
setFan(const uint8_t speed)IRMitsubishiAC
setMode(const uint8_t mode)IRMitsubishiAC
setPower(const bool on)IRMitsubishiAC
setRaw(const uint8_t *data)IRMitsubishiAC
setStartClock(const uint8_t clock)IRMitsubishiAC
setStopClock(const uint8_t clock)IRMitsubishiAC
setTemp(const uint8_t degrees)IRMitsubishiAC
setTimer(const uint8_t timer)IRMitsubishiAC
setVane(const uint8_t position)IRMitsubishiAC
setWideVane(const uint8_t position)IRMitsubishiAC
stateReset(void)IRMitsubishiAC
toCommon(void)IRMitsubishiAC
toCommonFanSpeed(const uint8_t speed)IRMitsubishiACstatic
toCommonMode(const uint8_t mode)IRMitsubishiACstatic
toCommonSwingH(const uint8_t pos)IRMitsubishiACstatic
toCommonSwingV(const uint8_t pos)IRMitsubishiACstatic
toString(void)IRMitsubishiAC
validChecksum(const uint8_t *data)IRMitsubishiACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC.html new file mode 100644 index 000000000..92707fd32 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC.html @@ -0,0 +1,1437 @@ + + + + + + + +IRremoteESP8266: IRMitsubishiAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control. + More...

+ +

#include <ir_Mitsubishi.h>

+
+Collaboration diagram for IRMitsubishiAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishiAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishiACMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setVane (const uint8_t position)
 Set the requested vane (Vertical Swing) operation mode of the a/c unit. More...
 
void setWideVane (const uint8_t position)
 Set the requested wide-vane (Horizontal Swing) operation mode of the a/c. More...
 
uint8_t getVane (void)
 Get the Vane (Vertical Swing) mode of the A/C. More...
 
uint8_t getWideVane (void)
 Get the Wide Vane (Horizontal Swing) mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t getClock (void)
 Get the clock time of the A/C unit. More...
 
void setClock (const uint8_t clock)
 Set the clock time on the A/C unit. More...
 
uint8_t getStartClock (void)
 Get the desired start time of the A/C unit. More...
 
void setStartClock (const uint8_t clock)
 Set the desired start time of the A/C unit. More...
 
uint8_t getStopClock (void)
 Get the desired stop time of the A/C unit. More...
 
void setStopClock (const uint8_t clock)
 Set the desired stop time of the A/C unit. More...
 
uint8_t getTimer (void)
 Get the timers active setting of the A/C. More...
 
void setTimer (const uint8_t timer)
 Set the timers active setting of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t *data)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calculateChecksum (const uint8_t *data)
 Calculate the checksum for a given state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishiACStateLength]
 The state in code form. More...
 
+

Detailed Description

+

Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control.

+
Warning
Consider this very alpha code. Seems to work, but not validated.
+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishiAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishiAC::IRMitsubishiAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+
Warning
Consider this very alpha code. Seems to work, but not validated.
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calculateChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::calculateChecksum (const uint8_t * data)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]dataThe value to calc the checksum of.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishiAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishiAC::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getClock (void )
+
+ +

Get the clock time of the A/C unit.

+
Returns
Nr. of 10 minute increments past midnight.
+
Note
1 = 1/6 hour (10 minutes). e.g. 4pm = 48.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishiAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishiAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getStartClock()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getStartClock (void )
+
+ +

Get the desired start time of the A/C unit.

+
Returns
Nr. of 10 minute increments past midnight.
+
Note
1 = 1/6 hour (10 minutes). e.g. 4pm = 48.
+ +
+
+ +

◆ getStopClock()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getStopClock (void )
+
+ +

Get the desired stop time of the A/C unit.

+
Returns
Nr. of 10 minute increments past midnight.
+
Note
1 = 1/6 hour (10 minutes). e.g. 10pm = 132.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getTimer (void )
+
+ +

Get the timers active setting of the A/C.

+
Returns
The current timers enabled.
+
Note
Possible values: kMitsubishiAcNoTimer, kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, kMitsubishiAcStartStopTimer
+ +
+
+ +

◆ getVane()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getVane (void )
+
+ +

Get the Vane (Vertical Swing) mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getWideVane()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getWideVane (void )
+
+ +

Get the Wide Vane (Horizontal Swing) mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::send (const uint16_t repeat = kMitsubishiACMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setClock (const uint8_t clock)
+
+ +

Set the clock time on the A/C unit.

+
Parameters
+ + +
[in]clockNr. of 10 minute increments past midnight.
+
+
+
Note
1 = 1/6 hour (10 minutes). e.g. 6am = 36.
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting. 0 is auto, 1-5 is speed, 6 is silent.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setStartClock()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setStartClock (const uint8_t clock)
+
+ +

Set the desired start time of the A/C unit.

+
Parameters
+ + +
[in]clockNr. of 10 minute increments past midnight.
+
+
+
Note
1 = 1/6 hour (10 minutes). e.g. 8pm = 120.
+ +
+
+ +

◆ setStopClock()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setStopClock (const uint8_t clock)
+
+ +

Set the desired stop time of the A/C unit.

+
Parameters
+ + +
[in]clockNr. of 10 minute increments past midnight.
+
+
+
Note
1 = 1/6 hour (10 minutes). e.g. 10pm = 132.
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setTimer (const uint8_t timer)
+
+ +

Set the timers active setting of the A/C.

+
Parameters
+ + +
[in]timerThe timer code indicating which ones are active.
+
+
+
Note
Possible values: kMitsubishiAcNoTimer, kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, kMitsubishiAcStartStopTimer
+ +
+
+ +

◆ setVane()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setVane (const uint8_t position)
+
+ +

Set the requested vane (Vertical Swing) operation mode of the a/c unit.

+
Parameters
+ + +
[in]positionThe position/mode to set the vane to.
+
+
+ +
+
+ +

◆ setWideVane()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setWideVane (const uint8_t position)
+
+ +

Set the requested wide-vane (Horizontal Swing) operation mode of the a/c.

+
Parameters
+ + +
[in]positionThe position/mode to set the wide vane to.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishiAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishiAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMitsubishiAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRMitsubishiAC::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishiAC::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishiAC::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRMitsubishiAC::validChecksum (const uint8_t * data)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]dataThe array to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishiAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishiAC::remote_state[kMitsubishiACStateLength]
+
+private
+
+ +

The state in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map new file mode 100644 index 000000000..627b45a20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 new file mode 100644 index 000000000..2eda9cf87 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 @@ -0,0 +1 @@ +c5704e67d45afe4844036674d82d8c46 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..cc1362a2285ddc2abb140a7b2c6ea01b2ce0588c GIT binary patch literal 3489 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 F{{uV9qMrZ& literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html new file mode 100644 index 000000000..b8ea4cc00 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html @@ -0,0 +1,129 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishiHeavy152Ac Member List
+
+
+ +

This is the complete list of members for IRMitsubishiHeavy152Ac, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishiHeavy152Acprivate
begin(void)IRMitsubishiHeavy152Ac
calibrate(void)IRMitsubishiHeavy152Acinline
checksum(void)IRMitsubishiHeavy152Acprivate
checkZmsSig(const uint8_t *state)IRMitsubishiHeavy152Acstatic
convertFan(const stdAc::fanspeed_t speed)IRMitsubishiHeavy152Acstatic
convertMode(const stdAc::opmode_t mode)IRMitsubishiHeavy152Acstatic
convertSwingH(const stdAc::swingh_t position)IRMitsubishiHeavy152Acstatic
convertSwingV(const stdAc::swingv_t position)IRMitsubishiHeavy152Acstatic
get3D(void)IRMitsubishiHeavy152Ac
getClean(void)IRMitsubishiHeavy152Ac
getEcono(void)IRMitsubishiHeavy152Ac
getFan(void)IRMitsubishiHeavy152Ac
getFilter(void)IRMitsubishiHeavy152Ac
getMode(void)IRMitsubishiHeavy152Ac
getNight(void)IRMitsubishiHeavy152Ac
getPower(void)IRMitsubishiHeavy152Ac
getRaw(void)IRMitsubishiHeavy152Ac
getSilent(void)IRMitsubishiHeavy152Ac
getSwingHorizontal(void)IRMitsubishiHeavy152Ac
getSwingVertical(void)IRMitsubishiHeavy152Ac
getTemp(void)IRMitsubishiHeavy152Ac
getTurbo(void)IRMitsubishiHeavy152Ac
IRMitsubishiHeavy152Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishiHeavy152Acexplicit
off(void)IRMitsubishiHeavy152Ac
on(void)IRMitsubishiHeavy152Ac
remote_stateIRMitsubishiHeavy152Acprivate
send(const uint16_t repeat=kMitsubishiHeavy152MinRepeat)IRMitsubishiHeavy152Ac
set3D(const bool on)IRMitsubishiHeavy152Ac
setClean(const bool on)IRMitsubishiHeavy152Ac
setEcono(const bool on)IRMitsubishiHeavy152Ac
setFan(const uint8_t fan)IRMitsubishiHeavy152Ac
setFilter(const bool on)IRMitsubishiHeavy152Ac
setMode(const uint8_t mode)IRMitsubishiHeavy152Ac
setNight(const bool on)IRMitsubishiHeavy152Ac
setPower(const bool on)IRMitsubishiHeavy152Ac
setRaw(const uint8_t *data)IRMitsubishiHeavy152Ac
setSilent(const bool on)IRMitsubishiHeavy152Ac
setSwingHorizontal(const uint8_t pos)IRMitsubishiHeavy152Ac
setSwingVertical(const uint8_t pos)IRMitsubishiHeavy152Ac
setTemp(const uint8_t temp)IRMitsubishiHeavy152Ac
setTurbo(const bool on)IRMitsubishiHeavy152Ac
stateReset(void)IRMitsubishiHeavy152Ac
toCommon(void)IRMitsubishiHeavy152Ac
toCommonFanSpeed(const uint8_t speed)IRMitsubishiHeavy152Acstatic
toCommonMode(const uint8_t mode)IRMitsubishiHeavy152Acstatic
toCommonSwingH(const uint8_t pos)IRMitsubishiHeavy152Acstatic
toCommonSwingV(const uint8_t pos)IRMitsubishiHeavy152Acstatic
toString(void)IRMitsubishiHeavy152Ac
validChecksum(const uint8_t *state, const uint16_t length=kMitsubishiHeavy152StateLength)IRMitsubishiHeavy152Acstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html new file mode 100644 index 000000000..061206339 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html @@ -0,0 +1,1593 @@ + + + + + + + +IRremoteESP8266: IRMitsubishiHeavy152Ac Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Mitsubishi Heavy 152-bit A/C messages. + More...

+ +

#include <ir_MitsubishiHeavy.h>

+
+Collaboration diagram for IRMitsubishiHeavy152Ac:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishiHeavy152Ac (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishiHeavy152MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const uint8_t pos)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const uint8_t pos)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setNight (const bool on)
 Set the Night (Sleep) mode of the A/C. More...
 
bool getNight (void)
 Get the Night (Sleep) mode of the A/C. More...
 
void set3D (const bool on)
 Set the 3D mode of the A/C. More...
 
bool get3D (void)
 Get the 3D mode of the A/C. More...
 
void setSilent (const bool on)
 Set the Silent (Quiet) mode of the A/C. More...
 
bool getSilent (void)
 Get the Silent (Quiet) mode of the A/C. More...
 
void setFilter (const bool on)
 Set the Filter mode of the A/C. More...
 
bool getFilter (void)
 Get the Filter mode of the A/C. More...
 
void setClean (const bool on)
 Set the Clean mode of the A/C. More...
 
bool getClean (void)
 Get the Clean mode of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo mode of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economical mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool checkZmsSig (const uint8_t *state)
 Verify the given state has a ZM-S signature. More...
 
static bool validChecksum (const uint8_t *state, const uint16_t length=kMitsubishiHeavy152StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate the checksum for the current internal state of the remote. Note: Technically it has no checksum, but does has inverted byte pairs. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishiHeavy152StateLength]
 State in code form. More...
 
+

Detailed Description

+

Class for handling detailed Mitsubishi Heavy 152-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishiHeavy152Ac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishiHeavy152Ac::IRMitsubishiHeavy152Ac (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishiHeavy152Ac::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::checksum (void )
+
+private
+
+ +

Calculate the checksum for the current internal state of the remote. Note: Technically it has no checksum, but does has inverted byte pairs.

+ +
+
+ +

◆ checkZmsSig()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::checkZmsSig (const uint8_t * state)
+
+static
+
+ +

Verify the given state has a ZM-S signature.

+
Parameters
+ + +
[in]stateA ptr to a state to be checked.
+
+
+
Returns
true, the check passed. Otherwise, false.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ get3D()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::get3D (void )
+
+ +

Get the 3D mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getClean (void )
+
+ +

Get the Clean mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getFilter()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getFilter (void )
+
+ +

Get the Filter mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getNight()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getNight (void )
+
+ +

Get the Night (Sleep) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishiHeavy152Ac::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSilent()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getSilent (void )
+
+ +

Get the Silent (Quiet) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getTurbo (void )
+
+ +

Get the Turbo mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::send (const uint16_t repeat = kMitsubishiHeavy152MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ set3D()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::set3D (const bool on)
+
+ +

Set the 3D mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setClean (const bool on)
+
+ +

Set the Clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setEcono (const bool on)
+
+ +

Set the Economical mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setFilter()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setFilter (const bool on)
+
+ +

Set the Filter mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setNight()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setNight (const bool on)
+
+ +

Set the Night (Sleep) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSilent()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setSilent (const bool on)
+
+ +

Set the Silent (Quiet) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setSwingHorizontal (const uint8_t pos)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setSwingVertical (const uint8_t pos)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setTurbo (const bool on)
+
+ +

Set the Turbo mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishiHeavy152Ac::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishiHeavy152Ac::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMitsubishiHeavy152Ac::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRMitsubishiHeavy152Ac::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishiHeavy152Ac::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishiHeavy152Ac::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRMitsubishiHeavy152Ac::validChecksum (const uint8_t * state,
const uint16_t length = kMitsubishiHeavy152StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false. Note: Technically it has no checksum, but does has inverted byte pairs.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishiHeavy152Ac::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishiHeavy152Ac::remote_state[kMitsubishiHeavy152StateLength]
+
+private
+
+ +

State in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map new file mode 100644 index 000000000..d1dc4b52e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 new file mode 100644 index 000000000..df1c2c463 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 @@ -0,0 +1 @@ +6ea04c88e8883bfc89458f5de25fdcea \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..2a4f52ae4b57e643d31c0e8bae7fbbee9c0f8432 GIT binary patch literal 4959 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 E0TJ4;3IG5A literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html new file mode 100644 index 000000000..e974689c6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html @@ -0,0 +1,122 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishiHeavy88Ac Member List
+
+
+ +

This is the complete list of members for IRMitsubishiHeavy88Ac, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishiHeavy88Acprivate
begin(void)IRMitsubishiHeavy88Ac
calibrate(void)IRMitsubishiHeavy88Acinline
checksum(void)IRMitsubishiHeavy88Acprivate
checkZjsSig(const uint8_t *state)IRMitsubishiHeavy88Acstatic
convertFan(const stdAc::fanspeed_t speed)IRMitsubishiHeavy88Acstatic
convertMode(const stdAc::opmode_t mode)IRMitsubishiHeavy88Acstatic
convertSwingH(const stdAc::swingh_t position)IRMitsubishiHeavy88Acstatic
convertSwingV(const stdAc::swingv_t position)IRMitsubishiHeavy88Acstatic
get3D(void)IRMitsubishiHeavy88Ac
getClean(void)IRMitsubishiHeavy88Ac
getEcono(void)IRMitsubishiHeavy88Ac
getFan(void)IRMitsubishiHeavy88Ac
getMode(void)IRMitsubishiHeavy88Ac
getPower(void)IRMitsubishiHeavy88Ac
getRaw(void)IRMitsubishiHeavy88Ac
getSwingHorizontal(void)IRMitsubishiHeavy88Ac
getSwingVertical(void)IRMitsubishiHeavy88Ac
getTemp(void)IRMitsubishiHeavy88Ac
getTurbo(void)IRMitsubishiHeavy88Ac
IRMitsubishiHeavy88Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishiHeavy88Acexplicit
off(void)IRMitsubishiHeavy88Ac
on(void)IRMitsubishiHeavy88Ac
remote_stateIRMitsubishiHeavy88Acprivate
send(const uint16_t repeat=kMitsubishiHeavy88MinRepeat)IRMitsubishiHeavy88Ac
set3D(const bool on)IRMitsubishiHeavy88Ac
setClean(const bool on)IRMitsubishiHeavy88Ac
setEcono(const bool on)IRMitsubishiHeavy88Ac
setFan(const uint8_t fan)IRMitsubishiHeavy88Ac
setMode(const uint8_t mode)IRMitsubishiHeavy88Ac
setPower(const bool on)IRMitsubishiHeavy88Ac
setRaw(const uint8_t *data)IRMitsubishiHeavy88Ac
setSwingHorizontal(const uint8_t pos)IRMitsubishiHeavy88Ac
setSwingVertical(const uint8_t pos)IRMitsubishiHeavy88Ac
setTemp(const uint8_t temp)IRMitsubishiHeavy88Ac
setTurbo(const bool on)IRMitsubishiHeavy88Ac
stateReset(void)IRMitsubishiHeavy88Ac
toCommon(void)IRMitsubishiHeavy88Ac
toCommonFanSpeed(const uint8_t speed)IRMitsubishiHeavy88Acstatic
toCommonSwingH(const uint8_t pos)IRMitsubishiHeavy88Acstatic
toCommonSwingV(const uint8_t pos)IRMitsubishiHeavy88Acstatic
toString(void)IRMitsubishiHeavy88Ac
validChecksum(const uint8_t *state, const uint16_t length=kMitsubishiHeavy88StateLength)IRMitsubishiHeavy88Acstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html new file mode 100644 index 000000000..2831dc0bd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html @@ -0,0 +1,1396 @@ + + + + + + + +IRremoteESP8266: IRMitsubishiHeavy88Ac Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Mitsubishi Heavy 88-bit A/C messages. + More...

+ +

#include <ir_MitsubishiHeavy.h>

+
+Collaboration diagram for IRMitsubishiHeavy88Ac:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishiHeavy88Ac (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishiHeavy88MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const uint8_t pos)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const uint8_t pos)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo mode of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economical mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
void set3D (const bool on)
 Set the 3D mode of the A/C. More...
 
bool get3D (void)
 Get the 3D mode of the A/C. More...
 
void setClean (const bool on)
 Set the Clean mode of the A/C. More...
 
bool getClean (void)
 Get the Clean mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool checkZjsSig (const uint8_t *state)
 Verify the given state has a ZJ-S signature. More...
 
static bool validChecksum (const uint8_t *state, const uint16_t length=kMitsubishiHeavy88StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate the checksum for the current internal state of the remote. Note: Technically it has no checksum, but does has inverted byte pairs. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishiHeavy88StateLength]
 State in code form. More...
 
+

Detailed Description

+

Class for handling detailed Mitsubishi Heavy 88-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishiHeavy88Ac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishiHeavy88Ac::IRMitsubishiHeavy88Ac (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishiHeavy88Ac::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::checksum (void )
+
+private
+
+ +

Calculate the checksum for the current internal state of the remote. Note: Technically it has no checksum, but does has inverted byte pairs.

+ +
+
+ +

◆ checkZjsSig()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::checkZjsSig (const uint8_t * state)
+
+static
+
+ +

Verify the given state has a ZJ-S signature.

+
Parameters
+ + +
[in]stateA ptr to a state to be checked.
+
+
+
Returns
true, the check passed. Otherwise, false.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ get3D()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::get3D (void )
+
+ +

Get the 3D mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::getClean (void )
+
+ +

Get the Clean mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishiHeavy88Ac::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::getTurbo (void )
+
+ +

Get the Turbo mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::send (const uint16_t repeat = kMitsubishiHeavy88MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ set3D()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::set3D (const bool on)
+
+ +

Set the 3D mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setClean (const bool on)
+
+ +

Set the Clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setEcono (const bool on)
+
+ +

Set the Economical mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setSwingHorizontal (const uint8_t pos)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setSwingVertical (const uint8_t pos)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setTurbo (const bool on)
+
+ +

Set the Turbo mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishiHeavy88Ac::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishiHeavy88Ac::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRMitsubishiHeavy88Ac::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishiHeavy88Ac::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishiHeavy88Ac::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRMitsubishiHeavy88Ac::validChecksum (const uint8_t * state,
const uint16_t length = kMitsubishiHeavy88StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false. Note: Technically it has no checksum, but does has inverted byte pairs.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishiHeavy88Ac::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishiHeavy88Ac::remote_state[kMitsubishiHeavy88StateLength]
+
+private
+
+ +

State in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map new file mode 100644 index 000000000..924baf61e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 new file mode 100644 index 000000000..c159b188d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 @@ -0,0 +1 @@ +efa3e5f38fe575e86f5114c55d9276b8 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..c50dbc0c424de71e43dc99b07d9d6a661880c908 GIT binary patch literal 4835 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 xQ1iQLaRcABK=!{%8md>a + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRNeoclimaAc Member List
+
+
+ +

This is the complete list of members for IRNeoclimaAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRNeoclimaAcprivate
begin(void)IRNeoclimaAc
calcChecksum(const uint8_t state[], const uint16_t length=kNeoclimaStateLength)IRNeoclimaAcstatic
calibrate(void)IRNeoclimaAcinline
checksum(const uint16_t length=kNeoclimaStateLength)IRNeoclimaAcprivate
convertFan(const stdAc::fanspeed_t speed)IRNeoclimaAc
convertMode(const stdAc::opmode_t mode)IRNeoclimaAc
get8CHeat(void)IRNeoclimaAc
getButton(void)IRNeoclimaAc
getEye(void)IRNeoclimaAc
getFan(void)IRNeoclimaAc
getFollow(void)IRNeoclimaAc
getFresh(void)IRNeoclimaAc
getHold(void)IRNeoclimaAc
getIon(void)IRNeoclimaAc
getLight(void)IRNeoclimaAc
getMode(void)IRNeoclimaAc
getPower(void)IRNeoclimaAc
getRaw(void)IRNeoclimaAc
getSleep(void)IRNeoclimaAc
getSwingH(void)IRNeoclimaAc
getSwingV(void)IRNeoclimaAc
getTemp(void)IRNeoclimaAc
getTurbo(void)IRNeoclimaAc
IRNeoclimaAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRNeoclimaAcexplicit
off(void)IRNeoclimaAc
on(void)IRNeoclimaAc
remote_stateIRNeoclimaAcprivate
send(const uint16_t repeat=kNeoclimaMinRepeat)IRNeoclimaAc
set8CHeat(const bool on)IRNeoclimaAc
setButton(const uint8_t button)IRNeoclimaAc
setEye(const bool on)IRNeoclimaAc
setFan(const uint8_t speed)IRNeoclimaAc
setFresh(const bool on)IRNeoclimaAc
setHold(const bool on)IRNeoclimaAc
setIon(const bool on)IRNeoclimaAc
setLight(const bool on)IRNeoclimaAc
setMode(const uint8_t mode)IRNeoclimaAc
setPower(const bool on)IRNeoclimaAc
setRaw(const uint8_t new_code[], const uint16_t length=kNeoclimaStateLength)IRNeoclimaAc
setSleep(const bool on)IRNeoclimaAc
setSwingH(const bool on)IRNeoclimaAc
setSwingV(const bool on)IRNeoclimaAc
setTemp(const uint8_t temp)IRNeoclimaAc
setTurbo(const bool on)IRNeoclimaAc
stateReset(void)IRNeoclimaAc
toCommon(void)IRNeoclimaAc
toCommonFanSpeed(const uint8_t speed)IRNeoclimaAcstatic
toCommonMode(const uint8_t mode)IRNeoclimaAcstatic
toString(void)IRNeoclimaAc
validChecksum(const uint8_t state[], const uint16_t length=kNeoclimaStateLength)IRNeoclimaAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc.html new file mode 100644 index 000000000..4cec65c07 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc.html @@ -0,0 +1,1584 @@ + + + + + + + +IRremoteESP8266: IRNeoclimaAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Neoclima A/C messages. + More...

+ +

#include <ir_Neoclima.h>

+
+Collaboration diagram for IRNeoclimaAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRNeoclimaAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kNeoclimaMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void setButton (const uint8_t button)
 Set the Button/Command pressed setting of the A/C. More...
 
uint8_t getButton (void)
 Get the Button/Command setting of the A/C. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingV (const bool on)
 Set the vertical swing setting of the A/C. More...
 
bool getSwingV (void)
 Get the vertical swing setting of the A/C. More...
 
void setSwingH (const bool on)
 Set the horizontal swing setting of the A/C. More...
 
bool getSwingH (void)
 Get the horizontal swing (Air Flow) setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setFresh (const bool on)
 Set the Fresh (air) setting of the A/C. More...
 
bool getFresh (void)
 Get the Frsh (air) setting of the A/C. More...
 
void setHold (const bool on)
 Set the Hold setting of the A/C. More...
 
bool getHold (void)
 Get the Hold setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (filter) setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (filter) setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light(LED display) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED display) setting of the A/C. More...
 
void set8CHeat (const bool on)
 Set the 8°C Heat setting of the A/C. More...
 
bool get8CHeat (void)
 Get the 8°C Heat setting of the A/C. More...
 
void setEye (const bool on)
 Set the Eye (Sensor) setting of the A/C. More...
 
bool getEye (void)
 Get the Eye (Sensor) setting of the A/C. More...
 
bool getFollow (void)
 Get the Follow Me setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kNeoclimaStateLength)
 Set the internal state from a valid code for this protocol. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kNeoclimaStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kNeoclimaStateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kNeoclimaStateLength)
 Calculate & update the checksum for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kNeoclimaStateLength]
 State of the remote in code. More...
 
+

Detailed Description

+

Class for handling detailed Neoclima A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRNeoclimaAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRNeoclimaAc::IRNeoclimaAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRNeoclimaAc::calcChecksum (const uint8_t state[],
const uint16_t length = kNeoclimaStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRNeoclimaAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRNeoclimaAc::checksum (const uint16_t length = kNeoclimaStateLength)
+
+private
+
+ +

Calculate & update the checksum for the internal state.

+
Parameters
+ + +
[in]lengthThe length/size of the internal state.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ get8CHeat()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::get8CHeat (void )
+
+ +

Get the 8°C Heat setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getButton()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::getButton (void )
+
+ +

Get the Button/Command setting of the A/C.

+
Returns
The value of the button/command that was pressed.
+ +
+
+ +

◆ getEye()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getEye (void )
+
+ +

Get the Eye (Sensor) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getFollow()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getFollow (void )
+
+ +

Get the Follow Me setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFresh()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getFresh (void )
+
+ +

Get the Frsh (air) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getHold()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getHold (void )
+
+ +

Get the Hold setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getIon (void )
+
+ +

Get the Ion (filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getLight (void )
+
+ +

Get the Light (LED display) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRNeoclimaAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getSwingH (void )
+
+ +

Get the horizontal swing (Air Flow) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getSwingV (void )
+
+ +

Get the vertical swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::send (const uint16_t repeat = kNeoclimaMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ set8CHeat()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::set8CHeat (const bool on)
+
+ +

Set the 8°C Heat setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
This feature maintains the room temperature steadily at 8°C and prevents the room from freezing by activating the heating operation automatically when nobody is at home over a longer period during severe winter.
+ +
+
+ +

◆ setButton()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setButton (const uint8_t button)
+
+ +

Set the Button/Command pressed setting of the A/C.

+
Parameters
+ + +
[in]buttonThe value of the button/command that was pressed.
+
+
+ +
+
+ +

◆ setEye()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setEye (const bool on)
+
+ +

Set the Eye (Sensor) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting. 0-3, 0 is auto, 1-3 is the speed
+
+
+ +
+
+ +

◆ setFresh()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setFresh (const bool on)
+
+ +

Set the Fresh (air) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setHold()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setHold (const bool on)
+
+ +

Set the Hold setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setIon (const bool on)
+
+ +

Set the Ion (filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setLight (const bool on)
+
+ +

Set the Light(LED display) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRNeoclimaAc::setRaw (const uint8_t new_code[],
const uint16_t length = kNeoclimaStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setSwingH (const bool on)
+
+ +

Set the horizontal swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setSwingV (const bool on)
+
+ +

Set the vertical swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRNeoclimaAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRNeoclimaAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRNeoclimaAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRNeoclimaAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRNeoclimaAc::validChecksum (const uint8_t state[],
const uint16_t length = kNeoclimaStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRNeoclimaAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRNeoclimaAc::remote_state[kNeoclimaStateLength]
+
+private
+
+ +

State of the remote in code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map new file mode 100644 index 000000000..57358d833 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 new file mode 100644 index 000000000..fe697a810 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 @@ -0,0 +1 @@ +1e6ee18f808b645d10f6652b3a78aca2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..9515ee73a64712d49d10e556d7f305e6ba48bf2d GIT binary patch literal 3405 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 A2><{9 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc-members.html new file mode 100644 index 000000000..50e639d84 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc-members.html @@ -0,0 +1,138 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRPanasonicAc Member List
+
+
+ +

This is the complete list of members for IRPanasonicAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_getTime(const uint8_t ptr[])IRPanasonicAcprivatestatic
_irsendIRPanasonicAcprivate
_setTime(uint8_t *const ptr, const uint16_t mins_since_midnight, const bool round_down)IRPanasonicAcprivatestatic
_swinghIRPanasonicAcprivate
_tempIRPanasonicAcprivate
begin(void)IRPanasonicAc
calcChecksum(const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)IRPanasonicAcstatic
calibrate(void)IRPanasonicAcinline
cancelOffTimer(void)IRPanasonicAc
cancelOnTimer(void)IRPanasonicAc
convertFan(const stdAc::fanspeed_t speed)IRPanasonicAcstatic
convertMode(const stdAc::opmode_t mode)IRPanasonicAcstatic
convertSwingH(const stdAc::swingh_t position)IRPanasonicAcstatic
convertSwingV(const stdAc::swingv_t position)IRPanasonicAcstatic
encodeTime(const uint8_t hours, const uint8_t mins)IRPanasonicAcstatic
fixChecksum(const uint16_t length=kPanasonicAcStateLength)IRPanasonicAcprivate
getClock(void)IRPanasonicAc
getFan(void)IRPanasonicAc
getIon(void)IRPanasonicAc
getMode(void)IRPanasonicAc
getModel(void)IRPanasonicAc
getOffTimer(void)IRPanasonicAc
getOnTimer(void)IRPanasonicAc
getPower(void)IRPanasonicAc
getPowerful(void)IRPanasonicAc
getQuiet(void)IRPanasonicAc
getRaw(void)IRPanasonicAc
getSwingHorizontal(void)IRPanasonicAc
getSwingVertical(void)IRPanasonicAc
getTemp(void)IRPanasonicAc
IRPanasonicAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRPanasonicAcexplicit
isOffTimerEnabled(void)IRPanasonicAc
isOnTimerEnabled(void)IRPanasonicAc
off(void)IRPanasonicAc
on(void)IRPanasonicAc
remote_stateIRPanasonicAcprivate
send(const uint16_t repeat=kPanasonicAcDefaultRepeat)IRPanasonicAc
setClock(const uint16_t mins_since_midnight)IRPanasonicAc
setFan(const uint8_t fan)IRPanasonicAc
setIon(const bool on)IRPanasonicAc
setMode(const uint8_t mode)IRPanasonicAc
setModel(const panasonic_ac_remote_model_t model)IRPanasonicAc
setOffTimer(const uint16_t mins_since_midnight, const bool enable=true)IRPanasonicAc
setOnTimer(const uint16_t mins_since_midnight, const bool enable=true)IRPanasonicAc
setPower(const bool on)IRPanasonicAc
setPowerful(const bool on)IRPanasonicAc
setQuiet(const bool on)IRPanasonicAc
setRaw(const uint8_t state[])IRPanasonicAc
setSwingHorizontal(const uint8_t direction)IRPanasonicAc
setSwingVertical(const uint8_t elevation)IRPanasonicAc
setTemp(const uint8_t temp, const bool remember=true)IRPanasonicAc
stateReset(void)IRPanasonicAc
toCommon(void)IRPanasonicAc
toCommonFanSpeed(const uint8_t speed)IRPanasonicAcstatic
toCommonMode(const uint8_t mode)IRPanasonicAcstatic
toCommonSwingH(const uint8_t pos)IRPanasonicAcstatic
toCommonSwingV(const uint8_t pos)IRPanasonicAcstatic
toString(void)IRPanasonicAc
validChecksum(const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)IRPanasonicAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc.html new file mode 100644 index 000000000..208d2d289 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc.html @@ -0,0 +1,1936 @@ + + + + + + + +IRremoteESP8266: IRPanasonicAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Panasonic A/C messages. + More...

+ +

#include <ir_Panasonic.h>

+
+Collaboration diagram for IRPanasonicAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRPanasonicAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kPanasonicAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Control the power state of the A/C unit. More...
 
bool getPower (void)
 Get the A/C power state of the remote. More...
 
void setTemp (const uint8_t temp, const bool remember=true)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setRaw (const uint8_t state[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setQuiet (const bool on)
 Set the Quiet setting of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet setting of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) setting of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (filter) setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (filter) setting of the A/C. More...
 
void setModel (const panasonic_ac_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
panasonic_ac_remote_model_t getModel (void)
 Get/Detect the model of the A/C. More...
 
void setSwingVertical (const uint8_t elevation)
 Control the vertical swing setting. More...
 
uint8_t getSwingVertical (void)
 Get the current vertical swing setting. More...
 
void setSwingHorizontal (const uint8_t direction)
 Control the horizontal swing setting. More...
 
uint8_t getSwingHorizontal (void)
 Get the current horizontal swing setting. More...
 
uint16_t getClock (void)
 Get the current clock time value. More...
 
void setClock (const uint16_t mins_since_midnight)
 Set the current clock time value. More...
 
uint16_t getOnTimer (void)
 Get the On Timer time value. More...
 
void setOnTimer (const uint16_t mins_since_midnight, const bool enable=true)
 Set/Enable the On Timer. More...
 
void cancelOnTimer (void)
 Cancel the On Timer. More...
 
bool isOnTimerEnabled (void)
 Check if the On Timer is Enabled. More...
 
uint16_t getOffTimer (void)
 Get the Off Timer time value. More...
 
void setOffTimer (const uint16_t mins_since_midnight, const bool enable=true)
 Set/Enable the Off Timer. More...
 
void cancelOffTimer (void)
 Cancel the Off Timer. More...
 
bool isOffTimerEnabled (void)
 Check if the Off Timer is Enabled. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)
 Calculate the checksum for a given state. More...
 
static uint16_t encodeTime (const uint8_t hours, const uint8_t mins)
 Convert standard (military/24hr) time to nr. of minutes since midnight. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a standard A/C vertical swing into its native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a standard A/C horizontal swing into its native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void fixChecksum (const uint16_t length=kPanasonicAcStateLength)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Static Private Member Functions

static uint16_t _getTime (const uint8_t ptr[])
 Get the time from a given pointer location. More...
 
static void _setTime (uint8_t *const ptr, const uint16_t mins_since_midnight, const bool round_down)
 Set the time at a given pointer location. More...
 
+ + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kPanasonicAcStateLength]
 The state in code form. More...
 
uint8_t _swingh
 
uint8_t _temp
 
+

Detailed Description

+

Class for handling detailed Panasonic A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRPanasonicAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRPanasonicAc::IRPanasonicAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _getTime()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRPanasonicAc::_getTime (const uint8_t ptr[])
+
+staticprivate
+
+ +

Get the time from a given pointer location.

+
Parameters
+ + +
[in]ptrA pointer to a time location in a state.
+
+
+
Returns
The time expressed as nr. of minutes past midnight.
+
Note
Internal use only.
+ +
+
+ +

◆ _setTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRPanasonicAc::_setTime (uint8_t *const ptr,
const uint16_t mins_since_midnight,
const bool round_down 
)
+
+staticprivate
+
+ +

Set the time at a given pointer location.

+
Parameters
+ + + + +
[in,out]ptrA pointer to a time location in a state.
[in]mins_since_midnightThe time as nr. of minutes past midnight.
[in]round_downDo we round to the nearest 10 minute mark?
+
+
+
Note
Internal use only.
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRPanasonicAc::calcChecksum (const uint8_t * state,
const uint16_t length = kPanasonicAcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe value to calc the checksum of.
[in]lengthThe size/length of the state.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRPanasonicAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ cancelOffTimer()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::cancelOffTimer (void )
+
+ +

Cancel the Off Timer.

+ +
+
+ +

◆ cancelOnTimer()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::cancelOnTimer (void )
+
+ +

Cancel the On Timer.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRPanasonicAc::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRPanasonicAc::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRPanasonicAc::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a standard A/C horizontal swing into its native setting.

+
Parameters
+ + +
[in]positionA stdAc::swingh_t position to convert.
+
+
+
Returns
The equivilent native horizontal swing position.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRPanasonicAc::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a standard A/C vertical swing into its native setting.

+
Parameters
+ + +
[in]positionA stdAc::swingv_t position to convert.
+
+
+
Returns
The equivilent native horizontal swing position.
+ +
+
+ +

◆ encodeTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint16_t IRPanasonicAc::encodeTime (const uint8_t hours,
const uint8_t mins 
)
+
+static
+
+ +

Convert standard (military/24hr) time to nr. of minutes since midnight.

+
Parameters
+ + + +
[in]hoursThe hours component of the time.
[in]minsThe minutes component of the time.
+
+
+
Returns
The nr of minutes since midnight.
+ +
+
+ +

◆ fixChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRPanasonicAc::fixChecksum (const uint16_t length = kPanasonicAcStateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe size/length of the state.
+
+
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint16_t IRPanasonicAc::getClock (void )
+
+ +

Get the current clock time value.

+
Returns
The time expressed as nr. of minutes past midnight.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::getIon (void )
+
+ +

Get the Ion (filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
panasonic_ac_remote_model_t IRPanasonicAc::getModel (void )
+
+ +

Get/Detect the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRPanasonicAc::getOffTimer (void )
+
+ +

Get the Off Timer time value.

+
Returns
The time expressed as nr. of minutes past midnight.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRPanasonicAc::getOnTimer (void )
+
+ +

Get the On Timer time value.

+
Returns
The time expressed as nr. of minutes past midnight.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::getPower (void )
+
+ +

Get the A/C power state of the remote.

+
Returns
true, the setting is on. false, the setting is off.
+
Warning
Except for CKP models, where it returns if the power state will be toggled on the A/C unit when the next message is sent.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::getPowerful (void )
+
+ +

Get the Powerful (Turbo) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::getQuiet (void )
+
+ +

Get the Quiet setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRPanasonicAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getSwingHorizontal (void )
+
+ +

Get the current horizontal swing setting.

+
Returns
The current position it is set to.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getSwingVertical (void )
+
+ +

Get the current vertical swing setting.

+
Returns
The current position it is set to.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ isOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::isOffTimerEnabled (void )
+
+ +

Check if the Off Timer is Enabled.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isOnTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::isOnTimerEnabled (void )
+
+ +

Check if the On Timer is Enabled.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::send (const uint16_t repeat = kPanasonicAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setClock (const uint16_t mins_since_midnight)
+
+ +

Set the current clock time value.

+
Parameters
+ + +
[in]mins_since_midnightThe time as nr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setIon (const bool on)
+
+ +

Set the Ion (filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setMode (const uint8_t desired)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]desiredThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setModel (const panasonic_ac_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRPanasonicAc::setOffTimer (const uint16_t mins_since_midnight,
const bool enable = true 
)
+
+ +

Set/Enable the Off Timer.

+
Parameters
+ + + +
[in]mins_since_midnightThe time as nr. of minutes past midnight.
[in]enableDo we enable the timer or not?
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRPanasonicAc::setOnTimer (const uint16_t mins_since_midnight,
const bool enable = true 
)
+
+ +

Set/Enable the On Timer.

+
Parameters
+ + + +
[in]mins_since_midnightThe time as nr. of minutes past midnight.
[in]enableDo we enable the timer or not?
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setPower (const bool on)
+
+ +

Control the power state of the A/C unit.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Warning
For CKP models, the remote has no memory of the power state the A/C unit should be in. For those models setting this on/true will toggle the power state of the Panasonic A/C unit with the next meessage. e.g. If the A/C unit is already on, setPower(true) will turn it off. If the A/C unit is already off, setPower(true) will turn it on. setPower(false) will leave the A/C power state as it was. For all other models, setPower(true) should set the internal state to turn it on, and setPower(false) should turn it off.
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setQuiet (const bool on)
+
+ +

Set the Quiet setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setRaw (const uint8_t state[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setSwingHorizontal (const uint8_t desired_direction)
+
+ +

Control the horizontal swing setting.

+
Parameters
+ + +
[in]desired_directionThe position to set the horizontal swing to.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setSwingVertical (const uint8_t desired_elevation)
+
+ +

Control the vertical swing setting.

+
Parameters
+ + +
[in]desired_elevationThe position to set the vertical swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRPanasonicAc::setTemp (const uint8_t celsius,
const bool remember = true 
)
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]celsiusThe temperature in degrees celsius.
[in]rememberA flag for the class to remember the temperature.
+
+
+
Note
Automatically safely limits the temp to the operating range supported.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRPanasonicAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRPanasonicAc::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRPanasonicAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRPanasonicAc::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRPanasonicAc::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRPanasonicAc::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRPanasonicAc::validChecksum (const uint8_t * state,
const uint16_t length = kPanasonicAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRPanasonicAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _swingh

+ +
+
+ + + + + +
+ + + + +
uint8_t IRPanasonicAc::_swingh
+
+private
+
+ +
+
+ +

◆ _temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRPanasonicAc::_temp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRPanasonicAc::remote_state[kPanasonicAcStateLength]
+
+private
+
+ +

The state in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.map new file mode 100644 index 000000000..806678cd6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 new file mode 100644 index 000000000..ddab76af4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 @@ -0,0 +1 @@ +d3db02dc98d87de4f04f73ee0ebb90c7 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..9b0c44699b51666a765a99f407ea753c0e89c3ec GIT binary patch literal 3434 zcmY*c2Q*x3*B+7R2`=#~VU&nY5Tl#O)mxBcbfcGu=tdnPVn~!k39b_N5~56m(K}(Z z#3*-$U`(QB)EHrm`kj3L_y6Cz=d5$ywb$D3d-mG<+534;ilv3&Wfp!G5D0YH*htSB zSmS;@Oboyq+bPHeEDUa@hI*j$Uw27oMHb)*HrCUir;)IiHRp6(_GPFW&Ey4jU_y+a8ZK$-aSapEO)u5Z~RU1T#EIirc|=M zyWQT1=kA5d(Ff1;6Nzh7R1k}PqRm$(++O~dd}2uPPGpxiGdcEVG_B>!Z+M7 zp-KM?DM|aSblEgDQ$aC2D)eYfbH~!w_MPE0;<`fjiPBWL`34mk_JzXA$|@x-Jz2V; zneNmc9(1s2=X6By9A(VY2$Rmw&yNa=8+5tJ8@k~TyY}z1OuG6dX`TJFy){K%w!i=W z`+Jc|vlT_$t7nLvnc0;_SrK#=U}IooptrEFFw497M4{{O&LA735WNA?`}+0k!igp2 z*`)5CSHt*i3tn|5tEfoovOI&wA8;^IS_q%r|ZijuO)06FB`)JdU`rZDJc;}#aB4!dExA={X*1+ zT=@2UFY^o}NpieIw*e>;Ye8Wo02Wt~f7`w>WZ@Z&o2L zIXxZQ+xw)xUMV;@c&5qUq5FMEt#GKYw6uwyzW%=CYTcj^7c(=npfmlf`}grbMO9U8 z3IcBNKf_=!hby`8$F_to81GBMRaI3DzC17V*#sbFeqas`;RWQezdzE+sR*R!>G@Vt zMuscCCGcAUB<}p|^a2MSkJq+WxLsCJL6t1e9pW8#KprEyhCM{Jv+@7HWi`%rd@;jx z4o*&8Q`1qoW6Iv%(i27@VR`xV_4S9T24cWD+o;A(Cx*0`_`}19PhQFn&5u`l8NvOZ zKc}gOtlo?{41_$Ixou#;ATKZ9)A+O%NQSca*flLJt>lah@7=|LnYlScb?wieq5J{@ zyL)@TFqW5>*X7u#)B9sh*RZ?ZrS}3zrEIiOga|nC$UDxEoT{r4o(99Yyy9@T?3fgw z6Mh+$E6t6z0Yo2;(z&;DIXO8V9vIDN;n!diio}u9eUYqVb z;-&Y_DfBleG6}ZvfJhnVavJ+VWZr~7&>c975{lf=*)G~DM`%O|ukm%kFgeQSk3nqN z$a~cYjW&_DCsUU$+d9-bF$S-aa$9D7CN#yJURoo4odstc+YK#jFIBMchmIM6%d$wp zm1$LCxty=NuY{TGt%rUxf|g|k%+CdGRdqu-VQPqmSF3HX)67X`@^bF#wCMLk`au`a zk`68W)Ot9eE%54;f_d_W#ikuPVN#2he)KjI-c=#=RBqn#itg?G9WQyC;jnr`X_|Oz zm~8;1dJIdrP19+;a#Hq+6u8c^zw$XSYcHPw(e+Kwgi1=CHwg)}zuzGFfH{m`8X$d< za)c%acK7U^${p0BZMIMW{Knl+D(KY13T3e~a*cVrHOU}$;HrT|IC-2fDUDOhZ77Yx z#_q>ZYgt}jE2u$8M~SSxD_-RP_l)|#;RhH-$M>|r7U{}Z`p znwANTZza0nOpxrq<{bd4s1>5m#iIr4Lj|xN5r%K6fV2=a5(@k{djy1 zFhPS|u0|97T-^}t1sf{7=s1@nTbWr}zC1i!%4nRXqoeDan!0yQE5Z`!v6L){yU#^_ zPf7;IomkycRejOdcjr}J-n+((`f~guWoyg&K^ph;Aq-5>b5~!PlNTxd`py<$t zQYSPJdIJjViPpA!u6;h-Bi|7t@pWqptqt}WD8^5m`3IlA5lup&xP*k#@ee%*(*-}} zDLxHZ8}l6~How8Oy}hlyy|yz@JO>3eJ8atd(>jN4%N*1!Q$^{~GnfW?&GicwDj&pD zCP%XE>MtA8q7|3dNt&*3V+{t(Is?{~@#g7PoMk2ZUus$_?Jyp5ZbZzw}60v z#l^*jX~XnubUh0TLJA5BJaYE^AK9VvBITWFrKMt2A_8psT2@3@xJ1=@GR?dIvajZK ze6STm8J4JV?)<|L9NWNNzh0;_M-dYfQxE(Kg2$bz07Y2YpN3CAoNyv}O}}?a71VsK z;zt+Ch&5P*35u~-V; z2EIEN(EX~Qz|_i$li}%;=;^2isxO5DRi?*<0m1nBeY@^IFC*t8SC&Hzm? z^{nHo+f#94V>gtQvyP6Uu<3%PF)>>1SVx(O$?@?XMsQ3|o%ua@RCMld)I>ud%{mfY$>913@J%Exa~1HqKFG@!}YYv9z?b zMu%bZ^KQW-N2IAKYh+|3z{=P(foXJ}>OurPs2Xn)8L4h;Y@Euk@*E`;W#otP#t8u> z`mw(+4#bw7&0UYd04l@@YXgJTNA7t6Gvfk5EV)YL32EacS)l>}5u z$B#bNp2jM|UwS8(56A??NQ%cbLBZjXk;UVk?j2YhF@^ogl^bemydoEmsXJ=}{{z3SsVTtD z&MwPiiaKg~@ZbR`l~?hv!HsP)IR*c4B?EdkuA{dFbkOLi`&^ShP*tC)3_(pS0qp>Y zGqO^b>i1j{4ah6N$(Y#V@Y&hfwnuZ5lL;IbyuH1X*!cQ(y3Z}Vyu6x^+a8=ulo}eF znwC~oJ#T7))WBqHYMlojHYx=#8{II=>jBVb>hCXiBP#{S;+v9^lJhFtdK8KgP~A(P zRY}V~$y0zP`qi4Qt|EYf0txohU%YtH8 zWD%rTs{d6rXMnu`Jy_$|nyLSS$I9Beugo}WrZZYqS65fHp&5g52bgDhc{!AiBrqR1 zWdO*eiHV7aMu?Z=I%RXio$Bl5m-GK4Z~if)0poGh + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRSamsungAc Member List
+
+
+ +

This is the complete list of members for IRSamsungAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_forcepowerIRSamsungAcprivate
_irsendIRSamsungAcprivate
_lastsentpowerstateIRSamsungAcprivate
begin(void)IRSamsungAc
calcChecksum(const uint8_t state[], const uint16_t length=kSamsungAcStateLength)IRSamsungAcstatic
calibrate(void)IRSamsungAcinline
checksum(const uint16_t length=kSamsungAcStateLength)IRSamsungAcprivate
convertFan(const stdAc::fanspeed_t speed)IRSamsungAc
convertMode(const stdAc::opmode_t mode)IRSamsungAc
getBeep(void)IRSamsungAc
getBreeze(void)IRSamsungAc
getClean(void)IRSamsungAc
getDisplay(void)IRSamsungAc
getFan(void)IRSamsungAc
getIon(void)IRSamsungAc
getMode(void)IRSamsungAc
getPower(void)IRSamsungAc
getPowerful(void)IRSamsungAc
getQuiet(void)IRSamsungAc
getRaw(void)IRSamsungAc
getSwing(void)IRSamsungAc
getTemp(void)IRSamsungAc
IRSamsungAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRSamsungAcexplicit
off(void)IRSamsungAc
on(void)IRSamsungAc
remote_stateIRSamsungAcprivate
send(const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)IRSamsungAc
sendExtended(const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)IRSamsungAc
sendOff(const uint16_t repeat=kSamsungAcDefaultRepeat)IRSamsungAc
sendOn(const uint16_t repeat=kSamsungAcDefaultRepeat)IRSamsungAc
setBeep(const bool on)IRSamsungAc
setBreeze(const bool on)IRSamsungAc
setClean(const bool on)IRSamsungAc
setDisplay(const bool on)IRSamsungAc
setFan(const uint8_t speed)IRSamsungAc
setIon(const bool on)IRSamsungAc
setMode(const uint8_t mode)IRSamsungAc
setPower(const bool on)IRSamsungAc
setPowerful(const bool on)IRSamsungAc
setQuiet(const bool on)IRSamsungAc
setRaw(const uint8_t new_code[], const uint16_t length=kSamsungAcStateLength)IRSamsungAc
setSwing(const bool on)IRSamsungAc
setTemp(const uint8_t temp)IRSamsungAc
stateReset(const bool forcepower=true, const bool initialPower=true)IRSamsungAc
toCommon(void)IRSamsungAc
toCommonFanSpeed(const uint8_t speed)IRSamsungAcstatic
toCommonMode(const uint8_t mode)IRSamsungAcstatic
toString(void)IRSamsungAc
validChecksum(const uint8_t state[], const uint16_t length=kSamsungAcStateLength)IRSamsungAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc.html new file mode 100644 index 000000000..3b0e593c0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc.html @@ -0,0 +1,1585 @@ + + + + + + + +IRremoteESP8266: IRSamsungAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Samsung A/C messages. + More...

+ +

#include <ir_Samsung.h>

+
+Collaboration diagram for IRSamsungAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRSamsungAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (const bool forcepower=true, const bool initialPower=true)
 Reset the internal state of the emulation. More...
 
void send (const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)
 Send the current internal state as an IR message. More...
 
void sendExtended (const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)
 Send the extended current internal state as an IR message. More...
 
void sendOn (const uint16_t repeat=kSamsungAcDefaultRepeat)
 Send the special extended "On" message as the library can't seem to reproduce this message automatically. More...
 
void sendOff (const uint16_t repeat=kSamsungAcDefaultRepeat)
 Send the special extended "Off" message as the library can't seem to reproduce this message automatically. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwing (const bool on)
 Set the vertical swing setting of the A/C. More...
 
bool getSwing (void)
 Get the vertical swing setting of the A/C. More...
 
void setBeep (const bool on)
 Set the Beep setting of the A/C. More...
 
bool getBeep (void)
 Get the Beep setting of the A/C. More...
 
void setClean (const bool on)
 Set the Clean setting of the A/C. More...
 
bool getClean (void)
 Get the Clean setting of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet setting of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet setting of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) setting of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) setting of the A/C. More...
 
void setBreeze (const bool on)
 Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree. More...
 
bool getBreeze (void)
 Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree. More...
 
void setDisplay (const bool on)
 Set the Display (Light/LED) setting of the A/C. More...
 
bool getDisplay (void)
 Get the Display (Light/LED) setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (Filter) setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (Filter) setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kSamsungAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kSamsungAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kSamsungAcStateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kSamsungAcStateLength)
 Update the checksum for the internal state. More...
 
+ + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kSamsungAcExtendedStateLength]
 State in code form. More...
 
bool _forcepower
 Hack to know when we need to send a special power mesg. More...
 
bool _lastsentpowerstate
 
+

Detailed Description

+

Class for handling detailed Samsung A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRSamsungAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRSamsungAc::IRSamsungAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRSamsungAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRSamsungAc::calcChecksum (const uint8_t state[],
const uint16_t length = kSamsungAcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRSamsungAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSamsungAc::checksum (const uint16_t length = kSamsungAcStateLength)
+
+private
+
+ +

Update the checksum for the internal state.

+
Parameters
+ + +
[in]lengthThe length/size of the internal array to checksum.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getBeep()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getBeep (void )
+
+ +

Get the Beep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getBreeze()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getBreeze (void )
+
+ +

Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree.

+
Returns
true, the setting is on. false, the setting is off.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getClean (void )
+
+ +

Get the Clean setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getDisplay()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getDisplay (void )
+
+ +

Get the Display (Light/LED) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getIon (void )
+
+ +

Get the Ion (Filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getPowerful (void )
+
+ +

Get the Powerful (Turbo) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getQuiet (void )
+
+ +

Get the Quiet setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRSamsungAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getSwing (void )
+
+ +

Get the vertical swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+
Todo:
(Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. e.g. 0xAE or 0XAF for swing move.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRSamsungAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRSamsungAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSamsungAc::send (const uint16_t repeat = kSamsungAcDefaultRepeat,
const bool calcchecksum = true 
)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + + +
[in]repeatNr. of times the message will be repeated.
[in]calcchecksumDo we update the checksum before sending?
+
+
+
Note
Use for most function/mode/settings changes to the unit. i.e. When the device is already running.
+ +
+
+ +

◆ sendExtended()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSamsungAc::sendExtended (const uint16_t repeat = kSamsungAcDefaultRepeat,
const bool calcchecksum = true 
)
+
+ +

Send the extended current internal state as an IR message.

+
Parameters
+ + + +
[in]repeatNr. of times the message will be repeated.
[in]calcchecksumDo we update the checksum before sending?
+
+
+
Note
Use this for when you need to power on/off the device. Samsung A/C requires an extended length message when you want to change the power operating mode of the A/C unit.
+ +
+
+ +

◆ sendOff()

+ +
+
+ + + + + + + + +
void IRSamsungAc::sendOff (const uint16_t repeat = kSamsungAcDefaultRepeat)
+
+ +

Send the special extended "Off" message as the library can't seem to reproduce this message automatically.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036
+ +
+
+ +

◆ sendOn()

+ +
+
+ + + + + + + + +
void IRSamsungAc::sendOn (const uint16_t repeat = kSamsungAcDefaultRepeat)
+
+ +

Send the special extended "On" message as the library can't seem to reproduce this message automatically.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036
+ +
+
+ +

◆ setBeep()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setBeep (const bool on)
+
+ +

Set the Beep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setBreeze()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setBreeze (const bool on)
+
+ +

Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setClean (const bool on)
+
+ +

Set the Clean setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setDisplay()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setDisplay (const bool on)
+
+ +

Set the Display (Light/LED) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setIon (const bool on)
+
+ +

Set the Ion (Filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setQuiet (const bool on)
+
+ +

Set the Quiet setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSamsungAc::setRaw (const uint8_t new_code[],
const uint16_t length = kSamsungAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setSwing (const bool on)
+
+ +

Set the vertical swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Todo:
(Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. e.g. 0xAE or 0XAF for swing move.
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSamsungAc::stateReset (const bool forcepower = true,
const bool initialPower = true 
)
+
+ +

Reset the internal state of the emulation.

+
Parameters
+ + + +
[in]forcepowerA flag indicating if force sending a special power message with the first send() call.
[in]initialPowerSet the initial power state. True, on. False, off.
+
+
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRSamsungAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRSamsungAc::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRSamsungAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRSamsungAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRSamsungAc::validChecksum (const uint8_t state[],
const uint16_t length = kSamsungAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _forcepower

+ +
+
+ + + + + +
+ + + + +
bool IRSamsungAc::_forcepower
+
+private
+
+ +

Hack to know when we need to send a special power mesg.

+ +
+
+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRSamsungAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _lastsentpowerstate

+ +
+
+ + + + + +
+ + + + +
bool IRSamsungAc::_lastsentpowerstate
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSamsungAc::remote_state[kSamsungAcExtendedStateLength]
+
+private
+
+ +

State in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.map new file mode 100644 index 000000000..7b65cd5e6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 new file mode 100644 index 000000000..c11ced0ba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 @@ -0,0 +1 @@ +383f10b4ef1888fea2358fde261598f6 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..9ce17f8b0db4b36a22dca1acb89858aca964d6ef GIT binary patch literal 3730 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 MQPhCtJ+gT5ACE<600000 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc-members.html new file mode 100644 index 000000000..904c5623f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc-members.html @@ -0,0 +1,130 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRSharpAc Member List
+
+
+ +

This is the complete list of members for IRSharpAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_fanIRSharpAcprivate
_irsendIRSharpAcprivate
_modeIRSharpAcprivate
_tempIRSharpAcprivate
begin(void)IRSharpAc
calcChecksum(uint8_t state[], const uint16_t length=kSharpAcStateLength)IRSharpAcprivatestatic
calibrate(void)IRSharpAcinline
checksum(void)IRSharpAcprivate
clearPowerSpecial(void)IRSharpAcprivate
convertFan(const stdAc::fanspeed_t speed)IRSharpAcstatic
convertMode(const stdAc::opmode_t mode)IRSharpAcstatic
getClean(void)IRSharpAc
getEconoToggle(void)IRSharpAc
getFan(void)IRSharpAc
getIon(void)IRSharpAc
getMode(void)IRSharpAc
getPower(void)IRSharpAc
getPowerSpecial(void)IRSharpAcprivate
getRaw(void)IRSharpAc
getSpecial(void)IRSharpAc
getSwingToggle(void)IRSharpAc
getTemp(void)IRSharpAc
getTimerEnabled(void)IRSharpAc
getTimerTime(void)IRSharpAc
getTimerType(void)IRSharpAc
getTurbo(void)IRSharpAc
IRSharpAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRSharpAcexplicit
isPowerSpecial(void)IRSharpAc
off(void)IRSharpAc
on(void)IRSharpAc
remoteIRSharpAcprivate
send(const uint16_t repeat=kSharpAcDefaultRepeat)IRSharpAc
setClean(const bool on)IRSharpAc
setEconoToggle(const bool on)IRSharpAc
setFan(const uint8_t fan, const bool save=true)IRSharpAc
setIon(const bool on)IRSharpAc
setMode(const uint8_t mode, const bool save=true)IRSharpAc
setPower(const bool on, const bool prev_on=true)IRSharpAc
setPowerSpecial(const uint8_t value)IRSharpAcprivate
setRaw(const uint8_t new_code[], const uint16_t length=kSharpAcStateLength)IRSharpAc
setSpecial(const uint8_t mode)IRSharpAc
setSwingToggle(const bool on)IRSharpAc
setTemp(const uint8_t temp, const bool save=true)IRSharpAc
setTimer(bool enable, bool timer_type, uint16_t mins)IRSharpAc
setTurbo(const bool on)IRSharpAc
stateReset(void)IRSharpAcprivate
toCommon(void)IRSharpAc
toCommonFanSpeed(const uint8_t speed)IRSharpAcstatic
toCommonMode(const uint8_t mode)IRSharpAcstatic
toString(void)IRSharpAc
validChecksum(uint8_t state[], const uint16_t length=kSharpAcStateLength)IRSharpAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc.html new file mode 100644 index 000000000..09a5d0a75 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc.html @@ -0,0 +1,1688 @@ + + + + + + + +IRremoteESP8266: IRSharpAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Sharp A/C messages. + More...

+ +

#include <ir_Sharp.h>

+
+Collaboration diagram for IRSharpAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRSharpAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kSharpAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on, const bool prev_on=true)
 Change the power setting, including the previous power state. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
bool isPowerSpecial (void)
 Is one of the special power states in use? More...
 
void setTemp (const uint8_t temp, const bool save=true)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan, const bool save=true)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode, const bool save=true)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSpecial (const uint8_t mode)
 Set the value of the Special (button/command?) setting. More...
 
uint8_t getSpecial (void)
 Get the value of the Special (button/command?) setting. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getSwingToggle (void)
 Get the (vertical) Swing Toggle setting of the A/C. More...
 
void setSwingToggle (const bool on)
 Set the (vertical) Swing Toggle setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (Filter) setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (Filter) setting of the A/C. More...
 
bool getEconoToggle (void)
 Get the Economical mode toggle setting of the A/C. More...
 
void setEconoToggle (const bool on)
 Set the Economical mode toggle setting of the A/C. More...
 
uint16_t getTimerTime (void)
 Get how long the timer is set for, in minutes. More...
 
bool getTimerEnabled (void)
 Is the Timer enabled? More...
 
bool getTimerType (void)
 Get the current timer type. More...
 
void setTimer (bool enable, bool timer_type, uint16_t mins)
 Set or cancel the timer function. More...
 
bool getClean (void)
 Get the Clean setting of the A/C. More...
 
void setClean (const bool on)
 Set the Economical mode toggle setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kSharpAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kSharpAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
void setPowerSpecial (const uint8_t value)
 Set the value of the Power Special setting without any checks. More...
 
uint8_t getPowerSpecial (void)
 Get the value of the Power Special setting. More...
 
void clearPowerSpecial (void)
 Clear the "special"/non-normal bits in the power section. e.g. for normal/common command modes. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calcChecksum (uint8_t state[], const uint16_t length=kSharpAcStateLength)
 Calculate the checksum for a given state. More...
 
+ + + + + + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote [kSharpAcStateLength]
 State of the remote in IR code form. More...
 
uint8_t _temp
 Saved copy of the desired temp. More...
 
uint8_t _mode
 Saved copy of the desired mode. More...
 
uint8_t _fan
 Saved copy of the desired fan speed. More...
 
+

Detailed Description

+

Class for handling detailed Sharp A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRSharpAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRSharpAc::IRSharpAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRSharpAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRSharpAc::calcChecksum (uint8_t state[],
const uint16_t length = kSharpAcStateLength 
)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated 4-bit checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRSharpAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSharpAc::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ clearPowerSpecial()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSharpAc::clearPowerSpecial (void )
+
+private
+
+ +

Clear the "special"/non-normal bits in the power section. e.g. for normal/common command modes.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRSharpAc::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRSharpAc::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getClean (void )
+
+ +

Get the Clean setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEconoToggle()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getEconoToggle (void )
+
+ +

Get the Economical mode toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRSharpAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getIon (void )
+
+ +

Get the Ion (Filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRSharpAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerSpecial()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRSharpAc::getPowerSpecial (void )
+
+private
+
+ +

Get the value of the Power Special setting.

+
Returns
The setting's value.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRSharpAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSpecial()

+ +
+
+ + + + + + + + +
uint8_t IRSharpAc::getSpecial (void )
+
+ +

Get the value of the Special (button/command?) setting.

+
Returns
The setting's value.
+ +
+
+ +

◆ getSwingToggle()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getSwingToggle (void )
+
+ +

Get the (vertical) Swing Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRSharpAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getTimerEnabled (void )
+
+ +

Is the Timer enabled?

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTimerTime()

+ +
+
+ + + + + + + + +
uint16_t IRSharpAc::getTimerTime (void )
+
+ +

Get how long the timer is set for, in minutes.

+
Returns
The time in nr of minutes.
+ +
+
+ +

◆ getTimerType()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getTimerType (void )
+
+ +

Get the current timer type.

+
Returns
true, It's an "On" timer. false, It's an "Off" timer.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isPowerSpecial()

+ +
+
+ + + + + + + + +
bool IRSharpAc::isPowerSpecial (void )
+
+ +

Is one of the special power states in use?

+
Returns
true, it is. false, it isn't.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRSharpAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRSharpAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRSharpAc::send (const uint16_t repeat = kSharpAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRSharpAc::setClean (const bool on)
+
+ +

Set the Economical mode toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
Officially A/C unit needs to be "Off" before clean mode can be entered
+ +
+
+ +

◆ setEconoToggle()

+ +
+
+ + + + + + + + +
void IRSharpAc::setEconoToggle (const bool on)
+
+ +

Set the Economical mode toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Warning
Probably incompatible with setTurbo()
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setFan (const uint8_t speed,
const bool save = true 
)
+
+ +

Set the speed of the fan.

+
Parameters
+ + + +
[in]speedThe desired setting.
[in]saveDo we save this setting as a user set one?
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRSharpAc::setIon (const bool on)
+
+ +

Set the Ion (Filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setMode (const uint8_t mode,
const bool save = true 
)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + + +
[in]modeThe desired operating mode.
[in]saveDo we save this setting as a user set one?
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setPower (const bool on,
const bool prev_on = true 
)
+
+ +

Change the power setting, including the previous power state.

+
Parameters
+ + + +
[in]ontrue, the setting is on. false, the setting is off.
[in]prev_ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerSpecial()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSharpAc::setPowerSpecial (const uint8_t value)
+
+private
+
+ +

Set the value of the Power Special setting without any checks.

+
Parameters
+ + +
[in]valueThe value to set Power Special to.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setRaw (const uint8_t new_code[],
const uint16_t length = kSharpAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSpecial()

+ +
+
+ + + + + + + + +
void IRSharpAc::setSpecial (const uint8_t mode)
+
+ +

Set the value of the Special (button/command?) setting.

+
Parameters
+ + +
[in]modeThe value to set Special to.
+
+
+ +
+
+ +

◆ setSwingToggle()

+ +
+
+ + + + + + + + +
void IRSharpAc::setSwingToggle (const bool on)
+
+ +

Set the (vertical) Swing Toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setTemp (const uint8_t temp,
const bool save = true 
)
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]tempThe temperature in degrees celsius.
[in]saveDo we save this setting as a user set one?
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRSharpAc::setTimer (bool enable,
bool timer_type,
uint16_t mins 
)
+
+ +

Set or cancel the timer function.

+
Parameters
+ + + + +
[in]enableIs the timer to be enabled (true) or canceled(false)?
[in]timer_typeAn On (true) or an Off (false). Ignored if canceled.
[in]minsNr. of minutes the timer is to be set to.
+
+
+
Note
Rounds down to 30 min increments. (max: 720 mins (12h), 0 is Off)
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRSharpAc::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
If you use this method, you will need to send it before making other changes to the settings, as they may overwrite some of the bits used by this setting.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSharpAc::stateReset (void )
+
+private
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRSharpAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRSharpAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRSharpAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRSharpAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRSharpAc::validChecksum (uint8_t state[],
const uint16_t length = kSharpAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _fan

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSharpAc::_fan
+
+private
+
+ +

Saved copy of the desired fan speed.

+ +
+
+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRSharpAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSharpAc::_mode
+
+private
+
+ +

Saved copy of the desired mode.

+ +
+
+ +

◆ _temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSharpAc::_temp
+
+private
+
+ +

Saved copy of the desired temp.

+ +
+
+ +

◆ remote

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSharpAc::remote[kSharpAcStateLength]
+
+private
+
+ +

State of the remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.map new file mode 100644 index 000000000..bd52394a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.md5 new file mode 100644 index 000000000..4e92a3fe3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.md5 @@ -0,0 +1 @@ +a87b7a535dbb4358d51525a2278a117d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..397be3abbff42fdcb1c2c648081cee364eaea847 GIT binary patch literal 3360 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 + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRTcl112Ac Member List
+
+
+ +

This is the complete list of members for IRTcl112Ac, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRTcl112Acprivate
begin(void)IRTcl112Ac
calcChecksum(uint8_t state[], const uint16_t length=kTcl112AcStateLength)IRTcl112Acstatic
calibrate(void)IRTcl112Acinline
checksum(const uint16_t length=kTcl112AcStateLength)IRTcl112Acprivate
convertFan(const stdAc::fanspeed_t speed)IRTcl112Ac
convertMode(const stdAc::opmode_t mode)IRTcl112Ac
getEcono(void)IRTcl112Ac
getFan(void)IRTcl112Ac
getHealth(void)IRTcl112Ac
getLight(void)IRTcl112Ac
getMode(void)IRTcl112Ac
getPower(void)IRTcl112Ac
getRaw(void)IRTcl112Ac
getSwingHorizontal(void)IRTcl112Ac
getSwingVertical(void)IRTcl112Ac
getTemp(void)IRTcl112Ac
getTurbo(void)IRTcl112Ac
IRTcl112Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRTcl112Acexplicit
off(void)IRTcl112Ac
on(void)IRTcl112Ac
remote_stateIRTcl112Acprivate
send(const uint16_t repeat=kTcl112AcDefaultRepeat)IRTcl112Ac
setEcono(const bool on)IRTcl112Ac
setFan(const uint8_t speed)IRTcl112Ac
setHealth(const bool on)IRTcl112Ac
setLight(const bool on)IRTcl112Ac
setMode(const uint8_t mode)IRTcl112Ac
setPower(const bool on)IRTcl112Ac
setRaw(const uint8_t new_code[], const uint16_t length=kTcl112AcStateLength)IRTcl112Ac
setSwingHorizontal(const bool on)IRTcl112Ac
setSwingVertical(const bool on)IRTcl112Ac
setTemp(const float celsius)IRTcl112Ac
setTurbo(const bool on)IRTcl112Ac
stateReset(void)IRTcl112Ac
toCommon(void)IRTcl112Ac
toCommonFanSpeed(const uint8_t speed)IRTcl112Acstatic
toCommonMode(const uint8_t mode)IRTcl112Acstatic
toString(void)IRTcl112Ac
validChecksum(uint8_t state[], const uint16_t length=kTcl112AcStateLength)IRTcl112Acstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac.html new file mode 100644 index 000000000..f814eac41 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac.html @@ -0,0 +1,1298 @@ + + + + + + + +IRremoteESP8266: IRTcl112Ac Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed TCL A/C messages. + More...

+ +

#include <ir_Tcl.h>

+
+Collaboration diagram for IRTcl112Ac:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRTcl112Ac (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kTcl112AcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void stateReset (void)
 Reset the internal state of the emulation. (On, Cool, 24C) More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kTcl112AcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const float celsius)
 Set the temperature. More...
 
float getTemp (void)
 Get the current temperature setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setEcono (const bool on)
 Set the economy setting of the A/C. More...
 
bool getEcono (void)
 Get the economy setting of the A/C. More...
 
void setHealth (const bool on)
 Set the Health (Filter) setting of the A/C. More...
 
bool getHealth (void)
 Get the Health (Filter) setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light (LED/Display) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED/Display) setting of the A/C. More...
 
void setSwingHorizontal (const bool on)
 Set the horizontal swing setting of the A/C. More...
 
bool getSwingHorizontal (void)
 Get the horizontal swing setting of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the vertical swing setting of the A/C. More...
 
bool getSwingVertical (void)
 Get the vertical swing setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (uint8_t state[], const uint16_t length=kTcl112AcStateLength)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (uint8_t state[], const uint16_t length=kTcl112AcStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kTcl112AcStateLength)
 Calculate & set the checksum for the current internal state of the remote. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kTcl112AcStateLength]
 The State in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed TCL A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRTcl112Ac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRTcl112Ac::IRTcl112Ac (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRTcl112Ac::calcChecksum (uint8_t state[],
const uint16_t length = kTcl112AcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRTcl112Ac::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRTcl112Ac::checksum (const uint16_t length = kTcl112AcStateLength)
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+
Parameters
+ + +
[in]lengthThe length/size of the internal array to checksum.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRTcl112Ac::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRTcl112Ac::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getEcono (void )
+
+ +

Get the economy setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRTcl112Ac::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getHealth()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getHealth (void )
+
+ +

Get the Health (Filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getLight (void )
+
+ +

Get the Light (LED/Display) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRTcl112Ac::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRTcl112Ac::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getSwingHorizontal (void )
+
+ +

Get the horizontal swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getSwingVertical (void )
+
+ +

Get the vertical swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
float IRTcl112Ac::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+
Note
The temperature resolution is 0.5 of a degree.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::send (const uint16_t repeat = kTcl112AcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setEcono (const bool on)
+
+ +

Set the economy setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+
Note
Unknown speeds will default to Auto.
+ +
+
+ +

◆ setHealth()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setHealth (const bool on)
+
+ +

Set the Health (Filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setLight (const bool on)
+
+ +

Set the Light (LED/Display) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+
Note
Fan/Ventilation mode sets the fan speed to high. Unknown values default to Auto.
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRTcl112Ac::setRaw (const uint8_t new_code[],
const uint16_t length = kTcl112AcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setSwingHorizontal (const bool on)
+
+ +

Set the horizontal swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setSwingVertical (const bool on)
+
+ +

Set the vertical swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setTemp (const float celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+
Note
The temperature resolution is 0.5 of a degree.
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::stateReset (void )
+
+ +

Reset the internal state of the emulation. (On, Cool, 24C)

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRTcl112Ac::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRTcl112Ac::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRTcl112Ac::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRTcl112Ac::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRTcl112Ac::validChecksum (uint8_t state[],
const uint16_t length = kTcl112AcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRTcl112Ac::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRTcl112Ac::remote_state[kTcl112AcStateLength]
+
+private
+
+ +

The State in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.map new file mode 100644 index 000000000..206ef60dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 new file mode 100644 index 000000000..b7845c7a0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 @@ -0,0 +1 @@ +b01bf74458107df4a91e8d68cd7bd7c2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..713bce3fb12da126a2761dc964636db9878bc7fc GIT binary patch literal 2945 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 Ba$*1g literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc-members.html new file mode 100644 index 000000000..3b51979c9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc-members.html @@ -0,0 +1,117 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRTecoAc Member List
+
+
+ +

This is the complete list of members for IRTecoAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRTecoAcprivate
begin(void)IRTecoAc
calibrate(void)IRTecoAcinline
convertFan(const stdAc::fanspeed_t speed)IRTecoAc
convertMode(const stdAc::opmode_t mode)IRTecoAc
getFan(void)IRTecoAc
getHumid(void)IRTecoAc
getLight(void)IRTecoAc
getMode(void)IRTecoAc
getPower(void)IRTecoAc
getRaw(void)IRTecoAc
getSave(void)IRTecoAc
getSleep(void)IRTecoAc
getSwing(void)IRTecoAc
getTemp(void)IRTecoAc
getTimer(void)IRTecoAc
getTimerEnabled(void)IRTecoAcprivate
IRTecoAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRTecoAcexplicit
off(void)IRTecoAc
on(void)IRTecoAc
remote_stateIRTecoAcprivate
send(const uint16_t repeat=kTecoDefaultRepeat)IRTecoAc
setFan(const uint8_t fan)IRTecoAc
setHumid(const bool on)IRTecoAc
setLight(const bool on)IRTecoAc
setMode(const uint8_t mode)IRTecoAc
setPower(const bool on)IRTecoAc
setRaw(const uint64_t new_code)IRTecoAc
setSave(const bool on)IRTecoAc
setSleep(const bool on)IRTecoAc
setSwing(const bool on)IRTecoAc
setTemp(const uint8_t temp)IRTecoAc
setTimer(const uint16_t mins)IRTecoAc
stateReset(void)IRTecoAc
toCommon(void)IRTecoAc
toCommonFanSpeed(const uint8_t speed)IRTecoAcstatic
toCommonMode(const uint8_t mode)IRTecoAcstatic
toString(void)IRTecoAc
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc.html new file mode 100644 index 000000000..992922ec8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc.html @@ -0,0 +1,1182 @@ + + + + + + + +IRremoteESP8266: IRTecoAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Teco A/C messages. + More...

+ +

#include <ir_Teco.h>

+
+Collaboration diagram for IRTecoAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRTecoAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state of the emulation. More...
 
void send (const uint16_t repeat=kTecoDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwing (const bool on)
 Set the (vertical) swing setting of the A/C. More...
 
bool getSwing (void)
 Get the (vertical) swing setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light (LED/Display) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED/Display) setting of the A/C. More...
 
void setHumid (const bool on)
 Set the Humid setting of the A/C. More...
 
bool getHumid (void)
 Get the Humid setting of the A/C. More...
 
void setSave (const bool on)
 Set the Save setting of the A/C. More...
 
bool getSave (void)
 Get the Save setting of the A/C. More...
 
uint16_t getTimer (void)
 Get the timer time for when the A/C unit will switch power state. More...
 
void setTimer (const uint16_t mins)
 Set the timer for when the A/C unit will switch power state. More...
 
uint64_t getRaw (void)
 Get a copy of the internal state/code for this protocol. More...
 
void setRaw (const uint64_t new_code)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

bool getTimerEnabled (void)
 Is the timer function enabled? More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote_state
 The state of the IR remote in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed Teco A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRTecoAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRTecoAc::IRTecoAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRTecoAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRTecoAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getHumid()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getHumid (void )
+
+ +

Get the Humid setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getLight (void )
+
+ +

Get the Light (LED/Display) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint64_t IRTecoAc::getRaw (void )
+
+ +

Get a copy of the internal state/code for this protocol.

+
Returns
A code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSave()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getSave (void )
+
+ +

Get the Save setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getSwing (void )
+
+ +

Get the (vertical) swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint16_t IRTecoAc::getTimer (void )
+
+ +

Get the timer time for when the A/C unit will switch power state.

+
Returns
The number of minutes left on the timer. 0 means off.
+ +
+
+ +

◆ getTimerEnabled()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRTecoAc::getTimerEnabled (void )
+
+private
+
+ +

Is the timer function enabled?

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRTecoAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRTecoAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRTecoAc::send (const uint16_t repeat = kTecoDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRTecoAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setHumid()

+ +
+
+ + + + + + + + +
void IRTecoAc::setHumid (const bool on)
+
+ +

Set the Humid setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRTecoAc::setLight (const bool on)
+
+ +

Set the Light (LED/Display) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRTecoAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRTecoAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRTecoAc::setRaw (const uint64_t new_code)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSave()

+ +
+
+ + + + + + + + +
void IRTecoAc::setSave (const bool on)
+
+ +

Set the Save setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRTecoAc::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRTecoAc::setSwing (const bool on)
+
+ +

Set the (vertical) swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRTecoAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRTecoAc::setTimer (const uint16_t nr_mins)
+
+ +

Set the timer for when the A/C unit will switch power state.

+
Parameters
+ + +
[in]nr_minsNumber of minutes before power state change. 0 will clear the timer. Max is 24 hrs.
+
+
+
Note
Time is stored internaly in increments of 30 mins.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRTecoAc::stateReset (void )
+
+ +

Reset the internal state of the emulation.

+
Note
Mode:auto, Power:Off, fan:auto, temp:16, swing:off, sleep:off
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRTecoAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRTecoAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRTecoAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRTecoAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRTecoAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRTecoAc::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.map new file mode 100644 index 000000000..f3e5d1502 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.md5 new file mode 100644 index 000000000..b08a20fd3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.md5 @@ -0,0 +1 @@ +70b332a49408f4e1d8c532bf7d103f45 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..60d06d0839e714fc567f6101fea03934da83da8d GIT binary patch literal 3054 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 Z1ei}+-M;H!h64+Dz(Chjr&ilB{9m7R$PNGi literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC-members.html new file mode 100644 index 000000000..f54311112 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC-members.html @@ -0,0 +1,108 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRToshibaAC Member List
+
+
+ +

This is the complete list of members for IRToshibaAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRToshibaACprivate
begin(void)IRToshibaAC
calcChecksum(const uint8_t state[], const uint16_t length=kToshibaACStateLength)IRToshibaACprivatestatic
calibrate(void)IRToshibaACinline
checksum(const uint16_t length=kToshibaACStateLength)IRToshibaACprivate
convertFan(const stdAc::fanspeed_t speed)IRToshibaAC
convertMode(const stdAc::opmode_t mode)IRToshibaAC
getFan(void)IRToshibaAC
getMode(const bool useRaw=false)IRToshibaAC
getPower(void)IRToshibaAC
getRaw(void)IRToshibaAC
getTemp(void)IRToshibaAC
IRToshibaAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRToshibaACexplicit
mode_stateIRToshibaACprivate
off(void)IRToshibaAC
on(void)IRToshibaAC
remote_stateIRToshibaACprivate
send(const uint16_t repeat=kToshibaACMinRepeat)IRToshibaAC
setFan(const uint8_t speed)IRToshibaAC
setMode(const uint8_t mode)IRToshibaAC
setPower(const bool on)IRToshibaAC
setRaw(const uint8_t newState[])IRToshibaAC
setTemp(const uint8_t degrees)IRToshibaAC
stateReset(void)IRToshibaAC
toCommon(void)IRToshibaAC
toCommonFanSpeed(const uint8_t speed)IRToshibaACstatic
toCommonMode(const uint8_t mode)IRToshibaACstatic
toString(void)IRToshibaAC
validChecksum(const uint8_t state[], const uint16_t length=kToshibaACStateLength)IRToshibaACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC.html new file mode 100644 index 000000000..285782974 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC.html @@ -0,0 +1,1001 @@ + + + + + + + +IRremoteESP8266: IRToshibaAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Toshiba A/C messages. + More...

+ +

#include <ir_Toshiba.h>

+
+Collaboration diagram for IRToshibaAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRToshibaAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kToshibaACMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (const bool useRaw=false)
 Get the operating mode setting of the A/C. More...
 
void setRaw (const uint8_t newState[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kToshibaACStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kToshibaACStateLength)
 Calculate & set the checksum for the current internal state of the remote. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kToshibaACStateLength)
 Calculate the checksum for a given state. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kToshibaACStateLength]
 The state in IR code form. More...
 
uint8_t mode_state
 
+

Detailed Description

+

Class for handling detailed Toshiba A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRToshibaAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRToshibaAC::IRToshibaAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRToshibaAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRToshibaAC::calcChecksum (const uint8_t state[],
const uint16_t length = kToshibaACStateLength 
)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRToshibaAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRToshibaAC::checksum (const uint16_t length = kToshibaACStateLength)
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+
Parameters
+ + +
[in]lengthThe length/size of the internal array to checksum.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::getMode (const bool useRaw = false)
+
+ +

Get the operating mode setting of the A/C.

+
Parameters
+ + +
[in]useRawIndicate to get the mode from the internal state array.
+
+
+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRToshibaAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRToshibaAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRToshibaAC::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRToshibaAC::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRToshibaAC::send (const uint16_t repeat = kToshibaACMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting (0 is Auto, 1-5 is the speed, 5 is Max)
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+
Note
If we get an unexpected mode, default to AUTO.
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setRaw (const uint8_t newState[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]newStateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRToshibaAC::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+
See also
https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L103
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRToshibaAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRToshibaAC::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRToshibaAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRToshibaAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRToshibaAC::validChecksum (const uint8_t state[],
const uint16_t length = kToshibaACStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRToshibaAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ mode_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRToshibaAC::mode_state
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRToshibaAC::remote_state[kToshibaACStateLength]
+
+private
+
+ +

The state in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.map new file mode 100644 index 000000000..483543b42 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 new file mode 100644 index 000000000..b4f1e5ba5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 @@ -0,0 +1 @@ +c09eeaf5909d6c222783788bba05faaf \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..c1bfa564da481a1b5716bfc5f461d10dffa40f2d GIT binary patch literal 3399 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 + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRTrotecESP Member List
+
+
+ +

This is the complete list of members for IRTrotecESP, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRTrotecESPprivate
begin(void)IRTrotecESP
calcChecksum(const uint8_t state[], const uint16_t length=kTrotecStateLength)IRTrotecESPprivatestatic
calibrate(void)IRTrotecESPinline
checksum(void)IRTrotecESPprivate
convertFan(const stdAc::fanspeed_t speed)IRTrotecESP
convertMode(const stdAc::opmode_t mode)IRTrotecESP
getMode(void)IRTrotecESP
getPower(void)IRTrotecESP
getRaw(void)IRTrotecESP
getSleep(void)IRTrotecESP
getSpeed(void)IRTrotecESP
getTemp(void)IRTrotecESP
getTimer(void)IRTrotecESP
IRTrotecESP(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRTrotecESPexplicit
off(void)IRTrotecESP
on(void)IRTrotecESP
remote_stateIRTrotecESPprivate
send(const uint16_t repeat=kTrotecDefaultRepeat)IRTrotecESP
setMode(const uint8_t mode)IRTrotecESP
setPower(const bool state)IRTrotecESP
setRaw(const uint8_t state[])IRTrotecESP
setSleep(const bool on)IRTrotecESP
setSpeed(const uint8_t fan)IRTrotecESP
setTemp(const uint8_t celsius)IRTrotecESP
setTimer(const uint8_t timer)IRTrotecESP
stateReset(void)IRTrotecESP
toCommon(void)IRTrotecESP
toCommonFanSpeed(const uint8_t speed)IRTrotecESPstatic
toCommonMode(const uint8_t mode)IRTrotecESPstatic
toString(void)IRTrotecESP
validChecksum(const uint8_t state[], const uint16_t length=kTrotecStateLength)IRTrotecESPstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP.html new file mode 100644 index 000000000..36bcf53a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP.html @@ -0,0 +1,1069 @@ + + + + + + + +IRremoteESP8266: IRTrotecESP Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Trotec A/C messages. + More...

+ +

#include <ir_Trotec.h>

+
+Collaboration diagram for IRTrotecESP:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRTrotecESP (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kTrotecDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool state)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t celsius)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setSpeed (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getSpeed (void)
 Get the current fan speed setting. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
uint8_t getTimer (void)
 Get the timer time in nr. of Hours. More...
 
void setTimer (const uint8_t timer)
 Set the timer time in nr. of Hours. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t state[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kTrotecStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate & set the checksum for the current internal state of the remote. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kTrotecStateLength)
 Calculate the checksum for a given state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kTrotecStateLength]
 Remote state in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed Trotec A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRTrotecESP()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRTrotecESP::IRTrotecESP (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRTrotecESP::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRTrotecESP::calcChecksum (const uint8_t state[],
const uint16_t length = kTrotecStateLength 
)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRTrotecESP::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRTrotecESP::checksum (void )
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRTrotecESP::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRTrotecESP::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRTrotecESP::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSpeed()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::getSpeed (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::getTimer (void )
+
+ +

Get the timer time in nr. of Hours.

+
Returns
Nr. of Hours.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRTrotecESP::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRTrotecESP::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRTrotecESP::send (const uint16_t repeat = kTrotecDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setRaw (const uint8_t state[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSpeed()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setSpeed (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setTemp (const uint8_t celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setTimer (const uint8_t timer)
+
+ +

Set the timer time in nr. of Hours.

+
Parameters
+ + +
[in]timerNr. of Hours. Max is kTrotecMaxTimer
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRTrotecESP::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRTrotecESP::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRTrotecESP::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRTrotecESP::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRTrotecESP::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRTrotecESP::validChecksum (const uint8_t state[],
const uint16_t length = kTrotecStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRTrotecESP::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRTrotecESP::remote_state[kTrotecStateLength]
+
+private
+
+ +

Remote state in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.map new file mode 100644 index 000000000..758a9b69c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 new file mode 100644 index 000000000..eafdf26cf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 @@ -0,0 +1 @@ +247690158326910cfd854f7b6909ded9 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..fc1d54d1302b81df7a1a454706238fc2d535eda1 GIT binary patch literal 3270 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 VdIYo&34Tl + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRVestelAc Member List
+
+
+ +

This is the complete list of members for IRVestelAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_getTimer(const uint8_t offset)IRVestelAcprivate
_irsendIRVestelAcprivate
_setTimer(const uint16_t minutes, const uint8_t offset)IRVestelAcprivate
begin(void)IRVestelAc
calcChecksum(const uint64_t state)IRVestelAcstatic
calibrate(void)IRVestelAcinline
checksum(void)IRVestelAcprivate
convertFan(const stdAc::fanspeed_t speed)IRVestelAcstatic
convertMode(const stdAc::opmode_t mode)IRVestelAcstatic
getFan(void)IRVestelAc
getIon(void)IRVestelAc
getMode(void)IRVestelAc
getOffTimer(void)IRVestelAc
getOnTimer(void)IRVestelAc
getPower(void)IRVestelAc
getRaw(void)IRVestelAc
getSleep(void)IRVestelAc
getSwing(void)IRVestelAc
getTemp(void)IRVestelAc
getTime(void)IRVestelAc
getTimer(void)IRVestelAc
getTurbo(void)IRVestelAc
IRVestelAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRVestelAcexplicit
isOffTimerActive(void)IRVestelAc
isOnTimerActive(void)IRVestelAc
isTimeCommand(void)IRVestelAc
isTimerActive(void)IRVestelAc
off(void)IRVestelAc
on(void)IRVestelAc
remote_stateIRVestelAcprivate
remote_time_stateIRVestelAcprivate
send(const uint16_t repeat=kNoRepeat)IRVestelAc
setAuto(const int8_t autoLevel)IRVestelAc
setFan(const uint8_t fan)IRVestelAc
setIon(const bool on)IRVestelAc
setMode(const uint8_t mode)IRVestelAc
setOffTimer(const uint16_t minutes)IRVestelAc
setOffTimerActive(const bool on)IRVestelAc
setOnTimer(const uint16_t minutes)IRVestelAc
setOnTimerActive(const bool on)IRVestelAc
setPower(const bool on)IRVestelAc
setRaw(const uint8_t *newState)IRVestelAc
setRaw(const uint64_t newState)IRVestelAc
setSleep(const bool on)IRVestelAc
setSwing(const bool on)IRVestelAc
setTemp(const uint8_t temp)IRVestelAc
setTime(const uint16_t minutes)IRVestelAc
setTimer(const uint16_t minutes)IRVestelAc
setTimerActive(const bool on)IRVestelAc
setTurbo(const bool on)IRVestelAc
stateReset(void)IRVestelAc
toCommon(void)IRVestelAc
toCommonFanSpeed(const uint8_t speed)IRVestelAcstatic
toCommonMode(const uint8_t mode)IRVestelAcstatic
toString(void)IRVestelAc
use_time_stateIRVestelAcprivate
validChecksum(const uint64_t state)IRVestelAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc.html new file mode 100644 index 000000000..32ca0cf07 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc.html @@ -0,0 +1,1758 @@ + + + + + + + +IRremoteESP8266: IRVestelAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Vestel A/C messages. + More...

+ +

#include <ir_Vestel.h>

+
+Collaboration diagram for IRVestelAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRVestelAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kNoRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setAuto (const int8_t autoLevel)
 Set Auto mode/level of the A/C. More...
 
void setTimer (const uint16_t minutes)
 Set Timer option of A/C. More...
 
uint16_t getTimer (void)
 Get the Timer time of A/C. More...
 
void setTime (const uint16_t minutes)
 Set the A/C's internal clock. More...
 
uint16_t getTime (void)
 Get the A/C's internal clock's time. More...
 
void setOnTimer (const uint16_t minutes)
 Set the On timer time on the A/C. More...
 
uint16_t getOnTimer (void)
 Get the A/C's On Timer time. More...
 
void setOffTimer (const uint16_t minutes)
 Set the Off timer time on the A/C. More...
 
uint16_t getOffTimer (void)
 Get the A/C's Off Timer time. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setRaw (const uint8_t *newState)
 Set the internal state from a valid code for this protocol. More...
 
void setRaw (const uint64_t newState)
 Set the internal state from a valid code for this protocol. More...
 
uint64_t getRaw (void)
 Get a copy of the internal state/code for this protocol. More...
 
void setSwing (const bool on)
 Set the Swing Roaming setting of the A/C. More...
 
bool getSwing (void)
 Get the Swing Roaming setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (Filter) setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (Filter) setting of the A/C. More...
 
bool isTimeCommand (void)
 Is the current state a time command? More...
 
bool isOnTimerActive (void)
 Get if the On Timer is active on the A/C. More...
 
void setOnTimerActive (const bool on)
 Set the On timer to be active on the A/C. More...
 
bool isOffTimerActive (void)
 Get if the Off Timer is active on the A/C. More...
 
void setOffTimerActive (const bool on)
 Set the Off timer to be active on the A/C. More...
 
bool isTimerActive (void)
 Get if the Timer is active on the A/C. More...
 
void setTimerActive (const bool on)
 Set the timer to be active on the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + +

+Private Member Functions

void checksum (void)
 Calculate & set the checksum for the current internal state of the remote. More...
 
void _setTimer (const uint16_t minutes, const uint8_t offset)
 Set a given timer time at a given bit offset. More...
 
uint16_t _getTimer (const uint8_t offset)
 Get the number of minutes a timer is set for. More...
 
+ + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote_state
 The state of the IR remote in IR code form. More...
 
uint64_t remote_time_state
 The time state of the remote in code form. More...
 
bool use_time_state
 
+

Detailed Description

+

Class for handling detailed Vestel A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRVestelAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRVestelAc::IRVestelAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _getTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRVestelAc::_getTimer (const uint8_t offset)
+
+private
+
+ +

Get the number of minutes a timer is set for.

+
Parameters
+ + +
[in]offsetNr. of bits offset from the start of the state.
+
+
+
Returns
The time expressed in nr. of minutes.
+ +
+
+ +

◆ _setTimer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRVestelAc::_setTimer (const uint16_t minutes,
const uint8_t offset 
)
+
+private
+
+ +

Set a given timer time at a given bit offset.

+
Parameters
+ + + +
[in]minutesTime in nr. of minutes.
[in]offsetNr. of bits offset from the start of the state.
+
+
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRVestelAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRVestelAc::calcChecksum (const uint64_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe state to calc the checksum of.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRVestelAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRVestelAc::checksum (void )
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRVestelAc::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRVestelAc::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRVestelAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getIon (void )
+
+ +

Get the Ion (Filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRVestelAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRVestelAc::getOffTimer (void )
+
+ +

Get the A/C's Off Timer time.

+
Returns
The time expressed in nr. of minutes.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRVestelAc::getOnTimer (void )
+
+ +

Get the A/C's On Timer time.

+
Returns
The time expressed in nr. of minutes.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint64_t IRVestelAc::getRaw (void )
+
+ +

Get a copy of the internal state/code for this protocol.

+
Returns
A code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getSwing (void )
+
+ +

Get the Swing Roaming setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRVestelAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTime()

+ +
+
+ + + + + + + + +
uint16_t IRVestelAc::getTime (void )
+
+ +

Get the A/C's internal clock's time.

+
Returns
The time expressed in nr. of minutes past midnight.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint16_t IRVestelAc::getTimer (void )
+
+ +

Get the Timer time of A/C.

+
Returns
The number of minutes of time on the timer.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isOffTimerActive()

+ +
+
+ + + + + + + + +
bool IRVestelAc::isOffTimerActive (void )
+
+ +

Get if the Off Timer is active on the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isOnTimerActive()

+ +
+
+ + + + + + + + +
bool IRVestelAc::isOnTimerActive (void )
+
+ +

Get if the On Timer is active on the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isTimeCommand()

+ +
+
+ + + + + + + + +
bool IRVestelAc::isTimeCommand (void )
+
+ +

Is the current state a time command?

+
Returns
true, if the state is a time message. Otherwise, false.
+ +
+
+ +

◆ isTimerActive()

+ +
+
+ + + + + + + + +
bool IRVestelAc::isTimerActive (void )
+
+ +

Get if the Timer is active on the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRVestelAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRVestelAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRVestelAc::send (const uint16_t repeat = kNoRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setAuto()

+ +
+
+ + + + + + + + +
void IRVestelAc::setAuto (const int8_t autoLevel)
+
+ +

Set Auto mode/level of the A/C.

+
Parameters
+ + +
[in]autoLevelThe auto mode/level setting.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRVestelAc::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRVestelAc::setIon (const bool on)
+
+ +

Set the Ion (Filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRVestelAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+
Note
If we get an unexpected mode, default to AUTO.
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRVestelAc::setOffTimer (const uint16_t minutes)
+
+ +

Set the Off timer time on the A/C.

+
Parameters
+ + +
[in]minutesTime in nr. of minutes.
+
+
+ +
+
+ +

◆ setOffTimerActive()

+ +
+
+ + + + + + + + +
void IRVestelAc::setOffTimerActive (const bool on)
+
+ +

Set the Off timer to be active on the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRVestelAc::setOnTimer (const uint16_t minutes)
+
+ +

Set the On timer time on the A/C.

+
Parameters
+ + +
[in]minutesTime in nr. of minutes.
+
+
+ +
+
+ +

◆ setOnTimerActive()

+ +
+
+ + + + + + + + +
void IRVestelAc::setOnTimerActive (const bool on)
+
+ +

Set the On timer to be active on the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRVestelAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw() [1/2]

+ +
+
+ + + + + + + + +
void IRVestelAc::setRaw (const uint64_t newState)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]newStateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setRaw() [2/2]

+ +
+
+ + + + + + + + +
void IRVestelAc::setRaw (const uint8_t * newState)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]newStateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRVestelAc::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRVestelAc::setSwing (const bool on)
+
+ +

Set the Swing Roaming setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTime()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTime (const uint16_t minutes)
+
+ +

Set the A/C's internal clock.

+
Parameters
+ + +
[in]minutesThe time expressed in nr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTimer (const uint16_t minutes)
+
+ +

Set Timer option of A/C.

+
Parameters
+ + +
[in]minutesNr of minutes the timer is to be set for.
+
+
+
Note
Valid arguments are 0, 0.5, 1, 2, 3 and 5 hours (in minutes). 0 disables the timer.
+ +
+
+ +

◆ setTimerActive()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTimerActive (const bool on)
+
+ +

Set the timer to be active on the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRVestelAc::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+
Note
Power On, Mode Auto, Fan Auto, Temp = 25C/77F
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRVestelAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRVestelAc::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRVestelAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRVestelAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRVestelAc::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe state to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRVestelAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRVestelAc::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+ +

◆ remote_time_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRVestelAc::remote_time_state
+
+private
+
+ +

The time state of the remote in code form.

+ +
+
+ +

◆ use_time_state

+ +
+
+ + + + + +
+ + + + +
bool IRVestelAc::use_time_state
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.map new file mode 100644 index 000000000..0f380bbd5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.md5 new file mode 100644 index 000000000..c193a6f83 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.md5 @@ -0,0 +1 @@ +f54c4cec990e7a1ff1e10a366cb92198 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..5b0622536caad1afcdbe0a3cf30ffedcc154e143 GIT binary patch literal 3288 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 + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRWhirlpoolAc Member List
+
+
+ +

This is the complete list of members for IRWhirlpoolAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_desiredtempIRWhirlpoolAcprivate
_irsendIRWhirlpoolAcprivate
_setMode(const uint8_t mode)IRWhirlpoolAcprivate
_setTemp(const uint8_t temp, const bool remember=true)IRWhirlpoolAcprivate
begin(void)IRWhirlpoolAc
calibrate(void)IRWhirlpoolAcinline
checksum(const uint16_t length=kWhirlpoolAcStateLength)IRWhirlpoolAcprivate
convertFan(const stdAc::fanspeed_t speed)IRWhirlpoolAc
convertMode(const stdAc::opmode_t mode)IRWhirlpoolAc
enableOffTimer(const bool on)IRWhirlpoolAc
enableOnTimer(const bool on)IRWhirlpoolAc
enableTimer(const uint16_t pos, const bool state)IRWhirlpoolAcprivate
getClock(void)IRWhirlpoolAc
getCommand(void)IRWhirlpoolAc
getFan(void)IRWhirlpoolAc
getLight(void)IRWhirlpoolAc
getMode(void)IRWhirlpoolAc
getModel(void)IRWhirlpoolAc
getOffTimer(void)IRWhirlpoolAc
getOnTimer(void)IRWhirlpoolAc
getPowerToggle(void)IRWhirlpoolAc
getRaw(const bool calcchecksum=true)IRWhirlpoolAc
getSleep(void)IRWhirlpoolAc
getSuper(void)IRWhirlpoolAc
getSwing(void)IRWhirlpoolAc
getTemp(void)IRWhirlpoolAc
getTempOffset(void)IRWhirlpoolAcprivate
getTime(const uint16_t pos)IRWhirlpoolAcprivate
IRWhirlpoolAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRWhirlpoolAcexplicit
isOffTimerEnabled(void)IRWhirlpoolAc
isOnTimerEnabled(void)IRWhirlpoolAc
isTimerEnabled(const uint16_t pos)IRWhirlpoolAcprivate
remote_stateIRWhirlpoolAcprivate
send(const uint16_t repeat=kWhirlpoolAcDefaultRepeat, const bool calcchecksum=true)IRWhirlpoolAc
setClock(const uint16_t minspastmidnight)IRWhirlpoolAc
setCommand(const uint8_t code)IRWhirlpoolAc
setFan(const uint8_t speed)IRWhirlpoolAc
setLight(const bool on)IRWhirlpoolAc
setMode(const uint8_t mode)IRWhirlpoolAc
setModel(const whirlpool_ac_remote_model_t model)IRWhirlpoolAc
setOffTimer(const uint16_t minspastmidnight)IRWhirlpoolAc
setOnTimer(const uint16_t minspastmidnight)IRWhirlpoolAc
setPowerToggle(const bool on)IRWhirlpoolAc
setRaw(const uint8_t new_code[], const uint16_t length=kWhirlpoolAcStateLength)IRWhirlpoolAc
setSleep(const bool on)IRWhirlpoolAc
setSuper(const bool on)IRWhirlpoolAc
setSwing(const bool on)IRWhirlpoolAc
setTemp(const uint8_t temp)IRWhirlpoolAc
setTime(const uint16_t pos, const uint16_t minspastmidnight)IRWhirlpoolAcprivate
stateReset(void)IRWhirlpoolAc
toCommon(void)IRWhirlpoolAc
toCommonFanSpeed(const uint8_t speed)IRWhirlpoolAcstatic
toCommonMode(const uint8_t mode)IRWhirlpoolAcstatic
toString(void)IRWhirlpoolAc
validChecksum(const uint8_t state[], const uint16_t length=kWhirlpoolAcStateLength)IRWhirlpoolAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc.html new file mode 100644 index 000000000..3ef4ae843 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc.html @@ -0,0 +1,1799 @@ + + + + + + + +IRremoteESP8266: IRWhirlpoolAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Whirlpool A/C messages. + More...

+ +

#include <ir_Whirlpool.h>

+
+Collaboration diagram for IRWhirlpoolAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRWhirlpoolAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kWhirlpoolAcDefaultRepeat, const bool calcchecksum=true)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void setPowerToggle (const bool on)
 Change the power toggle setting. More...
 
bool getPowerToggle (void)
 Get the value of the current power toggle setting. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setSuper (const bool on)
 Set the Super (Turbo/Jet) setting of the A/C. More...
 
bool getSuper (void)
 Get the Super (Turbo/Jet) setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwing (const bool on)
 Set the (vertical) swing setting of the A/C. More...
 
bool getSwing (void)
 Get the (vertical) swing setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light (Display/LED) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (Display/LED) setting of the A/C. More...
 
uint16_t getClock (void)
 Get the clock time in nr. of minutes past midnight. More...
 
void setClock (const uint16_t minspastmidnight)
 Set the clock time in nr. of minutes past midnight. More...
 
uint16_t getOnTimer (void)
 Get the On Timer time.. More...
 
void setOnTimer (const uint16_t minspastmidnight)
 Set the On Timer time. More...
 
void enableOnTimer (const bool on)
 Enable the On Timer. More...
 
bool isOnTimerEnabled (void)
 Is the On timer enabled? More...
 
uint16_t getOffTimer (void)
 Get the Off Timer time.. More...
 
void setOffTimer (const uint16_t minspastmidnight)
 Set the Off Timer time. More...
 
void enableOffTimer (const bool on)
 Enable the Off Timer. More...
 
bool isOffTimerEnabled (void)
 Is the Off timer enabled? More...
 
void setCommand (const uint8_t code)
 Set the Command (Button) setting of the A/C. More...
 
uint8_t getCommand (void)
 Get the Command (Button) setting of the A/C. More...
 
whirlpool_ac_remote_model_t getModel (void)
 Get/Detect the model of the A/C. More...
 
void setModel (const whirlpool_ac_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
uint8_t * getRaw (const bool calcchecksum=true)
 Get a copy of the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kWhirlpoolAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kWhirlpoolAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

void checksum (const uint16_t length=kWhirlpoolAcStateLength)
 Calculate & set the checksum for the current internal state of the remote. More...
 
uint16_t getTime (const uint16_t pos)
 Get the time in nr. of minutes past midnight. More...
 
void setTime (const uint16_t pos, const uint16_t minspastmidnight)
 Set the time in nr. of minutes past midnight. More...
 
bool isTimerEnabled (const uint16_t pos)
 Is the timer enabled at the given byte offset? More...
 
void enableTimer (const uint16_t pos, const bool state)
 Enable the timer enabled at the given byte offset. More...
 
void _setTemp (const uint8_t temp, const bool remember=true)
 Set the temperature. More...
 
void _setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
int8_t getTempOffset (void)
 Calculate the temp. offset in deg C for the current model. More...
 
+ + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kWhirlpoolAcStateLength]
 The state in IR code form. More...
 
uint8_t _desiredtemp
 The last user explicitly set temperature. More...
 
+

Detailed Description

+

Class for handling detailed Whirlpool A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRWhirlpoolAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRWhirlpoolAc::IRWhirlpoolAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _setMode()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRWhirlpoolAc::_setMode (const uint8_t mode)
+
+private
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+
Note
Internal use only.
+ +
+
+ +

◆ _setTemp()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::_setTemp (const uint8_t temp,
const bool remember = true 
)
+
+private
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]tempThe temperature in degrees celsius.
[in]rememberDo we save this temperature?
+
+
+
Note
Internal use only.
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRWhirlpoolAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
The uSec timing offset needed per modulation of the IR Led.
+
Note
This will produce a 65ms IR signal pulse at 38kHz. Only ever needs to be run once per object instantiation, if at all.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRWhirlpoolAc::checksum (const uint16_t length = kWhirlpoolAcStateLength)
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+
Parameters
+ + +
[in]lengthThe length/size of the internal state array.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ enableOffTimer()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::enableOffTimer (const bool on)
+
+ +

Enable the Off Timer.

+
Parameters
+ + +
[in]ontrue, the timer is enabled. false, the timer is disabled.
+
+
+ +
+
+ +

◆ enableOnTimer()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::enableOnTimer (const bool on)
+
+ +

Enable the On Timer.

+
Parameters
+ + +
[in]ontrue, the timer is enabled. false, the timer is disabled.
+
+
+ +
+
+ +

◆ enableTimer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::enableTimer (const uint16_t pos,
const bool on 
)
+
+private
+
+ +

Enable the timer enabled at the given byte offset.

+
Parameters
+ + + +
[in]posThe byte offset to write to.
[in]ontrue, the timer is enabled. false, the timer is disabled.
+
+
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint16_t IRWhirlpoolAc::getClock (void )
+
+ +

Get the clock time in nr. of minutes past midnight.

+
Returns
The time expressed as the Nr. of minutes past midnight.
+ +
+
+ +

◆ getCommand()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::getCommand (void )
+
+ +

Get the Command (Button) setting of the A/C.

+
Returns
The current Command (Button) of the A/C.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getLight (void )
+
+ +

Get the Light (Display/LED) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
whirlpool_ac_remote_model_t IRWhirlpoolAc::getModel (void )
+
+ +

Get/Detect the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRWhirlpoolAc::getOffTimer (void )
+
+ +

Get the Off Timer time..

+
Returns
The time expressed as the Nr. of minutes past midnight.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRWhirlpoolAc::getOnTimer (void )
+
+ +

Get the On Timer time..

+
Returns
The time expressed as the Nr. of minutes past midnight.
+ +
+
+ +

◆ getPowerToggle()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getPowerToggle (void )
+
+ +

Get the value of the current power toggle setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRWhirlpoolAc::getRaw (const bool calcchecksum = true)
+
+ +

Get a copy of the internal state/code for this protocol.

+
Parameters
+ + +
[in]calcchecksumDo we need to calculate the checksum?.
+
+
+
Returns
A code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSuper()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getSuper (void )
+
+ +

Get the Super (Turbo/Jet) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getSwing (void )
+
+ +

Get the (vertical) swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTempOffset()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRWhirlpoolAc::getTempOffset (void )
+
+private
+
+ +

Calculate the temp. offset in deg C for the current model.

+
Returns
The temperature offset.
+ +
+
+ +

◆ getTime()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRWhirlpoolAc::getTime (const uint16_t pos)
+
+private
+
+ +

Get the time in nr. of minutes past midnight.

+
Parameters
+ + +
[in]posThe byte offset to read from.
+
+
+
Returns
The time in Nr. of minutes past midnight.
+ +
+
+ +

◆ isOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::isOffTimerEnabled (void )
+
+ +

Is the Off timer enabled?

+
Returns
true, the Timer is enabled. false, the Timer is disabled.
+ +
+
+ +

◆ isOnTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::isOnTimerEnabled (void )
+
+ +

Is the On timer enabled?

+
Returns
true, the Timer is enabled. false, the Timer is disabled.
+ +
+
+ +

◆ isTimerEnabled()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRWhirlpoolAc::isTimerEnabled (const uint16_t pos)
+
+private
+
+ +

Is the timer enabled at the given byte offset?

+
Parameters
+ + +
[in]posThe byte offset to read from.
+
+
+
Returns
true, the Timer is on. false, the Timer is off.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::send (const uint16_t repeat = kWhirlpoolAcDefaultRepeat,
const bool calcchecksum = true 
)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + + +
[in]repeatNr. of times the message will be repeated.
[in]calcchecksumDo we need to calculate the checksum?.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setClock (const uint16_t minspastmidnight)
+
+ +

Set the clock time in nr. of minutes past midnight.

+
Parameters
+ + +
[in]minspastmidnightThe time expressed as minutes past midnight.
+
+
+ +
+
+ +

◆ setCommand()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setCommand (const uint8_t code)
+
+ +

Set the Command (Button) setting of the A/C.

+
Parameters
+ + +
[in]codeThe current Command (Button) of the A/C.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setLight (const bool on)
+
+ +

Set the Light (Display/LED) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setModel (const whirlpool_ac_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setOffTimer (const uint16_t minspastmidnight)
+
+ +

Set the Off Timer time.

+
Parameters
+ + +
[in]minspastmidnightThe time expressed as minutes past midnight.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setOnTimer (const uint16_t minspastmidnight)
+
+ +

Set the On Timer time.

+
Parameters
+ + +
[in]minspastmidnightThe time expressed as minutes past midnight.
+
+
+ +
+
+ +

◆ setPowerToggle()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setPowerToggle (const bool on)
+
+ +

Change the power toggle setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::setRaw (const uint8_t new_code[],
const uint16_t length = kWhirlpoolAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSuper()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setSuper (const bool on)
+
+ +

Set the Super (Turbo/Jet) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setSwing (const bool on)
+
+ +

Set the (vertical) swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::setTime (const uint16_t pos,
const uint16_t minspastmidnight 
)
+
+private
+
+ +

Set the time in nr. of minutes past midnight.

+
Parameters
+ + + +
[in]posThe byte offset to write to.
[in]minspastmidnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRWhirlpoolAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRWhirlpoolAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRWhirlpoolAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRWhirlpoolAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRWhirlpoolAc::validChecksum (const uint8_t state[],
const uint16_t length = kWhirlpoolAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _desiredtemp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRWhirlpoolAc::_desiredtemp
+
+private
+
+ +

The last user explicitly set temperature.

+ +
+
+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRWhirlpoolAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRWhirlpoolAc::remote_state[kWhirlpoolAcStateLength]
+
+private
+
+ +

The state in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map new file mode 100644 index 000000000..8fbbe1e23 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 new file mode 100644 index 000000000..2bd14cbec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 @@ -0,0 +1 @@ +67506f3229bc12f62882dd42ed993175 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..08f43344278773e6620112cfde7947563a9df425 GIT binary patch literal 3386 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 Hc8UBiDNAri literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac-members.html new file mode 100644 index 000000000..c9e1b88a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac-members.html @@ -0,0 +1,151 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRac Member List
+
+
+ +

This is the complete list of members for IRac, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_invertedIRacprivate
_modulationIRacprivate
_pinIRacprivate
_prevIRacprivate
amcor(IRAmcorAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)IRacprivate
argo(IRArgoAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const int16_t sleep=-1)IRacprivate
boolToString(const bool value)IRacstatic
carrier64(IRCarrierAc64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const int16_t sleep=-1)IRacprivate
cleanState(const stdAc::state_t state)IRacprivatestatic
cmpStates(const stdAc::state_t a, const stdAc::state_t b)IRacstatic
coolix(IRCoolixAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool light, const bool clean, const int16_t sleep=-1)IRacprivate
corona(IRCoronaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool econo)IRacprivate
daikin(IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool clean)IRacprivate
daikin128(IRDaikin128 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool econo, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
daikin152(IRDaikin152 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool econo)IRacprivate
daikin160(IRDaikin160 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)IRacprivate
daikin176(IRDaikin176 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingh_t swingh)IRacprivate
daikin2(IRDaikin2 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool econo, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
daikin216(IRDaikin216 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo)IRacprivate
daikin64(IRDaikin64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
delonghiac(IRDelonghiAc *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const bool turbo, const int16_t sleep=-1)IRacprivate
electra(IRElectraAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool lighttoggle, const bool clean)IRacprivate
fanspeedToString(const stdAc::fanspeed_t speed)IRacstatic
fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean)IRacprivate
getState(void)IRac
getStatePrev(void)IRac
goodweather(IRGoodweatherAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const int16_t sleep=-1)IRacprivate
gree(IRGreeAC *ac, const gree_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const bool clean, const int16_t sleep=-1)IRacprivate
haier(IRHaierAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool filter, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
haierYrwo2(IRHaierACYRW02 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const int16_t sleep=-1)IRacprivate
handleToggles(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)IRacprivatestatic
hasStateChanged(void)IRac
hitachi(IRHitachiAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh)IRacprivate
hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, const bool on, const bool power_toggle, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool swing_toggle, const int16_t sleep=-1)IRacprivate
hitachi344(IRHitachiAc344 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh)IRacprivate
hitachi424(IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)IRacprivate
initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)IRacstatic
initState(stdAc::state_t *state)IRacstatic
IRac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRacexplicit
isProtocolSupported(const decode_type_t protocol)IRacstatic
kelvinator(IRKelvinatorAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean)IRacprivate
lg(IRLgAc *ac, const lg_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)IRacprivate
markAsSent(void)IRac
midea(IRMideaAC *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const int16_t sleep=-1)IRacprivate
mitsubishi(IRMitsubishiAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const int16_t clock=-1)IRacprivate
mitsubishi112(IRMitsubishi112 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet)IRacprivate
mitsubishi136(IRMitsubishi136 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet)IRacprivate
mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean, const int16_t sleep=-1)IRacprivate
mitsubishiHeavy88(IRMitsubishiHeavy88Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool econo, const bool clean)IRacprivate
neoclima(IRNeoclimaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool light, const bool filter, const int16_t sleep=-1)IRacprivate
nextIRac
opmodeToString(const stdAc::opmode_t mode)IRacstatic
panasonic(IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool filter, const int16_t clock=-1)IRacprivate
samsung(IRSamsungAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean, const bool beep, const bool prevpower=true, const bool forcepower=true)IRacprivate
sendAc(void)IRac
sendAc(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)IRac
sendAc(const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)IRac
sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const bool clean)IRacprivate
strToBool(const char *str, const bool def=false)IRacstatic
strToFanspeed(const char *str, const stdAc::fanspeed_t def=stdAc::fanspeed_t::kAuto)IRacstatic
strToModel(const char *str, const int16_t def=-1)IRacstatic
strToOpmode(const char *str, const stdAc::opmode_t def=stdAc::opmode_t::kAuto)IRacstatic
strToSwingH(const char *str, const stdAc::swingh_t def=stdAc::swingh_t::kOff)IRacstatic
strToSwingV(const char *str, const stdAc::swingv_t def=stdAc::swingv_t::kOff)IRacstatic
swinghToString(const stdAc::swingh_t swingh)IRacstatic
swingvToString(const stdAc::swingv_t swingv)IRacstatic
tcl112(IRTcl112Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool light, const bool econo, const bool filter)IRacprivate
teco(IRTecoAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool light, const int16_t sleep=-1)IRacprivate
toshiba(IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)IRacprivate
trotec(IRTrotecESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const int16_t sleep=-1)IRacprivate
vestel(IRVestelAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const int16_t sleep=-1, const int16_t clock=-1, const bool sendNormal=true)IRacprivate
whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac.html new file mode 100644 index 000000000..8c0bb6274 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac.html @@ -0,0 +1,5644 @@ + + + + + + + +IRremoteESP8266: IRac Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

#include <IRac.h>

+
+Collaboration diagram for IRac:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRac (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void markAsSent (void)
 Update the previous state to the current one. More...
 
bool sendAc (void)
 Send an A/C message based soley on our internal state. More...
 
bool sendAc (const stdAc::state_t desired, const stdAc::state_t *prev=NULL)
 Send A/C message for a given device using state_t structures. More...
 
bool sendAc (const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)
 Send A/C message for a given device using common A/C settings. More...
 
stdAc::state_t getState (void)
 Get the current internal A/C climate state. More...
 
stdAc::state_t getStatePrev (void)
 Get the previous internal A/C climate state that should have already been sent to the device. i.e. What the A/C unit should already be set to. More...
 
bool hasStateChanged (void)
 Check if the internal state has changed from what was previously sent. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool isProtocolSupported (const decode_type_t protocol)
 Is the given protocol supported by the IRac class? More...
 
static void initState (stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)
 Initialse the given state with the supplied settings. More...
 
static void initState (stdAc::state_t *state)
 Initialse the given state with the supplied settings. More...
 
static bool cmpStates (const stdAc::state_t a, const stdAc::state_t b)
 Compare two AirCon states. More...
 
static bool strToBool (const char *str, const bool def=false)
 Convert the supplied str into the appropriate boolean value. More...
 
static int16_t strToModel (const char *str, const int16_t def=-1)
 Convert the supplied str into the appropriate enum. More...
 
static stdAc::opmode_t strToOpmode (const char *str, const stdAc::opmode_t def=stdAc::opmode_t::kAuto)
 Convert the supplied str into the appropriate enum. More...
 
static stdAc::fanspeed_t strToFanspeed (const char *str, const stdAc::fanspeed_t def=stdAc::fanspeed_t::kAuto)
 Convert the supplied str into the appropriate enum. More...
 
static stdAc::swingv_t strToSwingV (const char *str, const stdAc::swingv_t def=stdAc::swingv_t::kOff)
 Convert the supplied str into the appropriate enum. More...
 
static stdAc::swingh_t strToSwingH (const char *str, const stdAc::swingh_t def=stdAc::swingh_t::kOff)
 Convert the supplied str into the appropriate enum. More...
 
static String boolToString (const bool value)
 Convert the supplied boolean into the appropriate String. More...
 
static String opmodeToString (const stdAc::opmode_t mode)
 Convert the supplied operation mode into the appropriate String. More...
 
static String fanspeedToString (const stdAc::fanspeed_t speed)
 Convert the supplied fan speed enum into the appropriate String. More...
 
static String swingvToString (const stdAc::swingv_t swingv)
 Convert the supplied enum into the appropriate String. More...
 
static String swinghToString (const stdAc::swingh_t swingh)
 Convert the supplied enum into the appropriate String. More...
 
+ + + + +

+Public Attributes

stdAc::state_t next
 The state we want the device to be in after we send. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

void amcor (IRAmcorAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
 Send an Amcor A/C message with the supplied settings. More...
 
void argo (IRArgoAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const int16_t sleep=-1)
 Send an Argo A/C message with the supplied settings. More...
 
void carrier64 (IRCarrierAc64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const int16_t sleep=-1)
 Send a Carrier 64-bit A/C message with the supplied settings. More...
 
void coolix (IRCoolixAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool light, const bool clean, const int16_t sleep=-1)
 Send a Coolix A/C message with the supplied settings. More...
 
void corona (IRCoronaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool econo)
 Send a Corona A/C message with the supplied settings. More...
 
void daikin (IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool clean)
 Send a Daikin A/C message with the supplied settings. More...
 
void daikin128 (IRDaikin128 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool econo, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Daikin 128-bit A/C message with the supplied settings. More...
 
void daikin152 (IRDaikin152 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool econo)
 Send a Daikin 152-bit A/C message with the supplied settings. More...
 
void daikin160 (IRDaikin160 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)
 Send a Daikin 160-bit A/C message with the supplied settings. More...
 
void daikin176 (IRDaikin176 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingh_t swingh)
 Send a Daikin 176-bit A/C message with the supplied settings. More...
 
void daikin2 (IRDaikin2 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool econo, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Daikin2 A/C message with the supplied settings. More...
 
void daikin216 (IRDaikin216 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo)
 Send a Daikin 216-bit A/C message with the supplied settings. More...
 
void daikin64 (IRDaikin64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Daikin 64-bit A/C message with the supplied settings. More...
 
void delonghiac (IRDelonghiAc *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const bool turbo, const int16_t sleep=-1)
 Send a Delonghi A/C message with the supplied settings. More...
 
void electra (IRElectraAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool lighttoggle, const bool clean)
 Send an Electra A/C message with the supplied settings. More...
 
void fujitsu (IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean)
 Send a Fujitsu A/C message with the supplied settings. More...
 
void goodweather (IRGoodweatherAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const int16_t sleep=-1)
 Send a Goodweather A/C message with the supplied settings. More...
 
void gree (IRGreeAC *ac, const gree_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const bool clean, const int16_t sleep=-1)
 Send a Gree A/C message with the supplied settings. More...
 
void haier (IRHaierAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool filter, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Haier A/C message with the supplied settings. More...
 
void haierYrwo2 (IRHaierACYRW02 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const int16_t sleep=-1)
 Send a Haier YRWO2 A/C message with the supplied settings. More...
 
void hitachi (IRHitachiAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh)
 Send a Hitachi A/C message with the supplied settings. More...
 
void hitachi1 (IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, const bool on, const bool power_toggle, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool swing_toggle, const int16_t sleep=-1)
 Send a Hitachi1 A/C message with the supplied settings. More...
 
void hitachi344 (IRHitachiAc344 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh)
 Send a Hitachi 344-bit A/C message with the supplied settings. More...
 
void hitachi424 (IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)
 Send a Hitachi 424-bit A/C message with the supplied settings. More...
 
void kelvinator (IRKelvinatorAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean)
 Send a Kelvinator A/C message with the supplied settings. More...
 
void lg (IRLgAc *ac, const lg_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
 Send a LG A/C message with the supplied settings. More...
 
void midea (IRMideaAC *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const int16_t sleep=-1)
 Send a Midea A/C message with the supplied settings. More...
 
void mitsubishi (IRMitsubishiAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const int16_t clock=-1)
 Send a Mitsubishi A/C message with the supplied settings. More...
 
void mitsubishi112 (IRMitsubishi112 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet)
 Send a Mitsubishi 112-bit A/C message with the supplied settings. More...
 
void mitsubishi136 (IRMitsubishi136 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet)
 Send a Mitsubishi 136-bit A/C message with the supplied settings. More...
 
void mitsubishiHeavy88 (IRMitsubishiHeavy88Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool econo, const bool clean)
 Send a Mitsubishi Heavy 88-bit A/C message with the supplied settings. More...
 
void mitsubishiHeavy152 (IRMitsubishiHeavy152Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean, const int16_t sleep=-1)
 Send a Mitsubishi Heavy 152-bit A/C message with the supplied settings. More...
 
void neoclima (IRNeoclimaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool light, const bool filter, const int16_t sleep=-1)
 Send a Neoclima A/C message with the supplied settings. More...
 
void panasonic (IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool filter, const int16_t clock=-1)
 Send a Panasonic A/C message with the supplied settings. More...
 
void samsung (IRSamsungAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean, const bool beep, const bool prevpower=true, const bool forcepower=true)
 Send a Samsung A/C message with the supplied settings. More...
 
void sharp (IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const bool clean)
 Send a Sharp A/C message with the supplied settings. More...
 
void tcl112 (IRTcl112Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool turbo, const bool light, const bool econo, const bool filter)
 Send a TCL 112-bit A/C message with the supplied settings. More...
 
void teco (IRTecoAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool light, const int16_t sleep=-1)
 Send a Teco A/C message with the supplied settings. More...
 
void toshiba (IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
 Send a Toshiba A/C message with the supplied settings. More...
 
void trotec (IRTrotecESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const int16_t sleep=-1)
 Send a Trotec A/C message with the supplied settings. More...
 
void vestel (IRVestelAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const int16_t sleep=-1, const int16_t clock=-1, const bool sendNormal=true)
 Send a Vestel A/C message with the supplied settings. More...
 
void whirlpool (IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Whirlpool A/C message with the supplied settings. More...
 
+ + + + + + + +

+Static Private Member Functions

static stdAc::state_t cleanState (const stdAc::state_t state)
 Create a new state base on the provided state that has been suitably fixed. More...
 
static stdAc::state_t handleToggles (const stdAc::state_t desired, const stdAc::state_t *prev=NULL)
 Create a new state base on desired & previous states but handle any state changes for options that need to be toggled. More...
 
+ + + + + + + + + +

+Private Attributes

uint16_t _pin
 
bool _inverted
 
bool _modulation
 
stdAc::state_t _prev
 
+

Constructor & Destructor Documentation

+ +

◆ IRac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRac::IRac (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGpio pin to use when transmitting IR messages.
[in]invertedtrue, gpio output defaults to high. false, to low.
[in]use_modulationtrue means use frequency modulation. false, don't.
+
+
+ +
+
+

Member Function Documentation

+ +

◆ amcor()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::amcor (IRAmcorAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan 
)
+
+private
+
+ +

Send an Amcor A/C message with the supplied settings.

+
Parameters
+ + + + + + +
[in,out]acA Ptr to an IRAmcorAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
+
+
+ +
+
+ +

◆ argo()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::argo (IRArgoACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send an Argo A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRArgoAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]sleepNr. of minutes for sleep mode.
+
+
+
Note
-1 is Off, >= 0 is on.
+ +
+
+ +

◆ boolToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::boolToString (const bool value)
+
+static
+
+ +

Convert the supplied boolean into the appropriate String.

+
Parameters
+ + +
[in]valueThe boolean value to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ carrier64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::carrier64 (IRCarrierAc64ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Carrier 64-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRCarrierAc64 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]sleepNr. of minutes for sleep mode.
+
+
+
Note
-1 is Off, >= 0 is on.
+ +
+
+ +

◆ cleanState()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::state_t IRac::cleanState (const stdAc::state_t state)
+
+staticprivate
+
+ +

Create a new state base on the provided state that has been suitably fixed.

+
Note
This is for use with Home Assistant, which requires mode to be off if the power is off.
+
Parameters
+ + +
[in]stateThe state_t structure describing the desired a/c state.
+
+
+
Returns
A stdAc::state_t with the needed settings.
+ +
+
+ +

◆ cmpStates()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRac::cmpStates (const stdAc::state_t a,
const stdAc::state_t b 
)
+
+static
+
+ +

Compare two AirCon states.

+
Note
The comparison excludes the clock.
+
Parameters
+ + + +
aA state_t to be compared.
bA state_t to be compared.
+
+
+
Returns
True if they differ, False if they don't.
+ +
+
+ +

◆ coolix()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::coolix (IRCoolixACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool turbo,
const bool light,
const bool clean,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Coolix A/C message with the supplied settings.

+
Note
May result in multiple messages being sent.
+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRCoolixAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]sleepNr. of minutes for sleep mode.
+
+
+
Note
-1 is Off, >= 0 is on.
+ +
+
+ +

◆ corona()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::corona (IRCoronaAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool econo 
)
+
+private
+
+ +

Send a Corona A/C message with the supplied settings.

+
Note
May result in multiple messages being sent.
+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRCoronaAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]econoRun the device in economical mode.
+
+
+ +
+
+ +

◆ daikin()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin (IRDaikinESPac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool clean 
)
+
+private
+
+ +

Send a Daikin A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRDaikinESP object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ daikin128()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin128 (IRDaikin128ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet,
const bool turbo,
const bool light,
const bool econo,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Daikin 128-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin128 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]econoRun the device in economical mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ daikin152()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin152 (IRDaikin152ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet,
const bool turbo,
const bool econo 
)
+
+private
+
+ +

Send a Daikin 152-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin152 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
+
+
+ +
+
+ +

◆ daikin160()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin160 (IRDaikin160ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv 
)
+
+private
+
+ +

Send a Daikin 160-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRDaikin160 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
+
+
+ +
+
+ +

◆ daikin176()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin176 (IRDaikin176ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingh_t swingh 
)
+
+private
+
+ +

Send a Daikin 176-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRDaikin176 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swinghThe horizontal swing setting.
+
+
+ +
+
+ +

◆ daikin2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin2 (IRDaikin2ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool light,
const bool econo,
const bool filter,
const bool clean,
const bool beep,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Daikin2 A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin2 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]econoRun the device in economical mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]beepEnable/Disable beeps when receiving IR messages.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ daikin216()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin216 (IRDaikin216ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo 
)
+
+private
+
+ +

Send a Daikin 216-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin216 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
+
+
+ +
+
+ +

◆ daikin64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin64 (IRDaikin64ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet,
const bool turbo,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Daikin 64-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin64 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ delonghiac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::delonghiac (IRDelonghiAcac,
const bool on,
const stdAc::opmode_t mode,
const bool celsius,
const float degrees,
const stdAc::fanspeed_t fan,
const bool turbo,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Delonghi A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRDelonghiAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]turboRun the device in turbo/powerful mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ electra()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::electra (IRElectraAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool turbo,
const bool lighttoggle,
const bool clean 
)
+
+private
+
+ +

Send an Electra A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + +
[in,out]acA Ptr to an IRElectraAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lighttoggleShould we toggle the LED/Display?
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ fanspeedToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::fanspeedToString (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert the supplied fan speed enum into the appropriate String.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ fujitsu()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::fujitsu (IRFujitsuACac,
const fujitsu_ac_remote_model_t model,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool filter,
const bool clean 
)
+
+private
+
+ +

Send a Fujitsu A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + + +
[in,out]acA Ptr to an IRFujitsuAC object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ getState()

+ +
+
+ + + + + + + + +
stdAc::state_t IRac::getState (void )
+
+ +

Get the current internal A/C climate state.

+
Returns
A Ptr to a state containing the current (to be sent) settings.
+ +
+
+ +

◆ getStatePrev()

+ +
+
+ + + + + + + + +
stdAc::state_t IRac::getStatePrev (void )
+
+ +

Get the previous internal A/C climate state that should have already been sent to the device. i.e. What the A/C unit should already be set to.

+
Returns
A Ptr to a state containing the previously sent settings.
+ +
+
+ +

◆ goodweather()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::goodweather (IRGoodweatherAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool light,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Goodweather A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRGoodweatherAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ gree()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::gree (IRGreeACac,
const gree_ac_remote_model_t model,
const bool on,
const stdAc::opmode_t mode,
const bool celsius,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool light,
const bool clean,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Gree A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + +
[in,out]acA Ptr to an IRGreeAC object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ haier()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::haier (IRHaierACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool filter,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Haier A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRGreeAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ haierYrwo2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::haierYrwo2 (IRHaierACYRW02ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool filter,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Haier YRWO2 A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRHaierACYRW02 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ handleToggles()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::state_t IRac::handleToggles (const stdAc::state_t desired,
const stdAc::state_tprev = NULL 
)
+
+staticprivate
+
+ +

Create a new state base on desired & previous states but handle any state changes for options that need to be toggled.

+
Parameters
+ + + +
[in]desiredThe state_t structure describing the desired a/c state.
[in]prevA Ptr to the previous state_t structure.
+
+
+
Returns
A stdAc::state_t with the needed settings.
+ +
+
+ +

◆ hasStateChanged()

+ +
+
+ + + + + + + + +
bool IRac::hasStateChanged (void )
+
+ +

Check if the internal state has changed from what was previously sent.

+
Note
The comparison excludes the clock.
+
Returns
True if it has changed, False if not.
+ +
+
+ +

◆ hitachi()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::hitachi (IRHitachiAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh 
)
+
+private
+
+ +

Send a Hitachi A/C message with the supplied settings.

+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRHitachiAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
+
+
+ +
+
+ +

◆ hitachi1()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::hitachi1 (IRHitachiAc1ac,
const hitachi_ac1_remote_model_t model,
const bool on,
const bool power_toggle,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool swing_toggle,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Hitachi1 A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRHitachiAc1 object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]power_toggleThe power toggle setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]swing_toggleThe swing_toggle setting.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+
Note
The sleep mode used is the "Sleep 2" setting.
+ +
+
+ +

◆ hitachi344()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::hitachi344 (IRHitachiAc344ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh 
)
+
+private
+
+ +

Send a Hitachi 344-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRHitachiAc344 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
+
+
+ +
+
+ +

◆ hitachi424()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::hitachi424 (IRHitachiAc424ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv 
)
+
+private
+
+ +

Send a Hitachi 424-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRHitachiAc424 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
+
+
+ +
+
+ +

◆ initState() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
void IRac::initState (stdAc::state_tstate)
+
+static
+
+ +

Initialse the given state with the supplied settings.

+
Parameters
+ + +
[out]stateA Ptr to where the settings will be stored.
+
+
+
Note
Sets all the parameters to reasonable base/automatic defaults.
+ +
+
+ +

◆ initState() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::initState (stdAc::state_tstate,
const decode_type_t vendor,
const int16_t model,
const bool power,
const stdAc::opmode_t mode,
const float degrees,
const bool celsius,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool light,
const bool filter,
const bool clean,
const bool beep,
const int16_t sleep,
const int16_t clock 
)
+
+static
+
+ +

Initialse the given state with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + + + + + + + + +
[out]stateA Ptr to where the settings will be stored.
[in]vendorThe vendor/protocol type.
[in]modelThe A/C model if applicable.
[in]powerThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]beepEnable/Disable beeps when receiving IR messages.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on. Some devices it is the nr. of mins to run for. Others it may be the time to enter/exit sleep mode. i.e. Time in Nr. of mins since midnight.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ isProtocolSupported()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRac::isProtocolSupported (const decode_type_t protocol)
+
+static
+
+ +

Is the given protocol supported by the IRac class?

+
Parameters
+ + +
[in]protocolThe vendor/protocol type.
+
+
+
Returns
true if the protocol is supported by this class, otherwise false.
+ +
+
+ +

◆ kelvinator()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::kelvinator (IRKelvinatorACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool light,
const bool filter,
const bool clean 
)
+
+private
+
+ +

Send a Kelvinator A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + +
[in,out]acA Ptr to an IRKelvinatorAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. XFan, dry filters etc
+
+
+ +
+
+ +

◆ lg()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::lg (IRLgAcac,
const lg_ac_remote_model_t model,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan 
)
+
+private
+
+ +

Send a LG A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRLgAc object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
+
+
+ +
+
+ +

◆ markAsSent()

+ +
+
+ + + + + + + + +
void IRac::markAsSent (void )
+
+ +

Update the previous state to the current one.

+ +
+
+ +

◆ midea()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::midea (IRMideaACac,
const bool on,
const stdAc::opmode_t mode,
const bool celsius,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Midea A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRMideaAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ mitsubishi()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishi (IRMitsubishiACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Mitsubishi A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRMitsubishiAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+
Note
Clock can only be set in 10 minute increments. i.e. % 10.
+ +
+
+ +

◆ mitsubishi112()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishi112 (IRMitsubishi112ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet 
)
+
+private
+
+ +

Send a Mitsubishi 112-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRMitsubishi112 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
+
+
+ +
+
+ +

◆ mitsubishi136()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishi136 (IRMitsubishi136ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet 
)
+
+private
+
+ +

Send a Mitsubishi 136-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRMitsubishi136 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
+
+
+ +
+
+ +

◆ mitsubishiHeavy152()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishiHeavy152 (IRMitsubishiHeavy152Acac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool filter,
const bool clean,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Mitsubishi Heavy 152-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + + +
[in,out]acA Ptr to an IRMitsubishiHeavy152Ac object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
+
+
+ +
+
+ +

◆ mitsubishiHeavy88()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishiHeavy88 (IRMitsubishiHeavy88Acac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool turbo,
const bool econo,
const bool clean 
)
+
+private
+
+ +

Send a Mitsubishi Heavy 88-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + +
[in,out]acA Ptr to an IRMitsubishiHeavy88Ac object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ neoclima()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::neoclima (IRNeoclimaAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool turbo,
const bool light,
const bool filter,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Neoclima A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRNeoclimaAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
+
+
+ +
+
+ +

◆ opmodeToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::opmodeToString (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert the supplied operation mode into the appropriate String.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ panasonic()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::panasonic (IRPanasonicAcac,
const panasonic_ac_remote_model_t model,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool filter,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Panasonic A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + +
[in,out]acA Ptr to an IRPanasonicAc object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ samsung()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::samsung (IRSamsungAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet,
const bool turbo,
const bool light,
const bool filter,
const bool clean,
const bool beep,
const bool prevpower = true,
const bool forcepower = true 
)
+
+private
+
+ +

Send a Samsung A/C message with the supplied settings.

+
Note
Multiple IR messages may be generated & sent.
+
Parameters
+ + + + + + + + + + + + + + + +
[in,out]acA Ptr to an IRSamsungAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]beepEnable/Disable beeps when receiving IR messages.
[in]prevpowerThe power setting from the previous A/C state.
[in]forcepowerDo we force send the special power message?
+
+
+ +
+
+ +

◆ sendAc() [1/3]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRac::sendAc (const decode_type_t vendor,
const int16_t model,
const bool power,
const stdAc::opmode_t mode,
const float degrees,
const bool celsius,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool light,
const bool filter,
const bool clean,
const bool beep,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+ +

Send A/C message for a given device using common A/C settings.

+
Parameters
+ + + + + + + + +
[in]vendorThe vendor/protocol type.
[in]modelThe A/C model if applicable.
[in]powerThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]fanThe speed setting for the fan.
+
+
+
Note
The following are all "if supported" by the underlying A/C classes.
+
Parameters
+ + + + + + + + + + + + +
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]beepEnable/Disable beeps when receiving IR messages.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on. Some devices it is the nr. of mins to run for. Others it may be the time to enter/exit sleep mode. i.e. Time in Nr. of mins since midnight.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+
Returns
True, if accepted/converted/attempted etc. False, if unsupported.
+ +
+
+ +

◆ sendAc() [2/3]

+ +
+
+ + + + + + + + + + + + + + + + + + +
bool IRac::sendAc (const stdAc::state_t desired,
const stdAc::state_tprev = NULL 
)
+
+ +

Send A/C message for a given device using state_t structures.

+
Parameters
+ + + +
[in]desiredThe state_t structure describing the desired new ac state
[in]prevA Ptr to the state_t structure containing the previous state
+
+
+
Returns
True, if accepted/converted/attempted etc. False, if unsupported.
+ +
+
+ +

◆ sendAc() [3/3]

+ +
+
+ + + + + + + + +
bool IRac::sendAc (void )
+
+ +

Send an A/C message based soley on our internal state.

+
Returns
True, if accepted/converted/attempted. False, if unsupported.
+ +
+
+ +

◆ sharp()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::sharp (IRSharpAcac,
const bool on,
const bool prev_power,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool filter,
const bool clean 
)
+
+private
+
+ +

Send a Sharp A/C message with the supplied settings.

+
Note
Multiple IR messages may be generated & sent.
+
Parameters
+ + + + + + + + + + + +
[in,out]acA Ptr to an IRSharpAc object to use.
[in]onThe power setting.
[in]prev_powerThe power setting from the previous A/C state.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ strToBool()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRac::strToBool (const char * str,
const bool def = false 
)
+
+static
+
+ +

Convert the supplied str into the appropriate boolean value.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe boolean value to return if no conversion was possible.
+
+
+
Returns
The equivilent boolean value.
+ +
+
+ +

◆ strToFanspeed()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::fanspeed_t IRac::strToFanspeed (const char * str,
const stdAc::fanspeed_t def = stdAc::fanspeed_t::kAuto 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ strToModel()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int16_t IRac::strToModel (const char * str,
const int16_t def = -1 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Note
Assumes str is the model code or an integer >= 1.
+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ strToOpmode()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::opmode_t IRac::strToOpmode (const char * str,
const stdAc::opmode_t def = stdAc::opmode_t::kAuto 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ strToSwingH()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::swingh_t IRac::strToSwingH (const char * str,
const stdAc::swingh_t def = stdAc::swingh_t::kOff 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ strToSwingV()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::swingv_t IRac::strToSwingV (const char * str,
const stdAc::swingv_t def = stdAc::swingv_t::kOff 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ swinghToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::swinghToString (const stdAc::swingh_t swingh)
+
+static
+
+ +

Convert the supplied enum into the appropriate String.

+
Parameters
+ + +
[in]swinghThe enum to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ swingvToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::swingvToString (const stdAc::swingv_t swingv)
+
+static
+
+ +

Convert the supplied enum into the appropriate String.

+
Parameters
+ + +
[in]swingvThe enum to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ tcl112()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::tcl112 (IRTcl112Acac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool turbo,
const bool light,
const bool econo,
const bool filter 
)
+
+private
+
+ +

Send a TCL 112-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRTcl112Ac object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]econoRun the device in economical mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
+
+
+ +
+
+ +

◆ teco()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::teco (IRTecoAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool light,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Teco A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRTecoAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]lightTurn on the LED/Display mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
+
+
+ +
+
+ +

◆ toshiba()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::toshiba (IRToshibaACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan 
)
+
+private
+
+ +

Send a Toshiba A/C message with the supplied settings.

+
Parameters
+ + + + + + +
[in,out]acA Ptr to an IRToshibaAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
+
+
+ +
+
+ +

◆ trotec()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::trotec (IRTrotecESPac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Trotec A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRTrotecESP object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
+
+
+ +
+
+ +

◆ vestel()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::vestel (IRVestelAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool filter,
const int16_t sleep = -1,
const int16_t clock = -1,
const bool sendNormal = true 
)
+
+private
+
+ +

Send a Vestel A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRVestelAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
[in]sendNormalDo we send a Normal settings message at all? i.e In addition to the clock/time/timer message
+
+
+ +
+
+ +

◆ whirlpool()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::whirlpool (IRWhirlpoolAcac,
const whirlpool_ac_remote_model_t model,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool light,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Whirlpool A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRWhirlpoolAc object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+

Member Data Documentation

+ +

◆ _inverted

+ +
+
+ + + + + +
+ + + + +
bool IRac::_inverted
+
+private
+
+ +
+
+ +

◆ _modulation

+ +
+
+ + + + + +
+ + + + +
bool IRac::_modulation
+
+private
+
+ +
+
+ +

◆ _pin

+ +
+
+ + + + + +
+ + + + +
uint16_t IRac::_pin
+
+private
+
+ +
+
+ +

◆ _prev

+ +
+
+ + + + + +
+ + + + +
stdAc::state_t IRac::_prev
+
+private
+
+ +
+
+ +

◆ next

+ +
+
+ + + + +
stdAc::state_t IRac::next
+
+ +

The state we want the device to be in after we send.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.map new file mode 100644 index 000000000..a8e1d6323 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.md5 new file mode 100644 index 000000000..76e762f05 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.md5 @@ -0,0 +1 @@ +798baf66f32a8ad80bc719cc6de8c2ba \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..ed8ea1ee9140bc33fef84a87fb305f46cea3896e GIT binary patch literal 3252 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv-members.html new file mode 100644 index 000000000..8be86fdbc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv-members.html @@ -0,0 +1,189 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRrecv Member List
+
+
+ +

This is the complete list of members for IRrecv, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_ptr, const bool use_bits, const uint16_t remaining, const uint16_t required, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
_timer_numIRrecvprivate
_toleranceIRrecvprivate
_unknown_thresholdIRrecvprivate
_validTolerance(const uint8_t percentage)IRrecvprivate
compare(const uint16_t oldval, const uint16_t newval)IRrecvprivate
copyIrParams(volatile irparams_t *src, irparams_t *dst)IRrecvprivate
crudeNoiseFilter(decode_results *results, const uint16_t floor=0)IRrecvprivate
decode(decode_results *results, irparams_t *save=NULL, uint8_t max_skip=0, uint16_t noise_floor=0)IRrecv
decodeAirwell(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAirwellBits, const bool strict=true)IRrecvprivate
decodeAiwaRCT501(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAiwaRcT501Bits, const bool strict=true)IRrecvprivate
decodeAmcor(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAmcorBits, const bool strict=true)IRrecvprivate
decodeArgo(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kArgoBits, const bool strict=true)IRrecvprivate
decodeCarrierAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAcBits, const bool strict=true)IRrecvprivate
decodeCarrierAC40(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc40Bits, const bool strict=true)IRrecvprivate
decodeCarrierAC64(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc64Bits, const bool strict=true)IRrecvprivate
decodeCOOLIX(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoolixBits, const bool strict=true)IRrecvprivate
decodeCoronaAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoronaAcBitsShort, const bool strict=true)IRrecvprivate
decodeDaikin(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikinBits, const bool strict=true)IRrecvprivate
decodeDaikin128(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin128Bits, const bool strict=true)IRrecvprivate
decodeDaikin152(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin152Bits, const bool strict=true)IRrecvprivate
decodeDaikin160(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin160Bits, const bool strict=true)IRrecvprivate
decodeDaikin176(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin176Bits, const bool strict=true)IRrecvprivate
decodeDaikin2(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin2Bits, const bool strict=true)IRrecvprivate
decodeDaikin216(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin216Bits, const bool strict=true)IRrecvprivate
decodeDaikin64(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin64Bits, const bool strict=true)IRrecvprivate
decodeDelonghiAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDelonghiAcBits, const bool strict=true)IRrecvprivate
decodeDenon(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDenonBits, const bool strict=true)IRrecvprivate
decodeDISH(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDishBits, const bool strict=true)IRrecvprivate
decodeDoshisha(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDoshishaBits, const bool strict=true)IRrecvprivate
decodeElectraAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kElectraAcBits, const bool strict=true)IRrecvprivate
decodeEpson(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kEpsonBits, const bool strict=true)IRrecvprivate
decodeFujitsuAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kFujitsuAcBits, const bool strict=false)IRrecvprivate
decodeGICable(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGicableBits, const bool strict=true)IRrecvprivate
decodeGoodweather(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGoodweatherBits, const bool strict=true)IRrecvprivate
decodeGree(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGreeBits, const bool strict=true)IRrecvprivate
decodeHaierAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACBits, const bool strict=true)IRrecvprivate
decodeHaierACYRW02(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACYRW02Bits, const bool strict=true)IRrecvprivate
decodeHash(decode_results *results)IRrecvprivate
decodeHitachiAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAcBits, const bool strict=true, const bool MSBfirst=true)IRrecvprivate
decodeHitachiAC1(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc1Bits, const bool strict=true)IRrecvprivate
decodeHitachiAc3(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc3Bits, const bool strict=true)IRrecvprivate
decodeHitachiAc424(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc424Bits, const bool strict=true)IRrecvprivate
decodeInax(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kInaxBits, const bool strict=true)IRrecvprivate
decodeJVC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kJvcBits, const bool strict=true)IRrecvprivate
decodeKelvinator(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kKelvinatorBits, const bool strict=true)IRrecvprivate
decodeLasertag(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLasertagBits, const bool strict=true)IRrecvprivate
decodeLegoPf(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLegoPfBits, const bool strict=true)IRrecvprivate
decodeLG(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLgBits, const bool strict=false)IRrecvprivate
decodeLutron(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLutronBits, const bool strict=true)IRrecvprivate
decodeMagiQuest(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMagiquestBits, const bool strict=true)IRrecvprivate
decodeMidea(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMideaBits, const bool strict=true)IRrecvprivate
decodeMidea24(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMidea24Bits, const bool strict=true)IRrecvprivate
decodeMitsubishi(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)IRrecvprivate
decodeMitsubishi112(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi112Bits, const bool strict=true)IRrecvprivate
decodeMitsubishi136(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi136Bits, const bool strict=true)IRrecvprivate
decodeMitsubishi2(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)IRrecvprivate
decodeMitsubishiAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiACBits, const bool strict=false)IRrecvprivate
decodeMitsubishiHeavy(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiHeavy152Bits, const bool strict=true)IRrecvprivate
decodeMultibrackets(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMultibracketsBits, const bool strict=true)IRrecvprivate
decodeMWM(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=24, const bool strict=true)IRrecvprivate
decodeNEC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNECBits, const bool strict=true)IRrecvprivate
decodeNeoclima(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNeoclimaBits, const bool strict=true)IRrecvprivate
decodeNikai(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNikaiBits, const bool strict=true)IRrecvprivate
decodePanasonic(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicBits, const bool strict=false, const uint32_t manufacturer=kPanasonicManufacturer)IRrecvprivate
decodePanasonicAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicAcBits, const bool strict=true)IRrecvprivate
decodePioneer(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPioneerBits, const bool strict=true)IRrecvprivate
decodeRC5(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC5XBits, const bool strict=true)IRrecvprivate
decodeRC6(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC6Mode0Bits, const bool strict=false)IRrecvprivate
decodeRCMM(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRCMMBits, const bool strict=false)IRrecvprivate
decodeSAMSUNG(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungBits, const bool strict=true)IRrecvprivate
decodeSamsung36(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsung36Bits, const bool strict=true)IRrecvprivate
decodeSamsungAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungAcBits, const bool strict=true)IRrecvprivate
decodeSanyoLC7461(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSanyoLC7461Bits, bool strict=true)IRrecvprivate
decodeSharp(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpBits, const bool strict=true, const bool expansion=true)IRrecvprivate
decodeSharpAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpAcBits, const bool strict=true)IRrecvprivate
decodeSony(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSonyMinBits, const bool strict=false)IRrecvprivate
decodeSymphony(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSymphonyBits, const bool strict=true)IRrecvprivate
decodeTeco(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTecoBits, const bool strict=false)IRrecvprivate
decodeToshibaAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbytes=kToshibaACBits, const bool strict=true)IRrecvprivate
decodeTrotec(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTrotecBits, const bool strict=true)IRrecvprivate
decodeVestelAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kVestelAcBits, const bool strict=true)IRrecvprivate
decodeWhirlpoolAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhirlpoolAcBits, const bool strict=true)IRrecvprivate
decodeWhynter(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhynterBits, const bool strict=true)IRrecvprivate
decodeZepeal(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kZepealBits, const bool strict=true)IRrecvprivate
disableIRIn(void)IRrecv
enableIRIn(const bool pullup=false)IRrecv
getBufSize(void)IRrecv
getRClevel(decode_results *results, uint16_t *offset, uint16_t *used, uint16_t bitTime, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const uint16_t delta=0, const uint8_t maxwidth=3)IRrecvprivate
getTolerance(void)IRrecv
irparams_saveIRrecvprivate
IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)IRrecvexplicit
IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false)IRrecvexplicit
match(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)IRrecv
matchAtLeast(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)IRrecvprivate
matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchData(volatile uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchGenericConstBitTime(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t one, const uint32_t zero, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchManchester(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t clock_period, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)IRrecvprivate
matchManchesterData(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t half_period, const uint16_t starting_balance=0, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)IRrecvprivate
matchMark(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)IRrecv
matchSpace(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)IRrecv
resume(void)IRrecv
setTolerance(const uint8_t percent=kTolerance)IRrecv
setUnknownThreshold(const uint16_t length)IRrecv
ticksHigh(const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)IRrecvprivate
ticksLow(const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)IRrecvprivate
~IRrecv(void)IRrecv
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv.html new file mode 100644 index 000000000..88e252a44 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv.html @@ -0,0 +1,7184 @@ + + + + + + + +IRremoteESP8266: IRrecv Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for receiving IR messages. + More...

+ +

#include <IRrecv.h>

+
+Collaboration diagram for IRrecv:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRrecv (const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)
 Class constructor Args: More...
 
 IRrecv (const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false)
 
 ~IRrecv (void)
 Class destructor Cleans up after the object is no longer needed. e.g. Frees up all memory used by the various buffers, and disables any timers or interrupts used. More...
 
void setTolerance (const uint8_t percent=kTolerance)
 Set the base tolerance percentage for matching incoming IR messages. More...
 
uint8_t getTolerance (void)
 Get the base tolerance percentage for matching incoming IR messages. More...
 
bool decode (decode_results *results, irparams_t *save=NULL, uint8_t max_skip=0, uint16_t noise_floor=0)
 Decodes the received IR message. If the interrupt state is saved, we will immediately resume waiting for the next IR message to avoid missing messages. More...
 
void enableIRIn (const bool pullup=false)
 Set up and (re)start the IR capture mechanism. More...
 
void disableIRIn (void)
 Stop collection of any received IR data. Disable any timers and interrupts. More...
 
void resume (void)
 Resume collection of received IR data. More...
 
uint16_t getBufSize (void)
 Obtain the maximum number of entries possible in the capture buffer. i.e. It's size. More...
 
void setUnknownThreshold (const uint16_t length)
 Set the minimum length we will consider for reporting UNKNOWN message types. More...
 
bool match (const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
 Check if we match a pulse(measured) with the desired within +/-tolerance percent and/or +/- a fixed delta range. More...
 
bool matchMark (const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)
 Check if we match a mark signal(measured) with the desired within +/-tolerance percent, after an expected is excess is added. More...
 
bool matchSpace (const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)
 Check if we match a space signal(measured) with the desired within +/-tolerance percent, after an expected is excess is removed. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

uint8_t _validTolerance (const uint8_t percentage)
 Convert the tolerance percentage into something valid. More...
 
void copyIrParams (volatile irparams_t *src, irparams_t *dst)
 Make a copy of the interrupt state & buffer data. Needed because irparams is marked as volatile, thus memcpy() isn't allowed. Only call this when you know the interrupt handlers won't modify anything. i.e. In kStopState. More...
 
uint16_t compare (const uint16_t oldval, const uint16_t newval)
 Compare two tick values. More...
 
uint32_t ticksLow (const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
 Calculate the lower bound of the nr. of ticks. More...
 
uint32_t ticksHigh (const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
 Calculate the upper bound of the nr. of ticks. More...
 
bool matchAtLeast (const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
 Check if we match a pulse(measured) of at least desired within tolerance percent and/or a fixed delta margin. More...
 
uint16_t _matchGeneric (volatile uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_ptr, const bool use_bits, const uint16_t remaining, const uint16_t required, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode a generic/typical IR message. The data is stored in result_bits_ptr or result_bytes_ptr depending on flag use_bits. More...
 
match_result_t matchData (volatile uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode the typical data section of an IR message. The data value is stored in the least significant bits reguardless of the bit ordering requested. More...
 
uint16_t matchBytes (volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode the typical data section of an IR message. The bytes are stored at result_ptr. The first byte in the result equates to the first byte encountered, and so on. More...
 
uint16_t matchGeneric (volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode a generic/typical <= 64bit IR message. The data is stored at result_ptr. More...
 
uint16_t matchGeneric (volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode a generic/typical > 64bit IR message. The bytes are stored at result_ptr. The first byte in the result equates to the first byte encountered, and so on. More...
 
uint16_t matchGenericConstBitTime (volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t one, const uint32_t zero, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode a generic/typical constant bit time <= 64bit IR message. The data is stored at result_ptr. More...
 
uint16_t matchManchesterData (volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t half_period, const uint16_t starting_balance=0, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
 Match & decode a Manchester Code data (<= 64bits. More...
 
uint16_t matchManchester (volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t clock_period, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
 Match & decode a Manchester Code <= 64bit IR message. The data is stored at result_ptr. More...
 
void crudeNoiseFilter (decode_results *results, const uint16_t floor=0)
 Remove or merge pulses in the capture buffer that are too short. More...
 
bool decodeHash (decode_results *results)
 Decode any arbitrary IR message into a 32-bit code value. Instead of decoding using a standard encoding scheme (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. More...
 
bool decodeNEC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNECBits, const bool strict=true)
 Decode the supplied NEC (Renesas) message. Status: STABLE / Known good. More...
 
bool decodeArgo (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kArgoBits, const bool strict=true)
 Decode the supplied Argo message. Status: BETA / Probably works. More...
 
bool decodeSony (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSonyMinBits, const bool strict=false)
 Decode the supplied Sony/SIRC message. Status: STABLE / Should be working. strict mode is ALPHA / Untested. More...
 
bool decodeSanyoLC7461 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSanyoLC7461Bits, bool strict=true)
 Decode the supplied SANYO LC7461 message. Status: BETA / Probably works. More...
 
bool decodeMitsubishi (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)
 Decode the supplied Mitsubishi 16-bit message. Status: STABLE / Working. More...
 
bool decodeMitsubishi2 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)
 Decode the supplied second variation of a Mitsubishi 16-bit message. Status: STABLE / Working. More...
 
bool decodeMitsubishiAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiACBits, const bool strict=false)
 Decode the supplied Mitsubish 144-bit A/C message. Status: BETA / Probably works. More...
 
bool decodeMitsubishi136 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi136Bits, const bool strict=true)
 Decode the supplied Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: STABLE / Reported as working. More...
 
bool decodeMitsubishi112 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi112Bits, const bool strict=true)
 Decode the supplied Mitsubishi/TCL 112-bit A/C message. (MITSUBISHI112, TCL112AC) Status: STABLE / Reported as working. More...
 
bool decodeMitsubishiHeavy (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiHeavy152Bits, const bool strict=true)
 Decode the supplied Mitsubishi Heavy Industries A/C message. Status: BETA / Appears to be working. Needs testing against a real device. More...
 
int16_t getRClevel (decode_results *results, uint16_t *offset, uint16_t *used, uint16_t bitTime, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const uint16_t delta=0, const uint8_t maxwidth=3)
 Gets one undecoded level at a time from the raw buffer. The RC5/6 decoding is easier if the data is broken into time intervals. E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, successive calls to getRClevel will return MARK, MARK, SPACE. offset and used are updated to keep track of the current position. More...
 
bool decodeRC5 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC5XBits, const bool strict=true)
 Decode the supplied RC-5/RC5X message. Status: RC-5 (stable), RC-5X (alpha) More...
 
bool decodeRC6 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC6Mode0Bits, const bool strict=false)
 Decode the supplied RC6 message. Status: Stable. More...
 
bool decodeRCMM (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRCMMBits, const bool strict=false)
 Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. Status: STABLE / Should be working. More...
 
bool decodePanasonic (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicBits, const bool strict=false, const uint32_t manufacturer=kPanasonicManufacturer)
 Decode the supplied Panasonic message. Status: STABLE / Should be working. More...
 
bool decodeLG (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLgBits, const bool strict=false)
 Decode the supplied LG message. Status: STABLE / Working. More...
 
bool decodeInax (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kInaxBits, const bool strict=true)
 Decode the supplied Inax Toilet message. Status: Stable / Known working. More...
 
bool decodeJVC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kJvcBits, const bool strict=true)
 Decode the supplied JVC message. Status: Stable / Known working. More...
 
bool decodeSAMSUNG (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungBits, const bool strict=true)
 Decode the supplied Samsung 32-bit message. Status: STABLE. More...
 
bool decodeSamsung36 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsung36Bits, const bool strict=true)
 Decode the supplied Samsung36 message. Status: Alpha / Experimental. More...
 
bool decodeSamsungAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungAcBits, const bool strict=true)
 Decode the supplied Samsung A/C message. Status: Stable / Known to be working. More...
 
bool decodeWhynter (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhynterBits, const bool strict=true)
 Decode the supplied Whynter message. Status: STABLE / Working. Strict mode is ALPHA. More...
 
bool decodeCOOLIX (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoolixBits, const bool strict=true)
 Decode the supplied Coolix A/C message. Status: STABLE / Known Working. More...
 
bool decodeDenon (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDenonBits, const bool strict=true)
 Decode the supplied Delonghi A/C message. Status: STABLE / Should work fine. More...
 
bool decodeDISH (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDishBits, const bool strict=true)
 Decode the supplied DISH NETWORK message. Status: ALPHA (untested and unconfirmed.) More...
 
bool decodeSharp (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpBits, const bool strict=true, const bool expansion=true)
 Decode the supplied Sharp message. Status: STABLE / Working fine. More...
 
bool decodeSharpAc (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpAcBits, const bool strict=true)
 Decode the supplied Sharp A/C message. Status: STABLE / Known working. More...
 
bool decodeAiwaRCT501 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAiwaRcT501Bits, const bool strict=true)
 Decode the supplied Aiwa RC T501 message. Status: BETA / Should work. More...
 
bool decodeNikai (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNikaiBits, const bool strict=true)
 Decode the supplied Nikai message. Status: STABLE / Working. More...
 
bool decodeMagiQuest (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMagiquestBits, const bool strict=true)
 Decode the supplied MagiQuest message. Status: Beta / Should work. More...
 
bool decodeKelvinator (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kKelvinatorBits, const bool strict=true)
 Decode the supplied Kelvinator message. Status: STABLE / Known working. More...
 
bool decodeDaikin (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikinBits, const bool strict=true)
 Decode the supplied Daikin 280-bit message. (DAIKIN) Status: STABLE / Reported as working. More...
 
bool decodeDaikin64 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin64Bits, const bool strict=true)
 Decode the supplied Daikin 64-bit message. (DAIKIN64) Status: Beta / Probably Working. More...
 
bool decodeDaikin128 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin128Bits, const bool strict=true)
 Decode the supplied Daikin 128-bit message. (DAIKIN128) Status: STABLE / Known Working. More...
 
bool decodeDaikin152 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin152Bits, const bool strict=true)
 Decode the supplied Daikin 152-bit message. (DAIKIN152) Status: STABLE / Known Working. More...
 
bool decodeDaikin160 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin160Bits, const bool strict=true)
 Decode the supplied Daikin 160-bit message. (DAIKIN160) Status: STABLE / Confirmed working. More...
 
bool decodeDaikin176 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin176Bits, const bool strict=true)
 Decode the supplied Daikin 176-bit message. (DAIKIN176) Status: STABLE / Expected to work. More...
 
bool decodeDaikin2 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin2Bits, const bool strict=true)
 Decode the supplied Daikin 312-bit message. (DAIKIN2) Status: STABLE / Works as expected. More...
 
bool decodeDaikin216 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin216Bits, const bool strict=true)
 Decode the supplied Daikin 216-bit message. (DAIKIN216) Status: STABLE / Should be working. More...
 
bool decodeToshibaAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbytes=kToshibaACBits, const bool strict=true)
 Decode the supplied Toshiba A/C message. Status: STABLE / Working. More...
 
bool decodeTrotec (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTrotecBits, const bool strict=true)
 Decode the supplied Trotec message. Status: STABLE / Works. Untested on real devices. More...
 
bool decodeMidea (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMideaBits, const bool strict=true)
 Decode the supplied Midea message. Status: Alpha / Needs testing against a real device. More...
 
bool decodeMidea24 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMidea24Bits, const bool strict=true)
 Decode the supplied Midea24 message. Status: STABLE / Confirmed working on a real device. More...
 
bool decodeFujitsuAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kFujitsuAcBits, const bool strict=false)
 Decode the supplied Fujitsu AC IR message if possible. Status: STABLE / Working. More...
 
bool decodeLasertag (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLasertagBits, const bool strict=true)
 Decode the supplied Lasertag message. Status: BETA / Appears to be working 90% of the time. More...
 
bool decodeCarrierAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAcBits, const bool strict=true)
 Decode the supplied Carrier HVAC message. More...
 
bool decodeCarrierAC40 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc40Bits, const bool strict=true)
 Decode the supplied Carrier 40-bit HVAC message. Carrier HVAC messages contain only 40 bits, but it is sent three(3) times. Status: STABLE / Tested against a real device. More...
 
bool decodeCarrierAC64 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc64Bits, const bool strict=true)
 Decode the supplied Carrier 64-bit HVAC message. Status: STABLE / Known to be working. More...
 
bool decodeGoodweather (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGoodweatherBits, const bool strict=true)
 Decode the supplied Goodweather message. Status: BETA / Probably works. More...
 
bool decodeGree (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGreeBits, const bool strict=true)
 Decode the supplied Gree HVAC message. Status: STABLE / Working. More...
 
bool decodeHaierAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACBits, const bool strict=true)
 Decode the supplied Haier HSU07-HEA03 remote message. Status: STABLE / Known to be working. More...
 
bool decodeHaierACYRW02 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACYRW02Bits, const bool strict=true)
 Decode the supplied Haier YR-W02 remote A/C message. Status: BETA / Appears to be working. More...
 
bool decodeHitachiAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAcBits, const bool strict=true, const bool MSBfirst=true)
 Decode the supplied Hitachi A/C message. Status: STABLE / Expected to work. More...
 
bool decodeHitachiAC1 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc1Bits, const bool strict=true)
 
bool decodeHitachiAc3 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc3Bits, const bool strict=true)
 Decode the supplied Hitachi 15to27-byte/120to216-bit A/C message. Status: STABLE / Works fine. More...
 
bool decodeHitachiAc424 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc424Bits, const bool strict=true)
 Decode the supplied Hitachi 53-byte/424-bit A/C message. Status: STABLE / Reported as working. More...
 
bool decodeGICable (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGicableBits, const bool strict=true)
 Decode the supplied G.I. Cable message. Status: Alpha / Not tested against a real device. More...
 
bool decodeWhirlpoolAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhirlpoolAcBits, const bool strict=true)
 Decode the supplied Whirlpool A/C message. Status: STABLE / Working as intended. More...
 
bool decodeLutron (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLutronBits, const bool strict=true)
 Decode the supplied Lutron message. Status: STABLE / Working. More...
 
bool decodeElectraAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kElectraAcBits, const bool strict=true)
 Decode the supplied Electra A/C message. Status: STABLE / Known working. More...
 
bool decodePanasonicAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicAcBits, const bool strict=true)
 Decode the supplied Panasonic AC message. Status: STABLE / Works with real device(s). More...
 
bool decodePioneer (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPioneerBits, const bool strict=true)
 Decode the supplied Pioneer message. Status: STABLE / Should be working. (Self decodes & real examples) More...
 
bool decodeMWM (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=24, const bool strict=true)
 Decode the supplied MWM message. Status: Implemented. More...
 
bool decodeVestelAc (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kVestelAcBits, const bool strict=true)
 Decode the supplied Vestel message. Status: Alpha / Needs testing against a real device. More...
 
bool decodeTeco (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTecoBits, const bool strict=false)
 Decode the supplied Teco message. Status: STABLE / Tested. More...
 
bool decodeLegoPf (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLegoPfBits, const bool strict=true)
 Decode the supplied LEGO Power Functions message. Status: STABLE / Appears to work. More...
 
bool decodeNeoclima (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNeoclimaBits, const bool strict=true)
 Decode the supplied Neoclima message. Status: STABLE / Known working. More...
 
bool decodeAmcor (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAmcorBits, const bool strict=true)
 Decode the supplied Amcor HVAC message. Status: STABLE / Reported as working. More...
 
bool decodeEpson (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kEpsonBits, const bool strict=true)
 Decode the supplied Epson message. Status: Beta / Probably works. More...
 
bool decodeSymphony (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSymphonyBits, const bool strict=true)
 Decode the supplied Symphony packet/message. Status: STABLE / Should be working. More...
 
bool decodeAirwell (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAirwellBits, const bool strict=true)
 Decode the supplied Airwell "Manchester code" message. More...
 
bool decodeDelonghiAc (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDelonghiAcBits, const bool strict=true)
 Decode the supplied Delonghi A/C message. Status: STABLE / Expected to be working. More...
 
bool decodeDoshisha (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDoshishaBits, const bool strict=true)
 Decode the supplied Doshisha message. Status: STABLE / Works on real device. More...
 
bool decodeMultibrackets (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMultibracketsBits, const bool strict=true)
 Decode the Multibrackets message. Status: BETA / Appears to be working. More...
 
bool decodeCoronaAc (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoronaAcBitsShort, const bool strict=true)
 Decode the supplied CoronaAc message. Status: STABLE / Appears to be working. More...
 
bool decodeZepeal (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kZepealBits, const bool strict=true)
 Decode the supplied Zepeal message. Status: STABLE / Works on real device. More...
 
+ + + + + + + + + +

+Private Attributes

irparams_tirparams_save
 
uint8_t _tolerance
 
uint8_t _timer_num
 
uint16_t _unknown_threshold
 
+

Detailed Description

+

Class for receiving IR messages.

+

Constructor & Destructor Documentation

+ +

◆ IRrecv() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IRrecv::IRrecv (const uint16_t recvpin,
const uint16_t bufsize = kRawBuf,
const uint8_t timeout = kTimeoutMs,
const bool save_buffer = false,
const uint8_t timer_num = kDefaultESP32Timer 
)
+
+explicit
+
+ +

Class constructor Args:

+
Parameters
+ + + + + + +
[in]recvpinThe GPIO pin the IR receiver module's data pin is connected to.
[in]bufsizeNr. of entries to have in the capture buffer. (Default: kRawBuf)
[in]timeoutNr. of milli-Seconds of no signal before we stop capturing data. (Default: kTimeoutMs)
[in]save_bufferUse a second (save) buffer to decode from. (Default: false)
[in]timer_numNr. of the ESP32 timer to use (0 to 3) (ESP32 Only)
+
+
+ +
+
+ +

◆ IRrecv() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IRrecv::IRrecv (const uint16_t recvpin,
const uint16_t bufsize = kRawBuf,
const uint8_t timeout = kTimeoutMs,
const bool save_buffer = false 
)
+
+explicit
+
+ +
+
+ +

◆ ~IRrecv()

+ +
+
+ + + + + + + + +
IRrecv::~IRrecv (void )
+
+ +

Class destructor Cleans up after the object is no longer needed. e.g. Frees up all memory used by the various buffers, and disables any timers or interrupts used.

+ +
+
+

Member Function Documentation

+ +

◆ _matchGeneric()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::_matchGeneric (volatile uint16_t * data_ptr,
uint64_t * result_bits_ptr,
uint8_t * result_bytes_ptr,
const bool use_bits,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode a generic/typical IR message. The data is stored in result_bits_ptr or result_bytes_ptr depending on flag use_bits.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + + + + + + + + + + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[out]result_bits_ptrA pointer to where to start storing the bits we decoded.
[out]result_bytes_ptrA pointer to where to start storing the bytes we decoded.
[in]use_bitsA flag indicating if we are to decode bits or bytes.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+ +
+
+ +

◆ _validTolerance()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRrecv::_validTolerance (const uint8_t percentage)
+
+private
+
+ +

Convert the tolerance percentage into something valid.

+
Parameters
+ + +
[in]percentageAn integer percentage.
+
+
+ +
+
+ +

◆ compare()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::compare (const uint16_t oldval,
const uint16_t newval 
)
+
+private
+
+ +

Compare two tick values.

+
Parameters
+ + + +
[in]oldvalNr. of ticks.
[in]newvalNr. of ticks.
+
+
+
Returns
0 if newval is shorter, 1 if it is equal, & 2 if it is longer.
+
Note
Use a tolerance of 20%
+ +
+
+ +

◆ copyIrParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRrecv::copyIrParams (volatile irparams_tsrc,
irparams_tdst 
)
+
+private
+
+ +

Make a copy of the interrupt state & buffer data. Needed because irparams is marked as volatile, thus memcpy() isn't allowed. Only call this when you know the interrupt handlers won't modify anything. i.e. In kStopState.

+
Parameters
+ + + +
[in]srcPointer to an irparams_t structure to copy from.
[out]dstPointer to an irparams_t structure to copy to.
+
+
+ +
+
+ +

◆ crudeNoiseFilter()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRrecv::crudeNoiseFilter (decode_resultsresults,
const uint16_t floor = 0 
)
+
+private
+
+ +

Remove or merge pulses in the capture buffer that are too short.

+
Parameters
+ + + +
[in,out]resultsPtr to the decode_results we are going to filter.
[in]floorOnly allow values in the buffer large than this. (in microSeconds)
+
+
+ +
+
+ +

◆ decode()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decode (decode_resultsresults,
irparams_tsave = NULL,
uint8_t max_skip = 0,
uint16_t noise_floor = 0 
)
+
+ +

Decodes the received IR message. If the interrupt state is saved, we will immediately resume waiting for the next IR message to avoid missing messages.

+
Note
There is a trade-off here. Saving the state means less time lost until we can receiving the next message vs. using more RAM. Choose appropriately.
+
Parameters
+ + + + +
[out]resultsA PTR to where the decoded IR message will be stored.
[out]saveA PTR to an irparams_t instance in which to save the interrupt's memory/state. NULL means don't save it.
[in]max_skipMaximum Nr. of pulses at the begining of a capture we can skip when attempting to find a protocol we can successfully decode. This parameter can dramatically improve detection of protocols when there is light IR interference just before an incoming IR message, however, it comes at a steep performace price. (Default is 0. No skipping.)
+
+
+
Warning
Increasing the max_skip value will dramatically (linearly) increase the cpu time & usage to decode protocols. e.g. 0 -> 1 will be a 2x increase in cpu usage/time. 0 -> 2 will be a 3x increase etc. If you are going to do this, consider disabling protocol decoding for protocols you are not expecting.
+
Parameters
+ + +
[in]noise_floorPulses below this size (in usecs) will be removed or merged prior to any decoding. This is to try to remove noise/poor readings & slighly increase the chances of a successful decode but at the cost of data fidelity & integrity. (Defaults to 0 usecs. i.e. Don't filter; which is safe!)
+
+
+
Warning
DANGER: Here Be Dragons! If you set the noise_floor value too high, it WILL break decoding of some protocols. You have been warned! Any non-zero value has the potential to cook the captured raw data i.e. The raw data is going to lie to you. It may obscure hardware, circuit, & environment issues thus making it impossible to support you accurately or confidently. Values of <= 50 usecs will probably be safe. 51 - 100 usecs might be okay. 100 - 150 usecs is "Danger, Will Robinson!". 150 - 200 usecs expect broken protocols. At 200+ usecs, you have protocols you can't decode!!
+
Returns
A boolean indicating if an IR message is ready or not.
+ +
+
+ +

◆ decodeAirwell()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeAirwell (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kAirwellBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Airwell "Manchester code" message.

+

Status: BETA / Appears to be working.

Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+ +
+
+ +

◆ decodeAiwaRCT501()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeAiwaRCT501 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kAiwaRcT501Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Aiwa RC T501 message. Status: BETA / Should work.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
Aiwa RC T501 appears to be a 42 bit variant of the NEC1 protocol. However, we historically (original Arduino IRremote project) treats it as a 15 bit (data) protocol. So, we expect nbits to typically be 15, and we will remove the prefix and postfix from the raw data, and use that as the result.
+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+ +
+
+ +

◆ decodeAmcor()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeAmcor (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kAmcorBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Amcor HVAC message. Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeArgo()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeArgo (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kArgoBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Argo message. Status: BETA / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
This decoder is based soley off sendArgo(). We have no actual captures to test this against. If you have one of these units, please let us know.
+ +
+
+ +

◆ decodeCarrierAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCarrierAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCarrierAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Carrier HVAC message.

+
Note
Carrier HVAC messages contain only 32 bits, but it is sent three(3) times. i.e. normal + inverted + normal Status: BETA / Probably works.
+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeCarrierAC40()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCarrierAC40 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCarrierAc40Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Carrier 40-bit HVAC message. Carrier HVAC messages contain only 40 bits, but it is sent three(3) times. Status: STABLE / Tested against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeCarrierAC64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCarrierAC64 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCarrierAc64Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Carrier 64-bit HVAC message. Status: STABLE / Known to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeCOOLIX()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCOOLIX (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCoolixBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Coolix A/C message. Status: STABLE / Known Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeCoronaAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCoronaAc (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCoronaAcBitsShort,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied CoronaAc message. Status: STABLE / Appears to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store it
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeDaikin()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikinBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 280-bit message. (DAIKIN) Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
+ +
+
+ +

◆ decodeDaikin128()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin128 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin128Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 128-bit message. (DAIKIN128) Status: STABLE / Known Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/827
+ +
+
+ +

◆ decodeDaikin152()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin152 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin152Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 152-bit message. (DAIKIN152) Status: STABLE / Known Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/873
+ +
+
+ +

◆ decodeDaikin160()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin160 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin160Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 160-bit message. (DAIKIN160) Status: STABLE / Confirmed working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/731
+ +
+
+ +

◆ decodeDaikin176()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin176 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin176Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 176-bit message. (DAIKIN176) Status: STABLE / Expected to work.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeDaikin2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin2 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin2Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 312-bit message. (DAIKIN2) Status: STABLE / Works as expected.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeDaikin216()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin216 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin216Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 216-bit message. (DAIKIN216) Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/689
+
+https://github.com/danny-source/Arduino_DY_IRDaikin
+ +
+
+ +

◆ decodeDaikin64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin64 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin64Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 64-bit message. (DAIKIN64) Status: Beta / Probably Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1064
+ +
+
+ +

◆ decodeDelonghiAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDelonghiAc (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDelonghiAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Delonghi A/C message. Status: STABLE / Expected to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1096
+ +
+
+ +

◆ decodeDenon()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDenon (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDenonBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Delonghi A/C message. Status: STABLE / Should work fine.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp
+ +
+
+ +

◆ decodeDISH()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDISH (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDishBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied DISH NETWORK message. Status: ALPHA (untested and unconfirmed.)

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
Dishplayer is a different protocol. Typically a DISH device needs to get a command a total of at least 4 times to accept it.
+
See also
http://www.hifi-remote.com/wiki/index.php?title=Dish
+
+http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx
+
+https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp
+ +
+
+ +

◆ decodeDoshisha()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDoshisha (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDoshishaBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Doshisha message. Status: STABLE / Works on real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeElectraAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeElectraAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kElectraAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Electra A/C message. Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeEpson()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeEpson (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kEpsonBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Epson message. Status: Beta / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
Experimental data indicates there are at least three messages (first + 2 repeats). We only require the first + a single repeat to match. This helps us distinguish it from NEC messages which are near identical.
+ +
+
+ +

◆ decodeFujitsuAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeFujitsuAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kFujitsuAcBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied Fujitsu AC IR message if possible. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeGICable()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeGICable (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kGicableBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied G.I. Cable message. Status: Alpha / Not tested against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeGoodweather()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeGoodweather (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kGoodweatherBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Goodweather message. Status: BETA / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeGree()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeGree (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kGreeBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Gree HVAC message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeHaierAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHaierAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHaierACBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Haier HSU07-HEA03 remote message. Status: STABLE / Known to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeHaierACYRW02()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHaierACYRW02 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHaierACYRW02Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Haier YR-W02 remote A/C message. Status: BETA / Appears to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeHash()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRrecv::decodeHash (decode_resultsresults)
+
+private
+
+ +

Decode any arbitrary IR message into a 32-bit code value. Instead of decoding using a standard encoding scheme (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.

+

The algorithm: look at the sequence of MARK signals, and see if each one is shorter (0), the same length (1), or longer (2) than the previous. Do the same with the SPACE signals. Hash the resulting sequence of 0's, 1's, and 2's to a 32-bit value. This will give a unique value for each different code (probably), for most code systems.

See also
http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
+
Note
This isn't a "real" decoding, just an arbitrary value. Hopefully this code is unique for each button.
+ +
+
+ +

◆ decodeHitachiAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHitachiAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAcBits,
const bool strict = true,
const bool MSBfirst = true 
)
+
+private
+
+ +

Decode the supplied Hitachi A/C message. Status: STABLE / Expected to work.

+
Parameters
+ + + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, kHitachiAc344Bits
[in]strictFlag indicating if we should perform strict matching.
[in]MSBfirstIs the data per byte stored in MSB First (true) or LSB First order(false)?
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/417
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/453
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/1134
+ +
+
+ +

◆ decodeHitachiAC1()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHitachiAC1 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc1Bits,
const bool strict = true 
)
+
+private
+
+ +
+
+ +

◆ decodeHitachiAc3()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHitachiAc3 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc3Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Hitachi 15to27-byte/120to216-bit A/C message. Status: STABLE / Works fine.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol is almost exactly the same as HitachiAC424 except this variant has subtle timing differences and multiple lengths. There are five(5) typical lengths: kHitachiAc3MinStateLength (Cancel Timer), kHitachiAc3MinStateLength + 2 (Change Temp), kHitachiAc3StateLength - 6 (Change Mode), kHitachiAc3StateLength - 4 (Normal), & kHitachiAc3StateLength (Set Timer)
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1060
+ +
+
+ +

◆ decodeHitachiAc424()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHitachiAc424 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc424Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Hitachi 53-byte/424-bit A/C message. Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol is almost exactly the same as HitachiAC2 except this variant has a leader section as well, and subtle timing differences. It is also in LSBF order (per byte), rather than MSBF order.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/973
+
+(Japanese Manual) https://kadenfan.hitachi.co.jp/support/raj/item/docs/ras_aj22h_a_tori.pdf
+ +
+
+ +

◆ decodeInax()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeInax (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kInaxBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Inax Toilet message. Status: Stable / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/706
+ +
+
+ +

◆ decodeJVC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeJVC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kJvcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied JVC message. Status: Stable / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
JVC repeat codes don't have a header.
+
See also
http://www.sbprojects.com/knowledge/ir/jvc.php
+ +
+
+ +

◆ decodeKelvinator()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeKelvinator (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kKelvinatorBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Kelvinator message. Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeLasertag()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeLasertag (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kLasertagBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Lasertag message. Status: BETA / Appears to be working 90% of the time.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol is pretty much just raw Manchester encoding.
+
See also
http://www.sbprojects.com/knowledge/ir/rc5.php
+
+https://en.wikipedia.org/wiki/RC-5
+
+https://en.wikipedia.org/wiki/Manchester_code
+
Todo:
Convert to using matchManchester() if we can.
+ +
+
+ +

◆ decodeLegoPf()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeLegoPf (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kLegoPfBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied LEGO Power Functions message. Status: STABLE / Appears to work.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeLG()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeLG (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kLgBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied LG message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kLgBits or kLg32Bits.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
LG protocol has a repeat code which is 4 items long. Even though the protocol has 28/32 bits of data, only 24/28 bits are distinct. In transmission order, the 28/32 bits are constructed as follows: 8/12 bits of address + 16 bits of command + 4 bits of checksum.
+
+LG 32bit protocol appears near identical to the Samsung protocol. They possibly differ on how they repeat and initial HDR mark.
+
See also
https://funembedded.wordpress.com/2014/11/08/ir-remote-control-for-lg-conditioner-using-stm32f302-mcu-on-mbed-platform/
+ +
+
+ +

◆ decodeLutron()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeLutron (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kLutronBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Lutron message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeMagiQuest()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMagiQuest (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMagiquestBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied MagiQuest message. Status: Beta / Should work.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
MagiQuest protocol appears to be a header of 8 'zero' bits, followed by 32 bits of "wand ID" and finally 16 bits of "magnitude". Even though we describe this protocol as 56 bits, it really only has 48 bits of data that matter. In transmission order, 8 zeros + 32 wand_id + 16 magnitude.
+
See also
https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp
+ +
+
+ +

◆ decodeMidea()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMidea (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMideaBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Midea message. Status: Alpha / Needs testing against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, kHitachiAc344Bits
[in]strictFlag indicating if we should perform strict matching.
+
+
+ +
+
+ +

◆ decodeMidea24()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMidea24 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMidea24Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Midea24 message. Status: STABLE / Confirmed working on a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
This protocol is basically a 48-bit version of the NEC protocol with alternate bytes inverted, thus only 24 bits of real data.
+
Warning
Can't be used beyond 32 bits.
+ +
+
+ +

◆ decodeMitsubishi()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishi (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Mitsubishi 16-bit message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol appears to have no header.
+
See also
GlobalCache's Control Tower's Mitsubishi TV data.
+ +
+
+ +

◆ decodeMitsubishi112()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishi112 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishi112Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Mitsubishi/TCL 112-bit A/C message. (MITSUBISHI112, TCL112AC) Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Note
Note Mitsubishi112 & Tcl112Ac are basically the same protocol. The only significant difference I can see is Mitsubishi112 has a slightly longer header mark. We will use that to determine which variant it should be. The other differences require full decoding and only only with certain settings. There are some other timing differences too, but the tolerances will overlap.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/619
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/947
+ +
+
+ +

◆ decodeMitsubishi136()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishi136 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishi136Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/888
+ +
+
+ +

◆ decodeMitsubishi2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishi2 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied second variation of a Mitsubishi 16-bit message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/441
+ +
+
+ +

◆ decodeMitsubishiAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishiAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiACBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied Mitsubish 144-bit A/C message. Status: BETA / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
See also
https://www.analysir.com/blog/2015/01/06/reverse-engineering-mitsubishi-ac-infrared-protocol/
+ +
+
+ +

◆ decodeMitsubishiHeavy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishiHeavy (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiHeavy152Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Mitsubishi Heavy Industries A/C message. Status: BETA / Appears to be working. Needs testing against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kMitsubishiHeavy88Bits or kMitsubishiHeavy152Bits (def).
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeMultibrackets()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMultibrackets (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMultibracketsBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the Multibrackets message. Status: BETA / Appears to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeMWM()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMWM (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = 24,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied MWM message. Status: Implemented.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol is 2400 bps serial, 1 start bit (mark), 1 stop bit (space), no parity
+ +
+
+ +

◆ decodeNEC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeNEC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kNECBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied NEC (Renesas) message. Status: STABLE / Known good.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
NEC protocol has three variants/forms. Normal: an 8 bit address & an 8 bit command in 32 bit data form. i.e. address + inverted(address) + command + inverted(command) Extended: a 16 bit address & an 8 bit command in 32 bit data form. i.e. address + command + inverted(command) Repeat: a 0-bit code. i.e. No data bits. Just the header + footer.
+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+ +
+
+ +

◆ decodeNeoclima()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeNeoclima (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kNeoclimaBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Neoclima message. Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeNikai()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeNikai (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kNikaiBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Nikai message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+ +
+
+ +

◆ decodePanasonic()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodePanasonic (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kPanasonicBits,
const bool strict = false,
const uint32_t manufacturer = kPanasonicManufacturer 
)
+
+private
+
+ +

Decode the supplied Panasonic message. Status: STABLE / Should be working.

+
Parameters
+ + + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]manufacturerA 16-bit manufacturer code. e.g. 0x4004 is Panasonic
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Warning
Results to be used with sendPanasonic64(), not sendPanasonic().
+
Note
Panasonic 48-bit protocol is a modified version of Kaseikyo.
+
See also
http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615
+
+http://www.hifi-remote.com/wiki/index.php?title=Panasonic
+ +
+
+ +

◆ decodePanasonicAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodePanasonicAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kPanasonicAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Panasonic AC message. Status: STABLE / Works with real device(s).

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodePioneer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodePioneer (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kPioneerBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Pioneer message. Status: STABLE / Should be working. (Self decodes & real examples)

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeRC5()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeRC5 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kRC5XBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied RC-5/RC5X message. Status: RC-5 (stable), RC-5X (alpha)

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
The 'toggle' bit is included as the 6th (MSB) address bit, the MSB of data, & in the count of bits decoded.
+
Todo:
Serious testing of the RC-5X and strict aspects needs to be done.
+ +
+
+ +

◆ decodeRC6()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeRC6 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kRC6Mode0Bits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied RC6 message. Status: Stable.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Todo:
Testing of the strict compliance aspects.
+ +
+
+ +

◆ decodeRCMM()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeRCMM (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kRCMMBits,
const bool strict = false 
)
+
+private
+
+ +

Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeSAMSUNG()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSAMSUNG (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSamsungBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Samsung 32-bit message. Status: STABLE.

+
Note
Samsung messages whilst 32 bits in size, only contain 16 bits of distinct data. e.g. In transmition order: customer_byte + customer_byte(same) + address_byte + invert(address_byte)
+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
LG 32bit protocol appears near identical to the Samsung protocol. They differ on their compliance criteria and how they repeat.
+
See also
http://elektrolab.wz.cz/katalog/samsung_protocol.pdf
+ +
+
+ +

◆ decodeSamsung36()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSamsung36 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSamsung36Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Samsung36 message. Status: Alpha / Experimental.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/621
+ +
+
+ +

◆ decodeSamsungAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSamsungAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSamsungAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Samsung A/C message. Status: Stable / Known to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/505
+ +
+
+ +

◆ decodeSanyoLC7461()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSanyoLC7461 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSanyoLC7461Bits,
bool strict = true 
)
+
+private
+
+ +

Decode the supplied SANYO LC7461 message. Status: BETA / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
Based on @marcosamarinho's work. This protocol uses the NEC protocol. However, data is formatted as : address(13 bits), !address, command (8 bits), !command. According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon Information for this protocol is available at the Sanyo LC7461 datasheet.
+
See also
http://slydiman.narod.ru/scr/kb/sanyo.htm
+
+https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp
+
+http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf
+ +
+
+ +

◆ decodeSharp()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSharp (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSharpBits,
const bool strict = true,
const bool expansion = true 
)
+
+private
+
+ +

Decode the supplied Sharp message. Status: STABLE / Working fine.

+
Parameters
+ + + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
[in]expansionShould we expect the expansion bit to be set. Default is true.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This procedure returns a value suitable for use in sendSharpRaw().
+
Todo:
Need to ensure capture of the inverted message as it can be missed due to the interrupt timeout used to detect an end of message. Several compliance checks are disabled until that is resolved.
+ +
+
+ +

◆ decodeSharpAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSharpAc (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSharpAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Sharp A/C message. Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/638
+
+https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp
+ +
+
+ +

◆ decodeSony()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSony (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSonyMinBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied Sony/SIRC message. Status: STABLE / Should be working. strict mode is ALPHA / Untested.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
SONY protocol, SIRC (Serial Infra-Red Control) can be 12, 15, or 20 bits long.
+ +
+
+ +

◆ decodeSymphony()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSymphony (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSymphonyBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Symphony packet/message. Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeTeco()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeTeco (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kTecoBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied Teco message. Status: STABLE / Tested.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeToshibaAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeToshibaAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kToshibaACBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Toshiba A/C message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeTrotec()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeTrotec (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kTrotecBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Trotec message. Status: STABLE / Works. Untested on real devices.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeVestelAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeVestelAc (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kVestelAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Vestel message. Status: Alpha / Needs testing against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeWhirlpoolAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeWhirlpoolAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kWhirlpoolAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Whirlpool A/C message. Status: STABLE / Working as intended.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeWhynter()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeWhynter (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kWhynterBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Whynter message. Status: STABLE / Working. Strict mode is ALPHA.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp
+ +
+
+ +

◆ decodeZepeal()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeZepeal (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kZepealBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Zepeal message. Status: STABLE / Works on real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kZepealBits.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ disableIRIn()

+ +
+
+ + + + + + + + +
void IRrecv::disableIRIn (void )
+
+ +

Stop collection of any received IR data. Disable any timers and interrupts.

+ +
+
+ +

◆ enableIRIn()

+ +
+
+ + + + + + + + +
void IRrecv::enableIRIn (const bool pullup = false)
+
+ +

Set up and (re)start the IR capture mechanism.

+
Parameters
+ + +
[in]pullupA flag indicating should the GPIO use the internal pullup resistor. (Default: false. i.e. No.)
+
+
+ +
+
+ +

◆ getBufSize()

+ +
+
+ + + + + + + + +
uint16_t IRrecv::getBufSize (void )
+
+ +

Obtain the maximum number of entries possible in the capture buffer. i.e. It's size.

+
Returns
The size of the buffer that is in use by the object.
+ +
+
+ +

◆ getRClevel()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int16_t IRrecv::getRClevel (decode_resultsresults,
uint16_t * offset,
uint16_t * used,
uint16_t bitTime,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const uint16_t delta = 0,
const uint8_t maxwidth = 3 
)
+
+private
+
+ +

Gets one undecoded level at a time from the raw buffer. The RC5/6 decoding is easier if the data is broken into time intervals. E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, successive calls to getRClevel will return MARK, MARK, SPACE. offset and used are updated to keep track of the current position.

+
Parameters
+ + + + + + + + + +
[in,out]resultsPtr to the data to decode and where to store the decode result.
[in,out]offsetPtr to the currect offset to the rawbuf.
[in,out]usedPtr to the current used counter.
[in]bitTimeTime interval of single bit in microseconds.
[in]tolerancePercent tolerance to be used in matching.
[in]excessExtra useconds to add to Marks & removed from Spaces.
[in]deltaA non-scaling (+/-) error margin (in useconds).
[in]maxwidthMaximum number of successive levels to find in a single level (default is 3)
+
+
+
Returns
MARK, SPACE, or -1 for error. (The measured time interval is not a multiple of t1.)
+
See also
https://en.wikipedia.org/wiki/Manchester_code
+ +
+
+ +

◆ getTolerance()

+ +
+
+ + + + + + + + +
uint8_t IRrecv::getTolerance (void )
+
+ +

Get the base tolerance percentage for matching incoming IR messages.

+
Returns
A integer percentage.
+ +
+
+ +

◆ match()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::match (const uint32_t measured,
const uint32_t desired,
const uint8_t tolerance = kUseDefTol,
const uint16_t delta = 0 
)
+
+ +

Check if we match a pulse(measured) with the desired within +/-tolerance percent and/or +/- a fixed delta range.

+
Parameters
+ + + + + +
[in]measuredThe recorded period of the signal pulse.
[in]desiredThe expected period (in usecs) we are matching against.
[in]toleranceA percentage expressed as an integer. e.g. 10 is 10%.
[in]deltaA non-scaling (+/-) error margin (in useconds).
+
+
+
Returns
A Boolean. true if it matches, false if it doesn't.
+ +
+
+ +

◆ matchAtLeast()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::matchAtLeast (const uint32_t measured,
const uint32_t desired,
const uint8_t tolerance = kUseDefTol,
const uint16_t delta = 0 
)
+
+private
+
+ +

Check if we match a pulse(measured) of at least desired within tolerance percent and/or a fixed delta margin.

+
Parameters
+ + + + + +
[in]measuredThe recorded period of the signal pulse.
[in]desiredThe expected period (in usecs) we are matching against.
[in]toleranceA percentage expressed as an integer. e.g. 10 is 10%.
[in]deltaA non-scaling amount to reduce usecs by.
+
+
+
Returns
A Boolean. true if it matches, false if it doesn't.
+ +
+
+ +

◆ matchBytes()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchBytes (volatile uint16_t * data_ptr,
uint8_t * result_ptr,
const uint16_t remaining,
const uint16_t nbytes,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode the typical data section of an IR message. The bytes are stored at result_ptr. The first byte in the result equates to the first byte encountered, and so on.

+
Parameters
+ + + + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[out]result_ptrA ptr to where to start storing the bytes we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbytesNr. of data bytes we expect.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+ +
+
+ +

◆ matchData()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
match_result_t IRrecv::matchData (volatile uint16_t * data_ptr,
const uint16_t nbits,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode the typical data section of an IR message. The data value is stored in the least significant bits reguardless of the bit ordering requested.

+
Parameters
+ + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[in]nbitsNr. of data bits we expect.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
A match_result_t structure containing the success (or not), the data value, and how many buffer entries were used.
+ +
+
+ +

◆ matchGeneric() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchGeneric (volatile uint16_t * data_ptr,
uint64_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode a generic/typical <= 64bit IR message. The data is stored at result_ptr.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + + + + + + + + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[out]result_ptrA ptr to where to start storing the bits we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+ +
+
+ +

◆ matchGeneric() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchGeneric (volatile uint16_t * data_ptr,
uint8_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode a generic/typical > 64bit IR message. The bytes are stored at result_ptr. The first byte in the result equates to the first byte encountered, and so on.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + + + + + + + + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[out]result_ptrA ptr to where to start storing the bytes we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+ +
+
+ +

◆ matchGenericConstBitTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchGenericConstBitTime (volatile uint16_t * data_ptr,
uint64_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t one,
const uint32_t zero,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode a generic/typical constant bit time <= 64bit IR message. The data is stored at result_ptr.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + +
[in]data_ptrA pointer to where we are at in the capture buffer.
+
+
+
Note
data_ptr is assumed to be pointing to a "Mark", not a "Space".
+
Parameters
+ + + + + + + + + + + + + + +
[out]result_ptrA ptr to where to start storing the bits we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]oneNr. of uSeconds in an expected mark signal for a '1' bit.
[in]zeroNr. of uSeconds in an expected mark signal for a '0' bit.
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+
Note
Parameters one + zero add up to the total time for a bit. e.g. mark(one) + space(zero) is a 1, mark(zero) + space(one) is a 0.
+ +
+
+ +

◆ matchManchester()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchManchester (volatile const uint16_t * data_ptr,
uint64_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t half_period,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true,
const bool GEThomas = true 
)
+
+private
+
+ +

Match & decode a Manchester Code <= 64bit IR message. The data is stored at result_ptr.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + +
[in]data_ptrA pointer to where we are at in the capture buffer.
+
+
+
Note
data_ptr is assumed to be pointing to a "Mark", not a "Space".
+
Parameters
+ + + + + + + + + + + + + + +
[out]result_ptrA ptr to where to start storing the bits we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]half_periodNr. of uSeconds for half the clock's period. i.e. 1/2 wavelength
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
[in]GEThomasUse G.E. Thomas (true) or IEEE 802.3 (false) convention?
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+
See also
https://en.wikipedia.org/wiki/Manchester_code
+
+http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf
+ +
+
+ +

◆ matchManchesterData()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchManchesterData (volatile const uint16_t * data_ptr,
uint64_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t half_period,
const uint16_t starting_balance = 0,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true,
const bool GEThomas = true 
)
+
+private
+
+ +

Match & decode a Manchester Code data (<= 64bits.

+
Parameters
+ + +
[in]data_ptrA pointer to where we are at in the capture buffer.
+
+
+
Note
data_ptr is assumed to be pointing to a "Mark", not a "Space".
+
Parameters
+ + + + + + + + + + +
[out]result_ptrA ptr to where to start storing the bits we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]half_periodNr. of uSeconds for half the clock's period. i.e. 1/2 wavelength
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]starting_balanceAmount of uSeconds to assume exists prior to the current value pointed too.
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
[in]GEThomasUse G.E. Thomas (true) or IEEE 802.3 (false) convention?
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+
See also
https://en.wikipedia.org/wiki/Manchester_code
+
+http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf
+
Todo:
Clean up and optimise this. It is just "get it working code" atm.
+ +
+
+ +

◆ matchMark()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::matchMark (const uint32_t measured,
const uint32_t desired,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess 
)
+
+ +

Check if we match a mark signal(measured) with the desired within +/-tolerance percent, after an expected is excess is added.

+
Parameters
+ + + + + +
[in]measuredThe recorded period of the signal pulse.
[in]desiredThe expected period (in usecs) we are matching against.
[in]toleranceA percentage expressed as an integer. e.g. 10 is 10%.
[in]excessA non-scaling amount to reduce usecs by.
+
+
+
Returns
A Boolean. true if it matches, false if it doesn't.
+ +
+
+ +

◆ matchSpace()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::matchSpace (const uint32_t measured,
const uint32_t desired,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess 
)
+
+ +

Check if we match a space signal(measured) with the desired within +/-tolerance percent, after an expected is excess is removed.

+
Parameters
+ + + + + +
[in]measuredThe recorded period of the signal pulse.
[in]desiredThe expected period (in usecs) we are matching against.
[in]toleranceA percentage expressed as an integer. e.g. 10 is 10%.
[in]excessA non-scaling amount to reduce usecs by.
+
+
+
Returns
A Boolean. true if it matches, false if it doesn't.
+ +
+
+ +

◆ resume()

+ +
+
+ + + + + + + + +
void IRrecv::resume (void )
+
+ +

Resume collection of received IR data.

+
Note
This is required if decode() is successful and save_buffer was not set when the class was instanciated.
+
See also
IRrecv class constructor
+ +
+
+ +

◆ setTolerance()

+ +
+
+ + + + + + + + +
void IRrecv::setTolerance (const uint8_t percent = kTolerance)
+
+ +

Set the base tolerance percentage for matching incoming IR messages.

+
Parameters
+ + +
[in]percentAn integer percentage. (0-100)
+
+
+ +
+
+ +

◆ setUnknownThreshold()

+ +
+
+ + + + + + + + +
void IRrecv::setUnknownThreshold (const uint16_t length)
+
+ +

Set the minimum length we will consider for reporting UNKNOWN message types.

+
Parameters
+ + +
[in]lengthMin nr. of mark/space pulses required to be considered.
+
+
+ +
+
+ +

◆ ticksHigh()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint32_t IRrecv::ticksHigh (const uint32_t usecs,
const uint8_t tolerance = kUseDefTol,
const uint16_t delta = 0 
)
+
+private
+
+ +

Calculate the upper bound of the nr. of ticks.

+
Parameters
+ + + + +
[in]usecsNr. of uSeconds.
[in]tolerancePercent as an integer. e.g. 10 is 10%
[in]deltaA non-scaling amount to increase usecs by.
+
+
+
Returns
Nr. of ticks.
+ +
+
+ +

◆ ticksLow()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint32_t IRrecv::ticksLow (const uint32_t usecs,
const uint8_t tolerance = kUseDefTol,
const uint16_t delta = 0 
)
+
+private
+
+ +

Calculate the lower bound of the nr. of ticks.

+
Parameters
+ + + + +
[in]usecsNr. of uSeconds.
[in]tolerancePercent as an integer. e.g. 10 is 10%
[in]deltaA non-scaling amount to reduce usecs by.
+
+
+
Returns
Nr. of ticks.
+ +
+
+

Member Data Documentation

+ +

◆ _timer_num

+ +
+
+ + + + + +
+ + + + +
uint8_t IRrecv::_timer_num
+
+private
+
+ +
+
+ +

◆ _tolerance

+ +
+
+ + + + + +
+ + + + +
uint8_t IRrecv::_tolerance
+
+private
+
+ +
+
+ +

◆ _unknown_threshold

+ +
+
+ + + + + +
+ + + + +
uint16_t IRrecv::_unknown_threshold
+
+private
+
+ +
+
+ +

◆ irparams_save

+ +
+
+ + + + + +
+ + + + +
irparams_t* IRrecv::irparams_save
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.map new file mode 100644 index 000000000..afb28be42 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.md5 new file mode 100644 index 000000000..03ea8f4ee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.md5 @@ -0,0 +1 @@ +86a4a18f846668b6a3cf862d7669306a \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.png new file mode 100644 index 0000000000000000000000000000000000000000..69ea6e16f851a9224320aa46dad26e7c44cc5948 GIT binary patch literal 3293 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 M8d(^Y=sU;!1BWM6qW}N^ literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend-members.html new file mode 100644 index 000000000..af01c2961 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend-members.html @@ -0,0 +1,213 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRsend Member List
+
+
+ +

This is the complete list of members for IRsend, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_delayMicroseconds(uint32_t usec)IRsend
_dutycycleIRsendprivate
_freq_unittestIRsendprivate
_sendSony(const uint64_t data, const uint16_t nbits, const uint16_t repeat, const uint16_t freq)IRsendprivate
begin()IRsend
calcUSecPeriod(uint32_t hz, bool use_offset=true)IRsendprivate
calibrate(uint16_t hz=38000U)IRsend
defaultBits(const decode_type_t protocol)IRsendstatic
enableIROut(uint32_t freq, uint8_t duty=kDutyDefault)IRsend
encodeDoshisha(const uint8_t command, const uint8_t channel=0)IRsend
encodeJVC(uint8_t address, uint8_t command)IRsend
encodeLG(uint16_t address, uint16_t command)IRsend
encodeMagiQuest(const uint32_t wand_id, const uint16_t magnitude)IRsend
encodeNEC(uint16_t address, uint16_t command)IRsend
encodePanasonic(const uint16_t manufacturer, const uint8_t device, const uint8_t subdevice, const uint8_t function)IRsend
encodePioneer(uint16_t address, uint16_t command)IRsend
encodeRC5(const uint8_t address, const uint8_t command, const bool key_released=false)IRsend
encodeRC5X(const uint8_t address, const uint8_t command, const bool key_released=false)IRsend
encodeRC6(const uint32_t address, const uint8_t command, const uint16_t mode=kRC6Mode0Bits)IRsend
encodeSAMSUNG(const uint8_t customer, const uint8_t command)IRsend
encodeSanyoLC7461(uint16_t address, uint8_t command)IRsend
encodeSharp(const uint16_t address, const uint16_t command, const uint16_t expansion=1, const uint16_t check=0, const bool MSBfirst=false)IRsend
encodeSony(const uint16_t nbits, const uint16_t command, const uint16_t address, const uint16_t extended=0)IRsend
IRpinIRsendprivate
IRsend(uint16_t IRsendPin, bool inverted=false, bool use_modulation=true)IRsendexplicit
ledOff()IRsendprotected
ledOn()IRsendprotected
mark(uint16_t usec)IRsend
minRepeats(const decode_type_t protocol)IRsendstatic
modulationIRsendprivate
offTimePeriodIRsendprivate
onTimePeriodIRsendprivate
outputOffIRsendprotected
outputOnIRsendprotected
periodOffsetIRsendprivate
send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)IRsend
send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes)IRsend
sendAirwell(uint64_t data, uint16_t nbits=kAirwellBits, uint16_t repeat=kAirwellMinRepeats)IRsend
sendAiwaRCT501(uint64_t data, uint16_t nbits=kAiwaRcT501Bits, uint16_t repeat=kAiwaRcT501MinRepeats)IRsend
sendAmcor(const unsigned char data[], const uint16_t nbytes=kAmcorStateLength, const uint16_t repeat=kAmcorDefaultRepeat)IRsend
sendArgo(const unsigned char data[], const uint16_t nbytes=kArgoStateLength, const uint16_t repeat=kArgoDefaultRepeat)IRsend
sendCarrierAC(uint64_t data, uint16_t nbits=kCarrierAcBits, uint16_t repeat=kCarrierAcMinRepeat)IRsend
sendCarrierAC40(uint64_t data, uint16_t nbits=kCarrierAc40Bits, uint16_t repeat=kCarrierAc40MinRepeat)IRsend
sendCarrierAC64(uint64_t data, uint16_t nbits=kCarrierAc64Bits, uint16_t repeat=kCarrierAc64MinRepeat)IRsend
sendCOOLIX(uint64_t data, uint16_t nbits=kCoolixBits, uint16_t repeat=kCoolixDefaultRepeat)IRsend
sendCoronaAc(const uint8_t data[], const uint16_t nbytes=kCoronaAcStateLength, const uint16_t repeat=kNoRepeat)IRsend
sendDaikin(const unsigned char data[], const uint16_t nbytes=kDaikinStateLength, const uint16_t repeat=kDaikinDefaultRepeat)IRsend
sendDaikin128(const unsigned char data[], const uint16_t nbytes=kDaikin128StateLength, const uint16_t repeat=kDaikin128DefaultRepeat)IRsend
sendDaikin152(const unsigned char data[], const uint16_t nbytes=kDaikin152StateLength, const uint16_t repeat=kDaikin152DefaultRepeat)IRsend
sendDaikin160(const unsigned char data[], const uint16_t nbytes=kDaikin160StateLength, const uint16_t repeat=kDaikin160DefaultRepeat)IRsend
sendDaikin176(const unsigned char data[], const uint16_t nbytes=kDaikin176StateLength, const uint16_t repeat=kDaikin176DefaultRepeat)IRsend
sendDaikin2(const unsigned char data[], const uint16_t nbytes=kDaikin2StateLength, const uint16_t repeat=kDaikin2DefaultRepeat)IRsend
sendDaikin216(const unsigned char data[], const uint16_t nbytes=kDaikin216StateLength, const uint16_t repeat=kDaikin216DefaultRepeat)IRsend
sendDaikin64(const uint64_t data, const uint16_t nbits=kDaikin64Bits, const uint16_t repeat=kDaikin64DefaultRepeat)IRsend
sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark, uint32_t zerospace, uint64_t data, uint16_t nbits, bool MSBfirst=true)IRsend
sendDelonghiAc(uint64_t data, uint16_t nbits=kDelonghiAcBits, uint16_t repeat=kDelonghiAcDefaultRepeat)IRsend
sendDenon(uint64_t data, uint16_t nbits=kDenonBits, uint16_t repeat=kNoRepeat)IRsend
sendDISH(uint64_t data, uint16_t nbits=kDishBits, uint16_t repeat=kDishMinRepeat)IRsend
sendDoshisha(const uint64_t data, uint16_t nbits=kDoshishaBits, const uint16_t repeat=kNoRepeat)IRsend
sendElectraAC(const unsigned char data[], const uint16_t nbytes=kElectraAcStateLength, const uint16_t repeat=kNoRepeat)IRsend
sendEpson(uint64_t data, uint16_t nbits=kEpsonBits, uint16_t repeat=kEpsonMinRepeat)IRsend
sendFujitsuAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kFujitsuAcMinRepeat)IRsend
sendGC(uint16_t buf[], uint16_t len)IRsend
sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)IRsend
sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint32_t mesgtime, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)IRsend
sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint8_t *dataptr, const uint16_t nbytes, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)IRsend
sendGICable(uint64_t data, uint16_t nbits=kGicableBits, uint16_t repeat=kGicableMinRepeat)IRsend
sendGoodweather(const uint64_t data, const uint16_t nbits=kGoodweatherBits, const uint16_t repeat=kGoodweatherMinRepeat)IRsend
sendGree(const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)IRsend
sendGree(const uint8_t data[], const uint16_t nbytes=kGreeStateLength, const uint16_t repeat=kGreeDefaultRepeat)IRsend
sendHaierAC(const unsigned char data[], const uint16_t nbytes=kHaierACStateLength, const uint16_t repeat=kHaierAcDefaultRepeat)IRsend
sendHaierACYRW02(const unsigned char data[], const uint16_t nbytes=kHaierACYRW02StateLength, const uint16_t repeat=kHaierAcYrw02DefaultRepeat)IRsend
sendHitachiAC(const unsigned char data[], const uint16_t nbytes=kHitachiAcStateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAC1(const unsigned char data[], const uint16_t nbytes=kHitachiAc1StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAC2(const unsigned char data[], const uint16_t nbytes=kHitachiAc2StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAc3(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAc344(const unsigned char data[], const uint16_t nbytes=kHitachiAc344StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAc424(const unsigned char data[], const uint16_t nbytes=kHitachiAc424StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendInax(const uint64_t data, const uint16_t nbits=kInaxBits, const uint16_t repeat=kInaxMinRepeat)IRsend
sendJVC(uint64_t data, uint16_t nbits=kJvcBits, uint16_t repeat=kNoRepeat)IRsend
sendKelvinator(const unsigned char data[], const uint16_t nbytes=kKelvinatorStateLength, const uint16_t repeat=kKelvinatorDefaultRepeat)IRsend
sendLasertag(uint64_t data, uint16_t nbits=kLasertagBits, uint16_t repeat=kLasertagMinRepeat)IRsend
sendLegoPf(const uint64_t data, const uint16_t nbits=kLegoPfBits, const uint16_t repeat=kLegoPfMinRepeat)IRsend
sendLG(uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)IRsend
sendLG2(uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)IRsend
sendLutron(uint64_t data, uint16_t nbits=kLutronBits, uint16_t repeat=kNoRepeat)IRsend
sendMagiQuest(const uint64_t data, const uint16_t nbits=kMagiquestBits, const uint16_t repeat=kNoRepeat)IRsend
sendManchester(const uint16_t headermark, const uint32_t headerspace, const uint16_t half_period, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency=38, const bool MSBfirst=true, const uint16_t repeat=kNoRepeat, const uint8_t dutycycle=kDutyDefault, const bool GEThomas=true)IRsend
sendManchesterData(const uint16_t half_period, const uint64_t data, const uint16_t nbits, const bool MSBfirst=true, const bool GEThomas=true)IRsend
sendMidea(uint64_t data, uint16_t nbits=kMideaBits, uint16_t repeat=kMideaMinRepeat)IRsend
sendMidea24(const uint64_t data, const uint16_t nbits=kMidea24Bits, const uint16_t repeat=kMidea24MinRepeat)IRsend
sendMitsubishi(uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)IRsend
sendMitsubishi112(const unsigned char data[], const uint16_t nbytes=kMitsubishi112StateLength, const uint16_t repeat=kMitsubishi112MinRepeat)IRsend
sendMitsubishi136(const unsigned char data[], const uint16_t nbytes=kMitsubishi136StateLength, const uint16_t repeat=kMitsubishi136MinRepeat)IRsend
sendMitsubishi2(uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)IRsend
sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes=kMitsubishiACStateLength, const uint16_t repeat=kMitsubishiACMinRepeat)IRsend
sendMitsubishiHeavy152(const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy152StateLength, const uint16_t repeat=kMitsubishiHeavy152MinRepeat)IRsend
sendMitsubishiHeavy88(const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy88StateLength, const uint16_t repeat=kMitsubishiHeavy88MinRepeat)IRsend
sendMultibrackets(const uint64_t data, const uint16_t nbits=kMultibracketsBits, const uint16_t repeat=kMultibracketsDefaultRepeat)IRsend
sendMWM(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kNoRepeat)IRsend
sendNEC(uint64_t data, uint16_t nbits=kNECBits, uint16_t repeat=kNoRepeat)IRsend
sendNeoclima(const unsigned char data[], const uint16_t nbytes=kNeoclimaStateLength, const uint16_t repeat=kNeoclimaMinRepeat)IRsend
sendNikai(uint64_t data, uint16_t nbits=kNikaiBits, uint16_t repeat=kNoRepeat)IRsend
sendPanasonic(const uint16_t address, const uint32_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)IRsend
sendPanasonic64(const uint64_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)IRsend
sendPanasonicAC(const unsigned char data[], const uint16_t nbytes=kPanasonicAcStateLength, const uint16_t repeat=kPanasonicAcDefaultRepeat)IRsend
sendPioneer(const uint64_t data, const uint16_t nbits=kPioneerBits, const uint16_t repeat=kNoRepeat)IRsend
sendPronto(uint16_t data[], uint16_t len, uint16_t repeat=kNoRepeat)IRsend
sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz)IRsend
sendRC5(const uint64_t data, uint16_t nbits=kRC5XBits, const uint16_t repeat=kNoRepeat)IRsend
sendRC6(const uint64_t data, const uint16_t nbits=kRC6Mode0Bits, const uint16_t repeat=kNoRepeat)IRsend
sendRCMM(uint64_t data, uint16_t nbits=kRCMMBits, uint16_t repeat=kNoRepeat)IRsend
sendSAMSUNG(const uint64_t data, const uint16_t nbits=kSamsungBits, const uint16_t repeat=kNoRepeat)IRsend
sendSamsung36(const uint64_t data, const uint16_t nbits=kSamsung36Bits, const uint16_t repeat=kNoRepeat)IRsend
sendSamsungAC(const unsigned char data[], const uint16_t nbytes=kSamsungAcStateLength, const uint16_t repeat=kSamsungAcDefaultRepeat)IRsend
sendSanyoLC7461(const uint64_t data, const uint16_t nbits=kSanyoLC7461Bits, const uint16_t repeat=kNoRepeat)IRsend
sendSharp(const uint16_t address, const uint16_t command, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)IRsend
sendSharpAc(const unsigned char data[], const uint16_t nbytes=kSharpAcStateLength, const uint16_t repeat=kSharpAcDefaultRepeat)IRsend
sendSharpRaw(const uint64_t data, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)IRsend
sendSherwood(uint64_t data, uint16_t nbits=kSherwoodBits, uint16_t repeat=kSherwoodMinRepeat)IRsend
sendSony(const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat)IRsend
sendSony38(const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat+1)IRsend
sendSymphony(uint64_t data, uint16_t nbits=kSymphonyBits, uint16_t repeat=kSymphonyDefaultRepeat)IRsend
sendTcl112Ac(const unsigned char data[], const uint16_t nbytes=kTcl112AcStateLength, const uint16_t repeat=kTcl112AcDefaultRepeat)IRsend
sendTeco(const uint64_t data, const uint16_t nbits=kTecoBits, const uint16_t repeat=kNoRepeat)IRsend
sendToshibaAC(const unsigned char data[], const uint16_t nbytes=kToshibaACStateLength, const uint16_t repeat=kToshibaACMinRepeat)IRsend
sendTrotec(const unsigned char data[], const uint16_t nbytes=kTrotecStateLength, const uint16_t repeat=kTrotecDefaultRepeat)IRsend
sendVestelAc(const uint64_t data, const uint16_t nbits=kVestelAcBits, const uint16_t repeat=kNoRepeat)IRsend
sendWhirlpoolAC(const unsigned char data[], const uint16_t nbytes=kWhirlpoolAcStateLength, const uint16_t repeat=kWhirlpoolAcDefaultRepeat)IRsend
sendWhynter(const uint64_t data, const uint16_t nbits=kWhynterBits, const uint16_t repeat=kNoRepeat)IRsend
sendZepeal(const uint64_t data, const uint16_t nbits=kZepealBits, const uint16_t repeat=kZepealMinRepeat)IRsend
space(uint32_t usec)IRsend
toggleRC5(const uint64_t data)IRsend
toggleRC6(const uint64_t data, const uint16_t nbits=kRC6Mode0Bits)IRsend
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend.html new file mode 100644 index 000000000..93a9b7efe --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend.html @@ -0,0 +1,6599 @@ + + + + + + + +IRremoteESP8266: IRsend Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for sending all basic IR protocols. + More...

+ +

#include <IRsend.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRsend (uint16_t IRsendPin, bool inverted=false, bool use_modulation=true)
 Constructor for an IRsend object. More...
 
void begin ()
 Enable the pin for output. More...
 
void enableIROut (uint32_t freq, uint8_t duty=kDutyDefault)
 Set the output frequency modulation and duty cycle. More...
 
VIRTUAL void _delayMicroseconds (uint32_t usec)
 An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds(). More...
 
VIRTUAL uint16_t mark (uint16_t usec)
 Modulate the IR LED for the given period (usec) and at the duty cycle set. More...
 
VIRTUAL void space (uint32_t usec)
 Turn the pin (LED) off for a given time. Sends an IR space for the specified number of microseconds. A space is no output, so the PWM output is disabled. More...
 
int8_t calibrate (uint16_t hz=38000U)
 Calculate & set any offsets to account for execution times during sending. More...
 
void sendRaw (const uint16_t buf[], const uint16_t len, const uint16_t hz)
 Send a raw IRremote message. More...
 
void sendData (uint16_t onemark, uint32_t onespace, uint16_t zeromark, uint32_t zerospace, uint64_t data, uint16_t nbits, bool MSBfirst=true)
 Generic method for sending data that is common to most protocols. Will send leading or trailing 0's if the nbits is larger than the number of bits in data. More...
 
void sendManchesterData (const uint16_t half_period, const uint64_t data, const uint16_t nbits, const bool MSBfirst=true, const bool GEThomas=true)
 Generic method for sending Manchester code data. Will send leading or trailing 0's if the nbits is larger than the number of bits in data. More...
 
void sendManchester (const uint16_t headermark, const uint32_t headerspace, const uint16_t half_period, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency=38, const bool MSBfirst=true, const uint16_t repeat=kNoRepeat, const uint8_t dutycycle=kDutyDefault, const bool GEThomas=true)
 Generic method for sending Manchester code messages. Will send leading or trailing 0's if the nbits is larger than the number. More...
 
void sendGeneric (const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)
 Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits is larger than the number of bits in data. More...
 
void sendGeneric (const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint32_t mesgtime, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)
 Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits is larger than the number of bits in data. More...
 
void sendGeneric (const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint8_t *dataptr, const uint16_t nbytes, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)
 Generic method for sending simple protocol messages. More...
 
bool send (const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)
 Send a simple (up to 64 bits) IR message of a given type. An unknown/unsupported type will send nothing. More...
 
bool send (const decode_type_t type, const uint8_t *state, const uint16_t nbytes)
 Send a complex (>= 64 bits) IR message of a given type. An unknown/unsupported type will send nothing. More...
 
void sendNEC (uint64_t data, uint16_t nbits=kNECBits, uint16_t repeat=kNoRepeat)
 Send a raw NEC(Renesas) formatted message. Status: STABLE / Known working. More...
 
uint32_t encodeNEC (uint16_t address, uint16_t command)
 Calculate the raw NEC data based on address and command. Status: STABLE / Expected to work. More...
 
void sendSony (const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat)
 Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) Status: STABLE / Known working. More...
 
void sendSony38 (const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat+1)
 Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. Status: STABLE / Known working. More...
 
uint32_t encodeSony (const uint16_t nbits, const uint16_t command, const uint16_t address, const uint16_t extended=0)
 Convert Sony/SIRC command, address, & extended bits into sendSony format. Status: STABLE / Should be working. More...
 
void sendSherwood (uint64_t data, uint16_t nbits=kSherwoodBits, uint16_t repeat=kSherwoodMinRepeat)
 Send an IR command to a Sherwood device. Status: STABLE / Known working. More...
 
void sendSAMSUNG (const uint64_t data, const uint16_t nbits=kSamsungBits, const uint16_t repeat=kNoRepeat)
 Send a 32-bit Samsung formatted message. Status: STABLE / Should be working. More...
 
uint32_t encodeSAMSUNG (const uint8_t customer, const uint8_t command)
 Construct a raw Samsung message from the supplied customer(address) & command. Status: STABLE / Should be working. More...
 
void sendSamsung36 (const uint64_t data, const uint16_t nbits=kSamsung36Bits, const uint16_t repeat=kNoRepeat)
 Send a Samsung 36-bit formatted message. Status: Alpha / Experimental. More...
 
void sendSamsungAC (const unsigned char data[], const uint16_t nbytes=kSamsungAcStateLength, const uint16_t repeat=kSamsungAcDefaultRepeat)
 Send a Samsung A/C message. Status: Stable / Known working. More...
 
void sendLG (uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)
 Send an LG formatted message. (LG) Status: Beta / Should be working. More...
 
void sendLG2 (uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)
 Send an LG Variant-2 formatted message. (LG2) Status: Beta / Should be working. More...
 
uint32_t encodeLG (uint16_t address, uint16_t command)
 Construct a raw 28-bit LG message code from the supplied address & command. Status: STABLE / Works. More...
 
uint32_t encodeSharp (const uint16_t address, const uint16_t command, const uint16_t expansion=1, const uint16_t check=0, const bool MSBfirst=false)
 Encode a (raw) Sharp message from it's components. Status: STABLE / Works okay. More...
 
void sendSharp (const uint16_t address, const uint16_t command, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
 Send a Sharp message Status: DEPRECATED / Previously working fine. More...
 
void sendSharpRaw (const uint64_t data, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
 Send a (raw) Sharp message. More...
 
void sendSharpAc (const unsigned char data[], const uint16_t nbytes=kSharpAcStateLength, const uint16_t repeat=kSharpAcDefaultRepeat)
 Send a Sharp A/C message. Status: Alpha / Untested. More...
 
void sendJVC (uint64_t data, uint16_t nbits=kJvcBits, uint16_t repeat=kNoRepeat)
 Send a JVC formatted message. Status: STABLE / Working. More...
 
uint16_t encodeJVC (uint8_t address, uint8_t command)
 Calculate the raw JVC data based on address and command. Status: STABLE / Works fine. More...
 
void sendDenon (uint64_t data, uint16_t nbits=kDenonBits, uint16_t repeat=kNoRepeat)
 Send a Denon formatted message. Status: STABLE / Should be working. More...
 
uint64_t encodeSanyoLC7461 (uint16_t address, uint8_t command)
 Construct a Sanyo LC7461 message. More...
 
void sendSanyoLC7461 (const uint64_t data, const uint16_t nbits=kSanyoLC7461Bits, const uint16_t repeat=kNoRepeat)
 Send a Sanyo LC7461 message. Status: BETA / Probably works. More...
 
void sendDISH (uint64_t data, uint16_t nbits=kDishBits, uint16_t repeat=kDishMinRepeat)
 Send a DISH NETWORK formatted message. Status: STABLE / Working. More...
 
void sendPanasonic64 (const uint64_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
 Send a Panasonic formatted message. Status: STABLE / Should be working. More...
 
void sendPanasonic (const uint16_t address, const uint32_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
 Send a Panasonic formatted message. Status: STABLE, but DEPRECATED. More...
 
uint64_t encodePanasonic (const uint16_t manufacturer, const uint8_t device, const uint8_t subdevice, const uint8_t function)
 Calculate the raw Panasonic data based on device, subdevice, & function. Status: STABLE / Should be working. More...
 
void sendRC5 (const uint64_t data, uint16_t nbits=kRC5XBits, const uint16_t repeat=kNoRepeat)
 Send a Philips RC-5/RC-5X packet. Status: RC-5 (stable), RC-5X (alpha) More...
 
uint16_t encodeRC5 (const uint8_t address, const uint8_t command, const bool key_released=false)
 Encode a Philips RC-5 data message. Status: Beta / Should be working. More...
 
uint16_t encodeRC5X (const uint8_t address, const uint8_t command, const bool key_released=false)
 Encode a Philips RC-5X data message. Status: Beta / Should be working. More...
 
uint64_t toggleRC5 (const uint64_t data)
 Flip the toggle bit of a Philips RC-5/RC-5X data message. Used to indicate a change of remote button's state. Status: STABLE. More...
 
void sendRC6 (const uint64_t data, const uint16_t nbits=kRC6Mode0Bits, const uint16_t repeat=kNoRepeat)
 Send a Philips RC-6 packet. Status: Stable. More...
 
uint64_t encodeRC6 (const uint32_t address, const uint8_t command, const uint16_t mode=kRC6Mode0Bits)
 Encode a Philips RC-6 data message. Status: Beta / Should be working. More...
 
uint64_t toggleRC6 (const uint64_t data, const uint16_t nbits=kRC6Mode0Bits)
 Flip the toggle bit of a Philips RC-6 data message. Used to indicate a change of remote button's state. Status: STABLE / Should work fine. More...
 
void sendRCMM (uint64_t data, uint16_t nbits=kRCMMBits, uint16_t repeat=kNoRepeat)
 Send a Philips RC-MM packet. Status: STABLE / Should be working. More...
 
void sendCOOLIX (uint64_t data, uint16_t nbits=kCoolixBits, uint16_t repeat=kCoolixDefaultRepeat)
 Send a Coolix message Status: STABLE / Confirmed Working. More...
 
void sendWhynter (const uint64_t data, const uint16_t nbits=kWhynterBits, const uint16_t repeat=kNoRepeat)
 Send a Whynter message. Status: STABLE. More...
 
void sendMitsubishi (uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)
 Send the supplied Mitsubishi 16-bit message. Status: STABLE / Working. More...
 
void sendMitsubishi136 (const unsigned char data[], const uint16_t nbytes=kMitsubishi136StateLength, const uint16_t repeat=kMitsubishi136MinRepeat)
 Send a Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: BETA / Probably working. Needs to be tested against a real device. More...
 
void sendMitsubishi112 (const unsigned char data[], const uint16_t nbytes=kMitsubishi112StateLength, const uint16_t repeat=kMitsubishi112MinRepeat)
 Send a Mitsubishi 112-bit A/C formatted message. (MITSUBISHI112) Status: Stable / Reported as working. More...
 
void sendMitsubishi2 (uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)
 Send a supplied second variant Mitsubishi 16-bit message. Status: BETA / Probably works. More...
 
void sendMitsubishiAC (const unsigned char data[], const uint16_t nbytes=kMitsubishiACStateLength, const uint16_t repeat=kMitsubishiACMinRepeat)
 Send a Mitsubishi 144-bit A/C formatted message. (MITSUBISHI_AC) Status: STABLE / Working. More...
 
void sendMitsubishiHeavy88 (const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy88StateLength, const uint16_t repeat=kMitsubishiHeavy88MinRepeat)
 Send a MitsubishiHeavy 88-bit A/C message. Status: BETA / Appears to be working. Needs testing against a real device. More...
 
void sendMitsubishiHeavy152 (const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy152StateLength, const uint16_t repeat=kMitsubishiHeavy152MinRepeat)
 Send a MitsubishiHeavy 152-bit A/C message. Status: BETA / Appears to be working. Needs testing against a real device. More...
 
void sendFujitsuAC (const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kFujitsuAcMinRepeat)
 Send a Fujitsu A/C formatted message. Status: STABLE / Known Good. More...
 
void sendInax (const uint64_t data, const uint16_t nbits=kInaxBits, const uint16_t repeat=kInaxMinRepeat)
 Send a Inax Toilet formatted message. Status: STABLE / Working. More...
 
void sendGC (uint16_t buf[], uint16_t len)
 Send a shortened GlobalCache (GC) IRdb/control tower formatted message. Status: STABLE / Known working. More...
 
void sendKelvinator (const unsigned char data[], const uint16_t nbytes=kKelvinatorStateLength, const uint16_t repeat=kKelvinatorDefaultRepeat)
 Send a Kelvinator A/C message. Status: STABLE / Known working. More...
 
void sendDaikin (const unsigned char data[], const uint16_t nbytes=kDaikinStateLength, const uint16_t repeat=kDaikinDefaultRepeat)
 Send a Daikin 280-bit A/C formatted message. Status: STABLE. More...
 
void sendDaikin64 (const uint64_t data, const uint16_t nbits=kDaikin64Bits, const uint16_t repeat=kDaikin64DefaultRepeat)
 Send a Daikin64 (64-bit) A/C formatted message. Status: Beta / Probably Working. More...
 
void sendDaikin128 (const unsigned char data[], const uint16_t nbytes=kDaikin128StateLength, const uint16_t repeat=kDaikin128DefaultRepeat)
 Send a Daikin128 (128-bit) A/C formatted message. Status: STABLE / Known Working. More...
 
void sendDaikin152 (const unsigned char data[], const uint16_t nbytes=kDaikin152StateLength, const uint16_t repeat=kDaikin152DefaultRepeat)
 Send a Daikin152 (152-bit) A/C formatted message. Status: STABLE / Known Working. More...
 
void sendDaikin160 (const unsigned char data[], const uint16_t nbytes=kDaikin160StateLength, const uint16_t repeat=kDaikin160DefaultRepeat)
 Send a Daikin160 (160-bit) A/C formatted message. Status: STABLE / Confirmed working. More...
 
void sendDaikin176 (const unsigned char data[], const uint16_t nbytes=kDaikin176StateLength, const uint16_t repeat=kDaikin176DefaultRepeat)
 Send a Daikin176 (176-bit) A/C formatted message. Status: Alpha / Untested on a real device. More...
 
void sendDaikin2 (const unsigned char data[], const uint16_t nbytes=kDaikin2StateLength, const uint16_t repeat=kDaikin2DefaultRepeat)
 Send a Daikin2 (312-bit) A/C formatted message. Status: STABLE / Expected to work. More...
 
void sendDaikin216 (const unsigned char data[], const uint16_t nbytes=kDaikin216StateLength, const uint16_t repeat=kDaikin216DefaultRepeat)
 Send a Daikin216 (216-bit) A/C formatted message. Status: Alpha / Untested on a real device. More...
 
void sendAiwaRCT501 (uint64_t data, uint16_t nbits=kAiwaRcT501Bits, uint16_t repeat=kAiwaRcT501MinRepeats)
 Send an Aiwa RC T501 formatted message. Status: BETA / Should work. More...
 
void sendGree (const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)
 Send a Gree Heat Pump formatted message. Status: STABLE / Working. More...
 
void sendGree (const uint8_t data[], const uint16_t nbytes=kGreeStateLength, const uint16_t repeat=kGreeDefaultRepeat)
 Send a Gree Heat Pump formatted message. Status: STABLE / Working. More...
 
void sendGoodweather (const uint64_t data, const uint16_t nbits=kGoodweatherBits, const uint16_t repeat=kGoodweatherMinRepeat)
 Send a Goodweather HVAC formatted message. Status: BETA / Needs testing on real device. More...
 
void sendPronto (uint16_t data[], uint16_t len, uint16_t repeat=kNoRepeat)
 Send a Pronto Code formatted message. Status: STABLE / Known working. More...
 
void sendArgo (const unsigned char data[], const uint16_t nbytes=kArgoStateLength, const uint16_t repeat=kArgoDefaultRepeat)
 Send a Argo A/C formatted message. Status: BETA / Probably works. More...
 
void sendTrotec (const unsigned char data[], const uint16_t nbytes=kTrotecStateLength, const uint16_t repeat=kTrotecDefaultRepeat)
 Send a Trotec message. Status: Beta / Probably Working. More...
 
void sendNikai (uint64_t data, uint16_t nbits=kNikaiBits, uint16_t repeat=kNoRepeat)
 Send a Nikai formatted message. Status: STABLE / Working. More...
 
void sendToshibaAC (const unsigned char data[], const uint16_t nbytes=kToshibaACStateLength, const uint16_t repeat=kToshibaACMinRepeat)
 Send a Toshiba A/C message. Status: STABLE / Working. More...
 
void sendMidea (uint64_t data, uint16_t nbits=kMideaBits, uint16_t repeat=kMideaMinRepeat)
 Send a Midea message Status: Alpha / Needs testing against a real device. More...
 
void sendMidea24 (const uint64_t data, const uint16_t nbits=kMidea24Bits, const uint16_t repeat=kMidea24MinRepeat)
 Send a Midea24 formatted message. Status: STABLE / Confirmed working on a real device. More...
 
void sendMagiQuest (const uint64_t data, const uint16_t nbits=kMagiquestBits, const uint16_t repeat=kNoRepeat)
 Send a MagiQuest formatted message. Status: Beta / Should be working. More...
 
uint64_t encodeMagiQuest (const uint32_t wand_id, const uint16_t magnitude)
 Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. (Only 48 bits of real data + 8 leading zero bits) This is suitable for calling sendMagiQuest() with. e.g. sendMagiQuest(encodeMagiQuest(wand_id, magnitude)) More...
 
void sendLasertag (uint64_t data, uint16_t nbits=kLasertagBits, uint16_t repeat=kLasertagMinRepeat)
 Send a Lasertag packet/message. Status: STABLE / Working. More...
 
void sendCarrierAC (uint64_t data, uint16_t nbits=kCarrierAcBits, uint16_t repeat=kCarrierAcMinRepeat)
 Send a Carrier HVAC formatted message. Status: STABLE / Works on real devices. More...
 
void sendCarrierAC40 (uint64_t data, uint16_t nbits=kCarrierAc40Bits, uint16_t repeat=kCarrierAc40MinRepeat)
 Send a Carrier 40bit HVAC formatted message. Status: STABLE / Tested against a real device. More...
 
void sendCarrierAC64 (uint64_t data, uint16_t nbits=kCarrierAc64Bits, uint16_t repeat=kCarrierAc64MinRepeat)
 Send a Carrier 64bit HVAC formatted message. Status: STABLE / Known to be working. More...
 
void sendHaierAC (const unsigned char data[], const uint16_t nbytes=kHaierACStateLength, const uint16_t repeat=kHaierAcDefaultRepeat)
 Send a Haier A/C formatted message. (HSU07-HEA03 remote) Status: STABLE / Known to be working. More...
 
void sendHaierACYRW02 (const unsigned char data[], const uint16_t nbytes=kHaierACYRW02StateLength, const uint16_t repeat=kHaierAcYrw02DefaultRepeat)
 Send a Haier YR-W02 remote A/C formatted message. Status: Alpha / Untested on a real device. More...
 
void sendHitachiAC (const unsigned char data[], const uint16_t nbytes=kHitachiAcStateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) Status: STABLE / Working. More...
 
void sendHitachiAC1 (const unsigned char data[], const uint16_t nbytes=kHitachiAc1StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) Status: STABLE / Confirmed Working. More...
 
void sendHitachiAC2 (const unsigned char data[], const uint16_t nbytes=kHitachiAc2StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) Basically the same as sendHitatchiAC() except different size. Status: STABLE / Expected to work. More...
 
void sendHitachiAc3 (const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi(3) A/C formatted message. (HITACHI_AC3) Status: STABLE / Working fine. More...
 
void sendHitachiAc344 (const unsigned char data[], const uint16_t nbytes=kHitachiAc344StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) Basically the same as sendHitatchiAC() except different size. Status: Beta / Probably works. More...
 
void sendHitachiAc424 (const unsigned char data[], const uint16_t nbytes=kHitachiAc424StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) Status: STABLE / Reported as working. More...
 
void sendGICable (uint64_t data, uint16_t nbits=kGicableBits, uint16_t repeat=kGicableMinRepeat)
 Send a raw G.I. Cable formatted message. Status: Alpha / Untested. More...
 
void sendWhirlpoolAC (const unsigned char data[], const uint16_t nbytes=kWhirlpoolAcStateLength, const uint16_t repeat=kWhirlpoolAcDefaultRepeat)
 Send a Whirlpool A/C message. Status: BETA / Probably works. More...
 
void sendLutron (uint64_t data, uint16_t nbits=kLutronBits, uint16_t repeat=kNoRepeat)
 Send a Lutron formatted message. Status: Stable / Appears to be working for real devices. More...
 
void sendElectraAC (const unsigned char data[], const uint16_t nbytes=kElectraAcStateLength, const uint16_t repeat=kNoRepeat)
 Send a Electra A/C formatted message. Status: Alpha / Needs testing against a real device. More...
 
void sendPanasonicAC (const unsigned char data[], const uint16_t nbytes=kPanasonicAcStateLength, const uint16_t repeat=kPanasonicAcDefaultRepeat)
 Send a Panasonic A/C message. Status: STABLE / Work with real device(s). More...
 
void sendPioneer (const uint64_t data, const uint16_t nbits=kPioneerBits, const uint16_t repeat=kNoRepeat)
 Send a raw Pioneer formatted message. Status: STABLE / Expected to be working. More...
 
uint64_t encodePioneer (uint16_t address, uint16_t command)
 Calculate the raw Pioneer data code based on two NEC sub-codes Status: STABLE / Expected to work. More...
 
void sendMWM (const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kNoRepeat)
 Send a MWM packet/message. Status: Implemented. More...
 
void sendVestelAc (const uint64_t data, const uint16_t nbits=kVestelAcBits, const uint16_t repeat=kNoRepeat)
 Send a Vestel message Status: STABLE / Working. More...
 
void sendTcl112Ac (const unsigned char data[], const uint16_t nbytes=kTcl112AcStateLength, const uint16_t repeat=kTcl112AcDefaultRepeat)
 Send a TCL 112-bit A/C message. Status: Beta / Probably working. More...
 
void sendTeco (const uint64_t data, const uint16_t nbits=kTecoBits, const uint16_t repeat=kNoRepeat)
 Send a Teco A/C message. Status: Beta / Probably working. More...
 
void sendLegoPf (const uint64_t data, const uint16_t nbits=kLegoPfBits, const uint16_t repeat=kLegoPfMinRepeat)
 Send a LEGO Power Functions message. Status: Beta / Should work. More...
 
void sendNeoclima (const unsigned char data[], const uint16_t nbytes=kNeoclimaStateLength, const uint16_t repeat=kNeoclimaMinRepeat)
 Send a Neoclima message. Status: STABLE / Known to be working. More...
 
void sendAmcor (const unsigned char data[], const uint16_t nbytes=kAmcorStateLength, const uint16_t repeat=kAmcorDefaultRepeat)
 Send a Amcor HVAC formatted message. Status: STABLE / Reported as working. More...
 
void sendEpson (uint64_t data, uint16_t nbits=kEpsonBits, uint16_t repeat=kEpsonMinRepeat)
 Send an Epson formatted message. Status: Beta / Probably works. More...
 
void sendSymphony (uint64_t data, uint16_t nbits=kSymphonyBits, uint16_t repeat=kSymphonyDefaultRepeat)
 Send a Symphony packet. Status: STABLE / Should be working. More...
 
void sendAirwell (uint64_t data, uint16_t nbits=kAirwellBits, uint16_t repeat=kAirwellMinRepeats)
 Send an Airwell Manchester Code formatted message. Status: BETA / Appears to be working. More...
 
void sendDelonghiAc (uint64_t data, uint16_t nbits=kDelonghiAcBits, uint16_t repeat=kDelonghiAcDefaultRepeat)
 Send a Delonghi A/C formatted message. Status: STABLE / Reported as working on a real device. More...
 
void sendDoshisha (const uint64_t data, uint16_t nbits=kDoshishaBits, const uint16_t repeat=kNoRepeat)
 Send a Doshisha formatted message. Status: STABLE / Works on real device. More...
 
uint64_t encodeDoshisha (const uint8_t command, const uint8_t channel=0)
 Encode Doshisha combining constant values with command and channel. Status: STABLE / Working. More...
 
void sendMultibrackets (const uint64_t data, const uint16_t nbits=kMultibracketsBits, const uint16_t repeat=kMultibracketsDefaultRepeat)
 Send a Multibrackets formatted message. Status: BETA / Appears to be working. More...
 
void sendCoronaAc (const uint8_t data[], const uint16_t nbytes=kCoronaAcStateLength, const uint16_t repeat=kNoRepeat)
 Send a CoronaAc formatted message. Status: STABLE / Working on real device. More...
 
void sendZepeal (const uint64_t data, const uint16_t nbits=kZepealBits, const uint16_t repeat=kZepealMinRepeat)
 Send a Zepeal formatted message. Status: STABLE / Works on real device. More...
 
+ + + + + + + +

+Static Public Member Functions

static uint16_t minRepeats (const decode_type_t protocol)
 Get the minimum number of repeats for a given protocol. More...
 
static uint16_t defaultBits (const decode_type_t protocol)
 Get the default number of bits for a given protocol. More...
 
+ + + + + + + +

+Protected Member Functions

VIRTUAL void ledOff ()
 Turn off the IR LED. More...
 
VIRTUAL void ledOn ()
 Turn on the IR LED. More...
 
+ + + + + +

+Protected Attributes

uint8_t outputOn
 
uint8_t outputOff
 
+ + + + + + + +

+Private Member Functions

uint32_t calcUSecPeriod (uint32_t hz, bool use_offset=true)
 Calculate the period for a given frequency. More...
 
void _sendSony (const uint64_t data, const uint16_t nbits, const uint16_t repeat, const uint16_t freq)
 Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message Status: STABLE / Known working. More...
 
+ + + + + + + + + + + + + + + +

+Private Attributes

uint32_t _freq_unittest
 
uint16_t onTimePeriod
 
uint16_t offTimePeriod
 
uint16_t IRpin
 
int8_t periodOffset
 
uint8_t _dutycycle
 
bool modulation
 
+

Detailed Description

+

Class for sending all basic IR protocols.

+
Note
Originally from https://github.com/shirriff/Arduino-IRremote/ Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for sending IR code on ESP8266
+

Constructor & Destructor Documentation

+ +

◆ IRsend()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRsend::IRsend (uint16_t IRsendPin,
bool inverted = false,
bool use_modulation = true 
)
+
+explicit
+
+ +

Constructor for an IRsend object.

+
Parameters
+ + + +
[in]IRsendPinWhich GPIO pin to use when sending an IR command.
[in]invertedOptional flag to invert the output. (default = false) e.g. LED is illuminated when GPIO is LOW rather than HIGH.
+
+
+
Warning
Setting inverted to something other than the default could easily destroy your IR LED if you are overdriving it. Unless you REALLY know what you are doing, don't change this.
+
Parameters
+ + +
[in]use_modulationDo we do frequency modulation during transmission? i.e. If not, assume a 100% duty cycle. Ignore attempts to change the duty cycle etc.
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _delayMicroseconds()

+ +
+
+ + + + + + + + +
void IRsend::_delayMicroseconds (uint32_t usec)
+
+ +

An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds().

+

A version of delayMicroseconds() that handles large values and does NOT use the watch-dog friendly delay() calls where appropriate.

+
Parameters
+ + +
[in]usecNr. of uSeconds to delay for.
+
+
+
Note
Use this only if you know what you are doing as it may cause the WDT to reset the ESP8266.
+ +
+
+ +

◆ _sendSony()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::_sendSony (const uint64_t data,
const uint16_t nbits,
const uint16_t repeat,
const uint16_t freq 
)
+
+private
+
+ +

Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
[in]freqFrequency of the modulation to transmit at. (Hz or kHz)
+
+
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRsend::begin ()
+
+ +

Enable the pin for output.

+ +
+
+ +

◆ calcUSecPeriod()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint32_t IRsend::calcUSecPeriod (uint32_t hz,
bool use_offset = true 
)
+
+private
+
+ +

Calculate the period for a given frequency.

+
Parameters
+ + + +
[in]hzFrequency in Hz.
[in]use_offsetShould we use the calculated offset or not?
+
+
+
Returns
nr. of uSeconds.
+
Note
(T = 1/f)
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + + + + +
int8_t IRsend::calibrate (uint16_t hz = 38000U)
+
+ +

Calculate & set any offsets to account for execution times during sending.

+
Parameters
+ + +
[in]hzThe frequency to calibrate at >= 1000Hz. Default is 38000Hz.
+
+
+
Returns
The calculated period offset (in uSeconds) which is now in use. e.g. -5.
+
Note
This will generate an 65535us mark() IR LED signal. This only needs to be called once, if at all.
+ +
+
+ +

◆ defaultBits()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRsend::defaultBits (const decode_type_t protocol)
+
+static
+
+ +

Get the default number of bits for a given protocol.

+
Parameters
+ + +
[in]protocolProtocol number/type you want the default bit size for.
+
+
+
Returns
The number of bits.
+ +
+
+ +

◆ enableIROut()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRsend::enableIROut (uint32_t freq,
uint8_t duty = kDutyDefault 
)
+
+ +

Set the output frequency modulation and duty cycle.

+
Parameters
+ + + +
[in]freqThe freq we want to modulate at. Assumes < 1000 means kHz else Hz.
[in]dutyPercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent. This is ignored if modulation is disabled at object instantiation.
+
+
+
Note
Integer timing functions & math mean we can't do fractions of microseconds timing. Thus minor changes to the freq & duty values may have limited effect. You've been warned.
+ +
+
+ +

◆ encodeDoshisha()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodeDoshisha (const uint8_t command,
const uint8_t channel = 0 
)
+
+ +

Encode Doshisha combining constant values with command and channel. Status: STABLE / Working.

+
Parameters
+ + + +
[in]commandThe command code to be sent.
[in]channelThe one bit channel 0 for CH1 and 1 for CH2
+
+
+
Returns
The corresponding Doshisha code.
+ +
+
+ +

◆ encodeJVC()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint16_t IRsend::encodeJVC (uint8_t address,
uint8_t command 
)
+
+ +

Calculate the raw JVC data based on address and command. Status: STABLE / Works fine.

+
Parameters
+ + + +
[in]addressAn 8-bit address value.
[in]commandAn 8-bit command value.
+
+
+
Returns
A raw JVC message code, suitable for sendJVC()..
+
See also
http://www.sbprojects.com/knowledge/ir/jvc.php
+ +
+
+ +

◆ encodeLG()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeLG (uint16_t address,
uint16_t command 
)
+
+ +

Construct a raw 28-bit LG message code from the supplied address & command. Status: STABLE / Works.

+
Parameters
+ + + +
[in]addressThe address code.
[in]commandThe command code.
+
+
+
Returns
A raw 28-bit LG message code suitable for sendLG() etc.
+
Note
Sequence of bits = address + command + checksum.
+ +
+
+ +

◆ encodeMagiQuest()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodeMagiQuest (const uint32_t wand_id,
const uint16_t magnitude 
)
+
+ +

Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. (Only 48 bits of real data + 8 leading zero bits) This is suitable for calling sendMagiQuest() with. e.g. sendMagiQuest(encodeMagiQuest(wand_id, magnitude))

+
Parameters
+ + + +
[in]wand_idThe value for the wand ID.
[in]magnitudeThe value for the magnitude
+
+
+
Returns
A code suitable for calling sendMagiQuest() with.
+ +
+
+ +

◆ encodeNEC()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeNEC (uint16_t address,
uint16_t command 
)
+
+ +

Calculate the raw NEC data based on address and command. Status: STABLE / Expected to work.

+
Parameters
+ + + +
[in]addressAn address value.
[in]commandAn 8-bit command value.
+
+
+
Returns
A raw 32-bit NEC message suitable for use with sendNEC().
+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+ +
+
+ +

◆ encodePanasonic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodePanasonic (const uint16_t manufacturer,
const uint8_t device,
const uint8_t subdevice,
const uint8_t function 
)
+
+ +

Calculate the raw Panasonic data based on device, subdevice, & function. Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in]manufacturerA 16-bit manufacturer code. e.g. 0x4004 is Panasonic
[in]deviceAn 8-bit code.
[in]subdeviceAn 8-bit code.
[in]functionAn 8-bit code.
+
+
+
Returns
A value suitable for use with sendPanasonic64().
+
Note
Panasonic 48-bit protocol is a modified version of Kaseikyo.
+
See also
http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615
+ +
+
+ +

◆ encodePioneer()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodePioneer (uint16_t address,
uint16_t command 
)
+
+ +

Calculate the raw Pioneer data code based on two NEC sub-codes Status: STABLE / Expected to work.

+
Parameters
+ + + +
[in]addressA 16-bit "published" NEC value.
[in]commandA 16-bit "published" NEC value.
+
+
+
Returns
A raw 64-bit Pioneer message code for use with sendPioneer()`
+
Note
Address & Command can be take from a decode result OR from the spreadsheets located at: https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers where the first part is considered the address, and the second the command. e.g. "A556+AF20" is an Address of 0xA556 & a Command of 0xAF20.
+ +
+
+ +

◆ encodeRC5()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRsend::encodeRC5 (const uint8_t address,
const uint8_t command,
const bool key_released = false 
)
+
+ +

Encode a Philips RC-5 data message. Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]addressThe 5-bit address value for the message.
[in]commandThe 6-bit command value for the message.
[in]key_releasedIndicate if the remote key has been released.
+
+
+
Returns
A message suitable for use in sendRC5().
+ +
+
+ +

◆ encodeRC5X()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRsend::encodeRC5X (const uint8_t address,
const uint8_t command,
const bool key_released = false 
)
+
+ +

Encode a Philips RC-5X data message. Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]addressThe 5-bit address value for the message.
[in]commandThe 7-bit command value for the message.
[in]key_releasedIndicate if the remote key has been released.
+
+
+
Returns
A message suitable for use in sendRC5().
+ +
+
+ +

◆ encodeRC6()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodeRC6 (const uint32_t address,
const uint8_t command,
const uint16_t mode = kRC6Mode0Bits 
)
+
+ +

Encode a Philips RC-6 data message. Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]addressThe address (aka. control) value for the message. Includes the field/mode/toggle bits.
[in]commandThe 8-bit command value for the message. (aka. information)
[in]modeWhich protocol to use. Defined by nr. of bits in the protocol.
+
+
+
Returns
A data message suitable for use in sendRC6().
+ +
+
+ +

◆ encodeSAMSUNG()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeSAMSUNG (const uint8_t customer,
const uint8_t command 
)
+
+ +

Construct a raw Samsung message from the supplied customer(address) & command. Status: STABLE / Should be working.

+
Parameters
+ + + +
[in]customerThe customer code. (aka. Address)
[in]commandThe command code.
+
+
+
Returns
A raw 32-bit Samsung message suitable for sendSAMSUNG().
+ +
+
+ +

◆ encodeSanyoLC7461()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodeSanyoLC7461 (uint16_t address,
uint8_t command 
)
+
+ +

Construct a Sanyo LC7461 message.

+
Parameters
+ + + +
[in]addressThe 13 bit value of the address(Custom) portion of the protocol.
[in]commandThe 8 bit value of the command(Key) portion of the protocol.
+
+
+
Returns
An uint64_t with the encoded raw 42 bit Sanyo LC7461 data value.
+
Note
This protocol uses the NEC protocol timings. However, data is formatted as : address(13 bits), !address, command(8 bits), !command. According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
+ +
+
+ +

◆ encodeSharp()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeSharp (const uint16_t address,
const uint16_t command,
const uint16_t expansion = 1,
const uint16_t check = 0,
const bool MSBfirst = false 
)
+
+ +

Encode a (raw) Sharp message from it's components. Status: STABLE / Works okay.

+
Parameters
+ + + + + + +
[in]addressThe value of the address to be sent.
[in]commandThe value of the address to be sent. (8 bits)
[in]expansionThe value of the expansion bit to use. (0 or 1, typically 1)
[in]checkThe value of the check bit to use. (0 or 1, typically 0)
[in]MSBfirstFlag indicating MSB first or LSB first order.
+
+
+
Returns
A uint32_t containing the raw Sharp message for sendSharpRaw().
+
Note
Assumes the standard Sharp bit sizes. Historically sendSharp() sends address & command in MSB first order. This is actually incorrect. It should be sent in LSB order. The behaviour of sendSharp() hasn't been changed to maintain backward compatibility.
+ +
+
+ +

◆ encodeSony()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeSony (const uint16_t nbits,
const uint16_t command,
const uint16_t address,
const uint16_t extended = 0 
)
+
+ +

Convert Sony/SIRC command, address, & extended bits into sendSony format. Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in]nbitsSony protocol bit size.
[in]commandSony command bits.
[in]addressSony address bits.
[in]extendedSony extended bits.
+
+
+
Returns
A sendSony() etc compatible data message.
+ +
+
+ +

◆ ledOff()

+ +
+
+ + + + + +
+ + + + + + + +
void IRsend::ledOff ()
+
+protected
+
+ +

Turn off the IR LED.

+ +
+
+ +

◆ ledOn()

+ +
+
+ + + + + +
+ + + + + + + +
void IRsend::ledOn ()
+
+protected
+
+ +

Turn on the IR LED.

+ +
+
+ +

◆ mark()

+ +
+
+ + + + + + + + +
uint16_t IRsend::mark (uint16_t usec)
+
+ +

Modulate the IR LED for the given period (usec) and at the duty cycle set.

+
Parameters
+ + +
[in]usecThe period of time to modulate the IR LED for, in microseconds.
+
+
+
Returns
Nr. of pulses actually sent.
+
Note
The ESP8266 has no good way to do hardware PWM, so we have to do it all in software. There is a horrible kludge/brilliant hack to use the second serial TX line to do fairly accurate hardware PWM, but it is only available on a single specific GPIO and only available on some modules. e.g. It's not available on the ESP-01 module. Hence, for greater compatibility & choice, we don't use that method. Ref: https://www.analysir.com/blog/2017/01/29/updated-esp8266-nodemcu-backdoor-upwm-hack-for-ir-signals/
+ +
+
+ +

◆ minRepeats()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRsend::minRepeats (const decode_type_t protocol)
+
+static
+
+ +

Get the minimum number of repeats for a given protocol.

+
Parameters
+ + +
[in]protocolProtocol number/type of the message you want to send.
+
+
+
Returns
The number of repeats required.
+ +
+
+ +

◆ send() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRsend::send (const decode_type_t type,
const uint64_t data,
const uint16_t nbits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a simple (up to 64 bits) IR message of a given type. An unknown/unsupported type will send nothing.

+
Parameters
+ + + + + +
[in]typeProtocol number/type of the message you want to send.
[in]dataThe data you want to send (up to 64 bits).
[in]nbitsHow many bits long the message is to be.
[in]repeatHow many repeats to do?
+
+
+
Returns
True if it is a type we can attempt to send, false if not.
+ +
+
+ +

◆ send() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool IRsend::send (const decode_type_t type,
const uint8_t * state,
const uint16_t nbytes 
)
+
+ +

Send a complex (>= 64 bits) IR message of a given type. An unknown/unsupported type will send nothing.

+
Parameters
+ + + + +
[in]typeProtocol number/type of the message you want to send.
[in]stateA pointer to the array of bytes that make up the state[].
[in]nbytesHow many bytes are in the state.
+
+
+
Returns
True if it is a type we can attempt to send, false if not.
+ +
+
+ +

◆ sendAirwell()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendAirwell (uint64_t data,
uint16_t nbits = kAirwellBits,
uint16_t repeat = kAirwellMinRepeats 
)
+
+ +

Send an Airwell Manchester Code formatted message. Status: BETA / Appears to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of the message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+ +
+
+ +

◆ sendAiwaRCT501()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendAiwaRCT501 (uint64_t data,
uint16_t nbits = kAiwaRcT501Bits,
uint16_t repeat = kAiwaRcT501MinRepeats 
)
+
+ +

Send an Aiwa RC T501 formatted message. Status: BETA / Should work.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of the message to be sent. Typically kAiwaRcT501Bits. Max is 37 = (64 - 27)
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
http://lirc.sourceforge.net/remotes/aiwa/RC-T501
+ +
+
+ +

◆ sendAmcor()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendAmcor (const unsigned char data[],
const uint16_t nbytes = kAmcorStateLength,
const uint16_t repeat = kAmcorDefaultRepeat 
)
+
+ +

Send a Amcor HVAC formatted message. Status: STABLE / Reported as working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendArgo()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendArgo (const unsigned char data[],
const uint16_t nbytes = kArgoStateLength,
const uint16_t repeat = kArgoDefaultRepeat 
)
+
+ +

Send a Argo A/C formatted message. Status: BETA / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendCarrierAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCarrierAC (uint64_t data,
uint16_t nbits = kCarrierAcBits,
uint16_t repeat = kCarrierAcMinRepeat 
)
+
+ +

Send a Carrier HVAC formatted message. Status: STABLE / Works on real devices.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendCarrierAC40()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCarrierAC40 (uint64_t data,
uint16_t nbits = kCarrierAc40Bits,
uint16_t repeat = kCarrierAc40MinRepeat 
)
+
+ +

Send a Carrier 40bit HVAC formatted message. Status: STABLE / Tested against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe bit size of the message being sent.
[in]repeatThe number of times the message is to be repeated.
+
+
+ +
+
+ +

◆ sendCarrierAC64()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCarrierAC64 (uint64_t data,
uint16_t nbits = kCarrierAc64Bits,
uint16_t repeat = kCarrierAc64MinRepeat 
)
+
+ +

Send a Carrier 64bit HVAC formatted message. Status: STABLE / Known to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe bit size of the message being sent.
[in]repeatThe number of times the message is to be repeated.
+
+
+ +
+
+ +

◆ sendCOOLIX()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCOOLIX (uint64_t data,
uint16_t nbits = kCoolixBits,
uint16_t repeat = kCoolixDefaultRepeat 
)
+
+ +

Send a Coolix message Status: STABLE / Confirmed Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/z3t0/Arduino-IRremote/blob/master/ir_COOLIX.cpp
+ +
+
+ +

◆ sendCoronaAc()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCoronaAc (const uint8_t data[],
const uint16_t nbytes = kCoronaAcStateLength,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a CoronaAc formatted message. Status: STABLE / Working on real device.

+
Parameters
+ + + + +
[in]dataAn array of bytes containing the IR command.
[in]nbytesNr. of bytes of data in the array. e.g.
uint8_t data[kCoronaAcStateLength] = {
+
0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8,
+
0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00,
+
0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00};
+
[in]repeatNr. of times the message is to be repeated.
+
+
+ +
+
+ +

◆ sendDaikin()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin (const unsigned char data[],
const uint16_t nbytes = kDaikinStateLength,
const uint16_t repeat = kDaikinDefaultRepeat 
)
+
+ +

Send a Daikin 280-bit A/C formatted message. Status: STABLE.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
+
+https://github.com/blafois/Daikin-IR-Reverse
+ +
+
+ +

◆ sendDaikin128()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin128 (const unsigned char data[],
const uint16_t nbytes = kDaikin128StateLength,
const uint16_t repeat = kDaikin128DefaultRepeat 
)
+
+ +

Send a Daikin128 (128-bit) A/C formatted message. Status: STABLE / Known Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/827
+ +
+
+ +

◆ sendDaikin152()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin152 (const unsigned char data[],
const uint16_t nbytes = kDaikin152StateLength,
const uint16_t repeat = kDaikin152DefaultRepeat 
)
+
+ +

Send a Daikin152 (152-bit) A/C formatted message. Status: STABLE / Known Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/873
+ +
+
+ +

◆ sendDaikin160()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin160 (const unsigned char data[],
const uint16_t nbytes = kDaikin160StateLength,
const uint16_t repeat = kDaikin160DefaultRepeat 
)
+
+ +

Send a Daikin160 (160-bit) A/C formatted message. Status: STABLE / Confirmed working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/731
+ +
+
+ +

◆ sendDaikin176()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin176 (const unsigned char data[],
const uint16_t nbytes = kDaikin176StateLength,
const uint16_t repeat = kDaikin176DefaultRepeat 
)
+
+ +

Send a Daikin176 (176-bit) A/C formatted message. Status: Alpha / Untested on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendDaikin2()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin2 (const unsigned char data[],
const uint16_t nbytes = kDaikin2StateLength,
const uint16_t repeat = kDaikin2DefaultRepeat 
)
+
+ +

Send a Daikin2 (312-bit) A/C formatted message. Status: STABLE / Expected to work.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/582
+ +
+
+ +

◆ sendDaikin216()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin216 (const unsigned char data[],
const uint16_t nbytes = kDaikin216StateLength,
const uint16_t repeat = kDaikin216DefaultRepeat 
)
+
+ +

Send a Daikin216 (216-bit) A/C formatted message. Status: Alpha / Untested on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/689
+
+https://github.com/danny-source/Arduino_DY_IRDaikin
+ +
+
+ +

◆ sendDaikin64()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin64 (const uint64_t data,
const uint16_t nbits = kDaikin64Bits,
const uint16_t repeat = kDaikin64DefaultRepeat 
)
+
+ +

Send a Daikin64 (64-bit) A/C formatted message. Status: Beta / Probably Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1064
+ +
+
+ +

◆ sendData()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendData (uint16_t onemark,
uint32_t onespace,
uint16_t zeromark,
uint32_t zerospace,
uint64_t data,
uint16_t nbits,
bool MSBfirst = true 
)
+
+ +

Generic method for sending data that is common to most protocols. Will send leading or trailing 0's if the nbits is larger than the number of bits in data.

+
Parameters
+ + + + + + + + +
[in]onemarkNr. of usecs for the led to be pulsed for a '1' bit.
[in]onespaceNr. of usecs for the led to be fully off for a '1' bit.
[in]zeromarkNr. of usecs for the led to be pulsed for a '0' bit.
[in]zerospaceNr. of usecs for the led to be fully off for a '0' bit.
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
+
+
+ +
+
+ +

◆ sendDelonghiAc()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDelonghiAc (uint64_t data,
uint16_t nbits = kDelonghiAcBits,
uint16_t repeat = kDelonghiAcDefaultRepeat 
)
+
+ +

Send a Delonghi A/C formatted message. Status: STABLE / Reported as working on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1096
+ +
+
+ +

◆ sendDenon()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDenon (uint64_t data,
uint16_t nbits = kDenonBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Denon formatted message. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Some Denon devices use a Kaseikyo/Panasonic 48-bit format Others use the Sharp protocol.
+ +
+
+ +

◆ sendDISH()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDISH (uint64_t data,
uint16_t nbits = kDishBits,
uint16_t repeat = kDishMinRepeat 
)
+
+ +

Send a DISH NETWORK formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Dishplayer is a different protocol. Typically a DISH device needs to get a command a total of at least 4 times to accept it. e.g. repeat=3
+

Here is the LIRC file I found that seems to match the remote codes from the oscilloscope: DISH NETWORK (echostar 301):

See also
http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx
+
+http://www.hifi-remote.com/wiki/index.php?title=Dish
+ +
+
+ +

◆ sendDoshisha()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDoshisha (const uint64_t data,
uint16_t nbits = kDoshishaBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Doshisha formatted message. Status: STABLE / Works on real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendElectraAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendElectraAC (const unsigned char data[],
const uint16_t nbytes = kElectraAcStateLength,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Electra A/C formatted message. Status: Alpha / Needs testing against a real device.

+
Parameters
+ + +
[in]dataThe message to be sent.
+
+
+
Note
Guessing MSBF order.
+
Parameters
+ + + +
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendEpson()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendEpson (uint64_t data,
uint16_t nbits = kEpsonBits,
uint16_t repeat = kEpsonMinRepeat 
)
+
+ +

Send an Epson formatted message. Status: Beta / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of nbits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendFujitsuAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendFujitsuAC (const unsigned char data[],
const uint16_t nbytes,
const uint16_t repeat = kFujitsuAcMinRepeat 
)
+
+ +

Send a Fujitsu A/C formatted message. Status: STABLE / Known Good.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent. Typically one of: kFujitsuAcStateLength, kFujitsuAcStateLength - 1, kFujitsuAcStateLengthShort, kFujitsuAcStateLengthShort - 1
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendGC()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRsend::sendGC (uint16_t buf[],
uint16_t len 
)
+
+ +

Send a shortened GlobalCache (GC) IRdb/control tower formatted message. Status: STABLE / Known working.

+
Parameters
+ + + +
[in]bufArray of uint16_t containing the shortened GlobalCache data.
[in]lenNr. of entries in the buf[] array.
+
+
+
Note
Global Cache format without the emitter ID or request ID. Starts at the frequency (Hertz), followed by nr. of times to emit (count), then the offset for repeats (where a repeat will start from), then the rest of entries are the actual IR message as units of periodic time. e.g. sendir,1:1,1,38000,1,1,9,70,9,30,9,... -> 38000,1,1,9,70,9,30,9,...
+
See also
https://irdb.globalcache.com/Home/Database
+ +
+
+ +

◆ sendGeneric() [1/3]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGeneric (const uint16_t headermark,
const uint32_t headerspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t gap,
const uint32_t mesgtime,
const uint64_t data,
const uint16_t nbits,
const uint16_t frequency,
const bool MSBfirst,
const uint16_t repeat,
const uint8_t dutycycle 
)
+
+ +

Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits is larger than the number of bits in data.

+
Parameters
+ + + + + + + + + + + + + + + + +
[in]headermarkNr. of usecs for the led to be pulsed for the header mark. A value of 0 means no header mark.
[in]headerspaceNr. of usecs for the led to be off after the header mark. A value of 0 means no header space.
[in]onemarkNr. of usecs for the led to be pulsed for a '1' bit.
[in]onespaceNr. of usecs for the led to be fully off for a '1' bit.
[in]zeromarkNr. of usecs for the led to be pulsed for a '0' bit.
[in]zerospaceNr. of usecs for the led to be fully off for a '0' bit.
[in]footermarkNr. of usecs for the led to be pulsed for the footer mark. A value of 0 means no footer mark.
[in]gapNr. of usecs for the led to be off after the footer mark. This is effectively the gap between messages. A value of 0 means no gap space.
[in]mesgtimeMin. nr. of usecs a single message needs to be. This is effectively the min. total length of a single message.
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]frequencyThe frequency we want to modulate at. (Hz/kHz)
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]repeatNr. of extra times the message will be sent. e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages
[in]dutycyclePercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent.
+
+
+
Note
Assumes a frequency < 1000 means kHz otherwise it is in Hz. Most common value is 38000 or 38, for 38kHz.
+ +
+
+ +

◆ sendGeneric() [2/3]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGeneric (const uint16_t headermark,
const uint32_t headerspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t gap,
const uint64_t data,
const uint16_t nbits,
const uint16_t frequency,
const bool MSBfirst,
const uint16_t repeat,
const uint8_t dutycycle 
)
+
+ +

Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits is larger than the number of bits in data.

+
Parameters
+ + + + + + + + + + + + + + + +
[in]headermarkNr. of usecs for the led to be pulsed for the header mark. A value of 0 means no header mark.
[in]headerspaceNr. of usecs for the led to be off after the header mark. A value of 0 means no header space.
[in]onemarkNr. of usecs for the led to be pulsed for a '1' bit.
[in]onespaceNr. of usecs for the led to be fully off for a '1' bit.
[in]zeromarkNr. of usecs for the led to be pulsed for a '0' bit.
[in]zerospaceNr. of usecs for the led to be fully off for a '0' bit.
[in]footermarkNr. of usecs for the led to be pulsed for the footer mark. A value of 0 means no footer mark.
[in]gapNr. of usecs for the led to be off after the footer mark. This is effectively the gap between messages. A value of 0 means no gap space.
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]frequencyThe frequency we want to modulate at. (Hz/kHz)
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]repeatNr. of extra times the message will be sent. e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages
[in]dutycyclePercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent.
+
+
+
Note
Assumes a frequency < 1000 means kHz otherwise it is in Hz. Most common value is 38000 or 38, for 38kHz.
+ +
+
+ +

◆ sendGeneric() [3/3]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGeneric (const uint16_t headermark,
const uint32_t headerspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t gap,
const uint8_t * dataptr,
const uint16_t nbytes,
const uint16_t frequency,
const bool MSBfirst,
const uint16_t repeat,
const uint8_t dutycycle 
)
+
+ +

Generic method for sending simple protocol messages.

+
Parameters
+ + + + + + + + + + + + + + + +
[in]headermarkNr. of usecs for the led to be pulsed for the header mark. A value of 0 means no header mark.
[in]headerspaceNr. of usecs for the led to be off after the header mark. A value of 0 means no header space.
[in]onemarkNr. of usecs for the led to be pulsed for a '1' bit.
[in]onespaceNr. of usecs for the led to be fully off for a '1' bit.
[in]zeromarkNr. of usecs for the led to be pulsed for a '0' bit.
[in]zerospaceNr. of usecs for the led to be fully off for a '0' bit.
[in]footermarkNr. of usecs for the led to be pulsed for the footer mark. A value of 0 means no footer mark.
[in]gapNr. of usecs for the led to be off after the footer mark. This is effectively the gap between messages. A value of 0 means no gap space.
[in]dataptrPointer to the data to be transmitted.
[in]nbytesNr. of bytes of data to be sent.
[in]frequencyThe frequency we want to modulate at. (Hz/kHz)
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]repeatNr. of extra times the message will be sent. e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages
[in]dutycyclePercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent.
+
+
+
Note
Assumes a frequency < 1000 means kHz otherwise it is in Hz. Most common value is 38000 or 38, for 38kHz.
+ +
+
+ +

◆ sendGICable()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGICable (uint64_t data,
uint16_t nbits = kGicableBits,
uint16_t repeat = kGicableMinRepeat 
)
+
+ +

Send a raw G.I. Cable formatted message. Status: Alpha / Untested.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendGoodweather()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGoodweather (const uint64_t data,
const uint16_t nbits = kGoodweatherBits,
const uint16_t repeat = kGoodweatherMinRepeat 
)
+
+ +

Send a Goodweather HVAC formatted message. Status: BETA / Needs testing on real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendGree() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGree (const uint64_t data,
const uint16_t nbits = kGreeBits,
const uint16_t repeat = kGreeDefaultRepeat 
)
+
+ +

Send a Gree Heat Pump formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendGree() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGree (const uint8_t data[],
const uint16_t nbytes = kGreeStateLength,
const uint16_t repeat = kGreeDefaultRepeat 
)
+
+ +

Send a Gree Heat Pump formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendHaierAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHaierAC (const unsigned char data[],
const uint16_t nbytes = kHaierACStateLength,
const uint16_t repeat = kHaierAcDefaultRepeat 
)
+
+ +

Send a Haier A/C formatted message. (HSU07-HEA03 remote) Status: STABLE / Known to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendHaierACYRW02()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHaierACYRW02 (const unsigned char data[],
const uint16_t nbytes = kHaierACYRW02StateLength,
const uint16_t repeat = kHaierAcYrw02DefaultRepeat 
)
+
+ +

Send a Haier YR-W02 remote A/C formatted message. Status: Alpha / Untested on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendHitachiAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAC (const unsigned char data[],
const uint16_t nbytes = kHitachiAcStateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/417
+ +
+
+ +

◆ sendHitachiAC1()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAC1 (const unsigned char data[],
const uint16_t nbytes = kHitachiAc1StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) Status: STABLE / Confirmed Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Basically the same as sendHitatchiAC() except different size & header.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/453
+ +
+
+ +

◆ sendHitachiAC2()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAC2 (const unsigned char data[],
const uint16_t nbytes = kHitachiAc2StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) Basically the same as sendHitatchiAC() except different size. Status: STABLE / Expected to work.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendHitachiAc3()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAc3 (const unsigned char data[],
const uint16_t nbytes,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi(3) A/C formatted message. (HITACHI_AC3) Status: STABLE / Working fine.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is almost exactly the same as HitachiAC424 except this variant has subtle timing differences. There are five(5) typical sizes: kHitachiAc3MinStateLength (Cancel Timer), kHitachiAc3MinStateLength + 2 (Change Temp), kHitachiAc3StateLength - 6 (Change Mode), kHitachiAc3StateLength - 4 (Normal), & kHitachiAc3StateLength (Set Timer)
+ +
+
+ +

◆ sendHitachiAc344()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAc344 (const unsigned char data[],
const uint16_t nbytes = kHitachiAc344StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) Basically the same as sendHitatchiAC() except different size. Status: Beta / Probably works.

+
Parameters
+ + + + +
[in]dataAn array of bytes containing the IR command.
[in]nbytesNr. of bytes of data in the array.
[in]repeatNr. of times the message is to be repeated. (Default = 0).
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1134
+ +
+
+ +

◆ sendHitachiAc424()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAc424 (const unsigned char data[],
const uint16_t nbytes = kHitachiAc424StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) Status: STABLE / Reported as working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is almost exactly the same as HitachiAC2 except this variant has a leader section as well, and subtle timing differences. It is also in LSBF order (per byte), rather than MSBF order.
+ +
+
+ +

◆ sendInax()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendInax (const uint64_t data,
const uint16_t nbits = kInaxBits,
const uint16_t repeat = kInaxMinRepeat 
)
+
+ +

Send a Inax Toilet formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/706
+ +
+
+ +

◆ sendJVC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendJVC (uint64_t data,
uint16_t nbits = kJvcBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a JVC formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
http://www.sbprojects.com/knowledge/ir/jvc.php
+ +
+
+ +

◆ sendKelvinator()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendKelvinator (const unsigned char data[],
const uint16_t nbytes = kKelvinatorStateLength,
const uint16_t repeat = kKelvinatorDefaultRepeat 
)
+
+ +

Send a Kelvinator A/C message. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendLasertag()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLasertag (uint64_t data,
uint16_t nbits = kLasertagBits,
uint16_t repeat = kLasertagMinRepeat 
)
+
+ +

Send a Lasertag packet/message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is pretty much just raw Manchester encoding.
+
Todo:
Convert this to use sendManchester() if we can.`
+ +
+
+ +

◆ sendLegoPf()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLegoPf (const uint64_t data,
const uint16_t nbits = kLegoPfBits,
const uint16_t repeat = kLegoPfMinRepeat 
)
+
+ +

Send a LEGO Power Functions message. Status: Beta / Should work.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Non-zero repeats results in at least 5 messages per spec.
+ +
+
+ +

◆ sendLG()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLG (uint64_t data,
uint16_t nbits = kLgBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send an LG formatted message. (LG) Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent. Typically kLgBits or kLg32Bits.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
LG has a separate message to indicate a repeat, like NEC does.
+ +
+
+ +

◆ sendLG2()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLG2 (uint64_t data,
uint16_t nbits = kLgBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send an LG Variant-2 formatted message. (LG2) Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent. Typically kLgBits or kLg32Bits.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
LG has a separate message to indicate a repeat, like NEC does.
+ +
+
+ +

◆ sendLutron()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLutron (uint64_t data,
uint16_t nbits = kLutronBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Lutron formatted message. Status: Stable / Appears to be working for real devices.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
The protocol is really 36 bits long, but the first bit is always a 1. So, assume the 1 and only have a normal payload of 35 bits.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/515
+ +
+
+ +

◆ sendMagiQuest()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMagiQuest (const uint64_t data,
const uint16_t nbits = kMagiquestBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a MagiQuest formatted message. Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendManchester()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendManchester (const uint16_t headermark,
const uint32_t headerspace,
const uint16_t half_period,
const uint16_t footermark,
const uint32_t gap,
const uint64_t data,
const uint16_t nbits,
const uint16_t frequency = 38,
const bool MSBfirst = true,
const uint16_t repeat = kNoRepeat,
const uint8_t dutycycle = kDutyDefault,
const bool GEThomas = true 
)
+
+ +

Generic method for sending Manchester code messages. Will send leading or trailing 0's if the nbits is larger than the number.

+
Parameters
+ + + + + + + + + + + + + +
[in]headermarkNr. of usecs for the led to be pulsed for the header mark. A value of 0 means no header mark.
[in]headerspaceNr. of usecs for the led to be off after the header mark. A value of 0 means no header space.
[in]half_periodNr. of uSeconds for half the clock's period. (1/2 wavelength)
[in]footermarkNr. of usecs for the led to be pulsed for the footer mark. A value of 0 means no footer mark.
[in]gapMin. nr. of usecs for the led to be off after the footer mark. This is effectively the absolute minimum gap between messages.
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]frequencyThe frequency we want to modulate at. (Hz/kHz)
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]repeatNr. of extra times the message will be sent. e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages
[in]dutycyclePercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent.
[in]GEThomasUse G.E. Thomas (true/default) or IEEE 802.3 (false).
+
+
+
Note
Assumes a frequency < 1000 means kHz otherwise it is in Hz. Most common value is 38000 or 38, for 38kHz.
+ +
+
+ +

◆ sendManchesterData()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendManchesterData (const uint16_t half_period,
const uint64_t data,
const uint16_t nbits,
const bool MSBfirst = true,
const bool GEThomas = true 
)
+
+ +

Generic method for sending Manchester code data. Will send leading or trailing 0's if the nbits is larger than the number of bits in data.

+
Parameters
+ + + + + + +
[in]half_periodNr. of uSeconds for half the clock's period. (1/2 wavelength)
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]GEThomasUse G.E. Thomas (true/default) or IEEE 802.3 (false).
+
+
+ +
+
+ +

◆ sendMidea()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMidea (uint64_t data,
uint16_t nbits = kMideaBits,
uint16_t repeat = kMideaMinRepeat 
)
+
+ +

Send a Midea message Status: Alpha / Needs testing against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMidea24()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMidea24 (const uint64_t data,
const uint16_t nbits = kMidea24Bits,
const uint16_t repeat = kMidea24MinRepeat 
)
+
+ +

Send a Midea24 formatted message. Status: STABLE / Confirmed working on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1170
+
Note
This protocol is basically a 48-bit version of the NEC protocol with alternate bytes inverted, thus only 24 bits of real data, and with at least a single repeat.
+
Warning
Can't be used beyond 32 bits.
+ +
+
+ +

◆ sendMitsubishi()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishi (uint64_t data,
uint16_t nbits = kMitsubishiBits,
uint16_t repeat = kMitsubishiMinRepeat 
)
+
+ +

Send the supplied Mitsubishi 16-bit message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol appears to have no header.
+
See also
https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp
+
+GlobalCache's Control Tower's Mitsubishi TV data.
+ +
+
+ +

◆ sendMitsubishi112()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishi112 (const unsigned char data[],
const uint16_t nbytes = kMitsubishi112StateLength,
const uint16_t repeat = kMitsubishi112MinRepeat 
)
+
+ +

Send a Mitsubishi 112-bit A/C formatted message. (MITSUBISHI112) Status: Stable / Reported as working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/947
+ +
+
+ +

◆ sendMitsubishi136()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishi136 (const unsigned char data[],
const uint16_t nbytes = kMitsubishi136StateLength,
const uint16_t repeat = kMitsubishi136MinRepeat 
)
+
+ +

Send a Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: BETA / Probably working. Needs to be tested against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/888
+ +
+
+ +

◆ sendMitsubishi2()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishi2 (uint64_t data,
uint16_t nbits = kMitsubishiBits,
uint16_t repeat = kMitsubishiMinRepeat 
)
+
+ +

Send a supplied second variant Mitsubishi 16-bit message. Status: BETA / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Based on a Mitsubishi HC3000 projector's remote. This protocol appears to have a manditory in-protocol repeat. That is in addition to the entire message needing to be sent twice for the device to accept the command. That is separate from the repeat. i.e. Allegedly, the real remote requires the "Off" button pressed twice. You will need to add a suitable gap yourself.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/441
+ +
+
+ +

◆ sendMitsubishiAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishiAC (const unsigned char data[],
const uint16_t nbytes = kMitsubishiACStateLength,
const uint16_t repeat = kMitsubishiACMinRepeat 
)
+
+ +

Send a Mitsubishi 144-bit A/C formatted message. (MITSUBISHI_AC) Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMitsubishiHeavy152()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishiHeavy152 (const unsigned char data[],
const uint16_t nbytes = kMitsubishiHeavy152StateLength,
const uint16_t repeat = kMitsubishiHeavy152MinRepeat 
)
+
+ +

Send a MitsubishiHeavy 152-bit A/C message. Status: BETA / Appears to be working. Needs testing against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMitsubishiHeavy88()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishiHeavy88 (const unsigned char data[],
const uint16_t nbytes = kMitsubishiHeavy88StateLength,
const uint16_t repeat = kMitsubishiHeavy88MinRepeat 
)
+
+ +

Send a MitsubishiHeavy 88-bit A/C message. Status: BETA / Appears to be working. Needs testing against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMultibrackets()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMultibrackets (const uint64_t data,
const uint16_t nbits = kMultibracketsBits,
const uint16_t repeat = kMultibracketsDefaultRepeat 
)
+
+ +

Send a Multibrackets formatted message. Status: BETA / Appears to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMWM()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMWM (const unsigned char data[],
const uint16_t nbytes,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a MWM packet/message. Status: Implemented.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is 2400 bps serial, 1 start bit (mark), 1 stop bit (space), no parity
+ +
+
+ +

◆ sendNEC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendNEC (uint64_t data,
uint16_t nbits = kNECBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a raw NEC(Renesas) formatted message. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol appears to have no header.
+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+ +
+
+ +

◆ sendNeoclima()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendNeoclima (const unsigned char data[],
const uint16_t nbytes = kNeoclimaStateLength,
const uint16_t repeat = kNeoclimaMinRepeat 
)
+
+ +

Send a Neoclima message. Status: STABLE / Known to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendNikai()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendNikai (uint64_t data,
uint16_t nbits = kNikaiBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Nikai formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendPanasonic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPanasonic (const uint16_t address,
const uint32_t data,
const uint16_t nbits = kPanasonicBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Panasonic formatted message. Status: STABLE, but DEPRECATED.

+
Deprecated:
This is only for legacy use only, please use sendPanasonic64() instead.
+
Parameters
+ + + + + +
[in]addressThe 16-bit manufacturer code.
[in]dataThe 32-bit data portion of the message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is a modified version of Kaseikyo.
+ +
+
+ +

◆ sendPanasonic64()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPanasonic64 (const uint64_t data,
const uint16_t nbits = kPanasonicBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Panasonic formatted message. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is a modified version of Kaseikyo.
+
+Use this method if you want to send the results of decodePanasonic.
+ +
+
+ +

◆ sendPanasonicAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPanasonicAC (const unsigned char data[],
const uint16_t nbytes = kPanasonicAcStateLength,
const uint16_t repeat = kPanasonicAcDefaultRepeat 
)
+
+ +

Send a Panasonic A/C message. Status: STABLE / Work with real device(s).

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendPioneer()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPioneer (const uint64_t data,
const uint16_t nbits = kPioneerBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a raw Pioneer formatted message. Status: STABLE / Expected to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendPronto()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPronto (uint16_t data[],
uint16_t len,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Pronto Code formatted message. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataAn array of uint16_t containing the pronto codes.
[in]lenNr. of entries in the data[] array.
[in]repeatNr. of times to repeat the message.
+
+
+
Note
Pronto codes are typically represented in hexadecimal. You will need to convert the code to an array of integers, and calculate it's length. e.g.
A Sony 20 bit DVD remote command.
+
"0000 0067 0000 0015 0060 0018 0018 0018 0030 0018 0030 0018 0030 0018
+
0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0030 0018
+
0030 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018
+
0030 0018 0018 03f6"
+
converts to:
uint16_t prontoCode[46] = {
+
0x0000, 0x0067, 0x0000, 0x0015,
+
0x0060, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0030, 0x0018,
+
0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018,
+
0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018,
+
0x0030, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
+
0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018,
+
0x0018, 0x03f6};
+
// Send the Pronto(Sony) code. Repeat twice as Sony's require that.
+
sendPronto(prontoCode, 46, kSonyMinRepeat);
+
+
See also
http://www.etcwiki.org/wiki/Pronto_Infrared_Format
+
+http://www.remotecentral.com/features/irdisp2.htm
+ +
+
+ +

◆ sendRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendRaw (const uint16_t buf[],
const uint16_t len,
const uint16_t hz 
)
+
+ +

Send a raw IRremote message.

+
Parameters
+ + + + +
[in]bufAn array of uint16_t's that has microseconds elements.
[in]lenNr. of elements in the buf[] array.
[in]hzFrequency to send the message at. (kHz < 1000; Hz >= 1000)
+
+
+
Note
Even elements are Mark times (On), Odd elements are Space times (Off). Ref: examples/IRrecvDumpV2/IRrecvDumpV2.ino (or later)
+ +
+
+ +

◆ sendRC5()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendRC5 (const uint64_t data,
uint16_t nbits = kRC5XBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Philips RC-5/RC-5X packet. Status: RC-5 (stable), RC-5X (alpha)

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Caller needs to take care of flipping the toggle bit. That bit differentiates between key press & key release. For RC-5 it is the MSB of the data. For RC-5X it is the 2nd MSB of the data.
+
Todo:
Testing of the RC-5X components.
+ +
+
+ +

◆ sendRC6()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendRC6 (const uint64_t data,
const uint16_t nbits = kRC6Mode0Bits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Philips RC-6 packet. Status: Stable.

+
Note
Caller needs to take care of flipping the toggle bit (The 4th Most Significant Bit). That bit differentiates between key press & key release.
+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendRCMM()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendRCMM (uint64_t data,
uint16_t nbits = kRCMMBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Philips RC-MM packet. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendSAMSUNG()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSAMSUNG (const uint64_t data,
const uint16_t nbits = kSamsungBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a 32-bit Samsung formatted message. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
http://elektrolab.wz.cz/katalog/samsung_protocol.pdf
+
Note
Samsung has a separate message to indicate a repeat, like NEC does.
+
Todo:
Confirm that is actually how Samsung sends a repeat. The refdoc doesn't indicate it is true.
+ +
+
+ +

◆ sendSamsung36()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSamsung36 (const uint64_t data,
const uint16_t nbits = kSamsung36Bits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Samsung 36-bit formatted message. Status: Alpha / Experimental.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/621
+ +
+
+ +

◆ sendSamsungAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSamsungAC (const unsigned char data[],
const uint16_t nbytes = kSamsungAcStateLength,
const uint16_t repeat = kSamsungAcDefaultRepeat 
)
+
+ +

Send a Samsung A/C message. Status: Stable / Known working.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/505
+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendSanyoLC7461()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSanyoLC7461 (const uint64_t data,
const uint16_t nbits = kSanyoLC7461Bits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Sanyo LC7461 message. Status: BETA / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Based on @marcosamarinho's work. This protocol uses the NEC protocol timings. However, data is formatted as : address(13 bits), !address, command (8 bits), !command. According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon Information for this protocol is available at the Sanyo LC7461 datasheet. Repeats are performed similar to the NEC method of sending a special repeat message, rather than duplicating the entire message.
+
See also
https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp
+
+http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf
+ +
+
+ +

◆ sendSharp()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSharp (const uint16_t address,
const uint16_t command,
const uint16_t nbits = kSharpBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Sharp message Status: DEPRECATED / Previously working fine.

+
Deprecated:
Only use this if you are using legacy from the original Arduino-IRremote library. 99% of the time, you will want to use sendSharpRaw() instead
+
Parameters
+ + + + + +
[in]addressAddress value to be sent.
[in]commandCommand value to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This procedure has a non-standard invocation style compared to similar sendProtocol() routines. This is due to legacy, compatibility, & historic reasons. Normally the calling syntax version is like sendSharpRaw(). This procedure transmits the address & command in MSB first order, which is incorrect. This behaviour is left as-is to maintain backward compatibility with legacy code. In short, you should use sendSharpRaw(), encodeSharp(), and the correct values of address & command instead of using this, & the wrong values.
+ +
+
+ +

◆ sendSharpAc()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSharpAc (const unsigned char data[],
const uint16_t nbytes = kSharpAcStateLength,
const uint16_t repeat = kSharpAcDefaultRepeat 
)
+
+ +

Send a Sharp A/C message. Status: Alpha / Untested.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/638
+
+https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp
+ +
+
+ +

◆ sendSharpRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSharpRaw (const uint64_t data,
const uint16_t nbits = kSharpBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a (raw) Sharp message.

+
Note
Status: STABLE / Working fine.
+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
his procedure handles the inversion of bits required per protocol. The protocol spec says to send the LSB first, but legacy code & usage has us sending the MSB first. Grrrr. Normal invocation of encodeSharp() handles this for you, assuming you are using the correct/standard values. e.g. sendSharpRaw(encodeSharp(address, command));
+ +
+
+ +

◆ sendSherwood()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSherwood (uint64_t data,
uint16_t nbits = kSherwoodBits,
uint16_t repeat = kSherwoodMinRepeat 
)
+
+ +

Send an IR command to a Sherwood device. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Sherwood remote codes appear to be NEC codes with a manditory repeat code. i.e. repeat should be >= kSherwoodMinRepeat (1).
+ +
+
+ +

◆ sendSony()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSony (const uint64_t data,
const uint16_t nbits = kSony20Bits,
const uint16_t repeat = kSonyMinRepeat 
)
+
+ +

Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
sendSony() should typically be called with repeat=2 as Sony devices expect the message to be sent at least 3 times.
+ +
+
+ +

◆ sendSony38()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSony38 (const uint64_t data,
const uint16_t nbits = kSony20Bits,
const uint16_t repeat = kSonyMinRepeat + 1 
)
+
+ +

Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
sendSony38() should typically be called with repeat=3 as these Sony devices expect the message to be sent at least 4 times.
+
Warning
Messages send via this method will be detected by this library as just SONY, not SONY_38K as the library has no way to determine the modulation frequency used. Hence, there is no decodeSony38().
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1018
+ +
+
+ +

◆ sendSymphony()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSymphony (uint64_t data,
uint16_t nbits = kSymphonyBits,
uint16_t repeat = kSymphonyDefaultRepeat 
)
+
+ +

Send a Symphony packet. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendTcl112Ac()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendTcl112Ac (const unsigned char data[],
const uint16_t nbytes = kTcl112AcStateLength,
const uint16_t repeat = kTcl112AcDefaultRepeat 
)
+
+ +

Send a TCL 112-bit A/C message. Status: Beta / Probably working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendTeco()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendTeco (const uint64_t data,
const uint16_t nbits = kTecoBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Teco A/C message. Status: Beta / Probably working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendToshibaAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendToshibaAC (const unsigned char data[],
const uint16_t nbytes = kToshibaACStateLength,
const uint16_t repeat = kToshibaACMinRepeat 
)
+
+ +

Send a Toshiba A/C message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendTrotec()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendTrotec (const unsigned char data[],
const uint16_t nbytes = kTrotecStateLength,
const uint16_t repeat = kTrotecDefaultRepeat 
)
+
+ +

Send a Trotec message. Status: Beta / Probably Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendVestelAc()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendVestelAc (const uint64_t data,
const uint16_t nbits = kVestelAcBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Vestel message Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendWhirlpoolAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendWhirlpoolAC (const unsigned char data[],
const uint16_t nbytes = kWhirlpoolAcStateLength,
const uint16_t repeat = kWhirlpoolAcDefaultRepeat 
)
+
+ +

Send a Whirlpool A/C message. Status: BETA / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendWhynter()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendWhynter (const uint64_t data,
const uint16_t nbits = kWhynterBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Whynter message. Status: STABLE.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp
+ +
+
+ +

◆ sendZepeal()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendZepeal (const uint64_t data,
const uint16_t nbits = kZepealBits,
const uint16_t repeat = kZepealMinRepeat 
)
+
+ +

Send a Zepeal formatted message. Status: STABLE / Works on real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe bit size of the message being sent.
[in]repeatThe number of times the message is to be repeated.
+
+
+ +
+
+ +

◆ space()

+ +
+
+ + + + + + + + +
void IRsend::space (uint32_t time)
+
+ +

Turn the pin (LED) off for a given time. Sends an IR space for the specified number of microseconds. A space is no output, so the PWM output is disabled.

+
Parameters
+ + +
[in]timeTime in microseconds (us).
+
+
+ +
+
+ +

◆ toggleRC5()

+ +
+
+ + + + + + + + +
uint64_t IRsend::toggleRC5 (const uint64_t data)
+
+ +

Flip the toggle bit of a Philips RC-5/RC-5X data message. Used to indicate a change of remote button's state. Status: STABLE.

+
Parameters
+ + +
[in]dataThe existing RC-5/RC-5X message.
+
+
+
Returns
A data message suitable for use in sendRC5() with the toggle bit flipped.
+ +
+
+ +

◆ toggleRC6()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::toggleRC6 (const uint64_t data,
const uint16_t nbits = kRC6Mode0Bits 
)
+
+ +

Flip the toggle bit of a Philips RC-6 data message. Used to indicate a change of remote button's state. Status: STABLE / Should work fine.

+
Parameters
+ + + +
[in]dataThe existing RC-6 message.
[in]nbitsNr. of bits in the RC-6 protocol.
+
+
+
Returns
A data message suitable for use in sendRC6() with the toggle bit flipped.
+
Note
For RC-6 (20-bits), it is the 17th least significant bit.
+
+For RC-6 (36-bits/Xbox-360), it is the 16th least significant bit.
+ +
+
+

Member Data Documentation

+ +

◆ _dutycycle

+ +
+
+ + + + + +
+ + + + +
uint8_t IRsend::_dutycycle
+
+private
+
+ +
+
+ +

◆ _freq_unittest

+ +
+
+ + + + + +
+ + + + +
uint32_t IRsend::_freq_unittest
+
+private
+
+ +
+
+ +

◆ IRpin

+ +
+
+ + + + + +
+ + + + +
uint16_t IRsend::IRpin
+
+private
+
+ +
+
+ +

◆ modulation

+ +
+
+ + + + + +
+ + + + +
bool IRsend::modulation
+
+private
+
+ +
+
+ +

◆ offTimePeriod

+ +
+
+ + + + + +
+ + + + +
uint16_t IRsend::offTimePeriod
+
+private
+
+ +
+
+ +

◆ onTimePeriod

+ +
+
+ + + + + +
+ + + + +
uint16_t IRsend::onTimePeriod
+
+private
+
+ +
+
+ +

◆ outputOff

+ +
+
+ + + + + +
+ + + + +
uint8_t IRsend::outputOff
+
+protected
+
+ +
+
+ +

◆ outputOn

+ +
+
+ + + + + +
+ + + + +
uint8_t IRsend::outputOn
+
+protected
+
+ +
+
+ +

◆ periodOffset

+ +
+
+ + + + + +
+ + + + +
int8_t IRsend::periodOffset
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+
void sendPronto(uint16_t data[], uint16_t len, uint16_t repeat=kNoRepeat)
Send a Pronto Code formatted message. Status: STABLE / Known working.
Definition: ir_Pronto.cpp:56
+
const uint16_t kCoronaAcStateLength
Definition: IRremoteESP8266.h:833
+
const uint16_t kSonyMinRepeat
Definition: IRremoteESP8266.h:991
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer-members.html new file mode 100644 index 000000000..b1603a411 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer-members.html @@ -0,0 +1,84 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRtimer Member List
+
+
+ +

This is the complete list of members for IRtimer, including all inherited members.

+ + + + + + +
add(uint32_t usecs)IRtimerstatic
elapsed()IRtimer
IRtimer()IRtimer
reset()IRtimer
startIRtimerprivate
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer.html new file mode 100644 index 000000000..b0d7fac99 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer.html @@ -0,0 +1,235 @@ + + + + + + + +IRremoteESP8266: IRtimer Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

This class performs a simple timer in useconds since instantiated. + More...

+ +

#include <IRtimer.h>

+ + + + + + + + + + + +

+Public Member Functions

 IRtimer ()
 Class constructor. More...
 
void reset ()
 Resets the IRtimer object. More...
 
uint32_t elapsed ()
 Calculate how many microseconds have elapsed since the timer was started. More...
 
+ + + + +

+Static Public Member Functions

static void add (uint32_t usecs)
 Add time to the timer to simulate elapsed time. More...
 
+ + + +

+Private Attributes

uint32_t start
 
+

Detailed Description

+

This class performs a simple timer in useconds since instantiated.

+
Note
Handles when the system timer wraps around (once).
+

Constructor & Destructor Documentation

+ +

◆ IRtimer()

+ +
+
+ + + + + + + +
IRtimer::IRtimer ()
+
+ +

Class constructor.

+ +
+
+

Member Function Documentation

+ +

◆ add()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRtimer::add (uint32_t usecs)
+
+static
+
+ +

Add time to the timer to simulate elapsed time.

+
Parameters
+ + +
[in]usecsNr. of uSeconds to be added.
+
+
+
Note
Only used in unit testing.
+ +
+
+ +

◆ elapsed()

+ +
+
+ + + + + + + +
uint32_t IRtimer::elapsed ()
+
+ +

Calculate how many microseconds have elapsed since the timer was started.

+
Returns
Nr. of microseconds.
+ +
+
+ +

◆ reset()

+ +
+
+ + + + + + + +
void IRtimer::reset ()
+
+ +

Resets the IRtimer object.

+ +
+
+

Member Data Documentation

+ +

◆ start

+ +
+
+ + + + + +
+ + + + +
uint32_t IRtimer::start
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs-members.html new file mode 100644 index 000000000..63f0f8ba0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs-members.html @@ -0,0 +1,84 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
TimerMs Member List
+
+
+ +

This is the complete list of members for TimerMs, including all inherited members.

+ + + + + + +
add(uint32_t msecs)TimerMsstatic
elapsed()TimerMs
reset()TimerMs
startTimerMsprivate
TimerMs()TimerMs
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs.html new file mode 100644 index 000000000..a67791242 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs.html @@ -0,0 +1,235 @@ + + + + + + + +IRremoteESP8266: TimerMs Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

This class performs a simple timer in milli-seoncds since instantiated. + More...

+ +

#include <IRtimer.h>

+ + + + + + + + + + + +

+Public Member Functions

 TimerMs ()
 Class constructor. More...
 
void reset ()
 Resets the TimerMs object. More...
 
uint32_t elapsed ()
 Calculate how many milliseconds have elapsed since the timer was started. More...
 
+ + + + +

+Static Public Member Functions

static void add (uint32_t msecs)
 Add time to the timer to simulate elapsed time. More...
 
+ + + +

+Private Attributes

uint32_t start
 
+

Detailed Description

+

This class performs a simple timer in milli-seoncds since instantiated.

+
Note
Handles when the system timer wraps around (once).
+

Constructor & Destructor Documentation

+ +

◆ TimerMs()

+ +
+
+ + + + + + + +
TimerMs::TimerMs ()
+
+ +

Class constructor.

+ +
+
+

Member Function Documentation

+ +

◆ add()

+ +
+
+ + + + + +
+ + + + + + + + +
void TimerMs::add (uint32_t msecs)
+
+static
+
+ +

Add time to the timer to simulate elapsed time.

+
Parameters
+ + +
[in]msecsNr. of mSeconds to be added.
+
+
+
Note
Only used in unit testing.
+ +
+
+ +

◆ elapsed()

+ +
+
+ + + + + + + +
uint32_t TimerMs::elapsed ()
+
+ +

Calculate how many milliseconds have elapsed since the timer was started.

+
Returns
Nr. of milliseconds.
+ +
+
+ +

◆ reset()

+ +
+
+ + + + + + + +
void TimerMs::reset ()
+
+ +

Resets the TimerMs object.

+ +
+
+

Member Data Documentation

+ +

◆ start

+ +
+
+ + + + + +
+ + + + +
uint32_t TimerMs::start
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results-members.html new file mode 100644 index 000000000..5939b876d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results-members.html @@ -0,0 +1,89 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
decode_results Member List
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results.html new file mode 100644 index 000000000..2028cee12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results.html @@ -0,0 +1,274 @@ + + + + + + + +IRremoteESP8266: decode_results Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
decode_results Class Reference
+
+
+ +

Results returned from the decoder. + More...

+ +

#include <IRrecv.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

decode_type_t decode_type
 
union {
   struct {
      uint64_t   value
 
      uint32_t   address
 
      uint32_t   command
 
   } 
 
   uint8_t   state [kStateSizeMax]
 
}; 
 
uint16_t bits
 
volatile uint16_t * rawbuf
 
uint16_t rawlen
 
bool overflow
 
bool repeat
 
+

Detailed Description

+

Results returned from the decoder.

+

Member Data Documentation

+ +

◆ @2

+ +
+
+ + + + +
union { ... }
+
+ +
+
+ +

◆ address

+ +
+
+ + + + +
uint32_t decode_results::address
+
+ +
+
+ +

◆ bits

+ +
+
+ + + + +
uint16_t decode_results::bits
+
+ +
+
+ +

◆ command

+ +
+
+ + + + +
uint32_t decode_results::command
+
+ +
+
+ +

◆ decode_type

+ +
+
+ + + + +
decode_type_t decode_results::decode_type
+
+ +
+
+ +

◆ overflow

+ +
+
+ + + + +
bool decode_results::overflow
+
+ +
+
+ +

◆ rawbuf

+ +
+
+ + + + +
volatile uint16_t* decode_results::rawbuf
+
+ +
+
+ +

◆ rawlen

+ +
+
+ + + + +
uint16_t decode_results::rawlen
+
+ +
+
+ +

◆ repeat

+ +
+
+ + + + +
bool decode_results::repeat
+
+ +
+
+ +

◆ state

+ +
+
+ + + + +
uint8_t decode_results::state[kStateSizeMax]
+
+ +
+
+ +

◆ value

+ +
+
+ + + + +
uint64_t decode_results::value
+
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classes.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classes.html new file mode 100644 index 000000000..72eebee83 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classes.html @@ -0,0 +1,157 @@ + + + + + + + +IRremoteESP8266: Class Index + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Index
+
+
+
d | i | m | s | t
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  d  
+
IRDaikin160   IRHitachiAc   IRNeoclimaAc   IRWhirlpoolAc   
IRDaikin176   IRHitachiAc1   IRPanasonicAc   
  m  
+
decode_results   IRDaikin2   IRHitachiAc3   irparams_t   
  i  
+
IRDaikin216   IRHitachiAc344   IRrecv   magiquest   
IRDaikin64   IRHitachiAc424   IRSamsungAc   match_result_t   
IRac   IRDaikinESP   IRKelvinatorAC   IRsend   
  s  
+
IRAmcorAc   IRDelonghiAc   IRLgAc   IRSharpAc   
IRArgoAC   IRElectraAc   IRMideaAC   IRTcl112Ac   state_t (stdAc)   
IRCarrierAc64   IRFujitsuAC   IRMitsubishi112   IRTecoAc   
  t  
+
IRCoolixAC   IRGoodweatherAc   IRMitsubishi136   IRtimer   
IRCoronaAc   IRGreeAC   IRMitsubishiAC   IRToshibaAC   TimerMs   
IRDaikin128   IRHaierAC   IRMitsubishiHeavy152Ac   IRTrotecESP   
IRDaikin152   IRHaierACYRW02   IRMitsubishiHeavy88Ac   IRVestelAc   
+
d | i | m | s | t
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/closed.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h.html new file mode 100644 index 000000000..d0cada931 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/de-CH.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
de-CH.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h_source.html new file mode 100644 index 000000000..8ad5119f2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h_source.html @@ -0,0 +1,239 @@ + + + + + + + +IRremoteESP8266: src/locale/de-CH.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
de-CH.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - Martin (@finfinack)
+
2 // Locale/language file for German / Switzerland.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_DE_CH_H_
+
5 #define LOCALE_DE_CH_H_
+
6 
+
7 // Import German / Germany as default overrides.
+
8 #include "locale/de-DE.h"
+
9 
+
10 // As we have loaded another language, we need to #undef anything we need
+
11 // to update/change.
+
12 
+
13 #undef D_STR_ON
+
14 #define D_STR_ON "Ii"
+
15 #undef D_STR_OFF
+
16 #define D_STR_OFF "Us"
+
17 #undef D_STR_TOGGLE
+
18 #define D_STR_TOGGLE "Umschalte"
+
19 #undef D_STR_SLEEP
+
20 #define D_STR_SLEEP "Schlafe"
+
21 #undef D_STR_LIGHT
+
22 #define D_STR_LIGHT "Liecht"
+
23 #undef D_STR_POWERFUL
+
24 #define D_STR_POWERFUL "Starch"
+
25 #undef D_STR_QUIET
+
26 #define D_STR_QUIET "Liislig"
+
27 #undef D_STR_CLEAN
+
28 #define D_STR_CLEAN "Reinige"
+
29 #undef D_STR_PURIFY
+
30 #define D_STR_PURIFY "Frische"
+
31 #undef D_STR_HEALTH
+
32 #define D_STR_HEALTH "Gsundheit"
+
33 #undef D_STR_HUMID
+
34 #define D_STR_HUMID "Füecht"
+
35 #undef D_STR_SAVE
+
36 #define D_STR_SAVE "Speichere"
+
37 #undef D_STR_EYE
+
38 #define D_STR_EYE "Aug"
+
39 #undef D_STR_FOLLOW
+
40 #define D_STR_FOLLOW "Folge"
+
41 #undef D_STR_HOLD
+
42 #define D_STR_HOLD "Halte"
+
43 #undef D_STR_BUTTON
+
44 #define D_STR_BUTTON "Chnopf"
+
45 #undef D_STR_UP
+
46 #define D_STR_UP "Ufe"
+
47 #undef D_STR_TEMPUP
+
48 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
+
49 #undef D_STR_DOWN
+
50 #define D_STR_DOWN "Abe"
+
51 #undef D_STR_TEMPDOWN
+
52 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
+
53 #undef D_STR_CHANGE
+
54 #define D_STR_CHANGE "Wechsele"
+
55 #undef D_STR_MOVE
+
56 #define D_STR_MOVE "Verschiebe"
+
57 #undef D_STR_SET
+
58 #define D_STR_SET "Setze"
+
59 #undef D_STR_CANCEL
+
60 #define D_STR_CANCEL "Abbreche"
+
61 #undef D_STR_WEEKLY
+
62 #define D_STR_WEEKLY "Wüchentlich"
+
63 #undef D_STR_WEEKLYTIMER
+
64 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER
+
65 #undef D_STR_OUTSIDE
+
66 #define D_STR_OUTSIDE "Dusse"
+
67 #undef D_STR_LOUD
+
68 #define D_STR_LOUD "Luut"
+
69 #undef D_STR_UPPER
+
70 #define D_STR_UPPER "Obe"
+
71 #undef D_STR_LOWER
+
72 #define D_STR_LOWER "Une"
+
73 #undef D_STR_CIRCULATE
+
74 #define D_STR_CIRCULATE "Zirkuliere"
+
75 #undef D_STR_CEILING
+
76 #define D_STR_CEILING "Decki"
+
77 #undef D_STR_6THSENSE
+
78 #define D_STR_6THSENSE "6te Sinn"
+
79 
+
80 #undef D_STR_COOL
+
81 #define D_STR_COOL "Chüehle"
+
82 #undef D_STR_HEAT
+
83 #define D_STR_HEAT "Heize"
+
84 #undef D_STR_DRY
+
85 #define D_STR_DRY "Tröchne"
+
86 
+
87 #undef D_STR_MED
+
88 #define D_STR_MED "Mit"
+
89 #undef D_STR_MEDIUM
+
90 #define D_STR_MEDIUM "Mittel"
+
91 
+
92 #undef D_STR_HIGHEST
+
93 #define D_STR_HIGHEST "Höchscht"
+
94 #undef D_STR_HIGH
+
95 #define D_STR_HIGH "Höch"
+
96 #undef D_STR_HI
+
97 #define D_STR_HI "H"
+
98 #undef D_STR_MID
+
99 #define D_STR_MID "M"
+
100 #undef D_STR_MIDDLE
+
101 #define D_STR_MIDDLE "Mittel"
+
102 #undef D_STR_LOW
+
103 #define D_STR_LOW "Tüüf"
+
104 #undef D_STR_LO
+
105 #define D_STR_LO "T"
+
106 #undef D_STR_LOWEST
+
107 #define D_STR_LOWEST "Tüfschte"
+
108 #undef D_STR_MAXRIGHT
+
109 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT
+
110 #undef D_STR_RIGHTMAX_NOSPACE
+
111 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX
+
112 #undef D_STR_MAXLEFT
+
113 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT
+
114 #undef D_STR_LEFTMAX_NOSPACE
+
115 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX
+
116 #undef D_STR_CENTRE
+
117 #define D_STR_CENTRE "Mitti"
+
118 #undef D_STR_TOP
+
119 #define D_STR_TOP "Obe"
+
120 #undef D_STR_BOTTOM
+
121 #define D_STR_BOTTOM "Une"
+
122 
+
123 #undef D_STR_DAY
+
124 #define D_STR_DAY "Tag"
+
125 #undef D_STR_DAYS
+
126 #define D_STR_DAYS "Täg"
+
127 #undef D_STR_HOUR
+
128 #define D_STR_HOUR "Stund"
+
129 #undef D_STR_HOURS
+
130 #define D_STR_HOURS D_STR_HOUR "e"
+
131 #undef D_STR_MINUTE
+
132 #define D_STR_MINUTE "Minute"
+
133 #undef D_STR_MINUTES
+
134 #define D_STR_MINUTES D_STR_MINUTE
+
135 #undef D_STR_SECONDS
+
136 #define D_STR_SECONDS D_STR_SECOND
+
137 #undef D_STR_NOW
+
138 #define D_STR_NOW "Jetz"
+
139 
+
140 #undef D_STR_NO
+
141 #define D_STR_NO "Nei"
+
142 
+
143 #undef D_STR_REPEAT
+
144 #define D_STR_REPEAT "Wiederhole"
+
145 
+
146 // IRrecvDumpV2+
+
147 #undef D_STR_TIMESTAMP
+
148 #define D_STR_TIMESTAMP "Ziitstämpfel"
+
149 #undef D_STR_IRRECVDUMP_STARTUP
+
150 #define D_STR_IRRECVDUMP_STARTUP \
+
151  "IRrecvDump lauft und wartet uf IR Iigab ufem Pin %d"
+
152 #undef D_WARN_BUFFERFULL
+
153 #define D_WARN_BUFFERFULL \
+
154  "WARNUNG: IR Code isch zgross für de Buffer (>= %d). " \
+
155  "Dem Resultat sött mer nöd vertraue bevor das behobe isch. " \
+
156  "Bearbeite & vergrössere `kCaptureBufferSize`."
+
157 
+
158 #endif // LOCALE_DE_CH_H_
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h.html new file mode 100644 index 000000000..2b94c27ea --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/de-DE.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
de-DE.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h_source.html new file mode 100644 index 000000000..f3eda60f6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h_source.html @@ -0,0 +1,206 @@ + + + + + + + +IRremoteESP8266: src/locale/de-DE.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
de-DE.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - Martin (@finfinack)
+
2 // Locale/language file for German / Germany.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_DE_DE_H_
+
5 #define LOCALE_DE_DE_H_
+
6 
+
7 #define D_STR_UNKNOWN "UNBEKANNT"
+
8 #define D_STR_PROTOCOL "Protokoll"
+
9 #define D_STR_ON "Ein"
+
10 #define D_STR_OFF "Aus"
+
11 #define D_STR_MODE "Modus"
+
12 #define D_STR_TOGGLE "Umschalten"
+
13 #define D_STR_SLEEP "Schlafen"
+
14 #define D_STR_LIGHT "Licht"
+
15 #define D_STR_POWERFUL "Stark"
+
16 #define D_STR_QUIET "Ruhig"
+
17 #define D_STR_ECONO "Eco"
+
18 #define D_STR_BEEP "Piep"
+
19 #define D_STR_MOULD "Schimmel"
+
20 #define D_STR_CLEAN "Reinigen"
+
21 #define D_STR_PURIFY "Frischen"
+
22 #define D_STR_TIMER "Timer"
+
23 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER
+
24 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER
+
25 #define D_STR_CLOCK "Uhr"
+
26 #define D_STR_COMMAND "Befehl"
+
27 #define D_STR_HEALTH "Gesundheit"
+
28 #define D_STR_TEMP "Temp"
+
29 #define D_STR_HUMID "Feucht"
+
30 #define D_STR_SAVE "Speichern"
+
31 #define D_STR_EYE "Auge"
+
32 #define D_STR_FOLLOW "Folgen"
+
33 #define D_STR_FRESH "Frisch"
+
34 #define D_STR_HOLD "Halten"
+
35 #define D_STR_BUTTON "Knopf"
+
36 #define D_STR_NIGHT "Nacht"
+
37 #define D_STR_SILENT "Ruhig"
+
38 #define D_STR_UP "Hinauf"
+
39 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
+
40 #define D_STR_DOWN "Hinunter"
+
41 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
+
42 #define D_STR_CHANGE "Wechseln"
+
43 #define D_STR_MOVE "Verschieben"
+
44 #define D_STR_SET "Setzen"
+
45 #define D_STR_CANCEL "Abbrechen"
+
46 #define D_STR_COMFORT "Komfort"
+
47 #define D_STR_WEEKLY "Wöchentlich"
+
48 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER
+
49 #define D_STR_FAST "Schnell"
+
50 #define D_STR_SLOW "Langsam"
+
51 #define D_STR_AIRFLOW "Luftzug"
+
52 #define D_STR_STEP "Schritt"
+
53 #define D_STR_NA "N/A"
+
54 #define D_STR_OUTSIDE "Draussen"
+
55 #define D_STR_LOUD "Laut"
+
56 #define D_STR_UPPER "Oben"
+
57 #define D_STR_LOWER "Unten"
+
58 #define D_STR_BREEZE "Brise"
+
59 #define D_STR_CIRCULATE "Zirkulieren"
+
60 #define D_STR_CEILING "Decke"
+
61 #define D_STR_WALL "Wand"
+
62 #define D_STR_ROOM "Raum"
+
63 #define D_STR_6THSENSE "6ter Sinn"
+
64 #define D_STR_FIXED "Fixiert"
+
65 
+
66 #define D_STR_AUTOMATIC "Automatisch"
+
67 #define D_STR_MANUAL "Manuell"
+
68 #define D_STR_COOL "Kühlen"
+
69 #define D_STR_HEAT "Heizen"
+
70 #define D_STR_FAN "Lüfter"
+
71 #define D_STR_FANONLY "nur_lüfter"
+
72 #define D_STR_DRY "Trocken"
+
73 
+
74 #define D_STR_MED "Mit"
+
75 #define D_STR_MEDIUM "Mittel"
+
76 
+
77 #define D_STR_HIGHEST "Höchste"
+
78 #define D_STR_HIGH "Hoch"
+
79 #define D_STR_HI "H"
+
80 #define D_STR_MID "M"
+
81 #define D_STR_MIDDLE "Mittel"
+
82 #define D_STR_LOW "Tief"
+
83 #define D_STR_LO "T"
+
84 #define D_STR_LOWEST "Tiefste"
+
85 #define D_STR_RIGHT "Rechts"
+
86 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT
+
87 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX
+
88 #define D_STR_LEFT "Links"
+
89 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT
+
90 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX
+
91 #define D_STR_WIDE "Breit"
+
92 #define D_STR_CENTRE "Mitte"
+
93 #define D_STR_TOP "Oben"
+
94 #define D_STR_BOTTOM "Unten"
+
95 
+
96 #define D_STR_DAY "Tag"
+
97 #define D_STR_DAYS D_STR_DAY "e"
+
98 #define D_STR_HOUR "Stunde"
+
99 #define D_STR_HOURS D_STR_HOUR "n"
+
100 #define D_STR_MINUTES D_STR_MINUTE "n"
+
101 #define D_STR_SECOND "Sekunde"
+
102 #define D_STR_SECONDS D_STR_SECOND "n"
+
103 #define D_STR_NOW "Jetzt"
+
104 // These don't translate well to German as typically only 2 letter
+
105 // abbreviations are used. Hence, this is an approximation.
+
106 #define D_STR_THREELETTERDAYS "SonMonDieMitDonFreSam"
+
107 
+
108 #define D_STR_YES "Ja"
+
109 #define D_STR_NO "Nein"
+
110 #define D_STR_TRUE "Wahr"
+
111 #define D_STR_FALSE "Falsch"
+
112 
+
113 #define D_STR_REPEAT "Wiederholen"
+
114 
+
115 // IRrecvDumpV2+
+
116 #define D_STR_TIMESTAMP "Zeitstempel"
+
117 #define D_STR_LIBRARY "Bibliothek"
+
118 #define D_STR_MESGDESC "Nachr. Beschr."
+
119 #define D_STR_IRRECVDUMP_STARTUP \
+
120  "IRrecvDump läuft und wartet auf IR Eingabe auf Pin %d"
+
121 #define D_WARN_BUFFERFULL \
+
122  "WARNUNG: IR Code ist zu gross für Buffer (>= %d). " \
+
123  "Dem Resultat sollte nicht vertraut werden bevor das behoben ist. " \
+
124  "Bearbeite & vergrössere `kCaptureBufferSize`."
+
125 
+
126 #endif // LOCALE_DE_DE_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h.html new file mode 100644 index 000000000..512778196 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/defaults.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
defaults.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h_source.html new file mode 100644 index 000000000..f2cf638b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h_source.html @@ -0,0 +1,838 @@ + + + + + + + +IRremoteESP8266: src/locale/defaults.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
defaults.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // The default text to use throughout the library.
+
3 // The library will use this text if no locale (_IR_LOCALE_) is set or if
+
4 // the locale doesn't define particular values.
+
5 // If they are defined, this file should NOT override them.
+
6 //
+
7 // This file should contain a #define for every translateable/locale dependant
+
8 // string used by the library. Language specific files don't have to include
+
9 // everything.
+
10 //
+
11 // NOTE: ASCII/UTF-8 characters only. Unicode is NOT supported.
+
12 //
+
13 // The defaults are English (AU) / en-AU. Australia (AU) is pretty much the same
+
14 // as English (UK) for this libraries use case.
+
15 #ifndef LOCALE_DEFAULTS_H_
+
16 #define LOCALE_DEFAULTS_H_
+
17 
+
18 #ifndef D_STR_UNKNOWN
+
19 #define D_STR_UNKNOWN "UNKNOWN"
+
20 #endif // D_STR_UNKNOWN
+
21 #ifndef D_STR_PROTOCOL
+
22 #define D_STR_PROTOCOL "Protocol"
+
23 #endif // D_STR_PROTOCOL
+
24 #ifndef D_STR_POWER
+
25 #define D_STR_POWER "Power"
+
26 #endif // D_STR_POWER
+
27 #ifndef D_STR_PREVIOUS
+
28 #define D_STR_PREVIOUS "Previous"
+
29 #endif // D_STR_PREVIOUS
+
30 #ifndef D_STR_ON
+
31 #define D_STR_ON "On"
+
32 #endif // D_STR_ON
+
33 #ifndef D_STR_OFF
+
34 #define D_STR_OFF "Off"
+
35 #endif // D_STR_OFF
+
36 #ifndef D_STR_MODE
+
37 #define D_STR_MODE "Mode"
+
38 #endif // D_STR_MODE
+
39 #ifndef D_STR_TOGGLE
+
40 #define D_STR_TOGGLE "Toggle"
+
41 #endif // D_STR_TOGGLE
+
42 #ifndef D_STR_TURBO
+
43 #define D_STR_TURBO "Turbo"
+
44 #endif // D_STR_TURBO
+
45 #ifndef D_STR_SUPER
+
46 #define D_STR_SUPER "Super"
+
47 #endif // D_STR_SUPER
+
48 #ifndef D_STR_SLEEP
+
49 #define D_STR_SLEEP "Sleep"
+
50 #endif // D_STR_SLEEP
+
51 #ifndef D_STR_LIGHT
+
52 #define D_STR_LIGHT "Light"
+
53 #endif // D_STR_LIGHT
+
54 #ifndef D_STR_POWERFUL
+
55 #define D_STR_POWERFUL "Powerful"
+
56 #endif // D_STR_POWERFUL
+
57 #ifndef D_STR_QUIET
+
58 #define D_STR_QUIET "Quiet"
+
59 #endif // D_STR_QUIET
+
60 #ifndef D_STR_ECONO
+
61 #define D_STR_ECONO "Econo"
+
62 #endif // D_STR_ECONO
+
63 #ifndef D_STR_SWING
+
64 #define D_STR_SWING "Swing"
+
65 #endif // D_STR_SWING
+
66 #ifndef D_STR_SWINGH
+
67 #define D_STR_SWINGH D_STR_SWING"(H)" // Set `D_STR_SWING` first!
+
68 #endif // D_STR_SWINGH
+
69 #ifndef D_STR_SWINGV
+
70 #define D_STR_SWINGV D_STR_SWING"(V)" // Set `D_STR_SWING` first!
+
71 #endif // D_STR_SWINGV
+
72 #ifndef D_STR_BEEP
+
73 #define D_STR_BEEP "Beep"
+
74 #endif // D_STR_BEEP
+
75 #ifndef D_STR_MOULD
+
76 #define D_STR_MOULD "Mould"
+
77 #endif // D_STR_MOULD
+
78 #ifndef D_STR_CLEAN
+
79 #define D_STR_CLEAN "Clean"
+
80 #endif // D_STR_CLEAN
+
81 #ifndef D_STR_PURIFY
+
82 #define D_STR_PURIFY "Purify"
+
83 #endif // D_STR_PURIFY
+
84 #ifndef D_STR_TIMER
+
85 #define D_STR_TIMER "Timer"
+
86 #endif // D_STR_TIMER
+
87 #ifndef D_STR_ONTIMER
+
88 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER // Set `D_STR_ON` first!
+
89 #endif // D_STR_ONTIMER
+
90 #ifndef D_STR_OFFTIMER
+
91 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER // Set `D_STR_OFF` first!
+
92 #endif // D_STR_OFFTIMER
+
93 #ifndef D_STR_CLOCK
+
94 #define D_STR_CLOCK "Clock"
+
95 #endif // D_STR_CLOCK
+
96 #ifndef D_STR_COMMAND
+
97 #define D_STR_COMMAND "Command"
+
98 #endif // D_STR_COMMAND
+
99 #ifndef D_STR_XFAN
+
100 #define D_STR_XFAN "XFan"
+
101 #endif // D_STR_XFAN
+
102 #ifndef D_STR_HEALTH
+
103 #define D_STR_HEALTH "Health"
+
104 #endif // D_STR_HEALTH
+
105 #ifndef D_STR_MODEL
+
106 #define D_STR_MODEL "Model"
+
107 #endif // D_STR_MODEL
+
108 #ifndef D_STR_TEMP
+
109 #define D_STR_TEMP "Temp"
+
110 #endif // D_STR_TEMP
+
111 #ifndef D_STR_IFEEL
+
112 #define D_STR_IFEEL "IFeel"
+
113 #endif // D_STR_IFEEL
+
114 #ifndef D_STR_HUMID
+
115 #define D_STR_HUMID "Humid"
+
116 #endif // D_STR_HUMID
+
117 #ifndef D_STR_SAVE
+
118 #define D_STR_SAVE "Save"
+
119 #endif // D_STR_SAVE
+
120 #ifndef D_STR_EYE
+
121 #define D_STR_EYE "Eye"
+
122 #endif // D_STR_EYE
+
123 #ifndef D_STR_FOLLOW
+
124 #define D_STR_FOLLOW "Follow"
+
125 #endif // D_STR_FOLLOW
+
126 #ifndef D_STR_ION
+
127 #define D_STR_ION "Ion"
+
128 #endif // D_STR_ION
+
129 #ifndef D_STR_FRESH
+
130 #define D_STR_FRESH "Fresh"
+
131 #endif // D_STR_FRESH
+
132 #ifndef D_STR_HOLD
+
133 #define D_STR_HOLD "Hold"
+
134 #endif // D_STR_HOLD
+
135 #ifndef D_STR_8C_HEAT
+
136 #define D_STR_8C_HEAT "8C " D_STR_HEAT // Set `D_STR_HEAT` first!
+
137 #endif // D_STR_8C_HEAT
+
138 #ifndef D_STR_BUTTON
+
139 #define D_STR_BUTTON "Button"
+
140 #endif // D_STR_BUTTON
+
141 #ifndef D_STR_NIGHT
+
142 #define D_STR_NIGHT "Night"
+
143 #endif // D_STR_NIGHT
+
144 #ifndef D_STR_SILENT
+
145 #define D_STR_SILENT "Silent"
+
146 #endif // D_STR_SILENT
+
147 #ifndef D_STR_FILTER
+
148 #define D_STR_FILTER "Filter"
+
149 #endif // D_STR_FILTER
+
150 #ifndef D_STR_3D
+
151 #define D_STR_3D "3D"
+
152 #endif // D_STR_3D
+
153 #ifndef D_STR_CELSIUS
+
154 #define D_STR_CELSIUS "Celsius"
+
155 #endif // D_STR_CELSIUS
+
156 #ifndef D_STR_UP
+
157 #define D_STR_UP "Up"
+
158 #endif // D_STR_UP
+
159 #ifndef D_STR_TEMPUP
+
160 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP // Set `D_STR_TEMP` first!
+
161 #endif // D_STR_TEMPUP
+
162 #ifndef D_STR_DOWN
+
163 #define D_STR_DOWN "Down"
+
164 #endif // D_STR_DOWN
+
165 #ifndef D_STR_TEMPDOWN
+
166 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN // Set `D_STR_TEMP` first!
+
167 #endif // D_STR_TEMPDOWN
+
168 #ifndef D_STR_CHANGE
+
169 #define D_STR_CHANGE "Change"
+
170 #endif // D_STR_CHANGE
+
171 #ifndef D_STR_START
+
172 #define D_STR_START "Start"
+
173 #endif // D_STR_START
+
174 #ifndef D_STR_STOP
+
175 #define D_STR_STOP "Stop"
+
176 #endif // D_STR_STOP
+
177 #ifndef D_STR_MOVE
+
178 #define D_STR_MOVE "Move"
+
179 #endif // D_STR_MOVE
+
180 #ifndef D_STR_SET
+
181 #define D_STR_SET "Set"
+
182 #endif // D_STR_SET
+
183 #ifndef D_STR_CANCEL
+
184 #define D_STR_CANCEL "Cancel"
+
185 #endif // D_STR_CANCEL
+
186 #ifndef D_STR_COMFORT
+
187 #define D_STR_COMFORT "Comfort"
+
188 #endif // D_STR_COMFORT
+
189 #ifndef D_STR_SENSOR
+
190 #define D_STR_SENSOR "Sensor"
+
191 #endif // D_STR_SENSOR
+
192 #ifndef D_STR_DISPLAY
+
193 #define D_STR_DISPLAY "Display"
+
194 #endif // D_STR_DISPLAY
+
195 #ifndef D_STR_WEEKLY
+
196 #define D_STR_WEEKLY "Weekly"
+
197 #endif // D_STR_WEEKLY
+
198 #ifndef D_STR_WEEKLYTIMER
+
199 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER // Needs `D_STR_WEEKLY`!
+
200 #endif // D_STR_WEEKLYTIMER
+
201 #ifndef D_STR_WIFI
+
202 #define D_STR_WIFI "WiFi"
+
203 #endif // D_STR_WIFI
+
204 #ifndef D_STR_LAST
+
205 #define D_STR_LAST "Last"
+
206 #endif // D_STR_LAST
+
207 #ifndef D_STR_FAST
+
208 #define D_STR_FAST "Fast"
+
209 #endif // D_STR_FAST
+
210 #ifndef D_STR_SLOW
+
211 #define D_STR_SLOW "Slow"
+
212 #endif // D_STR_SLOW
+
213 #ifndef D_STR_AIRFLOW
+
214 #define D_STR_AIRFLOW "Air Flow"
+
215 #endif // D_STR_AIRFLOW
+
216 #ifndef D_STR_STEP
+
217 #define D_STR_STEP "Step"
+
218 #endif // D_STR_STEP
+
219 #ifndef D_STR_NA
+
220 #define D_STR_NA "N/A"
+
221 #endif // D_STR_NA
+
222 #ifndef D_STR_INSIDE
+
223 #define D_STR_INSIDE "Inside"
+
224 #endif // D_STR_INSIDE
+
225 #ifndef D_STR_OUTSIDE
+
226 #define D_STR_OUTSIDE "Outside"
+
227 #endif // D_STR_OUTSIDE
+
228 #ifndef D_STR_LOUD
+
229 #define D_STR_LOUD "Loud"
+
230 #endif // D_STR_LOUD
+
231 #ifndef D_STR_UPPER
+
232 #define D_STR_UPPER "Upper"
+
233 #endif // D_STR_UPPER
+
234 #ifndef D_STR_LOWER
+
235 #define D_STR_LOWER "Lower"
+
236 #endif // D_STR_LOWER
+
237 #ifndef D_STR_BREEZE
+
238 #define D_STR_BREEZE "Breeze"
+
239 #endif // D_STR_BREEZE
+
240 #ifndef D_STR_CIRCULATE
+
241 #define D_STR_CIRCULATE "Circulate"
+
242 #endif // D_STR_CIRCULATE
+
243 #ifndef D_STR_CEILING
+
244 #define D_STR_CEILING "Ceiling"
+
245 #endif // D_STR_CEILING
+
246 #ifndef D_STR_WALL
+
247 #define D_STR_WALL "Wall"
+
248 #endif // D_STR_WALL
+
249 #ifndef D_STR_ROOM
+
250 #define D_STR_ROOM "Room"
+
251 #endif // D_STR_ROOM
+
252 #ifndef D_STR_6THSENSE
+
253 #define D_STR_6THSENSE "6th Sense"
+
254 #endif // D_STR_6THSENSE
+
255 #ifndef D_STR_ZONEFOLLOW
+
256 #define D_STR_ZONEFOLLOW "Zone Follow"
+
257 #endif // D_STR_ZONEFOLLOW
+
258 #ifndef D_STR_FIXED
+
259 #define D_STR_FIXED "Fixed"
+
260 #endif // D_STR_FIXED
+
261 
+
262 #ifndef D_STR_AUTO
+
263 #define D_STR_AUTO "Auto"
+
264 #endif // D_STR_AUTO
+
265 #ifndef D_STR_AUTOMATIC
+
266 #define D_STR_AUTOMATIC "Automatic"
+
267 #endif // D_STR_AUTOMATIC
+
268 #ifndef D_STR_MANUAL
+
269 #define D_STR_MANUAL "Manual"
+
270 #endif // D_STR_MANUAL
+
271 #ifndef D_STR_COOL
+
272 #define D_STR_COOL "Cool"
+
273 #endif // D_STR_COOL
+
274 #ifndef D_STR_HEAT
+
275 #define D_STR_HEAT "Heat"
+
276 #endif // D_STR_HEAT
+
277 #ifndef D_STR_FAN
+
278 #define D_STR_FAN "Fan"
+
279 #endif // D_STR_FAN
+
280 #ifndef D_STR_FANONLY
+
281 #define D_STR_FANONLY "fan_only"
+
282 #endif // D_STR_FANONLY
+
283 #ifndef D_STR_DRY
+
284 #define D_STR_DRY "Dry"
+
285 #endif // D_STR_DRY
+
286 
+
287 #ifndef D_STR_MAX
+
288 #define D_STR_MAX "Max"
+
289 #endif // D_STR_MAX
+
290 #ifndef D_STR_MAXIMUM
+
291 #define D_STR_MAXIMUM "Maximum"
+
292 #endif // D_STR_MAXIMUM
+
293 #ifndef D_STR_MIN
+
294 #define D_STR_MIN "Min"
+
295 #endif // D_STR_MIN
+
296 #ifndef D_STR_MINIMUM
+
297 #define D_STR_MINIMUM "Minimum"
+
298 #endif // D_STR_MINIMUM
+
299 #ifndef D_STR_MED
+
300 #define D_STR_MED "Med"
+
301 #endif // D_STR_MED
+
302 #ifndef D_STR_MEDIUM
+
303 #define D_STR_MEDIUM "Medium"
+
304 #endif // D_STR_MEDIUM
+
305 
+
306 #ifndef D_STR_HIGHEST
+
307 #define D_STR_HIGHEST "Highest"
+
308 #endif // D_STR_HIGHEST
+
309 #ifndef D_STR_HIGH
+
310 #define D_STR_HIGH "High"
+
311 #endif // D_STR_HIGH
+
312 #ifndef D_STR_HI
+
313 #define D_STR_HI "Hi"
+
314 #endif // D_STR_HI
+
315 #ifndef D_STR_MID
+
316 #define D_STR_MID "Mid"
+
317 #endif // D_STR_MID
+
318 #ifndef D_STR_MIDDLE
+
319 #define D_STR_MIDDLE "Middle"
+
320 #endif // D_STR_MIDDLE
+
321 #ifndef D_STR_LOW
+
322 #define D_STR_LOW "Low"
+
323 #endif // D_STR_LOW
+
324 #ifndef D_STR_LO
+
325 #define D_STR_LO "Lo"
+
326 #endif // D_STR_LO
+
327 #ifndef D_STR_LOWEST
+
328 #define D_STR_LOWEST "Lowest"
+
329 #endif // D_STR_LOWEST
+
330 #ifndef D_STR_RIGHT
+
331 #define D_STR_RIGHT "Right"
+
332 #endif // D_STR_RIGHT
+
333 #ifndef D_STR_MAXRIGHT
+
334 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT // Set `D_STR_MAX` first!
+
335 #endif // D_STR_MAXRIGHT
+
336 #ifndef D_STR_RIGHTMAX_NOSPACE
+
337 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX // Set `D_STR_MAX` first!
+
338 #endif // D_STR_RIGHTMAX_NOSPACE
+
339 #ifndef D_STR_LEFT
+
340 #define D_STR_LEFT "Left"
+
341 #endif // D_STR_LEFT
+
342 #ifndef D_STR_MAXLEFT
+
343 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT // Set `D_STR_MAX` first!
+
344 #endif // D_STR_MAXLEFT
+
345 #ifndef D_STR_LEFTMAX_NOSPACE
+
346 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX // Set `D_STR_MAX` first!
+
347 #endif // D_STR_LEFTMAX_NOSPACE
+
348 #ifndef D_STR_WIDE
+
349 #define D_STR_WIDE "Wide"
+
350 #endif // D_STR_WIDE
+
351 #ifndef D_STR_CENTRE
+
352 #define D_STR_CENTRE "Centre"
+
353 #endif // D_STR_CENTRE
+
354 #ifndef D_STR_TOP
+
355 #define D_STR_TOP "Top"
+
356 #endif // D_STR_TOP
+
357 #ifndef D_STR_BOTTOM
+
358 #define D_STR_BOTTOM "Bottom"
+
359 #endif // D_STR_BOTTOM
+
360 
+
361 // Compound words/phrases/descriptions from pre-defined words.
+
362 // Note: Obviously these need to be defined *after* their component words.
+
363 #ifndef D_STR_EYEAUTO
+
364 #define D_STR_EYEAUTO D_STR_EYE " " D_STR_AUTO
+
365 #endif // D_STR_EYEAUTO
+
366 #ifndef D_STR_LIGHTTOGGLE
+
367 #define D_STR_LIGHTTOGGLE D_STR_LIGHT " " D_STR_TOGGLE
+
368 #endif // D_STR_LIGHTTOGGLE
+
369 #ifndef D_STR_OUTSIDEQUIET
+
370 #define D_STR_OUTSIDEQUIET D_STR_OUTSIDE " " D_STR_QUIET
+
371 #endif // D_STR_OUTSIDEQUIET
+
372 #ifndef D_STR_POWERTOGGLE
+
373 #define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE
+
374 #endif // D_STR_POWERTOGGLE
+
375 #ifndef D_STR_POWERBUTTON
+
376 #define D_STR_POWERBUTTON D_STR_POWER " " D_STR_BUTTON
+
377 #endif // D_STR_POWERBUTTON
+
378 #ifndef D_STR_PREVIOUSPOWER
+
379 #define D_STR_PREVIOUSPOWER D_STR_PREVIOUS " " D_STR_POWER
+
380 #endif // D_STR_PREVIOUSPOWER
+
381 #ifndef D_STR_DISPLAYTEMP
+
382 #define D_STR_DISPLAYTEMP D_STR_DISPLAY " " D_STR_TEMP
+
383 #endif // D_STR_DISPLAYTEMP
+
384 #ifndef D_STR_SENSORTEMP
+
385 #define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP
+
386 #endif // D_STR_SENSORTEMP
+
387 #ifndef D_STR_SLEEP_TIMER
+
388 #define D_STR_SLEEP_TIMER D_STR_SLEEP " " D_STR_TIMER
+
389 #endif // D_STR_SLEEP_TIMER
+
390 #ifndef D_STR_SWINGVMODE
+
391 #define D_STR_SWINGVMODE D_STR_SWINGV " " D_STR_MODE
+
392 #endif // D_STR_SWINGVMODE
+
393 #ifndef D_STR_SWINGVTOGGLE
+
394 #define D_STR_SWINGVTOGGLE D_STR_SWINGV " " D_STR_TOGGLE
+
395 #endif // D_STR_SWINGVTOGGLE
+
396 
+
397 // Separators
+
398 #ifndef D_CHR_TIME_SEP
+
399 #define D_CHR_TIME_SEP ':'
+
400 #endif // D_CHR_TIME_SEP
+
401 #ifndef D_STR_SPACELBRACE
+
402 #define D_STR_SPACELBRACE " ("
+
403 #endif // D_STR_SPACELBRACE
+
404 #ifndef D_STR_COMMASPACE
+
405 #define D_STR_COMMASPACE ", "
+
406 #endif // D_STR_COMMASPACE
+
407 #ifndef D_STR_COLONSPACE
+
408 #define D_STR_COLONSPACE ": "
+
409 #endif // D_STR_COLONSPACE
+
410 
+
411 #ifndef D_STR_DAY
+
412 #define D_STR_DAY "Day"
+
413 #endif // D_STR_DAY
+
414 #ifndef D_STR_DAYS
+
415 #define D_STR_DAYS D_STR_DAY "s"
+
416 #endif // D_STR_DAYS
+
417 #ifndef D_STR_HOUR
+
418 #define D_STR_HOUR "Hour"
+
419 #endif // D_STR_HOUR
+
420 #ifndef D_STR_HOURS
+
421 #define D_STR_HOURS D_STR_HOUR "s"
+
422 #endif // D_STR_HOURS
+
423 #ifndef D_STR_MINUTE
+
424 #define D_STR_MINUTE "Minute"
+
425 #endif // D_STR_MINUTE
+
426 #ifndef D_STR_MINUTES
+
427 #define D_STR_MINUTES D_STR_MINUTE "s"
+
428 #endif // D_STR_MINUTES
+
429 #ifndef D_STR_SECOND
+
430 #define D_STR_SECOND "Second"
+
431 #endif // D_STR_SECOND
+
432 #ifndef D_STR_SECONDS
+
433 #define D_STR_SECONDS D_STR_SECOND "s"
+
434 #endif // D_STR_SECONDS
+
435 #ifndef D_STR_NOW
+
436 #define D_STR_NOW "Now"
+
437 #endif // D_STR_NOW
+
438 #ifndef D_STR_THREELETTERDAYS
+
439 #define D_STR_THREELETTERDAYS "SunMonTueWedThuFriSat"
+
440 #endif // D_STR_THREELETTERDAYS
+
441 
+
442 #ifndef D_STR_YES
+
443 #define D_STR_YES "Yes"
+
444 #endif // D_STR_YES
+
445 #ifndef D_STR_NO
+
446 #define D_STR_NO "No"
+
447 #endif // D_STR_NO
+
448 #ifndef D_STR_TRUE
+
449 #define D_STR_TRUE "True"
+
450 #endif // D_STR_TRUE
+
451 #ifndef D_STR_FALSE
+
452 #define D_STR_FALSE "False"
+
453 #endif // D_STR_FALSE
+
454 
+
455 #ifndef D_STR_REPEAT
+
456 #define D_STR_REPEAT "Repeat"
+
457 #endif // D_STR_REPEAT
+
458 #ifndef D_STR_CODE
+
459 #define D_STR_CODE "Code"
+
460 #endif // D_STR_CODE
+
461 #ifndef D_STR_BITS
+
462 #define D_STR_BITS "Bits"
+
463 #endif // D_STR_BITS
+
464 
+
465 // Protocols Names
+
466 #ifndef D_STR_AIRWELL
+
467 #define D_STR_AIRWELL "AIRWELL"
+
468 #endif // D_STR_AIRWELL
+
469 #ifndef D_STR_AIWA_RC_T501
+
470 #define D_STR_AIWA_RC_T501 "AIWA_RC_T501"
+
471 #endif // D_STR_AIWA_RC_T501
+
472 #ifndef D_STR_AMCOR
+
473 #define D_STR_AMCOR "AMCOR"
+
474 #endif // D_STR_AMCOR
+
475 #ifndef D_STR_ARGO
+
476 #define D_STR_ARGO "ARGO"
+
477 #endif // D_STR_ARGO
+
478 #ifndef D_STR_CARRIER_AC
+
479 #define D_STR_CARRIER_AC "CARRIER_AC"
+
480 #endif // D_STR_CARRIER_AC
+
481 #ifndef D_STR_CARRIER_AC40
+
482 #define D_STR_CARRIER_AC40 D_STR_CARRIER_AC "40"
+
483 #endif // D_STR_CARRIER_AC40
+
484 #ifndef D_STR_CARRIER_AC64
+
485 #define D_STR_CARRIER_AC64 D_STR_CARRIER_AC "64"
+
486 #endif // D_STR_CARRIER_AC64
+
487 #ifndef D_STR_COOLIX
+
488 #define D_STR_COOLIX "COOLIX"
+
489 #endif // D_STR_COOLIX
+
490 #ifndef D_STR_CORONA_AC
+
491 #define D_STR_CORONA_AC "CORONA_AC"
+
492 #endif // D_STR_CORONA_AC
+
493 #ifndef D_STR_DAIKIN
+
494 #define D_STR_DAIKIN "DAIKIN"
+
495 #endif // D_STR_DAIKIN
+
496 #ifndef D_STR_DAIKIN128
+
497 #define D_STR_DAIKIN128 "DAIKIN128"
+
498 #endif // D_STR_DAIKIN128
+
499 #ifndef D_STR_DAIKIN152
+
500 #define D_STR_DAIKIN152 "DAIKIN152"
+
501 #endif // D_STR_DAIKIN152
+
502 #ifndef D_STR_DAIKIN160
+
503 #define D_STR_DAIKIN160 "DAIKIN160"
+
504 #endif // D_STR_DAIKIN160
+
505 #ifndef D_STR_DAIKIN176
+
506 #define D_STR_DAIKIN176 "DAIKIN176"
+
507 #endif // D_STR_DAIKIN176
+
508 #ifndef D_STR_DAIKIN2
+
509 #define D_STR_DAIKIN2 "DAIKIN2"
+
510 #endif // D_STR_DAIKIN2
+
511 #ifndef D_STR_DAIKIN216
+
512 #define D_STR_DAIKIN216 "DAIKIN216"
+
513 #endif // D_STR_DAIKIN216
+
514 #ifndef D_STR_DAIKIN64
+
515 #define D_STR_DAIKIN64 "DAIKIN64"
+
516 #endif // D_STR_DAIKIN64
+
517 #ifndef D_STR_DELONGHI_AC
+
518 #define D_STR_DELONGHI_AC "DELONGHI_AC"
+
519 #endif // D_STR_DELONGHI_AC
+
520 #ifndef D_STR_DENON
+
521 #define D_STR_DENON "DENON"
+
522 #endif // D_STR_DENON
+
523 #ifndef D_STR_DISH
+
524 #define D_STR_DISH "DISH"
+
525 #endif // D_STR_DISH
+
526 #ifndef D_STR_DOSHISHA
+
527 #define D_STR_DOSHISHA "DOSHISHA"
+
528 #endif // D_STR_DOSHISHA
+
529 #ifndef D_STR_ELECTRA_AC
+
530 #define D_STR_ELECTRA_AC "ELECTRA_AC"
+
531 #endif // D_STR_ELECTRA_AC
+
532 #ifndef D_STR_EPSON
+
533 #define D_STR_EPSON "EPSON"
+
534 #endif // D_STR_EPSON
+
535 #ifndef D_STR_FUJITSU_AC
+
536 #define D_STR_FUJITSU_AC "FUJITSU_AC"
+
537 #endif // D_STR_FUJITSU_AC
+
538 #ifndef D_STR_GICABLE
+
539 #define D_STR_GICABLE "GICABLE"
+
540 #endif // D_STR_GICABLE
+
541 #ifndef D_STR_GLOBALCACHE
+
542 #define D_STR_GLOBALCACHE "GLOBALCACHE"
+
543 #endif // D_STR_GLOBALCACHE
+
544 #ifndef D_STR_GOODWEATHER
+
545 #define D_STR_GOODWEATHER "GOODWEATHER"
+
546 #endif // D_STR_GOODWEATHER
+
547 #ifndef D_STR_GREE
+
548 #define D_STR_GREE "GREE"
+
549 #endif // D_STR_GREE
+
550 #ifndef D_STR_HAIER_AC
+
551 #define D_STR_HAIER_AC "HAIER_AC"
+
552 #endif // D_STR_HAIER_AC
+
553 #ifndef D_STR_HAIER_AC_YRW02
+
554 #define D_STR_HAIER_AC_YRW02 "HAIER_AC_YRW02"
+
555 #endif // D_STR_HAIER_AC_YRW02
+
556 #ifndef D_STR_HITACHI_AC
+
557 #define D_STR_HITACHI_AC "HITACHI_AC"
+
558 #endif // D_STR_HITACHI_AC
+
559 #ifndef D_STR_HITACHI_AC1
+
560 #define D_STR_HITACHI_AC1 "HITACHI_AC1"
+
561 #endif // D_STR_HITACHI_AC1
+
562 #ifndef D_STR_HITACHI_AC2
+
563 #define D_STR_HITACHI_AC2 "HITACHI_AC2"
+
564 #endif // D_STR_HITACHI_AC2
+
565 #ifndef D_STR_HITACHI_AC3
+
566 #define D_STR_HITACHI_AC3 "HITACHI_AC3"
+
567 #endif // D_STR_HITACHI_AC3
+
568 #ifndef D_STR_HITACHI_AC344
+
569 #define D_STR_HITACHI_AC344 "HITACHI_AC344"
+
570 #endif // D_STR_HITACHI_AC344
+
571 #ifndef D_STR_HITACHI_AC424
+
572 #define D_STR_HITACHI_AC424 "HITACHI_AC424"
+
573 #endif // D_STR_HITACHI_AC424
+
574 #ifndef D_STR_INAX
+
575 #define D_STR_INAX "INAX"
+
576 #endif // D_STR_INAX
+
577 #ifndef D_STR_JVC
+
578 #define D_STR_JVC "JVC"
+
579 #endif // D_STR_JVC
+
580 #ifndef D_STR_KELVINATOR
+
581 #define D_STR_KELVINATOR "KELVINATOR"
+
582 #endif // D_STR_KELVINATOR
+
583 #ifndef D_STR_LASERTAG
+
584 #define D_STR_LASERTAG "LASERTAG"
+
585 #endif // D_STR_LASERTAG
+
586 #ifndef D_STR_LEGOPF
+
587 #define D_STR_LEGOPF "LEGOPF"
+
588 #endif // D_STR_LEGOPF
+
589 #ifndef D_STR_LG
+
590 #define D_STR_LG "LG"
+
591 #endif // D_STR_LG
+
592 #ifndef D_STR_LG2
+
593 #define D_STR_LG2 "LG2"
+
594 #endif // D_STR_LG2
+
595 #ifndef D_STR_LUTRON
+
596 #define D_STR_LUTRON "LUTRON"
+
597 #endif // D_STR_LUTRON
+
598 #ifndef D_STR_MAGIQUEST
+
599 #define D_STR_MAGIQUEST "MAGIQUEST"
+
600 #endif // D_STR_MAGIQUEST
+
601 #ifndef D_STR_MIDEA
+
602 #define D_STR_MIDEA "MIDEA"
+
603 #endif // D_STR_MIDEA
+
604 #ifndef D_STR_MIDEA24
+
605 #define D_STR_MIDEA24 "MIDEA24"
+
606 #endif // D_STR_MIDEA24
+
607 #ifndef D_STR_MITSUBISHI
+
608 #define D_STR_MITSUBISHI "MITSUBISHI"
+
609 #endif // D_STR_MITSUBISHI
+
610 #ifndef D_STR_MITSUBISHI112
+
611 #define D_STR_MITSUBISHI112 "MITSUBISHI112"
+
612 #endif // D_STR_MITSUBISHI112
+
613 #ifndef D_STR_MITSUBISHI136
+
614 #define D_STR_MITSUBISHI136 "MITSUBISHI136"
+
615 #endif // D_STR_MITSUBISHI136
+
616 #ifndef D_STR_MITSUBISHI2
+
617 #define D_STR_MITSUBISHI2 "MITSUBISHI2"
+
618 #endif // D_STR_MITSUBISHI2
+
619 #ifndef D_STR_MITSUBISHI_AC
+
620 #define D_STR_MITSUBISHI_AC "MITSUBISHI_AC"
+
621 #endif // D_STR_MITSUBISHI_AC
+
622 #ifndef D_STR_MITSUBISHI_HEAVY_152
+
623 #define D_STR_MITSUBISHI_HEAVY_152 "MITSUBISHI_HEAVY_152"
+
624 #endif // D_STR_MITSUBISHI_HEAVY_152
+
625 #ifndef D_STR_MITSUBISHI_HEAVY_88
+
626 #define D_STR_MITSUBISHI_HEAVY_88 "MITSUBISHI_HEAVY_88"
+
627 #endif // D_STR_MITSUBISHI_HEAVY_88
+
628 #ifndef D_STR_MULTIBRACKETS
+
629 #define D_STR_MULTIBRACKETS "MULTIBRACKETS"
+
630 #endif // D_STR_MULTIBRACKETS
+
631 #ifndef D_STR_MWM
+
632 #define D_STR_MWM "MWM"
+
633 #endif // D_STR_MWM
+
634 #ifndef D_STR_NEC
+
635 #define D_STR_NEC "NEC"
+
636 #endif // D_STR_NEC
+
637 #ifndef D_STR_NEC_LIKE
+
638 #define D_STR_NEC_LIKE D_STR_NEC "_LIKE"
+
639 #endif // D_STR_NEC_LIKE
+
640 #ifndef D_STR_NEC_NON_STRICT
+
641 #define D_STR_NEC_NON_STRICT D_STR_NEC " (NON-STRICT)"
+
642 #endif // D_STR_NEC_NON_STRICT
+
643 #ifndef D_STR_NEOCLIMA
+
644 #define D_STR_NEOCLIMA "NEOCLIMA"
+
645 #endif // D_STR_NEOCLIMA
+
646 #ifndef D_STR_NIKAI
+
647 #define D_STR_NIKAI "NIKAI"
+
648 #endif // D_STR_NIKAI
+
649 #ifndef D_STR_PANASONIC
+
650 #define D_STR_PANASONIC "PANASONIC"
+
651 #endif // D_STR_PANASONIC
+
652 #ifndef D_STR_PANASONIC_AC
+
653 #define D_STR_PANASONIC_AC "PANASONIC_AC"
+
654 #endif // D_STR_PANASONIC_AC
+
655 #ifndef D_STR_PIONEER
+
656 #define D_STR_PIONEER "PIONEER"
+
657 #endif // D_STR_PIONEER
+
658 #ifndef D_STR_PRONTO
+
659 #define D_STR_PRONTO "PRONTO"
+
660 #endif // D_STR_PRONTO
+
661 #ifndef D_STR_RAW
+
662 #define D_STR_RAW "RAW"
+
663 #endif // D_STR_RAW
+
664 #ifndef D_STR_RC5
+
665 #define D_STR_RC5 "RC5"
+
666 #endif // D_STR_RC5
+
667 #ifndef D_STR_RC5X
+
668 #define D_STR_RC5X "RC5X"
+
669 #endif // D_STR_RC5X
+
670 #ifndef D_STR_RC6
+
671 #define D_STR_RC6 "RC6"
+
672 #endif // D_STR_RC6
+
673 #ifndef D_STR_RCMM
+
674 #define D_STR_RCMM "RCMM"
+
675 #endif // D_STR_RCMM
+
676 #ifndef D_STR_SAMSUNG
+
677 #define D_STR_SAMSUNG "SAMSUNG"
+
678 #endif // D_STR_SAMSUNG
+
679 #ifndef D_STR_SAMSUNG36
+
680 #define D_STR_SAMSUNG36 "SAMSUNG36"
+
681 #endif // D_STR_SAMSUNG36
+
682 #ifndef D_STR_SAMSUNG_AC
+
683 #define D_STR_SAMSUNG_AC "SAMSUNG_AC"
+
684 #endif // D_STR_SAMSUNG_AC
+
685 #ifndef D_STR_SANYO
+
686 #define D_STR_SANYO "SANYO"
+
687 #endif // D_STR_SANYO
+
688 #ifndef D_STR_SANYO_LC7461
+
689 #define D_STR_SANYO_LC7461 "SANYO_LC7461"
+
690 #endif // D_STR_SANYO_LC7461
+
691 #ifndef D_STR_SHARP
+
692 #define D_STR_SHARP "SHARP"
+
693 #endif // D_STR_SHARP
+
694 #ifndef D_STR_SHARP_AC
+
695 #define D_STR_SHARP_AC "SHARP_AC"
+
696 #endif // D_STR_SHARP_AC
+
697 #ifndef D_STR_SHERWOOD
+
698 #define D_STR_SHERWOOD "SHERWOOD"
+
699 #endif // D_STR_SHERWOOD
+
700 #ifndef D_STR_SONY
+
701 #define D_STR_SONY "SONY"
+
702 #endif // D_STR_SONY
+
703 #ifndef D_STR_SONY_38K
+
704 #define D_STR_SONY_38K "SONY_38K"
+
705 #endif // D_STR_SONY_38K
+
706 #ifndef D_STR_SYMPHONY
+
707 #define D_STR_SYMPHONY "SYMPHONY"
+
708 #endif // D_STR_SYMPHONY
+
709 #ifndef D_STR_TCL112AC
+
710 #define D_STR_TCL112AC "TCL112AC"
+
711 #endif // D_STR_TCL112AC
+
712 #ifndef D_STR_TECO
+
713 #define D_STR_TECO "TECO"
+
714 #endif // D_STR_TECO
+
715 #ifndef D_STR_TOSHIBA_AC
+
716 #define D_STR_TOSHIBA_AC "TOSHIBA_AC"
+
717 #endif // D_STR_TOSHIBA_AC
+
718 #ifndef D_STR_TROTEC
+
719 #define D_STR_TROTEC "TROTEC"
+
720 #endif // D_STR_TROTEC
+
721 #ifndef D_STR_UNUSED
+
722 #define D_STR_UNUSED "UNUSED"
+
723 #endif // D_STR_UNUSED
+
724 #ifndef D_STR_VESTEL_AC
+
725 #define D_STR_VESTEL_AC "VESTEL_AC"
+
726 #endif // D_STR_VESTEL_AC
+
727 #ifndef D_STR_WHIRLPOOL_AC
+
728 #define D_STR_WHIRLPOOL_AC "WHIRLPOOL_AC"
+
729 #endif // D_STR_WHIRLPOOL_AC
+
730 #ifndef D_STR_WHYNTER
+
731 #define D_STR_WHYNTER "WHYNTER"
+
732 #endif // D_STR_WHYNTER
+
733 #ifndef D_STR_ZEPEAL
+
734 #define D_STR_ZEPEAL "ZEPEAL"
+
735 #endif // D_STR_ZEPEAL
+
736 
+
737 // IRrecvDumpV2+
+
738 #ifndef D_STR_TIMESTAMP
+
739 #define D_STR_TIMESTAMP "Timestamp"
+
740 #endif // D_STR_TIMESTAMP
+
741 #ifndef D_STR_LIBRARY
+
742 #define D_STR_LIBRARY "Library"
+
743 #endif // D_STR_LIBRARY
+
744 #ifndef D_STR_MESGDESC
+
745 #define D_STR_MESGDESC "Mesg Desc."
+
746 #endif // D_STR_MESGDESC
+
747 #ifndef D_STR_IRRECVDUMP_STARTUP
+
748 #define D_STR_IRRECVDUMP_STARTUP \
+
749  "IRrecvDump is now running and waiting for IR input on Pin %d"
+
750 #endif // D_STR_IRRECVDUMP_STARTUP
+
751 #ifndef D_WARN_BUFFERFULL
+
752 #define D_WARN_BUFFERFULL \
+
753  "WARNING: IR code is too big for buffer (>= %d). " \
+
754  "This result shouldn't be trusted until this is resolved. " \
+
755  "Edit & increase `kCaptureBufferSize`."
+
756 #endif // D_WARN_BUFFERFULL
+
757 
+
758 #endif // LOCALE_DEFAULTS_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/deprecated.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/deprecated.html new file mode 100644 index 000000000..58f8129ca --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/deprecated.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Deprecated List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
Deprecated List
+
+
+
+
Member IRsend::sendPanasonic (const uint16_t address, const uint32_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
+
This is only for legacy use only, please use sendPanasonic64() instead.
+
Member IRsend::sendSharp (const uint16_t address, const uint16_t command, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
+
Only use this if you are using legacy from the original Arduino-IRremote library. 99% of the time, you will want to use sendSharpRaw() instead
+
Member resultToTimingInfo (const decode_results *const results)
+
This is only for those that want this legacy format.
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html new file mode 100644 index 000000000..6b30372c6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html @@ -0,0 +1,80 @@ + + + + + + + +IRremoteESP8266: docs Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
docs Directory Reference
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html new file mode 100644 index 000000000..9d915e190 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html @@ -0,0 +1,373 @@ + + + + + + + +IRremoteESP8266: src Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
src Directory Reference
+
+
+ + + + +

+Directories

directory  locale
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  i18n.h [code]
 
file  ir_Airwell.cpp
 Airwell "Manchester code" based protocol. Some other Airwell products use the COOLIX protocol.
 
file  ir_Aiwa.cpp
 Aiwa based protocol. Based off the RC-T501 RCU Inspired by IRremoteESP8266's implementation.
 
file  ir_Amcor.cpp
 Amcor A/C protocol.
 
file  ir_Amcor.h [code]
 Amcor A/C protocol.
 
file  ir_Argo.cpp
 Argo A/C protocol. Controls an Argo Ulisse 13 DCI A/C.
 
file  ir_Argo.h [code]
 Support for Argo Ulisse 13 DCI Mobile Split ACs.
 
file  ir_Carrier.cpp
 Carrier protocols.
 
file  ir_Carrier.h [code]
 Carrier A/C.
 
file  ir_Coolix.cpp
 Coolix A/C / heatpump.
 
file  ir_Coolix.h [code]
 
file  ir_Corona.cpp
 Corona A/C protocol.
 
file  ir_Corona.h [code]
 
file  ir_Daikin.cpp
 Support for Daikin A/C protocols.
 
file  ir_Daikin.h [code]
 Support for Daikin A/C protocols.
 
file  ir_Delonghi.cpp
 Delonghi based protocol.
 
file  ir_Delonghi.h [code]
 Delonghi A/C.
 
file  ir_Denon.cpp
 Denon support Original Denon support added by https://github.com/csBlueChip Ported over by Massimiliano Pinto.
 
file  ir_Dish.cpp
 DISH Network protocol support DISH support originally by Todd Treece.
 
file  ir_Doshisha.cpp
 Doshisha protocol support.
 
file  ir_Electra.cpp
 Support for Electra A/C protocols.
 
file  ir_Electra.h [code]
 Support for Electra A/C protocols.
 
file  ir_Epson.cpp
 Support for Epson protocols. Epson is an NEC-like protocol, except it doesn't use the NEC style repeat.
 
file  ir_Fujitsu.cpp
 Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham & David Conran.
 
file  ir_Fujitsu.h [code]
 Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham.
 
file  ir_GICable.cpp
 G.I. Cable.
 
file  ir_GlobalCache.cpp
 Global Cache IR format sender Originally added by Hisham Khalifa (http://www.hishamkhalifa.com)
 
file  ir_Goodweather.cpp
 Support for Goodweather compatible HVAC protocols.
 
file  ir_Goodweather.h [code]
 Support for Goodweather compatible HVAC protocols.
 
file  ir_Gree.cpp
 Support for Gree A/C protocols.
 
file  ir_Gree.h [code]
 Support for Gree A/C protocols.
 
file  ir_Haier.cpp
 Support for Haier A/C protocols. The specifics of reverse engineering the protocols details:
 
file  ir_Haier.h [code]
 Support for Haier A/C protocols. The specifics of reverse engineering the protocols details:
 
file  ir_Hitachi.cpp
 Support for Hitachi A/C protocols.
 
file  ir_Hitachi.h [code]
 Support for Hitachi A/C protocols.
 
file  ir_Inax.cpp
 Support for the Inax Robot Toilet IR protocols.
 
file  ir_JVC.cpp
 Support for JVC protocols. Originally added by Kristian Lauszus Thanks to zenwheel and other people at the original blog post.
 
file  ir_Kelvinator.cpp
 Support for Kelvinator A/C protocols. Code to emulate IR Kelvinator YALIF remote control unit, which should control at least the following Kelvinator A/C units: KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, KSV70HRC, KSV80HRC.
 
file  ir_Kelvinator.h [code]
 Support for Kelvinator A/C protocols.
 
file  ir_Lasertag.cpp
 Support for Lasertag protocols.
 
file  ir_Lego.cpp
 Support for LEGO protocols.
 
file  ir_LG.cpp
 Support for LG protocols. LG decode originally added by Darryl Smith (based on the JVC protocol) LG send originally added by https://github.com/chaeplin.
 
file  ir_LG.h [code]
 Support for LG protocols.
 
file  ir_Lutron.cpp
 Support for Lutron protocols.
 
file  ir_Magiquest.cpp
 Support for MagiQuest protocols.
 
file  ir_Magiquest.h [code]
 Support for MagiQuest protocols.
 
file  ir_Midea.cpp
 Support for Midea protocols. Midea added by crankyoldgit & bwze. send: bwze/crankyoldgit, decode: crankyoldgit.
 
file  ir_Midea.h [code]
 Support for Midea protocols. Midea added by crankyoldgit & bwze.
 
file  ir_Mitsubishi.cpp
 Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran.
 
file  ir_Mitsubishi.h [code]
 Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran.
 
file  ir_MitsubishiHeavy.cpp
 Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units.
 
file  ir_MitsubishiHeavy.h [code]
 Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units.
 
file  ir_Multibrackets.cpp
 Support for Multibrackets protocols.
 
file  ir_MWM.cpp
 Disney Made With Magic (MWM) Support derived from ir_Lasertag.cpp.
 
file  ir_NEC.cpp
 Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_NEC.h [code]
 Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Neoclima.cpp
 Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy Code by crankyoldgit.
 
file  ir_Neoclima.h [code]
 Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy.
 
file  ir_Nikai.cpp
 Nikai.
 
file  ir_Panasonic.cpp
 Support for Panasonic protocols. Panasonic protocol originally added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
 
file  ir_Panasonic.h [code]
 Support for Panasonic protocols.
 
file  ir_Pioneer.cpp
 Pioneer remote emulation.
 
file  ir_Pronto.cpp
 Pronto code message generation.
 
file  ir_RC5_RC6.cpp
 RC-5 & RC-6 support RC-5 & RC-6 support added from https://github.com/z3t0/Arduino-IRremote RC-5X support added by David Conran.
 
file  ir_RCMM.cpp
 Support for the Phillips RC-MM protocol.
 
file  ir_Samsung.cpp
 Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Samsung.h [code]
 Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Sanyo.cpp
 Support for Sanyo protocols. Sanyo LC7461 support originally by marcosamarinho Sanyo SA 8650B originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Sharp.cpp
 Support for Sharp protocols.
 
file  ir_Sharp.h [code]
 Support for Sharp protocols.
 
file  ir_Sherwood.cpp
 Support for Sherwood protocols.
 
file  ir_Sony.cpp
 Support for Sony SIRC(Serial Infra-Red Control) protocols. Sony originally added from https://github.com/shirriff/Arduino-IRremote/ Updates from marcosamarinho.
 
file  ir_Symphony.cpp
 Support for Symphony protocols.
 
file  ir_Tcl.cpp
 Support for TCL protocols.
 
file  ir_Tcl.h [code]
 Support for TCL protocols.
 
file  ir_Teco.cpp
 Support for Teco protocols.
 
file  ir_Teco.h [code]
 Support for Teco protocols.
 
file  ir_Toshiba.cpp
 Support for Toshiba protocols.
 
file  ir_Toshiba.h [code]
 Support for Toshiba protocols.
 
file  ir_Trotec.cpp
 Support for Trotec protocols.
 
file  ir_Trotec.h [code]
 Support for Trotec protocols.
 
file  ir_Vestel.cpp
 Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.
 
file  ir_Vestel.h [code]
 Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.
 
file  ir_Whirlpool.cpp
 Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.
 
file  ir_Whirlpool.h [code]
 Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.
 
file  ir_Whynter.cpp
 Support for Whynter protocols. Whynter A/C ARC-110WD added by Francesco Meschia Whynter originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Zepeal.cpp
 Support for Zepeal protocol. This protocol uses fixed length bit encoding. Most official information about Zepeal seems to be from Denkyosha.
 
file  IRac.cpp
 
file  IRac.h [code]
 
file  IRrecv.cpp
 
file  IRrecv.h [code]
 
file  IRremoteESP8266.h [code]
 
file  IRsend.cpp
 
file  IRsend.h [code]
 
file  IRtext.cpp
 
file  IRtext.h [code]
 
file  IRtimer.cpp
 
file  IRtimer.h [code]
 
file  IRutils.cpp
 
file  IRutils.h [code]
 
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html new file mode 100644 index 000000000..fc5e7c1db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html @@ -0,0 +1,106 @@ + + + + + + + +IRremoteESP8266: src/locale Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
locale Directory Reference
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  de-CH.h [code]
 
file  de-DE.h [code]
 
file  defaults.h [code]
 
file  en-AU.h [code]
 
file  en-IE.h [code]
 
file  en-UK.h [code]
 
file  en-US.h [code]
 
file  es-ES.h [code]
 
file  fr-FR.h [code]
 
file  it-IT.h [code]
 
file  zh-CN.h [code]
 
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doc.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.css b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.css new file mode 100644 index 000000000..73ecbb2cb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.css @@ -0,0 +1,1771 @@ +/* The standard CSS for doxygen 1.8.17 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +p.reference, p.definition { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +ul.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; + column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +th p.starttd, p.intertd, p.endtd { + font-size: 100%; + font-weight: 700; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +p.interli { +} + +p.interdd { +} + +p.intertd { +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #FFFFFF; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #FFFFFF; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +ul { + overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #FFFFFF; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl, img.inline { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +blockquote.DocNodeRTL { + border-left: 0; + border-right: 2px solid #9CAFD4; + margin: 0 4px 0 24px; + padding: 0 16px 0 12px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight, .memTemplItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: url('nav_f.png'); + background-repeat: repeat-x; + background-color: #E2E8F2; + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-color: #DFE5F1; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + +} + +.overload { + font-family: "courier new",courier,monospace; + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype, .tparams .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir, .tparams .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; +} + +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { + margin-left: 0px; + padding-left: 0px; +} + +dl.section.DocNodeRTL { + margin-right: 0px; + padding-right: 0px; +} + +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; +} + +dl.note.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; +} + +dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; +} + +dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.deprecated.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.todo.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.test.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.bug.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +.PageDocRTL-title div.toc { + float: left !important; + text-align: right; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +.PageDocRTL-title div.toc li { + background-position-x: right !important; + padding-left: 0 !important; + padding-right: 10px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +} + +.PageDocRTL-title div.toc li.level2 { + margin-left: 0 !important; + margin-right: 15px; +} + +.PageDocRTL-title div.toc li.level3 { + margin-left: 0 !important; + margin-right: 30px; +} + +.PageDocRTL-title div.toc li.level4 { + margin-left: 0 !important; + margin-right: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +/* +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTableHead tr { +} + +table.markdownTableBodyLeft td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft { + text-align: left +} + +th.markdownTableHeadRight { + text-align: right +} + +th.markdownTableHeadCenter { + text-align: center +} +*/ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + +.DocNodeRTL { + text-align: right; + direction: rtl; +} + +.DocNodeLTR { + text-align: left; + direction: ltr; +} + +table.DocNodeRTL { + width: auto; + margin-right: 0; + margin-left: auto; +} + +table.DocNodeLTR { + width: auto; + margin-right: auto; + margin-left: 0; +} + +tt, code, kbd, samp +{ + display: inline-block; + direction:ltr; +} +/* @end */ + +u { + text-decoration: underline; +} + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff17d807fd8aa003bed8bb2a69e8f0909592fd1 GIT binary patch literal 3779 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen__index_8md.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen__index_8md.html new file mode 100644 index 000000000..ad1a690b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen__index_8md.html @@ -0,0 +1,76 @@ + + + + + + + +IRremoteESP8266: docs/doxygen_index.md File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
docs/doxygen_index.md File Reference
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dynsections.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dynsections.js new file mode 100644 index 000000000..ea0a7b39a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dynsections.js @@ -0,0 +1,120 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +IRremoteESP8266: src/locale/en-AU.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-AU.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h_source.html new file mode 100644 index 000000000..0484fcd20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h_source.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: src/locale/en-AU.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-AU.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // Locale/language file for English / Australia.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_EN_AU_H_
+
5 #define LOCALE_EN_AU_H_
+
6 // Nothing should really need to be set here, as en-AU is the default
+
7 // locale/language.
+
8 #endif // LOCALE_EN_AU_H__
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h.html new file mode 100644 index 000000000..fe4574abc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/en-IE.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-IE.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h_source.html new file mode 100644 index 000000000..27678a585 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h_source.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: src/locale/en-IE.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-IE.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // Locale/language file for English / Ireland.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_EN_IE_H_
+
5 #define LOCALE_EN_IE_H_
+
6 // Nothing should really need to be set here, as en-IE is the same as en-AU,
+
7 // which is the default locale/language.
+
8 #endif // LOCALE_EN_IE_H__
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h.html new file mode 100644 index 000000000..a18db62c2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/en-UK.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-UK.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h_source.html new file mode 100644 index 000000000..e46cdbc56 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h_source.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: src/locale/en-UK.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-UK.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // Locale/language file for English / United Kingdom.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_EN_UK_H_
+
5 #define LOCALE_EN_UK_H_
+
6 // Nothing should really need to be set here, as en-UK is the same as en-AU,
+
7 // which is the default locale/language.
+
8 #endif // LOCALE_EN_UK_H__
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h.html new file mode 100644 index 000000000..ac8bce965 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/en-US.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-US.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h_source.html new file mode 100644 index 000000000..fd8ed5161 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h_source.html @@ -0,0 +1,93 @@ + + + + + + + +IRremoteESP8266: src/locale/en-US.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-US.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // Locale/language file for English / United States of America.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_EN_US_H_
+
5 #define LOCALE_EN_US_H_
+
6 // Not much should really need to be set here, as English is the default
+
7 // locale/language.
+
8 
+
9 // Overrides to the default.
+
10 #define D_STR_CENTRE "Center"
+
11 #define D_STR_MOULD "Mold"
+
12 
+
13 #endif // LOCALE_EN_US_H__
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h.html new file mode 100644 index 000000000..4d9de7fab --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/es-ES.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
es-ES.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h_source.html new file mode 100644 index 000000000..fe7a1d618 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h_source.html @@ -0,0 +1,216 @@ + + + + + + + +IRremoteESP8266: src/locale/es-ES.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
es-ES.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - Carlos (@charlieyv)
+
2 // Locale/language file for Spanish / Spain.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_ES_ES_H_
+
5 #define LOCALE_ES_ES_H_
+
6 
+
7 #define D_STR_UNKNOWN "DESCONOCIDO"
+
8 #define D_STR_PROTOCOL "Protocolo"
+
9 #define D_STR_POWER "Poder"
+
10 #define D_STR_PREVIOUS "Anterior"
+
11 #define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
+
12 #define D_STR_ON "Encendido"
+
13 #define D_STR_OFF "Apagado"
+
14 #define D_STR_MODE "Modo"
+
15 #define D_STR_TOGGLE "Palanca"
+
16 #define D_STR_SLEEP "Dormir"
+
17 #define D_STR_LIGHT "Luz"
+
18 #define D_STR_POWERFUL "Poderoso"
+
19 #define D_STR_QUIET "Silencio"
+
20 #define D_STR_ECONO "Econo"
+
21 #define D_STR_SWING "Oscilar"
+
22 #define D_STR_SWINGH D_STR_SWING"(H)"
+
23 #define D_STR_SWINGV D_STR_SWING"(V)"
+
24 #define D_STR_BEEP "Bip"
+
25 #define D_STR_MOULD "Molde"
+
26 #define D_STR_CLEAN "Limpiar"
+
27 #define D_STR_PURIFY "Purificar"
+
28 #define D_STR_TIMER "Temporizador"
+
29 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER
+
30 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER
+
31 #define D_STR_CLOCK "Reloj"
+
32 #define D_STR_COMMAND "Comando"
+
33 #define D_STR_HEALTH "Salud"
+
34 #define D_STR_MODEL "Modelo"
+
35 #define D_STR_TEMP "Temperatura"
+
36 #define D_STR_HUMID "Humedo"
+
37 #define D_STR_SAVE "Guardar"
+
38 #define D_STR_EYE "Ojo"
+
39 #define D_STR_FOLLOW "Seguir"
+
40 #define D_STR_FRESH "Fresco"
+
41 #define D_STR_HOLD "Mantener"
+
42 #define D_STR_8C_HEAT "8C " D_STR_HEAT
+
43 #define D_STR_BUTTON "Boton"
+
44 #define D_STR_NIGHT "Noche"
+
45 #define D_STR_SILENT "Silencio"
+
46 #define D_STR_FILTER "Filtro"
+
47 #define D_STR_UP "Arriba"
+
48 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
+
49 #define D_STR_DOWN "Abajo"
+
50 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
+
51 #define D_STR_CHANGE "Cambiar"
+
52 #define D_STR_START "Comenzar"
+
53 #define D_STR_STOP "Parar"
+
54 #define D_STR_MOVE "Mover"
+
55 #define D_STR_SET "Fijar"
+
56 #define D_STR_CANCEL "Cancelar"
+
57 #define D_STR_COMFORT "Comodo"
+
58 #define D_STR_WEEKLY "Semanal"
+
59 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER
+
60 #define D_STR_LAST "Ultimo"
+
61 #define D_STR_FAST "Rapido"
+
62 #define D_STR_SLOW "Lento"
+
63 #define D_STR_AIRFLOW "Flujo de Aire"
+
64 #define D_STR_STEP "Paso"
+
65 #define D_STR_OUTSIDE "Afuera"
+
66 #define D_STR_LOUD "Ruidoso"
+
67 #define D_STR_UPPER "Superior"
+
68 #define D_STR_LOWER "Inferior"
+
69 #define D_STR_BREEZE "Brisa"
+
70 #define D_STR_CIRCULATE "Circular"
+
71 #define D_STR_CEILING "Techo"
+
72 #define D_STR_WALL "Pared"
+
73 #define D_STR_ROOM "Cuarto"
+
74 #define D_STR_6THSENSE "6to. Sentido"
+
75 #define D_STR_ZONEFOLLOW "Zona Seguir"
+
76 #define D_STR_FIXED "Fijo"
+
77 #define D_STR_AUTOMATIC "Automatico"
+
78 #define D_STR_COOL "Frio"
+
79 #define D_STR_HEAT "Calor"
+
80 #define D_STR_FAN "Ventilador"
+
81 #define D_STR_FANONLY "ventilador_solamente"
+
82 #define D_STR_DRY "Seco"
+
83 #define D_STR_MAX "Max"
+
84 #define D_STR_MAXIMUM "Maximo"
+
85 #define D_STR_MIN "Min"
+
86 #define D_STR_MINIMUM "Minimo"
+
87 #define D_STR_MED "Med"
+
88 #define D_STR_MEDIUM "Medio"
+
89 #define D_STR_HIGHEST "Mas Alto"
+
90 #define D_STR_HIGH "Alto"
+
91 #define D_STR_HI D_STR_HIGH
+
92 #define D_STR_MIDDLE "Medio"
+
93 #define D_STR_MID D_STR_MIDDLE
+
94 #define D_STR_LOW "Bajo"
+
95 #define D_STR_LO D_STR_LOW
+
96 #define D_STR_LOWEST "Mas Bajo"
+
97 #define D_STR_RIGHT "Derecha"
+
98 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT
+
99 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX
+
100 #define D_STR_LEFT "Izquierda"
+
101 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT
+
102 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX
+
103 #define D_STR_WIDE "Ancho"
+
104 #define D_STR_CENTRE "Centro"
+
105 #define D_STR_TOP "Tope"
+
106 #define D_STR_BOTTOM "Fondo"
+
107 #define D_STR_DAY "Dia"
+
108 #define D_STR_DAYS D_STR_DAY "s"
+
109 #define D_STR_HOUR "Hora"
+
110 #define D_STR_HOURS D_STR_HOUR "s"
+
111 #define D_STR_MINUTE "Minuto"
+
112 #define D_STR_MINUTES D_STR_MINUTE "s"
+
113 #define D_STR_SECOND "Segundo"
+
114 #define D_STR_SECONDS D_STR_SECOND "s"
+
115 #define D_STR_NOW "Ahora"
+
116 #define D_STR_THREELETTERDAYS "DomLunMarMieJueVieSab"
+
117 #define D_STR_YES "Si"
+
118 #define D_STR_NO "No"
+
119 #define D_STR_TRUE "Cierto"
+
120 #define D_STR_FALSE "Falso"
+
121 #define D_STR_REPEAT "Repetir"
+
122 #define D_STR_CODE "Codigo"
+
123 
+
124 // IRrecvDumpV2+
+
125 #define D_STR_TIMESTAMP "marca de tiempo"
+
126 #define D_STR_LIBRARY "Libreria"
+
127 #define D_STR_IRRECVDUMP_STARTUP \
+
128  "IRrecvDump esta ahora corriendo y esperando por comando IR en Pin %d"
+
129 #ifndef D_WARN_BUFFERFULL
+
130 #define D_WARN_BUFFERFULL \
+
131  "WARNING: Codigo IR es muy grande para el buffer (>= %d). "\
+
132  "Este resultando no debe ser reconocido hasta que esto sea resuelto." \
+
133  "Edite & incremente `kCaptureBufferSize`."
+
134 #endif // D_WARN_BUFFERFULL
+
135 
+
136 #endif // LOCALE_ES_ES_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/files.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/files.html new file mode 100644 index 000000000..b77a4f9f9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/files.html @@ -0,0 +1,194 @@ + + + + + + + +IRremoteESP8266: File List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all files with brief descriptions:
+
[detail level 123]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 docs
  src
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderclosed.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h.html new file mode 100644 index 000000000..14793daa2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/fr-FR.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
fr-FR.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h_source.html new file mode 100644 index 000000000..5913604c0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h_source.html @@ -0,0 +1,197 @@ + + + + + + + +IRremoteESP8266: src/locale/fr-FR.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
fr-FR.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - Mathieu D(@Knackie)
+
2 // Locale/language file for French / Quebec.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_FR_FR_H_
+
5 #define LOCALE_FR_FR_H_
+
6 
+
7 #define D_STR_UNKNOWN "INCONNU"
+
8 #define D_STR_PROTOCOL "Protocole"
+
9 #define D_STR_TOGGLE "Bascule"
+
10 #define D_STR_SLEEP "Pause"
+
11 #define D_STR_LIGHT "Lumière"
+
12 #define D_STR_POWERFUL "Puissance"
+
13 #define D_STR_PREVIOUS "Precedente"
+
14 #define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
+
15 #define D_STR_QUIET "Silence"
+
16 #define D_STR_ECONO "Economie"
+
17 #define D_STR_BEEP "Bip"
+
18 #define D_STR_MOULD "Moule"
+
19 #define D_STR_CLEAN "Nettoyer"
+
20 #define D_STR_PURIFY "Purifier"
+
21 #define D_STR_ON "On"
+
22 #define D_STR_OFF "Off"
+
23 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER
+
24 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER
+
25 #define D_STR_CLOCK "Heure"
+
26 #define D_STR_COMMAND "Commandement"
+
27 #define D_STR_HEALTH "Santé"
+
28 #define D_STR_TEMP "Temporaire"
+
29 #define D_STR_HUMID "Humidité"
+
30 #define D_STR_SAVE "Sauvegarder"
+
31 #define D_STR_EYE "Oeil"
+
32 #define D_STR_FOLLOW "Suivre"
+
33 #define D_STR_FRESH "Frais"
+
34 #define D_STR_HOLD "Maintenir"
+
35 #define D_STR_BUTTON "Bouton"
+
36 #define D_STR_NIGHT "Nuit"
+
37 #define D_STR_SILENT "Silence"
+
38 #define D_STR_UP "En haut"
+
39 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
+
40 #define D_STR_DOWN "En bas"
+
41 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
+
42 #define D_STR_CHANGE "Changement"
+
43 #define D_STR_SET "Mettre"
+
44 #define D_STR_CANCEL "Annuler"
+
45 #define D_STR_COMFORT "Confort"
+
46 #define D_STR_WEEKLY "Chaque semaine"
+
47 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER
+
48 #define D_STR_FAST "Rapide"
+
49 #define D_STR_SLOW "Lent"
+
50 #define D_STR_AIRFLOW "Ebauche"
+
51 #define D_STR_STEP "Etape"
+
52 #define D_STR_OUTSIDE "Plein air"
+
53 #define D_STR_LOUD "Fort"
+
54 #define D_STR_UPPER "Au dessus"
+
55 #define D_STR_LOWER "En dessous"
+
56 #define D_STR_BREEZE "Brise"
+
57 #define D_STR_CIRCULATE "Faire circuler"
+
58 #define D_STR_CEILING "Plafond"
+
59 #define D_STR_WALL "Mur"
+
60 #define D_STR_ROOM "Pièce"
+
61 #define D_STR_6THSENSE "6ter Sens"
+
62 #define D_STR_FIXED "Fixer"
+
63 
+
64 #define D_STR_AUTOMATIC "Automatique"
+
65 #define D_STR_MANUAL "Manuel"
+
66 #define D_STR_COOL "Frais"
+
67 #define D_STR_HEAT "Chaleur"
+
68 #define D_STR_FAN "Ventillateur"
+
69 #define D_STR_FANONLY "Seul_fan"
+
70 #define D_STR_DRY "Sec"
+
71 
+
72 #define D_STR_MEDIUM "Moyen"
+
73 
+
74 #define D_STR_HIGHEST "Le plus haut"
+
75 #define D_STR_HIGH "Haut"
+
76 #define D_STR_HI "H"
+
77 #define D_STR_MID "M"
+
78 #define D_STR_MIDDLE "Moitié"
+
79 #define D_STR_LOW "Bas"
+
80 #define D_STR_LO "B"
+
81 #define D_STR_LOWEST "Le plus bas"
+
82 #define D_STR_RIGHT "Droite"
+
83 #define D_STR_MAX "Max"
+
84 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT
+
85 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX
+
86 #define D_STR_LEFT "Gauche"
+
87 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT
+
88 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX
+
89 #define D_STR_WIDE "Large"
+
90 #define D_STR_TOP "Au-dessus"
+
91 #define D_STR_BOTTOM "En-dessous"
+
92 
+
93 #define D_STR_DAY "Jour"
+
94 #define D_STR_HOUR "Heure"
+
95 #define D_STR_SECOND "Seconde"
+
96 #define D_STR_NOW "Maintenant"
+
97 #define D_STR_THREELETTERDAYS "LunMarMerJeuVenSamDim"
+
98 
+
99 #define D_STR_YES "Oui"
+
100 #define D_STR_NO "Non"
+
101 #define D_STR_TRUE "Vrai"
+
102 #define D_STR_FALSE "Faux"
+
103 
+
104 #define D_STR_REPEAT "Répetition"
+
105 
+
106 // IRrecvDumpV2+
+
107 #define D_STR_TIMESTAMP "Horodatage"
+
108 #define D_STR_LIBRARY "Bibliothèque"
+
109 #define D_STR_MESGDESC "Rèférence"
+
110 #define D_STR_IRRECVDUMP_STARTUP \
+
111  "IRrecvDump fonctionne et attend l’entrée IR sur la broche %d"
+
112 #define D_WARN_BUFFERFULL \
+
113  "ATTENTION: IR Code est trop gros pour le buffer (>= %d). " \
+
114  "Le résultat ne doit pas être approuvé avant que cela soit résolu. " \
+
115  "Modifier et agrandir `kCaptureBufferSize`."
+
116 
+
117 #endif // LOCALE_FR_FR_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions.html new file mode 100644 index 000000000..8c1ce9777 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions.html @@ -0,0 +1,262 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- _ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_a.html new file mode 100644 index 000000000..6b205ec13 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_a.html @@ -0,0 +1,90 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- a -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_b.html new file mode 100644 index 000000000..f6295fb16 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_b.html @@ -0,0 +1,142 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- b -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_c.html new file mode 100644 index 000000000..399846159 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_c.html @@ -0,0 +1,377 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- c -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_d.html new file mode 100644 index 000000000..d430dbd7d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_d.html @@ -0,0 +1,360 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- d -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_e.html new file mode 100644 index 000000000..111809dc6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_e.html @@ -0,0 +1,153 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- e -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_f.html new file mode 100644 index 000000000..2987a747c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_f.html @@ -0,0 +1,98 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- f -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func.html new file mode 100644 index 000000000..03a682390 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func.html @@ -0,0 +1,121 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- _ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_a.html new file mode 100644 index 000000000..f9827ebb4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_a.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_b.html new file mode 100644 index 000000000..7d6b5234b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_b.html @@ -0,0 +1,130 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_c.html new file mode 100644 index 000000000..7f83216f8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_c.html @@ -0,0 +1,356 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- c -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_d.html new file mode 100644 index 000000000..9795c7095 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_d.html @@ -0,0 +1,351 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- d -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_e.html new file mode 100644 index 000000000..bd4c8e138 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_e.html @@ -0,0 +1,150 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- e -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_f.html new file mode 100644 index 000000000..5a3c52eb6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_f.html @@ -0,0 +1,89 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- f -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_g.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_g.html new file mode 100644 index 000000000..96cde27c8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_g.html @@ -0,0 +1,777 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- g -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_h.html new file mode 100644 index 000000000..eac317665 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_h.html @@ -0,0 +1,106 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- h -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_i.html new file mode 100644 index 000000000..67add7234 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_i.html @@ -0,0 +1,258 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_k.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_k.html new file mode 100644 index 000000000..4d4c3a736 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_k.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- k -

    +
  • kelvinator() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_l.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_l.html new file mode 100644 index 000000000..c29455324 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_l.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- l -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_m.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_m.html new file mode 100644 index 000000000..fb1e3e368 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_m.html @@ -0,0 +1,133 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- m -

    +
  • mark() +: IRsend +
  • +
  • markAsSent() +: IRac +
  • +
  • match() +: IRrecv +
  • +
  • matchAtLeast() +: IRrecv +
  • +
  • matchBytes() +: IRrecv +
  • +
  • matchData() +: IRrecv +
  • +
  • matchGeneric() +: IRrecv +
  • +
  • matchGenericConstBitTime() +: IRrecv +
  • +
  • matchManchester() +: IRrecv +
  • +
  • matchManchesterData() +: IRrecv +
  • +
  • matchMark() +: IRrecv +
  • +
  • matchSpace() +: IRrecv +
  • +
  • midea() +: IRac +
  • +
  • minRepeats() +: IRsend +
  • +
  • mitsubishi() +: IRac +
  • +
  • mitsubishi112() +: IRac +
  • +
  • mitsubishi136() +: IRac +
  • +
  • mitsubishiHeavy152() +: IRac +
  • +
  • mitsubishiHeavy88() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_n.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_n.html new file mode 100644 index 000000000..1ed8fdb21 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_n.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- n -

    +
  • neoclima() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_o.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_o.html new file mode 100644 index 000000000..98b0c7c35 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_o.html @@ -0,0 +1,157 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_p.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_p.html new file mode 100644 index 000000000..fb659551b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_p.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- p -

    +
  • panasonic() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_r.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_r.html new file mode 100644 index 000000000..ba2940aba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_r.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- r -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_s.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_s.html new file mode 100644 index 000000000..b94617c0c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_s.html @@ -0,0 +1,1156 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- s -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_t.html new file mode 100644 index 000000000..19764a1f2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_t.html @@ -0,0 +1,297 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- t -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_u.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_u.html new file mode 100644 index 000000000..eb9d2cbfa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_u.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- u -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_v.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_v.html new file mode 100644 index 000000000..5c3693e4f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_v.html @@ -0,0 +1,119 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_w.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_w.html new file mode 100644 index 000000000..863296b9e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_w.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- w -

    +
  • whirlpool() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_~.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_~.html new file mode 100644 index 000000000..be24e6f9f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_~.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- ~ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_g.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_g.html new file mode 100644 index 000000000..d62a98dee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_g.html @@ -0,0 +1,777 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- g -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_h.html new file mode 100644 index 000000000..327b474a4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_h.html @@ -0,0 +1,109 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- h -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_i.html new file mode 100644 index 000000000..fa40ebe60 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_i.html @@ -0,0 +1,265 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_k.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_k.html new file mode 100644 index 000000000..d234e9b83 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_k.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- k -

    +
  • kelvinator() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_l.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_l.html new file mode 100644 index 000000000..e97cda96f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_l.html @@ -0,0 +1,97 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- l -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_m.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_m.html new file mode 100644 index 000000000..7a5beaee5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_m.html @@ -0,0 +1,148 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- m -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_n.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_n.html new file mode 100644 index 000000000..76f6bd78a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_n.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- n -

    +
  • neoclima() +: IRac +
  • +
  • next +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_o.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_o.html new file mode 100644 index 000000000..59c01849d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_o.html @@ -0,0 +1,173 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_p.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_p.html new file mode 100644 index 000000000..d52453d58 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_p.html @@ -0,0 +1,94 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- p -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_q.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_q.html new file mode 100644 index 000000000..82dc51deb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_q.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- q -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_r.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_r.html new file mode 100644 index 000000000..ede8716ba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_r.html @@ -0,0 +1,151 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- r -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_rela.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_rela.html new file mode 100644 index 000000000..568f1564c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_rela.html @@ -0,0 +1,77 @@ + + + + + + + +IRremoteESP8266: Class Members - Related Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_s.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_s.html new file mode 100644 index 000000000..91e9f3159 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_s.html @@ -0,0 +1,1193 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- s -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_t.html new file mode 100644 index 000000000..64393dccc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_t.html @@ -0,0 +1,309 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- t -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_u.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_u.html new file mode 100644 index 000000000..aeda54c2d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_u.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- u -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_v.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_v.html new file mode 100644 index 000000000..3ef7c39c6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_v.html @@ -0,0 +1,122 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- v -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars.html new file mode 100644 index 000000000..1eb24f7c7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars.html @@ -0,0 +1,563 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- _ -

+ + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- h -

+ + +

- i -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- q -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+ + +

- w -

+ + +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_a.html new file mode 100644 index 000000000..420e56269 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_a.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_b.html new file mode 100644 index 000000000..0a3196ab1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_b.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- b -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_c.html new file mode 100644 index 000000000..2def7a087 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_c.html @@ -0,0 +1,97 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- c -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_d.html new file mode 100644 index 000000000..9a9ddc836 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_d.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- d -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_e.html new file mode 100644 index 000000000..0cab373d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_e.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- e -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_f.html new file mode 100644 index 000000000..a53f124b0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_f.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- f -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_h.html new file mode 100644 index 000000000..d365bf7e4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_h.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- h -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_i.html new file mode 100644 index 000000000..000576cfe --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_i.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_l.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_l.html new file mode 100644 index 000000000..a8027a466 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_l.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- l -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_m.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_m.html new file mode 100644 index 000000000..2959960d3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_m.html @@ -0,0 +1,91 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- m -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_n.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_n.html new file mode 100644 index 000000000..598b08dd6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_n.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- n -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_o.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_o.html new file mode 100644 index 000000000..82097786b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_o.html @@ -0,0 +1,92 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- o -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_p.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_p.html new file mode 100644 index 000000000..997a6d00c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_p.html @@ -0,0 +1,91 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- p -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_q.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_q.html new file mode 100644 index 000000000..21d49182e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_q.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- q -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_r.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_r.html new file mode 100644 index 000000000..8a7baf613 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_r.html @@ -0,0 +1,140 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_s.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_s.html new file mode 100644 index 000000000..0518f87fc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_s.html @@ -0,0 +1,113 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- s -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_t.html new file mode 100644 index 000000000..2ed112f2c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_t.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- t -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_u.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_u.html new file mode 100644 index 000000000..a52e0c8a4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_u.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- u -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_v.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_v.html new file mode 100644 index 000000000..094dd4c27 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_v.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- v -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_w.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_w.html new file mode 100644 index 000000000..9da5476dd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_w.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- w -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_z.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_z.html new file mode 100644 index 000000000..a3501487e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_z.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_w.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_w.html new file mode 100644 index 000000000..efd7bd622 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_w.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- w -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_z.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_z.html new file mode 100644 index 000000000..2b16d459f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_z.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_~.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_~.html new file mode 100644 index 000000000..dc46b16b7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_~.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- ~ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals.html new file mode 100644 index 000000000..7ea1c71d3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- _ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_a.html new file mode 100644 index 000000000..ae8115d60 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_a.html @@ -0,0 +1,106 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- a -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_c.html new file mode 100644 index 000000000..121baa0db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_c.html @@ -0,0 +1,100 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- c -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_d.html new file mode 100644 index 000000000..34d34bc20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_d.html @@ -0,0 +1,121 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- d -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_e.html new file mode 100644 index 000000000..d7bb8acf2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_e.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- e -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_enum.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_enum.html new file mode 100644 index 000000000..2b3c7b53b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_enum.html @@ -0,0 +1,95 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_eval.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_eval.html new file mode 100644 index 000000000..41fffa21e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_eval.html @@ -0,0 +1,493 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- j -

+ + +

- k -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+ + +

- w -

+ + +

- y -

+ + +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_f.html new file mode 100644 index 000000000..d57b47a26 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_f.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- f -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_func.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_func.html new file mode 100644 index 000000000..1d31640cb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_func.html @@ -0,0 +1,184 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- c -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- x -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_g.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_g.html new file mode 100644 index 000000000..27ae53537 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_g.html @@ -0,0 +1,98 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- g -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_h.html new file mode 100644 index 000000000..fb077717b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_h.html @@ -0,0 +1,107 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- h -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_i.html new file mode 100644 index 000000000..4a0b8d8b6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_i.html @@ -0,0 +1,92 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_j.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_j.html new file mode 100644 index 000000000..7c90ed62d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_j.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- j -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_k.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_k.html new file mode 100644 index 000000000..a84fe0e7f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_k.html @@ -0,0 +1,7825 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- k -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_l.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_l.html new file mode 100644 index 000000000..7e56f59c1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_l.html @@ -0,0 +1,94 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- l -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_m.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_m.html new file mode 100644 index 000000000..57d34e5a0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_m.html @@ -0,0 +1,112 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- m -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_n.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_n.html new file mode 100644 index 000000000..715ffa0f0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_n.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- n -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_p.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_p.html new file mode 100644 index 000000000..e3df36e7f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_p.html @@ -0,0 +1,91 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- p -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_r.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_r.html new file mode 100644 index 000000000..7d4e405db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_r.html @@ -0,0 +1,121 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- r -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_s.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_s.html new file mode 100644 index 000000000..78989d651 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_s.html @@ -0,0 +1,124 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- s -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_t.html new file mode 100644 index 000000000..8c16fa974 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_t.html @@ -0,0 +1,92 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- t -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_type.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_type.html new file mode 100644 index 000000000..5f3e05a75 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_type.html @@ -0,0 +1,77 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_u.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_u.html new file mode 100644 index 000000000..860d132a7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_u.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- u -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_v.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_v.html new file mode 100644 index 000000000..5adfbfdf9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_v.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- v -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars.html new file mode 100644 index 000000000..4db0b55aa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- _ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_i.html new file mode 100644 index 000000000..47c235016 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_i.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_k.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_k.html new file mode 100644 index 000000000..48f17baeb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_k.html @@ -0,0 +1,7798 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- k -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_w.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_w.html new file mode 100644 index 000000000..5a333bf99 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_w.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- w -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_x.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_x.html new file mode 100644 index 000000000..714a73193 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_x.html @@ -0,0 +1,80 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- x -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_y.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_y.html new file mode 100644 index 000000000..f28dd18c0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_y.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- y -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_z.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_z.html new file mode 100644 index 000000000..3a092ec10 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_z.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.html new file mode 100644 index 000000000..8a04ec5bb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.html @@ -0,0 +1,136 @@ + + + + + + + +IRremoteESP8266: Graph Legend + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Graph Legend
+
+
+

This page explains how to interpret the graphs that are generated by doxygen.

+

Consider the following example:

/*! Invisible class because of truncation */
+
class Invisible { };
+
+
/*! Truncated class, inheritance relation is hidden */
+
class Truncated : public Invisible { };
+
+
/* Class not documented with doxygen comments */
+
class Undocumented { };
+
+
/*! Class that is inherited using public inheritance */
+
class PublicBase : public Truncated { };
+
+
/*! A template class */
+
template<class T> class Templ { };
+
+
/*! Class that is inherited using protected inheritance */
+
class ProtectedBase { };
+
+
/*! Class that is inherited using private inheritance */
+
class PrivateBase { };
+
+
/*! Class that is used by the Inherited class */
+
class Used { };
+
+
/*! Super class that inherits a number of other classes */
+
class Inherited : public PublicBase,
+
protected ProtectedBase,
+
private PrivateBase,
+
public Undocumented,
+
public Templ<int>
+
{
+
private:
+
Used *m_usedClass;
+
};
+

This will result in the following graph:

+

The boxes in the above graph have the following meaning:

+
    +
  • +A filled gray box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a gray border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+

The arrows have the following meaning:

+
    +
  • +A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labelled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labelled with the template parameters of the instance.
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.md5 new file mode 100644 index 000000000..8fcdccd1b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.md5 @@ -0,0 +1 @@ +f51bf6e9a10430aafef59831b08dcbfe \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.png new file mode 100644 index 0000000000000000000000000000000000000000..7e2cbcfb2d143e382be6ed65635a3d859e53bc36 GIT binary patch literal 20615 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 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/hierarchy.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/hierarchy.html new file mode 100644 index 000000000..225996d27 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/hierarchy.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: Class Hierarchy + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+
+
+

Go to the graphical class hierarchy

+This inheritance list is sorted roughly, but not completely, alphabetically:
+
[detail level 12]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Cdecode_resultsResults returned from the decoder
 CIRac
 CIRAmcorAcClass for handling detailed Amcor A/C messages
 CIRArgoACClass for handling detailed Argo A/C messages
 CIRCarrierAc64Class for handling detailed Carrier 64 bit A/C messages
 CIRCoolixACClass for handling detailed Coolix A/C messages
 CIRCoronaAcClass for handling detailed Corona A/C messages
 CIRDaikin128Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena
 CIRDaikin152Class for handling detailed Daikin 152-bit A/C messages
 CIRDaikin160Class for handling detailed Daikin 160-bit A/C messages
 CIRDaikin176Class for handling detailed Daikin 176-bit A/C messages
 CIRDaikin2Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99
 CIRDaikin216Class for handling detailed Daikin 216-bit A/C messages
 CIRDaikin64Class for handling detailed Daikin 64-bit A/C messages
 CIRDaikinESPClass for handling detailed Daikin 280-bit A/C messages
 CIRDelonghiAcClass for handling detailed Delonghi A/C messages
 CIRElectraAcClass for handling detailed Electra A/C messages
 CIRFujitsuACClass for handling detailed Fujitsu A/C messages
 CIRGoodweatherAcClass for handling detailed Goodweather A/C messages
 CIRGreeACClass for handling detailed Gree A/C messages
 CIRHaierACClass for handling detailed Haier A/C messages
 CIRHaierACYRW02Class for handling detailed Haier ACYRW02 A/C messages
 CIRHitachiAcClass for handling detailed Hitachi 224-bit A/C messages
 CIRHitachiAc1Class for handling detailed Hitachi 104-bit A/C messages
 CIRHitachiAc3Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages
 CIRHitachiAc424Class for handling detailed Hitachi 53-byte/424-bit A/C messages
 CIRHitachiAc344Class for handling detailed Hitachi 344-bit A/C messages
 CIRKelvinatorACClass for handling detailed Kelvinator A/C messages
 CIRLgAcClass for handling detailed LG A/C messages
 CIRMideaACClass for handling detailed Midea A/C messages
 CIRMitsubishi112
 CIRMitsubishi136Class for handling detailed Mitsubishi 136-bit A/C messages
 CIRMitsubishiACClass for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control
 CIRMitsubishiHeavy152AcClass for handling detailed Mitsubishi Heavy 152-bit A/C messages
 CIRMitsubishiHeavy88AcClass for handling detailed Mitsubishi Heavy 88-bit A/C messages
 CIRNeoclimaAcClass for handling detailed Neoclima A/C messages
 CIRPanasonicAcClass for handling detailed Panasonic A/C messages
 Cirparams_tInformation for the interrupt handler
 CIRrecvClass for receiving IR messages
 CIRSamsungAcClass for handling detailed Samsung A/C messages
 CIRsendClass for sending all basic IR protocols
 CIRSharpAcClass for handling detailed Sharp A/C messages
 CIRTcl112AcClass for handling detailed TCL A/C messages
 CIRTecoAcClass for handling detailed Teco A/C messages
 CIRtimerThis class performs a simple timer in useconds since instantiated
 CIRToshibaACClass for handling detailed Toshiba A/C messages
 CIRTrotecESPClass for handling detailed Trotec A/C messages
 CIRVestelAcClass for handling detailed Vestel A/C messages
 CIRWhirlpoolAcClass for handling detailed Whirlpool A/C messages
 CmagiquestMagiQuest packet is both Wand ID and magnitude of swish and flick
 Cmatch_result_tResults from a data match
 CstdAc::state_tStructure to hold a common A/C state
 CTimerMsThis class performs a simple timer in milli-seoncds since instantiated
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h.html new file mode 100644 index 000000000..74c2dc9e0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/i18n.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
i18n.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h_source.html new file mode 100644 index 000000000..d0ee17951 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h_source.html @@ -0,0 +1,107 @@ + + + + + + + +IRremoteESP8266: src/i18n.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
i18n.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 
+
3 #ifndef I18N_H_
+
4 #define I18N_H_
+
5 
+
6 #include "IRremoteESP8266.h"
+
7 
+
8 // Load the appropriate locale header file.
+
9 #ifndef _IR_LOCALE_
+
10 #define _IR_LOCALE_ en-AU
+
11 #endif // _IR_LOCALE_
+
12 
+
13 #define ENQUOTE_(x) #x
+
14 #define ENQUOTE(x) ENQUOTE_(x)
+
15 
+
16 // Load the desired/requested locale.
+
17 #ifdef _IR_LOCALE_
+
18 #include ENQUOTE(locale/_IR_LOCALE_.h)
+
19 #endif // _IR_LOCALE_
+
20 
+
21 // Now that any specific locale has been loaded, we can safely load the defaults
+
22 // as the defaults should not override anything that has now set.
+
23 #include "locale/defaults.h"
+
24 
+
25 #endif // I18N_H_
+
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/index.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/index.html new file mode 100644 index 000000000..42934a359 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/index.html @@ -0,0 +1,104 @@ + + + + + + + +IRremoteESP8266: IRremoteESP8266 Library API Documentation + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
IRremoteESP8266 Library API Documentation
+
+
+

+Getting Started

+

+The basics

+

For sending messages, look at the IRsend class.

+

For receiving messages, look at the IRrecv & decode_results classes.

+

+Air Conditioners

+

For generic Air Conditioner control, look at the IRac class & the stdAc::state_t structure.

+

For detailed Air Conditioner control, you need to determine what protocol the library detects your remote/Air Conditioner to be, look into the appropriate src/ir_Protocol.[h|cpp] files and use the appropriate class object. e.g. if IRrecvDumpV2 (or better) detects the protocol as KELVINATOR, open the src/ir_Kelvinator.* files, and examine the IRKelvinatorAC class the methods available to create/decode/send KELVINATOR messages with all the abilities the library offers. You can also select it from the Classes menu above.

+

Various native constants & options for a given Protocol's class object can be found in the associated header file for that protocol.

+

+Examples

+

Most of the common uses of this library's APIs have demonstration code available under the examples directory. It ranges from trivial examples to complex real-world project code.

+

+Tuning

+

The most commonly used & needed knobs for controlling aspects of this library are available via run-time class methods or at class-object instantiation. Again, you are referred to the IRsend & IRrecv classes.

+

+Advanced

+

Certain addition constants and options are available as compile-time tweaks. You should inspect IRremoteESP8266.h, IRsend.h, & IRrecv.h for General, Sending, & Receiving tweaks respectively.

+

+Protocol timings

+

Generally you should never need to adjust the timing parameters for a given protocol or device. However, occasionally some individual devices just want to be special. If you are having problems decoding/receiving a message, look into the tolerance, kTolerance, or IRrecv::setTolerance constants/methods etc first. However, if your problems is sending, or adjusting the tolerance doesn't work you may need to tweak per-protocol timing values. These are stored as constants in the ir_ProtocolName.cpp file for the given protocol. This is typically a step of last resort.

+

+Reducing code size & flash usage.

+

You can disable most protocols by either modifying the appropriate #‍defines in IRremoteESP8266.h or passing the appropriate compile-time flags, as documented in the same file.

+

Avoid using the A/C classes, especially the IRac class as they will force the compiler to include large amounts of code you may not need.

+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.map new file mode 100644 index 000000000..a8b60bc08 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.md5 new file mode 100644 index 000000000..47dabebf8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.md5 @@ -0,0 +1 @@ +a846ea81466572d0dcd38c89e164f553 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.png new file mode 100644 index 0000000000000000000000000000000000000000..9b6798ac0294f5fe01c7b96f26f12479d6946451 GIT binary patch literal 1406 zcmV-^1%djBP)P|0>U4%kLM77Pm>2yZUp$=*D`@aa!A6dT!$5@a*{!Hh;Do<4oLZ}ns|NW!i( zLm&`<)oMj$Kw(4a5#*vt}f{HdK^1; z4DIdhSY2HO00e_UT)lb~`T6-MC@8@7>(}w)$B$jBolJFgHSXQJhx+<@>C-1JEiJLXzn^d3ydgJ;C-d&g)rnlj&)FJE}%$PrFVOfV9O&~CT0ySrQDD=I4D*w~o3_W67S zz@?=nlBCIG;=sUwh@U%mj)Q}P;yP9SbR=0{o9bq8I2;7Pg@pw%Han%=ah)ok z%jKe0t4)|&Z8N0GpN?eBp!#LP@ApHi)gnJXUyM~$REW=KW@Z2YMMXtW6a|W+ATu)) z;cyskw;OJ^8=0AzTkhH9^ZB6BXi!#GCdMi&D@9Cg?R4mLy0r7@^?JN`@d9`5+=0<( zL|a=MK79C)R-JV0b^e6!O{A;1xEQOes|W^zVo_W!mxz~^mLek~1HoVrCr+G*yWi{e zA{L9m>2!*P-c(Xjf@m}fuh%OU#o=&>*xK5fs@myL6lF*G8XFtY*w~1TjSW11{v366 zbqE9k$j;72R#p}wk%;)(U@(}pc1A}0&uX&#YN_5CDk>^){``4#c6MTMaS<+;3q3tO zBCgZv(A3m~*49>h{rVMaYioG_{ymzTo3XyW4xLU1tJR9Owl;kJ{29y3%NQ6Kz}vTP zQC?n-y1F{tym=FWKmb0U54UdJg2iG%VPT=_+B=mh-`Lm~dV71}a5(Vu=TF39F+?H} zY;0@*_;ny192`U_6oSX&!QH!elh!LNEX4HmG@{Wc0Hn;X+74b*67u`~v{)?6$;sjA z)2I39(W5PgxNtbk?(S}umzPtk)zV}#addQ4+#d>s*wN9!l9Cc0KYpC;?d@DySs_UV z0s*$Pv@kC(k0(!_wva*s{Sy?m~3>+C5 z5%)TsPMXbTW@l&f?Afz?{P=OwGsDEh1gom5sL^O>GMQ55Psg4fAf>})PY;mN-{YTc z2DjTSo(Q&ow6?Y$^z;sd>Zggrs;sOGlz%_8#Xq| + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.md5 new file mode 100644 index 000000000..bd11ebe19 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.md5 @@ -0,0 +1 @@ +327933a92eeebe9fdbbc6b40d5ab778a \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.png new file mode 100644 index 0000000000000000000000000000000000000000..559fc0217e7185417012714eca5189f40e90ad54 GIT binary patch literal 674 zcmV;T0$u%yP)<)x#b{z+(IXiclnl~ylUXSi z0~t(6io_!mvyp{`y2DL~lG|ObLiu;z;VC`uz2576@gAw?GoAD8bbg;szw`8TAVLV- zA)H$aoC)iVmwWYoU{0FNW-J!FmCDcPbUMG^f0+Ju-sADOQmJ59I!&w9YBrn9^FoqC92>E>e^Ye3|P`IkzAGyMLlO%}{ z`uO;8yWLKwv)AigzUN7<)+c;E-|O{42)o@botR7}2qA~Vk;~=baQN`UJfF`=l9bEk zVzJoc@hldLTY4{-%VaVMA=GNMbW*F;5JH>HrdqA$a=Bu$NaqfRqtofs>-E84pwVa= zjmA0k5Q9>w^d&ip!C;_!gB~BY;_-O2>vs}~gw19{2#rP~0KnVZ+sP_S2!bF8f|*>c zzu({A&1Q2b6x!`}bWTx}TCElc1Q0@!Bqx&z0AM&Aa=BckQh8y~tM!RQB1xyy{eC}_ z$p8Rmvzgs)4+ewN>2$x}$K&zsb_)QI$z;3TuHWxpSnitNZ;?n82m~UL$a=kAtycT} z{_*jV$K$nHt#~|6uX%cUGMP*+m+STQ_4D&Hl}goWwHtc_0DL~*a=FZAvoe`18jafR zcA-${_xmjt%VAAEpI50=27^JNP_)}^yt<8 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.map new file mode 100644 index 000000000..3c6cfb9c1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.md5 new file mode 100644 index 000000000..18f33803c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.md5 @@ -0,0 +1 @@ +ef00148bc0f51868126f49db7c64045c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.png new file mode 100644 index 0000000000000000000000000000000000000000..1321a6dfd7a7a9709cdc0d4e46fb9a44fd9c0a1a GIT binary patch literal 1281 zcmV+c1^)VpP);K~!jg?V4*Sdtn^MpJ&$C#!R_Hl>6R{+!E4+l(3ddNo?iLSd*4F zq7+&b5iM=VW$qzFd7(&nfj6YQ@Cq}FSTSYh{9l~@Yi4tOa_f9vo#*%b&U3!!+w=U+ zbIt}a3QmU(~qobpZ%_lST`1p8g zYU;}+{bHu3rjCz~O(W#zNt2V4U!~{Q10ghv5H%DrgrSHb3`NY3HZ&w8WO#V^yH&i8 zA7^M(RFp!Y_i&CAQ%-rjz7 z@U5+_qN1YD=Tuf!;#Vh=pX_9qOeTEF$;k=cwYIhv8ykz?$jZvft5Pk3V1|mtVhqDB zE-s3TivCDW`^z`({u8VBR(`dAciV6tf-rk;B7llG$u~@CGtpb5S zBog5t4AaumAcQ0m$;Zd1v9Zzk7182y*6DOS9xpXD_4fAGEGHx+q^_lo!3ckI)9UdMoEiJ{HwY9Yc1qG$0rA|&xetv#kU0olt0iB^bovypP8$uWn5n(MS zH#hh6^z`uX5CE{Suz+EhUay~?o*oz&7#$t8c9vSLj*E-)@bH+Mo1@d|&l3g*2c=S} zTCElc1bjaKjbC_2Mn)(UN@ivz06?$TudlB=J3F)4Y&xAD85y~{y84zuo`b;9j*bop zA)QW_NF=kfvjG7C)-t`kyZ``~mzTzfjg3ucXsAdenwy)mc*?=SK}<|cR#uiwCbO}z zv6v$kiz6c=X*8NpDAZ^)DwXOjvU_@Z^7Hd;ZEXPnTCMis;Xy8!4-5>b)oLD(mzI`h ztgY_?Sq;@_G+ZvXp`pQGFj&jPUwfUModE!olapa#VfOa+5JIt7Y)yS%UmspfUJ&5w z>WUvwsZ;>K-QC@*nzy&NcXxM7N=oo1olb`k78VwUhle{jIMmkG+S%EC?74(&$-B6? zC=`mLqody5UTZl@rP9;WGcYjl{QNv8C#Sx?{_O1R@$s>}z5U_g!Qv@WsWd1kC@CrF z>go!WQ~-cXCQD3A^!NA2n^Y>5#bOzI@kbVk^bvDV?n9YOrbHrXYHGT_zc-ER_4>oZ z!&ddOoKw9P%fA6?Cjj!+%z{g8w`fT#KaE_j(B4)5{Yy=U4MT+-o(qRgM&kIagwu@jEt8gl1Os7JRu>0!{NNWt|=4>2qBltH5d%| ze)Hnu0`D3c8e%XQJRZ+Xd3kv`m&^=m;<8pJg00000NkvXXu0mjfI=ymM literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.map new file mode 100644 index 000000000..82841d494 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.md5 new file mode 100644 index 000000000..42c49f978 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.md5 @@ -0,0 +1 @@ +be983b2a61d65504f4b34c48e356ed36 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.png new file mode 100644 index 0000000000000000000000000000000000000000..6fe436b03a2ba1abe386d22c6940501dce873766 GIT binary patch literal 1088 zcmV-G1i$-%}XEY?Wv_l1bK_8?CD>NdqLy;f|6;T8sm8ZNI zi(%3w3L-N}NJ^q0E0QEksgNMBAhd%Xx)p(kE?H($L{SP^?t2i#*R*{zDdFAUY4@3D zX8+Hhondwqq9_V*5<~cH0qG8I5C*tG7~lqBkP&_3a5!dXXMamdnjn+OxLj`J_OCa{ z?RJ~Z<{y`oMwrcJx7!^Z$@rLLGMRo#Puc+?jEUfD5C*tG7~lqBkk$sV+3bytjo;Of zb_O*xH0X4?@8_h7WDF7r1VckZk!uJcgpfj^)YQ}%42I~ma1)tKE-x?d>+3r?Il&y< z>2wYZ417PwX0r(d0y>>uR8%C9NS>aaFdrS46ud!FsT4)gySqEFSS%8W&d$zanjRk? z_xJY;3JSPf?#|B6_n-JLC=`m};bFJiZM9nMb~}O~$&Hh;DMq1C1_uWrgr}#cF-;^A ziOFQD)oPJQgdj-xfTgXi4MIpD5X#ER6beP;)Ftlp@%#N99UZN$tuHSxF*$5Ddu(is z$K%mxG$xa2wOYgRgM$M;pHHLFSS*%UEIvLyPOh$$8RYl-7Zw&EgmrawiE?^-d#|sr zT`m^@U~g{^MbTg|xV^o-zP`S>xtXY!*XwO=ZZ0e=v{)=uD)nQ6UawcFR9>%FBog)a z_kTR$ve|5GHaoexQee>B+#H0EN~Ox>^4;Ct%F4<_nI$D90D$}Z`$&XHByu<$1VJno zOWZE!=jV-$josbdi;IgyA~9}`R4T2nucuHb5{bm;^Lad;=vJ*(YqQzZYIQQTrEm@M z`F!o|?GqCd@9*!4GQ*!axw*Lj0F%j7TU(ozl?5S`N~KpL% zD-;UH$H#AOZbG4uMx%LqdyCserBYQ_SM&M&hlhu+N}8UYRw|W8M@JkE=c|1qq;emW zlanKt%crKMUSD6MXokSuzolcELlW5G0j0}Up zP*qjc($eDd`TkwZ=;-Lu(vsb7XR%nxmz462B7z`(zkh9QEqohZp0cyE1pQkfYQ>^nVA`(P)MWEWHMP-SJ!6}354b4Wgd^$)YOz{CdTmm{H# + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.md5 new file mode 100644 index 000000000..965dce765 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.md5 @@ -0,0 +1 @@ +4d7d1c5757d6d8c2ba1dee85111694e8 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.png new file mode 100644 index 0000000000000000000000000000000000000000..e8860a43afbfc726982e32c419215d3b1ef734fd GIT binary patch literal 1317 zcmV+=1={+FP)E0@>;5No3{Y~001hL8Wk0#QmHIuSQmvt2@Vb}Dk|FD z-FgVSt5D4z>?y!1QRTbunNVHzzXf&GSZ+`)jL+vE92{76-QM0VEiL)@_#`GK&dkhw{)q2EB9YYA)@rrd z<>h6KMk5pov3hTBFN&h`^Yd2vt*x!h%uF7ScXoC*Gcz+iJ^iucLc8UuRBB~qB>-T5 zf8VN$L?SU544F*E=ktX^A@;$L!{Gn`2n0e

@6-F@Ht0c{>{nhV1O@tgNhuhX*SS zlgVsoXh=^_r_<>S24i`78LO|Xtgu)tI-MRK9$r>fwz09{*uPjTE-o%EFE4j@cMk~( z>Fw?PSPswvH5d$ieSH9cxVSibn!>`uv$M0Kqay@C78Vvz6g3)+)6>%5fKqI z8ZACPUaeNYal&?h5NKCd7XW}pqt(^b&Cbq-hKAZx1_T5k2y%UWZLT;uIYmcD3x&eD zxjCCd4i68Ll9KZB^7{Mxot&I(YD6MYe0)5WN)-qMdcFSq{M@p)r>94)R?B2E2d8j* zd;9$SESJkiMn-fxU3PXhhr>BNJ#{d|9?<4cynMhPjEN zD2k#4!bie^xej%6bE~VXYiVhDdU~>~8;!=JqoexzdZkj?-Q5iUczk?(d3kYlbtREV zJ3Bj_ot^gfNhA_gDpf>8L|R&!Uax<@8L?PAFfgFeXu`w8-=h}@1ai52Z*TAZ{=T)f z)nqbdWMsVmaAqJc?1e(1!C)939>$v3^y=c`!e+D2&(F8Fw{voG5CjPf3~X<2FDNLW z)9E!eHMzODjw})ga=AP`Jv}8Q<(=~y7Rt%VNmy7Iw(2C4$yk>{p#T7Ixm=UUgmqnA zU182EDk`{KuD7@M;^N}s;-Zg_&qpFaEf^mkx2oVc20@VV@o~$_k9+m}?cjkz1`iZ6 zc%YEM1BDD8C}i+JA!Flbb{@HrGRc%YEM1BDD8 bC}jQvT~HCrEM + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.md5 new file mode 100644 index 000000000..ece2dd31c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.md5 @@ -0,0 +1 @@ +bac1b057abc6acdf006c520a2648695e \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.png new file mode 100644 index 0000000000000000000000000000000000000000..29dd07a689fffd7d67f1ecc55429f74a69bde3fe GIT binary patch literal 1237 zcmV;`1Sw}Kmo5!^V8;KpGj$g^>DbR?6>zDvpvMk4X z|Jrdzqj7zG{mUi&0@l~pjYgwqBG?H42;W5T8ix_wIE>)NVdO^}$6~RT zmX^L-g?E0Oak;sm^1Og!;Az@%( z!2Nd1>oK(3?Uj|4<>lp1Pfu@hSS(g=Z!d?#q0wkeCUa+J2aQW4lIG^-_V)IOh=`=5 zq^YSX_iP4(K`xh%jg9%U-hdfrx7(+ury+#d+1b8w8X6i*CX>Nn003-mZXyWcbUM{) z^}@o!^768;Q5K7Z&1T2O#%i@%3Wf4MVR3O$DwSF+7CxWf*w~0pdvI_N85x?<=qJ{|yYe}C_e z5Q)T$j0}N5pw()<4$=l```OG`^uRu+{?l}IEZ zAtAfFyL!D|p-{->a?Fc$6R@Ki6%{ozGjnxyH9I@&D@UbL#l^*?q@>*5-qzRG_x1JN z+}ymrzK)HJy}Z159U_%V)6&vPN=hCc9zHLIL?SVnOm`DO5ClO81j6a*smWxb)9Dbx zn3xy@pFQJFr_*3C^z`&BE-p?^PC^JB4#(^3 zYgkxVaB#3rr~9Bz2L%PGRI1d})S{vytJV5>F`b>AN~QATL zwcJ z;rjY|8jU6riE3(UK9WcvD3wYMhf`Qs=<7s#RnpPX!R2zJqocRBwzjsm&@C1)5D!*X zR^CK#PyhfcD=VInANR=hTfmLO2yPrkaN{t78;23xIE>)NVZ_Vl!PV8(uh;SG@M2tD zUESB~_;o-8|9>1N@EV5^+&GNj#$g0E4kLd6VA0}La@q##00000NkvXXu0mjfQ)5>8 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.map new file mode 100644 index 000000000..72e272f5c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.md5 new file mode 100644 index 000000000..3857a757f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.md5 @@ -0,0 +1 @@ +beb2e4a39c2932d475766be916f606b6 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.png new file mode 100644 index 0000000000000000000000000000000000000000..28f2cbc5c1c23d2d3de726c7c1fb90c1d7adf752 GIT binary patch literal 1264 zcmV+UyDYiH5-AaqHYNX%LP}=Cn&h_0ZQnmmt^M}he1CXy>%9It=Q;1^dER@U z^L%#B*`V2M1_bDE`f3Be4I)s)5P>3w2oy2S);lVds~GdVe_(P*q&oc|V0OiX;1pC1o|(58i`p@<;@MGO%rV!m~tQBhGNBO_n! z;%$7pKv^tSZ*T9%HDASh0!>RxtE#H9Y(oekgk&-~GBQ%3P*}_GL$0o_!NI{LB_*4i zoBteKtyY(omVR7gncc$T;vxWGe}6wOFON>Adw6)Hr>C#2t=Z^lG#ZD)SzTTIr&YTk zxI#rDk=blE7z|})Wdea6BdW+5dd1pttdkwK+W zx3;#9kB`M-u}mhj(QCEZ*x1;doE*Jg|BgwKEqOATTv=HOA>7{HwmIbD;u01X*3!}< z5D0`qA^yTJD=P~^=;Y)S6cp6Z&|rCsXm>dqjmF&E+|10(ySqCZO;l7=U0ofQ%f&D( zEG%qcVc`{%=jZ2#hlkbG)qZ|{G#V{6HFa)o&PIb_SW{Ee&CQKUrFusW$O1JQjh&sH z5W={)I7b>DkEhjY_xAPx0JF2RX0!S6@o{QuYG`O^bad2Fud}nWq@*NYU*DOT8488+ zw_td9SSFL5ot+5;0zRMr${Sufoz7%3rBbO{t-im%f8$5|Umysyt*s40NTE<95{Xi& zWHOnKl>Ywy0Dy~&3rh=$M2e1%77B$kGc$I(?C$PzIGlolg08ME5{YD2BNB zaz#ajUa!~bbk@c!7z_po;qvk_gTdhQ`51R$Hsr2^teq#~< zAYAfZUS7Suy@!W~eSLk7Gzx{n&(AM3H1z!ZytufyzP|qS^z`NBMJ|^=Jw4g&B9qA? zA|g^#Q!g(sQCY>oFs!n&GB7Z3eSIBo!B4>L?X6m^=5o338y4k#sJpwnL?UTyY2xZUDlab&01y}$*xcM)TwIJ{m{=^%&(D9&qLWikPY;*NO-xL5R2l4IQ$q&_2N?`T zd3kwLQ&UJtNI*b9PfyRlzyN+bg$(N|Gd4D6(?ak%0D!TvG3%CZ_vrc4Ap%7V5h!Aa zKoLU(iWnkL#1MfZ#?H^k@8j2CC(xpzqR;p7Yk+3r|Di}BYA9leKoLU(iWnkL a#QXulG!^CDXaN@h0000 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.md5 new file mode 100644 index 000000000..02c096729 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.md5 @@ -0,0 +1 @@ +82db646c1e50878e4bc1d2d8e42f9084 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.png new file mode 100644 index 0000000000000000000000000000000000000000..d952333e9902c1b6e96b9120908f07a47f780507 GIT binary patch literal 1482 zcmV;*1vUDKP)P#zwl*(a`}Rv{)>xuf@WSHW&;PMR~p6 z+qZ9Pwc5G4ImVRF=X?3`Wol}wTrM9O8Ts=SkBML~Xf~T~-MVEo8d*=yTI-05i___J z5JH>H#+bq|EGH+YySrPf)#~+n^kH^$bJJijNTt%m#6*=!_2tW#{W(`xSFc^WCKij& zoH=vz=FM;4z9GG!prEa-O`%W-g~FVioY${kBb_A4%a<<;g~GhNyeChdKnT5FFPgI3 z?fc^ytz&F#?DXl=y}i9|x0}9QHa0d42E(~?=aQ0=nwpxnwziJo4{JvI{r;yt2=e-l+)?7TCI%JFKj#mqtV#X(t=@_PN(bZ>kH`` zjb>(MW^{Da?RFOy7QTD;?kEOPG;kbeC}F9ns6agdU58R(7-qFv!-gRi78U>i6B85Y z=P5~&NDl-8LZR^E$Bz_66&Dxx_xDp2<#aj$0B*M%#h?epnObehfPgJK2;2hW~8d;a`+sZ<&j73KAM>G!<4 zx|$xGo}Rw9x3{#kgod9#e@5a#$t4oW=H_OoDZ5;*!xtY622Cc@{QP{Vm^W|Upze{G znHdNK(Bt(du=yUHn3#C)-o4Jw&Yhhdy1u)+Yq#6)-@k9MSROxq3?a-B4E zYc7}T!Gi~ful&`kR{(&#yu6T7T3Twe*=#mjMn;B8rD|ws`1I+M&*$s!@3&g5htC{> zXZkudioiWmQ#GUAb}v0DxiGVahfdjY_4Gu3#9Z zP$^ls@e2@Nj z!Esz55R{jfyIii;*4C?6uby;8KZ&Ss9c5)@LqkJSsZ^y>DHMvHo}QDg=qC}iqmz@9 zpFe+o(p7{fqIUG(3~w|?@J4e4Z!|}QISgOCc)@)g5l+0&buOs4t6#xIxoWS>J kj^K^v2;OLp;Em>pAKIN$tCM2aIsgCw07*qoM6N<$g0ke=)Bpeg literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.map new file mode 100644 index 000000000..79bd99c23 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.md5 new file mode 100644 index 000000000..c95f62f61 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.md5 @@ -0,0 +1 @@ +8f9d660abbc70be4c1cf621adf15df03 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.png new file mode 100644 index 0000000000000000000000000000000000000000..e55a8da5344f547af9fd43693510e908a4c02aaa GIT binary patch literal 1334 zcmV-615*e2pBqN1R;7Ni~;MX;2#rd8A&v}nX?@_vW!b7`8S z)|#{~%mV|Nd1v1J?f$a6GwiMs5kX@ILXL%2pqV||EE}QCvJu)W8}ZNdhQ7W&E?&I2 z5Lz@-2!%o!Z5d})EEePT?c4JrNR!Ff*jUcvpK)gWB%8CE!V?SzX>4rF8q@bI8==jz z5!x&p@z@&4Idh{qClG3QIuIAdcYkAA(@pw>5(cRshx16(~U}u(TnurMTc$_0gj?mK5!t>|P zv-X)<_UzeHC`oxCl}h3F`#F60FkY{BUbkKF%V2SFF>P&aD5Z!*B6H63`SWK?)1FMdg<#G`S1P~GW`}?h&SFc{>{Q2{I{P>ZkrY6GSFe1YD@87v|=MLAe zU+31XTWLDHUN6UwAIC5Z+S=Ng?>4#>PggK0ZD!>(;H4$;n9(5sAm+vS!U1NhA^?BEQrz z8)i8E!Ghnj-oJlOeSJM=&z>cjOlIvfwUm{WW#o!RqX4X3yVjbB6crUQF)_i&$Ot1N zBNP=Cv0=l8-_q!GI@9W*P>5~Ywy|W%5|mPyrpegYm=*W?{lsE148uSvMOj%HZ{ED2 zx3?Ey&N^mG!7qa=SFXh8^D#U;jNk8{Q;zcTavTl^@pwGL-1_=@Dk>^SCX);g4`&_k zaAe<2rIhvi-Me=*H#c+U%o*OkeM>5pqNAgOA3uHo|4l4>J|8b$yhz*r!-o&8OX06{ z{3-LY&MGY}<>bkeoI7`p$;rvz9`AHI*|%>Wt*x!Rdi9D#BEi$APibgq;M=!vIGs-1 zZa0Sx9pdH7mwfv4iLS0L!r?Fgt5>gPaB$E%@Y(qK^((1Vie<}|VHgJe{rz-wbXf8G z_wNI+apT6caXWVGAQFiXi9~*><4>8lMR9w3JBdVsKpgqDa8HT~`-Mg)6{7gFjnBTa;Y36|i znP6!0k2cFjXtQjDHp@n6vuuPm%SLFkY(&mi(SpI?eCp8rPhVeO&R9;fa=p8zSvZu4 s{yxhl= + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.md5 new file mode 100644 index 000000000..e94efc85c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.md5 @@ -0,0 +1 @@ +8463fec8e273d2b003400f5fc52905d2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.png new file mode 100644 index 0000000000000000000000000000000000000000..24448b28b7f2e7f9b91b36ad0f98af6b910b1428 GIT binary patch literal 1280 zcmV+b1^@bqP)pY`VzC&CqHyuzMLZr) zQh6{K#NlvIT3X7B7cYoLqda=_h#xd9xp(g#k|bfb+qDkIz`y`Dn+>1OhY*67FJJQM({p7yLJte$wXsgBYk~+iL#F$KQcW%O?`d+c3;jWG&8HWw--s0uvjd(-EKxkMkp;U zO<5eE2YazdtLT*|H=1EUVRu+wG>Kql4Ae)h+9nmzU%7`B++7;_KJ1w6?Zp z74P7|gS>n9jtQOR*1!7TgHn&p&mPSY*P$}!$Bw% zA`}WCNfHkpJU~$tu3x{-=g*%}Rh4i!OnZAffj}TD{pr}TP4U&MS5Z|JpU<~t-OkQV zqR}YD#l=)tS5sSCn^mlqmKMgw#xR@B$g<3-Q>U<6tyEQ2v48)5dU|>Y1Onve=WiL$ zriO}&id@Utank-${5Mij zQNi-^a;|0M3|-Bv|2u|RI>InZM;K=5h_nwF+qLU9$c~ALiL_;D%}V#*HG|wC31NJn qr4x+rv-E^vmX0vY(h-JPI^q|CrMqc~qAI)q0000 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.md5 new file mode 100644 index 000000000..e976aad9e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.md5 @@ -0,0 +1 @@ +494470899dc7bc1f09771a91824eb25c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.png new file mode 100644 index 0000000000000000000000000000000000000000..aee74feca7b275cdd69716670a9dc4d8d75dac59 GIT binary patch literal 1904 zcmV-$2aouPP)pk`$uhP|ELY^AGL9JtaNvGmz9fh#{!C-j){Q0_fiRM@7>FMe2?sin%{~6TK(6CUI-o0nfo+Zl& zA%u{ZmsdGI?*TR*+Lyb22o5kdn40{}n}#HmxK3JMC!%E}@lB3LX| zSXfv=K|xhj6^@^to<4Nw5SPo{wr$&yBS*e{`?k71F)<;PO4)37R8&-BVDRAcalBM2MF=q%jNstl zl9Ceq9xW#)r?0Q?=+UDHp~S>Q9QozT7m-NBX0yY?!{5AlgGFa)^P%9#^ZYs~uY$9v%jO(a}--DW0<9 zYyfY0ZX-&Ltp27`ggWFmyNZrwUQK8`1ePN#Eob920qwc)b$)7RIx zva)h`cvz)U0YGGAq(C5W_Th#@1ONu(-^avRTKp+O2p8;jdu3(i=g*(XnAX--yo3q_0-Mc-*PB1VmCt`Z zK0fEqpD!&fU0hs52vt;6s8p&87cOWtnuUdhsi~>AZ{Om`kdTnn)YQVl!ik9qgTZj- z%o&M9;^*h*Ob-nWO-@ceefspw%*@Eh$fZk{$VO9AQp{#^b#*nKaAL9e)~#E(3;=vS zfB*jd`T6-8jmB!V_V)H>W@audEX>c(+wFD^hr?ttdwP1x%gf1xetv%a{r#k!E8;Be zvanaLUI9Qz+ zW^QgSo6RmRF3!rzBI7S!yx7vx!eX(=^XH1Jn08r=QmK?kB#sJ`$rOo1_(7tkrY1T% zIz2r-BqXG-uW!$uJ-;{B004jphyS0|*Vp51d<}_c)&czf$ngaq{refUq5Y#aw13ow z_K(`o{!ts+KWan!M{QR4|6qN6{rdNV=2tKpje&uIj>-!DWoKuvSAS@J8<|YzSVi=& qEtH1d|ELY^AGM+Vqc*gE)aEaYUPA9-4r{Cc0000I2T literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.map new file mode 100644 index 000000000..eabd6a84c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.md5 new file mode 100644 index 000000000..62bb81d6a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.md5 @@ -0,0 +1 @@ +ef1756185927c9dc031ac38fa0bd7314 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.png new file mode 100644 index 0000000000000000000000000000000000000000..d0bd0654fd6574445a63458b47793bbf174212f4 GIT binary patch literal 1214 zcmV;v1VQ_WP)2g@uzkDgfX%s-*@0i@ z0|(CgK0Dv@>^U#*c@MlwL<9>n7_Ttf!M}_ZzKK}jn}`*@iTw9_$IQ$O4<9}>!^{7g z@$vD3zJigTOeUF_nD{G({soqnmWt+CF!Fz~*^{!^KEYs+%a<>2s#$ZsiCE#Ah!wtx zSmB$96~2j-CH$6_7P`8+Hnf#eD5co9ZyzU4oZ$KM=LOeAqfsthx=9) z+`M^{`T6;B*eXeXe?LkohKGkY)!)B=&&7)uaX1{t|9J4=0Y85HD9inKZRB@$b|NCA z(`jzpxPjN}<>SYXhW_Tw8_t|LgUjV&dU~2~-@ftc)hiks8yOfF*ezQI`FtKt)3|>9 zI)1;uK%bhLqPe-5BS((#_U&8J=`>?wW2~;OGC4U}9ux8#fj~eu>E4p_=g&)LXJ^rN zE|-(a%1Rj<8xs+cd_FHOmrL5)+e_ANXlRh0o*p@S_N-J@RmqDNFJygvU2fmLEl#IX z>~_1fwzf(lkua_)rHhEXe*Icbo;)d;OhyhII3TfD%+R*uuM}J48Qk?bU)OaWJ$i&v zic_af0r2_rXA+47Ua$9$YCL=PjQjWR^ZomGu3Wi-*Xw0&ZjNv`%;MrA_4W0%wY8DY z=K)IU0DixpJ9qA2v)QlRO+J~g!M`r9$vcv3~#Y~%yRVYAuf<;$0b9u9{Ekj2GC zqiDyZdj zI*s!$U%miv=+GhKrCwQC$=cc)iA18L4xnio$z&3n&4yA6hr_}0@-l%yps2syVArRe znwlC02M1YLSU}S>0FE6yhRfw*baeEOYAB_Q^TUS^Q&CYtI-N#DHXI(0r=*_G=NTLv zWOjCTgBA*fjHze4{&vb=S?BNHzn{Bz?=mnjKsK92DaGT*kI^)Zd-v`UkH^VmGOVnu z5Q#*#tmSk%xp3hEKA(?xJdUpGM59sK+S{)EQV5w zCr_TBX&T+#-OSC+q3b%cv$OQ}_7V&R%aY4q`^f6(=s?$XhK7a!aJ$`1Pfs&HKhNpY zr>U;4rm3lkcs$O#cki~WH9R~_eSJM{x0~A9S~@y9@cDe~*|Vpl?)Up~yWIsfZ8jU{ z&Yd%soh>abL?RJBefmUWVNEO z_$Fe7Zz5LsCSrweB1N~3l + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.md5 new file mode 100644 index 000000000..7f14e3836 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.md5 @@ -0,0 +1 @@ +fd77e92eb539b07b298ba28c872ed33a \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.png new file mode 100644 index 0000000000000000000000000000000000000000..f6da0e6ffb0cda9e52d906c565b42d0a897bb3b1 GIT binary patch literal 1068 zcmV+{1k?M8P)#EGVjl zlqD^KR)Muk+7wt?5CvIAiwueuE+eprEFwy*E?G!KMj1$Ye~W?3eZKqrJ?CfrUi{{> znserO&hhKa+!2Kg!vI3!{PnvV_^uG)Fd@QWLWILaz%};w_swSW?`q|Lj?rkWuC8Xy zzpXf$rX3E)m$&o{a5x+^O>;ehe+I3uuYXlP-v$U_jE9_Ym=NJGA;Muogu{dghY5~w zjg5^%LqqHsLI@!g3WZ9ga%E*DCfH;$K?s+YmVUKUEIzM#5>}kSU|<;L@$s>@x3{yi z^YrwTor*@IHk+-dr^jNk{Cc58`PAx3+p0pLP_NfR2t6JT>)hSl&CbrAot^dhd|W{* zDk_XdV@*wsNF-7y6bAJPl zAP{J8Z_mxm&CAQ{>gsxWdSY{qjg8gT)~2VYudc4fsm_}=QIaNHC={BRnSl^iR#vi3 zi^VcLJWNrPUay~_qG&EdXT%4SoxZUopt*woX4HTo(>5h($ zwzs!^KA%dZa=BapfR>h)U@&-meC&3+X`0sQbZpLrg@wt<$>-q*)f z7YGEJo14eS$0Lyl^4n}Snx-j=f)M89dMlgT2H2wGw+5{cyF_8VoK>bz+&Naj5* zGc$8!WMpDuA{-9y?Cbyl6bc19t5&N$9uN1?5g(~k+SJt4-Q9hDejW@4=jZ30PN!Th zSF6=}z5f3Go~G%+!9lH7o1dQ_^V&GodDCLN*(6_p2L=X0q0r*uqQzp-YPH-cilXZ4 z>l3;eEH5vYm6d5U8o6A4cz9S>R|f#F+wCHeNU2n+RI0+lLf$)C{OY`E6NY=>{l|yH z9|-u2hr^!<5e^d~9416KOo(up5aBQ(!ePSm^WfUr+Sm8-?cfovwYBx@`}lT1hWtMc m3v$L`LWIMF2!{y~4wE0fWx}yS=X;+30000 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.md5 new file mode 100644 index 000000000..43f0e4cbd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.md5 @@ -0,0 +1 @@ +b7a5f99a38a961494782496866818bd7 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.png new file mode 100644 index 0000000000000000000000000000000000000000..fa378ff6502425b66ba9681fcb577fd81f2098bb GIT binary patch literal 1300 zcmV+v1?&2WP)2TVc{NsEff86)Y-nP`&>qm6A+YS&~z5}M-_#Vjh~N|yI&)qS02#@9(F z?@Q+g2j-mTdFDL#{O6o=&v3625kcbwVy?x`K=UtJ3?8m?ixFLoLW!h(oVQ&U50Yin9vDTPuBx7*F;&6~M-^X9BEKk<6K zoH})C&V3IJ4RPquq2JDZCc$73r4&6qJz4Efo;+dCo;`Rx9{ak^o;}Otv~zn|*rYSyh=$K%J3Nu^TU zx^;_BpFVN_{{02Xq2SAu+wG>gxf!Jt@pwG%_`13}lv21{F4nGHOE4H@=D+^GE>mB= zd?64BP+ne6Nl6KHb#=UX^TxJs-MW?b_I7sc*unDU%eiys4ge1xJYdC&6%R$aOB7l4jeeZ`Sa&lzkWS#x0_9yHqp`1!M=U_erIShD7YA=X>#e(C6rQZ-@ZNX z_`beAM1*hOzH#r~J+5EB&h6W`bNc)Jenv({7#J8}e0-eB%1Rm<8n7(O_UZ2KrlX^S zj~_p>fB${}LZJ|CZEYBaL3496SFc{R{a?O($=KK!e!oBO{PRM7p|`hJvNX@iu3ft% z5D28z0lOH6A$@&)88I_`W|osDPv-3F;>C;7*w|>-tE#G`tE)>yL=uUF0Fq25ZTs}} zv=kK;$+KtAL_}oEmMszt2GhPXnM}%>HEU#QYDz>zQmK@zTD3|{(-aYrfq?-5WPE%) zuW`x7EaMw3_@43M!w2f?>p6Y;G}F`5S$$@fs;a6qpI9u$wr$&3wrm+nDFT526B83z z`y3q|1z`2+)%Fd(@jgk-TExzkiR<=i|hQ6TEx(4$HFW?Cj+G_wQN# z%gf7gxm=`DsSJ_p>+5YlrIh{IvMj>kFvG*cY5or%KD3vr4I4I4QBlE-8#jJq1m?~k zIcJoVlyL0WG0vPh!_?H&oZ}`ZC$TJx;^JZq!(eD=h|bQ=oc?8HW$fO)o2I5FUcGvS zX_`EJ`jm!-2EKm%nl+}szaM~&8#ku4S65dPkH?9}<0z%La^(tO^HEe(#L=Ti*}He|tT8=3 zJycd!Qd?Wg%9Sf=X=$OUsfndamuB@3g+kQU)@HODhQZFAJMG)tnwlCOJ$l587ccO7 zy?8txd_Et=#l>l}ZeHZE!DtqMMcKeL`J=^f5Lyfep~Y|zS_}uF#c&W>3 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.md5 new file mode 100644 index 000000000..1e63f137d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.md5 @@ -0,0 +1 @@ +1a4371fa075bf61e18fb4a59f6c1ee8b \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.png new file mode 100644 index 0000000000000000000000000000000000000000..797a53002e9742e1e1c7811d595d508fa83e7863 GIT binary patch literal 1924 zcmV-~2YdL5P)$-l|_gwq^&Ue>!UN(dv2tY$Aync5AH2)adGwMNmMm=cHsK;N`&0{Z;wUEX>}$ zdtD;*^^AJZo>33lGwMNmMm_#G&*J0btE#GgcNTv%o_HpeN>83VNwyILK@h~p$7l2A z&G+uzb1Q?y$H!m1cya#8J32ZJA3p3sRz*cc2!hnq)VRbuJ3G_T(gFhmVTM<(T$!4h z+Oua*YHBK}!Ern>F%f?5Tosjv?N~Ka3i^bt^f+bmJIXO85L0GNUBS(&8Wo5m4 z_wN6n^Phs_xJIKnbm)*;t#*z#HZ}?bg7EP0*RNk&t=8Jw+KGvYM~@y=R#tX*cUM$Y zKv_vi$@utqd3ibPx~)hekqiwDefsnXYFb)aqNAgAIvwo3di4s&@q~l~06=kZaeaM# zb93|H;Go@Z-@ku9)D#sJ<>lp>Os410pSQKODHIA1t0kPMudjEBxMkO_U9c*bw!`6I zFc`J9wX=sHd_Moeg$uBqoSX~*KoEq>{5X94`Ph(?a?RI-`aInE(fHEA%xm@nCW5?W9q0{M@ zOs3Ij?C$PnGMSy7oeNeJ92~6CXb6IsnVIqT_t$E*adB~QC_g_xAt3>_IUJ5krGjmv z(Fg!||Ngzpr(e5vZSC5%^PcAalAfNPo}TU;S+eUHhG92u+&~Z{E-r2{`p1tS69n<| z=g)@^AKtlhr>?GUwk9hpYhYkNuh)-^j6_C8%49Me$KlZJ+qacUrOjr8-(s~|ed^RH z6h)68KYr`hEvV`1>l+>(&dSPin}A3plFQ`>4jedm@L)kf!M1JN7OY4l62XP_=FOX+ zprEw0wEq77Z{NNF0CYN?SS$treEs@$Y;262jmP8p`1thn^tepk+Sk!)@9w6;)SP z2L%NY1ff(a<#IVe5K^i1!Gi}jn~lL>ynOkRAczkiJ^%oWMk9GtNJt2|b3jxo)ykDC z2L}h|Imsmd$~uGoefjbwB_-w3rArQn!)1ts&*zgvTCFxVHrChI7eSDmoSf0oQI}~y ze*6dk;BYwbj)1{nOioS?4-do9u&^*vsnKXmCKHOH2!aF#29A%9!!IA3&4#Yel{t!{ zJRWb;rcGX6e>)FzRU{UR&1SRFXl!X|5s5?qfSo&c>U282UcX|+itXFC0|5N|`~UzG z6BFcYHk%CwA=j^8FDxu>mgYPCAMo|2LRM-c>p4IIa-s;YW>dr3`GQxn`Cc|0DM z%e{N|?ow408X6iA5%J{7llJ!Z#Kc7Kzui)&(+P#bWy_WU00II6I2=w_R~I~_udffo zu$Y(_*exzDRw|V*UcA`4b*pDtfu(&u^Y`~Zefsp}%a^C8r{`BrO-UliBTd7g=LtBLE;ODvFE<1OkJ>U@#aE1gWT~ z&}cOI`S}9_0~m(&_VyMO6f`t6cwCWKEG{iA4G#|w2nYZG#Ky*2EEcU+3omAnqeqXH zl$7-J^q9@&yu3W2P`Gj9MgTxTLBY+NH{06UqNAf1nSfiC_?cRvP+%BVU0prDjLYR- zy?Qk>GtT5k&%%}NlB|#tx_ly+1c64moInGsMYGEq$KAEilQQs z2;THdrP9{cR-@4vA0HnW7?_!v$zrj{#p*#t5{blYHp7h(0N~~2B@hVAX0t>hArCow z_UyiW`@~}Lx^?SN6oni0j~_pjO6ADNNJK;g-0i)+y%(Q`GYH}IzpI9Z26!*v*<3XL z2Jp8S=O4)axOZ1H3qpHFJ!sFU2kja4pgp4=v}e?V_KbSC`LEpKUlY*$0!BwiSFc{} z9C71WMn=Z3%7hT{ + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.md5 new file mode 100644 index 000000000..865f0a8cc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.md5 @@ -0,0 +1 @@ +8fe022190fb8b4af703989db74b3df09 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.png new file mode 100644 index 0000000000000000000000000000000000000000..6d3377afeccf3381da61bec65b478277c51e2be1 GIT binary patch literal 1089 zcmV-H1it%;P)b3fHe7NOVco12@N z!~a}~p-{-}c7JM6$fRoIxj_z}80?3*8@sMG0antptI?C&;cXt|%My*ySeM4$8nTCgl34+jSwM$D& zO#XM8=|Qt_I-Lobq{!uRw1iR2ND%~qzW>J|hVk)nG%A%!&1N%-852J;KR>TjDruU& zy1D`YTwGiv6f`t6%+AiD`042h01ys`6ZEgIuPZ7lVzC(7cFN1kBaz4_nx6vza5|mr z47NS-;o+g9qhoS%G9Hg73^7Qh(o_UpE>}}iQ(j&kgixo`g~MS0z~$v-ZfU2OZ*M7zG8&EV@9zKrp->o)#{+>ty5bZ?SuB>*(^KYL?(grT6`iqW zV*g*9&!(WDU}R)uYHBJLi={QOtgP(#_!yZLjYcVo%FoXy2*T_28jVI&Q(0N5P$+tO zdd|+yo}Zu1X0ylRNkx2TX9oaKTU*OyT3TBCe!t)E&sZ}7%n#dxgM*Ps#AdUlHEVQq zbbEW7$K#PCDHIB4W@c0>l|UfS>-C+TolKd-;i#*tlgs5*RaHKpueG%`6>*cv)ZX6C z&JYA4lgZGtPG*{ku=lJKZ!CW~;QzR>aBwDKfHM&ToQW9VOvC_ZA_h1UF_7dZ(~XUd z@9!h4Nn)Z>sr>#vvKmNp|4;lf+@6R5&O{7wCSrgy5d;4KN|Linw23Ph00000NkvXX Hu0mjf(GmI0 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.map new file mode 100644 index 000000000..5c7828789 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.md5 new file mode 100644 index 000000000..84388b9e5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.md5 @@ -0,0 +1 @@ +1cc4c4dcff122c327c69c3c13dedc3fa \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.png new file mode 100644 index 0000000000000000000000000000000000000000..9dd34695a8b6cfcf9a97313e58a8f907ce8f61d2 GIT binary patch literal 1144 zcmV-;1c&>HP)tBj z=lp%xCqm8X@oJCMi_Hx$X~`FVmM91h1HerVd-0-McNsZ+5_z z-()fo1mSYI002&>lOTxK*VoO>&6SmvwY4=eQ=w2C9UX0LZTWmYKA(SZa6rb*X7kk4 z)ZN{kQmIrZ6bau@>-GAfp&q6#7Jy#NlwTSgbGIpa1|^t=8B`+IsH8!-G^RotT)2Mx$|4 z6hfge89|%P*4WsXo0|(ERIAm2KmY)6d3niVv8t-7-shK;l#qj*oE!i^I2?{kFdB`1 zzaK#m2w_oC(ap^bc^iGAnHJL47K)3DF%0v1y+)%k?RFzod7l)A?I`}<^P__k(}q;sE}pPxTGJUlr$8Hq$v zT3A|IdVG9Lnivj;aU9Rf%R>;v<#OqCIx?rCqCz5(bai!|ot-^BJsAuJr_-5?_|DD_ z0HCI(hKe*dH+wuDkH_Q)w29rM9+KEEZQ*R=VBpmX?-e#Pxc8TU%Rf1VIpyNJQ?*5^7=?1|gJ6 zrO{}V-0%j2!IaMEUt)V=k`FY7gaA4oXbd00m`fv!xirFU3a*O8GVFjpp%{d^r62_%^R=h6n#b7_Pzmqr+KX@oJCM*aanhVSZGR8q?T0000< KMNUMnLSTZg9wK1? literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.map new file mode 100644 index 000000000..efdf67e75 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.md5 new file mode 100644 index 000000000..705c5ba93 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.md5 @@ -0,0 +1 @@ +8cd321ec10c446c399675698b2c22573 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.png new file mode 100644 index 0000000000000000000000000000000000000000..407da85421065d82d759dee3035ca42329837804 GIT binary patch literal 1273 zcmVDlccfa z!i7;&QnOs3v4u4;eaA_AN8A-NSoB5NJ#c1rD=i>Y8JbPvjo8JySIC@3f)Az@=b7WO%jV+}vDxdivz#BtZ}wjRpX) zyu3^h#Pjp>($doO^z`iPEUM)3c)Pp1D=RCfr>E)Z>04V{D6dp12L=W%FE9CgK99$9 z`-WO3lXY}-U>Mfg+B!ZyPUioniLh8KQ&Ur=rKMgS(QgPR)M~X$#w`T}1!xqYn3TdW z4EgeU6^TeBLTfWKGbbh{P)wTpn&IJLE|*IXgwbdO0GynhxD=$Mq(~$Z6yM(70szcr zvy1-u`FV77wB2q;<0~pE%4V~@p-B+L&KL|ve0==t`ta~@6!`o50{|W$ zA6*I*3WdpJ!Y~X%7#0?0u~^V$^oC|_Z7q)D7KZ-cBx~He-;^G3waj8`L^6~-zh>eYPI2;Cp!CP@0$K`VQ;o%{9 zjyE?q(PVgA6G9jn8QI<4Z8RG7dcC*%1-^aGWipwaot^#t{dT+Es|_O~Blq|Bk%^Cw zk2sD82M1#qrqO7mQYos5iHRvLF0QYyKRPxv)Rajh%IE|bZMii(^w z7>4EN=c8w`*P09lgU92ww6uhVhGu1DS*_Nst*xIwe|mL9|KU6nJ-ngOxCKygL!Qn@b_IxfDX1OChwm6hfOzA#Q$JpP!%q{64-VZp`I!xu4(1w*(UO|8psWp1Bl4 jn@b_IxfDX1OCi4iz(FC4v8gEK00000NkvXXu0mjfnOjtX literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.map new file mode 100644 index 000000000..d41d30f1c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.md5 new file mode 100644 index 000000000..880e7c145 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.md5 @@ -0,0 +1 @@ +a08686bcc5f729a82c296a6cc288080f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.png new file mode 100644 index 0000000000000000000000000000000000000000..bc365a65d4a851153b0ab9bcee29ffed158703fb GIT binary patch literal 2195 zcmV;E2yFL>P)92zy>9{ zK*3O`3L0byZyq1e^CeVq4euzV3IR!tv~+QIqlW@n7WhEpQD9r-PC-En3Tj-_!*&;F z=RVA(cA+h8sSK3=FMgQ*=b4A6JUnzdbVM)=0}uoe%7N$tAP9nU2tmsLoI?mA9-Ko6 zBA%oEgYNF`;^JbWN?C=nv$KPPgNd%<|6*cdh%R9j2@Vd<&d%07{L|~9LZJ|g#YReT~Ai^s;sh^}H)kVqum-QD^tj`M>W8ylCZo>dJ&5TZ+%D=RB2Ha3>% zD(v6uih_~YBkjZ2U1OlR~fCykuttV^_Su9p{b@j^44_OVi zem-mFFg!dwGc!}SjUWhuATBO03gueh z#035PI3ACOAV__Ey_p#>4BNA34}u{5{r&h#M@L6^c(|*p>xK;*PMtcXR4Pr!FW!d_ zDuJN;n{TfD@yD#KaxRA5w|;nd_{fnXR4SE9rLx)V@$qr}y~bL+_}1It^)MqN1H-U) z@7|@Pq$DOL4h#$|KBvuTwc47Rn&Zch^Z9%;4=F7zb#`{vU*Yk1IXO8Bg`%aUrL(g$ zJw4rYywy~y>AQD(Ih>nx`ag1W8@s!oEzjFx?637zRaG%DF+)Q`QmJ%mYAP-+PJgel z7B9Z_HajnMadAmYOG6MuE|;4VuRD2&i;I&=rALn*MG%C=VgUdmBO?(6ad2?(@$upD zc)A}!rBa!Zk>TUxT$^5n^nA3x&jPo6vp4Gkre$^QQSEiEl`^5Y&pd`O{CDl02T zMn?31TukJwsHi9@DbcUFwY7Es{{3V!IUpb)B_*Y+t4p`bV7#R?8f{nC)AV!!oqqP) zZw0^n@*j;x3&3)mKz;Vq`l6zuLx&Ezxw(0Hc_k+&_w@AW;*GV~Cat&G9I8~R>({R% z2oe+&WYK{Q4Gn>Tfwi@@7=}qC5&*!xd-pI5o0*wuYHGT5>(-q+ckoCKhtu2Jd;k9Z zk&%(Wz`*wQc6`0QzW&OUD-#nFiHV6E4#(h22cOT+%F04fG%YRd#*G`gb%QxI8ckAC zQgLyyySuxwvO79Dm`oKP2fG#afH*_NI? zwO;4dt5zo=1qKC*Npkf%F5VmHils@Uc3MR3=Iv<3D~h?M^RA`zWx6FdjP=L*w~!>~P$=Ybxdw9%4h~jTRrU4t z87r@%q9Q*(zpbqeKXAc#gMRv{pGr;o?z>+B_!VE7nK5-G#@9F3qWo5Hbfj2%h@G__ z$K`U9l9DDSCU`tvNJz-w;Na-!sKFLn*Ls6&Fo!rQm0De0?dRuLQ&V%|#0iUzb#VA} zdOSHf86O`n7K``o+qZ7ry0WsehK2?JfVa1|Mx%N5?Ahkcn=MMN)oQD&s~1OOBi6qJ{jx3{+k1O%89Z_L4i z%nu*_85{fefq|(vZC=}kUE*@N`oDn|M5EDUGTH3xtfQl&TCLV< zwXUwND2hrXl9G}V8jS`3@bdDCjEp>X>=>WV_w@7>i9|FSEiy84!Q>AfJOBXbIspLK zy?eJ@E|<&YbUJ;0&V+=7goFemwo};^X7< z^76KA+cr5lnV+A(e*JoXe}4vpVXVd0wSGPu{~bR)Jzb?z>CUjtl$)E|+}!N!?95`Z zyuH1zUcDM0A5SKev$L}gA3m%L69@!!Iz22b%-7dfDwXctyVsoLd_F%SB0_%!MbXgE zQ2Z*k`8lVirY>K;{PN|?ty{O^e>Zb-a&%g z!anL`2dyWONE{9)H8qt&p#%p9E0xOj_V%@F*IM+9tb<^BmzYE%5&oug3BE9dAc#;X zoPVFu@4wHqwm$y;d+Eifo15h#(Z3!&dQNmv(B}o`aQPyWo!RWK*zB*~y!kJR!cN&U*xePt!{aYR zmjHcUE9_zb1lc7xhY&YP3SWj8ynlWapRws z^gr~C-){jenFa4}SV}~HGgg;5_gf&a0T4tu`2G-rhzI8of`|v_5Q2yY=MaL3_dgZf V#SJuhcb)(M002ovPDHLkV1m|DDf$2a literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.map new file mode 100644 index 000000000..ae7dc8f2e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.md5 new file mode 100644 index 000000000..3ee74b3a2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.md5 @@ -0,0 +1 @@ +f936b6c8bdc58c028bb8933191b34c6c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.png new file mode 100644 index 0000000000000000000000000000000000000000..5db982d56e0d9d0186516cac62246704b7d6c911 GIT binary patch literal 1725 zcmV;u215CXP)Q5d200006VoOIv0RI60 z0RN!9r;`8x269P6K~!jg?V4{$Q(YX#&zW+|p;KZm%ycuXEW$FSW-pc*q=U^c*4zr$ zwhD@&D~T9LL9oQ4vZ6n%wp?SDf5JCPSy8wb<){R4Ga-}N?&eBHXvD0g_dYMq!+ma3 zo=1D6+w*ikug>}2bAR`D&-b1`_im6RNx;G=9HtXsVLkW-U_D?S)&u5=r&oGiG!p?{OE+wDGZ;J}ZaTToD7x7&a0T(j8>A#^w#G5U)aFLv(S$>;OY z?VmYwW^!_JzQGq@92kv8k|e|7@WF!zH5!fA>y2p;4u`jG+xF$l7njSGmX`MKulSQ8 z2*PHw?ccxOVzJQmuC6YLM6z<_%ID9Yhr{7JckWC~OmuW~%s2jm%|%=;*I+O}2t6JT zUHAEXTefV;&d$Dn|2~h$0|0#f{Ml$U3WdUyloXjv_U_%gm{3=)T*=GJqeqB~iyIjk z0pHI>8#Zh>apFXAaWRj_TfKVqqeqXBE|bY1gd7ehD=W)vHlvU8DwV3Yw^ygrK?ucS zF#up}Y;4b-JpzGX>C&b9_U-%l@go(swzjsYs3<8Zskyls0PyhP!zD|WT)TG7=krld z7)g?c4csZ`UoD2a!nR>eZ_d!h(VVO7wcYg@uJ> zWo1sM6T>hhYBZXmp`q^XZol83lao_kUQQ4MJ=EU4dj|&x`}+D&)o!;J6%~m@qL~+U zI2`r$_3z)m*Jw1Am6fQwJ3Bi`lKl4VTYG!^?c2BS-n|O|Xl`!K&(CjcY$Qq2?REnI zluG5q#6(|T->X-za2&6!tfa!;x^=6ru5NsMT%}S004x^E(W6H(3^N!EH*VZOZ3YJi zM@B|88qEUq9Z935r6oq0m6DPYH2ull;rh#DG|qU06;JpMAhl( zX&#T)-``J?RU0qF*BtZ~Dq0s4cBAwo5{rdIi&!0zS^b`jIftXY; zUAk0JQGv>o2P8=j4-W$Xd_EtlqOm(VI*P)g(SryEgBcka(P$LSx676-i$o$MNp^R4 z0|5Mf|37wD3<`xpp-|A31zQis#>V7w`KeQtS14+s2I> z6B835ghrz=5D3gX5y$cP_;_k;WoKt25mhrYGpUv~n+?Zt48tIVd_I44bQC?Qsi~;| zfM75+tZf&1R!S2;s$x7Y`jew0-;bXV0Di0E9vzhrC+QJ3H-myGo@(T|5^)eE6VNt52Rh84866f@o-Hn3|eGhd7+SZZ;z$ zV`^&3@AsqX+qZ9#NTrPm1VLD>)`5WmD%Ho2AEW7L&6+hLk;v(E&a2qHN-8N)EQ+uhL6Kpjd;OY86NN0zKuu|gt|7z~C`D1_s9 zb#=8=DxJA!>+0$P0IXfRmQo}ViO1vdcsvlo>({T_Y&Mh0G&D36i9`kl25M_-TU%S_ zp6#DEJKq!jo~o*tO*chXmOs4w!dbwQQ(b3^>IC64wq*AFsAgHRU(rUGf7A=|? zN~hDgT&}FFtWBFX%{>8;NObn>S+!ct0YUq>L@#DuIJa~|hkbw3@EiEmHiHW(n zx%v6|>FMb+_x=C?i^U?9O6dxQVa3J8Xp>r6TIzDSUcY`V7K{0OzFMtLPEMXVrvDL0 z(*9S`+S-a%u=z$|nLFs)HT?&I|Jb*R|0S#k%)@%XJgf)I!+O9xtOv})dcZuh{I}%? z-t<`JP9P9izI-`dnZ<*Oii)3=&u@xCp`ceG`&P_2?0UdFtOv})dcZua2h8&acHeOp T?v*Nt00000NkvXXu0mjfi1Svf literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.map new file mode 100644 index 000000000..975bb02bf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.md5 new file mode 100644 index 000000000..04d962ad6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.md5 @@ -0,0 +1 @@ +87662e5ac3f382c4e9890e2f0c246809 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.png new file mode 100644 index 0000000000000000000000000000000000000000..1ff0ee12323852716c57adc37169794085afc8c8 GIT binary patch literal 911 zcmV;A191F_P)i zsv?M^pre9_LbO4U3dTC7polouMVC|@N>Zi9!FEv5423rDa1iop^p%)KNb{TSdG6uv z|J-Me08tdN65!8o3(yHOPh(Lkd0ON~JRVf#=^|gSg6UfzrTNGW=1Ll00011tF@z} zV}E~NG3=WxFE0ZC_V)HvsQMZW<}(xuiK3XzW~Zj6#>dAKiG;d#3WWkml9Q8@1VQ{< z)jKp>w^pk)5C{MO7>4;GjOY2m!NH1(3YW{Zv9SRF$Y!&s>g434y1II6Yb%vX$p`D@ z9@Bx74kI8QxJsB%}oG6S69~;VSc~Ava*t8S(>IJk%+vCAc)!7 zSqNbu5ZK<{mi%L5V^>#Ku~;mXN_BR2o}Ztq(I?8FDC(U@5wF*a)+#DXO+g50npO-$ zB$G)D!!nr+GSAM=B$Ma)#>U26E{C>2U0t0Z2%;$7-Q8grmP{u9t4a=z<2a7XJ(}&$ z$H&Lv;o+sFrF=gBStQT%<>lpeyB(PhheN6&Niv;ILkIx?cDw!I;QtA1Ar47k(94ZtFg>X20eSIwr|LN%|TDmPQE%|(& zW!WFf)AIhTs;ZiwpI=#7$>nm20c~w=7m@$?_!z@5m&+wZc6WC( z48t%?Q&W@A=bM0rxkK?$7g@w`4QGNQ=`}?-Hw>KJ%Ha9o>d_IrIv%0#f zPrrK4XH8Ab!NGyfonq#D#b}s$8ViMU=;6Hh002ovPDHLkV1gwTwc!8& literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.map new file mode 100644 index 000000000..e760517d6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.md5 new file mode 100644 index 000000000..1c90a6e8a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.md5 @@ -0,0 +1 @@ +ba89299cb349c224517905a60a70be44 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.png new file mode 100644 index 0000000000000000000000000000000000000000..d6dfbd599b8e0999656c21f927b9c50e0d9f85d0 GIT binary patch literal 1369 zcmV-f1*ZCmP)K~!jg?V3+W8%rF=XVS7Qi6kO1hpJHtEh;64QfQ>;!AldGRPR-ZZaPx}Vd`cmCw}`|i%{Y!b*Y4B+|i2u?eIvkGq z|7nHto73LjUR+$vR{wFwg+d{(*Za#uIsM*4EbI2LC;*Rx5;XaB%R5J~ua4US2MhN>RW)Jw5Sw z9Ao|z+;Jw8iD4L$BP?uOB)*-Mx!w`2{Rl#9?ucwL~h->g_b8Ovr`cSfs$dHEEY>R9F|BV zpFVw3DwUIylYYNnBoeWGZrr%>bZ2J=-4L0X zndln)e99n&OEohy)8%q~`0&B)b{}bKYHITNd<_i^$KUu^va_>evDp6pKB}&*t)W70 zZmvKeAW4#YwRJjOI2<+@44s{wySuwIP1|g?!^1-W08P^_mn#?yvYlVQevMXZVPRoj zUf#=>FH@3lD$jB0>FH*(`QgKdi9~{{mz0z+3}ZH%zcW^$P~5zE^Zxz&kw|21ZSBE> z2S}I8<#+DfsjjYGUS6gsYJPscqN3unoTh1sL_!e6?Ch+~W<&j_rltS@MMXvI z%%!EJfj|JAgd7fs+wJb?=vY}i71W{I2hR!8wwR&b|W^r**rBX?yQiH)Dkw|np9Zss;CGamF4u2rv|9Ck3nefJ8 z!W)MPZyYAPahUMNVZs}S$q7FX;+>@bG)^#1uh;+jIL;i9;r}0p1;58(!W)MPZyYAP bahUuC>r&o#Wi+7b00000NkvXXu0mjf# + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.md5 new file mode 100644 index 000000000..854d22bae --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.md5 @@ -0,0 +1 @@ +ad82d3480a6e94b8a6c77c6da65217a4 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.png new file mode 100644 index 0000000000000000000000000000000000000000..e0006ac9da42db098adeac09c655b009d6b8fafd GIT binary patch literal 1340 zcmV-C1;hG@P)MDv6q8x0Xd z@ks6wx$nU=xik$?5}`EGmZDrzHB*0{eHgR&-;AN zd3P?~a}Fd30w5@f%}*DA_z>g`bwS=x7vv3fu_bp@DphN1>ra(}2oDc0DJd~_U!6Cn zr>A3MV^%K-0RRAMwOXZ8kt4Q$PZ}K^wN^cdKcuCly@{av4Rt}@P#5G4b@?UUuvo02 zp&@G~T7e(-hQr}VrBVv&e|KS~V2(F&adE}P#l|*-5JE_&)0s@>@bEBs8ibI%hg(}) z5JD#>Cu2mdR_Em87}{($yT8BRjCwwStZ#N=K|z6GA8l=4J=T5{S1OfpadFPh&I|@a zBof`++?ZFq1>Y0KR+KrxV5!q3??QfYPH(c)l~q% z-QAsBF3-))C1)8g9qH-mYiny+Sy>Q54u=B(=;-M1@$qqVbmVfm>+9==`CeXL3kwT| zHjd*E!t3j6Lw9Fqhs)(+7#0!|va+)BM*ky00Ko3A!M`Jf7ESkghF9YPY(cKaBz^z<$8O2zneZX zG7=gZDwD|wf>5i~dwY9gv3O``=<@Qixw%;`mw#D+L?WrFsljoa&*vv3BwSovkViie z92gjAY-~I~KhMm}%*e>F><2BSQpsYm%*(ZaH|_215JE>sN3mEuIXUU??@t~T2n3Up zlUG+)5{X145}BxJXJ=<`Z;xS^gM$Ny!)b1A{xT&mFE1)83d699iV6mUF)=Y=qF_-` zQCL_QolX~tL>i6e?Ci|MBEO`wvs0;5no|6`SnPhI(P(%)UUhY~Uau#Qy1To_$HxnW z!u$LC*w|PTHGO=1*x2|o#n;!D+{SU-L_v3VcSD0lqX7UO9v)0A z@^d;nJ8Noc78Vx#{QS&Qu-G-t&CN|Jl^z@%^!4?<84`&^+4TWP67e~3_%A62Q!Wa005F7OB4zPpU+2s-uwuLZv^BI zG{5A1+OGt8LtT(J)CGA%U641_1$jeVkT=xjoqwPd3WfFSK;St3<~`Fp-thT+Yt@5z yMQUm)xeL)-0Lp^yH`E1rLtT(J)CGA%UH$`sK_Gc%dR1ot0000b{i literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.map new file mode 100644 index 000000000..769988ee6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.md5 new file mode 100644 index 000000000..a26a3b99a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.md5 @@ -0,0 +1 @@ +c57cc0030c7d3a9e44b4f20708a8d83f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.png new file mode 100644 index 0000000000000000000000000000000000000000..e44e05dd8d0b8a002cfad686446f623efa164b39 GIT binary patch literal 1161 zcmV;41a|w0P)p!jZ6Ti!RetzEB*~w%wK}mCS zbFZ(jUrnBYeiv`t1J9cDwQ&u&Aq+7Mx*iPHzM-8%npY`B9YY8 z)SRB4Mj{c5#S)9f_V)I^d;^St)oT3^A*HRY4QTPfP9~ED1qBw11s{2Ea8O@g|MvFA zX0u%`7ap&xtDBshY;JC*)9G7VTY*48E|(V-6$ypH#l=Mkg2Lf2hGCD7j~b1J#bT9} zm1(uw=jZ42nNz70kH_op@Bh~+d_bvGDwRrNBxCzaJRVk8jZ%`;b8

gww3>})g|Rjbu1m5RY&c)eb`-M+E0fsg6#?vBM`mzS3p7Z)gs_Vo0m z&wO)pbANxY)oL>^AEHR#>lZu~f*^Lg9Um492Dw~rB9Xu_EE0*7mzT%malBs)1_Q7? z9uM?SgJ2kTbaVt zn4X?aCX*m;Hk(ltMGyprVJ4Fq3Wb2~fXd2BU<89fI-SmBGJ(tI^MQe)D2+zr@p!-$ z2m~OQCNqo00ttUUsf?{77K>#vnY>=F*=&X&D3wZ?OeVM6jsF6Nhlj+a1j8^eI2_K) z%S$8@0j|&I0|uANeSd%V`~ASZy}bp&G?|4$A&+7bb zCMJ`q(P$V9hC-qE@=S=E&41i?|0w(W`z0kMS-$D#eV63>OZKr^tuz{~wYAmf^No#- zsnzOSSCk*`M=dQaHk+-gs;Z--Ln@Wd&(G(&BC_vw*{8I$bbEU{*H!#NUi3>ILg_*d zr3*QfF65BxyWcn+{@)1%0u>b%#0ZHlDwQf*_2dysrIP5v81?@bGN}E997-2*C|$^* bbRp+&GutLWmQr^u00000NkvXXu0mjfN|7aN literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.map new file mode 100644 index 000000000..8756dabf2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.md5 new file mode 100644 index 000000000..cc64f617c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.md5 @@ -0,0 +1 @@ +388b2bb7b074fbc6b23cb65b17a2d52c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.png new file mode 100644 index 0000000000000000000000000000000000000000..00d80fd2a815c93944aa1ea1917ae9c0108239cd GIT binary patch literal 1573 zcmV+=2HN?FP)kOK~!jg?V4{$Q(qXz&rvhC*_h(AH4#k0H!?(rOmr6ZqBMsX=|q^6 zf2OWNk(uCLgosg?g`sWWVyl$J`lAq;lo(3s5EcIsRO`>^I%F-;vMK5H_Tv6n*QK`B ze)AIN^Xi=EInQ&Sd%oOz&$;(Pf*=5bmiX;-0f;R@+RzuI4Shk{(3b#eXLxw{%9SfS zRSF_GIk~#J+S%Q3-F*D`@!q|AJ}(IY001VFX?S>;Y6 zp)W`q`hv8fFaL-(@$vB;9UZ<5^Z`4pjYuTYYPB@X|9=R^x&{XaQ&UsPIqC23_pEp?TsM`Kl>|Z9?e@~r(!#>R znVA`?GyGMT4OpN0@lPft6I$BrGd+wCJGBLIMP^7He@#>P&aIt3vVi9`T^YuBztM@O?*EU{QTK0Z#4kBp4$>+2)i7=}Rz z7Zw)C?#q`i#bPm=%}z*2c=6(eOa84A0svmUdX=7@&StY?V`HB@dGc%ERx~#^=j7yY zIGm`csFISB(a}-Tu2QLrii*n0%0fayVq#)iTU-BdF8{-8+Bh7Jwzf71p-?FNncdG% zE|*`wejNaC`}S?ISR54GkW^N~N-+qvP}E&rMBD27}?Z z1!y#yhK2?V!=zGaW@hH6PoJpXZ4%zPb?f5Ai*s{xg@uJOnaqO^T2`x7uh(a1X9ECM zS681ue;yVV78e)CVzH8vk_H9_{xl(p7qn? zZdZ!mhGHZVNpElO$jC@~dU{$~n#17$05BK~=iJ$BHtP8I@83Jy@7}$OjEr>2ziGn1 z2SUi>@#^a8EEbE|Y-TVRv9YmEFF_ClLAacnn|O17!{Kn0N@ZhX+O|7l10RWypeOgynXEvKxS66WyUtV5bUtb3R#K*_$bh?Fw1&hT}TU$#F z*Jv~Y0|Q^be!YD8GKOI}IXP7CRtY@@$ML+pyorg4m6a8X#d7}q`MrDhlBy^aiuU$) za`ATI!UY`142w~%o;!E$@#Dt~216tg9XxoD!{KCPWQ2r- zT)leLXf%?$qDz-9+3j{dpP!YLb^Q2oYPei3SE*F{_U-HJ?0od-5tqxQdbdjG4qB}i zLMV|)a2zK$I(EC=-``&*lT}nygocJDCntaT^5xmHXS;XrCMThyqCz5(L_|dN^z`)f z^ze8*4<-asmnBA{Q7V<9KW}yf@*4s51I<73KJA|bX+vL-HuME)Ltl_K^aW`{UywHR zWs`rPj7FpH>p)-_=JK9t6K$kYsjuomY~aL+6Vxt5Zvkivdfw0%qz!#R+RzuI4So3m XG|P30+vN2;00000NkvXXu0mjfrZ)w> literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.map new file mode 100644 index 000000000..eb655359d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.md5 new file mode 100644 index 000000000..994f3c528 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.md5 @@ -0,0 +1 @@ +5a2b620ebe4a488c39b0491478c216ee \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.png new file mode 100644 index 0000000000000000000000000000000000000000..9d2c7f0096cb4f04de03012932251d6e726c97fe GIT binary patch literal 1583 zcmV+~2GIG5P){LYK~#90?VMjoQ*9i_KaaePoUtsXP?N~OqKFYCv74>%CRa(+MbG4Sahxl4Q z8L_p@co7JNRRroFAL4V%qIPEHOtZ{8#l ziE#GpS>C*P!=+1?#wCZOUncZ=J*B0k2q6dtgQMD3ty)DS5}~`h8-RE3-qF<5#I|kQ zG;zLMS~qOiz^z-i*t~f&LI^At3jilhoFF?po3ykvtX3;MJw592Sy@?JzkXdUhe9EQ z5DX0ssdasQeORql37cb_?Gzo!Lo|NedQ^71ek49uH1k89VijTsBz>eZ`E zpFW+Mni~51`$zq76h&eC_U#lG7gJqb&D^_a_aj>M_4OP%a)cKz zUQkq2#HLM~_|~frNmo7!G*W+@z2#3QA4i3iE9UL5_r>95V z8FV_Gw6wIS_X7VL(qu9vG@e9B`aMH99HyY4fc^XTGcq!w>6e+AiQR6;;c)Q&{d-od zSn*SO+1c4NH8rt&_il1?b15z^=JxH|3B{N*XO5;E3Wa`3D>E}w{hped3NYr4p5O0h zU|;~9PKOWzqtVFV;2_P-%>ZO%WB~B|`SXOvlPF2QOk`waP+MEeAod_X*C~iuMHuZvn0@~Wz=Ry}c-kqJG-j+to|O{Q2{lJ$rW2_bw)6pCLUx9k<)fp+krG z@Zp1|-DC<<=3`-fxBm@$Jpckb}%(uiXkBp3rFg!d=EEWSk zZv@rV)iE?Q#ItA5C@(M9#PoW-baZs^_U&7$tE&lxLabf8R@3i$T8Yrs)&{_W1q(*i z+iW(1!Jzu6?eTc<`~B?QyO)O#9}Fw>MqN0L8Ads+bJSJ?@X~&KoM59sa>gvWN z-kv>sxN_wRsi~=0EEbk6TSj_%I(ECAY15{0?AS2^fq=SSQCV3@Boe`7GO>E~YSyh= zr-|usIH;(oVCKx3G&VMJ`SN9TiT;xBX(fWs=fiHdYwC469eH_q>SJbpem)%?9rX3} zVX;^+8jWn+xRI$-r&3T*kg#rCl&@%RZdT${Oa2nRF~5O7W;E ziZp{nMVdjPBF!LC8S_>7@!Hjr{9bf+c8=LLrWwY1w_fu1A{0gbKZ692|IZ-#5@`mB hiZp{nMVdjP@-IgbS)YLiCV>C|002ovPDHLkV1mT-1H1qL literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.map new file mode 100644 index 000000000..5e69d0b66 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.md5 new file mode 100644 index 000000000..f6848c29b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.md5 @@ -0,0 +1 @@ +a45b337701fd72c704017f44bd397e8d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.png new file mode 100644 index 0000000000000000000000000000000000000000..ef8c7f7b0c0a28d91def468c57cc989a7f70d088 GIT binary patch literal 2616 zcmY*bc|4R`A0IE-vSlx2U(2;*r>GHQia|;)Wvqkj%Fb|^!i*tfi$StxsiC==3WKo@ z*A`ylGL{f7LW8l)+~@vv-}iGq&+q(o&Ut>{^IcAw9Sp+Hdw~}O0`WtwZruguPT*7G z<^(Fs2m$XL_HB>HTH_BhA(;cHritYR*w5gS(hXDUS3{cdo&tte`&ZoeY&{gag#i% zeIca5iz@tOY>dG?-qtf79UZNQx4DjeK%T~wm6t=Vs8jDZAOgvKW(_-i~HorJ(| zmMMyws;ct^J|(Z~>M+G7k?(zmrNf>)(L0?DGN`Pqyv96S5|xn1oOa^$9M6Zcv9UR+ zi;G&kuB^0Bz?(#B2&5#(AMdk;9R2jGt*iU>^V6FA;Rowc%pXkvAxiF|GH&vz!xY^tKcwziqm`%9T-xR)3wH0Y5zCs?QRa7YQak59whD(@4Ze9HH-w>ntBVEV3+`c}mq~v6%jZI~Fxp{7N zRTXfaaj`)8sMXDzZ0xT_;6w!f!CWk%$JNC}%GA{KcM{2y`1Pf6c&+8!^fa14AoTQ3 zjEs!5*Z)e?lH{{4xcW@#PTmj3>MQ@Jri^bQU@+K;6m%&tFwix)6u{o;tz){S!cuRh z&)S#DBBLjWTZ>Y3uMp$n`bW*;7WSza%$V`yTHnwRV)k=5DB#bJSzTSXFEDVKIBZ%@BxX~yRXp|aq0O_P z@ySUARB2n=tG6zs-BE~4P3ZOgDbI`7qFw~IojNu>aCIF@7BscGcTe=JghmCC=&;9W z_weB#01Bz;=@%o?#l*x88H{u1&UL)^9x#mF{r2KB7K`ob>hhgNV=&Q2Yt^G0bbtz` zhx6>%IN)b=4Gf5ZGy2oh)2Udj_rca|XT~-z6*Kj_U$$fg1E;8>a<*=wwub#Nu&#_u zo~yG(BFToxlaJiIyu!1yv+~Bq&H*&?BY>M}?d>+8aahXAxFA+R-G-=^gU zPXWlpY)u&zLSSyv%rEi^3Krhpm6u6Q>K+S}XJBr*p<)x2ATk5d=sh5=*&H4oPU-FS zv3mvP9;MMV$;>1Fb0Q)ND}#80H!yqqEN&j2b18x{jx!mTOq7F~H}yv+Csj~Fl!cH~ z9uZ~k>M=Ex5Fk-=P+3z`xD_pbNqDarF@C_O0xN3wy1KJoM_3H|)bf);p;$qoawaBt z9iO2WMMWp1lk-?hKzGsmUwzUr7=BQ!K<(Ss8b5_?J;#y>SP>E6bHwI!_a=$l$j67W68l1Xt;lg<3T|iqJ`4|OA zM!K&xdph;W^Z9u!e_YT{^XdpwsuZ#?&#Q>ONN**F{pxF|Js^@^%0 z%XrtF6@2hwh#|M2po*T}ed0AqSwIITCvnQwFK^txFE;ZbP(fFB{LXe5*%E_B^D5hx zSl_+bIUZDj?QmDPbYnES`>>KxyCbR?aT>@d@j_6zS`wq@<*ZPNI5ImcwcW^in$6+84VqjZW&Q=g&R#@t;`C6+)Pb z0n7clPa`72R*NHR<4;dc68EH5b8 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.md5 new file mode 100644 index 000000000..851893b9d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.md5 @@ -0,0 +1 @@ +189c2435c324f1057aaf97e832f8d5e8 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.png new file mode 100644 index 0000000000000000000000000000000000000000..d094da5283f35378a97baccd14a7440d68cd879d GIT binary patch literal 2503 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 RyK?{l002ovPDHLkV1h+q06zc# literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.map new file mode 100644 index 000000000..2668a5553 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.md5 new file mode 100644 index 000000000..4eda18e00 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.md5 @@ -0,0 +1 @@ +db104ffd0bed1c2b2b66be9a2d94884c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.png new file mode 100644 index 0000000000000000000000000000000000000000..842798e42ab3725cc0ea4103aaba9261996bb4b1 GIT binary patch literal 1440 zcmV;R1z-A!P)a~}>2xzYA& zotvR`eoyCo=gY}|{yFEHGhrY}l7PjraF`bG5MfPc0M>K{U`=NLXWP#7^mKcBJ5y5r zViXF+ix)4b?!Q(#j^o3_!w#49moq#(jN`a%#QA#C(9n>h^gIY4gmw|OrZWI*Is>q# zGr*s1dR$zbTCHYU#hv-HO}FI_`T>5&^wiYU^73-34IzXOa=F}yh={(vKHD@1;l#uQ z6^V(7X=`h{r{bS6Gc!|ISV-f94Gj$t!rtCq8s|jNu+rsnIZ2X7M@L0PMR|F7%gf8u z(6eXHs;a82R_p!0#la8+q0wmGym_Nisc4^^w(`Q|a%D0Zgixo`Q9-FxYBHHVeE4uZ z-)uI^GgWsW%QpiZUb$mTP&8&&Q1tnOiTp? zcKLaEc^exWQ&UqrJ3B(5Fe4)ad6Ai!d2({HxVSh!Kab;hZf-8h&&|zUSXlV_^{Za5 z7l}lZlas&JGdeo@?%lin{r$MOxa8#IwY9aSrKS1#`7d9-jEsz+oUySnk|ZxLFF$|& z{PE+*{{DXI<0_S^qM`!BFqur&-Q7*a?<(VFNE@_TtzG0sQc_Y-NkMIDDh$KWWl%#k zH8li5#Ky+f*4C0FDH4fVTU$wzM32P=g8^k)tyWi8*QKSUt*tEpfL^ahakOcSMkCq> z8yg#TN}fM|-qX`_y&V}D+1}oc+LM!$5JI!rjJi2FIn~wG*Dvb*`}bK{S*UF=82Eht z#l;0Go4&rj7K?=>$)CyiH2?suR%;uft)?Fy9;T(G)z{bCRd5KQQmIrbl?H=>3hMQG z0DzyLAG!%UIXRh3rtR%*9LJrVodp5`N(&7Q1pweUzP-KeaFv>bm!#*NTc zUOYWL)oS(D)|N)2u^Wnyk55fat*NP@B7uQ{91iE`=*af>PfJVV^Z8d-S35g9C~b3d z69B;H^92Hd)oMlifG!RW4zjbe>+0(E_Vx&Z=;-LUy1D`Y5CoxCt5;T5C}H2eeM1$7 zE*W&5)7{2!3-p!wmbw6xS>v0Oi{gocK`efyR= ziU0t5dwYdKp;#>T^71MzEtN{8j~+b&0BE&Z9*-9h5g`(Z{QUf=WAdj@pTfh#Q&Lib zgM+_+|Nipj%X>-{2m~!HE!o-GuCA^Mh2qt#S17Jhsl;NjZ6=0cNl8iQ>`0Fc+YNrp z8!5}30RP90l;y6lrZWI*Is>q#GXQHk1F)tu0Bbq}-0%v<;NYO+bv!6;Fg+_P%kerM u6p&=!Pj@(MO=kesbOvBeX8_i82KWcQGK80AIh@u20000 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.md5 new file mode 100644 index 000000000..5af67464a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.md5 @@ -0,0 +1 @@ +47e03bef0106d920f6df1a4650c42161 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.png new file mode 100644 index 0000000000000000000000000000000000000000..356ddb54bcddde9e44a7f258c6cae2ac2d9b718a GIT binary patch literal 1494 zcmV;{1u6Q8P))teC%Z=T43sIWnm&NfMGIQBY7oWo0Ed zZ{Ez%{KzRPDq`!_tvr1Aa5l=BSAxMH2M!#Vk*1}k1xb=~=enBoPXQvgYV?I?kOt$Jei42?PSv)YKqJ5(^eAz-Tnm($d1ucb+$H+{nq3C$U&8 z=yW>Pu3gLh`}gJe@AQ{1U&d%OQdn5Xwr$(!?d_Fg@pzoQd-qaWT1r`28T1jg2Um!Xf#q%Qo^A_hxq>eyBxoF?;cB+F6HXgt3)D^i~;gH{hyF`^OMOW zSFT(^k|e6Cs&dl!{eFZHjE|3V`}S>a+_*t!XXm7x_V#wpo;}OZ&=3s`4cKfp+2HB) zZ{ED2xw)B+jt)M5{>+677bb0c&z?Ob5(%C?d&ZL|Pl!gN*lf0(`~DT1%|>r;FL&?W zB@&5XGMRYr;DH=>xm+AQdK8UDgWYcD+O=yl(*F_S7rb7t$g+A`s;jGo!{M0J2INJf z(FniaKcyy-NQkDUCQ(#WB!-5DGPd8^+A8Ym>g4u@4I9M8ix=hg$jFEQL@XA|THnw5 zckkYb!oouF;>C-Myl^-y01=5q+0|C7ka&3jE#*6A%qwn9v0>0t%tJCv1`(bd((rcImBYPCp`gu~$=7K=^NmX?;vpBFD)48Z8v!bwc!)-$XfzrmNn+WuWef}q;PrZQ(*G%WpZ1q8Uyj@DCL9jq@pvZ1e*8ebefvf* z7{p?+@afYh>g(${b?Ov@gM*~gX`D_c6B83T^_Ppjwzih;?rt7GevHLp!E82@OeWFm z^-N4m@bTkEIk&H`4*5-@Y>GZR~ zoLuJ@7Z=mq+{~FXXBZnBn>KfJbd+>D&5|Wc&}cLSgF&25XU={7PT$kh!-*3o==2$m`dyNhA`q zwYA~*`|0lP24LN~b(1t^vzbsRL?{%RRzDle*`GXz4<9C(OmhAD^=b1A1_S5MpQpaQ z9-U6dv17;By?b}g{rpb9efxHbi;J;Zt(26M;B-3i`Fv=#S^&IWFIugZ%F0SiCKD@H zuKc6x?~aZR)~{brb#*lr6%{;v`jj0zcHnZkuv)Dd`5KJ|i^U>e_D!Xq6=raPpzF&^Fsk_qMm1l-sOBq}DIeYT`FwL(hf1CZ1OijWrZj)5XT4Sa wKS)BT@8>HN_5FM$qnfW^RPz;#YQBQ`2XT4QA9uR~`~Uy|07*qoM6N<$f_FdqK>z>% literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.map new file mode 100644 index 000000000..e7394ad03 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.md5 new file mode 100644 index 000000000..629a81748 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.md5 @@ -0,0 +1 @@ +f161f3f640d27ec87610fe7e0258daa2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.png new file mode 100644 index 0000000000000000000000000000000000000000..14d655e7ba0a3c2a1320a8b6d109441f43648a04 GIT binary patch literal 1122 zcmV-o1fBbdP)dFE6pQw3LtuQ2?LM7qQ;2R?h#tEka2$uay1F;}=ywi}q2}-yY7UQ~=J1%f zm}4*)Ff}z54=Kts;$n`+<3V$Cb3CN}TJ(B7W@cvMs!6vs9`h~RT47-!`uh4{GMONi zN-;k_kHW%2*zI;0jYhC63$0cQm&+B-sj8|1!!SrnN`hLg#=yV;o#@JT z4~xYDhGAeZ7`|H4-;h68SXdx$gx{sOxR^{%PKMhWjfN-`3gU9PNH7=-$K-N3+1%VD zcXxMWaBz^YEK6=~ZeC~wgF)i;dP!bh9&tLI?`p=9qf)8J-rgSZ`~AdXu@I?LN?KZ4 z$nEVdIXO8Y3Wb7j97hNtjf-Ij>^5xw)^}KA#W3@7qOMtrilA1PsHVv$HeY7fCagoQ#Z&@OzO+gw)hj zh{fU;u|OaI08p#dn46nJcXv1RdOez&ns9h{_=&5J58q}E!!WO6=jZ1y+Gl5HP%4$U zzP^UpY({^7Kd!E>5DJCha5xYQ1|w?5n)6YrtE;iTzK-49U6hxXqqMXX4-XGf^OBO{ zU&@4@)+Qz* zq@?icv=$2*jfTw5&c9-&roxC3^j+xP;+?9FKqG+rT^b1b^rhX07*qoM6N<$f + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.md5 new file mode 100644 index 000000000..6aec8ecfb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.md5 @@ -0,0 +1 @@ +2ba122d741860d8a73f208c9d30316bb \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.png new file mode 100644 index 0000000000000000000000000000000000000000..5c3154f570ba2ed94a15eb2eb37c0865386d7de6 GIT binary patch literal 878 zcmV-!1CjiRP)5fL8*f-O491mrCzWIZgsH=tx$?va1yMwWLQ6@sx=4pwG+-f(Lm=d@!jEmNrsSEv^PR(& z_szLM0tG<;WeW1!0)7z9n>s0HZx!-JBobL!S@|s~#naQ%GdnvgHUF8nWHNblbX0Ol z%5Z*u9*IQcnTpSY4i67YrAJAIhller<-FfCZ|X$zrcMg+*5BVhGczN_5JCu{PN!>Y zYYPU0ipnbr1?G*SC_xZXsno>81WA&2cX!3tR0PG=q)w-snwo+T-rnAdnU0Q*`T2RP z)mmFyySKOZ`ua*y6prJ1z20uO-{0Sh!!nr+MNvkhvA({3a&q$R?QLyst+TUJs?0D9 zilQvbepixW-Z+k1Utfn1S}YbRxxKx;yu6%Fr(G@=Ns{q+{Pgtn;o-q#GC7^jTrLLy z7#|ua%y-|x3ttpID#Ol zR7(C{9S(=VVBmQ^kx1lK>+9>QuCAtO+VA(fT&|j$ngS##dB5rP`nkEerKP28Hk;Rl zVc6i{pxf<^#bO-CU0hr^ozD07cMQYqcDvW>jYgv{FE1M#8#GM=01yNrNpf{{H53YY zz23s~D13MOd_Iojc6N3?ckS-(noOpFfq}-xMxW2;cDt*pssI3iK)`G^+ibR$mX^!Q z%ii8zalFUlIXgQu8jaoE-36*C;4Jx@{K#4IXVJW=6V01C(Y&dXFTUX&92}HhNAWy9 zJ~lTu%QIhi8yy`jl^%s52twY3g7*JSjcDG~NjZD_0HcV1Yj0z;VgLXD07*qoM6N<$ Ef>TSRDgXcg literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.map new file mode 100644 index 000000000..0bef81fa9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.md5 new file mode 100644 index 000000000..dbc1c97ac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.md5 @@ -0,0 +1 @@ +094d47bf89b4692d513b3c18447ea38c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.png new file mode 100644 index 0000000000000000000000000000000000000000..58a4979bb6bb0510e2adc6580570174fefcc2a52 GIT binary patch literal 1648 zcmV-$29NoPP)D1AZ00006VoOIv0RI60 z0RN!9r;`8x1|>;EK~!jg?V4{$Q+*W2f4{OzZnw>q?nPU+IU^WUQbO&8MnkjN_M(_9 z5q)9w2ZpScVFd+(ffjT9hoxgA3!BS&(FWEMg9umDAXh}LO>KAOpOrIg3vIj4iyvI} zm`^?H*>eNEpI7I1?%DYrzV~qMy*~y?k^~I2u;fn{u!vx^rVmDI`e3xCkBsC+e}8{# zYwMpXW#J){$@F?XwftLO2ZO=ew{O#4(!#{;cK7%9Cwnq}46@tpbk(zvsi>%!<6-7C zeK1x+tta2%IPrB9zeH5d#+p^(ev z9z1w3kw~DhOP4N*#bP#_T~t)$@pzC^C=@9yK|ly2kqF9p`t)hJT+ZQe)~{dx z;K2hF6AFdO%gZ?&j#MhWeEBkjFdPn}OZV^JU%7JSwQJXghK8uV0RVjY@`j|CwYIh*yRWYgLO4A=jh0naRVPlIAW1S1 z2(a1gfq{WJc?1H1%jH6LFc<^?OioUsoCbpd`9FXD3;-Yq!sqh=0463TkiWOLms*BG zp*3sP%*@Q7sknOe>S#1dlH|z92mrw6^ZimB3bk6TR;!aeX`9#M)ai5tK~Sl3a&nNdeED(~i^XQM zsbwq{0|1D{;?B;_5OC=J?e-SEeGbAS`r@g)1@AsR{<~f%*9FA72 z6^TSoo;(>F8>_6WJagvE$B!QqiGtf-NF=yiE{0)lx7%nm zrnH62mmH#HE&1Q>4A`*#Y_wL>3Kn}w&lgXq| zD3Zf443o>{=;hC9wQkt3p{%SdFE8)Kix)d~>`19{0DkM)xWI5aoje{d?P-5}HqLW? zy%@0BY#A9DJ9q931Og2W4g2=(qhZrUdLB|zQewB;*REZwR4V0ixxrwdVbew0*Q-{o zx^?Ro&6_ULzWyUHTGI!kHGMEz)5ko|#;&d|`s-MD5CkC<3X?taXsyv`=&EOdqgJbv umyl%se@z$6yrvIEYx-ccrVmDI`uGcWk&qO=0p^te0000 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.md5 new file mode 100644 index 000000000..569a1d5be --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.md5 @@ -0,0 +1 @@ +091acded027244d4f3129e0f10946f38 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.png new file mode 100644 index 0000000000000000000000000000000000000000..c39529cd3c9fd578b82c90443be7fb0ba8cbf687 GIT binary patch literal 925 zcmV;O17iG%P)rfbm&r$KGkq`&FSS%%j#X%jqh^Wv-3yDyObTSmd zNlQiQpy1#j2%>`ErYJ=ztvcx->flyU5d4{Hj6aQ7+vp%QMJ3H04wPQ6-U~6-Yujf! z-`kUq_iav2+5{?!0&;+Y?>3Mj@;S4MT*+CKUIc@|si~>&vZ5`Gjg12X1F7=2^BE3@ zS65dvZb^Ig_V$9oV7gND=cJXDl}!2hDmptm-zd3qedcp!7e6UyBocuTilV6E*q@a1 zGpNbg-rnBd-=7*o2qAFMWtYK~^> zR;SbT_Vz*uPfkvdGBYz{GMO+8Yi@2nJUm2VJRWzu-A1F4AP9=0uCA_--q6r6GBRSd zT5%k&sj1o8+Cuv6?JY%7IF8rW)~>CsskWzCPDzqxXJ;XV7K;S{5DJAn9?#O!(*6DY z#KeTp=R?z2mOVQ=+uhy0zP>h_&33yznM|UOyk774_;@4|VOh4Ts|)=xb~qfRrKKFl zt*@^yE-tF~r=;Qc``;+<($?07)+!pOS``-;Z)|KJo#%NB!;X)S(+>=X!vKJrn;TTh zvW(+6np0n2KRG#x^oNHB0DvF}9LE6w?(Xi8zO%Cf0Eoq6|8&SO48t(#ie}emG#aI8 zdUSMDmSq5d$z<~Re1n677K^33yZh+q2mo+#aRC6Rs;WX;S7Bk{bV^)wg^Pft(LXcUz^&#Shl<^7W&2#?1zHa7P1^0K|XJv=hGNl_Hbvg)0w*oXdqzGNTz5#)1b7x|poMLuVC@y>J2Kp>ELAKD@ag27-& zSKi6#a5ysM=L=yNCcT78{{3e*k + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.md5 new file mode 100644 index 000000000..07028de7e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.md5 @@ -0,0 +1 @@ +d0bba657e71229bb0975d1d5e96b55e1 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.png new file mode 100644 index 0000000000000000000000000000000000000000..ed97ecbf8e19133ba633e858c4abcbe4e9ed7f5b GIT binary patch literal 1579 zcmV+`2Gse9P)D1AZ00006VoOIv0RI60 z0RN!9r;`8x1>i|UK~!jg?V4>!Q*9W>@7u*Gb2)=)m^x2IWRXcKX%O1W2j5y@EOd}l zv;>W5i625C5SNgM77?-_oe;@-|Sh!6rioZz$50{$X+uepQwnmc%}xnmzY7#tj|t*zZD zDSMBL7cZ8SlrZ7H=Gtbny?ghLb4hy>qtQ4xILOZI+g#Mv*2a~dz0B>~w_P&)dCeWX z*WAH-%^keg+_9Uyj*pMmYPCD9!gDvBz!q(C5OX=yJrAq#c4Dey7Kq$-$g}55{X145~Zc3S*=#L9S}kWgCROPdUbU*I5^m3 zGBFyQPG?b35su>l0Rj2>`OC}82%*cDFDsQwx0)v>CyyOFW;UAv0HdR$Te>8Z$z(Da zJL9$UnjnamFJD3kV`F0h0231vR;yK^P`EAb>gqxWt*@`Qx3|A}^QN`6m04CMG84+Ajf{bI5B?Afz^ets7&TgnD~>0RXeJvs-q1{``4HMh1Ny6&0mYshA~~keO?n%?1Fl+wF9o zBuRgN|FN;L&0FktdstZ5+S(dI$l-7tJ$jTN2!zo0@81Cc7K??gWN~p301z4)Iy5x2 zw6vsBsf0qI&1ORgsZ=UjT$6%`~&0ssO718FvTE*!0FScaU5@IYT8`+^XE^wT>kj+NYkum{kZN zyVxb92@enV@$qpu9PFu)N~JDaD2mc*wd3RCOwET6ALwHQ$8nM*r>CdcZGC-xPn|l& zg#QeqkI%@+h}~`v3JQV{1_uWN0M4I3Us_taU5mW=`8psVptQ8~$&)8*Yikg~`ucjE zPWR~1Ba6jC5XAWSczJobUawzSS)nLOBobj5W;7b>>gu+8BZ)+EQdI--3uv@$q7@ST2`~L?WqFisN{7b+ueB_xJZNDJi*i>y`&MYHVzbh=@o@NeK!HQYw`> zIXV0H?{}$DtJNtfDeMe}VOOtSr9b>NH8n*>MkXaC9Y212czF2Al`FLVf`S66RC?sd z5re^CFc|1T_6iWOen;2q_4GS{x4Qq$(BG-Dzo6bt&*-}y-fQmQz2*+yYwqB^<__L# z?%=)V4mbZ<(ChWw>)3nD&CP{|hO#qmyw1qT;7ZRPM<$c8L&!fRat421a|iD=cko_w d2k$j^`~l(Y2!Ax%lV1P;002ovPDHLkV1l=f754xD literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.map new file mode 100644 index 000000000..548a598d9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.md5 new file mode 100644 index 000000000..655ca8cf2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.md5 @@ -0,0 +1 @@ +6be102575488e73fd84b8d956f0802b7 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.png new file mode 100644 index 0000000000000000000000000000000000000000..8021f07714f8fd58a6da9d8ead5a398d4d4d8331 GIT binary patch literal 1459 zcmV;k1x)&hP)L7Q5UyZRN)h5shfof5=3gnK5fve;KN4X|q%1YBg))*Ab0G7c_m7wE``)&h zQk(aEy&t%+=XuV#&)NCzx##}aWkf{KPy>B&n;n71KWJj82u%zXp^2d);(zXNxm;*z zY1xcewiJDReIb1zD`ReM4v!x{j!8gU5m6K)<~L+z{2-ii8o!Uz=|p*XdDtBe?p(0c(hQ(q*cX#(@hY?d$E5=sjkBD*V)G1uKaz)W*jDazR#Kc4#I&=sQheP2r zIXQ{4vN9M92I%#A6crWW_3PJvBAnlb=Xo&3@bKZon9duum0`2lKt%9*y|{Gg5-wi6 zi1G1pdHnS0(@086!szHIK7IOxy1F_vH#bKsoOL5f66|(6s;a6W2trKfj{0FLF)iUi`}Xa_@bIua zR$N>R#u(z_;*gn{37+Ti@23G4iv{)d^~lf9M{;s9dU|?bu~=~9#tj@jdK4VTAvZS{ zBO@bC!&e!6$>9>vGU)8ynN5fMp}M0@w{rL$+xlFQ|yKp+sZPqW!fMx&A5 zzI{u6zn^%XCxgL2k|ZhYg25n-j*e1JP7XO74u${j-MeXIWQ2mjpxmd|>*>Xd7v%H# zsJXeBIF6&m#YNfg%$YOv=+Pr0BI0?TYHMp1^OcsCQeIvjO-xMC($W$Mf(0&3tR+U&YsTW@B1%e1(Ae0B)zwvbJUu-f_wV1w)YKHb zUN0_OxPbHL&*SCGm$Hq)V30p2BqRU;0)YU4zi-#%=H?6Pc*jjMUUr zbar;aCbC?T;TnA|oRMk|d$Cvl9~&6Cfgad-m)Z9z1ve05F+MSY2I($KzS=*WVB^xz5J`3!|BlC>kGfCC2(DD00NI|jGg4Y%73 zqtS@s;$l=*R^t8p_wf0A=;-Lcz`(%9lM;rQUG&w~)?#^i8C_jnNKa2kO-&7M-n@zI z>}(i~Ms##^psTA3Cr+IB<-SZN6K>tQg^G#_a2$uax;mUYcWzyAT)uo6_4V~gOG|^p z;lSYFAW~CPAqWDBii$$)bvhji3JT=Y-0tpf96Wdsg@uL4%F4pKckgig`0zv{`IQ0oT|#niwh~;*-ArBV%J@n;pWMXe&cSXkw@cO$-&GiJ>AQ7I3H2 z8Ou1f3@(=|;#fp6BK@~VBYH3*?fndupuL}=CNwcrgeHcH(8N#?e*rY?XTOI$Q8fSn N002ovPDHLkV1l*{x~l*H literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.map new file mode 100644 index 000000000..567ca90a3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.md5 new file mode 100644 index 000000000..a60a6f7ec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.md5 @@ -0,0 +1 @@ +513e53cdbd67e1c3be296e616b5088fe \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.png new file mode 100644 index 0000000000000000000000000000000000000000..0b8afa3a54998330c4c48e926a2594d03eaa52b2 GIT binary patch literal 1014 zcmVp%d}4trgS?rFE!_E>#?~RE;`F7K;`sruT;MLS9>ao(A>7{ieJB z9e4lyxw~Ey03jqW@8;Kc8~D$_d7**xLIdZ8Muxl+3eH&!oAzd1Pcns{XaU zIF8%e+WK-!KbOP9!(cEdS29vNZEkLUm7kwZcXxM^g3m8Ba9(KOywLdOyqcPt7>4;? z4@ltkg~mtn((Cm@Lqk#-0000`tJO6%HS6o^&(F^w9T^#Eev9P{4i2X6`I_$c`}KN# zc6N4QVd22QKr|Yax7zJ?0Kn?%>IWY14HQ^kHk%DX$n(6}Z0_yty|}o5f9UG!GMP+b z`Q_#1?Q!Pk=OKh{xBH#C-EJQp9pyM~Z*MOU2w1IFsVR|2uq;t|Mc|q$r-&~Z+m-tR#ui)t2LX=2L}gI)9&uB zMx$9=T#Q5_CnqNgdQdE{SS+@%umAvPXlO{=p{J+k`1p8xdpi<|)YsShd_JY7CJ4gs z_t)0eN>!SshlhtrlC)SX%gf73dVn%EHa3!!wCHp?aSw`RX(*B;Jsyv|r?elhuC54z zI6ps68mh6e(dl%`6}Q{1QmIlWeNBfD&d$ziG#cp~xV^nCE-sG8;}Alg=L-r7VzJm8 z9^QbWD2k%wiel&2{r$bcV3?Sg5CkE$&*kN%N~Nl(sQCPJNzBd7O-@ek@9#^4vnkKHnp|1v{Vp;a5${gbRyH!(+-Ej=kwLo z)rm?Xkzg3+^z>9(5niuX+>(lTQ1bqjlan(xHa0ai6_3Z0no3GaIy*c2`ufh!&K@2f zoKC05@VLZOf%9u&T>TCLVtEVi<; zlG?PkwpLwTt<&ks%gc|Bj#^t=lR7XA0{}1>41yqt7cQRXU(+8S9~}X^cX%$B>+5~|Om1#&ii(QlN}9ZkM&noc`46BdN?rx{Hje~8 kztF&Wp@H*41LuXtZ$YMQX$d~A;{X5v07*qoM6N<$g7#MO?f?J) literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.map new file mode 100644 index 000000000..f53df572a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.md5 new file mode 100644 index 000000000..8d243e0ac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.md5 @@ -0,0 +1 @@ +8496a1131f5933bedde7a327a5d4457d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.png new file mode 100644 index 0000000000000000000000000000000000000000..437f5dcc4db1fa1df22fd5d89ec6bde26e9db351 GIT binary patch literal 1059 zcmV+;1l;?HP)R&+44# zJbr!n&N{${zvd$Fz{Y5@Ln(o*^^Kxw6?ZZt5T}Zz`(%b;vzl$ z$G#v4;^5$*>Lt~N^YimiD8!BkzbEbQ?^mmyS~4~^_9epi3kKc`2Hpz>-U|la3x?nE zVt9CXetw=FLkJ;+B9Ta=(d_Q-etdjDE`&mkch>K*va$jp^!xpl5=2yBU%1_FilQ=^ z%*@P;&1Q>6qts7EM@JnF2O1X&g+Ko;06?i!^7(uYhr{FXR78-bVrN7o5;>ht2w^xJ z=1h2ddvm+p3WY)}78{Mmr>7?r&*gG%x4WyWtEs7Jc6Rpt{T%?1PNyd)CnXX|TU*=I z)YR+iE3I>UeB9jJys@!?+9>o!$Ta$wOZ}z=_vqUe0)5c&EDMHTwY!h1YxyWX&sNpv#_v$ zVVKkD+}zxxL9qw~0$(DW==FMZF3^~k!Z0it46-xnGeQsq03ex6qIj`bY;0`2 zy}d=dBNB5Z{>zeFE*}{gvD@vBkB=ltUR+$5&F0U~Pq|!fG#aO;rym|3vf1p`)>beW zRH;-tozCfWzP!8;1Ti-^XD}Gr+uM(hjsO6?y}h)oPNxfp!{Kn4Q>WbeD}2{-xm+Yk zZf|dYU-J9?YPH&6Fi0d4m&;|h+w1G=0RTHYJAHk9dc9tyQe9nL4GsTR2!|IF6BE^{r^Z+;7WNcU{Qob0!uJaX-U|la d3kKc`h9B{;TY|t#CO!ZF002ovPDHLkV1k2R`b+=- literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.map new file mode 100644 index 000000000..7cf417931 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.md5 new file mode 100644 index 000000000..df2bca32a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.md5 @@ -0,0 +1 @@ +fbbd125722f48899a4de6646741795f2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.png new file mode 100644 index 0000000000000000000000000000000000000000..c3582874cd84a8870abfbf6abe950f53d3526cc3 GIT binary patch literal 869 zcmV-r1DgDaP)2uM+!GTbEgkW-V@&9j$dA0 z*59+C@HV#*1aZ6F5W8`?=lM*XQ^92L}h0N~OtUIz2rN zg+dyQrlX@{W@hH??Tsm`R;xarPp8wVRI2gu@j{`%4qsSU7#bRCYio-{B0rVNn`erm zHa0dOgcgeh01$~p%w}^q9HwcSB+1Y9(P(sSZSD5<7DdsKk&&ybt8_Yjc6N4ha&mNZ z#MIz8esgmZkH?F}qS0uy*=+3T*xK4!US7VxzjrtsKb6XZ=k@h<2%$ou2m}Jh$HxYP z;X9*dXJ^f3vr?(ValBfsuCA_jc6J&JhT-AiR4N4kD3{C8Xp|rbydYCm*E|)(%Jmm9vrcA5V)-0H}xvf^K34+LGvzwcne_PAyYOd4iWHMQ$QlU9m ztyX3)gs|q$d_JF5Dpep5SXx?oetrf3ba!{B)9II&m)g2%wc3e^38&L}eSJ+)R5F>g z*=$cwPxb5M`JKe;^->fS4u=5%^YinuSgf_Rm07oIU}tB?Xf%$EjdgW(dA(kz)7jkI z%!5kq%-P%9`;hq$z%UHMFm6VA-xddwXK^5T76)SV{KdE4{r!F6bu^B0xvbG>xS20J v+wFFt^auooVcZbX(*I{MAbA!CV)Xn6g*f?OQWOn400000NkvXXu0mjfTlc9r literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.map new file mode 100644 index 000000000..543dea86a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.md5 new file mode 100644 index 000000000..280ca8256 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.md5 @@ -0,0 +1 @@ +0bd47951338d799baa7faad737d93c2f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.png new file mode 100644 index 0000000000000000000000000000000000000000..aa25f7705a00fcff9d0edad30a57c5ccaea77fc8 GIT binary patch literal 1428 zcmV;F1#9|=P)E9S}3AoLi2?a_NFZwp@L(< z7B~%Jm?Z|8AcPwEuaRJFxe<=7F_qp_u<}j5u!clbOU0ZnJoCQ=A{;~K&VBK4$L_X! zuXjGzGS27K@A;nJ^XGhd{_QYG(==efN6OD0!0!fQC}tQ#F~b;&8CG=R?c2Ba?%n%Y zLph{0G&GcylthYunV}>}4i66>_>c}U!^6WQNk%KI_@tqsp@SOFp$9@3qcD3YW*9>; z!x)O0U)0dT!a|3`vHzTd=NC2f?~uu4R;%@AkK&(5#!#hFdF|S@NDLu_5VG0q{QP{U z)A{4a510rRE5VK8zvA_JYiert(?VNY8-&nqx5wz?gwvnix<<=(~loNe(BPs z@87>8y|=elB9Ww~rk0kLzJLEdl0Q8?txzbqT<)n;r(V5!g~XU8KRG#BT3X8Ga*K+J z#>U2wc>er(2w_S}ibNu5Yio=CKKb(H%VWomJ$UdS5D0w!{27TfO<%ckrMkMhySw}3 z$&+k0J1;Nq&Ye3|RaHs&fXz^fqWb#!AcV!m#R(Its;V|NHa>j#@b29^k|cFH9RT3V zmoJTtjSh$7+qZ9BU0p7hE0S-w+wb1JyS%)t*XwmUUBd6SX0y4qwKW(FYBZX2=gzII ztpNa@KYvcs^v=%C)2B}d1_q+rv{)?HuU{t!!e}%;dh`g1Q&Ur4zkb#0^>~b+qj0<3 zF-k(to;{0}If^4q5d?u=CVt7!&dve=0)YV1(JWqET%4PmOHEDv^yyPf7X<|cJv}`r zMsqnB4AL}x=FFM?{{Bc#Q&UrNLx>guXmt-gKx_U`U(d=5#HEEY>F7NcTTRu&Q^ z5{b*@x^d%1adB~Vb@j)OA0t)L)6-FKRTVll2OEzWyrT3T9TV`F=J`}X#B%p<8( zDwoTRM&r`b5=oL*uU=KDR3}cH7#SJ4b?cVj@88+k+1=gU+S&?-!+Y=1Y&MUMj&5#l zc6WCNgTeCha?}Ek$0G>B>-CyUCY0&%cmM#oxw(Sy@_I zno6ZQdi1EtWEvbCB7wLBhAtyU*vLG*^Y$3uxB0{A}; zC5C7iLove`iW$aG%rJ&xhA|W~jG>rG@XXIjP|PrfV&)G)$UJHe?|py(0000 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.md5 new file mode 100644 index 000000000..bf09ae4c3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.md5 @@ -0,0 +1 @@ +e2cd65da5815253bc9bf312036b6aaa3 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.png new file mode 100644 index 0000000000000000000000000000000000000000..e34bb58b381862d407a4d55be92445d14af5c1bb GIT binary patch literal 1328 zcmV-01<(44P)$LwW@bJ;r7yjuFaR(e(86XXW!H!7$7zLY|2TAWcL7X(9qh6A?g~ zhyZs?%*n}VY;3f*F$}{n%-7d9K0bb8V&d`f5ql2`<(-$nTew{A=;){$Sve+SXK85( z0H9K-ghC;M!SMI@=kxjN>+4Q>DwUd=n!2{O=H9#rR-#lYB?!V~GS$@7h{fXL<7474 z3JMCUtE*xA<>lq$bNym6cCxav006nUxqg0rdwY9&y}qfbsk^(|NpCP1I2=xXe!kIY zbYoIv+u7IGS0a&M7M*N~KOtP8yBI($Z1}gAo)IR9;?weSHl8 zC@Cq~-QBIMti&)ZIXM{saDRUke}8{xX9ve|kw^ppn4FyCa5!?goFE9LQV9SMi^XcS zdUbVGuh+-M#tMbP*Vk77fJh|T+uK`MSkP*<91dq?WyRH`3f5((^YinLO2_S-kdV;P(E-~UjRpXq)oNiEF5a`V zGlC%OCK3bzzg-y&2H3UPY&06};NSqRN3~l0HZiB_uCA^Kf;c@rl}IGf(a~OBUMVRl zv$L~Kg_zCehK2?zm3nb;@ze4F01Ab|F@o$&G#ZTpfuOy;-Db17QnFYq*uZg|LZPtP zY}k#Cj)p-ey;iFQ05F+Mc>H^MdRiqoSf*C1WQbAOMcg*Vm_3t4$_T zSy@?OVd3iPD%AJ(_F@kJDE zdwF@$>-DgEe0&Up000k2yg+NeBx^{MfFqueVyQa=HAcN`*q<=jRt6 zAJ5@%m`vu_*cgnrwze)VF8cWRz}tCjY%Df5me1!i7>xS*`ihDQZ*Ok^!1(xhTwENF z$BT@N+}+*H$jE>nhuhQ6=;$bu$*ilZlgVUJQBf=wYjAK-E|BBg$}e6l|8u~< zaj}q)CL(||5dox$2p~;F0BIruND~q8&JU$iQ&XRx$Cu_E6N`(BKR=Hz4MvdvPy8_C mnTP<=LpR0000 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.md5 new file mode 100644 index 000000000..efe4879d6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.md5 @@ -0,0 +1 @@ +40c25360d6e911f460499817a1f66d2f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.png new file mode 100644 index 0000000000000000000000000000000000000000..ff087624b598e18b2be1e0ae889690e7f0166afa GIT binary patch literal 1310 zcmV+(1>yRMP) z@B2Le_ha79KnQ{WlK&0mS10hBLFz>eQZHhVdJ!WUf3vZ%F*G#vt5W%%6c-nFc6MU7 z|CwKYzkhyy{>xMPzSwNGjg1YwCHke)+}zw(<@4RCsi}EpA@?t0ka`h=)QcE@h+bSS zSFhK9K}UaxUSGyX^b!aJ?d|Q@H3UHr1kq?THk&;)HHF%%s;Xo%*|Wg%^76K}HbQ-I zIGpkE@ed@~-`@{GkjZ5FKE6mN~ z@vN_}x3;!^zQ>;u4u=f}LvwSpMx%*r%Mn|TG#X8*R6-Esa=8Ei0)c?ZWKK>_Vh&oZ zmdoX`+3effTeVu9nVCta(?ufD@$oV0Ffua2VzFXlV@pa(91aHnpsudYZnrl!HbM}@ z<#GW4Z^b@id3iZ8F>!2c%2LJ>D0n{fH3dP6AJDtv>qodf^Sf|tZtS?M21VP@4MG&N@s7R;NVg073rw4;U zbeBj;Nr7P)K@fB@dOV(=7KkC0N~KaM-V(9>>-_v&EEf0m^@Tzq)Si-(Qc+QX4zE_L zt*@`A(P&<;7XXl&nu6thRy?@&leRHm6Mb6nPMZh9+^z0UavnqJTw>#m{Fln%+AhkZ*Q-z zuA+-EGc%JypWN zJzdH$l)>0Mo20|NuWU=X$N`FsY0QC(eKTwI)=pAP`Y z$jGRytZZm#aJ$_w3~z01NhFeohliDwmEPXogM)*|$H!18bbo)3ZcNF^$xf&9>FMd6 zSbPpvs}%r{mzRfGN=r*!E|<&Y%E-tNi9}6JP5b-%*VorNoo-=afoP2pKCh}&Dj0^1 zM&sYDQz&w|-0St?j}a!5DK|G)C=@0oC8<=ZhK7b8KYo;zmC@;Rp-`BRkT5(vY_VA4 z;^F`RJv}{3OG_~^G3fL0)mVH28jVIM6yhyZDwW6Mp$7}I*<4Uiz~}R`v$O4XdwF>| z(E=d^_kGA>vDDVqBIFmNe?Z^o;9qc&|A&Y{>O~AvFJh2-5rfo=7^GgrAoU`~E8o*B z7R%S?@jW>`JxxnX!&_d_tG2fGtMd5`kV>WaTZlZ(6N22oh(YQ_3{o#*ka`j0F9m(p UF!s_?C;$Ke07*qoM6N<$f_~U$AOHXW literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.map new file mode 100644 index 000000000..acdbbcaac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.md5 new file mode 100644 index 000000000..a3fc301c1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.md5 @@ -0,0 +1 @@ +8e6e75ba5587c932001eae5a688a6d27 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.png new file mode 100644 index 0000000000000000000000000000000000000000..7b3fc9762c1078931bd3a4339c12b2160c53f77e GIT binary patch literal 1480 zcmV;(1vmPMP)r4C@4H`Q}7Qo|J*tHGtN{{^ddu8f9TJedX`O%+7u^<+j%b@-ots< z)|+$fylgwuOuU-KF7qM8}($Z2`Sa{&Tfya*@ zGxrsX#m&vl1qB5$F)_Khxl>b9NMBi5xp3h^LPElkBS$V?y!h?gx1Z}?JbU&mHa7Or zqeoV&6_pWUZEa1hR;Q(<9XfQVwzhU-Vgu9(rBeCwmVxZUSy%e7m6&0bDg2r?x9*;LVI!Z6=>FG&K zOr$8Pt*!0awQCebDHMv4kr9W(5gr~sIXQ`ziA17%_wJ!Fsymy_Mp4w6GiNj!4ZWtd zwUv(Sb*ZVTiN18=#0eb7Efxy^z-qN35q3W~RYln4X?4EGz_nHynZ>&Ye5AZ{NNh#sBdQ294EfrN^H>eM(MF76=5}+uMta zi%9(V@gvH|pU#Zt@p!aa?d#XC>B2M`ji|$SBR$g8%6bdC0 ziAtsV^5qLjlJ)iV#l^)*NlE^6X0)eIp8^1~va)DJB9WNQX0zFxl9F=%{P|0lF1>yG z*6DO=G@8-T(Et(-@|UB!x;mH3)zj01rgFL5ZnvY}0ssgL3zJABcDr3Jmj`jvnwpxH zmKHvrKQJ(0Fc{+F;{gDAy*@fRIwvP5FE8)t(WCU^wm+Q)$MNFgVy435@h}WS&yM~5 z{U=YJEGjAz3Wc+?vr?%vkc^oP{ud9@{}dvTsIRY&?JRx<_#Fo+$4=o)X8|9-9R0tT zo10@hg&o6HIty^7vjAs03vi~hfRBT8aBwj6dF&~Cm|j^~8Tvf-6p-TnpB{3!p3VZC i=`6sR&H|k2EbtdXsd7>DTemX+0000 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.md5 new file mode 100644 index 000000000..527fc865e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.md5 @@ -0,0 +1 @@ +912bf27b3c1ff508088dbbabcad26cef \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.png new file mode 100644 index 0000000000000000000000000000000000000000..6d77adeec558412e66be9778344324d7222178a5 GIT binary patch literal 1310 zcmV+(1>yRMP)TO>-z0`-TVE% z_qE@(-Gc-{0E&Nx_T35mFetysLHR`v$}e&Rdrq`k?bz7Zccl`T_?Dv!c7oAS0)oMK>!QLW`M&qx10-c(gns*VZf02XoiyV|+Z_M*#Vio0~f` zGxOb9{DlDWOQ+K{H#hs?jYJ~R+}xaRYXiuyAAv7^357z1LLnB584QL%AlTX2866$v za5&M?(XFkmE|&|*Fbsnb(r7duk2f?lk3NKH7>z~-u`wzts->mn z_V)JVcir?Pe4i67gQ&Sff7EmNVKVL4FTP&8dv$O2%YyiN`%?&{iIXOAg z)6+;J7K^K^tIcM!!C(-HL~ae6&0b$$N1CgvD*(XV-5o&?m6eqei3G>-`}_OO&d!XC z45!n1e0&@d60*I$?Ql4>T5VTX7h0H=l{Gs%``0oFf{;q3QmNE4;-g<L85v2Z)7?{t!-2*cjV3cQlfhs> z2s=7Dj7B4>iosyS#l<1buV25sFK#p%>2!KRLIRrd`TWn5IX^!K0I=C?2qA{nwOW?-rjz5bA#h} ze}BLCT0WnjpP%2>*5<7d3Wc+?vo@RU^768`w-*JIlanhdDjFIZPEJmqpP%>k_9`nY zUtV6;*VhLI1`Gzn>+7r2=|m|30FsiD^m;wIe`NV8zfw|CMn*gsAlM1-Ht$N!O) zm6e#7n9nsPlL>en5&p!x-+%D@>#I?zRKdZ)B_$;|j`#NV%H?wZ=ioEn@cq8HxLBjn zaJgIz!-|TEMn^~epM%eQ!~Tkmja^z=`geU|Vj>YRe=1YIAIU-aMGnd@a!`Je literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.map new file mode 100644 index 000000000..28a530cd0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.md5 new file mode 100644 index 000000000..1371e210d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.md5 @@ -0,0 +1 @@ +8d39cd46dd30d6c731fd7374f101062f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.png new file mode 100644 index 0000000000000000000000000000000000000000..97cbab8ac15d7dfde4bf9b0f350b988e6a7c6f70 GIT binary patch literal 1308 zcmV+%1>^dOP)Q5d200006VoOIv0RI60 z0RN!9r;`8x1kp)EK~!jg?V3wSa$6XN*V4a>X{LjuP)sW*g2*mVLH9`rDilUZ6AP+Q z2zI5QQIi6dnnghoMP|VcA_GFK4jM@$8cp9;0^u?|w$#TKik; zd$;diuI=7Jx7!T}aD{}o00P2;9{}M2{tzDE&o694uh*;9YP_Tb54pLyN~O}%{LeZ# zJ3E`1nfZ1}!NuCznqIHR_Wbfrnx3BiE~^?nV#EtE#HDx3_C*Y9NF;IXM7; z`}=!^Lc!UVAJ3EVtiXtN;CnqN#A0HJ8 zMO<7QgTWAqM5m{xD6PN0pU>x0snq=Z{GFX0)XCv+mX?-KY_V7%gtxc1*vY*Gd*e^e zN4POeO-;S&@kv@*8jr`@+S+<}c&MqViHwY_tE;=dzBZXmF)=Y(trnZ?a5#2$b`ld4 z$H&J}PiAK3@bIuFK_Zdl<>l?|?b&R$fq{Y9*;!PA%jK@GuRlFKb$55OSS**z^?{z4 zn3&boRfogjcDu{U%7jAU@$vE9-Ca{tQ+j&3)9ExCjUgc+D=RB@yIrr>H#aw4Pr*L%CkG*wN~KaMwkJRj)M_<~mzS3zgpZGps99ZI z-QM2rJ*2O%ud=ezTQ0gt4-O8zOQ=*T6yMz3po{baJ!qY||M?ux&(BfQ>2%WRbc4Zg ze0)r$QVj;fo3TH^g8=t~=;&w^golSmL_|=jR8P}xx1)G^dO9N`gGQr42o(y2#bWWE z$80u}$>fBD1n)yE77GOw3Izb*nbs#^Hk%D0gb2w|) z9euJKgb)RBad9LP$!fJ?FEp`O3;+;|#S04y8yg!XB_#y~1<%jV000Vw;&J!t>dNQj zSi$e%PtLnz10MM?cDvo>az#Z&g@%T%t*vP^8qcBF*jR(XfGpv1xgwFMwzhVEfB)|8 zZg6mLZf@=~b-7%wL?V&PEG(?Bu#mxE2!%o> zlc~{Yv|25VMgsu!^z>M*RyLb05{a-PvAhu+aL#)`H|Bp8TCEoCod0(g0{=nJuCXr& zh~H@V^V@h}Hk+Xra=H8u(BR`e+Ruc?`12PNtI2Pw S*odG20000 + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.md5 new file mode 100644 index 000000000..6010a609d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.md5 @@ -0,0 +1 @@ +bc950b2a380edb2222e6039af29b1619 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.png new file mode 100644 index 0000000000000000000000000000000000000000..716877088edbf915379a5dbae082b0df9414cdd5 GIT binary patch literal 1141 zcmV-*1d98KP)J<)I#V3vWR8w^SVX{eGX%M^#Eb7I{3Lukuq&=ybXqg}vS}hs};TYj#DvpKsBK@bE%rKP1(snp?cP%F>R&pSIixm+%}cVS`S z?d|Ok9sB+M{{H@7skB%u5Cqxn_8h%Xt_sk1V`F0kLB!+nfq?;|(Rg)rMe1I!S1y-J zB$BhUvv@r2bUG7>#P06ypU?O!WHK29LHhdotX3;kFQhAig3IN~QS#E>-cII~vz<<- zIUJ7D=_CjulgWt1;-R6TyhnI?dNLRcJRXnF=Npa2mzNiMy|uMIEIIZgTbKPZr|VE-`?Kl za5&^%tJOL_J`TgM$z)nxT_r_&SHBH4NM?PPJroSXdwYANesXdG0Ek2)AAcSWhXDY$ zx3}aFMNt4iEEfArCqC&rlG)i=i9}LSQE_y1log}Vs7NGACX)m~#N%AC=y{mua zKj}L%$LHr~jYcy!H-nY_h&y)T zk&zJ`$2T@M001hL>h$#V`ubWXlX1CRgTYW)S*g)z001tRtGv8iDwQ@jH&<6zXP01~ z>3KOmK3-g0^msgFWn~J5Vrptir_;T@zFMtTwOUQBgke~zRFaDo8dtvyL{Pqyx!rEP zUQe)J&hkONgQC8mE52v4p97m6bJ*;d!)C`EHaq69*)fOBjyZY0F)~|Z|L=Ktc&MqV zp(=T@)9dwL<)_HdYPHlM#6CqZhP~b~hs};TY + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.md5 new file mode 100644 index 000000000..30529d258 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.md5 @@ -0,0 +1 @@ +f1bcb75b933276ee5fde30f34c416529 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.png new file mode 100644 index 0000000000000000000000000000000000000000..6d81796fb0c98be5fe1f1503f2b7a33ae54a626a GIT binary patch literal 1307 zcmV+$1?2jPP)D1AZ00006VoOIv0RI60 z0RN!9r;`8x1kg!DK~!jg?U`RFdv6@apT}4+f4)hCnZtI08)1d~xp23}B$M1N%F3S+ zbHRlh3Mo=<{EJBPrzn!*a5R#;fLzrT+Vs;;hfcbJ=-ix4uK%|f9tA|fI^ zJ$-a^6aZkgT8Z+_&CTrWY^T#1A0MyLXx!b}?RJ?=hGE#RU%%?>>mMH<5kh@^eOxY= zNFZPPqd_PX0stU{7>4!q^x!z|GwtEwK_-)NIGm`cD4|fO*X!S#xOeRbh{a;DSWJ!t z?DfgXNk~YDLZNtmepV`#a=Dy{=j7x}Pfxqkii(OVD=RG)i&m@U^Z8`2%gf8>=H?JW zy}iB7&CTu-kw{cnSa@`FbbEU{Ha51tzK-7U+D{DxZ*Ol02M0VJZ+?E>XIe!?g+L(C z>2!9xy}i9XD=W+8a=kZwpF{ZM3%u6pbSxH2tyX^^LaWsR04x>@(cIbDaeHktnUa!{ zUS3`hLN=Q%AtAxxa3F*(FE0TAXJ=>rOv4`y9*m5PR99Dfrx^?e0D#G4BAPCjD>5?D zyJvrf@W9*afcNW^l$3>qg^rF6KA&G(TYGqT=$&IU8d)q>Y-}vi-~`tD1UM`mX(!lZEfxD?v|946c-me91Z|LP|!bJvDxgWr>C2n8=|Sx z>4*y)$0sKzkB*Mqw|aYfdwhHx0Dxhb%jG&hKmRHX7K^2(rlz~Q`|9cn$MNCe;kUQ9 zzvoO!OHNJ>3JS8>Y~%%4R#x`jxa8VE3Al25d%LTvORLqszP`F#uIJ}x9LE6w@$vC$ zwVId@m&+|EC}?VGvRbV=ovyR9lc?R=+5!M%WMsH|D=se9Xfzs)hQr~MmX_Am)*c@p z+wJy=iHVJk4FEuYe?O1MBa+?M{%9bAQBhG$CR3$S4G#~y2PLO*I2@5kB#}r?Pfr~V z$KKvvMMZ_v>3nbc zd{ZTVpr+r^se|^~2YS68dLfZWKH060|7B<}4Er}WQhHre2kkX=&|Xsq?KO4yI2)Ii zmZ;b9^Dr8XY&M%5@!>W3D=p1u5R1j+CZyjIDTCgxse|^KI%uz{gZ7#_{sQWTUO2|y R`hEZa002ovPDHLkV1gajbuIt^ literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.map new file mode 100644 index 000000000..082401084 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.md5 new file mode 100644 index 000000000..5e164cba6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.md5 @@ -0,0 +1 @@ +636d74cd7d8543185699996922cb3512 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.png new file mode 100644 index 0000000000000000000000000000000000000000..c156a9810b293fc2ffa59fb2c5f7aeb0dfbfa78c GIT binary patch literal 985 zcmV;~119{5P)VjRZ-1ONa4L9zw>hd^FHkQWf-1w_aX+-~>i=xDN}B%ZReGK<9$4*zj4 zE-o%sR#p-&DLHsN9=F@g&j`OyT3%jGl%8Z_Fc`jMP`!X4FCfSZ2=W3FOD{;0oSK@7 z;f4w3XI{L%zG9IO3WWdwkH^#2))o(ywY9YvhVhNw-`~eDOe_}1@RXl$Z7J5pR+Y_V7j(6pzgr{3OPrBW%8Nb2kB&(6-m%LfJqDl029GBOqy7Xbiub#=G5w_96V zp;au)c64;`Pahv2SE*D4K~NOs^?IYwAIIA1a=FIF#;&igNs_Ftu0A|G+}qpR+1XiJ zTU%XS4b3qcjYmgE8yg$v=jUp*TCdlKZJM5*9vmEecz9@TZUz7d1Ol_!JTWl=0GOMb zqbN$DP=wF&`FvKZb$)*S?(WWJv#~52h2RK%XRPSy=_x5G0RR|{#+jKJyWLI@M0R#| zRaKSO>oph*e!t)4a$R0t=H=x90EUN$rBdm^!9h_`5dfg8tE;@coWEgvdwW4a!TtUH zCc(Y5bo(giI!*Y1(WyKR-X$)YR~YR4NtAvVDDhrKP1UEiJpd zyHN;^)e5Y_{*CI-O3Z(*=XUg@pyJR(o}I zB@&5#q$ioZmO`OuXlO8*Og^9Q<>h62dt0y9zrDTv%MyyBIF7SgtzYu%>+Ajf{l~}0 z@9*!QpPzw1AY6C;o+S63v$L~mwVI}BnM~H*-EA_N($mwU*r%eRLL!mSG%b}%?RLA< z>5QiJ;CL)8Eq%%Sk6{>wVHkb}eUCtp7ZBtH1bG2LUOIDRO0YP3skQb0&;`%ZEDY-p-00000NkvXX Hu0mjf@qEvD literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.map new file mode 100644 index 000000000..078ab7b14 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.md5 new file mode 100644 index 000000000..06179feb6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.md5 @@ -0,0 +1 @@ +b8916d3b51e3fb200c11a55d0ce781f3 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.png new file mode 100644 index 0000000000000000000000000000000000000000..ac6ff436a8b2b37819da9d17825284fcb69786ae GIT binary patch literal 1277 zcmVDc)z!APwm+51H=?YpEG8z# zKK)lGavV1?G4bUoeKRH|COD3BjJUiOjgOCiRX*PmgwTtKuqRSLFp&a+i4+h_q<~-| z1)MQ4F)^{Eq{Kc(2qA=AU0vmJ`S9?tqjG(HJuNLwB9V}*&CSggi-khgPElW9j}RIh z9HhQ7g-$FkF2)!ejmF&ET(w%gv$I3ub8~YFg(4^@Xk}%^Xf%$DjF?QOsi~>Y-_Z$p zp4V!%IXO8RjfVc}*a4kR_agEp2?+_rxEEua%_b6wMn*<3#yronESsO7|Kf75}5)Tg#udJ+$jg1wH#iOI6@5rjFtK;J0+}zxPgM;Vi=Se&{IT-*D zLM+SH)z$GlZ@=U0>}*6t#N*?mx3{-mueZldCR0&S5zDfko}PJmc@GZ{zbqdBbUK}5 zgxa2HHk&&;I}t)rQBeS3Fc^-HkJW1Ro8pX&43o*Uy}iA$vB7biN~N-2>g(%kY;3&0 zzt76bdPg=mIM~$Gbai#5R;yJi6{&4{dKzQ=^z<}2IXN&eFgiMF*K0JI($Z3fVG0Tg zy1TpWag|E7wY4=fGjnuw6d4)0xVY#{@s5r<*NOI}7=|HbV2qcRmH^=N^z`+|4-XFk z;OOXxO!ay_09;&LV2s1V!|UtoKO$>wZ6)!$yE_0lJ3D)EmyV8(%*;$OK0iPA^YgP> ztr%mY(dgsjV>X*H#wRBy0I6o^Nk&e|~-j0G{W2dwX|xckPX{ zu&_X$XqIJdHXCXA&p`8>=;`TMUS8hN&|tM%5kg&EU0SWSqM~Adf8T62@9yqaRaK3R zjrsfgD-?=?f`ZG-OOE4;ii(nwlDxgWU##{)nH`J8!t=a`hX=zjYin!m?d>E!H#Y|W zp`oF6r9z?5>-BoQUM7>Jq@-kLXB!L#lgZT6(=$Ci?L^^}58H)>g=Vw4zrP;<5)%`b zmzVeU_M)SsB@&5Jsr2yhNKH)z0G&=J7K`O_d1PdyudnZao!vetBd{#n($b<-D&5`P z%gV~q)6+>@qtPTKB{?b?hKY}lCug0Zp`oy_u!MvJe}DhY&CR&DIA_Xs+#o;rV)@H~ z-*?3Mn-NT;fM6m81QRJBm`DM^L<$HdQs9lBOvlE?zCMp{%^N0WW@dhU9^V>-h5sjh n8evbQfM6m81QRJBm`H)2R1B>)gGQ~C00000NkvXXu0mjf0u^3r literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.map new file mode 100644 index 000000000..402f748ac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.md5 new file mode 100644 index 000000000..3c6e51c78 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.md5 @@ -0,0 +1 @@ +8a2ff2afbd606f6ff99bf4a81ad27232 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.png new file mode 100644 index 0000000000000000000000000000000000000000..cbf8e53c5f6e16b529937e1fd74e4dc0ce81dbec GIT binary patch literal 1330 zcmV-21he7$Uq@Ou^gz?>YkpSud?z(sjjZ(a5&GyzwS_t zMl&-r^XZm;Ff%hV8jZ$Mp}Z_oC={RN=f?v8uu{k#3K=p`$dG|T=358KX0sh=ne}8}9>eS`s<mGDbqvD@T__YDA0O}R>}a*x=;-Lo%*@Bf$9G&8+9OY+(JCq` z004V?dse5YRBC8wXm@uvpU=lIjQC)fm6ZhmaBy%42nc9xZGHZVX!CJ4nM^r3IhmQ6 zx3{-eHEcG!v9U2NEe%D{(9qE3<>j}1uB@zNWMrTy8Xg{AUS7Vju|ep&ySqFd&)?r4 zMNxr3U@#a?Pfy>G1GGR*CezT+5C9-9F7CCO;^N|ylas^4Lj*w<7Z-6HH=E6~v$GQu z6H`-Dugy9;J4;DP@%Hv!SXgj&c79nPl}bB1JI~I}_bv2z_uAOzai*9QP_c6P3g@py1Qw|Oe5)%^(3JQjYhaDXqZPtiHqWJiD8jVKWSvsB09@_&011goO zyStkh*4NilsZ>8dKRTU0KR+)Pi(kG4*#op5YA_hGv$LCIr+9U7b;USSoj*gB-M@L_)k;!DfzP>CLORv}Sc)X^j zrqk2Yr>Cdh-rk3Y2b)tmJ3AvIBQr8GE-o%$S?%cPXm4*{TU(2Xi6IoD(YUp>g<+VN zmzRr+OI20X{r$aKt$xSiF!!NuZf>=;wQX%}_xJafy4h?#JUpzctCLEl{r&v_fV;c9 zr>7@6old1vH#awXdwXA7lR}}$WU`2eh}6_ngTe4|lMM|GBO@d0>+9j+;m@MGyE~J~ z92y$Z>-D#{xBdP7X0tguI{F>!L*Ce97-lk=#>dBrA<@tJS%=xd?(V znar-PE*_7EqG)w>bzWZHTNWK0#A0z;T3T{)@@t*pB@&4Q0Fa%X{rLDuY)FkpgblD9z+L@t+G zD&Owa^QS`w3K=p`$dG|Th71%kWT22C1BHx@pOL4hr$67vufay3g@uKm@8j11aPt2{ op+fdh$dG|Th71%kWT24w4|ZxFDpnIidjJ3c07*qoM6N<$f}zBJJpcdz literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.map new file mode 100644 index 000000000..62ae05dc9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.md5 new file mode 100644 index 000000000..d2ddcd27c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.md5 @@ -0,0 +1 @@ +e31d247ca830d0fbc9b398310b889137 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.png new file mode 100644 index 0000000000000000000000000000000000000000..f2784a51ca2a292ce86b832fdc92a6f0072b6ef7 GIT binary patch literal 1257 zcmV=P)po&?HdGVAKDUbbEWdva%8s6qJ#Xv9Pf4@hkop1_lN&3|m@SdOO79 z@vwh+xii|@+Uo1;^?Lp4>Z(?&6$k{LT^HFSPoYqFJRXE_e}Dhgke8PiolciXBy2WY zAQ0F;7#0;3K?n&1LS$rQTU*=9S45|ev&CX5DJdx|EWE$Jf2CnC7)?!0d3kwMDwR&B zudc3o=6`K%Ek8e>N~Old#c{dZ&CN~E`XCF`VzCSk4nhc1Q&U}ODl03`&d!dGjsO75 z%gY#s*=)A?`T2>7iRtNSSFzx7!3DKT!A3azP>&Pp^uM`SS(&#T#Si{ait6k3j+XL zUthmeh(uyiQj$O*P^;BWryL$0W@cuVm6Z(*4H1b%ry8M9n3k4Cp-^gTYmG*u!C-LX zc6fN$WHOn}=7oiYt*tFKoBc{4lgTt1jYJ}G)5HzP)=;C-SX^A(($ezu^yEruf9(wj z2mk=g&CMkzC;R&PLI{OI;pyqA(GoiOa=g0t=4xvlSrhLloY8{ zy0o-(cX#(vm&s(Ut*z_p>(SBC?>2D?vPYgqqsis+*>S65d;LPCCi{>{w|Dyy#O?Ck95=-AlUNJ>ibxCzRA z=$}7-#A0!Kd;7z~gJa!hvmG5BH8eCR6pH@-eh8t}YJGlw_V@Sq^77i=-tO(~b=8wZ zA}N*1`1ttT++3s4_;Hgg7HfBR*J82k?d^#~qJn|~KR-VJKx1R$@bIu!tBs3``$&Jp z8+(C3V6j-n$H(ob_T|;j&yUGu8Vm-VPRC-g000pY5#8P06%`d!Dpe#Bm6n#evq&I} zjEv;vGGinO7AY_W%H9W@a2K-|p4(r-KKI7(7tK;DI6r4-_$Y zpoqZ(MU0c5k!NRTKi|i%!AYRy<>jC6 TG;6AE00000NkvXXu0mjfUc70Y literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.map new file mode 100644 index 000000000..8eb29e24b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.md5 new file mode 100644 index 000000000..cb1829bbb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.md5 @@ -0,0 +1 @@ +e8d46fafad2734ff1ba6435e75760054 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.png new file mode 100644 index 0000000000000000000000000000000000000000..686145aacb4a96a4544507a80223dce64148b351 GIT binary patch literal 1371 zcmV-h1*H0kP)XS5p&K=~`+IR=?6)@a z&%r-&Kd<-3>he5Xz>lJ)%xVglijki zPibpw6NyBz=Kroxr_(t!G_>QE_Ax_4Lr$kNzC!y`G&nf8Q-1b65W<8CxrQQ!3=}bB zporPif#&AszIpRzw_R+GJs0T3ix+h|-S#!R#a03>EiG+rZH*m62qA<_CiCpsvj&49 zUPhc^Fc^G3zow>UW@hHEgWGJj`uh6qYg$@bh}mhh#GTC4)YRq6mkGlbi-jmgB9Zp? zb}pBTVVG1ZU0PcDtJS0+xI&dmC641hpYQhV+cKH#>({Rdrvib%=;$bq#}kP}!^6Yd zpK&Af_4VO6{^7%ig!=UK^tEf(YHMrVZuju;u*qa1>JJ}2G#ZWLB@bTb{{eHa9mz2)}&!l5mPnrwasvo}M0=Or}sMh!=)sWn~aT3Wajw#EI_i?$}$z zq_=Z07?emP*RNk+U0qGkfj}@eHnzS`wOW1a)~$wyhJyzWo;-Q7 zudk1&_xJa=x3>$0LLQIz`0?Y3i3x|pv4tFv1sV(npFe*NAv}Nnd@4C;Rm({8tK{O89&5a`pVPa%XD zhN)Dl_wV1II&~_Q^7!%N006(=AFEKQ)V#brg+ehhGLp2*+}zxyOP6lkxbfn}3o4bG zRHIZX3knLDOr~5e_j^luC(V7=*B{t}Z`6KRrENtyUj6aKK`*uvjbrKp+r^DS!O< zK@>L&vRj_ZvZ7p`%BSe*XNKsL#*O2ZKSOP`HID zQ0_xBGBQ*u)&2YTfB*g+Uk``F4u_+oqhnxT;Much5W-L>6pcpNY&M-vx7lpHy}hZ% zq|s;wgCQp;=jzp~UaxoiCgpOuR;!(zon2X3dGO#tBoZkuE(QQJHa7P3^w{lokH>T8 z&Yi--!uaSn4&sfyLZJu-gRft|CYr?Znx39sT3WiWuwb=XrBW#XAS)~D(W6IIRaGn& ztF5iAyu5rpixi4ht1T)jx^m@8s+HkSbUGb`P%IWlA`xOk>ht*shfPgQVzKzhkt1fa z*=#oRcsu|=XJ= + + + + + + +IRremoteESP8266: Class Hierarchy + + + + + + + + + +

+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Airwell_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Airwell_8cpp.html new file mode 100644 index 000000000..baf4b7576 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Airwell_8cpp.html @@ -0,0 +1,172 @@ + + + + + + + +IRremoteESP8266: src/ir_Airwell.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Airwell.cpp File Reference
+
+
+ +

Airwell "Manchester code" based protocol. Some other Airwell products use the COOLIX protocol. +More...

+ + + + + + + + + + + + +

+Variables

const uint8_t kAirwellOverhead = 4
 
const uint16_t kAirwellHalfClockPeriod = 950
 
const uint16_t kAirwellHdrMark = 3 * kAirwellHalfClockPeriod
 
const uint16_t kAirwellHdrSpace = 3 * kAirwellHalfClockPeriod
 
const uint16_t kAirwellFooterMark = 5 * kAirwellHalfClockPeriod
 
+

Detailed Description

+

Airwell "Manchester code" based protocol. Some other Airwell products use the COOLIX protocol.

+

Variable Documentation

+ +

◆ kAirwellFooterMark

+ +
+
+ + + + +
const uint16_t kAirwellFooterMark = 5 * kAirwellHalfClockPeriod
+
+ +
+
+ +

◆ kAirwellHalfClockPeriod

+ +
+
+ + + + +
const uint16_t kAirwellHalfClockPeriod = 950
+
+ +
+
+ +

◆ kAirwellHdrMark

+ +
+
+ + + + +
const uint16_t kAirwellHdrMark = 3 * kAirwellHalfClockPeriod
+
+ +
+
+ +

◆ kAirwellHdrSpace

+ +
+
+ + + + +
const uint16_t kAirwellHdrSpace = 3 * kAirwellHalfClockPeriod
+
+ +
+
+ +

◆ kAirwellOverhead

+ +
+
+ + + + +
const uint8_t kAirwellOverhead = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Aiwa_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Aiwa_8cpp.html new file mode 100644 index 000000000..f5fd8eaba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Aiwa_8cpp.html @@ -0,0 +1,157 @@ + + + + + + + +IRremoteESP8266: src/ir_Aiwa.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Aiwa.cpp File Reference
+
+
+ +

Aiwa based protocol. Based off the RC-T501 RCU Inspired by IRremoteESP8266's implementation. +More...

+ + + + + + + + + + +

+Variables

const uint16_t kAiwaRcT501PreBits = 26
 
const uint16_t kAiwaRcT501PostBits = 1
 
const uint64_t kAiwaRcT501PreData = 0x1D8113FULL
 
const uint64_t kAiwaRcT501PostData = 1ULL
 
+

Detailed Description

+

Aiwa based protocol. Based off the RC-T501 RCU Inspired by IRremoteESP8266's implementation.

+
See also
https://github.com/z3t0/Arduino-IRremote
+

Variable Documentation

+ +

◆ kAiwaRcT501PostBits

+ +
+
+ + + + +
const uint16_t kAiwaRcT501PostBits = 1
+
+ +
+
+ +

◆ kAiwaRcT501PostData

+ +
+
+ + + + +
const uint64_t kAiwaRcT501PostData = 1ULL
+
+ +
+
+ +

◆ kAiwaRcT501PreBits

+ +
+
+ + + + +
const uint16_t kAiwaRcT501PreBits = 26
+
+ +
+
+ +

◆ kAiwaRcT501PreData

+ +
+
+ + + + +
const uint64_t kAiwaRcT501PreData = 0x1D8113FULL
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8cpp.html new file mode 100644 index 000000000..cf51c2624 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8cpp.html @@ -0,0 +1,239 @@ + + + + + + + +IRremoteESP8266: src/ir_Amcor.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Amcor.cpp File Reference
+
+
+ +

Amcor A/C protocol. +More...

+ + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kAmcorHdrMark = 8200
 
const uint16_t kAmcorHdrSpace = 4200
 
const uint16_t kAmcorOneMark = 1500
 
const uint16_t kAmcorZeroMark = 600
 
const uint16_t kAmcorOneSpace = kAmcorZeroMark
 
const uint16_t kAmcorZeroSpace = kAmcorOneMark
 
const uint16_t kAmcorFooterMark = 1900
 
const uint16_t kAmcorGap = 34300
 
const uint8_t kAmcorTolerance = 40
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kAmcorFooterMark

+ +
+
+ + + + +
const uint16_t kAmcorFooterMark = 1900
+
+ +
+
+ +

◆ kAmcorGap

+ +
+
+ + + + +
const uint16_t kAmcorGap = 34300
+
+ +
+
+ +

◆ kAmcorHdrMark

+ +
+
+ + + + +
const uint16_t kAmcorHdrMark = 8200
+
+ +
+
+ +

◆ kAmcorHdrSpace

+ +
+
+ + + + +
const uint16_t kAmcorHdrSpace = 4200
+
+ +
+
+ +

◆ kAmcorOneMark

+ +
+
+ + + + +
const uint16_t kAmcorOneMark = 1500
+
+ +
+
+ +

◆ kAmcorOneSpace

+ +
+
+ + + + +
const uint16_t kAmcorOneSpace = kAmcorZeroMark
+
+ +
+
+ +

◆ kAmcorTolerance

+ +
+
+ + + + +
const uint8_t kAmcorTolerance = 40
+
+ +
+
+ +

◆ kAmcorZeroMark

+ +
+
+ + + + +
const uint16_t kAmcorZeroMark = 600
+
+ +
+
+ +

◆ kAmcorZeroSpace

+ +
+
+ + + + +
const uint16_t kAmcorZeroSpace = kAmcorOneMark
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h.html new file mode 100644 index 000000000..6ec44115a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h.html @@ -0,0 +1,615 @@ + + + + + + + +IRremoteESP8266: src/ir_Amcor.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Amcor.h File Reference
+
+
+ +

Amcor A/C protocol. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRAmcorAc
 Class for handling detailed Amcor A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kAmcorModeFanByte = 1
 
const uint8_t kAmcorFanMin = 0b001
 
const uint8_t kAmcorFanMed = 0b010
 
const uint8_t kAmcorFanMax = 0b011
 
const uint8_t kAmcorFanAuto = 0b100
 
const uint8_t kAmcorFanOffset = 4
 
const uint8_t kAmcorFanSize = 3
 
const uint8_t kAmcorCool = 0b001
 
const uint8_t kAmcorHeat = 0b010
 
const uint8_t kAmcorFan = 0b011
 
const uint8_t kAmcorDry = 0b100
 
const uint8_t kAmcorAuto = 0b101
 
const uint8_t kAmcorModeOffset = 0
 
const uint8_t kAmcorModeSize = 3
 
const uint8_t kAmcorTempByte = 2
 
const uint8_t kAmcorMinTemp = 12
 
const uint8_t kAmcorMaxTemp = 32
 
const uint8_t kAmcorTempOffset = 1
 
const uint8_t kAmcorTempSize = 6
 
const uint8_t kAmcorPowerByte = 5
 
const uint8_t kAmcorPowerOffset = 4
 
const uint8_t kAmcorPowerSize = 4
 
const uint8_t kAmcorPowerOn = 0b0011
 
const uint8_t kAmcorPowerOff = 0b1100
 
const uint8_t kAmcorSpecialByte = 6
 
const uint8_t kAmcorMax = 0b11
 
const uint8_t kAmcorMaxOffset = 0
 
const uint8_t kAmcorMaxSize = 2
 
const uint8_t kAmcorVentOn = 0b11
 
const uint8_t kAmcorVentOffset = 6
 
const uint8_t kAmcorVentSize = 2
 
const uint8_t kAmcorChecksumByte = kAmcorStateLength - 1
 
+

Detailed Description

+

Amcor A/C protocol.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/834
+
Remarks
Kudos to ldellus; For the breakdown and mapping of the bit values.
+

Variable Documentation

+ +

◆ kAmcorAuto

+ +
+
+ + + + +
const uint8_t kAmcorAuto = 0b101
+
+ +
+
+ +

◆ kAmcorChecksumByte

+ +
+
+ + + + +
const uint8_t kAmcorChecksumByte = kAmcorStateLength - 1
+
+ +
+
+ +

◆ kAmcorCool

+ +
+
+ + + + +
const uint8_t kAmcorCool = 0b001
+
+ +
+
+ +

◆ kAmcorDry

+ +
+
+ + + + +
const uint8_t kAmcorDry = 0b100
+
+ +
+
+ +

◆ kAmcorFan

+ +
+
+ + + + +
const uint8_t kAmcorFan = 0b011
+
+ +
+
+ +

◆ kAmcorFanAuto

+ +
+
+ + + + +
const uint8_t kAmcorFanAuto = 0b100
+
+ +
+
+ +

◆ kAmcorFanMax

+ +
+
+ + + + +
const uint8_t kAmcorFanMax = 0b011
+
+ +
+
+ +

◆ kAmcorFanMed

+ +
+
+ + + + +
const uint8_t kAmcorFanMed = 0b010
+
+ +
+
+ +

◆ kAmcorFanMin

+ +
+
+ + + + +
const uint8_t kAmcorFanMin = 0b001
+
+ +
+
+ +

◆ kAmcorFanOffset

+ +
+
+ + + + +
const uint8_t kAmcorFanOffset = 4
+
+ +
+
+ +

◆ kAmcorFanSize

+ +
+
+ + + + +
const uint8_t kAmcorFanSize = 3
+
+ +
+
+ +

◆ kAmcorHeat

+ +
+
+ + + + +
const uint8_t kAmcorHeat = 0b010
+
+ +
+
+ +

◆ kAmcorMax

+ +
+
+ + + + +
const uint8_t kAmcorMax = 0b11
+
+ +
+
+ +

◆ kAmcorMaxOffset

+ +
+
+ + + + +
const uint8_t kAmcorMaxOffset = 0
+
+ +
+
+ +

◆ kAmcorMaxSize

+ +
+
+ + + + +
const uint8_t kAmcorMaxSize = 2
+
+ +
+
+ +

◆ kAmcorMaxTemp

+ +
+
+ + + + +
const uint8_t kAmcorMaxTemp = 32
+
+ +
+
+ +

◆ kAmcorMinTemp

+ +
+
+ + + + +
const uint8_t kAmcorMinTemp = 12
+
+ +
+
+ +

◆ kAmcorModeFanByte

+ +
+
+ + + + +
const uint8_t kAmcorModeFanByte = 1
+
+ +
+
+ +

◆ kAmcorModeOffset

+ +
+
+ + + + +
const uint8_t kAmcorModeOffset = 0
+
+ +
+
+ +

◆ kAmcorModeSize

+ +
+
+ + + + +
const uint8_t kAmcorModeSize = 3
+
+ +
+
+ +

◆ kAmcorPowerByte

+ +
+
+ + + + +
const uint8_t kAmcorPowerByte = 5
+
+ +
+
+ +

◆ kAmcorPowerOff

+ +
+
+ + + + +
const uint8_t kAmcorPowerOff = 0b1100
+
+ +
+
+ +

◆ kAmcorPowerOffset

+ +
+
+ + + + +
const uint8_t kAmcorPowerOffset = 4
+
+ +
+
+ +

◆ kAmcorPowerOn

+ +
+
+ + + + +
const uint8_t kAmcorPowerOn = 0b0011
+
+ +
+
+ +

◆ kAmcorPowerSize

+ +
+
+ + + + +
const uint8_t kAmcorPowerSize = 4
+
+ +
+
+ +

◆ kAmcorSpecialByte

+ +
+
+ + + + +
const uint8_t kAmcorSpecialByte = 6
+
+ +
+
+ +

◆ kAmcorTempByte

+ +
+
+ + + + +
const uint8_t kAmcorTempByte = 2
+
+ +
+
+ +

◆ kAmcorTempOffset

+ +
+
+ + + + +
const uint8_t kAmcorTempOffset = 1
+
+ +
+
+ +

◆ kAmcorTempSize

+ +
+
+ + + + +
const uint8_t kAmcorTempSize = 6
+
+ +
+
+ +

◆ kAmcorVentOffset

+ +
+
+ + + + +
const uint8_t kAmcorVentOffset = 6
+
+ +
+
+ +

◆ kAmcorVentOn

+ +
+
+ + + + +
const uint8_t kAmcorVentOn = 0b11
+
+ +
+
+ +

◆ kAmcorVentSize

+ +
+
+ + + + +
const uint8_t kAmcorVentSize = 2
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h_source.html new file mode 100644 index 000000000..6bf1b93e7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h_source.html @@ -0,0 +1,274 @@ + + + + + + + +IRremoteESP8266: src/ir_Amcor.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Amcor.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
2 
+
7 // Supports:
+
8 // Brand: Amcor, Model: ADR-853H A/C
+
9 // Brand: Amcor, Model: TAC-495 remote
+
10 // Brand: Amcor, Model: TAC-444 remote
+
11 
+
12 #ifndef IR_AMCOR_H_
+
13 #define IR_AMCOR_H_
+
14 
+
15 #define __STDC_LIMIT_MACROS
+
16 #include <stdint.h>
+
17 #ifndef UNIT_TEST
+
18 #include <Arduino.h>
+
19 #endif
+
20 #include "IRremoteESP8266.h"
+
21 #include "IRsend.h"
+
22 #ifdef UNIT_TEST
+
23 #include "IRsend_test.h"
+
24 #endif
+
25 
+
26 
+
27 // Constants
+
28 
+
29 // state[1]
+
30 const uint8_t kAmcorModeFanByte = 1;
+
31 // Fan Control
+
32 const uint8_t kAmcorFanMin = 0b001;
+
33 const uint8_t kAmcorFanMed = 0b010;
+
34 const uint8_t kAmcorFanMax = 0b011;
+
35 const uint8_t kAmcorFanAuto = 0b100;
+
36 const uint8_t kAmcorFanOffset = 4;
+
37 const uint8_t kAmcorFanSize = 3;
+
38 // Modes
+
39 const uint8_t kAmcorCool = 0b001;
+
40 const uint8_t kAmcorHeat = 0b010;
+
41 const uint8_t kAmcorFan = 0b011; // Aka "Vent"
+
42 const uint8_t kAmcorDry = 0b100;
+
43 const uint8_t kAmcorAuto = 0b101;
+
44 const uint8_t kAmcorModeOffset = 0;
+
45 const uint8_t kAmcorModeSize = 3;
+
46 
+
47 // state[2]
+
48 const uint8_t kAmcorTempByte = 2;
+
49 // Temperature
+
50 const uint8_t kAmcorMinTemp = 12; // Celsius
+
51 const uint8_t kAmcorMaxTemp = 32; // Celsius
+
52 const uint8_t kAmcorTempOffset = 1;
+
53 const uint8_t kAmcorTempSize = 6; // Bits
+
54 
+
55 // state[5]
+
56 // Power
+
57 const uint8_t kAmcorPowerByte = 5;
+
58 const uint8_t kAmcorPowerOffset = 4;
+
59 const uint8_t kAmcorPowerSize = 4;
+
60 const uint8_t kAmcorPowerOn = 0b0011; // 0x3
+
61 const uint8_t kAmcorPowerOff = 0b1100; // 0xC
+
62 
+
63 // state[6]
+
64 const uint8_t kAmcorSpecialByte = 6;
+
65 // Max Mode (aka "Lo" in Cool and "Hi" in Heat)
+
66 const uint8_t kAmcorMax = 0b11;
+
67 const uint8_t kAmcorMaxOffset = 0;
+
68 const uint8_t kAmcorMaxSize = 2;
+
69 
+
70 // "Vent" Mode
+
71 const uint8_t kAmcorVentOn = 0b11;
+
72 const uint8_t kAmcorVentOffset = 6;
+
73 const uint8_t kAmcorVentSize = 2;
+
74 // state[7]
+
75 // Checksum byte.
+ +
77 
+
78 // Classes
+
79 
+
81 class IRAmcorAc {
+
82  public:
+
83  explicit IRAmcorAc(const uint16_t pin, const bool inverted = false,
+
84  const bool use_modulation = true);
+
85 
+
86  void stateReset();
+
87 #if SEND_AMCOR
+
88  void send(const uint16_t repeat = kAmcorDefaultRepeat);
+
93  int8_t calibrate(void) { return _irsend.calibrate(); }
+
94 #endif // SEND_AMCOR
+
95  void begin();
+
96  static uint8_t calcChecksum(const uint8_t state[],
+
97  const uint16_t length = kAmcorStateLength);
+
98  static bool validChecksum(const uint8_t state[],
+
99  const uint16_t length = kAmcorStateLength);
+
100  void setPower(const bool state);
+
101  bool getPower();
+
102  void on();
+
103  void off();
+
104  void setTemp(const uint8_t temp);
+
105  uint8_t getTemp();
+
106  void setMax(const bool on);
+
107  bool getMax(void);
+
108  void setFan(const uint8_t speed);
+
109  uint8_t getFan();
+
110  void setMode(const uint8_t mode);
+
111  uint8_t getMode();
+
112  uint8_t* getRaw();
+
113  void setRaw(const uint8_t state[]);
+
114  uint8_t convertMode(const stdAc::opmode_t mode);
+
115  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
116  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
117  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
118  stdAc::state_t toCommon(void);
+
119  String toString();
+
120 #ifndef UNIT_TEST
+
121 
+
122  private:
+ +
124 #else
+
125  IRsendTest _irsend;
+
128 #endif
+
129  uint8_t remote_state[kAmcorStateLength]; // The state of the IR remote.
+
130  void checksum(void);
+
131 };
+
132 #endif // IR_AMCOR_H_
+
+
IRAmcorAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Amcor.cpp:96
+
const uint8_t kAmcorSpecialByte
Definition: ir_Amcor.h:64
+
void setMode(const uint8_t mode)
Set the desired operation mode.
Definition: ir_Amcor.cpp:247
+
void send(const uint16_t repeat=kAmcorDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Amcor.cpp:106
+
const uint8_t kAmcorCool
Definition: ir_Amcor.h:39
+
const uint16_t kAmcorStateLength
Definition: IRremoteESP8266.h:818
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Amcor.cpp:303
+
const uint8_t kAmcorPowerOn
Definition: ir_Amcor.h:60
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kAmcorStateLength)
Calculate the checksum for the supplied state.
Definition: ir_Amcor.cpp:115
+
const uint8_t kAmcorMax
Definition: ir_Amcor.h:66
+
IRsend _irsend
Definition: ir_Amcor.h:123
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Amcor.cpp:285
+
const uint8_t kAmcorHeat
Definition: ir_Amcor.h:40
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Amcor.cpp:101
+
uint8_t getFan()
Get the current fan speed setting.
Definition: ir_Amcor.cpp:233
+ +
const uint8_t kAmcorMaxOffset
Definition: ir_Amcor.h:67
+
const uint8_t kAmcorFanAuto
Definition: ir_Amcor.h:35
+
uint8_t * getRaw()
Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.
Definition: ir_Amcor.cpp:145
+
const uint8_t kAmcorVentSize
Definition: ir_Amcor.h:73
+
uint8_t getMode()
Get the current operation mode setting.
Definition: ir_Amcor.cpp:240
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Amcor.cpp:217
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kAmcorTempByte
Definition: ir_Amcor.h:48
+
void on()
Set the internal state to have the power on.
Definition: ir_Amcor.cpp:157
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kAmcorPowerSize
Definition: ir_Amcor.h:59
+
Class for handling detailed Amcor A/C messages.
Definition: ir_Amcor.h:81
+
const uint8_t kAmcorMinTemp
Definition: ir_Amcor.h:50
+
void setMax(const bool on)
Control the current Maximum Cooling or Heating setting. (i.e. Turbo)
Definition: ir_Amcor.cpp:195
+
const uint8_t kAmcorMaxSize
Definition: ir_Amcor.h:68
+
const uint8_t kAmcorChecksumByte
Definition: ir_Amcor.h:76
+
void stateReset()
Reset the internals of the object to a known good state.
Definition: ir_Amcor.cpp:134
+
const uint8_t kAmcorFan
Definition: ir_Amcor.h:41
+
void setRaw(const uint8_t state[])
Set the raw state of the object.
Definition: ir_Amcor.cpp:152
+
const uint8_t kAmcorVentOn
Definition: ir_Amcor.h:71
+
const uint8_t kAmcorFanMin
Definition: ir_Amcor.h:32
+ +
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Amcor.cpp:267
+
const uint8_t kAmcorVentOffset
Definition: ir_Amcor.h:72
+
const uint8_t kAmcorDry
Definition: ir_Amcor.h:42
+
const uint8_t kAmcorFanMed
Definition: ir_Amcor.h:33
+
uint8_t remote_state[kAmcorStateLength]
Definition: ir_Amcor.h:129
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Amcor.cpp:178
+
const uint8_t kAmcorPowerByte
Definition: ir_Amcor.h:57
+
const uint8_t kAmcorTempSize
Definition: ir_Amcor.h:53
+
void off()
Set the internal state to have the power off.
Definition: ir_Amcor.cpp:160
+
void setPower(const bool state)
Set the internal state to have the desired power.
Definition: ir_Amcor.cpp:164
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Amcor.cpp:187
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Amcor.h:93
+
bool getPower()
Get the power setting from the internal state.
Definition: ir_Amcor.cpp:171
+
const uint8_t kAmcorPowerOff
Definition: ir_Amcor.h:61
+
const uint8_t kAmcorModeSize
Definition: ir_Amcor.h:45
+
void checksum(void)
Update the checksum value for the internal state.
Definition: ir_Amcor.cpp:128
+
const uint8_t kAmcorFanSize
Definition: ir_Amcor.h:37
+
const uint8_t kAmcorModeOffset
Definition: ir_Amcor.h:44
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kAmcorStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Amcor.cpp:123
+
const uint8_t kAmcorPowerOffset
Definition: ir_Amcor.h:58
+
const uint8_t kAmcorAuto
Definition: ir_Amcor.h:43
+
const uint8_t kAmcorModeFanByte
Definition: ir_Amcor.h:30
+
const uint8_t kAmcorMaxTemp
Definition: ir_Amcor.h:51
+
const uint16_t kAmcorDefaultRepeat
Definition: IRremoteESP8266.h:820
+
const uint8_t kAmcorFanOffset
Definition: ir_Amcor.h:36
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Amcor.cpp:327
+
const uint8_t kAmcorFanMax
Definition: ir_Amcor.h:34
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Amcor.cpp:353
+
bool getMax(void)
Is the Maximum Cooling or Heating setting (i.e. Turbo) setting on?
Definition: ir_Amcor.cpp:210
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Amcor.cpp:316
+
const uint8_t kAmcorTempOffset
Definition: ir_Amcor.h:52
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8cpp.html new file mode 100644 index 000000000..7acafb331 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8cpp.html @@ -0,0 +1,188 @@ + + + + + + + +IRremoteESP8266: src/ir_Argo.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Argo.cpp File Reference
+
+
+ +

Argo A/C protocol. Controls an Argo Ulisse 13 DCI A/C. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kArgoHdrMark = 6400
 
const uint16_t kArgoHdrSpace = 3300
 
const uint16_t kArgoBitMark = 400
 
const uint16_t kArgoOneSpace = 2200
 
const uint16_t kArgoZeroSpace = 900
 
const uint32_t kArgoGap = kDefaultMessageGap
 
+

Detailed Description

+

Argo A/C protocol. Controls an Argo Ulisse 13 DCI A/C.

+

Variable Documentation

+ +

◆ kArgoBitMark

+ +
+
+ + + + +
const uint16_t kArgoBitMark = 400
+
+ +
+
+ +

◆ kArgoGap

+ +
+
+ + + + +
const uint32_t kArgoGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kArgoHdrMark

+ +
+
+ + + + +
const uint16_t kArgoHdrMark = 6400
+
+ +
+
+ +

◆ kArgoHdrSpace

+ +
+
+ + + + +
const uint16_t kArgoHdrSpace = 3300
+
+ +
+
+ +

◆ kArgoOneSpace

+ +
+
+ + + + +
const uint16_t kArgoOneSpace = 2200
+
+ +
+
+ +

◆ kArgoZeroSpace

+ +
+
+ + + + +
const uint16_t kArgoZeroSpace = 900
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h.html new file mode 100644 index 000000000..4e754d73f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h.html @@ -0,0 +1,747 @@ + + + + + + + +IRremoteESP8266: src/ir_Argo.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Argo.h File Reference
+
+
+ +

Support for Argo Ulisse 13 DCI Mobile Split ACs. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRArgoAC
 Class for handling detailed Argo A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kArgoHeatBit = 0b00100000
 
const uint8_t kArgoTempLowOffset = 5
 
const uint8_t kArgoTempLowSize = 2
 
const uint8_t kArgoModeOffset = 3
 
const uint8_t kArgoModeSize = 3
 
const uint8_t kArgoCool = 0b000
 
const uint8_t kArgoDry = 0b001
 
const uint8_t kArgoAuto = 0b010
 
const uint8_t kArgoOff = 0b011
 
const uint8_t kArgoHeat = 0b100
 
const uint8_t kArgoHeatAuto = 0b101
 
const uint8_t kArgoHeatBlink = 0b110
 
const uint8_t kArgoTempHighOffset = 0
 
const uint8_t kArgoTempHighSize = 3
 
const uint8_t kArgoFanOffset = 3
 
const uint8_t kArgoFanSize = 2
 
const uint8_t kArgoFanAuto = 0
 
const uint8_t kArgoFan1 = 1
 
const uint8_t kArgoFan2 = 2
 
const uint8_t kArgoFan3 = 3
 
const uint8_t kArgoRoomTempLowOffset = 5
 
const uint8_t kArgoRoomTempLowSize = 3
 
const uint8_t kArgoRoomTempHighOffset = 0
 
const uint8_t kArgoRoomTempHighSize = 2
 
const uint8_t kArgoTempDelta = 4
 
const uint8_t kArgoMaxRoomTemp
 
const uint8_t kArgoNightBitOffset = 2
 
const uint8_t kArgoMaxBitOffset = 3
 
const uint8_t kArgoPowerBitOffset = 5
 
const uint8_t kArgoIFeelBitOffset = 7
 
const uint8_t kArgoMinTemp = 10
 
const uint8_t kArgoMaxTemp = 32
 
const uint8_t kArgoFlapAuto = 0
 
const uint8_t kArgoFlap1 = 1
 
const uint8_t kArgoFlap2 = 2
 
const uint8_t kArgoFlap3 = 3
 
const uint8_t kArgoFlap4 = 4
 
const uint8_t kArgoFlap5 = 5
 
const uint8_t kArgoFlap6 = 6
 
const uint8_t kArgoFlapFull = 7
 
+

Detailed Description

+

Support for Argo Ulisse 13 DCI Mobile Split ACs.

+

Variable Documentation

+ +

◆ kArgoAuto

+ +
+
+ + + + +
const uint8_t kArgoAuto = 0b010
+
+ +
+
+ +

◆ kArgoCool

+ +
+
+ + + + +
const uint8_t kArgoCool = 0b000
+
+ +
+
+ +

◆ kArgoDry

+ +
+
+ + + + +
const uint8_t kArgoDry = 0b001
+
+ +
+
+ +

◆ kArgoFan1

+ +
+
+ + + + +
const uint8_t kArgoFan1 = 1
+
+ +
+
+ +

◆ kArgoFan2

+ +
+
+ + + + +
const uint8_t kArgoFan2 = 2
+
+ +
+
+ +

◆ kArgoFan3

+ +
+
+ + + + +
const uint8_t kArgoFan3 = 3
+
+ +
+
+ +

◆ kArgoFanAuto

+ +
+
+ + + + +
const uint8_t kArgoFanAuto = 0
+
+ +
+
+ +

◆ kArgoFanOffset

+ +
+
+ + + + +
const uint8_t kArgoFanOffset = 3
+
+ +
+
+ +

◆ kArgoFanSize

+ +
+
+ + + + +
const uint8_t kArgoFanSize = 2
+
+ +
+
+ +

◆ kArgoFlap1

+ +
+
+ + + + +
const uint8_t kArgoFlap1 = 1
+
+ +
+
+ +

◆ kArgoFlap2

+ +
+
+ + + + +
const uint8_t kArgoFlap2 = 2
+
+ +
+
+ +

◆ kArgoFlap3

+ +
+
+ + + + +
const uint8_t kArgoFlap3 = 3
+
+ +
+
+ +

◆ kArgoFlap4

+ +
+
+ + + + +
const uint8_t kArgoFlap4 = 4
+
+ +
+
+ +

◆ kArgoFlap5

+ +
+
+ + + + +
const uint8_t kArgoFlap5 = 5
+
+ +
+
+ +

◆ kArgoFlap6

+ +
+
+ + + + +
const uint8_t kArgoFlap6 = 6
+
+ +
+
+ +

◆ kArgoFlapAuto

+ +
+
+ + + + +
const uint8_t kArgoFlapAuto = 0
+
+ +
+
+ +

◆ kArgoFlapFull

+ +
+
+ + + + +
const uint8_t kArgoFlapFull = 7
+
+ +
+
+ +

◆ kArgoHeat

+ +
+
+ + + + +
const uint8_t kArgoHeat = 0b100
+
+ +
+
+ +

◆ kArgoHeatAuto

+ +
+
+ + + + +
const uint8_t kArgoHeatAuto = 0b101
+
+ +
+
+ +

◆ kArgoHeatBit

+ +
+
+ + + + +
const uint8_t kArgoHeatBit = 0b00100000
+
+ +
+
+ +

◆ kArgoHeatBlink

+ +
+
+ + + + +
const uint8_t kArgoHeatBlink = 0b110
+
+ +
+
+ +

◆ kArgoIFeelBitOffset

+ +
+
+ + + + +
const uint8_t kArgoIFeelBitOffset = 7
+
+ +
+
+ +

◆ kArgoMaxBitOffset

+ +
+
+ + + + +
const uint8_t kArgoMaxBitOffset = 3
+
+ +
+
+ +

◆ kArgoMaxRoomTemp

+ +
+
+ + + + +
const uint8_t kArgoMaxRoomTemp
+
+Initial value: +
+
+ +

◆ kArgoMaxTemp

+ +
+
+ + + + +
const uint8_t kArgoMaxTemp = 32
+
+ +
+
+ +

◆ kArgoMinTemp

+ +
+
+ + + + +
const uint8_t kArgoMinTemp = 10
+
+ +
+
+ +

◆ kArgoModeOffset

+ +
+
+ + + + +
const uint8_t kArgoModeOffset = 3
+
+ +
+
+ +

◆ kArgoModeSize

+ +
+
+ + + + +
const uint8_t kArgoModeSize = 3
+
+ +
+
+ +

◆ kArgoNightBitOffset

+ +
+
+ + + + +
const uint8_t kArgoNightBitOffset = 2
+
+ +
+
+ +

◆ kArgoOff

+ +
+
+ + + + +
const uint8_t kArgoOff = 0b011
+
+ +
+
+ +

◆ kArgoPowerBitOffset

+ +
+
+ + + + +
const uint8_t kArgoPowerBitOffset = 5
+
+ +
+
+ +

◆ kArgoRoomTempHighOffset

+ +
+
+ + + + +
const uint8_t kArgoRoomTempHighOffset = 0
+
+ +
+
+ +

◆ kArgoRoomTempHighSize

+ +
+
+ + + + +
const uint8_t kArgoRoomTempHighSize = 2
+
+ +
+
+ +

◆ kArgoRoomTempLowOffset

+ +
+
+ + + + +
const uint8_t kArgoRoomTempLowOffset = 5
+
+ +
+
+ +

◆ kArgoRoomTempLowSize

+ +
+
+ + + + +
const uint8_t kArgoRoomTempLowSize = 3
+
+ +
+
+ +

◆ kArgoTempDelta

+ +
+
+ + + + +
const uint8_t kArgoTempDelta = 4
+
+ +
+
+ +

◆ kArgoTempHighOffset

+ +
+
+ + + + +
const uint8_t kArgoTempHighOffset = 0
+
+ +
+
+ +

◆ kArgoTempHighSize

+ +
+
+ + + + +
const uint8_t kArgoTempHighSize = 3
+
+ +
+
+ +

◆ kArgoTempLowOffset

+ +
+
+ + + + +
const uint8_t kArgoTempLowOffset = 5
+
+ +
+
+ +

◆ kArgoTempLowSize

+ +
+
+ + + + +
const uint8_t kArgoTempLowSize = 2
+
+ +
+
+
+
const uint8_t kArgoRoomTempHighSize
Definition: ir_Argo.h:79
+
const uint8_t kArgoRoomTempLowSize
Definition: ir_Argo.h:74
+
const uint8_t kArgoTempDelta
Definition: ir_Argo.h:81
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h_source.html new file mode 100644 index 000000000..c042059f9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h_source.html @@ -0,0 +1,373 @@ + + + + + + + +IRremoteESP8266: src/ir_Argo.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Argo.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 Schmolders
+
4 
+
5 // Supports:
+
6 // Brand: Argo, Model: Ulisse 13 DCI Mobile Split A/C
+
7 
+
8 #ifndef IR_ARGO_H_
+
9 #define IR_ARGO_H_
+
10 
+
11 #ifndef UNIT_TEST
+
12 #include <Arduino.h>
+
13 #endif
+
14 #include "IRremoteESP8266.h"
+
15 #include "IRsend.h"
+
16 #ifdef UNIT_TEST
+
17 #include "IRsend_test.h"
+
18 #endif
+
19 
+
20 
+
21 // ARGO Ulisse DCI
+
22 
+
23 /*
+
24  Protocol Description:
+
25  All in LSB first as it is sent. argo message array will be stored MSB first!
+
26  do LSB-MSB conversion in sendData
+
27  Byte 0: const 0 0 1 1 0 1 0 1
+
28  Byte 1: const 1 0 1 0 1 1 1 1
+
29  Byte 2: 0 0 0, 3bit Cool/Heat Mode, 2bit start SetTemp LSB first
+
30  Byte 3: 3bit End SetTemp, 2bit Fan Mode, 3bit RoomTemp LSB first
+
31  Byte 4: 2bit RoomTemp, 3bit Flap Mode, 3bit OnTimer
+
32  Byte 5: 8bit OnTimer
+
33  Byte 6: 8Bit OffTimer
+
34  Byte 7: 3bit OffTimer, 5bit Time
+
35  Byte 8: 6bit Time, 1bit Timer On/Off, 1bit Timer Program
+
36  Byte 9: 1bit Timer Program, 1bit Timer 1h, 1 bit Night Mode, 1bit Max Mode, 1bit Filter, 1bit on/off, 1bit const 0, 1bit iFeel
+
37  Byte 10: 2bit const 0 1, 6bit Checksum
+
38  Byte 11: 2bit Checksum
+
39 */
+
40 
+
41 // Constants. Store MSB left.
+
42 
+
43 // byte[2]
+
44 const uint8_t kArgoHeatBit = 0b00100000;
+
45 // kArgoTempLowMask = 0b11000000;
+
46 const uint8_t kArgoTempLowOffset = 5;
+
47 const uint8_t kArgoTempLowSize = 2;
+
48 
+
49 // Mode 0b00111000
+
50 const uint8_t kArgoModeOffset = 3;
+
51 const uint8_t kArgoModeSize = 3;
+
52 const uint8_t kArgoCool = 0b000;
+
53 const uint8_t kArgoDry = 0b001;
+
54 const uint8_t kArgoAuto = 0b010;
+
55 const uint8_t kArgoOff = 0b011;
+
56 const uint8_t kArgoHeat = 0b100;
+
57 const uint8_t kArgoHeatAuto = 0b101;
+
58 // ?no idea what mode that is
+
59 const uint8_t kArgoHeatBlink = 0b110;
+
60 
+
61 // byte[3]
+
62 // kArgoTempHighMask = 0b00000111;
+
63 const uint8_t kArgoTempHighOffset = 0;
+
64 const uint8_t kArgoTempHighSize = 3;
+
65 // Fan 0b00011000
+
66 const uint8_t kArgoFanOffset = 3;
+
67 const uint8_t kArgoFanSize = 2;
+
68 const uint8_t kArgoFanAuto = 0; // 0b00
+
69 const uint8_t kArgoFan1 = 1; // 0b01
+
70 const uint8_t kArgoFan2 = 2; // 0b10
+
71 const uint8_t kArgoFan3 = 3; // 0b11
+
72 // kArgoRoomTempLowMask = 0b11100000;
+
73 const uint8_t kArgoRoomTempLowOffset = 5;
+
74 const uint8_t kArgoRoomTempLowSize = 3;
+
75 
+
76 // byte[4]
+
77 // kArgoRoomTempHighMask = 0b00000011;
+
78 const uint8_t kArgoRoomTempHighOffset = 0;
+
79 const uint8_t kArgoRoomTempHighSize = 2;
+
80 
+
81 const uint8_t kArgoTempDelta = 4;
+
82 const uint8_t kArgoMaxRoomTemp =
+ +
84  kArgoTempDelta; // 35C
+
85 
+
86 // byte[9]
+
87 const uint8_t kArgoNightBitOffset = 2;
+
88 const uint8_t kArgoMaxBitOffset = 3;
+
89 const uint8_t kArgoPowerBitOffset = 5;
+
90 const uint8_t kArgoIFeelBitOffset = 7;
+
91 
+
92 const uint8_t kArgoMinTemp = 10; // Celsius delta +4
+
93 const uint8_t kArgoMaxTemp = 32; // Celsius
+
94 
+
95 const uint8_t kArgoFlapAuto = 0;
+
96 const uint8_t kArgoFlap1 = 1;
+
97 const uint8_t kArgoFlap2 = 2;
+
98 const uint8_t kArgoFlap3 = 3;
+
99 const uint8_t kArgoFlap4 = 4;
+
100 const uint8_t kArgoFlap5 = 5;
+
101 const uint8_t kArgoFlap6 = 6;
+
102 const uint8_t kArgoFlapFull = 7;
+
103 
+
104 // Legacy defines. (Deperecated)
+
105 #define ARGO_COOL_ON kArgoCoolOn
+
106 #define ARGO_COOL_OFF kArgoCoolOff
+
107 #define ARGO_COOL_AUTO kArgoCoolAuto
+
108 #define ARGO_COOL_HUM kArgoCoolHum
+
109 #define ARGO_HEAT_ON kArgoHeatOn
+
110 #define ARGO_HEAT_AUTO kArgoHeatAuto
+
111 #define ARGO_HEAT_BLINK kArgoHeatBlink
+
112 #define ARGO_MIN_TEMP kArgoMinTemp
+
113 #define ARGO_MAX_TEMP kArgoMaxTemp
+
114 #define ARGO_FAN_AUTO kArgoFanAuto
+
115 #define ARGO_FAN_3 kArgoFan3
+
116 #define ARGO_FAN_2 kArgoFan2
+
117 #define ARGO_FAN_1 kArgoFan1
+
118 #define ARGO_FLAP_AUTO kArgoFlapAuto
+
119 #define ARGO_FLAP_1 kArgoFlap1
+
120 #define ARGO_FLAP_2 kArgoFlap2
+
121 #define ARGO_FLAP_3 kArgoFlap3
+
122 #define ARGO_FLAP_4 kArgoFlap4
+
123 #define ARGO_FLAP_5 kArgoFlap5
+
124 #define ARGO_FLAP_6 kArgoFlap6
+
125 #define ARGO_FLAP_FULL kArgoFlapFull
+
126 
+
127 
+
129 class IRArgoAC {
+
130  public:
+
131  explicit IRArgoAC(const uint16_t pin, const bool inverted = false,
+
132  const bool use_modulation = true);
+
133 
+
134 #if SEND_ARGO
+
135  void send(const uint16_t repeat = kArgoDefaultRepeat);
+
140  int8_t calibrate(void) { return _irsend.calibrate(); }
+
141 #endif // SEND_ARGO
+
142  void begin(void);
+
143  void on(void);
+
144  void off(void);
+
145 
+
146  void setPower(const bool on);
+
147  bool getPower(void);
+
148 
+
149  void setTemp(const uint8_t degrees);
+
150  uint8_t getTemp(void);
+
151 
+
152  void setFan(const uint8_t fan);
+
153  uint8_t getFan(void);
+
154 
+
155  void setFlap(const uint8_t flap);
+
156  uint8_t getFlap(void);
+
157 
+
158  void setMode(const uint8_t mode);
+
159  uint8_t getMode(void);
+
160 
+
161  void setMax(const bool on);
+
162  bool getMax(void);
+
163 
+
164  void setNight(const bool on);
+
165  bool getNight(void);
+
166 
+
167  void setiFeel(const bool on);
+
168  bool getiFeel(void);
+
169 
+
170  void setTime(void);
+
171  void setRoomTemp(const uint8_t degrees);
+
172  uint8_t getRoomTemp(void);
+
173 
+
174  uint8_t* getRaw(void);
+
175  void setRaw(const uint8_t state[]);
+
176  static uint8_t calcChecksum(const uint8_t state[],
+
177  const uint16_t length = kArgoStateLength);
+
178  static bool validChecksum(const uint8_t state[],
+
179  const uint16_t length = kArgoStateLength);
+
180  static uint8_t convertMode(const stdAc::opmode_t mode);
+
181  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
182  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
183  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
184  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
185  stdAc::state_t toCommon(void);
+
186  String toString();
+
187 #ifndef UNIT_TEST
+
188 
+
189  private:
+ +
191 #else
+
192  IRsendTest _irsend;
+
194 #endif
+
196  // # of bytes per command
+
197  uint8_t argo[kArgoStateLength]; // Defined in IRremoteESP8266.h
+
198  void stateReset(void);
+
199  void checksum(void);
+
200 
+
201  // Attributes
+
202  uint8_t flap_mode;
+
203  uint8_t heat_mode;
+
204  uint8_t cool_mode;
+
205 };
+
206 
+
207 #endif // IR_ARGO_H_
+
+
const uint8_t kArgoFanOffset
Definition: ir_Argo.h:66
+
void setTime(void)
Set the time for the A/C.
Definition: ir_Argo.cpp:253
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kArgoStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Argo.cpp:74
+
uint8_t flap_mode
Definition: ir_Argo.h:202
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Argo.cpp:185
+
IRsend _irsend
instance of the IR send class
Definition: ir_Argo.h:190
+
const uint8_t kArgoHeatBlink
Definition: ir_Argo.h:59
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
const uint8_t kArgoMaxTemp
Definition: ir_Argo.h:93
+
const uint16_t kArgoDefaultRepeat
Definition: IRremoteESP8266.h:823
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Argo.cpp:162
+
void setFlap(const uint8_t flap)
Set the flap position. i.e. Swing.
Definition: ir_Argo.cpp:198
+
uint8_t getMode(void)
Get the current operation mode setting.
Definition: ir_Argo.cpp:210
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Argo.cpp:279
+
const uint8_t kArgoPowerBitOffset
Definition: ir_Argo.h:89
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kArgoTempHighOffset
Definition: ir_Argo.h:63
+
const uint8_t kArgoFlap2
Definition: ir_Argo.h:97
+
void stateReset(void)
Reset the internals of the object to a known good state.
Definition: ir_Argo.cpp:101
+
const uint8_t kArgoFlap4
Definition: ir_Argo.h:99
+
const uint8_t kArgoTempHighSize
Definition: ir_Argo.h:64
+
const uint8_t kArgoHeatBit
Definition: ir_Argo.h:44
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Argo.h:140
+
uint8_t argo[kArgoStateLength]
Definition: ir_Argo.h:197
+ +
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Argo.cpp:360
+
const uint8_t kArgoFlap3
Definition: ir_Argo.h:98
+
const uint8_t kArgoMaxBitOffset
Definition: ir_Argo.h:88
+
bool getiFeel(void)
Get the status of iFeel mode.
Definition: ir_Argo.cpp:249
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kArgoStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Argo.cpp:85
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
uint8_t getFlap(void)
Get the flap position. i.e. Swing.
Definition: ir_Argo.cpp:206
+
bool getMax(void)
Is the Max (i.e. Turbo) setting on?
Definition: ir_Argo.cpp:157
+
const uint16_t kArgoStateLength
Definition: IRremoteESP8266.h:821
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kArgoFan1
Definition: ir_Argo.h:69
+
uint8_t getRoomTemp(void)
Get the currently stored value for the room temperature setting.
Definition: ir_Argo.cpp:269
+
bool getPower(void)
Get the power setting from the internal state.
Definition: ir_Argo.cpp:147
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Argo.cpp:336
+
const uint8_t kArgoOff
Definition: ir_Argo.h:55
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Argo.cpp:316
+
const uint8_t kArgoFlapFull
Definition: ir_Argo.h:102
+
const uint8_t kArgoRoomTempHighSize
Definition: ir_Argo.h:79
+ +
const uint8_t kArgoDry
Definition: ir_Argo.h:53
+
const uint8_t kArgoAuto
Definition: ir_Argo.h:54
+
void setRoomTemp(const uint8_t degrees)
Set the value for the current room temperature.
Definition: ir_Argo.cpp:259
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Argo.cpp:298
+
const uint8_t kArgoTempLowOffset
Definition: ir_Argo.h:46
+
void off(void)
Set the internal state to have the power off.
Definition: ir_Argo.cpp:137
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Argo.cpp:191
+
void setPower(const bool on)
Set the internal state to have the desired power.
Definition: ir_Argo.cpp:141
+
const uint8_t kArgoRoomTempLowOffset
Definition: ir_Argo.h:73
+
const uint8_t kArgoFlap1
Definition: ir_Argo.h:96
+
const uint8_t kArgoModeOffset
Definition: ir_Argo.h:50
+
uint8_t * getRaw(void)
Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.
Definition: ir_Argo.cpp:122
+
const uint8_t kArgoTempLowSize
Definition: ir_Argo.h:47
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Argo.cpp:176
+
const uint8_t kArgoRoomTempLowSize
Definition: ir_Argo.h:74
+
uint8_t heat_mode
Definition: ir_Argo.h:203
+
const uint8_t kArgoMinTemp
Definition: ir_Argo.h:92
+
void on(void)
Set the internal state to have the power on.
Definition: ir_Argo.cpp:134
+
void setNight(const bool on)
Turn on/off the Night mode. i.e. Sleep.
Definition: ir_Argo.cpp:233
+
bool getNight(void)
Get the status of Night mode. i.e. Sleep.
Definition: ir_Argo.cpp:239
+
const uint8_t kArgoFan2
Definition: ir_Argo.h:70
+
const uint8_t kArgoIFeelBitOffset
Definition: ir_Argo.h:90
+
const uint8_t kArgoCool
Definition: ir_Argo.h:52
+
void send(const uint16_t repeat=kArgoDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Argo.cpp:65
+
const uint8_t kArgoHeatAuto
Definition: ir_Argo.h:57
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Argo.cpp:349
+
const uint8_t kArgoHeat
Definition: ir_Argo.h:56
+
void setRaw(const uint8_t state[])
Set the raw state of the object.
Definition: ir_Argo.cpp:129
+
const uint8_t kArgoFlap5
Definition: ir_Argo.h:100
+
IRArgoAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Argo.cpp:55
+
const uint8_t kArgoTempDelta
Definition: ir_Argo.h:81
+
const uint8_t kArgoRoomTempHighOffset
Definition: ir_Argo.h:78
+
void checksum(void)
Update the checksum for the internal state.
Definition: ir_Argo.cpp:91
+
const uint8_t kArgoFlap6
Definition: ir_Argo.h:101
+
const uint8_t kArgoModeSize
Definition: ir_Argo.h:51
+
uint8_t cool_mode
Definition: ir_Argo.h:204
+
void setiFeel(const bool on)
Turn on/off the iFeel mode.
Definition: ir_Argo.cpp:243
+
void setMax(const bool on)
Control the current Max setting. (i.e. Turbo)
Definition: ir_Argo.cpp:151
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Argo.cpp:386
+
const uint8_t kArgoFlapAuto
Definition: ir_Argo.h:95
+
const uint8_t kArgoFanSize
Definition: ir_Argo.h:67
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kArgoFan3
Definition: ir_Argo.h:71
+
Class for handling detailed Argo A/C messages.
Definition: ir_Argo.h:129
+
const uint8_t kArgoNightBitOffset
Definition: ir_Argo.h:87
+
const uint8_t kArgoFanAuto
Definition: ir_Argo.h:68
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Argo.cpp:60
+
void setMode(const uint8_t mode)
Set the desired operation mode.
Definition: ir_Argo.cpp:216
+
const uint8_t kArgoMaxRoomTemp
Definition: ir_Argo.h:82
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8cpp.html new file mode 100644 index 000000000..23c897e70 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8cpp.html @@ -0,0 +1,400 @@ + + + + + + + +IRremoteESP8266: src/ir_Carrier.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Carrier.cpp File Reference
+
+
+ +

Carrier protocols. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kCarrierAcHdrMark = 8532
 
const uint16_t kCarrierAcHdrSpace = 4228
 
const uint16_t kCarrierAcBitMark = 628
 
const uint16_t kCarrierAcOneSpace = 1320
 
const uint16_t kCarrierAcZeroSpace = 532
 
const uint16_t kCarrierAcGap = 20000
 
const uint16_t kCarrierAcFreq = 38
 
const uint16_t kCarrierAc40HdrMark = 8402
 
const uint16_t kCarrierAc40HdrSpace = 4166
 
const uint16_t kCarrierAc40BitMark = 547
 
const uint16_t kCarrierAc40OneSpace = 1540
 
const uint16_t kCarrierAc40ZeroSpace = 497
 
const uint32_t kCarrierAc40Gap = 150000
 
const uint16_t kCarrierAc64HdrMark = 8940
 
const uint16_t kCarrierAc64HdrSpace = 4556
 
const uint16_t kCarrierAc64BitMark = 503
 
const uint16_t kCarrierAc64OneSpace = 1736
 
const uint16_t kCarrierAc64ZeroSpace = 615
 
const uint32_t kCarrierAc64Gap = kDefaultMessageGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kCarrierAc40BitMark

+ +
+
+ + + + +
const uint16_t kCarrierAc40BitMark = 547
+
+ +
+
+ +

◆ kCarrierAc40Gap

+ +
+
+ + + + +
const uint32_t kCarrierAc40Gap = 150000
+
+
+ +

◆ kCarrierAc40HdrMark

+ +
+
+ + + + +
const uint16_t kCarrierAc40HdrMark = 8402
+
+ +
+
+ +

◆ kCarrierAc40HdrSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc40HdrSpace = 4166
+
+ +
+
+ +

◆ kCarrierAc40OneSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc40OneSpace = 1540
+
+ +
+
+ +

◆ kCarrierAc40ZeroSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc40ZeroSpace = 497
+
+ +
+
+ +

◆ kCarrierAc64BitMark

+ +
+
+ + + + +
const uint16_t kCarrierAc64BitMark = 503
+
+ +
+
+ +

◆ kCarrierAc64Gap

+ +
+
+ + + + +
const uint32_t kCarrierAc64Gap = kDefaultMessageGap
+
+ +
+
+ +

◆ kCarrierAc64HdrMark

+ +
+
+ + + + +
const uint16_t kCarrierAc64HdrMark = 8940
+
+ +
+
+ +

◆ kCarrierAc64HdrSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc64HdrSpace = 4556
+
+ +
+
+ +

◆ kCarrierAc64OneSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc64OneSpace = 1736
+
+ +
+
+ +

◆ kCarrierAc64ZeroSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc64ZeroSpace = 615
+
+ +
+
+ +

◆ kCarrierAcBitMark

+ +
+
+ + + + +
const uint16_t kCarrierAcBitMark = 628
+
+ +
+
+ +

◆ kCarrierAcFreq

+ +
+
+ + + + +
const uint16_t kCarrierAcFreq = 38
+
+ +
+
+ +

◆ kCarrierAcGap

+ +
+
+ + + + +
const uint16_t kCarrierAcGap = 20000
+
+ +
+
+ +

◆ kCarrierAcHdrMark

+ +
+
+ + + + +
const uint16_t kCarrierAcHdrMark = 8532
+
+ +
+
+ +

◆ kCarrierAcHdrSpace

+ +
+
+ + + + +
const uint16_t kCarrierAcHdrSpace = 4228
+
+ +
+
+ +

◆ kCarrierAcOneSpace

+ +
+
+ + + + +
const uint16_t kCarrierAcOneSpace = 1320
+
+ +
+
+ +

◆ kCarrierAcZeroSpace

+ +
+
+ + + + +
const uint16_t kCarrierAcZeroSpace = 532
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h.html new file mode 100644 index 000000000..a8953bf3e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h.html @@ -0,0 +1,568 @@ + + + + + + + +IRremoteESP8266: src/ir_Carrier.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Carrier.h File Reference
+
+
+ +

Carrier A/C. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRCarrierAc64
 Class for handling detailed Carrier 64 bit A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kCarrierAc64ChecksumOffset = 16
 
const uint8_t kCarrierAc64ChecksumSize = 4
 
const uint8_t kCarrierAc64ModeOffset
 
const uint8_t kCarrierAc64ModeSize = 2
 
const uint8_t kCarrierAc64Heat = 0b01
 
const uint8_t kCarrierAc64Cool = 0b10
 
const uint8_t kCarrierAc64Fan = 0b11
 
const uint8_t kCarrierAc64FanOffset
 
const uint8_t kCarrierAc64FanSize = 2
 
const uint8_t kCarrierAc64FanAuto = 0b00
 
const uint8_t kCarrierAc64FanLow = 0b01
 
const uint8_t kCarrierAc64FanMedium = 0b10
 
const uint8_t kCarrierAc64FanHigh = 0b11
 
const uint8_t kCarrierAc64TempOffset
 
const uint8_t kCarrierAc64TempSize = 4
 
const uint8_t kCarrierAc64MinTemp = 16
 
const uint8_t kCarrierAc64MaxTemp = 30
 
const uint8_t kCarrierAc64SwingVOffset
 
const uint8_t kCarrierAc64PowerOffset = kCarrierAc64SwingVOffset + 6 + 1
 
const uint8_t kCarrierAc64OffTimerEnableOffset
 
const uint8_t kCarrierAc64OnTimerEnableOffset
 
const uint8_t kCarrierAc64SleepOffset
 
const uint8_t kCarrierAc64TimerSize = 4
 
const uint8_t kCarrierAc64TimerMax = 9
 
const uint8_t kCarrierAc64TimerMin = 1
 
const uint8_t kCarrierAc64OnTimerOffset
 
const uint8_t kCarrierAc64OffTimerOffset
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kCarrierAc64ChecksumOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64ChecksumOffset = 16
+
+ +
+
+ +

◆ kCarrierAc64ChecksumSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64ChecksumSize = 4
+
+ +
+
+ +

◆ kCarrierAc64Cool

+ +
+
+ + + + +
const uint8_t kCarrierAc64Cool = 0b10
+
+ +
+
+ +

◆ kCarrierAc64Fan

+ +
+
+ + + + +
const uint8_t kCarrierAc64Fan = 0b11
+
+ +
+
+ +

◆ kCarrierAc64FanAuto

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanAuto = 0b00
+
+ +
+
+ +

◆ kCarrierAc64FanHigh

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanHigh = 0b11
+
+ +
+
+ +

◆ kCarrierAc64FanLow

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanLow = 0b01
+
+ +
+
+ +

◆ kCarrierAc64FanMedium

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanMedium = 0b10
+
+ +
+
+ +

◆ kCarrierAc64FanOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanOffset
+
+
+ +

◆ kCarrierAc64FanSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanSize = 2
+
+ +
+
+ +

◆ kCarrierAc64Heat

+ +
+
+ + + + +
const uint8_t kCarrierAc64Heat = 0b01
+
+ +
+
+ +

◆ kCarrierAc64MaxTemp

+ +
+
+ + + + +
const uint8_t kCarrierAc64MaxTemp = 30
+
+ +
+
+ +

◆ kCarrierAc64MinTemp

+ +
+
+ + + + +
const uint8_t kCarrierAc64MinTemp = 16
+
+ +
+
+ +

◆ kCarrierAc64ModeOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64ModeOffset
+
+
+ +

◆ kCarrierAc64ModeSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64ModeSize = 2
+
+ +
+
+ +

◆ kCarrierAc64OffTimerEnableOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64OffTimerEnableOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64OffTimerOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64OffTimerOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64OnTimerEnableOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64OnTimerEnableOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64OnTimerOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64OnTimerOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64PowerOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64PowerOffset = kCarrierAc64SwingVOffset + 6 + 1
+
+ +
+
+ +

◆ kCarrierAc64SleepOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64SleepOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64SwingVOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64SwingVOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64TempOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64TempOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64TempSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64TempSize = 4
+
+ +
+
+ +

◆ kCarrierAc64TimerMax

+ +
+
+ + + + +
const uint8_t kCarrierAc64TimerMax = 9
+
+ +
+
+ +

◆ kCarrierAc64TimerMin

+ +
+
+ + + + +
const uint8_t kCarrierAc64TimerMin = 1
+
+ +
+
+ +

◆ kCarrierAc64TimerSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64TimerSize = 4
+
+ +
+
+
+
const uint8_t kCarrierAc64SleepOffset
Definition: ir_Carrier.h:60
+
const uint8_t kCarrierAc64FanSize
Definition: ir_Carrier.h:43
+
const uint8_t kCarrierAc64OnTimerEnableOffset
Definition: ir_Carrier.h:58
+
const uint8_t kCarrierAc64OnTimerOffset
Definition: ir_Carrier.h:65
+
const uint8_t kCarrierAc64OffTimerEnableOffset
Definition: ir_Carrier.h:56
+
const uint8_t kCarrierAc64TimerSize
Definition: ir_Carrier.h:62
+
const uint8_t kCarrierAc64ChecksumSize
Definition: ir_Carrier.h:34
+
const uint8_t kCarrierAc64ModeOffset
Definition: ir_Carrier.h:35
+
const uint8_t kCarrierAc64PowerOffset
Definition: ir_Carrier.h:55
+
const uint8_t kCarrierAc64ModeSize
Definition: ir_Carrier.h:37
+
const uint8_t kCarrierAc64TempOffset
Definition: ir_Carrier.h:48
+
const uint8_t kCarrierAc64TempSize
Definition: ir_Carrier.h:50
+
const uint8_t kCarrierAc64ChecksumOffset
Definition: ir_Carrier.h:33
+
const uint8_t kCarrierAc64FanOffset
Definition: ir_Carrier.h:41
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h_source.html new file mode 100644 index 000000000..aa44f135b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h_source.html @@ -0,0 +1,275 @@ + + + + + + + +IRremoteESP8266: src/ir_Carrier.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Carrier.h
+
+
+Go to the documentation of this file.
1 // Copyright 2020 David Conran
+
6 
+
7 // Supports:
+
8 // Brand: Carrier/Surrey, Model: 42QG5A55970 remote
+
9 // Brand: Carrier/Surrey, Model: 619EGX0090E0 A/C
+
10 // Brand: Carrier/Surrey, Model: 619EGX0120E0 A/C
+
11 // Brand: Carrier/Surrey, Model: 619EGX0180E0 A/C
+
12 // Brand: Carrier/Surrey, Model: 619EGX0220E0 A/C
+
13 // Brand: Carrier/Surrey, Model: 53NGK009/012 Inverter
+
14 
+
15 #ifndef IR_CARRIER_H_
+
16 #define IR_CARRIER_H_
+
17 
+
18 #define __STDC_LIMIT_MACROS
+
19 #include <stdint.h>
+
20 #ifndef UNIT_TEST
+
21 #include <Arduino.h>
+
22 #endif
+
23 #include "IRremoteESP8266.h"
+
24 #include "IRsend.h"
+
25 #ifdef UNIT_TEST
+
26 #include "IRsend_test.h"
+
27 #endif
+
28 
+
29 
+
30 // Constants
+
31 
+
32 // CARRIER_AC64
+
33 const uint8_t kCarrierAc64ChecksumOffset = 16;
+
34 const uint8_t kCarrierAc64ChecksumSize = 4;
+ + +
37 const uint8_t kCarrierAc64ModeSize = 2;
+
38 const uint8_t kCarrierAc64Heat = 0b01; // 1
+
39 const uint8_t kCarrierAc64Cool = 0b10; // 2
+
40 const uint8_t kCarrierAc64Fan = 0b11; // 3
+ + +
43 const uint8_t kCarrierAc64FanSize = 2;
+
44 const uint8_t kCarrierAc64FanAuto = 0b00; // 0
+
45 const uint8_t kCarrierAc64FanLow = 0b01; // 1
+
46 const uint8_t kCarrierAc64FanMedium = 0b10; // 2
+
47 const uint8_t kCarrierAc64FanHigh = 0b11; // 3
+ +
49  kCarrierAc64FanSize; // 24
+
50 const uint8_t kCarrierAc64TempSize = 4;
+
51 const uint8_t kCarrierAc64MinTemp = 16; // Celsius
+
52 const uint8_t kCarrierAc64MaxTemp = 30; // Celsius
+ +
54  kCarrierAc64TempSize + 1; // 29
+
55 const uint8_t kCarrierAc64PowerOffset = kCarrierAc64SwingVOffset + 6 + 1; // 36
+ +
57  kCarrierAc64PowerOffset + 1; // 37
+ + +
60 const uint8_t kCarrierAc64SleepOffset =
+ +
62 const uint8_t kCarrierAc64TimerSize = 4;
+
63 const uint8_t kCarrierAc64TimerMax = 9; // Hours.
+
64 const uint8_t kCarrierAc64TimerMin = 1; // Hours.
+ +
66  kCarrierAc64SleepOffset + 12 + 1; // 52
+ +
68  kCarrierAc64TimerSize + 4; // 60
+
69 
+
70 
+
71 // Classes
+
72 
+ +
75  public:
+
76  explicit IRCarrierAc64(const uint16_t pin, const bool inverted = false,
+
77  const bool use_modulation = true);
+
78 
+
79  void stateReset();
+
80 #if SEND_CARRIER_AC64
+
81  void send(const uint16_t repeat = kCarrierAc64MinRepeat);
+
86  int8_t calibrate(void) { return _irsend.calibrate(); }
+
87 #endif // SEND_CARRIER_AC64
+
88  void begin();
+
89  static uint8_t calcChecksum(const uint64_t state);
+
90  static bool validChecksum(const uint64_t state);
+
91  void setPower(const bool on);
+
92  bool getPower();
+
93  void on();
+
94  void off();
+
95  void setTemp(const uint8_t temp);
+
96  uint8_t getTemp();
+
97  void setSwingV(const bool on);
+
98  bool getSwingV(void);
+
99  void setSleep(const bool on);
+
100  bool getSleep(void);
+
101  void setFan(const uint8_t speed);
+
102  uint8_t getFan();
+
103  void setMode(const uint8_t mode);
+
104  uint8_t getMode();
+
105  void setOnTimer(const uint16_t nr_of_mins);
+
106  uint16_t getOnTimer(void);
+
107  void setOffTimer(const uint16_t nr_of_mins);
+
108  uint16_t getOffTimer(void);
+
109  uint64_t getRaw();
+
110  void setRaw(const uint64_t state);
+
111  uint8_t convertMode(const stdAc::opmode_t mode);
+
112  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
113  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
114  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
115  stdAc::state_t toCommon(void);
+
116  String toString();
+
117 #ifndef UNIT_TEST
+
118 
+
119  private:
+ +
121 #else
+
122  IRsendTest _irsend;
+
124 #endif
+
126  uint64_t remote_state;
+
127  void checksum(void);
+
128  void _cancelOnTimer(void);
+
129  void _cancelOffTimer(void);
+
130 };
+
131 #endif // IR_CARRIER_H_
+
+
const uint8_t kCarrierAc64MinTemp
Definition: ir_Carrier.h:51
+
const uint8_t kCarrierAc64TimerMin
Definition: ir_Carrier.h:64
+
void off()
Change the power setting to Off.
Definition: ir_Carrier.cpp:318
+
uint16_t getOffTimer(void)
Get the current Off Timer time.
Definition: ir_Carrier.cpp:474
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Carrier.cpp:304
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Carrier.cpp:259
+
bool getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Carrier.cpp:412
+
IRCarrierAc64(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Carrier.cpp:228
+
void on()
Change the power setting to On.
Definition: ir_Carrier.cpp:315
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kCarrierAc64SleepOffset
Definition: ir_Carrier.h:60
+
stdAc::state_t toCommon(void)
Convert the A/C state to it's common stdAc::state_t equivalent.
Definition: ir_Carrier.cpp:523
+
uint64_t remote_state
The state of the IR remote.
Definition: ir_Carrier.h:126
+
const uint8_t kCarrierAc64Heat
Definition: ir_Carrier.h:38
+ +
const uint8_t kCarrierAc64FanSize
Definition: ir_Carrier.h:43
+
uint64_t getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Carrier.cpp:277
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void _cancelOnTimer(void)
Clear the On Timer enable bit.
Definition: ir_Carrier.cpp:436
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Carrier.cpp:265
+
const uint8_t kCarrierAc64Cool
Definition: ir_Carrier.h:39
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode to it's common stdAc::opmode_t equivalent.
Definition: ir_Carrier.cpp:355
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Carrier.cpp:322
+
uint8_t getFan()
Get the current fan speed setting.
Definition: ir_Carrier.cpp:365
+
const uint8_t kCarrierAc64OffTimerOffset
Definition: ir_Carrier.h:67
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kCarrierAc64OnTimerEnableOffset
Definition: ir_Carrier.h:58
+
void setTemp(const uint8_t temp)
Set the temp in deg C.
Definition: ir_Carrier.cpp:288
+
const uint8_t kCarrierAc64OnTimerOffset
Definition: ir_Carrier.h:65
+
uint16_t getOnTimer(void)
Get the current On Timer time.
Definition: ir_Carrier.cpp:443
+
void send(const uint16_t repeat=kCarrierAc64MinRepeat)
Send the current internal state as an IR message.
Definition: ir_Carrier.cpp:270
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Carrier.cpp:381
+
void setOffTimer(const uint16_t nr_of_mins)
Set the Off Timer time.
Definition: ir_Carrier.cpp:486
+
const uint8_t kCarrierAc64TimerMax
Definition: ir_Carrier.h:63
+
const uint8_t kCarrierAc64FanHigh
Definition: ir_Carrier.h:47
+ +
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Carrier.cpp:252
+
bool getPower()
Get the value of the current power setting.
Definition: ir_Carrier.cpp:310
+
const uint8_t kCarrierAc64FanMedium
Definition: ir_Carrier.h:46
+
const uint8_t kCarrierAc64MaxTemp
Definition: ir_Carrier.h:52
+
Class for handling detailed Carrier 64 bit A/C messages.
Definition: ir_Carrier.h:74
+
uint8_t getTemp()
Get the current temperature from the internal state.
Definition: ir_Carrier.cpp:297
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Carrier.h:120
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Carrier.cpp:234
+
const uint8_t kCarrierAc64OffTimerEnableOffset
Definition: ir_Carrier.h:56
+
const uint8_t kCarrierAc64SwingVOffset
Definition: ir_Carrier.h:53
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Carrier.cpp:239
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Carrier.h:86
+
void setRaw(const uint64_t state)
Set the internal state from a valid code for this protocol.
Definition: ir_Carrier.cpp:284
+
const uint8_t kCarrierAc64TimerSize
Definition: ir_Carrier.h:62
+
const uint8_t kCarrierAc64Fan
Definition: ir_Carrier.h:40
+
const uint8_t kCarrierAc64ChecksumSize
Definition: ir_Carrier.h:34
+
const uint8_t kCarrierAc64ModeOffset
Definition: ir_Carrier.h:35
+
bool getSleep(void)
Get the Sleep mode of the A/C.
Definition: ir_Carrier.cpp:431
+
void setOnTimer(const uint16_t nr_of_mins)
Set the On Timer time.
Definition: ir_Carrier.cpp:455
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a standard A/C mode into its native mode.
Definition: ir_Carrier.cpp:344
+
const uint16_t kCarrierAc64MinRepeat
Definition: IRremoteESP8266.h:831
+
const uint8_t kCarrierAc64FanLow
Definition: ir_Carrier.h:45
+
const uint8_t kCarrierAc64FanAuto
Definition: ir_Carrier.h:44
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Carrier.cpp:395
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Carrier.cpp:371
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Carrier.cpp:328
+
void setSwingV(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Carrier.cpp:406
+
void setSleep(const bool on)
Set the Sleep mode of the A/C.
Definition: ir_Carrier.cpp:418
+
void _cancelOffTimer(void)
Clear the Off Timer enable bit.
Definition: ir_Carrier.cpp:467
+
String toString()
Convert the internal state into a human readable string.
Definition: ir_Carrier.cpp:500
+
const uint8_t kCarrierAc64PowerOffset
Definition: ir_Carrier.h:55
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kCarrierAc64ModeSize
Definition: ir_Carrier.h:37
+
const uint8_t kCarrierAc64TempOffset
Definition: ir_Carrier.h:48
+
const uint8_t kCarrierAc64TempSize
Definition: ir_Carrier.h:50
+
const uint8_t kCarrierAc64ChecksumOffset
Definition: ir_Carrier.h:33
+
const uint8_t kCarrierAc64FanOffset
Definition: ir_Carrier.h:41
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8cpp.html new file mode 100644 index 000000000..d09e7f0cf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8cpp.html @@ -0,0 +1,301 @@ + + + + + + + +IRremoteESP8266: src/ir_Coolix.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Coolix.cpp File Reference
+
+
+ +

Coolix A/C / heatpump. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kCoolixTick = 276
 
const uint16_t kCoolixBitMarkTicks = 2
 
const uint16_t kCoolixBitMark = kCoolixBitMarkTicks * kCoolixTick
 
const uint16_t kCoolixOneSpaceTicks = 6
 
const uint16_t kCoolixOneSpace = kCoolixOneSpaceTicks * kCoolixTick
 
const uint16_t kCoolixZeroSpaceTicks = 2
 
const uint16_t kCoolixZeroSpace = kCoolixZeroSpaceTicks * kCoolixTick
 
const uint16_t kCoolixHdrMarkTicks = 17
 
const uint16_t kCoolixHdrMark = kCoolixHdrMarkTicks * kCoolixTick
 
const uint16_t kCoolixHdrSpaceTicks = 16
 
const uint16_t kCoolixHdrSpace = kCoolixHdrSpaceTicks * kCoolixTick
 
const uint16_t kCoolixMinGapTicks = kCoolixHdrMarkTicks + kCoolixZeroSpaceTicks
 
const uint16_t kCoolixMinGap = kCoolixMinGapTicks * kCoolixTick
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kCoolixBitMark

+ +
+
+ + + + +
const uint16_t kCoolixBitMark = kCoolixBitMarkTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixBitMarkTicks

+ +
+
+ + + + +
const uint16_t kCoolixBitMarkTicks = 2
+
+ +
+
+ +

◆ kCoolixHdrMark

+ +
+
+ + + + +
const uint16_t kCoolixHdrMark = kCoolixHdrMarkTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kCoolixHdrMarkTicks = 17
+
+ +
+
+ +

◆ kCoolixHdrSpace

+ +
+
+ + + + +
const uint16_t kCoolixHdrSpace = kCoolixHdrSpaceTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kCoolixHdrSpaceTicks = 16
+
+ +
+
+ +

◆ kCoolixMinGap

+ +
+
+ + + + +
const uint16_t kCoolixMinGap = kCoolixMinGapTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixMinGapTicks

+ +
+
+ + + + +
const uint16_t kCoolixMinGapTicks = kCoolixHdrMarkTicks + kCoolixZeroSpaceTicks
+
+ +
+
+ +

◆ kCoolixOneSpace

+ +
+
+ + + + +
const uint16_t kCoolixOneSpace = kCoolixOneSpaceTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kCoolixOneSpaceTicks = 6
+
+ +
+
+ +

◆ kCoolixTick

+ +
+
+ + + + +
const uint16_t kCoolixTick = 276
+
+ +
+
+ +

◆ kCoolixZeroSpace

+ +
+
+ + + + +
const uint16_t kCoolixZeroSpace = kCoolixZeroSpaceTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kCoolixZeroSpaceTicks = 2
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h.html new file mode 100644 index 000000000..47a8b96fa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h.html @@ -0,0 +1,768 @@ + + + + + + + +IRremoteESP8266: src/ir_Coolix.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Coolix.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRCoolixAC
 Class for handling detailed Coolix A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kCoolixCool = 0b000
 
const uint8_t kCoolixDry = 0b001
 
const uint8_t kCoolixAuto = 0b010
 
const uint8_t kCoolixHeat = 0b011
 
const uint8_t kCoolixFan = 0b100
 
const uint8_t kCoolixModeOffset = 2
 
const uint8_t kCoolixModeSize = 2
 
const uint8_t kCoolixZoneFollowMaskOffset = 19
 
const uint8_t kCoolixFanOffset = 13
 
const uint8_t kCoolixFanSize = 3
 
const uint8_t kCoolixFanMin = 0b100
 
const uint8_t kCoolixFanMed = 0b010
 
const uint8_t kCoolixFanMax = 0b001
 
const uint8_t kCoolixFanAuto = 0b101
 
const uint8_t kCoolixFanAuto0 = 0b000
 
const uint8_t kCoolixFanZoneFollow = 0b110
 
const uint8_t kCoolixFanFixed = 0b111
 
const uint8_t kCoolixTempMin = 17
 
const uint8_t kCoolixTempMax = 30
 
const uint8_t kCoolixTempRange = kCoolixTempMax - kCoolixTempMin + 1
 
const uint8_t kCoolixFanTempCode = 0b1110
 
const uint8_t kCoolixTempOffset = 4
 
const uint8_t kCoolixTempSize = 4
 
const uint8_t kCoolixTempMap [kCoolixTempRange]
 
const uint8_t kCoolixSensorTempMin = 16
 
const uint8_t kCoolixSensorTempMax = 30
 
const uint8_t kCoolixSensorTempIgnoreCode = 0b1111
 
const uint8_t kCoolixSensorTempOffset = 8
 
const uint8_t kCoolixSensorTempSize = 4
 
const uint8_t kCoolixPrefix = 0b1011
 
const uint8_t kCoolixUnknown = 0xFF
 
const uint32_t kCoolixOff = 0b101100100111101111100000
 
const uint32_t kCoolixSwing = 0b101100100110101111100000
 
const uint32_t kCoolixSwingH = 0b101100101111010110100010
 
const uint32_t kCoolixSwingV = 0b101100100000111111100000
 
const uint32_t kCoolixSleep = 0b101100101110000000000011
 
const uint32_t kCoolixTurbo = 0b101101011111010110100010
 
const uint32_t kCoolixLed = 0b101101011111010110100101
 
const uint32_t kCoolixClean = 0b101101011111010110101010
 
const uint32_t kCoolixCmdFan = 0b101100101011111111100100
 
const uint32_t kCoolixDefaultState = 0b101100100001111111001000
 
+

Variable Documentation

+ +

◆ kCoolixAuto

+ +
+
+ + + + +
const uint8_t kCoolixAuto = 0b010
+
+ +
+
+ +

◆ kCoolixClean

+ +
+
+ + + + +
const uint32_t kCoolixClean = 0b101101011111010110101010
+
+ +
+
+ +

◆ kCoolixCmdFan

+ +
+
+ + + + +
const uint32_t kCoolixCmdFan = 0b101100101011111111100100
+
+ +
+
+ +

◆ kCoolixCool

+ +
+
+ + + + +
const uint8_t kCoolixCool = 0b000
+
+ +
+
+ +

◆ kCoolixDefaultState

+ +
+
+ + + + +
const uint32_t kCoolixDefaultState = 0b101100100001111111001000
+
+ +
+
+ +

◆ kCoolixDry

+ +
+
+ + + + +
const uint8_t kCoolixDry = 0b001
+
+ +
+
+ +

◆ kCoolixFan

+ +
+
+ + + + +
const uint8_t kCoolixFan = 0b100
+
+ +
+
+ +

◆ kCoolixFanAuto

+ +
+
+ + + + +
const uint8_t kCoolixFanAuto = 0b101
+
+ +
+
+ +

◆ kCoolixFanAuto0

+ +
+
+ + + + +
const uint8_t kCoolixFanAuto0 = 0b000
+
+ +
+
+ +

◆ kCoolixFanFixed

+ +
+
+ + + + +
const uint8_t kCoolixFanFixed = 0b111
+
+ +
+
+ +

◆ kCoolixFanMax

+ +
+
+ + + + +
const uint8_t kCoolixFanMax = 0b001
+
+ +
+
+ +

◆ kCoolixFanMed

+ +
+
+ + + + +
const uint8_t kCoolixFanMed = 0b010
+
+ +
+
+ +

◆ kCoolixFanMin

+ +
+
+ + + + +
const uint8_t kCoolixFanMin = 0b100
+
+ +
+
+ +

◆ kCoolixFanOffset

+ +
+
+ + + + +
const uint8_t kCoolixFanOffset = 13
+
+ +
+
+ +

◆ kCoolixFanSize

+ +
+
+ + + + +
const uint8_t kCoolixFanSize = 3
+
+ +
+
+ +

◆ kCoolixFanTempCode

+ +
+
+ + + + +
const uint8_t kCoolixFanTempCode = 0b1110
+
+ +
+
+ +

◆ kCoolixFanZoneFollow

+ +
+
+ + + + +
const uint8_t kCoolixFanZoneFollow = 0b110
+
+ +
+
+ +

◆ kCoolixHeat

+ +
+
+ + + + +
const uint8_t kCoolixHeat = 0b011
+
+ +
+
+ +

◆ kCoolixLed

+ +
+
+ + + + +
const uint32_t kCoolixLed = 0b101101011111010110100101
+
+ +
+
+ +

◆ kCoolixModeOffset

+ +
+
+ + + + +
const uint8_t kCoolixModeOffset = 2
+
+ +
+
+ +

◆ kCoolixModeSize

+ +
+
+ + + + +
const uint8_t kCoolixModeSize = 2
+
+ +
+
+ +

◆ kCoolixOff

+ +
+
+ + + + +
const uint32_t kCoolixOff = 0b101100100111101111100000
+
+ +
+
+ +

◆ kCoolixPrefix

+ +
+
+ + + + +
const uint8_t kCoolixPrefix = 0b1011
+
+ +
+
+ +

◆ kCoolixSensorTempIgnoreCode

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempIgnoreCode = 0b1111
+
+ +
+
+ +

◆ kCoolixSensorTempMax

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempMax = 30
+
+ +
+
+ +

◆ kCoolixSensorTempMin

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempMin = 16
+
+ +
+
+ +

◆ kCoolixSensorTempOffset

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempOffset = 8
+
+ +
+
+ +

◆ kCoolixSensorTempSize

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempSize = 4
+
+ +
+
+ +

◆ kCoolixSleep

+ +
+
+ + + + +
const uint32_t kCoolixSleep = 0b101100101110000000000011
+
+ +
+
+ +

◆ kCoolixSwing

+ +
+
+ + + + +
const uint32_t kCoolixSwing = 0b101100100110101111100000
+
+ +
+
+ +

◆ kCoolixSwingH

+ +
+
+ + + + +
const uint32_t kCoolixSwingH = 0b101100101111010110100010
+
+ +
+
+ +

◆ kCoolixSwingV

+ +
+
+ + + + +
const uint32_t kCoolixSwingV = 0b101100100000111111100000
+
+ +
+
+ +

◆ kCoolixTempMap

+ +
+
+ + + + +
const uint8_t kCoolixTempMap[kCoolixTempRange]
+
+Initial value:
= {
+
0b0000,
+
0b0001,
+
0b0011,
+
0b0010,
+
0b0110,
+
0b0111,
+
0b0101,
+
0b0100,
+
0b1100,
+
0b1101,
+
0b1001,
+
0b1000,
+
0b1010,
+
0b1011
+
}
+
+
+
+ +

◆ kCoolixTempMax

+ +
+
+ + + + +
const uint8_t kCoolixTempMax = 30
+
+ +
+
+ +

◆ kCoolixTempMin

+ +
+
+ + + + +
const uint8_t kCoolixTempMin = 17
+
+ +
+
+ +

◆ kCoolixTempOffset

+ +
+
+ + + + +
const uint8_t kCoolixTempOffset = 4
+
+ +
+
+ +

◆ kCoolixTempRange

+ +
+
+ + + + +
const uint8_t kCoolixTempRange = kCoolixTempMax - kCoolixTempMin + 1
+
+ +
+
+ +

◆ kCoolixTempSize

+ +
+
+ + + + +
const uint8_t kCoolixTempSize = 4
+
+ +
+
+ +

◆ kCoolixTurbo

+ +
+
+ + + + +
const uint32_t kCoolixTurbo = 0b101101011111010110100010
+
+ +
+
+ +

◆ kCoolixUnknown

+ +
+
+ + + + +
const uint8_t kCoolixUnknown = 0xFF
+
+ +
+
+ +

◆ kCoolixZoneFollowMaskOffset

+ +
+
+ + + + +
const uint8_t kCoolixZoneFollowMaskOffset = 19
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h_source.html new file mode 100644 index 000000000..570f91033 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h_source.html @@ -0,0 +1,365 @@ + + + + + + + +IRremoteESP8266: src/ir_Coolix.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Coolix.h
+
+
+Go to the documentation of this file.
1 // Coolix A/C
+
2 //
+
3 // Copyright 2018 David Conran
+
4 
+
5 // Supports:
+
6 // Brand: Beko, Model: RG57K7(B)/BGEF Remote
+
7 // Brand: Beko, Model: BINR 070/071 split-type A/C
+
8 // Brand: Midea, Model: RG52D/BGE Remote
+
9 // Brand: Midea, Model: MS12FU-10HRDN1-QRD0GW(B) A/C
+
10 // Brand: Midea, Model: MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
+
11 // Brand: Tokio, Model: AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote
+
12 // Brand: Airwell, Model: RC08B remote
+
13 
+
14 #ifndef IR_COOLIX_H_
+
15 #define IR_COOLIX_H_
+
16 
+
17 #define __STDC_LIMIT_MACROS
+
18 #include <stdint.h>
+
19 #ifndef UNIT_TEST
+
20 #include <Arduino.h>
+
21 #endif
+
22 #include "IRremoteESP8266.h"
+
23 #include "IRsend.h"
+
24 #ifdef UNIT_TEST
+
25 #include "IRsend_test.h"
+
26 #endif
+
27 
+
28 // Ref:
+
29 // https://github.com/crankyoldgit/IRremoteESP8266/issues/484
+
30 // Kudos:
+
31 // Hamper: For the breakdown and mapping of the bit values.
+
32 
+
33 // Constants
+
34 // Modes
+
35 const uint8_t kCoolixCool = 0b000;
+
36 const uint8_t kCoolixDry = 0b001;
+
37 const uint8_t kCoolixAuto = 0b010;
+
38 const uint8_t kCoolixHeat = 0b011;
+
39 const uint8_t kCoolixFan = 0b100; // Synthetic.
+
40 // const uint32_t kCoolixModeMask = 0b000000000000000000001100; // 0xC
+
41 const uint8_t kCoolixModeOffset = 2;
+
42 const uint8_t kCoolixModeSize = 2;
+
43 // const uint32_t kCoolixZoneFollowMask = 0b000010000000000000000000 0x80000
+
44 const uint8_t kCoolixZoneFollowMaskOffset = 19;
+
45 // Fan Control
+
46 // const uint32_t kCoolixFanMask = 0b000000001110000000000000; // 0x00E000
+
47 const uint8_t kCoolixFanOffset = 13;
+
48 const uint8_t kCoolixFanSize = 3;
+
49 const uint8_t kCoolixFanMin = 0b100;
+
50 const uint8_t kCoolixFanMed = 0b010;
+
51 const uint8_t kCoolixFanMax = 0b001;
+
52 const uint8_t kCoolixFanAuto = 0b101;
+
53 const uint8_t kCoolixFanAuto0 = 0b000;
+
54 const uint8_t kCoolixFanZoneFollow = 0b110;
+
55 const uint8_t kCoolixFanFixed = 0b111;
+
56 // Temperature
+
57 const uint8_t kCoolixTempMin = 17; // Celsius
+
58 const uint8_t kCoolixTempMax = 30; // Celsius
+ +
60 const uint8_t kCoolixFanTempCode = 0b1110; // Part of Fan Mode.
+
61 // const uint32_t kCoolixTempMask = 0b11110000;
+
62 const uint8_t kCoolixTempOffset = 4;
+
63 const uint8_t kCoolixTempSize = 4;
+
64 const uint8_t kCoolixTempMap[kCoolixTempRange] = {
+
65  0b0000, // 17C
+
66  0b0001, // 18c
+
67  0b0011, // 19C
+
68  0b0010, // 20C
+
69  0b0110, // 21C
+
70  0b0111, // 22C
+
71  0b0101, // 23C
+
72  0b0100, // 24C
+
73  0b1100, // 25C
+
74  0b1101, // 26C
+
75  0b1001, // 27C
+
76  0b1000, // 28C
+
77  0b1010, // 29C
+
78  0b1011 // 30C
+
79 };
+
80 const uint8_t kCoolixSensorTempMin = 16; // Celsius
+
81 const uint8_t kCoolixSensorTempMax = 30; // Celsius
+
82 const uint8_t kCoolixSensorTempIgnoreCode = 0b1111;
+
83 // kCoolixSensorTempMask = 0b000000000000111100000000; // 0xF00
+
84 const uint8_t kCoolixSensorTempOffset = 8;
+
85 const uint8_t kCoolixSensorTempSize = 4;
+
86 // Fixed states/messages.
+
87 const uint8_t kCoolixPrefix = 0b1011; // 0xB
+
88 const uint8_t kCoolixUnknown = 0xFF;
+
89 const uint32_t kCoolixOff = 0b101100100111101111100000; // 0xB27BE0
+
90 const uint32_t kCoolixSwing = 0b101100100110101111100000; // 0xB26BE0
+
91 const uint32_t kCoolixSwingH = 0b101100101111010110100010; // 0xB5F5A2
+
92 const uint32_t kCoolixSwingV = 0b101100100000111111100000; // 0xB20FE0
+
93 const uint32_t kCoolixSleep = 0b101100101110000000000011; // 0xB2E003
+
94 const uint32_t kCoolixTurbo = 0b101101011111010110100010; // 0xB5F5A2
+
95 const uint32_t kCoolixLed = 0b101101011111010110100101; // 0xB5F5A5
+
96 const uint32_t kCoolixClean = 0b101101011111010110101010; // 0xB5F5AA
+
97 const uint32_t kCoolixCmdFan = 0b101100101011111111100100; // 0xB2BFE4
+
98 // On, 25C, Mode: Auto, Fan: Auto, Zone Follow: Off, Sensor Temp: Ignore.
+
99 const uint32_t kCoolixDefaultState = 0b101100100001111111001000; // 0xB21FC8
+
100 
+
101 // Classes
+
102 
+
105 class IRCoolixAC {
+
106  public:
+
107  explicit IRCoolixAC(const uint16_t pin, const bool inverted = false,
+
108  const bool use_modulation = true);
+
109  void stateReset();
+
110 #if SEND_COOLIX
+
111  void send(const uint16_t repeat = kCoolixDefaultRepeat);
+
116  int8_t calibrate(void) { return _irsend.calibrate(); }
+
117 #endif // SEND_COOLIX
+
118  void begin();
+
119  void on();
+
120  void off();
+
121  void setPower(const bool state);
+
122  bool getPower();
+
123  void setTemp(const uint8_t temp);
+
124  uint8_t getTemp();
+
125  void setSensorTemp(const uint8_t desired);
+
126  uint8_t getSensorTemp();
+
127  void clearSensorTemp();
+
128  void setFan(const uint8_t speed, const bool modecheck = true);
+
129  uint8_t getFan();
+
130  void setMode(const uint8_t mode);
+
131  uint8_t getMode();
+
132  void setSwing();
+
133  bool getSwing();
+
134  void setSleep();
+
135  bool getSleep();
+
136  void setTurbo();
+
137  bool getTurbo();
+
138  void setLed();
+
139  bool getLed();
+
140  void setClean();
+
141  bool getClean();
+
142  bool getZoneFollow();
+
143  uint32_t getRaw();
+
144  void setRaw(const uint32_t new_code);
+
145  uint8_t convertMode(const stdAc::opmode_t mode);
+
146  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
147  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
148  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
149  stdAc::state_t toCommon(const stdAc::state_t *prev = NULL);
+
150  String toString();
+
151 #ifndef UNIT_TEST
+
152 
+
153  private:
+ +
155 #else
+
156  IRsendTest _irsend;
+
158 #endif
+
160  // internal state
+
161  bool powerFlag;
+
162  bool turboFlag;
+
163  bool ledFlag;
+
164  bool cleanFlag;
+
165  bool sleepFlag;
+ +
167  bool swingFlag;
+ + +
170 
+
171  uint32_t remote_state;
+
172  uint32_t saved_state;
+
173  void setTempRaw(const uint8_t code);
+
174  uint8_t getTempRaw();
+
175  void setSensorTempRaw(const uint8_t code);
+
176  void setZoneFollow(const bool on);
+
177  bool isSpecialState(void);
+
178  bool handleSpecialState(const uint32_t data);
+
179  void updateSavedState(void);
+
180  void recoverSavedState(void);
+
181  uint32_t getNormalState(void);
+
182 };
+
183 
+
184 #endif // IR_COOLIX_H_
+
+
void setLed()
Toggle the Led (light) mode of the A/C.
Definition: ir_Coolix.cpp:325
+
const uint8_t kCoolixFanSize
Definition: ir_Coolix.h:48
+
const uint8_t kCoolixZoneFollowMaskOffset
Definition: ir_Coolix.h:44
+
bool zoneFollowFlag
Definition: ir_Coolix.h:166
+
const uint8_t kCoolixFanZoneFollow
Definition: ir_Coolix.h:54
+
uint32_t getNormalState(void)
+
void setTempRaw(const uint8_t code)
Set the raw (native) temperature value.
Definition: ir_Coolix.cpp:206
+
void setSensorTempRaw(const uint8_t code)
Set the raw (native) sensor temperature value.
Definition: ir_Coolix.cpp:237
+
bool getTurbo()
Get the Turbo setting of the A/C.
Definition: ir_Coolix.cpp:310
+
const uint8_t kCoolixFanMin
Definition: ir_Coolix.h:49
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Coolix.h:116
+
void setZoneFollow(const bool on)
Change the Zone Follow setting.
Definition: ir_Coolix.cpp:352
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Coolix.cpp:365
+
const uint32_t kCoolixSwingH
Definition: ir_Coolix.h:91
+
uint32_t remote_state
The state of the IR remote in IR code form.
Definition: ir_Coolix.h:171
+
void send(const uint16_t repeat=kCoolixDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Coolix.cpp:112
+
bool getZoneFollow()
Get the Zone Follow setting of the A/C.
Definition: ir_Coolix.cpp:345
+
const uint8_t kCoolixFanAuto0
Definition: ir_Coolix.h:53
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kCoolixDry
Definition: ir_Coolix.h:36
+
void setClean()
Toggle the Clean mode of the A/C.
Definition: ir_Coolix.cpp:337
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Coolix.cpp:227
+
const uint8_t kCoolixFanMed
Definition: ir_Coolix.h:50
+
bool getSwing()
Get the Swing setting of the A/C.
Definition: ir_Coolix.cpp:287
+
const uint8_t kCoolixTempSize
Definition: ir_Coolix.h:63
+
uint8_t getSensorTemp()
Get the sensor temperature setting.
Definition: ir_Coolix.cpp:253
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Coolix.h:154
+
bool turboFlag
Definition: ir_Coolix.h:162
+
const uint8_t kCoolixSensorTempMin
Definition: ir_Coolix.h:80
+ +
bool ledFlag
Definition: ir_Coolix.h:163
+
const uint32_t kCoolixSwing
Definition: ir_Coolix.h:90
+
const uint8_t kCoolixCool
Definition: ir_Coolix.h:35
+
const uint8_t kCoolixAuto
Definition: ir_Coolix.h:37
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
bool cleanFlag
Definition: ir_Coolix.h:164
+
uint32_t getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Coolix.cpp:122
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Coolix.cpp:488
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
void updateSavedState(void)
Backup the current internal state as long as it isn't a special state.
Definition: ir_Coolix.cpp:189
+
const uint8_t kCoolixHeat
Definition: ir_Coolix.h:38
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a standard A/C mode into its native mode.
Definition: ir_Coolix.cpp:448
+
const uint32_t kCoolixOff
Definition: ir_Coolix.h:89
+
stdAc::state_t toCommon(const stdAc::state_t *prev=NULL)
Convert the A/C state to it's common stdAc::state_t equivalent.
Definition: ir_Coolix.cpp:500
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void recoverSavedState(void)
Restore the current internal state from backup as long as it isn't a special state.
Definition: ir_Coolix.cpp:195
+
void setTurbo()
Toggle the Turbo mode of the A/C.
Definition: ir_Coolix.cpp:313
+
const uint8_t kCoolixSensorTempSize
Definition: ir_Coolix.h:85
+
const uint8_t kCoolixFanTempCode
Definition: ir_Coolix.h:60
+
bool swingVFlag
Definition: ir_Coolix.h:169
+
bool getClean()
Get the Clean setting of the A/C.
Definition: ir_Coolix.cpp:334
+
void on()
Change the power setting to On.
Definition: ir_Coolix.cpp:280
+ +
const uint8_t kCoolixTempMap[kCoolixTempRange]
Definition: ir_Coolix.h:64
+
void clearSensorTemp()
Clear the Sensor Temperature setting..
Definition: ir_Coolix.cpp:358
+
const uint32_t kCoolixClean
Definition: ir_Coolix.h:96
+
const uint8_t kCoolixFanFixed
Definition: ir_Coolix.h:55
+
const uint8_t kCoolixModeSize
Definition: ir_Coolix.h:42
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Coolix.cpp:93
+
const uint32_t kCoolixDefaultState
Definition: ir_Coolix.h:99
+
const uint16_t kCoolixDefaultRepeat
Definition: IRremoteESP8266.h:825
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Coolix.cpp:461
+
void setSleep()
Toggle the Sleep mode of the A/C.
Definition: ir_Coolix.cpp:302
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode to it's common stdAc::opmode_t equivalent.
Definition: ir_Coolix.cpp:475
+
uint32_t saved_state
Copy of the state if we required a special mode.
Definition: ir_Coolix.h:172
+
bool isSpecialState(void)
Is the current state is a special state?
Definition: ir_Coolix.cpp:142
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Coolix.cpp:218
+
const uint8_t kCoolixTempOffset
Definition: ir_Coolix.h:62
+
Class for handling detailed Coolix A/C messages.
Definition: ir_Coolix.h:105
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Coolix.cpp:393
+
uint8_t getFan()
Get the current fan speed setting.
Definition: ir_Coolix.cpp:403
+
const uint32_t kCoolixLed
Definition: ir_Coolix.h:95
+
const uint8_t kCoolixUnknown
Definition: ir_Coolix.h:88
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Coolix.cpp:107
+
void setRaw(const uint32_t new_code)
Set the internal state from a valid code for this protocol.
Definition: ir_Coolix.cpp:126
+
uint8_t getTempRaw()
Get the raw (native) temperature value.
Definition: ir_Coolix.cpp:212
+
const uint8_t kCoolixFanOffset
Definition: ir_Coolix.h:47
+
const uint32_t kCoolixCmdFan
Definition: ir_Coolix.h:97
+
const uint8_t kCoolixTempMax
Definition: ir_Coolix.h:58
+
bool swingFlag
Definition: ir_Coolix.h:167
+
const uint8_t kCoolixFan
Definition: ir_Coolix.h:39
+
const uint32_t kCoolixSwingV
Definition: ir_Coolix.h:92
+
bool swingHFlag
Definition: ir_Coolix.h:168
+
void off()
Change the power setting to Off.
Definition: ir_Coolix.cpp:283
+
bool sleepFlag
Definition: ir_Coolix.h:165
+
const uint32_t kCoolixSleep
Definition: ir_Coolix.h:93
+
void setSensorTemp(const uint8_t desired)
Set the sensor temperature.
Definition: ir_Coolix.cpp:243
+
IRCoolixAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Coolix.cpp:88
+
const uint8_t kCoolixPrefix
Definition: ir_Coolix.h:87
+
const uint8_t kCoolixTempRange
Definition: ir_Coolix.h:59
+
const uint8_t kCoolixTempMin
Definition: ir_Coolix.h:57
+
const uint8_t kCoolixSensorTempMax
Definition: ir_Coolix.h:81
+
const uint8_t kCoolixModeOffset
Definition: ir_Coolix.h:41
+
const uint8_t kCoolixFanMax
Definition: ir_Coolix.h:51
+
const uint8_t kCoolixSensorTempOffset
Definition: ir_Coolix.h:84
+
const uint8_t kCoolixFanAuto
Definition: ir_Coolix.h:52
+
bool powerFlag
Definition: ir_Coolix.h:161
+
String toString()
Convert the internal state into a human readable string.
Definition: ir_Coolix.cpp:559
+
bool getPower()
Get the value of the current power setting.
Definition: ir_Coolix.cpp:260
+
void setFan(const uint8_t speed, const bool modecheck=true)
Set the speed of the fan.
Definition: ir_Coolix.cpp:410
+
bool handleSpecialState(const uint32_t data)
Adjust any internal settings based on the type of special state we are supplied. Does nothing if it i...
Definition: ir_Coolix.cpp:160
+
bool getSleep()
Get the Sleep setting of the A/C.
Definition: ir_Coolix.cpp:299
+
void setPower(const bool state)
Change the power setting.
Definition: ir_Coolix.cpp:267
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setSwing()
Toggle the Swing mode of the A/C.
Definition: ir_Coolix.cpp:290
+
const uint8_t kCoolixSensorTempIgnoreCode
Definition: ir_Coolix.h:82
+
const uint32_t kCoolixTurbo
Definition: ir_Coolix.h:94
+
bool getLed()
Get the Led (light) setting of the A/C.
Definition: ir_Coolix.cpp:322
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8cpp.html new file mode 100644 index 000000000..ba795e56d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8cpp.html @@ -0,0 +1,256 @@ + + + + + + + +IRremoteESP8266: src/ir_Corona.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Corona.cpp File Reference
+
+
+ +

Corona A/C protocol. +More...

+ + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kCoronaAcHdrMark = 3500
 
const uint16_t kCoronaAcHdrSpace = 1680
 
const uint16_t kCoronaAcBitMark = 450
 
const uint16_t kCoronaAcOneSpace = 1270
 
const uint16_t kCoronaAcZeroSpace = 420
 
const uint16_t kCoronaAcSpaceGap = 10800
 
const uint16_t kCoronaAcFreq = 38000
 
const uint16_t kCoronaAcOverheadShort = 3
 
const uint16_t kCoronaAcOverhead = 11
 
const uint8_t kCoronaTolerance = 5
 
+

Detailed Description

+

Corona A/C protocol.

+
Note
Unsupported:
    +
  • Auto/Max button press (special format)
  • +
+
+

Variable Documentation

+ +

◆ kCoronaAcBitMark

+ +
+
+ + + + +
const uint16_t kCoronaAcBitMark = 450
+
+ +
+
+ +

◆ kCoronaAcFreq

+ +
+
+ + + + +
const uint16_t kCoronaAcFreq = 38000
+
+ +
+
+ +

◆ kCoronaAcHdrMark

+ +
+
+ + + + +
const uint16_t kCoronaAcHdrMark = 3500
+
+ +
+
+ +

◆ kCoronaAcHdrSpace

+ +
+
+ + + + +
const uint16_t kCoronaAcHdrSpace = 1680
+
+ +
+
+ +

◆ kCoronaAcOneSpace

+ +
+
+ + + + +
const uint16_t kCoronaAcOneSpace = 1270
+
+ +
+
+ +

◆ kCoronaAcOverhead

+ +
+
+ + + + +
const uint16_t kCoronaAcOverhead = 11
+
+ +
+
+ +

◆ kCoronaAcOverheadShort

+ +
+
+ + + + +
const uint16_t kCoronaAcOverheadShort = 3
+
+ +
+
+ +

◆ kCoronaAcSpaceGap

+ +
+
+ + + + +
const uint16_t kCoronaAcSpaceGap = 10800
+
+ +
+
+ +

◆ kCoronaAcZeroSpace

+ +
+
+ + + + +
const uint16_t kCoronaAcZeroSpace = 420
+
+ +
+
+ +

◆ kCoronaTolerance

+ +
+
+ + + + +
const uint8_t kCoronaTolerance = 5
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h.html new file mode 100644 index 000000000..62a551867 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h.html @@ -0,0 +1,730 @@ + + + + + + + +IRremoteESP8266: src/ir_Corona.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Corona.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRCoronaAc
 Class for handling detailed Corona A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kCoronaAcSectionBytes = 7
 
const uint8_t kCoronaAcSections = 3
 
const uint8_t kCoronaAcSectionHeader0Pos = 0
 
const uint8_t kCoronaAcSectionHeader0 = 0x28
 
const uint8_t kCoronaAcSectionHeader1Pos = 1
 
const uint8_t kCoronaAcSectionHeader1 = 0x61
 
const uint8_t kCoronaAcSectionLabelPos = 2
 
const uint8_t kCoronaAcSectionLabelBase = 0x0D
 
const uint8_t kCoronaAcSectionData0Pos = 3
 
const uint8_t kCoronaAcSectionData0InvPos = 4
 
const uint8_t kCoronaAcSectionData1Pos = 5
 
const uint8_t kCoronaAcSectionData1InvPos = 6
 
const uint8_t kCoronaAcSectionData0Base = 0x10
 
const uint8_t kCoronaAcSettingsSection = 0
 
const uint8_t kCoronaAcFanOffset = 0
 
const uint8_t kCoronaAcFanSize = 2
 
const uint8_t kCoronaAcFanAuto = 0b00
 
const uint8_t kCoronaAcFanLow = 0b01
 
const uint8_t kCoronaAcFanMedium = 0b10
 
const uint8_t kCoronaAcFanHigh = 0b11
 
const uint8_t kCoronaAcPowerSaveOffset = 3
 
const uint8_t kCoronaAcSwingVToggleOffset = 6
 
const uint8_t kCoronaAcTempOffset = 0
 
const uint8_t kCoronaAcTempSize = 4
 
const uint8_t kCoronaAcMinTemp = 17
 
const uint8_t kCoronaAcMaxTemp = 30
 
const uint8_t kCoronaAcPowerOffset
 
const uint8_t kCoronaAcPowerButtonOffset
 
const uint8_t kCoronaAcModeOffset
 
const uint8_t kCoronaAcModeSize = 2
 
const uint8_t kCoronaAcModeHeat = 0b00
 
const uint8_t kCoronaAcModeDry = 0b01
 
const uint8_t kCoronaAcModeCool = 0b10
 
const uint8_t kCoronaAcModeFan = 0b11
 
const uint8_t kCoronaAcOnTimerSection = 1
 
const uint8_t kCoronaAcOffTimerSection = 2
 
const uint16_t kCoronaAcTimerMax = 12 * 60
 
const uint16_t kCoronaAcTimerOff = 0xffff
 
const uint16_t kCoronaAcTimerUnitsPerMin = 30
 
+

Variable Documentation

+ +

◆ kCoronaAcFanAuto

+ +
+
+ + + + +
const uint8_t kCoronaAcFanAuto = 0b00
+
+ +
+
+ +

◆ kCoronaAcFanHigh

+ +
+
+ + + + +
const uint8_t kCoronaAcFanHigh = 0b11
+
+ +
+
+ +

◆ kCoronaAcFanLow

+ +
+
+ + + + +
const uint8_t kCoronaAcFanLow = 0b01
+
+ +
+
+ +

◆ kCoronaAcFanMedium

+ +
+
+ + + + +
const uint8_t kCoronaAcFanMedium = 0b10
+
+ +
+
+ +

◆ kCoronaAcFanOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcFanOffset = 0
+
+ +
+
+ +

◆ kCoronaAcFanSize

+ +
+
+ + + + +
const uint8_t kCoronaAcFanSize = 2
+
+ +
+
+ +

◆ kCoronaAcMaxTemp

+ +
+
+ + + + +
const uint8_t kCoronaAcMaxTemp = 30
+
+ +
+
+ +

◆ kCoronaAcMinTemp

+ +
+
+ + + + +
const uint8_t kCoronaAcMinTemp = 17
+
+ +
+
+ +

◆ kCoronaAcModeCool

+ +
+
+ + + + +
const uint8_t kCoronaAcModeCool = 0b10
+
+ +
+
+ +

◆ kCoronaAcModeDry

+ +
+
+ + + + +
const uint8_t kCoronaAcModeDry = 0b01
+
+ +
+
+ +

◆ kCoronaAcModeFan

+ +
+
+ + + + +
const uint8_t kCoronaAcModeFan = 0b11
+
+ +
+
+ +

◆ kCoronaAcModeHeat

+ +
+
+ + + + +
const uint8_t kCoronaAcModeHeat = 0b00
+
+ +
+
+ +

◆ kCoronaAcModeOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcModeOffset
+
+Initial value: +
+
+ +

◆ kCoronaAcModeSize

+ +
+
+ + + + +
const uint8_t kCoronaAcModeSize = 2
+
+ +
+
+ +

◆ kCoronaAcOffTimerSection

+ +
+
+ + + + +
const uint8_t kCoronaAcOffTimerSection = 2
+
+ +
+
+ +

◆ kCoronaAcOnTimerSection

+ +
+
+ + + + +
const uint8_t kCoronaAcOnTimerSection = 1
+
+ +
+
+ +

◆ kCoronaAcPowerButtonOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcPowerButtonOffset
+
+Initial value: +
+
+ +

◆ kCoronaAcPowerOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcPowerOffset
+
+Initial value: +
+
+ +

◆ kCoronaAcPowerSaveOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcPowerSaveOffset = 3
+
+ +
+
+ +

◆ kCoronaAcSectionBytes

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionBytes = 7
+
+ +
+
+ +

◆ kCoronaAcSectionData0Base

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData0Base = 0x10
+
+ +
+
+ +

◆ kCoronaAcSectionData0InvPos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData0InvPos = 4
+
+ +
+
+ +

◆ kCoronaAcSectionData0Pos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData0Pos = 3
+
+ +
+
+ +

◆ kCoronaAcSectionData1InvPos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData1InvPos = 6
+
+ +
+
+ +

◆ kCoronaAcSectionData1Pos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData1Pos = 5
+
+ +
+
+ +

◆ kCoronaAcSectionHeader0

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionHeader0 = 0x28
+
+ +
+
+ +

◆ kCoronaAcSectionHeader0Pos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionHeader0Pos = 0
+
+ +
+
+ +

◆ kCoronaAcSectionHeader1

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionHeader1 = 0x61
+
+ +
+
+ +

◆ kCoronaAcSectionHeader1Pos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionHeader1Pos = 1
+
+ +
+
+ +

◆ kCoronaAcSectionLabelBase

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionLabelBase = 0x0D
+
+ +
+
+ +

◆ kCoronaAcSectionLabelPos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionLabelPos = 2
+
+ +
+
+ +

◆ kCoronaAcSections

+ +
+
+ + + + +
const uint8_t kCoronaAcSections = 3
+
+ +
+
+ +

◆ kCoronaAcSettingsSection

+ +
+
+ + + + +
const uint8_t kCoronaAcSettingsSection = 0
+
+ +
+
+ +

◆ kCoronaAcSwingVToggleOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcSwingVToggleOffset = 6
+
+ +
+
+ +

◆ kCoronaAcTempOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcTempOffset = 0
+
+ +
+
+ +

◆ kCoronaAcTempSize

+ +
+
+ + + + +
const uint8_t kCoronaAcTempSize = 4
+
+ +
+
+ +

◆ kCoronaAcTimerMax

+ +
+
+ + + + +
const uint16_t kCoronaAcTimerMax = 12 * 60
+
+ +
+
+ +

◆ kCoronaAcTimerOff

+ +
+
+ + + + +
const uint16_t kCoronaAcTimerOff = 0xffff
+
+ +
+
+ +

◆ kCoronaAcTimerUnitsPerMin

+ +
+
+ + + + +
const uint16_t kCoronaAcTimerUnitsPerMin = 30
+
+ +
+
+
+
const uint8_t kCoronaAcTempOffset
Definition: ir_Corona.h:67
+
const uint8_t kCoronaAcTempSize
Definition: ir_Corona.h:68
+
const uint8_t kCoronaAcPowerOffset
Definition: ir_Corona.h:71
+
const uint8_t kCoronaAcPowerButtonOffset
Definition: ir_Corona.h:73
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h_source.html new file mode 100644 index 000000000..61f778b49 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h_source.html @@ -0,0 +1,319 @@ + + + + + + + +IRremoteESP8266: src/ir_Corona.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Corona.h
+
+
+Go to the documentation of this file.
1 // Corona A/C
+
2 //
+
3 // Copyright 2020 Christian Nilsson
+
4 
+
5 // Supports:
+
6 // Brand: Corona, Model: CSH-N2211 A/C
+
7 // Brand: Corona, Model: CSH-N2511 A/C
+
8 // Brand: Corona, Model: CSH-N2811 A/C
+
9 // Brand: Corona, Model: CSH-N4011 A/C
+
10 // Brand: Corona, Model: AR-01 remote
+
11 //
+
12 // Ref: https://docs.google.com/spreadsheets/d/1zzDEUQ52y7MZ7_xCU3pdjdqbRXOwZLsbTGvKWcicqCI/
+
13 // Ref: https://www.corona.co.jp/box/download.php?id=145060636229
+
14 
+
15 #ifndef IR_CORONA_H_
+
16 #define IR_CORONA_H_
+
17 
+
18 #define __STDC_LIMIT_MACROS
+
19 #include <stdint.h>
+
20 #ifndef UNIT_TEST
+
21 #include <Arduino.h>
+
22 #endif
+
23 #include "IRremoteESP8266.h"
+
24 #include "IRsend.h"
+
25 #ifdef UNIT_TEST
+
26 #include "IRsend_test.h"
+
27 #endif
+
28 
+
29 // Constants
+
30 
+
31 // CORONA_AC
+
32 const uint8_t kCoronaAcSectionBytes = 7; // kCoronaAcStateLengthShort
+
33 const uint8_t kCoronaAcSections = 3;
+
34 const uint8_t kCoronaAcSectionHeader0Pos = 0;
+
35 const uint8_t kCoronaAcSectionHeader0 = 0x28;
+
36 const uint8_t kCoronaAcSectionHeader1Pos = 1;
+
37 const uint8_t kCoronaAcSectionHeader1 = 0x61;
+
38 const uint8_t kCoronaAcSectionLabelPos = 2;
+
39 const uint8_t kCoronaAcSectionLabelBase = 0x0D; // 0b1101
+
40 const uint8_t kCoronaAcSectionData0Pos = 3;
+
41 const uint8_t kCoronaAcSectionData0InvPos = 4;
+
42 const uint8_t kCoronaAcSectionData1Pos = 5;
+
43 const uint8_t kCoronaAcSectionData1InvPos = 6;
+
44 const uint8_t kCoronaAcSectionData0Base = 0x10; // D0 Pos 4 always on
+
45 
+
46 const uint8_t kCoronaAcSettingsSection = 0;
+
47 // D0
+
48 const uint8_t kCoronaAcFanOffset = 0; // D0 LSB Pos 0-1
+
49 const uint8_t kCoronaAcFanSize = 2;
+
50 const uint8_t kCoronaAcFanAuto = 0b00; // 0
+
51 const uint8_t kCoronaAcFanLow = 0b01; // 1
+
52 const uint8_t kCoronaAcFanMedium = 0b10; // 2
+
53 const uint8_t kCoronaAcFanHigh = 0b11; // 3
+
54 
+
55 // One bit unknown // D0 Pos 2
+
56 const uint8_t kCoronaAcPowerSaveOffset = 3; // D0 Pos 3
+
57 // One bit unknown always on // D0 Pos 4
+
58 // One bit unknown // D0 Pos 5
+
59 const uint8_t kCoronaAcSwingVToggleOffset = 6; // D0 Pos 6
+
60 // One bit unknown // D0 MSB Pos 7
+
61 
+
62 // D1
+
63 /* full auto mode not supported by this code yet
+
64 const uint8_t kCoronaAcAutoD0 = 0b00010100; // only combined with power save
+
65 const uint8_t kCoronaAcAutoD1 = 0b10000011; // only combined with power
+
66 */
+
67 const uint8_t kCoronaAcTempOffset = 0; // D1 LSB Pos 0
+
68 const uint8_t kCoronaAcTempSize = 4;
+
69 const uint8_t kCoronaAcMinTemp = 17; // Celsius = 0b0001
+
70 const uint8_t kCoronaAcMaxTemp = 30; // Celsius = 0b1110
+
71 const uint8_t kCoronaAcPowerOffset =
+ + +
74  kCoronaAcPowerOffset + 1; // D1 Pos 5
+
75 const uint8_t kCoronaAcModeOffset =
+
76  kCoronaAcPowerButtonOffset + 1; // D1 MSB Pos 6-7
+
77 const uint8_t kCoronaAcModeSize = 2;
+
78 const uint8_t kCoronaAcModeHeat = 0b00; // 0
+
79 const uint8_t kCoronaAcModeDry = 0b01; // 1
+
80 const uint8_t kCoronaAcModeCool = 0b10; // 2
+
81 const uint8_t kCoronaAcModeFan = 0b11; // 3
+
82 
+
83 const uint8_t kCoronaAcOnTimerSection = 1;
+
84 const uint8_t kCoronaAcOffTimerSection = 2;
+
85 const uint16_t kCoronaAcTimerMax = 12 * 60; // 12H in Minutes
+
86 // Min value on remote is 1 hour, actual sent value can be 2 secs
+
87 const uint16_t kCoronaAcTimerOff = 0xffff;
+
88 const uint16_t kCoronaAcTimerUnitsPerMin = 30; // 30 units = 1 minute
+
89 
+
90 // Classes
+
91 
+
93 class IRCoronaAc {
+
94  public:
+
95  explicit IRCoronaAc(const uint16_t pin, const bool inverted = false,
+
96  const bool use_modulation = true);
+
97 
+
98  void stateReset();
+
99 #if SEND_CORONA_AC
+
100  void send(const uint16_t repeat = kNoRepeat);
+
105  int8_t calibrate(void) { return _irsend.calibrate(); }
+
106 #endif // SEND_CORONA_AC
+
107  void begin();
+
108  static bool validSection(const uint8_t state[], const uint16_t pos,
+
109  const uint8_t section);
+
110  void setPower(const bool on);
+
111  bool getPower();
+
112  bool getPowerButton();
+
113  void on();
+
114  void off();
+
115  void setTemp(const uint8_t temp);
+
116  uint8_t getTemp();
+
117  void setSwingVToggle(const bool on);
+
118  bool getSwingVToggle(void);
+
119  void setFan(const uint8_t speed);
+
120  uint8_t getFan();
+
121  void setMode(const uint8_t mode);
+
122  uint8_t getMode();
+
123  void setEcono(const bool on);
+
124  bool getEcono(void);
+
125  void setOnTimer(const uint16_t nr_of_mins);
+
126  uint16_t getOnTimer(void);
+
127  void setOffTimer(const uint16_t nr_of_mins);
+
128  uint16_t getOffTimer(void);
+
129  uint8_t* getRaw();
+
130  void setRaw(const uint8_t new_code[],
+
131  const uint16_t length = kCoronaAcStateLength);
+
132  uint8_t convertMode(const stdAc::opmode_t mode);
+
133  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
134  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
135  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ +
137  String toString();
+
138 #ifndef UNIT_TEST
+
139 
+
140  private:
+ +
142 #else
+
143  IRsendTest _irsend;
+
145 #endif
+ +
148  static uint8_t getSectionByte(const uint8_t section);
+
149  static void checksum(uint8_t* data);
+
150  void setPowerButton(const bool on);
+
151  void _setPower(const bool on);
+
152  void _setTimer(const uint8_t section, const uint16_t nr_of_mins);
+
153  uint16_t _getTimer(const uint8_t section);
+
154 };
+
155 #endif // IR_CORONA_H_
+
+
bool getPowerButton()
Get the value of the current power button setting.
Definition: ir_Corona.cpp:346
+
uint16_t getOnTimer(void)
Get the current On Timer time.
Definition: ir_Corona.cpp:518
+
const uint8_t kCoronaAcSectionBytes
Definition: ir_Corona.h:32
+
const uint8_t kCoronaAcTempOffset
Definition: ir_Corona.h:67
+
void setFan(const uint8_t speed)
Set the operating speed of the A/C Fan.
Definition: ir_Corona.cpp:415
+
void setEcono(const bool on)
Change the powersave setting.
Definition: ir_Corona.cpp:425
+
const uint8_t kCoronaAcSectionHeader0Pos
Definition: ir_Corona.h:34
+
void setRaw(const uint8_t new_code[], const uint16_t length=kCoronaAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Corona.cpp:285
+
const uint8_t kCoronaAcSectionLabelBase
Definition: ir_Corona.h:39
+
const uint8_t kCoronaAcModeFan
Definition: ir_Corona.h:81
+
void setPowerButton(const bool on)
Change the power button setting.
Definition: ir_Corona.cpp:339
+
Class for handling detailed Corona A/C messages.
Definition: ir_Corona.h:93
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kCoronaAcModeDry
Definition: ir_Corona.h:79
+
const uint8_t kCoronaAcSectionData0Base
Definition: ir_Corona.h:44
+
const uint8_t kCoronaAcPowerSaveOffset
Definition: ir_Corona.h:56
+
void setPower(const bool on)
Change the power setting. (in practice Standby, remote power)
Definition: ir_Corona.cpp:315
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Corona.cpp:155
+
const uint8_t kCoronaAcTempSize
Definition: ir_Corona.h:68
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Corona.cpp:255
+
const uint8_t kCoronaAcFanMedium
Definition: ir_Corona.h:52
+
const uint16_t kCoronaAcTimerUnitsPerMin
Definition: ir_Corona.h:88
+
void setOffTimer(const uint16_t nr_of_mins)
Set the Off Timer time.
Definition: ir_Corona.cpp:541
+
const uint8_t kCoronaAcFanLow
Definition: ir_Corona.h:51
+
stdAc::state_t toCommon()
Convert the A/C state to it's common stdAc::state_t equivalent.
Definition: ir_Corona.cpp:575
+ +
void setTemp(const uint8_t temp)
Set the temp in deg C.
Definition: ir_Corona.cpp:291
+
const uint8_t kCoronaAcSectionHeader0
Definition: ir_Corona.h:35
+
void setOnTimer(const uint16_t nr_of_mins)
Set the On Timer time.
Definition: ir_Corona.cpp:525
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t remote_state[kCoronaAcStateLength]
The state of the IR remote.
Definition: ir_Corona.h:147
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a standard A/C Fan speed into its native fan speed.
Definition: ir_Corona.cpp:439
+
const uint8_t kCoronaAcSwingVToggleOffset
Definition: ir_Corona.h:59
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kCoronaAcOffTimerSection
Definition: ir_Corona.h:84
+
void on()
Change the power setting to On.
Definition: ir_Corona.cpp:352
+
const uint16_t kCoronaAcTimerMax
Definition: ir_Corona.h:85
+
static bool validSection(const uint8_t state[], const uint16_t pos, const uint8_t section)
Check that a CoronaAc Section part is valid with section byte and inverted.
Definition: ir_Corona.cpp:188
+
bool getPower()
Get the current power setting. (in practice Standby, remote power)
Definition: ir_Corona.cpp:326
+
const uint8_t kCoronaAcSectionHeader1
Definition: ir_Corona.h:37
+
uint8_t getTemp()
Get the current temperature from the internal state.
Definition: ir_Corona.cpp:300
+
bool getEcono(void)
Get the value of the current powersave setting.
Definition: ir_Corona.cpp:431
+
bool getSwingVToggle(void)
Get the Vertical Swing toggle setting.
Definition: ir_Corona.cpp:473
+ +
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Corona.cpp:359
+
void send(const uint16_t repeat=kNoRepeat)
Send the current internal state as an IR message.
Definition: ir_Corona.cpp:260
+
const uint8_t kCoronaAcSectionData1InvPos
Definition: ir_Corona.h:43
+
const uint8_t kCoronaAcPowerOffset
Definition: ir_Corona.h:71
+
const uint8_t kCoronaAcPowerButtonOffset
Definition: ir_Corona.h:73
+
const uint8_t kCoronaAcSections
Definition: ir_Corona.h:33
+
const uint8_t kCoronaAcSectionData0InvPos
Definition: ir_Corona.h:41
+
const uint16_t kNoRepeat
Definition: IRremoteESP8266.h:810
+
const uint8_t kCoronaAcFanHigh
Definition: ir_Corona.h:53
+
const uint8_t kCoronaAcSectionData1Pos
Definition: ir_Corona.h:42
+
const uint16_t kCoronaAcStateLength
Definition: IRremoteESP8266.h:833
+
static void checksum(uint8_t *data)
Calculate and set the check values for the internal state.
Definition: ir_Corona.cpp:240
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a standard A/C mode into its native mode.
Definition: ir_Corona.cpp:385
+
uint16_t _getTimer(const uint8_t section)
Get the current Timer time.
Definition: ir_Corona.cpp:504
+
uint8_t getFan()
Get the operating speed of the A/C Fan.
Definition: ir_Corona.cpp:408
+
const uint8_t kCoronaAcFanSize
Definition: ir_Corona.h:49
+
void _setTimer(const uint8_t section, const uint16_t nr_of_mins)
Set the Timer time.
Definition: ir_Corona.cpp:483
+
const uint8_t kCoronaAcModeCool
Definition: ir_Corona.h:80
+
const uint8_t kCoronaAcMinTemp
Definition: ir_Corona.h:69
+
const uint8_t kCoronaAcSectionData0Pos
Definition: ir_Corona.h:40
+
const uint8_t kCoronaAcSectionLabelPos
Definition: ir_Corona.h:38
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode to it's common stdAc::opmode_t equivalent.
Definition: ir_Corona.cpp:397
+
uint16_t getOffTimer(void)
Get the current Off Timer time.
Definition: ir_Corona.cpp:534
+
const uint8_t kCoronaAcSectionHeader1Pos
Definition: ir_Corona.h:36
+
IRCoronaAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor for handling detailed Corona A/C messages.
Definition: ir_Corona.cpp:149
+
uint8_t * getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Corona.cpp:277
+
const uint8_t kCoronaAcSettingsSection
Definition: ir_Corona.h:46
+
const uint8_t kCoronaAcFanOffset
Definition: ir_Corona.h:48
+
const uint8_t kCoronaAcModeHeat
Definition: ir_Corona.h:78
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Corona.h:141
+
void setSwingVToggle(const bool on)
Set the Vertical Swing toggle setting.
Definition: ir_Corona.cpp:466
+
const uint8_t kCoronaAcModeOffset
Definition: ir_Corona.h:75
+
static uint8_t getSectionByte(const uint8_t section)
Get the byte that identifies the section.
Definition: ir_Corona.cpp:172
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Corona.cpp:366
+
void off()
Change the power setting to Off.
Definition: ir_Corona.cpp:355
+
void _setPower(const bool on)
Change the power setting. (in practice Standby, remote power)
Definition: ir_Corona.cpp:307
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed to it's common equivalent.
Definition: ir_Corona.cpp:453
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Corona.h:105
+
const uint16_t kCoronaAcTimerOff
Definition: ir_Corona.h:87
+
const uint8_t kCoronaAcOnTimerSection
Definition: ir_Corona.h:83
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
String toString()
Convert the internal state into a human readable string.
Definition: ir_Corona.cpp:550
+
const uint8_t kCoronaAcMaxTemp
Definition: ir_Corona.h:70
+
const uint8_t kCoronaAcFanAuto
Definition: ir_Corona.h:50
+
const uint8_t kCoronaAcModeSize
Definition: ir_Corona.h:77
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8cpp.html new file mode 100644 index 000000000..3f6d4561f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8cpp.html @@ -0,0 +1,114 @@ + + + + + + + +IRremoteESP8266: src/ir_Daikin.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Daikin.cpp File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h.html new file mode 100644 index 000000000..5732dacd5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h.html @@ -0,0 +1,5674 @@ + + + + + + + +IRremoteESP8266: src/ir_Daikin.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Daikin.h File Reference
+
+
+ +

Support for Daikin A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Classes

class  IRDaikinESP
 Class for handling detailed Daikin 280-bit A/C messages. More...
 
class  IRDaikin2
 Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99. More...
 
class  IRDaikin216
 Class for handling detailed Daikin 216-bit A/C messages. More...
 
class  IRDaikin160
 Class for handling detailed Daikin 160-bit A/C messages. More...
 
class  IRDaikin176
 Class for handling detailed Daikin 176-bit A/C messages. More...
 
class  IRDaikin128
 Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena. More...
 
class  IRDaikin152
 Class for handling detailed Daikin 152-bit A/C messages. More...
 
class  IRDaikin64
 Class for handling detailed Daikin 64-bit A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kDaikinAuto = 0b000
 
const uint8_t kDaikinDry = 0b010
 
const uint8_t kDaikinCool = 0b011
 
const uint8_t kDaikinHeat = 0b100
 
const uint8_t kDaikinFan = 0b110
 
const uint8_t kDaikinModeOffset = 4
 
const uint8_t kDaikinModeSize = 3
 
const uint8_t kDaikinMinTemp = 10
 
const uint8_t kDaikinMaxTemp = 32
 
const uint8_t kDaikinFanMin = 1
 
const uint8_t kDaikinFanMed = 3
 
const uint8_t kDaikinFanMax = 5
 
const uint8_t kDaikinFanAuto = 0b1010
 
const uint8_t kDaikinFanQuiet = 0b1011
 
const uint8_t kDaikinFanOffset = 4
 
const uint8_t kDaikinFanSize = 4
 
const uint8_t kDaikinSwingOffset = 0
 
const uint8_t kDaikinSwingSize = 4
 
const uint8_t kDaikinSwingOn = 0b1111
 
const uint8_t kDaikinSwingOff = 0b0000
 
const uint16_t kDaikinHeaderLength = 5
 
const uint8_t kDaikinSections = 3
 
const uint8_t kDaikinSection1Length = 8
 
const uint8_t kDaikinSection2Length = 8
 
const uint8_t kDaikinSection3Length
 
const uint8_t kDaikinByteComfort = 6
 
const uint8_t kDaikinByteChecksum1 = 7
 
const uint8_t kDaikinBitComfortOffset = 4
 
const uint8_t kDaikinBitComfort = 1 << kDaikinBitComfortOffset
 
const uint8_t kDaikinByteClockMinsLow = 13
 
const uint8_t kDaikinByteClockMinsHigh = 14
 
const uint8_t kDaikinClockMinsHighOffset = 0
 
const uint8_t kDaikinClockMinsHighSize = 3
 
const uint8_t kDaikinDoWOffset = 3
 
const uint8_t kDaikinDoWSize = 3
 
const uint8_t kDaikinByteChecksum2 = 15
 
const uint8_t kDaikinBytePower = 21
 
const uint8_t kDaikinBitPowerOffset = 0
 
const uint8_t kDaikinBitPower = 1 << kDaikinBitPowerOffset
 
const uint8_t kDaikinTempOffset = 1
 
const uint8_t kDaikinTempSize = 6
 
const uint8_t kDaikinByteTemp = 22
 
const uint8_t kDaikinByteFan = 24
 
const uint8_t kDaikinByteSwingH = 25
 
const uint8_t kDaikinByteOnTimerMinsLow = 26
 
const uint8_t kDaikinByteOnTimerMinsHigh = 27
 
const uint8_t kDaikinOnTimerMinsHighOffset = 0
 
const uint8_t kDaikinOnTimerMinsHighSize = 4
 
const uint8_t kDaikinByteOffTimerMinsLow = kDaikinByteOnTimerMinsHigh
 
const uint8_t kDaikinByteOffTimerMinsHigh = 28
 
const uint8_t kDaikinBytePowerful = 29
 
const uint8_t kDaikinBitPowerfulOffset = 0
 
const uint8_t kDaikinBitPowerful = 1 << kDaikinBitPowerfulOffset
 
const uint8_t kDaikinByteSilent = kDaikinBytePowerful
 
const uint8_t kDaikinBitSilentOffset = 5
 
const uint8_t kDaikinBitSilent = 1 << kDaikinBitSilentOffset
 
const uint8_t kDaikinByteSensor = 32
 
const uint8_t kDaikinBitSensorOffset = 1
 
const uint8_t kDaikinBitSensor = 1 << kDaikinBitSensorOffset
 
const uint8_t kDaikinByteEcono = kDaikinByteSensor
 
const uint8_t kDaikinBitEconoOffset = 2
 
const uint8_t kDaikinBitEcono = 1 << kDaikinBitEconoOffset
 
const uint8_t kDaikinByteEye = kDaikinByteSensor
 
const uint8_t kDaikinBitEye = 0b10000000
 
const uint8_t kDaikinByteWeeklyTimer = kDaikinByteSensor
 
const uint8_t kDaikinBitWeeklyTimerOffset = 7
 
const uint8_t kDaikinBitWeeklyTimer = 1 << kDaikinBitWeeklyTimerOffset
 
const uint8_t kDaikinByteMold = 33
 
const uint8_t kDaikinBitMoldOffset = 1
 
const uint8_t kDaikinBitMold = 1 << kDaikinBitMoldOffset
 
const uint8_t kDaikinByteOffTimer = kDaikinBytePower
 
const uint8_t kDaikinBitOffTimerOffset = 2
 
const uint8_t kDaikinBitOffTimer = 1 << kDaikinBitOffTimerOffset
 
const uint8_t kDaikinByteOnTimer = kDaikinByteOffTimer
 
const uint8_t kDaikinBitOnTimerOffset = 1
 
const uint8_t kDaikinBitOnTimer = 1 << kDaikinBitOnTimerOffset
 
const uint8_t kDaikinByteChecksum3 = kDaikinStateLength - 1
 
const uint16_t kDaikinUnusedTime = 0x600
 
const uint8_t kDaikinBeepQuiet = 1
 
const uint8_t kDaikinBeepLoud = 2
 
const uint8_t kDaikinBeepOff = 3
 
const uint8_t kDaikinLightBright = 1
 
const uint8_t kDaikinLightDim = 2
 
const uint8_t kDaikinLightOff = 3
 
const uint8_t kDaikinCurBit = kDaikinStateLength
 
const uint8_t kDaikinCurIndex = kDaikinStateLength + 1
 
const uint8_t kDaikinTolerance = 35
 
const uint16_t kDaikinMarkExcess = kMarkExcess
 
const uint16_t kDaikinHdrMark = 3650
 
const uint16_t kDaikinHdrSpace = 1623
 
const uint16_t kDaikinBitMark = 428
 
const uint16_t kDaikinZeroSpace = 428
 
const uint16_t kDaikinOneSpace = 1280
 
const uint16_t kDaikinGap = 29000
 
const uint64_t kDaikinFirstHeader64
 
const uint16_t kDaikin2Freq = 36700
 
const uint16_t kDaikin2LeaderMark = 10024
 
const uint16_t kDaikin2LeaderSpace = 25180
 
const uint16_t kDaikin2Gap = kDaikin2LeaderMark + kDaikin2LeaderSpace
 
const uint16_t kDaikin2HdrMark = 3500
 
const uint16_t kDaikin2HdrSpace = 1728
 
const uint16_t kDaikin2BitMark = 460
 
const uint16_t kDaikin2OneSpace = 1270
 
const uint16_t kDaikin2ZeroSpace = 420
 
const uint16_t kDaikin2Sections = 2
 
const uint16_t kDaikin2Section1Length = 20
 
const uint16_t kDaikin2Section2Length = 19
 
const uint8_t kDaikin2Tolerance = 5
 
const uint8_t kDaikin2BitSleepTimerOffset = 5
 
const uint8_t kDaikin2BitSleepTimer = 1 << kDaikin2BitSleepTimerOffset
 
const uint8_t kDaikin2BitPurifyOffset = 4
 
const uint8_t kDaikin2BitPurify = 1 << kDaikin2BitPurifyOffset
 
const uint8_t kDaikin2BitEyeOffset = 1
 
const uint8_t kDaikin2BitEye = 1 << kDaikin2BitEyeOffset
 
const uint8_t kDaikin2BitEyeAutoOffset = 7
 
const uint8_t kDaikin2BitEyeAuto = 1 << kDaikin2BitEyeAutoOffset
 
const uint8_t kDaikin2BitMoldOffset = 3
 
const uint8_t kDaikin2BitMold = 1 << kDaikin2BitMoldOffset
 
const uint8_t kDaikin2BitCleanOffset = 5
 
const uint8_t kDaikin2BitClean = 1 << kDaikin2BitCleanOffset
 
const uint8_t kDaikin2BitFreshAirOffset = 0
 
const uint8_t kDaikin2BitFreshAir = 1 << kDaikin2BitFreshAirOffset
 
const uint8_t kDaikin2BitFreshAirHighOffset = 7
 
const uint8_t kDaikin2BitFreshAirHigh = 1 << kDaikin2BitFreshAirHighOffset
 
const uint8_t kDaikin2BitPowerOffset = 7
 
const uint8_t kDaikin2BitPower = 1 << kDaikin2BitPowerOffset
 
const uint8_t kDaikin2LightOffset = 4
 
const uint8_t kDaikin2LightSize = 2
 
const uint8_t kDaikin2BeepOffset = 6
 
const uint8_t kDaikin2BeepSize = 2
 
const uint8_t kDaikin2SwingVHigh = 0x1
 
const uint8_t kDaikin2SwingVLow = 0x6
 
const uint8_t kDaikin2SwingVSwing = 0xF
 
const uint8_t kDaikin2SwingVAuto = 0xE
 
const uint8_t kDaikin2SwingVBreeze = 0xC
 
const uint8_t kDaikin2SwingVCirculate = 0xD
 
const uint8_t kDaikin2FanByte = 28
 
const uint8_t kDaikin2SwingHWide = 0xA3
 
const uint8_t kDaikin2SwingHLeftMax = 0xA8
 
const uint8_t kDaikin2SwingHLeft = 0xA9
 
const uint8_t kDaikin2SwingHMiddle = 0xAA
 
const uint8_t kDaikin2SwingHRight = 0xAB
 
const uint8_t kDaikin2SwingHRightMax = 0xAC
 
const uint8_t kDaikin2SwingHAuto = 0xBE
 
const uint8_t kDaikin2SwingHSwing = 0xBF
 
const uint8_t kDaikin2MinCoolTemp = 18
 
const uint16_t kDaikin216Freq = 38000
 
const uint16_t kDaikin216HdrMark = 3440
 
const uint16_t kDaikin216HdrSpace = 1750
 
const uint16_t kDaikin216BitMark = 420
 
const uint16_t kDaikin216OneSpace = 1300
 
const uint16_t kDaikin216ZeroSpace = 450
 
const uint16_t kDaikin216Gap = 29650
 
const uint16_t kDaikin216Sections = 2
 
const uint16_t kDaikin216Section1Length = 8
 
const uint16_t kDaikin216Section2Length
 
const uint8_t kDaikin216BytePower = 13
 
const uint8_t kDaikin216ByteMode = kDaikin216BytePower
 
const uint8_t kDaikin216ByteTemp = 14
 
const uint8_t kDaikin216TempOffset = 1
 
const uint8_t kDaikin216TempSize = 6
 
const uint8_t kDaikin216ByteFan = 16
 
const uint8_t kDaikin216MaskFan = 0b11110000
 
const uint8_t kDaikin216ByteSwingV = 16
 
const uint8_t kDaikin216SwingSize = 4
 
const uint8_t kDaikin216SwingOn = 0b1111
 
const uint8_t kDaikin216SwingOff = 0b0000
 
const uint8_t kDaikin216ByteSwingH = 17
 
const uint8_t kDaikin216BytePowerful = 21
 
const uint16_t kDaikin160Freq = 38000
 
const uint16_t kDaikin160HdrMark = 5000
 
const uint16_t kDaikin160HdrSpace = 2145
 
const uint16_t kDaikin160BitMark = 342
 
const uint16_t kDaikin160OneSpace = 1786
 
const uint16_t kDaikin160ZeroSpace = 700
 
const uint16_t kDaikin160Gap = 29650
 
const uint16_t kDaikin160Sections = 2
 
const uint16_t kDaikin160Section1Length = 7
 
const uint16_t kDaikin160Section2Length
 
const uint8_t kDaikin160BytePower = 12
 
const uint8_t kDaikin160ByteMode = kDaikin160BytePower
 
const uint8_t kDaikin160ByteTemp = 16
 
const uint8_t kDaikin160TempOffset = 1
 
const uint8_t kDaikin160TempSize = 6
 
const uint8_t kDaikin160ByteFan = 17
 
const uint8_t kDaikin160MaskFan = 0b00001111
 
const uint8_t kDaikin160ByteSwingV = 13
 
const uint8_t kDaikin160MaskSwingV = 0b11110000
 
const uint8_t kDaikin160SwingVLowest = 0x1
 
const uint8_t kDaikin160SwingVLow = 0x2
 
const uint8_t kDaikin160SwingVMiddle = 0x3
 
const uint8_t kDaikin160SwingVHigh = 0x4
 
const uint8_t kDaikin160SwingVHighest = 0x5
 
const uint8_t kDaikin160SwingVAuto = 0xF
 
const uint16_t kDaikin176Freq = 38000
 
const uint16_t kDaikin176HdrMark = 5070
 
const uint16_t kDaikin176HdrSpace = 2140
 
const uint16_t kDaikin176BitMark = 370
 
const uint16_t kDaikin176OneSpace = 1780
 
const uint16_t kDaikin176ZeroSpace = 710
 
const uint16_t kDaikin176Gap = 29410
 
const uint16_t kDaikin176Sections = 2
 
const uint16_t kDaikin176Section1Length = 7
 
const uint16_t kDaikin176Section2Length
 
const uint8_t kDaikin176Cool = 0b111
 
const uint8_t kDaikin176BytePower = 14
 
const uint8_t kDaikin176ByteMode = 12
 
const uint8_t kDaikin176MaskMode = 0b01110000
 
const uint8_t kDaikin176ByteModeButton = 13
 
const uint8_t kDaikin176ModeButton = 0b00000100
 
const uint8_t kDaikin176ByteTemp = 17
 
const uint8_t kDaikin176TempOffset = 1
 
const uint8_t kDaikin176TempSize = 6
 
const uint8_t kDaikin176DryFanTemp = 17
 
const uint8_t kDaikin176ByteFan = 18
 
const uint8_t kDaikin176MaskFan = 0b11110000
 
const uint8_t kDaikin176FanMax = 3
 
const uint8_t kDaikin176ByteSwingH = 18
 
const uint8_t kDaikin176SwingHAuto = 0x5
 
const uint8_t kDaikin176SwingHOff = 0x6
 
const uint16_t kDaikin128Freq = 38000
 
const uint16_t kDaikin128LeaderMark = 9800
 
const uint16_t kDaikin128LeaderSpace = 9800
 
const uint16_t kDaikin128HdrMark = 4600
 
const uint16_t kDaikin128HdrSpace = 2500
 
const uint16_t kDaikin128BitMark = 350
 
const uint16_t kDaikin128OneSpace = 954
 
const uint16_t kDaikin128ZeroSpace = 382
 
const uint16_t kDaikin128Gap = 20300
 
const uint16_t kDaikin128FooterMark = kDaikin128HdrMark
 
const uint16_t kDaikin128Sections = 2
 
const uint16_t kDaikin128SectionLength = 8
 
const uint8_t kDaikin128ByteModeFan = 1
 
const uint8_t kDaikin128ModeSize = 4
 
const uint8_t kDaikin128Dry = 0b00000001
 
const uint8_t kDaikin128Cool = 0b00000010
 
const uint8_t kDaikin128Fan = 0b00000100
 
const uint8_t kDaikin128Heat = 0b00001000
 
const uint8_t kDaikin128Auto = 0b00001010
 
const uint8_t kDaikin128MaskFan = 0b11110000
 
const uint8_t kDaikin128FanAuto = 0b0001
 
const uint8_t kDaikin128FanHigh = 0b0010
 
const uint8_t kDaikin128FanMed = 0b0100
 
const uint8_t kDaikin128FanLow = 0b1000
 
const uint8_t kDaikin128FanPowerful = 0b0011
 
const uint8_t kDaikin128FanQuiet = 0b1001
 
const uint8_t kDaikin128ByteClockMins = 2
 
const uint8_t kDaikin128ByteClockHours = 3
 
const uint8_t kDaikin128ByteOnTimer = 4
 
const uint8_t kDaikin128ByteOffTimer = 5
 
const uint8_t kDaikin128BitTimerEnabledOffset = 7
 
const uint8_t kDaikin128BitTimerEnabled = 1 << kDaikin128BitTimerEnabledOffset
 
const uint8_t kDaikin128TimerOffset = 0
 
const uint8_t kDaikin128TimerSize = 7
 
const uint8_t kDaikin128HalfHourOffset = 6
 
const uint8_t kDaikin128BitHalfHour = 1 << kDaikin128HalfHourOffset
 
const uint8_t kDaikin128HoursOffset = 0
 
const uint8_t kDaikin128HoursSize = 6
 
const uint8_t kDaikin128ByteTemp = 6
 
const uint8_t kDaikin128MinTemp = 16
 
const uint8_t kDaikin128MaxTemp = 30
 
const uint8_t kDaikin128BytePowerSwingSleep = 7
 
const uint8_t kDaikin128BitSwingOffset = 0
 
const uint8_t kDaikin128BitSwing = 1 << kDaikin128BitSwingOffset
 
const uint8_t kDaikin128BitSleepOffset = 1
 
const uint8_t kDaikin128BitSleep = 1 << kDaikin128BitSleepOffset
 
const uint8_t kDaikin128BitPowerToggleOffset = 3
 
const uint8_t kDaikin128BitPowerToggle = 1 << kDaikin128BitPowerToggleOffset
 
const uint8_t kDaikin128ByteEconoLight = 9
 
const uint8_t kDaikin128BitEconoOffset = 2
 
const uint8_t kDaikin128BitEcono = 1 << kDaikin128BitEconoOffset
 
const uint8_t kDaikin128BitWall = 0b00001000
 
const uint8_t kDaikin128BitCeiling = 0b00000001
 
const uint8_t kDaikin128MaskLight = kDaikin128BitWall | kDaikin128BitCeiling
 
const uint16_t kDaikin152Freq = 38000
 
const uint8_t kDaikin152LeaderBits = 5
 
const uint16_t kDaikin152HdrMark = 3492
 
const uint16_t kDaikin152HdrSpace = 1718
 
const uint16_t kDaikin152BitMark = 433
 
const uint16_t kDaikin152OneSpace = 1529
 
const uint16_t kDaikin152ZeroSpace = kDaikin152BitMark
 
const uint16_t kDaikin152Gap = 25182
 
const uint8_t kDaikin152ModeByte = 5
 
const uint8_t kDaikin152PowerByte = kDaikin152ModeByte
 
const uint8_t kDaikin152TempByte = 6
 
const uint8_t kDaikin152TempSize = 7
 
const uint8_t kDaikin152DryTemp = kDaikin2MinCoolTemp
 
const uint8_t kDaikin152FanTemp = 0x60
 
const uint8_t kDaikin152FanByte = 8
 
const uint8_t kDaikin152SwingVByte = kDaikin152FanByte
 
const uint8_t kDaikin152QuietByte = 13
 
const uint8_t kDaikin152PowerfulByte = kDaikin152QuietByte
 
const uint8_t kDaikin152EconoByte = 16
 
const uint8_t kDaikin152ComfortByte = kDaikin152EconoByte
 
const uint8_t kDaikin152ComfortOffset = 1
 
const uint8_t kDaikin152SensorByte = kDaikin152EconoByte
 
const uint8_t kDaikin152SensorOffset = 3
 
const uint16_t kDaikin64HdrMark = kDaikin128HdrMark
 
const uint16_t kDaikin64BitMark = kDaikin128BitMark
 
const uint16_t kDaikin64HdrSpace = kDaikin128HdrSpace
 
const uint16_t kDaikin64OneSpace = kDaikin128OneSpace
 
const uint16_t kDaikin64ZeroSpace = kDaikin128ZeroSpace
 
const uint16_t kDaikin64LdrMark = kDaikin128LeaderMark
 
const uint16_t kDaikin64Gap = kDaikin128Gap
 
const uint16_t kDaikin64LdrSpace = kDaikin128LeaderSpace
 
const uint16_t kDaikin64Freq = kDaikin128Freq
 
const uint8_t kDaikin64Overhead = 9
 
const int8_t kDaikin64ToleranceDelta = 5
 
const uint64_t kDaikin64KnownGoodState = 0x7C16161607204216
 
const uint8_t kDaikin64ModeOffset = 8
 
const uint8_t kDaikin64ModeSize = 4
 
const uint8_t kDaikin64Dry = 0b001
 
const uint8_t kDaikin64Cool = 0b010
 
const uint8_t kDaikin64Fan = 0b100
 
const uint8_t kDaikin64FanOffset = kDaikin64ModeOffset + kDaikin64ModeSize
 
const uint8_t kDaikin64FanSize = 4
 
const uint8_t kDaikin64FanAuto = 0b0001
 
const uint8_t kDaikin64FanLow = 0b1000
 
const uint8_t kDaikin64FanMed = 0b0100
 
const uint8_t kDaikin64FanHigh = 0b0010
 
const uint8_t kDaikin64FanQuiet = 0b1001
 
const uint8_t kDaikin64FanTurbo = 0b0011
 
const uint8_t kDaikin64ClockOffset = kDaikin64FanOffset + kDaikin64FanSize
 
const uint8_t kDaikin64ClockMinsSize = 8
 
const uint8_t kDaikin64ClockHoursSize = 8
 
const uint8_t kDaikin64ClockSize
 
const uint8_t kDaikin64OnTimeOffset
 
const uint8_t kDaikin64OnTimeSize = 6
 
const uint8_t kDaikin64OnTimeHalfHourBit
 
const uint8_t kDaikin64OnTimeEnableBit = kDaikin64OnTimeHalfHourBit + 1
 
const uint8_t kDaikin64OffTimeOffset = kDaikin64OnTimeEnableBit + 1
 
const uint8_t kDaikin64OffTimeSize = 6
 
const uint8_t kDaikin64OffTimeHalfHourBit
 
const uint8_t kDaikin64OffTimeEnableBit = kDaikin64OffTimeHalfHourBit + 1
 
const uint8_t kDaikin64TempOffset = 48
 
const uint8_t kDaikin64TempSize = 8
 
const uint8_t kDaikin64MinTemp = 16
 
const uint8_t kDaikin64MaxTemp = 30
 
const uint8_t kDaikin64SwingVBit = 56
 
const uint8_t kDaikin64SleepBit = kDaikin64SwingVBit + 1
 
const uint8_t kDaikin64PowerToggleBit = 59
 
const uint8_t kDaikin64ChecksumOffset = 60
 
const uint8_t kDaikin64ChecksumSize = 4
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kDaikin128Auto

+ +
+
+ + + + +
const uint8_t kDaikin128Auto = 0b00001010
+
+ +
+
+ +

◆ kDaikin128BitCeiling

+ +
+
+ + + + +
const uint8_t kDaikin128BitCeiling = 0b00000001
+
+ +
+
+ +

◆ kDaikin128BitEcono

+ +
+
+ + + + +
const uint8_t kDaikin128BitEcono = 1 << kDaikin128BitEconoOffset
+
+ +
+
+ +

◆ kDaikin128BitEconoOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitEconoOffset = 2
+
+ +
+
+ +

◆ kDaikin128BitHalfHour

+ +
+
+ + + + +
const uint8_t kDaikin128BitHalfHour = 1 << kDaikin128HalfHourOffset
+
+ +
+
+ +

◆ kDaikin128BitMark

+ +
+
+ + + + +
const uint16_t kDaikin128BitMark = 350
+
+ +
+
+ +

◆ kDaikin128BitPowerToggle

+ +
+
+ + + + +
const uint8_t kDaikin128BitPowerToggle = 1 << kDaikin128BitPowerToggleOffset
+
+ +
+
+ +

◆ kDaikin128BitPowerToggleOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitPowerToggleOffset = 3
+
+ +
+
+ +

◆ kDaikin128BitSleep

+ +
+
+ + + + +
const uint8_t kDaikin128BitSleep = 1 << kDaikin128BitSleepOffset
+
+ +
+
+ +

◆ kDaikin128BitSleepOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitSleepOffset = 1
+
+ +
+
+ +

◆ kDaikin128BitSwing

+ +
+
+ + + + +
const uint8_t kDaikin128BitSwing = 1 << kDaikin128BitSwingOffset
+
+ +
+
+ +

◆ kDaikin128BitSwingOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitSwingOffset = 0
+
+ +
+
+ +

◆ kDaikin128BitTimerEnabled

+ +
+
+ + + + +
const uint8_t kDaikin128BitTimerEnabled = 1 << kDaikin128BitTimerEnabledOffset
+
+ +
+
+ +

◆ kDaikin128BitTimerEnabledOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitTimerEnabledOffset = 7
+
+ +
+
+ +

◆ kDaikin128BitWall

+ +
+
+ + + + +
const uint8_t kDaikin128BitWall = 0b00001000
+
+ +
+
+ +

◆ kDaikin128ByteClockHours

+ +
+
+ + + + +
const uint8_t kDaikin128ByteClockHours = 3
+
+ +
+
+ +

◆ kDaikin128ByteClockMins

+ +
+
+ + + + +
const uint8_t kDaikin128ByteClockMins = 2
+
+ +
+
+ +

◆ kDaikin128ByteEconoLight

+ +
+
+ + + + +
const uint8_t kDaikin128ByteEconoLight = 9
+
+ +
+
+ +

◆ kDaikin128ByteModeFan

+ +
+
+ + + + +
const uint8_t kDaikin128ByteModeFan = 1
+
+ +
+
+ +

◆ kDaikin128ByteOffTimer

+ +
+
+ + + + +
const uint8_t kDaikin128ByteOffTimer = 5
+
+ +
+
+ +

◆ kDaikin128ByteOnTimer

+ +
+
+ + + + +
const uint8_t kDaikin128ByteOnTimer = 4
+
+ +
+
+ +

◆ kDaikin128BytePowerSwingSleep

+ +
+
+ + + + +
const uint8_t kDaikin128BytePowerSwingSleep = 7
+
+ +
+
+ +

◆ kDaikin128ByteTemp

+ +
+
+ + + + +
const uint8_t kDaikin128ByteTemp = 6
+
+ +
+
+ +

◆ kDaikin128Cool

+ +
+
+ + + + +
const uint8_t kDaikin128Cool = 0b00000010
+
+ +
+
+ +

◆ kDaikin128Dry

+ +
+
+ + + + +
const uint8_t kDaikin128Dry = 0b00000001
+
+ +
+
+ +

◆ kDaikin128Fan

+ +
+
+ + + + +
const uint8_t kDaikin128Fan = 0b00000100
+
+ +
+
+ +

◆ kDaikin128FanAuto

+ +
+
+ + + + +
const uint8_t kDaikin128FanAuto = 0b0001
+
+ +
+
+ +

◆ kDaikin128FanHigh

+ +
+
+ + + + +
const uint8_t kDaikin128FanHigh = 0b0010
+
+ +
+
+ +

◆ kDaikin128FanLow

+ +
+
+ + + + +
const uint8_t kDaikin128FanLow = 0b1000
+
+ +
+
+ +

◆ kDaikin128FanMed

+ +
+
+ + + + +
const uint8_t kDaikin128FanMed = 0b0100
+
+ +
+
+ +

◆ kDaikin128FanPowerful

+ +
+
+ + + + +
const uint8_t kDaikin128FanPowerful = 0b0011
+
+ +
+
+ +

◆ kDaikin128FanQuiet

+ +
+
+ + + + +
const uint8_t kDaikin128FanQuiet = 0b1001
+
+ +
+
+ +

◆ kDaikin128FooterMark

+ +
+
+ + + + +
const uint16_t kDaikin128FooterMark = kDaikin128HdrMark
+
+ +
+
+ +

◆ kDaikin128Freq

+ +
+
+ + + + +
const uint16_t kDaikin128Freq = 38000
+
+ +
+
+ +

◆ kDaikin128Gap

+ +
+
+ + + + +
const uint16_t kDaikin128Gap = 20300
+
+ +
+
+ +

◆ kDaikin128HalfHourOffset

+ +
+
+ + + + +
const uint8_t kDaikin128HalfHourOffset = 6
+
+ +
+
+ +

◆ kDaikin128HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin128HdrMark = 4600
+
+ +
+
+ +

◆ kDaikin128HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin128HdrSpace = 2500
+
+ +
+
+ +

◆ kDaikin128Heat

+ +
+
+ + + + +
const uint8_t kDaikin128Heat = 0b00001000
+
+ +
+
+ +

◆ kDaikin128HoursOffset

+ +
+
+ + + + +
const uint8_t kDaikin128HoursOffset = 0
+
+ +
+
+ +

◆ kDaikin128HoursSize

+ +
+
+ + + + +
const uint8_t kDaikin128HoursSize = 6
+
+ +
+
+ +

◆ kDaikin128LeaderMark

+ +
+
+ + + + +
const uint16_t kDaikin128LeaderMark = 9800
+
+ +
+
+ +

◆ kDaikin128LeaderSpace

+ +
+
+ + + + +
const uint16_t kDaikin128LeaderSpace = 9800
+
+ +
+
+ +

◆ kDaikin128MaskFan

+ +
+
+ + + + +
const uint8_t kDaikin128MaskFan = 0b11110000
+
+ +
+
+ +

◆ kDaikin128MaskLight

+ +
+
+ + + + +
const uint8_t kDaikin128MaskLight = kDaikin128BitWall | kDaikin128BitCeiling
+
+ +
+
+ +

◆ kDaikin128MaxTemp

+ +
+
+ + + + +
const uint8_t kDaikin128MaxTemp = 30
+
+ +
+
+ +

◆ kDaikin128MinTemp

+ +
+
+ + + + +
const uint8_t kDaikin128MinTemp = 16
+
+ +
+
+ +

◆ kDaikin128ModeSize

+ +
+
+ + + + +
const uint8_t kDaikin128ModeSize = 4
+
+ +
+
+ +

◆ kDaikin128OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin128OneSpace = 954
+
+ +
+
+ +

◆ kDaikin128SectionLength

+ +
+
+ + + + +
const uint16_t kDaikin128SectionLength = 8
+
+ +
+
+ +

◆ kDaikin128Sections

+ +
+
+ + + + +
const uint16_t kDaikin128Sections = 2
+
+ +
+
+ +

◆ kDaikin128TimerOffset

+ +
+
+ + + + +
const uint8_t kDaikin128TimerOffset = 0
+
+ +
+
+ +

◆ kDaikin128TimerSize

+ +
+
+ + + + +
const uint8_t kDaikin128TimerSize = 7
+
+ +
+
+ +

◆ kDaikin128ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin128ZeroSpace = 382
+
+ +
+
+ +

◆ kDaikin152BitMark

+ +
+
+ + + + +
const uint16_t kDaikin152BitMark = 433
+
+ +
+
+ +

◆ kDaikin152ComfortByte

+ +
+
+ + + + +
const uint8_t kDaikin152ComfortByte = kDaikin152EconoByte
+
+ +
+
+ +

◆ kDaikin152ComfortOffset

+ +
+
+ + + + +
const uint8_t kDaikin152ComfortOffset = 1
+
+ +
+
+ +

◆ kDaikin152DryTemp

+ +
+
+ + + + +
const uint8_t kDaikin152DryTemp = kDaikin2MinCoolTemp
+
+ +
+
+ +

◆ kDaikin152EconoByte

+ +
+
+ + + + +
const uint8_t kDaikin152EconoByte = 16
+
+ +
+
+ +

◆ kDaikin152FanByte

+ +
+
+ + + + +
const uint8_t kDaikin152FanByte = 8
+
+ +
+
+ +

◆ kDaikin152FanTemp

+ +
+
+ + + + +
const uint8_t kDaikin152FanTemp = 0x60
+
+ +
+
+ +

◆ kDaikin152Freq

+ +
+
+ + + + +
const uint16_t kDaikin152Freq = 38000
+
+ +
+
+ +

◆ kDaikin152Gap

+ +
+
+ + + + +
const uint16_t kDaikin152Gap = 25182
+
+ +
+
+ +

◆ kDaikin152HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin152HdrMark = 3492
+
+ +
+
+ +

◆ kDaikin152HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin152HdrSpace = 1718
+
+ +
+
+ +

◆ kDaikin152LeaderBits

+ +
+
+ + + + +
const uint8_t kDaikin152LeaderBits = 5
+
+ +
+
+ +

◆ kDaikin152ModeByte

+ +
+
+ + + + +
const uint8_t kDaikin152ModeByte = 5
+
+ +
+
+ +

◆ kDaikin152OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin152OneSpace = 1529
+
+ +
+
+ +

◆ kDaikin152PowerByte

+ +
+
+ + + + +
const uint8_t kDaikin152PowerByte = kDaikin152ModeByte
+
+ +
+
+ +

◆ kDaikin152PowerfulByte

+ +
+
+ + + + +
const uint8_t kDaikin152PowerfulByte = kDaikin152QuietByte
+
+ +
+
+ +

◆ kDaikin152QuietByte

+ +
+
+ + + + +
const uint8_t kDaikin152QuietByte = 13
+
+ +
+
+ +

◆ kDaikin152SensorByte

+ +
+
+ + + + +
const uint8_t kDaikin152SensorByte = kDaikin152EconoByte
+
+ +
+
+ +

◆ kDaikin152SensorOffset

+ +
+
+ + + + +
const uint8_t kDaikin152SensorOffset = 3
+
+ +
+
+ +

◆ kDaikin152SwingVByte

+ +
+
+ + + + +
const uint8_t kDaikin152SwingVByte = kDaikin152FanByte
+
+ +
+
+ +

◆ kDaikin152TempByte

+ +
+
+ + + + +
const uint8_t kDaikin152TempByte = 6
+
+ +
+
+ +

◆ kDaikin152TempSize

+ +
+
+ + + + +
const uint8_t kDaikin152TempSize = 7
+
+ +
+
+ +

◆ kDaikin152ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin152ZeroSpace = kDaikin152BitMark
+
+ +
+
+ +

◆ kDaikin160BitMark

+ +
+
+ + + + +
const uint16_t kDaikin160BitMark = 342
+
+ +
+
+ +

◆ kDaikin160ByteFan

+ +
+
+ + + + +
const uint8_t kDaikin160ByteFan = 17
+
+ +
+
+ +

◆ kDaikin160ByteMode

+ +
+
+ + + + +
const uint8_t kDaikin160ByteMode = kDaikin160BytePower
+
+ +
+
+ +

◆ kDaikin160BytePower

+ +
+
+ + + + +
const uint8_t kDaikin160BytePower = 12
+
+ +
+
+ +

◆ kDaikin160ByteSwingV

+ +
+
+ + + + +
const uint8_t kDaikin160ByteSwingV = 13
+
+ +
+
+ +

◆ kDaikin160ByteTemp

+ +
+
+ + + + +
const uint8_t kDaikin160ByteTemp = 16
+
+ +
+
+ +

◆ kDaikin160Freq

+ +
+
+ + + + +
const uint16_t kDaikin160Freq = 38000
+
+ +
+
+ +

◆ kDaikin160Gap

+ +
+
+ + + + +
const uint16_t kDaikin160Gap = 29650
+
+ +
+
+ +

◆ kDaikin160HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin160HdrMark = 5000
+
+ +
+
+ +

◆ kDaikin160HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin160HdrSpace = 2145
+
+ +
+
+ +

◆ kDaikin160MaskFan

+ +
+
+ + + + +
const uint8_t kDaikin160MaskFan = 0b00001111
+
+ +
+
+ +

◆ kDaikin160MaskSwingV

+ +
+
+ + + + +
const uint8_t kDaikin160MaskSwingV = 0b11110000
+
+ +
+
+ +

◆ kDaikin160OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin160OneSpace = 1786
+
+ +
+
+ +

◆ kDaikin160Section1Length

+ +
+
+ + + + +
const uint16_t kDaikin160Section1Length = 7
+
+ +
+
+ +

◆ kDaikin160Section2Length

+ +
+
+ + + + +
const uint16_t kDaikin160Section2Length
+
+
+ +

◆ kDaikin160Sections

+ +
+
+ + + + +
const uint16_t kDaikin160Sections = 2
+
+ +
+
+ +

◆ kDaikin160SwingVAuto

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVAuto = 0xF
+
+ +
+
+ +

◆ kDaikin160SwingVHigh

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVHigh = 0x4
+
+ +
+
+ +

◆ kDaikin160SwingVHighest

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVHighest = 0x5
+
+ +
+
+ +

◆ kDaikin160SwingVLow

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVLow = 0x2
+
+ +
+
+ +

◆ kDaikin160SwingVLowest

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVLowest = 0x1
+
+ +
+
+ +

◆ kDaikin160SwingVMiddle

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVMiddle = 0x3
+
+ +
+
+ +

◆ kDaikin160TempOffset

+ +
+
+ + + + +
const uint8_t kDaikin160TempOffset = 1
+
+ +
+
+ +

◆ kDaikin160TempSize

+ +
+
+ + + + +
const uint8_t kDaikin160TempSize = 6
+
+ +
+
+ +

◆ kDaikin160ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin160ZeroSpace = 700
+
+ +
+
+ +

◆ kDaikin176BitMark

+ +
+
+ + + + +
const uint16_t kDaikin176BitMark = 370
+
+ +
+
+ +

◆ kDaikin176ByteFan

+ +
+
+ + + + +
const uint8_t kDaikin176ByteFan = 18
+
+ +
+
+ +

◆ kDaikin176ByteMode

+ +
+
+ + + + +
const uint8_t kDaikin176ByteMode = 12
+
+ +
+
+ +

◆ kDaikin176ByteModeButton

+ +
+
+ + + + +
const uint8_t kDaikin176ByteModeButton = 13
+
+ +
+
+ +

◆ kDaikin176BytePower

+ +
+
+ + + + +
const uint8_t kDaikin176BytePower = 14
+
+ +
+
+ +

◆ kDaikin176ByteSwingH

+ +
+
+ + + + +
const uint8_t kDaikin176ByteSwingH = 18
+
+ +
+
+ +

◆ kDaikin176ByteTemp

+ +
+
+ + + + +
const uint8_t kDaikin176ByteTemp = 17
+
+ +
+
+ +

◆ kDaikin176Cool

+ +
+
+ + + + +
const uint8_t kDaikin176Cool = 0b111
+
+ +
+
+ +

◆ kDaikin176DryFanTemp

+ +
+
+ + + + +
const uint8_t kDaikin176DryFanTemp = 17
+
+ +
+
+ +

◆ kDaikin176FanMax

+ +
+
+ + + + +
const uint8_t kDaikin176FanMax = 3
+
+ +
+
+ +

◆ kDaikin176Freq

+ +
+
+ + + + +
const uint16_t kDaikin176Freq = 38000
+
+ +
+
+ +

◆ kDaikin176Gap

+ +
+
+ + + + +
const uint16_t kDaikin176Gap = 29410
+
+ +
+
+ +

◆ kDaikin176HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin176HdrMark = 5070
+
+ +
+
+ +

◆ kDaikin176HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin176HdrSpace = 2140
+
+ +
+
+ +

◆ kDaikin176MaskFan

+ +
+
+ + + + +
const uint8_t kDaikin176MaskFan = 0b11110000
+
+ +
+
+ +

◆ kDaikin176MaskMode

+ +
+
+ + + + +
const uint8_t kDaikin176MaskMode = 0b01110000
+
+ +
+
+ +

◆ kDaikin176ModeButton

+ +
+
+ + + + +
const uint8_t kDaikin176ModeButton = 0b00000100
+
+ +
+
+ +

◆ kDaikin176OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin176OneSpace = 1780
+
+ +
+
+ +

◆ kDaikin176Section1Length

+ +
+
+ + + + +
const uint16_t kDaikin176Section1Length = 7
+
+ +
+
+ +

◆ kDaikin176Section2Length

+ +
+
+ + + + +
const uint16_t kDaikin176Section2Length
+
+
+ +

◆ kDaikin176Sections

+ +
+
+ + + + +
const uint16_t kDaikin176Sections = 2
+
+ +
+
+ +

◆ kDaikin176SwingHAuto

+ +
+
+ + + + +
const uint8_t kDaikin176SwingHAuto = 0x5
+
+ +
+
+ +

◆ kDaikin176SwingHOff

+ +
+
+ + + + +
const uint8_t kDaikin176SwingHOff = 0x6
+
+ +
+
+ +

◆ kDaikin176TempOffset

+ +
+
+ + + + +
const uint8_t kDaikin176TempOffset = 1
+
+ +
+
+ +

◆ kDaikin176TempSize

+ +
+
+ + + + +
const uint8_t kDaikin176TempSize = 6
+
+ +
+
+ +

◆ kDaikin176ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin176ZeroSpace = 710
+
+ +
+
+ +

◆ kDaikin216BitMark

+ +
+
+ + + + +
const uint16_t kDaikin216BitMark = 420
+
+ +
+
+ +

◆ kDaikin216ByteFan

+ +
+
+ + + + +
const uint8_t kDaikin216ByteFan = 16
+
+ +
+
+ +

◆ kDaikin216ByteMode

+ +
+
+ + + + +
const uint8_t kDaikin216ByteMode = kDaikin216BytePower
+
+ +
+
+ +

◆ kDaikin216BytePower

+ +
+
+ + + + +
const uint8_t kDaikin216BytePower = 13
+
+ +
+
+ +

◆ kDaikin216BytePowerful

+ +
+
+ + + + +
const uint8_t kDaikin216BytePowerful = 21
+
+ +
+
+ +

◆ kDaikin216ByteSwingH

+ +
+
+ + + + +
const uint8_t kDaikin216ByteSwingH = 17
+
+ +
+
+ +

◆ kDaikin216ByteSwingV

+ +
+
+ + + + +
const uint8_t kDaikin216ByteSwingV = 16
+
+ +
+
+ +

◆ kDaikin216ByteTemp

+ +
+
+ + + + +
const uint8_t kDaikin216ByteTemp = 14
+
+ +
+
+ +

◆ kDaikin216Freq

+ +
+
+ + + + +
const uint16_t kDaikin216Freq = 38000
+
+ +
+
+ +

◆ kDaikin216Gap

+ +
+
+ + + + +
const uint16_t kDaikin216Gap = 29650
+
+ +
+
+ +

◆ kDaikin216HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin216HdrMark = 3440
+
+ +
+
+ +

◆ kDaikin216HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin216HdrSpace = 1750
+
+ +
+
+ +

◆ kDaikin216MaskFan

+ +
+
+ + + + +
const uint8_t kDaikin216MaskFan = 0b11110000
+
+ +
+
+ +

◆ kDaikin216OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin216OneSpace = 1300
+
+ +
+
+ +

◆ kDaikin216Section1Length

+ +
+
+ + + + +
const uint16_t kDaikin216Section1Length = 8
+
+ +
+
+ +

◆ kDaikin216Section2Length

+ +
+
+ + + + +
const uint16_t kDaikin216Section2Length
+
+
+ +

◆ kDaikin216Sections

+ +
+
+ + + + +
const uint16_t kDaikin216Sections = 2
+
+ +
+
+ +

◆ kDaikin216SwingOff

+ +
+
+ + + + +
const uint8_t kDaikin216SwingOff = 0b0000
+
+ +
+
+ +

◆ kDaikin216SwingOn

+ +
+
+ + + + +
const uint8_t kDaikin216SwingOn = 0b1111
+
+ +
+
+ +

◆ kDaikin216SwingSize

+ +
+
+ + + + +
const uint8_t kDaikin216SwingSize = 4
+
+ +
+
+ +

◆ kDaikin216TempOffset

+ +
+
+ + + + +
const uint8_t kDaikin216TempOffset = 1
+
+ +
+
+ +

◆ kDaikin216TempSize

+ +
+
+ + + + +
const uint8_t kDaikin216TempSize = 6
+
+ +
+
+ +

◆ kDaikin216ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin216ZeroSpace = 450
+
+ +
+
+ +

◆ kDaikin2BeepOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BeepOffset = 6
+
+ +
+
+ +

◆ kDaikin2BeepSize

+ +
+
+ + + + +
const uint8_t kDaikin2BeepSize = 2
+
+ +
+
+ +

◆ kDaikin2BitClean

+ +
+
+ + + + +
const uint8_t kDaikin2BitClean = 1 << kDaikin2BitCleanOffset
+
+ +
+
+ +

◆ kDaikin2BitCleanOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitCleanOffset = 5
+
+ +
+
+ +

◆ kDaikin2BitEye

+ +
+
+ + + + +
const uint8_t kDaikin2BitEye = 1 << kDaikin2BitEyeOffset
+
+ +
+
+ +

◆ kDaikin2BitEyeAuto

+ +
+
+ + + + +
const uint8_t kDaikin2BitEyeAuto = 1 << kDaikin2BitEyeAutoOffset
+
+ +
+
+ +

◆ kDaikin2BitEyeAutoOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitEyeAutoOffset = 7
+
+ +
+
+ +

◆ kDaikin2BitEyeOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitEyeOffset = 1
+
+ +
+
+ +

◆ kDaikin2BitFreshAir

+ +
+
+ + + + +
const uint8_t kDaikin2BitFreshAir = 1 << kDaikin2BitFreshAirOffset
+
+ +
+
+ +

◆ kDaikin2BitFreshAirHigh

+ +
+
+ + + + +
const uint8_t kDaikin2BitFreshAirHigh = 1 << kDaikin2BitFreshAirHighOffset
+
+ +
+
+ +

◆ kDaikin2BitFreshAirHighOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitFreshAirHighOffset = 7
+
+ +
+
+ +

◆ kDaikin2BitFreshAirOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitFreshAirOffset = 0
+
+ +
+
+ +

◆ kDaikin2BitMark

+ +
+
+ + + + +
const uint16_t kDaikin2BitMark = 460
+
+ +
+
+ +

◆ kDaikin2BitMold

+ +
+
+ + + + +
const uint8_t kDaikin2BitMold = 1 << kDaikin2BitMoldOffset
+
+ +
+
+ +

◆ kDaikin2BitMoldOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitMoldOffset = 3
+
+ +
+
+ +

◆ kDaikin2BitPower

+ +
+
+ + + + +
const uint8_t kDaikin2BitPower = 1 << kDaikin2BitPowerOffset
+
+ +
+
+ +

◆ kDaikin2BitPowerOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitPowerOffset = 7
+
+ +
+
+ +

◆ kDaikin2BitPurify

+ +
+
+ + + + +
const uint8_t kDaikin2BitPurify = 1 << kDaikin2BitPurifyOffset
+
+ +
+
+ +

◆ kDaikin2BitPurifyOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitPurifyOffset = 4
+
+ +
+
+ +

◆ kDaikin2BitSleepTimer

+ +
+
+ + + + +
const uint8_t kDaikin2BitSleepTimer = 1 << kDaikin2BitSleepTimerOffset
+
+ +
+
+ +

◆ kDaikin2BitSleepTimerOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitSleepTimerOffset = 5
+
+ +
+
+ +

◆ kDaikin2FanByte

+ +
+
+ + + + +
const uint8_t kDaikin2FanByte = 28
+
+ +
+
+ +

◆ kDaikin2Freq

+ +
+
+ + + + +
const uint16_t kDaikin2Freq = 36700
+
+ +
+
+ +

◆ kDaikin2Gap

+ +
+
+ + + + +
const uint16_t kDaikin2Gap = kDaikin2LeaderMark + kDaikin2LeaderSpace
+
+ +
+
+ +

◆ kDaikin2HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin2HdrMark = 3500
+
+ +
+
+ +

◆ kDaikin2HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin2HdrSpace = 1728
+
+ +
+
+ +

◆ kDaikin2LeaderMark

+ +
+
+ + + + +
const uint16_t kDaikin2LeaderMark = 10024
+
+ +
+
+ +

◆ kDaikin2LeaderSpace

+ +
+
+ + + + +
const uint16_t kDaikin2LeaderSpace = 25180
+
+ +
+
+ +

◆ kDaikin2LightOffset

+ +
+
+ + + + +
const uint8_t kDaikin2LightOffset = 4
+
+ +
+
+ +

◆ kDaikin2LightSize

+ +
+
+ + + + +
const uint8_t kDaikin2LightSize = 2
+
+ +
+
+ +

◆ kDaikin2MinCoolTemp

+ +
+
+ + + + +
const uint8_t kDaikin2MinCoolTemp = 18
+
+ +
+
+ +

◆ kDaikin2OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin2OneSpace = 1270
+
+ +
+
+ +

◆ kDaikin2Section1Length

+ +
+
+ + + + +
const uint16_t kDaikin2Section1Length = 20
+
+ +
+
+ +

◆ kDaikin2Section2Length

+ +
+
+ + + + +
const uint16_t kDaikin2Section2Length = 19
+
+ +
+
+ +

◆ kDaikin2Sections

+ +
+
+ + + + +
const uint16_t kDaikin2Sections = 2
+
+ +
+
+ +

◆ kDaikin2SwingHAuto

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHAuto = 0xBE
+
+ +
+
+ +

◆ kDaikin2SwingHLeft

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHLeft = 0xA9
+
+ +
+
+ +

◆ kDaikin2SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHLeftMax = 0xA8
+
+ +
+
+ +

◆ kDaikin2SwingHMiddle

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHMiddle = 0xAA
+
+ +
+
+ +

◆ kDaikin2SwingHRight

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHRight = 0xAB
+
+ +
+
+ +

◆ kDaikin2SwingHRightMax

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHRightMax = 0xAC
+
+ +
+
+ +

◆ kDaikin2SwingHSwing

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHSwing = 0xBF
+
+ +
+
+ +

◆ kDaikin2SwingHWide

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHWide = 0xA3
+
+ +
+
+ +

◆ kDaikin2SwingVAuto

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVAuto = 0xE
+
+ +
+
+ +

◆ kDaikin2SwingVBreeze

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVBreeze = 0xC
+
+ +
+
+ +

◆ kDaikin2SwingVCirculate

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVCirculate = 0xD
+
+ +
+
+ +

◆ kDaikin2SwingVHigh

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVHigh = 0x1
+
+ +
+
+ +

◆ kDaikin2SwingVLow

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVLow = 0x6
+
+ +
+
+ +

◆ kDaikin2SwingVSwing

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVSwing = 0xF
+
+ +
+
+ +

◆ kDaikin2Tolerance

+ +
+
+ + + + +
const uint8_t kDaikin2Tolerance = 5
+
+ +
+
+ +

◆ kDaikin2ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin2ZeroSpace = 420
+
+ +
+
+ +

◆ kDaikin64BitMark

+ +
+
+ + + + +
const uint16_t kDaikin64BitMark = kDaikin128BitMark
+
+ +
+
+ +

◆ kDaikin64ChecksumOffset

+ +
+
+ + + + +
const uint8_t kDaikin64ChecksumOffset = 60
+
+ +
+
+ +

◆ kDaikin64ChecksumSize

+ +
+
+ + + + +
const uint8_t kDaikin64ChecksumSize = 4
+
+ +
+
+ +

◆ kDaikin64ClockHoursSize

+ +
+
+ + + + +
const uint8_t kDaikin64ClockHoursSize = 8
+
+ +
+
+ +

◆ kDaikin64ClockMinsSize

+ +
+
+ + + + +
const uint8_t kDaikin64ClockMinsSize = 8
+
+ +
+
+ +

◆ kDaikin64ClockOffset

+ +
+
+ + + + +
const uint8_t kDaikin64ClockOffset = kDaikin64FanOffset + kDaikin64FanSize
+
+ +
+
+ +

◆ kDaikin64ClockSize

+ +
+
+ + + + +
const uint8_t kDaikin64ClockSize
+
+
+ +

◆ kDaikin64Cool

+ +
+
+ + + + +
const uint8_t kDaikin64Cool = 0b010
+
+ +
+
+ +

◆ kDaikin64Dry

+ +
+
+ + + + +
const uint8_t kDaikin64Dry = 0b001
+
+ +
+
+ +

◆ kDaikin64Fan

+ +
+
+ + + + +
const uint8_t kDaikin64Fan = 0b100
+
+ +
+
+ +

◆ kDaikin64FanAuto

+ +
+
+ + + + +
const uint8_t kDaikin64FanAuto = 0b0001
+
+ +
+
+ +

◆ kDaikin64FanHigh

+ +
+
+ + + + +
const uint8_t kDaikin64FanHigh = 0b0010
+
+ +
+
+ +

◆ kDaikin64FanLow

+ +
+
+ + + + +
const uint8_t kDaikin64FanLow = 0b1000
+
+ +
+
+ +

◆ kDaikin64FanMed

+ +
+
+ + + + +
const uint8_t kDaikin64FanMed = 0b0100
+
+ +
+
+ +

◆ kDaikin64FanOffset

+ +
+
+ + + + +
const uint8_t kDaikin64FanOffset = kDaikin64ModeOffset + kDaikin64ModeSize
+
+ +
+
+ +

◆ kDaikin64FanQuiet

+ +
+
+ + + + +
const uint8_t kDaikin64FanQuiet = 0b1001
+
+ +
+
+ +

◆ kDaikin64FanSize

+ +
+
+ + + + +
const uint8_t kDaikin64FanSize = 4
+
+ +
+
+ +

◆ kDaikin64FanTurbo

+ +
+
+ + + + +
const uint8_t kDaikin64FanTurbo = 0b0011
+
+ +
+
+ +

◆ kDaikin64Freq

+ +
+
+ + + + +
const uint16_t kDaikin64Freq = kDaikin128Freq
+
+ +
+
+ +

◆ kDaikin64Gap

+ +
+
+ + + + +
const uint16_t kDaikin64Gap = kDaikin128Gap
+
+ +
+
+ +

◆ kDaikin64HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin64HdrMark = kDaikin128HdrMark
+
+ +
+
+ +

◆ kDaikin64HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin64HdrSpace = kDaikin128HdrSpace
+
+ +
+
+ +

◆ kDaikin64KnownGoodState

+ +
+
+ + + + +
const uint64_t kDaikin64KnownGoodState = 0x7C16161607204216
+
+ +
+
+ +

◆ kDaikin64LdrMark

+ +
+
+ + + + +
const uint16_t kDaikin64LdrMark = kDaikin128LeaderMark
+
+ +
+
+ +

◆ kDaikin64LdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin64LdrSpace = kDaikin128LeaderSpace
+
+ +
+
+ +

◆ kDaikin64MaxTemp

+ +
+
+ + + + +
const uint8_t kDaikin64MaxTemp = 30
+
+ +
+
+ +

◆ kDaikin64MinTemp

+ +
+
+ + + + +
const uint8_t kDaikin64MinTemp = 16
+
+ +
+
+ +

◆ kDaikin64ModeOffset

+ +
+
+ + + + +
const uint8_t kDaikin64ModeOffset = 8
+
+ +
+
+ +

◆ kDaikin64ModeSize

+ +
+
+ + + + +
const uint8_t kDaikin64ModeSize = 4
+
+ +
+
+ +

◆ kDaikin64OffTimeEnableBit

+ +
+
+ + + + +
const uint8_t kDaikin64OffTimeEnableBit = kDaikin64OffTimeHalfHourBit + 1
+
+ +
+
+ +

◆ kDaikin64OffTimeHalfHourBit

+ +
+
+ + + + +
const uint8_t kDaikin64OffTimeHalfHourBit
+
+
+ +

◆ kDaikin64OffTimeOffset

+ +
+
+ + + + +
const uint8_t kDaikin64OffTimeOffset = kDaikin64OnTimeEnableBit + 1
+
+ +
+
+ +

◆ kDaikin64OffTimeSize

+ +
+
+ + + + +
const uint8_t kDaikin64OffTimeSize = 6
+
+ +
+
+ +

◆ kDaikin64OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin64OneSpace = kDaikin128OneSpace
+
+ +
+
+ +

◆ kDaikin64OnTimeEnableBit

+ +
+
+ + + + +
const uint8_t kDaikin64OnTimeEnableBit = kDaikin64OnTimeHalfHourBit + 1
+
+ +
+
+ +

◆ kDaikin64OnTimeHalfHourBit

+ +
+
+ + + + +
const uint8_t kDaikin64OnTimeHalfHourBit
+
+Initial value: +
+
+ +

◆ kDaikin64OnTimeOffset

+ +
+
+ + + + +
const uint8_t kDaikin64OnTimeOffset
+
+Initial value: +
+
+ +

◆ kDaikin64OnTimeSize

+ +
+
+ + + + +
const uint8_t kDaikin64OnTimeSize = 6
+
+ +
+
+ +

◆ kDaikin64Overhead

+ +
+
+ + + + +
const uint8_t kDaikin64Overhead = 9
+
+ +
+
+ +

◆ kDaikin64PowerToggleBit

+ +
+
+ + + + +
const uint8_t kDaikin64PowerToggleBit = 59
+
+ +
+
+ +

◆ kDaikin64SleepBit

+ +
+
+ + + + +
const uint8_t kDaikin64SleepBit = kDaikin64SwingVBit + 1
+
+ +
+
+ +

◆ kDaikin64SwingVBit

+ +
+
+ + + + +
const uint8_t kDaikin64SwingVBit = 56
+
+ +
+
+ +

◆ kDaikin64TempOffset

+ +
+
+ + + + +
const uint8_t kDaikin64TempOffset = 48
+
+ +
+
+ +

◆ kDaikin64TempSize

+ +
+
+ + + + +
const uint8_t kDaikin64TempSize = 8
+
+ +
+
+ +

◆ kDaikin64ToleranceDelta

+ +
+
+ + + + +
const int8_t kDaikin64ToleranceDelta = 5
+
+ +
+
+ +

◆ kDaikin64ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin64ZeroSpace = kDaikin128ZeroSpace
+
+ +
+
+ +

◆ kDaikinAuto

+ +
+
+ + + + +
const uint8_t kDaikinAuto = 0b000
+
+ +
+
+ +

◆ kDaikinBeepLoud

+ +
+
+ + + + +
const uint8_t kDaikinBeepLoud = 2
+
+ +
+
+ +

◆ kDaikinBeepOff

+ +
+
+ + + + +
const uint8_t kDaikinBeepOff = 3
+
+ +
+
+ +

◆ kDaikinBeepQuiet

+ +
+
+ + + + +
const uint8_t kDaikinBeepQuiet = 1
+
+ +
+
+ +

◆ kDaikinBitComfort

+ +
+
+ + + + +
const uint8_t kDaikinBitComfort = 1 << kDaikinBitComfortOffset
+
+ +
+
+ +

◆ kDaikinBitComfortOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitComfortOffset = 4
+
+ +
+
+ +

◆ kDaikinBitEcono

+ +
+
+ + + + +
const uint8_t kDaikinBitEcono = 1 << kDaikinBitEconoOffset
+
+ +
+
+ +

◆ kDaikinBitEconoOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitEconoOffset = 2
+
+ +
+
+ +

◆ kDaikinBitEye

+ +
+
+ + + + +
const uint8_t kDaikinBitEye = 0b10000000
+
+ +
+
+ +

◆ kDaikinBitMark

+ +
+
+ + + + +
const uint16_t kDaikinBitMark = 428
+
+ +
+
+ +

◆ kDaikinBitMold

+ +
+
+ + + + +
const uint8_t kDaikinBitMold = 1 << kDaikinBitMoldOffset
+
+ +
+
+ +

◆ kDaikinBitMoldOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitMoldOffset = 1
+
+ +
+
+ +

◆ kDaikinBitOffTimer

+ +
+
+ + + + +
const uint8_t kDaikinBitOffTimer = 1 << kDaikinBitOffTimerOffset
+
+ +
+
+ +

◆ kDaikinBitOffTimerOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitOffTimerOffset = 2
+
+ +
+
+ +

◆ kDaikinBitOnTimer

+ +
+
+ + + + +
const uint8_t kDaikinBitOnTimer = 1 << kDaikinBitOnTimerOffset
+
+ +
+
+ +

◆ kDaikinBitOnTimerOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitOnTimerOffset = 1
+
+ +
+
+ +

◆ kDaikinBitPower

+ +
+
+ + + + +
const uint8_t kDaikinBitPower = 1 << kDaikinBitPowerOffset
+
+ +
+
+ +

◆ kDaikinBitPowerful

+ +
+
+ + + + +
const uint8_t kDaikinBitPowerful = 1 << kDaikinBitPowerfulOffset
+
+ +
+
+ +

◆ kDaikinBitPowerfulOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitPowerfulOffset = 0
+
+ +
+
+ +

◆ kDaikinBitPowerOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitPowerOffset = 0
+
+ +
+
+ +

◆ kDaikinBitSensor

+ +
+
+ + + + +
const uint8_t kDaikinBitSensor = 1 << kDaikinBitSensorOffset
+
+ +
+
+ +

◆ kDaikinBitSensorOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitSensorOffset = 1
+
+ +
+
+ +

◆ kDaikinBitSilent

+ +
+
+ + + + +
const uint8_t kDaikinBitSilent = 1 << kDaikinBitSilentOffset
+
+ +
+
+ +

◆ kDaikinBitSilentOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitSilentOffset = 5
+
+ +
+
+ +

◆ kDaikinBitWeeklyTimer

+ +
+
+ + + + +
const uint8_t kDaikinBitWeeklyTimer = 1 << kDaikinBitWeeklyTimerOffset
+
+ +
+
+ +

◆ kDaikinBitWeeklyTimerOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitWeeklyTimerOffset = 7
+
+ +
+
+ +

◆ kDaikinByteChecksum1

+ +
+
+ + + + +
const uint8_t kDaikinByteChecksum1 = 7
+
+ +
+
+ +

◆ kDaikinByteChecksum2

+ +
+
+ + + + +
const uint8_t kDaikinByteChecksum2 = 15
+
+ +
+
+ +

◆ kDaikinByteChecksum3

+ +
+
+ + + + +
const uint8_t kDaikinByteChecksum3 = kDaikinStateLength - 1
+
+ +
+
+ +

◆ kDaikinByteClockMinsHigh

+ +
+
+ + + + +
const uint8_t kDaikinByteClockMinsHigh = 14
+
+ +
+
+ +

◆ kDaikinByteClockMinsLow

+ +
+
+ + + + +
const uint8_t kDaikinByteClockMinsLow = 13
+
+ +
+
+ +

◆ kDaikinByteComfort

+ +
+
+ + + + +
const uint8_t kDaikinByteComfort = 6
+
+ +
+
+ +

◆ kDaikinByteEcono

+ +
+
+ + + + +
const uint8_t kDaikinByteEcono = kDaikinByteSensor
+
+ +
+
+ +

◆ kDaikinByteEye

+ +
+
+ + + + +
const uint8_t kDaikinByteEye = kDaikinByteSensor
+
+ +
+
+ +

◆ kDaikinByteFan

+ +
+
+ + + + +
const uint8_t kDaikinByteFan = 24
+
+ +
+
+ +

◆ kDaikinByteMold

+ +
+
+ + + + +
const uint8_t kDaikinByteMold = 33
+
+ +
+
+ +

◆ kDaikinByteOffTimer

+ +
+
+ + + + +
const uint8_t kDaikinByteOffTimer = kDaikinBytePower
+
+ +
+
+ +

◆ kDaikinByteOffTimerMinsHigh

+ +
+
+ + + + +
const uint8_t kDaikinByteOffTimerMinsHigh = 28
+
+ +
+
+ +

◆ kDaikinByteOffTimerMinsLow

+ +
+
+ + + + +
const uint8_t kDaikinByteOffTimerMinsLow = kDaikinByteOnTimerMinsHigh
+
+ +
+
+ +

◆ kDaikinByteOnTimer

+ +
+
+ + + + +
const uint8_t kDaikinByteOnTimer = kDaikinByteOffTimer
+
+ +
+
+ +

◆ kDaikinByteOnTimerMinsHigh

+ +
+
+ + + + +
const uint8_t kDaikinByteOnTimerMinsHigh = 27
+
+ +
+
+ +

◆ kDaikinByteOnTimerMinsLow

+ +
+
+ + + + +
const uint8_t kDaikinByteOnTimerMinsLow = 26
+
+ +
+
+ +

◆ kDaikinBytePower

+ +
+
+ + + + +
const uint8_t kDaikinBytePower = 21
+
+ +
+
+ +

◆ kDaikinBytePowerful

+ +
+
+ + + + +
const uint8_t kDaikinBytePowerful = 29
+
+ +
+
+ +

◆ kDaikinByteSensor

+ +
+
+ + + + +
const uint8_t kDaikinByteSensor = 32
+
+ +
+
+ +

◆ kDaikinByteSilent

+ +
+
+ + + + +
const uint8_t kDaikinByteSilent = kDaikinBytePowerful
+
+ +
+
+ +

◆ kDaikinByteSwingH

+ +
+
+ + + + +
const uint8_t kDaikinByteSwingH = 25
+
+ +
+
+ +

◆ kDaikinByteTemp

+ +
+
+ + + + +
const uint8_t kDaikinByteTemp = 22
+
+ +
+
+ +

◆ kDaikinByteWeeklyTimer

+ +
+
+ + + + +
const uint8_t kDaikinByteWeeklyTimer = kDaikinByteSensor
+
+ +
+
+ +

◆ kDaikinClockMinsHighOffset

+ +
+
+ + + + +
const uint8_t kDaikinClockMinsHighOffset = 0
+
+ +
+
+ +

◆ kDaikinClockMinsHighSize

+ +
+
+ + + + +
const uint8_t kDaikinClockMinsHighSize = 3
+
+ +
+
+ +

◆ kDaikinCool

+ +
+
+ + + + +
const uint8_t kDaikinCool = 0b011
+
+ +
+
+ +

◆ kDaikinCurBit

+ +
+
+ + + + +
const uint8_t kDaikinCurBit = kDaikinStateLength
+
+ +
+
+ +

◆ kDaikinCurIndex

+ +
+
+ + + + +
const uint8_t kDaikinCurIndex = kDaikinStateLength + 1
+
+ +
+
+ +

◆ kDaikinDoWOffset

+ +
+
+ + + + +
const uint8_t kDaikinDoWOffset = 3
+
+ +
+
+ +

◆ kDaikinDoWSize

+ +
+
+ + + + +
const uint8_t kDaikinDoWSize = 3
+
+ +
+
+ +

◆ kDaikinDry

+ +
+
+ + + + +
const uint8_t kDaikinDry = 0b010
+
+ +
+
+ +

◆ kDaikinFan

+ +
+
+ + + + +
const uint8_t kDaikinFan = 0b110
+
+ +
+
+ +

◆ kDaikinFanAuto

+ +
+
+ + + + +
const uint8_t kDaikinFanAuto = 0b1010
+
+ +
+
+ +

◆ kDaikinFanMax

+ +
+
+ + + + +
const uint8_t kDaikinFanMax = 5
+
+ +
+
+ +

◆ kDaikinFanMed

+ +
+
+ + + + +
const uint8_t kDaikinFanMed = 3
+
+ +
+
+ +

◆ kDaikinFanMin

+ +
+
+ + + + +
const uint8_t kDaikinFanMin = 1
+
+ +
+
+ +

◆ kDaikinFanOffset

+ +
+
+ + + + +
const uint8_t kDaikinFanOffset = 4
+
+ +
+
+ +

◆ kDaikinFanQuiet

+ +
+
+ + + + +
const uint8_t kDaikinFanQuiet = 0b1011
+
+ +
+
+ +

◆ kDaikinFanSize

+ +
+
+ + + + +
const uint8_t kDaikinFanSize = 4
+
+ +
+
+ +

◆ kDaikinFirstHeader64

+ +
+
+ + + + +
const uint64_t kDaikinFirstHeader64
+
+Initial value:
=
+
0b1101011100000000000000001100010100000000001001111101101000010001
+
+
+
+ +

◆ kDaikinGap

+ +
+
+ + + + +
const uint16_t kDaikinGap = 29000
+
+ +
+
+ +

◆ kDaikinHdrMark

+ +
+
+ + + + +
const uint16_t kDaikinHdrMark = 3650
+
+ +
+
+ +

◆ kDaikinHdrSpace

+ +
+
+ + + + +
const uint16_t kDaikinHdrSpace = 1623
+
+ +
+
+ +

◆ kDaikinHeaderLength

+ +
+
+ + + + +
const uint16_t kDaikinHeaderLength = 5
+
+ +
+
+ +

◆ kDaikinHeat

+ +
+
+ + + + +
const uint8_t kDaikinHeat = 0b100
+
+ +
+
+ +

◆ kDaikinLightBright

+ +
+
+ + + + +
const uint8_t kDaikinLightBright = 1
+
+ +
+
+ +

◆ kDaikinLightDim

+ +
+
+ + + + +
const uint8_t kDaikinLightDim = 2
+
+ +
+
+ +

◆ kDaikinLightOff

+ +
+
+ + + + +
const uint8_t kDaikinLightOff = 3
+
+ +
+
+ +

◆ kDaikinMarkExcess

+ +
+
+ + + + +
const uint16_t kDaikinMarkExcess = kMarkExcess
+
+ +
+
+ +

◆ kDaikinMaxTemp

+ +
+
+ + + + +
const uint8_t kDaikinMaxTemp = 32
+
+ +
+
+ +

◆ kDaikinMinTemp

+ +
+
+ + + + +
const uint8_t kDaikinMinTemp = 10
+
+ +
+
+ +

◆ kDaikinModeOffset

+ +
+
+ + + + +
const uint8_t kDaikinModeOffset = 4
+
+ +
+
+ +

◆ kDaikinModeSize

+ +
+
+ + + + +
const uint8_t kDaikinModeSize = 3
+
+ +
+
+ +

◆ kDaikinOneSpace

+ +
+
+ + + + +
const uint16_t kDaikinOneSpace = 1280
+
+ +
+
+ +

◆ kDaikinOnTimerMinsHighOffset

+ +
+
+ + + + +
const uint8_t kDaikinOnTimerMinsHighOffset = 0
+
+ +
+
+ +

◆ kDaikinOnTimerMinsHighSize

+ +
+
+ + + + +
const uint8_t kDaikinOnTimerMinsHighSize = 4
+
+ +
+
+ +

◆ kDaikinSection1Length

+ +
+
+ + + + +
const uint8_t kDaikinSection1Length = 8
+
+ +
+
+ +

◆ kDaikinSection2Length

+ +
+
+ + + + +
const uint8_t kDaikinSection2Length = 8
+
+ +
+
+ +

◆ kDaikinSection3Length

+ +
+
+ + + + +
const uint8_t kDaikinSection3Length
+
+
+ +

◆ kDaikinSections

+ +
+
+ + + + +
const uint8_t kDaikinSections = 3
+
+ +
+
+ +

◆ kDaikinSwingOff

+ +
+
+ + + + +
const uint8_t kDaikinSwingOff = 0b0000
+
+ +
+
+ +

◆ kDaikinSwingOffset

+ +
+
+ + + + +
const uint8_t kDaikinSwingOffset = 0
+
+ +
+
+ +

◆ kDaikinSwingOn

+ +
+
+ + + + +
const uint8_t kDaikinSwingOn = 0b1111
+
+ +
+
+ +

◆ kDaikinSwingSize

+ +
+
+ + + + +
const uint8_t kDaikinSwingSize = 4
+
+ +
+
+ +

◆ kDaikinTempOffset

+ +
+
+ + + + +
const uint8_t kDaikinTempOffset = 1
+
+ +
+
+ +

◆ kDaikinTempSize

+ +
+
+ + + + +
const uint8_t kDaikinTempSize = 6
+
+ +
+
+ +

◆ kDaikinTolerance

+ +
+
+ + + + +
const uint8_t kDaikinTolerance = 35
+
+ +
+
+ +

◆ kDaikinUnusedTime

+ +
+
+ + + + +
const uint16_t kDaikinUnusedTime = 0x600
+
+ +
+
+ +

◆ kDaikinZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikinZeroSpace = 428
+
+ +
+
+
+
const uint8_t kDaikin64OnTimeOffset
Definition: ir_Daikin.h:485
+
const uint16_t kDaikin176StateLength
Definition: IRremoteESP8266.h:855
+
const uint8_t kDaikin64ClockOffset
Definition: ir_Daikin.h:480
+
const uint8_t kDaikinSection1Length
Definition: ir_Daikin.h:139
+
const uint8_t kDaikin64OffTimeOffset
Definition: ir_Daikin.h:491
+
const uint8_t kDaikin64ClockSize
Definition: ir_Daikin.h:483
+
const uint16_t kDaikin216StateLength
Definition: IRremoteESP8266.h:858
+
const uint16_t kDaikin216Section1Length
Definition: ir_Daikin.h:282
+
const uint16_t kDaikin160Section1Length
Definition: ir_Daikin.h:312
+
const uint8_t kDaikin64OnTimeSize
Definition: ir_Daikin.h:487
+
const uint16_t kDaikinStateLength
Definition: IRremoteESP8266.h:836
+
const uint16_t kDaikin160StateLength
Definition: IRremoteESP8266.h:846
+
const uint8_t kDaikinSection2Length
Definition: ir_Daikin.h:140
+
const uint8_t kDaikin64ClockHoursSize
Definition: ir_Daikin.h:482
+
const uint16_t kDaikin176Section1Length
Definition: ir_Daikin.h:342
+
const uint8_t kDaikin64ClockMinsSize
Definition: ir_Daikin.h:481
+
const uint8_t kDaikin64OffTimeSize
Definition: ir_Daikin.h:492
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h_source.html new file mode 100644 index 000000000..f557d4dd2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h_source.html @@ -0,0 +1,1801 @@ + + + + + + + +IRremoteESP8266: src/ir_Daikin.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Daikin.h
+
+
+Go to the documentation of this file.
1 // Copyright 2016 sillyfrog
+
2 // Copyright 2017 sillyfrog, crankyoldgit
+
3 // Copyright 2018-2020 crankyoldgit
+
4 // Copyright 2019 pasna (IRDaikin160 class / Daikin176 class)
+
5 
+
23 
+
24 // Supports:
+
25 // Brand: Daikin, Model: ARC433** remote (DAIKIN)
+
26 // Brand: Daikin, Model: ARC477A1 remote (DAIKIN2)
+
27 // Brand: Daikin, Model: FTXZ25NV1B A/C (DAIKIN2)
+
28 // Brand: Daikin, Model: FTXZ35NV1B A/C (DAIKIN2)
+
29 // Brand: Daikin, Model: FTXZ50NV1B A/C (DAIKIN2)
+
30 // Brand: Daikin, Model: ARC433B69 remote (DAIKIN216)
+
31 // Brand: Daikin, Model: ARC423A5 remote (DAIKIN160)
+
32 // Brand: Daikin, Model: FTE12HV2S A/C
+
33 // Brand: Daikin, Model: BRC4C153 remote (DAIKIN176)
+
34 // Brand: Daikin, Model: 17 Series A/C (DAIKIN128)
+
35 // Brand: Daikin, Model: FTXB12AXVJU A/C (DAIKIN128)
+
36 // Brand: Daikin, Model: FTXB09AXVJU A/C (DAIKIN128)
+
37 // Brand: Daikin, Model: BRC52B63 remote (DAIKIN128)
+
38 // Brand: Daikin, Model: ARC480A5 remote (DAIKIN152)
+
39 // Brand: Daikin, Model: FFN-C/FCN-F Series A/C (DAIKIN64)
+
40 // Brand: Daikin, Model: DGS01 remote (DAIKIN64)
+
41 // Brand: Daikin, Model: M Series A/C (DAIKIN)
+
42 // Brand: Daikin, Model: FTXM-M A/C (DAIKIN)
+
43 // Brand: Daikin, Model: ARC466A33 remote (DAIKIN)
+
44 
+
45 #ifndef IR_DAIKIN_H_
+
46 #define IR_DAIKIN_H_
+
47 
+
48 #ifndef UNIT_TEST
+
49 #include <Arduino.h>
+
50 #endif
+
51 #include "IRrecv.h"
+
52 #include "IRremoteESP8266.h"
+
53 #include "IRsend.h"
+
54 #ifdef UNIT_TEST
+
55 #include "IRsend_test.h"
+
56 #endif
+
57 
+
58 /*
+
59  Daikin AC map (i.e. DAIKIN, not the other variants)
+
60  byte 6=
+
61  b4:Comfort
+
62  byte 7= checksum of the first part (and last byte before a 29ms pause)
+
63  byte 13=Current time, mins past midnight, low bits
+
64  byte 14
+
65  b5-b3=Day of the week (SUN=1, MON=2, ..., SAT=7)
+
66  b2-b0=Current time, mins past midnight, high bits
+
67  byte 15= checksum of the second part (and last byte before a 29ms pause)
+
68  byte 21=mode
+
69  b7 = 0
+
70  b6+b5+b4 = Mode
+
71  Modes: b6+b5+b4
+
72  011 = Cool
+
73  100 = Heat (temp 23)
+
74  110 = FAN (temp not shown, but 25)
+
75  000 = Fully Automatic (temp 25)
+
76  010 = DRY (temp 0xc0 = 96 degrees c)
+
77  b3 = 1
+
78  b2 = OFF timer set
+
79  b1 = ON timer set
+
80  b0 = Air Conditioner ON
+
81  byte 22=temp*2 (Temp should be between 10 - 32)
+
82  byte 24=Fan
+
83  FAN control
+
84  b7+b6+b5+b4 = Fan speed
+
85  Fan: b7+b6+b5+b4
+
86  0×3 = 1 bar
+
87  0×4 = 2 bar
+
88  0×5 = 3 bar
+
89  0×6 = 4 bar
+
90  0×7 = 5 bar
+
91  0xa = Auto
+
92  0xb = Quite
+
93  b3+b2+b1+b0 = Swing control up/down
+
94  Swing control up/down:
+
95  0000 = Swing up/down off
+
96  1111 = Swing up/down on
+
97  byte 25
+
98  Swing control left/right:
+
99  0000 = Swing left/right off
+
100  1111 = Swing left/right on
+
101  byte 26=On timer mins past midnight, low bits
+
102  byte 27
+
103  b0-b3=On timer mins past midnight, high bits
+
104  b4-b7=Off timer mins past midnight, low bits
+
105  byte 28=Off timer mins past midnight, high bits
+
106  byte 29=Aux -> Powerful (bit 1), Silent (bit 5)
+
107  byte 32=Aux2
+
108  b1: Sensor
+
109  b2: Econo mode
+
110  b7: Intelligent eye on
+
111  byte 33=Aux3
+
112  b1: Mold Proof
+
113  byte 34= checksum of the third part
+
114 */
+
115 
+
116 // Constants
+
117 const uint8_t kDaikinAuto = 0b000;
+
118 const uint8_t kDaikinDry = 0b010;
+
119 const uint8_t kDaikinCool = 0b011;
+
120 const uint8_t kDaikinHeat = 0b100;
+
121 const uint8_t kDaikinFan = 0b110;
+
122 const uint8_t kDaikinModeOffset = 4;
+
123 const uint8_t kDaikinModeSize = 3;
+
124 const uint8_t kDaikinMinTemp = 10; // Celsius
+
125 const uint8_t kDaikinMaxTemp = 32; // Celsius
+
126 const uint8_t kDaikinFanMin = 1;
+
127 const uint8_t kDaikinFanMed = 3;
+
128 const uint8_t kDaikinFanMax = 5;
+
129 const uint8_t kDaikinFanAuto = 0b1010; // 10 / 0xA
+
130 const uint8_t kDaikinFanQuiet = 0b1011; // 11 / 0xB
+
131 const uint8_t kDaikinFanOffset = 4;
+
132 const uint8_t kDaikinFanSize = 4;
+
133 const uint8_t kDaikinSwingOffset = 0;
+
134 const uint8_t kDaikinSwingSize = 4;
+
135 const uint8_t kDaikinSwingOn = 0b1111;
+
136 const uint8_t kDaikinSwingOff = 0b0000;
+
137 const uint16_t kDaikinHeaderLength = 5;
+
138 const uint8_t kDaikinSections = 3;
+
139 const uint8_t kDaikinSection1Length = 8;
+
140 const uint8_t kDaikinSection2Length = 8;
+
141 const uint8_t kDaikinSection3Length =
+ +
143 const uint8_t kDaikinByteComfort = 6;
+
144 const uint8_t kDaikinByteChecksum1 = 7;
+
145 const uint8_t kDaikinBitComfortOffset = 4;
+ +
147 const uint8_t kDaikinByteClockMinsLow = 13;
+
148 const uint8_t kDaikinByteClockMinsHigh = 14;
+
149 const uint8_t kDaikinClockMinsHighOffset = 0;
+
150 const uint8_t kDaikinClockMinsHighSize = 3;
+
151 const uint8_t kDaikinDoWOffset = 3;
+
152 const uint8_t kDaikinDoWSize = 3;
+
153 const uint8_t kDaikinByteChecksum2 = 15;
+
154 const uint8_t kDaikinBytePower = 21;
+
155 const uint8_t kDaikinBitPowerOffset = 0;
+ +
157 const uint8_t kDaikinTempOffset = 1;
+
158 const uint8_t kDaikinTempSize = 6;
+
159 const uint8_t kDaikinByteTemp = 22;
+
160 const uint8_t kDaikinByteFan = 24;
+
161 const uint8_t kDaikinByteSwingH = 25;
+
162 const uint8_t kDaikinByteOnTimerMinsLow = 26;
+
163 const uint8_t kDaikinByteOnTimerMinsHigh = 27;
+ +
165 const uint8_t kDaikinOnTimerMinsHighSize = 4;
+ +
167 const uint8_t kDaikinByteOffTimerMinsHigh = 28;
+
168 const uint8_t kDaikinBytePowerful = 29;
+
169 const uint8_t kDaikinBitPowerfulOffset = 0;
+ + +
172 const uint8_t kDaikinBitSilentOffset = 5;
+ +
174 const uint8_t kDaikinByteSensor = 32;
+
175 const uint8_t kDaikinBitSensorOffset = 1;
+ + +
178 const uint8_t kDaikinBitEconoOffset = 2;
+ + +
181 const uint8_t kDaikinBitEye = 0b10000000;
+ +
183 const uint8_t kDaikinBitWeeklyTimerOffset = 7;
+ +
185 const uint8_t kDaikinByteMold = 33;
+
186 const uint8_t kDaikinBitMoldOffset = 1;
+ + +
189 const uint8_t kDaikinBitOffTimerOffset = 2;
+ + +
192 const uint8_t kDaikinBitOnTimerOffset = 1;
+ + +
195 const uint16_t kDaikinUnusedTime = 0x600;
+
196 const uint8_t kDaikinBeepQuiet = 1;
+
197 const uint8_t kDaikinBeepLoud = 2;
+
198 const uint8_t kDaikinBeepOff = 3;
+
199 const uint8_t kDaikinLightBright = 1;
+
200 const uint8_t kDaikinLightDim = 2;
+
201 const uint8_t kDaikinLightOff = 3;
+ + +
204 const uint8_t kDaikinTolerance = 35;
+ +
206 const uint16_t kDaikinHdrMark = 3650; // kDaikinBitMark * 8
+
207 const uint16_t kDaikinHdrSpace = 1623; // kDaikinBitMark * 4
+
208 const uint16_t kDaikinBitMark = 428;
+
209 const uint16_t kDaikinZeroSpace = 428;
+
210 const uint16_t kDaikinOneSpace = 1280;
+
211 const uint16_t kDaikinGap = 29000;
+
212 // Note bits in each octet swapped so can be sent as a single value
+
213 const uint64_t kDaikinFirstHeader64 =
+
214  0b1101011100000000000000001100010100000000001001111101101000010001;
+
215 
+
216 
+
217 const uint16_t kDaikin2Freq = 36700; // Modulation Frequency in Hz.
+
218 const uint16_t kDaikin2LeaderMark = 10024;
+
219 const uint16_t kDaikin2LeaderSpace = 25180;
+ +
221 const uint16_t kDaikin2HdrMark = 3500;
+
222 const uint16_t kDaikin2HdrSpace = 1728;
+
223 const uint16_t kDaikin2BitMark = 460;
+
224 const uint16_t kDaikin2OneSpace = 1270;
+
225 const uint16_t kDaikin2ZeroSpace = 420;
+
226 const uint16_t kDaikin2Sections = 2;
+
227 const uint16_t kDaikin2Section1Length = 20;
+
228 const uint16_t kDaikin2Section2Length = 19;
+
229 const uint8_t kDaikin2Tolerance = 5; // Extra percentage tolerance
+
230 const uint8_t kDaikin2BitSleepTimerOffset = 5;
+ +
232 const uint8_t kDaikin2BitPurifyOffset = 4;
+
233 const uint8_t kDaikin2BitPurify = 1 << kDaikin2BitPurifyOffset; // 0b00010000
+
234 const uint8_t kDaikin2BitEyeOffset = 1;
+
235 const uint8_t kDaikin2BitEye = 1 << kDaikin2BitEyeOffset; // 0b00000010
+
236 const uint8_t kDaikin2BitEyeAutoOffset = 7;
+
237 const uint8_t kDaikin2BitEyeAuto = 1 << kDaikin2BitEyeAutoOffset; // 0b10000000
+
238 const uint8_t kDaikin2BitMoldOffset = 3;
+
239 const uint8_t kDaikin2BitMold = 1 << kDaikin2BitMoldOffset; // 0b00001000
+
240 const uint8_t kDaikin2BitCleanOffset = 5; // Byte[8]
+
241 const uint8_t kDaikin2BitClean = 1 << kDaikin2BitCleanOffset; // 0b00100000
+
242 const uint8_t kDaikin2BitFreshAirOffset = 0;
+ + + +
246 const uint8_t kDaikin2BitPowerOffset = 7;
+
247 const uint8_t kDaikin2BitPower = 1 << kDaikin2BitPowerOffset; // 0b10000000
+
248 // const uint8_t kDaikin2LightMask = 0b00110000; // Byte[7]
+
249 const uint8_t kDaikin2LightOffset = 4; // Byte[7]
+
250 const uint8_t kDaikin2LightSize = 2;
+
251 // const uint8_t kDaikin2BeepMask = 0b11000000; // Byte[7]
+
252 const uint8_t kDaikin2BeepOffset = 6; // Byte[7]
+
253 const uint8_t kDaikin2BeepSize = 2;
+
254 const uint8_t kDaikin2SwingVHigh = 0x1;
+
255 const uint8_t kDaikin2SwingVLow = 0x6;
+
256 const uint8_t kDaikin2SwingVSwing = 0xF;
+
257 const uint8_t kDaikin2SwingVAuto = 0xE;
+
258 const uint8_t kDaikin2SwingVBreeze = 0xC;
+
259 const uint8_t kDaikin2SwingVCirculate = 0xD;
+
260 const uint8_t kDaikin2FanByte = 28;
+
261 
+
262 const uint8_t kDaikin2SwingHWide = 0xA3;
+
263 const uint8_t kDaikin2SwingHLeftMax = 0xA8;
+
264 const uint8_t kDaikin2SwingHLeft = 0xA9;
+
265 const uint8_t kDaikin2SwingHMiddle = 0xAA;
+
266 const uint8_t kDaikin2SwingHRight = 0xAB;
+
267 const uint8_t kDaikin2SwingHRightMax = 0xAC;
+
268 const uint8_t kDaikin2SwingHAuto = 0xBE;
+
269 const uint8_t kDaikin2SwingHSwing = 0xBF;
+
270 
+
271 const uint8_t kDaikin2MinCoolTemp = 18; // Min temp (in C) when in Cool mode.
+
272 
+
273 
+
274 const uint16_t kDaikin216Freq = 38000; // Modulation Frequency in Hz.
+
275 const uint16_t kDaikin216HdrMark = 3440;
+
276 const uint16_t kDaikin216HdrSpace = 1750;
+
277 const uint16_t kDaikin216BitMark = 420;
+
278 const uint16_t kDaikin216OneSpace = 1300;
+
279 const uint16_t kDaikin216ZeroSpace = 450;
+
280 const uint16_t kDaikin216Gap = 29650;
+
281 const uint16_t kDaikin216Sections = 2;
+
282 const uint16_t kDaikin216Section1Length = 8;
+ + +
285 const uint8_t kDaikin216BytePower = 13;
+ +
287 // const uint8_t kDaikin216MaskMode = 0b01110000;
+
288 const uint8_t kDaikin216ByteTemp = 14;
+
289 // const uint8_t kDaikin216MaskTemp = 0b01111110;
+
290 const uint8_t kDaikin216TempOffset = 1;
+
291 const uint8_t kDaikin216TempSize = 6;
+
292 
+
293 const uint8_t kDaikin216ByteFan = 16;
+
294 const uint8_t kDaikin216MaskFan = 0b11110000;
+
295 const uint8_t kDaikin216ByteSwingV = 16;
+
296 // const uint8_t kDaikin216MaskSwingV = 0b00001111;
+
297 const uint8_t kDaikin216SwingSize = 4;
+
298 const uint8_t kDaikin216SwingOn = 0b1111;
+
299 const uint8_t kDaikin216SwingOff = 0b0000;
+
300 const uint8_t kDaikin216ByteSwingH = 17;
+
301 const uint8_t kDaikin216BytePowerful = 21;
+
302 
+
303 
+
304 const uint16_t kDaikin160Freq = 38000; // Modulation Frequency in Hz.
+
305 const uint16_t kDaikin160HdrMark = 5000;
+
306 const uint16_t kDaikin160HdrSpace = 2145;
+
307 const uint16_t kDaikin160BitMark = 342;
+
308 const uint16_t kDaikin160OneSpace = 1786;
+
309 const uint16_t kDaikin160ZeroSpace = 700;
+
310 const uint16_t kDaikin160Gap = 29650;
+
311 const uint16_t kDaikin160Sections = 2;
+
312 const uint16_t kDaikin160Section1Length = 7;
+ + +
315 const uint8_t kDaikin160BytePower = 12;
+ +
317 // const uint8_t kDaikin160MaskMode = 0b01110000;
+
318 const uint8_t kDaikin160ByteTemp = 16;
+
319 // const uint8_t kDaikin160MaskTemp = 0b01111110;
+
320 const uint8_t kDaikin160TempOffset = 1;
+
321 const uint8_t kDaikin160TempSize = 6;
+
322 const uint8_t kDaikin160ByteFan = 17;
+
323 const uint8_t kDaikin160MaskFan = 0b00001111;
+
324 const uint8_t kDaikin160ByteSwingV = 13;
+
325 const uint8_t kDaikin160MaskSwingV = 0b11110000;
+
326 const uint8_t kDaikin160SwingVLowest = 0x1;
+
327 const uint8_t kDaikin160SwingVLow = 0x2;
+
328 const uint8_t kDaikin160SwingVMiddle = 0x3;
+
329 const uint8_t kDaikin160SwingVHigh = 0x4;
+
330 const uint8_t kDaikin160SwingVHighest = 0x5;
+
331 const uint8_t kDaikin160SwingVAuto = 0xF;
+
332 
+
333 
+
334 const uint16_t kDaikin176Freq = 38000; // Modulation Frequency in Hz.
+
335 const uint16_t kDaikin176HdrMark = 5070;
+
336 const uint16_t kDaikin176HdrSpace = 2140;
+
337 const uint16_t kDaikin176BitMark = 370;
+
338 const uint16_t kDaikin176OneSpace = 1780;
+
339 const uint16_t kDaikin176ZeroSpace = 710;
+
340 const uint16_t kDaikin176Gap = 29410;
+
341 const uint16_t kDaikin176Sections = 2;
+
342 const uint16_t kDaikin176Section1Length = 7;
+ + +
345 const uint8_t kDaikin176Cool = 0b111; // 7
+
346 const uint8_t kDaikin176BytePower = 14;
+
347 const uint8_t kDaikin176ByteMode = 12;
+
348 const uint8_t kDaikin176MaskMode = 0b01110000;
+
349 const uint8_t kDaikin176ByteModeButton = 13;
+
350 const uint8_t kDaikin176ModeButton = 0b00000100;
+
351 const uint8_t kDaikin176ByteTemp = 17;
+
352 // const uint8_t kDaikin176MaskTemp = 0b01111110;
+
353 const uint8_t kDaikin176TempOffset = 1;
+
354 const uint8_t kDaikin176TempSize = 6;
+
355 const uint8_t kDaikin176DryFanTemp = 17; // Dry/Fan mode is always 17 Celsius.
+
356 const uint8_t kDaikin176ByteFan = 18;
+
357 const uint8_t kDaikin176MaskFan = 0b11110000;
+
358 const uint8_t kDaikin176FanMax = 3;
+
359 const uint8_t kDaikin176ByteSwingH = 18;
+
360 // const uint8_t kDaikin176MaskSwingH = 0b00001111;
+
361 const uint8_t kDaikin176SwingHAuto = 0x5;
+
362 const uint8_t kDaikin176SwingHOff = 0x6;
+
363 
+
364 
+
365 const uint16_t kDaikin128Freq = 38000; // Modulation Frequency in Hz.
+
366 const uint16_t kDaikin128LeaderMark = 9800;
+
367 const uint16_t kDaikin128LeaderSpace = 9800;
+
368 const uint16_t kDaikin128HdrMark = 4600;
+
369 const uint16_t kDaikin128HdrSpace = 2500;
+
370 const uint16_t kDaikin128BitMark = 350;
+
371 const uint16_t kDaikin128OneSpace = 954;
+
372 const uint16_t kDaikin128ZeroSpace = 382;
+
373 const uint16_t kDaikin128Gap = 20300;
+ +
375 const uint16_t kDaikin128Sections = 2;
+
376 const uint16_t kDaikin128SectionLength = 8;
+
377 const uint8_t kDaikin128ByteModeFan = 1;
+
378 // const uint8_t kDaikin128MaskMode = 0b00001111;
+
379 const uint8_t kDaikin128ModeSize = 4;
+
380 const uint8_t kDaikin128Dry = 0b00000001;
+
381 const uint8_t kDaikin128Cool = 0b00000010;
+
382 const uint8_t kDaikin128Fan = 0b00000100;
+
383 const uint8_t kDaikin128Heat = 0b00001000;
+
384 const uint8_t kDaikin128Auto = 0b00001010;
+
385 const uint8_t kDaikin128MaskFan = 0b11110000;
+
386 const uint8_t kDaikin128FanAuto = 0b0001;
+
387 const uint8_t kDaikin128FanHigh = 0b0010;
+
388 const uint8_t kDaikin128FanMed = 0b0100;
+
389 const uint8_t kDaikin128FanLow = 0b1000;
+
390 const uint8_t kDaikin128FanPowerful = 0b0011;
+
391 const uint8_t kDaikin128FanQuiet = 0b1001;
+
392 const uint8_t kDaikin128ByteClockMins = 2;
+
393 const uint8_t kDaikin128ByteClockHours = 3;
+
394 const uint8_t kDaikin128ByteOnTimer = 4;
+
395 const uint8_t kDaikin128ByteOffTimer = 5;
+ + +
398 const uint8_t kDaikin128TimerOffset = 0;
+
399 const uint8_t kDaikin128TimerSize = 7;
+
400 const uint8_t kDaikin128HalfHourOffset = 6;
+ +
402 // const uint8_t kDaikin128MaskHours = 0b00111111;
+
403 const uint8_t kDaikin128HoursOffset = 0;
+
404 const uint8_t kDaikin128HoursSize = 6;
+
405 const uint8_t kDaikin128ByteTemp = 6;
+
406 const uint8_t kDaikin128MinTemp = 16; // C
+
407 const uint8_t kDaikin128MaxTemp = 30; // C
+ +
409 const uint8_t kDaikin128BitSwingOffset = 0;
+
410 const uint8_t kDaikin128BitSwing = 1 << kDaikin128BitSwingOffset; // 0b00000001
+
411 const uint8_t kDaikin128BitSleepOffset = 1;
+
412 const uint8_t kDaikin128BitSleep = 1 << kDaikin128BitSleepOffset; // 0b00000010
+ + +
415 const uint8_t kDaikin128ByteEconoLight = 9;
+
416 const uint8_t kDaikin128BitEconoOffset = 2;
+
417 const uint8_t kDaikin128BitEcono = 1 << kDaikin128BitEconoOffset; // 0b00000100
+
418 const uint8_t kDaikin128BitWall = 0b00001000;
+
419 const uint8_t kDaikin128BitCeiling = 0b00000001;
+ +
421 
+
422 
+
423 const uint16_t kDaikin152Freq = 38000; // Modulation Frequency in Hz.
+
424 const uint8_t kDaikin152LeaderBits = 5;
+
425 const uint16_t kDaikin152HdrMark = 3492;
+
426 const uint16_t kDaikin152HdrSpace = 1718;
+
427 const uint16_t kDaikin152BitMark = 433;
+
428 const uint16_t kDaikin152OneSpace = 1529;
+ +
430 const uint16_t kDaikin152Gap = 25182;
+
431 
+
432 // Byte[5]
+
433 const uint8_t kDaikin152ModeByte = 5; // Mask 0b01110000
+
434 const uint8_t kDaikin152PowerByte = kDaikin152ModeByte; // Mask 0b00000001
+
435 // Byte[6]
+
436 const uint8_t kDaikin152TempByte = 6; // Mask 0b11111110
+
437 const uint8_t kDaikin152TempSize = 7;
+
438 const uint8_t kDaikin152DryTemp = kDaikin2MinCoolTemp; // Celsius
+
439 const uint8_t kDaikin152FanTemp = 0x60; // 96 Celsius
+
440 // Byte[8]
+
441 const uint8_t kDaikin152FanByte = 8;
+ +
443 // Byte[13]
+
444 const uint8_t kDaikin152QuietByte = 13; // Mask 0b00100000
+
445 const uint8_t kDaikin152PowerfulByte = kDaikin152QuietByte; // Mask 0b00000001
+
446 // Byte[16]
+
447 const uint8_t kDaikin152EconoByte = 16; // Mask 0b00000100
+
448 const uint8_t kDaikin152ComfortByte = kDaikin152EconoByte; // Mask 0b00000010
+
449 const uint8_t kDaikin152ComfortOffset = 1; // Mask 0b00000010
+
450 const uint8_t kDaikin152SensorByte = kDaikin152EconoByte; // Mask 0b00001000
+
451 const uint8_t kDaikin152SensorOffset = 3; // Mask 0b00001000
+
452 
+
453 
+ + + + + + +
460 const uint16_t kDaikin64Gap = kDaikin128Gap;
+ +
462 const uint16_t kDaikin64Freq = kDaikin128Freq; // Hz.
+
463 const uint8_t kDaikin64Overhead = 9;
+
464 const int8_t kDaikin64ToleranceDelta = 5; // +5%
+
465 
+
466 const uint64_t kDaikin64KnownGoodState = 0x7C16161607204216;
+
467 const uint8_t kDaikin64ModeOffset = 8;
+
468 const uint8_t kDaikin64ModeSize = 4; // Mask 0b111100000000
+
469 const uint8_t kDaikin64Dry = 0b001;
+
470 const uint8_t kDaikin64Cool = 0b010;
+
471 const uint8_t kDaikin64Fan = 0b100;
+ +
473 const uint8_t kDaikin64FanSize = 4; // Mask 0b1111000000000000
+
474 const uint8_t kDaikin64FanAuto = 0b0001;
+
475 const uint8_t kDaikin64FanLow = 0b1000;
+
476 const uint8_t kDaikin64FanMed = 0b0100;
+
477 const uint8_t kDaikin64FanHigh = 0b0010;
+
478 const uint8_t kDaikin64FanQuiet = 0b1001;
+
479 const uint8_t kDaikin64FanTurbo = 0b0011;
+ +
481 const uint8_t kDaikin64ClockMinsSize = 8;
+
482 const uint8_t kDaikin64ClockHoursSize = 8;
+ +
484  kDaikin64ClockHoursSize; // Mask 0b1111111111111111 << 15
+ + +
487 const uint8_t kDaikin64OnTimeSize = 6;
+ + + + +
492 const uint8_t kDaikin64OffTimeSize = 6;
+ + + +
496 const uint8_t kDaikin64TempOffset = 48;
+
497 const uint8_t kDaikin64TempSize = 8; // Mask 0b11111111 << 47
+
498 const uint8_t kDaikin64MinTemp = 16; // Celsius
+
499 const uint8_t kDaikin64MaxTemp = 30; // Celsius
+
500 const uint8_t kDaikin64SwingVBit = 56;
+ +
502 const uint8_t kDaikin64PowerToggleBit = 59;
+
503 const uint8_t kDaikin64ChecksumOffset = 60;
+
504 const uint8_t kDaikin64ChecksumSize = 4; // Mask 0b1111 << 59
+
505 
+
506 // Legacy defines.
+
507 #define DAIKIN_COOL kDaikinCool
+
508 #define DAIKIN_HEAT kDaikinHeat
+
509 #define DAIKIN_FAN kDaikinFan
+
510 #define DAIKIN_AUTO kDaikinAuto
+
511 #define DAIKIN_DRY kDaikinDry
+
512 #define DAIKIN_MIN_TEMP kDaikinMinTemp
+
513 #define DAIKIN_MAX_TEMP kDaikinMaxTemp
+
514 #define DAIKIN_FAN_MIN kDaikinFanMin
+
515 #define DAIKIN_FAN_MAX kDaikinFanMax
+
516 #define DAIKIN_FAN_AUTO kDaikinFanAuto
+
517 #define DAIKIN_FAN_QUIET kDaikinFanQuiet
+
518 
+
520 class IRDaikinESP {
+
521  public:
+
522  explicit IRDaikinESP(const uint16_t pin, const bool inverted = false,
+
523  const bool use_modulation = true);
+
524 
+
525 #if SEND_DAIKIN
+
526  void send(const uint16_t repeat = kDaikinDefaultRepeat);
+
531  int8_t calibrate(void) { return _irsend.calibrate(); }
+
532 #endif
+
533  void begin(void);
+
534  void on(void);
+
535  void off(void);
+
536  void setPower(const bool on);
+
537  bool getPower(void);
+
538  void setTemp(const uint8_t temp);
+
539  uint8_t getTemp();
+
540  void setFan(const uint8_t fan);
+
541  uint8_t getFan(void);
+
542  void setMode(const uint8_t mode);
+
543  uint8_t getMode(void);
+
544  void setSwingVertical(const bool on);
+
545  bool getSwingVertical(void);
+
546  void setSwingHorizontal(const bool on);
+
547  bool getSwingHorizontal(void);
+
548  bool getQuiet(void);
+
549  void setQuiet(const bool on);
+
550  bool getPowerful(void);
+
551  void setPowerful(const bool on);
+
552  void setSensor(const bool on);
+
553  bool getSensor(void);
+
554  void setEcono(const bool on);
+
555  bool getEcono(void);
+
556  void setMold(const bool on);
+
557  bool getMold(void);
+
558  void setComfort(const bool on);
+
559  bool getComfort(void);
+
560  void enableOnTimer(const uint16_t starttime);
+
561  void disableOnTimer(void);
+
562  uint16_t getOnTime(void);
+
563  bool getOnTimerEnabled();
+
564  void enableOffTimer(const uint16_t endtime);
+
565  void disableOffTimer(void);
+
566  uint16_t getOffTime(void);
+
567  bool getOffTimerEnabled(void);
+
568  void setCurrentTime(const uint16_t mins_since_midnight);
+
569  uint16_t getCurrentTime(void);
+
570  void setCurrentDay(const uint8_t day_of_week);
+
571  uint8_t getCurrentDay(void);
+
572  void setWeeklyTimerEnable(const bool on);
+
573  bool getWeeklyTimerEnable(void);
+
574  uint8_t* getRaw(void);
+
575  void setRaw(const uint8_t new_code[],
+
576  const uint16_t length = kDaikinStateLength);
+
577  static bool validChecksum(uint8_t state[],
+
578  const uint16_t length = kDaikinStateLength);
+
579  static uint8_t convertMode(const stdAc::opmode_t mode);
+
580  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
581  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
582  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
583  stdAc::state_t toCommon(void);
+
584  String toString(void);
+
585 #ifndef UNIT_TEST
+
586 
+
587  private:
+ +
589 #else
+
590  IRsendTest _irsend;
+
592 #endif
+
594  // # of bytes per command
+ +
596  void stateReset(void);
+
597  void checksum(void);
+
598 };
+
599 
+
602 class IRDaikin2 {
+
603  public:
+
604  explicit IRDaikin2(const uint16_t pin, const bool inverted = false,
+
605  const bool use_modulation = true);
+
606 
+
607 #if SEND_DAIKIN2
+
608  void send(const uint16_t repeat = kDaikin2DefaultRepeat);
+
613  int8_t calibrate(void) { return _irsend.calibrate(); }
+
614 #endif
+
615  void begin();
+
616  void on();
+
617  void off();
+
618  void setPower(const bool state);
+
619  bool getPower();
+
620  void setTemp(const uint8_t temp);
+
621  uint8_t getTemp();
+
622  void setFan(const uint8_t fan);
+
623  uint8_t getFan();
+
624  uint8_t getMode();
+
625  void setMode(const uint8_t mode);
+
626  void setSwingVertical(const uint8_t position);
+
627  uint8_t getSwingVertical();
+
628  void setSwingHorizontal(const uint8_t position);
+
629  uint8_t getSwingHorizontal();
+
630  bool getQuiet();
+
631  void setQuiet(const bool on);
+
632  bool getPowerful();
+
633  void setPowerful(const bool on);
+
634  void setEcono(const bool on);
+
635  bool getEcono();
+
636  void setEye(const bool on);
+
637  bool getEye();
+
638  void setEyeAuto(const bool on);
+
639  bool getEyeAuto();
+
640  void setPurify(const bool on);
+
641  bool getPurify();
+
642  void setMold(const bool on);
+
643  bool getMold();
+
644  void enableOnTimer(const uint16_t starttime);
+
645  void disableOnTimer();
+
646  uint16_t getOnTime();
+
647  bool getOnTimerEnabled();
+
648  void enableSleepTimer(const uint16_t sleeptime);
+
649  void disableSleepTimer();
+
650  uint16_t getSleepTime();
+
651  bool getSleepTimerEnabled();
+
652  void enableOffTimer(const uint16_t endtime);
+
653  void disableOffTimer();
+
654  uint16_t getOffTime();
+
655  bool getOffTimerEnabled();
+
656  void setCurrentTime(const uint16_t time);
+
657  uint16_t getCurrentTime();
+
658  void setBeep(const uint8_t beep);
+
659  uint8_t getBeep();
+
660  void setLight(const uint8_t light);
+
661  uint8_t getLight();
+
662  void setClean(const bool on);
+
663  bool getClean();
+
664  void setFreshAir(const bool on);
+
665  bool getFreshAir();
+
666  void setFreshAirHigh(const bool on);
+
667  bool getFreshAirHigh();
+
668  uint8_t* getRaw();
+
669  void setRaw(const uint8_t new_code[]);
+
670  static bool validChecksum(uint8_t state[],
+
671  const uint16_t length = kDaikin2StateLength);
+
672  static uint8_t convertMode(const stdAc::opmode_t mode);
+
673  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
674  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
675  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
676  static stdAc::swingv_t toCommonSwingV(const uint8_t setting);
+
677  static stdAc::swingh_t toCommonSwingH(const uint8_t setting);
+
678  stdAc::state_t toCommon(void);
+
679  String toString();
+
680 #ifndef UNIT_TEST
+
681 
+
682  private:
+ +
684 #else
+
685  IRsendTest _irsend;
+
687 #endif
+
689  // # of bytes per command
+ +
691  void stateReset();
+
692  void checksum();
+
693  void clearOnTimerFlag();
+
694  void clearSleepTimerFlag();
+
695 };
+
696 
+
698 class IRDaikin216 {
+
699  public:
+
700  explicit IRDaikin216(const uint16_t pin, const bool inverted = false,
+
701  const bool use_modulation = true);
+
702 
+
703 #if SEND_DAIKIN216
+
704  void send(const uint16_t repeat = kDaikin216DefaultRepeat);
+
709  int8_t calibrate(void) { return _irsend.calibrate(); }
+
710 #endif
+
711  void begin();
+
712  uint8_t* getRaw();
+
713  void setRaw(const uint8_t new_code[]);
+
714  static bool validChecksum(uint8_t state[],
+
715  const uint16_t length = kDaikin216StateLength);
+
716  void on(void);
+
717  void off(void);
+
718  void setPower(const bool on);
+
719  bool getPower(void);
+
720  void setTemp(const uint8_t temp);
+
721  uint8_t getTemp();
+
722  void setMode(const uint8_t mode);
+
723  uint8_t getMode(void);
+
724  static uint8_t convertMode(const stdAc::opmode_t mode);
+
725  void setFan(const uint8_t fan);
+
726  uint8_t getFan(void);
+
727  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
728  void setSwingVertical(const bool on);
+
729  bool getSwingVertical(void);
+
730  void setSwingHorizontal(const bool on);
+
731  bool getSwingHorizontal(void);
+
732  void setQuiet(const bool on);
+
733  bool getQuiet(void);
+
734  void setPowerful(const bool on);
+
735  bool getPowerful(void);
+
736  stdAc::state_t toCommon(void);
+
737  String toString(void);
+
738 #ifndef UNIT_TEST
+
739 
+
740  private:
+ +
742 #else
+
743  IRsendTest _irsend;
+
745 #endif
+
747  // # of bytes per command
+ +
749  void stateReset();
+
750  void checksum();
+
751 };
+
752 
+
754 class IRDaikin160 {
+
755  public:
+
756  explicit IRDaikin160(const uint16_t pin, const bool inverted = false,
+
757  const bool use_modulation = true);
+
758 
+
759 #if SEND_DAIKIN160
+
760  void send(const uint16_t repeat = kDaikin160DefaultRepeat);
+
765  int8_t calibrate(void) { return _irsend.calibrate(); }
+
766 #endif
+
767  void begin();
+
768  uint8_t* getRaw();
+
769  void setRaw(const uint8_t new_code[]);
+
770  static bool validChecksum(uint8_t state[],
+
771  const uint16_t length = kDaikin160StateLength);
+
772  void on(void);
+
773  void off(void);
+
774  void setPower(const bool on);
+
775  bool getPower(void);
+
776  void setTemp(const uint8_t temp);
+
777  uint8_t getTemp();
+
778  void setMode(const uint8_t mode);
+
779  uint8_t getMode(void);
+
780  static uint8_t convertMode(const stdAc::opmode_t mode);
+
781  void setFan(const uint8_t fan);
+
782  uint8_t getFan(void);
+
783  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
784  void setSwingVertical(const uint8_t position);
+
785  uint8_t getSwingVertical(void);
+
786  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
787  static stdAc::swingv_t toCommonSwingV(const uint8_t setting);
+
788  stdAc::state_t toCommon(void);
+
789  String toString(void);
+
790 #ifndef UNIT_TEST
+
791 
+
792  private:
+ +
794 #else
+
795  IRsendTest _irsend;
+
797 #endif
+
799  // # of bytes per command
+ +
801  void stateReset();
+
802  void checksum();
+
803 };
+
804 
+
806 class IRDaikin176 {
+
807  public:
+
808  explicit IRDaikin176(const uint16_t pin, const bool inverted = false,
+
809  const bool use_modulation = true);
+
810 
+
811 #if SEND_DAIKIN176
+
812  void send(const uint16_t repeat = kDaikin176DefaultRepeat);
+
817  int8_t calibrate(void) { return _irsend.calibrate(); }
+
818 #endif
+
819  void begin();
+
820  uint8_t* getRaw();
+
821  void setRaw(const uint8_t new_code[]);
+
822  static bool validChecksum(uint8_t state[],
+
823  const uint16_t length = kDaikin176StateLength);
+
824  void on(void);
+
825  void off(void);
+
826  void setPower(const bool on);
+
827  bool getPower(void);
+
828  void setTemp(const uint8_t temp);
+
829  uint8_t getTemp();
+
830  void setMode(const uint8_t mode);
+
831  uint8_t getMode(void);
+
832  static uint8_t convertMode(const stdAc::opmode_t mode);
+
833  void setFan(const uint8_t fan);
+
834  uint8_t getFan(void);
+
835  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
836  void setSwingHorizontal(const uint8_t position);
+
837  uint8_t getSwingHorizontal(void);
+
838  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
839  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
840  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
841  static stdAc::swingh_t toCommonSwingH(const uint8_t setting);
+
842  stdAc::state_t toCommon(void);
+
843  String toString(void);
+
844 
+
845 #ifndef UNIT_TEST
+
846 
+
847  private:
+ +
849 #else
+
850  IRsendTest _irsend;
+
852 #endif
+
854  // # of bytes per command
+ +
856  uint8_t _saved_temp;
+
857  void stateReset();
+
858  void checksum();
+
859 };
+
860 
+
864 class IRDaikin128 {
+
865  public:
+
866  explicit IRDaikin128(const uint16_t pin, const bool inverted = false,
+
867  const bool use_modulation = true);
+
868 #if SEND_DAIKIN128
+
869  void send(const uint16_t repeat = kDaikin128DefaultRepeat);
+
874  int8_t calibrate(void) { return _irsend.calibrate(); }
+
875 #endif // SEND_DAIKIN128
+
876  void begin();
+
877  void setPowerToggle(const bool toggle);
+
878  bool getPowerToggle(void);
+
879  void setTemp(const uint8_t temp);
+
880  uint8_t getTemp(void);
+
881  void setFan(const uint8_t fan);
+
882  uint8_t getFan(void);
+
883  uint8_t getMode(void);
+
884  void setMode(const uint8_t mode);
+
885  void setSwingVertical(const bool on);
+
886  bool getSwingVertical();
+
887  bool getSleep(void);
+
888  void setSleep(const bool on);
+
889  bool getQuiet(void);
+
890  void setQuiet(const bool on);
+
891  bool getPowerful(void);
+
892  void setPowerful(const bool on);
+
893  void setEcono(const bool on);
+
894  bool getEcono(void);
+
895  void setOnTimer(const uint16_t mins_since_midnight);
+
896  uint16_t getOnTimer(void);
+
897  bool getOnTimerEnabled(void);
+
898  void setOnTimerEnabled(const bool on);
+
899  void setOffTimer(const uint16_t mins_since_midnight);
+
900  uint16_t getOffTimer(void);
+
901  bool getOffTimerEnabled(void);
+
902  void setOffTimerEnabled(const bool on);
+
903  void setClock(const uint16_t mins_since_midnight);
+
904  uint16_t getClock(void);
+
905  void setLightToggle(const uint8_t unit_type);
+
906  uint8_t getLightToggle(void);
+
907  uint8_t* getRaw(void);
+
908  void setRaw(const uint8_t new_code[]);
+
909  static bool validChecksum(uint8_t state[]);
+
910  static uint8_t convertMode(const stdAc::opmode_t mode);
+
911  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
912  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
913  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
914  stdAc::state_t toCommon(const stdAc::state_t *prev = NULL);
+
915  String toString(void);
+
916 #ifndef UNIT_TEST
+
917 
+
918  private:
+ +
920 #else
+
921  IRsendTest _irsend;
+
923 #endif
+
925  // # of bytes per command
+ +
927  void stateReset(void);
+
928  static uint8_t calcFirstChecksum(const uint8_t state[]);
+
929  static uint8_t calcSecondChecksum(const uint8_t state[]);
+
930  static void setTimer(uint8_t *ptr, const uint16_t mins_since_midnight);
+
931  static uint16_t getTimer(const uint8_t *ptr);
+
932  void checksum(void);
+
933  void clearOnTimerFlag(void);
+
934  void clearSleepTimerFlag(void);
+
935 };
+
936 
+
938 class IRDaikin152 {
+
939  public:
+
940  explicit IRDaikin152(const uint16_t pin, const bool inverted = false,
+
941  const bool use_modulation = true);
+
942 
+
943 #if SEND_DAIKIN152
+
944  void send(const uint16_t repeat = kDaikin152DefaultRepeat);
+
949  int8_t calibrate(void) { return _irsend.calibrate(); }
+
950 #endif
+
951  void begin();
+
952  uint8_t* getRaw();
+
953  void setRaw(const uint8_t new_code[]);
+
954  static bool validChecksum(uint8_t state[],
+
955  const uint16_t length = kDaikin152StateLength);
+
956  void on(void);
+
957  void off(void);
+
958  void setPower(const bool on);
+
959  bool getPower(void);
+
960  void setTemp(const uint8_t temp);
+
961  uint8_t getTemp();
+
962  void setFan(const uint8_t fan);
+
963  uint8_t getFan(void);
+
964  void setMode(const uint8_t mode);
+
965  uint8_t getMode(void);
+
966  void setSwingV(const bool on);
+
967  bool getSwingV(void);
+
968  bool getQuiet(void);
+
969  void setQuiet(const bool on);
+
970  bool getPowerful(void);
+
971  void setPowerful(const bool on);
+
972  void setSensor(const bool on);
+
973  bool getSensor(void);
+
974  void setEcono(const bool on);
+
975  bool getEcono(void);
+
976  void setComfort(const bool on);
+
977  bool getComfort(void);
+
978  static uint8_t convertMode(const stdAc::opmode_t mode);
+
979  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
980  stdAc::state_t toCommon(void);
+
981  String toString(void);
+
982 #ifndef UNIT_TEST
+
983 
+
984  private:
+ +
986 #else
+
987  IRsendTest _irsend;
+
989 #endif
+
991  // # of bytes per command
+ +
993  void stateReset();
+
994  void checksum();
+
995 };
+
996 
+
998 class IRDaikin64 {
+
999  public:
+
1000  explicit IRDaikin64(const uint16_t pin, const bool inverted = false,
+
1001  const bool use_modulation = true);
+
1002 
+
1003 #if SEND_DAIKIN64
+
1004  void send(const uint16_t repeat = kDaikin64DefaultRepeat);
+
1009  int8_t calibrate(void) { return _irsend.calibrate(); }
+
1010 #endif // SEND_DAIKIN64
+
1011  void begin();
+
1012  uint64_t getRaw();
+
1013  void setRaw(const uint64_t new_state);
+
1014  static uint8_t calcChecksum(const uint64_t state);
+
1015  static bool validChecksum(const uint64_t state);
+
1016  void setPowerToggle(const bool on);
+
1017  bool getPowerToggle(void);
+
1018  void setTemp(const uint8_t temp);
+
1019  uint8_t getTemp();
+
1020  void setFan(const uint8_t fan);
+
1021  uint8_t getFan(void);
+
1022  void setMode(const uint8_t mode);
+
1023  uint8_t getMode(void);
+
1024  void setSwingVertical(const bool on);
+
1025  bool getSwingVertical(void);
+
1026  void setSleep(const bool on);
+
1027  bool getSleep(void);
+
1028  bool getQuiet(void);
+
1029  void setQuiet(const bool on);
+
1030  bool getTurbo(void);
+
1031  void setTurbo(const bool on);
+
1032  void setClock(const uint16_t mins_since_midnight);
+
1033  uint16_t getClock(void);
+
1034  void setOnTimeEnabled(const bool on);
+
1035  bool getOnTimeEnabled(void);
+
1036  void setOnTime(const uint16_t mins_since_midnight);
+
1037  uint16_t getOnTime(void);
+
1038  void setOffTimeEnabled(const bool on);
+
1039  bool getOffTimeEnabled(void);
+
1040  void setOffTime(const uint16_t mins_since_midnight);
+
1041  uint16_t getOffTime(void);
+
1042  static uint8_t convertMode(const stdAc::opmode_t mode);
+
1043  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
1044  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
1045  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
1046  stdAc::state_t toCommon(const stdAc::state_t *prev = NULL);
+
1047  String toString(void);
+
1048 #ifndef UNIT_TEST
+
1049 
+
1050  private:
+ +
1052 #else
+
1053  IRsendTest _irsend;
+
1055 #endif
+
1057  uint64_t remote_state;
+
1058  void stateReset();
+
1059  void checksum();
+
1060 };
+
1061 #endif // IR_DAIKIN_H_
+
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:3957
+
const uint8_t kDaikin2SwingHRightMax
Definition: ir_Daikin.h:267
+
const uint8_t kDaikin64ChecksumOffset
Definition: ir_Daikin.h:503
+
const uint8_t kDaikin64TempOffset
Definition: ir_Daikin.h:496
+
void setCurrentTime(const uint16_t time)
Set the clock on the A/C unit.
Definition: ir_Daikin.cpp:958
+
const uint8_t kDaikinByteTemp
Definition: ir_Daikin.h:159
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:511
+
const uint16_t kDaikin152DefaultRepeat
Definition: IRremoteESP8266.h:854
+
const uint8_t kDaikinModeSize
Definition: ir_Daikin.h:123
+
const uint8_t kDaikin216ByteTemp
Definition: ir_Daikin.h:288
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_Daikin.cpp:1233
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikinStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:125
+
const uint16_t kDaikin152OneSpace
Definition: ir_Daikin.h:428
+
const uint8_t kDaikin152PowerByte
Definition: ir_Daikin.h:434
+
const uint8_t kDaikinBitEconoOffset
Definition: ir_Daikin.h:178
+
void setOffTimeEnabled(const bool on)
Set the enable status of the Off Timer.
Definition: ir_Daikin.cpp:3926
+
void on()
Change the power setting to On.
Definition: ir_Daikin.cpp:808
+
bool getPurify()
Get the Purify (Filter) mode status of the A/C.
Definition: ir_Daikin.cpp:1212
+
const uint8_t kDaikin176ByteTemp
Definition: ir_Daikin.h:351
+
void send(const uint16_t repeat=kDaikinDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:116
+
const uint8_t kDaikin152EconoByte
Definition: ir_Daikin.h:447
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:723
+
const uint8_t kDaikinDry
Definition: ir_Daikin.h:118
+
stdAc::state_t toCommon(const stdAc::state_t *prev=NULL)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:3072
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:1192
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:1598
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:146
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Daikin.cpp:2783
+
const uint8_t kDaikin128BitPowerToggleOffset
Definition: ir_Daikin.h:413
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:531
+
bool getPowerful(void)
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:334
+
const uint8_t kDaikin2BitSleepTimerOffset
Definition: ir_Daikin.h:230
+
const uint8_t kDaikin64OffTimeEnableBit
Definition: ir_Daikin.h:495
+
const uint8_t kDaikinBitOnTimerOffset
Definition: ir_Daikin.h:192
+
const uint8_t kDaikin2BitClean
Definition: ir_Daikin.h:241
+
const uint16_t kDaikin152ZeroSpace
Definition: ir_Daikin.h:429
+
const uint16_t kDaikin64OneSpace
Definition: ir_Daikin.h:457
+
const uint16_t kDaikin2DefaultRepeat
Definition: IRremoteESP8266.h:843
+
const uint8_t kDaikin128BitEconoOffset
Definition: ir_Daikin.h:416
+
const uint8_t kDaikin64Fan
Definition: ir_Daikin.h:471
+
const uint16_t kDaikin64Freq
Definition: ir_Daikin.h:462
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:3362
+
const uint8_t kDaikinByteFan
Definition: ir_Daikin.h:160
+
bool getOffTimerEnabled()
Get the enable status of the Off Timer.
Definition: ir_Daikin.cpp:1032
+
const uint8_t kDaikin128BitSwingOffset
Definition: ir_Daikin.h:409
+
const uint8_t kDaikin128MaskLight
Definition: ir_Daikin.h:420
+
void send(const uint16_t repeat=kDaikin2DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:728
+
const uint8_t kDaikin128BitSwing
Definition: ir_Daikin.h:410
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:2776
+
void setEyeAuto(const bool on)
Set the Automatic Eye (Sensor) mode of the A/C.
Definition: ir_Daikin.cpp:1110
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_Daikin.cpp:2461
+
bool getComfort(void)
Get the Comfort mode of the A/C.
Definition: ir_Daikin.cpp:384
+
const uint8_t kDaikin176SwingHAuto
Definition: ir_Daikin.h:361
+
const uint8_t kDaikin64OnTimeHalfHourBit
Definition: ir_Daikin.h:488
+
IRDaikin2(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:718
+
const uint8_t kDaikin216TempOffset
Definition: ir_Daikin.h:290
+
bool getWeeklyTimerEnable(void)
Get the enable status of the Weekly Timer.
Definition: ir_Daikin.cpp:491
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:111
+
const uint16_t kDaikin176Section2Length
Definition: ir_Daikin.h:343
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
void setSwingVertical(const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:892
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:1226
+
const uint8_t kDaikinBitSilent
Definition: ir_Daikin.h:173
+
bool getMold()
Get the Mould (filter) mode status of the A/C.
Definition: ir_Daikin.cpp:1068
+
const uint8_t kDaikin128MaskFan
Definition: ir_Daikin.h:385
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin2StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:737
+
bool getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:1677
+
const uint8_t kDaikin128TimerOffset
Definition: ir_Daikin.h:398
+
const uint8_t kDaikin64Overhead
Definition: ir_Daikin.h:463
+
const uint16_t kDaikinOneSpace
Definition: ir_Daikin.h:210
+
const uint8_t kDaikin216ByteSwingH
Definition: ir_Daikin.h:300
+
const uint8_t kDaikin128ByteTemp
Definition: ir_Daikin.h:405
+
const uint8_t kDaikinBitPower
Definition: ir_Daikin.h:156
+
const uint16_t kDaikin2ZeroSpace
Definition: ir_Daikin.h:225
+
Class for handling detailed Daikin 280-bit A/C messages.
Definition: ir_Daikin.h:520
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:2385
+
bool getOnTimerEnabled()
Get the enable status of the On Timer.
Definition: ir_Daikin.cpp:415
+
const uint16_t kDaikin2HdrMark
Definition: ir_Daikin.h:221
+
const uint8_t kDaikinBitPowerful
Definition: ir_Daikin.h:170
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin216StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:1522
+
void setOffTime(const uint16_t mins_since_midnight)
Set the Off Timer time for the A/C unit.
Definition: ir_Daikin.cpp:3946
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Daikin.cpp:2484
+
const uint8_t kDaikin64OnTimeOffset
Definition: ir_Daikin.h:485
+
const uint8_t kDaikin160ByteFan
Definition: ir_Daikin.h:322
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:2022
+
void off(void)
Change the power setting to Off.
Definition: ir_Daikin.cpp:1946
+
Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering an...
Definition: ir_Daikin.h:602
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:709
+
const uint16_t kDaikin176StateLength
Definition: IRremoteESP8266.h:855
+
void setSwingHorizontal(const uint8_t position)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:2440
+
Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Ven...
Definition: ir_Daikin.h:864
+
void setMold(const bool on)
Set the Mould (filter) mode of the A/C.
Definition: ir_Daikin.cpp:1062
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
static stdAc::swingh_t toCommonSwingH(const uint8_t setting)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Daikin.cpp:1249
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:1950
+
const uint8_t kDaikin176TempSize
Definition: ir_Daikin.h:354
+
const uint8_t kDaikin64TempSize
Definition: ir_Daikin.h:497
+
uint8_t getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:2063
+
const uint8_t kDaikin2BitFreshAirHigh
Definition: ir_Daikin.h:245
+
const uint8_t kDaikinBitEcono
Definition: ir_Daikin.h:179
+
void setSwingHorizontal(const bool on)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:295
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:1718
+
const uint8_t kDaikin152TempByte
Definition: ir_Daikin.h:436
+
const uint8_t kDaikin64ModeOffset
Definition: ir_Daikin.h:467
+
bool getTurbo(void)
Get the Turbo (Powerful) mode status of the A/C.
Definition: ir_Daikin.cpp:3818
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:2751
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:1592
+
bool getFreshAirHigh()
Get the (High) Fresh Air mode status of the A/C.
Definition: ir_Daikin.cpp:1104
+
const uint8_t kDaikinByteSwingH
Definition: ir_Daikin.h:161
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:1580
+
bool getPowerToggle(void)
Get the Power toggle setting of the A/C.
Definition: ir_Daikin.cpp:2715
+
const uint16_t kDaikin64HdrMark
Definition: ir_Daikin.h:454
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:2687
+
const uint16_t kDaikin176HdrMark
Definition: ir_Daikin.h:335
+
const uint8_t kDaikinBitOnTimer
Definition: ir_Daikin.h:193
+
void setOffTimer(const uint16_t mins_since_midnight)
Set the Off Timer time for the A/C unit.
Definition: ir_Daikin.cpp:3004
+
void disableOnTimer()
Disable the On timer.
Definition: ir_Daikin.cpp:988
+
const uint8_t kDaikinByteEye
Definition: ir_Daikin.h:180
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_Daikin.cpp:3469
+
void setClock(const uint16_t mins_since_midnight)
Set the clock on the A/C unit.
Definition: ir_Daikin.cpp:3874
+
const uint8_t kDaikin128FanPowerful
Definition: ir_Daikin.h:390
+
const uint16_t kDaikin128Freq
Definition: ir_Daikin.h:365
+
const uint16_t kDaikinGap
Definition: ir_Daikin.h:211
+
void disableSleepTimer()
Disable the sleep timer.
Definition: ir_Daikin.cpp:1160
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:919
+
const uint8_t kDaikinByteOnTimerMinsHigh
Definition: ir_Daikin.h:163
+
const uint8_t kDaikin128MinTemp
Definition: ir_Daikin.h:406
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:1943
+
const uint8_t kDaikin2SwingVSwing
Definition: ir_Daikin.h:256
+
const uint8_t kDaikin2BitSleepTimer
Definition: ir_Daikin.h:231
+
void off(void)
Change the power setting to Off.
Definition: ir_Daikin.cpp:1576
+
uint16_t getOnTime(void)
Get the On Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:406
+
bool getPowerful(void)
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:2915
+
const uint8_t kDaikin2BeepSize
Definition: ir_Daikin.h:253
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:3707
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:1561
+
bool getPower()
Get the value of the current power setting.
Definition: ir_Daikin.cpp:822
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:2302
+
const uint8_t kDaikin216ByteSwingV
Definition: ir_Daikin.h:295
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:3320
+
const uint8_t kDaikin160ByteSwingV
Definition: ir_Daikin.h:324
+
uint16_t getOnTime()
Get the On Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:996
+
const uint16_t kDaikin160Gap
Definition: ir_Daikin.h:310
+
Class for handling detailed Daikin 64-bit A/C messages.
Definition: ir_Daikin.h:998
+
const uint16_t kDaikinBitMark
Definition: ir_Daikin.h:208
+
bool getEcono()
Get the Economical mode of the A/C.
Definition: ir_Daikin.cpp:1140
+
void enableOffTimer(const uint16_t endtime)
Set the enable status & time of the Off Timer.
Definition: ir_Daikin.cpp:1009
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Daikin.cpp:3654
+
const uint8_t kDaikin64ClockOffset
Definition: ir_Daikin.h:480
+
const uint16_t kDaikin152BitMark
Definition: ir_Daikin.h:427
+
uint8_t remote[kDaikinStateLength]
The state of the IR remote.
Definition: ir_Daikin.h:595
+
const uint8_t kDaikin176FanMax
Definition: ir_Daikin.h:358
+
void setCurrentTime(const uint16_t mins_since_midnight)
Set the clock on the A/C unit.
Definition: ir_Daikin.cpp:449
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:1537
+
const uint16_t kDaikin152HdrSpace
Definition: ir_Daikin.h:426
+
const uint16_t kDaikin160BitMark
Definition: ir_Daikin.h:307
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:803
+
const uint8_t kDaikinBitOffTimerOffset
Definition: ir_Daikin.h:189
+
bool getPowerful()
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:1200
+
void setEcono(const bool on)
Set the Economy mode of the A/C.
Definition: ir_Daikin.cpp:3461
+
const uint8_t kDaikinByteOffTimerMinsHigh
Definition: ir_Daikin.h:167
+
const uint8_t kDaikin152ComfortOffset
Definition: ir_Daikin.h:449
+
void clearSleepTimerFlag()
Clear the sleep timer flag.
Definition: ir_Daikin.cpp:1155
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:3408
+
const uint8_t kDaikinBitMold
Definition: ir_Daikin.h:187
+
const uint8_t kDaikinModeOffset
Definition: ir_Daikin.h:122
+
const uint8_t kDaikin2MinCoolTemp
Definition: ir_Daikin.h:271
+
const uint8_t kDaikinBitOffTimer
Definition: ir_Daikin.h:190
+
const uint8_t kDaikin216ByteFan
Definition: ir_Daikin.h:293
+
bool getSwingVertical()
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:2853
+
const uint8_t kDaikin128BitSleepOffset
Definition: ir_Daikin.h:411
+
const uint8_t kDaikinDoWOffset
Definition: ir_Daikin.h:151
+ +
const uint8_t kDaikin176ByteModeButton
Definition: ir_Daikin.h:349
+
const uint8_t kDaikin64FanQuiet
Definition: ir_Daikin.h:478
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_Daikin.cpp:2882
+
void setPowerToggle(const bool toggle)
Set the Power toggle setting of the A/C.
Definition: ir_Daikin.cpp:2708
+
const uint8_t kDaikin152FanTemp
Definition: ir_Daikin.h:439
+
Class for handling detailed Daikin 216-bit A/C messages.
Definition: ir_Daikin.h:698
+
const uint8_t kDaikinBitMoldOffset
Definition: ir_Daikin.h:186
+
const uint8_t kDaikin64Cool
Definition: ir_Daikin.h:470
+
void setMold(const bool on)
Set the Mould mode of the A/C.
Definition: ir_Daikin.cpp:366
+
const uint8_t kDaikin64FanTurbo
Definition: ir_Daikin.h:479
+
const uint8_t kDaikinFan
Definition: ir_Daikin.h:121
+
bool getPowerful(void)
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:3454
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:1051
+
void setFreshAirHigh(const bool on)
Set the (High) Fresh Air mode of the A/C.
Definition: ir_Daikin.cpp:1098
+
void disableOffTimer()
Disable the Off timer.
Definition: ir_Daikin.cpp:1017
+
const uint16_t kDaikinZeroSpace
Definition: ir_Daikin.h:209
+
bool getOffTimeEnabled(void)
Get the enable status of the Off Timer.
Definition: ir_Daikin.cpp:3932
+
const uint8_t kDaikin2LightOffset
Definition: ir_Daikin.h:249
+
const uint8_t kDaikinSection1Length
Definition: ir_Daikin.h:139
+
const uint8_t kDaikinByteChecksum2
Definition: ir_Daikin.h:153
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:949
+
const uint8_t kDaikin64OffTimeOffset
Definition: ir_Daikin.h:491
+
const uint8_t kDaikin2BitEye
Definition: ir_Daikin.h:235
+
const uint8_t kDaikin128BitTimerEnabled
Definition: ir_Daikin.h:397
+
static uint16_t getTimer(const uint8_t *ptr)
Get the time for a timer at the given location.
Definition: ir_Daikin.cpp:2970
+
const uint8_t kDaikin160TempSize
Definition: ir_Daikin.h:321
+
const uint8_t kDaikinClockMinsHighSize
Definition: ir_Daikin.h:150
+
const uint8_t kDaikinBitComfortOffset
Definition: ir_Daikin.h:145
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:231
+
const uint8_t kDaikin2BitEyeAutoOffset
Definition: ir_Daikin.h:236
+
const uint8_t kDaikinByteWeeklyTimer
Definition: ir_Daikin.h:182
+
void setSensor(const bool on)
Set the Sensor mode of the A/C.
Definition: ir_Daikin.cpp:340
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:1985
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:3533
+
const uint8_t kDaikin64ClockSize
Definition: ir_Daikin.h:483
+
const uint8_t kDaikin176MaskMode
Definition: ir_Daikin.h:348
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint16_t kDaikinUnusedTime
Definition: ir_Daikin.h:195
+
const uint8_t kDaikin216SwingSize
Definition: ir_Daikin.h:297
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:817
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:3442
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:1654
+
uint16_t getOffTime()
Get the Off Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:1025
+
bool getFreshAir()
Get the Fresh Air mode status of the A/C.
Definition: ir_Daikin.cpp:1092
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint16_t kDaikin216ZeroSpace
Definition: ir_Daikin.h:279
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:2342
+
void off(void)
Change the power setting to Off.
Definition: ir_Daikin.cpp:3310
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:2899
+
bool getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:3856
+
const uint8_t kDaikin2BitPurifyOffset
Definition: ir_Daikin.h:232
+
const uint8_t kDaikin2SwingHLeft
Definition: ir_Daikin.h:264
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:796
+
uint16_t getOffTime(void)
Get the Off Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:3938
+
static stdAc::swingh_t toCommonSwingH(const uint8_t setting)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Daikin.cpp:2472
+
uint8_t getFan()
Get the current fan speed setting.
Definition: ir_Daikin.cpp:876
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:3840
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:1923
+
stdAc::state_t toCommon(const stdAc::state_t *prev=NULL)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:3991
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:323
+
static void setTimer(uint8_t *ptr, const uint16_t mins_since_midnight)
Set the time for a timer at the given location.
Definition: ir_Daikin.cpp:2956
+
const uint8_t kDaikin128HoursOffset
Definition: ir_Daikin.h:403
+
const uint8_t kDaikinBitPowerOffset
Definition: ir_Daikin.h:155
+
const uint16_t kDaikinHdrSpace
Definition: ir_Daikin.h:207
+
const uint16_t kDaikin160HdrSpace
Definition: ir_Daikin.h:306
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void setOnTimeEnabled(const bool on)
Set the enable status of the On Timer.
Definition: ir_Daikin.cpp:3895
+
IRDaikinESP(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:106
+
void setPower(const bool state)
Change the power setting.
Definition: ir_Daikin.cpp:815
+
const uint8_t kDaikinCurIndex
Definition: ir_Daikin.h:203
+
const uint8_t kDaikin2BitPurify
Definition: ir_Daikin.h:233
+
const uint8_t kDaikin160SwingVHighest
Definition: ir_Daikin.h:330
+
void setSwingVertical(const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:2046
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:2819
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:2032
+
const uint16_t kDaikin2Section2Length
Definition: ir_Daikin.h:228
+
uint8_t remote_state[kDaikin176StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:855
+
const uint8_t kDaikin216BytePower
Definition: ir_Daikin.h:285
+
const uint8_t kDaikin64SwingVBit
Definition: ir_Daikin.h:500
+
const uint16_t kDaikin152StateLength
Definition: IRremoteESP8266.h:852
+
const uint8_t kDaikin176ByteSwingH
Definition: ir_Daikin.h:359
+
const uint8_t kDaikin128BitCeiling
Definition: ir_Daikin.h:419
+
void off(void)
Change the power setting to Off.
Definition: ir_Daikin.cpp:207
+
const uint8_t kDaikin64ModeSize
Definition: ir_Daikin.h:468
+
const uint16_t kDaikin160OneSpace
Definition: ir_Daikin.h:308
+
const uint8_t kDaikinOnTimerMinsHighSize
Definition: ir_Daikin.h:165
+
void setFreshAir(const bool on)
Set the Fresh Air mode of the A/C.
Definition: ir_Daikin.cpp:1086
+
void setLight(const uint8_t light)
Set the Light (LED) mode of the A/C.
Definition: ir_Daikin.cpp:1056
+
const uint8_t kDaikin128BitPowerToggle
Definition: ir_Daikin.h:414
+
bool getComfort(void)
Get the Comfort mode of the A/C.
Definition: ir_Daikin.cpp:3500
+
bool getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:3421
+
const uint16_t kDaikin128ZeroSpace
Definition: ir_Daikin.h:372
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:1290
+
bool getSleepTimerEnabled()
Get the Sleep timer enabled status of the A/C.
Definition: ir_Daikin.cpp:1172
+
const uint8_t kDaikinFanMax
Definition: ir_Daikin.h:128
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:2729
+
const uint16_t kDaikin176Gap
Definition: ir_Daikin.h:340
+
uint16_t getOffTimer(void)
Get the Off Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:3010
+
const uint8_t kDaikinBytePowerful
Definition: ir_Daikin.h:168
+
const uint8_t kDaikin2BitFreshAirHighOffset
Definition: ir_Daikin.h:244
+
bool getSleep(void)
Get the Sleep mode of the A/C.
Definition: ir_Daikin.cpp:3868
+
void enableOnTimer(const uint16_t starttime)
Set the enable status & time of the On Timer.
Definition: ir_Daikin.cpp:975
+
void setOffTimerEnabled(const bool on)
Set the enable status of the Off Timer.
Definition: ir_Daikin.cpp:2990
+
const uint8_t kDaikin160ByteTemp
Definition: ir_Daikin.h:318
+
const uint8_t kDaikinBitSensor
Definition: ir_Daikin.h:176
+
const uint8_t kDaikin128FanMed
Definition: ir_Daikin.h:388
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:2408
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:2127
+
void off(void)
Change the power setting to Off..
Definition: ir_Daikin.cpp:2319
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:1568
+
const uint8_t kDaikin64PowerToggleBit
Definition: ir_Daikin.h:502
+
const uint8_t kDaikinOnTimerMinsHighOffset
Definition: ir_Daikin.h:164
+
const uint8_t kDaikinSwingOn
Definition: ir_Daikin.h:135
+
const uint16_t kDaikin216Freq
Definition: ir_Daikin.h:274
+
const uint8_t kDaikinSwingOffset
Definition: ir_Daikin.h:133
+
void clearOnTimerFlag()
Clear the On Timer flag.
Definition: ir_Daikin.cpp:983
+
void setSwingVertical(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:282
+
const uint16_t kDaikin216StateLength
Definition: IRremoteESP8266.h:858
+
const uint16_t kDaikin176Freq
Definition: ir_Daikin.h:334
+
uint16_t getCurrentTime(void)
Get the clock time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:460
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:2889
+
const uint8_t kDaikinBitComfort
Definition: ir_Daikin.h:146
+
const uint8_t kDaikin152TempSize
Definition: ir_Daikin.h:437
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:1631
+
const uint16_t kDaikin2Section1Length
Definition: ir_Daikin.h:227
+
void setLightToggle(const uint8_t unit_type)
Set the Light toggle setting of the A/C.
Definition: ir_Daikin.cpp:3017
+
const uint8_t kDaikin2SwingHMiddle
Definition: ir_Daikin.h:265
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:683
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:3672
+
const uint8_t kDaikin64OnTimeEnableBit
Definition: ir_Daikin.h:490
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:580
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:2336
+
const uint8_t kDaikin2BitFreshAir
Definition: ir_Daikin.h:243
+
const uint16_t kDaikin152Freq
Definition: ir_Daikin.h:423
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:2295
+
void send(const uint16_t repeat=kDaikin128DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:2701
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:3428
+
const uint16_t kDaikin128HdrSpace
Definition: ir_Daikin.h:369
+
bool getSensor(void)
Get the Sensor mode of the A/C.
Definition: ir_Daikin.cpp:346
+
const uint8_t kDaikinByteSensor
Definition: ir_Daikin.h:174
+
const uint8_t kDaikin128HoursSize
Definition: ir_Daikin.h:404
+
const uint8_t kDaikinBeepOff
Definition: ir_Daikin.h:198
+
const uint8_t kDaikin2BitCleanOffset
Definition: ir_Daikin.h:240
+
void setSensor(const bool on)
Set the Sensor mode of the A/C.
Definition: ir_Daikin.cpp:3475
+
const uint16_t kDaikin176HdrSpace
Definition: ir_Daikin.h:336
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Daikin.cpp:2374
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:3745
+
const uint16_t kDaikin2Sections
Definition: ir_Daikin.h:226
+
const uint8_t kDaikin160SwingVHigh
Definition: ir_Daikin.h:329
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:1616
+
static uint8_t calcSecondChecksum(const uint8_t state[])
Definition: ir_Daikin.cpp:2650
+
void setComfort(const bool on)
Set the Comfort mode of the A/C.
Definition: ir_Daikin.cpp:378
+
const uint16_t kDaikin128StateLength
Definition: IRremoteESP8266.h:849
+
const uint16_t kDaikin176DefaultRepeat
Definition: IRremoteESP8266.h:857
+
const uint8_t kDaikin2BeepOffset
Definition: ir_Daikin.h:252
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:259
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:2669
+
const uint8_t kDaikin128BitWall
Definition: ir_Daikin.h:418
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:3773
+
const uint16_t kDaikin2BitMark
Definition: ir_Daikin.h:223
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin152StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:3269
+
const uint8_t kDaikinByteClockMinsLow
Definition: ir_Daikin.h:147
+
const uint16_t kDaikin2LeaderSpace
Definition: ir_Daikin.h:219
+
void setComfort(const bool on)
Set the Comfort mode of the A/C.
Definition: ir_Daikin.cpp:3487
+
bool getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:1691
+
static stdAc::swingv_t toCommonSwingV(const uint8_t setting)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Daikin.cpp:933
+
void clearOnTimerFlag(void)
+
const uint16_t kDaikin160Sections
Definition: ir_Daikin.h:311
+
void setSwingV(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:3414
+
const uint8_t kDaikin64OffTimeHalfHourBit
Definition: ir_Daikin.h:493
+
const uint8_t kDaikin64FanAuto
Definition: ir_Daikin.h:474
+
void setSwingHorizontal(const uint8_t position)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:948
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:1699
+
const uint16_t kDaikin160Freq
Definition: ir_Daikin.h:304
+
uint8_t remote_state[kDaikin2StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:690
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:1264
+
uint8_t remote_state[kDaikin128StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:926
+
bool getPowerful(void)
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:1726
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:835
+
const uint8_t kDaikin64Dry
Definition: ir_Daikin.h:469
+
bool getMold(void)
Get the Mould mode status of the A/C.
Definition: ir_Daikin.cpp:372
+
const uint8_t kDaikin2SwingVBreeze
Definition: ir_Daikin.h:258
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:185
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:2789
+
IRDaikin176(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:2239
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin160StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:1878
+
const uint8_t kDaikin64FanLow
Definition: ir_Daikin.h:475
+
bool getPowerToggle(void)
Get the Power toggle setting of the A/C.
Definition: ir_Daikin.cpp:3701
+
uint8_t remote_state[kDaikin152StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:992
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:3307
+
IRDaikin160(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:1867
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:3326
+
const uint8_t kDaikinBeepLoud
Definition: ir_Daikin.h:197
+
const uint8_t kDaikinFanAuto
Definition: ir_Daikin.h:129
+
const uint8_t kDaikin152QuietByte
Definition: ir_Daikin.h:444
+
const uint8_t kDaikin128HalfHourOffset
Definition: ir_Daikin.h:400
+
const uint8_t kDaikin128Dry
Definition: ir_Daikin.h:380
+
void setSwingHorizontal(const bool on)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:1684
+
const uint64_t kDaikin64KnownGoodState
Definition: ir_Daikin.h:466
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin176StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:2250
+
const uint16_t kDaikin216Sections
Definition: ir_Daikin.h:281
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:1664
+
IRDaikin128(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:2638
+
uint16_t getOnTimer(void)
Get the On Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:2984
+
const uint8_t kDaikin152DryTemp
Definition: ir_Daikin.h:438
+
void setCurrentDay(const uint8_t day_of_week)
Set the current day of the week to be sent to the A/C unit.
Definition: ir_Daikin.cpp:469
+
IRDaikin64(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:3636
+
const uint8_t kDaikin128ByteClockHours
Definition: ir_Daikin.h:393
+
const uint8_t kDaikinTempSize
Definition: ir_Daikin.h:158
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:2265
+
IRDaikin152(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:3250
+
uint16_t getSleepTime()
Get the Sleep Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:1166
+
const uint16_t kDaikin160HdrMark
Definition: ir_Daikin.h:305
+
const uint16_t kDaikin64ZeroSpace
Definition: ir_Daikin.h:458
+
uint8_t getLightToggle(void)
Get the Light toggle setting of the A/C.
Definition: ir_Daikin.cpp:3031
+
const uint8_t kDaikin176MaskFan
Definition: ir_Daikin.h:357
+
static bool validChecksum(uint8_t state[])
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:2658
+
const uint16_t kDaikin128SectionLength
Definition: ir_Daikin.h:376
+
const uint8_t kDaikin176Cool
Definition: ir_Daikin.h:345
+
void setTurbo(const bool on)
Set the Turbo (Powerful) mode of the A/C.
Definition: ir_Daikin.cpp:3824
+
const uint16_t kDaikin128LeaderSpace
Definition: ir_Daikin.h:367
+
uint16_t getClock(void)
Get the clock time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:3885
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:862
+
const uint8_t kDaikinByteOnTimer
Definition: ir_Daikin.h:191
+
void setWeeklyTimerEnable(const bool on)
Set the enable status of the Weekly Timer.
Definition: ir_Daikin.cpp:484
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:1009
+
const uint16_t kDaikin2LeaderMark
Definition: ir_Daikin.h:218
+
const uint8_t kDaikinBeepQuiet
Definition: ir_Daikin.h:196
+
const uint8_t kDaikin2SwingVAuto
Definition: ir_Daikin.h:257
+
const uint8_t kDaikin2BitEyeOffset
Definition: ir_Daikin.h:234
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:498
+
const uint8_t kDaikin160TempOffset
Definition: ir_Daikin.h:320
+
const uint16_t kDaikin216Section1Length
Definition: ir_Daikin.h:282
+
const uint8_t kDaikinLightBright
Definition: ir_Daikin.h:199
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:3278
+
const uint16_t kDaikin152Gap
Definition: ir_Daikin.h:430
+
void send(const uint16_t repeat=kDaikin176DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:2310
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Daikin.cpp:917
+
const uint8_t kDaikin176BytePower
Definition: ir_Daikin.h:346
+
const uint8_t kDaikin128Auto
Definition: ir_Daikin.h:384
+
const uint8_t kDaikin160SwingVMiddle
Definition: ir_Daikin.h:328
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:3767
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:2008
+
void setEcono(const bool on)
Set the Economy mode of the A/C.
Definition: ir_Daikin.cpp:2874
+
const uint8_t kDaikinByteEcono
Definition: ir_Daikin.h:177
+
const uint16_t kDaikin128Gap
Definition: ir_Daikin.h:373
+
const uint8_t kDaikin64MaxTemp
Definition: ir_Daikin.h:499
+
const uint8_t kDaikinHeat
Definition: ir_Daikin.h:120
+
const uint16_t kDaikin216OneSpace
Definition: ir_Daikin.h:278
+
const uint8_t kDaikinBitSensorOffset
Definition: ir_Daikin.h:175
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:1893
+
const uint8_t kDaikin176SwingHOff
Definition: ir_Daikin.h:362
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:309
+
const uint8_t kDaikin216TempSize
Definition: ir_Daikin.h:291
+
const uint16_t kDaikin64BitMark
Definition: ir_Daikin.h:455
+
const uint8_t kDaikin160SwingVLowest
Definition: ir_Daikin.h:326
+
const uint16_t kDaikin216DefaultRepeat
Definition: IRremoteESP8266.h:860
+
uint16_t getOffTime(void)
Get the Off Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:436
+
const uint8_t kDaikinTempOffset
Definition: ir_Daikin.h:157
+
const uint8_t kDaikin2SwingHLeftMax
Definition: ir_Daikin.h:263
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:3314
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:1761
+
const uint8_t kDaikinCurBit
Definition: ir_Daikin.h:202
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:765
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:3834
+
const uint16_t kDaikin176BitMark
Definition: ir_Daikin.h:337
+
const uint16_t kDaikin160DefaultRepeat
Definition: IRremoteESP8266.h:848
+
void setPowerToggle(const bool on)
Set the Power toggle setting of the A/C.
Definition: ir_Daikin.cpp:3695
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:2362
+
void setEcono(const bool on)
Set the Economy mode of the A/C.
Definition: ir_Daikin.cpp:352
+
void off()
Change the power setting to Off.
Definition: ir_Daikin.cpp:811
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:2323
+
const int8_t kDaikin64ToleranceDelta
Definition: ir_Daikin.h:464
+
bool getEye()
Get the Eye (Sensor) mode status of the A/C.
Definition: ir_Daikin.cpp:1128
+
const uint8_t kDaikinFanOffset
Definition: ir_Daikin.h:131
+
const uint8_t kDaikin152SensorOffset
Definition: ir_Daikin.h:451
+
const uint8_t kDaikin160SwingVAuto
Definition: ir_Daikin.h:331
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:3255
+
const uint16_t kDaikinHeaderLength
Definition: ir_Daikin.h:137
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:211
+
const uint16_t kDaikin64LdrMark
Definition: ir_Daikin.h:459
+
const uint8_t kDaikin176ByteMode
Definition: ir_Daikin.h:347
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:3381
+
uint64_t remote_state
The state of the IR remote.
Definition: ir_Daikin.h:1057
+ +
const uint8_t kDaikinFanSize
Definition: ir_Daikin.h:132
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:1901
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:2518
+
uint8_t getSwingHorizontal()
Get the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:954
+
const uint8_t kDaikin128Cool
Definition: ir_Daikin.h:381
+
const uint8_t kDaikin128BytePowerSwingSleep
Definition: ir_Daikin.h:408
+
const uint16_t kDaikin176ZeroSpace
Definition: ir_Daikin.h:339
+
const uint8_t kDaikin128Heat
Definition: ir_Daikin.h:383
+
const uint8_t kDaikinSection3Length
Definition: ir_Daikin.h:141
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:3333
+
const uint8_t kDaikin160MaskSwingV
Definition: ir_Daikin.h:325
+
const uint16_t kDaikin160Section1Length
Definition: ir_Daikin.h:312
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:1573
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:2330
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:2244
+
const uint16_t kDaikin128Sections
Definition: ir_Daikin.h:375
+
const uint16_t kDaikin176Sections
Definition: ir_Daikin.h:341
+
bool getQuiet()
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:1186
+
const uint8_t kDaikinByteChecksum3
Definition: ir_Daikin.h:194
+
const uint16_t kDaikin128DefaultRepeat
Definition: IRremoteESP8266.h:851
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:3356
+
Class for handling detailed Daikin 152-bit A/C messages.
Definition: ir_Daikin.h:938
+
const uint8_t kDaikin216ByteMode
Definition: ir_Daikin.h:286
+
const uint8_t kDaikin64OnTimeSize
Definition: ir_Daikin.h:487
+
const uint8_t kDaikin128ByteOffTimer
Definition: ir_Daikin.h:395
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:2905
+
const uint8_t kDaikin160ByteMode
Definition: ir_Daikin.h:316
+
const uint8_t kDaikin64FanOffset
Definition: ir_Daikin.h:472
+
const uint8_t kDaikin128FanLow
Definition: ir_Daikin.h:389
+
const uint16_t kDaikinStateLength
Definition: IRremoteESP8266.h:836
+
void setOnTime(const uint16_t mins_since_midnight)
Set the On Timer time for the A/C unit.
Definition: ir_Daikin.cpp:3915
+
Class for handling detailed Daikin 160-bit A/C messages.
Definition: ir_Daikin.h:754
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:3284
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:588
+
const uint16_t kDaikin216Section2Length
Definition: ir_Daikin.h:283
+
const uint8_t kDaikin128BitSleep
Definition: ir_Daikin.h:412
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:3641
+
const uint8_t kDaikin64FanMed
Definition: ir_Daikin.h:476
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:236
+
const uint8_t kDaikin152SwingVByte
Definition: ir_Daikin.h:442
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:760
+
const uint16_t kDaikin128FooterMark
Definition: ir_Daikin.h:374
+
bool getOnTimerEnabled(void)
Get the enable status of the On Timer.
Definition: ir_Daikin.cpp:2946
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:888
+
void disableOffTimer(void)
Clear and disable the Off timer.
Definition: ir_Daikin.cpp:429
+
const uint8_t kDaikinByteSilent
Definition: ir_Daikin.h:171
+
void setPurify(const bool on)
Set the Purify (Filter) mode of the A/C.
Definition: ir_Daikin.cpp:1206
+
const uint16_t kDaikin2Gap
Definition: ir_Daikin.h:220
+
const uint8_t kDaikin176TempOffset
Definition: ir_Daikin.h:353
+
const uint8_t kDaikin176ByteFan
Definition: ir_Daikin.h:356
+
void setSleep(const bool on)
Set the Sleep mode of the A/C.
Definition: ir_Daikin.cpp:3862
+
const uint8_t kDaikin152LeaderBits
Definition: ir_Daikin.h:424
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:3723
+
void setOnTimer(const uint16_t mins_since_midnight)
Set the On Timer time for the A/C unit.
Definition: ir_Daikin.cpp:2978
+
const uint16_t kDaikinDefaultRepeat
Definition: IRremoteESP8266.h:840
+
const uint16_t kDaikin64DefaultRepeat
Definition: IRremoteESP8266.h:845
+
const uint8_t kDaikin152SensorByte
Definition: ir_Daikin.h:450
+
const uint8_t kDaikin2BitEyeAuto
Definition: ir_Daikin.h:237
+
const uint8_t kDaikin152ModeByte
Definition: ir_Daikin.h:433
+
const uint8_t kDaikinByteOffTimer
Definition: ir_Daikin.h:188
+
const uint16_t kDaikin64LdrSpace
Definition: ir_Daikin.h:461
+
const uint8_t kDaikin128Fan
Definition: ir_Daikin.h:382
+
bool getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:289
+
const uint8_t kDaikinBitPowerfulOffset
Definition: ir_Daikin.h:169
+
const uint8_t kDaikinBitEye
Definition: ir_Daikin.h:181
+
const uint8_t kDaikinByteOnTimerMinsLow
Definition: ir_Daikin.h:162
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:613
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Daikin.cpp:3805
+
static stdAc::swingv_t toCommonSwingV(const uint8_t setting)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Daikin.cpp:2087
+
const uint8_t kDaikinBitWeeklyTimer
Definition: ir_Daikin.h:184
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:2491
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:3395
+
void setOnTimerEnabled(const bool on)
Set the enable status of the On Timer.
Definition: ir_Daikin.cpp:2939
+
const uint8_t kDaikin128ByteEconoLight
Definition: ir_Daikin.h:415
+
const uint8_t kDaikin216BytePowerful
Definition: ir_Daikin.h:301
+
void setRaw(const uint64_t new_state)
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:3691
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:2316
+
void enableSleepTimer(const uint16_t sleeptime)
Set the enable status & time of the Sleep Timer.
Definition: ir_Daikin.cpp:1147
+
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:3665
+
bool getOnTimerEnabled()
Get the enable status of the On Timer.
Definition: ir_Daikin.cpp:1003
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:1586
+
const uint8_t kDaikin2SwingVHigh
Definition: ir_Daikin.h:254
+
const uint8_t kDaikinClockMinsHighOffset
Definition: ir_Daikin.h:149
+
const uint16_t kDaikin160Section2Length
Definition: ir_Daikin.h:313
+
const uint8_t kDaikin128FanQuiet
Definition: ir_Daikin.h:391
+
const uint8_t kDaikin216SwingOn
Definition: ir_Daikin.h:298
+
const uint8_t kDaikinDoWSize
Definition: ir_Daikin.h:152
+
void enableOnTimer(const uint16_t starttime)
Set the enable status & time of the On Timer.
Definition: ir_Daikin.cpp:390
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:985
+
const uint8_t kDaikin128TimerSize
Definition: ir_Daikin.h:399
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:2000
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:204
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:3373
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:1178
+
void setSwingVertical(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:3850
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Daikin.cpp:538
+
const uint8_t kDaikin2FanByte
Definition: ir_Daikin.h:260
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:752
+
const uint8_t kDaikinByteMold
Definition: ir_Daikin.h:185
+
const uint8_t kDaikin64FanSize
Definition: ir_Daikin.h:473
+
const uint8_t kDaikin160MaskFan
Definition: ir_Daikin.h:323
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:217
+
static uint8_t calcFirstChecksum(const uint8_t state[])
Definition: ir_Daikin.cpp:2645
+
const uint8_t kDaikin64MinTemp
Definition: ir_Daikin.h:498
+
const uint8_t kDaikin2SwingHRight
Definition: ir_Daikin.h:266
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:1991
+
bool getSleep(void)
Get the Sleep mode of the A/C.
Definition: ir_Daikin.cpp:2867
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:3037
+
uint8_t getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:2453
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:3436
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:2423
+
void setClock(const uint16_t mins_since_midnight)
Set the clock on the A/C unit.
Definition: ir_Daikin.cpp:2921
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:1968
+
uint16_t getOnTime(void)
Get the On Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:3907
+
bool getOffTimerEnabled(void)
Get the enable status of the Off Timer.
Definition: ir_Daikin.cpp:2997
+
const uint16_t kDaikin64Gap
Definition: ir_Daikin.h:460
+
const uint16_t kDaikin128OneSpace
Definition: ir_Daikin.h:371
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_Daikin.cpp:360
+
const uint16_t kDaikin152HdrMark
Definition: ir_Daikin.h:425
+
const uint8_t kDaikin2BitMoldOffset
Definition: ir_Daikin.h:238
+
const uint8_t kDaikin2BitPowerOffset
Definition: ir_Daikin.h:246
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:2430
+
const uint8_t kDaikinByteOffTimerMinsLow
Definition: ir_Daikin.h:166
+
const uint8_t kDaikin64SleepBit
Definition: ir_Daikin.h:501
+
const uint8_t kDaikin2SwingHSwing
Definition: ir_Daikin.h:269
+
void setSwingVertical(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:2846
+
bool getSensor(void)
Get the Sensor mode of the A/C.
Definition: ir_Daikin.cpp:3481
+
void enableOffTimer(const uint16_t endtime)
Set the enable status & time of the Off Timer.
Definition: ir_Daikin.cpp:421
+
const uint16_t kDaikin160StateLength
Definition: IRremoteESP8266.h:846
+
const uint16_t kDaikin216HdrMark
Definition: ir_Daikin.h:275
+
const uint8_t kDaikinByteClockMinsHigh
Definition: ir_Daikin.h:148
+
const uint16_t kDaikin2HdrSpace
Definition: ir_Daikin.h:222
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:250
+
const uint8_t kDaikin176ModeButton
Definition: ir_Daikin.h:350
+
const uint8_t kDaikinSections
Definition: ir_Daikin.h:138
+
const uint16_t kDaikin2StateLength
Definition: IRremoteESP8266.h:841
+
uint8_t _saved_temp
Definition: ir_Daikin.h:856
+
const uint8_t kDaikinByteComfort
Definition: ir_Daikin.h:143
+
const uint8_t kDaikinByteChecksum1
Definition: ir_Daikin.h:144
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:2273
+
void setEye(const bool on)
Set the Eye (Sensor) mode of the A/C.
Definition: ir_Daikin.cpp:1122
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:3302
+
const uint8_t kDaikin64FanHigh
Definition: ir_Daikin.h:477
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:793
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:3678
+
void send(const uint16_t repeat=kDaikin152DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:3260
+
const uint8_t kDaikin64ChecksumSize
Definition: ir_Daikin.h:504
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:223
+
const uint8_t kDaikinFanMed
Definition: ir_Daikin.h:127
+
bool getOnTimeEnabled(void)
Get the enable status of the On Timer.
Definition: ir_Daikin.cpp:3901
+
const uint8_t kDaikin152ComfortByte
Definition: ir_Daikin.h:448
+
const uint16_t kDaikin64HdrSpace
Definition: ir_Daikin.h:456
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:2677
+
void send(const uint16_t repeat=kDaikin216DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:1513
+
void setRaw(const uint8_t new_code[], const uint16_t length=kDaikinStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:193
+
const uint8_t kDaikin128BitTimerEnabledOffset
Definition: ir_Daikin.h:396
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:3506
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:317
+
void setSwingVertical(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:1670
+
const uint8_t kDaikin2LightSize
Definition: ir_Daikin.h:250
+
const uint8_t kDaikinSwingOff
Definition: ir_Daikin.h:136
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:2400
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:3729
+
const uint16_t kMarkExcess
Definition: IRrecv.h:24
+
const uint8_t kDaikin216SwingOff
Definition: ir_Daikin.h:299
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:1545
+
const uint8_t kDaikinSwingSize
Definition: ir_Daikin.h:134
+
const uint8_t kDaikinAuto
Definition: ir_Daikin.h:117
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:3791
+
const uint16_t kDaikin216BitMark
Definition: ir_Daikin.h:277
+
const uint8_t kDaikinCool
Definition: ir_Daikin.h:119
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:874
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:2643
+
const uint16_t kDaikin160ZeroSpace
Definition: ir_Daikin.h:309
+
const uint64_t kDaikinFirstHeader64
Definition: ir_Daikin.h:213
+
const uint8_t kDaikin128ByteModeFan
Definition: ir_Daikin.h:377
+
const uint16_t kDaikin216Gap
Definition: ir_Daikin.h:280
+
const uint8_t kDaikin2BitPower
Definition: ir_Daikin.h:247
+
void setBeep(const uint8_t beep)
Set the Beep mode of the A/C.
Definition: ir_Daikin.cpp:1044
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:1508
+
const uint8_t kDaikinFanQuiet
Definition: ir_Daikin.h:130
+
const uint16_t kDaikinMarkExcess
Definition: ir_Daikin.h:205
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Daikin.cpp:2764
+
uint8_t getBeep()
Get the Beep status of the A/C.
Definition: ir_Daikin.cpp:1038
+
const uint8_t kDaikinTolerance
Definition: ir_Daikin.h:204
+
bool getOffTimerEnabled(void)
Get the enable status of the Off Timer.
Definition: ir_Daikin.cpp:443
+
const uint8_t kDaikin216MaskFan
Definition: ir_Daikin.h:294
+
bool getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:302
+
const uint8_t kDaikin2SwingVLow
Definition: ir_Daikin.h:255
+
const uint8_t kDaikin160BytePower
Definition: ir_Daikin.h:315
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Daikin.cpp:525
+
void setClean(const bool on)
Set the Auto clean mode of the A/C.
Definition: ir_Daikin.cpp:1074
+
const uint16_t kDaikin216HdrSpace
Definition: ir_Daikin.h:276
+
const uint8_t kDaikinSection2Length
Definition: ir_Daikin.h:140
+
const uint8_t kDaikin128ModeSize
Definition: ir_Daikin.h:379
+
const uint16_t kDaikin176OneSpace
Definition: ir_Daikin.h:338
+
bool getEyeAuto()
Get the Automaitc Eye (Sensor) mode status of the A/C.
Definition: ir_Daikin.cpp:1116
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:848
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:3295
+
const uint16_t kDaikinHdrMark
Definition: ir_Daikin.h:206
+
const uint8_t kDaikin128ByteClockMins
Definition: ir_Daikin.h:392
+
const uint8_t kDaikinLightOff
Definition: ir_Daikin.h:201
+
void setEcono(const bool on)
Set the Economy mode of the A/C.
Definition: ir_Daikin.cpp:1134
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Daikin.cpp:2071
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:552
+
const uint8_t kDaikin2Tolerance
Definition: ir_Daikin.h:229
+
const uint8_t kDaikin160SwingVLow
Definition: ir_Daikin.h:327
+
const uint8_t kDaikin128BitHalfHour
Definition: ir_Daikin.h:401
+
const uint8_t kDaikin128BitEcono
Definition: ir_Daikin.h:417
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:3716
+
const uint8_t kDaikin176DryFanTemp
Definition: ir_Daikin.h:355
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:829
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:1962
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:265
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Daikin.cpp:2833
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:2722
+
const uint16_t kDaikin2OneSpace
Definition: ir_Daikin.h:224
+
const uint8_t kDaikin2SwingHWide
Definition: ir_Daikin.h:262
+
const uint8_t kDaikin152FanByte
Definition: ir_Daikin.h:441
+
uint8_t remote_state[kDaikin216StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:748
+
const uint8_t kDaikin64ClockHoursSize
Definition: ir_Daikin.h:482
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Daikin.cpp:3756
+
uint64_t getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Daikin.cpp:3684
+
const uint16_t kDaikin128HdrMark
Definition: ir_Daikin.h:368
+
uint8_t getLight()
Get the Light status of the A/C.
Definition: ir_Daikin.cpp:1050
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:2694
+
void send(const uint16_t repeat=kDaikin64DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:3646
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:1639
+
uint8_t getCurrentDay(void)
Get the current day of the week to be sent to the A/C unit.
Definition: ir_Daikin.cpp:477
+
bool getClean()
Get the Auto Clean mode status of the A/C.
Definition: ir_Daikin.cpp:1080
+
const uint8_t kDaikin2BitMold
Definition: ir_Daikin.h:239
+
const uint8_t kDaikinBitSilentOffset
Definition: ir_Daikin.h:172
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:1872
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:1930
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:2796
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:156
+
void clearSleepTimerFlag(void)
+
const uint8_t kDaikin128MaxTemp
Definition: ir_Daikin.h:407
+
void send(const uint16_t repeat=kDaikin160DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:1937
+
const uint8_t kDaikinMaxTemp
Definition: ir_Daikin.h:125
+
Class for handling detailed Daikin 176-bit A/C messages.
Definition: ir_Daikin.h:806
+
const uint8_t kDaikin128FanHigh
Definition: ir_Daikin.h:387
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:2101
+
const uint8_t kDaikin128FanAuto
Definition: ir_Daikin.h:386
+
uint8_t getSwingVertical()
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:910
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:741
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:1219
+
const uint8_t kDaikinBitWeeklyTimerOffset
Definition: ir_Daikin.h:183
+
uint8_t remote_state[kDaikin160StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:800
+
const uint16_t kDaikin176Section1Length
Definition: ir_Daikin.h:342
+
const uint16_t kDaikin2Freq
Definition: ir_Daikin.h:217
+
const uint16_t kDaikin128BitMark
Definition: ir_Daikin.h:370
+
const uint8_t kDaikinMinTemp
Definition: ir_Daikin.h:124
+
uint16_t getClock(void)
Get the clock time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:2932
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:1622
+
const uint8_t kDaikin2BitFreshAirOffset
Definition: ir_Daikin.h:242
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:1712
+
const uint8_t kDaikin152PowerfulByte
Definition: ir_Daikin.h:445
+
void disableOnTimer(void)
Clear and disable the On timer.
Definition: ir_Daikin.cpp:399
+
IRDaikin216(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class Constructor.
Definition: ir_Daikin.cpp:1503
+
const uint8_t kDaikin64ClockMinsSize
Definition: ir_Daikin.h:481
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:851
+
const uint8_t kDaikinFanMin
Definition: ir_Daikin.h:126
+
const uint8_t kDaikinBytePower
Definition: ir_Daikin.h:154
+
const uint16_t kDaikin128LeaderMark
Definition: ir_Daikin.h:366
+
void setSleep(const bool on)
Set the Sleep mode of the A/C.
Definition: ir_Daikin.cpp:2860
+
const uint8_t kDaikin2SwingVCirculate
Definition: ir_Daikin.h:259
+
const uint8_t kDaikin2SwingHAuto
Definition: ir_Daikin.h:268
+
const uint8_t kDaikinLightDim
Definition: ir_Daikin.h:200
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:1956
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:1733
+
const uint8_t kDaikin64OffTimeSize
Definition: ir_Daikin.h:492
+
uint16_t getCurrentTime()
Get the clock time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:967
+
const uint8_t kDaikin128ByteOnTimer
Definition: ir_Daikin.h:394
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8cpp.html new file mode 100644 index 000000000..e71f63ef8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8cpp.html @@ -0,0 +1,220 @@ + + + + + + + +IRremoteESP8266: src/ir_Delonghi.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Delonghi.cpp File Reference
+
+
+ +

Delonghi based protocol. +More...

+ + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kDelonghiAcHdrMark = 8984
 
const uint16_t kDelonghiAcBitMark = 572
 
const uint16_t kDelonghiAcHdrSpace = 4200
 
const uint16_t kDelonghiAcOneSpace = 1558
 
const uint16_t kDelonghiAcZeroSpace = 510
 
const uint32_t kDelonghiAcGap = kDefaultMessageGap
 
const uint16_t kDelonghiAcFreq = 38000
 
const uint16_t kDelonghiAcOverhead = 3
 
+

Detailed Description

+

Delonghi based protocol.

+

Variable Documentation

+ +

◆ kDelonghiAcBitMark

+ +
+
+ + + + +
const uint16_t kDelonghiAcBitMark = 572
+
+ +
+
+ +

◆ kDelonghiAcFreq

+ +
+
+ + + + +
const uint16_t kDelonghiAcFreq = 38000
+
+ +
+
+ +

◆ kDelonghiAcGap

+ +
+
+ + + + +
const uint32_t kDelonghiAcGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kDelonghiAcHdrMark

+ +
+
+ + + + +
const uint16_t kDelonghiAcHdrMark = 8984
+
+ +
+
+ +

◆ kDelonghiAcHdrSpace

+ +
+
+ + + + +
const uint16_t kDelonghiAcHdrSpace = 4200
+
+ +
+
+ +

◆ kDelonghiAcOneSpace

+ +
+
+ + + + +
const uint16_t kDelonghiAcOneSpace = 1558
+
+ +
+
+ +

◆ kDelonghiAcOverhead

+ +
+
+ + + + +
const uint16_t kDelonghiAcOverhead = 3
+
+ +
+
+ +

◆ kDelonghiAcZeroSpace

+ +
+
+ + + + +
const uint16_t kDelonghiAcZeroSpace = 510
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h.html new file mode 100644 index 000000000..4a6219b46 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h.html @@ -0,0 +1,695 @@ + + + + + + + +IRremoteESP8266: src/ir_Delonghi.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Delonghi.h File Reference
+
+
+ +

Delonghi A/C. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRDelonghiAc
 Class for handling detailed Delonghi A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kDelonghiAcTempOffset = 8
 
const uint8_t kDelonghiAcTempSize = 5
 
const uint8_t kDelonghiAcTempMinC = 18
 
const uint8_t kDelonghiAcTempMaxC = 32
 
const uint8_t kDelonghiAcTempMinF = 64
 
const uint8_t kDelonghiAcTempMaxF = 90
 
const uint8_t kDelonghiAcTempAutoDryMode = 0
 
const uint8_t kDelonghiAcTempFanMode = 0b00110
 
const uint8_t kDelonghiAcFanOffset
 
const uint8_t kDelonghiAcFanSize = 2
 
const uint8_t kDelonghiAcFanAuto = 0b00
 
const uint8_t kDelonghiAcFanHigh = 0b01
 
const uint8_t kDelonghiAcFanMedium = 0b10
 
const uint8_t kDelonghiAcFanLow = 0b11
 
const uint8_t kDelonghiAcTempUnitBit
 
const uint8_t kDelonghiAcPowerBit = kDelonghiAcTempUnitBit + 1
 
const uint8_t kDelonghiAcModeOffset = kDelonghiAcPowerBit + 1
 
const uint8_t kDelonghiAcModeSize = 3
 
const uint8_t kDelonghiAcCool = 0b000
 
const uint8_t kDelonghiAcDry = 0b001
 
const uint8_t kDelonghiAcFan = 0b010
 
const uint8_t kDelonghiAcAuto = 0b100
 
const uint8_t kDelonghiAcBoostBit
 
const uint8_t kDelonghiAcSleepBit = kDelonghiAcBoostBit + 1
 
const uint8_t kDelonghiAcOnTimerEnableBit = kDelonghiAcSleepBit + 3
 
const uint8_t kDelonghiAcHoursSize = 5
 
const uint8_t kDelonghiAcMinsSize = 6
 
const uint16_t kDelonghiAcTimerMax = 23 * 60 + 59
 
const uint8_t kDelonghiAcOnTimerHoursOffset
 
const uint8_t kDelonghiAcOnTimerMinsOffset
 
const uint8_t kDelonghiAcOffTimerEnableBit
 
const uint8_t kDelonghiAcOffTimerHoursOffset
 
const uint8_t kDelonghiAcOffTimerMinsOffset
 
const uint8_t kDelonghiAcChecksumOffset
 
const uint8_t kDelonghiAcChecksumSize = 8
 
+

Detailed Description

+

Delonghi A/C.

+
Note
Kudos to TheMaxxz For the breakdown and mapping of the bit values.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1096
+

Variable Documentation

+ +

◆ kDelonghiAcAuto

+ +
+
+ + + + +
const uint8_t kDelonghiAcAuto = 0b100
+
+ +
+
+ +

◆ kDelonghiAcBoostBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcBoostBit
+
+Initial value: +
+
+ +

◆ kDelonghiAcChecksumOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcChecksumOffset
+
+
+ +

◆ kDelonghiAcChecksumSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcChecksumSize = 8
+
+ +
+
+ +

◆ kDelonghiAcCool

+ +
+
+ + + + +
const uint8_t kDelonghiAcCool = 0b000
+
+ +
+
+ +

◆ kDelonghiAcDry

+ +
+
+ + + + +
const uint8_t kDelonghiAcDry = 0b001
+
+ +
+
+ +

◆ kDelonghiAcFan

+ +
+
+ + + + +
const uint8_t kDelonghiAcFan = 0b010
+
+ +
+
+ +

◆ kDelonghiAcFanAuto

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanAuto = 0b00
+
+ +
+
+ +

◆ kDelonghiAcFanHigh

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanHigh = 0b01
+
+ +
+
+ +

◆ kDelonghiAcFanLow

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanLow = 0b11
+
+ +
+
+ +

◆ kDelonghiAcFanMedium

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanMedium = 0b10
+
+ +
+
+ +

◆ kDelonghiAcFanOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanOffset
+
+Initial value: +
+
+ +

◆ kDelonghiAcFanSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanSize = 2
+
+ +
+
+ +

◆ kDelonghiAcHoursSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcHoursSize = 5
+
+ +
+
+ +

◆ kDelonghiAcMinsSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcMinsSize = 6
+
+ +
+
+ +

◆ kDelonghiAcModeOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcModeOffset = kDelonghiAcPowerBit + 1
+
+ +
+
+ +

◆ kDelonghiAcModeSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcModeSize = 3
+
+ +
+
+ +

◆ kDelonghiAcOffTimerEnableBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcOffTimerEnableBit
+
+
+ +

◆ kDelonghiAcOffTimerHoursOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcOffTimerHoursOffset
+
+Initial value: +
+
+ +

◆ kDelonghiAcOffTimerMinsOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcOffTimerMinsOffset
+
+
+ +

◆ kDelonghiAcOnTimerEnableBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcOnTimerEnableBit = kDelonghiAcSleepBit + 3
+
+ +
+
+ +

◆ kDelonghiAcOnTimerHoursOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcOnTimerHoursOffset
+
+Initial value: +
+
+ +

◆ kDelonghiAcOnTimerMinsOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcOnTimerMinsOffset
+
+
+ +

◆ kDelonghiAcPowerBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcPowerBit = kDelonghiAcTempUnitBit + 1
+
+ +
+
+ +

◆ kDelonghiAcSleepBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcSleepBit = kDelonghiAcBoostBit + 1
+
+ +
+
+ +

◆ kDelonghiAcTempAutoDryMode

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempAutoDryMode = 0
+
+ +
+
+ +

◆ kDelonghiAcTempFanMode

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempFanMode = 0b00110
+
+ +
+
+ +

◆ kDelonghiAcTempMaxC

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempMaxC = 32
+
+ +
+
+ +

◆ kDelonghiAcTempMaxF

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempMaxF = 90
+
+ +
+
+ +

◆ kDelonghiAcTempMinC

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempMinC = 18
+
+ +
+
+ +

◆ kDelonghiAcTempMinF

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempMinF = 64
+
+ +
+
+ +

◆ kDelonghiAcTempOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempOffset = 8
+
+ +
+
+ +

◆ kDelonghiAcTempSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempSize = 5
+
+ +
+
+ +

◆ kDelonghiAcTempUnitBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempUnitBit
+
+Initial value: +
+
+ +

◆ kDelonghiAcTimerMax

+ +
+
+ + + + +
const uint16_t kDelonghiAcTimerMax = 23 * 60 + 59
+
+ +
+
+
+
const uint8_t kDelonghiAcTempOffset
Definition: ir_Delonghi.h:50
+
const uint8_t kDelonghiAcOnTimerHoursOffset
Definition: ir_Delonghi.h:82
+
const uint8_t kDelonghiAcModeOffset
Definition: ir_Delonghi.h:68
+
const uint8_t kDelonghiAcOnTimerMinsOffset
Definition: ir_Delonghi.h:84
+
const uint8_t kDelonghiAcModeSize
Definition: ir_Delonghi.h:69
+
const uint8_t kDelonghiAcTempSize
Definition: ir_Delonghi.h:51
+
const uint8_t kDelonghiAcOffTimerMinsOffset
Definition: ir_Delonghi.h:91
+
const uint8_t kDelonghiAcFanSize
Definition: ir_Delonghi.h:60
+
const uint8_t kDelonghiAcOnTimerEnableBit
Definition: ir_Delonghi.h:78
+
const uint8_t kDelonghiAcMinsSize
Definition: ir_Delonghi.h:80
+
const uint8_t kDelonghiAcOffTimerEnableBit
Definition: ir_Delonghi.h:87
+
const uint8_t kDelonghiAcHoursSize
Definition: ir_Delonghi.h:79
+
const uint8_t kDelonghiAcFanOffset
Definition: ir_Delonghi.h:58
+
const uint8_t kDelonghiAcOffTimerHoursOffset
Definition: ir_Delonghi.h:89
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h_source.html new file mode 100644 index 000000000..c14c0dbe1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h_source.html @@ -0,0 +1,323 @@ + + + + + + + +IRremoteESP8266: src/ir_Delonghi.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Delonghi.h
+
+
+Go to the documentation of this file.
1 // Copyright 2020 David Conran
+
2 
+
7 
+
8 // Supports:
+
9 // Brand: Delonghi, Model: PAC A95
+
10 
+
11 #ifndef IR_DELONGHI_H_
+
12 #define IR_DELONGHI_H_
+
13 
+
14 #define __STDC_LIMIT_MACROS
+
15 #include <stdint.h>
+
16 #ifndef UNIT_TEST
+
17 #include <Arduino.h>
+
18 #endif
+
19 #include "IRremoteESP8266.h"
+
20 #include "IRsend.h"
+
21 #ifdef UNIT_TEST
+
22 #include "IRsend_test.h"
+
23 #endif
+
24 
+
25 /* State bit map:
+
26 
+
27 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------+
+
28 | FIXED HEADER | TEMPERATURE | FAN |F or C|
+
29 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------+
+
30  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+
31 
+
32 +--+--+--+--+-----+-----+
+
33 |ON| MODE |Boost|Sleep|
+
34 +--+--+--+--+-----+-----+
+
35 16 17 18 19 20 21
+
36 
+
37 +--+--+------------+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
38 | 0| 0|Timer Enable| ON TIME HOUR | 0 0| ON TIME MIN |
+
39 +--+--+------------+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
40  22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
+
41 
+
42 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
43 | 0 0| OFF TIMER | CHECKSUM |
+
44 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
45  38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+
46 
+
47 */
+
48 
+
49 // Constants
+
50 const uint8_t kDelonghiAcTempOffset = 8;
+
51 const uint8_t kDelonghiAcTempSize = 5;
+
52 const uint8_t kDelonghiAcTempMinC = 18; // Deg C
+
53 const uint8_t kDelonghiAcTempMaxC = 32; // Deg C
+
54 const uint8_t kDelonghiAcTempMinF = 64; // Deg F
+
55 const uint8_t kDelonghiAcTempMaxF = 90; // Deg F
+
56 const uint8_t kDelonghiAcTempAutoDryMode = 0;
+
57 const uint8_t kDelonghiAcTempFanMode = 0b00110;
+ +
59  kDelonghiAcTempSize; // 13
+
60 const uint8_t kDelonghiAcFanSize = 2;
+
61 const uint8_t kDelonghiAcFanAuto = 0b00;
+
62 const uint8_t kDelonghiAcFanHigh = 0b01;
+
63 const uint8_t kDelonghiAcFanMedium = 0b10;
+
64 const uint8_t kDelonghiAcFanLow = 0b11;
+ +
66  kDelonghiAcFanSize; // 15 (1 = Celsius, 0 = Fahrenheit)
+
67 const uint8_t kDelonghiAcPowerBit = kDelonghiAcTempUnitBit + 1; // 16
+
68 const uint8_t kDelonghiAcModeOffset = kDelonghiAcPowerBit + 1; // 17
+
69 const uint8_t kDelonghiAcModeSize = 3;
+
70 const uint8_t kDelonghiAcCool = 0b000;
+
71 const uint8_t kDelonghiAcDry = 0b001;
+
72 const uint8_t kDelonghiAcFan = 0b010;
+
73 const uint8_t kDelonghiAcAuto = 0b100;
+ +
75  kDelonghiAcModeSize; // 20 (Aka Turbo)
+
76 const uint8_t kDelonghiAcSleepBit = kDelonghiAcBoostBit + 1; // 21
+
77 // Two zero bits
+ +
79 const uint8_t kDelonghiAcHoursSize = 5; // Max 23 hrs
+
80 const uint8_t kDelonghiAcMinsSize = 6; // Max 59 mins
+
81 const uint16_t kDelonghiAcTimerMax = 23 * 60 + 59;
+ +
83  1; // 25
+ +
85  kDelonghiAcHoursSize + 2; // 32 (inc another two zero bits)
+
86 // Two zero bits
+ +
88  kDelonghiAcMinsSize + 2; // 40
+ +
90  1; // 41
+ +
92  kDelonghiAcHoursSize + 2; // 48 (inc another two zero bits)
+
93 // Two zero bits
+ +
95  kDelonghiAcMinsSize + 2; // 56
+
96 const uint8_t kDelonghiAcChecksumSize = 8;
+
97 
+
98 
+
99 // Classes
+
100 
+ +
103  public:
+
104  explicit IRDelonghiAc(const uint16_t pin, const bool inverted = false,
+
105  const bool use_modulation = true);
+
106  void stateReset();
+
107 #if SEND_DELONGHI_AC
+
108  void send(const uint16_t repeat = kDelonghiAcDefaultRepeat);
+
113  int8_t calibrate(void) { return _irsend.calibrate(); }
+
114 #endif // SEND_DELONGHI_AC
+
115  void begin();
+
116  static uint8_t calcChecksum(const uint64_t state);
+
117  static bool validChecksum(const uint64_t state);
+
118  void setPower(const bool on);
+
119  bool getPower();
+
120  void on();
+
121  void off();
+
122  void setTempUnit(const bool celsius);
+
123  bool getTempUnit(void);
+
124  void setTemp(const uint8_t temp, const bool fahrenheit = false,
+
125  const bool force = false);
+
126  uint8_t getTemp();
+
127  void setFan(const uint8_t speed);
+
128  uint8_t getFan();
+
129  void setMode(const uint8_t mode);
+
130  uint8_t getMode();
+
131  void setBoost(const bool on); // Aka Turbo
+
132  bool getBoost(); // Aka Turbo
+
133  void setSleep(const bool on);
+
134  bool getSleep();
+
135  void setOnTimerEnabled(const bool on);
+
136  bool getOnTimerEnabled(void);
+
137  void setOnTimer(const uint16_t nr_of_mins);
+
138  uint16_t getOnTimer(void);
+
139  void setOffTimerEnabled(const bool on);
+
140  bool getOffTimerEnabled(void);
+
141  void setOffTimer(const uint16_t nr_of_mins);
+
142  uint16_t getOffTimer(void);
+
143  uint64_t getRaw();
+
144  void setRaw(const uint64_t state);
+
145  uint8_t convertMode(const stdAc::opmode_t mode);
+
146  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
147  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
148  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
149  stdAc::state_t toCommon(void);
+
150  String toString();
+
151 #ifndef UNIT_TEST
+
152 
+
153  private:
+ +
155 #else
+
156  IRsendTest _irsend;
+
158 #endif
+
160  uint64_t remote_state;
+
161  uint8_t _saved_temp;
+ +
163  void checksum(void);
+
164 };
+
165 #endif // IR_DELONGHI_H_
+
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Delonghi.cpp:274
+
const uint8_t kDelonghiAcCool
Definition: ir_Delonghi.h:70
+
uint16_t getOnTimer(void)
Get the On timer time.
Definition: ir_Delonghi.cpp:393
+
const uint8_t kDelonghiAcTempOffset
Definition: ir_Delonghi.h:50
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Delonghi.cpp:100
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Delonghi.cpp:221
+
void send(const uint16_t repeat=kDelonghiAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Delonghi.cpp:105
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Delonghi.cpp:333
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Delonghi.cpp:214
+
void setRaw(const uint64_t state)
Set the internal state from a valid code for this protocol.
Definition: ir_Delonghi.cpp:153
+
const uint8_t kDelonghiAcTempFanMode
Definition: ir_Delonghi.h:57
+
const uint8_t kDelonghiAcOnTimerHoursOffset
Definition: ir_Delonghi.h:82
+
Class for handling detailed Delonghi A/C messages.
Definition: ir_Delonghi.h:102
+
IRDelonghiAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Delonghi.cpp:95
+
const uint8_t kDelonghiAcModeOffset
Definition: ir_Delonghi.h:68
+
const uint8_t kDelonghiAcTempMinC
Definition: ir_Delonghi.h:52
+
const uint8_t kDelonghiAcFanHigh
Definition: ir_Delonghi.h:62
+
void setOnTimer(const uint16_t nr_of_mins)
Set the On timer to activate in nr of minutes.
Definition: ir_Delonghi.cpp:381
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Delonghi.cpp:163
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
uint8_t _saved_temp
The previously user requested temp value.
Definition: ir_Delonghi.h:161
+
const uint8_t kDelonghiAcOnTimerMinsOffset
Definition: ir_Delonghi.h:84
+
void setOffTimerEnabled(const bool on)
Set the enable status of the Off Timer.
Definition: ir_Delonghi.cpp:402
+
const uint8_t kDelonghiAcFanMedium
Definition: ir_Delonghi.h:63
+
const uint8_t kDelonghiAcTempAutoDryMode
Definition: ir_Delonghi.h:56
+
const uint8_t kDelonghiAcFanLow
Definition: ir_Delonghi.h:64
+
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Delonghi.cpp:125
+
void on()
Change the power setting to On.
Definition: ir_Delonghi.cpp:156
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Delonghi.cpp:317
+ +
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Delonghi.h:113
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Delonghi.cpp:138
+
bool getPower()
Get the value of the current power setting.
Definition: ir_Delonghi.cpp:169
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
bool getOnTimerEnabled(void)
Get the enable status of the On Timer.
Definition: ir_Delonghi.cpp:374
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Delonghi.cpp:256
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kDelonghiAcModeSize
Definition: ir_Delonghi.h:69
+
const uint8_t kDelonghiAcFanAuto
Definition: ir_Delonghi.h:61
+
const uint8_t kDelonghiAcChecksumOffset
Definition: ir_Delonghi.h:94
+
void setOnTimerEnabled(const bool on)
Set the enable status of the On Timer.
Definition: ir_Delonghi.cpp:368
+
const uint8_t kDelonghiAcTempSize
Definition: ir_Delonghi.h:51
+
const uint8_t kDelonghiAcTempMaxF
Definition: ir_Delonghi.h:55
+
uint16_t getOffTimer(void)
Get the Off timer time.
Definition: ir_Delonghi.cpp:427
+
bool getBoost()
Get the Boost (Turbo) mode of the A/C.
Definition: ir_Delonghi.cpp:350
+ +
const uint8_t kDelonghiAcAuto
Definition: ir_Delonghi.h:73
+
const uint8_t kDelonghiAcOffTimerMinsOffset
Definition: ir_Delonghi.h:91
+
const uint8_t kDelonghiAcBoostBit
Definition: ir_Delonghi.h:74
+
const uint8_t kDelonghiAcSleepBit
Definition: ir_Delonghi.h:76
+
const uint8_t kDelonghiAcPowerBit
Definition: ir_Delonghi.h:67
+
const uint8_t kDelonghiAcFanSize
Definition: ir_Delonghi.h:60
+
bool getTempUnit(void)
Get the temperature scale unit of measure currently in use.
Definition: ir_Delonghi.cpp:181
+
const uint8_t kDelonghiAcOnTimerEnableBit
Definition: ir_Delonghi.h:78
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Delonghi.cpp:132
+
void setSleep(const bool on)
Set the Sleep mode of the A/C.
Definition: ir_Delonghi.cpp:356
+
const uint16_t kDelonghiAcDefaultRepeat
Definition: IRremoteESP8266.h:862
+
uint8_t _saved_temp_units
The previously user requested temp units.
Definition: ir_Delonghi.h:162
+
const uint16_t kDelonghiAcTimerMax
Definition: ir_Delonghi.h:81
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Delonghi.cpp:291
+
void setTemp(const uint8_t temp, const bool fahrenheit=false, const bool force=false)
Set the temperature.
Definition: ir_Delonghi.cpp:189
+
void setOffTimer(const uint16_t nr_of_mins)
Set the Off timer to activate in nr of minutes.
Definition: ir_Delonghi.cpp:415
+
bool getOffTimerEnabled(void)
Get the enable status of the Off Timer.
Definition: ir_Delonghi.cpp:408
+
const uint8_t kDelonghiAcMinsSize
Definition: ir_Delonghi.h:80
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Delonghi.cpp:113
+
IRsend _irsend
instance of the IR send class
Definition: ir_Delonghi.h:154
+
const uint8_t kDelonghiAcTempUnitBit
Definition: ir_Delonghi.h:65
+
void setTempUnit(const bool celsius)
Change the temperature scale units.
Definition: ir_Delonghi.cpp:175
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Delonghi.cpp:436
+
bool getSleep()
Get the Sleep mode status of the A/C.
Definition: ir_Delonghi.cpp:362
+
uint64_t remote_state
The state of the IR remote.
Definition: ir_Delonghi.h:160
+
uint8_t getFan()
Get the current native fan speed setting.
Definition: ir_Delonghi.cpp:249
+
const uint8_t kDelonghiAcOffTimerEnableBit
Definition: ir_Delonghi.h:87
+
const uint8_t kDelonghiAcDry
Definition: ir_Delonghi.h:71
+
const uint8_t kDelonghiAcFan
Definition: ir_Delonghi.h:72
+
uint64_t getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Delonghi.cpp:146
+
const uint8_t kDelonghiAcChecksumSize
Definition: ir_Delonghi.h:96
+
const uint8_t kDelonghiAcHoursSize
Definition: ir_Delonghi.h:79
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Delonghi.cpp:285
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Delonghi.cpp:462
+
const uint8_t kDelonghiAcFanOffset
Definition: ir_Delonghi.h:58
+
void setBoost(const bool on)
Set the Boost (Turbo) mode of the A/C.
Definition: ir_Delonghi.cpp:344
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void off()
Change the power setting to Off.
Definition: ir_Delonghi.cpp:159
+
const uint8_t kDelonghiAcTempMinF
Definition: ir_Delonghi.h:54
+
const uint8_t kDelonghiAcOffTimerHoursOffset
Definition: ir_Delonghi.h:89
+
const uint8_t kDelonghiAcTempMaxC
Definition: ir_Delonghi.h:53
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Denon_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Denon_8cpp.html new file mode 100644 index 000000000..4e9d4d77e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Denon_8cpp.html @@ -0,0 +1,346 @@ + + + + + + + +IRremoteESP8266: src/ir_Denon.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Denon.cpp File Reference
+
+
+ +

Denon support Original Denon support added by https://github.com/csBlueChip Ported over by Massimiliano Pinto. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kDenonTick = 263
 
const uint16_t kDenonHdrMarkTicks = 1
 
const uint16_t kDenonHdrMark = kDenonHdrMarkTicks * kDenonTick
 
const uint16_t kDenonHdrSpaceTicks = 3
 
const uint16_t kDenonHdrSpace = kDenonHdrSpaceTicks * kDenonTick
 
const uint16_t kDenonBitMarkTicks = 1
 
const uint16_t kDenonBitMark = kDenonBitMarkTicks * kDenonTick
 
const uint16_t kDenonOneSpaceTicks = 7
 
const uint16_t kDenonOneSpace = kDenonOneSpaceTicks * kDenonTick
 
const uint16_t kDenonZeroSpaceTicks = 3
 
const uint16_t kDenonZeroSpace = kDenonZeroSpaceTicks * kDenonTick
 
const uint16_t kDenonMinCommandLengthTicks = 510
 
const uint16_t kDenonMinGapTicks
 
const uint32_t kDenonMinGap = kDenonMinGapTicks * kDenonTick
 
const uint64_t kDenonManufacturer = 0x2A4CULL
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kDenonBitMark

+ +
+
+ + + + +
const uint16_t kDenonBitMark = kDenonBitMarkTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonBitMarkTicks

+ +
+
+ + + + +
const uint16_t kDenonBitMarkTicks = 1
+
+ +
+
+ +

◆ kDenonHdrMark

+ +
+
+ + + + +
const uint16_t kDenonHdrMark = kDenonHdrMarkTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kDenonHdrMarkTicks = 1
+
+ +
+
+ +

◆ kDenonHdrSpace

+ +
+
+ + + + +
const uint16_t kDenonHdrSpace = kDenonHdrSpaceTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kDenonHdrSpaceTicks = 3
+
+ +
+
+ +

◆ kDenonManufacturer

+ +
+
+ + + + +
const uint64_t kDenonManufacturer = 0x2A4CULL
+
+ +
+
+ +

◆ kDenonMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kDenonMinCommandLengthTicks = 510
+
+ +
+
+ +

◆ kDenonMinGap

+ +
+
+ + + + +
const uint32_t kDenonMinGap = kDenonMinGapTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonMinGapTicks

+ +
+
+ + + + +
const uint16_t kDenonMinGapTicks
+
+
+ +

◆ kDenonOneSpace

+ +
+
+ + + + +
const uint16_t kDenonOneSpace = kDenonOneSpaceTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kDenonOneSpaceTicks = 7
+
+ +
+
+ +

◆ kDenonTick

+ +
+
+ + + + +
const uint16_t kDenonTick = 263
+
+ +
+
+ +

◆ kDenonZeroSpace

+ +
+
+ + + + +
const uint16_t kDenonZeroSpace = kDenonZeroSpaceTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kDenonZeroSpaceTicks = 3
+
+ +
+
+
+
const uint16_t kDenonMinCommandLengthTicks
Definition: ir_Denon.cpp:31
+
const uint16_t kDenonHdrSpaceTicks
Definition: ir_Denon.cpp:23
+
const uint16_t kDenonBitMarkTicks
Definition: ir_Denon.cpp:25
+
const uint16_t kDenonHdrMarkTicks
Definition: ir_Denon.cpp:21
+
const uint16_t kDenonBits
Definition: IRremoteESP8266.h:863
+
const uint16_t kDenonOneSpaceTicks
Definition: ir_Denon.cpp:27
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Dish_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Dish_8cpp.html new file mode 100644 index 000000000..abc86c6b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Dish_8cpp.html @@ -0,0 +1,305 @@ + + + + + + + +IRremoteESP8266: src/ir_Dish.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Dish.cpp File Reference
+
+
+ +

DISH Network protocol support DISH support originally by Todd Treece. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kDishTick = 100
 
const uint16_t kDishHdrMarkTicks = 4
 
const uint16_t kDishHdrMark = kDishHdrMarkTicks * kDishTick
 
const uint16_t kDishHdrSpaceTicks = 61
 
const uint16_t kDishHdrSpace = kDishHdrSpaceTicks * kDishTick
 
const uint16_t kDishBitMarkTicks = 4
 
const uint16_t kDishBitMark = kDishBitMarkTicks * kDishTick
 
const uint16_t kDishOneSpaceTicks = 17
 
const uint16_t kDishOneSpace = kDishOneSpaceTicks * kDishTick
 
const uint16_t kDishZeroSpaceTicks = 28
 
const uint16_t kDishZeroSpace = kDishZeroSpaceTicks * kDishTick
 
const uint16_t kDishRptSpaceTicks = kDishHdrSpaceTicks
 
const uint16_t kDishRptSpace = kDishRptSpaceTicks * kDishTick
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kDishBitMark

+ +
+
+ + + + +
const uint16_t kDishBitMark = kDishBitMarkTicks * kDishTick
+
+ +
+
+ +

◆ kDishBitMarkTicks

+ +
+
+ + + + +
const uint16_t kDishBitMarkTicks = 4
+
+ +
+
+ +

◆ kDishHdrMark

+ +
+
+ + + + +
const uint16_t kDishHdrMark = kDishHdrMarkTicks * kDishTick
+
+ +
+
+ +

◆ kDishHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kDishHdrMarkTicks = 4
+
+ +
+
+ +

◆ kDishHdrSpace

+ +
+
+ + + + +
const uint16_t kDishHdrSpace = kDishHdrSpaceTicks * kDishTick
+
+ +
+
+ +

◆ kDishHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kDishHdrSpaceTicks = 61
+
+ +
+
+ +

◆ kDishOneSpace

+ +
+
+ + + + +
const uint16_t kDishOneSpace = kDishOneSpaceTicks * kDishTick
+
+ +
+
+ +

◆ kDishOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kDishOneSpaceTicks = 17
+
+ +
+
+ +

◆ kDishRptSpace

+ +
+
+ + + + +
const uint16_t kDishRptSpace = kDishRptSpaceTicks * kDishTick
+
+ +
+
+ +

◆ kDishRptSpaceTicks

+ +
+
+ + + + +
const uint16_t kDishRptSpaceTicks = kDishHdrSpaceTicks
+
+ +
+
+ +

◆ kDishTick

+ +
+
+ + + + +
const uint16_t kDishTick = 100
+
+ +
+
+ +

◆ kDishZeroSpace

+ +
+
+ + + + +
const uint16_t kDishZeroSpace = kDishZeroSpaceTicks * kDishTick
+
+ +
+
+ +

◆ kDishZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kDishZeroSpaceTicks = 28
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Doshisha_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Doshisha_8cpp.html new file mode 100644 index 000000000..7e19c1cdc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Doshisha_8cpp.html @@ -0,0 +1,429 @@ + + + + + + + +IRremoteESP8266: src/ir_Doshisha.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Doshisha.cpp File Reference
+
+
+ +

Doshisha protocol support. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kDoshishaHdrMark = 3412
 
const uint16_t kDoshishaHdrSpace = 1722
 
const uint16_t kDoshishaBitMark = 420
 
const uint16_t kDoshishaOneSpace = 1310
 
const uint16_t kDoshishaZeroSpace = 452
 
const uint64_t kRcz01SignatureMask = 0xffffffff00
 
const uint64_t kRcz01Signature = 0x800B304800
 
const uint8_t kRcz01CommandMask = 0xFE
 
const uint8_t kRcz01ChannelMask = 0x01
 
const uint8_t kRcz01CommandSwitchChannel = 0xD2
 
const uint8_t kRcz01CommandTimmer60 = 0x52
 
const uint8_t kRcz01CommandTimmer30 = 0x92
 
const uint8_t kRcz01CommandOff = 0xA0
 
const uint8_t kRcz01CommandLevelDown = 0x2C
 
const uint8_t kRcz01CommandLevelUp = 0xCC
 
const uint8_t kRcz01CommandLevel1 = 0xA4
 
const uint8_t kRcz01CommandLevel2 = 0x24
 
const uint8_t kRcz01CommandLevel3 = 0xC4
 
const uint8_t kRcz01CommandLevel4 = 0xD0
 
const uint8_t kRcz01CommandOn = 0xC0
 
const uint8_t kRcz01CommandNightLight = 0xC8
 
+

Detailed Description

+

Doshisha protocol support.

+
See also
https://www.doshisha-led.com/
+

Variable Documentation

+ +

◆ kDoshishaBitMark

+ +
+
+ + + + +
const uint16_t kDoshishaBitMark = 420
+
+ +
+
+ +

◆ kDoshishaHdrMark

+ +
+
+ + + + +
const uint16_t kDoshishaHdrMark = 3412
+
+ +
+
+ +

◆ kDoshishaHdrSpace

+ +
+
+ + + + +
const uint16_t kDoshishaHdrSpace = 1722
+
+ +
+
+ +

◆ kDoshishaOneSpace

+ +
+
+ + + + +
const uint16_t kDoshishaOneSpace = 1310
+
+ +
+
+ +

◆ kDoshishaZeroSpace

+ +
+
+ + + + +
const uint16_t kDoshishaZeroSpace = 452
+
+ +
+
+ +

◆ kRcz01ChannelMask

+ +
+
+ + + + +
const uint8_t kRcz01ChannelMask = 0x01
+
+ +
+
+ +

◆ kRcz01CommandLevel1

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevel1 = 0xA4
+
+ +
+
+ +

◆ kRcz01CommandLevel2

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevel2 = 0x24
+
+ +
+
+ +

◆ kRcz01CommandLevel3

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevel3 = 0xC4
+
+ +
+
+ +

◆ kRcz01CommandLevel4

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevel4 = 0xD0
+
+ +
+
+ +

◆ kRcz01CommandLevelDown

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevelDown = 0x2C
+
+ +
+
+ +

◆ kRcz01CommandLevelUp

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevelUp = 0xCC
+
+ +
+
+ +

◆ kRcz01CommandMask

+ +
+
+ + + + +
const uint8_t kRcz01CommandMask = 0xFE
+
+ +
+
+ +

◆ kRcz01CommandNightLight

+ +
+
+ + + + +
const uint8_t kRcz01CommandNightLight = 0xC8
+
+ +
+
+ +

◆ kRcz01CommandOff

+ +
+
+ + + + +
const uint8_t kRcz01CommandOff = 0xA0
+
+ +
+
+ +

◆ kRcz01CommandOn

+ +
+
+ + + + +
const uint8_t kRcz01CommandOn = 0xC0
+
+ +
+
+ +

◆ kRcz01CommandSwitchChannel

+ +
+
+ + + + +
const uint8_t kRcz01CommandSwitchChannel = 0xD2
+
+ +
+
+ +

◆ kRcz01CommandTimmer30

+ +
+
+ + + + +
const uint8_t kRcz01CommandTimmer30 = 0x92
+
+ +
+
+ +

◆ kRcz01CommandTimmer60

+ +
+
+ + + + +
const uint8_t kRcz01CommandTimmer60 = 0x52
+
+ +
+
+ +

◆ kRcz01Signature

+ +
+
+ + + + +
const uint64_t kRcz01Signature = 0x800B304800
+
+ +
+
+ +

◆ kRcz01SignatureMask

+ +
+
+ + + + +
const uint64_t kRcz01SignatureMask = 0xffffffff00
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8cpp.html new file mode 100644 index 000000000..30e634456 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8cpp.html @@ -0,0 +1,195 @@ + + + + + + + +IRremoteESP8266: src/ir_Electra.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Electra.cpp File Reference
+
+
+ +

Support for Electra A/C protocols. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kElectraAcHdrMark = 9166
 
const uint16_t kElectraAcBitMark = 646
 
const uint16_t kElectraAcHdrSpace = 4470
 
const uint16_t kElectraAcOneSpace = 1647
 
const uint16_t kElectraAcZeroSpace = 547
 
const uint32_t kElectraAcMessageGap = kDefaultMessageGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kElectraAcBitMark

+ +
+
+ + + + +
const uint16_t kElectraAcBitMark = 646
+
+ +
+
+ +

◆ kElectraAcHdrMark

+ +
+
+ + + + +
const uint16_t kElectraAcHdrMark = 9166
+
+ +
+
+ +

◆ kElectraAcHdrSpace

+ +
+
+ + + + +
const uint16_t kElectraAcHdrSpace = 4470
+
+ +
+
+ +

◆ kElectraAcMessageGap

+ +
+
+ + + + +
const uint32_t kElectraAcMessageGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kElectraAcOneSpace

+ +
+
+ + + + +
const uint16_t kElectraAcOneSpace = 1647
+
+ +
+
+ +

◆ kElectraAcZeroSpace

+ +
+
+ + + + +
const uint16_t kElectraAcZeroSpace = 547
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h.html new file mode 100644 index 000000000..e66afd648 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h.html @@ -0,0 +1,550 @@ + + + + + + + +IRremoteESP8266: src/ir_Electra.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Electra.h File Reference
+
+
+ +

Support for Electra A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRElectraAc
 Class for handling detailed Electra A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kElectraAcTempOffset = 3
 
const uint8_t kElectraAcTempSize = 5
 
const uint8_t kElectraAcMinTemp = 16
 
const uint8_t kElectraAcMaxTemp = 32
 
const uint8_t kElectraAcTempDelta = 8
 
const uint8_t kElectraAcSwingSize = 3
 
const uint8_t kElectraAcSwingOn = 0b000
 
const uint8_t kElectraAcSwingOff = 0b111
 
const uint8_t kElectraAcSwingVOffset = 0
 
const uint8_t kElectraAcSwingHOffset = 5
 
const uint8_t kElectraAcFanOffset = 5
 
const uint8_t kElectraAcFanSize = 3
 
const uint8_t kElectraAcFanAuto = 0b101
 
const uint8_t kElectraAcFanLow = 0b011
 
const uint8_t kElectraAcFanMed = 0b010
 
const uint8_t kElectraAcFanHigh = 0b001
 
const uint8_t kElectraAcTurboOffset = 6
 
const uint8_t kElectraAcModeOffset = 5
 
const uint8_t kElectraAcAuto = 0b000
 
const uint8_t kElectraAcCool = 0b001
 
const uint8_t kElectraAcDry = 0b010
 
const uint8_t kElectraAcHeat = 0b100
 
const uint8_t kElectraAcFan = 0b110
 
const uint8_t kElectraAcCleanOffset = 2
 
const uint8_t kElectraAcPowerOffset = 5
 
const uint8_t kElectraAcLightToggleOn = 0x15
 
const uint8_t kElectraAcLightToggleMask = 0x11
 
const uint8_t kElectraAcLightToggleOff = 0x08
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kElectraAcAuto

+ +
+
+ + + + +
const uint8_t kElectraAcAuto = 0b000
+
+ +
+
+ +

◆ kElectraAcCleanOffset

+ +
+
+ + + + +
const uint8_t kElectraAcCleanOffset = 2
+
+ +
+
+ +

◆ kElectraAcCool

+ +
+
+ + + + +
const uint8_t kElectraAcCool = 0b001
+
+ +
+
+ +

◆ kElectraAcDry

+ +
+
+ + + + +
const uint8_t kElectraAcDry = 0b010
+
+ +
+
+ +

◆ kElectraAcFan

+ +
+
+ + + + +
const uint8_t kElectraAcFan = 0b110
+
+ +
+
+ +

◆ kElectraAcFanAuto

+ +
+
+ + + + +
const uint8_t kElectraAcFanAuto = 0b101
+
+ +
+
+ +

◆ kElectraAcFanHigh

+ +
+
+ + + + +
const uint8_t kElectraAcFanHigh = 0b001
+
+ +
+
+ +

◆ kElectraAcFanLow

+ +
+
+ + + + +
const uint8_t kElectraAcFanLow = 0b011
+
+ +
+
+ +

◆ kElectraAcFanMed

+ +
+
+ + + + +
const uint8_t kElectraAcFanMed = 0b010
+
+ +
+
+ +

◆ kElectraAcFanOffset

+ +
+
+ + + + +
const uint8_t kElectraAcFanOffset = 5
+
+ +
+
+ +

◆ kElectraAcFanSize

+ +
+
+ + + + +
const uint8_t kElectraAcFanSize = 3
+
+ +
+
+ +

◆ kElectraAcHeat

+ +
+
+ + + + +
const uint8_t kElectraAcHeat = 0b100
+
+ +
+
+ +

◆ kElectraAcLightToggleMask

+ +
+
+ + + + +
const uint8_t kElectraAcLightToggleMask = 0x11
+
+ +
+
+ +

◆ kElectraAcLightToggleOff

+ +
+
+ + + + +
const uint8_t kElectraAcLightToggleOff = 0x08
+
+ +
+
+ +

◆ kElectraAcLightToggleOn

+ +
+
+ + + + +
const uint8_t kElectraAcLightToggleOn = 0x15
+
+ +
+
+ +

◆ kElectraAcMaxTemp

+ +
+
+ + + + +
const uint8_t kElectraAcMaxTemp = 32
+
+ +
+
+ +

◆ kElectraAcMinTemp

+ +
+
+ + + + +
const uint8_t kElectraAcMinTemp = 16
+
+ +
+
+ +

◆ kElectraAcModeOffset

+ +
+
+ + + + +
const uint8_t kElectraAcModeOffset = 5
+
+ +
+
+ +

◆ kElectraAcPowerOffset

+ +
+
+ + + + +
const uint8_t kElectraAcPowerOffset = 5
+
+ +
+
+ +

◆ kElectraAcSwingHOffset

+ +
+
+ + + + +
const uint8_t kElectraAcSwingHOffset = 5
+
+ +
+
+ +

◆ kElectraAcSwingOff

+ +
+
+ + + + +
const uint8_t kElectraAcSwingOff = 0b111
+
+ +
+
+ +

◆ kElectraAcSwingOn

+ +
+
+ + + + +
const uint8_t kElectraAcSwingOn = 0b000
+
+ +
+
+ +

◆ kElectraAcSwingSize

+ +
+
+ + + + +
const uint8_t kElectraAcSwingSize = 3
+
+ +
+
+ +

◆ kElectraAcSwingVOffset

+ +
+
+ + + + +
const uint8_t kElectraAcSwingVOffset = 0
+
+ +
+
+ +

◆ kElectraAcTempDelta

+ +
+
+ + + + +
const uint8_t kElectraAcTempDelta = 8
+
+ +
+
+ +

◆ kElectraAcTempOffset

+ +
+
+ + + + +
const uint8_t kElectraAcTempOffset = 3
+
+ +
+
+ +

◆ kElectraAcTempSize

+ +
+
+ + + + +
const uint8_t kElectraAcTempSize = 5
+
+ +
+
+ +

◆ kElectraAcTurboOffset

+ +
+
+ + + + +
const uint8_t kElectraAcTurboOffset = 6
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h_source.html new file mode 100644 index 000000000..a5a25cb15 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h_source.html @@ -0,0 +1,286 @@ + + + + + + + +IRremoteESP8266: src/ir_Electra.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Electra.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
5 
+
6 // Supports:
+
7 // Brand: AUX, Model: KFR-35GW/BpNFW=3 A/C
+
8 // Brand: AUX, Model: YKR-T/011 remote
+
9 // Brand: Electra, Model: Classic INV 17 / AXW12DCS A/C
+
10 // Brand: Electra, Model: YKR-M/003E remote
+
11 
+
12 #ifndef IR_ELECTRA_H_
+
13 #define IR_ELECTRA_H_
+
14 
+
15 #define __STDC_LIMIT_MACROS
+
16 #include <stdint.h>
+
17 #ifndef UNIT_TEST
+
18 #include <Arduino.h>
+
19 #endif
+
20 #include "IRremoteESP8266.h"
+
21 #include "IRsend.h"
+
22 #ifdef UNIT_TEST
+
23 #include "IRsend_test.h"
+
24 #endif
+
25 
+
26 // Constants
+
27 // state[1]
+
28 // Temp 0b11111000
+
29 const uint8_t kElectraAcTempOffset = 3;
+
30 const uint8_t kElectraAcTempSize = 5; // Bits
+
31 const uint8_t kElectraAcMinTemp = 16; // 16C
+
32 const uint8_t kElectraAcMaxTemp = 32; // 32C
+
33 const uint8_t kElectraAcTempDelta = 8;
+
34 const uint8_t kElectraAcSwingSize = 3; // Bits
+
35 const uint8_t kElectraAcSwingOn = 0b000;
+
36 const uint8_t kElectraAcSwingOff = 0b111;
+
37 // SwingVMask = 0b00000111;
+
38 const uint8_t kElectraAcSwingVOffset = 0;
+
39 // state[2]
+
40 // SwingHMask = 0b11100000;
+
41 const uint8_t kElectraAcSwingHOffset = 5;
+
42 // state[4]
+
43 // FanMask = 0b11100000;
+
44 const uint8_t kElectraAcFanOffset = 5;
+
45 const uint8_t kElectraAcFanSize = 3; // Bits
+
46 
+
47 const uint8_t kElectraAcFanAuto = 0b101;
+
48 const uint8_t kElectraAcFanLow = 0b011;
+
49 const uint8_t kElectraAcFanMed = 0b010;
+
50 const uint8_t kElectraAcFanHigh = 0b001;
+
51 // state[5]
+
52 // TurboMask = 0b01000000;
+
53 const uint8_t kElectraAcTurboOffset = 6;
+
54 
+
55 // state[6]
+
56 // Mode 0b11100000
+
57 const uint8_t kElectraAcModeOffset = 5;
+
58 const uint8_t kElectraAcAuto = 0b000;
+
59 const uint8_t kElectraAcCool = 0b001;
+
60 const uint8_t kElectraAcDry = 0b010;
+
61 const uint8_t kElectraAcHeat = 0b100;
+
62 const uint8_t kElectraAcFan = 0b110;
+
63 // state[9]
+
64 //
+
65 const uint8_t kElectraAcCleanOffset = 2; // Bit 0b00000100
+
66 const uint8_t kElectraAcPowerOffset = 5; // Bit 0b00100000
+
67 // state[11]
+
68 //
+
69 const uint8_t kElectraAcLightToggleOn = 0x15;
+
70 // Light has known ON values of 0x15 (0b00010101) or 0x19 (0b00011001)
+
71 // Thus common bits ON are: 0b00010001 (0x11)
+
72 // We will use this for the getLightToggle() test.
+
73 const uint8_t kElectraAcLightToggleMask = 0x11;
+
74 // and known OFF values of 0x08 (0b00001000) & 0x05 (0x00000101)
+
75 const uint8_t kElectraAcLightToggleOff = 0x08;
+
76 
+
77 
+
78 // Classes
+
80 class IRElectraAc {
+
81  public:
+
82  explicit IRElectraAc(const uint16_t pin, const bool inverted = false,
+
83  const bool use_modulation = true);
+
84  void stateReset(void);
+
85 #if SEND_ELECTRA_AC
+
86  void send(const uint16_t repeat = kElectraAcMinRepeat);
+
91  int8_t calibrate(void) { return _irsend.calibrate(); }
+
92 #endif // SEND_ELECTRA_AC
+
93  void begin(void);
+
94  void on(void);
+
95  void off(void);
+
96  void setPower(const bool on);
+
97  bool getPower(void);
+
98  void setMode(const uint8_t mode);
+
99  uint8_t getMode(void);
+
100  void setTemp(const uint8_t temp);
+
101  uint8_t getTemp(void);
+
102  void setFan(const uint8_t speed);
+
103  uint8_t getFan(void);
+
104  void setSwingV(const bool on);
+
105  bool getSwingV(void);
+
106  void setSwingH(const bool on);
+
107  bool getSwingH(void);
+
108  void setClean(const bool on);
+
109  bool getClean(void);
+
110  void setLightToggle(const bool on);
+
111  bool getLightToggle(void);
+
112  void setTurbo(const bool on);
+
113  bool getTurbo(void);
+
114  uint8_t* getRaw(void);
+
115  void setRaw(const uint8_t new_code[],
+
116  const uint16_t length = kElectraAcStateLength);
+
117  static bool validChecksum(const uint8_t state[],
+
118  const uint16_t length = kElectraAcStateLength);
+
119  static uint8_t calcChecksum(const uint8_t state[],
+
120  const uint16_t length = kElectraAcStateLength);
+
121  String toString(void);
+
122  uint8_t convertMode(const stdAc::opmode_t mode);
+
123  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
124  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
125  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
126  stdAc::state_t toCommon(void);
+
127 #ifndef UNIT_TEST
+
128 
+
129  private:
+ +
131 #else
+
132  IRsendTest _irsend;
+
134 #endif
+ +
137  void checksum(const uint16_t length = kElectraAcStateLength);
+
138 };
+
139 #endif // IR_ELECTRA_H_
+
+
bool getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Electra.cpp:263
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Electra.cpp:167
+
void checksum(const uint16_t length=kElectraAcStateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Electra.cpp:96
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Electra.cpp:111
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Electra.cpp:224
+
const uint8_t kElectraAcMinTemp
Definition: ir_Electra.h:31
+
bool getLightToggle(void)
Get the Light (LED) Toggle mode of the A/C.
Definition: ir_Electra.cpp:290
+
bool getTurbo(void)
Get the Turbo mode of the A/C.
Definition: ir_Electra.cpp:315
+
const uint8_t kElectraAcMaxTemp
Definition: ir_Electra.h:32
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kElectraAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Electra.cpp:88
+
const uint8_t kElectraAcFanAuto
Definition: ir_Electra.h:47
+
bool getSwingH(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Electra.cpp:277
+
const uint8_t kElectraAcPowerOffset
Definition: ir_Electra.h:66
+
void on(void)
Change the power setting to On.
Definition: ir_Electra.cpp:124
+
const uint8_t kElectraAcTurboOffset
Definition: ir_Electra.h:53
+
void setClean(const bool on)
Set the Clean mode of the A/C.
Definition: ir_Electra.cpp:297
+ +
const uint16_t kElectraAcMinRepeat
Definition: IRremoteESP8266.h:873
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
IRElectraAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Electra.cpp:57
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Electra.cpp:321
+
const uint8_t kElectraAcHeat
Definition: ir_Electra.h:61
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kElectraAcCool
Definition: ir_Electra.h:59
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Electra.cpp:208
+
Class for handling detailed Electra A/C messages.
Definition: ir_Electra.h:80
+
const uint8_t kElectraAcTempSize
Definition: ir_Electra.h:30
+
const uint8_t kElectraAcAuto
Definition: ir_Electra.h:58
+ +
const uint8_t kElectraAcTempOffset
Definition: ir_Electra.h:29
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Electra.cpp:180
+
const uint8_t kElectraAcDry
Definition: ir_Electra.h:60
+
bool getClean(void)
Get the Clean mode of the A/C.
Definition: ir_Electra.cpp:303
+
void setRaw(const uint8_t new_code[], const uint16_t length=kElectraAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Electra.cpp:119
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Electra.cpp:131
+
const uint8_t kElectraAcTempDelta
Definition: ir_Electra.h:33
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Electra.h:91
+
const uint8_t kElectraAcLightToggleOff
Definition: ir_Electra.h:75
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Electra.cpp:245
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Electra.cpp:137
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Electra.cpp:349
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Electra.cpp:192
+
const uint8_t kElectraAcLightToggleOn
Definition: ir_Electra.h:69
+
void setLightToggle(const bool on)
Set the Light (LED) Toggle mode of the A/C.
Definition: ir_Electra.cpp:284
+
const uint8_t kElectraAcFanLow
Definition: ir_Electra.h:48
+
void setSwingH(const bool on)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Electra.cpp:270
+
const uint8_t kElectraAcFanOffset
Definition: ir_Electra.h:44
+
const uint8_t kElectraAcModeOffset
Definition: ir_Electra.h:57
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kElectraAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Electra.cpp:78
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Electra.cpp:160
+
const uint8_t kElectraAcSwingSize
Definition: ir_Electra.h:34
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Electra.cpp:200
+
const uint8_t kElectraAcSwingHOffset
Definition: ir_Electra.h:41
+
void off(void)
Change the power setting to Off.
Definition: ir_Electra.cpp:127
+
void send(const uint16_t repeat=kElectraAcMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Electra.cpp:104
+
IRsend _irsend
instance of the IR send class
Definition: ir_Electra.h:130
+
const uint8_t kElectraAcSwingOn
Definition: ir_Electra.h:35
+
const uint8_t kElectraAcFanMed
Definition: ir_Electra.h:49
+
const uint8_t kElectraAcFanHigh
Definition: ir_Electra.h:50
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Electra.cpp:231
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Electra.cpp:72
+
void setTurbo(const bool on)
Set the Turbo mode of the A/C.
Definition: ir_Electra.cpp:309
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Electra.cpp:143
+
const uint8_t kElectraAcSwingVOffset
Definition: ir_Electra.h:38
+
const uint8_t kElectraAcFan
Definition: ir_Electra.h:62
+
uint8_t remote_state[kElectraAcStateLength]
The state of the IR remote.
Definition: ir_Electra.h:136
+
const uint8_t kElectraAcLightToggleMask
Definition: ir_Electra.h:73
+
const uint8_t kElectraAcSwingOff
Definition: ir_Electra.h:36
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kElectraAcFanSize
Definition: ir_Electra.h:45
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Electra.cpp:64
+
void setSwingV(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Electra.cpp:256
+
const uint16_t kElectraAcStateLength
Definition: IRremoteESP8266.h:871
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+
const uint8_t kElectraAcCleanOffset
Definition: ir_Electra.h:65
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Epson_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Epson_8cpp.html new file mode 100644 index 000000000..3b1fa2a04 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Epson_8cpp.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: src/ir_Epson.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Epson.cpp File Reference
+
+
+ +

Support for Epson protocols. Epson is an NEC-like protocol, except it doesn't use the NEC style repeat. +More...

+

Detailed Description

+

Support for Epson protocols. Epson is an NEC-like protocol, except it doesn't use the NEC style repeat.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1034
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8cpp.html new file mode 100644 index 000000000..20fa1a48d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8cpp.html @@ -0,0 +1,188 @@ + + + + + + + +IRremoteESP8266: src/ir_Fujitsu.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Fujitsu.cpp File Reference
+
+
+ +

Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham & David Conran. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kFujitsuAcHdrMark = 3324
 
const uint16_t kFujitsuAcHdrSpace = 1574
 
const uint16_t kFujitsuAcBitMark = 448
 
const uint16_t kFujitsuAcOneSpace = 1182
 
const uint16_t kFujitsuAcZeroSpace = 390
 
const uint16_t kFujitsuAcMinGap = 8100
 
+

Detailed Description

+

Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham & David Conran.

+

Variable Documentation

+ +

◆ kFujitsuAcBitMark

+ +
+
+ + + + +
const uint16_t kFujitsuAcBitMark = 448
+
+ +
+
+ +

◆ kFujitsuAcHdrMark

+ +
+
+ + + + +
const uint16_t kFujitsuAcHdrMark = 3324
+
+ +
+
+ +

◆ kFujitsuAcHdrSpace

+ +
+
+ + + + +
const uint16_t kFujitsuAcHdrSpace = 1574
+
+ +
+
+ +

◆ kFujitsuAcMinGap

+ +
+
+ + + + +
const uint16_t kFujitsuAcMinGap = 8100
+
+ +
+
+ +

◆ kFujitsuAcOneSpace

+ +
+
+ + + + +
const uint16_t kFujitsuAcOneSpace = 1182
+
+ +
+
+ +

◆ kFujitsuAcZeroSpace

+ +
+
+ + + + +
const uint16_t kFujitsuAcZeroSpace = 390
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h.html new file mode 100644 index 000000000..ed36c7104 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h.html @@ -0,0 +1,581 @@ + + + + + + + +IRremoteESP8266: src/ir_Fujitsu.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Fujitsu.h File Reference
+
+
+ +

Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRFujitsuAC
 Class for handling detailed Fujitsu A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kFujitsuAcModeAuto = 0x00
 
const uint8_t kFujitsuAcModeCool = 0x01
 
const uint8_t kFujitsuAcModeDry = 0x02
 
const uint8_t kFujitsuAcModeFan = 0x03
 
const uint8_t kFujitsuAcModeHeat = 0x04
 
const uint8_t kFujitsuAcCmdStayOn = 0x00
 
const uint8_t kFujitsuAcCmdTurnOn = 0x01
 
const uint8_t kFujitsuAcCmdTurnOff = 0x02
 
const uint8_t kFujitsuAcCmdEcono = 0x09
 
const uint8_t kFujitsuAcCmdPowerful = 0x39
 
const uint8_t kFujitsuAcCmdStepVert = 0x6C
 
const uint8_t kFujitsuAcCmdToggleSwingVert = 0x6D
 
const uint8_t kFujitsuAcCmdStepHoriz = 0x79
 
const uint8_t kFujitsuAcCmdToggleSwingHoriz = 0x7A
 
const uint8_t kFujitsuAcFanAuto = 0x00
 
const uint8_t kFujitsuAcFanHigh = 0x01
 
const uint8_t kFujitsuAcFanMed = 0x02
 
const uint8_t kFujitsuAcFanLow = 0x03
 
const uint8_t kFujitsuAcFanQuiet = 0x04
 
const uint8_t kFujitsuAcFanSize = 3
 
const uint8_t kFujitsuAcMinTemp = 16
 
const uint8_t kFujitsuAcMaxTemp = 30
 
const uint8_t kFujitsuAcSwingSize = 2
 
const uint8_t kFujitsuAcSwingOff = 0x00
 
const uint8_t kFujitsuAcSwingVert = 0x01
 
const uint8_t kFujitsuAcSwingHoriz = 0x02
 
const uint8_t kFujitsuAcSwingBoth = 0x03
 
const uint8_t kFujitsuAcOutsideQuietOffset = 7
 
const uint8_t kFujitsuAcCleanOffset = 3
 
const uint8_t kFujitsuAcFilterOffset = 3
 
+

Detailed Description

+

Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham.

+

Variable Documentation

+ +

◆ kFujitsuAcCleanOffset

+ +
+
+ + + + +
const uint8_t kFujitsuAcCleanOffset = 3
+
+ +
+
+ +

◆ kFujitsuAcCmdEcono

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdEcono = 0x09
+
+ +
+
+ +

◆ kFujitsuAcCmdPowerful

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdPowerful = 0x39
+
+ +
+
+ +

◆ kFujitsuAcCmdStayOn

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdStayOn = 0x00
+
+ +
+
+ +

◆ kFujitsuAcCmdStepHoriz

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdStepHoriz = 0x79
+
+ +
+
+ +

◆ kFujitsuAcCmdStepVert

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdStepVert = 0x6C
+
+ +
+
+ +

◆ kFujitsuAcCmdToggleSwingHoriz

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdToggleSwingHoriz = 0x7A
+
+ +
+
+ +

◆ kFujitsuAcCmdToggleSwingVert

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdToggleSwingVert = 0x6D
+
+ +
+
+ +

◆ kFujitsuAcCmdTurnOff

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdTurnOff = 0x02
+
+ +
+
+ +

◆ kFujitsuAcCmdTurnOn

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdTurnOn = 0x01
+
+ +
+
+ +

◆ kFujitsuAcFanAuto

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanAuto = 0x00
+
+ +
+
+ +

◆ kFujitsuAcFanHigh

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanHigh = 0x01
+
+ +
+
+ +

◆ kFujitsuAcFanLow

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanLow = 0x03
+
+ +
+
+ +

◆ kFujitsuAcFanMed

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanMed = 0x02
+
+ +
+
+ +

◆ kFujitsuAcFanQuiet

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanQuiet = 0x04
+
+ +
+
+ +

◆ kFujitsuAcFanSize

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanSize = 3
+
+ +
+
+ +

◆ kFujitsuAcFilterOffset

+ +
+
+ + + + +
const uint8_t kFujitsuAcFilterOffset = 3
+
+ +
+
+ +

◆ kFujitsuAcMaxTemp

+ +
+
+ + + + +
const uint8_t kFujitsuAcMaxTemp = 30
+
+ +
+
+ +

◆ kFujitsuAcMinTemp

+ +
+
+ + + + +
const uint8_t kFujitsuAcMinTemp = 16
+
+ +
+
+ +

◆ kFujitsuAcModeAuto

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeAuto = 0x00
+
+ +
+
+ +

◆ kFujitsuAcModeCool

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeCool = 0x01
+
+ +
+
+ +

◆ kFujitsuAcModeDry

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeDry = 0x02
+
+ +
+
+ +

◆ kFujitsuAcModeFan

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeFan = 0x03
+
+ +
+
+ +

◆ kFujitsuAcModeHeat

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeHeat = 0x04
+
+ +
+
+ +

◆ kFujitsuAcOutsideQuietOffset

+ +
+
+ + + + +
const uint8_t kFujitsuAcOutsideQuietOffset = 7
+
+ +
+
+ +

◆ kFujitsuAcSwingBoth

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingBoth = 0x03
+
+ +
+
+ +

◆ kFujitsuAcSwingHoriz

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingHoriz = 0x02
+
+ +
+
+ +

◆ kFujitsuAcSwingOff

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingOff = 0x00
+
+ +
+
+ +

◆ kFujitsuAcSwingSize

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingSize = 2
+
+ +
+
+ +

◆ kFujitsuAcSwingVert

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingVert = 0x01
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h_source.html new file mode 100644 index 000000000..ccc167f12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h_source.html @@ -0,0 +1,350 @@ + + + + + + + +IRremoteESP8266: src/ir_Fujitsu.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Fujitsu.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 Jonny Graham
+
2 // Copyright 2018-2019 David Conran
+
3 
+
7 
+
8 // Supports:
+
9 // Brand: Fujitsu, Model: AR-RAH2E remote
+
10 // Brand: Fujitsu, Model: ASYG30LFCA A/C (ARRAH2E)
+
11 // Brand: Fujitsu, Model: AR-DB1 remote
+
12 // Brand: Fujitsu, Model: AST9RSGCW A/C (ARDB1)
+
13 // Brand: Fujitsu, Model: AR-REB1E remote
+
14 // Brand: Fujitsu, Model: ASYG7LMCA A/C (ARREB1E)
+
15 // Brand: Fujitsu, Model: AR-RAE1E remote
+
16 // Brand: Fujitsu, Model: AGTV14LAC A/C
+
17 // Brand: Fujitsu, Model: AR-RAC1E remote
+
18 // Brand: Fujitsu, Model: ASTB09LBC A/C
+
19 // Brand: Fujitsu, Model: AR-RY4 remote
+
20 // Brand: Fujitsu General, Model: AR-JW2 remote
+
21 // Brand: Fujitsu, Model: AR-DL10 remote
+
22 // Brand: Fujitsu, Model: ASU30C1 A/C
+
23 
+
24 #ifndef IR_FUJITSU_H_
+
25 #define IR_FUJITSU_H_
+
26 
+
27 #define __STDC_LIMIT_MACROS
+
28 #include <stdint.h>
+
29 #ifdef ARDUINO
+
30 #include <Arduino.h>
+
31 #endif
+
32 #include "IRrecv.h"
+
33 #include "IRremoteESP8266.h"
+
34 #include "IRsend.h"
+
35 #ifdef UNIT_TEST
+
36 #include "IRsend_test.h"
+
37 #endif
+
38 
+
39 
+
40 // Constants
+
41 const uint8_t kFujitsuAcModeAuto = 0x00;
+
42 const uint8_t kFujitsuAcModeCool = 0x01;
+
43 const uint8_t kFujitsuAcModeDry = 0x02;
+
44 const uint8_t kFujitsuAcModeFan = 0x03;
+
45 const uint8_t kFujitsuAcModeHeat = 0x04;
+
46 
+
47 const uint8_t kFujitsuAcCmdStayOn = 0x00; // b00000000
+
48 const uint8_t kFujitsuAcCmdTurnOn = 0x01; // b00000001
+
49 const uint8_t kFujitsuAcCmdTurnOff = 0x02; // b00000010
+
50 const uint8_t kFujitsuAcCmdEcono = 0x09; // b00001001
+
51 const uint8_t kFujitsuAcCmdPowerful = 0x39; // b00111001
+
52 const uint8_t kFujitsuAcCmdStepVert = 0x6C; // b01101100
+
53 const uint8_t kFujitsuAcCmdToggleSwingVert = 0x6D; // b01101101
+
54 const uint8_t kFujitsuAcCmdStepHoriz = 0x79; // b01111001
+
55 const uint8_t kFujitsuAcCmdToggleSwingHoriz = 0x7A; // b01111010
+
56 
+
57 const uint8_t kFujitsuAcFanAuto = 0x00;
+
58 const uint8_t kFujitsuAcFanHigh = 0x01;
+
59 const uint8_t kFujitsuAcFanMed = 0x02;
+
60 const uint8_t kFujitsuAcFanLow = 0x03;
+
61 const uint8_t kFujitsuAcFanQuiet = 0x04;
+
62 const uint8_t kFujitsuAcFanSize = 3; // Bits
+
63 
+
64 const uint8_t kFujitsuAcMinTemp = 16; // 16C
+
65 const uint8_t kFujitsuAcMaxTemp = 30; // 30C
+
66 
+
67 const uint8_t kFujitsuAcSwingSize = 2;
+
68 const uint8_t kFujitsuAcSwingOff = 0x00;
+
69 const uint8_t kFujitsuAcSwingVert = 0x01;
+
70 const uint8_t kFujitsuAcSwingHoriz = 0x02;
+
71 const uint8_t kFujitsuAcSwingBoth = 0x03;
+
72 
+
73 const uint8_t kFujitsuAcOutsideQuietOffset = 7;
+
74 const uint8_t kFujitsuAcCleanOffset = 3;
+
75 const uint8_t kFujitsuAcFilterOffset = 3;
+
76 
+
77 // Legacy defines.
+
78 #define FUJITSU_AC_MODE_AUTO kFujitsuAcModeAuto
+
79 #define FUJITSU_AC_MODE_COOL kFujitsuAcModeCool
+
80 #define FUJITSU_AC_MODE_DRY kFujitsuAcModeDry
+
81 #define FUJITSU_AC_MODE_FAN kFujitsuAcModeFan
+
82 #define FUJITSU_AC_MODE_HEAT kFujitsuAcModeHeat
+
83 #define FUJITSU_AC_CMD_STAY_ON kFujitsuAcCmdStayOn
+
84 #define FUJITSU_AC_CMD_TURN_ON kFujitsuAcCmdTurnOn
+
85 #define FUJITSU_AC_CMD_TURN_OFF kFujitsuAcCmdTurnOff
+
86 #define FUJITSU_AC_CMD_STEP_HORIZ kFujitsuAcCmdStepHoriz
+
87 #define FUJITSU_AC_CMD_STEP_VERT kFujitsuAcCmdStepVert
+
88 #define FUJITSU_AC_FAN_AUTO kFujitsuAcFanAuto
+
89 #define FUJITSU_AC_FAN_HIGH kFujitsuAcFanHigh
+
90 #define FUJITSU_AC_FAN_MED kFujitsuAcFanMed
+
91 #define FUJITSU_AC_FAN_LOW kFujitsuAcFanLow
+
92 #define FUJITSU_AC_FAN_QUIET kFujitsuAcFanQuiet
+
93 #define FUJITSU_AC_MIN_TEMP kFujitsuAcMinTemp
+
94 #define FUJITSU_AC_MAX_TEMP kFujitsuAcMaxTemp
+
95 #define FUJITSU_AC_SWING_OFF kFujitsuAcSwingOff
+
96 #define FUJITSU_AC_SWING_VERT kFujitsuAcSwingVert
+
97 #define FUJITSU_AC_SWING_HORIZ kFujitsuAcSwingHoriz
+
98 #define FUJITSU_AC_SWING_BOTH kFujitsuAcSwingBoth
+
99 
+
101 class IRFujitsuAC {
+
102  public:
+
103  explicit IRFujitsuAC(const uint16_t pin,
+
104  const fujitsu_ac_remote_model_t model = ARRAH2E,
+
105  const bool inverted = false,
+
106  const bool use_modulation = true);
+
107  void setModel(const fujitsu_ac_remote_model_t model);
+ +
109  void stateReset(void);
+
110 #if SEND_FUJITSU_AC
+
111  void send(const uint16_t repeat = kFujitsuAcMinRepeat);
+
116  int8_t calibrate(void) { return _irsend.calibrate(); }
+
117 #endif // SEND_FUJITSU_AC
+
118  void begin(void);
+
119  void stepHoriz(void);
+
120  void toggleSwingHoriz(const bool update = true);
+
121  void stepVert(void);
+
122  void toggleSwingVert(const bool update = true);
+
123  void setCmd(const uint8_t cmd);
+
124  uint8_t getCmd(const bool raw = false);
+
125  void setTemp(const uint8_t temp);
+
126  uint8_t getTemp(void);
+
127  void setFanSpeed(const uint8_t fan);
+
128  uint8_t getFanSpeed(void);
+
129  void setMode(const uint8_t mode);
+
130  uint8_t getMode(void);
+
131  void setSwing(const uint8_t mode);
+
132  uint8_t getSwing(const bool raw = false);
+
133  uint8_t* getRaw(void);
+
134  bool setRaw(const uint8_t newState[], const uint16_t length);
+
135  uint8_t getStateLength(void);
+
136  static bool validChecksum(uint8_t* state, const uint16_t length);
+
137  void setPower(const bool on);
+
138  void off(void);
+
139  void on(void);
+
140  bool getPower(void);
+
141  void setClean(const bool on);
+
142  bool getClean(const bool raw = false);
+
143  void setFilter(const bool on);
+
144  bool getFilter(const bool raw = false);
+
145  void setOutsideQuiet(const bool on);
+
146 
+
147  bool getOutsideQuiet(const bool raw = false);
+
148 
+
149  uint8_t convertMode(const stdAc::opmode_t mode);
+
150  uint8_t convertFan(stdAc::fanspeed_t speed);
+
151  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
152  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
153  stdAc::state_t toCommon(void);
+
154  String toString(void);
+
155 #ifndef UNIT_TEST
+
156 
+
157  private:
+ +
159 #else
+
160  IRsendTest _irsend;
+
162 #endif
+ +
165  uint8_t _temp;
+
166  uint8_t _fanSpeed;
+
167  uint8_t _mode;
+
168  uint8_t _swingMode;
+
169  uint8_t _cmd;
+ +
171  uint8_t _state_length;
+ + +
174  bool _clean;
+
175  bool _filter;
+
176  void buildState(void);
+
177  void buildFromState(const uint16_t length);
+
178 };
+
179 
+
180 #endif // IR_FUJITSU_H_
+
+
bool _clean
Definition: ir_Fujitsu.h:174
+
const uint8_t kFujitsuAcCmdTurnOff
Definition: ir_Fujitsu.h:49
+
const uint16_t kFujitsuAcMinRepeat
Definition: IRremoteESP8266.h:874
+
uint8_t _cmd
Definition: ir_Fujitsu.h:169
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kFujitsuAcFilterOffset
Definition: ir_Fujitsu.h:75
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Fujitsu.h:116
+
void setClean(const bool on)
Set the Clean mode of the A/C.
Definition: ir_Fujitsu.cpp:491
+
const uint8_t kFujitsuAcCmdToggleSwingVert
Definition: ir_Fujitsu.h:53
+
uint8_t _fanSpeed
Definition: ir_Fujitsu.h:166
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Fujitsu.cpp:229
+
bool _filter
Definition: ir_Fujitsu.h:175
+ +
void stepVert(void)
Request the A/C to step the Vertical Swing.
Definition: ir_Fujitsu.cpp:323
+
bool _outsideQuiet
Definition: ir_Fujitsu.h:173
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Fujitsu.cpp:418
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Fujitsu.cpp:559
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Fujitsu.cpp:95
+
const uint8_t kFujitsuAcCleanOffset
Definition: ir_Fujitsu.h:74
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kFujitsuAcFanAuto
Definition: ir_Fujitsu.h:57
+
bool setRaw(const uint8_t newState[], const uint16_t length)
Set the internal state from a valid code for this protocol.
Definition: ir_Fujitsu.cpp:298
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kFujitsuAcOutsideQuietOffset
Definition: ir_Fujitsu.h:73
+
const uint8_t kFujitsuAcCmdTurnOn
Definition: ir_Fujitsu.h:48
+
uint8_t _state_length_short
Definition: ir_Fujitsu.h:172
+
const uint8_t kFujitsuAcMinTemp
Definition: ir_Fujitsu.h:64
+
const uint8_t kFujitsuAcFanHigh
Definition: ir_Fujitsu.h:58
+
const uint8_t kFujitsuAcModeHeat
Definition: ir_Fujitsu.h:45
+
void setFilter(const bool on)
Set the Filter mode status of the A/C.
Definition: ir_Fujitsu.cpp:512
+
uint8_t convertFan(stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Fujitsu.cpp:572
+ +
void stepHoriz(void)
Request the A/C to step the Horizontal Swing.
Definition: ir_Fujitsu.cpp:311
+
fujitsu_ac_remote_model_t getModel(void)
Get the currently emulated/detected model of the A/C.
Definition: ir_Fujitsu.cpp:92
+
const uint8_t kFujitsuAcCmdToggleSwingHoriz
Definition: ir_Fujitsu.h:55
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Fujitsu.h:158
+
fujitsu_ac_remote_model_t
Fujitsu A/C model numbers.
Definition: IRsend.h:120
+
void setCmd(const uint8_t cmd)
Set the requested (special) command part for the A/C message.
Definition: ir_Fujitsu.cpp:336
+
void buildFromState(const uint16_t length)
Build the internal state/config from the current (raw) A/C message.
Definition: ir_Fujitsu.cpp:236
+
uint8_t _temp
Definition: ir_Fujitsu.h:165
+
uint8_t _swingMode
Definition: ir_Fujitsu.h:168
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Fujitsu.cpp:107
+
Class for handling detailed Fujitsu A/C messages.
Definition: ir_Fujitsu.h:101
+
const uint8_t kFujitsuAcCmdStepVert
Definition: ir_Fujitsu.h:52
+
void setSwing(const uint8_t mode)
Set the requested swing operation mode of the A/C unit.
Definition: ir_Fujitsu.cpp:460
+
const uint16_t kFujitsuAcStateLength
Definition: IRremoteESP8266.h:875
+
const uint8_t kFujitsuAcCmdPowerful
Definition: ir_Fujitsu.h:51
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Fujitsu.cpp:586
+
const uint8_t kFujitsuAcSwingSize
Definition: ir_Fujitsu.h:67
+
uint8_t _mode
Definition: ir_Fujitsu.h:167
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Fujitsu.cpp:611
+
const uint8_t kFujitsuAcCmdStepHoriz
Definition: ir_Fujitsu.h:54
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Fujitsu.cpp:444
+
const uint8_t kFujitsuAcSwingHoriz
Definition: ir_Fujitsu.h:70
+
const uint8_t kFujitsuAcSwingVert
Definition: ir_Fujitsu.h:69
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Fujitsu.cpp:599
+
void toggleSwingVert(const bool update=true)
Request the A/C to toggle the Vertical Swing mode.
Definition: ir_Fujitsu.cpp:327
+ +
const uint8_t kFujitsuAcModeAuto
Definition: ir_Fujitsu.h:41
+
void setOutsideQuiet(const bool on)
Set the Outside Quiet mode of the A/C.
Definition: ir_Fujitsu.cpp:399
+
const uint8_t kFujitsuAcSwingOff
Definition: ir_Fujitsu.h:68
+
void setModel(const fujitsu_ac_remote_model_t model)
Set the currently emulated model of the A/C.
Definition: ir_Fujitsu.cpp:73
+
const uint8_t kFujitsuAcModeDry
Definition: ir_Fujitsu.h:43
+
@ ARRAH2E
Definition: IRsend.h:121
+
bool getFilter(const bool raw=false)
Get the Filter mode status of the A/C.
Definition: ir_Fujitsu.cpp:520
+
uint8_t getStateLength(void)
Get the length (size) of the state code for the current configuration.
Definition: ir_Fujitsu.cpp:214
+
const uint8_t kFujitsuAcFanSize
Definition: ir_Fujitsu.h:62
+
const uint8_t kFujitsuAcFanMed
Definition: ir_Fujitsu.h:59
+
IRFujitsuAC(const uint16_t pin, const fujitsu_ac_remote_model_t model=ARRAH2E, const bool inverted=false, const bool use_modulation=true)
Class Constructor.
Definition: ir_Fujitsu.cpp:63
+
const uint8_t kFujitsuAcSwingBoth
Definition: ir_Fujitsu.h:71
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Fujitsu.cpp:454
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Fujitsu.cpp:426
+
void buildState(void)
(Re)Build the state from the currently configured settings.
Definition: ir_Fujitsu.cpp:119
+
fujitsu_ac_remote_model_t _model
Definition: ir_Fujitsu.h:170
+
const uint8_t kFujitsuAcMaxTemp
Definition: ir_Fujitsu.h:65
+
const uint8_t kFujitsuAcCmdStayOn
Definition: ir_Fujitsu.h:47
+
bool getOutsideQuiet(const bool raw=false)
Get the Outside Quiet mode status of the A/C.
Definition: ir_Fujitsu.cpp:407
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Fujitsu.cpp:654
+
uint8_t getFanSpeed(void)
Get the current fan speed setting.
Definition: ir_Fujitsu.cpp:440
+
uint8_t getCmd(const bool raw=false)
Set the requested (special) command part for the A/C message.
Definition: ir_Fujitsu.cpp:376
+
void setFanSpeed(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Fujitsu.cpp:430
+
uint8_t getSwing(const bool raw=false)
Get the requested swing operation mode of the A/C unit.
Definition: ir_Fujitsu.cpp:483
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Fujitsu.cpp:388
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Fujitsu.cpp:383
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Fujitsu.cpp:391
+
void send(const uint16_t repeat=kFujitsuAcMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Fujitsu.cpp:112
+
bool getClean(const bool raw=false)
Get the Clean mode status of the A/C.
Definition: ir_Fujitsu.cpp:499
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Fujitsu.cpp:395
+
static bool validChecksum(uint8_t *state, const uint16_t length)
Verify the checksum is valid for a given state.
Definition: ir_Fujitsu.cpp:535
+
uint8_t _state_length
Definition: ir_Fujitsu.h:171
+
void toggleSwingHoriz(const bool update=true)
Request the A/C to toggle the Horizontal Swing mode.
Definition: ir_Fujitsu.cpp:315
+
const uint8_t kFujitsuAcModeFan
Definition: ir_Fujitsu.h:44
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kFujitsuAcCmdEcono
Definition: ir_Fujitsu.h:50
+
uint8_t remote_state[kFujitsuAcStateLength]
The state of the IR remote.
Definition: ir_Fujitsu.h:164
+
const uint8_t kFujitsuAcFanQuiet
Definition: ir_Fujitsu.h:61
+
const uint8_t kFujitsuAcFanLow
Definition: ir_Fujitsu.h:60
+
const uint8_t kFujitsuAcModeCool
Definition: ir_Fujitsu.h:42
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GICable_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GICable_8cpp.html new file mode 100644 index 000000000..635f3333b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GICable_8cpp.html @@ -0,0 +1,233 @@ + + + + + + + +IRremoteESP8266: src/ir_GICable.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_GICable.cpp File Reference
+
+
+ +

G.I. Cable. +More...

+ + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kGicableHdrMark = 9000
 
const uint16_t kGicableHdrSpace = 4400
 
const uint16_t kGicableBitMark = 550
 
const uint16_t kGicableOneSpace = 4400
 
const uint16_t kGicableZeroSpace = 2200
 
const uint16_t kGicableRptSpace = 2200
 
const uint32_t kGicableMinCommandLength = 99600
 
const uint32_t kGicableMinGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kGicableBitMark

+ +
+
+ + + + +
const uint16_t kGicableBitMark = 550
+
+ +
+
+ +

◆ kGicableHdrMark

+ +
+
+ + + + +
const uint16_t kGicableHdrMark = 9000
+
+ +
+
+ +

◆ kGicableHdrSpace

+ +
+
+ + + + +
const uint16_t kGicableHdrSpace = 4400
+
+ +
+
+ +

◆ kGicableMinCommandLength

+ +
+
+ + + + +
const uint32_t kGicableMinCommandLength = 99600
+
+ +
+
+ +

◆ kGicableMinGap

+ +
+
+ + + + +
const uint32_t kGicableMinGap
+
+
+ +

◆ kGicableOneSpace

+ +
+
+ + + + +
const uint16_t kGicableOneSpace = 4400
+
+ +
+
+ +

◆ kGicableRptSpace

+ +
+
+ + + + +
const uint16_t kGicableRptSpace = 2200
+
+ +
+
+ +

◆ kGicableZeroSpace

+ +
+
+ + + + +
const uint16_t kGicableZeroSpace = 2200
+
+ +
+
+
+
const uint16_t kGicableHdrSpace
Definition: ir_GICable.cpp:20
+
const uint16_t kGicableBits
Definition: IRremoteESP8266.h:879
+
const uint16_t kGicableOneSpace
Definition: ir_GICable.cpp:22
+
const uint32_t kGicableMinCommandLength
Definition: ir_GICable.cpp:25
+
const uint16_t kGicableBitMark
Definition: ir_GICable.cpp:21
+
const uint16_t kGicableHdrMark
Definition: ir_GICable.cpp:19
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GlobalCache_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GlobalCache_8cpp.html new file mode 100644 index 000000000..7ff602faf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GlobalCache_8cpp.html @@ -0,0 +1,189 @@ + + + + + + + +IRremoteESP8266: src/ir_GlobalCache.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_GlobalCache.cpp File Reference
+
+
+ +

Global Cache IR format sender Originally added by Hisham Khalifa (http://www.hishamkhalifa.com) +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kGlobalCacheMaxRepeat = 50
 
const uint32_t kGlobalCacheMinUsec = 80
 
const uint8_t kGlobalCacheFreqIndex = 0
 
const uint8_t kGlobalCacheRptIndex = kGlobalCacheFreqIndex + 1
 
const uint8_t kGlobalCacheRptStartIndex = kGlobalCacheRptIndex + 1
 
const uint8_t kGlobalCacheStartIndex = kGlobalCacheRptStartIndex + 1
 
+

Detailed Description

+

Global Cache IR format sender Originally added by Hisham Khalifa (http://www.hishamkhalifa.com)

+
See also
https://irdb.globalcache.com/Home/Database
+

Variable Documentation

+ +

◆ kGlobalCacheFreqIndex

+ +
+
+ + + + +
const uint8_t kGlobalCacheFreqIndex = 0
+
+ +
+
+ +

◆ kGlobalCacheMaxRepeat

+ +
+
+ + + + +
const uint16_t kGlobalCacheMaxRepeat = 50
+
+ +
+
+ +

◆ kGlobalCacheMinUsec

+ +
+
+ + + + +
const uint32_t kGlobalCacheMinUsec = 80
+
+ +
+
+ +

◆ kGlobalCacheRptIndex

+ +
+
+ + + + +
const uint8_t kGlobalCacheRptIndex = kGlobalCacheFreqIndex + 1
+
+ +
+
+ +

◆ kGlobalCacheRptStartIndex

+ +
+
+ + + + +
const uint8_t kGlobalCacheRptStartIndex = kGlobalCacheRptIndex + 1
+
+ +
+
+ +

◆ kGlobalCacheStartIndex

+ +
+
+ + + + +
const uint8_t kGlobalCacheStartIndex = kGlobalCacheRptStartIndex + 1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8cpp.html new file mode 100644 index 000000000..62188cc57 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8cpp.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: src/ir_Goodweather.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Goodweather.cpp File Reference
+
+
+ +

Support for Goodweather compatible HVAC protocols. +More...

+

Detailed Description

+

Support for Goodweather compatible HVAC protocols.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/697
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h.html new file mode 100644 index 000000000..a7910ef35 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h.html @@ -0,0 +1,886 @@ + + + + + + + +IRremoteESP8266: src/ir_Goodweather.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Goodweather.h File Reference
+
+
+ +

Support for Goodweather compatible HVAC protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRGoodweatherAc
 Class for handling detailed Goodweather A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kGoodweatherBitMark = 580
 
const uint16_t kGoodweatherOneSpace = 580
 
const uint16_t kGoodweatherZeroSpace = 1860
 
const uint16_t kGoodweatherHdrMark = 6820
 
const uint16_t kGoodweatherHdrSpace = 6820
 
const uint8_t kGoodweatherExtraTolerance = 12
 
const uint8_t kGoodweatherBitLight = 8
 
const uint8_t kGoodweatherBitTurbo = kGoodweatherBitLight + 3
 
const uint8_t kGoodweatherBitCommand = kGoodweatherBitTurbo + 5
 
const uint8_t kGoodweatherCommandSize = 4
 
const uint8_t kGoodweatherBitSleep = kGoodweatherBitCommand + 8
 
const uint8_t kGoodweatherBitPower = kGoodweatherBitSleep + 1
 
const uint8_t kGoodweatherBitSwing = kGoodweatherBitPower + 1
 
const uint8_t kGoodweatherSwingSize = 2
 
const uint8_t kGoodweatherBitAirFlow = kGoodweatherBitSwing + 2
 
const uint8_t kGoodweatherBitFan = kGoodweatherBitAirFlow + 1
 
const uint8_t kGoodweatherFanSize = 2
 
const uint8_t kGoodweatherBitTemp = kGoodweatherBitFan + 3
 
const uint8_t kGoodweatherTempSize = 4
 
const uint8_t kGoodweatherBitMode = kGoodweatherBitTemp + 5
 
const uint8_t kGoodweatherBitEOF = kGoodweatherBitMode + 3
 
const uint64_t kGoodweatherEOFMask = 0xFFULL << kGoodweatherBitEOF
 
const uint8_t kGoodweatherAuto = 0b000
 
const uint8_t kGoodweatherCool = 0b001
 
const uint8_t kGoodweatherDry = 0b010
 
const uint8_t kGoodweatherFan = 0b011
 
const uint8_t kGoodweatherHeat = 0b100
 
const uint8_t kGoodweatherSwingFast = 0b00
 
const uint8_t kGoodweatherSwingSlow = 0b01
 
const uint8_t kGoodweatherSwingOff = 0b10
 
const uint8_t kGoodweatherFanAuto = 0b00
 
const uint8_t kGoodweatherFanHigh = 0b01
 
const uint8_t kGoodweatherFanMed = 0b10
 
const uint8_t kGoodweatherFanLow = 0b11
 
const uint8_t kGoodweatherTempMin = 16
 
const uint8_t kGoodweatherTempMax = 31
 
const uint8_t kGoodweatherCmdPower = 0x00
 
const uint8_t kGoodweatherCmdMode = 0x01
 
const uint8_t kGoodweatherCmdUpTemp = 0x02
 
const uint8_t kGoodweatherCmdDownTemp = 0x03
 
const uint8_t kGoodweatherCmdSwing = 0x04
 
const uint8_t kGoodweatherCmdFan = 0x05
 
const uint8_t kGoodweatherCmdTimer = 0x06
 
const uint8_t kGoodweatherCmdAirFlow = 0x07
 
const uint8_t kGoodweatherCmdHold = 0x08
 
const uint8_t kGoodweatherCmdSleep = 0x09
 
const uint8_t kGoodweatherCmdTurbo = 0x0A
 
const uint8_t kGoodweatherCmdLight = 0x0B
 
const uint64_t kGoodweatherStateInit = 0xD50000000000
 
+

Detailed Description

+

Support for Goodweather compatible HVAC protocols.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/697
+

Variable Documentation

+ +

◆ kGoodweatherAuto

+ +
+
+ + + + +
const uint8_t kGoodweatherAuto = 0b000
+
+ +
+
+ +

◆ kGoodweatherBitAirFlow

+ +
+
+ + + + +
const uint8_t kGoodweatherBitAirFlow = kGoodweatherBitSwing + 2
+
+ +
+
+ +

◆ kGoodweatherBitCommand

+ +
+
+ + + + +
const uint8_t kGoodweatherBitCommand = kGoodweatherBitTurbo + 5
+
+ +
+
+ +

◆ kGoodweatherBitEOF

+ +
+
+ + + + +
const uint8_t kGoodweatherBitEOF = kGoodweatherBitMode + 3
+
+ +
+
+ +

◆ kGoodweatherBitFan

+ +
+
+ + + + +
const uint8_t kGoodweatherBitFan = kGoodweatherBitAirFlow + 1
+
+ +
+
+ +

◆ kGoodweatherBitLight

+ +
+
+ + + + +
const uint8_t kGoodweatherBitLight = 8
+
+ +
+
+ +

◆ kGoodweatherBitMark

+ +
+
+ + + + +
const uint16_t kGoodweatherBitMark = 580
+
+ +
+
+ +

◆ kGoodweatherBitMode

+ +
+
+ + + + +
const uint8_t kGoodweatherBitMode = kGoodweatherBitTemp + 5
+
+ +
+
+ +

◆ kGoodweatherBitPower

+ +
+
+ + + + +
const uint8_t kGoodweatherBitPower = kGoodweatherBitSleep + 1
+
+ +
+
+ +

◆ kGoodweatherBitSleep

+ +
+
+ + + + +
const uint8_t kGoodweatherBitSleep = kGoodweatherBitCommand + 8
+
+ +
+
+ +

◆ kGoodweatherBitSwing

+ +
+
+ + + + +
const uint8_t kGoodweatherBitSwing = kGoodweatherBitPower + 1
+
+ +
+
+ +

◆ kGoodweatherBitTemp

+ +
+
+ + + + +
const uint8_t kGoodweatherBitTemp = kGoodweatherBitFan + 3
+
+ +
+
+ +

◆ kGoodweatherBitTurbo

+ +
+
+ + + + +
const uint8_t kGoodweatherBitTurbo = kGoodweatherBitLight + 3
+
+ +
+
+ +

◆ kGoodweatherCmdAirFlow

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdAirFlow = 0x07
+
+ +
+
+ +

◆ kGoodweatherCmdDownTemp

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdDownTemp = 0x03
+
+ +
+
+ +

◆ kGoodweatherCmdFan

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdFan = 0x05
+
+ +
+
+ +

◆ kGoodweatherCmdHold

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdHold = 0x08
+
+ +
+
+ +

◆ kGoodweatherCmdLight

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdLight = 0x0B
+
+ +
+
+ +

◆ kGoodweatherCmdMode

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdMode = 0x01
+
+ +
+
+ +

◆ kGoodweatherCmdPower

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdPower = 0x00
+
+ +
+
+ +

◆ kGoodweatherCmdSleep

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdSleep = 0x09
+
+ +
+
+ +

◆ kGoodweatherCmdSwing

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdSwing = 0x04
+
+ +
+
+ +

◆ kGoodweatherCmdTimer

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdTimer = 0x06
+
+ +
+
+ +

◆ kGoodweatherCmdTurbo

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdTurbo = 0x0A
+
+ +
+
+ +

◆ kGoodweatherCmdUpTemp

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdUpTemp = 0x02
+
+ +
+
+ +

◆ kGoodweatherCommandSize

+ +
+
+ + + + +
const uint8_t kGoodweatherCommandSize = 4
+
+ +
+
+ +

◆ kGoodweatherCool

+ +
+
+ + + + +
const uint8_t kGoodweatherCool = 0b001
+
+ +
+
+ +

◆ kGoodweatherDry

+ +
+
+ + + + +
const uint8_t kGoodweatherDry = 0b010
+
+ +
+
+ +

◆ kGoodweatherEOFMask

+ +
+
+ + + + +
const uint64_t kGoodweatherEOFMask = 0xFFULL << kGoodweatherBitEOF
+
+ +
+
+ +

◆ kGoodweatherExtraTolerance

+ +
+
+ + + + +
const uint8_t kGoodweatherExtraTolerance = 12
+
+ +
+
+ +

◆ kGoodweatherFan

+ +
+
+ + + + +
const uint8_t kGoodweatherFan = 0b011
+
+ +
+
+ +

◆ kGoodweatherFanAuto

+ +
+
+ + + + +
const uint8_t kGoodweatherFanAuto = 0b00
+
+ +
+
+ +

◆ kGoodweatherFanHigh

+ +
+
+ + + + +
const uint8_t kGoodweatherFanHigh = 0b01
+
+ +
+
+ +

◆ kGoodweatherFanLow

+ +
+
+ + + + +
const uint8_t kGoodweatherFanLow = 0b11
+
+ +
+
+ +

◆ kGoodweatherFanMed

+ +
+
+ + + + +
const uint8_t kGoodweatherFanMed = 0b10
+
+ +
+
+ +

◆ kGoodweatherFanSize

+ +
+
+ + + + +
const uint8_t kGoodweatherFanSize = 2
+
+ +
+
+ +

◆ kGoodweatherHdrMark

+ +
+
+ + + + +
const uint16_t kGoodweatherHdrMark = 6820
+
+ +
+
+ +

◆ kGoodweatherHdrSpace

+ +
+
+ + + + +
const uint16_t kGoodweatherHdrSpace = 6820
+
+ +
+
+ +

◆ kGoodweatherHeat

+ +
+
+ + + + +
const uint8_t kGoodweatherHeat = 0b100
+
+ +
+
+ +

◆ kGoodweatherOneSpace

+ +
+
+ + + + +
const uint16_t kGoodweatherOneSpace = 580
+
+ +
+
+ +

◆ kGoodweatherStateInit

+ +
+
+ + + + +
const uint64_t kGoodweatherStateInit = 0xD50000000000
+
+ +
+
+ +

◆ kGoodweatherSwingFast

+ +
+
+ + + + +
const uint8_t kGoodweatherSwingFast = 0b00
+
+ +
+
+ +

◆ kGoodweatherSwingOff

+ +
+
+ + + + +
const uint8_t kGoodweatherSwingOff = 0b10
+
+ +
+
+ +

◆ kGoodweatherSwingSize

+ +
+
+ + + + +
const uint8_t kGoodweatherSwingSize = 2
+
+ +
+
+ +

◆ kGoodweatherSwingSlow

+ +
+
+ + + + +
const uint8_t kGoodweatherSwingSlow = 0b01
+
+ +
+
+ +

◆ kGoodweatherTempMax

+ +
+
+ + + + +
const uint8_t kGoodweatherTempMax = 31
+
+ +
+
+ +

◆ kGoodweatherTempMin

+ +
+
+ + + + +
const uint8_t kGoodweatherTempMin = 16
+
+ +
+
+ +

◆ kGoodweatherTempSize

+ +
+
+ + + + +
const uint8_t kGoodweatherTempSize = 4
+
+ +
+
+ +

◆ kGoodweatherZeroSpace

+ +
+
+ + + + +
const uint16_t kGoodweatherZeroSpace = 1860
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h_source.html new file mode 100644 index 000000000..3a72c4a94 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h_source.html @@ -0,0 +1,310 @@ + + + + + + + +IRremoteESP8266: src/ir_Goodweather.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Goodweather.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 ribeirodanielf
+
2 // Copyright 2019 David Conran
+
3 
+
7 
+
8 // Supports:
+
9 // Brand: Goodweather, Model: ZH/JT-03 remote
+
10 
+
11 #ifndef IR_GOODWEATHER_H_
+
12 #define IR_GOODWEATHER_H_
+
13 
+
14 #define __STDC_LIMIT_MACROS
+
15 #include <stdint.h>
+
16 #ifndef UNIT_TEST
+
17 #include <Arduino.h>
+
18 #endif
+
19 #include "IRremoteESP8266.h"
+
20 #include "IRsend.h"
+
21 #ifdef UNIT_TEST
+
22 #include "IRsend_test.h"
+
23 #endif
+
24 
+
25 
+
26 // Constants
+
27 // Timing
+
28 const uint16_t kGoodweatherBitMark = 580;
+
29 const uint16_t kGoodweatherOneSpace = 580;
+
30 const uint16_t kGoodweatherZeroSpace = 1860;
+
31 const uint16_t kGoodweatherHdrMark = 6820;
+
32 const uint16_t kGoodweatherHdrSpace = 6820;
+
33 const uint8_t kGoodweatherExtraTolerance = 12; // +12% extra
+
34 
+
35 // Masks
+
36 const uint8_t kGoodweatherBitLight = 8;
+
37 const uint8_t kGoodweatherBitTurbo = kGoodweatherBitLight + 3; // 11
+
38 const uint8_t kGoodweatherBitCommand = kGoodweatherBitTurbo + 5; // 16
+
39 const uint8_t kGoodweatherCommandSize = 4; // Bits
+
40 const uint8_t kGoodweatherBitSleep = kGoodweatherBitCommand + 8; // 24
+
41 const uint8_t kGoodweatherBitPower = kGoodweatherBitSleep + 1; // 25
+
42 const uint8_t kGoodweatherBitSwing = kGoodweatherBitPower + 1; // 26
+
43 const uint8_t kGoodweatherSwingSize = 2; // Bits
+
44 const uint8_t kGoodweatherBitAirFlow = kGoodweatherBitSwing + 2; // 28
+
45 const uint8_t kGoodweatherBitFan = kGoodweatherBitAirFlow + 1; // 29
+
46 const uint8_t kGoodweatherFanSize = 2; // Bits
+
47 const uint8_t kGoodweatherBitTemp = kGoodweatherBitFan + 3; // 32
+
48 const uint8_t kGoodweatherTempSize = 4; // Bits
+
49 const uint8_t kGoodweatherBitMode = kGoodweatherBitTemp + 5; // 37
+
50 const uint8_t kGoodweatherBitEOF = kGoodweatherBitMode + 3; // 40
+
51 const uint64_t kGoodweatherEOFMask = 0xFFULL << kGoodweatherBitEOF;
+
52 
+
53 // Modes
+
54 const uint8_t kGoodweatherAuto = 0b000;
+
55 const uint8_t kGoodweatherCool = 0b001;
+
56 const uint8_t kGoodweatherDry = 0b010;
+
57 const uint8_t kGoodweatherFan = 0b011;
+
58 const uint8_t kGoodweatherHeat = 0b100;
+
59 // Swing
+
60 const uint8_t kGoodweatherSwingFast = 0b00;
+
61 const uint8_t kGoodweatherSwingSlow = 0b01;
+
62 const uint8_t kGoodweatherSwingOff = 0b10;
+
63 // Fan Control
+
64 const uint8_t kGoodweatherFanAuto = 0b00;
+
65 const uint8_t kGoodweatherFanHigh = 0b01;
+
66 const uint8_t kGoodweatherFanMed = 0b10;
+
67 const uint8_t kGoodweatherFanLow = 0b11;
+
68 // Temperature
+
69 const uint8_t kGoodweatherTempMin = 16; // Celsius
+
70 const uint8_t kGoodweatherTempMax = 31; // Celsius
+
71 // Commands
+
72 const uint8_t kGoodweatherCmdPower = 0x00;
+
73 const uint8_t kGoodweatherCmdMode = 0x01;
+
74 const uint8_t kGoodweatherCmdUpTemp = 0x02;
+
75 const uint8_t kGoodweatherCmdDownTemp = 0x03;
+
76 const uint8_t kGoodweatherCmdSwing = 0x04;
+
77 const uint8_t kGoodweatherCmdFan = 0x05;
+
78 const uint8_t kGoodweatherCmdTimer = 0x06;
+
79 const uint8_t kGoodweatherCmdAirFlow = 0x07;
+
80 const uint8_t kGoodweatherCmdHold = 0x08;
+
81 const uint8_t kGoodweatherCmdSleep = 0x09;
+
82 const uint8_t kGoodweatherCmdTurbo = 0x0A;
+
83 const uint8_t kGoodweatherCmdLight = 0x0B;
+
84 // PAD EOF
+
85 const uint64_t kGoodweatherStateInit = 0xD50000000000;
+
86 
+
87 
+
88 // Classes
+ +
91  public:
+
92  explicit IRGoodweatherAc(const uint16_t pin, const bool inverted = false,
+
93  const bool use_modulation = true);
+
94  void stateReset(void);
+
95 #if SEND_GOODWEATHER
+
96  void send(const uint16_t repeat = kGoodweatherMinRepeat);
+
101  int8_t calibrate(void) { return _irsend.calibrate(); }
+
102 #endif // SEND_GOODWEATHER
+
103  void begin(void);
+
104  void on(void);
+
105  void off(void);
+
106  void setPower(const bool on);
+
107  bool getPower(void);
+
108  void setTemp(const uint8_t temp);
+
109  uint8_t getTemp(void);
+
110  void setFan(const uint8_t speed);
+
111  uint8_t getFan(void);
+
112  void setMode(const uint8_t mode);
+
113  uint8_t getMode();
+
114  void setSwing(const uint8_t speed);
+
115  uint8_t getSwing(void);
+
116  void setSleep(const bool toggle);
+
117  bool getSleep(void);
+
118  void setTurbo(const bool toggle);
+
119  bool getTurbo(void);
+
120  void setLight(const bool toggle);
+
121  bool getLight(void);
+
122  void setCommand(const uint8_t cmd);
+
123  uint8_t getCommand(void);
+
124  uint64_t getRaw(void);
+
125  void setRaw(const uint64_t state);
+
126  uint8_t convertMode(const stdAc::opmode_t mode);
+
127  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
128  uint8_t convertSwingV(const stdAc::swingv_t swingv);
+
129  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
130  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
131  stdAc::state_t toCommon(void);
+
132  String toString();
+
133 #ifndef UNIT_TEST
+
134 
+
135  private:
+ +
137 #else // UNIT_TEST
+
138  IRsendTest _irsend;
+
140 #endif // UNIT_TEST
+
142  uint64_t remote;
+
143 };
+
144 #endif // IR_GOODWEATHER_H_
+
+
const uint8_t kGoodweatherBitTurbo
Definition: ir_Goodweather.h:37
+
const uint8_t kGoodweatherCmdLight
Definition: ir_Goodweather.h:83
+
const uint8_t kGoodweatherCmdDownTemp
Definition: ir_Goodweather.h:75
+
void off(void)
Change the power setting to Off.
Definition: ir_Goodweather.cpp:96
+
void on(void)
Change the power setting to On.
Definition: ir_Goodweather.cpp:93
+
const uint16_t kGoodweatherOneSpace
Definition: ir_Goodweather.h:29
+
const uint8_t kGoodweatherCommandSize
Definition: ir_Goodweather.h:39
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Goodweather.cpp:71
+
const uint8_t kGoodweatherTempMin
Definition: ir_Goodweather.h:69
+
bool getLight(void)
Get the Light (LED) Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:184
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Goodweather.h:136
+
const uint8_t kGoodweatherCmdPower
Definition: ir_Goodweather.h:72
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Goodweather.cpp:317
+
const uint8_t kGoodweatherCmdAirFlow
Definition: ir_Goodweather.h:79
+
bool getTurbo(void)
Get the Turbo Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:210
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kGoodweatherFanSize
Definition: ir_Goodweather.h:46
+
void setTurbo(const bool toggle)
Set the Turbo Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:203
+
bool getSleep(void)
Get the Sleep Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:197
+
void setLight(const bool toggle)
Set the Light (LED) Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:177
+
const uint8_t kGoodweatherBitMode
Definition: ir_Goodweather.h:49
+ +
const uint8_t kGoodweatherCmdSwing
Definition: ir_Goodweather.h:76
+
const uint8_t kGoodweatherFanMed
Definition: ir_Goodweather.h:66
+
uint8_t convertSwingV(const stdAc::swingv_t swingv)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Goodweather.cpp:278
+
const uint8_t kGoodweatherCmdUpTemp
Definition: ir_Goodweather.h:74
+
const uint16_t kGoodweatherHdrSpace
Definition: ir_Goodweather.h:32
+
const uint64_t kGoodweatherEOFMask
Definition: ir_Goodweather.h:51
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Goodweather.h:101
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kGoodweatherFanAuto
Definition: ir_Goodweather.h:64
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
IRGoodweatherAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Goodweather.cpp:66
+
const uint16_t kGoodweatherZeroSpace
Definition: ir_Goodweather.h:30
+
void setRaw(const uint64_t state)
Set the internal state from a valid code for this protocol.
Definition: ir_Goodweather.cpp:90
+
const uint8_t kGoodweatherAuto
Definition: ir_Goodweather.h:54
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void send(const uint16_t repeat=kGoodweatherMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Goodweather.cpp:79
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Goodweather.cpp:293
+
const uint8_t kGoodweatherExtraTolerance
Definition: ir_Goodweather.h:33
+
const uint8_t kGoodweatherSwingSlow
Definition: ir_Goodweather.h:61
+
const uint8_t kGoodweatherTempSize
Definition: ir_Goodweather.h:48
+ +
const uint8_t kGoodweatherSwingOff
Definition: ir_Goodweather.h:62
+
const uint8_t kGoodweatherDry
Definition: ir_Goodweather.h:56
+
const uint8_t kGoodweatherSwingFast
Definition: ir_Goodweather.h:60
+
const uint8_t kGoodweatherBitFan
Definition: ir_Goodweather.h:45
+
const uint8_t kGoodweatherCmdSleep
Definition: ir_Goodweather.h:81
+
const uint8_t kGoodweatherCool
Definition: ir_Goodweather.h:55
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Goodweather.cpp:113
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Goodweather.cpp:74
+
const uint8_t kGoodweatherBitEOF
Definition: ir_Goodweather.h:50
+
const uint8_t kGoodweatherCmdFan
Definition: ir_Goodweather.h:77
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Goodweather.cpp:107
+
const uint8_t kGoodweatherCmdHold
Definition: ir_Goodweather.h:80
+
void setSwing(const uint8_t speed)
Set the Vertical Swing speed of the A/C.
Definition: ir_Goodweather.cpp:216
+
const uint8_t kGoodweatherFan
Definition: ir_Goodweather.h:57
+
const uint8_t kGoodweatherCmdTurbo
Definition: ir_Goodweather.h:82
+
void setCommand(const uint8_t cmd)
Set the remote Command type/button pressed.
Definition: ir_Goodweather.cpp:237
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Goodweather.cpp:147
+
const uint8_t kGoodweatherBitSwing
Definition: ir_Goodweather.h:42
+
const uint64_t kGoodweatherStateInit
Definition: ir_Goodweather.h:85
+
const uint8_t kGoodweatherCmdTimer
Definition: ir_Goodweather.h:78
+
const uint8_t kGoodweatherBitSleep
Definition: ir_Goodweather.h:40
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Goodweather.cpp:153
+
const uint8_t kGoodweatherBitLight
Definition: ir_Goodweather.h:36
+
const uint8_t kGoodweatherTempMax
Definition: ir_Goodweather.h:70
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Goodweather.cpp:306
+
uint8_t getCommand(void)
Get the Command type/button pressed from the current settings.
Definition: ir_Goodweather.cpp:244
+
const uint8_t kGoodweatherFanLow
Definition: ir_Goodweather.h:67
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Goodweather.cpp:124
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Goodweather.cpp:344
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Goodweather.cpp:131
+
const uint8_t kGoodweatherHeat
Definition: ir_Goodweather.h:58
+
const uint16_t kGoodweatherBitMark
Definition: ir_Goodweather.h:28
+
uint64_t remote
The state of the IR remote in IR code form.
Definition: ir_Goodweather.h:142
+
const uint8_t kGoodweatherFanHigh
Definition: ir_Goodweather.h:65
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Goodweather.cpp:264
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Goodweather.cpp:171
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Goodweather.cpp:251
+
const uint16_t kGoodweatherHdrMark
Definition: ir_Goodweather.h:31
+
const uint8_t kGoodweatherSwingSize
Definition: ir_Goodweather.h:43
+
const uint8_t kGoodweatherBitAirFlow
Definition: ir_Goodweather.h:44
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Goodweather.cpp:100
+
void setSleep(const bool toggle)
Set the Sleep Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:190
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
Class for handling detailed Goodweather A/C messages.
Definition: ir_Goodweather.h:90
+
const uint8_t kGoodweatherBitCommand
Definition: ir_Goodweather.h:38
+
const uint8_t kGoodweatherBitPower
Definition: ir_Goodweather.h:41
+
const uint8_t kGoodweatherBitTemp
Definition: ir_Goodweather.h:47
+
uint64_t getRaw(void)
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Goodweather.cpp:86
+
const uint16_t kGoodweatherMinRepeat
Definition: IRremoteESP8266.h:882
+
const uint8_t kGoodweatherCmdMode
Definition: ir_Goodweather.h:73
+
uint8_t getSwing(void)
Get the Vertical Swing speed of the A/C.
Definition: ir_Goodweather.cpp:231
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8cpp.html new file mode 100644 index 000000000..182deded3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8cpp.html @@ -0,0 +1,224 @@ + + + + + + + +IRremoteESP8266: src/ir_Gree.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Gree.cpp File Reference
+
+
+ +

Support for Gree A/C protocols. +More...

+ + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kGreeHdrMark = 9000
 
const uint16_t kGreeHdrSpace = 4500
 See #684 & real example in unit tests. More...
 
const uint16_t kGreeBitMark = 620
 
const uint16_t kGreeOneSpace = 1600
 
const uint16_t kGreeZeroSpace = 540
 
const uint16_t kGreeMsgSpace = 19000
 
const uint8_t kGreeBlockFooter = 0b010
 
const uint8_t kGreeBlockFooterBits = 3
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kGreeBitMark

+ +
+
+ + + + +
const uint16_t kGreeBitMark = 620
+
+ +
+
+ +

◆ kGreeBlockFooter

+ +
+
+ + + + +
const uint8_t kGreeBlockFooter = 0b010
+
+ +
+
+ +

◆ kGreeBlockFooterBits

+ +
+
+ + + + +
const uint8_t kGreeBlockFooterBits = 3
+
+ +
+
+ +

◆ kGreeHdrMark

+ +
+
+ + + + +
const uint16_t kGreeHdrMark = 9000
+
+ +
+
+ +

◆ kGreeHdrSpace

+ +
+
+ + + + +
const uint16_t kGreeHdrSpace = 4500
+
+ +

See #684 & real example in unit tests.

+ +
+
+ +

◆ kGreeMsgSpace

+ +
+
+ + + + +
const uint16_t kGreeMsgSpace = 19000
+
+ +
+
+ +

◆ kGreeOneSpace

+ +
+
+ + + + +
const uint16_t kGreeOneSpace = 1600
+
+ +
+
+ +

◆ kGreeZeroSpace

+ +
+
+ + + + +
const uint16_t kGreeZeroSpace = 540
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h.html new file mode 100644 index 000000000..1e9e1788e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h.html @@ -0,0 +1,934 @@ + + + + + + + +IRremoteESP8266: src/ir_Gree.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Gree.h File Reference
+
+
+ +

Support for Gree A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRGreeAC
 Class for handling detailed Gree A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kGreeAuto = 0
 
const uint8_t kGreeCool = 1
 
const uint8_t kGreeDry = 2
 
const uint8_t kGreeFan = 3
 
const uint8_t kGreeHeat = 4
 
const uint8_t kGreePower1Offset = 3
 
const uint8_t kGreeFanOffset = 4
 
const uint8_t kGreeFanSize = 2
 
const uint8_t kGreeFanAuto = 0
 
const uint8_t kGreeFanMin = 1
 
const uint8_t kGreeFanMed = 2
 
const uint8_t kGreeFanMax = 3
 
const uint8_t kGreeSwingAutoOffset = 6
 
const uint8_t kGreeSleepOffset = 7
 
const uint8_t kGreeTempOffset = 0
 
const uint8_t kGreeTempSize = 4
 
const uint8_t kGreeMinTempC = 16
 
const uint8_t kGreeMaxTempC = 30
 
const uint8_t kGreeMinTempF = 61
 
const uint8_t kGreeMaxTempF = 86
 
const uint8_t kGreeTimerHalfHrOffset = 4
 
const uint8_t kGreeTimerTensHrOffset = 5
 
const uint8_t kGreeTimerTensHrSize = 2
 
const uint16_t kGreeTimerMax = 24 * 60
 
const uint8_t kGreeTimerEnabledOffset = 7
 
const uint8_t kGreeTimerHoursOffset = 0
 
const uint8_t kGreeTimerHoursSize = 4
 
const uint8_t kGreeTurboOffset = 4
 
const uint8_t kGreeLightOffset = 5
 
const uint8_t kGreePower2Offset = 6
 
const uint8_t kGreeXfanOffset = 7
 
const uint8_t kGreeTempExtraDegreeFOffset = 2
 
const uint8_t kGreeUseFahrenheitOffset = 3
 
const uint8_t kGreeSwingSize = 4
 
const uint8_t kGreeSwingLastPos = 0b0000
 
const uint8_t kGreeSwingAuto = 0b0001
 
const uint8_t kGreeSwingUp = 0b0010
 
const uint8_t kGreeSwingMiddleUp = 0b0011
 
const uint8_t kGreeSwingMiddle = 0b0100
 
const uint8_t kGreeSwingMiddleDown = 0b0101
 
const uint8_t kGreeSwingDown = 0b0110
 
const uint8_t kGreeSwingDownAuto = 0b0111
 
const uint8_t kGreeSwingMiddleAuto = 0b1001
 
const uint8_t kGreeSwingUpAuto = 0b1011
 
const uint8_t kGreeWiFiOffset = 6
 
const uint8_t kGreeIFeelOffset = 2
 
const uint8_t kGreeDisplayTempOffset = 0
 
const uint8_t kGreeDisplayTempSize = 2
 
const uint8_t kGreeDisplayTempOff = 0b00
 
const uint8_t kGreeDisplayTempSet = 0b01
 
const uint8_t kGreeDisplayTempInside = 0b10
 
const uint8_t kGreeDisplayTempOutside = 0b11
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kGreeAuto

+ +
+
+ + + + +
const uint8_t kGreeAuto = 0
+
+ +
+
+ +

◆ kGreeCool

+ +
+
+ + + + +
const uint8_t kGreeCool = 1
+
+ +
+
+ +

◆ kGreeDisplayTempInside

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempInside = 0b10
+
+ +
+
+ +

◆ kGreeDisplayTempOff

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempOff = 0b00
+
+ +
+
+ +

◆ kGreeDisplayTempOffset

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempOffset = 0
+
+ +
+
+ +

◆ kGreeDisplayTempOutside

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempOutside = 0b11
+
+ +
+
+ +

◆ kGreeDisplayTempSet

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempSet = 0b01
+
+ +
+
+ +

◆ kGreeDisplayTempSize

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempSize = 2
+
+ +
+
+ +

◆ kGreeDry

+ +
+
+ + + + +
const uint8_t kGreeDry = 2
+
+ +
+
+ +

◆ kGreeFan

+ +
+
+ + + + +
const uint8_t kGreeFan = 3
+
+ +
+
+ +

◆ kGreeFanAuto

+ +
+
+ + + + +
const uint8_t kGreeFanAuto = 0
+
+ +
+
+ +

◆ kGreeFanMax

+ +
+
+ + + + +
const uint8_t kGreeFanMax = 3
+
+ +
+
+ +

◆ kGreeFanMed

+ +
+
+ + + + +
const uint8_t kGreeFanMed = 2
+
+ +
+
+ +

◆ kGreeFanMin

+ +
+
+ + + + +
const uint8_t kGreeFanMin = 1
+
+ +
+
+ +

◆ kGreeFanOffset

+ +
+
+ + + + +
const uint8_t kGreeFanOffset = 4
+
+ +
+
+ +

◆ kGreeFanSize

+ +
+
+ + + + +
const uint8_t kGreeFanSize = 2
+
+ +
+
+ +

◆ kGreeHeat

+ +
+
+ + + + +
const uint8_t kGreeHeat = 4
+
+ +
+
+ +

◆ kGreeIFeelOffset

+ +
+
+ + + + +
const uint8_t kGreeIFeelOffset = 2
+
+ +
+
+ +

◆ kGreeLightOffset

+ +
+
+ + + + +
const uint8_t kGreeLightOffset = 5
+
+ +
+
+ +

◆ kGreeMaxTempC

+ +
+
+ + + + +
const uint8_t kGreeMaxTempC = 30
+
+ +
+
+ +

◆ kGreeMaxTempF

+ +
+
+ + + + +
const uint8_t kGreeMaxTempF = 86
+
+ +
+
+ +

◆ kGreeMinTempC

+ +
+
+ + + + +
const uint8_t kGreeMinTempC = 16
+
+ +
+
+ +

◆ kGreeMinTempF

+ +
+
+ + + + +
const uint8_t kGreeMinTempF = 61
+
+ +
+
+ +

◆ kGreePower1Offset

+ +
+
+ + + + +
const uint8_t kGreePower1Offset = 3
+
+ +
+
+ +

◆ kGreePower2Offset

+ +
+
+ + + + +
const uint8_t kGreePower2Offset = 6
+
+ +
+
+ +

◆ kGreeSleepOffset

+ +
+
+ + + + +
const uint8_t kGreeSleepOffset = 7
+
+ +
+
+ +

◆ kGreeSwingAuto

+ +
+
+ + + + +
const uint8_t kGreeSwingAuto = 0b0001
+
+ +
+
+ +

◆ kGreeSwingAutoOffset

+ +
+
+ + + + +
const uint8_t kGreeSwingAutoOffset = 6
+
+ +
+
+ +

◆ kGreeSwingDown

+ +
+
+ + + + +
const uint8_t kGreeSwingDown = 0b0110
+
+ +
+
+ +

◆ kGreeSwingDownAuto

+ +
+
+ + + + +
const uint8_t kGreeSwingDownAuto = 0b0111
+
+ +
+
+ +

◆ kGreeSwingLastPos

+ +
+
+ + + + +
const uint8_t kGreeSwingLastPos = 0b0000
+
+ +
+
+ +

◆ kGreeSwingMiddle

+ +
+
+ + + + +
const uint8_t kGreeSwingMiddle = 0b0100
+
+ +
+
+ +

◆ kGreeSwingMiddleAuto

+ +
+
+ + + + +
const uint8_t kGreeSwingMiddleAuto = 0b1001
+
+ +
+
+ +

◆ kGreeSwingMiddleDown

+ +
+
+ + + + +
const uint8_t kGreeSwingMiddleDown = 0b0101
+
+ +
+
+ +

◆ kGreeSwingMiddleUp

+ +
+
+ + + + +
const uint8_t kGreeSwingMiddleUp = 0b0011
+
+ +
+
+ +

◆ kGreeSwingSize

+ +
+
+ + + + +
const uint8_t kGreeSwingSize = 4
+
+ +
+
+ +

◆ kGreeSwingUp

+ +
+
+ + + + +
const uint8_t kGreeSwingUp = 0b0010
+
+ +
+
+ +

◆ kGreeSwingUpAuto

+ +
+
+ + + + +
const uint8_t kGreeSwingUpAuto = 0b1011
+
+ +
+
+ +

◆ kGreeTempExtraDegreeFOffset

+ +
+
+ + + + +
const uint8_t kGreeTempExtraDegreeFOffset = 2
+
+ +
+
+ +

◆ kGreeTempOffset

+ +
+
+ + + + +
const uint8_t kGreeTempOffset = 0
+
+ +
+
+ +

◆ kGreeTempSize

+ +
+
+ + + + +
const uint8_t kGreeTempSize = 4
+
+ +
+
+ +

◆ kGreeTimerEnabledOffset

+ +
+
+ + + + +
const uint8_t kGreeTimerEnabledOffset = 7
+
+ +
+
+ +

◆ kGreeTimerHalfHrOffset

+ +
+
+ + + + +
const uint8_t kGreeTimerHalfHrOffset = 4
+
+ +
+
+ +

◆ kGreeTimerHoursOffset

+ +
+
+ + + + +
const uint8_t kGreeTimerHoursOffset = 0
+
+ +
+
+ +

◆ kGreeTimerHoursSize

+ +
+
+ + + + +
const uint8_t kGreeTimerHoursSize = 4
+
+ +
+
+ +

◆ kGreeTimerMax

+ +
+
+ + + + +
const uint16_t kGreeTimerMax = 24 * 60
+
+ +
+
+ +

◆ kGreeTimerTensHrOffset

+ +
+
+ + + + +
const uint8_t kGreeTimerTensHrOffset = 5
+
+ +
+
+ +

◆ kGreeTimerTensHrSize

+ +
+
+ + + + +
const uint8_t kGreeTimerTensHrSize = 2
+
+ +
+
+ +

◆ kGreeTurboOffset

+ +
+
+ + + + +
const uint8_t kGreeTurboOffset = 4
+
+ +
+
+ +

◆ kGreeUseFahrenheitOffset

+ +
+
+ + + + +
const uint8_t kGreeUseFahrenheitOffset = 3
+
+ +
+
+ +

◆ kGreeWiFiOffset

+ +
+
+ + + + +
const uint8_t kGreeWiFiOffset = 6
+
+ +
+
+ +

◆ kGreeXfanOffset

+ +
+
+ + + + +
const uint8_t kGreeXfanOffset = 7
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h_source.html new file mode 100644 index 000000000..4abec57b7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h_source.html @@ -0,0 +1,387 @@ + + + + + + + +IRremoteESP8266: src/ir_Gree.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Gree.h
+
+
+Go to the documentation of this file.
1 // Copyright 2016 David Conran
+
2 
+
6 
+
7 // Supports:
+
8 // Brand: Ultimate, Model: Heat Pump
+
9 // Brand: EKOKAI, Model: A/C
+
10 // Brand: RusClimate, Model: EACS/I-09HAR_X/N3 A/C
+
11 // Brand: RusClimate, Model: YAW1F remote
+
12 // Brand: Green, Model: YBOFB remote
+
13 // Brand: Green, Model: YBOFB2 remote
+
14 // Brand: Gree, Model: YAA1FBF remote
+
15 // Brand: Gree, Model: YB1F2F remote
+
16 
+
17 #ifndef IR_GREE_H_
+
18 #define IR_GREE_H_
+
19 
+
20 #define __STDC_LIMIT_MACROS
+
21 #include <stdint.h>
+
22 #ifndef UNIT_TEST
+
23 #include <Arduino.h>
+
24 #endif
+
25 #include "IRremoteESP8266.h"
+
26 #include "IRsend.h"
+
27 #ifdef UNIT_TEST
+
28 #include "IRsend_test.h"
+
29 #endif
+
30 
+
31 // Constants
+
32 
+
33 const uint8_t kGreeAuto = 0;
+
34 const uint8_t kGreeCool = 1;
+
35 const uint8_t kGreeDry = 2;
+
36 const uint8_t kGreeFan = 3;
+
37 const uint8_t kGreeHeat = 4;
+
38 
+
39 // Byte[0]
+
40 const uint8_t kGreePower1Offset = 3;
+
41 const uint8_t kGreeFanOffset = 4;
+
42 const uint8_t kGreeFanSize = 2; // Bits
+
43 const uint8_t kGreeFanAuto = 0;
+
44 const uint8_t kGreeFanMin = 1;
+
45 const uint8_t kGreeFanMed = 2;
+
46 const uint8_t kGreeFanMax = 3;
+
47 const uint8_t kGreeSwingAutoOffset = 6;
+
48 const uint8_t kGreeSleepOffset = 7;
+
49 // Byte[1]
+
50 const uint8_t kGreeTempOffset = 0;
+
51 const uint8_t kGreeTempSize = 4; // Mask 0b0000xxxx
+
52 const uint8_t kGreeMinTempC = 16; // Celsius
+
53 const uint8_t kGreeMaxTempC = 30; // Celsius
+
54 const uint8_t kGreeMinTempF = 61; // Fahrenheit
+
55 const uint8_t kGreeMaxTempF = 86; // Fahrenheit
+
56 const uint8_t kGreeTimerHalfHrOffset = 4; // Mask 0b000x0000
+
57 const uint8_t kGreeTimerTensHrOffset = 5;
+
58 const uint8_t kGreeTimerTensHrSize = 2; // Mask 0b0xx00000
+
59 const uint16_t kGreeTimerMax = 24 * 60;
+
60 const uint8_t kGreeTimerEnabledOffset = 7; // Mask 0bx0000000
+
61 // Byte[2]
+
62 const uint8_t kGreeTimerHoursOffset = 0;
+
63 const uint8_t kGreeTimerHoursSize = 4; // Bits
+
64 const uint8_t kGreeTurboOffset = 4;
+
65 const uint8_t kGreeLightOffset = 5;
+
66 // This might not be used. See #814
+
67 const uint8_t kGreePower2Offset = 6;
+
68 const uint8_t kGreeXfanOffset = 7;
+
69 // Byte[3]
+
70 const uint8_t kGreeTempExtraDegreeFOffset = 2; // Mask 0b00000x00
+
71 const uint8_t kGreeUseFahrenheitOffset = 3; // Mask 0b0000x000
+
72 // Byte[4]
+
73 const uint8_t kGreeSwingSize = 4; // Bits
+
74 const uint8_t kGreeSwingLastPos = 0b0000;
+
75 const uint8_t kGreeSwingAuto = 0b0001;
+
76 const uint8_t kGreeSwingUp = 0b0010;
+
77 const uint8_t kGreeSwingMiddleUp = 0b0011;
+
78 const uint8_t kGreeSwingMiddle = 0b0100;
+
79 const uint8_t kGreeSwingMiddleDown = 0b0101;
+
80 const uint8_t kGreeSwingDown = 0b0110;
+
81 const uint8_t kGreeSwingDownAuto = 0b0111;
+
82 const uint8_t kGreeSwingMiddleAuto = 0b1001;
+
83 const uint8_t kGreeSwingUpAuto = 0b1011;
+
84 // Byte[5]
+
85 const uint8_t kGreeWiFiOffset = 6; // Mask 0b0x000000
+
86 const uint8_t kGreeIFeelOffset = 2; // Mask 0b00000x00
+
87 const uint8_t kGreeDisplayTempOffset = 0;
+
88 const uint8_t kGreeDisplayTempSize = 2; // Mask 0b000000xx
+
89 const uint8_t kGreeDisplayTempOff = 0b00; // 0
+
90 const uint8_t kGreeDisplayTempSet = 0b01; // 1
+
91 const uint8_t kGreeDisplayTempInside = 0b10; // 2
+
92 const uint8_t kGreeDisplayTempOutside = 0b11; // 3
+
93 
+
94 
+
95 // Legacy defines.
+
96 #define GREE_AUTO kGreeAuto
+
97 #define GREE_COOL kGreeCool
+
98 #define GREE_DRY kGreeDry
+
99 #define GREE_FAN kGreeFan
+
100 #define GREE_HEAT kGreeHeat
+
101 #define GREE_MIN_TEMP kGreeMinTempC
+
102 #define GREE_MAX_TEMP kGreeMaxTempC
+
103 #define GREE_FAN_MAX kGreeFanMax
+
104 #define GREE_SWING_LAST_POS kGreeSwingLastPos
+
105 #define GREE_SWING_AUTO kGreeSwingAuto
+
106 #define GREE_SWING_UP kGreeSwingUp
+
107 #define GREE_SWING_MIDDLE_UP kGreeSwingMiddleUp
+
108 #define GREE_SWING_MIDDLE kGreeSwingMiddle
+
109 #define GREE_SWING_MIDDLE_DOWN kGreeSwingMiddleDown
+
110 #define GREE_SWING_DOWN kGreeSwingDown
+
111 #define GREE_SWING_DOWN_AUTO kGreeSwingDownAuto
+
112 #define GREE_SWING_MIDDLE_AUTO kGreeSwingMiddleAuto
+
113 #define GREE_SWING_UP_AUTO kGreeSwingUpAuto
+
114 
+
115 // Classes
+
117 class IRGreeAC {
+
118  public:
+
119  explicit IRGreeAC(
+
120  const uint16_t pin,
+ +
122  const bool inverted = false, const bool use_modulation = true);
+
123  void stateReset(void);
+
124 #if SEND_GREE
+
125  void send(const uint16_t repeat = kGreeDefaultRepeat);
+
130  int8_t calibrate(void) { return _irsend.calibrate(); }
+
131 #endif // SEND_GREE
+
132  void begin(void);
+
133  void on(void);
+
134  void off(void);
+
135  void setModel(const gree_ac_remote_model_t model);
+ +
137  void setPower(const bool on);
+
138  bool getPower(void);
+
139  void setTemp(const uint8_t temp, const bool fahrenheit = false);
+
140  uint8_t getTemp(void);
+
141  void setUseFahrenheit(const bool on);
+
142  bool getUseFahrenheit(void);
+
143  void setFan(const uint8_t speed);
+
144  uint8_t getFan(void);
+
145  void setMode(const uint8_t new_mode);
+
146  uint8_t getMode(void);
+
147  void setLight(const bool on);
+
148  bool getLight(void);
+
149  void setXFan(const bool on);
+
150  bool getXFan(void);
+
151  void setSleep(const bool on);
+
152  bool getSleep(void);
+
153  void setTurbo(const bool on);
+
154  bool getTurbo(void);
+
155  void setIFeel(const bool on);
+
156  bool getIFeel(void);
+
157  void setWiFi(const bool on);
+
158  bool getWiFi(void);
+
159  void setSwingVertical(const bool automatic, const uint8_t position);
+
160  bool getSwingVerticalAuto(void);
+
161  uint8_t getSwingVerticalPosition(void);
+
162  uint16_t getTimer(void);
+
163  void setTimer(const uint16_t minutes);
+
164  void setDisplayTempSource(const uint8_t mode);
+
165  uint8_t getDisplayTempSource(void);
+
166  uint8_t convertMode(const stdAc::opmode_t mode);
+
167  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
168  uint8_t convertSwingV(const stdAc::swingv_t swingv);
+
169  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
170  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
171  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
172  stdAc::state_t toCommon(void);
+
173  uint8_t* getRaw(void);
+
174  void setRaw(const uint8_t new_code[]);
+
175  static bool validChecksum(const uint8_t state[],
+
176  const uint16_t length = kGreeStateLength);
+
177  String toString(void);
+
178 #ifndef UNIT_TEST
+
179 
+
180  private:
+ +
182 #else // UNIT_TEST
+
183  IRsendTest _irsend;
+
185 #endif // UNIT_TEST
+ + +
189  void checksum(const uint16_t length = kGreeStateLength);
+
190  void fixup(void);
+
191  void setTimerEnabled(const bool on);
+
192  bool getTimerEnabled(void);
+
193 };
+
194 
+
195 #endif // IR_GREE_H_
+
+
void setSwingVertical(const bool automatic, const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Gree.cpp:395
+
const uint8_t kGreeTimerTensHrSize
Definition: ir_Gree.h:58
+
const uint16_t kGreeStateLength
Definition: IRremoteESP8266.h:883
+
uint8_t getTemp(void)
Get the set temperature.
Definition: ir_Gree.cpp:269
+
const uint8_t kGreeIFeelOffset
Definition: ir_Gree.h:86
+
const uint8_t kGreeXfanOffset
Definition: ir_Gree.h:68
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Gree.cpp:220
+
const uint8_t kGreeSwingUp
Definition: ir_Gree.h:76
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kGreeStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Gree.cpp:181
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Gree.cpp:609
+
const uint8_t kGreeFanSize
Definition: ir_Gree.h:42
+
void off(void)
Change the power setting to Off.
Definition: ir_Gree.cpp:205
+
uint16_t getTimer(void)
Get the timer time value from the A/C.
Definition: ir_Gree.cpp:449
+
const uint8_t kGreeFan
Definition: ir_Gree.h:36
+
void setXFan(const bool on)
Set the XFan (Mould) setting of the A/C.
Definition: ir_Gree.cpp:358
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Gree.cpp:542
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Gree.cpp:501
+
const uint8_t kGreeDry
Definition: ir_Gree.h:35
+
const uint8_t kGreeFanMax
Definition: ir_Gree.h:46
+
const uint8_t kGreeSleepOffset
Definition: ir_Gree.h:48
+
const uint8_t kGreeMaxTempF
Definition: ir_Gree.h:55
+
void setMode(const uint8_t new_mode)
Set the operating mode of the A/C.
Definition: ir_Gree.cpp:298
+
gree_ac_remote_model_t getModel(void)
Get/Detect the model of the A/C.
Definition: ir_Gree.cpp:199
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Gree.cpp:580
+
gree_ac_remote_model_t
Gree A/C model numbers.
Definition: IRsend.h:129
+
void send(const uint16_t repeat=kGreeDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Gree.cpp:143
+
const uint8_t kGreeSwingUpAuto
Definition: ir_Gree.h:83
+
const uint8_t kGreeDisplayTempOutside
Definition: ir_Gree.h:92
+
void fixup(void)
Fix up the internal state so it is correct.
Definition: ir_Gree.cpp:132
+
const uint8_t kGreeSwingDownAuto
Definition: ir_Gree.h:81
+
const uint8_t kGreeSwingSize
Definition: ir_Gree.h:73
+ +
void setPower(const bool on)
Change the power setting.
Definition: ir_Gree.cpp:210
+
bool getUseFahrenheit(void)
Get the default temperature units in use.
Definition: ir_Gree.cpp:234
+
const uint8_t kGreeTimerTensHrOffset
Definition: ir_Gree.h:57
+
void setTimerEnabled(const bool on)
Set the timer enable setting of the A/C.
Definition: ir_Gree.cpp:437
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Gree.cpp:151
+
bool getSwingVerticalAuto(void)
Get the Vertical Swing Automatic mode setting of the A/C.
Definition: ir_Gree.cpp:425
+
bool getLight(void)
Get the Light (LED) setting of the A/C.
Definition: ir_Gree.cpp:328
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kGreeSwingAutoOffset
Definition: ir_Gree.h:47
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kGreeDisplayTempSet
Definition: ir_Gree.h:90
+
const uint8_t kGreeTempOffset
Definition: ir_Gree.h:50
+
const uint8_t kGreeSwingMiddleDown
Definition: ir_Gree.h:79
+
IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model=gree_ac_remote_model_t::YAW1F, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Gree.cpp:112
+
const uint8_t kGreeFanMed
Definition: ir_Gree.h:45
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Gree.cpp:376
+ +
const uint8_t kGreeSwingMiddleAuto
Definition: ir_Gree.h:82
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Gree.cpp:514
+
const uint8_t kGreeHeat
Definition: ir_Gree.h:37
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Gree.cpp:370
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Gree.cpp:138
+
const uint16_t kGreeTimerMax
Definition: ir_Gree.h:59
+
@ YAW1F
Definition: IRsend.h:130
+
const uint8_t kGreeMaxTempC
Definition: ir_Gree.h:53
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Gree.h:130
+
uint8_t getSwingVerticalPosition(void)
Get the Vertical Swing position setting of the A/C.
Definition: ir_Gree.cpp:431
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Gree.cpp:292
+
const uint8_t kGreeMinTempF
Definition: ir_Gree.h:54
+
const uint8_t kGreeTurboOffset
Definition: ir_Gree.h:64
+
const uint8_t kGreeDisplayTempOff
Definition: ir_Gree.h:89
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Gree.cpp:283
+
void setUseFahrenheit(const bool on)
Set the default temperature units to use.
Definition: ir_Gree.cpp:228
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Gree.cpp:555
+
const uint8_t kGreeTimerHoursOffset
Definition: ir_Gree.h:62
+
const uint8_t kGreePower1Offset
Definition: ir_Gree.h:40
+
const uint8_t kGreeTimerHalfHrOffset
Definition: ir_Gree.h:56
+
bool getIFeel(void)
Get the IFeel setting of the A/C.
Definition: ir_Gree.cpp:340
+
const uint8_t kGreeTimerHoursSize
Definition: ir_Gree.h:63
+
void checksum(const uint16_t length=kGreeStateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Gree.cpp:171
+
bool getTimerEnabled(void)
Get the timer enabled setting of the A/C.
Definition: ir_Gree.cpp:443
+
const uint8_t kGreeDisplayTempSize
Definition: ir_Gree.h:88
+
void setTimer(const uint16_t minutes)
Set the A/C's timer to turn off in X many minutes.
Definition: ir_Gree.cpp:461
+
void setModel(const gree_ac_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_Gree.cpp:189
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Gree.cpp:388
+
const uint8_t kGreeFanOffset
Definition: ir_Gree.h:41
+
const uint8_t kGreeAuto
Definition: ir_Gree.h:33
+
void setWiFi(const bool on)
Set the Wifi (enabled) setting of the A/C.
Definition: ir_Gree.cpp:346
+
uint8_t convertSwingV(const stdAc::swingv_t swingv)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Gree.cpp:528
+
void setIFeel(const bool on)
Set the IFeel setting of the A/C.
Definition: ir_Gree.cpp:334
+
const uint8_t kGreeSwingMiddleUp
Definition: ir_Gree.h:77
+
uint8_t remote_state[kGreeStateLength]
The state in native IR code form.
Definition: ir_Gree.h:187
+
uint8_t getDisplayTempSource(void)
Get the temperature display mode. i.e. Internal, External temperature sensing.
Definition: ir_Gree.cpp:493
+
const uint8_t kGreeFanMin
Definition: ir_Gree.h:44
+
const uint8_t kGreeCool
Definition: ir_Gree.h:34
+
const uint8_t kGreeSwingMiddle
Definition: ir_Gree.h:78
+
bool getXFan(void)
Get the XFan (Mould) setting of the A/C.
Definition: ir_Gree.cpp:364
+
const uint8_t kGreeSwingLastPos
Definition: ir_Gree.h:74
+
void setTemp(const uint8_t temp, const bool fahrenheit=false)
Set the temp. in degrees.
Definition: ir_Gree.cpp:244
+
gree_ac_remote_model_t _model
Definition: ir_Gree.h:188
+
const uint8_t kGreeWiFiOffset
Definition: ir_Gree.h:85
+
const uint8_t kGreeTimerEnabledOffset
Definition: ir_Gree.h:60
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Gree.cpp:382
+
const uint8_t kGreeSwingDown
Definition: ir_Gree.h:80
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Gree.cpp:567
+
const uint8_t kGreeFanAuto
Definition: ir_Gree.h:43
+
const uint8_t kGreeUseFahrenheitOffset
Definition: ir_Gree.h:71
+
const uint8_t kGreeMinTempC
Definition: ir_Gree.h:52
+
const uint8_t kGreeTempSize
Definition: ir_Gree.h:51
+
void setDisplayTempSource(const uint8_t mode)
Set temperature display mode. i.e. Internal, External temperature sensing.
Definition: ir_Gree.cpp:486
+
const uint8_t kGreeSwingAuto
Definition: ir_Gree.h:75
+
Class for handling detailed Gree A/C messages.
Definition: ir_Gree.h:117
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Gree.cpp:316
+
const uint8_t kGreeTempExtraDegreeFOffset
Definition: ir_Gree.h:70
+
const uint8_t kGreeDisplayTempInside
Definition: ir_Gree.h:91
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Gree.cpp:120
+
const uint8_t kGreePower2Offset
Definition: ir_Gree.h:67
+
const uint8_t kGreeLightOffset
Definition: ir_Gree.h:65
+
bool getWiFi(void)
Get the Wifi (enabled) setting of the A/C.
Definition: ir_Gree.cpp:352
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Gree.cpp:158
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Gree.h:181
+
const uint8_t kGreeDisplayTempOffset
Definition: ir_Gree.h:87
+
void on(void)
Change the power setting to On.
Definition: ir_Gree.cpp:202
+
void setLight(const bool on)
Set the Light (LED) setting of the A/C.
Definition: ir_Gree.cpp:322
+
const uint16_t kGreeDefaultRepeat
Definition: IRremoteESP8266.h:885
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8cpp.html new file mode 100644 index 000000000..dd738e178 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8cpp.html @@ -0,0 +1,199 @@ + + + + + + + +IRremoteESP8266: src/ir_Haier.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Haier.cpp File Reference
+
+
+ +

Support for Haier A/C protocols. The specifics of reverse engineering the protocols details: +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kHaierAcHdr = 3000
 
const uint16_t kHaierAcHdrGap = 4300
 
const uint16_t kHaierAcBitMark = 520
 
const uint16_t kHaierAcOneSpace = 1650
 
const uint16_t kHaierAcZeroSpace = 650
 
const uint32_t kHaierAcMinGap = 150000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kHaierAcBitMark

+ +
+
+ + + + +
const uint16_t kHaierAcBitMark = 520
+
+ +
+
+ +

◆ kHaierAcHdr

+ +
+
+ + + + +
const uint16_t kHaierAcHdr = 3000
+
+ +
+
+ +

◆ kHaierAcHdrGap

+ +
+
+ + + + +
const uint16_t kHaierAcHdrGap = 4300
+
+ +
+
+ +

◆ kHaierAcMinGap

+ +
+
+ + + + +
const uint32_t kHaierAcMinGap = 150000
+
+ +
+
+ +

◆ kHaierAcOneSpace

+ +
+
+ + + + +
const uint16_t kHaierAcOneSpace = 1650
+
+ +
+
+ +

◆ kHaierAcZeroSpace

+ +
+
+ + + + +
const uint16_t kHaierAcZeroSpace = 650
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h.html new file mode 100644 index 000000000..c13ae8eee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h.html @@ -0,0 +1,1363 @@ + + + + + + + +IRremoteESP8266: src/ir_Haier.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Haier.h File Reference
+
+
+ +

Support for Haier A/C protocols. The specifics of reverse engineering the protocols details: +More...

+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

class  IRHaierAC
 Class for handling detailed Haier A/C messages. More...
 
class  IRHaierACYRW02
 Class for handling detailed Haier ACYRW02 A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kHaierAcPrefix = 0b10100101
 
const uint8_t kHaierAcMinTemp = 16
 
const uint8_t kHaierAcDefTemp = 25
 
const uint8_t kHaierAcMaxTemp = 30
 
const uint8_t kHaierAcCmdOff = 0b0000
 
const uint8_t kHaierAcCmdOn = 0b0001
 
const uint8_t kHaierAcCmdMode = 0b0010
 
const uint8_t kHaierAcCmdFan = 0b0011
 
const uint8_t kHaierAcCmdTempUp = 0b0110
 
const uint8_t kHaierAcCmdTempDown = 0b0111
 
const uint8_t kHaierAcCmdSleep = 0b1000
 
const uint8_t kHaierAcCmdTimerSet = 0b1001
 
const uint8_t kHaierAcCmdTimerCancel = 0b1010
 
const uint8_t kHaierAcCmdHealth = 0b1100
 
const uint8_t kHaierAcCmdSwing = 0b1101
 
const uint8_t kHaierAcOffTimerOffset = 6
 
const uint8_t kHaierAcOnTimerOffset = 7
 
const uint8_t kHaierAcHealthBitOffset = 5
 
const uint8_t kHaierAcSwingOffset = 6
 
const uint8_t kHaierAcSwingSize = 2
 
const uint8_t kHaierAcSwingOff = 0b00
 
const uint8_t kHaierAcSwingUp = 0b01
 
const uint8_t kHaierAcSwingDown = 0b10
 
const uint8_t kHaierAcSwingChg = 0b11
 
const uint8_t kHaierAcModeOffset = 5
 
const uint8_t kHaierAcAuto = 0
 
const uint8_t kHaierAcCool = 1
 
const uint8_t kHaierAcDry = 2
 
const uint8_t kHaierAcHeat = 3
 
const uint8_t kHaierAcFan = 4
 
const uint8_t kHaierAcFanAuto = 0
 
const uint8_t kHaierAcFanLow = 1
 
const uint8_t kHaierAcFanMed = 2
 
const uint8_t kHaierAcFanHigh = 3
 
const uint8_t kHaierAcTimeOffset = 0
 
const uint8_t kHaierAcHoursSize = 5
 
const uint8_t kHaierAcMinsSize = 6
 
const uint16_t kHaierAcMaxTime = (23 * 60) + 59
 
const uint8_t kHaierAcSleepBitOffset = 6
 
const uint8_t kHaierAcSleepBit = 0b01000000
 
const uint8_t kHaierAcYrw02Prefix = 0xA6
 
const uint8_t kHaierAcYrw02SwingOff = 0x0
 
const uint8_t kHaierAcYrw02SwingTop = 0x1
 
const uint8_t kHaierAcYrw02SwingMiddle = 0x2
 
const uint8_t kHaierAcYrw02SwingBottom = 0x3
 
const uint8_t kHaierAcYrw02SwingDown = 0xA
 
const uint8_t kHaierAcYrw02SwingAuto = 0xC
 
const uint8_t kHaierAcYrw02HealthOffset = 1
 
const uint8_t kHaierAcYrw02PowerOffset = 6
 
const uint8_t kHaierAcYrw02Power = 0b01000000
 
const uint8_t kHaierAcYrw02FanOffset = 5
 
const uint8_t kHaierAcYrw02FanSize = 3
 
const uint8_t kHaierAcYrw02FanHigh = 0b001
 
const uint8_t kHaierAcYrw02FanMed = 0b010
 
const uint8_t kHaierAcYrw02FanLow = 0b011
 
const uint8_t kHaierAcYrw02FanAuto = 0b101
 
const uint8_t kHaierAcYrw02TurboOffset = 6
 
const uint8_t kHaierAcYrw02TurboSize = 2
 
const uint8_t kHaierAcYrw02TurboOff = 0x0
 
const uint8_t kHaierAcYrw02TurboHigh = 0x1
 
const uint8_t kHaierAcYrw02TurboLow = 0x2
 
const uint8_t kHaierAcYrw02ModeOffset = 5
 
const uint8_t kHaierAcYrw02Auto = 0b000
 
const uint8_t kHaierAcYrw02Cool = 0b001
 
const uint8_t kHaierAcYrw02Dry = 0b010
 
const uint8_t kHaierAcYrw02Heat = 0b100
 
const uint8_t kHaierAcYrw02Fan = 0b110
 
const uint8_t kHaierAcYrw02SleepOffset = 7
 
const uint8_t kHaierAcYrw02Sleep = 0b10000000
 
const uint8_t kHaierAcYrw02ButtonTempUp = 0x0
 
const uint8_t kHaierAcYrw02ButtonTempDown = 0x1
 
const uint8_t kHaierAcYrw02ButtonSwing = 0x2
 
const uint8_t kHaierAcYrw02ButtonFan = 0x4
 
const uint8_t kHaierAcYrw02ButtonPower = 0x5
 
const uint8_t kHaierAcYrw02ButtonMode = 0x6
 
const uint8_t kHaierAcYrw02ButtonHealth = 0x7
 
const uint8_t kHaierAcYrw02ButtonTurbo = 0x8
 
const uint8_t kHaierAcYrw02ButtonSleep = 0xB
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kHaierAcAuto

+ +
+
+ + + + +
const uint8_t kHaierAcAuto = 0
+
+ +
+
+ +

◆ kHaierAcCmdFan

+ +
+
+ + + + +
const uint8_t kHaierAcCmdFan = 0b0011
+
+ +
+
+ +

◆ kHaierAcCmdHealth

+ +
+
+ + + + +
const uint8_t kHaierAcCmdHealth = 0b1100
+
+ +
+
+ +

◆ kHaierAcCmdMode

+ +
+
+ + + + +
const uint8_t kHaierAcCmdMode = 0b0010
+
+ +
+
+ +

◆ kHaierAcCmdOff

+ +
+
+ + + + +
const uint8_t kHaierAcCmdOff = 0b0000
+
+ +
+
+ +

◆ kHaierAcCmdOn

+ +
+
+ + + + +
const uint8_t kHaierAcCmdOn = 0b0001
+
+ +
+
+ +

◆ kHaierAcCmdSleep

+ +
+
+ + + + +
const uint8_t kHaierAcCmdSleep = 0b1000
+
+ +
+
+ +

◆ kHaierAcCmdSwing

+ +
+
+ + + + +
const uint8_t kHaierAcCmdSwing = 0b1101
+
+ +
+
+ +

◆ kHaierAcCmdTempDown

+ +
+
+ + + + +
const uint8_t kHaierAcCmdTempDown = 0b0111
+
+ +
+
+ +

◆ kHaierAcCmdTempUp

+ +
+
+ + + + +
const uint8_t kHaierAcCmdTempUp = 0b0110
+
+ +
+
+ +

◆ kHaierAcCmdTimerCancel

+ +
+
+ + + + +
const uint8_t kHaierAcCmdTimerCancel = 0b1010
+
+ +
+
+ +

◆ kHaierAcCmdTimerSet

+ +
+
+ + + + +
const uint8_t kHaierAcCmdTimerSet = 0b1001
+
+ +
+
+ +

◆ kHaierAcCool

+ +
+
+ + + + +
const uint8_t kHaierAcCool = 1
+
+ +
+
+ +

◆ kHaierAcDefTemp

+ +
+
+ + + + +
const uint8_t kHaierAcDefTemp = 25
+
+ +
+
+ +

◆ kHaierAcDry

+ +
+
+ + + + +
const uint8_t kHaierAcDry = 2
+
+ +
+
+ +

◆ kHaierAcFan

+ +
+
+ + + + +
const uint8_t kHaierAcFan = 4
+
+ +
+
+ +

◆ kHaierAcFanAuto

+ +
+
+ + + + +
const uint8_t kHaierAcFanAuto = 0
+
+ +
+
+ +

◆ kHaierAcFanHigh

+ +
+
+ + + + +
const uint8_t kHaierAcFanHigh = 3
+
+ +
+
+ +

◆ kHaierAcFanLow

+ +
+
+ + + + +
const uint8_t kHaierAcFanLow = 1
+
+ +
+
+ +

◆ kHaierAcFanMed

+ +
+
+ + + + +
const uint8_t kHaierAcFanMed = 2
+
+ +
+
+ +

◆ kHaierAcHealthBitOffset

+ +
+
+ + + + +
const uint8_t kHaierAcHealthBitOffset = 5
+
+ +
+
+ +

◆ kHaierAcHeat

+ +
+
+ + + + +
const uint8_t kHaierAcHeat = 3
+
+ +
+
+ +

◆ kHaierAcHoursSize

+ +
+
+ + + + +
const uint8_t kHaierAcHoursSize = 5
+
+ +
+
+ +

◆ kHaierAcMaxTemp

+ +
+
+ + + + +
const uint8_t kHaierAcMaxTemp = 30
+
+ +
+
+ +

◆ kHaierAcMaxTime

+ +
+
+ + + + +
const uint16_t kHaierAcMaxTime = (23 * 60) + 59
+
+ +
+
+ +

◆ kHaierAcMinsSize

+ +
+
+ + + + +
const uint8_t kHaierAcMinsSize = 6
+
+ +
+
+ +

◆ kHaierAcMinTemp

+ +
+
+ + + + +
const uint8_t kHaierAcMinTemp = 16
+
+ +
+
+ +

◆ kHaierAcModeOffset

+ +
+
+ + + + +
const uint8_t kHaierAcModeOffset = 5
+
+ +
+
+ +

◆ kHaierAcOffTimerOffset

+ +
+
+ + + + +
const uint8_t kHaierAcOffTimerOffset = 6
+
+ +
+
+ +

◆ kHaierAcOnTimerOffset

+ +
+
+ + + + +
const uint8_t kHaierAcOnTimerOffset = 7
+
+ +
+
+ +

◆ kHaierAcPrefix

+ +
+
+ + + + +
const uint8_t kHaierAcPrefix = 0b10100101
+
+ +
+
+ +

◆ kHaierAcSleepBit

+ +
+
+ + + + +
const uint8_t kHaierAcSleepBit = 0b01000000
+
+ +
+
+ +

◆ kHaierAcSleepBitOffset

+ +
+
+ + + + +
const uint8_t kHaierAcSleepBitOffset = 6
+
+ +
+
+ +

◆ kHaierAcSwingChg

+ +
+
+ + + + +
const uint8_t kHaierAcSwingChg = 0b11
+
+ +
+
+ +

◆ kHaierAcSwingDown

+ +
+
+ + + + +
const uint8_t kHaierAcSwingDown = 0b10
+
+ +
+
+ +

◆ kHaierAcSwingOff

+ +
+
+ + + + +
const uint8_t kHaierAcSwingOff = 0b00
+
+ +
+
+ +

◆ kHaierAcSwingOffset

+ +
+
+ + + + +
const uint8_t kHaierAcSwingOffset = 6
+
+ +
+
+ +

◆ kHaierAcSwingSize

+ +
+
+ + + + +
const uint8_t kHaierAcSwingSize = 2
+
+ +
+
+ +

◆ kHaierAcSwingUp

+ +
+
+ + + + +
const uint8_t kHaierAcSwingUp = 0b01
+
+ +
+
+ +

◆ kHaierAcTimeOffset

+ +
+
+ + + + +
const uint8_t kHaierAcTimeOffset = 0
+
+ +
+
+ +

◆ kHaierAcYrw02Auto

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Auto = 0b000
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonFan

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonFan = 0x4
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonHealth

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonHealth = 0x7
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonMode

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonMode = 0x6
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonPower

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonPower = 0x5
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonSleep

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonSleep = 0xB
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonSwing

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonSwing = 0x2
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonTempDown

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonTempDown = 0x1
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonTempUp

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonTempUp = 0x0
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonTurbo

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonTurbo = 0x8
+
+ +
+
+ +

◆ kHaierAcYrw02Cool

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Cool = 0b001
+
+ +
+
+ +

◆ kHaierAcYrw02Dry

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Dry = 0b010
+
+ +
+
+ +

◆ kHaierAcYrw02Fan

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Fan = 0b110
+
+ +
+
+ +

◆ kHaierAcYrw02FanAuto

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanAuto = 0b101
+
+ +
+
+ +

◆ kHaierAcYrw02FanHigh

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanHigh = 0b001
+
+ +
+
+ +

◆ kHaierAcYrw02FanLow

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanLow = 0b011
+
+ +
+
+ +

◆ kHaierAcYrw02FanMed

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanMed = 0b010
+
+ +
+
+ +

◆ kHaierAcYrw02FanOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanOffset = 5
+
+ +
+
+ +

◆ kHaierAcYrw02FanSize

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanSize = 3
+
+ +
+
+ +

◆ kHaierAcYrw02HealthOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02HealthOffset = 1
+
+ +
+
+ +

◆ kHaierAcYrw02Heat

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Heat = 0b100
+
+ +
+
+ +

◆ kHaierAcYrw02ModeOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ModeOffset = 5
+
+ +
+
+ +

◆ kHaierAcYrw02Power

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Power = 0b01000000
+
+ +
+
+ +

◆ kHaierAcYrw02PowerOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02PowerOffset = 6
+
+ +
+
+ +

◆ kHaierAcYrw02Prefix

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Prefix = 0xA6
+
+ +
+
+ +

◆ kHaierAcYrw02Sleep

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Sleep = 0b10000000
+
+ +
+
+ +

◆ kHaierAcYrw02SleepOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SleepOffset = 7
+
+ +
+
+ +

◆ kHaierAcYrw02SwingAuto

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingAuto = 0xC
+
+ +
+
+ +

◆ kHaierAcYrw02SwingBottom

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingBottom = 0x3
+
+ +
+
+ +

◆ kHaierAcYrw02SwingDown

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingDown = 0xA
+
+ +
+
+ +

◆ kHaierAcYrw02SwingMiddle

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingMiddle = 0x2
+
+ +
+
+ +

◆ kHaierAcYrw02SwingOff

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingOff = 0x0
+
+ +
+
+ +

◆ kHaierAcYrw02SwingTop

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingTop = 0x1
+
+ +
+
+ +

◆ kHaierAcYrw02TurboHigh

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboHigh = 0x1
+
+ +
+
+ +

◆ kHaierAcYrw02TurboLow

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboLow = 0x2
+
+ +
+
+ +

◆ kHaierAcYrw02TurboOff

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboOff = 0x0
+
+ +
+
+ +

◆ kHaierAcYrw02TurboOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboOffset = 6
+
+ +
+
+ +

◆ kHaierAcYrw02TurboSize

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboSize = 2
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h_source.html new file mode 100644 index 000000000..2869def4a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h_source.html @@ -0,0 +1,587 @@ + + + + + + + +IRremoteESP8266: src/ir_Haier.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Haier.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 crankyoldgit
+
11 
+
12 // Supports:
+
13 // Brand: Haier, Model: HSU07-HEA03 remote (HAIER_AC)
+
14 // Brand: Haier, Model: YR-W02 remote (HAIER_AC_YRW02)
+
15 // Brand: Haier, Model: HSU-09HMC203 A/C (HAIER_AC_YRW02)
+
16 
+
17 #ifndef IR_HAIER_H_
+
18 #define IR_HAIER_H_
+
19 
+
20 #ifndef UNIT_TEST
+
21 #include <Arduino.h>
+
22 #endif
+
23 #include "IRremoteESP8266.h"
+
24 #include "IRsend.h"
+
25 #ifdef UNIT_TEST
+
26 #include "IRsend_test.h"
+
27 #endif
+
28 
+
29 // Constants
+
30 
+
31 // Haier HSU07-HEA03 remote
+
32 // Byte 0
+
33 const uint8_t kHaierAcPrefix = 0b10100101;
+
34 
+
35 // Byte 1
+
36 const uint8_t kHaierAcMinTemp = 16;
+
37 const uint8_t kHaierAcDefTemp = 25;
+
38 const uint8_t kHaierAcMaxTemp = 30;
+
39 const uint8_t kHaierAcCmdOff = 0b0000;
+
40 const uint8_t kHaierAcCmdOn = 0b0001;
+
41 const uint8_t kHaierAcCmdMode = 0b0010;
+
42 const uint8_t kHaierAcCmdFan = 0b0011;
+
43 const uint8_t kHaierAcCmdTempUp = 0b0110;
+
44 const uint8_t kHaierAcCmdTempDown = 0b0111;
+
45 const uint8_t kHaierAcCmdSleep = 0b1000;
+
46 const uint8_t kHaierAcCmdTimerSet = 0b1001;
+
47 const uint8_t kHaierAcCmdTimerCancel = 0b1010;
+
48 const uint8_t kHaierAcCmdHealth = 0b1100;
+
49 const uint8_t kHaierAcCmdSwing = 0b1101;
+
50 
+
51 // Byte 2 (Clock Hours)
+
52 
+
53 // Byte 3 (Timer Flags & Clock Minutes)
+
54 const uint8_t kHaierAcOffTimerOffset = 6;
+
55 const uint8_t kHaierAcOnTimerOffset = 7;
+
56 
+
57 // Byte 4 (Health & Off Time Hours)
+
58 const uint8_t kHaierAcHealthBitOffset = 5;
+
59 
+
60 // Byte 5 (Swing & Off Time Mins)
+
61 const uint8_t kHaierAcSwingOffset = 6;
+
62 const uint8_t kHaierAcSwingSize = 2; // Bits
+
63 const uint8_t kHaierAcSwingOff = 0b00;
+
64 const uint8_t kHaierAcSwingUp = 0b01;
+
65 const uint8_t kHaierAcSwingDown = 0b10;
+
66 const uint8_t kHaierAcSwingChg = 0b11;
+
67 
+
68 // Byte 6 (Mode & On Time Hours)
+
69 const uint8_t kHaierAcModeOffset = 5;
+
70 const uint8_t kHaierAcAuto = 0;
+
71 const uint8_t kHaierAcCool = 1;
+
72 const uint8_t kHaierAcDry = 2;
+
73 const uint8_t kHaierAcHeat = 3;
+
74 const uint8_t kHaierAcFan = 4;
+
75 
+
76 const uint8_t kHaierAcFanAuto = 0;
+
77 const uint8_t kHaierAcFanLow = 1;
+
78 const uint8_t kHaierAcFanMed = 2;
+
79 const uint8_t kHaierAcFanHigh = 3;
+
80 
+
81 // Byte 7 (On Time Minutes)
+
82 
+
83 // Time
+
84 const uint8_t kHaierAcTimeOffset = 0; // Bits
+
85 const uint8_t kHaierAcHoursSize = 5; // Bits
+
86 const uint8_t kHaierAcMinsSize = 6; // Bits
+
87 
+
88 const uint16_t kHaierAcMaxTime = (23 * 60) + 59;
+
89 
+
90 // Byte 7
+
91 const uint8_t kHaierAcSleepBitOffset = 6;
+
92 const uint8_t kHaierAcSleepBit = 0b01000000;
+
93 
+
94 // Legacy Haier AC defines.
+
95 #define HAIER_AC_MIN_TEMP kHaierAcMinTemp
+
96 #define HAIER_AC_DEF_TEMP kHaierAcDefTemp
+
97 #define HAIER_AC_MAX_TEMP kHaierAcMaxTemp
+
98 #define HAIER_AC_CMD_OFF kHaierAcCmdOff
+
99 #define HAIER_AC_CMD_ON kHaierAcCmdOn
+
100 #define HAIER_AC_CMD_MODE kHaierAcCmdMode
+
101 #define HAIER_AC_CMD_FAN kHaierAcCmdFan
+
102 #define HAIER_AC_CMD_TEMP_UP kHaierAcCmdTempUp
+
103 #define HAIER_AC_CMD_TEMP_DOWN kHaierAcCmdTempDown
+
104 #define HAIER_AC_CMD_SLEEP kHaierAcCmdSleep
+
105 #define HAIER_AC_CMD_TIMER_SET kHaierAcCmdTimerSet
+
106 #define HAIER_AC_CMD_TIMER_CANCEL kHaierAcCmdTimerCancel
+
107 #define HAIER_AC_CMD_HEALTH kHaierAcCmdHealth
+
108 #define HAIER_AC_CMD_SWING kHaierAcCmdSwing
+
109 #define HAIER_AC_SWING_OFF kHaierAcSwingOff
+
110 #define HAIER_AC_SWING_UP kHaierAcSwingUp
+
111 #define HAIER_AC_SWING_DOWN kHaierAcSwingDown
+
112 #define HAIER_AC_SWING_CHG kHaierAcSwingChg
+
113 #define HAIER_AC_AUTO kHaierAcAuto
+
114 #define HAIER_AC_COOL kHaierAcCool
+
115 #define HAIER_AC_DRY kHaierAcDry
+
116 #define HAIER_AC_HEAT kHaierAcHeat
+
117 #define HAIER_AC_FAN kHaierAcFan
+
118 #define HAIER_AC_FAN_AUTO kHaierAcFanAuto
+
119 #define HAIER_AC_FAN_LOW kHaierAcFanLow
+
120 #define HAIER_AC_FAN_MED kHaierAcFanMed
+
121 #define HAIER_AC_FAN_HIGH kHaierAcFanHigh
+
122 
+
123 // Haier YRW02 remote
+
124 // Byte 0
+
125 const uint8_t kHaierAcYrw02Prefix = 0xA6;
+
126 
+
127 // Byte 1
+
128 // High Nibble - Temperature
+
129 // 0x0 = 16DegC, ... 0xE = 30DegC
+
130 // Low Nibble - Swing
+
131 const uint8_t kHaierAcYrw02SwingOff = 0x0;
+
132 const uint8_t kHaierAcYrw02SwingTop = 0x1;
+
133 const uint8_t kHaierAcYrw02SwingMiddle = 0x2; // Not available in heat mode.
+
134 const uint8_t kHaierAcYrw02SwingBottom = 0x3; // Only available in heat mode.
+
135 const uint8_t kHaierAcYrw02SwingDown = 0xA;
+
136 const uint8_t kHaierAcYrw02SwingAuto = 0xC; // Airflow
+
137 
+
138 // Byte 3
+
139 const uint8_t kHaierAcYrw02HealthOffset = 1;
+
140 
+
141 // Byte 4
+
142 const uint8_t kHaierAcYrw02PowerOffset = 6;
+
143 const uint8_t kHaierAcYrw02Power = 0b01000000;
+
144 
+
145 // Byte 5
+
146 // Bits 0-3
+
147 const uint8_t kHaierAcYrw02FanOffset = 5;
+
148 const uint8_t kHaierAcYrw02FanSize = 3;
+
149 const uint8_t kHaierAcYrw02FanHigh = 0b001;
+
150 const uint8_t kHaierAcYrw02FanMed = 0b010;
+
151 const uint8_t kHaierAcYrw02FanLow = 0b011;
+
152 const uint8_t kHaierAcYrw02FanAuto = 0b101;
+
153 
+
154 // Byte 6
+
155 const uint8_t kHaierAcYrw02TurboOffset = 6;
+
156 const uint8_t kHaierAcYrw02TurboSize = 2;
+
157 const uint8_t kHaierAcYrw02TurboOff = 0x0;
+
158 const uint8_t kHaierAcYrw02TurboHigh = 0x1;
+
159 const uint8_t kHaierAcYrw02TurboLow = 0x2;
+
160 
+
161 // Byte 7
+
162 // Mode mask 0b11100000
+
163 const uint8_t kHaierAcYrw02ModeOffset = 5;
+
164 const uint8_t kHaierAcYrw02Auto = 0b000; // 0
+
165 const uint8_t kHaierAcYrw02Cool = 0b001; // 1
+
166 const uint8_t kHaierAcYrw02Dry = 0b010; // 2
+
167 const uint8_t kHaierAcYrw02Heat = 0b100; // 4
+
168 const uint8_t kHaierAcYrw02Fan = 0b110; // 5
+
169 
+
170 // Byte 8
+
171 const uint8_t kHaierAcYrw02SleepOffset = 7;
+
172 const uint8_t kHaierAcYrw02Sleep = 0b10000000;
+
173 
+
174 // Byte 12
+
175 // Bits 4-7
+
176 const uint8_t kHaierAcYrw02ButtonTempUp = 0x0;
+
177 const uint8_t kHaierAcYrw02ButtonTempDown = 0x1;
+
178 const uint8_t kHaierAcYrw02ButtonSwing = 0x2;
+
179 const uint8_t kHaierAcYrw02ButtonFan = 0x4;
+
180 const uint8_t kHaierAcYrw02ButtonPower = 0x5;
+
181 const uint8_t kHaierAcYrw02ButtonMode = 0x6;
+
182 const uint8_t kHaierAcYrw02ButtonHealth = 0x7;
+
183 const uint8_t kHaierAcYrw02ButtonTurbo = 0x8;
+
184 const uint8_t kHaierAcYrw02ButtonSleep = 0xB;
+
185 
+
186 // Legacy Haier YRW02 remote defines.
+
187 #define HAIER_AC_YRW02_SWING_OFF kHaierAcYrw02SwingOff
+
188 #define HAIER_AC_YRW02_SWING_TOP kHaierAcYrw02SwingTop
+
189 #define HAIER_AC_YRW02_SWING_MIDDLE kHaierAcYrw02SwingMiddle
+
190 #define HAIER_AC_YRW02_SWING_BOTTOM kHaierAcYrw02SwingBottom
+
191 #define HAIER_AC_YRW02_SWING_DOWN kHaierAcYrw02SwingDown
+
192 #define HAIER_AC_YRW02_SWING_AUTO kHaierAcYrw02SwingAuto
+
193 #define HAIER_AC_YRW02_FAN_HIGH kHaierAcYrw02FanHigh
+
194 #define HAIER_AC_YRW02_FAN_MED kHaierAcYrw02FanMed
+
195 #define HAIER_AC_YRW02_FAN_LOW kHaierAcYrw02FanLow
+
196 #define HAIER_AC_YRW02_FAN_AUTO kHaierAcYrw02FanAuto
+
197 #define HAIER_AC_YRW02_TURBO_OFF kHaierAcYrw02TurboOff
+
198 #define HAIER_AC_YRW02_TURBO_HIGH kHaierAcYrw02TurboHigh
+
199 #define HAIER_AC_YRW02_TURBO_LOW kHaierAcYrw02TurboLow
+
200 #define HAIER_AC_YRW02_AUTO kHaierAcYrw02Auto
+
201 #define HAIER_AC_YRW02_COOL kHaierAcYrw02Cool
+
202 #define HAIER_AC_YRW02_DRY kHaierAcYrw02Dry
+
203 #define HAIER_AC_YRW02_HEAT kHaierAcYrw02Heat
+
204 #define HAIER_AC_YRW02_FAN kHaierAcYrw02Fan
+
205 #define HAIER_AC_YRW02_BUTTON_TEMP_UP kHaierAcYrw02ButtonTempUp
+
206 #define HAIER_AC_YRW02_BUTTON_TEMP_DOWN kHaierAcYrw02ButtonTempDown
+
207 #define HAIER_AC_YRW02_BUTTON_SWING kHaierAcYrw02ButtonSwing
+
208 #define HAIER_AC_YRW02_BUTTON_FAN kHaierAcYrw02ButtonFan
+
209 #define HAIER_AC_YRW02_BUTTON_POWER kHaierAcYrw02ButtonPower
+
210 #define HAIER_AC_YRW02_BUTTON_MODE kHaierAcYrw02ButtonMode
+
211 #define HAIER_AC_YRW02_BUTTON_HEALTH kHaierAcYrw02ButtonHealth
+
212 #define HAIER_AC_YRW02_BUTTON_TURBO kHaierAcYrw02ButtonTurbo
+
213 #define HAIER_AC_YRW02_BUTTON_SLEEP kHaierAcYrw02ButtonSleep
+
214 
+
215 // Classes
+
217 class IRHaierAC {
+
218  public:
+
219  explicit IRHaierAC(const uint16_t pin, const bool inverted = false,
+
220  const bool use_modulation = true);
+
221 #if SEND_HAIER_AC
+
222  void send(const uint16_t repeat = kHaierAcDefaultRepeat);
+
227  int8_t calibrate(void) { return _irsend.calibrate(); }
+
228 #endif // SEND_HAIER_AC
+
229  void begin(void);
+
230 
+
231  void setCommand(const uint8_t command);
+
232  uint8_t getCommand(void);
+
233 
+
234  void setTemp(const uint8_t temp);
+
235  uint8_t getTemp(void);
+
236 
+
237  void setFan(const uint8_t speed);
+
238  uint8_t getFan(void);
+
239 
+
240  uint8_t getMode(void);
+
241  void setMode(const uint8_t mode);
+
242 
+
243  bool getSleep(void);
+
244  void setSleep(const bool on);
+
245  bool getHealth(void);
+
246  void setHealth(const bool on);
+
247 
+
248  int16_t getOnTimer(void);
+
249  void setOnTimer(const uint16_t mins);
+
250  int16_t getOffTimer(void);
+
251  void setOffTimer(const uint16_t mins);
+
252  void cancelTimers(void);
+
253 
+
254  uint16_t getCurrTime(void);
+
255  void setCurrTime(const uint16_t mins);
+
256 
+
257  uint8_t getSwing(void);
+
258  void setSwing(const uint8_t state);
+
259 
+
260  uint8_t* getRaw(void);
+
261  void setRaw(const uint8_t new_code[]);
+
262  static bool validChecksum(uint8_t state[],
+
263  const uint16_t length = kHaierACStateLength);
+
264  uint8_t convertMode(const stdAc::opmode_t mode);
+
265  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
266  uint8_t convertSwingV(const stdAc::swingv_t position);
+
267  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
268  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
269  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
270  stdAc::state_t toCommon(void);
+
271  String toString(void);
+
272 #ifndef UNIT_TEST
+
273 
+
274  private:
+ +
276 #else // UNIT_TEST
+
277  IRsendTest _irsend;
+
279 #endif
+ +
282  void stateReset(void);
+
283  void checksum(void);
+
284  static uint16_t getTime(const uint8_t ptr[]);
+
285  static void setTime(uint8_t ptr[], const uint16_t nr_mins);
+
286 };
+
287 
+ +
290  public:
+
291  explicit IRHaierACYRW02(const uint16_t pin, const bool inverted = false,
+
292  const bool use_modulation = true);
+
293 #if SEND_HAIER_AC_YRW02
+
294  void send(const uint16_t repeat = kHaierAcYrw02DefaultRepeat);
+
299  int8_t calibrate(void) { return _irsend.calibrate(); }
+
300 #endif // SEND_HAIER_AC_YRW02
+
301  void begin(void);
+
302 
+
303  void setButton(const uint8_t button);
+
304  uint8_t getButton(void);
+
305 
+
306  void setTemp(const uint8_t temp);
+
307  uint8_t getTemp(void);
+
308 
+
309  void setFan(const uint8_t speed);
+
310  uint8_t getFan(void);
+
311 
+
312  uint8_t getMode(void);
+
313  void setMode(const uint8_t mode);
+
314 
+
315  bool getPower(void);
+
316  void setPower(const bool on);
+
317  void on(void);
+
318  void off(void);
+
319 
+
320  bool getSleep(void);
+
321  void setSleep(const bool on);
+
322  bool getHealth(void);
+
323  void setHealth(const bool on);
+
324 
+
325  uint8_t getTurbo(void);
+
326  void setTurbo(const uint8_t speed);
+
327 
+
328  uint8_t getSwing(void);
+
329  void setSwing(const uint8_t pos);
+
330 
+
331  uint8_t* getRaw(void);
+
332  void setRaw(const uint8_t new_code[]);
+
333  static bool validChecksum(uint8_t state[],
+
334  const uint16_t length = kHaierACYRW02StateLength);
+
335  uint8_t convertMode(const stdAc::opmode_t mode);
+
336  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
337  uint8_t convertSwingV(const stdAc::swingv_t position);
+
338  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
339  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
340  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
341  stdAc::state_t toCommon(void);
+
342  String toString(void);
+
343 #ifndef UNIT_TEST
+
344 
+
345  private:
+ +
347 #else // UNIT_TEST
+
348  IRsendTest _irsend;
+
350 #endif // UNIT_TEST
+ +
353  void stateReset(void);
+
354  void checksum(void);
+
355 };
+
356 #endif // IR_HAIER_H_
+
+
const uint8_t kHaierAcCmdFan
Definition: ir_Haier.h:42
+
const uint8_t kHaierAcFanHigh
Definition: ir_Haier.h:79
+
bool getHealth(void)
Get the Health (filter) setting of the A/C.
Definition: ir_Haier.cpp:674
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Haier.cpp:543
+
static void setTime(uint8_t ptr[], const uint16_t nr_mins)
Set the Time value at the given pointer.
Definition: ir_Haier.cpp:286
+
const uint16_t kHaierAcYrw02DefaultRepeat
Definition: IRremoteESP8266.h:891
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Haier.cpp:686
+
const uint8_t kHaierAcMinsSize
Definition: ir_Haier.h:86
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Haier.cpp:839
+
const uint8_t kHaierAcHealthBitOffset
Definition: ir_Haier.h:58
+
const uint8_t kHaierAcTimeOffset
Definition: ir_Haier.h:84
+
static uint16_t getTime(const uint8_t ptr[])
Get the Time value at the given pointer.
Definition: ir_Haier.cpp:254
+
const uint8_t kHaierAcYrw02ModeOffset
Definition: ir_Haier.h:163
+
const uint8_t kHaierAcYrw02Fan
Definition: ir_Haier.h:168
+
const uint16_t kHaierAcDefaultRepeat
Definition: IRremoteESP8266.h:888
+
const uint8_t kHaierAcYrw02FanMed
Definition: ir_Haier.h:150
+
const uint8_t kHaierAcSwingChg
Definition: ir_Haier.h:66
+
void setSwing(const uint8_t state)
Set the Vertical Swing mode of the A/C.
Definition: ir_Haier.cpp:329
+
const uint8_t kHaierAcAuto
Definition: ir_Haier.h:70
+
const uint8_t kHaierAcYrw02ButtonTurbo
Definition: ir_Haier.h:183
+
bool getHealth(void)
Get the Health (filter) setting of the A/C.
Definition: ir_Haier.cpp:235
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Haier.h:299
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Haier.h:346
+
const uint16_t kHaierACStateLength
Definition: IRremoteESP8266.h:886
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Haier.cpp:680
+
const uint8_t kHaierAcCmdTempDown
Definition: ir_Haier.h:44
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Haier.cpp:130
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Haier.cpp:108
+
const uint8_t kHaierAcCmdMode
Definition: ir_Haier.h:41
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kHaierAcYrw02ButtonHealth
Definition: ir_Haier.h:182
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Haier.cpp:161
+
void on(void)
Change the power setting to On.
Definition: ir_Haier.cpp:692
+
const uint8_t kHaierAcCmdSleep
Definition: ir_Haier.h:45
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Haier.cpp:358
+
const uint8_t kHaierAcYrw02PowerOffset
Definition: ir_Haier.h:142
+
const uint8_t kHaierAcYrw02TurboOffset
Definition: ir_Haier.h:155
+
int16_t getOffTimer(void)
Get the Off Timer value/setting of the A/C.
Definition: ir_Haier.cpp:271
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Haier.cpp:826
+
uint8_t remote_state[kHaierACYRW02StateLength]
The state in native form.
Definition: ir_Haier.h:352
+
const uint8_t kHaierAcYrw02Auto
Definition: ir_Haier.h:164
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Haier.cpp:123
+
const uint8_t kHaierAcCmdSwing
Definition: ir_Haier.h:49
+
const uint8_t kHaierAcYrw02Prefix
Definition: ir_Haier.h:125
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Haier.cpp:450
+
const uint8_t kHaierAcYrw02TurboSize
Definition: ir_Haier.h:156
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Haier.cpp:241
+
const uint8_t kHaierAcYrw02SwingTop
Definition: ir_Haier.h:132
+ +
const uint8_t kHaierAcCmdTimerSet
Definition: ir_Haier.h:46
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Haier.cpp:699
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Haier.cpp:188
+
const uint8_t kHaierAcCmdTempUp
Definition: ir_Haier.h:43
+
void cancelTimers(void)
Cancel/disable the On & Off timers.
Definition: ir_Haier.cpp:310
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Haier.cpp:569
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Haier.cpp:712
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Haier.h:275
+
void setSwing(const uint8_t pos)
Set the Vertical Swing mode of the A/C.
Definition: ir_Haier.cpp:761
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Haier.cpp:345
+
uint8_t getSwing(void)
Get the Vertical Swing position setting of the A/C.
Definition: ir_Haier.cpp:755
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kHaierAcFanLow
Definition: ir_Haier.h:77
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Haier.cpp:734
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kHaierAcYrw02Sleep
Definition: ir_Haier.h:172
+
const uint8_t kHaierAcYrw02ButtonSleep
Definition: ir_Haier.h:184
+
const uint8_t kHaierAcPrefix
Definition: ir_Haier.h:33
+
const uint16_t kHaierACYRW02StateLength
Definition: IRremoteESP8266.h:889
+
void setOnTimer(const uint16_t mins)
Set & enable the On Timer.
Definition: ir_Haier.cpp:295
+
const uint8_t kHaierAcSwingOff
Definition: ir_Haier.h:63
+
const uint8_t kHaierAcSwingDown
Definition: ir_Haier.h:65
+ +
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Haier.cpp:637
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Haier.cpp:864
+
const uint8_t kHaierAcYrw02FanHigh
Definition: ir_Haier.h:149
+
const uint8_t kHaierAcFan
Definition: ir_Haier.h:74
+
const uint8_t kHaierAcYrw02FanLow
Definition: ir_Haier.h:151
+
const uint8_t kHaierAcYrw02SwingAuto
Definition: ir_Haier.h:136
+
const uint8_t kHaierAcCool
Definition: ir_Haier.h:71
+
const uint8_t kHaierAcDefTemp
Definition: ir_Haier.h:37
+
uint8_t remote_state[kHaierACStateLength]
The state in native code form.
Definition: ir_Haier.h:281
+
const uint8_t kHaierAcYrw02SwingOff
Definition: ir_Haier.h:131
+
uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Haier.cpp:372
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Haier.cpp:741
+
const uint8_t kHaierAcOffTimerOffset
Definition: ir_Haier.h:54
+
void setHealth(const bool on)
Set the Health (filter) setting of the A/C.
Definition: ir_Haier.cpp:228
+
const uint8_t kHaierAcYrw02ButtonTempUp
Definition: ir_Haier.h:176
+
const uint8_t kHaierAcYrw02SleepOffset
Definition: ir_Haier.h:171
+
void off(void)
Change the power setting to Off.
Definition: ir_Haier.cpp:695
+
void setHealth(const bool on)
Set the Health (filter) setting of the A/C.
Definition: ir_Haier.cpp:667
+
const uint8_t kHaierAcMinTemp
Definition: ir_Haier.h:36
+
const uint8_t kHaierAcYrw02SwingDown
Definition: ir_Haier.h:135
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Haier.cpp:222
+
static bool validChecksum(uint8_t state[], const uint16_t length=kHaierACStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Haier.cpp:102
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Haier.cpp:554
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Haier.cpp:248
+
const uint8_t kHaierAcCmdHealth
Definition: ir_Haier.h:48
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Haier.cpp:661
+
const uint8_t kHaierAcCmdOn
Definition: ir_Haier.h:40
+
const uint8_t kHaierAcYrw02SwingMiddle
Definition: ir_Haier.h:133
+
const uint8_t kHaierAcYrw02ButtonSwing
Definition: ir_Haier.h:178
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Haier.cpp:890
+
const uint8_t kHaierAcYrw02TurboLow
Definition: ir_Haier.h:159
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Haier.cpp:585
+
const uint8_t kHaierAcFanMed
Definition: ir_Haier.h:78
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Haier.cpp:705
+
const uint8_t kHaierAcYrw02TurboOff
Definition: ir_Haier.h:157
+
uint8_t getButton(void)
Get the Button/Command setting of the A/C.
Definition: ir_Haier.cpp:615
+
const uint8_t kHaierAcYrw02ButtonTempDown
Definition: ir_Haier.h:177
+
Class for handling detailed Haier A/C messages.
Definition: ir_Haier.h:217
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Haier.cpp:643
+
const uint8_t kHaierAcYrw02FanOffset
Definition: ir_Haier.h:147
+
uint16_t getCurrTime(void)
Get the clock value of the A/C.
Definition: ir_Haier.cpp:281
+
const uint8_t kHaierAcSleepBitOffset
Definition: ir_Haier.h:91
+
void setOffTimer(const uint16_t mins)
Set & enable the Off Timer.
Definition: ir_Haier.cpp:303
+
const uint8_t kHaierAcYrw02FanAuto
Definition: ir_Haier.h:152
+
const uint8_t kHaierAcYrw02TurboHigh
Definition: ir_Haier.h:158
+
const uint8_t kHaierAcMaxTemp
Definition: ir_Haier.h:38
+
void send(const uint16_t repeat=kHaierAcYrw02DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Haier.cpp:548
+
void setButton(const uint8_t button)
Set the Button/Command setting of the A/C.
Definition: ir_Haier.cpp:598
+
const uint8_t kHaierAcYrw02ButtonFan
Definition: ir_Haier.h:179
+
const uint8_t kHaierAcYrw02Cool
Definition: ir_Haier.h:165
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Haier.cpp:387
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Haier.cpp:592
+
const uint8_t kHaierAcYrw02HealthOffset
Definition: ir_Haier.h:139
+
const uint8_t kHaierAcYrw02SwingBottom
Definition: ir_Haier.h:134
+
const uint8_t kHaierAcFanAuto
Definition: ir_Haier.h:76
+
uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Haier.cpp:811
+
uint8_t getCommand(void)
Get the Command/Button setting of the A/C.
Definition: ir_Haier.cpp:155
+
const uint8_t kHaierAcYrw02Power
Definition: ir_Haier.h:143
+
const uint8_t kHaierAcCmdOff
Definition: ir_Haier.h:39
+
IRHaierACYRW02(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Haier.cpp:538
+
const uint8_t kHaierAcYrw02Heat
Definition: ir_Haier.h:167
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Haier.cpp:94
+
void setCommand(const uint8_t command)
Set the Command/Button setting of the A/C.
Definition: ir_Haier.cpp:136
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Haier.h:227
+
const uint8_t kHaierAcSleepBit
Definition: ir_Haier.h:92
+
const uint8_t kHaierAcDry
Definition: ir_Haier.h:72
+
const uint8_t kHaierAcOnTimerOffset
Definition: ir_Haier.h:55
+
static bool validChecksum(uint8_t state[], const uint16_t length=kHaierACYRW02StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Haier.cpp:563
+
const uint8_t kHaierAcSwingUp
Definition: ir_Haier.h:64
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Haier.cpp:412
+
const uint8_t kHaierAcYrw02ButtonMode
Definition: ir_Haier.h:181
+
const uint8_t kHaierAcHeat
Definition: ir_Haier.h:73
+
const uint8_t kHaierAcYrw02FanSize
Definition: ir_Haier.h:148
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Haier.cpp:198
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Haier.cpp:83
+
uint8_t getSwing(void)
Get the Vertical Swing position setting of the A/C.
Definition: ir_Haier.cpp:323
+
const uint16_t kHaierAcMaxTime
Definition: ir_Haier.h:88
+
void setCurrTime(const uint16_t mins)
Set the clock value for the A/C.
Definition: ir_Haier.cpp:317
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Haier.cpp:851
+
Class for handling detailed Haier ACYRW02 A/C messages.
Definition: ir_Haier.h:289
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Haier.cpp:177
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Haier.cpp:423
+
IRHaierAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Haier.cpp:78
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Haier.cpp:204
+
const uint8_t kHaierAcSwingOffset
Definition: ir_Haier.h:61
+
void setTurbo(const uint8_t speed)
Set the Turbo setting of the A/C.
Definition: ir_Haier.cpp:721
+
const uint8_t kHaierAcYrw02Dry
Definition: ir_Haier.h:166
+
const uint8_t kHaierAcModeOffset
Definition: ir_Haier.h:69
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Haier.cpp:784
+
const uint8_t kHaierAcHoursSize
Definition: ir_Haier.h:85
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Haier.cpp:400
+
const uint8_t kHaierAcYrw02ButtonPower
Definition: ir_Haier.h:180
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Haier.cpp:621
+
int16_t getOnTimer(void)
Get the On Timer value/setting of the A/C.
Definition: ir_Haier.cpp:261
+
const uint8_t kHaierAcSwingSize
Definition: ir_Haier.h:62
+
const uint8_t kHaierAcCmdTimerCancel
Definition: ir_Haier.h:47
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Haier.cpp:797
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+
void send(const uint16_t repeat=kHaierAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Haier.cpp:88
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8cpp.html new file mode 100644 index 000000000..705884418 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8cpp.html @@ -0,0 +1,423 @@ + + + + + + + +IRremoteESP8266: src/ir_Hitachi.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Hitachi.cpp File Reference
+
+
+ +

Support for Hitachi A/C protocols. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kHitachiAcHdrMark = 3300
 
const uint16_t kHitachiAcHdrSpace = 1700
 
const uint16_t kHitachiAc1HdrMark = 3400
 
const uint16_t kHitachiAc1HdrSpace = 3400
 
const uint16_t kHitachiAcBitMark = 400
 
const uint16_t kHitachiAcOneSpace = 1250
 
const uint16_t kHitachiAcZeroSpace = 500
 
const uint32_t kHitachiAcMinGap = kDefaultMessageGap
 
const uint16_t kHitachiAc424LdrMark = 29784
 
const uint16_t kHitachiAc424LdrSpace = 49290
 
const uint16_t kHitachiAc424HdrMark = 3416
 
const uint16_t kHitachiAc424HdrSpace = 1604
 
const uint16_t kHitachiAc424BitMark = 463
 
const uint16_t kHitachiAc424OneSpace = 1208
 
const uint16_t kHitachiAc424ZeroSpace = 372
 
const uint16_t kHitachiAc3HdrMark = 3400
 
const uint16_t kHitachiAc3HdrSpace = 1660
 
const uint16_t kHitachiAc3BitMark = 460
 
const uint16_t kHitachiAc3OneSpace = 1250
 
const uint16_t kHitachiAc3ZeroSpace = 410
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kHitachiAc1HdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAc1HdrMark = 3400
+
+ +
+
+ +

◆ kHitachiAc1HdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc1HdrSpace = 3400
+
+ +
+
+ +

◆ kHitachiAc3BitMark

+ +
+
+ + + + +
const uint16_t kHitachiAc3BitMark = 460
+
+ +
+
+ +

◆ kHitachiAc3HdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAc3HdrMark = 3400
+
+ +
+
+ +

◆ kHitachiAc3HdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc3HdrSpace = 1660
+
+ +
+
+ +

◆ kHitachiAc3OneSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc3OneSpace = 1250
+
+ +
+
+ +

◆ kHitachiAc3ZeroSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc3ZeroSpace = 410
+
+ +
+
+ +

◆ kHitachiAc424BitMark

+ +
+
+ + + + +
const uint16_t kHitachiAc424BitMark = 463
+
+ +
+
+ +

◆ kHitachiAc424HdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAc424HdrMark = 3416
+
+ +
+
+ +

◆ kHitachiAc424HdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc424HdrSpace = 1604
+
+ +
+
+ +

◆ kHitachiAc424LdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAc424LdrMark = 29784
+
+ +
+
+ +

◆ kHitachiAc424LdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc424LdrSpace = 49290
+
+ +
+
+ +

◆ kHitachiAc424OneSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc424OneSpace = 1208
+
+ +
+
+ +

◆ kHitachiAc424ZeroSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc424ZeroSpace = 372
+
+ +
+
+ +

◆ kHitachiAcBitMark

+ +
+
+ + + + +
const uint16_t kHitachiAcBitMark = 400
+
+ +
+
+ +

◆ kHitachiAcHdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAcHdrMark = 3300
+
+ +
+
+ +

◆ kHitachiAcHdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAcHdrSpace = 1700
+
+ +
+
+ +

◆ kHitachiAcMinGap

+ +
+
+ + + + +
const uint32_t kHitachiAcMinGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kHitachiAcOneSpace

+ +
+
+ + + + +
const uint16_t kHitachiAcOneSpace = 1250
+
+ +
+
+ +

◆ kHitachiAcZeroSpace

+ +
+
+ + + + +
const uint16_t kHitachiAcZeroSpace = 500
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h.html new file mode 100644 index 000000000..062ecdd3d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h.html @@ -0,0 +1,2028 @@ + + + + + + + +IRremoteESP8266: src/ir_Hitachi.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Hitachi.h File Reference
+
+
+ +

Support for Hitachi A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + +

+Classes

class  IRHitachiAc
 Class for handling detailed Hitachi 224-bit A/C messages. More...
 
class  IRHitachiAc1
 Class for handling detailed Hitachi 104-bit A/C messages. More...
 
class  IRHitachiAc424
 Class for handling detailed Hitachi 53-byte/424-bit A/C messages. More...
 
class  IRHitachiAc3
 Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages. More...
 
class  IRHitachiAc344
 Class for handling detailed Hitachi 344-bit A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kHitachiAcFreq = 38000
 
const uint8_t kHitachiAcAuto = 2
 
const uint8_t kHitachiAcHeat = 3
 
const uint8_t kHitachiAcCool = 4
 
const uint8_t kHitachiAcDry = 5
 
const uint8_t kHitachiAcFan = 0xC
 
const uint8_t kHitachiAcFanAuto = 1
 
const uint8_t kHitachiAcFanLow = 2
 
const uint8_t kHitachiAcFanMed = 3
 
const uint8_t kHitachiAcFanHigh = 5
 
const uint8_t kHitachiAcMinTemp = 16
 
const uint8_t kHitachiAcMaxTemp = 32
 
const uint8_t kHitachiAcAutoTemp = 23
 
const uint8_t kHitachiAcPowerOffset = 0
 
const uint8_t kHitachiAcSwingOffset = 7
 
const uint8_t kHitachiAc424ButtonByte = 11
 
const uint8_t kHitachiAc424ButtonPowerMode = 0x13
 
const uint8_t kHitachiAc424ButtonFan = 0x42
 
const uint8_t kHitachiAc424ButtonTempDown = 0x43
 
const uint8_t kHitachiAc424ButtonTempUp = 0x44
 
const uint8_t kHitachiAc424ButtonSwingV = 0x81
 
const uint8_t kHitachiAc424ButtonSwingH = 0x8C
 
const uint8_t kHitachiAc344ButtonPowerMode = kHitachiAc424ButtonPowerMode
 
const uint8_t kHitachiAc344ButtonFan = kHitachiAc424ButtonFan
 
const uint8_t kHitachiAc344ButtonTempDown = kHitachiAc424ButtonTempDown
 
const uint8_t kHitachiAc344ButtonTempUp = kHitachiAc424ButtonTempUp
 
const uint8_t kHitachiAc344ButtonSwingV = kHitachiAc424ButtonSwingV
 
const uint8_t kHitachiAc344ButtonSwingH = kHitachiAc424ButtonSwingH
 
const uint8_t kHitachiAc424TempByte = 13
 
const uint8_t kHitachiAc424TempOffset = 2
 
const uint8_t kHitachiAc424TempSize = 6
 
const uint8_t kHitachiAc424MinTemp = 16
 
const uint8_t kHitachiAc424MaxTemp = 32
 
const uint8_t kHitachiAc344MinTemp = kHitachiAc424MinTemp
 
const uint8_t kHitachiAc344MaxTemp = kHitachiAc424MaxTemp
 
const uint8_t kHitachiAc424FanTemp = 27
 
const uint8_t kHitachiAc424ModeByte = 25
 
const uint8_t kHitachiAc424Fan = 1
 
const uint8_t kHitachiAc424Cool = 3
 
const uint8_t kHitachiAc424Dry = 5
 
const uint8_t kHitachiAc424Heat = 6
 
const uint8_t kHitachiAc344Fan = kHitachiAc424Fan
 
const uint8_t kHitachiAc344Cool = kHitachiAc424Cool
 
const uint8_t kHitachiAc344Dry = kHitachiAc424Dry
 
const uint8_t kHitachiAc344Heat = kHitachiAc424Heat
 
const uint8_t kHitachiAc424FanByte = kHitachiAc424ModeByte
 
const uint8_t kHitachiAc424FanMin = 1
 
const uint8_t kHitachiAc424FanLow = 2
 
const uint8_t kHitachiAc424FanMedium = 3
 
const uint8_t kHitachiAc424FanHigh = 4
 
const uint8_t kHitachiAc424FanAuto = 5
 
const uint8_t kHitachiAc424FanMax = 6
 
const uint8_t kHitachiAc424FanMaxDry = 2
 
const uint8_t kHitachiAc344FanMin = kHitachiAc424FanMin
 
const uint8_t kHitachiAc344FanLow = kHitachiAc424FanLow
 
const uint8_t kHitachiAc344FanMedium = kHitachiAc424FanMedium
 
const uint8_t kHitachiAc344FanHigh = kHitachiAc424FanHigh
 
const uint8_t kHitachiAc344FanAuto = kHitachiAc424FanAuto
 
const uint8_t kHitachiAc344FanMax = kHitachiAc424FanMax
 
const uint8_t kHitachiAc424PowerByte = 27
 
const uint8_t kHitachiAc424PowerOn = 0xF1
 
const uint8_t kHitachiAc424PowerOff = 0xE1
 
const uint8_t kHitachiAc344SwingHByte = 35
 
const uint8_t kHitachiAc344SwingHOffset = 0
 
const uint8_t kHitachiAc344SwingHSize = 3
 
const uint8_t kHitachiAc344SwingHAuto = 0
 
const uint8_t kHitachiAc344SwingHRightMax = 1
 
const uint8_t kHitachiAc344SwingHRight = 2
 
const uint8_t kHitachiAc344SwingHMiddle = 3
 
const uint8_t kHitachiAc344SwingHLeft = 4
 
const uint8_t kHitachiAc344SwingHLeftMax = 5
 
const uint8_t kHitachiAc344SwingVByte = 37
 
const uint8_t kHitachiAc344SwingVOffset = 5
 
const uint8_t kHitachiAc1ModelByte = 3
 
const uint8_t kHitachiAc1ModelOffset = 6
 
const uint8_t kHitachiAc1Model_A = 0b10
 
const uint8_t kHitachiAc1Model_B = 0b01
 
const uint8_t kHitachiAc1ModelSize = 2
 
const uint8_t kHitachiAc1ModeByte = 5
 
const uint8_t kHitachiAc1ModeOffset = 4
 
const uint8_t kHitachiAc1ModeSize = 4
 
const uint8_t kHitachiAc1Dry = 0b0010
 
const uint8_t kHitachiAc1Fan = 0b0100
 
const uint8_t kHitachiAc1Cool = 0b0110
 
const uint8_t kHitachiAc1Heat = 0b1001
 
const uint8_t kHitachiAc1Auto = 0b1110
 
const uint8_t kHitachiAc1FanByte = kHitachiAc1ModeByte
 
const uint8_t kHitachiAc1FanOffset = 0
 
const uint8_t kHitachiAc1FanSize = 4
 
const uint8_t kHitachiAc1FanAuto = 1
 
const uint8_t kHitachiAc1FanHigh = 2
 
const uint8_t kHitachiAc1FanMed = 4
 
const uint8_t kHitachiAc1FanLow = 8
 
const uint8_t kHitachiAc1TempByte = 6
 
const uint8_t kHitachiAc1TempOffset = 2
 
const uint8_t kHitachiAc1TempSize = 5
 
const uint8_t kHitachiAc1TempDelta = 7
 
const uint8_t kHitachiAc1TempAuto = 25
 
const uint8_t kHitachiAc1TimerSize = 16
 
const uint8_t kHitachiAc1OffTimerLowByte = 7
 
const uint8_t kHitachiAc1OffTimerHighByte = 8
 
const uint8_t kHitachiAc1OnTimerLowByte = 9
 
const uint8_t kHitachiAc1OnTimerHighByte = 10
 
const uint8_t kHitachiAc1PowerByte = 11
 
const uint8_t kHitachiAc1PowerOffset = 5
 
const uint8_t kHitachiAc1PowerToggleOffset = 4
 
const uint8_t kHitachiAc1SwingByte = kHitachiAc1PowerByte
 
const uint8_t kHitachiAc1SwingHOffset = 7
 
const uint8_t kHitachiAc1SwingVOffset = 6
 
const uint8_t kHitachiAc1SwingToggleOffset = 0
 
const uint8_t kHitachiAc1SleepByte = kHitachiAc1PowerByte
 
const uint8_t kHitachiAc1SleepOffset = 1
 
const uint8_t kHitachiAc1SleepSize = 3
 
const uint8_t kHitachiAc1SleepOff = 0b000
 
const uint8_t kHitachiAc1Sleep1 = 0b001
 
const uint8_t kHitachiAc1Sleep2 = 0b010
 
const uint8_t kHitachiAc1Sleep3 = 0b011
 
const uint8_t kHitachiAc1Sleep4 = 0b100
 
const uint8_t kHitachiAc1ChecksumStartByte = 5
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kHitachiAc1Auto

+ +
+
+ + + + +
const uint8_t kHitachiAc1Auto = 0b1110
+
+ +
+
+ +

◆ kHitachiAc1ChecksumStartByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1ChecksumStartByte = 5
+
+ +
+
+ +

◆ kHitachiAc1Cool

+ +
+
+ + + + +
const uint8_t kHitachiAc1Cool = 0b0110
+
+ +
+
+ +

◆ kHitachiAc1Dry

+ +
+
+ + + + +
const uint8_t kHitachiAc1Dry = 0b0010
+
+ +
+
+ +

◆ kHitachiAc1Fan

+ +
+
+ + + + +
const uint8_t kHitachiAc1Fan = 0b0100
+
+ +
+
+ +

◆ kHitachiAc1FanAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanAuto = 1
+
+ +
+
+ +

◆ kHitachiAc1FanByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanByte = kHitachiAc1ModeByte
+
+ +
+
+ +

◆ kHitachiAc1FanHigh

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanHigh = 2
+
+ +
+
+ +

◆ kHitachiAc1FanLow

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanLow = 8
+
+ +
+
+ +

◆ kHitachiAc1FanMed

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanMed = 4
+
+ +
+
+ +

◆ kHitachiAc1FanOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanOffset = 0
+
+ +
+
+ +

◆ kHitachiAc1FanSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanSize = 4
+
+ +
+
+ +

◆ kHitachiAc1Heat

+ +
+
+ + + + +
const uint8_t kHitachiAc1Heat = 0b1001
+
+ +
+
+ +

◆ kHitachiAc1ModeByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModeByte = 5
+
+ +
+
+ +

◆ kHitachiAc1Model_A

+ +
+
+ + + + +
const uint8_t kHitachiAc1Model_A = 0b10
+
+ +
+
+ +

◆ kHitachiAc1Model_B

+ +
+
+ + + + +
const uint8_t kHitachiAc1Model_B = 0b01
+
+ +
+
+ +

◆ kHitachiAc1ModelByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModelByte = 3
+
+ +
+
+ +

◆ kHitachiAc1ModelOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModelOffset = 6
+
+ +
+
+ +

◆ kHitachiAc1ModelSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModelSize = 2
+
+ +
+
+ +

◆ kHitachiAc1ModeOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModeOffset = 4
+
+ +
+
+ +

◆ kHitachiAc1ModeSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModeSize = 4
+
+ +
+
+ +

◆ kHitachiAc1OffTimerHighByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1OffTimerHighByte = 8
+
+ +
+
+ +

◆ kHitachiAc1OffTimerLowByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1OffTimerLowByte = 7
+
+ +
+
+ +

◆ kHitachiAc1OnTimerHighByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1OnTimerHighByte = 10
+
+ +
+
+ +

◆ kHitachiAc1OnTimerLowByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1OnTimerLowByte = 9
+
+ +
+
+ +

◆ kHitachiAc1PowerByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1PowerByte = 11
+
+ +
+
+ +

◆ kHitachiAc1PowerOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1PowerOffset = 5
+
+ +
+
+ +

◆ kHitachiAc1PowerToggleOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1PowerToggleOffset = 4
+
+ +
+
+ +

◆ kHitachiAc1Sleep1

+ +
+
+ + + + +
const uint8_t kHitachiAc1Sleep1 = 0b001
+
+ +
+
+ +

◆ kHitachiAc1Sleep2

+ +
+
+ + + + +
const uint8_t kHitachiAc1Sleep2 = 0b010
+
+ +
+
+ +

◆ kHitachiAc1Sleep3

+ +
+
+ + + + +
const uint8_t kHitachiAc1Sleep3 = 0b011
+
+ +
+
+ +

◆ kHitachiAc1Sleep4

+ +
+
+ + + + +
const uint8_t kHitachiAc1Sleep4 = 0b100
+
+ +
+
+ +

◆ kHitachiAc1SleepByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1SleepByte = kHitachiAc1PowerByte
+
+ +
+
+ +

◆ kHitachiAc1SleepOff

+ +
+
+ + + + +
const uint8_t kHitachiAc1SleepOff = 0b000
+
+ +
+
+ +

◆ kHitachiAc1SleepOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1SleepOffset = 1
+
+ +
+
+ +

◆ kHitachiAc1SleepSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1SleepSize = 3
+
+ +
+
+ +

◆ kHitachiAc1SwingByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1SwingByte = kHitachiAc1PowerByte
+
+ +
+
+ +

◆ kHitachiAc1SwingHOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1SwingHOffset = 7
+
+ +
+
+ +

◆ kHitachiAc1SwingToggleOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1SwingToggleOffset = 0
+
+ +
+
+ +

◆ kHitachiAc1SwingVOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1SwingVOffset = 6
+
+ +
+
+ +

◆ kHitachiAc1TempAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempAuto = 25
+
+ +
+
+ +

◆ kHitachiAc1TempByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempByte = 6
+
+ +
+
+ +

◆ kHitachiAc1TempDelta

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempDelta = 7
+
+ +
+
+ +

◆ kHitachiAc1TempOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempOffset = 2
+
+ +
+
+ +

◆ kHitachiAc1TempSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempSize = 5
+
+ +
+
+ +

◆ kHitachiAc1TimerSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1TimerSize = 16
+
+ +
+
+ +

◆ kHitachiAc344ButtonFan

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonFan = kHitachiAc424ButtonFan
+
+ +
+
+ +

◆ kHitachiAc344ButtonPowerMode

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonPowerMode = kHitachiAc424ButtonPowerMode
+
+ +
+
+ +

◆ kHitachiAc344ButtonSwingH

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonSwingH = kHitachiAc424ButtonSwingH
+
+ +
+
+ +

◆ kHitachiAc344ButtonSwingV

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonSwingV = kHitachiAc424ButtonSwingV
+
+ +
+
+ +

◆ kHitachiAc344ButtonTempDown

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonTempDown = kHitachiAc424ButtonTempDown
+
+ +
+
+ +

◆ kHitachiAc344ButtonTempUp

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonTempUp = kHitachiAc424ButtonTempUp
+
+ +
+
+ +

◆ kHitachiAc344Cool

+ +
+
+ + + + +
const uint8_t kHitachiAc344Cool = kHitachiAc424Cool
+
+ +
+
+ +

◆ kHitachiAc344Dry

+ +
+
+ + + + +
const uint8_t kHitachiAc344Dry = kHitachiAc424Dry
+
+ +
+
+ +

◆ kHitachiAc344Fan

+ +
+
+ + + + +
const uint8_t kHitachiAc344Fan = kHitachiAc424Fan
+
+ +
+
+ +

◆ kHitachiAc344FanAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanAuto = kHitachiAc424FanAuto
+
+ +
+
+ +

◆ kHitachiAc344FanHigh

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanHigh = kHitachiAc424FanHigh
+
+ +
+
+ +

◆ kHitachiAc344FanLow

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanLow = kHitachiAc424FanLow
+
+ +
+
+ +

◆ kHitachiAc344FanMax

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanMax = kHitachiAc424FanMax
+
+ +
+
+ +

◆ kHitachiAc344FanMedium

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanMedium = kHitachiAc424FanMedium
+
+ +
+
+ +

◆ kHitachiAc344FanMin

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanMin = kHitachiAc424FanMin
+
+ +
+
+ +

◆ kHitachiAc344Heat

+ +
+
+ + + + +
const uint8_t kHitachiAc344Heat = kHitachiAc424Heat
+
+ +
+
+ +

◆ kHitachiAc344MaxTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc344MaxTemp = kHitachiAc424MaxTemp
+
+ +
+
+ +

◆ kHitachiAc344MinTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc344MinTemp = kHitachiAc424MinTemp
+
+ +
+
+ +

◆ kHitachiAc344SwingHAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHAuto = 0
+
+ +
+
+ +

◆ kHitachiAc344SwingHByte

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHByte = 35
+
+ +
+
+ +

◆ kHitachiAc344SwingHLeft

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHLeft = 4
+
+ +
+
+ +

◆ kHitachiAc344SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHLeftMax = 5
+
+ +
+
+ +

◆ kHitachiAc344SwingHMiddle

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHMiddle = 3
+
+ +
+
+ +

◆ kHitachiAc344SwingHOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHOffset = 0
+
+ +
+
+ +

◆ kHitachiAc344SwingHRight

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHRight = 2
+
+ +
+
+ +

◆ kHitachiAc344SwingHRightMax

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHRightMax = 1
+
+ +
+
+ +

◆ kHitachiAc344SwingHSize

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHSize = 3
+
+ +
+
+ +

◆ kHitachiAc344SwingVByte

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingVByte = 37
+
+ +
+
+ +

◆ kHitachiAc344SwingVOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingVOffset = 5
+
+ +
+
+ +

◆ kHitachiAc424ButtonByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonByte = 11
+
+ +
+
+ +

◆ kHitachiAc424ButtonFan

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonFan = 0x42
+
+ +
+
+ +

◆ kHitachiAc424ButtonPowerMode

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonPowerMode = 0x13
+
+ +
+
+ +

◆ kHitachiAc424ButtonSwingH

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonSwingH = 0x8C
+
+ +
+
+ +

◆ kHitachiAc424ButtonSwingV

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonSwingV = 0x81
+
+ +
+
+ +

◆ kHitachiAc424ButtonTempDown

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonTempDown = 0x43
+
+ +
+
+ +

◆ kHitachiAc424ButtonTempUp

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonTempUp = 0x44
+
+ +
+
+ +

◆ kHitachiAc424Cool

+ +
+
+ + + + +
const uint8_t kHitachiAc424Cool = 3
+
+ +
+
+ +

◆ kHitachiAc424Dry

+ +
+
+ + + + +
const uint8_t kHitachiAc424Dry = 5
+
+ +
+
+ +

◆ kHitachiAc424Fan

+ +
+
+ + + + +
const uint8_t kHitachiAc424Fan = 1
+
+ +
+
+ +

◆ kHitachiAc424FanAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanAuto = 5
+
+ +
+
+ +

◆ kHitachiAc424FanByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanByte = kHitachiAc424ModeByte
+
+ +
+
+ +

◆ kHitachiAc424FanHigh

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanHigh = 4
+
+ +
+
+ +

◆ kHitachiAc424FanLow

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanLow = 2
+
+ +
+
+ +

◆ kHitachiAc424FanMax

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanMax = 6
+
+ +
+
+ +

◆ kHitachiAc424FanMaxDry

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanMaxDry = 2
+
+ +
+
+ +

◆ kHitachiAc424FanMedium

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanMedium = 3
+
+ +
+
+ +

◆ kHitachiAc424FanMin

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanMin = 1
+
+ +
+
+ +

◆ kHitachiAc424FanTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanTemp = 27
+
+ +
+
+ +

◆ kHitachiAc424Heat

+ +
+
+ + + + +
const uint8_t kHitachiAc424Heat = 6
+
+ +
+
+ +

◆ kHitachiAc424MaxTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc424MaxTemp = 32
+
+ +
+
+ +

◆ kHitachiAc424MinTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc424MinTemp = 16
+
+ +
+
+ +

◆ kHitachiAc424ModeByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424ModeByte = 25
+
+ +
+
+ +

◆ kHitachiAc424PowerByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424PowerByte = 27
+
+ +
+
+ +

◆ kHitachiAc424PowerOff

+ +
+
+ + + + +
const uint8_t kHitachiAc424PowerOff = 0xE1
+
+ +
+
+ +

◆ kHitachiAc424PowerOn

+ +
+
+ + + + +
const uint8_t kHitachiAc424PowerOn = 0xF1
+
+ +
+
+ +

◆ kHitachiAc424TempByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424TempByte = 13
+
+ +
+
+ +

◆ kHitachiAc424TempOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc424TempOffset = 2
+
+ +
+
+ +

◆ kHitachiAc424TempSize

+ +
+
+ + + + +
const uint8_t kHitachiAc424TempSize = 6
+
+ +
+
+ +

◆ kHitachiAcAuto

+ +
+
+ + + + +
const uint8_t kHitachiAcAuto = 2
+
+ +
+
+ +

◆ kHitachiAcAutoTemp

+ +
+
+ + + + +
const uint8_t kHitachiAcAutoTemp = 23
+
+ +
+
+ +

◆ kHitachiAcCool

+ +
+
+ + + + +
const uint8_t kHitachiAcCool = 4
+
+ +
+
+ +

◆ kHitachiAcDry

+ +
+
+ + + + +
const uint8_t kHitachiAcDry = 5
+
+ +
+
+ +

◆ kHitachiAcFan

+ +
+
+ + + + +
const uint8_t kHitachiAcFan = 0xC
+
+ +
+
+ +

◆ kHitachiAcFanAuto

+ +
+
+ + + + +
const uint8_t kHitachiAcFanAuto = 1
+
+ +
+
+ +

◆ kHitachiAcFanHigh

+ +
+
+ + + + +
const uint8_t kHitachiAcFanHigh = 5
+
+ +
+
+ +

◆ kHitachiAcFanLow

+ +
+
+ + + + +
const uint8_t kHitachiAcFanLow = 2
+
+ +
+
+ +

◆ kHitachiAcFanMed

+ +
+
+ + + + +
const uint8_t kHitachiAcFanMed = 3
+
+ +
+
+ +

◆ kHitachiAcFreq

+ +
+
+ + + + +
const uint16_t kHitachiAcFreq = 38000
+
+ +
+
+ +

◆ kHitachiAcHeat

+ +
+
+ + + + +
const uint8_t kHitachiAcHeat = 3
+
+ +
+
+ +

◆ kHitachiAcMaxTemp

+ +
+
+ + + + +
const uint8_t kHitachiAcMaxTemp = 32
+
+ +
+
+ +

◆ kHitachiAcMinTemp

+ +
+
+ + + + +
const uint8_t kHitachiAcMinTemp = 16
+
+ +
+
+ +

◆ kHitachiAcPowerOffset

+ +
+
+ + + + +
const uint8_t kHitachiAcPowerOffset = 0
+
+ +
+
+ +

◆ kHitachiAcSwingOffset

+ +
+
+ + + + +
const uint8_t kHitachiAcSwingOffset = 7
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h_source.html new file mode 100644 index 000000000..66b330dd1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h_source.html @@ -0,0 +1,734 @@ + + + + + + + +IRremoteESP8266: src/ir_Hitachi.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Hitachi.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018-2020 David Conran
+
10 
+
11 // Supports:
+
12 // Brand: Hitachi, Model: RAS-35THA6 remote
+
13 // Brand: Hitachi, Model: LT0541-HTA remote (HITACHI_AC1)
+
14 // Brand: Hitachi, Model: Series VI A/C (Circa 2007) (HITACHI_AC1)
+
15 // Brand: Hitachi, Model: RAR-8P2 remote (HITACHI_AC424)
+
16 // Brand: Hitachi, Model: RAS-AJ25H A/C (HITACHI_AC424)
+
17 // Brand: Hitachi, Model: PC-LH3B (HITACHI_AC3)
+
18 // Brand: Hitachi, Model: KAZE-312KSDP A/C (HITACHI_AC1)
+
19 // Brand: Hitachi, Model: R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
+
20 // Brand: Hitachi, Model: RAS-22NK A/C (HITACHI_AC344)
+
21 // Brand: Hitachi, Model: RF11T1 remote (HITACHI_AC344)
+
22 
+
23 #ifndef IR_HITACHI_H_
+
24 #define IR_HITACHI_H_
+
25 
+
26 #define __STDC_LIMIT_MACROS
+
27 #include <stdint.h>
+
28 #ifndef UNIT_TEST
+
29 #include <Arduino.h>
+
30 #endif
+
31 #include "IRremoteESP8266.h"
+
32 #include "IRsend.h"
+
33 #ifdef UNIT_TEST
+
34 #include "IRsend_test.h"
+
35 #endif
+
36 
+
37 // Constants
+
38 const uint16_t kHitachiAcFreq = 38000; // Hz.
+
39 const uint8_t kHitachiAcAuto = 2;
+
40 const uint8_t kHitachiAcHeat = 3;
+
41 const uint8_t kHitachiAcCool = 4;
+
42 const uint8_t kHitachiAcDry = 5;
+
43 const uint8_t kHitachiAcFan = 0xC;
+
44 const uint8_t kHitachiAcFanAuto = 1;
+
45 const uint8_t kHitachiAcFanLow = 2;
+
46 const uint8_t kHitachiAcFanMed = 3;
+
47 const uint8_t kHitachiAcFanHigh = 5;
+
48 const uint8_t kHitachiAcMinTemp = 16; // 16C
+
49 const uint8_t kHitachiAcMaxTemp = 32; // 32C
+
50 const uint8_t kHitachiAcAutoTemp = 23; // 23C
+
51 const uint8_t kHitachiAcPowerOffset = 0;
+
52 const uint8_t kHitachiAcSwingOffset = 7;
+
53 
+
54 // HitachiAc424 & HitachiAc344
+
55 // Byte[11]
+
56 const uint8_t kHitachiAc424ButtonByte = 11;
+
57 const uint8_t kHitachiAc424ButtonPowerMode = 0x13;
+
58 const uint8_t kHitachiAc424ButtonFan = 0x42;
+
59 const uint8_t kHitachiAc424ButtonTempDown = 0x43;
+
60 const uint8_t kHitachiAc424ButtonTempUp = 0x44;
+
61 const uint8_t kHitachiAc424ButtonSwingV = 0x81;
+
62 const uint8_t kHitachiAc424ButtonSwingH = 0x8C;
+ + + + + + +
69 
+
70 // Byte[13]
+
71 const uint8_t kHitachiAc424TempByte = 13;
+
72 const uint8_t kHitachiAc424TempOffset = 2;
+
73 const uint8_t kHitachiAc424TempSize = 6;
+
74 const uint8_t kHitachiAc424MinTemp = 16; // 16C
+
75 const uint8_t kHitachiAc424MaxTemp = 32; // 32C
+ + +
78 const uint8_t kHitachiAc424FanTemp = 27; // 27C
+
79 
+
80 // Byte[25]
+
81 const uint8_t kHitachiAc424ModeByte = 25;
+
82 const uint8_t kHitachiAc424Fan = 1;
+
83 const uint8_t kHitachiAc424Cool = 3;
+
84 const uint8_t kHitachiAc424Dry = 5;
+
85 const uint8_t kHitachiAc424Heat = 6;
+ + + + +
90 
+ +
92 const uint8_t kHitachiAc424FanMin = 1;
+
93 const uint8_t kHitachiAc424FanLow = 2;
+
94 const uint8_t kHitachiAc424FanMedium = 3;
+
95 const uint8_t kHitachiAc424FanHigh = 4;
+
96 const uint8_t kHitachiAc424FanAuto = 5;
+
97 const uint8_t kHitachiAc424FanMax = 6;
+
98 const uint8_t kHitachiAc424FanMaxDry = 2;
+ + + + + + +
105 
+
106 // Byte[27]
+
107 const uint8_t kHitachiAc424PowerByte = 27;
+
108 const uint8_t kHitachiAc424PowerOn = 0xF1;
+
109 const uint8_t kHitachiAc424PowerOff = 0xE1;
+
110 
+
111 // Byte[35]
+
112 const uint8_t kHitachiAc344SwingHByte = 35;
+
113 const uint8_t kHitachiAc344SwingHOffset = 0; // Mask 0b00000xxx
+
114 const uint8_t kHitachiAc344SwingHSize = 3; // Mask 0b00000xxx
+
115 const uint8_t kHitachiAc344SwingHAuto = 0; // 0b000
+
116 const uint8_t kHitachiAc344SwingHRightMax = 1; // 0b001
+
117 const uint8_t kHitachiAc344SwingHRight = 2; // 0b010
+
118 const uint8_t kHitachiAc344SwingHMiddle = 3; // 0b011
+
119 const uint8_t kHitachiAc344SwingHLeft = 4; // 0b100
+
120 const uint8_t kHitachiAc344SwingHLeftMax = 5; // 0b101
+
121 
+
122 // Byte[37]
+
123 const uint8_t kHitachiAc344SwingVByte = 37;
+
124 const uint8_t kHitachiAc344SwingVOffset = 5; // Mask 0b00x00000
+
125 
+
126 // HitachiAc1
+
127 // Byte[3] (Model)
+
128 const uint8_t kHitachiAc1ModelByte = 3;
+
129 const uint8_t kHitachiAc1ModelOffset = 6; // Mask 0b11000000
+
130 const uint8_t kHitachiAc1Model_A = 0b10;
+
131 const uint8_t kHitachiAc1Model_B = 0b01;
+
132 const uint8_t kHitachiAc1ModelSize = 2;
+
133 
+
134 // Byte[5] (Mode & Fan)
+
135 const uint8_t kHitachiAc1ModeByte = 5;
+
136 const uint8_t kHitachiAc1ModeOffset = 4;
+
137 const uint8_t kHitachiAc1ModeSize = 4; // Mask 0b11110000
+
138 const uint8_t kHitachiAc1Dry = 0b0010; // 2
+
139 const uint8_t kHitachiAc1Fan = 0b0100; // 4
+
140 const uint8_t kHitachiAc1Cool = 0b0110; // 6
+
141 const uint8_t kHitachiAc1Heat = 0b1001; // 9
+
142 const uint8_t kHitachiAc1Auto = 0b1110; // 14
+ +
144 const uint8_t kHitachiAc1FanOffset = 0;
+
145 const uint8_t kHitachiAc1FanSize = 4; // Mask 0b0001111
+
146 const uint8_t kHitachiAc1FanAuto = 1; // 0b0001
+
147 const uint8_t kHitachiAc1FanHigh = 2; // 0b0010
+
148 const uint8_t kHitachiAc1FanMed = 4; // 0b0100
+
149 const uint8_t kHitachiAc1FanLow = 8; // 0b1000
+
150 // Byte[6] (Temperature)
+
151 // Note: Temp is stored in LSB order.
+
152 const uint8_t kHitachiAc1TempByte = 6;
+
153 const uint8_t kHitachiAc1TempOffset = 2;
+
154 const uint8_t kHitachiAc1TempSize = 5; // Mask 0b01111100
+
155 const uint8_t kHitachiAc1TempDelta = 7;
+
156 const uint8_t kHitachiAc1TempAuto = 25; // Celsius
+
157 // Note: Timers are nr. of minutes & stored in LSB order.
+
158 // Byte[7-8] (Off Timer)
+
159 const uint8_t kHitachiAc1TimerSize = 16; // Mask 0b1111111111111111
+
160 const uint8_t kHitachiAc1OffTimerLowByte = 7;
+
161 const uint8_t kHitachiAc1OffTimerHighByte = 8;
+
162 // Byte[9-10] (On Timer)
+
163 const uint8_t kHitachiAc1OnTimerLowByte = 9;
+
164 const uint8_t kHitachiAc1OnTimerHighByte = 10;
+
165 // Byte[11] (Power/Swing/Sleep)
+
166 const uint8_t kHitachiAc1PowerByte = 11;
+
167 const uint8_t kHitachiAc1PowerOffset = 5; // Mask 0b00100000
+
168 const uint8_t kHitachiAc1PowerToggleOffset = 4; // Mask 0b00010000
+ +
170 const uint8_t kHitachiAc1SwingHOffset = 7; // Mask 0b10000000
+
171 const uint8_t kHitachiAc1SwingVOffset = 6; // Mask 0b01000000
+
172 const uint8_t kHitachiAc1SwingToggleOffset = 0; // Mask 0b00000001
+ +
174 const uint8_t kHitachiAc1SleepOffset = 1; // Mask 0b00001110
+
175 const uint8_t kHitachiAc1SleepSize = 3; // Mask 0b00001110
+
176 const uint8_t kHitachiAc1SleepOff = 0b000;
+
177 const uint8_t kHitachiAc1Sleep1 = 0b001;
+
178 const uint8_t kHitachiAc1Sleep2 = 0b010;
+
179 const uint8_t kHitachiAc1Sleep3 = 0b011;
+
180 const uint8_t kHitachiAc1Sleep4 = 0b100;
+
181 // Byte[12] (Checksum)
+ +
183 
+
184 
+
185 // Classes
+
188 class IRHitachiAc {
+
189  public:
+
190  explicit IRHitachiAc(const uint16_t pin, const bool inverted = false,
+
191  const bool use_modulation = true);
+
192  void stateReset(void);
+
193 #if SEND_HITACHI_AC
+
194  void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
199  int8_t calibrate(void) { return _irsend.calibrate(); }
+
200 #endif // SEND_HITACHI_AC
+
201  void begin(void);
+
202  void on(void);
+
203  void off(void);
+
204  void setPower(const bool on);
+
205  bool getPower(void);
+
206  void setTemp(const uint8_t temp);
+
207  uint8_t getTemp(void);
+
208  void setFan(const uint8_t speed);
+
209  uint8_t getFan(void);
+
210  void setMode(const uint8_t mode);
+
211  uint8_t getMode(void);
+
212  void setSwingVertical(const bool on);
+
213  bool getSwingVertical(void);
+
214  void setSwingHorizontal(const bool on);
+
215  bool getSwingHorizontal(void);
+
216  uint8_t* getRaw(void);
+
217  void setRaw(const uint8_t new_code[],
+
218  const uint16_t length = kHitachiAcStateLength);
+
219  static bool validChecksum(const uint8_t state[],
+
220  const uint16_t length = kHitachiAcStateLength);
+
221  static uint8_t calcChecksum(const uint8_t state[],
+
222  const uint16_t length = kHitachiAcStateLength);
+
223  uint8_t convertMode(const stdAc::opmode_t mode);
+
224  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
225  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
226  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
227  stdAc::state_t toCommon(void);
+
228  String toString(void);
+
229 #ifndef UNIT_TEST
+
230 
+
231  private:
+ +
233 #else // UNIT_TEST
+
234  IRsendTest _irsend;
+
236 #endif // UNIT_TEST
+ +
239  void checksum(const uint16_t length = kHitachiAcStateLength);
+
240  uint8_t _previoustemp;
+
241 };
+
242 
+ +
246  public:
+
247  explicit IRHitachiAc1(const uint16_t pin, const bool inverted = false,
+
248  const bool use_modulation = true);
+
249 
+
250  void stateReset(void);
+
251 #if SEND_HITACHI_AC1
+
252  void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
257  int8_t calibrate(void) { return _irsend.calibrate(); }
+
258 #endif // SEND_HITACHI_AC1
+
259  void begin(void);
+
260  void on(void);
+
261  void off(void);
+
262  void setModel(const hitachi_ac1_remote_model_t model);
+ +
264  void setPower(const bool on);
+
265  bool getPower(void);
+
266  void setPowerToggle(const bool on);
+
267  bool getPowerToggle(void);
+
268  void setTemp(const uint8_t temp);
+
269  uint8_t getTemp(void);
+
270  void setFan(const uint8_t speed, const bool force = false);
+
271  uint8_t getFan(void);
+
272  void setMode(const uint8_t mode);
+
273  uint8_t getMode(void);
+
274  void setSwingToggle(const bool toggle);
+
275  bool getSwingToggle(void);
+
276  void setSwingV(const bool on);
+
277  bool getSwingV(void);
+
278  void setSwingH(const bool on);
+
279  bool getSwingH(void);
+
280  void setSleep(const uint8_t mode);
+
281  uint8_t getSleep(void);
+
282  void setOnTimer(const uint16_t mins);
+
283  uint16_t getOnTimer(void);
+
284  void setOffTimer(const uint16_t mins);
+
285  uint16_t getOffTimer(void);
+
286  uint8_t* getRaw(void);
+
287  void setRaw(const uint8_t new_code[],
+
288  const uint16_t length = kHitachiAc1StateLength);
+
289  static bool validChecksum(const uint8_t state[],
+
290  const uint16_t length = kHitachiAc1StateLength);
+
291  static uint8_t calcChecksum(const uint8_t state[],
+
292  const uint16_t length = kHitachiAc1StateLength);
+
293  uint8_t convertMode(const stdAc::opmode_t mode);
+
294  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
295  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
296  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
297  stdAc::state_t toCommon(void);
+
298  String toString(void);
+
299 #ifndef UNIT_TEST
+
300 
+
301  private:
+ +
303 #else // UNIT_TEST
+
304  IRsendTest _irsend;
+
306 #endif // UNIT_TEST
+ +
309  void checksum(const uint16_t length = kHitachiAc1StateLength);
+
310 };
+
311 
+ +
314  friend class IRHitachiAc344;
+
315  public:
+
316  explicit IRHitachiAc424(const uint16_t pin, const bool inverted = false,
+
317  const bool use_modulation = true);
+
318  virtual void stateReset(void);
+
319 #if SEND_HITACHI_AC424
+
320  virtual void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
325  int8_t calibrate(void) { return _irsend.calibrate(); }
+
326 #endif // SEND_HITACHI_AC424
+
327  void begin(void);
+
328  void on(void);
+
329  void off(void);
+
330  void setPower(const bool on);
+
331  bool getPower(void);
+
332  void setTemp(const uint8_t temp, bool setPrevious = true);
+
333  uint8_t getTemp(void);
+
334  void setFan(const uint8_t speed);
+
335  uint8_t getFan(void);
+
336  uint8_t getButton(void);
+
337  void setButton(const uint8_t button);
+
338  void setSwingVToggle(const bool on);
+
339  bool getSwingVToggle(void);
+
340  void setMode(const uint8_t mode);
+
341  uint8_t getMode(void);
+
342  uint8_t* getRaw(void);
+
343  virtual void setRaw(const uint8_t new_code[],
+
344  const uint16_t length = kHitachiAc424StateLength);
+
345  uint8_t convertMode(const stdAc::opmode_t mode);
+
346  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
347  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
348  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
349  virtual stdAc::state_t toCommon(void);
+
350  String toString(void);
+
351 #ifndef UNIT_TEST
+
352 
+
353  private:
+ +
355 #else // UNIT_TEST
+
356  IRsendTest _irsend;
+
358 #endif // UNIT_TEST
+ +
361  void setInvertedStates(void);
+
362  String _toString(void);
+
363  uint8_t _previoustemp;
+
364 };
+
365 
+ +
368  public:
+
369  explicit IRHitachiAc3(const uint16_t pin, const bool inverted = false,
+
370  const bool use_modulation = true);
+
371 
+
372  void stateReset(void);
+
373 #if SEND_HITACHI_AC3
+
374  void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
379  int8_t calibrate(void) { return _irsend.calibrate(); }
+
380 #endif // SEND_HITACHI_AC3
+
381  void begin(void);
+
382  uint8_t getMode(void);
+
383  uint8_t* getRaw(void);
+
384  void setRaw(const uint8_t new_code[],
+
385  const uint16_t length = kHitachiAc3StateLength);
+
386  static bool hasInvertedStates(const uint8_t state[], const uint16_t length);
+
387 #ifndef UNIT_TEST
+
388 
+
389  private:
+ +
391 #else // UNIT_TEST
+
392  IRsendTest _irsend;
+
394 #endif // UNIT_TEST
+ +
397  void setInvertedStates(const uint16_t length = kHitachiAc3StateLength);
+
398 };
+
399 
+ +
402  public:
+
403  explicit IRHitachiAc344(const uint16_t pin, const bool inverted = false,
+
404  const bool use_modulation = true);
+
405  void stateReset(void);
+
406  void setRaw(const uint8_t new_code[],
+
407  const uint16_t length = kHitachiAc344StateLength);
+
408  stdAc::state_t toCommon(void);
+
409 #if SEND_HITACHI_AC344
+
410  void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
411 #endif // SEND_HITACHI_AC344
+
412  void setSwingV(const bool on);
+
413  bool getSwingV(void);
+
414  void setSwingH(const uint8_t position);
+
415  uint8_t getSwingH(void);
+
416  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
417  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
418  String toString(void);
+
419 };
+
420 #endif // IR_HITACHI_H_
+
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Hitachi.cpp:1585
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Hitachi.cpp:1087
+
uint8_t _previoustemp
Definition: ir_Hitachi.h:363
+
const uint8_t kHitachiAc424Fan
Definition: ir_Hitachi.h:82
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)
Calculate the checksum for a given state.
Definition: ir_Hitachi.cpp:448
+
const uint8_t kHitachiAc1TempOffset
Definition: ir_Hitachi.h:153
+
const uint8_t kHitachiAc424ButtonByte
Definition: ir_Hitachi.h:56
+
const uint8_t kHitachiAc1Fan
Definition: ir_Hitachi.h:139
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Hitachi.cpp:1149
+
const uint8_t kHitachiAc344SwingHRightMax
Definition: ir_Hitachi.h:116
+
IRHitachiAc3(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Hitachi.cpp:1378
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Hitachi.cpp:1107
+
const uint8_t kHitachiAcMinTemp
Definition: ir_Hitachi.h:48
+
bool getSwingVertical(void)
Get the Vertical Swing setting of the A/C.
Definition: ir_Hitachi.cpp:298
+
const uint8_t kHitachiAc344SwingVOffset
Definition: ir_Hitachi.h:124
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Hitachi.cpp:363
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Hitachi.cpp:593
+
uint8_t getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Hitachi.cpp:690
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Hitachi.h:354
+
void setTemp(const uint8_t temp, bool setPrevious=true)
Set the temperature.
Definition: ir_Hitachi.cpp:1134
+
const uint8_t kHitachiAcMaxTemp
Definition: ir_Hitachi.h:49
+
void setSleep(const uint8_t mode)
Set the Sleep setting of the A/C.
Definition: ir_Hitachi.cpp:698
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Hitachi.cpp:138
+
const uint8_t kHitachiAc1PowerOffset
Definition: ir_Hitachi.h:167
+
void off(void)
Change the power setting to Off.
Definition: ir_Hitachi.cpp:1097
+
const uint8_t kHitachiAcAuto
Definition: ir_Hitachi.h:39
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Hitachi.h:390
+
bool getSwingToggle(void)
Get the Swing Toggle setting of the A/C.
Definition: ir_Hitachi.cpp:651
+
const uint8_t kHitachiAc344ButtonFan
Definition: ir_Hitachi.h:64
+
const uint8_t kHitachiAc1Model_A
Definition: ir_Hitachi.h:130
+
const uint8_t kHitachiAc344ButtonPowerMode
Definition: ir_Hitachi.h:63
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Hitachi.cpp:279
+
void setPowerToggle(const bool on)
Change the power toggle setting.
Definition: ir_Hitachi.cpp:548
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a standard A/C horizontal swing into its native setting.
Definition: ir_Hitachi.cpp:1558
+
void checksum(const uint16_t length=kHitachiAc1StateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Hitachi.cpp:462
+
const uint16_t kHitachiAcStateLength
Definition: IRremoteESP8266.h:892
+
const uint8_t kHitachiAcPowerOffset
Definition: ir_Hitachi.h:51
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kHitachiAc344SwingHRight
Definition: ir_Hitachi.h:117
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Hitachi.cpp:1422
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Hitachi.h:379
+
void setSwingVertical(const bool on)
Set the Vertical Swing setting of the A/C.
Definition: ir_Hitachi.cpp:304
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Hitachi.cpp:427
+
void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
+
void setSwingHorizontal(const bool on)
Set the Horizontal Swing setting of the A/C.
Definition: ir_Hitachi.cpp:316
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Hitachi.cpp:1155
+
const uint8_t kHitachiAc1ModeOffset
Definition: ir_Hitachi.h:136
+
const uint16_t kHitachiAc1StateLength
Definition: IRremoteESP8266.h:895
+
void setSwingVToggle(const bool on)
Set the Vertical Swing toggle setting of the A/C.
Definition: ir_Hitachi.cpp:1202
+
const uint8_t kHitachiAc1ChecksumStartByte
Definition: ir_Hitachi.h:182
+
const uint8_t kHitachiAc344SwingHSize
Definition: ir_Hitachi.h:114
+
const uint8_t kHitachiAc344FanHigh
Definition: ir_Hitachi.h:102
+
void setOnTimer(const uint16_t mins)
Set the On Timer time.
Definition: ir_Hitachi.cpp:713
+
const uint8_t kHitachiAcFanHigh
Definition: ir_Hitachi.h:47
+
const uint8_t kHitachiAc1Sleep3
Definition: ir_Hitachi.h:179
+
const uint8_t kHitachiAc1TimerSize
Definition: ir_Hitachi.h:159
+
const uint8_t kHitachiAc1ModeSize
Definition: ir_Hitachi.h:137
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Hitachi.cpp:560
+
void stateReset(void)
Reset the internal state to auto fan, cooling, 23° Celsius.
Definition: ir_Hitachi.cpp:1503
+
const uint8_t kHitachiAc344Fan
Definition: ir_Hitachi.h:86
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Hitachi.cpp:227
+
Class for handling detailed Hitachi 53-byte/424-bit A/C messages.
Definition: ir_Hitachi.h:313
+
void setInvertedStates(void)
Update the internal consistency check for the protocol.
Definition: ir_Hitachi.cpp:1049
+
IRHitachiAc1(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Hitachi.cpp:422
+
void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Hitachi.cpp:492
+
const uint8_t kHitachiAc1Sleep1
Definition: ir_Hitachi.h:177
+
IRHitachiAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Hitachi.cpp:133
+
const uint8_t kHitachiAc344SwingHOffset
Definition: ir_Hitachi.h:113
+ +
const uint8_t kHitachiAc1Auto
Definition: ir_Hitachi.h:142
+
void setSwingV(const bool on)
Control the vertical swing setting.
Definition: ir_Hitachi.cpp:1526
+
const uint8_t kHitachiAc344MaxTemp
Definition: ir_Hitachi.h:77
+
const uint16_t kHitachiAc3StateLength
Definition: IRremoteESP8266.h:899
+
bool getSwingV(void)
Get the Vertical Swing setting of the A/C.
Definition: ir_Hitachi.cpp:665
+
hitachi_ac1_remote_model_t
HITACHI_AC1 A/C model numbers.
Definition: IRsend.h:135
+
uint8_t getButton(void)
Get the Button/Command setting of the A/C.
Definition: ir_Hitachi.cpp:1188
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Hitachi.h:257
+
const uint8_t kHitachiAc424ButtonSwingH
Definition: ir_Hitachi.h:62
+
const uint8_t kHitachiAc424PowerByte
Definition: ir_Hitachi.h:107
+
const uint8_t kHitachiAc424ButtonTempDown
Definition: ir_Hitachi.h:59
+
void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
Create and send the IR message to the A/C.
Definition: ir_Hitachi.cpp:1512
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kHitachiAc344SwingHAuto
Definition: ir_Hitachi.h:115
+
void setSwingH(const bool on)
Set the Horizontal Swing setting of the A/C.
Definition: ir_Hitachi.cpp:683
+
const uint8_t kHitachiAc344Heat
Definition: ir_Hitachi.h:89
+
Class for handling detailed Hitachi 224-bit A/C messages.
Definition: ir_Hitachi.h:188
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kHitachiAc344SwingHLeftMax
Definition: ir_Hitachi.h:120
+
const uint8_t kHitachiAc424TempSize
Definition: ir_Hitachi.h:73
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Hitachi.cpp:470
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Hitachi.cpp:746
+
const uint8_t kHitachiAc1FanLow
Definition: ir_Hitachi.h:149
+
Class for handling detailed Hitachi 344-bit A/C messages.
Definition: ir_Hitachi.h:401
+
const uint8_t kHitachiAc424MinTemp
Definition: ir_Hitachi.h:74
+
const uint8_t kHitachiAc344FanAuto
Definition: ir_Hitachi.h:103
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kHitachiAc1Model_B
Definition: ir_Hitachi.h:131
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Hitachi.cpp:336
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kHitachiAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Hitachi.cpp:163
+
const uint8_t kHitachiAc1FanHigh
Definition: ir_Hitachi.h:147
+
const uint8_t kHitachiAc1SleepSize
Definition: ir_Hitachi.h:175
+
const uint8_t kHitachiAc424ButtonSwingV
Definition: ir_Hitachi.h:61
+
const uint8_t kHitachiAcDry
Definition: ir_Hitachi.h:42
+
void setButton(const uint8_t button)
Set the Button/Command pressed setting of the A/C.
Definition: ir_Hitachi.cpp:1194
+
const uint8_t kHitachiAc1Sleep2
Definition: ir_Hitachi.h:178
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Hitachi.cpp:1595
+
const uint8_t kHitachiAc424ButtonTempUp
Definition: ir_Hitachi.h:60
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Hitachi.cpp:1384
+
const uint8_t kHitachiAc1PowerByte
Definition: ir_Hitachi.h:166
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Hitachi.cpp:1059
+
bool getSwingV(void)
Get the current vertical swing setting.
Definition: ir_Hitachi.cpp:1533
+
const uint8_t kHitachiAc1SwingVOffset
Definition: ir_Hitachi.h:171
+
const uint8_t kHitachiAc424ButtonFan
Definition: ir_Hitachi.h:58
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Hitachi.cpp:275
+
const uint8_t kHitachiAcFanAuto
Definition: ir_Hitachi.h:44
+
const uint8_t kHitachiAc1OffTimerHighByte
Definition: ir_Hitachi.h:161
+
const uint8_t kHitachiAc344Dry
Definition: ir_Hitachi.h:88
+
hitachi_ac1_remote_model_t getModel(void)
Get/Detect the model of the A/C.
Definition: ir_Hitachi.cpp:502
+
Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages.
Definition: ir_Hitachi.h:367
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
void setModel(const hitachi_ac1_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_Hitachi.cpp:512
+
const uint8_t kHitachiAc344FanLow
Definition: ir_Hitachi.h:100
+
const uint8_t kHitachiAc424FanMaxDry
Definition: ir_Hitachi.h:98
+
const uint8_t kHitachiAc424FanHigh
Definition: ir_Hitachi.h:95
+
void setSwingToggle(const bool toggle)
Set the Swing toggle setting of the A/C.
Definition: ir_Hitachi.cpp:658
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Hitachi.cpp:527
+
Class for handling detailed Hitachi 104-bit A/C messages.
Definition: ir_Hitachi.h:245
+
const uint8_t kHitachiAc344SwingHLeft
Definition: ir_Hitachi.h:119
+
bool getPowerToggle(void)
Get the value of the current power toggle setting.
Definition: ir_Hitachi.cpp:541
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Hitachi.cpp:1248
+
void on(void)
Change the power setting to On.
Definition: ir_Hitachi.cpp:553
+
const uint8_t kHitachiAc1TempSize
Definition: ir_Hitachi.h:154
+
const uint8_t kHitachiAc1SleepByte
Definition: ir_Hitachi.h:173
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Hitachi.cpp:1234
+
const uint8_t kHitachiAc1FanSize
Definition: ir_Hitachi.h:145
+
const uint8_t kHitachiAcFanMed
Definition: ir_Hitachi.h:46
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Hitachi.cpp:601
+
void on(void)
Change the power setting to On.
Definition: ir_Hitachi.cpp:220
+
const uint8_t kHitachiAc424ModeByte
Definition: ir_Hitachi.h:81
+
uint8_t getMode(void)
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Hitachi.cpp:323
+
const uint8_t kHitachiAc1OnTimerLowByte
Definition: ir_Hitachi.h:163
+
const uint8_t kHitachiAc344SwingHByte
Definition: ir_Hitachi.h:112
+
static bool hasInvertedStates(const uint8_t state[], const uint16_t length)
Check if every second byte of the state, after the fixed header is inverted to the previous byte.
Definition: ir_Hitachi.cpp:1414
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Hitachi.cpp:403
+
const uint16_t kHitachiAc424StateLength
Definition: IRremoteESP8266.h:905
+
uint8_t remote_state[kHitachiAc3StateLength]
The state in native code.
Definition: ir_Hitachi.h:396
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Hitachi.cpp:773
+
void off(void)
Change the power setting to Off.
Definition: ir_Hitachi.cpp:223
+
const uint8_t kHitachiAc1Heat
Definition: ir_Hitachi.h:141
+
const uint8_t kHitachiAc1TempByte
Definition: ir_Hitachi.h:152
+
const uint16_t kHitachiAcFreq
Definition: ir_Hitachi.h:38
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Hitachi.h:325
+
const uint8_t kHitachiAc1SleepOffset
Definition: ir_Hitachi.h:174
+
uint16_t getOffTimer(void)
Get the Off Timer vtime of the A/C.
Definition: ir_Hitachi.cpp:737
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Hitachi.cpp:1126
+
const uint8_t kHitachiAc424TempByte
Definition: ir_Hitachi.h:71
+
uint8_t remote_state[kHitachiAcStateLength]
The state in native code.
Definition: ir_Hitachi.h:238
+
const uint8_t kHitachiAcFanLow
Definition: ir_Hitachi.h:45
+
const uint8_t kHitachiAc344FanMin
Definition: ir_Hitachi.h:99
+
const uint8_t kHitachiAc424FanAuto
Definition: ir_Hitachi.h:96
+
void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:195
+
const uint8_t kHitachiAc1FanMed
Definition: ir_Hitachi.h:148
+
const uint8_t kHitachiAc424FanByte
Definition: ir_Hitachi.h:91
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Hitachi.cpp:533
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Hitachi.cpp:209
+
IRHitachiAc424(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Hitachi.cpp:1018
+
const uint8_t kHitachiAcCool
Definition: ir_Hitachi.h:41
+
const uint8_t kHitachiAc1Sleep4
Definition: ir_Hitachi.h:180
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Hitachi.cpp:1572
+
const uint8_t kHitachiAc1FanOffset
Definition: ir_Hitachi.h:144
+
const uint8_t kHitachiAc1SwingToggleOffset
Definition: ir_Hitachi.h:172
+
void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc1StateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:485
+
const uint8_t kHitachiAcHeat
Definition: ir_Hitachi.h:40
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Hitachi.cpp:1055
+
friend class IRHitachiAc344
Definition: ir_Hitachi.h:314
+
const uint8_t kHitachiAc1FanByte
Definition: ir_Hitachi.h:143
+
const uint8_t kHitachiAc424MaxTemp
Definition: ir_Hitachi.h:75
+
uint8_t remote_state[kHitachiAc1StateLength]
The state in native code.
Definition: ir_Hitachi.h:308
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Hitachi.cpp:375
+
void setInvertedStates(const uint16_t length=kHitachiAc3StateLength)
Invert every second byte of the internal state, after the fixed header.
Definition: ir_Hitachi.cpp:1404
+
const uint16_t kHitachiAc344StateLength
Definition: IRremoteESP8266.h:903
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Hitachi.h:232
+
const uint8_t kHitachiAc1SwingHOffset
Definition: ir_Hitachi.h:170
+
void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Hitachi.cpp:202
+
const uint8_t kHitachiAc424FanTemp
Definition: ir_Hitachi.h:78
+
const uint8_t kHitachiAc1Cool
Definition: ir_Hitachi.h:140
+
uint8_t remote_state[kHitachiAc424StateLength]
The state in native code.
Definition: ir_Hitachi.h:360
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Hitachi.cpp:613
+
uint8_t _previoustemp
Definition: ir_Hitachi.h:240
+
const uint8_t kHitachiAc1FanAuto
Definition: ir_Hitachi.h:146
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Hitachi.cpp:157
+
const uint8_t kHitachiAc424TempOffset
Definition: ir_Hitachi.h:72
+
const uint8_t kHitachiAc1ModelByte
Definition: ir_Hitachi.h:128
+
const uint8_t kHitachiAc424PowerOff
Definition: ir_Hitachi.h:109
+
const uint8_t kHitachiAc1PowerToggleOffset
Definition: ir_Hitachi.h:168
+
const uint8_t kHitachiAc424FanMin
Definition: ir_Hitachi.h:92
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Hitachi.cpp:1101
+
virtual void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Hitachi.cpp:1024
+
const uint8_t kHitachiAc344FanMax
Definition: ir_Hitachi.h:104
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Hitachi.h:302
+
const uint8_t kHitachiAc1ModelOffset
Definition: ir_Hitachi.h:129
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Hitachi.cpp:249
+
const uint8_t kHitachiAc424Dry
Definition: ir_Hitachi.h:84
+
void setSwingH(const uint8_t position)
Control the horizontal swing setting.
Definition: ir_Hitachi.cpp:1540
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Hitachi.cpp:567
+
const uint16_t kHitachiAcDefaultRepeat
Definition: IRremoteESP8266.h:894
+
const uint8_t kHitachiAc424PowerOn
Definition: ir_Hitachi.h:108
+
const uint8_t kHitachiAc344SwingVByte
Definition: ir_Hitachi.h:123
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Hitachi.cpp:1343
+
const uint8_t kHitachiAc344SwingHMiddle
Definition: ir_Hitachi.h:118
+
void checksum(const uint16_t length=kHitachiAcStateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Hitachi.cpp:172
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Hitachi.cpp:1221
+
uint16_t getOnTimer(void)
Get the On Timer vtime of the A/C.
Definition: ir_Hitachi.cpp:721
+
void setFan(const uint8_t speed, const bool force=false)
Set the speed of the fan.
Definition: ir_Hitachi.cpp:621
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Hitachi.cpp:759
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Hitachi.cpp:825
+
void setSwingV(const bool on)
Set the Vertical Swing setting of the A/C.
Definition: ir_Hitachi.cpp:671
+
const uint8_t kHitachiAc1SwingByte
Definition: ir_Hitachi.h:169
+
const uint8_t kHitachiAc1ModeByte
Definition: ir_Hitachi.h:135
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kHitachiAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Hitachi.cpp:180
+
const uint8_t kHitachiAc424FanMedium
Definition: ir_Hitachi.h:94
+
const uint8_t kHitachiAc344ButtonTempUp
Definition: ir_Hitachi.h:66
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Hitachi.cpp:350
+
const uint8_t kHitachiAc424Cool
Definition: ir_Hitachi.h:83
+
void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc3StateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:1434
+
const uint8_t kHitachiAcFan
Definition: ir_Hitachi.h:43
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Hitachi.cpp:1426
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Hitachi.cpp:797
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Hitachi.cpp:442
+
const uint8_t kHitachiAc1OnTimerHighByte
Definition: ir_Hitachi.h:164
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Hitachi.cpp:187
+
void setOffTimer(const uint16_t mins)
Set the Off Timer time.
Definition: ir_Hitachi.cpp:729
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Hitachi.cpp:786
+
virtual void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Hitachi.cpp:1074
+
const uint8_t kHitachiAc344ButtonSwingH
Definition: ir_Hitachi.h:68
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Hitachi.cpp:215
+
virtual void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc424StateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:1067
+
const uint8_t kHitachiAc424FanLow
Definition: ir_Hitachi.h:93
+
const uint8_t kHitachiAcAutoTemp
Definition: ir_Hitachi.h:50
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Hitachi.h:199
+
void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc344StateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:1520
+
const uint8_t kHitachiAc344FanMedium
Definition: ir_Hitachi.h:101
+
const uint8_t kHitachiAc1Dry
Definition: ir_Hitachi.h:138
+
bool getSwingH(void)
Get the Horizontal Swing setting of the A/C.
Definition: ir_Hitachi.cpp:677
+
bool getSwingHorizontal(void)
Get the Horizontal Swing setting of the A/C.
Definition: ir_Hitachi.cpp:310
+
const uint8_t kHitachiAc344Cool
Definition: ir_Hitachi.h:87
+
const uint8_t kHitachiAc424FanMax
Definition: ir_Hitachi.h:97
+
const uint8_t kHitachiAc424Heat
Definition: ir_Hitachi.h:85
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Hitachi.cpp:1261
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Hitachi.cpp:231
+
const uint8_t kHitachiAc1ModelSize
Definition: ir_Hitachi.h:132
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kHitachiAc344ButtonTempDown
Definition: ir_Hitachi.h:65
+
const uint8_t kHitachiAc424ButtonPowerMode
Definition: ir_Hitachi.h:57
+
const uint8_t kHitachiAc1TempAuto
Definition: ir_Hitachi.h:156
+
const uint8_t kHitachiAc1OffTimerLowByte
Definition: ir_Hitachi.h:160
+
const uint8_t kHitachiAc344MinTemp
Definition: ir_Hitachi.h:76
+
const uint8_t kHitachiAc1TempDelta
Definition: ir_Hitachi.h:155
+
void on(void)
Change the power setting to On.
Definition: ir_Hitachi.cpp:1094
+
const uint8_t kHitachiAcSwingOffset
Definition: ir_Hitachi.h:52
+
void off(void)
Change the power setting to Off.
Definition: ir_Hitachi.cpp:556
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Hitachi.cpp:1081
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Hitachi.cpp:477
+
const uint8_t kHitachiAc344ButtonSwingV
Definition: ir_Hitachi.h:67
+
const uint8_t kHitachiAc1SleepOff
Definition: ir_Hitachi.h:176
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Hitachi.cpp:255
+
virtual stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Hitachi.cpp:1274
+
uint8_t getSwingH(void)
Get the current horizontal swing setting.
Definition: ir_Hitachi.cpp:1550
+
String _toString(void)
Convert the internal state into a human readable string for the settings that are common to protocols...
Definition: ir_Hitachi.cpp:1302
+
bool getSwingVToggle(void)
Get the Vertical Swing toggle setting of the A/C.
Definition: ir_Hitachi.cpp:1214
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Inax_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Inax_8cpp.html new file mode 100644 index 000000000..5e5f3eaf4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Inax_8cpp.html @@ -0,0 +1,207 @@ + + + + + + + +IRremoteESP8266: src/ir_Inax.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Inax.cpp File Reference
+
+
+ +

Support for the Inax Robot Toilet IR protocols. +More...

+ + + + + + + + + + + + + + + + +

+Variables

const uint16_t kInaxTick = 500
 
const uint16_t kInaxHdrMark = 9000
 
const uint16_t kInaxHdrSpace = 4500
 
const uint16_t kInaxBitMark = 560
 
const uint16_t kInaxOneSpace = 1675
 
const uint16_t kInaxZeroSpace = kInaxBitMark
 
const uint16_t kInaxMinGap = 40000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kInaxBitMark

+ +
+
+ + + + +
const uint16_t kInaxBitMark = 560
+
+ +
+
+ +

◆ kInaxHdrMark

+ +
+
+ + + + +
const uint16_t kInaxHdrMark = 9000
+
+ +
+
+ +

◆ kInaxHdrSpace

+ +
+
+ + + + +
const uint16_t kInaxHdrSpace = 4500
+
+ +
+
+ +

◆ kInaxMinGap

+ +
+
+ + + + +
const uint16_t kInaxMinGap = 40000
+
+ +
+
+ +

◆ kInaxOneSpace

+ +
+
+ + + + +
const uint16_t kInaxOneSpace = 1675
+
+ +
+
+ +

◆ kInaxTick

+ +
+
+ + + + +
const uint16_t kInaxTick = 500
+
+ +
+
+ +

◆ kInaxZeroSpace

+ +
+
+ + + + +
const uint16_t kInaxZeroSpace = kInaxBitMark
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__JVC_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__JVC_8cpp.html new file mode 100644 index 000000000..0392fa940 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__JVC_8cpp.html @@ -0,0 +1,343 @@ + + + + + + + +IRremoteESP8266: src/ir_JVC.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_JVC.cpp File Reference
+
+
+ +

Support for JVC protocols. Originally added by Kristian Lauszus Thanks to zenwheel and other people at the original blog post. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kJvcTick = 75
 
const uint16_t kJvcHdrMarkTicks = 112
 
const uint16_t kJvcHdrMark = kJvcHdrMarkTicks * kJvcTick
 
const uint16_t kJvcHdrSpaceTicks = 56
 
const uint16_t kJvcHdrSpace = kJvcHdrSpaceTicks * kJvcTick
 
const uint16_t kJvcBitMarkTicks = 7
 
const uint16_t kJvcBitMark = kJvcBitMarkTicks * kJvcTick
 
const uint16_t kJvcOneSpaceTicks = 23
 
const uint16_t kJvcOneSpace = kJvcOneSpaceTicks * kJvcTick
 
const uint16_t kJvcZeroSpaceTicks = 7
 
const uint16_t kJvcZeroSpace = kJvcZeroSpaceTicks * kJvcTick
 
const uint16_t kJvcRptLengthTicks = 800
 
const uint16_t kJvcRptLength = kJvcRptLengthTicks * kJvcTick
 
const uint16_t kJvcMinGapTicks
 
const uint16_t kJvcMinGap = kJvcMinGapTicks * kJvcTick
 
+

Detailed Description

+

Support for JVC protocols. Originally added by Kristian Lauszus Thanks to zenwheel and other people at the original blog post.

+
See also
http://www.sbprojects.com/knowledge/ir/jvc.php
+

Variable Documentation

+ +

◆ kJvcBitMark

+ +
+
+ + + + +
const uint16_t kJvcBitMark = kJvcBitMarkTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcBitMarkTicks

+ +
+
+ + + + +
const uint16_t kJvcBitMarkTicks = 7
+
+ +
+
+ +

◆ kJvcHdrMark

+ +
+
+ + + + +
const uint16_t kJvcHdrMark = kJvcHdrMarkTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kJvcHdrMarkTicks = 112
+
+ +
+
+ +

◆ kJvcHdrSpace

+ +
+
+ + + + +
const uint16_t kJvcHdrSpace = kJvcHdrSpaceTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kJvcHdrSpaceTicks = 56
+
+ +
+
+ +

◆ kJvcMinGap

+ +
+
+ + + + +
const uint16_t kJvcMinGap = kJvcMinGapTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcMinGapTicks

+ +
+
+ + + + +
const uint16_t kJvcMinGapTicks
+
+
+ +

◆ kJvcOneSpace

+ +
+
+ + + + +
const uint16_t kJvcOneSpace = kJvcOneSpaceTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kJvcOneSpaceTicks = 23
+
+ +
+
+ +

◆ kJvcRptLength

+ +
+
+ + + + +
const uint16_t kJvcRptLength = kJvcRptLengthTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcRptLengthTicks

+ +
+
+ + + + +
const uint16_t kJvcRptLengthTicks = 800
+
+ +
+
+ +

◆ kJvcTick

+ +
+
+ + + + +
const uint16_t kJvcTick = 75
+
+ +
+
+ +

◆ kJvcZeroSpace

+ +
+
+ + + + +
const uint16_t kJvcZeroSpace = kJvcZeroSpaceTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kJvcZeroSpaceTicks = 7
+
+ +
+
+
+
const uint16_t kJvcHdrSpaceTicks
Definition: ir_JVC.cpp:23
+
const uint16_t kJvcBitMarkTicks
Definition: ir_JVC.cpp:25
+
const uint16_t kJvcBits
Definition: IRremoteESP8266.h:909
+
const uint16_t kJvcOneSpaceTicks
Definition: ir_JVC.cpp:27
+
const uint16_t kJvcHdrMarkTicks
Definition: ir_JVC.cpp:21
+
const uint16_t kJvcRptLengthTicks
Definition: ir_JVC.cpp:31
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8cpp.html new file mode 100644 index 000000000..2fabc1753 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8cpp.html @@ -0,0 +1,569 @@ + + + + + + + +IRremoteESP8266: src/ir_Kelvinator.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Kelvinator.cpp File Reference
+
+
+ +

Support for Kelvinator A/C protocols. Code to emulate IR Kelvinator YALIF remote control unit, which should control at least the following Kelvinator A/C units: KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, KSV70HRC, KSV80HRC. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kKelvinatorTick = 85
 
const uint16_t kKelvinatorHdrMarkTicks = 106
 
const uint16_t kKelvinatorHdrMark = kKelvinatorHdrMarkTicks * kKelvinatorTick
 
const uint16_t kKelvinatorHdrSpaceTicks = 53
 
const uint16_t kKelvinatorHdrSpace = kKelvinatorHdrSpaceTicks * kKelvinatorTick
 
const uint16_t kKelvinatorBitMarkTicks = 8
 
const uint16_t kKelvinatorBitMark = kKelvinatorBitMarkTicks * kKelvinatorTick
 
const uint16_t kKelvinatorOneSpaceTicks = 18
 
const uint16_t kKelvinatorOneSpace = kKelvinatorOneSpaceTicks * kKelvinatorTick
 
const uint16_t kKelvinatorZeroSpaceTicks = 6
 
const uint16_t kKelvinatorZeroSpace
 
const uint16_t kKelvinatorGapSpaceTicks = 235
 
const uint16_t kKelvinatorGapSpace = kKelvinatorGapSpaceTicks * kKelvinatorTick
 
const uint8_t kKelvinatorCmdFooter = 2
 
const uint8_t kKelvinatorCmdFooterBits = 3
 
const uint8_t kKelvinatorModeOffset = 0
 
const uint8_t kKelvinatorPowerOffset = 3
 
const uint8_t kKelvinatorFanOffset = 4
 
const uint8_t kKelvinatorFanSize = 3
 
const uint8_t kKelvinatorBasicFanSize = 2
 
const uint8_t kKelvinatorChecksumStart = 10
 
const uint8_t kKelvinatorVentSwingOffset = 6
 
const uint8_t kKelvinatorVentSwingVOffset = 0
 
const uint8_t kKelvinatorVentSwingHOffset = 4
 
const uint8_t kKelvinatorQuietOffset = 7
 
const uint8_t kKelvinatorIonFilterOffset = 6
 
const uint8_t kKelvinatorLightOffset = 5
 
const uint8_t kKelvinatorXfanOffset = 7
 
const uint8_t kKelvinatorTurboOffset = 4
 
+

Detailed Description

+

Support for Kelvinator A/C protocols. Code to emulate IR Kelvinator YALIF remote control unit, which should control at least the following Kelvinator A/C units: KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, KSV70HRC, KSV80HRC.

+
Note
Unsupported:
    +
  • All Sleep modes.
  • +
  • All Timer modes.
  • +
  • "I Feel" button & mode.
  • +
  • Energy Saving mode.
  • +
  • Low Heat mode.
  • +
  • Fahrenheit.
  • +
+
+

Variable Documentation

+ +

◆ kKelvinatorBasicFanSize

+ +
+
+ + + + +
const uint8_t kKelvinatorBasicFanSize = 2
+
+ +
+
+ +

◆ kKelvinatorBitMark

+ +
+
+ + + + +
const uint16_t kKelvinatorBitMark = kKelvinatorBitMarkTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorBitMarkTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorBitMarkTicks = 8
+
+ +
+
+ +

◆ kKelvinatorChecksumStart

+ +
+
+ + + + +
const uint8_t kKelvinatorChecksumStart = 10
+
+ +
+
+ +

◆ kKelvinatorCmdFooter

+ +
+
+ + + + +
const uint8_t kKelvinatorCmdFooter = 2
+
+ +
+
+ +

◆ kKelvinatorCmdFooterBits

+ +
+
+ + + + +
const uint8_t kKelvinatorCmdFooterBits = 3
+
+ +
+
+ +

◆ kKelvinatorFanOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorFanOffset = 4
+
+ +
+
+ +

◆ kKelvinatorFanSize

+ +
+
+ + + + +
const uint8_t kKelvinatorFanSize = 3
+
+ +
+
+ +

◆ kKelvinatorGapSpace

+ +
+
+ + + + +
const uint16_t kKelvinatorGapSpace = kKelvinatorGapSpaceTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorGapSpaceTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorGapSpaceTicks = 235
+
+ +
+
+ +

◆ kKelvinatorHdrMark

+ +
+
+ + + + +
const uint16_t kKelvinatorHdrMark = kKelvinatorHdrMarkTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorHdrMarkTicks = 106
+
+ +
+
+ +

◆ kKelvinatorHdrSpace

+ +
+
+ + + + +
const uint16_t kKelvinatorHdrSpace = kKelvinatorHdrSpaceTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorHdrSpaceTicks = 53
+
+ +
+
+ +

◆ kKelvinatorIonFilterOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorIonFilterOffset = 6
+
+ +
+
+ +

◆ kKelvinatorLightOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorLightOffset = 5
+
+ +
+
+ +

◆ kKelvinatorModeOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorModeOffset = 0
+
+ +
+
+ +

◆ kKelvinatorOneSpace

+ +
+
+ + + + +
const uint16_t kKelvinatorOneSpace = kKelvinatorOneSpaceTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorOneSpaceTicks = 18
+
+ +
+
+ +

◆ kKelvinatorPowerOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorPowerOffset = 3
+
+ +
+
+ +

◆ kKelvinatorQuietOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorQuietOffset = 7
+
+ +
+
+ +

◆ kKelvinatorTick

+ +
+
+ + + + +
const uint16_t kKelvinatorTick = 85
+
+ +
+
+ +

◆ kKelvinatorTurboOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorTurboOffset = 4
+
+ +
+
+ +

◆ kKelvinatorVentSwingHOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorVentSwingHOffset = 4
+
+ +
+
+ +

◆ kKelvinatorVentSwingOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorVentSwingOffset = 6
+
+ +
+
+ +

◆ kKelvinatorVentSwingVOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorVentSwingVOffset = 0
+
+ +
+
+ +

◆ kKelvinatorXfanOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorXfanOffset = 7
+
+ +
+
+ +

◆ kKelvinatorZeroSpace

+ +
+
+ + + + +
const uint16_t kKelvinatorZeroSpace
+
+Initial value: +
+
+ +

◆ kKelvinatorZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorZeroSpaceTicks = 6
+
+ +
+
+
+
const uint16_t kKelvinatorZeroSpaceTicks
Definition: ir_Kelvinator.cpp:39
+
const uint16_t kKelvinatorTick
Definition: ir_Kelvinator.cpp:30
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h.html new file mode 100644 index 000000000..3feaa32f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h.html @@ -0,0 +1,293 @@ + + + + + + + +IRremoteESP8266: src/ir_Kelvinator.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Kelvinator.h File Reference
+
+
+ +

Support for Kelvinator A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRKelvinatorAC
 Class for handling detailed Kelvinator A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kKelvinatorAuto = 0
 
const uint8_t kKelvinatorCool = 1
 
const uint8_t kKelvinatorDry = 2
 
const uint8_t kKelvinatorFan = 3
 
const uint8_t kKelvinatorHeat = 4
 
const uint8_t kKelvinatorBasicFanMax = 3
 
const uint8_t kKelvinatorFanAuto = 0
 
const uint8_t kKelvinatorFanMin = 1
 
const uint8_t kKelvinatorFanMax = 5
 
const uint8_t kKelvinatorMinTemp = 16
 
const uint8_t kKelvinatorMaxTemp = 30
 
const uint8_t kKelvinatorAutoTemp = 25
 
+

Detailed Description

+

Support for Kelvinator A/C protocols.

+

Variable Documentation

+ +

◆ kKelvinatorAuto

+ +
+
+ + + + +
const uint8_t kKelvinatorAuto = 0
+
+ +
+
+ +

◆ kKelvinatorAutoTemp

+ +
+
+ + + + +
const uint8_t kKelvinatorAutoTemp = 25
+
+ +
+
+ +

◆ kKelvinatorBasicFanMax

+ +
+
+ + + + +
const uint8_t kKelvinatorBasicFanMax = 3
+
+ +
+
+ +

◆ kKelvinatorCool

+ +
+
+ + + + +
const uint8_t kKelvinatorCool = 1
+
+ +
+
+ +

◆ kKelvinatorDry

+ +
+
+ + + + +
const uint8_t kKelvinatorDry = 2
+
+ +
+
+ +

◆ kKelvinatorFan

+ +
+
+ + + + +
const uint8_t kKelvinatorFan = 3
+
+ +
+
+ +

◆ kKelvinatorFanAuto

+ +
+
+ + + + +
const uint8_t kKelvinatorFanAuto = 0
+
+ +
+
+ +

◆ kKelvinatorFanMax

+ +
+
+ + + + +
const uint8_t kKelvinatorFanMax = 5
+
+ +
+
+ +

◆ kKelvinatorFanMin

+ +
+
+ + + + +
const uint8_t kKelvinatorFanMin = 1
+
+ +
+
+ +

◆ kKelvinatorHeat

+ +
+
+ + + + +
const uint8_t kKelvinatorHeat = 4
+
+ +
+
+ +

◆ kKelvinatorMaxTemp

+ +
+
+ + + + +
const uint8_t kKelvinatorMaxTemp = 30
+
+ +
+
+ +

◆ kKelvinatorMinTemp

+ +
+
+ + + + +
const uint8_t kKelvinatorMinTemp = 16
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h_source.html new file mode 100644 index 000000000..16ffcfeef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h_source.html @@ -0,0 +1,336 @@ + + + + + + + +IRremoteESP8266: src/ir_Kelvinator.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Kelvinator.h
+
+
+Go to the documentation of this file.
1 // Copyright 2016 David Conran
+
4 
+
5 // Supports:
+
6 // Brand: Kelvinator, Model: YALIF Remote
+
7 // Brand: Kelvinator, Model: KSV26CRC A/C
+
8 // Brand: Kelvinator, Model: KSV26HRC A/C
+
9 // Brand: Kelvinator, Model: KSV35CRC A/C
+
10 // Brand: Kelvinator, Model: KSV35HRC A/C
+
11 // Brand: Kelvinator, Model: KSV53HRC A/C
+
12 // Brand: Kelvinator, Model: KSV62HRC A/C
+
13 // Brand: Kelvinator, Model: KSV70CRC A/C
+
14 // Brand: Kelvinator, Model: KSV70HRC A/C
+
15 // Brand: Kelvinator, Model: KSV80HRC A/C
+
16 // Brand: Green, Model: YAPOF3 remote
+
17 
+
18 #ifndef IR_KELVINATOR_H_
+
19 #define IR_KELVINATOR_H_
+
20 
+
21 #define __STDC_LIMIT_MACROS
+
22 #include <stdint.h>
+
23 #ifndef UNIT_TEST
+
24 #include <Arduino.h>
+
25 #endif
+
26 #include "IRremoteESP8266.h"
+
27 #include "IRsend.h"
+
28 #ifdef UNIT_TEST
+
29 #include "IRsend_test.h"
+
30 #endif
+
31 
+
32 // Constants
+
33 const uint8_t kKelvinatorAuto = 0;
+
34 const uint8_t kKelvinatorCool = 1;
+
35 const uint8_t kKelvinatorDry = 2;
+
36 const uint8_t kKelvinatorFan = 3;
+
37 const uint8_t kKelvinatorHeat = 4;
+
38 const uint8_t kKelvinatorBasicFanMax = 3;
+
39 const uint8_t kKelvinatorFanAuto = 0;
+
40 const uint8_t kKelvinatorFanMin = 1;
+
41 const uint8_t kKelvinatorFanMax = 5;
+
42 const uint8_t kKelvinatorMinTemp = 16; // 16C
+
43 const uint8_t kKelvinatorMaxTemp = 30; // 30C
+
44 const uint8_t kKelvinatorAutoTemp = 25; // 25C
+
45 
+
46 // Legacy defines (Deprecated)
+
47 #define KELVINATOR_MIN_TEMP kKelvinatorMinTemp
+
48 #define KELVINATOR_MAX_TEMP kKelvinatorMaxTemp
+
49 #define KELVINATOR_HEAT kKelvinatorHeat
+
50 #define KELVINATOR_FAN_MAX kKelvinatorFanMax
+
51 #define KELVINATOR_FAN_AUTO kKelvinatorFanAuto
+
52 #define KELVINATOR_FAN kKelvinatorFan
+
53 #define KELVINATOR_DRY kKelvinatorDry
+
54 #define KELVINATOR_COOL kKelvinatorCool
+
55 #define KELVINATOR_BASIC_FAN_MAX kKelvinatorBasicFanMax
+
56 #define KELVINATOR_AUTO_TEMP kKelvinatorAutoTemp
+
57 #define KELVINATOR_AUTO kKelvinatorAuto
+
58 
+
59 /*
+
60  Kelvinator AC map
+
61 
+
62  (header mark and space)
+
63  byte 0 = Basic Modes
+
64  b2-0 = Modes
+
65  Modes:
+
66  000 = Auto (temp = 25C)
+
67  001 = Cool
+
68  010 = Dry (temp = 25C, but not shown)
+
69  011 = Fan
+
70  100 = Heat
+
71  b3 = Power Status (1 = On, 0 = Off)
+
72  b5-4 = Fan (Basic modes)
+
73  Fan:
+
74  00 = Auto
+
75  01 = Fan 1
+
76  10 = Fan 2
+
77  11 = Fan 3 or higher (See byte 14)
+
78  b6 = Vent swing (1 = On, 0 = Off) (See byte 4)
+
79  b7 = Sleep Modes 1 & 3 (1 = On, 0 = Off)
+
80  byte 1 = Temperature
+
81  b3-0: Degrees C.
+
82  0000 (0) = 16C
+
83  0001 (1) = 17C
+
84  0010 (2) = 18C
+
85  ...
+
86  1101 (13) = 29C
+
87  1110 (14) = 30C
+
88  byte 2 = Extras
+
89  b3-0 = UNKNOWN, typically 0.
+
90  b4 = Turbo Fan (1 = On, 0 = Off)
+
91  b5 = Light (Display) (1 = On, 0 = Off)
+
92  b6 = Ion Filter (1 = On, 0 = Off)
+
93  b7 = X-Fan (Fan runs for a while after power off) (1 = On, 0 = Off)
+
94  byte 3 = Section Indicator
+
95  b3-0 = Unused (Typically 0)
+
96  b5-4 = Unknown (possibly timer related) (Typically 0b01)
+
97  b7-6 = End of command block (B01)
+
98  (B010 marker and a gap of 20ms)
+
99  byte 4 = Extended options
+
100  b0 = Swing Vent Vertical (1 = On, 0 = Off)
+
101  b4 = Swing Vent Horizontal (1 = On, 0 = Off)
+
102  byte 5-6 = Timer related. Typically 0 except when timer in use.
+
103  byte 7 = checksum
+
104  b3-0 = Unknown (Used in Timer mode)
+
105  b7-4 = checksum of the previous bytes (0-6)
+
106  (gap of 40ms)
+
107  (header mark and space)
+
108  byte 8 = Repeat of byte 0
+
109  byte 9 = Repeat of byte 1
+
110  byte 10 = Repeat of byte 2
+
111  byte 11 = Section Indicator
+
112  b3-0 = Unused (Typically 0)
+
113  b5-4 = Unknown (possibly timer related) (Typically 0b11)
+
114  b7-6 = End of command block (B01)
+
115  (B010 marker and a gap of 20ms)
+
116  byte 12 = Extended options
+
117  b0 = Sleep mode 2 (1 = On, 0=Off)
+
118  b6-1 = Unknown (Used in Sleep Mode 3, Typically 0b000000)
+
119  b7 = Quiet Mode (1 = On, 0=Off)
+
120  byte 13 = Unknown (Sleep Mode 3 related, Typically 0x00)
+
121  byte 14 = Fan control
+
122  b3-0 = Unknown (Sleep Mode 3 related, Typically 0b0000)
+
123  b6-4 = Fan speed
+
124  0b000 (0) = Automatic
+
125  0b001 (1) = Fan 1
+
126  0b010 (2) = Fan 2
+
127  0b011 (3) = Fan 3
+
128  0b100 (4) = Fan 4
+
129  0b101 (5) = Fan 5
+
130  byte 15 = checksum
+
131  b3-0 = Unknown (Typically 0b0000)
+
132  b7-4 = checksum of the previous bytes (8-14)
+
133 */
+
134 
+
135 // Classes
+ +
138  public:
+
139  explicit IRKelvinatorAC(const uint16_t pin, const bool inverted = false,
+
140  const bool use_modulation = true);
+
141  void stateReset(void);
+
142 #if SEND_KELVINATOR
+
143  void send(const uint16_t repeat = kKelvinatorDefaultRepeat);
+
148  int8_t calibrate(void) { return _irsend.calibrate(); }
+
149 #endif // SEND_KELVINATOR
+
150  void begin(void);
+
151  void on(void);
+
152  void off(void);
+
153  void setPower(const bool on);
+
154  bool getPower(void);
+
155  void setTemp(const uint8_t degrees);
+
156  uint8_t getTemp(void);
+
157  void setFan(const uint8_t speed);
+
158  uint8_t getFan(void);
+
159  void setMode(const uint8_t mode);
+
160  uint8_t getMode(void);
+
161  void setSwingVertical(const bool on);
+
162  bool getSwingVertical(void);
+
163  void setSwingHorizontal(const bool on);
+
164  bool getSwingHorizontal(void);
+
165  void setQuiet(const bool on);
+
166  bool getQuiet(void);
+
167  void setIonFilter(const bool on);
+
168  bool getIonFilter(void);
+
169  void setLight(const bool on);
+
170  bool getLight(void);
+
171  void setXFan(const bool on);
+
172  bool getXFan(void);
+
173  void setTurbo(const bool on);
+
174  bool getTurbo(void);
+
175  uint8_t* getRaw(void);
+
176  void setRaw(const uint8_t new_code[]);
+
177  static uint8_t calcBlockChecksum(
+
178  const uint8_t* block, const uint16_t length = kKelvinatorStateLength / 2);
+
179  static bool validChecksum(const uint8_t state[],
+
180  const uint16_t length = kKelvinatorStateLength);
+
181  uint8_t convertMode(const stdAc::opmode_t mode);
+
182  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
183  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
184  stdAc::state_t toCommon(void);
+
185  String toString(void);
+
186 #ifndef UNIT_TEST
+
187 
+
188  private:
+ +
190 #else // UNIT_TEST
+
191  IRsendTest _irsend;
+
193 #endif // UNIT_TEST
+ +
196  void checksum(const uint16_t length = kKelvinatorStateLength);
+
197  void fixup(void);
+
198 };
+
199 
+
200 #endif // IR_KELVINATOR_H_
+
+
void setSwingHorizontal(const bool on)
Control the current horizontal swing setting.
Definition: ir_Kelvinator.cpp:314
+
void stateReset(void)
Reset the internals of the object to a known good state.
Definition: ir_Kelvinator.cpp:129
+
void checksum(const uint16_t length=kKelvinatorStateLength)
Calculate the checksum for the internal state.
Definition: ir_Kelvinator.cpp:188
+
bool getTurbo(void)
Is the Turbo setting on?
Definition: ir_Kelvinator.cpp:392
+
void setTurbo(const bool on)
Control the current Turbo setting.
Definition: ir_Kelvinator.cpp:385
+
bool getSwingVertical(void)
Is the vertical swing setting on?
Definition: ir_Kelvinator.cpp:308
+
const uint8_t kKelvinatorFanAuto
Definition: ir_Kelvinator.h:39
+
void on(void)
Set the internal state to have the power on.
Definition: ir_Kelvinator.cpp:212
+
const uint8_t kKelvinatorFanMax
Definition: ir_Kelvinator.h:41
+
const uint8_t kKelvinatorCool
Definition: ir_Kelvinator.h:34
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
void setLight(const bool on)
Control the current Light setting. i.e. The LED display on the A/C unit that shows the basic settings...
Definition: ir_Kelvinator.cpp:355
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed to it's stdAc::fanspeed_t equivalent.
Definition: ir_Kelvinator.cpp:425
+
const uint8_t kKelvinatorAutoTemp
Definition: ir_Kelvinator.h:44
+
uint8_t * getRaw(void)
Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.
Definition: ir_Kelvinator.cpp:158
+ +
void setIonFilter(const bool on)
Control the current Ion Filter setting.
Definition: ir_Kelvinator.cpp:341
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Kelvinator.cpp:248
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kKelvinatorMinTemp
Definition: ir_Kelvinator.h:42
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Kelvinator.h:148
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void setPower(const bool on)
Set the internal state to have the desired power.
Definition: ir_Kelvinator.cpp:219
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Kelvinator.cpp:266
+
void setMode(const uint8_t mode)
Set the desired operation mode.
Definition: ir_Kelvinator.cpp:278
+
void send(const uint16_t repeat=kKelvinatorDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Kelvinator.cpp:149
+
void setRaw(const uint8_t new_code[])
Set the raw state of the object.
Definition: ir_Kelvinator.cpp:165
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Kelvinator.cpp:136
+
uint8_t getMode(void)
Get the current operation mode setting.
Definition: ir_Kelvinator.cpp:272
+
static uint8_t calcBlockChecksum(const uint8_t *block, const uint16_t length=kKelvinatorStateLength/2)
Calculate the checksum for a given block of state.
Definition: ir_Kelvinator.cpp:174
+ +
IRsend _irsend
Instance of the IR send class.
Definition: ir_Kelvinator.h:189
+
bool getPower(void)
Get the power setting from the internal state.
Definition: ir_Kelvinator.cpp:226
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kKelvinatorStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Kelvinator.cpp:200
+
Class for handling detailed Kelvinator A/C messages.
Definition: ir_Kelvinator.h:137
+
const uint8_t kKelvinatorMaxTemp
Definition: ir_Kelvinator.h:43
+
void fixup(void)
Fix up any odd conditions for the current state.
Definition: ir_Kelvinator.cpp:139
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Kelvinator.cpp:241
+
const uint16_t kKelvinatorStateLength
Definition: IRremoteESP8266.h:910
+
stdAc::state_t toCommon(void)
Convert the internal A/C object state to it's stdAc::state_t equivalent.
Definition: ir_Kelvinator.cpp:431
+
void setQuiet(const bool on)
Control the current Quiet setting.
Definition: ir_Kelvinator.cpp:329
+
void setXFan(const bool on)
Control the current XFan setting. This setting will cause the unit blow air after power off to dry ou...
Definition: ir_Kelvinator.cpp:371
+
const uint8_t kKelvinatorFan
Definition: ir_Kelvinator.h:36
+
void setTemp(const uint8_t degrees)
Set the temperature setting.
Definition: ir_Kelvinator.cpp:232
+
const uint8_t kKelvinatorBasicFanMax
Definition: ir_Kelvinator.h:38
+
const uint8_t kKelvinatorFanMin
Definition: ir_Kelvinator.h:40
+
bool getLight(void)
Is the Light (Display) setting on?
Definition: ir_Kelvinator.cpp:362
+
const uint8_t kKelvinatorHeat
Definition: ir_Kelvinator.h:37
+
IRKelvinatorAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Kelvinator.cpp:124
+
void off(void)
Set the internal state to have the power off.
Definition: ir_Kelvinator.cpp:215
+
const uint16_t kKelvinatorDefaultRepeat
Definition: IRremoteESP8266.h:912
+
uint8_t remote_state[kKelvinatorStateLength]
The state in IR code form.
Definition: ir_Kelvinator.h:195
+
void setSwingVertical(const bool on)
Control the current vertical swing setting.
Definition: ir_Kelvinator.cpp:299
+
const uint8_t kKelvinatorDry
Definition: ir_Kelvinator.h:35
+
bool getIonFilter(void)
Is the Ion Filter setting on?
Definition: ir_Kelvinator.cpp:348
+
String toString(void)
Convert the internal settings into a human readable string.
Definition: ir_Kelvinator.cpp:459
+
bool getXFan(void)
Is the XFan setting on?
Definition: ir_Kelvinator.cpp:378
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode to it's stdAc::opmode_t equivalent.
Definition: ir_Kelvinator.cpp:412
+
bool getQuiet(void)
Is the Quiet setting on?
Definition: ir_Kelvinator.cpp:335
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
bool getSwingHorizontal(void)
Is the horizontal swing setting on?
Definition: ir_Kelvinator.cpp:323
+
const uint8_t kKelvinatorAuto
Definition: ir_Kelvinator.h:33
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a standard A/C mode (stdAc::opmode_t) into it a native mode.
Definition: ir_Kelvinator.cpp:399
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8cpp.html new file mode 100644 index 000000000..3613112d7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8cpp.html @@ -0,0 +1,557 @@ + + + + + + + +IRremoteESP8266: src/ir_LG.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_LG.cpp File Reference
+
+
+ +

Support for LG protocols. LG decode originally added by Darryl Smith (based on the JVC protocol) LG send originally added by https://github.com/chaeplin. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kLgTick = 50
 
const uint16_t kLgHdrMarkTicks = 170
 
const uint16_t kLgHdrMark = kLgHdrMarkTicks * kLgTick
 
const uint16_t kLgHdrSpaceTicks = 85
 
const uint16_t kLgHdrSpace = kLgHdrSpaceTicks * kLgTick
 
const uint16_t kLgBitMarkTicks = 11
 
const uint16_t kLgBitMark = kLgBitMarkTicks * kLgTick
 
const uint16_t kLgOneSpaceTicks = 32
 
const uint16_t kLgOneSpace = kLgOneSpaceTicks * kLgTick
 
const uint16_t kLgZeroSpaceTicks = 11
 
const uint16_t kLgZeroSpace = kLgZeroSpaceTicks * kLgTick
 
const uint16_t kLgRptSpaceTicks = 45
 
const uint16_t kLgRptSpace = kLgRptSpaceTicks * kLgTick
 
const uint16_t kLgMinGapTicks = 795
 
const uint16_t kLgMinGap = kLgMinGapTicks * kLgTick
 
const uint16_t kLgMinMessageLengthTicks = 2161
 
const uint32_t kLgMinMessageLength = kLgMinMessageLengthTicks * kLgTick
 
const uint16_t kLg32HdrMarkTicks = 90
 
const uint16_t kLg32HdrMark = kLg32HdrMarkTicks * kLgTick
 
const uint16_t kLg32HdrSpaceTicks = 89
 
const uint16_t kLg32HdrSpace = kLg32HdrSpaceTicks * kLgTick
 
const uint16_t kLg32RptHdrMarkTicks = 179
 
const uint16_t kLg32RptHdrMark = kLg32RptHdrMarkTicks * kLgTick
 
const uint16_t kLg2HdrMarkTicks = 64
 
const uint16_t kLg2HdrMark = kLg2HdrMarkTicks * kLgTick
 
const uint16_t kLg2HdrSpaceTicks = 197
 
const uint16_t kLg2HdrSpace = kLg2HdrSpaceTicks * kLgTick
 
const uint16_t kLg2BitMarkTicks = 10
 
const uint16_t kLg2BitMark = kLg2BitMarkTicks * kLgTick
 
+

Detailed Description

+

Support for LG protocols. LG decode originally added by Darryl Smith (based on the JVC protocol) LG send originally added by https://github.com/chaeplin.

+
See also
https://github.com/arendst/Tasmota/blob/54c2eb283a02e4287640a4595e506bc6eadbd7f2/sonoff/xdrv_05_irremote.ino#L327-438
+

Variable Documentation

+ +

◆ kLg2BitMark

+ +
+
+ + + + +
const uint16_t kLg2BitMark = kLg2BitMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLg2BitMarkTicks

+ +
+
+ + + + +
const uint16_t kLg2BitMarkTicks = 10
+
+ +
+
+ +

◆ kLg2HdrMark

+ +
+
+ + + + +
const uint16_t kLg2HdrMark = kLg2HdrMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLg2HdrMarkTicks

+ +
+
+ + + + +
const uint16_t kLg2HdrMarkTicks = 64
+
+ +
+
+ +

◆ kLg2HdrSpace

+ +
+
+ + + + +
const uint16_t kLg2HdrSpace = kLg2HdrSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLg2HdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kLg2HdrSpaceTicks = 197
+
+ +
+
+ +

◆ kLg32HdrMark

+ +
+
+ + + + +
const uint16_t kLg32HdrMark = kLg32HdrMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLg32HdrMarkTicks

+ +
+
+ + + + +
const uint16_t kLg32HdrMarkTicks = 90
+
+ +
+
+ +

◆ kLg32HdrSpace

+ +
+
+ + + + +
const uint16_t kLg32HdrSpace = kLg32HdrSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLg32HdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kLg32HdrSpaceTicks = 89
+
+ +
+
+ +

◆ kLg32RptHdrMark

+ +
+
+ + + + +
const uint16_t kLg32RptHdrMark = kLg32RptHdrMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLg32RptHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kLg32RptHdrMarkTicks = 179
+
+ +
+
+ +

◆ kLgBitMark

+ +
+
+ + + + +
const uint16_t kLgBitMark = kLgBitMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLgBitMarkTicks

+ +
+
+ + + + +
const uint16_t kLgBitMarkTicks = 11
+
+ +
+
+ +

◆ kLgHdrMark

+ +
+
+ + + + +
const uint16_t kLgHdrMark = kLgHdrMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLgHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kLgHdrMarkTicks = 170
+
+ +
+
+ +

◆ kLgHdrSpace

+ +
+
+ + + + +
const uint16_t kLgHdrSpace = kLgHdrSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLgHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kLgHdrSpaceTicks = 85
+
+ +
+
+ +

◆ kLgMinGap

+ +
+
+ + + + +
const uint16_t kLgMinGap = kLgMinGapTicks * kLgTick
+
+ +
+
+ +

◆ kLgMinGapTicks

+ +
+
+ + + + +
const uint16_t kLgMinGapTicks = 795
+
+ +
+
+ +

◆ kLgMinMessageLength

+ +
+
+ + + + +
const uint32_t kLgMinMessageLength = kLgMinMessageLengthTicks * kLgTick
+
+ +
+
+ +

◆ kLgMinMessageLengthTicks

+ +
+
+ + + + +
const uint16_t kLgMinMessageLengthTicks = 2161
+
+ +
+
+ +

◆ kLgOneSpace

+ +
+
+ + + + +
const uint16_t kLgOneSpace = kLgOneSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLgOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kLgOneSpaceTicks = 32
+
+ +
+
+ +

◆ kLgRptSpace

+ +
+
+ + + + +
const uint16_t kLgRptSpace = kLgRptSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLgRptSpaceTicks

+ +
+
+ + + + +
const uint16_t kLgRptSpaceTicks = 45
+
+ +
+
+ +

◆ kLgTick

+ +
+
+ + + + +
const uint16_t kLgTick = 50
+
+ +
+
+ +

◆ kLgZeroSpace

+ +
+
+ + + + +
const uint16_t kLgZeroSpace = kLgZeroSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLgZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kLgZeroSpaceTicks = 11
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h.html new file mode 100644 index 000000000..76c02aabf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h.html @@ -0,0 +1,550 @@ + + + + + + + +IRremoteESP8266: src/ir_LG.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_LG.h File Reference
+
+
+ +

Support for LG protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRLgAc
 Class for handling detailed LG A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kLgAcChecksumOffset = 0
 
const uint8_t kLgAcChecksumSize = kNibbleSize
 
const uint8_t kLgAcFanOffset = 4
 
const uint8_t kLgAcFanSize = 3
 
const uint8_t kLgAcFanLow = 0
 
const uint8_t kLgAcFanMedium = 2
 
const uint8_t kLgAcFanHigh = 4
 
const uint8_t kLgAcFanAuto = 5
 
const uint8_t kLgAcTempOffset = 8
 
const uint8_t kLgAcTempSize = 4
 
const uint8_t kLgAcTempAdjust = 15
 
const uint8_t kLgAcMinTemp = 16
 
const uint8_t kLgAcMaxTemp = 30
 
const uint8_t kLgAcModeOffset = 12
 
const uint8_t kLgAcModeSize = 3
 
const uint8_t kLgAcCool = 0
 
const uint8_t kLgAcDry = 1
 
const uint8_t kLgAcFan = 2
 
const uint8_t kLgAcAuto = 3
 
const uint8_t kLgAcHeat = 4
 
const uint8_t kLgAcPowerOffset = 18
 
const uint8_t kLgAcPowerSize = 2
 
const uint8_t kLgAcPowerOff = 3
 
const uint8_t kLgAcPowerOn = 0
 
const uint8_t kLgAcSignatureOffset = 20
 
const uint8_t kLgAcSignatureSize = 8
 
const uint8_t kLgAcSignature = 0x88
 
const uint32_t kLgAcOffCommand = 0x88C0051
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kLgAcAuto

+ +
+
+ + + + +
const uint8_t kLgAcAuto = 3
+
+ +
+
+ +

◆ kLgAcChecksumOffset

+ +
+
+ + + + +
const uint8_t kLgAcChecksumOffset = 0
+
+ +
+
+ +

◆ kLgAcChecksumSize

+ +
+
+ + + + +
const uint8_t kLgAcChecksumSize = kNibbleSize
+
+ +
+
+ +

◆ kLgAcCool

+ +
+
+ + + + +
const uint8_t kLgAcCool = 0
+
+ +
+
+ +

◆ kLgAcDry

+ +
+
+ + + + +
const uint8_t kLgAcDry = 1
+
+ +
+
+ +

◆ kLgAcFan

+ +
+
+ + + + +
const uint8_t kLgAcFan = 2
+
+ +
+
+ +

◆ kLgAcFanAuto

+ +
+
+ + + + +
const uint8_t kLgAcFanAuto = 5
+
+ +
+
+ +

◆ kLgAcFanHigh

+ +
+
+ + + + +
const uint8_t kLgAcFanHigh = 4
+
+ +
+
+ +

◆ kLgAcFanLow

+ +
+
+ + + + +
const uint8_t kLgAcFanLow = 0
+
+ +
+
+ +

◆ kLgAcFanMedium

+ +
+
+ + + + +
const uint8_t kLgAcFanMedium = 2
+
+ +
+
+ +

◆ kLgAcFanOffset

+ +
+
+ + + + +
const uint8_t kLgAcFanOffset = 4
+
+ +
+
+ +

◆ kLgAcFanSize

+ +
+
+ + + + +
const uint8_t kLgAcFanSize = 3
+
+ +
+
+ +

◆ kLgAcHeat

+ +
+
+ + + + +
const uint8_t kLgAcHeat = 4
+
+ +
+
+ +

◆ kLgAcMaxTemp

+ +
+
+ + + + +
const uint8_t kLgAcMaxTemp = 30
+
+ +
+
+ +

◆ kLgAcMinTemp

+ +
+
+ + + + +
const uint8_t kLgAcMinTemp = 16
+
+ +
+
+ +

◆ kLgAcModeOffset

+ +
+
+ + + + +
const uint8_t kLgAcModeOffset = 12
+
+ +
+
+ +

◆ kLgAcModeSize

+ +
+
+ + + + +
const uint8_t kLgAcModeSize = 3
+
+ +
+
+ +

◆ kLgAcOffCommand

+ +
+
+ + + + +
const uint32_t kLgAcOffCommand = 0x88C0051
+
+ +
+
+ +

◆ kLgAcPowerOff

+ +
+
+ + + + +
const uint8_t kLgAcPowerOff = 3
+
+ +
+
+ +

◆ kLgAcPowerOffset

+ +
+
+ + + + +
const uint8_t kLgAcPowerOffset = 18
+
+ +
+
+ +

◆ kLgAcPowerOn

+ +
+
+ + + + +
const uint8_t kLgAcPowerOn = 0
+
+ +
+
+ +

◆ kLgAcPowerSize

+ +
+
+ + + + +
const uint8_t kLgAcPowerSize = 2
+
+ +
+
+ +

◆ kLgAcSignature

+ +
+
+ + + + +
const uint8_t kLgAcSignature = 0x88
+
+ +
+
+ +

◆ kLgAcSignatureOffset

+ +
+
+ + + + +
const uint8_t kLgAcSignatureOffset = 20
+
+ +
+
+ +

◆ kLgAcSignatureSize

+ +
+
+ + + + +
const uint8_t kLgAcSignatureSize = 8
+
+ +
+
+ +

◆ kLgAcTempAdjust

+ +
+
+ + + + +
const uint8_t kLgAcTempAdjust = 15
+
+ +
+
+ +

◆ kLgAcTempOffset

+ +
+
+ + + + +
const uint8_t kLgAcTempOffset = 8
+
+ +
+
+ +

◆ kLgAcTempSize

+ +
+
+ + + + +
const uint8_t kLgAcTempSize = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h_source.html new file mode 100644 index 000000000..05bcb6a1b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h_source.html @@ -0,0 +1,262 @@ + + + + + + + +IRremoteESP8266: src/ir_LG.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_LG.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017, 2019 David Conran
+
2 
+
6 
+
7 
+
8 // Supports:
+
9 // Brand: LG, Model: 6711A20083V remote (LG)
+
10 // Brand: LG, Model: AKB74395308 remote (LG2)
+
11 // Brand: LG, Model: S4-W12JA3AA A/C (LG2)
+
12 // Brand: LG, Model: AKB75215403 remote (LG2)
+
13 // Brand: General Electric, Model: AG1BH09AW101 Split A/C
+
14 // Brand: General Electric, Model: 6711AR2853M A/C Remote
+
15 
+
16 #ifndef IR_LG_H_
+
17 #define IR_LG_H_
+
18 
+
19 #define __STDC_LIMIT_MACROS
+
20 #include <stdint.h>
+
21 #ifndef UNIT_TEST
+
22 #include <Arduino.h>
+
23 #endif
+
24 #include "IRremoteESP8266.h"
+
25 #include "IRsend.h"
+
26 #include "IRutils.h"
+
27 #ifdef UNIT_TEST
+
28 #include "IRsend_test.h"
+
29 #endif
+
30 
+
31 const uint8_t kLgAcChecksumOffset = 0; // Nr. of bits
+
32 const uint8_t kLgAcChecksumSize = kNibbleSize; // Nr. of bits
+
33 const uint8_t kLgAcFanOffset = 4; // Nr. of bits
+
34 const uint8_t kLgAcFanSize = 3; // Nr. of bits
+
35 const uint8_t kLgAcFanLow = 0; // 0b000
+
36 const uint8_t kLgAcFanMedium = 2; // 0b010
+
37 const uint8_t kLgAcFanHigh = 4; // 0b100
+
38 const uint8_t kLgAcFanAuto = 5; // 0b101
+
39 const uint8_t kLgAcTempOffset = 8; // Nr. of bits
+
40 const uint8_t kLgAcTempSize = 4; // Nr. of bits
+
41 const uint8_t kLgAcTempAdjust = 15;
+
42 const uint8_t kLgAcMinTemp = 16; // Celsius
+
43 const uint8_t kLgAcMaxTemp = 30; // Celsius
+
44 const uint8_t kLgAcModeOffset = 12; // Nr. of bits
+
45 const uint8_t kLgAcModeSize = 3; // Nr. of bits
+
46 const uint8_t kLgAcCool = 0; // 0b000
+
47 const uint8_t kLgAcDry = 1; // 0b001
+
48 const uint8_t kLgAcFan = 2; // 0b010
+
49 const uint8_t kLgAcAuto = 3; // 0b011
+
50 const uint8_t kLgAcHeat = 4; // 0b100
+
51 const uint8_t kLgAcPowerOffset = 18; // Nr. of bits
+
52 const uint8_t kLgAcPowerSize = 2; // Nr. of bits
+
53 const uint8_t kLgAcPowerOff = 3; // 0b11
+
54 const uint8_t kLgAcPowerOn = 0; // 0b00
+
55 const uint8_t kLgAcSignatureOffset = 20; // Nr. of bits
+
56 const uint8_t kLgAcSignatureSize = 8; // Nr. of bits
+
57 const uint8_t kLgAcSignature = 0x88;
+
58 
+
59 const uint32_t kLgAcOffCommand = 0x88C0051;
+
60 
+
61 // Classes
+
63 class IRLgAc {
+
64  public:
+
65  explicit IRLgAc(const uint16_t pin, const bool inverted = false,
+
66  const bool use_modulation = true);
+
67  void stateReset(void);
+
68  static uint8_t calcChecksum(const uint32_t state);
+
69  static bool validChecksum(const uint32_t state);
+
70  bool isValidLgAc(void);
+
71 #if SEND_LG
+
72  void send(const uint16_t repeat = kLgDefaultRepeat);
+
77  int8_t calibrate(void) { return _irsend.calibrate(); }
+
78 #endif // SEND_LG
+
79  void begin(void);
+
80  void on(void);
+
81  void off(void);
+
82  void setPower(const bool on);
+
83  bool getPower(void);
+
84  void setTemp(const uint8_t degrees);
+
85  uint8_t getTemp(void);
+
86  void setFan(const uint8_t speed);
+
87  uint8_t getFan(void);
+
88  void setMode(const uint8_t mode);
+
89  uint8_t getMode(void);
+
90  uint32_t getRaw(void);
+
91  void setRaw(const uint32_t new_code);
+
92  uint8_t convertMode(const stdAc::opmode_t mode);
+
93  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
94  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
95  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+ +
97  String toString(void);
+
98  void setModel(const lg_ac_remote_model_t model);
+ +
100 #ifndef UNIT_TEST
+
101 
+
102  private:
+ +
104 #else // UNIT_TEST
+
105  IRsendTest _irsend;
+
107 #endif // UNIT_TEST
+
109  uint32_t remote_state;
+
110  uint8_t _temp;
+ +
112  void checksum(void);
+
113  void _setTemp(const uint8_t value);
+
114 };
+
115 
+
116 #endif // IR_LG_H_
+
+
const uint8_t kLgAcFanMedium
Definition: ir_LG.h:36
+
void _setTemp(const uint8_t value)
Set the temperature.
Definition: ir_LG.cpp:375
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_LG.cpp:457
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
uint32_t getRaw(void)
Get a copy of the internal state/code for this protocol.
Definition: ir_LG.cpp:314
+
decode_type_t _protocol
Definition: ir_LG.h:111
+
const uint8_t kLgAcFanSize
Definition: ir_LG.h:34
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_LG.h:77
+
const uint8_t kLgAcFanAuto
Definition: ir_LG.h:38
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kLgAcFanOffset
Definition: ir_LG.h:33
+
const uint8_t kLgAcPowerOff
Definition: ir_LG.h:53
+
lg_ac_remote_model_t getModel(void)
Get the model of the A/C.
Definition: ir_LG.cpp:301
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_LG.cpp:400
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_LG.cpp:521
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_LG.cpp:421
+
const uint8_t kLgAcFanHigh
Definition: ir_LG.h:37
+ +
const uint8_t kLgAcPowerOffset
Definition: ir_LG.h:51
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kLgAcDry
Definition: ir_LG.h:47
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_LG.cpp:381
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kLgAcTempOffset
Definition: ir_LG.h:39
+
const uint32_t kLgAcOffCommand
Definition: ir_LG.h:59
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kNibbleSize
Definition: IRutils.h:17
+
static uint8_t calcChecksum(const uint32_t state)
Calculate the checksum for a given state.
Definition: ir_LG.cpp:330
+
const uint8_t kLgAcFanLow
Definition: ir_LG.h:35
+
void setModel(const lg_ac_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_LG.cpp:287
+
const uint16_t kLgDefaultRepeat
Definition: IRremoteESP8266.h:919
+
const uint8_t kLgAcMaxTemp
Definition: ir_LG.h:43
+
IRLgAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_LG.cpp:259
+
const uint8_t kLgAcSignature
Definition: ir_LG.h:57
+ +
const uint8_t kLgAcSignatureSize
Definition: ir_LG.h:56
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_LG.cpp:470
+
const uint8_t kLgAcTempSize
Definition: ir_LG.h:40
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_LG.cpp:484
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_LG.cpp:495
+
const uint8_t kLgAcCool
Definition: ir_LG.h:46
+
const uint8_t kLgAcHeat
Definition: ir_LG.h:50
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_LG.cpp:270
+
const uint8_t kLgAcChecksumSize
Definition: ir_LG.h:32
+
const uint8_t kLgAcPowerSize
Definition: ir_LG.h:52
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_LG.cpp:415
+
Class for handling detailed LG A/C messages.
Definition: ir_LG.h:63
+ +
const uint8_t kLgAcSignatureOffset
Definition: ir_LG.h:55
+
const uint8_t kLgAcModeSize
Definition: ir_LG.h:45
+
uint32_t remote_state
The state of the IR remote in IR code form.
Definition: ir_LG.h:109
+
lg_ac_remote_model_t
LG A/C model numbers.
Definition: IRsend.h:158
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_LG.cpp:427
+
uint8_t _temp
Definition: ir_LG.h:110
+
const uint8_t kLgAcModeOffset
Definition: ir_LG.h:44
+
const uint8_t kLgAcAuto
Definition: ir_LG.h:49
+
void setRaw(const uint32_t new_code)
Set the internal state from a valid code for this protocol.
Definition: ir_LG.cpp:321
+
const uint8_t kLgAcPowerOn
Definition: ir_LG.h:54
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_LG.cpp:390
+
void off(void)
Change the power setting to Off.
Definition: ir_LG.cpp:352
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_LG.cpp:367
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_LG.cpp:343
+
void stateReset(void)
Reset the internals of the object to a known good state.
Definition: ir_LG.cpp:264
+
const uint8_t kLgAcChecksumOffset
Definition: ir_LG.h:31
+
const uint8_t kLgAcMinTemp
Definition: ir_LG.h:42
+
const uint8_t kLgAcTempAdjust
Definition: ir_LG.h:41
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_LG.cpp:444
+
void setPower(const bool on)
Change the power setting.
Definition: ir_LG.cpp:356
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void send(const uint16_t repeat=kLgDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_LG.cpp:275
+
static bool validChecksum(const uint32_t state)
Verify the checksum is valid for a given state.
Definition: ir_LG.cpp:337
+
const uint8_t kLgAcFan
Definition: ir_LG.h:48
+
void on(void)
Change the power setting to On.
Definition: ir_LG.cpp:349
+
bool isValidLgAc(void)
Check if the internal state looks like a valud LG A/C message.
Definition: ir_LG.cpp:538
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_LG.h:103
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lasertag_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lasertag_8cpp.html new file mode 100644 index 000000000..568c1faa2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lasertag_8cpp.html @@ -0,0 +1,221 @@ + + + + + + + +IRremoteESP8266: src/ir_Lasertag.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Lasertag.cpp File Reference
+
+
+ +

Support for Lasertag protocols. +More...

+ + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kLasertagMinSamples = 13
 
const uint16_t kLasertagTick = 333
 
const uint32_t kLasertagMinGap = kDefaultMessageGap
 
const uint8_t kLasertagTolerance = 0
 
const uint16_t kLasertagExcess = 0
 
const uint16_t kLasertagDelta = 150
 
const int16_t kSpace = 1
 
const int16_t kMark = 0
 
+

Detailed Description

+

Support for Lasertag protocols.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/366
+

Variable Documentation

+ +

◆ kLasertagDelta

+ +
+
+ + + + +
const uint16_t kLasertagDelta = 150
+
+ +
+
+ +

◆ kLasertagExcess

+ +
+
+ + + + +
const uint16_t kLasertagExcess = 0
+
+ +
+
+ +

◆ kLasertagMinGap

+ +
+
+ + + + +
const uint32_t kLasertagMinGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kLasertagMinSamples

+ +
+
+ + + + +
const uint16_t kLasertagMinSamples = 13
+
+ +
+
+ +

◆ kLasertagTick

+ +
+
+ + + + +
const uint16_t kLasertagTick = 333
+
+ +
+
+ +

◆ kLasertagTolerance

+ +
+
+ + + + +
const uint8_t kLasertagTolerance = 0
+
+ +
+
+ +

◆ kMark

+ +
+
+ + + + +
const int16_t kMark = 0
+
+ +
+
+ +

◆ kSpace

+ +
+
+ + + + +
const int16_t kSpace = 1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lego_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lego_8cpp.html new file mode 100644 index 000000000..8a2d2c588 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lego_8cpp.html @@ -0,0 +1,176 @@ + + + + + + + +IRremoteESP8266: src/ir_Lego.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Lego.cpp File Reference
+
+
+ +

Support for LEGO protocols. +More...

+ + + + + + + + + + + + +

+Variables

const uint16_t kLegoPfBitMark = 158
 
const uint16_t kLegoPfHdrSpace = 1026
 
const uint16_t kLegoPfZeroSpace = 263
 
const uint16_t kLegoPfOneSpace = 553
 
const uint32_t kLegoPfMinCommandLength = 16000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kLegoPfBitMark

+ +
+
+ + + + +
const uint16_t kLegoPfBitMark = 158
+
+ +
+
+ +

◆ kLegoPfHdrSpace

+ +
+
+ + + + +
const uint16_t kLegoPfHdrSpace = 1026
+
+ +
+
+ +

◆ kLegoPfMinCommandLength

+ +
+
+ + + + +
const uint32_t kLegoPfMinCommandLength = 16000
+
+ +
+
+ +

◆ kLegoPfOneSpace

+ +
+
+ + + + +
const uint16_t kLegoPfOneSpace = 553
+
+ +
+
+ +

◆ kLegoPfZeroSpace

+ +
+
+ + + + +
const uint16_t kLegoPfZeroSpace = 263
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lutron_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lutron_8cpp.html new file mode 100644 index 000000000..b75090a1f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lutron_8cpp.html @@ -0,0 +1,144 @@ + + + + + + + +IRremoteESP8266: src/ir_Lutron.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Lutron.cpp File Reference
+
+
+ +

Support for Lutron protocols. +More...

+ + + + + + + + +

+Variables

const uint16_t kLutronTick = 2288
 
const uint32_t kLutronGap = 150000
 
const uint16_t kLutronDelta = 400
 
+

Detailed Description

+

Support for Lutron protocols.

+
Note
The Lutron protocol uses a sort of Run Length encoding to encode its data. There is no header or footer per-se. As a mark is the first data we will notice, we always assume the First bit of the technically 36-bit protocol is '1'. So it is assumed, and thus we only care about the 35 bits of data.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/515
+
+http://www.lutron.com/TechnicalDocumentLibrary/048158.doc
+

Variable Documentation

+ +

◆ kLutronDelta

+ +
+
+ + + + +
const uint16_t kLutronDelta = 400
+
+ +
+
+ +

◆ kLutronGap

+ +
+
+ + + + +
const uint32_t kLutronGap = 150000
+
+ +
+
+ +

◆ kLutronTick

+ +
+
+ + + + +
const uint16_t kLutronTick = 2288
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MWM_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MWM_8cpp.html new file mode 100644 index 000000000..8a6c009c2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MWM_8cpp.html @@ -0,0 +1,237 @@ + + + + + + + +IRremoteESP8266: src/ir_MWM.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_MWM.cpp File Reference
+
+
+ +

Disney Made With Magic (MWM) Support derived from ir_Lasertag.cpp. +More...

+ + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kMWMMinSamples = 6
 
const uint16_t kMWMTick = 417
 
const uint32_t kMWMMinGap = 30000
 
const uint8_t kMWMTolerance = 0
 
const uint16_t kMWMExcess = 0
 
const uint16_t kMWMDelta = 150
 
const uint8_t kMWMMaxWidth = 9
 
const int16_t kSpace = 1
 
const int16_t kMark = 0
 
+

Detailed Description

+

Disney Made With Magic (MWM) Support derived from ir_Lasertag.cpp.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/pull/557
+

Variable Documentation

+ +

◆ kMark

+ +
+
+ + + + +
const int16_t kMark = 0
+
+ +
+
+ +

◆ kMWMDelta

+ +
+
+ + + + +
const uint16_t kMWMDelta = 150
+
+ +
+
+ +

◆ kMWMExcess

+ +
+
+ + + + +
const uint16_t kMWMExcess = 0
+
+ +
+
+ +

◆ kMWMMaxWidth

+ +
+
+ + + + +
const uint8_t kMWMMaxWidth = 9
+
+ +
+
+ +

◆ kMWMMinGap

+ +
+
+ + + + +
const uint32_t kMWMMinGap = 30000
+
+ +
+
+ +

◆ kMWMMinSamples

+ +
+
+ + + + +
const uint16_t kMWMMinSamples = 6
+
+ +
+
+ +

◆ kMWMTick

+ +
+
+ + + + +
const uint16_t kMWMTick = 417
+
+ +
+
+ +

◆ kMWMTolerance

+ +
+
+ + + + +
const uint8_t kMWMTolerance = 0
+
+ +
+
+ +

◆ kSpace

+ +
+
+ + + + +
const int16_t kSpace = 1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8cpp.html new file mode 100644 index 000000000..3b0c54da6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8cpp.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: src/ir_Magiquest.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Magiquest.cpp File Reference
+
+
+ +

Support for MagiQuest protocols. +More...

+

Detailed Description

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h.html new file mode 100644 index 000000000..628b41793 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h.html @@ -0,0 +1,232 @@ + + + + + + + +IRremoteESP8266: src/ir_Magiquest.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Magiquest.h File Reference
+
+
+ +

Support for MagiQuest protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

union  magiquest
 MagiQuest packet is both Wand ID and magnitude of swish and flick. More...
 
+ + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kMagiQuestTotalUsec = 1150
 
const uint8_t kMagiQuestZeroRatio = 30
 
const uint8_t kMagiQuestOneRatio = 38
 
const uint16_t kMagiQuestMarkZero = 280
 
const uint16_t kMagiQuestSpaceZero = 850
 
const uint16_t kMagiQuestMarkOne = 580
 
const uint16_t kMagiQuestSpaceOne = 600
 
const uint32_t kMagiQuestGap = kDefaultMessageGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMagiQuestGap

+ +
+
+ + + + +
const uint32_t kMagiQuestGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kMagiQuestMarkOne

+ +
+
+ + + + +
const uint16_t kMagiQuestMarkOne = 580
+
+ +
+
+ +

◆ kMagiQuestMarkZero

+ +
+
+ + + + +
const uint16_t kMagiQuestMarkZero = 280
+
+ +
+
+ +

◆ kMagiQuestOneRatio

+ +
+
+ + + + +
const uint8_t kMagiQuestOneRatio = 38
+
+ +
+
+ +

◆ kMagiQuestSpaceOne

+ +
+
+ + + + +
const uint16_t kMagiQuestSpaceOne = 600
+
+ +
+
+ +

◆ kMagiQuestSpaceZero

+ +
+
+ + + + +
const uint16_t kMagiQuestSpaceZero = 850
+
+ +
+
+ +

◆ kMagiQuestTotalUsec

+ +
+
+ + + + +
const uint16_t kMagiQuestTotalUsec = 1150
+
+ +
+
+ +

◆ kMagiQuestZeroRatio

+ +
+
+ + + + +
const uint8_t kMagiQuestZeroRatio = 30
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h_source.html new file mode 100644 index 000000000..1928697e9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h_source.html @@ -0,0 +1,137 @@ + + + + + + + +IRremoteESP8266: src/ir_Magiquest.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Magiquest.h
+
+
+Go to the documentation of this file.
1 // Copyright 2013 mpflaga
+
2 // Copyright 2015 kitlaan
+
3 // Copyright 2017 Jason kendall, David Conran
+
4 
+
9 
+
10 // Supports:
+
11 // Brand: MagiQuest, Model: Wand
+
12 
+
13 #ifndef IR_MAGIQUEST_H_
+
14 #define IR_MAGIQUEST_H_
+
15 
+
16 #define __STDC_LIMIT_MACROS
+
17 #include <stdint.h>
+
18 #include "IRremoteESP8266.h"
+
19 #include "IRsend.h"
+
20 
+
22 union magiquest {
+
23  uint64_t llword;
+
24  uint8_t byte[8];
+
25  // uint16_t word[4];
+
26  uint32_t lword[2];
+
27  struct {
+
28  uint16_t magnitude;
+
29  uint32_t wand_id;
+
30  uint8_t padding;
+
31  uint8_t scrap;
+
32  } cmd;
+
33 };
+
34 
+
35 const uint16_t kMagiQuestTotalUsec = 1150;
+
36 const uint8_t kMagiQuestZeroRatio = 30; // usually <= ~25%
+
37 const uint8_t kMagiQuestOneRatio = 38; // usually >= ~50%
+
38 const uint16_t kMagiQuestMarkZero = 280;
+
39 const uint16_t kMagiQuestSpaceZero = 850;
+
40 const uint16_t kMagiQuestMarkOne = 580;
+
41 const uint16_t kMagiQuestSpaceOne = 600;
+
42 const uint32_t kMagiQuestGap = kDefaultMessageGap; // Just a guess.
+
43 #endif // IR_MAGIQUEST_H_
+
+
const uint32_t kDefaultMessageGap
Definition: IRsend.h:41
+
uint8_t scrap
Definition: ir_Magiquest.h:31
+
const uint16_t kMagiQuestMarkZero
Definition: ir_Magiquest.h:38
+ +
uint16_t magnitude
Definition: ir_Magiquest.h:28
+
struct magiquest::@0 cmd
+
uint64_t llword
Definition: ir_Magiquest.h:23
+ +
const uint16_t kMagiQuestMarkOne
Definition: ir_Magiquest.h:40
+
MagiQuest packet is both Wand ID and magnitude of swish and flick.
Definition: ir_Magiquest.h:22
+
uint32_t wand_id
Definition: ir_Magiquest.h:29
+
const uint32_t kMagiQuestGap
Definition: ir_Magiquest.h:42
+
const uint16_t kMagiQuestSpaceZero
Definition: ir_Magiquest.h:39
+
const uint16_t kMagiQuestSpaceOne
Definition: ir_Magiquest.h:41
+
uint32_t lword[2]
Definition: ir_Magiquest.h:26
+
const uint16_t kMagiQuestTotalUsec
Definition: ir_Magiquest.h:35
+
uint8_t padding
Definition: ir_Magiquest.h:30
+
const uint8_t kMagiQuestOneRatio
Definition: ir_Magiquest.h:37
+
const uint8_t kMagiQuestZeroRatio
Definition: ir_Magiquest.h:36
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8cpp.html new file mode 100644 index 000000000..4d39bc403 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8cpp.html @@ -0,0 +1,341 @@ + + + + + + + +IRremoteESP8266: src/ir_Midea.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Midea.cpp File Reference
+
+
+ +

Support for Midea protocols. Midea added by crankyoldgit & bwze. send: bwze/crankyoldgit, decode: crankyoldgit. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kMideaTick = 80
 
const uint16_t kMideaBitMarkTicks = 7
 
const uint16_t kMideaBitMark = kMideaBitMarkTicks * kMideaTick
 
const uint16_t kMideaOneSpaceTicks = 21
 
const uint16_t kMideaOneSpace = kMideaOneSpaceTicks * kMideaTick
 
const uint16_t kMideaZeroSpaceTicks = 7
 
const uint16_t kMideaZeroSpace = kMideaZeroSpaceTicks * kMideaTick
 
const uint16_t kMideaHdrMarkTicks = 56
 
const uint16_t kMideaHdrMark = kMideaHdrMarkTicks * kMideaTick
 
const uint16_t kMideaHdrSpaceTicks = 56
 
const uint16_t kMideaHdrSpace = kMideaHdrSpaceTicks * kMideaTick
 
const uint16_t kMideaMinGapTicks
 
const uint16_t kMideaMinGap = kMideaMinGapTicks * kMideaTick
 
const uint8_t kMideaTolerance = 30
 
const uint16_t kMidea24MinGap = 13000
 uSecs More...
 
+

Detailed Description

+

Support for Midea protocols. Midea added by crankyoldgit & bwze. send: bwze/crankyoldgit, decode: crankyoldgit.

+
See also
https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing
+

Variable Documentation

+ +

◆ kMidea24MinGap

+ +
+
+ + + + +
const uint16_t kMidea24MinGap = 13000
+
+ +

uSecs

+ +
+
+ +

◆ kMideaBitMark

+ +
+
+ + + + +
const uint16_t kMideaBitMark = kMideaBitMarkTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaBitMarkTicks

+ +
+
+ + + + +
const uint16_t kMideaBitMarkTicks = 7
+
+ +
+
+ +

◆ kMideaHdrMark

+ +
+
+ + + + +
const uint16_t kMideaHdrMark = kMideaHdrMarkTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kMideaHdrMarkTicks = 56
+
+ +
+
+ +

◆ kMideaHdrSpace

+ +
+
+ + + + +
const uint16_t kMideaHdrSpace = kMideaHdrSpaceTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kMideaHdrSpaceTicks = 56
+
+ +
+
+ +

◆ kMideaMinGap

+ +
+
+ + + + +
const uint16_t kMideaMinGap = kMideaMinGapTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaMinGapTicks

+ +
+
+ + + + +
const uint16_t kMideaMinGapTicks
+
+
+ +

◆ kMideaOneSpace

+ +
+
+ + + + +
const uint16_t kMideaOneSpace = kMideaOneSpaceTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kMideaOneSpaceTicks = 21
+
+ +
+
+ +

◆ kMideaTick

+ +
+
+ + + + +
const uint16_t kMideaTick = 80
+
+ +
+
+ +

◆ kMideaTolerance

+ +
+
+ + + + +
const uint8_t kMideaTolerance = 30
+
+ +
+
+ +

◆ kMideaZeroSpace

+ +
+
+ + + + +
const uint16_t kMideaZeroSpace = kMideaZeroSpaceTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kMideaZeroSpaceTicks = 7
+
+ +
+
+
+
const uint16_t kMideaZeroSpaceTicks
Definition: ir_Midea.cpp:25
+
const uint16_t kMideaBitMarkTicks
Definition: ir_Midea.cpp:21
+
const uint16_t kMideaHdrMarkTicks
Definition: ir_Midea.cpp:27
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h.html new file mode 100644 index 000000000..309a3a97a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h.html @@ -0,0 +1,454 @@ + + + + + + + +IRremoteESP8266: src/ir_Midea.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Midea.h File Reference
+
+
+ +

Support for Midea protocols. Midea added by crankyoldgit & bwze. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRMideaAC
 Class for handling detailed Midea A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kMideaACTempOffset = 24
 
const uint8_t kMideaACTempSize = 5
 
const uint8_t kMideaACMinTempF = 62
 
const uint8_t kMideaACMaxTempF = 86
 
const uint8_t kMideaACMinTempC = 17
 
const uint8_t kMideaACMaxTempC = 30
 
const uint8_t kMideaACCelsiusOffset = 29
 
const uint8_t kMideaACModeOffset = 32
 
const uint8_t kMideaACCool = 0
 
const uint8_t kMideaACDry = 1
 
const uint8_t kMideaACAuto = 2
 
const uint8_t kMideaACHeat = 3
 
const uint8_t kMideaACFan = 4
 
const uint8_t kMideaACFanOffset = 35
 
const uint8_t kMideaACFanSize = 2
 
const uint8_t kMideaACFanAuto = 0
 
const uint8_t kMideaACFanLow = 1
 
const uint8_t kMideaACFanMed = 2
 
const uint8_t kMideaACFanHigh = 3
 
const uint8_t kMideaACSleepOffset = 38
 
const uint8_t kMideaACPowerOffset = 39
 
const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C
 
+

Detailed Description

+

Support for Midea protocols. Midea added by crankyoldgit & bwze.

+
See also
https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing
+

Variable Documentation

+ +

◆ kMideaACAuto

+ +
+
+ + + + +
const uint8_t kMideaACAuto = 2
+
+ +
+
+ +

◆ kMideaACCelsiusOffset

+ +
+
+ + + + +
const uint8_t kMideaACCelsiusOffset = 29
+
+ +
+
+ +

◆ kMideaACCool

+ +
+
+ + + + +
const uint8_t kMideaACCool = 0
+
+ +
+
+ +

◆ kMideaACDry

+ +
+
+ + + + +
const uint8_t kMideaACDry = 1
+
+ +
+
+ +

◆ kMideaACFan

+ +
+
+ + + + +
const uint8_t kMideaACFan = 4
+
+ +
+
+ +

◆ kMideaACFanAuto

+ +
+
+ + + + +
const uint8_t kMideaACFanAuto = 0
+
+ +
+
+ +

◆ kMideaACFanHigh

+ +
+
+ + + + +
const uint8_t kMideaACFanHigh = 3
+
+ +
+
+ +

◆ kMideaACFanLow

+ +
+
+ + + + +
const uint8_t kMideaACFanLow = 1
+
+ +
+
+ +

◆ kMideaACFanMed

+ +
+
+ + + + +
const uint8_t kMideaACFanMed = 2
+
+ +
+
+ +

◆ kMideaACFanOffset

+ +
+
+ + + + +
const uint8_t kMideaACFanOffset = 35
+
+ +
+
+ +

◆ kMideaACFanSize

+ +
+
+ + + + +
const uint8_t kMideaACFanSize = 2
+
+ +
+
+ +

◆ kMideaACHeat

+ +
+
+ + + + +
const uint8_t kMideaACHeat = 3
+
+ +
+
+ +

◆ kMideaACMaxTempC

+ +
+
+ + + + +
const uint8_t kMideaACMaxTempC = 30
+
+ +
+
+ +

◆ kMideaACMaxTempF

+ +
+
+ + + + +
const uint8_t kMideaACMaxTempF = 86
+
+ +
+
+ +

◆ kMideaACMinTempC

+ +
+
+ + + + +
const uint8_t kMideaACMinTempC = 17
+
+ +
+
+ +

◆ kMideaACMinTempF

+ +
+
+ + + + +
const uint8_t kMideaACMinTempF = 62
+
+ +
+
+ +

◆ kMideaACModeOffset

+ +
+
+ + + + +
const uint8_t kMideaACModeOffset = 32
+
+ +
+
+ +

◆ kMideaACPowerOffset

+ +
+
+ + + + +
const uint8_t kMideaACPowerOffset = 39
+
+ +
+
+ +

◆ kMideaACSleepOffset

+ +
+
+ + + + +
const uint8_t kMideaACSleepOffset = 38
+
+ +
+
+ +

◆ kMideaACTempOffset

+ +
+
+ + + + +
const uint8_t kMideaACTempOffset = 24
+
+ +
+
+ +

◆ kMideaACTempSize

+ +
+
+ + + + +
const uint8_t kMideaACTempSize = 5
+
+ +
+
+ +

◆ kMideaACToggleSwingV

+ +
+
+ + + + +
const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h_source.html new file mode 100644 index 000000000..f8649c8cd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h_source.html @@ -0,0 +1,264 @@ + + + + + + + +IRremoteESP8266: src/ir_Midea.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Midea.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 David Conran
+
2 
+
7 
+
8 // Supports:
+
9 // Brand: Pioneer System, Model: RYBO12GMFILCAD A/C (12K BTU) (MIDEA)
+
10 // Brand: Pioneer System, Model: RUBO18GMFILCAD A/C (18K BTU) (MIDEA)
+
11 // Brand: Comfee, Model: MPD1-12CRN7 A/C (MIDEA)
+
12 // Brand: Keystone, Model: RG57H4(B)BGEF remote (MIDEA)
+
13 // Brand: Midea, Model: FS40-7AR Stand Fan (MIDEA24)
+
14 
+
15 #ifndef IR_MIDEA_H_
+
16 #define IR_MIDEA_H_
+
17 
+
18 #define __STDC_LIMIT_MACROS
+
19 #include <stdint.h>
+
20 #ifdef ARDUINO
+
21 #include <Arduino.h>
+
22 #endif
+
23 #include "IRremoteESP8266.h"
+
24 #include "IRsend.h"
+
25 #ifdef UNIT_TEST
+
26 #include "IRsend_test.h"
+
27 #endif
+
28 
+
29 // Constants
+
30 const uint8_t kMideaACTempOffset = 24;
+
31 const uint8_t kMideaACTempSize = 5; // Bits
+
32 const uint8_t kMideaACMinTempF = 62; // Fahrenheit
+
33 const uint8_t kMideaACMaxTempF = 86; // Fahrenheit
+
34 const uint8_t kMideaACMinTempC = 17; // Celsius
+
35 const uint8_t kMideaACMaxTempC = 30; // Celsius
+
36 const uint8_t kMideaACCelsiusOffset = 29;
+
37 const uint8_t kMideaACModeOffset = 32;
+
38 const uint8_t kMideaACCool = 0; // 0b000
+
39 const uint8_t kMideaACDry = 1; // 0b001
+
40 const uint8_t kMideaACAuto = 2; // 0b010
+
41 const uint8_t kMideaACHeat = 3; // 0b011
+
42 const uint8_t kMideaACFan = 4; // 0b100
+
43 const uint8_t kMideaACFanOffset = 35;
+
44 const uint8_t kMideaACFanSize = 2; // Bits
+
45 const uint8_t kMideaACFanAuto = 0; // 0b00
+
46 const uint8_t kMideaACFanLow = 1; // 0b01
+
47 const uint8_t kMideaACFanMed = 2; // 0b10
+
48 const uint8_t kMideaACFanHigh = 3; // 0b11
+
49 const uint8_t kMideaACSleepOffset = 38;
+
50 const uint8_t kMideaACPowerOffset = 39;
+
51 const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C;
+
52 
+
53 // Legacy defines. (Deprecated)
+
54 #define MIDEA_AC_COOL kMideaACCool
+
55 #define MIDEA_AC_DRY kMideaACDry
+
56 #define MIDEA_AC_AUTO kMideaACAuto
+
57 #define MIDEA_AC_HEAT kMideaACHeat
+
58 #define MIDEA_AC_FAN kMideaACFan
+
59 #define MIDEA_AC_FAN_AUTO kMideaACFanAuto
+
60 #define MIDEA_AC_FAN_LOW kMideaACFanLow
+
61 #define MIDEA_AC_FAN_MED kMideaACFanMed
+
62 #define MIDEA_AC_FAN_HI kMideaACFanHigh
+
63 #define MIDEA_AC_POWER kMideaACPower
+
64 #define MIDEA_AC_SLEEP kMideaACSleep
+
65 #define MIDEA_AC_MIN_TEMP_F kMideaACMinTempF
+
66 #define MIDEA_AC_MAX_TEMP_F kMideaACMaxTempF
+
67 #define MIDEA_AC_MIN_TEMP_C kMideaACMinTempC
+
68 #define MIDEA_AC_MAX_TEMP_C kMideaACMaxTempC
+
69 
+
70 // Classes
+
73 class IRMideaAC {
+
74  public:
+
75  explicit IRMideaAC(const uint16_t pin, const bool inverted = false,
+
76  const bool use_modulation = true);
+
77  void stateReset(void);
+
78 #if SEND_MIDEA
+
79  void send(const uint16_t repeat = kMideaMinRepeat);
+
84  int8_t calibrate(void) { return _irsend.calibrate(); }
+
85 #endif // SEND_MIDEA
+
86  void begin(void);
+
87  void on(void);
+
88  void off(void);
+
89  void setPower(const bool on);
+
90  bool getPower(void);
+
91  bool getUseCelsius(void);
+
92  void setUseCelsius(const bool celsius);
+
93  void setTemp(const uint8_t temp, const bool useCelsius = false);
+
94  uint8_t getTemp(const bool useCelsius = false);
+
95  void setFan(const uint8_t fan);
+
96  uint8_t getFan(void);
+
97  void setMode(const uint8_t mode);
+
98  uint8_t getMode(void);
+
99  void setRaw(const uint64_t newState);
+
100  uint64_t getRaw(void);
+
101  static bool validChecksum(const uint64_t state);
+
102  void setSleep(const bool on);
+
103  bool getSleep(void);
+
104  bool isSwingVToggle(void);
+
105  void setSwingVToggle(const bool on);
+
106  bool getSwingVToggle(void);
+
107  uint8_t convertMode(const stdAc::opmode_t mode);
+
108  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
109  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
110  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
111  stdAc::state_t toCommon(const stdAc::state_t *prev = NULL);
+
112  String toString(void);
+
113 #ifndef UNIT_TEST
+
114 
+
115  private:
+ +
117 #else // UNIT_TEST
+
118  IRsendTest _irsend;
+
120 #endif // UNIT_TEST
+
122  uint64_t remote_state;
+ +
124  void checksum(void);
+
125  static uint8_t calcChecksum(const uint64_t state);
+
126 };
+
127 
+
128 #endif // IR_MIDEA_H_
+
+
const uint8_t kMideaACMinTempF
Definition: ir_Midea.h:32
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Midea.cpp:105
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Midea.cpp:336
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Midea.cpp:238
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Midea.cpp:133
+
void setUseCelsius(const bool celsius)
Set the A/C unit to use Celsius natively.
Definition: ir_Midea.cpp:158
+
const uint16_t kMideaMinRepeat
Definition: IRremoteESP8266.h:923
+
void setTemp(const uint8_t temp, const bool useCelsius=false)
Set the temperature.
Definition: ir_Midea.cpp:169
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Midea.h:84
+
const uint8_t kMideaACTempOffset
Definition: ir_Midea.h:30
+
const uint8_t kMideaACFanSize
Definition: ir_Midea.h:44
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Midea.cpp:210
+
bool _SwingVToggle
Definition: ir_Midea.h:123
+
const uint8_t kMideaACAuto
Definition: ir_Midea.h:40
+
void checksum(void)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Midea.cpp:288
+
IRMideaAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Midea.cpp:93
+
const uint8_t kMideaACFan
Definition: ir_Midea.h:42
+
void send(const uint16_t repeat=kMideaMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Midea.cpp:110
+
const uint8_t kMideaACModeOffset
Definition: ir_Midea.h:37
+
bool isSwingVToggle(void)
Is the current state a vertical swing toggle message?
Definition: ir_Midea.cpp:254
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Midea.cpp:244
+ +
const uint8_t kMideaACMaxTempF
Definition: ir_Midea.h:33
+
const uint8_t kMideaACCelsiusOffset
Definition: ir_Midea.h:36
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
void setSwingVToggle(const bool on)
Set the A/C to toggle the vertical swing toggle for the next send.
Definition: ir_Midea.cpp:250
+
std::string String
Definition: IRremoteESP8266.h:1093
+
bool getSwingVToggle(void)
Definition: ir_Midea.cpp:260
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Midea.cpp:136
+ +
const uint8_t kMideaACHeat
Definition: ir_Midea.h:41
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Midea.cpp:146
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Midea.cpp:216
+
bool getUseCelsius(void)
Is the device currently using Celsius or the Fahrenheit temp scale?
Definition: ir_Midea.cpp:152
+
uint8_t getTemp(const bool useCelsius=false)
Get the current temperature setting.
Definition: ir_Midea.cpp:190
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Midea.cpp:323
+
const uint8_t kMideaACFanAuto
Definition: ir_Midea.h:45
+
const uint64_t kMideaACToggleSwingV
Definition: ir_Midea.h:51
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Midea.h:116
+
Class for handling detailed Midea A/C messages.
Definition: ir_Midea.h:73
+
void setRaw(const uint64_t newState)
Set the internal state from a valid code for this protocol.
Definition: ir_Midea.cpp:130
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Midea.cpp:222
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Midea.cpp:268
+
const uint8_t kMideaACTempSize
Definition: ir_Midea.h:31
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Midea.cpp:309
+
const uint8_t kMideaACSleepOffset
Definition: ir_Midea.h:49
+
const uint8_t kMideaACFanMed
Definition: ir_Midea.h:47
+
uint64_t getRaw(void)
Get a copy of the internal state/code for this protocol.
Definition: ir_Midea.cpp:123
+
const uint8_t kMideaACMinTempC
Definition: ir_Midea.h:34
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Midea.cpp:296
+
uint64_t remote_state
The state of the IR remote in IR code form.
Definition: ir_Midea.h:122
+
const uint8_t kMideaACPowerOffset
Definition: ir_Midea.h:50
+
const uint8_t kMideaACFanHigh
Definition: ir_Midea.h:48
+
const uint8_t kMideaACMaxTempC
Definition: ir_Midea.h:35
+
stdAc::state_t toCommon(const stdAc::state_t *prev=NULL)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Midea.cpp:348
+
const uint8_t kMideaACDry
Definition: ir_Midea.h:39
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Midea.cpp:384
+
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Midea.cpp:283
+
const uint8_t kMideaACFanOffset
Definition: ir_Midea.h:43
+
const uint8_t kMideaACCool
Definition: ir_Midea.h:38
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Midea.cpp:140
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Midea.cpp:98
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kMideaACFanLow
Definition: ir_Midea.h:46
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Midea.cpp:203
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html new file mode 100644 index 000000000..8c6af97fa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html @@ -0,0 +1,194 @@ + + + + + + + +IRremoteESP8266: src/ir_MitsubishiHeavy.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_MitsubishiHeavy.cpp File Reference
+
+
+ +

Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kMitsubishiHeavyHdrMark = 3140
 
const uint16_t kMitsubishiHeavyHdrSpace = 1630
 
const uint16_t kMitsubishiHeavyBitMark = 370
 
const uint16_t kMitsubishiHeavyOneSpace = 420
 
const uint16_t kMitsubishiHeavyZeroSpace = 1220
 
const uint32_t kMitsubishiHeavyGap = kDefaultMessageGap
 
+

Detailed Description

+

Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units.

+
Note
This code was heavily influenced by ToniA's great work & code, but it has been written from scratch. Nothing was copied other than constants and message analysis.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/660
+
+https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp
+
+https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp
+

Variable Documentation

+ +

◆ kMitsubishiHeavyBitMark

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyBitMark = 370
+
+ +
+
+ +

◆ kMitsubishiHeavyGap

+ +
+
+ + + + +
const uint32_t kMitsubishiHeavyGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kMitsubishiHeavyHdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyHdrMark = 3140
+
+ +
+
+ +

◆ kMitsubishiHeavyHdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyHdrSpace = 1630
+
+ +
+
+ +

◆ kMitsubishiHeavyOneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyOneSpace = 420
+
+ +
+
+ +

◆ kMitsubishiHeavyZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyZeroSpace = 1220
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h.html new file mode 100644 index 000000000..320f3cab8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h.html @@ -0,0 +1,1314 @@ + + + + + + + +IRremoteESP8266: src/ir_MitsubishiHeavy.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_MitsubishiHeavy.h File Reference
+
+
+ +

Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units. +More...

+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

class  IRMitsubishiHeavy152Ac
 Class for handling detailed Mitsubishi Heavy 152-bit A/C messages. More...
 
class  IRMitsubishiHeavy88Ac
 Class for handling detailed Mitsubishi Heavy 88-bit A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kMitsubishiHeavySigLength = 5
 
const uint8_t kMitsubishiHeavyZmsSig [kMitsubishiHeavySigLength]
 
const uint8_t kMitsubishiHeavyModeOffset = 0
 
const uint8_t kMitsubishiHeavyAuto = 0
 
const uint8_t kMitsubishiHeavyCool = 1
 
const uint8_t kMitsubishiHeavyDry = 2
 
const uint8_t kMitsubishiHeavyFan = 3
 
const uint8_t kMitsubishiHeavyHeat = 4
 
const uint8_t kMitsubishiHeavyPowerOffset = 3
 
const uint8_t kMitsubishiHeavyCleanOffset = 5
 
const uint8_t kMitsubishiHeavyFilterOffset = 6
 
const uint8_t kMitsubishiHeavyMinTemp = 17
 
const uint8_t kMitsubishiHeavyMaxTemp = 31
 
const uint8_t kMitsubishiHeavy152FanAuto = 0x0
 
const uint8_t kMitsubishiHeavy152FanLow = 0x1
 
const uint8_t kMitsubishiHeavy152FanMed = 0x2
 
const uint8_t kMitsubishiHeavy152FanHigh = 0x3
 
const uint8_t kMitsubishiHeavy152FanMax = 0x4
 
const uint8_t kMitsubishiHeavy152FanEcono = 0x6
 
const uint8_t kMitsubishiHeavy152FanTurbo = 0x8
 
const uint8_t kMitsubishiHeavy3DMask = 0b00010010
 
const uint8_t kMitsubishiHeavy152SwingVOffset = 5
 
const uint8_t kMitsubishiHeavy152SwingVSize = 3
 
const uint8_t kMitsubishiHeavy152SwingVAuto = 0
 
const uint8_t kMitsubishiHeavy152SwingVHighest = 1
 
const uint8_t kMitsubishiHeavy152SwingVHigh = 2
 
const uint8_t kMitsubishiHeavy152SwingVMiddle = 3
 
const uint8_t kMitsubishiHeavy152SwingVLow = 4
 
const uint8_t kMitsubishiHeavy152SwingVLowest = 5
 
const uint8_t kMitsubishiHeavy152SwingVOff = 6
 
const uint8_t kMitsubishiHeavy152SwingHAuto = 0
 
const uint8_t kMitsubishiHeavy152SwingHLeftMax = 1
 
const uint8_t kMitsubishiHeavy152SwingHLeft = 2
 
const uint8_t kMitsubishiHeavy152SwingHMiddle = 3
 
const uint8_t kMitsubishiHeavy152SwingHRight = 4
 
const uint8_t kMitsubishiHeavy152SwingHRightMax = 5
 
const uint8_t kMitsubishiHeavy152SwingHRightLeft = 6
 
const uint8_t kMitsubishiHeavy152SwingHLeftRight = 7
 
const uint8_t kMitsubishiHeavy152SwingHOff = 8
 
const uint8_t kMitsubishiHeavyNightOffset = 6
 
const uint8_t kMitsubishiHeavySilentOffset = 7
 
const uint8_t kMitsubishiHeavyZjsSig [kMitsubishiHeavySigLength]
 
const uint8_t kMitsubishiHeavy88CleanOffset = 5
 
const uint8_t kMitsubishiHeavy88SwingHOffset1 = 2
 
const uint8_t kMitsubishiHeavy88SwingHOffset2 = 6
 
const uint8_t kMitsubishiHeavy88SwingHSize = 2
 
const uint8_t kMitsubishiHeavy88SwingHOff = 0b0000
 
const uint8_t kMitsubishiHeavy88SwingHAuto = 0b1000
 
const uint8_t kMitsubishiHeavy88SwingHLeftMax = 0b0001
 
const uint8_t kMitsubishiHeavy88SwingHLeft = 0b0101
 
const uint8_t kMitsubishiHeavy88SwingHMiddle = 0b1001
 
const uint8_t kMitsubishiHeavy88SwingHRight = 0b1101
 
const uint8_t kMitsubishiHeavy88SwingHRightMax = 0b0010
 
const uint8_t kMitsubishiHeavy88SwingHRightLeft = 0b1010
 
const uint8_t kMitsubishiHeavy88SwingHLeftRight = 0b0110
 
const uint8_t kMitsubishiHeavy88SwingH3D = 0b1110
 
const uint8_t kMitsubishiHeavy88FanOffset = 5
 
const uint8_t kMitsubishiHeavy88FanSize = 3
 
const uint8_t kMitsubishiHeavy88FanAuto = 0
 
const uint8_t kMitsubishiHeavy88FanLow = 2
 
const uint8_t kMitsubishiHeavy88FanMed = 3
 
const uint8_t kMitsubishiHeavy88FanHigh = 4
 
const uint8_t kMitsubishiHeavy88FanTurbo = 6
 
const uint8_t kMitsubishiHeavy88FanEcono = 7
 
const uint8_t kMitsubishiHeavy88SwingVByte5Offset = 1
 
const uint8_t kMitsubishiHeavy88SwingVByte5Size = 1
 
const uint8_t kMitsubishiHeavy88SwingVByte7Offset = 3
 
const uint8_t kMitsubishiHeavy88SwingVByte7Size = 2
 
const uint8_t kMitsubishiHeavy88SwingVOff = 0b000
 
const uint8_t kMitsubishiHeavy88SwingVAuto = 0b100
 
const uint8_t kMitsubishiHeavy88SwingVHighest = 0b110
 
const uint8_t kMitsubishiHeavy88SwingVHigh = 0b001
 
const uint8_t kMitsubishiHeavy88SwingVMiddle = 0b011
 
const uint8_t kMitsubishiHeavy88SwingVLow = 0b101
 
const uint8_t kMitsubishiHeavy88SwingVLowest = 0b111
 
+

Detailed Description

+

Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units.

+
Note
This code was heavily influenced by ToniA's great work & code, but it has been written from scratch. Nothing was copied other than constants and message analysis.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/660
+
+https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp
+
+https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp
+

Variable Documentation

+ +

◆ kMitsubishiHeavy152FanAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanAuto = 0x0
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanEcono

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanEcono = 0x6
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanHigh

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanHigh = 0x3
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanLow

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanLow = 0x1
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanMax = 0x4
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanMed

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanMed = 0x2
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanTurbo

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanTurbo = 0x8
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHAuto = 0
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHLeft

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHLeft = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHLeftMax = 1
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHLeftRight

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHLeftRight = 7
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHMiddle = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHOff

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHOff = 8
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHRight

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHRight = 4
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHRightLeft

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHRightLeft = 6
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHRightMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHRightMax = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVAuto = 0
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVHigh

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVHigh = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVHighest

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVHighest = 1
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVLow

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVLow = 4
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVLowest

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVLowest = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVMiddle = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVOff

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVOff = 6
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVOffset = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVSize

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVSize = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy3DMask

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy3DMask = 0b00010010
+
+ +
+
+ +

◆ kMitsubishiHeavy88CleanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88CleanOffset = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanAuto = 0
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanEcono

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanEcono = 7
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanHigh

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanHigh = 4
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanLow

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanLow = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanMed

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanMed = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanOffset = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanSize

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanSize = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanTurbo

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanTurbo = 6
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingH3D

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingH3D = 0b1110
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHAuto = 0b1000
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHLeft

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHLeft = 0b0101
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHLeftMax = 0b0001
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHLeftRight

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHLeftRight = 0b0110
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHMiddle = 0b1001
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHOff

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHOff = 0b0000
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHOffset1

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHOffset1 = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHOffset2

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHOffset2 = 6
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHRight

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHRight = 0b1101
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHRightLeft

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHRightLeft = 0b1010
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHRightMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHRightMax = 0b0010
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHSize

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHSize = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVAuto = 0b100
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVByte5Offset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVByte5Offset = 1
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVByte5Size

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVByte5Size = 1
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVByte7Offset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVByte7Offset = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVByte7Size

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVByte7Size = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVHigh

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVHigh = 0b001
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVHighest

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVHighest = 0b110
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVLow

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVLow = 0b101
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVLowest

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVLowest = 0b111
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVMiddle = 0b011
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVOff

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVOff = 0b000
+
+ +
+
+ +

◆ kMitsubishiHeavyAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyAuto = 0
+
+ +
+
+ +

◆ kMitsubishiHeavyCleanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyCleanOffset = 5
+
+ +
+
+ +

◆ kMitsubishiHeavyCool

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyCool = 1
+
+ +
+
+ +

◆ kMitsubishiHeavyDry

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyDry = 2
+
+ +
+
+ +

◆ kMitsubishiHeavyFan

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyFan = 3
+
+ +
+
+ +

◆ kMitsubishiHeavyFilterOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyFilterOffset = 6
+
+ +
+
+ +

◆ kMitsubishiHeavyHeat

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyHeat = 4
+
+ +
+
+ +

◆ kMitsubishiHeavyMaxTemp

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyMaxTemp = 31
+
+ +
+
+ +

◆ kMitsubishiHeavyMinTemp

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyMinTemp = 17
+
+ +
+
+ +

◆ kMitsubishiHeavyModeOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyModeOffset = 0
+
+ +
+
+ +

◆ kMitsubishiHeavyNightOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyNightOffset = 6
+
+ +
+
+ +

◆ kMitsubishiHeavyPowerOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyPowerOffset = 3
+
+ +
+
+ +

◆ kMitsubishiHeavySigLength

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavySigLength = 5
+
+ +
+
+ +

◆ kMitsubishiHeavySilentOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavySilentOffset = 7
+
+ +
+
+ +

◆ kMitsubishiHeavyZjsSig

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyZjsSig[kMitsubishiHeavySigLength]
+
+Initial value:
= {
+
0xAD, 0x51, 0x3C, 0xD9, 0x26}
+
+
+
+ +

◆ kMitsubishiHeavyZmsSig

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyZmsSig[kMitsubishiHeavySigLength]
+
+Initial value:
= {
+
0xAD, 0x51, 0x3C, 0xE5, 0x1A}
+
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html new file mode 100644 index 000000000..eed842d5d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html @@ -0,0 +1,536 @@ + + + + + + + +IRremoteESP8266: src/ir_MitsubishiHeavy.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_MitsubishiHeavy.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
2 
+
12 
+
13 // Supports:
+
14 // Brand: Mitsubishi Heavy Industries, Model: RLA502A700B remote (152 bit)
+
15 // Brand: Mitsubishi Heavy Industries, Model: SRKxxZM-S A/C (152 bit)
+
16 // Brand: Mitsubishi Heavy Industries, Model: SRKxxZMXA-S A/C (152 bit)
+
17 // Brand: Mitsubishi Heavy Industries, Model: RKX502A001C remote (88 bit)
+
18 // Brand: Mitsubishi Heavy Industries, Model: SRKxxZJ-S A/C (88 bit)
+
19 
+
20 #ifndef IR_MITSUBISHIHEAVY_H_
+
21 #define IR_MITSUBISHIHEAVY_H_
+
22 
+
23 #ifndef UNIT_TEST
+
24 #include <Arduino.h>
+
25 #endif
+
26 #include "IRremoteESP8266.h"
+
27 #include "IRsend.h"
+
28 #ifdef UNIT_TEST
+
29 #include "IRsend_test.h"
+
30 #endif
+
31 
+
32 // Constants.
+
33 const uint8_t kMitsubishiHeavySigLength = 5;
+
34 
+
35 // ZMS (152 bit)
+ +
37  0xAD, 0x51, 0x3C, 0xE5, 0x1A};
+
38 // Byte[5]
+
39 const uint8_t kMitsubishiHeavyModeOffset = 0;
+
40 // Mode Mask = 0b00000111; // Byte 9 on ZJS
+
41 const uint8_t kMitsubishiHeavyAuto = 0; // 0b000
+
42 const uint8_t kMitsubishiHeavyCool = 1; // 0b001
+
43 const uint8_t kMitsubishiHeavyDry = 2; // 0b010
+
44 const uint8_t kMitsubishiHeavyFan = 3; // 0b011
+
45 const uint8_t kMitsubishiHeavyHeat = 4; // 0b100
+
46 const uint8_t kMitsubishiHeavyPowerOffset = 3; // Byte 9 on ZJS
+
47 const uint8_t kMitsubishiHeavyCleanOffset = 5;
+
48 const uint8_t kMitsubishiHeavyFilterOffset = 6;
+
49 // Byte[7]
+
50 const uint8_t kMitsubishiHeavyMinTemp = 17; // 17C
+
51 const uint8_t kMitsubishiHeavyMaxTemp = 31; // 31C
+
52 // Byte[9]
+
53 // FanMask = 0b00001111; // ~Byte 7 on ZJS.
+
54 const uint8_t kMitsubishiHeavy152FanAuto = 0x0; // 0b0000
+
55 const uint8_t kMitsubishiHeavy152FanLow = 0x1; // 0b0001
+
56 const uint8_t kMitsubishiHeavy152FanMed = 0x2; // 0b0010
+
57 const uint8_t kMitsubishiHeavy152FanHigh = 0x3; // 0b0011
+
58 const uint8_t kMitsubishiHeavy152FanMax = 0x4; // 0b0100
+
59 const uint8_t kMitsubishiHeavy152FanEcono = 0x6; // 0b0110
+
60 const uint8_t kMitsubishiHeavy152FanTurbo = 0x8; // 0b1000
+
61 // Byte[11]
+
62 const uint8_t kMitsubishiHeavy3DMask = 0b00010010;
+ +
64 const uint8_t kMitsubishiHeavy152SwingVSize = 3; // Bits
+
65 const uint8_t kMitsubishiHeavy152SwingVAuto = 0; // 0b000
+
66 const uint8_t kMitsubishiHeavy152SwingVHighest = 1; // 0b001
+
67 const uint8_t kMitsubishiHeavy152SwingVHigh = 2; // 0b010
+
68 const uint8_t kMitsubishiHeavy152SwingVMiddle = 3; // 0b011
+
69 const uint8_t kMitsubishiHeavy152SwingVLow = 4; // 0b100
+
70 const uint8_t kMitsubishiHeavy152SwingVLowest = 5; // 0b101
+
71 const uint8_t kMitsubishiHeavy152SwingVOff = 6; // 0b110
+
72 // Byte[13]
+
73 const uint8_t kMitsubishiHeavy152SwingHAuto = 0; // 0b0000
+
74 const uint8_t kMitsubishiHeavy152SwingHLeftMax = 1; // 0b0001
+
75 const uint8_t kMitsubishiHeavy152SwingHLeft = 2; // 0b0010
+
76 const uint8_t kMitsubishiHeavy152SwingHMiddle = 3; // 0b0011
+
77 const uint8_t kMitsubishiHeavy152SwingHRight = 4; // 0b0100
+
78 const uint8_t kMitsubishiHeavy152SwingHRightMax = 5; // 0b0101
+
79 const uint8_t kMitsubishiHeavy152SwingHRightLeft = 6; // 0b0110
+
80 const uint8_t kMitsubishiHeavy152SwingHLeftRight = 7; // 0b0111
+
81 const uint8_t kMitsubishiHeavy152SwingHOff = 8; // 0b1000
+
82 // Byte[15]
+
83 const uint8_t kMitsubishiHeavyNightOffset = 6;
+
84 const uint8_t kMitsubishiHeavySilentOffset = 7;
+
85 
+
86 
+
87 // ZJS (88 bit)
+ +
89  0xAD, 0x51, 0x3C, 0xD9, 0x26};
+
90 // Byte [5]
+ + + +
94 const uint8_t kMitsubishiHeavy88SwingHSize = 2; // Bits (per offset)
+
95 const uint8_t kMitsubishiHeavy88SwingHOff = 0b0000;
+
96 const uint8_t kMitsubishiHeavy88SwingHAuto = 0b1000;
+
97 const uint8_t kMitsubishiHeavy88SwingHLeftMax = 0b0001;
+
98 const uint8_t kMitsubishiHeavy88SwingHLeft = 0b0101;
+
99 const uint8_t kMitsubishiHeavy88SwingHMiddle = 0b1001;
+
100 const uint8_t kMitsubishiHeavy88SwingHRight = 0b1101;
+
101 const uint8_t kMitsubishiHeavy88SwingHRightMax = 0b0010;
+
102 const uint8_t kMitsubishiHeavy88SwingHRightLeft = 0b1010;
+
103 const uint8_t kMitsubishiHeavy88SwingHLeftRight = 0b0110;
+
104 const uint8_t kMitsubishiHeavy88SwingH3D = 0b1110;
+
105 // Byte[7]
+
106 const uint8_t kMitsubishiHeavy88FanOffset = 5;
+
107 const uint8_t kMitsubishiHeavy88FanSize = 3; // Bits
+
108 const uint8_t kMitsubishiHeavy88FanAuto = 0; // 0b000
+
109 const uint8_t kMitsubishiHeavy88FanLow = 2; // 0b010
+
110 const uint8_t kMitsubishiHeavy88FanMed = 3; // 0b011
+
111 const uint8_t kMitsubishiHeavy88FanHigh = 4; // 0b100
+
112 const uint8_t kMitsubishiHeavy88FanTurbo = 6; // 0b110
+
113 const uint8_t kMitsubishiHeavy88FanEcono = 7; // 0b111
+ + + + +
118 
+
119  // Mask 0b111
+
120 const uint8_t kMitsubishiHeavy88SwingVOff = 0b000; // 0
+
121 const uint8_t kMitsubishiHeavy88SwingVAuto = 0b100; // 4
+
122 const uint8_t kMitsubishiHeavy88SwingVHighest = 0b110; // 6
+
123 const uint8_t kMitsubishiHeavy88SwingVHigh = 0b001; // 1
+
124 const uint8_t kMitsubishiHeavy88SwingVMiddle = 0b011; // 3
+
125 const uint8_t kMitsubishiHeavy88SwingVLow = 0b101; // 5
+
126 const uint8_t kMitsubishiHeavy88SwingVLowest = 0b111; // 7
+
127 // Byte[9] is Power & Mode & Temp.
+
128 
+
129 
+
130 // Classes
+
131 
+ +
134  public:
+
135  explicit IRMitsubishiHeavy152Ac(const uint16_t pin,
+
136  const bool inverted = false,
+
137  const bool use_modulation = true);
+
138  void stateReset(void);
+
139 #if SEND_MITSUBISHIHEAVY
+
140  void send(const uint16_t repeat = kMitsubishiHeavy152MinRepeat);
+
145  int8_t calibrate(void) { return _irsend.calibrate(); }
+
146 #endif // SEND_MITSUBISHIHEAVY
+
147  void begin(void);
+
148  void on(void);
+
149  void off(void);
+
150 
+
151  void setPower(const bool on);
+
152  bool getPower(void);
+
153 
+
154  void setTemp(const uint8_t temp);
+
155  uint8_t getTemp(void);
+
156 
+
157  void setFan(const uint8_t fan);
+
158  uint8_t getFan(void);
+
159 
+
160  void setMode(const uint8_t mode);
+
161  uint8_t getMode(void);
+
162 
+
163  void setSwingVertical(const uint8_t pos);
+
164  uint8_t getSwingVertical(void);
+
165  void setSwingHorizontal(const uint8_t pos);
+
166  uint8_t getSwingHorizontal(void);
+
167 
+
168  void setNight(const bool on);
+
169  bool getNight(void);
+
170 
+
171  void set3D(const bool on);
+
172  bool get3D(void);
+
173 
+
174  void setSilent(const bool on);
+
175  bool getSilent(void);
+
176 
+
177  void setFilter(const bool on);
+
178  bool getFilter(void);
+
179 
+
180  void setClean(const bool on);
+
181  bool getClean(void);
+
182 
+
183  void setTurbo(const bool on);
+
184  bool getTurbo(void);
+
185 
+
186  void setEcono(const bool on);
+
187  bool getEcono(void);
+
188 
+
189  uint8_t* getRaw(void);
+
190  void setRaw(const uint8_t* data);
+
191 
+
192  static bool checkZmsSig(const uint8_t *state);
+
193  static bool validChecksum(
+
194  const uint8_t *state,
+
195  const uint16_t length = kMitsubishiHeavy152StateLength);
+
196  static uint8_t convertMode(const stdAc::opmode_t mode);
+
197  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
198  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
199  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
200  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
201  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
202  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
203  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
204  stdAc::state_t toCommon(void);
+
205  String toString(void);
+
206 #ifndef UNIT_TEST
+
207 
+
208  private:
+ +
210 #else // UNIT_TEST
+
211  IRsendTest _irsend;
+
213 #endif // UNIT_TEST
+ +
216  void checksum(void);
+
217 };
+
218 
+ +
221  public:
+
222  explicit IRMitsubishiHeavy88Ac(const uint16_t pin,
+
223  const bool inverted = false,
+
224  const bool use_modulation = true);
+
225  void stateReset(void);
+
226 #if SEND_MITSUBISHIHEAVY
+
227  void send(const uint16_t repeat = kMitsubishiHeavy88MinRepeat);
+
232  int8_t calibrate(void) { return _irsend.calibrate(); }
+
233 #endif // SEND_MITSUBISHIHEAVY
+
234  void begin(void);
+
235  void on(void);
+
236  void off(void);
+
237 
+
238  void setPower(const bool on);
+
239  bool getPower(void);
+
240 
+
241  void setTemp(const uint8_t temp);
+
242  uint8_t getTemp(void);
+
243 
+
244  void setFan(const uint8_t fan);
+
245  uint8_t getFan(void);
+
246 
+
247  void setMode(const uint8_t mode);
+
248  uint8_t getMode(void);
+
249 
+
250  void setSwingVertical(const uint8_t pos);
+
251  uint8_t getSwingVertical(void);
+
252  void setSwingHorizontal(const uint8_t pos);
+
253  uint8_t getSwingHorizontal(void);
+
254 
+
255  void setTurbo(const bool on);
+
256  bool getTurbo(void);
+
257 
+
258  void setEcono(const bool on);
+
259  bool getEcono(void);
+
260 
+
261  void set3D(const bool on);
+
262  bool get3D(void);
+
263 
+
264  void setClean(const bool on);
+
265  bool getClean(void);
+
266 
+
267  uint8_t* getRaw(void);
+
268  void setRaw(const uint8_t* data);
+
269 
+
270  static bool checkZjsSig(const uint8_t *state);
+
271  static bool validChecksum(
+
272  const uint8_t *state,
+
273  const uint16_t length = kMitsubishiHeavy88StateLength);
+
274  static uint8_t convertMode(const stdAc::opmode_t mode);
+
275  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
276  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
277  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
278  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
279  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
280  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
281  stdAc::state_t toCommon(void);
+
282  String toString(void);
+
283 #ifndef UNIT_TEST
+
284 
+
285  private:
+ +
287 #else // UNIT_TEST
+
288  IRsendTest _irsend;
+
290 #endif // UNIT_TEST
+ +
293  void checksum(void);
+
294 };
+
295 #endif // IR_MITSUBISHIHEAVY_H_
+
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_MitsubishiHeavy.cpp:976
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_MitsubishiHeavy.cpp:688
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_MitsubishiHeavy.cpp:655
+
const uint8_t kMitsubishiHeavy88SwingVByte5Size
Definition: ir_MitsubishiHeavy.h:115
+
const uint16_t kMitsubishiHeavy152StateLength
Definition: IRremoteESP8266.h:942
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_MitsubishiHeavy.h:145
+
Class for handling detailed Mitsubishi Heavy 152-bit A/C messages.
Definition: ir_MitsubishiHeavy.h:133
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_MitsubishiHeavy.cpp:632
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_MitsubishiHeavy.cpp:1002
+
void checksum(void)
Calculate the checksum for the current internal state of the remote. Note: Technically it has no chec...
Definition: ir_MitsubishiHeavy.cpp:325
+
const uint8_t kMitsubishiHeavy152SwingVHigh
Definition: ir_MitsubishiHeavy.h:67
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_MitsubishiHeavy.cpp:398
+
const uint8_t kMitsubishiHeavy152SwingHRightLeft
Definition: ir_MitsubishiHeavy.h:79
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_MitsubishiHeavy.cpp:355
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_MitsubishiHeavy.cpp:665
+
const uint8_t kMitsubishiHeavy3DMask
Definition: ir_MitsubishiHeavy.h:62
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_MitsubishiHeavy.cpp:933
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:310
+
void setPower(const bool on)
Change the power setting.
Definition: ir_MitsubishiHeavy.cpp:123
+
void set3D(const bool on)
Set the 3D mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:824
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
const uint8_t kMitsubishiHeavy152FanMed
Definition: ir_MitsubishiHeavy.h:56
+
const uint8_t kMitsubishiHeavyCleanOffset
Definition: ir_MitsubishiHeavy.h:47
+
void setSwingHorizontal(const uint8_t pos)
Set the Horizontal Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:763
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_MitsubishiHeavy.h:209
+
const uint8_t kMitsubishiHeavy152FanAuto
Definition: ir_MitsubishiHeavy.h:54
+
IRMitsubishiHeavy152Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_MitsubishiHeavy.cpp:77
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kMitsubishiHeavy152SwingVAuto
Definition: ir_MitsubishiHeavy.h:65
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:711
+
const uint8_t kMitsubishiHeavy88FanTurbo
Definition: ir_MitsubishiHeavy.h:112
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_MitsubishiHeavy.cpp:888
+
const uint8_t kMitsubishiHeavy88SwingHLeftMax
Definition: ir_MitsubishiHeavy.h:97
+
const uint8_t kMitsubishiHeavy152SwingVHighest
Definition: ir_MitsubishiHeavy.h:66
+
const uint8_t kMitsubishiHeavy88SwingH3D
Definition: ir_MitsubishiHeavy.h:104
+
const uint8_t kMitsubishiHeavy88SwingHLeft
Definition: ir_MitsubishiHeavy.h:98
+
const uint8_t kMitsubishiHeavy152SwingVLow
Definition: ir_MitsubishiHeavy.h:69
+
const uint8_t kMitsubishiHeavyNightOffset
Definition: ir_MitsubishiHeavy.h:83
+
const uint8_t kMitsubishiHeavy152SwingHOff
Definition: ir_MitsubishiHeavy.h:81
+
const uint8_t kMitsubishiHeavy88SwingHOffset1
Definition: ir_MitsubishiHeavy.h:92
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_MitsubishiHeavy.cpp:129
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_MitsubishiHeavy.cpp:95
+ +
const uint8_t kMitsubishiHeavy152SwingHLeftRight
Definition: ir_MitsubishiHeavy.h:80
+
void checksum(void)
Calculate the checksum for the current internal state of the remote. Note: Technically it has no chec...
Definition: ir_MitsubishiHeavy.cpp:860
+
const uint8_t kMitsubishiHeavy88SwingHMiddle
Definition: ir_MitsubishiHeavy.h:99
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_MitsubishiHeavy.cpp:426
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_MitsubishiHeavy.cpp:652
+
bool getTurbo(void)
Get the Turbo mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:296
+
const uint8_t kMitsubishiHeavy88SwingVAuto
Definition: ir_MitsubishiHeavy.h:121
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_MitsubishiHeavy.cpp:495
+
void setClean(const bool on)
Set the Clean mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:839
+
void setSilent(const bool on)
Set the Silent (Quiet) mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:251
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kMitsubishiHeavy88FanEcono
Definition: ir_MitsubishiHeavy.h:113
+
void setSwingVertical(const uint8_t pos)
Set the Vertical Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:733
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_MitsubishiHeavy.cpp:145
+
const uint8_t kMitsubishiHeavy88SwingHSize
Definition: ir_MitsubishiHeavy.h:94
+
void setClean(const bool on)
Set the Clean mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:275
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_MitsubishiHeavy.cpp:135
+
const uint8_t kMitsubishiHeavyPowerOffset
Definition: ir_MitsubishiHeavy.h:46
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_MitsubishiHeavy.cpp:116
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_MitsubishiHeavy.cpp:83
+
uint8_t getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:753
+
const uint8_t kMitsubishiHeavyFilterOffset
Definition: ir_MitsubishiHeavy.h:48
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_MitsubishiHeavy.cpp:903
+
void setNight(const bool on)
Set the Night (Sleep) mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:224
+
const uint8_t kMitsubishiHeavy88SwingHOffset2
Definition: ir_MitsubishiHeavy.h:93
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_MitsubishiHeavy.h:286
+
const uint8_t kMitsubishiHeavy152SwingVSize
Definition: ir_MitsubishiHeavy.h:64
+
const uint8_t kMitsubishiHeavySigLength
Definition: ir_MitsubishiHeavy.h:33
+
uint8_t getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:204
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_MitsubishiHeavy.cpp:119
+
void setSwingVertical(const uint8_t pos)
Set the Vertical Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:196
+
const uint8_t kMitsubishiHeavy88SwingHRightLeft
Definition: ir_MitsubishiHeavy.h:102
+
uint8_t remote_state[kMitsubishiHeavy88StateLength]
State in code form.
Definition: ir_MitsubishiHeavy.h:292
+
const uint8_t kMitsubishiHeavy152SwingHRight
Definition: ir_MitsubishiHeavy.h:77
+
uint8_t getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:786
+
const uint8_t kMitsubishiHeavyHeat
Definition: ir_MitsubishiHeavy.h:45
+
uint8_t getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:218
+
void setTurbo(const bool on)
Set the Turbo mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:796
+
bool getNight(void)
Get the Night (Sleep) mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:230
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_MitsubishiHeavy.cpp:704
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
const uint8_t kMitsubishiHeavy152SwingHLeftMax
Definition: ir_MitsubishiHeavy.h:74
+
bool getClean(void)
Get the Clean mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:282
+
const uint8_t kMitsubishiHeavyZmsSig[kMitsubishiHeavySigLength]
Definition: ir_MitsubishiHeavy.h:36
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:818
+
const uint16_t kMitsubishiHeavy152MinRepeat
Definition: IRremoteESP8266.h:944
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_MitsubishiHeavy.h:232
+
const uint8_t kMitsubishiHeavy88SwingVByte5Offset
Definition: ir_MitsubishiHeavy.h:114
+
static bool checkZjsSig(const uint8_t *state)
Verify the given state has a ZJ-S signature.
Definition: ir_MitsubishiHeavy.cpp:852
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_MitsubishiHeavy.cpp:671
+
IRMitsubishiHeavy88Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_MitsubishiHeavy.cpp:614
+
const uint8_t kMitsubishiHeavy88FanOffset
Definition: ir_MitsubishiHeavy.h:106
+
const uint8_t kMitsubishiHeavyMaxTemp
Definition: ir_MitsubishiHeavy.h:51
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_MitsubishiHeavy.cpp:647
+
const uint16_t kMitsubishiHeavy88StateLength
Definition: IRremoteESP8266.h:939
+
const uint8_t kMitsubishiHeavy88SwingVMiddle
Definition: ir_MitsubishiHeavy.h:124
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_MitsubishiHeavy.cpp:368
+
const uint8_t kMitsubishiHeavyZjsSig[kMitsubishiHeavySigLength]
Definition: ir_MitsubishiHeavy.h:88
+
const uint8_t kMitsubishiHeavy152FanLow
Definition: ir_MitsubishiHeavy.h:55
+
const uint8_t kMitsubishiHeavy88FanHigh
Definition: ir_MitsubishiHeavy.h:111
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_MitsubishiHeavy.cpp:413
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_MitsubishiHeavy.cpp:104
+
const uint8_t kMitsubishiHeavyMinTemp
Definition: ir_MitsubishiHeavy.h:50
+
const uint8_t kMitsubishiHeavyCool
Definition: ir_MitsubishiHeavy.h:42
+
void setEcono(const bool on)
Set the Economical mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:302
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_MitsubishiHeavy.cpp:681
+
bool getSilent(void)
Get the Silent (Quiet) mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:257
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_MitsubishiHeavy.cpp:640
+
const uint8_t kMitsubishiHeavy88FanLow
Definition: ir_MitsubishiHeavy.h:109
+
const uint8_t kMitsubishiHeavy88SwingVLow
Definition: ir_MitsubishiHeavy.h:125
+
static bool checkZmsSig(const uint8_t *state)
Verify the given state has a ZM-S signature.
Definition: ir_MitsubishiHeavy.cpp:317
+
const uint8_t kMitsubishiHeavy152SwingVMiddle
Definition: ir_MitsubishiHeavy.h:68
+
const uint8_t kMitsubishiHeavy88SwingHRight
Definition: ir_MitsubishiHeavy.h:100
+
const uint8_t kMitsubishiHeavy88SwingVHighest
Definition: ir_MitsubishiHeavy.h:122
+
const uint8_t kMitsubishiHeavyModeOffset
Definition: ir_MitsubishiHeavy.h:39
+
const uint8_t kMitsubishiHeavy88SwingVOff
Definition: ir_MitsubishiHeavy.h:120
+
bool getTurbo(void)
Get the Turbo mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:804
+
void setEcono(const bool on)
Set the Economical mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:810
+
const uint8_t kMitsubishiHeavy88SwingVLowest
Definition: ir_MitsubishiHeavy.h:126
+
const uint8_t kMitsubishiHeavy152SwingHAuto
Definition: ir_MitsubishiHeavy.h:73
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_MitsubishiHeavy.cpp:190
+
const uint8_t kMitsubishiHeavy152SwingHLeft
Definition: ir_MitsubishiHeavy.h:75
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_MitsubishiHeavy.cpp:152
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_MitsubishiHeavy.cpp:469
+
const uint8_t kMitsubishiHeavySilentOffset
Definition: ir_MitsubishiHeavy.h:84
+
bool getClean(void)
Get the Clean mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:845
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_MitsubishiHeavy.cpp:881
+
const uint8_t kMitsubishiHeavy88SwingHAuto
Definition: ir_MitsubishiHeavy.h:96
+
const uint8_t kMitsubishiHeavyFan
Definition: ir_MitsubishiHeavy.h:44
+
const uint16_t kMitsubishiHeavy88MinRepeat
Definition: IRremoteESP8266.h:941
+
const uint8_t kMitsubishiHeavy88SwingHOff
Definition: ir_MitsubishiHeavy.h:95
+
void setSwingHorizontal(const uint8_t pos)
Set the Horizontal Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:211
+
static bool validChecksum(const uint8_t *state, const uint16_t length=kMitsubishiHeavy152StateLength)
Verify the checksum is valid for a given state.
Definition: ir_MitsubishiHeavy.cpp:338
+
const uint8_t kMitsubishiHeavy152SwingVOff
Definition: ir_MitsubishiHeavy.h:71
+
const uint8_t kMitsubishiHeavy152SwingVLowest
Definition: ir_MitsubishiHeavy.h:70
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_MitsubishiHeavy.cpp:111
+
const uint8_t kMitsubishiHeavy88SwingHLeftRight
Definition: ir_MitsubishiHeavy.h:103
+
const uint8_t kMitsubishiHeavy88FanAuto
Definition: ir_MitsubishiHeavy.h:108
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:174
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_MitsubishiHeavy.cpp:440
+
const uint8_t kMitsubishiHeavy88FanMed
Definition: ir_MitsubishiHeavy.h:110
+
void setTurbo(const bool on)
Set the Turbo mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:288
+
uint8_t remote_state[kMitsubishiHeavy152StateLength]
State in code form.
Definition: ir_MitsubishiHeavy.h:215
+
bool getFilter(void)
Get the Filter mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:269
+
bool get3D(void)
Get the 3D mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:833
+
const uint8_t kMitsubishiHeavy88SwingHRightMax
Definition: ir_MitsubishiHeavy.h:101
+
const uint8_t kMitsubishiHeavy152SwingVOffset
Definition: ir_MitsubishiHeavy.h:63
+
void setPower(const bool on)
Change the power setting.
Definition: ir_MitsubishiHeavy.cpp:659
+
const uint8_t kMitsubishiHeavy88SwingVByte7Size
Definition: ir_MitsubishiHeavy.h:117
+
const uint8_t kMitsubishiHeavy152FanHigh
Definition: ir_MitsubishiHeavy.h:57
+
void setFilter(const bool on)
Set the Filter mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:263
+
static bool validChecksum(const uint8_t *state, const uint16_t length=kMitsubishiHeavy88StateLength)
Verify the checksum is valid for a given state.
Definition: ir_MitsubishiHeavy.cpp:873
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_MitsubishiHeavy.cpp:620
+
const uint8_t kMitsubishiHeavy152SwingHRightMax
Definition: ir_MitsubishiHeavy.h:78
+
void set3D(const bool on)
Set the 3D mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:236
+
const uint8_t kMitsubishiHeavy152SwingHMiddle
Definition: ir_MitsubishiHeavy.h:76
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_MitsubishiHeavy.cpp:383
+
Class for handling detailed Mitsubishi Heavy 88-bit A/C messages.
Definition: ir_MitsubishiHeavy.h:220
+
const uint8_t kMitsubishiHeavy152FanTurbo
Definition: ir_MitsubishiHeavy.h:60
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_MitsubishiHeavy.cpp:455
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_MitsubishiHeavy.cpp:918
+
const uint8_t kMitsubishiHeavyDry
Definition: ir_MitsubishiHeavy.h:43
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_MitsubishiHeavy.cpp:168
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_MitsubishiHeavy.cpp:947
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kMitsubishiHeavy88FanSize
Definition: ir_MitsubishiHeavy.h:107
+
const uint8_t kMitsubishiHeavy88SwingVByte7Offset
Definition: ir_MitsubishiHeavy.h:116
+
const uint8_t kMitsubishiHeavy88SwingVHigh
Definition: ir_MitsubishiHeavy.h:123
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_MitsubishiHeavy.cpp:962
+
void send(const uint16_t repeat=kMitsubishiHeavy88MinRepeat)
Send the current internal state as an IR message.
Definition: ir_MitsubishiHeavy.cpp:625
+
void send(const uint16_t repeat=kMitsubishiHeavy152MinRepeat)
Send the current internal state as an IR message.
Definition: ir_MitsubishiHeavy.cpp:88
+
const uint8_t kMitsubishiHeavy88CleanOffset
Definition: ir_MitsubishiHeavy.h:91
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_MitsubishiHeavy.cpp:727
+
const uint8_t kMitsubishiHeavyAuto
Definition: ir_MitsubishiHeavy.h:41
+
const uint8_t kMitsubishiHeavy152FanEcono
Definition: ir_MitsubishiHeavy.h:59
+
bool get3D(void)
Get the 3D mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:245
+
const uint8_t kMitsubishiHeavy152FanMax
Definition: ir_MitsubishiHeavy.h:58
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8cpp.html new file mode 100644 index 000000000..ae23abaec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8cpp.html @@ -0,0 +1,722 @@ + + + + + + + +IRremoteESP8266: src/ir_Mitsubishi.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Mitsubishi.cpp File Reference
+
+
+ +

Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kMitsubishiTick = 30
 
const uint16_t kMitsubishiBitMarkTicks = 10
 
const uint16_t kMitsubishiBitMark = kMitsubishiBitMarkTicks * kMitsubishiTick
 
const uint16_t kMitsubishiOneSpaceTicks = 70
 
const uint16_t kMitsubishiOneSpace = kMitsubishiOneSpaceTicks * kMitsubishiTick
 
const uint16_t kMitsubishiZeroSpaceTicks = 30
 
const uint16_t kMitsubishiZeroSpace
 
const uint16_t kMitsubishiMinCommandLengthTicks = 1786
 
const uint16_t kMitsubishiMinCommandLength
 
const uint16_t kMitsubishiMinGapTicks = 936
 
const uint16_t kMitsubishiMinGap = kMitsubishiMinGapTicks * kMitsubishiTick
 
const uint16_t kMitsubishi2HdrMark = 8400
 
const uint16_t kMitsubishi2HdrSpace = kMitsubishi2HdrMark / 2
 
const uint16_t kMitsubishi2BitMark = 560
 
const uint16_t kMitsubishi2ZeroSpace = 520
 
const uint16_t kMitsubishi2OneSpace = kMitsubishi2ZeroSpace * 3
 
const uint16_t kMitsubishi2MinGap = 28500
 
const uint16_t kMitsubishiAcHdrMark = 3400
 
const uint16_t kMitsubishiAcHdrSpace = 1750
 
const uint16_t kMitsubishiAcBitMark = 450
 
const uint16_t kMitsubishiAcOneSpace = 1300
 
const uint16_t kMitsubishiAcZeroSpace = 420
 
const uint16_t kMitsubishiAcRptMark = 440
 
const uint16_t kMitsubishiAcRptSpace = 17100
 
const uint8_t kMitsubishiAcExtraTolerance = 5
 
const uint16_t kMitsubishi136HdrMark = 3324
 
const uint16_t kMitsubishi136HdrSpace = 1474
 
const uint16_t kMitsubishi136BitMark = 467
 
const uint16_t kMitsubishi136OneSpace = 1137
 
const uint16_t kMitsubishi136ZeroSpace = 351
 
const uint32_t kMitsubishi136Gap = kDefaultMessageGap
 
const uint16_t kMitsubishi112HdrMark = 3450
 
const uint16_t kMitsubishi112HdrSpace = 1696
 
const uint16_t kMitsubishi112BitMark = 450
 
const uint16_t kMitsubishi112OneSpace = 1250
 
const uint16_t kMitsubishi112ZeroSpace = 385
 
const uint32_t kMitsubishi112Gap = kDefaultMessageGap
 
const uint8_t kMitsubishi112HdrMarkTolerance = 5
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMitsubishi112BitMark

+ +
+
+ + + + +
const uint16_t kMitsubishi112BitMark = 450
+
+ +
+
+ +

◆ kMitsubishi112Gap

+ +
+
+ + + + +
const uint32_t kMitsubishi112Gap = kDefaultMessageGap
+
+ +
+
+ +

◆ kMitsubishi112HdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishi112HdrMark = 3450
+
+ +
+
+ +

◆ kMitsubishi112HdrMarkTolerance

+ +
+
+ + + + +
const uint8_t kMitsubishi112HdrMarkTolerance = 5
+
+ +
+
+ +

◆ kMitsubishi112HdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi112HdrSpace = 1696
+
+ +
+
+ +

◆ kMitsubishi112OneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi112OneSpace = 1250
+
+ +
+
+ +

◆ kMitsubishi112ZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi112ZeroSpace = 385
+
+ +
+
+ +

◆ kMitsubishi136BitMark

+ +
+
+ + + + +
const uint16_t kMitsubishi136BitMark = 467
+
+ +
+
+ +

◆ kMitsubishi136Gap

+ +
+
+ + + + +
const uint32_t kMitsubishi136Gap = kDefaultMessageGap
+
+ +
+
+ +

◆ kMitsubishi136HdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishi136HdrMark = 3324
+
+ +
+
+ +

◆ kMitsubishi136HdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi136HdrSpace = 1474
+
+ +
+
+ +

◆ kMitsubishi136OneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi136OneSpace = 1137
+
+ +
+
+ +

◆ kMitsubishi136ZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi136ZeroSpace = 351
+
+ +
+
+ +

◆ kMitsubishi2BitMark

+ +
+
+ + + + +
const uint16_t kMitsubishi2BitMark = 560
+
+ +
+
+ +

◆ kMitsubishi2HdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishi2HdrMark = 8400
+
+ +
+
+ +

◆ kMitsubishi2HdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi2HdrSpace = kMitsubishi2HdrMark / 2
+
+ +
+
+ +

◆ kMitsubishi2MinGap

+ +
+
+ + + + +
const uint16_t kMitsubishi2MinGap = 28500
+
+ +
+
+ +

◆ kMitsubishi2OneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi2OneSpace = kMitsubishi2ZeroSpace * 3
+
+ +
+
+ +

◆ kMitsubishi2ZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi2ZeroSpace = 520
+
+ +
+
+ +

◆ kMitsubishiAcBitMark

+ +
+
+ + + + +
const uint16_t kMitsubishiAcBitMark = 450
+
+ +
+
+ +

◆ kMitsubishiAcExtraTolerance

+ +
+
+ + + + +
const uint8_t kMitsubishiAcExtraTolerance = 5
+
+ +
+
+ +

◆ kMitsubishiAcHdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishiAcHdrMark = 3400
+
+ +
+
+ +

◆ kMitsubishiAcHdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiAcHdrSpace = 1750
+
+ +
+
+ +

◆ kMitsubishiAcOneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiAcOneSpace = 1300
+
+ +
+
+ +

◆ kMitsubishiAcRptMark

+ +
+
+ + + + +
const uint16_t kMitsubishiAcRptMark = 440
+
+ +
+
+ +

◆ kMitsubishiAcRptSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiAcRptSpace = 17100
+
+ +
+
+ +

◆ kMitsubishiAcZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiAcZeroSpace = 420
+
+ +
+
+ +

◆ kMitsubishiBitMark

+ +
+
+ + + + +
const uint16_t kMitsubishiBitMark = kMitsubishiBitMarkTicks * kMitsubishiTick
+
+ +
+
+ +

◆ kMitsubishiBitMarkTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiBitMarkTicks = 10
+
+ +
+
+ +

◆ kMitsubishiMinCommandLength

+ +
+
+ + + + +
const uint16_t kMitsubishiMinCommandLength
+
+
+ +

◆ kMitsubishiMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiMinCommandLengthTicks = 1786
+
+ +
+
+ +

◆ kMitsubishiMinGap

+ +
+
+ + + + +
const uint16_t kMitsubishiMinGap = kMitsubishiMinGapTicks * kMitsubishiTick
+
+ +
+
+ +

◆ kMitsubishiMinGapTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiMinGapTicks = 936
+
+ +
+
+ +

◆ kMitsubishiOneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiOneSpace = kMitsubishiOneSpaceTicks * kMitsubishiTick
+
+ +
+
+ +

◆ kMitsubishiOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiOneSpaceTicks = 70
+
+ +
+
+ +

◆ kMitsubishiTick

+ +
+
+ + + + +
const uint16_t kMitsubishiTick = 30
+
+ +
+
+ +

◆ kMitsubishiZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiZeroSpace
+
+Initial value: +
+
+ +

◆ kMitsubishiZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiZeroSpaceTicks = 30
+
+ +
+
+
+
const uint16_t kMitsubishiTick
Definition: ir_Mitsubishi.cpp:34
+
const uint16_t kMitsubishiMinCommandLengthTicks
Definition: ir_Mitsubishi.cpp:42
+
const uint16_t kMitsubishiZeroSpaceTicks
Definition: ir_Mitsubishi.cpp:39
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h.html new file mode 100644 index 000000000..968bfbb6c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h.html @@ -0,0 +1,1609 @@ + + + + + + + +IRremoteESP8266: src/ir_Mitsubishi.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Mitsubishi.h File Reference
+
+
+ +

Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + +

+Classes

class  IRMitsubishiAC
 Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control. More...
 
class  IRMitsubishi136
 Class for handling detailed Mitsubishi 136-bit A/C messages. More...
 
class  IRMitsubishi112
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kMitsubishiAcModeOffset = 3
 
const uint8_t kMitsubishiAcAuto = 0b100
 
const uint8_t kMitsubishiAcCool = 0b011
 
const uint8_t kMitsubishiAcDry = 0b010
 
const uint8_t kMitsubishiAcHeat = 0b001
 
const uint8_t kMitsubishiAcPowerOffset = 5
 
const uint8_t kMitsubishiAcPower = 1 << kMitsubishiAcPowerOffset
 
const uint8_t kMitsubishiAcFanOffset = 0
 
const uint8_t kMitsubishiAcFanSize = 3
 
const uint8_t kMitsubishiAcFanAuto = 0
 
const uint8_t kMitsubishiAcFanAutoOffset = 7
 
const uint8_t kMitsubishiAcFanMax = 5
 
const uint8_t kMitsubishiAcFanRealMax = 4
 
const uint8_t kMitsubishiAcFanSilent = 6
 
const uint8_t kMitsubishiAcFanQuiet = kMitsubishiAcFanSilent
 
const uint8_t kMitsubishiAcMinTemp = 16
 
const uint8_t kMitsubishiAcMaxTemp = 31
 
const uint8_t kMitsubishiAcVaneBitOffset = 6
 
const uint8_t kMitsubishiAcVaneOffset = 3
 
const uint8_t kMitsubishiAcVaneSize = 3
 
const uint8_t kMitsubishiAcVaneAuto = 0
 
const uint8_t kMitsubishiAcVaneAutoMove = 7
 
const uint8_t kMitsubishiAcNoTimer = 0
 
const uint8_t kMitsubishiAcStartTimer = 5
 
const uint8_t kMitsubishiAcStopTimer = 3
 
const uint8_t kMitsubishiAcStartStopTimer = 7
 
const uint8_t kMitsubishiAcWideVaneAuto = 8
 
const uint8_t kMitsubishi136PowerByte = 5
 
const uint8_t kMitsubishi136PowerOffset = 6
 
const uint8_t kMitsubishi136PowerBit = 1 << kMitsubishi136PowerOffset
 
const uint8_t kMitsubishi136TempByte = 6
 
const uint8_t kMitsubishi136MinTemp = 17
 
const uint8_t kMitsubishi136MaxTemp = 30
 
const uint8_t kMitsubishi136ModeByte = kMitsubishi136TempByte
 
const uint8_t kMitsubishi136ModeOffset = 0
 
const uint8_t kMitsubishi136Fan = 0b000
 
const uint8_t kMitsubishi136Cool = 0b001
 
const uint8_t kMitsubishi136Heat = 0b010
 
const uint8_t kMitsubishi136Auto = 0b011
 
const uint8_t kMitsubishi136Dry = 0b101
 
const uint8_t kMitsubishi136SwingVByte = 7
 
const uint8_t kMitsubishi136SwingVLowest = 0b0000
 
const uint8_t kMitsubishi136SwingVLow = 0b0001
 
const uint8_t kMitsubishi136SwingVHigh = 0b0010
 
const uint8_t kMitsubishi136SwingVHighest = 0b0011
 
const uint8_t kMitsubishi136SwingVAuto = 0b1100
 
const uint8_t kMitsubishi136FanByte = kMitsubishi136SwingVByte
 
const uint8_t kMitsubishi136FanOffset = 1
 
const uint8_t kMitsubishi136FanSize = 2
 
const uint8_t kMitsubishi136FanMin = 0b00
 
const uint8_t kMitsubishi136FanLow = 0b01
 
const uint8_t kMitsubishi136FanMed = 0b10
 
const uint8_t kMitsubishi136FanMax = 0b11
 
const uint8_t kMitsubishi136FanQuiet = kMitsubishi136FanMin
 
const uint8_t kMitsubishi112PowerByte = 5
 
const uint8_t kMitsubishi112PowerOffset = 2
 
const uint8_t kMitsubishi112ModeByte = 6
 
const uint8_t kMitsubishi112ModeOffset = 0
 
const uint8_t kMitsubishi112Cool = 0b011
 
const uint8_t kMitsubishi112Heat = 0b001
 
const uint8_t kMitsubishi112Auto = 0b111
 
const uint8_t kMitsubishi112Dry = 0b010
 
const uint8_t kMitsubishi112TempByte = 7
 
const uint8_t kMitsubishi112TempSize = 4
 
const uint8_t kMitsubishi112MinTemp = 16
 
const uint8_t kMitsubishi112MaxTemp = 31
 
const uint8_t kMitsubishi112FanByte = 8
 
const uint8_t kMitsubishi112FanOffset = 0
 
const uint8_t kMitsubishi112FanSize = 3
 
const uint8_t kMitsubishi112FanMin = 0b010
 
const uint8_t kMitsubishi112FanLow = 0b011
 
const uint8_t kMitsubishi112FanMed = 0b101
 
const uint8_t kMitsubishi112FanMax = 0b000
 
const uint8_t kMitsubishi112FanQuiet = kMitsubishi112FanMin
 
const uint8_t kMitsubishi112SwingVByte = kMitsubishi112FanByte
 
const uint8_t kMitsubishi112SwingVOffset = 3
 
const uint8_t kMitsubishi112SwingVSize = 3
 
const uint8_t kMitsubishi112SwingVLowest = 0b101
 
const uint8_t kMitsubishi112SwingVLow = 0b100
 
const uint8_t kMitsubishi112SwingVMiddle = 0b011
 
const uint8_t kMitsubishi112SwingVHigh = 0b010
 
const uint8_t kMitsubishi112SwingVHighest = 0b001
 
const uint8_t kMitsubishi112SwingVAuto = 0b111
 
const uint8_t kMitsubishi112SwingHByte = 12
 
const uint8_t kMitsubishi112SwingHSize = 4
 
const uint8_t kMitsubishi112SwingHOffset = 2
 
const uint8_t kMitsubishi112SwingHLeftMax = 0b0001
 
const uint8_t kMitsubishi112SwingHLeft = 0b0010
 
const uint8_t kMitsubishi112SwingHMiddle = 0b0011
 
const uint8_t kMitsubishi112SwingHRight = 0b0100
 
const uint8_t kMitsubishi112SwingHRightMax = 0b0101
 
const uint8_t kMitsubishi112SwingHWide = 0b1000
 
const uint8_t kMitsubishi112SwingHAuto = 0b1100
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMitsubishi112Auto

+ +
+
+ + + + +
const uint8_t kMitsubishi112Auto = 0b111
+
+ +
+
+ +

◆ kMitsubishi112Cool

+ +
+
+ + + + +
const uint8_t kMitsubishi112Cool = 0b011
+
+ +
+
+ +

◆ kMitsubishi112Dry

+ +
+
+ + + + +
const uint8_t kMitsubishi112Dry = 0b010
+
+ +
+
+ +

◆ kMitsubishi112FanByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanByte = 8
+
+ +
+
+ +

◆ kMitsubishi112FanLow

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanLow = 0b011
+
+ +
+
+ +

◆ kMitsubishi112FanMax

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanMax = 0b000
+
+ +
+
+ +

◆ kMitsubishi112FanMed

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanMed = 0b101
+
+ +
+
+ +

◆ kMitsubishi112FanMin

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanMin = 0b010
+
+ +
+
+ +

◆ kMitsubishi112FanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanOffset = 0
+
+ +
+
+ +

◆ kMitsubishi112FanQuiet

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanQuiet = kMitsubishi112FanMin
+
+ +
+
+ +

◆ kMitsubishi112FanSize

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanSize = 3
+
+ +
+
+ +

◆ kMitsubishi112Heat

+ +
+
+ + + + +
const uint8_t kMitsubishi112Heat = 0b001
+
+ +
+
+ +

◆ kMitsubishi112MaxTemp

+ +
+
+ + + + +
const uint8_t kMitsubishi112MaxTemp = 31
+
+ +
+
+ +

◆ kMitsubishi112MinTemp

+ +
+
+ + + + +
const uint8_t kMitsubishi112MinTemp = 16
+
+ +
+
+ +

◆ kMitsubishi112ModeByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112ModeByte = 6
+
+ +
+
+ +

◆ kMitsubishi112ModeOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112ModeOffset = 0
+
+ +
+
+ +

◆ kMitsubishi112PowerByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112PowerByte = 5
+
+ +
+
+ +

◆ kMitsubishi112PowerOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112PowerOffset = 2
+
+ +
+
+ +

◆ kMitsubishi112SwingHAuto

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHAuto = 0b1100
+
+ +
+
+ +

◆ kMitsubishi112SwingHByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHByte = 12
+
+ +
+
+ +

◆ kMitsubishi112SwingHLeft

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHLeft = 0b0010
+
+ +
+
+ +

◆ kMitsubishi112SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHLeftMax = 0b0001
+
+ +
+
+ +

◆ kMitsubishi112SwingHMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHMiddle = 0b0011
+
+ +
+
+ +

◆ kMitsubishi112SwingHOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHOffset = 2
+
+ +
+
+ +

◆ kMitsubishi112SwingHRight

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHRight = 0b0100
+
+ +
+
+ +

◆ kMitsubishi112SwingHRightMax

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHRightMax = 0b0101
+
+ +
+
+ +

◆ kMitsubishi112SwingHSize

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHSize = 4
+
+ +
+
+ +

◆ kMitsubishi112SwingHWide

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHWide = 0b1000
+
+ +
+
+ +

◆ kMitsubishi112SwingVAuto

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVAuto = 0b111
+
+ +
+
+ +

◆ kMitsubishi112SwingVByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVByte = kMitsubishi112FanByte
+
+ +
+
+ +

◆ kMitsubishi112SwingVHigh

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVHigh = 0b010
+
+ +
+
+ +

◆ kMitsubishi112SwingVHighest

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVHighest = 0b001
+
+ +
+
+ +

◆ kMitsubishi112SwingVLow

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVLow = 0b100
+
+ +
+
+ +

◆ kMitsubishi112SwingVLowest

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVLowest = 0b101
+
+ +
+
+ +

◆ kMitsubishi112SwingVMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVMiddle = 0b011
+
+ +
+
+ +

◆ kMitsubishi112SwingVOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVOffset = 3
+
+ +
+
+ +

◆ kMitsubishi112SwingVSize

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVSize = 3
+
+ +
+
+ +

◆ kMitsubishi112TempByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112TempByte = 7
+
+ +
+
+ +

◆ kMitsubishi112TempSize

+ +
+
+ + + + +
const uint8_t kMitsubishi112TempSize = 4
+
+ +
+
+ +

◆ kMitsubishi136Auto

+ +
+
+ + + + +
const uint8_t kMitsubishi136Auto = 0b011
+
+ +
+
+ +

◆ kMitsubishi136Cool

+ +
+
+ + + + +
const uint8_t kMitsubishi136Cool = 0b001
+
+ +
+
+ +

◆ kMitsubishi136Dry

+ +
+
+ + + + +
const uint8_t kMitsubishi136Dry = 0b101
+
+ +
+
+ +

◆ kMitsubishi136Fan

+ +
+
+ + + + +
const uint8_t kMitsubishi136Fan = 0b000
+
+ +
+
+ +

◆ kMitsubishi136FanByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanByte = kMitsubishi136SwingVByte
+
+ +
+
+ +

◆ kMitsubishi136FanLow

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanLow = 0b01
+
+ +
+
+ +

◆ kMitsubishi136FanMax

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanMax = 0b11
+
+ +
+
+ +

◆ kMitsubishi136FanMed

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanMed = 0b10
+
+ +
+
+ +

◆ kMitsubishi136FanMin

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanMin = 0b00
+
+ +
+
+ +

◆ kMitsubishi136FanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanOffset = 1
+
+ +
+
+ +

◆ kMitsubishi136FanQuiet

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanQuiet = kMitsubishi136FanMin
+
+ +
+
+ +

◆ kMitsubishi136FanSize

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanSize = 2
+
+ +
+
+ +

◆ kMitsubishi136Heat

+ +
+
+ + + + +
const uint8_t kMitsubishi136Heat = 0b010
+
+ +
+
+ +

◆ kMitsubishi136MaxTemp

+ +
+
+ + + + +
const uint8_t kMitsubishi136MaxTemp = 30
+
+ +
+
+ +

◆ kMitsubishi136MinTemp

+ +
+
+ + + + +
const uint8_t kMitsubishi136MinTemp = 17
+
+ +
+
+ +

◆ kMitsubishi136ModeByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136ModeByte = kMitsubishi136TempByte
+
+ +
+
+ +

◆ kMitsubishi136ModeOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi136ModeOffset = 0
+
+ +
+
+ +

◆ kMitsubishi136PowerBit

+ +
+
+ + + + +
const uint8_t kMitsubishi136PowerBit = 1 << kMitsubishi136PowerOffset
+
+ +
+
+ +

◆ kMitsubishi136PowerByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136PowerByte = 5
+
+ +
+
+ +

◆ kMitsubishi136PowerOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi136PowerOffset = 6
+
+ +
+
+ +

◆ kMitsubishi136SwingVAuto

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVAuto = 0b1100
+
+ +
+
+ +

◆ kMitsubishi136SwingVByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVByte = 7
+
+ +
+
+ +

◆ kMitsubishi136SwingVHigh

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVHigh = 0b0010
+
+ +
+
+ +

◆ kMitsubishi136SwingVHighest

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVHighest = 0b0011
+
+ +
+
+ +

◆ kMitsubishi136SwingVLow

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVLow = 0b0001
+
+ +
+
+ +

◆ kMitsubishi136SwingVLowest

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVLowest = 0b0000
+
+ +
+
+ +

◆ kMitsubishi136TempByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136TempByte = 6
+
+ +
+
+ +

◆ kMitsubishiAcAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiAcAuto = 0b100
+
+ +
+
+ +

◆ kMitsubishiAcCool

+ +
+
+ + + + +
const uint8_t kMitsubishiAcCool = 0b011
+
+ +
+
+ +

◆ kMitsubishiAcDry

+ +
+
+ + + + +
const uint8_t kMitsubishiAcDry = 0b010
+
+ +
+
+ +

◆ kMitsubishiAcFanAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanAuto = 0
+
+ +
+
+ +

◆ kMitsubishiAcFanAutoOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanAutoOffset = 7
+
+ +
+
+ +

◆ kMitsubishiAcFanMax

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanMax = 5
+
+ +
+
+ +

◆ kMitsubishiAcFanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanOffset = 0
+
+ +
+
+ +

◆ kMitsubishiAcFanQuiet

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanQuiet = kMitsubishiAcFanSilent
+
+ +
+
+ +

◆ kMitsubishiAcFanRealMax

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanRealMax = 4
+
+ +
+
+ +

◆ kMitsubishiAcFanSilent

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanSilent = 6
+
+ +
+
+ +

◆ kMitsubishiAcFanSize

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanSize = 3
+
+ +
+
+ +

◆ kMitsubishiAcHeat

+ +
+
+ + + + +
const uint8_t kMitsubishiAcHeat = 0b001
+
+ +
+
+ +

◆ kMitsubishiAcMaxTemp

+ +
+
+ + + + +
const uint8_t kMitsubishiAcMaxTemp = 31
+
+ +
+
+ +

◆ kMitsubishiAcMinTemp

+ +
+
+ + + + +
const uint8_t kMitsubishiAcMinTemp = 16
+
+ +
+
+ +

◆ kMitsubishiAcModeOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcModeOffset = 3
+
+ +
+
+ +

◆ kMitsubishiAcNoTimer

+ +
+
+ + + + +
const uint8_t kMitsubishiAcNoTimer = 0
+
+ +
+
+ +

◆ kMitsubishiAcPower

+ +
+
+ + + + +
const uint8_t kMitsubishiAcPower = 1 << kMitsubishiAcPowerOffset
+
+ +
+
+ +

◆ kMitsubishiAcPowerOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcPowerOffset = 5
+
+ +
+
+ +

◆ kMitsubishiAcStartStopTimer

+ +
+
+ + + + +
const uint8_t kMitsubishiAcStartStopTimer = 7
+
+ +
+
+ +

◆ kMitsubishiAcStartTimer

+ +
+
+ + + + +
const uint8_t kMitsubishiAcStartTimer = 5
+
+ +
+
+ +

◆ kMitsubishiAcStopTimer

+ +
+
+ + + + +
const uint8_t kMitsubishiAcStopTimer = 3
+
+ +
+
+ +

◆ kMitsubishiAcVaneAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneAuto = 0
+
+ +
+
+ +

◆ kMitsubishiAcVaneAutoMove

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneAutoMove = 7
+
+ +
+
+ +

◆ kMitsubishiAcVaneBitOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneBitOffset = 6
+
+ +
+
+ +

◆ kMitsubishiAcVaneOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneOffset = 3
+
+ +
+
+ +

◆ kMitsubishiAcVaneSize

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneSize = 3
+
+ +
+
+ +

◆ kMitsubishiAcWideVaneAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiAcWideVaneAuto = 8
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h_source.html new file mode 100644 index 000000000..7c5ef139b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h_source.html @@ -0,0 +1,612 @@ + + + + + + + +IRremoteESP8266: src/ir_Mitsubishi.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Mitsubishi.h
+
+
+Go to the documentation of this file.
1 // Copyright 2009 Ken Shirriff
+
2 // Copyright 2017-2019 David Conran
+
3 // Copyright 2019 Mark Kuchel
+
4 
+
17 
+
18 // Supports:
+
19 // Brand: Mitsubishi, Model: TV (MITSUBISHI)
+
20 // Brand: Mitsubishi, Model: HC3000 Projector (MITSUBISHI2)
+
21 // Brand: Mitsubishi, Model: MS-GK24VA A/C
+
22 // Brand: Mitsubishi, Model: KM14A 0179213 remote
+
23 // Brand: Mitsubishi Electric, Model: PEAD-RP71JAA Ducted A/C (MITSUBISHI136)
+
24 // Brand: Mitsubishi Electric, Model: 001CP T7WE10714 remote (MITSUBISHI136)
+
25 // Brand: Mitsubishi Electric, Model: MSH-A24WV A/C (MITSUBISHI112)
+
26 // Brand: Mitsubishi Electric, Model: MUH-A24WV A/C (MITSUBISHI112)
+
27 // Brand: Mitsubishi Electric, Model: KPOA remote (MITSUBISHI112)
+
28 
+
29 #ifndef IR_MITSUBISHI_H_
+
30 #define IR_MITSUBISHI_H_
+
31 
+
32 #define __STDC_LIMIT_MACROS
+
33 #include <stdint.h>
+
34 #ifndef UNIT_TEST
+
35 #include <Arduino.h>
+
36 #endif
+
37 #include "IRremoteESP8266.h"
+
38 #include "IRsend.h"
+
39 #ifdef UNIT_TEST
+
40 #include "IRsend_test.h"
+
41 #endif
+
42 
+
43 
+
44 // Constants
+
45 const uint8_t kMitsubishiAcModeOffset = 3;
+
46 const uint8_t kMitsubishiAcAuto = 0b100;
+
47 const uint8_t kMitsubishiAcCool = 0b011;
+
48 const uint8_t kMitsubishiAcDry = 0b010;
+
49 const uint8_t kMitsubishiAcHeat = 0b001;
+
50 const uint8_t kMitsubishiAcPowerOffset = 5;
+
51 const uint8_t kMitsubishiAcPower = 1 << kMitsubishiAcPowerOffset; // 0x20
+
52 const uint8_t kMitsubishiAcFanOffset = 0;
+
53 const uint8_t kMitsubishiAcFanSize = 3; // Mask 0b111
+
54 const uint8_t kMitsubishiAcFanAuto = 0;
+
55 const uint8_t kMitsubishiAcFanAutoOffset = 7;
+
56 const uint8_t kMitsubishiAcFanMax = 5;
+
57 const uint8_t kMitsubishiAcFanRealMax = 4;
+
58 const uint8_t kMitsubishiAcFanSilent = 6;
+ +
60 const uint8_t kMitsubishiAcMinTemp = 16; // 16C
+
61 const uint8_t kMitsubishiAcMaxTemp = 31; // 31C
+
62 const uint8_t kMitsubishiAcVaneBitOffset = 6;
+
63 const uint8_t kMitsubishiAcVaneOffset = 3;
+
64 const uint8_t kMitsubishiAcVaneSize = 3;
+
65 const uint8_t kMitsubishiAcVaneAuto = 0;
+
66 const uint8_t kMitsubishiAcVaneAutoMove = 7;
+
67 const uint8_t kMitsubishiAcNoTimer = 0;
+
68 const uint8_t kMitsubishiAcStartTimer = 5;
+
69 const uint8_t kMitsubishiAcStopTimer = 3;
+
70 const uint8_t kMitsubishiAcStartStopTimer = 7;
+
71 const uint8_t kMitsubishiAcWideVaneAuto = 8;
+
72 
+
73 const uint8_t kMitsubishi136PowerByte = 5;
+
74 const uint8_t kMitsubishi136PowerOffset = 6;
+ +
76 const uint8_t kMitsubishi136TempByte = 6;
+
77 const uint8_t kMitsubishi136MinTemp = 17; // 17C
+
78 const uint8_t kMitsubishi136MaxTemp = 30; // 30C
+ +
80 const uint8_t kMitsubishi136ModeOffset = 0;
+
81 const uint8_t kMitsubishi136Fan = 0b000;
+
82 const uint8_t kMitsubishi136Cool = 0b001;
+
83 const uint8_t kMitsubishi136Heat = 0b010;
+
84 const uint8_t kMitsubishi136Auto = 0b011;
+
85 const uint8_t kMitsubishi136Dry = 0b101;
+
86 const uint8_t kMitsubishi136SwingVByte = 7;
+
87 const uint8_t kMitsubishi136SwingVLowest = 0b0000;
+
88 const uint8_t kMitsubishi136SwingVLow = 0b0001;
+
89 const uint8_t kMitsubishi136SwingVHigh = 0b0010;
+
90 const uint8_t kMitsubishi136SwingVHighest = 0b0011;
+
91 const uint8_t kMitsubishi136SwingVAuto = 0b1100;
+ +
93 // FanMask = 0b00000110;
+
94 const uint8_t kMitsubishi136FanOffset = 1;
+
95 const uint8_t kMitsubishi136FanSize = 2; // Bits
+
96 const uint8_t kMitsubishi136FanMin = 0b00;
+
97 const uint8_t kMitsubishi136FanLow = 0b01;
+
98 const uint8_t kMitsubishi136FanMed = 0b10;
+
99 const uint8_t kMitsubishi136FanMax = 0b11;
+ +
101 
+
102 // Mitsubishi112
+
103 
+
104 // remote_state[5]
+
105 const uint8_t kMitsubishi112PowerByte = 5;
+
106 const uint8_t kMitsubishi112PowerOffset = 2; // 0b00000100
+
107 // remote_state[6]
+
108 const uint8_t kMitsubishi112ModeByte = 6;
+
109 const uint8_t kMitsubishi112ModeOffset = 0; // Mask 0b00000111
+
110 const uint8_t kMitsubishi112Cool = 0b011;
+
111 const uint8_t kMitsubishi112Heat = 0b001;
+
112 const uint8_t kMitsubishi112Auto = 0b111;
+
113 const uint8_t kMitsubishi112Dry = 0b010;
+
114 // remote_state[7]
+
115 const uint8_t kMitsubishi112TempByte = 7;
+
116 const uint8_t kMitsubishi112TempSize = 4; // Mask 0b00001111
+
117 const uint8_t kMitsubishi112MinTemp = 16; // 16C
+
118 const uint8_t kMitsubishi112MaxTemp = 31; // 31C
+
119 // remote_state[8]
+
120 const uint8_t kMitsubishi112FanByte = 8;
+
121 const uint8_t kMitsubishi112FanOffset = 0; // Mask 0b00000111;
+
122 const uint8_t kMitsubishi112FanSize = 3;
+
123 const uint8_t kMitsubishi112FanMin = 0b010;
+
124 const uint8_t kMitsubishi112FanLow = 0b011;
+
125 const uint8_t kMitsubishi112FanMed = 0b101;
+
126 const uint8_t kMitsubishi112FanMax = 0b000;
+ + +
129 const uint8_t kMitsubishi112SwingVOffset = 3; // Mask 0b00111000
+
130 const uint8_t kMitsubishi112SwingVSize = 3; // Mask 0b00111000
+
131 const uint8_t kMitsubishi112SwingVLowest = 0b101;
+
132 const uint8_t kMitsubishi112SwingVLow = 0b100;
+
133 const uint8_t kMitsubishi112SwingVMiddle = 0b011;
+
134 const uint8_t kMitsubishi112SwingVHigh = 0b010;
+
135 const uint8_t kMitsubishi112SwingVHighest = 0b001;
+
136 const uint8_t kMitsubishi112SwingVAuto = 0b111;
+
137 // remote_state[12]
+
138 const uint8_t kMitsubishi112SwingHByte = 12;
+
139 const uint8_t kMitsubishi112SwingHSize = 4;
+
140 const uint8_t kMitsubishi112SwingHOffset = 2; // Mask 0b00111100
+
141 const uint8_t kMitsubishi112SwingHLeftMax = 0b0001;
+
142 const uint8_t kMitsubishi112SwingHLeft = 0b0010;
+
143 const uint8_t kMitsubishi112SwingHMiddle = 0b0011;
+
144 const uint8_t kMitsubishi112SwingHRight = 0b0100;
+
145 const uint8_t kMitsubishi112SwingHRightMax = 0b0101;
+
146 const uint8_t kMitsubishi112SwingHWide = 0b1000;
+
147 const uint8_t kMitsubishi112SwingHAuto = 0b1100;
+
148 
+
149 // Legacy defines (Deprecated)
+
150 #define MITSUBISHI_AC_VANE_AUTO_MOVE kMitsubishiAcVaneAutoMove
+
151 #define MITSUBISHI_AC_VANE_AUTO kMitsubishiAcVaneAuto
+
152 #define MITSUBISHI_AC_POWER kMitsubishiAcPower
+
153 #define MITSUBISHI_AC_MIN_TEMP kMitsubishiAcMinTemp
+
154 #define MITSUBISHI_AC_MAX_TEMP kMitsubishiAcMaxTemp
+
155 #define MITSUBISHI_AC_HEAT kMitsubishiAcHeat
+
156 #define MITSUBISHI_AC_FAN_SILENT kMitsubishiAcFanSilent
+
157 #define MITSUBISHI_AC_FAN_REAL_MAX kMitsubishiAcFanRealMax
+
158 #define MITSUBISHI_AC_FAN_MAX kMitsubishiAcFanMax
+
159 #define MITSUBISHI_AC_FAN_AUTO kMitsubishiAcFanAuto
+
160 #define MITSUBISHI_AC_DRY kMitsubishiAcDry
+
161 #define MITSUBISHI_AC_COOL kMitsubishiAcCool
+
162 #define MITSUBISHI_AC_AUTO kMitsubishiAcAuto
+
163 
+
164 
+ +
169  public:
+
170  explicit IRMitsubishiAC(const uint16_t pin, const bool inverted = false,
+
171  const bool use_modulation = true);
+
172  void stateReset(void);
+
173  static bool validChecksum(const uint8_t* data);
+
174 #if SEND_MITSUBISHI_AC
+
175  void send(const uint16_t repeat = kMitsubishiACMinRepeat);
+
180  int8_t calibrate(void) { return _irsend.calibrate(); }
+
181 #endif // SEND_MITSUBISHI_AC
+
182  void begin(void);
+
183  void on(void);
+
184  void off(void);
+
185  void setPower(const bool on);
+
186  bool getPower(void);
+
187  void setTemp(const uint8_t degrees);
+
188  uint8_t getTemp(void);
+
189  void setFan(const uint8_t speed);
+
190  uint8_t getFan(void);
+
191  void setMode(const uint8_t mode);
+
192  uint8_t getMode(void);
+
193  void setVane(const uint8_t position);
+
194  void setWideVane(const uint8_t position);
+
195  uint8_t getVane(void);
+
196  uint8_t getWideVane(void);
+
197  uint8_t* getRaw(void);
+
198  void setRaw(const uint8_t* data);
+
199  uint8_t getClock(void);
+
200  void setClock(const uint8_t clock);
+
201  uint8_t getStartClock(void);
+
202  void setStartClock(const uint8_t clock);
+
203  uint8_t getStopClock(void);
+
204  void setStopClock(const uint8_t clock);
+
205  uint8_t getTimer(void);
+
206  void setTimer(const uint8_t timer);
+
207  static uint8_t convertMode(const stdAc::opmode_t mode);
+
208  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
209  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
210  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
211  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
212  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
213  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
214  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
215  stdAc::state_t toCommon(void);
+
216  String toString(void);
+
217 #ifndef UNIT_TEST
+
218 
+
219  private:
+ +
221 #else // UNIT_TEST
+
222  IRsendTest _irsend;
+
224 #endif // UNIT_TEST
+ +
227  void checksum(void);
+
228  static uint8_t calculateChecksum(const uint8_t* data);
+
229 };
+
230 
+ +
233  public:
+
234  explicit IRMitsubishi136(const uint16_t pin, const bool inverted = false,
+
235  const bool use_modulation = true);
+
236  void stateReset(void);
+
237 #if SEND_MITSUBISHI136
+
238  void send(const uint16_t repeat = kMitsubishi136MinRepeat);
+
243  int8_t calibrate(void) { return _irsend.calibrate(); }
+
244 #endif // SEND_MITSUBISHI136
+
245  void begin(void);
+
246  static bool validChecksum(const uint8_t* data,
+
247  const uint16_t len = kMitsubishi136StateLength);
+
248  void on(void);
+
249  void off(void);
+
250  void setPower(const bool on);
+
251  bool getPower(void);
+
252  void setTemp(const uint8_t degrees);
+
253  uint8_t getTemp(void);
+
254  void setFan(const uint8_t speed);
+
255  uint8_t getFan(void);
+
256  void setMode(const uint8_t mode);
+
257  uint8_t getMode(void);
+
258  void setSwingV(const uint8_t position);
+
259  uint8_t getSwingV(void);
+
260  void setQuiet(const bool on);
+
261  bool getQuiet(void);
+
262  uint8_t* getRaw(void);
+
263  void setRaw(const uint8_t* data);
+
264  static uint8_t convertMode(const stdAc::opmode_t mode);
+
265  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
266  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
267  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
268  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
269  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
270  stdAc::state_t toCommon(void);
+
271  String toString(void);
+
272 #ifndef UNIT_TEST
+
273 
+
274  private:
+ +
276 #else // UNIT_TEST
+
277  IRsendTest _irsend;
+
279 #endif // UNIT_TEST
+ +
282  void checksum(void);
+
283 };
+
284 
+
285 
+ +
287  public:
+
288  explicit IRMitsubishi112(const uint16_t pin, const bool inverted = false,
+
289  const bool use_modulation = true);
+
290  void stateReset(void);
+
291 #if SEND_MITSUBISHI112
+
292  void send(const uint16_t repeat = kMitsubishi112MinRepeat);
+
297  int8_t calibrate(void) { return _irsend.calibrate(); }
+
298 #endif // SEND_MITSUBISHI112
+
299  void begin(void);
+
300  void on(void);
+
301  void off(void);
+
302  void setPower(const bool on);
+
303  bool getPower(void);
+
304  void setTemp(const uint8_t degrees);
+
305  uint8_t getTemp(void);
+
306  void setFan(const uint8_t speed);
+
307  uint8_t getFan(void);
+
308  void setMode(const uint8_t mode);
+
309  uint8_t getMode(void);
+
310  void setSwingV(const uint8_t position);
+
311  uint8_t getSwingV(void);
+
312  void setSwingH(const uint8_t position);
+
313  uint8_t getSwingH(void);
+
314  void setQuiet(const bool on);
+
315  bool getQuiet(void);
+
316  uint8_t* getRaw(void);
+
317  void setRaw(const uint8_t* data);
+
318  static uint8_t convertMode(const stdAc::opmode_t mode);
+
319  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
320  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
321  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
322  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
323  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
324  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
325  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
326  stdAc::state_t toCommon(void);
+
327  String toString(void);
+
328 #ifndef UNIT_TEST
+
329 
+
330  private:
+ +
332 #else // UNIT_TEST
+
333  IRsendTest _irsend;
+
335 #endif // UNIT_TEST
+ +
338  void checksum(void);
+
339 };
+
340 
+
341 #endif // IR_MITSUBISHI_H_
+
+
const uint8_t kMitsubishi112SwingVMiddle
Definition: ir_Mitsubishi.h:133
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Mitsubishi.cpp:1399
+
const uint8_t kMitsubishi112SwingVLowest
Definition: ir_Mitsubishi.h:131
+
const uint8_t kMitsubishi112ModeOffset
Definition: ir_Mitsubishi.h:109
+
const uint8_t kMitsubishi112SwingVAuto
Definition: ir_Mitsubishi.h:136
+
const uint8_t kMitsubishi112FanQuiet
Definition: ir_Mitsubishi.h:127
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Mitsubishi.cpp:1295
+
const uint8_t kMitsubishi112SwingHLeft
Definition: ir_Mitsubishi.h:142
+
const uint8_t kMitsubishi136ModeByte
Definition: ir_Mitsubishi.h:79
+
const uint8_t kMitsubishi112FanMed
Definition: ir_Mitsubishi.h:125
+
const uint16_t kMitsubishiACStateLength
Definition: IRremoteESP8266.h:930
+
const uint8_t kMitsubishiAcHeat
Definition: ir_Mitsubishi.h:49
+
const uint8_t kMitsubishiAcAuto
Definition: ir_Mitsubishi.h:46
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Mitsubishi.cpp:1309
+
const uint8_t kMitsubishi112ModeByte
Definition: ir_Mitsubishi.h:108
+
const uint8_t kMitsubishi112SwingHRight
Definition: ir_Mitsubishi.h:144
+
const uint8_t kMitsubishiAcFanSilent
Definition: ir_Mitsubishi.h:58
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Mitsubishi.h:297
+
const uint8_t kMitsubishiAcVaneAuto
Definition: ir_Mitsubishi.h:65
+
const uint8_t kMitsubishi112SwingHRightMax
Definition: ir_Mitsubishi.h:145
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Mitsubishi.cpp:874
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Mitsubishi.cpp:454
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Mitsubishi.cpp:907
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Mitsubishi.cpp:498
+
uint8_t getStopClock(void)
Get the desired stop time of the A/C unit.
Definition: ir_Mitsubishi.cpp:574
+
bool getQuiet(void)
Get the Quiet mode of the A/C.
Definition: ir_Mitsubishi.cpp:1482
+
const uint16_t kMitsubishi136MinRepeat
Definition: IRremoteESP8266.h:935
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
const uint8_t kMitsubishiAcFanOffset
Definition: ir_Mitsubishi.h:52
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Mitsubishi.cpp:388
+
void setVane(const uint8_t position)
Set the requested vane (Vertical Swing) operation mode of the a/c unit.
Definition: ir_Mitsubishi.cpp:520
+
const uint8_t kMitsubishi136FanMed
Definition: ir_Mitsubishi.h:98
+
const uint8_t kMitsubishi136PowerByte
Definition: ir_Mitsubishi.h:73
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kMitsubishi136PowerBit
Definition: ir_Mitsubishi.h:75
+
void setStopClock(const uint8_t clock)
Set the desired stop time of the A/C unit.
Definition: ir_Mitsubishi.cpp:579
+
const uint8_t kMitsubishi136MaxTemp
Definition: ir_Mitsubishi.h:78
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Mitsubishi.cpp:1046
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_Mitsubishi.cpp:417
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Mitsubishi.cpp:967
+
const uint16_t kMitsubishi112MinRepeat
Definition: IRremoteESP8266.h:938
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_Mitsubishi.cpp:1328
+
void setStartClock(const uint8_t clock)
Set the desired start time of the A/C unit.
Definition: ir_Mitsubishi.cpp:567
+
const uint8_t kMitsubishi112FanLow
Definition: ir_Mitsubishi.h:124
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:1558
+
const uint8_t kMitsubishi136FanSize
Definition: ir_Mitsubishi.h:95
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Mitsubishi.cpp:422
+
const uint8_t kMitsubishi136SwingVByte
Definition: ir_Mitsubishi.h:86
+
const uint8_t kMitsubishi112Heat
Definition: ir_Mitsubishi.h:111
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Mitsubishi.cpp:981
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Mitsubishi.cpp:960
+
const uint8_t kMitsubishi112SwingHLeftMax
Definition: ir_Mitsubishi.h:141
+
bool getQuiet(void)
Get the Quiet mode of the A/C.
Definition: ir_Mitsubishi.cpp:1039
+
static bool validChecksum(const uint8_t *data)
Verify the checksum is valid for a given state.
Definition: ir_Mitsubishi.cpp:429
+
uint8_t getClock(void)
Get the clock time of the A/C unit.
Definition: ir_Mitsubishi.cpp:550
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Mitsubishi.h:243
+
const uint8_t kMitsubishi112Cool
Definition: ir_Mitsubishi.h:110
+
const uint8_t kMitsubishi112PowerByte
Definition: ir_Mitsubishi.h:105
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Mitsubishi.cpp:1031
+ +
const uint8_t kMitsubishiAcNoTimer
Definition: ir_Mitsubishi.h:67
+
void send(const uint16_t repeat=kMitsubishi112MinRepeat)
Send the current internal state as an IR message.
Definition: ir_Mitsubishi.cpp:1314
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Mitsubishi.cpp:489
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Mitsubishi.cpp:448
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:1546
+
static uint8_t calculateChecksum(const uint8_t *data)
Calculate the checksum for a given state.
Definition: ir_Mitsubishi.cpp:436
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t getWideVane(void)
Get the Wide Vane (Horizontal Swing) mode of the A/C.
Definition: ir_Mitsubishi.cpp:543
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kMitsubishi136Cool
Definition: ir_Mitsubishi.h:82
+
const uint8_t kMitsubishi136Dry
Definition: ir_Mitsubishi.h:85
+
IRMitsubishi112(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Mitsubishi.cpp:1290
+
void setClock(const uint8_t clock)
Set the clock time on the A/C unit.
Definition: ir_Mitsubishi.cpp:555
+
const uint8_t kMitsubishiAcPowerOffset
Definition: ir_Mitsubishi.h:50
+
uint8_t getStartClock(void)
Get the desired start time of the A/C unit.
Definition: ir_Mitsubishi.cpp:562
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Mitsubishi.cpp:1362
+
std::string String
Definition: IRremoteESP8266.h:1093
+
Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done ...
Definition: ir_Mitsubishi.h:168
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:631
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:674
+
Definition: ir_Mitsubishi.h:286
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Mitsubishi.cpp:474
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Mitsubishi.cpp:1385
+
const uint8_t kMitsubishi112SwingVLow
Definition: ir_Mitsubishi.h:132
+
const uint8_t kMitsubishiAcFanSize
Definition: ir_Mitsubishi.h:53
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:646
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Mitsubishi.cpp:1353
+
uint8_t getVane(void)
Get the Vane (Vertical Swing) mode of the A/C.
Definition: ir_Mitsubishi.cpp:536
+
const uint8_t kMitsubishi112SwingHAuto
Definition: ir_Mitsubishi.h:147
+
const uint8_t kMitsubishi112MinTemp
Definition: ir_Mitsubishi.h:117
+
Class for handling detailed Mitsubishi 136-bit A/C messages.
Definition: ir_Mitsubishi.h:232
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Mitsubishi.cpp:1340
+
void checksum(void)
Calculate the checksum for the current internal state of the remote.
Definition: ir_Mitsubishi.cpp:1303
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Mitsubishi.cpp:604
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Mitsubishi.cpp:1150
+
const uint8_t kMitsubishi112TempByte
Definition: ir_Mitsubishi.h:115
+
const uint8_t kMitsubishiAcStopTimer
Definition: ir_Mitsubishi.h:69
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Mitsubishi.cpp:1627
+
const uint8_t kMitsubishiAcVaneSize
Definition: ir_Mitsubishi.h:64
+
const uint8_t kMitsubishiAcFanMax
Definition: ir_Mitsubishi.h:56
+
const uint8_t kMitsubishi112SwingVHighest
Definition: ir_Mitsubishi.h:135
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:702
+
const uint8_t kMitsubishi136FanLow
Definition: ir_Mitsubishi.h:97
+
const uint16_t kMitsubishiACMinRepeat
Definition: IRremoteESP8266.h:932
+
const uint8_t kMitsubishi136MinTemp
Definition: ir_Mitsubishi.h:77
+
const uint8_t kMitsubishi112SwingVOffset
Definition: ir_Mitsubishi.h:129
+
const uint8_t kMitsubishi112SwingVSize
Definition: ir_Mitsubishi.h:130
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:1112
+
IRMitsubishi136(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Mitsubishi.cpp:869
+
uint8_t remote_state[kMitsubishi112StateLength]
The state in code form.
Definition: ir_Mitsubishi.h:337
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Mitsubishi.h:220
+
const uint8_t kMitsubishi136Auto
Definition: ir_Mitsubishi.h:84
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Mitsubishi.cpp:1599
+
const uint8_t kMitsubishi112TempSize
Definition: ir_Mitsubishi.h:116
+
const uint8_t kMitsubishi136FanMax
Definition: ir_Mitsubishi.h:99
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Mitsubishi.cpp:410
+
const uint8_t kMitsubishiAcFanAuto
Definition: ir_Mitsubishi.h:54
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Mitsubishi.cpp:441
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Mitsubishi.cpp:742
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Mitsubishi.cpp:1124
+
const uint8_t kMitsubishiAcVaneOffset
Definition: ir_Mitsubishi.h:63
+
const uint8_t kMitsubishiAcFanQuiet
Definition: ir_Mitsubishi.h:59
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Mitsubishi.cpp:1502
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Mitsubishi.cpp:1489
+
const uint8_t kMitsubishiAcWideVaneAuto
Definition: ir_Mitsubishi.h:71
+
const uint8_t kMitsubishi112PowerOffset
Definition: ir_Mitsubishi.h:106
+
void send(const uint16_t repeat=kMitsubishi136MinRepeat)
Send the current internal state as an IR message.
Definition: ir_Mitsubishi.cpp:912
+
const uint8_t kMitsubishi136Fan
Definition: ir_Mitsubishi.h:81
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Mitsubishi.cpp:1369
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Mitsubishi.h:180
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Mitsubishi.cpp:1336
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Mitsubishi.cpp:504
+
const uint8_t kMitsubishi136FanOffset
Definition: ir_Mitsubishi.h:94
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Mitsubishi.cpp:1321
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:1530
+
void setSwingH(const uint8_t position)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1443
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:1086
+
const uint8_t kMitsubishi112SwingVByte
Definition: ir_Mitsubishi.h:128
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Mitsubishi.cpp:398
+
uint8_t remote_state[kMitsubishi136StateLength]
The state in code form.
Definition: ir_Mitsubishi.h:281
+
IRMitsubishiAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Mitsubishi.cpp:383
+
const uint8_t kMitsubishi112SwingHSize
Definition: ir_Mitsubishi.h:139
+
const uint8_t kMitsubishi136FanMin
Definition: ir_Mitsubishi.h:96
+
const uint8_t kMitsubishi136SwingVAuto
Definition: ir_Mitsubishi.h:91
+
const uint8_t kMitsubishiAcVaneBitOffset
Definition: ir_Mitsubishi.h:62
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Mitsubishi.h:331
+
const uint8_t kMitsubishi136Heat
Definition: ir_Mitsubishi.h:83
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Mitsubishi.cpp:951
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:662
+
void checksum(void)
Calculate the checksum for the current internal state of the remote.
Definition: ir_Mitsubishi.cpp:884
+
const uint8_t kMitsubishi112FanMin
Definition: ir_Mitsubishi.h:123
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Mitsubishi.cpp:974
+
const uint8_t kMitsubishiAcModeOffset
Definition: ir_Mitsubishi.h:45
+
const uint8_t kMitsubishiAcFanRealMax
Definition: ir_Mitsubishi.h:57
+
const uint8_t kMitsubishiAcStartStopTimer
Definition: ir_Mitsubishi.h:70
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Mitsubishi.cpp:616
+
uint8_t getTimer(void)
Get the timers active setting of the A/C.
Definition: ir_Mitsubishi.cpp:588
+
const uint8_t kMitsubishi112FanByte
Definition: ir_Mitsubishi.h:120
+
const uint8_t kMitsubishi112SwingVHigh
Definition: ir_Mitsubishi.h:134
+
const uint8_t kMitsubishi112SwingHMiddle
Definition: ir_Mitsubishi.h:143
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Mitsubishi.cpp:1346
+
const uint8_t kMitsubishi136SwingVLow
Definition: ir_Mitsubishi.h:88
+
const uint8_t kMitsubishi112FanSize
Definition: ir_Mitsubishi.h:122
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Mitsubishi.cpp:1059
+
const uint8_t kMitsubishiAcVaneAutoMove
Definition: ir_Mitsubishi.h:66
+
void send(const uint16_t repeat=kMitsubishiACMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Mitsubishi.cpp:403
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Mitsubishi.cpp:919
+
void setWideVane(const uint8_t position)
Set the requested wide-vane (Horizontal Swing) operation mode of the a/c.
Definition: ir_Mitsubishi.cpp:529
+
uint8_t getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1024
+
const uint8_t kMitsubishi112SwingHByte
Definition: ir_Mitsubishi.h:138
+
uint8_t getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1436
+
const uint8_t kMitsubishi112Auto
Definition: ir_Mitsubishi.h:112
+
const uint8_t kMitsubishiAcMinTemp
Definition: ir_Mitsubishi.h:60
+
const uint8_t kMitsubishi136SwingVLowest
Definition: ir_Mitsubishi.h:87
+
const uint8_t kMitsubishiAcStartTimer
Definition: ir_Mitsubishi.h:68
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_Mitsubishi.cpp:926
+
const uint8_t kMitsubishi136FanByte
Definition: ir_Mitsubishi.h:92
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:1072
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:1571
+
const uint8_t kMitsubishi136PowerOffset
Definition: ir_Mitsubishi.h:74
+
const uint8_t kMitsubishi112FanMax
Definition: ir_Mitsubishi.h:126
+
void on(void)
Set the requested power state of the A/C to off.
Definition: ir_Mitsubishi.cpp:1333
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Mitsubishi.h:275
+
void setSwingV(const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1006
+
const uint8_t kMitsubishi136TempByte
Definition: ir_Mitsubishi.h:76
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Mitsubishi.cpp:468
+
const uint8_t kMitsubishi112FanOffset
Definition: ir_Mitsubishi.h:121
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Mitsubishi.cpp:716
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Mitsubishi.cpp:944
+
const uint8_t kMitsubishi136FanQuiet
Definition: ir_Mitsubishi.h:100
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Mitsubishi.cpp:1472
+
const uint8_t kMitsubishiAcFanAutoOffset
Definition: ir_Mitsubishi.h:55
+
void setSwingV(const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1417
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:1099
+
const uint8_t kMitsubishi112SwingHOffset
Definition: ir_Mitsubishi.h:140
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:1585
+
uint8_t getSwingH(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1464
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Mitsubishi.cpp:934
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Mitsubishi.cpp:460
+
const uint8_t kMitsubishiAcMaxTemp
Definition: ir_Mitsubishi.h:61
+
const uint16_t kMitsubishi136StateLength
Definition: IRremoteESP8266.h:933
+
const uint8_t kMitsubishi136SwingVHigh
Definition: ir_Mitsubishi.h:89
+
const uint8_t kMitsubishiAcCool
Definition: ir_Mitsubishi.h:47
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:688
+
const uint8_t kMitsubishi112SwingHWide
Definition: ir_Mitsubishi.h:146
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Mitsubishi.cpp:931
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:1516
+
const uint8_t kMitsubishi112Dry
Definition: ir_Mitsubishi.h:113
+
const uint8_t kMitsubishi136SwingVHighest
Definition: ir_Mitsubishi.h:90
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Mitsubishi.cpp:1392
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Mitsubishi.cpp:938
+
const uint8_t kMitsubishiAcPower
Definition: ir_Mitsubishi.h:51
+
void setTimer(const uint8_t timer)
Set the timers active setting of the A/C.
Definition: ir_Mitsubishi.cpp:597
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Mitsubishi.cpp:444
+
uint8_t remote_state[kMitsubishiACStateLength]
The state in code form.
Definition: ir_Mitsubishi.h:226
+
const uint16_t kMitsubishi112StateLength
Definition: IRremoteESP8266.h:936
+
const uint8_t kMitsubishi136ModeOffset
Definition: ir_Mitsubishi.h:80
+
const uint8_t kMitsubishi112MaxTemp
Definition: ir_Mitsubishi.h:118
+
static bool validChecksum(const uint8_t *data, const uint16_t len=kMitsubishi136StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Mitsubishi.cpp:894
+
const uint8_t kMitsubishiAcDry
Definition: ir_Mitsubishi.h:48
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Mitsubishi.cpp:988
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Multibrackets_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Multibrackets_8cpp.html new file mode 100644 index 000000000..ce9f031d1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Multibrackets_8cpp.html @@ -0,0 +1,175 @@ + + + + + + + +IRremoteESP8266: src/ir_Multibrackets.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Multibrackets.cpp File Reference
+
+
+ +

Support for Multibrackets protocols. +More...

+ + + + + + + + + + + + +

+Variables

const uint16_t kMultibracketsTick = 5000
 
const uint16_t kMultibracketsHdrMark = 3 * kMultibracketsTick
 
const uint16_t kMultibracketsFooterSpace = 6 * kMultibracketsTick
 
const uint8_t kMultibracketsTolerance = 5
 
const uint16_t kMultibracketsFreq = 38000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMultibracketsFooterSpace

+ +
+
+ + + + +
const uint16_t kMultibracketsFooterSpace = 6 * kMultibracketsTick
+
+ +
+
+ +

◆ kMultibracketsFreq

+ +
+
+ + + + +
const uint16_t kMultibracketsFreq = 38000
+
+ +
+
+ +

◆ kMultibracketsHdrMark

+ +
+
+ + + + +
const uint16_t kMultibracketsHdrMark = 3 * kMultibracketsTick
+
+ +
+
+ +

◆ kMultibracketsTick

+ +
+
+ + + + +
const uint16_t kMultibracketsTick = 5000
+
+ +
+
+ +

◆ kMultibracketsTolerance

+ +
+
+ + + + +
const uint8_t kMultibracketsTolerance = 5
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8cpp.html new file mode 100644 index 000000000..bcfee8232 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8cpp.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: src/ir_NEC.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_NEC.cpp File Reference
+
+
+ +

Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+

Detailed Description

+

Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/.

+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h.html new file mode 100644 index 000000000..945f7a962 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h.html @@ -0,0 +1,642 @@ + + + + + + + +IRremoteESP8266: src/ir_NEC.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_NEC.h File Reference
+
+
+ +

Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kNecTick = 560
 
const uint16_t kNecHdrMarkTicks = 16
 
const uint16_t kNecHdrMark = kNecHdrMarkTicks * kNecTick
 
const uint16_t kNecHdrSpaceTicks = 8
 
const uint16_t kNecHdrSpace = kNecHdrSpaceTicks * kNecTick
 
const uint16_t kNecBitMarkTicks = 1
 
const uint16_t kNecBitMark = kNecBitMarkTicks * kNecTick
 
const uint16_t kNecOneSpaceTicks = 3
 
const uint16_t kNecOneSpace = kNecOneSpaceTicks * kNecTick
 
const uint16_t kNecZeroSpaceTicks = 1
 
const uint16_t kNecZeroSpace = kNecZeroSpaceTicks * kNecTick
 
const uint16_t kNecRptSpaceTicks = 4
 
const uint16_t kNecRptSpace = kNecRptSpaceTicks * kNecTick
 
const uint16_t kNecRptLength = 4
 
const uint16_t kNecMinCommandLengthTicks = 193
 
const uint32_t kNecMinCommandLength = kNecMinCommandLengthTicks * kNecTick
 
const uint32_t kNecMinGap
 
const uint16_t kNecMinGapTicks
 
const uint32_t kAlokaPower = 0xFF609F
 
const uint32_t kAlokaLedWhite = 0xFF906F
 
const uint32_t kAlokaLedGreen = 0xFF9867
 
const uint32_t kAlokaLedBlue = 0xFFD827
 
const uint32_t kAlokaLedPinkRed = 0xFF8877
 
const uint32_t kAlokaLedRed = 0xFFA857
 
const uint32_t kAlokaLedLightGreen = 0xFFE817
 
const uint32_t kAlokaLedMidBlue = 0xFF48B7
 
const uint32_t kAlokaLedPink = 0xFF6897
 
const uint32_t kAlokaLedOrange = 0xFFB24D
 
const uint32_t kAlokaLedYellow = 0xFF00FF
 
const uint32_t kAlokaNightFade = 0xFF50AF
 
const uint32_t kAlokaNightTimer = 0xFF7887
 
const uint32_t kAlokaLedRainbow = 0xFF708F
 
const uint32_t kAlokaLedTreeGrow = 0xFF58A7
 
+

Detailed Description

+

Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/.

+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+

Variable Documentation

+ +

◆ kAlokaLedBlue

+ +
+
+ + + + +
const uint32_t kAlokaLedBlue = 0xFFD827
+
+ +
+
+ +

◆ kAlokaLedGreen

+ +
+
+ + + + +
const uint32_t kAlokaLedGreen = 0xFF9867
+
+ +
+
+ +

◆ kAlokaLedLightGreen

+ +
+
+ + + + +
const uint32_t kAlokaLedLightGreen = 0xFFE817
+
+ +
+
+ +

◆ kAlokaLedMidBlue

+ +
+
+ + + + +
const uint32_t kAlokaLedMidBlue = 0xFF48B7
+
+ +
+
+ +

◆ kAlokaLedOrange

+ +
+
+ + + + +
const uint32_t kAlokaLedOrange = 0xFFB24D
+
+ +
+
+ +

◆ kAlokaLedPink

+ +
+
+ + + + +
const uint32_t kAlokaLedPink = 0xFF6897
+
+ +
+
+ +

◆ kAlokaLedPinkRed

+ +
+
+ + + + +
const uint32_t kAlokaLedPinkRed = 0xFF8877
+
+ +
+
+ +

◆ kAlokaLedRainbow

+ +
+
+ + + + +
const uint32_t kAlokaLedRainbow = 0xFF708F
+
+ +
+
+ +

◆ kAlokaLedRed

+ +
+
+ + + + +
const uint32_t kAlokaLedRed = 0xFFA857
+
+ +
+
+ +

◆ kAlokaLedTreeGrow

+ +
+
+ + + + +
const uint32_t kAlokaLedTreeGrow = 0xFF58A7
+
+ +
+
+ +

◆ kAlokaLedWhite

+ +
+
+ + + + +
const uint32_t kAlokaLedWhite = 0xFF906F
+
+ +
+
+ +

◆ kAlokaLedYellow

+ +
+
+ + + + +
const uint32_t kAlokaLedYellow = 0xFF00FF
+
+ +
+
+ +

◆ kAlokaNightFade

+ +
+
+ + + + +
const uint32_t kAlokaNightFade = 0xFF50AF
+
+ +
+
+ +

◆ kAlokaNightTimer

+ +
+
+ + + + +
const uint32_t kAlokaNightTimer = 0xFF7887
+
+ +
+
+ +

◆ kAlokaPower

+ +
+
+ + + + +
const uint32_t kAlokaPower = 0xFF609F
+
+ +
+
+ +

◆ kNecBitMark

+ +
+
+ + + + +
const uint16_t kNecBitMark = kNecBitMarkTicks * kNecTick
+
+ +
+
+ +

◆ kNecBitMarkTicks

+ +
+
+ + + + +
const uint16_t kNecBitMarkTicks = 1
+
+ +
+
+ +

◆ kNecHdrMark

+ +
+
+ + + + +
const uint16_t kNecHdrMark = kNecHdrMarkTicks * kNecTick
+
+ +
+
+ +

◆ kNecHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kNecHdrMarkTicks = 16
+
+ +
+
+ +

◆ kNecHdrSpace

+ +
+
+ + + + +
const uint16_t kNecHdrSpace = kNecHdrSpaceTicks * kNecTick
+
+ +
+
+ +

◆ kNecHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kNecHdrSpaceTicks = 8
+
+ +
+
+ +

◆ kNecMinCommandLength

+ +
+
+ + + + +
const uint32_t kNecMinCommandLength = kNecMinCommandLengthTicks * kNecTick
+
+ +
+
+ +

◆ kNecMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kNecMinCommandLengthTicks = 193
+
+ +
+
+ +

◆ kNecMinGap

+ +
+
+ + + + +
const uint32_t kNecMinGap
+
+
+ +

◆ kNecMinGapTicks

+ +
+
+ + + + +
const uint16_t kNecMinGapTicks
+
+
+ +

◆ kNecOneSpace

+ +
+
+ + + + +
const uint16_t kNecOneSpace = kNecOneSpaceTicks * kNecTick
+
+ +
+
+ +

◆ kNecOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kNecOneSpaceTicks = 3
+
+ +
+
+ +

◆ kNecRptLength

+ +
+
+ + + + +
const uint16_t kNecRptLength = 4
+
+ +
+
+ +

◆ kNecRptSpace

+ +
+
+ + + + +
const uint16_t kNecRptSpace = kNecRptSpaceTicks * kNecTick
+
+ +
+
+ +

◆ kNecRptSpaceTicks

+ +
+
+ + + + +
const uint16_t kNecRptSpaceTicks = 4
+
+ +
+
+ +

◆ kNecTick

+ +
+
+ + + + +
const uint16_t kNecTick = 560
+
+ +
+
+ +

◆ kNecZeroSpace

+ +
+
+ + + + +
const uint16_t kNecZeroSpace = kNecZeroSpaceTicks * kNecTick
+
+ +
+
+ +

◆ kNecZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kNecZeroSpaceTicks = 1
+
+ +
+
+
+
const uint16_t kNecBitMarkTicks
Definition: ir_NEC.h:30
+
const uint16_t kNecHdrSpace
Definition: ir_NEC.h:29
+
const uint16_t kNecBitMark
Definition: ir_NEC.h:31
+
const uint32_t kNecMinCommandLength
Definition: ir_NEC.h:40
+
const uint16_t kNecOneSpace
Definition: ir_NEC.h:33
+
const uint16_t kNecMinCommandLengthTicks
Definition: ir_NEC.h:39
+
const uint16_t kNecOneSpaceTicks
Definition: ir_NEC.h:32
+
const uint16_t kNecHdrMarkTicks
Definition: ir_NEC.h:26
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint16_t kNecHdrMark
Definition: ir_NEC.h:27
+
const uint16_t kNecHdrSpaceTicks
Definition: ir_NEC.h:28
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h_source.html new file mode 100644 index 000000000..6e315d527 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h_source.html @@ -0,0 +1,189 @@ + + + + + + + +IRremoteESP8266: src/ir_NEC.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_NEC.h
+
+
+Go to the documentation of this file.
1 // Copyright 2009 Ken Shirriff
+
2 // Copyright 2017, 2018 David Conran
+
3 
+
8 
+
9 // Supports:
+
10 // Brand: Yamaha, Model: RAV561 remote
+
11 // Brand: Yamaha, Model: RXV585B A/V Receiver
+
12 // Brand: Aloka, Model: SleepyLights LED Lamp
+
13 // Brand: Toshiba, Model: 42TL838 LCD TV
+
14 // Brand: Duux, Model: Blizzard Smart 10K / DXMA04 A/C
+
15 // Brand: Duux, Model: YJ-A081 TR Remote
+
16 // Brand: Silan Microelectronics, Model: SC6121-001 IC
+
17 
+
18 #ifndef IR_NEC_H_
+
19 #define IR_NEC_H_
+
20 
+
21 #include <stdint.h>
+
22 #include "IRremoteESP8266.h"
+
23 
+
24 // Constants
+
25 const uint16_t kNecTick = 560;
+
26 const uint16_t kNecHdrMarkTicks = 16;
+ +
28 const uint16_t kNecHdrSpaceTicks = 8;
+ +
30 const uint16_t kNecBitMarkTicks = 1;
+ +
32 const uint16_t kNecOneSpaceTicks = 3;
+ +
34 const uint16_t kNecZeroSpaceTicks = 1;
+ +
36 const uint16_t kNecRptSpaceTicks = 4;
+ +
38 const uint16_t kNecRptLength = 4;
+
39 const uint16_t kNecMinCommandLengthTicks = 193;
+ +
41 const uint32_t kNecMinGap =
+ + +
44  kNecBitMark);
+
45 const uint16_t kNecMinGapTicks =
+ + + +
49 
+
50 // IR codes and structure for kids ALOKA SleepyLights LED Lamp.
+
51 // https://aloka-designs.com/
+
52 // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1004
+
53 //
+
54 // May be useful for someone wanting to control the lamp.
+
55 //
+
56 // The lamp is toggled On and Off with the same power button.
+
57 // The colour, when selected, is the brightest and there are 4 levels of
+
58 // brightness that decrease on each send of the colour. A fifth send of the
+
59 // colour resets to brightest again.
+
60 //
+
61 // Remote buttons defined left to right, top line to bottom line on the remote.
+
62 const uint32_t kAlokaPower = 0xFF609F;
+
63 const uint32_t kAlokaLedWhite = 0xFF906F;
+
64 const uint32_t kAlokaLedGreen = 0xFF9867;
+
65 const uint32_t kAlokaLedBlue = 0xFFD827;
+
66 const uint32_t kAlokaLedPinkRed = 0xFF8877;
+
67 const uint32_t kAlokaLedRed = 0xFFA857;
+
68 const uint32_t kAlokaLedLightGreen = 0xFFE817;
+
69 const uint32_t kAlokaLedMidBlue = 0xFF48B7;
+
70 const uint32_t kAlokaLedPink = 0xFF6897;
+
71 const uint32_t kAlokaLedOrange = 0xFFB24D;
+
72 const uint32_t kAlokaLedYellow = 0xFF00FF;
+
73 const uint32_t kAlokaNightFade = 0xFF50AF;
+
74 const uint32_t kAlokaNightTimer = 0xFF7887;
+
75 const uint32_t kAlokaLedRainbow = 0xFF708F;
+
76 // Didn't have a better description for it...
+
77 const uint32_t kAlokaLedTreeGrow = 0xFF58A7;
+
78 #endif // IR_NEC_H_
+
+
const uint32_t kAlokaLedWhite
Definition: ir_NEC.h:63
+
const uint16_t kNecBitMarkTicks
Definition: ir_NEC.h:30
+
const uint16_t kNecHdrSpace
Definition: ir_NEC.h:29
+
const uint16_t kNecBitMark
Definition: ir_NEC.h:31
+
const uint32_t kNecMinCommandLength
Definition: ir_NEC.h:40
+
const uint16_t kNecZeroSpaceTicks
Definition: ir_NEC.h:34
+
const uint32_t kAlokaLedBlue
Definition: ir_NEC.h:65
+
const uint32_t kAlokaLedLightGreen
Definition: ir_NEC.h:68
+
const uint16_t kNecOneSpace
Definition: ir_NEC.h:33
+
const uint32_t kAlokaNightTimer
Definition: ir_NEC.h:74
+
const uint16_t kNecMinCommandLengthTicks
Definition: ir_NEC.h:39
+
const uint16_t kNecZeroSpace
Definition: ir_NEC.h:35
+
const uint16_t kNecOneSpaceTicks
Definition: ir_NEC.h:32
+
const uint16_t kNecRptSpace
Definition: ir_NEC.h:37
+
const uint16_t kNecHdrMarkTicks
Definition: ir_NEC.h:26
+
const uint32_t kAlokaNightFade
Definition: ir_NEC.h:73
+ +
const uint16_t kNecRptLength
Definition: ir_NEC.h:38
+
const uint32_t kAlokaLedPink
Definition: ir_NEC.h:70
+
const uint16_t kNecMinGapTicks
Definition: ir_NEC.h:45
+
const uint32_t kAlokaLedPinkRed
Definition: ir_NEC.h:66
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint32_t kAlokaLedRed
Definition: ir_NEC.h:67
+
const uint32_t kAlokaLedTreeGrow
Definition: ir_NEC.h:77
+
const uint16_t kNecHdrMark
Definition: ir_NEC.h:27
+
const uint16_t kNecRptSpaceTicks
Definition: ir_NEC.h:36
+
const uint32_t kAlokaLedOrange
Definition: ir_NEC.h:71
+
const uint32_t kNecMinGap
Definition: ir_NEC.h:41
+
const uint32_t kAlokaPower
Definition: ir_NEC.h:62
+
const uint32_t kAlokaLedMidBlue
Definition: ir_NEC.h:69
+
const uint32_t kAlokaLedRainbow
Definition: ir_NEC.h:75
+
const uint32_t kAlokaLedYellow
Definition: ir_NEC.h:72
+
const uint16_t kNecHdrSpaceTicks
Definition: ir_NEC.h:28
+
const uint16_t kNecTick
Definition: ir_NEC.h:25
+
const uint32_t kAlokaLedGreen
Definition: ir_NEC.h:64
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8cpp.html new file mode 100644 index 000000000..3de0b6df2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8cpp.html @@ -0,0 +1,191 @@ + + + + + + + +IRremoteESP8266: src/ir_Neoclima.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Neoclima.cpp File Reference
+
+
+ +

Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy Code by crankyoldgit. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kNeoclimaHdrMark = 6112
 
const uint16_t kNeoclimaHdrSpace = 7391
 
const uint16_t kNeoclimaBitMark = 537
 
const uint16_t kNeoclimaOneSpace = 1651
 
const uint16_t kNeoclimaZeroSpace = 571
 
const uint32_t kNeoclimaMinGap = kDefaultMessageGap
 
+

Detailed Description

+

Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy Code by crankyoldgit.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/764
+
+https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view
+

Variable Documentation

+ +

◆ kNeoclimaBitMark

+ +
+
+ + + + +
const uint16_t kNeoclimaBitMark = 537
+
+ +
+
+ +

◆ kNeoclimaHdrMark

+ +
+
+ + + + +
const uint16_t kNeoclimaHdrMark = 6112
+
+ +
+
+ +

◆ kNeoclimaHdrSpace

+ +
+
+ + + + +
const uint16_t kNeoclimaHdrSpace = 7391
+
+ +
+
+ +

◆ kNeoclimaMinGap

+ +
+
+ + + + +
const uint32_t kNeoclimaMinGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kNeoclimaOneSpace

+ +
+
+ + + + +
const uint16_t kNeoclimaOneSpace = 1651
+
+ +
+
+ +

◆ kNeoclimaZeroSpace

+ +
+
+ + + + +
const uint16_t kNeoclimaZeroSpace = 571
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h.html new file mode 100644 index 000000000..6ca564a14 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h.html @@ -0,0 +1,888 @@ + + + + + + + +IRremoteESP8266: src/ir_Neoclima.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Neoclima.h File Reference
+
+
+ +

Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRNeoclimaAc
 Class for handling detailed Neoclima A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kNeoclima8CHeatOffset = 1
 
const uint8_t kNeoclimaIonOffset = 2
 
const uint8_t kNeoclimaLightOffset = 0
 
const uint8_t kNeoclimaHoldOffset = 2
 
const uint8_t kNeoclimaTurboOffset = 3
 
const uint8_t kNeoclimaEyeOffset = 6
 
const uint8_t kNeoclimaFreshOffset = 7
 
const uint8_t kNeoclimaButtonOffset = 0
 
const uint8_t kNeoclimaButtonSize = 5
 
const uint8_t kNeoclimaButtonPower = 0x00
 
const uint8_t kNeoclimaButtonMode = 0x01
 
const uint8_t kNeoclimaButtonTempUp = 0x02
 
const uint8_t kNeoclimaButtonTempDown = 0x03
 
const uint8_t kNeoclimaButtonSwing = 0x04
 
const uint8_t kNeoclimaButtonFanSpeed = 0x05
 
const uint8_t kNeoclimaButtonAirFlow = 0x07
 
const uint8_t kNeoclimaButtonHold = 0x08
 
const uint8_t kNeoclimaButtonSleep = 0x09
 
const uint8_t kNeoclimaButtonTurbo = 0x0A
 
const uint8_t kNeoclimaButtonLight = 0x0B
 
const uint8_t kNeoclimaButtonEye = 0x0E
 
const uint8_t kNeoclimaButtonFollow = 0x13
 
const uint8_t kNeoclimaButtonIon = 0x14
 
const uint8_t kNeoclimaButtonFresh = 0x15
 
const uint8_t kNeoclimaButton8CHeat = 0x1D
 
const uint8_t kNeoclimaSleepOffset = 0
 
const uint8_t kNeoclimaPowerOffset = 1
 
const uint8_t kNeoclimaSwingVOffset = 2
 
const uint8_t kNeoclimaSwingVSize = 2
 
const uint8_t kNeoclimaSwingVOn = 0b01
 
const uint8_t kNeoclimaSwingVOff = 0b10
 
const uint8_t kNeoclimaSwingHOffset = 4
 
const uint8_t kNeoclimaFanOffest = 5
 
const uint8_t kNeoclimaFanSize = 2
 
const uint8_t kNeoclimaFanAuto = 0b00
 
const uint8_t kNeoclimaFanHigh = 0b01
 
const uint8_t kNeoclimaFanMed = 0b10
 
const uint8_t kNeoclimaFanLow = 0b11
 
const uint8_t kNeoclimaFollowMe = 0x5D
 
const uint8_t kNeoclimaTempOffset = 0
 
const uint8_t kNeoclimaTempSize = 5
 
const uint8_t kNeoclimaMinTemp = 16
 
const uint8_t kNeoclimaMaxTemp = 32
 
const uint8_t kNeoclimaModeOffset = 5
 
const uint8_t kNeoclimaAuto = 0b000
 
const uint8_t kNeoclimaCool = 0b001
 
const uint8_t kNeoclimaDry = 0b010
 
const uint8_t kNeoclimaFan = 0b011
 
const uint8_t kNeoclimaHeat = 0b100
 
+

Detailed Description

+

Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/764
+
+https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view
+

Variable Documentation

+ +

◆ kNeoclima8CHeatOffset

+ +
+
+ + + + +
const uint8_t kNeoclima8CHeatOffset = 1
+
+ +
+
+ +

◆ kNeoclimaAuto

+ +
+
+ + + + +
const uint8_t kNeoclimaAuto = 0b000
+
+ +
+
+ +

◆ kNeoclimaButton8CHeat

+ +
+
+ + + + +
const uint8_t kNeoclimaButton8CHeat = 0x1D
+
+ +
+
+ +

◆ kNeoclimaButtonAirFlow

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonAirFlow = 0x07
+
+ +
+
+ +

◆ kNeoclimaButtonEye

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonEye = 0x0E
+
+ +
+
+ +

◆ kNeoclimaButtonFanSpeed

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonFanSpeed = 0x05
+
+ +
+
+ +

◆ kNeoclimaButtonFollow

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonFollow = 0x13
+
+ +
+
+ +

◆ kNeoclimaButtonFresh

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonFresh = 0x15
+
+ +
+
+ +

◆ kNeoclimaButtonHold

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonHold = 0x08
+
+ +
+
+ +

◆ kNeoclimaButtonIon

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonIon = 0x14
+
+ +
+
+ +

◆ kNeoclimaButtonLight

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonLight = 0x0B
+
+ +
+
+ +

◆ kNeoclimaButtonMode

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonMode = 0x01
+
+ +
+
+ +

◆ kNeoclimaButtonOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonOffset = 0
+
+ +
+
+ +

◆ kNeoclimaButtonPower

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonPower = 0x00
+
+ +
+
+ +

◆ kNeoclimaButtonSize

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonSize = 5
+
+ +
+
+ +

◆ kNeoclimaButtonSleep

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonSleep = 0x09
+
+ +
+
+ +

◆ kNeoclimaButtonSwing

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonSwing = 0x04
+
+ +
+
+ +

◆ kNeoclimaButtonTempDown

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonTempDown = 0x03
+
+ +
+
+ +

◆ kNeoclimaButtonTempUp

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonTempUp = 0x02
+
+ +
+
+ +

◆ kNeoclimaButtonTurbo

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonTurbo = 0x0A
+
+ +
+
+ +

◆ kNeoclimaCool

+ +
+
+ + + + +
const uint8_t kNeoclimaCool = 0b001
+
+ +
+
+ +

◆ kNeoclimaDry

+ +
+
+ + + + +
const uint8_t kNeoclimaDry = 0b010
+
+ +
+
+ +

◆ kNeoclimaEyeOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaEyeOffset = 6
+
+ +
+
+ +

◆ kNeoclimaFan

+ +
+
+ + + + +
const uint8_t kNeoclimaFan = 0b011
+
+ +
+
+ +

◆ kNeoclimaFanAuto

+ +
+
+ + + + +
const uint8_t kNeoclimaFanAuto = 0b00
+
+ +
+
+ +

◆ kNeoclimaFanHigh

+ +
+
+ + + + +
const uint8_t kNeoclimaFanHigh = 0b01
+
+ +
+
+ +

◆ kNeoclimaFanLow

+ +
+
+ + + + +
const uint8_t kNeoclimaFanLow = 0b11
+
+ +
+
+ +

◆ kNeoclimaFanMed

+ +
+
+ + + + +
const uint8_t kNeoclimaFanMed = 0b10
+
+ +
+
+ +

◆ kNeoclimaFanOffest

+ +
+
+ + + + +
const uint8_t kNeoclimaFanOffest = 5
+
+ +
+
+ +

◆ kNeoclimaFanSize

+ +
+
+ + + + +
const uint8_t kNeoclimaFanSize = 2
+
+ +
+
+ +

◆ kNeoclimaFollowMe

+ +
+
+ + + + +
const uint8_t kNeoclimaFollowMe = 0x5D
+
+ +
+
+ +

◆ kNeoclimaFreshOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaFreshOffset = 7
+
+ +
+
+ +

◆ kNeoclimaHeat

+ +
+
+ + + + +
const uint8_t kNeoclimaHeat = 0b100
+
+ +
+
+ +

◆ kNeoclimaHoldOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaHoldOffset = 2
+
+ +
+
+ +

◆ kNeoclimaIonOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaIonOffset = 2
+
+ +
+
+ +

◆ kNeoclimaLightOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaLightOffset = 0
+
+ +
+
+ +

◆ kNeoclimaMaxTemp

+ +
+
+ + + + +
const uint8_t kNeoclimaMaxTemp = 32
+
+ +
+
+ +

◆ kNeoclimaMinTemp

+ +
+
+ + + + +
const uint8_t kNeoclimaMinTemp = 16
+
+ +
+
+ +

◆ kNeoclimaModeOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaModeOffset = 5
+
+ +
+
+ +

◆ kNeoclimaPowerOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaPowerOffset = 1
+
+ +
+
+ +

◆ kNeoclimaSleepOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaSleepOffset = 0
+
+ +
+
+ +

◆ kNeoclimaSwingHOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingHOffset = 4
+
+ +
+
+ +

◆ kNeoclimaSwingVOff

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingVOff = 0b10
+
+ +
+
+ +

◆ kNeoclimaSwingVOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingVOffset = 2
+
+ +
+
+ +

◆ kNeoclimaSwingVOn

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingVOn = 0b01
+
+ +
+
+ +

◆ kNeoclimaSwingVSize

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingVSize = 2
+
+ +
+
+ +

◆ kNeoclimaTempOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaTempOffset = 0
+
+ +
+
+ +

◆ kNeoclimaTempSize

+ +
+
+ + + + +
const uint8_t kNeoclimaTempSize = 5
+
+ +
+
+ +

◆ kNeoclimaTurboOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaTurboOffset = 3
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h_source.html new file mode 100644 index 000000000..ccfa9da53 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h_source.html @@ -0,0 +1,340 @@ + + + + + + + +IRremoteESP8266: src/ir_Neoclima.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Neoclima.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
2 
+
8 
+
9 // Supports:
+
10 // Brand: Neoclima, Model: NS-09AHTI A/C
+
11 // Brand: Neoclima, Model: ZH/TY-01 remote
+
12 
+
13 #ifndef IR_NEOCLIMA_H_
+
14 #define IR_NEOCLIMA_H_
+
15 
+
16 #define __STDC_LIMIT_MACROS
+
17 #include <stdint.h>
+
18 #ifndef UNIT_TEST
+
19 #include <Arduino.h>
+
20 #endif
+
21 #include "IRremoteESP8266.h"
+
22 #include "IRsend.h"
+
23 #ifdef UNIT_TEST
+
24 #include "IRsend_test.h"
+
25 #endif
+
26 
+
27 // Constants
+
28 // state[1]
+
29 const uint8_t kNeoclima8CHeatOffset = 1;
+
30 const uint8_t kNeoclimaIonOffset = 2;
+
31 // state[3]
+
32 const uint8_t kNeoclimaLightOffset = 0;
+
33 const uint8_t kNeoclimaHoldOffset = 2;
+
34 const uint8_t kNeoclimaTurboOffset = 3;
+
35 const uint8_t kNeoclimaEyeOffset = 6;
+
36 // state[5]
+
37 const uint8_t kNeoclimaFreshOffset = 7;
+
38 const uint8_t kNeoclimaButtonOffset = 0;
+
39 const uint8_t kNeoclimaButtonSize = 5;
+
40 const uint8_t kNeoclimaButtonPower = 0x00;
+
41 const uint8_t kNeoclimaButtonMode = 0x01;
+
42 const uint8_t kNeoclimaButtonTempUp = 0x02;
+
43 const uint8_t kNeoclimaButtonTempDown = 0x03;
+
44 const uint8_t kNeoclimaButtonSwing = 0x04;
+
45 const uint8_t kNeoclimaButtonFanSpeed = 0x05;
+
46 const uint8_t kNeoclimaButtonAirFlow = 0x07;
+
47 const uint8_t kNeoclimaButtonHold = 0x08;
+
48 const uint8_t kNeoclimaButtonSleep = 0x09;
+
49 const uint8_t kNeoclimaButtonTurbo = 0x0A;
+
50 const uint8_t kNeoclimaButtonLight = 0x0B;
+
51 const uint8_t kNeoclimaButtonEye = 0x0E;
+
52 const uint8_t kNeoclimaButtonFollow = 0x13;
+
53 const uint8_t kNeoclimaButtonIon = 0x14;
+
54 const uint8_t kNeoclimaButtonFresh = 0x15;
+
55 const uint8_t kNeoclimaButton8CHeat = 0x1D;
+
56 // state[7]
+
57 const uint8_t kNeoclimaSleepOffset = 0;
+
58 const uint8_t kNeoclimaPowerOffset = 1;
+
59 const uint8_t kNeoclimaSwingVOffset = 2;
+
60 const uint8_t kNeoclimaSwingVSize = 2; // Bits
+
61 const uint8_t kNeoclimaSwingVOn = 0b01;
+
62 const uint8_t kNeoclimaSwingVOff = 0b10;
+
63 const uint8_t kNeoclimaSwingHOffset = 4;
+
64 const uint8_t kNeoclimaFanOffest = 5;
+
65 const uint8_t kNeoclimaFanSize = 2;
+
66 const uint8_t kNeoclimaFanAuto = 0b00;
+
67 const uint8_t kNeoclimaFanHigh = 0b01;
+
68 const uint8_t kNeoclimaFanMed = 0b10;
+
69 const uint8_t kNeoclimaFanLow = 0b11;
+
70 // state[8]
+
71 const uint8_t kNeoclimaFollowMe = 0x5D; // Also 0x5F
+
72 // state[9]
+
73 const uint8_t kNeoclimaTempOffset = 0;
+
74 const uint8_t kNeoclimaTempSize = 5; // Bits
+
75 const uint8_t kNeoclimaMinTemp = 16; // 16C
+
76 const uint8_t kNeoclimaMaxTemp = 32; // 32C
+
77 const uint8_t kNeoclimaModeOffset = 5;
+
78 const uint8_t kNeoclimaAuto = 0b000;
+
79 const uint8_t kNeoclimaCool = 0b001;
+
80 const uint8_t kNeoclimaDry = 0b010;
+
81 const uint8_t kNeoclimaFan = 0b011;
+
82 const uint8_t kNeoclimaHeat = 0b100;
+
83 
+
84 // Classes
+
86 class IRNeoclimaAc {
+
87  public:
+
88  explicit IRNeoclimaAc(const uint16_t pin, const bool inverted = false,
+
89  const bool use_modulation = true);
+
90  void stateReset(void);
+
91 #if SEND_NEOCLIMA
+
92  void send(const uint16_t repeat = kNeoclimaMinRepeat);
+
97  int8_t calibrate(void) { return _irsend.calibrate(); }
+
98 #endif // SEND_NEOCLIMA
+
99  void begin(void);
+
100  void setButton(const uint8_t button);
+
101  uint8_t getButton(void);
+
102  void on(void);
+
103  void off(void);
+
104  void setPower(const bool on);
+
105  bool getPower(void);
+
106  void setMode(const uint8_t mode);
+
107  uint8_t getMode(void);
+
108  void setTemp(const uint8_t temp);
+
109  uint8_t getTemp(void);
+
110  void setFan(const uint8_t speed);
+
111  uint8_t getFan(void);
+
112  void setSwingV(const bool on);
+
113  bool getSwingV(void);
+
114  void setSwingH(const bool on);
+
115  bool getSwingH(void);
+
116  void setSleep(const bool on);
+
117  bool getSleep(void);
+
118  void setTurbo(const bool on);
+
119  bool getTurbo(void);
+
120  void setFresh(const bool on);
+
121  bool getFresh(void);
+
122  void setHold(const bool on);
+
123  bool getHold(void);
+
124  void setIon(const bool on);
+
125  bool getIon(void);
+
126  void setLight(const bool on);
+
127  bool getLight(void);
+
128  void set8CHeat(const bool on);
+
129  bool get8CHeat(void);
+
130  void setEye(const bool on);
+
131  bool getEye(void);
+
132  // DISABLED: See TODO in ir_Neoclima.cpp
+
133  // void setFollow(const bool on);
+
134  bool getFollow(void);
+
135  uint8_t* getRaw(void);
+
136  void setRaw(const uint8_t new_code[],
+
137  const uint16_t length = kNeoclimaStateLength);
+
138  static bool validChecksum(const uint8_t state[],
+
139  const uint16_t length = kNeoclimaStateLength);
+
140  static uint8_t calcChecksum(const uint8_t state[],
+
141  const uint16_t length = kNeoclimaStateLength);
+
142  String toString(void);
+
143  uint8_t convertMode(const stdAc::opmode_t mode);
+
144  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
145  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
146  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
147  stdAc::state_t toCommon(void);
+
148 #ifndef UNIT_TEST
+
149 
+
150  private:
+ +
152 #else // UNIT_TEST
+
153  IRsendTest _irsend;
+
155 #endif // UNIT_TEST
+ +
158  void checksum(const uint16_t length = kNeoclimaStateLength);
+
159 };
+
160 
+
161 #endif // IR_NEOCLIMA_H_
+
+
const uint8_t kNeoclimaFanHigh
Definition: ir_Neoclima.h:67
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Neoclima.cpp:237
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Neoclima.cpp:301
+
const uint8_t kNeoclimaButtonFanSpeed
Definition: ir_Neoclima.h:45
+
const uint8_t kNeoclimaButtonTurbo
Definition: ir_Neoclima.h:49
+
const uint8_t kNeoclimaFollowMe
Definition: ir_Neoclima.h:71
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Neoclima.cpp:319
+
const uint8_t kNeoclimaEyeOffset
Definition: ir_Neoclima.h:35
+
const uint8_t kNeoclimaTempOffset
Definition: ir_Neoclima.h:73
+
bool getEye(void)
Get the Eye (Sensor) setting of the A/C.
Definition: ir_Neoclima.cpp:442
+
bool getFollow(void)
Get the Follow Me setting of the A/C.
Definition: ir_Neoclima.cpp:459
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kNeoclimaIonOffset
Definition: ir_Neoclima.h:30
+
const uint8_t kNeoclimaDry
Definition: ir_Neoclima.h:80
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kNeoclimaStateLength)
Calculate the checksum for a given state.
Definition: ir_Neoclima.cpp:84
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Neoclima.h:97
+
const uint8_t kNeoclimaMaxTemp
Definition: ir_Neoclima.h:76
+
void set8CHeat(const bool on)
Set the 8°C Heat setting of the A/C.
Definition: ir_Neoclima.cpp:422
+
const uint8_t kNeoclimaButtonEye
Definition: ir_Neoclima.h:51
+
const uint8_t kNeoclimaMinTemp
Definition: ir_Neoclima.h:75
+
const uint8_t kNeoclimaButtonPower
Definition: ir_Neoclima.h:40
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Neoclima.cpp:258
+
const uint8_t kNeoclimaSwingVOn
Definition: ir_Neoclima.h:61
+
const uint8_t kNeoclimaButtonMode
Definition: ir_Neoclima.h:41
+
const uint16_t kNeoclimaStateLength
Definition: IRremoteESP8266.h:949
+
void setHold(const bool on)
Set the Hold setting of the A/C.
Definition: ir_Neoclima.cpp:379
+
const uint8_t kNeoclimaSleepOffset
Definition: ir_Neoclima.h:57
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Neoclima.cpp:205
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Neoclima.cpp:178
+
void setRaw(const uint8_t new_code[], const uint16_t length=kNeoclimaStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Neoclima.cpp:125
+
const uint8_t kNeoclimaButtonHold
Definition: ir_Neoclima.h:47
+ +
const uint8_t kNeoclimaSwingVSize
Definition: ir_Neoclima.h:60
+
const uint8_t kNeoclimaAuto
Definition: ir_Neoclima.h:78
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Neoclima.cpp:280
+
void setLight(const bool on)
Set the Light(LED display) setting of the A/C.
Definition: ir_Neoclima.cpp:405
+
const uint8_t kNeoclimaFan
Definition: ir_Neoclima.h:81
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Neoclima.cpp:117
+
const uint8_t kNeoclimaFanAuto
Definition: ir_Neoclima.h:66
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kNeoclimaFreshOffset
Definition: ir_Neoclima.h:37
+
bool getFresh(void)
Get the Frsh (air) setting of the A/C.
Definition: ir_Neoclima.cpp:373
+
uint8_t getButton(void)
Get the Button/Command setting of the A/C.
Definition: ir_Neoclima.cpp:159
+
std::string String
Definition: IRremoteESP8266.h:1093
+
bool getSwingH(void)
Get the horizontal swing (Air Flow) setting of the A/C.
Definition: ir_Neoclima.cpp:347
+
const uint8_t kNeoclimaButtonFresh
Definition: ir_Neoclima.h:54
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Neoclima.cpp:360
+
const uint8_t kNeoclimaButtonAirFlow
Definition: ir_Neoclima.h:46
+ +
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Neoclima.cpp:71
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Neoclima.cpp:287
+
const uint8_t kNeoclimaButtonOffset
Definition: ir_Neoclima.h:38
+
const uint8_t kNeoclimaButtonTempDown
Definition: ir_Neoclima.h:43
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Neoclima.cpp:78
+
const uint8_t kNeoclima8CHeatOffset
Definition: ir_Neoclima.h:29
+
const uint8_t kNeoclimaSwingHOffset
Definition: ir_Neoclima.h:63
+
const uint8_t kNeoclimaPowerOffset
Definition: ir_Neoclima.h:58
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Neoclima.cpp:251
+
const uint8_t kNeoclimaFanSize
Definition: ir_Neoclima.h:65
+
bool getSwingV(void)
Get the vertical swing setting of the A/C.
Definition: ir_Neoclima.cpp:333
+
const uint8_t kNeoclimaButtonSize
Definition: ir_Neoclima.h:39
+
const uint8_t kNeoclimaLightOffset
Definition: ir_Neoclima.h:32
+
uint8_t remote_state[kNeoclimaStateLength]
State of the remote in code.
Definition: ir_Neoclima.h:157
+
const uint8_t kNeoclimaTempSize
Definition: ir_Neoclima.h:74
+
const uint8_t kNeoclimaButtonLight
Definition: ir_Neoclima.h:50
+
void setIon(const bool on)
Set the Ion (filter) setting of the A/C.
Definition: ir_Neoclima.cpp:392
+
const uint8_t kNeoclimaButtonSwing
Definition: ir_Neoclima.h:44
+
const uint8_t kNeoclimaButtonFollow
Definition: ir_Neoclima.h:52
+
bool getHold(void)
Get the Hold setting of the A/C.
Definition: ir_Neoclima.cpp:386
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Neoclima.h:151
+
const uint8_t kNeoclimaSwingVOff
Definition: ir_Neoclima.h:62
+
void setSwingV(const bool on)
Set the vertical swing setting of the A/C.
Definition: ir_Neoclima.cpp:325
+
void setEye(const bool on)
Set the Eye (Sensor) setting of the A/C.
Definition: ir_Neoclima.cpp:435
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Neoclima.cpp:225
+
const uint8_t kNeoclimaButtonSleep
Definition: ir_Neoclima.h:48
+
const uint8_t kNeoclimaTurboOffset
Definition: ir_Neoclima.h:34
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Neoclima.cpp:164
+
const uint8_t kNeoclimaFanMed
Definition: ir_Neoclima.h:68
+
void setFresh(const bool on)
Set the Fresh (air) setting of the A/C.
Definition: ir_Neoclima.cpp:366
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Neoclima.cpp:465
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Neoclima.cpp:171
+
const uint8_t kNeoclimaCool
Definition: ir_Neoclima.h:79
+
const uint8_t kNeoclimaHoldOffset
Definition: ir_Neoclima.h:33
+
const uint8_t kNeoclimaButton8CHeat
Definition: ir_Neoclima.h:55
+
bool getIon(void)
Get the Ion (filter) setting of the A/C.
Definition: ir_Neoclima.cpp:399
+
const uint8_t kNeoclimaSwingVOffset
Definition: ir_Neoclima.h:59
+
bool get8CHeat(void)
Get the 8°C Heat setting of the A/C.
Definition: ir_Neoclima.cpp:429
+
const uint8_t kNeoclimaFanOffest
Definition: ir_Neoclima.h:64
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Neoclima.cpp:212
+
const uint8_t kNeoclimaHeat
Definition: ir_Neoclima.h:82
+
void setButton(const uint8_t button)
Set the Button/Command pressed setting of the A/C.
Definition: ir_Neoclima.cpp:131
+
const uint8_t kNeoclimaButtonIon
Definition: ir_Neoclima.h:53
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Neoclima.cpp:493
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Neoclima.cpp:184
+
const uint8_t kNeoclimaFanLow
Definition: ir_Neoclima.h:69
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Neoclima.cpp:353
+
void checksum(const uint16_t length=kNeoclimaStateLength)
Calculate & update the checksum for the internal state.
Definition: ir_Neoclima.cpp:102
+
const uint8_t kNeoclimaModeOffset
Definition: ir_Neoclima.h:77
+
void setSwingH(const bool on)
Set the horizontal swing setting of the A/C.
Definition: ir_Neoclima.cpp:340
+
void send(const uint16_t repeat=kNeoclimaMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Neoclima.cpp:110
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Neoclima.cpp:167
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint16_t kNeoclimaMinRepeat
Definition: IRremoteESP8266.h:951
+
IRNeoclimaAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Neoclima.cpp:64
+
Class for handling detailed Neoclima A/C messages.
Definition: ir_Neoclima.h:86
+
bool getLight(void)
Get the Light (LED display) setting of the A/C.
Definition: ir_Neoclima.cpp:412
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Neoclima.cpp:312
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kNeoclimaStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Neoclima.cpp:94
+
const uint8_t kNeoclimaButtonTempUp
Definition: ir_Neoclima.h:42
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Nikai_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Nikai_8cpp.html new file mode 100644 index 000000000..95c82cd74 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Nikai_8cpp.html @@ -0,0 +1,301 @@ + + + + + + + +IRremoteESP8266: src/ir_Nikai.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Nikai.cpp File Reference
+
+
+ +

Nikai. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kNikaiTick = 500
 
const uint16_t kNikaiHdrMarkTicks = 8
 
const uint16_t kNikaiHdrMark = kNikaiHdrMarkTicks * kNikaiTick
 
const uint16_t kNikaiHdrSpaceTicks = 8
 
const uint16_t kNikaiHdrSpace = kNikaiHdrSpaceTicks * kNikaiTick
 
const uint16_t kNikaiBitMarkTicks = 1
 
const uint16_t kNikaiBitMark = kNikaiBitMarkTicks * kNikaiTick
 
const uint16_t kNikaiOneSpaceTicks = 2
 
const uint16_t kNikaiOneSpace = kNikaiOneSpaceTicks * kNikaiTick
 
const uint16_t kNikaiZeroSpaceTicks = 4
 
const uint16_t kNikaiZeroSpace = kNikaiZeroSpaceTicks * kNikaiTick
 
const uint16_t kNikaiMinGapTicks = 17
 
const uint16_t kNikaiMinGap = kNikaiMinGapTicks * kNikaiTick
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kNikaiBitMark

+ +
+
+ + + + +
const uint16_t kNikaiBitMark = kNikaiBitMarkTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiBitMarkTicks

+ +
+
+ + + + +
const uint16_t kNikaiBitMarkTicks = 1
+
+ +
+
+ +

◆ kNikaiHdrMark

+ +
+
+ + + + +
const uint16_t kNikaiHdrMark = kNikaiHdrMarkTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kNikaiHdrMarkTicks = 8
+
+ +
+
+ +

◆ kNikaiHdrSpace

+ +
+
+ + + + +
const uint16_t kNikaiHdrSpace = kNikaiHdrSpaceTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kNikaiHdrSpaceTicks = 8
+
+ +
+
+ +

◆ kNikaiMinGap

+ +
+
+ + + + +
const uint16_t kNikaiMinGap = kNikaiMinGapTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiMinGapTicks

+ +
+
+ + + + +
const uint16_t kNikaiMinGapTicks = 17
+
+ +
+
+ +

◆ kNikaiOneSpace

+ +
+
+ + + + +
const uint16_t kNikaiOneSpace = kNikaiOneSpaceTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kNikaiOneSpaceTicks = 2
+
+ +
+
+ +

◆ kNikaiTick

+ +
+
+ + + + +
const uint16_t kNikaiTick = 500
+
+ +
+
+ +

◆ kNikaiZeroSpace

+ +
+
+ + + + +
const uint16_t kNikaiZeroSpace = kNikaiZeroSpaceTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kNikaiZeroSpaceTicks = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8cpp.html new file mode 100644 index 000000000..8e777f8ec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8cpp.html @@ -0,0 +1,416 @@ + + + + + + + +IRremoteESP8266: src/ir_Panasonic.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Panasonic.cpp File Reference
+
+
+ +

Support for Panasonic protocols. Panasonic protocol originally added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kPanasonicTick = 432
 
const uint16_t kPanasonicHdrMarkTicks = 8
 
const uint16_t kPanasonicHdrMark = kPanasonicHdrMarkTicks * kPanasonicTick
 
const uint16_t kPanasonicHdrSpaceTicks = 4
 
const uint16_t kPanasonicHdrSpace = kPanasonicHdrSpaceTicks * kPanasonicTick
 
const uint16_t kPanasonicBitMarkTicks = 1
 
const uint16_t kPanasonicBitMark = kPanasonicBitMarkTicks * kPanasonicTick
 
const uint16_t kPanasonicOneSpaceTicks = 3
 
const uint16_t kPanasonicOneSpace = kPanasonicOneSpaceTicks * kPanasonicTick
 
const uint16_t kPanasonicZeroSpaceTicks = 1
 
const uint16_t kPanasonicZeroSpace = kPanasonicZeroSpaceTicks * kPanasonicTick
 
const uint16_t kPanasonicMinCommandLengthTicks = 378
 
const uint32_t kPanasonicMinCommandLength
 
const uint16_t kPanasonicEndGap = 5000
 
const uint16_t kPanasonicMinGapTicks
 
const uint32_t kPanasonicMinGap = kPanasonicMinGapTicks * kPanasonicTick
 
const uint16_t kPanasonicAcSectionGap = 10000
 
const uint16_t kPanasonicAcSection1Length = 8
 
const uint32_t kPanasonicAcMessageGap = kDefaultMessageGap
 
+

Detailed Description

+

Support for Panasonic protocols. Panasonic protocol originally added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)

+
See also
Panasonic https://github.com/z3t0/Arduino-IRremote
+
+http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615
+
+Panasonic A/C support heavily influenced by https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp Panasonic A/C Clock & Timer support: Reverse Engineering by MikkelTb Code by crankyoldgit
+

Variable Documentation

+ +

◆ kPanasonicAcMessageGap

+ +
+
+ + + + +
const uint32_t kPanasonicAcMessageGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kPanasonicAcSection1Length

+ +
+
+ + + + +
const uint16_t kPanasonicAcSection1Length = 8
+
+ +
+
+ +

◆ kPanasonicAcSectionGap

+ +
+
+ + + + +
const uint16_t kPanasonicAcSectionGap = 10000
+
+ +
+
+ +

◆ kPanasonicBitMark

+ +
+
+ + + + +
const uint16_t kPanasonicBitMark = kPanasonicBitMarkTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicBitMarkTicks

+ +
+
+ + + + +
const uint16_t kPanasonicBitMarkTicks = 1
+
+ +
+
+ +

◆ kPanasonicEndGap

+ +
+
+ + + + +
const uint16_t kPanasonicEndGap = 5000
+
+ +
+
+ +

◆ kPanasonicHdrMark

+ +
+
+ + + + +
const uint16_t kPanasonicHdrMark = kPanasonicHdrMarkTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kPanasonicHdrMarkTicks = 8
+
+ +
+
+ +

◆ kPanasonicHdrSpace

+ +
+
+ + + + +
const uint16_t kPanasonicHdrSpace = kPanasonicHdrSpaceTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kPanasonicHdrSpaceTicks = 4
+
+ +
+
+ +

◆ kPanasonicMinCommandLength

+ +
+
+ + + + +
const uint32_t kPanasonicMinCommandLength
+
+
+ +

◆ kPanasonicMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kPanasonicMinCommandLengthTicks = 378
+
+ +
+
+ +

◆ kPanasonicMinGap

+ +
+
+ + + + +
const uint32_t kPanasonicMinGap = kPanasonicMinGapTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicMinGapTicks

+ +
+
+ + + + +
const uint16_t kPanasonicMinGapTicks
+
+
+ +

◆ kPanasonicOneSpace

+ +
+
+ + + + +
const uint16_t kPanasonicOneSpace = kPanasonicOneSpaceTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kPanasonicOneSpaceTicks = 3
+
+ +
+
+ +

◆ kPanasonicTick

+ +
+
+ + + + +
const uint16_t kPanasonicTick = 432
+
+
+ +

◆ kPanasonicZeroSpace

+ +
+
+ + + + +
const uint16_t kPanasonicZeroSpace = kPanasonicZeroSpaceTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kPanasonicZeroSpaceTicks = 1
+
+ +
+
+
+
const uint16_t kPanasonicHdrMarkTicks
Definition: ir_Panasonic.cpp:29
+
const uint16_t kPanasonicBits
Definition: IRremoteESP8266.h:952
+
const uint16_t kPanasonicTick
Definition: ir_Panasonic.cpp:28
+
const uint16_t kPanasonicBitMarkTicks
Definition: ir_Panasonic.cpp:33
+
const uint16_t kPanasonicOneSpaceTicks
Definition: ir_Panasonic.cpp:35
+
const uint16_t kPanasonicHdrSpaceTicks
Definition: ir_Panasonic.cpp:31
+
const uint16_t kPanasonicMinCommandLengthTicks
Definition: ir_Panasonic.cpp:39
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h.html new file mode 100644 index 000000000..1eab81246 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h.html @@ -0,0 +1,826 @@ + + + + + + + +IRremoteESP8266: src/ir_Panasonic.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Panasonic.h File Reference
+
+
+ +

Support for Panasonic protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRPanasonicAc
 Class for handling detailed Panasonic A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kPanasonicFreq = 36700
 
const uint16_t kPanasonicAcExcess = 0
 
const uint16_t kPanasonicAcTolerance = 40
 
const uint8_t kPanasonicAcAuto = 0
 
const uint8_t kPanasonicAcDry = 2
 
const uint8_t kPanasonicAcCool = 3
 
const uint8_t kPanasonicAcHeat = 4
 
const uint8_t kPanasonicAcFan = 6
 
const uint8_t kPanasonicAcFanMin = 0
 
const uint8_t kPanasonicAcFanMed = 2
 
const uint8_t kPanasonicAcFanMax = 4
 
const uint8_t kPanasonicAcFanAuto = 7
 
const uint8_t kPanasonicAcFanDelta = 3
 
const uint8_t kPanasonicAcPowerOffset = 0
 
const uint8_t kPanasonicAcTempOffset = 1
 
const uint8_t kPanasonicAcTempSize = 5
 
const uint8_t kPanasonicAcMinTemp = 16
 
const uint8_t kPanasonicAcMaxTemp = 30
 
const uint8_t kPanasonicAcFanModeTemp = 27
 
const uint8_t kPanasonicAcQuietOffset = 0
 
const uint8_t kPanasonicAcPowerfulOffset = 5
 
const uint8_t kPanasonicAcQuietCkpOffset = kPanasonicAcPowerfulOffset
 
const uint8_t kPanasonicAcPowerfulCkpOffset = kPanasonicAcQuietOffset
 
const uint8_t kPanasonicAcSwingVHighest = 0x1
 
const uint8_t kPanasonicAcSwingVHigh = 0x2
 
const uint8_t kPanasonicAcSwingVMiddle = 0x3
 
const uint8_t kPanasonicAcSwingVLow = 0x4
 
const uint8_t kPanasonicAcSwingVLowest = 0x5
 
const uint8_t kPanasonicAcSwingVAuto = 0xF
 
const uint8_t kPanasonicAcSwingHMiddle = 0x6
 
const uint8_t kPanasonicAcSwingHFullLeft = 0x9
 
const uint8_t kPanasonicAcSwingHLeft = 0xA
 
const uint8_t kPanasonicAcSwingHRight = 0xB
 
const uint8_t kPanasonicAcSwingHFullRight = 0xC
 
const uint8_t kPanasonicAcSwingHAuto = 0xD
 
const uint8_t kPanasonicAcChecksumInit = 0xF4
 
const uint8_t kPanasonicAcOnTimerOffset = 1
 
const uint8_t kPanasonicAcOffTimerOffset = 2
 
const uint8_t kPanasonicAcTimeSize = 11
 
const uint8_t kPanasonicAcTimeOverflowSize = 3
 
const uint16_t kPanasonicAcTimeMax = 23 * 60 + 59
 
const uint16_t kPanasonicAcTimeSpecial = 0x600
 
const uint8_t kPanasonicAcIonFilterByte = 22
 
const uint8_t kPanasonicAcIonFilterOffset = 0
 
const uint8_t kPanasonicKnownGoodState [kPanasonicAcStateLength]
 
+

Detailed Description

+

Support for Panasonic protocols.

+
See also
Panasonic A/C support heavily influenced by https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp
+

Variable Documentation

+ +

◆ kPanasonicAcAuto

+ +
+
+ + + + +
const uint8_t kPanasonicAcAuto = 0
+
+ +
+
+ +

◆ kPanasonicAcChecksumInit

+ +
+
+ + + + +
const uint8_t kPanasonicAcChecksumInit = 0xF4
+
+ +
+
+ +

◆ kPanasonicAcCool

+ +
+
+ + + + +
const uint8_t kPanasonicAcCool = 3
+
+ +
+
+ +

◆ kPanasonicAcDry

+ +
+
+ + + + +
const uint8_t kPanasonicAcDry = 2
+
+ +
+
+ +

◆ kPanasonicAcExcess

+ +
+
+ + + + +
const uint16_t kPanasonicAcExcess = 0
+
+ +
+
+ +

◆ kPanasonicAcFan

+ +
+
+ + + + +
const uint8_t kPanasonicAcFan = 6
+
+ +
+
+ +

◆ kPanasonicAcFanAuto

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanAuto = 7
+
+ +
+
+ +

◆ kPanasonicAcFanDelta

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanDelta = 3
+
+ +
+
+ +

◆ kPanasonicAcFanMax

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanMax = 4
+
+ +
+
+ +

◆ kPanasonicAcFanMed

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanMed = 2
+
+ +
+
+ +

◆ kPanasonicAcFanMin

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanMin = 0
+
+ +
+
+ +

◆ kPanasonicAcFanModeTemp

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanModeTemp = 27
+
+ +
+
+ +

◆ kPanasonicAcHeat

+ +
+
+ + + + +
const uint8_t kPanasonicAcHeat = 4
+
+ +
+
+ +

◆ kPanasonicAcIonFilterByte

+ +
+
+ + + + +
const uint8_t kPanasonicAcIonFilterByte = 22
+
+ +
+
+ +

◆ kPanasonicAcIonFilterOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcIonFilterOffset = 0
+
+ +
+
+ +

◆ kPanasonicAcMaxTemp

+ +
+
+ + + + +
const uint8_t kPanasonicAcMaxTemp = 30
+
+ +
+
+ +

◆ kPanasonicAcMinTemp

+ +
+
+ + + + +
const uint8_t kPanasonicAcMinTemp = 16
+
+ +
+
+ +

◆ kPanasonicAcOffTimerOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcOffTimerOffset = 2
+
+ +
+
+ +

◆ kPanasonicAcOnTimerOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcOnTimerOffset = 1
+
+ +
+
+ +

◆ kPanasonicAcPowerfulCkpOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcPowerfulCkpOffset = kPanasonicAcQuietOffset
+
+ +
+
+ +

◆ kPanasonicAcPowerfulOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcPowerfulOffset = 5
+
+ +
+
+ +

◆ kPanasonicAcPowerOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcPowerOffset = 0
+
+ +
+
+ +

◆ kPanasonicAcQuietCkpOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcQuietCkpOffset = kPanasonicAcPowerfulOffset
+
+ +
+
+ +

◆ kPanasonicAcQuietOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcQuietOffset = 0
+
+ +
+
+ +

◆ kPanasonicAcSwingHAuto

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHAuto = 0xD
+
+ +
+
+ +

◆ kPanasonicAcSwingHFullLeft

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHFullLeft = 0x9
+
+ +
+
+ +

◆ kPanasonicAcSwingHFullRight

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHFullRight = 0xC
+
+ +
+
+ +

◆ kPanasonicAcSwingHLeft

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHLeft = 0xA
+
+ +
+
+ +

◆ kPanasonicAcSwingHMiddle

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHMiddle = 0x6
+
+ +
+
+ +

◆ kPanasonicAcSwingHRight

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHRight = 0xB
+
+ +
+
+ +

◆ kPanasonicAcSwingVAuto

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVAuto = 0xF
+
+ +
+
+ +

◆ kPanasonicAcSwingVHigh

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVHigh = 0x2
+
+ +
+
+ +

◆ kPanasonicAcSwingVHighest

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVHighest = 0x1
+
+ +
+
+ +

◆ kPanasonicAcSwingVLow

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVLow = 0x4
+
+ +
+
+ +

◆ kPanasonicAcSwingVLowest

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVLowest = 0x5
+
+ +
+
+ +

◆ kPanasonicAcSwingVMiddle

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVMiddle = 0x3
+
+ +
+
+ +

◆ kPanasonicAcTempOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcTempOffset = 1
+
+ +
+
+ +

◆ kPanasonicAcTempSize

+ +
+
+ + + + +
const uint8_t kPanasonicAcTempSize = 5
+
+ +
+
+ +

◆ kPanasonicAcTimeMax

+ +
+
+ + + + +
const uint16_t kPanasonicAcTimeMax = 23 * 60 + 59
+
+ +
+
+ +

◆ kPanasonicAcTimeOverflowSize

+ +
+
+ + + + +
const uint8_t kPanasonicAcTimeOverflowSize = 3
+
+ +
+
+ +

◆ kPanasonicAcTimeSize

+ +
+
+ + + + +
const uint8_t kPanasonicAcTimeSize = 11
+
+ +
+
+ +

◆ kPanasonicAcTimeSpecial

+ +
+
+ + + + +
const uint16_t kPanasonicAcTimeSpecial = 0x600
+
+ +
+
+ +

◆ kPanasonicAcTolerance

+ +
+
+ + + + +
const uint16_t kPanasonicAcTolerance = 40
+
+ +
+
+ +

◆ kPanasonicFreq

+ +
+
+ + + + +
const uint16_t kPanasonicFreq = 36700
+
+ +
+
+ +

◆ kPanasonicKnownGoodState

+ +
+
+ + + + +
const uint8_t kPanasonicKnownGoodState[kPanasonicAcStateLength]
+
+Initial value:
= {
+
0x02, 0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x06, 0x02,
+
0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+
0x00, 0x0E, 0xE0, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00}
+
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h_source.html new file mode 100644 index 000000000..5e233c8dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h_source.html @@ -0,0 +1,368 @@ + + + + + + + +IRremoteESP8266: src/ir_Panasonic.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Panasonic.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 David Conran
+
2 
+
6 
+
7 // Supports:
+
8 // Brand: Panasonic, Model: TV (PANASONIC)
+
9 // Brand: Panasonic, Model: NKE series A/C (PANASONIC_AC NKE/2)
+
10 // Brand: Panasonic, Model: DKE series A/C (PANASONIC_AC DKE/3)
+
11 // Brand: Panasonic, Model: DKW series A/C (PANASONIC_AC DKE/3)
+
12 // Brand: Panasonic, Model: PKR series A/C (PANASONIC_AC DKE/3)
+
13 // Brand: Panasonic, Model: JKE series A/C (PANASONIC_AC JKE/4)
+
14 // Brand: Panasonic, Model: CKP series A/C (PANASONIC_AC CKP/5)
+
15 // Brand: Panasonic, Model: RKR series A/C (PANASONIC_AC RKR/6)
+
16 // Brand: Panasonic, Model: CS-ME10CKPG A/C (PANASONIC_AC CKP/5)
+
17 // Brand: Panasonic, Model: CS-ME12CKPG A/C (PANASONIC_AC CKP/5)
+
18 // Brand: Panasonic, Model: CS-ME14CKPG A/C (PANASONIC_AC CKP/5)
+
19 // Brand: Panasonic, Model: CS-E7PKR A/C (PANASONIC_AC DKE/2)
+
20 // Brand: Panasonic, Model: CS-Z9RKR A/C (PANASONIC_AC RKR/6)
+
21 // Brand: Panasonic, Model: CS-YW9MKD A/C (PANASONIC_AC JKE/4)
+
22 // Brand: Panasonic, Model: A75C2311 remote (PANASONIC_AC CKP/5)
+
23 // Brand: Panasonic, Model: A75C2616-1 remote (PANASONIC_AC DKE/3)
+
24 // Brand: Panasonic, Model: A75C3704 remote (PANASONIC_AC DKE/3)
+
25 // Brand: Panasonic, Model: A75C3747 remote (PANASONIC_AC JKE/4)
+
26 
+
27 #ifndef IR_PANASONIC_H_
+
28 #define IR_PANASONIC_H_
+
29 
+
30 #define __STDC_LIMIT_MACROS
+
31 #include <stdint.h>
+
32 #ifdef ARDUINO
+
33 #include <Arduino.h>
+
34 #endif
+
35 #include "IRremoteESP8266.h"
+
36 #include "IRsend.h"
+
37 #ifdef UNIT_TEST
+
38 #include "IRsend_test.h"
+
39 #endif
+
40 
+
41 // Constants
+
42 const uint16_t kPanasonicFreq = 36700;
+
43 const uint16_t kPanasonicAcExcess = 0;
+
44 // Much higher than usual. See issue #540.
+
45 const uint16_t kPanasonicAcTolerance = 40;
+
46 
+
47 const uint8_t kPanasonicAcAuto = 0; // 0b000
+
48 const uint8_t kPanasonicAcDry = 2; // 0b010
+
49 const uint8_t kPanasonicAcCool = 3; // 0b011
+
50 const uint8_t kPanasonicAcHeat = 4; // 0b010
+
51 const uint8_t kPanasonicAcFan = 6; // 0b110
+
52 const uint8_t kPanasonicAcFanMin = 0;
+
53 const uint8_t kPanasonicAcFanMed = 2;
+
54 const uint8_t kPanasonicAcFanMax = 4;
+
55 const uint8_t kPanasonicAcFanAuto = 7;
+
56 const uint8_t kPanasonicAcFanDelta = 3;
+
57 const uint8_t kPanasonicAcPowerOffset = 0;
+
58 const uint8_t kPanasonicAcTempOffset = 1; // Bits
+
59 const uint8_t kPanasonicAcTempSize = 5; // Bits
+
60 const uint8_t kPanasonicAcMinTemp = 16; // Celsius
+
61 const uint8_t kPanasonicAcMaxTemp = 30; // Celsius
+
62 const uint8_t kPanasonicAcFanModeTemp = 27; // Celsius
+
63 const uint8_t kPanasonicAcQuietOffset = 0;
+
64 const uint8_t kPanasonicAcPowerfulOffset = 5; // 0b100000
+
65 // CKP & RKR models have Powerful and Quiet bits swapped.
+ + +
68 const uint8_t kPanasonicAcSwingVHighest = 0x1; // 0b0001
+
69 const uint8_t kPanasonicAcSwingVHigh = 0x2; // 0b0010
+
70 const uint8_t kPanasonicAcSwingVMiddle = 0x3; // 0b0011
+
71 const uint8_t kPanasonicAcSwingVLow = 0x4; // 0b0100
+
72 const uint8_t kPanasonicAcSwingVLowest = 0x5; // 0b0101
+
73 const uint8_t kPanasonicAcSwingVAuto = 0xF; // 0b1111
+
74 
+
75 const uint8_t kPanasonicAcSwingHMiddle = 0x6; // 0b0110
+
76 const uint8_t kPanasonicAcSwingHFullLeft = 0x9; // 0b1001
+
77 const uint8_t kPanasonicAcSwingHLeft = 0xA; // 0b1010
+
78 const uint8_t kPanasonicAcSwingHRight = 0xB; // 0b1011
+
79 const uint8_t kPanasonicAcSwingHFullRight = 0xC; // 0b1100
+
80 const uint8_t kPanasonicAcSwingHAuto = 0xD; // 0b1101
+
81 const uint8_t kPanasonicAcChecksumInit = 0xF4;
+
82 const uint8_t kPanasonicAcOnTimerOffset = 1;
+
83 const uint8_t kPanasonicAcOffTimerOffset = 2;
+
84 const uint8_t kPanasonicAcTimeSize = 11; // Bits
+
85 const uint8_t kPanasonicAcTimeOverflowSize = 3; // Bits
+
86 const uint16_t kPanasonicAcTimeMax = 23 * 60 + 59; // Mins since midnight.
+
87 const uint16_t kPanasonicAcTimeSpecial = 0x600;
+
88 
+
89 const uint8_t kPanasonicAcIonFilterByte = 22; // Byte
+
90 const uint8_t kPanasonicAcIonFilterOffset = 0; // Bit
+
91 
+ +
93  0x02, 0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x06, 0x02,
+
94  0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+
95  0x00, 0x0E, 0xE0, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00};
+
96 
+ +
99  public:
+
100  explicit IRPanasonicAc(const uint16_t pin, const bool inverted = false,
+
101  const bool use_modulation = true);
+
102  void stateReset(void);
+
103 #if SEND_PANASONIC
+
104  void send(const uint16_t repeat = kPanasonicAcDefaultRepeat);
+
109  int8_t calibrate(void) { return _irsend.calibrate(); }
+
110 #endif // SEND_PANASONIC
+
111  void begin(void);
+
112  void on(void);
+
113  void off(void);
+
114  void setPower(const bool on);
+
115  bool getPower(void);
+
116  void setTemp(const uint8_t temp, const bool remember = true);
+
117  uint8_t getTemp(void);
+
118  void setFan(const uint8_t fan);
+
119  uint8_t getFan(void);
+
120  void setMode(const uint8_t mode);
+
121  uint8_t getMode(void);
+
122  void setRaw(const uint8_t state[]);
+
123  uint8_t *getRaw(void);
+
124  static bool validChecksum(const uint8_t *state,
+
125  const uint16_t length = kPanasonicAcStateLength);
+
126  static uint8_t calcChecksum(const uint8_t *state,
+
127  const uint16_t length = kPanasonicAcStateLength);
+
128  void setQuiet(const bool on);
+
129  bool getQuiet(void);
+
130  void setPowerful(const bool on);
+
131  bool getPowerful(void);
+
132  void setIon(const bool on);
+
133  bool getIon(void);
+
134  void setModel(const panasonic_ac_remote_model_t model);
+ +
136  void setSwingVertical(const uint8_t elevation);
+
137  uint8_t getSwingVertical(void);
+
138  void setSwingHorizontal(const uint8_t direction);
+
139  uint8_t getSwingHorizontal(void);
+
140  static uint16_t encodeTime(const uint8_t hours, const uint8_t mins);
+
141  uint16_t getClock(void);
+
142  void setClock(const uint16_t mins_since_midnight);
+
143  uint16_t getOnTimer(void);
+
144  void setOnTimer(const uint16_t mins_since_midnight, const bool enable = true);
+
145  void cancelOnTimer(void);
+
146  bool isOnTimerEnabled(void);
+
147  uint16_t getOffTimer(void);
+
148  void setOffTimer(const uint16_t mins_since_midnight,
+
149  const bool enable = true);
+
150  void cancelOffTimer(void);
+
151  bool isOffTimerEnabled(void);
+
152  static uint8_t convertMode(const stdAc::opmode_t mode);
+
153  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
154  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
155  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
156  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
157  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
158  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
159  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
160  stdAc::state_t toCommon(void);
+
161  String toString(void);
+
162 #ifndef UNIT_TEST
+
163 
+
164  private:
+ +
166 #else // UNIT_TEST
+
167  IRsendTest _irsend;
+
169 #endif // UNIT_TEST
+ +
172  uint8_t _swingh;
+
173  uint8_t _temp;
+
174  void fixChecksum(const uint16_t length = kPanasonicAcStateLength);
+
175  static uint16_t _getTime(const uint8_t ptr[]);
+
176  static void _setTime(uint8_t * const ptr, const uint16_t mins_since_midnight,
+
177  const bool round_down);
+
178 };
+
179 
+
180 #endif // IR_PANASONIC_H_
+
+
const uint8_t kPanasonicAcFanAuto
Definition: ir_Panasonic.h:55
+
static uint16_t _getTime(const uint8_t ptr[])
Get the time from a given pointer location.
Definition: ir_Panasonic.cpp:540
+
Class for handling detailed Panasonic A/C messages.
Definition: ir_Panasonic.h:98
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Panasonic.cpp:385
+
const uint8_t kPanasonicAcIonFilterOffset
Definition: ir_Panasonic.h:90
+
const uint8_t kPanasonicAcAuto
Definition: ir_Panasonic.h:47
+
const uint8_t kPanasonicAcTimeSize
Definition: ir_Panasonic.h:84
+
void setRaw(const uint8_t state[])
Set the internal state from a valid code for this protocol.
Definition: ir_Panasonic.cpp:322
+
const uint8_t kPanasonicAcSwingHRight
Definition: ir_Panasonic.h:78
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
const uint8_t kPanasonicAcFanMin
Definition: ir_Panasonic.h:52
+
uint16_t getOffTimer(void)
Get the Off Timer time value.
Definition: ir_Panasonic.cpp:601
+
const uint8_t kPanasonicAcQuietOffset
Definition: ir_Panasonic.h:63
+
const uint8_t kPanasonicAcOffTimerOffset
Definition: ir_Panasonic.h:83
+
const uint16_t kPanasonicAcTolerance
Definition: ir_Panasonic.h:45
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint16_t kPanasonicAcExcess
Definition: ir_Panasonic.h:43
+
uint8_t _swingh
Definition: ir_Panasonic.h:172
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a standard A/C vertical swing into its native setting.
Definition: ir_Panasonic.cpp:684
+
const uint8_t kPanasonicAcPowerfulOffset
Definition: ir_Panasonic.h:64
+
static uint16_t encodeTime(const uint8_t hours, const uint8_t mins)
Convert standard (military/24hr) time to nr. of minutes since midnight.
Definition: ir_Panasonic.cpp:532
+
const uint8_t kPanasonicAcTimeOverflowSize
Definition: ir_Panasonic.h:85
+
const uint8_t kPanasonicAcFanMed
Definition: ir_Panasonic.h:53
+ +
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Panasonic.cpp:457
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Panasonic.cpp:472
+
void setQuiet(const bool on)
Set the Quiet setting of the A/C.
Definition: ir_Panasonic.cpp:491
+
uint8_t _temp
Definition: ir_Panasonic.h:173
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
void setSwingVertical(const uint8_t elevation)
Control the vertical swing setting.
Definition: ir_Panasonic.cpp:411
+
std::string String
Definition: IRremoteESP8266.h:1093
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Panasonic.cpp:725
+
void setIon(const bool on)
Set the Ion (filter) setting of the A/C.
Definition: ir_Panasonic.cpp:648
+
const uint8_t kPanasonicAcPowerfulCkpOffset
Definition: ir_Panasonic.h:67
+
const uint8_t kPanasonicAcSwingHAuto
Definition: ir_Panasonic.h:80
+
const uint8_t kPanasonicAcMinTemp
Definition: ir_Panasonic.h:60
+
const uint8_t kPanasonicAcPowerOffset
Definition: ir_Panasonic.h:57
+
const uint8_t kPanasonicAcHeat
Definition: ir_Panasonic.h:50
+
void send(const uint16_t repeat=kPanasonicAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Panasonic.cpp:239
+
uint16_t getClock(void)
Get the current clock time value.
Definition: ir_Panasonic.cpp:550
+
bool getPower(void)
Get the A/C power state of the remote.
Definition: ir_Panasonic.cpp:344
+
bool getQuiet(void)
Get the Quiet setting of the A/C.
Definition: ir_Panasonic.cpp:479
+
panasonic_ac_remote_model_t
Panasonic A/C model numbers.
Definition: IRsend.h:141
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
void setOffTimer(const uint16_t mins_since_midnight, const bool enable=true)
Set/Enable the Off Timer.
Definition: ir_Panasonic.cpp:611
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Panasonic.cpp:762
+
static uint8_t calcChecksum(const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Panasonic.cpp:225
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Panasonic.cpp:657
+
const uint8_t kPanasonicAcChecksumInit
Definition: ir_Panasonic.h:81
+
static void _setTime(uint8_t *const ptr, const uint16_t mins_since_midnight, const bool round_down)
Set the time at a given pointer location.
Definition: ir_Panasonic.cpp:557
+
uint8_t getSwingVertical(void)
Get the current vertical swing setting.
Definition: ir_Panasonic.cpp:405
+
const uint16_t kPanasonicAcDefaultRepeat
Definition: IRremoteESP8266.h:958
+
const uint8_t kPanasonicAcSwingHFullRight
Definition: ir_Panasonic.h:79
+
const uint8_t kPanasonicAcSwingHLeft
Definition: ir_Panasonic.h:77
+
bool getPowerful(void)
Get the Powerful (Turbo) setting of the A/C.
Definition: ir_Panasonic.cpp:504
+
void setSwingHorizontal(const uint8_t direction)
Control the horizontal swing setting.
Definition: ir_Panasonic.cpp:428
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Panasonic.cpp:315
+
const uint16_t kPanasonicAcStateLength
Definition: IRremoteESP8266.h:954
+
const uint8_t kPanasonicAcSwingHMiddle
Definition: ir_Panasonic.h:75
+
const uint8_t kPanasonicAcCool
Definition: ir_Panasonic.h:49
+
const uint16_t kPanasonicFreq
Definition: ir_Panasonic.h:42
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Panasonic.cpp:739
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Panasonic.h:165
+
void setOnTimer(const uint16_t mins_since_midnight, const bool enable=true)
Set/Enable the On Timer.
Definition: ir_Panasonic.cpp:582
+
void on(void)
Change the power setting to On.
Definition: ir_Panasonic.cpp:349
+
IRPanasonicAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Panasonic.cpp:197
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Panasonic.cpp:788
+
const uint8_t kPanasonicAcQuietCkpOffset
Definition: ir_Panasonic.h:66
+
const uint8_t kPanasonicKnownGoodState[kPanasonicAcStateLength]
Definition: ir_Panasonic.h:92
+
const uint8_t kPanasonicAcSwingVAuto
Definition: ir_Panasonic.h:73
+
const uint8_t kPanasonicAcSwingVHigh
Definition: ir_Panasonic.h:69
+
bool isOnTimerEnabled(void)
Check if the On Timer is Enabled.
Definition: ir_Panasonic.cpp:595
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Panasonic.cpp:209
+
void fixChecksum(const uint16_t length=kPanasonicAcStateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Panasonic.cpp:232
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Panasonic.h:109
+
void setPower(const bool on)
Control the power state of the A/C unit.
Definition: ir_Panasonic.cpp:336
+
const uint8_t kPanasonicAcTempOffset
Definition: ir_Panasonic.h:58
+
void setClock(const uint16_t mins_since_midnight)
Set the current clock time value.
Definition: ir_Panasonic.cpp:571
+
const uint16_t kPanasonicAcTimeSpecial
Definition: ir_Panasonic.h:87
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Panasonic.cpp:362
+
const uint8_t kPanasonicAcSwingVLow
Definition: ir_Panasonic.h:71
+
void cancelOnTimer(void)
Cancel the On Timer.
Definition: ir_Panasonic.cpp:591
+
uint8_t getSwingHorizontal(void)
Get the current horizontal swing setting.
Definition: ir_Panasonic.cpp:422
+
const uint8_t kPanasonicAcFan
Definition: ir_Panasonic.h:51
+
void off(void)
Change the power setting to Off.
Definition: ir_Panasonic.cpp:352
+
const uint8_t kPanasonicAcDry
Definition: ir_Panasonic.h:48
+
uint8_t remote_state[kPanasonicAcStateLength]
The state in code form.
Definition: ir_Panasonic.h:171
+
void cancelOffTimer(void)
Cancel the Off Timer.
Definition: ir_Panasonic.cpp:626
+
const uint8_t kPanasonicAcIonFilterByte
Definition: ir_Panasonic.h:89
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Panasonic.cpp:670
+
const uint8_t kPanasonicAcSwingVMiddle
Definition: ir_Panasonic.h:70
+
static bool validChecksum(const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Panasonic.cpp:215
+
const uint8_t kPanasonicAcFanDelta
Definition: ir_Panasonic.h:56
+
const uint8_t kPanasonicAcSwingVHighest
Definition: ir_Panasonic.h:68
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Panasonic.cpp:202
+
const uint8_t kPanasonicAcTempSize
Definition: ir_Panasonic.h:59
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Panasonic.cpp:356
+
void setPowerful(const bool on)
Set the Powerful (Turbo) setting of the A/C.
Definition: ir_Panasonic.cpp:516
+
const uint8_t kPanasonicAcFanModeTemp
Definition: ir_Panasonic.h:62
+
const uint8_t kPanasonicAcFanMax
Definition: ir_Panasonic.h:54
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Panasonic.cpp:712
+
bool isOffTimerEnabled(void)
Check if the Off Timer is Enabled.
Definition: ir_Panasonic.cpp:630
+
const uint16_t kPanasonicAcTimeMax
Definition: ir_Panasonic.h:86
+
const uint8_t kPanasonicAcSwingHFullLeft
Definition: ir_Panasonic.h:76
+
panasonic_ac_remote_model_t getModel(void)
Get/Detect the model of the A/C.
Definition: ir_Panasonic.cpp:296
+
bool getIon(void)
Get the Ion (filter) setting of the A/C.
Definition: ir_Panasonic.cpp:636
+
uint16_t getOnTimer(void)
Get the On Timer time value.
Definition: ir_Panasonic.cpp:577
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setModel(const panasonic_ac_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_Panasonic.cpp:246
+
const uint8_t kPanasonicAcMaxTemp
Definition: ir_Panasonic.h:61
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a standard A/C horizontal swing into its native setting.
Definition: ir_Panasonic.cpp:698
+
void setTemp(const uint8_t temp, const bool remember=true)
Set the temperature.
Definition: ir_Panasonic.cpp:394
+
const uint8_t kPanasonicAcSwingVLowest
Definition: ir_Panasonic.h:72
+
const uint8_t kPanasonicAcOnTimerOffset
Definition: ir_Panasonic.h:82
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Panasonic.cpp:753
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pioneer_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pioneer_8cpp.html new file mode 100644 index 000000000..bd39de11e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pioneer_8cpp.html @@ -0,0 +1,341 @@ + + + + + + + +IRremoteESP8266: src/ir_Pioneer.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Pioneer.cpp File Reference
+
+
+ +

Pioneer remote emulation. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kPioneerTick = 534
 
const uint16_t kPioneerHdrMarkTicks = 16
 
const uint16_t kPioneerHdrMark = kPioneerHdrMarkTicks * kPioneerTick
 
const uint16_t kPioneerHdrSpaceTicks = 8
 
const uint16_t kPioneerHdrSpace = kPioneerHdrSpaceTicks * kPioneerTick
 
const uint16_t kPioneerBitMarkTicks = 1
 
const uint16_t kPioneerBitMark = kPioneerBitMarkTicks * kPioneerTick
 
const uint16_t kPioneerOneSpaceTicks = 3
 
const uint16_t kPioneerOneSpace = kPioneerOneSpaceTicks * kPioneerTick
 
const uint16_t kPioneerZeroSpaceTicks = 1
 
const uint16_t kPioneerZeroSpace = kPioneerZeroSpaceTicks * kPioneerTick
 
const uint16_t kPioneerMinCommandLengthTicks = 159
 
const uint32_t kPioneerMinCommandLength
 
const uint16_t kPioneerMinGapTicks = 47
 
const uint32_t kPioneerMinGap = kPioneerMinGapTicks * kPioneerTick
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kPioneerBitMark

+ +
+
+ + + + +
const uint16_t kPioneerBitMark = kPioneerBitMarkTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerBitMarkTicks

+ +
+
+ + + + +
const uint16_t kPioneerBitMarkTicks = 1
+
+ +
+
+ +

◆ kPioneerHdrMark

+ +
+
+ + + + +
const uint16_t kPioneerHdrMark = kPioneerHdrMarkTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kPioneerHdrMarkTicks = 16
+
+ +
+
+ +

◆ kPioneerHdrSpace

+ +
+
+ + + + +
const uint16_t kPioneerHdrSpace = kPioneerHdrSpaceTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kPioneerHdrSpaceTicks = 8
+
+ +
+
+ +

◆ kPioneerMinCommandLength

+ +
+
+ + + + +
const uint32_t kPioneerMinCommandLength
+
+
+ +

◆ kPioneerMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kPioneerMinCommandLengthTicks = 159
+
+ +
+
+ +

◆ kPioneerMinGap

+ +
+
+ + + + +
const uint32_t kPioneerMinGap = kPioneerMinGapTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerMinGapTicks

+ +
+
+ + + + +
const uint16_t kPioneerMinGapTicks = 47
+
+ +
+
+ +

◆ kPioneerOneSpace

+ +
+
+ + + + +
const uint16_t kPioneerOneSpace = kPioneerOneSpaceTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kPioneerOneSpaceTicks = 3
+
+ +
+
+ +

◆ kPioneerTick

+ +
+
+ + + + +
const uint16_t kPioneerTick = 534
+
+ +
+
+ +

◆ kPioneerZeroSpace

+ +
+
+ + + + +
const uint16_t kPioneerZeroSpace = kPioneerZeroSpaceTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kPioneerZeroSpaceTicks = 1
+
+ +
+
+
+
const uint16_t kPioneerMinCommandLengthTicks
Definition: ir_Pioneer.cpp:34
+
const uint16_t kPioneerTick
Definition: ir_Pioneer.cpp:23
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pronto_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pronto_8cpp.html new file mode 100644 index 000000000..e962543bf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pronto_8cpp.html @@ -0,0 +1,195 @@ + + + + + + + +IRremoteESP8266: src/ir_Pronto.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Pronto.cpp File Reference
+
+
+ +

Pronto code message generation. +More...

+ + + + + + + + + + + + + + +

+Variables

const float kProntoFreqFactor = 0.241246
 
const uint16_t kProntoTypeOffset = 0
 
const uint16_t kProntoFreqOffset = 1
 
const uint16_t kProntoSeq1LenOffset = 2
 
const uint16_t kProntoSeq2LenOffset = 3
 
const uint16_t kProntoDataOffset = 4
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kProntoDataOffset

+ +
+
+ + + + +
const uint16_t kProntoDataOffset = 4
+
+ +
+
+ +

◆ kProntoFreqFactor

+ +
+
+ + + + +
const float kProntoFreqFactor = 0.241246
+
+ +
+
+ +

◆ kProntoFreqOffset

+ +
+
+ + + + +
const uint16_t kProntoFreqOffset = 1
+
+ +
+
+ +

◆ kProntoSeq1LenOffset

+ +
+
+ + + + +
const uint16_t kProntoSeq1LenOffset = 2
+
+ +
+
+ +

◆ kProntoSeq2LenOffset

+ +
+
+ + + + +
const uint16_t kProntoSeq2LenOffset = 3
+
+ +
+
+ +

◆ kProntoTypeOffset

+ +
+
+ + + + +
const uint16_t kProntoTypeOffset = 0
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RC5__RC6_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RC5__RC6_8cpp.html new file mode 100644 index 000000000..0a479e434 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RC5__RC6_8cpp.html @@ -0,0 +1,361 @@ + + + + + + + +IRremoteESP8266: src/ir_RC5_RC6.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_RC5_RC6.cpp File Reference
+
+
+ +

RC-5 & RC-6 support RC-5 & RC-6 support added from https://github.com/z3t0/Arduino-IRremote RC-5X support added by David Conran. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kRc5T1 = 889
 
const uint32_t kRc5MinCommandLength = 113778
 
const uint32_t kRc5MinGap = kRc5MinCommandLength - kRC5RawBits * (2 * kRc5T1)
 
const uint16_t kRc5ToggleMask = 0x800
 
const uint16_t kRc5SamplesMin = 11
 
const uint16_t kRc6Tick = 444
 
const uint16_t kRc6HdrMarkTicks = 6
 
const uint16_t kRc6HdrMark = kRc6HdrMarkTicks * kRc6Tick
 
const uint16_t kRc6HdrSpaceTicks = 2
 
const uint16_t kRc6HdrSpace = kRc6HdrSpaceTicks * kRc6Tick
 
const uint16_t kRc6RptLengthTicks = 187
 
const uint32_t kRc6RptLength = kRc6RptLengthTicks * kRc6Tick
 
const uint32_t kRc6ToggleMask = 0x10000UL
 
const uint16_t kRc6_36ToggleMask = 0x8000
 
const int16_t kMark = 0
 
const int16_t kSpace = 1
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMark

+ +
+
+ + + + +
const int16_t kMark = 0
+
+ +
+
+ +

◆ kRc5MinCommandLength

+ +
+
+ + + + +
const uint32_t kRc5MinCommandLength = 113778
+
+ +
+
+ +

◆ kRc5MinGap

+ +
+
+ + + + +
const uint32_t kRc5MinGap = kRc5MinCommandLength - kRC5RawBits * (2 * kRc5T1)
+
+ +
+
+ +

◆ kRc5SamplesMin

+ +
+
+ + + + +
const uint16_t kRc5SamplesMin = 11
+
+ +
+
+ +

◆ kRc5T1

+ +
+
+ + + + +
const uint16_t kRc5T1 = 889
+
+ +
+
+ +

◆ kRc5ToggleMask

+ +
+
+ + + + +
const uint16_t kRc5ToggleMask = 0x800
+
+ +
+
+ +

◆ kRc6_36ToggleMask

+ +
+
+ + + + +
const uint16_t kRc6_36ToggleMask = 0x8000
+
+ +
+
+ +

◆ kRc6HdrMark

+ +
+
+ + + + +
const uint16_t kRc6HdrMark = kRc6HdrMarkTicks * kRc6Tick
+
+ +
+
+ +

◆ kRc6HdrMarkTicks

+ +
+
+ + + + +
const uint16_t kRc6HdrMarkTicks = 6
+
+ +
+
+ +

◆ kRc6HdrSpace

+ +
+
+ + + + +
const uint16_t kRc6HdrSpace = kRc6HdrSpaceTicks * kRc6Tick
+
+ +
+
+ +

◆ kRc6HdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kRc6HdrSpaceTicks = 2
+
+ +
+
+ +

◆ kRc6RptLength

+ +
+
+ + + + +
const uint32_t kRc6RptLength = kRc6RptLengthTicks * kRc6Tick
+
+ +
+
+ +

◆ kRc6RptLengthTicks

+ +
+
+ + + + +
const uint16_t kRc6RptLengthTicks = 187
+
+ +
+
+ +

◆ kRc6Tick

+ +
+
+ + + + +
const uint16_t kRc6Tick = 444
+
+ +
+
+ +

◆ kRc6ToggleMask

+ +
+
+ + + + +
const uint32_t kRc6ToggleMask = 0x10000UL
+
+ +
+
+ +

◆ kSpace

+ +
+
+ + + + +
const int16_t kSpace = 1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RCMM_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RCMM_8cpp.html new file mode 100644 index 000000000..fcffe316b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RCMM_8cpp.html @@ -0,0 +1,429 @@ + + + + + + + +IRremoteESP8266: src/ir_RCMM.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_RCMM.cpp File Reference
+
+
+ +

Support for the Phillips RC-MM protocol. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kRcmmTick = 28
 
const uint16_t kRcmmHdrMarkTicks = 15
 
const uint16_t kRcmmHdrMark = 416
 
const uint16_t kRcmmHdrSpaceTicks = 10
 
const uint16_t kRcmmHdrSpace = 277
 
const uint16_t kRcmmBitMarkTicks = 6
 
const uint16_t kRcmmBitMark = 166
 
const uint16_t kRcmmBitSpace0Ticks = 10
 
const uint16_t kRcmmBitSpace0 = 277
 
const uint16_t kRcmmBitSpace1Ticks = 16
 
const uint16_t kRcmmBitSpace1 = 444
 
const uint16_t kRcmmBitSpace2Ticks = 22
 
const uint16_t kRcmmBitSpace2 = 611
 
const uint16_t kRcmmBitSpace3Ticks = 28
 
const uint16_t kRcmmBitSpace3 = 777
 
const uint16_t kRcmmRptLengthTicks = 992
 
const uint32_t kRcmmRptLength = 27778
 
const uint16_t kRcmmMinGapTicks = 120
 
const uint32_t kRcmmMinGap = 3360
 
const uint8_t kRcmmTolerance = 10
 
const uint16_t kRcmmExcess = 50
 
+

Detailed Description

+

Support for the Phillips RC-MM protocol.

+
See also
http://www.sbprojects.com/knowledge/ir/rcmm.php
+

Variable Documentation

+ +

◆ kRcmmBitMark

+ +
+
+ + + + +
const uint16_t kRcmmBitMark = 166
+
+ +
+
+ +

◆ kRcmmBitMarkTicks

+ +
+
+ + + + +
const uint16_t kRcmmBitMarkTicks = 6
+
+ +
+
+ +

◆ kRcmmBitSpace0

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace0 = 277
+
+ +
+
+ +

◆ kRcmmBitSpace0Ticks

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace0Ticks = 10
+
+ +
+
+ +

◆ kRcmmBitSpace1

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace1 = 444
+
+ +
+
+ +

◆ kRcmmBitSpace1Ticks

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace1Ticks = 16
+
+ +
+
+ +

◆ kRcmmBitSpace2

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace2 = 611
+
+ +
+
+ +

◆ kRcmmBitSpace2Ticks

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace2Ticks = 22
+
+ +
+
+ +

◆ kRcmmBitSpace3

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace3 = 777
+
+ +
+
+ +

◆ kRcmmBitSpace3Ticks

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace3Ticks = 28
+
+ +
+
+ +

◆ kRcmmExcess

+ +
+
+ + + + +
const uint16_t kRcmmExcess = 50
+
+ +
+
+ +

◆ kRcmmHdrMark

+ +
+
+ + + + +
const uint16_t kRcmmHdrMark = 416
+
+ +
+
+ +

◆ kRcmmHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kRcmmHdrMarkTicks = 15
+
+ +
+
+ +

◆ kRcmmHdrSpace

+ +
+
+ + + + +
const uint16_t kRcmmHdrSpace = 277
+
+ +
+
+ +

◆ kRcmmHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kRcmmHdrSpaceTicks = 10
+
+ +
+
+ +

◆ kRcmmMinGap

+ +
+
+ + + + +
const uint32_t kRcmmMinGap = 3360
+
+ +
+
+ +

◆ kRcmmMinGapTicks

+ +
+
+ + + + +
const uint16_t kRcmmMinGapTicks = 120
+
+ +
+
+ +

◆ kRcmmRptLength

+ +
+
+ + + + +
const uint32_t kRcmmRptLength = 27778
+
+ +
+
+ +

◆ kRcmmRptLengthTicks

+ +
+
+ + + + +
const uint16_t kRcmmRptLengthTicks = 992
+
+ +
+
+ +

◆ kRcmmTick

+ +
+
+ + + + +
const uint16_t kRcmmTick = 28
+
+ +
+
+ +

◆ kRcmmTolerance

+ +
+
+ + + + +
const uint8_t kRcmmTolerance = 10
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8cpp.html new file mode 100644 index 000000000..c0203d881 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8cpp.html @@ -0,0 +1,529 @@ + + + + + + + +IRremoteESP8266: src/ir_Samsung.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Samsung.cpp File Reference
+
+
+ +

Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSamsungTick = 560
 
const uint16_t kSamsungHdrMarkTicks = 8
 
const uint16_t kSamsungHdrMark = kSamsungHdrMarkTicks * kSamsungTick
 
const uint16_t kSamsungHdrSpaceTicks = 8
 
const uint16_t kSamsungHdrSpace = kSamsungHdrSpaceTicks * kSamsungTick
 
const uint16_t kSamsungBitMarkTicks = 1
 
const uint16_t kSamsungBitMark = kSamsungBitMarkTicks * kSamsungTick
 
const uint16_t kSamsungOneSpaceTicks = 3
 
const uint16_t kSamsungOneSpace = kSamsungOneSpaceTicks * kSamsungTick
 
const uint16_t kSamsungZeroSpaceTicks = 1
 
const uint16_t kSamsungZeroSpace = kSamsungZeroSpaceTicks * kSamsungTick
 
const uint16_t kSamsungRptSpaceTicks = 4
 
const uint16_t kSamsungRptSpace = kSamsungRptSpaceTicks * kSamsungTick
 
const uint16_t kSamsungMinMessageLengthTicks = 193
 
const uint32_t kSamsungMinMessageLength
 
const uint16_t kSamsungMinGapTicks
 
const uint32_t kSamsungMinGap = kSamsungMinGapTicks * kSamsungTick
 
const uint16_t kSamsungAcHdrMark = 690
 
const uint16_t kSamsungAcHdrSpace = 17844
 
const uint8_t kSamsungAcSections = 2
 
const uint16_t kSamsungAcSectionMark = 3086
 
const uint16_t kSamsungAcSectionSpace = 8864
 
const uint16_t kSamsungAcSectionGap = 2886
 
const uint16_t kSamsungAcBitMark = 586
 
const uint16_t kSamsungAcOneSpace = 1432
 
const uint16_t kSamsungAcZeroSpace = 436
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSamsungAcBitMark

+ +
+
+ + + + +
const uint16_t kSamsungAcBitMark = 586
+
+ +
+
+ +

◆ kSamsungAcHdrMark

+ +
+
+ + + + +
const uint16_t kSamsungAcHdrMark = 690
+
+ +
+
+ +

◆ kSamsungAcHdrSpace

+ +
+
+ + + + +
const uint16_t kSamsungAcHdrSpace = 17844
+
+ +
+
+ +

◆ kSamsungAcOneSpace

+ +
+
+ + + + +
const uint16_t kSamsungAcOneSpace = 1432
+
+ +
+
+ +

◆ kSamsungAcSectionGap

+ +
+
+ + + + +
const uint16_t kSamsungAcSectionGap = 2886
+
+ +
+
+ +

◆ kSamsungAcSectionMark

+ +
+
+ + + + +
const uint16_t kSamsungAcSectionMark = 3086
+
+ +
+
+ +

◆ kSamsungAcSections

+ +
+
+ + + + +
const uint8_t kSamsungAcSections = 2
+
+ +
+
+ +

◆ kSamsungAcSectionSpace

+ +
+
+ + + + +
const uint16_t kSamsungAcSectionSpace = 8864
+
+ +
+
+ +

◆ kSamsungAcZeroSpace

+ +
+
+ + + + +
const uint16_t kSamsungAcZeroSpace = 436
+
+ +
+
+ +

◆ kSamsungBitMark

+ +
+
+ + + + +
const uint16_t kSamsungBitMark = kSamsungBitMarkTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungBitMarkTicks

+ +
+
+ + + + +
const uint16_t kSamsungBitMarkTicks = 1
+
+ +
+
+ +

◆ kSamsungHdrMark

+ +
+
+ + + + +
const uint16_t kSamsungHdrMark = kSamsungHdrMarkTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kSamsungHdrMarkTicks = 8
+
+ +
+
+ +

◆ kSamsungHdrSpace

+ +
+
+ + + + +
const uint16_t kSamsungHdrSpace = kSamsungHdrSpaceTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kSamsungHdrSpaceTicks = 8
+
+ +
+
+ +

◆ kSamsungMinGap

+ +
+
+ + + + +
const uint32_t kSamsungMinGap = kSamsungMinGapTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungMinGapTicks

+ +
+
+ + + + +
const uint16_t kSamsungMinGapTicks
+
+
+ +

◆ kSamsungMinMessageLength

+ +
+
+ + + + +
const uint32_t kSamsungMinMessageLength
+
+
+ +

◆ kSamsungMinMessageLengthTicks

+ +
+
+ + + + +
const uint16_t kSamsungMinMessageLengthTicks = 193
+
+ +
+
+ +

◆ kSamsungOneSpace

+ +
+
+ + + + +
const uint16_t kSamsungOneSpace = kSamsungOneSpaceTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kSamsungOneSpaceTicks = 3
+
+ +
+
+ +

◆ kSamsungRptSpace

+ +
+
+ + + + +
const uint16_t kSamsungRptSpace = kSamsungRptSpaceTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungRptSpaceTicks

+ +
+
+ + + + +
const uint16_t kSamsungRptSpaceTicks = 4
+
+ +
+
+ +

◆ kSamsungTick

+ +
+
+ + + + +
const uint16_t kSamsungTick = 560
+
+ +
+
+ +

◆ kSamsungZeroSpace

+ +
+
+ + + + +
const uint16_t kSamsungZeroSpace = kSamsungZeroSpaceTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kSamsungZeroSpaceTicks = 1
+
+ +
+
+
+
const uint16_t kSamsungMinMessageLengthTicks
Definition: ir_Samsung.cpp:36
+
const uint16_t kSamsungTick
Definition: ir_Samsung.cpp:23
+
const uint16_t kSamsungBitMarkTicks
Definition: ir_Samsung.cpp:28
+
const uint16_t kSamsungHdrMarkTicks
Definition: ir_Samsung.cpp:24
+
const uint16_t kSamsungOneSpaceTicks
Definition: ir_Samsung.cpp:30
+
const uint16_t kSamsungBits
Definition: IRremoteESP8266.h:967
+
const uint16_t kSamsungHdrSpaceTicks
Definition: ir_Samsung.cpp:26
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h.html new file mode 100644 index 000000000..09282ae84 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h.html @@ -0,0 +1,748 @@ + + + + + + + +IRremoteESP8266: src/ir_Samsung.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Samsung.h File Reference
+
+
+ +

Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRSamsungAc
 Class for handling detailed Samsung A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kSamsungAcPower1Offset = 5
 
const uint8_t kSamsungAcQuiet1Offset = 4
 
const uint8_t kSamsungAcQuiet5Offset = 5
 
const uint8_t kSamsungAcPower6Offset = 4
 
const uint8_t kSamsungAcPower6Size = 2
 
const uint8_t kSamsungAcPowerfulMask8 = 0b01010000
 
const uint8_t kSamsungAcSwingOffset = 4
 
const uint8_t kSamsungAcSwingSize = 3
 
const uint8_t kSamsungAcSwingMove = 0b010
 
const uint8_t kSamsungAcSwingStop = 0b111
 
const uint8_t kSamsungAcPowerful10Offset = 1
 
const uint8_t kSamsungAcPowerful10Size = 3
 
const uint8_t kSamsungAcPowerful10On = 0b011
 
const uint8_t kSamsungAcBreezeOffset = kSamsungAcPowerful10Offset
 
const uint8_t kSamsungAcBreezeSize = kSamsungAcPowerful10Size
 
const uint8_t kSamsungAcBreezeOn = 0b101
 
const uint8_t kSamsungAcDisplayOffset = 4
 
const uint8_t kSamsungAcClean10Offset = 7
 
const uint8_t kSamsungAcIonOffset = 0
 
const uint8_t kSamsungAcClean11Offset = 1
 
const uint8_t kSamsungAcMinTemp = 16
 
const uint8_t kSamsungAcMaxTemp = 30
 
const uint8_t kSamsungAcAutoTemp = 25
 
const uint8_t kSamsungAcModeOffset = 4
 
const uint8_t kSamsungAcAuto = 0
 
const uint8_t kSamsungAcCool = 1
 
const uint8_t kSamsungAcDry = 2
 
const uint8_t kSamsungAcFan = 3
 
const uint8_t kSamsungAcHeat = 4
 
const uint8_t kSamsungAcFanOffest = 1
 
const uint8_t kSamsungAcFanSize = 3
 
const uint8_t kSamsungAcFanAuto = 0
 
const uint8_t kSamsungAcFanLow = 2
 
const uint8_t kSamsungAcFanMed = 4
 
const uint8_t kSamsungAcFanHigh = 5
 
const uint8_t kSamsungAcFanAuto2 = 6
 
const uint8_t kSamsungAcFanTurbo = 7
 
const uint8_t kSamsungAcBeepOffset = 1
 
const uint16_t kSamsungAcSectionLength = 7
 
const uint64_t kSamsungAcPowerSection = 0x1D20F00000000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSamsungAcAuto

+ +
+
+ + + + +
const uint8_t kSamsungAcAuto = 0
+
+ +
+
+ +

◆ kSamsungAcAutoTemp

+ +
+
+ + + + +
const uint8_t kSamsungAcAutoTemp = 25
+
+ +
+
+ +

◆ kSamsungAcBeepOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcBeepOffset = 1
+
+ +
+
+ +

◆ kSamsungAcBreezeOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcBreezeOffset = kSamsungAcPowerful10Offset
+
+ +
+
+ +

◆ kSamsungAcBreezeOn

+ +
+
+ + + + +
const uint8_t kSamsungAcBreezeOn = 0b101
+
+ +
+
+ +

◆ kSamsungAcBreezeSize

+ +
+
+ + + + +
const uint8_t kSamsungAcBreezeSize = kSamsungAcPowerful10Size
+
+ +
+
+ +

◆ kSamsungAcClean10Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcClean10Offset = 7
+
+ +
+
+ +

◆ kSamsungAcClean11Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcClean11Offset = 1
+
+ +
+
+ +

◆ kSamsungAcCool

+ +
+
+ + + + +
const uint8_t kSamsungAcCool = 1
+
+ +
+
+ +

◆ kSamsungAcDisplayOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcDisplayOffset = 4
+
+ +
+
+ +

◆ kSamsungAcDry

+ +
+
+ + + + +
const uint8_t kSamsungAcDry = 2
+
+ +
+
+ +

◆ kSamsungAcFan

+ +
+
+ + + + +
const uint8_t kSamsungAcFan = 3
+
+ +
+
+ +

◆ kSamsungAcFanAuto

+ +
+
+ + + + +
const uint8_t kSamsungAcFanAuto = 0
+
+ +
+
+ +

◆ kSamsungAcFanAuto2

+ +
+
+ + + + +
const uint8_t kSamsungAcFanAuto2 = 6
+
+ +
+
+ +

◆ kSamsungAcFanHigh

+ +
+
+ + + + +
const uint8_t kSamsungAcFanHigh = 5
+
+ +
+
+ +

◆ kSamsungAcFanLow

+ +
+
+ + + + +
const uint8_t kSamsungAcFanLow = 2
+
+ +
+
+ +

◆ kSamsungAcFanMed

+ +
+
+ + + + +
const uint8_t kSamsungAcFanMed = 4
+
+ +
+
+ +

◆ kSamsungAcFanOffest

+ +
+
+ + + + +
const uint8_t kSamsungAcFanOffest = 1
+
+ +
+
+ +

◆ kSamsungAcFanSize

+ +
+
+ + + + +
const uint8_t kSamsungAcFanSize = 3
+
+ +
+
+ +

◆ kSamsungAcFanTurbo

+ +
+
+ + + + +
const uint8_t kSamsungAcFanTurbo = 7
+
+ +
+
+ +

◆ kSamsungAcHeat

+ +
+
+ + + + +
const uint8_t kSamsungAcHeat = 4
+
+ +
+
+ +

◆ kSamsungAcIonOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcIonOffset = 0
+
+ +
+
+ +

◆ kSamsungAcMaxTemp

+ +
+
+ + + + +
const uint8_t kSamsungAcMaxTemp = 30
+
+ +
+
+ +

◆ kSamsungAcMinTemp

+ +
+
+ + + + +
const uint8_t kSamsungAcMinTemp = 16
+
+ +
+
+ +

◆ kSamsungAcModeOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcModeOffset = 4
+
+ +
+
+ +

◆ kSamsungAcPower1Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcPower1Offset = 5
+
+ +
+
+ +

◆ kSamsungAcPower6Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcPower6Offset = 4
+
+ +
+
+ +

◆ kSamsungAcPower6Size

+ +
+
+ + + + +
const uint8_t kSamsungAcPower6Size = 2
+
+ +
+
+ +

◆ kSamsungAcPowerful10Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcPowerful10Offset = 1
+
+ +
+
+ +

◆ kSamsungAcPowerful10On

+ +
+
+ + + + +
const uint8_t kSamsungAcPowerful10On = 0b011
+
+ +
+
+ +

◆ kSamsungAcPowerful10Size

+ +
+
+ + + + +
const uint8_t kSamsungAcPowerful10Size = 3
+
+ +
+
+ +

◆ kSamsungAcPowerfulMask8

+ +
+
+ + + + +
const uint8_t kSamsungAcPowerfulMask8 = 0b01010000
+
+ +
+
+ +

◆ kSamsungAcPowerSection

+ +
+
+ + + + +
const uint64_t kSamsungAcPowerSection = 0x1D20F00000000
+
+ +
+
+ +

◆ kSamsungAcQuiet1Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcQuiet1Offset = 4
+
+ +
+
+ +

◆ kSamsungAcQuiet5Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcQuiet5Offset = 5
+
+ +
+
+ +

◆ kSamsungAcSectionLength

+ +
+
+ + + + +
const uint16_t kSamsungAcSectionLength = 7
+
+ +
+
+ +

◆ kSamsungAcSwingMove

+ +
+
+ + + + +
const uint8_t kSamsungAcSwingMove = 0b010
+
+ +
+
+ +

◆ kSamsungAcSwingOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcSwingOffset = 4
+
+ +
+
+ +

◆ kSamsungAcSwingSize

+ +
+
+ + + + +
const uint8_t kSamsungAcSwingSize = 3
+
+ +
+
+ +

◆ kSamsungAcSwingStop

+ +
+
+ + + + +
const uint8_t kSamsungAcSwingStop = 0b111
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h_source.html new file mode 100644 index 000000000..a6c27ffcd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h_source.html @@ -0,0 +1,335 @@ + + + + + + + +IRremoteESP8266: src/ir_Samsung.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Samsung.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 David Conran
+
9 
+
10 // Supports:
+
11 // Brand: Samsung, Model: UA55H6300 TV (SAMSUNG)
+
12 // Brand: Samsung, Model: BN59-01178B TV remote (SAMSUNG)
+
13 // Brand: Samsung, Model: DB63-03556X003 remote
+
14 // Brand: Samsung, Model: DB93-16761C remote
+
15 // Brand: Samsung, Model: IEC-R03 remote
+
16 // Brand: Samsung, Model: AK59-00167A Bluray remote (SAMSUNG36)
+
17 // Brand: Samsung, Model: AR09FSSDAWKNFA A/C (SAMSUNG_AC)
+
18 // Brand: Samsung, Model: AR12KSFPEWQNET A/C (SAMSUNG_AC)
+
19 // Brand: Samsung, Model: AR12HSSDBWKNEU A/C (SAMSUNG_AC)
+
20 // Brand: Samsung, Model: AR12NXCXAWKXEU A/C (SAMSUNG_AC)
+
21 
+
22 #ifndef IR_SAMSUNG_H_
+
23 #define IR_SAMSUNG_H_
+
24 
+
25 #define __STDC_LIMIT_MACROS
+
26 #include <stdint.h>
+
27 #ifndef UNIT_TEST
+
28 #include <Arduino.h>
+
29 #endif
+
30 #include "IRremoteESP8266.h"
+
31 #include "IRsend.h"
+
32 #ifdef UNIT_TEST
+
33 #include "IRsend_test.h"
+
34 #endif
+
35 
+
36 // Constants
+
37 
+
38 // SamsungAc
+
39 // Byte[1]
+
40 // Checksum 0b11110000 ???
+
41 const uint8_t kSamsungAcPower1Offset = 5; // Mask 0b00100000
+
42 const uint8_t kSamsungAcQuiet1Offset = 4; // Mask 0b00010000
+
43 // Byte[5]
+
44 const uint8_t kSamsungAcQuiet5Offset = 5;
+
45 // Byte[6]
+
46 const uint8_t kSamsungAcPower6Offset = 4; // Mask 0b00110000
+
47 const uint8_t kSamsungAcPower6Size = 2; // Bits
+
48 // Byte[8]
+
49 // Checksum 0b11110000 ???
+
50 const uint8_t kSamsungAcPowerfulMask8 = 0b01010000;
+
51 // Byte[9]
+
52 const uint8_t kSamsungAcSwingOffset = 4; // Mask 0b01110000
+
53 const uint8_t kSamsungAcSwingSize = 3; // Bits
+
54 const uint8_t kSamsungAcSwingMove = 0b010;
+
55 const uint8_t kSamsungAcSwingStop = 0b111;
+
56 // Byte[10]
+
57 const uint8_t kSamsungAcPowerful10Offset = 1; // Mask 0b00001110
+
58 const uint8_t kSamsungAcPowerful10Size = 3; // Mask 0b00001110
+
59 const uint8_t kSamsungAcPowerful10On = 0b011;
+
60 // Breeze (aka. WindFree)
+ + +
63 const uint8_t kSamsungAcBreezeOn = 0b101;
+
64 const uint8_t kSamsungAcDisplayOffset = 4; // Mask 0b00010000
+
65 const uint8_t kSamsungAcClean10Offset = 7; // Mask 0b10000000
+
66 // Byte[11]
+
67 const uint8_t kSamsungAcIonOffset = 0; // Mask 0b00000001
+
68 const uint8_t kSamsungAcClean11Offset = 1; // Mask 0b00000010
+
69 const uint8_t kSamsungAcMinTemp = 16; // C Mask 0b11110000
+
70 const uint8_t kSamsungAcMaxTemp = 30; // C Mask 0b11110000
+
71 const uint8_t kSamsungAcAutoTemp = 25; // C Mask 0b11110000
+
72 // Byte[12]
+
73 const uint8_t kSamsungAcModeOffset = 4; // Mask 0b01110000
+
74 const uint8_t kSamsungAcAuto = 0;
+
75 const uint8_t kSamsungAcCool = 1;
+
76 const uint8_t kSamsungAcDry = 2;
+
77 const uint8_t kSamsungAcFan = 3;
+
78 const uint8_t kSamsungAcHeat = 4;
+
79 const uint8_t kSamsungAcFanOffest = 1; // Mask 0b00001110
+
80 const uint8_t kSamsungAcFanSize = 3; // Bits
+
81 const uint8_t kSamsungAcFanAuto = 0;
+
82 const uint8_t kSamsungAcFanLow = 2;
+
83 const uint8_t kSamsungAcFanMed = 4;
+
84 const uint8_t kSamsungAcFanHigh = 5;
+
85 const uint8_t kSamsungAcFanAuto2 = 6;
+
86 const uint8_t kSamsungAcFanTurbo = 7;
+
87 // Byte[13]
+
88 const uint8_t kSamsungAcBeepOffset = 1; // Mask 0b00000010
+
89 
+
90 const uint16_t kSamsungAcSectionLength = 7;
+
91 const uint64_t kSamsungAcPowerSection = 0x1D20F00000000;
+
92 
+
93 // Classes
+
95 class IRSamsungAc {
+
96  public:
+
97  explicit IRSamsungAc(const uint16_t pin, const bool inverted = false,
+
98  const bool use_modulation = true);
+
99  void stateReset(const bool forcepower = true, const bool initialPower = true);
+
100 #if SEND_SAMSUNG_AC
+
101  void send(const uint16_t repeat = kSamsungAcDefaultRepeat,
+
102  const bool calcchecksum = true);
+
103  void sendExtended(const uint16_t repeat = kSamsungAcDefaultRepeat,
+
104  const bool calcchecksum = true);
+
105  void sendOn(const uint16_t repeat = kSamsungAcDefaultRepeat);
+
106  void sendOff(const uint16_t repeat = kSamsungAcDefaultRepeat);
+
111  int8_t calibrate(void) { return _irsend.calibrate(); }
+
112 #endif // SEND_SAMSUNG_AC
+
113  void begin(void);
+
114  void on(void);
+
115  void off(void);
+
116  void setPower(const bool on);
+
117  bool getPower(void);
+
118  void setTemp(const uint8_t temp);
+
119  uint8_t getTemp(void);
+
120  void setFan(const uint8_t speed);
+
121  uint8_t getFan(void);
+
122  void setMode(const uint8_t mode);
+
123  uint8_t getMode(void);
+
124  void setSwing(const bool on);
+
125  bool getSwing(void);
+
126  void setBeep(const bool on);
+
127  bool getBeep(void);
+
128  void setClean(const bool on);
+
129  bool getClean(void);
+
130  void setQuiet(const bool on);
+
131  bool getQuiet(void);
+
132  void setPowerful(const bool on);
+
133  bool getPowerful(void);
+
134  void setBreeze(const bool on);
+
135  bool getBreeze(void);
+
136  void setDisplay(const bool on);
+
137  bool getDisplay(void);
+
138  void setIon(const bool on);
+
139  bool getIon(void);
+
140  uint8_t* getRaw(void);
+
141  void setRaw(const uint8_t new_code[],
+
142  const uint16_t length = kSamsungAcStateLength);
+
143  static bool validChecksum(const uint8_t state[],
+
144  const uint16_t length = kSamsungAcStateLength);
+
145  static uint8_t calcChecksum(const uint8_t state[],
+
146  const uint16_t length = kSamsungAcStateLength);
+
147  uint8_t convertMode(const stdAc::opmode_t mode);
+
148  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
149  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
150  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
151  stdAc::state_t toCommon(void);
+
152  String toString(void);
+
153 #ifndef UNIT_TEST
+
154 
+
155  private:
+ +
157 #else // UNIT_TEST
+
158  IRsendTest _irsend;
+
160 #endif // UNIT_TEST
+ +
163  bool _forcepower;
+ +
165  void checksum(const uint16_t length = kSamsungAcStateLength);
+
166 };
+
167 
+
168 #endif // IR_SAMSUNG_H_
+
+
bool getIon(void)
Get the Ion (Filter) setting of the A/C.
Definition: ir_Samsung.cpp:636
+
const uint8_t kSamsungAcDry
Definition: ir_Samsung.h:76
+
Class for handling detailed Samsung A/C messages.
Definition: ir_Samsung.h:95
+
bool _forcepower
Hack to know when we need to send a special power mesg.
Definition: ir_Samsung.h:163
+
const uint8_t kSamsungAcCool
Definition: ir_Samsung.h:75
+
void setQuiet(const bool on)
Set the Quiet setting of the A/C.
Definition: ir_Samsung.cpp:563
+
const uint8_t kSamsungAcFanMed
Definition: ir_Samsung.h:83
+
void send(const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)
Send the current internal state as an IR message.
Definition: ir_Samsung.cpp:337
+
const uint8_t kSamsungAcFanAuto2
Definition: ir_Samsung.h:85
+
const uint8_t kSamsungAcAuto
Definition: ir_Samsung.h:74
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Samsung.h:156
+
IRSamsungAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Samsung.cpp:264
+
const uint8_t kSamsungAcFanHigh
Definition: ir_Samsung.h:84
+
const uint8_t kSamsungAcBreezeSize
Definition: ir_Samsung.h:62
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kSamsungAcFan
Definition: ir_Samsung.h:77
+
bool getBreeze(void)
Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree.
Definition: ir_Samsung.cpp:603
+
void setBreeze(const bool on)
Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree.
Definition: ir_Samsung.cpp:612
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Samsung.cpp:701
+
const uint8_t kSamsungAcSwingStop
Definition: ir_Samsung.h:55
+
const uint8_t kSamsungAcPower1Offset
Definition: ir_Samsung.h:41
+
bool getDisplay(void)
Get the Display (Light/LED) setting of the A/C.
Definition: ir_Samsung.cpp:624
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Samsung.cpp:480
+
const uint16_t kSamsungAcDefaultRepeat
Definition: IRremoteESP8266.h:973
+
const uint8_t kSamsungAcPowerful10On
Definition: ir_Samsung.h:59
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Samsung.cpp:438
+ +
void setSwing(const bool on)
Set the vertical swing setting of the A/C.
Definition: ir_Samsung.cpp:523
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Samsung.cpp:728
+
const uint16_t kSamsungAcSectionLength
Definition: ir_Samsung.h:90
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Samsung.cpp:285
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void setIon(const bool on)
Set the Ion (Filter) setting of the A/C.
Definition: ir_Samsung.cpp:642
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
void setRaw(const uint8_t new_code[], const uint16_t length=kSamsungAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Samsung.cpp:412
+
std::string String
Definition: IRremoteESP8266.h:1093
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Samsung.cpp:455
+
void sendOff(const uint16_t repeat=kSamsungAcDefaultRepeat)
Send the special extended "Off" message as the library can't seem to reproduce this message automatic...
Definition: ir_Samsung.cpp:392
+
const uint8_t kSamsungAcQuiet1Offset
Definition: ir_Samsung.h:42
+
bool getPowerful(void)
Get the Powerful (Turbo) setting of the A/C.
Definition: ir_Samsung.cpp:575
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Samsung.cpp:423
+
bool getBeep(void)
Get the Beep setting of the A/C.
Definition: ir_Samsung.cpp:530
+
const uint8_t kSamsungAcFanSize
Definition: ir_Samsung.h:80
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Samsung.cpp:662
+
uint8_t remote_state[kSamsungAcExtendedStateLength]
State in code form.
Definition: ir_Samsung.h:162
+
const uint8_t kSamsungAcPowerfulMask8
Definition: ir_Samsung.h:50
+
const uint16_t kSamsungAcStateLength
Definition: IRremoteESP8266.h:969
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kSamsungAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Samsung.cpp:310
+ +
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Samsung.cpp:446
+
const uint8_t kSamsungAcSwingOffset
Definition: ir_Samsung.h:52
+
const uint64_t kSamsungAcPowerSection
Definition: ir_Samsung.h:91
+
void setPowerful(const bool on)
Set the Powerful (Turbo) setting of the A/C.
Definition: ir_Samsung.cpp:584
+
const uint8_t kSamsungAcModeOffset
Definition: ir_Samsung.h:73
+
const uint16_t kSamsungAcExtendedStateLength
Definition: IRremoteESP8266.h:971
+
bool getQuiet(void)
Get the Quiet setting of the A/C.
Definition: ir_Samsung.cpp:556
+
const uint8_t kSamsungAcDisplayOffset
Definition: ir_Samsung.h:64
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Samsung.cpp:430
+
void setDisplay(const bool on)
Set the Display (Light/LED) setting of the A/C.
Definition: ir_Samsung.cpp:630
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Samsung.cpp:506
+
const uint8_t kSamsungAcBreezeOn
Definition: ir_Samsung.h:63
+
const uint8_t kSamsungAcPowerful10Offset
Definition: ir_Samsung.h:57
+
void stateReset(const bool forcepower=true, const bool initialPower=true)
Reset the internal state of the emulation.
Definition: ir_Samsung.cpp:274
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kSamsungAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Samsung.cpp:291
+
bool _lastsentpowerstate
Definition: ir_Samsung.h:164
+
const uint8_t kSamsungAcAutoTemp
Definition: ir_Samsung.h:71
+
const uint8_t kSamsungAcSwingMove
Definition: ir_Samsung.h:54
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Samsung.cpp:462
+
const uint8_t kSamsungAcBreezeOffset
Definition: ir_Samsung.h:61
+
const uint8_t kSamsungAcSwingSize
Definition: ir_Samsung.h:53
+
const uint8_t kSamsungAcFanLow
Definition: ir_Samsung.h:82
+
void setClean(const bool on)
Set the Clean setting of the A/C.
Definition: ir_Samsung.cpp:549
+
const uint8_t kSamsungAcHeat
Definition: ir_Samsung.h:78
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Samsung.cpp:676
+
void sendOn(const uint16_t repeat=kSamsungAcDefaultRepeat)
Send the special extended "On" message as the library can't seem to reproduce this message automatica...
Definition: ir_Samsung.cpp:379
+
const uint8_t kSamsungAcFanAuto
Definition: ir_Samsung.h:81
+
const uint8_t kSamsungAcClean11Offset
Definition: ir_Samsung.h:68
+
void checksum(const uint16_t length=kSamsungAcStateLength)
Update the checksum for the internal state.
Definition: ir_Samsung.cpp:323
+
void setBeep(const bool on)
Set the Beep setting of the A/C.
Definition: ir_Samsung.cpp:536
+
bool getClean(void)
Get the Clean setting of the A/C.
Definition: ir_Samsung.cpp:542
+
const uint8_t kSamsungAcFanOffest
Definition: ir_Samsung.h:79
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Samsung.cpp:649
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Samsung.h:111
+
void sendExtended(const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)
Send the extended current internal state as an IR message.
Definition: ir_Samsung.cpp:358
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Samsung.cpp:486
+
const uint8_t kSamsungAcMaxTemp
Definition: ir_Samsung.h:70
+
const uint8_t kSamsungAcIonOffset
Definition: ir_Samsung.h:67
+
const uint8_t kSamsungAcPower6Offset
Definition: ir_Samsung.h:46
+
const uint8_t kSamsungAcPowerful10Size
Definition: ir_Samsung.h:58
+
const uint8_t kSamsungAcClean10Offset
Definition: ir_Samsung.h:65
+
bool getSwing(void)
Get the vertical swing setting of the A/C.
Definition: ir_Samsung.cpp:514
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Samsung.cpp:426
+
const uint8_t kSamsungAcPower6Size
Definition: ir_Samsung.h:47
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Samsung.cpp:689
+
const uint8_t kSamsungAcBeepOffset
Definition: ir_Samsung.h:88
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Samsung.cpp:404
+
const uint8_t kSamsungAcQuiet5Offset
Definition: ir_Samsung.h:44
+
const uint8_t kSamsungAcFanTurbo
Definition: ir_Samsung.h:86
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kSamsungAcMinTemp
Definition: ir_Samsung.h:69
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sanyo_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sanyo_8cpp.html new file mode 100644 index 000000000..51a096705 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sanyo_8cpp.html @@ -0,0 +1,352 @@ + + + + + + + +IRremoteESP8266: src/ir_Sanyo.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Sanyo.cpp File Reference
+
+
+ +

Support for Sanyo protocols. Sanyo LC7461 support originally by marcosamarinho Sanyo SA 8650B originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSanyoSa8650bHdrMark = 3500
 
const uint16_t kSanyoSa8650bHdrSpace = 950
 
const uint16_t kSanyoSa8650bOneMark = 2400
 
const uint16_t kSanyoSa8650bZeroMark = 700
 
const uint16_t kSanyoSa8650bDoubleSpaceUsecs = 800
 
const uint16_t kSanyoSa8650bRptLength = 45000
 
const uint16_t kSanyoLc7461AddressMask = (1 << kSanyoLC7461AddressBits) - 1
 
const uint16_t kSanyoLc7461CommandMask = (1 << kSanyoLC7461CommandBits) - 1
 
const uint16_t kSanyoLc7461HdrMark = 9000
 
const uint16_t kSanyoLc7461HdrSpace = 4500
 
const uint16_t kSanyoLc7461BitMark = 560
 
const uint16_t kSanyoLc7461OneSpace = 1690
 
const uint16_t kSanyoLc7461ZeroSpace = 560
 
const uint32_t kSanyoLc7461MinCommandLength = 108000
 
const uint16_t kSanyoLc7461MinGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSanyoLc7461AddressMask

+ +
+
+ + + + +
const uint16_t kSanyoLc7461AddressMask = (1 << kSanyoLC7461AddressBits) - 1
+
+ +
+
+ +

◆ kSanyoLc7461BitMark

+ +
+
+ + + + +
const uint16_t kSanyoLc7461BitMark = 560
+
+ +
+
+ +

◆ kSanyoLc7461CommandMask

+ +
+
+ + + + +
const uint16_t kSanyoLc7461CommandMask = (1 << kSanyoLC7461CommandBits) - 1
+
+ +
+
+ +

◆ kSanyoLc7461HdrMark

+ +
+
+ + + + +
const uint16_t kSanyoLc7461HdrMark = 9000
+
+ +
+
+ +

◆ kSanyoLc7461HdrSpace

+ +
+
+ + + + +
const uint16_t kSanyoLc7461HdrSpace = 4500
+
+ +
+
+ +

◆ kSanyoLc7461MinCommandLength

+ +
+
+ + + + +
const uint32_t kSanyoLc7461MinCommandLength = 108000
+
+ +
+
+ +

◆ kSanyoLc7461MinGap

+ +
+
+ + + + +
const uint16_t kSanyoLc7461MinGap
+
+
+ +

◆ kSanyoLc7461OneSpace

+ +
+
+ + + + +
const uint16_t kSanyoLc7461OneSpace = 1690
+
+ +
+
+ +

◆ kSanyoLc7461ZeroSpace

+ +
+
+ + + + +
const uint16_t kSanyoLc7461ZeroSpace = 560
+
+ +
+
+ +

◆ kSanyoSa8650bDoubleSpaceUsecs

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bDoubleSpaceUsecs = 800
+
+ +
+
+ +

◆ kSanyoSa8650bHdrMark

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bHdrMark = 3500
+
+ +
+
+ +

◆ kSanyoSa8650bHdrSpace

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bHdrSpace = 950
+
+ +
+
+ +

◆ kSanyoSa8650bOneMark

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bOneMark = 2400
+
+ +
+
+ +

◆ kSanyoSa8650bRptLength

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bRptLength = 45000
+
+ +
+
+ +

◆ kSanyoSa8650bZeroMark

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bZeroMark = 700
+
+ +
+
+
+
const uint16_t kSanyoLc7461HdrMark
Definition: ir_Sanyo.cpp:37
+
const uint32_t kSanyoLc7461MinCommandLength
Definition: ir_Sanyo.cpp:42
+
const uint16_t kSanyoLC7461Bits
Definition: IRremoteESP8266.h:977
+
const uint16_t kSanyoLc7461HdrSpace
Definition: ir_Sanyo.cpp:38
+
const uint16_t kSanyoLc7461BitMark
Definition: ir_Sanyo.cpp:39
+
const uint16_t kSanyoLc7461ZeroSpace
Definition: ir_Sanyo.cpp:41
+
const uint16_t kSanyoLc7461OneSpace
Definition: ir_Sanyo.cpp:40
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8cpp.html new file mode 100644 index 000000000..27e3c360b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8cpp.html @@ -0,0 +1,301 @@ + + + + + + + +IRremoteESP8266: src/ir_Sharp.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Sharp.cpp File Reference
+
+
+ +

Support for Sharp protocols. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSharpTick = 26
 
const uint16_t kSharpBitMarkTicks = 10
 
const uint16_t kSharpBitMark = kSharpBitMarkTicks * kSharpTick
 
const uint16_t kSharpOneSpaceTicks = 70
 
const uint16_t kSharpOneSpace = kSharpOneSpaceTicks * kSharpTick
 
const uint16_t kSharpZeroSpaceTicks = 30
 
const uint16_t kSharpZeroSpace = kSharpZeroSpaceTicks * kSharpTick
 
const uint16_t kSharpGapTicks = 1677
 
const uint16_t kSharpGap = kSharpGapTicks * kSharpTick
 
const uint64_t kSharpToggleMask
 
const uint64_t kSharpAddressMask = ((uint64_t)1 << kSharpAddressBits) - 1
 
const uint64_t kSharpCommandMask = ((uint64_t)1 << kSharpCommandBits) - 1
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSharpAddressMask

+ +
+
+ + + + +
const uint64_t kSharpAddressMask = ((uint64_t)1 << kSharpAddressBits) - 1
+
+ +
+
+ +

◆ kSharpBitMark

+ +
+
+ + + + +
const uint16_t kSharpBitMark = kSharpBitMarkTicks * kSharpTick
+
+ +
+
+ +

◆ kSharpBitMarkTicks

+ +
+
+ + + + +
const uint16_t kSharpBitMarkTicks = 10
+
+ +
+
+ +

◆ kSharpCommandMask

+ +
+
+ + + + +
const uint64_t kSharpCommandMask = ((uint64_t)1 << kSharpCommandBits) - 1
+
+ +
+
+ +

◆ kSharpGap

+ +
+
+ + + + +
const uint16_t kSharpGap = kSharpGapTicks * kSharpTick
+
+ +
+
+ +

◆ kSharpGapTicks

+ +
+
+ + + + +
const uint16_t kSharpGapTicks = 1677
+
+ +
+
+ +

◆ kSharpOneSpace

+ +
+
+ + + + +
const uint16_t kSharpOneSpace = kSharpOneSpaceTicks * kSharpTick
+
+ +
+
+ +

◆ kSharpOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kSharpOneSpaceTicks = 70
+
+ +
+
+ +

◆ kSharpTick

+ +
+
+ + + + +
const uint16_t kSharpTick = 26
+
+ +
+
+ +

◆ kSharpToggleMask

+ +
+
+ + + + +
const uint64_t kSharpToggleMask
+
+Initial value:
=
+
((uint64_t)1 << (kSharpBits - kSharpAddressBits)) - 1
+
+
+
+ +

◆ kSharpZeroSpace

+ +
+
+ + + + +
const uint16_t kSharpZeroSpace = kSharpZeroSpaceTicks * kSharpTick
+
+ +
+
+ +

◆ kSharpZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kSharpZeroSpaceTicks = 30
+
+ +
+
+
+
const uint16_t kSharpBits
Definition: IRremoteESP8266.h:981
+
const uint8_t kSharpAddressBits
Definition: IRremoteESP8266.h:979
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h.html new file mode 100644 index 000000000..a5f909c81 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h.html @@ -0,0 +1,1074 @@ + + + + + + + +IRremoteESP8266: src/ir_Sharp.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Sharp.h File Reference
+
+
+ +

Support for Sharp protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRSharpAc
 Class for handling detailed Sharp A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSharpAcHdrMark = 3800
 
const uint16_t kSharpAcHdrSpace = 1900
 
const uint16_t kSharpAcBitMark = 470
 
const uint16_t kSharpAcZeroSpace = 500
 
const uint16_t kSharpAcOneSpace = 1400
 
const uint32_t kSharpAcGap = kDefaultMessageGap
 
const uint8_t kSharpAcByteTemp = 4
 
const uint8_t kSharpAcMinTemp = 15
 
const uint8_t kSharpAcMaxTemp = 30
 
const uint8_t kSharpAcBytePowerSpecial = 5
 
const uint8_t kSharpAcPowerSetSpecialOffset = kHighNibble
 
const uint8_t kSharpAcPowerSpecialSize = kNibbleSize
 
const uint8_t kSharpAcPowerUnknown = 0
 
const uint8_t kSharpAcPowerOnFromOff = 1
 
const uint8_t kSharpAcPowerOff = 2
 
const uint8_t kSharpAcPowerOn = 3
 
const uint8_t kSharpAcPowerSetSpecialOn = 6
 
const uint8_t kSharpAcPowerSetSpecialOff = 7
 
const uint8_t kSharpAcPowerTimerSetting = 8
 
const uint8_t kSharpAcByteMode = 6
 
const uint8_t kSharpAcModeSize = 2
 
const uint8_t kSharpAcAuto = 0b00
 
const uint8_t kSharpAcDry = 0b11
 
const uint8_t kSharpAcCool = 0b10
 
const uint8_t kSharpAcHeat = 0b01
 
const uint8_t kSharpAcByteClean = kSharpAcByteMode
 
const uint8_t kSharpAcBitCleanOffset = 3
 
const uint8_t kSharpAcByteFan = kSharpAcByteMode
 
const uint8_t kSharpAcFanOffset = 4
 
const uint8_t kSharpAcFanSize = 3
 
const uint8_t kSharpAcFanAuto = 0b010
 
const uint8_t kSharpAcFanMin = 0b100
 
const uint8_t kSharpAcFanMed = 0b011
 
const uint8_t kSharpAcFanHigh = 0b101
 
const uint8_t kSharpAcFanMax = 0b111
 
const uint8_t kSharpAcByteTimer = 7
 
const uint8_t kSharpAcTimerIncrement = 30
 
const uint8_t kSharpAcTimerHoursOffset = kLowNibble
 
const uint8_t kSharpAcTimerHoursSize = kNibbleSize
 
const uint8_t kSharpAcTimerHoursOff = 0b0000
 
const uint8_t kSharpAcTimerHoursMax = 0b1100
 
const uint8_t kSharpAcBitTimerType = 6
 
const uint8_t kSharpAcOffTimerType = 0b0
 
const uint8_t kSharpAcOnTimerType = 0b1
 
const uint8_t kSharpAcBitTimerEnabled = 7
 
const uint8_t kSharpAcByteSwing = 8
 
const uint8_t kSharpAcSwingOffset = 0
 
const uint8_t kSharpAcSwingSize = 3
 
const uint8_t kSharpAcSwingToggle = 0b111
 
const uint8_t kSharpAcSwingNoToggle = 0b000
 
const uint8_t kSharpAcByteSpecial = 10
 
const uint8_t kSharpAcSpecialPower = 0x00
 
const uint8_t kSharpAcSpecialTurbo = 0x01
 
const uint8_t kSharpAcSpecialTempEcono = 0x04
 
const uint8_t kSharpAcSpecialFan = 0x05
 
const uint8_t kSharpAcSpecialSwing = 0x06
 
const uint8_t kSharpAcSpecialTimer = 0xC0
 
const uint8_t kSharpAcSpecialTimerHalfHour = 0xDE
 
const uint8_t kSharpAcByteIon = 11
 
const uint8_t kSharpAcBitIonOffset = 2
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSharpAcAuto

+ +
+
+ + + + +
const uint8_t kSharpAcAuto = 0b00
+
+ +
+
+ +

◆ kSharpAcBitCleanOffset

+ +
+
+ + + + +
const uint8_t kSharpAcBitCleanOffset = 3
+
+ +
+
+ +

◆ kSharpAcBitIonOffset

+ +
+
+ + + + +
const uint8_t kSharpAcBitIonOffset = 2
+
+ +
+
+ +

◆ kSharpAcBitMark

+ +
+
+ + + + +
const uint16_t kSharpAcBitMark = 470
+
+ +
+
+ +

◆ kSharpAcBitTimerEnabled

+ +
+
+ + + + +
const uint8_t kSharpAcBitTimerEnabled = 7
+
+ +
+
+ +

◆ kSharpAcBitTimerType

+ +
+
+ + + + +
const uint8_t kSharpAcBitTimerType = 6
+
+ +
+
+ +

◆ kSharpAcByteClean

+ +
+
+ + + + +
const uint8_t kSharpAcByteClean = kSharpAcByteMode
+
+ +
+
+ +

◆ kSharpAcByteFan

+ +
+
+ + + + +
const uint8_t kSharpAcByteFan = kSharpAcByteMode
+
+ +
+
+ +

◆ kSharpAcByteIon

+ +
+
+ + + + +
const uint8_t kSharpAcByteIon = 11
+
+ +
+
+ +

◆ kSharpAcByteMode

+ +
+
+ + + + +
const uint8_t kSharpAcByteMode = 6
+
+ +
+
+ +

◆ kSharpAcBytePowerSpecial

+ +
+
+ + + + +
const uint8_t kSharpAcBytePowerSpecial = 5
+
+ +
+
+ +

◆ kSharpAcByteSpecial

+ +
+
+ + + + +
const uint8_t kSharpAcByteSpecial = 10
+
+ +
+
+ +

◆ kSharpAcByteSwing

+ +
+
+ + + + +
const uint8_t kSharpAcByteSwing = 8
+
+ +
+
+ +

◆ kSharpAcByteTemp

+ +
+
+ + + + +
const uint8_t kSharpAcByteTemp = 4
+
+ +
+
+ +

◆ kSharpAcByteTimer

+ +
+
+ + + + +
const uint8_t kSharpAcByteTimer = 7
+
+ +
+
+ +

◆ kSharpAcCool

+ +
+
+ + + + +
const uint8_t kSharpAcCool = 0b10
+
+ +
+
+ +

◆ kSharpAcDry

+ +
+
+ + + + +
const uint8_t kSharpAcDry = 0b11
+
+ +
+
+ +

◆ kSharpAcFanAuto

+ +
+
+ + + + +
const uint8_t kSharpAcFanAuto = 0b010
+
+ +
+
+ +

◆ kSharpAcFanHigh

+ +
+
+ + + + +
const uint8_t kSharpAcFanHigh = 0b101
+
+ +
+
+ +

◆ kSharpAcFanMax

+ +
+
+ + + + +
const uint8_t kSharpAcFanMax = 0b111
+
+ +
+
+ +

◆ kSharpAcFanMed

+ +
+
+ + + + +
const uint8_t kSharpAcFanMed = 0b011
+
+ +
+
+ +

◆ kSharpAcFanMin

+ +
+
+ + + + +
const uint8_t kSharpAcFanMin = 0b100
+
+ +
+
+ +

◆ kSharpAcFanOffset

+ +
+
+ + + + +
const uint8_t kSharpAcFanOffset = 4
+
+ +
+
+ +

◆ kSharpAcFanSize

+ +
+
+ + + + +
const uint8_t kSharpAcFanSize = 3
+
+ +
+
+ +

◆ kSharpAcGap

+ +
+
+ + + + +
const uint32_t kSharpAcGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kSharpAcHdrMark

+ +
+
+ + + + +
const uint16_t kSharpAcHdrMark = 3800
+
+ +
+
+ +

◆ kSharpAcHdrSpace

+ +
+
+ + + + +
const uint16_t kSharpAcHdrSpace = 1900
+
+ +
+
+ +

◆ kSharpAcHeat

+ +
+
+ + + + +
const uint8_t kSharpAcHeat = 0b01
+
+ +
+
+ +

◆ kSharpAcMaxTemp

+ +
+
+ + + + +
const uint8_t kSharpAcMaxTemp = 30
+
+ +
+
+ +

◆ kSharpAcMinTemp

+ +
+
+ + + + +
const uint8_t kSharpAcMinTemp = 15
+
+ +
+
+ +

◆ kSharpAcModeSize

+ +
+
+ + + + +
const uint8_t kSharpAcModeSize = 2
+
+ +
+
+ +

◆ kSharpAcOffTimerType

+ +
+
+ + + + +
const uint8_t kSharpAcOffTimerType = 0b0
+
+ +
+
+ +

◆ kSharpAcOneSpace

+ +
+
+ + + + +
const uint16_t kSharpAcOneSpace = 1400
+
+ +
+
+ +

◆ kSharpAcOnTimerType

+ +
+
+ + + + +
const uint8_t kSharpAcOnTimerType = 0b1
+
+ +
+
+ +

◆ kSharpAcPowerOff

+ +
+
+ + + + +
const uint8_t kSharpAcPowerOff = 2
+
+ +
+
+ +

◆ kSharpAcPowerOn

+ +
+
+ + + + +
const uint8_t kSharpAcPowerOn = 3
+
+ +
+
+ +

◆ kSharpAcPowerOnFromOff

+ +
+
+ + + + +
const uint8_t kSharpAcPowerOnFromOff = 1
+
+ +
+
+ +

◆ kSharpAcPowerSetSpecialOff

+ +
+
+ + + + +
const uint8_t kSharpAcPowerSetSpecialOff = 7
+
+ +
+
+ +

◆ kSharpAcPowerSetSpecialOffset

+ +
+
+ + + + +
const uint8_t kSharpAcPowerSetSpecialOffset = kHighNibble
+
+ +
+
+ +

◆ kSharpAcPowerSetSpecialOn

+ +
+
+ + + + +
const uint8_t kSharpAcPowerSetSpecialOn = 6
+
+ +
+
+ +

◆ kSharpAcPowerSpecialSize

+ +
+
+ + + + +
const uint8_t kSharpAcPowerSpecialSize = kNibbleSize
+
+ +
+
+ +

◆ kSharpAcPowerTimerSetting

+ +
+
+ + + + +
const uint8_t kSharpAcPowerTimerSetting = 8
+
+ +
+
+ +

◆ kSharpAcPowerUnknown

+ +
+
+ + + + +
const uint8_t kSharpAcPowerUnknown = 0
+
+ +
+
+ +

◆ kSharpAcSpecialFan

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialFan = 0x05
+
+ +
+
+ +

◆ kSharpAcSpecialPower

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialPower = 0x00
+
+ +
+
+ +

◆ kSharpAcSpecialSwing

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialSwing = 0x06
+
+ +
+
+ +

◆ kSharpAcSpecialTempEcono

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialTempEcono = 0x04
+
+ +
+
+ +

◆ kSharpAcSpecialTimer

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialTimer = 0xC0
+
+ +
+
+ +

◆ kSharpAcSpecialTimerHalfHour

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialTimerHalfHour = 0xDE
+
+ +
+
+ +

◆ kSharpAcSpecialTurbo

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialTurbo = 0x01
+
+ +
+
+ +

◆ kSharpAcSwingNoToggle

+ +
+
+ + + + +
const uint8_t kSharpAcSwingNoToggle = 0b000
+
+ +
+
+ +

◆ kSharpAcSwingOffset

+ +
+
+ + + + +
const uint8_t kSharpAcSwingOffset = 0
+
+ +
+
+ +

◆ kSharpAcSwingSize

+ +
+
+ + + + +
const uint8_t kSharpAcSwingSize = 3
+
+ +
+
+ +

◆ kSharpAcSwingToggle

+ +
+
+ + + + +
const uint8_t kSharpAcSwingToggle = 0b111
+
+ +
+
+ +

◆ kSharpAcTimerHoursMax

+ +
+
+ + + + +
const uint8_t kSharpAcTimerHoursMax = 0b1100
+
+ +
+
+ +

◆ kSharpAcTimerHoursOff

+ +
+
+ + + + +
const uint8_t kSharpAcTimerHoursOff = 0b0000
+
+ +
+
+ +

◆ kSharpAcTimerHoursOffset

+ +
+
+ + + + +
const uint8_t kSharpAcTimerHoursOffset = kLowNibble
+
+ +
+
+ +

◆ kSharpAcTimerHoursSize

+ +
+
+ + + + +
const uint8_t kSharpAcTimerHoursSize = kNibbleSize
+
+ +
+
+ +

◆ kSharpAcTimerIncrement

+ +
+
+ + + + +
const uint8_t kSharpAcTimerIncrement = 30
+
+ +
+
+ +

◆ kSharpAcZeroSpace

+ +
+
+ + + + +
const uint16_t kSharpAcZeroSpace = 500
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h_source.html new file mode 100644 index 000000000..9091598a9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h_source.html @@ -0,0 +1,373 @@ + + + + + + + +IRremoteESP8266: src/ir_Sharp.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Sharp.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 crankyoldgit
+
2 
+
12 
+
13 // Supports:
+
14 // Brand: Sharp, Model: LC-52D62U TV
+
15 // Brand: Sharp, Model: AY-ZP40KR A/C
+
16 // Brand: Sharp, Model: AH-AxSAY A/C
+
17 // Brand: Sharp, Model: CRMC-A907 JBEZ remote
+
18 // Brand: Sharp, Model: AH-XP10NRY A/C
+
19 // Brand: Sharp, Model: CRMC-820JBEZ remote
+
20 
+
21 #ifndef IR_SHARP_H_
+
22 #define IR_SHARP_H_
+
23 
+
24 #ifndef UNIT_TEST
+
25 #include <Arduino.h>
+
26 #endif
+
27 #include "IRrecv.h"
+
28 #include "IRremoteESP8266.h"
+
29 #include "IRsend.h"
+
30 #ifdef UNIT_TEST
+
31 #include "IRsend_test.h"
+
32 #endif
+
33 #include "IRutils.h"
+
34 
+
35 // Constants
+
36 const uint16_t kSharpAcHdrMark = 3800;
+
37 const uint16_t kSharpAcHdrSpace = 1900;
+
38 const uint16_t kSharpAcBitMark = 470;
+
39 const uint16_t kSharpAcZeroSpace = 500;
+
40 const uint16_t kSharpAcOneSpace = 1400;
+ +
42 
+
43 // Byte[4]
+
44 const uint8_t kSharpAcByteTemp = 4;
+
45 const uint8_t kSharpAcMinTemp = 15; // Celsius
+
46 const uint8_t kSharpAcMaxTemp = 30; // Celsius
+
47 // Byte[5]
+
48 const uint8_t kSharpAcBytePowerSpecial = 5;
+
49 const uint8_t kSharpAcPowerSetSpecialOffset = kHighNibble; // 0bxxxx0000
+
50 const uint8_t kSharpAcPowerSpecialSize = kNibbleSize; // 0bxxxx0000
+
51 const uint8_t kSharpAcPowerUnknown = 0; // 0b0000
+
52 const uint8_t kSharpAcPowerOnFromOff = 1; // 0b0001
+
53 const uint8_t kSharpAcPowerOff = 2; // 0b0010
+
54 const uint8_t kSharpAcPowerOn = 3; // 0b0011 (Normal)
+
55 const uint8_t kSharpAcPowerSetSpecialOn = 6; // 0b0110
+
56 const uint8_t kSharpAcPowerSetSpecialOff = 7; // 0b0111
+
57 const uint8_t kSharpAcPowerTimerSetting = 8; // 0b1000
+
58 // Byte[6]
+
59 const uint8_t kSharpAcByteMode = 6;
+
60 const uint8_t kSharpAcModeSize = 2; // Mask 0b000000xx;
+
61 const uint8_t kSharpAcAuto = 0b00;
+
62 const uint8_t kSharpAcDry = 0b11;
+
63 const uint8_t kSharpAcCool = 0b10;
+
64 const uint8_t kSharpAcHeat = 0b01;
+ +
66 const uint8_t kSharpAcBitCleanOffset = 3; // Mask 0b0000x000
+ +
68 const uint8_t kSharpAcFanOffset = 4; // Mask 0b0xxx0000
+
69 const uint8_t kSharpAcFanSize = 3; // Nr. of Bits
+
70 const uint8_t kSharpAcFanAuto = 0b010; // 2
+
71 const uint8_t kSharpAcFanMin = 0b100; // 4 (FAN1)
+
72 const uint8_t kSharpAcFanMed = 0b011; // 3 (FAN2)
+
73 const uint8_t kSharpAcFanHigh = 0b101; // 5 (FAN3)
+
74 const uint8_t kSharpAcFanMax = 0b111; // 7 (FAN4)
+
75 // Byte[7]
+
76 const uint8_t kSharpAcByteTimer = 7;
+
77 const uint8_t kSharpAcTimerIncrement = 30; // Mins
+ +
79 const uint8_t kSharpAcTimerHoursSize = kNibbleSize; // Mask 0b0000xxxx
+
80 const uint8_t kSharpAcTimerHoursOff = 0b0000;
+
81 const uint8_t kSharpAcTimerHoursMax = 0b1100; // 12
+
82 const uint8_t kSharpAcBitTimerType = 6; // Mask 0b0x000000
+
83 const uint8_t kSharpAcOffTimerType = 0b0;
+
84 const uint8_t kSharpAcOnTimerType = 0b1;
+
85 const uint8_t kSharpAcBitTimerEnabled = 7; // Mask 0bx0000000
+
86 // Byte[8]
+
87 const uint8_t kSharpAcByteSwing = 8;
+
88 const uint8_t kSharpAcSwingOffset = 0;
+
89 const uint8_t kSharpAcSwingSize = 3; // Mask 0b00000xxx
+
90 const uint8_t kSharpAcSwingToggle = 0b111;
+
91 const uint8_t kSharpAcSwingNoToggle = 0b000;
+
92 // Byte[10]
+
93 const uint8_t kSharpAcByteSpecial = 10; // Mask 0bxxxxxxxx
+
94 const uint8_t kSharpAcSpecialPower = 0x00;
+
95 const uint8_t kSharpAcSpecialTurbo = 0x01;
+
96 const uint8_t kSharpAcSpecialTempEcono = 0x04;
+
97 const uint8_t kSharpAcSpecialFan = 0x05;
+
98 const uint8_t kSharpAcSpecialSwing = 0x06;
+
99 const uint8_t kSharpAcSpecialTimer = 0xC0;
+
100 const uint8_t kSharpAcSpecialTimerHalfHour = 0xDE;
+
101 // Byte[11]
+
102 const uint8_t kSharpAcByteIon = 11;
+
103 const uint8_t kSharpAcBitIonOffset = 2; // Mask 0b00000x00
+
104 // Byte[12] (Checksum)
+
105 
+
106 // Classes
+
108 class IRSharpAc {
+
109  public:
+
110  explicit IRSharpAc(const uint16_t pin, const bool inverted = false,
+
111  const bool use_modulation = true);
+
112 #if SEND_SHARP_AC
+
113  void send(const uint16_t repeat = kSharpAcDefaultRepeat);
+
118  int8_t calibrate(void) { return _irsend.calibrate(); }
+
119 #endif // SEND_SHARP_AC
+
120  void begin(void);
+
121  void on(void);
+
122  void off(void);
+
123  void setPower(const bool on, const bool prev_on = true);
+
124  bool getPower(void);
+
125  bool isPowerSpecial(void);
+
126  void setTemp(const uint8_t temp, const bool save = true);
+
127  uint8_t getTemp(void);
+
128  void setFan(const uint8_t fan, const bool save = true);
+
129  uint8_t getFan(void);
+
130  void setMode(const uint8_t mode, const bool save = true);
+
131  uint8_t getMode(void);
+
132  void setSpecial(const uint8_t mode);
+
133  uint8_t getSpecial(void);
+
134  bool getTurbo(void);
+
135  void setTurbo(const bool on);
+
136  bool getSwingToggle(void);
+
137  void setSwingToggle(const bool on);
+
138  bool getIon(void);
+
139  void setIon(const bool on);
+
140  bool getEconoToggle(void);
+
141  void setEconoToggle(const bool on);
+
142  uint16_t getTimerTime(void);
+
143  bool getTimerEnabled(void);
+
144  bool getTimerType(void);
+
145  void setTimer(bool enable, bool timer_type, uint16_t mins);
+
146  bool getClean(void);
+
147  void setClean(const bool on);
+
148  uint8_t* getRaw(void);
+
149  void setRaw(const uint8_t new_code[],
+
150  const uint16_t length = kSharpAcStateLength);
+
151  static bool validChecksum(uint8_t state[],
+
152  const uint16_t length = kSharpAcStateLength);
+
153  static uint8_t convertMode(const stdAc::opmode_t mode);
+
154  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
155  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
156  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
157  stdAc::state_t toCommon(void);
+
158  String toString(void);
+
159 #ifndef UNIT_TEST
+
160 
+
161  private:
+ +
163 #else // UNIT_TEST
+
164  IRsendTest _irsend;
+
166 #endif // UNIT_TEST
+ +
169  uint8_t _temp;
+
170  uint8_t _mode;
+
171  uint8_t _fan;
+
172  void stateReset(void);
+
173  void checksum(void);
+
174  static uint8_t calcChecksum(uint8_t state[],
+
175  const uint16_t length = kSharpAcStateLength);
+
176  void setPowerSpecial(const uint8_t value);
+
177  uint8_t getPowerSpecial(void);
+
178  void clearPowerSpecial(void);
+
179 };
+
180 
+
181 #endif // IR_SHARP_H_
+
+
uint8_t getPowerSpecial(void)
Get the value of the Power Special setting.
Definition: ir_Sharp.cpp:319
+
const uint8_t kSharpAcTimerHoursSize
Definition: ir_Sharp.h:79
+
const uint8_t kSharpAcByteFan
Definition: ir_Sharp.h:67
+
const uint8_t kSharpAcFanSize
Definition: ir_Sharp.h:69
+
const uint8_t kSharpAcHeat
Definition: ir_Sharp.h:64
+
const uint8_t kSharpAcSpecialTempEcono
Definition: ir_Sharp.h:96
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Sharp.cpp:421
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Sharp.h:118
+
void setTimer(bool enable, bool timer_type, uint16_t mins)
Set or cancel the timer function.
Definition: ir_Sharp.cpp:568
+
bool isPowerSpecial(void)
Is one of the special power states in use?
Definition: ir_Sharp.cpp:332
+
void setTemp(const uint8_t temp, const bool save=true)
Set the temperature.
Definition: ir_Sharp.cpp:393
+
const uint8_t kSharpAcPowerOnFromOff
Definition: ir_Sharp.h:52
+
const uint8_t kSharpAcPowerSpecialSize
Definition: ir_Sharp.h:50
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Sharp.cpp:345
+
const uint16_t kSharpAcOneSpace
Definition: ir_Sharp.h:40
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
uint8_t _temp
Saved copy of the desired temp.
Definition: ir_Sharp.h:169
+
const uint32_t kDefaultMessageGap
Definition: IRsend.h:41
+
static uint8_t calcChecksum(uint8_t state[], const uint16_t length=kSharpAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Sharp.cpp:263
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Sharp.cpp:663
+
bool getIon(void)
Get the Ion (Filter) setting of the A/C.
Definition: ir_Sharp.cpp:515
+
const uint8_t kSharpAcSpecialTimer
Definition: ir_Sharp.h:99
+
const uint8_t kSharpAcOnTimerType
Definition: ir_Sharp.h:84
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Sharp.cpp:476
+
const uint8_t kSharpAcCool
Definition: ir_Sharp.h:63
+ +
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Sharp.cpp:360
+
const uint8_t kSharpAcSpecialFan
Definition: ir_Sharp.h:97
+
const uint8_t kSharpAcSpecialSwing
Definition: ir_Sharp.h:98
+
const uint8_t kSharpAcOffTimerType
Definition: ir_Sharp.h:83
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kSharpAcMaxTemp
Definition: ir_Sharp.h:46
+
void setFan(const uint8_t fan, const bool save=true)
Set the speed of the fan.
Definition: ir_Sharp.cpp:455
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
IRSharpAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Sharp.cpp:244
+
const uint8_t kSharpAcSwingOffset
Definition: ir_Sharp.h:88
+
const uint16_t kSharpAcZeroSpace
Definition: ir_Sharp.h:39
+
void setPower(const bool on, const bool prev_on=true)
Change the power setting, including the previous power state.
Definition: ir_Sharp.cpp:350
+
const uint8_t kSharpAcDry
Definition: ir_Sharp.h:62
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kNibbleSize
Definition: IRutils.h:17
+
const uint8_t kSharpAcTimerHoursMax
Definition: ir_Sharp.h:81
+
const uint8_t kSharpAcPowerOff
Definition: ir_Sharp.h:53
+
uint16_t getTimerTime(void)
Get how long the timer is set for, in minutes.
Definition: ir_Sharp.cpp:544
+
const uint8_t kLowNibble
Definition: IRutils.h:18
+
const uint8_t kSharpAcSwingNoToggle
Definition: ir_Sharp.h:91
+
const uint8_t kSharpAcTimerIncrement
Definition: ir_Sharp.h:77
+ +
const uint8_t kSharpAcPowerSetSpecialOn
Definition: ir_Sharp.h:55
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Sharp.cpp:612
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Sharp.cpp:492
+
static bool validChecksum(uint8_t state[], const uint16_t length=kSharpAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Sharp.cpp:274
+
uint8_t getSpecial(void)
Get the value of the Special (button/command?) setting.
Definition: ir_Sharp.cpp:388
+
const uint8_t kSharpAcSpecialTimerHalfHour
Definition: ir_Sharp.h:100
+
const uint8_t kSharpAcTimerHoursOff
Definition: ir_Sharp.h:80
+
const uint8_t kSharpAcBitTimerEnabled
Definition: ir_Sharp.h:85
+
const uint8_t kSharpAcByteTimer
Definition: ir_Sharp.h:76
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Sharp.cpp:414
+
const uint8_t kHighNibble
Definition: IRutils.h:19
+
const uint8_t kSharpAcByteSpecial
Definition: ir_Sharp.h:93
+
const uint8_t kSharpAcSwingToggle
Definition: ir_Sharp.h:90
+
void setPowerSpecial(const uint8_t value)
Set the value of the Power Special setting without any checks.
Definition: ir_Sharp.cpp:312
+
const uint8_t kSharpAcFanAuto
Definition: ir_Sharp.h:70
+
void send(const uint16_t repeat=kSharpAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Sharp.cpp:254
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Sharp.h:162
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Sharp.cpp:280
+
const uint32_t kSharpAcGap
Definition: ir_Sharp.h:41
+
const uint8_t kSharpAcBitTimerType
Definition: ir_Sharp.h:82
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Sharp.cpp:298
+
const uint8_t kSharpAcSwingSize
Definition: ir_Sharp.h:89
+
const uint8_t kSharpAcByteMode
Definition: ir_Sharp.h:59
+
bool getTimerType(void)
Get the current timer type.
Definition: ir_Sharp.cpp:559
+
const uint8_t kSharpAcPowerUnknown
Definition: ir_Sharp.h:51
+ +
const uint8_t kSharpAcPowerOn
Definition: ir_Sharp.h:54
+
void setSpecial(const uint8_t mode)
Set the value of the Special (button/command?) setting.
Definition: ir_Sharp.cpp:370
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Sharp.cpp:249
+
const uint8_t kSharpAcByteClean
Definition: ir_Sharp.h:65
+
const uint16_t kSharpAcStateLength
Definition: IRremoteESP8266.h:982
+
const uint8_t kSharpAcModeSize
Definition: ir_Sharp.h:60
+
const uint8_t kSharpAcFanMax
Definition: ir_Sharp.h:74
+ +
uint8_t _mode
Saved copy of the desired mode.
Definition: ir_Sharp.h:170
+
const uint8_t kSharpAcBytePowerSpecial
Definition: ir_Sharp.h:48
+
Class for handling detailed Sharp A/C messages.
Definition: ir_Sharp.h:108
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Sharp.cpp:639
+
bool getEconoToggle(void)
Get the Economical mode toggle setting of the A/C.
Definition: ir_Sharp.cpp:529
+
const uint8_t kSharpAcPowerTimerSetting
Definition: ir_Sharp.h:57
+
const uint8_t kSharpAcBitIonOffset
Definition: ir_Sharp.h:103
+
const uint8_t kSharpAcFanHigh
Definition: ir_Sharp.h:73
+
bool getSwingToggle(void)
Get the (vertical) Swing Toggle setting of the A/C.
Definition: ir_Sharp.cpp:500
+
const uint8_t kSharpAcFanMin
Definition: ir_Sharp.h:71
+
const uint8_t kSharpAcByteSwing
Definition: ir_Sharp.h:87
+
void setClean(const bool on)
Set the Economical mode toggle setting of the A/C.
Definition: ir_Sharp.cpp:595
+
uint8_t remote[kSharpAcStateLength]
State of the remote in IR code form.
Definition: ir_Sharp.h:168
+
const uint8_t kSharpAcFanMed
Definition: ir_Sharp.h:72
+
const uint16_t kSharpAcDefaultRepeat
Definition: IRremoteESP8266.h:984
+
const uint8_t kSharpAcTimerHoursOffset
Definition: ir_Sharp.h:78
+
uint8_t _fan
Saved copy of the desired fan speed.
Definition: ir_Sharp.h:171
+
const uint8_t kSharpAcByteIon
Definition: ir_Sharp.h:102
+
void setEconoToggle(const bool on)
Set the Economical mode toggle setting of the A/C.
Definition: ir_Sharp.cpp:537
+
const uint8_t kSharpAcFanOffset
Definition: ir_Sharp.h:68
+
bool getClean(void)
Get the Clean setting of the A/C.
Definition: ir_Sharp.cpp:588
+
const uint16_t kSharpAcHdrSpace
Definition: ir_Sharp.h:37
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Sharp.cpp:482
+
const uint8_t kSharpAcAuto
Definition: ir_Sharp.h:61
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Sharp.cpp:651
+
void setSwingToggle(const bool on)
Set the (vertical) Swing Toggle setting of the A/C.
Definition: ir_Sharp.cpp:507
+
bool getTimerEnabled(void)
Is the Timer enabled?
Definition: ir_Sharp.cpp:553
+
const uint8_t kSharpAcPowerSetSpecialOffset
Definition: ir_Sharp.h:49
+
const uint8_t kSharpAcPowerSetSpecialOff
Definition: ir_Sharp.h:56
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Sharp.cpp:342
+
void setMode(const uint8_t mode, const bool save=true)
Set the operating mode of the A/C.
Definition: ir_Sharp.cpp:428
+
const uint16_t kSharpAcBitMark
Definition: ir_Sharp.h:38
+
const uint8_t kSharpAcMinTemp
Definition: ir_Sharp.h:45
+
const uint8_t kSharpAcSpecialTurbo
Definition: ir_Sharp.h:95
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Sharp.cpp:690
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Sharp.cpp:286
+
const uint8_t kSharpAcByteTemp
Definition: ir_Sharp.h:44
+
void setIon(const bool on)
Set the Ion (Filter) setting of the A/C.
Definition: ir_Sharp.cpp:521
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void clearPowerSpecial(void)
Clear the "special"/non-normal bits in the power section. e.g. for normal/common command modes.
Definition: ir_Sharp.cpp:326
+
const uint16_t kSharpAcHdrMark
Definition: ir_Sharp.h:36
+
void setRaw(const uint8_t new_code[], const uint16_t length=kSharpAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Sharp.cpp:306
+
const uint8_t kSharpAcSpecialPower
Definition: ir_Sharp.h:94
+
const uint8_t kSharpAcBitCleanOffset
Definition: ir_Sharp.h:66
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Sharp.cpp:625
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sherwood_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sherwood_8cpp.html new file mode 100644 index 000000000..a6b133aa1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sherwood_8cpp.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: src/ir_Sherwood.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Sherwood.cpp File Reference
+
+
+ +

Support for Sherwood protocols. +More...

+

Detailed Description

+

Support for Sherwood protocols.

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sony_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sony_8cpp.html new file mode 100644 index 000000000..fa1d5b055 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sony_8cpp.html @@ -0,0 +1,335 @@ + + + + + + + +IRremoteESP8266: src/ir_Sony.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Sony.cpp File Reference
+
+
+ +

Support for Sony SIRC(Serial Infra-Red Control) protocols. Sony originally added from https://github.com/shirriff/Arduino-IRremote/ Updates from marcosamarinho. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSonyTick = 200
 
const uint16_t kSonyHdrMarkTicks = 12
 
const uint16_t kSonyHdrMark = kSonyHdrMarkTicks * kSonyTick
 
const uint16_t kSonySpaceTicks = 3
 
const uint16_t kSonySpace = kSonySpaceTicks * kSonyTick
 
const uint16_t kSonyOneMarkTicks = 6
 
const uint16_t kSonyOneMark = kSonyOneMarkTicks * kSonyTick
 
const uint16_t kSonyZeroMarkTicks = 3
 
const uint16_t kSonyZeroMark = kSonyZeroMarkTicks * kSonyTick
 
const uint16_t kSonyRptLengthTicks = 225
 
const uint16_t kSonyRptLength = kSonyRptLengthTicks * kSonyTick
 
const uint16_t kSonyMinGapTicks = 50
 
const uint16_t kSonyMinGap = kSonyMinGapTicks * kSonyTick
 
const uint16_t kSonyStdFreq = 40000
 
const uint16_t kSonyAltFreq = 38000
 
+

Detailed Description

+

Support for Sony SIRC(Serial Infra-Red Control) protocols. Sony originally added from https://github.com/shirriff/Arduino-IRremote/ Updates from marcosamarinho.

+
See also
http://www.sbprojects.com/knowledge/ir/sirc.php
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/1018
+

Variable Documentation

+ +

◆ kSonyAltFreq

+ +
+
+ + + + +
const uint16_t kSonyAltFreq = 38000
+
+ +
+
+ +

◆ kSonyHdrMark

+ +
+
+ + + + +
const uint16_t kSonyHdrMark = kSonyHdrMarkTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kSonyHdrMarkTicks = 12
+
+ +
+
+ +

◆ kSonyMinGap

+ +
+
+ + + + +
const uint16_t kSonyMinGap = kSonyMinGapTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyMinGapTicks

+ +
+
+ + + + +
const uint16_t kSonyMinGapTicks = 50
+
+ +
+
+ +

◆ kSonyOneMark

+ +
+
+ + + + +
const uint16_t kSonyOneMark = kSonyOneMarkTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyOneMarkTicks

+ +
+
+ + + + +
const uint16_t kSonyOneMarkTicks = 6
+
+ +
+
+ +

◆ kSonyRptLength

+ +
+
+ + + + +
const uint16_t kSonyRptLength = kSonyRptLengthTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyRptLengthTicks

+ +
+
+ + + + +
const uint16_t kSonyRptLengthTicks = 225
+
+ +
+
+ +

◆ kSonySpace

+ +
+
+ + + + +
const uint16_t kSonySpace = kSonySpaceTicks * kSonyTick
+
+ +
+
+ +

◆ kSonySpaceTicks

+ +
+
+ + + + +
const uint16_t kSonySpaceTicks = 3
+
+ +
+
+ +

◆ kSonyStdFreq

+ +
+
+ + + + +
const uint16_t kSonyStdFreq = 40000
+
+ +
+
+ +

◆ kSonyTick

+ +
+
+ + + + +
const uint16_t kSonyTick = 200
+
+ +
+
+ +

◆ kSonyZeroMark

+ +
+
+ + + + +
const uint16_t kSonyZeroMark = kSonyZeroMarkTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyZeroMarkTicks

+ +
+
+ + + + +
const uint16_t kSonyZeroMarkTicks = 3
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Symphony_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Symphony_8cpp.html new file mode 100644 index 000000000..9ad124022 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Symphony_8cpp.html @@ -0,0 +1,181 @@ + + + + + + + +IRremoteESP8266: src/ir_Symphony.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Symphony.cpp File Reference
+
+
+ +

Support for Symphony protocols. +More...

+ + + + + + + + + + + + +

+Variables

const uint16_t kSymphonyZeroMark = 400
 
const uint16_t kSymphonyZeroSpace = 1250
 
const uint16_t kSymphonyOneMark = kSymphonyZeroSpace
 
const uint16_t kSymphonyOneSpace = kSymphonyZeroMark
 
const uint32_t kSymphonyFooterGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSymphonyFooterGap

+ +
+
+ + + + +
const uint32_t kSymphonyFooterGap
+
+Initial value: +
+
+ +

◆ kSymphonyOneMark

+ +
+
+ + + + +
const uint16_t kSymphonyOneMark = kSymphonyZeroSpace
+
+ +
+
+ +

◆ kSymphonyOneSpace

+ +
+
+ + + + +
const uint16_t kSymphonyOneSpace = kSymphonyZeroMark
+
+ +
+
+ +

◆ kSymphonyZeroMark

+ +
+
+ + + + +
const uint16_t kSymphonyZeroMark = 400
+
+ +
+
+ +

◆ kSymphonyZeroSpace

+ +
+
+ + + + +
const uint16_t kSymphonyZeroSpace = 1250
+
+ +
+
+
+
const uint16_t kSymphonyZeroMark
Definition: ir_Symphony.cpp:29
+
const uint16_t kSymphonyZeroSpace
Definition: ir_Symphony.cpp:30
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8cpp.html new file mode 100644 index 000000000..722bb446c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8cpp.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: src/ir_Tcl.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Tcl.cpp File Reference
+
+
+ +

Support for TCL protocols. +More...

+

Detailed Description

+

Support for TCL protocols.

+
Note
There is no decodedecodeTcl112Ac(). It's the same as decodeMitsubishi112(). A shared routine is used. You can find it in: ir_Mitsubishi.cpp
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h.html new file mode 100644 index 000000000..9a6621ade --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h.html @@ -0,0 +1,613 @@ + + + + + + + +IRremoteESP8266: src/ir_Tcl.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Tcl.h File Reference
+
+
+ +

Support for TCL protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRTcl112Ac
 Class for handling detailed TCL A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kTcl112AcHdrMark = 3000
 
const uint16_t kTcl112AcHdrSpace = 1650
 
const uint16_t kTcl112AcBitMark = 500
 
const uint16_t kTcl112AcOneSpace = 1050
 
const uint16_t kTcl112AcZeroSpace = 325
 
const uint32_t kTcl112AcGap = kDefaultMessageGap
 
const uint8_t kTcl112AcHdrMarkTolerance = 6
 
const uint8_t kTcl112AcTolerance = 5
 
const uint8_t kTcl112AcHeat = 1
 
const uint8_t kTcl112AcDry = 2
 
const uint8_t kTcl112AcCool = 3
 
const uint8_t kTcl112AcFan = 7
 
const uint8_t kTcl112AcAuto = 8
 
const uint8_t kTcl112AcModeSize = 4
 
const uint8_t kTcl112AcFanSize = 3
 
const uint8_t kTcl112AcFanAuto = 0b000
 
const uint8_t kTcl112AcFanLow = 0b010
 
const uint8_t kTcl112AcFanMed = 0b011
 
const uint8_t kTcl112AcFanHigh = 0b101
 
const uint8_t kTcl112AcHalfDegreeOffset = 5
 
const float kTcl112AcTempMax = 31.0
 
const float kTcl112AcTempMin = 16.0
 
const uint8_t kTcl112AcPowerOffset = 2
 
const uint8_t kTcl112AcBitEconoOffset = 7
 
const uint8_t kTcl112AcBitLightOffset = 6
 
const uint8_t kTcl112AcBitHealthOffset = 4
 
const uint8_t kTcl112AcBitSwingHOffset = 3
 
const uint8_t kTcl112AcSwingVOffset = 3
 
const uint8_t kTcl112AcSwingVSize = 3
 
const uint8_t kTcl112AcSwingVOn = 0b111
 
const uint8_t kTcl112AcSwingVOff = 0b000
 
const uint8_t kTcl112AcBitTurboOffset = 6
 
+

Detailed Description

+

Support for TCL protocols.

+

Variable Documentation

+ +

◆ kTcl112AcAuto

+ +
+
+ + + + +
const uint8_t kTcl112AcAuto = 8
+
+ +
+
+ +

◆ kTcl112AcBitEconoOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitEconoOffset = 7
+
+ +
+
+ +

◆ kTcl112AcBitHealthOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitHealthOffset = 4
+
+ +
+
+ +

◆ kTcl112AcBitLightOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitLightOffset = 6
+
+ +
+
+ +

◆ kTcl112AcBitMark

+ +
+
+ + + + +
const uint16_t kTcl112AcBitMark = 500
+
+ +
+
+ +

◆ kTcl112AcBitSwingHOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitSwingHOffset = 3
+
+ +
+
+ +

◆ kTcl112AcBitTurboOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitTurboOffset = 6
+
+ +
+
+ +

◆ kTcl112AcCool

+ +
+
+ + + + +
const uint8_t kTcl112AcCool = 3
+
+ +
+
+ +

◆ kTcl112AcDry

+ +
+
+ + + + +
const uint8_t kTcl112AcDry = 2
+
+ +
+
+ +

◆ kTcl112AcFan

+ +
+
+ + + + +
const uint8_t kTcl112AcFan = 7
+
+ +
+
+ +

◆ kTcl112AcFanAuto

+ +
+
+ + + + +
const uint8_t kTcl112AcFanAuto = 0b000
+
+ +
+
+ +

◆ kTcl112AcFanHigh

+ +
+
+ + + + +
const uint8_t kTcl112AcFanHigh = 0b101
+
+ +
+
+ +

◆ kTcl112AcFanLow

+ +
+
+ + + + +
const uint8_t kTcl112AcFanLow = 0b010
+
+ +
+
+ +

◆ kTcl112AcFanMed

+ +
+
+ + + + +
const uint8_t kTcl112AcFanMed = 0b011
+
+ +
+
+ +

◆ kTcl112AcFanSize

+ +
+
+ + + + +
const uint8_t kTcl112AcFanSize = 3
+
+ +
+
+ +

◆ kTcl112AcGap

+ +
+
+ + + + +
const uint32_t kTcl112AcGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kTcl112AcHalfDegreeOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcHalfDegreeOffset = 5
+
+ +
+
+ +

◆ kTcl112AcHdrMark

+ +
+
+ + + + +
const uint16_t kTcl112AcHdrMark = 3000
+
+ +
+
+ +

◆ kTcl112AcHdrMarkTolerance

+ +
+
+ + + + +
const uint8_t kTcl112AcHdrMarkTolerance = 6
+
+ +
+
+ +

◆ kTcl112AcHdrSpace

+ +
+
+ + + + +
const uint16_t kTcl112AcHdrSpace = 1650
+
+ +
+
+ +

◆ kTcl112AcHeat

+ +
+
+ + + + +
const uint8_t kTcl112AcHeat = 1
+
+ +
+
+ +

◆ kTcl112AcModeSize

+ +
+
+ + + + +
const uint8_t kTcl112AcModeSize = 4
+
+ +
+
+ +

◆ kTcl112AcOneSpace

+ +
+
+ + + + +
const uint16_t kTcl112AcOneSpace = 1050
+
+ +
+
+ +

◆ kTcl112AcPowerOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcPowerOffset = 2
+
+ +
+
+ +

◆ kTcl112AcSwingVOff

+ +
+
+ + + + +
const uint8_t kTcl112AcSwingVOff = 0b000
+
+ +
+
+ +

◆ kTcl112AcSwingVOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcSwingVOffset = 3
+
+ +
+
+ +

◆ kTcl112AcSwingVOn

+ +
+
+ + + + +
const uint8_t kTcl112AcSwingVOn = 0b111
+
+ +
+
+ +

◆ kTcl112AcSwingVSize

+ +
+
+ + + + +
const uint8_t kTcl112AcSwingVSize = 3
+
+ +
+
+ +

◆ kTcl112AcTempMax

+ +
+
+ + + + +
const float kTcl112AcTempMax = 31.0
+
+ +
+
+ +

◆ kTcl112AcTempMin

+ +
+
+ + + + +
const float kTcl112AcTempMin = 16.0
+
+ +
+
+ +

◆ kTcl112AcTolerance

+ +
+
+ + + + +
const uint8_t kTcl112AcTolerance = 5
+
+ +
+
+ +

◆ kTcl112AcZeroSpace

+ +
+
+ + + + +
const uint16_t kTcl112AcZeroSpace = 325
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h_source.html new file mode 100644 index 000000000..3c6dbbbcf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h_source.html @@ -0,0 +1,281 @@ + + + + + + + +IRremoteESP8266: src/ir_Tcl.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Tcl.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
2 
+
5 
+
6 // Supports:
+
7 // Brand: Leberg, Model: LBS-TOR07 A/C
+
8 
+
9 #ifndef IR_TCL_H_
+
10 #define IR_TCL_H_
+
11 
+
12 #ifndef UNIT_TEST
+
13 #include <Arduino.h>
+
14 #endif
+
15 #include "IRremoteESP8266.h"
+
16 #include "IRsend.h"
+
17 #include "IRrecv.h"
+
18 #ifdef UNIT_TEST
+
19 #include "IRsend_test.h"
+
20 #endif
+
21 
+
22 // Constants
+
23 const uint16_t kTcl112AcHdrMark = 3000;
+
24 const uint16_t kTcl112AcHdrSpace = 1650;
+
25 const uint16_t kTcl112AcBitMark = 500;
+
26 const uint16_t kTcl112AcOneSpace = 1050;
+
27 const uint16_t kTcl112AcZeroSpace = 325;
+
28 const uint32_t kTcl112AcGap = kDefaultMessageGap; // Just a guess.
+
29 // Total tolerance percentage to use for matching the header mark.
+
30 const uint8_t kTcl112AcHdrMarkTolerance = 6;
+
31 const uint8_t kTcl112AcTolerance = 5; // Extra Percentage for the rest.
+
32 
+
33 const uint8_t kTcl112AcHeat = 1;
+
34 const uint8_t kTcl112AcDry = 2;
+
35 const uint8_t kTcl112AcCool = 3;
+
36 const uint8_t kTcl112AcFan = 7;
+
37 const uint8_t kTcl112AcAuto = 8;
+
38 const uint8_t kTcl112AcModeSize = 4; // Nr. of Bits
+
39 
+
40 const uint8_t kTcl112AcFanSize = 3; // Nr. of Bits. Mask = 0b00000111
+
41 const uint8_t kTcl112AcFanAuto = 0b000;
+
42 const uint8_t kTcl112AcFanLow = 0b010;
+
43 const uint8_t kTcl112AcFanMed = 0b011;
+
44 const uint8_t kTcl112AcFanHigh = 0b101;
+
45 
+
46 const uint8_t kTcl112AcHalfDegreeOffset = 5;
+
47 const float kTcl112AcTempMax = 31.0;
+
48 const float kTcl112AcTempMin = 16.0;
+
49 
+
50 const uint8_t kTcl112AcPowerOffset = 2;
+
51 const uint8_t kTcl112AcBitEconoOffset = 7;
+
52 const uint8_t kTcl112AcBitLightOffset = 6;
+
53 const uint8_t kTcl112AcBitHealthOffset = 4;
+
54 const uint8_t kTcl112AcBitSwingHOffset = 3;
+
55 const uint8_t kTcl112AcSwingVOffset = 3; // Mask 0b00111000
+
56 const uint8_t kTcl112AcSwingVSize = 3; // Nr. of bits.
+
57 const uint8_t kTcl112AcSwingVOn = 0b111;
+
58 const uint8_t kTcl112AcSwingVOff = 0b000;
+
59 const uint8_t kTcl112AcBitTurboOffset = 6;
+
60 
+
61 // Classes
+
63 class IRTcl112Ac {
+
64  public:
+
65  explicit IRTcl112Ac(const uint16_t pin, const bool inverted = false,
+
66  const bool use_modulation = true);
+
67 #if SEND_TCL112AC
+
68  void send(const uint16_t repeat = kTcl112AcDefaultRepeat);
+
73  int8_t calibrate(void) { return _irsend.calibrate(); }
+
74 #endif // SEND_TCL
+
75  void begin(void);
+
76  void stateReset(void);
+
77  uint8_t* getRaw(void);
+
78  void setRaw(const uint8_t new_code[],
+
79  const uint16_t length = kTcl112AcStateLength);
+
80  void on(void);
+
81  void off(void);
+
82  void setPower(const bool on);
+
83  bool getPower(void);
+
84  void setTemp(const float celsius); // Celsius in 0.5 increments
+
85  float getTemp(void);
+
86  void setMode(const uint8_t mode);
+
87  uint8_t getMode(void);
+
88  static uint8_t calcChecksum(uint8_t state[],
+
89  const uint16_t length = kTcl112AcStateLength);
+
90  static bool validChecksum(uint8_t state[],
+
91  const uint16_t length = kTcl112AcStateLength);
+
92  void setFan(const uint8_t speed);
+
93  uint8_t getFan(void);
+
94  void setEcono(const bool on);
+
95  bool getEcono(void);
+
96  void setHealth(const bool on);
+
97  bool getHealth(void);
+
98  void setLight(const bool on);
+
99  bool getLight(void);
+
100  void setSwingHorizontal(const bool on);
+
101  bool getSwingHorizontal(void);
+
102  void setSwingVertical(const bool on);
+
103  bool getSwingVertical(void);
+
104  void setTurbo(const bool on);
+
105  bool getTurbo(void);
+
106  uint8_t convertMode(const stdAc::opmode_t mode);
+
107  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
108  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
109  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
110  stdAc::state_t toCommon(void);
+
111  String toString(void);
+
112 #ifndef UNIT_TEST
+
113 
+
114  private:
+ +
116 #else // UNIT_TEST
+
117  IRsendTest _irsend;
+
119 #endif // UNIT_TEST
+ +
122  void checksum(const uint16_t length = kTcl112AcStateLength);
+
123 };
+
124 
+
125 #endif // IR_TCL_H_
+
+
bool getSwingHorizontal(void)
Get the horizontal swing setting of the A/C.
Definition: ir_Tcl.cpp:248
+
void setSwingHorizontal(const bool on)
Set the horizontal swing setting of the A/C.
Definition: ir_Tcl.cpp:242
+
const uint8_t kTcl112AcBitSwingHOffset
Definition: ir_Tcl.h:54
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Tcl.cpp:297
+
static uint8_t calcChecksum(uint8_t state[], const uint16_t length=kTcl112AcStateLength)
Calculate the checksum for a given state.
Definition: ir_Tcl.cpp:66
+
const float kTcl112AcTempMin
Definition: ir_Tcl.h:48
+
void setSwingVertical(const bool on)
Set the vertical swing setting of the A/C.
Definition: ir_Tcl.cpp:254
+
bool getEcono(void)
Get the economy setting of the A/C.
Definition: ir_Tcl.cpp:212
+
const uint16_t kTcl112AcHdrSpace
Definition: ir_Tcl.h:24
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Tcl.cpp:284
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint32_t kDefaultMessageGap
Definition: IRsend.h:41
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Tcl.cpp:363
+
const uint8_t kTcl112AcFanLow
Definition: ir_Tcl.h:42
+
void send(const uint16_t repeat=kTcl112AcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Tcl.cpp:57
+
const uint16_t kTcl112AcBitMark
Definition: ir_Tcl.h:25
+
const uint8_t kTcl112AcSwingVOffset
Definition: ir_Tcl.h:55
+
const uint8_t kTcl112AcFanMed
Definition: ir_Tcl.h:43
+
bool getLight(void)
Get the Light (LED/Display) setting of the A/C.
Definition: ir_Tcl.cpp:236
+
bool getHealth(void)
Get the Health (Filter) setting of the A/C.
Definition: ir_Tcl.cpp:224
+ +
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void setEcono(const bool on)
Set the economy setting of the A/C.
Definition: ir_Tcl.cpp:206
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Tcl.cpp:200
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kTcl112AcBitLightOffset
Definition: ir_Tcl.h:52
+
const uint16_t kTcl112AcOneSpace
Definition: ir_Tcl.h:26
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void stateReset(void)
Reset the internal state of the emulation. (On, Cool, 24C)
Definition: ir_Tcl.cpp:90
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Tcl.cpp:132
+
Class for handling detailed TCL A/C messages.
Definition: ir_Tcl.h:63
+
void checksum(const uint16_t length=kTcl112AcStateLength)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Tcl.cpp:75
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Tcl.cpp:335
+ +
IRsend _irsend
Instance of the IR send class.
Definition: ir_Tcl.h:115
+
void setTemp(const float celsius)
Set the temperature.
Definition: ir_Tcl.cpp:160
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Tcl.cpp:100
+
void setLight(const bool on)
Set the Light (LED/Display) setting of the A/C.
Definition: ir_Tcl.cpp:230
+
const uint8_t kTcl112AcHalfDegreeOffset
Definition: ir_Tcl.h:46
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Tcl.cpp:120
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Tcl.h:73
+
const uint32_t kTcl112AcGap
Definition: ir_Tcl.h:28
+
static bool validChecksum(uint8_t state[], const uint16_t length=kTcl112AcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Tcl.cpp:85
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Tcl.cpp:52
+
const uint8_t kTcl112AcSwingVOn
Definition: ir_Tcl.h:57
+
const uint8_t kTcl112AcAuto
Definition: ir_Tcl.h:37
+
const uint16_t kTcl112AcDefaultRepeat
Definition: IRremoteESP8266.h:996
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Tcl.cpp:324
+
const float kTcl112AcTempMax
Definition: ir_Tcl.h:47
+
const uint16_t kTcl112AcHdrMark
Definition: ir_Tcl.h:23
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Tcl.cpp:140
+
const uint8_t kTcl112AcBitHealthOffset
Definition: ir_Tcl.h:53
+
const uint8_t kTcl112AcFanAuto
Definition: ir_Tcl.h:41
+
const uint8_t kTcl112AcModeSize
Definition: ir_Tcl.h:38
+
const uint8_t kTcl112AcSwingVSize
Definition: ir_Tcl.h:56
+
const uint8_t kTcl112AcCool
Definition: ir_Tcl.h:35
+
float getTemp(void)
Get the current temperature setting.
Definition: ir_Tcl.cpp:175
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Tcl.cpp:113
+
const uint8_t kTcl112AcFanSize
Definition: ir_Tcl.h:40
+ +
const uint8_t kTcl112AcPowerOffset
Definition: ir_Tcl.h:50
+
void setHealth(const bool on)
Set the Health (Filter) setting of the A/C.
Definition: ir_Tcl.cpp:218
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Tcl.cpp:116
+
void setRaw(const uint8_t new_code[], const uint16_t length=kTcl112AcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Tcl.cpp:108
+
const uint8_t kTcl112AcSwingVOff
Definition: ir_Tcl.h:58
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Tcl.cpp:185
+
const uint8_t kTcl112AcHdrMarkTolerance
Definition: ir_Tcl.h:30
+
uint8_t remote_state[kTcl112AcStateLength]
The State in IR code form.
Definition: ir_Tcl.h:121
+
const uint8_t kTcl112AcDry
Definition: ir_Tcl.h:34
+
const uint8_t kTcl112AcFanHigh
Definition: ir_Tcl.h:44
+
const uint16_t kTcl112AcStateLength
Definition: IRremoteESP8266.h:994
+
const uint8_t kTcl112AcFan
Definition: ir_Tcl.h:36
+
const uint8_t kTcl112AcBitTurboOffset
Definition: ir_Tcl.h:59
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Tcl.cpp:126
+
const uint8_t kTcl112AcBitEconoOffset
Definition: ir_Tcl.h:51
+
const uint16_t kTcl112AcZeroSpace
Definition: ir_Tcl.h:27
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Tcl.cpp:311
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Tcl.cpp:267
+
IRTcl112Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Tcl.cpp:47
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Tcl.cpp:277
+
const uint8_t kTcl112AcTolerance
Definition: ir_Tcl.h:31
+
const uint8_t kTcl112AcHeat
Definition: ir_Tcl.h:33
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
bool getSwingVertical(void)
Get the vertical swing setting of the A/C.
Definition: ir_Tcl.cpp:261
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8cpp.html new file mode 100644 index 000000000..56e288060 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8cpp.html @@ -0,0 +1,188 @@ + + + + + + + +IRremoteESP8266: src/ir_Teco.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Teco.cpp File Reference
+
+
+ +

Support for Teco protocols. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kTecoHdrMark = 9000
 
const uint16_t kTecoHdrSpace = 4440
 
const uint16_t kTecoBitMark = 620
 
const uint16_t kTecoOneSpace = 1650
 
const uint16_t kTecoZeroSpace = 580
 
const uint32_t kTecoGap = kDefaultMessageGap
 
+

Detailed Description

+

Support for Teco protocols.

+

Variable Documentation

+ +

◆ kTecoBitMark

+ +
+
+ + + + +
const uint16_t kTecoBitMark = 620
+
+ +
+
+ +

◆ kTecoGap

+ +
+
+ + + + +
const uint32_t kTecoGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kTecoHdrMark

+ +
+
+ + + + +
const uint16_t kTecoHdrMark = 9000
+
+ +
+
+ +

◆ kTecoHdrSpace

+ +
+
+ + + + +
const uint16_t kTecoHdrSpace = 4440
+
+ +
+
+ +

◆ kTecoOneSpace

+ +
+
+ + + + +
const uint16_t kTecoOneSpace = 1650
+
+ +
+
+ +

◆ kTecoZeroSpace

+ +
+
+ + + + +
const uint16_t kTecoZeroSpace = 580
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h.html new file mode 100644 index 000000000..a387292b9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h.html @@ -0,0 +1,565 @@ + + + + + + + +IRremoteESP8266: src/ir_Teco.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Teco.h File Reference
+
+
+ +

Support for Teco protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRTecoAc
 Class for handling detailed Teco A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kTecoAuto = 0
 
const uint8_t kTecoCool = 1
 
const uint8_t kTecoDry = 2
 
const uint8_t kTecoFan = 3
 
const uint8_t kTecoHeat = 4
 
const uint8_t kTecoFanAuto = 0
 
const uint8_t kTecoFanLow = 1
 
const uint8_t kTecoFanMed = 2
 
const uint8_t kTecoFanHigh = 3
 
const uint8_t kTecoMinTemp = 16
 
const uint8_t kTecoMaxTemp = 30
 
const uint8_t kTecoModeOffset = 0
 
const uint8_t kTecoPowerOffset = 3
 
const uint8_t kTecoFanOffset = 4
 
const uint8_t kTecoFanSize = 2
 
const uint8_t kTecoSwingOffset = 6
 
const uint8_t kTecoSleepOffset = 7
 
const uint8_t kTecoTempOffset = 8
 
const uint8_t kTecoTempSize = 4
 
const uint8_t kTecoTimerHalfHourOffset = 12
 
const uint8_t kTecoTimerTensHoursOffset = 13
 
const uint8_t kTecoTimerTensHoursSize = 2
 
const uint8_t kTecoTimerOnOffset = 15
 
const uint8_t kTecoTimerUnitHoursOffset = 16
 
const uint8_t kTecoTimerUnitHoursSize = 4
 
const uint8_t kTecoHumidOffset = 20
 
const uint8_t kTecoLightOffset = 21
 
const uint8_t kTecoSaveOffset = 23
 
const uint64_t kTecoReset = 0b01001010000000000000010000000000000
 
+

Detailed Description

+

Support for Teco protocols.

+

Variable Documentation

+ +

◆ kTecoAuto

+ +
+
+ + + + +
const uint8_t kTecoAuto = 0
+
+ +
+
+ +

◆ kTecoCool

+ +
+
+ + + + +
const uint8_t kTecoCool = 1
+
+ +
+
+ +

◆ kTecoDry

+ +
+
+ + + + +
const uint8_t kTecoDry = 2
+
+ +
+
+ +

◆ kTecoFan

+ +
+
+ + + + +
const uint8_t kTecoFan = 3
+
+ +
+
+ +

◆ kTecoFanAuto

+ +
+
+ + + + +
const uint8_t kTecoFanAuto = 0
+
+ +
+
+ +

◆ kTecoFanHigh

+ +
+
+ + + + +
const uint8_t kTecoFanHigh = 3
+
+ +
+
+ +

◆ kTecoFanLow

+ +
+
+ + + + +
const uint8_t kTecoFanLow = 1
+
+ +
+
+ +

◆ kTecoFanMed

+ +
+
+ + + + +
const uint8_t kTecoFanMed = 2
+
+ +
+
+ +

◆ kTecoFanOffset

+ +
+
+ + + + +
const uint8_t kTecoFanOffset = 4
+
+ +
+
+ +

◆ kTecoFanSize

+ +
+
+ + + + +
const uint8_t kTecoFanSize = 2
+
+ +
+
+ +

◆ kTecoHeat

+ +
+
+ + + + +
const uint8_t kTecoHeat = 4
+
+ +
+
+ +

◆ kTecoHumidOffset

+ +
+
+ + + + +
const uint8_t kTecoHumidOffset = 20
+
+ +
+
+ +

◆ kTecoLightOffset

+ +
+
+ + + + +
const uint8_t kTecoLightOffset = 21
+
+ +
+
+ +

◆ kTecoMaxTemp

+ +
+
+ + + + +
const uint8_t kTecoMaxTemp = 30
+
+ +
+
+ +

◆ kTecoMinTemp

+ +
+
+ + + + +
const uint8_t kTecoMinTemp = 16
+
+ +
+
+ +

◆ kTecoModeOffset

+ +
+
+ + + + +
const uint8_t kTecoModeOffset = 0
+
+ +
+
+ +

◆ kTecoPowerOffset

+ +
+
+ + + + +
const uint8_t kTecoPowerOffset = 3
+
+ +
+
+ +

◆ kTecoReset

+ +
+
+ + + + +
const uint64_t kTecoReset = 0b01001010000000000000010000000000000
+
+ +
+
+ +

◆ kTecoSaveOffset

+ +
+
+ + + + +
const uint8_t kTecoSaveOffset = 23
+
+ +
+
+ +

◆ kTecoSleepOffset

+ +
+
+ + + + +
const uint8_t kTecoSleepOffset = 7
+
+ +
+
+ +

◆ kTecoSwingOffset

+ +
+
+ + + + +
const uint8_t kTecoSwingOffset = 6
+
+ +
+
+ +

◆ kTecoTempOffset

+ +
+
+ + + + +
const uint8_t kTecoTempOffset = 8
+
+ +
+
+ +

◆ kTecoTempSize

+ +
+
+ + + + +
const uint8_t kTecoTempSize = 4
+
+ +
+
+ +

◆ kTecoTimerHalfHourOffset

+ +
+
+ + + + +
const uint8_t kTecoTimerHalfHourOffset = 12
+
+ +
+
+ +

◆ kTecoTimerOnOffset

+ +
+
+ + + + +
const uint8_t kTecoTimerOnOffset = 15
+
+ +
+
+ +

◆ kTecoTimerTensHoursOffset

+ +
+
+ + + + +
const uint8_t kTecoTimerTensHoursOffset = 13
+
+ +
+
+ +

◆ kTecoTimerTensHoursSize

+ +
+
+ + + + +
const uint8_t kTecoTimerTensHoursSize = 2
+
+ +
+
+ +

◆ kTecoTimerUnitHoursOffset

+ +
+
+ + + + +
const uint8_t kTecoTimerUnitHoursOffset = 16
+
+ +
+
+ +

◆ kTecoTimerUnitHoursSize

+ +
+
+ + + + +
const uint8_t kTecoTimerUnitHoursSize = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h_source.html new file mode 100644 index 000000000..ea0e37a5f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h_source.html @@ -0,0 +1,324 @@ + + + + + + + +IRremoteESP8266: src/ir_Teco.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Teco.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 Fabien Valthier
+
2 
+
5 
+
6 // Supports:
+
7 // Brand: Alaska, Model: SAC9010QC A/C
+
8 // Brand: Alaska, Model: SAC9010QC remote
+
9 
+
10 #ifndef IR_TECO_H_
+
11 #define IR_TECO_H_
+
12 
+
13 #ifndef UNIT_TEST
+
14 #include <Arduino.h>
+
15 #endif
+
16 #include "IRremoteESP8266.h"
+
17 #include "IRsend.h"
+
18 #ifdef UNIT_TEST
+
19 #include "IRsend_test.h"
+
20 #endif
+
21 
+
22 // Constants.
+
23 const uint8_t kTecoAuto = 0;
+
24 const uint8_t kTecoCool = 1;
+
25 const uint8_t kTecoDry = 2;
+
26 const uint8_t kTecoFan = 3;
+
27 const uint8_t kTecoHeat = 4;
+
28 const uint8_t kTecoFanAuto = 0; // 0b00
+
29 const uint8_t kTecoFanLow = 1; // 0b01
+
30 const uint8_t kTecoFanMed = 2; // 0b10
+
31 const uint8_t kTecoFanHigh = 3; // 0b11
+
32 const uint8_t kTecoMinTemp = 16; // 16C
+
33 const uint8_t kTecoMaxTemp = 30; // 30C
+
34 
+
35 const uint8_t kTecoModeOffset = 0;
+
36 const uint8_t kTecoPowerOffset = 3;
+
37 const uint8_t kTecoFanOffset = 4;
+
38 const uint8_t kTecoFanSize = 2; // Nr. of bits
+
39 const uint8_t kTecoSwingOffset = 6;
+
40 const uint8_t kTecoSleepOffset = 7;
+
41 const uint8_t kTecoTempOffset = 8;
+
42 const uint8_t kTecoTempSize = 4; // Nr. of bits
+
43 const uint8_t kTecoTimerHalfHourOffset = 12;
+
44 const uint8_t kTecoTimerTensHoursOffset = 13;
+
45 const uint8_t kTecoTimerTensHoursSize = 2; // Nr. of bits
+
46 const uint8_t kTecoTimerOnOffset = 15;
+
47 const uint8_t kTecoTimerUnitHoursOffset = 16;
+
48 const uint8_t kTecoTimerUnitHoursSize = 4; // Nr. of bits
+
49 const uint8_t kTecoHumidOffset = 20;
+
50 const uint8_t kTecoLightOffset = 21;
+
51 const uint8_t kTecoSaveOffset = 23;
+
52 const uint64_t kTecoReset = 0b01001010000000000000010000000000000;
+
53 /*
+
54  (header mark and space)
+
55  Teco AC map read and to be sent in LSB with number of bits
+
56 
+
57  byte 0 = Cst 0x02
+
58  byte 1 = Cst 0x50
+
59  b6-7 = "AIR" 0, 1, 2 (Not Implemented)
+
60  byte 2:
+
61  b0 = Save
+
62  b1 = "Tree with bubbles" / Filter?? (Not Implemented)
+
63  b2 = Light/LED.
+
64  b3 = Humid
+
65  b4-7 = Timer hours (unit, not thenth)
+
66  hours:
+
67  0000 (0) = +0 hour
+
68  0001 (1) = +1 hour
+
69  ...
+
70  1001 (9) = +9 hours
+
71  byte 3: = timer and Temperature
+
72  b0 = Timer (1 = On, 0 = Off)
+
73  b1-2 = Timer - number of 10hours
+
74  10Hours:
+
75  00 = 0 * 10hours of timer
+
76  01 = 1 * 10 hours of timer
+
77  10 = 2 * 10hours of timer
+
78  b3 = Timer - half hour (1=half hour on, 0 = round hour)
+
79  b4-7: Degrees C.
+
80  0000 (0) = 16C
+
81  0001 (1) = 17C
+
82  0010 (2) = 18C
+
83  ...
+
84  1101 (13) = 29C
+
85  1110 (14) = 30C
+
86  byte 4: Basics
+
87  b0 = Sleep Mode (1 = On, 0 = Off)
+
88  b1 = Vent swing (1 = On, 0 = Off)
+
89  b2-3 = Fan
+
90  Fan:
+
91  00 = Auto
+
92  01 = Fan 1
+
93  10 = Fan 2
+
94  11 = Fan 3 or higher
+
95  b4 = Power Status (1 = On, 0 = Off)
+
96  b5-7 = Modes LSB first
+
97  Modes:
+
98  000 = Auto (temp = 25C)
+
99  001 = Cool
+
100  010 = Dry (temp = 25C, but not shown)
+
101  011 = Fan
+
102  100 = Heat
+
103 */
+
104 
+
105 // Classes
+
107 class IRTecoAc {
+
108  public:
+
109  explicit IRTecoAc(const uint16_t pin, const bool inverted = false,
+
110  const bool use_modulation = true);
+
111  void stateReset(void);
+
112 #if SEND_TECO
+
113  void send(const uint16_t repeat = kTecoDefaultRepeat);
+
118  int8_t calibrate(void) { return _irsend.calibrate(); }
+
119 #endif // SEND_TECO
+
120  void begin(void);
+
121  void on(void);
+
122  void off(void);
+
123 
+
124  void setPower(const bool on);
+
125  bool getPower(void);
+
126 
+
127  void setTemp(const uint8_t temp);
+
128  uint8_t getTemp(void);
+
129 
+
130  void setFan(const uint8_t fan);
+
131  uint8_t getFan(void);
+
132 
+
133  void setMode(const uint8_t mode);
+
134  uint8_t getMode(void);
+
135 
+
136  void setSwing(const bool on);
+
137  bool getSwing(void);
+
138 
+
139  void setSleep(const bool on);
+
140  bool getSleep(void);
+
141 
+
142  void setLight(const bool on);
+
143  bool getLight(void);
+
144 
+
145  void setHumid(const bool on);
+
146  bool getHumid(void);
+
147 
+
148  void setSave(const bool on);
+
149  bool getSave(void);
+
150 
+
151  uint16_t getTimer(void);
+
152  void setTimer(const uint16_t mins);
+
153 
+
154  uint64_t getRaw(void);
+
155  void setRaw(const uint64_t new_code);
+
156 
+
157  uint8_t convertMode(const stdAc::opmode_t mode);
+
158  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
159  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
160  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
161  stdAc::state_t toCommon(void);
+
162  String toString(void);
+
163 #ifndef UNIT_TEST
+
164 
+
165  private:
+ +
167 #else // UNIT_TEST
+
168  IRsendTest _irsend;
+
170 #endif // UNIT_TEST
+
172  uint64_t remote_state;
+
173  bool getTimerEnabled(void);
+
174 };
+
175 
+
176 #endif // IR_TECO_H_
+
+
bool getSwing(void)
Get the (vertical) swing setting of the A/C.
Definition: ir_Teco.cpp:163
+
const uint8_t kTecoFanMed
Definition: ir_Teco.h:30
+
bool getHumid(void)
Get the Humid setting of the A/C.
Definition: ir_Teco.cpp:199
+
const uint8_t kTecoTempOffset
Definition: ir_Teco.h:41
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Teco.cpp:94
+
const uint8_t kTecoPowerOffset
Definition: ir_Teco.h:36
+
const uint64_t kTecoReset
Definition: ir_Teco.h:52
+
bool getTimerEnabled(void)
Is the timer function enabled?
Definition: ir_Teco.cpp:217
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Teco.cpp:283
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Teco.cpp:84
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Teco.cpp:175
+
const uint8_t kTecoModeOffset
Definition: ir_Teco.h:35
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Teco.cpp:256
+
uint16_t getTimer(void)
Get the timer time for when the A/C unit will switch power state.
Definition: ir_Teco.cpp:223
+
const uint8_t kTecoTempSize
Definition: ir_Teco.h:42
+
const uint8_t kTecoSleepOffset
Definition: ir_Teco.h:40
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Teco.h:118
+ +
const uint8_t kTecoMinTemp
Definition: ir_Teco.h:32
+
void setRaw(const uint64_t new_code)
Set the internal state from a valid code for this protocol.
Definition: ir_Teco.cpp:78
+
IRTecoAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Teco.cpp:51
+
const uint8_t kTecoMaxTemp
Definition: ir_Teco.h:33
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Teco.cpp:81
+
const uint8_t kTecoDry
Definition: ir_Teco.h:25
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kTecoHeat
Definition: ir_Teco.h:27
+
const uint8_t kTecoTimerTensHoursOffset
Definition: ir_Teco.h:44
+
const uint8_t kTecoFanOffset
Definition: ir_Teco.h:37
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Teco.cpp:88
+
void setSwing(const bool on)
Set the (vertical) swing setting of the A/C.
Definition: ir_Teco.cpp:157
+
const uint8_t kTecoSaveOffset
Definition: ir_Teco.h:51
+
const uint8_t kTecoTimerUnitHoursOffset
Definition: ir_Teco.h:47
+ +
void setHumid(const bool on)
Set the Humid setting of the A/C.
Definition: ir_Teco.cpp:193
+
void setTimer(const uint16_t mins)
Set the timer for when the A/C unit will switch power state.
Definition: ir_Teco.cpp:239
+
const uint8_t kTecoFanLow
Definition: ir_Teco.h:29
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Teco.cpp:169
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Teco.cpp:56
+
const uint16_t kTecoDefaultRepeat
Definition: IRremoteESP8266.h:998
+
const uint8_t kTecoFanSize
Definition: ir_Teco.h:38
+
const uint8_t kTecoFanAuto
Definition: ir_Teco.h:28
+
bool getLight(void)
Get the Light (LED/Display) setting of the A/C.
Definition: ir_Teco.cpp:187
+
const uint8_t kTecoCool
Definition: ir_Teco.h:24
+
const uint8_t kTecoTimerTensHoursSize
Definition: ir_Teco.h:45
+
bool getSave(void)
Get the Save setting of the A/C.
Definition: ir_Teco.cpp:211
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Teco.cpp:334
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Teco.cpp:110
+
const uint8_t kTecoTimerUnitHoursSize
Definition: ir_Teco.h:48
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Teco.cpp:100
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Teco.cpp:136
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Teco.cpp:296
+
void setSave(const bool on)
Set the Save setting of the A/C.
Definition: ir_Teco.cpp:205
+
const uint8_t kTecoHumidOffset
Definition: ir_Teco.h:49
+
const uint8_t kTecoSwingOffset
Definition: ir_Teco.h:39
+
void stateReset(void)
Reset the internal state of the emulation.
Definition: ir_Teco.cpp:68
+
uint64_t getRaw(void)
Get a copy of the internal state/code for this protocol.
Definition: ir_Teco.cpp:74
+
const uint8_t kTecoLightOffset
Definition: ir_Teco.h:50
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Teco.cpp:130
+
const uint8_t kTecoFan
Definition: ir_Teco.h:26
+
const uint8_t kTecoTimerOnOffset
Definition: ir_Teco.h:46
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Teco.cpp:151
+
Class for handling detailed Teco A/C messages.
Definition: ir_Teco.h:107
+
uint64_t remote_state
The state of the IR remote in IR code form.
Definition: ir_Teco.h:172
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Teco.cpp:269
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Teco.cpp:307
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Teco.h:166
+
void setLight(const bool on)
Set the Light (LED/Display) setting of the A/C.
Definition: ir_Teco.cpp:181
+
void send(const uint16_t repeat=kTecoDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Teco.cpp:61
+
const uint8_t kTecoFanHigh
Definition: ir_Teco.h:31
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kTecoAuto
Definition: ir_Teco.h:23
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Teco.cpp:116
+
const uint8_t kTecoTimerHalfHourOffset
Definition: ir_Teco.h:43
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8cpp.html new file mode 100644 index 000000000..29efab1fc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8cpp.html @@ -0,0 +1,191 @@ + + + + + + + +IRremoteESP8266: src/ir_Toshiba.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Toshiba.cpp File Reference
+
+
+ +

Support for Toshiba protocols. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kToshibaAcHdrMark = 4400
 
const uint16_t kToshibaAcHdrSpace = 4300
 
const uint16_t kToshibaAcBitMark = 543
 
const uint16_t kToshibaAcOneSpace = 1623
 
const uint16_t kToshibaAcZeroSpace = 472
 
const uint16_t kToshibaAcMinGap = 7048
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kToshibaAcBitMark

+ +
+
+ + + + +
const uint16_t kToshibaAcBitMark = 543
+
+ +
+
+ +

◆ kToshibaAcHdrMark

+ +
+
+ + + + +
const uint16_t kToshibaAcHdrMark = 4400
+
+ +
+
+ +

◆ kToshibaAcHdrSpace

+ +
+
+ + + + +
const uint16_t kToshibaAcHdrSpace = 4300
+
+ +
+
+ +

◆ kToshibaAcMinGap

+ +
+
+ + + + +
const uint16_t kToshibaAcMinGap = 7048
+
+ +
+
+ +

◆ kToshibaAcOneSpace

+ +
+
+ + + + +
const uint16_t kToshibaAcOneSpace = 1623
+
+ +
+
+ +

◆ kToshibaAcZeroSpace

+ +
+
+ + + + +
const uint16_t kToshibaAcZeroSpace = 472
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h.html new file mode 100644 index 000000000..a48d5a462 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h.html @@ -0,0 +1,376 @@ + + + + + + + +IRremoteESP8266: src/ir_Toshiba.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Toshiba.h File Reference
+
+
+ +

Support for Toshiba protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRToshibaAC
 Class for handling detailed Toshiba A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kToshibaAcModeOffset = 0
 
const uint8_t kToshibaAcModeSize = 2
 
const uint8_t kToshibaAcAuto = 0
 
const uint8_t kToshibaAcCool = 1
 
const uint8_t kToshibaAcDry = 2
 
const uint8_t kToshibaAcHeat = 3
 
const uint8_t kToshibaAcPowerOffset = 2
 
const uint8_t kToshibaAcFanOffset = 5
 
const uint8_t kToshibaAcFanSize = 3
 
const uint8_t kToshibaAcFanAuto = 0b000
 
const uint8_t kToshibaAcFanMin = 0b001
 
const uint8_t kToshibaAcFanMed = 0b011
 
const uint8_t kToshibaAcFanMax = 0b101
 
const uint8_t kToshibaAcTempOffset = 4
 
const uint8_t kToshibaAcTempSize = 4
 
const uint8_t kToshibaAcMinTemp = 17
 
const uint8_t kToshibaAcMaxTemp = 30
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kToshibaAcAuto

+ +
+
+ + + + +
const uint8_t kToshibaAcAuto = 0
+
+ +
+
+ +

◆ kToshibaAcCool

+ +
+
+ + + + +
const uint8_t kToshibaAcCool = 1
+
+ +
+
+ +

◆ kToshibaAcDry

+ +
+
+ + + + +
const uint8_t kToshibaAcDry = 2
+
+ +
+
+ +

◆ kToshibaAcFanAuto

+ +
+
+ + + + +
const uint8_t kToshibaAcFanAuto = 0b000
+
+ +
+
+ +

◆ kToshibaAcFanMax

+ +
+
+ + + + +
const uint8_t kToshibaAcFanMax = 0b101
+
+ +
+
+ +

◆ kToshibaAcFanMed

+ +
+
+ + + + +
const uint8_t kToshibaAcFanMed = 0b011
+
+ +
+
+ +

◆ kToshibaAcFanMin

+ +
+
+ + + + +
const uint8_t kToshibaAcFanMin = 0b001
+
+ +
+
+ +

◆ kToshibaAcFanOffset

+ +
+
+ + + + +
const uint8_t kToshibaAcFanOffset = 5
+
+ +
+
+ +

◆ kToshibaAcFanSize

+ +
+
+ + + + +
const uint8_t kToshibaAcFanSize = 3
+
+ +
+
+ +

◆ kToshibaAcHeat

+ +
+
+ + + + +
const uint8_t kToshibaAcHeat = 3
+
+ +
+
+ +

◆ kToshibaAcMaxTemp

+ +
+
+ + + + +
const uint8_t kToshibaAcMaxTemp = 30
+
+ +
+
+ +

◆ kToshibaAcMinTemp

+ +
+
+ + + + +
const uint8_t kToshibaAcMinTemp = 17
+
+ +
+
+ +

◆ kToshibaAcModeOffset

+ +
+
+ + + + +
const uint8_t kToshibaAcModeOffset = 0
+
+ +
+
+ +

◆ kToshibaAcModeSize

+ +
+
+ + + + +
const uint8_t kToshibaAcModeSize = 2
+
+ +
+
+ +

◆ kToshibaAcPowerOffset

+ +
+
+ + + + +
const uint8_t kToshibaAcPowerOffset = 2
+
+ +
+
+ +

◆ kToshibaAcTempOffset

+ +
+
+ + + + +
const uint8_t kToshibaAcTempOffset = 4
+
+ +
+
+ +

◆ kToshibaAcTempSize

+ +
+
+ + + + +
const uint8_t kToshibaAcTempSize = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h_source.html new file mode 100644 index 000000000..5eac89ce6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h_source.html @@ -0,0 +1,238 @@ + + + + + + + +IRremoteESP8266: src/ir_Toshiba.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Toshiba.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 David Conran
+
2 
+
7 
+
8 // Supports:
+
9 // Brand: Toshiba, Model: RAS-B13N3KV2
+
10 // Brand: Toshiba, Model: Akita EVO II
+
11 // Brand: Toshiba, Model: RAS-B13N3KVP-E
+
12 // Brand: Toshiba, Model: RAS 18SKP-ES
+
13 // Brand: Toshiba, Model: WH-TA04NE
+
14 // Brand: Toshiba, Model: WC-L03SE
+
15 
+
16 #ifndef IR_TOSHIBA_H_
+
17 #define IR_TOSHIBA_H_
+
18 
+
19 #define __STDC_LIMIT_MACROS
+
20 #include <stdint.h>
+
21 #ifdef ARDUINO
+
22 #include <Arduino.h>
+
23 #endif
+
24 #include "IRremoteESP8266.h"
+
25 #include "IRsend.h"
+
26 #ifdef UNIT_TEST
+
27 #include "IRsend_test.h"
+
28 #endif
+
29 
+
30 // Constants
+
31 const uint8_t kToshibaAcModeOffset = 0;
+
32 const uint8_t kToshibaAcModeSize = 2; // Nr. of bits
+
33 const uint8_t kToshibaAcAuto = 0;
+
34 const uint8_t kToshibaAcCool = 1;
+
35 const uint8_t kToshibaAcDry = 2;
+
36 const uint8_t kToshibaAcHeat = 3;
+
37 const uint8_t kToshibaAcPowerOffset = 2;
+
38 const uint8_t kToshibaAcFanOffset = 5;
+
39 const uint8_t kToshibaAcFanSize = 3; // Nr. of bits
+
40 const uint8_t kToshibaAcFanAuto = 0b000;
+
41 const uint8_t kToshibaAcFanMin = 0b001;
+
42 const uint8_t kToshibaAcFanMed = 0b011;
+
43 const uint8_t kToshibaAcFanMax = 0b101;
+
44 const uint8_t kToshibaAcTempOffset = 4;
+
45 const uint8_t kToshibaAcTempSize = 4; // Nr. of bits
+
46 const uint8_t kToshibaAcMinTemp = 17; // 17C
+
47 const uint8_t kToshibaAcMaxTemp = 30; // 30C
+
48 
+
49 // Legacy defines. (Deperecated)
+
50 #define TOSHIBA_AC_AUTO kToshibaAcAuto
+
51 #define TOSHIBA_AC_COOL kToshibaAcCool
+
52 #define TOSHIBA_AC_DRY kToshibaAcDry
+
53 #define TOSHIBA_AC_HEAT kToshibaAcHeat
+
54 #define TOSHIBA_AC_POWER kToshibaAcPower
+
55 #define TOSHIBA_AC_FAN_AUTO kToshibaAcFanAuto
+
56 #define TOSHIBA_AC_FAN_MAX kToshibaAcFanMax
+
57 #define TOSHIBA_AC_MIN_TEMP kToshibaAcMinTemp
+
58 #define TOSHIBA_AC_MAX_TEMP kToshibaAcMaxTemp
+
59 
+
60 // Classes
+
62 class IRToshibaAC {
+
63  public:
+
64  explicit IRToshibaAC(const uint16_t pin, const bool inverted = false,
+
65  const bool use_modulation = true);
+
66  void stateReset(void);
+
67 #if SEND_TOSHIBA_AC
+
68  void send(const uint16_t repeat = kToshibaACMinRepeat);
+
73  int8_t calibrate(void) { return _irsend.calibrate(); }
+
74 #endif // SEND_TOSHIBA_AC
+
75  void begin(void);
+
76  void on(void);
+
77  void off(void);
+
78  void setPower(const bool on);
+
79  bool getPower(void);
+
80  void setTemp(const uint8_t degrees);
+
81  uint8_t getTemp(void);
+
82  void setFan(const uint8_t speed);
+
83  uint8_t getFan(void);
+
84  void setMode(const uint8_t mode);
+
85  uint8_t getMode(const bool useRaw = false);
+
86  void setRaw(const uint8_t newState[]);
+
87  uint8_t* getRaw(void);
+
88  static bool validChecksum(const uint8_t state[],
+
89  const uint16_t length = kToshibaACStateLength);
+
90  uint8_t convertMode(const stdAc::opmode_t mode);
+
91  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
92  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
93  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ +
95  String toString(void);
+
96 #ifndef UNIT_TEST
+
97 
+
98  private:
+ +
100 #else // UNIT_TEST
+
101  IRsendTest _irsend;
+
103 #endif // UNIT_TEST
+ +
106  void checksum(const uint16_t length = kToshibaACStateLength);
+
107  static uint8_t calcChecksum(const uint8_t state[],
+
108  const uint16_t length = kToshibaACStateLength);
+
109  uint8_t mode_state;
+
110 };
+
111 
+
112 #endif // IR_TOSHIBA_H_
+
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Toshiba.cpp:134
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Toshiba.cpp:249
+
Class for handling detailed Toshiba A/C messages.
Definition: ir_Toshiba.h:62
+
const uint8_t kToshibaAcCool
Definition: ir_Toshiba.h:34
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kToshibaACStateLength)
Calculate the checksum for a given state.
Definition: ir_Toshiba.cpp:101
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Toshiba.cpp:131
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Toshiba.cpp:222
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kToshibaAcFanAuto
Definition: ir_Toshiba.h:40
+
void send(const uint16_t repeat=kToshibaACMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Toshiba.cpp:78
+
const uint8_t kToshibaAcModeOffset
Definition: ir_Toshiba.h:31
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Toshiba.cpp:172
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Toshiba.cpp:274
+
const uint8_t kToshibaAcMinTemp
Definition: ir_Toshiba.h:46
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Toshiba.h:99
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Toshiba.h:73
+ +
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Toshiba.cpp:85
+
void checksum(const uint16_t length=kToshibaACStateLength)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Toshiba.cpp:124
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Toshiba.cpp:150
+
const uint8_t kToshibaAcPowerOffset
Definition: ir_Toshiba.h:37
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Toshiba.cpp:300
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Toshiba.cpp:138
+
std::string String
Definition: IRremoteESP8266.h:1093
+
IRToshibaAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Toshiba.cpp:59
+
const uint8_t kToshibaAcFanMed
Definition: ir_Toshiba.h:42
+ +
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Toshiba.cpp:73
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Toshiba.cpp:65
+
const uint8_t kToshibaAcTempSize
Definition: ir_Toshiba.h:45
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Toshiba.cpp:165
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Toshiba.cpp:261
+
const uint8_t kToshibaAcHeat
Definition: ir_Toshiba.h:36
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Toshiba.cpp:203
+
const uint8_t kToshibaAcModeSize
Definition: ir_Toshiba.h:32
+
void setRaw(const uint8_t newState[])
Set the internal state from a valid code for this protocol.
Definition: ir_Toshiba.cpp:92
+
const uint16_t kToshibaACMinRepeat
Definition: IRremoteESP8266.h:1001
+
uint8_t getMode(const bool useRaw=false)
Get the operating mode setting of the A/C.
Definition: ir_Toshiba.cpp:193
+
const uint16_t kToshibaACStateLength
Definition: IRremoteESP8266.h:999
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kToshibaACStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Toshiba.cpp:116
+
const uint8_t kToshibaAcFanSize
Definition: ir_Toshiba.h:39
+
const uint8_t kToshibaAcFanOffset
Definition: ir_Toshiba.h:38
+
uint8_t remote_state[kToshibaACStateLength]
The state in IR code form.
Definition: ir_Toshiba.h:105
+
const uint8_t kToshibaAcDry
Definition: ir_Toshiba.h:35
+
uint8_t mode_state
Definition: ir_Toshiba.h:109
+
const uint8_t kToshibaAcAuto
Definition: ir_Toshiba.h:33
+
const uint8_t kToshibaAcMaxTemp
Definition: ir_Toshiba.h:47
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Toshiba.cpp:235
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Toshiba.cpp:156
+
const uint8_t kToshibaAcTempOffset
Definition: ir_Toshiba.h:44
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Toshiba.cpp:183
+
const uint8_t kToshibaAcFanMax
Definition: ir_Toshiba.h:43
+
const uint8_t kToshibaAcFanMin
Definition: ir_Toshiba.h:41
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8cpp.html new file mode 100644 index 000000000..3d4b6e325 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8cpp.html @@ -0,0 +1,207 @@ + + + + + + + +IRremoteESP8266: src/ir_Trotec.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Trotec.cpp File Reference
+
+
+ +

Support for Trotec protocols. +More...

+ + + + + + + + + + + + + + + + +

+Variables

const uint16_t kTrotecHdrMark = 5952
 
const uint16_t kTrotecHdrSpace = 7364
 
const uint16_t kTrotecBitMark = 592
 
const uint16_t kTrotecOneSpace = 1560
 
const uint16_t kTrotecZeroSpace = 592
 
const uint16_t kTrotecGap = 6184
 
const uint16_t kTrotecGapEnd = 1500
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kTrotecBitMark

+ +
+
+ + + + +
const uint16_t kTrotecBitMark = 592
+
+ +
+
+ +

◆ kTrotecGap

+ +
+
+ + + + +
const uint16_t kTrotecGap = 6184
+
+ +
+
+ +

◆ kTrotecGapEnd

+ +
+
+ + + + +
const uint16_t kTrotecGapEnd = 1500
+
+ +
+
+ +

◆ kTrotecHdrMark

+ +
+
+ + + + +
const uint16_t kTrotecHdrMark = 5952
+
+ +
+
+ +

◆ kTrotecHdrSpace

+ +
+
+ + + + +
const uint16_t kTrotecHdrSpace = 7364
+
+ +
+
+ +

◆ kTrotecOneSpace

+ +
+
+ + + + +
const uint16_t kTrotecOneSpace = 1560
+
+ +
+
+ +

◆ kTrotecZeroSpace

+ +
+
+ + + + +
const uint16_t kTrotecZeroSpace = 592
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h.html new file mode 100644 index 000000000..943ec1243 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h.html @@ -0,0 +1,456 @@ + + + + + + + +IRremoteESP8266: src/ir_Trotec.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Trotec.h File Reference
+
+
+ +

Support for Trotec protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRTrotecESP
 Class for handling detailed Trotec A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kTrotecIntro1 = 0x12
 
const uint8_t kTrotecIntro2 = 0x34
 
const uint8_t kTrotecModeOffset = 0
 
const uint8_t kTrotecModeSize = 2
 
const uint8_t kTrotecAuto = 0
 
const uint8_t kTrotecCool = 1
 
const uint8_t kTrotecDry = 2
 
const uint8_t kTrotecFan = 3
 
const uint8_t kTrotecPowerBitOffset = 3
 
const uint8_t kTrotecFanOffset = 4
 
const uint8_t kTrotecFanSize = 2
 
const uint8_t kTrotecFanLow = 1
 
const uint8_t kTrotecFanMed = 2
 
const uint8_t kTrotecFanHigh = 3
 
const uint8_t kTrotecTempOffset = 0
 
const uint8_t kTrotecTempSize = 4
 
const uint8_t kTrotecMinTemp = 18
 
const uint8_t kTrotecDefTemp = 25
 
const uint8_t kTrotecMaxTemp = 32
 
const uint8_t kTrotecSleepBitOffset = 7
 
const uint8_t kTrotecTimerBitOffset = 6
 
const uint8_t kTrotecMaxTimer = 23
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kTrotecAuto

+ +
+
+ + + + +
const uint8_t kTrotecAuto = 0
+
+ +
+
+ +

◆ kTrotecCool

+ +
+
+ + + + +
const uint8_t kTrotecCool = 1
+
+ +
+
+ +

◆ kTrotecDefTemp

+ +
+
+ + + + +
const uint8_t kTrotecDefTemp = 25
+
+ +
+
+ +

◆ kTrotecDry

+ +
+
+ + + + +
const uint8_t kTrotecDry = 2
+
+ +
+
+ +

◆ kTrotecFan

+ +
+
+ + + + +
const uint8_t kTrotecFan = 3
+
+ +
+
+ +

◆ kTrotecFanHigh

+ +
+
+ + + + +
const uint8_t kTrotecFanHigh = 3
+
+ +
+
+ +

◆ kTrotecFanLow

+ +
+
+ + + + +
const uint8_t kTrotecFanLow = 1
+
+ +
+
+ +

◆ kTrotecFanMed

+ +
+
+ + + + +
const uint8_t kTrotecFanMed = 2
+
+ +
+
+ +

◆ kTrotecFanOffset

+ +
+
+ + + + +
const uint8_t kTrotecFanOffset = 4
+
+ +
+
+ +

◆ kTrotecFanSize

+ +
+
+ + + + +
const uint8_t kTrotecFanSize = 2
+
+ +
+
+ +

◆ kTrotecIntro1

+ +
+
+ + + + +
const uint8_t kTrotecIntro1 = 0x12
+
+ +
+
+ +

◆ kTrotecIntro2

+ +
+
+ + + + +
const uint8_t kTrotecIntro2 = 0x34
+
+ +
+
+ +

◆ kTrotecMaxTemp

+ +
+
+ + + + +
const uint8_t kTrotecMaxTemp = 32
+
+ +
+
+ +

◆ kTrotecMaxTimer

+ +
+
+ + + + +
const uint8_t kTrotecMaxTimer = 23
+
+ +
+
+ +

◆ kTrotecMinTemp

+ +
+
+ + + + +
const uint8_t kTrotecMinTemp = 18
+
+ +
+
+ +

◆ kTrotecModeOffset

+ +
+
+ + + + +
const uint8_t kTrotecModeOffset = 0
+
+ +
+
+ +

◆ kTrotecModeSize

+ +
+
+ + + + +
const uint8_t kTrotecModeSize = 2
+
+ +
+
+ +

◆ kTrotecPowerBitOffset

+ +
+
+ + + + +
const uint8_t kTrotecPowerBitOffset = 3
+
+ +
+
+ +

◆ kTrotecSleepBitOffset

+ +
+
+ + + + +
const uint8_t kTrotecSleepBitOffset = 7
+
+ +
+
+ +

◆ kTrotecTempOffset

+ +
+
+ + + + +
const uint8_t kTrotecTempOffset = 0
+
+ +
+
+ +

◆ kTrotecTempSize

+ +
+
+ + + + +
const uint8_t kTrotecTempSize = 4
+
+ +
+
+ +

◆ kTrotecTimerBitOffset

+ +
+
+ + + + +
const uint8_t kTrotecTimerBitOffset = 6
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h_source.html new file mode 100644 index 000000000..950f39edc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h_source.html @@ -0,0 +1,270 @@ + + + + + + + +IRremoteESP8266: src/ir_Trotec.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Trotec.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 stufisher
+
2 // Copyright 2019 crankyoldgit
+
3 
+
8 
+
9 // Supports:
+
10 // Brand: Trotec, Model: PAC 3200 A/C
+
11 // Brand: Duux, Model: Blizzard Smart 10K / DXMA04 A/C
+
12 
+
13 #ifndef IR_TROTEC_H_
+
14 #define IR_TROTEC_H_
+
15 
+
16 #ifndef UNIT_TEST
+
17 #include <Arduino.h>
+
18 #endif
+
19 #include "IRremoteESP8266.h"
+
20 #include "IRsend.h"
+
21 #ifdef UNIT_TEST
+
22 #include "IRsend_test.h"
+
23 #endif
+
24 
+
25 // Constants
+
26 // Byte 0
+
27 const uint8_t kTrotecIntro1 = 0x12;
+
28 
+
29 // Byte 1
+
30 const uint8_t kTrotecIntro2 = 0x34;
+
31 
+
32 // Byte 2
+
33 const uint8_t kTrotecModeOffset = 0;
+
34 const uint8_t kTrotecModeSize = 2; // Nr. of bits
+
35 const uint8_t kTrotecAuto = 0;
+
36 const uint8_t kTrotecCool = 1;
+
37 const uint8_t kTrotecDry = 2;
+
38 const uint8_t kTrotecFan = 3;
+
39 
+
40 const uint8_t kTrotecPowerBitOffset = 3;
+
41 
+
42 const uint8_t kTrotecFanOffset = 4;
+
43 const uint8_t kTrotecFanSize = 2; // Nr. of bits
+
44 const uint8_t kTrotecFanLow = 1;
+
45 const uint8_t kTrotecFanMed = 2;
+
46 const uint8_t kTrotecFanHigh = 3;
+
47 
+
48 // Byte 3
+
49 const uint8_t kTrotecTempOffset = 0;
+
50 const uint8_t kTrotecTempSize = 4; // Nr. of bits
+
51 const uint8_t kTrotecMinTemp = 18;
+
52 const uint8_t kTrotecDefTemp = 25;
+
53 const uint8_t kTrotecMaxTemp = 32;
+
54 const uint8_t kTrotecSleepBitOffset = 7;
+
55 
+
56 // Byte 5
+
57 const uint8_t kTrotecTimerBitOffset = 6;
+
58 
+
59 // Byte 6
+
60 const uint8_t kTrotecMaxTimer = 23;
+
61 
+
62 // Legacy defines. (Deperecated)
+
63 #define TROTEC_AUTO kTrotecAuto
+
64 #define TROTEC_COOL kTrotecCool
+
65 #define TROTEC_DRY kTrotecDry
+
66 #define TROTEC_FAN kTrotecFan
+
67 #define TROTEC_FAN_LOW kTrotecFanLow
+
68 #define TROTEC_FAN_MED kTrotecFanMed
+
69 #define TROTEC_FAN_HIGH kTrotecFanHigh
+
70 #define TROTEC_MIN_TEMP kTrotecMinTemp
+
71 #define TROTEC_MAX_TEMP kTrotecMaxTemp
+
72 #define TROTEC_MAX_TIMER kTrotecMaxTimer
+
73 
+
74 // Class
+
76 class IRTrotecESP {
+
77  public:
+
78  explicit IRTrotecESP(const uint16_t pin, const bool inverted = false,
+
79  const bool use_modulation = true);
+
80 #if SEND_TROTEC
+
81  void send(const uint16_t repeat = kTrotecDefaultRepeat);
+
86  int8_t calibrate(void) { return _irsend.calibrate(); }
+
87 #endif // SEND_TROTEC
+
88  void begin(void);
+
89  void stateReset(void);
+
90 
+
91  void on(void);
+
92  void off(void);
+
93  void setPower(const bool state);
+
94  bool getPower(void);
+
95 
+
96  void setTemp(const uint8_t celsius);
+
97  uint8_t getTemp(void);
+
98 
+
99  void setSpeed(const uint8_t fan);
+
100  uint8_t getSpeed(void);
+
101 
+
102  uint8_t getMode(void);
+
103  void setMode(const uint8_t mode);
+
104 
+
105  bool getSleep(void);
+
106  void setSleep(const bool on);
+
107 
+
108  uint8_t getTimer(void);
+
109  void setTimer(const uint8_t timer);
+
110 
+
111  uint8_t* getRaw(void);
+
112  void setRaw(const uint8_t state[]);
+
113  static bool validChecksum(const uint8_t state[],
+
114  const uint16_t length = kTrotecStateLength);
+
115  uint8_t convertMode(const stdAc::opmode_t mode);
+
116  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
117  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
118  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
119  stdAc::state_t toCommon(void);
+
120  String toString(void);
+
121 #ifndef UNIT_TEST
+
122 
+
123  private:
+ +
125 #else // UNIT_TEST
+
126  IRsendTest _irsend;
+
128 #endif // UNIT_TEST
+ +
131  static uint8_t calcChecksum(const uint8_t state[],
+
132  const uint16_t length = kTrotecStateLength);
+
133  void checksum(void);
+
134 };
+
135 
+
136 #endif // IR_TROTEC_H_
+
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Trotec.cpp:184
+
const uint8_t kTrotecFanOffset
Definition: ir_Trotec.h:42
+
void checksum(void)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Trotec.cpp:98
+
const uint8_t kTrotecTimerBitOffset
Definition: ir_Trotec.h:57
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Trotec.cpp:197
+
const uint16_t kTrotecDefaultRepeat
Definition: IRremoteESP8266.h:1004
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Trotec.cpp:169
+
const uint8_t kTrotecSleepBitOffset
Definition: ir_Trotec.h:54
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Trotec.cpp:291
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Trotec.cpp:70
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Trotec.cpp:143
+
const uint8_t kTrotecFanMed
Definition: ir_Trotec.h:45
+ +
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Trotec.cpp:118
+
const uint8_t kTrotecIntro2
Definition: ir_Trotec.h:30
+
const uint8_t kTrotecFanHigh
Definition: ir_Trotec.h:46
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
std::string String
Definition: IRremoteESP8266.h:1093
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kTrotecStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Trotec.cpp:93
+
const uint8_t kTrotecMinTemp
Definition: ir_Trotec.h:51
+
const uint8_t kTrotecDefTemp
Definition: ir_Trotec.h:52
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Trotec.cpp:130
+
const uint8_t kTrotecMaxTimer
Definition: ir_Trotec.h:60
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Trotec.cpp:265
+ +
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Trotec.cpp:215
+
const uint8_t kTrotecDry
Definition: ir_Trotec.h:37
+
const uint8_t kTrotecTempOffset
Definition: ir_Trotec.h:49
+
uint8_t getTimer(void)
Get the timer time in nr. of Hours.
Definition: ir_Trotec.cpp:210
+
void setTemp(const uint8_t celsius)
Set the temperature.
Definition: ir_Trotec.cpp:175
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Trotec.cpp:162
+
const uint16_t kTrotecStateLength
Definition: IRremoteESP8266.h:1002
+
const uint8_t kTrotecMaxTemp
Definition: ir_Trotec.h:53
+
const uint8_t kTrotecFanLow
Definition: ir_Trotec.h:44
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Trotec.cpp:104
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Trotec.h:86
+
void setTimer(const uint8_t timer)
Set the timer time in nr. of Hours.
Definition: ir_Trotec.cpp:203
+
void setPower(const bool state)
Change the power setting.
Definition: ir_Trotec.cpp:137
+
const uint8_t kTrotecFan
Definition: ir_Trotec.h:38
+
const uint8_t kTrotecModeSize
Definition: ir_Trotec.h:34
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Trotec.cpp:242
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Trotec.h:124
+
const uint8_t kTrotecCool
Definition: ir_Trotec.h:36
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Trotec.cpp:191
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Trotec.cpp:133
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kTrotecStateLength)
Calculate the checksum for a given state.
Definition: ir_Trotec.cpp:84
+
void send(const uint16_t repeat=kTrotecDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Trotec.cpp:75
+
uint8_t remote_state[kTrotecStateLength]
Remote state in IR code form.
Definition: ir_Trotec.h:130
+
const uint8_t kTrotecModeOffset
Definition: ir_Trotec.h:33
+
const uint8_t kTrotecAuto
Definition: ir_Trotec.h:35
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Trotec.cpp:254
+
Class for handling detailed Trotec A/C messages.
Definition: ir_Trotec.h:76
+
const uint8_t kTrotecFanSize
Definition: ir_Trotec.h:43
+
uint8_t getSpeed(void)
Get the current fan speed setting.
Definition: ir_Trotec.cpp:156
+
IRTrotecESP(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Trotec.cpp:65
+
const uint8_t kTrotecTempSize
Definition: ir_Trotec.h:50
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Trotec.cpp:228
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kTrotecIntro1
Definition: ir_Trotec.h:27
+
void setRaw(const uint8_t state[])
Set the internal state from a valid code for this protocol.
Definition: ir_Trotec.cpp:125
+
void setSpeed(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Trotec.cpp:149
+
const uint8_t kTrotecPowerBitOffset
Definition: ir_Trotec.h:40
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8cpp.html new file mode 100644 index 000000000..36b147b25 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8cpp.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: src/ir_Vestel.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Vestel.cpp File Reference
+
+
+ +

Support for Vestel protocols. Vestel added by Erdem U. Altinyurt. +More...

+

Detailed Description

+

Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h.html new file mode 100644 index 000000000..ff591a74e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h.html @@ -0,0 +1,905 @@ + + + + + + + +IRremoteESP8266: src/ir_Vestel.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Vestel.h File Reference
+
+
+ +

Support for Vestel protocols. Vestel added by Erdem U. Altinyurt. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRVestelAc
 Class for handling detailed Vestel A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kVestelAcHdrMark = 3110
 
const uint16_t kVestelAcHdrSpace = 9066
 
const uint16_t kVestelAcBitMark = 520
 
const uint16_t kVestelAcOneSpace = 1535
 
const uint16_t kVestelAcZeroSpace = 480
 
const uint16_t kVestelAcTolerance = 30
 
const uint8_t kVestelAcMinTempH = 16
 
const uint8_t kVestelAcMinTempC = 18
 
const uint8_t kVestelAcMaxTemp = 30
 
const uint8_t kVestelAcAuto = 0
 
const uint8_t kVestelAcCool = 1
 
const uint8_t kVestelAcDry = 2
 
const uint8_t kVestelAcFan = 3
 
const uint8_t kVestelAcHeat = 4
 
const uint8_t kVestelAcFanAuto = 1
 
const uint8_t kVestelAcFanLow = 5
 
const uint8_t kVestelAcFanMed = 9
 
const uint8_t kVestelAcFanHigh = 0xB
 
const uint8_t kVestelAcFanAutoCool = 0xC
 
const uint8_t kVestelAcFanAutoHot = 0xD
 
const uint8_t kVestelAcNormal = 1
 
const uint8_t kVestelAcSleep = 3
 
const uint8_t kVestelAcTurbo = 7
 
const uint8_t kVestelAcIon = 4
 
const uint8_t kVestelAcSwing = 0xA
 
const uint8_t kVestelAcChecksumOffset = 12
 
const uint8_t kVestelAcChecksumSize = 8
 
const uint8_t kVestelAcSwingOffset = 20
 
const uint8_t kVestelAcTurboSleepOffset = 24
 
const uint8_t kVestelAcTempOffset = 36
 
const uint8_t kVestelAcFanOffset = 40
 
const uint8_t kVestelAcFanSize = 4
 
const uint8_t kVestelAcModeOffset = 44
 
const uint8_t kVestelAcIonOffset = 50
 
const uint8_t kVestelAcPowerOffset = 52
 
const uint8_t kVestelAcPowerSize = 2
 
const uint8_t kVestelAcOffTimeOffset = 20
 
const uint8_t kVestelAcOnTimeOffset = 28
 
const uint8_t kVestelAcTimerHourSize = 5
 
const uint8_t kVestelAcTimerMinsSize = 3
 
const uint8_t kVestelAcTimerSize
 
const uint8_t kVestelAcHourOffset = 36
 
const uint8_t kVestelAcHourSize = 5
 
const uint8_t kVestelAcOnTimerFlagOffset = kVestelAcHourOffset + 5
 
const uint8_t kVestelAcOffTimerFlagOffset = kVestelAcHourOffset + 6
 
const uint8_t kVestelAcTimerFlagOffset = kVestelAcHourOffset + 7
 
const uint8_t kVestelAcMinuteOffset = 44
 
const uint8_t kVestelAcMinuteSize = 8
 
const uint64_t kVestelAcStateDefault = 0x0F00D9001FEF201ULL
 
const uint64_t kVestelAcTimeStateDefault = 0x201ULL
 
+

Detailed Description

+

Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.

+

Variable Documentation

+ +

◆ kVestelAcAuto

+ +
+
+ + + + +
const uint8_t kVestelAcAuto = 0
+
+ +
+
+ +

◆ kVestelAcBitMark

+ +
+
+ + + + +
const uint16_t kVestelAcBitMark = 520
+
+ +
+
+ +

◆ kVestelAcChecksumOffset

+ +
+
+ + + + +
const uint8_t kVestelAcChecksumOffset = 12
+
+ +
+
+ +

◆ kVestelAcChecksumSize

+ +
+
+ + + + +
const uint8_t kVestelAcChecksumSize = 8
+
+ +
+
+ +

◆ kVestelAcCool

+ +
+
+ + + + +
const uint8_t kVestelAcCool = 1
+
+ +
+
+ +

◆ kVestelAcDry

+ +
+
+ + + + +
const uint8_t kVestelAcDry = 2
+
+ +
+
+ +

◆ kVestelAcFan

+ +
+
+ + + + +
const uint8_t kVestelAcFan = 3
+
+ +
+
+ +

◆ kVestelAcFanAuto

+ +
+
+ + + + +
const uint8_t kVestelAcFanAuto = 1
+
+ +
+
+ +

◆ kVestelAcFanAutoCool

+ +
+
+ + + + +
const uint8_t kVestelAcFanAutoCool = 0xC
+
+ +
+
+ +

◆ kVestelAcFanAutoHot

+ +
+
+ + + + +
const uint8_t kVestelAcFanAutoHot = 0xD
+
+ +
+
+ +

◆ kVestelAcFanHigh

+ +
+
+ + + + +
const uint8_t kVestelAcFanHigh = 0xB
+
+ +
+
+ +

◆ kVestelAcFanLow

+ +
+
+ + + + +
const uint8_t kVestelAcFanLow = 5
+
+ +
+
+ +

◆ kVestelAcFanMed

+ +
+
+ + + + +
const uint8_t kVestelAcFanMed = 9
+
+ +
+
+ +

◆ kVestelAcFanOffset

+ +
+
+ + + + +
const uint8_t kVestelAcFanOffset = 40
+
+ +
+
+ +

◆ kVestelAcFanSize

+ +
+
+ + + + +
const uint8_t kVestelAcFanSize = 4
+
+ +
+
+ +

◆ kVestelAcHdrMark

+ +
+
+ + + + +
const uint16_t kVestelAcHdrMark = 3110
+
+ +
+
+ +

◆ kVestelAcHdrSpace

+ +
+
+ + + + +
const uint16_t kVestelAcHdrSpace = 9066
+
+ +
+
+ +

◆ kVestelAcHeat

+ +
+
+ + + + +
const uint8_t kVestelAcHeat = 4
+
+ +
+
+ +

◆ kVestelAcHourOffset

+ +
+
+ + + + +
const uint8_t kVestelAcHourOffset = 36
+
+ +
+
+ +

◆ kVestelAcHourSize

+ +
+
+ + + + +
const uint8_t kVestelAcHourSize = 5
+
+ +
+
+ +

◆ kVestelAcIon

+ +
+
+ + + + +
const uint8_t kVestelAcIon = 4
+
+ +
+
+ +

◆ kVestelAcIonOffset

+ +
+
+ + + + +
const uint8_t kVestelAcIonOffset = 50
+
+ +
+
+ +

◆ kVestelAcMaxTemp

+ +
+
+ + + + +
const uint8_t kVestelAcMaxTemp = 30
+
+ +
+
+ +

◆ kVestelAcMinTempC

+ +
+
+ + + + +
const uint8_t kVestelAcMinTempC = 18
+
+ +
+
+ +

◆ kVestelAcMinTempH

+ +
+
+ + + + +
const uint8_t kVestelAcMinTempH = 16
+
+ +
+
+ +

◆ kVestelAcMinuteOffset

+ +
+
+ + + + +
const uint8_t kVestelAcMinuteOffset = 44
+
+ +
+
+ +

◆ kVestelAcMinuteSize

+ +
+
+ + + + +
const uint8_t kVestelAcMinuteSize = 8
+
+ +
+
+ +

◆ kVestelAcModeOffset

+ +
+
+ + + + +
const uint8_t kVestelAcModeOffset = 44
+
+ +
+
+ +

◆ kVestelAcNormal

+ +
+
+ + + + +
const uint8_t kVestelAcNormal = 1
+
+ +
+
+ +

◆ kVestelAcOffTimeOffset

+ +
+
+ + + + +
const uint8_t kVestelAcOffTimeOffset = 20
+
+ +
+
+ +

◆ kVestelAcOffTimerFlagOffset

+ +
+
+ + + + +
const uint8_t kVestelAcOffTimerFlagOffset = kVestelAcHourOffset + 6
+
+ +
+
+ +

◆ kVestelAcOneSpace

+ +
+
+ + + + +
const uint16_t kVestelAcOneSpace = 1535
+
+ +
+
+ +

◆ kVestelAcOnTimeOffset

+ +
+
+ + + + +
const uint8_t kVestelAcOnTimeOffset = 28
+
+ +
+
+ +

◆ kVestelAcOnTimerFlagOffset

+ +
+
+ + + + +
const uint8_t kVestelAcOnTimerFlagOffset = kVestelAcHourOffset + 5
+
+ +
+
+ +

◆ kVestelAcPowerOffset

+ +
+
+ + + + +
const uint8_t kVestelAcPowerOffset = 52
+
+ +
+
+ +

◆ kVestelAcPowerSize

+ +
+
+ + + + +
const uint8_t kVestelAcPowerSize = 2
+
+ +
+
+ +

◆ kVestelAcSleep

+ +
+
+ + + + +
const uint8_t kVestelAcSleep = 3
+
+ +
+
+ +

◆ kVestelAcStateDefault

+ +
+
+ + + + +
const uint64_t kVestelAcStateDefault = 0x0F00D9001FEF201ULL
+
+ +
+
+ +

◆ kVestelAcSwing

+ +
+
+ + + + +
const uint8_t kVestelAcSwing = 0xA
+
+ +
+
+ +

◆ kVestelAcSwingOffset

+ +
+
+ + + + +
const uint8_t kVestelAcSwingOffset = 20
+
+ +
+
+ +

◆ kVestelAcTempOffset

+ +
+
+ + + + +
const uint8_t kVestelAcTempOffset = 36
+
+ +
+
+ +

◆ kVestelAcTimerFlagOffset

+ +
+
+ + + + +
const uint8_t kVestelAcTimerFlagOffset = kVestelAcHourOffset + 7
+
+ +
+
+ +

◆ kVestelAcTimerHourSize

+ +
+
+ + + + +
const uint8_t kVestelAcTimerHourSize = 5
+
+ +
+
+ +

◆ kVestelAcTimerMinsSize

+ +
+
+ + + + +
const uint8_t kVestelAcTimerMinsSize = 3
+
+ +
+
+ +

◆ kVestelAcTimerSize

+ +
+
+ + + + +
const uint8_t kVestelAcTimerSize
+
+
+ +

◆ kVestelAcTimeStateDefault

+ +
+
+ + + + +
const uint64_t kVestelAcTimeStateDefault = 0x201ULL
+
+ +
+
+ +

◆ kVestelAcTolerance

+ +
+
+ + + + +
const uint16_t kVestelAcTolerance = 30
+
+ +
+
+ +

◆ kVestelAcTurbo

+ +
+
+ + + + +
const uint8_t kVestelAcTurbo = 7
+
+ +
+
+ +

◆ kVestelAcTurboSleepOffset

+ +
+
+ + + + +
const uint8_t kVestelAcTurboSleepOffset = 24
+
+ +
+
+ +

◆ kVestelAcZeroSpace

+ +
+
+ + + + +
const uint16_t kVestelAcZeroSpace = 480
+
+ +
+
+
+
const uint8_t kVestelAcTimerHourSize
Definition: ir_Vestel.h:99
+
const uint8_t kVestelAcTimerMinsSize
Definition: ir_Vestel.h:100
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h_source.html new file mode 100644 index 000000000..e737cba4c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h_source.html @@ -0,0 +1,378 @@ + + + + + + + +IRremoteESP8266: src/ir_Vestel.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Vestel.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 Erdem U. Altinyurt
+
2 // Copyright 2019 David Conran
+
3 
+
7 
+
8 // Supports:
+
9 // Brand: Vestel, Model: BIOX CXP-9 A/C (9K BTU)
+
10 
+
11 #ifndef IR_VESTEL_H_
+
12 #define IR_VESTEL_H_
+
13 
+
14 #define __STDC_LIMIT_MACROS
+
15 #include <stdint.h>
+
16 #ifdef ARDUINO
+
17 #include <Arduino.h>
+
18 #endif
+
19 #include "IRremoteESP8266.h"
+
20 #include "IRsend.h"
+
21 #ifdef UNIT_TEST
+
22 #include "IRsend_test.h"
+
23 #endif
+
24 
+
25 
+
26 // Structure of a Command message (56 bits)
+
27 // Signature: 12 bits. e.g. 0x201
+
28 // Checksum: 8 bits
+
29 // Swing: 4 bits. (auto 0xA, stop 0xF)
+
30 // turbo_sleep_normal: 4bits. (normal 0x1, sleep 0x3, turbo 0x7)
+
31 // Unused: 8 bits. (0x00)
+
32 // Temperature: 4 bits. (Celsius, but offset by -16 degrees. e.g. 0x0 = 16C)
+
33 // Fan Speed: 4 bits (auto 0x1, low 0x5, mid 0x9, high 0xB, 0xD auto hot,
+
34 // 0xC auto cool)
+
35 // Mode: 3 bits. (auto 0x0, cold 0x1, dry 0x2, fan 0x3, hot 0x4)
+
36 // unknown/unused: 6 bits.
+
37 // Ion flag: 1 bit.
+
38 // unknown/unused: 1 bit.
+
39 // Power/message type: 4 bits. (on 0xF, off 0xC, 0x0 == Timer mesage)
+
40 //
+
41 // Structure of a Time(r) message (56 bits)
+
42 // Signature: 12 bits. e.g. 0x201
+
43 // Checksum: 8 bits
+
44 // Off Minutes: 3 bits. (Stored in 10 min increments. eg. xx:20 is 0x2)
+
45 // Off Hours: 5 bits. (0x17 == 11PM / 23:00)
+
46 // On Minutes: 3 bits. (Stored in 10 min increments. eg. xx:20 is 0x2)
+
47 // On Hours: 5 bits. (0x9 == 9AM / 09:00)
+
48 // Clock Hours: 5 bits.
+
49 // On Timer flag: 1 bit.
+
50 // Off Timer flag: 1 bit.
+
51 // Timer mode flag: 1 bit. (Off after X many hours/mins, not at clock time.)
+
52 // Clock Minutes: 8 bits. (0-59)
+
53 // Power/message type: 4 bits. (0x0 == Timer mesage, else see Comman message)
+
54 
+
55 // Constants
+
56 const uint16_t kVestelAcHdrMark = 3110;
+
57 const uint16_t kVestelAcHdrSpace = 9066;
+
58 const uint16_t kVestelAcBitMark = 520;
+
59 const uint16_t kVestelAcOneSpace = 1535;
+
60 const uint16_t kVestelAcZeroSpace = 480;
+
61 const uint16_t kVestelAcTolerance = 30;
+
62 
+
63 const uint8_t kVestelAcMinTempH = 16;
+
64 const uint8_t kVestelAcMinTempC = 18;
+
65 const uint8_t kVestelAcMaxTemp = 30;
+
66 
+
67 const uint8_t kVestelAcAuto = 0;
+
68 const uint8_t kVestelAcCool = 1;
+
69 const uint8_t kVestelAcDry = 2;
+
70 const uint8_t kVestelAcFan = 3;
+
71 const uint8_t kVestelAcHeat = 4;
+
72 
+
73 const uint8_t kVestelAcFanAuto = 1;
+
74 const uint8_t kVestelAcFanLow = 5;
+
75 const uint8_t kVestelAcFanMed = 9;
+
76 const uint8_t kVestelAcFanHigh = 0xB;
+
77 const uint8_t kVestelAcFanAutoCool = 0xC;
+
78 const uint8_t kVestelAcFanAutoHot = 0xD;
+
79 
+
80 const uint8_t kVestelAcNormal = 1;
+
81 const uint8_t kVestelAcSleep = 3;
+
82 const uint8_t kVestelAcTurbo = 7;
+
83 const uint8_t kVestelAcIon = 4;
+
84 const uint8_t kVestelAcSwing = 0xA;
+
85 
+
86 const uint8_t kVestelAcChecksumOffset = 12;
+
87 const uint8_t kVestelAcChecksumSize = 8; // Nr. of bits
+
88 const uint8_t kVestelAcSwingOffset = 20;
+
89 const uint8_t kVestelAcTurboSleepOffset = 24;
+
90 const uint8_t kVestelAcTempOffset = 36;
+
91 const uint8_t kVestelAcFanOffset = 40;
+
92 const uint8_t kVestelAcFanSize = 4; // Nr. of bits
+
93 const uint8_t kVestelAcModeOffset = 44;
+
94 const uint8_t kVestelAcIonOffset = 50;
+
95 const uint8_t kVestelAcPowerOffset = 52;
+
96 const uint8_t kVestelAcPowerSize = 2; // Nr. of bits
+
97 const uint8_t kVestelAcOffTimeOffset = 20;
+
98 const uint8_t kVestelAcOnTimeOffset = 28;
+
99 const uint8_t kVestelAcTimerHourSize = 5; // Nr. of bits
+
100 const uint8_t kVestelAcTimerMinsSize = 3; // Nr. of bits
+ +
102  kVestelAcTimerMinsSize; // Nr. of bits
+
103 const uint8_t kVestelAcHourOffset = 36; // 5 bits
+
104 const uint8_t kVestelAcHourSize = 5; // Nr. of bits
+ + + +
108 const uint8_t kVestelAcMinuteOffset = 44;
+
109 const uint8_t kVestelAcMinuteSize = 8; // Nr. of bits
+
110 // Default states
+
111 const uint64_t kVestelAcStateDefault = 0x0F00D9001FEF201ULL;
+
112 const uint64_t kVestelAcTimeStateDefault = 0x201ULL;
+
113 
+
114 // Classes
+
116 class IRVestelAc {
+
117  public:
+
118  explicit IRVestelAc(const uint16_t pin, const bool inverted = false,
+
119  const bool use_modulation = true);
+
120  void stateReset(void);
+
121 #if SEND_VESTEL_AC
+
122  void send(const uint16_t repeat = kNoRepeat);
+
127  int8_t calibrate(void) { return _irsend.calibrate(); }
+
128 #endif // SEND_VESTEL_AC
+
129  void begin(void);
+
130  void on(void);
+
131  void off(void);
+
132  void setPower(const bool on);
+
133  bool getPower(void);
+
134  void setAuto(const int8_t autoLevel);
+
135  void setTimer(const uint16_t minutes);
+
136  uint16_t getTimer(void);
+
137  void setTime(const uint16_t minutes);
+
138  uint16_t getTime(void);
+
139  void setOnTimer(const uint16_t minutes);
+
140  uint16_t getOnTimer(void);
+
141  void setOffTimer(const uint16_t minutes);
+
142  uint16_t getOffTimer(void);
+
143  void setTemp(const uint8_t temp);
+
144  uint8_t getTemp(void);
+
145  void setFan(const uint8_t fan);
+
146  uint8_t getFan(void);
+
147  void setMode(const uint8_t mode);
+
148  uint8_t getMode(void);
+
149  void setRaw(const uint8_t* newState);
+
150  void setRaw(const uint64_t newState);
+
151  uint64_t getRaw(void);
+
152  static bool validChecksum(const uint64_t state);
+
153  void setSwing(const bool on);
+
154  bool getSwing(void);
+
155  void setSleep(const bool on);
+
156  bool getSleep(void);
+
157  void setTurbo(const bool on);
+
158  bool getTurbo(void);
+
159  void setIon(const bool on);
+
160  bool getIon(void);
+
161  bool isTimeCommand(void);
+
162  bool isOnTimerActive(void);
+
163  void setOnTimerActive(const bool on);
+
164  bool isOffTimerActive(void);
+
165  void setOffTimerActive(const bool on);
+
166  bool isTimerActive(void);
+
167  void setTimerActive(const bool on);
+
168  static uint8_t calcChecksum(const uint64_t state);
+
169  static uint8_t convertMode(const stdAc::opmode_t mode);
+
170  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
171  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
172  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
173  stdAc::state_t toCommon(void);
+
174  String toString(void);
+
175 #ifndef UNIT_TEST
+
176 
+
177  private:
+ +
179 #else // UNIT_TEST
+
180  IRsendTest _irsend;
+
182 #endif // UNIT_TEST
+
184  uint64_t remote_state;
+
185  uint64_t remote_time_state;
+ +
187  void checksum(void);
+
188  void _setTimer(const uint16_t minutes, const uint8_t offset);
+
189  uint16_t _getTimer(const uint8_t offset);
+
190 };
+
191 
+
192 #endif // IR_VESTEL_H_
+
+
const uint16_t kVestelAcHdrSpace
Definition: ir_Vestel.h:57
+
const uint8_t kVestelAcOffTimeOffset
Definition: ir_Vestel.h:97
+
const uint8_t kVestelAcFanAutoHot
Definition: ir_Vestel.h:78
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Vestel.cpp:60
+
uint16_t getOffTimer(void)
Get the A/C's Off Timer time.
Definition: ir_Vestel.cpp:330
+
const uint8_t kVestelAcTimerHourSize
Definition: ir_Vestel.h:99
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Vestel.cpp:478
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Vestel.cpp:67
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Vestel.cpp:147
+
const uint8_t kVestelAcHourSize
Definition: ir_Vestel.h:104
+
const uint8_t kVestelAcFanOffset
Definition: ir_Vestel.h:91
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Vestel.cpp:130
+
void setOffTimerActive(const bool on)
Set the Off timer to be active on the A/C.
Definition: ir_Vestel.cpp:310
+
void setTime(const uint16_t minutes)
Set the A/C's internal clock.
Definition: ir_Vestel.cpp:247
+
const uint8_t kVestelAcMaxTemp
Definition: ir_Vestel.h:65
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Vestel.cpp:116
+
bool isTimeCommand(void)
Is the current state a time command?
Definition: ir_Vestel.cpp:419
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kVestelAcSleep
Definition: ir_Vestel.h:81
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Vestel.h:127
+
const uint8_t kVestelAcDry
Definition: ir_Vestel.h:69
+
const uint16_t kVestelAcBitMark
Definition: ir_Vestel.h:58
+
const uint8_t kVestelAcAuto
Definition: ir_Vestel.h:67
+
const uint8_t kVestelAcFanMed
Definition: ir_Vestel.h:75
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Vestel.cpp:351
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Vestel.h:178
+
void setTimer(const uint16_t minutes)
Set Timer option of A/C.
Definition: ir_Vestel.cpp:228
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Vestel.cpp:109
+
uint16_t _getTimer(const uint8_t offset)
Get the number of minutes a timer is set for.
Definition: ir_Vestel.cpp:289
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Vestel.cpp:178
+ +
bool isOffTimerActive(void)
Get if the Off Timer is active on the A/C.
Definition: ir_Vestel.cpp:317
+
const uint8_t kVestelAcMinuteSize
Definition: ir_Vestel.h:109
+
const uint8_t kVestelAcMinTempC
Definition: ir_Vestel.h:64
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kVestelAcChecksumSize
Definition: ir_Vestel.h:87
+
uint16_t getTimer(void)
Get the Timer time of A/C.
Definition: ir_Vestel.cpp:243
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kVestelAcFanSize
Definition: ir_Vestel.h:92
+
const uint8_t kVestelAcSwingOffset
Definition: ir_Vestel.h:88
+
bool isOnTimerActive(void)
Get if the On Timer is active on the A/C.
Definition: ir_Vestel.cpp:272
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kVestelAcTimerFlagOffset
Definition: ir_Vestel.h:107
+
bool isTimerActive(void)
Get if the Timer is active on the A/C.
Definition: ir_Vestel.cpp:220
+
void setRaw(const uint8_t *newState)
Set the internal state from a valid code for this protocol.
Definition: ir_Vestel.cpp:87
+
const uint8_t kVestelAcFan
Definition: ir_Vestel.h:70
+ +
const uint8_t kVestelAcMinTempH
Definition: ir_Vestel.h:63
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Vestel.cpp:140
+
const uint16_t kVestelAcHdrMark
Definition: ir_Vestel.h:56
+
const uint16_t kNoRepeat
Definition: IRremoteESP8266.h:810
+
uint64_t remote_time_state
The time state of the remote in code form.
Definition: ir_Vestel.h:185
+
const uint8_t kVestelAcOnTimerFlagOffset
Definition: ir_Vestel.h:105
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Vestel.cpp:454
+
uint64_t remote_state
The state of the IR remote in IR code form.
Definition: ir_Vestel.h:184
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Vestel.cpp:344
+
const uint16_t kVestelAcOneSpace
Definition: ir_Vestel.h:59
+
void checksum(void)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Vestel.cpp:409
+
void setSwing(const bool on)
Set the Swing Roaming setting of the A/C.
Definition: ir_Vestel.cpp:379
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Vestel.cpp:359
+
const uint8_t kVestelAcTempOffset
Definition: ir_Vestel.h:90
+
void setOffTimer(const uint16_t minutes)
Set the Off timer time on the A/C.
Definition: ir_Vestel.cpp:323
+
const uint8_t kVestelAcTimerMinsSize
Definition: ir_Vestel.h:100
+
void setOnTimerActive(const bool on)
Set the On timer to be active on the A/C.
Definition: ir_Vestel.cpp:265
+
const uint8_t kVestelAcHourOffset
Definition: ir_Vestel.h:103
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Vestel.cpp:467
+
void send(const uint16_t repeat=kNoRepeat)
Send the current internal state as an IR message.
Definition: ir_Vestel.cpp:72
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Vestel.cpp:112
+
const uint8_t kVestelAcFanAutoCool
Definition: ir_Vestel.h:77
+
const uint64_t kVestelAcStateDefault
Definition: ir_Vestel.h:111
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Vestel.cpp:427
+
void setIon(const bool on)
Set the Ion (Filter) setting of the A/C.
Definition: ir_Vestel.cpp:366
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Vestel.cpp:505
+
const uint16_t kVestelAcTolerance
Definition: ir_Vestel.h:61
+
const uint8_t kVestelAcFanLow
Definition: ir_Vestel.h:74
+
const uint8_t kVestelAcChecksumOffset
Definition: ir_Vestel.h:86
+
const uint8_t kVestelAcPowerSize
Definition: ir_Vestel.h:96
+
const uint8_t kVestelAcSwing
Definition: ir_Vestel.h:84
+
const uint8_t kVestelAcIonOffset
Definition: ir_Vestel.h:94
+
const uint8_t kVestelAcOnTimeOffset
Definition: ir_Vestel.h:98
+
const uint16_t kVestelAcZeroSpace
Definition: ir_Vestel.h:60
+
const uint8_t kVestelAcMinuteOffset
Definition: ir_Vestel.h:108
+
const uint64_t kVestelAcTimeStateDefault
Definition: ir_Vestel.h:112
+
uint16_t getTime(void)
Get the A/C's internal clock's time.
Definition: ir_Vestel.cpp:257
+
const uint8_t kVestelAcTurboSleepOffset
Definition: ir_Vestel.h:89
+
const uint8_t kVestelAcTurbo
Definition: ir_Vestel.h:82
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Vestel.cpp:124
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Vestel.cpp:395
+
uint64_t getRaw(void)
Get a copy of the internal state/code for this protocol.
Definition: ir_Vestel.cpp:79
+
const uint8_t kVestelAcHeat
Definition: ir_Vestel.h:71
+
const uint8_t kVestelAcNormal
Definition: ir_Vestel.h:80
+
const uint8_t kVestelAcFanHigh
Definition: ir_Vestel.h:76
+
const uint8_t kVestelAcTimerSize
Definition: ir_Vestel.h:101
+
IRVestelAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Vestel.cpp:54
+
Class for handling detailed Vestel A/C messages.
Definition: ir_Vestel.h:116
+
bool getIon(void)
Get the Ion (Filter) setting of the A/C.
Definition: ir_Vestel.cpp:373
+
const uint8_t kVestelAcCool
Definition: ir_Vestel.h:68
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Vestel.cpp:171
+
uint16_t getOnTimer(void)
Get the A/C's On Timer time.
Definition: ir_Vestel.cpp:304
+
void setTimerActive(const bool on)
Set the timer to be active on the A/C.
Definition: ir_Vestel.cpp:213
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Vestel.cpp:336
+
void _setTimer(const uint16_t minutes, const uint8_t offset)
Set a given timer time at a given bit offset.
Definition: ir_Vestel.cpp:279
+
bool use_time_state
Definition: ir_Vestel.h:186
+
const uint8_t kVestelAcOffTimerFlagOffset
Definition: ir_Vestel.h:106
+
const uint8_t kVestelAcModeOffset
Definition: ir_Vestel.h:93
+
const uint8_t kVestelAcIon
Definition: ir_Vestel.h:83
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Vestel.cpp:165
+
bool getSwing(void)
Get the Swing Roaming setting of the A/C.
Definition: ir_Vestel.cpp:387
+
const uint8_t kVestelAcPowerOffset
Definition: ir_Vestel.h:95
+
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Vestel.cpp:403
+
void setAuto(const int8_t autoLevel)
Set Auto mode/level of the A/C.
Definition: ir_Vestel.cpp:195
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kVestelAcFanAuto
Definition: ir_Vestel.h:73
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Vestel.cpp:440
+
void setOnTimer(const uint16_t minutes)
Set the On timer time on the A/C.
Definition: ir_Vestel.cpp:297
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8cpp.html new file mode 100644 index 000000000..95fcdadbf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8cpp.html @@ -0,0 +1,224 @@ + + + + + + + +IRremoteESP8266: src/ir_Whirlpool.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Whirlpool.cpp File Reference
+
+
+ +

Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea. +More...

+ + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kWhirlpoolAcHdrMark = 8950
 
const uint16_t kWhirlpoolAcHdrSpace = 4484
 
const uint16_t kWhirlpoolAcBitMark = 597
 
const uint16_t kWhirlpoolAcOneSpace = 1649
 
const uint16_t kWhirlpoolAcZeroSpace = 533
 
const uint16_t kWhirlpoolAcGap = 7920
 
const uint32_t kWhirlpoolAcMinGap = kDefaultMessageGap
 
const uint8_t kWhirlpoolAcSections = 3
 
+

Detailed Description

+

Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/509
+
Note
Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. Advanced 6thSense, Dehumidify, & Sleep modes are not supported.
+
+Dim == !Light, Jet == Super == Turbo
+

Variable Documentation

+ +

◆ kWhirlpoolAcBitMark

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcBitMark = 597
+
+ +
+
+ +

◆ kWhirlpoolAcGap

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcGap = 7920
+
+ +
+
+ +

◆ kWhirlpoolAcHdrMark

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcHdrMark = 8950
+
+ +
+
+ +

◆ kWhirlpoolAcHdrSpace

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcHdrSpace = 4484
+
+ +
+
+ +

◆ kWhirlpoolAcMinGap

+ +
+
+ + + + +
const uint32_t kWhirlpoolAcMinGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kWhirlpoolAcOneSpace

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcOneSpace = 1649
+
+ +
+
+ +

◆ kWhirlpoolAcSections

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSections = 3
+
+ +
+
+ +

◆ kWhirlpoolAcZeroSpace

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcZeroSpace = 533
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h.html new file mode 100644 index 000000000..555b83ade --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h.html @@ -0,0 +1,937 @@ + + + + + + + +IRremoteESP8266: src/ir_Whirlpool.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Whirlpool.h File Reference
+
+
+ +

Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRWhirlpoolAc
 Class for handling detailed Whirlpool A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kWhirlpoolAcChecksumByte1 = 13
 
const uint8_t kWhirlpoolAcChecksumByte2 = kWhirlpoolAcStateLength - 1
 
const uint8_t kWhirlpoolAcHeat = 0
 
const uint8_t kWhirlpoolAcAuto = 1
 
const uint8_t kWhirlpoolAcCool = 2
 
const uint8_t kWhirlpoolAcDry = 3
 
const uint8_t kWhirlpoolAcFan = 4
 
const uint8_t kWhirlpoolAcModeOffset = 0
 
const uint8_t kWhirlpoolAcModePos = 3
 
const uint8_t kWhirlpoolAcFanOffset = 0
 
const uint8_t kWhirlpoolAcFanSize = 2
 
const uint8_t kWhirlpoolAcFanAuto = 0
 
const uint8_t kWhirlpoolAcFanHigh = 1
 
const uint8_t kWhirlpoolAcFanMedium = 2
 
const uint8_t kWhirlpoolAcFanLow = 3
 
const uint8_t kWhirlpoolAcFanPos = 2
 
const uint8_t kWhirlpoolAcMinTemp = 18
 
const uint8_t kWhirlpoolAcMaxTemp = 32
 
const uint8_t kWhirlpoolAcAutoTemp = 23
 
const uint8_t kWhirlpoolAcTempPos = 3
 
const uint8_t kWhirlpoolAcSwing1Offset = 7
 
const uint8_t kWhirlpoolAcSwing2Offset = 6
 
const uint8_t kWhirlpoolAcLightOffset = 5
 
const uint8_t kWhirlpoolAcPowerToggleOffset = 2
 
const uint8_t kWhirlpoolAcPowerTogglePos = 2
 
const uint8_t kWhirlpoolAcSleepOffset = 3
 
const uint8_t kWhirlpoolAcSleepPos = 2
 
const uint8_t kWhirlpoolAcSuperMask = 0b10010000
 
const uint8_t kWhirlpoolAcSuperPos = 5
 
const uint8_t kWhirlpoolAcHourOffset = 0
 
const uint8_t kWhirlpoolAcHourSize = 5
 
const uint8_t kWhirlpoolAcMinuteOffset = 0
 
const uint8_t kWhirlpoolAcMinuteSize = 6
 
const uint8_t kWhirlpoolAcTimerEnableOffset = 7
 
const uint8_t kWhirlpoolAcClockPos = 6
 
const uint8_t kWhirlpoolAcOffTimerPos = 8
 
const uint8_t kWhirlpoolAcOnTimerPos = 10
 
const uint8_t kWhirlpoolAcCommandPos = 15
 
const uint8_t kWhirlpoolAcCommandLight = 0x00
 
const uint8_t kWhirlpoolAcCommandPower = 0x01
 
const uint8_t kWhirlpoolAcCommandTemp = 0x02
 
const uint8_t kWhirlpoolAcCommandSleep = 0x03
 
const uint8_t kWhirlpoolAcCommandSuper = 0x04
 
const uint8_t kWhirlpoolAcCommandOnTimer = 0x05
 
const uint8_t kWhirlpoolAcCommandMode = 0x06
 
const uint8_t kWhirlpoolAcCommandSwing = 0x07
 
const uint8_t kWhirlpoolAcCommandIFeel = 0x0D
 
const uint8_t kWhirlpoolAcCommandFanSpeed = 0x11
 
const uint8_t kWhirlpoolAcCommand6thSense = 0x17
 
const uint8_t kWhirlpoolAcCommandOffTimer = 0x1D
 
const uint8_t kWhirlpoolAcAltTempOffset = 3
 
const uint8_t kWhirlpoolAcAltTempPos = 18
 
+

Detailed Description

+

Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/509
+
Note
Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. Advanced 6thSense, Dehumidify, & Sleep modes are not supported.
+
+Dim == !Light, Jet == Super == Turbo
+

Variable Documentation

+ +

◆ kWhirlpoolAcAltTempOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcAltTempOffset = 3
+
+ +
+
+ +

◆ kWhirlpoolAcAltTempPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcAltTempPos = 18
+
+ +
+
+ +

◆ kWhirlpoolAcAuto

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcAuto = 1
+
+ +
+
+ +

◆ kWhirlpoolAcAutoTemp

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcAutoTemp = 23
+
+ +
+
+ +

◆ kWhirlpoolAcChecksumByte1

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcChecksumByte1 = 13
+
+ +
+
+ +

◆ kWhirlpoolAcChecksumByte2

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcChecksumByte2 = kWhirlpoolAcStateLength - 1
+
+ +
+
+ +

◆ kWhirlpoolAcClockPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcClockPos = 6
+
+ +
+
+ +

◆ kWhirlpoolAcCommand6thSense

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommand6thSense = 0x17
+
+ +
+
+ +

◆ kWhirlpoolAcCommandFanSpeed

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandFanSpeed = 0x11
+
+ +
+
+ +

◆ kWhirlpoolAcCommandIFeel

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandIFeel = 0x0D
+
+ +
+
+ +

◆ kWhirlpoolAcCommandLight

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandLight = 0x00
+
+ +
+
+ +

◆ kWhirlpoolAcCommandMode

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandMode = 0x06
+
+ +
+
+ +

◆ kWhirlpoolAcCommandOffTimer

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandOffTimer = 0x1D
+
+ +
+
+ +

◆ kWhirlpoolAcCommandOnTimer

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandOnTimer = 0x05
+
+ +
+
+ +

◆ kWhirlpoolAcCommandPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandPos = 15
+
+ +
+
+ +

◆ kWhirlpoolAcCommandPower

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandPower = 0x01
+
+ +
+
+ +

◆ kWhirlpoolAcCommandSleep

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandSleep = 0x03
+
+ +
+
+ +

◆ kWhirlpoolAcCommandSuper

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandSuper = 0x04
+
+ +
+
+ +

◆ kWhirlpoolAcCommandSwing

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandSwing = 0x07
+
+ +
+
+ +

◆ kWhirlpoolAcCommandTemp

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandTemp = 0x02
+
+ +
+
+ +

◆ kWhirlpoolAcCool

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCool = 2
+
+ +
+
+ +

◆ kWhirlpoolAcDry

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcDry = 3
+
+ +
+
+ +

◆ kWhirlpoolAcFan

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFan = 4
+
+ +
+
+ +

◆ kWhirlpoolAcFanAuto

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanAuto = 0
+
+ +
+
+ +

◆ kWhirlpoolAcFanHigh

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanHigh = 1
+
+ +
+
+ +

◆ kWhirlpoolAcFanLow

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanLow = 3
+
+ +
+
+ +

◆ kWhirlpoolAcFanMedium

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanMedium = 2
+
+ +
+
+ +

◆ kWhirlpoolAcFanOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanOffset = 0
+
+ +
+
+ +

◆ kWhirlpoolAcFanPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanPos = 2
+
+ +
+
+ +

◆ kWhirlpoolAcFanSize

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanSize = 2
+
+ +
+
+ +

◆ kWhirlpoolAcHeat

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcHeat = 0
+
+ +
+
+ +

◆ kWhirlpoolAcHourOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcHourOffset = 0
+
+ +
+
+ +

◆ kWhirlpoolAcHourSize

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcHourSize = 5
+
+ +
+
+ +

◆ kWhirlpoolAcLightOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcLightOffset = 5
+
+ +
+
+ +

◆ kWhirlpoolAcMaxTemp

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcMaxTemp = 32
+
+ +
+
+ +

◆ kWhirlpoolAcMinTemp

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcMinTemp = 18
+
+ +
+
+ +

◆ kWhirlpoolAcMinuteOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcMinuteOffset = 0
+
+ +
+
+ +

◆ kWhirlpoolAcMinuteSize

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcMinuteSize = 6
+
+ +
+
+ +

◆ kWhirlpoolAcModeOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcModeOffset = 0
+
+ +
+
+ +

◆ kWhirlpoolAcModePos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcModePos = 3
+
+ +
+
+ +

◆ kWhirlpoolAcOffTimerPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcOffTimerPos = 8
+
+ +
+
+ +

◆ kWhirlpoolAcOnTimerPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcOnTimerPos = 10
+
+ +
+
+ +

◆ kWhirlpoolAcPowerToggleOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcPowerToggleOffset = 2
+
+ +
+
+ +

◆ kWhirlpoolAcPowerTogglePos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcPowerTogglePos = 2
+
+ +
+
+ +

◆ kWhirlpoolAcSleepOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSleepOffset = 3
+
+ +
+
+ +

◆ kWhirlpoolAcSleepPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSleepPos = 2
+
+ +
+
+ +

◆ kWhirlpoolAcSuperMask

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSuperMask = 0b10010000
+
+ +
+
+ +

◆ kWhirlpoolAcSuperPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSuperPos = 5
+
+ +
+
+ +

◆ kWhirlpoolAcSwing1Offset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSwing1Offset = 7
+
+ +
+
+ +

◆ kWhirlpoolAcSwing2Offset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSwing2Offset = 6
+
+ +
+
+ +

◆ kWhirlpoolAcTempPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcTempPos = 3
+
+ +
+
+ +

◆ kWhirlpoolAcTimerEnableOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcTimerEnableOffset = 7
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h_source.html new file mode 100644 index 000000000..380cd8281 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h_source.html @@ -0,0 +1,353 @@ + + + + + + + +IRremoteESP8266: src/ir_Whirlpool.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Whirlpool.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 David Conran
+
2 
+
10 
+
11 // Supports:
+
12 // Brand: Whirlpool, Model: DG11J1-3A remote
+
13 // Brand: Whirlpool, Model: DG11J1-04 remote
+
14 // Brand: Whirlpool, Model: DG11J1-91 remote
+
15 // Brand: Whirlpool, Model: SPIS409L A/C
+
16 // Brand: Whirlpool, Model: SPIS412L A/C
+
17 // Brand: Whirlpool, Model: SPIW409L A/C
+
18 // Brand: Whirlpool, Model: SPIW412L A/C
+
19 // Brand: Whirlpool, Model: SPIW418L A/C
+
20 
+
21 #ifndef IR_WHIRLPOOL_H_
+
22 #define IR_WHIRLPOOL_H_
+
23 
+
24 #define __STDC_LIMIT_MACROS
+
25 #include <stdint.h>
+
26 #ifndef UNIT_TEST
+
27 #include <Arduino.h>
+
28 #endif
+
29 #include "IRremoteESP8266.h"
+
30 #include "IRsend.h"
+
31 #ifdef UNIT_TEST
+
32 #include "IRsend_test.h"
+
33 #endif
+
34 
+
35 // Constants
+
36 const uint8_t kWhirlpoolAcChecksumByte1 = 13;
+ +
38 const uint8_t kWhirlpoolAcHeat = 0;
+
39 const uint8_t kWhirlpoolAcAuto = 1;
+
40 const uint8_t kWhirlpoolAcCool = 2;
+
41 const uint8_t kWhirlpoolAcDry = 3;
+
42 const uint8_t kWhirlpoolAcFan = 4;
+
43 const uint8_t kWhirlpoolAcModeOffset = 0;
+
44 const uint8_t kWhirlpoolAcModePos = 3;
+
45 const uint8_t kWhirlpoolAcFanOffset = 0; // Mask 0b00000011
+
46 const uint8_t kWhirlpoolAcFanSize = 2; // Nr. of bits
+
47 const uint8_t kWhirlpoolAcFanAuto = 0;
+
48 const uint8_t kWhirlpoolAcFanHigh = 1;
+
49 const uint8_t kWhirlpoolAcFanMedium = 2;
+
50 const uint8_t kWhirlpoolAcFanLow = 3;
+
51 const uint8_t kWhirlpoolAcFanPos = 2;
+
52 const uint8_t kWhirlpoolAcMinTemp = 18; // 18C (DG11J1-3A), 16C (DG11J1-91)
+
53 const uint8_t kWhirlpoolAcMaxTemp = 32; // 32C (DG11J1-3A), 30C (DG11J1-91)
+
54 const uint8_t kWhirlpoolAcAutoTemp = 23; // 23C
+
55 const uint8_t kWhirlpoolAcTempPos = 3;
+
56 const uint8_t kWhirlpoolAcSwing1Offset = 7;
+
57 const uint8_t kWhirlpoolAcSwing2Offset = 6;
+
58 const uint8_t kWhirlpoolAcLightOffset = 5;
+
59 const uint8_t kWhirlpoolAcPowerToggleOffset = 2; // 0b00000100
+
60 const uint8_t kWhirlpoolAcPowerTogglePos = 2;
+
61 const uint8_t kWhirlpoolAcSleepOffset = 3;
+
62 const uint8_t kWhirlpoolAcSleepPos = 2;
+
63 const uint8_t kWhirlpoolAcSuperMask = 0b10010000;
+
64 const uint8_t kWhirlpoolAcSuperPos = 5;
+
65 const uint8_t kWhirlpoolAcHourOffset = 0; // Mask 0b00011111
+
66 const uint8_t kWhirlpoolAcHourSize = 5; // Nr. of bits
+
67 const uint8_t kWhirlpoolAcMinuteOffset = 0; // Mask 0b00111111
+
68 const uint8_t kWhirlpoolAcMinuteSize = 6; // Nr. of bits
+
69 const uint8_t kWhirlpoolAcTimerEnableOffset = 7; // 0b10000000
+
70 const uint8_t kWhirlpoolAcClockPos = 6;
+
71 const uint8_t kWhirlpoolAcOffTimerPos = 8;
+
72 const uint8_t kWhirlpoolAcOnTimerPos = 10;
+
73 const uint8_t kWhirlpoolAcCommandPos = 15;
+
74 const uint8_t kWhirlpoolAcCommandLight = 0x00;
+
75 const uint8_t kWhirlpoolAcCommandPower = 0x01;
+
76 const uint8_t kWhirlpoolAcCommandTemp = 0x02;
+
77 const uint8_t kWhirlpoolAcCommandSleep = 0x03;
+
78 const uint8_t kWhirlpoolAcCommandSuper = 0x04;
+
79 const uint8_t kWhirlpoolAcCommandOnTimer = 0x05;
+
80 const uint8_t kWhirlpoolAcCommandMode = 0x06;
+
81 const uint8_t kWhirlpoolAcCommandSwing = 0x07;
+
82 const uint8_t kWhirlpoolAcCommandIFeel = 0x0D;
+
83 const uint8_t kWhirlpoolAcCommandFanSpeed = 0x11;
+
84 const uint8_t kWhirlpoolAcCommand6thSense = 0x17;
+
85 const uint8_t kWhirlpoolAcCommandOffTimer = 0x1D;
+
86 const uint8_t kWhirlpoolAcAltTempOffset = 3;
+
87 const uint8_t kWhirlpoolAcAltTempPos = 18;
+
88 
+
89 // Classes
+ +
92  public:
+
93  explicit IRWhirlpoolAc(const uint16_t pin, const bool inverted = false,
+
94  const bool use_modulation = true);
+
95  void stateReset(void);
+
96 #if SEND_WHIRLPOOL_AC
+
97  void send(const uint16_t repeat = kWhirlpoolAcDefaultRepeat,
+
98  const bool calcchecksum = true);
+
103  int8_t calibrate(void) { return _irsend.calibrate(); }
+
104 #endif // SEND_WHIRLPOOL_AC
+
105  void begin(void);
+
106  void setPowerToggle(const bool on);
+
107  bool getPowerToggle(void);
+
108  void setSleep(const bool on);
+
109  bool getSleep(void);
+
110  void setSuper(const bool on);
+
111  bool getSuper(void);
+
112  void setTemp(const uint8_t temp);
+
113  uint8_t getTemp(void);
+
114  void setFan(const uint8_t speed);
+
115  uint8_t getFan(void);
+
116  void setMode(const uint8_t mode);
+
117  uint8_t getMode(void);
+
118  void setSwing(const bool on);
+
119  bool getSwing(void);
+
120  void setLight(const bool on);
+
121  bool getLight(void);
+
122  uint16_t getClock(void);
+
123  void setClock(const uint16_t minspastmidnight);
+
124  uint16_t getOnTimer(void);
+
125  void setOnTimer(const uint16_t minspastmidnight);
+
126  void enableOnTimer(const bool on);
+
127  bool isOnTimerEnabled(void);
+
128  uint16_t getOffTimer(void);
+
129  void setOffTimer(const uint16_t minspastmidnight);
+
130  void enableOffTimer(const bool on);
+
131  bool isOffTimerEnabled(void);
+
132  void setCommand(const uint8_t code);
+
133  uint8_t getCommand(void);
+ +
135  void setModel(const whirlpool_ac_remote_model_t model);
+
136  uint8_t* getRaw(const bool calcchecksum = true);
+
137  void setRaw(const uint8_t new_code[],
+
138  const uint16_t length = kWhirlpoolAcStateLength);
+
139  static bool validChecksum(const uint8_t state[],
+
140  const uint16_t length = kWhirlpoolAcStateLength);
+
141  uint8_t convertMode(const stdAc::opmode_t mode);
+
142  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
143  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
144  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
145  stdAc::state_t toCommon(void);
+
146  String toString(void);
+
147 #ifndef UNIT_TEST
+
148 
+
149  private:
+ +
151 #else // UNIT_TEST
+
152  IRsendTest _irsend;
+
154 #endif // UNIT_TEST
+ +
157  uint8_t _desiredtemp;
+
158  void checksum(const uint16_t length = kWhirlpoolAcStateLength);
+
159  uint16_t getTime(const uint16_t pos);
+
160  void setTime(const uint16_t pos, const uint16_t minspastmidnight);
+
161  bool isTimerEnabled(const uint16_t pos);
+
162  void enableTimer(const uint16_t pos, const bool state);
+
163  void _setTemp(const uint8_t temp, const bool remember = true);
+
164  void _setMode(const uint8_t mode);
+
165  int8_t getTempOffset(void);
+
166 };
+
167 
+
168 #endif // IR_WHIRLPOOL_H_
+
+
const uint8_t kWhirlpoolAcLightOffset
Definition: ir_Whirlpool.h:58
+
void send(const uint16_t repeat=kWhirlpoolAcDefaultRepeat, const bool calcchecksum=true)
Send the current internal state as an IR message.
Definition: ir_Whirlpool.cpp:139
+
const uint8_t kWhirlpoolAcOnTimerPos
Definition: ir_Whirlpool.h:72
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Whirlpool.cpp:89
+
uint16_t getClock(void)
Get the clock time in nr. of minutes past midnight.
Definition: ir_Whirlpool.cpp:357
+
const uint8_t kWhirlpoolAcCommandSuper
Definition: ir_Whirlpool.h:78
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Whirlpool.h:103
+
const uint8_t kWhirlpoolAcFanSize
Definition: ir_Whirlpool.h:46
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Whirlpool.cpp:485
+
const uint8_t kWhirlpoolAcSuperPos
Definition: ir_Whirlpool.h:64
+
void _setTemp(const uint8_t temp, const bool remember=true)
Set the temperature.
Definition: ir_Whirlpool.cpp:198
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
whirlpool_ac_remote_model_t
Whirlpool A/C model numbers.
Definition: IRsend.h:152
+
const uint8_t kWhirlpoolAcAutoTemp
Definition: ir_Whirlpool.h:54
+
const uint8_t kWhirlpoolAcModePos
Definition: ir_Whirlpool.h:44
+
const uint8_t kWhirlpoolAcFanHigh
Definition: ir_Whirlpool.h:48
+
const uint8_t kWhirlpoolAcPowerTogglePos
Definition: ir_Whirlpool.h:60
+
const uint8_t kWhirlpoolAcMaxTemp
Definition: ir_Whirlpool.h:53
+
const uint8_t kWhirlpoolAcAltTempPos
Definition: ir_Whirlpool.h:87
+
const uint8_t kWhirlpoolAcAuto
Definition: ir_Whirlpool.h:39
+
const uint8_t kWhirlpoolAcFanPos
Definition: ir_Whirlpool.h:51
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Whirlpool.cpp:498
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Whirlpool.cpp:525
+
bool isOnTimerEnabled(void)
Is the On timer enabled?
Definition: ir_Whirlpool.cpp:400
+
IRWhirlpoolAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Whirlpool.cpp:84
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Whirlpool.cpp:255
+
const uint8_t kWhirlpoolAcCommandOnTimer
Definition: ir_Whirlpool.h:79
+ +
const uint8_t kWhirlpoolAcTempPos
Definition: ir_Whirlpool.h:55
+
bool getLight(void)
Get the Light (Display/LED) setting of the A/C.
Definition: ir_Whirlpool.cpp:308
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Whirlpool.cpp:209
+
const uint8_t kWhirlpoolAcTimerEnableOffset
Definition: ir_Whirlpool.h:69
+
const uint8_t kWhirlpoolAcCommandIFeel
Definition: ir_Whirlpool.h:82
+
bool getSwing(void)
Get the (vertical) swing setting of the A/C.
Definition: ir_Whirlpool.cpp:293
+
const uint8_t kWhirlpoolAcModeOffset
Definition: ir_Whirlpool.h:43
+
void setClock(const uint16_t minspastmidnight)
Set the clock time in nr. of minutes past midnight.
Definition: ir_Whirlpool.cpp:351
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kWhirlpoolAcSuperMask
Definition: ir_Whirlpool.h:63
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kWhirlpoolAcChecksumByte1
Definition: ir_Whirlpool.h:36
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Whirlpool.cpp:444
+
const uint8_t kWhirlpoolAcMinuteSize
Definition: ir_Whirlpool.h:68
+
uint16_t getTime(const uint16_t pos)
Get the time in nr. of minutes past midnight.
Definition: ir_Whirlpool.cpp:328
+
void enableTimer(const uint16_t pos, const bool state)
Enable the timer enabled at the given byte offset.
Definition: ir_Whirlpool.cpp:345
+
Class for handling detailed Whirlpool A/C messages.
Definition: ir_Whirlpool.h:91
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kWhirlpoolAcCommandPos
Definition: ir_Whirlpool.h:73
+
const uint8_t kWhirlpoolAcCommandMode
Definition: ir_Whirlpool.h:80
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Whirlpool.cpp:217
+
int8_t getTempOffset(void)
Calculate the temp. offset in deg C for the current model.
Definition: ir_Whirlpool.cpp:187
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Whirlpool.cpp:278
+
const uint8_t kWhirlpoolAcCool
Definition: ir_Whirlpool.h:40
+
const uint8_t kWhirlpoolAcSleepPos
Definition: ir_Whirlpool.h:62
+
whirlpool_ac_remote_model_t getModel(void)
Get/Detect the model of the A/C.
Definition: ir_Whirlpool.cpp:162
+
const uint8_t kWhirlpoolAcCommandOffTimer
Definition: ir_Whirlpool.h:85
+
const uint8_t kWhirlpoolAcSwing1Offset
Definition: ir_Whirlpool.h:56
+ +
const uint8_t kWhirlpoolAcCommandSwing
Definition: ir_Whirlpool.h:81
+
bool isOffTimerEnabled(void)
Is the Off timer enabled?
Definition: ir_Whirlpool.cpp:375
+
const uint8_t kWhirlpoolAcMinuteOffset
Definition: ir_Whirlpool.h:67
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kWhirlpoolAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Whirlpool.cpp:104
+
const uint8_t kWhirlpoolAcFanMedium
Definition: ir_Whirlpool.h:49
+
const uint8_t kWhirlpoolAcDry
Definition: ir_Whirlpool.h:41
+
const uint8_t kWhirlpoolAcAltTempOffset
Definition: ir_Whirlpool.h:86
+
void setPowerToggle(const bool on)
Change the power toggle setting.
Definition: ir_Whirlpool.cpp:413
+
void setOffTimer(const uint16_t minspastmidnight)
Set the Off Timer time.
Definition: ir_Whirlpool.cpp:363
+
const uint8_t kWhirlpoolAcSwing2Offset
Definition: ir_Whirlpool.h:57
+
const uint8_t kWhirlpoolAcCommandLight
Definition: ir_Whirlpool.h:74
+
uint8_t getCommand(void)
Get the Command (Button) setting of the A/C.
Definition: ir_Whirlpool.cpp:429
+
void _setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Whirlpool.cpp:225
+
const uint8_t kWhirlpoolAcFanLow
Definition: ir_Whirlpool.h:50
+
const uint16_t kWhirlpoolAcDefaultRepeat
Definition: IRremoteESP8266.h:1007
+
const uint8_t kWhirlpoolAcOffTimerPos
Definition: ir_Whirlpool.h:71
+
uint16_t getOffTimer(void)
Get the Off Timer time..
Definition: ir_Whirlpool.cpp:369
+
void setModel(const whirlpool_ac_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_Whirlpool.cpp:171
+
void setSuper(const bool on)
Set the Super (Turbo/Jet) setting of the A/C.
Definition: ir_Whirlpool.cpp:450
+
const uint8_t kWhirlpoolAcChecksumByte2
Definition: ir_Whirlpool.h:37
+
const uint8_t kWhirlpoolAcFan
Definition: ir_Whirlpool.h:42
+
uint16_t getOnTimer(void)
Get the On Timer time..
Definition: ir_Whirlpool.cpp:394
+
const uint8_t kWhirlpoolAcCommandFanSpeed
Definition: ir_Whirlpool.h:83
+
void setCommand(const uint8_t code)
Set the Command (Button) setting of the A/C.
Definition: ir_Whirlpool.cpp:478
+
const uint16_t kWhirlpoolAcStateLength
Definition: IRremoteESP8266.h:1005
+
const uint8_t kWhirlpoolAcHourOffset
Definition: ir_Whirlpool.h:65
+
void setRaw(const uint8_t new_code[], const uint16_t length=kWhirlpoolAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Whirlpool.cpp:156
+
const uint8_t kWhirlpoolAcMinTemp
Definition: ir_Whirlpool.h:52
+
bool getSuper(void)
Get the Super (Turbo/Jet) setting of the A/C.
Definition: ir_Whirlpool.cpp:472
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Whirlpool.cpp:435
+
uint8_t remote_state[kWhirlpoolAcStateLength]
The state in IR code form.
Definition: ir_Whirlpool.h:156
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Whirlpool.cpp:248
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Whirlpool.cpp:563
+
const uint8_t kWhirlpoolAcHeat
Definition: ir_Whirlpool.h:38
+
void checksum(const uint16_t length=kWhirlpoolAcStateLength)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Whirlpool.cpp:125
+
void enableOffTimer(const bool on)
Enable the Off Timer.
Definition: ir_Whirlpool.cpp:381
+
const uint8_t kWhirlpoolAcCommandPower
Definition: ir_Whirlpool.h:75
+
void enableOnTimer(const bool on)
Enable the On Timer.
Definition: ir_Whirlpool.cpp:406
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Whirlpool.h:150
+
void setOnTimer(const uint16_t minspastmidnight)
Set the On Timer time.
Definition: ir_Whirlpool.cpp:388
+
uint8_t _desiredtemp
The last user explicitly set temperature.
Definition: ir_Whirlpool.h:157
+
bool getPowerToggle(void)
Get the value of the current power toggle setting.
Definition: ir_Whirlpool.cpp:422
+
const uint8_t kWhirlpoolAcCommandTemp
Definition: ir_Whirlpool.h:76
+
const uint8_t kWhirlpoolAcFanOffset
Definition: ir_Whirlpool.h:45
+
const uint8_t kWhirlpoolAcCommand6thSense
Definition: ir_Whirlpool.h:84
+
const uint8_t kWhirlpoolAcCommandSleep
Definition: ir_Whirlpool.h:77
+
const uint8_t kWhirlpoolAcClockPos
Definition: ir_Whirlpool.h:70
+
const uint8_t kWhirlpoolAcPowerToggleOffset
Definition: ir_Whirlpool.h:59
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Whirlpool.cpp:98
+
const uint8_t kWhirlpoolAcSleepOffset
Definition: ir_Whirlpool.h:61
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Whirlpool.cpp:536
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Whirlpool.cpp:262
+
void setLight(const bool on)
Set the Light (Display/LED) setting of the A/C.
Definition: ir_Whirlpool.cpp:301
+
void setTime(const uint16_t pos, const uint16_t minspastmidnight)
Set the time in nr. of minutes past midnight.
Definition: ir_Whirlpool.cpp:315
+
void setSwing(const bool on)
Set the (vertical) swing setting of the A/C.
Definition: ir_Whirlpool.cpp:285
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Whirlpool.cpp:512
+
const uint8_t kWhirlpoolAcHourSize
Definition: ir_Whirlpool.h:66
+
const uint8_t kWhirlpoolAcFanAuto
Definition: ir_Whirlpool.h:47
+
uint8_t * getRaw(const bool calcchecksum=true)
Get a copy of the internal state/code for this protocol.
Definition: ir_Whirlpool.cpp:148
+
bool isTimerEnabled(const uint16_t pos)
Is the timer enabled at the given byte offset?
Definition: ir_Whirlpool.cpp:338
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whynter_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whynter_8cpp.html new file mode 100644 index 000000000..11e6a0701 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whynter_8cpp.html @@ -0,0 +1,344 @@ + + + + + + + +IRremoteESP8266: src/ir_Whynter.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Whynter.cpp File Reference
+
+
+ +

Support for Whynter protocols. Whynter A/C ARC-110WD added by Francesco Meschia Whynter originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kWhynterTick = 50
 
const uint16_t kWhynterHdrMarkTicks = 57
 
const uint16_t kWhynterHdrMark = kWhynterHdrMarkTicks * kWhynterTick
 
const uint16_t kWhynterHdrSpaceTicks = 57
 
const uint16_t kWhynterHdrSpace = kWhynterHdrSpaceTicks * kWhynterTick
 
const uint16_t kWhynterBitMarkTicks = 15
 
const uint16_t kWhynterBitMark = kWhynterBitMarkTicks * kWhynterTick
 
const uint16_t kWhynterOneSpaceTicks = 43
 
const uint16_t kWhynterOneSpace = kWhynterOneSpaceTicks * kWhynterTick
 
const uint16_t kWhynterZeroSpaceTicks = 15
 
const uint16_t kWhynterZeroSpace = kWhynterZeroSpaceTicks * kWhynterTick
 
const uint16_t kWhynterMinCommandLengthTicks = 2160
 
const uint32_t kWhynterMinCommandLength
 
const uint16_t kWhynterMinGapTicks
 
const uint16_t kWhynterMinGap = kWhynterMinGapTicks * kWhynterTick
 
+

Detailed Description

+

Support for Whynter protocols. Whynter A/C ARC-110WD added by Francesco Meschia Whynter originally added from https://github.com/shirriff/Arduino-IRremote/.

+

Variable Documentation

+ +

◆ kWhynterBitMark

+ +
+
+ + + + +
const uint16_t kWhynterBitMark = kWhynterBitMarkTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterBitMarkTicks

+ +
+
+ + + + +
const uint16_t kWhynterBitMarkTicks = 15
+
+ +
+
+ +

◆ kWhynterHdrMark

+ +
+
+ + + + +
const uint16_t kWhynterHdrMark = kWhynterHdrMarkTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kWhynterHdrMarkTicks = 57
+
+ +
+
+ +

◆ kWhynterHdrSpace

+ +
+
+ + + + +
const uint16_t kWhynterHdrSpace = kWhynterHdrSpaceTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kWhynterHdrSpaceTicks = 57
+
+ +
+
+ +

◆ kWhynterMinCommandLength

+ +
+
+ + + + +
const uint32_t kWhynterMinCommandLength
+
+
+ +

◆ kWhynterMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kWhynterMinCommandLengthTicks = 2160
+
+ +
+
+ +

◆ kWhynterMinGap

+ +
+
+ + + + +
const uint16_t kWhynterMinGap = kWhynterMinGapTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterMinGapTicks

+ +
+
+ + + + +
const uint16_t kWhynterMinGapTicks
+
+
+ +

◆ kWhynterOneSpace

+ +
+
+ + + + +
const uint16_t kWhynterOneSpace = kWhynterOneSpaceTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kWhynterOneSpaceTicks = 43
+
+ +
+
+ +

◆ kWhynterTick

+ +
+
+ + + + +
const uint16_t kWhynterTick = 50
+
+ +
+
+ +

◆ kWhynterZeroSpace

+ +
+
+ + + + +
const uint16_t kWhynterZeroSpace = kWhynterZeroSpaceTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kWhynterZeroSpaceTicks = 15
+
+ +
+
+
+
const uint16_t kWhynterBits
Definition: IRremoteESP8266.h:1008
+
const uint16_t kWhynterZeroSpaceTicks
Definition: ir_Whynter.cpp:27
+
const uint16_t kWhynterMinCommandLengthTicks
Definition: ir_Whynter.cpp:29
+
const uint16_t kWhynterBitMarkTicks
Definition: ir_Whynter.cpp:23
+
const uint16_t kWhynterTick
Definition: ir_Whynter.cpp:18
+
const uint16_t kWhynterOneSpaceTicks
Definition: ir_Whynter.cpp:25
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Zepeal_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Zepeal_8cpp.html new file mode 100644 index 000000000..a28b6cdcd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Zepeal_8cpp.html @@ -0,0 +1,333 @@ + + + + + + + +IRremoteESP8266: src/ir_Zepeal.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Zepeal.cpp File Reference
+
+
+ +

Support for Zepeal protocol. This protocol uses fixed length bit encoding. Most official information about Zepeal seems to be from Denkyosha. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kZepealHdrMark = 2330
 
const uint16_t kZepealHdrSpace = 3380
 
const uint16_t kZepealOneMark = 1300
 
const uint16_t kZepealZeroMark = 420
 
const uint16_t kZepealOneSpace = kZepealZeroMark
 
const uint16_t kZepealZeroSpace = kZepealOneMark
 
const uint16_t kZepealFooterMark = 420
 
const uint16_t kZepealGap = 6750
 
const uint8_t kZepealTolerance = 40
 
const uint8_t kZepealSignature = 0x6C
 
const uint16_t kZepealCommandSpeed = 0x6C82
 
const uint16_t kZepealCommandOffOn = 0x6C81
 
const uint16_t kZepealCommandRhythm = 0x6C84
 
const uint16_t kZepealCommandOffTimer = 0x6C88
 
const uint16_t kZepealCommandOnTimer = 0x6CC3
 
+

Detailed Description

+

Support for Zepeal protocol. This protocol uses fixed length bit encoding. Most official information about Zepeal seems to be from Denkyosha.

+
See also
https://www.denkyosha.co.jp/
+

Variable Documentation

+ +

◆ kZepealCommandOffOn

+ +
+
+ + + + +
const uint16_t kZepealCommandOffOn = 0x6C81
+
+ +
+
+ +

◆ kZepealCommandOffTimer

+ +
+
+ + + + +
const uint16_t kZepealCommandOffTimer = 0x6C88
+
+ +
+
+ +

◆ kZepealCommandOnTimer

+ +
+
+ + + + +
const uint16_t kZepealCommandOnTimer = 0x6CC3
+
+ +
+
+ +

◆ kZepealCommandRhythm

+ +
+
+ + + + +
const uint16_t kZepealCommandRhythm = 0x6C84
+
+ +
+
+ +

◆ kZepealCommandSpeed

+ +
+
+ + + + +
const uint16_t kZepealCommandSpeed = 0x6C82
+
+ +
+
+ +

◆ kZepealFooterMark

+ +
+
+ + + + +
const uint16_t kZepealFooterMark = 420
+
+ +
+
+ +

◆ kZepealGap

+ +
+
+ + + + +
const uint16_t kZepealGap = 6750
+
+ +
+
+ +

◆ kZepealHdrMark

+ +
+
+ + + + +
const uint16_t kZepealHdrMark = 2330
+
+ +
+
+ +

◆ kZepealHdrSpace

+ +
+
+ + + + +
const uint16_t kZepealHdrSpace = 3380
+
+ +
+
+ +

◆ kZepealOneMark

+ +
+
+ + + + +
const uint16_t kZepealOneMark = 1300
+
+ +
+
+ +

◆ kZepealOneSpace

+ +
+
+ + + + +
const uint16_t kZepealOneSpace = kZepealZeroMark
+
+ +
+
+ +

◆ kZepealSignature

+ +
+
+ + + + +
const uint8_t kZepealSignature = 0x6C
+
+ +
+
+ +

◆ kZepealTolerance

+ +
+
+ + + + +
const uint8_t kZepealTolerance = 40
+
+ +
+
+ +

◆ kZepealZeroMark

+ +
+
+ + + + +
const uint16_t kZepealZeroMark = 420
+
+ +
+
+ +

◆ kZepealZeroSpace

+ +
+
+ + + + +
const uint16_t kZepealZeroSpace = kZepealOneMark
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h.html new file mode 100644 index 000000000..8bd3af9fa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/it-IT.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
it-IT.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h_source.html new file mode 100644 index 000000000..4b554dec9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h_source.html @@ -0,0 +1,239 @@ + + + + + + + +IRremoteESP8266: src/locale/it-IT.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
it-IT.h
+
+
+Go to the documentation of this file.
1 // Copyright 2020 - Enrico Gueli (@egueli)
+
2 // Locale/language file for Italian.
+
3 // This file will override the default values located in `defaults.h`.
+
4 
+
5 #ifndef LOCALE_IT_IT_H_
+
6 #define LOCALE_IT_IT_H_
+
7 
+
8 #define D_STR_UNKNOWN "SCONOSCIUTO"
+
9 #define D_STR_PROTOCOL "Protocollo"
+
10 #define D_STR_POWER "Accensione"
+
11 #define D_STR_PREVIOUS "Precedente"
+
12 #define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
+
13 #define D_STR_ON "Acceso"
+
14 #define D_STR_OFF "Spento"
+
15 #define D_STR_MODE "Modalità"
+
16 #define D_STR_TOGGLE "Alterna"
+
17 #define D_STR_SLEEP "Sonno"
+
18 #define D_STR_LIGHT "Leggero"
+
19 #define D_STR_POWERFUL "Forte"
+
20 #define D_STR_QUIET "Silenzioso"
+
21 #define D_STR_ECONO "Eco"
+
22 #define D_STR_SWING "Swing"
+
23 #define D_STR_SWINGH D_STR_SWING"(O)" // Set `D_STR_SWING` first!
+
24 #define D_STR_SWINGV D_STR_SWING"(V)" // Set `D_STR_SWING` first!
+
25 #define D_STR_MOULD "Muffa"
+
26 #define D_STR_CLEAN "Pulizia"
+
27 #define D_STR_PURIFY "Purifica"
+
28 #define D_STR_TIMER "Timer"
+
29 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER // Set `D_STR_ON` first!
+
30 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER // Set `D_STR_OFF` first!
+
31 #define D_STR_CLOCK "Orologio"
+
32 #define D_STR_COMMAND "Comando"
+
33 #define D_STR_MODEL "Modello"
+
34 #define D_STR_TEMP "Temp"
+
35 #define D_STR_HUMID "Umido"
+
36 #define D_STR_SAVE "Salva"
+
37 #define D_STR_EYE "Occhio"
+
38 #define D_STR_FOLLOW "Segui"
+
39 #define D_STR_ION "Ioni"
+
40 #define D_STR_FRESH "Fresco"
+
41 #define D_STR_HOLD "Mantieni"
+
42 #define D_STR_8C_HEAT "8C " D_STR_HEAT // Set `D_STR_HEAT` first!
+
43 #define D_STR_BUTTON "Pulsante"
+
44 #define D_STR_NIGHT "Notte"
+
45 #define D_STR_SILENT "Silenzioso"
+
46 #define D_STR_FILTER "Filtro"
+
47 #define D_STR_UP "Su"
+
48 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP // Set `D_STR_TEMP` first!
+
49 #define D_STR_DOWN "Giù"
+
50 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN // Set `D_STR_TEMP` first!
+
51 #define D_STR_CHANGE "Cambia"
+
52 #define D_STR_START "Avvia"
+
53 #define D_STR_STOP "Ferma"
+
54 #define D_STR_MOVE "Muovi"
+
55 #define D_STR_SET "Imposta"
+
56 #define D_STR_CANCEL "Annulla"
+
57 #define D_STR_SENSOR "Sensore"
+
58 #define D_STR_WEEKLY "Settimanale"
+
59 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER // Needs `D_STR_WEEKLY`!
+
60 #define D_STR_LAST "Ultimo"
+
61 #define D_STR_FAST "Veloce"
+
62 #define D_STR_SLOW "Lento"
+
63 #define D_STR_AIRFLOW "Flusso d'aria"
+
64 #define D_STR_STEP "Passo"
+
65 #define D_STR_NA "N/D"
+
66 #define D_STR_OUTSIDE "Esterno"
+
67 #define D_STR_LOUD "Rumoroso"
+
68 #define D_STR_UPPER "Superiore"
+
69 #define D_STR_LOWER "Inferiore"
+
70 #define D_STR_CIRCULATE "Circolare"
+
71 #define D_STR_CEILING "Soffitto"
+
72 #define D_STR_WALL "Muro"
+
73 #define D_STR_ROOM "Camera"
+
74 #define D_STR_FIXED "Fisso"
+
75 
+
76 #define D_STR_AUTO "Auto"
+
77 #define D_STR_AUTOMATIC "Automatico"
+
78 #define D_STR_MANUAL "Manuale"
+
79 #define D_STR_COOL "Fresco"
+
80 #define D_STR_HEAT "Caldo"
+
81 #define D_STR_FAN "Ventola"
+
82 #define D_STR_FANONLY "solo_ventola"
+
83 #define D_STR_DRY "Secco"
+
84 
+
85 #define D_STR_MAX "Max"
+
86 #define D_STR_MAXIMUM "Massimo"
+
87 #define D_STR_MINIMUM "Minimo"
+
88 #define D_STR_MEDIUM "Medio"
+
89 
+
90 #define D_STR_HIGHEST "Molto alto"
+
91 #define D_STR_HIGH "Alto"
+
92 #define D_STR_MID "Med"
+
93 #define D_STR_MIDDLE "Medio"
+
94 #define D_STR_LOW "Basso"
+
95 #define D_STR_LOWEST "Bassissimo"
+
96 #define D_STR_RIGHT "Destra"
+
97 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT // Set `D_STR_MAX` first!
+
98 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX // Set `D_STR_MAX` first!
+
99 #define D_STR_LEFT "Sinistra"
+
100 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT // Set `D_STR_MAX` first!
+
101 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX // Set `D_STR_MAX` first!
+
102 #define D_STR_WIDE "Largo"
+
103 #define D_STR_CENTRE "Centro"
+
104 #define D_STR_TOP "Superiore"
+
105 #define D_STR_BOTTOM "Inferiore"
+
106 // Compound words/phrases/descriptions from pre-defined words.
+
107 // Note: Obviously these need to be defined *after* their component words.
+
108 
+
109 #define D_STR_EYEAUTO D_STR_EYE " " D_STR_AUTO
+
110 #define D_STR_LIGHTTOGGLE D_STR_LIGHT " " D_STR_TOGGLE
+
111 #define D_STR_OUTSIDEQUIET D_STR_OUTSIDE " " D_STR_QUIET
+
112 #define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE
+
113 #define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP
+
114 #define D_STR_SLEEP_TIMER D_STR_SLEEP " " D_STR_TIMER
+
115 #define D_STR_SWINGVMODE D_STR_SWINGV " " D_STR_MODE
+
116 #define D_STR_SWINGVTOGGLE D_STR_SWINGV " " D_STR_TOGGLE
+
117 // Separators
+
118 #ifndef D_CHR_TIME_SEP
+
119 #define D_CHR_TIME_SEP '.'
+
120 #endif // D_CHR_TIME_SEP
+
121 
+
122 #define D_STR_SPACELBRACE " ("
+
123 #define D_STR_COMMASPACE ", "
+
124 #define D_STR_COLONSPACE ": "
+
125 
+
126 #define D_STR_DAY "Giorno"
+
127 #define D_STR_DAYS D_STR_DAY "s"
+
128 #define D_STR_HOUR "Ore"
+
129 #define D_STR_HOURS D_STR_HOUR "s"
+
130 #define D_STR_MINUTE "Minuti"
+
131 #define D_STR_MINUTES D_STR_MINUTE "s"
+
132 #define D_STR_SECOND "Secondi"
+
133 #define D_STR_SECONDS D_STR_SECOND "s"
+
134 #define D_STR_NOW "Adesso"
+
135 #define D_STR_THREELETTERDAYS "DomLunMarMerGioVenSab"
+
136 
+
137 #define D_STR_YES "Sì"
+
138 #define D_STR_TRUE "Vero"
+
139 #define D_STR_FALSE "Falso"
+
140 
+
141 #define D_STR_REPEAT "Ripeti"
+
142 #define D_STR_CODE "Codice"
+
143 #define D_STR_BITS "Bit"
+
144 
+
145 // IRrecvDumpV2+
+
146 #define D_STR_LIBRARY "Libreria"
+
147 #define D_STR_MESGDESC "Desc. Mess."
+
148 #define D_STR_IRRECVDUMP_STARTUP \
+
149  "IRrecvDump è ora attivo e in attesa di segnali IR dal pin %d"
+
150 
+
151 #ifndef D_WARN_BUFFERFULL
+
152 #define D_WARN_BUFFERFULL \
+
153  "ATTENZIONE: il codice IR è troppo grande per il buffer (>= %d). " \
+
154  "Non fare affidamento a questi risultati finché questo problema " \
+
155  "non è risolto." \
+
156  "Modifica e aumenta `kCaptureBufferSize`."
+
157 #endif // D_WARN_BUFFERFULL
+
158 
+
159 #endif // LOCALE_IT_IT_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/jquery.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/jquery.js new file mode 100644 index 000000000..103c32d79 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/jquery.js @@ -0,0 +1,35 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element +},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** + * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler + * Licensed under MIT + * @author Ariel Flesler + * @version 2.1.2 + */ +;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/md_src_locale_README.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/md_src_locale_README.html new file mode 100644 index 000000000..2289f61b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/md_src_locale_README.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: Internationalisation (I18N) & Locale Files + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
Internationalisation (I18N) & Locale Files
+
+
+

This directory contains the files used by the library to store the text it uses. If you want to add support for a language, this is the correct place. If you are adding text strings to a routine, you should use the ones here.

+

+Changing the language/locale used by the library.

+

There are several ways to change which locale file is used by the library. Use which ever one suits your needs best. To keep the space used by the library to a minimum, all methods require the change to happen at compile time. There is no runtime option to change locales.

+

+Change <tt>_IR_LOCALE_</tt> in the <tt>src/IRremoteESP8266.h</tt> file.

+

In the IRremoteESP8266.h file, find and locate the lines that look like:

{c++}
+
#ifndef _IR_LOCALE_
+
#define _IR_LOCALE_ en-AU
+
#endif // _IR_LOCALE_
+

Change en-AU to the language & country that best suits your needs. e.g. de-DE for Germany/German.

+

+Use a compile-time build flag.

+

Use the compiler flag: -D_IR_LOCALE_=en-AU when compiling the library. Especially when compiling the IRtext.cpp file. Change en-AU to a value which matches one of the file names in this directory. e.g. de-DE for Germany/German, which will use the de_DE.h file.

+

+Use the appropriate pre-prepared build environment. _(PlatformIO only)_

+

If you examine the platformio.ini file located in the same directory as the example code you may find pre-setup compile environments for the different supported locales. Choose the appropriate one for you language by asking PlatformIO to build or upload using that environment. e.g. See IRrecvDumpV2's platformio.ini

+

+Use a custom <tt>build_flags</tt>. _(PlatformIO only)_

+

Edit the platformio.ini file in the directory containing your example/source code. Either in the default PlatformIO environment ([env]), or in which ever PlatformIO environment you using, change or add the following line:

build_flags = -D_IR_LOCALE_=en-AU ; Or use which ever locale variable you want.
+

Every time you change that line, you should do a pio clean or choose the clean option from the build menu, to ensure a fresh copy of IRtext.o is created.

+

+Adding support for a new locale/language.

+

Only ASCII/UTF-8 8-bit characters are supported. Unicode is not supported. Unicode may work. It may not. It's just not supported. i.e. If Arduino's Serial.print() can handle it, it will probably work.

+

+Copy/create a new locale file in this directory.

+

Copy en-AU.h or which every is a closer fit for your language to xx-YY.h where xx is the ISO code for the language. e.g. en is English. de is German etc. and YY is the ISO country code. e.g. AU is Australia. Modify the comments and all LOCALE_EN_AU_H_s in the file to LOCALE_XX_YY_H_ for your locale.

+

+Override any <tt>#â€define</tt> values that reside in <tt>defaults.h</tt>

+

Go through the defaults.h file, and find any #‍define lines that define a macro starting with D_ that has text that needs to change for your locale. Copy or create a corresponding #‍define D_STR_HELLOWORLD "Hello World" in your xx-YY.h file, and translate the text appropriately e.g. #‍define D_STR_HELLOWORLD "Bonjour le monde" (French)

+

Any values you #‍define in xx-YY.h will override the corresponding value in the defaults.h file.

+

+Supporting a dialect/regional variant of another <em>existing</em> language/locale.

+

Similar to the previous step, if you only need to modify a small subset of the strings used in another locale file, then include the other locale file and then make sure to #‍undef any strings that need to be (re-)changed. See the Swiss-German for an example of how to do this. i.e. It #‍include "locale/de-DE.h"s the German locale, and redefines any strings that are not standard German.

+

+Adding new text strings to the library.

+

If you need to add an entirely new string to the library to support some feature etc. e.g. _"Widget"_. You should first understand how the library tries to do this such that it is easy to support different languages for it.

+
    +
  1. Use a constant named kWidgetStr in the appropriate statement in the .cpp file.
  2. +
  3. Edit IRtext.cpp, and add the appropriate line for your new constant. e.g.
    {c++}
    +
    String kWidgetStr = D_STR_WIDGET;
    +
  4. +
+

The kWidgetStr variable will house the sole copy of the string for the entire library. This limits any duplication. The D_STR_WIDGET macro will be what is targeted by the different language / locales files.

+
    +
  1. Edit locale/defaults.h, and add the appropriate stanza for your new string. e.g.
    {c++}
    +
    #ifndef D_STR_WIDGET
    +
    #define D_STR_WIDGET "Turbo"
    +
    #endif // D_STR_WIDGET
    +
  2. +
  3. _(Manual)_ Update IRtext.h, and add the appropriate line for your new constant. e.g.
    {c++}
    +
    extern const String kWidgetStr;
    +
  4. +
+

For any file that #‍include <IRtext.h>s this file, it will tell it that the string is stored elsewhere, and to look for it elsewhere at the object linking stage of the build. This is what makes the string be referenced from a central location.

+
    +
  1. _(Automatic)_ Run tools/generate_irtext_h.sh to update IRtext.h. In the src/locale directory. Run the ../../tools/generate_irtext_h.sh command. It will update the file for you automatically.
  2. +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menu.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menu.js new file mode 100644 index 000000000..433c15b8f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menu.js @@ -0,0 +1,50 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { + function makeTree(data,relPath) { + var result=''; + if ('children' in data) { + result+=''; + } + return result; + } + + $('#main-nav').append(makeTree(menudata,relPath)); + $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + if (searchEnabled) { + if (serverSide) { + $('#main-menu').append('
  • '); + } else { + $('#main-menu').append('
  • '); + } + } + $('#main-menu').smartmenus(); +} +/* @license-end */ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menudata.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menudata.js new file mode 100644 index 000000000..f6289d4dd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menudata.js @@ -0,0 +1,189 @@ +/* +@licstart The following is the entire license notice for the +JavaScript code in this file. + +Copyright (C) 1997-2019 by Dimitri van Heesch + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as published by +the Free Software Foundation + +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, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +@licend The above is the entire license notice +for the JavaScript code in this file +*/ +var menudata={children:[ +{text:"Main Page",url:"index.html"}, +{text:"Related Pages",url:"pages.html"}, +{text:"Namespaces",url:"namespaces.html",children:[ +{text:"Namespace List",url:"namespaces.html"}, +{text:"Namespace Members",url:"namespacemembers.html",children:[ +{text:"All",url:"namespacemembers.html",children:[ +{text:"a",url:"namespacemembers.html#index_a"}, +{text:"b",url:"namespacemembers.html#index_b"}, +{text:"d",url:"namespacemembers.html#index_d"}, +{text:"f",url:"namespacemembers.html#index_f"}, +{text:"g",url:"namespacemembers.html#index_g"}, +{text:"h",url:"namespacemembers.html#index_h"}, +{text:"m",url:"namespacemembers.html#index_m"}, +{text:"o",url:"namespacemembers.html#index_o"}, +{text:"r",url:"namespacemembers.html#index_r"}, +{text:"s",url:"namespacemembers.html#index_s"}, +{text:"u",url:"namespacemembers.html#index_u"}]}, +{text:"Functions",url:"namespacemembers_func.html"}, +{text:"Enumerations",url:"namespacemembers_enum.html"}]}]}, +{text:"Classes",url:"annotated.html",children:[ +{text:"Class List",url:"annotated.html"}, +{text:"Class Index",url:"classes.html"}, +{text:"Class Hierarchy",url:"inherits.html"}, +{text:"Class Members",url:"functions.html",children:[ +{text:"All",url:"functions.html",children:[ +{text:"_",url:"functions.html#index__5F"}, +{text:"a",url:"functions_a.html#index_a"}, +{text:"b",url:"functions_b.html#index_b"}, +{text:"c",url:"functions_c.html#index_c"}, +{text:"d",url:"functions_d.html#index_d"}, +{text:"e",url:"functions_e.html#index_e"}, +{text:"f",url:"functions_f.html#index_f"}, +{text:"g",url:"functions_g.html#index_g"}, +{text:"h",url:"functions_h.html#index_h"}, +{text:"i",url:"functions_i.html#index_i"}, +{text:"k",url:"functions_k.html#index_k"}, +{text:"l",url:"functions_l.html#index_l"}, +{text:"m",url:"functions_m.html#index_m"}, +{text:"n",url:"functions_n.html#index_n"}, +{text:"o",url:"functions_o.html#index_o"}, +{text:"p",url:"functions_p.html#index_p"}, +{text:"q",url:"functions_q.html#index_q"}, +{text:"r",url:"functions_r.html#index_r"}, +{text:"s",url:"functions_s.html#index_s"}, +{text:"t",url:"functions_t.html#index_t"}, +{text:"u",url:"functions_u.html#index_u"}, +{text:"v",url:"functions_v.html#index_v"}, +{text:"w",url:"functions_w.html#index_w"}, +{text:"z",url:"functions_z.html#index_z"}, +{text:"~",url:"functions_~.html#index__7E"}]}, +{text:"Functions",url:"functions_func.html",children:[ +{text:"_",url:"functions_func.html#index__5F"}, +{text:"a",url:"functions_func_a.html#index_a"}, +{text:"b",url:"functions_func_b.html#index_b"}, +{text:"c",url:"functions_func_c.html#index_c"}, +{text:"d",url:"functions_func_d.html#index_d"}, +{text:"e",url:"functions_func_e.html#index_e"}, +{text:"f",url:"functions_func_f.html#index_f"}, +{text:"g",url:"functions_func_g.html#index_g"}, +{text:"h",url:"functions_func_h.html#index_h"}, +{text:"i",url:"functions_func_i.html#index_i"}, +{text:"k",url:"functions_func_k.html#index_k"}, +{text:"l",url:"functions_func_l.html#index_l"}, +{text:"m",url:"functions_func_m.html#index_m"}, +{text:"n",url:"functions_func_n.html#index_n"}, +{text:"o",url:"functions_func_o.html#index_o"}, +{text:"p",url:"functions_func_p.html#index_p"}, +{text:"r",url:"functions_func_r.html#index_r"}, +{text:"s",url:"functions_func_s.html#index_s"}, +{text:"t",url:"functions_func_t.html#index_t"}, +{text:"u",url:"functions_func_u.html#index_u"}, +{text:"v",url:"functions_func_v.html#index_v"}, +{text:"w",url:"functions_func_w.html#index_w"}, +{text:"~",url:"functions_func_~.html#index__7E"}]}, +{text:"Variables",url:"functions_vars.html",children:[ +{text:"_",url:"functions_vars.html#index__5F"}, +{text:"a",url:"functions_vars.html#index_a"}, +{text:"b",url:"functions_vars.html#index_b"}, +{text:"c",url:"functions_vars.html#index_c"}, +{text:"d",url:"functions_vars.html#index_d"}, +{text:"e",url:"functions_vars.html#index_e"}, +{text:"f",url:"functions_vars.html#index_f"}, +{text:"h",url:"functions_vars.html#index_h"}, +{text:"i",url:"functions_vars.html#index_i"}, +{text:"l",url:"functions_vars.html#index_l"}, +{text:"m",url:"functions_vars.html#index_m"}, +{text:"n",url:"functions_vars.html#index_n"}, +{text:"o",url:"functions_vars.html#index_o"}, +{text:"p",url:"functions_vars.html#index_p"}, +{text:"q",url:"functions_vars.html#index_q"}, +{text:"r",url:"functions_vars.html#index_r"}, +{text:"s",url:"functions_vars.html#index_s"}, +{text:"t",url:"functions_vars.html#index_t"}, +{text:"u",url:"functions_vars.html#index_u"}, +{text:"v",url:"functions_vars.html#index_v"}, +{text:"w",url:"functions_vars.html#index_w"}, +{text:"z",url:"functions_vars.html#index_z"}]}, +{text:"Related Functions",url:"functions_rela.html"}]}]}, +{text:"Files",url:"files.html",children:[ +{text:"File List",url:"files.html"}, +{text:"File Members",url:"globals.html",children:[ +{text:"All",url:"globals.html",children:[ +{text:"_",url:"globals.html#index__5F"}, +{text:"a",url:"globals_a.html#index_a"}, +{text:"c",url:"globals_c.html#index_c"}, +{text:"d",url:"globals_d.html#index_d"}, +{text:"e",url:"globals_e.html#index_e"}, +{text:"f",url:"globals_f.html#index_f"}, +{text:"g",url:"globals_g.html#index_g"}, +{text:"h",url:"globals_h.html#index_h"}, +{text:"i",url:"globals_i.html#index_i"}, +{text:"j",url:"globals_j.html#index_j"}, +{text:"k",url:"globals_k.html#index_k"}, +{text:"l",url:"globals_l.html#index_l"}, +{text:"m",url:"globals_m.html#index_m"}, +{text:"n",url:"globals_n.html#index_n"}, +{text:"p",url:"globals_p.html#index_p"}, +{text:"r",url:"globals_r.html#index_r"}, +{text:"s",url:"globals_s.html#index_s"}, +{text:"t",url:"globals_t.html#index_t"}, +{text:"u",url:"globals_u.html#index_u"}, +{text:"v",url:"globals_v.html#index_v"}, +{text:"w",url:"globals_w.html#index_w"}, +{text:"x",url:"globals_x.html#index_x"}, +{text:"y",url:"globals_y.html#index_y"}, +{text:"z",url:"globals_z.html#index_z"}]}, +{text:"Functions",url:"globals_func.html",children:[ +{text:"c",url:"globals_func.html#index_c"}, +{text:"f",url:"globals_func.html#index_f"}, +{text:"g",url:"globals_func.html#index_g"}, +{text:"h",url:"globals_func.html#index_h"}, +{text:"i",url:"globals_func.html#index_i"}, +{text:"r",url:"globals_func.html#index_r"}, +{text:"s",url:"globals_func.html#index_s"}, +{text:"t",url:"globals_func.html#index_t"}, +{text:"u",url:"globals_func.html#index_u"}, +{text:"x",url:"globals_func.html#index_x"}]}, +{text:"Variables",url:"globals_vars.html",children:[ +{text:"_",url:"globals_vars.html#index__5F"}, +{text:"i",url:"globals_vars_i.html#index_i"}, +{text:"k",url:"globals_vars_k.html#index_k"}]}, +{text:"Typedefs",url:"globals_type.html"}, +{text:"Enumerations",url:"globals_enum.html"}, +{text:"Enumerator",url:"globals_eval.html",children:[ +{text:"a",url:"globals_eval.html#index_a"}, +{text:"c",url:"globals_eval.html#index_c"}, +{text:"d",url:"globals_eval.html#index_d"}, +{text:"e",url:"globals_eval.html#index_e"}, +{text:"f",url:"globals_eval.html#index_f"}, +{text:"g",url:"globals_eval.html#index_g"}, +{text:"h",url:"globals_eval.html#index_h"}, +{text:"i",url:"globals_eval.html#index_i"}, +{text:"j",url:"globals_eval.html#index_j"}, +{text:"k",url:"globals_eval.html#index_k"}, +{text:"l",url:"globals_eval.html#index_l"}, +{text:"m",url:"globals_eval.html#index_m"}, +{text:"n",url:"globals_eval.html#index_n"}, +{text:"p",url:"globals_eval.html#index_p"}, +{text:"r",url:"globals_eval.html#index_r"}, +{text:"s",url:"globals_eval.html#index_s"}, +{text:"t",url:"globals_eval.html#index_t"}, +{text:"u",url:"globals_eval.html#index_u"}, +{text:"v",url:"globals_eval.html#index_v"}, +{text:"w",url:"globals_eval.html#index_w"}, +{text:"y",url:"globals_eval.html#index_y"}, +{text:"z",url:"globals_eval.html#index_z"}]}]}]}]} diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceIRAcUtils.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceIRAcUtils.html new file mode 100644 index 000000000..3813acb54 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceIRAcUtils.html @@ -0,0 +1,161 @@ + + + + + + + +IRremoteESP8266: IRAcUtils Namespace Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    IRAcUtils Namespace Reference
    +
    +
    + + + + + + + + +

    +Functions

    String resultAcToString (const decode_results *const result)
     Display the human readable state of an A/C message if we can. More...
     
    bool decodeToState (const decode_results *decode, stdAc::state_t *result, const stdAc::state_t *prev)
     Convert a valid IR A/C remote message that we understand enough into a Common A/C state. More...
     
    +

    Function Documentation

    + +

    ◆ decodeToState()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    bool IRAcUtils::decodeToState (const decode_resultsdecode,
    stdAc::state_tresult,
    const stdAc::state_tprev 
    )
    +
    + +

    Convert a valid IR A/C remote message that we understand enough into a Common A/C state.

    +
    Parameters
    + + + + +
    [in]decodeA PTR to a successful raw IR decode object.
    [in]resultA PTR to a state structure to store the result in.
    [in]prevA PTR to a state structure which has the prev. state.
    +
    +
    +
    Returns
    A boolean indicating success or failure.
    + +
    +
    + +

    ◆ resultAcToString()

    + +
    +
    + + + + + + + + +
    String IRAcUtils::resultAcToString (const decode_results *const result)
    +
    + +

    Display the human readable state of an A/C message if we can.

    +
    Parameters
    + + +
    [in]resultA Ptr to the captured decode_results that contains an A/C mesg.
    +
    +
    +
    Returns
    A string with the human description of the A/C message. An empty string if we can't.
    + +
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceirutils.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceirutils.html new file mode 100644 index 000000000..296bae1d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceirutils.html @@ -0,0 +1,1303 @@ + + + + + + + +IRremoteESP8266: irutils Namespace Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    irutils Namespace Reference
    +
    +
    + +

    Namespace for covering common functions & procedures for advancd protocol handlers. +More...

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Functions

    String addLabeledString (const String value, const String label, const bool precomma)
     Create a String with a colon separated "label: value" pair suitable for Humans. More...
     
    String addBoolToString (const bool value, const String label, const bool precomma)
     Create a String with a colon separated flag suitable for Humans. e.g. "Power: On". More...
     
    String addIntToString (const uint16_t value, const String label, const bool precomma)
     Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23". More...
     
    String modelToStr (const decode_type_t protocol, const int16_t model)
     Generate the model string for a given Protocol/Model pair. More...
     
    String addModelToString (const decode_type_t protocol, const int16_t model, const bool precomma)
     Create a String of human output for a given protocol model number. e.g. "Model: JKE". More...
     
    String addTempToString (const uint16_t degrees, const bool celsius, const bool precomma)
     Create a String of human output for a given temperature. e.g. "Temp: 25C". More...
     
    String addModeToString (const uint8_t mode, const uint8_t automatic, const uint8_t cool, const uint8_t heat, const uint8_t dry, const uint8_t fan)
     Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)". More...
     
    String addDayToString (const uint8_t day_of_week, const int8_t offset, const bool precomma)
     Create a String of the 3-letter day of the week from a numerical day of the week. e.g. "Day: 1 (Mon)". More...
     
    String addFanToString (const uint8_t speed, const uint8_t high, const uint8_t low, const uint8_t automatic, const uint8_t quiet, const uint8_t medium)
     Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)". More...
     
    String htmlEscape (const String unescaped)
     Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS. More...
     
    String msToString (uint32_t const msecs)
     Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds". More...
     
    String minsToString (const uint16_t mins)
     Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59". More...
     
    uint8_t sumNibbles (const uint8_t *const start, const uint16_t length, const uint8_t init)
     Sum all the nibbles together in a series of bytes. More...
     
    uint8_t sumNibbles (const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)
     Sum all the nibbles together in an integer. More...
     
    uint8_t bcdToUint8 (const uint8_t bcd)
     Convert a byte of Binary Coded Decimal(BCD) into an Integer. More...
     
    uint8_t uint8ToBcd (const uint8_t integer)
     Convert an Integer into a byte of Binary Coded Decimal(BCD). More...
     
    bool getBit (const uint64_t data, const uint8_t position, const uint8_t size)
     Return the value of positionth bit of an Integer. More...
     
    bool getBit (const uint8_t data, const uint8_t position)
     Return the value of positionth bit of an Integer. More...
     
    uint64_t setBit (const uint64_t data, const uint8_t position, const bool on, const uint8_t size)
     Return the value of an Integer with the positionth bit changed. More...
     
    uint8_t setBit (const uint8_t data, const uint8_t position, const bool on)
     Return the value of an Integer with the positionth bit changed. More...
     
    void setBit (uint8_t *const data, const uint8_t position, const bool on)
     Alter the value of an Integer with the positionth bit changed. More...
     
    void setBit (uint32_t *const data, const uint8_t position, const bool on)
     Alter the value of an Integer with the positionth bit changed. More...
     
    void setBit (uint64_t *const data, const uint8_t position, const bool on)
     Alter the value of an Integer with the positionth bit changed. More...
     
    void setBits (uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)
     Alter an uint8_t value by overwriting an arbitary given number of bits. More...
     
    void setBits (uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)
     Alter an uint32_t value by overwriting an arbitary given number of bits. More...
     
    void setBits (uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)
     Alter an uint64_t value by overwriting an arbitary given number of bits. More...
     
    +

    Detailed Description

    +

    Namespace for covering common functions & procedures for advancd protocol handlers.

    +

    Function Documentation

    + +

    ◆ addBoolToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addBoolToString (const bool value,
    const String label,
    const bool precomma 
    )
    +
    + +

    Create a String with a colon separated flag suitable for Humans. e.g. "Power: On".

    +
    Parameters
    + + + + +
    [in]valueThe value to come after the label.
    [in]labelThe label to precede the value.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addDayToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addDayToString (const uint8_t day_of_week,
    const int8_t offset,
    const bool precomma 
    )
    +
    + +

    Create a String of the 3-letter day of the week from a numerical day of the week. e.g. "Day: 1 (Mon)".

    +
    Parameters
    + + + + +
    [in]day_of_weekA numerical version of the sequential day of the week. e.g. Saturday = 7 etc.
    [in]offsetDays to offset by. e.g. For different day starting the week.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addFanToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addFanToString (const uint8_t speed,
    const uint8_t high,
    const uint8_t low,
    const uint8_t automatic,
    const uint8_t quiet,
    const uint8_t medium 
    )
    +
    + +

    Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)".

    +
    Parameters
    + + + + + + + +
    [in]speedThe numeric speed of the fan to display.
    [in]highThe numeric value for High speed.
    [in]lowThe numeric value for Low speed.
    [in]automaticThe numeric value for Auto speed.
    [in]quietThe numeric value for Quiet speed.
    [in]mediumThe numeric value for Medium speed.
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addIntToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addIntToString (const uint16_t value,
    const String label,
    const bool precomma 
    )
    +
    + +

    Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23".

    +
    Parameters
    + + + + +
    [in]valueThe value to come after the label.
    [in]labelThe label to precede the value.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addLabeledString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addLabeledString (const String value,
    const String label,
    const bool precomma 
    )
    +
    + +

    Create a String with a colon separated "label: value" pair suitable for Humans.

    +
    Parameters
    + + + + +
    [in]valueThe value to come after the label.
    [in]labelThe label to precede the value.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addModelToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addModelToString (const decode_type_t protocol,
    const int16_t model,
    const bool precomma 
    )
    +
    + +

    Create a String of human output for a given protocol model number. e.g. "Model: JKE".

    +
    Parameters
    + + + + +
    [in]protocolThe IR protocol.
    [in]modelThe model number for that protocol.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addModeToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addModeToString (const uint8_t mode,
    const uint8_t automatic,
    const uint8_t cool,
    const uint8_t heat,
    const uint8_t dry,
    const uint8_t fan 
    )
    +
    + +

    Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)".

    +
    Parameters
    + + + + + + + +
    [in]modeThe operating mode to display.
    [in]automaticThe numeric value for Auto mode.
    [in]coolThe numeric value for Cool mode.
    [in]heatThe numeric value for Heat mode.
    [in]dryThe numeric value for Dry mode.
    [in]fanThe numeric value for Fan mode.
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addTempToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addTempToString (const uint16_t degrees,
    const bool celsius,
    const bool precomma 
    )
    +
    + +

    Create a String of human output for a given temperature. e.g. "Temp: 25C".

    +
    Parameters
    + + + + +
    [in]degreesThe temperature in degrees.
    [in]celsiusIs the temp Celsius or Fahrenheit. true is C, false is F
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ bcdToUint8()

    + +
    +
    + + + + + + + + +
    uint8_t irutils::bcdToUint8 (const uint8_t bcd)
    +
    + +

    Convert a byte of Binary Coded Decimal(BCD) into an Integer.

    +
    Parameters
    + + +
    [in]bcdThe BCD value.
    +
    +
    +
    Returns
    A normal Integer value.
    + +
    +
    + +

    ◆ getBit() [1/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    bool irutils::getBit (const uint64_t data,
    const uint8_t position,
    const uint8_t size 
    )
    +
    + +

    Return the value of positionth bit of an Integer.

    +
    Parameters
    + + + + +
    [in]dataValue to be examined.
    [in]positionNr. of the Nth bit to be examined. 0 is the LSB.
    [in]sizeNr. of bits in data.
    +
    +
    +
    Returns
    The bit's value.
    + +
    +
    + +

    ◆ getBit() [2/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    bool irutils::getBit (const uint8_t data,
    const uint8_t position 
    )
    +
    + +

    Return the value of positionth bit of an Integer.

    +
    Parameters
    + + + +
    [in]dataValue to be examined.
    [in]positionNr. of the Nth bit to be examined. 0 is the LSB.
    +
    +
    +
    Returns
    The bit's value.
    + +
    +
    + +

    ◆ htmlEscape()

    + +
    +
    + + + + + + + + +
    String irutils::htmlEscape (const String unescaped)
    +
    + +

    Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS.

    +
    Parameters
    + + +
    [in]unescapedA String containing text to make HTML safe.
    +
    +
    +
    Returns
    A string that is HTML safe.
    + +
    +
    + +

    ◆ minsToString()

    + +
    +
    + + + + + + + + +
    String irutils::minsToString (const uint16_t mins)
    +
    + +

    Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59".

    +
    Parameters
    + + +
    [in]minsNr. of Minutes.
    +
    +
    +
    Returns
    A human readable string.
    + +
    +
    + +

    ◆ modelToStr()

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    String irutils::modelToStr (const decode_type_t protocol,
    const int16_t model 
    )
    +
    + +

    Generate the model string for a given Protocol/Model pair.

    +
    Parameters
    + + + +
    [in]protocolThe IR protocol.
    [in]modelThe model number for that protocol.
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ msToString()

    + +
    +
    + + + + + + + + +
    String irutils::msToString (uint32_t const msecs)
    +
    + +

    Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds".

    +
    Parameters
    + + +
    [in]msecsNr. of milliSeconds (ms).
    +
    +
    +
    Returns
    A human readable string.
    + +
    +
    + +

    ◆ setBit() [1/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    uint64_t irutils::setBit (const uint64_t data,
    const uint8_t position,
    const bool on,
    const uint8_t size 
    )
    +
    + +

    Return the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + + +
    [in]dataValue to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    [in]sizeNr. of bits in data.
    +
    +
    +
    Returns
    A suitably modified integer.
    + +
    +
    + +

    ◆ setBit() [2/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    uint8_t irutils::setBit (const uint8_t data,
    const uint8_t position,
    const bool on 
    )
    +
    + +

    Return the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + +
    [in]dataValue to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    +
    +
    +
    Returns
    A suitably modified integer.
    + +
    +
    + +

    ◆ setBit() [3/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBit (uint32_t *const data,
    const uint8_t position,
    const bool on 
    )
    +
    + +

    Alter the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + +
    [in,out]dataA pointer to the 32-bit integer to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    +
    +
    + +
    +
    + +

    ◆ setBit() [4/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBit (uint64_t *const data,
    const uint8_t position,
    const bool on 
    )
    +
    + +

    Alter the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + +
    [in,out]dataA pointer to the 64-bit integer to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    +
    +
    + +
    +
    + +

    ◆ setBit() [5/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBit (uint8_t *const data,
    const uint8_t position,
    const bool on 
    )
    +
    + +

    Alter the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + +
    [in,out]dataA pointer to the 8-bit integer to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    +
    +
    + +
    +
    + +

    ◆ setBits() [1/3]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBits (uint32_t *const dst,
    const uint8_t offset,
    const uint8_t nbits,
    const uint32_t data 
    )
    +
    + +

    Alter an uint32_t value by overwriting an arbitary given number of bits.

    +
    Parameters
    + + + + + +
    [in,out]dstA pointer to the value to be changed.
    [in]offsetNr. of bits from the Least Significant Bit to be ignored
    [in]nbitsNr of bits of data to be placed into the destination.
    [in]dataThe value to be placed.
    +
    +
    + +
    +
    + +

    ◆ setBits() [2/3]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBits (uint64_t *const dst,
    const uint8_t offset,
    const uint8_t nbits,
    const uint64_t data 
    )
    +
    + +

    Alter an uint64_t value by overwriting an arbitary given number of bits.

    +
    Parameters
    + + + + + +
    [in,out]dstA pointer to the value to be changed.
    [in]offsetNr. of bits from the Least Significant Bit to be ignored
    [in]nbitsNr of bits of data to be placed into the destination.
    [in]dataThe value to be placed.
    +
    +
    + +
    +
    + +

    ◆ setBits() [3/3]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBits (uint8_t *const dst,
    const uint8_t offset,
    const uint8_t nbits,
    const uint8_t data 
    )
    +
    + +

    Alter an uint8_t value by overwriting an arbitary given number of bits.

    +
    Parameters
    + + + + + +
    [in,out]dstA pointer to the value to be changed.
    [in]offsetNr. of bits from the Least Significant Bit to be ignored
    [in]nbitsNr of bits of data to be placed into the destination.
    [in]dataThe value to be placed.
    +
    +
    + +
    +
    + +

    ◆ sumNibbles() [1/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    uint8_t irutils::sumNibbles (const uint64_t data,
    const uint8_t count,
    const uint8_t init,
    const bool nibbleonly 
    )
    +
    + +

    Sum all the nibbles together in an integer.

    +
    Parameters
    + + + + + +
    [in]dataThe integer to be summed.
    [in]countThe number of nibbles to sum. Starts from LSB. Max of 16.
    [in]initStarting value of the calculation to use. (Default is 0)
    [in]nibbleonlytrue, the result is 4 bits. false, it's 8 bits.
    +
    +
    +
    Returns
    The 4/8-bit calculated result of all the nibbles and init value.
    + +
    +
    + +

    ◆ sumNibbles() [2/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    uint8_t irutils::sumNibbles (const uint8_t *const start,
    const uint16_t length,
    const uint8_t init 
    )
    +
    + +

    Sum all the nibbles together in a series of bytes.

    +
    Parameters
    + + + + +
    [in]startA ptr to the start of the byte array to calculate over.
    [in]lengthHow many bytes to use in the calculation.
    [in]initStarting value of the calculation to use. (Default is 0)
    +
    +
    +
    Returns
    The 8-bit calculated result of all the bytes and init value.
    + +
    +
    + +

    ◆ uint8ToBcd()

    + +
    +
    + + + + + + + + +
    uint8_t irutils::uint8ToBcd (const uint8_t integer)
    +
    + +

    Convert an Integer into a byte of Binary Coded Decimal(BCD).

    +
    Parameters
    + + +
    [in]integerThe number to convert.
    +
    +
    +
    Returns
    An 8-bit BCD value.
    + +
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers.html new file mode 100644 index 000000000..894fdde87 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers.html @@ -0,0 +1,188 @@ + + + + + + + +IRremoteESP8266: Namespace Members + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    Here is a list of all namespace members with links to the namespace documentation for each member:
    + +

    - a -

    + + +

    - b -

    + + +

    - d -

    + + +

    - f -

      +
    • fanspeed_t +: stdAc +
    • +
    + + +

    - g -

    + + +

    - h -

    + + +

    - m -

    + + +

    - o -

    + + +

    - r -

    + + +

    - s -

    + + +

    - u -

    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_enum.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_enum.html new file mode 100644 index 000000000..20b291697 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_enum.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: Namespace Members + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_func.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_func.html new file mode 100644 index 000000000..2e79392e0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_func.html @@ -0,0 +1,134 @@ + + + + + + + +IRremoteESP8266: Namespace Members + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaces.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaces.html new file mode 100644 index 000000000..5112518f1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaces.html @@ -0,0 +1,83 @@ + + + + + + + +IRremoteESP8266: Namespace List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    +
    Namespace List
    +
    +
    +
    Here is a list of all namespaces with brief descriptions:
    + + + + +
     NIRAcUtils
     NirutilsNamespace for covering common functions & procedures for advancd protocol handlers
     NstdAcEnumerators and Structures for the Common A/C API
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacestdAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacestdAc.html new file mode 100644 index 000000000..59ba02326 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacestdAc.html @@ -0,0 +1,286 @@ + + + + + + + +IRremoteESP8266: stdAc Namespace Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    stdAc Namespace Reference
    +
    +
    + +

    Enumerators and Structures for the Common A/C API. +More...

    + + + + + +

    +Classes

    struct  state_t
     Structure to hold a common A/C state. More...
     
    + + + + + + + + + + + + + +

    +Enumerations

    enum  opmode_t {
    +  opmode_t::kOff = -1, +opmode_t::kAuto = 0, +opmode_t::kCool = 1, +opmode_t::kHeat = 2, +
    +  opmode_t::kDry = 3, +opmode_t::kFan = 4, +opmode_t::kLastOpmodeEnum = kFan +
    + }
     Common A/C settings for A/C operating modes. More...
     
    enum  fanspeed_t {
    +  fanspeed_t::kAuto = 0, +fanspeed_t::kMin = 1, +fanspeed_t::kLow = 2, +fanspeed_t::kMedium = 3, +
    +  fanspeed_t::kHigh = 4, +fanspeed_t::kMax = 5, +fanspeed_t::kLastFanspeedEnum = kMax +
    + }
     Common A/C settings for Fan Speeds. More...
     
    enum  swingv_t {
    +  swingv_t::kOff = -1, +swingv_t::kAuto = 0, +swingv_t::kHighest = 1, +swingv_t::kHigh = 2, +
    +  swingv_t::kMiddle = 3, +swingv_t::kLow = 4, +swingv_t::kLowest = 5, +swingv_t::kLastSwingvEnum = kLowest +
    + }
     Common A/C settings for Vertical Swing. More...
     
    enum  swingh_t {
    +  swingh_t::kOff = -1, +swingh_t::kAuto = 0, +swingh_t::kLeftMax = 1, +swingh_t::kLeft = 2, +
    +  swingh_t::kMiddle = 3, +swingh_t::kRight = 4, +swingh_t::kRightMax = 5, +swingh_t::kWide = 6, +
    +  swingh_t::kLastSwinghEnum = kWide +
    + }
     Common A/C settings for Horizontal Swing. More...
     
    +

    Detailed Description

    +

    Enumerators and Structures for the Common A/C API.

    +

    Enumeration Type Documentation

    + +

    ◆ fanspeed_t

    + +
    +
    + + + + + +
    + + + + +
    enum stdAc::fanspeed_t
    +
    +strong
    +
    + +

    Common A/C settings for Fan Speeds.

    + + + + + + + + +
    Enumerator
    kAuto 
    kMin 
    kLow 
    kMedium 
    kHigh 
    kMax 
    kLastFanspeedEnum 
    + +
    +
    + +

    ◆ opmode_t

    + +
    +
    + + + + + +
    + + + + +
    enum stdAc::opmode_t
    +
    +strong
    +
    + +

    Common A/C settings for A/C operating modes.

    + + + + + + + + +
    Enumerator
    kOff 
    kAuto 
    kCool 
    kHeat 
    kDry 
    kFan 
    kLastOpmodeEnum 
    + +
    +
    + +

    ◆ swingh_t

    + +
    +
    + + + + + +
    + + + + +
    enum stdAc::swingh_t
    +
    +strong
    +
    + +

    Common A/C settings for Horizontal Swing.

    + + + + + + + + + + +
    Enumerator
    kOff 
    kAuto 
    kLeftMax 
    kLeft 
    kMiddle 
    kRight 
    kRightMax 
    kWide 
    kLastSwinghEnum 
    + +
    +
    + +

    ◆ swingv_t

    + +
    +
    + + + + + +
    + + + + +
    enum stdAc::swingv_t
    +
    +strong
    +
    + +

    Common A/C settings for Vertical Swing.

    + + + + + + + + + +
    Enumerator
    kOff 
    kAuto 
    kHighest 
    kHigh 
    kMiddle 
    kLow 
    kLowest 
    kLastSwingvEnum 
    + +
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_f.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_g.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + + +IRremoteESP8266: Related Pages + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    +
    Related Pages
    +
    +
    +
    Here is a list of all related documentation pages:
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.html new file mode 100644 index 000000000..26dd244fd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.js new file mode 100644 index 000000000..0be3721bd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.js @@ -0,0 +1,50 @@ +var searchData= +[ + ['_5fcancelofftimer_0',['_cancelOffTimer',['../classIRCarrierAc64.html#a4a0fdf34836b1c954b27c9b242324679',1,'IRCarrierAc64']]], + ['_5fcancelontimer_1',['_cancelOnTimer',['../classIRCarrierAc64.html#a43e7be5a1a6fe2dbfe245e99d2205779',1,'IRCarrierAc64']]], + ['_5fclean_2',['_clean',['../classIRFujitsuAC.html#acf7808cfeb6e15cea1d5ee8196075e04',1,'IRFujitsuAC']]], + ['_5fcmd_3',['_cmd',['../classIRFujitsuAC.html#a5e66bc4a24b892525cfa02bb4d741cbf',1,'IRFujitsuAC']]], + ['_5fdelaymicroseconds_4',['_delayMicroseconds',['../classIRsend.html#a61ceb32aa53f538b93377b10e58b45c9',1,'IRsend']]], + ['_5fdesiredtemp_5',['_desiredtemp',['../classIRWhirlpoolAc.html#aee17cfa10f19e0df992b25cff58e9613',1,'IRWhirlpoolAc']]], + ['_5fdutycycle_6',['_dutycycle',['../classIRsend.html#a602e96e8cdbd6af41d288d905043e51f',1,'IRsend']]], + ['_5ffan_7',['_fan',['../classIRSharpAc.html#ad0f4e6025f2952c477bbd3f72a64d2fe',1,'IRSharpAc']]], + ['_5ffanspeed_8',['_fanSpeed',['../classIRFujitsuAC.html#a537f02328039c044f7152bf0a61a05c9',1,'IRFujitsuAC']]], + ['_5ffilter_9',['_filter',['../classIRFujitsuAC.html#a4a2f96f4f1cd6650d48ebc3b13fd561c',1,'IRFujitsuAC']]], + ['_5fforcepower_10',['_forcepower',['../classIRSamsungAc.html#a022c96bfab671b1d0b6b5b331be31993',1,'IRSamsungAc']]], + ['_5ffreq_5funittest_11',['_freq_unittest',['../classIRsend.html#a2caec2f35ecdb890b1e34d9eb3642363',1,'IRsend']]], + ['_5fgettime_12',['_getTime',['../classIRPanasonicAc.html#ab0a592b759daf90be548ac69ae99f40f',1,'IRPanasonicAc']]], + ['_5fgettimer_13',['_getTimer',['../classIRCoronaAc.html#a419053fbf9ef27e937db0ff7519927bd',1,'IRCoronaAc::_getTimer()'],['../classIRVestelAc.html#ad3f095d248ad3c84a777ed9f2d3b001e',1,'IRVestelAc::_getTimer()']]], + ['_5finverted_14',['_inverted',['../classIRac.html#a9cfaa0b92819f06b3aa5b3e9e48b9d51',1,'IRac']]], + ['_5firsend_15',['_irsend',['../classIRAmcorAc.html#a6245bb51fa206031c3348e3eb6cb096d',1,'IRAmcorAc::_irsend()'],['../classIRArgoAC.html#a1abd8d958c3e153c4f2aaf7a3716414e',1,'IRArgoAC::_irsend()'],['../classIRCarrierAc64.html#a17270f2b1d6cab828e2a51fc23b36437',1,'IRCarrierAc64::_irsend()'],['../classIRCoolixAC.html#a6c7033e72fb860bca600ba6ea6e7afef',1,'IRCoolixAC::_irsend()'],['../classIRCoronaAc.html#afba5a3c3cff3859303a91d136ad00b66',1,'IRCoronaAc::_irsend()'],['../classIRDaikinESP.html#a2f5a8cb170d54f06bfa3eeb9b8ff838e',1,'IRDaikinESP::_irsend()'],['../classIRDaikin2.html#aa8ba00ae2c09af098146452164c4cb3b',1,'IRDaikin2::_irsend()'],['../classIRDaikin216.html#ac0e88b92a5c75138ce5b3a31f0c09be2',1,'IRDaikin216::_irsend()'],['../classIRDaikin160.html#a3094f35b359d8774a95dd3896c0e45e4',1,'IRDaikin160::_irsend()'],['../classIRDaikin176.html#a24f7022eb1c1936f5ee95ac0d732584c',1,'IRDaikin176::_irsend()'],['../classIRDaikin128.html#a1f155cc34e6c21d206962239d0135d1b',1,'IRDaikin128::_irsend()'],['../classIRDaikin152.html#a9b203215156d48dabac0fa8fd19dc613',1,'IRDaikin152::_irsend()'],['../classIRDaikin64.html#a6eb57b0eb12dab12bd9cf2fe4fded2c7',1,'IRDaikin64::_irsend()'],['../classIRDelonghiAc.html#a8cbe8b6857b7492c108118b4eda3ecb0',1,'IRDelonghiAc::_irsend()'],['../classIRElectraAc.html#af8732b31f2a4421226220dd8a4a4f985',1,'IRElectraAc::_irsend()'],['../classIRFujitsuAC.html#a2b7fec218b3530b06ce8b49f472e9595',1,'IRFujitsuAC::_irsend()'],['../classIRGoodweatherAc.html#acf606eb9e024c99407138dbd058e98d9',1,'IRGoodweatherAc::_irsend()'],['../classIRGreeAC.html#a36390655badf0ad5b5809499a8634f70',1,'IRGreeAC::_irsend()'],['../classIRHaierAC.html#aec69643fe633a57d635754690225fdd1',1,'IRHaierAC::_irsend()'],['../classIRHaierACYRW02.html#a24dd00bfa5e062c5c7f459bcd60213b7',1,'IRHaierACYRW02::_irsend()'],['../classIRHitachiAc.html#a0e296fa54cc4c56e16c6fc58c7ad827f',1,'IRHitachiAc::_irsend()'],['../classIRHitachiAc1.html#a61ad6289fc3719a850299788e642b98b',1,'IRHitachiAc1::_irsend()'],['../classIRHitachiAc424.html#a39157a1bda46304429570be2880c6ec4',1,'IRHitachiAc424::_irsend()'],['../classIRHitachiAc3.html#a8dc3b713e29f3ea96a106868451ba728',1,'IRHitachiAc3::_irsend()'],['../classIRKelvinatorAC.html#ae3571bf6de20e47f81ad1da8f1d13118',1,'IRKelvinatorAC::_irsend()'],['../classIRLgAc.html#a779f321b65db6ad05ab3e578b38cf093',1,'IRLgAc::_irsend()'],['../classIRMideaAC.html#ae2b6068355ecdc360c4c2ca2fd8d921b',1,'IRMideaAC::_irsend()'],['../classIRMitsubishiAC.html#a6753b676690f35bc8ba73504fdc34946',1,'IRMitsubishiAC::_irsend()'],['../classIRMitsubishi136.html#acd14c7bb6b26d0603ee552a000e16d43',1,'IRMitsubishi136::_irsend()'],['../classIRMitsubishi112.html#af858d640f9b2fca053287f280c8a27c0',1,'IRMitsubishi112::_irsend()'],['../classIRMitsubishiHeavy152Ac.html#a1ebd4c8b06d64e0944358156f58d414e',1,'IRMitsubishiHeavy152Ac::_irsend()'],['../classIRMitsubishiHeavy88Ac.html#a1e999c9ee028d35c03cd6b4751bcb8be',1,'IRMitsubishiHeavy88Ac::_irsend()'],['../classIRNeoclimaAc.html#a43e42b1c7e68e5a85ed10454c6210be5',1,'IRNeoclimaAc::_irsend()'],['../classIRPanasonicAc.html#a065dcc65ef3dbb8f2384f883fb97d102',1,'IRPanasonicAc::_irsend()'],['../classIRSamsungAc.html#a5815878dbebe512c41c26924cf9f5eeb',1,'IRSamsungAc::_irsend()'],['../classIRSharpAc.html#a10ee598c31c0f8179ace953ed88e37c6',1,'IRSharpAc::_irsend()'],['../classIRTcl112Ac.html#a3f10e710a44c3a80f4f9ed5247b28058',1,'IRTcl112Ac::_irsend()'],['../classIRTecoAc.html#a283ff8b73ef2998f0668d0a03cba0938',1,'IRTecoAc::_irsend()'],['../classIRToshibaAC.html#a694609136a9cbdb9af5f8bb98411c2eb',1,'IRToshibaAC::_irsend()'],['../classIRTrotecESP.html#a1faa968fc2651dc1774160950e97a74e',1,'IRTrotecESP::_irsend()'],['../classIRVestelAc.html#a56d35fc5d39c97b4c6f2decf176e2cae',1,'IRVestelAc::_irsend()'],['../classIRWhirlpoolAc.html#af4fdac2382048e2776c787bebd482e9e',1,'IRWhirlpoolAc::_irsend()']]], + ['_5firtimer_5funittest_5fnow_16',['_IRtimer_unittest_now',['../IRtimer_8cpp.html#a4ac531aa761a28d68edbc12967038180',1,'IRtimer.cpp']]], + ['_5flastsentpowerstate_17',['_lastsentpowerstate',['../classIRSamsungAc.html#af1c6712dc05a451e815675abe972d9b4',1,'IRSamsungAc']]], + ['_5fmatchgeneric_18',['_matchGeneric',['../classIRrecv.html#af0b300fe6fdff58324525e8208be3024',1,'IRrecv']]], + ['_5fmode_19',['_mode',['../classIRFujitsuAC.html#a1b22f3bb3dc43e370aabad5b6efd7ca5',1,'IRFujitsuAC::_mode()'],['../classIRSharpAc.html#a169d5636aead556234dc301729050619',1,'IRSharpAc::_mode()']]], + ['_5fmodel_20',['_model',['../classIRFujitsuAC.html#a181c71dbd46ceabdcfe08448ee32bba7',1,'IRFujitsuAC::_model()'],['../classIRGreeAC.html#ae357bf1611f349e2686f4f46c2581c47',1,'IRGreeAC::_model()']]], + ['_5fmodulation_21',['_modulation',['../classIRac.html#acc6b7380f11c38d13fffa99ca2189a9b',1,'IRac']]], + ['_5foutsidequiet_22',['_outsideQuiet',['../classIRFujitsuAC.html#a20a794245e0bc44607faf7927a285672',1,'IRFujitsuAC']]], + ['_5fpin_23',['_pin',['../classIRac.html#aba78a2510d8cdcaf4c601e8b0574ae6c',1,'IRac']]], + ['_5fprev_24',['_prev',['../classIRac.html#a8c63dc78c49f3714887fea0feefffd44',1,'IRac']]], + ['_5fprevioustemp_25',['_previoustemp',['../classIRHitachiAc.html#a1368dcd7f4c0049822fd2b9b1e0acb5e',1,'IRHitachiAc::_previoustemp()'],['../classIRHitachiAc424.html#aba6c17936775e268744af23a4a533f92',1,'IRHitachiAc424::_previoustemp()']]], + ['_5fprotocol_26',['_protocol',['../classIRLgAc.html#a9bd32e865a7358bbf32830d888e2786a',1,'IRLgAc']]], + ['_5fsaved_5ftemp_27',['_saved_temp',['../classIRDaikin176.html#a8f1d6c765bf09c1a3dc9678c3939a5be',1,'IRDaikin176::_saved_temp()'],['../classIRDelonghiAc.html#a724aa5748e714a7f0109a2f3502cd1d1',1,'IRDelonghiAc::_saved_temp()']]], + ['_5fsaved_5ftemp_5funits_28',['_saved_temp_units',['../classIRDelonghiAc.html#a14fba6ccbc25da76744d28e7a40c385b',1,'IRDelonghiAc']]], + ['_5fsendsony_29',['_sendSony',['../classIRsend.html#a21352b4499f976872a74bae36ea10338',1,'IRsend']]], + ['_5fsetmode_30',['_setMode',['../classIRWhirlpoolAc.html#a60fd8da35d6e0137711e114a5307d664',1,'IRWhirlpoolAc']]], + ['_5fsetpower_31',['_setPower',['../classIRCoronaAc.html#a4b05b7e34e0f2e66f59ff279c6970478',1,'IRCoronaAc']]], + ['_5fsettemp_32',['_setTemp',['../classIRLgAc.html#a39aca9861608211c8e74c89a7ccc97cd',1,'IRLgAc::_setTemp()'],['../classIRWhirlpoolAc.html#abb221e09077efd96304f84e8ca130458',1,'IRWhirlpoolAc::_setTemp()']]], + ['_5fsettime_33',['_setTime',['../classIRPanasonicAc.html#a51e306dd7a3e4d580ed5396fcd166141',1,'IRPanasonicAc']]], + ['_5fsettimer_34',['_setTimer',['../classIRCoronaAc.html#a0ea9319987de7cb7f3dcb9fbefb60a2c',1,'IRCoronaAc::_setTimer()'],['../classIRVestelAc.html#a726178a16458c84d031aec07355d0dd2',1,'IRVestelAc::_setTimer()']]], + ['_5fstate_5flength_35',['_state_length',['../classIRFujitsuAC.html#aea1819d0041f305e2c990f6f3eced865',1,'IRFujitsuAC']]], + ['_5fstate_5flength_5fshort_36',['_state_length_short',['../classIRFujitsuAC.html#a7093cf32cd2e856ff692aebc732c1d50',1,'IRFujitsuAC']]], + ['_5fswingh_37',['_swingh',['../classIRPanasonicAc.html#ad0300ee66bcab38e13724520cb3226f9',1,'IRPanasonicAc']]], + ['_5fswingmode_38',['_swingMode',['../classIRFujitsuAC.html#a74a00fbba55b457b68f61481ce9ffbaa',1,'IRFujitsuAC']]], + ['_5fswingvtoggle_39',['_SwingVToggle',['../classIRMideaAC.html#adb4318940487aea09116fe6b9f061470',1,'IRMideaAC']]], + ['_5ftemp_40',['_temp',['../classIRFujitsuAC.html#afcff35df74885c63651134ba85359694',1,'IRFujitsuAC::_temp()'],['../classIRLgAc.html#a1eeb727ee96c26b784a607aabd4577c9',1,'IRLgAc::_temp()'],['../classIRPanasonicAc.html#af6511e3c9745ff6750dc6fc3fdda21b3',1,'IRPanasonicAc::_temp()'],['../classIRSharpAc.html#a1d0a6274534123133217175920c7cd95',1,'IRSharpAc::_temp()']]], + ['_5ftimer_5fnum_41',['_timer_num',['../classIRrecv.html#aff11c0c20735b16ce411088003607911',1,'IRrecv']]], + ['_5ftimerms_5funittest_5fnow_42',['_TimerMs_unittest_now',['../IRtimer_8cpp.html#aed35ce7fa92ebb856a03f81e756cb2c6',1,'IRtimer.cpp']]], + ['_5ftolerance_43',['_tolerance',['../classIRrecv.html#a0459a65dd31b215713ad66a1e4f3540e',1,'IRrecv']]], + ['_5ftostring_44',['_toString',['../classIRHitachiAc424.html#af7ab654c4eecf770a70399f6b9959db3',1,'IRHitachiAc424']]], + ['_5funknown_5fthreshold_45',['_unknown_threshold',['../classIRrecv.html#adb8cbc5c1cb739f33f5be25b3a6c79bd',1,'IRrecv']]], + ['_5fvalidtolerance_46',['_validTolerance',['../classIRrecv.html#a0b4221970de0d027b5ae99648fa1c003',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.html new file mode 100644 index 000000000..8eb215b90 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.js new file mode 100644 index 000000000..02e9d8e2f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.js @@ -0,0 +1,23 @@ +var searchData= +[ + ['add_47',['add',['../classIRtimer.html#aa8e3ff975ae5468b4727790c828fa032',1,'IRtimer::add()'],['../classTimerMs.html#a77bfc23a029a9172c3dbac03f746b0cb',1,'TimerMs::add()']]], + ['addbooltostring_48',['addBoolToString',['../namespaceirutils.html#a12ba9cf1830a886649a80c3cc5fdce2b',1,'irutils']]], + ['adddaytostring_49',['addDayToString',['../namespaceirutils.html#a6ead1d10578c64627f8a24b5d8a7444f',1,'irutils']]], + ['addfantostring_50',['addFanToString',['../namespaceirutils.html#ae023bbabc452173d348c14eac7d86ab4',1,'irutils']]], + ['addinttostring_51',['addIntToString',['../namespaceirutils.html#a772e623c4b60208200e02afbaec66651',1,'irutils']]], + ['addlabeledstring_52',['addLabeledString',['../namespaceirutils.html#ac98793392d1e65c1b8d6895eb9d9b75b',1,'irutils']]], + ['addmodeltostring_53',['addModelToString',['../namespaceirutils.html#a06e5a5c2b6f6649035dfa5eb19801367',1,'irutils']]], + ['addmodetostring_54',['addModeToString',['../namespaceirutils.html#a8b74ae0258e98aa0eaebc6f3efe1481e',1,'irutils']]], + ['address_55',['address',['../classdecode__results.html#a2858c3a5e28eccca95d44aaa87b70e9e',1,'decode_results']]], + ['addtemptostring_56',['addTempToString',['../namespaceirutils.html#a0cef0634f4db979a93b7dc19cc2b4a85',1,'irutils']]], + ['airwell_57',['AIRWELL',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0cd75c2edaa4c674d679dbb39635990a',1,'IRremoteESP8266.h']]], + ['aiwa_5frc_5ft501_58',['AIWA_RC_T501',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7dc14b2c4769ef9de663c2e2165d8f75',1,'IRremoteESP8266.h']]], + ['akb75215403_59',['AKB75215403',['../IRsend_8h.html#a50c54713e16502d280723334879dc83ba37d3851f43307f1e1eac46c5fbf3f08a',1,'IRsend.h']]], + ['amcor_60',['amcor',['../classIRac.html#a4bad16621b232572e14fe4a53f678131',1,'IRac::amcor()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1325ba25674d7a99562f15a1b392086b',1,'AMCOR(): IRremoteESP8266.h']]], + ['ardb1_61',['ARDB1',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a6f6fcd0be917d91b71c1b80b5446ee5b',1,'IRsend.h']]], + ['argo_62',['argo',['../classIRArgoAC.html#ab607bde051712a57fe9c0a0cf9da20ac',1,'IRArgoAC::argo()'],['../classIRac.html#aa06ee1314529dbf96f4e6f3c28ea6821',1,'IRac::argo()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac9ff1fa84905b54238b16d31197efb72',1,'ARGO(): IRremoteESP8266.h']]], + ['arjw2_63',['ARJW2',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0acbca1f3d199103d8cb9d856b9089cdc4',1,'IRsend.h']]], + ['arrah2e_64',['ARRAH2E',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a6ccf47af1067e794e02e21f03389297b',1,'IRsend.h']]], + ['arreb1e_65',['ARREB1E',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a2443ff6f0181dbc1af275c709d67147a',1,'IRsend.h']]], + ['arry4_66',['ARRY4',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0aee3994c5a4a8447463d67df2cdf5a946',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.html new file mode 100644 index 000000000..6fd3a4aa2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.js new file mode 100644 index 000000000..46c722884 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['padding_3198',['padding',['../unionmagiquest.html#a28ca4be56c78ef762f87171506dc6e93',1,'magiquest']]], + ['panasonic_3199',['panasonic',['../classIRac.html#af873db2b9735127eb6f079861daed67a',1,'IRac::panasonic()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf87c99938d26a1f77d4f082c070d4660',1,'PANASONIC(): IRremoteESP8266.h']]], + ['panasonic_5fac_3200',['PANASONIC_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada02178d0c70511011d5f381291bb7e491',1,'IRremoteESP8266.h']]], + ['panasonic_5fac_5fremote_5fmodel_5ft_3201',['panasonic_ac_remote_model_t',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6f',1,'IRsend.h']]], + ['periodoffset_3202',['periodOffset',['../classIRsend.html#a1b5180cbf4f88f19fca3f677e1e91b96',1,'IRsend']]], + ['pioneer_3203',['PIONEER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadadf49fef8f6e9740c92af2e25384f7846',1,'IRremoteESP8266.h']]], + ['power_3204',['power',['../structstdAc_1_1state__t.html#ab85d37cc99bbbc4915331369c4ea622e',1,'stdAc::state_t']]], + ['powerflag_3205',['powerFlag',['../classIRCoolixAC.html#a5984ff64ff14df92291618a647da08f9',1,'IRCoolixAC']]], + ['pronto_3206',['PRONTO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada5b68c32f80c4afa6e61039843b2d1f97',1,'IRremoteESP8266.h']]], + ['protocol_3207',['protocol',['../structstdAc_1_1state__t.html#af59897778be0e571f77dd11337352c27',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.html new file mode 100644 index 000000000..f78343b9b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.js new file mode 100644 index 000000000..7b22d20b7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['quiet_3208',['quiet',['../structstdAc_1_1state__t.html#a251ad14e187a9905137e9e4e010c3e34',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.html new file mode 100644 index 000000000..dd9ff1d59 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.js new file mode 100644 index 000000000..138cb936c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.js @@ -0,0 +1,29 @@ +var searchData= +[ + ['r_5flt0541_5fhta_5fa_3209',['R_LT0541_HTA_A',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49afed7c9dd67250bb1e72081e5f05b35f8',1,'IRsend.h']]], + ['r_5flt0541_5fhta_5fb_3210',['R_LT0541_HTA_B',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49a03b6e058b4cfeb6719906bc3cd57594f',1,'IRsend.h']]], + ['raw_3211',['RAW',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadabdeded99fe7d3f2773014a9a2cfb73d7',1,'IRremoteESP8266.h']]], + ['rawbuf_3212',['rawbuf',['../structirparams__t.html#a6f8a82b51fa206a8cb195e5838aa0cb3',1,'irparams_t::rawbuf()'],['../classdecode__results.html#a19043dc161cd5e0d3dcc82b5a7470e49',1,'decode_results::rawbuf()']]], + ['rawlen_3213',['rawlen',['../structirparams__t.html#a08e83386c65a90038e0d4922f1f6aa84',1,'irparams_t::rawlen()'],['../classdecode__results.html#a913e19fc5032fa1f97cf8afe0fa450ec',1,'decode_results::rawlen()']]], + ['rc5_3214',['RC5',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac3c0a3883a1488209bcd91730ece33b2',1,'IRremoteESP8266.h']]], + ['rc5x_3215',['RC5X',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8a3ac4419806a34ba566bfcbbb0e4f1d',1,'IRremoteESP8266.h']]], + ['rc6_3216',['RC6',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7f7247f15587eb3812846f424b941abe',1,'IRremoteESP8266.h']]], + ['rcmm_3217',['RCMM',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada79204b7ae26be334cebf3ea8268c34ab',1,'IRremoteESP8266.h']]], + ['rcvstate_3218',['rcvstate',['../structirparams__t.html#a63354788dab4569f4092cd05e77f0260',1,'irparams_t']]], + ['readme_2emd_3219',['README.md',['../README_8md.html',1,'']]], + ['recoversavedstate_3220',['recoverSavedState',['../classIRCoolixAC.html#a134cb36681c3fab53074b402bba0a45c',1,'IRCoolixAC']]], + ['recvpin_3221',['recvpin',['../structirparams__t.html#a50da5aa1c42a69b01d50ea688db67d14',1,'irparams_t']]], + ['remote_3222',['remote',['../classIRDaikinESP.html#ac24751c23f6b27cb26dcd51e91c63c9b',1,'IRDaikinESP::remote()'],['../classIRGoodweatherAc.html#af511a0703a4cbc77f5b8a520abf11f2f',1,'IRGoodweatherAc::remote()'],['../classIRSharpAc.html#a411a4db0579ed84b54533dcde153d5da',1,'IRSharpAc::remote()']]], + ['remote_5fstate_3223',['remote_state',['../classIRAmcorAc.html#acef1c3896f03afd5d10d5cbb7ed105ce',1,'IRAmcorAc::remote_state()'],['../classIRCarrierAc64.html#a257272c7cb54f5854e79053c8223a43e',1,'IRCarrierAc64::remote_state()'],['../classIRCoolixAC.html#a03bf575961d4d924275cb16a45edaa46',1,'IRCoolixAC::remote_state()'],['../classIRCoronaAc.html#afcf0b21ac5c438dc560612a785a29864',1,'IRCoronaAc::remote_state()'],['../classIRDaikin2.html#a0b28396956687a4009cab7c860b9ce4b',1,'IRDaikin2::remote_state()'],['../classIRDaikin216.html#abf9bab0a52f9227d54f583488b024a85',1,'IRDaikin216::remote_state()'],['../classIRDaikin160.html#a17fb5726060e8872735559654a72cb22',1,'IRDaikin160::remote_state()'],['../classIRDaikin176.html#adb6863da11f0569524f0beb31681d0b5',1,'IRDaikin176::remote_state()'],['../classIRDaikin128.html#af1b36cc2f51cd145da3bfe7ec3d9134a',1,'IRDaikin128::remote_state()'],['../classIRDaikin152.html#aa16c89c0cb6d83aef83d293466dab197',1,'IRDaikin152::remote_state()'],['../classIRDaikin64.html#aa279d6df0d130e727c3a1500b283eda0',1,'IRDaikin64::remote_state()'],['../classIRDelonghiAc.html#a3b3364143c52dc2a29d9db43612c07b1',1,'IRDelonghiAc::remote_state()'],['../classIRElectraAc.html#a3f423f5d896e4bfc2f3a0ce04b596289',1,'IRElectraAc::remote_state()'],['../classIRFujitsuAC.html#a851b9192e1f18f6a4b2f1726d49ef33b',1,'IRFujitsuAC::remote_state()'],['../classIRGreeAC.html#a9e0cb21278ac3c9a72738ab8e6e09096',1,'IRGreeAC::remote_state()'],['../classIRHaierAC.html#a609abaeab9df642fdaccd77235a84eed',1,'IRHaierAC::remote_state()'],['../classIRHaierACYRW02.html#a08069ef89f5c5e2c1ba8563cdad24578',1,'IRHaierACYRW02::remote_state()'],['../classIRHitachiAc.html#a44b3d360b2a8044782b73f7f4a533a99',1,'IRHitachiAc::remote_state()'],['../classIRHitachiAc1.html#a13340cba808d457d6093f1c9efffc419',1,'IRHitachiAc1::remote_state()'],['../classIRHitachiAc424.html#a58bac4ef7f46ef1e9f38c1a144e2ca41',1,'IRHitachiAc424::remote_state()'],['../classIRHitachiAc3.html#a5602ded229a41796c205519449f7d509',1,'IRHitachiAc3::remote_state()'],['../classIRKelvinatorAC.html#a70f75821274e53cc5ed64ac53a6e32b4',1,'IRKelvinatorAC::remote_state()'],['../classIRLgAc.html#a481133671657b13ecce1bd08f710089d',1,'IRLgAc::remote_state()'],['../classIRMideaAC.html#a8f122367cc407e7bb658fe7f3132effb',1,'IRMideaAC::remote_state()'],['../classIRMitsubishiAC.html#ac0a149b9705371e59c45ece162bc1aab',1,'IRMitsubishiAC::remote_state()'],['../classIRMitsubishi136.html#ad1e80d693d3558f0bed4c0f7995bddd5',1,'IRMitsubishi136::remote_state()'],['../classIRMitsubishi112.html#a64a40e57208d08b5cd6ef87a7c8d6671',1,'IRMitsubishi112::remote_state()'],['../classIRMitsubishiHeavy152Ac.html#a6d333f238bf1b42e39919d4897080aa8',1,'IRMitsubishiHeavy152Ac::remote_state()'],['../classIRMitsubishiHeavy88Ac.html#a46be0e755530f59fad7d3f9050ecc107',1,'IRMitsubishiHeavy88Ac::remote_state()'],['../classIRNeoclimaAc.html#a336507e0635ede3b9ebf53881ece50bb',1,'IRNeoclimaAc::remote_state()'],['../classIRPanasonicAc.html#a85d5118c0ed947cc77f2ed94b0d44e4a',1,'IRPanasonicAc::remote_state()'],['../classIRSamsungAc.html#a5966a3b665ce034de807de1955396e10',1,'IRSamsungAc::remote_state()'],['../classIRTcl112Ac.html#a6eda1148a977a3ccf0c6c30239fca4c8',1,'IRTcl112Ac::remote_state()'],['../classIRTecoAc.html#a3c2ad7587ed4f5589deb20d8dc16b1e4',1,'IRTecoAc::remote_state()'],['../classIRToshibaAC.html#aab228aa6db2255dddf98a46a25cbb0f0',1,'IRToshibaAC::remote_state()'],['../classIRTrotecESP.html#afccba55e2c3d42c716591c10bc9afa18',1,'IRTrotecESP::remote_state()'],['../classIRVestelAc.html#a74d889a0db2fa63a2e38aaa15819568c',1,'IRVestelAc::remote_state()'],['../classIRWhirlpoolAc.html#a65333985c39773896071081ebcca4821',1,'IRWhirlpoolAc::remote_state()']]], + ['remote_5ftime_5fstate_3224',['remote_time_state',['../classIRVestelAc.html#a9b10e4a0c1f71aecbeb385666d1a53bd',1,'IRVestelAc']]], + ['repeat_3225',['repeat',['../classdecode__results.html#a09da48786fe3966cd5621840fd771bfa',1,'decode_results']]], + ['reset_3226',['reset',['../classIRtimer.html#aaaf886de2c9533a8c791242dc575db1a',1,'IRtimer::reset()'],['../classTimerMs.html#a25ab025793a4d432e7d4180cbd31157b',1,'TimerMs::reset()']]], + ['resultactostring_3227',['resultAcToString',['../namespaceIRAcUtils.html#ac3d2683bc26edc2bf58916187b5349c3',1,'IRAcUtils']]], + ['resulttohexidecimal_3228',['resultToHexidecimal',['../IRutils_8cpp.html#a25a669d53f231de6152f8e60cedf39f7',1,'resultToHexidecimal(const decode_results *const result): IRutils.cpp'],['../IRutils_8h.html#a25a669d53f231de6152f8e60cedf39f7',1,'resultToHexidecimal(const decode_results *const result): IRutils.cpp']]], + ['resulttohumanreadablebasic_3229',['resultToHumanReadableBasic',['../IRutils_8cpp.html#a0cc6ae1b9649b1ea1d2bfe7e7b03b6d8',1,'resultToHumanReadableBasic(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#a0cc6ae1b9649b1ea1d2bfe7e7b03b6d8',1,'resultToHumanReadableBasic(const decode_results *const results): IRutils.cpp']]], + ['resulttorawarray_3230',['resultToRawArray',['../IRutils_8cpp.html#a7b3bbfa1f2bf2dea2fc40a2fefe05a2a',1,'resultToRawArray(const decode_results *const decode): IRutils.cpp'],['../IRutils_8h.html#a7b3bbfa1f2bf2dea2fc40a2fefe05a2a',1,'resultToRawArray(const decode_results *const decode): IRutils.cpp']]], + ['resulttosourcecode_3231',['resultToSourceCode',['../IRutils_8cpp.html#a10fc00c8b399dddb67a228325e6e2f79',1,'resultToSourceCode(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#a10fc00c8b399dddb67a228325e6e2f79',1,'resultToSourceCode(const decode_results *const results): IRutils.cpp']]], + ['resulttotiminginfo_3232',['resultToTimingInfo',['../IRutils_8cpp.html#afbfdef125ff077431f3abc27a1eeb800',1,'resultToTimingInfo(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#afbfdef125ff077431f3abc27a1eeb800',1,'resultToTimingInfo(const decode_results *const results): IRutils.cpp']]], + ['resume_3233',['resume',['../classIRrecv.html#a6b5beb7348d807d8d98ae929d005510e',1,'IRrecv']]], + ['reversebits_3234',['reverseBits',['../IRutils_8cpp.html#a366219b6f1c46f41c6573b3e5e875e41',1,'reverseBits(uint64_t input, uint16_t nbits): IRutils.cpp'],['../IRutils_8h.html#a366219b6f1c46f41c6573b3e5e875e41',1,'reverseBits(uint64_t input, uint16_t nbits): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.html new file mode 100644 index 000000000..2611a100d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.js new file mode 100644 index 000000000..745394494 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.js @@ -0,0 +1,244 @@ +var searchData= +[ + ['samsung_3235',['samsung',['../classIRac.html#a619c659a11c258ea9623eaa37689ba4c',1,'IRac::samsung()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada2b451b6e7bebbf070d0913ec77d5d438',1,'SAMSUNG(): IRremoteESP8266.h']]], + ['samsung36_3236',['SAMSUNG36',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa0d1be0c368e3594bc546c241d031fd4',1,'IRremoteESP8266.h']]], + ['samsung_5fac_3237',['SAMSUNG_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada39f991023009d760432489e7ad7ad4df',1,'IRremoteESP8266.h']]], + ['sanyo_3238',['SANYO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac1cf5078ebfd7ff83c70e8ec8522b288',1,'IRremoteESP8266.h']]], + ['sanyo_5flc7461_3239',['SANYO_LC7461',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada558721044a11b1d4b491343f02267e1d',1,'IRremoteESP8266.h']]], + ['saved_5fstate_3240',['saved_state',['../classIRCoolixAC.html#aec0bce8019d7d49a30915394bee56b9a',1,'IRCoolixAC']]], + ['scrap_3241',['scrap',['../unionmagiquest.html#afd0bcf9a87f0fa2db87b68b211952a73',1,'magiquest']]], + ['send_3242',['send',['../classIRAmcorAc.html#a4fa894c01a8baabfeadb39634a850fd9',1,'IRAmcorAc::send()'],['../classIRArgoAC.html#a0e4793a4f6fc537ec1450f5a42206dae',1,'IRArgoAC::send()'],['../classIRCarrierAc64.html#aace8aa2d125c6e80bcdd6d96eac722c2',1,'IRCarrierAc64::send()'],['../classIRCoolixAC.html#aaaa681d6cfcf04d110b913e8bb27a53c',1,'IRCoolixAC::send()'],['../classIRCoronaAc.html#aa0c8a1ef4473a3c7d02e1a04c7678fa6',1,'IRCoronaAc::send()'],['../classIRDaikinESP.html#a9f0d2641b54e97da943fceb0ba3f67eb',1,'IRDaikinESP::send()'],['../classIRDaikin2.html#aae2db88038d8d02617f16588e6a82b64',1,'IRDaikin2::send()'],['../classIRDaikin216.html#ab1061620f838cf7774c16c593b4ada8c',1,'IRDaikin216::send()'],['../classIRDaikin160.html#a0e1c74070c03be02e40fdd05ed56465c',1,'IRDaikin160::send()'],['../classIRDaikin176.html#affd71592fa8ed05816d94edbf94d2c0a',1,'IRDaikin176::send()'],['../classIRDaikin128.html#aae7fec91ad2265e8b0378c6b99379e89',1,'IRDaikin128::send()'],['../classIRDaikin152.html#a205de6821effc077f51d941d369791e4',1,'IRDaikin152::send()'],['../classIRDaikin64.html#a904eec38045d9ddc8a97ab33c8a2ac4d',1,'IRDaikin64::send()'],['../classIRDelonghiAc.html#afba831b6884771b84bab684732e0f4f5',1,'IRDelonghiAc::send()'],['../classIRElectraAc.html#a30170a65de1161e26daeddf694f8afdb',1,'IRElectraAc::send()'],['../classIRFujitsuAC.html#a1f1aa593cc4503d14c0fbea5cd9823a1',1,'IRFujitsuAC::send()'],['../classIRGoodweatherAc.html#abcc3c9d9b0912b09d3c0b0c1affb8cc8',1,'IRGoodweatherAc::send()'],['../classIRGreeAC.html#a9823578040c2d15e2b3e8e3a17a9e220',1,'IRGreeAC::send()'],['../classIRHaierAC.html#a9fe53d04965efca6daf234f20d20eb5a',1,'IRHaierAC::send()'],['../classIRHaierACYRW02.html#a65a5d5840dddac505b009e899a0dada7',1,'IRHaierACYRW02::send()'],['../classIRHitachiAc.html#afc53e562370bbaba8b5dda26a62de427',1,'IRHitachiAc::send()'],['../classIRHitachiAc1.html#aafad51c226066b8697cf00661ef38d99',1,'IRHitachiAc1::send()'],['../classIRHitachiAc424.html#adf15121bb329e1bb061f9e5efb848764',1,'IRHitachiAc424::send()'],['../classIRHitachiAc3.html#ab95fd527a4841c44d6e91c8b4afee8b4',1,'IRHitachiAc3::send()'],['../classIRHitachiAc344.html#ae9b33c0adfc1506b1d9ede1e3285c3e3',1,'IRHitachiAc344::send()'],['../classIRKelvinatorAC.html#aa55fbfefbaca1acf5bc9ba796bea8464',1,'IRKelvinatorAC::send()'],['../classIRLgAc.html#aea85c840161b48f2e8d31e7e6e7da532',1,'IRLgAc::send()'],['../classIRMideaAC.html#af66b9f76ad794450a0a7eace4bb59300',1,'IRMideaAC::send()'],['../classIRMitsubishiAC.html#a2467ad33d88af8f6244e7cd0620e012e',1,'IRMitsubishiAC::send()'],['../classIRMitsubishi136.html#a41295e551acf428e76b9b404af2381ad',1,'IRMitsubishi136::send()'],['../classIRMitsubishi112.html#a8f813da813b1a281654147ada2e63eba',1,'IRMitsubishi112::send()'],['../classIRMitsubishiHeavy152Ac.html#acc53c5c136c6987c420d48bddcf9b2da',1,'IRMitsubishiHeavy152Ac::send()'],['../classIRMitsubishiHeavy88Ac.html#a707cb3ec3e3c18bedeb12205580d5048',1,'IRMitsubishiHeavy88Ac::send()'],['../classIRNeoclimaAc.html#a2220bbb1d928b8f6490cd43b702ef430',1,'IRNeoclimaAc::send()'],['../classIRPanasonicAc.html#a778420ebe52aa6422ba5633ce91676df',1,'IRPanasonicAc::send()'],['../classIRSamsungAc.html#a8128429fcb1828a049784d832cafc9fe',1,'IRSamsungAc::send()'],['../classIRSharpAc.html#a829872744bf9fef51dccd89584ddffe6',1,'IRSharpAc::send()'],['../classIRTcl112Ac.html#a9aa8c67e167a3d241157306d0668ff15',1,'IRTcl112Ac::send()'],['../classIRTecoAc.html#ad5785e93e8c0c95a8618b0e371adaa79',1,'IRTecoAc::send()'],['../classIRToshibaAC.html#a14b155d3a20fb9c127eb7f3fe1fd16cd',1,'IRToshibaAC::send()'],['../classIRTrotecESP.html#add228d50195d7b9b43346a90bf959512',1,'IRTrotecESP::send()'],['../classIRVestelAc.html#a606497754b381e70d13ddef5643c9d0b',1,'IRVestelAc::send()'],['../classIRWhirlpoolAc.html#a0c043b3d7cc993940941351e6c63b5cc',1,'IRWhirlpoolAc::send()'],['../classIRsend.html#a204eedc3ad182fb2f40c42ef58f78cfc',1,'IRsend::send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)'],['../classIRsend.html#ac684c209ea8722f0a377070752df0040',1,'IRsend::send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes)']]], + ['sendac_3243',['sendAc',['../classIRac.html#a0cea80b7bab92c9dc4f18c61f5762130',1,'IRac::sendAc(void)'],['../classIRac.html#aa33c42968acafc5cf479574483f94ea9',1,'IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)'],['../classIRac.html#ad60fbe1488efe2d02307d81b090b3b72',1,'IRac::sendAc(const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)']]], + ['sendairwell_3244',['sendAirwell',['../classIRsend.html#a5b180d3845b45af38a19b72e6fa8e0c0',1,'IRsend']]], + ['sendaiwarct501_3245',['sendAiwaRCT501',['../classIRsend.html#ad39a4b13ad2e8500c95db49265e7c771',1,'IRsend']]], + ['sendamcor_3246',['sendAmcor',['../classIRsend.html#acd64b100eb155f90451d467188a83e92',1,'IRsend']]], + ['sendargo_3247',['sendArgo',['../classIRsend.html#a59668b767e4ad4966fe0bc259c3bd34f',1,'IRsend']]], + ['sendcarrierac_3248',['sendCarrierAC',['../classIRsend.html#a9e859a8b5eaea2e64978c8f93b78d159',1,'IRsend']]], + ['sendcarrierac40_3249',['sendCarrierAC40',['../classIRsend.html#a4342b775777d2ff9371f48aa39ad9b69',1,'IRsend']]], + ['sendcarrierac64_3250',['sendCarrierAC64',['../classIRsend.html#abf755688d87fcef5aee86c6a2c89e7c4',1,'IRsend']]], + ['sendcoolix_3251',['sendCOOLIX',['../classIRsend.html#a088af5f0d76965c61fe5716f7b8f2b61',1,'IRsend']]], + ['sendcoronaac_3252',['sendCoronaAc',['../classIRsend.html#a81f82b8248b324799a48a7685d62aaa5',1,'IRsend']]], + ['senddaikin_3253',['sendDaikin',['../classIRsend.html#a3010546144b5ca3b3c94f5881050dbd0',1,'IRsend']]], + ['senddaikin128_3254',['sendDaikin128',['../classIRsend.html#a72a41a704d48750c144c6467ae9a1430',1,'IRsend']]], + ['senddaikin152_3255',['sendDaikin152',['../classIRsend.html#a4ad420eb86e0ae38b12e983f7eaa912c',1,'IRsend']]], + ['senddaikin160_3256',['sendDaikin160',['../classIRsend.html#ab144a86def38f9f5c98701742683c004',1,'IRsend']]], + ['senddaikin176_3257',['sendDaikin176',['../classIRsend.html#ac4b5bcb95d3aff70b2f84074177e9e92',1,'IRsend']]], + ['senddaikin2_3258',['sendDaikin2',['../classIRsend.html#a34262e579cbb6634459bc09c5b15dfa0',1,'IRsend']]], + ['senddaikin216_3259',['sendDaikin216',['../classIRsend.html#aa99bfdaa71ff5bf088faaa17d304f45d',1,'IRsend']]], + ['senddaikin64_3260',['sendDaikin64',['../classIRsend.html#aa403d2192a6eb57910e6f84695475b27',1,'IRsend']]], + ['senddata_3261',['sendData',['../classIRsend.html#a4f8cd77dab7ce6c406029fe87674858f',1,'IRsend']]], + ['senddelonghiac_3262',['sendDelonghiAc',['../classIRsend.html#a35dc18f9abbffa8da40816a8a9df1093',1,'IRsend']]], + ['senddenon_3263',['sendDenon',['../classIRsend.html#a2618e000bf91cf1585329308a078653a',1,'IRsend']]], + ['senddish_3264',['sendDISH',['../classIRsend.html#ac7a72d61af219d983409911bdc1769b8',1,'IRsend']]], + ['senddoshisha_3265',['sendDoshisha',['../classIRsend.html#a3a9a8247e470975137b37f474bb97639',1,'IRsend']]], + ['sendelectraac_3266',['sendElectraAC',['../classIRsend.html#a52526c4e7bc4402e57ecf81e0047d49c',1,'IRsend']]], + ['sendepson_3267',['sendEpson',['../classIRsend.html#a063168fd82f6a88cca7253b42b9c0b28',1,'IRsend']]], + ['sendextended_3268',['sendExtended',['../classIRSamsungAc.html#a16a8dbd8f3fd34a6e681125b276acfd9',1,'IRSamsungAc']]], + ['sendfujitsuac_3269',['sendFujitsuAC',['../classIRsend.html#a1a3d3f83d0b7a59ff5510b038f658eb6',1,'IRsend']]], + ['sendgc_3270',['sendGC',['../classIRsend.html#acf987a501326d9c945cd8dbeb0806e17',1,'IRsend']]], + ['sendgeneric_3271',['sendGeneric',['../classIRsend.html#a5215fd797dfd490816f31bb99b38c273',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)'],['../classIRsend.html#aaace48306af9c020c18848db1a05e641',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint32_t mesgtime, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)'],['../classIRsend.html#a4f5ad649827692b4b42d15b45c7f684b',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint8_t *dataptr, const uint16_t nbytes, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)']]], + ['sendgicable_3272',['sendGICable',['../classIRsend.html#a61dd16bc150473bbfd998dada72b205f',1,'IRsend']]], + ['sendgoodweather_3273',['sendGoodweather',['../classIRsend.html#a8e2d98ae5c39ee07a61f08facecbaa1e',1,'IRsend']]], + ['sendgree_3274',['sendGree',['../classIRsend.html#aca81ea348ceb6b0c9e62073b57bc0b17',1,'IRsend::sendGree(const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)'],['../classIRsend.html#af788e7d9a2ad2483313434f9b5196753',1,'IRsend::sendGree(const uint8_t data[], const uint16_t nbytes=kGreeStateLength, const uint16_t repeat=kGreeDefaultRepeat)']]], + ['sendhaierac_3275',['sendHaierAC',['../classIRsend.html#a6b4b9144d56dda302f5b321f1c5017ff',1,'IRsend']]], + ['sendhaieracyrw02_3276',['sendHaierACYRW02',['../classIRsend.html#a6aa1c1a6880872c87a46e4e0ead5d9b0',1,'IRsend']]], + ['sendhitachiac_3277',['sendHitachiAC',['../classIRsend.html#a8e6079b8b1b69ad7d7f8d05c492becbe',1,'IRsend']]], + ['sendhitachiac1_3278',['sendHitachiAC1',['../classIRsend.html#a5be9a87ce052e4f056766919247e0b22',1,'IRsend']]], + ['sendhitachiac2_3279',['sendHitachiAC2',['../classIRsend.html#a451b1913608a4ba8c26d9af8c85d16f1',1,'IRsend']]], + ['sendhitachiac3_3280',['sendHitachiAc3',['../classIRsend.html#aec7e67f4292622521b5a0a8cfdd21d84',1,'IRsend']]], + ['sendhitachiac344_3281',['sendHitachiAc344',['../classIRsend.html#a5fb28d54f2832651d992450673d05c01',1,'IRsend']]], + ['sendhitachiac424_3282',['sendHitachiAc424',['../classIRsend.html#a2a9676de30bb868b313cc9c30025f790',1,'IRsend']]], + ['sendinax_3283',['sendInax',['../classIRsend.html#a5fa5ff62276d9d680fb1255cc8b99eec',1,'IRsend']]], + ['sendjvc_3284',['sendJVC',['../classIRsend.html#aaa10c899768a5b4cdb1a7913d06141ca',1,'IRsend']]], + ['sendkelvinator_3285',['sendKelvinator',['../classIRsend.html#a8cba9df982fc91f895196d61d2e65b0e',1,'IRsend']]], + ['sendlasertag_3286',['sendLasertag',['../classIRsend.html#a55a79f9727590044751f291a4df83892',1,'IRsend']]], + ['sendlegopf_3287',['sendLegoPf',['../classIRsend.html#a4e38273aeacf01873a013c02d41a44e4',1,'IRsend']]], + ['sendlg_3288',['sendLG',['../classIRsend.html#a079a84c82f360d6d55fde5c27634f51c',1,'IRsend']]], + ['sendlg2_3289',['sendLG2',['../classIRsend.html#a5b6be1ceac8a4bc4ef55dc12eb060531',1,'IRsend']]], + ['sendlutron_3290',['sendLutron',['../classIRsend.html#a85f2a98255d3af7b7407c082ea7b7c16',1,'IRsend']]], + ['sendmagiquest_3291',['sendMagiQuest',['../classIRsend.html#af1d0e9ec0f735fc5fb9011d4f4cb8327',1,'IRsend']]], + ['sendmanchester_3292',['sendManchester',['../classIRsend.html#a7862231cbb1d50f42996c25e2f05b93e',1,'IRsend']]], + ['sendmanchesterdata_3293',['sendManchesterData',['../classIRsend.html#aa76aa33785827c1278eb57d1c15236f8',1,'IRsend']]], + ['sendmidea_3294',['sendMidea',['../classIRsend.html#a37d91b3a77b36509abdc53e2fec20a67',1,'IRsend']]], + ['sendmidea24_3295',['sendMidea24',['../classIRsend.html#a103d79e8df7954e9ab6284fa9f3daf02',1,'IRsend']]], + ['sendmitsubishi_3296',['sendMitsubishi',['../classIRsend.html#a59e8941a25c5c0bbc839fba5b1a22813',1,'IRsend']]], + ['sendmitsubishi112_3297',['sendMitsubishi112',['../classIRsend.html#a0a55e688c6aad015494168f25eb337b5',1,'IRsend']]], + ['sendmitsubishi136_3298',['sendMitsubishi136',['../classIRsend.html#a988a8b7dda3563977d537d6ac448ebc8',1,'IRsend']]], + ['sendmitsubishi2_3299',['sendMitsubishi2',['../classIRsend.html#ac54e50a6819f5c39e060891f1f6ea0f2',1,'IRsend']]], + ['sendmitsubishiac_3300',['sendMitsubishiAC',['../classIRsend.html#a3600527a82f9f22387c9f16ae51fb06f',1,'IRsend']]], + ['sendmitsubishiheavy152_3301',['sendMitsubishiHeavy152',['../classIRsend.html#ae1cffc4882c63f192c231397d19a4032',1,'IRsend']]], + ['sendmitsubishiheavy88_3302',['sendMitsubishiHeavy88',['../classIRsend.html#afaf4fd0c3dabd1bd6f8fe421294c5063',1,'IRsend']]], + ['sendmultibrackets_3303',['sendMultibrackets',['../classIRsend.html#a9026d42480b85270e560e122b8be3b6c',1,'IRsend']]], + ['sendmwm_3304',['sendMWM',['../classIRsend.html#a98301801daf929ec8ce022987ae394f2',1,'IRsend']]], + ['sendnec_3305',['sendNEC',['../classIRsend.html#a324c9e455c0bae51ebe9bc07e915c043',1,'IRsend']]], + ['sendneoclima_3306',['sendNeoclima',['../classIRsend.html#a71e1b5e780851210465bbf061b9c095b',1,'IRsend']]], + ['sendnikai_3307',['sendNikai',['../classIRsend.html#a693e6616b81509cf27d1345c140acc96',1,'IRsend']]], + ['sendoff_3308',['sendOff',['../classIRSamsungAc.html#a96e2ae87f3ffcf1ad812f256f31e4898',1,'IRSamsungAc']]], + ['sendon_3309',['sendOn',['../classIRSamsungAc.html#a7e6980c829dfd143d4d19abaf5d65678',1,'IRSamsungAc']]], + ['sendpanasonic_3310',['sendPanasonic',['../classIRsend.html#a92192475f89b19cfdf7fd0416a263145',1,'IRsend']]], + ['sendpanasonic64_3311',['sendPanasonic64',['../classIRsend.html#adc4fd287f3546f7ff0b67e177a42b560',1,'IRsend']]], + ['sendpanasonicac_3312',['sendPanasonicAC',['../classIRsend.html#a10a3c387a328dbb11733a251f4db7614',1,'IRsend']]], + ['sendpioneer_3313',['sendPioneer',['../classIRsend.html#a11f099f3768a659d1f996589cea8a313',1,'IRsend']]], + ['sendpronto_3314',['sendPronto',['../classIRsend.html#a0b349351e2ba19f87e6b01cde7e67c49',1,'IRsend']]], + ['sendraw_3315',['sendRaw',['../classIRsend.html#a2b9b84f828918f933bd1764d113b53f8',1,'IRsend']]], + ['sendrc5_3316',['sendRC5',['../classIRsend.html#a2bd2ccb27ecd57e14b36f76d82af308a',1,'IRsend']]], + ['sendrc6_3317',['sendRC6',['../classIRsend.html#a2192a95e0d162f9b1775fc2a47f65c37',1,'IRsend']]], + ['sendrcmm_3318',['sendRCMM',['../classIRsend.html#a3cafe475a58234a0d3aa655a2464be75',1,'IRsend']]], + ['sendsamsung_3319',['sendSAMSUNG',['../classIRsend.html#a5252dd159aad713c099de6728ac56d81',1,'IRsend']]], + ['sendsamsung36_3320',['sendSamsung36',['../classIRsend.html#ab5dcd4ec5ddb0b0351870ddf54e5ba66',1,'IRsend']]], + ['sendsamsungac_3321',['sendSamsungAC',['../classIRsend.html#a2773d251da1d35b964810c8cc4cb438b',1,'IRsend']]], + ['sendsanyolc7461_3322',['sendSanyoLC7461',['../classIRsend.html#aa23e51a97a0ec1907d22623fed6dd223',1,'IRsend']]], + ['sendsharp_3323',['sendSharp',['../classIRsend.html#a801ae78ac5a72116c566c4ac5f99c6bd',1,'IRsend']]], + ['sendsharpac_3324',['sendSharpAc',['../classIRsend.html#a438e4c9d50e62da7d772d8d638728213',1,'IRsend']]], + ['sendsharpraw_3325',['sendSharpRaw',['../classIRsend.html#aa1f12fd537ca8c21c183ee41d17a3afc',1,'IRsend']]], + ['sendsherwood_3326',['sendSherwood',['../classIRsend.html#afb3a89acfb868c92a997a3000e70c6e8',1,'IRsend']]], + ['sendsony_3327',['sendSony',['../classIRsend.html#a02bb64503474a0841c51664cf4668d85',1,'IRsend']]], + ['sendsony38_3328',['sendSony38',['../classIRsend.html#a558442f49b32453f0fb987c29e1ec6d3',1,'IRsend']]], + ['sendsymphony_3329',['sendSymphony',['../classIRsend.html#a1f1d5a30660ab0061f64d559d4916d4e',1,'IRsend']]], + ['sendtcl112ac_3330',['sendTcl112Ac',['../classIRsend.html#a2dedce2841e4a6445a98f03393fce823',1,'IRsend']]], + ['sendteco_3331',['sendTeco',['../classIRsend.html#ac6300f977fe94119813481ba682ce33f',1,'IRsend']]], + ['sendtoshibaac_3332',['sendToshibaAC',['../classIRsend.html#a4ef8e028135536dc1f5a63be85ef7d49',1,'IRsend']]], + ['sendtrotec_3333',['sendTrotec',['../classIRsend.html#a135796327b5db127473f4d198e663c00',1,'IRsend']]], + ['sendvestelac_3334',['sendVestelAc',['../classIRsend.html#a129a40f9d344cb0fadfd4cca53ca6b44',1,'IRsend']]], + ['sendwhirlpoolac_3335',['sendWhirlpoolAC',['../classIRsend.html#aa440a50000a259072f93ad6c0e42ec22',1,'IRsend']]], + ['sendwhynter_3336',['sendWhynter',['../classIRsend.html#a07188366deed3dd902cba80a711cf220',1,'IRsend']]], + ['sendzepeal_3337',['sendZepeal',['../classIRsend.html#a9bcba8bbac41d679b5b930e67d3e1b7f',1,'IRsend']]], + ['serialprintuint64_3338',['serialPrintUint64',['../IRutils_8cpp.html#ad2b0a4b9a1a7fca3d5f5afc14b682433',1,'serialPrintUint64(uint64_t input, uint8_t base): IRutils.cpp'],['../IRutils_8h.html#a315d5f05fb572564025bc9ce9b820243',1,'serialPrintUint64(uint64_t input, uint8_t base=10): IRutils.cpp']]], + ['set3d_3339',['set3D',['../classIRMitsubishiHeavy152Ac.html#ab22654d492a4b0e82efcd0c96fc9bbe3',1,'IRMitsubishiHeavy152Ac::set3D()'],['../classIRMitsubishiHeavy88Ac.html#ae0b7eac743a8de6852722f067e010ba7',1,'IRMitsubishiHeavy88Ac::set3D()']]], + ['set8cheat_3340',['set8CHeat',['../classIRNeoclimaAc.html#a3176c5fe3251bd6a31a3a0ddc2c294be',1,'IRNeoclimaAc']]], + ['setauto_3341',['setAuto',['../classIRVestelAc.html#a2509eed2e0d7b23595bbe6dd7df17d74',1,'IRVestelAc']]], + ['setbeep_3342',['setBeep',['../classIRDaikin2.html#a4c0588887a45403a0a9f2cf95f847889',1,'IRDaikin2::setBeep()'],['../classIRSamsungAc.html#a092ccbea031dd4be747076530117649d',1,'IRSamsungAc::setBeep()']]], + ['setbit_3343',['setBit',['../namespaceirutils.html#a316301577d2ff338bfba6605df2cc46b',1,'irutils::setBit(const uint64_t data, const uint8_t position, const bool on, const uint8_t size)'],['../namespaceirutils.html#a2e9e858b490fa3328b4c5bd01adedb8c',1,'irutils::setBit(const uint8_t data, const uint8_t position, const bool on)'],['../namespaceirutils.html#ac1b3de6e733d9c4d614a8239f5bd3220',1,'irutils::setBit(uint8_t *const data, const uint8_t position, const bool on)'],['../namespaceirutils.html#a86bbcf05c1601712b1d587b87035f09b',1,'irutils::setBit(uint32_t *const data, const uint8_t position, const bool on)'],['../namespaceirutils.html#a9e7814e2274f02df0dac0106c293c487',1,'irutils::setBit(uint64_t *const data, const uint8_t position, const bool on)']]], + ['setbits_3344',['setBits',['../namespaceirutils.html#ab4f5e3eb26e111909ddc93a8b018ba78',1,'irutils::setBits(uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)'],['../namespaceirutils.html#a3fd8b18a76f0ae8f730b4de55fc9486e',1,'irutils::setBits(uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)'],['../namespaceirutils.html#a4dfb0984a9ea38602805987a7845839c',1,'irutils::setBits(uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)']]], + ['setboost_3345',['setBoost',['../classIRDelonghiAc.html#a827d1e43e9252657147226aa3f8e4eb8',1,'IRDelonghiAc']]], + ['setbreeze_3346',['setBreeze',['../classIRSamsungAc.html#a310a73f15a0274fbaf15b981abaae592',1,'IRSamsungAc']]], + ['setbutton_3347',['setButton',['../classIRHaierACYRW02.html#aa0f1561e2446f6231f722581f5bae34d',1,'IRHaierACYRW02::setButton()'],['../classIRHitachiAc424.html#af4ded7ea8aa94271d5135eebd3bb80a8',1,'IRHitachiAc424::setButton()'],['../classIRNeoclimaAc.html#a7e2e6e646411b4f5ea3c1ce1e944581c',1,'IRNeoclimaAc::setButton()']]], + ['setclean_3348',['setClean',['../classIRCoolixAC.html#a0087ac58749ef946632fbb5a8b41fe0d',1,'IRCoolixAC::setClean()'],['../classIRDaikin2.html#a21e09b867710a225d5cf53006f723326',1,'IRDaikin2::setClean()'],['../classIRElectraAc.html#a4aa44fc40196067469dfa8a722e33115',1,'IRElectraAc::setClean()'],['../classIRFujitsuAC.html#a7f6f18ea39bf28717cb65ff348b1b2f5',1,'IRFujitsuAC::setClean()'],['../classIRMitsubishiHeavy152Ac.html#a11678e7eb906414770938f6efce266f1',1,'IRMitsubishiHeavy152Ac::setClean()'],['../classIRMitsubishiHeavy88Ac.html#a65968304e4aaf025dfefc49d5d777cbd',1,'IRMitsubishiHeavy88Ac::setClean()'],['../classIRSamsungAc.html#a911ca57dfb0e6787cba330e8d49b2496',1,'IRSamsungAc::setClean()'],['../classIRSharpAc.html#ace6e7b98496a594031809fe8a535c429',1,'IRSharpAc::setClean()']]], + ['setclock_3349',['setClock',['../classIRDaikin128.html#aa9928ac010ec79ddab4f551eedf2f5d9',1,'IRDaikin128::setClock()'],['../classIRDaikin64.html#a655f1cec5e28f79e5718573678c535ec',1,'IRDaikin64::setClock()'],['../classIRMitsubishiAC.html#a7abe34adf36bdd1a65a17f56ee8af1f6',1,'IRMitsubishiAC::setClock()'],['../classIRPanasonicAc.html#a3f76c6aca94f52c227c2e259512fd101',1,'IRPanasonicAc::setClock()'],['../classIRWhirlpoolAc.html#aab09aae7de733414bf480c3df22b83f8',1,'IRWhirlpoolAc::setClock()']]], + ['setcmd_3350',['setCmd',['../classIRFujitsuAC.html#a7579944c11b3d31bb069303926307617',1,'IRFujitsuAC']]], + ['setcomfort_3351',['setComfort',['../classIRDaikinESP.html#aaa15c0be7ffb8e845a03d193583a58d1',1,'IRDaikinESP::setComfort()'],['../classIRDaikin152.html#a95de2dc0a90fe4212cb60973b9430486',1,'IRDaikin152::setComfort()']]], + ['setcommand_3352',['setCommand',['../classIRGoodweatherAc.html#a4e266f42b7a82c49208e2acc7813e07b',1,'IRGoodweatherAc::setCommand()'],['../classIRHaierAC.html#ade34c951e72a794c2ff7fa0d1595d68f',1,'IRHaierAC::setCommand()'],['../classIRWhirlpoolAc.html#aaea26b1388489dff70a98fde1e6185be',1,'IRWhirlpoolAc::setCommand()']]], + ['setcurrentday_3353',['setCurrentDay',['../classIRDaikinESP.html#a5465b9857fd73b82362f766368717d16',1,'IRDaikinESP']]], + ['setcurrenttime_3354',['setCurrentTime',['../classIRDaikinESP.html#ae6559268982ae0968358a885c7dbba6e',1,'IRDaikinESP::setCurrentTime()'],['../classIRDaikin2.html#a8b32b1b9a87c9b671af6aeedb709d520',1,'IRDaikin2::setCurrentTime()']]], + ['setcurrtime_3355',['setCurrTime',['../classIRHaierAC.html#a53500ebdec058d27396e5906a572fe15',1,'IRHaierAC']]], + ['setdisplay_3356',['setDisplay',['../classIRSamsungAc.html#ad20199bed3a01208ec694b9d4eb7ef98',1,'IRSamsungAc']]], + ['setdisplaytempsource_3357',['setDisplayTempSource',['../classIRGreeAC.html#a1d073c31ea169d0e5cf33c8592982035',1,'IRGreeAC']]], + ['setecono_3358',['setEcono',['../classIRCoronaAc.html#abb5624317fff60674bed410be3a3fa52',1,'IRCoronaAc::setEcono()'],['../classIRDaikinESP.html#a12129aedd6320522a9b6e811e347089c',1,'IRDaikinESP::setEcono()'],['../classIRDaikin2.html#a42a44a6cefa6bf6f45148d39c216ebc0',1,'IRDaikin2::setEcono()'],['../classIRDaikin128.html#a07fb5289ee476e0335fec4845254b7ce',1,'IRDaikin128::setEcono()'],['../classIRDaikin152.html#a8062d16f7aefb7586e3d3bdfea8755b4',1,'IRDaikin152::setEcono()'],['../classIRMitsubishiHeavy152Ac.html#ab3964219ee3c0c5112bb38c892a01784',1,'IRMitsubishiHeavy152Ac::setEcono()'],['../classIRMitsubishiHeavy88Ac.html#a7612448f1cceaa6aeee1697f51adaf43',1,'IRMitsubishiHeavy88Ac::setEcono()'],['../classIRTcl112Ac.html#a48ac7acfa8fed8e9da39907282f4f377',1,'IRTcl112Ac::setEcono()']]], + ['seteconotoggle_3359',['setEconoToggle',['../classIRSharpAc.html#ae3495676b8bffecba5c56fbf1ab9ee4d',1,'IRSharpAc']]], + ['seteye_3360',['setEye',['../classIRDaikin2.html#a5ba8e5d5dd4aba45a90de1d450a7a88b',1,'IRDaikin2::setEye()'],['../classIRNeoclimaAc.html#aaf433cab785db382c55a420e68e7d7ec',1,'IRNeoclimaAc::setEye()']]], + ['seteyeauto_3361',['setEyeAuto',['../classIRDaikin2.html#a975c2fdb261d6d2b6c8e196fbd074899',1,'IRDaikin2']]], + ['setfan_3362',['setFan',['../classIRAmcorAc.html#acf26fc65363e2734e4dc6eb562812553',1,'IRAmcorAc::setFan()'],['../classIRArgoAC.html#a8144f003628e128ec6630aef49ed5cb5',1,'IRArgoAC::setFan()'],['../classIRCarrierAc64.html#a312027468b508e9d38dd9e23ee99f9e4',1,'IRCarrierAc64::setFan()'],['../classIRCoolixAC.html#aff4189cb1000c6db7d88624fbadbe0cb',1,'IRCoolixAC::setFan()'],['../classIRCoronaAc.html#aa4da12502bf85438846bdde56391ee5c',1,'IRCoronaAc::setFan()'],['../classIRDaikinESP.html#a1f191f45e473482a86aad9a1c879e083',1,'IRDaikinESP::setFan()'],['../classIRDaikin2.html#af9f3ddbdd1f1d5d99c84846b73c5daa1',1,'IRDaikin2::setFan()'],['../classIRDaikin216.html#a8fadfb1e61deca74a2d1b9c1d5ae62e1',1,'IRDaikin216::setFan()'],['../classIRDaikin160.html#a7f507c64dc7a9fa1e9391e9e8473af1b',1,'IRDaikin160::setFan()'],['../classIRDaikin176.html#a050a9943dc7d8289472e6b9dbdcb06c1',1,'IRDaikin176::setFan()'],['../classIRDaikin128.html#a0495834250e97e7831e9906ab548fe44',1,'IRDaikin128::setFan()'],['../classIRDaikin152.html#a385a4f65dfccd0a9e94be06ae60c5343',1,'IRDaikin152::setFan()'],['../classIRDaikin64.html#af39206f90b99fd5ee340923b196368b8',1,'IRDaikin64::setFan()'],['../classIRDelonghiAc.html#a440f1e0efa18c6b1a8e18e0a97fbfb79',1,'IRDelonghiAc::setFan()'],['../classIRElectraAc.html#aa338ce18cafaf9c7b9aa3385e681bbe7',1,'IRElectraAc::setFan()'],['../classIRGoodweatherAc.html#af8cf9ba59af548677e586cd59e8a6cc2',1,'IRGoodweatherAc::setFan()'],['../classIRGreeAC.html#a9bb570e71df5002298505d49473e6bac',1,'IRGreeAC::setFan()'],['../classIRHaierAC.html#a42ee1c5889f07bf7615c8f853bca2261',1,'IRHaierAC::setFan()'],['../classIRHaierACYRW02.html#ae9c3a7bffc08d9d5204616823f709889',1,'IRHaierACYRW02::setFan()'],['../classIRHitachiAc.html#a0760b07502b976880ee8499dc6fa61ff',1,'IRHitachiAc::setFan()'],['../classIRHitachiAc1.html#a7294dc1324877d4a64f7b4373d97d745',1,'IRHitachiAc1::setFan()'],['../classIRHitachiAc424.html#afd69bcff56224f39af92fc2d334b67bb',1,'IRHitachiAc424::setFan()'],['../classIRKelvinatorAC.html#af08e94be9699983c0087c9b059aad319',1,'IRKelvinatorAC::setFan()'],['../classIRLgAc.html#a0f1901a21ffb93641d3481417d74bb4e',1,'IRLgAc::setFan()'],['../classIRMideaAC.html#a546eeca4eea015899a5ad9f5d1c6fafb',1,'IRMideaAC::setFan()'],['../classIRMitsubishiAC.html#a4e88e50b2eddd0233aade5c1bf7819f1',1,'IRMitsubishiAC::setFan()'],['../classIRMitsubishi136.html#a2aa62126614f734ec3d1b7b3cb653e9e',1,'IRMitsubishi136::setFan()'],['../classIRMitsubishi112.html#ab681e78572c869a8c57079a660fe1505',1,'IRMitsubishi112::setFan()'],['../classIRMitsubishiHeavy152Ac.html#ac8d8eceba935aa626cb229d1c41081bb',1,'IRMitsubishiHeavy152Ac::setFan()'],['../classIRMitsubishiHeavy88Ac.html#a4f8c934a82091547c36da512329e76d7',1,'IRMitsubishiHeavy88Ac::setFan()'],['../classIRNeoclimaAc.html#a8db9d2d446e8614b2fc4583a454d7cee',1,'IRNeoclimaAc::setFan()'],['../classIRPanasonicAc.html#a8d77292226f55601c30ee53252ba83cd',1,'IRPanasonicAc::setFan()'],['../classIRSamsungAc.html#a6c7571e14fe6629348273a2b49a0a824',1,'IRSamsungAc::setFan()'],['../classIRSharpAc.html#a5138068f8ba4c51939ff3bb14f0aae45',1,'IRSharpAc::setFan()'],['../classIRTcl112Ac.html#a0dab8ad6675c4ec122d0d7e28a557cba',1,'IRTcl112Ac::setFan()'],['../classIRTecoAc.html#afda9a33ca450568f968217bedc9ad7f2',1,'IRTecoAc::setFan()'],['../classIRToshibaAC.html#a020ba3e95c607f52ce091193fc5825fc',1,'IRToshibaAC::setFan()'],['../classIRVestelAc.html#af53dfd0a0372c878b6ba2ca1cfc21ccd',1,'IRVestelAc::setFan()'],['../classIRWhirlpoolAc.html#a8da28ee25fdc91d55a9f6ab5dab3af81',1,'IRWhirlpoolAc::setFan()']]], + ['setfanspeed_3363',['setFanSpeed',['../classIRFujitsuAC.html#af0fc10ec0a606434477cb41c60eb49e5',1,'IRFujitsuAC']]], + ['setfilter_3364',['setFilter',['../classIRFujitsuAC.html#aec0048efe87f60406c76ad6bc3ffbc61',1,'IRFujitsuAC::setFilter()'],['../classIRMitsubishiHeavy152Ac.html#aaf76ac48228d3a7b8490e684407e65b1',1,'IRMitsubishiHeavy152Ac::setFilter()']]], + ['setflap_3365',['setFlap',['../classIRArgoAC.html#a55a6402ffc3fe7fb59775050901416ca',1,'IRArgoAC']]], + ['setfresh_3366',['setFresh',['../classIRNeoclimaAc.html#a6354d8b902ffc1e7c044a61185504404',1,'IRNeoclimaAc']]], + ['setfreshair_3367',['setFreshAir',['../classIRDaikin2.html#a6e0596c7b9f9b43b8d241340ae08e886',1,'IRDaikin2']]], + ['setfreshairhigh_3368',['setFreshAirHigh',['../classIRDaikin2.html#a044471f2298a1942bcc2f859f9459924',1,'IRDaikin2']]], + ['sethealth_3369',['setHealth',['../classIRHaierAC.html#a48c9ae91809d63156eeb3889f2e908f4',1,'IRHaierAC::setHealth()'],['../classIRHaierACYRW02.html#a79673650a2285f029a35ab69edeb0e74',1,'IRHaierACYRW02::setHealth()'],['../classIRTcl112Ac.html#a28ed509977d8642174bc6c9aa97ae1c3',1,'IRTcl112Ac::setHealth()']]], + ['sethold_3370',['setHold',['../classIRNeoclimaAc.html#a2eb4e0a2ff39ceb1b6b571998d91b31e',1,'IRNeoclimaAc']]], + ['sethumid_3371',['setHumid',['../classIRTecoAc.html#a4ab07a7c95f34d3b292926c719aeb303',1,'IRTecoAc']]], + ['setifeel_3372',['setIFeel',['../classIRGreeAC.html#a68a670156a5e0a91a8a3cf9225263e0b',1,'IRGreeAC::setIFeel()'],['../classIRArgoAC.html#ae59f903855961441b676b7f662602554',1,'IRArgoAC::setiFeel()']]], + ['setinvertedstates_3373',['setInvertedStates',['../classIRHitachiAc424.html#ad18528cf83e863b98cb1609eec970ac5',1,'IRHitachiAc424::setInvertedStates()'],['../classIRHitachiAc3.html#af37c710449cd32df4753509749e31cad',1,'IRHitachiAc3::setInvertedStates()']]], + ['setion_3374',['setIon',['../classIRNeoclimaAc.html#a504fc5e371746fda8e7eb7cc0abf137a',1,'IRNeoclimaAc::setIon()'],['../classIRPanasonicAc.html#a5a1c4f5b9eb7a3a1a81a6acd0491c3cd',1,'IRPanasonicAc::setIon()'],['../classIRSamsungAc.html#aeee65ca6d2100635a517077f01053bed',1,'IRSamsungAc::setIon()'],['../classIRSharpAc.html#af6a390362bc5b40eecc6564b16b3379b',1,'IRSharpAc::setIon()'],['../classIRVestelAc.html#acf860da68a15d463dab437a808c9c8c6',1,'IRVestelAc::setIon()']]], + ['setionfilter_3375',['setIonFilter',['../classIRKelvinatorAC.html#a6a219c481ddc21d93028f5c799c25883',1,'IRKelvinatorAC']]], + ['setled_3376',['setLed',['../classIRCoolixAC.html#a3132f99cffa108129dff64a0b68bd614',1,'IRCoolixAC']]], + ['setlight_3377',['setLight',['../classIRDaikin2.html#a7ecadb3335e9b22729a89b4c41456242',1,'IRDaikin2::setLight()'],['../classIRGoodweatherAc.html#a3f149ff426b236ba9f90659a6daf4a9c',1,'IRGoodweatherAc::setLight()'],['../classIRGreeAC.html#a702bbba38e11bb8f3428ee707fc82311',1,'IRGreeAC::setLight()'],['../classIRKelvinatorAC.html#a870890c2bc8510f8f7351ca21db8d855',1,'IRKelvinatorAC::setLight()'],['../classIRNeoclimaAc.html#a1d7a6ec6d319544bee907a23a1d14084',1,'IRNeoclimaAc::setLight()'],['../classIRTcl112Ac.html#a7dec5b0559f996df8a4fc259ab6012e9',1,'IRTcl112Ac::setLight()'],['../classIRTecoAc.html#a25d97c1e7be31d80a4ffad0026e633d7',1,'IRTecoAc::setLight()'],['../classIRWhirlpoolAc.html#a70b4c0467a7747f9cf9e106af1025771',1,'IRWhirlpoolAc::setLight()']]], + ['setlighttoggle_3378',['setLightToggle',['../classIRDaikin128.html#a6361c789141ccecb729c104e71ddcc41',1,'IRDaikin128::setLightToggle()'],['../classIRElectraAc.html#a15373982641e36f4b68258368700be7d',1,'IRElectraAc::setLightToggle()']]], + ['setmax_3379',['setMax',['../classIRAmcorAc.html#a1250c6b106378286d9db013296c9b16f',1,'IRAmcorAc::setMax()'],['../classIRArgoAC.html#a909c1f74e9452d0e19fc3ffd28b1b81b',1,'IRArgoAC::setMax()']]], + ['setmode_3380',['setMode',['../classIRAmcorAc.html#afa9c2d080ed5c4c7bc64eb13a07eab68',1,'IRAmcorAc::setMode()'],['../classIRArgoAC.html#a8575f0ef967b09308ed6a453857e65c7',1,'IRArgoAC::setMode()'],['../classIRCarrierAc64.html#ae462eeec49ff91358f1b9921750ee36d',1,'IRCarrierAc64::setMode()'],['../classIRCoolixAC.html#a5c0094d32aca6a5323f4dc72a03f02e9',1,'IRCoolixAC::setMode()'],['../classIRCoronaAc.html#aedeeedd176c89e5b7b650a4311e712be',1,'IRCoronaAc::setMode()'],['../classIRDaikinESP.html#af0f463201c877d33fa8680053dda7551',1,'IRDaikinESP::setMode()'],['../classIRDaikin2.html#a24ef3b53f22fe3557ed2dbc98a5bc6d2',1,'IRDaikin2::setMode()'],['../classIRDaikin216.html#a1d0dfce75ac95df9125b2cfe7c955080',1,'IRDaikin216::setMode()'],['../classIRDaikin160.html#a48e6fff63fd8b894c649fb495a467faa',1,'IRDaikin160::setMode()'],['../classIRDaikin176.html#a7ce82479f5ae2721baae8119b711c112',1,'IRDaikin176::setMode()'],['../classIRDaikin128.html#a9693e9931449f39253ca9102ac5cbfe9',1,'IRDaikin128::setMode()'],['../classIRDaikin152.html#aad0a46c751b73792282d6614103f57d8',1,'IRDaikin152::setMode()'],['../classIRDaikin64.html#a04dff0d273457a7bc3f3e0e1af4f7cd9',1,'IRDaikin64::setMode()'],['../classIRDelonghiAc.html#a62392c26321f038a84d99d54039bcfae',1,'IRDelonghiAc::setMode()'],['../classIRElectraAc.html#a911b7410fd2f29464c1505e183c04c5d',1,'IRElectraAc::setMode()'],['../classIRFujitsuAC.html#ac125c320f9794aae931bc59ba332a4a8',1,'IRFujitsuAC::setMode()'],['../classIRGoodweatherAc.html#a8eed6b70b7b1c2e8a9620db7462e1fb5',1,'IRGoodweatherAc::setMode()'],['../classIRGreeAC.html#a9d9dbd416e3dc270fcfda620b3bb4fe2',1,'IRGreeAC::setMode()'],['../classIRHaierAC.html#a3ad0317f2fd4f57d8ce61353ab3e48c7',1,'IRHaierAC::setMode()'],['../classIRHaierACYRW02.html#ae762c5f5422b4af612fa00f7c26452ed',1,'IRHaierACYRW02::setMode()'],['../classIRHitachiAc.html#a208f73a42484a1555145b41849e8c51f',1,'IRHitachiAc::setMode()'],['../classIRHitachiAc1.html#a1f3ced601e1131b70f840820ecb3feaa',1,'IRHitachiAc1::setMode()'],['../classIRHitachiAc424.html#a373a51d207674e35e00762b057f73cd5',1,'IRHitachiAc424::setMode()'],['../classIRKelvinatorAC.html#af55cc77892bc960587037c337b90d1bc',1,'IRKelvinatorAC::setMode()'],['../classIRLgAc.html#a5e1b21d9121c6bf6507f615f470b5890',1,'IRLgAc::setMode()'],['../classIRMideaAC.html#a3b92f25a82741ae404e8f9af8dbca3a8',1,'IRMideaAC::setMode()'],['../classIRMitsubishiAC.html#a2b4e2f00ee5a385172b13e8d9858ac0b',1,'IRMitsubishiAC::setMode()'],['../classIRMitsubishi136.html#aaef2ed81bdeb183995e2342c2ca17a8b',1,'IRMitsubishi136::setMode()'],['../classIRMitsubishi112.html#a0c1434e1d8dd513007400042324e868e',1,'IRMitsubishi112::setMode()'],['../classIRMitsubishiHeavy152Ac.html#a5a68388f337d7ba80289359903a1d01d',1,'IRMitsubishiHeavy152Ac::setMode()'],['../classIRMitsubishiHeavy88Ac.html#a1802cc8a382d6161b83f8947137d941d',1,'IRMitsubishiHeavy88Ac::setMode()'],['../classIRNeoclimaAc.html#adabd715c4a2ec34dd88330b97a1f0ecd',1,'IRNeoclimaAc::setMode()'],['../classIRPanasonicAc.html#add025b64e736d5120abeb2564a2849a4',1,'IRPanasonicAc::setMode()'],['../classIRSamsungAc.html#a708d9c6c91d774d6eeadbc0bd7f350af',1,'IRSamsungAc::setMode()'],['../classIRSharpAc.html#ab51c207de90391cb7190e3ec95adc16e',1,'IRSharpAc::setMode()'],['../classIRTcl112Ac.html#a1a050c9b238691ba6d4764beeb788778',1,'IRTcl112Ac::setMode()'],['../classIRTecoAc.html#aba404540b723fa4687a4fda954221130',1,'IRTecoAc::setMode()'],['../classIRToshibaAC.html#aa001cddc464d6cbcc342e5e4c7af13ff',1,'IRToshibaAC::setMode()'],['../classIRTrotecESP.html#a5d34e8d1e1be765e51cbfb6874482997',1,'IRTrotecESP::setMode()'],['../classIRVestelAc.html#a470e14ab5623386c0fa2b02fd15ea1d8',1,'IRVestelAc::setMode()'],['../classIRWhirlpoolAc.html#ab09869929f5cc1fd0cc5dede93bba1c5',1,'IRWhirlpoolAc::setMode()']]], + ['setmodel_3381',['setModel',['../classIRFujitsuAC.html#a5393698000d8becf33ff332b32b97c73',1,'IRFujitsuAC::setModel()'],['../classIRGreeAC.html#a1075a08c30a2de97892e0842cb30e451',1,'IRGreeAC::setModel()'],['../classIRHitachiAc1.html#abb8c2c87e87f9d538f171e842c9d309a',1,'IRHitachiAc1::setModel()'],['../classIRLgAc.html#ae4b8758ecf10bd7e25ed401593692821',1,'IRLgAc::setModel()'],['../classIRPanasonicAc.html#a342531bfea3b05484de84e537bde390c',1,'IRPanasonicAc::setModel()'],['../classIRWhirlpoolAc.html#accfa1660ed792acc3cf48ff60d9570f0',1,'IRWhirlpoolAc::setModel()']]], + ['setmold_3382',['setMold',['../classIRDaikinESP.html#a1616d08c8fd3c628fc45a76c32743ac9',1,'IRDaikinESP::setMold()'],['../classIRDaikin2.html#ad53e046e545f3b6c5418dfbaf58653ca',1,'IRDaikin2::setMold()']]], + ['setnight_3383',['setNight',['../classIRArgoAC.html#a769dd3b538653940e41883848bc1e19c',1,'IRArgoAC::setNight()'],['../classIRMitsubishiHeavy152Ac.html#a6920a1aad327e2f347b09da12f11cf8c',1,'IRMitsubishiHeavy152Ac::setNight()']]], + ['setofftime_3384',['setOffTime',['../classIRDaikin64.html#a46a0b1e2438087ba557494b0b4fce4a5',1,'IRDaikin64']]], + ['setofftimeenabled_3385',['setOffTimeEnabled',['../classIRDaikin64.html#aea59ae39ddd0fc33a6941d0affceae9a',1,'IRDaikin64']]], + ['setofftimer_3386',['setOffTimer',['../classIRCarrierAc64.html#a92b1066e783db1bdffabfdc57699deef',1,'IRCarrierAc64::setOffTimer()'],['../classIRCoronaAc.html#a00f269b6389bf65d1816e80b835aa9b0',1,'IRCoronaAc::setOffTimer()'],['../classIRDaikin128.html#a30ca067676dfde963986e25c84616368',1,'IRDaikin128::setOffTimer()'],['../classIRDelonghiAc.html#a9602c652b10b06c6eeae0e6158c42c68',1,'IRDelonghiAc::setOffTimer()'],['../classIRHaierAC.html#aa16b36aa7ef07628343dbd2dfe5157a2',1,'IRHaierAC::setOffTimer()'],['../classIRHitachiAc1.html#a62e9c7b68e63d1791d79805f2bce99df',1,'IRHitachiAc1::setOffTimer()'],['../classIRPanasonicAc.html#a08e097f40cee6c614ec1a8de716222cf',1,'IRPanasonicAc::setOffTimer()'],['../classIRVestelAc.html#acc61cd785d2f668a86ecefb243d63549',1,'IRVestelAc::setOffTimer()'],['../classIRWhirlpoolAc.html#a69f3555c9b27f3cfd9167ed3239804b8',1,'IRWhirlpoolAc::setOffTimer()']]], + ['setofftimeractive_3387',['setOffTimerActive',['../classIRVestelAc.html#a8a023f5594b446f0c20f66c4ee584d8e',1,'IRVestelAc']]], + ['setofftimerenabled_3388',['setOffTimerEnabled',['../classIRDaikin128.html#aac8a178bdaf7de7a183991e710a9a9d8',1,'IRDaikin128::setOffTimerEnabled()'],['../classIRDelonghiAc.html#a5cf81c9864f3c3728d4dd65e4d9c49c8',1,'IRDelonghiAc::setOffTimerEnabled()']]], + ['setontime_3389',['setOnTime',['../classIRDaikin64.html#aaada482820a90492a933f368fafaebb7',1,'IRDaikin64']]], + ['setontimeenabled_3390',['setOnTimeEnabled',['../classIRDaikin64.html#a8e7a7c1f775f8ddf9d48a96915751c7a',1,'IRDaikin64']]], + ['setontimer_3391',['setOnTimer',['../classIRCarrierAc64.html#a9049a8d91200b878cc2a1b9b80a280ea',1,'IRCarrierAc64::setOnTimer()'],['../classIRCoronaAc.html#aae4142f45cc9c2b3e392b72cb404a2d8',1,'IRCoronaAc::setOnTimer()'],['../classIRDaikin128.html#a21773493eafae741b5716ac569eaf0a8',1,'IRDaikin128::setOnTimer()'],['../classIRDelonghiAc.html#a9a478f463a632893be7c4f5223c188ad',1,'IRDelonghiAc::setOnTimer()'],['../classIRHaierAC.html#aa5e95aa05749f6d35dd31b021fea2f5b',1,'IRHaierAC::setOnTimer()'],['../classIRHitachiAc1.html#a51ed6155f228628942ba08ea2ff5c547',1,'IRHitachiAc1::setOnTimer()'],['../classIRPanasonicAc.html#a51fdaa11e4e3f77189a94007a5acbec2',1,'IRPanasonicAc::setOnTimer()'],['../classIRVestelAc.html#af19bb7704326eb5688f2a2fa08e10ee2',1,'IRVestelAc::setOnTimer()'],['../classIRWhirlpoolAc.html#a1cb0e346e6f40b65b98a768df7fdace8',1,'IRWhirlpoolAc::setOnTimer()']]], + ['setontimeractive_3392',['setOnTimerActive',['../classIRVestelAc.html#a16ef4ecb7c76bef89b6e0ca36746d606',1,'IRVestelAc']]], + ['setontimerenabled_3393',['setOnTimerEnabled',['../classIRDaikin128.html#a07f693fac3de101c91c190e5e70edb57',1,'IRDaikin128::setOnTimerEnabled()'],['../classIRDelonghiAc.html#af6b956c273284e287093260039003362',1,'IRDelonghiAc::setOnTimerEnabled()']]], + ['setoutsidequiet_3394',['setOutsideQuiet',['../classIRFujitsuAC.html#a9a0533cba18739e52014307bf4b1ad07',1,'IRFujitsuAC']]], + ['setpower_3395',['setPower',['../classIRAmcorAc.html#a2ccfb2c2f0feb8a8cea9e10e30035988',1,'IRAmcorAc::setPower()'],['../classIRArgoAC.html#a991f73d84952c1d8ac86c579d1b01785',1,'IRArgoAC::setPower()'],['../classIRCarrierAc64.html#a8acf59cbf3b02381b5188324030b7727',1,'IRCarrierAc64::setPower()'],['../classIRCoolixAC.html#a41dc75b29e7a05eff5f16161cb9b3eeb',1,'IRCoolixAC::setPower()'],['../classIRCoronaAc.html#adc636402b51e0c78c4797aea5f80915d',1,'IRCoronaAc::setPower()'],['../classIRDaikinESP.html#aa0fb65d01bb203d17d923504ddd60984',1,'IRDaikinESP::setPower()'],['../classIRDaikin2.html#a3adfe1a80a702b7098ccd0e18225396e',1,'IRDaikin2::setPower()'],['../classIRDaikin216.html#a130a98bb2422a228977dea8a4e068ace',1,'IRDaikin216::setPower()'],['../classIRDaikin160.html#af1a800ef7494c49a868d01039f5c37e4',1,'IRDaikin160::setPower()'],['../classIRDaikin176.html#a58c755ba53d1f14a51b0c64ff4ef0669',1,'IRDaikin176::setPower()'],['../classIRDaikin152.html#a887f7340b9c3e7933f5d06bc5f59ee91',1,'IRDaikin152::setPower()'],['../classIRDelonghiAc.html#aa1ebbf63aa2331b87b95df9c5bdb41dc',1,'IRDelonghiAc::setPower()'],['../classIRElectraAc.html#abd04ffe9a77a97d4fafbcecd3a7949a4',1,'IRElectraAc::setPower()'],['../classIRFujitsuAC.html#a8d8211f20c8ec299e1fcb588a0846ac2',1,'IRFujitsuAC::setPower()'],['../classIRGoodweatherAc.html#ac49e30082777b10fe9edf6ec7bd76ea5',1,'IRGoodweatherAc::setPower()'],['../classIRGreeAC.html#a16b8c6af038752cd2b416cdcf9e2fb51',1,'IRGreeAC::setPower()'],['../classIRHaierACYRW02.html#a32e4a52cf31b43ad96ff3d8f0f390620',1,'IRHaierACYRW02::setPower()'],['../classIRHitachiAc.html#ad78a7176ded93735a296eefbf75cbc06',1,'IRHitachiAc::setPower()'],['../classIRHitachiAc1.html#a4dd034793018ea58d0cc32e7a47e8f35',1,'IRHitachiAc1::setPower()'],['../classIRHitachiAc424.html#a7b0b2e2c631d1bce2dd4677bb71e79b4',1,'IRHitachiAc424::setPower()'],['../classIRKelvinatorAC.html#a517a0193a9236a28a20d1760d7401efd',1,'IRKelvinatorAC::setPower()'],['../classIRLgAc.html#a175e6482fd1565d43906c527f911b59e',1,'IRLgAc::setPower()'],['../classIRMideaAC.html#ab8341f8d3d553d8b0ed9270cc15fc8ec',1,'IRMideaAC::setPower()'],['../classIRMitsubishiAC.html#a13f26de3c35b01470176b6fd9efda566',1,'IRMitsubishiAC::setPower()'],['../classIRMitsubishi136.html#a4bf52b3784faaca95ff97a09b8be322a',1,'IRMitsubishi136::setPower()'],['../classIRMitsubishi112.html#a0545da32a5048bc9d857ffb05767d3a6',1,'IRMitsubishi112::setPower()'],['../classIRMitsubishiHeavy152Ac.html#a08202752226ff3295eb8ccd637b0158b',1,'IRMitsubishiHeavy152Ac::setPower()'],['../classIRMitsubishiHeavy88Ac.html#ac2ee9dd82e84a3735e8a0c69e64cb02e',1,'IRMitsubishiHeavy88Ac::setPower()'],['../classIRNeoclimaAc.html#ac19bea3b79cdfc868bd137b0a70c0718',1,'IRNeoclimaAc::setPower()'],['../classIRPanasonicAc.html#ad60bf8a88d041f8e8ab3d728831ee8f3',1,'IRPanasonicAc::setPower()'],['../classIRSamsungAc.html#a4af21fa0dcbf5595386f67db676a443c',1,'IRSamsungAc::setPower()'],['../classIRSharpAc.html#a6b57a66878f125f86d2aed8bd7545000',1,'IRSharpAc::setPower()'],['../classIRTcl112Ac.html#ad2367d2481f94f14b9c4f7b378711b7e',1,'IRTcl112Ac::setPower()'],['../classIRTecoAc.html#a989e48a889b36ec36386a532c81872d9',1,'IRTecoAc::setPower()'],['../classIRToshibaAC.html#a100f01c014582e162f9fd287beb91dff',1,'IRToshibaAC::setPower()'],['../classIRTrotecESP.html#a0f3f5f5db367cb5a9adb936fada94fd5',1,'IRTrotecESP::setPower()'],['../classIRVestelAc.html#a01e06ff3916d4a14f9ca49f22918a47b',1,'IRVestelAc::setPower()']]], + ['setpowerbutton_3396',['setPowerButton',['../classIRCoronaAc.html#a518471d42a62863953c97334cad348be',1,'IRCoronaAc']]], + ['setpowerful_3397',['setPowerful',['../classIRDaikinESP.html#a4c0da54ee1639a3bf813cb3f3afee064',1,'IRDaikinESP::setPowerful()'],['../classIRDaikin2.html#a6538104cdcf1b55e480aaddd51116d9a',1,'IRDaikin2::setPowerful()'],['../classIRDaikin216.html#a5cb6e958f3b9789828738defe4d12c7b',1,'IRDaikin216::setPowerful()'],['../classIRDaikin128.html#aeb3aa5013b1746ed714146ca7f233119',1,'IRDaikin128::setPowerful()'],['../classIRDaikin152.html#a6477111b5662146e937c10cf02423e10',1,'IRDaikin152::setPowerful()'],['../classIRPanasonicAc.html#a6357688bc9cca92ab222343ee045f4f4',1,'IRPanasonicAc::setPowerful()'],['../classIRSamsungAc.html#ab657b79740e0f84c09611ea3b10d06f0',1,'IRSamsungAc::setPowerful()']]], + ['setpowerspecial_3398',['setPowerSpecial',['../classIRSharpAc.html#af7dd64c6d82a8502d2ee176f7b0f5abb',1,'IRSharpAc']]], + ['setpowertoggle_3399',['setPowerToggle',['../classIRDaikin128.html#a5d7edaa44f0c9ca55ef1040dd42e42e3',1,'IRDaikin128::setPowerToggle()'],['../classIRDaikin64.html#ac7f673619842d217d4eda893da2f35fd',1,'IRDaikin64::setPowerToggle()'],['../classIRHitachiAc1.html#ae30430edd92ec4b848c8a105a78e8068',1,'IRHitachiAc1::setPowerToggle()'],['../classIRWhirlpoolAc.html#a61bec25edce5bc244acb41f79df561e7',1,'IRWhirlpoolAc::setPowerToggle()']]], + ['setpurify_3400',['setPurify',['../classIRDaikin2.html#accd4430e998a8c9be80b5a708be9337e',1,'IRDaikin2']]], + ['setquiet_3401',['setQuiet',['../classIRDaikinESP.html#a4927eb8b2db2540efa90b37f4c3cc733',1,'IRDaikinESP::setQuiet()'],['../classIRDaikin2.html#a61ca7e72f850d0f9600fa9d8a336a8ef',1,'IRDaikin2::setQuiet()'],['../classIRDaikin216.html#a062528f54412cd3d2339c7bf82305ebb',1,'IRDaikin216::setQuiet()'],['../classIRDaikin128.html#a89c49332006831debbabbfcb5ec30249',1,'IRDaikin128::setQuiet()'],['../classIRDaikin152.html#a3aadf5f0ae11c5c6c53f351dd6b9c1a4',1,'IRDaikin152::setQuiet()'],['../classIRDaikin64.html#a7e3fb8debcefb76e76dda5612e28f377',1,'IRDaikin64::setQuiet()'],['../classIRKelvinatorAC.html#a2a3ca238649c55cd4f6f92f48eddf9ac',1,'IRKelvinatorAC::setQuiet()'],['../classIRMitsubishi136.html#a70c8a44f93e90ba025a8909c004c3a7b',1,'IRMitsubishi136::setQuiet()'],['../classIRMitsubishi112.html#a9fbbfb7bb1f6cccfcdcfbc4dcc335169',1,'IRMitsubishi112::setQuiet()'],['../classIRPanasonicAc.html#a51b6ae49cb490f697adeaf7f9f466518',1,'IRPanasonicAc::setQuiet()'],['../classIRSamsungAc.html#a6b3dd7d83c613a06f3499f1c8b26a67b',1,'IRSamsungAc::setQuiet()']]], + ['setraw_3402',['setRaw',['../classIRAmcorAc.html#ac0520033d7a59c817ca8ec08462fe39b',1,'IRAmcorAc::setRaw()'],['../classIRArgoAC.html#a98db56256eb71bf2e8da419007145e2b',1,'IRArgoAC::setRaw()'],['../classIRCarrierAc64.html#af49cf0b53bf8ff946a63bae94be0251d',1,'IRCarrierAc64::setRaw()'],['../classIRCoolixAC.html#aed28d08743c529a5715331255a8d5507',1,'IRCoolixAC::setRaw()'],['../classIRCoronaAc.html#a9ccf78675a3c175209c8d0ef08e2e671',1,'IRCoronaAc::setRaw()'],['../classIRDaikinESP.html#a7c69fc77ead837e5b4f1ececd9f43ca9',1,'IRDaikinESP::setRaw()'],['../classIRDaikin2.html#a132001e73eb5744a3a174c5517c9bbda',1,'IRDaikin2::setRaw()'],['../classIRDaikin216.html#a49f6a2ffc2e76ec4ff020e773bd70160',1,'IRDaikin216::setRaw()'],['../classIRDaikin160.html#a22e8a1600f612dd4326b2f9722d3a269',1,'IRDaikin160::setRaw()'],['../classIRDaikin176.html#a51e5f74b532eca958c09998727064e8d',1,'IRDaikin176::setRaw()'],['../classIRDaikin128.html#a25db29e01def45e8850ac9da68aa7ea7',1,'IRDaikin128::setRaw()'],['../classIRDaikin152.html#aab10e030ebe66e44607e9f35af1eb4cb',1,'IRDaikin152::setRaw()'],['../classIRDaikin64.html#a5f081026aca2bccc6fdeef8199e80779',1,'IRDaikin64::setRaw()'],['../classIRDelonghiAc.html#a219bafa7839f10acca33526cf585152a',1,'IRDelonghiAc::setRaw()'],['../classIRElectraAc.html#ae57c51cd3f5d1ebfb2fe7b926d149dd6',1,'IRElectraAc::setRaw()'],['../classIRFujitsuAC.html#a9b89d756948affa7029eeeed51916cbb',1,'IRFujitsuAC::setRaw()'],['../classIRGoodweatherAc.html#a2eae4bbdb14fea9e3004d656f852df59',1,'IRGoodweatherAc::setRaw()'],['../classIRGreeAC.html#a588f526f2f5500c7c2933ca91ccaf865',1,'IRGreeAC::setRaw()'],['../classIRHaierAC.html#a152961e20b5a5bed2ea03cbc65d65ce9',1,'IRHaierAC::setRaw()'],['../classIRHaierACYRW02.html#a389e711e128533c409731d2c87868c85',1,'IRHaierACYRW02::setRaw()'],['../classIRHitachiAc.html#a3b67215c162ef508c68c49b621c5199b',1,'IRHitachiAc::setRaw()'],['../classIRHitachiAc1.html#ae2d40bc477e30ee574f5c5e2ba4e09c2',1,'IRHitachiAc1::setRaw()'],['../classIRHitachiAc424.html#adc24b8b984ff20cebdf81f65843bb283',1,'IRHitachiAc424::setRaw()'],['../classIRHitachiAc3.html#acff4faf79a30df7b7e7c183dec4153a7',1,'IRHitachiAc3::setRaw()'],['../classIRHitachiAc344.html#a31c8984cfea8364734da6f32fe9a2337',1,'IRHitachiAc344::setRaw()'],['../classIRKelvinatorAC.html#a4a32bbf1a7ee8a089ea1e4e7c750433b',1,'IRKelvinatorAC::setRaw()'],['../classIRLgAc.html#a0da8ea4946826736f526386dc4d115cc',1,'IRLgAc::setRaw()'],['../classIRMideaAC.html#ab24da22531f5b2823551501642ec1b94',1,'IRMideaAC::setRaw()'],['../classIRMitsubishiAC.html#ac7bb79f91d5a9296c2b2b74aae1bfb53',1,'IRMitsubishiAC::setRaw()'],['../classIRMitsubishi136.html#abf0487a6fb163bf896e09b2cae6ee939',1,'IRMitsubishi136::setRaw()'],['../classIRMitsubishi112.html#a5c82f92d4a1ba1477ae7738ed5ade368',1,'IRMitsubishi112::setRaw()'],['../classIRMitsubishiHeavy152Ac.html#a8d42a2d87bf889ab4b233ea0c239f4c2',1,'IRMitsubishiHeavy152Ac::setRaw()'],['../classIRMitsubishiHeavy88Ac.html#abf01e448da9ec6e3b4512f58c3020299',1,'IRMitsubishiHeavy88Ac::setRaw()'],['../classIRNeoclimaAc.html#a607ea7df35572578ef86da7f505ab407',1,'IRNeoclimaAc::setRaw()'],['../classIRPanasonicAc.html#a63308883e8447aa5cdf7d29107be220f',1,'IRPanasonicAc::setRaw()'],['../classIRSamsungAc.html#a95377e8c73b51e73e78b51a2b2fa16d4',1,'IRSamsungAc::setRaw()'],['../classIRSharpAc.html#a89b18c4ee29afa56ebed5fa32e578df7',1,'IRSharpAc::setRaw()'],['../classIRTcl112Ac.html#a5b0994f37df6846137b564eeb322f21b',1,'IRTcl112Ac::setRaw()'],['../classIRTecoAc.html#a1ef3423214f55a2e2695cc1180f94bcc',1,'IRTecoAc::setRaw()'],['../classIRToshibaAC.html#ae74ff9241303eb4c7f3593f73e781c73',1,'IRToshibaAC::setRaw()'],['../classIRTrotecESP.html#a4ffe5ee2559828a61af710bb7d892b6c',1,'IRTrotecESP::setRaw()'],['../classIRVestelAc.html#a617bf1f4b5596d5ad005237e8445c12e',1,'IRVestelAc::setRaw(const uint8_t *newState)'],['../classIRVestelAc.html#a5cc86216d33f228c0648d6c66526b0eb',1,'IRVestelAc::setRaw(const uint64_t newState)'],['../classIRWhirlpoolAc.html#afa9c66ea36c970f80c88a0489448ab5b',1,'IRWhirlpoolAc::setRaw()']]], + ['setroomtemp_3403',['setRoomTemp',['../classIRArgoAC.html#aec5a2edc6f414aab201a18defaa78c5b',1,'IRArgoAC']]], + ['setsave_3404',['setSave',['../classIRTecoAc.html#a0f7d203d44d4040be3a4b28fcd5dd34c',1,'IRTecoAc']]], + ['setsensor_3405',['setSensor',['../classIRDaikinESP.html#ae1c95533934fffb29eed3e9a27e8f636',1,'IRDaikinESP::setSensor()'],['../classIRDaikin152.html#af418dbf2bb79dab0193801167dfb5b78',1,'IRDaikin152::setSensor()']]], + ['setsensortemp_3406',['setSensorTemp',['../classIRCoolixAC.html#a05e660b2b61b9a312e29688289f4bf3e',1,'IRCoolixAC']]], + ['setsensortempraw_3407',['setSensorTempRaw',['../classIRCoolixAC.html#a425c3f5fb26330266156c133fb9104eb',1,'IRCoolixAC']]], + ['setsilent_3408',['setSilent',['../classIRMitsubishiHeavy152Ac.html#ab398b9ea2965f059903137ab088791c0',1,'IRMitsubishiHeavy152Ac']]], + ['setsleep_3409',['setSleep',['../classIRCarrierAc64.html#aa729dbef39afeeed8e83f26b927d3b21',1,'IRCarrierAc64::setSleep()'],['../classIRCoolixAC.html#a4ee44167eca3fc88115fef3e845a3768',1,'IRCoolixAC::setSleep()'],['../classIRDaikin128.html#ac43854ae557ec5582f2bfd9150fd57f2',1,'IRDaikin128::setSleep()'],['../classIRDaikin64.html#a7faf8e018179fed2b091a78d0d69a9b8',1,'IRDaikin64::setSleep()'],['../classIRDelonghiAc.html#aa74806e520b2b01a5b0c87ee32ce427e',1,'IRDelonghiAc::setSleep()'],['../classIRGoodweatherAc.html#a30987629a159c5112649f0973895c9c1',1,'IRGoodweatherAc::setSleep()'],['../classIRGreeAC.html#ac9c11817d15bc5c82732a901cd95e07c',1,'IRGreeAC::setSleep()'],['../classIRHaierAC.html#acb72b89fa53b565f9d32db4d8960f988',1,'IRHaierAC::setSleep()'],['../classIRHaierACYRW02.html#ad63834eb1a91ed974af988c385570457',1,'IRHaierACYRW02::setSleep()'],['../classIRHitachiAc1.html#a2ddb6a5d446b379884828e81df0806ee',1,'IRHitachiAc1::setSleep()'],['../classIRMideaAC.html#a1e008ff673450060bf39a65f1cb926e6',1,'IRMideaAC::setSleep()'],['../classIRNeoclimaAc.html#ad01a62fb369c6894333adb2fe0f52b79',1,'IRNeoclimaAc::setSleep()'],['../classIRTecoAc.html#a1e989a4fbd21c507ba13014b1e336ce2',1,'IRTecoAc::setSleep()'],['../classIRTrotecESP.html#a41c558c6937e61e77269139f96135420',1,'IRTrotecESP::setSleep()'],['../classIRVestelAc.html#a4b93d5585b7fb9d509e7fcf84e2b4abc',1,'IRVestelAc::setSleep()'],['../classIRWhirlpoolAc.html#a6eaa24abc9eac64d9cbe79205a239474',1,'IRWhirlpoolAc::setSleep()']]], + ['setspecial_3410',['setSpecial',['../classIRSharpAc.html#ad7d2eca8b863569a1b17fdca4930d84f',1,'IRSharpAc']]], + ['setspeed_3411',['setSpeed',['../classIRTrotecESP.html#a268146141ce0358c2353c0ff59cfbad3',1,'IRTrotecESP']]], + ['setstartclock_3412',['setStartClock',['../classIRMitsubishiAC.html#a22d8c0dfd8098cb274d915476ed4caae',1,'IRMitsubishiAC']]], + ['setstopclock_3413',['setStopClock',['../classIRMitsubishiAC.html#a228dafbf1ea3e9c3487506a5ca2ea274',1,'IRMitsubishiAC']]], + ['setsuper_3414',['setSuper',['../classIRWhirlpoolAc.html#a19a14674b0bae79d3aee81b8d48aacc7',1,'IRWhirlpoolAc']]], + ['setswing_3415',['setSwing',['../classIRCoolixAC.html#a57e3641e20f072df238b305045e74246',1,'IRCoolixAC::setSwing()'],['../classIRFujitsuAC.html#a60ab8f21b5561e94a322b72a606468b9',1,'IRFujitsuAC::setSwing()'],['../classIRGoodweatherAc.html#a4d11a6885a5e7851e7c941b559159c35',1,'IRGoodweatherAc::setSwing()'],['../classIRHaierAC.html#a28c8bf6e0f45e074bf5eb13c25805627',1,'IRHaierAC::setSwing()'],['../classIRHaierACYRW02.html#ab9152dd09dec2db522dd96778f3b1556',1,'IRHaierACYRW02::setSwing()'],['../classIRSamsungAc.html#aaa7aaca1134e1565f527fcaa96a2fa6e',1,'IRSamsungAc::setSwing()'],['../classIRTecoAc.html#aaaeb10176c0b73e72fdb63b53fdcd5d0',1,'IRTecoAc::setSwing()'],['../classIRVestelAc.html#a6c98427df6e5e8081a6dcbfcd436ff0d',1,'IRVestelAc::setSwing()'],['../classIRWhirlpoolAc.html#a6fec80710ba87599840e576f37e0c944',1,'IRWhirlpoolAc::setSwing()']]], + ['setswingh_3416',['setSwingH',['../classIRElectraAc.html#afcd40681003d57b4f1b652175fc276a8',1,'IRElectraAc::setSwingH()'],['../classIRHitachiAc1.html#af6cc42d52dfed89e23d3d180e7b69af9',1,'IRHitachiAc1::setSwingH()'],['../classIRHitachiAc344.html#a5651cb90ba9b87ef841f8987bad267d4',1,'IRHitachiAc344::setSwingH()'],['../classIRMitsubishi112.html#a99f97b04ac22a7942ea371f470faaf49',1,'IRMitsubishi112::setSwingH()'],['../classIRNeoclimaAc.html#a1aeebc60d7bbd0fb801ad88f639cb6a0',1,'IRNeoclimaAc::setSwingH()']]], + ['setswinghorizontal_3417',['setSwingHorizontal',['../classIRDaikinESP.html#a5a7ec7b00811138879c636b03ae58606',1,'IRDaikinESP::setSwingHorizontal()'],['../classIRDaikin2.html#a75b6d6fb5bab0a9c951ad35e3e1d07c5',1,'IRDaikin2::setSwingHorizontal()'],['../classIRDaikin216.html#af8a1525cbe8d813c419d17ee6776a7d9',1,'IRDaikin216::setSwingHorizontal()'],['../classIRDaikin176.html#a9e63cf22410ffad45f6b308674079ee8',1,'IRDaikin176::setSwingHorizontal()'],['../classIRHitachiAc.html#ae70600f4a6f9fd7579221b11cd73062f',1,'IRHitachiAc::setSwingHorizontal()'],['../classIRKelvinatorAC.html#a2f1731f71bc74fb7ad6fec1210ecb1c7',1,'IRKelvinatorAC::setSwingHorizontal()'],['../classIRMitsubishiHeavy152Ac.html#a8713144e057424809292494a663dcd22',1,'IRMitsubishiHeavy152Ac::setSwingHorizontal()'],['../classIRMitsubishiHeavy88Ac.html#aaceffdd4e631fb2d4c404de0c8ff8cdb',1,'IRMitsubishiHeavy88Ac::setSwingHorizontal()'],['../classIRPanasonicAc.html#a32f3f07813165a39359887485dd87254',1,'IRPanasonicAc::setSwingHorizontal()'],['../classIRTcl112Ac.html#aedc63c59a924d64048bc034a752ce7ed',1,'IRTcl112Ac::setSwingHorizontal()']]], + ['setswingtoggle_3418',['setSwingToggle',['../classIRHitachiAc1.html#a24ec128b6bb27cfc4be4dda9ece003d6',1,'IRHitachiAc1::setSwingToggle()'],['../classIRSharpAc.html#a0d397009ecf213111207fcebb12b95fb',1,'IRSharpAc::setSwingToggle()']]], + ['setswingv_3419',['setSwingV',['../classIRCarrierAc64.html#a61a3f9f29cabc0634a9a74fc2227d8c5',1,'IRCarrierAc64::setSwingV()'],['../classIRDaikin152.html#ad151bb85529d46f7e3e3e65dbf446ff0',1,'IRDaikin152::setSwingV()'],['../classIRElectraAc.html#ae5b33942670e0033cbb9b9c7a1524e93',1,'IRElectraAc::setSwingV()'],['../classIRHitachiAc1.html#a1bcc61a9a33a3ddec41d44d52e7df0d3',1,'IRHitachiAc1::setSwingV()'],['../classIRHitachiAc344.html#a3982f110de8ff9881cf4070902294285',1,'IRHitachiAc344::setSwingV()'],['../classIRMitsubishi136.html#a0d54bc6dd55da18b05f723a1b61e575e',1,'IRMitsubishi136::setSwingV()'],['../classIRMitsubishi112.html#ae33b469f1b67616f101f4a3df874fb78',1,'IRMitsubishi112::setSwingV()'],['../classIRNeoclimaAc.html#aa6e5f6f092f52c5c289642c9576c8bc0',1,'IRNeoclimaAc::setSwingV()']]], + ['setswingvertical_3420',['setSwingVertical',['../classIRDaikinESP.html#a9200ef5751df5d488d7e08b138ec6356',1,'IRDaikinESP::setSwingVertical()'],['../classIRDaikin2.html#a35e72dc8e7967ee8ca8e84a6344468f3',1,'IRDaikin2::setSwingVertical()'],['../classIRDaikin216.html#a851484d5a37ceb1b0fc32e2e4bc2bcbb',1,'IRDaikin216::setSwingVertical()'],['../classIRDaikin160.html#a1683a255393f233d3e5b46d186d62881',1,'IRDaikin160::setSwingVertical()'],['../classIRDaikin128.html#a961aceb41145001003a50c5988f04c4d',1,'IRDaikin128::setSwingVertical()'],['../classIRDaikin64.html#afca186067111fa7181916a218c2800ec',1,'IRDaikin64::setSwingVertical()'],['../classIRGreeAC.html#a1b571dea8a5bf553554e45074f3a01c0',1,'IRGreeAC::setSwingVertical()'],['../classIRHitachiAc.html#a7e3ee78e4835fe402095b544c1e52f9f',1,'IRHitachiAc::setSwingVertical()'],['../classIRKelvinatorAC.html#a7334fbf8f2a67b33562ecea6b6e66f0e',1,'IRKelvinatorAC::setSwingVertical()'],['../classIRMitsubishiHeavy152Ac.html#aea3ac937feff058feef321bfe7357145',1,'IRMitsubishiHeavy152Ac::setSwingVertical()'],['../classIRMitsubishiHeavy88Ac.html#a9406e1890483703afb7b383e1363f8ec',1,'IRMitsubishiHeavy88Ac::setSwingVertical()'],['../classIRPanasonicAc.html#a48f31b1f85c92fac22f85a1aa8074c6e',1,'IRPanasonicAc::setSwingVertical()'],['../classIRTcl112Ac.html#a53f702dcc66de81f6e7e03d538a6946d',1,'IRTcl112Ac::setSwingVertical()']]], + ['setswingvtoggle_3421',['setSwingVToggle',['../classIRCoronaAc.html#a7cb31da86353ec637239cb747890bd7b',1,'IRCoronaAc::setSwingVToggle()'],['../classIRHitachiAc424.html#a220fd85bd213dd13ee9c609d4d7d20c1',1,'IRHitachiAc424::setSwingVToggle()'],['../classIRMideaAC.html#a7fce182bff4f5bc2c6679b20f344837b',1,'IRMideaAC::setSwingVToggle()']]], + ['settemp_3422',['setTemp',['../classIRAmcorAc.html#af4b2c476b76534687f14e9be963e9522',1,'IRAmcorAc::setTemp()'],['../classIRArgoAC.html#abad424a3cf1894715baa03780fa9b53b',1,'IRArgoAC::setTemp()'],['../classIRCarrierAc64.html#a79e193514ac6d07be537a78887426311',1,'IRCarrierAc64::setTemp()'],['../classIRCoolixAC.html#a1d4b4fb810b9f3835ee585b2aa66088f',1,'IRCoolixAC::setTemp()'],['../classIRCoronaAc.html#a9b1d5223cbb6ae6ba07f32871b27d9c6',1,'IRCoronaAc::setTemp()'],['../classIRDaikinESP.html#a631db8830684b745711667aed73a6433',1,'IRDaikinESP::setTemp()'],['../classIRDaikin2.html#a7f752c785fe180d5038e35bb07ff965a',1,'IRDaikin2::setTemp()'],['../classIRDaikin216.html#a8735732d3264eec119127d4353990669',1,'IRDaikin216::setTemp()'],['../classIRDaikin160.html#abedd99ed838478a7ef856537c6fabb82',1,'IRDaikin160::setTemp()'],['../classIRDaikin176.html#acb3b296f4c87a5a37258c666ef886ff3',1,'IRDaikin176::setTemp()'],['../classIRDaikin128.html#aba143a1b80e6de7d1c7b987eeda6b0db',1,'IRDaikin128::setTemp()'],['../classIRDaikin152.html#a97567ade1c0262b3f95f23f171936d8c',1,'IRDaikin152::setTemp()'],['../classIRDaikin64.html#adb1eb657998c05a143365755da0a1e81',1,'IRDaikin64::setTemp()'],['../classIRDelonghiAc.html#a08cc3e32c50277e3f986ed2c3945ce0d',1,'IRDelonghiAc::setTemp()'],['../classIRElectraAc.html#a5f986d9a376b6d5348fcb021d66d235b',1,'IRElectraAc::setTemp()'],['../classIRFujitsuAC.html#ab56c02fc0311ee7f28e780948cbc6a75',1,'IRFujitsuAC::setTemp()'],['../classIRGoodweatherAc.html#a8b1c90f69a3a2e412020d07809d180cc',1,'IRGoodweatherAc::setTemp()'],['../classIRGreeAC.html#a1890c6d134183beb89b791ec565623bb',1,'IRGreeAC::setTemp()'],['../classIRHaierAC.html#a9fb2a375cc1b8692fe4d5dcdd765cc46',1,'IRHaierAC::setTemp()'],['../classIRHaierACYRW02.html#a80170879e7bd391e360d41f18f6fa52b',1,'IRHaierACYRW02::setTemp()'],['../classIRHitachiAc.html#a9f416886ae341cdb6d449572e4d168a9',1,'IRHitachiAc::setTemp()'],['../classIRHitachiAc1.html#a10ba2dcbe447e505cbaa1a9b63f4823c',1,'IRHitachiAc1::setTemp()'],['../classIRHitachiAc424.html#a5cca8f31d07ce87b6e4a0ff0c22b1be8',1,'IRHitachiAc424::setTemp()'],['../classIRKelvinatorAC.html#ab098a376c7393d377abcc6c1f504d372',1,'IRKelvinatorAC::setTemp()'],['../classIRLgAc.html#ad9924a8bc9737ec6007d76ec47b34142',1,'IRLgAc::setTemp()'],['../classIRMideaAC.html#a42f79e73f418d5267eed7ba5b0e266f5',1,'IRMideaAC::setTemp()'],['../classIRMitsubishiAC.html#afd629013630747400e005fab8407d711',1,'IRMitsubishiAC::setTemp()'],['../classIRMitsubishi136.html#ac19c9234a5f65cae50b64d56c4bebb8f',1,'IRMitsubishi136::setTemp()'],['../classIRMitsubishi112.html#a03ba44a6d2f152b7afade423f12c8726',1,'IRMitsubishi112::setTemp()'],['../classIRMitsubishiHeavy152Ac.html#ad4f9ae94b8ab1fff8fc99b8d7818a8fe',1,'IRMitsubishiHeavy152Ac::setTemp()'],['../classIRMitsubishiHeavy88Ac.html#aa4a92e5334aebdca5d2b26b642e9b9e8',1,'IRMitsubishiHeavy88Ac::setTemp()'],['../classIRNeoclimaAc.html#a59e27fa001f9ab674b69eb2c41b6393c',1,'IRNeoclimaAc::setTemp()'],['../classIRPanasonicAc.html#a58376c311177e701333f4915515d49f1',1,'IRPanasonicAc::setTemp()'],['../classIRSamsungAc.html#a94a71e82321343220836aa614b231bd0',1,'IRSamsungAc::setTemp()'],['../classIRSharpAc.html#a151f88799cdab6fda4cfef83b30e5917',1,'IRSharpAc::setTemp()'],['../classIRTcl112Ac.html#a110bae0201b63db0409c352dd8d62786',1,'IRTcl112Ac::setTemp()'],['../classIRTecoAc.html#a405106cb572dac338d79da48fe7a7cb3',1,'IRTecoAc::setTemp()'],['../classIRToshibaAC.html#a923fad1f637e1851a77a063978994604',1,'IRToshibaAC::setTemp()'],['../classIRTrotecESP.html#ad467e7fe9ff61fec4ec10b367c0f9279',1,'IRTrotecESP::setTemp()'],['../classIRVestelAc.html#a8c4eddfba4edfa16e317e12677736756',1,'IRVestelAc::setTemp()'],['../classIRWhirlpoolAc.html#afff1ae75ffa362abb791c97c20023755',1,'IRWhirlpoolAc::setTemp()']]], + ['settempraw_3423',['setTempRaw',['../classIRCoolixAC.html#ae9371280e92daa8e1441523026f1ef0a',1,'IRCoolixAC']]], + ['settempunit_3424',['setTempUnit',['../classIRDelonghiAc.html#a4e3681e49065ba232577ca05157a5ef2',1,'IRDelonghiAc']]], + ['settime_3425',['setTime',['../classIRArgoAC.html#ae285801cde19da82e128098097624852',1,'IRArgoAC::setTime()'],['../classIRHaierAC.html#a81ca00cf5b49308c2609b717d34958ad',1,'IRHaierAC::setTime()'],['../classIRVestelAc.html#afc5dedf83855a8fea8b29494bfb07d64',1,'IRVestelAc::setTime()'],['../classIRWhirlpoolAc.html#a40289737223c14c8a1e723e7a28bad13',1,'IRWhirlpoolAc::setTime()']]], + ['settimer_3426',['setTimer',['../classIRDaikin128.html#a8498de57fc1bdb2f71a678f7877d3125',1,'IRDaikin128::setTimer()'],['../classIRGreeAC.html#a84debd45d2f2ba221f825257e0bc6294',1,'IRGreeAC::setTimer()'],['../classIRMitsubishiAC.html#acb56c91ef0db6ace7782d356af2dcd4d',1,'IRMitsubishiAC::setTimer()'],['../classIRSharpAc.html#a8782543c33e48af0a09e548276eb6413',1,'IRSharpAc::setTimer()'],['../classIRTecoAc.html#a88a84e22d53a204da754c04210fadd04',1,'IRTecoAc::setTimer()'],['../classIRTrotecESP.html#a92bfed0f247b21c77737b720151dbb88',1,'IRTrotecESP::setTimer()'],['../classIRVestelAc.html#a7c66e1ec13c827714eaa2233f50f072b',1,'IRVestelAc::setTimer()']]], + ['settimeractive_3427',['setTimerActive',['../classIRVestelAc.html#a77f78e534b19a8dca776b17aa06739aa',1,'IRVestelAc']]], + ['settimerenabled_3428',['setTimerEnabled',['../classIRGreeAC.html#a1002d6dfe409076fa7ef252589d5043c',1,'IRGreeAC']]], + ['settolerance_3429',['setTolerance',['../classIRrecv.html#aa091c449db70c65fd0221669df7438ea',1,'IRrecv']]], + ['setturbo_3430',['setTurbo',['../classIRCoolixAC.html#a65a04ec9028025155792be5ba0f81927',1,'IRCoolixAC::setTurbo()'],['../classIRDaikin64.html#a734cc23f79a4de4099a4ceb1aff14762',1,'IRDaikin64::setTurbo()'],['../classIRElectraAc.html#adb40e95465788b03e4cb845bd481f7ed',1,'IRElectraAc::setTurbo()'],['../classIRGoodweatherAc.html#a7827fc5a8f85b284c0121727dba34f11',1,'IRGoodweatherAc::setTurbo()'],['../classIRGreeAC.html#ae873023ad81f7dcb12ee5b061e160bea',1,'IRGreeAC::setTurbo()'],['../classIRHaierACYRW02.html#aba5f028ee1ebf7be2d4de5a66237f01b',1,'IRHaierACYRW02::setTurbo()'],['../classIRKelvinatorAC.html#a7d9c44970e85f23c83723f27e96260ee',1,'IRKelvinatorAC::setTurbo()'],['../classIRMitsubishiHeavy152Ac.html#a275e8ae44e2018a848b3e8f0893c8023',1,'IRMitsubishiHeavy152Ac::setTurbo()'],['../classIRMitsubishiHeavy88Ac.html#a39ac892d349180327cce92c6f82bea30',1,'IRMitsubishiHeavy88Ac::setTurbo()'],['../classIRNeoclimaAc.html#aa2a9563d9e3c5c95dfa512c0bb87e16f',1,'IRNeoclimaAc::setTurbo()'],['../classIRSharpAc.html#a8a184ae8eeb07704b9b69849421e3172',1,'IRSharpAc::setTurbo()'],['../classIRTcl112Ac.html#a99e3b3e2f0cc627b6d872d04b35d6230',1,'IRTcl112Ac::setTurbo()'],['../classIRVestelAc.html#afa762d0fa63ecc7444c1c107f8f07cdb',1,'IRVestelAc::setTurbo()']]], + ['setunknownthreshold_3431',['setUnknownThreshold',['../classIRrecv.html#a02693553aad1decd67bdae60402e48bf',1,'IRrecv']]], + ['setusecelsius_3432',['setUseCelsius',['../classIRMideaAC.html#a1eeb72ddd2b9867c2f9c392080b9c1ed',1,'IRMideaAC']]], + ['setusefahrenheit_3433',['setUseFahrenheit',['../classIRGreeAC.html#af559afaa9da5fd27cdb516355da67bd6',1,'IRGreeAC']]], + ['setvane_3434',['setVane',['../classIRMitsubishiAC.html#abb247f1dca5cf23a7b8a16852dcf32f1',1,'IRMitsubishiAC']]], + ['setweeklytimerenable_3435',['setWeeklyTimerEnable',['../classIRDaikinESP.html#a0db67d46b13acfad9b94c7e4691777b8',1,'IRDaikinESP']]], + ['setwidevane_3436',['setWideVane',['../classIRMitsubishiAC.html#a02b2b3d7456e6123c60dca70de346c25',1,'IRMitsubishiAC']]], + ['setwifi_3437',['setWiFi',['../classIRGreeAC.html#afde745ceaa97f9608195b2ba9fce6c5c',1,'IRGreeAC']]], + ['setxfan_3438',['setXFan',['../classIRGreeAC.html#af465c607222fa433f54c2ce56ced2474',1,'IRGreeAC::setXFan()'],['../classIRKelvinatorAC.html#af02da81109109cf1cb44057fd1a40164',1,'IRKelvinatorAC::setXFan()']]], + ['setzonefollow_3439',['setZoneFollow',['../classIRCoolixAC.html#a0c0f39d8e2e79d8259000695263ec3fa',1,'IRCoolixAC']]], + ['sharp_3440',['sharp',['../classIRac.html#a7b6d8b4e554a89f339f896fe4233ed15',1,'IRac::sharp()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaad63db67a2284cd7e3ffe382b6d6ea82',1,'SHARP(): IRremoteESP8266.h']]], + ['sharp_5fac_3441',['SHARP_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada353a9d71906702ae10aa4f803a04ca68',1,'IRremoteESP8266.h']]], + ['sherwood_3442',['SHERWOOD',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1412522651b0c8f1a35e1db3807466bb',1,'IRremoteESP8266.h']]], + ['sleep_3443',['sleep',['../structstdAc_1_1state__t.html#a94fa6098d7422292a1c6943973cd106a',1,'stdAc::state_t']]], + ['sleepflag_3444',['sleepFlag',['../classIRCoolixAC.html#a26560e04d1f77830e40e5570845b9e06',1,'IRCoolixAC']]], + ['sony_3445',['SONY',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada72d58193d4d25517202d22b7e57a65c3',1,'IRremoteESP8266.h']]], + ['sony_5f38k_3446',['SONY_38K',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0027bcfbb78c0c2b951dfff1102a027b',1,'IRremoteESP8266.h']]], + ['space_3447',['space',['../classIRsend.html#a0417b10d4e16718a87f8b2062a7d04a1',1,'IRsend']]], + ['start_3448',['start',['../classIRtimer.html#aaa087b8688ff8150e0fc1ec6d5c4a52a',1,'IRtimer::start()'],['../classTimerMs.html#a15ad2e08a5931397391d48f040722f65',1,'TimerMs::start()']]], + ['state_3449',['state',['../classdecode__results.html#aaeb4b1b2e950bdd181582c385b2f4305',1,'decode_results']]], + ['state_5ft_3450',['state_t',['../structstdAc_1_1state__t.html',1,'stdAc']]], + ['statereset_3451',['stateReset',['../classIRAmcorAc.html#a018ab4ca4d738d848d3388ea1300b83b',1,'IRAmcorAc::stateReset()'],['../classIRArgoAC.html#af34a99bc37c4496c9fd68856aa065a13',1,'IRArgoAC::stateReset()'],['../classIRCarrierAc64.html#abe58c8f97ab4c34fd0cf198b07589694',1,'IRCarrierAc64::stateReset()'],['../classIRCoolixAC.html#a88a44b7ba5ac7d5654de4592bd41c207',1,'IRCoolixAC::stateReset()'],['../classIRCoronaAc.html#a47726d4ff93528bd8a5a6f1b47ba7141',1,'IRCoronaAc::stateReset()'],['../classIRDaikinESP.html#a49f6b90336225f7e94b8aefd066e1993',1,'IRDaikinESP::stateReset()'],['../classIRDaikin2.html#a9b49e90604bf6b1abb93581eecfc6c88',1,'IRDaikin2::stateReset()'],['../classIRDaikin216.html#adbc856e6531b38963db5680d279a4767',1,'IRDaikin216::stateReset()'],['../classIRDaikin160.html#ade56e55c8a0c81f0803dec2cda4625b0',1,'IRDaikin160::stateReset()'],['../classIRDaikin176.html#ab86a1b458a1be5d7fe5fcb7e287ef1d3',1,'IRDaikin176::stateReset()'],['../classIRDaikin128.html#ab604a7594c3b0131c5d977e3fc3b3565',1,'IRDaikin128::stateReset()'],['../classIRDaikin152.html#a278291def7d0e14552e7fbe9a56346bd',1,'IRDaikin152::stateReset()'],['../classIRDaikin64.html#af5a691404b8026cf1da45502f1c019f4',1,'IRDaikin64::stateReset()'],['../classIRDelonghiAc.html#aac444790a16678a1e88f1adef02829ba',1,'IRDelonghiAc::stateReset()'],['../classIRElectraAc.html#ab8035c14158fcf3758f46f6976b814f7',1,'IRElectraAc::stateReset()'],['../classIRFujitsuAC.html#a603a0e1870f406e4e746a7bb4c37fb70',1,'IRFujitsuAC::stateReset()'],['../classIRGoodweatherAc.html#ae7f8873ad58e553dc89307220628bebf',1,'IRGoodweatherAc::stateReset()'],['../classIRGreeAC.html#a61356a0dfb4656ac438c3629c591b165',1,'IRGreeAC::stateReset()'],['../classIRHaierAC.html#a62fbae1d2bac01ac3a2194274aa839d9',1,'IRHaierAC::stateReset()'],['../classIRHaierACYRW02.html#a106e7ffa0d69cdf976087c6e190d03ea',1,'IRHaierACYRW02::stateReset()'],['../classIRHitachiAc.html#a0564c00c60e64e57e20f3c1a4bd3d894',1,'IRHitachiAc::stateReset()'],['../classIRHitachiAc1.html#a9764b329d982d018b15098b3044f9596',1,'IRHitachiAc1::stateReset()'],['../classIRHitachiAc424.html#afd8d5b21086b34cdc07b498157240f8f',1,'IRHitachiAc424::stateReset()'],['../classIRHitachiAc3.html#a7bdcddf9c7f85b7cb43a92198e422549',1,'IRHitachiAc3::stateReset()'],['../classIRHitachiAc344.html#ab0174472d44790a5516b8f4377a89f22',1,'IRHitachiAc344::stateReset()'],['../classIRKelvinatorAC.html#ad6fefe85023c3fc318b0e45924874f9f',1,'IRKelvinatorAC::stateReset()'],['../classIRLgAc.html#a5959000c9f0b2cf64742d6a2f1c4c9b9',1,'IRLgAc::stateReset()'],['../classIRMideaAC.html#acc584e07406e1811acfb26f6cd5383cd',1,'IRMideaAC::stateReset()'],['../classIRMitsubishiAC.html#a8da4be360c8e2fd3a5a40cb4049b5d84',1,'IRMitsubishiAC::stateReset()'],['../classIRMitsubishi136.html#a67556dab7ed42c68a274f4f24ecc35bb',1,'IRMitsubishi136::stateReset()'],['../classIRMitsubishi112.html#a9c601ba34e10d5c63886c2c5b405d9ae',1,'IRMitsubishi112::stateReset()'],['../classIRMitsubishiHeavy152Ac.html#a0b239cacd3a8a96f2e3d7047f26119da',1,'IRMitsubishiHeavy152Ac::stateReset()'],['../classIRMitsubishiHeavy88Ac.html#a1cf118f435c99372c89a140a79c67f1f',1,'IRMitsubishiHeavy88Ac::stateReset()'],['../classIRNeoclimaAc.html#a5ce32a6e6195b246696cb609994f3762',1,'IRNeoclimaAc::stateReset()'],['../classIRPanasonicAc.html#a9a9fbf531f04c486edf913c382351b2b',1,'IRPanasonicAc::stateReset()'],['../classIRSamsungAc.html#a52186401655966b3103d3d73fb77e7f0',1,'IRSamsungAc::stateReset()'],['../classIRSharpAc.html#aa151c704ba4f5690a7cfadaf90c4b60d',1,'IRSharpAc::stateReset()'],['../classIRTcl112Ac.html#a049f475c1af7b62b9f3482dcf9e66d4a',1,'IRTcl112Ac::stateReset()'],['../classIRTecoAc.html#ad53e6f3d3693ee6efb419326a3d4c492',1,'IRTecoAc::stateReset()'],['../classIRToshibaAC.html#a3d3c3df261b4db7a9d831c94cc206e8a',1,'IRToshibaAC::stateReset()'],['../classIRTrotecESP.html#a86c3415d8c1880c325bc22c2c4ca44e0',1,'IRTrotecESP::stateReset()'],['../classIRVestelAc.html#a921100234f5751f8b94d9673a5d217f9',1,'IRVestelAc::stateReset()'],['../classIRWhirlpoolAc.html#a371a6f48a2f4f66e4243dacbbf4471be',1,'IRWhirlpoolAc::stateReset()']]], + ['stdac_3452',['stdAc',['../namespacestdAc.html',1,'']]], + ['stephoriz_3453',['stepHoriz',['../classIRFujitsuAC.html#a53c48bc1f32c849263a3aa86ff06b1d4',1,'IRFujitsuAC']]], + ['stepvert_3454',['stepVert',['../classIRFujitsuAC.html#a942f106c27ce04094b5b615f2e174022',1,'IRFujitsuAC']]], + ['string_3455',['String',['../IRremoteESP8266_8h.html#afbeda3fd1bdc8c37d01bdf9f5c8274ff',1,'IRremoteESP8266.h']]], + ['strtobool_3456',['strToBool',['../classIRac.html#a3dba736fe25bd3a3a47b9ec7dae51728',1,'IRac']]], + ['strtodecodetype_3457',['strToDecodeType',['../IRutils_8cpp.html#ae1614f315c1ebc44eaf1ac62055cc1ff',1,'strToDecodeType(const char *const str): IRutils.cpp'],['../IRutils_8h.html#a10b9312e4ac9c96d895af83db01ed72e',1,'strToDecodeType(const char *str): IRutils.cpp']]], + ['strtofanspeed_3458',['strToFanspeed',['../classIRac.html#a7173b12c155d04dd1db07a055f4ecb03',1,'IRac']]], + ['strtomodel_3459',['strToModel',['../classIRac.html#a7036fbbb918d644a98b5efa16374a256',1,'IRac']]], + ['strtoopmode_3460',['strToOpmode',['../classIRac.html#a251fa76ddacc84d2655bac723b7dea28',1,'IRac']]], + ['strtoswingh_3461',['strToSwingH',['../classIRac.html#a294d6040909519f465945245df56e56d',1,'IRac']]], + ['strtoswingv_3462',['strToSwingV',['../classIRac.html#a538c861d79afabb11fb8becedd3962f8',1,'IRac']]], + ['success_3463',['success',['../structmatch__result__t.html#a13fe18ae6cf89364df443a64295b2f90',1,'match_result_t']]], + ['sumbytes_3464',['sumBytes',['../IRutils_8cpp.html#abfbd3d7cc33d0aac341e6619f3390108',1,'sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init): IRutils.cpp'],['../IRutils_8h.html#a3f33bdd680bea210b212d4e9925eb8eb',1,'sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0): IRutils.cpp']]], + ['sumnibbles_3465',['sumNibbles',['../namespaceirutils.html#a4752ecc3eafa3ca2e13344a52519b343',1,'irutils::sumNibbles(const uint8_t *const start, const uint16_t length, const uint8_t init)'],['../namespaceirutils.html#aeb5202fa0093ee6b7e07d4290229fbd2',1,'irutils::sumNibbles(const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)']]], + ['swingflag_3466',['swingFlag',['../classIRCoolixAC.html#a6d61903a90cebef56b931bebbfa5cba3',1,'IRCoolixAC']]], + ['swingh_3467',['swingh',['../structstdAc_1_1state__t.html#a761bb702891ed1fa35906929a4c8a3f8',1,'stdAc::state_t']]], + ['swingh_5ft_3468',['swingh_t',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147',1,'stdAc']]], + ['swinghflag_3469',['swingHFlag',['../classIRCoolixAC.html#a1c5fb27fb58d4d1a1fd8c9931eba58c4',1,'IRCoolixAC']]], + ['swinghtostring_3470',['swinghToString',['../classIRac.html#a21c9d71bbf229fd8369480e50a7c3689',1,'IRac']]], + ['swingv_3471',['swingv',['../structstdAc_1_1state__t.html#a35477d368350d8981ad8b7b09505857e',1,'stdAc::state_t']]], + ['swingv_5ft_3472',['swingv_t',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43',1,'stdAc']]], + ['swingvflag_3473',['swingVFlag',['../classIRCoolixAC.html#adf18ad8494466f6301176ce10aa3a075',1,'IRCoolixAC']]], + ['swingvtostring_3474',['swingvToString',['../classIRac.html#a641b59e48183a8f6d9b739ce7210f142',1,'IRac']]], + ['symphony_3475',['SYMPHONY',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada44c4a84d776e02328ef3b169e743e5ec',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.html new file mode 100644 index 000000000..72d12e90e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.js new file mode 100644 index 000000000..ee5a479d4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.js @@ -0,0 +1,28 @@ +var searchData= +[ + ['tcl112_3476',['tcl112',['../classIRac.html#a3028bd9e83956d57b592bb96638b3f59',1,'IRac']]], + ['tcl112ac_3477',['TCL112AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac4a6ebe702365620ed65ac6f484afda6',1,'IRremoteESP8266.h']]], + ['teco_3478',['teco',['../classIRac.html#a9e612e04e270dd5710e8a63a64b56064',1,'IRac::teco()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3a15ee4466478d484508acc3d4d7a050',1,'TECO(): IRremoteESP8266.h']]], + ['tickshigh_3479',['ticksHigh',['../classIRrecv.html#a573dbb20695f2ffc808623df8c36280c',1,'IRrecv']]], + ['tickslow_3480',['ticksLow',['../classIRrecv.html#ac08e50c5eec10c0095157f4bdd4051c8',1,'IRrecv']]], + ['timeout_3481',['timeout',['../structirparams__t.html#a132d6448ad59f03f6b35c4b04a6d1af4',1,'irparams_t']]], + ['timer_3482',['timer',['../structirparams__t.html#a6d4594a4d6bf8a2587095be7adfc018d',1,'irparams_t']]], + ['timerms_3483',['TimerMs',['../classTimerMs.html',1,'TimerMs'],['../classTimerMs.html#a7bf7f8d2fcf76b27b34ea4705810eef5',1,'TimerMs::TimerMs()']]], + ['tocommon_3484',['toCommon',['../classIRAmcorAc.html#aac4ae204cf0c393c18e5de96c4ba44ab',1,'IRAmcorAc::toCommon()'],['../classIRArgoAC.html#a4b1fda530b50c30cb863a3c146f4c81b',1,'IRArgoAC::toCommon()'],['../classIRCarrierAc64.html#a7c4a84d0d9f1e78ba611e118ddb90635',1,'IRCarrierAc64::toCommon()'],['../classIRCoolixAC.html#acadeabae7017e49c944eb22528297b3a',1,'IRCoolixAC::toCommon()'],['../classIRCoronaAc.html#a78dee47464e312d57e660b34c10bb13c',1,'IRCoronaAc::toCommon()'],['../classIRDaikinESP.html#a6bc97a753db054ce2ed59809845e23f1',1,'IRDaikinESP::toCommon()'],['../classIRDaikin2.html#a090407aff4ef81714e31ef28ac41d8e2',1,'IRDaikin2::toCommon()'],['../classIRDaikin216.html#ac477511261d7f135ee4f909eb5512f9a',1,'IRDaikin216::toCommon()'],['../classIRDaikin160.html#a0641f2e7f86412a36dcbe98b9049d322',1,'IRDaikin160::toCommon()'],['../classIRDaikin176.html#ac99fcb66d866196b51ad11384154f8ae',1,'IRDaikin176::toCommon()'],['../classIRDaikin128.html#a54de8ff37216f7a3a2cc744d97c2e1c6',1,'IRDaikin128::toCommon()'],['../classIRDaikin152.html#a96fee4c7cee70cc9249c556b277b2f74',1,'IRDaikin152::toCommon()'],['../classIRDaikin64.html#ad57748fa03e79a277508aa42b08c8f83',1,'IRDaikin64::toCommon()'],['../classIRDelonghiAc.html#a2cdcd20dffb763a5f9ff7bd264c1d3e8',1,'IRDelonghiAc::toCommon()'],['../classIRElectraAc.html#ad10aba2fa72f4b839538fc5a99c696ad',1,'IRElectraAc::toCommon()'],['../classIRFujitsuAC.html#adfd6ff9d4449eae7a5268b26058a483f',1,'IRFujitsuAC::toCommon()'],['../classIRGoodweatherAc.html#ae616e9fc03406ec88b5c5ddcde5f2f2c',1,'IRGoodweatherAc::toCommon()'],['../classIRGreeAC.html#ac28c640aa4b5dd0dbbca42b056f877f7',1,'IRGreeAC::toCommon()'],['../classIRHaierAC.html#a1e74862d6ab7e65108a7b1a3b7af7e91',1,'IRHaierAC::toCommon()'],['../classIRHaierACYRW02.html#aff86d2e3e1d357f0eecf6322964e7c16',1,'IRHaierACYRW02::toCommon()'],['../classIRHitachiAc.html#aa1ec8cc4b5025272c72dc69c6d6486a3',1,'IRHitachiAc::toCommon()'],['../classIRHitachiAc1.html#aef93034682210a6c564fbea4461ab47e',1,'IRHitachiAc1::toCommon()'],['../classIRHitachiAc424.html#a36711772ebdf385e0a95564f8a552634',1,'IRHitachiAc424::toCommon()'],['../classIRHitachiAc344.html#a146203ad02a3df4037b97c0416ba828e',1,'IRHitachiAc344::toCommon()'],['../classIRKelvinatorAC.html#a1e900aa29dad75f74de2bb797d475b20',1,'IRKelvinatorAC::toCommon()'],['../classIRLgAc.html#a75c52ef31270f25651521ae2be558faa',1,'IRLgAc::toCommon()'],['../classIRMideaAC.html#a62086b58f71908b75e28a61bd4f6bf15',1,'IRMideaAC::toCommon()'],['../classIRMitsubishiAC.html#a42338266a34940e657e5226c81f2fd06',1,'IRMitsubishiAC::toCommon()'],['../classIRMitsubishi136.html#a938360f488ec923e138744b6f80477bb',1,'IRMitsubishi136::toCommon()'],['../classIRMitsubishi112.html#aadde5055371b418fd733a2e93d12b478',1,'IRMitsubishi112::toCommon()'],['../classIRMitsubishiHeavy152Ac.html#af9cbfb13cd48d5d503756c50df8fc7b7',1,'IRMitsubishiHeavy152Ac::toCommon()'],['../classIRMitsubishiHeavy88Ac.html#a3f80427169359dc72367e6ee4e52c42f',1,'IRMitsubishiHeavy88Ac::toCommon()'],['../classIRNeoclimaAc.html#a455397211c7cb8074f6b7358dc6a5b9e',1,'IRNeoclimaAc::toCommon()'],['../classIRPanasonicAc.html#af2218f117db06424ced00ba6c0cc3234',1,'IRPanasonicAc::toCommon()'],['../classIRSamsungAc.html#a01e9279d541f64ebfa433c35a3651796',1,'IRSamsungAc::toCommon()'],['../classIRSharpAc.html#aaade155b2128ba11c2e91bba676c72d9',1,'IRSharpAc::toCommon()'],['../classIRTcl112Ac.html#af5813975bfe55a76d202f8c7f48df82d',1,'IRTcl112Ac::toCommon()'],['../classIRTecoAc.html#af3953289854dabf105c6612f14ef5da0',1,'IRTecoAc::toCommon()'],['../classIRToshibaAC.html#acda90e0171043c3a673ffac52ef9b4b5',1,'IRToshibaAC::toCommon()'],['../classIRTrotecESP.html#ac224a0a18a64ce9802c3f25fafa20a04',1,'IRTrotecESP::toCommon()'],['../classIRVestelAc.html#adb7ab58e91f13b999b62559fc7add91a',1,'IRVestelAc::toCommon()'],['../classIRWhirlpoolAc.html#a961da338e344fd975934f9f69d97f5b5',1,'IRWhirlpoolAc::toCommon()']]], + ['tocommonfanspeed_3485',['toCommonFanSpeed',['../classIRAmcorAc.html#a951aa81d98c66138f61069431e13f35a',1,'IRAmcorAc::toCommonFanSpeed()'],['../classIRArgoAC.html#a334afe3ce6536089bc2832985067f029',1,'IRArgoAC::toCommonFanSpeed()'],['../classIRCarrierAc64.html#a5a9149acc82fcc22a5be8dcbe791ab77',1,'IRCarrierAc64::toCommonFanSpeed()'],['../classIRCoolixAC.html#a6a0e7219c667eb06897b47a7c36f5fbc',1,'IRCoolixAC::toCommonFanSpeed()'],['../classIRCoronaAc.html#a6d5d0015f01acc97badff7edda964485',1,'IRCoronaAc::toCommonFanSpeed()'],['../classIRDaikinESP.html#a6855a423f10a2230953646d478400574',1,'IRDaikinESP::toCommonFanSpeed()'],['../classIRDaikin176.html#a6f9b7dddcf98c7a42495c900dddf505d',1,'IRDaikin176::toCommonFanSpeed()'],['../classIRDaikin128.html#a1c53a27678731229308e355eb94ec762',1,'IRDaikin128::toCommonFanSpeed()'],['../classIRDaikin64.html#acd24c4932e2bfd6bffbb9a90da2028a6',1,'IRDaikin64::toCommonFanSpeed()'],['../classIRDelonghiAc.html#a231e26843e3616e7455fd020dbb8807b',1,'IRDelonghiAc::toCommonFanSpeed()'],['../classIRElectraAc.html#a5d53fb85582344cfdbfa33da6acbdb7d',1,'IRElectraAc::toCommonFanSpeed()'],['../classIRFujitsuAC.html#a93a35e42d887b5ca6414b295a4a91526',1,'IRFujitsuAC::toCommonFanSpeed()'],['../classIRGoodweatherAc.html#aff899c76d5b808ee35c9f88c116b5dc4',1,'IRGoodweatherAc::toCommonFanSpeed()'],['../classIRGreeAC.html#ade6cb54e99b6dab1df708cbf25fc5967',1,'IRGreeAC::toCommonFanSpeed()'],['../classIRHaierAC.html#ad67ee0b7299d041aad77382dde893229',1,'IRHaierAC::toCommonFanSpeed()'],['../classIRHaierACYRW02.html#a15402e3ba2a9875d5b49f6dab3e85034',1,'IRHaierACYRW02::toCommonFanSpeed()'],['../classIRHitachiAc.html#afba02d48c4a023ed800abf38d5314c7e',1,'IRHitachiAc::toCommonFanSpeed()'],['../classIRHitachiAc1.html#a99f205391deb75d23d08d63e1feff0d4',1,'IRHitachiAc1::toCommonFanSpeed()'],['../classIRHitachiAc424.html#a16abdf55ea3ae4b06e2a23dad3496738',1,'IRHitachiAc424::toCommonFanSpeed()'],['../classIRKelvinatorAC.html#a0ebd262c554c5c843bc3f710570e1401',1,'IRKelvinatorAC::toCommonFanSpeed()'],['../classIRLgAc.html#af47317ba139a4b1e5961b9a45db974df',1,'IRLgAc::toCommonFanSpeed()'],['../classIRMideaAC.html#acd89d4864a46b146ac4f648c4406ded5',1,'IRMideaAC::toCommonFanSpeed()'],['../classIRMitsubishiAC.html#aa7dd30cde520b14575d7fcd992c3bbf1',1,'IRMitsubishiAC::toCommonFanSpeed()'],['../classIRMitsubishi136.html#aaf9f9f17f3ac59ef325b57b9110faa34',1,'IRMitsubishi136::toCommonFanSpeed()'],['../classIRMitsubishi112.html#aaeee082d9adbf7b0d91316c703571f1a',1,'IRMitsubishi112::toCommonFanSpeed()'],['../classIRMitsubishiHeavy152Ac.html#a5e26c3121aceb944fc688e6f641dd5b1',1,'IRMitsubishiHeavy152Ac::toCommonFanSpeed()'],['../classIRMitsubishiHeavy88Ac.html#aa5dae03951ba9a9aeac62184c27f9439',1,'IRMitsubishiHeavy88Ac::toCommonFanSpeed()'],['../classIRNeoclimaAc.html#a5d87285928bd8bfa2abad92fbdf384b5',1,'IRNeoclimaAc::toCommonFanSpeed()'],['../classIRPanasonicAc.html#a1eff8e4d670abc303a02d8baeeb58f8c',1,'IRPanasonicAc::toCommonFanSpeed()'],['../classIRSamsungAc.html#a2905b33c273d2be6cabfc3b16b51a5b4',1,'IRSamsungAc::toCommonFanSpeed()'],['../classIRSharpAc.html#a520666e591965b3b3b2421e06260976a',1,'IRSharpAc::toCommonFanSpeed()'],['../classIRTcl112Ac.html#a66843ee5b53ce9be1aef3774b8df5c84',1,'IRTcl112Ac::toCommonFanSpeed()'],['../classIRTecoAc.html#ac3ad2828770440695969d696ca6ff46d',1,'IRTecoAc::toCommonFanSpeed()'],['../classIRToshibaAC.html#a6c77121c9aba3928e676394f88e88dee',1,'IRToshibaAC::toCommonFanSpeed()'],['../classIRTrotecESP.html#a4aaf17993757533370290fffb728befc',1,'IRTrotecESP::toCommonFanSpeed()'],['../classIRVestelAc.html#a6dfd46f56f2d6b15344722cde0741500',1,'IRVestelAc::toCommonFanSpeed()'],['../classIRWhirlpoolAc.html#a61ef6661a985763540b7c2273b8b1b9c',1,'IRWhirlpoolAc::toCommonFanSpeed()']]], + ['tocommonmode_3486',['toCommonMode',['../classIRAmcorAc.html#a6da2f34f1e044f815e94ede578f4c26f',1,'IRAmcorAc::toCommonMode()'],['../classIRArgoAC.html#a8ccd3f5398f50548fda3a9e0172fb5fa',1,'IRArgoAC::toCommonMode()'],['../classIRCarrierAc64.html#ab17b24d0306b8983886d15175898909e',1,'IRCarrierAc64::toCommonMode()'],['../classIRCoolixAC.html#a789fb5d5eab2e78d392c8e0b9a194b18',1,'IRCoolixAC::toCommonMode()'],['../classIRCoronaAc.html#a04ca6532beb099893eb1dd5d01bb4d31',1,'IRCoronaAc::toCommonMode()'],['../classIRDaikinESP.html#a3a7543204520da36547c163a96e30deb',1,'IRDaikinESP::toCommonMode()'],['../classIRDaikin176.html#aa0b9c96d3bf08400a5110bcfa9f1ec9d',1,'IRDaikin176::toCommonMode()'],['../classIRDaikin128.html#a105a4fc511feba96afc956bb36d2dc50',1,'IRDaikin128::toCommonMode()'],['../classIRDaikin64.html#a80b9dd0fbf935bed5035463af2ad0102',1,'IRDaikin64::toCommonMode()'],['../classIRDelonghiAc.html#a5a3eef369009836a629369cf835741c4',1,'IRDelonghiAc::toCommonMode()'],['../classIRElectraAc.html#a01bd399c3b8908083b95f31d97ddb26f',1,'IRElectraAc::toCommonMode()'],['../classIRFujitsuAC.html#a96140e74d31631581003064f70041d02',1,'IRFujitsuAC::toCommonMode()'],['../classIRGoodweatherAc.html#ab3bcd1354b715179f67499c28fb219fb',1,'IRGoodweatherAc::toCommonMode()'],['../classIRGreeAC.html#a3f393071163fd1577c772a8515e2b5a9',1,'IRGreeAC::toCommonMode()'],['../classIRHaierAC.html#a4d73f75516afff0ef18bdbb7ed9c26ed',1,'IRHaierAC::toCommonMode()'],['../classIRHaierACYRW02.html#a24007a5be360c93ec157b95c8cc06493',1,'IRHaierACYRW02::toCommonMode()'],['../classIRHitachiAc.html#ab7edc0f5571100e1778779081e1c1114',1,'IRHitachiAc::toCommonMode()'],['../classIRHitachiAc1.html#a5cbca62775089593fe2447a77d84b3d5',1,'IRHitachiAc1::toCommonMode()'],['../classIRHitachiAc424.html#a2a725d8dc2178975c977a7496792e667',1,'IRHitachiAc424::toCommonMode()'],['../classIRKelvinatorAC.html#ae2683d38ae72b99e6843e37d36f96db2',1,'IRKelvinatorAC::toCommonMode()'],['../classIRLgAc.html#ac3436968a4445f0210403c353d766b73',1,'IRLgAc::toCommonMode()'],['../classIRMideaAC.html#ac2e0ff374678aadd7fea80194aef8bca',1,'IRMideaAC::toCommonMode()'],['../classIRMitsubishiAC.html#a7eae5da584faf41139be597d6a5e7210',1,'IRMitsubishiAC::toCommonMode()'],['../classIRMitsubishi136.html#a2771fd09b2e953b037c0c65c4e4029ee',1,'IRMitsubishi136::toCommonMode()'],['../classIRMitsubishi112.html#a6da77ebe6e03cfc09aa35e531c292ed1',1,'IRMitsubishi112::toCommonMode()'],['../classIRMitsubishiHeavy152Ac.html#a9faaff371ad3ec33de5646a1afd1992a',1,'IRMitsubishiHeavy152Ac::toCommonMode()'],['../classIRNeoclimaAc.html#a2a220b673c96e54e675d8296aa8b2303',1,'IRNeoclimaAc::toCommonMode()'],['../classIRPanasonicAc.html#a1ace0180b9ac3f4bd17357a03c64792e',1,'IRPanasonicAc::toCommonMode()'],['../classIRSamsungAc.html#a39820a05a9650e9da8a44109234a8d87',1,'IRSamsungAc::toCommonMode()'],['../classIRSharpAc.html#a5e8fca86bcf138bb7c1fd1b4e4384b5f',1,'IRSharpAc::toCommonMode()'],['../classIRTcl112Ac.html#a230a8d768089d869efdea6589b0a9e37',1,'IRTcl112Ac::toCommonMode()'],['../classIRTecoAc.html#ac6c7011b31208887de6d15edbffb211a',1,'IRTecoAc::toCommonMode()'],['../classIRToshibaAC.html#a77871a927ee67460b7bdcb8f204297bc',1,'IRToshibaAC::toCommonMode()'],['../classIRTrotecESP.html#a2b28b06bd25234427d90172b27d57092',1,'IRTrotecESP::toCommonMode()'],['../classIRVestelAc.html#add602c0f052c8ada3b3b5748dda50a58',1,'IRVestelAc::toCommonMode()'],['../classIRWhirlpoolAc.html#a748caa4e22f2f1f47e6334b1a031c4d8',1,'IRWhirlpoolAc::toCommonMode()']]], + ['tocommonswingh_3487',['toCommonSwingH',['../classIRDaikin2.html#a85bb152a4bdcc2798270ee58a3cfe2ae',1,'IRDaikin2::toCommonSwingH()'],['../classIRDaikin176.html#a6a3b66c9777992ed9fcab4e26c1d74dc',1,'IRDaikin176::toCommonSwingH()'],['../classIRHitachiAc344.html#a31562e32ccdf179032e75334b16279f0',1,'IRHitachiAc344::toCommonSwingH()'],['../classIRMitsubishiAC.html#ad7446e0a4ea8d349004c2b4224e69cd9',1,'IRMitsubishiAC::toCommonSwingH()'],['../classIRMitsubishi112.html#a17cfee6dc9ddc38465539ca46f29b263',1,'IRMitsubishi112::toCommonSwingH()'],['../classIRMitsubishiHeavy152Ac.html#afb9e039776c77e898928e9139a21a2b8',1,'IRMitsubishiHeavy152Ac::toCommonSwingH()'],['../classIRMitsubishiHeavy88Ac.html#aead69a01407729240055bd64e583b51b',1,'IRMitsubishiHeavy88Ac::toCommonSwingH()'],['../classIRPanasonicAc.html#aa4241990c350ca936c73b8391c2a11fc',1,'IRPanasonicAc::toCommonSwingH()']]], + ['tocommonswingv_3488',['toCommonSwingV',['../classIRDaikin2.html#a1f3e17757bd4beb0330d75ec3df9788b',1,'IRDaikin2::toCommonSwingV()'],['../classIRDaikin160.html#afae9b50e59c0efa46b96eef9f05a95b7',1,'IRDaikin160::toCommonSwingV()'],['../classIRGreeAC.html#a537d17801a90e22ad2baba7145b038cb',1,'IRGreeAC::toCommonSwingV()'],['../classIRHaierAC.html#aac354e2e4ad72d91667509398078b309',1,'IRHaierAC::toCommonSwingV()'],['../classIRHaierACYRW02.html#a0e426a3479fd80bb3816f016fac22f19',1,'IRHaierACYRW02::toCommonSwingV()'],['../classIRMitsubishiAC.html#a173e3c22f4173f235e7213e41925fdd9',1,'IRMitsubishiAC::toCommonSwingV()'],['../classIRMitsubishi136.html#aca5e6ac2d886083c8c56e2949f9d11e9',1,'IRMitsubishi136::toCommonSwingV()'],['../classIRMitsubishi112.html#a0e577d8554a090d7f2ac2a9ddd3bf15c',1,'IRMitsubishi112::toCommonSwingV()'],['../classIRMitsubishiHeavy152Ac.html#ae4dd9b8f0b5b4becb07618e859a09a51',1,'IRMitsubishiHeavy152Ac::toCommonSwingV()'],['../classIRMitsubishiHeavy88Ac.html#a0597303839e79c97b0fafe6c9ddbcf9a',1,'IRMitsubishiHeavy88Ac::toCommonSwingV()'],['../classIRPanasonicAc.html#adae801e0a2641c196a59d65c26404a13',1,'IRPanasonicAc::toCommonSwingV()']]], + ['todo_20list_3489',['Todo List',['../todo.html',1,'']]], + ['togglerc5_3490',['toggleRC5',['../classIRsend.html#a42a78d4a3ef0f88b54bee488320344da',1,'IRsend']]], + ['togglerc6_3491',['toggleRC6',['../classIRsend.html#a5a0e8778394021ea12a8b8c2daf0add6',1,'IRsend']]], + ['toggleswinghoriz_3492',['toggleSwingHoriz',['../classIRFujitsuAC.html#aeba829bb9a9934ad9246a5ba4f4c03fc',1,'IRFujitsuAC']]], + ['toggleswingvert_3493',['toggleSwingVert',['../classIRFujitsuAC.html#a6dc9cc4bda83215fa97896c41b01e584',1,'IRFujitsuAC']]], + ['toshiba_3494',['toshiba',['../classIRac.html#a384e62cc56ebbdd790ebcd500ce56fc5',1,'IRac']]], + ['toshiba_5fac_3495',['TOSHIBA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada66de3fced9e8f97d1919bcf4d5726f3e',1,'IRremoteESP8266.h']]], + ['tostring_3496',['toString',['../classIRAmcorAc.html#a2435fd76c642e4a64c7e2330236dcaa6',1,'IRAmcorAc::toString()'],['../classIRArgoAC.html#ad9f52d54687754c0b8d676cb75a3b1bf',1,'IRArgoAC::toString()'],['../classIRCarrierAc64.html#acede081614a80ae46345d4ae45e39ab2',1,'IRCarrierAc64::toString()'],['../classIRCoolixAC.html#ad1282b4071f003ab35d2a97287ba6d2d',1,'IRCoolixAC::toString()'],['../classIRCoronaAc.html#a13e87d763ffd0d25a9d09010828c2124',1,'IRCoronaAc::toString()'],['../classIRDaikinESP.html#a38e705d3ed5128e400efd971e50518d5',1,'IRDaikinESP::toString()'],['../classIRDaikin2.html#a5804ef19f37ee7b8a525bc8db5146c73',1,'IRDaikin2::toString()'],['../classIRDaikin216.html#a5b9ea30424aa3abd9fdee95c78ba9e40',1,'IRDaikin216::toString()'],['../classIRDaikin160.html#a5d9ff2f09b95023c595e9c4794cb29b8',1,'IRDaikin160::toString()'],['../classIRDaikin176.html#a5ff8d589c7e97bd48b50e0ae01356783',1,'IRDaikin176::toString()'],['../classIRDaikin128.html#a48fc2a4080400f83260d2c861c831a28',1,'IRDaikin128::toString()'],['../classIRDaikin152.html#abb9253e8fe7e9bdf786246ce7ab8c54b',1,'IRDaikin152::toString()'],['../classIRDaikin64.html#aa19ba82f1dd405633f078eaf5cb915b8',1,'IRDaikin64::toString()'],['../classIRDelonghiAc.html#a386fb70137a7c2100d05f3202c224887',1,'IRDelonghiAc::toString()'],['../classIRElectraAc.html#a2b1f49b99ec17e211c6cc63d4f72f6a4',1,'IRElectraAc::toString()'],['../classIRFujitsuAC.html#ad779b8b86849ab4c6fe3cfc4afe2c7b8',1,'IRFujitsuAC::toString()'],['../classIRGoodweatherAc.html#a8c298ad0ab98789aa4eb419ed134ee03',1,'IRGoodweatherAc::toString()'],['../classIRGreeAC.html#a1f18b275e0e3d10fbc952d1da9613074',1,'IRGreeAC::toString()'],['../classIRHaierAC.html#a7effff64e7c9c20b7d9e6c2c10e0ffbc',1,'IRHaierAC::toString()'],['../classIRHaierACYRW02.html#a3858dd619f4ea4071b248bb5fb64fb08',1,'IRHaierACYRW02::toString()'],['../classIRHitachiAc.html#a9d927f191807b52fbd4f5d411e0c6519',1,'IRHitachiAc::toString()'],['../classIRHitachiAc1.html#ac70d5ed48897559d7e2ff0f843c79ddc',1,'IRHitachiAc1::toString()'],['../classIRHitachiAc424.html#abc1c122c68d62b582a7e38cdaf9febe7',1,'IRHitachiAc424::toString()'],['../classIRHitachiAc344.html#a5286ffe0ad72f82f66ad19bd6c3bdacc',1,'IRHitachiAc344::toString()'],['../classIRKelvinatorAC.html#a2cc438f41b6f4ed2f9df42acc1ffccfe',1,'IRKelvinatorAC::toString()'],['../classIRLgAc.html#a4546e2e0f63aac0bb9bd54f4f93c5f6c',1,'IRLgAc::toString()'],['../classIRMideaAC.html#a4980fbb52145e1d12a6fa5601f75018a',1,'IRMideaAC::toString()'],['../classIRMitsubishiAC.html#a28cfd4bb4d3372fb983f737c7e86b530',1,'IRMitsubishiAC::toString()'],['../classIRMitsubishi136.html#a8e49c540665a724c895674edef31d980',1,'IRMitsubishi136::toString()'],['../classIRMitsubishi112.html#ab99894eb185d13c5bd097c287fdbddeb',1,'IRMitsubishi112::toString()'],['../classIRMitsubishiHeavy152Ac.html#a9082e1498220f7b641f5f265d1131c0a',1,'IRMitsubishiHeavy152Ac::toString()'],['../classIRMitsubishiHeavy88Ac.html#a7c77e68371e70eb5fd565d8ac815950e',1,'IRMitsubishiHeavy88Ac::toString()'],['../classIRNeoclimaAc.html#a9e6a036411583bad6daf1ef2e60e013c',1,'IRNeoclimaAc::toString()'],['../classIRPanasonicAc.html#ada0b3e2bf11123d0a2f5df8692ae73ad',1,'IRPanasonicAc::toString()'],['../classIRSamsungAc.html#a82de7f9c7b4984f002ea3849b4e95ff2',1,'IRSamsungAc::toString()'],['../classIRSharpAc.html#afee9b0acec54d1683404b7af66c73046',1,'IRSharpAc::toString()'],['../classIRTcl112Ac.html#a381c019f805973000ac5ddb6c70e2773',1,'IRTcl112Ac::toString()'],['../classIRTecoAc.html#a7f085b545dac637927ae58fca13e5c5f',1,'IRTecoAc::toString()'],['../classIRToshibaAC.html#a5bbf6a725f496ac40ec2fac8f9a0dc1c',1,'IRToshibaAC::toString()'],['../classIRTrotecESP.html#a06783a7571b684be20ee5485f30ceb3c',1,'IRTrotecESP::toString()'],['../classIRVestelAc.html#a5fd0630ad7c1d5da3b1bfc5aefc443ec',1,'IRVestelAc::toString()'],['../classIRWhirlpoolAc.html#ad599025e8413f23d13a9783ff4c1fe93',1,'IRWhirlpoolAc::toString()']]], + ['trotec_3497',['trotec',['../classIRac.html#aed1a012c0546c2b1d53e86871a42ba1a',1,'IRac::trotec()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7d0f8056d221b37f68f80bace2b794b9',1,'TROTEC(): IRremoteESP8266.h']]], + ['turbo_3498',['turbo',['../structstdAc_1_1state__t.html#aae084b686685f2b2a07ccdda649e358c',1,'stdAc::state_t']]], + ['turboflag_3499',['turboFlag',['../classIRCoolixAC.html#a60a8a848951555dba34f2a317d6611ea',1,'IRCoolixAC']]], + ['typetostring_3500',['typeToString',['../IRutils_8cpp.html#a9e98a1b929f36dfa75c2e325bf281cd1',1,'typeToString(const decode_type_t protocol, const bool isRepeat): IRutils.cpp'],['../IRutils_8h.html#a7f49135f3d160700eb12ff6b7309341c',1,'typeToString(const decode_type_t protocol, const bool isRepeat=false): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.html new file mode 100644 index 000000000..767aec361 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.js new file mode 100644 index 000000000..485738113 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['uint64tostring_3501',['uint64ToString',['../IRutils_8cpp.html#a9f6ddef74b41ef6f8d2805fcfc396420',1,'uint64ToString(uint64_t input, uint8_t base): IRutils.cpp'],['../IRutils_8h.html#a781650451d38303e80da677539f574ee',1,'uint64ToString(uint64_t input, uint8_t base=10): IRutils.cpp']]], + ['uint8tobcd_3502',['uint8ToBcd',['../namespaceirutils.html#a534704a52b75acd46f687cc0a2b91bf1',1,'irutils']]], + ['unknown_3503',['UNKNOWN',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada6ce26a62afab55d7606ad4e92428b30c',1,'IRremoteESP8266.h']]], + ['unused_3504',['UNUSED',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa09b651ef326a9d8efcee5cc5b720ab4',1,'IRremoteESP8266.h']]], + ['updatesavedstate_3505',['updateSavedState',['../classIRCoolixAC.html#a1f39630b328939307bb08c18e56e9ad3',1,'IRCoolixAC']]], + ['use_5ftime_5fstate_3506',['use_time_state',['../classIRVestelAc.html#af1b622c50a4952fb3edaf483e1bf9328',1,'IRVestelAc']]], + ['used_3507',['used',['../structmatch__result__t.html#a26cea305aa83ed65b88ac0b6ed6de54a',1,'match_result_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.html new file mode 100644 index 000000000..7bd7afe63 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.js new file mode 100644 index 000000000..a9e6c124f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['validchecksum_3508',['validChecksum',['../classIRAmcorAc.html#a1ad297a62ac3152c9d957cef38757d28',1,'IRAmcorAc::validChecksum()'],['../classIRArgoAC.html#acfa5a9df8273123e6f4c48684ef60006',1,'IRArgoAC::validChecksum()'],['../classIRCarrierAc64.html#affa23f178e079cd3a6c933240759fe80',1,'IRCarrierAc64::validChecksum()'],['../classIRDaikinESP.html#ad766e60827f80b96a66449bddc621d87',1,'IRDaikinESP::validChecksum()'],['../classIRDaikin2.html#ade5c0dbfe38d9ac0c4bc009c897af04d',1,'IRDaikin2::validChecksum()'],['../classIRDaikin216.html#a663c11977545ba01b34715a61a26ab88',1,'IRDaikin216::validChecksum()'],['../classIRDaikin160.html#a0d9f3af404e3b6c116e8c27e938f8479',1,'IRDaikin160::validChecksum()'],['../classIRDaikin176.html#abc97abc68f535f7ad801b393e0a795d5',1,'IRDaikin176::validChecksum()'],['../classIRDaikin128.html#ad0b16e48bff00c5cdeffa1419c003946',1,'IRDaikin128::validChecksum()'],['../classIRDaikin152.html#ade1c641eecea63857115fc20f1811fe7',1,'IRDaikin152::validChecksum()'],['../classIRDaikin64.html#ab04287881112ff21d1ea541c0f21b507',1,'IRDaikin64::validChecksum()'],['../classIRDelonghiAc.html#ae39b20bcea2b7090ac2e29d8cd28e5f6',1,'IRDelonghiAc::validChecksum()'],['../classIRElectraAc.html#a60034a18e7574844fb59a03e7789f419',1,'IRElectraAc::validChecksum()'],['../classIRFujitsuAC.html#a26153c647d127356e47d35a7456c6235',1,'IRFujitsuAC::validChecksum()'],['../classIRGreeAC.html#a74e7df0634f0a60110db8c033d9d5b1d',1,'IRGreeAC::validChecksum()'],['../classIRHaierAC.html#ad7aae554b8f0a76493efc2a43ac0f780',1,'IRHaierAC::validChecksum()'],['../classIRHaierACYRW02.html#a3f6d071d215b0316cccc2e94c4786954',1,'IRHaierACYRW02::validChecksum()'],['../classIRHitachiAc.html#a2549c1fd2e8a603eb8924fbba8b26e87',1,'IRHitachiAc::validChecksum()'],['../classIRHitachiAc1.html#aa6b7ab76567ee15aa08b1594c67bd29d',1,'IRHitachiAc1::validChecksum()'],['../classIRKelvinatorAC.html#aaa915fa5eb3f7e5c7a3dc143b6fda826',1,'IRKelvinatorAC::validChecksum()'],['../classIRLgAc.html#a51748fa24de24049a2fafb4590e84176',1,'IRLgAc::validChecksum()'],['../classIRMideaAC.html#a971ab4af0267bb732834e7e1f7b8e354',1,'IRMideaAC::validChecksum()'],['../classIRMitsubishiAC.html#ad74885e17434aa9038dc19ad74de4cd0',1,'IRMitsubishiAC::validChecksum()'],['../classIRMitsubishi136.html#a666d1268a93e96b50ac9012c09320de9',1,'IRMitsubishi136::validChecksum()'],['../classIRMitsubishiHeavy152Ac.html#abef94200719da0c14e211315ffc8bede',1,'IRMitsubishiHeavy152Ac::validChecksum()'],['../classIRMitsubishiHeavy88Ac.html#aabd9d8f81108f20f1d7adff3ac6c2fd4',1,'IRMitsubishiHeavy88Ac::validChecksum()'],['../classIRNeoclimaAc.html#a32e4b4444e0a97b6da4447e977f74f94',1,'IRNeoclimaAc::validChecksum()'],['../classIRPanasonicAc.html#a6a084754596f7840dd308041d11a822d',1,'IRPanasonicAc::validChecksum()'],['../classIRSamsungAc.html#a4f7339bce78ce2b656fc597b4c88db22',1,'IRSamsungAc::validChecksum()'],['../classIRSharpAc.html#acb7fb0ac19e09da02d36cb73c808420d',1,'IRSharpAc::validChecksum()'],['../classIRTcl112Ac.html#a204bc37ffadf72ed31b305197c4803f4',1,'IRTcl112Ac::validChecksum()'],['../classIRToshibaAC.html#adc7c1eee14e4de896121ad06e88b61eb',1,'IRToshibaAC::validChecksum()'],['../classIRTrotecESP.html#ae08748e33ed12c536b18f6d0dc4da1c7',1,'IRTrotecESP::validChecksum()'],['../classIRVestelAc.html#ad3bcc08fb4242af7dcc65e534816a219',1,'IRVestelAc::validChecksum()'],['../classIRWhirlpoolAc.html#a2d891069ebdecc62b03e8c92befa15c6',1,'IRWhirlpoolAc::validChecksum()']]], + ['validsection_3509',['validSection',['../classIRCoronaAc.html#af36894d88e7fb45affc883ba0b077862',1,'IRCoronaAc']]], + ['value_3510',['value',['../classdecode__results.html#a033502b7a6b4b0412e5a2062e33c5f47',1,'decode_results']]], + ['vestel_3511',['vestel',['../classIRac.html#a9b1cd1a4d44bc56e62128b9dbc178bba',1,'IRac']]], + ['vestel_5fac_3512',['VESTEL_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada165413c6395bde985757b5b446f76569',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.html new file mode 100644 index 000000000..35702ecdd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.js new file mode 100644 index 000000000..3b357053e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['wand_5fid_3513',['wand_id',['../unionmagiquest.html#a1b159cd47635d548e1d4198cd6d41e93',1,'magiquest']]], + ['whirlpool_3514',['whirlpool',['../classIRac.html#ae5f7a03589f614c03c5ad8629100b05a',1,'IRac']]], + ['whirlpool_5fac_3515',['WHIRLPOOL_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9faf927323d110269541b356f079b85a',1,'IRremoteESP8266.h']]], + ['whirlpool_5fac_5fremote_5fmodel_5ft_3516',['whirlpool_ac_remote_model_t',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2',1,'IRsend.h']]], + ['whynter_3517',['WHYNTER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada458cdd7fa2b29dc8617c694696580c0c',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.html new file mode 100644 index 000000000..540cdb6a5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.js new file mode 100644 index 000000000..072cb0952 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['xorbytes_3518',['xorBytes',['../IRutils_8cpp.html#aaa2a3fb714375e61051a0b24623b9cc9',1,'xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init): IRutils.cpp'],['../IRutils_8h.html#ab030689a93499311ee8e6621ac8757aa',1,'xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.html new file mode 100644 index 000000000..14e13e7d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.js new file mode 100644 index 000000000..8079328d1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['yaw1f_3519',['YAW1F',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9a6b29d752ac8bafc8fedabc1282fccfb6',1,'IRsend.h']]], + ['ybofb_3520',['YBOFB',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9a5d6dadebb4f337aa20ea06a87ae9b34a',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.html new file mode 100644 index 000000000..233281a12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.js new file mode 100644 index 000000000..403d933ff --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['zepeal_3521',['ZEPEAL',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1622e3d0835b4d47add716811c7bf797',1,'IRremoteESP8266.h']]], + ['zh_2dcn_2eh_3522',['zh-CN.h',['../zh-CN_8h.html',1,'']]], + ['zonefollowflag_3523',['zoneFollowFlag',['../classIRCoolixAC.html#a9cb37ed201fcf842c153f0414d9bfd9f',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.html new file mode 100644 index 000000000..470a5bffa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.js new file mode 100644 index 000000000..e3b5013ee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['_7eirrecv_3524',['~IRrecv',['../classIRrecv.html#a87d4cca5e350177cb0922842dda1eb5b',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.html new file mode 100644 index 000000000..b26d91650 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.js new file mode 100644 index 000000000..88a5182d9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['bcdtouint8_67',['bcdToUint8',['../namespaceirutils.html#af18c4abfd0ed9f4b3a099ecec1999ee7',1,'irutils']]], + ['beep_68',['beep',['../structstdAc_1_1state__t.html#a468ce4cf8b68467964b1f1840257663d',1,'stdAc::state_t']]], + ['begin_69',['begin',['../classIRAmcorAc.html#aa723533eea981f79844f241d5bb84654',1,'IRAmcorAc::begin()'],['../classIRArgoAC.html#aca61a63c37797699540c180354809bd8',1,'IRArgoAC::begin()'],['../classIRCarrierAc64.html#a7d9800edffad8a529971535ada5c00ad',1,'IRCarrierAc64::begin()'],['../classIRCoolixAC.html#a506a5ab28865d0243d75ebb7fe62e4ea',1,'IRCoolixAC::begin()'],['../classIRCoronaAc.html#a7db1a8eb9c3c7f76091b2707458e54a9',1,'IRCoronaAc::begin()'],['../classIRDaikinESP.html#accd087c48f246a71898cc6fd7afc2cc7',1,'IRDaikinESP::begin()'],['../classIRDaikin2.html#a6a7b5c28feec523ee81e99a9c32da26e',1,'IRDaikin2::begin()'],['../classIRDaikin216.html#a95be01fb6e672ebd12f2ebca0406ba15',1,'IRDaikin216::begin()'],['../classIRDaikin160.html#a62bb5f66cd99711e388eaa1be9faf617',1,'IRDaikin160::begin()'],['../classIRDaikin176.html#aa742f7d9ae3c9e57cae0e471d7fe59d1',1,'IRDaikin176::begin()'],['../classIRDaikin128.html#af86dba9e085b771c8c3caaebb9f8ee84',1,'IRDaikin128::begin()'],['../classIRDaikin152.html#a2746854350ca7d3a71699439f9843381',1,'IRDaikin152::begin()'],['../classIRDaikin64.html#a291d5f702b4ce763507c731db08b48f2',1,'IRDaikin64::begin()'],['../classIRDelonghiAc.html#a8d5e4f95e929c2365b2be47f42c6328c',1,'IRDelonghiAc::begin()'],['../classIRElectraAc.html#afff519ff9e81ec4aa03ff337f8efef13',1,'IRElectraAc::begin()'],['../classIRFujitsuAC.html#af0dc3fffdafae5970bc367f31029464b',1,'IRFujitsuAC::begin()'],['../classIRGoodweatherAc.html#abace3c8b25d4737a83fe33f94fc741d9',1,'IRGoodweatherAc::begin()'],['../classIRGreeAC.html#a44cf8f0e09248741094af4b35321ab1c',1,'IRGreeAC::begin()'],['../classIRHaierAC.html#ab92fd48ccb5707cb6d14e9d46ce42e17',1,'IRHaierAC::begin()'],['../classIRHaierACYRW02.html#addc01e60e8c4045fab6f22c852eb620f',1,'IRHaierACYRW02::begin()'],['../classIRHitachiAc.html#a62817c840f352bb01a394c37fc95f0f0',1,'IRHitachiAc::begin()'],['../classIRHitachiAc1.html#a28d5d351003d3e0bc1506b06cac8b3d6',1,'IRHitachiAc1::begin()'],['../classIRHitachiAc424.html#a11866bba49e9b976eb22b1039787ecae',1,'IRHitachiAc424::begin()'],['../classIRHitachiAc3.html#a6d79ac7b8ce977e8059019349d6991a7',1,'IRHitachiAc3::begin()'],['../classIRKelvinatorAC.html#a4591bf4e8131aa2a228cbc611156e7f4',1,'IRKelvinatorAC::begin()'],['../classIRLgAc.html#ac08ada1c67ace5ee2ebe4d325aa8c25d',1,'IRLgAc::begin()'],['../classIRMideaAC.html#ac36b6aa76b6b98ab186cd1d5ad9246b4',1,'IRMideaAC::begin()'],['../classIRMitsubishiAC.html#aa6e58080fd811f5b6d0f90c4ef5917df',1,'IRMitsubishiAC::begin()'],['../classIRMitsubishi136.html#abbcd8307862beee2899d2b9900537520',1,'IRMitsubishi136::begin()'],['../classIRMitsubishi112.html#a1d00958556872286b1818d0dbf02e112',1,'IRMitsubishi112::begin()'],['../classIRMitsubishiHeavy152Ac.html#afd649a53d9f7d9b31b7a5732d6cd0857',1,'IRMitsubishiHeavy152Ac::begin()'],['../classIRMitsubishiHeavy88Ac.html#a9bcf18c942ad4df4856bd319215a2002',1,'IRMitsubishiHeavy88Ac::begin()'],['../classIRNeoclimaAc.html#a8f82159b94d86cc4e3d4719441bfa96e',1,'IRNeoclimaAc::begin()'],['../classIRPanasonicAc.html#af48075dc4eb84fcc7f718375d4b0e00a',1,'IRPanasonicAc::begin()'],['../classIRSamsungAc.html#a89f1f902042cd6c6ba9d0f0c6d2cc581',1,'IRSamsungAc::begin()'],['../classIRSharpAc.html#ab87e5b599b7e8fc387fff25b5e13e34f',1,'IRSharpAc::begin()'],['../classIRTcl112Ac.html#a5b9983ab4027951679f0dc31b33cbadf',1,'IRTcl112Ac::begin()'],['../classIRTecoAc.html#a3b23a8556686c83b146101fc31b0dff3',1,'IRTecoAc::begin()'],['../classIRToshibaAC.html#a41e847f399e42c91b0f4aa2ef5d36cba',1,'IRToshibaAC::begin()'],['../classIRTrotecESP.html#a093b874287adb8ef2cc60c832765ff58',1,'IRTrotecESP::begin()'],['../classIRVestelAc.html#a794808d49eb6ce1521ff800b2b15a580',1,'IRVestelAc::begin()'],['../classIRWhirlpoolAc.html#a21db8b31504d416efb2511a33bdc2209',1,'IRWhirlpoolAc::begin()'],['../classIRsend.html#a386f026bf739b0718efde4cffa6ce129',1,'IRsend::begin()']]], + ['bits_70',['bits',['../classdecode__results.html#aa5ba2fd53bdb36bdc120d8eabd9f36d7',1,'decode_results']]], + ['booltostring_71',['boolToString',['../classIRac.html#a9bbd9e6b72e82a752df56e8c489668cf',1,'IRac']]], + ['bufsize_72',['bufsize',['../structirparams__t.html#a2b34d697b85ee6a0ce08344c941e50ec',1,'irparams_t']]], + ['buildfromstate_73',['buildFromState',['../classIRFujitsuAC.html#a6fc8d7d0f649185e0858974394636a8d',1,'IRFujitsuAC']]], + ['buildstate_74',['buildState',['../classIRFujitsuAC.html#ac885c7952253fcee9bf5b4a889b54da9',1,'IRFujitsuAC']]], + ['byte_75',['byte',['../unionmagiquest.html#af1a9c9a147a1610fe5f0e77ca3e09e44',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.html new file mode 100644 index 000000000..b61b96f83 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.js new file mode 100644 index 000000000..527d634a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.js @@ -0,0 +1,45 @@ +var searchData= +[ + ['calcblockchecksum_76',['calcBlockChecksum',['../classIRKelvinatorAC.html#a22f561397c526ed6cc3f69a5d527d8d6',1,'IRKelvinatorAC']]], + ['calcchecksum_77',['calcChecksum',['../classIRAmcorAc.html#aec764cf4d88bb3fcbe3f36d24780f6a9',1,'IRAmcorAc::calcChecksum()'],['../classIRArgoAC.html#acab2fe3b9f77f57f0e99da0bec0d7392',1,'IRArgoAC::calcChecksum()'],['../classIRCarrierAc64.html#a20676dcf4b0a6510cc3bce282fbf8504',1,'IRCarrierAc64::calcChecksum()'],['../classIRDaikin64.html#ac29c18fde1b0cd98991e68c0f672d0e9',1,'IRDaikin64::calcChecksum()'],['../classIRDelonghiAc.html#a14d7629bb888deb02e83886191f44c2d',1,'IRDelonghiAc::calcChecksum()'],['../classIRElectraAc.html#aa8063d07e41ca2cc0fd27093a2e67bb2',1,'IRElectraAc::calcChecksum()'],['../classIRHitachiAc.html#a6e5da77c12ad105439eb159b6a58104a',1,'IRHitachiAc::calcChecksum()'],['../classIRHitachiAc1.html#a6995513d5b59cd7b14cfff39c8843e8d',1,'IRHitachiAc1::calcChecksum()'],['../classIRLgAc.html#a96024e736cf87e65b4e2db7c4c269520',1,'IRLgAc::calcChecksum()'],['../classIRMideaAC.html#ac8733348b311ecf8eed87021cdf4ee31',1,'IRMideaAC::calcChecksum()'],['../classIRNeoclimaAc.html#ac75f316cd1813cdb4e8a6d45d10ddd57',1,'IRNeoclimaAc::calcChecksum()'],['../classIRPanasonicAc.html#a0e38b0f3c54e49cdb59f92279e19840f',1,'IRPanasonicAc::calcChecksum()'],['../classIRSamsungAc.html#a00f9b2a1480d2ed45bdea5d236c77d0f',1,'IRSamsungAc::calcChecksum()'],['../classIRSharpAc.html#af3655c9c394b1391572e8ffab70881ff',1,'IRSharpAc::calcChecksum()'],['../classIRTcl112Ac.html#a0973a1c8a53661ee7720ecb5d08e6dcc',1,'IRTcl112Ac::calcChecksum()'],['../classIRToshibaAC.html#a0d91d32d0d9d722f750eb423d88509f4',1,'IRToshibaAC::calcChecksum()'],['../classIRTrotecESP.html#ac1fdbcbbb8dd1ca50ccf2b55c7281c89',1,'IRTrotecESP::calcChecksum()'],['../classIRVestelAc.html#ac0ba3de4de70350c5325b3d5e0b39e58',1,'IRVestelAc::calcChecksum()']]], + ['calcfirstchecksum_78',['calcFirstChecksum',['../classIRDaikin128.html#a25b25f6b73bb5f1fd17a16080179d4bc',1,'IRDaikin128']]], + ['calcsecondchecksum_79',['calcSecondChecksum',['../classIRDaikin128.html#aea8da64300afe0d62ddf3082a72251f2',1,'IRDaikin128']]], + ['calculatechecksum_80',['calculateChecksum',['../classIRMitsubishiAC.html#aaadefc5880dcd48e3fb2f12b59101f71',1,'IRMitsubishiAC']]], + ['calcusecperiod_81',['calcUSecPeriod',['../classIRsend.html#ae9e68c0ed22e27c8f7ff82cec7ca3e33',1,'IRsend']]], + ['calibrate_82',['calibrate',['../classIRAmcorAc.html#a6206e866e859bc4690cb014c49c1ff80',1,'IRAmcorAc::calibrate()'],['../classIRArgoAC.html#a63cd2f350a7f249c020439543ef3c6d5',1,'IRArgoAC::calibrate()'],['../classIRCarrierAc64.html#a0718376156750e66f98ea0549c75b21b',1,'IRCarrierAc64::calibrate()'],['../classIRCoolixAC.html#a9e39ce5050888210d6ba9b79ae3763e3',1,'IRCoolixAC::calibrate()'],['../classIRCoronaAc.html#a5b10141e4a6e3d8511fb7f9f46d00a96',1,'IRCoronaAc::calibrate()'],['../classIRDaikinESP.html#a638a49f49275a2ab0affb09088794e1b',1,'IRDaikinESP::calibrate()'],['../classIRDaikin2.html#a96c62125bddf113c6524960062d05a57',1,'IRDaikin2::calibrate()'],['../classIRDaikin216.html#a49d7501966528c0a690cfb505f163e26',1,'IRDaikin216::calibrate()'],['../classIRDaikin160.html#a608b5556f316c31e3a8aa73684e4e10d',1,'IRDaikin160::calibrate()'],['../classIRDaikin176.html#a1f5989110782c18aa18e3757c50f4a31',1,'IRDaikin176::calibrate()'],['../classIRDaikin128.html#a281396f4c632899648694e3139c3acd0',1,'IRDaikin128::calibrate()'],['../classIRDaikin152.html#a82fa8bfb3384ed09473345b6e194c3ba',1,'IRDaikin152::calibrate()'],['../classIRDaikin64.html#a12a1e21ba1b06f9b3ffac56691ff2206',1,'IRDaikin64::calibrate()'],['../classIRDelonghiAc.html#aab8f78adcd7fcbea0be753a4fc7696e0',1,'IRDelonghiAc::calibrate()'],['../classIRElectraAc.html#af333e90117ab035ff92389d4eefb3649',1,'IRElectraAc::calibrate()'],['../classIRFujitsuAC.html#a8bb6d8456561dfb04ccac95e0e489558',1,'IRFujitsuAC::calibrate()'],['../classIRGoodweatherAc.html#a8a747144587cf38d64bb32a7f86432b3',1,'IRGoodweatherAc::calibrate()'],['../classIRGreeAC.html#a8069d00a16ed04fd6fa10d84b364bca7',1,'IRGreeAC::calibrate()'],['../classIRHaierAC.html#a448b1d5db05f7722db4758e968ea3171',1,'IRHaierAC::calibrate()'],['../classIRHaierACYRW02.html#a2081b29d0526e339a6b94fc41c854197',1,'IRHaierACYRW02::calibrate()'],['../classIRHitachiAc.html#aaabd743da491ef5d73c4b8c46f11241a',1,'IRHitachiAc::calibrate()'],['../classIRHitachiAc1.html#a847a26df2e19668b147cba2eef595a21',1,'IRHitachiAc1::calibrate()'],['../classIRHitachiAc424.html#aae5e5c13767f335331c5fab8d8ba55d6',1,'IRHitachiAc424::calibrate()'],['../classIRHitachiAc3.html#a02e065c08f9ec4a3d9e6f71432087595',1,'IRHitachiAc3::calibrate()'],['../classIRKelvinatorAC.html#aee8863c1678b09432618bb4ca734db95',1,'IRKelvinatorAC::calibrate()'],['../classIRLgAc.html#a4fd11e935c781319b29f606f2f4b2570',1,'IRLgAc::calibrate()'],['../classIRMideaAC.html#a4077604c2af56783f95a0a64eda7148b',1,'IRMideaAC::calibrate()'],['../classIRMitsubishiAC.html#a973c876e34942776ac98f27de96c5228',1,'IRMitsubishiAC::calibrate()'],['../classIRMitsubishi136.html#a76133542efc3763cb7edc9809ad8d93c',1,'IRMitsubishi136::calibrate()'],['../classIRMitsubishi112.html#ad148250070a3f4ac57ed6cb957ffdefb',1,'IRMitsubishi112::calibrate()'],['../classIRMitsubishiHeavy152Ac.html#a5d4c4ce0e69ed33a2f1db2af127c13c5',1,'IRMitsubishiHeavy152Ac::calibrate()'],['../classIRMitsubishiHeavy88Ac.html#a027423ffbee92ef65b02423f7cbaeca8',1,'IRMitsubishiHeavy88Ac::calibrate()'],['../classIRNeoclimaAc.html#a636dd97ca22c847f966eca8112c8eede',1,'IRNeoclimaAc::calibrate()'],['../classIRPanasonicAc.html#a3f850333f2aa7ce40856c99ef85ffd79',1,'IRPanasonicAc::calibrate()'],['../classIRSamsungAc.html#a5cc7486ae41f61cbe0bb053dd7c9e9e3',1,'IRSamsungAc::calibrate()'],['../classIRSharpAc.html#ac37b1a5679ce90e84f6f95c5df1526bb',1,'IRSharpAc::calibrate()'],['../classIRTcl112Ac.html#a435744e4c6ef31b362d15523ce0584f5',1,'IRTcl112Ac::calibrate()'],['../classIRTecoAc.html#ad700578cbae74857483372597a399ff3',1,'IRTecoAc::calibrate()'],['../classIRToshibaAC.html#a74c66bba288cb3cbb43008edb7b376bf',1,'IRToshibaAC::calibrate()'],['../classIRTrotecESP.html#a56de318a27011e0bddb40738c18dbcf2',1,'IRTrotecESP::calibrate()'],['../classIRVestelAc.html#aae91667d96d86de824a20c256c311f15',1,'IRVestelAc::calibrate()'],['../classIRWhirlpoolAc.html#a006c59c1c84c62fccd3730bec30ef5e8',1,'IRWhirlpoolAc::calibrate()'],['../classIRsend.html#ad1776aa6c699f9eeca1eef9bb4fe355b',1,'IRsend::calibrate()']]], + ['cancelofftimer_83',['cancelOffTimer',['../classIRPanasonicAc.html#a6d202284320c59205cb0d02cb613cada',1,'IRPanasonicAc']]], + ['cancelontimer_84',['cancelOnTimer',['../classIRPanasonicAc.html#a102e7c029a923e121e40326859f2e4a3',1,'IRPanasonicAc']]], + ['canceltimers_85',['cancelTimers',['../classIRHaierAC.html#a1cccc733f74232751f95c32e47795638',1,'IRHaierAC']]], + ['carrier64_86',['carrier64',['../classIRac.html#a8090f2d79a31b81a0342b2e9efb9d555',1,'IRac']]], + ['carrier_5fac_87',['CARRIER_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4d7328071e0a48bc828fccb02f969c20',1,'IRremoteESP8266.h']]], + ['carrier_5fac40_88',['CARRIER_AC40',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1340c578f7986b0ed126744127af3907',1,'IRremoteESP8266.h']]], + ['carrier_5fac64_89',['CARRIER_AC64',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4122973f5d8ce282457d348857ba0af0',1,'IRremoteESP8266.h']]], + ['celsius_90',['celsius',['../structstdAc_1_1state__t.html#a235b17f3979b155b368bfdc2b14123f5',1,'stdAc::state_t']]], + ['celsiustofahrenheit_91',['celsiusToFahrenheit',['../IRutils_8cpp.html#a19b940e26a4f8ddcaf86cce1ec62d563',1,'celsiusToFahrenheit(const float deg): IRutils.cpp'],['../IRutils_8h.html#a19b940e26a4f8ddcaf86cce1ec62d563',1,'celsiusToFahrenheit(const float deg): IRutils.cpp']]], + ['checksum_92',['checksum',['../classIRAmcorAc.html#a67244a75731be6a3bd96ecc0384d0113',1,'IRAmcorAc::checksum()'],['../classIRArgoAC.html#ab0fe4e42d1c1201a92f5c4738b869763',1,'IRArgoAC::checksum()'],['../classIRCarrierAc64.html#a005fab56acf94fe97db7fa92651b2882',1,'IRCarrierAc64::checksum()'],['../classIRCoronaAc.html#ae0257fdafacf7fd2e7ac6ca3f8ae3168',1,'IRCoronaAc::checksum()'],['../classIRDaikinESP.html#ac8ac2a0674dc5cfaf514d319b51b20ab',1,'IRDaikinESP::checksum()'],['../classIRDaikin2.html#abb8e4ad1f8c3ada4211541e5a6e23e64',1,'IRDaikin2::checksum()'],['../classIRDaikin216.html#af2c951901b3b9db9f285a4e9b563ea5e',1,'IRDaikin216::checksum()'],['../classIRDaikin160.html#a34090a598e2b25ee4688c8fbac933638',1,'IRDaikin160::checksum()'],['../classIRDaikin176.html#a4cfe2c4ca95adbf66e149b322d58a843',1,'IRDaikin176::checksum()'],['../classIRDaikin128.html#a747c906808c269581de6cf9b02e5c0a7',1,'IRDaikin128::checksum()'],['../classIRDaikin152.html#a0e208d3e1938abcb320665fffd6ed0e3',1,'IRDaikin152::checksum()'],['../classIRDaikin64.html#a27e2f82b2f13f1e63e981af8f1d3912a',1,'IRDaikin64::checksum()'],['../classIRDelonghiAc.html#ae4c4e7140a763eee159991f5c8afc54f',1,'IRDelonghiAc::checksum()'],['../classIRElectraAc.html#a73dc5b9a038669cc1f00f5b64ad458d1',1,'IRElectraAc::checksum()'],['../classIRGreeAC.html#aaa6b2702d79a7a3db454b99d71064679',1,'IRGreeAC::checksum()'],['../classIRHaierAC.html#ab7faae274ff7f30bf7df3c58d6e7e210',1,'IRHaierAC::checksum()'],['../classIRHaierACYRW02.html#a18045defdd5641ae13c7c75dda0cf23a',1,'IRHaierACYRW02::checksum()'],['../classIRHitachiAc.html#a3b65ccbd6de6b5dcb5a794b471e363f5',1,'IRHitachiAc::checksum()'],['../classIRHitachiAc1.html#aa6687d6282b134d508d6534e8446b341',1,'IRHitachiAc1::checksum()'],['../classIRKelvinatorAC.html#a09acf66b92d3fde6692ec02ff8e62dab',1,'IRKelvinatorAC::checksum()'],['../classIRLgAc.html#a438cbbb77668205c3f2b59b8f28585cd',1,'IRLgAc::checksum()'],['../classIRMideaAC.html#a418b7cbb4b388dba732176d891bb499d',1,'IRMideaAC::checksum()'],['../classIRMitsubishiAC.html#a7c5b1e5c53d99f1564d8a0424f626adb',1,'IRMitsubishiAC::checksum()'],['../classIRMitsubishi136.html#aa2c6fe9b28462052cf6627960126a783',1,'IRMitsubishi136::checksum()'],['../classIRMitsubishi112.html#a65ee232bfc09d05724b8ec5ada538ccf',1,'IRMitsubishi112::checksum()'],['../classIRMitsubishiHeavy152Ac.html#a14cdcaeefef283f707d0fae5108d65f4',1,'IRMitsubishiHeavy152Ac::checksum()'],['../classIRMitsubishiHeavy88Ac.html#acb03ef0da10d3fec14c71bfa087a02b8',1,'IRMitsubishiHeavy88Ac::checksum()'],['../classIRNeoclimaAc.html#acba18ea35a59f6f1ccbcfd75e7979feb',1,'IRNeoclimaAc::checksum()'],['../classIRSamsungAc.html#a75c5886916dd3ef3aa6f96f04934048d',1,'IRSamsungAc::checksum()'],['../classIRSharpAc.html#ad87f46ad9220213d77022dc34920d802',1,'IRSharpAc::checksum()'],['../classIRTcl112Ac.html#a2486f46c7db6a3dfbe3af9c842ff37fa',1,'IRTcl112Ac::checksum()'],['../classIRToshibaAC.html#a5aa2c6fc3b07830f872f98906df7e9ec',1,'IRToshibaAC::checksum()'],['../classIRTrotecESP.html#a5e416e083653ab365f65b3f645f60e8c',1,'IRTrotecESP::checksum()'],['../classIRVestelAc.html#a7a9046e7b5ff57864862bf5f7ad23c4d',1,'IRVestelAc::checksum()'],['../classIRWhirlpoolAc.html#a7790be3df6c4609e5c08c17c5ee52047',1,'IRWhirlpoolAc::checksum()']]], + ['checkzjssig_93',['checkZjsSig',['../classIRMitsubishiHeavy88Ac.html#a6aaf8ae4c9b52d73229b20414099f309',1,'IRMitsubishiHeavy88Ac']]], + ['checkzmssig_94',['checkZmsSig',['../classIRMitsubishiHeavy152Ac.html#a3d1c9d2c98945d21eb1ce82fac1771d2',1,'IRMitsubishiHeavy152Ac']]], + ['clean_95',['clean',['../structstdAc_1_1state__t.html#a703fa57ade60d68deccbb2a59258b32a',1,'stdAc::state_t']]], + ['cleanflag_96',['cleanFlag',['../classIRCoolixAC.html#a9280bc7517713dae451a64e35674804d',1,'IRCoolixAC']]], + ['cleanstate_97',['cleanState',['../classIRac.html#aad988dc123495012758307213a933f37',1,'IRac']]], + ['clearontimerflag_98',['clearOnTimerFlag',['../classIRDaikin2.html#a3587ce954ba94e347d08d73974b50d72',1,'IRDaikin2::clearOnTimerFlag()'],['../classIRDaikin128.html#a8f0bd823535a5bf8b2642eed698b9a71',1,'IRDaikin128::clearOnTimerFlag()']]], + ['clearpowerspecial_99',['clearPowerSpecial',['../classIRSharpAc.html#a3c98c96a66dff560941e461a70efdb1a',1,'IRSharpAc']]], + ['clearsensortemp_100',['clearSensorTemp',['../classIRCoolixAC.html#a5deca09ced33931f089f5cd3c07eac4a',1,'IRCoolixAC']]], + ['clearsleeptimerflag_101',['clearSleepTimerFlag',['../classIRDaikin2.html#a0c165ff91a712e61910ef25e9728e066',1,'IRDaikin2::clearSleepTimerFlag()'],['../classIRDaikin128.html#a5517a481892dd55f4528103037a0d408',1,'IRDaikin128::clearSleepTimerFlag()']]], + ['clock_102',['clock',['../structstdAc_1_1state__t.html#ab1d76172930ebfe992fd9b700369e787',1,'stdAc::state_t']]], + ['cmd_103',['cmd',['../unionmagiquest.html#a71f7646ffd59f0478ae28fad2d724a44',1,'magiquest']]], + ['cmpstates_104',['cmpStates',['../classIRac.html#a3ba4eee08650dfcdd6d492a67c86f016',1,'IRac']]], + ['command_105',['command',['../classdecode__results.html#a9b750d09f713b0693472f815fd0fd402',1,'decode_results']]], + ['compare_106',['compare',['../classIRrecv.html#ad7347c72b14d9f2f20f65bcf235ab3dc',1,'IRrecv']]], + ['convertfan_107',['convertFan',['../classIRAmcorAc.html#ad0f8b7cdf5942c3680639d410f53d18c',1,'IRAmcorAc::convertFan()'],['../classIRArgoAC.html#acd147993fb998a0e7015173b9514d4a2',1,'IRArgoAC::convertFan()'],['../classIRCarrierAc64.html#a255e6679397434877f1c6c9ac70fff50',1,'IRCarrierAc64::convertFan()'],['../classIRCoolixAC.html#a7ffa1cfcf82bd905b0f607401200c895',1,'IRCoolixAC::convertFan()'],['../classIRCoronaAc.html#a6826036fcabbb45e7369f42912fae02f',1,'IRCoronaAc::convertFan()'],['../classIRDaikinESP.html#ab58be19636d41d60b9c62d658ca18cae',1,'IRDaikinESP::convertFan()'],['../classIRDaikin2.html#ad147ea14695c9498bb091862e172dc81',1,'IRDaikin2::convertFan()'],['../classIRDaikin216.html#a520cc65161290f15022b4108f7049a83',1,'IRDaikin216::convertFan()'],['../classIRDaikin160.html#a32658c0f24d0b0c398d54ef648d717a9',1,'IRDaikin160::convertFan()'],['../classIRDaikin176.html#ae3dda9a55f851b5253d0677835a2c3dd',1,'IRDaikin176::convertFan()'],['../classIRDaikin128.html#a983c13bc608fbfa32d7ea2c36dc84116',1,'IRDaikin128::convertFan()'],['../classIRDaikin152.html#a5e2e79252602ca3493baf00cf3fe7787',1,'IRDaikin152::convertFan()'],['../classIRDaikin64.html#a109ff0c33b0a7dfd763683538915c811',1,'IRDaikin64::convertFan()'],['../classIRDelonghiAc.html#aeff2970b20963ae59b99464ae683113f',1,'IRDelonghiAc::convertFan()'],['../classIRElectraAc.html#afcf3ef62d69e370cb88dd2036e5a1357',1,'IRElectraAc::convertFan()'],['../classIRFujitsuAC.html#a111060b7c93e77fdbd1dc96fc8a6c10f',1,'IRFujitsuAC::convertFan()'],['../classIRGoodweatherAc.html#abb443826453a65e87f6dedddf2dd74d5',1,'IRGoodweatherAc::convertFan()'],['../classIRGreeAC.html#a39aa0e4759330aef39382813d3aa96a4',1,'IRGreeAC::convertFan()'],['../classIRHaierAC.html#a58628dd19a7247fc5358c0dc8c30baba',1,'IRHaierAC::convertFan()'],['../classIRHaierACYRW02.html#a66e42d018f3d86b136624a347d333401',1,'IRHaierACYRW02::convertFan()'],['../classIRHitachiAc.html#a5c632c9efc42d9378fdefe608c9bb771',1,'IRHitachiAc::convertFan()'],['../classIRHitachiAc1.html#a96c22fddcd7dfcc5b8f205cc5c7efdef',1,'IRHitachiAc1::convertFan()'],['../classIRHitachiAc424.html#a4f502b779f9fe4aca3a2f649c4cfbda3',1,'IRHitachiAc424::convertFan()'],['../classIRLgAc.html#a71ce8d1be4222ecae26fcea3b71a1ba6',1,'IRLgAc::convertFan()'],['../classIRMideaAC.html#a08a8e49986ce808fd7edd8aee7399a64',1,'IRMideaAC::convertFan()'],['../classIRMitsubishiAC.html#a58ce95e1ae198a9855ee5e81335570cf',1,'IRMitsubishiAC::convertFan()'],['../classIRMitsubishi136.html#a81e691b386950859d1ad0a3c7faf7e49',1,'IRMitsubishi136::convertFan()'],['../classIRMitsubishi112.html#a4194e5b076687b79153bc8cd50c9bc86',1,'IRMitsubishi112::convertFan()'],['../classIRMitsubishiHeavy152Ac.html#ae11040290301b5fe66dfe79e8ea9512b',1,'IRMitsubishiHeavy152Ac::convertFan()'],['../classIRMitsubishiHeavy88Ac.html#acd69c45dbc3f5a150e17b82b5eae7b3f',1,'IRMitsubishiHeavy88Ac::convertFan()'],['../classIRNeoclimaAc.html#a8c3ac622428f118b28d53a3a82740993',1,'IRNeoclimaAc::convertFan()'],['../classIRPanasonicAc.html#aeada51b2d1ff51ff81dfc5c996b416df',1,'IRPanasonicAc::convertFan()'],['../classIRSamsungAc.html#a6be52cc6980ad0bf80261c2a48eb3c87',1,'IRSamsungAc::convertFan()'],['../classIRSharpAc.html#a9b58f12bc44639694a8422a2b9b78a88',1,'IRSharpAc::convertFan()'],['../classIRTcl112Ac.html#a3f8178f8f646ed9892eefa40bbff4fb1',1,'IRTcl112Ac::convertFan()'],['../classIRTecoAc.html#a262aead12607ff962dd97c73e6dea078',1,'IRTecoAc::convertFan()'],['../classIRToshibaAC.html#aeef5cfb840f3058629b486232b7efb22',1,'IRToshibaAC::convertFan()'],['../classIRTrotecESP.html#a905d4d5bd298db8c2e1a9b004fd541e8',1,'IRTrotecESP::convertFan()'],['../classIRVestelAc.html#aa7702b0e50b6c8073cd7740a630b19dd',1,'IRVestelAc::convertFan()'],['../classIRWhirlpoolAc.html#a3004feef0ec5fe327d6a43d68d029377',1,'IRWhirlpoolAc::convertFan()']]], + ['convertmode_108',['convertMode',['../classIRAmcorAc.html#ab57117e1072b5265ac9ab5be6d58bccc',1,'IRAmcorAc::convertMode()'],['../classIRArgoAC.html#ad242e7b18dea9768b9fad6b1e0e12f65',1,'IRArgoAC::convertMode()'],['../classIRCarrierAc64.html#a8e94b1526b26cec55f1e700c86aaf74e',1,'IRCarrierAc64::convertMode()'],['../classIRCoolixAC.html#acfb0d2c20322cb4d3cd681a3a54b30fe',1,'IRCoolixAC::convertMode()'],['../classIRCoronaAc.html#a9f9cf8e38285cb2f3caf79e14516bda1',1,'IRCoronaAc::convertMode()'],['../classIRDaikinESP.html#aa96f52596148cab1f806faf190a0aa0a',1,'IRDaikinESP::convertMode()'],['../classIRDaikin2.html#a10aae6ec9783eac9d89ff98b947767dd',1,'IRDaikin2::convertMode()'],['../classIRDaikin216.html#a4fa9eca71ee6ad66b3fffd8b779f5fb0',1,'IRDaikin216::convertMode()'],['../classIRDaikin160.html#ac69861fdbde341fc75d90a5e4918aa56',1,'IRDaikin160::convertMode()'],['../classIRDaikin176.html#ab07fd6eab0ac6132625a291dae8cfc78',1,'IRDaikin176::convertMode()'],['../classIRDaikin128.html#a0bad4830267887299b2773075a16b283',1,'IRDaikin128::convertMode()'],['../classIRDaikin152.html#a25592419c95c0271d8a0c4203a2919c3',1,'IRDaikin152::convertMode()'],['../classIRDaikin64.html#a595d91c0294c9482aa453f077eebf882',1,'IRDaikin64::convertMode()'],['../classIRDelonghiAc.html#a51a6eab431f81fa448a48c0ec071e706',1,'IRDelonghiAc::convertMode()'],['../classIRElectraAc.html#a0026a1981e713ce1f6916203717e0a00',1,'IRElectraAc::convertMode()'],['../classIRFujitsuAC.html#a242504a5b97c19ff7e369efcadd3916e',1,'IRFujitsuAC::convertMode()'],['../classIRGoodweatherAc.html#aef14e2b6c220e556300d286922da1f54',1,'IRGoodweatherAc::convertMode()'],['../classIRGreeAC.html#a609e87ad4926f150b44426caf79fd38e',1,'IRGreeAC::convertMode()'],['../classIRHaierAC.html#af6188dbed5cae022b4fd1eef358f594c',1,'IRHaierAC::convertMode()'],['../classIRHaierACYRW02.html#a9a51f3d4b4c60ed7d99f9836a57bb3e5',1,'IRHaierACYRW02::convertMode()'],['../classIRHitachiAc.html#af1bdc5e22e5e24218421bd3bbb436301',1,'IRHitachiAc::convertMode()'],['../classIRHitachiAc1.html#a6211c96f463353791e5d922d9939f23c',1,'IRHitachiAc1::convertMode()'],['../classIRHitachiAc424.html#a974bf3ada7117e463b8c23e2158902be',1,'IRHitachiAc424::convertMode()'],['../classIRKelvinatorAC.html#acc9d70a94dd3813005ca0381b80a35e4',1,'IRKelvinatorAC::convertMode()'],['../classIRLgAc.html#a114eca216b7c9c7be33d4527f848311e',1,'IRLgAc::convertMode()'],['../classIRMideaAC.html#a0ca16c8bc2232be467baba8ea69b40d4',1,'IRMideaAC::convertMode()'],['../classIRMitsubishiAC.html#a86d069e406d247bafbefbdd09b22894f',1,'IRMitsubishiAC::convertMode()'],['../classIRMitsubishi136.html#a43b8ff1083d09563a5d3a25b24e480ea',1,'IRMitsubishi136::convertMode()'],['../classIRMitsubishi112.html#aa41d6ec8bc6dc91891aaddbd996f6040',1,'IRMitsubishi112::convertMode()'],['../classIRMitsubishiHeavy152Ac.html#a067ca776edc19a577e8bcda5013e1d0f',1,'IRMitsubishiHeavy152Ac::convertMode()'],['../classIRMitsubishiHeavy88Ac.html#ad0419d176d70935fc535cdcc47ffba02',1,'IRMitsubishiHeavy88Ac::convertMode()'],['../classIRNeoclimaAc.html#a61335773816ecbbeb949e5da78d07e50',1,'IRNeoclimaAc::convertMode()'],['../classIRPanasonicAc.html#a3f3bc3e4b73338351f33f26c635075bb',1,'IRPanasonicAc::convertMode()'],['../classIRSamsungAc.html#a76f7fed436bdfcd9c9a9da8dd99cb9f7',1,'IRSamsungAc::convertMode()'],['../classIRSharpAc.html#a340d60b4b24c10479b3fed4409e0834b',1,'IRSharpAc::convertMode()'],['../classIRTcl112Ac.html#ac063653636319a9451590b08abbfecdc',1,'IRTcl112Ac::convertMode()'],['../classIRTecoAc.html#a5f95c5aacd8fc312acd0f36fd9dc33f2',1,'IRTecoAc::convertMode()'],['../classIRToshibaAC.html#a1cdcb695e128d57c721623cfdc9a8e8d',1,'IRToshibaAC::convertMode()'],['../classIRTrotecESP.html#a114a7022f0382275a55a2775d3d8e894',1,'IRTrotecESP::convertMode()'],['../classIRVestelAc.html#a5bb967d4972374254dad2c0a6fac7ed2',1,'IRVestelAc::convertMode()'],['../classIRWhirlpoolAc.html#afbf2f473c98f480d68c8bb28e1202d56',1,'IRWhirlpoolAc::convertMode()']]], + ['convertswingh_109',['convertSwingH',['../classIRDaikin2.html#a79a989ad0221157c4dd8d992cc2863dc',1,'IRDaikin2::convertSwingH()'],['../classIRDaikin176.html#a2387b8dff2a9c9cd164034977b03f192',1,'IRDaikin176::convertSwingH()'],['../classIRHitachiAc344.html#a34d0fa5b522b51dac46f33cbb0a0a389',1,'IRHitachiAc344::convertSwingH()'],['../classIRMitsubishiAC.html#a8235a527a178486bb58ce62749aaf2fb',1,'IRMitsubishiAC::convertSwingH()'],['../classIRMitsubishi112.html#ab17598ce693475ef167525b8408e2da4',1,'IRMitsubishi112::convertSwingH()'],['../classIRMitsubishiHeavy152Ac.html#a0183cf4fcefb60ac61060dde698efbd1',1,'IRMitsubishiHeavy152Ac::convertSwingH()'],['../classIRMitsubishiHeavy88Ac.html#a8b995256a6651822731da7a912c01f19',1,'IRMitsubishiHeavy88Ac::convertSwingH()'],['../classIRPanasonicAc.html#abb17db3452ae347101dc6eaa8e84433b',1,'IRPanasonicAc::convertSwingH()']]], + ['convertswingv_110',['convertSwingV',['../classIRArgoAC.html#ac23ff32b45c3fc5402e7e303ad9b5d54',1,'IRArgoAC::convertSwingV()'],['../classIRDaikin2.html#aa3de8468b869989ec52a5f9f57ff4a77',1,'IRDaikin2::convertSwingV()'],['../classIRDaikin160.html#a615f599f3bc3e8dec5e5ef92512a2301',1,'IRDaikin160::convertSwingV()'],['../classIRGoodweatherAc.html#a3b37c04fd9b60b63052d93374fc15d4f',1,'IRGoodweatherAc::convertSwingV()'],['../classIRGreeAC.html#ae3717400d1dc0336bcc5fa17c1397a9b',1,'IRGreeAC::convertSwingV()'],['../classIRHaierAC.html#a34053c32ba50ff3b81b208d068efe2a4',1,'IRHaierAC::convertSwingV()'],['../classIRHaierACYRW02.html#a1f7dffe29fbe67989b2f425d629850db',1,'IRHaierACYRW02::convertSwingV()'],['../classIRMitsubishiAC.html#ab561f6421b2f3e0d92d9fab685da639a',1,'IRMitsubishiAC::convertSwingV()'],['../classIRMitsubishi136.html#a59dee0c57d3ca2bdf4c7839142d23059',1,'IRMitsubishi136::convertSwingV()'],['../classIRMitsubishi112.html#a95c545497e0acc6f78ec229a2ada9de0',1,'IRMitsubishi112::convertSwingV()'],['../classIRMitsubishiHeavy152Ac.html#a93f2678fce3b35cfe3e31221d3355291',1,'IRMitsubishiHeavy152Ac::convertSwingV()'],['../classIRMitsubishiHeavy88Ac.html#abeba5346e1fc2223838fbc5d3ed03f23',1,'IRMitsubishiHeavy88Ac::convertSwingV()'],['../classIRPanasonicAc.html#a024e64fe32848e9b0b72e9c04db0fd98',1,'IRPanasonicAc::convertSwingV()']]], + ['cool_5fmode_111',['cool_mode',['../classIRArgoAC.html#a74e7e489d743f213664d9259f1e7a431',1,'IRArgoAC']]], + ['coolix_112',['coolix',['../classIRac.html#a4750db3b06db51f5a23c22538c41b7b3',1,'IRac::coolix()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadae561d1d82d90c1b54a1a502431749873',1,'COOLIX(): IRremoteESP8266.h']]], + ['copyirparams_113',['copyIrParams',['../classIRrecv.html#ab017a0f9256954bb7d943e3c6b7e31bf',1,'IRrecv']]], + ['corona_114',['corona',['../classIRac.html#adcf2bdb1ef6dc057532ae7d188557dac',1,'IRac']]], + ['corona_5fac_115',['CORONA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf61f2c360f487309cfa466a44fcae106',1,'IRremoteESP8266.h']]], + ['countbits_116',['countBits',['../IRutils_8cpp.html#a84621a9f7fb2d57bd425f9f0d662cf7d',1,'countBits(const uint8_t *const start, const uint16_t length, const bool ones, const uint16_t init): IRutils.cpp'],['../IRutils_8cpp.html#aae8042367bb94df81672603270fa7342',1,'countBits(const uint64_t data, const uint8_t length, const bool ones, const uint16_t init): IRutils.cpp'],['../IRutils_8h.html#a27816eac50afafa9e53ba4b53675da20',1,'countBits(const uint8_t *const start, const uint16_t length, const bool ones=true, const uint16_t init=0): IRutils.cpp'],['../IRutils_8h.html#a5a719829db11f5d5560b4367c0d2d365',1,'countBits(const uint64_t data, const uint8_t length, const bool ones=true, const uint16_t init=0): IRutils.cpp']]], + ['crudenoisefilter_117',['crudeNoiseFilter',['../classIRrecv.html#ae833bdb8fccc676043fc4ccae432fab1',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.html new file mode 100644 index 000000000..06de1550e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.js new file mode 100644 index 000000000..450e9d625 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.js @@ -0,0 +1,111 @@ +var searchData= +[ + ['daikin_118',['daikin',['../classIRac.html#afb6d77bbeb5b2465437cef4f58b83e0e',1,'IRac::daikin()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad8dc0597fd237d7098246334f3b5f37e',1,'DAIKIN(): IRremoteESP8266.h']]], + ['daikin128_119',['daikin128',['../classIRac.html#a8fe7c254e1bcb32b6b6fdc1f91693a50',1,'IRac::daikin128()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4b26fb376f6375dd6d1d4be186438f88',1,'DAIKIN128(): IRremoteESP8266.h']]], + ['daikin152_120',['daikin152',['../classIRac.html#a6dff8e608e3e9fecffe71c3fd1ebe74e',1,'IRac::daikin152()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad3f5f7ca39aee5fdab671a1b0d647ae4',1,'DAIKIN152(): IRremoteESP8266.h']]], + ['daikin160_121',['daikin160',['../classIRac.html#a3b34f44d713efa52f30d43405cde831c',1,'IRac::daikin160()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4db6a848df3aed4289801e1b2bbbf6aa',1,'DAIKIN160(): IRremoteESP8266.h']]], + ['daikin176_122',['daikin176',['../classIRac.html#aaae173fd58a7b53c3f4d2edbf7c4afe7',1,'IRac::daikin176()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada57f78a3b04d904f19d10bac13483deab',1,'DAIKIN176(): IRremoteESP8266.h']]], + ['daikin2_123',['daikin2',['../classIRac.html#a89eddc0e1b3c41c608208d2752dc954c',1,'IRac::daikin2()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab37b344f84d575ec78a92ca55e153586',1,'DAIKIN2(): IRremoteESP8266.h']]], + ['daikin216_124',['daikin216',['../classIRac.html#a101ac8b9e9564e557ef1a1f61ff111d9',1,'IRac::daikin216()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa833fa3a20c3cbb7e6206dac4da30ffb',1,'DAIKIN216(): IRremoteESP8266.h']]], + ['daikin64_125',['daikin64',['../classIRac.html#a074db6fc0cff2878d80a397020e1b249',1,'IRac::daikin64()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada70581853ce4883b747d22fdfd74409c4',1,'DAIKIN64(): IRremoteESP8266.h']]], + ['data_126',['data',['../structmatch__result__t.html#ae88be61a6d1ffa7c3525aa958f4c0d25',1,'match_result_t']]], + ['de_2dch_2eh_127',['de-CH.h',['../de-CH_8h.html',1,'']]], + ['de_2dde_2eh_128',['de-DE.h',['../de-DE_8h.html',1,'']]], + ['decode_129',['decode',['../classIRrecv.html#aeaa5c07a8b46f8fbb982f996cc1f9f4b',1,'IRrecv']]], + ['decode_5fresults_130',['decode_results',['../classdecode__results.html',1,'']]], + ['decode_5ftype_131',['decode_type',['../classdecode__results.html#a9c0e9f161b9c90dc10b7561d4c0b50fa',1,'decode_results']]], + ['decode_5ftype_5ft_132',['decode_type_t',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fad',1,'IRremoteESP8266.h']]], + ['decodeairwell_133',['decodeAirwell',['../classIRrecv.html#acf4635d5ee146a82498cb0c269b6af41',1,'IRrecv']]], + ['decodeaiwarct501_134',['decodeAiwaRCT501',['../classIRrecv.html#aa4d678376a4c0f8ea953474a6f5ef9d2',1,'IRrecv']]], + ['decodeamcor_135',['decodeAmcor',['../classIRrecv.html#a8d81fcfb47e36925975d313027689a44',1,'IRrecv']]], + ['decodeargo_136',['decodeArgo',['../classIRrecv.html#a94f12dc000a6e7b75ea8680fd48fc487',1,'IRrecv']]], + ['decodecarrierac_137',['decodeCarrierAC',['../classIRrecv.html#acf3d1c37038120a5c0996d92577ce74a',1,'IRrecv']]], + ['decodecarrierac40_138',['decodeCarrierAC40',['../classIRrecv.html#a4bdb35ec34f49401a6b9becd15b8a3b5',1,'IRrecv']]], + ['decodecarrierac64_139',['decodeCarrierAC64',['../classIRrecv.html#a79d03c31da48a385ab47cc8f342ef9b3',1,'IRrecv']]], + ['decodecoolix_140',['decodeCOOLIX',['../classIRrecv.html#a964af7e72e2133688f0596c718cb98ca',1,'IRrecv']]], + ['decodecoronaac_141',['decodeCoronaAc',['../classIRrecv.html#a981cba14551c93af57f9c1c0e1775d12',1,'IRrecv']]], + ['decodedaikin_142',['decodeDaikin',['../classIRrecv.html#a141f0de9f4cae8daeb025aff3904ecaa',1,'IRrecv']]], + ['decodedaikin128_143',['decodeDaikin128',['../classIRrecv.html#ac7188577c874d9f8f19304a3ec775415',1,'IRrecv']]], + ['decodedaikin152_144',['decodeDaikin152',['../classIRrecv.html#ab20a6586b4e56cc428012ec96f5ccc2c',1,'IRrecv']]], + ['decodedaikin160_145',['decodeDaikin160',['../classIRrecv.html#af0b9822defe6b29099079d664d9dc413',1,'IRrecv']]], + ['decodedaikin176_146',['decodeDaikin176',['../classIRrecv.html#aa142d1340201b6fdc5b462f46fe21ee0',1,'IRrecv']]], + ['decodedaikin2_147',['decodeDaikin2',['../classIRrecv.html#a4c4799a0d45ea5562159c46939617d80',1,'IRrecv']]], + ['decodedaikin216_148',['decodeDaikin216',['../classIRrecv.html#a7f860686a5c58aa8f4d1842cfb15b2f9',1,'IRrecv']]], + ['decodedaikin64_149',['decodeDaikin64',['../classIRrecv.html#a030701f081a9c6eab0c07b75433b524c',1,'IRrecv']]], + ['decodedelonghiac_150',['decodeDelonghiAc',['../classIRrecv.html#a8c91cc83770d243e942387cc16e9ca6f',1,'IRrecv']]], + ['decodedenon_151',['decodeDenon',['../classIRrecv.html#a0b1bd1c817cb43bc3755126191b7f4a2',1,'IRrecv']]], + ['decodedish_152',['decodeDISH',['../classIRrecv.html#a851776d9178aeb706d9a1abd3f254e31',1,'IRrecv']]], + ['decodedoshisha_153',['decodeDoshisha',['../classIRrecv.html#a675c45e6b32aaeca3de734ccf2f0c819',1,'IRrecv']]], + ['decodeelectraac_154',['decodeElectraAC',['../classIRrecv.html#ad3a7be8afc36451c8e28e27f3c3e9aaa',1,'IRrecv']]], + ['decodeepson_155',['decodeEpson',['../classIRrecv.html#aaadef8415f273ba25f4086fecd681d2e',1,'IRrecv']]], + ['decodefujitsuac_156',['decodeFujitsuAC',['../classIRrecv.html#aa3778bdf994bf9c99ac48ef95434a826',1,'IRrecv']]], + ['decodegicable_157',['decodeGICable',['../classIRrecv.html#afade8dac9b1d023e5e0946e6b2c08aea',1,'IRrecv']]], + ['decodegoodweather_158',['decodeGoodweather',['../classIRrecv.html#a64650ce7dbaf5fc860a6a253d906e9de',1,'IRrecv']]], + ['decodegree_159',['decodeGree',['../classIRrecv.html#a2e756342d7524a13d53d6c656700638c',1,'IRrecv']]], + ['decodehaierac_160',['decodeHaierAC',['../classIRrecv.html#ad97403174f05197a7fa9a4a0107e3111',1,'IRrecv']]], + ['decodehaieracyrw02_161',['decodeHaierACYRW02',['../classIRrecv.html#a281fb9d972fee75db49209c42f649822',1,'IRrecv']]], + ['decodehash_162',['decodeHash',['../classIRrecv.html#a7c15fbfa7936ca474712a1953911fd06',1,'IRrecv']]], + ['decodehitachiac_163',['decodeHitachiAC',['../classIRrecv.html#aa42facfffc0e304005272b6ddd4583c8',1,'IRrecv']]], + ['decodehitachiac1_164',['decodeHitachiAC1',['../classIRrecv.html#a122e0dcbf14c90ec2d77399acce21459',1,'IRrecv']]], + ['decodehitachiac3_165',['decodeHitachiAc3',['../classIRrecv.html#a113bc834eff00f55d5545ce3fa1ab203',1,'IRrecv']]], + ['decodehitachiac424_166',['decodeHitachiAc424',['../classIRrecv.html#a01c3dda56d6d916076fa1affa2213129',1,'IRrecv']]], + ['decodeinax_167',['decodeInax',['../classIRrecv.html#a94545c6a8da027b9cb0e23ecba4c29d8',1,'IRrecv']]], + ['decodejvc_168',['decodeJVC',['../classIRrecv.html#a25ab71efc223a418e9630d8421f44bc9',1,'IRrecv']]], + ['decodekelvinator_169',['decodeKelvinator',['../classIRrecv.html#a0ac82f20b48b2d71ee07eb392578b226',1,'IRrecv']]], + ['decodelasertag_170',['decodeLasertag',['../classIRrecv.html#ae4af614a45ea65cb3304ef5bd7965122',1,'IRrecv']]], + ['decodelegopf_171',['decodeLegoPf',['../classIRrecv.html#aea75ad0ba1d8fec33de16501940f2553',1,'IRrecv']]], + ['decodelg_172',['decodeLG',['../classIRrecv.html#afe70015c36b1477a5de0c193163e13a7',1,'IRrecv']]], + ['decodelutron_173',['decodeLutron',['../classIRrecv.html#a6093c4404a9a9d415c5bfeab5ec53be5',1,'IRrecv']]], + ['decodemagiquest_174',['decodeMagiQuest',['../classIRrecv.html#a6f3bfcc6767484151dee758bcf94fb0b',1,'IRrecv']]], + ['decodemidea_175',['decodeMidea',['../classIRrecv.html#a255b15601f7439a09ab5e77ad78816fb',1,'IRrecv']]], + ['decodemidea24_176',['decodeMidea24',['../classIRrecv.html#a62a04019308b29ae2aea4b3a83ba9155',1,'IRrecv']]], + ['decodemitsubishi_177',['decodeMitsubishi',['../classIRrecv.html#a6efe3be80f0ebef3ff94ed0e56c5c52a',1,'IRrecv']]], + ['decodemitsubishi112_178',['decodeMitsubishi112',['../classIRrecv.html#ae0690ff3cb5a5cdcdb6a514bb7bf0cdd',1,'IRrecv']]], + ['decodemitsubishi136_179',['decodeMitsubishi136',['../classIRrecv.html#a87b3ee57dbdf762a0e305ddd43eec629',1,'IRrecv']]], + ['decodemitsubishi2_180',['decodeMitsubishi2',['../classIRrecv.html#a9514197850491a5b8c30ae9ffc89d895',1,'IRrecv']]], + ['decodemitsubishiac_181',['decodeMitsubishiAC',['../classIRrecv.html#a942c5f41df5cbff32a8b7703673cb621',1,'IRrecv']]], + ['decodemitsubishiheavy_182',['decodeMitsubishiHeavy',['../classIRrecv.html#aef9cedf79793806df4cc5376710781bc',1,'IRrecv']]], + ['decodemultibrackets_183',['decodeMultibrackets',['../classIRrecv.html#af61afacc9865232643164ba824e665ab',1,'IRrecv']]], + ['decodemwm_184',['decodeMWM',['../classIRrecv.html#a27518b5d792cdf3ab333b324f409f328',1,'IRrecv']]], + ['decodenec_185',['decodeNEC',['../classIRrecv.html#a52b844f80df7f64edf9ce9cc189ac5b9',1,'IRrecv']]], + ['decodeneoclima_186',['decodeNeoclima',['../classIRrecv.html#a4729ee949e533448b481ae33bbbf1adf',1,'IRrecv']]], + ['decodenikai_187',['decodeNikai',['../classIRrecv.html#abbcbf5fc07d7e37d7724acc37bb5f592',1,'IRrecv']]], + ['decodepanasonic_188',['decodePanasonic',['../classIRrecv.html#aa8dd5f24d28576c6db03cc463bd0a865',1,'IRrecv']]], + ['decodepanasonicac_189',['decodePanasonicAC',['../classIRrecv.html#a0f78e180ed731e8fb16d1c85aa721c95',1,'IRrecv']]], + ['decodepioneer_190',['decodePioneer',['../classIRrecv.html#a78a9487cbe8a562392a07a4090b3091e',1,'IRrecv']]], + ['decoderc5_191',['decodeRC5',['../classIRrecv.html#adab9dffbeceee514520fababd0e721bd',1,'IRrecv']]], + ['decoderc6_192',['decodeRC6',['../classIRrecv.html#a67316499ef37db82e3b3ecaac25c5980',1,'IRrecv']]], + ['decodercmm_193',['decodeRCMM',['../classIRrecv.html#a0e7bf769cb5bebf174e852e4b0b08cf3',1,'IRrecv']]], + ['decodesamsung_194',['decodeSAMSUNG',['../classIRrecv.html#a18b6cf177364faf11b9a076dd2025eec',1,'IRrecv']]], + ['decodesamsung36_195',['decodeSamsung36',['../classIRrecv.html#a290a9e6a0b12ef1fe02a92a456c8ad57',1,'IRrecv']]], + ['decodesamsungac_196',['decodeSamsungAC',['../classIRrecv.html#ae779c76ebd0f3cd1fc13abaa55f80d67',1,'IRrecv']]], + ['decodesanyolc7461_197',['decodeSanyoLC7461',['../classIRrecv.html#a201a5a78f43c2ac216fae4a2ba4d14ec',1,'IRrecv']]], + ['decodesharp_198',['decodeSharp',['../classIRrecv.html#a3390d63ba21a835d7c74c261532a22a7',1,'IRrecv']]], + ['decodesharpac_199',['decodeSharpAc',['../classIRrecv.html#a8a9b920079f783e236f8a938e20b9743',1,'IRrecv']]], + ['decodesony_200',['decodeSony',['../classIRrecv.html#ab03227955cf7d1d00c1620c55d7f9f18',1,'IRrecv']]], + ['decodesymphony_201',['decodeSymphony',['../classIRrecv.html#a61cdf4d891654521afbc6ca9fb415745',1,'IRrecv']]], + ['decodeteco_202',['decodeTeco',['../classIRrecv.html#a950711d7df8dfe4cda86f53650cd9f56',1,'IRrecv']]], + ['decodetoshibaac_203',['decodeToshibaAC',['../classIRrecv.html#a01228e51ede905beac689967bb14b538',1,'IRrecv']]], + ['decodetostate_204',['decodeToState',['../namespaceIRAcUtils.html#ac5eb498bf12cb6cba023c9c1e9726949',1,'IRAcUtils']]], + ['decodetrotec_205',['decodeTrotec',['../classIRrecv.html#ae2920c488173f3fa37f5325438157ced',1,'IRrecv']]], + ['decodevestelac_206',['decodeVestelAc',['../classIRrecv.html#a5d48b3c91434c18c7726cca504d75b73',1,'IRrecv']]], + ['decodewhirlpoolac_207',['decodeWhirlpoolAC',['../classIRrecv.html#a0d1eec83cf092f5621cb34b3e94777c4',1,'IRrecv']]], + ['decodewhynter_208',['decodeWhynter',['../classIRrecv.html#a66289f6a462557ad26e6c0a64f36cf02',1,'IRrecv']]], + ['decodezepeal_209',['decodeZepeal',['../classIRrecv.html#a72afd857c8b2e0192021a40afc96c2d8',1,'IRrecv']]], + ['defaultbits_210',['defaultBits',['../classIRsend.html#a70a2256bee8ad9b8ea8571dd4f26596f',1,'IRsend']]], + ['defaults_2eh_211',['defaults.h',['../defaults_8h.html',1,'']]], + ['degrees_212',['degrees',['../structstdAc_1_1state__t.html#a3d1ff0ff2e0035db4ee8ead5c53b2dbd',1,'stdAc::state_t']]], + ['delonghi_5fac_213',['DELONGHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada149190c9dec98e9c3f4a2bd530b154a3',1,'IRremoteESP8266.h']]], + ['delonghiac_214',['delonghiac',['../classIRac.html#af290b0b08cff5121bb88c62051ed1074',1,'IRac']]], + ['denon_215',['DENON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada2bda37b76abb290d1675c3e027e3c2e1',1,'IRremoteESP8266.h']]], + ['deprecated_20list_216',['Deprecated List',['../deprecated.html',1,'']]], + ['dg11j13a_217',['DG11J13A',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2a868d69f0605cf9151b0163a3481e2fb9',1,'IRsend.h']]], + ['dg11j191_218',['DG11J191',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2adaecfc16f36975f231db2507a8a36c0c',1,'IRsend.h']]], + ['disableirin_219',['disableIRIn',['../classIRrecv.html#a9f4a719e756ad78c7dd47186f8bef087',1,'IRrecv']]], + ['disableofftimer_220',['disableOffTimer',['../classIRDaikinESP.html#a1e4e05ad0799002d0ab25db92dcaac06',1,'IRDaikinESP::disableOffTimer()'],['../classIRDaikin2.html#a6c8ad4c34713d61942c80b6052e6283a',1,'IRDaikin2::disableOffTimer()']]], + ['disableontimer_221',['disableOnTimer',['../classIRDaikinESP.html#a0733e4a15d76baac23493926ef1765b1',1,'IRDaikinESP::disableOnTimer()'],['../classIRDaikin2.html#ab0e77969a86af9637cb9aa4b4befd4aa',1,'IRDaikin2::disableOnTimer()']]], + ['disablesleeptimer_222',['disableSleepTimer',['../classIRDaikin2.html#a5461cf51967d3fe67489384c82daac47',1,'IRDaikin2']]], + ['dish_223',['DISH',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac27c6ac38ba872593af8e46ac2fdc85a',1,'IRremoteESP8266.h']]], + ['doshisha_224',['DOSHISHA',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab4566b260773b60c85450f40fa5b4341',1,'IRremoteESP8266.h']]], + ['doxygen_5findex_2emd_225',['doxygen_index.md',['../doxygen__index_8md.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.html new file mode 100644 index 000000000..2544c4e5b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.js new file mode 100644 index 000000000..c57085813 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.js @@ -0,0 +1,34 @@ +var searchData= +[ + ['econo_226',['econo',['../structstdAc_1_1state__t.html#a580c826c6d9671715adfe8445531b957',1,'stdAc::state_t']]], + ['elapsed_227',['elapsed',['../classIRtimer.html#ad655e585f053580d49d8de7d52cd62a1',1,'IRtimer::elapsed()'],['../classTimerMs.html#ad4aa759c58727393f69863b3461dfc09',1,'TimerMs::elapsed()']]], + ['electra_228',['electra',['../classIRac.html#abb847bd5e09feb293432b8a8cf0dd9de',1,'IRac']]], + ['electra_5fac_229',['ELECTRA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada05f193ef4ead3e54624bd92dc3203fac',1,'IRremoteESP8266.h']]], + ['en_2dau_2eh_230',['en-AU.h',['../en-AU_8h.html',1,'']]], + ['en_2die_2eh_231',['en-IE.h',['../en-IE_8h.html',1,'']]], + ['en_2duk_2eh_232',['en-UK.h',['../en-UK_8h.html',1,'']]], + ['en_2dus_2eh_233',['en-US.h',['../en-US_8h.html',1,'']]], + ['enableirin_234',['enableIRIn',['../classIRrecv.html#a52c05ec6d8f3dbfb75f21f3b4fe7be3d',1,'IRrecv']]], + ['enableirout_235',['enableIROut',['../classIRsend.html#ab3b6d36c9b5d26c400526717d433ed2d',1,'IRsend']]], + ['enableofftimer_236',['enableOffTimer',['../classIRDaikinESP.html#a8a5686066bfc86f1d7cc454e793d3357',1,'IRDaikinESP::enableOffTimer()'],['../classIRDaikin2.html#afc7ba7d7de2976e010a72778091d633a',1,'IRDaikin2::enableOffTimer()'],['../classIRWhirlpoolAc.html#abb1c3685d90d81b44e72050cd0e042f6',1,'IRWhirlpoolAc::enableOffTimer()']]], + ['enableontimer_237',['enableOnTimer',['../classIRDaikinESP.html#aac4d0f5f60c9f4c41d3bb1e0f24bc4bc',1,'IRDaikinESP::enableOnTimer()'],['../classIRDaikin2.html#a91ec5f7c67cb87102a5eb030e0763b50',1,'IRDaikin2::enableOnTimer()'],['../classIRWhirlpoolAc.html#aa3edd58882cf4fc65172e490c9e0bb2e',1,'IRWhirlpoolAc::enableOnTimer()']]], + ['enablesleeptimer_238',['enableSleepTimer',['../classIRDaikin2.html#a9c86782a98a54818ae92419eec5a060b',1,'IRDaikin2']]], + ['enabletimer_239',['enableTimer',['../classIRWhirlpoolAc.html#ad07804318721bc5dd60f7322e02c9696',1,'IRWhirlpoolAc']]], + ['encodedoshisha_240',['encodeDoshisha',['../classIRsend.html#a0522a2256e8358df715065530be6317d',1,'IRsend']]], + ['encodejvc_241',['encodeJVC',['../classIRsend.html#a6303b991c0545443e7ccf63ba89dbf18',1,'IRsend']]], + ['encodelg_242',['encodeLG',['../classIRsend.html#a109b67a68e7a33900cb5c5017ed4578b',1,'IRsend']]], + ['encodemagiquest_243',['encodeMagiQuest',['../classIRsend.html#a4ee40126279dbde8bb02888115577563',1,'IRsend']]], + ['encodenec_244',['encodeNEC',['../classIRsend.html#ab2e1ce918e4e06b955c3d2a089ce189c',1,'IRsend']]], + ['encodepanasonic_245',['encodePanasonic',['../classIRsend.html#a8340497ae75f00c844e53dfc73700d9c',1,'IRsend']]], + ['encodepioneer_246',['encodePioneer',['../classIRsend.html#ae0686829eba31587b71034a1c0495971',1,'IRsend']]], + ['encoderc5_247',['encodeRC5',['../classIRsend.html#a88457fd4cc01d6e8097e04c022ede74a',1,'IRsend']]], + ['encoderc5x_248',['encodeRC5X',['../classIRsend.html#ae760ef1be11f25f7a61237f96a8871d9',1,'IRsend']]], + ['encoderc6_249',['encodeRC6',['../classIRsend.html#ac0e341462426ea146b944502a6d3fde0',1,'IRsend']]], + ['encodesamsung_250',['encodeSAMSUNG',['../classIRsend.html#a4ab0579bd854306b2667de19207e4ffb',1,'IRsend']]], + ['encodesanyolc7461_251',['encodeSanyoLC7461',['../classIRsend.html#a864bef0dc48f6af4b59057362906cf5d',1,'IRsend']]], + ['encodesharp_252',['encodeSharp',['../classIRsend.html#a8f4c7a36380ba31155eba5ff8f5f631e',1,'IRsend']]], + ['encodesony_253',['encodeSony',['../classIRsend.html#aa0aea2cb04f0a7ee9056f15fecfc08c3',1,'IRsend']]], + ['encodetime_254',['encodeTime',['../classIRPanasonicAc.html#a0eee4ad6105d35ee6c34c4666174b04b',1,'IRPanasonicAc']]], + ['epson_255',['EPSON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaaf677fd380c38297264a10732631927c',1,'IRremoteESP8266.h']]], + ['es_2des_2eh_256',['es-ES.h',['../es-ES_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.html new file mode 100644 index 000000000..43f14eab3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.js new file mode 100644 index 000000000..3952b75de --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['fahrenheittocelsius_257',['fahrenheitToCelsius',['../IRutils_8cpp.html#a83538e86145850c24b1c824723089502',1,'fahrenheitToCelsius(const float deg): IRutils.cpp'],['../IRutils_8h.html#a83538e86145850c24b1c824723089502',1,'fahrenheitToCelsius(const float deg): IRutils.cpp']]], + ['fanspeed_258',['fanspeed',['../structstdAc_1_1state__t.html#a28a50c877a0eaa71689ccc3bf9c957d7',1,'stdAc::state_t']]], + ['fanspeed_5ft_259',['fanspeed_t',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383',1,'stdAc']]], + ['fanspeedtostring_260',['fanspeedToString',['../classIRac.html#ab8d8a1ce5de8970c07c90fb41731e2e6',1,'IRac']]], + ['filter_261',['filter',['../structstdAc_1_1state__t.html#a41e4b957f9e011ddb32d35bfcd56c0e7',1,'stdAc::state_t']]], + ['fixchecksum_262',['fixChecksum',['../classIRPanasonicAc.html#aa40bef35000ddf6d14e286b3f2044897',1,'IRPanasonicAc']]], + ['fixup_263',['fixup',['../classIRGreeAC.html#a5bbdcc83f9d49e32379cd27cad0ba130',1,'IRGreeAC::fixup()'],['../classIRKelvinatorAC.html#a389af589003c39794ae5d4bd572fa485',1,'IRKelvinatorAC::fixup()']]], + ['flap_5fmode_264',['flap_mode',['../classIRArgoAC.html#abfc383d92ced7d47945cc5ac996e5fc4',1,'IRArgoAC']]], + ['fr_2dfr_2eh_265',['fr-FR.h',['../fr-FR_8h.html',1,'']]], + ['fujitsu_266',['fujitsu',['../classIRac.html#a23cf80270562ca28ae1f1da2bbb559e7',1,'IRac']]], + ['fujitsu_5fac_267',['FUJITSU_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad8cf99a3a8776d644b78313306a2108c',1,'IRremoteESP8266.h']]], + ['fujitsu_5fac_5fremote_5fmodel_5ft_268',['fujitsu_ac_remote_model_t',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.html new file mode 100644 index 000000000..af52f82a4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.js new file mode 100644 index 000000000..7437f2c8e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.js @@ -0,0 +1,118 @@ +var searchData= +[ + ['ge6711ar2853m_269',['GE6711AR2853M',['../IRsend_8h.html#a50c54713e16502d280723334879dc83bada534bddbb58907faa6c7eae385ec790',1,'IRsend.h']]], + ['get3d_270',['get3D',['../classIRMitsubishiHeavy152Ac.html#ab55c9e587d472baf6a6d9cb61c733b08',1,'IRMitsubishiHeavy152Ac::get3D()'],['../classIRMitsubishiHeavy88Ac.html#ad5171595fef2360f50d7991897c40632',1,'IRMitsubishiHeavy88Ac::get3D()']]], + ['get8cheat_271',['get8CHeat',['../classIRNeoclimaAc.html#aee5b855ce2decb455eaaceb6b4913368',1,'IRNeoclimaAc']]], + ['getbeep_272',['getBeep',['../classIRDaikin2.html#ab6cc9737950ac0ab476bb240897902ec',1,'IRDaikin2::getBeep()'],['../classIRSamsungAc.html#ab13b10f80e8e1169f0b01239f357b3ba',1,'IRSamsungAc::getBeep()']]], + ['getbit_273',['getBit',['../namespaceirutils.html#ac0756774b20e4f7c836abee466800ee6',1,'irutils::getBit(const uint64_t data, const uint8_t position, const uint8_t size)'],['../namespaceirutils.html#a27f90f74ed0b7af37c7bd8cd2a059dee',1,'irutils::getBit(const uint8_t data, const uint8_t position)']]], + ['getboost_274',['getBoost',['../classIRDelonghiAc.html#abf9fd996c60573eca50b5e165cbcbf63',1,'IRDelonghiAc']]], + ['getbreeze_275',['getBreeze',['../classIRSamsungAc.html#ad46fed65fb1375bf3a3940aa2cb311d5',1,'IRSamsungAc']]], + ['getbufsize_276',['getBufSize',['../classIRrecv.html#a69ab02ea6823ccf18d1f6be87ca1b92e',1,'IRrecv']]], + ['getbutton_277',['getButton',['../classIRHaierACYRW02.html#af4df303e5662aa63cba715ff49e09b75',1,'IRHaierACYRW02::getButton()'],['../classIRHitachiAc424.html#a32fa646e61cbaca805f33995344732cc',1,'IRHitachiAc424::getButton()'],['../classIRNeoclimaAc.html#a747fec9ea02220e6cf7465f5f9bb800a',1,'IRNeoclimaAc::getButton()']]], + ['getclean_278',['getClean',['../classIRCoolixAC.html#a272f94ef641041835a650dd4fbdda7bf',1,'IRCoolixAC::getClean()'],['../classIRDaikin2.html#a7930bbca261f07ef1c129cd6a2c848b4',1,'IRDaikin2::getClean()'],['../classIRElectraAc.html#aa06b1246aaa3f25b239b50e395258b7a',1,'IRElectraAc::getClean()'],['../classIRFujitsuAC.html#a4bf872038fc175d1496eae25e9fcdce3',1,'IRFujitsuAC::getClean()'],['../classIRMitsubishiHeavy152Ac.html#a8e7c2759efe24e580d5886600f513648',1,'IRMitsubishiHeavy152Ac::getClean()'],['../classIRMitsubishiHeavy88Ac.html#a54eafb2474559371393c3ec3ba560d3a',1,'IRMitsubishiHeavy88Ac::getClean()'],['../classIRSamsungAc.html#a789edd6c6b0cb291753204d1e9c78fc8',1,'IRSamsungAc::getClean()'],['../classIRSharpAc.html#a599032d1101f15b98ffa9aa3039bc7d6',1,'IRSharpAc::getClean()']]], + ['getclock_279',['getClock',['../classIRDaikin128.html#a6ef4d58f53b35619e8cc44fae6125490',1,'IRDaikin128::getClock()'],['../classIRDaikin64.html#a676ecda2ad53f78ef5cbf470f524918e',1,'IRDaikin64::getClock()'],['../classIRMitsubishiAC.html#a8918c5b8a72d58282b160c8fde9866ad',1,'IRMitsubishiAC::getClock()'],['../classIRPanasonicAc.html#a084479e8f23f7dbb8f155209b36efb3b',1,'IRPanasonicAc::getClock()'],['../classIRWhirlpoolAc.html#a329e06f4c44fa9aef42952f2d123b7a8',1,'IRWhirlpoolAc::getClock()']]], + ['getcmd_280',['getCmd',['../classIRFujitsuAC.html#a758d209fd0e07cb200b2d4a232b6b0a2',1,'IRFujitsuAC']]], + ['getcomfort_281',['getComfort',['../classIRDaikinESP.html#a4377e48a16a6ed1cb4fb2b711e672b16',1,'IRDaikinESP::getComfort()'],['../classIRDaikin152.html#a22cc2073fd7d4a609c335172ff6720cf',1,'IRDaikin152::getComfort()']]], + ['getcommand_282',['getCommand',['../classIRGoodweatherAc.html#aa2a24e8c783cb5b463a95fa05779456e',1,'IRGoodweatherAc::getCommand()'],['../classIRHaierAC.html#a3a291fccea5f4b32f83da2605d2a82e0',1,'IRHaierAC::getCommand()'],['../classIRWhirlpoolAc.html#ab1c34a9498bc2c8da8e4bdcfe4bf011a',1,'IRWhirlpoolAc::getCommand()']]], + ['getcorrectedrawlength_283',['getCorrectedRawLength',['../IRutils_8cpp.html#aad5f25cf6a2dded8b48f4a6dd16857be',1,'getCorrectedRawLength(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#aad5f25cf6a2dded8b48f4a6dd16857be',1,'getCorrectedRawLength(const decode_results *const results): IRutils.cpp']]], + ['getcurrentday_284',['getCurrentDay',['../classIRDaikinESP.html#ad0ecc69b2ab3e7678c8e4e8d64949077',1,'IRDaikinESP']]], + ['getcurrenttime_285',['getCurrentTime',['../classIRDaikinESP.html#a724c204890e6810d150ed54794c9a505',1,'IRDaikinESP::getCurrentTime()'],['../classIRDaikin2.html#a94dc89b80dfdee2afa718314ec522b53',1,'IRDaikin2::getCurrentTime()']]], + ['getcurrtime_286',['getCurrTime',['../classIRHaierAC.html#aa0e05983088035f6d85c520843922c25',1,'IRHaierAC']]], + ['getdisplay_287',['getDisplay',['../classIRSamsungAc.html#a890aa3cab0918fda56daf0bf84ecc5c1',1,'IRSamsungAc']]], + ['getdisplaytempsource_288',['getDisplayTempSource',['../classIRGreeAC.html#adea5a2d2b3a9d699c722e7a93784809e',1,'IRGreeAC']]], + ['getecono_289',['getEcono',['../classIRCoronaAc.html#a0b8413e2a7aeecc5c0c55049c1705c38',1,'IRCoronaAc::getEcono()'],['../classIRDaikinESP.html#a84337719e737ea4dc1e1fb10f6f7df92',1,'IRDaikinESP::getEcono()'],['../classIRDaikin2.html#ad8098fa67e8808eebfad7611b6fc7881',1,'IRDaikin2::getEcono()'],['../classIRDaikin128.html#a0c05f4c6f996d56d56075e20a46f2c2c',1,'IRDaikin128::getEcono()'],['../classIRDaikin152.html#a9946c73f0c5906fbb2f39119e00531e5',1,'IRDaikin152::getEcono()'],['../classIRMitsubishiHeavy152Ac.html#aa7814232c84ff918f1d05ec105abf851',1,'IRMitsubishiHeavy152Ac::getEcono()'],['../classIRMitsubishiHeavy88Ac.html#af3accae413215cdd45a180f22bbe443e',1,'IRMitsubishiHeavy88Ac::getEcono()'],['../classIRTcl112Ac.html#afabe458a354d822f3ff929a461b6e046',1,'IRTcl112Ac::getEcono()']]], + ['geteconotoggle_290',['getEconoToggle',['../classIRSharpAc.html#a701542019d3a823ba203f0db3cfce353',1,'IRSharpAc']]], + ['geteye_291',['getEye',['../classIRDaikin2.html#a02fbd472d3c79b2391fc11da692c8998',1,'IRDaikin2::getEye()'],['../classIRNeoclimaAc.html#a15b91e2c854537d94cbabd7cd9bd30e4',1,'IRNeoclimaAc::getEye()']]], + ['geteyeauto_292',['getEyeAuto',['../classIRDaikin2.html#a0cae45648292bdee8092a30338975ed0',1,'IRDaikin2']]], + ['getfan_293',['getFan',['../classIRAmcorAc.html#a8ba84d83fc426ee5b75e0be27fd22d9c',1,'IRAmcorAc::getFan()'],['../classIRArgoAC.html#a413e60e09f1abcf231a173e1374e51e0',1,'IRArgoAC::getFan()'],['../classIRCarrierAc64.html#a93bb27688657af434d57f0dd9a159566',1,'IRCarrierAc64::getFan()'],['../classIRCoolixAC.html#a937c0084f79eaef2a160331993dfb881',1,'IRCoolixAC::getFan()'],['../classIRCoronaAc.html#aa51ccd3684009d5a56bbde73eab7ccfa',1,'IRCoronaAc::getFan()'],['../classIRDaikinESP.html#addad5838bb00885df8af258a61fa4131',1,'IRDaikinESP::getFan()'],['../classIRDaikin2.html#aafe89842b356c288dd38d256f9eb050c',1,'IRDaikin2::getFan()'],['../classIRDaikin216.html#a0905e04fc3d21249b057aa79721c1614',1,'IRDaikin216::getFan()'],['../classIRDaikin160.html#a2eb3987f87d19e1ab01dac111ae2d16b',1,'IRDaikin160::getFan()'],['../classIRDaikin176.html#a59c3d23a5e1b7c69c05690cf7984dab8',1,'IRDaikin176::getFan()'],['../classIRDaikin128.html#a68a7bdb134ea62913f51844f976beab1',1,'IRDaikin128::getFan()'],['../classIRDaikin152.html#a64eacdc63547026477b5f861e7da62ea',1,'IRDaikin152::getFan()'],['../classIRDaikin64.html#abdd4bc3d5464b5297b4f2fd0e7a831e1',1,'IRDaikin64::getFan()'],['../classIRDelonghiAc.html#afd2ed0ec70e3912335a9174bca7e7f5e',1,'IRDelonghiAc::getFan()'],['../classIRElectraAc.html#a6e8b30452671c26777ba2bc556bc8dce',1,'IRElectraAc::getFan()'],['../classIRGoodweatherAc.html#ac1ac922370ad09a80dd4e7158b279b9f',1,'IRGoodweatherAc::getFan()'],['../classIRGreeAC.html#a0bf5a552490c7500f0584affacac13d0',1,'IRGreeAC::getFan()'],['../classIRHaierAC.html#a5b15678e94acc14a0bb86bff61230e93',1,'IRHaierAC::getFan()'],['../classIRHaierACYRW02.html#a6de2fb6111049720913eb28bf6f64a00',1,'IRHaierACYRW02::getFan()'],['../classIRHitachiAc.html#a6a5f5b9544e93e842f76a2f4994c1665',1,'IRHitachiAc::getFan()'],['../classIRHitachiAc1.html#af1c6acc2ff9946af7091695b616c2cac',1,'IRHitachiAc1::getFan()'],['../classIRHitachiAc424.html#ab3ecfb8b6fb503ba3eed023609f2fe7b',1,'IRHitachiAc424::getFan()'],['../classIRKelvinatorAC.html#a64ce2ccf879217410269230218e0c76b',1,'IRKelvinatorAC::getFan()'],['../classIRLgAc.html#a10d666ca13c99696a53dca7f5773d7de',1,'IRLgAc::getFan()'],['../classIRMideaAC.html#ab793e409c666e001242623a2607786e7',1,'IRMideaAC::getFan()'],['../classIRMitsubishiAC.html#a06cb4179b92af1b1d3c167659c30db95',1,'IRMitsubishiAC::getFan()'],['../classIRMitsubishi136.html#a61b0a21a32eb1211cab201587de6f7ce',1,'IRMitsubishi136::getFan()'],['../classIRMitsubishi112.html#a00446fe1fdf27012acd41303b711e575',1,'IRMitsubishi112::getFan()'],['../classIRMitsubishiHeavy152Ac.html#a957abe79b7966da644db091ffe75d73b',1,'IRMitsubishiHeavy152Ac::getFan()'],['../classIRMitsubishiHeavy88Ac.html#ac00255061012eef8d62f44e478839d7e',1,'IRMitsubishiHeavy88Ac::getFan()'],['../classIRNeoclimaAc.html#a8690eda2de7b00029f70304131388890',1,'IRNeoclimaAc::getFan()'],['../classIRPanasonicAc.html#a302ba64400c820a5a0d822315516564a',1,'IRPanasonicAc::getFan()'],['../classIRSamsungAc.html#a6461c72b2598d1bdc14263552b5b0c98',1,'IRSamsungAc::getFan()'],['../classIRSharpAc.html#abae439959603f62b0fe5aea8ec93afb5',1,'IRSharpAc::getFan()'],['../classIRTcl112Ac.html#af59bcc28ac97869595a5ad928300908b',1,'IRTcl112Ac::getFan()'],['../classIRTecoAc.html#a420b209010276b30c9bc322b7393b3be',1,'IRTecoAc::getFan()'],['../classIRToshibaAC.html#afd2000b62b79afde107ebc8a513724ab',1,'IRToshibaAC::getFan()'],['../classIRVestelAc.html#a492abc867ad5b766715eaa301c71f3c8',1,'IRVestelAc::getFan()'],['../classIRWhirlpoolAc.html#a80fedb2ddec4a3dbb2c96b5a76a26e1a',1,'IRWhirlpoolAc::getFan()']]], + ['getfanspeed_294',['getFanSpeed',['../classIRFujitsuAC.html#aacb180bb884b80c1f8bbbed7e2dd23d5',1,'IRFujitsuAC']]], + ['getfilter_295',['getFilter',['../classIRFujitsuAC.html#a430ed6a4b946d1b4527741b42e12a25c',1,'IRFujitsuAC::getFilter()'],['../classIRMitsubishiHeavy152Ac.html#aaf2864f7187acd1b75d9daad2d504c13',1,'IRMitsubishiHeavy152Ac::getFilter()']]], + ['getflap_296',['getFlap',['../classIRArgoAC.html#a2285908626731c2feaa85635f3ce1ff1',1,'IRArgoAC']]], + ['getfollow_297',['getFollow',['../classIRNeoclimaAc.html#af4ed34fe7b151bcc5ff6922a54427da0',1,'IRNeoclimaAc']]], + ['getfresh_298',['getFresh',['../classIRNeoclimaAc.html#a2c411cf55667339ff8e3664a6d0ee843',1,'IRNeoclimaAc']]], + ['getfreshair_299',['getFreshAir',['../classIRDaikin2.html#aad50061042e14f665e5ecbd85ac48741',1,'IRDaikin2']]], + ['getfreshairhigh_300',['getFreshAirHigh',['../classIRDaikin2.html#a72c8d47c2e6664eb0e40efe6933e4ac1',1,'IRDaikin2']]], + ['gethealth_301',['getHealth',['../classIRHaierAC.html#a5c69955fe18f4ddb0286084f3fb39228',1,'IRHaierAC::getHealth()'],['../classIRHaierACYRW02.html#a97fc67cddf50a51b0db6c4e22fcaafa1',1,'IRHaierACYRW02::getHealth()'],['../classIRTcl112Ac.html#adf484b6a4097dd8834c202c81fea0ad4',1,'IRTcl112Ac::getHealth()']]], + ['gethold_302',['getHold',['../classIRNeoclimaAc.html#a63045d768858265ed1bbc4c337de79eb',1,'IRNeoclimaAc']]], + ['gethumid_303',['getHumid',['../classIRTecoAc.html#a30012508c6ba93ad07185a13795c5909',1,'IRTecoAc']]], + ['getifeel_304',['getiFeel',['../classIRArgoAC.html#abc802d8ab9dbd9f918bc2aa36d2ea414',1,'IRArgoAC::getiFeel()'],['../classIRGreeAC.html#ae1f8352fc32fa773bb33243cc32657a2',1,'IRGreeAC::getIFeel()']]], + ['getion_305',['getIon',['../classIRNeoclimaAc.html#a908a65189ba6eb8141d50da000feec0a',1,'IRNeoclimaAc::getIon()'],['../classIRPanasonicAc.html#a6d6909b7b96815c227f0009dcbd3ce8c',1,'IRPanasonicAc::getIon()'],['../classIRSamsungAc.html#aab1ebb523ca45431a0127b82cb4ce36f',1,'IRSamsungAc::getIon()'],['../classIRSharpAc.html#a1de89912129d0a1fffbd51625a1eeab7',1,'IRSharpAc::getIon()'],['../classIRVestelAc.html#a835f194f14479c25a3d651f324e6436c',1,'IRVestelAc::getIon()']]], + ['getionfilter_306',['getIonFilter',['../classIRKelvinatorAC.html#a81127edca40e504c432b2079030f84a5',1,'IRKelvinatorAC']]], + ['getled_307',['getLed',['../classIRCoolixAC.html#aa7712ebbf103c4d61dc645cb42dcf3f0',1,'IRCoolixAC']]], + ['getlight_308',['getLight',['../classIRDaikin2.html#ada92da390d8b4247a014057c3d6fa296',1,'IRDaikin2::getLight()'],['../classIRGoodweatherAc.html#a90454990d7f9cde54ab5a11170d5e97d',1,'IRGoodweatherAc::getLight()'],['../classIRGreeAC.html#ae63281a9caf850429857cc3fa99ccf05',1,'IRGreeAC::getLight()'],['../classIRKelvinatorAC.html#a85e77c7a1b763373b0732d125923f53f',1,'IRKelvinatorAC::getLight()'],['../classIRNeoclimaAc.html#ad87fc87e34c3de56c4bbe35443e92226',1,'IRNeoclimaAc::getLight()'],['../classIRTcl112Ac.html#ae711a585331ffab24f96b0bb0f3960ed',1,'IRTcl112Ac::getLight()'],['../classIRTecoAc.html#a12a2bb7a5d3c90139dba85d54a535b8f',1,'IRTecoAc::getLight()'],['../classIRWhirlpoolAc.html#a87f2274da6101e1c2e78eb4e68aadff0',1,'IRWhirlpoolAc::getLight()']]], + ['getlighttoggle_309',['getLightToggle',['../classIRDaikin128.html#a3e279e67bbafc0dc74dbd847e2e8ad75',1,'IRDaikin128::getLightToggle()'],['../classIRElectraAc.html#a63bc44235b18e11531479dc2f633f94b',1,'IRElectraAc::getLightToggle()']]], + ['getmax_310',['getMax',['../classIRAmcorAc.html#a61659b6b54d652713efdf408a09db087',1,'IRAmcorAc::getMax()'],['../classIRArgoAC.html#aff24da9d975bf1f6df0a83be2ad7a913',1,'IRArgoAC::getMax()']]], + ['getmode_311',['getMode',['../classIRAmcorAc.html#a30fd2a228e63e6b9a1544c3c1ec910f7',1,'IRAmcorAc::getMode()'],['../classIRArgoAC.html#a532a313f22c716b60cee070d9ba0839d',1,'IRArgoAC::getMode()'],['../classIRCarrierAc64.html#a4f8e0435a086ec934b10e9bd66f2ae85',1,'IRCarrierAc64::getMode()'],['../classIRCoolixAC.html#a16772a297404e2c54f951c49bfc608de',1,'IRCoolixAC::getMode()'],['../classIRCoronaAc.html#aa6ccd147a1da55d5e9596159008d40de',1,'IRCoronaAc::getMode()'],['../classIRDaikinESP.html#a164452703a7a6d46766acc85aab63898',1,'IRDaikinESP::getMode()'],['../classIRDaikin2.html#a681279a765159550ac1ec84895fff4d2',1,'IRDaikin2::getMode()'],['../classIRDaikin216.html#a21b3e93f98ac55e743efe38c20617d6a',1,'IRDaikin216::getMode()'],['../classIRDaikin160.html#a2b890fe446db67acd828fefd4afef84f',1,'IRDaikin160::getMode()'],['../classIRDaikin176.html#a1fc59660d77eb9dc3a8361d7d4698cd9',1,'IRDaikin176::getMode()'],['../classIRDaikin128.html#aa3d96e14663c498a6e0938ba04a02f87',1,'IRDaikin128::getMode()'],['../classIRDaikin152.html#af4c6c468f3075ffa83694a0da15a707b',1,'IRDaikin152::getMode()'],['../classIRDaikin64.html#a96624667a4494087074792562090b552',1,'IRDaikin64::getMode()'],['../classIRDelonghiAc.html#a89d9fa5b2c4a59b46cac111418232090',1,'IRDelonghiAc::getMode()'],['../classIRElectraAc.html#a473a794960bc07837e407830a3ea528b',1,'IRElectraAc::getMode()'],['../classIRFujitsuAC.html#a5f9630d81acffc74434ce852b9523d17',1,'IRFujitsuAC::getMode()'],['../classIRGoodweatherAc.html#a622e11c7b236fa127008f990819eca75',1,'IRGoodweatherAc::getMode()'],['../classIRGreeAC.html#abb5c4a29000c8b22b25e150e7ef5a6c3',1,'IRGreeAC::getMode()'],['../classIRHaierAC.html#aa180c60030d9972807238cceba886ff5',1,'IRHaierAC::getMode()'],['../classIRHaierACYRW02.html#aec7359fb8c796fc45577a40370f874c9',1,'IRHaierACYRW02::getMode()'],['../classIRHitachiAc.html#a414a4083e15deb1890a1eab4827d78ac',1,'IRHitachiAc::getMode()'],['../classIRHitachiAc1.html#afc4fdc94989297b73e08e9c82bd00733',1,'IRHitachiAc1::getMode()'],['../classIRHitachiAc424.html#ac1bf6df8277d50dcad8e389b21971e24',1,'IRHitachiAc424::getMode()'],['../classIRHitachiAc3.html#a511c9b731a0367fd05b32b42a69adec2',1,'IRHitachiAc3::getMode()'],['../classIRKelvinatorAC.html#a7a0f8f587fdda24db12db7aace478fd6',1,'IRKelvinatorAC::getMode()'],['../classIRLgAc.html#a19752b31eb74aad0cc9538a2f0af8b8c',1,'IRLgAc::getMode()'],['../classIRMideaAC.html#a1b5d19958e11a85d1af09b15631af124',1,'IRMideaAC::getMode()'],['../classIRMitsubishiAC.html#a069fd1d3bea102968e74b312fdf01548',1,'IRMitsubishiAC::getMode()'],['../classIRMitsubishi136.html#a3176aec8444f500bdea6e650cee2dbcc',1,'IRMitsubishi136::getMode()'],['../classIRMitsubishi112.html#ac2006f1e33f2a0cebcb6c23fcac389bb',1,'IRMitsubishi112::getMode()'],['../classIRMitsubishiHeavy152Ac.html#af0a51f8195492aac62bea483cb9a392c',1,'IRMitsubishiHeavy152Ac::getMode()'],['../classIRMitsubishiHeavy88Ac.html#ae8e1263a77b8fb04c2a4a5d6ce9805f9',1,'IRMitsubishiHeavy88Ac::getMode()'],['../classIRNeoclimaAc.html#ad2a43e0405a44787bb177bf13a324dde',1,'IRNeoclimaAc::getMode()'],['../classIRPanasonicAc.html#a5ffd59dd87b047e172ba74866267a9f3',1,'IRPanasonicAc::getMode()'],['../classIRSamsungAc.html#a740a874ee2c492027623943043a1ebf6',1,'IRSamsungAc::getMode()'],['../classIRSharpAc.html#adbccabd2ec614c8b921a02af8b529b4e',1,'IRSharpAc::getMode()'],['../classIRTcl112Ac.html#ad1b6538977bc464f1e6719b5cea89945',1,'IRTcl112Ac::getMode()'],['../classIRTecoAc.html#a4200081a4d42f2ec06935f71c4870e67',1,'IRTecoAc::getMode()'],['../classIRToshibaAC.html#aba5db1f6c8665443f26875ee9716302f',1,'IRToshibaAC::getMode()'],['../classIRTrotecESP.html#ab1b08911e9b76a06a08f4c7b8a2244c0',1,'IRTrotecESP::getMode()'],['../classIRVestelAc.html#ae5b3d9f1420f4d1951ba148399ccbd41',1,'IRVestelAc::getMode()'],['../classIRWhirlpoolAc.html#a4d2896e42e9c5ee1e8dc8f7e917618dc',1,'IRWhirlpoolAc::getMode()']]], + ['getmodel_312',['getModel',['../classIRFujitsuAC.html#a35c6bfb730014f3a24676f94e8308163',1,'IRFujitsuAC::getModel()'],['../classIRGreeAC.html#a3780fc11488a2b40f3c1a50bb94783c7',1,'IRGreeAC::getModel()'],['../classIRHitachiAc1.html#a9ad677e1a2d7acba032701051538b08a',1,'IRHitachiAc1::getModel()'],['../classIRLgAc.html#aa49cde438a42a5415e127cc95da465ac',1,'IRLgAc::getModel()'],['../classIRPanasonicAc.html#a625be846baf3ec556a59379785e642e8',1,'IRPanasonicAc::getModel()'],['../classIRWhirlpoolAc.html#ac55e17fde1ef2acf6524d936732a0469',1,'IRWhirlpoolAc::getModel()']]], + ['getmold_313',['getMold',['../classIRDaikinESP.html#ad593ac32c01752f56e9476af234cf813',1,'IRDaikinESP::getMold()'],['../classIRDaikin2.html#a330b3a8f25bd2d053dab318126b32569',1,'IRDaikin2::getMold()']]], + ['getnight_314',['getNight',['../classIRArgoAC.html#adca87781240cf9c22e6bbaad9d59537c',1,'IRArgoAC::getNight()'],['../classIRMitsubishiHeavy152Ac.html#a659036b987991f39daa13fbd23b35f35',1,'IRMitsubishiHeavy152Ac::getNight()']]], + ['getnormalstate_315',['getNormalState',['../classIRCoolixAC.html#a458618f926f8b57e4b9bdeae0d13a70d',1,'IRCoolixAC']]], + ['getofftime_316',['getOffTime',['../classIRDaikinESP.html#a5213017d706cd6bce88cbfb65150bdb5',1,'IRDaikinESP::getOffTime()'],['../classIRDaikin2.html#af3a47c7b99cec3b108b5173cf1ae7da4',1,'IRDaikin2::getOffTime()'],['../classIRDaikin64.html#a7f163901c3b5065e393e3ae0e01d599a',1,'IRDaikin64::getOffTime()']]], + ['getofftimeenabled_317',['getOffTimeEnabled',['../classIRDaikin64.html#a9ebf2deb196caece88c286d8c03bb69a',1,'IRDaikin64']]], + ['getofftimer_318',['getOffTimer',['../classIRCarrierAc64.html#a6a28f83442d695385f76f13913c76542',1,'IRCarrierAc64::getOffTimer()'],['../classIRCoronaAc.html#a4602f36769e6b135fec8802a3b087adf',1,'IRCoronaAc::getOffTimer()'],['../classIRDaikin128.html#a6a18b029d75b006de5aeac2efb8e08e2',1,'IRDaikin128::getOffTimer()'],['../classIRDelonghiAc.html#acd32fa9acbc9782df9aa00325efea2a7',1,'IRDelonghiAc::getOffTimer()'],['../classIRHaierAC.html#a8b5c970b3204aa447d86dc2941dbd7b1',1,'IRHaierAC::getOffTimer()'],['../classIRHitachiAc1.html#ab99d73871d3510a830f988628dc5e33d',1,'IRHitachiAc1::getOffTimer()'],['../classIRPanasonicAc.html#a4bce377d32504f666662f1d93645761f',1,'IRPanasonicAc::getOffTimer()'],['../classIRVestelAc.html#a575ba7c6aee1d2377975ef0ef938775a',1,'IRVestelAc::getOffTimer()'],['../classIRWhirlpoolAc.html#a05e1308970e0169d6a081baf120efd9f',1,'IRWhirlpoolAc::getOffTimer()']]], + ['getofftimerenabled_319',['getOffTimerEnabled',['../classIRDaikinESP.html#af6388cd6d2189f9067b708d46917a83a',1,'IRDaikinESP::getOffTimerEnabled()'],['../classIRDaikin2.html#a7a413002b64497a5fce7cdcdd6924e8f',1,'IRDaikin2::getOffTimerEnabled()'],['../classIRDaikin128.html#a4234e0e3ff261afa9d5ec6a8b92d8f53',1,'IRDaikin128::getOffTimerEnabled()'],['../classIRDelonghiAc.html#ac1b91f6d4bb5e41e43fc7e4b9a3187a3',1,'IRDelonghiAc::getOffTimerEnabled()']]], + ['getontime_320',['getOnTime',['../classIRDaikinESP.html#a8a6730accc69647cbc12ebc99b2cfb77',1,'IRDaikinESP::getOnTime()'],['../classIRDaikin2.html#ad62f28698595be7717f0f29a5396853d',1,'IRDaikin2::getOnTime()'],['../classIRDaikin64.html#a9b316390ffc3e81d423d3e4b326be7d4',1,'IRDaikin64::getOnTime()']]], + ['getontimeenabled_321',['getOnTimeEnabled',['../classIRDaikin64.html#a0b9795a5536566fe2f9b713aaff4b9ee',1,'IRDaikin64']]], + ['getontimer_322',['getOnTimer',['../classIRCarrierAc64.html#a071ebd204e56e2cd771281b1c42b9cb5',1,'IRCarrierAc64::getOnTimer()'],['../classIRCoronaAc.html#a7beec38ab35dbebe955c4da188de25d5',1,'IRCoronaAc::getOnTimer()'],['../classIRDaikin128.html#a3b8a36d99a7cbf87bac8480f16c3d583',1,'IRDaikin128::getOnTimer()'],['../classIRDelonghiAc.html#a03f6d037d62d3c641b45ec97a1bff715',1,'IRDelonghiAc::getOnTimer()'],['../classIRHaierAC.html#a99d3339eb5ecdbf1c86e85408507af7b',1,'IRHaierAC::getOnTimer()'],['../classIRHitachiAc1.html#a9d5846c1efcc8fae1eeb6079a61cb18b',1,'IRHitachiAc1::getOnTimer()'],['../classIRPanasonicAc.html#a51d50a59e09f0911022c59ab60bf4889',1,'IRPanasonicAc::getOnTimer()'],['../classIRVestelAc.html#aa39e3047ea694ada9cc7e992e7b03e32',1,'IRVestelAc::getOnTimer()'],['../classIRWhirlpoolAc.html#a26c00db3316585e32d64428d6732fcd0',1,'IRWhirlpoolAc::getOnTimer()']]], + ['getontimerenabled_323',['getOnTimerEnabled',['../classIRDaikinESP.html#a45e473403547c8ec95a50aeb1ed93607',1,'IRDaikinESP::getOnTimerEnabled()'],['../classIRDaikin2.html#a8921edb7885d728ee5294fa03cb13a87',1,'IRDaikin2::getOnTimerEnabled()'],['../classIRDaikin128.html#a450948bdbdc22da751c8f1abc2da642d',1,'IRDaikin128::getOnTimerEnabled()'],['../classIRDelonghiAc.html#a0911f40ee5838bfc6b7deb3193e6a62a',1,'IRDelonghiAc::getOnTimerEnabled()']]], + ['getoutsidequiet_324',['getOutsideQuiet',['../classIRFujitsuAC.html#a404a06b5022899e622e629ec099864f5',1,'IRFujitsuAC']]], + ['getpower_325',['getPower',['../classIRAmcorAc.html#a141e2af9eb4530b175a430dee31bc5ae',1,'IRAmcorAc::getPower()'],['../classIRArgoAC.html#a10812d30095c4adc24cb3eee25e2d246',1,'IRArgoAC::getPower()'],['../classIRCarrierAc64.html#ad50ebb44815e55cc0a99f4762939dc54',1,'IRCarrierAc64::getPower()'],['../classIRCoolixAC.html#a150e3b827d8002e77135955079c78704',1,'IRCoolixAC::getPower()'],['../classIRCoronaAc.html#a313c5489b53bba5747e871ec0a7af417',1,'IRCoronaAc::getPower()'],['../classIRDaikinESP.html#a1d72647db12276493d8e093a4feda44e',1,'IRDaikinESP::getPower()'],['../classIRDaikin2.html#a2f25c4ff097f82a91c062aacd5ebabfc',1,'IRDaikin2::getPower()'],['../classIRDaikin216.html#a2b1e1dd2a059466ab5e5c8ab7eb4f2b4',1,'IRDaikin216::getPower()'],['../classIRDaikin160.html#ad472f0d0680da6ab83a1b636bc00e271',1,'IRDaikin160::getPower()'],['../classIRDaikin176.html#ad564616fc1bf90c00c594c2d3cb5394d',1,'IRDaikin176::getPower()'],['../classIRDaikin152.html#a8581147072fecf6ebd0dd2da50a63f05',1,'IRDaikin152::getPower()'],['../classIRDelonghiAc.html#ae077f0e444fcf24b1e0343e93244b7e8',1,'IRDelonghiAc::getPower()'],['../classIRElectraAc.html#aed11407cd8be470baf5d4667e28e1273',1,'IRElectraAc::getPower()'],['../classIRFujitsuAC.html#a5d03a83db8bc2084ae2acea17c2c7ae2',1,'IRFujitsuAC::getPower()'],['../classIRGoodweatherAc.html#a6f7db9f499c4fea860976bb273ba15df',1,'IRGoodweatherAc::getPower()'],['../classIRGreeAC.html#ac2c97551e02c6cce1b9983cc902f5f1a',1,'IRGreeAC::getPower()'],['../classIRHaierACYRW02.html#a446ee5873e80fa474d322ca5ff598fb5',1,'IRHaierACYRW02::getPower()'],['../classIRHitachiAc.html#a3be8c7ded012c2ad5cab59ee6fe3c88e',1,'IRHitachiAc::getPower()'],['../classIRHitachiAc1.html#ab4756a44153997ff686e8a14369407c0',1,'IRHitachiAc1::getPower()'],['../classIRHitachiAc424.html#ae4d3370d89253ec0861a60b84b2d078c',1,'IRHitachiAc424::getPower()'],['../classIRKelvinatorAC.html#a3dc660afab763c9a4b0cfc5d8e14d220',1,'IRKelvinatorAC::getPower()'],['../classIRLgAc.html#ac09b8af7cc2d46881d3a710068acb5bd',1,'IRLgAc::getPower()'],['../classIRMideaAC.html#a2035653f3ac503a8d30563fded46cab2',1,'IRMideaAC::getPower()'],['../classIRMitsubishiAC.html#aa5fb3f328b6c8a553d25088ec9e858d7',1,'IRMitsubishiAC::getPower()'],['../classIRMitsubishi136.html#a371faf10c80560e1ad59c70d66147723',1,'IRMitsubishi136::getPower()'],['../classIRMitsubishi112.html#afb9ea09a7a9724410470944f6decaeed',1,'IRMitsubishi112::getPower()'],['../classIRMitsubishiHeavy152Ac.html#a1e1d742e255685d1b16935d6031b25fc',1,'IRMitsubishiHeavy152Ac::getPower()'],['../classIRMitsubishiHeavy88Ac.html#a05c50ad07ba7be443414792c7e585354',1,'IRMitsubishiHeavy88Ac::getPower()'],['../classIRNeoclimaAc.html#a635e81f673155eb123dab84a78ff86d5',1,'IRNeoclimaAc::getPower()'],['../classIRPanasonicAc.html#a2d50ed3994f6cc6e205d2c5fb6c0cc55',1,'IRPanasonicAc::getPower()'],['../classIRSamsungAc.html#a26fb214fdf3af4d39a898a1721583cf3',1,'IRSamsungAc::getPower()'],['../classIRSharpAc.html#a49c6c86c901a8d02d7a0d67bfcc397af',1,'IRSharpAc::getPower()'],['../classIRTcl112Ac.html#a36e3b74c79ec42a0922893a3ccd5d045',1,'IRTcl112Ac::getPower()'],['../classIRTecoAc.html#a66c39da54baa6d0c56418ff8027a12a6',1,'IRTecoAc::getPower()'],['../classIRToshibaAC.html#a6d69c147e786aa642906f24c9781bb0f',1,'IRToshibaAC::getPower()'],['../classIRTrotecESP.html#a2e303fe918f79281df98cffb9d2cd539',1,'IRTrotecESP::getPower()'],['../classIRVestelAc.html#a1d6cdc9ad13ebbf1e9a4a83f95244ced',1,'IRVestelAc::getPower()']]], + ['getpowerbutton_326',['getPowerButton',['../classIRCoronaAc.html#ae38a9860cc3fe73909ba20260ad9a51a',1,'IRCoronaAc']]], + ['getpowerful_327',['getPowerful',['../classIRDaikinESP.html#a827c3dc88027b043271a469bc41c4bb1',1,'IRDaikinESP::getPowerful()'],['../classIRDaikin2.html#abad28f7287f4d90d196eb0eb7f93ed43',1,'IRDaikin2::getPowerful()'],['../classIRDaikin216.html#acf94e292df8f45233e115324a95a5e83',1,'IRDaikin216::getPowerful()'],['../classIRDaikin128.html#a50f2de409b3e8966f8406b659aaaedac',1,'IRDaikin128::getPowerful()'],['../classIRDaikin152.html#a20ec24a0ef288cabb93080b4fa0f71fe',1,'IRDaikin152::getPowerful()'],['../classIRPanasonicAc.html#a736b77df0563705095d8f4241a80b1cb',1,'IRPanasonicAc::getPowerful()'],['../classIRSamsungAc.html#ac43367d5aec71e1dcb5b178427268412',1,'IRSamsungAc::getPowerful()']]], + ['getpowerspecial_328',['getPowerSpecial',['../classIRSharpAc.html#aeb5d032c42863b6c3e2665c0719b9341',1,'IRSharpAc']]], + ['getpowertoggle_329',['getPowerToggle',['../classIRDaikin128.html#a0b6b298a0287411f6fe34ec1a0032ff1',1,'IRDaikin128::getPowerToggle()'],['../classIRDaikin64.html#a7921b6a9e776a1802b98e25c0ac4d2dc',1,'IRDaikin64::getPowerToggle()'],['../classIRHitachiAc1.html#a384412f40bfde7a9934fbb7eb2813641',1,'IRHitachiAc1::getPowerToggle()'],['../classIRWhirlpoolAc.html#a08150bcdcf13f0dfb3a7608b2d354a1e',1,'IRWhirlpoolAc::getPowerToggle()']]], + ['getpurify_330',['getPurify',['../classIRDaikin2.html#a3e2785832ae78bafa655aa61853a47bf',1,'IRDaikin2']]], + ['getquiet_331',['getQuiet',['../classIRDaikinESP.html#a25dcfbeacce65f9a89d14a87f759c483',1,'IRDaikinESP::getQuiet()'],['../classIRDaikin2.html#a237eb163e3dd1bf8e45ae2324f0b7dcf',1,'IRDaikin2::getQuiet()'],['../classIRDaikin216.html#aaa0f1aa62f8afd3d489a33af1c1067bc',1,'IRDaikin216::getQuiet()'],['../classIRDaikin128.html#a685bbc2afeecdef69180229b64e1d54b',1,'IRDaikin128::getQuiet()'],['../classIRDaikin152.html#adc8878ec0f6ea2d4fc2fa756a2e9ef4e',1,'IRDaikin152::getQuiet()'],['../classIRDaikin64.html#a431e41baa2881f397b5bf8ee2b79fec9',1,'IRDaikin64::getQuiet()'],['../classIRKelvinatorAC.html#a467c0d63911a87bed8815a5b636d6d75',1,'IRKelvinatorAC::getQuiet()'],['../classIRMitsubishi136.html#afaf690f15d21fea1070b33b2720e98fa',1,'IRMitsubishi136::getQuiet()'],['../classIRMitsubishi112.html#a3b3b78ba5114d783ab7696f3e4687002',1,'IRMitsubishi112::getQuiet()'],['../classIRPanasonicAc.html#a8d7dfc9b5f7c7a4523c0bfa4e0bc415a',1,'IRPanasonicAc::getQuiet()'],['../classIRSamsungAc.html#a0baaf3d40419bb744204bdb30d4aa9b9',1,'IRSamsungAc::getQuiet()']]], + ['getraw_332',['getRaw',['../classIRAmcorAc.html#aa2b99d815e499edf3ae53aebb35cbe9b',1,'IRAmcorAc::getRaw()'],['../classIRArgoAC.html#ac9e8b45dbbef453a54e3593d7e2927fb',1,'IRArgoAC::getRaw()'],['../classIRCarrierAc64.html#ad40279db2c9bd3d1abb5a6e028ec0d80',1,'IRCarrierAc64::getRaw()'],['../classIRCoolixAC.html#aa231938dfcff03325383205edc9c88d2',1,'IRCoolixAC::getRaw()'],['../classIRCoronaAc.html#ac2ba3b4bcefb801da345c9da5daa85fc',1,'IRCoronaAc::getRaw()'],['../classIRDaikinESP.html#ab100221dacc23402f486dee038df046d',1,'IRDaikinESP::getRaw()'],['../classIRDaikin2.html#aaf2ac0fc5924829a1209bd5e0b608b5f',1,'IRDaikin2::getRaw()'],['../classIRDaikin216.html#ac41b3de39ffc6ccd097085c727329531',1,'IRDaikin216::getRaw()'],['../classIRDaikin160.html#aeb68f80476362b0581fcb273b13cdf1e',1,'IRDaikin160::getRaw()'],['../classIRDaikin176.html#a86896be45037015683299004f2eb4d22',1,'IRDaikin176::getRaw()'],['../classIRDaikin128.html#a05669c2b1a6720b95d9a5fb898179a10',1,'IRDaikin128::getRaw()'],['../classIRDaikin152.html#a4af01f8a2459493762977f8ed260c4e6',1,'IRDaikin152::getRaw()'],['../classIRDaikin64.html#a1f8df45c67771ffca620f8c2f17af2e0',1,'IRDaikin64::getRaw()'],['../classIRDelonghiAc.html#a9e6934607f162df3d259d8fb95319d67',1,'IRDelonghiAc::getRaw()'],['../classIRElectraAc.html#a7674d29474ecbbb6366d96056794314c',1,'IRElectraAc::getRaw()'],['../classIRFujitsuAC.html#ae4dce44cab1f26756d63728cb8d55e65',1,'IRFujitsuAC::getRaw()'],['../classIRGoodweatherAc.html#a82d973e562b2425e8823fbc7332c06de',1,'IRGoodweatherAc::getRaw()'],['../classIRGreeAC.html#afa1595d4f69200b0076db1b9f8f2ea73',1,'IRGreeAC::getRaw()'],['../classIRHaierAC.html#abf72eed86c2c86c4f0f5f49f6a788b82',1,'IRHaierAC::getRaw()'],['../classIRHaierACYRW02.html#abca7bbe8c723551723f24f186343b764',1,'IRHaierACYRW02::getRaw()'],['../classIRHitachiAc.html#a8dafb9436f63cfc2d7e4f558fbd6e1ab',1,'IRHitachiAc::getRaw()'],['../classIRHitachiAc1.html#ad850b6364603880ccc444381e85af564',1,'IRHitachiAc1::getRaw()'],['../classIRHitachiAc424.html#acd8388f938feeaf6808ff65779435b5d',1,'IRHitachiAc424::getRaw()'],['../classIRHitachiAc3.html#a915605ca6d0bf3ff6fc9b376ddd394ae',1,'IRHitachiAc3::getRaw()'],['../classIRKelvinatorAC.html#a09149dd7bc45ca50b0c490b9c1f1e6f4',1,'IRKelvinatorAC::getRaw()'],['../classIRLgAc.html#afcb529d2f2c9016388264b80e6a99351',1,'IRLgAc::getRaw()'],['../classIRMideaAC.html#ae0b2c3a5a0a1d84eaeb462bbbe944d97',1,'IRMideaAC::getRaw()'],['../classIRMitsubishiAC.html#a1f2d0ea70bdeb71efab4c20ccd876aa9',1,'IRMitsubishiAC::getRaw()'],['../classIRMitsubishi136.html#a61cceec2bf241a75be1389391e8f3d9a',1,'IRMitsubishi136::getRaw()'],['../classIRMitsubishi112.html#a5e47e892921b8464652b55f41f42fd9a',1,'IRMitsubishi112::getRaw()'],['../classIRMitsubishiHeavy152Ac.html#a34ae73479c76b08512eaa87ed0662c0a',1,'IRMitsubishiHeavy152Ac::getRaw()'],['../classIRMitsubishiHeavy88Ac.html#af96915ac45861327ed7d55803dadd4fd',1,'IRMitsubishiHeavy88Ac::getRaw()'],['../classIRNeoclimaAc.html#a1f67329cad92d4252b0d33effce6380e',1,'IRNeoclimaAc::getRaw()'],['../classIRPanasonicAc.html#ad65c2bcdc3984a986f5ef2f03b5574d4',1,'IRPanasonicAc::getRaw()'],['../classIRSamsungAc.html#a96c6ac410053f0f2804160040d9fcf12',1,'IRSamsungAc::getRaw()'],['../classIRSharpAc.html#a9d680b0145c376060bd2d2e4c2630162',1,'IRSharpAc::getRaw()'],['../classIRTcl112Ac.html#a517375b764d1381aa5a7d4ec962346ec',1,'IRTcl112Ac::getRaw()'],['../classIRTecoAc.html#a7726e9d638cb81c7a4010112887a0ffe',1,'IRTecoAc::getRaw()'],['../classIRToshibaAC.html#a3572a06423851d2c4da5f85133a1a8ff',1,'IRToshibaAC::getRaw()'],['../classIRTrotecESP.html#a412dd2cf9dcb711003bcbb5b579cb2b8',1,'IRTrotecESP::getRaw()'],['../classIRVestelAc.html#afffd1dbcdec22ecca4efe9a996bf27e5',1,'IRVestelAc::getRaw()'],['../classIRWhirlpoolAc.html#a788a6a5373256e10200969cc5c73da63',1,'IRWhirlpoolAc::getRaw()']]], + ['getrclevel_333',['getRClevel',['../classIRrecv.html#a8e32daaa903a8e42dad7faaf405b33dc',1,'IRrecv']]], + ['getroomtemp_334',['getRoomTemp',['../classIRArgoAC.html#a5e4d8447c8851d2fce656abce6c4d368',1,'IRArgoAC']]], + ['getsave_335',['getSave',['../classIRTecoAc.html#a0b4eea3d89f3aef649e32ee1b8bf65a3',1,'IRTecoAc']]], + ['getsectionbyte_336',['getSectionByte',['../classIRCoronaAc.html#aed9181df842370739a5b4977b20769f9',1,'IRCoronaAc']]], + ['getsensor_337',['getSensor',['../classIRDaikinESP.html#ac22369a04bb8f428a127b3625d9989fc',1,'IRDaikinESP::getSensor()'],['../classIRDaikin152.html#a88d4d0d41f33f71d4a846f6c2547f597',1,'IRDaikin152::getSensor()']]], + ['getsensortemp_338',['getSensorTemp',['../classIRCoolixAC.html#aebbed796cab76248138e124aac1d535a',1,'IRCoolixAC']]], + ['getsilent_339',['getSilent',['../classIRMitsubishiHeavy152Ac.html#a93aa735996a31d6f1928aa35d704bd24',1,'IRMitsubishiHeavy152Ac']]], + ['getsleep_340',['getSleep',['../classIRCarrierAc64.html#a24f208b955af86f6927ac97b7f7066d5',1,'IRCarrierAc64::getSleep()'],['../classIRCoolixAC.html#a0b22f5427254c3f784f468d53909882c',1,'IRCoolixAC::getSleep()'],['../classIRDaikin128.html#a0cab507cdea112168757e1ab1a5a1dbe',1,'IRDaikin128::getSleep()'],['../classIRDaikin64.html#a32f4b90d4071cdbc4f37dd401e2d771f',1,'IRDaikin64::getSleep()'],['../classIRDelonghiAc.html#ab9baadd8f41c6dc7f89e71415e0e57b5',1,'IRDelonghiAc::getSleep()'],['../classIRGoodweatherAc.html#acf84e27fedc3c30a03c7d83e4843f8e0',1,'IRGoodweatherAc::getSleep()'],['../classIRGreeAC.html#abd106daa5324a454c5ced13e2fed2a1b',1,'IRGreeAC::getSleep()'],['../classIRHaierAC.html#a0ac7155d5ba294ce50b9436a35aa166b',1,'IRHaierAC::getSleep()'],['../classIRHaierACYRW02.html#acecf20cbe6065a4096ee5a353d2161c9',1,'IRHaierACYRW02::getSleep()'],['../classIRHitachiAc1.html#ab2e82cce1d9dc6e6ce66f2382ffcf4d4',1,'IRHitachiAc1::getSleep()'],['../classIRMideaAC.html#af4b76f42fd9be5eed9b546be7b0c34db',1,'IRMideaAC::getSleep()'],['../classIRNeoclimaAc.html#a8565f8f39127ed51eec7f7883319da61',1,'IRNeoclimaAc::getSleep()'],['../classIRTecoAc.html#a3eebb19e029aa882e161eb2bd6cfe333',1,'IRTecoAc::getSleep()'],['../classIRTrotecESP.html#a28558241d4dd18e191c6fab2c21f973e',1,'IRTrotecESP::getSleep()'],['../classIRVestelAc.html#a54f97dfe120c96b8c041550ed26d46f2',1,'IRVestelAc::getSleep()'],['../classIRWhirlpoolAc.html#a83c1b70e9c3b256b9e77ff6fb7fe0bde',1,'IRWhirlpoolAc::getSleep()']]], + ['getsleeptime_341',['getSleepTime',['../classIRDaikin2.html#a31af96f9a05b3adea2e2ae84d3d242b9',1,'IRDaikin2']]], + ['getsleeptimerenabled_342',['getSleepTimerEnabled',['../classIRDaikin2.html#ae4944acaa5c9d381a1875f4d0b16590a',1,'IRDaikin2']]], + ['getspecial_343',['getSpecial',['../classIRSharpAc.html#a18fb9e6f965682e4faae3d1ecc2561cb',1,'IRSharpAc']]], + ['getspeed_344',['getSpeed',['../classIRTrotecESP.html#ae57c9ab5bc2196f5028ea1af1bdb5428',1,'IRTrotecESP']]], + ['getstartclock_345',['getStartClock',['../classIRMitsubishiAC.html#a0e0d8fa3bec35107929aaa9e9b4b5818',1,'IRMitsubishiAC']]], + ['getstate_346',['getState',['../classIRac.html#af0122722691881b04c312bb30efcc3f2',1,'IRac']]], + ['getstatelength_347',['getStateLength',['../classIRFujitsuAC.html#a02636372996211d464c7394329921ea0',1,'IRFujitsuAC']]], + ['getstateprev_348',['getStatePrev',['../classIRac.html#adf582223eae0127491c7f1db38f101d3',1,'IRac']]], + ['getstopclock_349',['getStopClock',['../classIRMitsubishiAC.html#a9b6266611d7cf75337557533a32796c2',1,'IRMitsubishiAC']]], + ['getsuper_350',['getSuper',['../classIRWhirlpoolAc.html#a8bcf542e3499d05c4028157c803a0965',1,'IRWhirlpoolAc']]], + ['getswing_351',['getSwing',['../classIRCoolixAC.html#a4846bb6a16802158dca3a8b1b7f5b6ff',1,'IRCoolixAC::getSwing()'],['../classIRFujitsuAC.html#af6f05f1375c3c4662d10026028fadbed',1,'IRFujitsuAC::getSwing()'],['../classIRGoodweatherAc.html#a96c844ec310323b62d9127ff250c3629',1,'IRGoodweatherAc::getSwing()'],['../classIRHaierAC.html#aa18839d213e4cd46405c683ec67fa23e',1,'IRHaierAC::getSwing()'],['../classIRHaierACYRW02.html#a88b15d20c007926ab5871b8e6a9fbe3f',1,'IRHaierACYRW02::getSwing()'],['../classIRSamsungAc.html#a5e6a7caccfdcb23cdb7d1341376c2343',1,'IRSamsungAc::getSwing()'],['../classIRTecoAc.html#a152fb025a2ba4410864637e8fdcef27a',1,'IRTecoAc::getSwing()'],['../classIRVestelAc.html#a991f8ca21319cb39b6c4cd358de4dbf4',1,'IRVestelAc::getSwing()'],['../classIRWhirlpoolAc.html#abac55fcea520ea4bbef3fa76223e2efc',1,'IRWhirlpoolAc::getSwing()']]], + ['getswingh_352',['getSwingH',['../classIRElectraAc.html#a40e8f0ae2e57c3adf756b12524b36e6d',1,'IRElectraAc::getSwingH()'],['../classIRHitachiAc1.html#ac5bfde2c87281d3e7f427cb7ea601e85',1,'IRHitachiAc1::getSwingH()'],['../classIRHitachiAc344.html#a33ad0fe4939b2e2456a3d8a09da5a161',1,'IRHitachiAc344::getSwingH()'],['../classIRMitsubishi112.html#a05a343020c64f0ef95c365adcb337140',1,'IRMitsubishi112::getSwingH()'],['../classIRNeoclimaAc.html#a133fb28183fc33702bd8afb7c8886cb2',1,'IRNeoclimaAc::getSwingH()']]], + ['getswinghorizontal_353',['getSwingHorizontal',['../classIRDaikinESP.html#a0a551cc1c22b5378015e8722919534aa',1,'IRDaikinESP::getSwingHorizontal()'],['../classIRDaikin2.html#a338a70b5d7f71da467a0f32b4a057f13',1,'IRDaikin2::getSwingHorizontal()'],['../classIRDaikin216.html#a4b5c648e6568bf1dd24932e108c560d9',1,'IRDaikin216::getSwingHorizontal()'],['../classIRDaikin176.html#aac0a1b9b5e618b31c651b9abc158a552',1,'IRDaikin176::getSwingHorizontal()'],['../classIRHitachiAc.html#a080f87358270eb1482d4a5d4b873f22c',1,'IRHitachiAc::getSwingHorizontal()'],['../classIRKelvinatorAC.html#abe27eb5ec7eb4c4b766a47b551422af3',1,'IRKelvinatorAC::getSwingHorizontal()'],['../classIRMitsubishiHeavy152Ac.html#a587eddf4684bdcb6c399b3f9c6cec684',1,'IRMitsubishiHeavy152Ac::getSwingHorizontal()'],['../classIRMitsubishiHeavy88Ac.html#ae538830313d02aa1ecc671188687dd35',1,'IRMitsubishiHeavy88Ac::getSwingHorizontal()'],['../classIRPanasonicAc.html#a37d9b268b3c8527be0939e0a24b02ef6',1,'IRPanasonicAc::getSwingHorizontal()'],['../classIRTcl112Ac.html#a7080def7f41498fc5af723e852c2e75c',1,'IRTcl112Ac::getSwingHorizontal()']]], + ['getswingtoggle_354',['getSwingToggle',['../classIRHitachiAc1.html#ac4a5d4d5f9b4ae000d0acb232a1e2752',1,'IRHitachiAc1::getSwingToggle()'],['../classIRSharpAc.html#ae0327e90a68638c254706a99ed40f173',1,'IRSharpAc::getSwingToggle()']]], + ['getswingv_355',['getSwingV',['../classIRCarrierAc64.html#a78aac688a4b040b2b6102fac8b028bde',1,'IRCarrierAc64::getSwingV()'],['../classIRDaikin152.html#a74ee60e666520513b33927178f15bc7e',1,'IRDaikin152::getSwingV()'],['../classIRElectraAc.html#a9cd2a7d7716f855dca6be12e3cdc3d24',1,'IRElectraAc::getSwingV()'],['../classIRHitachiAc1.html#a24216e1bc4cf9e9187e9031cee1684dc',1,'IRHitachiAc1::getSwingV()'],['../classIRHitachiAc344.html#a4e011e409f1bf97c8bd4043e2d069020',1,'IRHitachiAc344::getSwingV()'],['../classIRMitsubishi136.html#af2cacca74c4a6ade5f9689674bb707ea',1,'IRMitsubishi136::getSwingV()'],['../classIRMitsubishi112.html#a6d1e939169686978c83a2b26ebc3b8c2',1,'IRMitsubishi112::getSwingV()'],['../classIRNeoclimaAc.html#a3007ed9857bb212de05b7757ee0691e3',1,'IRNeoclimaAc::getSwingV()']]], + ['getswingvertical_356',['getSwingVertical',['../classIRDaikinESP.html#a95f87fd97248e13c6339b71702a79e3a',1,'IRDaikinESP::getSwingVertical()'],['../classIRDaikin2.html#aa1d07be72001f06b6a8dfc279ffc40f5',1,'IRDaikin2::getSwingVertical()'],['../classIRDaikin216.html#ae72a3858a0023dac48fe755fd1bb1677',1,'IRDaikin216::getSwingVertical()'],['../classIRDaikin160.html#a5ed62940052f79587c92eaf92e30cf53',1,'IRDaikin160::getSwingVertical()'],['../classIRDaikin128.html#a60c21eaff6bf860ae25b974a0fd04e11',1,'IRDaikin128::getSwingVertical()'],['../classIRDaikin64.html#a7d538ad1ae23b92c1d82ae85ddd55ef1',1,'IRDaikin64::getSwingVertical()'],['../classIRHitachiAc.html#a9f507cc12bd3a5639777af0329a6dd5c',1,'IRHitachiAc::getSwingVertical()'],['../classIRKelvinatorAC.html#a69aaabc1f34e061272a76e4dc3c98bf1',1,'IRKelvinatorAC::getSwingVertical()'],['../classIRMitsubishiHeavy152Ac.html#a73c59d829a82306edf22acbd930650e0',1,'IRMitsubishiHeavy152Ac::getSwingVertical()'],['../classIRMitsubishiHeavy88Ac.html#ae836aee7dfb729f6b978b0b4ac8e9d3c',1,'IRMitsubishiHeavy88Ac::getSwingVertical()'],['../classIRPanasonicAc.html#a7a35303cd4fb4b23c0e5a25777d5819c',1,'IRPanasonicAc::getSwingVertical()'],['../classIRTcl112Ac.html#a0b75d06b14c1b7e2d2eb3a8779160ae5',1,'IRTcl112Ac::getSwingVertical()']]], + ['getswingverticalauto_357',['getSwingVerticalAuto',['../classIRGreeAC.html#a4105bcde953896b12df050b12f1a45cc',1,'IRGreeAC']]], + ['getswingverticalposition_358',['getSwingVerticalPosition',['../classIRGreeAC.html#a7b1b840483ef92102dd61fefd52ccd8b',1,'IRGreeAC']]], + ['getswingvtoggle_359',['getSwingVToggle',['../classIRCoronaAc.html#ab10588a662031607ed4d01603a4471d6',1,'IRCoronaAc::getSwingVToggle()'],['../classIRHitachiAc424.html#ab697f595b6323288b6fd86f2a2911333',1,'IRHitachiAc424::getSwingVToggle()'],['../classIRMideaAC.html#a50b260d69bc0df8851bfccb003971dfe',1,'IRMideaAC::getSwingVToggle()']]], + ['gettemp_360',['getTemp',['../classIRAmcorAc.html#a2f3e4765a3ae65ffda197f5a58070bf3',1,'IRAmcorAc::getTemp()'],['../classIRArgoAC.html#af5c4cfd3cac33f223e2807ec831df0a9',1,'IRArgoAC::getTemp()'],['../classIRCarrierAc64.html#a799edf21e766b8ae2638a9b1e1d18ac1',1,'IRCarrierAc64::getTemp()'],['../classIRCoolixAC.html#af90462598f294a75b35e20d986251942',1,'IRCoolixAC::getTemp()'],['../classIRCoronaAc.html#ac951434588fd9fa2de630db9ae844840',1,'IRCoronaAc::getTemp()'],['../classIRDaikinESP.html#a43c6675b688cad1ca714ecd726dbb411',1,'IRDaikinESP::getTemp()'],['../classIRDaikin2.html#aa1d39acc14bff5d55e918cb123c66e83',1,'IRDaikin2::getTemp()'],['../classIRDaikin216.html#a65b37310c01075c34cedd5ca1c8a2c37',1,'IRDaikin216::getTemp()'],['../classIRDaikin160.html#ae9cee15343fce5b0f32a4f2ff13a9dbe',1,'IRDaikin160::getTemp()'],['../classIRDaikin176.html#aa9015826e70e4ef1a319db4b2a3fba5f',1,'IRDaikin176::getTemp()'],['../classIRDaikin128.html#a0b5aa11a597bded38c067a9e9a01fd45',1,'IRDaikin128::getTemp()'],['../classIRDaikin152.html#af0a1f8bf9fe412186b53977d225032b2',1,'IRDaikin152::getTemp()'],['../classIRDaikin64.html#abeff1ec38e2d3c9fa12d59e506e7b699',1,'IRDaikin64::getTemp()'],['../classIRDelonghiAc.html#a5664302ab883fc88c23c8bb2aa020cb9',1,'IRDelonghiAc::getTemp()'],['../classIRElectraAc.html#ae92bd241a14058ece0e6d27332f9a3fa',1,'IRElectraAc::getTemp()'],['../classIRFujitsuAC.html#a9209df913f46821a66a390b8cff37acf',1,'IRFujitsuAC::getTemp()'],['../classIRGoodweatherAc.html#a796089c84e265cd7f1b2b82edc6b2367',1,'IRGoodweatherAc::getTemp()'],['../classIRGreeAC.html#a3e935c044cdccfb988a97d5fb0c4068b',1,'IRGreeAC::getTemp()'],['../classIRHaierAC.html#af137371c6766ee068a0200ff1facd8b0',1,'IRHaierAC::getTemp()'],['../classIRHaierACYRW02.html#a9cb0edcb5f36054e4e024c38ec3f26b9',1,'IRHaierACYRW02::getTemp()'],['../classIRHitachiAc.html#a85e0b2dfa45e894d1a89a2f862c6aa69',1,'IRHitachiAc::getTemp()'],['../classIRHitachiAc1.html#ac5c55a06a32134bb3e30b83cce2feeaa',1,'IRHitachiAc1::getTemp()'],['../classIRHitachiAc424.html#aa405408fd31795b714486af88a86112e',1,'IRHitachiAc424::getTemp()'],['../classIRKelvinatorAC.html#aabda77a2381526f4be86f05b311248db',1,'IRKelvinatorAC::getTemp()'],['../classIRLgAc.html#a029399c5926bd4f1ff0b26175bc4af79',1,'IRLgAc::getTemp()'],['../classIRMideaAC.html#a546ab6d3e317e6219ad371fd0825520d',1,'IRMideaAC::getTemp()'],['../classIRMitsubishiAC.html#a9881be01c53dce83bd1eae8a32f150f4',1,'IRMitsubishiAC::getTemp()'],['../classIRMitsubishi136.html#a34bc0e7666264a7e567e45405a57e3e0',1,'IRMitsubishi136::getTemp()'],['../classIRMitsubishi112.html#a4bfd306fecfcaa4c20589440ecfb35db',1,'IRMitsubishi112::getTemp()'],['../classIRMitsubishiHeavy152Ac.html#a7ec864271cf232cab7b8bd778bc36cb4',1,'IRMitsubishiHeavy152Ac::getTemp()'],['../classIRMitsubishiHeavy88Ac.html#afd629c9951a390b7809bc6ac4d3aeeb1',1,'IRMitsubishiHeavy88Ac::getTemp()'],['../classIRNeoclimaAc.html#aaa1a625af6cf094823b58f1fe43deb3a',1,'IRNeoclimaAc::getTemp()'],['../classIRPanasonicAc.html#af8a5607c317e541752fada6ca79ee80f',1,'IRPanasonicAc::getTemp()'],['../classIRSamsungAc.html#a11a6c86f2e4a918e1587ef564c63dddd',1,'IRSamsungAc::getTemp()'],['../classIRSharpAc.html#a1f75c17cc396162e776f3c6cd1848f50',1,'IRSharpAc::getTemp()'],['../classIRTcl112Ac.html#a61bf139cc737b99e5d68294c353eb353',1,'IRTcl112Ac::getTemp()'],['../classIRTecoAc.html#a40e717564222c5c1e4fdce13eba5efc3',1,'IRTecoAc::getTemp()'],['../classIRToshibaAC.html#ab2a9b47d49c5608c97a7c6968c43037d',1,'IRToshibaAC::getTemp()'],['../classIRTrotecESP.html#adcfae2ee1e58cd6a78805c72d7a8a942',1,'IRTrotecESP::getTemp()'],['../classIRVestelAc.html#a835ab977fa0dbf47776e5d618d59c819',1,'IRVestelAc::getTemp()'],['../classIRWhirlpoolAc.html#a4a73ee67cb2eb4407e78add1009cdd51',1,'IRWhirlpoolAc::getTemp()']]], + ['gettempoffset_361',['getTempOffset',['../classIRWhirlpoolAc.html#a2d6111c9b97745d197f0b5d4d4610b3d',1,'IRWhirlpoolAc']]], + ['gettempraw_362',['getTempRaw',['../classIRCoolixAC.html#a559634f3c6aee54683d4b6ccbbc7a884',1,'IRCoolixAC']]], + ['gettempunit_363',['getTempUnit',['../classIRDelonghiAc.html#a8bbe27e1e87fbfc6b126c7f135886632',1,'IRDelonghiAc']]], + ['gettime_364',['getTime',['../classIRHaierAC.html#a60e891775fbc3a77ee487cde26f650c5',1,'IRHaierAC::getTime()'],['../classIRVestelAc.html#a3542ec93c30ec3bc1bb4e242edcf1def',1,'IRVestelAc::getTime()'],['../classIRWhirlpoolAc.html#a27aba1f22b55aa6f72686e0a722682b0',1,'IRWhirlpoolAc::getTime()']]], + ['gettimer_365',['getTimer',['../classIRDaikin128.html#ab35fa1fdd65db9d9cd7fbaffdd4ecd85',1,'IRDaikin128::getTimer()'],['../classIRGreeAC.html#a7a56024e2840306e071e03d1fae53ce9',1,'IRGreeAC::getTimer()'],['../classIRMitsubishiAC.html#a8bb8e92a00f8d9dfff31589d435c9ae5',1,'IRMitsubishiAC::getTimer()'],['../classIRTecoAc.html#a0bff25b2c686e397b62300ce5cad90f7',1,'IRTecoAc::getTimer()'],['../classIRTrotecESP.html#ae372b3120f0253c5a1607460817d36f6',1,'IRTrotecESP::getTimer()'],['../classIRVestelAc.html#aca4faedc9d82e357c8974fc6143b6e77',1,'IRVestelAc::getTimer()']]], + ['gettimerenabled_366',['getTimerEnabled',['../classIRGreeAC.html#aeec03eb7f506a0ba62c28469b789b0da',1,'IRGreeAC::getTimerEnabled()'],['../classIRSharpAc.html#abd7c061b343b4f096019f42ad6162940',1,'IRSharpAc::getTimerEnabled()'],['../classIRTecoAc.html#a3524f149cd3076e757a1b3228bdf12f2',1,'IRTecoAc::getTimerEnabled()']]], + ['gettimertime_367',['getTimerTime',['../classIRSharpAc.html#a72044d8afb1349a29cd8adcc8644c7ac',1,'IRSharpAc']]], + ['gettimertype_368',['getTimerType',['../classIRSharpAc.html#a9357c50c356b29cc444bf9aafb7df146',1,'IRSharpAc']]], + ['gettolerance_369',['getTolerance',['../classIRrecv.html#a144f64da3b44708394c06b0fbefb6347',1,'IRrecv']]], + ['getturbo_370',['getTurbo',['../classIRCoolixAC.html#ab5f87216fb91bbb437c0899b0742a63f',1,'IRCoolixAC::getTurbo()'],['../classIRDaikin64.html#ade80a5ea137c32bdedd794d64925a2d3',1,'IRDaikin64::getTurbo()'],['../classIRElectraAc.html#a75cae6845498eec84109374a2fefcced',1,'IRElectraAc::getTurbo()'],['../classIRGoodweatherAc.html#a983eca3c2ec1233184939702f43557eb',1,'IRGoodweatherAc::getTurbo()'],['../classIRGreeAC.html#a6e319c8584d0cb82223fd190fa4bde29',1,'IRGreeAC::getTurbo()'],['../classIRHaierACYRW02.html#a4ccd26dad24915b81ae5fb94d18fb85a',1,'IRHaierACYRW02::getTurbo()'],['../classIRKelvinatorAC.html#aff32ab0524f4afeb9b53aa65b8df8e36',1,'IRKelvinatorAC::getTurbo()'],['../classIRMitsubishiHeavy152Ac.html#acf2a73ccddb87bd66c39670bd1d3caba',1,'IRMitsubishiHeavy152Ac::getTurbo()'],['../classIRMitsubishiHeavy88Ac.html#a179ecc619e9eea4adb601309421e5fc0',1,'IRMitsubishiHeavy88Ac::getTurbo()'],['../classIRNeoclimaAc.html#a6cf241f0392744a91b703475ee88bfa1',1,'IRNeoclimaAc::getTurbo()'],['../classIRSharpAc.html#aad2ec46f8da6fd84bc0523f40d6bd57d',1,'IRSharpAc::getTurbo()'],['../classIRTcl112Ac.html#a0de33a2175eada44030d3640d940b697',1,'IRTcl112Ac::getTurbo()'],['../classIRVestelAc.html#a9ce168cc9422e54d631aed571cfe66be',1,'IRVestelAc::getTurbo()']]], + ['getusecelsius_371',['getUseCelsius',['../classIRMideaAC.html#aa88de606a914e33e8beb75a069137b52',1,'IRMideaAC']]], + ['getusefahrenheit_372',['getUseFahrenheit',['../classIRGreeAC.html#aad6acfb8a697aba851bb34b14bc94ac1',1,'IRGreeAC']]], + ['getvane_373',['getVane',['../classIRMitsubishiAC.html#acd98301535e7e161f8fdf42877f3e482',1,'IRMitsubishiAC']]], + ['getweeklytimerenable_374',['getWeeklyTimerEnable',['../classIRDaikinESP.html#a9ee2013c069496884c62b6e9a58d01db',1,'IRDaikinESP']]], + ['getwidevane_375',['getWideVane',['../classIRMitsubishiAC.html#a217dba9f9dcc6f75d466b0b7beca3aea',1,'IRMitsubishiAC']]], + ['getwifi_376',['getWiFi',['../classIRGreeAC.html#a967afbe980bae858ce0e4daea6628c37',1,'IRGreeAC']]], + ['getxfan_377',['getXFan',['../classIRGreeAC.html#acb677dde02be1a3461a7c8bc2406194f',1,'IRGreeAC::getXFan()'],['../classIRKelvinatorAC.html#a2e511ca0a8876928412c2db9214e7fe2',1,'IRKelvinatorAC::getXFan()']]], + ['getzonefollow_378',['getZoneFollow',['../classIRCoolixAC.html#a647a41d63301e3d95460323d1fe0ce4a',1,'IRCoolixAC']]], + ['gicable_379',['GICABLE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac8f9010b746a07a7a6329d1b336b68cf',1,'IRremoteESP8266.h']]], + ['globalcache_380',['GLOBALCACHE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf8c11b983768907fdb625ff9fb3729d2',1,'IRremoteESP8266.h']]], + ['goodweather_381',['goodweather',['../classIRac.html#ac47ff5c6faf41e6fb37df258a8bafc08',1,'IRac::goodweather()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9e8d893590b745f6b1b5ffcb556d9cba',1,'GOODWEATHER(): IRremoteESP8266.h']]], + ['gree_382',['gree',['../classIRac.html#ab66e48b039c9990bf97cd8c2512a6c70',1,'IRac::gree()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadae3a5e7c315f6f88b34a4c856f280ed83',1,'GREE(): IRremoteESP8266.h']]], + ['gree_5fac_5fremote_5fmodel_5ft_383',['gree_ac_remote_model_t',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.html new file mode 100644 index 000000000..cf2b5df92 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.js new file mode 100644 index 000000000..e58d7a183 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['haier_384',['haier',['../classIRac.html#ae0a29a4cb8c7a4707a7725c576822a58',1,'IRac']]], + ['haier_5fac_385',['HAIER_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1f232bcdf330ec2e353196941b9f1628',1,'IRremoteESP8266.h']]], + ['haier_5fac_5fyrw02_386',['HAIER_AC_YRW02',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaacda5821835865551f6df46c76282fa4',1,'IRremoteESP8266.h']]], + ['haieryrwo2_387',['haierYrwo2',['../classIRac.html#a7bc779a162dd9a1b4c925febec443353',1,'IRac']]], + ['handlespecialstate_388',['handleSpecialState',['../classIRCoolixAC.html#af78090c6d8b45b4202a80f1223640390',1,'IRCoolixAC']]], + ['handletoggles_389',['handleToggles',['../classIRac.html#a36833999dce4ad608a5a0f084988cfd1',1,'IRac']]], + ['hasacstate_390',['hasACState',['../IRutils_8cpp.html#a6efd4986db60709d3501606ec7ab5382',1,'hasACState(const decode_type_t protocol): IRutils.cpp'],['../IRutils_8h.html#a6efd4986db60709d3501606ec7ab5382',1,'hasACState(const decode_type_t protocol): IRutils.cpp']]], + ['hasinvertedstates_391',['hasInvertedStates',['../classIRHitachiAc3.html#ac06b36245c85480d97c1a9f49cfaa005',1,'IRHitachiAc3']]], + ['hasstatechanged_392',['hasStateChanged',['../classIRac.html#a35258c35a2d2b19886292b22b2aa053a',1,'IRac']]], + ['heat_5fmode_393',['heat_mode',['../classIRArgoAC.html#a255762f71502b9ffeb0686759991ec53',1,'IRArgoAC']]], + ['hitachi_394',['hitachi',['../classIRac.html#acd0f2fcf03aabf947a19a195000add3c',1,'IRac']]], + ['hitachi1_395',['hitachi1',['../classIRac.html#ac8807d62f6ae87af72d44b50bed3f17b',1,'IRac']]], + ['hitachi344_396',['hitachi344',['../classIRac.html#a0bc34635a1a349816344916a82585460',1,'IRac']]], + ['hitachi424_397',['hitachi424',['../classIRac.html#aec6de0752ddd3a3e7c6824cb1b692508',1,'IRac']]], + ['hitachi_5fac_398',['HITACHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9020fb54ac69d8aec0185f7e80c962ca',1,'IRremoteESP8266.h']]], + ['hitachi_5fac1_399',['HITACHI_AC1',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7d9a74161d95e62bece3c0e48900cb35',1,'IRremoteESP8266.h']]], + ['hitachi_5fac1_5fremote_5fmodel_5ft_400',['hitachi_ac1_remote_model_t',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49',1,'IRsend.h']]], + ['hitachi_5fac2_401',['HITACHI_AC2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab5a44068d519506efa8a3113aa44c9c0',1,'IRremoteESP8266.h']]], + ['hitachi_5fac3_402',['HITACHI_AC3',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac3487c47b14da6af922f5b27992b30f3',1,'IRremoteESP8266.h']]], + ['hitachi_5fac344_403',['HITACHI_AC344',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1e147eb39adc40e4181940cc2357f070',1,'IRremoteESP8266.h']]], + ['hitachi_5fac424_404',['HITACHI_AC424',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada85af068f8964d4359512265d8cc27a31',1,'IRremoteESP8266.h']]], + ['htmlescape_405',['htmlEscape',['../namespaceirutils.html#a6e55c6fdcc82e1ef8bd5f73df83609a7',1,'irutils']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.html new file mode 100644 index 000000000..690785a5d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.js new file mode 100644 index 000000000..64280c4ef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.js @@ -0,0 +1,175 @@ +var searchData= +[ + ['i18n_2eh_406',['i18n.h',['../i18n_8h.html',1,'']]], + ['inax_407',['INAX',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadafc566aab3afb8face6d8965ca4d0eab7',1,'IRremoteESP8266.h']]], + ['irremoteesp8266_20library_20api_20documentation_408',['IRremoteESP8266 Library API Documentation',['../index.html',1,'']]], + ['initstate_409',['initState',['../classIRac.html#af1c4ae70e61298c0be8d350d67e7c342',1,'IRac::initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)'],['../classIRac.html#a165b7fdb9b3a02b1fb5ff2c2c3747958',1,'IRac::initState(stdAc::state_t *state)']]], + ['invertbits_410',['invertBits',['../IRutils_8cpp.html#a1a85904f25c8ec77fb554d238c59cfdb',1,'invertBits(const uint64_t data, const uint16_t nbits): IRutils.cpp'],['../IRutils_8h.html#a1a85904f25c8ec77fb554d238c59cfdb',1,'invertBits(const uint64_t data, const uint16_t nbits): IRutils.cpp']]], + ['ir_5fairwell_2ecpp_411',['ir_Airwell.cpp',['../ir__Airwell_8cpp.html',1,'']]], + ['ir_5faiwa_2ecpp_412',['ir_Aiwa.cpp',['../ir__Aiwa_8cpp.html',1,'']]], + ['ir_5famcor_2ecpp_413',['ir_Amcor.cpp',['../ir__Amcor_8cpp.html',1,'']]], + ['ir_5famcor_2eh_414',['ir_Amcor.h',['../ir__Amcor_8h.html',1,'']]], + ['ir_5fargo_2ecpp_415',['ir_Argo.cpp',['../ir__Argo_8cpp.html',1,'']]], + ['ir_5fargo_2eh_416',['ir_Argo.h',['../ir__Argo_8h.html',1,'']]], + ['ir_5fcarrier_2ecpp_417',['ir_Carrier.cpp',['../ir__Carrier_8cpp.html',1,'']]], + ['ir_5fcarrier_2eh_418',['ir_Carrier.h',['../ir__Carrier_8h.html',1,'']]], + ['ir_5fcoolix_2ecpp_419',['ir_Coolix.cpp',['../ir__Coolix_8cpp.html',1,'']]], + ['ir_5fcoolix_2eh_420',['ir_Coolix.h',['../ir__Coolix_8h.html',1,'']]], + ['ir_5fcorona_2ecpp_421',['ir_Corona.cpp',['../ir__Corona_8cpp.html',1,'']]], + ['ir_5fcorona_2eh_422',['ir_Corona.h',['../ir__Corona_8h.html',1,'']]], + ['ir_5fdaikin_2ecpp_423',['ir_Daikin.cpp',['../ir__Daikin_8cpp.html',1,'']]], + ['ir_5fdaikin_2eh_424',['ir_Daikin.h',['../ir__Daikin_8h.html',1,'']]], + ['ir_5fdelonghi_2ecpp_425',['ir_Delonghi.cpp',['../ir__Delonghi_8cpp.html',1,'']]], + ['ir_5fdelonghi_2eh_426',['ir_Delonghi.h',['../ir__Delonghi_8h.html',1,'']]], + ['ir_5fdenon_2ecpp_427',['ir_Denon.cpp',['../ir__Denon_8cpp.html',1,'']]], + ['ir_5fdish_2ecpp_428',['ir_Dish.cpp',['../ir__Dish_8cpp.html',1,'']]], + ['ir_5fdoshisha_2ecpp_429',['ir_Doshisha.cpp',['../ir__Doshisha_8cpp.html',1,'']]], + ['ir_5felectra_2ecpp_430',['ir_Electra.cpp',['../ir__Electra_8cpp.html',1,'']]], + ['ir_5felectra_2eh_431',['ir_Electra.h',['../ir__Electra_8h.html',1,'']]], + ['ir_5fepson_2ecpp_432',['ir_Epson.cpp',['../ir__Epson_8cpp.html',1,'']]], + ['ir_5ffujitsu_2ecpp_433',['ir_Fujitsu.cpp',['../ir__Fujitsu_8cpp.html',1,'']]], + ['ir_5ffujitsu_2eh_434',['ir_Fujitsu.h',['../ir__Fujitsu_8h.html',1,'']]], + ['ir_5fgicable_2ecpp_435',['ir_GICable.cpp',['../ir__GICable_8cpp.html',1,'']]], + ['ir_5fglobalcache_2ecpp_436',['ir_GlobalCache.cpp',['../ir__GlobalCache_8cpp.html',1,'']]], + ['ir_5fgoodweather_2ecpp_437',['ir_Goodweather.cpp',['../ir__Goodweather_8cpp.html',1,'']]], + ['ir_5fgoodweather_2eh_438',['ir_Goodweather.h',['../ir__Goodweather_8h.html',1,'']]], + ['ir_5fgree_2ecpp_439',['ir_Gree.cpp',['../ir__Gree_8cpp.html',1,'']]], + ['ir_5fgree_2eh_440',['ir_Gree.h',['../ir__Gree_8h.html',1,'']]], + ['ir_5fhaier_2ecpp_441',['ir_Haier.cpp',['../ir__Haier_8cpp.html',1,'']]], + ['ir_5fhaier_2eh_442',['ir_Haier.h',['../ir__Haier_8h.html',1,'']]], + ['ir_5fhitachi_2ecpp_443',['ir_Hitachi.cpp',['../ir__Hitachi_8cpp.html',1,'']]], + ['ir_5fhitachi_2eh_444',['ir_Hitachi.h',['../ir__Hitachi_8h.html',1,'']]], + ['ir_5finax_2ecpp_445',['ir_Inax.cpp',['../ir__Inax_8cpp.html',1,'']]], + ['ir_5fjvc_2ecpp_446',['ir_JVC.cpp',['../ir__JVC_8cpp.html',1,'']]], + ['ir_5fkelvinator_2ecpp_447',['ir_Kelvinator.cpp',['../ir__Kelvinator_8cpp.html',1,'']]], + ['ir_5fkelvinator_2eh_448',['ir_Kelvinator.h',['../ir__Kelvinator_8h.html',1,'']]], + ['ir_5flasertag_2ecpp_449',['ir_Lasertag.cpp',['../ir__Lasertag_8cpp.html',1,'']]], + ['ir_5flego_2ecpp_450',['ir_Lego.cpp',['../ir__Lego_8cpp.html',1,'']]], + ['ir_5flg_2ecpp_451',['ir_LG.cpp',['../ir__LG_8cpp.html',1,'']]], + ['ir_5flg_2eh_452',['ir_LG.h',['../ir__LG_8h.html',1,'']]], + ['ir_5flutron_2ecpp_453',['ir_Lutron.cpp',['../ir__Lutron_8cpp.html',1,'']]], + ['ir_5fmagiquest_2ecpp_454',['ir_Magiquest.cpp',['../ir__Magiquest_8cpp.html',1,'']]], + ['ir_5fmagiquest_2eh_455',['ir_Magiquest.h',['../ir__Magiquest_8h.html',1,'']]], + ['ir_5fmidea_2ecpp_456',['ir_Midea.cpp',['../ir__Midea_8cpp.html',1,'']]], + ['ir_5fmidea_2eh_457',['ir_Midea.h',['../ir__Midea_8h.html',1,'']]], + ['ir_5fmitsubishi_2ecpp_458',['ir_Mitsubishi.cpp',['../ir__Mitsubishi_8cpp.html',1,'']]], + ['ir_5fmitsubishi_2eh_459',['ir_Mitsubishi.h',['../ir__Mitsubishi_8h.html',1,'']]], + ['ir_5fmitsubishiheavy_2ecpp_460',['ir_MitsubishiHeavy.cpp',['../ir__MitsubishiHeavy_8cpp.html',1,'']]], + ['ir_5fmitsubishiheavy_2eh_461',['ir_MitsubishiHeavy.h',['../ir__MitsubishiHeavy_8h.html',1,'']]], + ['ir_5fmultibrackets_2ecpp_462',['ir_Multibrackets.cpp',['../ir__Multibrackets_8cpp.html',1,'']]], + ['ir_5fmwm_2ecpp_463',['ir_MWM.cpp',['../ir__MWM_8cpp.html',1,'']]], + ['ir_5fnec_2ecpp_464',['ir_NEC.cpp',['../ir__NEC_8cpp.html',1,'']]], + ['ir_5fnec_2eh_465',['ir_NEC.h',['../ir__NEC_8h.html',1,'']]], + ['ir_5fneoclima_2ecpp_466',['ir_Neoclima.cpp',['../ir__Neoclima_8cpp.html',1,'']]], + ['ir_5fneoclima_2eh_467',['ir_Neoclima.h',['../ir__Neoclima_8h.html',1,'']]], + ['ir_5fnikai_2ecpp_468',['ir_Nikai.cpp',['../ir__Nikai_8cpp.html',1,'']]], + ['ir_5fpanasonic_2ecpp_469',['ir_Panasonic.cpp',['../ir__Panasonic_8cpp.html',1,'']]], + ['ir_5fpanasonic_2eh_470',['ir_Panasonic.h',['../ir__Panasonic_8h.html',1,'']]], + ['ir_5fpioneer_2ecpp_471',['ir_Pioneer.cpp',['../ir__Pioneer_8cpp.html',1,'']]], + ['ir_5fpronto_2ecpp_472',['ir_Pronto.cpp',['../ir__Pronto_8cpp.html',1,'']]], + ['ir_5frc5_5frc6_2ecpp_473',['ir_RC5_RC6.cpp',['../ir__RC5__RC6_8cpp.html',1,'']]], + ['ir_5frcmm_2ecpp_474',['ir_RCMM.cpp',['../ir__RCMM_8cpp.html',1,'']]], + ['ir_5fsamsung_2ecpp_475',['ir_Samsung.cpp',['../ir__Samsung_8cpp.html',1,'']]], + ['ir_5fsamsung_2eh_476',['ir_Samsung.h',['../ir__Samsung_8h.html',1,'']]], + ['ir_5fsanyo_2ecpp_477',['ir_Sanyo.cpp',['../ir__Sanyo_8cpp.html',1,'']]], + ['ir_5fsharp_2ecpp_478',['ir_Sharp.cpp',['../ir__Sharp_8cpp.html',1,'']]], + ['ir_5fsharp_2eh_479',['ir_Sharp.h',['../ir__Sharp_8h.html',1,'']]], + ['ir_5fsherwood_2ecpp_480',['ir_Sherwood.cpp',['../ir__Sherwood_8cpp.html',1,'']]], + ['ir_5fsony_2ecpp_481',['ir_Sony.cpp',['../ir__Sony_8cpp.html',1,'']]], + ['ir_5fsymphony_2ecpp_482',['ir_Symphony.cpp',['../ir__Symphony_8cpp.html',1,'']]], + ['ir_5ftcl_2ecpp_483',['ir_Tcl.cpp',['../ir__Tcl_8cpp.html',1,'']]], + ['ir_5ftcl_2eh_484',['ir_Tcl.h',['../ir__Tcl_8h.html',1,'']]], + ['ir_5fteco_2ecpp_485',['ir_Teco.cpp',['../ir__Teco_8cpp.html',1,'']]], + ['ir_5fteco_2eh_486',['ir_Teco.h',['../ir__Teco_8h.html',1,'']]], + ['ir_5ftoshiba_2ecpp_487',['ir_Toshiba.cpp',['../ir__Toshiba_8cpp.html',1,'']]], + ['ir_5ftoshiba_2eh_488',['ir_Toshiba.h',['../ir__Toshiba_8h.html',1,'']]], + ['ir_5ftrotec_2ecpp_489',['ir_Trotec.cpp',['../ir__Trotec_8cpp.html',1,'']]], + ['ir_5ftrotec_2eh_490',['ir_Trotec.h',['../ir__Trotec_8h.html',1,'']]], + ['ir_5fvestel_2ecpp_491',['ir_Vestel.cpp',['../ir__Vestel_8cpp.html',1,'']]], + ['ir_5fvestel_2eh_492',['ir_Vestel.h',['../ir__Vestel_8h.html',1,'']]], + ['ir_5fwhirlpool_2ecpp_493',['ir_Whirlpool.cpp',['../ir__Whirlpool_8cpp.html',1,'']]], + ['ir_5fwhirlpool_2eh_494',['ir_Whirlpool.h',['../ir__Whirlpool_8h.html',1,'']]], + ['ir_5fwhynter_2ecpp_495',['ir_Whynter.cpp',['../ir__Whynter_8cpp.html',1,'']]], + ['ir_5fzepeal_2ecpp_496',['ir_Zepeal.cpp',['../ir__Zepeal_8cpp.html',1,'']]], + ['irac_497',['IRac',['../classIRac.html',1,'IRac'],['../classIRac.html#abb0864e277d4f6c68a92c2729112a40d',1,'IRac::IRac()']]], + ['irac_2ecpp_498',['IRac.cpp',['../IRac_8cpp.html',1,'']]], + ['irac_2eh_499',['IRac.h',['../IRac_8h.html',1,'']]], + ['iracutils_500',['IRAcUtils',['../namespaceIRAcUtils.html',1,'']]], + ['iramcorac_501',['IRAmcorAc',['../classIRAmcorAc.html',1,'IRAmcorAc'],['../classIRAmcorAc.html#a92db59a33c861dcd3b2960e9711f97c4',1,'IRAmcorAc::IRAmcorAc()']]], + ['irargoac_502',['IRArgoAC',['../classIRArgoAC.html',1,'IRArgoAC'],['../classIRArgoAC.html#ad6c2250738397441b8f956d1477b7d70',1,'IRArgoAC::IRArgoAC()']]], + ['ircarrierac64_503',['IRCarrierAc64',['../classIRCarrierAc64.html',1,'IRCarrierAc64'],['../classIRCarrierAc64.html#ac225c0f24a0e385a145375ff447ab79b',1,'IRCarrierAc64::IRCarrierAc64()']]], + ['ircoolixac_504',['IRCoolixAC',['../classIRCoolixAC.html',1,'IRCoolixAC'],['../classIRCoolixAC.html#a043ad3b74e964e39b111e1fcf9e55f42',1,'IRCoolixAC::IRCoolixAC()']]], + ['ircoronaac_505',['IRCoronaAc',['../classIRCoronaAc.html',1,'IRCoronaAc'],['../classIRCoronaAc.html#aa96f1ffce21cdec5b3901ebbb1c63fbb',1,'IRCoronaAc::IRCoronaAc()']]], + ['irdaikin128_506',['IRDaikin128',['../classIRDaikin128.html',1,'IRDaikin128'],['../classIRDaikin128.html#aa669739541daf1a2b39ce1cd0424c43b',1,'IRDaikin128::IRDaikin128()']]], + ['irdaikin152_507',['IRDaikin152',['../classIRDaikin152.html',1,'IRDaikin152'],['../classIRDaikin152.html#a68dce79bab5890d9aea325a45ef8e4a3',1,'IRDaikin152::IRDaikin152()']]], + ['irdaikin160_508',['IRDaikin160',['../classIRDaikin160.html',1,'IRDaikin160'],['../classIRDaikin160.html#a76fb744b041c38abb730bce0538a497a',1,'IRDaikin160::IRDaikin160()']]], + ['irdaikin176_509',['IRDaikin176',['../classIRDaikin176.html',1,'IRDaikin176'],['../classIRDaikin176.html#accfe7c3f34351844d12059455f65f312',1,'IRDaikin176::IRDaikin176()']]], + ['irdaikin2_510',['IRDaikin2',['../classIRDaikin2.html',1,'IRDaikin2'],['../classIRDaikin2.html#a3ffe908313f162b92e92307578592fca',1,'IRDaikin2::IRDaikin2()']]], + ['irdaikin216_511',['IRDaikin216',['../classIRDaikin216.html',1,'IRDaikin216'],['../classIRDaikin216.html#ad802bde79e5ee2d16e3b09fbc8bbe8df',1,'IRDaikin216::IRDaikin216()']]], + ['irdaikin64_512',['IRDaikin64',['../classIRDaikin64.html',1,'IRDaikin64'],['../classIRDaikin64.html#a88855df33ce903884b21d2ef4771e94f',1,'IRDaikin64::IRDaikin64()']]], + ['irdaikinesp_513',['IRDaikinESP',['../classIRDaikinESP.html',1,'IRDaikinESP'],['../classIRDaikinESP.html#a2652cb45e07e8a4329c16cded9f6ad9a',1,'IRDaikinESP::IRDaikinESP()']]], + ['irdelonghiac_514',['IRDelonghiAc',['../classIRDelonghiAc.html',1,'IRDelonghiAc'],['../classIRDelonghiAc.html#aa6f8661cf6baa369a0a5b9d775c392e0',1,'IRDelonghiAc::IRDelonghiAc()']]], + ['irelectraac_515',['IRElectraAc',['../classIRElectraAc.html',1,'IRElectraAc'],['../classIRElectraAc.html#a2f56ad22943c3d261b1d2ef88d86e300',1,'IRElectraAc::IRElectraAc()']]], + ['irfujitsuac_516',['IRFujitsuAC',['../classIRFujitsuAC.html',1,'IRFujitsuAC'],['../classIRFujitsuAC.html#acdb70f239884507f540b872ba25747ce',1,'IRFujitsuAC::IRFujitsuAC()']]], + ['irgoodweatherac_517',['IRGoodweatherAc',['../classIRGoodweatherAc.html',1,'IRGoodweatherAc'],['../classIRGoodweatherAc.html#a681feff1a58125cde97b2d7ed0ba775e',1,'IRGoodweatherAc::IRGoodweatherAc()']]], + ['irgreeac_518',['IRGreeAC',['../classIRGreeAC.html',1,'IRGreeAC'],['../classIRGreeAC.html#abf7ead6ebee4bc776f83fb55f6fe6b63',1,'IRGreeAC::IRGreeAC()']]], + ['irhaierac_519',['IRHaierAC',['../classIRHaierAC.html',1,'IRHaierAC'],['../classIRHaierAC.html#a0b78060cbd150cd886a409adc2dea49c',1,'IRHaierAC::IRHaierAC()']]], + ['irhaieracyrw02_520',['IRHaierACYRW02',['../classIRHaierACYRW02.html',1,'IRHaierACYRW02'],['../classIRHaierACYRW02.html#afd9354c36df33434840bbc5f38d4e7ed',1,'IRHaierACYRW02::IRHaierACYRW02()']]], + ['irhitachiac_521',['IRHitachiAc',['../classIRHitachiAc.html',1,'IRHitachiAc'],['../classIRHitachiAc.html#a4c43e95e0cc28339e7162d7090ae16bf',1,'IRHitachiAc::IRHitachiAc()']]], + ['irhitachiac1_522',['IRHitachiAc1',['../classIRHitachiAc1.html',1,'IRHitachiAc1'],['../classIRHitachiAc1.html#ac00cfd9a60e08d34f292878de47f622f',1,'IRHitachiAc1::IRHitachiAc1()']]], + ['irhitachiac3_523',['IRHitachiAc3',['../classIRHitachiAc3.html',1,'IRHitachiAc3'],['../classIRHitachiAc3.html#adef0e7ad217f078ce418e3aa82b9cb86',1,'IRHitachiAc3::IRHitachiAc3()']]], + ['irhitachiac344_524',['IRHitachiAc344',['../classIRHitachiAc344.html',1,'IRHitachiAc344'],['../classIRHitachiAc424.html#a3c885313a79bf8c02bc5eb9f7d80088b',1,'IRHitachiAc424::IRHitachiAc344()'],['../classIRHitachiAc344.html#afbff8a1dd2777880d2d1713d07e1d419',1,'IRHitachiAc344::IRHitachiAc344()']]], + ['irhitachiac424_525',['IRHitachiAc424',['../classIRHitachiAc424.html',1,'IRHitachiAc424'],['../classIRHitachiAc424.html#add708c10a56d20621ef65a0ddcc2aac1',1,'IRHitachiAc424::IRHitachiAc424()']]], + ['irkelvinatorac_526',['IRKelvinatorAC',['../classIRKelvinatorAC.html',1,'IRKelvinatorAC'],['../classIRKelvinatorAC.html#a111dd384b1898a4fb880a19b6d1b1635',1,'IRKelvinatorAC::IRKelvinatorAC()']]], + ['irlgac_527',['IRLgAc',['../classIRLgAc.html',1,'IRLgAc'],['../classIRLgAc.html#a290636496526a9ed2057532649709375',1,'IRLgAc::IRLgAc()']]], + ['irmideaac_528',['IRMideaAC',['../classIRMideaAC.html',1,'IRMideaAC'],['../classIRMideaAC.html#a1ef2f532a1e6c6bfe89617d3fd0d9082',1,'IRMideaAC::IRMideaAC()']]], + ['irmitsubishi112_529',['IRMitsubishi112',['../classIRMitsubishi112.html',1,'IRMitsubishi112'],['../classIRMitsubishi112.html#adea6f3b7b7619b0bf6da4a94cec9d712',1,'IRMitsubishi112::IRMitsubishi112()']]], + ['irmitsubishi136_530',['IRMitsubishi136',['../classIRMitsubishi136.html',1,'IRMitsubishi136'],['../classIRMitsubishi136.html#ad92926b993869d0695f11ddb999b2090',1,'IRMitsubishi136::IRMitsubishi136()']]], + ['irmitsubishiac_531',['IRMitsubishiAC',['../classIRMitsubishiAC.html',1,'IRMitsubishiAC'],['../classIRMitsubishiAC.html#a83fabfd9ebed5cef8dd2a18a85fdf4e6',1,'IRMitsubishiAC::IRMitsubishiAC()']]], + ['irmitsubishiheavy152ac_532',['IRMitsubishiHeavy152Ac',['../classIRMitsubishiHeavy152Ac.html',1,'IRMitsubishiHeavy152Ac'],['../classIRMitsubishiHeavy152Ac.html#a704e9f96c2d0a07f9ba16a400d9c97aa',1,'IRMitsubishiHeavy152Ac::IRMitsubishiHeavy152Ac()']]], + ['irmitsubishiheavy88ac_533',['IRMitsubishiHeavy88Ac',['../classIRMitsubishiHeavy88Ac.html',1,'IRMitsubishiHeavy88Ac'],['../classIRMitsubishiHeavy88Ac.html#aceabecf4a615e807a4636ff5990d77d7',1,'IRMitsubishiHeavy88Ac::IRMitsubishiHeavy88Ac()']]], + ['irneoclimaac_534',['IRNeoclimaAc',['../classIRNeoclimaAc.html',1,'IRNeoclimaAc'],['../classIRNeoclimaAc.html#a99ed2962176e5f12f8387fab977c6395',1,'IRNeoclimaAc::IRNeoclimaAc()']]], + ['irpanasonicac_535',['IRPanasonicAc',['../classIRPanasonicAc.html',1,'IRPanasonicAc'],['../classIRPanasonicAc.html#ae8b0f4518ee1a913d47a7101b0a11185',1,'IRPanasonicAc::IRPanasonicAc()']]], + ['irparams_536',['irparams',['../IRrecv_8cpp.html#a5620be27a7445f25d43dbe3432ed6fd1',1,'IRrecv.cpp']]], + ['irparams_5fsave_537',['irparams_save',['../classIRrecv.html#a6fdac84ce51ce119972bf121ccc95aab',1,'IRrecv::irparams_save()'],['../IRrecv_8cpp.html#a96e84ae171529ee954c53e2e938dd998',1,'irparams_save(): IRrecv.cpp']]], + ['irparams_5ft_538',['irparams_t',['../structirparams__t.html',1,'']]], + ['irpin_539',['IRpin',['../classIRsend.html#ae4a6ea1e72f4861167002d6e7bf17b7c',1,'IRsend']]], + ['irrecv_540',['IRrecv',['../classIRrecv.html',1,'IRrecv'],['../classIRrecv.html#a8fe4d26ef1f863db1db9994fed5fc209',1,'IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)'],['../classIRrecv.html#a3bb1bcc1c1a3184294dd35c8f6f758b1',1,'IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false)']]], + ['irrecv_2ecpp_541',['IRrecv.cpp',['../IRrecv_8cpp.html',1,'']]], + ['irrecv_2eh_542',['IRrecv.h',['../IRrecv_8h.html',1,'']]], + ['irremote_5fmux_543',['irremote_mux',['../IRrecv_8cpp.html#ad2612f65707186ef7df0179d3636b4ea',1,'IRrecv.cpp']]], + ['irremoteesp8266_2eh_544',['IRremoteESP8266.h',['../IRremoteESP8266_8h.html',1,'']]], + ['irsamsungac_545',['IRSamsungAc',['../classIRSamsungAc.html',1,'IRSamsungAc'],['../classIRSamsungAc.html#a0db771b80d7d7a63b5ecb4b25efee609',1,'IRSamsungAc::IRSamsungAc()']]], + ['irsend_546',['IRsend',['../classIRsend.html',1,'IRsend'],['../classIRsend.html#a792780b7de996c90c86dd7b700eaf271',1,'IRsend::IRsend()']]], + ['irsend_2ecpp_547',['IRsend.cpp',['../IRsend_8cpp.html',1,'']]], + ['irsend_2eh_548',['IRsend.h',['../IRsend_8h.html',1,'']]], + ['irsharpac_549',['IRSharpAc',['../classIRSharpAc.html',1,'IRSharpAc'],['../classIRSharpAc.html#a30b5f8f634a41c943b4e1453d12bc980',1,'IRSharpAc::IRSharpAc()']]], + ['irtcl112ac_550',['IRTcl112Ac',['../classIRTcl112Ac.html',1,'IRTcl112Ac'],['../classIRTcl112Ac.html#a061bdfdf4444cb5e06fa90824985c1ec',1,'IRTcl112Ac::IRTcl112Ac()']]], + ['irtecoac_551',['IRTecoAc',['../classIRTecoAc.html',1,'IRTecoAc'],['../classIRTecoAc.html#a56e3f31a080bfd565570bf3b165e71d4',1,'IRTecoAc::IRTecoAc()']]], + ['irtext_2ecpp_552',['IRtext.cpp',['../IRtext_8cpp.html',1,'']]], + ['irtext_2eh_553',['IRtext.h',['../IRtext_8h.html',1,'']]], + ['irtimer_554',['IRtimer',['../classIRtimer.html',1,'IRtimer'],['../classIRtimer.html#a09d64d689137ef8ca68973bb9e550e76',1,'IRtimer::IRtimer()']]], + ['irtimer_2ecpp_555',['IRtimer.cpp',['../IRtimer_8cpp.html',1,'']]], + ['irtimer_2eh_556',['IRtimer.h',['../IRtimer_8h.html',1,'']]], + ['irtoshibaac_557',['IRToshibaAC',['../classIRToshibaAC.html',1,'IRToshibaAC'],['../classIRToshibaAC.html#abf2b3db316f7d6acb20c4f7ea2476ec2',1,'IRToshibaAC::IRToshibaAC()']]], + ['irtrotecesp_558',['IRTrotecESP',['../classIRTrotecESP.html',1,'IRTrotecESP'],['../classIRTrotecESP.html#a1b56b6e55bf133ccab6a482090408ee5',1,'IRTrotecESP::IRTrotecESP()']]], + ['irutils_559',['irutils',['../namespaceirutils.html',1,'']]], + ['irutils_2ecpp_560',['IRutils.cpp',['../IRutils_8cpp.html',1,'']]], + ['irutils_2eh_561',['IRutils.h',['../IRutils_8h.html',1,'']]], + ['irvestelac_562',['IRVestelAc',['../classIRVestelAc.html',1,'IRVestelAc'],['../classIRVestelAc.html#af1583ef81331edf112a0d04771c2cbec',1,'IRVestelAc::IRVestelAc()']]], + ['irwhirlpoolac_563',['IRWhirlpoolAc',['../classIRWhirlpoolAc.html',1,'IRWhirlpoolAc'],['../classIRWhirlpoolAc.html#a89bc9d440a5f7d04a602d7bc73904bc2',1,'IRWhirlpoolAc::IRWhirlpoolAc()']]], + ['isofftimeractive_564',['isOffTimerActive',['../classIRVestelAc.html#aa756171e82ed1b43593b81aa3a63b812',1,'IRVestelAc']]], + ['isofftimerenabled_565',['isOffTimerEnabled',['../classIRPanasonicAc.html#ac8e218b4886d66889734b01232767c8a',1,'IRPanasonicAc::isOffTimerEnabled()'],['../classIRWhirlpoolAc.html#a1bc1366524cf3c7fb426e908a166801f',1,'IRWhirlpoolAc::isOffTimerEnabled()']]], + ['isontimeractive_566',['isOnTimerActive',['../classIRVestelAc.html#a67f0e970af50fcf6e01e4cac85c5862a',1,'IRVestelAc']]], + ['isontimerenabled_567',['isOnTimerEnabled',['../classIRPanasonicAc.html#a04cbf8f5063a3892020d383c77abc57c',1,'IRPanasonicAc::isOnTimerEnabled()'],['../classIRWhirlpoolAc.html#aff1b8c2d063b376725a5a77745f6be3a',1,'IRWhirlpoolAc::isOnTimerEnabled()']]], + ['ispowerspecial_568',['isPowerSpecial',['../classIRSharpAc.html#a57072f2458897ffb9184769aca10b944',1,'IRSharpAc']]], + ['isprotocolsupported_569',['isProtocolSupported',['../classIRac.html#ad9c2fc9d07db70704f78a2d5f7be5b1c',1,'IRac']]], + ['isspecialstate_570',['isSpecialState',['../classIRCoolixAC.html#a51bde954328ca5887a8353ba5562b3db',1,'IRCoolixAC']]], + ['isswingvtoggle_571',['isSwingVToggle',['../classIRMideaAC.html#a848076f02a38a32c691a4617586862cc',1,'IRMideaAC']]], + ['istimecommand_572',['isTimeCommand',['../classIRVestelAc.html#ae811a07c1a8d82e7068c39b9ca73aaf1',1,'IRVestelAc']]], + ['istimeractive_573',['isTimerActive',['../classIRVestelAc.html#a160b73df8e1eda984f9bfbff3df7fa63',1,'IRVestelAc']]], + ['istimerenabled_574',['isTimerEnabled',['../classIRWhirlpoolAc.html#a5a713ffed99ab3450257d83e2d6e15ee',1,'IRWhirlpoolAc']]], + ['isvalidlgac_575',['isValidLgAc',['../classIRLgAc.html#a5984041eb12603ac1a277c28b355322a',1,'IRLgAc']]], + ['it_2dit_2eh_576',['it-IT.h',['../it-IT_8h.html',1,'']]], + ['internationalisation_20_28i18n_29_20_26_20locale_20files_577',['Internationalisation (I18N) & Locale Files',['../md_src_locale_README.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.html new file mode 100644 index 000000000..f2f3d3a38 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.js new file mode 100644 index 000000000..7ee51c41b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['jvc_578',['JVC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada5b6f507fb4bbd70ee70be4e2e0b0371d',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.html new file mode 100644 index 000000000..14f34036c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.js new file mode 100644 index 000000000..600985f6a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.js @@ -0,0 +1,2560 @@ +var searchData= +[ + ['k3dstr_579',['k3DStr',['../IRtext_8cpp.html#aedbfd5e861447c2cde9f7bb6aade1370',1,'k3DStr(): IRtext.cpp'],['../IRtext_8h.html#a084c940b7221cd1d85d4a3b58063051d',1,'k3DStr(): IRtext.cpp']]], + ['k6thsensestr_580',['k6thSenseStr',['../IRtext_8cpp.html#ad0bfc24932f22a599c7e7bf04fb57b10',1,'k6thSenseStr(): IRtext.cpp'],['../IRtext_8h.html#a7425119d393b134c4659db9d35691e35',1,'k6thSenseStr(): IRtext.cpp']]], + ['k8cheatstr_581',['k8CHeatStr',['../IRtext_8cpp.html#ac6ab822edcfe7768cd1a8b0426a1bd59',1,'k8CHeatStr(): IRtext.cpp'],['../IRtext_8h.html#acfcc1bc573f4520f3e37977a949b74e8',1,'k8CHeatStr(): IRtext.cpp']]], + ['kairflowstr_582',['kAirFlowStr',['../IRtext_8cpp.html#a7ecf1c6454bbf9963ca85a2bd7d4a34a',1,'kAirFlowStr(): IRtext.cpp'],['../IRtext_8h.html#a0f7e35a10e28e403da578c85b0e6b180',1,'kAirFlowStr(): IRtext.cpp']]], + ['kairwellbits_583',['kAirwellBits',['../IRremoteESP8266_8h.html#a570219a14f2d19c7a6ce0aecd37a3b1f',1,'IRremoteESP8266.h']]], + ['kairwellfootermark_584',['kAirwellFooterMark',['../ir__Airwell_8cpp.html#a2f41c6fe12eb5b3369ffb67fc6333431',1,'ir_Airwell.cpp']]], + ['kairwellhalfclockperiod_585',['kAirwellHalfClockPeriod',['../ir__Airwell_8cpp.html#a955f70631a1bc9be8453ccc9fbb3ecfc',1,'ir_Airwell.cpp']]], + ['kairwellhdrmark_586',['kAirwellHdrMark',['../ir__Airwell_8cpp.html#ad0c7b6c28df61b706eef2ec05506d8c2',1,'ir_Airwell.cpp']]], + ['kairwellhdrspace_587',['kAirwellHdrSpace',['../ir__Airwell_8cpp.html#ad7e80d679eaa5742f261619cc1115567',1,'ir_Airwell.cpp']]], + ['kairwellminrepeats_588',['kAirwellMinRepeats',['../IRremoteESP8266_8h.html#a669217ae5aa0baa159f7452f53551875',1,'IRremoteESP8266.h']]], + ['kairwelloverhead_589',['kAirwellOverhead',['../ir__Airwell_8cpp.html#a8365fb4b254f5eeb6fed59cdc627fead',1,'ir_Airwell.cpp']]], + ['kaiwarct501bits_590',['kAiwaRcT501Bits',['../IRremoteESP8266_8h.html#a9078adf040d21c9c3eb10ed69f9dced6',1,'IRremoteESP8266.h']]], + ['kaiwarct501minrepeats_591',['kAiwaRcT501MinRepeats',['../IRremoteESP8266_8h.html#ad796714d955b6cc8e207b03058eae5a3',1,'IRremoteESP8266.h']]], + ['kaiwarct501postbits_592',['kAiwaRcT501PostBits',['../ir__Aiwa_8cpp.html#a1ad2ad119febec79cb20bf2356ae4dd4',1,'ir_Aiwa.cpp']]], + ['kaiwarct501postdata_593',['kAiwaRcT501PostData',['../ir__Aiwa_8cpp.html#a5c8aa67edc9ceed9dc398f878930b1cb',1,'ir_Aiwa.cpp']]], + ['kaiwarct501prebits_594',['kAiwaRcT501PreBits',['../ir__Aiwa_8cpp.html#a614f30df204126f234ce1d256406f075',1,'ir_Aiwa.cpp']]], + ['kaiwarct501predata_595',['kAiwaRcT501PreData',['../ir__Aiwa_8cpp.html#a9aafbd2938553c9b97dac6f4e3edee6e',1,'ir_Aiwa.cpp']]], + ['kallprotocolnamesstr_596',['kAllProtocolNamesStr',['../IRtext_8cpp.html#a3ef36cf85e44181ecc4d11085b7abed6',1,'kAllProtocolNamesStr(): IRtext.cpp'],['../IRtext_8h.html#aa0dfe94cd4cba3bec642328f399dc775',1,'kAllProtocolNamesStr(): IRtext.cpp']]], + ['kalokabits_597',['kAlokaBits',['../IRremoteESP8266_8h.html#a864918ca63a5fe7345688a72d61ddf23',1,'IRremoteESP8266.h']]], + ['kalokaledblue_598',['kAlokaLedBlue',['../ir__NEC_8h.html#a49908cff59d8e7a4926638c74b796c61',1,'ir_NEC.h']]], + ['kalokaledgreen_599',['kAlokaLedGreen',['../ir__NEC_8h.html#aa6c6afc878f4b2a8d4b9349bf6766fb6',1,'ir_NEC.h']]], + ['kalokaledlightgreen_600',['kAlokaLedLightGreen',['../ir__NEC_8h.html#ab2daa6b17fd2d5e30fc47105e4c3c6b6',1,'ir_NEC.h']]], + ['kalokaledmidblue_601',['kAlokaLedMidBlue',['../ir__NEC_8h.html#a47d88027186cd96216bea935ca93d7bc',1,'ir_NEC.h']]], + ['kalokaledorange_602',['kAlokaLedOrange',['../ir__NEC_8h.html#a40f8ae5d6ec8f6aa887c73f032ce03bb',1,'ir_NEC.h']]], + ['kalokaledpink_603',['kAlokaLedPink',['../ir__NEC_8h.html#a53cf14e43062b82259e8d171a992ceff',1,'ir_NEC.h']]], + ['kalokaledpinkred_604',['kAlokaLedPinkRed',['../ir__NEC_8h.html#a20ef8a4a844577849b4b3bc7a86fe352',1,'ir_NEC.h']]], + ['kalokaledrainbow_605',['kAlokaLedRainbow',['../ir__NEC_8h.html#a724ce8d8c71c07a019ed2ddfba269151',1,'ir_NEC.h']]], + ['kalokaledred_606',['kAlokaLedRed',['../ir__NEC_8h.html#ade8f47e4607be919ca05b6dd6ed23ae9',1,'ir_NEC.h']]], + ['kalokaledtreegrow_607',['kAlokaLedTreeGrow',['../ir__NEC_8h.html#a5ecb76db25229f9f05044e54239144ee',1,'ir_NEC.h']]], + ['kalokaledwhite_608',['kAlokaLedWhite',['../ir__NEC_8h.html#a0c0b35e9d905de0b299e38e5807f363e',1,'ir_NEC.h']]], + ['kalokaledyellow_609',['kAlokaLedYellow',['../ir__NEC_8h.html#a1853a0e8856b8af97f458a180c41d6d5',1,'ir_NEC.h']]], + ['kalokanightfade_610',['kAlokaNightFade',['../ir__NEC_8h.html#adb8489faf42032a38187759b5f1037a1',1,'ir_NEC.h']]], + ['kalokanighttimer_611',['kAlokaNightTimer',['../ir__NEC_8h.html#a1b48b8bbd71fbe3728487f36123f4e4b',1,'ir_NEC.h']]], + ['kalokapower_612',['kAlokaPower',['../ir__NEC_8h.html#a147ecbccf8f11976f65b3f374b6ab2d0',1,'ir_NEC.h']]], + ['kamcorauto_613',['kAmcorAuto',['../ir__Amcor_8h.html#a9c02a27d5ed80963ff3b1ff32fc261c5',1,'ir_Amcor.h']]], + ['kamcorbits_614',['kAmcorBits',['../IRremoteESP8266_8h.html#a34bcab75a8ab94adfd46a245dd0748db',1,'IRremoteESP8266.h']]], + ['kamcorchecksumbyte_615',['kAmcorChecksumByte',['../ir__Amcor_8h.html#a6c60b38dd5b08d5787e346a55dfe0111',1,'ir_Amcor.h']]], + ['kamcorcool_616',['kAmcorCool',['../ir__Amcor_8h.html#a221c452a3323bd4d39a6084f84ecefbd',1,'ir_Amcor.h']]], + ['kamcordefaultrepeat_617',['kAmcorDefaultRepeat',['../IRremoteESP8266_8h.html#a746e1ce73c2ebd9bd1f5300494820a0c',1,'IRremoteESP8266.h']]], + ['kamcordry_618',['kAmcorDry',['../ir__Amcor_8h.html#a4d285053d14cf85d0c17e738c53538cd',1,'ir_Amcor.h']]], + ['kamcorfan_619',['kAmcorFan',['../ir__Amcor_8h.html#a5fa0c6e3a73c94fc419ff8d1aa1423c2',1,'ir_Amcor.h']]], + ['kamcorfanauto_620',['kAmcorFanAuto',['../ir__Amcor_8h.html#a3199dbace6444ed6ca7ff2e55a8a3a24',1,'ir_Amcor.h']]], + ['kamcorfanmax_621',['kAmcorFanMax',['../ir__Amcor_8h.html#a08ea054d4121220ba758a0e0cacef8ca',1,'ir_Amcor.h']]], + ['kamcorfanmed_622',['kAmcorFanMed',['../ir__Amcor_8h.html#a9ef019a27cf0724ff1f1ff39e06c0c87',1,'ir_Amcor.h']]], + ['kamcorfanmin_623',['kAmcorFanMin',['../ir__Amcor_8h.html#a0276f72dc5b39557850838c8c70fd157',1,'ir_Amcor.h']]], + ['kamcorfanoffset_624',['kAmcorFanOffset',['../ir__Amcor_8h.html#aaa3beed08599db5e155b3b54a3fc60bd',1,'ir_Amcor.h']]], + ['kamcorfansize_625',['kAmcorFanSize',['../ir__Amcor_8h.html#a4a6d1ad01cd89d8064efdd29311948b7',1,'ir_Amcor.h']]], + ['kamcorfootermark_626',['kAmcorFooterMark',['../ir__Amcor_8cpp.html#a3f877b05b07810ff43712dd4412af4f5',1,'ir_Amcor.cpp']]], + ['kamcorgap_627',['kAmcorGap',['../ir__Amcor_8cpp.html#a090f83ec3d4f3fd10baa16bf512dca23',1,'ir_Amcor.cpp']]], + ['kamcorhdrmark_628',['kAmcorHdrMark',['../ir__Amcor_8cpp.html#ab528f545e9af4ffb0f13d5674cfd1589',1,'ir_Amcor.cpp']]], + ['kamcorhdrspace_629',['kAmcorHdrSpace',['../ir__Amcor_8cpp.html#ae0e00c60c4220d27ef7051b45f2ae8b5',1,'ir_Amcor.cpp']]], + ['kamcorheat_630',['kAmcorHeat',['../ir__Amcor_8h.html#a9467539574a0030d166fac79684216f8',1,'ir_Amcor.h']]], + ['kamcormax_631',['kAmcorMax',['../ir__Amcor_8h.html#afac44479dc50e3885e474d2cf8d1f878',1,'ir_Amcor.h']]], + ['kamcormaxoffset_632',['kAmcorMaxOffset',['../ir__Amcor_8h.html#a2740428d3e431ff7b04e85ec73009660',1,'ir_Amcor.h']]], + ['kamcormaxsize_633',['kAmcorMaxSize',['../ir__Amcor_8h.html#a01d5ae3a2abe48f35971ad5373230ff8',1,'ir_Amcor.h']]], + ['kamcormaxtemp_634',['kAmcorMaxTemp',['../ir__Amcor_8h.html#a6460abc4e2b44e4ef3f680c7e195c019',1,'ir_Amcor.h']]], + ['kamcormintemp_635',['kAmcorMinTemp',['../ir__Amcor_8h.html#a2d952bf3f43cb55253a89db1bcc0b568',1,'ir_Amcor.h']]], + ['kamcormodefanbyte_636',['kAmcorModeFanByte',['../ir__Amcor_8h.html#a077021dbba23d1727caf1fe037e5bd88',1,'ir_Amcor.h']]], + ['kamcormodeoffset_637',['kAmcorModeOffset',['../ir__Amcor_8h.html#a1aebade414c6d493d5fd1ae8d9b4f626',1,'ir_Amcor.h']]], + ['kamcormodesize_638',['kAmcorModeSize',['../ir__Amcor_8h.html#aa306915bcc7fcf7209584d84dc5d1aa4',1,'ir_Amcor.h']]], + ['kamcoronemark_639',['kAmcorOneMark',['../ir__Amcor_8cpp.html#a402a3643dc6b85813eb5f28d742c4e7f',1,'ir_Amcor.cpp']]], + ['kamcoronespace_640',['kAmcorOneSpace',['../ir__Amcor_8cpp.html#a51163573fdc7b8017c7311f0e4011b1b',1,'ir_Amcor.cpp']]], + ['kamcorpowerbyte_641',['kAmcorPowerByte',['../ir__Amcor_8h.html#a47e85c75d262d9091f27c7ddca141ab7',1,'ir_Amcor.h']]], + ['kamcorpoweroff_642',['kAmcorPowerOff',['../ir__Amcor_8h.html#aeccd11f34ca0a93f682ab6c144f07fb7',1,'ir_Amcor.h']]], + ['kamcorpoweroffset_643',['kAmcorPowerOffset',['../ir__Amcor_8h.html#aeebaa4acca33937e47df058885d3167f',1,'ir_Amcor.h']]], + ['kamcorpoweron_644',['kAmcorPowerOn',['../ir__Amcor_8h.html#adf21c2364e64c818ba5379e78cae9d5c',1,'ir_Amcor.h']]], + ['kamcorpowersize_645',['kAmcorPowerSize',['../ir__Amcor_8h.html#a6a4e3568f341a7a60bdf7a4dc56fd482',1,'ir_Amcor.h']]], + ['kamcorspecialbyte_646',['kAmcorSpecialByte',['../ir__Amcor_8h.html#aa73133f5a673eebd7e8ca99155138cb7',1,'ir_Amcor.h']]], + ['kamcorstatelength_647',['kAmcorStateLength',['../IRremoteESP8266_8h.html#a62866e6918602533d590912487150bc7',1,'IRremoteESP8266.h']]], + ['kamcortempbyte_648',['kAmcorTempByte',['../ir__Amcor_8h.html#a9d352d1da6a93fc990786662fb3698de',1,'ir_Amcor.h']]], + ['kamcortempoffset_649',['kAmcorTempOffset',['../ir__Amcor_8h.html#ae7113af741d2edfebf0fc4d4cc181b2d',1,'ir_Amcor.h']]], + ['kamcortempsize_650',['kAmcorTempSize',['../ir__Amcor_8h.html#a4c5fb23ff11e99a2b860553b145e33bb',1,'ir_Amcor.h']]], + ['kamcortolerance_651',['kAmcorTolerance',['../ir__Amcor_8cpp.html#ad7a4b72f06c5e71002a44c3e4d483bef',1,'ir_Amcor.cpp']]], + ['kamcorventoffset_652',['kAmcorVentOffset',['../ir__Amcor_8h.html#aa231f74cdba0fe6813c2d6c77268d300',1,'ir_Amcor.h']]], + ['kamcorventon_653',['kAmcorVentOn',['../ir__Amcor_8h.html#a0774a9180ab233da61c77c717be02521',1,'ir_Amcor.h']]], + ['kamcorventsize_654',['kAmcorVentSize',['../ir__Amcor_8h.html#a55cd6972c20ddc0fa24ee8f42b50e46f',1,'ir_Amcor.h']]], + ['kamcorzeromark_655',['kAmcorZeroMark',['../ir__Amcor_8cpp.html#a6f16bcf81087461a4e196a2c670f29ee',1,'ir_Amcor.cpp']]], + ['kamcorzerospace_656',['kAmcorZeroSpace',['../ir__Amcor_8cpp.html#a0cbb87d1a5bb594cf428c79cd96c8733',1,'ir_Amcor.cpp']]], + ['kargoauto_657',['kArgoAuto',['../ir__Argo_8h.html#a527fa5776cb58f88013de5062c620b12',1,'ir_Argo.h']]], + ['kargobitmark_658',['kArgoBitMark',['../ir__Argo_8cpp.html#aa15902c11e3a7d3cbb25504764b163c1',1,'ir_Argo.cpp']]], + ['kargobits_659',['kArgoBits',['../IRremoteESP8266_8h.html#a351efcd1805c87bd338de81dab3f8fb2',1,'IRremoteESP8266.h']]], + ['kargocool_660',['kArgoCool',['../ir__Argo_8h.html#ab331356887b5f8f04f5ffdf9031fde71',1,'ir_Argo.h']]], + ['kargodefaultrepeat_661',['kArgoDefaultRepeat',['../IRremoteESP8266_8h.html#a9a2190c526885753c676db666e48b764',1,'IRremoteESP8266.h']]], + ['kargodry_662',['kArgoDry',['../ir__Argo_8h.html#ae119706139f65f730db477d060a7bc5d',1,'ir_Argo.h']]], + ['kargofan1_663',['kArgoFan1',['../ir__Argo_8h.html#abfbde2676afb8b027a26a49d947a1396',1,'ir_Argo.h']]], + ['kargofan2_664',['kArgoFan2',['../ir__Argo_8h.html#a7b544220198b6aa311da78bc02b0e211',1,'ir_Argo.h']]], + ['kargofan3_665',['kArgoFan3',['../ir__Argo_8h.html#aa34af62e7134bbca2028d74ba7dfed4e',1,'ir_Argo.h']]], + ['kargofanauto_666',['kArgoFanAuto',['../ir__Argo_8h.html#a3b17c0ba868b439135e6e016452f1623',1,'ir_Argo.h']]], + ['kargofanoffset_667',['kArgoFanOffset',['../ir__Argo_8h.html#ab652e466dfce6bfabab04f70e23e6bc9',1,'ir_Argo.h']]], + ['kargofansize_668',['kArgoFanSize',['../ir__Argo_8h.html#a032348f63ce0e391120161f2547ab280',1,'ir_Argo.h']]], + ['kargoflap1_669',['kArgoFlap1',['../ir__Argo_8h.html#a477dac25a687b9d875cf9e94623d5e84',1,'ir_Argo.h']]], + ['kargoflap2_670',['kArgoFlap2',['../ir__Argo_8h.html#aa72401adcdd23c12d36f98370c605ef6',1,'ir_Argo.h']]], + ['kargoflap3_671',['kArgoFlap3',['../ir__Argo_8h.html#ab18e2931823d631b533c14f417ed4adb',1,'ir_Argo.h']]], + ['kargoflap4_672',['kArgoFlap4',['../ir__Argo_8h.html#a59204076030de56e1160fc599879b142',1,'ir_Argo.h']]], + ['kargoflap5_673',['kArgoFlap5',['../ir__Argo_8h.html#a5a3f4c1b1303b177a924c61dfdcce3e6',1,'ir_Argo.h']]], + ['kargoflap6_674',['kArgoFlap6',['../ir__Argo_8h.html#ac11d6b575b4abc7ac5aec9006ac41634',1,'ir_Argo.h']]], + ['kargoflapauto_675',['kArgoFlapAuto',['../ir__Argo_8h.html#af7f4a97011f94e4bf453e7cfd01fd780',1,'ir_Argo.h']]], + ['kargoflapfull_676',['kArgoFlapFull',['../ir__Argo_8h.html#a8befe8d8b6826fc79176b66eea8352b7',1,'ir_Argo.h']]], + ['kargogap_677',['kArgoGap',['../ir__Argo_8cpp.html#a1a28fc063dea8beacbaac39cf8e9b81b',1,'ir_Argo.cpp']]], + ['kargohdrmark_678',['kArgoHdrMark',['../ir__Argo_8cpp.html#a5c25d5a07e397fe86378021e7c3f2980',1,'ir_Argo.cpp']]], + ['kargohdrspace_679',['kArgoHdrSpace',['../ir__Argo_8cpp.html#a10e8a2ac55f8b123093cd92757d1603d',1,'ir_Argo.cpp']]], + ['kargoheat_680',['kArgoHeat',['../ir__Argo_8h.html#a431536a03ef985b53a4147df5a043b21',1,'ir_Argo.h']]], + ['kargoheatauto_681',['kArgoHeatAuto',['../ir__Argo_8h.html#a154f8b3e0d600d87b2822027bf0c6619',1,'ir_Argo.h']]], + ['kargoheatbit_682',['kArgoHeatBit',['../ir__Argo_8h.html#ada4b42336f3d423e3ef1060605c7f7f1',1,'ir_Argo.h']]], + ['kargoheatblink_683',['kArgoHeatBlink',['../ir__Argo_8h.html#ad29933c939f9364399dfa0f7eaa8cce6',1,'ir_Argo.h']]], + ['kargoifeelbitoffset_684',['kArgoIFeelBitOffset',['../ir__Argo_8h.html#a0dc059f228415b3cc7a22b50fff71e9c',1,'ir_Argo.h']]], + ['kargomaxbitoffset_685',['kArgoMaxBitOffset',['../ir__Argo_8h.html#af487de7857781edbe368a2ba724fc7c7',1,'ir_Argo.h']]], + ['kargomaxroomtemp_686',['kArgoMaxRoomTemp',['../ir__Argo_8h.html#a27427d4479dc126e8782985008d4dd7d',1,'ir_Argo.h']]], + ['kargomaxtemp_687',['kArgoMaxTemp',['../ir__Argo_8h.html#a2409d2f472fb950c070fa5c0a07f69ce',1,'ir_Argo.h']]], + ['kargomintemp_688',['kArgoMinTemp',['../ir__Argo_8h.html#a4bc4e4cfe12af43730cb128f4043ad11',1,'ir_Argo.h']]], + ['kargomodeoffset_689',['kArgoModeOffset',['../ir__Argo_8h.html#a127045d26371fa051310208b0a3d0316',1,'ir_Argo.h']]], + ['kargomodesize_690',['kArgoModeSize',['../ir__Argo_8h.html#a98e4d25798fb992200ade3dd5e53a401',1,'ir_Argo.h']]], + ['kargonightbitoffset_691',['kArgoNightBitOffset',['../ir__Argo_8h.html#a4d0f78fc9017ed0ff93c77794a411738',1,'ir_Argo.h']]], + ['kargooff_692',['kArgoOff',['../ir__Argo_8h.html#af3c6e4f7b18095179ea9e20e45e1890a',1,'ir_Argo.h']]], + ['kargoonespace_693',['kArgoOneSpace',['../ir__Argo_8cpp.html#a47131b446d160fed9c7af1886d3580e4',1,'ir_Argo.cpp']]], + ['kargopowerbitoffset_694',['kArgoPowerBitOffset',['../ir__Argo_8h.html#a26c8b660b323ac8a8f1bbf30d7f40bf7',1,'ir_Argo.h']]], + ['kargoroomtemphighoffset_695',['kArgoRoomTempHighOffset',['../ir__Argo_8h.html#abe1b434b09b0c42d0d7c90496d180aeb',1,'ir_Argo.h']]], + ['kargoroomtemphighsize_696',['kArgoRoomTempHighSize',['../ir__Argo_8h.html#a6fdcdd90f37c2f4572815b279379484d',1,'ir_Argo.h']]], + ['kargoroomtemplowoffset_697',['kArgoRoomTempLowOffset',['../ir__Argo_8h.html#a1272f85bf89b7f0326352ae7a05b2244',1,'ir_Argo.h']]], + ['kargoroomtemplowsize_698',['kArgoRoomTempLowSize',['../ir__Argo_8h.html#a2cd767383014feb1c6cdea45715e49c7',1,'ir_Argo.h']]], + ['kargostatelength_699',['kArgoStateLength',['../IRremoteESP8266_8h.html#a5f38a56eacd9964a8514cb57de287a45',1,'IRremoteESP8266.h']]], + ['kargotempdelta_700',['kArgoTempDelta',['../ir__Argo_8h.html#a7256560730a73dcaaa60cdfc8140fc0b',1,'ir_Argo.h']]], + ['kargotemphighoffset_701',['kArgoTempHighOffset',['../ir__Argo_8h.html#af06b47b51a4b837ee92a2e2774d214e3',1,'ir_Argo.h']]], + ['kargotemphighsize_702',['kArgoTempHighSize',['../ir__Argo_8h.html#af2b0c18a612c097f6356ff04ce9c78d0',1,'ir_Argo.h']]], + ['kargotemplowoffset_703',['kArgoTempLowOffset',['../ir__Argo_8h.html#a17137f6bec2d629cca04a859bb48dae8',1,'ir_Argo.h']]], + ['kargotemplowsize_704',['kArgoTempLowSize',['../ir__Argo_8h.html#aa50679112dc998ff06588d9a35ff313c',1,'ir_Argo.h']]], + ['kargozerospace_705',['kArgoZeroSpace',['../ir__Argo_8cpp.html#a5e06b6d522b35f503ca1e5db27f32ff6',1,'ir_Argo.cpp']]], + ['kauto_706',['kAuto',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444faa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()']]], + ['kautomaticstr_707',['kAutomaticStr',['../IRtext_8cpp.html#a66a32b6387a99572644e91f3299910a6',1,'kAutomaticStr(): IRtext.cpp'],['../IRtext_8h.html#a0fc9126a02b933a2af702cd6fdcb47ea',1,'kAutomaticStr(): IRtext.cpp']]], + ['kautostr_708',['kAutoStr',['../IRtext_8cpp.html#ae8ec328761b0218d0b18479a972b1121',1,'kAutoStr(): IRtext.cpp'],['../IRtext_8h.html#a15a085c4f9e89926d2c165de4b1755d9',1,'kAutoStr(): IRtext.cpp']]], + ['kbeepstr_709',['kBeepStr',['../IRtext_8cpp.html#a429f5c2f5aea162bd1568e8489aecb28',1,'kBeepStr(): IRtext.cpp'],['../IRtext_8h.html#a2e98c29968ade682d94f35e28364c878',1,'kBeepStr(): IRtext.cpp']]], + ['kbitsstr_710',['kBitsStr',['../IRtext_8cpp.html#aaabaca413c37bb6b18dc13daf5b335c1',1,'kBitsStr(): IRtext.cpp'],['../IRtext_8h.html#aaf3e1b0041b00b261dfd949b41569d94',1,'kBitsStr(): IRtext.cpp']]], + ['kbottomstr_711',['kBottomStr',['../IRtext_8cpp.html#ab0bd355efc13bd278a0e33765a783cd0',1,'kBottomStr(): IRtext.cpp'],['../IRtext_8h.html#accfb2322a40cfaf6707394e43f39e2a3',1,'kBottomStr(): IRtext.cpp']]], + ['kbreezestr_712',['kBreezeStr',['../IRtext_8cpp.html#ab0317e8cf720936fb02816e7827bea9e',1,'kBreezeStr(): IRtext.cpp'],['../IRtext_8h.html#af4f31b53c295a877507e3ef5a5fbbc9d',1,'kBreezeStr(): IRtext.cpp']]], + ['kbuttonstr_713',['kButtonStr',['../IRtext_8cpp.html#a6ee11e0a45632c54e34bed14c3a971ce',1,'kButtonStr(): IRtext.cpp'],['../IRtext_8h.html#a58bf62453a96d4e84bd1da3449b8799e',1,'kButtonStr(): IRtext.cpp']]], + ['kcancelstr_714',['kCancelStr',['../IRtext_8cpp.html#af79c3879bac5ca97947f16c3a6a03321',1,'kCancelStr(): IRtext.cpp'],['../IRtext_8h.html#ab64c4cdebbc72cbb62ae6cd9a449876b',1,'kCancelStr(): IRtext.cpp']]], + ['kcarrierac40bitmark_715',['kCarrierAc40BitMark',['../ir__Carrier_8cpp.html#a3f8996aa3a7b9b871bc6556f98efb345',1,'ir_Carrier.cpp']]], + ['kcarrierac40bits_716',['kCarrierAc40Bits',['../IRremoteESP8266_8h.html#a56d1176a7b3fe59aeb3f4f39926c617d',1,'IRremoteESP8266.h']]], + ['kcarrierac40gap_717',['kCarrierAc40Gap',['../ir__Carrier_8cpp.html#aa5f0d39a4e12645a6fb477efb3191384',1,'ir_Carrier.cpp']]], + ['kcarrierac40hdrmark_718',['kCarrierAc40HdrMark',['../ir__Carrier_8cpp.html#a4b77665ded6dab393779d2763bc367f0',1,'ir_Carrier.cpp']]], + ['kcarrierac40hdrspace_719',['kCarrierAc40HdrSpace',['../ir__Carrier_8cpp.html#a5ea98bc575a7ac8d7f5da937feeaeed4',1,'ir_Carrier.cpp']]], + ['kcarrierac40minrepeat_720',['kCarrierAc40MinRepeat',['../IRremoteESP8266_8h.html#a222aa743f398883a4910fbbb6d408bdc',1,'IRremoteESP8266.h']]], + ['kcarrierac40onespace_721',['kCarrierAc40OneSpace',['../ir__Carrier_8cpp.html#a79073c06820817e077c5bd8d9b8acfbd',1,'ir_Carrier.cpp']]], + ['kcarrierac40zerospace_722',['kCarrierAc40ZeroSpace',['../ir__Carrier_8cpp.html#a2ee9b60c12887983a6f4f123db6fd5e9',1,'ir_Carrier.cpp']]], + ['kcarrierac64bitmark_723',['kCarrierAc64BitMark',['../ir__Carrier_8cpp.html#ae32b2dab6a654fa293f54684da45c5c0',1,'ir_Carrier.cpp']]], + ['kcarrierac64bits_724',['kCarrierAc64Bits',['../IRremoteESP8266_8h.html#a41bc7ab7289e499ad33901da3eab661a',1,'IRremoteESP8266.h']]], + ['kcarrierac64checksumoffset_725',['kCarrierAc64ChecksumOffset',['../ir__Carrier_8h.html#a3aa65474b5be8c77d498b7e83d8b8f31',1,'ir_Carrier.h']]], + ['kcarrierac64checksumsize_726',['kCarrierAc64ChecksumSize',['../ir__Carrier_8h.html#a0b446c17c4965508f335e68c786f0596',1,'ir_Carrier.h']]], + ['kcarrierac64cool_727',['kCarrierAc64Cool',['../ir__Carrier_8h.html#aa75d5965da484d09f6f4c645cdb23869',1,'ir_Carrier.h']]], + ['kcarrierac64fan_728',['kCarrierAc64Fan',['../ir__Carrier_8h.html#a57655ceea762b18e0dd96724ddf888bd',1,'ir_Carrier.h']]], + ['kcarrierac64fanauto_729',['kCarrierAc64FanAuto',['../ir__Carrier_8h.html#a12d1fb295a0d9cf407040ab544acc245',1,'ir_Carrier.h']]], + ['kcarrierac64fanhigh_730',['kCarrierAc64FanHigh',['../ir__Carrier_8h.html#a099f2e82998bd78d25cec17a4be5f230',1,'ir_Carrier.h']]], + ['kcarrierac64fanlow_731',['kCarrierAc64FanLow',['../ir__Carrier_8h.html#aaeee61e5924bdc8028c4775f96ba14d2',1,'ir_Carrier.h']]], + ['kcarrierac64fanmedium_732',['kCarrierAc64FanMedium',['../ir__Carrier_8h.html#aeb8943f8d9f2bd95a9df6500eea7cba4',1,'ir_Carrier.h']]], + ['kcarrierac64fanoffset_733',['kCarrierAc64FanOffset',['../ir__Carrier_8h.html#abbd2da4887e1c313df40506c82cba836',1,'ir_Carrier.h']]], + ['kcarrierac64fansize_734',['kCarrierAc64FanSize',['../ir__Carrier_8h.html#aebcfb795028fea2d1b4bfde9a045e672',1,'ir_Carrier.h']]], + ['kcarrierac64gap_735',['kCarrierAc64Gap',['../ir__Carrier_8cpp.html#a6f7ba77f1350126d78a23d7ba967e258',1,'ir_Carrier.cpp']]], + ['kcarrierac64hdrmark_736',['kCarrierAc64HdrMark',['../ir__Carrier_8cpp.html#a19dc2108d4490c82c03c87c625bc5f31',1,'ir_Carrier.cpp']]], + ['kcarrierac64hdrspace_737',['kCarrierAc64HdrSpace',['../ir__Carrier_8cpp.html#ad73dbf55f5ffa03d92ec699b23e8ca8d',1,'ir_Carrier.cpp']]], + ['kcarrierac64heat_738',['kCarrierAc64Heat',['../ir__Carrier_8h.html#ac261ba8bff6f103bb9043c85a6f21d58',1,'ir_Carrier.h']]], + ['kcarrierac64maxtemp_739',['kCarrierAc64MaxTemp',['../ir__Carrier_8h.html#a5653bc180a4c849b5e0b33b957255ae4',1,'ir_Carrier.h']]], + ['kcarrierac64minrepeat_740',['kCarrierAc64MinRepeat',['../IRremoteESP8266_8h.html#a8b2b3670dc74ce9fbf3c8b511422a06c',1,'IRremoteESP8266.h']]], + ['kcarrierac64mintemp_741',['kCarrierAc64MinTemp',['../ir__Carrier_8h.html#a9e7a88bf52839ecb34da1966bb8a956b',1,'ir_Carrier.h']]], + ['kcarrierac64modeoffset_742',['kCarrierAc64ModeOffset',['../ir__Carrier_8h.html#a7f2ef38df606cb00f1c859914fc6f085',1,'ir_Carrier.h']]], + ['kcarrierac64modesize_743',['kCarrierAc64ModeSize',['../ir__Carrier_8h.html#a8d28dd57b7ad6b9f4bb2ba11fa4b63f7',1,'ir_Carrier.h']]], + ['kcarrierac64offtimerenableoffset_744',['kCarrierAc64OffTimerEnableOffset',['../ir__Carrier_8h.html#a1afcf0873e42c5cda5328bfe97d97ade',1,'ir_Carrier.h']]], + ['kcarrierac64offtimeroffset_745',['kCarrierAc64OffTimerOffset',['../ir__Carrier_8h.html#a0c9189a86abe1bc41f9db34e4ab77172',1,'ir_Carrier.h']]], + ['kcarrierac64onespace_746',['kCarrierAc64OneSpace',['../ir__Carrier_8cpp.html#a58ea051d56227a4037682f5d612b4cc7',1,'ir_Carrier.cpp']]], + ['kcarrierac64ontimerenableoffset_747',['kCarrierAc64OnTimerEnableOffset',['../ir__Carrier_8h.html#a8a03bb9d7ead5116dff0b81732300b40',1,'ir_Carrier.h']]], + ['kcarrierac64ontimeroffset_748',['kCarrierAc64OnTimerOffset',['../ir__Carrier_8h.html#ad2fd8df9a5114e0fc34a3657aac61f9c',1,'ir_Carrier.h']]], + ['kcarrierac64poweroffset_749',['kCarrierAc64PowerOffset',['../ir__Carrier_8h.html#a943b94e79e98237678b66f6f4a1b6af4',1,'ir_Carrier.h']]], + ['kcarrierac64sleepoffset_750',['kCarrierAc64SleepOffset',['../ir__Carrier_8h.html#a8ae023f5e44d5c29df41ab0f5cd534a0',1,'ir_Carrier.h']]], + ['kcarrierac64swingvoffset_751',['kCarrierAc64SwingVOffset',['../ir__Carrier_8h.html#a186dcc18acb75f98370d71f4640f02ce',1,'ir_Carrier.h']]], + ['kcarrierac64tempoffset_752',['kCarrierAc64TempOffset',['../ir__Carrier_8h.html#a3d3663b7e55cae59f1b8bba5ffbb5fad',1,'ir_Carrier.h']]], + ['kcarrierac64tempsize_753',['kCarrierAc64TempSize',['../ir__Carrier_8h.html#ae9e16d5ab69b493607ce84dfbded150f',1,'ir_Carrier.h']]], + ['kcarrierac64timermax_754',['kCarrierAc64TimerMax',['../ir__Carrier_8h.html#a78a34b51e51dc3b4129f350673c9fa96',1,'ir_Carrier.h']]], + ['kcarrierac64timermin_755',['kCarrierAc64TimerMin',['../ir__Carrier_8h.html#aeebac3e61246f2e148806d4b4e8ac13e',1,'ir_Carrier.h']]], + ['kcarrierac64timersize_756',['kCarrierAc64TimerSize',['../ir__Carrier_8h.html#adced87f4aed397ea8f2bb5ac2749dce5',1,'ir_Carrier.h']]], + ['kcarrierac64zerospace_757',['kCarrierAc64ZeroSpace',['../ir__Carrier_8cpp.html#af28d4332e0f1ad19aa743b993f44cdc7',1,'ir_Carrier.cpp']]], + ['kcarrieracbitmark_758',['kCarrierAcBitMark',['../ir__Carrier_8cpp.html#af4a608f81c745734499ec1842167940b',1,'ir_Carrier.cpp']]], + ['kcarrieracbits_759',['kCarrierAcBits',['../IRremoteESP8266_8h.html#a668d9ac84f7dae61c35534b842d4956b',1,'IRremoteESP8266.h']]], + ['kcarrieracfreq_760',['kCarrierAcFreq',['../ir__Carrier_8cpp.html#a795dc2d9b122bd3794fddbddef571058',1,'ir_Carrier.cpp']]], + ['kcarrieracgap_761',['kCarrierAcGap',['../ir__Carrier_8cpp.html#a00767c0b503a7fc8f0b2ddfac24a4f85',1,'ir_Carrier.cpp']]], + ['kcarrierachdrmark_762',['kCarrierAcHdrMark',['../ir__Carrier_8cpp.html#ad9a7754e77cfcfd6c6032d497bc4528d',1,'ir_Carrier.cpp']]], + ['kcarrierachdrspace_763',['kCarrierAcHdrSpace',['../ir__Carrier_8cpp.html#a8e09857e2fe15d6983ec0384c57140d4',1,'ir_Carrier.cpp']]], + ['kcarrieracminrepeat_764',['kCarrierAcMinRepeat',['../IRremoteESP8266_8h.html#a78c8a8b11179e8fd20bf09fa35f6b886',1,'IRremoteESP8266.h']]], + ['kcarrieraconespace_765',['kCarrierAcOneSpace',['../ir__Carrier_8cpp.html#ab04a214a7c2e0439384736c46ddc6c61',1,'ir_Carrier.cpp']]], + ['kcarrieraczerospace_766',['kCarrierAcZeroSpace',['../ir__Carrier_8cpp.html#a51c9c4bbd6e2927baac15dc60c1e60fa',1,'ir_Carrier.cpp']]], + ['kceilingstr_767',['kCeilingStr',['../IRtext_8cpp.html#a5258c9d80502d5a8e14bb324a394452b',1,'kCeilingStr(): IRtext.cpp'],['../IRtext_8h.html#aa47afe8f4c175954e9439c0c9e48c83e',1,'kCeilingStr(): IRtext.cpp']]], + ['kcelsiusstr_768',['kCelsiusStr',['../IRtext_8cpp.html#af0ad7ca76c659a17872960bcbcfbdbbf',1,'kCelsiusStr(): IRtext.cpp'],['../IRtext_8h.html#aae21484e9f049a7cfa507068abd3915e',1,'kCelsiusStr(): IRtext.cpp']]], + ['kcentrestr_769',['kCentreStr',['../IRtext_8cpp.html#a87a4151e0361c9f75d0d5c00f9bad1ee',1,'kCentreStr(): IRtext.cpp'],['../IRtext_8h.html#aab13bc11db65584fbb8a61c686d67228',1,'kCentreStr(): IRtext.cpp']]], + ['kchangestr_770',['kChangeStr',['../IRtext_8cpp.html#a1f6396eb9bd4327a7a2307e5724c1dd7',1,'kChangeStr(): IRtext.cpp'],['../IRtext_8h.html#a46e6bd06cfbf5f462042d7c720db01ae',1,'kChangeStr(): IRtext.cpp']]], + ['kcirculatestr_771',['kCirculateStr',['../IRtext_8cpp.html#a869ef1f579373ff4b5b61b1cba215680',1,'kCirculateStr(): IRtext.cpp'],['../IRtext_8h.html#a0ba8b339babc7f7f26dbab2399bcc578',1,'kCirculateStr(): IRtext.cpp']]], + ['kcleanstr_772',['kCleanStr',['../IRtext_8cpp.html#ad2d97c52e8df2704654fdbd0a7a0561e',1,'kCleanStr(): IRtext.cpp'],['../IRtext_8h.html#a45c17b23773e9dcded65a82577b00263',1,'kCleanStr(): IRtext.cpp']]], + ['kclockstr_773',['kClockStr',['../IRtext_8cpp.html#ad39bd469d5474159463543184cfae321',1,'kClockStr(): IRtext.cpp'],['../IRtext_8h.html#a6e4b8f591a1d3d399a559d41847b3fa8',1,'kClockStr(): IRtext.cpp']]], + ['kcodestr_774',['kCodeStr',['../IRtext_8cpp.html#a26e4bf74871ce457f42ec839545987f4',1,'kCodeStr(): IRtext.cpp'],['../IRtext_8h.html#a58a9da5cec40746dbe20455c6ef6c8fd',1,'kCodeStr(): IRtext.cpp']]], + ['kcolonspacestr_775',['kColonSpaceStr',['../IRtext_8cpp.html#a5d978c9ac25163a9629b7e8e2d37d25e',1,'kColonSpaceStr(): IRtext.cpp'],['../IRtext_8h.html#aab1b0d2ea5169c1e1d8eff4daef36512',1,'kColonSpaceStr(): IRtext.cpp']]], + ['kcomfortstr_776',['kComfortStr',['../IRtext_8cpp.html#aa7f0cfdb126ff7b0f8db6033bb51f36d',1,'kComfortStr(): IRtext.cpp'],['../IRtext_8h.html#a20037561545d4ba4cfe66c1e103ecde1',1,'kComfortStr(): IRtext.cpp']]], + ['kcommandstr_777',['kCommandStr',['../IRtext_8cpp.html#afd5865ea8c0f8565369dd2c4ee4622d6',1,'kCommandStr(): IRtext.cpp'],['../IRtext_8h.html#afdc9e8cc5c8c5c03749898d4f2d38606',1,'kCommandStr(): IRtext.cpp']]], + ['kcommaspacestr_778',['kCommaSpaceStr',['../IRtext_8cpp.html#ac8a9678d4c9eeee17a9dc28624c0ab49',1,'kCommaSpaceStr(): IRtext.cpp'],['../IRtext_8h.html#a48f5dfcf2e0f13f502980d42e879aec3',1,'kCommaSpaceStr(): IRtext.cpp']]], + ['kcool_779',['kCool',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fab9480fe865ab6bbfb66c8308068a06c2',1,'stdAc']]], + ['kcoolixauto_780',['kCoolixAuto',['../ir__Coolix_8h.html#a73c1ef7c2c80c861256a14a9f256b125',1,'ir_Coolix.h']]], + ['kcoolixbitmark_781',['kCoolixBitMark',['../ir__Coolix_8cpp.html#acd8562a27ec6c0a6c2cf9480082e04cd',1,'ir_Coolix.cpp']]], + ['kcoolixbitmarkticks_782',['kCoolixBitMarkTicks',['../ir__Coolix_8cpp.html#aefaa206b4316a4fd921f7171295d1232',1,'ir_Coolix.cpp']]], + ['kcoolixbits_783',['kCoolixBits',['../IRremoteESP8266_8h.html#aed48c68a637e4b45b80bbf4964ea79f9',1,'IRremoteESP8266.h']]], + ['kcoolixclean_784',['kCoolixClean',['../ir__Coolix_8h.html#a5cc9fcde4a6da54917b4d69bb352bc86',1,'ir_Coolix.h']]], + ['kcoolixcmdfan_785',['kCoolixCmdFan',['../ir__Coolix_8h.html#a7d5ff02f4a0c379322877b3dcf934c77',1,'ir_Coolix.h']]], + ['kcoolixcool_786',['kCoolixCool',['../ir__Coolix_8h.html#ae285ee4206fe45d25bb1d99b848c7e65',1,'ir_Coolix.h']]], + ['kcoolixdefaultrepeat_787',['kCoolixDefaultRepeat',['../IRremoteESP8266_8h.html#aa89410d369d71738c8cbefae6ac3b00f',1,'IRremoteESP8266.h']]], + ['kcoolixdefaultstate_788',['kCoolixDefaultState',['../ir__Coolix_8h.html#ad54ebf20658c33e5ad54fc54a513511e',1,'ir_Coolix.h']]], + ['kcoolixdry_789',['kCoolixDry',['../ir__Coolix_8h.html#a904c4135f61120e71577f6830adae689',1,'ir_Coolix.h']]], + ['kcoolixfan_790',['kCoolixFan',['../ir__Coolix_8h.html#a2e050321c994844f2ff6668ba6973ac4',1,'ir_Coolix.h']]], + ['kcoolixfanauto_791',['kCoolixFanAuto',['../ir__Coolix_8h.html#ac25d3c45ed7d7d30ff2ebf617d8265f0',1,'ir_Coolix.h']]], + ['kcoolixfanauto0_792',['kCoolixFanAuto0',['../ir__Coolix_8h.html#a38cccd1edee2c88c1b080f1d5600ead7',1,'ir_Coolix.h']]], + ['kcoolixfanfixed_793',['kCoolixFanFixed',['../ir__Coolix_8h.html#a37a3a23d8fe30df024cb844f82f90b2a',1,'ir_Coolix.h']]], + ['kcoolixfanmax_794',['kCoolixFanMax',['../ir__Coolix_8h.html#aabb349ee111467088b9a292950aba753',1,'ir_Coolix.h']]], + ['kcoolixfanmed_795',['kCoolixFanMed',['../ir__Coolix_8h.html#a2750626cda2e389df901b459805e09bd',1,'ir_Coolix.h']]], + ['kcoolixfanmin_796',['kCoolixFanMin',['../ir__Coolix_8h.html#a6c0086075cce1698c48cc30e045ab5bf',1,'ir_Coolix.h']]], + ['kcoolixfanoffset_797',['kCoolixFanOffset',['../ir__Coolix_8h.html#a1656f488974bd12db4049dfa8ff43a4e',1,'ir_Coolix.h']]], + ['kcoolixfansize_798',['kCoolixFanSize',['../ir__Coolix_8h.html#a5f4649b5b73766245bc82191cdc0e596',1,'ir_Coolix.h']]], + ['kcoolixfantempcode_799',['kCoolixFanTempCode',['../ir__Coolix_8h.html#a6d2d6f2fd8f5e9a4491623b9351efcba',1,'ir_Coolix.h']]], + ['kcoolixfanzonefollow_800',['kCoolixFanZoneFollow',['../ir__Coolix_8h.html#a5a71c6acd18b3198c7900e2de34c48a3',1,'ir_Coolix.h']]], + ['kcoolixhdrmark_801',['kCoolixHdrMark',['../ir__Coolix_8cpp.html#a746299797d958ccf116e6d1cdab3ad06',1,'ir_Coolix.cpp']]], + ['kcoolixhdrmarkticks_802',['kCoolixHdrMarkTicks',['../ir__Coolix_8cpp.html#a04d520a0fe3d773f377810174e5463a4',1,'ir_Coolix.cpp']]], + ['kcoolixhdrspace_803',['kCoolixHdrSpace',['../ir__Coolix_8cpp.html#ab7ff2a6bd99e0e6a0db3f14350cca84c',1,'ir_Coolix.cpp']]], + ['kcoolixhdrspaceticks_804',['kCoolixHdrSpaceTicks',['../ir__Coolix_8cpp.html#a58951e9800513b019ccb9f04ae55716f',1,'ir_Coolix.cpp']]], + ['kcoolixheat_805',['kCoolixHeat',['../ir__Coolix_8h.html#a234b39696f0b2fac6b37aa309082505e',1,'ir_Coolix.h']]], + ['kcoolixled_806',['kCoolixLed',['../ir__Coolix_8h.html#a68ae46e117caf0d7a3cc2ef9492495f1',1,'ir_Coolix.h']]], + ['kcoolixmingap_807',['kCoolixMinGap',['../ir__Coolix_8cpp.html#a46da2480f6850af899db74a4f2270cdc',1,'ir_Coolix.cpp']]], + ['kcoolixmingapticks_808',['kCoolixMinGapTicks',['../ir__Coolix_8cpp.html#a94f47fbf027fcb90664b302ff123f535',1,'ir_Coolix.cpp']]], + ['kcoolixmodeoffset_809',['kCoolixModeOffset',['../ir__Coolix_8h.html#acd17067177e1cc6776b7932afd9fbdb2',1,'ir_Coolix.h']]], + ['kcoolixmodesize_810',['kCoolixModeSize',['../ir__Coolix_8h.html#a69e5ee4c5eb95ca3346d9d9186a688a8',1,'ir_Coolix.h']]], + ['kcoolixoff_811',['kCoolixOff',['../ir__Coolix_8h.html#aef6f59b83a14b8505f395b2eb8d8ad39',1,'ir_Coolix.h']]], + ['kcoolixonespace_812',['kCoolixOneSpace',['../ir__Coolix_8cpp.html#a97a8439ace71584e36ab7306c3d53749',1,'ir_Coolix.cpp']]], + ['kcoolixonespaceticks_813',['kCoolixOneSpaceTicks',['../ir__Coolix_8cpp.html#a78770eaf597e4aa2ed539248ef10ec11',1,'ir_Coolix.cpp']]], + ['kcoolixprefix_814',['kCoolixPrefix',['../ir__Coolix_8h.html#a1b88ef6651189ba330d8e2847528964b',1,'ir_Coolix.h']]], + ['kcoolixsensortempignorecode_815',['kCoolixSensorTempIgnoreCode',['../ir__Coolix_8h.html#ae3aba531b0c0053424786ec4bb2be934',1,'ir_Coolix.h']]], + ['kcoolixsensortempmax_816',['kCoolixSensorTempMax',['../ir__Coolix_8h.html#a71641b1240ee439e77128165cedf899f',1,'ir_Coolix.h']]], + ['kcoolixsensortempmin_817',['kCoolixSensorTempMin',['../ir__Coolix_8h.html#a48f3f3ad79a53e0758270647db0b089c',1,'ir_Coolix.h']]], + ['kcoolixsensortempoffset_818',['kCoolixSensorTempOffset',['../ir__Coolix_8h.html#a03edec58ad078d7de7436929c463898a',1,'ir_Coolix.h']]], + ['kcoolixsensortempsize_819',['kCoolixSensorTempSize',['../ir__Coolix_8h.html#a979d1d4f84432afc29ac3fcc78353d6c',1,'ir_Coolix.h']]], + ['kcoolixsleep_820',['kCoolixSleep',['../ir__Coolix_8h.html#aa7f9f96e56bd3f6b814bc84b947b2417',1,'ir_Coolix.h']]], + ['kcoolixswing_821',['kCoolixSwing',['../ir__Coolix_8h.html#a799ad5ab7cf43f0aac3c342305f14b90',1,'ir_Coolix.h']]], + ['kcoolixswingh_822',['kCoolixSwingH',['../ir__Coolix_8h.html#a877bd2731dfc86d864e38a5ceb4ede6e',1,'ir_Coolix.h']]], + ['kcoolixswingv_823',['kCoolixSwingV',['../ir__Coolix_8h.html#ab9fcaf25426f1f9ad293e165f8c0bf38',1,'ir_Coolix.h']]], + ['kcoolixtempmap_824',['kCoolixTempMap',['../ir__Coolix_8h.html#a9c8931df1dbed38c8119f6605266c710',1,'ir_Coolix.h']]], + ['kcoolixtempmax_825',['kCoolixTempMax',['../ir__Coolix_8h.html#afbbb02bfeaaf5cb558ca28cdd5cfc4c3',1,'ir_Coolix.h']]], + ['kcoolixtempmin_826',['kCoolixTempMin',['../ir__Coolix_8h.html#accd37cf257fa5fbeb64e28f0d63888fb',1,'ir_Coolix.h']]], + ['kcoolixtempoffset_827',['kCoolixTempOffset',['../ir__Coolix_8h.html#ac49173b671af51026e378d65c7bc696b',1,'ir_Coolix.h']]], + ['kcoolixtemprange_828',['kCoolixTempRange',['../ir__Coolix_8h.html#a74e3e75466fd27672968d660e3fddc9a',1,'ir_Coolix.h']]], + ['kcoolixtempsize_829',['kCoolixTempSize',['../ir__Coolix_8h.html#a7a22c5c9bdd23ef80ffe9d6760c0650e',1,'ir_Coolix.h']]], + ['kcoolixtick_830',['kCoolixTick',['../ir__Coolix_8cpp.html#a61ddf842920e2b3e33fdb856bd911eae',1,'ir_Coolix.cpp']]], + ['kcoolixturbo_831',['kCoolixTurbo',['../ir__Coolix_8h.html#ade957b6f4a6cdb064c709972a5c31a4b',1,'ir_Coolix.h']]], + ['kcoolixunknown_832',['kCoolixUnknown',['../ir__Coolix_8h.html#a2913e31a9dc5b89cbcae940cd5d59497',1,'ir_Coolix.h']]], + ['kcoolixzerospace_833',['kCoolixZeroSpace',['../ir__Coolix_8cpp.html#a1a9ccf6b91e786f310ffe53d55cfd6d1',1,'ir_Coolix.cpp']]], + ['kcoolixzerospaceticks_834',['kCoolixZeroSpaceTicks',['../ir__Coolix_8cpp.html#af1a750cb3e1f142326cd177118c27136',1,'ir_Coolix.cpp']]], + ['kcoolixzonefollowmaskoffset_835',['kCoolixZoneFollowMaskOffset',['../ir__Coolix_8h.html#ae5da4da07b9d1bb715102cafd4a0105e',1,'ir_Coolix.h']]], + ['kcoolstr_836',['kCoolStr',['../IRtext_8cpp.html#a31258a2210b16dc977bcfd96938a8937',1,'kCoolStr(): IRtext.cpp'],['../IRtext_8h.html#ac25d86b97b8e53292dc8d0604ae263a3',1,'kCoolStr(): IRtext.cpp']]], + ['kcoronaacbitmark_837',['kCoronaAcBitMark',['../ir__Corona_8cpp.html#a1ecb863f625463289d34e210885238db',1,'ir_Corona.cpp']]], + ['kcoronaacbits_838',['kCoronaAcBits',['../IRremoteESP8266_8h.html#aaf59be616d7e3a5e605b8d1e08f20686',1,'IRremoteESP8266.h']]], + ['kcoronaacbitsshort_839',['kCoronaAcBitsShort',['../IRremoteESP8266_8h.html#a1191a9293b03aa14426083b6f411a4e3',1,'IRremoteESP8266.h']]], + ['kcoronaacfanauto_840',['kCoronaAcFanAuto',['../ir__Corona_8h.html#a8c97a0c674c000e4486159d628f1aa0a',1,'ir_Corona.h']]], + ['kcoronaacfanhigh_841',['kCoronaAcFanHigh',['../ir__Corona_8h.html#a4f58be196a744892402e287b12502dcb',1,'ir_Corona.h']]], + ['kcoronaacfanlow_842',['kCoronaAcFanLow',['../ir__Corona_8h.html#af9e5c729be856bf4b1bc10568f96c183',1,'ir_Corona.h']]], + ['kcoronaacfanmedium_843',['kCoronaAcFanMedium',['../ir__Corona_8h.html#a9d6b46c006bd6ea54a14b92a2d7a3dff',1,'ir_Corona.h']]], + ['kcoronaacfanoffset_844',['kCoronaAcFanOffset',['../ir__Corona_8h.html#ab9944dc3abdc09c4d616f43aaffccdec',1,'ir_Corona.h']]], + ['kcoronaacfansize_845',['kCoronaAcFanSize',['../ir__Corona_8h.html#a07463e8e2e7d2bf004142ec6b89c7851',1,'ir_Corona.h']]], + ['kcoronaacfreq_846',['kCoronaAcFreq',['../ir__Corona_8cpp.html#a0cb56860c88e9503743bcf94068bbf56',1,'ir_Corona.cpp']]], + ['kcoronaachdrmark_847',['kCoronaAcHdrMark',['../ir__Corona_8cpp.html#a697d84f13a1228dbae3cfb491124689a',1,'ir_Corona.cpp']]], + ['kcoronaachdrspace_848',['kCoronaAcHdrSpace',['../ir__Corona_8cpp.html#ad2425c406aa36c7752832d19f4a735f7',1,'ir_Corona.cpp']]], + ['kcoronaacmaxtemp_849',['kCoronaAcMaxTemp',['../ir__Corona_8h.html#aa6d199e5bb8382443da4e1f303dd7988',1,'ir_Corona.h']]], + ['kcoronaacmintemp_850',['kCoronaAcMinTemp',['../ir__Corona_8h.html#ae984b624da5e2d5ef1405e1b8d9424ba',1,'ir_Corona.h']]], + ['kcoronaacmodecool_851',['kCoronaAcModeCool',['../ir__Corona_8h.html#a6f8bb2e27990014686828b4b7e2c84c6',1,'ir_Corona.h']]], + ['kcoronaacmodedry_852',['kCoronaAcModeDry',['../ir__Corona_8h.html#afd47996b221103ae142363f04014fb4b',1,'ir_Corona.h']]], + ['kcoronaacmodefan_853',['kCoronaAcModeFan',['../ir__Corona_8h.html#ab8098af3e0f9cd82a7c9c771ffd8ad15',1,'ir_Corona.h']]], + ['kcoronaacmodeheat_854',['kCoronaAcModeHeat',['../ir__Corona_8h.html#a7f3c7c051ae3ee07621c47505a87bec1',1,'ir_Corona.h']]], + ['kcoronaacmodeoffset_855',['kCoronaAcModeOffset',['../ir__Corona_8h.html#aa4caa3638ad09dc3a223320651adbd49',1,'ir_Corona.h']]], + ['kcoronaacmodesize_856',['kCoronaAcModeSize',['../ir__Corona_8h.html#a38baa949868e16e67d7c2eb933b5019d',1,'ir_Corona.h']]], + ['kcoronaacofftimersection_857',['kCoronaAcOffTimerSection',['../ir__Corona_8h.html#ac2cfdbf9b3ed3d85c0e298c3de8f357b',1,'ir_Corona.h']]], + ['kcoronaaconespace_858',['kCoronaAcOneSpace',['../ir__Corona_8cpp.html#a6d9c199bdefbbb30b9561c5498c5a76e',1,'ir_Corona.cpp']]], + ['kcoronaacontimersection_859',['kCoronaAcOnTimerSection',['../ir__Corona_8h.html#a711b7b5bd2081ca9b1e7ab25573ff612',1,'ir_Corona.h']]], + ['kcoronaacoverhead_860',['kCoronaAcOverhead',['../ir__Corona_8cpp.html#aaef71b297a7868863a2ad7219bafabeb',1,'ir_Corona.cpp']]], + ['kcoronaacoverheadshort_861',['kCoronaAcOverheadShort',['../ir__Corona_8cpp.html#a56010f67a047f551db681bb0ec8c35f7',1,'ir_Corona.cpp']]], + ['kcoronaacpowerbuttonoffset_862',['kCoronaAcPowerButtonOffset',['../ir__Corona_8h.html#a71b6c16b1b5cffbd1991fea675e5a65e',1,'ir_Corona.h']]], + ['kcoronaacpoweroffset_863',['kCoronaAcPowerOffset',['../ir__Corona_8h.html#ac2258a233d0f1ef3207fdd5abd8c855d',1,'ir_Corona.h']]], + ['kcoronaacpowersaveoffset_864',['kCoronaAcPowerSaveOffset',['../ir__Corona_8h.html#a3bd4f3e2a1001aede28c886e7bbe42ae',1,'ir_Corona.h']]], + ['kcoronaacsectionbytes_865',['kCoronaAcSectionBytes',['../ir__Corona_8h.html#a094063159064053dd5e5059eb0d90f7c',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0base_866',['kCoronaAcSectionData0Base',['../ir__Corona_8h.html#a2d0b1f5a0839839a17947bde624d4c74',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0invpos_867',['kCoronaAcSectionData0InvPos',['../ir__Corona_8h.html#a1a16967cb9024658763c7e6b6b5f8dd3',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0pos_868',['kCoronaAcSectionData0Pos',['../ir__Corona_8h.html#a285f66040fa3db6c9955a97ef6eee4b7',1,'ir_Corona.h']]], + ['kcoronaacsectiondata1invpos_869',['kCoronaAcSectionData1InvPos',['../ir__Corona_8h.html#ad32635d2264331f4ee128e990411a704',1,'ir_Corona.h']]], + ['kcoronaacsectiondata1pos_870',['kCoronaAcSectionData1Pos',['../ir__Corona_8h.html#a1b10ed7cf1c43a3a8be6de6d3cfc12af',1,'ir_Corona.h']]], + ['kcoronaacsectionheader0_871',['kCoronaAcSectionHeader0',['../ir__Corona_8h.html#a39a2c0d214a10f8f9685e9955c0be0a4',1,'ir_Corona.h']]], + ['kcoronaacsectionheader0pos_872',['kCoronaAcSectionHeader0Pos',['../ir__Corona_8h.html#a8641d0234280b8cc3bb255abebea6540',1,'ir_Corona.h']]], + ['kcoronaacsectionheader1_873',['kCoronaAcSectionHeader1',['../ir__Corona_8h.html#a8a661569fc7b97ba2e9e755b944162f8',1,'ir_Corona.h']]], + ['kcoronaacsectionheader1pos_874',['kCoronaAcSectionHeader1Pos',['../ir__Corona_8h.html#adaadcbe7d57b048250f32b44a96d3853',1,'ir_Corona.h']]], + ['kcoronaacsectionlabelbase_875',['kCoronaAcSectionLabelBase',['../ir__Corona_8h.html#a6ff8a3461b87df048878faf49c12d064',1,'ir_Corona.h']]], + ['kcoronaacsectionlabelpos_876',['kCoronaAcSectionLabelPos',['../ir__Corona_8h.html#a5c68109fb92da47236c4100c2db28e2c',1,'ir_Corona.h']]], + ['kcoronaacsections_877',['kCoronaAcSections',['../ir__Corona_8h.html#a37e6cc5e2e186b2f5c5c938496ece111',1,'ir_Corona.h']]], + ['kcoronaacsettingssection_878',['kCoronaAcSettingsSection',['../ir__Corona_8h.html#a5a83a045fd9878eae073f25e6c5b4753',1,'ir_Corona.h']]], + ['kcoronaacspacegap_879',['kCoronaAcSpaceGap',['../ir__Corona_8cpp.html#a50f46039059d2a427bc9bc93c53df4fd',1,'ir_Corona.cpp']]], + ['kcoronaacstatelength_880',['kCoronaAcStateLength',['../IRremoteESP8266_8h.html#ab18df94a82b365ff30caaabb05a9fcaf',1,'IRremoteESP8266.h']]], + ['kcoronaacstatelengthshort_881',['kCoronaAcStateLengthShort',['../IRremoteESP8266_8h.html#a32b65ada4941a9622fbbc60f01b82425',1,'IRremoteESP8266.h']]], + ['kcoronaacswingvtoggleoffset_882',['kCoronaAcSwingVToggleOffset',['../ir__Corona_8h.html#a1475a44b94a8cfe83fb48b3c3d98e148',1,'ir_Corona.h']]], + ['kcoronaactempoffset_883',['kCoronaAcTempOffset',['../ir__Corona_8h.html#ae31731c985397a9a8b66ab933deccd7c',1,'ir_Corona.h']]], + ['kcoronaactempsize_884',['kCoronaAcTempSize',['../ir__Corona_8h.html#a69dac2ce8e51b8e1890c8b7844eab9dd',1,'ir_Corona.h']]], + ['kcoronaactimermax_885',['kCoronaAcTimerMax',['../ir__Corona_8h.html#af0428879b0fd39def7ea41e2906d9127',1,'ir_Corona.h']]], + ['kcoronaactimeroff_886',['kCoronaAcTimerOff',['../ir__Corona_8h.html#af0feaf445fae561c3fa18ec68a19edef',1,'ir_Corona.h']]], + ['kcoronaactimerunitspermin_887',['kCoronaAcTimerUnitsPerMin',['../ir__Corona_8h.html#a7f76e80480abdbdcdaf39186901950a4',1,'ir_Corona.h']]], + ['kcoronaaczerospace_888',['kCoronaAcZeroSpace',['../ir__Corona_8cpp.html#af64bbcaf63ca9d06089de382354eb2d9',1,'ir_Corona.cpp']]], + ['kcoronatolerance_889',['kCoronaTolerance',['../ir__Corona_8cpp.html#aad3726c95bfd7a9f79ba1e0c7058bb7b',1,'ir_Corona.cpp']]], + ['kdaikin128auto_890',['kDaikin128Auto',['../ir__Daikin_8h.html#a1d2a0f9db8e1be93bff12ec23ba212e0',1,'ir_Daikin.h']]], + ['kdaikin128bitceiling_891',['kDaikin128BitCeiling',['../ir__Daikin_8h.html#a0e1d1c1e7544eb455187290dbe4a1520',1,'ir_Daikin.h']]], + ['kdaikin128bitecono_892',['kDaikin128BitEcono',['../ir__Daikin_8h.html#a34add42c4df4db799ddf52e8e5587dee',1,'ir_Daikin.h']]], + ['kdaikin128biteconooffset_893',['kDaikin128BitEconoOffset',['../ir__Daikin_8h.html#af822203d873d9b847c3a7b08d236f82b',1,'ir_Daikin.h']]], + ['kdaikin128bithalfhour_894',['kDaikin128BitHalfHour',['../ir__Daikin_8h.html#abf955f8f24fd37bbe21222ca160b3299',1,'ir_Daikin.h']]], + ['kdaikin128bitmark_895',['kDaikin128BitMark',['../ir__Daikin_8h.html#a5178ac70eb4e134597e504d373d52fcd',1,'ir_Daikin.h']]], + ['kdaikin128bitpowertoggle_896',['kDaikin128BitPowerToggle',['../ir__Daikin_8h.html#a813506d8d3f8b6933379bcfc097e4b29',1,'ir_Daikin.h']]], + ['kdaikin128bitpowertoggleoffset_897',['kDaikin128BitPowerToggleOffset',['../ir__Daikin_8h.html#a05e33573c5050b1e54721a1716d652b5',1,'ir_Daikin.h']]], + ['kdaikin128bits_898',['kDaikin128Bits',['../IRremoteESP8266_8h.html#a5bb2e6f8acbc0123de5ac0fd76e1646a',1,'IRremoteESP8266.h']]], + ['kdaikin128bitsleep_899',['kDaikin128BitSleep',['../ir__Daikin_8h.html#a0cb96f1803fab5bfac8ef79a311308de',1,'ir_Daikin.h']]], + ['kdaikin128bitsleepoffset_900',['kDaikin128BitSleepOffset',['../ir__Daikin_8h.html#a7b4aa1ef19f1c23ef74b45eb90734c6f',1,'ir_Daikin.h']]], + ['kdaikin128bitswing_901',['kDaikin128BitSwing',['../ir__Daikin_8h.html#a8f6ab5b7f9871f08364abf3337ae48b4',1,'ir_Daikin.h']]], + ['kdaikin128bitswingoffset_902',['kDaikin128BitSwingOffset',['../ir__Daikin_8h.html#a7f98cf3863ab58b147dc31c497bc07bc',1,'ir_Daikin.h']]], + ['kdaikin128bittimerenabled_903',['kDaikin128BitTimerEnabled',['../ir__Daikin_8h.html#a1197dadb35f318b000ff6ee7ad3ca8b0',1,'ir_Daikin.h']]], + ['kdaikin128bittimerenabledoffset_904',['kDaikin128BitTimerEnabledOffset',['../ir__Daikin_8h.html#af913ee51e5b90ad12f87dbed9ce349d6',1,'ir_Daikin.h']]], + ['kdaikin128bitwall_905',['kDaikin128BitWall',['../ir__Daikin_8h.html#a842b3b696f95c5515ee4180626d78973',1,'ir_Daikin.h']]], + ['kdaikin128byteclockhours_906',['kDaikin128ByteClockHours',['../ir__Daikin_8h.html#a0d705309d30881fd2fe806e5bf8ae27d',1,'ir_Daikin.h']]], + ['kdaikin128byteclockmins_907',['kDaikin128ByteClockMins',['../ir__Daikin_8h.html#ab8c9af42d68548e1e711a0b38976342b',1,'ir_Daikin.h']]], + ['kdaikin128byteeconolight_908',['kDaikin128ByteEconoLight',['../ir__Daikin_8h.html#a75a3c1f1790006f0005666a023218c79',1,'ir_Daikin.h']]], + ['kdaikin128bytemodefan_909',['kDaikin128ByteModeFan',['../ir__Daikin_8h.html#a8433ab362f79a6bb3570d310a05f1141',1,'ir_Daikin.h']]], + ['kdaikin128byteofftimer_910',['kDaikin128ByteOffTimer',['../ir__Daikin_8h.html#a66e243db1131f58d0840980ca64c0282',1,'ir_Daikin.h']]], + ['kdaikin128byteontimer_911',['kDaikin128ByteOnTimer',['../ir__Daikin_8h.html#af27f1f25a52dc4c182111acd2abc554d',1,'ir_Daikin.h']]], + ['kdaikin128bytepowerswingsleep_912',['kDaikin128BytePowerSwingSleep',['../ir__Daikin_8h.html#a0f5a9f1ac68c516744220ad230805c15',1,'ir_Daikin.h']]], + ['kdaikin128bytetemp_913',['kDaikin128ByteTemp',['../ir__Daikin_8h.html#a4d3d5683aaee8e76138750a0f6ff1465',1,'ir_Daikin.h']]], + ['kdaikin128cool_914',['kDaikin128Cool',['../ir__Daikin_8h.html#a24ee5ffe877d7caa964256e5723af7e1',1,'ir_Daikin.h']]], + ['kdaikin128defaultrepeat_915',['kDaikin128DefaultRepeat',['../IRremoteESP8266_8h.html#a5c116cb58be005468de125f6ee651ccb',1,'IRremoteESP8266.h']]], + ['kdaikin128dry_916',['kDaikin128Dry',['../ir__Daikin_8h.html#ac4da761bf3b0ce12e6513a2718b3a907',1,'ir_Daikin.h']]], + ['kdaikin128fan_917',['kDaikin128Fan',['../ir__Daikin_8h.html#ac1c41d54f27d1653181ac69384f1130f',1,'ir_Daikin.h']]], + ['kdaikin128fanauto_918',['kDaikin128FanAuto',['../ir__Daikin_8h.html#aec2fe4618978c17e60a1ea8b1a89c263',1,'ir_Daikin.h']]], + ['kdaikin128fanhigh_919',['kDaikin128FanHigh',['../ir__Daikin_8h.html#a7ffd52eb15f6ffb5a0ffcddf39aa8f0d',1,'ir_Daikin.h']]], + ['kdaikin128fanlow_920',['kDaikin128FanLow',['../ir__Daikin_8h.html#a505c58ff23c5a551c6e2e356f66e9cc1',1,'ir_Daikin.h']]], + ['kdaikin128fanmed_921',['kDaikin128FanMed',['../ir__Daikin_8h.html#a4eb21add9bfb6774047a8a2c8b87ebbf',1,'ir_Daikin.h']]], + ['kdaikin128fanpowerful_922',['kDaikin128FanPowerful',['../ir__Daikin_8h.html#ae0899153669a6e8848556cd65c26c8b5',1,'ir_Daikin.h']]], + ['kdaikin128fanquiet_923',['kDaikin128FanQuiet',['../ir__Daikin_8h.html#a54777f468236bf4b342240e8c523308d',1,'ir_Daikin.h']]], + ['kdaikin128footermark_924',['kDaikin128FooterMark',['../ir__Daikin_8h.html#ad5668b12e38afa4b44a8e214dac22f2e',1,'ir_Daikin.h']]], + ['kdaikin128freq_925',['kDaikin128Freq',['../ir__Daikin_8h.html#a5a76fc08310d517cb7e182c287e77df1',1,'ir_Daikin.h']]], + ['kdaikin128gap_926',['kDaikin128Gap',['../ir__Daikin_8h.html#a6323c59eb5906ac2887a02f9cd09a329',1,'ir_Daikin.h']]], + ['kdaikin128halfhouroffset_927',['kDaikin128HalfHourOffset',['../ir__Daikin_8h.html#a8fddd8a5dbad2fd49445eaa2104f7da3',1,'ir_Daikin.h']]], + ['kdaikin128hdrmark_928',['kDaikin128HdrMark',['../ir__Daikin_8h.html#a6257375541b6e10bda4083d9529e80f0',1,'ir_Daikin.h']]], + ['kdaikin128hdrspace_929',['kDaikin128HdrSpace',['../ir__Daikin_8h.html#a114a4cef444d4c552b90701cb7debc73',1,'ir_Daikin.h']]], + ['kdaikin128heat_930',['kDaikin128Heat',['../ir__Daikin_8h.html#ada28db809b26e2ae9e927650d4cb4f7a',1,'ir_Daikin.h']]], + ['kdaikin128hoursoffset_931',['kDaikin128HoursOffset',['../ir__Daikin_8h.html#ace543fba33c68e3df4aa4d250ed1e792',1,'ir_Daikin.h']]], + ['kdaikin128hourssize_932',['kDaikin128HoursSize',['../ir__Daikin_8h.html#ac5441402c0ee486f3c752a91f09375ff',1,'ir_Daikin.h']]], + ['kdaikin128leadermark_933',['kDaikin128LeaderMark',['../ir__Daikin_8h.html#ab609b8979a2d2bf4fa5b7164590b2bfb',1,'ir_Daikin.h']]], + ['kdaikin128leaderspace_934',['kDaikin128LeaderSpace',['../ir__Daikin_8h.html#a259bfa510a9ec06049c0a7bf6563eb35',1,'ir_Daikin.h']]], + ['kdaikin128maskfan_935',['kDaikin128MaskFan',['../ir__Daikin_8h.html#ae58228f3b9eae0ec171527ced89e509f',1,'ir_Daikin.h']]], + ['kdaikin128masklight_936',['kDaikin128MaskLight',['../ir__Daikin_8h.html#a8d3d4325f91cbdd8ce0cec25fc0d2022',1,'ir_Daikin.h']]], + ['kdaikin128maxtemp_937',['kDaikin128MaxTemp',['../ir__Daikin_8h.html#a7dcd514d292ef98d70083227d046baad',1,'ir_Daikin.h']]], + ['kdaikin128mintemp_938',['kDaikin128MinTemp',['../ir__Daikin_8h.html#aad27f3ff311f1defc5ac9fb3be0ad504',1,'ir_Daikin.h']]], + ['kdaikin128modesize_939',['kDaikin128ModeSize',['../ir__Daikin_8h.html#a32a97adddfa791cc0e48d9bd847a3a4c',1,'ir_Daikin.h']]], + ['kdaikin128onespace_940',['kDaikin128OneSpace',['../ir__Daikin_8h.html#ac6a9a48ae0037b889a6619361fd090ac',1,'ir_Daikin.h']]], + ['kdaikin128sectionlength_941',['kDaikin128SectionLength',['../ir__Daikin_8h.html#a204a306e7d7071d4b798f7947c232520',1,'ir_Daikin.h']]], + ['kdaikin128sections_942',['kDaikin128Sections',['../ir__Daikin_8h.html#a81f0cfda4d8452d6053cc6999a270b1f',1,'ir_Daikin.h']]], + ['kdaikin128statelength_943',['kDaikin128StateLength',['../IRremoteESP8266_8h.html#a4279ccd14a3af2046e393661a7b4879f',1,'IRremoteESP8266.h']]], + ['kdaikin128timeroffset_944',['kDaikin128TimerOffset',['../ir__Daikin_8h.html#aabde7c45424ae82a812485e8ceb58dbd',1,'ir_Daikin.h']]], + ['kdaikin128timersize_945',['kDaikin128TimerSize',['../ir__Daikin_8h.html#a6f4022c5e4a092eb039c53ea72f51188',1,'ir_Daikin.h']]], + ['kdaikin128zerospace_946',['kDaikin128ZeroSpace',['../ir__Daikin_8h.html#a1ca69805ada8ec451199c18d9da6f02a',1,'ir_Daikin.h']]], + ['kdaikin152bitmark_947',['kDaikin152BitMark',['../ir__Daikin_8h.html#afd50318eaa383a7e85f0d0c2866bc9d5',1,'ir_Daikin.h']]], + ['kdaikin152bits_948',['kDaikin152Bits',['../IRremoteESP8266_8h.html#af056e1ac2d00c6d6440c3dd2ae283f09',1,'IRremoteESP8266.h']]], + ['kdaikin152comfortbyte_949',['kDaikin152ComfortByte',['../ir__Daikin_8h.html#a414b7acd5259122af5b496979fe068dc',1,'ir_Daikin.h']]], + ['kdaikin152comfortoffset_950',['kDaikin152ComfortOffset',['../ir__Daikin_8h.html#a9cc7bb09fb66aa0cf7d0b751505fd3e6',1,'ir_Daikin.h']]], + ['kdaikin152defaultrepeat_951',['kDaikin152DefaultRepeat',['../IRremoteESP8266_8h.html#a9407eebab271524e74bc3ddddb1a2e0b',1,'IRremoteESP8266.h']]], + ['kdaikin152drytemp_952',['kDaikin152DryTemp',['../ir__Daikin_8h.html#a86e9308c00dbdd79546687af412c4156',1,'ir_Daikin.h']]], + ['kdaikin152econobyte_953',['kDaikin152EconoByte',['../ir__Daikin_8h.html#a988782fd6bcf25b098d7c07e38679a78',1,'ir_Daikin.h']]], + ['kdaikin152fanbyte_954',['kDaikin152FanByte',['../ir__Daikin_8h.html#a1972e59df2902335e37b2d66d16048a8',1,'ir_Daikin.h']]], + ['kdaikin152fantemp_955',['kDaikin152FanTemp',['../ir__Daikin_8h.html#ad5c5bb7e8b181c79fe68607c1a4d202f',1,'ir_Daikin.h']]], + ['kdaikin152freq_956',['kDaikin152Freq',['../ir__Daikin_8h.html#aa45492ae186142971975b7da56658a0b',1,'ir_Daikin.h']]], + ['kdaikin152gap_957',['kDaikin152Gap',['../ir__Daikin_8h.html#aee02d3b17db4a382035c00329c6c2a0a',1,'ir_Daikin.h']]], + ['kdaikin152hdrmark_958',['kDaikin152HdrMark',['../ir__Daikin_8h.html#a85fad797a9b43cb317fdb2e2c254a3bb',1,'ir_Daikin.h']]], + ['kdaikin152hdrspace_959',['kDaikin152HdrSpace',['../ir__Daikin_8h.html#a0eb0b1b5fabab75a5956b6b939696a12',1,'ir_Daikin.h']]], + ['kdaikin152leaderbits_960',['kDaikin152LeaderBits',['../ir__Daikin_8h.html#a432454efd5ea7457d34fe014b0d328c1',1,'ir_Daikin.h']]], + ['kdaikin152modebyte_961',['kDaikin152ModeByte',['../ir__Daikin_8h.html#a1aaa767f722926e9aaf02dbcd8029003',1,'ir_Daikin.h']]], + ['kdaikin152onespace_962',['kDaikin152OneSpace',['../ir__Daikin_8h.html#a1f96172c74b261a26ec6d71201f7c589',1,'ir_Daikin.h']]], + ['kdaikin152powerbyte_963',['kDaikin152PowerByte',['../ir__Daikin_8h.html#a67ff6fbdc004d3a29b1d31c5bc47f572',1,'ir_Daikin.h']]], + ['kdaikin152powerfulbyte_964',['kDaikin152PowerfulByte',['../ir__Daikin_8h.html#a720a3019f7bb2f8c458a7b79fbadd08f',1,'ir_Daikin.h']]], + ['kdaikin152quietbyte_965',['kDaikin152QuietByte',['../ir__Daikin_8h.html#ad534758115c401368a428d887faa8768',1,'ir_Daikin.h']]], + ['kdaikin152sensorbyte_966',['kDaikin152SensorByte',['../ir__Daikin_8h.html#a33187d50e8414f943d050a0b1c312168',1,'ir_Daikin.h']]], + ['kdaikin152sensoroffset_967',['kDaikin152SensorOffset',['../ir__Daikin_8h.html#a01ef92b6eb478b1897fdfdcea03d7116',1,'ir_Daikin.h']]], + ['kdaikin152statelength_968',['kDaikin152StateLength',['../IRremoteESP8266_8h.html#ae7579708922ffd3e44295f8770878983',1,'IRremoteESP8266.h']]], + ['kdaikin152swingvbyte_969',['kDaikin152SwingVByte',['../ir__Daikin_8h.html#a9ed39bcce7d0bc73060fba843dfd2b28',1,'ir_Daikin.h']]], + ['kdaikin152tempbyte_970',['kDaikin152TempByte',['../ir__Daikin_8h.html#a5e232b17db30a7e0ba159e2413df8b14',1,'ir_Daikin.h']]], + ['kdaikin152tempsize_971',['kDaikin152TempSize',['../ir__Daikin_8h.html#ad22ee842100e70d95f1ebcdcaf3f2099',1,'ir_Daikin.h']]], + ['kdaikin152zerospace_972',['kDaikin152ZeroSpace',['../ir__Daikin_8h.html#aec201aee71c0e301e8e191ddcaadb2de',1,'ir_Daikin.h']]], + ['kdaikin160bitmark_973',['kDaikin160BitMark',['../ir__Daikin_8h.html#a852c2268ed7a8dd42c629e8a0706b6f5',1,'ir_Daikin.h']]], + ['kdaikin160bits_974',['kDaikin160Bits',['../IRremoteESP8266_8h.html#aa6f1d6dded2ae3500cd52aa0c482a1b6',1,'IRremoteESP8266.h']]], + ['kdaikin160bytefan_975',['kDaikin160ByteFan',['../ir__Daikin_8h.html#a980ae6010c956c92348d3ac88c084247',1,'ir_Daikin.h']]], + ['kdaikin160bytemode_976',['kDaikin160ByteMode',['../ir__Daikin_8h.html#a6c5bcb2c4447dafc53c26775539886e6',1,'ir_Daikin.h']]], + ['kdaikin160bytepower_977',['kDaikin160BytePower',['../ir__Daikin_8h.html#a8e79923cf8aa346ea52791887b54ffbe',1,'ir_Daikin.h']]], + ['kdaikin160byteswingv_978',['kDaikin160ByteSwingV',['../ir__Daikin_8h.html#a35032831d79e96a98527896cd5d52efe',1,'ir_Daikin.h']]], + ['kdaikin160bytetemp_979',['kDaikin160ByteTemp',['../ir__Daikin_8h.html#a1b9eed515f9cfc3508cce7d53fb7a84a',1,'ir_Daikin.h']]], + ['kdaikin160defaultrepeat_980',['kDaikin160DefaultRepeat',['../IRremoteESP8266_8h.html#a82f4f1d8fae51c7e2f1f6753ca6e6053',1,'IRremoteESP8266.h']]], + ['kdaikin160freq_981',['kDaikin160Freq',['../ir__Daikin_8h.html#a69e8abb57aecc6b99c60c5df7e18ff39',1,'ir_Daikin.h']]], + ['kdaikin160gap_982',['kDaikin160Gap',['../ir__Daikin_8h.html#a8d107f0d63ef6951d657a55a370e8a8b',1,'ir_Daikin.h']]], + ['kdaikin160hdrmark_983',['kDaikin160HdrMark',['../ir__Daikin_8h.html#a96043b43ba4d963456206e2d02639325',1,'ir_Daikin.h']]], + ['kdaikin160hdrspace_984',['kDaikin160HdrSpace',['../ir__Daikin_8h.html#aefa7b5de43483951e00bd5d2cdbe5665',1,'ir_Daikin.h']]], + ['kdaikin160maskfan_985',['kDaikin160MaskFan',['../ir__Daikin_8h.html#a623f586183436960361a85f8480c87c6',1,'ir_Daikin.h']]], + ['kdaikin160maskswingv_986',['kDaikin160MaskSwingV',['../ir__Daikin_8h.html#abfaa078f7dfdd1c0bb14ad15fee26604',1,'ir_Daikin.h']]], + ['kdaikin160onespace_987',['kDaikin160OneSpace',['../ir__Daikin_8h.html#a068c2252191675dca6503bfc37e4785e',1,'ir_Daikin.h']]], + ['kdaikin160section1length_988',['kDaikin160Section1Length',['../ir__Daikin_8h.html#a06b59ee56cddcdcd9dfa375663da0c2d',1,'ir_Daikin.h']]], + ['kdaikin160section2length_989',['kDaikin160Section2Length',['../ir__Daikin_8h.html#a7d6194a363661e11167cc972f1b92f68',1,'ir_Daikin.h']]], + ['kdaikin160sections_990',['kDaikin160Sections',['../ir__Daikin_8h.html#afcc5de2994c1cd618437f1c67a5754d0',1,'ir_Daikin.h']]], + ['kdaikin160statelength_991',['kDaikin160StateLength',['../IRremoteESP8266_8h.html#a09f022a12a40a8fae09bfbddfbee6d62',1,'IRremoteESP8266.h']]], + ['kdaikin160swingvauto_992',['kDaikin160SwingVAuto',['../ir__Daikin_8h.html#aa6d9ee84d2c15c69ed8dbbc832285baf',1,'ir_Daikin.h']]], + ['kdaikin160swingvhigh_993',['kDaikin160SwingVHigh',['../ir__Daikin_8h.html#abf542bd70d12534af72fb4ec8df5d265',1,'ir_Daikin.h']]], + ['kdaikin160swingvhighest_994',['kDaikin160SwingVHighest',['../ir__Daikin_8h.html#a2a48ca041acbde68b902a4d0be4aeec5',1,'ir_Daikin.h']]], + ['kdaikin160swingvlow_995',['kDaikin160SwingVLow',['../ir__Daikin_8h.html#a04ff7cb63db6b281ced56283288f05c0',1,'ir_Daikin.h']]], + ['kdaikin160swingvlowest_996',['kDaikin160SwingVLowest',['../ir__Daikin_8h.html#ac4f34c7862802b21dede2ac0b534c8d8',1,'ir_Daikin.h']]], + ['kdaikin160swingvmiddle_997',['kDaikin160SwingVMiddle',['../ir__Daikin_8h.html#a620b644f07f9b664f09417bb362dc216',1,'ir_Daikin.h']]], + ['kdaikin160tempoffset_998',['kDaikin160TempOffset',['../ir__Daikin_8h.html#aa2f7050929bab65dbdb8af5b493dafe2',1,'ir_Daikin.h']]], + ['kdaikin160tempsize_999',['kDaikin160TempSize',['../ir__Daikin_8h.html#adfecac727480010fae8e419ac3f13e73',1,'ir_Daikin.h']]], + ['kdaikin160zerospace_1000',['kDaikin160ZeroSpace',['../ir__Daikin_8h.html#a2b4591126c0b26ab16b5611dbfa4d5f6',1,'ir_Daikin.h']]], + ['kdaikin176bitmark_1001',['kDaikin176BitMark',['../ir__Daikin_8h.html#a4be0185fb8f65c0286cbf55dfd63a40f',1,'ir_Daikin.h']]], + ['kdaikin176bits_1002',['kDaikin176Bits',['../IRremoteESP8266_8h.html#a78baf9c97c548618428d2fcfd7cc91d7',1,'IRremoteESP8266.h']]], + ['kdaikin176bytefan_1003',['kDaikin176ByteFan',['../ir__Daikin_8h.html#a21e4b1854d3f87757ba0f0c10074226c',1,'ir_Daikin.h']]], + ['kdaikin176bytemode_1004',['kDaikin176ByteMode',['../ir__Daikin_8h.html#ad114b4570f96bcbf5358fa1ece354572',1,'ir_Daikin.h']]], + ['kdaikin176bytemodebutton_1005',['kDaikin176ByteModeButton',['../ir__Daikin_8h.html#aacda7563a2aaa9a56c77ce550f24a237',1,'ir_Daikin.h']]], + ['kdaikin176bytepower_1006',['kDaikin176BytePower',['../ir__Daikin_8h.html#aabfb9642dce0ab4169b193955221b938',1,'ir_Daikin.h']]], + ['kdaikin176byteswingh_1007',['kDaikin176ByteSwingH',['../ir__Daikin_8h.html#a4566642e6aaa0d64c531fafe0309dccc',1,'ir_Daikin.h']]], + ['kdaikin176bytetemp_1008',['kDaikin176ByteTemp',['../ir__Daikin_8h.html#afab294c7e8c65e5bf58e85bee4901752',1,'ir_Daikin.h']]], + ['kdaikin176cool_1009',['kDaikin176Cool',['../ir__Daikin_8h.html#ab67e912a9abdda7dcbe52ce90b70a3b5',1,'ir_Daikin.h']]], + ['kdaikin176defaultrepeat_1010',['kDaikin176DefaultRepeat',['../IRremoteESP8266_8h.html#a0228803e8fff3c73227214d4bb3d8b05',1,'IRremoteESP8266.h']]], + ['kdaikin176dryfantemp_1011',['kDaikin176DryFanTemp',['../ir__Daikin_8h.html#a462ad30312f13443f51b510e5b391f42',1,'ir_Daikin.h']]], + ['kdaikin176fanmax_1012',['kDaikin176FanMax',['../ir__Daikin_8h.html#a97e77d2a09bc753c17104f9695a0c0b1',1,'ir_Daikin.h']]], + ['kdaikin176freq_1013',['kDaikin176Freq',['../ir__Daikin_8h.html#a7f0c76e579dad510f21c34ba57cbf8dc',1,'ir_Daikin.h']]], + ['kdaikin176gap_1014',['kDaikin176Gap',['../ir__Daikin_8h.html#a0309c9d689f64e2d57ab09a2bb27bc18',1,'ir_Daikin.h']]], + ['kdaikin176hdrmark_1015',['kDaikin176HdrMark',['../ir__Daikin_8h.html#a9ff1ca660571d09caa0de39ce1370720',1,'ir_Daikin.h']]], + ['kdaikin176hdrspace_1016',['kDaikin176HdrSpace',['../ir__Daikin_8h.html#a64c4874b5d92682911ca84e826e1ff0b',1,'ir_Daikin.h']]], + ['kdaikin176maskfan_1017',['kDaikin176MaskFan',['../ir__Daikin_8h.html#ae7410031c68ae8426caa61bc97909cdf',1,'ir_Daikin.h']]], + ['kdaikin176maskmode_1018',['kDaikin176MaskMode',['../ir__Daikin_8h.html#a65b76b7a85d70a4ed1af359b2babffa1',1,'ir_Daikin.h']]], + ['kdaikin176modebutton_1019',['kDaikin176ModeButton',['../ir__Daikin_8h.html#a5c8602d17e9f70eefd735741b9d714eb',1,'ir_Daikin.h']]], + ['kdaikin176onespace_1020',['kDaikin176OneSpace',['../ir__Daikin_8h.html#a86ed046d66daf884ac0f06722991f5ba',1,'ir_Daikin.h']]], + ['kdaikin176section1length_1021',['kDaikin176Section1Length',['../ir__Daikin_8h.html#a4c5ce7df75834c77c0908cc40dbe02ed',1,'ir_Daikin.h']]], + ['kdaikin176section2length_1022',['kDaikin176Section2Length',['../ir__Daikin_8h.html#a9e2bb25a1d64d2c042e7eef38f5347d0',1,'ir_Daikin.h']]], + ['kdaikin176sections_1023',['kDaikin176Sections',['../ir__Daikin_8h.html#a177d12ac0f4fe8b5c5aeaf8f72579607',1,'ir_Daikin.h']]], + ['kdaikin176statelength_1024',['kDaikin176StateLength',['../IRremoteESP8266_8h.html#aa71fc87dcb6f14b82997e1d2269429d2',1,'IRremoteESP8266.h']]], + ['kdaikin176swinghauto_1025',['kDaikin176SwingHAuto',['../ir__Daikin_8h.html#a326ffcf00330a1759e4f71f8f8603f23',1,'ir_Daikin.h']]], + ['kdaikin176swinghoff_1026',['kDaikin176SwingHOff',['../ir__Daikin_8h.html#a8672ccb9016808c84b1b06de6584188a',1,'ir_Daikin.h']]], + ['kdaikin176tempoffset_1027',['kDaikin176TempOffset',['../ir__Daikin_8h.html#aa5f6cc15ca424e4bf9cc4357d9db79c9',1,'ir_Daikin.h']]], + ['kdaikin176tempsize_1028',['kDaikin176TempSize',['../ir__Daikin_8h.html#a3ef1914f2caf650a90d8412f2c1e2b74',1,'ir_Daikin.h']]], + ['kdaikin176zerospace_1029',['kDaikin176ZeroSpace',['../ir__Daikin_8h.html#a4db8836caa6cae0bab6fbde94409c879',1,'ir_Daikin.h']]], + ['kdaikin216bitmark_1030',['kDaikin216BitMark',['../ir__Daikin_8h.html#ada7cf9c593d716617ff4436755eef4f9',1,'ir_Daikin.h']]], + ['kdaikin216bits_1031',['kDaikin216Bits',['../IRremoteESP8266_8h.html#a317bf475ee4c6ddd802995dc535377d9',1,'IRremoteESP8266.h']]], + ['kdaikin216bytefan_1032',['kDaikin216ByteFan',['../ir__Daikin_8h.html#a832e7a349293058ebc50c17b904fb8f7',1,'ir_Daikin.h']]], + ['kdaikin216bytemode_1033',['kDaikin216ByteMode',['../ir__Daikin_8h.html#a48974eb3ceb40f2f580bd266a60f0392',1,'ir_Daikin.h']]], + ['kdaikin216bytepower_1034',['kDaikin216BytePower',['../ir__Daikin_8h.html#a740c2db81aebd8cb9e18b3f8c6c5b8be',1,'ir_Daikin.h']]], + ['kdaikin216bytepowerful_1035',['kDaikin216BytePowerful',['../ir__Daikin_8h.html#a9a428d988d705beae3ff1f7c0f01cb8d',1,'ir_Daikin.h']]], + ['kdaikin216byteswingh_1036',['kDaikin216ByteSwingH',['../ir__Daikin_8h.html#a20239baacdf9fb981eb0fb84b0ef536a',1,'ir_Daikin.h']]], + ['kdaikin216byteswingv_1037',['kDaikin216ByteSwingV',['../ir__Daikin_8h.html#a9fd16b0fb0d67a7058816d4b4f1659fc',1,'ir_Daikin.h']]], + ['kdaikin216bytetemp_1038',['kDaikin216ByteTemp',['../ir__Daikin_8h.html#a5828687e12d2b7fe1d793235d91750bd',1,'ir_Daikin.h']]], + ['kdaikin216defaultrepeat_1039',['kDaikin216DefaultRepeat',['../IRremoteESP8266_8h.html#a9d14d424d5a93de62f3e6f453db112db',1,'IRremoteESP8266.h']]], + ['kdaikin216freq_1040',['kDaikin216Freq',['../ir__Daikin_8h.html#aa3a9753c90ecb6d7f5ee3e5a16c79217',1,'ir_Daikin.h']]], + ['kdaikin216gap_1041',['kDaikin216Gap',['../ir__Daikin_8h.html#ab807adaab8afbeb97afaa9ddb2ec2c63',1,'ir_Daikin.h']]], + ['kdaikin216hdrmark_1042',['kDaikin216HdrMark',['../ir__Daikin_8h.html#a24163655b3d374aa643506c2bf4a2406',1,'ir_Daikin.h']]], + ['kdaikin216hdrspace_1043',['kDaikin216HdrSpace',['../ir__Daikin_8h.html#a2e69973e9a4aee29668597d09fcd70a4',1,'ir_Daikin.h']]], + ['kdaikin216maskfan_1044',['kDaikin216MaskFan',['../ir__Daikin_8h.html#a88f67ea1fe03ef40b81c5226ff5c72d5',1,'ir_Daikin.h']]], + ['kdaikin216onespace_1045',['kDaikin216OneSpace',['../ir__Daikin_8h.html#a1edeb73093bdea23e6cfb39c31ca1fce',1,'ir_Daikin.h']]], + ['kdaikin216section1length_1046',['kDaikin216Section1Length',['../ir__Daikin_8h.html#a5aacc812feb33ef954adc49086036859',1,'ir_Daikin.h']]], + ['kdaikin216section2length_1047',['kDaikin216Section2Length',['../ir__Daikin_8h.html#aade497bb9aad663a9e1e9403188d2154',1,'ir_Daikin.h']]], + ['kdaikin216sections_1048',['kDaikin216Sections',['../ir__Daikin_8h.html#a0ecd54bb733b982e3e5adf0c13ac9f6b',1,'ir_Daikin.h']]], + ['kdaikin216statelength_1049',['kDaikin216StateLength',['../IRremoteESP8266_8h.html#a70a1a65c1947b440e4ff27477de5ddc7',1,'IRremoteESP8266.h']]], + ['kdaikin216swingoff_1050',['kDaikin216SwingOff',['../ir__Daikin_8h.html#a84d6bb74c705dfbcd558f0b411a2a88e',1,'ir_Daikin.h']]], + ['kdaikin216swingon_1051',['kDaikin216SwingOn',['../ir__Daikin_8h.html#a4b2d77aafd84ed004390b5d4c7ad0455',1,'ir_Daikin.h']]], + ['kdaikin216swingsize_1052',['kDaikin216SwingSize',['../ir__Daikin_8h.html#a90d9e740067051fe294f1b408f7e020b',1,'ir_Daikin.h']]], + ['kdaikin216tempoffset_1053',['kDaikin216TempOffset',['../ir__Daikin_8h.html#a8e497623bb05ff10287ca06ac6ec15f6',1,'ir_Daikin.h']]], + ['kdaikin216tempsize_1054',['kDaikin216TempSize',['../ir__Daikin_8h.html#a3ef59f8474b38d1b0311f1018dbd6225',1,'ir_Daikin.h']]], + ['kdaikin216zerospace_1055',['kDaikin216ZeroSpace',['../ir__Daikin_8h.html#a448250dbb5a3a9733f21a0e347d17999',1,'ir_Daikin.h']]], + ['kdaikin2beepoffset_1056',['kDaikin2BeepOffset',['../ir__Daikin_8h.html#ad7f6110b5e3bf8c3b72ca07b745bae7c',1,'ir_Daikin.h']]], + ['kdaikin2beepsize_1057',['kDaikin2BeepSize',['../ir__Daikin_8h.html#a3a42f10a3427bff7af3c745592fe58fe',1,'ir_Daikin.h']]], + ['kdaikin2bitclean_1058',['kDaikin2BitClean',['../ir__Daikin_8h.html#a6672ff35e765c9ecb14107e7732b0bb2',1,'ir_Daikin.h']]], + ['kdaikin2bitcleanoffset_1059',['kDaikin2BitCleanOffset',['../ir__Daikin_8h.html#a4fa7ed25fb3f2371c3b5c7cf4906a3f3',1,'ir_Daikin.h']]], + ['kdaikin2biteye_1060',['kDaikin2BitEye',['../ir__Daikin_8h.html#a8adb3f3e8508adf8adc530365fceb96b',1,'ir_Daikin.h']]], + ['kdaikin2biteyeauto_1061',['kDaikin2BitEyeAuto',['../ir__Daikin_8h.html#a6a24519db9870520a645e4ad31857e39',1,'ir_Daikin.h']]], + ['kdaikin2biteyeautooffset_1062',['kDaikin2BitEyeAutoOffset',['../ir__Daikin_8h.html#a73db209ad074eeaef1a5317cbee8ab35',1,'ir_Daikin.h']]], + ['kdaikin2biteyeoffset_1063',['kDaikin2BitEyeOffset',['../ir__Daikin_8h.html#a7a4c6e131d9a0e441de549bd5f93074f',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshair_1064',['kDaikin2BitFreshAir',['../ir__Daikin_8h.html#a9ab2c4b0f415ce0042b848e44850b7b8',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairhigh_1065',['kDaikin2BitFreshAirHigh',['../ir__Daikin_8h.html#a21a3f3c0f39827057d8f459283a72980',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairhighoffset_1066',['kDaikin2BitFreshAirHighOffset',['../ir__Daikin_8h.html#afd4f5946e5fa5d8f48af32b8934b0f93',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairoffset_1067',['kDaikin2BitFreshAirOffset',['../ir__Daikin_8h.html#a15e49a577737bdca28c28aeeb4260e57',1,'ir_Daikin.h']]], + ['kdaikin2bitmark_1068',['kDaikin2BitMark',['../ir__Daikin_8h.html#a226f10b7216d4f039cf79af823673a18',1,'ir_Daikin.h']]], + ['kdaikin2bitmold_1069',['kDaikin2BitMold',['../ir__Daikin_8h.html#aa452116afeb7d246cee672d2717e0ff7',1,'ir_Daikin.h']]], + ['kdaikin2bitmoldoffset_1070',['kDaikin2BitMoldOffset',['../ir__Daikin_8h.html#a0e58caeb44ebc6b7c6d06e91fee33795',1,'ir_Daikin.h']]], + ['kdaikin2bitpower_1071',['kDaikin2BitPower',['../ir__Daikin_8h.html#ac7b549d7b68bc245521d7f4e6a4643ab',1,'ir_Daikin.h']]], + ['kdaikin2bitpoweroffset_1072',['kDaikin2BitPowerOffset',['../ir__Daikin_8h.html#a617d14e811cb26b86fef3048151ffc45',1,'ir_Daikin.h']]], + ['kdaikin2bitpurify_1073',['kDaikin2BitPurify',['../ir__Daikin_8h.html#a9c4d6aa579adbfe454aa19f9f604f21c',1,'ir_Daikin.h']]], + ['kdaikin2bitpurifyoffset_1074',['kDaikin2BitPurifyOffset',['../ir__Daikin_8h.html#a847a9646dc86c26da931e5bf6640ddab',1,'ir_Daikin.h']]], + ['kdaikin2bits_1075',['kDaikin2Bits',['../IRremoteESP8266_8h.html#affd9b805fff390d05a83ff4eaa1c98de',1,'IRremoteESP8266.h']]], + ['kdaikin2bitsleeptimer_1076',['kDaikin2BitSleepTimer',['../ir__Daikin_8h.html#a928ae056887b123fdf6b1e2072d03564',1,'ir_Daikin.h']]], + ['kdaikin2bitsleeptimeroffset_1077',['kDaikin2BitSleepTimerOffset',['../ir__Daikin_8h.html#abf7cfde40fd00c3500ed08831434b80f',1,'ir_Daikin.h']]], + ['kdaikin2defaultrepeat_1078',['kDaikin2DefaultRepeat',['../IRremoteESP8266_8h.html#a2dde8fd00f8a28e35da04cff9a3a1908',1,'IRremoteESP8266.h']]], + ['kdaikin2fanbyte_1079',['kDaikin2FanByte',['../ir__Daikin_8h.html#a88608f735885e11734ae83a0cc69dc8d',1,'ir_Daikin.h']]], + ['kdaikin2freq_1080',['kDaikin2Freq',['../ir__Daikin_8h.html#ab82e4836d9023c4ba3041d1226761461',1,'ir_Daikin.h']]], + ['kdaikin2gap_1081',['kDaikin2Gap',['../ir__Daikin_8h.html#afe14712c1be4ca14d5cd41e77d4bada0',1,'ir_Daikin.h']]], + ['kdaikin2hdrmark_1082',['kDaikin2HdrMark',['../ir__Daikin_8h.html#ab679ef183af5b94f53697d434e6540c3',1,'ir_Daikin.h']]], + ['kdaikin2hdrspace_1083',['kDaikin2HdrSpace',['../ir__Daikin_8h.html#a557f8eeaf55ff7fda0cacd0245ac27d3',1,'ir_Daikin.h']]], + ['kdaikin2leadermark_1084',['kDaikin2LeaderMark',['../ir__Daikin_8h.html#a533c7ea8f968502d4b31e14eb2b1f614',1,'ir_Daikin.h']]], + ['kdaikin2leaderspace_1085',['kDaikin2LeaderSpace',['../ir__Daikin_8h.html#a9d48d64e470ff0318bd62b3385433f57',1,'ir_Daikin.h']]], + ['kdaikin2lightoffset_1086',['kDaikin2LightOffset',['../ir__Daikin_8h.html#a0f40d38db7c625df9504798938ba24eb',1,'ir_Daikin.h']]], + ['kdaikin2lightsize_1087',['kDaikin2LightSize',['../ir__Daikin_8h.html#a4dc46fabef2c96a263a504a5f9012e1f',1,'ir_Daikin.h']]], + ['kdaikin2mincooltemp_1088',['kDaikin2MinCoolTemp',['../ir__Daikin_8h.html#a78b37644f9327537d35bec4c0fd8faee',1,'ir_Daikin.h']]], + ['kdaikin2onespace_1089',['kDaikin2OneSpace',['../ir__Daikin_8h.html#a70a96368500562fa95f88dc2f203c194',1,'ir_Daikin.h']]], + ['kdaikin2section1length_1090',['kDaikin2Section1Length',['../ir__Daikin_8h.html#a463878e9bfb22ca3c64a40259598872c',1,'ir_Daikin.h']]], + ['kdaikin2section2length_1091',['kDaikin2Section2Length',['../ir__Daikin_8h.html#a8cb956f86fdf487b1ea7ac388eeda2b5',1,'ir_Daikin.h']]], + ['kdaikin2sections_1092',['kDaikin2Sections',['../ir__Daikin_8h.html#a770cef4efa5d5668b063cf0e26f1b134',1,'ir_Daikin.h']]], + ['kdaikin2statelength_1093',['kDaikin2StateLength',['../IRremoteESP8266_8h.html#a349e4d17f83bb3e707ff19c0255c1644',1,'IRremoteESP8266.h']]], + ['kdaikin2swinghauto_1094',['kDaikin2SwingHAuto',['../ir__Daikin_8h.html#a834a3138b0f9bfdac98d26aa63bc951e',1,'ir_Daikin.h']]], + ['kdaikin2swinghleft_1095',['kDaikin2SwingHLeft',['../ir__Daikin_8h.html#aa9b294b2f12660081171df290a7e874f',1,'ir_Daikin.h']]], + ['kdaikin2swinghleftmax_1096',['kDaikin2SwingHLeftMax',['../ir__Daikin_8h.html#aac08696fc9734996537204c089db2f7c',1,'ir_Daikin.h']]], + ['kdaikin2swinghmiddle_1097',['kDaikin2SwingHMiddle',['../ir__Daikin_8h.html#ab882d68819344e622182b07ded30cccf',1,'ir_Daikin.h']]], + ['kdaikin2swinghright_1098',['kDaikin2SwingHRight',['../ir__Daikin_8h.html#a8d7c79266bedbb722dc1a74c8b727a27',1,'ir_Daikin.h']]], + ['kdaikin2swinghrightmax_1099',['kDaikin2SwingHRightMax',['../ir__Daikin_8h.html#a843ad9ee10eccd799814ca9fff57f481',1,'ir_Daikin.h']]], + ['kdaikin2swinghswing_1100',['kDaikin2SwingHSwing',['../ir__Daikin_8h.html#a3776d46e94a771a6dc94d14257f34d09',1,'ir_Daikin.h']]], + ['kdaikin2swinghwide_1101',['kDaikin2SwingHWide',['../ir__Daikin_8h.html#a93157e048486e564757ba737551cf481',1,'ir_Daikin.h']]], + ['kdaikin2swingvauto_1102',['kDaikin2SwingVAuto',['../ir__Daikin_8h.html#aa91228576ef22854a693c86df5276cbb',1,'ir_Daikin.h']]], + ['kdaikin2swingvbreeze_1103',['kDaikin2SwingVBreeze',['../ir__Daikin_8h.html#a5646d38fff6a985314158796665d9d76',1,'ir_Daikin.h']]], + ['kdaikin2swingvcirculate_1104',['kDaikin2SwingVCirculate',['../ir__Daikin_8h.html#a717bb32ce20e6d65ee78a9e8ba0f5490',1,'ir_Daikin.h']]], + ['kdaikin2swingvhigh_1105',['kDaikin2SwingVHigh',['../ir__Daikin_8h.html#a2d25d46fb289c3450ed6817a45982e27',1,'ir_Daikin.h']]], + ['kdaikin2swingvlow_1106',['kDaikin2SwingVLow',['../ir__Daikin_8h.html#accae3be213670675f8dfc974fe19f2cf',1,'ir_Daikin.h']]], + ['kdaikin2swingvswing_1107',['kDaikin2SwingVSwing',['../ir__Daikin_8h.html#a2a62938481ba7b4374df50867295c07d',1,'ir_Daikin.h']]], + ['kdaikin2tolerance_1108',['kDaikin2Tolerance',['../ir__Daikin_8h.html#ac428e884b15026c0610cc1b0b8b46154',1,'ir_Daikin.h']]], + ['kdaikin2zerospace_1109',['kDaikin2ZeroSpace',['../ir__Daikin_8h.html#a91b023ce8679d8d0e4434e014e746f99',1,'ir_Daikin.h']]], + ['kdaikin64bitmark_1110',['kDaikin64BitMark',['../ir__Daikin_8h.html#a6d89c1acd56b670b2aba65429d6fbf00',1,'ir_Daikin.h']]], + ['kdaikin64bits_1111',['kDaikin64Bits',['../IRremoteESP8266_8h.html#a89266e9211a81eda22475fb5a258484f',1,'IRremoteESP8266.h']]], + ['kdaikin64checksumoffset_1112',['kDaikin64ChecksumOffset',['../ir__Daikin_8h.html#a5c47c0a0b1d2a23620beb2496af958c5',1,'ir_Daikin.h']]], + ['kdaikin64checksumsize_1113',['kDaikin64ChecksumSize',['../ir__Daikin_8h.html#a0c068274c73deb732e70a7daf6684391',1,'ir_Daikin.h']]], + ['kdaikin64clockhourssize_1114',['kDaikin64ClockHoursSize',['../ir__Daikin_8h.html#ae6d8f59a9707bc807a209167231d4399',1,'ir_Daikin.h']]], + ['kdaikin64clockminssize_1115',['kDaikin64ClockMinsSize',['../ir__Daikin_8h.html#a3ab23d9db994fb6dd52208f5f69b4531',1,'ir_Daikin.h']]], + ['kdaikin64clockoffset_1116',['kDaikin64ClockOffset',['../ir__Daikin_8h.html#af204ccf4e6bd33439cec240445785e9c',1,'ir_Daikin.h']]], + ['kdaikin64clocksize_1117',['kDaikin64ClockSize',['../ir__Daikin_8h.html#a110f42ae8aa2651b195c67eef15c4d79',1,'ir_Daikin.h']]], + ['kdaikin64cool_1118',['kDaikin64Cool',['../ir__Daikin_8h.html#a1ed020e8e7b5b741e90c4a27ca9f3a91',1,'ir_Daikin.h']]], + ['kdaikin64defaultrepeat_1119',['kDaikin64DefaultRepeat',['../IRremoteESP8266_8h.html#aca64338c3e3bbe52f8ec5688317041b3',1,'IRremoteESP8266.h']]], + ['kdaikin64dry_1120',['kDaikin64Dry',['../ir__Daikin_8h.html#aa494c8e2a54209c7467fdd7f40655b0b',1,'ir_Daikin.h']]], + ['kdaikin64fan_1121',['kDaikin64Fan',['../ir__Daikin_8h.html#aa1f4bb12be0f74af35ee54a5540f8a7b',1,'ir_Daikin.h']]], + ['kdaikin64fanauto_1122',['kDaikin64FanAuto',['../ir__Daikin_8h.html#a6fbc965cb8194048ed27d586321c01b2',1,'ir_Daikin.h']]], + ['kdaikin64fanhigh_1123',['kDaikin64FanHigh',['../ir__Daikin_8h.html#a122d57c30d1f4ad8f20d44077b0a1970',1,'ir_Daikin.h']]], + ['kdaikin64fanlow_1124',['kDaikin64FanLow',['../ir__Daikin_8h.html#a5a692fdcb373acf101536adb4c18384f',1,'ir_Daikin.h']]], + ['kdaikin64fanmed_1125',['kDaikin64FanMed',['../ir__Daikin_8h.html#a9b2737ba57e38d4c3dfe7bc65de4c944',1,'ir_Daikin.h']]], + ['kdaikin64fanoffset_1126',['kDaikin64FanOffset',['../ir__Daikin_8h.html#a5523d6df96b83aa152adc1cbdac6534f',1,'ir_Daikin.h']]], + ['kdaikin64fanquiet_1127',['kDaikin64FanQuiet',['../ir__Daikin_8h.html#a1a7d78b2ed8ca5b83d6422d659ecb296',1,'ir_Daikin.h']]], + ['kdaikin64fansize_1128',['kDaikin64FanSize',['../ir__Daikin_8h.html#ac907b8f8d46eb7983a1289f23bc02401',1,'ir_Daikin.h']]], + ['kdaikin64fanturbo_1129',['kDaikin64FanTurbo',['../ir__Daikin_8h.html#ae6d370916c0897bc82346136d7922f5d',1,'ir_Daikin.h']]], + ['kdaikin64freq_1130',['kDaikin64Freq',['../ir__Daikin_8h.html#a7b63829df4d0e1de61ed396c3b07e988',1,'ir_Daikin.h']]], + ['kdaikin64gap_1131',['kDaikin64Gap',['../ir__Daikin_8h.html#ae191cb5f6c65b944970158caaf56618d',1,'ir_Daikin.h']]], + ['kdaikin64hdrmark_1132',['kDaikin64HdrMark',['../ir__Daikin_8h.html#abe7b92798de08dfc5f044869891bdec5',1,'ir_Daikin.h']]], + ['kdaikin64hdrspace_1133',['kDaikin64HdrSpace',['../ir__Daikin_8h.html#a1eac122554acda264f9aa48261b2a884',1,'ir_Daikin.h']]], + ['kdaikin64knowngoodstate_1134',['kDaikin64KnownGoodState',['../ir__Daikin_8h.html#a09f0aa8c586b35b79bbceb19e822eb48',1,'ir_Daikin.h']]], + ['kdaikin64ldrmark_1135',['kDaikin64LdrMark',['../ir__Daikin_8h.html#aca20b8ee0fa9a8aa2d676ef12bd5ba97',1,'ir_Daikin.h']]], + ['kdaikin64ldrspace_1136',['kDaikin64LdrSpace',['../ir__Daikin_8h.html#ada1084c119abe58dadcb17eb4cfed072',1,'ir_Daikin.h']]], + ['kdaikin64maxtemp_1137',['kDaikin64MaxTemp',['../ir__Daikin_8h.html#a495e3b77590263a2c043c1ba12489fac',1,'ir_Daikin.h']]], + ['kdaikin64mintemp_1138',['kDaikin64MinTemp',['../ir__Daikin_8h.html#a209cb1798ae64de1f5274fb167ee62ea',1,'ir_Daikin.h']]], + ['kdaikin64modeoffset_1139',['kDaikin64ModeOffset',['../ir__Daikin_8h.html#ac32a0c805d01b5a9fa4d4aeb5546b8e3',1,'ir_Daikin.h']]], + ['kdaikin64modesize_1140',['kDaikin64ModeSize',['../ir__Daikin_8h.html#a451465916f9ae0586cf915005be33315',1,'ir_Daikin.h']]], + ['kdaikin64offtimeenablebit_1141',['kDaikin64OffTimeEnableBit',['../ir__Daikin_8h.html#a5d5c1380e6dd22cef44a76f74049a813',1,'ir_Daikin.h']]], + ['kdaikin64offtimehalfhourbit_1142',['kDaikin64OffTimeHalfHourBit',['../ir__Daikin_8h.html#a766df1d3c0fce7576a3e694b6e0d9242',1,'ir_Daikin.h']]], + ['kdaikin64offtimeoffset_1143',['kDaikin64OffTimeOffset',['../ir__Daikin_8h.html#a3aecddae0a4c0a3123b296dd6b0fb38e',1,'ir_Daikin.h']]], + ['kdaikin64offtimesize_1144',['kDaikin64OffTimeSize',['../ir__Daikin_8h.html#a70e8ae340d5f1ca35b2d6a46020b9dcc',1,'ir_Daikin.h']]], + ['kdaikin64onespace_1145',['kDaikin64OneSpace',['../ir__Daikin_8h.html#ab3129b72f5300893d04b47e72dd420e1',1,'ir_Daikin.h']]], + ['kdaikin64ontimeenablebit_1146',['kDaikin64OnTimeEnableBit',['../ir__Daikin_8h.html#ae264ee33d051149cecc08e3a026feba7',1,'ir_Daikin.h']]], + ['kdaikin64ontimehalfhourbit_1147',['kDaikin64OnTimeHalfHourBit',['../ir__Daikin_8h.html#a0d37e6624946b26dd30c3ed25181cc37',1,'ir_Daikin.h']]], + ['kdaikin64ontimeoffset_1148',['kDaikin64OnTimeOffset',['../ir__Daikin_8h.html#a6b4af969e8b114502f067b039b0a9467',1,'ir_Daikin.h']]], + ['kdaikin64ontimesize_1149',['kDaikin64OnTimeSize',['../ir__Daikin_8h.html#a46c5e1db123959992db9e746e2b3c58a',1,'ir_Daikin.h']]], + ['kdaikin64overhead_1150',['kDaikin64Overhead',['../ir__Daikin_8h.html#af0dafe45d0127430e05f2312e8ba99bb',1,'ir_Daikin.h']]], + ['kdaikin64powertogglebit_1151',['kDaikin64PowerToggleBit',['../ir__Daikin_8h.html#a55ca8803d859f0ffaac3c3547d6b532c',1,'ir_Daikin.h']]], + ['kdaikin64sleepbit_1152',['kDaikin64SleepBit',['../ir__Daikin_8h.html#addbe01f4a4766469fe5fd1cf9972f437',1,'ir_Daikin.h']]], + ['kdaikin64swingvbit_1153',['kDaikin64SwingVBit',['../ir__Daikin_8h.html#a9c7cbb529c760cead772fe03f7f90b1a',1,'ir_Daikin.h']]], + ['kdaikin64tempoffset_1154',['kDaikin64TempOffset',['../ir__Daikin_8h.html#a4b66ea40f97deafc22df18bd0942b5f1',1,'ir_Daikin.h']]], + ['kdaikin64tempsize_1155',['kDaikin64TempSize',['../ir__Daikin_8h.html#acc21945b46b307068e8669c83fbe5837',1,'ir_Daikin.h']]], + ['kdaikin64tolerancedelta_1156',['kDaikin64ToleranceDelta',['../ir__Daikin_8h.html#ae0b22a140c2727de9a347e8ab8d554e9',1,'ir_Daikin.h']]], + ['kdaikin64zerospace_1157',['kDaikin64ZeroSpace',['../ir__Daikin_8h.html#a142e45c289af1e9802254b9c138003fa',1,'ir_Daikin.h']]], + ['kdaikinauto_1158',['kDaikinAuto',['../ir__Daikin_8h.html#af3a0e7c149d020002cdf345a15606542',1,'ir_Daikin.h']]], + ['kdaikinbeeploud_1159',['kDaikinBeepLoud',['../ir__Daikin_8h.html#a4eb2b3899076882e3ed23220138ebac1',1,'ir_Daikin.h']]], + ['kdaikinbeepoff_1160',['kDaikinBeepOff',['../ir__Daikin_8h.html#a8271934c8bbd4b8e4d6aacdee5a038cf',1,'ir_Daikin.h']]], + ['kdaikinbeepquiet_1161',['kDaikinBeepQuiet',['../ir__Daikin_8h.html#a11008f7d6afc934426b88704d47301e7',1,'ir_Daikin.h']]], + ['kdaikinbitcomfort_1162',['kDaikinBitComfort',['../ir__Daikin_8h.html#aede9991f88965161d3f7cf1dba7fdeb7',1,'ir_Daikin.h']]], + ['kdaikinbitcomfortoffset_1163',['kDaikinBitComfortOffset',['../ir__Daikin_8h.html#a2e218dda2eb4ab3a97ea8018192c5f85',1,'ir_Daikin.h']]], + ['kdaikinbitecono_1164',['kDaikinBitEcono',['../ir__Daikin_8h.html#ab579939e749517944e6e497d5e44e922',1,'ir_Daikin.h']]], + ['kdaikinbiteconooffset_1165',['kDaikinBitEconoOffset',['../ir__Daikin_8h.html#aa99539b36ab708397bd1adbd4fd4f378',1,'ir_Daikin.h']]], + ['kdaikinbiteye_1166',['kDaikinBitEye',['../ir__Daikin_8h.html#a98bbaae1b0f16cf6f2428dcf326eda51',1,'ir_Daikin.h']]], + ['kdaikinbitmark_1167',['kDaikinBitMark',['../ir__Daikin_8h.html#ae109b9ea2120f989dac2529345e38adb',1,'ir_Daikin.h']]], + ['kdaikinbitmold_1168',['kDaikinBitMold',['../ir__Daikin_8h.html#a916ad89ccf3c0225a4ca1b36d74c67b2',1,'ir_Daikin.h']]], + ['kdaikinbitmoldoffset_1169',['kDaikinBitMoldOffset',['../ir__Daikin_8h.html#ad794d6ff5b5d05642e2668378d3a1100',1,'ir_Daikin.h']]], + ['kdaikinbitofftimer_1170',['kDaikinBitOffTimer',['../ir__Daikin_8h.html#a5d68046ada1892be65f14d06c2a25b2b',1,'ir_Daikin.h']]], + ['kdaikinbitofftimeroffset_1171',['kDaikinBitOffTimerOffset',['../ir__Daikin_8h.html#a7156bec80ef23aa0e4e212e11d63bdef',1,'ir_Daikin.h']]], + ['kdaikinbitontimer_1172',['kDaikinBitOnTimer',['../ir__Daikin_8h.html#a421a745ce85313d326e00b996b5afd80',1,'ir_Daikin.h']]], + ['kdaikinbitontimeroffset_1173',['kDaikinBitOnTimerOffset',['../ir__Daikin_8h.html#a7a6b740034320cc25fb6d33d36845ca0',1,'ir_Daikin.h']]], + ['kdaikinbitpower_1174',['kDaikinBitPower',['../ir__Daikin_8h.html#ab0d91673bcd73cbbbf5f18d6d73b699e',1,'ir_Daikin.h']]], + ['kdaikinbitpowerful_1175',['kDaikinBitPowerful',['../ir__Daikin_8h.html#a4d03bc31a28d866c3bf855f6482209e8',1,'ir_Daikin.h']]], + ['kdaikinbitpowerfuloffset_1176',['kDaikinBitPowerfulOffset',['../ir__Daikin_8h.html#a772bca7454e28bd3f61cdd24f58b98c8',1,'ir_Daikin.h']]], + ['kdaikinbitpoweroffset_1177',['kDaikinBitPowerOffset',['../ir__Daikin_8h.html#ad3672753b2b06b52cd8afeca3f564af4',1,'ir_Daikin.h']]], + ['kdaikinbits_1178',['kDaikinBits',['../IRremoteESP8266_8h.html#a657f8e60bc1f896d4a46ec101c289485',1,'IRremoteESP8266.h']]], + ['kdaikinbitsensor_1179',['kDaikinBitSensor',['../ir__Daikin_8h.html#a37c7e26d1af184f844ef2c46064137ad',1,'ir_Daikin.h']]], + ['kdaikinbitsensoroffset_1180',['kDaikinBitSensorOffset',['../ir__Daikin_8h.html#a1ccb2c358aef3bf55005cf6b391e9e9b',1,'ir_Daikin.h']]], + ['kdaikinbitsilent_1181',['kDaikinBitSilent',['../ir__Daikin_8h.html#a85249d39c34b1a8b3bb8de4da32bb502',1,'ir_Daikin.h']]], + ['kdaikinbitsilentoffset_1182',['kDaikinBitSilentOffset',['../ir__Daikin_8h.html#a3fb5172c458084319937aa4ec2d6383b',1,'ir_Daikin.h']]], + ['kdaikinbitsshort_1183',['kDaikinBitsShort',['../IRremoteESP8266_8h.html#aebaa8eb786747761fb369cfd34181cb7',1,'IRremoteESP8266.h']]], + ['kdaikinbitweeklytimer_1184',['kDaikinBitWeeklyTimer',['../ir__Daikin_8h.html#a7d58b7c351394a43117e4710acd35cec',1,'ir_Daikin.h']]], + ['kdaikinbitweeklytimeroffset_1185',['kDaikinBitWeeklyTimerOffset',['../ir__Daikin_8h.html#a8ff2c05701327b6f26bee66361e39365',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum1_1186',['kDaikinByteChecksum1',['../ir__Daikin_8h.html#a887d8d38cf4330e1107443471fa119ca',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum2_1187',['kDaikinByteChecksum2',['../ir__Daikin_8h.html#ab27225f21b29e617bf03fc68cc6e8e0f',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum3_1188',['kDaikinByteChecksum3',['../ir__Daikin_8h.html#a7277c453d4deed6abf0a7577b5b4454f',1,'ir_Daikin.h']]], + ['kdaikinbyteclockminshigh_1189',['kDaikinByteClockMinsHigh',['../ir__Daikin_8h.html#ade7d506fd7da26ae1713602c1620f716',1,'ir_Daikin.h']]], + ['kdaikinbyteclockminslow_1190',['kDaikinByteClockMinsLow',['../ir__Daikin_8h.html#a3c096c2f33eca6c6f7f57f0f684a4b43',1,'ir_Daikin.h']]], + ['kdaikinbytecomfort_1191',['kDaikinByteComfort',['../ir__Daikin_8h.html#a3b209715b7ac4e8ef4f15043654e646b',1,'ir_Daikin.h']]], + ['kdaikinbyteecono_1192',['kDaikinByteEcono',['../ir__Daikin_8h.html#ae08470f2e453a2a5b60bdb478fc8c6d7',1,'ir_Daikin.h']]], + ['kdaikinbyteeye_1193',['kDaikinByteEye',['../ir__Daikin_8h.html#ad3e2bb2f17d599c708e64cf08c042331',1,'ir_Daikin.h']]], + ['kdaikinbytefan_1194',['kDaikinByteFan',['../ir__Daikin_8h.html#a9078ad5b6b9afe43ffa0e646c35f3db6',1,'ir_Daikin.h']]], + ['kdaikinbytemold_1195',['kDaikinByteMold',['../ir__Daikin_8h.html#a81e098798e6aa7c0882703dced8ab039',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimer_1196',['kDaikinByteOffTimer',['../ir__Daikin_8h.html#ad7fce891883a25e260cd8c0890d46f59',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimerminshigh_1197',['kDaikinByteOffTimerMinsHigh',['../ir__Daikin_8h.html#a0294c99254e3eef7e7fa2cd169e0e5a9',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimerminslow_1198',['kDaikinByteOffTimerMinsLow',['../ir__Daikin_8h.html#a45855767cf37f1562a7726dbf6419c87',1,'ir_Daikin.h']]], + ['kdaikinbyteontimer_1199',['kDaikinByteOnTimer',['../ir__Daikin_8h.html#a0a685bb92d8e3df4c9bd96b71c48f352',1,'ir_Daikin.h']]], + ['kdaikinbyteontimerminshigh_1200',['kDaikinByteOnTimerMinsHigh',['../ir__Daikin_8h.html#a77ce46689e1a353237edd45e7170bff6',1,'ir_Daikin.h']]], + ['kdaikinbyteontimerminslow_1201',['kDaikinByteOnTimerMinsLow',['../ir__Daikin_8h.html#a7c434f5c6a3febddf3da44e1c2b97872',1,'ir_Daikin.h']]], + ['kdaikinbytepower_1202',['kDaikinBytePower',['../ir__Daikin_8h.html#aa99cac4871f7ef1cdff2f41496989218',1,'ir_Daikin.h']]], + ['kdaikinbytepowerful_1203',['kDaikinBytePowerful',['../ir__Daikin_8h.html#a79b3d4cd40f839a3708fa33abb4b74c4',1,'ir_Daikin.h']]], + ['kdaikinbytesensor_1204',['kDaikinByteSensor',['../ir__Daikin_8h.html#afd18e8b5b4c9c6572659ea46df01a6df',1,'ir_Daikin.h']]], + ['kdaikinbytesilent_1205',['kDaikinByteSilent',['../ir__Daikin_8h.html#aac58a7371777f682cac3189d9905b968',1,'ir_Daikin.h']]], + ['kdaikinbyteswingh_1206',['kDaikinByteSwingH',['../ir__Daikin_8h.html#a58b88a2679bd57d723aa33afca4f2427',1,'ir_Daikin.h']]], + ['kdaikinbytetemp_1207',['kDaikinByteTemp',['../ir__Daikin_8h.html#acd14c2ebc40a8375343595ed8f0109f8',1,'ir_Daikin.h']]], + ['kdaikinbyteweeklytimer_1208',['kDaikinByteWeeklyTimer',['../ir__Daikin_8h.html#ad4eba59910311bdc8b489b27b4b59751',1,'ir_Daikin.h']]], + ['kdaikinclockminshighoffset_1209',['kDaikinClockMinsHighOffset',['../ir__Daikin_8h.html#a1b28496ffacf558f7919029f029c2dc6',1,'ir_Daikin.h']]], + ['kdaikinclockminshighsize_1210',['kDaikinClockMinsHighSize',['../ir__Daikin_8h.html#a1e018d153b13c65e411b3b090efc6d27',1,'ir_Daikin.h']]], + ['kdaikincool_1211',['kDaikinCool',['../ir__Daikin_8h.html#aa57615a0a9f79b97139580a807bf095f',1,'ir_Daikin.h']]], + ['kdaikincurbit_1212',['kDaikinCurBit',['../ir__Daikin_8h.html#afccfde2b46f5fcb425f02a79a9c20494',1,'ir_Daikin.h']]], + ['kdaikincurindex_1213',['kDaikinCurIndex',['../ir__Daikin_8h.html#a5c01a0bfbd92b337d2e4a5c3df381865',1,'ir_Daikin.h']]], + ['kdaikindefaultrepeat_1214',['kDaikinDefaultRepeat',['../IRremoteESP8266_8h.html#af691d5202b7f121a16b2d9871ee14d9c',1,'IRremoteESP8266.h']]], + ['kdaikindowoffset_1215',['kDaikinDoWOffset',['../ir__Daikin_8h.html#a07793a4b1ea8e9aabb77730ccbdf7e15',1,'ir_Daikin.h']]], + ['kdaikindowsize_1216',['kDaikinDoWSize',['../ir__Daikin_8h.html#a7bb34e2fc2c1926167b79889a5036ba0',1,'ir_Daikin.h']]], + ['kdaikindry_1217',['kDaikinDry',['../ir__Daikin_8h.html#ab6143bef74a122c3fba3a3b29df0cf29',1,'ir_Daikin.h']]], + ['kdaikinfan_1218',['kDaikinFan',['../ir__Daikin_8h.html#a616df34328cdac764aecc9ffb0f16f09',1,'ir_Daikin.h']]], + ['kdaikinfanauto_1219',['kDaikinFanAuto',['../ir__Daikin_8h.html#a87807bd5727d9da1b615fca2bd732292',1,'ir_Daikin.h']]], + ['kdaikinfanmax_1220',['kDaikinFanMax',['../ir__Daikin_8h.html#ab483f3913a909884f44f8cd8f779bca0',1,'ir_Daikin.h']]], + ['kdaikinfanmed_1221',['kDaikinFanMed',['../ir__Daikin_8h.html#ab6eb2c902c2b5f927160efc9fb9ab08c',1,'ir_Daikin.h']]], + ['kdaikinfanmin_1222',['kDaikinFanMin',['../ir__Daikin_8h.html#a83ad300b9374e50c22211501ee2d1a7a',1,'ir_Daikin.h']]], + ['kdaikinfanoffset_1223',['kDaikinFanOffset',['../ir__Daikin_8h.html#a48d0d0cb1174069d5b6ee2882761cb88',1,'ir_Daikin.h']]], + ['kdaikinfanquiet_1224',['kDaikinFanQuiet',['../ir__Daikin_8h.html#aae481cf166671c30bccdc7f47aa6666e',1,'ir_Daikin.h']]], + ['kdaikinfansize_1225',['kDaikinFanSize',['../ir__Daikin_8h.html#a1e490e414ff3f5f55b4cca443661cd1a',1,'ir_Daikin.h']]], + ['kdaikinfirstheader64_1226',['kDaikinFirstHeader64',['../ir__Daikin_8h.html#a0bd3b36061d545bb21562622642f4196',1,'ir_Daikin.h']]], + ['kdaikingap_1227',['kDaikinGap',['../ir__Daikin_8h.html#aed68991584125a277593c339ab387276',1,'ir_Daikin.h']]], + ['kdaikinhdrmark_1228',['kDaikinHdrMark',['../ir__Daikin_8h.html#a0a38b3bdfd8f4f7a18f969188388e29e',1,'ir_Daikin.h']]], + ['kdaikinhdrspace_1229',['kDaikinHdrSpace',['../ir__Daikin_8h.html#ac4ca6c53faeec7d7a7ccfb50802087dc',1,'ir_Daikin.h']]], + ['kdaikinheaderlength_1230',['kDaikinHeaderLength',['../ir__Daikin_8h.html#a476ca864b6791439549bb4257ca78b23',1,'ir_Daikin.h']]], + ['kdaikinheat_1231',['kDaikinHeat',['../ir__Daikin_8h.html#a05824dc5af4ed0d3eceda540ad0e7a9f',1,'ir_Daikin.h']]], + ['kdaikinlightbright_1232',['kDaikinLightBright',['../ir__Daikin_8h.html#a20a3103d8d0a672c0c05c1679bf3b2ab',1,'ir_Daikin.h']]], + ['kdaikinlightdim_1233',['kDaikinLightDim',['../ir__Daikin_8h.html#a1093baf5b62fca42f9361715be2198a3',1,'ir_Daikin.h']]], + ['kdaikinlightoff_1234',['kDaikinLightOff',['../ir__Daikin_8h.html#ae57f7d2ea43e865ebf8175a8dbacab45',1,'ir_Daikin.h']]], + ['kdaikinmarkexcess_1235',['kDaikinMarkExcess',['../ir__Daikin_8h.html#a5331e1ee51bd7b001346aa41ee5d26cc',1,'ir_Daikin.h']]], + ['kdaikinmaxtemp_1236',['kDaikinMaxTemp',['../ir__Daikin_8h.html#aab7be756494a5ed23e9202af769e0012',1,'ir_Daikin.h']]], + ['kdaikinmintemp_1237',['kDaikinMinTemp',['../ir__Daikin_8h.html#af257feb15dc282c7d06351ee9eed666b',1,'ir_Daikin.h']]], + ['kdaikinmodeoffset_1238',['kDaikinModeOffset',['../ir__Daikin_8h.html#a9a3aa5ee98496b468c5ba86faa3eeeae',1,'ir_Daikin.h']]], + ['kdaikinmodesize_1239',['kDaikinModeSize',['../ir__Daikin_8h.html#a00fc390085520e5382dbce2633b7142e',1,'ir_Daikin.h']]], + ['kdaikinonespace_1240',['kDaikinOneSpace',['../ir__Daikin_8h.html#a6653082dcfde989bd2c5810809fc18a9',1,'ir_Daikin.h']]], + ['kdaikinontimerminshighoffset_1241',['kDaikinOnTimerMinsHighOffset',['../ir__Daikin_8h.html#a2a4a4254fc853901686982c1410c77c8',1,'ir_Daikin.h']]], + ['kdaikinontimerminshighsize_1242',['kDaikinOnTimerMinsHighSize',['../ir__Daikin_8h.html#a2fc9c203378e49ea1d49557d776de620',1,'ir_Daikin.h']]], + ['kdaikinsection1length_1243',['kDaikinSection1Length',['../ir__Daikin_8h.html#ab3b8aacbebe6c1c5514141102d1ca26f',1,'ir_Daikin.h']]], + ['kdaikinsection2length_1244',['kDaikinSection2Length',['../ir__Daikin_8h.html#a2e65cdf05d22a20f01ae5f6d3e222218',1,'ir_Daikin.h']]], + ['kdaikinsection3length_1245',['kDaikinSection3Length',['../ir__Daikin_8h.html#ae7dbaf6b4034267e4610087f9f2f51e3',1,'ir_Daikin.h']]], + ['kdaikinsections_1246',['kDaikinSections',['../ir__Daikin_8h.html#aad822c70789b861fa5beb839833e0b4c',1,'ir_Daikin.h']]], + ['kdaikinstatelength_1247',['kDaikinStateLength',['../IRremoteESP8266_8h.html#af1fda5b9f355e526dc66cf58824315a7',1,'IRremoteESP8266.h']]], + ['kdaikinstatelengthshort_1248',['kDaikinStateLengthShort',['../IRremoteESP8266_8h.html#ae94c897cb0bd25ca7a4d693c7be9be3d',1,'IRremoteESP8266.h']]], + ['kdaikinswingoff_1249',['kDaikinSwingOff',['../ir__Daikin_8h.html#abc9194f48f63632b87c6139dd8ab6ecf',1,'ir_Daikin.h']]], + ['kdaikinswingoffset_1250',['kDaikinSwingOffset',['../ir__Daikin_8h.html#abeac0c8df9be90fc5b28db4b2284ed10',1,'ir_Daikin.h']]], + ['kdaikinswingon_1251',['kDaikinSwingOn',['../ir__Daikin_8h.html#af19ec29dc79837deca05f6061f2e6524',1,'ir_Daikin.h']]], + ['kdaikinswingsize_1252',['kDaikinSwingSize',['../ir__Daikin_8h.html#a0f7daf6ef2652bc0be591caa2fa0fad6',1,'ir_Daikin.h']]], + ['kdaikintempoffset_1253',['kDaikinTempOffset',['../ir__Daikin_8h.html#a1a38843bdf0f65f29c21b301f6f45ba5',1,'ir_Daikin.h']]], + ['kdaikintempsize_1254',['kDaikinTempSize',['../ir__Daikin_8h.html#aa2eef2bb403846d88df5387912af0a00',1,'ir_Daikin.h']]], + ['kdaikintolerance_1255',['kDaikinTolerance',['../ir__Daikin_8h.html#aea3938d1522df0040ddb9775075d6669',1,'ir_Daikin.h']]], + ['kdaikinunusedtime_1256',['kDaikinUnusedTime',['../ir__Daikin_8h.html#af60d27bb9d08317498b35f62c167f6a4',1,'ir_Daikin.h']]], + ['kdaikinzerospace_1257',['kDaikinZeroSpace',['../ir__Daikin_8h.html#ace5b2c2be3b58f22248eafb2148d059c',1,'ir_Daikin.h']]], + ['kdaysstr_1258',['kDaysStr',['../IRtext_8cpp.html#a4269111ae41c3a673ec0a87fca0fd78b',1,'kDaysStr(): IRtext.cpp'],['../IRtext_8h.html#aa779ae24412ef82ee3d1eade3f0381ae',1,'kDaysStr(): IRtext.cpp']]], + ['kdaystr_1259',['kDayStr',['../IRtext_8cpp.html#ab6fb8803c6a95d1926abb56b7ecb2e09',1,'kDayStr(): IRtext.cpp'],['../IRtext_8h.html#adb64531a5054629613696f9af39420e2',1,'kDayStr(): IRtext.cpp']]], + ['kdefaultesp32timer_1260',['kDefaultESP32Timer',['../IRrecv_8h.html#a80a2d3445a1752d18caf307d7677b709',1,'IRrecv.h']]], + ['kdefaultmessagegap_1261',['kDefaultMessageGap',['../IRsend_8h.html#ad49e9828319afbad49fd5082c50ef4a7',1,'IRsend.h']]], + ['kdelonghiacauto_1262',['kDelonghiAcAuto',['../ir__Delonghi_8h.html#ab10d4fe0b9dbe99ed942b73a6ff61d37',1,'ir_Delonghi.h']]], + ['kdelonghiacbitmark_1263',['kDelonghiAcBitMark',['../ir__Delonghi_8cpp.html#aa70f02d16b78f513e245871d4db0785a',1,'ir_Delonghi.cpp']]], + ['kdelonghiacbits_1264',['kDelonghiAcBits',['../IRremoteESP8266_8h.html#a7b9fba82b602cf38147f0586e037f909',1,'IRremoteESP8266.h']]], + ['kdelonghiacboostbit_1265',['kDelonghiAcBoostBit',['../ir__Delonghi_8h.html#a52c86741107eb5e33780f78fbf5667d5',1,'ir_Delonghi.h']]], + ['kdelonghiacchecksumoffset_1266',['kDelonghiAcChecksumOffset',['../ir__Delonghi_8h.html#a4b5e3d9874b016f60b7f9c26e7cf0cfd',1,'ir_Delonghi.h']]], + ['kdelonghiacchecksumsize_1267',['kDelonghiAcChecksumSize',['../ir__Delonghi_8h.html#a376acfc72923eccd3a1a9cc04453c0fc',1,'ir_Delonghi.h']]], + ['kdelonghiaccool_1268',['kDelonghiAcCool',['../ir__Delonghi_8h.html#a9447cc3a3f6f4e0603ecc99104523119',1,'ir_Delonghi.h']]], + ['kdelonghiacdefaultrepeat_1269',['kDelonghiAcDefaultRepeat',['../IRremoteESP8266_8h.html#a8f18256a0a6893e077e253e5e80da164',1,'IRremoteESP8266.h']]], + ['kdelonghiacdry_1270',['kDelonghiAcDry',['../ir__Delonghi_8h.html#a1c83f080ac1f48548fcfa5d691ef893d',1,'ir_Delonghi.h']]], + ['kdelonghiacfan_1271',['kDelonghiAcFan',['../ir__Delonghi_8h.html#af494534acfb8ae1c0f9c15bc13e2d0c8',1,'ir_Delonghi.h']]], + ['kdelonghiacfanauto_1272',['kDelonghiAcFanAuto',['../ir__Delonghi_8h.html#adf2286936d79d8c899283fa6e3838ebb',1,'ir_Delonghi.h']]], + ['kdelonghiacfanhigh_1273',['kDelonghiAcFanHigh',['../ir__Delonghi_8h.html#a03027eb1a6a382479b44db0699aee30b',1,'ir_Delonghi.h']]], + ['kdelonghiacfanlow_1274',['kDelonghiAcFanLow',['../ir__Delonghi_8h.html#a053a51021679cd5c4720e7ec68fa43eb',1,'ir_Delonghi.h']]], + ['kdelonghiacfanmedium_1275',['kDelonghiAcFanMedium',['../ir__Delonghi_8h.html#ac748c5e0b7c5acb108086f90c088028f',1,'ir_Delonghi.h']]], + ['kdelonghiacfanoffset_1276',['kDelonghiAcFanOffset',['../ir__Delonghi_8h.html#ab9ff55f2717de8401a940b6afd4c13d6',1,'ir_Delonghi.h']]], + ['kdelonghiacfansize_1277',['kDelonghiAcFanSize',['../ir__Delonghi_8h.html#adc3ed20ff78231b8ac2eb82481d3ebb2',1,'ir_Delonghi.h']]], + ['kdelonghiacfreq_1278',['kDelonghiAcFreq',['../ir__Delonghi_8cpp.html#a9425e4f71aa6454a89b55f3b5789d94d',1,'ir_Delonghi.cpp']]], + ['kdelonghiacgap_1279',['kDelonghiAcGap',['../ir__Delonghi_8cpp.html#ab1cd2481fc96811ed822c8c9f63420c3',1,'ir_Delonghi.cpp']]], + ['kdelonghiachdrmark_1280',['kDelonghiAcHdrMark',['../ir__Delonghi_8cpp.html#a0feead944883173788b8d02b7ae94ef8',1,'ir_Delonghi.cpp']]], + ['kdelonghiachdrspace_1281',['kDelonghiAcHdrSpace',['../ir__Delonghi_8cpp.html#a606ea96746b1b6471b1d76f05bdc7e5a',1,'ir_Delonghi.cpp']]], + ['kdelonghiachourssize_1282',['kDelonghiAcHoursSize',['../ir__Delonghi_8h.html#a94e0d6ed9ba66c467d9fb4467ab4e512',1,'ir_Delonghi.h']]], + ['kdelonghiacminssize_1283',['kDelonghiAcMinsSize',['../ir__Delonghi_8h.html#a91ed842a356878349760fe75f6d686b2',1,'ir_Delonghi.h']]], + ['kdelonghiacmodeoffset_1284',['kDelonghiAcModeOffset',['../ir__Delonghi_8h.html#a8044375ad833a12e56974b71ddfc2bc7',1,'ir_Delonghi.h']]], + ['kdelonghiacmodesize_1285',['kDelonghiAcModeSize',['../ir__Delonghi_8h.html#a30dc468cb735389aff3a27846e8a24f1',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerenablebit_1286',['kDelonghiAcOffTimerEnableBit',['../ir__Delonghi_8h.html#a93b8d905151be16f6d0918d6fd8d27e2',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerhoursoffset_1287',['kDelonghiAcOffTimerHoursOffset',['../ir__Delonghi_8h.html#a6d7b8115532bf01ae8c53b2ecbbf223b',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerminsoffset_1288',['kDelonghiAcOffTimerMinsOffset',['../ir__Delonghi_8h.html#a47b2f9c730c23d2c117141653622e04b',1,'ir_Delonghi.h']]], + ['kdelonghiaconespace_1289',['kDelonghiAcOneSpace',['../ir__Delonghi_8cpp.html#a8805fdc60cd3537ba2d94038610a3490',1,'ir_Delonghi.cpp']]], + ['kdelonghiacontimerenablebit_1290',['kDelonghiAcOnTimerEnableBit',['../ir__Delonghi_8h.html#a56d225e53ffcc29c486fce295ff3295b',1,'ir_Delonghi.h']]], + ['kdelonghiacontimerhoursoffset_1291',['kDelonghiAcOnTimerHoursOffset',['../ir__Delonghi_8h.html#a310b01f1ba238a8342261c01f77f0234',1,'ir_Delonghi.h']]], + ['kdelonghiacontimerminsoffset_1292',['kDelonghiAcOnTimerMinsOffset',['../ir__Delonghi_8h.html#a37d9a33640b64833daeb1ccc4e209be1',1,'ir_Delonghi.h']]], + ['kdelonghiacoverhead_1293',['kDelonghiAcOverhead',['../ir__Delonghi_8cpp.html#ac265c123c0cd7492d26f030d129f3475',1,'ir_Delonghi.cpp']]], + ['kdelonghiacpowerbit_1294',['kDelonghiAcPowerBit',['../ir__Delonghi_8h.html#ac89b7d74aaf3d4beaa21849085d2d7e3',1,'ir_Delonghi.h']]], + ['kdelonghiacsleepbit_1295',['kDelonghiAcSleepBit',['../ir__Delonghi_8h.html#aa1f75ea73bac50c6645625393b137391',1,'ir_Delonghi.h']]], + ['kdelonghiactempautodrymode_1296',['kDelonghiAcTempAutoDryMode',['../ir__Delonghi_8h.html#add6f728d2746a089e00a35644d664a6c',1,'ir_Delonghi.h']]], + ['kdelonghiactempfanmode_1297',['kDelonghiAcTempFanMode',['../ir__Delonghi_8h.html#a120ae31fac35c33214317c3187aae15c',1,'ir_Delonghi.h']]], + ['kdelonghiactempmaxc_1298',['kDelonghiAcTempMaxC',['../ir__Delonghi_8h.html#a476922b8d240c46cf092897f6c701e87',1,'ir_Delonghi.h']]], + ['kdelonghiactempmaxf_1299',['kDelonghiAcTempMaxF',['../ir__Delonghi_8h.html#abc11f81bc221aa3789258b7a990633b3',1,'ir_Delonghi.h']]], + ['kdelonghiactempminc_1300',['kDelonghiAcTempMinC',['../ir__Delonghi_8h.html#ad31267284f7dd8f533fc978ed7e92428',1,'ir_Delonghi.h']]], + ['kdelonghiactempminf_1301',['kDelonghiAcTempMinF',['../ir__Delonghi_8h.html#a0311abab5eff5a8c47261db8e3d40ed5',1,'ir_Delonghi.h']]], + ['kdelonghiactempoffset_1302',['kDelonghiAcTempOffset',['../ir__Delonghi_8h.html#a9d02f6520d6d1d7e305ea651099cc9ef',1,'ir_Delonghi.h']]], + ['kdelonghiactempsize_1303',['kDelonghiAcTempSize',['../ir__Delonghi_8h.html#a3fb467e0d2385893c8c7a8daa0505ec1',1,'ir_Delonghi.h']]], + ['kdelonghiactempunitbit_1304',['kDelonghiAcTempUnitBit',['../ir__Delonghi_8h.html#ac9e6f419569558f4bd5f5a6e10d24bb6',1,'ir_Delonghi.h']]], + ['kdelonghiactimermax_1305',['kDelonghiAcTimerMax',['../ir__Delonghi_8h.html#a44d3f0d850c5cd5ad8c0e2dc7c2bd860',1,'ir_Delonghi.h']]], + ['kdelonghiaczerospace_1306',['kDelonghiAcZeroSpace',['../ir__Delonghi_8cpp.html#a4c1a9a70a50c7da9aa6cf91af85c695e',1,'ir_Delonghi.cpp']]], + ['kdenon48bits_1307',['kDenon48Bits',['../IRremoteESP8266_8h.html#ad7389b5b4f01a16dbf940eaae005c805',1,'IRremoteESP8266.h']]], + ['kdenonbitmark_1308',['kDenonBitMark',['../ir__Denon_8cpp.html#a1cd978061cfdc9bf1d5e1142dad86e59',1,'ir_Denon.cpp']]], + ['kdenonbitmarkticks_1309',['kDenonBitMarkTicks',['../ir__Denon_8cpp.html#ae6dddc89296abc186ac524c3f1efbe63',1,'ir_Denon.cpp']]], + ['kdenonbits_1310',['kDenonBits',['../IRremoteESP8266_8h.html#a29160117e25f3dfc1cb899a4a53bc238',1,'IRremoteESP8266.h']]], + ['kdenonhdrmark_1311',['kDenonHdrMark',['../ir__Denon_8cpp.html#a6f7b5da8c723615200109f425df72254',1,'ir_Denon.cpp']]], + ['kdenonhdrmarkticks_1312',['kDenonHdrMarkTicks',['../ir__Denon_8cpp.html#a484a90cdd15de164c931f1c70ab02938',1,'ir_Denon.cpp']]], + ['kdenonhdrspace_1313',['kDenonHdrSpace',['../ir__Denon_8cpp.html#a758b11259a5dcab3e949739cf67106be',1,'ir_Denon.cpp']]], + ['kdenonhdrspaceticks_1314',['kDenonHdrSpaceTicks',['../ir__Denon_8cpp.html#afe6cb1be37dcea0251ebf0fc43640fe1',1,'ir_Denon.cpp']]], + ['kdenonlegacybits_1315',['kDenonLegacyBits',['../IRremoteESP8266_8h.html#aacf2eea1349016ccbc96e97a0976f4ec',1,'IRremoteESP8266.h']]], + ['kdenonmanufacturer_1316',['kDenonManufacturer',['../ir__Denon_8cpp.html#abd89138765e21d25991fd5857506491b',1,'ir_Denon.cpp']]], + ['kdenonmincommandlengthticks_1317',['kDenonMinCommandLengthTicks',['../ir__Denon_8cpp.html#abb20f9f6053e0d46399011de71697a6a',1,'ir_Denon.cpp']]], + ['kdenonmingap_1318',['kDenonMinGap',['../ir__Denon_8cpp.html#a19b3fe79e06b3ece2cb167d5e14b2c11',1,'ir_Denon.cpp']]], + ['kdenonmingapticks_1319',['kDenonMinGapTicks',['../ir__Denon_8cpp.html#a191e0cfcf8167805ef9bfdc05463c313',1,'ir_Denon.cpp']]], + ['kdenononespace_1320',['kDenonOneSpace',['../ir__Denon_8cpp.html#a150b22eeeb64b59a3d9df51904fdda3f',1,'ir_Denon.cpp']]], + ['kdenononespaceticks_1321',['kDenonOneSpaceTicks',['../ir__Denon_8cpp.html#ad15a88b8f6b953918799eac1e814d107',1,'ir_Denon.cpp']]], + ['kdenontick_1322',['kDenonTick',['../ir__Denon_8cpp.html#a6cc0eba04ca4a2362068bf47d1869752',1,'ir_Denon.cpp']]], + ['kdenonzerospace_1323',['kDenonZeroSpace',['../ir__Denon_8cpp.html#ad8f53f000727e66938d086eadb5bf6eb',1,'ir_Denon.cpp']]], + ['kdenonzerospaceticks_1324',['kDenonZeroSpaceTicks',['../ir__Denon_8cpp.html#aed0c86367586cd043d8381499b3a4bdd',1,'ir_Denon.cpp']]], + ['kdishbitmark_1325',['kDishBitMark',['../ir__Dish_8cpp.html#aabe7f9815a2f5e65558b0f482e2ac50e',1,'ir_Dish.cpp']]], + ['kdishbitmarkticks_1326',['kDishBitMarkTicks',['../ir__Dish_8cpp.html#a1cfd9b730c78aac35f6c2cb56367c7bb',1,'ir_Dish.cpp']]], + ['kdishbits_1327',['kDishBits',['../IRremoteESP8266_8h.html#aea0cc15e1c7a6edcd6b60d9ac62d4831',1,'IRremoteESP8266.h']]], + ['kdishhdrmark_1328',['kDishHdrMark',['../ir__Dish_8cpp.html#ac4311aaed27b1f37a41a2a9cced0ecc5',1,'ir_Dish.cpp']]], + ['kdishhdrmarkticks_1329',['kDishHdrMarkTicks',['../ir__Dish_8cpp.html#a8dce19ee6e3a6859bd2d43c0c9e90517',1,'ir_Dish.cpp']]], + ['kdishhdrspace_1330',['kDishHdrSpace',['../ir__Dish_8cpp.html#ac68dfa9e554c919fd51b379621b2fbc4',1,'ir_Dish.cpp']]], + ['kdishhdrspaceticks_1331',['kDishHdrSpaceTicks',['../ir__Dish_8cpp.html#ab212535e169722d7f23b461b011400c2',1,'ir_Dish.cpp']]], + ['kdishminrepeat_1332',['kDishMinRepeat',['../IRremoteESP8266_8h.html#a5c2263819b032e3af4d416ab41126bd8',1,'IRremoteESP8266.h']]], + ['kdishonespace_1333',['kDishOneSpace',['../ir__Dish_8cpp.html#a6f1986377a4571c8eba5f401b772c194',1,'ir_Dish.cpp']]], + ['kdishonespaceticks_1334',['kDishOneSpaceTicks',['../ir__Dish_8cpp.html#ade25414e4747c56303752060d9f89446',1,'ir_Dish.cpp']]], + ['kdishrptspace_1335',['kDishRptSpace',['../ir__Dish_8cpp.html#a67628a3581fe85638f72711581ec0e42',1,'ir_Dish.cpp']]], + ['kdishrptspaceticks_1336',['kDishRptSpaceTicks',['../ir__Dish_8cpp.html#a801af68fd07720f74abcf2712e3228dd',1,'ir_Dish.cpp']]], + ['kdishtick_1337',['kDishTick',['../ir__Dish_8cpp.html#aa1eccae3b18a457c7cec248d483e808a',1,'ir_Dish.cpp']]], + ['kdishzerospace_1338',['kDishZeroSpace',['../ir__Dish_8cpp.html#acde5c5a789af871f7b5aacdf3f0efeb7',1,'ir_Dish.cpp']]], + ['kdishzerospaceticks_1339',['kDishZeroSpaceTicks',['../ir__Dish_8cpp.html#a68a0f2b9e2e457c8a58fa533e0ca5336',1,'ir_Dish.cpp']]], + ['kdisplaytempstr_1340',['kDisplayTempStr',['../IRtext_8cpp.html#a018814e961b4eb51b91680db3be7d17c',1,'kDisplayTempStr(): IRtext.cpp'],['../IRtext_8h.html#a98f3ba92617c82c9091f155eebcdb3f3',1,'kDisplayTempStr(): IRtext.cpp']]], + ['kdoshishabitmark_1341',['kDoshishaBitMark',['../ir__Doshisha_8cpp.html#a50a4feaff92c4a9fbba6128638fdb2fb',1,'ir_Doshisha.cpp']]], + ['kdoshishabits_1342',['kDoshishaBits',['../IRremoteESP8266_8h.html#aedc53534cf6a40144be80abeee498362',1,'IRremoteESP8266.h']]], + ['kdoshishahdrmark_1343',['kDoshishaHdrMark',['../ir__Doshisha_8cpp.html#adbfc15a1abb62540538afc9c645c1875',1,'ir_Doshisha.cpp']]], + ['kdoshishahdrspace_1344',['kDoshishaHdrSpace',['../ir__Doshisha_8cpp.html#a95a58b09fde0ee9ba59fcf838d16f736',1,'ir_Doshisha.cpp']]], + ['kdoshishaonespace_1345',['kDoshishaOneSpace',['../ir__Doshisha_8cpp.html#a48f3b70ddd3bc06c628ebe7ce29e74d3',1,'ir_Doshisha.cpp']]], + ['kdoshishazerospace_1346',['kDoshishaZeroSpace',['../ir__Doshisha_8cpp.html#a055ae27320600bc7e100ea7e147775f9',1,'ir_Doshisha.cpp']]], + ['kdownstr_1347',['kDownStr',['../IRtext_8cpp.html#a24998688cbbe54780843983394e925e5',1,'kDownStr(): IRtext.cpp'],['../IRtext_8h.html#a1f452a2ac1a2b89b9c71cf64c177f6bd',1,'kDownStr(): IRtext.cpp']]], + ['kdry_1348',['kDry',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa0d254f21cc940f41cf7cc1c8ff46ce1f',1,'stdAc']]], + ['kdrystr_1349',['kDryStr',['../IRtext_8cpp.html#a149780a7bbdd13757ee4336c281ccd9d',1,'kDryStr(): IRtext.cpp'],['../IRtext_8h.html#aa0f25fa3aa8d26f4635c38e563a974f5',1,'kDryStr(): IRtext.cpp']]], + ['kdutydefault_1350',['kDutyDefault',['../IRsend_8h.html#affa33c170fe058b783372852fca7cc5b',1,'IRsend.h']]], + ['kdutymax_1351',['kDutyMax',['../IRsend_8h.html#ac076e3f79a3d8d2dae9fc248a6f571e2',1,'IRsend.h']]], + ['keconostr_1352',['kEconoStr',['../IRtext_8cpp.html#a4e3bee67564fe8f13d1d4f997924f464',1,'kEconoStr(): IRtext.cpp'],['../IRtext_8h.html#ab0b71c4429416a581a393f07e898bade',1,'kEconoStr(): IRtext.cpp']]], + ['kelectraacauto_1353',['kElectraAcAuto',['../ir__Electra_8h.html#a536965f5003a474d68860005883afb5a',1,'ir_Electra.h']]], + ['kelectraacbitmark_1354',['kElectraAcBitMark',['../ir__Electra_8cpp.html#a41f7254b061b099b8131ec4d2a775116',1,'ir_Electra.cpp']]], + ['kelectraacbits_1355',['kElectraAcBits',['../IRremoteESP8266_8h.html#aa46876681f26ccf39c6d341fef041a16',1,'IRremoteESP8266.h']]], + ['kelectraaccleanoffset_1356',['kElectraAcCleanOffset',['../ir__Electra_8h.html#a466b5c998c1e2736214f816f1bab8239',1,'ir_Electra.h']]], + ['kelectraaccool_1357',['kElectraAcCool',['../ir__Electra_8h.html#a6a37f4e24aad54a982994599a1bca59d',1,'ir_Electra.h']]], + ['kelectraacdry_1358',['kElectraAcDry',['../ir__Electra_8h.html#a9b8636631c22e003072bf84a9e30ddff',1,'ir_Electra.h']]], + ['kelectraacfan_1359',['kElectraAcFan',['../ir__Electra_8h.html#a28047c7d083d8bc9d9e34ab210c28185',1,'ir_Electra.h']]], + ['kelectraacfanauto_1360',['kElectraAcFanAuto',['../ir__Electra_8h.html#a48b3067393d4dc1e3461db4535212bff',1,'ir_Electra.h']]], + ['kelectraacfanhigh_1361',['kElectraAcFanHigh',['../ir__Electra_8h.html#a5cbf3118669f056f377b4625e8e97d8c',1,'ir_Electra.h']]], + ['kelectraacfanlow_1362',['kElectraAcFanLow',['../ir__Electra_8h.html#a9a5663e86cb766a4e4579d1b81473c44',1,'ir_Electra.h']]], + ['kelectraacfanmed_1363',['kElectraAcFanMed',['../ir__Electra_8h.html#a4e906bcb7aa6c0fc5c71bd06c43c3993',1,'ir_Electra.h']]], + ['kelectraacfanoffset_1364',['kElectraAcFanOffset',['../ir__Electra_8h.html#a0efe73807b12370aa7c57ff831e56192',1,'ir_Electra.h']]], + ['kelectraacfansize_1365',['kElectraAcFanSize',['../ir__Electra_8h.html#aeb9bddbd47459ae51c1207baac9e6219',1,'ir_Electra.h']]], + ['kelectraachdrmark_1366',['kElectraAcHdrMark',['../ir__Electra_8cpp.html#a1200826684547765f1e526f362408e2e',1,'ir_Electra.cpp']]], + ['kelectraachdrspace_1367',['kElectraAcHdrSpace',['../ir__Electra_8cpp.html#a28cd57057c52b0def3683e71ee92c5d3',1,'ir_Electra.cpp']]], + ['kelectraacheat_1368',['kElectraAcHeat',['../ir__Electra_8h.html#af764a4738f146b752b8e29357af257e3',1,'ir_Electra.h']]], + ['kelectraaclighttogglemask_1369',['kElectraAcLightToggleMask',['../ir__Electra_8h.html#aa51ccef46052dd988ac1bccc4f2303f6',1,'ir_Electra.h']]], + ['kelectraaclighttoggleoff_1370',['kElectraAcLightToggleOff',['../ir__Electra_8h.html#ae98c4a00f003cc98c253b9367226c5c5',1,'ir_Electra.h']]], + ['kelectraaclighttoggleon_1371',['kElectraAcLightToggleOn',['../ir__Electra_8h.html#aa9ca231e98b7e529b081c3aaa1876df9',1,'ir_Electra.h']]], + ['kelectraacmaxtemp_1372',['kElectraAcMaxTemp',['../ir__Electra_8h.html#a3962ca1ae42f006baa1181683cbcbf86',1,'ir_Electra.h']]], + ['kelectraacmessagegap_1373',['kElectraAcMessageGap',['../ir__Electra_8cpp.html#adbcde2296ebf6ea93c7c95ce6d0b264e',1,'ir_Electra.cpp']]], + ['kelectraacminrepeat_1374',['kElectraAcMinRepeat',['../IRremoteESP8266_8h.html#a2ca237d578ca9a59aecac9813ab851ba',1,'IRremoteESP8266.h']]], + ['kelectraacmintemp_1375',['kElectraAcMinTemp',['../ir__Electra_8h.html#ad6f62477d70b59c958ba347c228f8e2b',1,'ir_Electra.h']]], + ['kelectraacmodeoffset_1376',['kElectraAcModeOffset',['../ir__Electra_8h.html#a79ea9dfa776115e5ec4ee816c4eef559',1,'ir_Electra.h']]], + ['kelectraaconespace_1377',['kElectraAcOneSpace',['../ir__Electra_8cpp.html#aeb59d520635a93f5dd7acdbe4327174d',1,'ir_Electra.cpp']]], + ['kelectraacpoweroffset_1378',['kElectraAcPowerOffset',['../ir__Electra_8h.html#a54012f7683397fada44f13c3e57d9ee0',1,'ir_Electra.h']]], + ['kelectraacstatelength_1379',['kElectraAcStateLength',['../IRremoteESP8266_8h.html#a8fb8c5778feaa94114218c36e8e43641',1,'IRremoteESP8266.h']]], + ['kelectraacswinghoffset_1380',['kElectraAcSwingHOffset',['../ir__Electra_8h.html#ac39219316f9b49ead4183cd206b4a3fb',1,'ir_Electra.h']]], + ['kelectraacswingoff_1381',['kElectraAcSwingOff',['../ir__Electra_8h.html#ade2211d0bd695daf490300db856d660a',1,'ir_Electra.h']]], + ['kelectraacswingon_1382',['kElectraAcSwingOn',['../ir__Electra_8h.html#a4ef75911d929752357d727aee339563e',1,'ir_Electra.h']]], + ['kelectraacswingsize_1383',['kElectraAcSwingSize',['../ir__Electra_8h.html#a67c58c049b50d04d4fadd93eee0231cf',1,'ir_Electra.h']]], + ['kelectraacswingvoffset_1384',['kElectraAcSwingVOffset',['../ir__Electra_8h.html#a4a5737e41994fe6c0cd566be354a70fb',1,'ir_Electra.h']]], + ['kelectraactempdelta_1385',['kElectraAcTempDelta',['../ir__Electra_8h.html#ac3310f7b0d4b9fbe22d7192465669487',1,'ir_Electra.h']]], + ['kelectraactempoffset_1386',['kElectraAcTempOffset',['../ir__Electra_8h.html#a928ee72169f9ab56a4209606aa7e5e43',1,'ir_Electra.h']]], + ['kelectraactempsize_1387',['kElectraAcTempSize',['../ir__Electra_8h.html#aeeb469144f4fd02ddd8a802f5cf7c308',1,'ir_Electra.h']]], + ['kelectraacturbooffset_1388',['kElectraAcTurboOffset',['../ir__Electra_8h.html#afbbd997ef8ddf5a4adfd0a37404d6782',1,'ir_Electra.h']]], + ['kelectraaczerospace_1389',['kElectraAcZeroSpace',['../ir__Electra_8cpp.html#a1453e0796cfe6ca169fd3c56e2595082',1,'ir_Electra.cpp']]], + ['kelvinator_1390',['kelvinator',['../classIRac.html#a6e4d8061841a7271205f81bd8e7d6171',1,'IRac::kelvinator()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab3a52797572065c912c34c976c08c542',1,'KELVINATOR(): IRremoteESP8266.h']]], + ['kepsonbits_1391',['kEpsonBits',['../IRremoteESP8266_8h.html#a77a0ed1143f5bfec87e0c9fde5c2c425',1,'IRremoteESP8266.h']]], + ['kepsonminrepeat_1392',['kEpsonMinRepeat',['../IRremoteESP8266_8h.html#ac8738cb054de937b77269acb973c5133',1,'IRremoteESP8266.h']]], + ['keyeautostr_1393',['kEyeAutoStr',['../IRtext_8cpp.html#ab7c525442638022439c7a277e1edf694',1,'kEyeAutoStr(): IRtext.cpp'],['../IRtext_8h.html#ae1395c08682a2b858261d76b97311f4f',1,'kEyeAutoStr(): IRtext.cpp']]], + ['keyestr_1394',['kEyeStr',['../IRtext_8cpp.html#a1d8dc83e7f15aacd013509e36a49a9d8',1,'kEyeStr(): IRtext.cpp'],['../IRtext_8h.html#a84f6d62456976cc31fe6b1648182a885',1,'kEyeStr(): IRtext.cpp']]], + ['kfalsestr_1395',['kFalseStr',['../IRtext_8cpp.html#a338ee31c8fb5a1c74c0640b279051cd2',1,'kFalseStr(): IRtext.cpp'],['../IRtext_8h.html#a3dc9321c4146369e0e0794e6a4de1988',1,'kFalseStr(): IRtext.cpp']]], + ['kfan_1396',['kFan',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa03b7310c6ec7018a07ee9e3ffb95a34b',1,'stdAc']]], + ['kfanonlystr_1397',['kFanOnlyStr',['../IRtext_8cpp.html#adada7550fa28466a6db6f4544f8c7063',1,'kFanOnlyStr(): IRtext.cpp'],['../IRtext_8h.html#a220378c7b69db06362af5ad932965628',1,'kFanOnlyStr(): IRtext.cpp']]], + ['kfanstr_1398',['kFanStr',['../IRtext_8cpp.html#aaab703dfae684a786852a55c0f7f61ec',1,'kFanStr(): IRtext.cpp'],['../IRtext_8h.html#af7a0d76c40f3173a3e1367665d789300',1,'kFanStr(): IRtext.cpp']]], + ['kfaststr_1399',['kFastStr',['../IRtext_8cpp.html#ad6084cb569cd62bb1199c6ecc8ac4126',1,'kFastStr(): IRtext.cpp'],['../IRtext_8h.html#a82c26d9c7690ce001223e2a7cf8664d8',1,'kFastStr(): IRtext.cpp']]], + ['kfilterstr_1400',['kFilterStr',['../IRtext_8cpp.html#af287ead64de5dc3b1cbafe7bc945e519',1,'kFilterStr(): IRtext.cpp'],['../IRtext_8h.html#a5b3133e24c729077da411e08119033be',1,'kFilterStr(): IRtext.cpp']]], + ['kfixedstr_1401',['kFixedStr',['../IRtext_8cpp.html#ab45f91a889dae134e48c86586608bfc9',1,'kFixedStr(): IRtext.cpp'],['../IRtext_8h.html#ad9112f221a20ab498c5f133c4cea0b14',1,'kFixedStr(): IRtext.cpp']]], + ['kfnvbasis32_1402',['kFnvBasis32',['../IRrecv_8h.html#a04d9b0c909b377b36af3ece668482ca3',1,'IRrecv.h']]], + ['kfnvprime32_1403',['kFnvPrime32',['../IRrecv_8h.html#abcfcce36d3e2faef742aa3529c22f23f',1,'IRrecv.h']]], + ['kfollowstr_1404',['kFollowStr',['../IRtext_8cpp.html#a5477068666c86b3d605df8cf0240c86f',1,'kFollowStr(): IRtext.cpp'],['../IRtext_8h.html#a47a659e1c6373c4af92f4261148f695b',1,'kFollowStr(): IRtext.cpp']]], + ['kfooter_1405',['kFooter',['../IRrecv_8h.html#a5abb2b821f207ee9cf35f889f86d0ea3',1,'IRrecv.h']]], + ['kfreshstr_1406',['kFreshStr',['../IRtext_8cpp.html#ae416979803b912c932aa5eda837fc471',1,'kFreshStr(): IRtext.cpp'],['../IRtext_8h.html#adc8991e424df3ebf2f47ffc2854057f2',1,'kFreshStr(): IRtext.cpp']]], + ['kfujitsuacbitmark_1407',['kFujitsuAcBitMark',['../ir__Fujitsu_8cpp.html#a2e01906b1317da42fcc204284646e3db',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacbits_1408',['kFujitsuAcBits',['../IRremoteESP8266_8h.html#aecd63891cac014d1b7e344638086ad47',1,'IRremoteESP8266.h']]], + ['kfujitsuaccleanoffset_1409',['kFujitsuAcCleanOffset',['../ir__Fujitsu_8h.html#ae7e7dc770ef9712296d2beeb085d2c1f',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdecono_1410',['kFujitsuAcCmdEcono',['../ir__Fujitsu_8h.html#a1e1eb4274232c43769f70b40f395a084',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdpowerful_1411',['kFujitsuAcCmdPowerful',['../ir__Fujitsu_8h.html#a69349537a37674a82b8ca630e6ca1b5a',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstayon_1412',['kFujitsuAcCmdStayOn',['../ir__Fujitsu_8h.html#acc729a2cd570761f97c63b98024c157d',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstephoriz_1413',['kFujitsuAcCmdStepHoriz',['../ir__Fujitsu_8h.html#ac67e3fa9ab8f1e1146bed1296f9a2131',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstepvert_1414',['kFujitsuAcCmdStepVert',['../ir__Fujitsu_8h.html#a5dda60d753d93089fc323bfcd9567afd',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdtoggleswinghoriz_1415',['kFujitsuAcCmdToggleSwingHoriz',['../ir__Fujitsu_8h.html#a43b5912e65a8e6d3f1c672b155135f27',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdtoggleswingvert_1416',['kFujitsuAcCmdToggleSwingVert',['../ir__Fujitsu_8h.html#a66960882cee5d109f332917fe1f8067c',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdturnoff_1417',['kFujitsuAcCmdTurnOff',['../ir__Fujitsu_8h.html#a073903b56c40d89b9999ee9b7dc48f00',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdturnon_1418',['kFujitsuAcCmdTurnOn',['../ir__Fujitsu_8h.html#a51c2abda78c7d6ced59f88acb857281e',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanauto_1419',['kFujitsuAcFanAuto',['../ir__Fujitsu_8h.html#a55bbb5a5b1760515f070d302c9fa4cbb',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanhigh_1420',['kFujitsuAcFanHigh',['../ir__Fujitsu_8h.html#a30b11ea24865a00b10468015aae77886',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanlow_1421',['kFujitsuAcFanLow',['../ir__Fujitsu_8h.html#aa0162cde862a3c02dd877a3a7933c130',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanmed_1422',['kFujitsuAcFanMed',['../ir__Fujitsu_8h.html#a0efcb8e8a6521e4788a82ff6c556b67b',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanquiet_1423',['kFujitsuAcFanQuiet',['../ir__Fujitsu_8h.html#a9abb4ec5fe9f27c6acd62273329490b6',1,'ir_Fujitsu.h']]], + ['kfujitsuacfansize_1424',['kFujitsuAcFanSize',['../ir__Fujitsu_8h.html#a797e68082ceebea788a215ecbfc279d9',1,'ir_Fujitsu.h']]], + ['kfujitsuacfilteroffset_1425',['kFujitsuAcFilterOffset',['../ir__Fujitsu_8h.html#a3c6349b24651bffb33f2633d3c65144c',1,'ir_Fujitsu.h']]], + ['kfujitsuachdrmark_1426',['kFujitsuAcHdrMark',['../ir__Fujitsu_8cpp.html#a96402e0aed6962a8a72cc736fa9bbc08',1,'ir_Fujitsu.cpp']]], + ['kfujitsuachdrspace_1427',['kFujitsuAcHdrSpace',['../ir__Fujitsu_8cpp.html#a655e37e172ab06dc06ca69f3c06223b2',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacmaxtemp_1428',['kFujitsuAcMaxTemp',['../ir__Fujitsu_8h.html#ad817f46441ac1284e3bbe8417e4f4388',1,'ir_Fujitsu.h']]], + ['kfujitsuacminbits_1429',['kFujitsuAcMinBits',['../IRremoteESP8266_8h.html#a025caa6d0ae6becdd5ee58b5ac6ed61f',1,'IRremoteESP8266.h']]], + ['kfujitsuacmingap_1430',['kFujitsuAcMinGap',['../ir__Fujitsu_8cpp.html#a255fab3b9047b34cf6c4d42c0c82c485',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacminrepeat_1431',['kFujitsuAcMinRepeat',['../IRremoteESP8266_8h.html#a9dd52420366167afb4c8831b4ccd02fa',1,'IRremoteESP8266.h']]], + ['kfujitsuacmintemp_1432',['kFujitsuAcMinTemp',['../ir__Fujitsu_8h.html#a35ec9572b356a7bcfb75947d03b198f7',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodeauto_1433',['kFujitsuAcModeAuto',['../ir__Fujitsu_8h.html#acf0aa6d1d033c893a3acd5b8d7756a5b',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodecool_1434',['kFujitsuAcModeCool',['../ir__Fujitsu_8h.html#a782e226fadab0a256144821cacea2314',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodedry_1435',['kFujitsuAcModeDry',['../ir__Fujitsu_8h.html#ae66f2ed2e554a6befdf0377d01bce257',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodefan_1436',['kFujitsuAcModeFan',['../ir__Fujitsu_8h.html#a7cc07ec4747b5cebc50257ec02297800',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodeheat_1437',['kFujitsuAcModeHeat',['../ir__Fujitsu_8h.html#ad9b47b7419853a4cb1cf072023dac69b',1,'ir_Fujitsu.h']]], + ['kfujitsuaconespace_1438',['kFujitsuAcOneSpace',['../ir__Fujitsu_8cpp.html#a4f5246e6428cc701dbaa18923904713a',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacoutsidequietoffset_1439',['kFujitsuAcOutsideQuietOffset',['../ir__Fujitsu_8h.html#a38522dc07bb7be2dd1ec654d4e60eb4f',1,'ir_Fujitsu.h']]], + ['kfujitsuacstatelength_1440',['kFujitsuAcStateLength',['../IRremoteESP8266_8h.html#ac3aa33a8386f73de0f57fc1ff7c6e7d9',1,'IRremoteESP8266.h']]], + ['kfujitsuacstatelengthshort_1441',['kFujitsuAcStateLengthShort',['../IRremoteESP8266_8h.html#a81cb09663eedbdc3888ee68438f0a5d3',1,'IRremoteESP8266.h']]], + ['kfujitsuacswingboth_1442',['kFujitsuAcSwingBoth',['../ir__Fujitsu_8h.html#a07c5a757b0c3bbe07412813807272434',1,'ir_Fujitsu.h']]], + ['kfujitsuacswinghoriz_1443',['kFujitsuAcSwingHoriz',['../ir__Fujitsu_8h.html#a8875f62d61afb8cbf468207aedcb8982',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingoff_1444',['kFujitsuAcSwingOff',['../ir__Fujitsu_8h.html#a7f8109a1b8fd13a93d6b0255d05413df',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingsize_1445',['kFujitsuAcSwingSize',['../ir__Fujitsu_8h.html#a1eb20884dc6c9bccbe899f779c4b5ad4',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingvert_1446',['kFujitsuAcSwingVert',['../ir__Fujitsu_8h.html#a5c532a43ab11bf7cb353de2081260f40',1,'ir_Fujitsu.h']]], + ['kfujitsuaczerospace_1447',['kFujitsuAcZeroSpace',['../ir__Fujitsu_8cpp.html#a3815b89a2037cd0c8d774217df603d6e',1,'ir_Fujitsu.cpp']]], + ['kgicablebitmark_1448',['kGicableBitMark',['../ir__GICable_8cpp.html#ac315be0b5e02fb4c7109a6f67c4fac8e',1,'ir_GICable.cpp']]], + ['kgicablebits_1449',['kGicableBits',['../IRremoteESP8266_8h.html#aceb5cbd7ba5d8bc11560ba29137b10fa',1,'IRremoteESP8266.h']]], + ['kgicablehdrmark_1450',['kGicableHdrMark',['../ir__GICable_8cpp.html#a0388e7a2030246928029ed1c79ba819d',1,'ir_GICable.cpp']]], + ['kgicablehdrspace_1451',['kGicableHdrSpace',['../ir__GICable_8cpp.html#ab357b0a095155eab6206245008387fc0',1,'ir_GICable.cpp']]], + ['kgicablemincommandlength_1452',['kGicableMinCommandLength',['../ir__GICable_8cpp.html#a79db5de95ff6b42259f0a54fa59f46f6',1,'ir_GICable.cpp']]], + ['kgicablemingap_1453',['kGicableMinGap',['../ir__GICable_8cpp.html#aff7027ab4b933e4a7f5506590c25f699',1,'ir_GICable.cpp']]], + ['kgicableminrepeat_1454',['kGicableMinRepeat',['../IRremoteESP8266_8h.html#ad8142649290db6fc337ac839d4078aef',1,'IRremoteESP8266.h']]], + ['kgicableonespace_1455',['kGicableOneSpace',['../ir__GICable_8cpp.html#a31300a6f41363cbc22d40f26e693b8be',1,'ir_GICable.cpp']]], + ['kgicablerptspace_1456',['kGicableRptSpace',['../ir__GICable_8cpp.html#a9e0d82ed05e210dec2980a7d1a2e081b',1,'ir_GICable.cpp']]], + ['kgicablezerospace_1457',['kGicableZeroSpace',['../ir__GICable_8cpp.html#a1383f274e701ad5c8141beb7703783ff',1,'ir_GICable.cpp']]], + ['kglobalcachefreqindex_1458',['kGlobalCacheFreqIndex',['../ir__GlobalCache_8cpp.html#aaa0bdfe1eb76e8519a111b6588a5a3ff',1,'ir_GlobalCache.cpp']]], + ['kglobalcachemaxrepeat_1459',['kGlobalCacheMaxRepeat',['../ir__GlobalCache_8cpp.html#ae4a19c45ab538e8a386769cd98943a0d',1,'ir_GlobalCache.cpp']]], + ['kglobalcacheminusec_1460',['kGlobalCacheMinUsec',['../ir__GlobalCache_8cpp.html#a133cf089a7b40516fac3b1143981b2a6',1,'ir_GlobalCache.cpp']]], + ['kglobalcacherptindex_1461',['kGlobalCacheRptIndex',['../ir__GlobalCache_8cpp.html#ad4d55ed7e89cfc6d513dae6ecb211fe9',1,'ir_GlobalCache.cpp']]], + ['kglobalcacherptstartindex_1462',['kGlobalCacheRptStartIndex',['../ir__GlobalCache_8cpp.html#afde4c65e9e75558df6ac7aa479bf507a',1,'ir_GlobalCache.cpp']]], + ['kglobalcachestartindex_1463',['kGlobalCacheStartIndex',['../ir__GlobalCache_8cpp.html#a8640be7a67ce3f49452b28bc24912637',1,'ir_GlobalCache.cpp']]], + ['kgoodweatherauto_1464',['kGoodweatherAuto',['../ir__Goodweather_8h.html#a2fc5f0f7d0f68dcff193548830f50528',1,'ir_Goodweather.h']]], + ['kgoodweatherbitairflow_1465',['kGoodweatherBitAirFlow',['../ir__Goodweather_8h.html#ad86cdbc34a6a82c7595cace56d040d64',1,'ir_Goodweather.h']]], + ['kgoodweatherbitcommand_1466',['kGoodweatherBitCommand',['../ir__Goodweather_8h.html#ad6973bf4ac7801097077938e133b1718',1,'ir_Goodweather.h']]], + ['kgoodweatherbiteof_1467',['kGoodweatherBitEOF',['../ir__Goodweather_8h.html#a239d4d1fee77e0d220efb0bc0b3c779a',1,'ir_Goodweather.h']]], + ['kgoodweatherbitfan_1468',['kGoodweatherBitFan',['../ir__Goodweather_8h.html#aa3d5f146109dd671e4d7d86c1dbccba7',1,'ir_Goodweather.h']]], + ['kgoodweatherbitlight_1469',['kGoodweatherBitLight',['../ir__Goodweather_8h.html#a976dc2b37d1fcec4bbc0958861b5a9b0',1,'ir_Goodweather.h']]], + ['kgoodweatherbitmark_1470',['kGoodweatherBitMark',['../ir__Goodweather_8h.html#acb9fb47b2a207997fda0244d1bafbe89',1,'ir_Goodweather.h']]], + ['kgoodweatherbitmode_1471',['kGoodweatherBitMode',['../ir__Goodweather_8h.html#a3795b45c06f6d2db23cc45478bfeeca9',1,'ir_Goodweather.h']]], + ['kgoodweatherbitpower_1472',['kGoodweatherBitPower',['../ir__Goodweather_8h.html#a652b820b22c8381a6035fea7b1ae1b8d',1,'ir_Goodweather.h']]], + ['kgoodweatherbits_1473',['kGoodweatherBits',['../IRremoteESP8266_8h.html#afa2675ce42d00175ec95caa6cd87a425',1,'IRremoteESP8266.h']]], + ['kgoodweatherbitsleep_1474',['kGoodweatherBitSleep',['../ir__Goodweather_8h.html#a763e8033483516c093ad12a378e0c8f8',1,'ir_Goodweather.h']]], + ['kgoodweatherbitswing_1475',['kGoodweatherBitSwing',['../ir__Goodweather_8h.html#a0a3fc264b6a77157174c207688ac2cda',1,'ir_Goodweather.h']]], + ['kgoodweatherbittemp_1476',['kGoodweatherBitTemp',['../ir__Goodweather_8h.html#a692faf9976f90d67d183ff99ed06ee51',1,'ir_Goodweather.h']]], + ['kgoodweatherbitturbo_1477',['kGoodweatherBitTurbo',['../ir__Goodweather_8h.html#afe2ad22bc8ba5ab9cad025e9adaf4d56',1,'ir_Goodweather.h']]], + ['kgoodweathercmdairflow_1478',['kGoodweatherCmdAirFlow',['../ir__Goodweather_8h.html#aa51248353573abd95af37e46f0a2c4a7',1,'ir_Goodweather.h']]], + ['kgoodweathercmddowntemp_1479',['kGoodweatherCmdDownTemp',['../ir__Goodweather_8h.html#a8a0b72bf745b6003fb460a3c917eecff',1,'ir_Goodweather.h']]], + ['kgoodweathercmdfan_1480',['kGoodweatherCmdFan',['../ir__Goodweather_8h.html#a4a0881f87af157fdf9ed3d9f342f1ac5',1,'ir_Goodweather.h']]], + ['kgoodweathercmdhold_1481',['kGoodweatherCmdHold',['../ir__Goodweather_8h.html#ac0f3b1413228cb7e86822c5690f20344',1,'ir_Goodweather.h']]], + ['kgoodweathercmdlight_1482',['kGoodweatherCmdLight',['../ir__Goodweather_8h.html#ae70c4e66b17db9caf4800eb57a50706f',1,'ir_Goodweather.h']]], + ['kgoodweathercmdmode_1483',['kGoodweatherCmdMode',['../ir__Goodweather_8h.html#a6042296931ab29e9dfa5a701f3e42175',1,'ir_Goodweather.h']]], + ['kgoodweathercmdpower_1484',['kGoodweatherCmdPower',['../ir__Goodweather_8h.html#a3f1bf85bb10343512bb276adfc64b3b2',1,'ir_Goodweather.h']]], + ['kgoodweathercmdsleep_1485',['kGoodweatherCmdSleep',['../ir__Goodweather_8h.html#a3f4d72b620c73aec68c2125430ca709d',1,'ir_Goodweather.h']]], + ['kgoodweathercmdswing_1486',['kGoodweatherCmdSwing',['../ir__Goodweather_8h.html#ab4ceedbe859811a9fb394f6ebf233cb5',1,'ir_Goodweather.h']]], + ['kgoodweathercmdtimer_1487',['kGoodweatherCmdTimer',['../ir__Goodweather_8h.html#ad4d247ea6c9fc237e0acda84fdaa2eb6',1,'ir_Goodweather.h']]], + ['kgoodweathercmdturbo_1488',['kGoodweatherCmdTurbo',['../ir__Goodweather_8h.html#aebc6d53b3e7d1769bff47968c19c09c9',1,'ir_Goodweather.h']]], + ['kgoodweathercmduptemp_1489',['kGoodweatherCmdUpTemp',['../ir__Goodweather_8h.html#a51a089b03bd72a247a4c35c2ff3f3dc6',1,'ir_Goodweather.h']]], + ['kgoodweathercommandsize_1490',['kGoodweatherCommandSize',['../ir__Goodweather_8h.html#aa5ae9f1b5f6458a25b31b0d2c7feb508',1,'ir_Goodweather.h']]], + ['kgoodweathercool_1491',['kGoodweatherCool',['../ir__Goodweather_8h.html#a92c807d6ff8a3356e65f04e82b99aba4',1,'ir_Goodweather.h']]], + ['kgoodweatherdry_1492',['kGoodweatherDry',['../ir__Goodweather_8h.html#ac5174a3e2c64361c25adcf7caa5b714c',1,'ir_Goodweather.h']]], + ['kgoodweathereofmask_1493',['kGoodweatherEOFMask',['../ir__Goodweather_8h.html#a3d86da1a2bab92a9f70cc88e2628f266',1,'ir_Goodweather.h']]], + ['kgoodweatherextratolerance_1494',['kGoodweatherExtraTolerance',['../ir__Goodweather_8h.html#aae814dfbd574241d3b434d0bf2d38939',1,'ir_Goodweather.h']]], + ['kgoodweatherfan_1495',['kGoodweatherFan',['../ir__Goodweather_8h.html#ad56f00c7e39df93d28419d6a4afa360b',1,'ir_Goodweather.h']]], + ['kgoodweatherfanauto_1496',['kGoodweatherFanAuto',['../ir__Goodweather_8h.html#a9cc119524ac1cb93395dff3bb44b85cc',1,'ir_Goodweather.h']]], + ['kgoodweatherfanhigh_1497',['kGoodweatherFanHigh',['../ir__Goodweather_8h.html#af2b24de50923a0aabd4379dc6d3ef10f',1,'ir_Goodweather.h']]], + ['kgoodweatherfanlow_1498',['kGoodweatherFanLow',['../ir__Goodweather_8h.html#a7bc7c0cf9f2df574a7c087542991ab9b',1,'ir_Goodweather.h']]], + ['kgoodweatherfanmed_1499',['kGoodweatherFanMed',['../ir__Goodweather_8h.html#a5174245e9369a488332b32dfa416963e',1,'ir_Goodweather.h']]], + ['kgoodweatherfansize_1500',['kGoodweatherFanSize',['../ir__Goodweather_8h.html#a687ae6502d8fe6b4a5bd11468106481e',1,'ir_Goodweather.h']]], + ['kgoodweatherhdrmark_1501',['kGoodweatherHdrMark',['../ir__Goodweather_8h.html#a5c39e33226770babb4b0e89fc0cde709',1,'ir_Goodweather.h']]], + ['kgoodweatherhdrspace_1502',['kGoodweatherHdrSpace',['../ir__Goodweather_8h.html#a837bfeaa111b00e2744c4ada89281bfb',1,'ir_Goodweather.h']]], + ['kgoodweatherheat_1503',['kGoodweatherHeat',['../ir__Goodweather_8h.html#a17d223f03df2718151a426582a224a2e',1,'ir_Goodweather.h']]], + ['kgoodweatherminrepeat_1504',['kGoodweatherMinRepeat',['../IRremoteESP8266_8h.html#a885bc5a3a5ba2d8827a62d07a43d0321',1,'IRremoteESP8266.h']]], + ['kgoodweatheronespace_1505',['kGoodweatherOneSpace',['../ir__Goodweather_8h.html#a8efa251085a8f434cb91c049e65cda56',1,'ir_Goodweather.h']]], + ['kgoodweatherstateinit_1506',['kGoodweatherStateInit',['../ir__Goodweather_8h.html#a5ec0e7ca097241d6bef0cbf2135c8fca',1,'ir_Goodweather.h']]], + ['kgoodweatherswingfast_1507',['kGoodweatherSwingFast',['../ir__Goodweather_8h.html#a2d2fa76fa35cf7d450aaf0b980660514',1,'ir_Goodweather.h']]], + ['kgoodweatherswingoff_1508',['kGoodweatherSwingOff',['../ir__Goodweather_8h.html#aa2c53f56daa2820351924d91b542bb67',1,'ir_Goodweather.h']]], + ['kgoodweatherswingsize_1509',['kGoodweatherSwingSize',['../ir__Goodweather_8h.html#a208e47dc4f9e6a85464b4ce3ecaf5c3e',1,'ir_Goodweather.h']]], + ['kgoodweatherswingslow_1510',['kGoodweatherSwingSlow',['../ir__Goodweather_8h.html#ad2c87d849af2c77088ffc533d279aadb',1,'ir_Goodweather.h']]], + ['kgoodweathertempmax_1511',['kGoodweatherTempMax',['../ir__Goodweather_8h.html#abec401548ce2221a9c668318a33a039c',1,'ir_Goodweather.h']]], + ['kgoodweathertempmin_1512',['kGoodweatherTempMin',['../ir__Goodweather_8h.html#a8e76c0ec1bd5e124d9cee5742a2d1cfe',1,'ir_Goodweather.h']]], + ['kgoodweathertempsize_1513',['kGoodweatherTempSize',['../ir__Goodweather_8h.html#a2ef3336be36de4f34940de28cfe195a8',1,'ir_Goodweather.h']]], + ['kgoodweatherzerospace_1514',['kGoodweatherZeroSpace',['../ir__Goodweather_8h.html#a411cbfb812d102daeaf6a83c742f9a9a',1,'ir_Goodweather.h']]], + ['kgpiounused_1515',['kGpioUnused',['../IRac_8h.html#afd817f0bc02c516b6430098dcecde383',1,'IRac.h']]], + ['kgreeauto_1516',['kGreeAuto',['../ir__Gree_8h.html#a65d2d0192a1baff86b859da1018ef2f8',1,'ir_Gree.h']]], + ['kgreebitmark_1517',['kGreeBitMark',['../ir__Gree_8cpp.html#ad7e23346f6d793cc2469e4c8a5650397',1,'ir_Gree.cpp']]], + ['kgreebits_1518',['kGreeBits',['../IRremoteESP8266_8h.html#acadcc5d03e09784642f008d4d2913c7d',1,'IRremoteESP8266.h']]], + ['kgreeblockfooter_1519',['kGreeBlockFooter',['../ir__Gree_8cpp.html#ae6d01cfa7ee2ef6ff27c1ecd7cd9be51',1,'ir_Gree.cpp']]], + ['kgreeblockfooterbits_1520',['kGreeBlockFooterBits',['../ir__Gree_8cpp.html#ae866eef4c729c703597a266917799cbd',1,'ir_Gree.cpp']]], + ['kgreecool_1521',['kGreeCool',['../ir__Gree_8h.html#a1e1eeab696b43864cec66e6485487cea',1,'ir_Gree.h']]], + ['kgreedefaultrepeat_1522',['kGreeDefaultRepeat',['../IRremoteESP8266_8h.html#a6816d2cb11b99a61fb63e6d0928e6706',1,'IRremoteESP8266.h']]], + ['kgreedisplaytempinside_1523',['kGreeDisplayTempInside',['../ir__Gree_8h.html#a7495e5873f63135490090929ed79e994',1,'ir_Gree.h']]], + ['kgreedisplaytempoff_1524',['kGreeDisplayTempOff',['../ir__Gree_8h.html#aa5881910d1c01b816f3ac22ddf0f89a8',1,'ir_Gree.h']]], + ['kgreedisplaytempoffset_1525',['kGreeDisplayTempOffset',['../ir__Gree_8h.html#ab60baff4d0e83964d6e5b23994949a06',1,'ir_Gree.h']]], + ['kgreedisplaytempoutside_1526',['kGreeDisplayTempOutside',['../ir__Gree_8h.html#a737c90e90897053623b15b5579cdb6a1',1,'ir_Gree.h']]], + ['kgreedisplaytempset_1527',['kGreeDisplayTempSet',['../ir__Gree_8h.html#a20f7d0948b158f83655ee4187a104176',1,'ir_Gree.h']]], + ['kgreedisplaytempsize_1528',['kGreeDisplayTempSize',['../ir__Gree_8h.html#aad94a8d5de27b1a46c03c9e3773cf8ec',1,'ir_Gree.h']]], + ['kgreedry_1529',['kGreeDry',['../ir__Gree_8h.html#aa818bcc036988ee24fe0467d128d174f',1,'ir_Gree.h']]], + ['kgreefan_1530',['kGreeFan',['../ir__Gree_8h.html#aa1513ffe43257664f761e4e1a5c2a38f',1,'ir_Gree.h']]], + ['kgreefanauto_1531',['kGreeFanAuto',['../ir__Gree_8h.html#aaad16357e34078257315aad7155b2cd1',1,'ir_Gree.h']]], + ['kgreefanmax_1532',['kGreeFanMax',['../ir__Gree_8h.html#a8753f860f2f503a4a70609fb000654f2',1,'ir_Gree.h']]], + ['kgreefanmed_1533',['kGreeFanMed',['../ir__Gree_8h.html#a674d096a91a5db4b5b7f1b0650c833de',1,'ir_Gree.h']]], + ['kgreefanmin_1534',['kGreeFanMin',['../ir__Gree_8h.html#a34ca09b196c41acc85a4fa0036f3ac3b',1,'ir_Gree.h']]], + ['kgreefanoffset_1535',['kGreeFanOffset',['../ir__Gree_8h.html#a3227e6075f673408577884feb0e6ef10',1,'ir_Gree.h']]], + ['kgreefansize_1536',['kGreeFanSize',['../ir__Gree_8h.html#a8285633b179fbe513c6f8bd2c316e957',1,'ir_Gree.h']]], + ['kgreehdrmark_1537',['kGreeHdrMark',['../ir__Gree_8cpp.html#aaae182fb09bed73e37a5b5d3aee6a5fb',1,'ir_Gree.cpp']]], + ['kgreehdrspace_1538',['kGreeHdrSpace',['../ir__Gree_8cpp.html#a96b50632219c2b5808aea4ee9077b15c',1,'ir_Gree.cpp']]], + ['kgreeheat_1539',['kGreeHeat',['../ir__Gree_8h.html#ada5dac7b789497bf7a434a809d4070f6',1,'ir_Gree.h']]], + ['kgreeifeeloffset_1540',['kGreeIFeelOffset',['../ir__Gree_8h.html#a7253f3b97bade5353a72bfcf2df7976b',1,'ir_Gree.h']]], + ['kgreelightoffset_1541',['kGreeLightOffset',['../ir__Gree_8h.html#ade795164ac467f2547583b9654e2e471',1,'ir_Gree.h']]], + ['kgreemaxtempc_1542',['kGreeMaxTempC',['../ir__Gree_8h.html#a4c01aedfff06ed5a028c40010ad7bfa0',1,'ir_Gree.h']]], + ['kgreemaxtempf_1543',['kGreeMaxTempF',['../ir__Gree_8h.html#a6495898a7a6ddda1473b55820f4b6c44',1,'ir_Gree.h']]], + ['kgreemintempc_1544',['kGreeMinTempC',['../ir__Gree_8h.html#ad127acfc710e281a7b29023c8d1da8f6',1,'ir_Gree.h']]], + ['kgreemintempf_1545',['kGreeMinTempF',['../ir__Gree_8h.html#acf0ecb1b535894e3e790b668333fb66b',1,'ir_Gree.h']]], + ['kgreemsgspace_1546',['kGreeMsgSpace',['../ir__Gree_8cpp.html#a619ed3a2915196ab91d87db2b5a829fd',1,'ir_Gree.cpp']]], + ['kgreeonespace_1547',['kGreeOneSpace',['../ir__Gree_8cpp.html#ab139138084643ea0fca13b28412904e9',1,'ir_Gree.cpp']]], + ['kgreepower1offset_1548',['kGreePower1Offset',['../ir__Gree_8h.html#a300b990aa836926d38dfea0ee99dc295',1,'ir_Gree.h']]], + ['kgreepower2offset_1549',['kGreePower2Offset',['../ir__Gree_8h.html#af29131d47e6cba73682727cd5e8b243d',1,'ir_Gree.h']]], + ['kgreesleepoffset_1550',['kGreeSleepOffset',['../ir__Gree_8h.html#ab715200758a0a4ee2733baf924729132',1,'ir_Gree.h']]], + ['kgreestatelength_1551',['kGreeStateLength',['../IRremoteESP8266_8h.html#a5558b24542873d8475e1ee0e2439839f',1,'IRremoteESP8266.h']]], + ['kgreeswingauto_1552',['kGreeSwingAuto',['../ir__Gree_8h.html#a414a503ad11c1d1d3b68d8b630df1f3a',1,'ir_Gree.h']]], + ['kgreeswingautooffset_1553',['kGreeSwingAutoOffset',['../ir__Gree_8h.html#a60d3de1ba88a6b06c79205116fbd7869',1,'ir_Gree.h']]], + ['kgreeswingdown_1554',['kGreeSwingDown',['../ir__Gree_8h.html#abbe69b966ceb1f9eb60fe9c3fb18088d',1,'ir_Gree.h']]], + ['kgreeswingdownauto_1555',['kGreeSwingDownAuto',['../ir__Gree_8h.html#abc7d7b7de5dd2eb9c0a6ca28827aeb06',1,'ir_Gree.h']]], + ['kgreeswinglastpos_1556',['kGreeSwingLastPos',['../ir__Gree_8h.html#a630cd8fec01f13bfda0fffc1a0e59199',1,'ir_Gree.h']]], + ['kgreeswingmiddle_1557',['kGreeSwingMiddle',['../ir__Gree_8h.html#a12a7caa871f33a5bb83611b4efc7a42b',1,'ir_Gree.h']]], + ['kgreeswingmiddleauto_1558',['kGreeSwingMiddleAuto',['../ir__Gree_8h.html#ac9f85ef5c1bfeac1e4c759742e2d147f',1,'ir_Gree.h']]], + ['kgreeswingmiddledown_1559',['kGreeSwingMiddleDown',['../ir__Gree_8h.html#acad74b8154d73786e093fa215ab800b0',1,'ir_Gree.h']]], + ['kgreeswingmiddleup_1560',['kGreeSwingMiddleUp',['../ir__Gree_8h.html#aefbdd203df5b35eb61be1d0edd712c80',1,'ir_Gree.h']]], + ['kgreeswingsize_1561',['kGreeSwingSize',['../ir__Gree_8h.html#a287e3c06c9a1efbf7091841f2f689968',1,'ir_Gree.h']]], + ['kgreeswingup_1562',['kGreeSwingUp',['../ir__Gree_8h.html#adad431eb1010951fcf77dc4dac6449c6',1,'ir_Gree.h']]], + ['kgreeswingupauto_1563',['kGreeSwingUpAuto',['../ir__Gree_8h.html#a63f04add215785d4ccfe6ccec03d7667',1,'ir_Gree.h']]], + ['kgreetempextradegreefoffset_1564',['kGreeTempExtraDegreeFOffset',['../ir__Gree_8h.html#abbbca05f6971b4bc2d83d4e5bd79854c',1,'ir_Gree.h']]], + ['kgreetempoffset_1565',['kGreeTempOffset',['../ir__Gree_8h.html#a838def81d0f1253e7371fa237f5f0a34',1,'ir_Gree.h']]], + ['kgreetempsize_1566',['kGreeTempSize',['../ir__Gree_8h.html#a15e8555687b1e6bfc47cd4ee4079b700',1,'ir_Gree.h']]], + ['kgreetimerenabledoffset_1567',['kGreeTimerEnabledOffset',['../ir__Gree_8h.html#aec18110852ca714f58734749ef8d4e7d',1,'ir_Gree.h']]], + ['kgreetimerhalfhroffset_1568',['kGreeTimerHalfHrOffset',['../ir__Gree_8h.html#af0779698759e0b6b41bd1f0b77fbddea',1,'ir_Gree.h']]], + ['kgreetimerhoursoffset_1569',['kGreeTimerHoursOffset',['../ir__Gree_8h.html#a1aeba4b3c5bff86b541291ea29220a60',1,'ir_Gree.h']]], + ['kgreetimerhourssize_1570',['kGreeTimerHoursSize',['../ir__Gree_8h.html#af08673b8c795a0c9a710825ceacd6bdb',1,'ir_Gree.h']]], + ['kgreetimermax_1571',['kGreeTimerMax',['../ir__Gree_8h.html#a76048e03908dd0d22cc8cacfbd99a40b',1,'ir_Gree.h']]], + ['kgreetimertenshroffset_1572',['kGreeTimerTensHrOffset',['../ir__Gree_8h.html#a5ca305d48fde5b5c6792c7734b31b941',1,'ir_Gree.h']]], + ['kgreetimertenshrsize_1573',['kGreeTimerTensHrSize',['../ir__Gree_8h.html#a5d8b007e38dcec0327ed0e38705f05c0',1,'ir_Gree.h']]], + ['kgreeturbooffset_1574',['kGreeTurboOffset',['../ir__Gree_8h.html#a5fe9afa8e66edd95a94404abe00dd1f1',1,'ir_Gree.h']]], + ['kgreeusefahrenheitoffset_1575',['kGreeUseFahrenheitOffset',['../ir__Gree_8h.html#a741c43d31a99fd8b723315d9db0724cc',1,'ir_Gree.h']]], + ['kgreewifioffset_1576',['kGreeWiFiOffset',['../ir__Gree_8h.html#a993dede6398a2c4ec2c1e025f4746768',1,'ir_Gree.h']]], + ['kgreexfanoffset_1577',['kGreeXfanOffset',['../ir__Gree_8h.html#a2388c44b2826823349d02dec581da584',1,'ir_Gree.h']]], + ['kgreezerospace_1578',['kGreeZeroSpace',['../ir__Gree_8cpp.html#aa4694ba8ff0e14cd6b9c4730675c385f',1,'ir_Gree.cpp']]], + ['khaieracauto_1579',['kHaierAcAuto',['../ir__Haier_8h.html#ac33a02f63ee77e0d3050598511730865',1,'ir_Haier.h']]], + ['khaieracbitmark_1580',['kHaierAcBitMark',['../ir__Haier_8cpp.html#a4dec38325834c873c03588a8046f0963',1,'ir_Haier.cpp']]], + ['khaieracbits_1581',['kHaierACBits',['../IRremoteESP8266_8h.html#ad44cfa0951c24d1f0c67b2fba997f720',1,'IRremoteESP8266.h']]], + ['khaieraccmdfan_1582',['kHaierAcCmdFan',['../ir__Haier_8h.html#a447818ec7970e2ca09540afe44ecf90d',1,'ir_Haier.h']]], + ['khaieraccmdhealth_1583',['kHaierAcCmdHealth',['../ir__Haier_8h.html#a83cd0b5f307d9ae3ed0a3c6ed8fef94d',1,'ir_Haier.h']]], + ['khaieraccmdmode_1584',['kHaierAcCmdMode',['../ir__Haier_8h.html#a4543aa4ee28323bb9cb5c077f9bf9da1',1,'ir_Haier.h']]], + ['khaieraccmdoff_1585',['kHaierAcCmdOff',['../ir__Haier_8h.html#a96599917176ee244874926d1a530dd7e',1,'ir_Haier.h']]], + ['khaieraccmdon_1586',['kHaierAcCmdOn',['../ir__Haier_8h.html#a83973c2ad2b7b95611c81628c387e0d8',1,'ir_Haier.h']]], + ['khaieraccmdsleep_1587',['kHaierAcCmdSleep',['../ir__Haier_8h.html#abe52b62dd513395f2a8c7d47fa2fc514',1,'ir_Haier.h']]], + ['khaieraccmdswing_1588',['kHaierAcCmdSwing',['../ir__Haier_8h.html#afab164c2aabf39fdc1e956ff88af19d9',1,'ir_Haier.h']]], + ['khaieraccmdtempdown_1589',['kHaierAcCmdTempDown',['../ir__Haier_8h.html#aecc31139b4e45a7784669554c6fdbb54',1,'ir_Haier.h']]], + ['khaieraccmdtempup_1590',['kHaierAcCmdTempUp',['../ir__Haier_8h.html#aab5363f07920971c31d6acf8e70d392c',1,'ir_Haier.h']]], + ['khaieraccmdtimercancel_1591',['kHaierAcCmdTimerCancel',['../ir__Haier_8h.html#ab780da80fc471f004c5b34dc8f347d00',1,'ir_Haier.h']]], + ['khaieraccmdtimerset_1592',['kHaierAcCmdTimerSet',['../ir__Haier_8h.html#a9bd7c081d460a4ae5e3eac977f3916e4',1,'ir_Haier.h']]], + ['khaieraccool_1593',['kHaierAcCool',['../ir__Haier_8h.html#a83cd81ea1115f42a403ea5ee07a32bbb',1,'ir_Haier.h']]], + ['khaieracdefaultrepeat_1594',['kHaierAcDefaultRepeat',['../IRremoteESP8266_8h.html#a882914932449e33933b6f8e224cbaf3c',1,'IRremoteESP8266.h']]], + ['khaieracdeftemp_1595',['kHaierAcDefTemp',['../ir__Haier_8h.html#a86c9e8176fc01e52e883cadcc1d31763',1,'ir_Haier.h']]], + ['khaieracdry_1596',['kHaierAcDry',['../ir__Haier_8h.html#a3d36fbe1308221248f45044e5a671636',1,'ir_Haier.h']]], + ['khaieracfan_1597',['kHaierAcFan',['../ir__Haier_8h.html#af4049629b2139ca82471dfed1e1ced15',1,'ir_Haier.h']]], + ['khaieracfanauto_1598',['kHaierAcFanAuto',['../ir__Haier_8h.html#a8a34e74f7083caa98ed4afc31294539e',1,'ir_Haier.h']]], + ['khaieracfanhigh_1599',['kHaierAcFanHigh',['../ir__Haier_8h.html#aa4d9e45ca5777707778ef78a3284da19',1,'ir_Haier.h']]], + ['khaieracfanlow_1600',['kHaierAcFanLow',['../ir__Haier_8h.html#ae31e878b09284a6730a11e2017cfd7a8',1,'ir_Haier.h']]], + ['khaieracfanmed_1601',['kHaierAcFanMed',['../ir__Haier_8h.html#a5dfa833768e549964aa0bf8a336c32b0',1,'ir_Haier.h']]], + ['khaierachdr_1602',['kHaierAcHdr',['../ir__Haier_8cpp.html#a0f5dbd2eb92f10bc354e6b0a7a074084',1,'ir_Haier.cpp']]], + ['khaierachdrgap_1603',['kHaierAcHdrGap',['../ir__Haier_8cpp.html#a4c3fe62f8e5abf5d084009bbd4c4f878',1,'ir_Haier.cpp']]], + ['khaierachealthbitoffset_1604',['kHaierAcHealthBitOffset',['../ir__Haier_8h.html#ae2e5e80f891c9bbca2844d808b0b3d1b',1,'ir_Haier.h']]], + ['khaieracheat_1605',['kHaierAcHeat',['../ir__Haier_8h.html#a0edb011bdf85197e63a32d37f8517dd2',1,'ir_Haier.h']]], + ['khaierachourssize_1606',['kHaierAcHoursSize',['../ir__Haier_8h.html#a3db7b7dddae84a5d12101c5cdd06975e',1,'ir_Haier.h']]], + ['khaieracmaxtemp_1607',['kHaierAcMaxTemp',['../ir__Haier_8h.html#a925252489fe34d9932151817d0dbe90b',1,'ir_Haier.h']]], + ['khaieracmaxtime_1608',['kHaierAcMaxTime',['../ir__Haier_8h.html#ae04e48e926a7533c3b62f0ff991e1f88',1,'ir_Haier.h']]], + ['khaieracmingap_1609',['kHaierAcMinGap',['../ir__Haier_8cpp.html#a7ab1f44876a931da765b52e4633e5e82',1,'ir_Haier.cpp']]], + ['khaieracminssize_1610',['kHaierAcMinsSize',['../ir__Haier_8h.html#a105e047084515305e896d8ff776d05e6',1,'ir_Haier.h']]], + ['khaieracmintemp_1611',['kHaierAcMinTemp',['../ir__Haier_8h.html#aafd2a4f38ecf78482a5a94e9c6c23f1c',1,'ir_Haier.h']]], + ['khaieracmodeoffset_1612',['kHaierAcModeOffset',['../ir__Haier_8h.html#a93fdbb1742923cf3f738c8078d5660f8',1,'ir_Haier.h']]], + ['khaieracofftimeroffset_1613',['kHaierAcOffTimerOffset',['../ir__Haier_8h.html#ace8cd6ed41c3f247ada91052d653b515',1,'ir_Haier.h']]], + ['khaieraconespace_1614',['kHaierAcOneSpace',['../ir__Haier_8cpp.html#a43739aa786e08fca2a4a62a680b5c38b',1,'ir_Haier.cpp']]], + ['khaieracontimeroffset_1615',['kHaierAcOnTimerOffset',['../ir__Haier_8h.html#a5189092c278fb5c31efd4f539f905da5',1,'ir_Haier.h']]], + ['khaieracprefix_1616',['kHaierAcPrefix',['../ir__Haier_8h.html#a8502c9bea40205e01e6a01b47354272a',1,'ir_Haier.h']]], + ['khaieracsleepbit_1617',['kHaierAcSleepBit',['../ir__Haier_8h.html#ac63b91acdffa55d440b08aee05bda5dc',1,'ir_Haier.h']]], + ['khaieracsleepbitoffset_1618',['kHaierAcSleepBitOffset',['../ir__Haier_8h.html#ad9f4cbfd8e6a5874d661195858156eec',1,'ir_Haier.h']]], + ['khaieracstatelength_1619',['kHaierACStateLength',['../IRremoteESP8266_8h.html#afb4cd0c1a9c689d862e7095f0ab6dbe5',1,'IRremoteESP8266.h']]], + ['khaieracswingchg_1620',['kHaierAcSwingChg',['../ir__Haier_8h.html#af65a92a0b9d29a52ac882d4457e954e8',1,'ir_Haier.h']]], + ['khaieracswingdown_1621',['kHaierAcSwingDown',['../ir__Haier_8h.html#a2cf3a2102c6d4f9aede44efe853ffaa8',1,'ir_Haier.h']]], + ['khaieracswingoff_1622',['kHaierAcSwingOff',['../ir__Haier_8h.html#ac21f78c3cef931154b3fc953bbebc3b4',1,'ir_Haier.h']]], + ['khaieracswingoffset_1623',['kHaierAcSwingOffset',['../ir__Haier_8h.html#a0872af0b2b3f22f6681917b9c81c3bbd',1,'ir_Haier.h']]], + ['khaieracswingsize_1624',['kHaierAcSwingSize',['../ir__Haier_8h.html#ad032725404a02c0e5a93350f20daf6e1',1,'ir_Haier.h']]], + ['khaieracswingup_1625',['kHaierAcSwingUp',['../ir__Haier_8h.html#a4bff8829604ee927dda5cfc54bd6cfe6',1,'ir_Haier.h']]], + ['khaieractimeoffset_1626',['kHaierAcTimeOffset',['../ir__Haier_8h.html#abb7a8ec83d3c0dbbe4d660d6bf627f23',1,'ir_Haier.h']]], + ['khaieracyrw02auto_1627',['kHaierAcYrw02Auto',['../ir__Haier_8h.html#aa025eeba1c344c50cc98334c97a3c174',1,'ir_Haier.h']]], + ['khaieracyrw02bits_1628',['kHaierACYRW02Bits',['../IRremoteESP8266_8h.html#aab346c5ad482113978e5a2cbb7a06f27',1,'IRremoteESP8266.h']]], + ['khaieracyrw02buttonfan_1629',['kHaierAcYrw02ButtonFan',['../ir__Haier_8h.html#a0f9c265510e1e27f38817f08ef9c622b',1,'ir_Haier.h']]], + ['khaieracyrw02buttonhealth_1630',['kHaierAcYrw02ButtonHealth',['../ir__Haier_8h.html#ab1dc6c0a4ed59446bb69c4dd671c78cd',1,'ir_Haier.h']]], + ['khaieracyrw02buttonmode_1631',['kHaierAcYrw02ButtonMode',['../ir__Haier_8h.html#a74466c50b450b08407c9f226a5d657e5',1,'ir_Haier.h']]], + ['khaieracyrw02buttonpower_1632',['kHaierAcYrw02ButtonPower',['../ir__Haier_8h.html#af36b9c628a697f6c596052ecd143d80b',1,'ir_Haier.h']]], + ['khaieracyrw02buttonsleep_1633',['kHaierAcYrw02ButtonSleep',['../ir__Haier_8h.html#a5c7b8ff351e3d0167ec2c897c4820c40',1,'ir_Haier.h']]], + ['khaieracyrw02buttonswing_1634',['kHaierAcYrw02ButtonSwing',['../ir__Haier_8h.html#aa10c558317448783535e96be5876505c',1,'ir_Haier.h']]], + ['khaieracyrw02buttontempdown_1635',['kHaierAcYrw02ButtonTempDown',['../ir__Haier_8h.html#af4a9e5f7f705c331531ea2863dbbd11d',1,'ir_Haier.h']]], + ['khaieracyrw02buttontempup_1636',['kHaierAcYrw02ButtonTempUp',['../ir__Haier_8h.html#a3b24373f9c812f93eca05ee47e61d6e0',1,'ir_Haier.h']]], + ['khaieracyrw02buttonturbo_1637',['kHaierAcYrw02ButtonTurbo',['../ir__Haier_8h.html#ad80547c526b2eba142297715c0a0636d',1,'ir_Haier.h']]], + ['khaieracyrw02cool_1638',['kHaierAcYrw02Cool',['../ir__Haier_8h.html#a30c5d4e61ae3112a8a3e3622eecbb10b',1,'ir_Haier.h']]], + ['khaieracyrw02defaultrepeat_1639',['kHaierAcYrw02DefaultRepeat',['../IRremoteESP8266_8h.html#a62412e221207dbc2660f93dc265b4218',1,'IRremoteESP8266.h']]], + ['khaieracyrw02dry_1640',['kHaierAcYrw02Dry',['../ir__Haier_8h.html#a66cd902f2d35b4c8f66f085a0950a5fc',1,'ir_Haier.h']]], + ['khaieracyrw02fan_1641',['kHaierAcYrw02Fan',['../ir__Haier_8h.html#a35f50f043a2dda75c59507c1ed845b5d',1,'ir_Haier.h']]], + ['khaieracyrw02fanauto_1642',['kHaierAcYrw02FanAuto',['../ir__Haier_8h.html#ad554d38035ac15e4ea8b855802886989',1,'ir_Haier.h']]], + ['khaieracyrw02fanhigh_1643',['kHaierAcYrw02FanHigh',['../ir__Haier_8h.html#ab47bc48ac77fbf6734a41d10f0a53e4a',1,'ir_Haier.h']]], + ['khaieracyrw02fanlow_1644',['kHaierAcYrw02FanLow',['../ir__Haier_8h.html#a9a0a14ab98e1e52b60b9b9bf611c20cc',1,'ir_Haier.h']]], + ['khaieracyrw02fanmed_1645',['kHaierAcYrw02FanMed',['../ir__Haier_8h.html#a65583649324c6039112e7db26d685afc',1,'ir_Haier.h']]], + ['khaieracyrw02fanoffset_1646',['kHaierAcYrw02FanOffset',['../ir__Haier_8h.html#a0910d1996a451c98383124a39ef65f84',1,'ir_Haier.h']]], + ['khaieracyrw02fansize_1647',['kHaierAcYrw02FanSize',['../ir__Haier_8h.html#aa2c6bd47b47e0ea1b51931fec7daef4d',1,'ir_Haier.h']]], + ['khaieracyrw02healthoffset_1648',['kHaierAcYrw02HealthOffset',['../ir__Haier_8h.html#a4bcb42b359472cf770e0710b5369493b',1,'ir_Haier.h']]], + ['khaieracyrw02heat_1649',['kHaierAcYrw02Heat',['../ir__Haier_8h.html#aa0873975b6649294a3c9943130cb7a38',1,'ir_Haier.h']]], + ['khaieracyrw02modeoffset_1650',['kHaierAcYrw02ModeOffset',['../ir__Haier_8h.html#a027199b609d29ead8aec9bb89178cb30',1,'ir_Haier.h']]], + ['khaieracyrw02power_1651',['kHaierAcYrw02Power',['../ir__Haier_8h.html#abe59df7abf20a66107516054f3a2d32b',1,'ir_Haier.h']]], + ['khaieracyrw02poweroffset_1652',['kHaierAcYrw02PowerOffset',['../ir__Haier_8h.html#a67401152b0aa06fb7922bbca743cd600',1,'ir_Haier.h']]], + ['khaieracyrw02prefix_1653',['kHaierAcYrw02Prefix',['../ir__Haier_8h.html#ac62d0f7ca94e064712f8a7a80da2f11e',1,'ir_Haier.h']]], + ['khaieracyrw02sleep_1654',['kHaierAcYrw02Sleep',['../ir__Haier_8h.html#abb70fe8ca6004246345df3d841047252',1,'ir_Haier.h']]], + ['khaieracyrw02sleepoffset_1655',['kHaierAcYrw02SleepOffset',['../ir__Haier_8h.html#ac651bfee5d261124700c81ec5db184a7',1,'ir_Haier.h']]], + ['khaieracyrw02statelength_1656',['kHaierACYRW02StateLength',['../IRremoteESP8266_8h.html#a8f52b7d4595c117cf0b81ffbd1148cda',1,'IRremoteESP8266.h']]], + ['khaieracyrw02swingauto_1657',['kHaierAcYrw02SwingAuto',['../ir__Haier_8h.html#a95ae88223d910d4d966949241bccff8d',1,'ir_Haier.h']]], + ['khaieracyrw02swingbottom_1658',['kHaierAcYrw02SwingBottom',['../ir__Haier_8h.html#aa4b64385da5e9b2a89e15f70cd8c89e9',1,'ir_Haier.h']]], + ['khaieracyrw02swingdown_1659',['kHaierAcYrw02SwingDown',['../ir__Haier_8h.html#aab380411ac07b2b7f67956a5bbc362fb',1,'ir_Haier.h']]], + ['khaieracyrw02swingmiddle_1660',['kHaierAcYrw02SwingMiddle',['../ir__Haier_8h.html#a32d6dd98a050711bf928bf250b769839',1,'ir_Haier.h']]], + ['khaieracyrw02swingoff_1661',['kHaierAcYrw02SwingOff',['../ir__Haier_8h.html#a62570c15418cf24a94c92b162967f892',1,'ir_Haier.h']]], + ['khaieracyrw02swingtop_1662',['kHaierAcYrw02SwingTop',['../ir__Haier_8h.html#adf10f1bc1b293c684232cb6398631f70',1,'ir_Haier.h']]], + ['khaieracyrw02turbohigh_1663',['kHaierAcYrw02TurboHigh',['../ir__Haier_8h.html#ab096c15c69f242b99fbc1e4d7bd7548e',1,'ir_Haier.h']]], + ['khaieracyrw02turbolow_1664',['kHaierAcYrw02TurboLow',['../ir__Haier_8h.html#a19b7f4aee8115eb77267c415d8b3bd82',1,'ir_Haier.h']]], + ['khaieracyrw02turbooff_1665',['kHaierAcYrw02TurboOff',['../ir__Haier_8h.html#aa06ba46287b5806a6373e921cee34a51',1,'ir_Haier.h']]], + ['khaieracyrw02turbooffset_1666',['kHaierAcYrw02TurboOffset',['../ir__Haier_8h.html#a6581fc8ec43b9ac9f877bf27231554bd',1,'ir_Haier.h']]], + ['khaieracyrw02turbosize_1667',['kHaierAcYrw02TurboSize',['../ir__Haier_8h.html#a6ad469ec094d8af5a68cc94a744079bb',1,'ir_Haier.h']]], + ['khaieraczerospace_1668',['kHaierAcZeroSpace',['../ir__Haier_8cpp.html#af2b1a4f27c7b50a1e60ae00bbbec7a16',1,'ir_Haier.cpp']]], + ['kheader_1669',['kHeader',['../IRrecv_8h.html#a0eac186845b9b998a252a3bdfa72e8ed',1,'IRrecv.h']]], + ['khealthstr_1670',['kHealthStr',['../IRtext_8cpp.html#a12474bbd4a7f700c922bcc1de240894f',1,'kHealthStr(): IRtext.cpp'],['../IRtext_8h.html#a7ef833cf90df2c97ef46c5c4b6225a42',1,'kHealthStr(): IRtext.cpp']]], + ['kheat_1671',['kHeat',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444faece059b52386d38cd6da9729cca08b4e',1,'stdAc']]], + ['kheatstr_1672',['kHeatStr',['../IRtext_8cpp.html#a3a16f1dabca01c8f8e5ba1516408ba39',1,'kHeatStr(): IRtext.cpp'],['../IRtext_8h.html#a058df7d2db245e307719d025352d464d',1,'kHeatStr(): IRtext.cpp']]], + ['khigh_1673',['kHigh',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa022f15e910eb36278094efb6e808a07',1,'stdAc::kHigh()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43aa022f15e910eb36278094efb6e808a07',1,'stdAc::kHigh()']]], + ['khighest_1674',['kHighest',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a24d8e31603e486f788826bc24e3a2e1d',1,'stdAc']]], + ['khigheststr_1675',['kHighestStr',['../IRtext_8cpp.html#a219f1d54c5ea75bd5c736efc0d7d7275',1,'kHighestStr(): IRtext.cpp'],['../IRtext_8h.html#ad7706307f507466526b4288e33385bde',1,'kHighestStr(): IRtext.cpp']]], + ['khighnibble_1676',['kHighNibble',['../IRutils_8h.html#a26dd96e82207f707c21e696a60b9c032',1,'IRutils.h']]], + ['khighstr_1677',['kHighStr',['../IRtext_8cpp.html#a127a20ad54e671f48a8faa822ff006f4',1,'kHighStr(): IRtext.cpp'],['../IRtext_8h.html#a5b4ade5e08f30c5e9a61c813bb2046f1',1,'kHighStr(): IRtext.cpp']]], + ['khistr_1678',['kHiStr',['../IRtext_8cpp.html#a7f4994ce51aed70ce6b5b4c88b886466',1,'kHiStr(): IRtext.cpp'],['../IRtext_8h.html#aa6fe661cdd9e2f1dc30d6fee2980cadd',1,'kHiStr(): IRtext.cpp']]], + ['khitachiac1auto_1679',['kHitachiAc1Auto',['../ir__Hitachi_8h.html#a2689ef34702107dc3dce3d1cfa260fc9',1,'ir_Hitachi.h']]], + ['khitachiac1bits_1680',['kHitachiAc1Bits',['../IRremoteESP8266_8h.html#aae6947c431d2c9da4fe2fdd9428012c1',1,'IRremoteESP8266.h']]], + ['khitachiac1checksumstartbyte_1681',['kHitachiAc1ChecksumStartByte',['../ir__Hitachi_8h.html#afafa689c5e922b812f63e08941feb2a7',1,'ir_Hitachi.h']]], + ['khitachiac1cool_1682',['kHitachiAc1Cool',['../ir__Hitachi_8h.html#a1146eda7688843d16094acf7a19a75ac',1,'ir_Hitachi.h']]], + ['khitachiac1dry_1683',['kHitachiAc1Dry',['../ir__Hitachi_8h.html#a82895db5201610844da803bf333102a3',1,'ir_Hitachi.h']]], + ['khitachiac1fan_1684',['kHitachiAc1Fan',['../ir__Hitachi_8h.html#ac5a3ba0e0e4ed02d4792d5a8e6a22654',1,'ir_Hitachi.h']]], + ['khitachiac1fanauto_1685',['kHitachiAc1FanAuto',['../ir__Hitachi_8h.html#a6f9adda7b08ec4b8566ceb4d79966689',1,'ir_Hitachi.h']]], + ['khitachiac1fanbyte_1686',['kHitachiAc1FanByte',['../ir__Hitachi_8h.html#afe6b5951ba3b4e7ad5400f30228d106e',1,'ir_Hitachi.h']]], + ['khitachiac1fanhigh_1687',['kHitachiAc1FanHigh',['../ir__Hitachi_8h.html#ace677cf030da9d74eda0f50d54c91411',1,'ir_Hitachi.h']]], + ['khitachiac1fanlow_1688',['kHitachiAc1FanLow',['../ir__Hitachi_8h.html#a011219de5c0e2ba043a8be6345f8cb05',1,'ir_Hitachi.h']]], + ['khitachiac1fanmed_1689',['kHitachiAc1FanMed',['../ir__Hitachi_8h.html#afbc2a535d85adb80cbcbac63e2432b1a',1,'ir_Hitachi.h']]], + ['khitachiac1fanoffset_1690',['kHitachiAc1FanOffset',['../ir__Hitachi_8h.html#af533c283666d80c0b9348f706909f4c4',1,'ir_Hitachi.h']]], + ['khitachiac1fansize_1691',['kHitachiAc1FanSize',['../ir__Hitachi_8h.html#a2b2a24680efaf1eeaf76dacaabef5c1d',1,'ir_Hitachi.h']]], + ['khitachiac1hdrmark_1692',['kHitachiAc1HdrMark',['../ir__Hitachi_8cpp.html#a2b1891174c78be6f960e92b389d25fe7',1,'ir_Hitachi.cpp']]], + ['khitachiac1hdrspace_1693',['kHitachiAc1HdrSpace',['../ir__Hitachi_8cpp.html#a93f34ee53a375dd7f4ccf82458453701',1,'ir_Hitachi.cpp']]], + ['khitachiac1heat_1694',['kHitachiAc1Heat',['../ir__Hitachi_8h.html#abd5d4db30d6be3b990a74d4481e7eabe',1,'ir_Hitachi.h']]], + ['khitachiac1modebyte_1695',['kHitachiAc1ModeByte',['../ir__Hitachi_8h.html#a57e27b66ff6d471c0dd335b610bc6e24',1,'ir_Hitachi.h']]], + ['khitachiac1model_5fa_1696',['kHitachiAc1Model_A',['../ir__Hitachi_8h.html#a5f8fc3bb000d46705e4530ca0a8f7b60',1,'ir_Hitachi.h']]], + ['khitachiac1model_5fb_1697',['kHitachiAc1Model_B',['../ir__Hitachi_8h.html#a2d894a528c538b8a3922e2500241a55b',1,'ir_Hitachi.h']]], + ['khitachiac1modelbyte_1698',['kHitachiAc1ModelByte',['../ir__Hitachi_8h.html#a2e2a76b8b7decef99cfb7b197e8fb7f7',1,'ir_Hitachi.h']]], + ['khitachiac1modeloffset_1699',['kHitachiAc1ModelOffset',['../ir__Hitachi_8h.html#a8a440a64e6e164511e0976dc5b6585ff',1,'ir_Hitachi.h']]], + ['khitachiac1modelsize_1700',['kHitachiAc1ModelSize',['../ir__Hitachi_8h.html#ab74bbcb475b7eaf33f70dbfdb853d8c3',1,'ir_Hitachi.h']]], + ['khitachiac1modeoffset_1701',['kHitachiAc1ModeOffset',['../ir__Hitachi_8h.html#a3f010fa5ae43ee36771be18659d8bc80',1,'ir_Hitachi.h']]], + ['khitachiac1modesize_1702',['kHitachiAc1ModeSize',['../ir__Hitachi_8h.html#a38b456d96602e83e7832e2a7af75f321',1,'ir_Hitachi.h']]], + ['khitachiac1offtimerhighbyte_1703',['kHitachiAc1OffTimerHighByte',['../ir__Hitachi_8h.html#a36e6b7fc328ee247c11f5779487119b6',1,'ir_Hitachi.h']]], + ['khitachiac1offtimerlowbyte_1704',['kHitachiAc1OffTimerLowByte',['../ir__Hitachi_8h.html#ac8eaedd191009b2ddaf1e047ac6ecf11',1,'ir_Hitachi.h']]], + ['khitachiac1ontimerhighbyte_1705',['kHitachiAc1OnTimerHighByte',['../ir__Hitachi_8h.html#aff6907e9999561abceac42e4cce1dc3b',1,'ir_Hitachi.h']]], + ['khitachiac1ontimerlowbyte_1706',['kHitachiAc1OnTimerLowByte',['../ir__Hitachi_8h.html#a95fef3be6809026b714847c709ba655b',1,'ir_Hitachi.h']]], + ['khitachiac1powerbyte_1707',['kHitachiAc1PowerByte',['../ir__Hitachi_8h.html#acda489ff6137ab3ebfb1795a32e1ec8e',1,'ir_Hitachi.h']]], + ['khitachiac1poweroffset_1708',['kHitachiAc1PowerOffset',['../ir__Hitachi_8h.html#a3fdcd0375b85ac2641d9d5cc6e4770f8',1,'ir_Hitachi.h']]], + ['khitachiac1powertoggleoffset_1709',['kHitachiAc1PowerToggleOffset',['../ir__Hitachi_8h.html#aac994777ce070ad69550229824800ee0',1,'ir_Hitachi.h']]], + ['khitachiac1sleep1_1710',['kHitachiAc1Sleep1',['../ir__Hitachi_8h.html#ab4ca89a9d8c8034e6a3d8ff17b09f3d5',1,'ir_Hitachi.h']]], + ['khitachiac1sleep2_1711',['kHitachiAc1Sleep2',['../ir__Hitachi_8h.html#a1e1a1ea1743b38da6bc6be63fa796689',1,'ir_Hitachi.h']]], + ['khitachiac1sleep3_1712',['kHitachiAc1Sleep3',['../ir__Hitachi_8h.html#a17eaa63f13a3c04aede9f485c310a930',1,'ir_Hitachi.h']]], + ['khitachiac1sleep4_1713',['kHitachiAc1Sleep4',['../ir__Hitachi_8h.html#a21360448a538fbd9491aa9dd28e6c545',1,'ir_Hitachi.h']]], + ['khitachiac1sleepbyte_1714',['kHitachiAc1SleepByte',['../ir__Hitachi_8h.html#ac693a15878e7cdc8e1f575502ea82843',1,'ir_Hitachi.h']]], + ['khitachiac1sleepoff_1715',['kHitachiAc1SleepOff',['../ir__Hitachi_8h.html#a96f87cb3838a1e1aab4b8407dcfc5b78',1,'ir_Hitachi.h']]], + ['khitachiac1sleepoffset_1716',['kHitachiAc1SleepOffset',['../ir__Hitachi_8h.html#a277ca55dbfd35258ea40059bdff62488',1,'ir_Hitachi.h']]], + ['khitachiac1sleepsize_1717',['kHitachiAc1SleepSize',['../ir__Hitachi_8h.html#a199cedd7120057f735ffc640f93a9a1a',1,'ir_Hitachi.h']]], + ['khitachiac1statelength_1718',['kHitachiAc1StateLength',['../IRremoteESP8266_8h.html#abb5e2ddb1a8d3c6fa7a94dbe1989ec5d',1,'IRremoteESP8266.h']]], + ['khitachiac1swingbyte_1719',['kHitachiAc1SwingByte',['../ir__Hitachi_8h.html#a5a283583007b26c1b45d8d7afcd55408',1,'ir_Hitachi.h']]], + ['khitachiac1swinghoffset_1720',['kHitachiAc1SwingHOffset',['../ir__Hitachi_8h.html#ab35d4bb6c17fc5bbcb5385a642476238',1,'ir_Hitachi.h']]], + ['khitachiac1swingtoggleoffset_1721',['kHitachiAc1SwingToggleOffset',['../ir__Hitachi_8h.html#a08eac3b64687e83229648c8664d75dc4',1,'ir_Hitachi.h']]], + ['khitachiac1swingvoffset_1722',['kHitachiAc1SwingVOffset',['../ir__Hitachi_8h.html#af4e410f10812d49175cd419ed678535b',1,'ir_Hitachi.h']]], + ['khitachiac1tempauto_1723',['kHitachiAc1TempAuto',['../ir__Hitachi_8h.html#ad402dff999a97b50b392572899522b6a',1,'ir_Hitachi.h']]], + ['khitachiac1tempbyte_1724',['kHitachiAc1TempByte',['../ir__Hitachi_8h.html#a03185c3b2ddb62d12267da014796da56',1,'ir_Hitachi.h']]], + ['khitachiac1tempdelta_1725',['kHitachiAc1TempDelta',['../ir__Hitachi_8h.html#a279c856a2b4d25651b117a8c654cb48d',1,'ir_Hitachi.h']]], + ['khitachiac1tempoffset_1726',['kHitachiAc1TempOffset',['../ir__Hitachi_8h.html#a8a92aa41be23301229ecec1486714b9a',1,'ir_Hitachi.h']]], + ['khitachiac1tempsize_1727',['kHitachiAc1TempSize',['../ir__Hitachi_8h.html#affb52642edc8f2231f0dc83bc5271885',1,'ir_Hitachi.h']]], + ['khitachiac1timersize_1728',['kHitachiAc1TimerSize',['../ir__Hitachi_8h.html#afd7f469f67f55263b0031b325232751b',1,'ir_Hitachi.h']]], + ['khitachiac2bits_1729',['kHitachiAc2Bits',['../IRremoteESP8266_8h.html#a362a0b0b0afc216cf8162a3724cf073a',1,'IRremoteESP8266.h']]], + ['khitachiac2statelength_1730',['kHitachiAc2StateLength',['../IRremoteESP8266_8h.html#a10377a40053a12e091dbff2869db0352',1,'IRremoteESP8266.h']]], + ['khitachiac344bits_1731',['kHitachiAc344Bits',['../IRremoteESP8266_8h.html#a204fc2410c3d555a37b152a01dceead0',1,'IRremoteESP8266.h']]], + ['khitachiac344buttonfan_1732',['kHitachiAc344ButtonFan',['../ir__Hitachi_8h.html#a5f33b956ec83ee0004785a9c44bd5b0b',1,'ir_Hitachi.h']]], + ['khitachiac344buttonpowermode_1733',['kHitachiAc344ButtonPowerMode',['../ir__Hitachi_8h.html#a3816a8ad86e03f8c5870057e7ad86335',1,'ir_Hitachi.h']]], + ['khitachiac344buttonswingh_1734',['kHitachiAc344ButtonSwingH',['../ir__Hitachi_8h.html#a10dea534868d76d99e91458ee28f5fe9',1,'ir_Hitachi.h']]], + ['khitachiac344buttonswingv_1735',['kHitachiAc344ButtonSwingV',['../ir__Hitachi_8h.html#a95c1b0ee7e3802631f4c2708371e7d34',1,'ir_Hitachi.h']]], + ['khitachiac344buttontempdown_1736',['kHitachiAc344ButtonTempDown',['../ir__Hitachi_8h.html#a05d9bd95037669f1d3743d935471db33',1,'ir_Hitachi.h']]], + ['khitachiac344buttontempup_1737',['kHitachiAc344ButtonTempUp',['../ir__Hitachi_8h.html#a74abf2ce4ed5918bf68f485eff179578',1,'ir_Hitachi.h']]], + ['khitachiac344cool_1738',['kHitachiAc344Cool',['../ir__Hitachi_8h.html#a92d4d8dea34a9387e55852b6b5289328',1,'ir_Hitachi.h']]], + ['khitachiac344dry_1739',['kHitachiAc344Dry',['../ir__Hitachi_8h.html#a37697339ddc2ffaf4ee13b5e140adf2c',1,'ir_Hitachi.h']]], + ['khitachiac344fan_1740',['kHitachiAc344Fan',['../ir__Hitachi_8h.html#a296cd0fc1f414a4e15ce228b5a794bcb',1,'ir_Hitachi.h']]], + ['khitachiac344fanauto_1741',['kHitachiAc344FanAuto',['../ir__Hitachi_8h.html#a6439744edb1ae4dd9e8ea2097fac7a9d',1,'ir_Hitachi.h']]], + ['khitachiac344fanhigh_1742',['kHitachiAc344FanHigh',['../ir__Hitachi_8h.html#a83ea1924948ce9ac8266ab64a41f3ebd',1,'ir_Hitachi.h']]], + ['khitachiac344fanlow_1743',['kHitachiAc344FanLow',['../ir__Hitachi_8h.html#acbbb61fde653c84a8e35865fa724872c',1,'ir_Hitachi.h']]], + ['khitachiac344fanmax_1744',['kHitachiAc344FanMax',['../ir__Hitachi_8h.html#af041ed41027b8e444e3069d9a3481c51',1,'ir_Hitachi.h']]], + ['khitachiac344fanmedium_1745',['kHitachiAc344FanMedium',['../ir__Hitachi_8h.html#aa6d47b5c28f758aa297b345cbf853c9a',1,'ir_Hitachi.h']]], + ['khitachiac344fanmin_1746',['kHitachiAc344FanMin',['../ir__Hitachi_8h.html#ac4bafed10c76739698e9a35183beb970',1,'ir_Hitachi.h']]], + ['khitachiac344heat_1747',['kHitachiAc344Heat',['../ir__Hitachi_8h.html#a6c4102910d21dc838efee1fb2477218d',1,'ir_Hitachi.h']]], + ['khitachiac344maxtemp_1748',['kHitachiAc344MaxTemp',['../ir__Hitachi_8h.html#a4a394fc23fb119ba67e3ca53e4b88f7f',1,'ir_Hitachi.h']]], + ['khitachiac344mintemp_1749',['kHitachiAc344MinTemp',['../ir__Hitachi_8h.html#a7322f7769c9c1af2311180474e5b0f57',1,'ir_Hitachi.h']]], + ['khitachiac344statelength_1750',['kHitachiAc344StateLength',['../IRremoteESP8266_8h.html#a2192f6b7c353f7f124dff3b57eab0659',1,'IRremoteESP8266.h']]], + ['khitachiac344swinghauto_1751',['kHitachiAc344SwingHAuto',['../ir__Hitachi_8h.html#a4f93eccee6e3e5f5c49c84034ca25af3',1,'ir_Hitachi.h']]], + ['khitachiac344swinghbyte_1752',['kHitachiAc344SwingHByte',['../ir__Hitachi_8h.html#a132b64e007043ade4f209b0416fd5f4d',1,'ir_Hitachi.h']]], + ['khitachiac344swinghleft_1753',['kHitachiAc344SwingHLeft',['../ir__Hitachi_8h.html#af714a1eb296b05f3fc8167aff5419764',1,'ir_Hitachi.h']]], + ['khitachiac344swinghleftmax_1754',['kHitachiAc344SwingHLeftMax',['../ir__Hitachi_8h.html#ad0c5636ac0ccfd7e9cd087101bd5d204',1,'ir_Hitachi.h']]], + ['khitachiac344swinghmiddle_1755',['kHitachiAc344SwingHMiddle',['../ir__Hitachi_8h.html#a7e4372e02d72723049b378e955070c21',1,'ir_Hitachi.h']]], + ['khitachiac344swinghoffset_1756',['kHitachiAc344SwingHOffset',['../ir__Hitachi_8h.html#a7e8e57b0b37f20a502eb66f13980989c',1,'ir_Hitachi.h']]], + ['khitachiac344swinghright_1757',['kHitachiAc344SwingHRight',['../ir__Hitachi_8h.html#af4b087dec06cfd86920dbf9df22aca63',1,'ir_Hitachi.h']]], + ['khitachiac344swinghrightmax_1758',['kHitachiAc344SwingHRightMax',['../ir__Hitachi_8h.html#a90cffc131be89a36d352c462403f689f',1,'ir_Hitachi.h']]], + ['khitachiac344swinghsize_1759',['kHitachiAc344SwingHSize',['../ir__Hitachi_8h.html#aadd389cd818207920c1e8efef53fde91',1,'ir_Hitachi.h']]], + ['khitachiac344swingvbyte_1760',['kHitachiAc344SwingVByte',['../ir__Hitachi_8h.html#ae40211be39e522ebf9b580b3481f49f3',1,'ir_Hitachi.h']]], + ['khitachiac344swingvoffset_1761',['kHitachiAc344SwingVOffset',['../ir__Hitachi_8h.html#a8b38ef096697f70bdba8f4bd2799e148',1,'ir_Hitachi.h']]], + ['khitachiac3bitmark_1762',['kHitachiAc3BitMark',['../ir__Hitachi_8cpp.html#a68269a88e02a3030749061e5f28f74cc',1,'ir_Hitachi.cpp']]], + ['khitachiac3bits_1763',['kHitachiAc3Bits',['../IRremoteESP8266_8h.html#ac26b896cdc17018269fa881e10e3aabb',1,'IRremoteESP8266.h']]], + ['khitachiac3hdrmark_1764',['kHitachiAc3HdrMark',['../ir__Hitachi_8cpp.html#af0a80a66094e67b4a78e8dfa539cd22f',1,'ir_Hitachi.cpp']]], + ['khitachiac3hdrspace_1765',['kHitachiAc3HdrSpace',['../ir__Hitachi_8cpp.html#aca4dc0b851c69a5e640337d68eb6f412',1,'ir_Hitachi.cpp']]], + ['khitachiac3minbits_1766',['kHitachiAc3MinBits',['../IRremoteESP8266_8h.html#a66ebaf70d2b4018371825c9cd3078a42',1,'IRremoteESP8266.h']]], + ['khitachiac3minstatelength_1767',['kHitachiAc3MinStateLength',['../IRremoteESP8266_8h.html#ac3becb270bfddaa1c64b1f8582dfc902',1,'IRremoteESP8266.h']]], + ['khitachiac3onespace_1768',['kHitachiAc3OneSpace',['../ir__Hitachi_8cpp.html#a0e630e38b4bffd5ec931153c20e41d97',1,'ir_Hitachi.cpp']]], + ['khitachiac3statelength_1769',['kHitachiAc3StateLength',['../IRremoteESP8266_8h.html#a9cc230bac4f902d46049c7b2c2fdbd3d',1,'IRremoteESP8266.h']]], + ['khitachiac3zerospace_1770',['kHitachiAc3ZeroSpace',['../ir__Hitachi_8cpp.html#a7cf96a2734bcc9a5eb390b8647666925',1,'ir_Hitachi.cpp']]], + ['khitachiac424bitmark_1771',['kHitachiAc424BitMark',['../ir__Hitachi_8cpp.html#acf5f9d83873a74688eb0413708e26eed',1,'ir_Hitachi.cpp']]], + ['khitachiac424bits_1772',['kHitachiAc424Bits',['../IRremoteESP8266_8h.html#ab466e28528a0d688a1b91e8af69025cb',1,'IRremoteESP8266.h']]], + ['khitachiac424buttonbyte_1773',['kHitachiAc424ButtonByte',['../ir__Hitachi_8h.html#a057159edca95f9a000c80c7059919e83',1,'ir_Hitachi.h']]], + ['khitachiac424buttonfan_1774',['kHitachiAc424ButtonFan',['../ir__Hitachi_8h.html#a4aa278fb1983213a2506c71debe035aa',1,'ir_Hitachi.h']]], + ['khitachiac424buttonpowermode_1775',['kHitachiAc424ButtonPowerMode',['../ir__Hitachi_8h.html#a2dd37a36c6ad928ad0c3485ae4ea78fd',1,'ir_Hitachi.h']]], + ['khitachiac424buttonswingh_1776',['kHitachiAc424ButtonSwingH',['../ir__Hitachi_8h.html#af3a0d9499fab327bc7dfb5d57562a946',1,'ir_Hitachi.h']]], + ['khitachiac424buttonswingv_1777',['kHitachiAc424ButtonSwingV',['../ir__Hitachi_8h.html#a59d8e5407daf37d38e0c76ab3abdec9d',1,'ir_Hitachi.h']]], + ['khitachiac424buttontempdown_1778',['kHitachiAc424ButtonTempDown',['../ir__Hitachi_8h.html#ad909ee0bc97e24aa70ff6ecd1cffe6c2',1,'ir_Hitachi.h']]], + ['khitachiac424buttontempup_1779',['kHitachiAc424ButtonTempUp',['../ir__Hitachi_8h.html#ac8885804fb276f6327beb2018b204359',1,'ir_Hitachi.h']]], + ['khitachiac424cool_1780',['kHitachiAc424Cool',['../ir__Hitachi_8h.html#a64c1e01c222e6dec001a7052e822d64f',1,'ir_Hitachi.h']]], + ['khitachiac424dry_1781',['kHitachiAc424Dry',['../ir__Hitachi_8h.html#a56bfde42914bc92f47929179cddcbdf3',1,'ir_Hitachi.h']]], + ['khitachiac424fan_1782',['kHitachiAc424Fan',['../ir__Hitachi_8h.html#a35db6fdcedeb3de0ffb0bb72f1e60a0b',1,'ir_Hitachi.h']]], + ['khitachiac424fanauto_1783',['kHitachiAc424FanAuto',['../ir__Hitachi_8h.html#add1ec95cfd4e388f90154b25410471d0',1,'ir_Hitachi.h']]], + ['khitachiac424fanbyte_1784',['kHitachiAc424FanByte',['../ir__Hitachi_8h.html#aa4758708fe16d13cf6f50b7aa9e12bf6',1,'ir_Hitachi.h']]], + ['khitachiac424fanhigh_1785',['kHitachiAc424FanHigh',['../ir__Hitachi_8h.html#aacabc41baea6c3ddf711424a400144a3',1,'ir_Hitachi.h']]], + ['khitachiac424fanlow_1786',['kHitachiAc424FanLow',['../ir__Hitachi_8h.html#acae66b060db5cd03732ccbf808c6049e',1,'ir_Hitachi.h']]], + ['khitachiac424fanmax_1787',['kHitachiAc424FanMax',['../ir__Hitachi_8h.html#a6298e6dee6ff9f5fc57cfc9ccf30c073',1,'ir_Hitachi.h']]], + ['khitachiac424fanmaxdry_1788',['kHitachiAc424FanMaxDry',['../ir__Hitachi_8h.html#af770b29d838610b87463551444548ac0',1,'ir_Hitachi.h']]], + ['khitachiac424fanmedium_1789',['kHitachiAc424FanMedium',['../ir__Hitachi_8h.html#a3d6479f2e76bd84eeda9f5c0772210c5',1,'ir_Hitachi.h']]], + ['khitachiac424fanmin_1790',['kHitachiAc424FanMin',['../ir__Hitachi_8h.html#aacf1d4b99d89a0e24622ca02402c683b',1,'ir_Hitachi.h']]], + ['khitachiac424fantemp_1791',['kHitachiAc424FanTemp',['../ir__Hitachi_8h.html#a874362698fad488da1a477c4f99923aa',1,'ir_Hitachi.h']]], + ['khitachiac424hdrmark_1792',['kHitachiAc424HdrMark',['../ir__Hitachi_8cpp.html#a7b1dcaa7569237831b08ea061fd403fb',1,'ir_Hitachi.cpp']]], + ['khitachiac424hdrspace_1793',['kHitachiAc424HdrSpace',['../ir__Hitachi_8cpp.html#a9309b801d147dd3eba96ed15245f7445',1,'ir_Hitachi.cpp']]], + ['khitachiac424heat_1794',['kHitachiAc424Heat',['../ir__Hitachi_8h.html#a5cfd38c9e7aa2c39dfa38b1ef4b33b4c',1,'ir_Hitachi.h']]], + ['khitachiac424ldrmark_1795',['kHitachiAc424LdrMark',['../ir__Hitachi_8cpp.html#a0e2a88cb5930fb9726a453bdefe33bae',1,'ir_Hitachi.cpp']]], + ['khitachiac424ldrspace_1796',['kHitachiAc424LdrSpace',['../ir__Hitachi_8cpp.html#ad6285b55ed74e0e1087c3eb12d63b39c',1,'ir_Hitachi.cpp']]], + ['khitachiac424maxtemp_1797',['kHitachiAc424MaxTemp',['../ir__Hitachi_8h.html#a22574044b5a9163aca1f0581b9fa9241',1,'ir_Hitachi.h']]], + ['khitachiac424mintemp_1798',['kHitachiAc424MinTemp',['../ir__Hitachi_8h.html#a3d4311f1f28bbe31a22b80556e678b22',1,'ir_Hitachi.h']]], + ['khitachiac424modebyte_1799',['kHitachiAc424ModeByte',['../ir__Hitachi_8h.html#a3c6e0d27a95d94142360efa19a342c99',1,'ir_Hitachi.h']]], + ['khitachiac424onespace_1800',['kHitachiAc424OneSpace',['../ir__Hitachi_8cpp.html#a9b9cd22801f17acac593a8bcf334fd71',1,'ir_Hitachi.cpp']]], + ['khitachiac424powerbyte_1801',['kHitachiAc424PowerByte',['../ir__Hitachi_8h.html#a815e6761376ca4eae649ec837d55dc25',1,'ir_Hitachi.h']]], + ['khitachiac424poweroff_1802',['kHitachiAc424PowerOff',['../ir__Hitachi_8h.html#affc2d076cc0de329466ecbde7186d4eb',1,'ir_Hitachi.h']]], + ['khitachiac424poweron_1803',['kHitachiAc424PowerOn',['../ir__Hitachi_8h.html#a922478904efd86c6ecf7dabec3dd759f',1,'ir_Hitachi.h']]], + ['khitachiac424statelength_1804',['kHitachiAc424StateLength',['../IRremoteESP8266_8h.html#aff17d9c0ccf683895d2c868094679f0a',1,'IRremoteESP8266.h']]], + ['khitachiac424tempbyte_1805',['kHitachiAc424TempByte',['../ir__Hitachi_8h.html#a5de1ae606d6a34e24420b08a73542b94',1,'ir_Hitachi.h']]], + ['khitachiac424tempoffset_1806',['kHitachiAc424TempOffset',['../ir__Hitachi_8h.html#a3adb47220c4c72a62d9296092047900f',1,'ir_Hitachi.h']]], + ['khitachiac424tempsize_1807',['kHitachiAc424TempSize',['../ir__Hitachi_8h.html#ae6738f4a4476e5f34efbeb52e8c413de',1,'ir_Hitachi.h']]], + ['khitachiac424zerospace_1808',['kHitachiAc424ZeroSpace',['../ir__Hitachi_8cpp.html#a0f2032ac476bf344df31dc9351b2b98a',1,'ir_Hitachi.cpp']]], + ['khitachiacauto_1809',['kHitachiAcAuto',['../ir__Hitachi_8h.html#af8c74a8388361162b93339e1b0bc94d9',1,'ir_Hitachi.h']]], + ['khitachiacautotemp_1810',['kHitachiAcAutoTemp',['../ir__Hitachi_8h.html#aaa28bb683fefc065cb115fbfb66994ec',1,'ir_Hitachi.h']]], + ['khitachiacbitmark_1811',['kHitachiAcBitMark',['../ir__Hitachi_8cpp.html#a0993bf3d527a12bfe51c7bbfcf788c59',1,'ir_Hitachi.cpp']]], + ['khitachiacbits_1812',['kHitachiAcBits',['../IRremoteESP8266_8h.html#aec91e459b1e52765c700f8f7a4723f3b',1,'IRremoteESP8266.h']]], + ['khitachiaccool_1813',['kHitachiAcCool',['../ir__Hitachi_8h.html#a2b40b07601fdf8b038c97bb8bd2bec59',1,'ir_Hitachi.h']]], + ['khitachiacdefaultrepeat_1814',['kHitachiAcDefaultRepeat',['../IRremoteESP8266_8h.html#acc8510281d2ff9a808501d375c03ba21',1,'IRremoteESP8266.h']]], + ['khitachiacdry_1815',['kHitachiAcDry',['../ir__Hitachi_8h.html#a19730b13fca736392600580c156ae3c3',1,'ir_Hitachi.h']]], + ['khitachiacfan_1816',['kHitachiAcFan',['../ir__Hitachi_8h.html#a69626883b6fdbd3ccd26bb3123bf1883',1,'ir_Hitachi.h']]], + ['khitachiacfanauto_1817',['kHitachiAcFanAuto',['../ir__Hitachi_8h.html#a6be6f6eae193e784133be63d7cc5d75e',1,'ir_Hitachi.h']]], + ['khitachiacfanhigh_1818',['kHitachiAcFanHigh',['../ir__Hitachi_8h.html#a85ef905a1d3704237141f07defc128f5',1,'ir_Hitachi.h']]], + ['khitachiacfanlow_1819',['kHitachiAcFanLow',['../ir__Hitachi_8h.html#a0add8c3a3d00a81fcc3279af78256de2',1,'ir_Hitachi.h']]], + ['khitachiacfanmed_1820',['kHitachiAcFanMed',['../ir__Hitachi_8h.html#ac88b4cfdce5d69bf07316ddd716c2c11',1,'ir_Hitachi.h']]], + ['khitachiacfreq_1821',['kHitachiAcFreq',['../ir__Hitachi_8h.html#a443eaa664017d7b671bef0e9aa2d643b',1,'ir_Hitachi.h']]], + ['khitachiachdrmark_1822',['kHitachiAcHdrMark',['../ir__Hitachi_8cpp.html#aefe34d17f5c72ee05afb9a6302a450da',1,'ir_Hitachi.cpp']]], + ['khitachiachdrspace_1823',['kHitachiAcHdrSpace',['../ir__Hitachi_8cpp.html#a4a4352723f119ea070be1eba2aafe36b',1,'ir_Hitachi.cpp']]], + ['khitachiacheat_1824',['kHitachiAcHeat',['../ir__Hitachi_8h.html#add2498e77e5585fd8c82a553bb0c22c0',1,'ir_Hitachi.h']]], + ['khitachiacmaxtemp_1825',['kHitachiAcMaxTemp',['../ir__Hitachi_8h.html#a63e17171c40d770d25f24d018aee2c4c',1,'ir_Hitachi.h']]], + ['khitachiacmingap_1826',['kHitachiAcMinGap',['../ir__Hitachi_8cpp.html#a14016b9110c11423c628c8e220e50864',1,'ir_Hitachi.cpp']]], + ['khitachiacmintemp_1827',['kHitachiAcMinTemp',['../ir__Hitachi_8h.html#a9b4f3ea50cc0491f10ff8dc8eabb3ecd',1,'ir_Hitachi.h']]], + ['khitachiaconespace_1828',['kHitachiAcOneSpace',['../ir__Hitachi_8cpp.html#a79a79aaf52a05c021621335586dd928f',1,'ir_Hitachi.cpp']]], + ['khitachiacpoweroffset_1829',['kHitachiAcPowerOffset',['../ir__Hitachi_8h.html#a30062f0646ac63c3612d13f98211e36b',1,'ir_Hitachi.h']]], + ['khitachiacstatelength_1830',['kHitachiAcStateLength',['../IRremoteESP8266_8h.html#a8bef76bac826afbbc51c2a867af15ed8',1,'IRremoteESP8266.h']]], + ['khitachiacswingoffset_1831',['kHitachiAcSwingOffset',['../ir__Hitachi_8h.html#aac1fcff513a4eca2aeb4f13c739165e2',1,'ir_Hitachi.h']]], + ['khitachiaczerospace_1832',['kHitachiAcZeroSpace',['../ir__Hitachi_8cpp.html#a0b03a4abb11d69a8b8da56ca2abc50c8',1,'ir_Hitachi.cpp']]], + ['kholdstr_1833',['kHoldStr',['../IRtext_8cpp.html#a86fd1f86e4a513603449e90a47500986',1,'kHoldStr(): IRtext.cpp'],['../IRtext_8h.html#adb2d0f01f1429b0f3eb7193519fe3d6e',1,'kHoldStr(): IRtext.cpp']]], + ['khoursstr_1834',['kHoursStr',['../IRtext_8cpp.html#ae94260daddf2ea56e54d56bbad66526c',1,'kHoursStr(): IRtext.cpp'],['../IRtext_8h.html#a10ecbc18040f0d0ed88b728c18b0a161',1,'kHoursStr(): IRtext.cpp']]], + ['khourstr_1835',['kHourStr',['../IRtext_8cpp.html#a1d25a0bf2c8a638fff1557a0c5637977',1,'kHourStr(): IRtext.cpp'],['../IRtext_8h.html#a67a94ecb5a557b5335a8085cf1d8cdd6',1,'kHourStr(): IRtext.cpp']]], + ['khumidstr_1836',['kHumidStr',['../IRtext_8cpp.html#aae236cd2e7ed4961360fe687fe38170d',1,'kHumidStr(): IRtext.cpp'],['../IRtext_8h.html#a25365e722200ac40d581c4f585f9ae2f',1,'kHumidStr(): IRtext.cpp']]], + ['kidlestate_1837',['kIdleState',['../IRrecv_8h.html#aabba6fe7d7b97c45173eb7781a5d99bf',1,'IRrecv.h']]], + ['kifeelstr_1838',['kIFeelStr',['../IRtext_8cpp.html#a3c7368d9138477f0eac2a6249ba2606b',1,'kIFeelStr(): IRtext.cpp'],['../IRtext_8h.html#a40f90b18252e14a73dd91527f621e35f',1,'kIFeelStr(): IRtext.cpp']]], + ['kinaxbitmark_1839',['kInaxBitMark',['../ir__Inax_8cpp.html#a84553819866dbfcfad8cba87f6c02e04',1,'ir_Inax.cpp']]], + ['kinaxbits_1840',['kInaxBits',['../IRremoteESP8266_8h.html#af8441f25b32d113096adeaff331c126a',1,'IRremoteESP8266.h']]], + ['kinaxhdrmark_1841',['kInaxHdrMark',['../ir__Inax_8cpp.html#ac467a96d91b6266c3ce9a2a4ec2a8b44',1,'ir_Inax.cpp']]], + ['kinaxhdrspace_1842',['kInaxHdrSpace',['../ir__Inax_8cpp.html#a6ddcc8ca7a5d05cee91e57b3e69cca33',1,'ir_Inax.cpp']]], + ['kinaxmingap_1843',['kInaxMinGap',['../ir__Inax_8cpp.html#a600f49303a77fbdc1d77aae2abe9b9aa',1,'ir_Inax.cpp']]], + ['kinaxminrepeat_1844',['kInaxMinRepeat',['../IRremoteESP8266_8h.html#a37a3d0ae51a6ce850a424fe77d5b22d2',1,'IRremoteESP8266.h']]], + ['kinaxonespace_1845',['kInaxOneSpace',['../ir__Inax_8cpp.html#aeb77e3a51838547a29c1b343eba4c7ef',1,'ir_Inax.cpp']]], + ['kinaxtick_1846',['kInaxTick',['../ir__Inax_8cpp.html#ad437f0beac0893853cc9d5cc214b03c6',1,'ir_Inax.cpp']]], + ['kinaxzerospace_1847',['kInaxZeroSpace',['../ir__Inax_8cpp.html#a115f1f061362c1c3c41e3bb20ea7e1c6',1,'ir_Inax.cpp']]], + ['kinsidestr_1848',['kInsideStr',['../IRtext_8cpp.html#aa94c7a9b472bcd2297b43a5b4008bc51',1,'kInsideStr(): IRtext.cpp'],['../IRtext_8h.html#a55c406749cb48970c11c58ec83ef97eb',1,'kInsideStr(): IRtext.cpp']]], + ['kionstr_1849',['kIonStr',['../IRtext_8cpp.html#afc36ce4beed72e662a8d9d1473dad235',1,'kIonStr(): IRtext.cpp'],['../IRtext_8h.html#add28006fe2f8ac70db1b5048c85be84b',1,'kIonStr(): IRtext.cpp']]], + ['kjvcbitmark_1850',['kJvcBitMark',['../ir__JVC_8cpp.html#a23c11d77431d37bba18776f9341c767f',1,'ir_JVC.cpp']]], + ['kjvcbitmarkticks_1851',['kJvcBitMarkTicks',['../ir__JVC_8cpp.html#aad7cf432a9bd0d2b4df66d5f903a70dd',1,'ir_JVC.cpp']]], + ['kjvcbits_1852',['kJvcBits',['../IRremoteESP8266_8h.html#a7c28467832e7480864a6be0ce87c608f',1,'IRremoteESP8266.h']]], + ['kjvchdrmark_1853',['kJvcHdrMark',['../ir__JVC_8cpp.html#a60d81ad0066288b602054bd24a912f1f',1,'ir_JVC.cpp']]], + ['kjvchdrmarkticks_1854',['kJvcHdrMarkTicks',['../ir__JVC_8cpp.html#abb12fba45b7a366e23849d693953e749',1,'ir_JVC.cpp']]], + ['kjvchdrspace_1855',['kJvcHdrSpace',['../ir__JVC_8cpp.html#a5444718f66ba8b43c1d7d99f7b378a0d',1,'ir_JVC.cpp']]], + ['kjvchdrspaceticks_1856',['kJvcHdrSpaceTicks',['../ir__JVC_8cpp.html#ae7cf6cb7b5ea5fe17a9b182d1ef3b008',1,'ir_JVC.cpp']]], + ['kjvcmingap_1857',['kJvcMinGap',['../ir__JVC_8cpp.html#ac19d8396c10adb687a883d016ec43aa5',1,'ir_JVC.cpp']]], + ['kjvcmingapticks_1858',['kJvcMinGapTicks',['../ir__JVC_8cpp.html#a525e7d672b148c02bdca1f66ab92e6c7',1,'ir_JVC.cpp']]], + ['kjvconespace_1859',['kJvcOneSpace',['../ir__JVC_8cpp.html#a8befef1d03f3a09541c2612c66c0256f',1,'ir_JVC.cpp']]], + ['kjvconespaceticks_1860',['kJvcOneSpaceTicks',['../ir__JVC_8cpp.html#a20d4f7737d71bdbec58694e775669df9',1,'ir_JVC.cpp']]], + ['kjvcrptlength_1861',['kJvcRptLength',['../ir__JVC_8cpp.html#a3896e40881e70c63234fecb88375b5a1',1,'ir_JVC.cpp']]], + ['kjvcrptlengthticks_1862',['kJvcRptLengthTicks',['../ir__JVC_8cpp.html#a75e03cf5739ab0ba67e5cfa426776d16',1,'ir_JVC.cpp']]], + ['kjvctick_1863',['kJvcTick',['../ir__JVC_8cpp.html#acd5a2ba251824cac5311adcc9a813b1a',1,'ir_JVC.cpp']]], + ['kjvczerospace_1864',['kJvcZeroSpace',['../ir__JVC_8cpp.html#a67c790b909f82e044b8c4e7227d9c189',1,'ir_JVC.cpp']]], + ['kjvczerospaceticks_1865',['kJvcZeroSpaceTicks',['../ir__JVC_8cpp.html#a0a5319df3b1e01741cd35a37087342f5',1,'ir_JVC.cpp']]], + ['kkelvinatorauto_1866',['kKelvinatorAuto',['../ir__Kelvinator_8h.html#a879b005fc5493a693b05e3bb7cbc8fbf',1,'ir_Kelvinator.h']]], + ['kkelvinatorautotemp_1867',['kKelvinatorAutoTemp',['../ir__Kelvinator_8h.html#afa9e7ea8c9fb86cb02358cc8221733b0',1,'ir_Kelvinator.h']]], + ['kkelvinatorbasicfanmax_1868',['kKelvinatorBasicFanMax',['../ir__Kelvinator_8h.html#a10624389f033451cf9a6f4530c2dfb98',1,'ir_Kelvinator.h']]], + ['kkelvinatorbasicfansize_1869',['kKelvinatorBasicFanSize',['../ir__Kelvinator_8cpp.html#a35ffe10c5c1b834703fe44c5eeeb4c8f',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbitmark_1870',['kKelvinatorBitMark',['../ir__Kelvinator_8cpp.html#a2014f9f92f1e24a04341398e7e673807',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbitmarkticks_1871',['kKelvinatorBitMarkTicks',['../ir__Kelvinator_8cpp.html#a2d6579257ab7f185e4f0fecdbdf03835',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbits_1872',['kKelvinatorBits',['../IRremoteESP8266_8h.html#acfa71cb3caf4964829bb1f557dee5b86',1,'IRremoteESP8266.h']]], + ['kkelvinatorchecksumstart_1873',['kKelvinatorChecksumStart',['../ir__Kelvinator_8cpp.html#a0afa7cec1db6a5f46c1b30d7ce718ae6',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcmdfooter_1874',['kKelvinatorCmdFooter',['../ir__Kelvinator_8cpp.html#ad2361e09472fa03376b447114a19513f',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcmdfooterbits_1875',['kKelvinatorCmdFooterBits',['../ir__Kelvinator_8cpp.html#af6c85d3b30a5949da53ad9400734f203',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcool_1876',['kKelvinatorCool',['../ir__Kelvinator_8h.html#ad49a2e457470d6e16d001cdae3215606',1,'ir_Kelvinator.h']]], + ['kkelvinatordefaultrepeat_1877',['kKelvinatorDefaultRepeat',['../IRremoteESP8266_8h.html#a94c968c5cc929f189b8e578d2f55b132',1,'IRremoteESP8266.h']]], + ['kkelvinatordry_1878',['kKelvinatorDry',['../ir__Kelvinator_8h.html#a181b3d10b522f9afb29706da42afea55',1,'ir_Kelvinator.h']]], + ['kkelvinatorfan_1879',['kKelvinatorFan',['../ir__Kelvinator_8h.html#a8d6d97be2fd8a5aefa1319d3f662a50c',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanauto_1880',['kKelvinatorFanAuto',['../ir__Kelvinator_8h.html#ac4994c36634ca0ad8791807c9a992976',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanmax_1881',['kKelvinatorFanMax',['../ir__Kelvinator_8h.html#a889ce17d112d1a61420e1064d72c583a',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanmin_1882',['kKelvinatorFanMin',['../ir__Kelvinator_8h.html#a36a9422e2e6c6b7a87e8b2deffd1b189',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanoffset_1883',['kKelvinatorFanOffset',['../ir__Kelvinator_8cpp.html#a4988bb98a4f8798c0b927e981667cfbd',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorfansize_1884',['kKelvinatorFanSize',['../ir__Kelvinator_8cpp.html#a286636ba83aceab9c8518878a6d7209e',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorgapspace_1885',['kKelvinatorGapSpace',['../ir__Kelvinator_8cpp.html#abf66116a235a9d05089182f2f7fd7640',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorgapspaceticks_1886',['kKelvinatorGapSpaceTicks',['../ir__Kelvinator_8cpp.html#a6a81fb4c1cf1ad34f99f3ca87ab74a5c',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrmark_1887',['kKelvinatorHdrMark',['../ir__Kelvinator_8cpp.html#a413e824c6bdd4778e70f496917b3fe30',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrmarkticks_1888',['kKelvinatorHdrMarkTicks',['../ir__Kelvinator_8cpp.html#a8ad828958071c75a80928abfb916c0df',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrspace_1889',['kKelvinatorHdrSpace',['../ir__Kelvinator_8cpp.html#a9cab23fbd5ba62714fda24765db0e7d1',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrspaceticks_1890',['kKelvinatorHdrSpaceTicks',['../ir__Kelvinator_8cpp.html#ab4fbf899dcb2c2d510055215617d5b44',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorheat_1891',['kKelvinatorHeat',['../ir__Kelvinator_8h.html#a080eade5648791e37c76af7a52e85731',1,'ir_Kelvinator.h']]], + ['kkelvinatorionfilteroffset_1892',['kKelvinatorIonFilterOffset',['../ir__Kelvinator_8cpp.html#a5cbdc907f0cb6a47d0c548148933067b',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorlightoffset_1893',['kKelvinatorLightOffset',['../ir__Kelvinator_8cpp.html#a7e757add18951b8e36c2065c5dbefc24',1,'ir_Kelvinator.cpp']]], + ['kkelvinatormaxtemp_1894',['kKelvinatorMaxTemp',['../ir__Kelvinator_8h.html#a14933442e718db1a87bae5d076ad228d',1,'ir_Kelvinator.h']]], + ['kkelvinatormintemp_1895',['kKelvinatorMinTemp',['../ir__Kelvinator_8h.html#a98871ce825dbbe80d072f25253142879',1,'ir_Kelvinator.h']]], + ['kkelvinatormodeoffset_1896',['kKelvinatorModeOffset',['../ir__Kelvinator_8cpp.html#a6a52d11326d5f83653c510393bb2a518',1,'ir_Kelvinator.cpp']]], + ['kkelvinatoronespace_1897',['kKelvinatorOneSpace',['../ir__Kelvinator_8cpp.html#aae5a009282517309b8fdbfdaced9d659',1,'ir_Kelvinator.cpp']]], + ['kkelvinatoronespaceticks_1898',['kKelvinatorOneSpaceTicks',['../ir__Kelvinator_8cpp.html#ac907f4495debdcaf680f6e6941b844d5',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorpoweroffset_1899',['kKelvinatorPowerOffset',['../ir__Kelvinator_8cpp.html#a5a9591e2dd98f68ad6f562e199b1a304',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorquietoffset_1900',['kKelvinatorQuietOffset',['../ir__Kelvinator_8cpp.html#ad354be321ea41c51ead876fd30674546',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorstatelength_1901',['kKelvinatorStateLength',['../IRremoteESP8266_8h.html#af68545e8c2fe9af3719fb74c5d21f0c9',1,'IRremoteESP8266.h']]], + ['kkelvinatortick_1902',['kKelvinatorTick',['../ir__Kelvinator_8cpp.html#a846cbb5609b1dff139a90487000c7393',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorturbooffset_1903',['kKelvinatorTurboOffset',['../ir__Kelvinator_8cpp.html#a21987b6f00c7f2e9bba94c59bc5b804b',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswinghoffset_1904',['kKelvinatorVentSwingHOffset',['../ir__Kelvinator_8cpp.html#a551df2c1e21764f12030f6bfa6d5942d',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswingoffset_1905',['kKelvinatorVentSwingOffset',['../ir__Kelvinator_8cpp.html#a38012bf9daa0c362a9007107183391ef',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswingvoffset_1906',['kKelvinatorVentSwingVOffset',['../ir__Kelvinator_8cpp.html#a64d3767b464d4fe2543560cf5a2a5b21',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorxfanoffset_1907',['kKelvinatorXfanOffset',['../ir__Kelvinator_8cpp.html#a4417448475405306f10166fc9cd98054',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorzerospace_1908',['kKelvinatorZeroSpace',['../ir__Kelvinator_8cpp.html#a10469f76f50285a6084bb088fd601dea',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorzerospaceticks_1909',['kKelvinatorZeroSpaceTicks',['../ir__Kelvinator_8cpp.html#a0abc0fdc3d9ac9f12133a46e95d69432',1,'ir_Kelvinator.cpp']]], + ['klasertagbits_1910',['kLasertagBits',['../IRremoteESP8266_8h.html#a3ea0e89a8b6a3ffa4a2d346abeed851e',1,'IRremoteESP8266.h']]], + ['klasertagdelta_1911',['kLasertagDelta',['../ir__Lasertag_8cpp.html#a5c0e8e9c6dec0480c09fcd339ed62257',1,'ir_Lasertag.cpp']]], + ['klasertagexcess_1912',['kLasertagExcess',['../ir__Lasertag_8cpp.html#afa77dc5a431a8d851320e7623378983e',1,'ir_Lasertag.cpp']]], + ['klasertagmingap_1913',['kLasertagMinGap',['../ir__Lasertag_8cpp.html#a33762e2c44dac34e00d255b41d9f2822',1,'ir_Lasertag.cpp']]], + ['klasertagminrepeat_1914',['kLasertagMinRepeat',['../IRremoteESP8266_8h.html#a9b36135c3df24eab232a5edac8c58c5e',1,'IRremoteESP8266.h']]], + ['klasertagminsamples_1915',['kLasertagMinSamples',['../ir__Lasertag_8cpp.html#acbf98970106cadb43e0703ae2caab0c1',1,'ir_Lasertag.cpp']]], + ['klasertagtick_1916',['kLasertagTick',['../ir__Lasertag_8cpp.html#a878b5d53379f8b1b21dfe19f1f83a626',1,'ir_Lasertag.cpp']]], + ['klasertagtolerance_1917',['kLasertagTolerance',['../ir__Lasertag_8cpp.html#a6146bcf378515d31330b3fec5c967346',1,'ir_Lasertag.cpp']]], + ['klastdecodetype_1918',['kLastDecodeType',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab09881b84bf9d61af99e62a85cce0b59',1,'IRremoteESP8266.h']]], + ['klastfanspeedenum_1919',['kLastFanspeedEnum',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383ab2d2a6993491fd666f1fa0afff5913ad',1,'stdAc']]], + ['klastopmodeenum_1920',['kLastOpmodeEnum',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa8dd00ffd575f66172d594e78860aad9f',1,'stdAc']]], + ['klaststr_1921',['kLastStr',['../IRtext_8cpp.html#ad7c8430b935afb7aec114788a9c0bf7d',1,'kLastStr(): IRtext.cpp'],['../IRtext_8h.html#aa9ffd7c6e6921607653ed5dc1fea4f32',1,'kLastStr(): IRtext.cpp']]], + ['klastswinghenum_1922',['kLastSwinghEnum',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147ac5bc5e605db47897c114283926ba7fe4',1,'stdAc']]], + ['klastswingvenum_1923',['kLastSwingvEnum',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a4127912afc084d51c71c4ea0c7dd7b30',1,'stdAc']]], + ['kleft_1924',['kLeft',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a2d5fde1d924910a2a01ecd8e70a87c28',1,'stdAc']]], + ['kleftmax_1925',['kLeftMax',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a375fe2e8ea70186052eeb2983baa1d7d',1,'stdAc']]], + ['kleftmaxstr_1926',['kLeftMaxStr',['../IRtext_8cpp.html#a1a82999b6eb3b6637f51bb8ce6a46efd',1,'kLeftMaxStr(): IRtext.cpp'],['../IRtext_8h.html#ab2fd48f052fcfed8ca779ca499edcdbf',1,'kLeftMaxStr(): IRtext.cpp']]], + ['kleftstr_1927',['kLeftStr',['../IRtext_8cpp.html#a0bb005966f2ff2da12a542e713f7f1f2',1,'kLeftStr(): IRtext.cpp'],['../IRtext_8h.html#a001f11495c7c9452ceec68455ae524bf',1,'kLeftStr(): IRtext.cpp']]], + ['klegopfbitmark_1928',['kLegoPfBitMark',['../ir__Lego_8cpp.html#afdf76660f62bfefb4a813d57cd84b590',1,'ir_Lego.cpp']]], + ['klegopfbits_1929',['kLegoPfBits',['../IRremoteESP8266_8h.html#a8a7c7659250a81c7c84fc739eafed13e',1,'IRremoteESP8266.h']]], + ['klegopfhdrspace_1930',['kLegoPfHdrSpace',['../ir__Lego_8cpp.html#a140e8707900bfd4e3a9e2722a6b0bfb3',1,'ir_Lego.cpp']]], + ['klegopfmincommandlength_1931',['kLegoPfMinCommandLength',['../ir__Lego_8cpp.html#ad9a0c5184cc422ec1b32edf58c52d2b1',1,'ir_Lego.cpp']]], + ['klegopfminrepeat_1932',['kLegoPfMinRepeat',['../IRremoteESP8266_8h.html#a2614cf3cb840f028eb1dc684aeb1272c',1,'IRremoteESP8266.h']]], + ['klegopfonespace_1933',['kLegoPfOneSpace',['../ir__Lego_8cpp.html#a59a41085f2e8f81e1019fd40782269e3',1,'ir_Lego.cpp']]], + ['klegopfzerospace_1934',['kLegoPfZeroSpace',['../ir__Lego_8cpp.html#ada07e8aaf79cf58c46b301a410d9fb3e',1,'ir_Lego.cpp']]], + ['klg2bitmark_1935',['kLg2BitMark',['../ir__LG_8cpp.html#abf4db4647161db6fb2548b5200c41843',1,'ir_LG.cpp']]], + ['klg2bitmarkticks_1936',['kLg2BitMarkTicks',['../ir__LG_8cpp.html#aae477dcb68b9c5f1b12adf832eb388a1',1,'ir_LG.cpp']]], + ['klg2hdrmark_1937',['kLg2HdrMark',['../ir__LG_8cpp.html#a5ca50077fba2d5130220255e1659e0c3',1,'ir_LG.cpp']]], + ['klg2hdrmarkticks_1938',['kLg2HdrMarkTicks',['../ir__LG_8cpp.html#adb636fb6b634c651364ae954d31b5692',1,'ir_LG.cpp']]], + ['klg2hdrspace_1939',['kLg2HdrSpace',['../ir__LG_8cpp.html#a6637da052fea9320e97cff261f219cdb',1,'ir_LG.cpp']]], + ['klg2hdrspaceticks_1940',['kLg2HdrSpaceTicks',['../ir__LG_8cpp.html#abd2f843416070a93587d07e4d32f1eb5',1,'ir_LG.cpp']]], + ['klg32bits_1941',['kLg32Bits',['../IRremoteESP8266_8h.html#ae3c458814d7221b66d2f267cb2663bd2',1,'IRremoteESP8266.h']]], + ['klg32hdrmark_1942',['kLg32HdrMark',['../ir__LG_8cpp.html#a26cb3fb11b1a0bf0815868767e50f31b',1,'ir_LG.cpp']]], + ['klg32hdrmarkticks_1943',['kLg32HdrMarkTicks',['../ir__LG_8cpp.html#aded50973c0a938d455c1537cb240d5e9',1,'ir_LG.cpp']]], + ['klg32hdrspace_1944',['kLg32HdrSpace',['../ir__LG_8cpp.html#a59ddf2070642615e162c85b7575aff76',1,'ir_LG.cpp']]], + ['klg32hdrspaceticks_1945',['kLg32HdrSpaceTicks',['../ir__LG_8cpp.html#aa029c2c83a96f1ff02610eddd6b946fa',1,'ir_LG.cpp']]], + ['klg32rpthdrmark_1946',['kLg32RptHdrMark',['../ir__LG_8cpp.html#af19a674228bea82c1c588aa9dd974805',1,'ir_LG.cpp']]], + ['klg32rpthdrmarkticks_1947',['kLg32RptHdrMarkTicks',['../ir__LG_8cpp.html#a5c79f7072eee35fc1df10ecd18e2a3d2',1,'ir_LG.cpp']]], + ['klgacauto_1948',['kLgAcAuto',['../ir__LG_8h.html#ae5e45a0f42ce7544d6fb7981a43fb932',1,'ir_LG.h']]], + ['klgacchecksumoffset_1949',['kLgAcChecksumOffset',['../ir__LG_8h.html#aa0b9abe43a870097d886efcd0fd3bb96',1,'ir_LG.h']]], + ['klgacchecksumsize_1950',['kLgAcChecksumSize',['../ir__LG_8h.html#a177d205346380d47ae47b52079e5ffaf',1,'ir_LG.h']]], + ['klgaccool_1951',['kLgAcCool',['../ir__LG_8h.html#a3ba35885488bdda3d87ba344a5c58eb2',1,'ir_LG.h']]], + ['klgacdry_1952',['kLgAcDry',['../ir__LG_8h.html#ab3b9a106551be1217e0c824cffe1ea44',1,'ir_LG.h']]], + ['klgacfan_1953',['kLgAcFan',['../ir__LG_8h.html#afc12144673b8dd0555833427fa757275',1,'ir_LG.h']]], + ['klgacfanauto_1954',['kLgAcFanAuto',['../ir__LG_8h.html#a3dee1dc33f768d36a2216213c90a0a5c',1,'ir_LG.h']]], + ['klgacfanhigh_1955',['kLgAcFanHigh',['../ir__LG_8h.html#a89888f8d36899b5526e4c2ebb1097357',1,'ir_LG.h']]], + ['klgacfanlow_1956',['kLgAcFanLow',['../ir__LG_8h.html#afa3633c1b26d837f85b10a8a8d677efc',1,'ir_LG.h']]], + ['klgacfanmedium_1957',['kLgAcFanMedium',['../ir__LG_8h.html#abe0fb8a8f9d6ab9ebda36d0343841619',1,'ir_LG.h']]], + ['klgacfanoffset_1958',['kLgAcFanOffset',['../ir__LG_8h.html#a428d348215682243f7e5fe03c7580665',1,'ir_LG.h']]], + ['klgacfansize_1959',['kLgAcFanSize',['../ir__LG_8h.html#a4baf7484fee55fdd5cdbf13d11d7f1b9',1,'ir_LG.h']]], + ['klgacheat_1960',['kLgAcHeat',['../ir__LG_8h.html#a6c17d61082cc24f9d714c5d4ac151933',1,'ir_LG.h']]], + ['klgacmaxtemp_1961',['kLgAcMaxTemp',['../ir__LG_8h.html#a0fab7b6e6d1138638bdeadeab85f5090',1,'ir_LG.h']]], + ['klgacmintemp_1962',['kLgAcMinTemp',['../ir__LG_8h.html#ae3bef99e329f057358001cacf67f6d70',1,'ir_LG.h']]], + ['klgacmodeoffset_1963',['kLgAcModeOffset',['../ir__LG_8h.html#abbc65ef461fd214d9ef41ebf62693467',1,'ir_LG.h']]], + ['klgacmodesize_1964',['kLgAcModeSize',['../ir__LG_8h.html#ae9927832fbb45c310666d8de1ebe5f0f',1,'ir_LG.h']]], + ['klgacoffcommand_1965',['kLgAcOffCommand',['../ir__LG_8h.html#aecf8158eec1d9ec0d54056392b512296',1,'ir_LG.h']]], + ['klgacpoweroff_1966',['kLgAcPowerOff',['../ir__LG_8h.html#a3b2681e41071298197d849fbd7649318',1,'ir_LG.h']]], + ['klgacpoweroffset_1967',['kLgAcPowerOffset',['../ir__LG_8h.html#a7cce14305909efe3b904d68f902d42de',1,'ir_LG.h']]], + ['klgacpoweron_1968',['kLgAcPowerOn',['../ir__LG_8h.html#a87d2f6e4e2755aaab4762952b1bf6108',1,'ir_LG.h']]], + ['klgacpowersize_1969',['kLgAcPowerSize',['../ir__LG_8h.html#a624eee0bc9084e4d9d801f8cbdc28d1e',1,'ir_LG.h']]], + ['klgacsignature_1970',['kLgAcSignature',['../ir__LG_8h.html#ab7c3589deb28829ad0313b1505ec196e',1,'ir_LG.h']]], + ['klgacsignatureoffset_1971',['kLgAcSignatureOffset',['../ir__LG_8h.html#a406dff4b4ffa5b809b8ea87ddfd3bf8b',1,'ir_LG.h']]], + ['klgacsignaturesize_1972',['kLgAcSignatureSize',['../ir__LG_8h.html#a7420d729a5dca26d95be3b9907eb477e',1,'ir_LG.h']]], + ['klgactempadjust_1973',['kLgAcTempAdjust',['../ir__LG_8h.html#a16210dc395a86dc4562436047c22600f',1,'ir_LG.h']]], + ['klgactempoffset_1974',['kLgAcTempOffset',['../ir__LG_8h.html#aca5ae781e03e4a88a83303cb0cae0609',1,'ir_LG.h']]], + ['klgactempsize_1975',['kLgAcTempSize',['../ir__LG_8h.html#ad0235a6c5bebb086b75dc65433b3c9e1',1,'ir_LG.h']]], + ['klgbitmark_1976',['kLgBitMark',['../ir__LG_8cpp.html#a9311195710d4c3a2ac48456390a03138',1,'ir_LG.cpp']]], + ['klgbitmarkticks_1977',['kLgBitMarkTicks',['../ir__LG_8cpp.html#a80b2d221b207c8c0faa74f1f39e9920b',1,'ir_LG.cpp']]], + ['klgbits_1978',['kLgBits',['../IRremoteESP8266_8h.html#a256bd6093034b3e4c33324680f3a7102',1,'IRremoteESP8266.h']]], + ['klgdefaultrepeat_1979',['kLgDefaultRepeat',['../IRremoteESP8266_8h.html#a2d6832b3d214e0adad781c205993e461',1,'IRremoteESP8266.h']]], + ['klghdrmark_1980',['kLgHdrMark',['../ir__LG_8cpp.html#a74f253d9e4cc72148233021c47d59f35',1,'ir_LG.cpp']]], + ['klghdrmarkticks_1981',['kLgHdrMarkTicks',['../ir__LG_8cpp.html#a6f1f88f3cefe49b9796a10a9109e560e',1,'ir_LG.cpp']]], + ['klghdrspace_1982',['kLgHdrSpace',['../ir__LG_8cpp.html#a6eaf100cde647fc119d3e993680afd47',1,'ir_LG.cpp']]], + ['klghdrspaceticks_1983',['kLgHdrSpaceTicks',['../ir__LG_8cpp.html#a22d8775d4c8985970b47e449232b45de',1,'ir_LG.cpp']]], + ['klgmingap_1984',['kLgMinGap',['../ir__LG_8cpp.html#a784323468e6b5ebc65bd2870a94fb553',1,'ir_LG.cpp']]], + ['klgmingapticks_1985',['kLgMinGapTicks',['../ir__LG_8cpp.html#aa56fd5b4fe946992aa1b9bdf61b1518b',1,'ir_LG.cpp']]], + ['klgminmessagelength_1986',['kLgMinMessageLength',['../ir__LG_8cpp.html#a4eb3f82ae2ca6c34b58e512848a6dc41',1,'ir_LG.cpp']]], + ['klgminmessagelengthticks_1987',['kLgMinMessageLengthTicks',['../ir__LG_8cpp.html#ab000fc974bdd0723e8bcb4872f33dd72',1,'ir_LG.cpp']]], + ['klgonespace_1988',['kLgOneSpace',['../ir__LG_8cpp.html#a05fe6a47f437efc686cb46ec805da4d4',1,'ir_LG.cpp']]], + ['klgonespaceticks_1989',['kLgOneSpaceTicks',['../ir__LG_8cpp.html#a535b089cd72bd027cbc34eb917d71ae5',1,'ir_LG.cpp']]], + ['klgrptspace_1990',['kLgRptSpace',['../ir__LG_8cpp.html#a834b8f08ee32030c51ea5e2c5bd5a73c',1,'ir_LG.cpp']]], + ['klgrptspaceticks_1991',['kLgRptSpaceTicks',['../ir__LG_8cpp.html#abc43b327c2c752dc5ed2794f08e2eba8',1,'ir_LG.cpp']]], + ['klgtick_1992',['kLgTick',['../ir__LG_8cpp.html#ab8ab28ebf1fae94aa900a3199a6fc191',1,'ir_LG.cpp']]], + ['klgzerospace_1993',['kLgZeroSpace',['../ir__LG_8cpp.html#a981fe3cfc4adf0b3016a008ca1bbf734',1,'ir_LG.cpp']]], + ['klgzerospaceticks_1994',['kLgZeroSpaceTicks',['../ir__LG_8cpp.html#af932345e15db822da67d7796cd5b6584',1,'ir_LG.cpp']]], + ['klightstr_1995',['kLightStr',['../IRtext_8cpp.html#a2912b7dc11fd571706eaaf90e0095a4f',1,'kLightStr(): IRtext.cpp'],['../IRtext_8h.html#a926ebb4be14179afdc55d5524c8eb5da',1,'kLightStr(): IRtext.cpp']]], + ['klighttogglestr_1996',['kLightToggleStr',['../IRtext_8cpp.html#a74a3ef3c72995e19582be04a2716b285',1,'kLightToggleStr(): IRtext.cpp'],['../IRtext_8h.html#af9ac8ce54e78f0d8f7e0043d08e6256c',1,'kLightToggleStr(): IRtext.cpp']]], + ['klostr_1997',['kLoStr',['../IRtext_8cpp.html#a72fc3855eec7026260de3a6b3a25c377',1,'kLoStr(): IRtext.cpp'],['../IRtext_8h.html#abf3295aeb3dfb7048e677d8d6e65e47c',1,'kLoStr(): IRtext.cpp']]], + ['kloudstr_1998',['kLoudStr',['../IRtext_8cpp.html#a3b6d3eed96c5623cc95ebcfb93cb6f96',1,'kLoudStr(): IRtext.cpp'],['../IRtext_8h.html#a7d265b75ed59c0be3c6b72ec0eaf8aa2',1,'kLoudStr(): IRtext.cpp']]], + ['klow_1999',['kLow',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383acd8fe42741a3bbc973bbf1d404afeff4',1,'stdAc::kLow()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43acd8fe42741a3bbc973bbf1d404afeff4',1,'stdAc::kLow()']]], + ['klowerstr_2000',['kLowerStr',['../IRtext_8cpp.html#a518681524ec3c8f8bc993823003fe58a',1,'kLowerStr(): IRtext.cpp'],['../IRtext_8h.html#ae389ed4ed6982d4617ee3f3e82ce388c',1,'kLowerStr(): IRtext.cpp']]], + ['klowest_2001',['kLowest',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a334c684494b7f19d765cf062ae94a314',1,'stdAc']]], + ['kloweststr_2002',['kLowestStr',['../IRtext_8cpp.html#ae0c595955599a398669a372edd339f67',1,'kLowestStr(): IRtext.cpp'],['../IRtext_8h.html#a31a34e51d7f1f9360cc3a7ea3f2bf7a3',1,'kLowestStr(): IRtext.cpp']]], + ['klownibble_2003',['kLowNibble',['../IRutils_8h.html#ad0288cc71e1814a27c27393f06676eec',1,'IRutils.h']]], + ['klowstr_2004',['kLowStr',['../IRtext_8cpp.html#a18f69bf40b866ee1d30d1586757d5f41',1,'kLowStr(): IRtext.cpp'],['../IRtext_8h.html#a09c0f7f1b07f7591bdbe56fd8a18f7ea',1,'kLowStr(): IRtext.cpp']]], + ['klutronbits_2005',['kLutronBits',['../IRremoteESP8266_8h.html#a814dfab515b91887c494237b1f6ebd99',1,'IRremoteESP8266.h']]], + ['klutrondelta_2006',['kLutronDelta',['../ir__Lutron_8cpp.html#a4220004fac195ef46388199ad9624860',1,'ir_Lutron.cpp']]], + ['klutrongap_2007',['kLutronGap',['../ir__Lutron_8cpp.html#a18ffb51db0ae33904a64012cb72d6165',1,'ir_Lutron.cpp']]], + ['klutrontick_2008',['kLutronTick',['../ir__Lutron_8cpp.html#a04a84309978b79c0983c398a497a087a',1,'ir_Lutron.cpp']]], + ['kmagiquestbits_2009',['kMagiquestBits',['../IRremoteESP8266_8h.html#ad756bfec6eabbe2ac10b7847f87fb751',1,'IRremoteESP8266.h']]], + ['kmagiquestgap_2010',['kMagiQuestGap',['../ir__Magiquest_8h.html#aebdea5a1a55547d812f1f7bb2d3ddf1f',1,'ir_Magiquest.h']]], + ['kmagiquestmarkone_2011',['kMagiQuestMarkOne',['../ir__Magiquest_8h.html#a0d5d090015ecf49995514054c29cb4e2',1,'ir_Magiquest.h']]], + ['kmagiquestmarkzero_2012',['kMagiQuestMarkZero',['../ir__Magiquest_8h.html#a7240a15dbb9bc6a1e31575be7837c390',1,'ir_Magiquest.h']]], + ['kmagiquestoneratio_2013',['kMagiQuestOneRatio',['../ir__Magiquest_8h.html#a073cdb7ca4dd35b8fa05d99eb7da5b65',1,'ir_Magiquest.h']]], + ['kmagiquestspaceone_2014',['kMagiQuestSpaceOne',['../ir__Magiquest_8h.html#a92bad440c0291cbb903f08de08d96fb2',1,'ir_Magiquest.h']]], + ['kmagiquestspacezero_2015',['kMagiQuestSpaceZero',['../ir__Magiquest_8h.html#abe557052c5c3bef87e62daf71b4c8654',1,'ir_Magiquest.h']]], + ['kmagiquesttotalusec_2016',['kMagiQuestTotalUsec',['../ir__Magiquest_8h.html#a819dcf22b127f4f7b282d784490a83c3',1,'ir_Magiquest.h']]], + ['kmagiquestzeroratio_2017',['kMagiQuestZeroRatio',['../ir__Magiquest_8h.html#a41e5594b8e1510267e563ed78fbe98b0',1,'ir_Magiquest.h']]], + ['kmanualstr_2018',['kManualStr',['../IRtext_8cpp.html#a619896ae89717b2b0e1d3492bb528cbc',1,'kManualStr(): IRtext.cpp'],['../IRtext_8h.html#aa8d9143da032cdc1accf7f4441b05bc8',1,'kManualStr(): IRtext.cpp']]], + ['kmark_2019',['kMark',['../ir__Lasertag_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_Lasertag.cpp'],['../ir__MWM_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_MWM.cpp'],['../ir__RC5__RC6_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_RC5_RC6.cpp']]], + ['kmarkexcess_2020',['kMarkExcess',['../IRrecv_8h.html#a99bbffe986ad7ba86d2b11e75f4aa50e',1,'IRrecv.h']]], + ['kmarkstate_2021',['kMarkState',['../IRrecv_8h.html#acc85ad22929660bdc17fe185d87edfb2',1,'IRrecv.h']]], + ['kmax_2022',['kMax',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa0b1ac8aae6b1cfbbe89085c642b3b4b',1,'stdAc']]], + ['kmaxaccurateusecdelay_2023',['kMaxAccurateUsecDelay',['../IRsend_8h.html#a527e66125f3ae6ce87adbc72eab7d0b9',1,'IRsend.h']]], + ['kmaximumstr_2024',['kMaximumStr',['../IRtext_8cpp.html#af346693e98c91c7ce79bb22c7460dcee',1,'kMaximumStr(): IRtext.cpp'],['../IRtext_8h.html#a487173616cc3fced0489c01c11333912',1,'kMaximumStr(): IRtext.cpp']]], + ['kmaxleftstr_2025',['kMaxLeftStr',['../IRtext_8cpp.html#ae8ad7e46c3a33b4b9c5fa6545c9e3822',1,'kMaxLeftStr(): IRtext.cpp'],['../IRtext_8h.html#aac197960695463757652bc643efdcd59',1,'kMaxLeftStr(): IRtext.cpp']]], + ['kmaxrightstr_2026',['kMaxRightStr',['../IRtext_8cpp.html#a1ae3f331adb8ac6d1a27aa3d688fb65f',1,'kMaxRightStr(): IRtext.cpp'],['../IRtext_8h.html#a0f888d5c39cf82b2c02a7caad10c716e',1,'kMaxRightStr(): IRtext.cpp']]], + ['kmaxstr_2027',['kMaxStr',['../IRtext_8cpp.html#ad30e01090f06db0a3cb0c00bb6d2f0ca',1,'kMaxStr(): IRtext.cpp'],['../IRtext_8h.html#a7f4b2ff4134386a09e2bcb5f71f591cb',1,'kMaxStr(): IRtext.cpp']]], + ['kmaxtimeoutms_2028',['kMaxTimeoutMs',['../IRrecv_8h.html#a73391726d7caccb9b498bba73a969784',1,'IRrecv.h']]], + ['kmedium_2029',['kMedium',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383a3ce9d817402b59f65fb01ea044bb1ee9',1,'stdAc']]], + ['kmediumstr_2030',['kMediumStr',['../IRtext_8cpp.html#ac59539e93fdc7d8f15f1f55bcbf933c5',1,'kMediumStr(): IRtext.cpp'],['../IRtext_8h.html#a122ee1c6b866267f771888a7d7b2969b',1,'kMediumStr(): IRtext.cpp']]], + ['kmedstr_2031',['kMedStr',['../IRtext_8cpp.html#a4832f8f5118018fa3c6eae1cd652eabf',1,'kMedStr(): IRtext.cpp'],['../IRtext_8h.html#a18f613c7f11f6f746227cfa8cc1e00e0',1,'kMedStr(): IRtext.cpp']]], + ['kmiddle_2032',['kMiddle',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43ab3199775e825c139b44e3e9ccf3cbc7e',1,'stdAc::kMiddle()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147ab3199775e825c139b44e3e9ccf3cbc7e',1,'stdAc::kMiddle()']]], + ['kmiddlestr_2033',['kMiddleStr',['../IRtext_8cpp.html#a536f05d84867cfae601d4c1a2312d755',1,'kMiddleStr(): IRtext.cpp'],['../IRtext_8h.html#abbd5b682b584b737c76bded900a6ffad',1,'kMiddleStr(): IRtext.cpp']]], + ['kmidea24bits_2034',['kMidea24Bits',['../IRremoteESP8266_8h.html#aff132faa67b1d07890378df5c9b52a14',1,'IRremoteESP8266.h']]], + ['kmidea24mingap_2035',['kMidea24MinGap',['../ir__Midea_8cpp.html#abfee73cafcc017c4742893908200dffc',1,'ir_Midea.cpp']]], + ['kmidea24minrepeat_2036',['kMidea24MinRepeat',['../IRremoteESP8266_8h.html#a8ed4bb62818fc64e4c4b60ef1094059e',1,'IRremoteESP8266.h']]], + ['kmideaacauto_2037',['kMideaACAuto',['../ir__Midea_8h.html#a379f580c4d1832a62fe49d66f7c13af6',1,'ir_Midea.h']]], + ['kmideaaccelsiusoffset_2038',['kMideaACCelsiusOffset',['../ir__Midea_8h.html#a3354c62fbd83c1f0c55aee359d45a1e0',1,'ir_Midea.h']]], + ['kmideaaccool_2039',['kMideaACCool',['../ir__Midea_8h.html#a94b1b18f6aa9c5010699ea9bfcc89b21',1,'ir_Midea.h']]], + ['kmideaacdry_2040',['kMideaACDry',['../ir__Midea_8h.html#a88c2d215406e337b437b99a04c4ca6c4',1,'ir_Midea.h']]], + ['kmideaacfan_2041',['kMideaACFan',['../ir__Midea_8h.html#ac92dd372bb18d43aea73d5ec511e1290',1,'ir_Midea.h']]], + ['kmideaacfanauto_2042',['kMideaACFanAuto',['../ir__Midea_8h.html#a334a64f653b141d67ffda2eca2a9851f',1,'ir_Midea.h']]], + ['kmideaacfanhigh_2043',['kMideaACFanHigh',['../ir__Midea_8h.html#a9c177aff562a19f32d6cf010704ac681',1,'ir_Midea.h']]], + ['kmideaacfanlow_2044',['kMideaACFanLow',['../ir__Midea_8h.html#a90ebe3812e8b554798a2083ddfe9fdff',1,'ir_Midea.h']]], + ['kmideaacfanmed_2045',['kMideaACFanMed',['../ir__Midea_8h.html#a9406c8d9ad79e6a121a29cd5455e8e7d',1,'ir_Midea.h']]], + ['kmideaacfanoffset_2046',['kMideaACFanOffset',['../ir__Midea_8h.html#ac210e7bed85ad46cef1fa15a71d8e4c9',1,'ir_Midea.h']]], + ['kmideaacfansize_2047',['kMideaACFanSize',['../ir__Midea_8h.html#ab2726e607d432d00b625471d51b71b21',1,'ir_Midea.h']]], + ['kmideaacheat_2048',['kMideaACHeat',['../ir__Midea_8h.html#aa0fb74d8406327a9510f0efa8a16a488',1,'ir_Midea.h']]], + ['kmideaacmaxtempc_2049',['kMideaACMaxTempC',['../ir__Midea_8h.html#a0cccc3093cffabe1e512f298c04b3ba1',1,'ir_Midea.h']]], + ['kmideaacmaxtempf_2050',['kMideaACMaxTempF',['../ir__Midea_8h.html#ac7306c86080e934055d5be9728c91629',1,'ir_Midea.h']]], + ['kmideaacmintempc_2051',['kMideaACMinTempC',['../ir__Midea_8h.html#ae849eb79db6c077d617283154edade84',1,'ir_Midea.h']]], + ['kmideaacmintempf_2052',['kMideaACMinTempF',['../ir__Midea_8h.html#a0b0bdf519164f793a129d0e32152069a',1,'ir_Midea.h']]], + ['kmideaacmodeoffset_2053',['kMideaACModeOffset',['../ir__Midea_8h.html#a04fb535d82fe9d44d6898dd7c2e3491e',1,'ir_Midea.h']]], + ['kmideaacpoweroffset_2054',['kMideaACPowerOffset',['../ir__Midea_8h.html#a299cd691572c33f5d4742a9c289c279c',1,'ir_Midea.h']]], + ['kmideaacsleepoffset_2055',['kMideaACSleepOffset',['../ir__Midea_8h.html#a3c968881e59795eadfcb991b36755494',1,'ir_Midea.h']]], + ['kmideaactempoffset_2056',['kMideaACTempOffset',['../ir__Midea_8h.html#aec7e9182f167eb9b094670cf9889a595',1,'ir_Midea.h']]], + ['kmideaactempsize_2057',['kMideaACTempSize',['../ir__Midea_8h.html#aad2041ff636467046b63ceeb9fdfaaea',1,'ir_Midea.h']]], + ['kmideaactoggleswingv_2058',['kMideaACToggleSwingV',['../ir__Midea_8h.html#a5420b72289d3ae99a6dbc5c94914c473',1,'ir_Midea.h']]], + ['kmideabitmark_2059',['kMideaBitMark',['../ir__Midea_8cpp.html#a39dc2d03456f67418519dc0f5efde7e0',1,'ir_Midea.cpp']]], + ['kmideabitmarkticks_2060',['kMideaBitMarkTicks',['../ir__Midea_8cpp.html#ac4d9b1460516aa19913b5bd328c1e176',1,'ir_Midea.cpp']]], + ['kmideabits_2061',['kMideaBits',['../IRremoteESP8266_8h.html#afc98096b1e2945e2eaeb07d70d511239',1,'IRremoteESP8266.h']]], + ['kmideahdrmark_2062',['kMideaHdrMark',['../ir__Midea_8cpp.html#adcaa1ad6e2ba1022f3c90266f4fd0378',1,'ir_Midea.cpp']]], + ['kmideahdrmarkticks_2063',['kMideaHdrMarkTicks',['../ir__Midea_8cpp.html#af63b6cfcc5dc3e501b61c0d55d678f9e',1,'ir_Midea.cpp']]], + ['kmideahdrspace_2064',['kMideaHdrSpace',['../ir__Midea_8cpp.html#a8676eda087a85f6639b547140496c12f',1,'ir_Midea.cpp']]], + ['kmideahdrspaceticks_2065',['kMideaHdrSpaceTicks',['../ir__Midea_8cpp.html#aad99b5d8361733a9ca662735783e061c',1,'ir_Midea.cpp']]], + ['kmideamingap_2066',['kMideaMinGap',['../ir__Midea_8cpp.html#ad9ed8fb4841654fa756614862ac63be7',1,'ir_Midea.cpp']]], + ['kmideamingapticks_2067',['kMideaMinGapTicks',['../ir__Midea_8cpp.html#accd4e69e8fe0957ba013b97879fb1120',1,'ir_Midea.cpp']]], + ['kmideaminrepeat_2068',['kMideaMinRepeat',['../IRremoteESP8266_8h.html#aa8876e8e177b8e71154f8cfb42b19160',1,'IRremoteESP8266.h']]], + ['kmideaonespace_2069',['kMideaOneSpace',['../ir__Midea_8cpp.html#aabe187743f36e664c6069b004e9a82f7',1,'ir_Midea.cpp']]], + ['kmideaonespaceticks_2070',['kMideaOneSpaceTicks',['../ir__Midea_8cpp.html#a2cf0d5df2e5a3d7b1d24fd25ae3d7453',1,'ir_Midea.cpp']]], + ['kmideatick_2071',['kMideaTick',['../ir__Midea_8cpp.html#a878185258a4174978b072ac36aa377e2',1,'ir_Midea.cpp']]], + ['kmideatolerance_2072',['kMideaTolerance',['../ir__Midea_8cpp.html#a55553c3b8e7997fb1257ac2a37a929b6',1,'ir_Midea.cpp']]], + ['kmideazerospace_2073',['kMideaZeroSpace',['../ir__Midea_8cpp.html#a107d1d062e8475b84ec4ab548c3f01ef',1,'ir_Midea.cpp']]], + ['kmideazerospaceticks_2074',['kMideaZeroSpaceTicks',['../ir__Midea_8cpp.html#acd6580988c12ef5614727dd4d1b4c92d',1,'ir_Midea.cpp']]], + ['kmidstr_2075',['kMidStr',['../IRtext_8cpp.html#afd827d424c0bfdcc34b3607440fd2652',1,'kMidStr(): IRtext.cpp'],['../IRtext_8h.html#a571a28fe4174574caac4d93fb09ae196',1,'kMidStr(): IRtext.cpp']]], + ['kmin_2076',['kMin',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383a8fbc2f6c44a6d70550df79903eb57d48',1,'stdAc']]], + ['kminimumstr_2077',['kMinimumStr',['../IRtext_8cpp.html#acbd869e5978b6fee053d33d8cf21e11a',1,'kMinimumStr(): IRtext.cpp'],['../IRtext_8h.html#a4f6fee52ae5f7f9c8fe791dbae762607',1,'kMinimumStr(): IRtext.cpp']]], + ['kminstr_2078',['kMinStr',['../IRtext_8cpp.html#a2b0c7369c1a93b8a7d5a87bf37fcee34',1,'kMinStr(): IRtext.cpp'],['../IRtext_8h.html#a4940a3f71a484f936d3e58b9573931a8',1,'kMinStr(): IRtext.cpp']]], + ['kminutesstr_2079',['kMinutesStr',['../IRtext_8cpp.html#a1c05b3e6af04586a0060c58979df002f',1,'kMinutesStr(): IRtext.cpp'],['../IRtext_8h.html#a3358666a695e8d54c23b20dc6a371a38',1,'kMinutesStr(): IRtext.cpp']]], + ['kminutestr_2080',['kMinuteStr',['../IRtext_8cpp.html#acab620931ba510a7bc395bad59169099',1,'kMinuteStr(): IRtext.cpp'],['../IRtext_8h.html#a54df015b1adadb211a30f826999c78f6',1,'kMinuteStr(): IRtext.cpp']]], + ['kmitsubishi112auto_2081',['kMitsubishi112Auto',['../ir__Mitsubishi_8h.html#a6e38f06ff78e3406a4f2cf1e1b453402',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112bitmark_2082',['kMitsubishi112BitMark',['../ir__Mitsubishi_8cpp.html#aef96bbd77d5bd66ed220840c09f54c37',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112bits_2083',['kMitsubishi112Bits',['../IRremoteESP8266_8h.html#ae8349abe183be965e3d051cb736773a8',1,'IRremoteESP8266.h']]], + ['kmitsubishi112cool_2084',['kMitsubishi112Cool',['../ir__Mitsubishi_8h.html#aa9d1a63a8a275cda1794628f8d516963',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112dry_2085',['kMitsubishi112Dry',['../ir__Mitsubishi_8h.html#a4a3023d0342003b7947b19c9c5c25fb3',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanbyte_2086',['kMitsubishi112FanByte',['../ir__Mitsubishi_8h.html#a4312828eb864a67f8cc67a90c1324d3a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanlow_2087',['kMitsubishi112FanLow',['../ir__Mitsubishi_8h.html#a4b8d6d04bb75ed98f6ed5bdff7472f50',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmax_2088',['kMitsubishi112FanMax',['../ir__Mitsubishi_8h.html#a5a3e7c72ed85864b34f8ee298b3adc49',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmed_2089',['kMitsubishi112FanMed',['../ir__Mitsubishi_8h.html#aa8a81057eeccbf528962b31a197b0319',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmin_2090',['kMitsubishi112FanMin',['../ir__Mitsubishi_8h.html#ad8b101130e781d30b5d4072b3c514c78',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanoffset_2091',['kMitsubishi112FanOffset',['../ir__Mitsubishi_8h.html#ac000e0d3a59314c115e516f37c29983d',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanquiet_2092',['kMitsubishi112FanQuiet',['../ir__Mitsubishi_8h.html#addcf7a99c5ba2f4510754d22a4c0760f',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fansize_2093',['kMitsubishi112FanSize',['../ir__Mitsubishi_8h.html#ab102138f689d66c2c4c97445931f2dec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112gap_2094',['kMitsubishi112Gap',['../ir__Mitsubishi_8cpp.html#ab24cc7d395c1620b9519b5d0ce2a2023',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrmark_2095',['kMitsubishi112HdrMark',['../ir__Mitsubishi_8cpp.html#a3082567d58d6f8e6ef26714ff23f3728',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrmarktolerance_2096',['kMitsubishi112HdrMarkTolerance',['../ir__Mitsubishi_8cpp.html#a288931e01f8cffa1917fb7bc59710e20',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrspace_2097',['kMitsubishi112HdrSpace',['../ir__Mitsubishi_8cpp.html#a7b35ecbbc94f7ef622b20f21f83c0fba',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112heat_2098',['kMitsubishi112Heat',['../ir__Mitsubishi_8h.html#a260b6883e9433b466abf31618b1c4015',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112maxtemp_2099',['kMitsubishi112MaxTemp',['../ir__Mitsubishi_8h.html#afd968ea297ef8856b7266a8cc6e1bba0',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112minrepeat_2100',['kMitsubishi112MinRepeat',['../IRremoteESP8266_8h.html#a6bba58bb0f33feb9a6dfd20637d01d13',1,'IRremoteESP8266.h']]], + ['kmitsubishi112mintemp_2101',['kMitsubishi112MinTemp',['../ir__Mitsubishi_8h.html#acea288a8911a540cb9602d057eccb2a6',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112modebyte_2102',['kMitsubishi112ModeByte',['../ir__Mitsubishi_8h.html#a7e7663483fa89b4283baafba744d707a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112modeoffset_2103',['kMitsubishi112ModeOffset',['../ir__Mitsubishi_8h.html#a39c8631bfd414738f1934eb28e74b97b',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112onespace_2104',['kMitsubishi112OneSpace',['../ir__Mitsubishi_8cpp.html#a8dd0d824826a7da007e78741015d418a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112powerbyte_2105',['kMitsubishi112PowerByte',['../ir__Mitsubishi_8h.html#ab09f78fee2a242dfdb0318a4caf7a2d6',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112poweroffset_2106',['kMitsubishi112PowerOffset',['../ir__Mitsubishi_8h.html#afd78de91190fa6ec8ffcc9132e3a8b35',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112statelength_2107',['kMitsubishi112StateLength',['../IRremoteESP8266_8h.html#a5ff0437b26e325bc2516a3e63c7ffe76',1,'IRremoteESP8266.h']]], + ['kmitsubishi112swinghauto_2108',['kMitsubishi112SwingHAuto',['../ir__Mitsubishi_8h.html#ab55e72c6d2b407868cda075efb24ac92',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghbyte_2109',['kMitsubishi112SwingHByte',['../ir__Mitsubishi_8h.html#ac149161c62c9ceee1c3a37d73930a7e8',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghleft_2110',['kMitsubishi112SwingHLeft',['../ir__Mitsubishi_8h.html#a8299b42b0972bda8a4bc4f32527c33e9',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghleftmax_2111',['kMitsubishi112SwingHLeftMax',['../ir__Mitsubishi_8h.html#a48346e97056af670454bc77a64b904bc',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghmiddle_2112',['kMitsubishi112SwingHMiddle',['../ir__Mitsubishi_8h.html#a7adcab7d152d84adef2059339de4bb40',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghoffset_2113',['kMitsubishi112SwingHOffset',['../ir__Mitsubishi_8h.html#a42f92264157e170d68046b9970a057ed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghright_2114',['kMitsubishi112SwingHRight',['../ir__Mitsubishi_8h.html#a76cf277572a2b628d4a5353186ca2522',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghrightmax_2115',['kMitsubishi112SwingHRightMax',['../ir__Mitsubishi_8h.html#a1ff73f603b6e32075cbc9253d3090b49',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghsize_2116',['kMitsubishi112SwingHSize',['../ir__Mitsubishi_8h.html#a9ab977dbab987789d40fae38212f07ba',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghwide_2117',['kMitsubishi112SwingHWide',['../ir__Mitsubishi_8h.html#afab80db45769ab2957afc0e4799b46e5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvauto_2118',['kMitsubishi112SwingVAuto',['../ir__Mitsubishi_8h.html#a1e16b172e864a74b426b1f823770cdaa',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvbyte_2119',['kMitsubishi112SwingVByte',['../ir__Mitsubishi_8h.html#afbcd99e59a029ccc6276c87a46d560dd',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvhigh_2120',['kMitsubishi112SwingVHigh',['../ir__Mitsubishi_8h.html#ab6e345e609d72f9ed903e30f3aa9a26f',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvhighest_2121',['kMitsubishi112SwingVHighest',['../ir__Mitsubishi_8h.html#a1cb8c62990dfb98a8ea228ad59cd88e5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvlow_2122',['kMitsubishi112SwingVLow',['../ir__Mitsubishi_8h.html#a515bea322889f619d64ae96c37eaba72',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvlowest_2123',['kMitsubishi112SwingVLowest',['../ir__Mitsubishi_8h.html#ac4dd729a11e3ece244df6b1ddc9250f8',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvmiddle_2124',['kMitsubishi112SwingVMiddle',['../ir__Mitsubishi_8h.html#a0ae62480999dc4cf8a223b59938a0d68',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvoffset_2125',['kMitsubishi112SwingVOffset',['../ir__Mitsubishi_8h.html#ae4f3919271bb464d90a42066e8052c64',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvsize_2126',['kMitsubishi112SwingVSize',['../ir__Mitsubishi_8h.html#ae4f466b64691d8aa20e66a982d65ceea',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112tempbyte_2127',['kMitsubishi112TempByte',['../ir__Mitsubishi_8h.html#a4099370512a63ae3414221ab45f05034',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112tempsize_2128',['kMitsubishi112TempSize',['../ir__Mitsubishi_8h.html#a30d0ece1b7db3558ecc03214843c9fec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112zerospace_2129',['kMitsubishi112ZeroSpace',['../ir__Mitsubishi_8cpp.html#ad70d1567dc2e4ea07a247f2555fc23b4',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136auto_2130',['kMitsubishi136Auto',['../ir__Mitsubishi_8h.html#ae10977a0d09f4c583b03fa05720c3aed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136bitmark_2131',['kMitsubishi136BitMark',['../ir__Mitsubishi_8cpp.html#a3aa9c715088a58a8b4a97d5038dbf6d4',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136bits_2132',['kMitsubishi136Bits',['../IRremoteESP8266_8h.html#aa19f0122b2f906e5473a6ea232c38974',1,'IRremoteESP8266.h']]], + ['kmitsubishi136cool_2133',['kMitsubishi136Cool',['../ir__Mitsubishi_8h.html#a93332579055a07ea291b3caf9ad11944',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136dry_2134',['kMitsubishi136Dry',['../ir__Mitsubishi_8h.html#ad612c480e8664169e2b8e062d47bd8b9',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fan_2135',['kMitsubishi136Fan',['../ir__Mitsubishi_8h.html#a4445944955b9017fcd6d1ae447f1b0d7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanbyte_2136',['kMitsubishi136FanByte',['../ir__Mitsubishi_8h.html#a62166a745fdf0bbbd4b0eb114073b03e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanlow_2137',['kMitsubishi136FanLow',['../ir__Mitsubishi_8h.html#af0f7177491c4cb053e6811376be956ec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmax_2138',['kMitsubishi136FanMax',['../ir__Mitsubishi_8h.html#a43a4337e20fbf4f6747a58c15213bd16',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmed_2139',['kMitsubishi136FanMed',['../ir__Mitsubishi_8h.html#a73ff7df8fe65829cfd5875dc5040dec7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmin_2140',['kMitsubishi136FanMin',['../ir__Mitsubishi_8h.html#a2623eaf6e7d2ceb20ee72faddf46569e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanoffset_2141',['kMitsubishi136FanOffset',['../ir__Mitsubishi_8h.html#aaa194e1e4394d3805477f4b2b78d3a81',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanquiet_2142',['kMitsubishi136FanQuiet',['../ir__Mitsubishi_8h.html#af2f7483bbb99216614e01dd5aedc35d5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fansize_2143',['kMitsubishi136FanSize',['../ir__Mitsubishi_8h.html#a3fa7836f102aa9c78d7dd287a038baee',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136gap_2144',['kMitsubishi136Gap',['../ir__Mitsubishi_8cpp.html#a3f9e0708bbe8ed3ff98a563c3ff1af2b',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136hdrmark_2145',['kMitsubishi136HdrMark',['../ir__Mitsubishi_8cpp.html#a49c54ff757d070de54e3739b775bea00',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136hdrspace_2146',['kMitsubishi136HdrSpace',['../ir__Mitsubishi_8cpp.html#a1ddd09e423c427b3956298c20725188a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136heat_2147',['kMitsubishi136Heat',['../ir__Mitsubishi_8h.html#a932f074e9348d35cea119c8141eeb7f2',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136maxtemp_2148',['kMitsubishi136MaxTemp',['../ir__Mitsubishi_8h.html#a2db420b28003dc3e05bf1c86830c61ed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136minrepeat_2149',['kMitsubishi136MinRepeat',['../IRremoteESP8266_8h.html#a448bd7af5fdab67fb40901a3d6efed21',1,'IRremoteESP8266.h']]], + ['kmitsubishi136mintemp_2150',['kMitsubishi136MinTemp',['../ir__Mitsubishi_8h.html#a5e2e5783d33f927f941271a44d11434c',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136modebyte_2151',['kMitsubishi136ModeByte',['../ir__Mitsubishi_8h.html#a98fbde8559e82a1875235019913e859c',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136modeoffset_2152',['kMitsubishi136ModeOffset',['../ir__Mitsubishi_8h.html#a061d59096df59826d951e83594728893',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136onespace_2153',['kMitsubishi136OneSpace',['../ir__Mitsubishi_8cpp.html#a9a0cfee8b6ea94d3f798d53d30c99d5f',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136powerbit_2154',['kMitsubishi136PowerBit',['../ir__Mitsubishi_8h.html#abbe2f7821db2a6f4696cf7f9138c509d',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136powerbyte_2155',['kMitsubishi136PowerByte',['../ir__Mitsubishi_8h.html#aca06b9d066d3f1a322bbb0f3d1a874a7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136poweroffset_2156',['kMitsubishi136PowerOffset',['../ir__Mitsubishi_8h.html#ad235f31bc4b42548373c15e18f29e8b1',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136statelength_2157',['kMitsubishi136StateLength',['../IRremoteESP8266_8h.html#a01adbe4e1afb2ba26a5a60bf5b0b42f6',1,'IRremoteESP8266.h']]], + ['kmitsubishi136swingvauto_2158',['kMitsubishi136SwingVAuto',['../ir__Mitsubishi_8h.html#a828c2cc017cb7d00872137464d2119ae',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvbyte_2159',['kMitsubishi136SwingVByte',['../ir__Mitsubishi_8h.html#ab31414515f89e94ec8b63028e215b5ad',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvhigh_2160',['kMitsubishi136SwingVHigh',['../ir__Mitsubishi_8h.html#a319b36df23511aba8fb16b13eda9333b',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvhighest_2161',['kMitsubishi136SwingVHighest',['../ir__Mitsubishi_8h.html#a5bd1dbb97df91dfec0f9493120ea1269',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvlow_2162',['kMitsubishi136SwingVLow',['../ir__Mitsubishi_8h.html#a1ba4f3f7eb75bb54a752cfb11f196af0',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvlowest_2163',['kMitsubishi136SwingVLowest',['../ir__Mitsubishi_8h.html#ab0701f0127b07780066040bc08e46a2e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136tempbyte_2164',['kMitsubishi136TempByte',['../ir__Mitsubishi_8h.html#a22bf24adb745489a75fb877fa5cc249a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136zerospace_2165',['kMitsubishi136ZeroSpace',['../ir__Mitsubishi_8cpp.html#afaf1eca1169f492dcdd8a7266756c827',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2bitmark_2166',['kMitsubishi2BitMark',['../ir__Mitsubishi_8cpp.html#a8b0e87a15c51c3b62c14b4e7a071207f',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2hdrmark_2167',['kMitsubishi2HdrMark',['../ir__Mitsubishi_8cpp.html#a2d838e748f1f69165fb6b672955ea95e',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2hdrspace_2168',['kMitsubishi2HdrSpace',['../ir__Mitsubishi_8cpp.html#acd8994a08389c8d874afcbb8eb9c0861',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2mingap_2169',['kMitsubishi2MinGap',['../ir__Mitsubishi_8cpp.html#a7fa283a14968b582123a474c86a6fde9',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2onespace_2170',['kMitsubishi2OneSpace',['../ir__Mitsubishi_8cpp.html#aeee614cef3e95f661dca95b344edcf64',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2zerospace_2171',['kMitsubishi2ZeroSpace',['../ir__Mitsubishi_8cpp.html#a665522ccd10f4c9fba39e3f8f8a5cb95',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacauto_2172',['kMitsubishiAcAuto',['../ir__Mitsubishi_8h.html#a1fdbdc0906594e0efebbd05110877000',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacbitmark_2173',['kMitsubishiAcBitMark',['../ir__Mitsubishi_8cpp.html#a3787c48ffff208ef964886efab7e17ca',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacbits_2174',['kMitsubishiACBits',['../IRremoteESP8266_8h.html#a911a47148656b26da2e094a7ced1fc8b',1,'IRremoteESP8266.h']]], + ['kmitsubishiaccool_2175',['kMitsubishiAcCool',['../ir__Mitsubishi_8h.html#a434455f6c76f0ca354b01e6a8a6479e9',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacdry_2176',['kMitsubishiAcDry',['../ir__Mitsubishi_8h.html#a9875c4b91a1b155b5f2e12370c33e031',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacextratolerance_2177',['kMitsubishiAcExtraTolerance',['../ir__Mitsubishi_8cpp.html#a98a0e4182311d584d4de4632eb491f04',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacfanauto_2178',['kMitsubishiAcFanAuto',['../ir__Mitsubishi_8h.html#a302cfd0468875cff23c69f71c392ad36',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanautooffset_2179',['kMitsubishiAcFanAutoOffset',['../ir__Mitsubishi_8h.html#ab8696268b90bf45314d712c212d68a10',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanmax_2180',['kMitsubishiAcFanMax',['../ir__Mitsubishi_8h.html#abbc2b87dfc6b2364d065f66f4d3e540c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanoffset_2181',['kMitsubishiAcFanOffset',['../ir__Mitsubishi_8h.html#ac16a5f7fe9800006de4511fd4ac89d64',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanquiet_2182',['kMitsubishiAcFanQuiet',['../ir__Mitsubishi_8h.html#a90799250620dec05385b9e81cfcb83af',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanrealmax_2183',['kMitsubishiAcFanRealMax',['../ir__Mitsubishi_8h.html#aa28f81fbd686adb082786e7cda9a17fc',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfansilent_2184',['kMitsubishiAcFanSilent',['../ir__Mitsubishi_8h.html#a731206548afa4f2672a78dae677f6b44',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfansize_2185',['kMitsubishiAcFanSize',['../ir__Mitsubishi_8h.html#a565c641228d28357282b211048f1bd1c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiachdrmark_2186',['kMitsubishiAcHdrMark',['../ir__Mitsubishi_8cpp.html#a11fcb08ce6bf9fa5fc50ca0e5c7d2d64',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiachdrspace_2187',['kMitsubishiAcHdrSpace',['../ir__Mitsubishi_8cpp.html#af0af560129a4666aeba1a4a9ab59e271',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacheat_2188',['kMitsubishiAcHeat',['../ir__Mitsubishi_8h.html#a6107df195ecf54ec4ef97b5ab82e911c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacmaxtemp_2189',['kMitsubishiAcMaxTemp',['../ir__Mitsubishi_8h.html#a8ba3fba3eb9dd63f5ade3cb3bd11269b',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacminrepeat_2190',['kMitsubishiACMinRepeat',['../IRremoteESP8266_8h.html#a376653a421df42d889ac3b2a071de58b',1,'IRremoteESP8266.h']]], + ['kmitsubishiacmintemp_2191',['kMitsubishiAcMinTemp',['../ir__Mitsubishi_8h.html#a2d6d53ccf446fcb03331f4e9757f4169',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacmodeoffset_2192',['kMitsubishiAcModeOffset',['../ir__Mitsubishi_8h.html#ac0037c13e3f90b7bde5a8328faaa3b9b',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacnotimer_2193',['kMitsubishiAcNoTimer',['../ir__Mitsubishi_8h.html#a0f5da97478cd6cdf2ffab161657e4ab6',1,'ir_Mitsubishi.h']]], + ['kmitsubishiaconespace_2194',['kMitsubishiAcOneSpace',['../ir__Mitsubishi_8cpp.html#abdf26b381c5288556257fabf43458775',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacpower_2195',['kMitsubishiAcPower',['../ir__Mitsubishi_8h.html#a864c4d936663d68f65ed4525072bd3eb',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacpoweroffset_2196',['kMitsubishiAcPowerOffset',['../ir__Mitsubishi_8h.html#a78749519549fb76a920ca447a4504e72',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacrptmark_2197',['kMitsubishiAcRptMark',['../ir__Mitsubishi_8cpp.html#a541d764aef906909a1a0d40466567c92',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacrptspace_2198',['kMitsubishiAcRptSpace',['../ir__Mitsubishi_8cpp.html#a4b120db1bd34c62778597abf05092d0a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacstartstoptimer_2199',['kMitsubishiAcStartStopTimer',['../ir__Mitsubishi_8h.html#aecbdc43fb4bd199c47cb5125816eab59',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacstarttimer_2200',['kMitsubishiAcStartTimer',['../ir__Mitsubishi_8h.html#a4107cbc35f18204f46adb57b0fd0f09c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacstatelength_2201',['kMitsubishiACStateLength',['../IRremoteESP8266_8h.html#a7d0d6dd6d5741f91a1afb641f11d9bc5',1,'IRremoteESP8266.h']]], + ['kmitsubishiacstoptimer_2202',['kMitsubishiAcStopTimer',['../ir__Mitsubishi_8h.html#a5e59039d523d15b145aa87222d52f2bf',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneauto_2203',['kMitsubishiAcVaneAuto',['../ir__Mitsubishi_8h.html#a1caff28ea3678cc5f655fc7147c5a15e',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneautomove_2204',['kMitsubishiAcVaneAutoMove',['../ir__Mitsubishi_8h.html#a2dc0b1ff66ffc21f626d7d8894a31fbb',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvanebitoffset_2205',['kMitsubishiAcVaneBitOffset',['../ir__Mitsubishi_8h.html#a0766870a9709320cfff03d0147f8e414',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneoffset_2206',['kMitsubishiAcVaneOffset',['../ir__Mitsubishi_8h.html#a2e928c1f814b71a1c346b3e987d7b857',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvanesize_2207',['kMitsubishiAcVaneSize',['../ir__Mitsubishi_8h.html#a27d52c41a9309a89e3a2c45b87c501ff',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacwidevaneauto_2208',['kMitsubishiAcWideVaneAuto',['../ir__Mitsubishi_8h.html#a2081e2b8eb778e15b7d9f2f0f332c012',1,'ir_Mitsubishi.h']]], + ['kmitsubishiaczerospace_2209',['kMitsubishiAcZeroSpace',['../ir__Mitsubishi_8cpp.html#a9481515c349154bbb6f56cec2712ba85',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibitmark_2210',['kMitsubishiBitMark',['../ir__Mitsubishi_8cpp.html#a82c8e081b172080df14bdd6e3e6eb608',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibitmarkticks_2211',['kMitsubishiBitMarkTicks',['../ir__Mitsubishi_8cpp.html#a6daf88606f40b13bce698c73d00f5faf',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibits_2212',['kMitsubishiBits',['../IRremoteESP8266_8h.html#abd2187340d0b94996136081413e2ad22',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152bits_2213',['kMitsubishiHeavy152Bits',['../IRremoteESP8266_8h.html#ab973b35583dabc7e04b12018fac04cc9',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152fanauto_2214',['kMitsubishiHeavy152FanAuto',['../ir__MitsubishiHeavy_8h.html#ae1739c1b5cd00b28a06dfd96413570a8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanecono_2215',['kMitsubishiHeavy152FanEcono',['../ir__MitsubishiHeavy_8h.html#acf0522589438103f805889e980259eb8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanhigh_2216',['kMitsubishiHeavy152FanHigh',['../ir__MitsubishiHeavy_8h.html#a48881ddd596b6945d04465b3f7a9bee6',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanlow_2217',['kMitsubishiHeavy152FanLow',['../ir__MitsubishiHeavy_8h.html#acff7254b2ced32550ec9305dbaac3d95',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanmax_2218',['kMitsubishiHeavy152FanMax',['../ir__MitsubishiHeavy_8h.html#aa1e9a41137a7dd65fc049ae41856795f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanmed_2219',['kMitsubishiHeavy152FanMed',['../ir__MitsubishiHeavy_8h.html#ac432324a30abcc0e664cf0ff8e974516',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanturbo_2220',['kMitsubishiHeavy152FanTurbo',['../ir__MitsubishiHeavy_8h.html#a7665d1ecb52afabd0dd951f2ab54e59b',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152minrepeat_2221',['kMitsubishiHeavy152MinRepeat',['../IRremoteESP8266_8h.html#a789cbb74cf332f8440a4fcdcac188741',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152statelength_2222',['kMitsubishiHeavy152StateLength',['../IRremoteESP8266_8h.html#a31d12a44c8c3a3c4533f65b8213e2086',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152swinghauto_2223',['kMitsubishiHeavy152SwingHAuto',['../ir__MitsubishiHeavy_8h.html#ac0ed87ce67ece78e2e9f2b49da5ba152',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleft_2224',['kMitsubishiHeavy152SwingHLeft',['../ir__MitsubishiHeavy_8h.html#a1a20549b529745e913565e6d717d9f95',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleftmax_2225',['kMitsubishiHeavy152SwingHLeftMax',['../ir__MitsubishiHeavy_8h.html#a970e6b602f5bbd4d560249966f6de6c9',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleftright_2226',['kMitsubishiHeavy152SwingHLeftRight',['../ir__MitsubishiHeavy_8h.html#a24c71dc5a17affb2f2d136f6846befbc',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghmiddle_2227',['kMitsubishiHeavy152SwingHMiddle',['../ir__MitsubishiHeavy_8h.html#af1a02e21631c1efb12a01b3db065916c',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghoff_2228',['kMitsubishiHeavy152SwingHOff',['../ir__MitsubishiHeavy_8h.html#a246f8f9c9083f21ee22c2367ece2b9e2',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghright_2229',['kMitsubishiHeavy152SwingHRight',['../ir__MitsubishiHeavy_8h.html#aeec05249b3958f5a1cd629b328209e05',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghrightleft_2230',['kMitsubishiHeavy152SwingHRightLeft',['../ir__MitsubishiHeavy_8h.html#a43ddc14cc8707aa9743519b1c54eb776',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghrightmax_2231',['kMitsubishiHeavy152SwingHRightMax',['../ir__MitsubishiHeavy_8h.html#ae825ed46bf143bc6a01891a5f021c870',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvauto_2232',['kMitsubishiHeavy152SwingVAuto',['../ir__MitsubishiHeavy_8h.html#a31c20346b5538d74b58cb1fd499b5751',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvhigh_2233',['kMitsubishiHeavy152SwingVHigh',['../ir__MitsubishiHeavy_8h.html#a9ac8e39e46b43fb2276af7dd9724e3d4',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvhighest_2234',['kMitsubishiHeavy152SwingVHighest',['../ir__MitsubishiHeavy_8h.html#a554efbb611fd29a5d388d8195aa79993',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvlow_2235',['kMitsubishiHeavy152SwingVLow',['../ir__MitsubishiHeavy_8h.html#ad9a0b57ba70d318572b77236c23830a7',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvlowest_2236',['kMitsubishiHeavy152SwingVLowest',['../ir__MitsubishiHeavy_8h.html#a02f1b980aa78b4ff314209d16bf0a6e8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvmiddle_2237',['kMitsubishiHeavy152SwingVMiddle',['../ir__MitsubishiHeavy_8h.html#ae5c3ec8b8837dddff01d71c44a4ba813',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvoff_2238',['kMitsubishiHeavy152SwingVOff',['../ir__MitsubishiHeavy_8h.html#abb6905210a2f4021d157eeb61eaed7cd',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvoffset_2239',['kMitsubishiHeavy152SwingVOffset',['../ir__MitsubishiHeavy_8h.html#ae46f3549243667bbc38d6dc058772699',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvsize_2240',['kMitsubishiHeavy152SwingVSize',['../ir__MitsubishiHeavy_8h.html#a9cf7566686359cd5d553881b5eb96131',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy3dmask_2241',['kMitsubishiHeavy3DMask',['../ir__MitsubishiHeavy_8h.html#a16dcde537c9a2b1e8ddab4d6e08abb39',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88bits_2242',['kMitsubishiHeavy88Bits',['../IRremoteESP8266_8h.html#aa80d389140df4ab7071bfb3510b35dda',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88cleanoffset_2243',['kMitsubishiHeavy88CleanOffset',['../ir__MitsubishiHeavy_8h.html#ac0a4108b9ce94b3a85c2cb9680c98f4e',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanauto_2244',['kMitsubishiHeavy88FanAuto',['../ir__MitsubishiHeavy_8h.html#a607cbc27223765b3dd1f9bfd77932d0f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanecono_2245',['kMitsubishiHeavy88FanEcono',['../ir__MitsubishiHeavy_8h.html#ab5fbaaffd9e0182fc7e60252f89da2c3',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanhigh_2246',['kMitsubishiHeavy88FanHigh',['../ir__MitsubishiHeavy_8h.html#aa45b29aaa7d8df7a34dfe6308a6b6412',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanlow_2247',['kMitsubishiHeavy88FanLow',['../ir__MitsubishiHeavy_8h.html#a92f0cba1aef78e5ade01c648837e7553',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanmed_2248',['kMitsubishiHeavy88FanMed',['../ir__MitsubishiHeavy_8h.html#aade681ee8ed4c4647a997a3caad093ea',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanoffset_2249',['kMitsubishiHeavy88FanOffset',['../ir__MitsubishiHeavy_8h.html#a477fe23b5b186f4386e5d0cbded98710',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fansize_2250',['kMitsubishiHeavy88FanSize',['../ir__MitsubishiHeavy_8h.html#a68ffc738a040b3c95a839362e069fe8a',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanturbo_2251',['kMitsubishiHeavy88FanTurbo',['../ir__MitsubishiHeavy_8h.html#a29201ebd9395edb2660337ee00efa1dd',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88minrepeat_2252',['kMitsubishiHeavy88MinRepeat',['../IRremoteESP8266_8h.html#ad7bccde1a9b32c962c99748fb130f711',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88statelength_2253',['kMitsubishiHeavy88StateLength',['../IRremoteESP8266_8h.html#a515e5a081c388dd4313b20ff2b6c7955',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88swingh3d_2254',['kMitsubishiHeavy88SwingH3D',['../ir__MitsubishiHeavy_8h.html#adfeb87be0ddfc6c06bbcb4a1506d3185',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghauto_2255',['kMitsubishiHeavy88SwingHAuto',['../ir__MitsubishiHeavy_8h.html#ac39f2339ab90bdc6d9c98dd6cf95fce2',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleft_2256',['kMitsubishiHeavy88SwingHLeft',['../ir__MitsubishiHeavy_8h.html#a32a76b07c6da2b09d04d985544d91af1',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleftmax_2257',['kMitsubishiHeavy88SwingHLeftMax',['../ir__MitsubishiHeavy_8h.html#a83340e32cff8ca09eb7596ec55a67853',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleftright_2258',['kMitsubishiHeavy88SwingHLeftRight',['../ir__MitsubishiHeavy_8h.html#a82f7addc930441b6e756d71ce3df24ca',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghmiddle_2259',['kMitsubishiHeavy88SwingHMiddle',['../ir__MitsubishiHeavy_8h.html#a7a4b00b2953f2bc068d83c2618484c69',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoff_2260',['kMitsubishiHeavy88SwingHOff',['../ir__MitsubishiHeavy_8h.html#a5313aeb4115ca5a795c6ebb9871ce436',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoffset1_2261',['kMitsubishiHeavy88SwingHOffset1',['../ir__MitsubishiHeavy_8h.html#aeefa28e96d259e4ad5b63b86abf46f39',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoffset2_2262',['kMitsubishiHeavy88SwingHOffset2',['../ir__MitsubishiHeavy_8h.html#a9efbee563f821dad4006e8c56de9131d',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghright_2263',['kMitsubishiHeavy88SwingHRight',['../ir__MitsubishiHeavy_8h.html#a35224e254d897b9d42e16f9dae04d984',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghrightleft_2264',['kMitsubishiHeavy88SwingHRightLeft',['../ir__MitsubishiHeavy_8h.html#aa913c0f1c61260c533c66aaa12dc83ac',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghrightmax_2265',['kMitsubishiHeavy88SwingHRightMax',['../ir__MitsubishiHeavy_8h.html#a83c481d42999e377a2c50cacc28017b0',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghsize_2266',['kMitsubishiHeavy88SwingHSize',['../ir__MitsubishiHeavy_8h.html#a46a3cb1874cf5d1875e971094527b98f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvauto_2267',['kMitsubishiHeavy88SwingVAuto',['../ir__MitsubishiHeavy_8h.html#a65c66f030afd2795d3132b3d0be2cabe',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte5offset_2268',['kMitsubishiHeavy88SwingVByte5Offset',['../ir__MitsubishiHeavy_8h.html#adab63d1b0145cbea0953a9fdd34fd3cf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte5size_2269',['kMitsubishiHeavy88SwingVByte5Size',['../ir__MitsubishiHeavy_8h.html#ae0569562330f8c2af57a78764341c310',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte7offset_2270',['kMitsubishiHeavy88SwingVByte7Offset',['../ir__MitsubishiHeavy_8h.html#a8e864258ce7f01edb3b8d4672bba6312',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte7size_2271',['kMitsubishiHeavy88SwingVByte7Size',['../ir__MitsubishiHeavy_8h.html#a2e0d599b002366cc73d07f876d4fc0f7',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvhigh_2272',['kMitsubishiHeavy88SwingVHigh',['../ir__MitsubishiHeavy_8h.html#af99a8f0925f184f56080ddf3e9a37606',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvhighest_2273',['kMitsubishiHeavy88SwingVHighest',['../ir__MitsubishiHeavy_8h.html#adc2a20b5ca5dda6417c60a1a3c321fc0',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvlow_2274',['kMitsubishiHeavy88SwingVLow',['../ir__MitsubishiHeavy_8h.html#adb086c76e06cbf6c8808470363da5e93',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvlowest_2275',['kMitsubishiHeavy88SwingVLowest',['../ir__MitsubishiHeavy_8h.html#a6f4af31ee9b187648c242aca2851d3ed',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvmiddle_2276',['kMitsubishiHeavy88SwingVMiddle',['../ir__MitsubishiHeavy_8h.html#aeaddb1d80dd777c0fdd8e77661479598',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvoff_2277',['kMitsubishiHeavy88SwingVOff',['../ir__MitsubishiHeavy_8h.html#ad29f5b94153e0fc9943a2c4c02aa1f61',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyauto_2278',['kMitsubishiHeavyAuto',['../ir__MitsubishiHeavy_8h.html#a1bcb7429a89904e3b431aaaff20e35fa',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavybitmark_2279',['kMitsubishiHeavyBitMark',['../ir__MitsubishiHeavy_8cpp.html#a54b398e130a1893bdc81067c636d6001',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavycleanoffset_2280',['kMitsubishiHeavyCleanOffset',['../ir__MitsubishiHeavy_8h.html#acbcff6b22bf5dee4eeb1dbccc323409a',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavycool_2281',['kMitsubishiHeavyCool',['../ir__MitsubishiHeavy_8h.html#a5d819a9a6372fde79380a6890ffd3168',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavydry_2282',['kMitsubishiHeavyDry',['../ir__MitsubishiHeavy_8h.html#a749f4d74b6cce4ad29a7ab78bb780eaf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyfan_2283',['kMitsubishiHeavyFan',['../ir__MitsubishiHeavy_8h.html#a55d9e0b9676da64dfdc888e7941665f8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyfilteroffset_2284',['kMitsubishiHeavyFilterOffset',['../ir__MitsubishiHeavy_8h.html#a32232c193503a4a6bab8f783fdebeddf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavygap_2285',['kMitsubishiHeavyGap',['../ir__MitsubishiHeavy_8cpp.html#a92920bf4a95bccb9b55c623ff6dac96a',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyhdrmark_2286',['kMitsubishiHeavyHdrMark',['../ir__MitsubishiHeavy_8cpp.html#a9b1724efadc251117733297c424e76f4',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyhdrspace_2287',['kMitsubishiHeavyHdrSpace',['../ir__MitsubishiHeavy_8cpp.html#a9070250903c1d1653beb54ac3de27033',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyheat_2288',['kMitsubishiHeavyHeat',['../ir__MitsubishiHeavy_8h.html#a0b76a854d109dd0622155015edd31d74',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymaxtemp_2289',['kMitsubishiHeavyMaxTemp',['../ir__MitsubishiHeavy_8h.html#a49abbf34671b67eb4ebbe881444180f4',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymintemp_2290',['kMitsubishiHeavyMinTemp',['../ir__MitsubishiHeavy_8h.html#afa83fd435c67699da272b883277dbb98',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymodeoffset_2291',['kMitsubishiHeavyModeOffset',['../ir__MitsubishiHeavy_8h.html#a2ac27d9659d3a203c8cc360bda901d10',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavynightoffset_2292',['kMitsubishiHeavyNightOffset',['../ir__MitsubishiHeavy_8h.html#a01b341211034e272bf5d4be00b88cc78',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyonespace_2293',['kMitsubishiHeavyOneSpace',['../ir__MitsubishiHeavy_8cpp.html#adec6564e4af2886b4c7d44343d98b9dc',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavypoweroffset_2294',['kMitsubishiHeavyPowerOffset',['../ir__MitsubishiHeavy_8h.html#a51d81b3a7d97e423858e00aecd9719c9',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavysiglength_2295',['kMitsubishiHeavySigLength',['../ir__MitsubishiHeavy_8h.html#af08e6fc65b10821e52dd4a0073033d14',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavysilentoffset_2296',['kMitsubishiHeavySilentOffset',['../ir__MitsubishiHeavy_8h.html#a9b7eb89d7a3f08e84339317d1f21ca6f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyzerospace_2297',['kMitsubishiHeavyZeroSpace',['../ir__MitsubishiHeavy_8cpp.html#a903c30cee53f76c7dc3d2fef74b6e4b2',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyzjssig_2298',['kMitsubishiHeavyZjsSig',['../ir__MitsubishiHeavy_8h.html#a01eb89bfc9d4b271a97fea566eb937ff',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyzmssig_2299',['kMitsubishiHeavyZmsSig',['../ir__MitsubishiHeavy_8h.html#a18761991123d121c8d40531d07922165',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishimincommandlength_2300',['kMitsubishiMinCommandLength',['../ir__Mitsubishi_8cpp.html#ad5a6d37e755ce1faa4cdb024d2bed26a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimincommandlengthticks_2301',['kMitsubishiMinCommandLengthTicks',['../ir__Mitsubishi_8cpp.html#a4f69a50c720c7a19f0ee04d262eb5948',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimingap_2302',['kMitsubishiMinGap',['../ir__Mitsubishi_8cpp.html#a66f6379ca4c0e5f03eda2d81be0a35b2',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimingapticks_2303',['kMitsubishiMinGapTicks',['../ir__Mitsubishi_8cpp.html#af9e8409306344cf4cd0117f2131fc67a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiminrepeat_2304',['kMitsubishiMinRepeat',['../IRremoteESP8266_8h.html#ad88bda81b48f25d30bb5a169d3b6bcec',1,'IRremoteESP8266.h']]], + ['kmitsubishionespace_2305',['kMitsubishiOneSpace',['../ir__Mitsubishi_8cpp.html#ab3c6a50b722402633aaf26e2a4a39ff0',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishionespaceticks_2306',['kMitsubishiOneSpaceTicks',['../ir__Mitsubishi_8cpp.html#a3b12f2aa2c3b4b7ef439f86356aab9cf',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishitick_2307',['kMitsubishiTick',['../ir__Mitsubishi_8cpp.html#a5197eb8b6e8de8fdfb9f056b6f7d9aa5',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishizerospace_2308',['kMitsubishiZeroSpace',['../ir__Mitsubishi_8cpp.html#a9660ac382e9a929f6acb73a32b2a1a3c',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishizerospaceticks_2309',['kMitsubishiZeroSpaceTicks',['../ir__Mitsubishi_8cpp.html#a18f364a0ba491236538bc9d086303d69',1,'ir_Mitsubishi.cpp']]], + ['kmodebitssize_2310',['kModeBitsSize',['../IRutils_8h.html#a5432915ab86062fceadc067a233f1627',1,'IRutils.h']]], + ['kmodelstr_2311',['kModelStr',['../IRtext_8cpp.html#a40905418e2934e539c50c6cfc2c4ffe3',1,'kModelStr(): IRtext.cpp'],['../IRtext_8h.html#a4a553cfcc7ca2a8cea8e1263f5f6c186',1,'kModelStr(): IRtext.cpp']]], + ['kmodestr_2312',['kModeStr',['../IRtext_8cpp.html#a7260c578d290c33b7705cd1439d992ee',1,'kModeStr(): IRtext.cpp'],['../IRtext_8h.html#a6666695e388b607bfd3bb0e6efd4193f',1,'kModeStr(): IRtext.cpp']]], + ['kmouldstr_2313',['kMouldStr',['../IRtext_8cpp.html#ac665ea584a4949565aa35629d791dbc5',1,'kMouldStr(): IRtext.cpp'],['../IRtext_8h.html#a693b29e4764d959dac781a0992f2bf30',1,'kMouldStr(): IRtext.cpp']]], + ['kmovestr_2314',['kMoveStr',['../IRtext_8cpp.html#a321f98699209fb487287c4911a0c0200',1,'kMoveStr(): IRtext.cpp'],['../IRtext_8h.html#ae99940df2a9243fd7fe6f3814c0802dd',1,'kMoveStr(): IRtext.cpp']]], + ['kmultibracketsbits_2315',['kMultibracketsBits',['../IRremoteESP8266_8h.html#aad7be0971479839493615cafcd654fc1',1,'IRremoteESP8266.h']]], + ['kmultibracketsdefaultrepeat_2316',['kMultibracketsDefaultRepeat',['../IRremoteESP8266_8h.html#a5aa418baefd018d5facc08d3bb721fe9',1,'IRremoteESP8266.h']]], + ['kmultibracketsfooterspace_2317',['kMultibracketsFooterSpace',['../ir__Multibrackets_8cpp.html#a738cde2d6a25611bea116d04375dd28a',1,'ir_Multibrackets.cpp']]], + ['kmultibracketsfreq_2318',['kMultibracketsFreq',['../ir__Multibrackets_8cpp.html#a38ba01a3c516f6018199aa9031a5fb4a',1,'ir_Multibrackets.cpp']]], + ['kmultibracketshdrmark_2319',['kMultibracketsHdrMark',['../ir__Multibrackets_8cpp.html#a4eaafbf701604ceb6591b8a8b9c1d202',1,'ir_Multibrackets.cpp']]], + ['kmultibracketstick_2320',['kMultibracketsTick',['../ir__Multibrackets_8cpp.html#aa528fbf06b8d5293d82b7efc2bcd1e9b',1,'ir_Multibrackets.cpp']]], + ['kmultibracketstolerance_2321',['kMultibracketsTolerance',['../ir__Multibrackets_8cpp.html#a242017fb86f015cdecbf31c278c43ccc',1,'ir_Multibrackets.cpp']]], + ['kmwmdelta_2322',['kMWMDelta',['../ir__MWM_8cpp.html#a4e32849a3c799af002d1290a8a33366e',1,'ir_MWM.cpp']]], + ['kmwmexcess_2323',['kMWMExcess',['../ir__MWM_8cpp.html#ab3ff88bfc09c94e70fb74a77dbdd87d7',1,'ir_MWM.cpp']]], + ['kmwmmaxwidth_2324',['kMWMMaxWidth',['../ir__MWM_8cpp.html#a833013dcb331ebce3b885b0ce73c9eaa',1,'ir_MWM.cpp']]], + ['kmwmmingap_2325',['kMWMMinGap',['../ir__MWM_8cpp.html#a4d1f9c5442390a5ba089270c1187e917',1,'ir_MWM.cpp']]], + ['kmwmminsamples_2326',['kMWMMinSamples',['../ir__MWM_8cpp.html#ad386c922a0fcbd0c5b904b9abdd8d582',1,'ir_MWM.cpp']]], + ['kmwmtick_2327',['kMWMTick',['../ir__MWM_8cpp.html#a42c39c0101ccad1e88fa206a26447256',1,'ir_MWM.cpp']]], + ['kmwmtolerance_2328',['kMWMTolerance',['../ir__MWM_8cpp.html#ae3a91ec66f51f50810229b4adc1264fd',1,'ir_MWM.cpp']]], + ['knastr_2329',['kNAStr',['../IRtext_8cpp.html#a1757349137713553454f405872bc4dcd',1,'kNAStr(): IRtext.cpp'],['../IRtext_8h.html#a5d094344fba1715dbde69ff947775264',1,'kNAStr(): IRtext.cpp']]], + ['knecbitmark_2330',['kNecBitMark',['../ir__NEC_8h.html#ab536a800ec8f7259fe7e485ea4aea465',1,'ir_NEC.h']]], + ['knecbitmarkticks_2331',['kNecBitMarkTicks',['../ir__NEC_8h.html#a84ca60f84d64d65872b40a87819eccc1',1,'ir_NEC.h']]], + ['knecbits_2332',['kNECBits',['../IRremoteESP8266_8h.html#a65e03baf646815b4b02f943bdd74a097',1,'IRremoteESP8266.h']]], + ['knechdrmark_2333',['kNecHdrMark',['../ir__NEC_8h.html#ac727ede47d30ec76b03e4a41b48ce8c7',1,'ir_NEC.h']]], + ['knechdrmarkticks_2334',['kNecHdrMarkTicks',['../ir__NEC_8h.html#ab1486c07a09bc4324c03b1c887f5c5f7',1,'ir_NEC.h']]], + ['knechdrspace_2335',['kNecHdrSpace',['../ir__NEC_8h.html#a8279410369d6ed266502615d3ff1750b',1,'ir_NEC.h']]], + ['knechdrspaceticks_2336',['kNecHdrSpaceTicks',['../ir__NEC_8h.html#a4470ee927c0c3447bdda20c52b0f8566',1,'ir_NEC.h']]], + ['knecmincommandlength_2337',['kNecMinCommandLength',['../ir__NEC_8h.html#ac7b8d897d9e5bbf29b9b1b899a2ef7d8',1,'ir_NEC.h']]], + ['knecmincommandlengthticks_2338',['kNecMinCommandLengthTicks',['../ir__NEC_8h.html#a78e411960e643495987b1cb53268bc46',1,'ir_NEC.h']]], + ['knecmingap_2339',['kNecMinGap',['../ir__NEC_8h.html#a3d6ecc128599df57dc98e97e51b2264e',1,'ir_NEC.h']]], + ['knecmingapticks_2340',['kNecMinGapTicks',['../ir__NEC_8h.html#a2e6d938510a34aa1217a56aa51ece9f5',1,'ir_NEC.h']]], + ['kneconespace_2341',['kNecOneSpace',['../ir__NEC_8h.html#af57080e9b7513d1c8e7e781f3d502fbd',1,'ir_NEC.h']]], + ['kneconespaceticks_2342',['kNecOneSpaceTicks',['../ir__NEC_8h.html#a2f1e5412d44816f92e4b6c72e16e8b1f',1,'ir_NEC.h']]], + ['knecrptlength_2343',['kNecRptLength',['../ir__NEC_8h.html#af4ab20595dfda177fbb06dd821ea14c7',1,'ir_NEC.h']]], + ['knecrptspace_2344',['kNecRptSpace',['../ir__NEC_8h.html#a9538478446b1ae5d72c8366dd6a11673',1,'ir_NEC.h']]], + ['knecrptspaceticks_2345',['kNecRptSpaceTicks',['../ir__NEC_8h.html#a91b5296d480008a4b44c5b084756f04b',1,'ir_NEC.h']]], + ['knectick_2346',['kNecTick',['../ir__NEC_8h.html#abe1ec110798236c7b626f7efe4cc5657',1,'ir_NEC.h']]], + ['kneczerospace_2347',['kNecZeroSpace',['../ir__NEC_8h.html#a00573a6bdb348339b9898173b644b693',1,'ir_NEC.h']]], + ['kneczerospaceticks_2348',['kNecZeroSpaceTicks',['../ir__NEC_8h.html#a80f316535d761c64f1d5752ef80a65ff',1,'ir_NEC.h']]], + ['kneoclima8cheatoffset_2349',['kNeoclima8CHeatOffset',['../ir__Neoclima_8h.html#a4e9654ac35708a22912448eef3eb2b35',1,'ir_Neoclima.h']]], + ['kneoclimaauto_2350',['kNeoclimaAuto',['../ir__Neoclima_8h.html#a4574742c21aae9aafaff9b10f9423006',1,'ir_Neoclima.h']]], + ['kneoclimabitmark_2351',['kNeoclimaBitMark',['../ir__Neoclima_8cpp.html#ae34236a830ec2d200575ac33fda43689',1,'ir_Neoclima.cpp']]], + ['kneoclimabits_2352',['kNeoclimaBits',['../IRremoteESP8266_8h.html#afff9132e57296b4d7e04ec9e1e5ab04f',1,'IRremoteESP8266.h']]], + ['kneoclimabutton8cheat_2353',['kNeoclimaButton8CHeat',['../ir__Neoclima_8h.html#ad337d964ff800bea5c55f1fe69dfb7ff',1,'ir_Neoclima.h']]], + ['kneoclimabuttonairflow_2354',['kNeoclimaButtonAirFlow',['../ir__Neoclima_8h.html#ab5fff838f8e5ac9ff213fc69346ffa7c',1,'ir_Neoclima.h']]], + ['kneoclimabuttoneye_2355',['kNeoclimaButtonEye',['../ir__Neoclima_8h.html#a6cabdccd3c8d52cb2817f99454bdc884',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfanspeed_2356',['kNeoclimaButtonFanSpeed',['../ir__Neoclima_8h.html#ab41ffd863516b79b6c7e9b69e7d5a272',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfollow_2357',['kNeoclimaButtonFollow',['../ir__Neoclima_8h.html#a592017dce3bfa4ea2f0f341a818aff72',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfresh_2358',['kNeoclimaButtonFresh',['../ir__Neoclima_8h.html#a6a965f2dc7860879ccaf410405095e9c',1,'ir_Neoclima.h']]], + ['kneoclimabuttonhold_2359',['kNeoclimaButtonHold',['../ir__Neoclima_8h.html#aada6fdb6572bd7d841de89f1d1eed3fe',1,'ir_Neoclima.h']]], + ['kneoclimabuttonion_2360',['kNeoclimaButtonIon',['../ir__Neoclima_8h.html#a05dccf1c19237d315bb78f387f8fd57f',1,'ir_Neoclima.h']]], + ['kneoclimabuttonlight_2361',['kNeoclimaButtonLight',['../ir__Neoclima_8h.html#ac66b472b31f6183f4615584561baa284',1,'ir_Neoclima.h']]], + ['kneoclimabuttonmode_2362',['kNeoclimaButtonMode',['../ir__Neoclima_8h.html#a4cfee4b0898f1504be5cbd129cd99278',1,'ir_Neoclima.h']]], + ['kneoclimabuttonoffset_2363',['kNeoclimaButtonOffset',['../ir__Neoclima_8h.html#a08ae86c15defd78ecac0f322f84190d3',1,'ir_Neoclima.h']]], + ['kneoclimabuttonpower_2364',['kNeoclimaButtonPower',['../ir__Neoclima_8h.html#a047d19978c58b35dcd6a069fce04af87',1,'ir_Neoclima.h']]], + ['kneoclimabuttonsize_2365',['kNeoclimaButtonSize',['../ir__Neoclima_8h.html#aac90dbf9fe499df2edf64df44f449e57',1,'ir_Neoclima.h']]], + ['kneoclimabuttonsleep_2366',['kNeoclimaButtonSleep',['../ir__Neoclima_8h.html#adcbe2a89eecf41fe1fe2b8c62428084e',1,'ir_Neoclima.h']]], + ['kneoclimabuttonswing_2367',['kNeoclimaButtonSwing',['../ir__Neoclima_8h.html#aeea180bef85a40d8c7fe3f5facf7b199',1,'ir_Neoclima.h']]], + ['kneoclimabuttontempdown_2368',['kNeoclimaButtonTempDown',['../ir__Neoclima_8h.html#aee91f1ebdf89b6fe9f3b31937d1185a0',1,'ir_Neoclima.h']]], + ['kneoclimabuttontempup_2369',['kNeoclimaButtonTempUp',['../ir__Neoclima_8h.html#abb093132f77d179ab02fc4a022d55236',1,'ir_Neoclima.h']]], + ['kneoclimabuttonturbo_2370',['kNeoclimaButtonTurbo',['../ir__Neoclima_8h.html#af156d94f9e47e8b5e2e2493308cca04c',1,'ir_Neoclima.h']]], + ['kneoclimacool_2371',['kNeoclimaCool',['../ir__Neoclima_8h.html#ac5d874e5ffce72ce68176f38e780c439',1,'ir_Neoclima.h']]], + ['kneoclimadry_2372',['kNeoclimaDry',['../ir__Neoclima_8h.html#ab68ba4480e1bcb685579c5f902d0709e',1,'ir_Neoclima.h']]], + ['kneoclimaeyeoffset_2373',['kNeoclimaEyeOffset',['../ir__Neoclima_8h.html#ad7baeea22b87a69150c65b2c049ee0b2',1,'ir_Neoclima.h']]], + ['kneoclimafan_2374',['kNeoclimaFan',['../ir__Neoclima_8h.html#aa6166bd65d80a708d790dbf703c83ea2',1,'ir_Neoclima.h']]], + ['kneoclimafanauto_2375',['kNeoclimaFanAuto',['../ir__Neoclima_8h.html#a7885fdbc4ae3336aac74d7ee3d8c3258',1,'ir_Neoclima.h']]], + ['kneoclimafanhigh_2376',['kNeoclimaFanHigh',['../ir__Neoclima_8h.html#a57ddf91c1cbb157b3a53b1082bac2d75',1,'ir_Neoclima.h']]], + ['kneoclimafanlow_2377',['kNeoclimaFanLow',['../ir__Neoclima_8h.html#ac9031328be51a46543ebd4360aaca55a',1,'ir_Neoclima.h']]], + ['kneoclimafanmed_2378',['kNeoclimaFanMed',['../ir__Neoclima_8h.html#a11faf2a34faf44460795b50bfbdab402',1,'ir_Neoclima.h']]], + ['kneoclimafanoffest_2379',['kNeoclimaFanOffest',['../ir__Neoclima_8h.html#a32f614475b5f00f8ccdf12498c519713',1,'ir_Neoclima.h']]], + ['kneoclimafansize_2380',['kNeoclimaFanSize',['../ir__Neoclima_8h.html#a888cbc3f0a38137cb909188b6fff91b1',1,'ir_Neoclima.h']]], + ['kneoclimafollowme_2381',['kNeoclimaFollowMe',['../ir__Neoclima_8h.html#a493c1e6b8b8909f4201cd506a1f4804a',1,'ir_Neoclima.h']]], + ['kneoclimafreshoffset_2382',['kNeoclimaFreshOffset',['../ir__Neoclima_8h.html#af19f0f77ece049bdef26930be1b0309f',1,'ir_Neoclima.h']]], + ['kneoclimahdrmark_2383',['kNeoclimaHdrMark',['../ir__Neoclima_8cpp.html#aa392821c0ce822a7b7d67efd202bedd5',1,'ir_Neoclima.cpp']]], + ['kneoclimahdrspace_2384',['kNeoclimaHdrSpace',['../ir__Neoclima_8cpp.html#a3714ad66d75162ccb286152b70375588',1,'ir_Neoclima.cpp']]], + ['kneoclimaheat_2385',['kNeoclimaHeat',['../ir__Neoclima_8h.html#a5a5e53801c0f8e554c391ed56404b926',1,'ir_Neoclima.h']]], + ['kneoclimaholdoffset_2386',['kNeoclimaHoldOffset',['../ir__Neoclima_8h.html#a3a91e7504c7820223021dcc2cbbf9f2a',1,'ir_Neoclima.h']]], + ['kneoclimaionoffset_2387',['kNeoclimaIonOffset',['../ir__Neoclima_8h.html#ad420932425fbe261368938e604dfb0c1',1,'ir_Neoclima.h']]], + ['kneoclimalightoffset_2388',['kNeoclimaLightOffset',['../ir__Neoclima_8h.html#af58a863257c5d436b299ac8cbcb57686',1,'ir_Neoclima.h']]], + ['kneoclimamaxtemp_2389',['kNeoclimaMaxTemp',['../ir__Neoclima_8h.html#a755ef8290df8a3e19f236839bee42412',1,'ir_Neoclima.h']]], + ['kneoclimamingap_2390',['kNeoclimaMinGap',['../ir__Neoclima_8cpp.html#a0e54c73eff563f6c3ec39a0951dd3d2d',1,'ir_Neoclima.cpp']]], + ['kneoclimaminrepeat_2391',['kNeoclimaMinRepeat',['../IRremoteESP8266_8h.html#a16fc26a3ff66a66068ac9638554df847',1,'IRremoteESP8266.h']]], + ['kneoclimamintemp_2392',['kNeoclimaMinTemp',['../ir__Neoclima_8h.html#adc979ad2ac64481f13b1085b1fdd13c4',1,'ir_Neoclima.h']]], + ['kneoclimamodeoffset_2393',['kNeoclimaModeOffset',['../ir__Neoclima_8h.html#a823a960610ef3387099d2a2103dd0b56',1,'ir_Neoclima.h']]], + ['kneoclimaonespace_2394',['kNeoclimaOneSpace',['../ir__Neoclima_8cpp.html#a5fd5f3b7f04134190aafc65762528da0',1,'ir_Neoclima.cpp']]], + ['kneoclimapoweroffset_2395',['kNeoclimaPowerOffset',['../ir__Neoclima_8h.html#a9b881e5400fe9bcd3b1422aeb355cf7c',1,'ir_Neoclima.h']]], + ['kneoclimasleepoffset_2396',['kNeoclimaSleepOffset',['../ir__Neoclima_8h.html#ac0c978cdc30827c7390b93a9a4f05d24',1,'ir_Neoclima.h']]], + ['kneoclimastatelength_2397',['kNeoclimaStateLength',['../IRremoteESP8266_8h.html#a5a871ed6d145c5ea3d50e96600c02e31',1,'IRremoteESP8266.h']]], + ['kneoclimaswinghoffset_2398',['kNeoclimaSwingHOffset',['../ir__Neoclima_8h.html#a5f2e8ccaa590386b0947b0f291ebcb09',1,'ir_Neoclima.h']]], + ['kneoclimaswingvoff_2399',['kNeoclimaSwingVOff',['../ir__Neoclima_8h.html#ad230a8c18e6edb5709cb29033f1fd221',1,'ir_Neoclima.h']]], + ['kneoclimaswingvoffset_2400',['kNeoclimaSwingVOffset',['../ir__Neoclima_8h.html#a91b63c4712093684625a16c76bcc6784',1,'ir_Neoclima.h']]], + ['kneoclimaswingvon_2401',['kNeoclimaSwingVOn',['../ir__Neoclima_8h.html#a7021804eb30e7a7c5b9c9ababb1b8cad',1,'ir_Neoclima.h']]], + ['kneoclimaswingvsize_2402',['kNeoclimaSwingVSize',['../ir__Neoclima_8h.html#ab4b49ec2c326d0e94eba23e7a93b6fc6',1,'ir_Neoclima.h']]], + ['kneoclimatempoffset_2403',['kNeoclimaTempOffset',['../ir__Neoclima_8h.html#a5c3470f6c773b4c557e6996f8c29a573',1,'ir_Neoclima.h']]], + ['kneoclimatempsize_2404',['kNeoclimaTempSize',['../ir__Neoclima_8h.html#af848fc3f4ce46c8786fd2b3e129b1e48',1,'ir_Neoclima.h']]], + ['kneoclimaturbooffset_2405',['kNeoclimaTurboOffset',['../ir__Neoclima_8h.html#ae23c6faf5f54ff12d592360b42d69971',1,'ir_Neoclima.h']]], + ['kneoclimazerospace_2406',['kNeoclimaZeroSpace',['../ir__Neoclima_8cpp.html#a0b98d84da4651d8d31f8f1d84621c21e',1,'ir_Neoclima.cpp']]], + ['knibblesize_2407',['kNibbleSize',['../IRutils_8h.html#aa72cd082cdde3d8d7473ed9d11ff6846',1,'IRutils.h']]], + ['knightstr_2408',['kNightStr',['../IRtext_8cpp.html#a01908d3c0f79bc015a699fc0576a8771',1,'kNightStr(): IRtext.cpp'],['../IRtext_8h.html#afe6519eaae5b1fb4d110529ce98f05b0',1,'kNightStr(): IRtext.cpp']]], + ['knikaibitmark_2409',['kNikaiBitMark',['../ir__Nikai_8cpp.html#ad665145b0ee9cc722d9fde43cbd3fd82',1,'ir_Nikai.cpp']]], + ['knikaibitmarkticks_2410',['kNikaiBitMarkTicks',['../ir__Nikai_8cpp.html#ac10d1b4c45af3ddbf3c50b85dbb0c2f0',1,'ir_Nikai.cpp']]], + ['knikaibits_2411',['kNikaiBits',['../IRremoteESP8266_8h.html#a9fce002592f9e2488b1b717d0b1a6a40',1,'IRremoteESP8266.h']]], + ['knikaihdrmark_2412',['kNikaiHdrMark',['../ir__Nikai_8cpp.html#ae0656b931e18e6e011a7c74cfaf4384b',1,'ir_Nikai.cpp']]], + ['knikaihdrmarkticks_2413',['kNikaiHdrMarkTicks',['../ir__Nikai_8cpp.html#a11671cee9a312ece8f1c90596eddd7ac',1,'ir_Nikai.cpp']]], + ['knikaihdrspace_2414',['kNikaiHdrSpace',['../ir__Nikai_8cpp.html#ae801e20e669f3039888bf48074988b84',1,'ir_Nikai.cpp']]], + ['knikaihdrspaceticks_2415',['kNikaiHdrSpaceTicks',['../ir__Nikai_8cpp.html#a83885a2fc573f947afe5015cd2f4d953',1,'ir_Nikai.cpp']]], + ['knikaimingap_2416',['kNikaiMinGap',['../ir__Nikai_8cpp.html#ad88846eaa7559df7fb944283fd292da1',1,'ir_Nikai.cpp']]], + ['knikaimingapticks_2417',['kNikaiMinGapTicks',['../ir__Nikai_8cpp.html#afdf938a763f30e3c5e534eba269dff1f',1,'ir_Nikai.cpp']]], + ['knikaionespace_2418',['kNikaiOneSpace',['../ir__Nikai_8cpp.html#a4bb69ab22b2abcd20ffff90f9267fa43',1,'ir_Nikai.cpp']]], + ['knikaionespaceticks_2419',['kNikaiOneSpaceTicks',['../ir__Nikai_8cpp.html#a25a4d289b7fad06c31312df552ee81ab',1,'ir_Nikai.cpp']]], + ['knikaitick_2420',['kNikaiTick',['../ir__Nikai_8cpp.html#a70eb8953509420081d0a294203eeb34b',1,'ir_Nikai.cpp']]], + ['knikaizerospace_2421',['kNikaiZeroSpace',['../ir__Nikai_8cpp.html#aa9af57c5c936107b00096e16cc6f57d9',1,'ir_Nikai.cpp']]], + ['knikaizerospaceticks_2422',['kNikaiZeroSpaceTicks',['../ir__Nikai_8cpp.html#a8df777a744c018e27c6969c2109d6d79',1,'ir_Nikai.cpp']]], + ['knorepeat_2423',['kNoRepeat',['../IRremoteESP8266_8h.html#a1a49dde7ffbd753f7756cf0c9dc6d826',1,'IRremoteESP8266.h']]], + ['knostr_2424',['kNoStr',['../IRtext_8cpp.html#a07897ceb4a6607d87ef37a517908a4b5',1,'kNoStr(): IRtext.cpp'],['../IRtext_8h.html#a51c9fb58ee7d01e96e2571018aea746d',1,'kNoStr(): IRtext.cpp']]], + ['knowstr_2425',['kNowStr',['../IRtext_8cpp.html#a09d8590020bcf998746528d0e50f7a20',1,'kNowStr(): IRtext.cpp'],['../IRtext_8h.html#a6a3c0965a32c36d9b5aa4918b473cc12',1,'kNowStr(): IRtext.cpp']]], + ['koff_2426',['kOff',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444facc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43acc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147acc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()']]], + ['koffstr_2427',['kOffStr',['../IRtext_8cpp.html#a9ce19a214db45b8cff83032ffa1ccdd8',1,'kOffStr(): IRtext.cpp'],['../IRtext_8h.html#a95f119413a113c9a2e8c246892b8c52a',1,'kOffStr(): IRtext.cpp']]], + ['kofftimerstr_2428',['kOffTimerStr',['../IRtext_8cpp.html#ae5faab97b26f9e877f79f49002bbba2c',1,'kOffTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a818275085f8a8d7c083b66f081689b1f',1,'kOffTimerStr(): IRtext.cpp']]], + ['konstr_2429',['kOnStr',['../IRtext_8cpp.html#ab3f42c8df156baa46326a57193f78c51',1,'kOnStr(): IRtext.cpp'],['../IRtext_8h.html#aaf4ffad7f827a2ce8512e644bc9c25c7',1,'kOnStr(): IRtext.cpp']]], + ['kontimerstr_2430',['kOnTimerStr',['../IRtext_8cpp.html#adaecb1b5526f2bb3a1334e816a414273',1,'kOnTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a9f355a0d834790287d95eea30b57564d',1,'kOnTimerStr(): IRtext.cpp']]], + ['koutsidequietstr_2431',['kOutsideQuietStr',['../IRtext_8cpp.html#a103f2a8a2a6d351cd8ea259de3c454ef',1,'kOutsideQuietStr(): IRtext.cpp'],['../IRtext_8h.html#afaf12ae53365f790b47ff3790e94cc1c',1,'kOutsideQuietStr(): IRtext.cpp']]], + ['koutsidestr_2432',['kOutsideStr',['../IRtext_8cpp.html#a8465ee1e8b1e5dd58a9cf872c9569e01',1,'kOutsideStr(): IRtext.cpp'],['../IRtext_8h.html#ada5c81e0fcc4073d6f51e7447e8c5da0',1,'kOutsideStr(): IRtext.cpp']]], + ['kpanasonicacauto_2433',['kPanasonicAcAuto',['../ir__Panasonic_8h.html#aa7c839a4342205c384870e8a4f5ec36b',1,'ir_Panasonic.h']]], + ['kpanasonicacbits_2434',['kPanasonicAcBits',['../IRremoteESP8266_8h.html#a210f5c78b0f90b64dd5037698141433a',1,'IRremoteESP8266.h']]], + ['kpanasonicacchecksuminit_2435',['kPanasonicAcChecksumInit',['../ir__Panasonic_8h.html#a49329b4fef403696effcbcc5c8a86cd2',1,'ir_Panasonic.h']]], + ['kpanasonicaccool_2436',['kPanasonicAcCool',['../ir__Panasonic_8h.html#acfaa3d61fbb13fc6cd8d354f1c0a8dc7',1,'ir_Panasonic.h']]], + ['kpanasonicacdefaultrepeat_2437',['kPanasonicAcDefaultRepeat',['../IRremoteESP8266_8h.html#af6b7c6ad564253cb128ac92c00e86f0c',1,'IRremoteESP8266.h']]], + ['kpanasonicacdry_2438',['kPanasonicAcDry',['../ir__Panasonic_8h.html#a2d211bd2150a67819453f3220dc0cc91',1,'ir_Panasonic.h']]], + ['kpanasonicacexcess_2439',['kPanasonicAcExcess',['../ir__Panasonic_8h.html#adde8b69377faa9a4566dc15e95711257',1,'ir_Panasonic.h']]], + ['kpanasonicacfan_2440',['kPanasonicAcFan',['../ir__Panasonic_8h.html#a87e4dd423bbd1f879a9d5da31e1fea5e',1,'ir_Panasonic.h']]], + ['kpanasonicacfanauto_2441',['kPanasonicAcFanAuto',['../ir__Panasonic_8h.html#a7d4486fd68969af4f7230f12e865c698',1,'ir_Panasonic.h']]], + ['kpanasonicacfandelta_2442',['kPanasonicAcFanDelta',['../ir__Panasonic_8h.html#a2210f85a17fba2bbdfbb883e9fb57e52',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmax_2443',['kPanasonicAcFanMax',['../ir__Panasonic_8h.html#aa4599c84d72ab9c622b642870efb9cf1',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmed_2444',['kPanasonicAcFanMed',['../ir__Panasonic_8h.html#a978004e8e2c4122fec81c5a972b842a0',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmin_2445',['kPanasonicAcFanMin',['../ir__Panasonic_8h.html#a450c7951a525817d27351fb7c8ff2df9',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmodetemp_2446',['kPanasonicAcFanModeTemp',['../ir__Panasonic_8h.html#a76543f9d81c2d109e04359f0c61dcb99',1,'ir_Panasonic.h']]], + ['kpanasonicacheat_2447',['kPanasonicAcHeat',['../ir__Panasonic_8h.html#ac37bb7dd975a9aa803edfc108a5071ed',1,'ir_Panasonic.h']]], + ['kpanasonicacionfilterbyte_2448',['kPanasonicAcIonFilterByte',['../ir__Panasonic_8h.html#a16c946660d2ee3821dd2e30a69144a38',1,'ir_Panasonic.h']]], + ['kpanasonicacionfilteroffset_2449',['kPanasonicAcIonFilterOffset',['../ir__Panasonic_8h.html#a5c1b18d1b834e9d46cbd29c74a1b8269',1,'ir_Panasonic.h']]], + ['kpanasonicacmaxtemp_2450',['kPanasonicAcMaxTemp',['../ir__Panasonic_8h.html#a95fe6bc5b2565bf29d1a6dcee2f0c39f',1,'ir_Panasonic.h']]], + ['kpanasonicacmessagegap_2451',['kPanasonicAcMessageGap',['../ir__Panasonic_8cpp.html#a962cde97e8d98ad32f0b59172b641d6d',1,'ir_Panasonic.cpp']]], + ['kpanasonicacmintemp_2452',['kPanasonicAcMinTemp',['../ir__Panasonic_8h.html#a7861e8477904e1a572bcf35286fd3733',1,'ir_Panasonic.h']]], + ['kpanasonicacofftimeroffset_2453',['kPanasonicAcOffTimerOffset',['../ir__Panasonic_8h.html#a477b61044f1db5c296f13a404c536046',1,'ir_Panasonic.h']]], + ['kpanasonicacontimeroffset_2454',['kPanasonicAcOnTimerOffset',['../ir__Panasonic_8h.html#a64350202f82aabfd1673f0dda4d3c13d',1,'ir_Panasonic.h']]], + ['kpanasonicacpowerfulckpoffset_2455',['kPanasonicAcPowerfulCkpOffset',['../ir__Panasonic_8h.html#aa839301a08c8e49548f497e786dbb6fa',1,'ir_Panasonic.h']]], + ['kpanasonicacpowerfuloffset_2456',['kPanasonicAcPowerfulOffset',['../ir__Panasonic_8h.html#a27e9b1af4b65830015576beed69cb27d',1,'ir_Panasonic.h']]], + ['kpanasonicacpoweroffset_2457',['kPanasonicAcPowerOffset',['../ir__Panasonic_8h.html#a9e9b3d0c77ef93ab472ce14ed1534c77',1,'ir_Panasonic.h']]], + ['kpanasonicacquietckpoffset_2458',['kPanasonicAcQuietCkpOffset',['../ir__Panasonic_8h.html#a5a3779cd6fd8d573ae14ed4a6d676dba',1,'ir_Panasonic.h']]], + ['kpanasonicacquietoffset_2459',['kPanasonicAcQuietOffset',['../ir__Panasonic_8h.html#a1ec8db8798f79dead05233ee6333700d',1,'ir_Panasonic.h']]], + ['kpanasonicacsection1length_2460',['kPanasonicAcSection1Length',['../ir__Panasonic_8cpp.html#a34c6c085d468ed4b35f814452335d334',1,'ir_Panasonic.cpp']]], + ['kpanasonicacsectiongap_2461',['kPanasonicAcSectionGap',['../ir__Panasonic_8cpp.html#a3cf28f1268e8a35da220d42deda7c456',1,'ir_Panasonic.cpp']]], + ['kpanasonicacshortbits_2462',['kPanasonicAcShortBits',['../IRremoteESP8266_8h.html#a2fd1f84669f7994bb3c235a508333c6c',1,'IRremoteESP8266.h']]], + ['kpanasonicacstatelength_2463',['kPanasonicAcStateLength',['../IRremoteESP8266_8h.html#ab21d86545b57738354e7a3b833d38f94',1,'IRremoteESP8266.h']]], + ['kpanasonicacstateshortlength_2464',['kPanasonicAcStateShortLength',['../IRremoteESP8266_8h.html#a0a6ca8c1dfa6f313421ddf268d76d8e6',1,'IRremoteESP8266.h']]], + ['kpanasonicacswinghauto_2465',['kPanasonicAcSwingHAuto',['../ir__Panasonic_8h.html#a91e2933692ad98acf054c7a69f6c2018',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghfullleft_2466',['kPanasonicAcSwingHFullLeft',['../ir__Panasonic_8h.html#abf1d8c53a1b69d99019c6878f9ec220d',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghfullright_2467',['kPanasonicAcSwingHFullRight',['../ir__Panasonic_8h.html#a0e1b7a7591a0f14b2f8be3cb222f1187',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghleft_2468',['kPanasonicAcSwingHLeft',['../ir__Panasonic_8h.html#a853f2c2922e03a975bdd11efc474fa7e',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghmiddle_2469',['kPanasonicAcSwingHMiddle',['../ir__Panasonic_8h.html#afad8a7257fc178321867f16939fff7c7',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghright_2470',['kPanasonicAcSwingHRight',['../ir__Panasonic_8h.html#a282900f1c494efdc6ee057357e624d2e',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvauto_2471',['kPanasonicAcSwingVAuto',['../ir__Panasonic_8h.html#a218e2ea8c76966105c71edcb6e46cd12',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvhigh_2472',['kPanasonicAcSwingVHigh',['../ir__Panasonic_8h.html#a25c63195112c5aedc5b5bad40441c55a',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvhighest_2473',['kPanasonicAcSwingVHighest',['../ir__Panasonic_8h.html#ac1cea523d6e1da08d333e0b4acec81af',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvlow_2474',['kPanasonicAcSwingVLow',['../ir__Panasonic_8h.html#a3ae9b6c5581f1bfb5b31e252052a6c9d',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvlowest_2475',['kPanasonicAcSwingVLowest',['../ir__Panasonic_8h.html#af269e81dae5989c33199d607adcc04a0',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvmiddle_2476',['kPanasonicAcSwingVMiddle',['../ir__Panasonic_8h.html#a5d46c8234f97e10695507b17a7483d51',1,'ir_Panasonic.h']]], + ['kpanasonicactempoffset_2477',['kPanasonicAcTempOffset',['../ir__Panasonic_8h.html#a203e0351cd53db8376312a3289503175',1,'ir_Panasonic.h']]], + ['kpanasonicactempsize_2478',['kPanasonicAcTempSize',['../ir__Panasonic_8h.html#af30649a3489a4a1dc1f655d15c00e991',1,'ir_Panasonic.h']]], + ['kpanasonicactimemax_2479',['kPanasonicAcTimeMax',['../ir__Panasonic_8h.html#a61378ccad09d1a2e900123a8cbd34858',1,'ir_Panasonic.h']]], + ['kpanasonicactimeoverflowsize_2480',['kPanasonicAcTimeOverflowSize',['../ir__Panasonic_8h.html#ad7942b5ffbb2b1f7a5d9b3719592622b',1,'ir_Panasonic.h']]], + ['kpanasonicactimesize_2481',['kPanasonicAcTimeSize',['../ir__Panasonic_8h.html#a16577844a2f5ca46e2dff076952f2963',1,'ir_Panasonic.h']]], + ['kpanasonicactimespecial_2482',['kPanasonicAcTimeSpecial',['../ir__Panasonic_8h.html#aefb20e7cdbbc27e3c0725a8660a84a28',1,'ir_Panasonic.h']]], + ['kpanasonicactolerance_2483',['kPanasonicAcTolerance',['../ir__Panasonic_8h.html#a586a655b3afd82c38588fc1b61089aa1',1,'ir_Panasonic.h']]], + ['kpanasonicbitmark_2484',['kPanasonicBitMark',['../ir__Panasonic_8cpp.html#a428cd02c5dc3dc571e495efa0707cc99',1,'ir_Panasonic.cpp']]], + ['kpanasonicbitmarkticks_2485',['kPanasonicBitMarkTicks',['../ir__Panasonic_8cpp.html#aa0b259da4bc3dbf6c8b2ca31de759f55',1,'ir_Panasonic.cpp']]], + ['kpanasonicbits_2486',['kPanasonicBits',['../IRremoteESP8266_8h.html#aa148f54492be1cf8a8b285a96861a0b7',1,'IRremoteESP8266.h']]], + ['kpanasonicckp_2487',['kPanasonicCkp',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa537e8c640473597d2a1cb832498f9cb0',1,'IRsend.h']]], + ['kpanasonicdke_2488',['kPanasonicDke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fac8df2e0cfd553b0103f4c06a0fd573fd',1,'IRsend.h']]], + ['kpanasonicendgap_2489',['kPanasonicEndGap',['../ir__Panasonic_8cpp.html#a3cb2f7a925bb8374a90e3156febabb39',1,'ir_Panasonic.cpp']]], + ['kpanasonicfreq_2490',['kPanasonicFreq',['../ir__Panasonic_8h.html#af344612d7f1c0d3f8271c312f310243e',1,'ir_Panasonic.h']]], + ['kpanasonichdrmark_2491',['kPanasonicHdrMark',['../ir__Panasonic_8cpp.html#a0d36b699fead0e229c583dae94f5e8f9',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrmarkticks_2492',['kPanasonicHdrMarkTicks',['../ir__Panasonic_8cpp.html#a0f2d448b87f30840ee38c27032cd10bd',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrspace_2493',['kPanasonicHdrSpace',['../ir__Panasonic_8cpp.html#ae56b3eb80f186a63b0f69c6b4e9efce8',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrspaceticks_2494',['kPanasonicHdrSpaceTicks',['../ir__Panasonic_8cpp.html#a5fa430a5612bd21eb859356cc9c62a3c',1,'ir_Panasonic.cpp']]], + ['kpanasonicjke_2495',['kPanasonicJke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fabf39cff180c071fbc44601eeded236c4',1,'IRsend.h']]], + ['kpanasonicknowngoodstate_2496',['kPanasonicKnownGoodState',['../ir__Panasonic_8h.html#a88a9678f8b00efa173b800b0b8441f87',1,'ir_Panasonic.h']]], + ['kpanasoniclke_2497',['kPanasonicLke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa71ceb4b576a03a47f0d945323b896cd6',1,'IRsend.h']]], + ['kpanasonicmanufacturer_2498',['kPanasonicManufacturer',['../IRremoteESP8266_8h.html#a1dd1a9799e5d20d39e82ff678bf07b47',1,'IRremoteESP8266.h']]], + ['kpanasonicmincommandlength_2499',['kPanasonicMinCommandLength',['../ir__Panasonic_8cpp.html#a5f191fff3eeb722cb03bee859a016132',1,'ir_Panasonic.cpp']]], + ['kpanasonicmincommandlengthticks_2500',['kPanasonicMinCommandLengthTicks',['../ir__Panasonic_8cpp.html#aba420f9aa4c3e6f261e422962362ce31',1,'ir_Panasonic.cpp']]], + ['kpanasonicmingap_2501',['kPanasonicMinGap',['../ir__Panasonic_8cpp.html#a61592f3569c0ee4825cca185fb43236d',1,'ir_Panasonic.cpp']]], + ['kpanasonicmingapticks_2502',['kPanasonicMinGapTicks',['../ir__Panasonic_8cpp.html#aa605847e951b22f1f31b82e6b04c4bab',1,'ir_Panasonic.cpp']]], + ['kpanasonicnke_2503',['kPanasonicNke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6faf70fc847e204f60ab1dc5ecb330fc790',1,'IRsend.h']]], + ['kpanasoniconespace_2504',['kPanasonicOneSpace',['../ir__Panasonic_8cpp.html#a9069f2ab94cacbd301d7615795c155b1',1,'ir_Panasonic.cpp']]], + ['kpanasoniconespaceticks_2505',['kPanasonicOneSpaceTicks',['../ir__Panasonic_8cpp.html#aa7a8cb818a098bb8ec395af7f5dbc6d7',1,'ir_Panasonic.cpp']]], + ['kpanasonicrkr_2506',['kPanasonicRkr',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fab809a062f38eb61589cf5aa2db5789db',1,'IRsend.h']]], + ['kpanasonictick_2507',['kPanasonicTick',['../ir__Panasonic_8cpp.html#ab2fddd81fb53066257aeaa60069527a8',1,'ir_Panasonic.cpp']]], + ['kpanasonicunknown_2508',['kPanasonicUnknown',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa3b23623c9580717d0ade5137200ae2a4',1,'IRsend.h']]], + ['kpanasoniczerospace_2509',['kPanasonicZeroSpace',['../ir__Panasonic_8cpp.html#a43f64a8326fd2447653c81488673fd21',1,'ir_Panasonic.cpp']]], + ['kpanasoniczerospaceticks_2510',['kPanasonicZeroSpaceTicks',['../ir__Panasonic_8cpp.html#a58fef1468dbd4c3963be58754f38b125',1,'ir_Panasonic.cpp']]], + ['kperiodoffset_2511',['kPeriodOffset',['../IRsend_8h.html#a3a451a4e72e39a4bbf75c62af0ac62f5',1,'IRsend.h']]], + ['kpioneerbitmark_2512',['kPioneerBitMark',['../ir__Pioneer_8cpp.html#a6117fd080ad88efcf943aef53dadd1ad',1,'ir_Pioneer.cpp']]], + ['kpioneerbitmarkticks_2513',['kPioneerBitMarkTicks',['../ir__Pioneer_8cpp.html#a1cd60e52b21df3b10ac5f668cf61df16',1,'ir_Pioneer.cpp']]], + ['kpioneerbits_2514',['kPioneerBits',['../IRremoteESP8266_8h.html#a6a7ccd31e0a6f967a219b1a53b89653b',1,'IRremoteESP8266.h']]], + ['kpioneerhdrmark_2515',['kPioneerHdrMark',['../ir__Pioneer_8cpp.html#a03c4df7d9eba6ab56df0451a18e5adbd',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrmarkticks_2516',['kPioneerHdrMarkTicks',['../ir__Pioneer_8cpp.html#a9fc6ba8a158cae2d0d67af8e6cddd169',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrspace_2517',['kPioneerHdrSpace',['../ir__Pioneer_8cpp.html#a1308ff993ce7d030bdef919d65f35e62',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrspaceticks_2518',['kPioneerHdrSpaceTicks',['../ir__Pioneer_8cpp.html#a6c2ab5c384101f9184fd0960f21d13a5',1,'ir_Pioneer.cpp']]], + ['kpioneermincommandlength_2519',['kPioneerMinCommandLength',['../ir__Pioneer_8cpp.html#a22cb7d70bb0eb3b0ce6c7da3631d832f',1,'ir_Pioneer.cpp']]], + ['kpioneermincommandlengthticks_2520',['kPioneerMinCommandLengthTicks',['../ir__Pioneer_8cpp.html#a472ab59d00c439cc8832081492e742cc',1,'ir_Pioneer.cpp']]], + ['kpioneermingap_2521',['kPioneerMinGap',['../ir__Pioneer_8cpp.html#adc67bf557bd3474f18dfaa3125c1af41',1,'ir_Pioneer.cpp']]], + ['kpioneermingapticks_2522',['kPioneerMinGapTicks',['../ir__Pioneer_8cpp.html#abe0ebf83502225b39926ab745a8f8be2',1,'ir_Pioneer.cpp']]], + ['kpioneeronespace_2523',['kPioneerOneSpace',['../ir__Pioneer_8cpp.html#a5238b059346168128184bca93de16a54',1,'ir_Pioneer.cpp']]], + ['kpioneeronespaceticks_2524',['kPioneerOneSpaceTicks',['../ir__Pioneer_8cpp.html#af637842c88b54a022ac1ba3fef3fa041',1,'ir_Pioneer.cpp']]], + ['kpioneertick_2525',['kPioneerTick',['../ir__Pioneer_8cpp.html#a63de2364627344f86537ac82447c5cb4',1,'ir_Pioneer.cpp']]], + ['kpioneerzerospace_2526',['kPioneerZeroSpace',['../ir__Pioneer_8cpp.html#a3c6428f201dd3e32c171d6db44269d67',1,'ir_Pioneer.cpp']]], + ['kpioneerzerospaceticks_2527',['kPioneerZeroSpaceTicks',['../ir__Pioneer_8cpp.html#acdeea63204ce47f1556fa31bbed8a4a4',1,'ir_Pioneer.cpp']]], + ['kpowerbuttonstr_2528',['kPowerButtonStr',['../IRtext_8cpp.html#a69d36084b1410a06aa780edcda9428dd',1,'kPowerButtonStr(): IRtext.cpp'],['../IRtext_8h.html#adb54b8d070a4ba7f08b7d2d0f1c03d1c',1,'kPowerButtonStr(): IRtext.cpp']]], + ['kpowerfulstr_2529',['kPowerfulStr',['../IRtext_8cpp.html#a5dfc12bfa12ddf7da3ab6c216258284a',1,'kPowerfulStr(): IRtext.cpp'],['../IRtext_8h.html#a7980630cd028febca8245730dffa684b',1,'kPowerfulStr(): IRtext.cpp']]], + ['kpowerstr_2530',['kPowerStr',['../IRtext_8cpp.html#a5b4b43efe1f1c27d6aee90ebb3500792',1,'kPowerStr(): IRtext.cpp'],['../IRtext_8h.html#a47a76dc8d87d9694a36c6417d7e19dda',1,'kPowerStr(): IRtext.cpp']]], + ['kpowertogglestr_2531',['kPowerToggleStr',['../IRtext_8cpp.html#a2f7e242dc28cf61fb718bb5c1b681642',1,'kPowerToggleStr(): IRtext.cpp'],['../IRtext_8h.html#afd802a94c6146efb7812ef89f3bf0cc5',1,'kPowerToggleStr(): IRtext.cpp']]], + ['kpreviouspowerstr_2532',['kPreviousPowerStr',['../IRtext_8cpp.html#a2a5cd83ac519798debd7065eb03d5d72',1,'kPreviousPowerStr(): IRtext.cpp'],['../IRtext_8h.html#a9833364e538f50be227ff6c0b01f8f7c',1,'kPreviousPowerStr(): IRtext.cpp']]], + ['kprontodataoffset_2533',['kProntoDataOffset',['../ir__Pronto_8cpp.html#ac073b9ac759e09091b3d80af747656a1',1,'ir_Pronto.cpp']]], + ['kprontofreqfactor_2534',['kProntoFreqFactor',['../ir__Pronto_8cpp.html#aa63eef9baeb563c8494d85d13b956db8',1,'ir_Pronto.cpp']]], + ['kprontofreqoffset_2535',['kProntoFreqOffset',['../ir__Pronto_8cpp.html#a2fae4105559199e292121bcb847d9d52',1,'ir_Pronto.cpp']]], + ['kprontominlength_2536',['kProntoMinLength',['../IRremoteESP8266_8h.html#a25dd42234e21d41b0b4bc97e1fe921c4',1,'IRremoteESP8266.h']]], + ['kprontoseq1lenoffset_2537',['kProntoSeq1LenOffset',['../ir__Pronto_8cpp.html#a1df51305dddf233fc3963856e288366f',1,'ir_Pronto.cpp']]], + ['kprontoseq2lenoffset_2538',['kProntoSeq2LenOffset',['../ir__Pronto_8cpp.html#a708744a9f82547e5abc17d7ed866a648',1,'ir_Pronto.cpp']]], + ['kprontotypeoffset_2539',['kProntoTypeOffset',['../ir__Pronto_8cpp.html#a603ff34f28f270a98bf0bebdaf19bfbc',1,'ir_Pronto.cpp']]], + ['kprotocolstr_2540',['kProtocolStr',['../IRtext_8cpp.html#afb9e901ded9e88a48218282a7446ff63',1,'kProtocolStr(): IRtext.cpp'],['../IRtext_8h.html#ac50f97a0d33041fe4bba6e02c500c8ef',1,'kProtocolStr(): IRtext.cpp']]], + ['kpurifystr_2541',['kPurifyStr',['../IRtext_8cpp.html#a85c2b59f6cba1878648d3d8fe9d7f9a4',1,'kPurifyStr(): IRtext.cpp'],['../IRtext_8h.html#aae574dbb4b9f70db0e64386d61c21beb',1,'kPurifyStr(): IRtext.cpp']]], + ['kquietstr_2542',['kQuietStr',['../IRtext_8cpp.html#a6f85e3119eb884455f474ff909be6b53',1,'kQuietStr(): IRtext.cpp'],['../IRtext_8h.html#a7086660370d73d6f499972cf802db8f7',1,'kQuietStr(): IRtext.cpp']]], + ['krawbuf_2543',['kRawBuf',['../IRrecv_8h.html#aadfa37def10a1adeaf2cf4c09d7504e3',1,'IRrecv.h']]], + ['krawtick_2544',['kRawTick',['../IRrecv_8h.html#a373dde69c312b0122665e581eea1297b',1,'IRrecv.h']]], + ['krc5bits_2545',['kRC5Bits',['../IRremoteESP8266_8h.html#ad0935984e6518e340562665742199483',1,'IRremoteESP8266.h']]], + ['krc5mincommandlength_2546',['kRc5MinCommandLength',['../ir__RC5__RC6_8cpp.html#a32b5997148b53fd2984388f6d0384c35',1,'ir_RC5_RC6.cpp']]], + ['krc5mingap_2547',['kRc5MinGap',['../ir__RC5__RC6_8cpp.html#a26580409f593179d838c465647e35c41',1,'ir_RC5_RC6.cpp']]], + ['krc5rawbits_2548',['kRC5RawBits',['../IRremoteESP8266_8h.html#a955183d3358fcafea853014ddd890574',1,'IRremoteESP8266.h']]], + ['krc5samplesmin_2549',['kRc5SamplesMin',['../ir__RC5__RC6_8cpp.html#aa206173838597c760b4a01c36bbc771a',1,'ir_RC5_RC6.cpp']]], + ['krc5t1_2550',['kRc5T1',['../ir__RC5__RC6_8cpp.html#aa42cae15fa77a196eb8f198de09e19eb',1,'ir_RC5_RC6.cpp']]], + ['krc5togglemask_2551',['kRc5ToggleMask',['../ir__RC5__RC6_8cpp.html#ae3485c1c157d6d84a0385cb1bfb8833a',1,'ir_RC5_RC6.cpp']]], + ['krc5xbits_2552',['kRC5XBits',['../IRremoteESP8266_8h.html#abec3ebb217126560e824fa8b66d495bc',1,'IRremoteESP8266.h']]], + ['krc6_5f36bits_2553',['kRC6_36Bits',['../IRremoteESP8266_8h.html#a30a2cb328aa0d47f53aba56055ac74e0',1,'IRremoteESP8266.h']]], + ['krc6_5f36togglemask_2554',['kRc6_36ToggleMask',['../ir__RC5__RC6_8cpp.html#a31ae862ce2a43edd99bda647262b18fa',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrmark_2555',['kRc6HdrMark',['../ir__RC5__RC6_8cpp.html#ae05bbb9f690cc92feb0a9c14b3b8c477',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrmarkticks_2556',['kRc6HdrMarkTicks',['../ir__RC5__RC6_8cpp.html#aff2a5bc05ddf61d289c44a4fd093009c',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrspace_2557',['kRc6HdrSpace',['../ir__RC5__RC6_8cpp.html#a0196311c9b116cf48c8f901fb6c93ac3',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrspaceticks_2558',['kRc6HdrSpaceTicks',['../ir__RC5__RC6_8cpp.html#a35a9cc59fe5251a34c88e34b6a507fd3',1,'ir_RC5_RC6.cpp']]], + ['krc6mode0bits_2559',['kRC6Mode0Bits',['../IRremoteESP8266_8h.html#a84a6d3e15e98f7a4917d252d5665534a',1,'IRremoteESP8266.h']]], + ['krc6rptlength_2560',['kRc6RptLength',['../ir__RC5__RC6_8cpp.html#a4989f36b790a99545e708c8681b6b961',1,'ir_RC5_RC6.cpp']]], + ['krc6rptlengthticks_2561',['kRc6RptLengthTicks',['../ir__RC5__RC6_8cpp.html#acf2dc0074bfe7671deb8985eba4396e3',1,'ir_RC5_RC6.cpp']]], + ['krc6tick_2562',['kRc6Tick',['../ir__RC5__RC6_8cpp.html#aad98dc2541039634817609d4e297322f',1,'ir_RC5_RC6.cpp']]], + ['krc6togglemask_2563',['kRc6ToggleMask',['../ir__RC5__RC6_8cpp.html#a4df09270c1e9cda504026189e30829ff',1,'ir_RC5_RC6.cpp']]], + ['krcmmbitmark_2564',['kRcmmBitMark',['../ir__RCMM_8cpp.html#ad768f62bbd7e4df567c3e53ea0a8ed06',1,'ir_RCMM.cpp']]], + ['krcmmbitmarkticks_2565',['kRcmmBitMarkTicks',['../ir__RCMM_8cpp.html#a48aeb7992d30f8c7cfa04dbd14ea0996',1,'ir_RCMM.cpp']]], + ['krcmmbits_2566',['kRCMMBits',['../IRremoteESP8266_8h.html#a2bfaf393c2d77a594f2a0a5a763e84f5',1,'IRremoteESP8266.h']]], + ['krcmmbitspace0_2567',['kRcmmBitSpace0',['../ir__RCMM_8cpp.html#a34a7b22107461be18500f6d1ddf979e3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace0ticks_2568',['kRcmmBitSpace0Ticks',['../ir__RCMM_8cpp.html#a0864042e8c098169d1d221fbd798cda3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace1_2569',['kRcmmBitSpace1',['../ir__RCMM_8cpp.html#a812b9895f0eccaaf78752dc7030022aa',1,'ir_RCMM.cpp']]], + ['krcmmbitspace1ticks_2570',['kRcmmBitSpace1Ticks',['../ir__RCMM_8cpp.html#a89f945e0a91feccd505f0b8310a9ebb9',1,'ir_RCMM.cpp']]], + ['krcmmbitspace2_2571',['kRcmmBitSpace2',['../ir__RCMM_8cpp.html#aff0db6a8f28d3a307cd7bbb6dc90e3e3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace2ticks_2572',['kRcmmBitSpace2Ticks',['../ir__RCMM_8cpp.html#a592dda1dd9239c9a015163b80cddf859',1,'ir_RCMM.cpp']]], + ['krcmmbitspace3_2573',['kRcmmBitSpace3',['../ir__RCMM_8cpp.html#a5e6351cbcb4c576871584dbf61d87d33',1,'ir_RCMM.cpp']]], + ['krcmmbitspace3ticks_2574',['kRcmmBitSpace3Ticks',['../ir__RCMM_8cpp.html#aa3f7d7e37ffa6bf9649eef7720770767',1,'ir_RCMM.cpp']]], + ['krcmmexcess_2575',['kRcmmExcess',['../ir__RCMM_8cpp.html#a3845e23031e92fd008157b0f95827432',1,'ir_RCMM.cpp']]], + ['krcmmhdrmark_2576',['kRcmmHdrMark',['../ir__RCMM_8cpp.html#a7fc5d5c1dc89ef0615fcaebaacc504df',1,'ir_RCMM.cpp']]], + ['krcmmhdrmarkticks_2577',['kRcmmHdrMarkTicks',['../ir__RCMM_8cpp.html#a00e93c94548ac081083ed2cabd614330',1,'ir_RCMM.cpp']]], + ['krcmmhdrspace_2578',['kRcmmHdrSpace',['../ir__RCMM_8cpp.html#af4dc2548c8069caf889612b3b28895ea',1,'ir_RCMM.cpp']]], + ['krcmmhdrspaceticks_2579',['kRcmmHdrSpaceTicks',['../ir__RCMM_8cpp.html#a87cd8bb5322fb38aecd20362a7df5016',1,'ir_RCMM.cpp']]], + ['krcmmmingap_2580',['kRcmmMinGap',['../ir__RCMM_8cpp.html#a94f9533bf18c0a2c2b6511ffa95ff5dc',1,'ir_RCMM.cpp']]], + ['krcmmmingapticks_2581',['kRcmmMinGapTicks',['../ir__RCMM_8cpp.html#aacb274f2da878aed511f6ab400cd51e9',1,'ir_RCMM.cpp']]], + ['krcmmrptlength_2582',['kRcmmRptLength',['../ir__RCMM_8cpp.html#a1dccf2b944d4eeb8b7dd2a1f66548a68',1,'ir_RCMM.cpp']]], + ['krcmmrptlengthticks_2583',['kRcmmRptLengthTicks',['../ir__RCMM_8cpp.html#a4cd637fa0a6071f9ea0b52c346ffe7f0',1,'ir_RCMM.cpp']]], + ['krcmmtick_2584',['kRcmmTick',['../ir__RCMM_8cpp.html#a9e1a3a26185d58ff675eec7485bc671f',1,'ir_RCMM.cpp']]], + ['krcmmtolerance_2585',['kRcmmTolerance',['../ir__RCMM_8cpp.html#a4b95480078186b3498ca6426e5bbc428',1,'ir_RCMM.cpp']]], + ['krcz01channelmask_2586',['kRcz01ChannelMask',['../ir__Doshisha_8cpp.html#a085b3d47e4cf8d8b4ba999ae58ec3533',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel1_2587',['kRcz01CommandLevel1',['../ir__Doshisha_8cpp.html#a436b801a282374de0f28e27828e1c4bf',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel2_2588',['kRcz01CommandLevel2',['../ir__Doshisha_8cpp.html#a311ef41fff985236216238565219bfe7',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel3_2589',['kRcz01CommandLevel3',['../ir__Doshisha_8cpp.html#a879bd44f482c87fbaf9fecaad8ed4c6d',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel4_2590',['kRcz01CommandLevel4',['../ir__Doshisha_8cpp.html#a52bad85f1a3918e3031297a6c6074b45',1,'ir_Doshisha.cpp']]], + ['krcz01commandleveldown_2591',['kRcz01CommandLevelDown',['../ir__Doshisha_8cpp.html#a1678269506503f1abf871ed0af6dcc2b',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevelup_2592',['kRcz01CommandLevelUp',['../ir__Doshisha_8cpp.html#a4eba011d2b110a5348783534e957660e',1,'ir_Doshisha.cpp']]], + ['krcz01commandmask_2593',['kRcz01CommandMask',['../ir__Doshisha_8cpp.html#a148e2f676f895f4e3b77b39780e2ca94',1,'ir_Doshisha.cpp']]], + ['krcz01commandnightlight_2594',['kRcz01CommandNightLight',['../ir__Doshisha_8cpp.html#a47e9d5bf353cf8aef8199fb74693aa0f',1,'ir_Doshisha.cpp']]], + ['krcz01commandoff_2595',['kRcz01CommandOff',['../ir__Doshisha_8cpp.html#a97fd32975ab9fafa85e0704964780773',1,'ir_Doshisha.cpp']]], + ['krcz01commandon_2596',['kRcz01CommandOn',['../ir__Doshisha_8cpp.html#a7377eac8b1d938903fd43d7505dd8a49',1,'ir_Doshisha.cpp']]], + ['krcz01commandswitchchannel_2597',['kRcz01CommandSwitchChannel',['../ir__Doshisha_8cpp.html#afcd3fe98c34ef9572c1a68bd143e128b',1,'ir_Doshisha.cpp']]], + ['krcz01commandtimmer30_2598',['kRcz01CommandTimmer30',['../ir__Doshisha_8cpp.html#a3deebab67d01756f7776f0d11cbdef6e',1,'ir_Doshisha.cpp']]], + ['krcz01commandtimmer60_2599',['kRcz01CommandTimmer60',['../ir__Doshisha_8cpp.html#abac6b50227512508aeb5b6042a8380fd',1,'ir_Doshisha.cpp']]], + ['krcz01signature_2600',['kRcz01Signature',['../ir__Doshisha_8cpp.html#a35c6dff74ae1702933e33f02f743f616',1,'ir_Doshisha.cpp']]], + ['krcz01signaturemask_2601',['kRcz01SignatureMask',['../ir__Doshisha_8cpp.html#a1f3b9cdfba7cc7515611d7145b7318a5',1,'ir_Doshisha.cpp']]], + ['krepeat_2602',['kRepeat',['../IRrecv_8h.html#ae8b11750ba7f2e2d56343f770720ed89',1,'IRrecv.h']]], + ['krepeatstr_2603',['kRepeatStr',['../IRtext_8cpp.html#ad55ef2e023915f39c7ce77e7eeb1ad76',1,'kRepeatStr(): IRtext.cpp'],['../IRtext_8h.html#a74a53cc1564f75b36269eb1ca8c6235b',1,'kRepeatStr(): IRtext.cpp']]], + ['kright_2604',['kRight',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a2dd2b017192f8a09367d48c7648213c9',1,'stdAc']]], + ['krightmax_2605',['kRightMax',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a856bf9929ade459f451be17c97db4b32',1,'stdAc']]], + ['krightmaxstr_2606',['kRightMaxStr',['../IRtext_8cpp.html#af3e63659779f5fdb4aded4861521e564',1,'kRightMaxStr(): IRtext.cpp'],['../IRtext_8h.html#ac7a90008560fd1e7b4ed240f354d8fae',1,'kRightMaxStr(): IRtext.cpp']]], + ['krightstr_2607',['kRightStr',['../IRtext_8cpp.html#aacc9b0b21efb6053b75ed117d4ab9105',1,'kRightStr(): IRtext.cpp'],['../IRtext_8h.html#a953f9c48fcf87e81bf6f383e8fe8b1dd',1,'kRightStr(): IRtext.cpp']]], + ['kroomstr_2608',['kRoomStr',['../IRtext_8cpp.html#ab3f02ff54af9a94fd57d098838a4a642',1,'kRoomStr(): IRtext.cpp'],['../IRtext_8h.html#a5358a85538e4643c1cc109a7a0b90079',1,'kRoomStr(): IRtext.cpp']]], + ['ksamsung36bits_2609',['kSamsung36Bits',['../IRremoteESP8266_8h.html#a5e1e6f30a41f0d94652429a9e1034179',1,'IRremoteESP8266.h']]], + ['ksamsungacauto_2610',['kSamsungAcAuto',['../ir__Samsung_8h.html#a1b05ff970f45c57b13fc13d11e95396b',1,'ir_Samsung.h']]], + ['ksamsungacautotemp_2611',['kSamsungAcAutoTemp',['../ir__Samsung_8h.html#a87bb469afc0e2b6bad44634f3ba5e0ef',1,'ir_Samsung.h']]], + ['ksamsungacbeepoffset_2612',['kSamsungAcBeepOffset',['../ir__Samsung_8h.html#a12ae1e43d05d39c39d335c97223e003e',1,'ir_Samsung.h']]], + ['ksamsungacbitmark_2613',['kSamsungAcBitMark',['../ir__Samsung_8cpp.html#a37e6f36939f1a12ffe52907bbb64a4cf',1,'ir_Samsung.cpp']]], + ['ksamsungacbits_2614',['kSamsungAcBits',['../IRremoteESP8266_8h.html#adebe85ab48eb876ec15daacca246797c',1,'IRremoteESP8266.h']]], + ['ksamsungacbreezeoffset_2615',['kSamsungAcBreezeOffset',['../ir__Samsung_8h.html#a31d5463b3819fe41ce078b085c395a40',1,'ir_Samsung.h']]], + ['ksamsungacbreezeon_2616',['kSamsungAcBreezeOn',['../ir__Samsung_8h.html#a06299ba6942969f7b9472e752b50d4d7',1,'ir_Samsung.h']]], + ['ksamsungacbreezesize_2617',['kSamsungAcBreezeSize',['../ir__Samsung_8h.html#a1f6ec492aa58cb704147213e3b6f9f24',1,'ir_Samsung.h']]], + ['ksamsungacclean10offset_2618',['kSamsungAcClean10Offset',['../ir__Samsung_8h.html#a0982038a8c3e27972e69b83c350a0ff3',1,'ir_Samsung.h']]], + ['ksamsungacclean11offset_2619',['kSamsungAcClean11Offset',['../ir__Samsung_8h.html#a87666330f9a410ced00bf15c5f22daf2',1,'ir_Samsung.h']]], + ['ksamsungaccool_2620',['kSamsungAcCool',['../ir__Samsung_8h.html#a24d40e01f046f887b7d41dad67ad7555',1,'ir_Samsung.h']]], + ['ksamsungacdefaultrepeat_2621',['kSamsungAcDefaultRepeat',['../IRremoteESP8266_8h.html#a973f4e0189fc10805f67b67f708be1e4',1,'IRremoteESP8266.h']]], + ['ksamsungacdisplayoffset_2622',['kSamsungAcDisplayOffset',['../ir__Samsung_8h.html#af47c9229cbe569b93ad5f4986c4484ab',1,'ir_Samsung.h']]], + ['ksamsungacdry_2623',['kSamsungAcDry',['../ir__Samsung_8h.html#a6423976c7a41f526e7a878cecb257bbd',1,'ir_Samsung.h']]], + ['ksamsungacextendedbits_2624',['kSamsungAcExtendedBits',['../IRremoteESP8266_8h.html#a296e700965e70a622fe99675ff0438af',1,'IRremoteESP8266.h']]], + ['ksamsungacextendedstatelength_2625',['kSamsungAcExtendedStateLength',['../IRremoteESP8266_8h.html#a28039071f1130e9bc86efddd8265cbf9',1,'IRremoteESP8266.h']]], + ['ksamsungacfan_2626',['kSamsungAcFan',['../ir__Samsung_8h.html#a61d825254b26894a2f097ad92a7dbff2',1,'ir_Samsung.h']]], + ['ksamsungacfanauto_2627',['kSamsungAcFanAuto',['../ir__Samsung_8h.html#a37b29911f4d2b71dcdbd18a5d6dc301a',1,'ir_Samsung.h']]], + ['ksamsungacfanauto2_2628',['kSamsungAcFanAuto2',['../ir__Samsung_8h.html#aafa4319fb523b14d58371f757497e82a',1,'ir_Samsung.h']]], + ['ksamsungacfanhigh_2629',['kSamsungAcFanHigh',['../ir__Samsung_8h.html#a52cccad28fad5b9886ef408af02f56f9',1,'ir_Samsung.h']]], + ['ksamsungacfanlow_2630',['kSamsungAcFanLow',['../ir__Samsung_8h.html#a6f16b5b3f2dea3461f5d44379e8b8634',1,'ir_Samsung.h']]], + ['ksamsungacfanmed_2631',['kSamsungAcFanMed',['../ir__Samsung_8h.html#a798c3544dbd6bb6c8622cf45f88abc14',1,'ir_Samsung.h']]], + ['ksamsungacfanoffest_2632',['kSamsungAcFanOffest',['../ir__Samsung_8h.html#a1dd4a351c1a036972f741fbdafb05a7e',1,'ir_Samsung.h']]], + ['ksamsungacfansize_2633',['kSamsungAcFanSize',['../ir__Samsung_8h.html#a5b055e9951e23ba44bf1fdeed805b332',1,'ir_Samsung.h']]], + ['ksamsungacfanturbo_2634',['kSamsungAcFanTurbo',['../ir__Samsung_8h.html#af6c1432748eaa19df35531b87d197095',1,'ir_Samsung.h']]], + ['ksamsungachdrmark_2635',['kSamsungAcHdrMark',['../ir__Samsung_8cpp.html#ab7385ca5b7b417753b253a0f7cb3721b',1,'ir_Samsung.cpp']]], + ['ksamsungachdrspace_2636',['kSamsungAcHdrSpace',['../ir__Samsung_8cpp.html#a1b1f903fff13b10fb2431be9373e27cb',1,'ir_Samsung.cpp']]], + ['ksamsungacheat_2637',['kSamsungAcHeat',['../ir__Samsung_8h.html#a44ce6be7046ec4b4fe9caba7b71b8f0d',1,'ir_Samsung.h']]], + ['ksamsungacionoffset_2638',['kSamsungAcIonOffset',['../ir__Samsung_8h.html#aa7bbd222553072c092158421d1b9977f',1,'ir_Samsung.h']]], + ['ksamsungacmaxtemp_2639',['kSamsungAcMaxTemp',['../ir__Samsung_8h.html#a0a994796db81a3d56dd2c27cad448a71',1,'ir_Samsung.h']]], + ['ksamsungacmintemp_2640',['kSamsungAcMinTemp',['../ir__Samsung_8h.html#ad5f46ccb96335519f5633c33de0d8018',1,'ir_Samsung.h']]], + ['ksamsungacmodeoffset_2641',['kSamsungAcModeOffset',['../ir__Samsung_8h.html#a64b2aceb5c0d4dbea2d4697efe65aef2',1,'ir_Samsung.h']]], + ['ksamsungaconespace_2642',['kSamsungAcOneSpace',['../ir__Samsung_8cpp.html#ab106d9b7efb165eed83ae2ccef9a49b4',1,'ir_Samsung.cpp']]], + ['ksamsungacpower1offset_2643',['kSamsungAcPower1Offset',['../ir__Samsung_8h.html#aa6a4ff05acfabf24e4dfc126e583c46c',1,'ir_Samsung.h']]], + ['ksamsungacpower6offset_2644',['kSamsungAcPower6Offset',['../ir__Samsung_8h.html#a90591c7d6069d81493f894328d595187',1,'ir_Samsung.h']]], + ['ksamsungacpower6size_2645',['kSamsungAcPower6Size',['../ir__Samsung_8h.html#ace0a7a2cfedbb77d05de53abc5906992',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10offset_2646',['kSamsungAcPowerful10Offset',['../ir__Samsung_8h.html#a7f92d734af799e058723e898d3ebdd30',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10on_2647',['kSamsungAcPowerful10On',['../ir__Samsung_8h.html#aa05bb4788febba1f56b2b3929ac273a3',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10size_2648',['kSamsungAcPowerful10Size',['../ir__Samsung_8h.html#a19ede17e420f68ea552497461e69006a',1,'ir_Samsung.h']]], + ['ksamsungacpowerfulmask8_2649',['kSamsungAcPowerfulMask8',['../ir__Samsung_8h.html#a39e23325e35688a3641c467b720381ce',1,'ir_Samsung.h']]], + ['ksamsungacpowersection_2650',['kSamsungAcPowerSection',['../ir__Samsung_8h.html#a9264b5d640d9052c153562fd38415676',1,'ir_Samsung.h']]], + ['ksamsungacquiet1offset_2651',['kSamsungAcQuiet1Offset',['../ir__Samsung_8h.html#ab029485b433f7eef6413d8194790c566',1,'ir_Samsung.h']]], + ['ksamsungacquiet5offset_2652',['kSamsungAcQuiet5Offset',['../ir__Samsung_8h.html#ae10abd66772da9bab4ba266f29e7ec75',1,'ir_Samsung.h']]], + ['ksamsungacsectiongap_2653',['kSamsungAcSectionGap',['../ir__Samsung_8cpp.html#a9752fc615c215a93c1ee65edca3a359e',1,'ir_Samsung.cpp']]], + ['ksamsungacsectionlength_2654',['kSamsungAcSectionLength',['../ir__Samsung_8h.html#ad3faedf7b111f1b91d671666e38ce6f3',1,'ir_Samsung.h']]], + ['ksamsungacsectionmark_2655',['kSamsungAcSectionMark',['../ir__Samsung_8cpp.html#a4304073cddaa2da9613dedce499fee56',1,'ir_Samsung.cpp']]], + ['ksamsungacsections_2656',['kSamsungAcSections',['../ir__Samsung_8cpp.html#a86185d98d6e891a17688d9d2a0fa7114',1,'ir_Samsung.cpp']]], + ['ksamsungacsectionspace_2657',['kSamsungAcSectionSpace',['../ir__Samsung_8cpp.html#a4837f502ef9b7c972ec409cf4fc3c605',1,'ir_Samsung.cpp']]], + ['ksamsungacstatelength_2658',['kSamsungAcStateLength',['../IRremoteESP8266_8h.html#a2d07d8c8917fee072a261d00e67e0d36',1,'IRremoteESP8266.h']]], + ['ksamsungacswingmove_2659',['kSamsungAcSwingMove',['../ir__Samsung_8h.html#ab2d2b422e3972f77aef23f77c7cfbbac',1,'ir_Samsung.h']]], + ['ksamsungacswingoffset_2660',['kSamsungAcSwingOffset',['../ir__Samsung_8h.html#ab71772d77c56cf4d01f3ce4ab751a55c',1,'ir_Samsung.h']]], + ['ksamsungacswingsize_2661',['kSamsungAcSwingSize',['../ir__Samsung_8h.html#a1b50618058108826f9103f46bf7677ee',1,'ir_Samsung.h']]], + ['ksamsungacswingstop_2662',['kSamsungAcSwingStop',['../ir__Samsung_8h.html#a37c1720d66c4ba02e368946e53036367',1,'ir_Samsung.h']]], + ['ksamsungaczerospace_2663',['kSamsungAcZeroSpace',['../ir__Samsung_8cpp.html#a7492a25e730f93f22c099ab687621b18',1,'ir_Samsung.cpp']]], + ['ksamsungbitmark_2664',['kSamsungBitMark',['../ir__Samsung_8cpp.html#a03f9ae317a7a701437c8015dfde4401f',1,'ir_Samsung.cpp']]], + ['ksamsungbitmarkticks_2665',['kSamsungBitMarkTicks',['../ir__Samsung_8cpp.html#afe1663f83396f7e5cf9bfc32f321e539',1,'ir_Samsung.cpp']]], + ['ksamsungbits_2666',['kSamsungBits',['../IRremoteESP8266_8h.html#a7c1c015cce09284799cbf5a2f21ee170',1,'IRremoteESP8266.h']]], + ['ksamsunghdrmark_2667',['kSamsungHdrMark',['../ir__Samsung_8cpp.html#a3d0598585af609af4c8d5004789d2df7',1,'ir_Samsung.cpp']]], + ['ksamsunghdrmarkticks_2668',['kSamsungHdrMarkTicks',['../ir__Samsung_8cpp.html#a0c81f486877d24bfd40215b089c52f2a',1,'ir_Samsung.cpp']]], + ['ksamsunghdrspace_2669',['kSamsungHdrSpace',['../ir__Samsung_8cpp.html#a2f55c53bfc72de06ff202c8ec401163d',1,'ir_Samsung.cpp']]], + ['ksamsunghdrspaceticks_2670',['kSamsungHdrSpaceTicks',['../ir__Samsung_8cpp.html#a1ae96cedfa4ed26869d295cfbb8056dd',1,'ir_Samsung.cpp']]], + ['ksamsungmingap_2671',['kSamsungMinGap',['../ir__Samsung_8cpp.html#ab13edb242547803b386aa8539a4b9470',1,'ir_Samsung.cpp']]], + ['ksamsungmingapticks_2672',['kSamsungMinGapTicks',['../ir__Samsung_8cpp.html#a55d79dcfcd43f05ebe456a9a2fce3ff0',1,'ir_Samsung.cpp']]], + ['ksamsungminmessagelength_2673',['kSamsungMinMessageLength',['../ir__Samsung_8cpp.html#ae2ec2e45f91f872e85c250c7aac0efc1',1,'ir_Samsung.cpp']]], + ['ksamsungminmessagelengthticks_2674',['kSamsungMinMessageLengthTicks',['../ir__Samsung_8cpp.html#a6d436a1b71158ff9b5d7ae21344cd7d2',1,'ir_Samsung.cpp']]], + ['ksamsungonespace_2675',['kSamsungOneSpace',['../ir__Samsung_8cpp.html#ab486b048d13f44623ee291d4221c2a1b',1,'ir_Samsung.cpp']]], + ['ksamsungonespaceticks_2676',['kSamsungOneSpaceTicks',['../ir__Samsung_8cpp.html#a484a1e3ce3dcbbef15be559bfb5822d0',1,'ir_Samsung.cpp']]], + ['ksamsungrptspace_2677',['kSamsungRptSpace',['../ir__Samsung_8cpp.html#a1cc2f3bcd7f2ca36f0a726828c14aa74',1,'ir_Samsung.cpp']]], + ['ksamsungrptspaceticks_2678',['kSamsungRptSpaceTicks',['../ir__Samsung_8cpp.html#a6864f78ad1428358acbc8b46796e50cc',1,'ir_Samsung.cpp']]], + ['ksamsungtick_2679',['kSamsungTick',['../ir__Samsung_8cpp.html#accd7d51c2714bd383170831372f57bc5',1,'ir_Samsung.cpp']]], + ['ksamsungzerospace_2680',['kSamsungZeroSpace',['../ir__Samsung_8cpp.html#ae2c828a3d099d6195208a3794022587e',1,'ir_Samsung.cpp']]], + ['ksamsungzerospaceticks_2681',['kSamsungZeroSpaceTicks',['../ir__Samsung_8cpp.html#aea63a73a5b0af2c173bc473ee2447a93',1,'ir_Samsung.cpp']]], + ['ksanyolc7461addressbits_2682',['kSanyoLC7461AddressBits',['../IRremoteESP8266_8h.html#a7e15e988acbea0fb4dfaee6f5bfa12d0',1,'IRremoteESP8266.h']]], + ['ksanyolc7461addressmask_2683',['kSanyoLc7461AddressMask',['../ir__Sanyo_8cpp.html#a785ccc066e433f11791f8a30243944d3',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461bitmark_2684',['kSanyoLc7461BitMark',['../ir__Sanyo_8cpp.html#a1360ba5ac3f30715c00a6a65155cfec8',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461bits_2685',['kSanyoLC7461Bits',['../IRremoteESP8266_8h.html#ad067db05b273337e0df38d529094c9e8',1,'IRremoteESP8266.h']]], + ['ksanyolc7461commandbits_2686',['kSanyoLC7461CommandBits',['../IRremoteESP8266_8h.html#a5cd69a192be51634ce72a40398a6c0d7',1,'IRremoteESP8266.h']]], + ['ksanyolc7461commandmask_2687',['kSanyoLc7461CommandMask',['../ir__Sanyo_8cpp.html#abdd072e210a7616d564a9d4a7f798ad3',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461hdrmark_2688',['kSanyoLc7461HdrMark',['../ir__Sanyo_8cpp.html#a0b2e520442dd96f8cd77969230713277',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461hdrspace_2689',['kSanyoLc7461HdrSpace',['../ir__Sanyo_8cpp.html#aa9ca2469e22f66d6e5e3f4ef952484ba',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461mincommandlength_2690',['kSanyoLc7461MinCommandLength',['../ir__Sanyo_8cpp.html#a237fac9264bba0014124a815133868b2',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461mingap_2691',['kSanyoLc7461MinGap',['../ir__Sanyo_8cpp.html#aff7f31500dbe9939e223bed6b6c631a8',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461onespace_2692',['kSanyoLc7461OneSpace',['../ir__Sanyo_8cpp.html#a52716e37d6943b01e9df37956f1a83de',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461zerospace_2693',['kSanyoLc7461ZeroSpace',['../ir__Sanyo_8cpp.html#a4e386992c8fca642c259e86e34729a4d',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bbits_2694',['kSanyoSA8650BBits',['../IRremoteESP8266_8h.html#a2c572c8bfa811b7dc3a8a537cc642b85',1,'IRremoteESP8266.h']]], + ['ksanyosa8650bdoublespaceusecs_2695',['kSanyoSa8650bDoubleSpaceUsecs',['../ir__Sanyo_8cpp.html#a828caf6fd05e81cedee67c558b88a0b6',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bhdrmark_2696',['kSanyoSa8650bHdrMark',['../ir__Sanyo_8cpp.html#a9d0472d183a96b8ca71a2b704a06cac8',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bhdrspace_2697',['kSanyoSa8650bHdrSpace',['../ir__Sanyo_8cpp.html#ab432df3bd299b72b4449672d611798b7',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bonemark_2698',['kSanyoSa8650bOneMark',['../ir__Sanyo_8cpp.html#a8854c7bd32c1ec53e8e1869cd9dd8cdd',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650brptlength_2699',['kSanyoSa8650bRptLength',['../ir__Sanyo_8cpp.html#a327ee6de7027aacfa9aa6ee8bdc74e3e',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bzeromark_2700',['kSanyoSa8650bZeroMark',['../ir__Sanyo_8cpp.html#a516a45a7934f23274fa302d7e711b43c',1,'ir_Sanyo.cpp']]], + ['ksavestr_2701',['kSaveStr',['../IRtext_8cpp.html#a24f9462727ee596a3ae16393c33e3ebc',1,'kSaveStr(): IRtext.cpp'],['../IRtext_8h.html#acb40b78a5269c43cc3e4f44d3da01069',1,'kSaveStr(): IRtext.cpp']]], + ['ksecondsstr_2702',['kSecondsStr',['../IRtext_8cpp.html#a282cb9785839a9da66a9333d788c0fb1',1,'kSecondsStr(): IRtext.cpp'],['../IRtext_8h.html#ad736b59d3fe45b3c06bd301af4d7b455',1,'kSecondsStr(): IRtext.cpp']]], + ['ksecondstr_2703',['kSecondStr',['../IRtext_8cpp.html#a5ec55e16709cbd2c4b1ff8c72c01c1f5',1,'kSecondStr(): IRtext.cpp'],['../IRtext_8h.html#ad3489e1c008bc517b8bf0271c40252d1',1,'kSecondStr(): IRtext.cpp']]], + ['ksensorstr_2704',['kSensorStr',['../IRtext_8cpp.html#aa7e6eab2fbc832f98d6560f62453c934',1,'kSensorStr(): IRtext.cpp'],['../IRtext_8h.html#a56ee9a96dd0a7ee0a5f95c286f6ea7e8',1,'kSensorStr(): IRtext.cpp']]], + ['ksensortempstr_2705',['kSensorTempStr',['../IRtext_8cpp.html#a756daa989457676d2af255428a01e1d5',1,'kSensorTempStr(): IRtext.cpp'],['../IRtext_8h.html#a03e76a09bade0c229fea1ce31fe8c9a1',1,'kSensorTempStr(): IRtext.cpp']]], + ['ksetstr_2706',['kSetStr',['../IRtext_8cpp.html#a27b5e437df44d4d41db9b296a1f236a1',1,'kSetStr(): IRtext.cpp'],['../IRtext_8h.html#a31d3426b8a8d1a35c47c88ef00023fce',1,'kSetStr(): IRtext.cpp']]], + ['ksharpacauto_2707',['kSharpAcAuto',['../ir__Sharp_8h.html#ad4e228b234598a84e11a76e7f2d27199',1,'ir_Sharp.h']]], + ['ksharpacbitcleanoffset_2708',['kSharpAcBitCleanOffset',['../ir__Sharp_8h.html#a3460827972f31d05070c638a57782286',1,'ir_Sharp.h']]], + ['ksharpacbitionoffset_2709',['kSharpAcBitIonOffset',['../ir__Sharp_8h.html#a73f967e9950d04941ed9f6815815fb23',1,'ir_Sharp.h']]], + ['ksharpacbitmark_2710',['kSharpAcBitMark',['../ir__Sharp_8h.html#ae73dd2c91b531bf3a52641b36f56ead7',1,'ir_Sharp.h']]], + ['ksharpacbits_2711',['kSharpAcBits',['../IRremoteESP8266_8h.html#a6c106a982acced5d8aeef98644002ca2',1,'IRremoteESP8266.h']]], + ['ksharpacbittimerenabled_2712',['kSharpAcBitTimerEnabled',['../ir__Sharp_8h.html#a083863299df4ff081be0add9d5082700',1,'ir_Sharp.h']]], + ['ksharpacbittimertype_2713',['kSharpAcBitTimerType',['../ir__Sharp_8h.html#ad47cf2f20c4589b9cbe6b583d62b4675',1,'ir_Sharp.h']]], + ['ksharpacbyteclean_2714',['kSharpAcByteClean',['../ir__Sharp_8h.html#a2f4a4ddf407413a52d45c955ebd5bcd5',1,'ir_Sharp.h']]], + ['ksharpacbytefan_2715',['kSharpAcByteFan',['../ir__Sharp_8h.html#a24139aa535ca54dcf45558da5ee2ac56',1,'ir_Sharp.h']]], + ['ksharpacbyteion_2716',['kSharpAcByteIon',['../ir__Sharp_8h.html#aaceee11c539050ba5ac368b9612131a4',1,'ir_Sharp.h']]], + ['ksharpacbytemode_2717',['kSharpAcByteMode',['../ir__Sharp_8h.html#af7d8a2ab79ae4f2ad48e569576fd34e8',1,'ir_Sharp.h']]], + ['ksharpacbytepowerspecial_2718',['kSharpAcBytePowerSpecial',['../ir__Sharp_8h.html#a44d180bd3babec15143ba8ea8aa18906',1,'ir_Sharp.h']]], + ['ksharpacbytespecial_2719',['kSharpAcByteSpecial',['../ir__Sharp_8h.html#a78ba1ef4993661f9dfaad776dff1b43e',1,'ir_Sharp.h']]], + ['ksharpacbyteswing_2720',['kSharpAcByteSwing',['../ir__Sharp_8h.html#aee580a3c6cfd75f75f46852d0f3df0db',1,'ir_Sharp.h']]], + ['ksharpacbytetemp_2721',['kSharpAcByteTemp',['../ir__Sharp_8h.html#a1b67ab12ed664517124fe3c1d7325927',1,'ir_Sharp.h']]], + ['ksharpacbytetimer_2722',['kSharpAcByteTimer',['../ir__Sharp_8h.html#af2fc9b6abae8ca6ca0d01b8c924386be',1,'ir_Sharp.h']]], + ['ksharpaccool_2723',['kSharpAcCool',['../ir__Sharp_8h.html#ae828d7e915f69cc1e9538839fc51c895',1,'ir_Sharp.h']]], + ['ksharpacdefaultrepeat_2724',['kSharpAcDefaultRepeat',['../IRremoteESP8266_8h.html#a7f0438831899e3df16f9002717c818b9',1,'IRremoteESP8266.h']]], + ['ksharpacdry_2725',['kSharpAcDry',['../ir__Sharp_8h.html#a50ae949b473ed4a6482fa00d747b2c0f',1,'ir_Sharp.h']]], + ['ksharpacfanauto_2726',['kSharpAcFanAuto',['../ir__Sharp_8h.html#a2ef78269271593420ea2bdc20025ca69',1,'ir_Sharp.h']]], + ['ksharpacfanhigh_2727',['kSharpAcFanHigh',['../ir__Sharp_8h.html#af29136d64c2f2a2515918ccf0ff0f594',1,'ir_Sharp.h']]], + ['ksharpacfanmax_2728',['kSharpAcFanMax',['../ir__Sharp_8h.html#a8b0aaa58a5f4caabea84e3b448793054',1,'ir_Sharp.h']]], + ['ksharpacfanmed_2729',['kSharpAcFanMed',['../ir__Sharp_8h.html#a7607f054da76f5e1508abf42d9cd71fc',1,'ir_Sharp.h']]], + ['ksharpacfanmin_2730',['kSharpAcFanMin',['../ir__Sharp_8h.html#a2372fdfbb0d8c2163a3eae5b8eda570a',1,'ir_Sharp.h']]], + ['ksharpacfanoffset_2731',['kSharpAcFanOffset',['../ir__Sharp_8h.html#ae95f02db8d9799ce726f5f467922a36c',1,'ir_Sharp.h']]], + ['ksharpacfansize_2732',['kSharpAcFanSize',['../ir__Sharp_8h.html#a2640f5c4eb0b4e62b9e2124a1fbfb6d2',1,'ir_Sharp.h']]], + ['ksharpacgap_2733',['kSharpAcGap',['../ir__Sharp_8h.html#a777eb0358ce3ef4528f086ff9ff7cd8d',1,'ir_Sharp.h']]], + ['ksharpachdrmark_2734',['kSharpAcHdrMark',['../ir__Sharp_8h.html#aff6f1e55de051762a0def881a5bb555c',1,'ir_Sharp.h']]], + ['ksharpachdrspace_2735',['kSharpAcHdrSpace',['../ir__Sharp_8h.html#a0ea5ff96afd358a8ad1be8d8ed808f04',1,'ir_Sharp.h']]], + ['ksharpacheat_2736',['kSharpAcHeat',['../ir__Sharp_8h.html#ab546d06a0b1f3477f88282f764f208cb',1,'ir_Sharp.h']]], + ['ksharpacmaxtemp_2737',['kSharpAcMaxTemp',['../ir__Sharp_8h.html#a6cfb060ea8c2f650fdd73b055cfda00a',1,'ir_Sharp.h']]], + ['ksharpacmintemp_2738',['kSharpAcMinTemp',['../ir__Sharp_8h.html#ad9ac5214b6cc780d9424ec7d038fe837',1,'ir_Sharp.h']]], + ['ksharpacmodesize_2739',['kSharpAcModeSize',['../ir__Sharp_8h.html#a7dfcf91a08bc37884cc4882c60004736',1,'ir_Sharp.h']]], + ['ksharpacofftimertype_2740',['kSharpAcOffTimerType',['../ir__Sharp_8h.html#ada633bea9c6c2ffd234c8262e92cebd5',1,'ir_Sharp.h']]], + ['ksharpaconespace_2741',['kSharpAcOneSpace',['../ir__Sharp_8h.html#a20e8eb7c8763fbddb20530badbaab38b',1,'ir_Sharp.h']]], + ['ksharpacontimertype_2742',['kSharpAcOnTimerType',['../ir__Sharp_8h.html#adce8625b00931645c7ccf54edf263c59',1,'ir_Sharp.h']]], + ['ksharpacpoweroff_2743',['kSharpAcPowerOff',['../ir__Sharp_8h.html#a5c13882a47bdd289507e8a5a23ec99d6',1,'ir_Sharp.h']]], + ['ksharpacpoweron_2744',['kSharpAcPowerOn',['../ir__Sharp_8h.html#af485487ea50dd2f9bc153e5f83dc5cf9',1,'ir_Sharp.h']]], + ['ksharpacpoweronfromoff_2745',['kSharpAcPowerOnFromOff',['../ir__Sharp_8h.html#ae484cf776fa47542f4d693c29052fc9f',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialoff_2746',['kSharpAcPowerSetSpecialOff',['../ir__Sharp_8h.html#a93b22ba4b5e68f8185ed28a6bb7c05dd',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialoffset_2747',['kSharpAcPowerSetSpecialOffset',['../ir__Sharp_8h.html#a0603455573e1dd203a5f6718efc12085',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialon_2748',['kSharpAcPowerSetSpecialOn',['../ir__Sharp_8h.html#a67aff6b22c0cfb89debb8ade7239f07e',1,'ir_Sharp.h']]], + ['ksharpacpowerspecialsize_2749',['kSharpAcPowerSpecialSize',['../ir__Sharp_8h.html#a233d545e942de27ec9e96d0d5e7afdb3',1,'ir_Sharp.h']]], + ['ksharpacpowertimersetting_2750',['kSharpAcPowerTimerSetting',['../ir__Sharp_8h.html#a208cb9446ea1f42db42a1f6e24b61219',1,'ir_Sharp.h']]], + ['ksharpacpowerunknown_2751',['kSharpAcPowerUnknown',['../ir__Sharp_8h.html#ab20172b860fa1401607f0678c682640f',1,'ir_Sharp.h']]], + ['ksharpacspecialfan_2752',['kSharpAcSpecialFan',['../ir__Sharp_8h.html#a6c1a1c535150f973eecb1a131d0c4780',1,'ir_Sharp.h']]], + ['ksharpacspecialpower_2753',['kSharpAcSpecialPower',['../ir__Sharp_8h.html#a843585897995ee15e39af0d452d8660d',1,'ir_Sharp.h']]], + ['ksharpacspecialswing_2754',['kSharpAcSpecialSwing',['../ir__Sharp_8h.html#a34127a7df393d2a5a84ca90e60e8507a',1,'ir_Sharp.h']]], + ['ksharpacspecialtempecono_2755',['kSharpAcSpecialTempEcono',['../ir__Sharp_8h.html#af2dcb54fc26802d1818ef88e6ddfc819',1,'ir_Sharp.h']]], + ['ksharpacspecialtimer_2756',['kSharpAcSpecialTimer',['../ir__Sharp_8h.html#a539b21c344db53fbfd4f17c91ab98139',1,'ir_Sharp.h']]], + ['ksharpacspecialtimerhalfhour_2757',['kSharpAcSpecialTimerHalfHour',['../ir__Sharp_8h.html#a1f9bf40a4af95689947c09559ed049bf',1,'ir_Sharp.h']]], + ['ksharpacspecialturbo_2758',['kSharpAcSpecialTurbo',['../ir__Sharp_8h.html#a270bb2bc83d4eb8974f498dd8eb299bb',1,'ir_Sharp.h']]], + ['ksharpacstatelength_2759',['kSharpAcStateLength',['../IRremoteESP8266_8h.html#a5192edb9406a8572e393918bab69e3c6',1,'IRremoteESP8266.h']]], + ['ksharpacswingnotoggle_2760',['kSharpAcSwingNoToggle',['../ir__Sharp_8h.html#a9c56d4f694ea69921ba2cb75f67426d6',1,'ir_Sharp.h']]], + ['ksharpacswingoffset_2761',['kSharpAcSwingOffset',['../ir__Sharp_8h.html#a61c5356e645867fa2eeda02c83e5b9ae',1,'ir_Sharp.h']]], + ['ksharpacswingsize_2762',['kSharpAcSwingSize',['../ir__Sharp_8h.html#aafec87d2ddea0fd56d176f1b5f80a6fa',1,'ir_Sharp.h']]], + ['ksharpacswingtoggle_2763',['kSharpAcSwingToggle',['../ir__Sharp_8h.html#aa6db653d25f67214819292b8f86af0e6',1,'ir_Sharp.h']]], + ['ksharpactimerhoursmax_2764',['kSharpAcTimerHoursMax',['../ir__Sharp_8h.html#a63af01993ba1e539dfb8dae67f42b9ae',1,'ir_Sharp.h']]], + ['ksharpactimerhoursoff_2765',['kSharpAcTimerHoursOff',['../ir__Sharp_8h.html#a462c10c12d828ba58d589cc365bd7be3',1,'ir_Sharp.h']]], + ['ksharpactimerhoursoffset_2766',['kSharpAcTimerHoursOffset',['../ir__Sharp_8h.html#aeb8d6ca49ba029bdb3663ff6b9c2cc4d',1,'ir_Sharp.h']]], + ['ksharpactimerhourssize_2767',['kSharpAcTimerHoursSize',['../ir__Sharp_8h.html#a965ed2ef8ba32a325ec41a351d88c17d',1,'ir_Sharp.h']]], + ['ksharpactimerincrement_2768',['kSharpAcTimerIncrement',['../ir__Sharp_8h.html#af32638e308a7034eb013b7ea9569273e',1,'ir_Sharp.h']]], + ['ksharpaczerospace_2769',['kSharpAcZeroSpace',['../ir__Sharp_8h.html#a5310e0404daae1a6e534dbaeaa9a9939',1,'ir_Sharp.h']]], + ['ksharpaddressbits_2770',['kSharpAddressBits',['../IRremoteESP8266_8h.html#a79c2f3cc459267cf0261124ddef47f5e',1,'IRremoteESP8266.h']]], + ['ksharpaddressmask_2771',['kSharpAddressMask',['../ir__Sharp_8cpp.html#a84fba003383cd4652fc804b97002f464',1,'ir_Sharp.cpp']]], + ['ksharpbitmark_2772',['kSharpBitMark',['../ir__Sharp_8cpp.html#ae2adc2bffb2b024faab8da363621733f',1,'ir_Sharp.cpp']]], + ['ksharpbitmarkticks_2773',['kSharpBitMarkTicks',['../ir__Sharp_8cpp.html#aa64bd0c359add4038c0143b5774627bb',1,'ir_Sharp.cpp']]], + ['ksharpbits_2774',['kSharpBits',['../IRremoteESP8266_8h.html#a8a74f9d7cec751cc0945fd89fa6237ae',1,'IRremoteESP8266.h']]], + ['ksharpcommandbits_2775',['kSharpCommandBits',['../IRremoteESP8266_8h.html#ae4cdfc8e358ec738d20c1bda49842ccf',1,'IRremoteESP8266.h']]], + ['ksharpcommandmask_2776',['kSharpCommandMask',['../ir__Sharp_8cpp.html#ad44eda54ade4bef4fdf4451fdb784950',1,'ir_Sharp.cpp']]], + ['ksharpgap_2777',['kSharpGap',['../ir__Sharp_8cpp.html#a77015be2a04274bcb332ec21cb75251e',1,'ir_Sharp.cpp']]], + ['ksharpgapticks_2778',['kSharpGapTicks',['../ir__Sharp_8cpp.html#a4aa110ec2934797f71ddf9bcd34498d1',1,'ir_Sharp.cpp']]], + ['ksharponespace_2779',['kSharpOneSpace',['../ir__Sharp_8cpp.html#a3359539480a203db37c2cf2efd88fdcc',1,'ir_Sharp.cpp']]], + ['ksharponespaceticks_2780',['kSharpOneSpaceTicks',['../ir__Sharp_8cpp.html#a12e18dfd195faae6ca581936434c9063',1,'ir_Sharp.cpp']]], + ['ksharptick_2781',['kSharpTick',['../ir__Sharp_8cpp.html#af417ab19220576243753903657923ba7',1,'ir_Sharp.cpp']]], + ['ksharptogglemask_2782',['kSharpToggleMask',['../ir__Sharp_8cpp.html#a2701123f01683c6927c23c7699bce13a',1,'ir_Sharp.cpp']]], + ['ksharpzerospace_2783',['kSharpZeroSpace',['../ir__Sharp_8cpp.html#ac2ad6123d938999e234896e1635e3063',1,'ir_Sharp.cpp']]], + ['ksharpzerospaceticks_2784',['kSharpZeroSpaceTicks',['../ir__Sharp_8cpp.html#af8c638f77ff29c2d20555343be80e5f0',1,'ir_Sharp.cpp']]], + ['ksherwoodbits_2785',['kSherwoodBits',['../IRremoteESP8266_8h.html#a94abd640c9e7aa225f4a8873a1ddea6a',1,'IRremoteESP8266.h']]], + ['ksherwoodminrepeat_2786',['kSherwoodMinRepeat',['../IRremoteESP8266_8h.html#a2e00b92b55657fc4e140eb85e3a414dc',1,'IRremoteESP8266.h']]], + ['ksilentstr_2787',['kSilentStr',['../IRtext_8cpp.html#a398d3c627c5b95c5d7adfb5308fc7de0',1,'kSilentStr(): IRtext.cpp'],['../IRtext_8h.html#a8efb4256a49dc0acd27d6995851d585e',1,'kSilentStr(): IRtext.cpp']]], + ['ksinglerepeat_2788',['kSingleRepeat',['../IRremoteESP8266_8h.html#a46835b1e2d279570fd818749e88180d4',1,'IRremoteESP8266.h']]], + ['ksleepstr_2789',['kSleepStr',['../IRtext_8cpp.html#a38068788c0ef50e6034dbcffeec1eb36',1,'kSleepStr(): IRtext.cpp'],['../IRtext_8h.html#af9ac743c367e179723b128ad69f124c5',1,'kSleepStr(): IRtext.cpp']]], + ['ksleeptimerstr_2790',['kSleepTimerStr',['../IRtext_8cpp.html#a3402e1f6d78e3c59b71bd0dfdf020b51',1,'kSleepTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a86639857f884487cf3bedc91e71d6faa',1,'kSleepTimerStr(): IRtext.cpp']]], + ['kslowstr_2791',['kSlowStr',['../IRtext_8cpp.html#a3131a17a06dff31058579b301227a04f',1,'kSlowStr(): IRtext.cpp'],['../IRtext_8h.html#a171736ab5e3d59198ed740ea5fd93473',1,'kSlowStr(): IRtext.cpp']]], + ['ksony12bits_2792',['kSony12Bits',['../IRremoteESP8266_8h.html#aa16fdf708a67dbe22c85ad4bac9b05b6',1,'IRremoteESP8266.h']]], + ['ksony15bits_2793',['kSony15Bits',['../IRremoteESP8266_8h.html#ad868d68d289d618ace266519afa059f4',1,'IRremoteESP8266.h']]], + ['ksony20bits_2794',['kSony20Bits',['../IRremoteESP8266_8h.html#aa9cd1ff8036f6c3a288c4f34af4a5eb4',1,'IRremoteESP8266.h']]], + ['ksonyaltfreq_2795',['kSonyAltFreq',['../ir__Sony_8cpp.html#a05912a15a9a6a4a78416600adc7e526b',1,'ir_Sony.cpp']]], + ['ksonyhdrmark_2796',['kSonyHdrMark',['../ir__Sony_8cpp.html#afac5a232c82e81ac257ddfc94aa4f379',1,'ir_Sony.cpp']]], + ['ksonyhdrmarkticks_2797',['kSonyHdrMarkTicks',['../ir__Sony_8cpp.html#a89abc5f0556f38d462202d1de78cbddb',1,'ir_Sony.cpp']]], + ['ksonyminbits_2798',['kSonyMinBits',['../IRremoteESP8266_8h.html#a6f0794107a7643e0bec8de6de9e7621b',1,'IRremoteESP8266.h']]], + ['ksonymingap_2799',['kSonyMinGap',['../ir__Sony_8cpp.html#abfe3a5e1fa2a38ee556326b1ea0e7e11',1,'ir_Sony.cpp']]], + ['ksonymingapticks_2800',['kSonyMinGapTicks',['../ir__Sony_8cpp.html#a150d62f71f79295153bac4694bae0aa3',1,'ir_Sony.cpp']]], + ['ksonyminrepeat_2801',['kSonyMinRepeat',['../IRremoteESP8266_8h.html#a112408429fb4a5cca22a66a351453bad',1,'IRremoteESP8266.h']]], + ['ksonyonemark_2802',['kSonyOneMark',['../ir__Sony_8cpp.html#a490e7ca2b0f81848ae42eb57d0023d13',1,'ir_Sony.cpp']]], + ['ksonyonemarkticks_2803',['kSonyOneMarkTicks',['../ir__Sony_8cpp.html#ad41c0d0496661c2e066056de6974bfe9',1,'ir_Sony.cpp']]], + ['ksonyrptlength_2804',['kSonyRptLength',['../ir__Sony_8cpp.html#a24578b92cf53caa48fa3660f16ec90ec',1,'ir_Sony.cpp']]], + ['ksonyrptlengthticks_2805',['kSonyRptLengthTicks',['../ir__Sony_8cpp.html#a0a7f67ba27e03c35d5df35a2a14a1e19',1,'ir_Sony.cpp']]], + ['ksonyspace_2806',['kSonySpace',['../ir__Sony_8cpp.html#ad09a9eb0dc0b809cea0d0a2a8ff6b9fb',1,'ir_Sony.cpp']]], + ['ksonyspaceticks_2807',['kSonySpaceTicks',['../ir__Sony_8cpp.html#a80dccfab869821cadaf02df664d91eda',1,'ir_Sony.cpp']]], + ['ksonystdfreq_2808',['kSonyStdFreq',['../ir__Sony_8cpp.html#a5e5b14c45909411d160e051f0bc7c63d',1,'ir_Sony.cpp']]], + ['ksonytick_2809',['kSonyTick',['../ir__Sony_8cpp.html#a7ced75a5e9f06f5c68132665d27e01b8',1,'ir_Sony.cpp']]], + ['ksonyzeromark_2810',['kSonyZeroMark',['../ir__Sony_8cpp.html#a7808995a9d2755681f1461d578d5480b',1,'ir_Sony.cpp']]], + ['ksonyzeromarkticks_2811',['kSonyZeroMarkTicks',['../ir__Sony_8cpp.html#a542aed17f98a11ca89456eec507a5225',1,'ir_Sony.cpp']]], + ['kspace_2812',['kSpace',['../ir__Lasertag_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_Lasertag.cpp'],['../ir__MWM_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_MWM.cpp'],['../ir__RC5__RC6_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_RC5_RC6.cpp']]], + ['kspacelbracestr_2813',['kSpaceLBraceStr',['../IRtext_8cpp.html#a156ef0014809a3509e7b254a9585e0a1',1,'kSpaceLBraceStr(): IRtext.cpp'],['../IRtext_8h.html#a42a2d6b1e764138a5e20b7a34e0cff03',1,'kSpaceLBraceStr(): IRtext.cpp']]], + ['kspacestate_2814',['kSpaceState',['../IRrecv_8h.html#acc0d1931164a8967c210eb03a2d03e2a',1,'IRrecv.h']]], + ['kstartoffset_2815',['kStartOffset',['../IRrecv_8h.html#a44a836a34428f8f75b1ae566de4bb972',1,'IRrecv.h']]], + ['kstartstr_2816',['kStartStr',['../IRtext_8cpp.html#a2075a48eed571455a88e7dfbc3a547ef',1,'kStartStr(): IRtext.cpp'],['../IRtext_8h.html#ad030c0930697d3c295f3783e8519995c',1,'kStartStr(): IRtext.cpp']]], + ['kstatesizemax_2817',['kStateSizeMax',['../IRrecv_8h.html#ab7d82cf4c0937c9b1d59d75f6f347ab2',1,'IRrecv.h']]], + ['kstepstr_2818',['kStepStr',['../IRtext_8cpp.html#ac6c64c4bdc955b6528616db3a4b303c1',1,'kStepStr(): IRtext.cpp'],['../IRtext_8h.html#ad8cc5f179089e8497a9670492429d7e3',1,'kStepStr(): IRtext.cpp']]], + ['kstopstate_2819',['kStopState',['../IRrecv_8h.html#a0e87ae8496a061e394bc9f7f3415a9b3',1,'IRrecv.h']]], + ['kstopstr_2820',['kStopStr',['../IRtext_8cpp.html#a0466188f9064d18622304cd375b18390',1,'kStopStr(): IRtext.cpp'],['../IRtext_8h.html#a7037a67c71778fe06f9dc9b4363f6f9b',1,'kStopStr(): IRtext.cpp']]], + ['ksuperstr_2821',['kSuperStr',['../IRtext_8cpp.html#a81e6c76017bc819882a043ac8fcc2854',1,'kSuperStr(): IRtext.cpp'],['../IRtext_8h.html#af83fbe756a22ef800d40bc738be886c7',1,'kSuperStr(): IRtext.cpp']]], + ['kswinghstr_2822',['kSwingHStr',['../IRtext_8cpp.html#a12d4e0afe0f6b96af817ebc95eb0b6f4',1,'kSwingHStr(): IRtext.cpp'],['../IRtext_8h.html#acfad569446290c1da0c102b98344411c',1,'kSwingHStr(): IRtext.cpp']]], + ['kswingstr_2823',['kSwingStr',['../IRtext_8cpp.html#a106174aef3a46450c0a16bef7c36a8c5',1,'kSwingStr(): IRtext.cpp'],['../IRtext_8h.html#a56d1a94eae3422758b2762da008e243c',1,'kSwingStr(): IRtext.cpp']]], + ['kswingvmodestr_2824',['kSwingVModeStr',['../IRtext_8cpp.html#ab71be957190939e2b4643f2e56e1201f',1,'kSwingVModeStr(): IRtext.cpp'],['../IRtext_8h.html#a0c801e35becc1eab4cdf0076e1c99485',1,'kSwingVModeStr(): IRtext.cpp']]], + ['kswingvstr_2825',['kSwingVStr',['../IRtext_8cpp.html#a6dc1ec788e0659e82219534b5dbb79bc',1,'kSwingVStr(): IRtext.cpp'],['../IRtext_8h.html#a8415af77afcb671c3729d604be51fd22',1,'kSwingVStr(): IRtext.cpp']]], + ['kswingvtogglestr_2826',['kSwingVToggleStr',['../IRtext_8cpp.html#a3efcf06e5ac4d6309bad1b1d0e49a933',1,'kSwingVToggleStr(): IRtext.cpp'],['../IRtext_8h.html#a27ae4d475898878bd8e71111066629c6',1,'kSwingVToggleStr(): IRtext.cpp']]], + ['ksymphonybits_2827',['kSymphonyBits',['../IRremoteESP8266_8h.html#abb5b89578ab0757999530c0383f38533',1,'IRremoteESP8266.h']]], + ['ksymphonydefaultrepeat_2828',['kSymphonyDefaultRepeat',['../IRremoteESP8266_8h.html#a219b8495f77932c200680f7a2b133880',1,'IRremoteESP8266.h']]], + ['ksymphonyfootergap_2829',['kSymphonyFooterGap',['../ir__Symphony_8cpp.html#a363cf54f4e752932d5e341975c2445f4',1,'ir_Symphony.cpp']]], + ['ksymphonyonemark_2830',['kSymphonyOneMark',['../ir__Symphony_8cpp.html#a469bfa8046ba75f9ba7cda4996dd785d',1,'ir_Symphony.cpp']]], + ['ksymphonyonespace_2831',['kSymphonyOneSpace',['../ir__Symphony_8cpp.html#ab699747bdf28d5a89920041e9c5bb01b',1,'ir_Symphony.cpp']]], + ['ksymphonyzeromark_2832',['kSymphonyZeroMark',['../ir__Symphony_8cpp.html#a58f27b1b9da16ffe73448c7ae3998fc9',1,'ir_Symphony.cpp']]], + ['ksymphonyzerospace_2833',['kSymphonyZeroSpace',['../ir__Symphony_8cpp.html#a9aaf8db419618de847573d2019155287',1,'ir_Symphony.cpp']]], + ['ktcl112acauto_2834',['kTcl112AcAuto',['../ir__Tcl_8h.html#a11a982cc182e446d53ded658cb7a08b6',1,'ir_Tcl.h']]], + ['ktcl112acbiteconooffset_2835',['kTcl112AcBitEconoOffset',['../ir__Tcl_8h.html#a97c8948de72d702b859a7abccfbc423e',1,'ir_Tcl.h']]], + ['ktcl112acbithealthoffset_2836',['kTcl112AcBitHealthOffset',['../ir__Tcl_8h.html#a2acb2c5cd2f8b729047f9eecf93f96af',1,'ir_Tcl.h']]], + ['ktcl112acbitlightoffset_2837',['kTcl112AcBitLightOffset',['../ir__Tcl_8h.html#ad87c878f7a30a05418a5babfc52c0e9e',1,'ir_Tcl.h']]], + ['ktcl112acbitmark_2838',['kTcl112AcBitMark',['../ir__Tcl_8h.html#a45360de532d2262246bf57cb7c08604d',1,'ir_Tcl.h']]], + ['ktcl112acbits_2839',['kTcl112AcBits',['../IRremoteESP8266_8h.html#a4a60d79056d70d3d56067b0bb2ec00f4',1,'IRremoteESP8266.h']]], + ['ktcl112acbitswinghoffset_2840',['kTcl112AcBitSwingHOffset',['../ir__Tcl_8h.html#ad807894f92249e44d1725f18de013369',1,'ir_Tcl.h']]], + ['ktcl112acbitturbooffset_2841',['kTcl112AcBitTurboOffset',['../ir__Tcl_8h.html#a7a6e09c1b4620e96820b3b3c54fb0e18',1,'ir_Tcl.h']]], + ['ktcl112accool_2842',['kTcl112AcCool',['../ir__Tcl_8h.html#a4a4b778086b3ebf856b750fe0c4bd2c0',1,'ir_Tcl.h']]], + ['ktcl112acdefaultrepeat_2843',['kTcl112AcDefaultRepeat',['../IRremoteESP8266_8h.html#a97c82cec6d72845d9ab8a201b0fa5034',1,'IRremoteESP8266.h']]], + ['ktcl112acdry_2844',['kTcl112AcDry',['../ir__Tcl_8h.html#a1d9ec40c278fedf87acb7420ef861101',1,'ir_Tcl.h']]], + ['ktcl112acfan_2845',['kTcl112AcFan',['../ir__Tcl_8h.html#ae07f3dd0a84be27bcb13ba60f4fd025b',1,'ir_Tcl.h']]], + ['ktcl112acfanauto_2846',['kTcl112AcFanAuto',['../ir__Tcl_8h.html#a099935d6d2bf6ebb28332005036c59c0',1,'ir_Tcl.h']]], + ['ktcl112acfanhigh_2847',['kTcl112AcFanHigh',['../ir__Tcl_8h.html#aab9672bac3e83b2e3b3d2cc5f1aa0e1f',1,'ir_Tcl.h']]], + ['ktcl112acfanlow_2848',['kTcl112AcFanLow',['../ir__Tcl_8h.html#a5114fe3f978672fc62c0cd16f6d46dd7',1,'ir_Tcl.h']]], + ['ktcl112acfanmed_2849',['kTcl112AcFanMed',['../ir__Tcl_8h.html#ad8f34f1972da347a169e2eb4ddf3d835',1,'ir_Tcl.h']]], + ['ktcl112acfansize_2850',['kTcl112AcFanSize',['../ir__Tcl_8h.html#a802bbb6258edf6dcdd05a383db28e9d3',1,'ir_Tcl.h']]], + ['ktcl112acgap_2851',['kTcl112AcGap',['../ir__Tcl_8h.html#a9ccdf5ce9ce325b9813dadbdc855a469',1,'ir_Tcl.h']]], + ['ktcl112achalfdegreeoffset_2852',['kTcl112AcHalfDegreeOffset',['../ir__Tcl_8h.html#a1ba7d7fa8df2243330eafce097209651',1,'ir_Tcl.h']]], + ['ktcl112achdrmark_2853',['kTcl112AcHdrMark',['../ir__Tcl_8h.html#a56f9f7daf3ada77f8f844afd46a80de9',1,'ir_Tcl.h']]], + ['ktcl112achdrmarktolerance_2854',['kTcl112AcHdrMarkTolerance',['../ir__Tcl_8h.html#ab9d980747b2ddd1b7fb04f00d71af1e7',1,'ir_Tcl.h']]], + ['ktcl112achdrspace_2855',['kTcl112AcHdrSpace',['../ir__Tcl_8h.html#a9135b4d7496383ad3a7da7c3ac7c92b4',1,'ir_Tcl.h']]], + ['ktcl112acheat_2856',['kTcl112AcHeat',['../ir__Tcl_8h.html#ae573f856f0bdf50406e9be84b1aa8ade',1,'ir_Tcl.h']]], + ['ktcl112acmodesize_2857',['kTcl112AcModeSize',['../ir__Tcl_8h.html#a07e49881d14cb1c84cfbf3695ae64580',1,'ir_Tcl.h']]], + ['ktcl112aconespace_2858',['kTcl112AcOneSpace',['../ir__Tcl_8h.html#af1e67019978260ba3f514cd895b54dad',1,'ir_Tcl.h']]], + ['ktcl112acpoweroffset_2859',['kTcl112AcPowerOffset',['../ir__Tcl_8h.html#ad36204b310ec8a069f631322d806aa7f',1,'ir_Tcl.h']]], + ['ktcl112acstatelength_2860',['kTcl112AcStateLength',['../IRremoteESP8266_8h.html#a23ba2f5af02242e14ae7eefcd066152e',1,'IRremoteESP8266.h']]], + ['ktcl112acswingvoff_2861',['kTcl112AcSwingVOff',['../ir__Tcl_8h.html#aa78e1b544f392c251093d458e5d21e12',1,'ir_Tcl.h']]], + ['ktcl112acswingvoffset_2862',['kTcl112AcSwingVOffset',['../ir__Tcl_8h.html#ab0412b0d865eaf788a5672300575b1d8',1,'ir_Tcl.h']]], + ['ktcl112acswingvon_2863',['kTcl112AcSwingVOn',['../ir__Tcl_8h.html#a5406fbabd66478d601aebc6939a3788f',1,'ir_Tcl.h']]], + ['ktcl112acswingvsize_2864',['kTcl112AcSwingVSize',['../ir__Tcl_8h.html#a7bacb40b18b280da13b2d1b781c825e5',1,'ir_Tcl.h']]], + ['ktcl112actempmax_2865',['kTcl112AcTempMax',['../ir__Tcl_8h.html#a60efbe31031e1e9c3a17c7d80cac54cb',1,'ir_Tcl.h']]], + ['ktcl112actempmin_2866',['kTcl112AcTempMin',['../ir__Tcl_8h.html#a30fe65ec015bc4d91cd35ead9cc43dcc',1,'ir_Tcl.h']]], + ['ktcl112actolerance_2867',['kTcl112AcTolerance',['../ir__Tcl_8h.html#a13bbe794b2b59763f7f93f15a3f26820',1,'ir_Tcl.h']]], + ['ktcl112aczerospace_2868',['kTcl112AcZeroSpace',['../ir__Tcl_8h.html#abc05edaeb1a4fa7e6ccf9bda1f66b483',1,'ir_Tcl.h']]], + ['ktecoauto_2869',['kTecoAuto',['../ir__Teco_8h.html#a79178aa25d9f60c0a838285369e1b910',1,'ir_Teco.h']]], + ['ktecobitmark_2870',['kTecoBitMark',['../ir__Teco_8cpp.html#a0aa2e352f4a61027b17467e92863883b',1,'ir_Teco.cpp']]], + ['ktecobits_2871',['kTecoBits',['../IRremoteESP8266_8h.html#aee01958e9d97a70a6881cf560ca0ca9d',1,'IRremoteESP8266.h']]], + ['ktecocool_2872',['kTecoCool',['../ir__Teco_8h.html#a554686c72b6bc487d03c9461f9633a6b',1,'ir_Teco.h']]], + ['ktecodefaultrepeat_2873',['kTecoDefaultRepeat',['../IRremoteESP8266_8h.html#a095362359f34c1ee5ab71d56e6d64f64',1,'IRremoteESP8266.h']]], + ['ktecodry_2874',['kTecoDry',['../ir__Teco_8h.html#af7efcf371967eb97fd31d54016a82006',1,'ir_Teco.h']]], + ['ktecofan_2875',['kTecoFan',['../ir__Teco_8h.html#a7385fe198242c9203e3a5d5ffb7beb4d',1,'ir_Teco.h']]], + ['ktecofanauto_2876',['kTecoFanAuto',['../ir__Teco_8h.html#a43e58c0158efac1c4e5497c619b5674c',1,'ir_Teco.h']]], + ['ktecofanhigh_2877',['kTecoFanHigh',['../ir__Teco_8h.html#a0a73f5f892e7f9812793fbf5dab458dd',1,'ir_Teco.h']]], + ['ktecofanlow_2878',['kTecoFanLow',['../ir__Teco_8h.html#abac7443a86fb304376dd94a9c10e6940',1,'ir_Teco.h']]], + ['ktecofanmed_2879',['kTecoFanMed',['../ir__Teco_8h.html#a35f313943f9e2f5b69d5237fdaa64914',1,'ir_Teco.h']]], + ['ktecofanoffset_2880',['kTecoFanOffset',['../ir__Teco_8h.html#ae70841ad987ac89abaaf99b11655eaae',1,'ir_Teco.h']]], + ['ktecofansize_2881',['kTecoFanSize',['../ir__Teco_8h.html#a45734d2be952e3faa796d86245eaf241',1,'ir_Teco.h']]], + ['ktecogap_2882',['kTecoGap',['../ir__Teco_8cpp.html#a6a153d84287fba3bd11e3e5054fd7e30',1,'ir_Teco.cpp']]], + ['ktecohdrmark_2883',['kTecoHdrMark',['../ir__Teco_8cpp.html#ada983ce2d6f03949cddfe06191ab05d9',1,'ir_Teco.cpp']]], + ['ktecohdrspace_2884',['kTecoHdrSpace',['../ir__Teco_8cpp.html#acf417d42fd39dbaf06282162ab5b17e2',1,'ir_Teco.cpp']]], + ['ktecoheat_2885',['kTecoHeat',['../ir__Teco_8h.html#ab6f9dbeb2838b124be12d08fd9b209bb',1,'ir_Teco.h']]], + ['ktecohumidoffset_2886',['kTecoHumidOffset',['../ir__Teco_8h.html#ad95126f6815d24b5d1b38e44677f3d7e',1,'ir_Teco.h']]], + ['ktecolightoffset_2887',['kTecoLightOffset',['../ir__Teco_8h.html#a5dc2cb366974b2baa9f7cbfb26d90415',1,'ir_Teco.h']]], + ['ktecomaxtemp_2888',['kTecoMaxTemp',['../ir__Teco_8h.html#a1c24aa0cc4d475a5eb97d5208f4dcf06',1,'ir_Teco.h']]], + ['ktecomintemp_2889',['kTecoMinTemp',['../ir__Teco_8h.html#a54da99bfcbea5e076c3ca2934e769ab1',1,'ir_Teco.h']]], + ['ktecomodeoffset_2890',['kTecoModeOffset',['../ir__Teco_8h.html#a1aca7a8a2822cd1494dabeda5b11b9be',1,'ir_Teco.h']]], + ['ktecoonespace_2891',['kTecoOneSpace',['../ir__Teco_8cpp.html#a62eccbf6773ea8fbc18432627c62d0d5',1,'ir_Teco.cpp']]], + ['ktecopoweroffset_2892',['kTecoPowerOffset',['../ir__Teco_8h.html#a4eec88582ed29e424549497deb9eceef',1,'ir_Teco.h']]], + ['ktecoreset_2893',['kTecoReset',['../ir__Teco_8h.html#acf559a2cd772835ce46c3f673cd95806',1,'ir_Teco.h']]], + ['ktecosaveoffset_2894',['kTecoSaveOffset',['../ir__Teco_8h.html#a63d5efa7cfc84ee22d3575cc713d1f62',1,'ir_Teco.h']]], + ['ktecosleepoffset_2895',['kTecoSleepOffset',['../ir__Teco_8h.html#ae7da65034a8a84e79ebb1497e56e38fe',1,'ir_Teco.h']]], + ['ktecoswingoffset_2896',['kTecoSwingOffset',['../ir__Teco_8h.html#aaa821eb3ad9a5edadba2b83b6d2094b6',1,'ir_Teco.h']]], + ['ktecotempoffset_2897',['kTecoTempOffset',['../ir__Teco_8h.html#ae887d9c5702d63e4b4fa5250ed5bf0d9',1,'ir_Teco.h']]], + ['ktecotempsize_2898',['kTecoTempSize',['../ir__Teco_8h.html#a635db8dbba35e4326958fca6dfe67603',1,'ir_Teco.h']]], + ['ktecotimerhalfhouroffset_2899',['kTecoTimerHalfHourOffset',['../ir__Teco_8h.html#a2692a59900c10b6da6662fac5a312e04',1,'ir_Teco.h']]], + ['ktecotimeronoffset_2900',['kTecoTimerOnOffset',['../ir__Teco_8h.html#a7bcf79fa5e5280ad35c9a9512b2fdc7f',1,'ir_Teco.h']]], + ['ktecotimertenshoursoffset_2901',['kTecoTimerTensHoursOffset',['../ir__Teco_8h.html#adaa73601e31fa7217d371645d835f0ca',1,'ir_Teco.h']]], + ['ktecotimertenshourssize_2902',['kTecoTimerTensHoursSize',['../ir__Teco_8h.html#a57bf1b777b9b56aad4f224b6bba1218c',1,'ir_Teco.h']]], + ['ktecotimerunithoursoffset_2903',['kTecoTimerUnitHoursOffset',['../ir__Teco_8h.html#ac47fc38319e7e1d90d42c789b806cdbd',1,'ir_Teco.h']]], + ['ktecotimerunithourssize_2904',['kTecoTimerUnitHoursSize',['../ir__Teco_8h.html#a54ac664e32ce0d8b4d8d4d4d459dbc46',1,'ir_Teco.h']]], + ['ktecozerospace_2905',['kTecoZeroSpace',['../ir__Teco_8cpp.html#a8dc1f6ea44519a0930b48f69a83a7363',1,'ir_Teco.cpp']]], + ['ktempdownstr_2906',['kTempDownStr',['../IRtext_8cpp.html#a3fa3262c5631c9357a5723c70dc3be12',1,'kTempDownStr(): IRtext.cpp'],['../IRtext_8h.html#a3d367a899d7e8ed20844bb3c48bf6395',1,'kTempDownStr(): IRtext.cpp']]], + ['ktempstr_2907',['kTempStr',['../IRtext_8cpp.html#a487bd9a4225536aba2595be0b5cb8039',1,'kTempStr(): IRtext.cpp'],['../IRtext_8h.html#a87652df1cf724353547f27a9ebde5edb',1,'kTempStr(): IRtext.cpp']]], + ['ktempupstr_2908',['kTempUpStr',['../IRtext_8cpp.html#a7c4f18322b600aaaf5a8716654d05dc3',1,'kTempUpStr(): IRtext.cpp'],['../IRtext_8h.html#a71687df5bc94e4ca18cf59c9ff238e86',1,'kTempUpStr(): IRtext.cpp']]], + ['kthreeletterdayofweekstr_2909',['kThreeLetterDayOfWeekStr',['../IRtext_8cpp.html#ae16da0464743313a1fbeae92dcfcebbd',1,'kThreeLetterDayOfWeekStr(): IRtext.cpp'],['../IRtext_8h.html#a837ecfeff9a1bc7546016229e9f2ddfb',1,'kThreeLetterDayOfWeekStr(): IRtext.cpp']]], + ['ktimeoutms_2910',['kTimeoutMs',['../IRrecv_8h.html#ad37e9659aaef29c541802d9759e0ab7b',1,'IRrecv.h']]], + ['ktimerstr_2911',['kTimerStr',['../IRtext_8cpp.html#a2b5219ba887cfbc578fb880ebada832a',1,'kTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a36fa3584a89f6e48757eba8f3df7e109',1,'kTimerStr(): IRtext.cpp']]], + ['ktimesep_2912',['kTimeSep',['../IRtext_8cpp.html#a277b588db53ec31ab7b0d287310c6d50',1,'kTimeSep(): IRtext.cpp'],['../IRtext_8h.html#a277b588db53ec31ab7b0d287310c6d50',1,'kTimeSep(): IRtext.cpp']]], + ['ktogglestr_2913',['kToggleStr',['../IRtext_8cpp.html#a33860b90859d19191c9759b099283b37',1,'kToggleStr(): IRtext.cpp'],['../IRtext_8h.html#a05b1e2f809dadf05e22e1cb1d1a7f07e',1,'kToggleStr(): IRtext.cpp']]], + ['ktolerance_2914',['kTolerance',['../IRrecv_8h.html#a7884008b3a738dfc7bd8658655e10272',1,'IRrecv.h']]], + ['ktopstr_2915',['kTopStr',['../IRtext_8cpp.html#a65a8bf89c9dd0277607478277c0c7088',1,'kTopStr(): IRtext.cpp'],['../IRtext_8h.html#a6bb6abfc54409b801dcb591f036635d2',1,'kTopStr(): IRtext.cpp']]], + ['ktoshibaacauto_2916',['kToshibaAcAuto',['../ir__Toshiba_8h.html#a4730189595a884ae6535805948e096aa',1,'ir_Toshiba.h']]], + ['ktoshibaacbitmark_2917',['kToshibaAcBitMark',['../ir__Toshiba_8cpp.html#adff1c244103ff274243b8e20ca209866',1,'ir_Toshiba.cpp']]], + ['ktoshibaacbits_2918',['kToshibaACBits',['../IRremoteESP8266_8h.html#a172dde7867fa9a68902c3ad7ea9629b0',1,'IRremoteESP8266.h']]], + ['ktoshibaaccool_2919',['kToshibaAcCool',['../ir__Toshiba_8h.html#a2f30e65bb092365d1a8bcb1f3395333a',1,'ir_Toshiba.h']]], + ['ktoshibaacdry_2920',['kToshibaAcDry',['../ir__Toshiba_8h.html#a10b77d1038efc59775398789c33af91e',1,'ir_Toshiba.h']]], + ['ktoshibaacfanauto_2921',['kToshibaAcFanAuto',['../ir__Toshiba_8h.html#a69f52e19a5b0e68abda00b680fbef7f6',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmax_2922',['kToshibaAcFanMax',['../ir__Toshiba_8h.html#a0f6ffde3491f464166d6064d7dfe5ba4',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmed_2923',['kToshibaAcFanMed',['../ir__Toshiba_8h.html#a3ff967af7d1a30c7c5cb958eaa5cbd58',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmin_2924',['kToshibaAcFanMin',['../ir__Toshiba_8h.html#ab2c5eea9ccabf2e0e56bc03baec5d898',1,'ir_Toshiba.h']]], + ['ktoshibaacfanoffset_2925',['kToshibaAcFanOffset',['../ir__Toshiba_8h.html#a8276d25876329968bbf36eac3598972c',1,'ir_Toshiba.h']]], + ['ktoshibaacfansize_2926',['kToshibaAcFanSize',['../ir__Toshiba_8h.html#a5a91c19e799721560a5a9ef77a245888',1,'ir_Toshiba.h']]], + ['ktoshibaachdrmark_2927',['kToshibaAcHdrMark',['../ir__Toshiba_8cpp.html#a2eac25ff2a381ad6690623641153a780',1,'ir_Toshiba.cpp']]], + ['ktoshibaachdrspace_2928',['kToshibaAcHdrSpace',['../ir__Toshiba_8cpp.html#a0ae9047d5a204f320c06736fa40d0a7d',1,'ir_Toshiba.cpp']]], + ['ktoshibaacheat_2929',['kToshibaAcHeat',['../ir__Toshiba_8h.html#aa9ec24f9a5e460aa7017f642ce7a4c0d',1,'ir_Toshiba.h']]], + ['ktoshibaacmaxtemp_2930',['kToshibaAcMaxTemp',['../ir__Toshiba_8h.html#a475028a2a519e3310506ceac0a5dc4e6',1,'ir_Toshiba.h']]], + ['ktoshibaacmingap_2931',['kToshibaAcMinGap',['../ir__Toshiba_8cpp.html#ade7642284aa7c6a638b9fab45610cc59',1,'ir_Toshiba.cpp']]], + ['ktoshibaacminrepeat_2932',['kToshibaACMinRepeat',['../IRremoteESP8266_8h.html#a8fca6a7c3cd608ff49cab35f24af0546',1,'IRremoteESP8266.h']]], + ['ktoshibaacmintemp_2933',['kToshibaAcMinTemp',['../ir__Toshiba_8h.html#ad0e8e76aabc38ac7ba2f13a009de98e0',1,'ir_Toshiba.h']]], + ['ktoshibaacmodeoffset_2934',['kToshibaAcModeOffset',['../ir__Toshiba_8h.html#a4e097e34b0f2dd9eaacf94d043f726d0',1,'ir_Toshiba.h']]], + ['ktoshibaacmodesize_2935',['kToshibaAcModeSize',['../ir__Toshiba_8h.html#a920d55af8e499a7c2293a7d8180104da',1,'ir_Toshiba.h']]], + ['ktoshibaaconespace_2936',['kToshibaAcOneSpace',['../ir__Toshiba_8cpp.html#a787330c9e5f9d30e8df157acc15f56dd',1,'ir_Toshiba.cpp']]], + ['ktoshibaacpoweroffset_2937',['kToshibaAcPowerOffset',['../ir__Toshiba_8h.html#adfd3caac2bd0b636508afbbf67b04dcd',1,'ir_Toshiba.h']]], + ['ktoshibaacstatelength_2938',['kToshibaACStateLength',['../IRremoteESP8266_8h.html#ad3be6a1b9241c20bb1464a2cb80b97d2',1,'IRremoteESP8266.h']]], + ['ktoshibaactempoffset_2939',['kToshibaAcTempOffset',['../ir__Toshiba_8h.html#a68be75c21288e249d7b44fe9648de91f',1,'ir_Toshiba.h']]], + ['ktoshibaactempsize_2940',['kToshibaAcTempSize',['../ir__Toshiba_8h.html#a89ec8108586e0d5b9f58a160f4db37c8',1,'ir_Toshiba.h']]], + ['ktoshibaaczerospace_2941',['kToshibaAcZeroSpace',['../ir__Toshiba_8cpp.html#ab2fc2833cfb31d872894073687eebd99',1,'ir_Toshiba.cpp']]], + ['ktrotecauto_2942',['kTrotecAuto',['../ir__Trotec_8h.html#a53b2687b96f8e69ec6f57dd2ac7a6dfa',1,'ir_Trotec.h']]], + ['ktrotecbitmark_2943',['kTrotecBitMark',['../ir__Trotec_8cpp.html#a870b2da19855eff625a2834ca7fd8765',1,'ir_Trotec.cpp']]], + ['ktrotecbits_2944',['kTrotecBits',['../IRremoteESP8266_8h.html#ab819cb0a34937714dcb10059799c26e2',1,'IRremoteESP8266.h']]], + ['ktroteccool_2945',['kTrotecCool',['../ir__Trotec_8h.html#add33a35046e4270ad9ff3b998526d5d1',1,'ir_Trotec.h']]], + ['ktrotecdefaultrepeat_2946',['kTrotecDefaultRepeat',['../IRremoteESP8266_8h.html#a4c0411462f2854a8606deca09ed15df5',1,'IRremoteESP8266.h']]], + ['ktrotecdeftemp_2947',['kTrotecDefTemp',['../ir__Trotec_8h.html#ac28d1d0ea6db18716a7d9d21e84178c0',1,'ir_Trotec.h']]], + ['ktrotecdry_2948',['kTrotecDry',['../ir__Trotec_8h.html#abdaa1836c6bc90b1d5813df028a76e21',1,'ir_Trotec.h']]], + ['ktrotecfan_2949',['kTrotecFan',['../ir__Trotec_8h.html#a9309d528d50dd542a5184a51fb101a6a',1,'ir_Trotec.h']]], + ['ktrotecfanhigh_2950',['kTrotecFanHigh',['../ir__Trotec_8h.html#ae780f0bb6b9b83f3dbcc1c1e282e5436',1,'ir_Trotec.h']]], + ['ktrotecfanlow_2951',['kTrotecFanLow',['../ir__Trotec_8h.html#aa1c3695c1becc935d2a3b2691996a17b',1,'ir_Trotec.h']]], + ['ktrotecfanmed_2952',['kTrotecFanMed',['../ir__Trotec_8h.html#abae1944f529099ff4736b6cb13bcbeda',1,'ir_Trotec.h']]], + ['ktrotecfanoffset_2953',['kTrotecFanOffset',['../ir__Trotec_8h.html#a3b9034b96268707f7b6fc45a16499479',1,'ir_Trotec.h']]], + ['ktrotecfansize_2954',['kTrotecFanSize',['../ir__Trotec_8h.html#a89d7de622d0f53f800c1a5a2887a81e4',1,'ir_Trotec.h']]], + ['ktrotecgap_2955',['kTrotecGap',['../ir__Trotec_8cpp.html#a753ba93d7b757dc58fcf1b4a6bb65ff6',1,'ir_Trotec.cpp']]], + ['ktrotecgapend_2956',['kTrotecGapEnd',['../ir__Trotec_8cpp.html#a5fcc4a020bcebfe90abe12d4a47de372',1,'ir_Trotec.cpp']]], + ['ktrotechdrmark_2957',['kTrotecHdrMark',['../ir__Trotec_8cpp.html#a809faed7ee2fef78a5b8271a2c5ddd10',1,'ir_Trotec.cpp']]], + ['ktrotechdrspace_2958',['kTrotecHdrSpace',['../ir__Trotec_8cpp.html#a5d42cd98bf737dd8161572afa393be1e',1,'ir_Trotec.cpp']]], + ['ktrotecintro1_2959',['kTrotecIntro1',['../ir__Trotec_8h.html#aabc5c6a9b4867c25d84ffe2839e88564',1,'ir_Trotec.h']]], + ['ktrotecintro2_2960',['kTrotecIntro2',['../ir__Trotec_8h.html#ac33de8b2fc4b70bb272a56f6bbb68e34',1,'ir_Trotec.h']]], + ['ktrotecmaxtemp_2961',['kTrotecMaxTemp',['../ir__Trotec_8h.html#abfe4004dcac892f575ec1efb09567595',1,'ir_Trotec.h']]], + ['ktrotecmaxtimer_2962',['kTrotecMaxTimer',['../ir__Trotec_8h.html#a8467d1b9983d5750a61817cacb148efd',1,'ir_Trotec.h']]], + ['ktrotecmintemp_2963',['kTrotecMinTemp',['../ir__Trotec_8h.html#a091904af9fee2384e137feab274af7f8',1,'ir_Trotec.h']]], + ['ktrotecmodeoffset_2964',['kTrotecModeOffset',['../ir__Trotec_8h.html#aa0d48802845d5cf0410550bb98e4cbb5',1,'ir_Trotec.h']]], + ['ktrotecmodesize_2965',['kTrotecModeSize',['../ir__Trotec_8h.html#ae45ea2f0f8b5d09568c0322e1735ca85',1,'ir_Trotec.h']]], + ['ktroteconespace_2966',['kTrotecOneSpace',['../ir__Trotec_8cpp.html#a570aa73a82089906971932212d99a283',1,'ir_Trotec.cpp']]], + ['ktrotecpowerbitoffset_2967',['kTrotecPowerBitOffset',['../ir__Trotec_8h.html#a11fcdfe886385de6363d06371cdcff43',1,'ir_Trotec.h']]], + ['ktrotecsleepbitoffset_2968',['kTrotecSleepBitOffset',['../ir__Trotec_8h.html#af81754a025119a3dc9924df5508b18c0',1,'ir_Trotec.h']]], + ['ktrotecstatelength_2969',['kTrotecStateLength',['../IRremoteESP8266_8h.html#ae1d2aa52fef81f03b92c35f4970728d2',1,'IRremoteESP8266.h']]], + ['ktrotectempoffset_2970',['kTrotecTempOffset',['../ir__Trotec_8h.html#a08a844aefec8d0440365c9204a01034c',1,'ir_Trotec.h']]], + ['ktrotectempsize_2971',['kTrotecTempSize',['../ir__Trotec_8h.html#a1141680a808f41513548a8747c37f975',1,'ir_Trotec.h']]], + ['ktrotectimerbitoffset_2972',['kTrotecTimerBitOffset',['../ir__Trotec_8h.html#aad59f1284ec04736a3c6629c3cd87731',1,'ir_Trotec.h']]], + ['ktroteczerospace_2973',['kTrotecZeroSpace',['../ir__Trotec_8cpp.html#a8e8f85e7b8a8157eb425316b5108d717',1,'ir_Trotec.cpp']]], + ['ktruestr_2974',['kTrueStr',['../IRtext_8cpp.html#a28a627d6f48d7d06a560f9613e4550fa',1,'kTrueStr(): IRtext.cpp'],['../IRtext_8h.html#aca6e78a25b9dacd2508069f0a6b919c0',1,'kTrueStr(): IRtext.cpp']]], + ['kturbostr_2975',['kTurboStr',['../IRtext_8cpp.html#a9f3f7395d980887699ac5a0c146d37d2',1,'kTurboStr(): IRtext.cpp'],['../IRtext_8h.html#a3ced6d2a545174133308d7803157f7f8',1,'kTurboStr(): IRtext.cpp']]], + ['kunknownstr_2976',['kUnknownStr',['../IRtext_8cpp.html#a9c6c6d47ce3eb07cc607faa600978029',1,'kUnknownStr(): IRtext.cpp'],['../IRtext_8h.html#aa59176b31741b60729d4279817a7da1b',1,'kUnknownStr(): IRtext.cpp']]], + ['kunknownthreshold_2977',['kUnknownThreshold',['../IRrecv_8h.html#aa6b5a940c7a0432aa82a8d823202cd7f',1,'IRrecv.h']]], + ['kupperstr_2978',['kUpperStr',['../IRtext_8cpp.html#a887bb7c61f38014d21b025c67102fa0b',1,'kUpperStr(): IRtext.cpp'],['../IRtext_8h.html#a5aea60591627481d90688f655b2eb82a',1,'kUpperStr(): IRtext.cpp']]], + ['kupstr_2979',['kUpStr',['../IRtext_8cpp.html#ab970b3d5239f08f21a8e5e2eae49739f',1,'kUpStr(): IRtext.cpp'],['../IRtext_8h.html#a8672abbd2a279c032f0435ed75143b1a',1,'kUpStr(): IRtext.cpp']]], + ['kusedeftol_2980',['kUseDefTol',['../IRrecv_8h.html#a05025e8bd724ae2d0c7fea6e924ca84c',1,'IRrecv.h']]], + ['kvestelacauto_2981',['kVestelAcAuto',['../ir__Vestel_8h.html#a157e879cbe3b216075e3b7b2db5fdc3c',1,'ir_Vestel.h']]], + ['kvestelacbitmark_2982',['kVestelAcBitMark',['../ir__Vestel_8h.html#a70d7198002c61529956625986aa533f0',1,'ir_Vestel.h']]], + ['kvestelacbits_2983',['kVestelAcBits',['../IRremoteESP8266_8h.html#ae31945a1ce90b2d4c33b5c91d980d3a7',1,'IRremoteESP8266.h']]], + ['kvestelacchecksumoffset_2984',['kVestelAcChecksumOffset',['../ir__Vestel_8h.html#ac3fa10d1dba540a82b77cc88b01f9a7e',1,'ir_Vestel.h']]], + ['kvestelacchecksumsize_2985',['kVestelAcChecksumSize',['../ir__Vestel_8h.html#a61979a3b944ce7309c5b3f5b24b0a14c',1,'ir_Vestel.h']]], + ['kvestelaccool_2986',['kVestelAcCool',['../ir__Vestel_8h.html#aa2ec681dd63a976a6b2b182ae590e020',1,'ir_Vestel.h']]], + ['kvestelacdry_2987',['kVestelAcDry',['../ir__Vestel_8h.html#a21a255842a75a932a3a0735851d9c197',1,'ir_Vestel.h']]], + ['kvestelacfan_2988',['kVestelAcFan',['../ir__Vestel_8h.html#aeabf5404a3f66fd1428b6e4c09f24c08',1,'ir_Vestel.h']]], + ['kvestelacfanauto_2989',['kVestelAcFanAuto',['../ir__Vestel_8h.html#ac2f3175c25844414de2c2489595dd851',1,'ir_Vestel.h']]], + ['kvestelacfanautocool_2990',['kVestelAcFanAutoCool',['../ir__Vestel_8h.html#ab40dc2ebe05c77e701e2d5acf16b2658',1,'ir_Vestel.h']]], + ['kvestelacfanautohot_2991',['kVestelAcFanAutoHot',['../ir__Vestel_8h.html#a95dee8baacedb7aa62edbdecf766cdc1',1,'ir_Vestel.h']]], + ['kvestelacfanhigh_2992',['kVestelAcFanHigh',['../ir__Vestel_8h.html#acae63d91ee2a2b448fe1a68b2472e4a3',1,'ir_Vestel.h']]], + ['kvestelacfanlow_2993',['kVestelAcFanLow',['../ir__Vestel_8h.html#a21ce5e539ecb764be8dbad33914f4b87',1,'ir_Vestel.h']]], + ['kvestelacfanmed_2994',['kVestelAcFanMed',['../ir__Vestel_8h.html#a265fa70e0e38caefb45ed007eb25a430',1,'ir_Vestel.h']]], + ['kvestelacfanoffset_2995',['kVestelAcFanOffset',['../ir__Vestel_8h.html#af0f1c1989322f256b7b1b5dba613feba',1,'ir_Vestel.h']]], + ['kvestelacfansize_2996',['kVestelAcFanSize',['../ir__Vestel_8h.html#ae61e23edfb71206e736497ab479c08ad',1,'ir_Vestel.h']]], + ['kvestelachdrmark_2997',['kVestelAcHdrMark',['../ir__Vestel_8h.html#a32871ab992bfee13918a50f04508a95a',1,'ir_Vestel.h']]], + ['kvestelachdrspace_2998',['kVestelAcHdrSpace',['../ir__Vestel_8h.html#a2389409048e409b411ea8416829c06ef',1,'ir_Vestel.h']]], + ['kvestelacheat_2999',['kVestelAcHeat',['../ir__Vestel_8h.html#a33d36614992862c41f5e48548b0a45f1',1,'ir_Vestel.h']]], + ['kvestelachouroffset_3000',['kVestelAcHourOffset',['../ir__Vestel_8h.html#af4c3729a4b9df092e01d74109f539cca',1,'ir_Vestel.h']]], + ['kvestelachoursize_3001',['kVestelAcHourSize',['../ir__Vestel_8h.html#a2c0fd442d92620ca062637d01258bacf',1,'ir_Vestel.h']]], + ['kvestelacion_3002',['kVestelAcIon',['../ir__Vestel_8h.html#a6a661c914fd67e261e2148d797789339',1,'ir_Vestel.h']]], + ['kvestelacionoffset_3003',['kVestelAcIonOffset',['../ir__Vestel_8h.html#a9b1cd19c4b0037714f1c47ba031edd0b',1,'ir_Vestel.h']]], + ['kvestelacmaxtemp_3004',['kVestelAcMaxTemp',['../ir__Vestel_8h.html#a4e49902b2e4fe049fd5969b4532cc7b4',1,'ir_Vestel.h']]], + ['kvestelacmintempc_3005',['kVestelAcMinTempC',['../ir__Vestel_8h.html#ae597f05d0886a5a2aa8c43db187a657b',1,'ir_Vestel.h']]], + ['kvestelacmintemph_3006',['kVestelAcMinTempH',['../ir__Vestel_8h.html#a06977d297c84adac7927c80c7b0e7297',1,'ir_Vestel.h']]], + ['kvestelacminuteoffset_3007',['kVestelAcMinuteOffset',['../ir__Vestel_8h.html#a7c5f318a30e86394af19265e73b68034',1,'ir_Vestel.h']]], + ['kvestelacminutesize_3008',['kVestelAcMinuteSize',['../ir__Vestel_8h.html#a8abd51cd0d0404ae8bb139690bf55eb0',1,'ir_Vestel.h']]], + ['kvestelacmodeoffset_3009',['kVestelAcModeOffset',['../ir__Vestel_8h.html#a5334689cb0fbeaee67133f1f86bdce58',1,'ir_Vestel.h']]], + ['kvestelacnormal_3010',['kVestelAcNormal',['../ir__Vestel_8h.html#afa4c0fafcc806cd22dfb45475631d754',1,'ir_Vestel.h']]], + ['kvestelacofftimeoffset_3011',['kVestelAcOffTimeOffset',['../ir__Vestel_8h.html#a64ce11367a28d6481801ac3ac641df4b',1,'ir_Vestel.h']]], + ['kvestelacofftimerflagoffset_3012',['kVestelAcOffTimerFlagOffset',['../ir__Vestel_8h.html#ab36bed197f2c2b65599667b4cdf8225b',1,'ir_Vestel.h']]], + ['kvestelaconespace_3013',['kVestelAcOneSpace',['../ir__Vestel_8h.html#a507a849ef5e031f40ecc0e5db6ac8dd6',1,'ir_Vestel.h']]], + ['kvestelacontimeoffset_3014',['kVestelAcOnTimeOffset',['../ir__Vestel_8h.html#a51e257abca02cb1c97de4a5418fb7e61',1,'ir_Vestel.h']]], + ['kvestelacontimerflagoffset_3015',['kVestelAcOnTimerFlagOffset',['../ir__Vestel_8h.html#a8aa66163683538129fbdaf21746a9144',1,'ir_Vestel.h']]], + ['kvestelacpoweroffset_3016',['kVestelAcPowerOffset',['../ir__Vestel_8h.html#ab1c5709fa37fc711929688bd72c300be',1,'ir_Vestel.h']]], + ['kvestelacpowersize_3017',['kVestelAcPowerSize',['../ir__Vestel_8h.html#a884236b7213902c5e7d79327effc8f97',1,'ir_Vestel.h']]], + ['kvestelacsleep_3018',['kVestelAcSleep',['../ir__Vestel_8h.html#abc4701f0a44ed48a139d192f86a7169b',1,'ir_Vestel.h']]], + ['kvestelacstatedefault_3019',['kVestelAcStateDefault',['../ir__Vestel_8h.html#a4207797ae1043280ec6364de5981a791',1,'ir_Vestel.h']]], + ['kvestelacswing_3020',['kVestelAcSwing',['../ir__Vestel_8h.html#aeb764aa28cb134348e64fde5cb4d40f0',1,'ir_Vestel.h']]], + ['kvestelacswingoffset_3021',['kVestelAcSwingOffset',['../ir__Vestel_8h.html#ad3249b7c42070013c7c81d3feb0b1a43',1,'ir_Vestel.h']]], + ['kvestelactempoffset_3022',['kVestelAcTempOffset',['../ir__Vestel_8h.html#a9cf24276d722ee54a17c8beaf2b415cd',1,'ir_Vestel.h']]], + ['kvestelactimerflagoffset_3023',['kVestelAcTimerFlagOffset',['../ir__Vestel_8h.html#a0e53cb471d133b13cfa8fd3204d70776',1,'ir_Vestel.h']]], + ['kvestelactimerhoursize_3024',['kVestelAcTimerHourSize',['../ir__Vestel_8h.html#ad52ad7c6b1efb7eee74a276dbca330e3',1,'ir_Vestel.h']]], + ['kvestelactimerminssize_3025',['kVestelAcTimerMinsSize',['../ir__Vestel_8h.html#a7696fac000df0fd5136b7cbd96393b9e',1,'ir_Vestel.h']]], + ['kvestelactimersize_3026',['kVestelAcTimerSize',['../ir__Vestel_8h.html#a43f134a4db94790c671380be29fb8e2c',1,'ir_Vestel.h']]], + ['kvestelactimestatedefault_3027',['kVestelAcTimeStateDefault',['../ir__Vestel_8h.html#aaf4d9b6a41269ede2101d45cc1549794',1,'ir_Vestel.h']]], + ['kvestelactolerance_3028',['kVestelAcTolerance',['../ir__Vestel_8h.html#a4abe236ac8a801aa03ab843c3e418711',1,'ir_Vestel.h']]], + ['kvestelacturbo_3029',['kVestelAcTurbo',['../ir__Vestel_8h.html#a85b8b744f201b1666f9608f693a61059',1,'ir_Vestel.h']]], + ['kvestelacturbosleepoffset_3030',['kVestelAcTurboSleepOffset',['../ir__Vestel_8h.html#a97c21dc060558aa4f543f2d05385f674',1,'ir_Vestel.h']]], + ['kvestelaczerospace_3031',['kVestelAcZeroSpace',['../ir__Vestel_8h.html#a2094b0ff279fb1696b51e57d657efd13',1,'ir_Vestel.h']]], + ['kwallstr_3032',['kWallStr',['../IRtext_8cpp.html#a860a71561b888c82318daad9f2c34592',1,'kWallStr(): IRtext.cpp'],['../IRtext_8h.html#add1af6d900b500ca7affff3c9ff02d29',1,'kWallStr(): IRtext.cpp']]], + ['kweeklytimerstr_3033',['kWeeklyTimerStr',['../IRtext_8cpp.html#aaf0b7bf26b4710a4c032cec9e55c545a',1,'kWeeklyTimerStr(): IRtext.cpp'],['../IRtext_8h.html#ab59fa6f63401196c0ff32aba6da9d9aa',1,'kWeeklyTimerStr(): IRtext.cpp']]], + ['kwhirlpoolacalttempoffset_3034',['kWhirlpoolAcAltTempOffset',['../ir__Whirlpool_8h.html#a5cdc8be18d6489572d7c16dbbcc0c838',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacalttemppos_3035',['kWhirlpoolAcAltTempPos',['../ir__Whirlpool_8h.html#a019206ce06ef164cc3abb586183d0789',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacauto_3036',['kWhirlpoolAcAuto',['../ir__Whirlpool_8h.html#a2f3cc5447f8042e9c2eae0c2e0dc1b80',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacautotemp_3037',['kWhirlpoolAcAutoTemp',['../ir__Whirlpool_8h.html#a314b66dc86a7f622d73d3973d9dca86d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacbitmark_3038',['kWhirlpoolAcBitMark',['../ir__Whirlpool_8cpp.html#a5c076ca2e18927f8b0594cb74a7de1ff',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacbits_3039',['kWhirlpoolAcBits',['../IRremoteESP8266_8h.html#a149bd4f3fb9c83e683095d393209ede3',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacchecksumbyte1_3040',['kWhirlpoolAcChecksumByte1',['../ir__Whirlpool_8h.html#ab199c13354730c715debbeed63182cbd',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacchecksumbyte2_3041',['kWhirlpoolAcChecksumByte2',['../ir__Whirlpool_8h.html#a37d1a2fd814ccf83062325225bddb9be',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacclockpos_3042',['kWhirlpoolAcClockPos',['../ir__Whirlpool_8h.html#ad624453fc485adaaa156bfde374208a4',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommand6thsense_3043',['kWhirlpoolAcCommand6thSense',['../ir__Whirlpool_8h.html#a48b1309aab30dd871ce047881680efa2',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandfanspeed_3044',['kWhirlpoolAcCommandFanSpeed',['../ir__Whirlpool_8h.html#a4712f7dd6c5631f6aa692eeb99fa3963',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandifeel_3045',['kWhirlpoolAcCommandIFeel',['../ir__Whirlpool_8h.html#a5cb95c379d033d7f5b0c81755f1d376f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandlight_3046',['kWhirlpoolAcCommandLight',['../ir__Whirlpool_8h.html#af6ae6f50d9dbfa610b7033181e4f7eb1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandmode_3047',['kWhirlpoolAcCommandMode',['../ir__Whirlpool_8h.html#ab03770a941b7277a66fe65003497e183',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandofftimer_3048',['kWhirlpoolAcCommandOffTimer',['../ir__Whirlpool_8h.html#a072883e3780aa0970183ab330db26118',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandontimer_3049',['kWhirlpoolAcCommandOnTimer',['../ir__Whirlpool_8h.html#a54cbadf2ded73e66d6d12b6622249bdc',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandpos_3050',['kWhirlpoolAcCommandPos',['../ir__Whirlpool_8h.html#a1a3bc2210991ccfd418a5137dc7e0aa8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandpower_3051',['kWhirlpoolAcCommandPower',['../ir__Whirlpool_8h.html#ac215c2827ebfe25a896d53e576b643d1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandsleep_3052',['kWhirlpoolAcCommandSleep',['../ir__Whirlpool_8h.html#a695c9d69953ad2663512ede38e619b09',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandsuper_3053',['kWhirlpoolAcCommandSuper',['../ir__Whirlpool_8h.html#a4da2162e70a7257c5f4149e8556816d4',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandswing_3054',['kWhirlpoolAcCommandSwing',['../ir__Whirlpool_8h.html#a320e57c0727a74f049883c77233647a9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandtemp_3055',['kWhirlpoolAcCommandTemp',['../ir__Whirlpool_8h.html#a6e567d58af9bc3fb246e3d47a09fb065',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccool_3056',['kWhirlpoolAcCool',['../ir__Whirlpool_8h.html#a9574c0a604ffee1df43222344f649db8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacdefaultrepeat_3057',['kWhirlpoolAcDefaultRepeat',['../IRremoteESP8266_8h.html#a3b41358898f69d96bdeece17ead13ee0',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacdry_3058',['kWhirlpoolAcDry',['../ir__Whirlpool_8h.html#ab7433a4e3e8ad7ee665ab234df43e45f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfan_3059',['kWhirlpoolAcFan',['../ir__Whirlpool_8h.html#a91ecddbde81174268fdde3679565daeb',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanauto_3060',['kWhirlpoolAcFanAuto',['../ir__Whirlpool_8h.html#a133a436db244935a812beba78a1a9d05',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanhigh_3061',['kWhirlpoolAcFanHigh',['../ir__Whirlpool_8h.html#a93affe2700e13830ff09ee16801be56d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanlow_3062',['kWhirlpoolAcFanLow',['../ir__Whirlpool_8h.html#abdbd00636661a234d9e30521144d76e1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanmedium_3063',['kWhirlpoolAcFanMedium',['../ir__Whirlpool_8h.html#acf1ae9526d2fd3f49d484608730f607d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanoffset_3064',['kWhirlpoolAcFanOffset',['../ir__Whirlpool_8h.html#a2cbca4b466aab8816efa70d1653bc895',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanpos_3065',['kWhirlpoolAcFanPos',['../ir__Whirlpool_8h.html#a02d5f4fe0837c9f9738cfb46f83c2ed9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfansize_3066',['kWhirlpoolAcFanSize',['../ir__Whirlpool_8h.html#ae26fab46c0f06c04f4d51b61e623873c',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacgap_3067',['kWhirlpoolAcGap',['../ir__Whirlpool_8cpp.html#a5946b0c81f68442645f795f4f6518972',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolachdrmark_3068',['kWhirlpoolAcHdrMark',['../ir__Whirlpool_8cpp.html#ad2f759eb7426cfe5fb3421f101c926bb',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolachdrspace_3069',['kWhirlpoolAcHdrSpace',['../ir__Whirlpool_8cpp.html#a7a83a305cc6ebb7be7163bd1c3fb679d',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacheat_3070',['kWhirlpoolAcHeat',['../ir__Whirlpool_8h.html#a1e9290ec94cca537b5c44d2e4326b59c',1,'ir_Whirlpool.h']]], + ['kwhirlpoolachouroffset_3071',['kWhirlpoolAcHourOffset',['../ir__Whirlpool_8h.html#a8940e79b0e5b9f4bcf2a3e518cc59432',1,'ir_Whirlpool.h']]], + ['kwhirlpoolachoursize_3072',['kWhirlpoolAcHourSize',['../ir__Whirlpool_8h.html#ac50066e7e496cb7af6ecdb21cee7f2c9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaclightoffset_3073',['kWhirlpoolAcLightOffset',['../ir__Whirlpool_8h.html#a5a5fbcfa7f383fb72f96c414adea8966',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmaxtemp_3074',['kWhirlpoolAcMaxTemp',['../ir__Whirlpool_8h.html#a08171b333f214963e21a0c574783299f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmingap_3075',['kWhirlpoolAcMinGap',['../ir__Whirlpool_8cpp.html#aa6e5e114daf18d77914a08f831c37c7d',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacmintemp_3076',['kWhirlpoolAcMinTemp',['../ir__Whirlpool_8h.html#aeffef97e3247609d5731b525692f1e7b',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacminuteoffset_3077',['kWhirlpoolAcMinuteOffset',['../ir__Whirlpool_8h.html#ae22595d5d1ffdc4c6b02080cd38d14d7',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacminutesize_3078',['kWhirlpoolAcMinuteSize',['../ir__Whirlpool_8h.html#a3a5cecc4480a1cb3da19f246902ab1d9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmodeoffset_3079',['kWhirlpoolAcModeOffset',['../ir__Whirlpool_8h.html#a662d0ab4b5f2b40bc2427e2b8d18351e',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmodepos_3080',['kWhirlpoolAcModePos',['../ir__Whirlpool_8h.html#a6a7e8449c00a260c1ef740ebc4a08d50',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacofftimerpos_3081',['kWhirlpoolAcOffTimerPos',['../ir__Whirlpool_8h.html#a48a18046ded6bae11cd87d41d615d05f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaconespace_3082',['kWhirlpoolAcOneSpace',['../ir__Whirlpool_8cpp.html#a7680ed11a0bc6b2f9340e3557681a470',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacontimerpos_3083',['kWhirlpoolAcOnTimerPos',['../ir__Whirlpool_8h.html#ad10d9924f4d57547f7dc8ea085e1666f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacpowertoggleoffset_3084',['kWhirlpoolAcPowerToggleOffset',['../ir__Whirlpool_8h.html#a1db76f65f3f10e73a0fdee65850934a2',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacpowertogglepos_3085',['kWhirlpoolAcPowerTogglePos',['../ir__Whirlpool_8h.html#a353f4f6101a152fdcfe7f13b8f8764d8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsections_3086',['kWhirlpoolAcSections',['../ir__Whirlpool_8cpp.html#a75ebed07d288ac32a0138035279b41c7',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacsleepoffset_3087',['kWhirlpoolAcSleepOffset',['../ir__Whirlpool_8h.html#a83961870cfae146cbb519560ff609fc3',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsleeppos_3088',['kWhirlpoolAcSleepPos',['../ir__Whirlpool_8h.html#a739f14122bce3a130d441bb0a47b4666',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacstatelength_3089',['kWhirlpoolAcStateLength',['../IRremoteESP8266_8h.html#a0fff60a43f776fb999d0f1f91d88154f',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacsupermask_3090',['kWhirlpoolAcSuperMask',['../ir__Whirlpool_8h.html#a1946501e50abd9e1c0a3e07007a98c24',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsuperpos_3091',['kWhirlpoolAcSuperPos',['../ir__Whirlpool_8h.html#a68e051a102449fc6712f709b166a99b9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacswing1offset_3092',['kWhirlpoolAcSwing1Offset',['../ir__Whirlpool_8h.html#adeba9b215f8044e64df2bf805eecaa3b',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacswing2offset_3093',['kWhirlpoolAcSwing2Offset',['../ir__Whirlpool_8h.html#a3290f0b70f3eafdd885d4a08c6d5d5a3',1,'ir_Whirlpool.h']]], + ['kwhirlpoolactemppos_3094',['kWhirlpoolAcTempPos',['../ir__Whirlpool_8h.html#a15a3ef7abed2fca2881d4f5ccc969522',1,'ir_Whirlpool.h']]], + ['kwhirlpoolactimerenableoffset_3095',['kWhirlpoolAcTimerEnableOffset',['../ir__Whirlpool_8h.html#ab4694ec5e153e41f6cf56920e2291970',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaczerospace_3096',['kWhirlpoolAcZeroSpace',['../ir__Whirlpool_8cpp.html#af03c9ee4d432bbce7d2ee214dd5ca095',1,'ir_Whirlpool.cpp']]], + ['kwhynterbitmark_3097',['kWhynterBitMark',['../ir__Whynter_8cpp.html#a032043e058989b6402d8af99d2c20552',1,'ir_Whynter.cpp']]], + ['kwhynterbitmarkticks_3098',['kWhynterBitMarkTicks',['../ir__Whynter_8cpp.html#acfd8f04e0453ec1b9cd85837053a47e2',1,'ir_Whynter.cpp']]], + ['kwhynterbits_3099',['kWhynterBits',['../IRremoteESP8266_8h.html#a4553f6670e241a67104d45216a4ebd98',1,'IRremoteESP8266.h']]], + ['kwhynterhdrmark_3100',['kWhynterHdrMark',['../ir__Whynter_8cpp.html#a7d62b0e658fe6f697d41d6932e4e6662',1,'ir_Whynter.cpp']]], + ['kwhynterhdrmarkticks_3101',['kWhynterHdrMarkTicks',['../ir__Whynter_8cpp.html#a34da808cebff09fc038589c035f2d2fe',1,'ir_Whynter.cpp']]], + ['kwhynterhdrspace_3102',['kWhynterHdrSpace',['../ir__Whynter_8cpp.html#ad20c874e642238e299a44ead2ea592f1',1,'ir_Whynter.cpp']]], + ['kwhynterhdrspaceticks_3103',['kWhynterHdrSpaceTicks',['../ir__Whynter_8cpp.html#a8090f73380ea212e904402555156364d',1,'ir_Whynter.cpp']]], + ['kwhyntermincommandlength_3104',['kWhynterMinCommandLength',['../ir__Whynter_8cpp.html#a5e584a8d6aa8a146c9c8e74839b28e8f',1,'ir_Whynter.cpp']]], + ['kwhyntermincommandlengthticks_3105',['kWhynterMinCommandLengthTicks',['../ir__Whynter_8cpp.html#a65e8195824053403967573b7603059e7',1,'ir_Whynter.cpp']]], + ['kwhyntermingap_3106',['kWhynterMinGap',['../ir__Whynter_8cpp.html#ad09957f4c9c76d76ab55a74f440dad5f',1,'ir_Whynter.cpp']]], + ['kwhyntermingapticks_3107',['kWhynterMinGapTicks',['../ir__Whynter_8cpp.html#a89af5f0ab7af456f58052bf9256620a2',1,'ir_Whynter.cpp']]], + ['kwhynteronespace_3108',['kWhynterOneSpace',['../ir__Whynter_8cpp.html#a78993c22d94b107a37f61cddad728003',1,'ir_Whynter.cpp']]], + ['kwhynteronespaceticks_3109',['kWhynterOneSpaceTicks',['../ir__Whynter_8cpp.html#a95a5903a8f057df2b6587a331fec6f18',1,'ir_Whynter.cpp']]], + ['kwhyntertick_3110',['kWhynterTick',['../ir__Whynter_8cpp.html#a8f704cdf6cfd11455101919d7a772389',1,'ir_Whynter.cpp']]], + ['kwhynterzerospace_3111',['kWhynterZeroSpace',['../ir__Whynter_8cpp.html#a426deb9a35a1a6afdcbcfa58c6943490',1,'ir_Whynter.cpp']]], + ['kwhynterzerospaceticks_3112',['kWhynterZeroSpaceTicks',['../ir__Whynter_8cpp.html#ae38da416cd065b561287ebd2fe0257f0',1,'ir_Whynter.cpp']]], + ['kwide_3113',['kWide',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a9934dc3d02540583d5f13be6716739cd',1,'stdAc']]], + ['kwidestr_3114',['kWideStr',['../IRtext_8cpp.html#a19875c78e68ba6fdd78df3526f82969c',1,'kWideStr(): IRtext.cpp'],['../IRtext_8h.html#a6fe3dbd6899e85e79e517f71cc74a87b',1,'kWideStr(): IRtext.cpp']]], + ['kwifistr_3115',['kWifiStr',['../IRtext_8cpp.html#a3f2dddbcbc03e31ed6f1081fce001ea4',1,'kWifiStr(): IRtext.cpp'],['../IRtext_8h.html#a8bc9343f209803dbab3e765e39b41b4d',1,'kWifiStr(): IRtext.cpp']]], + ['kxfanstr_3116',['kXFanStr',['../IRtext_8cpp.html#ada36ab4b7555d38a76c4477971736cb7',1,'kXFanStr(): IRtext.cpp'],['../IRtext_8h.html#a7ddc859861308f2f9077abcec2a4b571',1,'kXFanStr(): IRtext.cpp']]], + ['kyesstr_3117',['kYesStr',['../IRtext_8cpp.html#a96492aa94d18702db41a639ae2a45423',1,'kYesStr(): IRtext.cpp'],['../IRtext_8h.html#a95ca78b5cc3caa31c564a28480379fae',1,'kYesStr(): IRtext.cpp']]], + ['kzepealbits_3118',['kZepealBits',['../IRremoteESP8266_8h.html#af09c9402a1c4fa24f692994498641296',1,'IRremoteESP8266.h']]], + ['kzepealcommandoffon_3119',['kZepealCommandOffOn',['../ir__Zepeal_8cpp.html#a37af9800da3144c218d422e54066e837',1,'ir_Zepeal.cpp']]], + ['kzepealcommandofftimer_3120',['kZepealCommandOffTimer',['../ir__Zepeal_8cpp.html#a87b136a95af4437182530d6f7cbc69ee',1,'ir_Zepeal.cpp']]], + ['kzepealcommandontimer_3121',['kZepealCommandOnTimer',['../ir__Zepeal_8cpp.html#aed4491019bb6575c113404a095e8b116',1,'ir_Zepeal.cpp']]], + ['kzepealcommandrhythm_3122',['kZepealCommandRhythm',['../ir__Zepeal_8cpp.html#aa3960b3bdaa77c060543881bdf71e46c',1,'ir_Zepeal.cpp']]], + ['kzepealcommandspeed_3123',['kZepealCommandSpeed',['../ir__Zepeal_8cpp.html#a1189a81901daaf4b8b45e8f45caf0f49',1,'ir_Zepeal.cpp']]], + ['kzepealfootermark_3124',['kZepealFooterMark',['../ir__Zepeal_8cpp.html#a83167e93978d9cec8cf2dfac980582ba',1,'ir_Zepeal.cpp']]], + ['kzepealgap_3125',['kZepealGap',['../ir__Zepeal_8cpp.html#ab5bea0fe08e14fa3d1812bea018f44f0',1,'ir_Zepeal.cpp']]], + ['kzepealhdrmark_3126',['kZepealHdrMark',['../ir__Zepeal_8cpp.html#abee2a1537cfff9481d3060fba94a4b04',1,'ir_Zepeal.cpp']]], + ['kzepealhdrspace_3127',['kZepealHdrSpace',['../ir__Zepeal_8cpp.html#ad49be13d3dd108a18e4e641a40ff0408',1,'ir_Zepeal.cpp']]], + ['kzepealminrepeat_3128',['kZepealMinRepeat',['../IRremoteESP8266_8h.html#afb5c734e808d8f108f976f0556bf6e58',1,'IRremoteESP8266.h']]], + ['kzepealonemark_3129',['kZepealOneMark',['../ir__Zepeal_8cpp.html#a4d9919883561086dd3e3060e93983480',1,'ir_Zepeal.cpp']]], + ['kzepealonespace_3130',['kZepealOneSpace',['../ir__Zepeal_8cpp.html#a88702dbff33a9dddcfd4b255637460a0',1,'ir_Zepeal.cpp']]], + ['kzepealsignature_3131',['kZepealSignature',['../ir__Zepeal_8cpp.html#a7994e564096ac01b77d9ebe3a753167d',1,'ir_Zepeal.cpp']]], + ['kzepealtolerance_3132',['kZepealTolerance',['../ir__Zepeal_8cpp.html#ab35f666ef98b24b8b4bacdf462a9fbe6',1,'ir_Zepeal.cpp']]], + ['kzepealzeromark_3133',['kZepealZeroMark',['../ir__Zepeal_8cpp.html#a94eac58ef78ea4e39687f54e381c3a00',1,'ir_Zepeal.cpp']]], + ['kzepealzerospace_3134',['kZepealZeroSpace',['../ir__Zepeal_8cpp.html#a1af802b587e8f0a88ae87ab964fde690',1,'ir_Zepeal.cpp']]], + ['kzonefollowstr_3135',['kZoneFollowStr',['../IRtext_8cpp.html#a9a112fb47e39e35d096fe09266d37db1',1,'kZoneFollowStr(): IRtext.cpp'],['../IRtext_8h.html#a100dc6d7c4d53bffa00a24a582ace80f',1,'kZoneFollowStr(): IRtext.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.html new file mode 100644 index 000000000..da60ab8d5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.js new file mode 100644 index 000000000..4d332bcdd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['lasertag_3136',['LASERTAG',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada92eadf4fa6dd16da5b79a2fcbf729894',1,'IRremoteESP8266.h']]], + ['ledflag_3137',['ledFlag',['../classIRCoolixAC.html#a03ba5e0a6cb47a7bb054155c2111a69c',1,'IRCoolixAC']]], + ['ledoff_3138',['ledOff',['../classIRsend.html#ae71cc5aa99f894785fb4f7abc05841b2',1,'IRsend']]], + ['ledon_3139',['ledOn',['../classIRsend.html#a13d804171fa7c14aff4def38c6ffb6c8',1,'IRsend']]], + ['legopf_3140',['LEGOPF',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9a31bf5555b17ea7b115a5c2550fc1de',1,'IRremoteESP8266.h']]], + ['lg_3141',['lg',['../classIRac.html#afad31ecf9eae573882d53dd6629485fb',1,'IRac::lg()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadadf6c249ac7d923229f9e623eff9a61f4',1,'LG(): IRremoteESP8266.h']]], + ['lg2_3142',['LG2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8402547ec0b99b9b0efe97dec65badf9',1,'IRremoteESP8266.h']]], + ['lg_5fac_5fremote_5fmodel_5ft_3143',['lg_ac_remote_model_t',['../IRsend_8h.html#a50c54713e16502d280723334879dc83b',1,'IRsend.h']]], + ['light_3144',['light',['../structstdAc_1_1state__t.html#a51c3a5c4703ea49b420d70aeb18b6b9b',1,'stdAc::state_t']]], + ['llword_3145',['llword',['../unionmagiquest.html#ad57fbc75ab289c3e93b94be0b2187d65',1,'magiquest']]], + ['lutron_3146',['LUTRON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada76cc459b9e26d82ed82cf120272fd8cb',1,'IRremoteESP8266.h']]], + ['lword_3147',['lword',['../unionmagiquest.html#ac87102145311831a232002b52fe2d02c',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.html new file mode 100644 index 000000000..bc376fec3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.js new file mode 100644 index 000000000..d968b1b91 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.js @@ -0,0 +1,39 @@ +var searchData= +[ + ['magiquest_3148',['magiquest',['../unionmagiquest.html',1,'magiquest'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3be750ce1687bc1a92fee05b0c511100',1,'MAGIQUEST(): IRremoteESP8266.h']]], + ['magnitude_3149',['magnitude',['../unionmagiquest.html#a8f687419a00322a04aab223dec093d6e',1,'magiquest']]], + ['mark_3150',['mark',['../classIRsend.html#a7399389d40bfe24bc062ffca88fc3780',1,'IRsend']]], + ['markassent_3151',['markAsSent',['../classIRac.html#ad0e45b13f477e29823b8c138704536c4',1,'IRac']]], + ['match_3152',['match',['../classIRrecv.html#a8bc218dae714ab189a3da4fff269cdaa',1,'IRrecv']]], + ['match_5fresult_5ft_3153',['match_result_t',['../structmatch__result__t.html',1,'']]], + ['matchatleast_3154',['matchAtLeast',['../classIRrecv.html#ae7bfd4ff689c7563c65c4e6e8c58187a',1,'IRrecv']]], + ['matchbytes_3155',['matchBytes',['../classIRrecv.html#adc2c9bc4c4e5741cfac7468126bf8ca6',1,'IRrecv']]], + ['matchdata_3156',['matchData',['../classIRrecv.html#a5361439cb69b1069553544e486502d2e',1,'IRrecv']]], + ['matchgeneric_3157',['matchGeneric',['../classIRrecv.html#ab783f52acc2ff4052313d6947563e4fd',1,'IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)'],['../classIRrecv.html#a4448c1658383962d735353352987c9aa',1,'IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)']]], + ['matchgenericconstbittime_3158',['matchGenericConstBitTime',['../classIRrecv.html#a4582d75ef1d11aee35fce86c38dcccf0',1,'IRrecv']]], + ['matchmanchester_3159',['matchManchester',['../classIRrecv.html#ade70777ad0e047e11b99b03d8f5e3728',1,'IRrecv']]], + ['matchmanchesterdata_3160',['matchManchesterData',['../classIRrecv.html#ab44403411a217eb8ea75271575f8ab83',1,'IRrecv']]], + ['matchmark_3161',['matchMark',['../classIRrecv.html#ae78ef12b8194db5d3cb5a2605d29830d',1,'IRrecv']]], + ['matchspace_3162',['matchSpace',['../classIRrecv.html#a9fd363e8b2edee2ed3c473349ecc58fc',1,'IRrecv']]], + ['midea_3163',['midea',['../classIRac.html#a5b9c72198497eca0121945b557691309',1,'IRac::midea()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1571f3cf72caf1cf23481802b450382a',1,'MIDEA(): IRremoteESP8266.h']]], + ['midea24_3164',['MIDEA24',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada59b5ac5c1d354e50932dc0208d9b0b43',1,'IRremoteESP8266.h']]], + ['minrepeats_3165',['minRepeats',['../classIRsend.html#ae02772f34180163861b7e4eb3520db2a',1,'IRsend']]], + ['minstostring_3166',['minsToString',['../namespaceirutils.html#aebab40a2c69624adc1a5a8a6db72952f',1,'irutils']]], + ['mitsubishi_3167',['mitsubishi',['../classIRac.html#aaa60bcac75dc5dda40c78f8c227b19a3',1,'IRac::mitsubishi()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab98915357fe1cb91de0536136be20d07',1,'MITSUBISHI(): IRremoteESP8266.h']]], + ['mitsubishi112_3168',['mitsubishi112',['../classIRac.html#a2438b6e4403d5952adb299083e038e10',1,'IRac::mitsubishi112()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab8e5875a5959b72ca7ff17bccff97c4d',1,'MITSUBISHI112(): IRremoteESP8266.h']]], + ['mitsubishi136_3169',['mitsubishi136',['../classIRac.html#aa3033eb835cf3cd313ee2c2f38357e8e',1,'IRac::mitsubishi136()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3c73724a654627a04cc96e280b9630fe',1,'MITSUBISHI136(): IRremoteESP8266.h']]], + ['mitsubishi2_3170',['MITSUBISHI2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada66368850d567cbeb3b2c2233cae34cd0',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fac_3171',['MITSUBISHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada45198cb83bbf76b320eaa91d09c44b38',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fheavy_5f152_3172',['MITSUBISHI_HEAVY_152',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada15c8d1d51d5f9e42fd03638cbdfb7cbf',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fheavy_5f88_3173',['MITSUBISHI_HEAVY_88',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad303f6c0494d33354cb7c11af258f663',1,'IRremoteESP8266.h']]], + ['mitsubishiheavy152_3174',['mitsubishiHeavy152',['../classIRac.html#a635b89320d878c1e3f270d7146cb9b00',1,'IRac']]], + ['mitsubishiheavy88_3175',['mitsubishiHeavy88',['../classIRac.html#af6c9084c5e902f98a03ad0eaf3b9448e',1,'IRac']]], + ['mode_3176',['mode',['../structstdAc_1_1state__t.html#ae5e4b17fac2ea36300f796670337d7a7',1,'stdAc::state_t']]], + ['mode_5fstate_3177',['mode_state',['../classIRToshibaAC.html#a5bb8b6cef598bb8273369b3fa7ade1b0',1,'IRToshibaAC']]], + ['model_3178',['model',['../structstdAc_1_1state__t.html#aa1a57a63b2ea80c1f9c4a1bcf16a4c62',1,'stdAc::state_t']]], + ['modeltostr_3179',['modelToStr',['../namespaceirutils.html#ae89b70ce66617a8707c1951eadbc6fbd',1,'irutils']]], + ['modulation_3180',['modulation',['../classIRsend.html#a11e26c03c87e2bed756eb7f318570bd8',1,'IRsend']]], + ['mstostring_3181',['msToString',['../namespaceirutils.html#a9c59c8dd886c283fdb8adc9082c6890a',1,'irutils']]], + ['multibrackets_3182',['MULTIBRACKETS',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaaebb72f3ad9ff2a706d8041763de6e49',1,'IRremoteESP8266.h']]], + ['mwm_3183',['MWM',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8a6938c955212e1fb81fb511437cbe56',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.html new file mode 100644 index 000000000..2e3c74dc6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.js new file mode 100644 index 000000000..55dcd37aa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['nec_3184',['NEC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0811f93a25b0873e21979d569eeac05e',1,'IRremoteESP8266.h']]], + ['nec_5flike_3185',['NEC_LIKE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada97acfde550d201fa0abc3120098fb471',1,'IRremoteESP8266.h']]], + ['neoclima_3186',['neoclima',['../classIRac.html#a0e468b705922e58308c5e340499f2391',1,'IRac::neoclima()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac698e0c030768ed91207b0e63910c3e7',1,'NEOCLIMA(): IRremoteESP8266.h']]], + ['next_3187',['next',['../classIRac.html#ae85d7ac0c58028b2547518f88d3e98fe',1,'IRac']]], + ['nikai_3188',['NIKAI',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0bc180c4ab5e68798451f4799f7f9377',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.html new file mode 100644 index 000000000..246f8ab12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.js new file mode 100644 index 000000000..5a8f7d74d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['off_3189',['off',['../classIRAmcorAc.html#a5c67c2acde4964bf863d5ae73555ea1a',1,'IRAmcorAc::off()'],['../classIRArgoAC.html#ab5ab7cc22bbce59bb02ca60431dca3fb',1,'IRArgoAC::off()'],['../classIRCarrierAc64.html#ac7a262d768626f01dac94f5e2891c98e',1,'IRCarrierAc64::off()'],['../classIRCoolixAC.html#a7538665a38e193ecd3a0bed41e9f1417',1,'IRCoolixAC::off()'],['../classIRCoronaAc.html#a3744c68ec90d89999be4db5bd6ffe2a3',1,'IRCoronaAc::off()'],['../classIRDaikinESP.html#a5d1d22f45d877660719916ca546bd3af',1,'IRDaikinESP::off()'],['../classIRDaikin2.html#a84a48dfceb4d7137eb485e6897ccceac',1,'IRDaikin2::off()'],['../classIRDaikin216.html#a086d8cea2d6dd0f74c5cbece79d91567',1,'IRDaikin216::off()'],['../classIRDaikin160.html#a95f8c71bbf861d3c884656364e04b02a',1,'IRDaikin160::off()'],['../classIRDaikin176.html#a4ad81df1fe4921abee3634bf19b0d0f7',1,'IRDaikin176::off()'],['../classIRDaikin152.html#a035588ad676a54d2b6ada8cefe10e114',1,'IRDaikin152::off()'],['../classIRDelonghiAc.html#aa2f8f1d5da390bd5e5b36102dd40f5c8',1,'IRDelonghiAc::off()'],['../classIRElectraAc.html#afe3a9b789eafbef19d015cdebf71dc0d',1,'IRElectraAc::off()'],['../classIRFujitsuAC.html#ae7a320c2d2b8afbd9a04251053831cdd',1,'IRFujitsuAC::off()'],['../classIRGoodweatherAc.html#ad6863d837140951fcc0faf629025d48e',1,'IRGoodweatherAc::off()'],['../classIRGreeAC.html#a4cce897175ed731ab62402133089ed4f',1,'IRGreeAC::off()'],['../classIRHaierACYRW02.html#a9837ba26574f8bd452d616173819a9a4',1,'IRHaierACYRW02::off()'],['../classIRHitachiAc.html#a62be5ca181c8c9d11b65b38b1ed178b5',1,'IRHitachiAc::off()'],['../classIRHitachiAc1.html#a646b554980706d0dd2ac762be8458cdb',1,'IRHitachiAc1::off()'],['../classIRHitachiAc424.html#a0815a09fc49449bac03d996c63040a5f',1,'IRHitachiAc424::off()'],['../classIRKelvinatorAC.html#a4a759df902d1465c9520da7c7c595abc',1,'IRKelvinatorAC::off()'],['../classIRLgAc.html#a6d3d50b34575fecb93ed8bd5897c3f7c',1,'IRLgAc::off()'],['../classIRMideaAC.html#a29fbafcf47dc41475d009c4c92b2917b',1,'IRMideaAC::off()'],['../classIRMitsubishiAC.html#ac204620341200994c28411f53d5aa046',1,'IRMitsubishiAC::off()'],['../classIRMitsubishi136.html#a4122014509e9e755881920650f19baf3',1,'IRMitsubishi136::off()'],['../classIRMitsubishi112.html#ab5b6370edf2626da2e9f124a218678a8',1,'IRMitsubishi112::off()'],['../classIRMitsubishiHeavy152Ac.html#a93b603cc37d2dc7e3e7005ce21a0b2d7',1,'IRMitsubishiHeavy152Ac::off()'],['../classIRMitsubishiHeavy88Ac.html#a45c56c0454755d704a3df1f1f3647130',1,'IRMitsubishiHeavy88Ac::off()'],['../classIRNeoclimaAc.html#a9a277308bf8d8b0cd06a28964e7cbafb',1,'IRNeoclimaAc::off()'],['../classIRPanasonicAc.html#a03b706293c1c5b348bba536e6d8d33f5',1,'IRPanasonicAc::off()'],['../classIRSamsungAc.html#a34cb19bb4902441a2b9f10892eb17d83',1,'IRSamsungAc::off()'],['../classIRSharpAc.html#a178925a1d7ca01aae5c107fab5b32e93',1,'IRSharpAc::off()'],['../classIRTcl112Ac.html#ab2e39430629fcada55a584cff66d2749',1,'IRTcl112Ac::off()'],['../classIRTecoAc.html#ade1b1541bf2de053c78657af1ebcd001',1,'IRTecoAc::off()'],['../classIRToshibaAC.html#a70b145f7b9c46790e4e5da812bb66e58',1,'IRToshibaAC::off()'],['../classIRTrotecESP.html#a8f300ddaf255de1cdfee10b76b1f08e0',1,'IRTrotecESP::off()'],['../classIRVestelAc.html#a59e90e51e3518ef26bb382903ce67357',1,'IRVestelAc::off()']]], + ['offtimeperiod_3190',['offTimePeriod',['../classIRsend.html#a9e45c9e4f54db86c1f3e506cd72fe4c1',1,'IRsend']]], + ['on_3191',['on',['../classIRAmcorAc.html#adff3f4b9f57815a4062443f3e4dab78c',1,'IRAmcorAc::on()'],['../classIRArgoAC.html#a70497752f7afd8e3274cf4d8b1e22628',1,'IRArgoAC::on()'],['../classIRCarrierAc64.html#a39c13b713e36fbf94605f251b36bdfae',1,'IRCarrierAc64::on()'],['../classIRCoolixAC.html#a59c414fe0e951cd50083ab1fc45286ed',1,'IRCoolixAC::on()'],['../classIRCoronaAc.html#a7fe14d62eaccdc2db8db168c90a3cd87',1,'IRCoronaAc::on()'],['../classIRDaikinESP.html#a502e9dea10605d52e291d49af26b07eb',1,'IRDaikinESP::on()'],['../classIRDaikin2.html#a009ac70fd8b8695f3d931a42667fdb66',1,'IRDaikin2::on()'],['../classIRDaikin216.html#a09f54bb4ed1d553b4bbf6ffe6992a755',1,'IRDaikin216::on()'],['../classIRDaikin160.html#a2b6c282ad5cb2a702857532ab020110b',1,'IRDaikin160::on()'],['../classIRDaikin176.html#a3ca59ccdad4b7958fc4dc1a4b0593f38',1,'IRDaikin176::on()'],['../classIRDaikin152.html#a10ee74aa43e3940d657ac88cb03b9138',1,'IRDaikin152::on()'],['../classIRDelonghiAc.html#ab21d64ace3107a8f3359b3828bc2cab5',1,'IRDelonghiAc::on()'],['../classIRElectraAc.html#a99e29f982435b01c726d0234a433cfa6',1,'IRElectraAc::on()'],['../classIRFujitsuAC.html#adcb24818d088c879beb7d76ada332f43',1,'IRFujitsuAC::on()'],['../classIRGoodweatherAc.html#a1e3c2a9f47376062ab66318d6af4324b',1,'IRGoodweatherAc::on()'],['../classIRGreeAC.html#a69e399e411a19e5669e752d52ae66f15',1,'IRGreeAC::on()'],['../classIRHaierACYRW02.html#aaeb257d68235278be272e521fdec7331',1,'IRHaierACYRW02::on()'],['../classIRHitachiAc.html#a855e95d55d4ebfb3958b9d80a7b42c6f',1,'IRHitachiAc::on()'],['../classIRHitachiAc1.html#aea4fe1fddb56c8df31077b301e9c6473',1,'IRHitachiAc1::on()'],['../classIRHitachiAc424.html#ad414bca642af40ed81a6cbf93a0bf40b',1,'IRHitachiAc424::on()'],['../classIRKelvinatorAC.html#a714d0e70f2996694e2c46afdd9996341',1,'IRKelvinatorAC::on()'],['../classIRLgAc.html#a171358340c1ba8f90fef0c5454f2aa41',1,'IRLgAc::on()'],['../classIRMideaAC.html#af8dde03cb641a5af4f2ef0dcf70f1ca0',1,'IRMideaAC::on()'],['../classIRMitsubishiAC.html#a2946d1b3b641d7b991c0d296d5c5e77e',1,'IRMitsubishiAC::on()'],['../classIRMitsubishi136.html#a74180e99a5f4f1f4b740b442a1b74a06',1,'IRMitsubishi136::on()'],['../classIRMitsubishi112.html#accd250f130b4d0cd61593982b84b9138',1,'IRMitsubishi112::on()'],['../classIRMitsubishiHeavy152Ac.html#a5c7aec50b53fdc3af591e077a4a268e4',1,'IRMitsubishiHeavy152Ac::on()'],['../classIRMitsubishiHeavy88Ac.html#a44ce2c4f03b8b8973922f5bf59a19d2c',1,'IRMitsubishiHeavy88Ac::on()'],['../classIRNeoclimaAc.html#ab4a23cefef02351883dc4088dec51071',1,'IRNeoclimaAc::on()'],['../classIRPanasonicAc.html#a88e6b0f607b17266567306576e623a0c',1,'IRPanasonicAc::on()'],['../classIRSamsungAc.html#a68cf52997489a1c835662c7cdf23463c',1,'IRSamsungAc::on()'],['../classIRSharpAc.html#a5c8dad46c2965fc0d87780a8bd8b98f4',1,'IRSharpAc::on()'],['../classIRTcl112Ac.html#a0bbf7f0b9753b516fda0544c17b15b8a',1,'IRTcl112Ac::on()'],['../classIRTecoAc.html#af26015e5c663c346cf7db6d8af3f8c60',1,'IRTecoAc::on()'],['../classIRToshibaAC.html#abdc35338e4a18132d56bf6b46ddea590',1,'IRToshibaAC::on()'],['../classIRTrotecESP.html#a86c050edab8409a9b38d28f311f19404',1,'IRTrotecESP::on()'],['../classIRVestelAc.html#a4ed05fb5cbdfa5677ca238616bf03922',1,'IRVestelAc::on()']]], + ['ontimeperiod_3192',['onTimePeriod',['../classIRsend.html#aaaa65f31dbea033f8130e847b0366d94',1,'IRsend']]], + ['opmode_5ft_3193',['opmode_t',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444f',1,'stdAc']]], + ['opmodetostring_3194',['opmodeToString',['../classIRac.html#a6dd1b87f2477bc3721d207b1fed482b8',1,'IRac']]], + ['outputoff_3195',['outputOff',['../classIRsend.html#a5e80df8b2ee534dbd6ddc30a852a2791',1,'IRsend']]], + ['outputon_3196',['outputOn',['../classIRsend.html#a4acfc45b339e724e2dbdff24762dfa7d',1,'IRsend']]], + ['overflow_3197',['overflow',['../structirparams__t.html#aa39b4f38e0ffcd470766373e03548e58',1,'irparams_t::overflow()'],['../classdecode__results.html#a821bc53c006bab3283c6b8592f0c43d3',1,'decode_results::overflow()']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.html new file mode 100644 index 000000000..f7e4c14e1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.js new file mode 100644 index 000000000..1e99ee58b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['decode_5fresults_3525',['decode_results',['../classdecode__results.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.html new file mode 100644 index 000000000..c7ff4b311 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.js new file mode 100644 index 000000000..49407fd27 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.js @@ -0,0 +1,51 @@ +var searchData= +[ + ['irac_3526',['IRac',['../classIRac.html',1,'']]], + ['iramcorac_3527',['IRAmcorAc',['../classIRAmcorAc.html',1,'']]], + ['irargoac_3528',['IRArgoAC',['../classIRArgoAC.html',1,'']]], + ['ircarrierac64_3529',['IRCarrierAc64',['../classIRCarrierAc64.html',1,'']]], + ['ircoolixac_3530',['IRCoolixAC',['../classIRCoolixAC.html',1,'']]], + ['ircoronaac_3531',['IRCoronaAc',['../classIRCoronaAc.html',1,'']]], + ['irdaikin128_3532',['IRDaikin128',['../classIRDaikin128.html',1,'']]], + ['irdaikin152_3533',['IRDaikin152',['../classIRDaikin152.html',1,'']]], + ['irdaikin160_3534',['IRDaikin160',['../classIRDaikin160.html',1,'']]], + ['irdaikin176_3535',['IRDaikin176',['../classIRDaikin176.html',1,'']]], + ['irdaikin2_3536',['IRDaikin2',['../classIRDaikin2.html',1,'']]], + ['irdaikin216_3537',['IRDaikin216',['../classIRDaikin216.html',1,'']]], + ['irdaikin64_3538',['IRDaikin64',['../classIRDaikin64.html',1,'']]], + ['irdaikinesp_3539',['IRDaikinESP',['../classIRDaikinESP.html',1,'']]], + ['irdelonghiac_3540',['IRDelonghiAc',['../classIRDelonghiAc.html',1,'']]], + ['irelectraac_3541',['IRElectraAc',['../classIRElectraAc.html',1,'']]], + ['irfujitsuac_3542',['IRFujitsuAC',['../classIRFujitsuAC.html',1,'']]], + ['irgoodweatherac_3543',['IRGoodweatherAc',['../classIRGoodweatherAc.html',1,'']]], + ['irgreeac_3544',['IRGreeAC',['../classIRGreeAC.html',1,'']]], + ['irhaierac_3545',['IRHaierAC',['../classIRHaierAC.html',1,'']]], + ['irhaieracyrw02_3546',['IRHaierACYRW02',['../classIRHaierACYRW02.html',1,'']]], + ['irhitachiac_3547',['IRHitachiAc',['../classIRHitachiAc.html',1,'']]], + ['irhitachiac1_3548',['IRHitachiAc1',['../classIRHitachiAc1.html',1,'']]], + ['irhitachiac3_3549',['IRHitachiAc3',['../classIRHitachiAc3.html',1,'']]], + ['irhitachiac344_3550',['IRHitachiAc344',['../classIRHitachiAc344.html',1,'']]], + ['irhitachiac424_3551',['IRHitachiAc424',['../classIRHitachiAc424.html',1,'']]], + ['irkelvinatorac_3552',['IRKelvinatorAC',['../classIRKelvinatorAC.html',1,'']]], + ['irlgac_3553',['IRLgAc',['../classIRLgAc.html',1,'']]], + ['irmideaac_3554',['IRMideaAC',['../classIRMideaAC.html',1,'']]], + ['irmitsubishi112_3555',['IRMitsubishi112',['../classIRMitsubishi112.html',1,'']]], + ['irmitsubishi136_3556',['IRMitsubishi136',['../classIRMitsubishi136.html',1,'']]], + ['irmitsubishiac_3557',['IRMitsubishiAC',['../classIRMitsubishiAC.html',1,'']]], + ['irmitsubishiheavy152ac_3558',['IRMitsubishiHeavy152Ac',['../classIRMitsubishiHeavy152Ac.html',1,'']]], + ['irmitsubishiheavy88ac_3559',['IRMitsubishiHeavy88Ac',['../classIRMitsubishiHeavy88Ac.html',1,'']]], + ['irneoclimaac_3560',['IRNeoclimaAc',['../classIRNeoclimaAc.html',1,'']]], + ['irpanasonicac_3561',['IRPanasonicAc',['../classIRPanasonicAc.html',1,'']]], + ['irparams_5ft_3562',['irparams_t',['../structirparams__t.html',1,'']]], + ['irrecv_3563',['IRrecv',['../classIRrecv.html',1,'']]], + ['irsamsungac_3564',['IRSamsungAc',['../classIRSamsungAc.html',1,'']]], + ['irsend_3565',['IRsend',['../classIRsend.html',1,'']]], + ['irsharpac_3566',['IRSharpAc',['../classIRSharpAc.html',1,'']]], + ['irtcl112ac_3567',['IRTcl112Ac',['../classIRTcl112Ac.html',1,'']]], + ['irtecoac_3568',['IRTecoAc',['../classIRTecoAc.html',1,'']]], + ['irtimer_3569',['IRtimer',['../classIRtimer.html',1,'']]], + ['irtoshibaac_3570',['IRToshibaAC',['../classIRToshibaAC.html',1,'']]], + ['irtrotecesp_3571',['IRTrotecESP',['../classIRTrotecESP.html',1,'']]], + ['irvestelac_3572',['IRVestelAc',['../classIRVestelAc.html',1,'']]], + ['irwhirlpoolac_3573',['IRWhirlpoolAc',['../classIRWhirlpoolAc.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.html new file mode 100644 index 000000000..0d1e8a0cd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.js new file mode 100644 index 000000000..6b48c0d25 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['magiquest_3574',['magiquest',['../unionmagiquest.html',1,'']]], + ['match_5fresult_5ft_3575',['match_result_t',['../structmatch__result__t.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.html new file mode 100644 index 000000000..21025456b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.js new file mode 100644 index 000000000..5c2121b37 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['state_5ft_3576',['state_t',['../structstdAc_1_1state__t.html',1,'stdAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.html new file mode 100644 index 000000000..095ab5952 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.js new file mode 100644 index 000000000..a4b18ce82 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['timerms_3577',['TimerMs',['../classTimerMs.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/close.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/close.png new file mode 100644 index 0000000000000000000000000000000000000000..9342d3dfeea7b7c4ee610987e717804b5a42ceb9 GIT binary patch literal 273 zcmV+s0q*{ZP)4(RlMby96)VwnbG{ zbe&}^BDn7x>$<{ck4zAK-=nT;=hHG)kmplIF${xqm8db3oX6wT3bvp`TE@m0cg;b) zBuSL}5?N7O(iZLdAlz@)b)Rd~DnSsSX&P5qC`XwuFwcAYLC+d2>+1(8on;wpt8QIC X2MT$R4iQDd00000NkvXXu0mjfia~GN literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.html new file mode 100644 index 000000000..9669700af --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.js new file mode 100644 index 000000000..f1f1a5972 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['decode_5ftype_5ft_6976',['decode_type_t',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fad',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.html new file mode 100644 index 000000000..dfec174d1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.js new file mode 100644 index 000000000..6f4ff342e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['fanspeed_5ft_6977',['fanspeed_t',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383',1,'stdAc']]], + ['fujitsu_5fac_5fremote_5fmodel_5ft_6978',['fujitsu_ac_remote_model_t',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.html new file mode 100644 index 000000000..db70c3668 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.js new file mode 100644 index 000000000..a09539dd4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['gree_5fac_5fremote_5fmodel_5ft_6979',['gree_ac_remote_model_t',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.html new file mode 100644 index 000000000..fb7ec1764 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.js new file mode 100644 index 000000000..22a2e8dcd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['hitachi_5fac1_5fremote_5fmodel_5ft_6980',['hitachi_ac1_remote_model_t',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.html new file mode 100644 index 000000000..b8b51ef8f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.js new file mode 100644 index 000000000..9f8fd8ed4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['lg_5fac_5fremote_5fmodel_5ft_6981',['lg_ac_remote_model_t',['../IRsend_8h.html#a50c54713e16502d280723334879dc83b',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.html new file mode 100644 index 000000000..d39b033aa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.js new file mode 100644 index 000000000..575ca6e52 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['opmode_5ft_6982',['opmode_t',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444f',1,'stdAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.html new file mode 100644 index 000000000..7dd141e97 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.js new file mode 100644 index 000000000..b72fde82b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['panasonic_5fac_5fremote_5fmodel_5ft_6983',['panasonic_ac_remote_model_t',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6f',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.html new file mode 100644 index 000000000..2836f52ee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.js new file mode 100644 index 000000000..02ccbf16b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['swingh_5ft_6984',['swingh_t',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147',1,'stdAc']]], + ['swingv_5ft_6985',['swingv_t',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43',1,'stdAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.html new file mode 100644 index 000000000..cf04f764b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.js new file mode 100644 index 000000000..2f78a824e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['whirlpool_5fac_5fremote_5fmodel_5ft_6986',['whirlpool_ac_remote_model_t',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.html new file mode 100644 index 000000000..928624899 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.js new file mode 100644 index 000000000..c19cd973e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['airwell_6987',['AIRWELL',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0cd75c2edaa4c674d679dbb39635990a',1,'IRremoteESP8266.h']]], + ['aiwa_5frc_5ft501_6988',['AIWA_RC_T501',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7dc14b2c4769ef9de663c2e2165d8f75',1,'IRremoteESP8266.h']]], + ['akb75215403_6989',['AKB75215403',['../IRsend_8h.html#a50c54713e16502d280723334879dc83ba37d3851f43307f1e1eac46c5fbf3f08a',1,'IRsend.h']]], + ['amcor_6990',['AMCOR',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1325ba25674d7a99562f15a1b392086b',1,'IRremoteESP8266.h']]], + ['ardb1_6991',['ARDB1',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a6f6fcd0be917d91b71c1b80b5446ee5b',1,'IRsend.h']]], + ['argo_6992',['ARGO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac9ff1fa84905b54238b16d31197efb72',1,'IRremoteESP8266.h']]], + ['arjw2_6993',['ARJW2',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0acbca1f3d199103d8cb9d856b9089cdc4',1,'IRsend.h']]], + ['arrah2e_6994',['ARRAH2E',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a6ccf47af1067e794e02e21f03389297b',1,'IRsend.h']]], + ['arreb1e_6995',['ARREB1E',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a2443ff6f0181dbc1af275c709d67147a',1,'IRsend.h']]], + ['arry4_6996',['ARRY4',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0aee3994c5a4a8447463d67df2cdf5a946',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.html new file mode 100644 index 000000000..e22a79fb9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.js new file mode 100644 index 000000000..62123eb2c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['carrier_5fac_6997',['CARRIER_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4d7328071e0a48bc828fccb02f969c20',1,'IRremoteESP8266.h']]], + ['carrier_5fac40_6998',['CARRIER_AC40',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1340c578f7986b0ed126744127af3907',1,'IRremoteESP8266.h']]], + ['carrier_5fac64_6999',['CARRIER_AC64',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4122973f5d8ce282457d348857ba0af0',1,'IRremoteESP8266.h']]], + ['coolix_7000',['COOLIX',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadae561d1d82d90c1b54a1a502431749873',1,'IRremoteESP8266.h']]], + ['corona_5fac_7001',['CORONA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf61f2c360f487309cfa466a44fcae106',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.html new file mode 100644 index 000000000..7107c3d7d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.js new file mode 100644 index 000000000..c5c4d155a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['tcl112ac_7109',['TCL112AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac4a6ebe702365620ed65ac6f484afda6',1,'IRremoteESP8266.h']]], + ['teco_7110',['TECO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3a15ee4466478d484508acc3d4d7a050',1,'IRremoteESP8266.h']]], + ['toshiba_5fac_7111',['TOSHIBA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada66de3fced9e8f97d1919bcf4d5726f3e',1,'IRremoteESP8266.h']]], + ['trotec_7112',['TROTEC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7d0f8056d221b37f68f80bace2b794b9',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.html new file mode 100644 index 000000000..aab485d35 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.js new file mode 100644 index 000000000..4bd54ec38 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['unknown_7113',['UNKNOWN',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada6ce26a62afab55d7606ad4e92428b30c',1,'IRremoteESP8266.h']]], + ['unused_7114',['UNUSED',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa09b651ef326a9d8efcee5cc5b720ab4',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.html new file mode 100644 index 000000000..9d9425504 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.js new file mode 100644 index 000000000..47989297d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['vestel_5fac_7115',['VESTEL_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada165413c6395bde985757b5b446f76569',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.html new file mode 100644 index 000000000..f7dea3e56 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.js new file mode 100644 index 000000000..7380f07ea --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['whirlpool_5fac_7116',['WHIRLPOOL_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9faf927323d110269541b356f079b85a',1,'IRremoteESP8266.h']]], + ['whynter_7117',['WHYNTER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada458cdd7fa2b29dc8617c694696580c0c',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.html new file mode 100644 index 000000000..6a7874ada --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.js new file mode 100644 index 000000000..8e1d3c7ff --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['yaw1f_7118',['YAW1F',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9a6b29d752ac8bafc8fedabc1282fccfb6',1,'IRsend.h']]], + ['ybofb_7119',['YBOFB',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9a5d6dadebb4f337aa20ea06a87ae9b34a',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.html new file mode 100644 index 000000000..1e778765b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.js new file mode 100644 index 000000000..7ae142fc9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['zepeal_7120',['ZEPEAL',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1622e3d0835b4d47add716811c7bf797',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.html new file mode 100644 index 000000000..01a77bf7a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.js new file mode 100644 index 000000000..164f437b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['daikin_7002',['DAIKIN',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad8dc0597fd237d7098246334f3b5f37e',1,'IRremoteESP8266.h']]], + ['daikin128_7003',['DAIKIN128',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4b26fb376f6375dd6d1d4be186438f88',1,'IRremoteESP8266.h']]], + ['daikin152_7004',['DAIKIN152',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad3f5f7ca39aee5fdab671a1b0d647ae4',1,'IRremoteESP8266.h']]], + ['daikin160_7005',['DAIKIN160',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4db6a848df3aed4289801e1b2bbbf6aa',1,'IRremoteESP8266.h']]], + ['daikin176_7006',['DAIKIN176',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada57f78a3b04d904f19d10bac13483deab',1,'IRremoteESP8266.h']]], + ['daikin2_7007',['DAIKIN2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab37b344f84d575ec78a92ca55e153586',1,'IRremoteESP8266.h']]], + ['daikin216_7008',['DAIKIN216',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa833fa3a20c3cbb7e6206dac4da30ffb',1,'IRremoteESP8266.h']]], + ['daikin64_7009',['DAIKIN64',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada70581853ce4883b747d22fdfd74409c4',1,'IRremoteESP8266.h']]], + ['delonghi_5fac_7010',['DELONGHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada149190c9dec98e9c3f4a2bd530b154a3',1,'IRremoteESP8266.h']]], + ['denon_7011',['DENON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada2bda37b76abb290d1675c3e027e3c2e1',1,'IRremoteESP8266.h']]], + ['dg11j13a_7012',['DG11J13A',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2a868d69f0605cf9151b0163a3481e2fb9',1,'IRsend.h']]], + ['dg11j191_7013',['DG11J191',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2adaecfc16f36975f231db2507a8a36c0c',1,'IRsend.h']]], + ['dish_7014',['DISH',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac27c6ac38ba872593af8e46ac2fdc85a',1,'IRremoteESP8266.h']]], + ['doshisha_7015',['DOSHISHA',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab4566b260773b60c85450f40fa5b4341',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.html new file mode 100644 index 000000000..4e761d602 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.js new file mode 100644 index 000000000..7794084e0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['electra_5fac_7016',['ELECTRA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada05f193ef4ead3e54624bd92dc3203fac',1,'IRremoteESP8266.h']]], + ['epson_7017',['EPSON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaaf677fd380c38297264a10732631927c',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.html new file mode 100644 index 000000000..e2977a05c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.js new file mode 100644 index 000000000..a1b41ed5e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['fujitsu_5fac_7018',['FUJITSU_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad8cf99a3a8776d644b78313306a2108c',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.html new file mode 100644 index 000000000..eabdd4be2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.js new file mode 100644 index 000000000..3a9434783 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['ge6711ar2853m_7019',['GE6711AR2853M',['../IRsend_8h.html#a50c54713e16502d280723334879dc83bada534bddbb58907faa6c7eae385ec790',1,'IRsend.h']]], + ['gicable_7020',['GICABLE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac8f9010b746a07a7a6329d1b336b68cf',1,'IRremoteESP8266.h']]], + ['globalcache_7021',['GLOBALCACHE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf8c11b983768907fdb625ff9fb3729d2',1,'IRremoteESP8266.h']]], + ['goodweather_7022',['GOODWEATHER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9e8d893590b745f6b1b5ffcb556d9cba',1,'IRremoteESP8266.h']]], + ['gree_7023',['GREE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadae3a5e7c315f6f88b34a4c856f280ed83',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.html new file mode 100644 index 000000000..24764919a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.js new file mode 100644 index 000000000..ddc065eb8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['haier_5fac_7024',['HAIER_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1f232bcdf330ec2e353196941b9f1628',1,'IRremoteESP8266.h']]], + ['haier_5fac_5fyrw02_7025',['HAIER_AC_YRW02',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaacda5821835865551f6df46c76282fa4',1,'IRremoteESP8266.h']]], + ['hitachi_5fac_7026',['HITACHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9020fb54ac69d8aec0185f7e80c962ca',1,'IRremoteESP8266.h']]], + ['hitachi_5fac1_7027',['HITACHI_AC1',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7d9a74161d95e62bece3c0e48900cb35',1,'IRremoteESP8266.h']]], + ['hitachi_5fac2_7028',['HITACHI_AC2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab5a44068d519506efa8a3113aa44c9c0',1,'IRremoteESP8266.h']]], + ['hitachi_5fac3_7029',['HITACHI_AC3',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac3487c47b14da6af922f5b27992b30f3',1,'IRremoteESP8266.h']]], + ['hitachi_5fac344_7030',['HITACHI_AC344',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1e147eb39adc40e4181940cc2357f070',1,'IRremoteESP8266.h']]], + ['hitachi_5fac424_7031',['HITACHI_AC424',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada85af068f8964d4359512265d8cc27a31',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.html new file mode 100644 index 000000000..5d5ce7ee6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.js new file mode 100644 index 000000000..32f72ebfa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['inax_7032',['INAX',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadafc566aab3afb8face6d8965ca4d0eab7',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.html new file mode 100644 index 000000000..be088de03 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.js new file mode 100644 index 000000000..b6c589bc7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['jvc_7033',['JVC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada5b6f507fb4bbd70ee70be4e2e0b0371d',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.html new file mode 100644 index 000000000..b521e0972 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.js new file mode 100644 index 000000000..c79d90305 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.js @@ -0,0 +1,35 @@ +var searchData= +[ + ['kauto_7034',['kAuto',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444faa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()']]], + ['kcool_7035',['kCool',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fab9480fe865ab6bbfb66c8308068a06c2',1,'stdAc']]], + ['kdry_7036',['kDry',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa0d254f21cc940f41cf7cc1c8ff46ce1f',1,'stdAc']]], + ['kelvinator_7037',['KELVINATOR',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab3a52797572065c912c34c976c08c542',1,'IRremoteESP8266.h']]], + ['kfan_7038',['kFan',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa03b7310c6ec7018a07ee9e3ffb95a34b',1,'stdAc']]], + ['kheat_7039',['kHeat',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444faece059b52386d38cd6da9729cca08b4e',1,'stdAc']]], + ['khigh_7040',['kHigh',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa022f15e910eb36278094efb6e808a07',1,'stdAc::kHigh()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43aa022f15e910eb36278094efb6e808a07',1,'stdAc::kHigh()']]], + ['khighest_7041',['kHighest',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a24d8e31603e486f788826bc24e3a2e1d',1,'stdAc']]], + ['klastdecodetype_7042',['kLastDecodeType',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab09881b84bf9d61af99e62a85cce0b59',1,'IRremoteESP8266.h']]], + ['klastfanspeedenum_7043',['kLastFanspeedEnum',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383ab2d2a6993491fd666f1fa0afff5913ad',1,'stdAc']]], + ['klastopmodeenum_7044',['kLastOpmodeEnum',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa8dd00ffd575f66172d594e78860aad9f',1,'stdAc']]], + ['klastswinghenum_7045',['kLastSwinghEnum',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147ac5bc5e605db47897c114283926ba7fe4',1,'stdAc']]], + ['klastswingvenum_7046',['kLastSwingvEnum',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a4127912afc084d51c71c4ea0c7dd7b30',1,'stdAc']]], + ['kleft_7047',['kLeft',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a2d5fde1d924910a2a01ecd8e70a87c28',1,'stdAc']]], + ['kleftmax_7048',['kLeftMax',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a375fe2e8ea70186052eeb2983baa1d7d',1,'stdAc']]], + ['klow_7049',['kLow',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383acd8fe42741a3bbc973bbf1d404afeff4',1,'stdAc::kLow()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43acd8fe42741a3bbc973bbf1d404afeff4',1,'stdAc::kLow()']]], + ['klowest_7050',['kLowest',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a334c684494b7f19d765cf062ae94a314',1,'stdAc']]], + ['kmax_7051',['kMax',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa0b1ac8aae6b1cfbbe89085c642b3b4b',1,'stdAc']]], + ['kmedium_7052',['kMedium',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383a3ce9d817402b59f65fb01ea044bb1ee9',1,'stdAc']]], + ['kmiddle_7053',['kMiddle',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43ab3199775e825c139b44e3e9ccf3cbc7e',1,'stdAc::kMiddle()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147ab3199775e825c139b44e3e9ccf3cbc7e',1,'stdAc::kMiddle()']]], + ['kmin_7054',['kMin',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383a8fbc2f6c44a6d70550df79903eb57d48',1,'stdAc']]], + ['koff_7055',['kOff',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444facc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43acc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147acc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()']]], + ['kpanasonicckp_7056',['kPanasonicCkp',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa537e8c640473597d2a1cb832498f9cb0',1,'IRsend.h']]], + ['kpanasonicdke_7057',['kPanasonicDke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fac8df2e0cfd553b0103f4c06a0fd573fd',1,'IRsend.h']]], + ['kpanasonicjke_7058',['kPanasonicJke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fabf39cff180c071fbc44601eeded236c4',1,'IRsend.h']]], + ['kpanasoniclke_7059',['kPanasonicLke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa71ceb4b576a03a47f0d945323b896cd6',1,'IRsend.h']]], + ['kpanasonicnke_7060',['kPanasonicNke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6faf70fc847e204f60ab1dc5ecb330fc790',1,'IRsend.h']]], + ['kpanasonicrkr_7061',['kPanasonicRkr',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fab809a062f38eb61589cf5aa2db5789db',1,'IRsend.h']]], + ['kpanasonicunknown_7062',['kPanasonicUnknown',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa3b23623c9580717d0ade5137200ae2a4',1,'IRsend.h']]], + ['kright_7063',['kRight',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a2dd2b017192f8a09367d48c7648213c9',1,'stdAc']]], + ['krightmax_7064',['kRightMax',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a856bf9929ade459f451be17c97db4b32',1,'stdAc']]], + ['kwide_7065',['kWide',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a9934dc3d02540583d5f13be6716739cd',1,'stdAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.html new file mode 100644 index 000000000..ea342169a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.js new file mode 100644 index 000000000..c9b03ff30 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['lasertag_7066',['LASERTAG',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada92eadf4fa6dd16da5b79a2fcbf729894',1,'IRremoteESP8266.h']]], + ['legopf_7067',['LEGOPF',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9a31bf5555b17ea7b115a5c2550fc1de',1,'IRremoteESP8266.h']]], + ['lg_7068',['LG',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadadf6c249ac7d923229f9e623eff9a61f4',1,'IRremoteESP8266.h']]], + ['lg2_7069',['LG2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8402547ec0b99b9b0efe97dec65badf9',1,'IRremoteESP8266.h']]], + ['lutron_7070',['LUTRON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada76cc459b9e26d82ed82cf120272fd8cb',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.html new file mode 100644 index 000000000..0bb27ce3b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.js new file mode 100644 index 000000000..c4d23b604 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['magiquest_7071',['MAGIQUEST',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3be750ce1687bc1a92fee05b0c511100',1,'IRremoteESP8266.h']]], + ['midea_7072',['MIDEA',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1571f3cf72caf1cf23481802b450382a',1,'IRremoteESP8266.h']]], + ['midea24_7073',['MIDEA24',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada59b5ac5c1d354e50932dc0208d9b0b43',1,'IRremoteESP8266.h']]], + ['mitsubishi_7074',['MITSUBISHI',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab98915357fe1cb91de0536136be20d07',1,'IRremoteESP8266.h']]], + ['mitsubishi112_7075',['MITSUBISHI112',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab8e5875a5959b72ca7ff17bccff97c4d',1,'IRremoteESP8266.h']]], + ['mitsubishi136_7076',['MITSUBISHI136',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3c73724a654627a04cc96e280b9630fe',1,'IRremoteESP8266.h']]], + ['mitsubishi2_7077',['MITSUBISHI2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada66368850d567cbeb3b2c2233cae34cd0',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fac_7078',['MITSUBISHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada45198cb83bbf76b320eaa91d09c44b38',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fheavy_5f152_7079',['MITSUBISHI_HEAVY_152',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada15c8d1d51d5f9e42fd03638cbdfb7cbf',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fheavy_5f88_7080',['MITSUBISHI_HEAVY_88',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad303f6c0494d33354cb7c11af258f663',1,'IRremoteESP8266.h']]], + ['multibrackets_7081',['MULTIBRACKETS',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaaebb72f3ad9ff2a706d8041763de6e49',1,'IRremoteESP8266.h']]], + ['mwm_7082',['MWM',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8a6938c955212e1fb81fb511437cbe56',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.html new file mode 100644 index 000000000..1ee90d91d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.js new file mode 100644 index 000000000..c1f6db3ae --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['nec_7083',['NEC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0811f93a25b0873e21979d569eeac05e',1,'IRremoteESP8266.h']]], + ['nec_5flike_7084',['NEC_LIKE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada97acfde550d201fa0abc3120098fb471',1,'IRremoteESP8266.h']]], + ['neoclima_7085',['NEOCLIMA',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac698e0c030768ed91207b0e63910c3e7',1,'IRremoteESP8266.h']]], + ['nikai_7086',['NIKAI',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0bc180c4ab5e68798451f4799f7f9377',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.html new file mode 100644 index 000000000..e1b3b48a0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.js new file mode 100644 index 000000000..2495af799 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['panasonic_7087',['PANASONIC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf87c99938d26a1f77d4f082c070d4660',1,'IRremoteESP8266.h']]], + ['panasonic_5fac_7088',['PANASONIC_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada02178d0c70511011d5f381291bb7e491',1,'IRremoteESP8266.h']]], + ['pioneer_7089',['PIONEER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadadf49fef8f6e9740c92af2e25384f7846',1,'IRremoteESP8266.h']]], + ['pronto_7090',['PRONTO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada5b68c32f80c4afa6e61039843b2d1f97',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.html new file mode 100644 index 000000000..c5d31975c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.js new file mode 100644 index 000000000..f1be901f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['r_5flt0541_5fhta_5fa_7091',['R_LT0541_HTA_A',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49afed7c9dd67250bb1e72081e5f05b35f8',1,'IRsend.h']]], + ['r_5flt0541_5fhta_5fb_7092',['R_LT0541_HTA_B',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49a03b6e058b4cfeb6719906bc3cd57594f',1,'IRsend.h']]], + ['raw_7093',['RAW',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadabdeded99fe7d3f2773014a9a2cfb73d7',1,'IRremoteESP8266.h']]], + ['rc5_7094',['RC5',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac3c0a3883a1488209bcd91730ece33b2',1,'IRremoteESP8266.h']]], + ['rc5x_7095',['RC5X',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8a3ac4419806a34ba566bfcbbb0e4f1d',1,'IRremoteESP8266.h']]], + ['rc6_7096',['RC6',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7f7247f15587eb3812846f424b941abe',1,'IRremoteESP8266.h']]], + ['rcmm_7097',['RCMM',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada79204b7ae26be334cebf3ea8268c34ab',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.html new file mode 100644 index 000000000..5de961d49 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.js new file mode 100644 index 000000000..9af6f712f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['samsung_7098',['SAMSUNG',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada2b451b6e7bebbf070d0913ec77d5d438',1,'IRremoteESP8266.h']]], + ['samsung36_7099',['SAMSUNG36',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa0d1be0c368e3594bc546c241d031fd4',1,'IRremoteESP8266.h']]], + ['samsung_5fac_7100',['SAMSUNG_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada39f991023009d760432489e7ad7ad4df',1,'IRremoteESP8266.h']]], + ['sanyo_7101',['SANYO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac1cf5078ebfd7ff83c70e8ec8522b288',1,'IRremoteESP8266.h']]], + ['sanyo_5flc7461_7102',['SANYO_LC7461',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada558721044a11b1d4b491343f02267e1d',1,'IRremoteESP8266.h']]], + ['sharp_7103',['SHARP',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaad63db67a2284cd7e3ffe382b6d6ea82',1,'IRremoteESP8266.h']]], + ['sharp_5fac_7104',['SHARP_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada353a9d71906702ae10aa4f803a04ca68',1,'IRremoteESP8266.h']]], + ['sherwood_7105',['SHERWOOD',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1412522651b0c8f1a35e1db3807466bb',1,'IRremoteESP8266.h']]], + ['sony_7106',['SONY',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada72d58193d4d25517202d22b7e57a65c3',1,'IRremoteESP8266.h']]], + ['sony_5f38k_7107',['SONY_38K',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0027bcfbb78c0c2b951dfff1102a027b',1,'IRremoteESP8266.h']]], + ['symphony_7108',['SYMPHONY',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada44c4a84d776e02328ef3b169e743e5ec',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.html new file mode 100644 index 000000000..737608e10 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.js new file mode 100644 index 000000000..b09800636 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['de_2dch_2eh_3581',['de-CH.h',['../de-CH_8h.html',1,'']]], + ['de_2dde_2eh_3582',['de-DE.h',['../de-DE_8h.html',1,'']]], + ['defaults_2eh_3583',['defaults.h',['../defaults_8h.html',1,'']]], + ['doxygen_5findex_2emd_3584',['doxygen_index.md',['../doxygen__index_8md.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.html new file mode 100644 index 000000000..f27a62dee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.js new file mode 100644 index 000000000..cf4d29ee1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['en_2dau_2eh_3585',['en-AU.h',['../en-AU_8h.html',1,'']]], + ['en_2die_2eh_3586',['en-IE.h',['../en-IE_8h.html',1,'']]], + ['en_2duk_2eh_3587',['en-UK.h',['../en-UK_8h.html',1,'']]], + ['en_2dus_2eh_3588',['en-US.h',['../en-US_8h.html',1,'']]], + ['es_2des_2eh_3589',['es-ES.h',['../es-ES_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.html new file mode 100644 index 000000000..a45066e93 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.js new file mode 100644 index 000000000..67cf50118 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['fr_2dfr_2eh_3590',['fr-FR.h',['../fr-FR_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.html new file mode 100644 index 000000000..1076bc5a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.js new file mode 100644 index 000000000..77fc9aa49 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.js @@ -0,0 +1,104 @@ +var searchData= +[ + ['i18n_2eh_3591',['i18n.h',['../i18n_8h.html',1,'']]], + ['ir_5fairwell_2ecpp_3592',['ir_Airwell.cpp',['../ir__Airwell_8cpp.html',1,'']]], + ['ir_5faiwa_2ecpp_3593',['ir_Aiwa.cpp',['../ir__Aiwa_8cpp.html',1,'']]], + ['ir_5famcor_2ecpp_3594',['ir_Amcor.cpp',['../ir__Amcor_8cpp.html',1,'']]], + ['ir_5famcor_2eh_3595',['ir_Amcor.h',['../ir__Amcor_8h.html',1,'']]], + ['ir_5fargo_2ecpp_3596',['ir_Argo.cpp',['../ir__Argo_8cpp.html',1,'']]], + ['ir_5fargo_2eh_3597',['ir_Argo.h',['../ir__Argo_8h.html',1,'']]], + ['ir_5fcarrier_2ecpp_3598',['ir_Carrier.cpp',['../ir__Carrier_8cpp.html',1,'']]], + ['ir_5fcarrier_2eh_3599',['ir_Carrier.h',['../ir__Carrier_8h.html',1,'']]], + ['ir_5fcoolix_2ecpp_3600',['ir_Coolix.cpp',['../ir__Coolix_8cpp.html',1,'']]], + ['ir_5fcoolix_2eh_3601',['ir_Coolix.h',['../ir__Coolix_8h.html',1,'']]], + ['ir_5fcorona_2ecpp_3602',['ir_Corona.cpp',['../ir__Corona_8cpp.html',1,'']]], + ['ir_5fcorona_2eh_3603',['ir_Corona.h',['../ir__Corona_8h.html',1,'']]], + ['ir_5fdaikin_2ecpp_3604',['ir_Daikin.cpp',['../ir__Daikin_8cpp.html',1,'']]], + ['ir_5fdaikin_2eh_3605',['ir_Daikin.h',['../ir__Daikin_8h.html',1,'']]], + ['ir_5fdelonghi_2ecpp_3606',['ir_Delonghi.cpp',['../ir__Delonghi_8cpp.html',1,'']]], + ['ir_5fdelonghi_2eh_3607',['ir_Delonghi.h',['../ir__Delonghi_8h.html',1,'']]], + ['ir_5fdenon_2ecpp_3608',['ir_Denon.cpp',['../ir__Denon_8cpp.html',1,'']]], + ['ir_5fdish_2ecpp_3609',['ir_Dish.cpp',['../ir__Dish_8cpp.html',1,'']]], + ['ir_5fdoshisha_2ecpp_3610',['ir_Doshisha.cpp',['../ir__Doshisha_8cpp.html',1,'']]], + ['ir_5felectra_2ecpp_3611',['ir_Electra.cpp',['../ir__Electra_8cpp.html',1,'']]], + ['ir_5felectra_2eh_3612',['ir_Electra.h',['../ir__Electra_8h.html',1,'']]], + ['ir_5fepson_2ecpp_3613',['ir_Epson.cpp',['../ir__Epson_8cpp.html',1,'']]], + ['ir_5ffujitsu_2ecpp_3614',['ir_Fujitsu.cpp',['../ir__Fujitsu_8cpp.html',1,'']]], + ['ir_5ffujitsu_2eh_3615',['ir_Fujitsu.h',['../ir__Fujitsu_8h.html',1,'']]], + ['ir_5fgicable_2ecpp_3616',['ir_GICable.cpp',['../ir__GICable_8cpp.html',1,'']]], + ['ir_5fglobalcache_2ecpp_3617',['ir_GlobalCache.cpp',['../ir__GlobalCache_8cpp.html',1,'']]], + ['ir_5fgoodweather_2ecpp_3618',['ir_Goodweather.cpp',['../ir__Goodweather_8cpp.html',1,'']]], + ['ir_5fgoodweather_2eh_3619',['ir_Goodweather.h',['../ir__Goodweather_8h.html',1,'']]], + ['ir_5fgree_2ecpp_3620',['ir_Gree.cpp',['../ir__Gree_8cpp.html',1,'']]], + ['ir_5fgree_2eh_3621',['ir_Gree.h',['../ir__Gree_8h.html',1,'']]], + ['ir_5fhaier_2ecpp_3622',['ir_Haier.cpp',['../ir__Haier_8cpp.html',1,'']]], + ['ir_5fhaier_2eh_3623',['ir_Haier.h',['../ir__Haier_8h.html',1,'']]], + ['ir_5fhitachi_2ecpp_3624',['ir_Hitachi.cpp',['../ir__Hitachi_8cpp.html',1,'']]], + ['ir_5fhitachi_2eh_3625',['ir_Hitachi.h',['../ir__Hitachi_8h.html',1,'']]], + ['ir_5finax_2ecpp_3626',['ir_Inax.cpp',['../ir__Inax_8cpp.html',1,'']]], + ['ir_5fjvc_2ecpp_3627',['ir_JVC.cpp',['../ir__JVC_8cpp.html',1,'']]], + ['ir_5fkelvinator_2ecpp_3628',['ir_Kelvinator.cpp',['../ir__Kelvinator_8cpp.html',1,'']]], + ['ir_5fkelvinator_2eh_3629',['ir_Kelvinator.h',['../ir__Kelvinator_8h.html',1,'']]], + ['ir_5flasertag_2ecpp_3630',['ir_Lasertag.cpp',['../ir__Lasertag_8cpp.html',1,'']]], + ['ir_5flego_2ecpp_3631',['ir_Lego.cpp',['../ir__Lego_8cpp.html',1,'']]], + ['ir_5flg_2ecpp_3632',['ir_LG.cpp',['../ir__LG_8cpp.html',1,'']]], + ['ir_5flg_2eh_3633',['ir_LG.h',['../ir__LG_8h.html',1,'']]], + ['ir_5flutron_2ecpp_3634',['ir_Lutron.cpp',['../ir__Lutron_8cpp.html',1,'']]], + ['ir_5fmagiquest_2ecpp_3635',['ir_Magiquest.cpp',['../ir__Magiquest_8cpp.html',1,'']]], + ['ir_5fmagiquest_2eh_3636',['ir_Magiquest.h',['../ir__Magiquest_8h.html',1,'']]], + ['ir_5fmidea_2ecpp_3637',['ir_Midea.cpp',['../ir__Midea_8cpp.html',1,'']]], + ['ir_5fmidea_2eh_3638',['ir_Midea.h',['../ir__Midea_8h.html',1,'']]], + ['ir_5fmitsubishi_2ecpp_3639',['ir_Mitsubishi.cpp',['../ir__Mitsubishi_8cpp.html',1,'']]], + ['ir_5fmitsubishi_2eh_3640',['ir_Mitsubishi.h',['../ir__Mitsubishi_8h.html',1,'']]], + ['ir_5fmitsubishiheavy_2ecpp_3641',['ir_MitsubishiHeavy.cpp',['../ir__MitsubishiHeavy_8cpp.html',1,'']]], + ['ir_5fmitsubishiheavy_2eh_3642',['ir_MitsubishiHeavy.h',['../ir__MitsubishiHeavy_8h.html',1,'']]], + ['ir_5fmultibrackets_2ecpp_3643',['ir_Multibrackets.cpp',['../ir__Multibrackets_8cpp.html',1,'']]], + ['ir_5fmwm_2ecpp_3644',['ir_MWM.cpp',['../ir__MWM_8cpp.html',1,'']]], + ['ir_5fnec_2ecpp_3645',['ir_NEC.cpp',['../ir__NEC_8cpp.html',1,'']]], + ['ir_5fnec_2eh_3646',['ir_NEC.h',['../ir__NEC_8h.html',1,'']]], + ['ir_5fneoclima_2ecpp_3647',['ir_Neoclima.cpp',['../ir__Neoclima_8cpp.html',1,'']]], + ['ir_5fneoclima_2eh_3648',['ir_Neoclima.h',['../ir__Neoclima_8h.html',1,'']]], + ['ir_5fnikai_2ecpp_3649',['ir_Nikai.cpp',['../ir__Nikai_8cpp.html',1,'']]], + ['ir_5fpanasonic_2ecpp_3650',['ir_Panasonic.cpp',['../ir__Panasonic_8cpp.html',1,'']]], + ['ir_5fpanasonic_2eh_3651',['ir_Panasonic.h',['../ir__Panasonic_8h.html',1,'']]], + ['ir_5fpioneer_2ecpp_3652',['ir_Pioneer.cpp',['../ir__Pioneer_8cpp.html',1,'']]], + ['ir_5fpronto_2ecpp_3653',['ir_Pronto.cpp',['../ir__Pronto_8cpp.html',1,'']]], + ['ir_5frc5_5frc6_2ecpp_3654',['ir_RC5_RC6.cpp',['../ir__RC5__RC6_8cpp.html',1,'']]], + ['ir_5frcmm_2ecpp_3655',['ir_RCMM.cpp',['../ir__RCMM_8cpp.html',1,'']]], + ['ir_5fsamsung_2ecpp_3656',['ir_Samsung.cpp',['../ir__Samsung_8cpp.html',1,'']]], + ['ir_5fsamsung_2eh_3657',['ir_Samsung.h',['../ir__Samsung_8h.html',1,'']]], + ['ir_5fsanyo_2ecpp_3658',['ir_Sanyo.cpp',['../ir__Sanyo_8cpp.html',1,'']]], + ['ir_5fsharp_2ecpp_3659',['ir_Sharp.cpp',['../ir__Sharp_8cpp.html',1,'']]], + ['ir_5fsharp_2eh_3660',['ir_Sharp.h',['../ir__Sharp_8h.html',1,'']]], + ['ir_5fsherwood_2ecpp_3661',['ir_Sherwood.cpp',['../ir__Sherwood_8cpp.html',1,'']]], + ['ir_5fsony_2ecpp_3662',['ir_Sony.cpp',['../ir__Sony_8cpp.html',1,'']]], + ['ir_5fsymphony_2ecpp_3663',['ir_Symphony.cpp',['../ir__Symphony_8cpp.html',1,'']]], + ['ir_5ftcl_2ecpp_3664',['ir_Tcl.cpp',['../ir__Tcl_8cpp.html',1,'']]], + ['ir_5ftcl_2eh_3665',['ir_Tcl.h',['../ir__Tcl_8h.html',1,'']]], + ['ir_5fteco_2ecpp_3666',['ir_Teco.cpp',['../ir__Teco_8cpp.html',1,'']]], + ['ir_5fteco_2eh_3667',['ir_Teco.h',['../ir__Teco_8h.html',1,'']]], + ['ir_5ftoshiba_2ecpp_3668',['ir_Toshiba.cpp',['../ir__Toshiba_8cpp.html',1,'']]], + ['ir_5ftoshiba_2eh_3669',['ir_Toshiba.h',['../ir__Toshiba_8h.html',1,'']]], + ['ir_5ftrotec_2ecpp_3670',['ir_Trotec.cpp',['../ir__Trotec_8cpp.html',1,'']]], + ['ir_5ftrotec_2eh_3671',['ir_Trotec.h',['../ir__Trotec_8h.html',1,'']]], + ['ir_5fvestel_2ecpp_3672',['ir_Vestel.cpp',['../ir__Vestel_8cpp.html',1,'']]], + ['ir_5fvestel_2eh_3673',['ir_Vestel.h',['../ir__Vestel_8h.html',1,'']]], + ['ir_5fwhirlpool_2ecpp_3674',['ir_Whirlpool.cpp',['../ir__Whirlpool_8cpp.html',1,'']]], + ['ir_5fwhirlpool_2eh_3675',['ir_Whirlpool.h',['../ir__Whirlpool_8h.html',1,'']]], + ['ir_5fwhynter_2ecpp_3676',['ir_Whynter.cpp',['../ir__Whynter_8cpp.html',1,'']]], + ['ir_5fzepeal_2ecpp_3677',['ir_Zepeal.cpp',['../ir__Zepeal_8cpp.html',1,'']]], + ['irac_2ecpp_3678',['IRac.cpp',['../IRac_8cpp.html',1,'']]], + ['irac_2eh_3679',['IRac.h',['../IRac_8h.html',1,'']]], + ['irrecv_2ecpp_3680',['IRrecv.cpp',['../IRrecv_8cpp.html',1,'']]], + ['irrecv_2eh_3681',['IRrecv.h',['../IRrecv_8h.html',1,'']]], + ['irremoteesp8266_2eh_3682',['IRremoteESP8266.h',['../IRremoteESP8266_8h.html',1,'']]], + ['irsend_2ecpp_3683',['IRsend.cpp',['../IRsend_8cpp.html',1,'']]], + ['irsend_2eh_3684',['IRsend.h',['../IRsend_8h.html',1,'']]], + ['irtext_2ecpp_3685',['IRtext.cpp',['../IRtext_8cpp.html',1,'']]], + ['irtext_2eh_3686',['IRtext.h',['../IRtext_8h.html',1,'']]], + ['irtimer_2ecpp_3687',['IRtimer.cpp',['../IRtimer_8cpp.html',1,'']]], + ['irtimer_2eh_3688',['IRtimer.h',['../IRtimer_8h.html',1,'']]], + ['irutils_2ecpp_3689',['IRutils.cpp',['../IRutils_8cpp.html',1,'']]], + ['irutils_2eh_3690',['IRutils.h',['../IRutils_8h.html',1,'']]], + ['it_2dit_2eh_3691',['it-IT.h',['../it-IT_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.html new file mode 100644 index 000000000..e5cd7f43a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.js new file mode 100644 index 000000000..7ac14309d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['readme_2emd_3692',['README.md',['../README_8md.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.html new file mode 100644 index 000000000..2cc480f29 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.js new file mode 100644 index 000000000..8fcced443 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['zh_2dcn_2eh_3693',['zh-CN.h',['../zh-CN_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.html new file mode 100644 index 000000000..e17c71111 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.js new file mode 100644 index 000000000..597eca1db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['_5fcancelofftimer_3694',['_cancelOffTimer',['../classIRCarrierAc64.html#a4a0fdf34836b1c954b27c9b242324679',1,'IRCarrierAc64']]], + ['_5fcancelontimer_3695',['_cancelOnTimer',['../classIRCarrierAc64.html#a43e7be5a1a6fe2dbfe245e99d2205779',1,'IRCarrierAc64']]], + ['_5fdelaymicroseconds_3696',['_delayMicroseconds',['../classIRsend.html#a61ceb32aa53f538b93377b10e58b45c9',1,'IRsend']]], + ['_5fgettime_3697',['_getTime',['../classIRPanasonicAc.html#ab0a592b759daf90be548ac69ae99f40f',1,'IRPanasonicAc']]], + ['_5fgettimer_3698',['_getTimer',['../classIRCoronaAc.html#a419053fbf9ef27e937db0ff7519927bd',1,'IRCoronaAc::_getTimer()'],['../classIRVestelAc.html#ad3f095d248ad3c84a777ed9f2d3b001e',1,'IRVestelAc::_getTimer()']]], + ['_5fmatchgeneric_3699',['_matchGeneric',['../classIRrecv.html#af0b300fe6fdff58324525e8208be3024',1,'IRrecv']]], + ['_5fsendsony_3700',['_sendSony',['../classIRsend.html#a21352b4499f976872a74bae36ea10338',1,'IRsend']]], + ['_5fsetmode_3701',['_setMode',['../classIRWhirlpoolAc.html#a60fd8da35d6e0137711e114a5307d664',1,'IRWhirlpoolAc']]], + ['_5fsetpower_3702',['_setPower',['../classIRCoronaAc.html#a4b05b7e34e0f2e66f59ff279c6970478',1,'IRCoronaAc']]], + ['_5fsettemp_3703',['_setTemp',['../classIRLgAc.html#a39aca9861608211c8e74c89a7ccc97cd',1,'IRLgAc::_setTemp()'],['../classIRWhirlpoolAc.html#abb221e09077efd96304f84e8ca130458',1,'IRWhirlpoolAc::_setTemp()']]], + ['_5fsettime_3704',['_setTime',['../classIRPanasonicAc.html#a51e306dd7a3e4d580ed5396fcd166141',1,'IRPanasonicAc']]], + ['_5fsettimer_3705',['_setTimer',['../classIRCoronaAc.html#a0ea9319987de7cb7f3dcb9fbefb60a2c',1,'IRCoronaAc::_setTimer()'],['../classIRVestelAc.html#a726178a16458c84d031aec07355d0dd2',1,'IRVestelAc::_setTimer()']]], + ['_5ftostring_3706',['_toString',['../classIRHitachiAc424.html#af7ab654c4eecf770a70399f6b9959db3',1,'IRHitachiAc424']]], + ['_5fvalidtolerance_3707',['_validTolerance',['../classIRrecv.html#a0b4221970de0d027b5ae99648fa1c003',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.html new file mode 100644 index 000000000..0ddac0a4f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.js new file mode 100644 index 000000000..37bfc00b2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['add_3708',['add',['../classIRtimer.html#aa8e3ff975ae5468b4727790c828fa032',1,'IRtimer::add()'],['../classTimerMs.html#a77bfc23a029a9172c3dbac03f746b0cb',1,'TimerMs::add()']]], + ['addbooltostring_3709',['addBoolToString',['../namespaceirutils.html#a12ba9cf1830a886649a80c3cc5fdce2b',1,'irutils']]], + ['adddaytostring_3710',['addDayToString',['../namespaceirutils.html#a6ead1d10578c64627f8a24b5d8a7444f',1,'irutils']]], + ['addfantostring_3711',['addFanToString',['../namespaceirutils.html#ae023bbabc452173d348c14eac7d86ab4',1,'irutils']]], + ['addinttostring_3712',['addIntToString',['../namespaceirutils.html#a772e623c4b60208200e02afbaec66651',1,'irutils']]], + ['addlabeledstring_3713',['addLabeledString',['../namespaceirutils.html#ac98793392d1e65c1b8d6895eb9d9b75b',1,'irutils']]], + ['addmodeltostring_3714',['addModelToString',['../namespaceirutils.html#a06e5a5c2b6f6649035dfa5eb19801367',1,'irutils']]], + ['addmodetostring_3715',['addModeToString',['../namespaceirutils.html#a8b74ae0258e98aa0eaebc6f3efe1481e',1,'irutils']]], + ['addtemptostring_3716',['addTempToString',['../namespaceirutils.html#a0cef0634f4db979a93b7dc19cc2b4a85',1,'irutils']]], + ['amcor_3717',['amcor',['../classIRac.html#a4bad16621b232572e14fe4a53f678131',1,'IRac']]], + ['argo_3718',['argo',['../classIRac.html#aa06ee1314529dbf96f4e6f3c28ea6821',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.html new file mode 100644 index 000000000..09422e1e5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.js new file mode 100644 index 000000000..9f5b65adc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['recoversavedstate_4090',['recoverSavedState',['../classIRCoolixAC.html#a134cb36681c3fab53074b402bba0a45c',1,'IRCoolixAC']]], + ['reset_4091',['reset',['../classIRtimer.html#aaaf886de2c9533a8c791242dc575db1a',1,'IRtimer::reset()'],['../classTimerMs.html#a25ab025793a4d432e7d4180cbd31157b',1,'TimerMs::reset()']]], + ['resultactostring_4092',['resultAcToString',['../namespaceIRAcUtils.html#ac3d2683bc26edc2bf58916187b5349c3',1,'IRAcUtils']]], + ['resulttohexidecimal_4093',['resultToHexidecimal',['../IRutils_8cpp.html#a25a669d53f231de6152f8e60cedf39f7',1,'resultToHexidecimal(const decode_results *const result): IRutils.cpp'],['../IRutils_8h.html#a25a669d53f231de6152f8e60cedf39f7',1,'resultToHexidecimal(const decode_results *const result): IRutils.cpp']]], + ['resulttohumanreadablebasic_4094',['resultToHumanReadableBasic',['../IRutils_8cpp.html#a0cc6ae1b9649b1ea1d2bfe7e7b03b6d8',1,'resultToHumanReadableBasic(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#a0cc6ae1b9649b1ea1d2bfe7e7b03b6d8',1,'resultToHumanReadableBasic(const decode_results *const results): IRutils.cpp']]], + ['resulttorawarray_4095',['resultToRawArray',['../IRutils_8cpp.html#a7b3bbfa1f2bf2dea2fc40a2fefe05a2a',1,'resultToRawArray(const decode_results *const decode): IRutils.cpp'],['../IRutils_8h.html#a7b3bbfa1f2bf2dea2fc40a2fefe05a2a',1,'resultToRawArray(const decode_results *const decode): IRutils.cpp']]], + ['resulttosourcecode_4096',['resultToSourceCode',['../IRutils_8cpp.html#a10fc00c8b399dddb67a228325e6e2f79',1,'resultToSourceCode(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#a10fc00c8b399dddb67a228325e6e2f79',1,'resultToSourceCode(const decode_results *const results): IRutils.cpp']]], + ['resulttotiminginfo_4097',['resultToTimingInfo',['../IRutils_8cpp.html#afbfdef125ff077431f3abc27a1eeb800',1,'resultToTimingInfo(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#afbfdef125ff077431f3abc27a1eeb800',1,'resultToTimingInfo(const decode_results *const results): IRutils.cpp']]], + ['resume_4098',['resume',['../classIRrecv.html#a6b5beb7348d807d8d98ae929d005510e',1,'IRrecv']]], + ['reversebits_4099',['reverseBits',['../IRutils_8cpp.html#a366219b6f1c46f41c6573b3e5e875e41',1,'reverseBits(uint64_t input, uint16_t nbits): IRutils.cpp'],['../IRutils_8h.html#a366219b6f1c46f41c6573b3e5e875e41',1,'reverseBits(uint64_t input, uint16_t nbits): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.html new file mode 100644 index 000000000..1cde7b49e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.js new file mode 100644 index 000000000..a8ba75f82 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.js @@ -0,0 +1,218 @@ +var searchData= +[ + ['samsung_4100',['samsung',['../classIRac.html#a619c659a11c258ea9623eaa37689ba4c',1,'IRac']]], + ['send_4101',['send',['../classIRAmcorAc.html#a4fa894c01a8baabfeadb39634a850fd9',1,'IRAmcorAc::send()'],['../classIRArgoAC.html#a0e4793a4f6fc537ec1450f5a42206dae',1,'IRArgoAC::send()'],['../classIRCarrierAc64.html#aace8aa2d125c6e80bcdd6d96eac722c2',1,'IRCarrierAc64::send()'],['../classIRCoolixAC.html#aaaa681d6cfcf04d110b913e8bb27a53c',1,'IRCoolixAC::send()'],['../classIRCoronaAc.html#aa0c8a1ef4473a3c7d02e1a04c7678fa6',1,'IRCoronaAc::send()'],['../classIRDaikinESP.html#a9f0d2641b54e97da943fceb0ba3f67eb',1,'IRDaikinESP::send()'],['../classIRDaikin2.html#aae2db88038d8d02617f16588e6a82b64',1,'IRDaikin2::send()'],['../classIRDaikin216.html#ab1061620f838cf7774c16c593b4ada8c',1,'IRDaikin216::send()'],['../classIRDaikin160.html#a0e1c74070c03be02e40fdd05ed56465c',1,'IRDaikin160::send()'],['../classIRDaikin176.html#affd71592fa8ed05816d94edbf94d2c0a',1,'IRDaikin176::send()'],['../classIRDaikin128.html#aae7fec91ad2265e8b0378c6b99379e89',1,'IRDaikin128::send()'],['../classIRDaikin152.html#a205de6821effc077f51d941d369791e4',1,'IRDaikin152::send()'],['../classIRDaikin64.html#a904eec38045d9ddc8a97ab33c8a2ac4d',1,'IRDaikin64::send()'],['../classIRDelonghiAc.html#afba831b6884771b84bab684732e0f4f5',1,'IRDelonghiAc::send()'],['../classIRElectraAc.html#a30170a65de1161e26daeddf694f8afdb',1,'IRElectraAc::send()'],['../classIRFujitsuAC.html#a1f1aa593cc4503d14c0fbea5cd9823a1',1,'IRFujitsuAC::send()'],['../classIRGoodweatherAc.html#abcc3c9d9b0912b09d3c0b0c1affb8cc8',1,'IRGoodweatherAc::send()'],['../classIRGreeAC.html#a9823578040c2d15e2b3e8e3a17a9e220',1,'IRGreeAC::send()'],['../classIRHaierAC.html#a9fe53d04965efca6daf234f20d20eb5a',1,'IRHaierAC::send()'],['../classIRHaierACYRW02.html#a65a5d5840dddac505b009e899a0dada7',1,'IRHaierACYRW02::send()'],['../classIRHitachiAc.html#afc53e562370bbaba8b5dda26a62de427',1,'IRHitachiAc::send()'],['../classIRHitachiAc1.html#aafad51c226066b8697cf00661ef38d99',1,'IRHitachiAc1::send()'],['../classIRHitachiAc424.html#adf15121bb329e1bb061f9e5efb848764',1,'IRHitachiAc424::send()'],['../classIRHitachiAc3.html#ab95fd527a4841c44d6e91c8b4afee8b4',1,'IRHitachiAc3::send()'],['../classIRHitachiAc344.html#ae9b33c0adfc1506b1d9ede1e3285c3e3',1,'IRHitachiAc344::send()'],['../classIRKelvinatorAC.html#aa55fbfefbaca1acf5bc9ba796bea8464',1,'IRKelvinatorAC::send()'],['../classIRLgAc.html#aea85c840161b48f2e8d31e7e6e7da532',1,'IRLgAc::send()'],['../classIRMideaAC.html#af66b9f76ad794450a0a7eace4bb59300',1,'IRMideaAC::send()'],['../classIRMitsubishiAC.html#a2467ad33d88af8f6244e7cd0620e012e',1,'IRMitsubishiAC::send()'],['../classIRMitsubishi136.html#a41295e551acf428e76b9b404af2381ad',1,'IRMitsubishi136::send()'],['../classIRMitsubishi112.html#a8f813da813b1a281654147ada2e63eba',1,'IRMitsubishi112::send()'],['../classIRMitsubishiHeavy152Ac.html#acc53c5c136c6987c420d48bddcf9b2da',1,'IRMitsubishiHeavy152Ac::send()'],['../classIRMitsubishiHeavy88Ac.html#a707cb3ec3e3c18bedeb12205580d5048',1,'IRMitsubishiHeavy88Ac::send()'],['../classIRNeoclimaAc.html#a2220bbb1d928b8f6490cd43b702ef430',1,'IRNeoclimaAc::send()'],['../classIRPanasonicAc.html#a778420ebe52aa6422ba5633ce91676df',1,'IRPanasonicAc::send()'],['../classIRSamsungAc.html#a8128429fcb1828a049784d832cafc9fe',1,'IRSamsungAc::send()'],['../classIRSharpAc.html#a829872744bf9fef51dccd89584ddffe6',1,'IRSharpAc::send()'],['../classIRTcl112Ac.html#a9aa8c67e167a3d241157306d0668ff15',1,'IRTcl112Ac::send()'],['../classIRTecoAc.html#ad5785e93e8c0c95a8618b0e371adaa79',1,'IRTecoAc::send()'],['../classIRToshibaAC.html#a14b155d3a20fb9c127eb7f3fe1fd16cd',1,'IRToshibaAC::send()'],['../classIRTrotecESP.html#add228d50195d7b9b43346a90bf959512',1,'IRTrotecESP::send()'],['../classIRVestelAc.html#a606497754b381e70d13ddef5643c9d0b',1,'IRVestelAc::send()'],['../classIRWhirlpoolAc.html#a0c043b3d7cc993940941351e6c63b5cc',1,'IRWhirlpoolAc::send()'],['../classIRsend.html#a204eedc3ad182fb2f40c42ef58f78cfc',1,'IRsend::send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)'],['../classIRsend.html#ac684c209ea8722f0a377070752df0040',1,'IRsend::send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes)']]], + ['sendac_4102',['sendAc',['../classIRac.html#a0cea80b7bab92c9dc4f18c61f5762130',1,'IRac::sendAc(void)'],['../classIRac.html#aa33c42968acafc5cf479574483f94ea9',1,'IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)'],['../classIRac.html#ad60fbe1488efe2d02307d81b090b3b72',1,'IRac::sendAc(const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)']]], + ['sendairwell_4103',['sendAirwell',['../classIRsend.html#a5b180d3845b45af38a19b72e6fa8e0c0',1,'IRsend']]], + ['sendaiwarct501_4104',['sendAiwaRCT501',['../classIRsend.html#ad39a4b13ad2e8500c95db49265e7c771',1,'IRsend']]], + ['sendamcor_4105',['sendAmcor',['../classIRsend.html#acd64b100eb155f90451d467188a83e92',1,'IRsend']]], + ['sendargo_4106',['sendArgo',['../classIRsend.html#a59668b767e4ad4966fe0bc259c3bd34f',1,'IRsend']]], + ['sendcarrierac_4107',['sendCarrierAC',['../classIRsend.html#a9e859a8b5eaea2e64978c8f93b78d159',1,'IRsend']]], + ['sendcarrierac40_4108',['sendCarrierAC40',['../classIRsend.html#a4342b775777d2ff9371f48aa39ad9b69',1,'IRsend']]], + ['sendcarrierac64_4109',['sendCarrierAC64',['../classIRsend.html#abf755688d87fcef5aee86c6a2c89e7c4',1,'IRsend']]], + ['sendcoolix_4110',['sendCOOLIX',['../classIRsend.html#a088af5f0d76965c61fe5716f7b8f2b61',1,'IRsend']]], + ['sendcoronaac_4111',['sendCoronaAc',['../classIRsend.html#a81f82b8248b324799a48a7685d62aaa5',1,'IRsend']]], + ['senddaikin_4112',['sendDaikin',['../classIRsend.html#a3010546144b5ca3b3c94f5881050dbd0',1,'IRsend']]], + ['senddaikin128_4113',['sendDaikin128',['../classIRsend.html#a72a41a704d48750c144c6467ae9a1430',1,'IRsend']]], + ['senddaikin152_4114',['sendDaikin152',['../classIRsend.html#a4ad420eb86e0ae38b12e983f7eaa912c',1,'IRsend']]], + ['senddaikin160_4115',['sendDaikin160',['../classIRsend.html#ab144a86def38f9f5c98701742683c004',1,'IRsend']]], + ['senddaikin176_4116',['sendDaikin176',['../classIRsend.html#ac4b5bcb95d3aff70b2f84074177e9e92',1,'IRsend']]], + ['senddaikin2_4117',['sendDaikin2',['../classIRsend.html#a34262e579cbb6634459bc09c5b15dfa0',1,'IRsend']]], + ['senddaikin216_4118',['sendDaikin216',['../classIRsend.html#aa99bfdaa71ff5bf088faaa17d304f45d',1,'IRsend']]], + ['senddaikin64_4119',['sendDaikin64',['../classIRsend.html#aa403d2192a6eb57910e6f84695475b27',1,'IRsend']]], + ['senddata_4120',['sendData',['../classIRsend.html#a4f8cd77dab7ce6c406029fe87674858f',1,'IRsend']]], + ['senddelonghiac_4121',['sendDelonghiAc',['../classIRsend.html#a35dc18f9abbffa8da40816a8a9df1093',1,'IRsend']]], + ['senddenon_4122',['sendDenon',['../classIRsend.html#a2618e000bf91cf1585329308a078653a',1,'IRsend']]], + ['senddish_4123',['sendDISH',['../classIRsend.html#ac7a72d61af219d983409911bdc1769b8',1,'IRsend']]], + ['senddoshisha_4124',['sendDoshisha',['../classIRsend.html#a3a9a8247e470975137b37f474bb97639',1,'IRsend']]], + ['sendelectraac_4125',['sendElectraAC',['../classIRsend.html#a52526c4e7bc4402e57ecf81e0047d49c',1,'IRsend']]], + ['sendepson_4126',['sendEpson',['../classIRsend.html#a063168fd82f6a88cca7253b42b9c0b28',1,'IRsend']]], + ['sendextended_4127',['sendExtended',['../classIRSamsungAc.html#a16a8dbd8f3fd34a6e681125b276acfd9',1,'IRSamsungAc']]], + ['sendfujitsuac_4128',['sendFujitsuAC',['../classIRsend.html#a1a3d3f83d0b7a59ff5510b038f658eb6',1,'IRsend']]], + ['sendgc_4129',['sendGC',['../classIRsend.html#acf987a501326d9c945cd8dbeb0806e17',1,'IRsend']]], + ['sendgeneric_4130',['sendGeneric',['../classIRsend.html#a5215fd797dfd490816f31bb99b38c273',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)'],['../classIRsend.html#aaace48306af9c020c18848db1a05e641',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint32_t mesgtime, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)'],['../classIRsend.html#a4f5ad649827692b4b42d15b45c7f684b',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint8_t *dataptr, const uint16_t nbytes, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)']]], + ['sendgicable_4131',['sendGICable',['../classIRsend.html#a61dd16bc150473bbfd998dada72b205f',1,'IRsend']]], + ['sendgoodweather_4132',['sendGoodweather',['../classIRsend.html#a8e2d98ae5c39ee07a61f08facecbaa1e',1,'IRsend']]], + ['sendgree_4133',['sendGree',['../classIRsend.html#aca81ea348ceb6b0c9e62073b57bc0b17',1,'IRsend::sendGree(const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)'],['../classIRsend.html#af788e7d9a2ad2483313434f9b5196753',1,'IRsend::sendGree(const uint8_t data[], const uint16_t nbytes=kGreeStateLength, const uint16_t repeat=kGreeDefaultRepeat)']]], + ['sendhaierac_4134',['sendHaierAC',['../classIRsend.html#a6b4b9144d56dda302f5b321f1c5017ff',1,'IRsend']]], + ['sendhaieracyrw02_4135',['sendHaierACYRW02',['../classIRsend.html#a6aa1c1a6880872c87a46e4e0ead5d9b0',1,'IRsend']]], + ['sendhitachiac_4136',['sendHitachiAC',['../classIRsend.html#a8e6079b8b1b69ad7d7f8d05c492becbe',1,'IRsend']]], + ['sendhitachiac1_4137',['sendHitachiAC1',['../classIRsend.html#a5be9a87ce052e4f056766919247e0b22',1,'IRsend']]], + ['sendhitachiac2_4138',['sendHitachiAC2',['../classIRsend.html#a451b1913608a4ba8c26d9af8c85d16f1',1,'IRsend']]], + ['sendhitachiac3_4139',['sendHitachiAc3',['../classIRsend.html#aec7e67f4292622521b5a0a8cfdd21d84',1,'IRsend']]], + ['sendhitachiac344_4140',['sendHitachiAc344',['../classIRsend.html#a5fb28d54f2832651d992450673d05c01',1,'IRsend']]], + ['sendhitachiac424_4141',['sendHitachiAc424',['../classIRsend.html#a2a9676de30bb868b313cc9c30025f790',1,'IRsend']]], + ['sendinax_4142',['sendInax',['../classIRsend.html#a5fa5ff62276d9d680fb1255cc8b99eec',1,'IRsend']]], + ['sendjvc_4143',['sendJVC',['../classIRsend.html#aaa10c899768a5b4cdb1a7913d06141ca',1,'IRsend']]], + ['sendkelvinator_4144',['sendKelvinator',['../classIRsend.html#a8cba9df982fc91f895196d61d2e65b0e',1,'IRsend']]], + ['sendlasertag_4145',['sendLasertag',['../classIRsend.html#a55a79f9727590044751f291a4df83892',1,'IRsend']]], + ['sendlegopf_4146',['sendLegoPf',['../classIRsend.html#a4e38273aeacf01873a013c02d41a44e4',1,'IRsend']]], + ['sendlg_4147',['sendLG',['../classIRsend.html#a079a84c82f360d6d55fde5c27634f51c',1,'IRsend']]], + ['sendlg2_4148',['sendLG2',['../classIRsend.html#a5b6be1ceac8a4bc4ef55dc12eb060531',1,'IRsend']]], + ['sendlutron_4149',['sendLutron',['../classIRsend.html#a85f2a98255d3af7b7407c082ea7b7c16',1,'IRsend']]], + ['sendmagiquest_4150',['sendMagiQuest',['../classIRsend.html#af1d0e9ec0f735fc5fb9011d4f4cb8327',1,'IRsend']]], + ['sendmanchester_4151',['sendManchester',['../classIRsend.html#a7862231cbb1d50f42996c25e2f05b93e',1,'IRsend']]], + ['sendmanchesterdata_4152',['sendManchesterData',['../classIRsend.html#aa76aa33785827c1278eb57d1c15236f8',1,'IRsend']]], + ['sendmidea_4153',['sendMidea',['../classIRsend.html#a37d91b3a77b36509abdc53e2fec20a67',1,'IRsend']]], + ['sendmidea24_4154',['sendMidea24',['../classIRsend.html#a103d79e8df7954e9ab6284fa9f3daf02',1,'IRsend']]], + ['sendmitsubishi_4155',['sendMitsubishi',['../classIRsend.html#a59e8941a25c5c0bbc839fba5b1a22813',1,'IRsend']]], + ['sendmitsubishi112_4156',['sendMitsubishi112',['../classIRsend.html#a0a55e688c6aad015494168f25eb337b5',1,'IRsend']]], + ['sendmitsubishi136_4157',['sendMitsubishi136',['../classIRsend.html#a988a8b7dda3563977d537d6ac448ebc8',1,'IRsend']]], + ['sendmitsubishi2_4158',['sendMitsubishi2',['../classIRsend.html#ac54e50a6819f5c39e060891f1f6ea0f2',1,'IRsend']]], + ['sendmitsubishiac_4159',['sendMitsubishiAC',['../classIRsend.html#a3600527a82f9f22387c9f16ae51fb06f',1,'IRsend']]], + ['sendmitsubishiheavy152_4160',['sendMitsubishiHeavy152',['../classIRsend.html#ae1cffc4882c63f192c231397d19a4032',1,'IRsend']]], + ['sendmitsubishiheavy88_4161',['sendMitsubishiHeavy88',['../classIRsend.html#afaf4fd0c3dabd1bd6f8fe421294c5063',1,'IRsend']]], + ['sendmultibrackets_4162',['sendMultibrackets',['../classIRsend.html#a9026d42480b85270e560e122b8be3b6c',1,'IRsend']]], + ['sendmwm_4163',['sendMWM',['../classIRsend.html#a98301801daf929ec8ce022987ae394f2',1,'IRsend']]], + ['sendnec_4164',['sendNEC',['../classIRsend.html#a324c9e455c0bae51ebe9bc07e915c043',1,'IRsend']]], + ['sendneoclima_4165',['sendNeoclima',['../classIRsend.html#a71e1b5e780851210465bbf061b9c095b',1,'IRsend']]], + ['sendnikai_4166',['sendNikai',['../classIRsend.html#a693e6616b81509cf27d1345c140acc96',1,'IRsend']]], + ['sendoff_4167',['sendOff',['../classIRSamsungAc.html#a96e2ae87f3ffcf1ad812f256f31e4898',1,'IRSamsungAc']]], + ['sendon_4168',['sendOn',['../classIRSamsungAc.html#a7e6980c829dfd143d4d19abaf5d65678',1,'IRSamsungAc']]], + ['sendpanasonic_4169',['sendPanasonic',['../classIRsend.html#a92192475f89b19cfdf7fd0416a263145',1,'IRsend']]], + ['sendpanasonic64_4170',['sendPanasonic64',['../classIRsend.html#adc4fd287f3546f7ff0b67e177a42b560',1,'IRsend']]], + ['sendpanasonicac_4171',['sendPanasonicAC',['../classIRsend.html#a10a3c387a328dbb11733a251f4db7614',1,'IRsend']]], + ['sendpioneer_4172',['sendPioneer',['../classIRsend.html#a11f099f3768a659d1f996589cea8a313',1,'IRsend']]], + ['sendpronto_4173',['sendPronto',['../classIRsend.html#a0b349351e2ba19f87e6b01cde7e67c49',1,'IRsend']]], + ['sendraw_4174',['sendRaw',['../classIRsend.html#a2b9b84f828918f933bd1764d113b53f8',1,'IRsend']]], + ['sendrc5_4175',['sendRC5',['../classIRsend.html#a2bd2ccb27ecd57e14b36f76d82af308a',1,'IRsend']]], + ['sendrc6_4176',['sendRC6',['../classIRsend.html#a2192a95e0d162f9b1775fc2a47f65c37',1,'IRsend']]], + ['sendrcmm_4177',['sendRCMM',['../classIRsend.html#a3cafe475a58234a0d3aa655a2464be75',1,'IRsend']]], + ['sendsamsung_4178',['sendSAMSUNG',['../classIRsend.html#a5252dd159aad713c099de6728ac56d81',1,'IRsend']]], + ['sendsamsung36_4179',['sendSamsung36',['../classIRsend.html#ab5dcd4ec5ddb0b0351870ddf54e5ba66',1,'IRsend']]], + ['sendsamsungac_4180',['sendSamsungAC',['../classIRsend.html#a2773d251da1d35b964810c8cc4cb438b',1,'IRsend']]], + ['sendsanyolc7461_4181',['sendSanyoLC7461',['../classIRsend.html#aa23e51a97a0ec1907d22623fed6dd223',1,'IRsend']]], + ['sendsharp_4182',['sendSharp',['../classIRsend.html#a801ae78ac5a72116c566c4ac5f99c6bd',1,'IRsend']]], + ['sendsharpac_4183',['sendSharpAc',['../classIRsend.html#a438e4c9d50e62da7d772d8d638728213',1,'IRsend']]], + ['sendsharpraw_4184',['sendSharpRaw',['../classIRsend.html#aa1f12fd537ca8c21c183ee41d17a3afc',1,'IRsend']]], + ['sendsherwood_4185',['sendSherwood',['../classIRsend.html#afb3a89acfb868c92a997a3000e70c6e8',1,'IRsend']]], + ['sendsony_4186',['sendSony',['../classIRsend.html#a02bb64503474a0841c51664cf4668d85',1,'IRsend']]], + ['sendsony38_4187',['sendSony38',['../classIRsend.html#a558442f49b32453f0fb987c29e1ec6d3',1,'IRsend']]], + ['sendsymphony_4188',['sendSymphony',['../classIRsend.html#a1f1d5a30660ab0061f64d559d4916d4e',1,'IRsend']]], + ['sendtcl112ac_4189',['sendTcl112Ac',['../classIRsend.html#a2dedce2841e4a6445a98f03393fce823',1,'IRsend']]], + ['sendteco_4190',['sendTeco',['../classIRsend.html#ac6300f977fe94119813481ba682ce33f',1,'IRsend']]], + ['sendtoshibaac_4191',['sendToshibaAC',['../classIRsend.html#a4ef8e028135536dc1f5a63be85ef7d49',1,'IRsend']]], + ['sendtrotec_4192',['sendTrotec',['../classIRsend.html#a135796327b5db127473f4d198e663c00',1,'IRsend']]], + ['sendvestelac_4193',['sendVestelAc',['../classIRsend.html#a129a40f9d344cb0fadfd4cca53ca6b44',1,'IRsend']]], + ['sendwhirlpoolac_4194',['sendWhirlpoolAC',['../classIRsend.html#aa440a50000a259072f93ad6c0e42ec22',1,'IRsend']]], + ['sendwhynter_4195',['sendWhynter',['../classIRsend.html#a07188366deed3dd902cba80a711cf220',1,'IRsend']]], + ['sendzepeal_4196',['sendZepeal',['../classIRsend.html#a9bcba8bbac41d679b5b930e67d3e1b7f',1,'IRsend']]], + ['serialprintuint64_4197',['serialPrintUint64',['../IRutils_8cpp.html#ad2b0a4b9a1a7fca3d5f5afc14b682433',1,'serialPrintUint64(uint64_t input, uint8_t base): IRutils.cpp'],['../IRutils_8h.html#a315d5f05fb572564025bc9ce9b820243',1,'serialPrintUint64(uint64_t input, uint8_t base=10): IRutils.cpp']]], + ['set3d_4198',['set3D',['../classIRMitsubishiHeavy152Ac.html#ab22654d492a4b0e82efcd0c96fc9bbe3',1,'IRMitsubishiHeavy152Ac::set3D()'],['../classIRMitsubishiHeavy88Ac.html#ae0b7eac743a8de6852722f067e010ba7',1,'IRMitsubishiHeavy88Ac::set3D()']]], + ['set8cheat_4199',['set8CHeat',['../classIRNeoclimaAc.html#a3176c5fe3251bd6a31a3a0ddc2c294be',1,'IRNeoclimaAc']]], + ['setauto_4200',['setAuto',['../classIRVestelAc.html#a2509eed2e0d7b23595bbe6dd7df17d74',1,'IRVestelAc']]], + ['setbeep_4201',['setBeep',['../classIRDaikin2.html#a4c0588887a45403a0a9f2cf95f847889',1,'IRDaikin2::setBeep()'],['../classIRSamsungAc.html#a092ccbea031dd4be747076530117649d',1,'IRSamsungAc::setBeep()']]], + ['setbit_4202',['setBit',['../namespaceirutils.html#a316301577d2ff338bfba6605df2cc46b',1,'irutils::setBit(const uint64_t data, const uint8_t position, const bool on, const uint8_t size)'],['../namespaceirutils.html#a2e9e858b490fa3328b4c5bd01adedb8c',1,'irutils::setBit(const uint8_t data, const uint8_t position, const bool on)'],['../namespaceirutils.html#ac1b3de6e733d9c4d614a8239f5bd3220',1,'irutils::setBit(uint8_t *const data, const uint8_t position, const bool on)'],['../namespaceirutils.html#a86bbcf05c1601712b1d587b87035f09b',1,'irutils::setBit(uint32_t *const data, const uint8_t position, const bool on)'],['../namespaceirutils.html#a9e7814e2274f02df0dac0106c293c487',1,'irutils::setBit(uint64_t *const data, const uint8_t position, const bool on)']]], + ['setbits_4203',['setBits',['../namespaceirutils.html#ab4f5e3eb26e111909ddc93a8b018ba78',1,'irutils::setBits(uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)'],['../namespaceirutils.html#a3fd8b18a76f0ae8f730b4de55fc9486e',1,'irutils::setBits(uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)'],['../namespaceirutils.html#a4dfb0984a9ea38602805987a7845839c',1,'irutils::setBits(uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)']]], + ['setboost_4204',['setBoost',['../classIRDelonghiAc.html#a827d1e43e9252657147226aa3f8e4eb8',1,'IRDelonghiAc']]], + ['setbreeze_4205',['setBreeze',['../classIRSamsungAc.html#a310a73f15a0274fbaf15b981abaae592',1,'IRSamsungAc']]], + ['setbutton_4206',['setButton',['../classIRHaierACYRW02.html#aa0f1561e2446f6231f722581f5bae34d',1,'IRHaierACYRW02::setButton()'],['../classIRHitachiAc424.html#af4ded7ea8aa94271d5135eebd3bb80a8',1,'IRHitachiAc424::setButton()'],['../classIRNeoclimaAc.html#a7e2e6e646411b4f5ea3c1ce1e944581c',1,'IRNeoclimaAc::setButton()']]], + ['setclean_4207',['setClean',['../classIRCoolixAC.html#a0087ac58749ef946632fbb5a8b41fe0d',1,'IRCoolixAC::setClean()'],['../classIRDaikin2.html#a21e09b867710a225d5cf53006f723326',1,'IRDaikin2::setClean()'],['../classIRElectraAc.html#a4aa44fc40196067469dfa8a722e33115',1,'IRElectraAc::setClean()'],['../classIRFujitsuAC.html#a7f6f18ea39bf28717cb65ff348b1b2f5',1,'IRFujitsuAC::setClean()'],['../classIRMitsubishiHeavy152Ac.html#a11678e7eb906414770938f6efce266f1',1,'IRMitsubishiHeavy152Ac::setClean()'],['../classIRMitsubishiHeavy88Ac.html#a65968304e4aaf025dfefc49d5d777cbd',1,'IRMitsubishiHeavy88Ac::setClean()'],['../classIRSamsungAc.html#a911ca57dfb0e6787cba330e8d49b2496',1,'IRSamsungAc::setClean()'],['../classIRSharpAc.html#ace6e7b98496a594031809fe8a535c429',1,'IRSharpAc::setClean()']]], + ['setclock_4208',['setClock',['../classIRDaikin128.html#aa9928ac010ec79ddab4f551eedf2f5d9',1,'IRDaikin128::setClock()'],['../classIRDaikin64.html#a655f1cec5e28f79e5718573678c535ec',1,'IRDaikin64::setClock()'],['../classIRMitsubishiAC.html#a7abe34adf36bdd1a65a17f56ee8af1f6',1,'IRMitsubishiAC::setClock()'],['../classIRPanasonicAc.html#a3f76c6aca94f52c227c2e259512fd101',1,'IRPanasonicAc::setClock()'],['../classIRWhirlpoolAc.html#aab09aae7de733414bf480c3df22b83f8',1,'IRWhirlpoolAc::setClock()']]], + ['setcmd_4209',['setCmd',['../classIRFujitsuAC.html#a7579944c11b3d31bb069303926307617',1,'IRFujitsuAC']]], + ['setcomfort_4210',['setComfort',['../classIRDaikinESP.html#aaa15c0be7ffb8e845a03d193583a58d1',1,'IRDaikinESP::setComfort()'],['../classIRDaikin152.html#a95de2dc0a90fe4212cb60973b9430486',1,'IRDaikin152::setComfort()']]], + ['setcommand_4211',['setCommand',['../classIRGoodweatherAc.html#a4e266f42b7a82c49208e2acc7813e07b',1,'IRGoodweatherAc::setCommand()'],['../classIRHaierAC.html#ade34c951e72a794c2ff7fa0d1595d68f',1,'IRHaierAC::setCommand()'],['../classIRWhirlpoolAc.html#aaea26b1388489dff70a98fde1e6185be',1,'IRWhirlpoolAc::setCommand()']]], + ['setcurrentday_4212',['setCurrentDay',['../classIRDaikinESP.html#a5465b9857fd73b82362f766368717d16',1,'IRDaikinESP']]], + ['setcurrenttime_4213',['setCurrentTime',['../classIRDaikinESP.html#ae6559268982ae0968358a885c7dbba6e',1,'IRDaikinESP::setCurrentTime()'],['../classIRDaikin2.html#a8b32b1b9a87c9b671af6aeedb709d520',1,'IRDaikin2::setCurrentTime()']]], + ['setcurrtime_4214',['setCurrTime',['../classIRHaierAC.html#a53500ebdec058d27396e5906a572fe15',1,'IRHaierAC']]], + ['setdisplay_4215',['setDisplay',['../classIRSamsungAc.html#ad20199bed3a01208ec694b9d4eb7ef98',1,'IRSamsungAc']]], + ['setdisplaytempsource_4216',['setDisplayTempSource',['../classIRGreeAC.html#a1d073c31ea169d0e5cf33c8592982035',1,'IRGreeAC']]], + ['setecono_4217',['setEcono',['../classIRCoronaAc.html#abb5624317fff60674bed410be3a3fa52',1,'IRCoronaAc::setEcono()'],['../classIRDaikinESP.html#a12129aedd6320522a9b6e811e347089c',1,'IRDaikinESP::setEcono()'],['../classIRDaikin2.html#a42a44a6cefa6bf6f45148d39c216ebc0',1,'IRDaikin2::setEcono()'],['../classIRDaikin128.html#a07fb5289ee476e0335fec4845254b7ce',1,'IRDaikin128::setEcono()'],['../classIRDaikin152.html#a8062d16f7aefb7586e3d3bdfea8755b4',1,'IRDaikin152::setEcono()'],['../classIRMitsubishiHeavy152Ac.html#ab3964219ee3c0c5112bb38c892a01784',1,'IRMitsubishiHeavy152Ac::setEcono()'],['../classIRMitsubishiHeavy88Ac.html#a7612448f1cceaa6aeee1697f51adaf43',1,'IRMitsubishiHeavy88Ac::setEcono()'],['../classIRTcl112Ac.html#a48ac7acfa8fed8e9da39907282f4f377',1,'IRTcl112Ac::setEcono()']]], + ['seteconotoggle_4218',['setEconoToggle',['../classIRSharpAc.html#ae3495676b8bffecba5c56fbf1ab9ee4d',1,'IRSharpAc']]], + ['seteye_4219',['setEye',['../classIRDaikin2.html#a5ba8e5d5dd4aba45a90de1d450a7a88b',1,'IRDaikin2::setEye()'],['../classIRNeoclimaAc.html#aaf433cab785db382c55a420e68e7d7ec',1,'IRNeoclimaAc::setEye()']]], + ['seteyeauto_4220',['setEyeAuto',['../classIRDaikin2.html#a975c2fdb261d6d2b6c8e196fbd074899',1,'IRDaikin2']]], + ['setfan_4221',['setFan',['../classIRAmcorAc.html#acf26fc65363e2734e4dc6eb562812553',1,'IRAmcorAc::setFan()'],['../classIRArgoAC.html#a8144f003628e128ec6630aef49ed5cb5',1,'IRArgoAC::setFan()'],['../classIRCarrierAc64.html#a312027468b508e9d38dd9e23ee99f9e4',1,'IRCarrierAc64::setFan()'],['../classIRCoolixAC.html#aff4189cb1000c6db7d88624fbadbe0cb',1,'IRCoolixAC::setFan()'],['../classIRCoronaAc.html#aa4da12502bf85438846bdde56391ee5c',1,'IRCoronaAc::setFan()'],['../classIRDaikinESP.html#a1f191f45e473482a86aad9a1c879e083',1,'IRDaikinESP::setFan()'],['../classIRDaikin2.html#af9f3ddbdd1f1d5d99c84846b73c5daa1',1,'IRDaikin2::setFan()'],['../classIRDaikin216.html#a8fadfb1e61deca74a2d1b9c1d5ae62e1',1,'IRDaikin216::setFan()'],['../classIRDaikin160.html#a7f507c64dc7a9fa1e9391e9e8473af1b',1,'IRDaikin160::setFan()'],['../classIRDaikin176.html#a050a9943dc7d8289472e6b9dbdcb06c1',1,'IRDaikin176::setFan()'],['../classIRDaikin128.html#a0495834250e97e7831e9906ab548fe44',1,'IRDaikin128::setFan()'],['../classIRDaikin152.html#a385a4f65dfccd0a9e94be06ae60c5343',1,'IRDaikin152::setFan()'],['../classIRDaikin64.html#af39206f90b99fd5ee340923b196368b8',1,'IRDaikin64::setFan()'],['../classIRDelonghiAc.html#a440f1e0efa18c6b1a8e18e0a97fbfb79',1,'IRDelonghiAc::setFan()'],['../classIRElectraAc.html#aa338ce18cafaf9c7b9aa3385e681bbe7',1,'IRElectraAc::setFan()'],['../classIRGoodweatherAc.html#af8cf9ba59af548677e586cd59e8a6cc2',1,'IRGoodweatherAc::setFan()'],['../classIRGreeAC.html#a9bb570e71df5002298505d49473e6bac',1,'IRGreeAC::setFan()'],['../classIRHaierAC.html#a42ee1c5889f07bf7615c8f853bca2261',1,'IRHaierAC::setFan()'],['../classIRHaierACYRW02.html#ae9c3a7bffc08d9d5204616823f709889',1,'IRHaierACYRW02::setFan()'],['../classIRHitachiAc.html#a0760b07502b976880ee8499dc6fa61ff',1,'IRHitachiAc::setFan()'],['../classIRHitachiAc1.html#a7294dc1324877d4a64f7b4373d97d745',1,'IRHitachiAc1::setFan()'],['../classIRHitachiAc424.html#afd69bcff56224f39af92fc2d334b67bb',1,'IRHitachiAc424::setFan()'],['../classIRKelvinatorAC.html#af08e94be9699983c0087c9b059aad319',1,'IRKelvinatorAC::setFan()'],['../classIRLgAc.html#a0f1901a21ffb93641d3481417d74bb4e',1,'IRLgAc::setFan()'],['../classIRMideaAC.html#a546eeca4eea015899a5ad9f5d1c6fafb',1,'IRMideaAC::setFan()'],['../classIRMitsubishiAC.html#a4e88e50b2eddd0233aade5c1bf7819f1',1,'IRMitsubishiAC::setFan()'],['../classIRMitsubishi136.html#a2aa62126614f734ec3d1b7b3cb653e9e',1,'IRMitsubishi136::setFan()'],['../classIRMitsubishi112.html#ab681e78572c869a8c57079a660fe1505',1,'IRMitsubishi112::setFan()'],['../classIRMitsubishiHeavy152Ac.html#ac8d8eceba935aa626cb229d1c41081bb',1,'IRMitsubishiHeavy152Ac::setFan()'],['../classIRMitsubishiHeavy88Ac.html#a4f8c934a82091547c36da512329e76d7',1,'IRMitsubishiHeavy88Ac::setFan()'],['../classIRNeoclimaAc.html#a8db9d2d446e8614b2fc4583a454d7cee',1,'IRNeoclimaAc::setFan()'],['../classIRPanasonicAc.html#a8d77292226f55601c30ee53252ba83cd',1,'IRPanasonicAc::setFan()'],['../classIRSamsungAc.html#a6c7571e14fe6629348273a2b49a0a824',1,'IRSamsungAc::setFan()'],['../classIRSharpAc.html#a5138068f8ba4c51939ff3bb14f0aae45',1,'IRSharpAc::setFan()'],['../classIRTcl112Ac.html#a0dab8ad6675c4ec122d0d7e28a557cba',1,'IRTcl112Ac::setFan()'],['../classIRTecoAc.html#afda9a33ca450568f968217bedc9ad7f2',1,'IRTecoAc::setFan()'],['../classIRToshibaAC.html#a020ba3e95c607f52ce091193fc5825fc',1,'IRToshibaAC::setFan()'],['../classIRVestelAc.html#af53dfd0a0372c878b6ba2ca1cfc21ccd',1,'IRVestelAc::setFan()'],['../classIRWhirlpoolAc.html#a8da28ee25fdc91d55a9f6ab5dab3af81',1,'IRWhirlpoolAc::setFan()']]], + ['setfanspeed_4222',['setFanSpeed',['../classIRFujitsuAC.html#af0fc10ec0a606434477cb41c60eb49e5',1,'IRFujitsuAC']]], + ['setfilter_4223',['setFilter',['../classIRFujitsuAC.html#aec0048efe87f60406c76ad6bc3ffbc61',1,'IRFujitsuAC::setFilter()'],['../classIRMitsubishiHeavy152Ac.html#aaf76ac48228d3a7b8490e684407e65b1',1,'IRMitsubishiHeavy152Ac::setFilter()']]], + ['setflap_4224',['setFlap',['../classIRArgoAC.html#a55a6402ffc3fe7fb59775050901416ca',1,'IRArgoAC']]], + ['setfresh_4225',['setFresh',['../classIRNeoclimaAc.html#a6354d8b902ffc1e7c044a61185504404',1,'IRNeoclimaAc']]], + ['setfreshair_4226',['setFreshAir',['../classIRDaikin2.html#a6e0596c7b9f9b43b8d241340ae08e886',1,'IRDaikin2']]], + ['setfreshairhigh_4227',['setFreshAirHigh',['../classIRDaikin2.html#a044471f2298a1942bcc2f859f9459924',1,'IRDaikin2']]], + ['sethealth_4228',['setHealth',['../classIRHaierAC.html#a48c9ae91809d63156eeb3889f2e908f4',1,'IRHaierAC::setHealth()'],['../classIRHaierACYRW02.html#a79673650a2285f029a35ab69edeb0e74',1,'IRHaierACYRW02::setHealth()'],['../classIRTcl112Ac.html#a28ed509977d8642174bc6c9aa97ae1c3',1,'IRTcl112Ac::setHealth()']]], + ['sethold_4229',['setHold',['../classIRNeoclimaAc.html#a2eb4e0a2ff39ceb1b6b571998d91b31e',1,'IRNeoclimaAc']]], + ['sethumid_4230',['setHumid',['../classIRTecoAc.html#a4ab07a7c95f34d3b292926c719aeb303',1,'IRTecoAc']]], + ['setifeel_4231',['setIFeel',['../classIRGreeAC.html#a68a670156a5e0a91a8a3cf9225263e0b',1,'IRGreeAC::setIFeel()'],['../classIRArgoAC.html#ae59f903855961441b676b7f662602554',1,'IRArgoAC::setiFeel()']]], + ['setinvertedstates_4232',['setInvertedStates',['../classIRHitachiAc424.html#ad18528cf83e863b98cb1609eec970ac5',1,'IRHitachiAc424::setInvertedStates()'],['../classIRHitachiAc3.html#af37c710449cd32df4753509749e31cad',1,'IRHitachiAc3::setInvertedStates()']]], + ['setion_4233',['setIon',['../classIRNeoclimaAc.html#a504fc5e371746fda8e7eb7cc0abf137a',1,'IRNeoclimaAc::setIon()'],['../classIRPanasonicAc.html#a5a1c4f5b9eb7a3a1a81a6acd0491c3cd',1,'IRPanasonicAc::setIon()'],['../classIRSamsungAc.html#aeee65ca6d2100635a517077f01053bed',1,'IRSamsungAc::setIon()'],['../classIRSharpAc.html#af6a390362bc5b40eecc6564b16b3379b',1,'IRSharpAc::setIon()'],['../classIRVestelAc.html#acf860da68a15d463dab437a808c9c8c6',1,'IRVestelAc::setIon()']]], + ['setionfilter_4234',['setIonFilter',['../classIRKelvinatorAC.html#a6a219c481ddc21d93028f5c799c25883',1,'IRKelvinatorAC']]], + ['setled_4235',['setLed',['../classIRCoolixAC.html#a3132f99cffa108129dff64a0b68bd614',1,'IRCoolixAC']]], + ['setlight_4236',['setLight',['../classIRDaikin2.html#a7ecadb3335e9b22729a89b4c41456242',1,'IRDaikin2::setLight()'],['../classIRGoodweatherAc.html#a3f149ff426b236ba9f90659a6daf4a9c',1,'IRGoodweatherAc::setLight()'],['../classIRGreeAC.html#a702bbba38e11bb8f3428ee707fc82311',1,'IRGreeAC::setLight()'],['../classIRKelvinatorAC.html#a870890c2bc8510f8f7351ca21db8d855',1,'IRKelvinatorAC::setLight()'],['../classIRNeoclimaAc.html#a1d7a6ec6d319544bee907a23a1d14084',1,'IRNeoclimaAc::setLight()'],['../classIRTcl112Ac.html#a7dec5b0559f996df8a4fc259ab6012e9',1,'IRTcl112Ac::setLight()'],['../classIRTecoAc.html#a25d97c1e7be31d80a4ffad0026e633d7',1,'IRTecoAc::setLight()'],['../classIRWhirlpoolAc.html#a70b4c0467a7747f9cf9e106af1025771',1,'IRWhirlpoolAc::setLight()']]], + ['setlighttoggle_4237',['setLightToggle',['../classIRDaikin128.html#a6361c789141ccecb729c104e71ddcc41',1,'IRDaikin128::setLightToggle()'],['../classIRElectraAc.html#a15373982641e36f4b68258368700be7d',1,'IRElectraAc::setLightToggle()']]], + ['setmax_4238',['setMax',['../classIRAmcorAc.html#a1250c6b106378286d9db013296c9b16f',1,'IRAmcorAc::setMax()'],['../classIRArgoAC.html#a909c1f74e9452d0e19fc3ffd28b1b81b',1,'IRArgoAC::setMax()']]], + ['setmode_4239',['setMode',['../classIRAmcorAc.html#afa9c2d080ed5c4c7bc64eb13a07eab68',1,'IRAmcorAc::setMode()'],['../classIRArgoAC.html#a8575f0ef967b09308ed6a453857e65c7',1,'IRArgoAC::setMode()'],['../classIRCarrierAc64.html#ae462eeec49ff91358f1b9921750ee36d',1,'IRCarrierAc64::setMode()'],['../classIRCoolixAC.html#a5c0094d32aca6a5323f4dc72a03f02e9',1,'IRCoolixAC::setMode()'],['../classIRCoronaAc.html#aedeeedd176c89e5b7b650a4311e712be',1,'IRCoronaAc::setMode()'],['../classIRDaikinESP.html#af0f463201c877d33fa8680053dda7551',1,'IRDaikinESP::setMode()'],['../classIRDaikin2.html#a24ef3b53f22fe3557ed2dbc98a5bc6d2',1,'IRDaikin2::setMode()'],['../classIRDaikin216.html#a1d0dfce75ac95df9125b2cfe7c955080',1,'IRDaikin216::setMode()'],['../classIRDaikin160.html#a48e6fff63fd8b894c649fb495a467faa',1,'IRDaikin160::setMode()'],['../classIRDaikin176.html#a7ce82479f5ae2721baae8119b711c112',1,'IRDaikin176::setMode()'],['../classIRDaikin128.html#a9693e9931449f39253ca9102ac5cbfe9',1,'IRDaikin128::setMode()'],['../classIRDaikin152.html#aad0a46c751b73792282d6614103f57d8',1,'IRDaikin152::setMode()'],['../classIRDaikin64.html#a04dff0d273457a7bc3f3e0e1af4f7cd9',1,'IRDaikin64::setMode()'],['../classIRDelonghiAc.html#a62392c26321f038a84d99d54039bcfae',1,'IRDelonghiAc::setMode()'],['../classIRElectraAc.html#a911b7410fd2f29464c1505e183c04c5d',1,'IRElectraAc::setMode()'],['../classIRFujitsuAC.html#ac125c320f9794aae931bc59ba332a4a8',1,'IRFujitsuAC::setMode()'],['../classIRGoodweatherAc.html#a8eed6b70b7b1c2e8a9620db7462e1fb5',1,'IRGoodweatherAc::setMode()'],['../classIRGreeAC.html#a9d9dbd416e3dc270fcfda620b3bb4fe2',1,'IRGreeAC::setMode()'],['../classIRHaierAC.html#a3ad0317f2fd4f57d8ce61353ab3e48c7',1,'IRHaierAC::setMode()'],['../classIRHaierACYRW02.html#ae762c5f5422b4af612fa00f7c26452ed',1,'IRHaierACYRW02::setMode()'],['../classIRHitachiAc.html#a208f73a42484a1555145b41849e8c51f',1,'IRHitachiAc::setMode()'],['../classIRHitachiAc1.html#a1f3ced601e1131b70f840820ecb3feaa',1,'IRHitachiAc1::setMode()'],['../classIRHitachiAc424.html#a373a51d207674e35e00762b057f73cd5',1,'IRHitachiAc424::setMode()'],['../classIRKelvinatorAC.html#af55cc77892bc960587037c337b90d1bc',1,'IRKelvinatorAC::setMode()'],['../classIRLgAc.html#a5e1b21d9121c6bf6507f615f470b5890',1,'IRLgAc::setMode()'],['../classIRMideaAC.html#a3b92f25a82741ae404e8f9af8dbca3a8',1,'IRMideaAC::setMode()'],['../classIRMitsubishiAC.html#a2b4e2f00ee5a385172b13e8d9858ac0b',1,'IRMitsubishiAC::setMode()'],['../classIRMitsubishi136.html#aaef2ed81bdeb183995e2342c2ca17a8b',1,'IRMitsubishi136::setMode()'],['../classIRMitsubishi112.html#a0c1434e1d8dd513007400042324e868e',1,'IRMitsubishi112::setMode()'],['../classIRMitsubishiHeavy152Ac.html#a5a68388f337d7ba80289359903a1d01d',1,'IRMitsubishiHeavy152Ac::setMode()'],['../classIRMitsubishiHeavy88Ac.html#a1802cc8a382d6161b83f8947137d941d',1,'IRMitsubishiHeavy88Ac::setMode()'],['../classIRNeoclimaAc.html#adabd715c4a2ec34dd88330b97a1f0ecd',1,'IRNeoclimaAc::setMode()'],['../classIRPanasonicAc.html#add025b64e736d5120abeb2564a2849a4',1,'IRPanasonicAc::setMode()'],['../classIRSamsungAc.html#a708d9c6c91d774d6eeadbc0bd7f350af',1,'IRSamsungAc::setMode()'],['../classIRSharpAc.html#ab51c207de90391cb7190e3ec95adc16e',1,'IRSharpAc::setMode()'],['../classIRTcl112Ac.html#a1a050c9b238691ba6d4764beeb788778',1,'IRTcl112Ac::setMode()'],['../classIRTecoAc.html#aba404540b723fa4687a4fda954221130',1,'IRTecoAc::setMode()'],['../classIRToshibaAC.html#aa001cddc464d6cbcc342e5e4c7af13ff',1,'IRToshibaAC::setMode()'],['../classIRTrotecESP.html#a5d34e8d1e1be765e51cbfb6874482997',1,'IRTrotecESP::setMode()'],['../classIRVestelAc.html#a470e14ab5623386c0fa2b02fd15ea1d8',1,'IRVestelAc::setMode()'],['../classIRWhirlpoolAc.html#ab09869929f5cc1fd0cc5dede93bba1c5',1,'IRWhirlpoolAc::setMode()']]], + ['setmodel_4240',['setModel',['../classIRFujitsuAC.html#a5393698000d8becf33ff332b32b97c73',1,'IRFujitsuAC::setModel()'],['../classIRGreeAC.html#a1075a08c30a2de97892e0842cb30e451',1,'IRGreeAC::setModel()'],['../classIRHitachiAc1.html#abb8c2c87e87f9d538f171e842c9d309a',1,'IRHitachiAc1::setModel()'],['../classIRLgAc.html#ae4b8758ecf10bd7e25ed401593692821',1,'IRLgAc::setModel()'],['../classIRPanasonicAc.html#a342531bfea3b05484de84e537bde390c',1,'IRPanasonicAc::setModel()'],['../classIRWhirlpoolAc.html#accfa1660ed792acc3cf48ff60d9570f0',1,'IRWhirlpoolAc::setModel()']]], + ['setmold_4241',['setMold',['../classIRDaikinESP.html#a1616d08c8fd3c628fc45a76c32743ac9',1,'IRDaikinESP::setMold()'],['../classIRDaikin2.html#ad53e046e545f3b6c5418dfbaf58653ca',1,'IRDaikin2::setMold()']]], + ['setnight_4242',['setNight',['../classIRArgoAC.html#a769dd3b538653940e41883848bc1e19c',1,'IRArgoAC::setNight()'],['../classIRMitsubishiHeavy152Ac.html#a6920a1aad327e2f347b09da12f11cf8c',1,'IRMitsubishiHeavy152Ac::setNight()']]], + ['setofftime_4243',['setOffTime',['../classIRDaikin64.html#a46a0b1e2438087ba557494b0b4fce4a5',1,'IRDaikin64']]], + ['setofftimeenabled_4244',['setOffTimeEnabled',['../classIRDaikin64.html#aea59ae39ddd0fc33a6941d0affceae9a',1,'IRDaikin64']]], + ['setofftimer_4245',['setOffTimer',['../classIRCarrierAc64.html#a92b1066e783db1bdffabfdc57699deef',1,'IRCarrierAc64::setOffTimer()'],['../classIRCoronaAc.html#a00f269b6389bf65d1816e80b835aa9b0',1,'IRCoronaAc::setOffTimer()'],['../classIRDaikin128.html#a30ca067676dfde963986e25c84616368',1,'IRDaikin128::setOffTimer()'],['../classIRDelonghiAc.html#a9602c652b10b06c6eeae0e6158c42c68',1,'IRDelonghiAc::setOffTimer()'],['../classIRHaierAC.html#aa16b36aa7ef07628343dbd2dfe5157a2',1,'IRHaierAC::setOffTimer()'],['../classIRHitachiAc1.html#a62e9c7b68e63d1791d79805f2bce99df',1,'IRHitachiAc1::setOffTimer()'],['../classIRPanasonicAc.html#a08e097f40cee6c614ec1a8de716222cf',1,'IRPanasonicAc::setOffTimer()'],['../classIRVestelAc.html#acc61cd785d2f668a86ecefb243d63549',1,'IRVestelAc::setOffTimer()'],['../classIRWhirlpoolAc.html#a69f3555c9b27f3cfd9167ed3239804b8',1,'IRWhirlpoolAc::setOffTimer()']]], + ['setofftimeractive_4246',['setOffTimerActive',['../classIRVestelAc.html#a8a023f5594b446f0c20f66c4ee584d8e',1,'IRVestelAc']]], + ['setofftimerenabled_4247',['setOffTimerEnabled',['../classIRDaikin128.html#aac8a178bdaf7de7a183991e710a9a9d8',1,'IRDaikin128::setOffTimerEnabled()'],['../classIRDelonghiAc.html#a5cf81c9864f3c3728d4dd65e4d9c49c8',1,'IRDelonghiAc::setOffTimerEnabled()']]], + ['setontime_4248',['setOnTime',['../classIRDaikin64.html#aaada482820a90492a933f368fafaebb7',1,'IRDaikin64']]], + ['setontimeenabled_4249',['setOnTimeEnabled',['../classIRDaikin64.html#a8e7a7c1f775f8ddf9d48a96915751c7a',1,'IRDaikin64']]], + ['setontimer_4250',['setOnTimer',['../classIRCarrierAc64.html#a9049a8d91200b878cc2a1b9b80a280ea',1,'IRCarrierAc64::setOnTimer()'],['../classIRCoronaAc.html#aae4142f45cc9c2b3e392b72cb404a2d8',1,'IRCoronaAc::setOnTimer()'],['../classIRDaikin128.html#a21773493eafae741b5716ac569eaf0a8',1,'IRDaikin128::setOnTimer()'],['../classIRDelonghiAc.html#a9a478f463a632893be7c4f5223c188ad',1,'IRDelonghiAc::setOnTimer()'],['../classIRHaierAC.html#aa5e95aa05749f6d35dd31b021fea2f5b',1,'IRHaierAC::setOnTimer()'],['../classIRHitachiAc1.html#a51ed6155f228628942ba08ea2ff5c547',1,'IRHitachiAc1::setOnTimer()'],['../classIRPanasonicAc.html#a51fdaa11e4e3f77189a94007a5acbec2',1,'IRPanasonicAc::setOnTimer()'],['../classIRVestelAc.html#af19bb7704326eb5688f2a2fa08e10ee2',1,'IRVestelAc::setOnTimer()'],['../classIRWhirlpoolAc.html#a1cb0e346e6f40b65b98a768df7fdace8',1,'IRWhirlpoolAc::setOnTimer()']]], + ['setontimeractive_4251',['setOnTimerActive',['../classIRVestelAc.html#a16ef4ecb7c76bef89b6e0ca36746d606',1,'IRVestelAc']]], + ['setontimerenabled_4252',['setOnTimerEnabled',['../classIRDaikin128.html#a07f693fac3de101c91c190e5e70edb57',1,'IRDaikin128::setOnTimerEnabled()'],['../classIRDelonghiAc.html#af6b956c273284e287093260039003362',1,'IRDelonghiAc::setOnTimerEnabled()']]], + ['setoutsidequiet_4253',['setOutsideQuiet',['../classIRFujitsuAC.html#a9a0533cba18739e52014307bf4b1ad07',1,'IRFujitsuAC']]], + ['setpower_4254',['setPower',['../classIRAmcorAc.html#a2ccfb2c2f0feb8a8cea9e10e30035988',1,'IRAmcorAc::setPower()'],['../classIRArgoAC.html#a991f73d84952c1d8ac86c579d1b01785',1,'IRArgoAC::setPower()'],['../classIRCarrierAc64.html#a8acf59cbf3b02381b5188324030b7727',1,'IRCarrierAc64::setPower()'],['../classIRCoolixAC.html#a41dc75b29e7a05eff5f16161cb9b3eeb',1,'IRCoolixAC::setPower()'],['../classIRCoronaAc.html#adc636402b51e0c78c4797aea5f80915d',1,'IRCoronaAc::setPower()'],['../classIRDaikinESP.html#aa0fb65d01bb203d17d923504ddd60984',1,'IRDaikinESP::setPower()'],['../classIRDaikin2.html#a3adfe1a80a702b7098ccd0e18225396e',1,'IRDaikin2::setPower()'],['../classIRDaikin216.html#a130a98bb2422a228977dea8a4e068ace',1,'IRDaikin216::setPower()'],['../classIRDaikin160.html#af1a800ef7494c49a868d01039f5c37e4',1,'IRDaikin160::setPower()'],['../classIRDaikin176.html#a58c755ba53d1f14a51b0c64ff4ef0669',1,'IRDaikin176::setPower()'],['../classIRDaikin152.html#a887f7340b9c3e7933f5d06bc5f59ee91',1,'IRDaikin152::setPower()'],['../classIRDelonghiAc.html#aa1ebbf63aa2331b87b95df9c5bdb41dc',1,'IRDelonghiAc::setPower()'],['../classIRElectraAc.html#abd04ffe9a77a97d4fafbcecd3a7949a4',1,'IRElectraAc::setPower()'],['../classIRFujitsuAC.html#a8d8211f20c8ec299e1fcb588a0846ac2',1,'IRFujitsuAC::setPower()'],['../classIRGoodweatherAc.html#ac49e30082777b10fe9edf6ec7bd76ea5',1,'IRGoodweatherAc::setPower()'],['../classIRGreeAC.html#a16b8c6af038752cd2b416cdcf9e2fb51',1,'IRGreeAC::setPower()'],['../classIRHaierACYRW02.html#a32e4a52cf31b43ad96ff3d8f0f390620',1,'IRHaierACYRW02::setPower()'],['../classIRHitachiAc.html#ad78a7176ded93735a296eefbf75cbc06',1,'IRHitachiAc::setPower()'],['../classIRHitachiAc1.html#a4dd034793018ea58d0cc32e7a47e8f35',1,'IRHitachiAc1::setPower()'],['../classIRHitachiAc424.html#a7b0b2e2c631d1bce2dd4677bb71e79b4',1,'IRHitachiAc424::setPower()'],['../classIRKelvinatorAC.html#a517a0193a9236a28a20d1760d7401efd',1,'IRKelvinatorAC::setPower()'],['../classIRLgAc.html#a175e6482fd1565d43906c527f911b59e',1,'IRLgAc::setPower()'],['../classIRMideaAC.html#ab8341f8d3d553d8b0ed9270cc15fc8ec',1,'IRMideaAC::setPower()'],['../classIRMitsubishiAC.html#a13f26de3c35b01470176b6fd9efda566',1,'IRMitsubishiAC::setPower()'],['../classIRMitsubishi136.html#a4bf52b3784faaca95ff97a09b8be322a',1,'IRMitsubishi136::setPower()'],['../classIRMitsubishi112.html#a0545da32a5048bc9d857ffb05767d3a6',1,'IRMitsubishi112::setPower()'],['../classIRMitsubishiHeavy152Ac.html#a08202752226ff3295eb8ccd637b0158b',1,'IRMitsubishiHeavy152Ac::setPower()'],['../classIRMitsubishiHeavy88Ac.html#ac2ee9dd82e84a3735e8a0c69e64cb02e',1,'IRMitsubishiHeavy88Ac::setPower()'],['../classIRNeoclimaAc.html#ac19bea3b79cdfc868bd137b0a70c0718',1,'IRNeoclimaAc::setPower()'],['../classIRPanasonicAc.html#ad60bf8a88d041f8e8ab3d728831ee8f3',1,'IRPanasonicAc::setPower()'],['../classIRSamsungAc.html#a4af21fa0dcbf5595386f67db676a443c',1,'IRSamsungAc::setPower()'],['../classIRSharpAc.html#a6b57a66878f125f86d2aed8bd7545000',1,'IRSharpAc::setPower()'],['../classIRTcl112Ac.html#ad2367d2481f94f14b9c4f7b378711b7e',1,'IRTcl112Ac::setPower()'],['../classIRTecoAc.html#a989e48a889b36ec36386a532c81872d9',1,'IRTecoAc::setPower()'],['../classIRToshibaAC.html#a100f01c014582e162f9fd287beb91dff',1,'IRToshibaAC::setPower()'],['../classIRTrotecESP.html#a0f3f5f5db367cb5a9adb936fada94fd5',1,'IRTrotecESP::setPower()'],['../classIRVestelAc.html#a01e06ff3916d4a14f9ca49f22918a47b',1,'IRVestelAc::setPower()']]], + ['setpowerbutton_4255',['setPowerButton',['../classIRCoronaAc.html#a518471d42a62863953c97334cad348be',1,'IRCoronaAc']]], + ['setpowerful_4256',['setPowerful',['../classIRDaikinESP.html#a4c0da54ee1639a3bf813cb3f3afee064',1,'IRDaikinESP::setPowerful()'],['../classIRDaikin2.html#a6538104cdcf1b55e480aaddd51116d9a',1,'IRDaikin2::setPowerful()'],['../classIRDaikin216.html#a5cb6e958f3b9789828738defe4d12c7b',1,'IRDaikin216::setPowerful()'],['../classIRDaikin128.html#aeb3aa5013b1746ed714146ca7f233119',1,'IRDaikin128::setPowerful()'],['../classIRDaikin152.html#a6477111b5662146e937c10cf02423e10',1,'IRDaikin152::setPowerful()'],['../classIRPanasonicAc.html#a6357688bc9cca92ab222343ee045f4f4',1,'IRPanasonicAc::setPowerful()'],['../classIRSamsungAc.html#ab657b79740e0f84c09611ea3b10d06f0',1,'IRSamsungAc::setPowerful()']]], + ['setpowerspecial_4257',['setPowerSpecial',['../classIRSharpAc.html#af7dd64c6d82a8502d2ee176f7b0f5abb',1,'IRSharpAc']]], + ['setpowertoggle_4258',['setPowerToggle',['../classIRDaikin128.html#a5d7edaa44f0c9ca55ef1040dd42e42e3',1,'IRDaikin128::setPowerToggle()'],['../classIRDaikin64.html#ac7f673619842d217d4eda893da2f35fd',1,'IRDaikin64::setPowerToggle()'],['../classIRHitachiAc1.html#ae30430edd92ec4b848c8a105a78e8068',1,'IRHitachiAc1::setPowerToggle()'],['../classIRWhirlpoolAc.html#a61bec25edce5bc244acb41f79df561e7',1,'IRWhirlpoolAc::setPowerToggle()']]], + ['setpurify_4259',['setPurify',['../classIRDaikin2.html#accd4430e998a8c9be80b5a708be9337e',1,'IRDaikin2']]], + ['setquiet_4260',['setQuiet',['../classIRDaikinESP.html#a4927eb8b2db2540efa90b37f4c3cc733',1,'IRDaikinESP::setQuiet()'],['../classIRDaikin2.html#a61ca7e72f850d0f9600fa9d8a336a8ef',1,'IRDaikin2::setQuiet()'],['../classIRDaikin216.html#a062528f54412cd3d2339c7bf82305ebb',1,'IRDaikin216::setQuiet()'],['../classIRDaikin128.html#a89c49332006831debbabbfcb5ec30249',1,'IRDaikin128::setQuiet()'],['../classIRDaikin152.html#a3aadf5f0ae11c5c6c53f351dd6b9c1a4',1,'IRDaikin152::setQuiet()'],['../classIRDaikin64.html#a7e3fb8debcefb76e76dda5612e28f377',1,'IRDaikin64::setQuiet()'],['../classIRKelvinatorAC.html#a2a3ca238649c55cd4f6f92f48eddf9ac',1,'IRKelvinatorAC::setQuiet()'],['../classIRMitsubishi136.html#a70c8a44f93e90ba025a8909c004c3a7b',1,'IRMitsubishi136::setQuiet()'],['../classIRMitsubishi112.html#a9fbbfb7bb1f6cccfcdcfbc4dcc335169',1,'IRMitsubishi112::setQuiet()'],['../classIRPanasonicAc.html#a51b6ae49cb490f697adeaf7f9f466518',1,'IRPanasonicAc::setQuiet()'],['../classIRSamsungAc.html#a6b3dd7d83c613a06f3499f1c8b26a67b',1,'IRSamsungAc::setQuiet()']]], + ['setraw_4261',['setRaw',['../classIRAmcorAc.html#ac0520033d7a59c817ca8ec08462fe39b',1,'IRAmcorAc::setRaw()'],['../classIRArgoAC.html#a98db56256eb71bf2e8da419007145e2b',1,'IRArgoAC::setRaw()'],['../classIRCarrierAc64.html#af49cf0b53bf8ff946a63bae94be0251d',1,'IRCarrierAc64::setRaw()'],['../classIRCoolixAC.html#aed28d08743c529a5715331255a8d5507',1,'IRCoolixAC::setRaw()'],['../classIRCoronaAc.html#a9ccf78675a3c175209c8d0ef08e2e671',1,'IRCoronaAc::setRaw()'],['../classIRDaikinESP.html#a7c69fc77ead837e5b4f1ececd9f43ca9',1,'IRDaikinESP::setRaw()'],['../classIRDaikin2.html#a132001e73eb5744a3a174c5517c9bbda',1,'IRDaikin2::setRaw()'],['../classIRDaikin216.html#a49f6a2ffc2e76ec4ff020e773bd70160',1,'IRDaikin216::setRaw()'],['../classIRDaikin160.html#a22e8a1600f612dd4326b2f9722d3a269',1,'IRDaikin160::setRaw()'],['../classIRDaikin176.html#a51e5f74b532eca958c09998727064e8d',1,'IRDaikin176::setRaw()'],['../classIRDaikin128.html#a25db29e01def45e8850ac9da68aa7ea7',1,'IRDaikin128::setRaw()'],['../classIRDaikin152.html#aab10e030ebe66e44607e9f35af1eb4cb',1,'IRDaikin152::setRaw()'],['../classIRDaikin64.html#a5f081026aca2bccc6fdeef8199e80779',1,'IRDaikin64::setRaw()'],['../classIRDelonghiAc.html#a219bafa7839f10acca33526cf585152a',1,'IRDelonghiAc::setRaw()'],['../classIRElectraAc.html#ae57c51cd3f5d1ebfb2fe7b926d149dd6',1,'IRElectraAc::setRaw()'],['../classIRFujitsuAC.html#a9b89d756948affa7029eeeed51916cbb',1,'IRFujitsuAC::setRaw()'],['../classIRGoodweatherAc.html#a2eae4bbdb14fea9e3004d656f852df59',1,'IRGoodweatherAc::setRaw()'],['../classIRGreeAC.html#a588f526f2f5500c7c2933ca91ccaf865',1,'IRGreeAC::setRaw()'],['../classIRHaierAC.html#a152961e20b5a5bed2ea03cbc65d65ce9',1,'IRHaierAC::setRaw()'],['../classIRHaierACYRW02.html#a389e711e128533c409731d2c87868c85',1,'IRHaierACYRW02::setRaw()'],['../classIRHitachiAc.html#a3b67215c162ef508c68c49b621c5199b',1,'IRHitachiAc::setRaw()'],['../classIRHitachiAc1.html#ae2d40bc477e30ee574f5c5e2ba4e09c2',1,'IRHitachiAc1::setRaw()'],['../classIRHitachiAc424.html#adc24b8b984ff20cebdf81f65843bb283',1,'IRHitachiAc424::setRaw()'],['../classIRHitachiAc3.html#acff4faf79a30df7b7e7c183dec4153a7',1,'IRHitachiAc3::setRaw()'],['../classIRHitachiAc344.html#a31c8984cfea8364734da6f32fe9a2337',1,'IRHitachiAc344::setRaw()'],['../classIRKelvinatorAC.html#a4a32bbf1a7ee8a089ea1e4e7c750433b',1,'IRKelvinatorAC::setRaw()'],['../classIRLgAc.html#a0da8ea4946826736f526386dc4d115cc',1,'IRLgAc::setRaw()'],['../classIRMideaAC.html#ab24da22531f5b2823551501642ec1b94',1,'IRMideaAC::setRaw()'],['../classIRMitsubishiAC.html#ac7bb79f91d5a9296c2b2b74aae1bfb53',1,'IRMitsubishiAC::setRaw()'],['../classIRMitsubishi136.html#abf0487a6fb163bf896e09b2cae6ee939',1,'IRMitsubishi136::setRaw()'],['../classIRMitsubishi112.html#a5c82f92d4a1ba1477ae7738ed5ade368',1,'IRMitsubishi112::setRaw()'],['../classIRMitsubishiHeavy152Ac.html#a8d42a2d87bf889ab4b233ea0c239f4c2',1,'IRMitsubishiHeavy152Ac::setRaw()'],['../classIRMitsubishiHeavy88Ac.html#abf01e448da9ec6e3b4512f58c3020299',1,'IRMitsubishiHeavy88Ac::setRaw()'],['../classIRNeoclimaAc.html#a607ea7df35572578ef86da7f505ab407',1,'IRNeoclimaAc::setRaw()'],['../classIRPanasonicAc.html#a63308883e8447aa5cdf7d29107be220f',1,'IRPanasonicAc::setRaw()'],['../classIRSamsungAc.html#a95377e8c73b51e73e78b51a2b2fa16d4',1,'IRSamsungAc::setRaw()'],['../classIRSharpAc.html#a89b18c4ee29afa56ebed5fa32e578df7',1,'IRSharpAc::setRaw()'],['../classIRTcl112Ac.html#a5b0994f37df6846137b564eeb322f21b',1,'IRTcl112Ac::setRaw()'],['../classIRTecoAc.html#a1ef3423214f55a2e2695cc1180f94bcc',1,'IRTecoAc::setRaw()'],['../classIRToshibaAC.html#ae74ff9241303eb4c7f3593f73e781c73',1,'IRToshibaAC::setRaw()'],['../classIRTrotecESP.html#a4ffe5ee2559828a61af710bb7d892b6c',1,'IRTrotecESP::setRaw()'],['../classIRVestelAc.html#a617bf1f4b5596d5ad005237e8445c12e',1,'IRVestelAc::setRaw(const uint8_t *newState)'],['../classIRVestelAc.html#a5cc86216d33f228c0648d6c66526b0eb',1,'IRVestelAc::setRaw(const uint64_t newState)'],['../classIRWhirlpoolAc.html#afa9c66ea36c970f80c88a0489448ab5b',1,'IRWhirlpoolAc::setRaw()']]], + ['setroomtemp_4262',['setRoomTemp',['../classIRArgoAC.html#aec5a2edc6f414aab201a18defaa78c5b',1,'IRArgoAC']]], + ['setsave_4263',['setSave',['../classIRTecoAc.html#a0f7d203d44d4040be3a4b28fcd5dd34c',1,'IRTecoAc']]], + ['setsensor_4264',['setSensor',['../classIRDaikinESP.html#ae1c95533934fffb29eed3e9a27e8f636',1,'IRDaikinESP::setSensor()'],['../classIRDaikin152.html#af418dbf2bb79dab0193801167dfb5b78',1,'IRDaikin152::setSensor()']]], + ['setsensortemp_4265',['setSensorTemp',['../classIRCoolixAC.html#a05e660b2b61b9a312e29688289f4bf3e',1,'IRCoolixAC']]], + ['setsensortempraw_4266',['setSensorTempRaw',['../classIRCoolixAC.html#a425c3f5fb26330266156c133fb9104eb',1,'IRCoolixAC']]], + ['setsilent_4267',['setSilent',['../classIRMitsubishiHeavy152Ac.html#ab398b9ea2965f059903137ab088791c0',1,'IRMitsubishiHeavy152Ac']]], + ['setsleep_4268',['setSleep',['../classIRCarrierAc64.html#aa729dbef39afeeed8e83f26b927d3b21',1,'IRCarrierAc64::setSleep()'],['../classIRCoolixAC.html#a4ee44167eca3fc88115fef3e845a3768',1,'IRCoolixAC::setSleep()'],['../classIRDaikin128.html#ac43854ae557ec5582f2bfd9150fd57f2',1,'IRDaikin128::setSleep()'],['../classIRDaikin64.html#a7faf8e018179fed2b091a78d0d69a9b8',1,'IRDaikin64::setSleep()'],['../classIRDelonghiAc.html#aa74806e520b2b01a5b0c87ee32ce427e',1,'IRDelonghiAc::setSleep()'],['../classIRGoodweatherAc.html#a30987629a159c5112649f0973895c9c1',1,'IRGoodweatherAc::setSleep()'],['../classIRGreeAC.html#ac9c11817d15bc5c82732a901cd95e07c',1,'IRGreeAC::setSleep()'],['../classIRHaierAC.html#acb72b89fa53b565f9d32db4d8960f988',1,'IRHaierAC::setSleep()'],['../classIRHaierACYRW02.html#ad63834eb1a91ed974af988c385570457',1,'IRHaierACYRW02::setSleep()'],['../classIRHitachiAc1.html#a2ddb6a5d446b379884828e81df0806ee',1,'IRHitachiAc1::setSleep()'],['../classIRMideaAC.html#a1e008ff673450060bf39a65f1cb926e6',1,'IRMideaAC::setSleep()'],['../classIRNeoclimaAc.html#ad01a62fb369c6894333adb2fe0f52b79',1,'IRNeoclimaAc::setSleep()'],['../classIRTecoAc.html#a1e989a4fbd21c507ba13014b1e336ce2',1,'IRTecoAc::setSleep()'],['../classIRTrotecESP.html#a41c558c6937e61e77269139f96135420',1,'IRTrotecESP::setSleep()'],['../classIRVestelAc.html#a4b93d5585b7fb9d509e7fcf84e2b4abc',1,'IRVestelAc::setSleep()'],['../classIRWhirlpoolAc.html#a6eaa24abc9eac64d9cbe79205a239474',1,'IRWhirlpoolAc::setSleep()']]], + ['setspecial_4269',['setSpecial',['../classIRSharpAc.html#ad7d2eca8b863569a1b17fdca4930d84f',1,'IRSharpAc']]], + ['setspeed_4270',['setSpeed',['../classIRTrotecESP.html#a268146141ce0358c2353c0ff59cfbad3',1,'IRTrotecESP']]], + ['setstartclock_4271',['setStartClock',['../classIRMitsubishiAC.html#a22d8c0dfd8098cb274d915476ed4caae',1,'IRMitsubishiAC']]], + ['setstopclock_4272',['setStopClock',['../classIRMitsubishiAC.html#a228dafbf1ea3e9c3487506a5ca2ea274',1,'IRMitsubishiAC']]], + ['setsuper_4273',['setSuper',['../classIRWhirlpoolAc.html#a19a14674b0bae79d3aee81b8d48aacc7',1,'IRWhirlpoolAc']]], + ['setswing_4274',['setSwing',['../classIRCoolixAC.html#a57e3641e20f072df238b305045e74246',1,'IRCoolixAC::setSwing()'],['../classIRFujitsuAC.html#a60ab8f21b5561e94a322b72a606468b9',1,'IRFujitsuAC::setSwing()'],['../classIRGoodweatherAc.html#a4d11a6885a5e7851e7c941b559159c35',1,'IRGoodweatherAc::setSwing()'],['../classIRHaierAC.html#a28c8bf6e0f45e074bf5eb13c25805627',1,'IRHaierAC::setSwing()'],['../classIRHaierACYRW02.html#ab9152dd09dec2db522dd96778f3b1556',1,'IRHaierACYRW02::setSwing()'],['../classIRSamsungAc.html#aaa7aaca1134e1565f527fcaa96a2fa6e',1,'IRSamsungAc::setSwing()'],['../classIRTecoAc.html#aaaeb10176c0b73e72fdb63b53fdcd5d0',1,'IRTecoAc::setSwing()'],['../classIRVestelAc.html#a6c98427df6e5e8081a6dcbfcd436ff0d',1,'IRVestelAc::setSwing()'],['../classIRWhirlpoolAc.html#a6fec80710ba87599840e576f37e0c944',1,'IRWhirlpoolAc::setSwing()']]], + ['setswingh_4275',['setSwingH',['../classIRElectraAc.html#afcd40681003d57b4f1b652175fc276a8',1,'IRElectraAc::setSwingH()'],['../classIRHitachiAc1.html#af6cc42d52dfed89e23d3d180e7b69af9',1,'IRHitachiAc1::setSwingH()'],['../classIRHitachiAc344.html#a5651cb90ba9b87ef841f8987bad267d4',1,'IRHitachiAc344::setSwingH()'],['../classIRMitsubishi112.html#a99f97b04ac22a7942ea371f470faaf49',1,'IRMitsubishi112::setSwingH()'],['../classIRNeoclimaAc.html#a1aeebc60d7bbd0fb801ad88f639cb6a0',1,'IRNeoclimaAc::setSwingH()']]], + ['setswinghorizontal_4276',['setSwingHorizontal',['../classIRDaikinESP.html#a5a7ec7b00811138879c636b03ae58606',1,'IRDaikinESP::setSwingHorizontal()'],['../classIRDaikin2.html#a75b6d6fb5bab0a9c951ad35e3e1d07c5',1,'IRDaikin2::setSwingHorizontal()'],['../classIRDaikin216.html#af8a1525cbe8d813c419d17ee6776a7d9',1,'IRDaikin216::setSwingHorizontal()'],['../classIRDaikin176.html#a9e63cf22410ffad45f6b308674079ee8',1,'IRDaikin176::setSwingHorizontal()'],['../classIRHitachiAc.html#ae70600f4a6f9fd7579221b11cd73062f',1,'IRHitachiAc::setSwingHorizontal()'],['../classIRKelvinatorAC.html#a2f1731f71bc74fb7ad6fec1210ecb1c7',1,'IRKelvinatorAC::setSwingHorizontal()'],['../classIRMitsubishiHeavy152Ac.html#a8713144e057424809292494a663dcd22',1,'IRMitsubishiHeavy152Ac::setSwingHorizontal()'],['../classIRMitsubishiHeavy88Ac.html#aaceffdd4e631fb2d4c404de0c8ff8cdb',1,'IRMitsubishiHeavy88Ac::setSwingHorizontal()'],['../classIRPanasonicAc.html#a32f3f07813165a39359887485dd87254',1,'IRPanasonicAc::setSwingHorizontal()'],['../classIRTcl112Ac.html#aedc63c59a924d64048bc034a752ce7ed',1,'IRTcl112Ac::setSwingHorizontal()']]], + ['setswingtoggle_4277',['setSwingToggle',['../classIRHitachiAc1.html#a24ec128b6bb27cfc4be4dda9ece003d6',1,'IRHitachiAc1::setSwingToggle()'],['../classIRSharpAc.html#a0d397009ecf213111207fcebb12b95fb',1,'IRSharpAc::setSwingToggle()']]], + ['setswingv_4278',['setSwingV',['../classIRCarrierAc64.html#a61a3f9f29cabc0634a9a74fc2227d8c5',1,'IRCarrierAc64::setSwingV()'],['../classIRDaikin152.html#ad151bb85529d46f7e3e3e65dbf446ff0',1,'IRDaikin152::setSwingV()'],['../classIRElectraAc.html#ae5b33942670e0033cbb9b9c7a1524e93',1,'IRElectraAc::setSwingV()'],['../classIRHitachiAc1.html#a1bcc61a9a33a3ddec41d44d52e7df0d3',1,'IRHitachiAc1::setSwingV()'],['../classIRHitachiAc344.html#a3982f110de8ff9881cf4070902294285',1,'IRHitachiAc344::setSwingV()'],['../classIRMitsubishi136.html#a0d54bc6dd55da18b05f723a1b61e575e',1,'IRMitsubishi136::setSwingV()'],['../classIRMitsubishi112.html#ae33b469f1b67616f101f4a3df874fb78',1,'IRMitsubishi112::setSwingV()'],['../classIRNeoclimaAc.html#aa6e5f6f092f52c5c289642c9576c8bc0',1,'IRNeoclimaAc::setSwingV()']]], + ['setswingvertical_4279',['setSwingVertical',['../classIRDaikinESP.html#a9200ef5751df5d488d7e08b138ec6356',1,'IRDaikinESP::setSwingVertical()'],['../classIRDaikin2.html#a35e72dc8e7967ee8ca8e84a6344468f3',1,'IRDaikin2::setSwingVertical()'],['../classIRDaikin216.html#a851484d5a37ceb1b0fc32e2e4bc2bcbb',1,'IRDaikin216::setSwingVertical()'],['../classIRDaikin160.html#a1683a255393f233d3e5b46d186d62881',1,'IRDaikin160::setSwingVertical()'],['../classIRDaikin128.html#a961aceb41145001003a50c5988f04c4d',1,'IRDaikin128::setSwingVertical()'],['../classIRDaikin64.html#afca186067111fa7181916a218c2800ec',1,'IRDaikin64::setSwingVertical()'],['../classIRGreeAC.html#a1b571dea8a5bf553554e45074f3a01c0',1,'IRGreeAC::setSwingVertical()'],['../classIRHitachiAc.html#a7e3ee78e4835fe402095b544c1e52f9f',1,'IRHitachiAc::setSwingVertical()'],['../classIRKelvinatorAC.html#a7334fbf8f2a67b33562ecea6b6e66f0e',1,'IRKelvinatorAC::setSwingVertical()'],['../classIRMitsubishiHeavy152Ac.html#aea3ac937feff058feef321bfe7357145',1,'IRMitsubishiHeavy152Ac::setSwingVertical()'],['../classIRMitsubishiHeavy88Ac.html#a9406e1890483703afb7b383e1363f8ec',1,'IRMitsubishiHeavy88Ac::setSwingVertical()'],['../classIRPanasonicAc.html#a48f31b1f85c92fac22f85a1aa8074c6e',1,'IRPanasonicAc::setSwingVertical()'],['../classIRTcl112Ac.html#a53f702dcc66de81f6e7e03d538a6946d',1,'IRTcl112Ac::setSwingVertical()']]], + ['setswingvtoggle_4280',['setSwingVToggle',['../classIRCoronaAc.html#a7cb31da86353ec637239cb747890bd7b',1,'IRCoronaAc::setSwingVToggle()'],['../classIRHitachiAc424.html#a220fd85bd213dd13ee9c609d4d7d20c1',1,'IRHitachiAc424::setSwingVToggle()'],['../classIRMideaAC.html#a7fce182bff4f5bc2c6679b20f344837b',1,'IRMideaAC::setSwingVToggle()']]], + ['settemp_4281',['setTemp',['../classIRAmcorAc.html#af4b2c476b76534687f14e9be963e9522',1,'IRAmcorAc::setTemp()'],['../classIRArgoAC.html#abad424a3cf1894715baa03780fa9b53b',1,'IRArgoAC::setTemp()'],['../classIRCarrierAc64.html#a79e193514ac6d07be537a78887426311',1,'IRCarrierAc64::setTemp()'],['../classIRCoolixAC.html#a1d4b4fb810b9f3835ee585b2aa66088f',1,'IRCoolixAC::setTemp()'],['../classIRCoronaAc.html#a9b1d5223cbb6ae6ba07f32871b27d9c6',1,'IRCoronaAc::setTemp()'],['../classIRDaikinESP.html#a631db8830684b745711667aed73a6433',1,'IRDaikinESP::setTemp()'],['../classIRDaikin2.html#a7f752c785fe180d5038e35bb07ff965a',1,'IRDaikin2::setTemp()'],['../classIRDaikin216.html#a8735732d3264eec119127d4353990669',1,'IRDaikin216::setTemp()'],['../classIRDaikin160.html#abedd99ed838478a7ef856537c6fabb82',1,'IRDaikin160::setTemp()'],['../classIRDaikin176.html#acb3b296f4c87a5a37258c666ef886ff3',1,'IRDaikin176::setTemp()'],['../classIRDaikin128.html#aba143a1b80e6de7d1c7b987eeda6b0db',1,'IRDaikin128::setTemp()'],['../classIRDaikin152.html#a97567ade1c0262b3f95f23f171936d8c',1,'IRDaikin152::setTemp()'],['../classIRDaikin64.html#adb1eb657998c05a143365755da0a1e81',1,'IRDaikin64::setTemp()'],['../classIRDelonghiAc.html#a08cc3e32c50277e3f986ed2c3945ce0d',1,'IRDelonghiAc::setTemp()'],['../classIRElectraAc.html#a5f986d9a376b6d5348fcb021d66d235b',1,'IRElectraAc::setTemp()'],['../classIRFujitsuAC.html#ab56c02fc0311ee7f28e780948cbc6a75',1,'IRFujitsuAC::setTemp()'],['../classIRGoodweatherAc.html#a8b1c90f69a3a2e412020d07809d180cc',1,'IRGoodweatherAc::setTemp()'],['../classIRGreeAC.html#a1890c6d134183beb89b791ec565623bb',1,'IRGreeAC::setTemp()'],['../classIRHaierAC.html#a9fb2a375cc1b8692fe4d5dcdd765cc46',1,'IRHaierAC::setTemp()'],['../classIRHaierACYRW02.html#a80170879e7bd391e360d41f18f6fa52b',1,'IRHaierACYRW02::setTemp()'],['../classIRHitachiAc.html#a9f416886ae341cdb6d449572e4d168a9',1,'IRHitachiAc::setTemp()'],['../classIRHitachiAc1.html#a10ba2dcbe447e505cbaa1a9b63f4823c',1,'IRHitachiAc1::setTemp()'],['../classIRHitachiAc424.html#a5cca8f31d07ce87b6e4a0ff0c22b1be8',1,'IRHitachiAc424::setTemp()'],['../classIRKelvinatorAC.html#ab098a376c7393d377abcc6c1f504d372',1,'IRKelvinatorAC::setTemp()'],['../classIRLgAc.html#ad9924a8bc9737ec6007d76ec47b34142',1,'IRLgAc::setTemp()'],['../classIRMideaAC.html#a42f79e73f418d5267eed7ba5b0e266f5',1,'IRMideaAC::setTemp()'],['../classIRMitsubishiAC.html#afd629013630747400e005fab8407d711',1,'IRMitsubishiAC::setTemp()'],['../classIRMitsubishi136.html#ac19c9234a5f65cae50b64d56c4bebb8f',1,'IRMitsubishi136::setTemp()'],['../classIRMitsubishi112.html#a03ba44a6d2f152b7afade423f12c8726',1,'IRMitsubishi112::setTemp()'],['../classIRMitsubishiHeavy152Ac.html#ad4f9ae94b8ab1fff8fc99b8d7818a8fe',1,'IRMitsubishiHeavy152Ac::setTemp()'],['../classIRMitsubishiHeavy88Ac.html#aa4a92e5334aebdca5d2b26b642e9b9e8',1,'IRMitsubishiHeavy88Ac::setTemp()'],['../classIRNeoclimaAc.html#a59e27fa001f9ab674b69eb2c41b6393c',1,'IRNeoclimaAc::setTemp()'],['../classIRPanasonicAc.html#a58376c311177e701333f4915515d49f1',1,'IRPanasonicAc::setTemp()'],['../classIRSamsungAc.html#a94a71e82321343220836aa614b231bd0',1,'IRSamsungAc::setTemp()'],['../classIRSharpAc.html#a151f88799cdab6fda4cfef83b30e5917',1,'IRSharpAc::setTemp()'],['../classIRTcl112Ac.html#a110bae0201b63db0409c352dd8d62786',1,'IRTcl112Ac::setTemp()'],['../classIRTecoAc.html#a405106cb572dac338d79da48fe7a7cb3',1,'IRTecoAc::setTemp()'],['../classIRToshibaAC.html#a923fad1f637e1851a77a063978994604',1,'IRToshibaAC::setTemp()'],['../classIRTrotecESP.html#ad467e7fe9ff61fec4ec10b367c0f9279',1,'IRTrotecESP::setTemp()'],['../classIRVestelAc.html#a8c4eddfba4edfa16e317e12677736756',1,'IRVestelAc::setTemp()'],['../classIRWhirlpoolAc.html#afff1ae75ffa362abb791c97c20023755',1,'IRWhirlpoolAc::setTemp()']]], + ['settempraw_4282',['setTempRaw',['../classIRCoolixAC.html#ae9371280e92daa8e1441523026f1ef0a',1,'IRCoolixAC']]], + ['settempunit_4283',['setTempUnit',['../classIRDelonghiAc.html#a4e3681e49065ba232577ca05157a5ef2',1,'IRDelonghiAc']]], + ['settime_4284',['setTime',['../classIRArgoAC.html#ae285801cde19da82e128098097624852',1,'IRArgoAC::setTime()'],['../classIRHaierAC.html#a81ca00cf5b49308c2609b717d34958ad',1,'IRHaierAC::setTime()'],['../classIRVestelAc.html#afc5dedf83855a8fea8b29494bfb07d64',1,'IRVestelAc::setTime()'],['../classIRWhirlpoolAc.html#a40289737223c14c8a1e723e7a28bad13',1,'IRWhirlpoolAc::setTime()']]], + ['settimer_4285',['setTimer',['../classIRDaikin128.html#a8498de57fc1bdb2f71a678f7877d3125',1,'IRDaikin128::setTimer()'],['../classIRGreeAC.html#a84debd45d2f2ba221f825257e0bc6294',1,'IRGreeAC::setTimer()'],['../classIRMitsubishiAC.html#acb56c91ef0db6ace7782d356af2dcd4d',1,'IRMitsubishiAC::setTimer()'],['../classIRSharpAc.html#a8782543c33e48af0a09e548276eb6413',1,'IRSharpAc::setTimer()'],['../classIRTecoAc.html#a88a84e22d53a204da754c04210fadd04',1,'IRTecoAc::setTimer()'],['../classIRTrotecESP.html#a92bfed0f247b21c77737b720151dbb88',1,'IRTrotecESP::setTimer()'],['../classIRVestelAc.html#a7c66e1ec13c827714eaa2233f50f072b',1,'IRVestelAc::setTimer()']]], + ['settimeractive_4286',['setTimerActive',['../classIRVestelAc.html#a77f78e534b19a8dca776b17aa06739aa',1,'IRVestelAc']]], + ['settimerenabled_4287',['setTimerEnabled',['../classIRGreeAC.html#a1002d6dfe409076fa7ef252589d5043c',1,'IRGreeAC']]], + ['settolerance_4288',['setTolerance',['../classIRrecv.html#aa091c449db70c65fd0221669df7438ea',1,'IRrecv']]], + ['setturbo_4289',['setTurbo',['../classIRCoolixAC.html#a65a04ec9028025155792be5ba0f81927',1,'IRCoolixAC::setTurbo()'],['../classIRDaikin64.html#a734cc23f79a4de4099a4ceb1aff14762',1,'IRDaikin64::setTurbo()'],['../classIRElectraAc.html#adb40e95465788b03e4cb845bd481f7ed',1,'IRElectraAc::setTurbo()'],['../classIRGoodweatherAc.html#a7827fc5a8f85b284c0121727dba34f11',1,'IRGoodweatherAc::setTurbo()'],['../classIRGreeAC.html#ae873023ad81f7dcb12ee5b061e160bea',1,'IRGreeAC::setTurbo()'],['../classIRHaierACYRW02.html#aba5f028ee1ebf7be2d4de5a66237f01b',1,'IRHaierACYRW02::setTurbo()'],['../classIRKelvinatorAC.html#a7d9c44970e85f23c83723f27e96260ee',1,'IRKelvinatorAC::setTurbo()'],['../classIRMitsubishiHeavy152Ac.html#a275e8ae44e2018a848b3e8f0893c8023',1,'IRMitsubishiHeavy152Ac::setTurbo()'],['../classIRMitsubishiHeavy88Ac.html#a39ac892d349180327cce92c6f82bea30',1,'IRMitsubishiHeavy88Ac::setTurbo()'],['../classIRNeoclimaAc.html#aa2a9563d9e3c5c95dfa512c0bb87e16f',1,'IRNeoclimaAc::setTurbo()'],['../classIRSharpAc.html#a8a184ae8eeb07704b9b69849421e3172',1,'IRSharpAc::setTurbo()'],['../classIRTcl112Ac.html#a99e3b3e2f0cc627b6d872d04b35d6230',1,'IRTcl112Ac::setTurbo()'],['../classIRVestelAc.html#afa762d0fa63ecc7444c1c107f8f07cdb',1,'IRVestelAc::setTurbo()']]], + ['setunknownthreshold_4290',['setUnknownThreshold',['../classIRrecv.html#a02693553aad1decd67bdae60402e48bf',1,'IRrecv']]], + ['setusecelsius_4291',['setUseCelsius',['../classIRMideaAC.html#a1eeb72ddd2b9867c2f9c392080b9c1ed',1,'IRMideaAC']]], + ['setusefahrenheit_4292',['setUseFahrenheit',['../classIRGreeAC.html#af559afaa9da5fd27cdb516355da67bd6',1,'IRGreeAC']]], + ['setvane_4293',['setVane',['../classIRMitsubishiAC.html#abb247f1dca5cf23a7b8a16852dcf32f1',1,'IRMitsubishiAC']]], + ['setweeklytimerenable_4294',['setWeeklyTimerEnable',['../classIRDaikinESP.html#a0db67d46b13acfad9b94c7e4691777b8',1,'IRDaikinESP']]], + ['setwidevane_4295',['setWideVane',['../classIRMitsubishiAC.html#a02b2b3d7456e6123c60dca70de346c25',1,'IRMitsubishiAC']]], + ['setwifi_4296',['setWiFi',['../classIRGreeAC.html#afde745ceaa97f9608195b2ba9fce6c5c',1,'IRGreeAC']]], + ['setxfan_4297',['setXFan',['../classIRGreeAC.html#af465c607222fa433f54c2ce56ced2474',1,'IRGreeAC::setXFan()'],['../classIRKelvinatorAC.html#af02da81109109cf1cb44057fd1a40164',1,'IRKelvinatorAC::setXFan()']]], + ['setzonefollow_4298',['setZoneFollow',['../classIRCoolixAC.html#a0c0f39d8e2e79d8259000695263ec3fa',1,'IRCoolixAC']]], + ['sharp_4299',['sharp',['../classIRac.html#a7b6d8b4e554a89f339f896fe4233ed15',1,'IRac']]], + ['space_4300',['space',['../classIRsend.html#a0417b10d4e16718a87f8b2062a7d04a1',1,'IRsend']]], + ['statereset_4301',['stateReset',['../classIRAmcorAc.html#a018ab4ca4d738d848d3388ea1300b83b',1,'IRAmcorAc::stateReset()'],['../classIRArgoAC.html#af34a99bc37c4496c9fd68856aa065a13',1,'IRArgoAC::stateReset()'],['../classIRCarrierAc64.html#abe58c8f97ab4c34fd0cf198b07589694',1,'IRCarrierAc64::stateReset()'],['../classIRCoolixAC.html#a88a44b7ba5ac7d5654de4592bd41c207',1,'IRCoolixAC::stateReset()'],['../classIRCoronaAc.html#a47726d4ff93528bd8a5a6f1b47ba7141',1,'IRCoronaAc::stateReset()'],['../classIRDaikinESP.html#a49f6b90336225f7e94b8aefd066e1993',1,'IRDaikinESP::stateReset()'],['../classIRDaikin2.html#a9b49e90604bf6b1abb93581eecfc6c88',1,'IRDaikin2::stateReset()'],['../classIRDaikin216.html#adbc856e6531b38963db5680d279a4767',1,'IRDaikin216::stateReset()'],['../classIRDaikin160.html#ade56e55c8a0c81f0803dec2cda4625b0',1,'IRDaikin160::stateReset()'],['../classIRDaikin176.html#ab86a1b458a1be5d7fe5fcb7e287ef1d3',1,'IRDaikin176::stateReset()'],['../classIRDaikin128.html#ab604a7594c3b0131c5d977e3fc3b3565',1,'IRDaikin128::stateReset()'],['../classIRDaikin152.html#a278291def7d0e14552e7fbe9a56346bd',1,'IRDaikin152::stateReset()'],['../classIRDaikin64.html#af5a691404b8026cf1da45502f1c019f4',1,'IRDaikin64::stateReset()'],['../classIRDelonghiAc.html#aac444790a16678a1e88f1adef02829ba',1,'IRDelonghiAc::stateReset()'],['../classIRElectraAc.html#ab8035c14158fcf3758f46f6976b814f7',1,'IRElectraAc::stateReset()'],['../classIRFujitsuAC.html#a603a0e1870f406e4e746a7bb4c37fb70',1,'IRFujitsuAC::stateReset()'],['../classIRGoodweatherAc.html#ae7f8873ad58e553dc89307220628bebf',1,'IRGoodweatherAc::stateReset()'],['../classIRGreeAC.html#a61356a0dfb4656ac438c3629c591b165',1,'IRGreeAC::stateReset()'],['../classIRHaierAC.html#a62fbae1d2bac01ac3a2194274aa839d9',1,'IRHaierAC::stateReset()'],['../classIRHaierACYRW02.html#a106e7ffa0d69cdf976087c6e190d03ea',1,'IRHaierACYRW02::stateReset()'],['../classIRHitachiAc.html#a0564c00c60e64e57e20f3c1a4bd3d894',1,'IRHitachiAc::stateReset()'],['../classIRHitachiAc1.html#a9764b329d982d018b15098b3044f9596',1,'IRHitachiAc1::stateReset()'],['../classIRHitachiAc424.html#afd8d5b21086b34cdc07b498157240f8f',1,'IRHitachiAc424::stateReset()'],['../classIRHitachiAc3.html#a7bdcddf9c7f85b7cb43a92198e422549',1,'IRHitachiAc3::stateReset()'],['../classIRHitachiAc344.html#ab0174472d44790a5516b8f4377a89f22',1,'IRHitachiAc344::stateReset()'],['../classIRKelvinatorAC.html#ad6fefe85023c3fc318b0e45924874f9f',1,'IRKelvinatorAC::stateReset()'],['../classIRLgAc.html#a5959000c9f0b2cf64742d6a2f1c4c9b9',1,'IRLgAc::stateReset()'],['../classIRMideaAC.html#acc584e07406e1811acfb26f6cd5383cd',1,'IRMideaAC::stateReset()'],['../classIRMitsubishiAC.html#a8da4be360c8e2fd3a5a40cb4049b5d84',1,'IRMitsubishiAC::stateReset()'],['../classIRMitsubishi136.html#a67556dab7ed42c68a274f4f24ecc35bb',1,'IRMitsubishi136::stateReset()'],['../classIRMitsubishi112.html#a9c601ba34e10d5c63886c2c5b405d9ae',1,'IRMitsubishi112::stateReset()'],['../classIRMitsubishiHeavy152Ac.html#a0b239cacd3a8a96f2e3d7047f26119da',1,'IRMitsubishiHeavy152Ac::stateReset()'],['../classIRMitsubishiHeavy88Ac.html#a1cf118f435c99372c89a140a79c67f1f',1,'IRMitsubishiHeavy88Ac::stateReset()'],['../classIRNeoclimaAc.html#a5ce32a6e6195b246696cb609994f3762',1,'IRNeoclimaAc::stateReset()'],['../classIRPanasonicAc.html#a9a9fbf531f04c486edf913c382351b2b',1,'IRPanasonicAc::stateReset()'],['../classIRSamsungAc.html#a52186401655966b3103d3d73fb77e7f0',1,'IRSamsungAc::stateReset()'],['../classIRSharpAc.html#aa151c704ba4f5690a7cfadaf90c4b60d',1,'IRSharpAc::stateReset()'],['../classIRTcl112Ac.html#a049f475c1af7b62b9f3482dcf9e66d4a',1,'IRTcl112Ac::stateReset()'],['../classIRTecoAc.html#ad53e6f3d3693ee6efb419326a3d4c492',1,'IRTecoAc::stateReset()'],['../classIRToshibaAC.html#a3d3c3df261b4db7a9d831c94cc206e8a',1,'IRToshibaAC::stateReset()'],['../classIRTrotecESP.html#a86c3415d8c1880c325bc22c2c4ca44e0',1,'IRTrotecESP::stateReset()'],['../classIRVestelAc.html#a921100234f5751f8b94d9673a5d217f9',1,'IRVestelAc::stateReset()'],['../classIRWhirlpoolAc.html#a371a6f48a2f4f66e4243dacbbf4471be',1,'IRWhirlpoolAc::stateReset()']]], + ['stephoriz_4302',['stepHoriz',['../classIRFujitsuAC.html#a53c48bc1f32c849263a3aa86ff06b1d4',1,'IRFujitsuAC']]], + ['stepvert_4303',['stepVert',['../classIRFujitsuAC.html#a942f106c27ce04094b5b615f2e174022',1,'IRFujitsuAC']]], + ['strtobool_4304',['strToBool',['../classIRac.html#a3dba736fe25bd3a3a47b9ec7dae51728',1,'IRac']]], + ['strtodecodetype_4305',['strToDecodeType',['../IRutils_8cpp.html#ae1614f315c1ebc44eaf1ac62055cc1ff',1,'strToDecodeType(const char *const str): IRutils.cpp'],['../IRutils_8h.html#a10b9312e4ac9c96d895af83db01ed72e',1,'strToDecodeType(const char *str): IRutils.cpp']]], + ['strtofanspeed_4306',['strToFanspeed',['../classIRac.html#a7173b12c155d04dd1db07a055f4ecb03',1,'IRac']]], + ['strtomodel_4307',['strToModel',['../classIRac.html#a7036fbbb918d644a98b5efa16374a256',1,'IRac']]], + ['strtoopmode_4308',['strToOpmode',['../classIRac.html#a251fa76ddacc84d2655bac723b7dea28',1,'IRac']]], + ['strtoswingh_4309',['strToSwingH',['../classIRac.html#a294d6040909519f465945245df56e56d',1,'IRac']]], + ['strtoswingv_4310',['strToSwingV',['../classIRac.html#a538c861d79afabb11fb8becedd3962f8',1,'IRac']]], + ['sumbytes_4311',['sumBytes',['../IRutils_8cpp.html#abfbd3d7cc33d0aac341e6619f3390108',1,'sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init): IRutils.cpp'],['../IRutils_8h.html#a3f33bdd680bea210b212d4e9925eb8eb',1,'sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0): IRutils.cpp']]], + ['sumnibbles_4312',['sumNibbles',['../namespaceirutils.html#a4752ecc3eafa3ca2e13344a52519b343',1,'irutils::sumNibbles(const uint8_t *const start, const uint16_t length, const uint8_t init)'],['../namespaceirutils.html#aeb5202fa0093ee6b7e07d4290229fbd2',1,'irutils::sumNibbles(const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)']]], + ['swinghtostring_4313',['swinghToString',['../classIRac.html#a21c9d71bbf229fd8369480e50a7c3689',1,'IRac']]], + ['swingvtostring_4314',['swingvToString',['../classIRac.html#a641b59e48183a8f6d9b739ce7210f142',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.html new file mode 100644 index 000000000..48e591559 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.js new file mode 100644 index 000000000..9efc7ec0e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.js @@ -0,0 +1,21 @@ +var searchData= +[ + ['tcl112_4315',['tcl112',['../classIRac.html#a3028bd9e83956d57b592bb96638b3f59',1,'IRac']]], + ['teco_4316',['teco',['../classIRac.html#a9e612e04e270dd5710e8a63a64b56064',1,'IRac']]], + ['tickshigh_4317',['ticksHigh',['../classIRrecv.html#a573dbb20695f2ffc808623df8c36280c',1,'IRrecv']]], + ['tickslow_4318',['ticksLow',['../classIRrecv.html#ac08e50c5eec10c0095157f4bdd4051c8',1,'IRrecv']]], + ['timerms_4319',['TimerMs',['../classTimerMs.html#a7bf7f8d2fcf76b27b34ea4705810eef5',1,'TimerMs']]], + ['tocommon_4320',['toCommon',['../classIRAmcorAc.html#aac4ae204cf0c393c18e5de96c4ba44ab',1,'IRAmcorAc::toCommon()'],['../classIRArgoAC.html#a4b1fda530b50c30cb863a3c146f4c81b',1,'IRArgoAC::toCommon()'],['../classIRCarrierAc64.html#a7c4a84d0d9f1e78ba611e118ddb90635',1,'IRCarrierAc64::toCommon()'],['../classIRCoolixAC.html#acadeabae7017e49c944eb22528297b3a',1,'IRCoolixAC::toCommon()'],['../classIRCoronaAc.html#a78dee47464e312d57e660b34c10bb13c',1,'IRCoronaAc::toCommon()'],['../classIRDaikinESP.html#a6bc97a753db054ce2ed59809845e23f1',1,'IRDaikinESP::toCommon()'],['../classIRDaikin2.html#a090407aff4ef81714e31ef28ac41d8e2',1,'IRDaikin2::toCommon()'],['../classIRDaikin216.html#ac477511261d7f135ee4f909eb5512f9a',1,'IRDaikin216::toCommon()'],['../classIRDaikin160.html#a0641f2e7f86412a36dcbe98b9049d322',1,'IRDaikin160::toCommon()'],['../classIRDaikin176.html#ac99fcb66d866196b51ad11384154f8ae',1,'IRDaikin176::toCommon()'],['../classIRDaikin128.html#a54de8ff37216f7a3a2cc744d97c2e1c6',1,'IRDaikin128::toCommon()'],['../classIRDaikin152.html#a96fee4c7cee70cc9249c556b277b2f74',1,'IRDaikin152::toCommon()'],['../classIRDaikin64.html#ad57748fa03e79a277508aa42b08c8f83',1,'IRDaikin64::toCommon()'],['../classIRDelonghiAc.html#a2cdcd20dffb763a5f9ff7bd264c1d3e8',1,'IRDelonghiAc::toCommon()'],['../classIRElectraAc.html#ad10aba2fa72f4b839538fc5a99c696ad',1,'IRElectraAc::toCommon()'],['../classIRFujitsuAC.html#adfd6ff9d4449eae7a5268b26058a483f',1,'IRFujitsuAC::toCommon()'],['../classIRGoodweatherAc.html#ae616e9fc03406ec88b5c5ddcde5f2f2c',1,'IRGoodweatherAc::toCommon()'],['../classIRGreeAC.html#ac28c640aa4b5dd0dbbca42b056f877f7',1,'IRGreeAC::toCommon()'],['../classIRHaierAC.html#a1e74862d6ab7e65108a7b1a3b7af7e91',1,'IRHaierAC::toCommon()'],['../classIRHaierACYRW02.html#aff86d2e3e1d357f0eecf6322964e7c16',1,'IRHaierACYRW02::toCommon()'],['../classIRHitachiAc.html#aa1ec8cc4b5025272c72dc69c6d6486a3',1,'IRHitachiAc::toCommon()'],['../classIRHitachiAc1.html#aef93034682210a6c564fbea4461ab47e',1,'IRHitachiAc1::toCommon()'],['../classIRHitachiAc424.html#a36711772ebdf385e0a95564f8a552634',1,'IRHitachiAc424::toCommon()'],['../classIRHitachiAc344.html#a146203ad02a3df4037b97c0416ba828e',1,'IRHitachiAc344::toCommon()'],['../classIRKelvinatorAC.html#a1e900aa29dad75f74de2bb797d475b20',1,'IRKelvinatorAC::toCommon()'],['../classIRLgAc.html#a75c52ef31270f25651521ae2be558faa',1,'IRLgAc::toCommon()'],['../classIRMideaAC.html#a62086b58f71908b75e28a61bd4f6bf15',1,'IRMideaAC::toCommon()'],['../classIRMitsubishiAC.html#a42338266a34940e657e5226c81f2fd06',1,'IRMitsubishiAC::toCommon()'],['../classIRMitsubishi136.html#a938360f488ec923e138744b6f80477bb',1,'IRMitsubishi136::toCommon()'],['../classIRMitsubishi112.html#aadde5055371b418fd733a2e93d12b478',1,'IRMitsubishi112::toCommon()'],['../classIRMitsubishiHeavy152Ac.html#af9cbfb13cd48d5d503756c50df8fc7b7',1,'IRMitsubishiHeavy152Ac::toCommon()'],['../classIRMitsubishiHeavy88Ac.html#a3f80427169359dc72367e6ee4e52c42f',1,'IRMitsubishiHeavy88Ac::toCommon()'],['../classIRNeoclimaAc.html#a455397211c7cb8074f6b7358dc6a5b9e',1,'IRNeoclimaAc::toCommon()'],['../classIRPanasonicAc.html#af2218f117db06424ced00ba6c0cc3234',1,'IRPanasonicAc::toCommon()'],['../classIRSamsungAc.html#a01e9279d541f64ebfa433c35a3651796',1,'IRSamsungAc::toCommon()'],['../classIRSharpAc.html#aaade155b2128ba11c2e91bba676c72d9',1,'IRSharpAc::toCommon()'],['../classIRTcl112Ac.html#af5813975bfe55a76d202f8c7f48df82d',1,'IRTcl112Ac::toCommon()'],['../classIRTecoAc.html#af3953289854dabf105c6612f14ef5da0',1,'IRTecoAc::toCommon()'],['../classIRToshibaAC.html#acda90e0171043c3a673ffac52ef9b4b5',1,'IRToshibaAC::toCommon()'],['../classIRTrotecESP.html#ac224a0a18a64ce9802c3f25fafa20a04',1,'IRTrotecESP::toCommon()'],['../classIRVestelAc.html#adb7ab58e91f13b999b62559fc7add91a',1,'IRVestelAc::toCommon()'],['../classIRWhirlpoolAc.html#a961da338e344fd975934f9f69d97f5b5',1,'IRWhirlpoolAc::toCommon()']]], + ['tocommonfanspeed_4321',['toCommonFanSpeed',['../classIRAmcorAc.html#a951aa81d98c66138f61069431e13f35a',1,'IRAmcorAc::toCommonFanSpeed()'],['../classIRArgoAC.html#a334afe3ce6536089bc2832985067f029',1,'IRArgoAC::toCommonFanSpeed()'],['../classIRCarrierAc64.html#a5a9149acc82fcc22a5be8dcbe791ab77',1,'IRCarrierAc64::toCommonFanSpeed()'],['../classIRCoolixAC.html#a6a0e7219c667eb06897b47a7c36f5fbc',1,'IRCoolixAC::toCommonFanSpeed()'],['../classIRCoronaAc.html#a6d5d0015f01acc97badff7edda964485',1,'IRCoronaAc::toCommonFanSpeed()'],['../classIRDaikinESP.html#a6855a423f10a2230953646d478400574',1,'IRDaikinESP::toCommonFanSpeed()'],['../classIRDaikin176.html#a6f9b7dddcf98c7a42495c900dddf505d',1,'IRDaikin176::toCommonFanSpeed()'],['../classIRDaikin128.html#a1c53a27678731229308e355eb94ec762',1,'IRDaikin128::toCommonFanSpeed()'],['../classIRDaikin64.html#acd24c4932e2bfd6bffbb9a90da2028a6',1,'IRDaikin64::toCommonFanSpeed()'],['../classIRDelonghiAc.html#a231e26843e3616e7455fd020dbb8807b',1,'IRDelonghiAc::toCommonFanSpeed()'],['../classIRElectraAc.html#a5d53fb85582344cfdbfa33da6acbdb7d',1,'IRElectraAc::toCommonFanSpeed()'],['../classIRFujitsuAC.html#a93a35e42d887b5ca6414b295a4a91526',1,'IRFujitsuAC::toCommonFanSpeed()'],['../classIRGoodweatherAc.html#aff899c76d5b808ee35c9f88c116b5dc4',1,'IRGoodweatherAc::toCommonFanSpeed()'],['../classIRGreeAC.html#ade6cb54e99b6dab1df708cbf25fc5967',1,'IRGreeAC::toCommonFanSpeed()'],['../classIRHaierAC.html#ad67ee0b7299d041aad77382dde893229',1,'IRHaierAC::toCommonFanSpeed()'],['../classIRHaierACYRW02.html#a15402e3ba2a9875d5b49f6dab3e85034',1,'IRHaierACYRW02::toCommonFanSpeed()'],['../classIRHitachiAc.html#afba02d48c4a023ed800abf38d5314c7e',1,'IRHitachiAc::toCommonFanSpeed()'],['../classIRHitachiAc1.html#a99f205391deb75d23d08d63e1feff0d4',1,'IRHitachiAc1::toCommonFanSpeed()'],['../classIRHitachiAc424.html#a16abdf55ea3ae4b06e2a23dad3496738',1,'IRHitachiAc424::toCommonFanSpeed()'],['../classIRKelvinatorAC.html#a0ebd262c554c5c843bc3f710570e1401',1,'IRKelvinatorAC::toCommonFanSpeed()'],['../classIRLgAc.html#af47317ba139a4b1e5961b9a45db974df',1,'IRLgAc::toCommonFanSpeed()'],['../classIRMideaAC.html#acd89d4864a46b146ac4f648c4406ded5',1,'IRMideaAC::toCommonFanSpeed()'],['../classIRMitsubishiAC.html#aa7dd30cde520b14575d7fcd992c3bbf1',1,'IRMitsubishiAC::toCommonFanSpeed()'],['../classIRMitsubishi136.html#aaf9f9f17f3ac59ef325b57b9110faa34',1,'IRMitsubishi136::toCommonFanSpeed()'],['../classIRMitsubishi112.html#aaeee082d9adbf7b0d91316c703571f1a',1,'IRMitsubishi112::toCommonFanSpeed()'],['../classIRMitsubishiHeavy152Ac.html#a5e26c3121aceb944fc688e6f641dd5b1',1,'IRMitsubishiHeavy152Ac::toCommonFanSpeed()'],['../classIRMitsubishiHeavy88Ac.html#aa5dae03951ba9a9aeac62184c27f9439',1,'IRMitsubishiHeavy88Ac::toCommonFanSpeed()'],['../classIRNeoclimaAc.html#a5d87285928bd8bfa2abad92fbdf384b5',1,'IRNeoclimaAc::toCommonFanSpeed()'],['../classIRPanasonicAc.html#a1eff8e4d670abc303a02d8baeeb58f8c',1,'IRPanasonicAc::toCommonFanSpeed()'],['../classIRSamsungAc.html#a2905b33c273d2be6cabfc3b16b51a5b4',1,'IRSamsungAc::toCommonFanSpeed()'],['../classIRSharpAc.html#a520666e591965b3b3b2421e06260976a',1,'IRSharpAc::toCommonFanSpeed()'],['../classIRTcl112Ac.html#a66843ee5b53ce9be1aef3774b8df5c84',1,'IRTcl112Ac::toCommonFanSpeed()'],['../classIRTecoAc.html#ac3ad2828770440695969d696ca6ff46d',1,'IRTecoAc::toCommonFanSpeed()'],['../classIRToshibaAC.html#a6c77121c9aba3928e676394f88e88dee',1,'IRToshibaAC::toCommonFanSpeed()'],['../classIRTrotecESP.html#a4aaf17993757533370290fffb728befc',1,'IRTrotecESP::toCommonFanSpeed()'],['../classIRVestelAc.html#a6dfd46f56f2d6b15344722cde0741500',1,'IRVestelAc::toCommonFanSpeed()'],['../classIRWhirlpoolAc.html#a61ef6661a985763540b7c2273b8b1b9c',1,'IRWhirlpoolAc::toCommonFanSpeed()']]], + ['tocommonmode_4322',['toCommonMode',['../classIRAmcorAc.html#a6da2f34f1e044f815e94ede578f4c26f',1,'IRAmcorAc::toCommonMode()'],['../classIRArgoAC.html#a8ccd3f5398f50548fda3a9e0172fb5fa',1,'IRArgoAC::toCommonMode()'],['../classIRCarrierAc64.html#ab17b24d0306b8983886d15175898909e',1,'IRCarrierAc64::toCommonMode()'],['../classIRCoolixAC.html#a789fb5d5eab2e78d392c8e0b9a194b18',1,'IRCoolixAC::toCommonMode()'],['../classIRCoronaAc.html#a04ca6532beb099893eb1dd5d01bb4d31',1,'IRCoronaAc::toCommonMode()'],['../classIRDaikinESP.html#a3a7543204520da36547c163a96e30deb',1,'IRDaikinESP::toCommonMode()'],['../classIRDaikin176.html#aa0b9c96d3bf08400a5110bcfa9f1ec9d',1,'IRDaikin176::toCommonMode()'],['../classIRDaikin128.html#a105a4fc511feba96afc956bb36d2dc50',1,'IRDaikin128::toCommonMode()'],['../classIRDaikin64.html#a80b9dd0fbf935bed5035463af2ad0102',1,'IRDaikin64::toCommonMode()'],['../classIRDelonghiAc.html#a5a3eef369009836a629369cf835741c4',1,'IRDelonghiAc::toCommonMode()'],['../classIRElectraAc.html#a01bd399c3b8908083b95f31d97ddb26f',1,'IRElectraAc::toCommonMode()'],['../classIRFujitsuAC.html#a96140e74d31631581003064f70041d02',1,'IRFujitsuAC::toCommonMode()'],['../classIRGoodweatherAc.html#ab3bcd1354b715179f67499c28fb219fb',1,'IRGoodweatherAc::toCommonMode()'],['../classIRGreeAC.html#a3f393071163fd1577c772a8515e2b5a9',1,'IRGreeAC::toCommonMode()'],['../classIRHaierAC.html#a4d73f75516afff0ef18bdbb7ed9c26ed',1,'IRHaierAC::toCommonMode()'],['../classIRHaierACYRW02.html#a24007a5be360c93ec157b95c8cc06493',1,'IRHaierACYRW02::toCommonMode()'],['../classIRHitachiAc.html#ab7edc0f5571100e1778779081e1c1114',1,'IRHitachiAc::toCommonMode()'],['../classIRHitachiAc1.html#a5cbca62775089593fe2447a77d84b3d5',1,'IRHitachiAc1::toCommonMode()'],['../classIRHitachiAc424.html#a2a725d8dc2178975c977a7496792e667',1,'IRHitachiAc424::toCommonMode()'],['../classIRKelvinatorAC.html#ae2683d38ae72b99e6843e37d36f96db2',1,'IRKelvinatorAC::toCommonMode()'],['../classIRLgAc.html#ac3436968a4445f0210403c353d766b73',1,'IRLgAc::toCommonMode()'],['../classIRMideaAC.html#ac2e0ff374678aadd7fea80194aef8bca',1,'IRMideaAC::toCommonMode()'],['../classIRMitsubishiAC.html#a7eae5da584faf41139be597d6a5e7210',1,'IRMitsubishiAC::toCommonMode()'],['../classIRMitsubishi136.html#a2771fd09b2e953b037c0c65c4e4029ee',1,'IRMitsubishi136::toCommonMode()'],['../classIRMitsubishi112.html#a6da77ebe6e03cfc09aa35e531c292ed1',1,'IRMitsubishi112::toCommonMode()'],['../classIRMitsubishiHeavy152Ac.html#a9faaff371ad3ec33de5646a1afd1992a',1,'IRMitsubishiHeavy152Ac::toCommonMode()'],['../classIRNeoclimaAc.html#a2a220b673c96e54e675d8296aa8b2303',1,'IRNeoclimaAc::toCommonMode()'],['../classIRPanasonicAc.html#a1ace0180b9ac3f4bd17357a03c64792e',1,'IRPanasonicAc::toCommonMode()'],['../classIRSamsungAc.html#a39820a05a9650e9da8a44109234a8d87',1,'IRSamsungAc::toCommonMode()'],['../classIRSharpAc.html#a5e8fca86bcf138bb7c1fd1b4e4384b5f',1,'IRSharpAc::toCommonMode()'],['../classIRTcl112Ac.html#a230a8d768089d869efdea6589b0a9e37',1,'IRTcl112Ac::toCommonMode()'],['../classIRTecoAc.html#ac6c7011b31208887de6d15edbffb211a',1,'IRTecoAc::toCommonMode()'],['../classIRToshibaAC.html#a77871a927ee67460b7bdcb8f204297bc',1,'IRToshibaAC::toCommonMode()'],['../classIRTrotecESP.html#a2b28b06bd25234427d90172b27d57092',1,'IRTrotecESP::toCommonMode()'],['../classIRVestelAc.html#add602c0f052c8ada3b3b5748dda50a58',1,'IRVestelAc::toCommonMode()'],['../classIRWhirlpoolAc.html#a748caa4e22f2f1f47e6334b1a031c4d8',1,'IRWhirlpoolAc::toCommonMode()']]], + ['tocommonswingh_4323',['toCommonSwingH',['../classIRDaikin2.html#a85bb152a4bdcc2798270ee58a3cfe2ae',1,'IRDaikin2::toCommonSwingH()'],['../classIRDaikin176.html#a6a3b66c9777992ed9fcab4e26c1d74dc',1,'IRDaikin176::toCommonSwingH()'],['../classIRHitachiAc344.html#a31562e32ccdf179032e75334b16279f0',1,'IRHitachiAc344::toCommonSwingH()'],['../classIRMitsubishiAC.html#ad7446e0a4ea8d349004c2b4224e69cd9',1,'IRMitsubishiAC::toCommonSwingH()'],['../classIRMitsubishi112.html#a17cfee6dc9ddc38465539ca46f29b263',1,'IRMitsubishi112::toCommonSwingH()'],['../classIRMitsubishiHeavy152Ac.html#afb9e039776c77e898928e9139a21a2b8',1,'IRMitsubishiHeavy152Ac::toCommonSwingH()'],['../classIRMitsubishiHeavy88Ac.html#aead69a01407729240055bd64e583b51b',1,'IRMitsubishiHeavy88Ac::toCommonSwingH()'],['../classIRPanasonicAc.html#aa4241990c350ca936c73b8391c2a11fc',1,'IRPanasonicAc::toCommonSwingH()']]], + ['tocommonswingv_4324',['toCommonSwingV',['../classIRDaikin2.html#a1f3e17757bd4beb0330d75ec3df9788b',1,'IRDaikin2::toCommonSwingV()'],['../classIRDaikin160.html#afae9b50e59c0efa46b96eef9f05a95b7',1,'IRDaikin160::toCommonSwingV()'],['../classIRGreeAC.html#a537d17801a90e22ad2baba7145b038cb',1,'IRGreeAC::toCommonSwingV()'],['../classIRHaierAC.html#aac354e2e4ad72d91667509398078b309',1,'IRHaierAC::toCommonSwingV()'],['../classIRHaierACYRW02.html#a0e426a3479fd80bb3816f016fac22f19',1,'IRHaierACYRW02::toCommonSwingV()'],['../classIRMitsubishiAC.html#a173e3c22f4173f235e7213e41925fdd9',1,'IRMitsubishiAC::toCommonSwingV()'],['../classIRMitsubishi136.html#aca5e6ac2d886083c8c56e2949f9d11e9',1,'IRMitsubishi136::toCommonSwingV()'],['../classIRMitsubishi112.html#a0e577d8554a090d7f2ac2a9ddd3bf15c',1,'IRMitsubishi112::toCommonSwingV()'],['../classIRMitsubishiHeavy152Ac.html#ae4dd9b8f0b5b4becb07618e859a09a51',1,'IRMitsubishiHeavy152Ac::toCommonSwingV()'],['../classIRMitsubishiHeavy88Ac.html#a0597303839e79c97b0fafe6c9ddbcf9a',1,'IRMitsubishiHeavy88Ac::toCommonSwingV()'],['../classIRPanasonicAc.html#adae801e0a2641c196a59d65c26404a13',1,'IRPanasonicAc::toCommonSwingV()']]], + ['togglerc5_4325',['toggleRC5',['../classIRsend.html#a42a78d4a3ef0f88b54bee488320344da',1,'IRsend']]], + ['togglerc6_4326',['toggleRC6',['../classIRsend.html#a5a0e8778394021ea12a8b8c2daf0add6',1,'IRsend']]], + ['toggleswinghoriz_4327',['toggleSwingHoriz',['../classIRFujitsuAC.html#aeba829bb9a9934ad9246a5ba4f4c03fc',1,'IRFujitsuAC']]], + ['toggleswingvert_4328',['toggleSwingVert',['../classIRFujitsuAC.html#a6dc9cc4bda83215fa97896c41b01e584',1,'IRFujitsuAC']]], + ['toshiba_4329',['toshiba',['../classIRac.html#a384e62cc56ebbdd790ebcd500ce56fc5',1,'IRac']]], + ['tostring_4330',['toString',['../classIRAmcorAc.html#a2435fd76c642e4a64c7e2330236dcaa6',1,'IRAmcorAc::toString()'],['../classIRArgoAC.html#ad9f52d54687754c0b8d676cb75a3b1bf',1,'IRArgoAC::toString()'],['../classIRCarrierAc64.html#acede081614a80ae46345d4ae45e39ab2',1,'IRCarrierAc64::toString()'],['../classIRCoolixAC.html#ad1282b4071f003ab35d2a97287ba6d2d',1,'IRCoolixAC::toString()'],['../classIRCoronaAc.html#a13e87d763ffd0d25a9d09010828c2124',1,'IRCoronaAc::toString()'],['../classIRDaikinESP.html#a38e705d3ed5128e400efd971e50518d5',1,'IRDaikinESP::toString()'],['../classIRDaikin2.html#a5804ef19f37ee7b8a525bc8db5146c73',1,'IRDaikin2::toString()'],['../classIRDaikin216.html#a5b9ea30424aa3abd9fdee95c78ba9e40',1,'IRDaikin216::toString()'],['../classIRDaikin160.html#a5d9ff2f09b95023c595e9c4794cb29b8',1,'IRDaikin160::toString()'],['../classIRDaikin176.html#a5ff8d589c7e97bd48b50e0ae01356783',1,'IRDaikin176::toString()'],['../classIRDaikin128.html#a48fc2a4080400f83260d2c861c831a28',1,'IRDaikin128::toString()'],['../classIRDaikin152.html#abb9253e8fe7e9bdf786246ce7ab8c54b',1,'IRDaikin152::toString()'],['../classIRDaikin64.html#aa19ba82f1dd405633f078eaf5cb915b8',1,'IRDaikin64::toString()'],['../classIRDelonghiAc.html#a386fb70137a7c2100d05f3202c224887',1,'IRDelonghiAc::toString()'],['../classIRElectraAc.html#a2b1f49b99ec17e211c6cc63d4f72f6a4',1,'IRElectraAc::toString()'],['../classIRFujitsuAC.html#ad779b8b86849ab4c6fe3cfc4afe2c7b8',1,'IRFujitsuAC::toString()'],['../classIRGoodweatherAc.html#a8c298ad0ab98789aa4eb419ed134ee03',1,'IRGoodweatherAc::toString()'],['../classIRGreeAC.html#a1f18b275e0e3d10fbc952d1da9613074',1,'IRGreeAC::toString()'],['../classIRHaierAC.html#a7effff64e7c9c20b7d9e6c2c10e0ffbc',1,'IRHaierAC::toString()'],['../classIRHaierACYRW02.html#a3858dd619f4ea4071b248bb5fb64fb08',1,'IRHaierACYRW02::toString()'],['../classIRHitachiAc.html#a9d927f191807b52fbd4f5d411e0c6519',1,'IRHitachiAc::toString()'],['../classIRHitachiAc1.html#ac70d5ed48897559d7e2ff0f843c79ddc',1,'IRHitachiAc1::toString()'],['../classIRHitachiAc424.html#abc1c122c68d62b582a7e38cdaf9febe7',1,'IRHitachiAc424::toString()'],['../classIRHitachiAc344.html#a5286ffe0ad72f82f66ad19bd6c3bdacc',1,'IRHitachiAc344::toString()'],['../classIRKelvinatorAC.html#a2cc438f41b6f4ed2f9df42acc1ffccfe',1,'IRKelvinatorAC::toString()'],['../classIRLgAc.html#a4546e2e0f63aac0bb9bd54f4f93c5f6c',1,'IRLgAc::toString()'],['../classIRMideaAC.html#a4980fbb52145e1d12a6fa5601f75018a',1,'IRMideaAC::toString()'],['../classIRMitsubishiAC.html#a28cfd4bb4d3372fb983f737c7e86b530',1,'IRMitsubishiAC::toString()'],['../classIRMitsubishi136.html#a8e49c540665a724c895674edef31d980',1,'IRMitsubishi136::toString()'],['../classIRMitsubishi112.html#ab99894eb185d13c5bd097c287fdbddeb',1,'IRMitsubishi112::toString()'],['../classIRMitsubishiHeavy152Ac.html#a9082e1498220f7b641f5f265d1131c0a',1,'IRMitsubishiHeavy152Ac::toString()'],['../classIRMitsubishiHeavy88Ac.html#a7c77e68371e70eb5fd565d8ac815950e',1,'IRMitsubishiHeavy88Ac::toString()'],['../classIRNeoclimaAc.html#a9e6a036411583bad6daf1ef2e60e013c',1,'IRNeoclimaAc::toString()'],['../classIRPanasonicAc.html#ada0b3e2bf11123d0a2f5df8692ae73ad',1,'IRPanasonicAc::toString()'],['../classIRSamsungAc.html#a82de7f9c7b4984f002ea3849b4e95ff2',1,'IRSamsungAc::toString()'],['../classIRSharpAc.html#afee9b0acec54d1683404b7af66c73046',1,'IRSharpAc::toString()'],['../classIRTcl112Ac.html#a381c019f805973000ac5ddb6c70e2773',1,'IRTcl112Ac::toString()'],['../classIRTecoAc.html#a7f085b545dac637927ae58fca13e5c5f',1,'IRTecoAc::toString()'],['../classIRToshibaAC.html#a5bbf6a725f496ac40ec2fac8f9a0dc1c',1,'IRToshibaAC::toString()'],['../classIRTrotecESP.html#a06783a7571b684be20ee5485f30ceb3c',1,'IRTrotecESP::toString()'],['../classIRVestelAc.html#a5fd0630ad7c1d5da3b1bfc5aefc443ec',1,'IRVestelAc::toString()'],['../classIRWhirlpoolAc.html#ad599025e8413f23d13a9783ff4c1fe93',1,'IRWhirlpoolAc::toString()']]], + ['trotec_4331',['trotec',['../classIRac.html#aed1a012c0546c2b1d53e86871a42ba1a',1,'IRac']]], + ['typetostring_4332',['typeToString',['../IRutils_8cpp.html#a9e98a1b929f36dfa75c2e325bf281cd1',1,'typeToString(const decode_type_t protocol, const bool isRepeat): IRutils.cpp'],['../IRutils_8h.html#a7f49135f3d160700eb12ff6b7309341c',1,'typeToString(const decode_type_t protocol, const bool isRepeat=false): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.html new file mode 100644 index 000000000..f1fc553fe --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.js new file mode 100644 index 000000000..dab397642 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['uint64tostring_4333',['uint64ToString',['../IRutils_8cpp.html#a9f6ddef74b41ef6f8d2805fcfc396420',1,'uint64ToString(uint64_t input, uint8_t base): IRutils.cpp'],['../IRutils_8h.html#a781650451d38303e80da677539f574ee',1,'uint64ToString(uint64_t input, uint8_t base=10): IRutils.cpp']]], + ['uint8tobcd_4334',['uint8ToBcd',['../namespaceirutils.html#a534704a52b75acd46f687cc0a2b91bf1',1,'irutils']]], + ['updatesavedstate_4335',['updateSavedState',['../classIRCoolixAC.html#a1f39630b328939307bb08c18e56e9ad3',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.html new file mode 100644 index 000000000..0302cd989 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.js new file mode 100644 index 000000000..dd25196f9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['validchecksum_4336',['validChecksum',['../classIRAmcorAc.html#a1ad297a62ac3152c9d957cef38757d28',1,'IRAmcorAc::validChecksum()'],['../classIRArgoAC.html#acfa5a9df8273123e6f4c48684ef60006',1,'IRArgoAC::validChecksum()'],['../classIRCarrierAc64.html#affa23f178e079cd3a6c933240759fe80',1,'IRCarrierAc64::validChecksum()'],['../classIRDaikinESP.html#ad766e60827f80b96a66449bddc621d87',1,'IRDaikinESP::validChecksum()'],['../classIRDaikin2.html#ade5c0dbfe38d9ac0c4bc009c897af04d',1,'IRDaikin2::validChecksum()'],['../classIRDaikin216.html#a663c11977545ba01b34715a61a26ab88',1,'IRDaikin216::validChecksum()'],['../classIRDaikin160.html#a0d9f3af404e3b6c116e8c27e938f8479',1,'IRDaikin160::validChecksum()'],['../classIRDaikin176.html#abc97abc68f535f7ad801b393e0a795d5',1,'IRDaikin176::validChecksum()'],['../classIRDaikin128.html#ad0b16e48bff00c5cdeffa1419c003946',1,'IRDaikin128::validChecksum()'],['../classIRDaikin152.html#ade1c641eecea63857115fc20f1811fe7',1,'IRDaikin152::validChecksum()'],['../classIRDaikin64.html#ab04287881112ff21d1ea541c0f21b507',1,'IRDaikin64::validChecksum()'],['../classIRDelonghiAc.html#ae39b20bcea2b7090ac2e29d8cd28e5f6',1,'IRDelonghiAc::validChecksum()'],['../classIRElectraAc.html#a60034a18e7574844fb59a03e7789f419',1,'IRElectraAc::validChecksum()'],['../classIRFujitsuAC.html#a26153c647d127356e47d35a7456c6235',1,'IRFujitsuAC::validChecksum()'],['../classIRGreeAC.html#a74e7df0634f0a60110db8c033d9d5b1d',1,'IRGreeAC::validChecksum()'],['../classIRHaierAC.html#ad7aae554b8f0a76493efc2a43ac0f780',1,'IRHaierAC::validChecksum()'],['../classIRHaierACYRW02.html#a3f6d071d215b0316cccc2e94c4786954',1,'IRHaierACYRW02::validChecksum()'],['../classIRHitachiAc.html#a2549c1fd2e8a603eb8924fbba8b26e87',1,'IRHitachiAc::validChecksum()'],['../classIRHitachiAc1.html#aa6b7ab76567ee15aa08b1594c67bd29d',1,'IRHitachiAc1::validChecksum()'],['../classIRKelvinatorAC.html#aaa915fa5eb3f7e5c7a3dc143b6fda826',1,'IRKelvinatorAC::validChecksum()'],['../classIRLgAc.html#a51748fa24de24049a2fafb4590e84176',1,'IRLgAc::validChecksum()'],['../classIRMideaAC.html#a971ab4af0267bb732834e7e1f7b8e354',1,'IRMideaAC::validChecksum()'],['../classIRMitsubishiAC.html#ad74885e17434aa9038dc19ad74de4cd0',1,'IRMitsubishiAC::validChecksum()'],['../classIRMitsubishi136.html#a666d1268a93e96b50ac9012c09320de9',1,'IRMitsubishi136::validChecksum()'],['../classIRMitsubishiHeavy152Ac.html#abef94200719da0c14e211315ffc8bede',1,'IRMitsubishiHeavy152Ac::validChecksum()'],['../classIRMitsubishiHeavy88Ac.html#aabd9d8f81108f20f1d7adff3ac6c2fd4',1,'IRMitsubishiHeavy88Ac::validChecksum()'],['../classIRNeoclimaAc.html#a32e4b4444e0a97b6da4447e977f74f94',1,'IRNeoclimaAc::validChecksum()'],['../classIRPanasonicAc.html#a6a084754596f7840dd308041d11a822d',1,'IRPanasonicAc::validChecksum()'],['../classIRSamsungAc.html#a4f7339bce78ce2b656fc597b4c88db22',1,'IRSamsungAc::validChecksum()'],['../classIRSharpAc.html#acb7fb0ac19e09da02d36cb73c808420d',1,'IRSharpAc::validChecksum()'],['../classIRTcl112Ac.html#a204bc37ffadf72ed31b305197c4803f4',1,'IRTcl112Ac::validChecksum()'],['../classIRToshibaAC.html#adc7c1eee14e4de896121ad06e88b61eb',1,'IRToshibaAC::validChecksum()'],['../classIRTrotecESP.html#ae08748e33ed12c536b18f6d0dc4da1c7',1,'IRTrotecESP::validChecksum()'],['../classIRVestelAc.html#ad3bcc08fb4242af7dcc65e534816a219',1,'IRVestelAc::validChecksum()'],['../classIRWhirlpoolAc.html#a2d891069ebdecc62b03e8c92befa15c6',1,'IRWhirlpoolAc::validChecksum()']]], + ['validsection_4337',['validSection',['../classIRCoronaAc.html#af36894d88e7fb45affc883ba0b077862',1,'IRCoronaAc']]], + ['vestel_4338',['vestel',['../classIRac.html#a9b1cd1a4d44bc56e62128b9dbc178bba',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.html new file mode 100644 index 000000000..18cf76b24 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.js new file mode 100644 index 000000000..21b364b8b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['whirlpool_4339',['whirlpool',['../classIRac.html#ae5f7a03589f614c03c5ad8629100b05a',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.html new file mode 100644 index 000000000..9182391d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.js new file mode 100644 index 000000000..a9612ad4b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['xorbytes_4340',['xorBytes',['../IRutils_8cpp.html#aaa2a3fb714375e61051a0b24623b9cc9',1,'xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init): IRutils.cpp'],['../IRutils_8h.html#ab030689a93499311ee8e6621ac8757aa',1,'xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.html new file mode 100644 index 000000000..807950604 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.js new file mode 100644 index 000000000..4d4a5aec2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['_7eirrecv_4341',['~IRrecv',['../classIRrecv.html#a87d4cca5e350177cb0922842dda1eb5b',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.html new file mode 100644 index 000000000..2737c5ac1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.js new file mode 100644 index 000000000..42aa9fc12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['bcdtouint8_3719',['bcdToUint8',['../namespaceirutils.html#af18c4abfd0ed9f4b3a099ecec1999ee7',1,'irutils']]], + ['begin_3720',['begin',['../classIRAmcorAc.html#aa723533eea981f79844f241d5bb84654',1,'IRAmcorAc::begin()'],['../classIRArgoAC.html#aca61a63c37797699540c180354809bd8',1,'IRArgoAC::begin()'],['../classIRCarrierAc64.html#a7d9800edffad8a529971535ada5c00ad',1,'IRCarrierAc64::begin()'],['../classIRCoolixAC.html#a506a5ab28865d0243d75ebb7fe62e4ea',1,'IRCoolixAC::begin()'],['../classIRCoronaAc.html#a7db1a8eb9c3c7f76091b2707458e54a9',1,'IRCoronaAc::begin()'],['../classIRDaikinESP.html#accd087c48f246a71898cc6fd7afc2cc7',1,'IRDaikinESP::begin()'],['../classIRDaikin2.html#a6a7b5c28feec523ee81e99a9c32da26e',1,'IRDaikin2::begin()'],['../classIRDaikin216.html#a95be01fb6e672ebd12f2ebca0406ba15',1,'IRDaikin216::begin()'],['../classIRDaikin160.html#a62bb5f66cd99711e388eaa1be9faf617',1,'IRDaikin160::begin()'],['../classIRDaikin176.html#aa742f7d9ae3c9e57cae0e471d7fe59d1',1,'IRDaikin176::begin()'],['../classIRDaikin128.html#af86dba9e085b771c8c3caaebb9f8ee84',1,'IRDaikin128::begin()'],['../classIRDaikin152.html#a2746854350ca7d3a71699439f9843381',1,'IRDaikin152::begin()'],['../classIRDaikin64.html#a291d5f702b4ce763507c731db08b48f2',1,'IRDaikin64::begin()'],['../classIRDelonghiAc.html#a8d5e4f95e929c2365b2be47f42c6328c',1,'IRDelonghiAc::begin()'],['../classIRElectraAc.html#afff519ff9e81ec4aa03ff337f8efef13',1,'IRElectraAc::begin()'],['../classIRFujitsuAC.html#af0dc3fffdafae5970bc367f31029464b',1,'IRFujitsuAC::begin()'],['../classIRGoodweatherAc.html#abace3c8b25d4737a83fe33f94fc741d9',1,'IRGoodweatherAc::begin()'],['../classIRGreeAC.html#a44cf8f0e09248741094af4b35321ab1c',1,'IRGreeAC::begin()'],['../classIRHaierAC.html#ab92fd48ccb5707cb6d14e9d46ce42e17',1,'IRHaierAC::begin()'],['../classIRHaierACYRW02.html#addc01e60e8c4045fab6f22c852eb620f',1,'IRHaierACYRW02::begin()'],['../classIRHitachiAc.html#a62817c840f352bb01a394c37fc95f0f0',1,'IRHitachiAc::begin()'],['../classIRHitachiAc1.html#a28d5d351003d3e0bc1506b06cac8b3d6',1,'IRHitachiAc1::begin()'],['../classIRHitachiAc424.html#a11866bba49e9b976eb22b1039787ecae',1,'IRHitachiAc424::begin()'],['../classIRHitachiAc3.html#a6d79ac7b8ce977e8059019349d6991a7',1,'IRHitachiAc3::begin()'],['../classIRKelvinatorAC.html#a4591bf4e8131aa2a228cbc611156e7f4',1,'IRKelvinatorAC::begin()'],['../classIRLgAc.html#ac08ada1c67ace5ee2ebe4d325aa8c25d',1,'IRLgAc::begin()'],['../classIRMideaAC.html#ac36b6aa76b6b98ab186cd1d5ad9246b4',1,'IRMideaAC::begin()'],['../classIRMitsubishiAC.html#aa6e58080fd811f5b6d0f90c4ef5917df',1,'IRMitsubishiAC::begin()'],['../classIRMitsubishi136.html#abbcd8307862beee2899d2b9900537520',1,'IRMitsubishi136::begin()'],['../classIRMitsubishi112.html#a1d00958556872286b1818d0dbf02e112',1,'IRMitsubishi112::begin()'],['../classIRMitsubishiHeavy152Ac.html#afd649a53d9f7d9b31b7a5732d6cd0857',1,'IRMitsubishiHeavy152Ac::begin()'],['../classIRMitsubishiHeavy88Ac.html#a9bcf18c942ad4df4856bd319215a2002',1,'IRMitsubishiHeavy88Ac::begin()'],['../classIRNeoclimaAc.html#a8f82159b94d86cc4e3d4719441bfa96e',1,'IRNeoclimaAc::begin()'],['../classIRPanasonicAc.html#af48075dc4eb84fcc7f718375d4b0e00a',1,'IRPanasonicAc::begin()'],['../classIRSamsungAc.html#a89f1f902042cd6c6ba9d0f0c6d2cc581',1,'IRSamsungAc::begin()'],['../classIRSharpAc.html#ab87e5b599b7e8fc387fff25b5e13e34f',1,'IRSharpAc::begin()'],['../classIRTcl112Ac.html#a5b9983ab4027951679f0dc31b33cbadf',1,'IRTcl112Ac::begin()'],['../classIRTecoAc.html#a3b23a8556686c83b146101fc31b0dff3',1,'IRTecoAc::begin()'],['../classIRToshibaAC.html#a41e847f399e42c91b0f4aa2ef5d36cba',1,'IRToshibaAC::begin()'],['../classIRTrotecESP.html#a093b874287adb8ef2cc60c832765ff58',1,'IRTrotecESP::begin()'],['../classIRVestelAc.html#a794808d49eb6ce1521ff800b2b15a580',1,'IRVestelAc::begin()'],['../classIRWhirlpoolAc.html#a21db8b31504d416efb2511a33bdc2209',1,'IRWhirlpoolAc::begin()'],['../classIRsend.html#a386f026bf739b0718efde4cffa6ce129',1,'IRsend::begin()']]], + ['booltostring_3721',['boolToString',['../classIRac.html#a9bbd9e6b72e82a752df56e8c489668cf',1,'IRac']]], + ['buildfromstate_3722',['buildFromState',['../classIRFujitsuAC.html#a6fc8d7d0f649185e0858974394636a8d',1,'IRFujitsuAC']]], + ['buildstate_3723',['buildState',['../classIRFujitsuAC.html#ac885c7952253fcee9bf5b4a889b54da9',1,'IRFujitsuAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.html new file mode 100644 index 000000000..6da86e7da --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.js new file mode 100644 index 000000000..0498304c7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.js @@ -0,0 +1,34 @@ +var searchData= +[ + ['calcblockchecksum_3724',['calcBlockChecksum',['../classIRKelvinatorAC.html#a22f561397c526ed6cc3f69a5d527d8d6',1,'IRKelvinatorAC']]], + ['calcchecksum_3725',['calcChecksum',['../classIRAmcorAc.html#aec764cf4d88bb3fcbe3f36d24780f6a9',1,'IRAmcorAc::calcChecksum()'],['../classIRArgoAC.html#acab2fe3b9f77f57f0e99da0bec0d7392',1,'IRArgoAC::calcChecksum()'],['../classIRCarrierAc64.html#a20676dcf4b0a6510cc3bce282fbf8504',1,'IRCarrierAc64::calcChecksum()'],['../classIRDaikin64.html#ac29c18fde1b0cd98991e68c0f672d0e9',1,'IRDaikin64::calcChecksum()'],['../classIRDelonghiAc.html#a14d7629bb888deb02e83886191f44c2d',1,'IRDelonghiAc::calcChecksum()'],['../classIRElectraAc.html#aa8063d07e41ca2cc0fd27093a2e67bb2',1,'IRElectraAc::calcChecksum()'],['../classIRHitachiAc.html#a6e5da77c12ad105439eb159b6a58104a',1,'IRHitachiAc::calcChecksum()'],['../classIRHitachiAc1.html#a6995513d5b59cd7b14cfff39c8843e8d',1,'IRHitachiAc1::calcChecksum()'],['../classIRLgAc.html#a96024e736cf87e65b4e2db7c4c269520',1,'IRLgAc::calcChecksum()'],['../classIRMideaAC.html#ac8733348b311ecf8eed87021cdf4ee31',1,'IRMideaAC::calcChecksum()'],['../classIRNeoclimaAc.html#ac75f316cd1813cdb4e8a6d45d10ddd57',1,'IRNeoclimaAc::calcChecksum()'],['../classIRPanasonicAc.html#a0e38b0f3c54e49cdb59f92279e19840f',1,'IRPanasonicAc::calcChecksum()'],['../classIRSamsungAc.html#a00f9b2a1480d2ed45bdea5d236c77d0f',1,'IRSamsungAc::calcChecksum()'],['../classIRSharpAc.html#af3655c9c394b1391572e8ffab70881ff',1,'IRSharpAc::calcChecksum()'],['../classIRTcl112Ac.html#a0973a1c8a53661ee7720ecb5d08e6dcc',1,'IRTcl112Ac::calcChecksum()'],['../classIRToshibaAC.html#a0d91d32d0d9d722f750eb423d88509f4',1,'IRToshibaAC::calcChecksum()'],['../classIRTrotecESP.html#ac1fdbcbbb8dd1ca50ccf2b55c7281c89',1,'IRTrotecESP::calcChecksum()'],['../classIRVestelAc.html#ac0ba3de4de70350c5325b3d5e0b39e58',1,'IRVestelAc::calcChecksum()']]], + ['calcfirstchecksum_3726',['calcFirstChecksum',['../classIRDaikin128.html#a25b25f6b73bb5f1fd17a16080179d4bc',1,'IRDaikin128']]], + ['calcsecondchecksum_3727',['calcSecondChecksum',['../classIRDaikin128.html#aea8da64300afe0d62ddf3082a72251f2',1,'IRDaikin128']]], + ['calculatechecksum_3728',['calculateChecksum',['../classIRMitsubishiAC.html#aaadefc5880dcd48e3fb2f12b59101f71',1,'IRMitsubishiAC']]], + ['calcusecperiod_3729',['calcUSecPeriod',['../classIRsend.html#ae9e68c0ed22e27c8f7ff82cec7ca3e33',1,'IRsend']]], + ['calibrate_3730',['calibrate',['../classIRAmcorAc.html#a6206e866e859bc4690cb014c49c1ff80',1,'IRAmcorAc::calibrate()'],['../classIRArgoAC.html#a63cd2f350a7f249c020439543ef3c6d5',1,'IRArgoAC::calibrate()'],['../classIRCarrierAc64.html#a0718376156750e66f98ea0549c75b21b',1,'IRCarrierAc64::calibrate()'],['../classIRCoolixAC.html#a9e39ce5050888210d6ba9b79ae3763e3',1,'IRCoolixAC::calibrate()'],['../classIRCoronaAc.html#a5b10141e4a6e3d8511fb7f9f46d00a96',1,'IRCoronaAc::calibrate()'],['../classIRDaikinESP.html#a638a49f49275a2ab0affb09088794e1b',1,'IRDaikinESP::calibrate()'],['../classIRDaikin2.html#a96c62125bddf113c6524960062d05a57',1,'IRDaikin2::calibrate()'],['../classIRDaikin216.html#a49d7501966528c0a690cfb505f163e26',1,'IRDaikin216::calibrate()'],['../classIRDaikin160.html#a608b5556f316c31e3a8aa73684e4e10d',1,'IRDaikin160::calibrate()'],['../classIRDaikin176.html#a1f5989110782c18aa18e3757c50f4a31',1,'IRDaikin176::calibrate()'],['../classIRDaikin128.html#a281396f4c632899648694e3139c3acd0',1,'IRDaikin128::calibrate()'],['../classIRDaikin152.html#a82fa8bfb3384ed09473345b6e194c3ba',1,'IRDaikin152::calibrate()'],['../classIRDaikin64.html#a12a1e21ba1b06f9b3ffac56691ff2206',1,'IRDaikin64::calibrate()'],['../classIRDelonghiAc.html#aab8f78adcd7fcbea0be753a4fc7696e0',1,'IRDelonghiAc::calibrate()'],['../classIRElectraAc.html#af333e90117ab035ff92389d4eefb3649',1,'IRElectraAc::calibrate()'],['../classIRFujitsuAC.html#a8bb6d8456561dfb04ccac95e0e489558',1,'IRFujitsuAC::calibrate()'],['../classIRGoodweatherAc.html#a8a747144587cf38d64bb32a7f86432b3',1,'IRGoodweatherAc::calibrate()'],['../classIRGreeAC.html#a8069d00a16ed04fd6fa10d84b364bca7',1,'IRGreeAC::calibrate()'],['../classIRHaierAC.html#a448b1d5db05f7722db4758e968ea3171',1,'IRHaierAC::calibrate()'],['../classIRHaierACYRW02.html#a2081b29d0526e339a6b94fc41c854197',1,'IRHaierACYRW02::calibrate()'],['../classIRHitachiAc.html#aaabd743da491ef5d73c4b8c46f11241a',1,'IRHitachiAc::calibrate()'],['../classIRHitachiAc1.html#a847a26df2e19668b147cba2eef595a21',1,'IRHitachiAc1::calibrate()'],['../classIRHitachiAc424.html#aae5e5c13767f335331c5fab8d8ba55d6',1,'IRHitachiAc424::calibrate()'],['../classIRHitachiAc3.html#a02e065c08f9ec4a3d9e6f71432087595',1,'IRHitachiAc3::calibrate()'],['../classIRKelvinatorAC.html#aee8863c1678b09432618bb4ca734db95',1,'IRKelvinatorAC::calibrate()'],['../classIRLgAc.html#a4fd11e935c781319b29f606f2f4b2570',1,'IRLgAc::calibrate()'],['../classIRMideaAC.html#a4077604c2af56783f95a0a64eda7148b',1,'IRMideaAC::calibrate()'],['../classIRMitsubishiAC.html#a973c876e34942776ac98f27de96c5228',1,'IRMitsubishiAC::calibrate()'],['../classIRMitsubishi136.html#a76133542efc3763cb7edc9809ad8d93c',1,'IRMitsubishi136::calibrate()'],['../classIRMitsubishi112.html#ad148250070a3f4ac57ed6cb957ffdefb',1,'IRMitsubishi112::calibrate()'],['../classIRMitsubishiHeavy152Ac.html#a5d4c4ce0e69ed33a2f1db2af127c13c5',1,'IRMitsubishiHeavy152Ac::calibrate()'],['../classIRMitsubishiHeavy88Ac.html#a027423ffbee92ef65b02423f7cbaeca8',1,'IRMitsubishiHeavy88Ac::calibrate()'],['../classIRNeoclimaAc.html#a636dd97ca22c847f966eca8112c8eede',1,'IRNeoclimaAc::calibrate()'],['../classIRPanasonicAc.html#a3f850333f2aa7ce40856c99ef85ffd79',1,'IRPanasonicAc::calibrate()'],['../classIRSamsungAc.html#a5cc7486ae41f61cbe0bb053dd7c9e9e3',1,'IRSamsungAc::calibrate()'],['../classIRSharpAc.html#ac37b1a5679ce90e84f6f95c5df1526bb',1,'IRSharpAc::calibrate()'],['../classIRTcl112Ac.html#a435744e4c6ef31b362d15523ce0584f5',1,'IRTcl112Ac::calibrate()'],['../classIRTecoAc.html#ad700578cbae74857483372597a399ff3',1,'IRTecoAc::calibrate()'],['../classIRToshibaAC.html#a74c66bba288cb3cbb43008edb7b376bf',1,'IRToshibaAC::calibrate()'],['../classIRTrotecESP.html#a56de318a27011e0bddb40738c18dbcf2',1,'IRTrotecESP::calibrate()'],['../classIRVestelAc.html#aae91667d96d86de824a20c256c311f15',1,'IRVestelAc::calibrate()'],['../classIRWhirlpoolAc.html#a006c59c1c84c62fccd3730bec30ef5e8',1,'IRWhirlpoolAc::calibrate()'],['../classIRsend.html#ad1776aa6c699f9eeca1eef9bb4fe355b',1,'IRsend::calibrate()']]], + ['cancelofftimer_3731',['cancelOffTimer',['../classIRPanasonicAc.html#a6d202284320c59205cb0d02cb613cada',1,'IRPanasonicAc']]], + ['cancelontimer_3732',['cancelOnTimer',['../classIRPanasonicAc.html#a102e7c029a923e121e40326859f2e4a3',1,'IRPanasonicAc']]], + ['canceltimers_3733',['cancelTimers',['../classIRHaierAC.html#a1cccc733f74232751f95c32e47795638',1,'IRHaierAC']]], + ['carrier64_3734',['carrier64',['../classIRac.html#a8090f2d79a31b81a0342b2e9efb9d555',1,'IRac']]], + ['celsiustofahrenheit_3735',['celsiusToFahrenheit',['../IRutils_8cpp.html#a19b940e26a4f8ddcaf86cce1ec62d563',1,'celsiusToFahrenheit(const float deg): IRutils.cpp'],['../IRutils_8h.html#a19b940e26a4f8ddcaf86cce1ec62d563',1,'celsiusToFahrenheit(const float deg): IRutils.cpp']]], + ['checksum_3736',['checksum',['../classIRAmcorAc.html#a67244a75731be6a3bd96ecc0384d0113',1,'IRAmcorAc::checksum()'],['../classIRArgoAC.html#ab0fe4e42d1c1201a92f5c4738b869763',1,'IRArgoAC::checksum()'],['../classIRCarrierAc64.html#a005fab56acf94fe97db7fa92651b2882',1,'IRCarrierAc64::checksum()'],['../classIRCoronaAc.html#ae0257fdafacf7fd2e7ac6ca3f8ae3168',1,'IRCoronaAc::checksum()'],['../classIRDaikinESP.html#ac8ac2a0674dc5cfaf514d319b51b20ab',1,'IRDaikinESP::checksum()'],['../classIRDaikin2.html#abb8e4ad1f8c3ada4211541e5a6e23e64',1,'IRDaikin2::checksum()'],['../classIRDaikin216.html#af2c951901b3b9db9f285a4e9b563ea5e',1,'IRDaikin216::checksum()'],['../classIRDaikin160.html#a34090a598e2b25ee4688c8fbac933638',1,'IRDaikin160::checksum()'],['../classIRDaikin176.html#a4cfe2c4ca95adbf66e149b322d58a843',1,'IRDaikin176::checksum()'],['../classIRDaikin128.html#a747c906808c269581de6cf9b02e5c0a7',1,'IRDaikin128::checksum()'],['../classIRDaikin152.html#a0e208d3e1938abcb320665fffd6ed0e3',1,'IRDaikin152::checksum()'],['../classIRDaikin64.html#a27e2f82b2f13f1e63e981af8f1d3912a',1,'IRDaikin64::checksum()'],['../classIRDelonghiAc.html#ae4c4e7140a763eee159991f5c8afc54f',1,'IRDelonghiAc::checksum()'],['../classIRElectraAc.html#a73dc5b9a038669cc1f00f5b64ad458d1',1,'IRElectraAc::checksum()'],['../classIRGreeAC.html#aaa6b2702d79a7a3db454b99d71064679',1,'IRGreeAC::checksum()'],['../classIRHaierAC.html#ab7faae274ff7f30bf7df3c58d6e7e210',1,'IRHaierAC::checksum()'],['../classIRHaierACYRW02.html#a18045defdd5641ae13c7c75dda0cf23a',1,'IRHaierACYRW02::checksum()'],['../classIRHitachiAc.html#a3b65ccbd6de6b5dcb5a794b471e363f5',1,'IRHitachiAc::checksum()'],['../classIRHitachiAc1.html#aa6687d6282b134d508d6534e8446b341',1,'IRHitachiAc1::checksum()'],['../classIRKelvinatorAC.html#a09acf66b92d3fde6692ec02ff8e62dab',1,'IRKelvinatorAC::checksum()'],['../classIRLgAc.html#a438cbbb77668205c3f2b59b8f28585cd',1,'IRLgAc::checksum()'],['../classIRMideaAC.html#a418b7cbb4b388dba732176d891bb499d',1,'IRMideaAC::checksum()'],['../classIRMitsubishiAC.html#a7c5b1e5c53d99f1564d8a0424f626adb',1,'IRMitsubishiAC::checksum()'],['../classIRMitsubishi136.html#aa2c6fe9b28462052cf6627960126a783',1,'IRMitsubishi136::checksum()'],['../classIRMitsubishi112.html#a65ee232bfc09d05724b8ec5ada538ccf',1,'IRMitsubishi112::checksum()'],['../classIRMitsubishiHeavy152Ac.html#a14cdcaeefef283f707d0fae5108d65f4',1,'IRMitsubishiHeavy152Ac::checksum()'],['../classIRMitsubishiHeavy88Ac.html#acb03ef0da10d3fec14c71bfa087a02b8',1,'IRMitsubishiHeavy88Ac::checksum()'],['../classIRNeoclimaAc.html#acba18ea35a59f6f1ccbcfd75e7979feb',1,'IRNeoclimaAc::checksum()'],['../classIRSamsungAc.html#a75c5886916dd3ef3aa6f96f04934048d',1,'IRSamsungAc::checksum()'],['../classIRSharpAc.html#ad87f46ad9220213d77022dc34920d802',1,'IRSharpAc::checksum()'],['../classIRTcl112Ac.html#a2486f46c7db6a3dfbe3af9c842ff37fa',1,'IRTcl112Ac::checksum()'],['../classIRToshibaAC.html#a5aa2c6fc3b07830f872f98906df7e9ec',1,'IRToshibaAC::checksum()'],['../classIRTrotecESP.html#a5e416e083653ab365f65b3f645f60e8c',1,'IRTrotecESP::checksum()'],['../classIRVestelAc.html#a7a9046e7b5ff57864862bf5f7ad23c4d',1,'IRVestelAc::checksum()'],['../classIRWhirlpoolAc.html#a7790be3df6c4609e5c08c17c5ee52047',1,'IRWhirlpoolAc::checksum()']]], + ['checkzjssig_3737',['checkZjsSig',['../classIRMitsubishiHeavy88Ac.html#a6aaf8ae4c9b52d73229b20414099f309',1,'IRMitsubishiHeavy88Ac']]], + ['checkzmssig_3738',['checkZmsSig',['../classIRMitsubishiHeavy152Ac.html#a3d1c9d2c98945d21eb1ce82fac1771d2',1,'IRMitsubishiHeavy152Ac']]], + ['cleanstate_3739',['cleanState',['../classIRac.html#aad988dc123495012758307213a933f37',1,'IRac']]], + ['clearontimerflag_3740',['clearOnTimerFlag',['../classIRDaikin2.html#a3587ce954ba94e347d08d73974b50d72',1,'IRDaikin2::clearOnTimerFlag()'],['../classIRDaikin128.html#a8f0bd823535a5bf8b2642eed698b9a71',1,'IRDaikin128::clearOnTimerFlag()']]], + ['clearpowerspecial_3741',['clearPowerSpecial',['../classIRSharpAc.html#a3c98c96a66dff560941e461a70efdb1a',1,'IRSharpAc']]], + ['clearsensortemp_3742',['clearSensorTemp',['../classIRCoolixAC.html#a5deca09ced33931f089f5cd3c07eac4a',1,'IRCoolixAC']]], + ['clearsleeptimerflag_3743',['clearSleepTimerFlag',['../classIRDaikin2.html#a0c165ff91a712e61910ef25e9728e066',1,'IRDaikin2::clearSleepTimerFlag()'],['../classIRDaikin128.html#a5517a481892dd55f4528103037a0d408',1,'IRDaikin128::clearSleepTimerFlag()']]], + ['cmpstates_3744',['cmpStates',['../classIRac.html#a3ba4eee08650dfcdd6d492a67c86f016',1,'IRac']]], + ['compare_3745',['compare',['../classIRrecv.html#ad7347c72b14d9f2f20f65bcf235ab3dc',1,'IRrecv']]], + ['convertfan_3746',['convertFan',['../classIRAmcorAc.html#ad0f8b7cdf5942c3680639d410f53d18c',1,'IRAmcorAc::convertFan()'],['../classIRArgoAC.html#acd147993fb998a0e7015173b9514d4a2',1,'IRArgoAC::convertFan()'],['../classIRCarrierAc64.html#a255e6679397434877f1c6c9ac70fff50',1,'IRCarrierAc64::convertFan()'],['../classIRCoolixAC.html#a7ffa1cfcf82bd905b0f607401200c895',1,'IRCoolixAC::convertFan()'],['../classIRCoronaAc.html#a6826036fcabbb45e7369f42912fae02f',1,'IRCoronaAc::convertFan()'],['../classIRDaikinESP.html#ab58be19636d41d60b9c62d658ca18cae',1,'IRDaikinESP::convertFan()'],['../classIRDaikin2.html#ad147ea14695c9498bb091862e172dc81',1,'IRDaikin2::convertFan()'],['../classIRDaikin216.html#a520cc65161290f15022b4108f7049a83',1,'IRDaikin216::convertFan()'],['../classIRDaikin160.html#a32658c0f24d0b0c398d54ef648d717a9',1,'IRDaikin160::convertFan()'],['../classIRDaikin176.html#ae3dda9a55f851b5253d0677835a2c3dd',1,'IRDaikin176::convertFan()'],['../classIRDaikin128.html#a983c13bc608fbfa32d7ea2c36dc84116',1,'IRDaikin128::convertFan()'],['../classIRDaikin152.html#a5e2e79252602ca3493baf00cf3fe7787',1,'IRDaikin152::convertFan()'],['../classIRDaikin64.html#a109ff0c33b0a7dfd763683538915c811',1,'IRDaikin64::convertFan()'],['../classIRDelonghiAc.html#aeff2970b20963ae59b99464ae683113f',1,'IRDelonghiAc::convertFan()'],['../classIRElectraAc.html#afcf3ef62d69e370cb88dd2036e5a1357',1,'IRElectraAc::convertFan()'],['../classIRFujitsuAC.html#a111060b7c93e77fdbd1dc96fc8a6c10f',1,'IRFujitsuAC::convertFan()'],['../classIRGoodweatherAc.html#abb443826453a65e87f6dedddf2dd74d5',1,'IRGoodweatherAc::convertFan()'],['../classIRGreeAC.html#a39aa0e4759330aef39382813d3aa96a4',1,'IRGreeAC::convertFan()'],['../classIRHaierAC.html#a58628dd19a7247fc5358c0dc8c30baba',1,'IRHaierAC::convertFan()'],['../classIRHaierACYRW02.html#a66e42d018f3d86b136624a347d333401',1,'IRHaierACYRW02::convertFan()'],['../classIRHitachiAc.html#a5c632c9efc42d9378fdefe608c9bb771',1,'IRHitachiAc::convertFan()'],['../classIRHitachiAc1.html#a96c22fddcd7dfcc5b8f205cc5c7efdef',1,'IRHitachiAc1::convertFan()'],['../classIRHitachiAc424.html#a4f502b779f9fe4aca3a2f649c4cfbda3',1,'IRHitachiAc424::convertFan()'],['../classIRLgAc.html#a71ce8d1be4222ecae26fcea3b71a1ba6',1,'IRLgAc::convertFan()'],['../classIRMideaAC.html#a08a8e49986ce808fd7edd8aee7399a64',1,'IRMideaAC::convertFan()'],['../classIRMitsubishiAC.html#a58ce95e1ae198a9855ee5e81335570cf',1,'IRMitsubishiAC::convertFan()'],['../classIRMitsubishi136.html#a81e691b386950859d1ad0a3c7faf7e49',1,'IRMitsubishi136::convertFan()'],['../classIRMitsubishi112.html#a4194e5b076687b79153bc8cd50c9bc86',1,'IRMitsubishi112::convertFan()'],['../classIRMitsubishiHeavy152Ac.html#ae11040290301b5fe66dfe79e8ea9512b',1,'IRMitsubishiHeavy152Ac::convertFan()'],['../classIRMitsubishiHeavy88Ac.html#acd69c45dbc3f5a150e17b82b5eae7b3f',1,'IRMitsubishiHeavy88Ac::convertFan()'],['../classIRNeoclimaAc.html#a8c3ac622428f118b28d53a3a82740993',1,'IRNeoclimaAc::convertFan()'],['../classIRPanasonicAc.html#aeada51b2d1ff51ff81dfc5c996b416df',1,'IRPanasonicAc::convertFan()'],['../classIRSamsungAc.html#a6be52cc6980ad0bf80261c2a48eb3c87',1,'IRSamsungAc::convertFan()'],['../classIRSharpAc.html#a9b58f12bc44639694a8422a2b9b78a88',1,'IRSharpAc::convertFan()'],['../classIRTcl112Ac.html#a3f8178f8f646ed9892eefa40bbff4fb1',1,'IRTcl112Ac::convertFan()'],['../classIRTecoAc.html#a262aead12607ff962dd97c73e6dea078',1,'IRTecoAc::convertFan()'],['../classIRToshibaAC.html#aeef5cfb840f3058629b486232b7efb22',1,'IRToshibaAC::convertFan()'],['../classIRTrotecESP.html#a905d4d5bd298db8c2e1a9b004fd541e8',1,'IRTrotecESP::convertFan()'],['../classIRVestelAc.html#aa7702b0e50b6c8073cd7740a630b19dd',1,'IRVestelAc::convertFan()'],['../classIRWhirlpoolAc.html#a3004feef0ec5fe327d6a43d68d029377',1,'IRWhirlpoolAc::convertFan()']]], + ['convertmode_3747',['convertMode',['../classIRAmcorAc.html#ab57117e1072b5265ac9ab5be6d58bccc',1,'IRAmcorAc::convertMode()'],['../classIRArgoAC.html#ad242e7b18dea9768b9fad6b1e0e12f65',1,'IRArgoAC::convertMode()'],['../classIRCarrierAc64.html#a8e94b1526b26cec55f1e700c86aaf74e',1,'IRCarrierAc64::convertMode()'],['../classIRCoolixAC.html#acfb0d2c20322cb4d3cd681a3a54b30fe',1,'IRCoolixAC::convertMode()'],['../classIRCoronaAc.html#a9f9cf8e38285cb2f3caf79e14516bda1',1,'IRCoronaAc::convertMode()'],['../classIRDaikinESP.html#aa96f52596148cab1f806faf190a0aa0a',1,'IRDaikinESP::convertMode()'],['../classIRDaikin2.html#a10aae6ec9783eac9d89ff98b947767dd',1,'IRDaikin2::convertMode()'],['../classIRDaikin216.html#a4fa9eca71ee6ad66b3fffd8b779f5fb0',1,'IRDaikin216::convertMode()'],['../classIRDaikin160.html#ac69861fdbde341fc75d90a5e4918aa56',1,'IRDaikin160::convertMode()'],['../classIRDaikin176.html#ab07fd6eab0ac6132625a291dae8cfc78',1,'IRDaikin176::convertMode()'],['../classIRDaikin128.html#a0bad4830267887299b2773075a16b283',1,'IRDaikin128::convertMode()'],['../classIRDaikin152.html#a25592419c95c0271d8a0c4203a2919c3',1,'IRDaikin152::convertMode()'],['../classIRDaikin64.html#a595d91c0294c9482aa453f077eebf882',1,'IRDaikin64::convertMode()'],['../classIRDelonghiAc.html#a51a6eab431f81fa448a48c0ec071e706',1,'IRDelonghiAc::convertMode()'],['../classIRElectraAc.html#a0026a1981e713ce1f6916203717e0a00',1,'IRElectraAc::convertMode()'],['../classIRFujitsuAC.html#a242504a5b97c19ff7e369efcadd3916e',1,'IRFujitsuAC::convertMode()'],['../classIRGoodweatherAc.html#aef14e2b6c220e556300d286922da1f54',1,'IRGoodweatherAc::convertMode()'],['../classIRGreeAC.html#a609e87ad4926f150b44426caf79fd38e',1,'IRGreeAC::convertMode()'],['../classIRHaierAC.html#af6188dbed5cae022b4fd1eef358f594c',1,'IRHaierAC::convertMode()'],['../classIRHaierACYRW02.html#a9a51f3d4b4c60ed7d99f9836a57bb3e5',1,'IRHaierACYRW02::convertMode()'],['../classIRHitachiAc.html#af1bdc5e22e5e24218421bd3bbb436301',1,'IRHitachiAc::convertMode()'],['../classIRHitachiAc1.html#a6211c96f463353791e5d922d9939f23c',1,'IRHitachiAc1::convertMode()'],['../classIRHitachiAc424.html#a974bf3ada7117e463b8c23e2158902be',1,'IRHitachiAc424::convertMode()'],['../classIRKelvinatorAC.html#acc9d70a94dd3813005ca0381b80a35e4',1,'IRKelvinatorAC::convertMode()'],['../classIRLgAc.html#a114eca216b7c9c7be33d4527f848311e',1,'IRLgAc::convertMode()'],['../classIRMideaAC.html#a0ca16c8bc2232be467baba8ea69b40d4',1,'IRMideaAC::convertMode()'],['../classIRMitsubishiAC.html#a86d069e406d247bafbefbdd09b22894f',1,'IRMitsubishiAC::convertMode()'],['../classIRMitsubishi136.html#a43b8ff1083d09563a5d3a25b24e480ea',1,'IRMitsubishi136::convertMode()'],['../classIRMitsubishi112.html#aa41d6ec8bc6dc91891aaddbd996f6040',1,'IRMitsubishi112::convertMode()'],['../classIRMitsubishiHeavy152Ac.html#a067ca776edc19a577e8bcda5013e1d0f',1,'IRMitsubishiHeavy152Ac::convertMode()'],['../classIRMitsubishiHeavy88Ac.html#ad0419d176d70935fc535cdcc47ffba02',1,'IRMitsubishiHeavy88Ac::convertMode()'],['../classIRNeoclimaAc.html#a61335773816ecbbeb949e5da78d07e50',1,'IRNeoclimaAc::convertMode()'],['../classIRPanasonicAc.html#a3f3bc3e4b73338351f33f26c635075bb',1,'IRPanasonicAc::convertMode()'],['../classIRSamsungAc.html#a76f7fed436bdfcd9c9a9da8dd99cb9f7',1,'IRSamsungAc::convertMode()'],['../classIRSharpAc.html#a340d60b4b24c10479b3fed4409e0834b',1,'IRSharpAc::convertMode()'],['../classIRTcl112Ac.html#ac063653636319a9451590b08abbfecdc',1,'IRTcl112Ac::convertMode()'],['../classIRTecoAc.html#a5f95c5aacd8fc312acd0f36fd9dc33f2',1,'IRTecoAc::convertMode()'],['../classIRToshibaAC.html#a1cdcb695e128d57c721623cfdc9a8e8d',1,'IRToshibaAC::convertMode()'],['../classIRTrotecESP.html#a114a7022f0382275a55a2775d3d8e894',1,'IRTrotecESP::convertMode()'],['../classIRVestelAc.html#a5bb967d4972374254dad2c0a6fac7ed2',1,'IRVestelAc::convertMode()'],['../classIRWhirlpoolAc.html#afbf2f473c98f480d68c8bb28e1202d56',1,'IRWhirlpoolAc::convertMode()']]], + ['convertswingh_3748',['convertSwingH',['../classIRDaikin2.html#a79a989ad0221157c4dd8d992cc2863dc',1,'IRDaikin2::convertSwingH()'],['../classIRDaikin176.html#a2387b8dff2a9c9cd164034977b03f192',1,'IRDaikin176::convertSwingH()'],['../classIRHitachiAc344.html#a34d0fa5b522b51dac46f33cbb0a0a389',1,'IRHitachiAc344::convertSwingH()'],['../classIRMitsubishiAC.html#a8235a527a178486bb58ce62749aaf2fb',1,'IRMitsubishiAC::convertSwingH()'],['../classIRMitsubishi112.html#ab17598ce693475ef167525b8408e2da4',1,'IRMitsubishi112::convertSwingH()'],['../classIRMitsubishiHeavy152Ac.html#a0183cf4fcefb60ac61060dde698efbd1',1,'IRMitsubishiHeavy152Ac::convertSwingH()'],['../classIRMitsubishiHeavy88Ac.html#a8b995256a6651822731da7a912c01f19',1,'IRMitsubishiHeavy88Ac::convertSwingH()'],['../classIRPanasonicAc.html#abb17db3452ae347101dc6eaa8e84433b',1,'IRPanasonicAc::convertSwingH()']]], + ['convertswingv_3749',['convertSwingV',['../classIRArgoAC.html#ac23ff32b45c3fc5402e7e303ad9b5d54',1,'IRArgoAC::convertSwingV()'],['../classIRDaikin2.html#aa3de8468b869989ec52a5f9f57ff4a77',1,'IRDaikin2::convertSwingV()'],['../classIRDaikin160.html#a615f599f3bc3e8dec5e5ef92512a2301',1,'IRDaikin160::convertSwingV()'],['../classIRGoodweatherAc.html#a3b37c04fd9b60b63052d93374fc15d4f',1,'IRGoodweatherAc::convertSwingV()'],['../classIRGreeAC.html#ae3717400d1dc0336bcc5fa17c1397a9b',1,'IRGreeAC::convertSwingV()'],['../classIRHaierAC.html#a34053c32ba50ff3b81b208d068efe2a4',1,'IRHaierAC::convertSwingV()'],['../classIRHaierACYRW02.html#a1f7dffe29fbe67989b2f425d629850db',1,'IRHaierACYRW02::convertSwingV()'],['../classIRMitsubishiAC.html#ab561f6421b2f3e0d92d9fab685da639a',1,'IRMitsubishiAC::convertSwingV()'],['../classIRMitsubishi136.html#a59dee0c57d3ca2bdf4c7839142d23059',1,'IRMitsubishi136::convertSwingV()'],['../classIRMitsubishi112.html#a95c545497e0acc6f78ec229a2ada9de0',1,'IRMitsubishi112::convertSwingV()'],['../classIRMitsubishiHeavy152Ac.html#a93f2678fce3b35cfe3e31221d3355291',1,'IRMitsubishiHeavy152Ac::convertSwingV()'],['../classIRMitsubishiHeavy88Ac.html#abeba5346e1fc2223838fbc5d3ed03f23',1,'IRMitsubishiHeavy88Ac::convertSwingV()'],['../classIRPanasonicAc.html#a024e64fe32848e9b0b72e9c04db0fd98',1,'IRPanasonicAc::convertSwingV()']]], + ['coolix_3750',['coolix',['../classIRac.html#a4750db3b06db51f5a23c22538c41b7b3',1,'IRac']]], + ['copyirparams_3751',['copyIrParams',['../classIRrecv.html#ab017a0f9256954bb7d943e3c6b7e31bf',1,'IRrecv']]], + ['corona_3752',['corona',['../classIRac.html#adcf2bdb1ef6dc057532ae7d188557dac',1,'IRac']]], + ['countbits_3753',['countBits',['../IRutils_8cpp.html#a84621a9f7fb2d57bd425f9f0d662cf7d',1,'countBits(const uint8_t *const start, const uint16_t length, const bool ones, const uint16_t init): IRutils.cpp'],['../IRutils_8cpp.html#aae8042367bb94df81672603270fa7342',1,'countBits(const uint64_t data, const uint8_t length, const bool ones, const uint16_t init): IRutils.cpp'],['../IRutils_8h.html#a27816eac50afafa9e53ba4b53675da20',1,'countBits(const uint8_t *const start, const uint16_t length, const bool ones=true, const uint16_t init=0): IRutils.cpp'],['../IRutils_8h.html#a5a719829db11f5d5560b4367c0d2d365',1,'countBits(const uint64_t data, const uint8_t length, const bool ones=true, const uint16_t init=0): IRutils.cpp']]], + ['crudenoisefilter_3754',['crudeNoiseFilter',['../classIRrecv.html#ae833bdb8fccc676043fc4ccae432fab1',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.html new file mode 100644 index 000000000..911304e60 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.js new file mode 100644 index 000000000..25bed5a59 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.js @@ -0,0 +1,95 @@ +var searchData= +[ + ['daikin_3755',['daikin',['../classIRac.html#afb6d77bbeb5b2465437cef4f58b83e0e',1,'IRac']]], + ['daikin128_3756',['daikin128',['../classIRac.html#a8fe7c254e1bcb32b6b6fdc1f91693a50',1,'IRac']]], + ['daikin152_3757',['daikin152',['../classIRac.html#a6dff8e608e3e9fecffe71c3fd1ebe74e',1,'IRac']]], + ['daikin160_3758',['daikin160',['../classIRac.html#a3b34f44d713efa52f30d43405cde831c',1,'IRac']]], + ['daikin176_3759',['daikin176',['../classIRac.html#aaae173fd58a7b53c3f4d2edbf7c4afe7',1,'IRac']]], + ['daikin2_3760',['daikin2',['../classIRac.html#a89eddc0e1b3c41c608208d2752dc954c',1,'IRac']]], + ['daikin216_3761',['daikin216',['../classIRac.html#a101ac8b9e9564e557ef1a1f61ff111d9',1,'IRac']]], + ['daikin64_3762',['daikin64',['../classIRac.html#a074db6fc0cff2878d80a397020e1b249',1,'IRac']]], + ['decode_3763',['decode',['../classIRrecv.html#aeaa5c07a8b46f8fbb982f996cc1f9f4b',1,'IRrecv']]], + ['decodeairwell_3764',['decodeAirwell',['../classIRrecv.html#acf4635d5ee146a82498cb0c269b6af41',1,'IRrecv']]], + ['decodeaiwarct501_3765',['decodeAiwaRCT501',['../classIRrecv.html#aa4d678376a4c0f8ea953474a6f5ef9d2',1,'IRrecv']]], + ['decodeamcor_3766',['decodeAmcor',['../classIRrecv.html#a8d81fcfb47e36925975d313027689a44',1,'IRrecv']]], + ['decodeargo_3767',['decodeArgo',['../classIRrecv.html#a94f12dc000a6e7b75ea8680fd48fc487',1,'IRrecv']]], + ['decodecarrierac_3768',['decodeCarrierAC',['../classIRrecv.html#acf3d1c37038120a5c0996d92577ce74a',1,'IRrecv']]], + ['decodecarrierac40_3769',['decodeCarrierAC40',['../classIRrecv.html#a4bdb35ec34f49401a6b9becd15b8a3b5',1,'IRrecv']]], + ['decodecarrierac64_3770',['decodeCarrierAC64',['../classIRrecv.html#a79d03c31da48a385ab47cc8f342ef9b3',1,'IRrecv']]], + ['decodecoolix_3771',['decodeCOOLIX',['../classIRrecv.html#a964af7e72e2133688f0596c718cb98ca',1,'IRrecv']]], + ['decodecoronaac_3772',['decodeCoronaAc',['../classIRrecv.html#a981cba14551c93af57f9c1c0e1775d12',1,'IRrecv']]], + ['decodedaikin_3773',['decodeDaikin',['../classIRrecv.html#a141f0de9f4cae8daeb025aff3904ecaa',1,'IRrecv']]], + ['decodedaikin128_3774',['decodeDaikin128',['../classIRrecv.html#ac7188577c874d9f8f19304a3ec775415',1,'IRrecv']]], + ['decodedaikin152_3775',['decodeDaikin152',['../classIRrecv.html#ab20a6586b4e56cc428012ec96f5ccc2c',1,'IRrecv']]], + ['decodedaikin160_3776',['decodeDaikin160',['../classIRrecv.html#af0b9822defe6b29099079d664d9dc413',1,'IRrecv']]], + ['decodedaikin176_3777',['decodeDaikin176',['../classIRrecv.html#aa142d1340201b6fdc5b462f46fe21ee0',1,'IRrecv']]], + ['decodedaikin2_3778',['decodeDaikin2',['../classIRrecv.html#a4c4799a0d45ea5562159c46939617d80',1,'IRrecv']]], + ['decodedaikin216_3779',['decodeDaikin216',['../classIRrecv.html#a7f860686a5c58aa8f4d1842cfb15b2f9',1,'IRrecv']]], + ['decodedaikin64_3780',['decodeDaikin64',['../classIRrecv.html#a030701f081a9c6eab0c07b75433b524c',1,'IRrecv']]], + ['decodedelonghiac_3781',['decodeDelonghiAc',['../classIRrecv.html#a8c91cc83770d243e942387cc16e9ca6f',1,'IRrecv']]], + ['decodedenon_3782',['decodeDenon',['../classIRrecv.html#a0b1bd1c817cb43bc3755126191b7f4a2',1,'IRrecv']]], + ['decodedish_3783',['decodeDISH',['../classIRrecv.html#a851776d9178aeb706d9a1abd3f254e31',1,'IRrecv']]], + ['decodedoshisha_3784',['decodeDoshisha',['../classIRrecv.html#a675c45e6b32aaeca3de734ccf2f0c819',1,'IRrecv']]], + ['decodeelectraac_3785',['decodeElectraAC',['../classIRrecv.html#ad3a7be8afc36451c8e28e27f3c3e9aaa',1,'IRrecv']]], + ['decodeepson_3786',['decodeEpson',['../classIRrecv.html#aaadef8415f273ba25f4086fecd681d2e',1,'IRrecv']]], + ['decodefujitsuac_3787',['decodeFujitsuAC',['../classIRrecv.html#aa3778bdf994bf9c99ac48ef95434a826',1,'IRrecv']]], + ['decodegicable_3788',['decodeGICable',['../classIRrecv.html#afade8dac9b1d023e5e0946e6b2c08aea',1,'IRrecv']]], + ['decodegoodweather_3789',['decodeGoodweather',['../classIRrecv.html#a64650ce7dbaf5fc860a6a253d906e9de',1,'IRrecv']]], + ['decodegree_3790',['decodeGree',['../classIRrecv.html#a2e756342d7524a13d53d6c656700638c',1,'IRrecv']]], + ['decodehaierac_3791',['decodeHaierAC',['../classIRrecv.html#ad97403174f05197a7fa9a4a0107e3111',1,'IRrecv']]], + ['decodehaieracyrw02_3792',['decodeHaierACYRW02',['../classIRrecv.html#a281fb9d972fee75db49209c42f649822',1,'IRrecv']]], + ['decodehash_3793',['decodeHash',['../classIRrecv.html#a7c15fbfa7936ca474712a1953911fd06',1,'IRrecv']]], + ['decodehitachiac_3794',['decodeHitachiAC',['../classIRrecv.html#aa42facfffc0e304005272b6ddd4583c8',1,'IRrecv']]], + ['decodehitachiac1_3795',['decodeHitachiAC1',['../classIRrecv.html#a122e0dcbf14c90ec2d77399acce21459',1,'IRrecv']]], + ['decodehitachiac3_3796',['decodeHitachiAc3',['../classIRrecv.html#a113bc834eff00f55d5545ce3fa1ab203',1,'IRrecv']]], + ['decodehitachiac424_3797',['decodeHitachiAc424',['../classIRrecv.html#a01c3dda56d6d916076fa1affa2213129',1,'IRrecv']]], + ['decodeinax_3798',['decodeInax',['../classIRrecv.html#a94545c6a8da027b9cb0e23ecba4c29d8',1,'IRrecv']]], + ['decodejvc_3799',['decodeJVC',['../classIRrecv.html#a25ab71efc223a418e9630d8421f44bc9',1,'IRrecv']]], + ['decodekelvinator_3800',['decodeKelvinator',['../classIRrecv.html#a0ac82f20b48b2d71ee07eb392578b226',1,'IRrecv']]], + ['decodelasertag_3801',['decodeLasertag',['../classIRrecv.html#ae4af614a45ea65cb3304ef5bd7965122',1,'IRrecv']]], + ['decodelegopf_3802',['decodeLegoPf',['../classIRrecv.html#aea75ad0ba1d8fec33de16501940f2553',1,'IRrecv']]], + ['decodelg_3803',['decodeLG',['../classIRrecv.html#afe70015c36b1477a5de0c193163e13a7',1,'IRrecv']]], + ['decodelutron_3804',['decodeLutron',['../classIRrecv.html#a6093c4404a9a9d415c5bfeab5ec53be5',1,'IRrecv']]], + ['decodemagiquest_3805',['decodeMagiQuest',['../classIRrecv.html#a6f3bfcc6767484151dee758bcf94fb0b',1,'IRrecv']]], + ['decodemidea_3806',['decodeMidea',['../classIRrecv.html#a255b15601f7439a09ab5e77ad78816fb',1,'IRrecv']]], + ['decodemidea24_3807',['decodeMidea24',['../classIRrecv.html#a62a04019308b29ae2aea4b3a83ba9155',1,'IRrecv']]], + ['decodemitsubishi_3808',['decodeMitsubishi',['../classIRrecv.html#a6efe3be80f0ebef3ff94ed0e56c5c52a',1,'IRrecv']]], + ['decodemitsubishi112_3809',['decodeMitsubishi112',['../classIRrecv.html#ae0690ff3cb5a5cdcdb6a514bb7bf0cdd',1,'IRrecv']]], + ['decodemitsubishi136_3810',['decodeMitsubishi136',['../classIRrecv.html#a87b3ee57dbdf762a0e305ddd43eec629',1,'IRrecv']]], + ['decodemitsubishi2_3811',['decodeMitsubishi2',['../classIRrecv.html#a9514197850491a5b8c30ae9ffc89d895',1,'IRrecv']]], + ['decodemitsubishiac_3812',['decodeMitsubishiAC',['../classIRrecv.html#a942c5f41df5cbff32a8b7703673cb621',1,'IRrecv']]], + ['decodemitsubishiheavy_3813',['decodeMitsubishiHeavy',['../classIRrecv.html#aef9cedf79793806df4cc5376710781bc',1,'IRrecv']]], + ['decodemultibrackets_3814',['decodeMultibrackets',['../classIRrecv.html#af61afacc9865232643164ba824e665ab',1,'IRrecv']]], + ['decodemwm_3815',['decodeMWM',['../classIRrecv.html#a27518b5d792cdf3ab333b324f409f328',1,'IRrecv']]], + ['decodenec_3816',['decodeNEC',['../classIRrecv.html#a52b844f80df7f64edf9ce9cc189ac5b9',1,'IRrecv']]], + ['decodeneoclima_3817',['decodeNeoclima',['../classIRrecv.html#a4729ee949e533448b481ae33bbbf1adf',1,'IRrecv']]], + ['decodenikai_3818',['decodeNikai',['../classIRrecv.html#abbcbf5fc07d7e37d7724acc37bb5f592',1,'IRrecv']]], + ['decodepanasonic_3819',['decodePanasonic',['../classIRrecv.html#aa8dd5f24d28576c6db03cc463bd0a865',1,'IRrecv']]], + ['decodepanasonicac_3820',['decodePanasonicAC',['../classIRrecv.html#a0f78e180ed731e8fb16d1c85aa721c95',1,'IRrecv']]], + ['decodepioneer_3821',['decodePioneer',['../classIRrecv.html#a78a9487cbe8a562392a07a4090b3091e',1,'IRrecv']]], + ['decoderc5_3822',['decodeRC5',['../classIRrecv.html#adab9dffbeceee514520fababd0e721bd',1,'IRrecv']]], + ['decoderc6_3823',['decodeRC6',['../classIRrecv.html#a67316499ef37db82e3b3ecaac25c5980',1,'IRrecv']]], + ['decodercmm_3824',['decodeRCMM',['../classIRrecv.html#a0e7bf769cb5bebf174e852e4b0b08cf3',1,'IRrecv']]], + ['decodesamsung_3825',['decodeSAMSUNG',['../classIRrecv.html#a18b6cf177364faf11b9a076dd2025eec',1,'IRrecv']]], + ['decodesamsung36_3826',['decodeSamsung36',['../classIRrecv.html#a290a9e6a0b12ef1fe02a92a456c8ad57',1,'IRrecv']]], + ['decodesamsungac_3827',['decodeSamsungAC',['../classIRrecv.html#ae779c76ebd0f3cd1fc13abaa55f80d67',1,'IRrecv']]], + ['decodesanyolc7461_3828',['decodeSanyoLC7461',['../classIRrecv.html#a201a5a78f43c2ac216fae4a2ba4d14ec',1,'IRrecv']]], + ['decodesharp_3829',['decodeSharp',['../classIRrecv.html#a3390d63ba21a835d7c74c261532a22a7',1,'IRrecv']]], + ['decodesharpac_3830',['decodeSharpAc',['../classIRrecv.html#a8a9b920079f783e236f8a938e20b9743',1,'IRrecv']]], + ['decodesony_3831',['decodeSony',['../classIRrecv.html#ab03227955cf7d1d00c1620c55d7f9f18',1,'IRrecv']]], + ['decodesymphony_3832',['decodeSymphony',['../classIRrecv.html#a61cdf4d891654521afbc6ca9fb415745',1,'IRrecv']]], + ['decodeteco_3833',['decodeTeco',['../classIRrecv.html#a950711d7df8dfe4cda86f53650cd9f56',1,'IRrecv']]], + ['decodetoshibaac_3834',['decodeToshibaAC',['../classIRrecv.html#a01228e51ede905beac689967bb14b538',1,'IRrecv']]], + ['decodetostate_3835',['decodeToState',['../namespaceIRAcUtils.html#ac5eb498bf12cb6cba023c9c1e9726949',1,'IRAcUtils']]], + ['decodetrotec_3836',['decodeTrotec',['../classIRrecv.html#ae2920c488173f3fa37f5325438157ced',1,'IRrecv']]], + ['decodevestelac_3837',['decodeVestelAc',['../classIRrecv.html#a5d48b3c91434c18c7726cca504d75b73',1,'IRrecv']]], + ['decodewhirlpoolac_3838',['decodeWhirlpoolAC',['../classIRrecv.html#a0d1eec83cf092f5621cb34b3e94777c4',1,'IRrecv']]], + ['decodewhynter_3839',['decodeWhynter',['../classIRrecv.html#a66289f6a462557ad26e6c0a64f36cf02',1,'IRrecv']]], + ['decodezepeal_3840',['decodeZepeal',['../classIRrecv.html#a72afd857c8b2e0192021a40afc96c2d8',1,'IRrecv']]], + ['defaultbits_3841',['defaultBits',['../classIRsend.html#a70a2256bee8ad9b8ea8571dd4f26596f',1,'IRsend']]], + ['delonghiac_3842',['delonghiac',['../classIRac.html#af290b0b08cff5121bb88c62051ed1074',1,'IRac']]], + ['disableirin_3843',['disableIRIn',['../classIRrecv.html#a9f4a719e756ad78c7dd47186f8bef087',1,'IRrecv']]], + ['disableofftimer_3844',['disableOffTimer',['../classIRDaikinESP.html#a1e4e05ad0799002d0ab25db92dcaac06',1,'IRDaikinESP::disableOffTimer()'],['../classIRDaikin2.html#a6c8ad4c34713d61942c80b6052e6283a',1,'IRDaikin2::disableOffTimer()']]], + ['disableontimer_3845',['disableOnTimer',['../classIRDaikinESP.html#a0733e4a15d76baac23493926ef1765b1',1,'IRDaikinESP::disableOnTimer()'],['../classIRDaikin2.html#ab0e77969a86af9637cb9aa4b4befd4aa',1,'IRDaikin2::disableOnTimer()']]], + ['disablesleeptimer_3846',['disableSleepTimer',['../classIRDaikin2.html#a5461cf51967d3fe67489384c82daac47',1,'IRDaikin2']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.html new file mode 100644 index 000000000..61b920db6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.js new file mode 100644 index 000000000..17a079595 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.js @@ -0,0 +1,26 @@ +var searchData= +[ + ['elapsed_3847',['elapsed',['../classIRtimer.html#ad655e585f053580d49d8de7d52cd62a1',1,'IRtimer::elapsed()'],['../classTimerMs.html#ad4aa759c58727393f69863b3461dfc09',1,'TimerMs::elapsed()']]], + ['electra_3848',['electra',['../classIRac.html#abb847bd5e09feb293432b8a8cf0dd9de',1,'IRac']]], + ['enableirin_3849',['enableIRIn',['../classIRrecv.html#a52c05ec6d8f3dbfb75f21f3b4fe7be3d',1,'IRrecv']]], + ['enableirout_3850',['enableIROut',['../classIRsend.html#ab3b6d36c9b5d26c400526717d433ed2d',1,'IRsend']]], + ['enableofftimer_3851',['enableOffTimer',['../classIRDaikinESP.html#a8a5686066bfc86f1d7cc454e793d3357',1,'IRDaikinESP::enableOffTimer()'],['../classIRDaikin2.html#afc7ba7d7de2976e010a72778091d633a',1,'IRDaikin2::enableOffTimer()'],['../classIRWhirlpoolAc.html#abb1c3685d90d81b44e72050cd0e042f6',1,'IRWhirlpoolAc::enableOffTimer()']]], + ['enableontimer_3852',['enableOnTimer',['../classIRDaikinESP.html#aac4d0f5f60c9f4c41d3bb1e0f24bc4bc',1,'IRDaikinESP::enableOnTimer()'],['../classIRDaikin2.html#a91ec5f7c67cb87102a5eb030e0763b50',1,'IRDaikin2::enableOnTimer()'],['../classIRWhirlpoolAc.html#aa3edd58882cf4fc65172e490c9e0bb2e',1,'IRWhirlpoolAc::enableOnTimer()']]], + ['enablesleeptimer_3853',['enableSleepTimer',['../classIRDaikin2.html#a9c86782a98a54818ae92419eec5a060b',1,'IRDaikin2']]], + ['enabletimer_3854',['enableTimer',['../classIRWhirlpoolAc.html#ad07804318721bc5dd60f7322e02c9696',1,'IRWhirlpoolAc']]], + ['encodedoshisha_3855',['encodeDoshisha',['../classIRsend.html#a0522a2256e8358df715065530be6317d',1,'IRsend']]], + ['encodejvc_3856',['encodeJVC',['../classIRsend.html#a6303b991c0545443e7ccf63ba89dbf18',1,'IRsend']]], + ['encodelg_3857',['encodeLG',['../classIRsend.html#a109b67a68e7a33900cb5c5017ed4578b',1,'IRsend']]], + ['encodemagiquest_3858',['encodeMagiQuest',['../classIRsend.html#a4ee40126279dbde8bb02888115577563',1,'IRsend']]], + ['encodenec_3859',['encodeNEC',['../classIRsend.html#ab2e1ce918e4e06b955c3d2a089ce189c',1,'IRsend']]], + ['encodepanasonic_3860',['encodePanasonic',['../classIRsend.html#a8340497ae75f00c844e53dfc73700d9c',1,'IRsend']]], + ['encodepioneer_3861',['encodePioneer',['../classIRsend.html#ae0686829eba31587b71034a1c0495971',1,'IRsend']]], + ['encoderc5_3862',['encodeRC5',['../classIRsend.html#a88457fd4cc01d6e8097e04c022ede74a',1,'IRsend']]], + ['encoderc5x_3863',['encodeRC5X',['../classIRsend.html#ae760ef1be11f25f7a61237f96a8871d9',1,'IRsend']]], + ['encoderc6_3864',['encodeRC6',['../classIRsend.html#ac0e341462426ea146b944502a6d3fde0',1,'IRsend']]], + ['encodesamsung_3865',['encodeSAMSUNG',['../classIRsend.html#a4ab0579bd854306b2667de19207e4ffb',1,'IRsend']]], + ['encodesanyolc7461_3866',['encodeSanyoLC7461',['../classIRsend.html#a864bef0dc48f6af4b59057362906cf5d',1,'IRsend']]], + ['encodesharp_3867',['encodeSharp',['../classIRsend.html#a8f4c7a36380ba31155eba5ff8f5f631e',1,'IRsend']]], + ['encodesony_3868',['encodeSony',['../classIRsend.html#aa0aea2cb04f0a7ee9056f15fecfc08c3',1,'IRsend']]], + ['encodetime_3869',['encodeTime',['../classIRPanasonicAc.html#a0eee4ad6105d35ee6c34c4666174b04b',1,'IRPanasonicAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.html new file mode 100644 index 000000000..dc70a4a07 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.js new file mode 100644 index 000000000..5cf543885 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['fahrenheittocelsius_3870',['fahrenheitToCelsius',['../IRutils_8cpp.html#a83538e86145850c24b1c824723089502',1,'fahrenheitToCelsius(const float deg): IRutils.cpp'],['../IRutils_8h.html#a83538e86145850c24b1c824723089502',1,'fahrenheitToCelsius(const float deg): IRutils.cpp']]], + ['fanspeedtostring_3871',['fanspeedToString',['../classIRac.html#ab8d8a1ce5de8970c07c90fb41731e2e6',1,'IRac']]], + ['fixchecksum_3872',['fixChecksum',['../classIRPanasonicAc.html#aa40bef35000ddf6d14e286b3f2044897',1,'IRPanasonicAc']]], + ['fixup_3873',['fixup',['../classIRGreeAC.html#a5bbdcc83f9d49e32379cd27cad0ba130',1,'IRGreeAC::fixup()'],['../classIRKelvinatorAC.html#a389af589003c39794ae5d4bd572fa485',1,'IRKelvinatorAC::fixup()']]], + ['fujitsu_3874',['fujitsu',['../classIRac.html#a23cf80270562ca28ae1f1da2bbb559e7',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.html new file mode 100644 index 000000000..7de310677 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.js new file mode 100644 index 000000000..e0bde456f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.js @@ -0,0 +1,114 @@ +var searchData= +[ + ['get3d_3875',['get3D',['../classIRMitsubishiHeavy152Ac.html#ab55c9e587d472baf6a6d9cb61c733b08',1,'IRMitsubishiHeavy152Ac::get3D()'],['../classIRMitsubishiHeavy88Ac.html#ad5171595fef2360f50d7991897c40632',1,'IRMitsubishiHeavy88Ac::get3D()']]], + ['get8cheat_3876',['get8CHeat',['../classIRNeoclimaAc.html#aee5b855ce2decb455eaaceb6b4913368',1,'IRNeoclimaAc']]], + ['getbeep_3877',['getBeep',['../classIRDaikin2.html#ab6cc9737950ac0ab476bb240897902ec',1,'IRDaikin2::getBeep()'],['../classIRSamsungAc.html#ab13b10f80e8e1169f0b01239f357b3ba',1,'IRSamsungAc::getBeep()']]], + ['getbit_3878',['getBit',['../namespaceirutils.html#ac0756774b20e4f7c836abee466800ee6',1,'irutils::getBit(const uint64_t data, const uint8_t position, const uint8_t size)'],['../namespaceirutils.html#a27f90f74ed0b7af37c7bd8cd2a059dee',1,'irutils::getBit(const uint8_t data, const uint8_t position)']]], + ['getboost_3879',['getBoost',['../classIRDelonghiAc.html#abf9fd996c60573eca50b5e165cbcbf63',1,'IRDelonghiAc']]], + ['getbreeze_3880',['getBreeze',['../classIRSamsungAc.html#ad46fed65fb1375bf3a3940aa2cb311d5',1,'IRSamsungAc']]], + ['getbufsize_3881',['getBufSize',['../classIRrecv.html#a69ab02ea6823ccf18d1f6be87ca1b92e',1,'IRrecv']]], + ['getbutton_3882',['getButton',['../classIRHaierACYRW02.html#af4df303e5662aa63cba715ff49e09b75',1,'IRHaierACYRW02::getButton()'],['../classIRHitachiAc424.html#a32fa646e61cbaca805f33995344732cc',1,'IRHitachiAc424::getButton()'],['../classIRNeoclimaAc.html#a747fec9ea02220e6cf7465f5f9bb800a',1,'IRNeoclimaAc::getButton()']]], + ['getclean_3883',['getClean',['../classIRCoolixAC.html#a272f94ef641041835a650dd4fbdda7bf',1,'IRCoolixAC::getClean()'],['../classIRDaikin2.html#a7930bbca261f07ef1c129cd6a2c848b4',1,'IRDaikin2::getClean()'],['../classIRElectraAc.html#aa06b1246aaa3f25b239b50e395258b7a',1,'IRElectraAc::getClean()'],['../classIRFujitsuAC.html#a4bf872038fc175d1496eae25e9fcdce3',1,'IRFujitsuAC::getClean()'],['../classIRMitsubishiHeavy152Ac.html#a8e7c2759efe24e580d5886600f513648',1,'IRMitsubishiHeavy152Ac::getClean()'],['../classIRMitsubishiHeavy88Ac.html#a54eafb2474559371393c3ec3ba560d3a',1,'IRMitsubishiHeavy88Ac::getClean()'],['../classIRSamsungAc.html#a789edd6c6b0cb291753204d1e9c78fc8',1,'IRSamsungAc::getClean()'],['../classIRSharpAc.html#a599032d1101f15b98ffa9aa3039bc7d6',1,'IRSharpAc::getClean()']]], + ['getclock_3884',['getClock',['../classIRDaikin128.html#a6ef4d58f53b35619e8cc44fae6125490',1,'IRDaikin128::getClock()'],['../classIRDaikin64.html#a676ecda2ad53f78ef5cbf470f524918e',1,'IRDaikin64::getClock()'],['../classIRMitsubishiAC.html#a8918c5b8a72d58282b160c8fde9866ad',1,'IRMitsubishiAC::getClock()'],['../classIRPanasonicAc.html#a084479e8f23f7dbb8f155209b36efb3b',1,'IRPanasonicAc::getClock()'],['../classIRWhirlpoolAc.html#a329e06f4c44fa9aef42952f2d123b7a8',1,'IRWhirlpoolAc::getClock()']]], + ['getcmd_3885',['getCmd',['../classIRFujitsuAC.html#a758d209fd0e07cb200b2d4a232b6b0a2',1,'IRFujitsuAC']]], + ['getcomfort_3886',['getComfort',['../classIRDaikinESP.html#a4377e48a16a6ed1cb4fb2b711e672b16',1,'IRDaikinESP::getComfort()'],['../classIRDaikin152.html#a22cc2073fd7d4a609c335172ff6720cf',1,'IRDaikin152::getComfort()']]], + ['getcommand_3887',['getCommand',['../classIRGoodweatherAc.html#aa2a24e8c783cb5b463a95fa05779456e',1,'IRGoodweatherAc::getCommand()'],['../classIRHaierAC.html#a3a291fccea5f4b32f83da2605d2a82e0',1,'IRHaierAC::getCommand()'],['../classIRWhirlpoolAc.html#ab1c34a9498bc2c8da8e4bdcfe4bf011a',1,'IRWhirlpoolAc::getCommand()']]], + ['getcorrectedrawlength_3888',['getCorrectedRawLength',['../IRutils_8cpp.html#aad5f25cf6a2dded8b48f4a6dd16857be',1,'getCorrectedRawLength(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#aad5f25cf6a2dded8b48f4a6dd16857be',1,'getCorrectedRawLength(const decode_results *const results): IRutils.cpp']]], + ['getcurrentday_3889',['getCurrentDay',['../classIRDaikinESP.html#ad0ecc69b2ab3e7678c8e4e8d64949077',1,'IRDaikinESP']]], + ['getcurrenttime_3890',['getCurrentTime',['../classIRDaikinESP.html#a724c204890e6810d150ed54794c9a505',1,'IRDaikinESP::getCurrentTime()'],['../classIRDaikin2.html#a94dc89b80dfdee2afa718314ec522b53',1,'IRDaikin2::getCurrentTime()']]], + ['getcurrtime_3891',['getCurrTime',['../classIRHaierAC.html#aa0e05983088035f6d85c520843922c25',1,'IRHaierAC']]], + ['getdisplay_3892',['getDisplay',['../classIRSamsungAc.html#a890aa3cab0918fda56daf0bf84ecc5c1',1,'IRSamsungAc']]], + ['getdisplaytempsource_3893',['getDisplayTempSource',['../classIRGreeAC.html#adea5a2d2b3a9d699c722e7a93784809e',1,'IRGreeAC']]], + ['getecono_3894',['getEcono',['../classIRCoronaAc.html#a0b8413e2a7aeecc5c0c55049c1705c38',1,'IRCoronaAc::getEcono()'],['../classIRDaikinESP.html#a84337719e737ea4dc1e1fb10f6f7df92',1,'IRDaikinESP::getEcono()'],['../classIRDaikin2.html#ad8098fa67e8808eebfad7611b6fc7881',1,'IRDaikin2::getEcono()'],['../classIRDaikin128.html#a0c05f4c6f996d56d56075e20a46f2c2c',1,'IRDaikin128::getEcono()'],['../classIRDaikin152.html#a9946c73f0c5906fbb2f39119e00531e5',1,'IRDaikin152::getEcono()'],['../classIRMitsubishiHeavy152Ac.html#aa7814232c84ff918f1d05ec105abf851',1,'IRMitsubishiHeavy152Ac::getEcono()'],['../classIRMitsubishiHeavy88Ac.html#af3accae413215cdd45a180f22bbe443e',1,'IRMitsubishiHeavy88Ac::getEcono()'],['../classIRTcl112Ac.html#afabe458a354d822f3ff929a461b6e046',1,'IRTcl112Ac::getEcono()']]], + ['geteconotoggle_3895',['getEconoToggle',['../classIRSharpAc.html#a701542019d3a823ba203f0db3cfce353',1,'IRSharpAc']]], + ['geteye_3896',['getEye',['../classIRDaikin2.html#a02fbd472d3c79b2391fc11da692c8998',1,'IRDaikin2::getEye()'],['../classIRNeoclimaAc.html#a15b91e2c854537d94cbabd7cd9bd30e4',1,'IRNeoclimaAc::getEye()']]], + ['geteyeauto_3897',['getEyeAuto',['../classIRDaikin2.html#a0cae45648292bdee8092a30338975ed0',1,'IRDaikin2']]], + ['getfan_3898',['getFan',['../classIRAmcorAc.html#a8ba84d83fc426ee5b75e0be27fd22d9c',1,'IRAmcorAc::getFan()'],['../classIRArgoAC.html#a413e60e09f1abcf231a173e1374e51e0',1,'IRArgoAC::getFan()'],['../classIRCarrierAc64.html#a93bb27688657af434d57f0dd9a159566',1,'IRCarrierAc64::getFan()'],['../classIRCoolixAC.html#a937c0084f79eaef2a160331993dfb881',1,'IRCoolixAC::getFan()'],['../classIRCoronaAc.html#aa51ccd3684009d5a56bbde73eab7ccfa',1,'IRCoronaAc::getFan()'],['../classIRDaikinESP.html#addad5838bb00885df8af258a61fa4131',1,'IRDaikinESP::getFan()'],['../classIRDaikin2.html#aafe89842b356c288dd38d256f9eb050c',1,'IRDaikin2::getFan()'],['../classIRDaikin216.html#a0905e04fc3d21249b057aa79721c1614',1,'IRDaikin216::getFan()'],['../classIRDaikin160.html#a2eb3987f87d19e1ab01dac111ae2d16b',1,'IRDaikin160::getFan()'],['../classIRDaikin176.html#a59c3d23a5e1b7c69c05690cf7984dab8',1,'IRDaikin176::getFan()'],['../classIRDaikin128.html#a68a7bdb134ea62913f51844f976beab1',1,'IRDaikin128::getFan()'],['../classIRDaikin152.html#a64eacdc63547026477b5f861e7da62ea',1,'IRDaikin152::getFan()'],['../classIRDaikin64.html#abdd4bc3d5464b5297b4f2fd0e7a831e1',1,'IRDaikin64::getFan()'],['../classIRDelonghiAc.html#afd2ed0ec70e3912335a9174bca7e7f5e',1,'IRDelonghiAc::getFan()'],['../classIRElectraAc.html#a6e8b30452671c26777ba2bc556bc8dce',1,'IRElectraAc::getFan()'],['../classIRGoodweatherAc.html#ac1ac922370ad09a80dd4e7158b279b9f',1,'IRGoodweatherAc::getFan()'],['../classIRGreeAC.html#a0bf5a552490c7500f0584affacac13d0',1,'IRGreeAC::getFan()'],['../classIRHaierAC.html#a5b15678e94acc14a0bb86bff61230e93',1,'IRHaierAC::getFan()'],['../classIRHaierACYRW02.html#a6de2fb6111049720913eb28bf6f64a00',1,'IRHaierACYRW02::getFan()'],['../classIRHitachiAc.html#a6a5f5b9544e93e842f76a2f4994c1665',1,'IRHitachiAc::getFan()'],['../classIRHitachiAc1.html#af1c6acc2ff9946af7091695b616c2cac',1,'IRHitachiAc1::getFan()'],['../classIRHitachiAc424.html#ab3ecfb8b6fb503ba3eed023609f2fe7b',1,'IRHitachiAc424::getFan()'],['../classIRKelvinatorAC.html#a64ce2ccf879217410269230218e0c76b',1,'IRKelvinatorAC::getFan()'],['../classIRLgAc.html#a10d666ca13c99696a53dca7f5773d7de',1,'IRLgAc::getFan()'],['../classIRMideaAC.html#ab793e409c666e001242623a2607786e7',1,'IRMideaAC::getFan()'],['../classIRMitsubishiAC.html#a06cb4179b92af1b1d3c167659c30db95',1,'IRMitsubishiAC::getFan()'],['../classIRMitsubishi136.html#a61b0a21a32eb1211cab201587de6f7ce',1,'IRMitsubishi136::getFan()'],['../classIRMitsubishi112.html#a00446fe1fdf27012acd41303b711e575',1,'IRMitsubishi112::getFan()'],['../classIRMitsubishiHeavy152Ac.html#a957abe79b7966da644db091ffe75d73b',1,'IRMitsubishiHeavy152Ac::getFan()'],['../classIRMitsubishiHeavy88Ac.html#ac00255061012eef8d62f44e478839d7e',1,'IRMitsubishiHeavy88Ac::getFan()'],['../classIRNeoclimaAc.html#a8690eda2de7b00029f70304131388890',1,'IRNeoclimaAc::getFan()'],['../classIRPanasonicAc.html#a302ba64400c820a5a0d822315516564a',1,'IRPanasonicAc::getFan()'],['../classIRSamsungAc.html#a6461c72b2598d1bdc14263552b5b0c98',1,'IRSamsungAc::getFan()'],['../classIRSharpAc.html#abae439959603f62b0fe5aea8ec93afb5',1,'IRSharpAc::getFan()'],['../classIRTcl112Ac.html#af59bcc28ac97869595a5ad928300908b',1,'IRTcl112Ac::getFan()'],['../classIRTecoAc.html#a420b209010276b30c9bc322b7393b3be',1,'IRTecoAc::getFan()'],['../classIRToshibaAC.html#afd2000b62b79afde107ebc8a513724ab',1,'IRToshibaAC::getFan()'],['../classIRVestelAc.html#a492abc867ad5b766715eaa301c71f3c8',1,'IRVestelAc::getFan()'],['../classIRWhirlpoolAc.html#a80fedb2ddec4a3dbb2c96b5a76a26e1a',1,'IRWhirlpoolAc::getFan()']]], + ['getfanspeed_3899',['getFanSpeed',['../classIRFujitsuAC.html#aacb180bb884b80c1f8bbbed7e2dd23d5',1,'IRFujitsuAC']]], + ['getfilter_3900',['getFilter',['../classIRFujitsuAC.html#a430ed6a4b946d1b4527741b42e12a25c',1,'IRFujitsuAC::getFilter()'],['../classIRMitsubishiHeavy152Ac.html#aaf2864f7187acd1b75d9daad2d504c13',1,'IRMitsubishiHeavy152Ac::getFilter()']]], + ['getflap_3901',['getFlap',['../classIRArgoAC.html#a2285908626731c2feaa85635f3ce1ff1',1,'IRArgoAC']]], + ['getfollow_3902',['getFollow',['../classIRNeoclimaAc.html#af4ed34fe7b151bcc5ff6922a54427da0',1,'IRNeoclimaAc']]], + ['getfresh_3903',['getFresh',['../classIRNeoclimaAc.html#a2c411cf55667339ff8e3664a6d0ee843',1,'IRNeoclimaAc']]], + ['getfreshair_3904',['getFreshAir',['../classIRDaikin2.html#aad50061042e14f665e5ecbd85ac48741',1,'IRDaikin2']]], + ['getfreshairhigh_3905',['getFreshAirHigh',['../classIRDaikin2.html#a72c8d47c2e6664eb0e40efe6933e4ac1',1,'IRDaikin2']]], + ['gethealth_3906',['getHealth',['../classIRHaierAC.html#a5c69955fe18f4ddb0286084f3fb39228',1,'IRHaierAC::getHealth()'],['../classIRHaierACYRW02.html#a97fc67cddf50a51b0db6c4e22fcaafa1',1,'IRHaierACYRW02::getHealth()'],['../classIRTcl112Ac.html#adf484b6a4097dd8834c202c81fea0ad4',1,'IRTcl112Ac::getHealth()']]], + ['gethold_3907',['getHold',['../classIRNeoclimaAc.html#a63045d768858265ed1bbc4c337de79eb',1,'IRNeoclimaAc']]], + ['gethumid_3908',['getHumid',['../classIRTecoAc.html#a30012508c6ba93ad07185a13795c5909',1,'IRTecoAc']]], + ['getifeel_3909',['getiFeel',['../classIRArgoAC.html#abc802d8ab9dbd9f918bc2aa36d2ea414',1,'IRArgoAC::getiFeel()'],['../classIRGreeAC.html#ae1f8352fc32fa773bb33243cc32657a2',1,'IRGreeAC::getIFeel()']]], + ['getion_3910',['getIon',['../classIRNeoclimaAc.html#a908a65189ba6eb8141d50da000feec0a',1,'IRNeoclimaAc::getIon()'],['../classIRPanasonicAc.html#a6d6909b7b96815c227f0009dcbd3ce8c',1,'IRPanasonicAc::getIon()'],['../classIRSamsungAc.html#aab1ebb523ca45431a0127b82cb4ce36f',1,'IRSamsungAc::getIon()'],['../classIRSharpAc.html#a1de89912129d0a1fffbd51625a1eeab7',1,'IRSharpAc::getIon()'],['../classIRVestelAc.html#a835f194f14479c25a3d651f324e6436c',1,'IRVestelAc::getIon()']]], + ['getionfilter_3911',['getIonFilter',['../classIRKelvinatorAC.html#a81127edca40e504c432b2079030f84a5',1,'IRKelvinatorAC']]], + ['getled_3912',['getLed',['../classIRCoolixAC.html#aa7712ebbf103c4d61dc645cb42dcf3f0',1,'IRCoolixAC']]], + ['getlight_3913',['getLight',['../classIRDaikin2.html#ada92da390d8b4247a014057c3d6fa296',1,'IRDaikin2::getLight()'],['../classIRGoodweatherAc.html#a90454990d7f9cde54ab5a11170d5e97d',1,'IRGoodweatherAc::getLight()'],['../classIRGreeAC.html#ae63281a9caf850429857cc3fa99ccf05',1,'IRGreeAC::getLight()'],['../classIRKelvinatorAC.html#a85e77c7a1b763373b0732d125923f53f',1,'IRKelvinatorAC::getLight()'],['../classIRNeoclimaAc.html#ad87fc87e34c3de56c4bbe35443e92226',1,'IRNeoclimaAc::getLight()'],['../classIRTcl112Ac.html#ae711a585331ffab24f96b0bb0f3960ed',1,'IRTcl112Ac::getLight()'],['../classIRTecoAc.html#a12a2bb7a5d3c90139dba85d54a535b8f',1,'IRTecoAc::getLight()'],['../classIRWhirlpoolAc.html#a87f2274da6101e1c2e78eb4e68aadff0',1,'IRWhirlpoolAc::getLight()']]], + ['getlighttoggle_3914',['getLightToggle',['../classIRDaikin128.html#a3e279e67bbafc0dc74dbd847e2e8ad75',1,'IRDaikin128::getLightToggle()'],['../classIRElectraAc.html#a63bc44235b18e11531479dc2f633f94b',1,'IRElectraAc::getLightToggle()']]], + ['getmax_3915',['getMax',['../classIRAmcorAc.html#a61659b6b54d652713efdf408a09db087',1,'IRAmcorAc::getMax()'],['../classIRArgoAC.html#aff24da9d975bf1f6df0a83be2ad7a913',1,'IRArgoAC::getMax()']]], + ['getmode_3916',['getMode',['../classIRAmcorAc.html#a30fd2a228e63e6b9a1544c3c1ec910f7',1,'IRAmcorAc::getMode()'],['../classIRArgoAC.html#a532a313f22c716b60cee070d9ba0839d',1,'IRArgoAC::getMode()'],['../classIRCarrierAc64.html#a4f8e0435a086ec934b10e9bd66f2ae85',1,'IRCarrierAc64::getMode()'],['../classIRCoolixAC.html#a16772a297404e2c54f951c49bfc608de',1,'IRCoolixAC::getMode()'],['../classIRCoronaAc.html#aa6ccd147a1da55d5e9596159008d40de',1,'IRCoronaAc::getMode()'],['../classIRDaikinESP.html#a164452703a7a6d46766acc85aab63898',1,'IRDaikinESP::getMode()'],['../classIRDaikin2.html#a681279a765159550ac1ec84895fff4d2',1,'IRDaikin2::getMode()'],['../classIRDaikin216.html#a21b3e93f98ac55e743efe38c20617d6a',1,'IRDaikin216::getMode()'],['../classIRDaikin160.html#a2b890fe446db67acd828fefd4afef84f',1,'IRDaikin160::getMode()'],['../classIRDaikin176.html#a1fc59660d77eb9dc3a8361d7d4698cd9',1,'IRDaikin176::getMode()'],['../classIRDaikin128.html#aa3d96e14663c498a6e0938ba04a02f87',1,'IRDaikin128::getMode()'],['../classIRDaikin152.html#af4c6c468f3075ffa83694a0da15a707b',1,'IRDaikin152::getMode()'],['../classIRDaikin64.html#a96624667a4494087074792562090b552',1,'IRDaikin64::getMode()'],['../classIRDelonghiAc.html#a89d9fa5b2c4a59b46cac111418232090',1,'IRDelonghiAc::getMode()'],['../classIRElectraAc.html#a473a794960bc07837e407830a3ea528b',1,'IRElectraAc::getMode()'],['../classIRFujitsuAC.html#a5f9630d81acffc74434ce852b9523d17',1,'IRFujitsuAC::getMode()'],['../classIRGoodweatherAc.html#a622e11c7b236fa127008f990819eca75',1,'IRGoodweatherAc::getMode()'],['../classIRGreeAC.html#abb5c4a29000c8b22b25e150e7ef5a6c3',1,'IRGreeAC::getMode()'],['../classIRHaierAC.html#aa180c60030d9972807238cceba886ff5',1,'IRHaierAC::getMode()'],['../classIRHaierACYRW02.html#aec7359fb8c796fc45577a40370f874c9',1,'IRHaierACYRW02::getMode()'],['../classIRHitachiAc.html#a414a4083e15deb1890a1eab4827d78ac',1,'IRHitachiAc::getMode()'],['../classIRHitachiAc1.html#afc4fdc94989297b73e08e9c82bd00733',1,'IRHitachiAc1::getMode()'],['../classIRHitachiAc424.html#ac1bf6df8277d50dcad8e389b21971e24',1,'IRHitachiAc424::getMode()'],['../classIRHitachiAc3.html#a511c9b731a0367fd05b32b42a69adec2',1,'IRHitachiAc3::getMode()'],['../classIRKelvinatorAC.html#a7a0f8f587fdda24db12db7aace478fd6',1,'IRKelvinatorAC::getMode()'],['../classIRLgAc.html#a19752b31eb74aad0cc9538a2f0af8b8c',1,'IRLgAc::getMode()'],['../classIRMideaAC.html#a1b5d19958e11a85d1af09b15631af124',1,'IRMideaAC::getMode()'],['../classIRMitsubishiAC.html#a069fd1d3bea102968e74b312fdf01548',1,'IRMitsubishiAC::getMode()'],['../classIRMitsubishi136.html#a3176aec8444f500bdea6e650cee2dbcc',1,'IRMitsubishi136::getMode()'],['../classIRMitsubishi112.html#ac2006f1e33f2a0cebcb6c23fcac389bb',1,'IRMitsubishi112::getMode()'],['../classIRMitsubishiHeavy152Ac.html#af0a51f8195492aac62bea483cb9a392c',1,'IRMitsubishiHeavy152Ac::getMode()'],['../classIRMitsubishiHeavy88Ac.html#ae8e1263a77b8fb04c2a4a5d6ce9805f9',1,'IRMitsubishiHeavy88Ac::getMode()'],['../classIRNeoclimaAc.html#ad2a43e0405a44787bb177bf13a324dde',1,'IRNeoclimaAc::getMode()'],['../classIRPanasonicAc.html#a5ffd59dd87b047e172ba74866267a9f3',1,'IRPanasonicAc::getMode()'],['../classIRSamsungAc.html#a740a874ee2c492027623943043a1ebf6',1,'IRSamsungAc::getMode()'],['../classIRSharpAc.html#adbccabd2ec614c8b921a02af8b529b4e',1,'IRSharpAc::getMode()'],['../classIRTcl112Ac.html#ad1b6538977bc464f1e6719b5cea89945',1,'IRTcl112Ac::getMode()'],['../classIRTecoAc.html#a4200081a4d42f2ec06935f71c4870e67',1,'IRTecoAc::getMode()'],['../classIRToshibaAC.html#aba5db1f6c8665443f26875ee9716302f',1,'IRToshibaAC::getMode()'],['../classIRTrotecESP.html#ab1b08911e9b76a06a08f4c7b8a2244c0',1,'IRTrotecESP::getMode()'],['../classIRVestelAc.html#ae5b3d9f1420f4d1951ba148399ccbd41',1,'IRVestelAc::getMode()'],['../classIRWhirlpoolAc.html#a4d2896e42e9c5ee1e8dc8f7e917618dc',1,'IRWhirlpoolAc::getMode()']]], + ['getmodel_3917',['getModel',['../classIRFujitsuAC.html#a35c6bfb730014f3a24676f94e8308163',1,'IRFujitsuAC::getModel()'],['../classIRGreeAC.html#a3780fc11488a2b40f3c1a50bb94783c7',1,'IRGreeAC::getModel()'],['../classIRHitachiAc1.html#a9ad677e1a2d7acba032701051538b08a',1,'IRHitachiAc1::getModel()'],['../classIRLgAc.html#aa49cde438a42a5415e127cc95da465ac',1,'IRLgAc::getModel()'],['../classIRPanasonicAc.html#a625be846baf3ec556a59379785e642e8',1,'IRPanasonicAc::getModel()'],['../classIRWhirlpoolAc.html#ac55e17fde1ef2acf6524d936732a0469',1,'IRWhirlpoolAc::getModel()']]], + ['getmold_3918',['getMold',['../classIRDaikinESP.html#ad593ac32c01752f56e9476af234cf813',1,'IRDaikinESP::getMold()'],['../classIRDaikin2.html#a330b3a8f25bd2d053dab318126b32569',1,'IRDaikin2::getMold()']]], + ['getnight_3919',['getNight',['../classIRArgoAC.html#adca87781240cf9c22e6bbaad9d59537c',1,'IRArgoAC::getNight()'],['../classIRMitsubishiHeavy152Ac.html#a659036b987991f39daa13fbd23b35f35',1,'IRMitsubishiHeavy152Ac::getNight()']]], + ['getnormalstate_3920',['getNormalState',['../classIRCoolixAC.html#a458618f926f8b57e4b9bdeae0d13a70d',1,'IRCoolixAC']]], + ['getofftime_3921',['getOffTime',['../classIRDaikinESP.html#a5213017d706cd6bce88cbfb65150bdb5',1,'IRDaikinESP::getOffTime()'],['../classIRDaikin2.html#af3a47c7b99cec3b108b5173cf1ae7da4',1,'IRDaikin2::getOffTime()'],['../classIRDaikin64.html#a7f163901c3b5065e393e3ae0e01d599a',1,'IRDaikin64::getOffTime()']]], + ['getofftimeenabled_3922',['getOffTimeEnabled',['../classIRDaikin64.html#a9ebf2deb196caece88c286d8c03bb69a',1,'IRDaikin64']]], + ['getofftimer_3923',['getOffTimer',['../classIRCarrierAc64.html#a6a28f83442d695385f76f13913c76542',1,'IRCarrierAc64::getOffTimer()'],['../classIRCoronaAc.html#a4602f36769e6b135fec8802a3b087adf',1,'IRCoronaAc::getOffTimer()'],['../classIRDaikin128.html#a6a18b029d75b006de5aeac2efb8e08e2',1,'IRDaikin128::getOffTimer()'],['../classIRDelonghiAc.html#acd32fa9acbc9782df9aa00325efea2a7',1,'IRDelonghiAc::getOffTimer()'],['../classIRHaierAC.html#a8b5c970b3204aa447d86dc2941dbd7b1',1,'IRHaierAC::getOffTimer()'],['../classIRHitachiAc1.html#ab99d73871d3510a830f988628dc5e33d',1,'IRHitachiAc1::getOffTimer()'],['../classIRPanasonicAc.html#a4bce377d32504f666662f1d93645761f',1,'IRPanasonicAc::getOffTimer()'],['../classIRVestelAc.html#a575ba7c6aee1d2377975ef0ef938775a',1,'IRVestelAc::getOffTimer()'],['../classIRWhirlpoolAc.html#a05e1308970e0169d6a081baf120efd9f',1,'IRWhirlpoolAc::getOffTimer()']]], + ['getofftimerenabled_3924',['getOffTimerEnabled',['../classIRDaikinESP.html#af6388cd6d2189f9067b708d46917a83a',1,'IRDaikinESP::getOffTimerEnabled()'],['../classIRDaikin2.html#a7a413002b64497a5fce7cdcdd6924e8f',1,'IRDaikin2::getOffTimerEnabled()'],['../classIRDaikin128.html#a4234e0e3ff261afa9d5ec6a8b92d8f53',1,'IRDaikin128::getOffTimerEnabled()'],['../classIRDelonghiAc.html#ac1b91f6d4bb5e41e43fc7e4b9a3187a3',1,'IRDelonghiAc::getOffTimerEnabled()']]], + ['getontime_3925',['getOnTime',['../classIRDaikinESP.html#a8a6730accc69647cbc12ebc99b2cfb77',1,'IRDaikinESP::getOnTime()'],['../classIRDaikin2.html#ad62f28698595be7717f0f29a5396853d',1,'IRDaikin2::getOnTime()'],['../classIRDaikin64.html#a9b316390ffc3e81d423d3e4b326be7d4',1,'IRDaikin64::getOnTime()']]], + ['getontimeenabled_3926',['getOnTimeEnabled',['../classIRDaikin64.html#a0b9795a5536566fe2f9b713aaff4b9ee',1,'IRDaikin64']]], + ['getontimer_3927',['getOnTimer',['../classIRCarrierAc64.html#a071ebd204e56e2cd771281b1c42b9cb5',1,'IRCarrierAc64::getOnTimer()'],['../classIRCoronaAc.html#a7beec38ab35dbebe955c4da188de25d5',1,'IRCoronaAc::getOnTimer()'],['../classIRDaikin128.html#a3b8a36d99a7cbf87bac8480f16c3d583',1,'IRDaikin128::getOnTimer()'],['../classIRDelonghiAc.html#a03f6d037d62d3c641b45ec97a1bff715',1,'IRDelonghiAc::getOnTimer()'],['../classIRHaierAC.html#a99d3339eb5ecdbf1c86e85408507af7b',1,'IRHaierAC::getOnTimer()'],['../classIRHitachiAc1.html#a9d5846c1efcc8fae1eeb6079a61cb18b',1,'IRHitachiAc1::getOnTimer()'],['../classIRPanasonicAc.html#a51d50a59e09f0911022c59ab60bf4889',1,'IRPanasonicAc::getOnTimer()'],['../classIRVestelAc.html#aa39e3047ea694ada9cc7e992e7b03e32',1,'IRVestelAc::getOnTimer()'],['../classIRWhirlpoolAc.html#a26c00db3316585e32d64428d6732fcd0',1,'IRWhirlpoolAc::getOnTimer()']]], + ['getontimerenabled_3928',['getOnTimerEnabled',['../classIRDaikinESP.html#a45e473403547c8ec95a50aeb1ed93607',1,'IRDaikinESP::getOnTimerEnabled()'],['../classIRDaikin2.html#a8921edb7885d728ee5294fa03cb13a87',1,'IRDaikin2::getOnTimerEnabled()'],['../classIRDaikin128.html#a450948bdbdc22da751c8f1abc2da642d',1,'IRDaikin128::getOnTimerEnabled()'],['../classIRDelonghiAc.html#a0911f40ee5838bfc6b7deb3193e6a62a',1,'IRDelonghiAc::getOnTimerEnabled()']]], + ['getoutsidequiet_3929',['getOutsideQuiet',['../classIRFujitsuAC.html#a404a06b5022899e622e629ec099864f5',1,'IRFujitsuAC']]], + ['getpower_3930',['getPower',['../classIRAmcorAc.html#a141e2af9eb4530b175a430dee31bc5ae',1,'IRAmcorAc::getPower()'],['../classIRArgoAC.html#a10812d30095c4adc24cb3eee25e2d246',1,'IRArgoAC::getPower()'],['../classIRCarrierAc64.html#ad50ebb44815e55cc0a99f4762939dc54',1,'IRCarrierAc64::getPower()'],['../classIRCoolixAC.html#a150e3b827d8002e77135955079c78704',1,'IRCoolixAC::getPower()'],['../classIRCoronaAc.html#a313c5489b53bba5747e871ec0a7af417',1,'IRCoronaAc::getPower()'],['../classIRDaikinESP.html#a1d72647db12276493d8e093a4feda44e',1,'IRDaikinESP::getPower()'],['../classIRDaikin2.html#a2f25c4ff097f82a91c062aacd5ebabfc',1,'IRDaikin2::getPower()'],['../classIRDaikin216.html#a2b1e1dd2a059466ab5e5c8ab7eb4f2b4',1,'IRDaikin216::getPower()'],['../classIRDaikin160.html#ad472f0d0680da6ab83a1b636bc00e271',1,'IRDaikin160::getPower()'],['../classIRDaikin176.html#ad564616fc1bf90c00c594c2d3cb5394d',1,'IRDaikin176::getPower()'],['../classIRDaikin152.html#a8581147072fecf6ebd0dd2da50a63f05',1,'IRDaikin152::getPower()'],['../classIRDelonghiAc.html#ae077f0e444fcf24b1e0343e93244b7e8',1,'IRDelonghiAc::getPower()'],['../classIRElectraAc.html#aed11407cd8be470baf5d4667e28e1273',1,'IRElectraAc::getPower()'],['../classIRFujitsuAC.html#a5d03a83db8bc2084ae2acea17c2c7ae2',1,'IRFujitsuAC::getPower()'],['../classIRGoodweatherAc.html#a6f7db9f499c4fea860976bb273ba15df',1,'IRGoodweatherAc::getPower()'],['../classIRGreeAC.html#ac2c97551e02c6cce1b9983cc902f5f1a',1,'IRGreeAC::getPower()'],['../classIRHaierACYRW02.html#a446ee5873e80fa474d322ca5ff598fb5',1,'IRHaierACYRW02::getPower()'],['../classIRHitachiAc.html#a3be8c7ded012c2ad5cab59ee6fe3c88e',1,'IRHitachiAc::getPower()'],['../classIRHitachiAc1.html#ab4756a44153997ff686e8a14369407c0',1,'IRHitachiAc1::getPower()'],['../classIRHitachiAc424.html#ae4d3370d89253ec0861a60b84b2d078c',1,'IRHitachiAc424::getPower()'],['../classIRKelvinatorAC.html#a3dc660afab763c9a4b0cfc5d8e14d220',1,'IRKelvinatorAC::getPower()'],['../classIRLgAc.html#ac09b8af7cc2d46881d3a710068acb5bd',1,'IRLgAc::getPower()'],['../classIRMideaAC.html#a2035653f3ac503a8d30563fded46cab2',1,'IRMideaAC::getPower()'],['../classIRMitsubishiAC.html#aa5fb3f328b6c8a553d25088ec9e858d7',1,'IRMitsubishiAC::getPower()'],['../classIRMitsubishi136.html#a371faf10c80560e1ad59c70d66147723',1,'IRMitsubishi136::getPower()'],['../classIRMitsubishi112.html#afb9ea09a7a9724410470944f6decaeed',1,'IRMitsubishi112::getPower()'],['../classIRMitsubishiHeavy152Ac.html#a1e1d742e255685d1b16935d6031b25fc',1,'IRMitsubishiHeavy152Ac::getPower()'],['../classIRMitsubishiHeavy88Ac.html#a05c50ad07ba7be443414792c7e585354',1,'IRMitsubishiHeavy88Ac::getPower()'],['../classIRNeoclimaAc.html#a635e81f673155eb123dab84a78ff86d5',1,'IRNeoclimaAc::getPower()'],['../classIRPanasonicAc.html#a2d50ed3994f6cc6e205d2c5fb6c0cc55',1,'IRPanasonicAc::getPower()'],['../classIRSamsungAc.html#a26fb214fdf3af4d39a898a1721583cf3',1,'IRSamsungAc::getPower()'],['../classIRSharpAc.html#a49c6c86c901a8d02d7a0d67bfcc397af',1,'IRSharpAc::getPower()'],['../classIRTcl112Ac.html#a36e3b74c79ec42a0922893a3ccd5d045',1,'IRTcl112Ac::getPower()'],['../classIRTecoAc.html#a66c39da54baa6d0c56418ff8027a12a6',1,'IRTecoAc::getPower()'],['../classIRToshibaAC.html#a6d69c147e786aa642906f24c9781bb0f',1,'IRToshibaAC::getPower()'],['../classIRTrotecESP.html#a2e303fe918f79281df98cffb9d2cd539',1,'IRTrotecESP::getPower()'],['../classIRVestelAc.html#a1d6cdc9ad13ebbf1e9a4a83f95244ced',1,'IRVestelAc::getPower()']]], + ['getpowerbutton_3931',['getPowerButton',['../classIRCoronaAc.html#ae38a9860cc3fe73909ba20260ad9a51a',1,'IRCoronaAc']]], + ['getpowerful_3932',['getPowerful',['../classIRDaikinESP.html#a827c3dc88027b043271a469bc41c4bb1',1,'IRDaikinESP::getPowerful()'],['../classIRDaikin2.html#abad28f7287f4d90d196eb0eb7f93ed43',1,'IRDaikin2::getPowerful()'],['../classIRDaikin216.html#acf94e292df8f45233e115324a95a5e83',1,'IRDaikin216::getPowerful()'],['../classIRDaikin128.html#a50f2de409b3e8966f8406b659aaaedac',1,'IRDaikin128::getPowerful()'],['../classIRDaikin152.html#a20ec24a0ef288cabb93080b4fa0f71fe',1,'IRDaikin152::getPowerful()'],['../classIRPanasonicAc.html#a736b77df0563705095d8f4241a80b1cb',1,'IRPanasonicAc::getPowerful()'],['../classIRSamsungAc.html#ac43367d5aec71e1dcb5b178427268412',1,'IRSamsungAc::getPowerful()']]], + ['getpowerspecial_3933',['getPowerSpecial',['../classIRSharpAc.html#aeb5d032c42863b6c3e2665c0719b9341',1,'IRSharpAc']]], + ['getpowertoggle_3934',['getPowerToggle',['../classIRDaikin128.html#a0b6b298a0287411f6fe34ec1a0032ff1',1,'IRDaikin128::getPowerToggle()'],['../classIRDaikin64.html#a7921b6a9e776a1802b98e25c0ac4d2dc',1,'IRDaikin64::getPowerToggle()'],['../classIRHitachiAc1.html#a384412f40bfde7a9934fbb7eb2813641',1,'IRHitachiAc1::getPowerToggle()'],['../classIRWhirlpoolAc.html#a08150bcdcf13f0dfb3a7608b2d354a1e',1,'IRWhirlpoolAc::getPowerToggle()']]], + ['getpurify_3935',['getPurify',['../classIRDaikin2.html#a3e2785832ae78bafa655aa61853a47bf',1,'IRDaikin2']]], + ['getquiet_3936',['getQuiet',['../classIRDaikinESP.html#a25dcfbeacce65f9a89d14a87f759c483',1,'IRDaikinESP::getQuiet()'],['../classIRDaikin2.html#a237eb163e3dd1bf8e45ae2324f0b7dcf',1,'IRDaikin2::getQuiet()'],['../classIRDaikin216.html#aaa0f1aa62f8afd3d489a33af1c1067bc',1,'IRDaikin216::getQuiet()'],['../classIRDaikin128.html#a685bbc2afeecdef69180229b64e1d54b',1,'IRDaikin128::getQuiet()'],['../classIRDaikin152.html#adc8878ec0f6ea2d4fc2fa756a2e9ef4e',1,'IRDaikin152::getQuiet()'],['../classIRDaikin64.html#a431e41baa2881f397b5bf8ee2b79fec9',1,'IRDaikin64::getQuiet()'],['../classIRKelvinatorAC.html#a467c0d63911a87bed8815a5b636d6d75',1,'IRKelvinatorAC::getQuiet()'],['../classIRMitsubishi136.html#afaf690f15d21fea1070b33b2720e98fa',1,'IRMitsubishi136::getQuiet()'],['../classIRMitsubishi112.html#a3b3b78ba5114d783ab7696f3e4687002',1,'IRMitsubishi112::getQuiet()'],['../classIRPanasonicAc.html#a8d7dfc9b5f7c7a4523c0bfa4e0bc415a',1,'IRPanasonicAc::getQuiet()'],['../classIRSamsungAc.html#a0baaf3d40419bb744204bdb30d4aa9b9',1,'IRSamsungAc::getQuiet()']]], + ['getraw_3937',['getRaw',['../classIRAmcorAc.html#aa2b99d815e499edf3ae53aebb35cbe9b',1,'IRAmcorAc::getRaw()'],['../classIRArgoAC.html#ac9e8b45dbbef453a54e3593d7e2927fb',1,'IRArgoAC::getRaw()'],['../classIRCarrierAc64.html#ad40279db2c9bd3d1abb5a6e028ec0d80',1,'IRCarrierAc64::getRaw()'],['../classIRCoolixAC.html#aa231938dfcff03325383205edc9c88d2',1,'IRCoolixAC::getRaw()'],['../classIRCoronaAc.html#ac2ba3b4bcefb801da345c9da5daa85fc',1,'IRCoronaAc::getRaw()'],['../classIRDaikinESP.html#ab100221dacc23402f486dee038df046d',1,'IRDaikinESP::getRaw()'],['../classIRDaikin2.html#aaf2ac0fc5924829a1209bd5e0b608b5f',1,'IRDaikin2::getRaw()'],['../classIRDaikin216.html#ac41b3de39ffc6ccd097085c727329531',1,'IRDaikin216::getRaw()'],['../classIRDaikin160.html#aeb68f80476362b0581fcb273b13cdf1e',1,'IRDaikin160::getRaw()'],['../classIRDaikin176.html#a86896be45037015683299004f2eb4d22',1,'IRDaikin176::getRaw()'],['../classIRDaikin128.html#a05669c2b1a6720b95d9a5fb898179a10',1,'IRDaikin128::getRaw()'],['../classIRDaikin152.html#a4af01f8a2459493762977f8ed260c4e6',1,'IRDaikin152::getRaw()'],['../classIRDaikin64.html#a1f8df45c67771ffca620f8c2f17af2e0',1,'IRDaikin64::getRaw()'],['../classIRDelonghiAc.html#a9e6934607f162df3d259d8fb95319d67',1,'IRDelonghiAc::getRaw()'],['../classIRElectraAc.html#a7674d29474ecbbb6366d96056794314c',1,'IRElectraAc::getRaw()'],['../classIRFujitsuAC.html#ae4dce44cab1f26756d63728cb8d55e65',1,'IRFujitsuAC::getRaw()'],['../classIRGoodweatherAc.html#a82d973e562b2425e8823fbc7332c06de',1,'IRGoodweatherAc::getRaw()'],['../classIRGreeAC.html#afa1595d4f69200b0076db1b9f8f2ea73',1,'IRGreeAC::getRaw()'],['../classIRHaierAC.html#abf72eed86c2c86c4f0f5f49f6a788b82',1,'IRHaierAC::getRaw()'],['../classIRHaierACYRW02.html#abca7bbe8c723551723f24f186343b764',1,'IRHaierACYRW02::getRaw()'],['../classIRHitachiAc.html#a8dafb9436f63cfc2d7e4f558fbd6e1ab',1,'IRHitachiAc::getRaw()'],['../classIRHitachiAc1.html#ad850b6364603880ccc444381e85af564',1,'IRHitachiAc1::getRaw()'],['../classIRHitachiAc424.html#acd8388f938feeaf6808ff65779435b5d',1,'IRHitachiAc424::getRaw()'],['../classIRHitachiAc3.html#a915605ca6d0bf3ff6fc9b376ddd394ae',1,'IRHitachiAc3::getRaw()'],['../classIRKelvinatorAC.html#a09149dd7bc45ca50b0c490b9c1f1e6f4',1,'IRKelvinatorAC::getRaw()'],['../classIRLgAc.html#afcb529d2f2c9016388264b80e6a99351',1,'IRLgAc::getRaw()'],['../classIRMideaAC.html#ae0b2c3a5a0a1d84eaeb462bbbe944d97',1,'IRMideaAC::getRaw()'],['../classIRMitsubishiAC.html#a1f2d0ea70bdeb71efab4c20ccd876aa9',1,'IRMitsubishiAC::getRaw()'],['../classIRMitsubishi136.html#a61cceec2bf241a75be1389391e8f3d9a',1,'IRMitsubishi136::getRaw()'],['../classIRMitsubishi112.html#a5e47e892921b8464652b55f41f42fd9a',1,'IRMitsubishi112::getRaw()'],['../classIRMitsubishiHeavy152Ac.html#a34ae73479c76b08512eaa87ed0662c0a',1,'IRMitsubishiHeavy152Ac::getRaw()'],['../classIRMitsubishiHeavy88Ac.html#af96915ac45861327ed7d55803dadd4fd',1,'IRMitsubishiHeavy88Ac::getRaw()'],['../classIRNeoclimaAc.html#a1f67329cad92d4252b0d33effce6380e',1,'IRNeoclimaAc::getRaw()'],['../classIRPanasonicAc.html#ad65c2bcdc3984a986f5ef2f03b5574d4',1,'IRPanasonicAc::getRaw()'],['../classIRSamsungAc.html#a96c6ac410053f0f2804160040d9fcf12',1,'IRSamsungAc::getRaw()'],['../classIRSharpAc.html#a9d680b0145c376060bd2d2e4c2630162',1,'IRSharpAc::getRaw()'],['../classIRTcl112Ac.html#a517375b764d1381aa5a7d4ec962346ec',1,'IRTcl112Ac::getRaw()'],['../classIRTecoAc.html#a7726e9d638cb81c7a4010112887a0ffe',1,'IRTecoAc::getRaw()'],['../classIRToshibaAC.html#a3572a06423851d2c4da5f85133a1a8ff',1,'IRToshibaAC::getRaw()'],['../classIRTrotecESP.html#a412dd2cf9dcb711003bcbb5b579cb2b8',1,'IRTrotecESP::getRaw()'],['../classIRVestelAc.html#afffd1dbcdec22ecca4efe9a996bf27e5',1,'IRVestelAc::getRaw()'],['../classIRWhirlpoolAc.html#a788a6a5373256e10200969cc5c73da63',1,'IRWhirlpoolAc::getRaw()']]], + ['getrclevel_3938',['getRClevel',['../classIRrecv.html#a8e32daaa903a8e42dad7faaf405b33dc',1,'IRrecv']]], + ['getroomtemp_3939',['getRoomTemp',['../classIRArgoAC.html#a5e4d8447c8851d2fce656abce6c4d368',1,'IRArgoAC']]], + ['getsave_3940',['getSave',['../classIRTecoAc.html#a0b4eea3d89f3aef649e32ee1b8bf65a3',1,'IRTecoAc']]], + ['getsectionbyte_3941',['getSectionByte',['../classIRCoronaAc.html#aed9181df842370739a5b4977b20769f9',1,'IRCoronaAc']]], + ['getsensor_3942',['getSensor',['../classIRDaikinESP.html#ac22369a04bb8f428a127b3625d9989fc',1,'IRDaikinESP::getSensor()'],['../classIRDaikin152.html#a88d4d0d41f33f71d4a846f6c2547f597',1,'IRDaikin152::getSensor()']]], + ['getsensortemp_3943',['getSensorTemp',['../classIRCoolixAC.html#aebbed796cab76248138e124aac1d535a',1,'IRCoolixAC']]], + ['getsilent_3944',['getSilent',['../classIRMitsubishiHeavy152Ac.html#a93aa735996a31d6f1928aa35d704bd24',1,'IRMitsubishiHeavy152Ac']]], + ['getsleep_3945',['getSleep',['../classIRCarrierAc64.html#a24f208b955af86f6927ac97b7f7066d5',1,'IRCarrierAc64::getSleep()'],['../classIRCoolixAC.html#a0b22f5427254c3f784f468d53909882c',1,'IRCoolixAC::getSleep()'],['../classIRDaikin128.html#a0cab507cdea112168757e1ab1a5a1dbe',1,'IRDaikin128::getSleep()'],['../classIRDaikin64.html#a32f4b90d4071cdbc4f37dd401e2d771f',1,'IRDaikin64::getSleep()'],['../classIRDelonghiAc.html#ab9baadd8f41c6dc7f89e71415e0e57b5',1,'IRDelonghiAc::getSleep()'],['../classIRGoodweatherAc.html#acf84e27fedc3c30a03c7d83e4843f8e0',1,'IRGoodweatherAc::getSleep()'],['../classIRGreeAC.html#abd106daa5324a454c5ced13e2fed2a1b',1,'IRGreeAC::getSleep()'],['../classIRHaierAC.html#a0ac7155d5ba294ce50b9436a35aa166b',1,'IRHaierAC::getSleep()'],['../classIRHaierACYRW02.html#acecf20cbe6065a4096ee5a353d2161c9',1,'IRHaierACYRW02::getSleep()'],['../classIRHitachiAc1.html#ab2e82cce1d9dc6e6ce66f2382ffcf4d4',1,'IRHitachiAc1::getSleep()'],['../classIRMideaAC.html#af4b76f42fd9be5eed9b546be7b0c34db',1,'IRMideaAC::getSleep()'],['../classIRNeoclimaAc.html#a8565f8f39127ed51eec7f7883319da61',1,'IRNeoclimaAc::getSleep()'],['../classIRTecoAc.html#a3eebb19e029aa882e161eb2bd6cfe333',1,'IRTecoAc::getSleep()'],['../classIRTrotecESP.html#a28558241d4dd18e191c6fab2c21f973e',1,'IRTrotecESP::getSleep()'],['../classIRVestelAc.html#a54f97dfe120c96b8c041550ed26d46f2',1,'IRVestelAc::getSleep()'],['../classIRWhirlpoolAc.html#a83c1b70e9c3b256b9e77ff6fb7fe0bde',1,'IRWhirlpoolAc::getSleep()']]], + ['getsleeptime_3946',['getSleepTime',['../classIRDaikin2.html#a31af96f9a05b3adea2e2ae84d3d242b9',1,'IRDaikin2']]], + ['getsleeptimerenabled_3947',['getSleepTimerEnabled',['../classIRDaikin2.html#ae4944acaa5c9d381a1875f4d0b16590a',1,'IRDaikin2']]], + ['getspecial_3948',['getSpecial',['../classIRSharpAc.html#a18fb9e6f965682e4faae3d1ecc2561cb',1,'IRSharpAc']]], + ['getspeed_3949',['getSpeed',['../classIRTrotecESP.html#ae57c9ab5bc2196f5028ea1af1bdb5428',1,'IRTrotecESP']]], + ['getstartclock_3950',['getStartClock',['../classIRMitsubishiAC.html#a0e0d8fa3bec35107929aaa9e9b4b5818',1,'IRMitsubishiAC']]], + ['getstate_3951',['getState',['../classIRac.html#af0122722691881b04c312bb30efcc3f2',1,'IRac']]], + ['getstatelength_3952',['getStateLength',['../classIRFujitsuAC.html#a02636372996211d464c7394329921ea0',1,'IRFujitsuAC']]], + ['getstateprev_3953',['getStatePrev',['../classIRac.html#adf582223eae0127491c7f1db38f101d3',1,'IRac']]], + ['getstopclock_3954',['getStopClock',['../classIRMitsubishiAC.html#a9b6266611d7cf75337557533a32796c2',1,'IRMitsubishiAC']]], + ['getsuper_3955',['getSuper',['../classIRWhirlpoolAc.html#a8bcf542e3499d05c4028157c803a0965',1,'IRWhirlpoolAc']]], + ['getswing_3956',['getSwing',['../classIRCoolixAC.html#a4846bb6a16802158dca3a8b1b7f5b6ff',1,'IRCoolixAC::getSwing()'],['../classIRFujitsuAC.html#af6f05f1375c3c4662d10026028fadbed',1,'IRFujitsuAC::getSwing()'],['../classIRGoodweatherAc.html#a96c844ec310323b62d9127ff250c3629',1,'IRGoodweatherAc::getSwing()'],['../classIRHaierAC.html#aa18839d213e4cd46405c683ec67fa23e',1,'IRHaierAC::getSwing()'],['../classIRHaierACYRW02.html#a88b15d20c007926ab5871b8e6a9fbe3f',1,'IRHaierACYRW02::getSwing()'],['../classIRSamsungAc.html#a5e6a7caccfdcb23cdb7d1341376c2343',1,'IRSamsungAc::getSwing()'],['../classIRTecoAc.html#a152fb025a2ba4410864637e8fdcef27a',1,'IRTecoAc::getSwing()'],['../classIRVestelAc.html#a991f8ca21319cb39b6c4cd358de4dbf4',1,'IRVestelAc::getSwing()'],['../classIRWhirlpoolAc.html#abac55fcea520ea4bbef3fa76223e2efc',1,'IRWhirlpoolAc::getSwing()']]], + ['getswingh_3957',['getSwingH',['../classIRElectraAc.html#a40e8f0ae2e57c3adf756b12524b36e6d',1,'IRElectraAc::getSwingH()'],['../classIRHitachiAc1.html#ac5bfde2c87281d3e7f427cb7ea601e85',1,'IRHitachiAc1::getSwingH()'],['../classIRHitachiAc344.html#a33ad0fe4939b2e2456a3d8a09da5a161',1,'IRHitachiAc344::getSwingH()'],['../classIRMitsubishi112.html#a05a343020c64f0ef95c365adcb337140',1,'IRMitsubishi112::getSwingH()'],['../classIRNeoclimaAc.html#a133fb28183fc33702bd8afb7c8886cb2',1,'IRNeoclimaAc::getSwingH()']]], + ['getswinghorizontal_3958',['getSwingHorizontal',['../classIRDaikinESP.html#a0a551cc1c22b5378015e8722919534aa',1,'IRDaikinESP::getSwingHorizontal()'],['../classIRDaikin2.html#a338a70b5d7f71da467a0f32b4a057f13',1,'IRDaikin2::getSwingHorizontal()'],['../classIRDaikin216.html#a4b5c648e6568bf1dd24932e108c560d9',1,'IRDaikin216::getSwingHorizontal()'],['../classIRDaikin176.html#aac0a1b9b5e618b31c651b9abc158a552',1,'IRDaikin176::getSwingHorizontal()'],['../classIRHitachiAc.html#a080f87358270eb1482d4a5d4b873f22c',1,'IRHitachiAc::getSwingHorizontal()'],['../classIRKelvinatorAC.html#abe27eb5ec7eb4c4b766a47b551422af3',1,'IRKelvinatorAC::getSwingHorizontal()'],['../classIRMitsubishiHeavy152Ac.html#a587eddf4684bdcb6c399b3f9c6cec684',1,'IRMitsubishiHeavy152Ac::getSwingHorizontal()'],['../classIRMitsubishiHeavy88Ac.html#ae538830313d02aa1ecc671188687dd35',1,'IRMitsubishiHeavy88Ac::getSwingHorizontal()'],['../classIRPanasonicAc.html#a37d9b268b3c8527be0939e0a24b02ef6',1,'IRPanasonicAc::getSwingHorizontal()'],['../classIRTcl112Ac.html#a7080def7f41498fc5af723e852c2e75c',1,'IRTcl112Ac::getSwingHorizontal()']]], + ['getswingtoggle_3959',['getSwingToggle',['../classIRHitachiAc1.html#ac4a5d4d5f9b4ae000d0acb232a1e2752',1,'IRHitachiAc1::getSwingToggle()'],['../classIRSharpAc.html#ae0327e90a68638c254706a99ed40f173',1,'IRSharpAc::getSwingToggle()']]], + ['getswingv_3960',['getSwingV',['../classIRCarrierAc64.html#a78aac688a4b040b2b6102fac8b028bde',1,'IRCarrierAc64::getSwingV()'],['../classIRDaikin152.html#a74ee60e666520513b33927178f15bc7e',1,'IRDaikin152::getSwingV()'],['../classIRElectraAc.html#a9cd2a7d7716f855dca6be12e3cdc3d24',1,'IRElectraAc::getSwingV()'],['../classIRHitachiAc1.html#a24216e1bc4cf9e9187e9031cee1684dc',1,'IRHitachiAc1::getSwingV()'],['../classIRHitachiAc344.html#a4e011e409f1bf97c8bd4043e2d069020',1,'IRHitachiAc344::getSwingV()'],['../classIRMitsubishi136.html#af2cacca74c4a6ade5f9689674bb707ea',1,'IRMitsubishi136::getSwingV()'],['../classIRMitsubishi112.html#a6d1e939169686978c83a2b26ebc3b8c2',1,'IRMitsubishi112::getSwingV()'],['../classIRNeoclimaAc.html#a3007ed9857bb212de05b7757ee0691e3',1,'IRNeoclimaAc::getSwingV()']]], + ['getswingvertical_3961',['getSwingVertical',['../classIRDaikinESP.html#a95f87fd97248e13c6339b71702a79e3a',1,'IRDaikinESP::getSwingVertical()'],['../classIRDaikin2.html#aa1d07be72001f06b6a8dfc279ffc40f5',1,'IRDaikin2::getSwingVertical()'],['../classIRDaikin216.html#ae72a3858a0023dac48fe755fd1bb1677',1,'IRDaikin216::getSwingVertical()'],['../classIRDaikin160.html#a5ed62940052f79587c92eaf92e30cf53',1,'IRDaikin160::getSwingVertical()'],['../classIRDaikin128.html#a60c21eaff6bf860ae25b974a0fd04e11',1,'IRDaikin128::getSwingVertical()'],['../classIRDaikin64.html#a7d538ad1ae23b92c1d82ae85ddd55ef1',1,'IRDaikin64::getSwingVertical()'],['../classIRHitachiAc.html#a9f507cc12bd3a5639777af0329a6dd5c',1,'IRHitachiAc::getSwingVertical()'],['../classIRKelvinatorAC.html#a69aaabc1f34e061272a76e4dc3c98bf1',1,'IRKelvinatorAC::getSwingVertical()'],['../classIRMitsubishiHeavy152Ac.html#a73c59d829a82306edf22acbd930650e0',1,'IRMitsubishiHeavy152Ac::getSwingVertical()'],['../classIRMitsubishiHeavy88Ac.html#ae836aee7dfb729f6b978b0b4ac8e9d3c',1,'IRMitsubishiHeavy88Ac::getSwingVertical()'],['../classIRPanasonicAc.html#a7a35303cd4fb4b23c0e5a25777d5819c',1,'IRPanasonicAc::getSwingVertical()'],['../classIRTcl112Ac.html#a0b75d06b14c1b7e2d2eb3a8779160ae5',1,'IRTcl112Ac::getSwingVertical()']]], + ['getswingverticalauto_3962',['getSwingVerticalAuto',['../classIRGreeAC.html#a4105bcde953896b12df050b12f1a45cc',1,'IRGreeAC']]], + ['getswingverticalposition_3963',['getSwingVerticalPosition',['../classIRGreeAC.html#a7b1b840483ef92102dd61fefd52ccd8b',1,'IRGreeAC']]], + ['getswingvtoggle_3964',['getSwingVToggle',['../classIRCoronaAc.html#ab10588a662031607ed4d01603a4471d6',1,'IRCoronaAc::getSwingVToggle()'],['../classIRHitachiAc424.html#ab697f595b6323288b6fd86f2a2911333',1,'IRHitachiAc424::getSwingVToggle()'],['../classIRMideaAC.html#a50b260d69bc0df8851bfccb003971dfe',1,'IRMideaAC::getSwingVToggle()']]], + ['gettemp_3965',['getTemp',['../classIRAmcorAc.html#a2f3e4765a3ae65ffda197f5a58070bf3',1,'IRAmcorAc::getTemp()'],['../classIRArgoAC.html#af5c4cfd3cac33f223e2807ec831df0a9',1,'IRArgoAC::getTemp()'],['../classIRCarrierAc64.html#a799edf21e766b8ae2638a9b1e1d18ac1',1,'IRCarrierAc64::getTemp()'],['../classIRCoolixAC.html#af90462598f294a75b35e20d986251942',1,'IRCoolixAC::getTemp()'],['../classIRCoronaAc.html#ac951434588fd9fa2de630db9ae844840',1,'IRCoronaAc::getTemp()'],['../classIRDaikinESP.html#a43c6675b688cad1ca714ecd726dbb411',1,'IRDaikinESP::getTemp()'],['../classIRDaikin2.html#aa1d39acc14bff5d55e918cb123c66e83',1,'IRDaikin2::getTemp()'],['../classIRDaikin216.html#a65b37310c01075c34cedd5ca1c8a2c37',1,'IRDaikin216::getTemp()'],['../classIRDaikin160.html#ae9cee15343fce5b0f32a4f2ff13a9dbe',1,'IRDaikin160::getTemp()'],['../classIRDaikin176.html#aa9015826e70e4ef1a319db4b2a3fba5f',1,'IRDaikin176::getTemp()'],['../classIRDaikin128.html#a0b5aa11a597bded38c067a9e9a01fd45',1,'IRDaikin128::getTemp()'],['../classIRDaikin152.html#af0a1f8bf9fe412186b53977d225032b2',1,'IRDaikin152::getTemp()'],['../classIRDaikin64.html#abeff1ec38e2d3c9fa12d59e506e7b699',1,'IRDaikin64::getTemp()'],['../classIRDelonghiAc.html#a5664302ab883fc88c23c8bb2aa020cb9',1,'IRDelonghiAc::getTemp()'],['../classIRElectraAc.html#ae92bd241a14058ece0e6d27332f9a3fa',1,'IRElectraAc::getTemp()'],['../classIRFujitsuAC.html#a9209df913f46821a66a390b8cff37acf',1,'IRFujitsuAC::getTemp()'],['../classIRGoodweatherAc.html#a796089c84e265cd7f1b2b82edc6b2367',1,'IRGoodweatherAc::getTemp()'],['../classIRGreeAC.html#a3e935c044cdccfb988a97d5fb0c4068b',1,'IRGreeAC::getTemp()'],['../classIRHaierAC.html#af137371c6766ee068a0200ff1facd8b0',1,'IRHaierAC::getTemp()'],['../classIRHaierACYRW02.html#a9cb0edcb5f36054e4e024c38ec3f26b9',1,'IRHaierACYRW02::getTemp()'],['../classIRHitachiAc.html#a85e0b2dfa45e894d1a89a2f862c6aa69',1,'IRHitachiAc::getTemp()'],['../classIRHitachiAc1.html#ac5c55a06a32134bb3e30b83cce2feeaa',1,'IRHitachiAc1::getTemp()'],['../classIRHitachiAc424.html#aa405408fd31795b714486af88a86112e',1,'IRHitachiAc424::getTemp()'],['../classIRKelvinatorAC.html#aabda77a2381526f4be86f05b311248db',1,'IRKelvinatorAC::getTemp()'],['../classIRLgAc.html#a029399c5926bd4f1ff0b26175bc4af79',1,'IRLgAc::getTemp()'],['../classIRMideaAC.html#a546ab6d3e317e6219ad371fd0825520d',1,'IRMideaAC::getTemp()'],['../classIRMitsubishiAC.html#a9881be01c53dce83bd1eae8a32f150f4',1,'IRMitsubishiAC::getTemp()'],['../classIRMitsubishi136.html#a34bc0e7666264a7e567e45405a57e3e0',1,'IRMitsubishi136::getTemp()'],['../classIRMitsubishi112.html#a4bfd306fecfcaa4c20589440ecfb35db',1,'IRMitsubishi112::getTemp()'],['../classIRMitsubishiHeavy152Ac.html#a7ec864271cf232cab7b8bd778bc36cb4',1,'IRMitsubishiHeavy152Ac::getTemp()'],['../classIRMitsubishiHeavy88Ac.html#afd629c9951a390b7809bc6ac4d3aeeb1',1,'IRMitsubishiHeavy88Ac::getTemp()'],['../classIRNeoclimaAc.html#aaa1a625af6cf094823b58f1fe43deb3a',1,'IRNeoclimaAc::getTemp()'],['../classIRPanasonicAc.html#af8a5607c317e541752fada6ca79ee80f',1,'IRPanasonicAc::getTemp()'],['../classIRSamsungAc.html#a11a6c86f2e4a918e1587ef564c63dddd',1,'IRSamsungAc::getTemp()'],['../classIRSharpAc.html#a1f75c17cc396162e776f3c6cd1848f50',1,'IRSharpAc::getTemp()'],['../classIRTcl112Ac.html#a61bf139cc737b99e5d68294c353eb353',1,'IRTcl112Ac::getTemp()'],['../classIRTecoAc.html#a40e717564222c5c1e4fdce13eba5efc3',1,'IRTecoAc::getTemp()'],['../classIRToshibaAC.html#ab2a9b47d49c5608c97a7c6968c43037d',1,'IRToshibaAC::getTemp()'],['../classIRTrotecESP.html#adcfae2ee1e58cd6a78805c72d7a8a942',1,'IRTrotecESP::getTemp()'],['../classIRVestelAc.html#a835ab977fa0dbf47776e5d618d59c819',1,'IRVestelAc::getTemp()'],['../classIRWhirlpoolAc.html#a4a73ee67cb2eb4407e78add1009cdd51',1,'IRWhirlpoolAc::getTemp()']]], + ['gettempoffset_3966',['getTempOffset',['../classIRWhirlpoolAc.html#a2d6111c9b97745d197f0b5d4d4610b3d',1,'IRWhirlpoolAc']]], + ['gettempraw_3967',['getTempRaw',['../classIRCoolixAC.html#a559634f3c6aee54683d4b6ccbbc7a884',1,'IRCoolixAC']]], + ['gettempunit_3968',['getTempUnit',['../classIRDelonghiAc.html#a8bbe27e1e87fbfc6b126c7f135886632',1,'IRDelonghiAc']]], + ['gettime_3969',['getTime',['../classIRHaierAC.html#a60e891775fbc3a77ee487cde26f650c5',1,'IRHaierAC::getTime()'],['../classIRVestelAc.html#a3542ec93c30ec3bc1bb4e242edcf1def',1,'IRVestelAc::getTime()'],['../classIRWhirlpoolAc.html#a27aba1f22b55aa6f72686e0a722682b0',1,'IRWhirlpoolAc::getTime()']]], + ['gettimer_3970',['getTimer',['../classIRDaikin128.html#ab35fa1fdd65db9d9cd7fbaffdd4ecd85',1,'IRDaikin128::getTimer()'],['../classIRGreeAC.html#a7a56024e2840306e071e03d1fae53ce9',1,'IRGreeAC::getTimer()'],['../classIRMitsubishiAC.html#a8bb8e92a00f8d9dfff31589d435c9ae5',1,'IRMitsubishiAC::getTimer()'],['../classIRTecoAc.html#a0bff25b2c686e397b62300ce5cad90f7',1,'IRTecoAc::getTimer()'],['../classIRTrotecESP.html#ae372b3120f0253c5a1607460817d36f6',1,'IRTrotecESP::getTimer()'],['../classIRVestelAc.html#aca4faedc9d82e357c8974fc6143b6e77',1,'IRVestelAc::getTimer()']]], + ['gettimerenabled_3971',['getTimerEnabled',['../classIRGreeAC.html#aeec03eb7f506a0ba62c28469b789b0da',1,'IRGreeAC::getTimerEnabled()'],['../classIRSharpAc.html#abd7c061b343b4f096019f42ad6162940',1,'IRSharpAc::getTimerEnabled()'],['../classIRTecoAc.html#a3524f149cd3076e757a1b3228bdf12f2',1,'IRTecoAc::getTimerEnabled()']]], + ['gettimertime_3972',['getTimerTime',['../classIRSharpAc.html#a72044d8afb1349a29cd8adcc8644c7ac',1,'IRSharpAc']]], + ['gettimertype_3973',['getTimerType',['../classIRSharpAc.html#a9357c50c356b29cc444bf9aafb7df146',1,'IRSharpAc']]], + ['gettolerance_3974',['getTolerance',['../classIRrecv.html#a144f64da3b44708394c06b0fbefb6347',1,'IRrecv']]], + ['getturbo_3975',['getTurbo',['../classIRCoolixAC.html#ab5f87216fb91bbb437c0899b0742a63f',1,'IRCoolixAC::getTurbo()'],['../classIRDaikin64.html#ade80a5ea137c32bdedd794d64925a2d3',1,'IRDaikin64::getTurbo()'],['../classIRElectraAc.html#a75cae6845498eec84109374a2fefcced',1,'IRElectraAc::getTurbo()'],['../classIRGoodweatherAc.html#a983eca3c2ec1233184939702f43557eb',1,'IRGoodweatherAc::getTurbo()'],['../classIRGreeAC.html#a6e319c8584d0cb82223fd190fa4bde29',1,'IRGreeAC::getTurbo()'],['../classIRHaierACYRW02.html#a4ccd26dad24915b81ae5fb94d18fb85a',1,'IRHaierACYRW02::getTurbo()'],['../classIRKelvinatorAC.html#aff32ab0524f4afeb9b53aa65b8df8e36',1,'IRKelvinatorAC::getTurbo()'],['../classIRMitsubishiHeavy152Ac.html#acf2a73ccddb87bd66c39670bd1d3caba',1,'IRMitsubishiHeavy152Ac::getTurbo()'],['../classIRMitsubishiHeavy88Ac.html#a179ecc619e9eea4adb601309421e5fc0',1,'IRMitsubishiHeavy88Ac::getTurbo()'],['../classIRNeoclimaAc.html#a6cf241f0392744a91b703475ee88bfa1',1,'IRNeoclimaAc::getTurbo()'],['../classIRSharpAc.html#aad2ec46f8da6fd84bc0523f40d6bd57d',1,'IRSharpAc::getTurbo()'],['../classIRTcl112Ac.html#a0de33a2175eada44030d3640d940b697',1,'IRTcl112Ac::getTurbo()'],['../classIRVestelAc.html#a9ce168cc9422e54d631aed571cfe66be',1,'IRVestelAc::getTurbo()']]], + ['getusecelsius_3976',['getUseCelsius',['../classIRMideaAC.html#aa88de606a914e33e8beb75a069137b52',1,'IRMideaAC']]], + ['getusefahrenheit_3977',['getUseFahrenheit',['../classIRGreeAC.html#aad6acfb8a697aba851bb34b14bc94ac1',1,'IRGreeAC']]], + ['getvane_3978',['getVane',['../classIRMitsubishiAC.html#acd98301535e7e161f8fdf42877f3e482',1,'IRMitsubishiAC']]], + ['getweeklytimerenable_3979',['getWeeklyTimerEnable',['../classIRDaikinESP.html#a9ee2013c069496884c62b6e9a58d01db',1,'IRDaikinESP']]], + ['getwidevane_3980',['getWideVane',['../classIRMitsubishiAC.html#a217dba9f9dcc6f75d466b0b7beca3aea',1,'IRMitsubishiAC']]], + ['getwifi_3981',['getWiFi',['../classIRGreeAC.html#a967afbe980bae858ce0e4daea6628c37',1,'IRGreeAC']]], + ['getxfan_3982',['getXFan',['../classIRGreeAC.html#acb677dde02be1a3461a7c8bc2406194f',1,'IRGreeAC::getXFan()'],['../classIRKelvinatorAC.html#a2e511ca0a8876928412c2db9214e7fe2',1,'IRKelvinatorAC::getXFan()']]], + ['getzonefollow_3983',['getZoneFollow',['../classIRCoolixAC.html#a647a41d63301e3d95460323d1fe0ce4a',1,'IRCoolixAC']]], + ['goodweather_3984',['goodweather',['../classIRac.html#ac47ff5c6faf41e6fb37df258a8bafc08',1,'IRac']]], + ['gree_3985',['gree',['../classIRac.html#ab66e48b039c9990bf97cd8c2512a6c70',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.html new file mode 100644 index 000000000..7422be245 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.js new file mode 100644 index 000000000..60ae567c3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['haier_3986',['haier',['../classIRac.html#ae0a29a4cb8c7a4707a7725c576822a58',1,'IRac']]], + ['haieryrwo2_3987',['haierYrwo2',['../classIRac.html#a7bc779a162dd9a1b4c925febec443353',1,'IRac']]], + ['handlespecialstate_3988',['handleSpecialState',['../classIRCoolixAC.html#af78090c6d8b45b4202a80f1223640390',1,'IRCoolixAC']]], + ['handletoggles_3989',['handleToggles',['../classIRac.html#a36833999dce4ad608a5a0f084988cfd1',1,'IRac']]], + ['hasacstate_3990',['hasACState',['../IRutils_8cpp.html#a6efd4986db60709d3501606ec7ab5382',1,'hasACState(const decode_type_t protocol): IRutils.cpp'],['../IRutils_8h.html#a6efd4986db60709d3501606ec7ab5382',1,'hasACState(const decode_type_t protocol): IRutils.cpp']]], + ['hasinvertedstates_3991',['hasInvertedStates',['../classIRHitachiAc3.html#ac06b36245c85480d97c1a9f49cfaa005',1,'IRHitachiAc3']]], + ['hasstatechanged_3992',['hasStateChanged',['../classIRac.html#a35258c35a2d2b19886292b22b2aa053a',1,'IRac']]], + ['hitachi_3993',['hitachi',['../classIRac.html#acd0f2fcf03aabf947a19a195000add3c',1,'IRac']]], + ['hitachi1_3994',['hitachi1',['../classIRac.html#ac8807d62f6ae87af72d44b50bed3f17b',1,'IRac']]], + ['hitachi344_3995',['hitachi344',['../classIRac.html#a0bc34635a1a349816344916a82585460',1,'IRac']]], + ['hitachi424_3996',['hitachi424',['../classIRac.html#aec6de0752ddd3a3e7c6824cb1b692508',1,'IRac']]], + ['htmlescape_3997',['htmlEscape',['../namespaceirutils.html#a6e55c6fdcc82e1ef8bd5f73df83609a7',1,'irutils']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.html new file mode 100644 index 000000000..befd4faaa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.js new file mode 100644 index 000000000..97c6d2069 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.js @@ -0,0 +1,64 @@ +var searchData= +[ + ['initstate_3998',['initState',['../classIRac.html#af1c4ae70e61298c0be8d350d67e7c342',1,'IRac::initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)'],['../classIRac.html#a165b7fdb9b3a02b1fb5ff2c2c3747958',1,'IRac::initState(stdAc::state_t *state)']]], + ['invertbits_3999',['invertBits',['../IRutils_8cpp.html#a1a85904f25c8ec77fb554d238c59cfdb',1,'invertBits(const uint64_t data, const uint16_t nbits): IRutils.cpp'],['../IRutils_8h.html#a1a85904f25c8ec77fb554d238c59cfdb',1,'invertBits(const uint64_t data, const uint16_t nbits): IRutils.cpp']]], + ['irac_4000',['IRac',['../classIRac.html#abb0864e277d4f6c68a92c2729112a40d',1,'IRac']]], + ['iramcorac_4001',['IRAmcorAc',['../classIRAmcorAc.html#a92db59a33c861dcd3b2960e9711f97c4',1,'IRAmcorAc']]], + ['irargoac_4002',['IRArgoAC',['../classIRArgoAC.html#ad6c2250738397441b8f956d1477b7d70',1,'IRArgoAC']]], + ['ircarrierac64_4003',['IRCarrierAc64',['../classIRCarrierAc64.html#ac225c0f24a0e385a145375ff447ab79b',1,'IRCarrierAc64']]], + ['ircoolixac_4004',['IRCoolixAC',['../classIRCoolixAC.html#a043ad3b74e964e39b111e1fcf9e55f42',1,'IRCoolixAC']]], + ['ircoronaac_4005',['IRCoronaAc',['../classIRCoronaAc.html#aa96f1ffce21cdec5b3901ebbb1c63fbb',1,'IRCoronaAc']]], + ['irdaikin128_4006',['IRDaikin128',['../classIRDaikin128.html#aa669739541daf1a2b39ce1cd0424c43b',1,'IRDaikin128']]], + ['irdaikin152_4007',['IRDaikin152',['../classIRDaikin152.html#a68dce79bab5890d9aea325a45ef8e4a3',1,'IRDaikin152']]], + ['irdaikin160_4008',['IRDaikin160',['../classIRDaikin160.html#a76fb744b041c38abb730bce0538a497a',1,'IRDaikin160']]], + ['irdaikin176_4009',['IRDaikin176',['../classIRDaikin176.html#accfe7c3f34351844d12059455f65f312',1,'IRDaikin176']]], + ['irdaikin2_4010',['IRDaikin2',['../classIRDaikin2.html#a3ffe908313f162b92e92307578592fca',1,'IRDaikin2']]], + ['irdaikin216_4011',['IRDaikin216',['../classIRDaikin216.html#ad802bde79e5ee2d16e3b09fbc8bbe8df',1,'IRDaikin216']]], + ['irdaikin64_4012',['IRDaikin64',['../classIRDaikin64.html#a88855df33ce903884b21d2ef4771e94f',1,'IRDaikin64']]], + ['irdaikinesp_4013',['IRDaikinESP',['../classIRDaikinESP.html#a2652cb45e07e8a4329c16cded9f6ad9a',1,'IRDaikinESP']]], + ['irdelonghiac_4014',['IRDelonghiAc',['../classIRDelonghiAc.html#aa6f8661cf6baa369a0a5b9d775c392e0',1,'IRDelonghiAc']]], + ['irelectraac_4015',['IRElectraAc',['../classIRElectraAc.html#a2f56ad22943c3d261b1d2ef88d86e300',1,'IRElectraAc']]], + ['irfujitsuac_4016',['IRFujitsuAC',['../classIRFujitsuAC.html#acdb70f239884507f540b872ba25747ce',1,'IRFujitsuAC']]], + ['irgoodweatherac_4017',['IRGoodweatherAc',['../classIRGoodweatherAc.html#a681feff1a58125cde97b2d7ed0ba775e',1,'IRGoodweatherAc']]], + ['irgreeac_4018',['IRGreeAC',['../classIRGreeAC.html#abf7ead6ebee4bc776f83fb55f6fe6b63',1,'IRGreeAC']]], + ['irhaierac_4019',['IRHaierAC',['../classIRHaierAC.html#a0b78060cbd150cd886a409adc2dea49c',1,'IRHaierAC']]], + ['irhaieracyrw02_4020',['IRHaierACYRW02',['../classIRHaierACYRW02.html#afd9354c36df33434840bbc5f38d4e7ed',1,'IRHaierACYRW02']]], + ['irhitachiac_4021',['IRHitachiAc',['../classIRHitachiAc.html#a4c43e95e0cc28339e7162d7090ae16bf',1,'IRHitachiAc']]], + ['irhitachiac1_4022',['IRHitachiAc1',['../classIRHitachiAc1.html#ac00cfd9a60e08d34f292878de47f622f',1,'IRHitachiAc1']]], + ['irhitachiac3_4023',['IRHitachiAc3',['../classIRHitachiAc3.html#adef0e7ad217f078ce418e3aa82b9cb86',1,'IRHitachiAc3']]], + ['irhitachiac344_4024',['IRHitachiAc344',['../classIRHitachiAc344.html#afbff8a1dd2777880d2d1713d07e1d419',1,'IRHitachiAc344']]], + ['irhitachiac424_4025',['IRHitachiAc424',['../classIRHitachiAc424.html#add708c10a56d20621ef65a0ddcc2aac1',1,'IRHitachiAc424']]], + ['irkelvinatorac_4026',['IRKelvinatorAC',['../classIRKelvinatorAC.html#a111dd384b1898a4fb880a19b6d1b1635',1,'IRKelvinatorAC']]], + ['irlgac_4027',['IRLgAc',['../classIRLgAc.html#a290636496526a9ed2057532649709375',1,'IRLgAc']]], + ['irmideaac_4028',['IRMideaAC',['../classIRMideaAC.html#a1ef2f532a1e6c6bfe89617d3fd0d9082',1,'IRMideaAC']]], + ['irmitsubishi112_4029',['IRMitsubishi112',['../classIRMitsubishi112.html#adea6f3b7b7619b0bf6da4a94cec9d712',1,'IRMitsubishi112']]], + ['irmitsubishi136_4030',['IRMitsubishi136',['../classIRMitsubishi136.html#ad92926b993869d0695f11ddb999b2090',1,'IRMitsubishi136']]], + ['irmitsubishiac_4031',['IRMitsubishiAC',['../classIRMitsubishiAC.html#a83fabfd9ebed5cef8dd2a18a85fdf4e6',1,'IRMitsubishiAC']]], + ['irmitsubishiheavy152ac_4032',['IRMitsubishiHeavy152Ac',['../classIRMitsubishiHeavy152Ac.html#a704e9f96c2d0a07f9ba16a400d9c97aa',1,'IRMitsubishiHeavy152Ac']]], + ['irmitsubishiheavy88ac_4033',['IRMitsubishiHeavy88Ac',['../classIRMitsubishiHeavy88Ac.html#aceabecf4a615e807a4636ff5990d77d7',1,'IRMitsubishiHeavy88Ac']]], + ['irneoclimaac_4034',['IRNeoclimaAc',['../classIRNeoclimaAc.html#a99ed2962176e5f12f8387fab977c6395',1,'IRNeoclimaAc']]], + ['irpanasonicac_4035',['IRPanasonicAc',['../classIRPanasonicAc.html#ae8b0f4518ee1a913d47a7101b0a11185',1,'IRPanasonicAc']]], + ['irrecv_4036',['IRrecv',['../classIRrecv.html#a8fe4d26ef1f863db1db9994fed5fc209',1,'IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)'],['../classIRrecv.html#a3bb1bcc1c1a3184294dd35c8f6f758b1',1,'IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false)']]], + ['irsamsungac_4037',['IRSamsungAc',['../classIRSamsungAc.html#a0db771b80d7d7a63b5ecb4b25efee609',1,'IRSamsungAc']]], + ['irsend_4038',['IRsend',['../classIRsend.html#a792780b7de996c90c86dd7b700eaf271',1,'IRsend']]], + ['irsharpac_4039',['IRSharpAc',['../classIRSharpAc.html#a30b5f8f634a41c943b4e1453d12bc980',1,'IRSharpAc']]], + ['irtcl112ac_4040',['IRTcl112Ac',['../classIRTcl112Ac.html#a061bdfdf4444cb5e06fa90824985c1ec',1,'IRTcl112Ac']]], + ['irtecoac_4041',['IRTecoAc',['../classIRTecoAc.html#a56e3f31a080bfd565570bf3b165e71d4',1,'IRTecoAc']]], + ['irtimer_4042',['IRtimer',['../classIRtimer.html#a09d64d689137ef8ca68973bb9e550e76',1,'IRtimer']]], + ['irtoshibaac_4043',['IRToshibaAC',['../classIRToshibaAC.html#abf2b3db316f7d6acb20c4f7ea2476ec2',1,'IRToshibaAC']]], + ['irtrotecesp_4044',['IRTrotecESP',['../classIRTrotecESP.html#a1b56b6e55bf133ccab6a482090408ee5',1,'IRTrotecESP']]], + ['irvestelac_4045',['IRVestelAc',['../classIRVestelAc.html#af1583ef81331edf112a0d04771c2cbec',1,'IRVestelAc']]], + ['irwhirlpoolac_4046',['IRWhirlpoolAc',['../classIRWhirlpoolAc.html#a89bc9d440a5f7d04a602d7bc73904bc2',1,'IRWhirlpoolAc']]], + ['isofftimeractive_4047',['isOffTimerActive',['../classIRVestelAc.html#aa756171e82ed1b43593b81aa3a63b812',1,'IRVestelAc']]], + ['isofftimerenabled_4048',['isOffTimerEnabled',['../classIRPanasonicAc.html#ac8e218b4886d66889734b01232767c8a',1,'IRPanasonicAc::isOffTimerEnabled()'],['../classIRWhirlpoolAc.html#a1bc1366524cf3c7fb426e908a166801f',1,'IRWhirlpoolAc::isOffTimerEnabled()']]], + ['isontimeractive_4049',['isOnTimerActive',['../classIRVestelAc.html#a67f0e970af50fcf6e01e4cac85c5862a',1,'IRVestelAc']]], + ['isontimerenabled_4050',['isOnTimerEnabled',['../classIRPanasonicAc.html#a04cbf8f5063a3892020d383c77abc57c',1,'IRPanasonicAc::isOnTimerEnabled()'],['../classIRWhirlpoolAc.html#aff1b8c2d063b376725a5a77745f6be3a',1,'IRWhirlpoolAc::isOnTimerEnabled()']]], + ['ispowerspecial_4051',['isPowerSpecial',['../classIRSharpAc.html#a57072f2458897ffb9184769aca10b944',1,'IRSharpAc']]], + ['isprotocolsupported_4052',['isProtocolSupported',['../classIRac.html#ad9c2fc9d07db70704f78a2d5f7be5b1c',1,'IRac']]], + ['isspecialstate_4053',['isSpecialState',['../classIRCoolixAC.html#a51bde954328ca5887a8353ba5562b3db',1,'IRCoolixAC']]], + ['isswingvtoggle_4054',['isSwingVToggle',['../classIRMideaAC.html#a848076f02a38a32c691a4617586862cc',1,'IRMideaAC']]], + ['istimecommand_4055',['isTimeCommand',['../classIRVestelAc.html#ae811a07c1a8d82e7068c39b9ca73aaf1',1,'IRVestelAc']]], + ['istimeractive_4056',['isTimerActive',['../classIRVestelAc.html#a160b73df8e1eda984f9bfbff3df7fa63',1,'IRVestelAc']]], + ['istimerenabled_4057',['isTimerEnabled',['../classIRWhirlpoolAc.html#a5a713ffed99ab3450257d83e2d6e15ee',1,'IRWhirlpoolAc']]], + ['isvalidlgac_4058',['isValidLgAc',['../classIRLgAc.html#a5984041eb12603ac1a277c28b355322a',1,'IRLgAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.html new file mode 100644 index 000000000..a81e96336 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.js new file mode 100644 index 000000000..42993aa20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['kelvinator_4059',['kelvinator',['../classIRac.html#a6e4d8061841a7271205f81bd8e7d6171',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.html new file mode 100644 index 000000000..345265d62 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.js new file mode 100644 index 000000000..18f4d0950 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['ledoff_4060',['ledOff',['../classIRsend.html#ae71cc5aa99f894785fb4f7abc05841b2',1,'IRsend']]], + ['ledon_4061',['ledOn',['../classIRsend.html#a13d804171fa7c14aff4def38c6ffb6c8',1,'IRsend']]], + ['lg_4062',['lg',['../classIRac.html#afad31ecf9eae573882d53dd6629485fb',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.html new file mode 100644 index 000000000..858bfd6c9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.js new file mode 100644 index 000000000..a9f6f2360 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['mark_4063',['mark',['../classIRsend.html#a7399389d40bfe24bc062ffca88fc3780',1,'IRsend']]], + ['markassent_4064',['markAsSent',['../classIRac.html#ad0e45b13f477e29823b8c138704536c4',1,'IRac']]], + ['match_4065',['match',['../classIRrecv.html#a8bc218dae714ab189a3da4fff269cdaa',1,'IRrecv']]], + ['matchatleast_4066',['matchAtLeast',['../classIRrecv.html#ae7bfd4ff689c7563c65c4e6e8c58187a',1,'IRrecv']]], + ['matchbytes_4067',['matchBytes',['../classIRrecv.html#adc2c9bc4c4e5741cfac7468126bf8ca6',1,'IRrecv']]], + ['matchdata_4068',['matchData',['../classIRrecv.html#a5361439cb69b1069553544e486502d2e',1,'IRrecv']]], + ['matchgeneric_4069',['matchGeneric',['../classIRrecv.html#ab783f52acc2ff4052313d6947563e4fd',1,'IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)'],['../classIRrecv.html#a4448c1658383962d735353352987c9aa',1,'IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)']]], + ['matchgenericconstbittime_4070',['matchGenericConstBitTime',['../classIRrecv.html#a4582d75ef1d11aee35fce86c38dcccf0',1,'IRrecv']]], + ['matchmanchester_4071',['matchManchester',['../classIRrecv.html#ade70777ad0e047e11b99b03d8f5e3728',1,'IRrecv']]], + ['matchmanchesterdata_4072',['matchManchesterData',['../classIRrecv.html#ab44403411a217eb8ea75271575f8ab83',1,'IRrecv']]], + ['matchmark_4073',['matchMark',['../classIRrecv.html#ae78ef12b8194db5d3cb5a2605d29830d',1,'IRrecv']]], + ['matchspace_4074',['matchSpace',['../classIRrecv.html#a9fd363e8b2edee2ed3c473349ecc58fc',1,'IRrecv']]], + ['midea_4075',['midea',['../classIRac.html#a5b9c72198497eca0121945b557691309',1,'IRac']]], + ['minrepeats_4076',['minRepeats',['../classIRsend.html#ae02772f34180163861b7e4eb3520db2a',1,'IRsend']]], + ['minstostring_4077',['minsToString',['../namespaceirutils.html#aebab40a2c69624adc1a5a8a6db72952f',1,'irutils']]], + ['mitsubishi_4078',['mitsubishi',['../classIRac.html#aaa60bcac75dc5dda40c78f8c227b19a3',1,'IRac']]], + ['mitsubishi112_4079',['mitsubishi112',['../classIRac.html#a2438b6e4403d5952adb299083e038e10',1,'IRac']]], + ['mitsubishi136_4080',['mitsubishi136',['../classIRac.html#aa3033eb835cf3cd313ee2c2f38357e8e',1,'IRac']]], + ['mitsubishiheavy152_4081',['mitsubishiHeavy152',['../classIRac.html#a635b89320d878c1e3f270d7146cb9b00',1,'IRac']]], + ['mitsubishiheavy88_4082',['mitsubishiHeavy88',['../classIRac.html#af6c9084c5e902f98a03ad0eaf3b9448e',1,'IRac']]], + ['modeltostr_4083',['modelToStr',['../namespaceirutils.html#ae89b70ce66617a8707c1951eadbc6fbd',1,'irutils']]], + ['mstostring_4084',['msToString',['../namespaceirutils.html#a9c59c8dd886c283fdb8adc9082c6890a',1,'irutils']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.html new file mode 100644 index 000000000..2f09f51ba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.js new file mode 100644 index 000000000..d3ffd6eff --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['neoclima_4085',['neoclima',['../classIRac.html#a0e468b705922e58308c5e340499f2391',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.html new file mode 100644 index 000000000..ee5afa650 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.js new file mode 100644 index 000000000..1fc2ce013 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['off_4086',['off',['../classIRAmcorAc.html#a5c67c2acde4964bf863d5ae73555ea1a',1,'IRAmcorAc::off()'],['../classIRArgoAC.html#ab5ab7cc22bbce59bb02ca60431dca3fb',1,'IRArgoAC::off()'],['../classIRCarrierAc64.html#ac7a262d768626f01dac94f5e2891c98e',1,'IRCarrierAc64::off()'],['../classIRCoolixAC.html#a7538665a38e193ecd3a0bed41e9f1417',1,'IRCoolixAC::off()'],['../classIRCoronaAc.html#a3744c68ec90d89999be4db5bd6ffe2a3',1,'IRCoronaAc::off()'],['../classIRDaikinESP.html#a5d1d22f45d877660719916ca546bd3af',1,'IRDaikinESP::off()'],['../classIRDaikin2.html#a84a48dfceb4d7137eb485e6897ccceac',1,'IRDaikin2::off()'],['../classIRDaikin216.html#a086d8cea2d6dd0f74c5cbece79d91567',1,'IRDaikin216::off()'],['../classIRDaikin160.html#a95f8c71bbf861d3c884656364e04b02a',1,'IRDaikin160::off()'],['../classIRDaikin176.html#a4ad81df1fe4921abee3634bf19b0d0f7',1,'IRDaikin176::off()'],['../classIRDaikin152.html#a035588ad676a54d2b6ada8cefe10e114',1,'IRDaikin152::off()'],['../classIRDelonghiAc.html#aa2f8f1d5da390bd5e5b36102dd40f5c8',1,'IRDelonghiAc::off()'],['../classIRElectraAc.html#afe3a9b789eafbef19d015cdebf71dc0d',1,'IRElectraAc::off()'],['../classIRFujitsuAC.html#ae7a320c2d2b8afbd9a04251053831cdd',1,'IRFujitsuAC::off()'],['../classIRGoodweatherAc.html#ad6863d837140951fcc0faf629025d48e',1,'IRGoodweatherAc::off()'],['../classIRGreeAC.html#a4cce897175ed731ab62402133089ed4f',1,'IRGreeAC::off()'],['../classIRHaierACYRW02.html#a9837ba26574f8bd452d616173819a9a4',1,'IRHaierACYRW02::off()'],['../classIRHitachiAc.html#a62be5ca181c8c9d11b65b38b1ed178b5',1,'IRHitachiAc::off()'],['../classIRHitachiAc1.html#a646b554980706d0dd2ac762be8458cdb',1,'IRHitachiAc1::off()'],['../classIRHitachiAc424.html#a0815a09fc49449bac03d996c63040a5f',1,'IRHitachiAc424::off()'],['../classIRKelvinatorAC.html#a4a759df902d1465c9520da7c7c595abc',1,'IRKelvinatorAC::off()'],['../classIRLgAc.html#a6d3d50b34575fecb93ed8bd5897c3f7c',1,'IRLgAc::off()'],['../classIRMideaAC.html#a29fbafcf47dc41475d009c4c92b2917b',1,'IRMideaAC::off()'],['../classIRMitsubishiAC.html#ac204620341200994c28411f53d5aa046',1,'IRMitsubishiAC::off()'],['../classIRMitsubishi136.html#a4122014509e9e755881920650f19baf3',1,'IRMitsubishi136::off()'],['../classIRMitsubishi112.html#ab5b6370edf2626da2e9f124a218678a8',1,'IRMitsubishi112::off()'],['../classIRMitsubishiHeavy152Ac.html#a93b603cc37d2dc7e3e7005ce21a0b2d7',1,'IRMitsubishiHeavy152Ac::off()'],['../classIRMitsubishiHeavy88Ac.html#a45c56c0454755d704a3df1f1f3647130',1,'IRMitsubishiHeavy88Ac::off()'],['../classIRNeoclimaAc.html#a9a277308bf8d8b0cd06a28964e7cbafb',1,'IRNeoclimaAc::off()'],['../classIRPanasonicAc.html#a03b706293c1c5b348bba536e6d8d33f5',1,'IRPanasonicAc::off()'],['../classIRSamsungAc.html#a34cb19bb4902441a2b9f10892eb17d83',1,'IRSamsungAc::off()'],['../classIRSharpAc.html#a178925a1d7ca01aae5c107fab5b32e93',1,'IRSharpAc::off()'],['../classIRTcl112Ac.html#ab2e39430629fcada55a584cff66d2749',1,'IRTcl112Ac::off()'],['../classIRTecoAc.html#ade1b1541bf2de053c78657af1ebcd001',1,'IRTecoAc::off()'],['../classIRToshibaAC.html#a70b145f7b9c46790e4e5da812bb66e58',1,'IRToshibaAC::off()'],['../classIRTrotecESP.html#a8f300ddaf255de1cdfee10b76b1f08e0',1,'IRTrotecESP::off()'],['../classIRVestelAc.html#a59e90e51e3518ef26bb382903ce67357',1,'IRVestelAc::off()']]], + ['on_4087',['on',['../classIRAmcorAc.html#adff3f4b9f57815a4062443f3e4dab78c',1,'IRAmcorAc::on()'],['../classIRArgoAC.html#a70497752f7afd8e3274cf4d8b1e22628',1,'IRArgoAC::on()'],['../classIRCarrierAc64.html#a39c13b713e36fbf94605f251b36bdfae',1,'IRCarrierAc64::on()'],['../classIRCoolixAC.html#a59c414fe0e951cd50083ab1fc45286ed',1,'IRCoolixAC::on()'],['../classIRCoronaAc.html#a7fe14d62eaccdc2db8db168c90a3cd87',1,'IRCoronaAc::on()'],['../classIRDaikinESP.html#a502e9dea10605d52e291d49af26b07eb',1,'IRDaikinESP::on()'],['../classIRDaikin2.html#a009ac70fd8b8695f3d931a42667fdb66',1,'IRDaikin2::on()'],['../classIRDaikin216.html#a09f54bb4ed1d553b4bbf6ffe6992a755',1,'IRDaikin216::on()'],['../classIRDaikin160.html#a2b6c282ad5cb2a702857532ab020110b',1,'IRDaikin160::on()'],['../classIRDaikin176.html#a3ca59ccdad4b7958fc4dc1a4b0593f38',1,'IRDaikin176::on()'],['../classIRDaikin152.html#a10ee74aa43e3940d657ac88cb03b9138',1,'IRDaikin152::on()'],['../classIRDelonghiAc.html#ab21d64ace3107a8f3359b3828bc2cab5',1,'IRDelonghiAc::on()'],['../classIRElectraAc.html#a99e29f982435b01c726d0234a433cfa6',1,'IRElectraAc::on()'],['../classIRFujitsuAC.html#adcb24818d088c879beb7d76ada332f43',1,'IRFujitsuAC::on()'],['../classIRGoodweatherAc.html#a1e3c2a9f47376062ab66318d6af4324b',1,'IRGoodweatherAc::on()'],['../classIRGreeAC.html#a69e399e411a19e5669e752d52ae66f15',1,'IRGreeAC::on()'],['../classIRHaierACYRW02.html#aaeb257d68235278be272e521fdec7331',1,'IRHaierACYRW02::on()'],['../classIRHitachiAc.html#a855e95d55d4ebfb3958b9d80a7b42c6f',1,'IRHitachiAc::on()'],['../classIRHitachiAc1.html#aea4fe1fddb56c8df31077b301e9c6473',1,'IRHitachiAc1::on()'],['../classIRHitachiAc424.html#ad414bca642af40ed81a6cbf93a0bf40b',1,'IRHitachiAc424::on()'],['../classIRKelvinatorAC.html#a714d0e70f2996694e2c46afdd9996341',1,'IRKelvinatorAC::on()'],['../classIRLgAc.html#a171358340c1ba8f90fef0c5454f2aa41',1,'IRLgAc::on()'],['../classIRMideaAC.html#af8dde03cb641a5af4f2ef0dcf70f1ca0',1,'IRMideaAC::on()'],['../classIRMitsubishiAC.html#a2946d1b3b641d7b991c0d296d5c5e77e',1,'IRMitsubishiAC::on()'],['../classIRMitsubishi136.html#a74180e99a5f4f1f4b740b442a1b74a06',1,'IRMitsubishi136::on()'],['../classIRMitsubishi112.html#accd250f130b4d0cd61593982b84b9138',1,'IRMitsubishi112::on()'],['../classIRMitsubishiHeavy152Ac.html#a5c7aec50b53fdc3af591e077a4a268e4',1,'IRMitsubishiHeavy152Ac::on()'],['../classIRMitsubishiHeavy88Ac.html#a44ce2c4f03b8b8973922f5bf59a19d2c',1,'IRMitsubishiHeavy88Ac::on()'],['../classIRNeoclimaAc.html#ab4a23cefef02351883dc4088dec51071',1,'IRNeoclimaAc::on()'],['../classIRPanasonicAc.html#a88e6b0f607b17266567306576e623a0c',1,'IRPanasonicAc::on()'],['../classIRSamsungAc.html#a68cf52997489a1c835662c7cdf23463c',1,'IRSamsungAc::on()'],['../classIRSharpAc.html#a5c8dad46c2965fc0d87780a8bd8b98f4',1,'IRSharpAc::on()'],['../classIRTcl112Ac.html#a0bbf7f0b9753b516fda0544c17b15b8a',1,'IRTcl112Ac::on()'],['../classIRTecoAc.html#af26015e5c663c346cf7db6d8af3f8c60',1,'IRTecoAc::on()'],['../classIRToshibaAC.html#abdc35338e4a18132d56bf6b46ddea590',1,'IRToshibaAC::on()'],['../classIRTrotecESP.html#a86c050edab8409a9b38d28f311f19404',1,'IRTrotecESP::on()'],['../classIRVestelAc.html#a4ed05fb5cbdfa5677ca238616bf03922',1,'IRVestelAc::on()']]], + ['opmodetostring_4088',['opmodeToString',['../classIRac.html#a6dd1b87f2477bc3721d207b1fed482b8',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.html new file mode 100644 index 000000000..f17c412c9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.js new file mode 100644 index 000000000..83b7a1a88 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['panasonic_4089',['panasonic',['../classIRac.html#af873db2b9735127eb6f079861daed67a',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/mag_sel.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/mag_sel.png new file mode 100644 index 0000000000000000000000000000000000000000..39c0ed52a25dd9d080ee0d42ae6c6042bdfa04d7 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz6!2%?$TA$hhDVB6cUq=Rpjs4tz5?O(Kg=CK) zUj~NU84L`?eGCi_EEpJ?t}-xGu`@87+QPtK?83kxQ`TapwHK(CDaqU2h2ejD|C#+j z9%q3^WHAE+w=f7ZGR&GI0Tg5}@$_|Nf5gMiEhFgvHvB$N=!mC_V~EE2vzPXI9ZnEo zd+1zHor@dYLod2Y{ z@R$7$Z!PXTbY$|@#T!bMzm?`b<(R`cbw(gxJHzu zB$lLFB^RXvDF!10LknF)BV7aY5JN*NBMU1-b8Q0yD+2>vd*|CI8glbfGSez?Ylunu RoetE%;OXk;vd$@?2>>CYplSdB literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.html new file mode 100644 index 000000000..76996d1c2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.js new file mode 100644 index 000000000..f3d7c6876 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['iracutils_3578',['IRAcUtils',['../namespaceIRAcUtils.html',1,'']]], + ['irutils_3579',['irutils',['../namespaceirutils.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.html new file mode 100644 index 000000000..c69e3662f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.js new file mode 100644 index 000000000..cc0a30d3e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['stdac_3580',['stdAc',['../namespacestdAc.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/nomatches.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/nomatches.html new file mode 100644 index 000000000..437732089 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
    +
    No Matches
    +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.html new file mode 100644 index 000000000..9a6a29ad3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.js new file mode 100644 index 000000000..09c98c152 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['deprecated_20list_7122',['Deprecated List',['../deprecated.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.html new file mode 100644 index 000000000..132ee038e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.js new file mode 100644 index 000000000..19c13b8cf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['irremoteesp8266_20library_20api_20documentation_7123',['IRremoteESP8266 Library API Documentation',['../index.html',1,'']]], + ['internationalisation_20_28i18n_29_20_26_20locale_20files_7124',['Internationalisation (I18N) & Locale Files',['../md_src_locale_README.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.html new file mode 100644 index 000000000..6109d4704 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.js new file mode 100644 index 000000000..08bad4bef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['todo_20list_7125',['Todo List',['../todo.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.html new file mode 100644 index 000000000..bbe15faaa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.js new file mode 100644 index 000000000..ae64177b7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['irhitachiac344_7121',['IRHitachiAc344',['../classIRHitachiAc424.html#a3c885313a79bf8c02bc5eb9f7d80088b',1,'IRHitachiAc424']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.css b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.css new file mode 100644 index 000000000..3cf9df94a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + float: none; + margin-top: 8px; + right: 0px; + width: 170px; + height: 24px; + z-index: 102; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:115px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; + -webkit-border-radius: 0px; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:8px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; + z-index:10000; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.js new file mode 100644 index 000000000..a554ab9cb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.js @@ -0,0 +1,814 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e(R!W8j_r#qQ#gnr4kAxdU#F0+OBry$Z+ z_0PMi;P|#{d%mw(dnw=jM%@$onTJa%@6Nm3`;2S#nwtVFJI#`U@2Q@@JCCctagvF- z8H=anvo~dTmJ2YA%wA6IHRv%{vxvUm|R)kgZeo zmX%Zb;mpflGZdXCTAgit`||AFzkI#z&(3d4(htA?U2FOL4WF6wY&TB#n3n*I4+hl| z*NBpo#FA92vEu822WQ%mvv4FO#qs` BFGc_W literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_r.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_r.png new file mode 100644 index 0000000000000000000000000000000000000000..1af5d21ee13e070d7600f1c4657fde843b953a69 GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9c!2%@BXHTsJQY`6?zK#qG8~eHcB(ehe3dtTp zz6=bxGZ+|(`xqD=STHa&U1eaXVrO7DwS|Gf*oA>XrmV$GYcEhOQT(QLuS{~ooZ2P@v=Xc@RKW@Irliv8_;wroU0*)0O?temdsA~70jrdux+`@W7 z-N(<(C)L?hOO?KV{>8(jC{hpKsws)#Fh zvsO>IB+gb@b+rGWaO&!a9Z{!U+fV*s7TS>fdt&j$L%^U@Epd$~Nl7e8wMs5Z1yT$~ z28I^8hDN#u<{^fLRz?<9hUVG^237_Jy7tbuQ8eV{r(~v8;?@w8^gA7>fx*+&&t;uc GLK6VEQpiUD literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/searchdata.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/searchdata.js new file mode 100644 index 000000000..d96a757c3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/searchdata.js @@ -0,0 +1,45 @@ +var indexSectionsWithContent = +{ + 0: "_abcdefghijklmnopqrstuvwxyz~", + 1: "dimst", + 2: "is", + 3: "defirz", + 4: "_abcdefghiklmnoprstuvwx~", + 5: "_abcdefhiklmnopqrstuvwz", + 6: "s", + 7: "dfghlopsw", + 8: "acdefghijklmnprstuvwyz", + 9: "i", + 10: "dit" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "classes", + 2: "namespaces", + 3: "files", + 4: "functions", + 5: "variables", + 6: "typedefs", + 7: "enums", + 8: "enumvalues", + 9: "related", + 10: "pages" +}; + +var indexSectionLabels = +{ + 0: "All", + 1: "Classes", + 2: "Namespaces", + 3: "Files", + 4: "Functions", + 5: "Variables", + 6: "Typedefs", + 7: "Enumerations", + 8: "Enumerator", + 9: "Friends", + 10: "Pages" +}; + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.html new file mode 100644 index 000000000..376db4791 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.js new file mode 100644 index 000000000..d482b28e6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['string_6975',['String',['../IRremoteESP8266_8h.html#afbeda3fd1bdc8c37d01bdf9f5c8274ff',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.html new file mode 100644 index 000000000..bf3eba5cc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.js new file mode 100644 index 000000000..5dc345ec5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.js @@ -0,0 +1,36 @@ +var searchData= +[ + ['_5fclean_4342',['_clean',['../classIRFujitsuAC.html#acf7808cfeb6e15cea1d5ee8196075e04',1,'IRFujitsuAC']]], + ['_5fcmd_4343',['_cmd',['../classIRFujitsuAC.html#a5e66bc4a24b892525cfa02bb4d741cbf',1,'IRFujitsuAC']]], + ['_5fdesiredtemp_4344',['_desiredtemp',['../classIRWhirlpoolAc.html#aee17cfa10f19e0df992b25cff58e9613',1,'IRWhirlpoolAc']]], + ['_5fdutycycle_4345',['_dutycycle',['../classIRsend.html#a602e96e8cdbd6af41d288d905043e51f',1,'IRsend']]], + ['_5ffan_4346',['_fan',['../classIRSharpAc.html#ad0f4e6025f2952c477bbd3f72a64d2fe',1,'IRSharpAc']]], + ['_5ffanspeed_4347',['_fanSpeed',['../classIRFujitsuAC.html#a537f02328039c044f7152bf0a61a05c9',1,'IRFujitsuAC']]], + ['_5ffilter_4348',['_filter',['../classIRFujitsuAC.html#a4a2f96f4f1cd6650d48ebc3b13fd561c',1,'IRFujitsuAC']]], + ['_5fforcepower_4349',['_forcepower',['../classIRSamsungAc.html#a022c96bfab671b1d0b6b5b331be31993',1,'IRSamsungAc']]], + ['_5ffreq_5funittest_4350',['_freq_unittest',['../classIRsend.html#a2caec2f35ecdb890b1e34d9eb3642363',1,'IRsend']]], + ['_5finverted_4351',['_inverted',['../classIRac.html#a9cfaa0b92819f06b3aa5b3e9e48b9d51',1,'IRac']]], + ['_5firsend_4352',['_irsend',['../classIRAmcorAc.html#a6245bb51fa206031c3348e3eb6cb096d',1,'IRAmcorAc::_irsend()'],['../classIRArgoAC.html#a1abd8d958c3e153c4f2aaf7a3716414e',1,'IRArgoAC::_irsend()'],['../classIRCarrierAc64.html#a17270f2b1d6cab828e2a51fc23b36437',1,'IRCarrierAc64::_irsend()'],['../classIRCoolixAC.html#a6c7033e72fb860bca600ba6ea6e7afef',1,'IRCoolixAC::_irsend()'],['../classIRCoronaAc.html#afba5a3c3cff3859303a91d136ad00b66',1,'IRCoronaAc::_irsend()'],['../classIRDaikinESP.html#a2f5a8cb170d54f06bfa3eeb9b8ff838e',1,'IRDaikinESP::_irsend()'],['../classIRDaikin2.html#aa8ba00ae2c09af098146452164c4cb3b',1,'IRDaikin2::_irsend()'],['../classIRDaikin216.html#ac0e88b92a5c75138ce5b3a31f0c09be2',1,'IRDaikin216::_irsend()'],['../classIRDaikin160.html#a3094f35b359d8774a95dd3896c0e45e4',1,'IRDaikin160::_irsend()'],['../classIRDaikin176.html#a24f7022eb1c1936f5ee95ac0d732584c',1,'IRDaikin176::_irsend()'],['../classIRDaikin128.html#a1f155cc34e6c21d206962239d0135d1b',1,'IRDaikin128::_irsend()'],['../classIRDaikin152.html#a9b203215156d48dabac0fa8fd19dc613',1,'IRDaikin152::_irsend()'],['../classIRDaikin64.html#a6eb57b0eb12dab12bd9cf2fe4fded2c7',1,'IRDaikin64::_irsend()'],['../classIRDelonghiAc.html#a8cbe8b6857b7492c108118b4eda3ecb0',1,'IRDelonghiAc::_irsend()'],['../classIRElectraAc.html#af8732b31f2a4421226220dd8a4a4f985',1,'IRElectraAc::_irsend()'],['../classIRFujitsuAC.html#a2b7fec218b3530b06ce8b49f472e9595',1,'IRFujitsuAC::_irsend()'],['../classIRGoodweatherAc.html#acf606eb9e024c99407138dbd058e98d9',1,'IRGoodweatherAc::_irsend()'],['../classIRGreeAC.html#a36390655badf0ad5b5809499a8634f70',1,'IRGreeAC::_irsend()'],['../classIRHaierAC.html#aec69643fe633a57d635754690225fdd1',1,'IRHaierAC::_irsend()'],['../classIRHaierACYRW02.html#a24dd00bfa5e062c5c7f459bcd60213b7',1,'IRHaierACYRW02::_irsend()'],['../classIRHitachiAc.html#a0e296fa54cc4c56e16c6fc58c7ad827f',1,'IRHitachiAc::_irsend()'],['../classIRHitachiAc1.html#a61ad6289fc3719a850299788e642b98b',1,'IRHitachiAc1::_irsend()'],['../classIRHitachiAc424.html#a39157a1bda46304429570be2880c6ec4',1,'IRHitachiAc424::_irsend()'],['../classIRHitachiAc3.html#a8dc3b713e29f3ea96a106868451ba728',1,'IRHitachiAc3::_irsend()'],['../classIRKelvinatorAC.html#ae3571bf6de20e47f81ad1da8f1d13118',1,'IRKelvinatorAC::_irsend()'],['../classIRLgAc.html#a779f321b65db6ad05ab3e578b38cf093',1,'IRLgAc::_irsend()'],['../classIRMideaAC.html#ae2b6068355ecdc360c4c2ca2fd8d921b',1,'IRMideaAC::_irsend()'],['../classIRMitsubishiAC.html#a6753b676690f35bc8ba73504fdc34946',1,'IRMitsubishiAC::_irsend()'],['../classIRMitsubishi136.html#acd14c7bb6b26d0603ee552a000e16d43',1,'IRMitsubishi136::_irsend()'],['../classIRMitsubishi112.html#af858d640f9b2fca053287f280c8a27c0',1,'IRMitsubishi112::_irsend()'],['../classIRMitsubishiHeavy152Ac.html#a1ebd4c8b06d64e0944358156f58d414e',1,'IRMitsubishiHeavy152Ac::_irsend()'],['../classIRMitsubishiHeavy88Ac.html#a1e999c9ee028d35c03cd6b4751bcb8be',1,'IRMitsubishiHeavy88Ac::_irsend()'],['../classIRNeoclimaAc.html#a43e42b1c7e68e5a85ed10454c6210be5',1,'IRNeoclimaAc::_irsend()'],['../classIRPanasonicAc.html#a065dcc65ef3dbb8f2384f883fb97d102',1,'IRPanasonicAc::_irsend()'],['../classIRSamsungAc.html#a5815878dbebe512c41c26924cf9f5eeb',1,'IRSamsungAc::_irsend()'],['../classIRSharpAc.html#a10ee598c31c0f8179ace953ed88e37c6',1,'IRSharpAc::_irsend()'],['../classIRTcl112Ac.html#a3f10e710a44c3a80f4f9ed5247b28058',1,'IRTcl112Ac::_irsend()'],['../classIRTecoAc.html#a283ff8b73ef2998f0668d0a03cba0938',1,'IRTecoAc::_irsend()'],['../classIRToshibaAC.html#a694609136a9cbdb9af5f8bb98411c2eb',1,'IRToshibaAC::_irsend()'],['../classIRTrotecESP.html#a1faa968fc2651dc1774160950e97a74e',1,'IRTrotecESP::_irsend()'],['../classIRVestelAc.html#a56d35fc5d39c97b4c6f2decf176e2cae',1,'IRVestelAc::_irsend()'],['../classIRWhirlpoolAc.html#af4fdac2382048e2776c787bebd482e9e',1,'IRWhirlpoolAc::_irsend()']]], + ['_5firtimer_5funittest_5fnow_4353',['_IRtimer_unittest_now',['../IRtimer_8cpp.html#a4ac531aa761a28d68edbc12967038180',1,'IRtimer.cpp']]], + ['_5flastsentpowerstate_4354',['_lastsentpowerstate',['../classIRSamsungAc.html#af1c6712dc05a451e815675abe972d9b4',1,'IRSamsungAc']]], + ['_5fmode_4355',['_mode',['../classIRFujitsuAC.html#a1b22f3bb3dc43e370aabad5b6efd7ca5',1,'IRFujitsuAC::_mode()'],['../classIRSharpAc.html#a169d5636aead556234dc301729050619',1,'IRSharpAc::_mode()']]], + ['_5fmodel_4356',['_model',['../classIRFujitsuAC.html#a181c71dbd46ceabdcfe08448ee32bba7',1,'IRFujitsuAC::_model()'],['../classIRGreeAC.html#ae357bf1611f349e2686f4f46c2581c47',1,'IRGreeAC::_model()']]], + ['_5fmodulation_4357',['_modulation',['../classIRac.html#acc6b7380f11c38d13fffa99ca2189a9b',1,'IRac']]], + ['_5foutsidequiet_4358',['_outsideQuiet',['../classIRFujitsuAC.html#a20a794245e0bc44607faf7927a285672',1,'IRFujitsuAC']]], + ['_5fpin_4359',['_pin',['../classIRac.html#aba78a2510d8cdcaf4c601e8b0574ae6c',1,'IRac']]], + ['_5fprev_4360',['_prev',['../classIRac.html#a8c63dc78c49f3714887fea0feefffd44',1,'IRac']]], + ['_5fprevioustemp_4361',['_previoustemp',['../classIRHitachiAc.html#a1368dcd7f4c0049822fd2b9b1e0acb5e',1,'IRHitachiAc::_previoustemp()'],['../classIRHitachiAc424.html#aba6c17936775e268744af23a4a533f92',1,'IRHitachiAc424::_previoustemp()']]], + ['_5fprotocol_4362',['_protocol',['../classIRLgAc.html#a9bd32e865a7358bbf32830d888e2786a',1,'IRLgAc']]], + ['_5fsaved_5ftemp_4363',['_saved_temp',['../classIRDaikin176.html#a8f1d6c765bf09c1a3dc9678c3939a5be',1,'IRDaikin176::_saved_temp()'],['../classIRDelonghiAc.html#a724aa5748e714a7f0109a2f3502cd1d1',1,'IRDelonghiAc::_saved_temp()']]], + ['_5fsaved_5ftemp_5funits_4364',['_saved_temp_units',['../classIRDelonghiAc.html#a14fba6ccbc25da76744d28e7a40c385b',1,'IRDelonghiAc']]], + ['_5fstate_5flength_4365',['_state_length',['../classIRFujitsuAC.html#aea1819d0041f305e2c990f6f3eced865',1,'IRFujitsuAC']]], + ['_5fstate_5flength_5fshort_4366',['_state_length_short',['../classIRFujitsuAC.html#a7093cf32cd2e856ff692aebc732c1d50',1,'IRFujitsuAC']]], + ['_5fswingh_4367',['_swingh',['../classIRPanasonicAc.html#ad0300ee66bcab38e13724520cb3226f9',1,'IRPanasonicAc']]], + ['_5fswingmode_4368',['_swingMode',['../classIRFujitsuAC.html#a74a00fbba55b457b68f61481ce9ffbaa',1,'IRFujitsuAC']]], + ['_5fswingvtoggle_4369',['_SwingVToggle',['../classIRMideaAC.html#adb4318940487aea09116fe6b9f061470',1,'IRMideaAC']]], + ['_5ftemp_4370',['_temp',['../classIRFujitsuAC.html#afcff35df74885c63651134ba85359694',1,'IRFujitsuAC::_temp()'],['../classIRLgAc.html#a1eeb727ee96c26b784a607aabd4577c9',1,'IRLgAc::_temp()'],['../classIRPanasonicAc.html#af6511e3c9745ff6750dc6fc3fdda21b3',1,'IRPanasonicAc::_temp()'],['../classIRSharpAc.html#a1d0a6274534123133217175920c7cd95',1,'IRSharpAc::_temp()']]], + ['_5ftimer_5fnum_4371',['_timer_num',['../classIRrecv.html#aff11c0c20735b16ce411088003607911',1,'IRrecv']]], + ['_5ftimerms_5funittest_5fnow_4372',['_TimerMs_unittest_now',['../IRtimer_8cpp.html#aed35ce7fa92ebb856a03f81e756cb2c6',1,'IRtimer.cpp']]], + ['_5ftolerance_4373',['_tolerance',['../classIRrecv.html#a0459a65dd31b215713ad66a1e4f3540e',1,'IRrecv']]], + ['_5funknown_5fthreshold_4374',['_unknown_threshold',['../classIRrecv.html#adb8cbc5c1cb739f33f5be25b3a6c79bd',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.html new file mode 100644 index 000000000..49fe59a12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.js new file mode 100644 index 000000000..3f8cb0a00 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['address_4375',['address',['../classdecode__results.html#a2858c3a5e28eccca95d44aaa87b70e9e',1,'decode_results']]], + ['argo_4376',['argo',['../classIRArgoAC.html#ab607bde051712a57fe9c0a0cf9da20ac',1,'IRArgoAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.html new file mode 100644 index 000000000..92982ac57 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.js new file mode 100644 index 000000000..d1ff18c76 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['rawbuf_6946',['rawbuf',['../structirparams__t.html#a6f8a82b51fa206a8cb195e5838aa0cb3',1,'irparams_t::rawbuf()'],['../classdecode__results.html#a19043dc161cd5e0d3dcc82b5a7470e49',1,'decode_results::rawbuf()']]], + ['rawlen_6947',['rawlen',['../structirparams__t.html#a08e83386c65a90038e0d4922f1f6aa84',1,'irparams_t::rawlen()'],['../classdecode__results.html#a913e19fc5032fa1f97cf8afe0fa450ec',1,'decode_results::rawlen()']]], + ['rcvstate_6948',['rcvstate',['../structirparams__t.html#a63354788dab4569f4092cd05e77f0260',1,'irparams_t']]], + ['recvpin_6949',['recvpin',['../structirparams__t.html#a50da5aa1c42a69b01d50ea688db67d14',1,'irparams_t']]], + ['remote_6950',['remote',['../classIRDaikinESP.html#ac24751c23f6b27cb26dcd51e91c63c9b',1,'IRDaikinESP::remote()'],['../classIRGoodweatherAc.html#af511a0703a4cbc77f5b8a520abf11f2f',1,'IRGoodweatherAc::remote()'],['../classIRSharpAc.html#a411a4db0579ed84b54533dcde153d5da',1,'IRSharpAc::remote()']]], + ['remote_5fstate_6951',['remote_state',['../classIRAmcorAc.html#acef1c3896f03afd5d10d5cbb7ed105ce',1,'IRAmcorAc::remote_state()'],['../classIRCarrierAc64.html#a257272c7cb54f5854e79053c8223a43e',1,'IRCarrierAc64::remote_state()'],['../classIRCoolixAC.html#a03bf575961d4d924275cb16a45edaa46',1,'IRCoolixAC::remote_state()'],['../classIRCoronaAc.html#afcf0b21ac5c438dc560612a785a29864',1,'IRCoronaAc::remote_state()'],['../classIRDaikin2.html#a0b28396956687a4009cab7c860b9ce4b',1,'IRDaikin2::remote_state()'],['../classIRDaikin216.html#abf9bab0a52f9227d54f583488b024a85',1,'IRDaikin216::remote_state()'],['../classIRDaikin160.html#a17fb5726060e8872735559654a72cb22',1,'IRDaikin160::remote_state()'],['../classIRDaikin176.html#adb6863da11f0569524f0beb31681d0b5',1,'IRDaikin176::remote_state()'],['../classIRDaikin128.html#af1b36cc2f51cd145da3bfe7ec3d9134a',1,'IRDaikin128::remote_state()'],['../classIRDaikin152.html#aa16c89c0cb6d83aef83d293466dab197',1,'IRDaikin152::remote_state()'],['../classIRDaikin64.html#aa279d6df0d130e727c3a1500b283eda0',1,'IRDaikin64::remote_state()'],['../classIRDelonghiAc.html#a3b3364143c52dc2a29d9db43612c07b1',1,'IRDelonghiAc::remote_state()'],['../classIRElectraAc.html#a3f423f5d896e4bfc2f3a0ce04b596289',1,'IRElectraAc::remote_state()'],['../classIRFujitsuAC.html#a851b9192e1f18f6a4b2f1726d49ef33b',1,'IRFujitsuAC::remote_state()'],['../classIRGreeAC.html#a9e0cb21278ac3c9a72738ab8e6e09096',1,'IRGreeAC::remote_state()'],['../classIRHaierAC.html#a609abaeab9df642fdaccd77235a84eed',1,'IRHaierAC::remote_state()'],['../classIRHaierACYRW02.html#a08069ef89f5c5e2c1ba8563cdad24578',1,'IRHaierACYRW02::remote_state()'],['../classIRHitachiAc.html#a44b3d360b2a8044782b73f7f4a533a99',1,'IRHitachiAc::remote_state()'],['../classIRHitachiAc1.html#a13340cba808d457d6093f1c9efffc419',1,'IRHitachiAc1::remote_state()'],['../classIRHitachiAc424.html#a58bac4ef7f46ef1e9f38c1a144e2ca41',1,'IRHitachiAc424::remote_state()'],['../classIRHitachiAc3.html#a5602ded229a41796c205519449f7d509',1,'IRHitachiAc3::remote_state()'],['../classIRKelvinatorAC.html#a70f75821274e53cc5ed64ac53a6e32b4',1,'IRKelvinatorAC::remote_state()'],['../classIRLgAc.html#a481133671657b13ecce1bd08f710089d',1,'IRLgAc::remote_state()'],['../classIRMideaAC.html#a8f122367cc407e7bb658fe7f3132effb',1,'IRMideaAC::remote_state()'],['../classIRMitsubishiAC.html#ac0a149b9705371e59c45ece162bc1aab',1,'IRMitsubishiAC::remote_state()'],['../classIRMitsubishi136.html#ad1e80d693d3558f0bed4c0f7995bddd5',1,'IRMitsubishi136::remote_state()'],['../classIRMitsubishi112.html#a64a40e57208d08b5cd6ef87a7c8d6671',1,'IRMitsubishi112::remote_state()'],['../classIRMitsubishiHeavy152Ac.html#a6d333f238bf1b42e39919d4897080aa8',1,'IRMitsubishiHeavy152Ac::remote_state()'],['../classIRMitsubishiHeavy88Ac.html#a46be0e755530f59fad7d3f9050ecc107',1,'IRMitsubishiHeavy88Ac::remote_state()'],['../classIRNeoclimaAc.html#a336507e0635ede3b9ebf53881ece50bb',1,'IRNeoclimaAc::remote_state()'],['../classIRPanasonicAc.html#a85d5118c0ed947cc77f2ed94b0d44e4a',1,'IRPanasonicAc::remote_state()'],['../classIRSamsungAc.html#a5966a3b665ce034de807de1955396e10',1,'IRSamsungAc::remote_state()'],['../classIRTcl112Ac.html#a6eda1148a977a3ccf0c6c30239fca4c8',1,'IRTcl112Ac::remote_state()'],['../classIRTecoAc.html#a3c2ad7587ed4f5589deb20d8dc16b1e4',1,'IRTecoAc::remote_state()'],['../classIRToshibaAC.html#aab228aa6db2255dddf98a46a25cbb0f0',1,'IRToshibaAC::remote_state()'],['../classIRTrotecESP.html#afccba55e2c3d42c716591c10bc9afa18',1,'IRTrotecESP::remote_state()'],['../classIRVestelAc.html#a74d889a0db2fa63a2e38aaa15819568c',1,'IRVestelAc::remote_state()'],['../classIRWhirlpoolAc.html#a65333985c39773896071081ebcca4821',1,'IRWhirlpoolAc::remote_state()']]], + ['remote_5ftime_5fstate_6952',['remote_time_state',['../classIRVestelAc.html#a9b10e4a0c1f71aecbeb385666d1a53bd',1,'IRVestelAc']]], + ['repeat_6953',['repeat',['../classdecode__results.html#a09da48786fe3966cd5621840fd771bfa',1,'decode_results']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.html new file mode 100644 index 000000000..94f1a8cf9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.js new file mode 100644 index 000000000..7b6252538 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['saved_5fstate_6954',['saved_state',['../classIRCoolixAC.html#aec0bce8019d7d49a30915394bee56b9a',1,'IRCoolixAC']]], + ['scrap_6955',['scrap',['../unionmagiquest.html#afd0bcf9a87f0fa2db87b68b211952a73',1,'magiquest']]], + ['sleep_6956',['sleep',['../structstdAc_1_1state__t.html#a94fa6098d7422292a1c6943973cd106a',1,'stdAc::state_t']]], + ['sleepflag_6957',['sleepFlag',['../classIRCoolixAC.html#a26560e04d1f77830e40e5570845b9e06',1,'IRCoolixAC']]], + ['start_6958',['start',['../classIRtimer.html#aaa087b8688ff8150e0fc1ec6d5c4a52a',1,'IRtimer::start()'],['../classTimerMs.html#a15ad2e08a5931397391d48f040722f65',1,'TimerMs::start()']]], + ['state_6959',['state',['../classdecode__results.html#aaeb4b1b2e950bdd181582c385b2f4305',1,'decode_results']]], + ['success_6960',['success',['../structmatch__result__t.html#a13fe18ae6cf89364df443a64295b2f90',1,'match_result_t']]], + ['swingflag_6961',['swingFlag',['../classIRCoolixAC.html#a6d61903a90cebef56b931bebbfa5cba3',1,'IRCoolixAC']]], + ['swingh_6962',['swingh',['../structstdAc_1_1state__t.html#a761bb702891ed1fa35906929a4c8a3f8',1,'stdAc::state_t']]], + ['swinghflag_6963',['swingHFlag',['../classIRCoolixAC.html#a1c5fb27fb58d4d1a1fd8c9931eba58c4',1,'IRCoolixAC']]], + ['swingv_6964',['swingv',['../structstdAc_1_1state__t.html#a35477d368350d8981ad8b7b09505857e',1,'stdAc::state_t']]], + ['swingvflag_6965',['swingVFlag',['../classIRCoolixAC.html#adf18ad8494466f6301176ce10aa3a075',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.html new file mode 100644 index 000000000..61c013a4e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.js new file mode 100644 index 000000000..97e250db2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['timeout_6966',['timeout',['../structirparams__t.html#a132d6448ad59f03f6b35c4b04a6d1af4',1,'irparams_t']]], + ['timer_6967',['timer',['../structirparams__t.html#a6d4594a4d6bf8a2587095be7adfc018d',1,'irparams_t']]], + ['turbo_6968',['turbo',['../structstdAc_1_1state__t.html#aae084b686685f2b2a07ccdda649e358c',1,'stdAc::state_t']]], + ['turboflag_6969',['turboFlag',['../classIRCoolixAC.html#a60a8a848951555dba34f2a317d6611ea',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.html new file mode 100644 index 000000000..87b7ca676 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.js new file mode 100644 index 000000000..738a0e612 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['use_5ftime_5fstate_6970',['use_time_state',['../classIRVestelAc.html#af1b622c50a4952fb3edaf483e1bf9328',1,'IRVestelAc']]], + ['used_6971',['used',['../structmatch__result__t.html#a26cea305aa83ed65b88ac0b6ed6de54a',1,'match_result_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.html new file mode 100644 index 000000000..874fe5958 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.js new file mode 100644 index 000000000..20f2534d1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['value_6972',['value',['../classdecode__results.html#a033502b7a6b4b0412e5a2062e33c5f47',1,'decode_results']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.html new file mode 100644 index 000000000..3ca879906 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.js new file mode 100644 index 000000000..6837a7b68 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['wand_5fid_6973',['wand_id',['../unionmagiquest.html#a1b159cd47635d548e1d4198cd6d41e93',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.html new file mode 100644 index 000000000..2b5a4330f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.js new file mode 100644 index 000000000..f11625d47 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['zonefollowflag_6974',['zoneFollowFlag',['../classIRCoolixAC.html#a9cb37ed201fcf842c153f0414d9bfd9f',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.html new file mode 100644 index 000000000..0c8a18cf9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.js new file mode 100644 index 000000000..a68ff94f4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['beep_4377',['beep',['../structstdAc_1_1state__t.html#a468ce4cf8b68467964b1f1840257663d',1,'stdAc::state_t']]], + ['bits_4378',['bits',['../classdecode__results.html#aa5ba2fd53bdb36bdc120d8eabd9f36d7',1,'decode_results']]], + ['bufsize_4379',['bufsize',['../structirparams__t.html#a2b34d697b85ee6a0ce08344c941e50ec',1,'irparams_t']]], + ['byte_4380',['byte',['../unionmagiquest.html#af1a9c9a147a1610fe5f0e77ca3e09e44',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.html new file mode 100644 index 000000000..19a31fc28 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.js new file mode 100644 index 000000000..5ed66be69 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['celsius_4381',['celsius',['../structstdAc_1_1state__t.html#a235b17f3979b155b368bfdc2b14123f5',1,'stdAc::state_t']]], + ['clean_4382',['clean',['../structstdAc_1_1state__t.html#a703fa57ade60d68deccbb2a59258b32a',1,'stdAc::state_t']]], + ['cleanflag_4383',['cleanFlag',['../classIRCoolixAC.html#a9280bc7517713dae451a64e35674804d',1,'IRCoolixAC']]], + ['clock_4384',['clock',['../structstdAc_1_1state__t.html#ab1d76172930ebfe992fd9b700369e787',1,'stdAc::state_t']]], + ['cmd_4385',['cmd',['../unionmagiquest.html#a71f7646ffd59f0478ae28fad2d724a44',1,'magiquest']]], + ['command_4386',['command',['../classdecode__results.html#a9b750d09f713b0693472f815fd0fd402',1,'decode_results']]], + ['cool_5fmode_4387',['cool_mode',['../classIRArgoAC.html#a74e7e489d743f213664d9259f1e7a431',1,'IRArgoAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.html new file mode 100644 index 000000000..bdc37be7f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.js new file mode 100644 index 000000000..1f911c339 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['data_4388',['data',['../structmatch__result__t.html#ae88be61a6d1ffa7c3525aa958f4c0d25',1,'match_result_t']]], + ['decode_5ftype_4389',['decode_type',['../classdecode__results.html#a9c0e9f161b9c90dc10b7561d4c0b50fa',1,'decode_results']]], + ['degrees_4390',['degrees',['../structstdAc_1_1state__t.html#a3d1ff0ff2e0035db4ee8ead5c53b2dbd',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.html new file mode 100644 index 000000000..6aa2249b4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.js new file mode 100644 index 000000000..fdbe17906 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['econo_4391',['econo',['../structstdAc_1_1state__t.html#a580c826c6d9671715adfe8445531b957',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.html new file mode 100644 index 000000000..ce4a90635 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.js new file mode 100644 index 000000000..d6e83ad6b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['fanspeed_4392',['fanspeed',['../structstdAc_1_1state__t.html#a28a50c877a0eaa71689ccc3bf9c957d7',1,'stdAc::state_t']]], + ['filter_4393',['filter',['../structstdAc_1_1state__t.html#a41e4b957f9e011ddb32d35bfcd56c0e7',1,'stdAc::state_t']]], + ['flap_5fmode_4394',['flap_mode',['../classIRArgoAC.html#abfc383d92ced7d47945cc5ac996e5fc4',1,'IRArgoAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.html new file mode 100644 index 000000000..39ffd4746 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.js new file mode 100644 index 000000000..adfaa07ee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['heat_5fmode_4395',['heat_mode',['../classIRArgoAC.html#a255762f71502b9ffeb0686759991ec53',1,'IRArgoAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.html new file mode 100644 index 000000000..37a2eddfa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.js new file mode 100644 index 000000000..e951bfb37 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['irparams_4396',['irparams',['../IRrecv_8cpp.html#a5620be27a7445f25d43dbe3432ed6fd1',1,'IRrecv.cpp']]], + ['irparams_5fsave_4397',['irparams_save',['../classIRrecv.html#a6fdac84ce51ce119972bf121ccc95aab',1,'IRrecv::irparams_save()'],['../IRrecv_8cpp.html#a96e84ae171529ee954c53e2e938dd998',1,'irparams_save(): IRrecv.cpp']]], + ['irpin_4398',['IRpin',['../classIRsend.html#ae4a6ea1e72f4861167002d6e7bf17b7c',1,'IRsend']]], + ['irremote_5fmux_4399',['irremote_mux',['../IRrecv_8cpp.html#ad2612f65707186ef7df0179d3636b4ea',1,'IRrecv.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.html new file mode 100644 index 000000000..21e5a4f3c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.js new file mode 100644 index 000000000..005123ec5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.js @@ -0,0 +1,2528 @@ +var searchData= +[ + ['k3dstr_4400',['k3DStr',['../IRtext_8cpp.html#aedbfd5e861447c2cde9f7bb6aade1370',1,'k3DStr(): IRtext.cpp'],['../IRtext_8h.html#a084c940b7221cd1d85d4a3b58063051d',1,'k3DStr(): IRtext.cpp']]], + ['k6thsensestr_4401',['k6thSenseStr',['../IRtext_8cpp.html#ad0bfc24932f22a599c7e7bf04fb57b10',1,'k6thSenseStr(): IRtext.cpp'],['../IRtext_8h.html#a7425119d393b134c4659db9d35691e35',1,'k6thSenseStr(): IRtext.cpp']]], + ['k8cheatstr_4402',['k8CHeatStr',['../IRtext_8cpp.html#ac6ab822edcfe7768cd1a8b0426a1bd59',1,'k8CHeatStr(): IRtext.cpp'],['../IRtext_8h.html#acfcc1bc573f4520f3e37977a949b74e8',1,'k8CHeatStr(): IRtext.cpp']]], + ['kairflowstr_4403',['kAirFlowStr',['../IRtext_8cpp.html#a7ecf1c6454bbf9963ca85a2bd7d4a34a',1,'kAirFlowStr(): IRtext.cpp'],['../IRtext_8h.html#a0f7e35a10e28e403da578c85b0e6b180',1,'kAirFlowStr(): IRtext.cpp']]], + ['kairwellbits_4404',['kAirwellBits',['../IRremoteESP8266_8h.html#a570219a14f2d19c7a6ce0aecd37a3b1f',1,'IRremoteESP8266.h']]], + ['kairwellfootermark_4405',['kAirwellFooterMark',['../ir__Airwell_8cpp.html#a2f41c6fe12eb5b3369ffb67fc6333431',1,'ir_Airwell.cpp']]], + ['kairwellhalfclockperiod_4406',['kAirwellHalfClockPeriod',['../ir__Airwell_8cpp.html#a955f70631a1bc9be8453ccc9fbb3ecfc',1,'ir_Airwell.cpp']]], + ['kairwellhdrmark_4407',['kAirwellHdrMark',['../ir__Airwell_8cpp.html#ad0c7b6c28df61b706eef2ec05506d8c2',1,'ir_Airwell.cpp']]], + ['kairwellhdrspace_4408',['kAirwellHdrSpace',['../ir__Airwell_8cpp.html#ad7e80d679eaa5742f261619cc1115567',1,'ir_Airwell.cpp']]], + ['kairwellminrepeats_4409',['kAirwellMinRepeats',['../IRremoteESP8266_8h.html#a669217ae5aa0baa159f7452f53551875',1,'IRremoteESP8266.h']]], + ['kairwelloverhead_4410',['kAirwellOverhead',['../ir__Airwell_8cpp.html#a8365fb4b254f5eeb6fed59cdc627fead',1,'ir_Airwell.cpp']]], + ['kaiwarct501bits_4411',['kAiwaRcT501Bits',['../IRremoteESP8266_8h.html#a9078adf040d21c9c3eb10ed69f9dced6',1,'IRremoteESP8266.h']]], + ['kaiwarct501minrepeats_4412',['kAiwaRcT501MinRepeats',['../IRremoteESP8266_8h.html#ad796714d955b6cc8e207b03058eae5a3',1,'IRremoteESP8266.h']]], + ['kaiwarct501postbits_4413',['kAiwaRcT501PostBits',['../ir__Aiwa_8cpp.html#a1ad2ad119febec79cb20bf2356ae4dd4',1,'ir_Aiwa.cpp']]], + ['kaiwarct501postdata_4414',['kAiwaRcT501PostData',['../ir__Aiwa_8cpp.html#a5c8aa67edc9ceed9dc398f878930b1cb',1,'ir_Aiwa.cpp']]], + ['kaiwarct501prebits_4415',['kAiwaRcT501PreBits',['../ir__Aiwa_8cpp.html#a614f30df204126f234ce1d256406f075',1,'ir_Aiwa.cpp']]], + ['kaiwarct501predata_4416',['kAiwaRcT501PreData',['../ir__Aiwa_8cpp.html#a9aafbd2938553c9b97dac6f4e3edee6e',1,'ir_Aiwa.cpp']]], + ['kallprotocolnamesstr_4417',['kAllProtocolNamesStr',['../IRtext_8cpp.html#a3ef36cf85e44181ecc4d11085b7abed6',1,'kAllProtocolNamesStr(): IRtext.cpp'],['../IRtext_8h.html#aa0dfe94cd4cba3bec642328f399dc775',1,'kAllProtocolNamesStr(): IRtext.cpp']]], + ['kalokabits_4418',['kAlokaBits',['../IRremoteESP8266_8h.html#a864918ca63a5fe7345688a72d61ddf23',1,'IRremoteESP8266.h']]], + ['kalokaledblue_4419',['kAlokaLedBlue',['../ir__NEC_8h.html#a49908cff59d8e7a4926638c74b796c61',1,'ir_NEC.h']]], + ['kalokaledgreen_4420',['kAlokaLedGreen',['../ir__NEC_8h.html#aa6c6afc878f4b2a8d4b9349bf6766fb6',1,'ir_NEC.h']]], + ['kalokaledlightgreen_4421',['kAlokaLedLightGreen',['../ir__NEC_8h.html#ab2daa6b17fd2d5e30fc47105e4c3c6b6',1,'ir_NEC.h']]], + ['kalokaledmidblue_4422',['kAlokaLedMidBlue',['../ir__NEC_8h.html#a47d88027186cd96216bea935ca93d7bc',1,'ir_NEC.h']]], + ['kalokaledorange_4423',['kAlokaLedOrange',['../ir__NEC_8h.html#a40f8ae5d6ec8f6aa887c73f032ce03bb',1,'ir_NEC.h']]], + ['kalokaledpink_4424',['kAlokaLedPink',['../ir__NEC_8h.html#a53cf14e43062b82259e8d171a992ceff',1,'ir_NEC.h']]], + ['kalokaledpinkred_4425',['kAlokaLedPinkRed',['../ir__NEC_8h.html#a20ef8a4a844577849b4b3bc7a86fe352',1,'ir_NEC.h']]], + ['kalokaledrainbow_4426',['kAlokaLedRainbow',['../ir__NEC_8h.html#a724ce8d8c71c07a019ed2ddfba269151',1,'ir_NEC.h']]], + ['kalokaledred_4427',['kAlokaLedRed',['../ir__NEC_8h.html#ade8f47e4607be919ca05b6dd6ed23ae9',1,'ir_NEC.h']]], + ['kalokaledtreegrow_4428',['kAlokaLedTreeGrow',['../ir__NEC_8h.html#a5ecb76db25229f9f05044e54239144ee',1,'ir_NEC.h']]], + ['kalokaledwhite_4429',['kAlokaLedWhite',['../ir__NEC_8h.html#a0c0b35e9d905de0b299e38e5807f363e',1,'ir_NEC.h']]], + ['kalokaledyellow_4430',['kAlokaLedYellow',['../ir__NEC_8h.html#a1853a0e8856b8af97f458a180c41d6d5',1,'ir_NEC.h']]], + ['kalokanightfade_4431',['kAlokaNightFade',['../ir__NEC_8h.html#adb8489faf42032a38187759b5f1037a1',1,'ir_NEC.h']]], + ['kalokanighttimer_4432',['kAlokaNightTimer',['../ir__NEC_8h.html#a1b48b8bbd71fbe3728487f36123f4e4b',1,'ir_NEC.h']]], + ['kalokapower_4433',['kAlokaPower',['../ir__NEC_8h.html#a147ecbccf8f11976f65b3f374b6ab2d0',1,'ir_NEC.h']]], + ['kamcorauto_4434',['kAmcorAuto',['../ir__Amcor_8h.html#a9c02a27d5ed80963ff3b1ff32fc261c5',1,'ir_Amcor.h']]], + ['kamcorbits_4435',['kAmcorBits',['../IRremoteESP8266_8h.html#a34bcab75a8ab94adfd46a245dd0748db',1,'IRremoteESP8266.h']]], + ['kamcorchecksumbyte_4436',['kAmcorChecksumByte',['../ir__Amcor_8h.html#a6c60b38dd5b08d5787e346a55dfe0111',1,'ir_Amcor.h']]], + ['kamcorcool_4437',['kAmcorCool',['../ir__Amcor_8h.html#a221c452a3323bd4d39a6084f84ecefbd',1,'ir_Amcor.h']]], + ['kamcordefaultrepeat_4438',['kAmcorDefaultRepeat',['../IRremoteESP8266_8h.html#a746e1ce73c2ebd9bd1f5300494820a0c',1,'IRremoteESP8266.h']]], + ['kamcordry_4439',['kAmcorDry',['../ir__Amcor_8h.html#a4d285053d14cf85d0c17e738c53538cd',1,'ir_Amcor.h']]], + ['kamcorfan_4440',['kAmcorFan',['../ir__Amcor_8h.html#a5fa0c6e3a73c94fc419ff8d1aa1423c2',1,'ir_Amcor.h']]], + ['kamcorfanauto_4441',['kAmcorFanAuto',['../ir__Amcor_8h.html#a3199dbace6444ed6ca7ff2e55a8a3a24',1,'ir_Amcor.h']]], + ['kamcorfanmax_4442',['kAmcorFanMax',['../ir__Amcor_8h.html#a08ea054d4121220ba758a0e0cacef8ca',1,'ir_Amcor.h']]], + ['kamcorfanmed_4443',['kAmcorFanMed',['../ir__Amcor_8h.html#a9ef019a27cf0724ff1f1ff39e06c0c87',1,'ir_Amcor.h']]], + ['kamcorfanmin_4444',['kAmcorFanMin',['../ir__Amcor_8h.html#a0276f72dc5b39557850838c8c70fd157',1,'ir_Amcor.h']]], + ['kamcorfanoffset_4445',['kAmcorFanOffset',['../ir__Amcor_8h.html#aaa3beed08599db5e155b3b54a3fc60bd',1,'ir_Amcor.h']]], + ['kamcorfansize_4446',['kAmcorFanSize',['../ir__Amcor_8h.html#a4a6d1ad01cd89d8064efdd29311948b7',1,'ir_Amcor.h']]], + ['kamcorfootermark_4447',['kAmcorFooterMark',['../ir__Amcor_8cpp.html#a3f877b05b07810ff43712dd4412af4f5',1,'ir_Amcor.cpp']]], + ['kamcorgap_4448',['kAmcorGap',['../ir__Amcor_8cpp.html#a090f83ec3d4f3fd10baa16bf512dca23',1,'ir_Amcor.cpp']]], + ['kamcorhdrmark_4449',['kAmcorHdrMark',['../ir__Amcor_8cpp.html#ab528f545e9af4ffb0f13d5674cfd1589',1,'ir_Amcor.cpp']]], + ['kamcorhdrspace_4450',['kAmcorHdrSpace',['../ir__Amcor_8cpp.html#ae0e00c60c4220d27ef7051b45f2ae8b5',1,'ir_Amcor.cpp']]], + ['kamcorheat_4451',['kAmcorHeat',['../ir__Amcor_8h.html#a9467539574a0030d166fac79684216f8',1,'ir_Amcor.h']]], + ['kamcormax_4452',['kAmcorMax',['../ir__Amcor_8h.html#afac44479dc50e3885e474d2cf8d1f878',1,'ir_Amcor.h']]], + ['kamcormaxoffset_4453',['kAmcorMaxOffset',['../ir__Amcor_8h.html#a2740428d3e431ff7b04e85ec73009660',1,'ir_Amcor.h']]], + ['kamcormaxsize_4454',['kAmcorMaxSize',['../ir__Amcor_8h.html#a01d5ae3a2abe48f35971ad5373230ff8',1,'ir_Amcor.h']]], + ['kamcormaxtemp_4455',['kAmcorMaxTemp',['../ir__Amcor_8h.html#a6460abc4e2b44e4ef3f680c7e195c019',1,'ir_Amcor.h']]], + ['kamcormintemp_4456',['kAmcorMinTemp',['../ir__Amcor_8h.html#a2d952bf3f43cb55253a89db1bcc0b568',1,'ir_Amcor.h']]], + ['kamcormodefanbyte_4457',['kAmcorModeFanByte',['../ir__Amcor_8h.html#a077021dbba23d1727caf1fe037e5bd88',1,'ir_Amcor.h']]], + ['kamcormodeoffset_4458',['kAmcorModeOffset',['../ir__Amcor_8h.html#a1aebade414c6d493d5fd1ae8d9b4f626',1,'ir_Amcor.h']]], + ['kamcormodesize_4459',['kAmcorModeSize',['../ir__Amcor_8h.html#aa306915bcc7fcf7209584d84dc5d1aa4',1,'ir_Amcor.h']]], + ['kamcoronemark_4460',['kAmcorOneMark',['../ir__Amcor_8cpp.html#a402a3643dc6b85813eb5f28d742c4e7f',1,'ir_Amcor.cpp']]], + ['kamcoronespace_4461',['kAmcorOneSpace',['../ir__Amcor_8cpp.html#a51163573fdc7b8017c7311f0e4011b1b',1,'ir_Amcor.cpp']]], + ['kamcorpowerbyte_4462',['kAmcorPowerByte',['../ir__Amcor_8h.html#a47e85c75d262d9091f27c7ddca141ab7',1,'ir_Amcor.h']]], + ['kamcorpoweroff_4463',['kAmcorPowerOff',['../ir__Amcor_8h.html#aeccd11f34ca0a93f682ab6c144f07fb7',1,'ir_Amcor.h']]], + ['kamcorpoweroffset_4464',['kAmcorPowerOffset',['../ir__Amcor_8h.html#aeebaa4acca33937e47df058885d3167f',1,'ir_Amcor.h']]], + ['kamcorpoweron_4465',['kAmcorPowerOn',['../ir__Amcor_8h.html#adf21c2364e64c818ba5379e78cae9d5c',1,'ir_Amcor.h']]], + ['kamcorpowersize_4466',['kAmcorPowerSize',['../ir__Amcor_8h.html#a6a4e3568f341a7a60bdf7a4dc56fd482',1,'ir_Amcor.h']]], + ['kamcorspecialbyte_4467',['kAmcorSpecialByte',['../ir__Amcor_8h.html#aa73133f5a673eebd7e8ca99155138cb7',1,'ir_Amcor.h']]], + ['kamcorstatelength_4468',['kAmcorStateLength',['../IRremoteESP8266_8h.html#a62866e6918602533d590912487150bc7',1,'IRremoteESP8266.h']]], + ['kamcortempbyte_4469',['kAmcorTempByte',['../ir__Amcor_8h.html#a9d352d1da6a93fc990786662fb3698de',1,'ir_Amcor.h']]], + ['kamcortempoffset_4470',['kAmcorTempOffset',['../ir__Amcor_8h.html#ae7113af741d2edfebf0fc4d4cc181b2d',1,'ir_Amcor.h']]], + ['kamcortempsize_4471',['kAmcorTempSize',['../ir__Amcor_8h.html#a4c5fb23ff11e99a2b860553b145e33bb',1,'ir_Amcor.h']]], + ['kamcortolerance_4472',['kAmcorTolerance',['../ir__Amcor_8cpp.html#ad7a4b72f06c5e71002a44c3e4d483bef',1,'ir_Amcor.cpp']]], + ['kamcorventoffset_4473',['kAmcorVentOffset',['../ir__Amcor_8h.html#aa231f74cdba0fe6813c2d6c77268d300',1,'ir_Amcor.h']]], + ['kamcorventon_4474',['kAmcorVentOn',['../ir__Amcor_8h.html#a0774a9180ab233da61c77c717be02521',1,'ir_Amcor.h']]], + ['kamcorventsize_4475',['kAmcorVentSize',['../ir__Amcor_8h.html#a55cd6972c20ddc0fa24ee8f42b50e46f',1,'ir_Amcor.h']]], + ['kamcorzeromark_4476',['kAmcorZeroMark',['../ir__Amcor_8cpp.html#a6f16bcf81087461a4e196a2c670f29ee',1,'ir_Amcor.cpp']]], + ['kamcorzerospace_4477',['kAmcorZeroSpace',['../ir__Amcor_8cpp.html#a0cbb87d1a5bb594cf428c79cd96c8733',1,'ir_Amcor.cpp']]], + ['kargoauto_4478',['kArgoAuto',['../ir__Argo_8h.html#a527fa5776cb58f88013de5062c620b12',1,'ir_Argo.h']]], + ['kargobitmark_4479',['kArgoBitMark',['../ir__Argo_8cpp.html#aa15902c11e3a7d3cbb25504764b163c1',1,'ir_Argo.cpp']]], + ['kargobits_4480',['kArgoBits',['../IRremoteESP8266_8h.html#a351efcd1805c87bd338de81dab3f8fb2',1,'IRremoteESP8266.h']]], + ['kargocool_4481',['kArgoCool',['../ir__Argo_8h.html#ab331356887b5f8f04f5ffdf9031fde71',1,'ir_Argo.h']]], + ['kargodefaultrepeat_4482',['kArgoDefaultRepeat',['../IRremoteESP8266_8h.html#a9a2190c526885753c676db666e48b764',1,'IRremoteESP8266.h']]], + ['kargodry_4483',['kArgoDry',['../ir__Argo_8h.html#ae119706139f65f730db477d060a7bc5d',1,'ir_Argo.h']]], + ['kargofan1_4484',['kArgoFan1',['../ir__Argo_8h.html#abfbde2676afb8b027a26a49d947a1396',1,'ir_Argo.h']]], + ['kargofan2_4485',['kArgoFan2',['../ir__Argo_8h.html#a7b544220198b6aa311da78bc02b0e211',1,'ir_Argo.h']]], + ['kargofan3_4486',['kArgoFan3',['../ir__Argo_8h.html#aa34af62e7134bbca2028d74ba7dfed4e',1,'ir_Argo.h']]], + ['kargofanauto_4487',['kArgoFanAuto',['../ir__Argo_8h.html#a3b17c0ba868b439135e6e016452f1623',1,'ir_Argo.h']]], + ['kargofanoffset_4488',['kArgoFanOffset',['../ir__Argo_8h.html#ab652e466dfce6bfabab04f70e23e6bc9',1,'ir_Argo.h']]], + ['kargofansize_4489',['kArgoFanSize',['../ir__Argo_8h.html#a032348f63ce0e391120161f2547ab280',1,'ir_Argo.h']]], + ['kargoflap1_4490',['kArgoFlap1',['../ir__Argo_8h.html#a477dac25a687b9d875cf9e94623d5e84',1,'ir_Argo.h']]], + ['kargoflap2_4491',['kArgoFlap2',['../ir__Argo_8h.html#aa72401adcdd23c12d36f98370c605ef6',1,'ir_Argo.h']]], + ['kargoflap3_4492',['kArgoFlap3',['../ir__Argo_8h.html#ab18e2931823d631b533c14f417ed4adb',1,'ir_Argo.h']]], + ['kargoflap4_4493',['kArgoFlap4',['../ir__Argo_8h.html#a59204076030de56e1160fc599879b142',1,'ir_Argo.h']]], + ['kargoflap5_4494',['kArgoFlap5',['../ir__Argo_8h.html#a5a3f4c1b1303b177a924c61dfdcce3e6',1,'ir_Argo.h']]], + ['kargoflap6_4495',['kArgoFlap6',['../ir__Argo_8h.html#ac11d6b575b4abc7ac5aec9006ac41634',1,'ir_Argo.h']]], + ['kargoflapauto_4496',['kArgoFlapAuto',['../ir__Argo_8h.html#af7f4a97011f94e4bf453e7cfd01fd780',1,'ir_Argo.h']]], + ['kargoflapfull_4497',['kArgoFlapFull',['../ir__Argo_8h.html#a8befe8d8b6826fc79176b66eea8352b7',1,'ir_Argo.h']]], + ['kargogap_4498',['kArgoGap',['../ir__Argo_8cpp.html#a1a28fc063dea8beacbaac39cf8e9b81b',1,'ir_Argo.cpp']]], + ['kargohdrmark_4499',['kArgoHdrMark',['../ir__Argo_8cpp.html#a5c25d5a07e397fe86378021e7c3f2980',1,'ir_Argo.cpp']]], + ['kargohdrspace_4500',['kArgoHdrSpace',['../ir__Argo_8cpp.html#a10e8a2ac55f8b123093cd92757d1603d',1,'ir_Argo.cpp']]], + ['kargoheat_4501',['kArgoHeat',['../ir__Argo_8h.html#a431536a03ef985b53a4147df5a043b21',1,'ir_Argo.h']]], + ['kargoheatauto_4502',['kArgoHeatAuto',['../ir__Argo_8h.html#a154f8b3e0d600d87b2822027bf0c6619',1,'ir_Argo.h']]], + ['kargoheatbit_4503',['kArgoHeatBit',['../ir__Argo_8h.html#ada4b42336f3d423e3ef1060605c7f7f1',1,'ir_Argo.h']]], + ['kargoheatblink_4504',['kArgoHeatBlink',['../ir__Argo_8h.html#ad29933c939f9364399dfa0f7eaa8cce6',1,'ir_Argo.h']]], + ['kargoifeelbitoffset_4505',['kArgoIFeelBitOffset',['../ir__Argo_8h.html#a0dc059f228415b3cc7a22b50fff71e9c',1,'ir_Argo.h']]], + ['kargomaxbitoffset_4506',['kArgoMaxBitOffset',['../ir__Argo_8h.html#af487de7857781edbe368a2ba724fc7c7',1,'ir_Argo.h']]], + ['kargomaxroomtemp_4507',['kArgoMaxRoomTemp',['../ir__Argo_8h.html#a27427d4479dc126e8782985008d4dd7d',1,'ir_Argo.h']]], + ['kargomaxtemp_4508',['kArgoMaxTemp',['../ir__Argo_8h.html#a2409d2f472fb950c070fa5c0a07f69ce',1,'ir_Argo.h']]], + ['kargomintemp_4509',['kArgoMinTemp',['../ir__Argo_8h.html#a4bc4e4cfe12af43730cb128f4043ad11',1,'ir_Argo.h']]], + ['kargomodeoffset_4510',['kArgoModeOffset',['../ir__Argo_8h.html#a127045d26371fa051310208b0a3d0316',1,'ir_Argo.h']]], + ['kargomodesize_4511',['kArgoModeSize',['../ir__Argo_8h.html#a98e4d25798fb992200ade3dd5e53a401',1,'ir_Argo.h']]], + ['kargonightbitoffset_4512',['kArgoNightBitOffset',['../ir__Argo_8h.html#a4d0f78fc9017ed0ff93c77794a411738',1,'ir_Argo.h']]], + ['kargooff_4513',['kArgoOff',['../ir__Argo_8h.html#af3c6e4f7b18095179ea9e20e45e1890a',1,'ir_Argo.h']]], + ['kargoonespace_4514',['kArgoOneSpace',['../ir__Argo_8cpp.html#a47131b446d160fed9c7af1886d3580e4',1,'ir_Argo.cpp']]], + ['kargopowerbitoffset_4515',['kArgoPowerBitOffset',['../ir__Argo_8h.html#a26c8b660b323ac8a8f1bbf30d7f40bf7',1,'ir_Argo.h']]], + ['kargoroomtemphighoffset_4516',['kArgoRoomTempHighOffset',['../ir__Argo_8h.html#abe1b434b09b0c42d0d7c90496d180aeb',1,'ir_Argo.h']]], + ['kargoroomtemphighsize_4517',['kArgoRoomTempHighSize',['../ir__Argo_8h.html#a6fdcdd90f37c2f4572815b279379484d',1,'ir_Argo.h']]], + ['kargoroomtemplowoffset_4518',['kArgoRoomTempLowOffset',['../ir__Argo_8h.html#a1272f85bf89b7f0326352ae7a05b2244',1,'ir_Argo.h']]], + ['kargoroomtemplowsize_4519',['kArgoRoomTempLowSize',['../ir__Argo_8h.html#a2cd767383014feb1c6cdea45715e49c7',1,'ir_Argo.h']]], + ['kargostatelength_4520',['kArgoStateLength',['../IRremoteESP8266_8h.html#a5f38a56eacd9964a8514cb57de287a45',1,'IRremoteESP8266.h']]], + ['kargotempdelta_4521',['kArgoTempDelta',['../ir__Argo_8h.html#a7256560730a73dcaaa60cdfc8140fc0b',1,'ir_Argo.h']]], + ['kargotemphighoffset_4522',['kArgoTempHighOffset',['../ir__Argo_8h.html#af06b47b51a4b837ee92a2e2774d214e3',1,'ir_Argo.h']]], + ['kargotemphighsize_4523',['kArgoTempHighSize',['../ir__Argo_8h.html#af2b0c18a612c097f6356ff04ce9c78d0',1,'ir_Argo.h']]], + ['kargotemplowoffset_4524',['kArgoTempLowOffset',['../ir__Argo_8h.html#a17137f6bec2d629cca04a859bb48dae8',1,'ir_Argo.h']]], + ['kargotemplowsize_4525',['kArgoTempLowSize',['../ir__Argo_8h.html#aa50679112dc998ff06588d9a35ff313c',1,'ir_Argo.h']]], + ['kargozerospace_4526',['kArgoZeroSpace',['../ir__Argo_8cpp.html#a5e06b6d522b35f503ca1e5db27f32ff6',1,'ir_Argo.cpp']]], + ['kautomaticstr_4527',['kAutomaticStr',['../IRtext_8cpp.html#a66a32b6387a99572644e91f3299910a6',1,'kAutomaticStr(): IRtext.cpp'],['../IRtext_8h.html#a0fc9126a02b933a2af702cd6fdcb47ea',1,'kAutomaticStr(): IRtext.cpp']]], + ['kautostr_4528',['kAutoStr',['../IRtext_8cpp.html#ae8ec328761b0218d0b18479a972b1121',1,'kAutoStr(): IRtext.cpp'],['../IRtext_8h.html#a15a085c4f9e89926d2c165de4b1755d9',1,'kAutoStr(): IRtext.cpp']]], + ['kbeepstr_4529',['kBeepStr',['../IRtext_8cpp.html#a429f5c2f5aea162bd1568e8489aecb28',1,'kBeepStr(): IRtext.cpp'],['../IRtext_8h.html#a2e98c29968ade682d94f35e28364c878',1,'kBeepStr(): IRtext.cpp']]], + ['kbitsstr_4530',['kBitsStr',['../IRtext_8cpp.html#aaabaca413c37bb6b18dc13daf5b335c1',1,'kBitsStr(): IRtext.cpp'],['../IRtext_8h.html#aaf3e1b0041b00b261dfd949b41569d94',1,'kBitsStr(): IRtext.cpp']]], + ['kbottomstr_4531',['kBottomStr',['../IRtext_8cpp.html#ab0bd355efc13bd278a0e33765a783cd0',1,'kBottomStr(): IRtext.cpp'],['../IRtext_8h.html#accfb2322a40cfaf6707394e43f39e2a3',1,'kBottomStr(): IRtext.cpp']]], + ['kbreezestr_4532',['kBreezeStr',['../IRtext_8cpp.html#ab0317e8cf720936fb02816e7827bea9e',1,'kBreezeStr(): IRtext.cpp'],['../IRtext_8h.html#af4f31b53c295a877507e3ef5a5fbbc9d',1,'kBreezeStr(): IRtext.cpp']]], + ['kbuttonstr_4533',['kButtonStr',['../IRtext_8cpp.html#a6ee11e0a45632c54e34bed14c3a971ce',1,'kButtonStr(): IRtext.cpp'],['../IRtext_8h.html#a58bf62453a96d4e84bd1da3449b8799e',1,'kButtonStr(): IRtext.cpp']]], + ['kcancelstr_4534',['kCancelStr',['../IRtext_8cpp.html#af79c3879bac5ca97947f16c3a6a03321',1,'kCancelStr(): IRtext.cpp'],['../IRtext_8h.html#ab64c4cdebbc72cbb62ae6cd9a449876b',1,'kCancelStr(): IRtext.cpp']]], + ['kcarrierac40bitmark_4535',['kCarrierAc40BitMark',['../ir__Carrier_8cpp.html#a3f8996aa3a7b9b871bc6556f98efb345',1,'ir_Carrier.cpp']]], + ['kcarrierac40bits_4536',['kCarrierAc40Bits',['../IRremoteESP8266_8h.html#a56d1176a7b3fe59aeb3f4f39926c617d',1,'IRremoteESP8266.h']]], + ['kcarrierac40gap_4537',['kCarrierAc40Gap',['../ir__Carrier_8cpp.html#aa5f0d39a4e12645a6fb477efb3191384',1,'ir_Carrier.cpp']]], + ['kcarrierac40hdrmark_4538',['kCarrierAc40HdrMark',['../ir__Carrier_8cpp.html#a4b77665ded6dab393779d2763bc367f0',1,'ir_Carrier.cpp']]], + ['kcarrierac40hdrspace_4539',['kCarrierAc40HdrSpace',['../ir__Carrier_8cpp.html#a5ea98bc575a7ac8d7f5da937feeaeed4',1,'ir_Carrier.cpp']]], + ['kcarrierac40minrepeat_4540',['kCarrierAc40MinRepeat',['../IRremoteESP8266_8h.html#a222aa743f398883a4910fbbb6d408bdc',1,'IRremoteESP8266.h']]], + ['kcarrierac40onespace_4541',['kCarrierAc40OneSpace',['../ir__Carrier_8cpp.html#a79073c06820817e077c5bd8d9b8acfbd',1,'ir_Carrier.cpp']]], + ['kcarrierac40zerospace_4542',['kCarrierAc40ZeroSpace',['../ir__Carrier_8cpp.html#a2ee9b60c12887983a6f4f123db6fd5e9',1,'ir_Carrier.cpp']]], + ['kcarrierac64bitmark_4543',['kCarrierAc64BitMark',['../ir__Carrier_8cpp.html#ae32b2dab6a654fa293f54684da45c5c0',1,'ir_Carrier.cpp']]], + ['kcarrierac64bits_4544',['kCarrierAc64Bits',['../IRremoteESP8266_8h.html#a41bc7ab7289e499ad33901da3eab661a',1,'IRremoteESP8266.h']]], + ['kcarrierac64checksumoffset_4545',['kCarrierAc64ChecksumOffset',['../ir__Carrier_8h.html#a3aa65474b5be8c77d498b7e83d8b8f31',1,'ir_Carrier.h']]], + ['kcarrierac64checksumsize_4546',['kCarrierAc64ChecksumSize',['../ir__Carrier_8h.html#a0b446c17c4965508f335e68c786f0596',1,'ir_Carrier.h']]], + ['kcarrierac64cool_4547',['kCarrierAc64Cool',['../ir__Carrier_8h.html#aa75d5965da484d09f6f4c645cdb23869',1,'ir_Carrier.h']]], + ['kcarrierac64fan_4548',['kCarrierAc64Fan',['../ir__Carrier_8h.html#a57655ceea762b18e0dd96724ddf888bd',1,'ir_Carrier.h']]], + ['kcarrierac64fanauto_4549',['kCarrierAc64FanAuto',['../ir__Carrier_8h.html#a12d1fb295a0d9cf407040ab544acc245',1,'ir_Carrier.h']]], + ['kcarrierac64fanhigh_4550',['kCarrierAc64FanHigh',['../ir__Carrier_8h.html#a099f2e82998bd78d25cec17a4be5f230',1,'ir_Carrier.h']]], + ['kcarrierac64fanlow_4551',['kCarrierAc64FanLow',['../ir__Carrier_8h.html#aaeee61e5924bdc8028c4775f96ba14d2',1,'ir_Carrier.h']]], + ['kcarrierac64fanmedium_4552',['kCarrierAc64FanMedium',['../ir__Carrier_8h.html#aeb8943f8d9f2bd95a9df6500eea7cba4',1,'ir_Carrier.h']]], + ['kcarrierac64fanoffset_4553',['kCarrierAc64FanOffset',['../ir__Carrier_8h.html#abbd2da4887e1c313df40506c82cba836',1,'ir_Carrier.h']]], + ['kcarrierac64fansize_4554',['kCarrierAc64FanSize',['../ir__Carrier_8h.html#aebcfb795028fea2d1b4bfde9a045e672',1,'ir_Carrier.h']]], + ['kcarrierac64gap_4555',['kCarrierAc64Gap',['../ir__Carrier_8cpp.html#a6f7ba77f1350126d78a23d7ba967e258',1,'ir_Carrier.cpp']]], + ['kcarrierac64hdrmark_4556',['kCarrierAc64HdrMark',['../ir__Carrier_8cpp.html#a19dc2108d4490c82c03c87c625bc5f31',1,'ir_Carrier.cpp']]], + ['kcarrierac64hdrspace_4557',['kCarrierAc64HdrSpace',['../ir__Carrier_8cpp.html#ad73dbf55f5ffa03d92ec699b23e8ca8d',1,'ir_Carrier.cpp']]], + ['kcarrierac64heat_4558',['kCarrierAc64Heat',['../ir__Carrier_8h.html#ac261ba8bff6f103bb9043c85a6f21d58',1,'ir_Carrier.h']]], + ['kcarrierac64maxtemp_4559',['kCarrierAc64MaxTemp',['../ir__Carrier_8h.html#a5653bc180a4c849b5e0b33b957255ae4',1,'ir_Carrier.h']]], + ['kcarrierac64minrepeat_4560',['kCarrierAc64MinRepeat',['../IRremoteESP8266_8h.html#a8b2b3670dc74ce9fbf3c8b511422a06c',1,'IRremoteESP8266.h']]], + ['kcarrierac64mintemp_4561',['kCarrierAc64MinTemp',['../ir__Carrier_8h.html#a9e7a88bf52839ecb34da1966bb8a956b',1,'ir_Carrier.h']]], + ['kcarrierac64modeoffset_4562',['kCarrierAc64ModeOffset',['../ir__Carrier_8h.html#a7f2ef38df606cb00f1c859914fc6f085',1,'ir_Carrier.h']]], + ['kcarrierac64modesize_4563',['kCarrierAc64ModeSize',['../ir__Carrier_8h.html#a8d28dd57b7ad6b9f4bb2ba11fa4b63f7',1,'ir_Carrier.h']]], + ['kcarrierac64offtimerenableoffset_4564',['kCarrierAc64OffTimerEnableOffset',['../ir__Carrier_8h.html#a1afcf0873e42c5cda5328bfe97d97ade',1,'ir_Carrier.h']]], + ['kcarrierac64offtimeroffset_4565',['kCarrierAc64OffTimerOffset',['../ir__Carrier_8h.html#a0c9189a86abe1bc41f9db34e4ab77172',1,'ir_Carrier.h']]], + ['kcarrierac64onespace_4566',['kCarrierAc64OneSpace',['../ir__Carrier_8cpp.html#a58ea051d56227a4037682f5d612b4cc7',1,'ir_Carrier.cpp']]], + ['kcarrierac64ontimerenableoffset_4567',['kCarrierAc64OnTimerEnableOffset',['../ir__Carrier_8h.html#a8a03bb9d7ead5116dff0b81732300b40',1,'ir_Carrier.h']]], + ['kcarrierac64ontimeroffset_4568',['kCarrierAc64OnTimerOffset',['../ir__Carrier_8h.html#ad2fd8df9a5114e0fc34a3657aac61f9c',1,'ir_Carrier.h']]], + ['kcarrierac64poweroffset_4569',['kCarrierAc64PowerOffset',['../ir__Carrier_8h.html#a943b94e79e98237678b66f6f4a1b6af4',1,'ir_Carrier.h']]], + ['kcarrierac64sleepoffset_4570',['kCarrierAc64SleepOffset',['../ir__Carrier_8h.html#a8ae023f5e44d5c29df41ab0f5cd534a0',1,'ir_Carrier.h']]], + ['kcarrierac64swingvoffset_4571',['kCarrierAc64SwingVOffset',['../ir__Carrier_8h.html#a186dcc18acb75f98370d71f4640f02ce',1,'ir_Carrier.h']]], + ['kcarrierac64tempoffset_4572',['kCarrierAc64TempOffset',['../ir__Carrier_8h.html#a3d3663b7e55cae59f1b8bba5ffbb5fad',1,'ir_Carrier.h']]], + ['kcarrierac64tempsize_4573',['kCarrierAc64TempSize',['../ir__Carrier_8h.html#ae9e16d5ab69b493607ce84dfbded150f',1,'ir_Carrier.h']]], + ['kcarrierac64timermax_4574',['kCarrierAc64TimerMax',['../ir__Carrier_8h.html#a78a34b51e51dc3b4129f350673c9fa96',1,'ir_Carrier.h']]], + ['kcarrierac64timermin_4575',['kCarrierAc64TimerMin',['../ir__Carrier_8h.html#aeebac3e61246f2e148806d4b4e8ac13e',1,'ir_Carrier.h']]], + ['kcarrierac64timersize_4576',['kCarrierAc64TimerSize',['../ir__Carrier_8h.html#adced87f4aed397ea8f2bb5ac2749dce5',1,'ir_Carrier.h']]], + ['kcarrierac64zerospace_4577',['kCarrierAc64ZeroSpace',['../ir__Carrier_8cpp.html#af28d4332e0f1ad19aa743b993f44cdc7',1,'ir_Carrier.cpp']]], + ['kcarrieracbitmark_4578',['kCarrierAcBitMark',['../ir__Carrier_8cpp.html#af4a608f81c745734499ec1842167940b',1,'ir_Carrier.cpp']]], + ['kcarrieracbits_4579',['kCarrierAcBits',['../IRremoteESP8266_8h.html#a668d9ac84f7dae61c35534b842d4956b',1,'IRremoteESP8266.h']]], + ['kcarrieracfreq_4580',['kCarrierAcFreq',['../ir__Carrier_8cpp.html#a795dc2d9b122bd3794fddbddef571058',1,'ir_Carrier.cpp']]], + ['kcarrieracgap_4581',['kCarrierAcGap',['../ir__Carrier_8cpp.html#a00767c0b503a7fc8f0b2ddfac24a4f85',1,'ir_Carrier.cpp']]], + ['kcarrierachdrmark_4582',['kCarrierAcHdrMark',['../ir__Carrier_8cpp.html#ad9a7754e77cfcfd6c6032d497bc4528d',1,'ir_Carrier.cpp']]], + ['kcarrierachdrspace_4583',['kCarrierAcHdrSpace',['../ir__Carrier_8cpp.html#a8e09857e2fe15d6983ec0384c57140d4',1,'ir_Carrier.cpp']]], + ['kcarrieracminrepeat_4584',['kCarrierAcMinRepeat',['../IRremoteESP8266_8h.html#a78c8a8b11179e8fd20bf09fa35f6b886',1,'IRremoteESP8266.h']]], + ['kcarrieraconespace_4585',['kCarrierAcOneSpace',['../ir__Carrier_8cpp.html#ab04a214a7c2e0439384736c46ddc6c61',1,'ir_Carrier.cpp']]], + ['kcarrieraczerospace_4586',['kCarrierAcZeroSpace',['../ir__Carrier_8cpp.html#a51c9c4bbd6e2927baac15dc60c1e60fa',1,'ir_Carrier.cpp']]], + ['kceilingstr_4587',['kCeilingStr',['../IRtext_8cpp.html#a5258c9d80502d5a8e14bb324a394452b',1,'kCeilingStr(): IRtext.cpp'],['../IRtext_8h.html#aa47afe8f4c175954e9439c0c9e48c83e',1,'kCeilingStr(): IRtext.cpp']]], + ['kcelsiusstr_4588',['kCelsiusStr',['../IRtext_8cpp.html#af0ad7ca76c659a17872960bcbcfbdbbf',1,'kCelsiusStr(): IRtext.cpp'],['../IRtext_8h.html#aae21484e9f049a7cfa507068abd3915e',1,'kCelsiusStr(): IRtext.cpp']]], + ['kcentrestr_4589',['kCentreStr',['../IRtext_8cpp.html#a87a4151e0361c9f75d0d5c00f9bad1ee',1,'kCentreStr(): IRtext.cpp'],['../IRtext_8h.html#aab13bc11db65584fbb8a61c686d67228',1,'kCentreStr(): IRtext.cpp']]], + ['kchangestr_4590',['kChangeStr',['../IRtext_8cpp.html#a1f6396eb9bd4327a7a2307e5724c1dd7',1,'kChangeStr(): IRtext.cpp'],['../IRtext_8h.html#a46e6bd06cfbf5f462042d7c720db01ae',1,'kChangeStr(): IRtext.cpp']]], + ['kcirculatestr_4591',['kCirculateStr',['../IRtext_8cpp.html#a869ef1f579373ff4b5b61b1cba215680',1,'kCirculateStr(): IRtext.cpp'],['../IRtext_8h.html#a0ba8b339babc7f7f26dbab2399bcc578',1,'kCirculateStr(): IRtext.cpp']]], + ['kcleanstr_4592',['kCleanStr',['../IRtext_8cpp.html#ad2d97c52e8df2704654fdbd0a7a0561e',1,'kCleanStr(): IRtext.cpp'],['../IRtext_8h.html#a45c17b23773e9dcded65a82577b00263',1,'kCleanStr(): IRtext.cpp']]], + ['kclockstr_4593',['kClockStr',['../IRtext_8cpp.html#ad39bd469d5474159463543184cfae321',1,'kClockStr(): IRtext.cpp'],['../IRtext_8h.html#a6e4b8f591a1d3d399a559d41847b3fa8',1,'kClockStr(): IRtext.cpp']]], + ['kcodestr_4594',['kCodeStr',['../IRtext_8cpp.html#a26e4bf74871ce457f42ec839545987f4',1,'kCodeStr(): IRtext.cpp'],['../IRtext_8h.html#a58a9da5cec40746dbe20455c6ef6c8fd',1,'kCodeStr(): IRtext.cpp']]], + ['kcolonspacestr_4595',['kColonSpaceStr',['../IRtext_8cpp.html#a5d978c9ac25163a9629b7e8e2d37d25e',1,'kColonSpaceStr(): IRtext.cpp'],['../IRtext_8h.html#aab1b0d2ea5169c1e1d8eff4daef36512',1,'kColonSpaceStr(): IRtext.cpp']]], + ['kcomfortstr_4596',['kComfortStr',['../IRtext_8cpp.html#aa7f0cfdb126ff7b0f8db6033bb51f36d',1,'kComfortStr(): IRtext.cpp'],['../IRtext_8h.html#a20037561545d4ba4cfe66c1e103ecde1',1,'kComfortStr(): IRtext.cpp']]], + ['kcommandstr_4597',['kCommandStr',['../IRtext_8cpp.html#afd5865ea8c0f8565369dd2c4ee4622d6',1,'kCommandStr(): IRtext.cpp'],['../IRtext_8h.html#afdc9e8cc5c8c5c03749898d4f2d38606',1,'kCommandStr(): IRtext.cpp']]], + ['kcommaspacestr_4598',['kCommaSpaceStr',['../IRtext_8cpp.html#ac8a9678d4c9eeee17a9dc28624c0ab49',1,'kCommaSpaceStr(): IRtext.cpp'],['../IRtext_8h.html#a48f5dfcf2e0f13f502980d42e879aec3',1,'kCommaSpaceStr(): IRtext.cpp']]], + ['kcoolixauto_4599',['kCoolixAuto',['../ir__Coolix_8h.html#a73c1ef7c2c80c861256a14a9f256b125',1,'ir_Coolix.h']]], + ['kcoolixbitmark_4600',['kCoolixBitMark',['../ir__Coolix_8cpp.html#acd8562a27ec6c0a6c2cf9480082e04cd',1,'ir_Coolix.cpp']]], + ['kcoolixbitmarkticks_4601',['kCoolixBitMarkTicks',['../ir__Coolix_8cpp.html#aefaa206b4316a4fd921f7171295d1232',1,'ir_Coolix.cpp']]], + ['kcoolixbits_4602',['kCoolixBits',['../IRremoteESP8266_8h.html#aed48c68a637e4b45b80bbf4964ea79f9',1,'IRremoteESP8266.h']]], + ['kcoolixclean_4603',['kCoolixClean',['../ir__Coolix_8h.html#a5cc9fcde4a6da54917b4d69bb352bc86',1,'ir_Coolix.h']]], + ['kcoolixcmdfan_4604',['kCoolixCmdFan',['../ir__Coolix_8h.html#a7d5ff02f4a0c379322877b3dcf934c77',1,'ir_Coolix.h']]], + ['kcoolixcool_4605',['kCoolixCool',['../ir__Coolix_8h.html#ae285ee4206fe45d25bb1d99b848c7e65',1,'ir_Coolix.h']]], + ['kcoolixdefaultrepeat_4606',['kCoolixDefaultRepeat',['../IRremoteESP8266_8h.html#aa89410d369d71738c8cbefae6ac3b00f',1,'IRremoteESP8266.h']]], + ['kcoolixdefaultstate_4607',['kCoolixDefaultState',['../ir__Coolix_8h.html#ad54ebf20658c33e5ad54fc54a513511e',1,'ir_Coolix.h']]], + ['kcoolixdry_4608',['kCoolixDry',['../ir__Coolix_8h.html#a904c4135f61120e71577f6830adae689',1,'ir_Coolix.h']]], + ['kcoolixfan_4609',['kCoolixFan',['../ir__Coolix_8h.html#a2e050321c994844f2ff6668ba6973ac4',1,'ir_Coolix.h']]], + ['kcoolixfanauto_4610',['kCoolixFanAuto',['../ir__Coolix_8h.html#ac25d3c45ed7d7d30ff2ebf617d8265f0',1,'ir_Coolix.h']]], + ['kcoolixfanauto0_4611',['kCoolixFanAuto0',['../ir__Coolix_8h.html#a38cccd1edee2c88c1b080f1d5600ead7',1,'ir_Coolix.h']]], + ['kcoolixfanfixed_4612',['kCoolixFanFixed',['../ir__Coolix_8h.html#a37a3a23d8fe30df024cb844f82f90b2a',1,'ir_Coolix.h']]], + ['kcoolixfanmax_4613',['kCoolixFanMax',['../ir__Coolix_8h.html#aabb349ee111467088b9a292950aba753',1,'ir_Coolix.h']]], + ['kcoolixfanmed_4614',['kCoolixFanMed',['../ir__Coolix_8h.html#a2750626cda2e389df901b459805e09bd',1,'ir_Coolix.h']]], + ['kcoolixfanmin_4615',['kCoolixFanMin',['../ir__Coolix_8h.html#a6c0086075cce1698c48cc30e045ab5bf',1,'ir_Coolix.h']]], + ['kcoolixfanoffset_4616',['kCoolixFanOffset',['../ir__Coolix_8h.html#a1656f488974bd12db4049dfa8ff43a4e',1,'ir_Coolix.h']]], + ['kcoolixfansize_4617',['kCoolixFanSize',['../ir__Coolix_8h.html#a5f4649b5b73766245bc82191cdc0e596',1,'ir_Coolix.h']]], + ['kcoolixfantempcode_4618',['kCoolixFanTempCode',['../ir__Coolix_8h.html#a6d2d6f2fd8f5e9a4491623b9351efcba',1,'ir_Coolix.h']]], + ['kcoolixfanzonefollow_4619',['kCoolixFanZoneFollow',['../ir__Coolix_8h.html#a5a71c6acd18b3198c7900e2de34c48a3',1,'ir_Coolix.h']]], + ['kcoolixhdrmark_4620',['kCoolixHdrMark',['../ir__Coolix_8cpp.html#a746299797d958ccf116e6d1cdab3ad06',1,'ir_Coolix.cpp']]], + ['kcoolixhdrmarkticks_4621',['kCoolixHdrMarkTicks',['../ir__Coolix_8cpp.html#a04d520a0fe3d773f377810174e5463a4',1,'ir_Coolix.cpp']]], + ['kcoolixhdrspace_4622',['kCoolixHdrSpace',['../ir__Coolix_8cpp.html#ab7ff2a6bd99e0e6a0db3f14350cca84c',1,'ir_Coolix.cpp']]], + ['kcoolixhdrspaceticks_4623',['kCoolixHdrSpaceTicks',['../ir__Coolix_8cpp.html#a58951e9800513b019ccb9f04ae55716f',1,'ir_Coolix.cpp']]], + ['kcoolixheat_4624',['kCoolixHeat',['../ir__Coolix_8h.html#a234b39696f0b2fac6b37aa309082505e',1,'ir_Coolix.h']]], + ['kcoolixled_4625',['kCoolixLed',['../ir__Coolix_8h.html#a68ae46e117caf0d7a3cc2ef9492495f1',1,'ir_Coolix.h']]], + ['kcoolixmingap_4626',['kCoolixMinGap',['../ir__Coolix_8cpp.html#a46da2480f6850af899db74a4f2270cdc',1,'ir_Coolix.cpp']]], + ['kcoolixmingapticks_4627',['kCoolixMinGapTicks',['../ir__Coolix_8cpp.html#a94f47fbf027fcb90664b302ff123f535',1,'ir_Coolix.cpp']]], + ['kcoolixmodeoffset_4628',['kCoolixModeOffset',['../ir__Coolix_8h.html#acd17067177e1cc6776b7932afd9fbdb2',1,'ir_Coolix.h']]], + ['kcoolixmodesize_4629',['kCoolixModeSize',['../ir__Coolix_8h.html#a69e5ee4c5eb95ca3346d9d9186a688a8',1,'ir_Coolix.h']]], + ['kcoolixoff_4630',['kCoolixOff',['../ir__Coolix_8h.html#aef6f59b83a14b8505f395b2eb8d8ad39',1,'ir_Coolix.h']]], + ['kcoolixonespace_4631',['kCoolixOneSpace',['../ir__Coolix_8cpp.html#a97a8439ace71584e36ab7306c3d53749',1,'ir_Coolix.cpp']]], + ['kcoolixonespaceticks_4632',['kCoolixOneSpaceTicks',['../ir__Coolix_8cpp.html#a78770eaf597e4aa2ed539248ef10ec11',1,'ir_Coolix.cpp']]], + ['kcoolixprefix_4633',['kCoolixPrefix',['../ir__Coolix_8h.html#a1b88ef6651189ba330d8e2847528964b',1,'ir_Coolix.h']]], + ['kcoolixsensortempignorecode_4634',['kCoolixSensorTempIgnoreCode',['../ir__Coolix_8h.html#ae3aba531b0c0053424786ec4bb2be934',1,'ir_Coolix.h']]], + ['kcoolixsensortempmax_4635',['kCoolixSensorTempMax',['../ir__Coolix_8h.html#a71641b1240ee439e77128165cedf899f',1,'ir_Coolix.h']]], + ['kcoolixsensortempmin_4636',['kCoolixSensorTempMin',['../ir__Coolix_8h.html#a48f3f3ad79a53e0758270647db0b089c',1,'ir_Coolix.h']]], + ['kcoolixsensortempoffset_4637',['kCoolixSensorTempOffset',['../ir__Coolix_8h.html#a03edec58ad078d7de7436929c463898a',1,'ir_Coolix.h']]], + ['kcoolixsensortempsize_4638',['kCoolixSensorTempSize',['../ir__Coolix_8h.html#a979d1d4f84432afc29ac3fcc78353d6c',1,'ir_Coolix.h']]], + ['kcoolixsleep_4639',['kCoolixSleep',['../ir__Coolix_8h.html#aa7f9f96e56bd3f6b814bc84b947b2417',1,'ir_Coolix.h']]], + ['kcoolixswing_4640',['kCoolixSwing',['../ir__Coolix_8h.html#a799ad5ab7cf43f0aac3c342305f14b90',1,'ir_Coolix.h']]], + ['kcoolixswingh_4641',['kCoolixSwingH',['../ir__Coolix_8h.html#a877bd2731dfc86d864e38a5ceb4ede6e',1,'ir_Coolix.h']]], + ['kcoolixswingv_4642',['kCoolixSwingV',['../ir__Coolix_8h.html#ab9fcaf25426f1f9ad293e165f8c0bf38',1,'ir_Coolix.h']]], + ['kcoolixtempmap_4643',['kCoolixTempMap',['../ir__Coolix_8h.html#a9c8931df1dbed38c8119f6605266c710',1,'ir_Coolix.h']]], + ['kcoolixtempmax_4644',['kCoolixTempMax',['../ir__Coolix_8h.html#afbbb02bfeaaf5cb558ca28cdd5cfc4c3',1,'ir_Coolix.h']]], + ['kcoolixtempmin_4645',['kCoolixTempMin',['../ir__Coolix_8h.html#accd37cf257fa5fbeb64e28f0d63888fb',1,'ir_Coolix.h']]], + ['kcoolixtempoffset_4646',['kCoolixTempOffset',['../ir__Coolix_8h.html#ac49173b671af51026e378d65c7bc696b',1,'ir_Coolix.h']]], + ['kcoolixtemprange_4647',['kCoolixTempRange',['../ir__Coolix_8h.html#a74e3e75466fd27672968d660e3fddc9a',1,'ir_Coolix.h']]], + ['kcoolixtempsize_4648',['kCoolixTempSize',['../ir__Coolix_8h.html#a7a22c5c9bdd23ef80ffe9d6760c0650e',1,'ir_Coolix.h']]], + ['kcoolixtick_4649',['kCoolixTick',['../ir__Coolix_8cpp.html#a61ddf842920e2b3e33fdb856bd911eae',1,'ir_Coolix.cpp']]], + ['kcoolixturbo_4650',['kCoolixTurbo',['../ir__Coolix_8h.html#ade957b6f4a6cdb064c709972a5c31a4b',1,'ir_Coolix.h']]], + ['kcoolixunknown_4651',['kCoolixUnknown',['../ir__Coolix_8h.html#a2913e31a9dc5b89cbcae940cd5d59497',1,'ir_Coolix.h']]], + ['kcoolixzerospace_4652',['kCoolixZeroSpace',['../ir__Coolix_8cpp.html#a1a9ccf6b91e786f310ffe53d55cfd6d1',1,'ir_Coolix.cpp']]], + ['kcoolixzerospaceticks_4653',['kCoolixZeroSpaceTicks',['../ir__Coolix_8cpp.html#af1a750cb3e1f142326cd177118c27136',1,'ir_Coolix.cpp']]], + ['kcoolixzonefollowmaskoffset_4654',['kCoolixZoneFollowMaskOffset',['../ir__Coolix_8h.html#ae5da4da07b9d1bb715102cafd4a0105e',1,'ir_Coolix.h']]], + ['kcoolstr_4655',['kCoolStr',['../IRtext_8cpp.html#a31258a2210b16dc977bcfd96938a8937',1,'kCoolStr(): IRtext.cpp'],['../IRtext_8h.html#ac25d86b97b8e53292dc8d0604ae263a3',1,'kCoolStr(): IRtext.cpp']]], + ['kcoronaacbitmark_4656',['kCoronaAcBitMark',['../ir__Corona_8cpp.html#a1ecb863f625463289d34e210885238db',1,'ir_Corona.cpp']]], + ['kcoronaacbits_4657',['kCoronaAcBits',['../IRremoteESP8266_8h.html#aaf59be616d7e3a5e605b8d1e08f20686',1,'IRremoteESP8266.h']]], + ['kcoronaacbitsshort_4658',['kCoronaAcBitsShort',['../IRremoteESP8266_8h.html#a1191a9293b03aa14426083b6f411a4e3',1,'IRremoteESP8266.h']]], + ['kcoronaacfanauto_4659',['kCoronaAcFanAuto',['../ir__Corona_8h.html#a8c97a0c674c000e4486159d628f1aa0a',1,'ir_Corona.h']]], + ['kcoronaacfanhigh_4660',['kCoronaAcFanHigh',['../ir__Corona_8h.html#a4f58be196a744892402e287b12502dcb',1,'ir_Corona.h']]], + ['kcoronaacfanlow_4661',['kCoronaAcFanLow',['../ir__Corona_8h.html#af9e5c729be856bf4b1bc10568f96c183',1,'ir_Corona.h']]], + ['kcoronaacfanmedium_4662',['kCoronaAcFanMedium',['../ir__Corona_8h.html#a9d6b46c006bd6ea54a14b92a2d7a3dff',1,'ir_Corona.h']]], + ['kcoronaacfanoffset_4663',['kCoronaAcFanOffset',['../ir__Corona_8h.html#ab9944dc3abdc09c4d616f43aaffccdec',1,'ir_Corona.h']]], + ['kcoronaacfansize_4664',['kCoronaAcFanSize',['../ir__Corona_8h.html#a07463e8e2e7d2bf004142ec6b89c7851',1,'ir_Corona.h']]], + ['kcoronaacfreq_4665',['kCoronaAcFreq',['../ir__Corona_8cpp.html#a0cb56860c88e9503743bcf94068bbf56',1,'ir_Corona.cpp']]], + ['kcoronaachdrmark_4666',['kCoronaAcHdrMark',['../ir__Corona_8cpp.html#a697d84f13a1228dbae3cfb491124689a',1,'ir_Corona.cpp']]], + ['kcoronaachdrspace_4667',['kCoronaAcHdrSpace',['../ir__Corona_8cpp.html#ad2425c406aa36c7752832d19f4a735f7',1,'ir_Corona.cpp']]], + ['kcoronaacmaxtemp_4668',['kCoronaAcMaxTemp',['../ir__Corona_8h.html#aa6d199e5bb8382443da4e1f303dd7988',1,'ir_Corona.h']]], + ['kcoronaacmintemp_4669',['kCoronaAcMinTemp',['../ir__Corona_8h.html#ae984b624da5e2d5ef1405e1b8d9424ba',1,'ir_Corona.h']]], + ['kcoronaacmodecool_4670',['kCoronaAcModeCool',['../ir__Corona_8h.html#a6f8bb2e27990014686828b4b7e2c84c6',1,'ir_Corona.h']]], + ['kcoronaacmodedry_4671',['kCoronaAcModeDry',['../ir__Corona_8h.html#afd47996b221103ae142363f04014fb4b',1,'ir_Corona.h']]], + ['kcoronaacmodefan_4672',['kCoronaAcModeFan',['../ir__Corona_8h.html#ab8098af3e0f9cd82a7c9c771ffd8ad15',1,'ir_Corona.h']]], + ['kcoronaacmodeheat_4673',['kCoronaAcModeHeat',['../ir__Corona_8h.html#a7f3c7c051ae3ee07621c47505a87bec1',1,'ir_Corona.h']]], + ['kcoronaacmodeoffset_4674',['kCoronaAcModeOffset',['../ir__Corona_8h.html#aa4caa3638ad09dc3a223320651adbd49',1,'ir_Corona.h']]], + ['kcoronaacmodesize_4675',['kCoronaAcModeSize',['../ir__Corona_8h.html#a38baa949868e16e67d7c2eb933b5019d',1,'ir_Corona.h']]], + ['kcoronaacofftimersection_4676',['kCoronaAcOffTimerSection',['../ir__Corona_8h.html#ac2cfdbf9b3ed3d85c0e298c3de8f357b',1,'ir_Corona.h']]], + ['kcoronaaconespace_4677',['kCoronaAcOneSpace',['../ir__Corona_8cpp.html#a6d9c199bdefbbb30b9561c5498c5a76e',1,'ir_Corona.cpp']]], + ['kcoronaacontimersection_4678',['kCoronaAcOnTimerSection',['../ir__Corona_8h.html#a711b7b5bd2081ca9b1e7ab25573ff612',1,'ir_Corona.h']]], + ['kcoronaacoverhead_4679',['kCoronaAcOverhead',['../ir__Corona_8cpp.html#aaef71b297a7868863a2ad7219bafabeb',1,'ir_Corona.cpp']]], + ['kcoronaacoverheadshort_4680',['kCoronaAcOverheadShort',['../ir__Corona_8cpp.html#a56010f67a047f551db681bb0ec8c35f7',1,'ir_Corona.cpp']]], + ['kcoronaacpowerbuttonoffset_4681',['kCoronaAcPowerButtonOffset',['../ir__Corona_8h.html#a71b6c16b1b5cffbd1991fea675e5a65e',1,'ir_Corona.h']]], + ['kcoronaacpoweroffset_4682',['kCoronaAcPowerOffset',['../ir__Corona_8h.html#ac2258a233d0f1ef3207fdd5abd8c855d',1,'ir_Corona.h']]], + ['kcoronaacpowersaveoffset_4683',['kCoronaAcPowerSaveOffset',['../ir__Corona_8h.html#a3bd4f3e2a1001aede28c886e7bbe42ae',1,'ir_Corona.h']]], + ['kcoronaacsectionbytes_4684',['kCoronaAcSectionBytes',['../ir__Corona_8h.html#a094063159064053dd5e5059eb0d90f7c',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0base_4685',['kCoronaAcSectionData0Base',['../ir__Corona_8h.html#a2d0b1f5a0839839a17947bde624d4c74',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0invpos_4686',['kCoronaAcSectionData0InvPos',['../ir__Corona_8h.html#a1a16967cb9024658763c7e6b6b5f8dd3',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0pos_4687',['kCoronaAcSectionData0Pos',['../ir__Corona_8h.html#a285f66040fa3db6c9955a97ef6eee4b7',1,'ir_Corona.h']]], + ['kcoronaacsectiondata1invpos_4688',['kCoronaAcSectionData1InvPos',['../ir__Corona_8h.html#ad32635d2264331f4ee128e990411a704',1,'ir_Corona.h']]], + ['kcoronaacsectiondata1pos_4689',['kCoronaAcSectionData1Pos',['../ir__Corona_8h.html#a1b10ed7cf1c43a3a8be6de6d3cfc12af',1,'ir_Corona.h']]], + ['kcoronaacsectionheader0_4690',['kCoronaAcSectionHeader0',['../ir__Corona_8h.html#a39a2c0d214a10f8f9685e9955c0be0a4',1,'ir_Corona.h']]], + ['kcoronaacsectionheader0pos_4691',['kCoronaAcSectionHeader0Pos',['../ir__Corona_8h.html#a8641d0234280b8cc3bb255abebea6540',1,'ir_Corona.h']]], + ['kcoronaacsectionheader1_4692',['kCoronaAcSectionHeader1',['../ir__Corona_8h.html#a8a661569fc7b97ba2e9e755b944162f8',1,'ir_Corona.h']]], + ['kcoronaacsectionheader1pos_4693',['kCoronaAcSectionHeader1Pos',['../ir__Corona_8h.html#adaadcbe7d57b048250f32b44a96d3853',1,'ir_Corona.h']]], + ['kcoronaacsectionlabelbase_4694',['kCoronaAcSectionLabelBase',['../ir__Corona_8h.html#a6ff8a3461b87df048878faf49c12d064',1,'ir_Corona.h']]], + ['kcoronaacsectionlabelpos_4695',['kCoronaAcSectionLabelPos',['../ir__Corona_8h.html#a5c68109fb92da47236c4100c2db28e2c',1,'ir_Corona.h']]], + ['kcoronaacsections_4696',['kCoronaAcSections',['../ir__Corona_8h.html#a37e6cc5e2e186b2f5c5c938496ece111',1,'ir_Corona.h']]], + ['kcoronaacsettingssection_4697',['kCoronaAcSettingsSection',['../ir__Corona_8h.html#a5a83a045fd9878eae073f25e6c5b4753',1,'ir_Corona.h']]], + ['kcoronaacspacegap_4698',['kCoronaAcSpaceGap',['../ir__Corona_8cpp.html#a50f46039059d2a427bc9bc93c53df4fd',1,'ir_Corona.cpp']]], + ['kcoronaacstatelength_4699',['kCoronaAcStateLength',['../IRremoteESP8266_8h.html#ab18df94a82b365ff30caaabb05a9fcaf',1,'IRremoteESP8266.h']]], + ['kcoronaacstatelengthshort_4700',['kCoronaAcStateLengthShort',['../IRremoteESP8266_8h.html#a32b65ada4941a9622fbbc60f01b82425',1,'IRremoteESP8266.h']]], + ['kcoronaacswingvtoggleoffset_4701',['kCoronaAcSwingVToggleOffset',['../ir__Corona_8h.html#a1475a44b94a8cfe83fb48b3c3d98e148',1,'ir_Corona.h']]], + ['kcoronaactempoffset_4702',['kCoronaAcTempOffset',['../ir__Corona_8h.html#ae31731c985397a9a8b66ab933deccd7c',1,'ir_Corona.h']]], + ['kcoronaactempsize_4703',['kCoronaAcTempSize',['../ir__Corona_8h.html#a69dac2ce8e51b8e1890c8b7844eab9dd',1,'ir_Corona.h']]], + ['kcoronaactimermax_4704',['kCoronaAcTimerMax',['../ir__Corona_8h.html#af0428879b0fd39def7ea41e2906d9127',1,'ir_Corona.h']]], + ['kcoronaactimeroff_4705',['kCoronaAcTimerOff',['../ir__Corona_8h.html#af0feaf445fae561c3fa18ec68a19edef',1,'ir_Corona.h']]], + ['kcoronaactimerunitspermin_4706',['kCoronaAcTimerUnitsPerMin',['../ir__Corona_8h.html#a7f76e80480abdbdcdaf39186901950a4',1,'ir_Corona.h']]], + ['kcoronaaczerospace_4707',['kCoronaAcZeroSpace',['../ir__Corona_8cpp.html#af64bbcaf63ca9d06089de382354eb2d9',1,'ir_Corona.cpp']]], + ['kcoronatolerance_4708',['kCoronaTolerance',['../ir__Corona_8cpp.html#aad3726c95bfd7a9f79ba1e0c7058bb7b',1,'ir_Corona.cpp']]], + ['kdaikin128auto_4709',['kDaikin128Auto',['../ir__Daikin_8h.html#a1d2a0f9db8e1be93bff12ec23ba212e0',1,'ir_Daikin.h']]], + ['kdaikin128bitceiling_4710',['kDaikin128BitCeiling',['../ir__Daikin_8h.html#a0e1d1c1e7544eb455187290dbe4a1520',1,'ir_Daikin.h']]], + ['kdaikin128bitecono_4711',['kDaikin128BitEcono',['../ir__Daikin_8h.html#a34add42c4df4db799ddf52e8e5587dee',1,'ir_Daikin.h']]], + ['kdaikin128biteconooffset_4712',['kDaikin128BitEconoOffset',['../ir__Daikin_8h.html#af822203d873d9b847c3a7b08d236f82b',1,'ir_Daikin.h']]], + ['kdaikin128bithalfhour_4713',['kDaikin128BitHalfHour',['../ir__Daikin_8h.html#abf955f8f24fd37bbe21222ca160b3299',1,'ir_Daikin.h']]], + ['kdaikin128bitmark_4714',['kDaikin128BitMark',['../ir__Daikin_8h.html#a5178ac70eb4e134597e504d373d52fcd',1,'ir_Daikin.h']]], + ['kdaikin128bitpowertoggle_4715',['kDaikin128BitPowerToggle',['../ir__Daikin_8h.html#a813506d8d3f8b6933379bcfc097e4b29',1,'ir_Daikin.h']]], + ['kdaikin128bitpowertoggleoffset_4716',['kDaikin128BitPowerToggleOffset',['../ir__Daikin_8h.html#a05e33573c5050b1e54721a1716d652b5',1,'ir_Daikin.h']]], + ['kdaikin128bits_4717',['kDaikin128Bits',['../IRremoteESP8266_8h.html#a5bb2e6f8acbc0123de5ac0fd76e1646a',1,'IRremoteESP8266.h']]], + ['kdaikin128bitsleep_4718',['kDaikin128BitSleep',['../ir__Daikin_8h.html#a0cb96f1803fab5bfac8ef79a311308de',1,'ir_Daikin.h']]], + ['kdaikin128bitsleepoffset_4719',['kDaikin128BitSleepOffset',['../ir__Daikin_8h.html#a7b4aa1ef19f1c23ef74b45eb90734c6f',1,'ir_Daikin.h']]], + ['kdaikin128bitswing_4720',['kDaikin128BitSwing',['../ir__Daikin_8h.html#a8f6ab5b7f9871f08364abf3337ae48b4',1,'ir_Daikin.h']]], + ['kdaikin128bitswingoffset_4721',['kDaikin128BitSwingOffset',['../ir__Daikin_8h.html#a7f98cf3863ab58b147dc31c497bc07bc',1,'ir_Daikin.h']]], + ['kdaikin128bittimerenabled_4722',['kDaikin128BitTimerEnabled',['../ir__Daikin_8h.html#a1197dadb35f318b000ff6ee7ad3ca8b0',1,'ir_Daikin.h']]], + ['kdaikin128bittimerenabledoffset_4723',['kDaikin128BitTimerEnabledOffset',['../ir__Daikin_8h.html#af913ee51e5b90ad12f87dbed9ce349d6',1,'ir_Daikin.h']]], + ['kdaikin128bitwall_4724',['kDaikin128BitWall',['../ir__Daikin_8h.html#a842b3b696f95c5515ee4180626d78973',1,'ir_Daikin.h']]], + ['kdaikin128byteclockhours_4725',['kDaikin128ByteClockHours',['../ir__Daikin_8h.html#a0d705309d30881fd2fe806e5bf8ae27d',1,'ir_Daikin.h']]], + ['kdaikin128byteclockmins_4726',['kDaikin128ByteClockMins',['../ir__Daikin_8h.html#ab8c9af42d68548e1e711a0b38976342b',1,'ir_Daikin.h']]], + ['kdaikin128byteeconolight_4727',['kDaikin128ByteEconoLight',['../ir__Daikin_8h.html#a75a3c1f1790006f0005666a023218c79',1,'ir_Daikin.h']]], + ['kdaikin128bytemodefan_4728',['kDaikin128ByteModeFan',['../ir__Daikin_8h.html#a8433ab362f79a6bb3570d310a05f1141',1,'ir_Daikin.h']]], + ['kdaikin128byteofftimer_4729',['kDaikin128ByteOffTimer',['../ir__Daikin_8h.html#a66e243db1131f58d0840980ca64c0282',1,'ir_Daikin.h']]], + ['kdaikin128byteontimer_4730',['kDaikin128ByteOnTimer',['../ir__Daikin_8h.html#af27f1f25a52dc4c182111acd2abc554d',1,'ir_Daikin.h']]], + ['kdaikin128bytepowerswingsleep_4731',['kDaikin128BytePowerSwingSleep',['../ir__Daikin_8h.html#a0f5a9f1ac68c516744220ad230805c15',1,'ir_Daikin.h']]], + ['kdaikin128bytetemp_4732',['kDaikin128ByteTemp',['../ir__Daikin_8h.html#a4d3d5683aaee8e76138750a0f6ff1465',1,'ir_Daikin.h']]], + ['kdaikin128cool_4733',['kDaikin128Cool',['../ir__Daikin_8h.html#a24ee5ffe877d7caa964256e5723af7e1',1,'ir_Daikin.h']]], + ['kdaikin128defaultrepeat_4734',['kDaikin128DefaultRepeat',['../IRremoteESP8266_8h.html#a5c116cb58be005468de125f6ee651ccb',1,'IRremoteESP8266.h']]], + ['kdaikin128dry_4735',['kDaikin128Dry',['../ir__Daikin_8h.html#ac4da761bf3b0ce12e6513a2718b3a907',1,'ir_Daikin.h']]], + ['kdaikin128fan_4736',['kDaikin128Fan',['../ir__Daikin_8h.html#ac1c41d54f27d1653181ac69384f1130f',1,'ir_Daikin.h']]], + ['kdaikin128fanauto_4737',['kDaikin128FanAuto',['../ir__Daikin_8h.html#aec2fe4618978c17e60a1ea8b1a89c263',1,'ir_Daikin.h']]], + ['kdaikin128fanhigh_4738',['kDaikin128FanHigh',['../ir__Daikin_8h.html#a7ffd52eb15f6ffb5a0ffcddf39aa8f0d',1,'ir_Daikin.h']]], + ['kdaikin128fanlow_4739',['kDaikin128FanLow',['../ir__Daikin_8h.html#a505c58ff23c5a551c6e2e356f66e9cc1',1,'ir_Daikin.h']]], + ['kdaikin128fanmed_4740',['kDaikin128FanMed',['../ir__Daikin_8h.html#a4eb21add9bfb6774047a8a2c8b87ebbf',1,'ir_Daikin.h']]], + ['kdaikin128fanpowerful_4741',['kDaikin128FanPowerful',['../ir__Daikin_8h.html#ae0899153669a6e8848556cd65c26c8b5',1,'ir_Daikin.h']]], + ['kdaikin128fanquiet_4742',['kDaikin128FanQuiet',['../ir__Daikin_8h.html#a54777f468236bf4b342240e8c523308d',1,'ir_Daikin.h']]], + ['kdaikin128footermark_4743',['kDaikin128FooterMark',['../ir__Daikin_8h.html#ad5668b12e38afa4b44a8e214dac22f2e',1,'ir_Daikin.h']]], + ['kdaikin128freq_4744',['kDaikin128Freq',['../ir__Daikin_8h.html#a5a76fc08310d517cb7e182c287e77df1',1,'ir_Daikin.h']]], + ['kdaikin128gap_4745',['kDaikin128Gap',['../ir__Daikin_8h.html#a6323c59eb5906ac2887a02f9cd09a329',1,'ir_Daikin.h']]], + ['kdaikin128halfhouroffset_4746',['kDaikin128HalfHourOffset',['../ir__Daikin_8h.html#a8fddd8a5dbad2fd49445eaa2104f7da3',1,'ir_Daikin.h']]], + ['kdaikin128hdrmark_4747',['kDaikin128HdrMark',['../ir__Daikin_8h.html#a6257375541b6e10bda4083d9529e80f0',1,'ir_Daikin.h']]], + ['kdaikin128hdrspace_4748',['kDaikin128HdrSpace',['../ir__Daikin_8h.html#a114a4cef444d4c552b90701cb7debc73',1,'ir_Daikin.h']]], + ['kdaikin128heat_4749',['kDaikin128Heat',['../ir__Daikin_8h.html#ada28db809b26e2ae9e927650d4cb4f7a',1,'ir_Daikin.h']]], + ['kdaikin128hoursoffset_4750',['kDaikin128HoursOffset',['../ir__Daikin_8h.html#ace543fba33c68e3df4aa4d250ed1e792',1,'ir_Daikin.h']]], + ['kdaikin128hourssize_4751',['kDaikin128HoursSize',['../ir__Daikin_8h.html#ac5441402c0ee486f3c752a91f09375ff',1,'ir_Daikin.h']]], + ['kdaikin128leadermark_4752',['kDaikin128LeaderMark',['../ir__Daikin_8h.html#ab609b8979a2d2bf4fa5b7164590b2bfb',1,'ir_Daikin.h']]], + ['kdaikin128leaderspace_4753',['kDaikin128LeaderSpace',['../ir__Daikin_8h.html#a259bfa510a9ec06049c0a7bf6563eb35',1,'ir_Daikin.h']]], + ['kdaikin128maskfan_4754',['kDaikin128MaskFan',['../ir__Daikin_8h.html#ae58228f3b9eae0ec171527ced89e509f',1,'ir_Daikin.h']]], + ['kdaikin128masklight_4755',['kDaikin128MaskLight',['../ir__Daikin_8h.html#a8d3d4325f91cbdd8ce0cec25fc0d2022',1,'ir_Daikin.h']]], + ['kdaikin128maxtemp_4756',['kDaikin128MaxTemp',['../ir__Daikin_8h.html#a7dcd514d292ef98d70083227d046baad',1,'ir_Daikin.h']]], + ['kdaikin128mintemp_4757',['kDaikin128MinTemp',['../ir__Daikin_8h.html#aad27f3ff311f1defc5ac9fb3be0ad504',1,'ir_Daikin.h']]], + ['kdaikin128modesize_4758',['kDaikin128ModeSize',['../ir__Daikin_8h.html#a32a97adddfa791cc0e48d9bd847a3a4c',1,'ir_Daikin.h']]], + ['kdaikin128onespace_4759',['kDaikin128OneSpace',['../ir__Daikin_8h.html#ac6a9a48ae0037b889a6619361fd090ac',1,'ir_Daikin.h']]], + ['kdaikin128sectionlength_4760',['kDaikin128SectionLength',['../ir__Daikin_8h.html#a204a306e7d7071d4b798f7947c232520',1,'ir_Daikin.h']]], + ['kdaikin128sections_4761',['kDaikin128Sections',['../ir__Daikin_8h.html#a81f0cfda4d8452d6053cc6999a270b1f',1,'ir_Daikin.h']]], + ['kdaikin128statelength_4762',['kDaikin128StateLength',['../IRremoteESP8266_8h.html#a4279ccd14a3af2046e393661a7b4879f',1,'IRremoteESP8266.h']]], + ['kdaikin128timeroffset_4763',['kDaikin128TimerOffset',['../ir__Daikin_8h.html#aabde7c45424ae82a812485e8ceb58dbd',1,'ir_Daikin.h']]], + ['kdaikin128timersize_4764',['kDaikin128TimerSize',['../ir__Daikin_8h.html#a6f4022c5e4a092eb039c53ea72f51188',1,'ir_Daikin.h']]], + ['kdaikin128zerospace_4765',['kDaikin128ZeroSpace',['../ir__Daikin_8h.html#a1ca69805ada8ec451199c18d9da6f02a',1,'ir_Daikin.h']]], + ['kdaikin152bitmark_4766',['kDaikin152BitMark',['../ir__Daikin_8h.html#afd50318eaa383a7e85f0d0c2866bc9d5',1,'ir_Daikin.h']]], + ['kdaikin152bits_4767',['kDaikin152Bits',['../IRremoteESP8266_8h.html#af056e1ac2d00c6d6440c3dd2ae283f09',1,'IRremoteESP8266.h']]], + ['kdaikin152comfortbyte_4768',['kDaikin152ComfortByte',['../ir__Daikin_8h.html#a414b7acd5259122af5b496979fe068dc',1,'ir_Daikin.h']]], + ['kdaikin152comfortoffset_4769',['kDaikin152ComfortOffset',['../ir__Daikin_8h.html#a9cc7bb09fb66aa0cf7d0b751505fd3e6',1,'ir_Daikin.h']]], + ['kdaikin152defaultrepeat_4770',['kDaikin152DefaultRepeat',['../IRremoteESP8266_8h.html#a9407eebab271524e74bc3ddddb1a2e0b',1,'IRremoteESP8266.h']]], + ['kdaikin152drytemp_4771',['kDaikin152DryTemp',['../ir__Daikin_8h.html#a86e9308c00dbdd79546687af412c4156',1,'ir_Daikin.h']]], + ['kdaikin152econobyte_4772',['kDaikin152EconoByte',['../ir__Daikin_8h.html#a988782fd6bcf25b098d7c07e38679a78',1,'ir_Daikin.h']]], + ['kdaikin152fanbyte_4773',['kDaikin152FanByte',['../ir__Daikin_8h.html#a1972e59df2902335e37b2d66d16048a8',1,'ir_Daikin.h']]], + ['kdaikin152fantemp_4774',['kDaikin152FanTemp',['../ir__Daikin_8h.html#ad5c5bb7e8b181c79fe68607c1a4d202f',1,'ir_Daikin.h']]], + ['kdaikin152freq_4775',['kDaikin152Freq',['../ir__Daikin_8h.html#aa45492ae186142971975b7da56658a0b',1,'ir_Daikin.h']]], + ['kdaikin152gap_4776',['kDaikin152Gap',['../ir__Daikin_8h.html#aee02d3b17db4a382035c00329c6c2a0a',1,'ir_Daikin.h']]], + ['kdaikin152hdrmark_4777',['kDaikin152HdrMark',['../ir__Daikin_8h.html#a85fad797a9b43cb317fdb2e2c254a3bb',1,'ir_Daikin.h']]], + ['kdaikin152hdrspace_4778',['kDaikin152HdrSpace',['../ir__Daikin_8h.html#a0eb0b1b5fabab75a5956b6b939696a12',1,'ir_Daikin.h']]], + ['kdaikin152leaderbits_4779',['kDaikin152LeaderBits',['../ir__Daikin_8h.html#a432454efd5ea7457d34fe014b0d328c1',1,'ir_Daikin.h']]], + ['kdaikin152modebyte_4780',['kDaikin152ModeByte',['../ir__Daikin_8h.html#a1aaa767f722926e9aaf02dbcd8029003',1,'ir_Daikin.h']]], + ['kdaikin152onespace_4781',['kDaikin152OneSpace',['../ir__Daikin_8h.html#a1f96172c74b261a26ec6d71201f7c589',1,'ir_Daikin.h']]], + ['kdaikin152powerbyte_4782',['kDaikin152PowerByte',['../ir__Daikin_8h.html#a67ff6fbdc004d3a29b1d31c5bc47f572',1,'ir_Daikin.h']]], + ['kdaikin152powerfulbyte_4783',['kDaikin152PowerfulByte',['../ir__Daikin_8h.html#a720a3019f7bb2f8c458a7b79fbadd08f',1,'ir_Daikin.h']]], + ['kdaikin152quietbyte_4784',['kDaikin152QuietByte',['../ir__Daikin_8h.html#ad534758115c401368a428d887faa8768',1,'ir_Daikin.h']]], + ['kdaikin152sensorbyte_4785',['kDaikin152SensorByte',['../ir__Daikin_8h.html#a33187d50e8414f943d050a0b1c312168',1,'ir_Daikin.h']]], + ['kdaikin152sensoroffset_4786',['kDaikin152SensorOffset',['../ir__Daikin_8h.html#a01ef92b6eb478b1897fdfdcea03d7116',1,'ir_Daikin.h']]], + ['kdaikin152statelength_4787',['kDaikin152StateLength',['../IRremoteESP8266_8h.html#ae7579708922ffd3e44295f8770878983',1,'IRremoteESP8266.h']]], + ['kdaikin152swingvbyte_4788',['kDaikin152SwingVByte',['../ir__Daikin_8h.html#a9ed39bcce7d0bc73060fba843dfd2b28',1,'ir_Daikin.h']]], + ['kdaikin152tempbyte_4789',['kDaikin152TempByte',['../ir__Daikin_8h.html#a5e232b17db30a7e0ba159e2413df8b14',1,'ir_Daikin.h']]], + ['kdaikin152tempsize_4790',['kDaikin152TempSize',['../ir__Daikin_8h.html#ad22ee842100e70d95f1ebcdcaf3f2099',1,'ir_Daikin.h']]], + ['kdaikin152zerospace_4791',['kDaikin152ZeroSpace',['../ir__Daikin_8h.html#aec201aee71c0e301e8e191ddcaadb2de',1,'ir_Daikin.h']]], + ['kdaikin160bitmark_4792',['kDaikin160BitMark',['../ir__Daikin_8h.html#a852c2268ed7a8dd42c629e8a0706b6f5',1,'ir_Daikin.h']]], + ['kdaikin160bits_4793',['kDaikin160Bits',['../IRremoteESP8266_8h.html#aa6f1d6dded2ae3500cd52aa0c482a1b6',1,'IRremoteESP8266.h']]], + ['kdaikin160bytefan_4794',['kDaikin160ByteFan',['../ir__Daikin_8h.html#a980ae6010c956c92348d3ac88c084247',1,'ir_Daikin.h']]], + ['kdaikin160bytemode_4795',['kDaikin160ByteMode',['../ir__Daikin_8h.html#a6c5bcb2c4447dafc53c26775539886e6',1,'ir_Daikin.h']]], + ['kdaikin160bytepower_4796',['kDaikin160BytePower',['../ir__Daikin_8h.html#a8e79923cf8aa346ea52791887b54ffbe',1,'ir_Daikin.h']]], + ['kdaikin160byteswingv_4797',['kDaikin160ByteSwingV',['../ir__Daikin_8h.html#a35032831d79e96a98527896cd5d52efe',1,'ir_Daikin.h']]], + ['kdaikin160bytetemp_4798',['kDaikin160ByteTemp',['../ir__Daikin_8h.html#a1b9eed515f9cfc3508cce7d53fb7a84a',1,'ir_Daikin.h']]], + ['kdaikin160defaultrepeat_4799',['kDaikin160DefaultRepeat',['../IRremoteESP8266_8h.html#a82f4f1d8fae51c7e2f1f6753ca6e6053',1,'IRremoteESP8266.h']]], + ['kdaikin160freq_4800',['kDaikin160Freq',['../ir__Daikin_8h.html#a69e8abb57aecc6b99c60c5df7e18ff39',1,'ir_Daikin.h']]], + ['kdaikin160gap_4801',['kDaikin160Gap',['../ir__Daikin_8h.html#a8d107f0d63ef6951d657a55a370e8a8b',1,'ir_Daikin.h']]], + ['kdaikin160hdrmark_4802',['kDaikin160HdrMark',['../ir__Daikin_8h.html#a96043b43ba4d963456206e2d02639325',1,'ir_Daikin.h']]], + ['kdaikin160hdrspace_4803',['kDaikin160HdrSpace',['../ir__Daikin_8h.html#aefa7b5de43483951e00bd5d2cdbe5665',1,'ir_Daikin.h']]], + ['kdaikin160maskfan_4804',['kDaikin160MaskFan',['../ir__Daikin_8h.html#a623f586183436960361a85f8480c87c6',1,'ir_Daikin.h']]], + ['kdaikin160maskswingv_4805',['kDaikin160MaskSwingV',['../ir__Daikin_8h.html#abfaa078f7dfdd1c0bb14ad15fee26604',1,'ir_Daikin.h']]], + ['kdaikin160onespace_4806',['kDaikin160OneSpace',['../ir__Daikin_8h.html#a068c2252191675dca6503bfc37e4785e',1,'ir_Daikin.h']]], + ['kdaikin160section1length_4807',['kDaikin160Section1Length',['../ir__Daikin_8h.html#a06b59ee56cddcdcd9dfa375663da0c2d',1,'ir_Daikin.h']]], + ['kdaikin160section2length_4808',['kDaikin160Section2Length',['../ir__Daikin_8h.html#a7d6194a363661e11167cc972f1b92f68',1,'ir_Daikin.h']]], + ['kdaikin160sections_4809',['kDaikin160Sections',['../ir__Daikin_8h.html#afcc5de2994c1cd618437f1c67a5754d0',1,'ir_Daikin.h']]], + ['kdaikin160statelength_4810',['kDaikin160StateLength',['../IRremoteESP8266_8h.html#a09f022a12a40a8fae09bfbddfbee6d62',1,'IRremoteESP8266.h']]], + ['kdaikin160swingvauto_4811',['kDaikin160SwingVAuto',['../ir__Daikin_8h.html#aa6d9ee84d2c15c69ed8dbbc832285baf',1,'ir_Daikin.h']]], + ['kdaikin160swingvhigh_4812',['kDaikin160SwingVHigh',['../ir__Daikin_8h.html#abf542bd70d12534af72fb4ec8df5d265',1,'ir_Daikin.h']]], + ['kdaikin160swingvhighest_4813',['kDaikin160SwingVHighest',['../ir__Daikin_8h.html#a2a48ca041acbde68b902a4d0be4aeec5',1,'ir_Daikin.h']]], + ['kdaikin160swingvlow_4814',['kDaikin160SwingVLow',['../ir__Daikin_8h.html#a04ff7cb63db6b281ced56283288f05c0',1,'ir_Daikin.h']]], + ['kdaikin160swingvlowest_4815',['kDaikin160SwingVLowest',['../ir__Daikin_8h.html#ac4f34c7862802b21dede2ac0b534c8d8',1,'ir_Daikin.h']]], + ['kdaikin160swingvmiddle_4816',['kDaikin160SwingVMiddle',['../ir__Daikin_8h.html#a620b644f07f9b664f09417bb362dc216',1,'ir_Daikin.h']]], + ['kdaikin160tempoffset_4817',['kDaikin160TempOffset',['../ir__Daikin_8h.html#aa2f7050929bab65dbdb8af5b493dafe2',1,'ir_Daikin.h']]], + ['kdaikin160tempsize_4818',['kDaikin160TempSize',['../ir__Daikin_8h.html#adfecac727480010fae8e419ac3f13e73',1,'ir_Daikin.h']]], + ['kdaikin160zerospace_4819',['kDaikin160ZeroSpace',['../ir__Daikin_8h.html#a2b4591126c0b26ab16b5611dbfa4d5f6',1,'ir_Daikin.h']]], + ['kdaikin176bitmark_4820',['kDaikin176BitMark',['../ir__Daikin_8h.html#a4be0185fb8f65c0286cbf55dfd63a40f',1,'ir_Daikin.h']]], + ['kdaikin176bits_4821',['kDaikin176Bits',['../IRremoteESP8266_8h.html#a78baf9c97c548618428d2fcfd7cc91d7',1,'IRremoteESP8266.h']]], + ['kdaikin176bytefan_4822',['kDaikin176ByteFan',['../ir__Daikin_8h.html#a21e4b1854d3f87757ba0f0c10074226c',1,'ir_Daikin.h']]], + ['kdaikin176bytemode_4823',['kDaikin176ByteMode',['../ir__Daikin_8h.html#ad114b4570f96bcbf5358fa1ece354572',1,'ir_Daikin.h']]], + ['kdaikin176bytemodebutton_4824',['kDaikin176ByteModeButton',['../ir__Daikin_8h.html#aacda7563a2aaa9a56c77ce550f24a237',1,'ir_Daikin.h']]], + ['kdaikin176bytepower_4825',['kDaikin176BytePower',['../ir__Daikin_8h.html#aabfb9642dce0ab4169b193955221b938',1,'ir_Daikin.h']]], + ['kdaikin176byteswingh_4826',['kDaikin176ByteSwingH',['../ir__Daikin_8h.html#a4566642e6aaa0d64c531fafe0309dccc',1,'ir_Daikin.h']]], + ['kdaikin176bytetemp_4827',['kDaikin176ByteTemp',['../ir__Daikin_8h.html#afab294c7e8c65e5bf58e85bee4901752',1,'ir_Daikin.h']]], + ['kdaikin176cool_4828',['kDaikin176Cool',['../ir__Daikin_8h.html#ab67e912a9abdda7dcbe52ce90b70a3b5',1,'ir_Daikin.h']]], + ['kdaikin176defaultrepeat_4829',['kDaikin176DefaultRepeat',['../IRremoteESP8266_8h.html#a0228803e8fff3c73227214d4bb3d8b05',1,'IRremoteESP8266.h']]], + ['kdaikin176dryfantemp_4830',['kDaikin176DryFanTemp',['../ir__Daikin_8h.html#a462ad30312f13443f51b510e5b391f42',1,'ir_Daikin.h']]], + ['kdaikin176fanmax_4831',['kDaikin176FanMax',['../ir__Daikin_8h.html#a97e77d2a09bc753c17104f9695a0c0b1',1,'ir_Daikin.h']]], + ['kdaikin176freq_4832',['kDaikin176Freq',['../ir__Daikin_8h.html#a7f0c76e579dad510f21c34ba57cbf8dc',1,'ir_Daikin.h']]], + ['kdaikin176gap_4833',['kDaikin176Gap',['../ir__Daikin_8h.html#a0309c9d689f64e2d57ab09a2bb27bc18',1,'ir_Daikin.h']]], + ['kdaikin176hdrmark_4834',['kDaikin176HdrMark',['../ir__Daikin_8h.html#a9ff1ca660571d09caa0de39ce1370720',1,'ir_Daikin.h']]], + ['kdaikin176hdrspace_4835',['kDaikin176HdrSpace',['../ir__Daikin_8h.html#a64c4874b5d92682911ca84e826e1ff0b',1,'ir_Daikin.h']]], + ['kdaikin176maskfan_4836',['kDaikin176MaskFan',['../ir__Daikin_8h.html#ae7410031c68ae8426caa61bc97909cdf',1,'ir_Daikin.h']]], + ['kdaikin176maskmode_4837',['kDaikin176MaskMode',['../ir__Daikin_8h.html#a65b76b7a85d70a4ed1af359b2babffa1',1,'ir_Daikin.h']]], + ['kdaikin176modebutton_4838',['kDaikin176ModeButton',['../ir__Daikin_8h.html#a5c8602d17e9f70eefd735741b9d714eb',1,'ir_Daikin.h']]], + ['kdaikin176onespace_4839',['kDaikin176OneSpace',['../ir__Daikin_8h.html#a86ed046d66daf884ac0f06722991f5ba',1,'ir_Daikin.h']]], + ['kdaikin176section1length_4840',['kDaikin176Section1Length',['../ir__Daikin_8h.html#a4c5ce7df75834c77c0908cc40dbe02ed',1,'ir_Daikin.h']]], + ['kdaikin176section2length_4841',['kDaikin176Section2Length',['../ir__Daikin_8h.html#a9e2bb25a1d64d2c042e7eef38f5347d0',1,'ir_Daikin.h']]], + ['kdaikin176sections_4842',['kDaikin176Sections',['../ir__Daikin_8h.html#a177d12ac0f4fe8b5c5aeaf8f72579607',1,'ir_Daikin.h']]], + ['kdaikin176statelength_4843',['kDaikin176StateLength',['../IRremoteESP8266_8h.html#aa71fc87dcb6f14b82997e1d2269429d2',1,'IRremoteESP8266.h']]], + ['kdaikin176swinghauto_4844',['kDaikin176SwingHAuto',['../ir__Daikin_8h.html#a326ffcf00330a1759e4f71f8f8603f23',1,'ir_Daikin.h']]], + ['kdaikin176swinghoff_4845',['kDaikin176SwingHOff',['../ir__Daikin_8h.html#a8672ccb9016808c84b1b06de6584188a',1,'ir_Daikin.h']]], + ['kdaikin176tempoffset_4846',['kDaikin176TempOffset',['../ir__Daikin_8h.html#aa5f6cc15ca424e4bf9cc4357d9db79c9',1,'ir_Daikin.h']]], + ['kdaikin176tempsize_4847',['kDaikin176TempSize',['../ir__Daikin_8h.html#a3ef1914f2caf650a90d8412f2c1e2b74',1,'ir_Daikin.h']]], + ['kdaikin176zerospace_4848',['kDaikin176ZeroSpace',['../ir__Daikin_8h.html#a4db8836caa6cae0bab6fbde94409c879',1,'ir_Daikin.h']]], + ['kdaikin216bitmark_4849',['kDaikin216BitMark',['../ir__Daikin_8h.html#ada7cf9c593d716617ff4436755eef4f9',1,'ir_Daikin.h']]], + ['kdaikin216bits_4850',['kDaikin216Bits',['../IRremoteESP8266_8h.html#a317bf475ee4c6ddd802995dc535377d9',1,'IRremoteESP8266.h']]], + ['kdaikin216bytefan_4851',['kDaikin216ByteFan',['../ir__Daikin_8h.html#a832e7a349293058ebc50c17b904fb8f7',1,'ir_Daikin.h']]], + ['kdaikin216bytemode_4852',['kDaikin216ByteMode',['../ir__Daikin_8h.html#a48974eb3ceb40f2f580bd266a60f0392',1,'ir_Daikin.h']]], + ['kdaikin216bytepower_4853',['kDaikin216BytePower',['../ir__Daikin_8h.html#a740c2db81aebd8cb9e18b3f8c6c5b8be',1,'ir_Daikin.h']]], + ['kdaikin216bytepowerful_4854',['kDaikin216BytePowerful',['../ir__Daikin_8h.html#a9a428d988d705beae3ff1f7c0f01cb8d',1,'ir_Daikin.h']]], + ['kdaikin216byteswingh_4855',['kDaikin216ByteSwingH',['../ir__Daikin_8h.html#a20239baacdf9fb981eb0fb84b0ef536a',1,'ir_Daikin.h']]], + ['kdaikin216byteswingv_4856',['kDaikin216ByteSwingV',['../ir__Daikin_8h.html#a9fd16b0fb0d67a7058816d4b4f1659fc',1,'ir_Daikin.h']]], + ['kdaikin216bytetemp_4857',['kDaikin216ByteTemp',['../ir__Daikin_8h.html#a5828687e12d2b7fe1d793235d91750bd',1,'ir_Daikin.h']]], + ['kdaikin216defaultrepeat_4858',['kDaikin216DefaultRepeat',['../IRremoteESP8266_8h.html#a9d14d424d5a93de62f3e6f453db112db',1,'IRremoteESP8266.h']]], + ['kdaikin216freq_4859',['kDaikin216Freq',['../ir__Daikin_8h.html#aa3a9753c90ecb6d7f5ee3e5a16c79217',1,'ir_Daikin.h']]], + ['kdaikin216gap_4860',['kDaikin216Gap',['../ir__Daikin_8h.html#ab807adaab8afbeb97afaa9ddb2ec2c63',1,'ir_Daikin.h']]], + ['kdaikin216hdrmark_4861',['kDaikin216HdrMark',['../ir__Daikin_8h.html#a24163655b3d374aa643506c2bf4a2406',1,'ir_Daikin.h']]], + ['kdaikin216hdrspace_4862',['kDaikin216HdrSpace',['../ir__Daikin_8h.html#a2e69973e9a4aee29668597d09fcd70a4',1,'ir_Daikin.h']]], + ['kdaikin216maskfan_4863',['kDaikin216MaskFan',['../ir__Daikin_8h.html#a88f67ea1fe03ef40b81c5226ff5c72d5',1,'ir_Daikin.h']]], + ['kdaikin216onespace_4864',['kDaikin216OneSpace',['../ir__Daikin_8h.html#a1edeb73093bdea23e6cfb39c31ca1fce',1,'ir_Daikin.h']]], + ['kdaikin216section1length_4865',['kDaikin216Section1Length',['../ir__Daikin_8h.html#a5aacc812feb33ef954adc49086036859',1,'ir_Daikin.h']]], + ['kdaikin216section2length_4866',['kDaikin216Section2Length',['../ir__Daikin_8h.html#aade497bb9aad663a9e1e9403188d2154',1,'ir_Daikin.h']]], + ['kdaikin216sections_4867',['kDaikin216Sections',['../ir__Daikin_8h.html#a0ecd54bb733b982e3e5adf0c13ac9f6b',1,'ir_Daikin.h']]], + ['kdaikin216statelength_4868',['kDaikin216StateLength',['../IRremoteESP8266_8h.html#a70a1a65c1947b440e4ff27477de5ddc7',1,'IRremoteESP8266.h']]], + ['kdaikin216swingoff_4869',['kDaikin216SwingOff',['../ir__Daikin_8h.html#a84d6bb74c705dfbcd558f0b411a2a88e',1,'ir_Daikin.h']]], + ['kdaikin216swingon_4870',['kDaikin216SwingOn',['../ir__Daikin_8h.html#a4b2d77aafd84ed004390b5d4c7ad0455',1,'ir_Daikin.h']]], + ['kdaikin216swingsize_4871',['kDaikin216SwingSize',['../ir__Daikin_8h.html#a90d9e740067051fe294f1b408f7e020b',1,'ir_Daikin.h']]], + ['kdaikin216tempoffset_4872',['kDaikin216TempOffset',['../ir__Daikin_8h.html#a8e497623bb05ff10287ca06ac6ec15f6',1,'ir_Daikin.h']]], + ['kdaikin216tempsize_4873',['kDaikin216TempSize',['../ir__Daikin_8h.html#a3ef59f8474b38d1b0311f1018dbd6225',1,'ir_Daikin.h']]], + ['kdaikin216zerospace_4874',['kDaikin216ZeroSpace',['../ir__Daikin_8h.html#a448250dbb5a3a9733f21a0e347d17999',1,'ir_Daikin.h']]], + ['kdaikin2beepoffset_4875',['kDaikin2BeepOffset',['../ir__Daikin_8h.html#ad7f6110b5e3bf8c3b72ca07b745bae7c',1,'ir_Daikin.h']]], + ['kdaikin2beepsize_4876',['kDaikin2BeepSize',['../ir__Daikin_8h.html#a3a42f10a3427bff7af3c745592fe58fe',1,'ir_Daikin.h']]], + ['kdaikin2bitclean_4877',['kDaikin2BitClean',['../ir__Daikin_8h.html#a6672ff35e765c9ecb14107e7732b0bb2',1,'ir_Daikin.h']]], + ['kdaikin2bitcleanoffset_4878',['kDaikin2BitCleanOffset',['../ir__Daikin_8h.html#a4fa7ed25fb3f2371c3b5c7cf4906a3f3',1,'ir_Daikin.h']]], + ['kdaikin2biteye_4879',['kDaikin2BitEye',['../ir__Daikin_8h.html#a8adb3f3e8508adf8adc530365fceb96b',1,'ir_Daikin.h']]], + ['kdaikin2biteyeauto_4880',['kDaikin2BitEyeAuto',['../ir__Daikin_8h.html#a6a24519db9870520a645e4ad31857e39',1,'ir_Daikin.h']]], + ['kdaikin2biteyeautooffset_4881',['kDaikin2BitEyeAutoOffset',['../ir__Daikin_8h.html#a73db209ad074eeaef1a5317cbee8ab35',1,'ir_Daikin.h']]], + ['kdaikin2biteyeoffset_4882',['kDaikin2BitEyeOffset',['../ir__Daikin_8h.html#a7a4c6e131d9a0e441de549bd5f93074f',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshair_4883',['kDaikin2BitFreshAir',['../ir__Daikin_8h.html#a9ab2c4b0f415ce0042b848e44850b7b8',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairhigh_4884',['kDaikin2BitFreshAirHigh',['../ir__Daikin_8h.html#a21a3f3c0f39827057d8f459283a72980',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairhighoffset_4885',['kDaikin2BitFreshAirHighOffset',['../ir__Daikin_8h.html#afd4f5946e5fa5d8f48af32b8934b0f93',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairoffset_4886',['kDaikin2BitFreshAirOffset',['../ir__Daikin_8h.html#a15e49a577737bdca28c28aeeb4260e57',1,'ir_Daikin.h']]], + ['kdaikin2bitmark_4887',['kDaikin2BitMark',['../ir__Daikin_8h.html#a226f10b7216d4f039cf79af823673a18',1,'ir_Daikin.h']]], + ['kdaikin2bitmold_4888',['kDaikin2BitMold',['../ir__Daikin_8h.html#aa452116afeb7d246cee672d2717e0ff7',1,'ir_Daikin.h']]], + ['kdaikin2bitmoldoffset_4889',['kDaikin2BitMoldOffset',['../ir__Daikin_8h.html#a0e58caeb44ebc6b7c6d06e91fee33795',1,'ir_Daikin.h']]], + ['kdaikin2bitpower_4890',['kDaikin2BitPower',['../ir__Daikin_8h.html#ac7b549d7b68bc245521d7f4e6a4643ab',1,'ir_Daikin.h']]], + ['kdaikin2bitpoweroffset_4891',['kDaikin2BitPowerOffset',['../ir__Daikin_8h.html#a617d14e811cb26b86fef3048151ffc45',1,'ir_Daikin.h']]], + ['kdaikin2bitpurify_4892',['kDaikin2BitPurify',['../ir__Daikin_8h.html#a9c4d6aa579adbfe454aa19f9f604f21c',1,'ir_Daikin.h']]], + ['kdaikin2bitpurifyoffset_4893',['kDaikin2BitPurifyOffset',['../ir__Daikin_8h.html#a847a9646dc86c26da931e5bf6640ddab',1,'ir_Daikin.h']]], + ['kdaikin2bits_4894',['kDaikin2Bits',['../IRremoteESP8266_8h.html#affd9b805fff390d05a83ff4eaa1c98de',1,'IRremoteESP8266.h']]], + ['kdaikin2bitsleeptimer_4895',['kDaikin2BitSleepTimer',['../ir__Daikin_8h.html#a928ae056887b123fdf6b1e2072d03564',1,'ir_Daikin.h']]], + ['kdaikin2bitsleeptimeroffset_4896',['kDaikin2BitSleepTimerOffset',['../ir__Daikin_8h.html#abf7cfde40fd00c3500ed08831434b80f',1,'ir_Daikin.h']]], + ['kdaikin2defaultrepeat_4897',['kDaikin2DefaultRepeat',['../IRremoteESP8266_8h.html#a2dde8fd00f8a28e35da04cff9a3a1908',1,'IRremoteESP8266.h']]], + ['kdaikin2fanbyte_4898',['kDaikin2FanByte',['../ir__Daikin_8h.html#a88608f735885e11734ae83a0cc69dc8d',1,'ir_Daikin.h']]], + ['kdaikin2freq_4899',['kDaikin2Freq',['../ir__Daikin_8h.html#ab82e4836d9023c4ba3041d1226761461',1,'ir_Daikin.h']]], + ['kdaikin2gap_4900',['kDaikin2Gap',['../ir__Daikin_8h.html#afe14712c1be4ca14d5cd41e77d4bada0',1,'ir_Daikin.h']]], + ['kdaikin2hdrmark_4901',['kDaikin2HdrMark',['../ir__Daikin_8h.html#ab679ef183af5b94f53697d434e6540c3',1,'ir_Daikin.h']]], + ['kdaikin2hdrspace_4902',['kDaikin2HdrSpace',['../ir__Daikin_8h.html#a557f8eeaf55ff7fda0cacd0245ac27d3',1,'ir_Daikin.h']]], + ['kdaikin2leadermark_4903',['kDaikin2LeaderMark',['../ir__Daikin_8h.html#a533c7ea8f968502d4b31e14eb2b1f614',1,'ir_Daikin.h']]], + ['kdaikin2leaderspace_4904',['kDaikin2LeaderSpace',['../ir__Daikin_8h.html#a9d48d64e470ff0318bd62b3385433f57',1,'ir_Daikin.h']]], + ['kdaikin2lightoffset_4905',['kDaikin2LightOffset',['../ir__Daikin_8h.html#a0f40d38db7c625df9504798938ba24eb',1,'ir_Daikin.h']]], + ['kdaikin2lightsize_4906',['kDaikin2LightSize',['../ir__Daikin_8h.html#a4dc46fabef2c96a263a504a5f9012e1f',1,'ir_Daikin.h']]], + ['kdaikin2mincooltemp_4907',['kDaikin2MinCoolTemp',['../ir__Daikin_8h.html#a78b37644f9327537d35bec4c0fd8faee',1,'ir_Daikin.h']]], + ['kdaikin2onespace_4908',['kDaikin2OneSpace',['../ir__Daikin_8h.html#a70a96368500562fa95f88dc2f203c194',1,'ir_Daikin.h']]], + ['kdaikin2section1length_4909',['kDaikin2Section1Length',['../ir__Daikin_8h.html#a463878e9bfb22ca3c64a40259598872c',1,'ir_Daikin.h']]], + ['kdaikin2section2length_4910',['kDaikin2Section2Length',['../ir__Daikin_8h.html#a8cb956f86fdf487b1ea7ac388eeda2b5',1,'ir_Daikin.h']]], + ['kdaikin2sections_4911',['kDaikin2Sections',['../ir__Daikin_8h.html#a770cef4efa5d5668b063cf0e26f1b134',1,'ir_Daikin.h']]], + ['kdaikin2statelength_4912',['kDaikin2StateLength',['../IRremoteESP8266_8h.html#a349e4d17f83bb3e707ff19c0255c1644',1,'IRremoteESP8266.h']]], + ['kdaikin2swinghauto_4913',['kDaikin2SwingHAuto',['../ir__Daikin_8h.html#a834a3138b0f9bfdac98d26aa63bc951e',1,'ir_Daikin.h']]], + ['kdaikin2swinghleft_4914',['kDaikin2SwingHLeft',['../ir__Daikin_8h.html#aa9b294b2f12660081171df290a7e874f',1,'ir_Daikin.h']]], + ['kdaikin2swinghleftmax_4915',['kDaikin2SwingHLeftMax',['../ir__Daikin_8h.html#aac08696fc9734996537204c089db2f7c',1,'ir_Daikin.h']]], + ['kdaikin2swinghmiddle_4916',['kDaikin2SwingHMiddle',['../ir__Daikin_8h.html#ab882d68819344e622182b07ded30cccf',1,'ir_Daikin.h']]], + ['kdaikin2swinghright_4917',['kDaikin2SwingHRight',['../ir__Daikin_8h.html#a8d7c79266bedbb722dc1a74c8b727a27',1,'ir_Daikin.h']]], + ['kdaikin2swinghrightmax_4918',['kDaikin2SwingHRightMax',['../ir__Daikin_8h.html#a843ad9ee10eccd799814ca9fff57f481',1,'ir_Daikin.h']]], + ['kdaikin2swinghswing_4919',['kDaikin2SwingHSwing',['../ir__Daikin_8h.html#a3776d46e94a771a6dc94d14257f34d09',1,'ir_Daikin.h']]], + ['kdaikin2swinghwide_4920',['kDaikin2SwingHWide',['../ir__Daikin_8h.html#a93157e048486e564757ba737551cf481',1,'ir_Daikin.h']]], + ['kdaikin2swingvauto_4921',['kDaikin2SwingVAuto',['../ir__Daikin_8h.html#aa91228576ef22854a693c86df5276cbb',1,'ir_Daikin.h']]], + ['kdaikin2swingvbreeze_4922',['kDaikin2SwingVBreeze',['../ir__Daikin_8h.html#a5646d38fff6a985314158796665d9d76',1,'ir_Daikin.h']]], + ['kdaikin2swingvcirculate_4923',['kDaikin2SwingVCirculate',['../ir__Daikin_8h.html#a717bb32ce20e6d65ee78a9e8ba0f5490',1,'ir_Daikin.h']]], + ['kdaikin2swingvhigh_4924',['kDaikin2SwingVHigh',['../ir__Daikin_8h.html#a2d25d46fb289c3450ed6817a45982e27',1,'ir_Daikin.h']]], + ['kdaikin2swingvlow_4925',['kDaikin2SwingVLow',['../ir__Daikin_8h.html#accae3be213670675f8dfc974fe19f2cf',1,'ir_Daikin.h']]], + ['kdaikin2swingvswing_4926',['kDaikin2SwingVSwing',['../ir__Daikin_8h.html#a2a62938481ba7b4374df50867295c07d',1,'ir_Daikin.h']]], + ['kdaikin2tolerance_4927',['kDaikin2Tolerance',['../ir__Daikin_8h.html#ac428e884b15026c0610cc1b0b8b46154',1,'ir_Daikin.h']]], + ['kdaikin2zerospace_4928',['kDaikin2ZeroSpace',['../ir__Daikin_8h.html#a91b023ce8679d8d0e4434e014e746f99',1,'ir_Daikin.h']]], + ['kdaikin64bitmark_4929',['kDaikin64BitMark',['../ir__Daikin_8h.html#a6d89c1acd56b670b2aba65429d6fbf00',1,'ir_Daikin.h']]], + ['kdaikin64bits_4930',['kDaikin64Bits',['../IRremoteESP8266_8h.html#a89266e9211a81eda22475fb5a258484f',1,'IRremoteESP8266.h']]], + ['kdaikin64checksumoffset_4931',['kDaikin64ChecksumOffset',['../ir__Daikin_8h.html#a5c47c0a0b1d2a23620beb2496af958c5',1,'ir_Daikin.h']]], + ['kdaikin64checksumsize_4932',['kDaikin64ChecksumSize',['../ir__Daikin_8h.html#a0c068274c73deb732e70a7daf6684391',1,'ir_Daikin.h']]], + ['kdaikin64clockhourssize_4933',['kDaikin64ClockHoursSize',['../ir__Daikin_8h.html#ae6d8f59a9707bc807a209167231d4399',1,'ir_Daikin.h']]], + ['kdaikin64clockminssize_4934',['kDaikin64ClockMinsSize',['../ir__Daikin_8h.html#a3ab23d9db994fb6dd52208f5f69b4531',1,'ir_Daikin.h']]], + ['kdaikin64clockoffset_4935',['kDaikin64ClockOffset',['../ir__Daikin_8h.html#af204ccf4e6bd33439cec240445785e9c',1,'ir_Daikin.h']]], + ['kdaikin64clocksize_4936',['kDaikin64ClockSize',['../ir__Daikin_8h.html#a110f42ae8aa2651b195c67eef15c4d79',1,'ir_Daikin.h']]], + ['kdaikin64cool_4937',['kDaikin64Cool',['../ir__Daikin_8h.html#a1ed020e8e7b5b741e90c4a27ca9f3a91',1,'ir_Daikin.h']]], + ['kdaikin64defaultrepeat_4938',['kDaikin64DefaultRepeat',['../IRremoteESP8266_8h.html#aca64338c3e3bbe52f8ec5688317041b3',1,'IRremoteESP8266.h']]], + ['kdaikin64dry_4939',['kDaikin64Dry',['../ir__Daikin_8h.html#aa494c8e2a54209c7467fdd7f40655b0b',1,'ir_Daikin.h']]], + ['kdaikin64fan_4940',['kDaikin64Fan',['../ir__Daikin_8h.html#aa1f4bb12be0f74af35ee54a5540f8a7b',1,'ir_Daikin.h']]], + ['kdaikin64fanauto_4941',['kDaikin64FanAuto',['../ir__Daikin_8h.html#a6fbc965cb8194048ed27d586321c01b2',1,'ir_Daikin.h']]], + ['kdaikin64fanhigh_4942',['kDaikin64FanHigh',['../ir__Daikin_8h.html#a122d57c30d1f4ad8f20d44077b0a1970',1,'ir_Daikin.h']]], + ['kdaikin64fanlow_4943',['kDaikin64FanLow',['../ir__Daikin_8h.html#a5a692fdcb373acf101536adb4c18384f',1,'ir_Daikin.h']]], + ['kdaikin64fanmed_4944',['kDaikin64FanMed',['../ir__Daikin_8h.html#a9b2737ba57e38d4c3dfe7bc65de4c944',1,'ir_Daikin.h']]], + ['kdaikin64fanoffset_4945',['kDaikin64FanOffset',['../ir__Daikin_8h.html#a5523d6df96b83aa152adc1cbdac6534f',1,'ir_Daikin.h']]], + ['kdaikin64fanquiet_4946',['kDaikin64FanQuiet',['../ir__Daikin_8h.html#a1a7d78b2ed8ca5b83d6422d659ecb296',1,'ir_Daikin.h']]], + ['kdaikin64fansize_4947',['kDaikin64FanSize',['../ir__Daikin_8h.html#ac907b8f8d46eb7983a1289f23bc02401',1,'ir_Daikin.h']]], + ['kdaikin64fanturbo_4948',['kDaikin64FanTurbo',['../ir__Daikin_8h.html#ae6d370916c0897bc82346136d7922f5d',1,'ir_Daikin.h']]], + ['kdaikin64freq_4949',['kDaikin64Freq',['../ir__Daikin_8h.html#a7b63829df4d0e1de61ed396c3b07e988',1,'ir_Daikin.h']]], + ['kdaikin64gap_4950',['kDaikin64Gap',['../ir__Daikin_8h.html#ae191cb5f6c65b944970158caaf56618d',1,'ir_Daikin.h']]], + ['kdaikin64hdrmark_4951',['kDaikin64HdrMark',['../ir__Daikin_8h.html#abe7b92798de08dfc5f044869891bdec5',1,'ir_Daikin.h']]], + ['kdaikin64hdrspace_4952',['kDaikin64HdrSpace',['../ir__Daikin_8h.html#a1eac122554acda264f9aa48261b2a884',1,'ir_Daikin.h']]], + ['kdaikin64knowngoodstate_4953',['kDaikin64KnownGoodState',['../ir__Daikin_8h.html#a09f0aa8c586b35b79bbceb19e822eb48',1,'ir_Daikin.h']]], + ['kdaikin64ldrmark_4954',['kDaikin64LdrMark',['../ir__Daikin_8h.html#aca20b8ee0fa9a8aa2d676ef12bd5ba97',1,'ir_Daikin.h']]], + ['kdaikin64ldrspace_4955',['kDaikin64LdrSpace',['../ir__Daikin_8h.html#ada1084c119abe58dadcb17eb4cfed072',1,'ir_Daikin.h']]], + ['kdaikin64maxtemp_4956',['kDaikin64MaxTemp',['../ir__Daikin_8h.html#a495e3b77590263a2c043c1ba12489fac',1,'ir_Daikin.h']]], + ['kdaikin64mintemp_4957',['kDaikin64MinTemp',['../ir__Daikin_8h.html#a209cb1798ae64de1f5274fb167ee62ea',1,'ir_Daikin.h']]], + ['kdaikin64modeoffset_4958',['kDaikin64ModeOffset',['../ir__Daikin_8h.html#ac32a0c805d01b5a9fa4d4aeb5546b8e3',1,'ir_Daikin.h']]], + ['kdaikin64modesize_4959',['kDaikin64ModeSize',['../ir__Daikin_8h.html#a451465916f9ae0586cf915005be33315',1,'ir_Daikin.h']]], + ['kdaikin64offtimeenablebit_4960',['kDaikin64OffTimeEnableBit',['../ir__Daikin_8h.html#a5d5c1380e6dd22cef44a76f74049a813',1,'ir_Daikin.h']]], + ['kdaikin64offtimehalfhourbit_4961',['kDaikin64OffTimeHalfHourBit',['../ir__Daikin_8h.html#a766df1d3c0fce7576a3e694b6e0d9242',1,'ir_Daikin.h']]], + ['kdaikin64offtimeoffset_4962',['kDaikin64OffTimeOffset',['../ir__Daikin_8h.html#a3aecddae0a4c0a3123b296dd6b0fb38e',1,'ir_Daikin.h']]], + ['kdaikin64offtimesize_4963',['kDaikin64OffTimeSize',['../ir__Daikin_8h.html#a70e8ae340d5f1ca35b2d6a46020b9dcc',1,'ir_Daikin.h']]], + ['kdaikin64onespace_4964',['kDaikin64OneSpace',['../ir__Daikin_8h.html#ab3129b72f5300893d04b47e72dd420e1',1,'ir_Daikin.h']]], + ['kdaikin64ontimeenablebit_4965',['kDaikin64OnTimeEnableBit',['../ir__Daikin_8h.html#ae264ee33d051149cecc08e3a026feba7',1,'ir_Daikin.h']]], + ['kdaikin64ontimehalfhourbit_4966',['kDaikin64OnTimeHalfHourBit',['../ir__Daikin_8h.html#a0d37e6624946b26dd30c3ed25181cc37',1,'ir_Daikin.h']]], + ['kdaikin64ontimeoffset_4967',['kDaikin64OnTimeOffset',['../ir__Daikin_8h.html#a6b4af969e8b114502f067b039b0a9467',1,'ir_Daikin.h']]], + ['kdaikin64ontimesize_4968',['kDaikin64OnTimeSize',['../ir__Daikin_8h.html#a46c5e1db123959992db9e746e2b3c58a',1,'ir_Daikin.h']]], + ['kdaikin64overhead_4969',['kDaikin64Overhead',['../ir__Daikin_8h.html#af0dafe45d0127430e05f2312e8ba99bb',1,'ir_Daikin.h']]], + ['kdaikin64powertogglebit_4970',['kDaikin64PowerToggleBit',['../ir__Daikin_8h.html#a55ca8803d859f0ffaac3c3547d6b532c',1,'ir_Daikin.h']]], + ['kdaikin64sleepbit_4971',['kDaikin64SleepBit',['../ir__Daikin_8h.html#addbe01f4a4766469fe5fd1cf9972f437',1,'ir_Daikin.h']]], + ['kdaikin64swingvbit_4972',['kDaikin64SwingVBit',['../ir__Daikin_8h.html#a9c7cbb529c760cead772fe03f7f90b1a',1,'ir_Daikin.h']]], + ['kdaikin64tempoffset_4973',['kDaikin64TempOffset',['../ir__Daikin_8h.html#a4b66ea40f97deafc22df18bd0942b5f1',1,'ir_Daikin.h']]], + ['kdaikin64tempsize_4974',['kDaikin64TempSize',['../ir__Daikin_8h.html#acc21945b46b307068e8669c83fbe5837',1,'ir_Daikin.h']]], + ['kdaikin64tolerancedelta_4975',['kDaikin64ToleranceDelta',['../ir__Daikin_8h.html#ae0b22a140c2727de9a347e8ab8d554e9',1,'ir_Daikin.h']]], + ['kdaikin64zerospace_4976',['kDaikin64ZeroSpace',['../ir__Daikin_8h.html#a142e45c289af1e9802254b9c138003fa',1,'ir_Daikin.h']]], + ['kdaikinauto_4977',['kDaikinAuto',['../ir__Daikin_8h.html#af3a0e7c149d020002cdf345a15606542',1,'ir_Daikin.h']]], + ['kdaikinbeeploud_4978',['kDaikinBeepLoud',['../ir__Daikin_8h.html#a4eb2b3899076882e3ed23220138ebac1',1,'ir_Daikin.h']]], + ['kdaikinbeepoff_4979',['kDaikinBeepOff',['../ir__Daikin_8h.html#a8271934c8bbd4b8e4d6aacdee5a038cf',1,'ir_Daikin.h']]], + ['kdaikinbeepquiet_4980',['kDaikinBeepQuiet',['../ir__Daikin_8h.html#a11008f7d6afc934426b88704d47301e7',1,'ir_Daikin.h']]], + ['kdaikinbitcomfort_4981',['kDaikinBitComfort',['../ir__Daikin_8h.html#aede9991f88965161d3f7cf1dba7fdeb7',1,'ir_Daikin.h']]], + ['kdaikinbitcomfortoffset_4982',['kDaikinBitComfortOffset',['../ir__Daikin_8h.html#a2e218dda2eb4ab3a97ea8018192c5f85',1,'ir_Daikin.h']]], + ['kdaikinbitecono_4983',['kDaikinBitEcono',['../ir__Daikin_8h.html#ab579939e749517944e6e497d5e44e922',1,'ir_Daikin.h']]], + ['kdaikinbiteconooffset_4984',['kDaikinBitEconoOffset',['../ir__Daikin_8h.html#aa99539b36ab708397bd1adbd4fd4f378',1,'ir_Daikin.h']]], + ['kdaikinbiteye_4985',['kDaikinBitEye',['../ir__Daikin_8h.html#a98bbaae1b0f16cf6f2428dcf326eda51',1,'ir_Daikin.h']]], + ['kdaikinbitmark_4986',['kDaikinBitMark',['../ir__Daikin_8h.html#ae109b9ea2120f989dac2529345e38adb',1,'ir_Daikin.h']]], + ['kdaikinbitmold_4987',['kDaikinBitMold',['../ir__Daikin_8h.html#a916ad89ccf3c0225a4ca1b36d74c67b2',1,'ir_Daikin.h']]], + ['kdaikinbitmoldoffset_4988',['kDaikinBitMoldOffset',['../ir__Daikin_8h.html#ad794d6ff5b5d05642e2668378d3a1100',1,'ir_Daikin.h']]], + ['kdaikinbitofftimer_4989',['kDaikinBitOffTimer',['../ir__Daikin_8h.html#a5d68046ada1892be65f14d06c2a25b2b',1,'ir_Daikin.h']]], + ['kdaikinbitofftimeroffset_4990',['kDaikinBitOffTimerOffset',['../ir__Daikin_8h.html#a7156bec80ef23aa0e4e212e11d63bdef',1,'ir_Daikin.h']]], + ['kdaikinbitontimer_4991',['kDaikinBitOnTimer',['../ir__Daikin_8h.html#a421a745ce85313d326e00b996b5afd80',1,'ir_Daikin.h']]], + ['kdaikinbitontimeroffset_4992',['kDaikinBitOnTimerOffset',['../ir__Daikin_8h.html#a7a6b740034320cc25fb6d33d36845ca0',1,'ir_Daikin.h']]], + ['kdaikinbitpower_4993',['kDaikinBitPower',['../ir__Daikin_8h.html#ab0d91673bcd73cbbbf5f18d6d73b699e',1,'ir_Daikin.h']]], + ['kdaikinbitpowerful_4994',['kDaikinBitPowerful',['../ir__Daikin_8h.html#a4d03bc31a28d866c3bf855f6482209e8',1,'ir_Daikin.h']]], + ['kdaikinbitpowerfuloffset_4995',['kDaikinBitPowerfulOffset',['../ir__Daikin_8h.html#a772bca7454e28bd3f61cdd24f58b98c8',1,'ir_Daikin.h']]], + ['kdaikinbitpoweroffset_4996',['kDaikinBitPowerOffset',['../ir__Daikin_8h.html#ad3672753b2b06b52cd8afeca3f564af4',1,'ir_Daikin.h']]], + ['kdaikinbits_4997',['kDaikinBits',['../IRremoteESP8266_8h.html#a657f8e60bc1f896d4a46ec101c289485',1,'IRremoteESP8266.h']]], + ['kdaikinbitsensor_4998',['kDaikinBitSensor',['../ir__Daikin_8h.html#a37c7e26d1af184f844ef2c46064137ad',1,'ir_Daikin.h']]], + ['kdaikinbitsensoroffset_4999',['kDaikinBitSensorOffset',['../ir__Daikin_8h.html#a1ccb2c358aef3bf55005cf6b391e9e9b',1,'ir_Daikin.h']]], + ['kdaikinbitsilent_5000',['kDaikinBitSilent',['../ir__Daikin_8h.html#a85249d39c34b1a8b3bb8de4da32bb502',1,'ir_Daikin.h']]], + ['kdaikinbitsilentoffset_5001',['kDaikinBitSilentOffset',['../ir__Daikin_8h.html#a3fb5172c458084319937aa4ec2d6383b',1,'ir_Daikin.h']]], + ['kdaikinbitsshort_5002',['kDaikinBitsShort',['../IRremoteESP8266_8h.html#aebaa8eb786747761fb369cfd34181cb7',1,'IRremoteESP8266.h']]], + ['kdaikinbitweeklytimer_5003',['kDaikinBitWeeklyTimer',['../ir__Daikin_8h.html#a7d58b7c351394a43117e4710acd35cec',1,'ir_Daikin.h']]], + ['kdaikinbitweeklytimeroffset_5004',['kDaikinBitWeeklyTimerOffset',['../ir__Daikin_8h.html#a8ff2c05701327b6f26bee66361e39365',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum1_5005',['kDaikinByteChecksum1',['../ir__Daikin_8h.html#a887d8d38cf4330e1107443471fa119ca',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum2_5006',['kDaikinByteChecksum2',['../ir__Daikin_8h.html#ab27225f21b29e617bf03fc68cc6e8e0f',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum3_5007',['kDaikinByteChecksum3',['../ir__Daikin_8h.html#a7277c453d4deed6abf0a7577b5b4454f',1,'ir_Daikin.h']]], + ['kdaikinbyteclockminshigh_5008',['kDaikinByteClockMinsHigh',['../ir__Daikin_8h.html#ade7d506fd7da26ae1713602c1620f716',1,'ir_Daikin.h']]], + ['kdaikinbyteclockminslow_5009',['kDaikinByteClockMinsLow',['../ir__Daikin_8h.html#a3c096c2f33eca6c6f7f57f0f684a4b43',1,'ir_Daikin.h']]], + ['kdaikinbytecomfort_5010',['kDaikinByteComfort',['../ir__Daikin_8h.html#a3b209715b7ac4e8ef4f15043654e646b',1,'ir_Daikin.h']]], + ['kdaikinbyteecono_5011',['kDaikinByteEcono',['../ir__Daikin_8h.html#ae08470f2e453a2a5b60bdb478fc8c6d7',1,'ir_Daikin.h']]], + ['kdaikinbyteeye_5012',['kDaikinByteEye',['../ir__Daikin_8h.html#ad3e2bb2f17d599c708e64cf08c042331',1,'ir_Daikin.h']]], + ['kdaikinbytefan_5013',['kDaikinByteFan',['../ir__Daikin_8h.html#a9078ad5b6b9afe43ffa0e646c35f3db6',1,'ir_Daikin.h']]], + ['kdaikinbytemold_5014',['kDaikinByteMold',['../ir__Daikin_8h.html#a81e098798e6aa7c0882703dced8ab039',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimer_5015',['kDaikinByteOffTimer',['../ir__Daikin_8h.html#ad7fce891883a25e260cd8c0890d46f59',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimerminshigh_5016',['kDaikinByteOffTimerMinsHigh',['../ir__Daikin_8h.html#a0294c99254e3eef7e7fa2cd169e0e5a9',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimerminslow_5017',['kDaikinByteOffTimerMinsLow',['../ir__Daikin_8h.html#a45855767cf37f1562a7726dbf6419c87',1,'ir_Daikin.h']]], + ['kdaikinbyteontimer_5018',['kDaikinByteOnTimer',['../ir__Daikin_8h.html#a0a685bb92d8e3df4c9bd96b71c48f352',1,'ir_Daikin.h']]], + ['kdaikinbyteontimerminshigh_5019',['kDaikinByteOnTimerMinsHigh',['../ir__Daikin_8h.html#a77ce46689e1a353237edd45e7170bff6',1,'ir_Daikin.h']]], + ['kdaikinbyteontimerminslow_5020',['kDaikinByteOnTimerMinsLow',['../ir__Daikin_8h.html#a7c434f5c6a3febddf3da44e1c2b97872',1,'ir_Daikin.h']]], + ['kdaikinbytepower_5021',['kDaikinBytePower',['../ir__Daikin_8h.html#aa99cac4871f7ef1cdff2f41496989218',1,'ir_Daikin.h']]], + ['kdaikinbytepowerful_5022',['kDaikinBytePowerful',['../ir__Daikin_8h.html#a79b3d4cd40f839a3708fa33abb4b74c4',1,'ir_Daikin.h']]], + ['kdaikinbytesensor_5023',['kDaikinByteSensor',['../ir__Daikin_8h.html#afd18e8b5b4c9c6572659ea46df01a6df',1,'ir_Daikin.h']]], + ['kdaikinbytesilent_5024',['kDaikinByteSilent',['../ir__Daikin_8h.html#aac58a7371777f682cac3189d9905b968',1,'ir_Daikin.h']]], + ['kdaikinbyteswingh_5025',['kDaikinByteSwingH',['../ir__Daikin_8h.html#a58b88a2679bd57d723aa33afca4f2427',1,'ir_Daikin.h']]], + ['kdaikinbytetemp_5026',['kDaikinByteTemp',['../ir__Daikin_8h.html#acd14c2ebc40a8375343595ed8f0109f8',1,'ir_Daikin.h']]], + ['kdaikinbyteweeklytimer_5027',['kDaikinByteWeeklyTimer',['../ir__Daikin_8h.html#ad4eba59910311bdc8b489b27b4b59751',1,'ir_Daikin.h']]], + ['kdaikinclockminshighoffset_5028',['kDaikinClockMinsHighOffset',['../ir__Daikin_8h.html#a1b28496ffacf558f7919029f029c2dc6',1,'ir_Daikin.h']]], + ['kdaikinclockminshighsize_5029',['kDaikinClockMinsHighSize',['../ir__Daikin_8h.html#a1e018d153b13c65e411b3b090efc6d27',1,'ir_Daikin.h']]], + ['kdaikincool_5030',['kDaikinCool',['../ir__Daikin_8h.html#aa57615a0a9f79b97139580a807bf095f',1,'ir_Daikin.h']]], + ['kdaikincurbit_5031',['kDaikinCurBit',['../ir__Daikin_8h.html#afccfde2b46f5fcb425f02a79a9c20494',1,'ir_Daikin.h']]], + ['kdaikincurindex_5032',['kDaikinCurIndex',['../ir__Daikin_8h.html#a5c01a0bfbd92b337d2e4a5c3df381865',1,'ir_Daikin.h']]], + ['kdaikindefaultrepeat_5033',['kDaikinDefaultRepeat',['../IRremoteESP8266_8h.html#af691d5202b7f121a16b2d9871ee14d9c',1,'IRremoteESP8266.h']]], + ['kdaikindowoffset_5034',['kDaikinDoWOffset',['../ir__Daikin_8h.html#a07793a4b1ea8e9aabb77730ccbdf7e15',1,'ir_Daikin.h']]], + ['kdaikindowsize_5035',['kDaikinDoWSize',['../ir__Daikin_8h.html#a7bb34e2fc2c1926167b79889a5036ba0',1,'ir_Daikin.h']]], + ['kdaikindry_5036',['kDaikinDry',['../ir__Daikin_8h.html#ab6143bef74a122c3fba3a3b29df0cf29',1,'ir_Daikin.h']]], + ['kdaikinfan_5037',['kDaikinFan',['../ir__Daikin_8h.html#a616df34328cdac764aecc9ffb0f16f09',1,'ir_Daikin.h']]], + ['kdaikinfanauto_5038',['kDaikinFanAuto',['../ir__Daikin_8h.html#a87807bd5727d9da1b615fca2bd732292',1,'ir_Daikin.h']]], + ['kdaikinfanmax_5039',['kDaikinFanMax',['../ir__Daikin_8h.html#ab483f3913a909884f44f8cd8f779bca0',1,'ir_Daikin.h']]], + ['kdaikinfanmed_5040',['kDaikinFanMed',['../ir__Daikin_8h.html#ab6eb2c902c2b5f927160efc9fb9ab08c',1,'ir_Daikin.h']]], + ['kdaikinfanmin_5041',['kDaikinFanMin',['../ir__Daikin_8h.html#a83ad300b9374e50c22211501ee2d1a7a',1,'ir_Daikin.h']]], + ['kdaikinfanoffset_5042',['kDaikinFanOffset',['../ir__Daikin_8h.html#a48d0d0cb1174069d5b6ee2882761cb88',1,'ir_Daikin.h']]], + ['kdaikinfanquiet_5043',['kDaikinFanQuiet',['../ir__Daikin_8h.html#aae481cf166671c30bccdc7f47aa6666e',1,'ir_Daikin.h']]], + ['kdaikinfansize_5044',['kDaikinFanSize',['../ir__Daikin_8h.html#a1e490e414ff3f5f55b4cca443661cd1a',1,'ir_Daikin.h']]], + ['kdaikinfirstheader64_5045',['kDaikinFirstHeader64',['../ir__Daikin_8h.html#a0bd3b36061d545bb21562622642f4196',1,'ir_Daikin.h']]], + ['kdaikingap_5046',['kDaikinGap',['../ir__Daikin_8h.html#aed68991584125a277593c339ab387276',1,'ir_Daikin.h']]], + ['kdaikinhdrmark_5047',['kDaikinHdrMark',['../ir__Daikin_8h.html#a0a38b3bdfd8f4f7a18f969188388e29e',1,'ir_Daikin.h']]], + ['kdaikinhdrspace_5048',['kDaikinHdrSpace',['../ir__Daikin_8h.html#ac4ca6c53faeec7d7a7ccfb50802087dc',1,'ir_Daikin.h']]], + ['kdaikinheaderlength_5049',['kDaikinHeaderLength',['../ir__Daikin_8h.html#a476ca864b6791439549bb4257ca78b23',1,'ir_Daikin.h']]], + ['kdaikinheat_5050',['kDaikinHeat',['../ir__Daikin_8h.html#a05824dc5af4ed0d3eceda540ad0e7a9f',1,'ir_Daikin.h']]], + ['kdaikinlightbright_5051',['kDaikinLightBright',['../ir__Daikin_8h.html#a20a3103d8d0a672c0c05c1679bf3b2ab',1,'ir_Daikin.h']]], + ['kdaikinlightdim_5052',['kDaikinLightDim',['../ir__Daikin_8h.html#a1093baf5b62fca42f9361715be2198a3',1,'ir_Daikin.h']]], + ['kdaikinlightoff_5053',['kDaikinLightOff',['../ir__Daikin_8h.html#ae57f7d2ea43e865ebf8175a8dbacab45',1,'ir_Daikin.h']]], + ['kdaikinmarkexcess_5054',['kDaikinMarkExcess',['../ir__Daikin_8h.html#a5331e1ee51bd7b001346aa41ee5d26cc',1,'ir_Daikin.h']]], + ['kdaikinmaxtemp_5055',['kDaikinMaxTemp',['../ir__Daikin_8h.html#aab7be756494a5ed23e9202af769e0012',1,'ir_Daikin.h']]], + ['kdaikinmintemp_5056',['kDaikinMinTemp',['../ir__Daikin_8h.html#af257feb15dc282c7d06351ee9eed666b',1,'ir_Daikin.h']]], + ['kdaikinmodeoffset_5057',['kDaikinModeOffset',['../ir__Daikin_8h.html#a9a3aa5ee98496b468c5ba86faa3eeeae',1,'ir_Daikin.h']]], + ['kdaikinmodesize_5058',['kDaikinModeSize',['../ir__Daikin_8h.html#a00fc390085520e5382dbce2633b7142e',1,'ir_Daikin.h']]], + ['kdaikinonespace_5059',['kDaikinOneSpace',['../ir__Daikin_8h.html#a6653082dcfde989bd2c5810809fc18a9',1,'ir_Daikin.h']]], + ['kdaikinontimerminshighoffset_5060',['kDaikinOnTimerMinsHighOffset',['../ir__Daikin_8h.html#a2a4a4254fc853901686982c1410c77c8',1,'ir_Daikin.h']]], + ['kdaikinontimerminshighsize_5061',['kDaikinOnTimerMinsHighSize',['../ir__Daikin_8h.html#a2fc9c203378e49ea1d49557d776de620',1,'ir_Daikin.h']]], + ['kdaikinsection1length_5062',['kDaikinSection1Length',['../ir__Daikin_8h.html#ab3b8aacbebe6c1c5514141102d1ca26f',1,'ir_Daikin.h']]], + ['kdaikinsection2length_5063',['kDaikinSection2Length',['../ir__Daikin_8h.html#a2e65cdf05d22a20f01ae5f6d3e222218',1,'ir_Daikin.h']]], + ['kdaikinsection3length_5064',['kDaikinSection3Length',['../ir__Daikin_8h.html#ae7dbaf6b4034267e4610087f9f2f51e3',1,'ir_Daikin.h']]], + ['kdaikinsections_5065',['kDaikinSections',['../ir__Daikin_8h.html#aad822c70789b861fa5beb839833e0b4c',1,'ir_Daikin.h']]], + ['kdaikinstatelength_5066',['kDaikinStateLength',['../IRremoteESP8266_8h.html#af1fda5b9f355e526dc66cf58824315a7',1,'IRremoteESP8266.h']]], + ['kdaikinstatelengthshort_5067',['kDaikinStateLengthShort',['../IRremoteESP8266_8h.html#ae94c897cb0bd25ca7a4d693c7be9be3d',1,'IRremoteESP8266.h']]], + ['kdaikinswingoff_5068',['kDaikinSwingOff',['../ir__Daikin_8h.html#abc9194f48f63632b87c6139dd8ab6ecf',1,'ir_Daikin.h']]], + ['kdaikinswingoffset_5069',['kDaikinSwingOffset',['../ir__Daikin_8h.html#abeac0c8df9be90fc5b28db4b2284ed10',1,'ir_Daikin.h']]], + ['kdaikinswingon_5070',['kDaikinSwingOn',['../ir__Daikin_8h.html#af19ec29dc79837deca05f6061f2e6524',1,'ir_Daikin.h']]], + ['kdaikinswingsize_5071',['kDaikinSwingSize',['../ir__Daikin_8h.html#a0f7daf6ef2652bc0be591caa2fa0fad6',1,'ir_Daikin.h']]], + ['kdaikintempoffset_5072',['kDaikinTempOffset',['../ir__Daikin_8h.html#a1a38843bdf0f65f29c21b301f6f45ba5',1,'ir_Daikin.h']]], + ['kdaikintempsize_5073',['kDaikinTempSize',['../ir__Daikin_8h.html#aa2eef2bb403846d88df5387912af0a00',1,'ir_Daikin.h']]], + ['kdaikintolerance_5074',['kDaikinTolerance',['../ir__Daikin_8h.html#aea3938d1522df0040ddb9775075d6669',1,'ir_Daikin.h']]], + ['kdaikinunusedtime_5075',['kDaikinUnusedTime',['../ir__Daikin_8h.html#af60d27bb9d08317498b35f62c167f6a4',1,'ir_Daikin.h']]], + ['kdaikinzerospace_5076',['kDaikinZeroSpace',['../ir__Daikin_8h.html#ace5b2c2be3b58f22248eafb2148d059c',1,'ir_Daikin.h']]], + ['kdaysstr_5077',['kDaysStr',['../IRtext_8cpp.html#a4269111ae41c3a673ec0a87fca0fd78b',1,'kDaysStr(): IRtext.cpp'],['../IRtext_8h.html#aa779ae24412ef82ee3d1eade3f0381ae',1,'kDaysStr(): IRtext.cpp']]], + ['kdaystr_5078',['kDayStr',['../IRtext_8cpp.html#ab6fb8803c6a95d1926abb56b7ecb2e09',1,'kDayStr(): IRtext.cpp'],['../IRtext_8h.html#adb64531a5054629613696f9af39420e2',1,'kDayStr(): IRtext.cpp']]], + ['kdefaultesp32timer_5079',['kDefaultESP32Timer',['../IRrecv_8h.html#a80a2d3445a1752d18caf307d7677b709',1,'IRrecv.h']]], + ['kdefaultmessagegap_5080',['kDefaultMessageGap',['../IRsend_8h.html#ad49e9828319afbad49fd5082c50ef4a7',1,'IRsend.h']]], + ['kdelonghiacauto_5081',['kDelonghiAcAuto',['../ir__Delonghi_8h.html#ab10d4fe0b9dbe99ed942b73a6ff61d37',1,'ir_Delonghi.h']]], + ['kdelonghiacbitmark_5082',['kDelonghiAcBitMark',['../ir__Delonghi_8cpp.html#aa70f02d16b78f513e245871d4db0785a',1,'ir_Delonghi.cpp']]], + ['kdelonghiacbits_5083',['kDelonghiAcBits',['../IRremoteESP8266_8h.html#a7b9fba82b602cf38147f0586e037f909',1,'IRremoteESP8266.h']]], + ['kdelonghiacboostbit_5084',['kDelonghiAcBoostBit',['../ir__Delonghi_8h.html#a52c86741107eb5e33780f78fbf5667d5',1,'ir_Delonghi.h']]], + ['kdelonghiacchecksumoffset_5085',['kDelonghiAcChecksumOffset',['../ir__Delonghi_8h.html#a4b5e3d9874b016f60b7f9c26e7cf0cfd',1,'ir_Delonghi.h']]], + ['kdelonghiacchecksumsize_5086',['kDelonghiAcChecksumSize',['../ir__Delonghi_8h.html#a376acfc72923eccd3a1a9cc04453c0fc',1,'ir_Delonghi.h']]], + ['kdelonghiaccool_5087',['kDelonghiAcCool',['../ir__Delonghi_8h.html#a9447cc3a3f6f4e0603ecc99104523119',1,'ir_Delonghi.h']]], + ['kdelonghiacdefaultrepeat_5088',['kDelonghiAcDefaultRepeat',['../IRremoteESP8266_8h.html#a8f18256a0a6893e077e253e5e80da164',1,'IRremoteESP8266.h']]], + ['kdelonghiacdry_5089',['kDelonghiAcDry',['../ir__Delonghi_8h.html#a1c83f080ac1f48548fcfa5d691ef893d',1,'ir_Delonghi.h']]], + ['kdelonghiacfan_5090',['kDelonghiAcFan',['../ir__Delonghi_8h.html#af494534acfb8ae1c0f9c15bc13e2d0c8',1,'ir_Delonghi.h']]], + ['kdelonghiacfanauto_5091',['kDelonghiAcFanAuto',['../ir__Delonghi_8h.html#adf2286936d79d8c899283fa6e3838ebb',1,'ir_Delonghi.h']]], + ['kdelonghiacfanhigh_5092',['kDelonghiAcFanHigh',['../ir__Delonghi_8h.html#a03027eb1a6a382479b44db0699aee30b',1,'ir_Delonghi.h']]], + ['kdelonghiacfanlow_5093',['kDelonghiAcFanLow',['../ir__Delonghi_8h.html#a053a51021679cd5c4720e7ec68fa43eb',1,'ir_Delonghi.h']]], + ['kdelonghiacfanmedium_5094',['kDelonghiAcFanMedium',['../ir__Delonghi_8h.html#ac748c5e0b7c5acb108086f90c088028f',1,'ir_Delonghi.h']]], + ['kdelonghiacfanoffset_5095',['kDelonghiAcFanOffset',['../ir__Delonghi_8h.html#ab9ff55f2717de8401a940b6afd4c13d6',1,'ir_Delonghi.h']]], + ['kdelonghiacfansize_5096',['kDelonghiAcFanSize',['../ir__Delonghi_8h.html#adc3ed20ff78231b8ac2eb82481d3ebb2',1,'ir_Delonghi.h']]], + ['kdelonghiacfreq_5097',['kDelonghiAcFreq',['../ir__Delonghi_8cpp.html#a9425e4f71aa6454a89b55f3b5789d94d',1,'ir_Delonghi.cpp']]], + ['kdelonghiacgap_5098',['kDelonghiAcGap',['../ir__Delonghi_8cpp.html#ab1cd2481fc96811ed822c8c9f63420c3',1,'ir_Delonghi.cpp']]], + ['kdelonghiachdrmark_5099',['kDelonghiAcHdrMark',['../ir__Delonghi_8cpp.html#a0feead944883173788b8d02b7ae94ef8',1,'ir_Delonghi.cpp']]], + ['kdelonghiachdrspace_5100',['kDelonghiAcHdrSpace',['../ir__Delonghi_8cpp.html#a606ea96746b1b6471b1d76f05bdc7e5a',1,'ir_Delonghi.cpp']]], + ['kdelonghiachourssize_5101',['kDelonghiAcHoursSize',['../ir__Delonghi_8h.html#a94e0d6ed9ba66c467d9fb4467ab4e512',1,'ir_Delonghi.h']]], + ['kdelonghiacminssize_5102',['kDelonghiAcMinsSize',['../ir__Delonghi_8h.html#a91ed842a356878349760fe75f6d686b2',1,'ir_Delonghi.h']]], + ['kdelonghiacmodeoffset_5103',['kDelonghiAcModeOffset',['../ir__Delonghi_8h.html#a8044375ad833a12e56974b71ddfc2bc7',1,'ir_Delonghi.h']]], + ['kdelonghiacmodesize_5104',['kDelonghiAcModeSize',['../ir__Delonghi_8h.html#a30dc468cb735389aff3a27846e8a24f1',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerenablebit_5105',['kDelonghiAcOffTimerEnableBit',['../ir__Delonghi_8h.html#a93b8d905151be16f6d0918d6fd8d27e2',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerhoursoffset_5106',['kDelonghiAcOffTimerHoursOffset',['../ir__Delonghi_8h.html#a6d7b8115532bf01ae8c53b2ecbbf223b',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerminsoffset_5107',['kDelonghiAcOffTimerMinsOffset',['../ir__Delonghi_8h.html#a47b2f9c730c23d2c117141653622e04b',1,'ir_Delonghi.h']]], + ['kdelonghiaconespace_5108',['kDelonghiAcOneSpace',['../ir__Delonghi_8cpp.html#a8805fdc60cd3537ba2d94038610a3490',1,'ir_Delonghi.cpp']]], + ['kdelonghiacontimerenablebit_5109',['kDelonghiAcOnTimerEnableBit',['../ir__Delonghi_8h.html#a56d225e53ffcc29c486fce295ff3295b',1,'ir_Delonghi.h']]], + ['kdelonghiacontimerhoursoffset_5110',['kDelonghiAcOnTimerHoursOffset',['../ir__Delonghi_8h.html#a310b01f1ba238a8342261c01f77f0234',1,'ir_Delonghi.h']]], + ['kdelonghiacontimerminsoffset_5111',['kDelonghiAcOnTimerMinsOffset',['../ir__Delonghi_8h.html#a37d9a33640b64833daeb1ccc4e209be1',1,'ir_Delonghi.h']]], + ['kdelonghiacoverhead_5112',['kDelonghiAcOverhead',['../ir__Delonghi_8cpp.html#ac265c123c0cd7492d26f030d129f3475',1,'ir_Delonghi.cpp']]], + ['kdelonghiacpowerbit_5113',['kDelonghiAcPowerBit',['../ir__Delonghi_8h.html#ac89b7d74aaf3d4beaa21849085d2d7e3',1,'ir_Delonghi.h']]], + ['kdelonghiacsleepbit_5114',['kDelonghiAcSleepBit',['../ir__Delonghi_8h.html#aa1f75ea73bac50c6645625393b137391',1,'ir_Delonghi.h']]], + ['kdelonghiactempautodrymode_5115',['kDelonghiAcTempAutoDryMode',['../ir__Delonghi_8h.html#add6f728d2746a089e00a35644d664a6c',1,'ir_Delonghi.h']]], + ['kdelonghiactempfanmode_5116',['kDelonghiAcTempFanMode',['../ir__Delonghi_8h.html#a120ae31fac35c33214317c3187aae15c',1,'ir_Delonghi.h']]], + ['kdelonghiactempmaxc_5117',['kDelonghiAcTempMaxC',['../ir__Delonghi_8h.html#a476922b8d240c46cf092897f6c701e87',1,'ir_Delonghi.h']]], + ['kdelonghiactempmaxf_5118',['kDelonghiAcTempMaxF',['../ir__Delonghi_8h.html#abc11f81bc221aa3789258b7a990633b3',1,'ir_Delonghi.h']]], + ['kdelonghiactempminc_5119',['kDelonghiAcTempMinC',['../ir__Delonghi_8h.html#ad31267284f7dd8f533fc978ed7e92428',1,'ir_Delonghi.h']]], + ['kdelonghiactempminf_5120',['kDelonghiAcTempMinF',['../ir__Delonghi_8h.html#a0311abab5eff5a8c47261db8e3d40ed5',1,'ir_Delonghi.h']]], + ['kdelonghiactempoffset_5121',['kDelonghiAcTempOffset',['../ir__Delonghi_8h.html#a9d02f6520d6d1d7e305ea651099cc9ef',1,'ir_Delonghi.h']]], + ['kdelonghiactempsize_5122',['kDelonghiAcTempSize',['../ir__Delonghi_8h.html#a3fb467e0d2385893c8c7a8daa0505ec1',1,'ir_Delonghi.h']]], + ['kdelonghiactempunitbit_5123',['kDelonghiAcTempUnitBit',['../ir__Delonghi_8h.html#ac9e6f419569558f4bd5f5a6e10d24bb6',1,'ir_Delonghi.h']]], + ['kdelonghiactimermax_5124',['kDelonghiAcTimerMax',['../ir__Delonghi_8h.html#a44d3f0d850c5cd5ad8c0e2dc7c2bd860',1,'ir_Delonghi.h']]], + ['kdelonghiaczerospace_5125',['kDelonghiAcZeroSpace',['../ir__Delonghi_8cpp.html#a4c1a9a70a50c7da9aa6cf91af85c695e',1,'ir_Delonghi.cpp']]], + ['kdenon48bits_5126',['kDenon48Bits',['../IRremoteESP8266_8h.html#ad7389b5b4f01a16dbf940eaae005c805',1,'IRremoteESP8266.h']]], + ['kdenonbitmark_5127',['kDenonBitMark',['../ir__Denon_8cpp.html#a1cd978061cfdc9bf1d5e1142dad86e59',1,'ir_Denon.cpp']]], + ['kdenonbitmarkticks_5128',['kDenonBitMarkTicks',['../ir__Denon_8cpp.html#ae6dddc89296abc186ac524c3f1efbe63',1,'ir_Denon.cpp']]], + ['kdenonbits_5129',['kDenonBits',['../IRremoteESP8266_8h.html#a29160117e25f3dfc1cb899a4a53bc238',1,'IRremoteESP8266.h']]], + ['kdenonhdrmark_5130',['kDenonHdrMark',['../ir__Denon_8cpp.html#a6f7b5da8c723615200109f425df72254',1,'ir_Denon.cpp']]], + ['kdenonhdrmarkticks_5131',['kDenonHdrMarkTicks',['../ir__Denon_8cpp.html#a484a90cdd15de164c931f1c70ab02938',1,'ir_Denon.cpp']]], + ['kdenonhdrspace_5132',['kDenonHdrSpace',['../ir__Denon_8cpp.html#a758b11259a5dcab3e949739cf67106be',1,'ir_Denon.cpp']]], + ['kdenonhdrspaceticks_5133',['kDenonHdrSpaceTicks',['../ir__Denon_8cpp.html#afe6cb1be37dcea0251ebf0fc43640fe1',1,'ir_Denon.cpp']]], + ['kdenonlegacybits_5134',['kDenonLegacyBits',['../IRremoteESP8266_8h.html#aacf2eea1349016ccbc96e97a0976f4ec',1,'IRremoteESP8266.h']]], + ['kdenonmanufacturer_5135',['kDenonManufacturer',['../ir__Denon_8cpp.html#abd89138765e21d25991fd5857506491b',1,'ir_Denon.cpp']]], + ['kdenonmincommandlengthticks_5136',['kDenonMinCommandLengthTicks',['../ir__Denon_8cpp.html#abb20f9f6053e0d46399011de71697a6a',1,'ir_Denon.cpp']]], + ['kdenonmingap_5137',['kDenonMinGap',['../ir__Denon_8cpp.html#a19b3fe79e06b3ece2cb167d5e14b2c11',1,'ir_Denon.cpp']]], + ['kdenonmingapticks_5138',['kDenonMinGapTicks',['../ir__Denon_8cpp.html#a191e0cfcf8167805ef9bfdc05463c313',1,'ir_Denon.cpp']]], + ['kdenononespace_5139',['kDenonOneSpace',['../ir__Denon_8cpp.html#a150b22eeeb64b59a3d9df51904fdda3f',1,'ir_Denon.cpp']]], + ['kdenononespaceticks_5140',['kDenonOneSpaceTicks',['../ir__Denon_8cpp.html#ad15a88b8f6b953918799eac1e814d107',1,'ir_Denon.cpp']]], + ['kdenontick_5141',['kDenonTick',['../ir__Denon_8cpp.html#a6cc0eba04ca4a2362068bf47d1869752',1,'ir_Denon.cpp']]], + ['kdenonzerospace_5142',['kDenonZeroSpace',['../ir__Denon_8cpp.html#ad8f53f000727e66938d086eadb5bf6eb',1,'ir_Denon.cpp']]], + ['kdenonzerospaceticks_5143',['kDenonZeroSpaceTicks',['../ir__Denon_8cpp.html#aed0c86367586cd043d8381499b3a4bdd',1,'ir_Denon.cpp']]], + ['kdishbitmark_5144',['kDishBitMark',['../ir__Dish_8cpp.html#aabe7f9815a2f5e65558b0f482e2ac50e',1,'ir_Dish.cpp']]], + ['kdishbitmarkticks_5145',['kDishBitMarkTicks',['../ir__Dish_8cpp.html#a1cfd9b730c78aac35f6c2cb56367c7bb',1,'ir_Dish.cpp']]], + ['kdishbits_5146',['kDishBits',['../IRremoteESP8266_8h.html#aea0cc15e1c7a6edcd6b60d9ac62d4831',1,'IRremoteESP8266.h']]], + ['kdishhdrmark_5147',['kDishHdrMark',['../ir__Dish_8cpp.html#ac4311aaed27b1f37a41a2a9cced0ecc5',1,'ir_Dish.cpp']]], + ['kdishhdrmarkticks_5148',['kDishHdrMarkTicks',['../ir__Dish_8cpp.html#a8dce19ee6e3a6859bd2d43c0c9e90517',1,'ir_Dish.cpp']]], + ['kdishhdrspace_5149',['kDishHdrSpace',['../ir__Dish_8cpp.html#ac68dfa9e554c919fd51b379621b2fbc4',1,'ir_Dish.cpp']]], + ['kdishhdrspaceticks_5150',['kDishHdrSpaceTicks',['../ir__Dish_8cpp.html#ab212535e169722d7f23b461b011400c2',1,'ir_Dish.cpp']]], + ['kdishminrepeat_5151',['kDishMinRepeat',['../IRremoteESP8266_8h.html#a5c2263819b032e3af4d416ab41126bd8',1,'IRremoteESP8266.h']]], + ['kdishonespace_5152',['kDishOneSpace',['../ir__Dish_8cpp.html#a6f1986377a4571c8eba5f401b772c194',1,'ir_Dish.cpp']]], + ['kdishonespaceticks_5153',['kDishOneSpaceTicks',['../ir__Dish_8cpp.html#ade25414e4747c56303752060d9f89446',1,'ir_Dish.cpp']]], + ['kdishrptspace_5154',['kDishRptSpace',['../ir__Dish_8cpp.html#a67628a3581fe85638f72711581ec0e42',1,'ir_Dish.cpp']]], + ['kdishrptspaceticks_5155',['kDishRptSpaceTicks',['../ir__Dish_8cpp.html#a801af68fd07720f74abcf2712e3228dd',1,'ir_Dish.cpp']]], + ['kdishtick_5156',['kDishTick',['../ir__Dish_8cpp.html#aa1eccae3b18a457c7cec248d483e808a',1,'ir_Dish.cpp']]], + ['kdishzerospace_5157',['kDishZeroSpace',['../ir__Dish_8cpp.html#acde5c5a789af871f7b5aacdf3f0efeb7',1,'ir_Dish.cpp']]], + ['kdishzerospaceticks_5158',['kDishZeroSpaceTicks',['../ir__Dish_8cpp.html#a68a0f2b9e2e457c8a58fa533e0ca5336',1,'ir_Dish.cpp']]], + ['kdisplaytempstr_5159',['kDisplayTempStr',['../IRtext_8cpp.html#a018814e961b4eb51b91680db3be7d17c',1,'kDisplayTempStr(): IRtext.cpp'],['../IRtext_8h.html#a98f3ba92617c82c9091f155eebcdb3f3',1,'kDisplayTempStr(): IRtext.cpp']]], + ['kdoshishabitmark_5160',['kDoshishaBitMark',['../ir__Doshisha_8cpp.html#a50a4feaff92c4a9fbba6128638fdb2fb',1,'ir_Doshisha.cpp']]], + ['kdoshishabits_5161',['kDoshishaBits',['../IRremoteESP8266_8h.html#aedc53534cf6a40144be80abeee498362',1,'IRremoteESP8266.h']]], + ['kdoshishahdrmark_5162',['kDoshishaHdrMark',['../ir__Doshisha_8cpp.html#adbfc15a1abb62540538afc9c645c1875',1,'ir_Doshisha.cpp']]], + ['kdoshishahdrspace_5163',['kDoshishaHdrSpace',['../ir__Doshisha_8cpp.html#a95a58b09fde0ee9ba59fcf838d16f736',1,'ir_Doshisha.cpp']]], + ['kdoshishaonespace_5164',['kDoshishaOneSpace',['../ir__Doshisha_8cpp.html#a48f3b70ddd3bc06c628ebe7ce29e74d3',1,'ir_Doshisha.cpp']]], + ['kdoshishazerospace_5165',['kDoshishaZeroSpace',['../ir__Doshisha_8cpp.html#a055ae27320600bc7e100ea7e147775f9',1,'ir_Doshisha.cpp']]], + ['kdownstr_5166',['kDownStr',['../IRtext_8cpp.html#a24998688cbbe54780843983394e925e5',1,'kDownStr(): IRtext.cpp'],['../IRtext_8h.html#a1f452a2ac1a2b89b9c71cf64c177f6bd',1,'kDownStr(): IRtext.cpp']]], + ['kdrystr_5167',['kDryStr',['../IRtext_8cpp.html#a149780a7bbdd13757ee4336c281ccd9d',1,'kDryStr(): IRtext.cpp'],['../IRtext_8h.html#aa0f25fa3aa8d26f4635c38e563a974f5',1,'kDryStr(): IRtext.cpp']]], + ['kdutydefault_5168',['kDutyDefault',['../IRsend_8h.html#affa33c170fe058b783372852fca7cc5b',1,'IRsend.h']]], + ['kdutymax_5169',['kDutyMax',['../IRsend_8h.html#ac076e3f79a3d8d2dae9fc248a6f571e2',1,'IRsend.h']]], + ['keconostr_5170',['kEconoStr',['../IRtext_8cpp.html#a4e3bee67564fe8f13d1d4f997924f464',1,'kEconoStr(): IRtext.cpp'],['../IRtext_8h.html#ab0b71c4429416a581a393f07e898bade',1,'kEconoStr(): IRtext.cpp']]], + ['kelectraacauto_5171',['kElectraAcAuto',['../ir__Electra_8h.html#a536965f5003a474d68860005883afb5a',1,'ir_Electra.h']]], + ['kelectraacbitmark_5172',['kElectraAcBitMark',['../ir__Electra_8cpp.html#a41f7254b061b099b8131ec4d2a775116',1,'ir_Electra.cpp']]], + ['kelectraacbits_5173',['kElectraAcBits',['../IRremoteESP8266_8h.html#aa46876681f26ccf39c6d341fef041a16',1,'IRremoteESP8266.h']]], + ['kelectraaccleanoffset_5174',['kElectraAcCleanOffset',['../ir__Electra_8h.html#a466b5c998c1e2736214f816f1bab8239',1,'ir_Electra.h']]], + ['kelectraaccool_5175',['kElectraAcCool',['../ir__Electra_8h.html#a6a37f4e24aad54a982994599a1bca59d',1,'ir_Electra.h']]], + ['kelectraacdry_5176',['kElectraAcDry',['../ir__Electra_8h.html#a9b8636631c22e003072bf84a9e30ddff',1,'ir_Electra.h']]], + ['kelectraacfan_5177',['kElectraAcFan',['../ir__Electra_8h.html#a28047c7d083d8bc9d9e34ab210c28185',1,'ir_Electra.h']]], + ['kelectraacfanauto_5178',['kElectraAcFanAuto',['../ir__Electra_8h.html#a48b3067393d4dc1e3461db4535212bff',1,'ir_Electra.h']]], + ['kelectraacfanhigh_5179',['kElectraAcFanHigh',['../ir__Electra_8h.html#a5cbf3118669f056f377b4625e8e97d8c',1,'ir_Electra.h']]], + ['kelectraacfanlow_5180',['kElectraAcFanLow',['../ir__Electra_8h.html#a9a5663e86cb766a4e4579d1b81473c44',1,'ir_Electra.h']]], + ['kelectraacfanmed_5181',['kElectraAcFanMed',['../ir__Electra_8h.html#a4e906bcb7aa6c0fc5c71bd06c43c3993',1,'ir_Electra.h']]], + ['kelectraacfanoffset_5182',['kElectraAcFanOffset',['../ir__Electra_8h.html#a0efe73807b12370aa7c57ff831e56192',1,'ir_Electra.h']]], + ['kelectraacfansize_5183',['kElectraAcFanSize',['../ir__Electra_8h.html#aeb9bddbd47459ae51c1207baac9e6219',1,'ir_Electra.h']]], + ['kelectraachdrmark_5184',['kElectraAcHdrMark',['../ir__Electra_8cpp.html#a1200826684547765f1e526f362408e2e',1,'ir_Electra.cpp']]], + ['kelectraachdrspace_5185',['kElectraAcHdrSpace',['../ir__Electra_8cpp.html#a28cd57057c52b0def3683e71ee92c5d3',1,'ir_Electra.cpp']]], + ['kelectraacheat_5186',['kElectraAcHeat',['../ir__Electra_8h.html#af764a4738f146b752b8e29357af257e3',1,'ir_Electra.h']]], + ['kelectraaclighttogglemask_5187',['kElectraAcLightToggleMask',['../ir__Electra_8h.html#aa51ccef46052dd988ac1bccc4f2303f6',1,'ir_Electra.h']]], + ['kelectraaclighttoggleoff_5188',['kElectraAcLightToggleOff',['../ir__Electra_8h.html#ae98c4a00f003cc98c253b9367226c5c5',1,'ir_Electra.h']]], + ['kelectraaclighttoggleon_5189',['kElectraAcLightToggleOn',['../ir__Electra_8h.html#aa9ca231e98b7e529b081c3aaa1876df9',1,'ir_Electra.h']]], + ['kelectraacmaxtemp_5190',['kElectraAcMaxTemp',['../ir__Electra_8h.html#a3962ca1ae42f006baa1181683cbcbf86',1,'ir_Electra.h']]], + ['kelectraacmessagegap_5191',['kElectraAcMessageGap',['../ir__Electra_8cpp.html#adbcde2296ebf6ea93c7c95ce6d0b264e',1,'ir_Electra.cpp']]], + ['kelectraacminrepeat_5192',['kElectraAcMinRepeat',['../IRremoteESP8266_8h.html#a2ca237d578ca9a59aecac9813ab851ba',1,'IRremoteESP8266.h']]], + ['kelectraacmintemp_5193',['kElectraAcMinTemp',['../ir__Electra_8h.html#ad6f62477d70b59c958ba347c228f8e2b',1,'ir_Electra.h']]], + ['kelectraacmodeoffset_5194',['kElectraAcModeOffset',['../ir__Electra_8h.html#a79ea9dfa776115e5ec4ee816c4eef559',1,'ir_Electra.h']]], + ['kelectraaconespace_5195',['kElectraAcOneSpace',['../ir__Electra_8cpp.html#aeb59d520635a93f5dd7acdbe4327174d',1,'ir_Electra.cpp']]], + ['kelectraacpoweroffset_5196',['kElectraAcPowerOffset',['../ir__Electra_8h.html#a54012f7683397fada44f13c3e57d9ee0',1,'ir_Electra.h']]], + ['kelectraacstatelength_5197',['kElectraAcStateLength',['../IRremoteESP8266_8h.html#a8fb8c5778feaa94114218c36e8e43641',1,'IRremoteESP8266.h']]], + ['kelectraacswinghoffset_5198',['kElectraAcSwingHOffset',['../ir__Electra_8h.html#ac39219316f9b49ead4183cd206b4a3fb',1,'ir_Electra.h']]], + ['kelectraacswingoff_5199',['kElectraAcSwingOff',['../ir__Electra_8h.html#ade2211d0bd695daf490300db856d660a',1,'ir_Electra.h']]], + ['kelectraacswingon_5200',['kElectraAcSwingOn',['../ir__Electra_8h.html#a4ef75911d929752357d727aee339563e',1,'ir_Electra.h']]], + ['kelectraacswingsize_5201',['kElectraAcSwingSize',['../ir__Electra_8h.html#a67c58c049b50d04d4fadd93eee0231cf',1,'ir_Electra.h']]], + ['kelectraacswingvoffset_5202',['kElectraAcSwingVOffset',['../ir__Electra_8h.html#a4a5737e41994fe6c0cd566be354a70fb',1,'ir_Electra.h']]], + ['kelectraactempdelta_5203',['kElectraAcTempDelta',['../ir__Electra_8h.html#ac3310f7b0d4b9fbe22d7192465669487',1,'ir_Electra.h']]], + ['kelectraactempoffset_5204',['kElectraAcTempOffset',['../ir__Electra_8h.html#a928ee72169f9ab56a4209606aa7e5e43',1,'ir_Electra.h']]], + ['kelectraactempsize_5205',['kElectraAcTempSize',['../ir__Electra_8h.html#aeeb469144f4fd02ddd8a802f5cf7c308',1,'ir_Electra.h']]], + ['kelectraacturbooffset_5206',['kElectraAcTurboOffset',['../ir__Electra_8h.html#afbbd997ef8ddf5a4adfd0a37404d6782',1,'ir_Electra.h']]], + ['kelectraaczerospace_5207',['kElectraAcZeroSpace',['../ir__Electra_8cpp.html#a1453e0796cfe6ca169fd3c56e2595082',1,'ir_Electra.cpp']]], + ['kepsonbits_5208',['kEpsonBits',['../IRremoteESP8266_8h.html#a77a0ed1143f5bfec87e0c9fde5c2c425',1,'IRremoteESP8266.h']]], + ['kepsonminrepeat_5209',['kEpsonMinRepeat',['../IRremoteESP8266_8h.html#ac8738cb054de937b77269acb973c5133',1,'IRremoteESP8266.h']]], + ['keyeautostr_5210',['kEyeAutoStr',['../IRtext_8cpp.html#ab7c525442638022439c7a277e1edf694',1,'kEyeAutoStr(): IRtext.cpp'],['../IRtext_8h.html#ae1395c08682a2b858261d76b97311f4f',1,'kEyeAutoStr(): IRtext.cpp']]], + ['keyestr_5211',['kEyeStr',['../IRtext_8cpp.html#a1d8dc83e7f15aacd013509e36a49a9d8',1,'kEyeStr(): IRtext.cpp'],['../IRtext_8h.html#a84f6d62456976cc31fe6b1648182a885',1,'kEyeStr(): IRtext.cpp']]], + ['kfalsestr_5212',['kFalseStr',['../IRtext_8cpp.html#a338ee31c8fb5a1c74c0640b279051cd2',1,'kFalseStr(): IRtext.cpp'],['../IRtext_8h.html#a3dc9321c4146369e0e0794e6a4de1988',1,'kFalseStr(): IRtext.cpp']]], + ['kfanonlystr_5213',['kFanOnlyStr',['../IRtext_8cpp.html#adada7550fa28466a6db6f4544f8c7063',1,'kFanOnlyStr(): IRtext.cpp'],['../IRtext_8h.html#a220378c7b69db06362af5ad932965628',1,'kFanOnlyStr(): IRtext.cpp']]], + ['kfanstr_5214',['kFanStr',['../IRtext_8cpp.html#aaab703dfae684a786852a55c0f7f61ec',1,'kFanStr(): IRtext.cpp'],['../IRtext_8h.html#af7a0d76c40f3173a3e1367665d789300',1,'kFanStr(): IRtext.cpp']]], + ['kfaststr_5215',['kFastStr',['../IRtext_8cpp.html#ad6084cb569cd62bb1199c6ecc8ac4126',1,'kFastStr(): IRtext.cpp'],['../IRtext_8h.html#a82c26d9c7690ce001223e2a7cf8664d8',1,'kFastStr(): IRtext.cpp']]], + ['kfilterstr_5216',['kFilterStr',['../IRtext_8cpp.html#af287ead64de5dc3b1cbafe7bc945e519',1,'kFilterStr(): IRtext.cpp'],['../IRtext_8h.html#a5b3133e24c729077da411e08119033be',1,'kFilterStr(): IRtext.cpp']]], + ['kfixedstr_5217',['kFixedStr',['../IRtext_8cpp.html#ab45f91a889dae134e48c86586608bfc9',1,'kFixedStr(): IRtext.cpp'],['../IRtext_8h.html#ad9112f221a20ab498c5f133c4cea0b14',1,'kFixedStr(): IRtext.cpp']]], + ['kfnvbasis32_5218',['kFnvBasis32',['../IRrecv_8h.html#a04d9b0c909b377b36af3ece668482ca3',1,'IRrecv.h']]], + ['kfnvprime32_5219',['kFnvPrime32',['../IRrecv_8h.html#abcfcce36d3e2faef742aa3529c22f23f',1,'IRrecv.h']]], + ['kfollowstr_5220',['kFollowStr',['../IRtext_8cpp.html#a5477068666c86b3d605df8cf0240c86f',1,'kFollowStr(): IRtext.cpp'],['../IRtext_8h.html#a47a659e1c6373c4af92f4261148f695b',1,'kFollowStr(): IRtext.cpp']]], + ['kfooter_5221',['kFooter',['../IRrecv_8h.html#a5abb2b821f207ee9cf35f889f86d0ea3',1,'IRrecv.h']]], + ['kfreshstr_5222',['kFreshStr',['../IRtext_8cpp.html#ae416979803b912c932aa5eda837fc471',1,'kFreshStr(): IRtext.cpp'],['../IRtext_8h.html#adc8991e424df3ebf2f47ffc2854057f2',1,'kFreshStr(): IRtext.cpp']]], + ['kfujitsuacbitmark_5223',['kFujitsuAcBitMark',['../ir__Fujitsu_8cpp.html#a2e01906b1317da42fcc204284646e3db',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacbits_5224',['kFujitsuAcBits',['../IRremoteESP8266_8h.html#aecd63891cac014d1b7e344638086ad47',1,'IRremoteESP8266.h']]], + ['kfujitsuaccleanoffset_5225',['kFujitsuAcCleanOffset',['../ir__Fujitsu_8h.html#ae7e7dc770ef9712296d2beeb085d2c1f',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdecono_5226',['kFujitsuAcCmdEcono',['../ir__Fujitsu_8h.html#a1e1eb4274232c43769f70b40f395a084',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdpowerful_5227',['kFujitsuAcCmdPowerful',['../ir__Fujitsu_8h.html#a69349537a37674a82b8ca630e6ca1b5a',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstayon_5228',['kFujitsuAcCmdStayOn',['../ir__Fujitsu_8h.html#acc729a2cd570761f97c63b98024c157d',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstephoriz_5229',['kFujitsuAcCmdStepHoriz',['../ir__Fujitsu_8h.html#ac67e3fa9ab8f1e1146bed1296f9a2131',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstepvert_5230',['kFujitsuAcCmdStepVert',['../ir__Fujitsu_8h.html#a5dda60d753d93089fc323bfcd9567afd',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdtoggleswinghoriz_5231',['kFujitsuAcCmdToggleSwingHoriz',['../ir__Fujitsu_8h.html#a43b5912e65a8e6d3f1c672b155135f27',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdtoggleswingvert_5232',['kFujitsuAcCmdToggleSwingVert',['../ir__Fujitsu_8h.html#a66960882cee5d109f332917fe1f8067c',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdturnoff_5233',['kFujitsuAcCmdTurnOff',['../ir__Fujitsu_8h.html#a073903b56c40d89b9999ee9b7dc48f00',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdturnon_5234',['kFujitsuAcCmdTurnOn',['../ir__Fujitsu_8h.html#a51c2abda78c7d6ced59f88acb857281e',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanauto_5235',['kFujitsuAcFanAuto',['../ir__Fujitsu_8h.html#a55bbb5a5b1760515f070d302c9fa4cbb',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanhigh_5236',['kFujitsuAcFanHigh',['../ir__Fujitsu_8h.html#a30b11ea24865a00b10468015aae77886',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanlow_5237',['kFujitsuAcFanLow',['../ir__Fujitsu_8h.html#aa0162cde862a3c02dd877a3a7933c130',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanmed_5238',['kFujitsuAcFanMed',['../ir__Fujitsu_8h.html#a0efcb8e8a6521e4788a82ff6c556b67b',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanquiet_5239',['kFujitsuAcFanQuiet',['../ir__Fujitsu_8h.html#a9abb4ec5fe9f27c6acd62273329490b6',1,'ir_Fujitsu.h']]], + ['kfujitsuacfansize_5240',['kFujitsuAcFanSize',['../ir__Fujitsu_8h.html#a797e68082ceebea788a215ecbfc279d9',1,'ir_Fujitsu.h']]], + ['kfujitsuacfilteroffset_5241',['kFujitsuAcFilterOffset',['../ir__Fujitsu_8h.html#a3c6349b24651bffb33f2633d3c65144c',1,'ir_Fujitsu.h']]], + ['kfujitsuachdrmark_5242',['kFujitsuAcHdrMark',['../ir__Fujitsu_8cpp.html#a96402e0aed6962a8a72cc736fa9bbc08',1,'ir_Fujitsu.cpp']]], + ['kfujitsuachdrspace_5243',['kFujitsuAcHdrSpace',['../ir__Fujitsu_8cpp.html#a655e37e172ab06dc06ca69f3c06223b2',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacmaxtemp_5244',['kFujitsuAcMaxTemp',['../ir__Fujitsu_8h.html#ad817f46441ac1284e3bbe8417e4f4388',1,'ir_Fujitsu.h']]], + ['kfujitsuacminbits_5245',['kFujitsuAcMinBits',['../IRremoteESP8266_8h.html#a025caa6d0ae6becdd5ee58b5ac6ed61f',1,'IRremoteESP8266.h']]], + ['kfujitsuacmingap_5246',['kFujitsuAcMinGap',['../ir__Fujitsu_8cpp.html#a255fab3b9047b34cf6c4d42c0c82c485',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacminrepeat_5247',['kFujitsuAcMinRepeat',['../IRremoteESP8266_8h.html#a9dd52420366167afb4c8831b4ccd02fa',1,'IRremoteESP8266.h']]], + ['kfujitsuacmintemp_5248',['kFujitsuAcMinTemp',['../ir__Fujitsu_8h.html#a35ec9572b356a7bcfb75947d03b198f7',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodeauto_5249',['kFujitsuAcModeAuto',['../ir__Fujitsu_8h.html#acf0aa6d1d033c893a3acd5b8d7756a5b',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodecool_5250',['kFujitsuAcModeCool',['../ir__Fujitsu_8h.html#a782e226fadab0a256144821cacea2314',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodedry_5251',['kFujitsuAcModeDry',['../ir__Fujitsu_8h.html#ae66f2ed2e554a6befdf0377d01bce257',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodefan_5252',['kFujitsuAcModeFan',['../ir__Fujitsu_8h.html#a7cc07ec4747b5cebc50257ec02297800',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodeheat_5253',['kFujitsuAcModeHeat',['../ir__Fujitsu_8h.html#ad9b47b7419853a4cb1cf072023dac69b',1,'ir_Fujitsu.h']]], + ['kfujitsuaconespace_5254',['kFujitsuAcOneSpace',['../ir__Fujitsu_8cpp.html#a4f5246e6428cc701dbaa18923904713a',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacoutsidequietoffset_5255',['kFujitsuAcOutsideQuietOffset',['../ir__Fujitsu_8h.html#a38522dc07bb7be2dd1ec654d4e60eb4f',1,'ir_Fujitsu.h']]], + ['kfujitsuacstatelength_5256',['kFujitsuAcStateLength',['../IRremoteESP8266_8h.html#ac3aa33a8386f73de0f57fc1ff7c6e7d9',1,'IRremoteESP8266.h']]], + ['kfujitsuacstatelengthshort_5257',['kFujitsuAcStateLengthShort',['../IRremoteESP8266_8h.html#a81cb09663eedbdc3888ee68438f0a5d3',1,'IRremoteESP8266.h']]], + ['kfujitsuacswingboth_5258',['kFujitsuAcSwingBoth',['../ir__Fujitsu_8h.html#a07c5a757b0c3bbe07412813807272434',1,'ir_Fujitsu.h']]], + ['kfujitsuacswinghoriz_5259',['kFujitsuAcSwingHoriz',['../ir__Fujitsu_8h.html#a8875f62d61afb8cbf468207aedcb8982',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingoff_5260',['kFujitsuAcSwingOff',['../ir__Fujitsu_8h.html#a7f8109a1b8fd13a93d6b0255d05413df',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingsize_5261',['kFujitsuAcSwingSize',['../ir__Fujitsu_8h.html#a1eb20884dc6c9bccbe899f779c4b5ad4',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingvert_5262',['kFujitsuAcSwingVert',['../ir__Fujitsu_8h.html#a5c532a43ab11bf7cb353de2081260f40',1,'ir_Fujitsu.h']]], + ['kfujitsuaczerospace_5263',['kFujitsuAcZeroSpace',['../ir__Fujitsu_8cpp.html#a3815b89a2037cd0c8d774217df603d6e',1,'ir_Fujitsu.cpp']]], + ['kgicablebitmark_5264',['kGicableBitMark',['../ir__GICable_8cpp.html#ac315be0b5e02fb4c7109a6f67c4fac8e',1,'ir_GICable.cpp']]], + ['kgicablebits_5265',['kGicableBits',['../IRremoteESP8266_8h.html#aceb5cbd7ba5d8bc11560ba29137b10fa',1,'IRremoteESP8266.h']]], + ['kgicablehdrmark_5266',['kGicableHdrMark',['../ir__GICable_8cpp.html#a0388e7a2030246928029ed1c79ba819d',1,'ir_GICable.cpp']]], + ['kgicablehdrspace_5267',['kGicableHdrSpace',['../ir__GICable_8cpp.html#ab357b0a095155eab6206245008387fc0',1,'ir_GICable.cpp']]], + ['kgicablemincommandlength_5268',['kGicableMinCommandLength',['../ir__GICable_8cpp.html#a79db5de95ff6b42259f0a54fa59f46f6',1,'ir_GICable.cpp']]], + ['kgicablemingap_5269',['kGicableMinGap',['../ir__GICable_8cpp.html#aff7027ab4b933e4a7f5506590c25f699',1,'ir_GICable.cpp']]], + ['kgicableminrepeat_5270',['kGicableMinRepeat',['../IRremoteESP8266_8h.html#ad8142649290db6fc337ac839d4078aef',1,'IRremoteESP8266.h']]], + ['kgicableonespace_5271',['kGicableOneSpace',['../ir__GICable_8cpp.html#a31300a6f41363cbc22d40f26e693b8be',1,'ir_GICable.cpp']]], + ['kgicablerptspace_5272',['kGicableRptSpace',['../ir__GICable_8cpp.html#a9e0d82ed05e210dec2980a7d1a2e081b',1,'ir_GICable.cpp']]], + ['kgicablezerospace_5273',['kGicableZeroSpace',['../ir__GICable_8cpp.html#a1383f274e701ad5c8141beb7703783ff',1,'ir_GICable.cpp']]], + ['kglobalcachefreqindex_5274',['kGlobalCacheFreqIndex',['../ir__GlobalCache_8cpp.html#aaa0bdfe1eb76e8519a111b6588a5a3ff',1,'ir_GlobalCache.cpp']]], + ['kglobalcachemaxrepeat_5275',['kGlobalCacheMaxRepeat',['../ir__GlobalCache_8cpp.html#ae4a19c45ab538e8a386769cd98943a0d',1,'ir_GlobalCache.cpp']]], + ['kglobalcacheminusec_5276',['kGlobalCacheMinUsec',['../ir__GlobalCache_8cpp.html#a133cf089a7b40516fac3b1143981b2a6',1,'ir_GlobalCache.cpp']]], + ['kglobalcacherptindex_5277',['kGlobalCacheRptIndex',['../ir__GlobalCache_8cpp.html#ad4d55ed7e89cfc6d513dae6ecb211fe9',1,'ir_GlobalCache.cpp']]], + ['kglobalcacherptstartindex_5278',['kGlobalCacheRptStartIndex',['../ir__GlobalCache_8cpp.html#afde4c65e9e75558df6ac7aa479bf507a',1,'ir_GlobalCache.cpp']]], + ['kglobalcachestartindex_5279',['kGlobalCacheStartIndex',['../ir__GlobalCache_8cpp.html#a8640be7a67ce3f49452b28bc24912637',1,'ir_GlobalCache.cpp']]], + ['kgoodweatherauto_5280',['kGoodweatherAuto',['../ir__Goodweather_8h.html#a2fc5f0f7d0f68dcff193548830f50528',1,'ir_Goodweather.h']]], + ['kgoodweatherbitairflow_5281',['kGoodweatherBitAirFlow',['../ir__Goodweather_8h.html#ad86cdbc34a6a82c7595cace56d040d64',1,'ir_Goodweather.h']]], + ['kgoodweatherbitcommand_5282',['kGoodweatherBitCommand',['../ir__Goodweather_8h.html#ad6973bf4ac7801097077938e133b1718',1,'ir_Goodweather.h']]], + ['kgoodweatherbiteof_5283',['kGoodweatherBitEOF',['../ir__Goodweather_8h.html#a239d4d1fee77e0d220efb0bc0b3c779a',1,'ir_Goodweather.h']]], + ['kgoodweatherbitfan_5284',['kGoodweatherBitFan',['../ir__Goodweather_8h.html#aa3d5f146109dd671e4d7d86c1dbccba7',1,'ir_Goodweather.h']]], + ['kgoodweatherbitlight_5285',['kGoodweatherBitLight',['../ir__Goodweather_8h.html#a976dc2b37d1fcec4bbc0958861b5a9b0',1,'ir_Goodweather.h']]], + ['kgoodweatherbitmark_5286',['kGoodweatherBitMark',['../ir__Goodweather_8h.html#acb9fb47b2a207997fda0244d1bafbe89',1,'ir_Goodweather.h']]], + ['kgoodweatherbitmode_5287',['kGoodweatherBitMode',['../ir__Goodweather_8h.html#a3795b45c06f6d2db23cc45478bfeeca9',1,'ir_Goodweather.h']]], + ['kgoodweatherbitpower_5288',['kGoodweatherBitPower',['../ir__Goodweather_8h.html#a652b820b22c8381a6035fea7b1ae1b8d',1,'ir_Goodweather.h']]], + ['kgoodweatherbits_5289',['kGoodweatherBits',['../IRremoteESP8266_8h.html#afa2675ce42d00175ec95caa6cd87a425',1,'IRremoteESP8266.h']]], + ['kgoodweatherbitsleep_5290',['kGoodweatherBitSleep',['../ir__Goodweather_8h.html#a763e8033483516c093ad12a378e0c8f8',1,'ir_Goodweather.h']]], + ['kgoodweatherbitswing_5291',['kGoodweatherBitSwing',['../ir__Goodweather_8h.html#a0a3fc264b6a77157174c207688ac2cda',1,'ir_Goodweather.h']]], + ['kgoodweatherbittemp_5292',['kGoodweatherBitTemp',['../ir__Goodweather_8h.html#a692faf9976f90d67d183ff99ed06ee51',1,'ir_Goodweather.h']]], + ['kgoodweatherbitturbo_5293',['kGoodweatherBitTurbo',['../ir__Goodweather_8h.html#afe2ad22bc8ba5ab9cad025e9adaf4d56',1,'ir_Goodweather.h']]], + ['kgoodweathercmdairflow_5294',['kGoodweatherCmdAirFlow',['../ir__Goodweather_8h.html#aa51248353573abd95af37e46f0a2c4a7',1,'ir_Goodweather.h']]], + ['kgoodweathercmddowntemp_5295',['kGoodweatherCmdDownTemp',['../ir__Goodweather_8h.html#a8a0b72bf745b6003fb460a3c917eecff',1,'ir_Goodweather.h']]], + ['kgoodweathercmdfan_5296',['kGoodweatherCmdFan',['../ir__Goodweather_8h.html#a4a0881f87af157fdf9ed3d9f342f1ac5',1,'ir_Goodweather.h']]], + ['kgoodweathercmdhold_5297',['kGoodweatherCmdHold',['../ir__Goodweather_8h.html#ac0f3b1413228cb7e86822c5690f20344',1,'ir_Goodweather.h']]], + ['kgoodweathercmdlight_5298',['kGoodweatherCmdLight',['../ir__Goodweather_8h.html#ae70c4e66b17db9caf4800eb57a50706f',1,'ir_Goodweather.h']]], + ['kgoodweathercmdmode_5299',['kGoodweatherCmdMode',['../ir__Goodweather_8h.html#a6042296931ab29e9dfa5a701f3e42175',1,'ir_Goodweather.h']]], + ['kgoodweathercmdpower_5300',['kGoodweatherCmdPower',['../ir__Goodweather_8h.html#a3f1bf85bb10343512bb276adfc64b3b2',1,'ir_Goodweather.h']]], + ['kgoodweathercmdsleep_5301',['kGoodweatherCmdSleep',['../ir__Goodweather_8h.html#a3f4d72b620c73aec68c2125430ca709d',1,'ir_Goodweather.h']]], + ['kgoodweathercmdswing_5302',['kGoodweatherCmdSwing',['../ir__Goodweather_8h.html#ab4ceedbe859811a9fb394f6ebf233cb5',1,'ir_Goodweather.h']]], + ['kgoodweathercmdtimer_5303',['kGoodweatherCmdTimer',['../ir__Goodweather_8h.html#ad4d247ea6c9fc237e0acda84fdaa2eb6',1,'ir_Goodweather.h']]], + ['kgoodweathercmdturbo_5304',['kGoodweatherCmdTurbo',['../ir__Goodweather_8h.html#aebc6d53b3e7d1769bff47968c19c09c9',1,'ir_Goodweather.h']]], + ['kgoodweathercmduptemp_5305',['kGoodweatherCmdUpTemp',['../ir__Goodweather_8h.html#a51a089b03bd72a247a4c35c2ff3f3dc6',1,'ir_Goodweather.h']]], + ['kgoodweathercommandsize_5306',['kGoodweatherCommandSize',['../ir__Goodweather_8h.html#aa5ae9f1b5f6458a25b31b0d2c7feb508',1,'ir_Goodweather.h']]], + ['kgoodweathercool_5307',['kGoodweatherCool',['../ir__Goodweather_8h.html#a92c807d6ff8a3356e65f04e82b99aba4',1,'ir_Goodweather.h']]], + ['kgoodweatherdry_5308',['kGoodweatherDry',['../ir__Goodweather_8h.html#ac5174a3e2c64361c25adcf7caa5b714c',1,'ir_Goodweather.h']]], + ['kgoodweathereofmask_5309',['kGoodweatherEOFMask',['../ir__Goodweather_8h.html#a3d86da1a2bab92a9f70cc88e2628f266',1,'ir_Goodweather.h']]], + ['kgoodweatherextratolerance_5310',['kGoodweatherExtraTolerance',['../ir__Goodweather_8h.html#aae814dfbd574241d3b434d0bf2d38939',1,'ir_Goodweather.h']]], + ['kgoodweatherfan_5311',['kGoodweatherFan',['../ir__Goodweather_8h.html#ad56f00c7e39df93d28419d6a4afa360b',1,'ir_Goodweather.h']]], + ['kgoodweatherfanauto_5312',['kGoodweatherFanAuto',['../ir__Goodweather_8h.html#a9cc119524ac1cb93395dff3bb44b85cc',1,'ir_Goodweather.h']]], + ['kgoodweatherfanhigh_5313',['kGoodweatherFanHigh',['../ir__Goodweather_8h.html#af2b24de50923a0aabd4379dc6d3ef10f',1,'ir_Goodweather.h']]], + ['kgoodweatherfanlow_5314',['kGoodweatherFanLow',['../ir__Goodweather_8h.html#a7bc7c0cf9f2df574a7c087542991ab9b',1,'ir_Goodweather.h']]], + ['kgoodweatherfanmed_5315',['kGoodweatherFanMed',['../ir__Goodweather_8h.html#a5174245e9369a488332b32dfa416963e',1,'ir_Goodweather.h']]], + ['kgoodweatherfansize_5316',['kGoodweatherFanSize',['../ir__Goodweather_8h.html#a687ae6502d8fe6b4a5bd11468106481e',1,'ir_Goodweather.h']]], + ['kgoodweatherhdrmark_5317',['kGoodweatherHdrMark',['../ir__Goodweather_8h.html#a5c39e33226770babb4b0e89fc0cde709',1,'ir_Goodweather.h']]], + ['kgoodweatherhdrspace_5318',['kGoodweatherHdrSpace',['../ir__Goodweather_8h.html#a837bfeaa111b00e2744c4ada89281bfb',1,'ir_Goodweather.h']]], + ['kgoodweatherheat_5319',['kGoodweatherHeat',['../ir__Goodweather_8h.html#a17d223f03df2718151a426582a224a2e',1,'ir_Goodweather.h']]], + ['kgoodweatherminrepeat_5320',['kGoodweatherMinRepeat',['../IRremoteESP8266_8h.html#a885bc5a3a5ba2d8827a62d07a43d0321',1,'IRremoteESP8266.h']]], + ['kgoodweatheronespace_5321',['kGoodweatherOneSpace',['../ir__Goodweather_8h.html#a8efa251085a8f434cb91c049e65cda56',1,'ir_Goodweather.h']]], + ['kgoodweatherstateinit_5322',['kGoodweatherStateInit',['../ir__Goodweather_8h.html#a5ec0e7ca097241d6bef0cbf2135c8fca',1,'ir_Goodweather.h']]], + ['kgoodweatherswingfast_5323',['kGoodweatherSwingFast',['../ir__Goodweather_8h.html#a2d2fa76fa35cf7d450aaf0b980660514',1,'ir_Goodweather.h']]], + ['kgoodweatherswingoff_5324',['kGoodweatherSwingOff',['../ir__Goodweather_8h.html#aa2c53f56daa2820351924d91b542bb67',1,'ir_Goodweather.h']]], + ['kgoodweatherswingsize_5325',['kGoodweatherSwingSize',['../ir__Goodweather_8h.html#a208e47dc4f9e6a85464b4ce3ecaf5c3e',1,'ir_Goodweather.h']]], + ['kgoodweatherswingslow_5326',['kGoodweatherSwingSlow',['../ir__Goodweather_8h.html#ad2c87d849af2c77088ffc533d279aadb',1,'ir_Goodweather.h']]], + ['kgoodweathertempmax_5327',['kGoodweatherTempMax',['../ir__Goodweather_8h.html#abec401548ce2221a9c668318a33a039c',1,'ir_Goodweather.h']]], + ['kgoodweathertempmin_5328',['kGoodweatherTempMin',['../ir__Goodweather_8h.html#a8e76c0ec1bd5e124d9cee5742a2d1cfe',1,'ir_Goodweather.h']]], + ['kgoodweathertempsize_5329',['kGoodweatherTempSize',['../ir__Goodweather_8h.html#a2ef3336be36de4f34940de28cfe195a8',1,'ir_Goodweather.h']]], + ['kgoodweatherzerospace_5330',['kGoodweatherZeroSpace',['../ir__Goodweather_8h.html#a411cbfb812d102daeaf6a83c742f9a9a',1,'ir_Goodweather.h']]], + ['kgpiounused_5331',['kGpioUnused',['../IRac_8h.html#afd817f0bc02c516b6430098dcecde383',1,'IRac.h']]], + ['kgreeauto_5332',['kGreeAuto',['../ir__Gree_8h.html#a65d2d0192a1baff86b859da1018ef2f8',1,'ir_Gree.h']]], + ['kgreebitmark_5333',['kGreeBitMark',['../ir__Gree_8cpp.html#ad7e23346f6d793cc2469e4c8a5650397',1,'ir_Gree.cpp']]], + ['kgreebits_5334',['kGreeBits',['../IRremoteESP8266_8h.html#acadcc5d03e09784642f008d4d2913c7d',1,'IRremoteESP8266.h']]], + ['kgreeblockfooter_5335',['kGreeBlockFooter',['../ir__Gree_8cpp.html#ae6d01cfa7ee2ef6ff27c1ecd7cd9be51',1,'ir_Gree.cpp']]], + ['kgreeblockfooterbits_5336',['kGreeBlockFooterBits',['../ir__Gree_8cpp.html#ae866eef4c729c703597a266917799cbd',1,'ir_Gree.cpp']]], + ['kgreecool_5337',['kGreeCool',['../ir__Gree_8h.html#a1e1eeab696b43864cec66e6485487cea',1,'ir_Gree.h']]], + ['kgreedefaultrepeat_5338',['kGreeDefaultRepeat',['../IRremoteESP8266_8h.html#a6816d2cb11b99a61fb63e6d0928e6706',1,'IRremoteESP8266.h']]], + ['kgreedisplaytempinside_5339',['kGreeDisplayTempInside',['../ir__Gree_8h.html#a7495e5873f63135490090929ed79e994',1,'ir_Gree.h']]], + ['kgreedisplaytempoff_5340',['kGreeDisplayTempOff',['../ir__Gree_8h.html#aa5881910d1c01b816f3ac22ddf0f89a8',1,'ir_Gree.h']]], + ['kgreedisplaytempoffset_5341',['kGreeDisplayTempOffset',['../ir__Gree_8h.html#ab60baff4d0e83964d6e5b23994949a06',1,'ir_Gree.h']]], + ['kgreedisplaytempoutside_5342',['kGreeDisplayTempOutside',['../ir__Gree_8h.html#a737c90e90897053623b15b5579cdb6a1',1,'ir_Gree.h']]], + ['kgreedisplaytempset_5343',['kGreeDisplayTempSet',['../ir__Gree_8h.html#a20f7d0948b158f83655ee4187a104176',1,'ir_Gree.h']]], + ['kgreedisplaytempsize_5344',['kGreeDisplayTempSize',['../ir__Gree_8h.html#aad94a8d5de27b1a46c03c9e3773cf8ec',1,'ir_Gree.h']]], + ['kgreedry_5345',['kGreeDry',['../ir__Gree_8h.html#aa818bcc036988ee24fe0467d128d174f',1,'ir_Gree.h']]], + ['kgreefan_5346',['kGreeFan',['../ir__Gree_8h.html#aa1513ffe43257664f761e4e1a5c2a38f',1,'ir_Gree.h']]], + ['kgreefanauto_5347',['kGreeFanAuto',['../ir__Gree_8h.html#aaad16357e34078257315aad7155b2cd1',1,'ir_Gree.h']]], + ['kgreefanmax_5348',['kGreeFanMax',['../ir__Gree_8h.html#a8753f860f2f503a4a70609fb000654f2',1,'ir_Gree.h']]], + ['kgreefanmed_5349',['kGreeFanMed',['../ir__Gree_8h.html#a674d096a91a5db4b5b7f1b0650c833de',1,'ir_Gree.h']]], + ['kgreefanmin_5350',['kGreeFanMin',['../ir__Gree_8h.html#a34ca09b196c41acc85a4fa0036f3ac3b',1,'ir_Gree.h']]], + ['kgreefanoffset_5351',['kGreeFanOffset',['../ir__Gree_8h.html#a3227e6075f673408577884feb0e6ef10',1,'ir_Gree.h']]], + ['kgreefansize_5352',['kGreeFanSize',['../ir__Gree_8h.html#a8285633b179fbe513c6f8bd2c316e957',1,'ir_Gree.h']]], + ['kgreehdrmark_5353',['kGreeHdrMark',['../ir__Gree_8cpp.html#aaae182fb09bed73e37a5b5d3aee6a5fb',1,'ir_Gree.cpp']]], + ['kgreehdrspace_5354',['kGreeHdrSpace',['../ir__Gree_8cpp.html#a96b50632219c2b5808aea4ee9077b15c',1,'ir_Gree.cpp']]], + ['kgreeheat_5355',['kGreeHeat',['../ir__Gree_8h.html#ada5dac7b789497bf7a434a809d4070f6',1,'ir_Gree.h']]], + ['kgreeifeeloffset_5356',['kGreeIFeelOffset',['../ir__Gree_8h.html#a7253f3b97bade5353a72bfcf2df7976b',1,'ir_Gree.h']]], + ['kgreelightoffset_5357',['kGreeLightOffset',['../ir__Gree_8h.html#ade795164ac467f2547583b9654e2e471',1,'ir_Gree.h']]], + ['kgreemaxtempc_5358',['kGreeMaxTempC',['../ir__Gree_8h.html#a4c01aedfff06ed5a028c40010ad7bfa0',1,'ir_Gree.h']]], + ['kgreemaxtempf_5359',['kGreeMaxTempF',['../ir__Gree_8h.html#a6495898a7a6ddda1473b55820f4b6c44',1,'ir_Gree.h']]], + ['kgreemintempc_5360',['kGreeMinTempC',['../ir__Gree_8h.html#ad127acfc710e281a7b29023c8d1da8f6',1,'ir_Gree.h']]], + ['kgreemintempf_5361',['kGreeMinTempF',['../ir__Gree_8h.html#acf0ecb1b535894e3e790b668333fb66b',1,'ir_Gree.h']]], + ['kgreemsgspace_5362',['kGreeMsgSpace',['../ir__Gree_8cpp.html#a619ed3a2915196ab91d87db2b5a829fd',1,'ir_Gree.cpp']]], + ['kgreeonespace_5363',['kGreeOneSpace',['../ir__Gree_8cpp.html#ab139138084643ea0fca13b28412904e9',1,'ir_Gree.cpp']]], + ['kgreepower1offset_5364',['kGreePower1Offset',['../ir__Gree_8h.html#a300b990aa836926d38dfea0ee99dc295',1,'ir_Gree.h']]], + ['kgreepower2offset_5365',['kGreePower2Offset',['../ir__Gree_8h.html#af29131d47e6cba73682727cd5e8b243d',1,'ir_Gree.h']]], + ['kgreesleepoffset_5366',['kGreeSleepOffset',['../ir__Gree_8h.html#ab715200758a0a4ee2733baf924729132',1,'ir_Gree.h']]], + ['kgreestatelength_5367',['kGreeStateLength',['../IRremoteESP8266_8h.html#a5558b24542873d8475e1ee0e2439839f',1,'IRremoteESP8266.h']]], + ['kgreeswingauto_5368',['kGreeSwingAuto',['../ir__Gree_8h.html#a414a503ad11c1d1d3b68d8b630df1f3a',1,'ir_Gree.h']]], + ['kgreeswingautooffset_5369',['kGreeSwingAutoOffset',['../ir__Gree_8h.html#a60d3de1ba88a6b06c79205116fbd7869',1,'ir_Gree.h']]], + ['kgreeswingdown_5370',['kGreeSwingDown',['../ir__Gree_8h.html#abbe69b966ceb1f9eb60fe9c3fb18088d',1,'ir_Gree.h']]], + ['kgreeswingdownauto_5371',['kGreeSwingDownAuto',['../ir__Gree_8h.html#abc7d7b7de5dd2eb9c0a6ca28827aeb06',1,'ir_Gree.h']]], + ['kgreeswinglastpos_5372',['kGreeSwingLastPos',['../ir__Gree_8h.html#a630cd8fec01f13bfda0fffc1a0e59199',1,'ir_Gree.h']]], + ['kgreeswingmiddle_5373',['kGreeSwingMiddle',['../ir__Gree_8h.html#a12a7caa871f33a5bb83611b4efc7a42b',1,'ir_Gree.h']]], + ['kgreeswingmiddleauto_5374',['kGreeSwingMiddleAuto',['../ir__Gree_8h.html#ac9f85ef5c1bfeac1e4c759742e2d147f',1,'ir_Gree.h']]], + ['kgreeswingmiddledown_5375',['kGreeSwingMiddleDown',['../ir__Gree_8h.html#acad74b8154d73786e093fa215ab800b0',1,'ir_Gree.h']]], + ['kgreeswingmiddleup_5376',['kGreeSwingMiddleUp',['../ir__Gree_8h.html#aefbdd203df5b35eb61be1d0edd712c80',1,'ir_Gree.h']]], + ['kgreeswingsize_5377',['kGreeSwingSize',['../ir__Gree_8h.html#a287e3c06c9a1efbf7091841f2f689968',1,'ir_Gree.h']]], + ['kgreeswingup_5378',['kGreeSwingUp',['../ir__Gree_8h.html#adad431eb1010951fcf77dc4dac6449c6',1,'ir_Gree.h']]], + ['kgreeswingupauto_5379',['kGreeSwingUpAuto',['../ir__Gree_8h.html#a63f04add215785d4ccfe6ccec03d7667',1,'ir_Gree.h']]], + ['kgreetempextradegreefoffset_5380',['kGreeTempExtraDegreeFOffset',['../ir__Gree_8h.html#abbbca05f6971b4bc2d83d4e5bd79854c',1,'ir_Gree.h']]], + ['kgreetempoffset_5381',['kGreeTempOffset',['../ir__Gree_8h.html#a838def81d0f1253e7371fa237f5f0a34',1,'ir_Gree.h']]], + ['kgreetempsize_5382',['kGreeTempSize',['../ir__Gree_8h.html#a15e8555687b1e6bfc47cd4ee4079b700',1,'ir_Gree.h']]], + ['kgreetimerenabledoffset_5383',['kGreeTimerEnabledOffset',['../ir__Gree_8h.html#aec18110852ca714f58734749ef8d4e7d',1,'ir_Gree.h']]], + ['kgreetimerhalfhroffset_5384',['kGreeTimerHalfHrOffset',['../ir__Gree_8h.html#af0779698759e0b6b41bd1f0b77fbddea',1,'ir_Gree.h']]], + ['kgreetimerhoursoffset_5385',['kGreeTimerHoursOffset',['../ir__Gree_8h.html#a1aeba4b3c5bff86b541291ea29220a60',1,'ir_Gree.h']]], + ['kgreetimerhourssize_5386',['kGreeTimerHoursSize',['../ir__Gree_8h.html#af08673b8c795a0c9a710825ceacd6bdb',1,'ir_Gree.h']]], + ['kgreetimermax_5387',['kGreeTimerMax',['../ir__Gree_8h.html#a76048e03908dd0d22cc8cacfbd99a40b',1,'ir_Gree.h']]], + ['kgreetimertenshroffset_5388',['kGreeTimerTensHrOffset',['../ir__Gree_8h.html#a5ca305d48fde5b5c6792c7734b31b941',1,'ir_Gree.h']]], + ['kgreetimertenshrsize_5389',['kGreeTimerTensHrSize',['../ir__Gree_8h.html#a5d8b007e38dcec0327ed0e38705f05c0',1,'ir_Gree.h']]], + ['kgreeturbooffset_5390',['kGreeTurboOffset',['../ir__Gree_8h.html#a5fe9afa8e66edd95a94404abe00dd1f1',1,'ir_Gree.h']]], + ['kgreeusefahrenheitoffset_5391',['kGreeUseFahrenheitOffset',['../ir__Gree_8h.html#a741c43d31a99fd8b723315d9db0724cc',1,'ir_Gree.h']]], + ['kgreewifioffset_5392',['kGreeWiFiOffset',['../ir__Gree_8h.html#a993dede6398a2c4ec2c1e025f4746768',1,'ir_Gree.h']]], + ['kgreexfanoffset_5393',['kGreeXfanOffset',['../ir__Gree_8h.html#a2388c44b2826823349d02dec581da584',1,'ir_Gree.h']]], + ['kgreezerospace_5394',['kGreeZeroSpace',['../ir__Gree_8cpp.html#aa4694ba8ff0e14cd6b9c4730675c385f',1,'ir_Gree.cpp']]], + ['khaieracauto_5395',['kHaierAcAuto',['../ir__Haier_8h.html#ac33a02f63ee77e0d3050598511730865',1,'ir_Haier.h']]], + ['khaieracbitmark_5396',['kHaierAcBitMark',['../ir__Haier_8cpp.html#a4dec38325834c873c03588a8046f0963',1,'ir_Haier.cpp']]], + ['khaieracbits_5397',['kHaierACBits',['../IRremoteESP8266_8h.html#ad44cfa0951c24d1f0c67b2fba997f720',1,'IRremoteESP8266.h']]], + ['khaieraccmdfan_5398',['kHaierAcCmdFan',['../ir__Haier_8h.html#a447818ec7970e2ca09540afe44ecf90d',1,'ir_Haier.h']]], + ['khaieraccmdhealth_5399',['kHaierAcCmdHealth',['../ir__Haier_8h.html#a83cd0b5f307d9ae3ed0a3c6ed8fef94d',1,'ir_Haier.h']]], + ['khaieraccmdmode_5400',['kHaierAcCmdMode',['../ir__Haier_8h.html#a4543aa4ee28323bb9cb5c077f9bf9da1',1,'ir_Haier.h']]], + ['khaieraccmdoff_5401',['kHaierAcCmdOff',['../ir__Haier_8h.html#a96599917176ee244874926d1a530dd7e',1,'ir_Haier.h']]], + ['khaieraccmdon_5402',['kHaierAcCmdOn',['../ir__Haier_8h.html#a83973c2ad2b7b95611c81628c387e0d8',1,'ir_Haier.h']]], + ['khaieraccmdsleep_5403',['kHaierAcCmdSleep',['../ir__Haier_8h.html#abe52b62dd513395f2a8c7d47fa2fc514',1,'ir_Haier.h']]], + ['khaieraccmdswing_5404',['kHaierAcCmdSwing',['../ir__Haier_8h.html#afab164c2aabf39fdc1e956ff88af19d9',1,'ir_Haier.h']]], + ['khaieraccmdtempdown_5405',['kHaierAcCmdTempDown',['../ir__Haier_8h.html#aecc31139b4e45a7784669554c6fdbb54',1,'ir_Haier.h']]], + ['khaieraccmdtempup_5406',['kHaierAcCmdTempUp',['../ir__Haier_8h.html#aab5363f07920971c31d6acf8e70d392c',1,'ir_Haier.h']]], + ['khaieraccmdtimercancel_5407',['kHaierAcCmdTimerCancel',['../ir__Haier_8h.html#ab780da80fc471f004c5b34dc8f347d00',1,'ir_Haier.h']]], + ['khaieraccmdtimerset_5408',['kHaierAcCmdTimerSet',['../ir__Haier_8h.html#a9bd7c081d460a4ae5e3eac977f3916e4',1,'ir_Haier.h']]], + ['khaieraccool_5409',['kHaierAcCool',['../ir__Haier_8h.html#a83cd81ea1115f42a403ea5ee07a32bbb',1,'ir_Haier.h']]], + ['khaieracdefaultrepeat_5410',['kHaierAcDefaultRepeat',['../IRremoteESP8266_8h.html#a882914932449e33933b6f8e224cbaf3c',1,'IRremoteESP8266.h']]], + ['khaieracdeftemp_5411',['kHaierAcDefTemp',['../ir__Haier_8h.html#a86c9e8176fc01e52e883cadcc1d31763',1,'ir_Haier.h']]], + ['khaieracdry_5412',['kHaierAcDry',['../ir__Haier_8h.html#a3d36fbe1308221248f45044e5a671636',1,'ir_Haier.h']]], + ['khaieracfan_5413',['kHaierAcFan',['../ir__Haier_8h.html#af4049629b2139ca82471dfed1e1ced15',1,'ir_Haier.h']]], + ['khaieracfanauto_5414',['kHaierAcFanAuto',['../ir__Haier_8h.html#a8a34e74f7083caa98ed4afc31294539e',1,'ir_Haier.h']]], + ['khaieracfanhigh_5415',['kHaierAcFanHigh',['../ir__Haier_8h.html#aa4d9e45ca5777707778ef78a3284da19',1,'ir_Haier.h']]], + ['khaieracfanlow_5416',['kHaierAcFanLow',['../ir__Haier_8h.html#ae31e878b09284a6730a11e2017cfd7a8',1,'ir_Haier.h']]], + ['khaieracfanmed_5417',['kHaierAcFanMed',['../ir__Haier_8h.html#a5dfa833768e549964aa0bf8a336c32b0',1,'ir_Haier.h']]], + ['khaierachdr_5418',['kHaierAcHdr',['../ir__Haier_8cpp.html#a0f5dbd2eb92f10bc354e6b0a7a074084',1,'ir_Haier.cpp']]], + ['khaierachdrgap_5419',['kHaierAcHdrGap',['../ir__Haier_8cpp.html#a4c3fe62f8e5abf5d084009bbd4c4f878',1,'ir_Haier.cpp']]], + ['khaierachealthbitoffset_5420',['kHaierAcHealthBitOffset',['../ir__Haier_8h.html#ae2e5e80f891c9bbca2844d808b0b3d1b',1,'ir_Haier.h']]], + ['khaieracheat_5421',['kHaierAcHeat',['../ir__Haier_8h.html#a0edb011bdf85197e63a32d37f8517dd2',1,'ir_Haier.h']]], + ['khaierachourssize_5422',['kHaierAcHoursSize',['../ir__Haier_8h.html#a3db7b7dddae84a5d12101c5cdd06975e',1,'ir_Haier.h']]], + ['khaieracmaxtemp_5423',['kHaierAcMaxTemp',['../ir__Haier_8h.html#a925252489fe34d9932151817d0dbe90b',1,'ir_Haier.h']]], + ['khaieracmaxtime_5424',['kHaierAcMaxTime',['../ir__Haier_8h.html#ae04e48e926a7533c3b62f0ff991e1f88',1,'ir_Haier.h']]], + ['khaieracmingap_5425',['kHaierAcMinGap',['../ir__Haier_8cpp.html#a7ab1f44876a931da765b52e4633e5e82',1,'ir_Haier.cpp']]], + ['khaieracminssize_5426',['kHaierAcMinsSize',['../ir__Haier_8h.html#a105e047084515305e896d8ff776d05e6',1,'ir_Haier.h']]], + ['khaieracmintemp_5427',['kHaierAcMinTemp',['../ir__Haier_8h.html#aafd2a4f38ecf78482a5a94e9c6c23f1c',1,'ir_Haier.h']]], + ['khaieracmodeoffset_5428',['kHaierAcModeOffset',['../ir__Haier_8h.html#a93fdbb1742923cf3f738c8078d5660f8',1,'ir_Haier.h']]], + ['khaieracofftimeroffset_5429',['kHaierAcOffTimerOffset',['../ir__Haier_8h.html#ace8cd6ed41c3f247ada91052d653b515',1,'ir_Haier.h']]], + ['khaieraconespace_5430',['kHaierAcOneSpace',['../ir__Haier_8cpp.html#a43739aa786e08fca2a4a62a680b5c38b',1,'ir_Haier.cpp']]], + ['khaieracontimeroffset_5431',['kHaierAcOnTimerOffset',['../ir__Haier_8h.html#a5189092c278fb5c31efd4f539f905da5',1,'ir_Haier.h']]], + ['khaieracprefix_5432',['kHaierAcPrefix',['../ir__Haier_8h.html#a8502c9bea40205e01e6a01b47354272a',1,'ir_Haier.h']]], + ['khaieracsleepbit_5433',['kHaierAcSleepBit',['../ir__Haier_8h.html#ac63b91acdffa55d440b08aee05bda5dc',1,'ir_Haier.h']]], + ['khaieracsleepbitoffset_5434',['kHaierAcSleepBitOffset',['../ir__Haier_8h.html#ad9f4cbfd8e6a5874d661195858156eec',1,'ir_Haier.h']]], + ['khaieracstatelength_5435',['kHaierACStateLength',['../IRremoteESP8266_8h.html#afb4cd0c1a9c689d862e7095f0ab6dbe5',1,'IRremoteESP8266.h']]], + ['khaieracswingchg_5436',['kHaierAcSwingChg',['../ir__Haier_8h.html#af65a92a0b9d29a52ac882d4457e954e8',1,'ir_Haier.h']]], + ['khaieracswingdown_5437',['kHaierAcSwingDown',['../ir__Haier_8h.html#a2cf3a2102c6d4f9aede44efe853ffaa8',1,'ir_Haier.h']]], + ['khaieracswingoff_5438',['kHaierAcSwingOff',['../ir__Haier_8h.html#ac21f78c3cef931154b3fc953bbebc3b4',1,'ir_Haier.h']]], + ['khaieracswingoffset_5439',['kHaierAcSwingOffset',['../ir__Haier_8h.html#a0872af0b2b3f22f6681917b9c81c3bbd',1,'ir_Haier.h']]], + ['khaieracswingsize_5440',['kHaierAcSwingSize',['../ir__Haier_8h.html#ad032725404a02c0e5a93350f20daf6e1',1,'ir_Haier.h']]], + ['khaieracswingup_5441',['kHaierAcSwingUp',['../ir__Haier_8h.html#a4bff8829604ee927dda5cfc54bd6cfe6',1,'ir_Haier.h']]], + ['khaieractimeoffset_5442',['kHaierAcTimeOffset',['../ir__Haier_8h.html#abb7a8ec83d3c0dbbe4d660d6bf627f23',1,'ir_Haier.h']]], + ['khaieracyrw02auto_5443',['kHaierAcYrw02Auto',['../ir__Haier_8h.html#aa025eeba1c344c50cc98334c97a3c174',1,'ir_Haier.h']]], + ['khaieracyrw02bits_5444',['kHaierACYRW02Bits',['../IRremoteESP8266_8h.html#aab346c5ad482113978e5a2cbb7a06f27',1,'IRremoteESP8266.h']]], + ['khaieracyrw02buttonfan_5445',['kHaierAcYrw02ButtonFan',['../ir__Haier_8h.html#a0f9c265510e1e27f38817f08ef9c622b',1,'ir_Haier.h']]], + ['khaieracyrw02buttonhealth_5446',['kHaierAcYrw02ButtonHealth',['../ir__Haier_8h.html#ab1dc6c0a4ed59446bb69c4dd671c78cd',1,'ir_Haier.h']]], + ['khaieracyrw02buttonmode_5447',['kHaierAcYrw02ButtonMode',['../ir__Haier_8h.html#a74466c50b450b08407c9f226a5d657e5',1,'ir_Haier.h']]], + ['khaieracyrw02buttonpower_5448',['kHaierAcYrw02ButtonPower',['../ir__Haier_8h.html#af36b9c628a697f6c596052ecd143d80b',1,'ir_Haier.h']]], + ['khaieracyrw02buttonsleep_5449',['kHaierAcYrw02ButtonSleep',['../ir__Haier_8h.html#a5c7b8ff351e3d0167ec2c897c4820c40',1,'ir_Haier.h']]], + ['khaieracyrw02buttonswing_5450',['kHaierAcYrw02ButtonSwing',['../ir__Haier_8h.html#aa10c558317448783535e96be5876505c',1,'ir_Haier.h']]], + ['khaieracyrw02buttontempdown_5451',['kHaierAcYrw02ButtonTempDown',['../ir__Haier_8h.html#af4a9e5f7f705c331531ea2863dbbd11d',1,'ir_Haier.h']]], + ['khaieracyrw02buttontempup_5452',['kHaierAcYrw02ButtonTempUp',['../ir__Haier_8h.html#a3b24373f9c812f93eca05ee47e61d6e0',1,'ir_Haier.h']]], + ['khaieracyrw02buttonturbo_5453',['kHaierAcYrw02ButtonTurbo',['../ir__Haier_8h.html#ad80547c526b2eba142297715c0a0636d',1,'ir_Haier.h']]], + ['khaieracyrw02cool_5454',['kHaierAcYrw02Cool',['../ir__Haier_8h.html#a30c5d4e61ae3112a8a3e3622eecbb10b',1,'ir_Haier.h']]], + ['khaieracyrw02defaultrepeat_5455',['kHaierAcYrw02DefaultRepeat',['../IRremoteESP8266_8h.html#a62412e221207dbc2660f93dc265b4218',1,'IRremoteESP8266.h']]], + ['khaieracyrw02dry_5456',['kHaierAcYrw02Dry',['../ir__Haier_8h.html#a66cd902f2d35b4c8f66f085a0950a5fc',1,'ir_Haier.h']]], + ['khaieracyrw02fan_5457',['kHaierAcYrw02Fan',['../ir__Haier_8h.html#a35f50f043a2dda75c59507c1ed845b5d',1,'ir_Haier.h']]], + ['khaieracyrw02fanauto_5458',['kHaierAcYrw02FanAuto',['../ir__Haier_8h.html#ad554d38035ac15e4ea8b855802886989',1,'ir_Haier.h']]], + ['khaieracyrw02fanhigh_5459',['kHaierAcYrw02FanHigh',['../ir__Haier_8h.html#ab47bc48ac77fbf6734a41d10f0a53e4a',1,'ir_Haier.h']]], + ['khaieracyrw02fanlow_5460',['kHaierAcYrw02FanLow',['../ir__Haier_8h.html#a9a0a14ab98e1e52b60b9b9bf611c20cc',1,'ir_Haier.h']]], + ['khaieracyrw02fanmed_5461',['kHaierAcYrw02FanMed',['../ir__Haier_8h.html#a65583649324c6039112e7db26d685afc',1,'ir_Haier.h']]], + ['khaieracyrw02fanoffset_5462',['kHaierAcYrw02FanOffset',['../ir__Haier_8h.html#a0910d1996a451c98383124a39ef65f84',1,'ir_Haier.h']]], + ['khaieracyrw02fansize_5463',['kHaierAcYrw02FanSize',['../ir__Haier_8h.html#aa2c6bd47b47e0ea1b51931fec7daef4d',1,'ir_Haier.h']]], + ['khaieracyrw02healthoffset_5464',['kHaierAcYrw02HealthOffset',['../ir__Haier_8h.html#a4bcb42b359472cf770e0710b5369493b',1,'ir_Haier.h']]], + ['khaieracyrw02heat_5465',['kHaierAcYrw02Heat',['../ir__Haier_8h.html#aa0873975b6649294a3c9943130cb7a38',1,'ir_Haier.h']]], + ['khaieracyrw02modeoffset_5466',['kHaierAcYrw02ModeOffset',['../ir__Haier_8h.html#a027199b609d29ead8aec9bb89178cb30',1,'ir_Haier.h']]], + ['khaieracyrw02power_5467',['kHaierAcYrw02Power',['../ir__Haier_8h.html#abe59df7abf20a66107516054f3a2d32b',1,'ir_Haier.h']]], + ['khaieracyrw02poweroffset_5468',['kHaierAcYrw02PowerOffset',['../ir__Haier_8h.html#a67401152b0aa06fb7922bbca743cd600',1,'ir_Haier.h']]], + ['khaieracyrw02prefix_5469',['kHaierAcYrw02Prefix',['../ir__Haier_8h.html#ac62d0f7ca94e064712f8a7a80da2f11e',1,'ir_Haier.h']]], + ['khaieracyrw02sleep_5470',['kHaierAcYrw02Sleep',['../ir__Haier_8h.html#abb70fe8ca6004246345df3d841047252',1,'ir_Haier.h']]], + ['khaieracyrw02sleepoffset_5471',['kHaierAcYrw02SleepOffset',['../ir__Haier_8h.html#ac651bfee5d261124700c81ec5db184a7',1,'ir_Haier.h']]], + ['khaieracyrw02statelength_5472',['kHaierACYRW02StateLength',['../IRremoteESP8266_8h.html#a8f52b7d4595c117cf0b81ffbd1148cda',1,'IRremoteESP8266.h']]], + ['khaieracyrw02swingauto_5473',['kHaierAcYrw02SwingAuto',['../ir__Haier_8h.html#a95ae88223d910d4d966949241bccff8d',1,'ir_Haier.h']]], + ['khaieracyrw02swingbottom_5474',['kHaierAcYrw02SwingBottom',['../ir__Haier_8h.html#aa4b64385da5e9b2a89e15f70cd8c89e9',1,'ir_Haier.h']]], + ['khaieracyrw02swingdown_5475',['kHaierAcYrw02SwingDown',['../ir__Haier_8h.html#aab380411ac07b2b7f67956a5bbc362fb',1,'ir_Haier.h']]], + ['khaieracyrw02swingmiddle_5476',['kHaierAcYrw02SwingMiddle',['../ir__Haier_8h.html#a32d6dd98a050711bf928bf250b769839',1,'ir_Haier.h']]], + ['khaieracyrw02swingoff_5477',['kHaierAcYrw02SwingOff',['../ir__Haier_8h.html#a62570c15418cf24a94c92b162967f892',1,'ir_Haier.h']]], + ['khaieracyrw02swingtop_5478',['kHaierAcYrw02SwingTop',['../ir__Haier_8h.html#adf10f1bc1b293c684232cb6398631f70',1,'ir_Haier.h']]], + ['khaieracyrw02turbohigh_5479',['kHaierAcYrw02TurboHigh',['../ir__Haier_8h.html#ab096c15c69f242b99fbc1e4d7bd7548e',1,'ir_Haier.h']]], + ['khaieracyrw02turbolow_5480',['kHaierAcYrw02TurboLow',['../ir__Haier_8h.html#a19b7f4aee8115eb77267c415d8b3bd82',1,'ir_Haier.h']]], + ['khaieracyrw02turbooff_5481',['kHaierAcYrw02TurboOff',['../ir__Haier_8h.html#aa06ba46287b5806a6373e921cee34a51',1,'ir_Haier.h']]], + ['khaieracyrw02turbooffset_5482',['kHaierAcYrw02TurboOffset',['../ir__Haier_8h.html#a6581fc8ec43b9ac9f877bf27231554bd',1,'ir_Haier.h']]], + ['khaieracyrw02turbosize_5483',['kHaierAcYrw02TurboSize',['../ir__Haier_8h.html#a6ad469ec094d8af5a68cc94a744079bb',1,'ir_Haier.h']]], + ['khaieraczerospace_5484',['kHaierAcZeroSpace',['../ir__Haier_8cpp.html#af2b1a4f27c7b50a1e60ae00bbbec7a16',1,'ir_Haier.cpp']]], + ['kheader_5485',['kHeader',['../IRrecv_8h.html#a0eac186845b9b998a252a3bdfa72e8ed',1,'IRrecv.h']]], + ['khealthstr_5486',['kHealthStr',['../IRtext_8cpp.html#a12474bbd4a7f700c922bcc1de240894f',1,'kHealthStr(): IRtext.cpp'],['../IRtext_8h.html#a7ef833cf90df2c97ef46c5c4b6225a42',1,'kHealthStr(): IRtext.cpp']]], + ['kheatstr_5487',['kHeatStr',['../IRtext_8cpp.html#a3a16f1dabca01c8f8e5ba1516408ba39',1,'kHeatStr(): IRtext.cpp'],['../IRtext_8h.html#a058df7d2db245e307719d025352d464d',1,'kHeatStr(): IRtext.cpp']]], + ['khigheststr_5488',['kHighestStr',['../IRtext_8cpp.html#a219f1d54c5ea75bd5c736efc0d7d7275',1,'kHighestStr(): IRtext.cpp'],['../IRtext_8h.html#ad7706307f507466526b4288e33385bde',1,'kHighestStr(): IRtext.cpp']]], + ['khighnibble_5489',['kHighNibble',['../IRutils_8h.html#a26dd96e82207f707c21e696a60b9c032',1,'IRutils.h']]], + ['khighstr_5490',['kHighStr',['../IRtext_8cpp.html#a127a20ad54e671f48a8faa822ff006f4',1,'kHighStr(): IRtext.cpp'],['../IRtext_8h.html#a5b4ade5e08f30c5e9a61c813bb2046f1',1,'kHighStr(): IRtext.cpp']]], + ['khistr_5491',['kHiStr',['../IRtext_8cpp.html#a7f4994ce51aed70ce6b5b4c88b886466',1,'kHiStr(): IRtext.cpp'],['../IRtext_8h.html#aa6fe661cdd9e2f1dc30d6fee2980cadd',1,'kHiStr(): IRtext.cpp']]], + ['khitachiac1auto_5492',['kHitachiAc1Auto',['../ir__Hitachi_8h.html#a2689ef34702107dc3dce3d1cfa260fc9',1,'ir_Hitachi.h']]], + ['khitachiac1bits_5493',['kHitachiAc1Bits',['../IRremoteESP8266_8h.html#aae6947c431d2c9da4fe2fdd9428012c1',1,'IRremoteESP8266.h']]], + ['khitachiac1checksumstartbyte_5494',['kHitachiAc1ChecksumStartByte',['../ir__Hitachi_8h.html#afafa689c5e922b812f63e08941feb2a7',1,'ir_Hitachi.h']]], + ['khitachiac1cool_5495',['kHitachiAc1Cool',['../ir__Hitachi_8h.html#a1146eda7688843d16094acf7a19a75ac',1,'ir_Hitachi.h']]], + ['khitachiac1dry_5496',['kHitachiAc1Dry',['../ir__Hitachi_8h.html#a82895db5201610844da803bf333102a3',1,'ir_Hitachi.h']]], + ['khitachiac1fan_5497',['kHitachiAc1Fan',['../ir__Hitachi_8h.html#ac5a3ba0e0e4ed02d4792d5a8e6a22654',1,'ir_Hitachi.h']]], + ['khitachiac1fanauto_5498',['kHitachiAc1FanAuto',['../ir__Hitachi_8h.html#a6f9adda7b08ec4b8566ceb4d79966689',1,'ir_Hitachi.h']]], + ['khitachiac1fanbyte_5499',['kHitachiAc1FanByte',['../ir__Hitachi_8h.html#afe6b5951ba3b4e7ad5400f30228d106e',1,'ir_Hitachi.h']]], + ['khitachiac1fanhigh_5500',['kHitachiAc1FanHigh',['../ir__Hitachi_8h.html#ace677cf030da9d74eda0f50d54c91411',1,'ir_Hitachi.h']]], + ['khitachiac1fanlow_5501',['kHitachiAc1FanLow',['../ir__Hitachi_8h.html#a011219de5c0e2ba043a8be6345f8cb05',1,'ir_Hitachi.h']]], + ['khitachiac1fanmed_5502',['kHitachiAc1FanMed',['../ir__Hitachi_8h.html#afbc2a535d85adb80cbcbac63e2432b1a',1,'ir_Hitachi.h']]], + ['khitachiac1fanoffset_5503',['kHitachiAc1FanOffset',['../ir__Hitachi_8h.html#af533c283666d80c0b9348f706909f4c4',1,'ir_Hitachi.h']]], + ['khitachiac1fansize_5504',['kHitachiAc1FanSize',['../ir__Hitachi_8h.html#a2b2a24680efaf1eeaf76dacaabef5c1d',1,'ir_Hitachi.h']]], + ['khitachiac1hdrmark_5505',['kHitachiAc1HdrMark',['../ir__Hitachi_8cpp.html#a2b1891174c78be6f960e92b389d25fe7',1,'ir_Hitachi.cpp']]], + ['khitachiac1hdrspace_5506',['kHitachiAc1HdrSpace',['../ir__Hitachi_8cpp.html#a93f34ee53a375dd7f4ccf82458453701',1,'ir_Hitachi.cpp']]], + ['khitachiac1heat_5507',['kHitachiAc1Heat',['../ir__Hitachi_8h.html#abd5d4db30d6be3b990a74d4481e7eabe',1,'ir_Hitachi.h']]], + ['khitachiac1modebyte_5508',['kHitachiAc1ModeByte',['../ir__Hitachi_8h.html#a57e27b66ff6d471c0dd335b610bc6e24',1,'ir_Hitachi.h']]], + ['khitachiac1model_5fa_5509',['kHitachiAc1Model_A',['../ir__Hitachi_8h.html#a5f8fc3bb000d46705e4530ca0a8f7b60',1,'ir_Hitachi.h']]], + ['khitachiac1model_5fb_5510',['kHitachiAc1Model_B',['../ir__Hitachi_8h.html#a2d894a528c538b8a3922e2500241a55b',1,'ir_Hitachi.h']]], + ['khitachiac1modelbyte_5511',['kHitachiAc1ModelByte',['../ir__Hitachi_8h.html#a2e2a76b8b7decef99cfb7b197e8fb7f7',1,'ir_Hitachi.h']]], + ['khitachiac1modeloffset_5512',['kHitachiAc1ModelOffset',['../ir__Hitachi_8h.html#a8a440a64e6e164511e0976dc5b6585ff',1,'ir_Hitachi.h']]], + ['khitachiac1modelsize_5513',['kHitachiAc1ModelSize',['../ir__Hitachi_8h.html#ab74bbcb475b7eaf33f70dbfdb853d8c3',1,'ir_Hitachi.h']]], + ['khitachiac1modeoffset_5514',['kHitachiAc1ModeOffset',['../ir__Hitachi_8h.html#a3f010fa5ae43ee36771be18659d8bc80',1,'ir_Hitachi.h']]], + ['khitachiac1modesize_5515',['kHitachiAc1ModeSize',['../ir__Hitachi_8h.html#a38b456d96602e83e7832e2a7af75f321',1,'ir_Hitachi.h']]], + ['khitachiac1offtimerhighbyte_5516',['kHitachiAc1OffTimerHighByte',['../ir__Hitachi_8h.html#a36e6b7fc328ee247c11f5779487119b6',1,'ir_Hitachi.h']]], + ['khitachiac1offtimerlowbyte_5517',['kHitachiAc1OffTimerLowByte',['../ir__Hitachi_8h.html#ac8eaedd191009b2ddaf1e047ac6ecf11',1,'ir_Hitachi.h']]], + ['khitachiac1ontimerhighbyte_5518',['kHitachiAc1OnTimerHighByte',['../ir__Hitachi_8h.html#aff6907e9999561abceac42e4cce1dc3b',1,'ir_Hitachi.h']]], + ['khitachiac1ontimerlowbyte_5519',['kHitachiAc1OnTimerLowByte',['../ir__Hitachi_8h.html#a95fef3be6809026b714847c709ba655b',1,'ir_Hitachi.h']]], + ['khitachiac1powerbyte_5520',['kHitachiAc1PowerByte',['../ir__Hitachi_8h.html#acda489ff6137ab3ebfb1795a32e1ec8e',1,'ir_Hitachi.h']]], + ['khitachiac1poweroffset_5521',['kHitachiAc1PowerOffset',['../ir__Hitachi_8h.html#a3fdcd0375b85ac2641d9d5cc6e4770f8',1,'ir_Hitachi.h']]], + ['khitachiac1powertoggleoffset_5522',['kHitachiAc1PowerToggleOffset',['../ir__Hitachi_8h.html#aac994777ce070ad69550229824800ee0',1,'ir_Hitachi.h']]], + ['khitachiac1sleep1_5523',['kHitachiAc1Sleep1',['../ir__Hitachi_8h.html#ab4ca89a9d8c8034e6a3d8ff17b09f3d5',1,'ir_Hitachi.h']]], + ['khitachiac1sleep2_5524',['kHitachiAc1Sleep2',['../ir__Hitachi_8h.html#a1e1a1ea1743b38da6bc6be63fa796689',1,'ir_Hitachi.h']]], + ['khitachiac1sleep3_5525',['kHitachiAc1Sleep3',['../ir__Hitachi_8h.html#a17eaa63f13a3c04aede9f485c310a930',1,'ir_Hitachi.h']]], + ['khitachiac1sleep4_5526',['kHitachiAc1Sleep4',['../ir__Hitachi_8h.html#a21360448a538fbd9491aa9dd28e6c545',1,'ir_Hitachi.h']]], + ['khitachiac1sleepbyte_5527',['kHitachiAc1SleepByte',['../ir__Hitachi_8h.html#ac693a15878e7cdc8e1f575502ea82843',1,'ir_Hitachi.h']]], + ['khitachiac1sleepoff_5528',['kHitachiAc1SleepOff',['../ir__Hitachi_8h.html#a96f87cb3838a1e1aab4b8407dcfc5b78',1,'ir_Hitachi.h']]], + ['khitachiac1sleepoffset_5529',['kHitachiAc1SleepOffset',['../ir__Hitachi_8h.html#a277ca55dbfd35258ea40059bdff62488',1,'ir_Hitachi.h']]], + ['khitachiac1sleepsize_5530',['kHitachiAc1SleepSize',['../ir__Hitachi_8h.html#a199cedd7120057f735ffc640f93a9a1a',1,'ir_Hitachi.h']]], + ['khitachiac1statelength_5531',['kHitachiAc1StateLength',['../IRremoteESP8266_8h.html#abb5e2ddb1a8d3c6fa7a94dbe1989ec5d',1,'IRremoteESP8266.h']]], + ['khitachiac1swingbyte_5532',['kHitachiAc1SwingByte',['../ir__Hitachi_8h.html#a5a283583007b26c1b45d8d7afcd55408',1,'ir_Hitachi.h']]], + ['khitachiac1swinghoffset_5533',['kHitachiAc1SwingHOffset',['../ir__Hitachi_8h.html#ab35d4bb6c17fc5bbcb5385a642476238',1,'ir_Hitachi.h']]], + ['khitachiac1swingtoggleoffset_5534',['kHitachiAc1SwingToggleOffset',['../ir__Hitachi_8h.html#a08eac3b64687e83229648c8664d75dc4',1,'ir_Hitachi.h']]], + ['khitachiac1swingvoffset_5535',['kHitachiAc1SwingVOffset',['../ir__Hitachi_8h.html#af4e410f10812d49175cd419ed678535b',1,'ir_Hitachi.h']]], + ['khitachiac1tempauto_5536',['kHitachiAc1TempAuto',['../ir__Hitachi_8h.html#ad402dff999a97b50b392572899522b6a',1,'ir_Hitachi.h']]], + ['khitachiac1tempbyte_5537',['kHitachiAc1TempByte',['../ir__Hitachi_8h.html#a03185c3b2ddb62d12267da014796da56',1,'ir_Hitachi.h']]], + ['khitachiac1tempdelta_5538',['kHitachiAc1TempDelta',['../ir__Hitachi_8h.html#a279c856a2b4d25651b117a8c654cb48d',1,'ir_Hitachi.h']]], + ['khitachiac1tempoffset_5539',['kHitachiAc1TempOffset',['../ir__Hitachi_8h.html#a8a92aa41be23301229ecec1486714b9a',1,'ir_Hitachi.h']]], + ['khitachiac1tempsize_5540',['kHitachiAc1TempSize',['../ir__Hitachi_8h.html#affb52642edc8f2231f0dc83bc5271885',1,'ir_Hitachi.h']]], + ['khitachiac1timersize_5541',['kHitachiAc1TimerSize',['../ir__Hitachi_8h.html#afd7f469f67f55263b0031b325232751b',1,'ir_Hitachi.h']]], + ['khitachiac2bits_5542',['kHitachiAc2Bits',['../IRremoteESP8266_8h.html#a362a0b0b0afc216cf8162a3724cf073a',1,'IRremoteESP8266.h']]], + ['khitachiac2statelength_5543',['kHitachiAc2StateLength',['../IRremoteESP8266_8h.html#a10377a40053a12e091dbff2869db0352',1,'IRremoteESP8266.h']]], + ['khitachiac344bits_5544',['kHitachiAc344Bits',['../IRremoteESP8266_8h.html#a204fc2410c3d555a37b152a01dceead0',1,'IRremoteESP8266.h']]], + ['khitachiac344buttonfan_5545',['kHitachiAc344ButtonFan',['../ir__Hitachi_8h.html#a5f33b956ec83ee0004785a9c44bd5b0b',1,'ir_Hitachi.h']]], + ['khitachiac344buttonpowermode_5546',['kHitachiAc344ButtonPowerMode',['../ir__Hitachi_8h.html#a3816a8ad86e03f8c5870057e7ad86335',1,'ir_Hitachi.h']]], + ['khitachiac344buttonswingh_5547',['kHitachiAc344ButtonSwingH',['../ir__Hitachi_8h.html#a10dea534868d76d99e91458ee28f5fe9',1,'ir_Hitachi.h']]], + ['khitachiac344buttonswingv_5548',['kHitachiAc344ButtonSwingV',['../ir__Hitachi_8h.html#a95c1b0ee7e3802631f4c2708371e7d34',1,'ir_Hitachi.h']]], + ['khitachiac344buttontempdown_5549',['kHitachiAc344ButtonTempDown',['../ir__Hitachi_8h.html#a05d9bd95037669f1d3743d935471db33',1,'ir_Hitachi.h']]], + ['khitachiac344buttontempup_5550',['kHitachiAc344ButtonTempUp',['../ir__Hitachi_8h.html#a74abf2ce4ed5918bf68f485eff179578',1,'ir_Hitachi.h']]], + ['khitachiac344cool_5551',['kHitachiAc344Cool',['../ir__Hitachi_8h.html#a92d4d8dea34a9387e55852b6b5289328',1,'ir_Hitachi.h']]], + ['khitachiac344dry_5552',['kHitachiAc344Dry',['../ir__Hitachi_8h.html#a37697339ddc2ffaf4ee13b5e140adf2c',1,'ir_Hitachi.h']]], + ['khitachiac344fan_5553',['kHitachiAc344Fan',['../ir__Hitachi_8h.html#a296cd0fc1f414a4e15ce228b5a794bcb',1,'ir_Hitachi.h']]], + ['khitachiac344fanauto_5554',['kHitachiAc344FanAuto',['../ir__Hitachi_8h.html#a6439744edb1ae4dd9e8ea2097fac7a9d',1,'ir_Hitachi.h']]], + ['khitachiac344fanhigh_5555',['kHitachiAc344FanHigh',['../ir__Hitachi_8h.html#a83ea1924948ce9ac8266ab64a41f3ebd',1,'ir_Hitachi.h']]], + ['khitachiac344fanlow_5556',['kHitachiAc344FanLow',['../ir__Hitachi_8h.html#acbbb61fde653c84a8e35865fa724872c',1,'ir_Hitachi.h']]], + ['khitachiac344fanmax_5557',['kHitachiAc344FanMax',['../ir__Hitachi_8h.html#af041ed41027b8e444e3069d9a3481c51',1,'ir_Hitachi.h']]], + ['khitachiac344fanmedium_5558',['kHitachiAc344FanMedium',['../ir__Hitachi_8h.html#aa6d47b5c28f758aa297b345cbf853c9a',1,'ir_Hitachi.h']]], + ['khitachiac344fanmin_5559',['kHitachiAc344FanMin',['../ir__Hitachi_8h.html#ac4bafed10c76739698e9a35183beb970',1,'ir_Hitachi.h']]], + ['khitachiac344heat_5560',['kHitachiAc344Heat',['../ir__Hitachi_8h.html#a6c4102910d21dc838efee1fb2477218d',1,'ir_Hitachi.h']]], + ['khitachiac344maxtemp_5561',['kHitachiAc344MaxTemp',['../ir__Hitachi_8h.html#a4a394fc23fb119ba67e3ca53e4b88f7f',1,'ir_Hitachi.h']]], + ['khitachiac344mintemp_5562',['kHitachiAc344MinTemp',['../ir__Hitachi_8h.html#a7322f7769c9c1af2311180474e5b0f57',1,'ir_Hitachi.h']]], + ['khitachiac344statelength_5563',['kHitachiAc344StateLength',['../IRremoteESP8266_8h.html#a2192f6b7c353f7f124dff3b57eab0659',1,'IRremoteESP8266.h']]], + ['khitachiac344swinghauto_5564',['kHitachiAc344SwingHAuto',['../ir__Hitachi_8h.html#a4f93eccee6e3e5f5c49c84034ca25af3',1,'ir_Hitachi.h']]], + ['khitachiac344swinghbyte_5565',['kHitachiAc344SwingHByte',['../ir__Hitachi_8h.html#a132b64e007043ade4f209b0416fd5f4d',1,'ir_Hitachi.h']]], + ['khitachiac344swinghleft_5566',['kHitachiAc344SwingHLeft',['../ir__Hitachi_8h.html#af714a1eb296b05f3fc8167aff5419764',1,'ir_Hitachi.h']]], + ['khitachiac344swinghleftmax_5567',['kHitachiAc344SwingHLeftMax',['../ir__Hitachi_8h.html#ad0c5636ac0ccfd7e9cd087101bd5d204',1,'ir_Hitachi.h']]], + ['khitachiac344swinghmiddle_5568',['kHitachiAc344SwingHMiddle',['../ir__Hitachi_8h.html#a7e4372e02d72723049b378e955070c21',1,'ir_Hitachi.h']]], + ['khitachiac344swinghoffset_5569',['kHitachiAc344SwingHOffset',['../ir__Hitachi_8h.html#a7e8e57b0b37f20a502eb66f13980989c',1,'ir_Hitachi.h']]], + ['khitachiac344swinghright_5570',['kHitachiAc344SwingHRight',['../ir__Hitachi_8h.html#af4b087dec06cfd86920dbf9df22aca63',1,'ir_Hitachi.h']]], + ['khitachiac344swinghrightmax_5571',['kHitachiAc344SwingHRightMax',['../ir__Hitachi_8h.html#a90cffc131be89a36d352c462403f689f',1,'ir_Hitachi.h']]], + ['khitachiac344swinghsize_5572',['kHitachiAc344SwingHSize',['../ir__Hitachi_8h.html#aadd389cd818207920c1e8efef53fde91',1,'ir_Hitachi.h']]], + ['khitachiac344swingvbyte_5573',['kHitachiAc344SwingVByte',['../ir__Hitachi_8h.html#ae40211be39e522ebf9b580b3481f49f3',1,'ir_Hitachi.h']]], + ['khitachiac344swingvoffset_5574',['kHitachiAc344SwingVOffset',['../ir__Hitachi_8h.html#a8b38ef096697f70bdba8f4bd2799e148',1,'ir_Hitachi.h']]], + ['khitachiac3bitmark_5575',['kHitachiAc3BitMark',['../ir__Hitachi_8cpp.html#a68269a88e02a3030749061e5f28f74cc',1,'ir_Hitachi.cpp']]], + ['khitachiac3bits_5576',['kHitachiAc3Bits',['../IRremoteESP8266_8h.html#ac26b896cdc17018269fa881e10e3aabb',1,'IRremoteESP8266.h']]], + ['khitachiac3hdrmark_5577',['kHitachiAc3HdrMark',['../ir__Hitachi_8cpp.html#af0a80a66094e67b4a78e8dfa539cd22f',1,'ir_Hitachi.cpp']]], + ['khitachiac3hdrspace_5578',['kHitachiAc3HdrSpace',['../ir__Hitachi_8cpp.html#aca4dc0b851c69a5e640337d68eb6f412',1,'ir_Hitachi.cpp']]], + ['khitachiac3minbits_5579',['kHitachiAc3MinBits',['../IRremoteESP8266_8h.html#a66ebaf70d2b4018371825c9cd3078a42',1,'IRremoteESP8266.h']]], + ['khitachiac3minstatelength_5580',['kHitachiAc3MinStateLength',['../IRremoteESP8266_8h.html#ac3becb270bfddaa1c64b1f8582dfc902',1,'IRremoteESP8266.h']]], + ['khitachiac3onespace_5581',['kHitachiAc3OneSpace',['../ir__Hitachi_8cpp.html#a0e630e38b4bffd5ec931153c20e41d97',1,'ir_Hitachi.cpp']]], + ['khitachiac3statelength_5582',['kHitachiAc3StateLength',['../IRremoteESP8266_8h.html#a9cc230bac4f902d46049c7b2c2fdbd3d',1,'IRremoteESP8266.h']]], + ['khitachiac3zerospace_5583',['kHitachiAc3ZeroSpace',['../ir__Hitachi_8cpp.html#a7cf96a2734bcc9a5eb390b8647666925',1,'ir_Hitachi.cpp']]], + ['khitachiac424bitmark_5584',['kHitachiAc424BitMark',['../ir__Hitachi_8cpp.html#acf5f9d83873a74688eb0413708e26eed',1,'ir_Hitachi.cpp']]], + ['khitachiac424bits_5585',['kHitachiAc424Bits',['../IRremoteESP8266_8h.html#ab466e28528a0d688a1b91e8af69025cb',1,'IRremoteESP8266.h']]], + ['khitachiac424buttonbyte_5586',['kHitachiAc424ButtonByte',['../ir__Hitachi_8h.html#a057159edca95f9a000c80c7059919e83',1,'ir_Hitachi.h']]], + ['khitachiac424buttonfan_5587',['kHitachiAc424ButtonFan',['../ir__Hitachi_8h.html#a4aa278fb1983213a2506c71debe035aa',1,'ir_Hitachi.h']]], + ['khitachiac424buttonpowermode_5588',['kHitachiAc424ButtonPowerMode',['../ir__Hitachi_8h.html#a2dd37a36c6ad928ad0c3485ae4ea78fd',1,'ir_Hitachi.h']]], + ['khitachiac424buttonswingh_5589',['kHitachiAc424ButtonSwingH',['../ir__Hitachi_8h.html#af3a0d9499fab327bc7dfb5d57562a946',1,'ir_Hitachi.h']]], + ['khitachiac424buttonswingv_5590',['kHitachiAc424ButtonSwingV',['../ir__Hitachi_8h.html#a59d8e5407daf37d38e0c76ab3abdec9d',1,'ir_Hitachi.h']]], + ['khitachiac424buttontempdown_5591',['kHitachiAc424ButtonTempDown',['../ir__Hitachi_8h.html#ad909ee0bc97e24aa70ff6ecd1cffe6c2',1,'ir_Hitachi.h']]], + ['khitachiac424buttontempup_5592',['kHitachiAc424ButtonTempUp',['../ir__Hitachi_8h.html#ac8885804fb276f6327beb2018b204359',1,'ir_Hitachi.h']]], + ['khitachiac424cool_5593',['kHitachiAc424Cool',['../ir__Hitachi_8h.html#a64c1e01c222e6dec001a7052e822d64f',1,'ir_Hitachi.h']]], + ['khitachiac424dry_5594',['kHitachiAc424Dry',['../ir__Hitachi_8h.html#a56bfde42914bc92f47929179cddcbdf3',1,'ir_Hitachi.h']]], + ['khitachiac424fan_5595',['kHitachiAc424Fan',['../ir__Hitachi_8h.html#a35db6fdcedeb3de0ffb0bb72f1e60a0b',1,'ir_Hitachi.h']]], + ['khitachiac424fanauto_5596',['kHitachiAc424FanAuto',['../ir__Hitachi_8h.html#add1ec95cfd4e388f90154b25410471d0',1,'ir_Hitachi.h']]], + ['khitachiac424fanbyte_5597',['kHitachiAc424FanByte',['../ir__Hitachi_8h.html#aa4758708fe16d13cf6f50b7aa9e12bf6',1,'ir_Hitachi.h']]], + ['khitachiac424fanhigh_5598',['kHitachiAc424FanHigh',['../ir__Hitachi_8h.html#aacabc41baea6c3ddf711424a400144a3',1,'ir_Hitachi.h']]], + ['khitachiac424fanlow_5599',['kHitachiAc424FanLow',['../ir__Hitachi_8h.html#acae66b060db5cd03732ccbf808c6049e',1,'ir_Hitachi.h']]], + ['khitachiac424fanmax_5600',['kHitachiAc424FanMax',['../ir__Hitachi_8h.html#a6298e6dee6ff9f5fc57cfc9ccf30c073',1,'ir_Hitachi.h']]], + ['khitachiac424fanmaxdry_5601',['kHitachiAc424FanMaxDry',['../ir__Hitachi_8h.html#af770b29d838610b87463551444548ac0',1,'ir_Hitachi.h']]], + ['khitachiac424fanmedium_5602',['kHitachiAc424FanMedium',['../ir__Hitachi_8h.html#a3d6479f2e76bd84eeda9f5c0772210c5',1,'ir_Hitachi.h']]], + ['khitachiac424fanmin_5603',['kHitachiAc424FanMin',['../ir__Hitachi_8h.html#aacf1d4b99d89a0e24622ca02402c683b',1,'ir_Hitachi.h']]], + ['khitachiac424fantemp_5604',['kHitachiAc424FanTemp',['../ir__Hitachi_8h.html#a874362698fad488da1a477c4f99923aa',1,'ir_Hitachi.h']]], + ['khitachiac424hdrmark_5605',['kHitachiAc424HdrMark',['../ir__Hitachi_8cpp.html#a7b1dcaa7569237831b08ea061fd403fb',1,'ir_Hitachi.cpp']]], + ['khitachiac424hdrspace_5606',['kHitachiAc424HdrSpace',['../ir__Hitachi_8cpp.html#a9309b801d147dd3eba96ed15245f7445',1,'ir_Hitachi.cpp']]], + ['khitachiac424heat_5607',['kHitachiAc424Heat',['../ir__Hitachi_8h.html#a5cfd38c9e7aa2c39dfa38b1ef4b33b4c',1,'ir_Hitachi.h']]], + ['khitachiac424ldrmark_5608',['kHitachiAc424LdrMark',['../ir__Hitachi_8cpp.html#a0e2a88cb5930fb9726a453bdefe33bae',1,'ir_Hitachi.cpp']]], + ['khitachiac424ldrspace_5609',['kHitachiAc424LdrSpace',['../ir__Hitachi_8cpp.html#ad6285b55ed74e0e1087c3eb12d63b39c',1,'ir_Hitachi.cpp']]], + ['khitachiac424maxtemp_5610',['kHitachiAc424MaxTemp',['../ir__Hitachi_8h.html#a22574044b5a9163aca1f0581b9fa9241',1,'ir_Hitachi.h']]], + ['khitachiac424mintemp_5611',['kHitachiAc424MinTemp',['../ir__Hitachi_8h.html#a3d4311f1f28bbe31a22b80556e678b22',1,'ir_Hitachi.h']]], + ['khitachiac424modebyte_5612',['kHitachiAc424ModeByte',['../ir__Hitachi_8h.html#a3c6e0d27a95d94142360efa19a342c99',1,'ir_Hitachi.h']]], + ['khitachiac424onespace_5613',['kHitachiAc424OneSpace',['../ir__Hitachi_8cpp.html#a9b9cd22801f17acac593a8bcf334fd71',1,'ir_Hitachi.cpp']]], + ['khitachiac424powerbyte_5614',['kHitachiAc424PowerByte',['../ir__Hitachi_8h.html#a815e6761376ca4eae649ec837d55dc25',1,'ir_Hitachi.h']]], + ['khitachiac424poweroff_5615',['kHitachiAc424PowerOff',['../ir__Hitachi_8h.html#affc2d076cc0de329466ecbde7186d4eb',1,'ir_Hitachi.h']]], + ['khitachiac424poweron_5616',['kHitachiAc424PowerOn',['../ir__Hitachi_8h.html#a922478904efd86c6ecf7dabec3dd759f',1,'ir_Hitachi.h']]], + ['khitachiac424statelength_5617',['kHitachiAc424StateLength',['../IRremoteESP8266_8h.html#aff17d9c0ccf683895d2c868094679f0a',1,'IRremoteESP8266.h']]], + ['khitachiac424tempbyte_5618',['kHitachiAc424TempByte',['../ir__Hitachi_8h.html#a5de1ae606d6a34e24420b08a73542b94',1,'ir_Hitachi.h']]], + ['khitachiac424tempoffset_5619',['kHitachiAc424TempOffset',['../ir__Hitachi_8h.html#a3adb47220c4c72a62d9296092047900f',1,'ir_Hitachi.h']]], + ['khitachiac424tempsize_5620',['kHitachiAc424TempSize',['../ir__Hitachi_8h.html#ae6738f4a4476e5f34efbeb52e8c413de',1,'ir_Hitachi.h']]], + ['khitachiac424zerospace_5621',['kHitachiAc424ZeroSpace',['../ir__Hitachi_8cpp.html#a0f2032ac476bf344df31dc9351b2b98a',1,'ir_Hitachi.cpp']]], + ['khitachiacauto_5622',['kHitachiAcAuto',['../ir__Hitachi_8h.html#af8c74a8388361162b93339e1b0bc94d9',1,'ir_Hitachi.h']]], + ['khitachiacautotemp_5623',['kHitachiAcAutoTemp',['../ir__Hitachi_8h.html#aaa28bb683fefc065cb115fbfb66994ec',1,'ir_Hitachi.h']]], + ['khitachiacbitmark_5624',['kHitachiAcBitMark',['../ir__Hitachi_8cpp.html#a0993bf3d527a12bfe51c7bbfcf788c59',1,'ir_Hitachi.cpp']]], + ['khitachiacbits_5625',['kHitachiAcBits',['../IRremoteESP8266_8h.html#aec91e459b1e52765c700f8f7a4723f3b',1,'IRremoteESP8266.h']]], + ['khitachiaccool_5626',['kHitachiAcCool',['../ir__Hitachi_8h.html#a2b40b07601fdf8b038c97bb8bd2bec59',1,'ir_Hitachi.h']]], + ['khitachiacdefaultrepeat_5627',['kHitachiAcDefaultRepeat',['../IRremoteESP8266_8h.html#acc8510281d2ff9a808501d375c03ba21',1,'IRremoteESP8266.h']]], + ['khitachiacdry_5628',['kHitachiAcDry',['../ir__Hitachi_8h.html#a19730b13fca736392600580c156ae3c3',1,'ir_Hitachi.h']]], + ['khitachiacfan_5629',['kHitachiAcFan',['../ir__Hitachi_8h.html#a69626883b6fdbd3ccd26bb3123bf1883',1,'ir_Hitachi.h']]], + ['khitachiacfanauto_5630',['kHitachiAcFanAuto',['../ir__Hitachi_8h.html#a6be6f6eae193e784133be63d7cc5d75e',1,'ir_Hitachi.h']]], + ['khitachiacfanhigh_5631',['kHitachiAcFanHigh',['../ir__Hitachi_8h.html#a85ef905a1d3704237141f07defc128f5',1,'ir_Hitachi.h']]], + ['khitachiacfanlow_5632',['kHitachiAcFanLow',['../ir__Hitachi_8h.html#a0add8c3a3d00a81fcc3279af78256de2',1,'ir_Hitachi.h']]], + ['khitachiacfanmed_5633',['kHitachiAcFanMed',['../ir__Hitachi_8h.html#ac88b4cfdce5d69bf07316ddd716c2c11',1,'ir_Hitachi.h']]], + ['khitachiacfreq_5634',['kHitachiAcFreq',['../ir__Hitachi_8h.html#a443eaa664017d7b671bef0e9aa2d643b',1,'ir_Hitachi.h']]], + ['khitachiachdrmark_5635',['kHitachiAcHdrMark',['../ir__Hitachi_8cpp.html#aefe34d17f5c72ee05afb9a6302a450da',1,'ir_Hitachi.cpp']]], + ['khitachiachdrspace_5636',['kHitachiAcHdrSpace',['../ir__Hitachi_8cpp.html#a4a4352723f119ea070be1eba2aafe36b',1,'ir_Hitachi.cpp']]], + ['khitachiacheat_5637',['kHitachiAcHeat',['../ir__Hitachi_8h.html#add2498e77e5585fd8c82a553bb0c22c0',1,'ir_Hitachi.h']]], + ['khitachiacmaxtemp_5638',['kHitachiAcMaxTemp',['../ir__Hitachi_8h.html#a63e17171c40d770d25f24d018aee2c4c',1,'ir_Hitachi.h']]], + ['khitachiacmingap_5639',['kHitachiAcMinGap',['../ir__Hitachi_8cpp.html#a14016b9110c11423c628c8e220e50864',1,'ir_Hitachi.cpp']]], + ['khitachiacmintemp_5640',['kHitachiAcMinTemp',['../ir__Hitachi_8h.html#a9b4f3ea50cc0491f10ff8dc8eabb3ecd',1,'ir_Hitachi.h']]], + ['khitachiaconespace_5641',['kHitachiAcOneSpace',['../ir__Hitachi_8cpp.html#a79a79aaf52a05c021621335586dd928f',1,'ir_Hitachi.cpp']]], + ['khitachiacpoweroffset_5642',['kHitachiAcPowerOffset',['../ir__Hitachi_8h.html#a30062f0646ac63c3612d13f98211e36b',1,'ir_Hitachi.h']]], + ['khitachiacstatelength_5643',['kHitachiAcStateLength',['../IRremoteESP8266_8h.html#a8bef76bac826afbbc51c2a867af15ed8',1,'IRremoteESP8266.h']]], + ['khitachiacswingoffset_5644',['kHitachiAcSwingOffset',['../ir__Hitachi_8h.html#aac1fcff513a4eca2aeb4f13c739165e2',1,'ir_Hitachi.h']]], + ['khitachiaczerospace_5645',['kHitachiAcZeroSpace',['../ir__Hitachi_8cpp.html#a0b03a4abb11d69a8b8da56ca2abc50c8',1,'ir_Hitachi.cpp']]], + ['kholdstr_5646',['kHoldStr',['../IRtext_8cpp.html#a86fd1f86e4a513603449e90a47500986',1,'kHoldStr(): IRtext.cpp'],['../IRtext_8h.html#adb2d0f01f1429b0f3eb7193519fe3d6e',1,'kHoldStr(): IRtext.cpp']]], + ['khoursstr_5647',['kHoursStr',['../IRtext_8cpp.html#ae94260daddf2ea56e54d56bbad66526c',1,'kHoursStr(): IRtext.cpp'],['../IRtext_8h.html#a10ecbc18040f0d0ed88b728c18b0a161',1,'kHoursStr(): IRtext.cpp']]], + ['khourstr_5648',['kHourStr',['../IRtext_8cpp.html#a1d25a0bf2c8a638fff1557a0c5637977',1,'kHourStr(): IRtext.cpp'],['../IRtext_8h.html#a67a94ecb5a557b5335a8085cf1d8cdd6',1,'kHourStr(): IRtext.cpp']]], + ['khumidstr_5649',['kHumidStr',['../IRtext_8cpp.html#aae236cd2e7ed4961360fe687fe38170d',1,'kHumidStr(): IRtext.cpp'],['../IRtext_8h.html#a25365e722200ac40d581c4f585f9ae2f',1,'kHumidStr(): IRtext.cpp']]], + ['kidlestate_5650',['kIdleState',['../IRrecv_8h.html#aabba6fe7d7b97c45173eb7781a5d99bf',1,'IRrecv.h']]], + ['kifeelstr_5651',['kIFeelStr',['../IRtext_8cpp.html#a3c7368d9138477f0eac2a6249ba2606b',1,'kIFeelStr(): IRtext.cpp'],['../IRtext_8h.html#a40f90b18252e14a73dd91527f621e35f',1,'kIFeelStr(): IRtext.cpp']]], + ['kinaxbitmark_5652',['kInaxBitMark',['../ir__Inax_8cpp.html#a84553819866dbfcfad8cba87f6c02e04',1,'ir_Inax.cpp']]], + ['kinaxbits_5653',['kInaxBits',['../IRremoteESP8266_8h.html#af8441f25b32d113096adeaff331c126a',1,'IRremoteESP8266.h']]], + ['kinaxhdrmark_5654',['kInaxHdrMark',['../ir__Inax_8cpp.html#ac467a96d91b6266c3ce9a2a4ec2a8b44',1,'ir_Inax.cpp']]], + ['kinaxhdrspace_5655',['kInaxHdrSpace',['../ir__Inax_8cpp.html#a6ddcc8ca7a5d05cee91e57b3e69cca33',1,'ir_Inax.cpp']]], + ['kinaxmingap_5656',['kInaxMinGap',['../ir__Inax_8cpp.html#a600f49303a77fbdc1d77aae2abe9b9aa',1,'ir_Inax.cpp']]], + ['kinaxminrepeat_5657',['kInaxMinRepeat',['../IRremoteESP8266_8h.html#a37a3d0ae51a6ce850a424fe77d5b22d2',1,'IRremoteESP8266.h']]], + ['kinaxonespace_5658',['kInaxOneSpace',['../ir__Inax_8cpp.html#aeb77e3a51838547a29c1b343eba4c7ef',1,'ir_Inax.cpp']]], + ['kinaxtick_5659',['kInaxTick',['../ir__Inax_8cpp.html#ad437f0beac0893853cc9d5cc214b03c6',1,'ir_Inax.cpp']]], + ['kinaxzerospace_5660',['kInaxZeroSpace',['../ir__Inax_8cpp.html#a115f1f061362c1c3c41e3bb20ea7e1c6',1,'ir_Inax.cpp']]], + ['kinsidestr_5661',['kInsideStr',['../IRtext_8cpp.html#aa94c7a9b472bcd2297b43a5b4008bc51',1,'kInsideStr(): IRtext.cpp'],['../IRtext_8h.html#a55c406749cb48970c11c58ec83ef97eb',1,'kInsideStr(): IRtext.cpp']]], + ['kionstr_5662',['kIonStr',['../IRtext_8cpp.html#afc36ce4beed72e662a8d9d1473dad235',1,'kIonStr(): IRtext.cpp'],['../IRtext_8h.html#add28006fe2f8ac70db1b5048c85be84b',1,'kIonStr(): IRtext.cpp']]], + ['kjvcbitmark_5663',['kJvcBitMark',['../ir__JVC_8cpp.html#a23c11d77431d37bba18776f9341c767f',1,'ir_JVC.cpp']]], + ['kjvcbitmarkticks_5664',['kJvcBitMarkTicks',['../ir__JVC_8cpp.html#aad7cf432a9bd0d2b4df66d5f903a70dd',1,'ir_JVC.cpp']]], + ['kjvcbits_5665',['kJvcBits',['../IRremoteESP8266_8h.html#a7c28467832e7480864a6be0ce87c608f',1,'IRremoteESP8266.h']]], + ['kjvchdrmark_5666',['kJvcHdrMark',['../ir__JVC_8cpp.html#a60d81ad0066288b602054bd24a912f1f',1,'ir_JVC.cpp']]], + ['kjvchdrmarkticks_5667',['kJvcHdrMarkTicks',['../ir__JVC_8cpp.html#abb12fba45b7a366e23849d693953e749',1,'ir_JVC.cpp']]], + ['kjvchdrspace_5668',['kJvcHdrSpace',['../ir__JVC_8cpp.html#a5444718f66ba8b43c1d7d99f7b378a0d',1,'ir_JVC.cpp']]], + ['kjvchdrspaceticks_5669',['kJvcHdrSpaceTicks',['../ir__JVC_8cpp.html#ae7cf6cb7b5ea5fe17a9b182d1ef3b008',1,'ir_JVC.cpp']]], + ['kjvcmingap_5670',['kJvcMinGap',['../ir__JVC_8cpp.html#ac19d8396c10adb687a883d016ec43aa5',1,'ir_JVC.cpp']]], + ['kjvcmingapticks_5671',['kJvcMinGapTicks',['../ir__JVC_8cpp.html#a525e7d672b148c02bdca1f66ab92e6c7',1,'ir_JVC.cpp']]], + ['kjvconespace_5672',['kJvcOneSpace',['../ir__JVC_8cpp.html#a8befef1d03f3a09541c2612c66c0256f',1,'ir_JVC.cpp']]], + ['kjvconespaceticks_5673',['kJvcOneSpaceTicks',['../ir__JVC_8cpp.html#a20d4f7737d71bdbec58694e775669df9',1,'ir_JVC.cpp']]], + ['kjvcrptlength_5674',['kJvcRptLength',['../ir__JVC_8cpp.html#a3896e40881e70c63234fecb88375b5a1',1,'ir_JVC.cpp']]], + ['kjvcrptlengthticks_5675',['kJvcRptLengthTicks',['../ir__JVC_8cpp.html#a75e03cf5739ab0ba67e5cfa426776d16',1,'ir_JVC.cpp']]], + ['kjvctick_5676',['kJvcTick',['../ir__JVC_8cpp.html#acd5a2ba251824cac5311adcc9a813b1a',1,'ir_JVC.cpp']]], + ['kjvczerospace_5677',['kJvcZeroSpace',['../ir__JVC_8cpp.html#a67c790b909f82e044b8c4e7227d9c189',1,'ir_JVC.cpp']]], + ['kjvczerospaceticks_5678',['kJvcZeroSpaceTicks',['../ir__JVC_8cpp.html#a0a5319df3b1e01741cd35a37087342f5',1,'ir_JVC.cpp']]], + ['kkelvinatorauto_5679',['kKelvinatorAuto',['../ir__Kelvinator_8h.html#a879b005fc5493a693b05e3bb7cbc8fbf',1,'ir_Kelvinator.h']]], + ['kkelvinatorautotemp_5680',['kKelvinatorAutoTemp',['../ir__Kelvinator_8h.html#afa9e7ea8c9fb86cb02358cc8221733b0',1,'ir_Kelvinator.h']]], + ['kkelvinatorbasicfanmax_5681',['kKelvinatorBasicFanMax',['../ir__Kelvinator_8h.html#a10624389f033451cf9a6f4530c2dfb98',1,'ir_Kelvinator.h']]], + ['kkelvinatorbasicfansize_5682',['kKelvinatorBasicFanSize',['../ir__Kelvinator_8cpp.html#a35ffe10c5c1b834703fe44c5eeeb4c8f',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbitmark_5683',['kKelvinatorBitMark',['../ir__Kelvinator_8cpp.html#a2014f9f92f1e24a04341398e7e673807',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbitmarkticks_5684',['kKelvinatorBitMarkTicks',['../ir__Kelvinator_8cpp.html#a2d6579257ab7f185e4f0fecdbdf03835',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbits_5685',['kKelvinatorBits',['../IRremoteESP8266_8h.html#acfa71cb3caf4964829bb1f557dee5b86',1,'IRremoteESP8266.h']]], + ['kkelvinatorchecksumstart_5686',['kKelvinatorChecksumStart',['../ir__Kelvinator_8cpp.html#a0afa7cec1db6a5f46c1b30d7ce718ae6',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcmdfooter_5687',['kKelvinatorCmdFooter',['../ir__Kelvinator_8cpp.html#ad2361e09472fa03376b447114a19513f',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcmdfooterbits_5688',['kKelvinatorCmdFooterBits',['../ir__Kelvinator_8cpp.html#af6c85d3b30a5949da53ad9400734f203',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcool_5689',['kKelvinatorCool',['../ir__Kelvinator_8h.html#ad49a2e457470d6e16d001cdae3215606',1,'ir_Kelvinator.h']]], + ['kkelvinatordefaultrepeat_5690',['kKelvinatorDefaultRepeat',['../IRremoteESP8266_8h.html#a94c968c5cc929f189b8e578d2f55b132',1,'IRremoteESP8266.h']]], + ['kkelvinatordry_5691',['kKelvinatorDry',['../ir__Kelvinator_8h.html#a181b3d10b522f9afb29706da42afea55',1,'ir_Kelvinator.h']]], + ['kkelvinatorfan_5692',['kKelvinatorFan',['../ir__Kelvinator_8h.html#a8d6d97be2fd8a5aefa1319d3f662a50c',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanauto_5693',['kKelvinatorFanAuto',['../ir__Kelvinator_8h.html#ac4994c36634ca0ad8791807c9a992976',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanmax_5694',['kKelvinatorFanMax',['../ir__Kelvinator_8h.html#a889ce17d112d1a61420e1064d72c583a',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanmin_5695',['kKelvinatorFanMin',['../ir__Kelvinator_8h.html#a36a9422e2e6c6b7a87e8b2deffd1b189',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanoffset_5696',['kKelvinatorFanOffset',['../ir__Kelvinator_8cpp.html#a4988bb98a4f8798c0b927e981667cfbd',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorfansize_5697',['kKelvinatorFanSize',['../ir__Kelvinator_8cpp.html#a286636ba83aceab9c8518878a6d7209e',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorgapspace_5698',['kKelvinatorGapSpace',['../ir__Kelvinator_8cpp.html#abf66116a235a9d05089182f2f7fd7640',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorgapspaceticks_5699',['kKelvinatorGapSpaceTicks',['../ir__Kelvinator_8cpp.html#a6a81fb4c1cf1ad34f99f3ca87ab74a5c',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrmark_5700',['kKelvinatorHdrMark',['../ir__Kelvinator_8cpp.html#a413e824c6bdd4778e70f496917b3fe30',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrmarkticks_5701',['kKelvinatorHdrMarkTicks',['../ir__Kelvinator_8cpp.html#a8ad828958071c75a80928abfb916c0df',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrspace_5702',['kKelvinatorHdrSpace',['../ir__Kelvinator_8cpp.html#a9cab23fbd5ba62714fda24765db0e7d1',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrspaceticks_5703',['kKelvinatorHdrSpaceTicks',['../ir__Kelvinator_8cpp.html#ab4fbf899dcb2c2d510055215617d5b44',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorheat_5704',['kKelvinatorHeat',['../ir__Kelvinator_8h.html#a080eade5648791e37c76af7a52e85731',1,'ir_Kelvinator.h']]], + ['kkelvinatorionfilteroffset_5705',['kKelvinatorIonFilterOffset',['../ir__Kelvinator_8cpp.html#a5cbdc907f0cb6a47d0c548148933067b',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorlightoffset_5706',['kKelvinatorLightOffset',['../ir__Kelvinator_8cpp.html#a7e757add18951b8e36c2065c5dbefc24',1,'ir_Kelvinator.cpp']]], + ['kkelvinatormaxtemp_5707',['kKelvinatorMaxTemp',['../ir__Kelvinator_8h.html#a14933442e718db1a87bae5d076ad228d',1,'ir_Kelvinator.h']]], + ['kkelvinatormintemp_5708',['kKelvinatorMinTemp',['../ir__Kelvinator_8h.html#a98871ce825dbbe80d072f25253142879',1,'ir_Kelvinator.h']]], + ['kkelvinatormodeoffset_5709',['kKelvinatorModeOffset',['../ir__Kelvinator_8cpp.html#a6a52d11326d5f83653c510393bb2a518',1,'ir_Kelvinator.cpp']]], + ['kkelvinatoronespace_5710',['kKelvinatorOneSpace',['../ir__Kelvinator_8cpp.html#aae5a009282517309b8fdbfdaced9d659',1,'ir_Kelvinator.cpp']]], + ['kkelvinatoronespaceticks_5711',['kKelvinatorOneSpaceTicks',['../ir__Kelvinator_8cpp.html#ac907f4495debdcaf680f6e6941b844d5',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorpoweroffset_5712',['kKelvinatorPowerOffset',['../ir__Kelvinator_8cpp.html#a5a9591e2dd98f68ad6f562e199b1a304',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorquietoffset_5713',['kKelvinatorQuietOffset',['../ir__Kelvinator_8cpp.html#ad354be321ea41c51ead876fd30674546',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorstatelength_5714',['kKelvinatorStateLength',['../IRremoteESP8266_8h.html#af68545e8c2fe9af3719fb74c5d21f0c9',1,'IRremoteESP8266.h']]], + ['kkelvinatortick_5715',['kKelvinatorTick',['../ir__Kelvinator_8cpp.html#a846cbb5609b1dff139a90487000c7393',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorturbooffset_5716',['kKelvinatorTurboOffset',['../ir__Kelvinator_8cpp.html#a21987b6f00c7f2e9bba94c59bc5b804b',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswinghoffset_5717',['kKelvinatorVentSwingHOffset',['../ir__Kelvinator_8cpp.html#a551df2c1e21764f12030f6bfa6d5942d',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswingoffset_5718',['kKelvinatorVentSwingOffset',['../ir__Kelvinator_8cpp.html#a38012bf9daa0c362a9007107183391ef',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswingvoffset_5719',['kKelvinatorVentSwingVOffset',['../ir__Kelvinator_8cpp.html#a64d3767b464d4fe2543560cf5a2a5b21',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorxfanoffset_5720',['kKelvinatorXfanOffset',['../ir__Kelvinator_8cpp.html#a4417448475405306f10166fc9cd98054',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorzerospace_5721',['kKelvinatorZeroSpace',['../ir__Kelvinator_8cpp.html#a10469f76f50285a6084bb088fd601dea',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorzerospaceticks_5722',['kKelvinatorZeroSpaceTicks',['../ir__Kelvinator_8cpp.html#a0abc0fdc3d9ac9f12133a46e95d69432',1,'ir_Kelvinator.cpp']]], + ['klasertagbits_5723',['kLasertagBits',['../IRremoteESP8266_8h.html#a3ea0e89a8b6a3ffa4a2d346abeed851e',1,'IRremoteESP8266.h']]], + ['klasertagdelta_5724',['kLasertagDelta',['../ir__Lasertag_8cpp.html#a5c0e8e9c6dec0480c09fcd339ed62257',1,'ir_Lasertag.cpp']]], + ['klasertagexcess_5725',['kLasertagExcess',['../ir__Lasertag_8cpp.html#afa77dc5a431a8d851320e7623378983e',1,'ir_Lasertag.cpp']]], + ['klasertagmingap_5726',['kLasertagMinGap',['../ir__Lasertag_8cpp.html#a33762e2c44dac34e00d255b41d9f2822',1,'ir_Lasertag.cpp']]], + ['klasertagminrepeat_5727',['kLasertagMinRepeat',['../IRremoteESP8266_8h.html#a9b36135c3df24eab232a5edac8c58c5e',1,'IRremoteESP8266.h']]], + ['klasertagminsamples_5728',['kLasertagMinSamples',['../ir__Lasertag_8cpp.html#acbf98970106cadb43e0703ae2caab0c1',1,'ir_Lasertag.cpp']]], + ['klasertagtick_5729',['kLasertagTick',['../ir__Lasertag_8cpp.html#a878b5d53379f8b1b21dfe19f1f83a626',1,'ir_Lasertag.cpp']]], + ['klasertagtolerance_5730',['kLasertagTolerance',['../ir__Lasertag_8cpp.html#a6146bcf378515d31330b3fec5c967346',1,'ir_Lasertag.cpp']]], + ['klaststr_5731',['kLastStr',['../IRtext_8cpp.html#ad7c8430b935afb7aec114788a9c0bf7d',1,'kLastStr(): IRtext.cpp'],['../IRtext_8h.html#aa9ffd7c6e6921607653ed5dc1fea4f32',1,'kLastStr(): IRtext.cpp']]], + ['kleftmaxstr_5732',['kLeftMaxStr',['../IRtext_8cpp.html#a1a82999b6eb3b6637f51bb8ce6a46efd',1,'kLeftMaxStr(): IRtext.cpp'],['../IRtext_8h.html#ab2fd48f052fcfed8ca779ca499edcdbf',1,'kLeftMaxStr(): IRtext.cpp']]], + ['kleftstr_5733',['kLeftStr',['../IRtext_8cpp.html#a0bb005966f2ff2da12a542e713f7f1f2',1,'kLeftStr(): IRtext.cpp'],['../IRtext_8h.html#a001f11495c7c9452ceec68455ae524bf',1,'kLeftStr(): IRtext.cpp']]], + ['klegopfbitmark_5734',['kLegoPfBitMark',['../ir__Lego_8cpp.html#afdf76660f62bfefb4a813d57cd84b590',1,'ir_Lego.cpp']]], + ['klegopfbits_5735',['kLegoPfBits',['../IRremoteESP8266_8h.html#a8a7c7659250a81c7c84fc739eafed13e',1,'IRremoteESP8266.h']]], + ['klegopfhdrspace_5736',['kLegoPfHdrSpace',['../ir__Lego_8cpp.html#a140e8707900bfd4e3a9e2722a6b0bfb3',1,'ir_Lego.cpp']]], + ['klegopfmincommandlength_5737',['kLegoPfMinCommandLength',['../ir__Lego_8cpp.html#ad9a0c5184cc422ec1b32edf58c52d2b1',1,'ir_Lego.cpp']]], + ['klegopfminrepeat_5738',['kLegoPfMinRepeat',['../IRremoteESP8266_8h.html#a2614cf3cb840f028eb1dc684aeb1272c',1,'IRremoteESP8266.h']]], + ['klegopfonespace_5739',['kLegoPfOneSpace',['../ir__Lego_8cpp.html#a59a41085f2e8f81e1019fd40782269e3',1,'ir_Lego.cpp']]], + ['klegopfzerospace_5740',['kLegoPfZeroSpace',['../ir__Lego_8cpp.html#ada07e8aaf79cf58c46b301a410d9fb3e',1,'ir_Lego.cpp']]], + ['klg2bitmark_5741',['kLg2BitMark',['../ir__LG_8cpp.html#abf4db4647161db6fb2548b5200c41843',1,'ir_LG.cpp']]], + ['klg2bitmarkticks_5742',['kLg2BitMarkTicks',['../ir__LG_8cpp.html#aae477dcb68b9c5f1b12adf832eb388a1',1,'ir_LG.cpp']]], + ['klg2hdrmark_5743',['kLg2HdrMark',['../ir__LG_8cpp.html#a5ca50077fba2d5130220255e1659e0c3',1,'ir_LG.cpp']]], + ['klg2hdrmarkticks_5744',['kLg2HdrMarkTicks',['../ir__LG_8cpp.html#adb636fb6b634c651364ae954d31b5692',1,'ir_LG.cpp']]], + ['klg2hdrspace_5745',['kLg2HdrSpace',['../ir__LG_8cpp.html#a6637da052fea9320e97cff261f219cdb',1,'ir_LG.cpp']]], + ['klg2hdrspaceticks_5746',['kLg2HdrSpaceTicks',['../ir__LG_8cpp.html#abd2f843416070a93587d07e4d32f1eb5',1,'ir_LG.cpp']]], + ['klg32bits_5747',['kLg32Bits',['../IRremoteESP8266_8h.html#ae3c458814d7221b66d2f267cb2663bd2',1,'IRremoteESP8266.h']]], + ['klg32hdrmark_5748',['kLg32HdrMark',['../ir__LG_8cpp.html#a26cb3fb11b1a0bf0815868767e50f31b',1,'ir_LG.cpp']]], + ['klg32hdrmarkticks_5749',['kLg32HdrMarkTicks',['../ir__LG_8cpp.html#aded50973c0a938d455c1537cb240d5e9',1,'ir_LG.cpp']]], + ['klg32hdrspace_5750',['kLg32HdrSpace',['../ir__LG_8cpp.html#a59ddf2070642615e162c85b7575aff76',1,'ir_LG.cpp']]], + ['klg32hdrspaceticks_5751',['kLg32HdrSpaceTicks',['../ir__LG_8cpp.html#aa029c2c83a96f1ff02610eddd6b946fa',1,'ir_LG.cpp']]], + ['klg32rpthdrmark_5752',['kLg32RptHdrMark',['../ir__LG_8cpp.html#af19a674228bea82c1c588aa9dd974805',1,'ir_LG.cpp']]], + ['klg32rpthdrmarkticks_5753',['kLg32RptHdrMarkTicks',['../ir__LG_8cpp.html#a5c79f7072eee35fc1df10ecd18e2a3d2',1,'ir_LG.cpp']]], + ['klgacauto_5754',['kLgAcAuto',['../ir__LG_8h.html#ae5e45a0f42ce7544d6fb7981a43fb932',1,'ir_LG.h']]], + ['klgacchecksumoffset_5755',['kLgAcChecksumOffset',['../ir__LG_8h.html#aa0b9abe43a870097d886efcd0fd3bb96',1,'ir_LG.h']]], + ['klgacchecksumsize_5756',['kLgAcChecksumSize',['../ir__LG_8h.html#a177d205346380d47ae47b52079e5ffaf',1,'ir_LG.h']]], + ['klgaccool_5757',['kLgAcCool',['../ir__LG_8h.html#a3ba35885488bdda3d87ba344a5c58eb2',1,'ir_LG.h']]], + ['klgacdry_5758',['kLgAcDry',['../ir__LG_8h.html#ab3b9a106551be1217e0c824cffe1ea44',1,'ir_LG.h']]], + ['klgacfan_5759',['kLgAcFan',['../ir__LG_8h.html#afc12144673b8dd0555833427fa757275',1,'ir_LG.h']]], + ['klgacfanauto_5760',['kLgAcFanAuto',['../ir__LG_8h.html#a3dee1dc33f768d36a2216213c90a0a5c',1,'ir_LG.h']]], + ['klgacfanhigh_5761',['kLgAcFanHigh',['../ir__LG_8h.html#a89888f8d36899b5526e4c2ebb1097357',1,'ir_LG.h']]], + ['klgacfanlow_5762',['kLgAcFanLow',['../ir__LG_8h.html#afa3633c1b26d837f85b10a8a8d677efc',1,'ir_LG.h']]], + ['klgacfanmedium_5763',['kLgAcFanMedium',['../ir__LG_8h.html#abe0fb8a8f9d6ab9ebda36d0343841619',1,'ir_LG.h']]], + ['klgacfanoffset_5764',['kLgAcFanOffset',['../ir__LG_8h.html#a428d348215682243f7e5fe03c7580665',1,'ir_LG.h']]], + ['klgacfansize_5765',['kLgAcFanSize',['../ir__LG_8h.html#a4baf7484fee55fdd5cdbf13d11d7f1b9',1,'ir_LG.h']]], + ['klgacheat_5766',['kLgAcHeat',['../ir__LG_8h.html#a6c17d61082cc24f9d714c5d4ac151933',1,'ir_LG.h']]], + ['klgacmaxtemp_5767',['kLgAcMaxTemp',['../ir__LG_8h.html#a0fab7b6e6d1138638bdeadeab85f5090',1,'ir_LG.h']]], + ['klgacmintemp_5768',['kLgAcMinTemp',['../ir__LG_8h.html#ae3bef99e329f057358001cacf67f6d70',1,'ir_LG.h']]], + ['klgacmodeoffset_5769',['kLgAcModeOffset',['../ir__LG_8h.html#abbc65ef461fd214d9ef41ebf62693467',1,'ir_LG.h']]], + ['klgacmodesize_5770',['kLgAcModeSize',['../ir__LG_8h.html#ae9927832fbb45c310666d8de1ebe5f0f',1,'ir_LG.h']]], + ['klgacoffcommand_5771',['kLgAcOffCommand',['../ir__LG_8h.html#aecf8158eec1d9ec0d54056392b512296',1,'ir_LG.h']]], + ['klgacpoweroff_5772',['kLgAcPowerOff',['../ir__LG_8h.html#a3b2681e41071298197d849fbd7649318',1,'ir_LG.h']]], + ['klgacpoweroffset_5773',['kLgAcPowerOffset',['../ir__LG_8h.html#a7cce14305909efe3b904d68f902d42de',1,'ir_LG.h']]], + ['klgacpoweron_5774',['kLgAcPowerOn',['../ir__LG_8h.html#a87d2f6e4e2755aaab4762952b1bf6108',1,'ir_LG.h']]], + ['klgacpowersize_5775',['kLgAcPowerSize',['../ir__LG_8h.html#a624eee0bc9084e4d9d801f8cbdc28d1e',1,'ir_LG.h']]], + ['klgacsignature_5776',['kLgAcSignature',['../ir__LG_8h.html#ab7c3589deb28829ad0313b1505ec196e',1,'ir_LG.h']]], + ['klgacsignatureoffset_5777',['kLgAcSignatureOffset',['../ir__LG_8h.html#a406dff4b4ffa5b809b8ea87ddfd3bf8b',1,'ir_LG.h']]], + ['klgacsignaturesize_5778',['kLgAcSignatureSize',['../ir__LG_8h.html#a7420d729a5dca26d95be3b9907eb477e',1,'ir_LG.h']]], + ['klgactempadjust_5779',['kLgAcTempAdjust',['../ir__LG_8h.html#a16210dc395a86dc4562436047c22600f',1,'ir_LG.h']]], + ['klgactempoffset_5780',['kLgAcTempOffset',['../ir__LG_8h.html#aca5ae781e03e4a88a83303cb0cae0609',1,'ir_LG.h']]], + ['klgactempsize_5781',['kLgAcTempSize',['../ir__LG_8h.html#ad0235a6c5bebb086b75dc65433b3c9e1',1,'ir_LG.h']]], + ['klgbitmark_5782',['kLgBitMark',['../ir__LG_8cpp.html#a9311195710d4c3a2ac48456390a03138',1,'ir_LG.cpp']]], + ['klgbitmarkticks_5783',['kLgBitMarkTicks',['../ir__LG_8cpp.html#a80b2d221b207c8c0faa74f1f39e9920b',1,'ir_LG.cpp']]], + ['klgbits_5784',['kLgBits',['../IRremoteESP8266_8h.html#a256bd6093034b3e4c33324680f3a7102',1,'IRremoteESP8266.h']]], + ['klgdefaultrepeat_5785',['kLgDefaultRepeat',['../IRremoteESP8266_8h.html#a2d6832b3d214e0adad781c205993e461',1,'IRremoteESP8266.h']]], + ['klghdrmark_5786',['kLgHdrMark',['../ir__LG_8cpp.html#a74f253d9e4cc72148233021c47d59f35',1,'ir_LG.cpp']]], + ['klghdrmarkticks_5787',['kLgHdrMarkTicks',['../ir__LG_8cpp.html#a6f1f88f3cefe49b9796a10a9109e560e',1,'ir_LG.cpp']]], + ['klghdrspace_5788',['kLgHdrSpace',['../ir__LG_8cpp.html#a6eaf100cde647fc119d3e993680afd47',1,'ir_LG.cpp']]], + ['klghdrspaceticks_5789',['kLgHdrSpaceTicks',['../ir__LG_8cpp.html#a22d8775d4c8985970b47e449232b45de',1,'ir_LG.cpp']]], + ['klgmingap_5790',['kLgMinGap',['../ir__LG_8cpp.html#a784323468e6b5ebc65bd2870a94fb553',1,'ir_LG.cpp']]], + ['klgmingapticks_5791',['kLgMinGapTicks',['../ir__LG_8cpp.html#aa56fd5b4fe946992aa1b9bdf61b1518b',1,'ir_LG.cpp']]], + ['klgminmessagelength_5792',['kLgMinMessageLength',['../ir__LG_8cpp.html#a4eb3f82ae2ca6c34b58e512848a6dc41',1,'ir_LG.cpp']]], + ['klgminmessagelengthticks_5793',['kLgMinMessageLengthTicks',['../ir__LG_8cpp.html#ab000fc974bdd0723e8bcb4872f33dd72',1,'ir_LG.cpp']]], + ['klgonespace_5794',['kLgOneSpace',['../ir__LG_8cpp.html#a05fe6a47f437efc686cb46ec805da4d4',1,'ir_LG.cpp']]], + ['klgonespaceticks_5795',['kLgOneSpaceTicks',['../ir__LG_8cpp.html#a535b089cd72bd027cbc34eb917d71ae5',1,'ir_LG.cpp']]], + ['klgrptspace_5796',['kLgRptSpace',['../ir__LG_8cpp.html#a834b8f08ee32030c51ea5e2c5bd5a73c',1,'ir_LG.cpp']]], + ['klgrptspaceticks_5797',['kLgRptSpaceTicks',['../ir__LG_8cpp.html#abc43b327c2c752dc5ed2794f08e2eba8',1,'ir_LG.cpp']]], + ['klgtick_5798',['kLgTick',['../ir__LG_8cpp.html#ab8ab28ebf1fae94aa900a3199a6fc191',1,'ir_LG.cpp']]], + ['klgzerospace_5799',['kLgZeroSpace',['../ir__LG_8cpp.html#a981fe3cfc4adf0b3016a008ca1bbf734',1,'ir_LG.cpp']]], + ['klgzerospaceticks_5800',['kLgZeroSpaceTicks',['../ir__LG_8cpp.html#af932345e15db822da67d7796cd5b6584',1,'ir_LG.cpp']]], + ['klightstr_5801',['kLightStr',['../IRtext_8cpp.html#a2912b7dc11fd571706eaaf90e0095a4f',1,'kLightStr(): IRtext.cpp'],['../IRtext_8h.html#a926ebb4be14179afdc55d5524c8eb5da',1,'kLightStr(): IRtext.cpp']]], + ['klighttogglestr_5802',['kLightToggleStr',['../IRtext_8cpp.html#a74a3ef3c72995e19582be04a2716b285',1,'kLightToggleStr(): IRtext.cpp'],['../IRtext_8h.html#af9ac8ce54e78f0d8f7e0043d08e6256c',1,'kLightToggleStr(): IRtext.cpp']]], + ['klostr_5803',['kLoStr',['../IRtext_8cpp.html#a72fc3855eec7026260de3a6b3a25c377',1,'kLoStr(): IRtext.cpp'],['../IRtext_8h.html#abf3295aeb3dfb7048e677d8d6e65e47c',1,'kLoStr(): IRtext.cpp']]], + ['kloudstr_5804',['kLoudStr',['../IRtext_8cpp.html#a3b6d3eed96c5623cc95ebcfb93cb6f96',1,'kLoudStr(): IRtext.cpp'],['../IRtext_8h.html#a7d265b75ed59c0be3c6b72ec0eaf8aa2',1,'kLoudStr(): IRtext.cpp']]], + ['klowerstr_5805',['kLowerStr',['../IRtext_8cpp.html#a518681524ec3c8f8bc993823003fe58a',1,'kLowerStr(): IRtext.cpp'],['../IRtext_8h.html#ae389ed4ed6982d4617ee3f3e82ce388c',1,'kLowerStr(): IRtext.cpp']]], + ['kloweststr_5806',['kLowestStr',['../IRtext_8cpp.html#ae0c595955599a398669a372edd339f67',1,'kLowestStr(): IRtext.cpp'],['../IRtext_8h.html#a31a34e51d7f1f9360cc3a7ea3f2bf7a3',1,'kLowestStr(): IRtext.cpp']]], + ['klownibble_5807',['kLowNibble',['../IRutils_8h.html#ad0288cc71e1814a27c27393f06676eec',1,'IRutils.h']]], + ['klowstr_5808',['kLowStr',['../IRtext_8cpp.html#a18f69bf40b866ee1d30d1586757d5f41',1,'kLowStr(): IRtext.cpp'],['../IRtext_8h.html#a09c0f7f1b07f7591bdbe56fd8a18f7ea',1,'kLowStr(): IRtext.cpp']]], + ['klutronbits_5809',['kLutronBits',['../IRremoteESP8266_8h.html#a814dfab515b91887c494237b1f6ebd99',1,'IRremoteESP8266.h']]], + ['klutrondelta_5810',['kLutronDelta',['../ir__Lutron_8cpp.html#a4220004fac195ef46388199ad9624860',1,'ir_Lutron.cpp']]], + ['klutrongap_5811',['kLutronGap',['../ir__Lutron_8cpp.html#a18ffb51db0ae33904a64012cb72d6165',1,'ir_Lutron.cpp']]], + ['klutrontick_5812',['kLutronTick',['../ir__Lutron_8cpp.html#a04a84309978b79c0983c398a497a087a',1,'ir_Lutron.cpp']]], + ['kmagiquestbits_5813',['kMagiquestBits',['../IRremoteESP8266_8h.html#ad756bfec6eabbe2ac10b7847f87fb751',1,'IRremoteESP8266.h']]], + ['kmagiquestgap_5814',['kMagiQuestGap',['../ir__Magiquest_8h.html#aebdea5a1a55547d812f1f7bb2d3ddf1f',1,'ir_Magiquest.h']]], + ['kmagiquestmarkone_5815',['kMagiQuestMarkOne',['../ir__Magiquest_8h.html#a0d5d090015ecf49995514054c29cb4e2',1,'ir_Magiquest.h']]], + ['kmagiquestmarkzero_5816',['kMagiQuestMarkZero',['../ir__Magiquest_8h.html#a7240a15dbb9bc6a1e31575be7837c390',1,'ir_Magiquest.h']]], + ['kmagiquestoneratio_5817',['kMagiQuestOneRatio',['../ir__Magiquest_8h.html#a073cdb7ca4dd35b8fa05d99eb7da5b65',1,'ir_Magiquest.h']]], + ['kmagiquestspaceone_5818',['kMagiQuestSpaceOne',['../ir__Magiquest_8h.html#a92bad440c0291cbb903f08de08d96fb2',1,'ir_Magiquest.h']]], + ['kmagiquestspacezero_5819',['kMagiQuestSpaceZero',['../ir__Magiquest_8h.html#abe557052c5c3bef87e62daf71b4c8654',1,'ir_Magiquest.h']]], + ['kmagiquesttotalusec_5820',['kMagiQuestTotalUsec',['../ir__Magiquest_8h.html#a819dcf22b127f4f7b282d784490a83c3',1,'ir_Magiquest.h']]], + ['kmagiquestzeroratio_5821',['kMagiQuestZeroRatio',['../ir__Magiquest_8h.html#a41e5594b8e1510267e563ed78fbe98b0',1,'ir_Magiquest.h']]], + ['kmanualstr_5822',['kManualStr',['../IRtext_8cpp.html#a619896ae89717b2b0e1d3492bb528cbc',1,'kManualStr(): IRtext.cpp'],['../IRtext_8h.html#aa8d9143da032cdc1accf7f4441b05bc8',1,'kManualStr(): IRtext.cpp']]], + ['kmark_5823',['kMark',['../ir__Lasertag_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_Lasertag.cpp'],['../ir__MWM_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_MWM.cpp'],['../ir__RC5__RC6_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_RC5_RC6.cpp']]], + ['kmarkexcess_5824',['kMarkExcess',['../IRrecv_8h.html#a99bbffe986ad7ba86d2b11e75f4aa50e',1,'IRrecv.h']]], + ['kmarkstate_5825',['kMarkState',['../IRrecv_8h.html#acc85ad22929660bdc17fe185d87edfb2',1,'IRrecv.h']]], + ['kmaxaccurateusecdelay_5826',['kMaxAccurateUsecDelay',['../IRsend_8h.html#a527e66125f3ae6ce87adbc72eab7d0b9',1,'IRsend.h']]], + ['kmaximumstr_5827',['kMaximumStr',['../IRtext_8cpp.html#af346693e98c91c7ce79bb22c7460dcee',1,'kMaximumStr(): IRtext.cpp'],['../IRtext_8h.html#a487173616cc3fced0489c01c11333912',1,'kMaximumStr(): IRtext.cpp']]], + ['kmaxleftstr_5828',['kMaxLeftStr',['../IRtext_8cpp.html#ae8ad7e46c3a33b4b9c5fa6545c9e3822',1,'kMaxLeftStr(): IRtext.cpp'],['../IRtext_8h.html#aac197960695463757652bc643efdcd59',1,'kMaxLeftStr(): IRtext.cpp']]], + ['kmaxrightstr_5829',['kMaxRightStr',['../IRtext_8cpp.html#a1ae3f331adb8ac6d1a27aa3d688fb65f',1,'kMaxRightStr(): IRtext.cpp'],['../IRtext_8h.html#a0f888d5c39cf82b2c02a7caad10c716e',1,'kMaxRightStr(): IRtext.cpp']]], + ['kmaxstr_5830',['kMaxStr',['../IRtext_8cpp.html#ad30e01090f06db0a3cb0c00bb6d2f0ca',1,'kMaxStr(): IRtext.cpp'],['../IRtext_8h.html#a7f4b2ff4134386a09e2bcb5f71f591cb',1,'kMaxStr(): IRtext.cpp']]], + ['kmaxtimeoutms_5831',['kMaxTimeoutMs',['../IRrecv_8h.html#a73391726d7caccb9b498bba73a969784',1,'IRrecv.h']]], + ['kmediumstr_5832',['kMediumStr',['../IRtext_8cpp.html#ac59539e93fdc7d8f15f1f55bcbf933c5',1,'kMediumStr(): IRtext.cpp'],['../IRtext_8h.html#a122ee1c6b866267f771888a7d7b2969b',1,'kMediumStr(): IRtext.cpp']]], + ['kmedstr_5833',['kMedStr',['../IRtext_8cpp.html#a4832f8f5118018fa3c6eae1cd652eabf',1,'kMedStr(): IRtext.cpp'],['../IRtext_8h.html#a18f613c7f11f6f746227cfa8cc1e00e0',1,'kMedStr(): IRtext.cpp']]], + ['kmiddlestr_5834',['kMiddleStr',['../IRtext_8cpp.html#a536f05d84867cfae601d4c1a2312d755',1,'kMiddleStr(): IRtext.cpp'],['../IRtext_8h.html#abbd5b682b584b737c76bded900a6ffad',1,'kMiddleStr(): IRtext.cpp']]], + ['kmidea24bits_5835',['kMidea24Bits',['../IRremoteESP8266_8h.html#aff132faa67b1d07890378df5c9b52a14',1,'IRremoteESP8266.h']]], + ['kmidea24mingap_5836',['kMidea24MinGap',['../ir__Midea_8cpp.html#abfee73cafcc017c4742893908200dffc',1,'ir_Midea.cpp']]], + ['kmidea24minrepeat_5837',['kMidea24MinRepeat',['../IRremoteESP8266_8h.html#a8ed4bb62818fc64e4c4b60ef1094059e',1,'IRremoteESP8266.h']]], + ['kmideaacauto_5838',['kMideaACAuto',['../ir__Midea_8h.html#a379f580c4d1832a62fe49d66f7c13af6',1,'ir_Midea.h']]], + ['kmideaaccelsiusoffset_5839',['kMideaACCelsiusOffset',['../ir__Midea_8h.html#a3354c62fbd83c1f0c55aee359d45a1e0',1,'ir_Midea.h']]], + ['kmideaaccool_5840',['kMideaACCool',['../ir__Midea_8h.html#a94b1b18f6aa9c5010699ea9bfcc89b21',1,'ir_Midea.h']]], + ['kmideaacdry_5841',['kMideaACDry',['../ir__Midea_8h.html#a88c2d215406e337b437b99a04c4ca6c4',1,'ir_Midea.h']]], + ['kmideaacfan_5842',['kMideaACFan',['../ir__Midea_8h.html#ac92dd372bb18d43aea73d5ec511e1290',1,'ir_Midea.h']]], + ['kmideaacfanauto_5843',['kMideaACFanAuto',['../ir__Midea_8h.html#a334a64f653b141d67ffda2eca2a9851f',1,'ir_Midea.h']]], + ['kmideaacfanhigh_5844',['kMideaACFanHigh',['../ir__Midea_8h.html#a9c177aff562a19f32d6cf010704ac681',1,'ir_Midea.h']]], + ['kmideaacfanlow_5845',['kMideaACFanLow',['../ir__Midea_8h.html#a90ebe3812e8b554798a2083ddfe9fdff',1,'ir_Midea.h']]], + ['kmideaacfanmed_5846',['kMideaACFanMed',['../ir__Midea_8h.html#a9406c8d9ad79e6a121a29cd5455e8e7d',1,'ir_Midea.h']]], + ['kmideaacfanoffset_5847',['kMideaACFanOffset',['../ir__Midea_8h.html#ac210e7bed85ad46cef1fa15a71d8e4c9',1,'ir_Midea.h']]], + ['kmideaacfansize_5848',['kMideaACFanSize',['../ir__Midea_8h.html#ab2726e607d432d00b625471d51b71b21',1,'ir_Midea.h']]], + ['kmideaacheat_5849',['kMideaACHeat',['../ir__Midea_8h.html#aa0fb74d8406327a9510f0efa8a16a488',1,'ir_Midea.h']]], + ['kmideaacmaxtempc_5850',['kMideaACMaxTempC',['../ir__Midea_8h.html#a0cccc3093cffabe1e512f298c04b3ba1',1,'ir_Midea.h']]], + ['kmideaacmaxtempf_5851',['kMideaACMaxTempF',['../ir__Midea_8h.html#ac7306c86080e934055d5be9728c91629',1,'ir_Midea.h']]], + ['kmideaacmintempc_5852',['kMideaACMinTempC',['../ir__Midea_8h.html#ae849eb79db6c077d617283154edade84',1,'ir_Midea.h']]], + ['kmideaacmintempf_5853',['kMideaACMinTempF',['../ir__Midea_8h.html#a0b0bdf519164f793a129d0e32152069a',1,'ir_Midea.h']]], + ['kmideaacmodeoffset_5854',['kMideaACModeOffset',['../ir__Midea_8h.html#a04fb535d82fe9d44d6898dd7c2e3491e',1,'ir_Midea.h']]], + ['kmideaacpoweroffset_5855',['kMideaACPowerOffset',['../ir__Midea_8h.html#a299cd691572c33f5d4742a9c289c279c',1,'ir_Midea.h']]], + ['kmideaacsleepoffset_5856',['kMideaACSleepOffset',['../ir__Midea_8h.html#a3c968881e59795eadfcb991b36755494',1,'ir_Midea.h']]], + ['kmideaactempoffset_5857',['kMideaACTempOffset',['../ir__Midea_8h.html#aec7e9182f167eb9b094670cf9889a595',1,'ir_Midea.h']]], + ['kmideaactempsize_5858',['kMideaACTempSize',['../ir__Midea_8h.html#aad2041ff636467046b63ceeb9fdfaaea',1,'ir_Midea.h']]], + ['kmideaactoggleswingv_5859',['kMideaACToggleSwingV',['../ir__Midea_8h.html#a5420b72289d3ae99a6dbc5c94914c473',1,'ir_Midea.h']]], + ['kmideabitmark_5860',['kMideaBitMark',['../ir__Midea_8cpp.html#a39dc2d03456f67418519dc0f5efde7e0',1,'ir_Midea.cpp']]], + ['kmideabitmarkticks_5861',['kMideaBitMarkTicks',['../ir__Midea_8cpp.html#ac4d9b1460516aa19913b5bd328c1e176',1,'ir_Midea.cpp']]], + ['kmideabits_5862',['kMideaBits',['../IRremoteESP8266_8h.html#afc98096b1e2945e2eaeb07d70d511239',1,'IRremoteESP8266.h']]], + ['kmideahdrmark_5863',['kMideaHdrMark',['../ir__Midea_8cpp.html#adcaa1ad6e2ba1022f3c90266f4fd0378',1,'ir_Midea.cpp']]], + ['kmideahdrmarkticks_5864',['kMideaHdrMarkTicks',['../ir__Midea_8cpp.html#af63b6cfcc5dc3e501b61c0d55d678f9e',1,'ir_Midea.cpp']]], + ['kmideahdrspace_5865',['kMideaHdrSpace',['../ir__Midea_8cpp.html#a8676eda087a85f6639b547140496c12f',1,'ir_Midea.cpp']]], + ['kmideahdrspaceticks_5866',['kMideaHdrSpaceTicks',['../ir__Midea_8cpp.html#aad99b5d8361733a9ca662735783e061c',1,'ir_Midea.cpp']]], + ['kmideamingap_5867',['kMideaMinGap',['../ir__Midea_8cpp.html#ad9ed8fb4841654fa756614862ac63be7',1,'ir_Midea.cpp']]], + ['kmideamingapticks_5868',['kMideaMinGapTicks',['../ir__Midea_8cpp.html#accd4e69e8fe0957ba013b97879fb1120',1,'ir_Midea.cpp']]], + ['kmideaminrepeat_5869',['kMideaMinRepeat',['../IRremoteESP8266_8h.html#aa8876e8e177b8e71154f8cfb42b19160',1,'IRremoteESP8266.h']]], + ['kmideaonespace_5870',['kMideaOneSpace',['../ir__Midea_8cpp.html#aabe187743f36e664c6069b004e9a82f7',1,'ir_Midea.cpp']]], + ['kmideaonespaceticks_5871',['kMideaOneSpaceTicks',['../ir__Midea_8cpp.html#a2cf0d5df2e5a3d7b1d24fd25ae3d7453',1,'ir_Midea.cpp']]], + ['kmideatick_5872',['kMideaTick',['../ir__Midea_8cpp.html#a878185258a4174978b072ac36aa377e2',1,'ir_Midea.cpp']]], + ['kmideatolerance_5873',['kMideaTolerance',['../ir__Midea_8cpp.html#a55553c3b8e7997fb1257ac2a37a929b6',1,'ir_Midea.cpp']]], + ['kmideazerospace_5874',['kMideaZeroSpace',['../ir__Midea_8cpp.html#a107d1d062e8475b84ec4ab548c3f01ef',1,'ir_Midea.cpp']]], + ['kmideazerospaceticks_5875',['kMideaZeroSpaceTicks',['../ir__Midea_8cpp.html#acd6580988c12ef5614727dd4d1b4c92d',1,'ir_Midea.cpp']]], + ['kmidstr_5876',['kMidStr',['../IRtext_8cpp.html#afd827d424c0bfdcc34b3607440fd2652',1,'kMidStr(): IRtext.cpp'],['../IRtext_8h.html#a571a28fe4174574caac4d93fb09ae196',1,'kMidStr(): IRtext.cpp']]], + ['kminimumstr_5877',['kMinimumStr',['../IRtext_8cpp.html#acbd869e5978b6fee053d33d8cf21e11a',1,'kMinimumStr(): IRtext.cpp'],['../IRtext_8h.html#a4f6fee52ae5f7f9c8fe791dbae762607',1,'kMinimumStr(): IRtext.cpp']]], + ['kminstr_5878',['kMinStr',['../IRtext_8cpp.html#a2b0c7369c1a93b8a7d5a87bf37fcee34',1,'kMinStr(): IRtext.cpp'],['../IRtext_8h.html#a4940a3f71a484f936d3e58b9573931a8',1,'kMinStr(): IRtext.cpp']]], + ['kminutesstr_5879',['kMinutesStr',['../IRtext_8cpp.html#a1c05b3e6af04586a0060c58979df002f',1,'kMinutesStr(): IRtext.cpp'],['../IRtext_8h.html#a3358666a695e8d54c23b20dc6a371a38',1,'kMinutesStr(): IRtext.cpp']]], + ['kminutestr_5880',['kMinuteStr',['../IRtext_8cpp.html#acab620931ba510a7bc395bad59169099',1,'kMinuteStr(): IRtext.cpp'],['../IRtext_8h.html#a54df015b1adadb211a30f826999c78f6',1,'kMinuteStr(): IRtext.cpp']]], + ['kmitsubishi112auto_5881',['kMitsubishi112Auto',['../ir__Mitsubishi_8h.html#a6e38f06ff78e3406a4f2cf1e1b453402',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112bitmark_5882',['kMitsubishi112BitMark',['../ir__Mitsubishi_8cpp.html#aef96bbd77d5bd66ed220840c09f54c37',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112bits_5883',['kMitsubishi112Bits',['../IRremoteESP8266_8h.html#ae8349abe183be965e3d051cb736773a8',1,'IRremoteESP8266.h']]], + ['kmitsubishi112cool_5884',['kMitsubishi112Cool',['../ir__Mitsubishi_8h.html#aa9d1a63a8a275cda1794628f8d516963',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112dry_5885',['kMitsubishi112Dry',['../ir__Mitsubishi_8h.html#a4a3023d0342003b7947b19c9c5c25fb3',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanbyte_5886',['kMitsubishi112FanByte',['../ir__Mitsubishi_8h.html#a4312828eb864a67f8cc67a90c1324d3a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanlow_5887',['kMitsubishi112FanLow',['../ir__Mitsubishi_8h.html#a4b8d6d04bb75ed98f6ed5bdff7472f50',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmax_5888',['kMitsubishi112FanMax',['../ir__Mitsubishi_8h.html#a5a3e7c72ed85864b34f8ee298b3adc49',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmed_5889',['kMitsubishi112FanMed',['../ir__Mitsubishi_8h.html#aa8a81057eeccbf528962b31a197b0319',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmin_5890',['kMitsubishi112FanMin',['../ir__Mitsubishi_8h.html#ad8b101130e781d30b5d4072b3c514c78',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanoffset_5891',['kMitsubishi112FanOffset',['../ir__Mitsubishi_8h.html#ac000e0d3a59314c115e516f37c29983d',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanquiet_5892',['kMitsubishi112FanQuiet',['../ir__Mitsubishi_8h.html#addcf7a99c5ba2f4510754d22a4c0760f',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fansize_5893',['kMitsubishi112FanSize',['../ir__Mitsubishi_8h.html#ab102138f689d66c2c4c97445931f2dec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112gap_5894',['kMitsubishi112Gap',['../ir__Mitsubishi_8cpp.html#ab24cc7d395c1620b9519b5d0ce2a2023',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrmark_5895',['kMitsubishi112HdrMark',['../ir__Mitsubishi_8cpp.html#a3082567d58d6f8e6ef26714ff23f3728',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrmarktolerance_5896',['kMitsubishi112HdrMarkTolerance',['../ir__Mitsubishi_8cpp.html#a288931e01f8cffa1917fb7bc59710e20',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrspace_5897',['kMitsubishi112HdrSpace',['../ir__Mitsubishi_8cpp.html#a7b35ecbbc94f7ef622b20f21f83c0fba',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112heat_5898',['kMitsubishi112Heat',['../ir__Mitsubishi_8h.html#a260b6883e9433b466abf31618b1c4015',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112maxtemp_5899',['kMitsubishi112MaxTemp',['../ir__Mitsubishi_8h.html#afd968ea297ef8856b7266a8cc6e1bba0',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112minrepeat_5900',['kMitsubishi112MinRepeat',['../IRremoteESP8266_8h.html#a6bba58bb0f33feb9a6dfd20637d01d13',1,'IRremoteESP8266.h']]], + ['kmitsubishi112mintemp_5901',['kMitsubishi112MinTemp',['../ir__Mitsubishi_8h.html#acea288a8911a540cb9602d057eccb2a6',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112modebyte_5902',['kMitsubishi112ModeByte',['../ir__Mitsubishi_8h.html#a7e7663483fa89b4283baafba744d707a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112modeoffset_5903',['kMitsubishi112ModeOffset',['../ir__Mitsubishi_8h.html#a39c8631bfd414738f1934eb28e74b97b',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112onespace_5904',['kMitsubishi112OneSpace',['../ir__Mitsubishi_8cpp.html#a8dd0d824826a7da007e78741015d418a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112powerbyte_5905',['kMitsubishi112PowerByte',['../ir__Mitsubishi_8h.html#ab09f78fee2a242dfdb0318a4caf7a2d6',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112poweroffset_5906',['kMitsubishi112PowerOffset',['../ir__Mitsubishi_8h.html#afd78de91190fa6ec8ffcc9132e3a8b35',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112statelength_5907',['kMitsubishi112StateLength',['../IRremoteESP8266_8h.html#a5ff0437b26e325bc2516a3e63c7ffe76',1,'IRremoteESP8266.h']]], + ['kmitsubishi112swinghauto_5908',['kMitsubishi112SwingHAuto',['../ir__Mitsubishi_8h.html#ab55e72c6d2b407868cda075efb24ac92',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghbyte_5909',['kMitsubishi112SwingHByte',['../ir__Mitsubishi_8h.html#ac149161c62c9ceee1c3a37d73930a7e8',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghleft_5910',['kMitsubishi112SwingHLeft',['../ir__Mitsubishi_8h.html#a8299b42b0972bda8a4bc4f32527c33e9',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghleftmax_5911',['kMitsubishi112SwingHLeftMax',['../ir__Mitsubishi_8h.html#a48346e97056af670454bc77a64b904bc',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghmiddle_5912',['kMitsubishi112SwingHMiddle',['../ir__Mitsubishi_8h.html#a7adcab7d152d84adef2059339de4bb40',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghoffset_5913',['kMitsubishi112SwingHOffset',['../ir__Mitsubishi_8h.html#a42f92264157e170d68046b9970a057ed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghright_5914',['kMitsubishi112SwingHRight',['../ir__Mitsubishi_8h.html#a76cf277572a2b628d4a5353186ca2522',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghrightmax_5915',['kMitsubishi112SwingHRightMax',['../ir__Mitsubishi_8h.html#a1ff73f603b6e32075cbc9253d3090b49',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghsize_5916',['kMitsubishi112SwingHSize',['../ir__Mitsubishi_8h.html#a9ab977dbab987789d40fae38212f07ba',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghwide_5917',['kMitsubishi112SwingHWide',['../ir__Mitsubishi_8h.html#afab80db45769ab2957afc0e4799b46e5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvauto_5918',['kMitsubishi112SwingVAuto',['../ir__Mitsubishi_8h.html#a1e16b172e864a74b426b1f823770cdaa',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvbyte_5919',['kMitsubishi112SwingVByte',['../ir__Mitsubishi_8h.html#afbcd99e59a029ccc6276c87a46d560dd',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvhigh_5920',['kMitsubishi112SwingVHigh',['../ir__Mitsubishi_8h.html#ab6e345e609d72f9ed903e30f3aa9a26f',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvhighest_5921',['kMitsubishi112SwingVHighest',['../ir__Mitsubishi_8h.html#a1cb8c62990dfb98a8ea228ad59cd88e5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvlow_5922',['kMitsubishi112SwingVLow',['../ir__Mitsubishi_8h.html#a515bea322889f619d64ae96c37eaba72',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvlowest_5923',['kMitsubishi112SwingVLowest',['../ir__Mitsubishi_8h.html#ac4dd729a11e3ece244df6b1ddc9250f8',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvmiddle_5924',['kMitsubishi112SwingVMiddle',['../ir__Mitsubishi_8h.html#a0ae62480999dc4cf8a223b59938a0d68',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvoffset_5925',['kMitsubishi112SwingVOffset',['../ir__Mitsubishi_8h.html#ae4f3919271bb464d90a42066e8052c64',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvsize_5926',['kMitsubishi112SwingVSize',['../ir__Mitsubishi_8h.html#ae4f466b64691d8aa20e66a982d65ceea',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112tempbyte_5927',['kMitsubishi112TempByte',['../ir__Mitsubishi_8h.html#a4099370512a63ae3414221ab45f05034',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112tempsize_5928',['kMitsubishi112TempSize',['../ir__Mitsubishi_8h.html#a30d0ece1b7db3558ecc03214843c9fec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112zerospace_5929',['kMitsubishi112ZeroSpace',['../ir__Mitsubishi_8cpp.html#ad70d1567dc2e4ea07a247f2555fc23b4',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136auto_5930',['kMitsubishi136Auto',['../ir__Mitsubishi_8h.html#ae10977a0d09f4c583b03fa05720c3aed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136bitmark_5931',['kMitsubishi136BitMark',['../ir__Mitsubishi_8cpp.html#a3aa9c715088a58a8b4a97d5038dbf6d4',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136bits_5932',['kMitsubishi136Bits',['../IRremoteESP8266_8h.html#aa19f0122b2f906e5473a6ea232c38974',1,'IRremoteESP8266.h']]], + ['kmitsubishi136cool_5933',['kMitsubishi136Cool',['../ir__Mitsubishi_8h.html#a93332579055a07ea291b3caf9ad11944',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136dry_5934',['kMitsubishi136Dry',['../ir__Mitsubishi_8h.html#ad612c480e8664169e2b8e062d47bd8b9',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fan_5935',['kMitsubishi136Fan',['../ir__Mitsubishi_8h.html#a4445944955b9017fcd6d1ae447f1b0d7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanbyte_5936',['kMitsubishi136FanByte',['../ir__Mitsubishi_8h.html#a62166a745fdf0bbbd4b0eb114073b03e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanlow_5937',['kMitsubishi136FanLow',['../ir__Mitsubishi_8h.html#af0f7177491c4cb053e6811376be956ec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmax_5938',['kMitsubishi136FanMax',['../ir__Mitsubishi_8h.html#a43a4337e20fbf4f6747a58c15213bd16',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmed_5939',['kMitsubishi136FanMed',['../ir__Mitsubishi_8h.html#a73ff7df8fe65829cfd5875dc5040dec7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmin_5940',['kMitsubishi136FanMin',['../ir__Mitsubishi_8h.html#a2623eaf6e7d2ceb20ee72faddf46569e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanoffset_5941',['kMitsubishi136FanOffset',['../ir__Mitsubishi_8h.html#aaa194e1e4394d3805477f4b2b78d3a81',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanquiet_5942',['kMitsubishi136FanQuiet',['../ir__Mitsubishi_8h.html#af2f7483bbb99216614e01dd5aedc35d5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fansize_5943',['kMitsubishi136FanSize',['../ir__Mitsubishi_8h.html#a3fa7836f102aa9c78d7dd287a038baee',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136gap_5944',['kMitsubishi136Gap',['../ir__Mitsubishi_8cpp.html#a3f9e0708bbe8ed3ff98a563c3ff1af2b',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136hdrmark_5945',['kMitsubishi136HdrMark',['../ir__Mitsubishi_8cpp.html#a49c54ff757d070de54e3739b775bea00',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136hdrspace_5946',['kMitsubishi136HdrSpace',['../ir__Mitsubishi_8cpp.html#a1ddd09e423c427b3956298c20725188a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136heat_5947',['kMitsubishi136Heat',['../ir__Mitsubishi_8h.html#a932f074e9348d35cea119c8141eeb7f2',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136maxtemp_5948',['kMitsubishi136MaxTemp',['../ir__Mitsubishi_8h.html#a2db420b28003dc3e05bf1c86830c61ed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136minrepeat_5949',['kMitsubishi136MinRepeat',['../IRremoteESP8266_8h.html#a448bd7af5fdab67fb40901a3d6efed21',1,'IRremoteESP8266.h']]], + ['kmitsubishi136mintemp_5950',['kMitsubishi136MinTemp',['../ir__Mitsubishi_8h.html#a5e2e5783d33f927f941271a44d11434c',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136modebyte_5951',['kMitsubishi136ModeByte',['../ir__Mitsubishi_8h.html#a98fbde8559e82a1875235019913e859c',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136modeoffset_5952',['kMitsubishi136ModeOffset',['../ir__Mitsubishi_8h.html#a061d59096df59826d951e83594728893',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136onespace_5953',['kMitsubishi136OneSpace',['../ir__Mitsubishi_8cpp.html#a9a0cfee8b6ea94d3f798d53d30c99d5f',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136powerbit_5954',['kMitsubishi136PowerBit',['../ir__Mitsubishi_8h.html#abbe2f7821db2a6f4696cf7f9138c509d',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136powerbyte_5955',['kMitsubishi136PowerByte',['../ir__Mitsubishi_8h.html#aca06b9d066d3f1a322bbb0f3d1a874a7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136poweroffset_5956',['kMitsubishi136PowerOffset',['../ir__Mitsubishi_8h.html#ad235f31bc4b42548373c15e18f29e8b1',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136statelength_5957',['kMitsubishi136StateLength',['../IRremoteESP8266_8h.html#a01adbe4e1afb2ba26a5a60bf5b0b42f6',1,'IRremoteESP8266.h']]], + ['kmitsubishi136swingvauto_5958',['kMitsubishi136SwingVAuto',['../ir__Mitsubishi_8h.html#a828c2cc017cb7d00872137464d2119ae',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvbyte_5959',['kMitsubishi136SwingVByte',['../ir__Mitsubishi_8h.html#ab31414515f89e94ec8b63028e215b5ad',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvhigh_5960',['kMitsubishi136SwingVHigh',['../ir__Mitsubishi_8h.html#a319b36df23511aba8fb16b13eda9333b',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvhighest_5961',['kMitsubishi136SwingVHighest',['../ir__Mitsubishi_8h.html#a5bd1dbb97df91dfec0f9493120ea1269',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvlow_5962',['kMitsubishi136SwingVLow',['../ir__Mitsubishi_8h.html#a1ba4f3f7eb75bb54a752cfb11f196af0',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvlowest_5963',['kMitsubishi136SwingVLowest',['../ir__Mitsubishi_8h.html#ab0701f0127b07780066040bc08e46a2e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136tempbyte_5964',['kMitsubishi136TempByte',['../ir__Mitsubishi_8h.html#a22bf24adb745489a75fb877fa5cc249a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136zerospace_5965',['kMitsubishi136ZeroSpace',['../ir__Mitsubishi_8cpp.html#afaf1eca1169f492dcdd8a7266756c827',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2bitmark_5966',['kMitsubishi2BitMark',['../ir__Mitsubishi_8cpp.html#a8b0e87a15c51c3b62c14b4e7a071207f',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2hdrmark_5967',['kMitsubishi2HdrMark',['../ir__Mitsubishi_8cpp.html#a2d838e748f1f69165fb6b672955ea95e',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2hdrspace_5968',['kMitsubishi2HdrSpace',['../ir__Mitsubishi_8cpp.html#acd8994a08389c8d874afcbb8eb9c0861',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2mingap_5969',['kMitsubishi2MinGap',['../ir__Mitsubishi_8cpp.html#a7fa283a14968b582123a474c86a6fde9',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2onespace_5970',['kMitsubishi2OneSpace',['../ir__Mitsubishi_8cpp.html#aeee614cef3e95f661dca95b344edcf64',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2zerospace_5971',['kMitsubishi2ZeroSpace',['../ir__Mitsubishi_8cpp.html#a665522ccd10f4c9fba39e3f8f8a5cb95',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacauto_5972',['kMitsubishiAcAuto',['../ir__Mitsubishi_8h.html#a1fdbdc0906594e0efebbd05110877000',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacbitmark_5973',['kMitsubishiAcBitMark',['../ir__Mitsubishi_8cpp.html#a3787c48ffff208ef964886efab7e17ca',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacbits_5974',['kMitsubishiACBits',['../IRremoteESP8266_8h.html#a911a47148656b26da2e094a7ced1fc8b',1,'IRremoteESP8266.h']]], + ['kmitsubishiaccool_5975',['kMitsubishiAcCool',['../ir__Mitsubishi_8h.html#a434455f6c76f0ca354b01e6a8a6479e9',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacdry_5976',['kMitsubishiAcDry',['../ir__Mitsubishi_8h.html#a9875c4b91a1b155b5f2e12370c33e031',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacextratolerance_5977',['kMitsubishiAcExtraTolerance',['../ir__Mitsubishi_8cpp.html#a98a0e4182311d584d4de4632eb491f04',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacfanauto_5978',['kMitsubishiAcFanAuto',['../ir__Mitsubishi_8h.html#a302cfd0468875cff23c69f71c392ad36',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanautooffset_5979',['kMitsubishiAcFanAutoOffset',['../ir__Mitsubishi_8h.html#ab8696268b90bf45314d712c212d68a10',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanmax_5980',['kMitsubishiAcFanMax',['../ir__Mitsubishi_8h.html#abbc2b87dfc6b2364d065f66f4d3e540c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanoffset_5981',['kMitsubishiAcFanOffset',['../ir__Mitsubishi_8h.html#ac16a5f7fe9800006de4511fd4ac89d64',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanquiet_5982',['kMitsubishiAcFanQuiet',['../ir__Mitsubishi_8h.html#a90799250620dec05385b9e81cfcb83af',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanrealmax_5983',['kMitsubishiAcFanRealMax',['../ir__Mitsubishi_8h.html#aa28f81fbd686adb082786e7cda9a17fc',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfansilent_5984',['kMitsubishiAcFanSilent',['../ir__Mitsubishi_8h.html#a731206548afa4f2672a78dae677f6b44',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfansize_5985',['kMitsubishiAcFanSize',['../ir__Mitsubishi_8h.html#a565c641228d28357282b211048f1bd1c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiachdrmark_5986',['kMitsubishiAcHdrMark',['../ir__Mitsubishi_8cpp.html#a11fcb08ce6bf9fa5fc50ca0e5c7d2d64',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiachdrspace_5987',['kMitsubishiAcHdrSpace',['../ir__Mitsubishi_8cpp.html#af0af560129a4666aeba1a4a9ab59e271',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacheat_5988',['kMitsubishiAcHeat',['../ir__Mitsubishi_8h.html#a6107df195ecf54ec4ef97b5ab82e911c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacmaxtemp_5989',['kMitsubishiAcMaxTemp',['../ir__Mitsubishi_8h.html#a8ba3fba3eb9dd63f5ade3cb3bd11269b',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacminrepeat_5990',['kMitsubishiACMinRepeat',['../IRremoteESP8266_8h.html#a376653a421df42d889ac3b2a071de58b',1,'IRremoteESP8266.h']]], + ['kmitsubishiacmintemp_5991',['kMitsubishiAcMinTemp',['../ir__Mitsubishi_8h.html#a2d6d53ccf446fcb03331f4e9757f4169',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacmodeoffset_5992',['kMitsubishiAcModeOffset',['../ir__Mitsubishi_8h.html#ac0037c13e3f90b7bde5a8328faaa3b9b',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacnotimer_5993',['kMitsubishiAcNoTimer',['../ir__Mitsubishi_8h.html#a0f5da97478cd6cdf2ffab161657e4ab6',1,'ir_Mitsubishi.h']]], + ['kmitsubishiaconespace_5994',['kMitsubishiAcOneSpace',['../ir__Mitsubishi_8cpp.html#abdf26b381c5288556257fabf43458775',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacpower_5995',['kMitsubishiAcPower',['../ir__Mitsubishi_8h.html#a864c4d936663d68f65ed4525072bd3eb',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacpoweroffset_5996',['kMitsubishiAcPowerOffset',['../ir__Mitsubishi_8h.html#a78749519549fb76a920ca447a4504e72',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacrptmark_5997',['kMitsubishiAcRptMark',['../ir__Mitsubishi_8cpp.html#a541d764aef906909a1a0d40466567c92',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacrptspace_5998',['kMitsubishiAcRptSpace',['../ir__Mitsubishi_8cpp.html#a4b120db1bd34c62778597abf05092d0a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacstartstoptimer_5999',['kMitsubishiAcStartStopTimer',['../ir__Mitsubishi_8h.html#aecbdc43fb4bd199c47cb5125816eab59',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacstarttimer_6000',['kMitsubishiAcStartTimer',['../ir__Mitsubishi_8h.html#a4107cbc35f18204f46adb57b0fd0f09c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacstatelength_6001',['kMitsubishiACStateLength',['../IRremoteESP8266_8h.html#a7d0d6dd6d5741f91a1afb641f11d9bc5',1,'IRremoteESP8266.h']]], + ['kmitsubishiacstoptimer_6002',['kMitsubishiAcStopTimer',['../ir__Mitsubishi_8h.html#a5e59039d523d15b145aa87222d52f2bf',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneauto_6003',['kMitsubishiAcVaneAuto',['../ir__Mitsubishi_8h.html#a1caff28ea3678cc5f655fc7147c5a15e',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneautomove_6004',['kMitsubishiAcVaneAutoMove',['../ir__Mitsubishi_8h.html#a2dc0b1ff66ffc21f626d7d8894a31fbb',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvanebitoffset_6005',['kMitsubishiAcVaneBitOffset',['../ir__Mitsubishi_8h.html#a0766870a9709320cfff03d0147f8e414',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneoffset_6006',['kMitsubishiAcVaneOffset',['../ir__Mitsubishi_8h.html#a2e928c1f814b71a1c346b3e987d7b857',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvanesize_6007',['kMitsubishiAcVaneSize',['../ir__Mitsubishi_8h.html#a27d52c41a9309a89e3a2c45b87c501ff',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacwidevaneauto_6008',['kMitsubishiAcWideVaneAuto',['../ir__Mitsubishi_8h.html#a2081e2b8eb778e15b7d9f2f0f332c012',1,'ir_Mitsubishi.h']]], + ['kmitsubishiaczerospace_6009',['kMitsubishiAcZeroSpace',['../ir__Mitsubishi_8cpp.html#a9481515c349154bbb6f56cec2712ba85',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibitmark_6010',['kMitsubishiBitMark',['../ir__Mitsubishi_8cpp.html#a82c8e081b172080df14bdd6e3e6eb608',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibitmarkticks_6011',['kMitsubishiBitMarkTicks',['../ir__Mitsubishi_8cpp.html#a6daf88606f40b13bce698c73d00f5faf',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibits_6012',['kMitsubishiBits',['../IRremoteESP8266_8h.html#abd2187340d0b94996136081413e2ad22',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152bits_6013',['kMitsubishiHeavy152Bits',['../IRremoteESP8266_8h.html#ab973b35583dabc7e04b12018fac04cc9',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152fanauto_6014',['kMitsubishiHeavy152FanAuto',['../ir__MitsubishiHeavy_8h.html#ae1739c1b5cd00b28a06dfd96413570a8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanecono_6015',['kMitsubishiHeavy152FanEcono',['../ir__MitsubishiHeavy_8h.html#acf0522589438103f805889e980259eb8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanhigh_6016',['kMitsubishiHeavy152FanHigh',['../ir__MitsubishiHeavy_8h.html#a48881ddd596b6945d04465b3f7a9bee6',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanlow_6017',['kMitsubishiHeavy152FanLow',['../ir__MitsubishiHeavy_8h.html#acff7254b2ced32550ec9305dbaac3d95',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanmax_6018',['kMitsubishiHeavy152FanMax',['../ir__MitsubishiHeavy_8h.html#aa1e9a41137a7dd65fc049ae41856795f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanmed_6019',['kMitsubishiHeavy152FanMed',['../ir__MitsubishiHeavy_8h.html#ac432324a30abcc0e664cf0ff8e974516',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanturbo_6020',['kMitsubishiHeavy152FanTurbo',['../ir__MitsubishiHeavy_8h.html#a7665d1ecb52afabd0dd951f2ab54e59b',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152minrepeat_6021',['kMitsubishiHeavy152MinRepeat',['../IRremoteESP8266_8h.html#a789cbb74cf332f8440a4fcdcac188741',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152statelength_6022',['kMitsubishiHeavy152StateLength',['../IRremoteESP8266_8h.html#a31d12a44c8c3a3c4533f65b8213e2086',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152swinghauto_6023',['kMitsubishiHeavy152SwingHAuto',['../ir__MitsubishiHeavy_8h.html#ac0ed87ce67ece78e2e9f2b49da5ba152',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleft_6024',['kMitsubishiHeavy152SwingHLeft',['../ir__MitsubishiHeavy_8h.html#a1a20549b529745e913565e6d717d9f95',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleftmax_6025',['kMitsubishiHeavy152SwingHLeftMax',['../ir__MitsubishiHeavy_8h.html#a970e6b602f5bbd4d560249966f6de6c9',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleftright_6026',['kMitsubishiHeavy152SwingHLeftRight',['../ir__MitsubishiHeavy_8h.html#a24c71dc5a17affb2f2d136f6846befbc',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghmiddle_6027',['kMitsubishiHeavy152SwingHMiddle',['../ir__MitsubishiHeavy_8h.html#af1a02e21631c1efb12a01b3db065916c',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghoff_6028',['kMitsubishiHeavy152SwingHOff',['../ir__MitsubishiHeavy_8h.html#a246f8f9c9083f21ee22c2367ece2b9e2',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghright_6029',['kMitsubishiHeavy152SwingHRight',['../ir__MitsubishiHeavy_8h.html#aeec05249b3958f5a1cd629b328209e05',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghrightleft_6030',['kMitsubishiHeavy152SwingHRightLeft',['../ir__MitsubishiHeavy_8h.html#a43ddc14cc8707aa9743519b1c54eb776',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghrightmax_6031',['kMitsubishiHeavy152SwingHRightMax',['../ir__MitsubishiHeavy_8h.html#ae825ed46bf143bc6a01891a5f021c870',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvauto_6032',['kMitsubishiHeavy152SwingVAuto',['../ir__MitsubishiHeavy_8h.html#a31c20346b5538d74b58cb1fd499b5751',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvhigh_6033',['kMitsubishiHeavy152SwingVHigh',['../ir__MitsubishiHeavy_8h.html#a9ac8e39e46b43fb2276af7dd9724e3d4',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvhighest_6034',['kMitsubishiHeavy152SwingVHighest',['../ir__MitsubishiHeavy_8h.html#a554efbb611fd29a5d388d8195aa79993',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvlow_6035',['kMitsubishiHeavy152SwingVLow',['../ir__MitsubishiHeavy_8h.html#ad9a0b57ba70d318572b77236c23830a7',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvlowest_6036',['kMitsubishiHeavy152SwingVLowest',['../ir__MitsubishiHeavy_8h.html#a02f1b980aa78b4ff314209d16bf0a6e8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvmiddle_6037',['kMitsubishiHeavy152SwingVMiddle',['../ir__MitsubishiHeavy_8h.html#ae5c3ec8b8837dddff01d71c44a4ba813',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvoff_6038',['kMitsubishiHeavy152SwingVOff',['../ir__MitsubishiHeavy_8h.html#abb6905210a2f4021d157eeb61eaed7cd',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvoffset_6039',['kMitsubishiHeavy152SwingVOffset',['../ir__MitsubishiHeavy_8h.html#ae46f3549243667bbc38d6dc058772699',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvsize_6040',['kMitsubishiHeavy152SwingVSize',['../ir__MitsubishiHeavy_8h.html#a9cf7566686359cd5d553881b5eb96131',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy3dmask_6041',['kMitsubishiHeavy3DMask',['../ir__MitsubishiHeavy_8h.html#a16dcde537c9a2b1e8ddab4d6e08abb39',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88bits_6042',['kMitsubishiHeavy88Bits',['../IRremoteESP8266_8h.html#aa80d389140df4ab7071bfb3510b35dda',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88cleanoffset_6043',['kMitsubishiHeavy88CleanOffset',['../ir__MitsubishiHeavy_8h.html#ac0a4108b9ce94b3a85c2cb9680c98f4e',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanauto_6044',['kMitsubishiHeavy88FanAuto',['../ir__MitsubishiHeavy_8h.html#a607cbc27223765b3dd1f9bfd77932d0f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanecono_6045',['kMitsubishiHeavy88FanEcono',['../ir__MitsubishiHeavy_8h.html#ab5fbaaffd9e0182fc7e60252f89da2c3',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanhigh_6046',['kMitsubishiHeavy88FanHigh',['../ir__MitsubishiHeavy_8h.html#aa45b29aaa7d8df7a34dfe6308a6b6412',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanlow_6047',['kMitsubishiHeavy88FanLow',['../ir__MitsubishiHeavy_8h.html#a92f0cba1aef78e5ade01c648837e7553',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanmed_6048',['kMitsubishiHeavy88FanMed',['../ir__MitsubishiHeavy_8h.html#aade681ee8ed4c4647a997a3caad093ea',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanoffset_6049',['kMitsubishiHeavy88FanOffset',['../ir__MitsubishiHeavy_8h.html#a477fe23b5b186f4386e5d0cbded98710',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fansize_6050',['kMitsubishiHeavy88FanSize',['../ir__MitsubishiHeavy_8h.html#a68ffc738a040b3c95a839362e069fe8a',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanturbo_6051',['kMitsubishiHeavy88FanTurbo',['../ir__MitsubishiHeavy_8h.html#a29201ebd9395edb2660337ee00efa1dd',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88minrepeat_6052',['kMitsubishiHeavy88MinRepeat',['../IRremoteESP8266_8h.html#ad7bccde1a9b32c962c99748fb130f711',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88statelength_6053',['kMitsubishiHeavy88StateLength',['../IRremoteESP8266_8h.html#a515e5a081c388dd4313b20ff2b6c7955',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88swingh3d_6054',['kMitsubishiHeavy88SwingH3D',['../ir__MitsubishiHeavy_8h.html#adfeb87be0ddfc6c06bbcb4a1506d3185',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghauto_6055',['kMitsubishiHeavy88SwingHAuto',['../ir__MitsubishiHeavy_8h.html#ac39f2339ab90bdc6d9c98dd6cf95fce2',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleft_6056',['kMitsubishiHeavy88SwingHLeft',['../ir__MitsubishiHeavy_8h.html#a32a76b07c6da2b09d04d985544d91af1',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleftmax_6057',['kMitsubishiHeavy88SwingHLeftMax',['../ir__MitsubishiHeavy_8h.html#a83340e32cff8ca09eb7596ec55a67853',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleftright_6058',['kMitsubishiHeavy88SwingHLeftRight',['../ir__MitsubishiHeavy_8h.html#a82f7addc930441b6e756d71ce3df24ca',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghmiddle_6059',['kMitsubishiHeavy88SwingHMiddle',['../ir__MitsubishiHeavy_8h.html#a7a4b00b2953f2bc068d83c2618484c69',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoff_6060',['kMitsubishiHeavy88SwingHOff',['../ir__MitsubishiHeavy_8h.html#a5313aeb4115ca5a795c6ebb9871ce436',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoffset1_6061',['kMitsubishiHeavy88SwingHOffset1',['../ir__MitsubishiHeavy_8h.html#aeefa28e96d259e4ad5b63b86abf46f39',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoffset2_6062',['kMitsubishiHeavy88SwingHOffset2',['../ir__MitsubishiHeavy_8h.html#a9efbee563f821dad4006e8c56de9131d',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghright_6063',['kMitsubishiHeavy88SwingHRight',['../ir__MitsubishiHeavy_8h.html#a35224e254d897b9d42e16f9dae04d984',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghrightleft_6064',['kMitsubishiHeavy88SwingHRightLeft',['../ir__MitsubishiHeavy_8h.html#aa913c0f1c61260c533c66aaa12dc83ac',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghrightmax_6065',['kMitsubishiHeavy88SwingHRightMax',['../ir__MitsubishiHeavy_8h.html#a83c481d42999e377a2c50cacc28017b0',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghsize_6066',['kMitsubishiHeavy88SwingHSize',['../ir__MitsubishiHeavy_8h.html#a46a3cb1874cf5d1875e971094527b98f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvauto_6067',['kMitsubishiHeavy88SwingVAuto',['../ir__MitsubishiHeavy_8h.html#a65c66f030afd2795d3132b3d0be2cabe',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte5offset_6068',['kMitsubishiHeavy88SwingVByte5Offset',['../ir__MitsubishiHeavy_8h.html#adab63d1b0145cbea0953a9fdd34fd3cf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte5size_6069',['kMitsubishiHeavy88SwingVByte5Size',['../ir__MitsubishiHeavy_8h.html#ae0569562330f8c2af57a78764341c310',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte7offset_6070',['kMitsubishiHeavy88SwingVByte7Offset',['../ir__MitsubishiHeavy_8h.html#a8e864258ce7f01edb3b8d4672bba6312',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte7size_6071',['kMitsubishiHeavy88SwingVByte7Size',['../ir__MitsubishiHeavy_8h.html#a2e0d599b002366cc73d07f876d4fc0f7',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvhigh_6072',['kMitsubishiHeavy88SwingVHigh',['../ir__MitsubishiHeavy_8h.html#af99a8f0925f184f56080ddf3e9a37606',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvhighest_6073',['kMitsubishiHeavy88SwingVHighest',['../ir__MitsubishiHeavy_8h.html#adc2a20b5ca5dda6417c60a1a3c321fc0',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvlow_6074',['kMitsubishiHeavy88SwingVLow',['../ir__MitsubishiHeavy_8h.html#adb086c76e06cbf6c8808470363da5e93',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvlowest_6075',['kMitsubishiHeavy88SwingVLowest',['../ir__MitsubishiHeavy_8h.html#a6f4af31ee9b187648c242aca2851d3ed',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvmiddle_6076',['kMitsubishiHeavy88SwingVMiddle',['../ir__MitsubishiHeavy_8h.html#aeaddb1d80dd777c0fdd8e77661479598',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvoff_6077',['kMitsubishiHeavy88SwingVOff',['../ir__MitsubishiHeavy_8h.html#ad29f5b94153e0fc9943a2c4c02aa1f61',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyauto_6078',['kMitsubishiHeavyAuto',['../ir__MitsubishiHeavy_8h.html#a1bcb7429a89904e3b431aaaff20e35fa',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavybitmark_6079',['kMitsubishiHeavyBitMark',['../ir__MitsubishiHeavy_8cpp.html#a54b398e130a1893bdc81067c636d6001',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavycleanoffset_6080',['kMitsubishiHeavyCleanOffset',['../ir__MitsubishiHeavy_8h.html#acbcff6b22bf5dee4eeb1dbccc323409a',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavycool_6081',['kMitsubishiHeavyCool',['../ir__MitsubishiHeavy_8h.html#a5d819a9a6372fde79380a6890ffd3168',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavydry_6082',['kMitsubishiHeavyDry',['../ir__MitsubishiHeavy_8h.html#a749f4d74b6cce4ad29a7ab78bb780eaf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyfan_6083',['kMitsubishiHeavyFan',['../ir__MitsubishiHeavy_8h.html#a55d9e0b9676da64dfdc888e7941665f8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyfilteroffset_6084',['kMitsubishiHeavyFilterOffset',['../ir__MitsubishiHeavy_8h.html#a32232c193503a4a6bab8f783fdebeddf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavygap_6085',['kMitsubishiHeavyGap',['../ir__MitsubishiHeavy_8cpp.html#a92920bf4a95bccb9b55c623ff6dac96a',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyhdrmark_6086',['kMitsubishiHeavyHdrMark',['../ir__MitsubishiHeavy_8cpp.html#a9b1724efadc251117733297c424e76f4',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyhdrspace_6087',['kMitsubishiHeavyHdrSpace',['../ir__MitsubishiHeavy_8cpp.html#a9070250903c1d1653beb54ac3de27033',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyheat_6088',['kMitsubishiHeavyHeat',['../ir__MitsubishiHeavy_8h.html#a0b76a854d109dd0622155015edd31d74',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymaxtemp_6089',['kMitsubishiHeavyMaxTemp',['../ir__MitsubishiHeavy_8h.html#a49abbf34671b67eb4ebbe881444180f4',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymintemp_6090',['kMitsubishiHeavyMinTemp',['../ir__MitsubishiHeavy_8h.html#afa83fd435c67699da272b883277dbb98',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymodeoffset_6091',['kMitsubishiHeavyModeOffset',['../ir__MitsubishiHeavy_8h.html#a2ac27d9659d3a203c8cc360bda901d10',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavynightoffset_6092',['kMitsubishiHeavyNightOffset',['../ir__MitsubishiHeavy_8h.html#a01b341211034e272bf5d4be00b88cc78',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyonespace_6093',['kMitsubishiHeavyOneSpace',['../ir__MitsubishiHeavy_8cpp.html#adec6564e4af2886b4c7d44343d98b9dc',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavypoweroffset_6094',['kMitsubishiHeavyPowerOffset',['../ir__MitsubishiHeavy_8h.html#a51d81b3a7d97e423858e00aecd9719c9',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavysiglength_6095',['kMitsubishiHeavySigLength',['../ir__MitsubishiHeavy_8h.html#af08e6fc65b10821e52dd4a0073033d14',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavysilentoffset_6096',['kMitsubishiHeavySilentOffset',['../ir__MitsubishiHeavy_8h.html#a9b7eb89d7a3f08e84339317d1f21ca6f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyzerospace_6097',['kMitsubishiHeavyZeroSpace',['../ir__MitsubishiHeavy_8cpp.html#a903c30cee53f76c7dc3d2fef74b6e4b2',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyzjssig_6098',['kMitsubishiHeavyZjsSig',['../ir__MitsubishiHeavy_8h.html#a01eb89bfc9d4b271a97fea566eb937ff',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyzmssig_6099',['kMitsubishiHeavyZmsSig',['../ir__MitsubishiHeavy_8h.html#a18761991123d121c8d40531d07922165',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishimincommandlength_6100',['kMitsubishiMinCommandLength',['../ir__Mitsubishi_8cpp.html#ad5a6d37e755ce1faa4cdb024d2bed26a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimincommandlengthticks_6101',['kMitsubishiMinCommandLengthTicks',['../ir__Mitsubishi_8cpp.html#a4f69a50c720c7a19f0ee04d262eb5948',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimingap_6102',['kMitsubishiMinGap',['../ir__Mitsubishi_8cpp.html#a66f6379ca4c0e5f03eda2d81be0a35b2',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimingapticks_6103',['kMitsubishiMinGapTicks',['../ir__Mitsubishi_8cpp.html#af9e8409306344cf4cd0117f2131fc67a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiminrepeat_6104',['kMitsubishiMinRepeat',['../IRremoteESP8266_8h.html#ad88bda81b48f25d30bb5a169d3b6bcec',1,'IRremoteESP8266.h']]], + ['kmitsubishionespace_6105',['kMitsubishiOneSpace',['../ir__Mitsubishi_8cpp.html#ab3c6a50b722402633aaf26e2a4a39ff0',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishionespaceticks_6106',['kMitsubishiOneSpaceTicks',['../ir__Mitsubishi_8cpp.html#a3b12f2aa2c3b4b7ef439f86356aab9cf',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishitick_6107',['kMitsubishiTick',['../ir__Mitsubishi_8cpp.html#a5197eb8b6e8de8fdfb9f056b6f7d9aa5',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishizerospace_6108',['kMitsubishiZeroSpace',['../ir__Mitsubishi_8cpp.html#a9660ac382e9a929f6acb73a32b2a1a3c',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishizerospaceticks_6109',['kMitsubishiZeroSpaceTicks',['../ir__Mitsubishi_8cpp.html#a18f364a0ba491236538bc9d086303d69',1,'ir_Mitsubishi.cpp']]], + ['kmodebitssize_6110',['kModeBitsSize',['../IRutils_8h.html#a5432915ab86062fceadc067a233f1627',1,'IRutils.h']]], + ['kmodelstr_6111',['kModelStr',['../IRtext_8cpp.html#a40905418e2934e539c50c6cfc2c4ffe3',1,'kModelStr(): IRtext.cpp'],['../IRtext_8h.html#a4a553cfcc7ca2a8cea8e1263f5f6c186',1,'kModelStr(): IRtext.cpp']]], + ['kmodestr_6112',['kModeStr',['../IRtext_8cpp.html#a7260c578d290c33b7705cd1439d992ee',1,'kModeStr(): IRtext.cpp'],['../IRtext_8h.html#a6666695e388b607bfd3bb0e6efd4193f',1,'kModeStr(): IRtext.cpp']]], + ['kmouldstr_6113',['kMouldStr',['../IRtext_8cpp.html#ac665ea584a4949565aa35629d791dbc5',1,'kMouldStr(): IRtext.cpp'],['../IRtext_8h.html#a693b29e4764d959dac781a0992f2bf30',1,'kMouldStr(): IRtext.cpp']]], + ['kmovestr_6114',['kMoveStr',['../IRtext_8cpp.html#a321f98699209fb487287c4911a0c0200',1,'kMoveStr(): IRtext.cpp'],['../IRtext_8h.html#ae99940df2a9243fd7fe6f3814c0802dd',1,'kMoveStr(): IRtext.cpp']]], + ['kmultibracketsbits_6115',['kMultibracketsBits',['../IRremoteESP8266_8h.html#aad7be0971479839493615cafcd654fc1',1,'IRremoteESP8266.h']]], + ['kmultibracketsdefaultrepeat_6116',['kMultibracketsDefaultRepeat',['../IRremoteESP8266_8h.html#a5aa418baefd018d5facc08d3bb721fe9',1,'IRremoteESP8266.h']]], + ['kmultibracketsfooterspace_6117',['kMultibracketsFooterSpace',['../ir__Multibrackets_8cpp.html#a738cde2d6a25611bea116d04375dd28a',1,'ir_Multibrackets.cpp']]], + ['kmultibracketsfreq_6118',['kMultibracketsFreq',['../ir__Multibrackets_8cpp.html#a38ba01a3c516f6018199aa9031a5fb4a',1,'ir_Multibrackets.cpp']]], + ['kmultibracketshdrmark_6119',['kMultibracketsHdrMark',['../ir__Multibrackets_8cpp.html#a4eaafbf701604ceb6591b8a8b9c1d202',1,'ir_Multibrackets.cpp']]], + ['kmultibracketstick_6120',['kMultibracketsTick',['../ir__Multibrackets_8cpp.html#aa528fbf06b8d5293d82b7efc2bcd1e9b',1,'ir_Multibrackets.cpp']]], + ['kmultibracketstolerance_6121',['kMultibracketsTolerance',['../ir__Multibrackets_8cpp.html#a242017fb86f015cdecbf31c278c43ccc',1,'ir_Multibrackets.cpp']]], + ['kmwmdelta_6122',['kMWMDelta',['../ir__MWM_8cpp.html#a4e32849a3c799af002d1290a8a33366e',1,'ir_MWM.cpp']]], + ['kmwmexcess_6123',['kMWMExcess',['../ir__MWM_8cpp.html#ab3ff88bfc09c94e70fb74a77dbdd87d7',1,'ir_MWM.cpp']]], + ['kmwmmaxwidth_6124',['kMWMMaxWidth',['../ir__MWM_8cpp.html#a833013dcb331ebce3b885b0ce73c9eaa',1,'ir_MWM.cpp']]], + ['kmwmmingap_6125',['kMWMMinGap',['../ir__MWM_8cpp.html#a4d1f9c5442390a5ba089270c1187e917',1,'ir_MWM.cpp']]], + ['kmwmminsamples_6126',['kMWMMinSamples',['../ir__MWM_8cpp.html#ad386c922a0fcbd0c5b904b9abdd8d582',1,'ir_MWM.cpp']]], + ['kmwmtick_6127',['kMWMTick',['../ir__MWM_8cpp.html#a42c39c0101ccad1e88fa206a26447256',1,'ir_MWM.cpp']]], + ['kmwmtolerance_6128',['kMWMTolerance',['../ir__MWM_8cpp.html#ae3a91ec66f51f50810229b4adc1264fd',1,'ir_MWM.cpp']]], + ['knastr_6129',['kNAStr',['../IRtext_8cpp.html#a1757349137713553454f405872bc4dcd',1,'kNAStr(): IRtext.cpp'],['../IRtext_8h.html#a5d094344fba1715dbde69ff947775264',1,'kNAStr(): IRtext.cpp']]], + ['knecbitmark_6130',['kNecBitMark',['../ir__NEC_8h.html#ab536a800ec8f7259fe7e485ea4aea465',1,'ir_NEC.h']]], + ['knecbitmarkticks_6131',['kNecBitMarkTicks',['../ir__NEC_8h.html#a84ca60f84d64d65872b40a87819eccc1',1,'ir_NEC.h']]], + ['knecbits_6132',['kNECBits',['../IRremoteESP8266_8h.html#a65e03baf646815b4b02f943bdd74a097',1,'IRremoteESP8266.h']]], + ['knechdrmark_6133',['kNecHdrMark',['../ir__NEC_8h.html#ac727ede47d30ec76b03e4a41b48ce8c7',1,'ir_NEC.h']]], + ['knechdrmarkticks_6134',['kNecHdrMarkTicks',['../ir__NEC_8h.html#ab1486c07a09bc4324c03b1c887f5c5f7',1,'ir_NEC.h']]], + ['knechdrspace_6135',['kNecHdrSpace',['../ir__NEC_8h.html#a8279410369d6ed266502615d3ff1750b',1,'ir_NEC.h']]], + ['knechdrspaceticks_6136',['kNecHdrSpaceTicks',['../ir__NEC_8h.html#a4470ee927c0c3447bdda20c52b0f8566',1,'ir_NEC.h']]], + ['knecmincommandlength_6137',['kNecMinCommandLength',['../ir__NEC_8h.html#ac7b8d897d9e5bbf29b9b1b899a2ef7d8',1,'ir_NEC.h']]], + ['knecmincommandlengthticks_6138',['kNecMinCommandLengthTicks',['../ir__NEC_8h.html#a78e411960e643495987b1cb53268bc46',1,'ir_NEC.h']]], + ['knecmingap_6139',['kNecMinGap',['../ir__NEC_8h.html#a3d6ecc128599df57dc98e97e51b2264e',1,'ir_NEC.h']]], + ['knecmingapticks_6140',['kNecMinGapTicks',['../ir__NEC_8h.html#a2e6d938510a34aa1217a56aa51ece9f5',1,'ir_NEC.h']]], + ['kneconespace_6141',['kNecOneSpace',['../ir__NEC_8h.html#af57080e9b7513d1c8e7e781f3d502fbd',1,'ir_NEC.h']]], + ['kneconespaceticks_6142',['kNecOneSpaceTicks',['../ir__NEC_8h.html#a2f1e5412d44816f92e4b6c72e16e8b1f',1,'ir_NEC.h']]], + ['knecrptlength_6143',['kNecRptLength',['../ir__NEC_8h.html#af4ab20595dfda177fbb06dd821ea14c7',1,'ir_NEC.h']]], + ['knecrptspace_6144',['kNecRptSpace',['../ir__NEC_8h.html#a9538478446b1ae5d72c8366dd6a11673',1,'ir_NEC.h']]], + ['knecrptspaceticks_6145',['kNecRptSpaceTicks',['../ir__NEC_8h.html#a91b5296d480008a4b44c5b084756f04b',1,'ir_NEC.h']]], + ['knectick_6146',['kNecTick',['../ir__NEC_8h.html#abe1ec110798236c7b626f7efe4cc5657',1,'ir_NEC.h']]], + ['kneczerospace_6147',['kNecZeroSpace',['../ir__NEC_8h.html#a00573a6bdb348339b9898173b644b693',1,'ir_NEC.h']]], + ['kneczerospaceticks_6148',['kNecZeroSpaceTicks',['../ir__NEC_8h.html#a80f316535d761c64f1d5752ef80a65ff',1,'ir_NEC.h']]], + ['kneoclima8cheatoffset_6149',['kNeoclima8CHeatOffset',['../ir__Neoclima_8h.html#a4e9654ac35708a22912448eef3eb2b35',1,'ir_Neoclima.h']]], + ['kneoclimaauto_6150',['kNeoclimaAuto',['../ir__Neoclima_8h.html#a4574742c21aae9aafaff9b10f9423006',1,'ir_Neoclima.h']]], + ['kneoclimabitmark_6151',['kNeoclimaBitMark',['../ir__Neoclima_8cpp.html#ae34236a830ec2d200575ac33fda43689',1,'ir_Neoclima.cpp']]], + ['kneoclimabits_6152',['kNeoclimaBits',['../IRremoteESP8266_8h.html#afff9132e57296b4d7e04ec9e1e5ab04f',1,'IRremoteESP8266.h']]], + ['kneoclimabutton8cheat_6153',['kNeoclimaButton8CHeat',['../ir__Neoclima_8h.html#ad337d964ff800bea5c55f1fe69dfb7ff',1,'ir_Neoclima.h']]], + ['kneoclimabuttonairflow_6154',['kNeoclimaButtonAirFlow',['../ir__Neoclima_8h.html#ab5fff838f8e5ac9ff213fc69346ffa7c',1,'ir_Neoclima.h']]], + ['kneoclimabuttoneye_6155',['kNeoclimaButtonEye',['../ir__Neoclima_8h.html#a6cabdccd3c8d52cb2817f99454bdc884',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfanspeed_6156',['kNeoclimaButtonFanSpeed',['../ir__Neoclima_8h.html#ab41ffd863516b79b6c7e9b69e7d5a272',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfollow_6157',['kNeoclimaButtonFollow',['../ir__Neoclima_8h.html#a592017dce3bfa4ea2f0f341a818aff72',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfresh_6158',['kNeoclimaButtonFresh',['../ir__Neoclima_8h.html#a6a965f2dc7860879ccaf410405095e9c',1,'ir_Neoclima.h']]], + ['kneoclimabuttonhold_6159',['kNeoclimaButtonHold',['../ir__Neoclima_8h.html#aada6fdb6572bd7d841de89f1d1eed3fe',1,'ir_Neoclima.h']]], + ['kneoclimabuttonion_6160',['kNeoclimaButtonIon',['../ir__Neoclima_8h.html#a05dccf1c19237d315bb78f387f8fd57f',1,'ir_Neoclima.h']]], + ['kneoclimabuttonlight_6161',['kNeoclimaButtonLight',['../ir__Neoclima_8h.html#ac66b472b31f6183f4615584561baa284',1,'ir_Neoclima.h']]], + ['kneoclimabuttonmode_6162',['kNeoclimaButtonMode',['../ir__Neoclima_8h.html#a4cfee4b0898f1504be5cbd129cd99278',1,'ir_Neoclima.h']]], + ['kneoclimabuttonoffset_6163',['kNeoclimaButtonOffset',['../ir__Neoclima_8h.html#a08ae86c15defd78ecac0f322f84190d3',1,'ir_Neoclima.h']]], + ['kneoclimabuttonpower_6164',['kNeoclimaButtonPower',['../ir__Neoclima_8h.html#a047d19978c58b35dcd6a069fce04af87',1,'ir_Neoclima.h']]], + ['kneoclimabuttonsize_6165',['kNeoclimaButtonSize',['../ir__Neoclima_8h.html#aac90dbf9fe499df2edf64df44f449e57',1,'ir_Neoclima.h']]], + ['kneoclimabuttonsleep_6166',['kNeoclimaButtonSleep',['../ir__Neoclima_8h.html#adcbe2a89eecf41fe1fe2b8c62428084e',1,'ir_Neoclima.h']]], + ['kneoclimabuttonswing_6167',['kNeoclimaButtonSwing',['../ir__Neoclima_8h.html#aeea180bef85a40d8c7fe3f5facf7b199',1,'ir_Neoclima.h']]], + ['kneoclimabuttontempdown_6168',['kNeoclimaButtonTempDown',['../ir__Neoclima_8h.html#aee91f1ebdf89b6fe9f3b31937d1185a0',1,'ir_Neoclima.h']]], + ['kneoclimabuttontempup_6169',['kNeoclimaButtonTempUp',['../ir__Neoclima_8h.html#abb093132f77d179ab02fc4a022d55236',1,'ir_Neoclima.h']]], + ['kneoclimabuttonturbo_6170',['kNeoclimaButtonTurbo',['../ir__Neoclima_8h.html#af156d94f9e47e8b5e2e2493308cca04c',1,'ir_Neoclima.h']]], + ['kneoclimacool_6171',['kNeoclimaCool',['../ir__Neoclima_8h.html#ac5d874e5ffce72ce68176f38e780c439',1,'ir_Neoclima.h']]], + ['kneoclimadry_6172',['kNeoclimaDry',['../ir__Neoclima_8h.html#ab68ba4480e1bcb685579c5f902d0709e',1,'ir_Neoclima.h']]], + ['kneoclimaeyeoffset_6173',['kNeoclimaEyeOffset',['../ir__Neoclima_8h.html#ad7baeea22b87a69150c65b2c049ee0b2',1,'ir_Neoclima.h']]], + ['kneoclimafan_6174',['kNeoclimaFan',['../ir__Neoclima_8h.html#aa6166bd65d80a708d790dbf703c83ea2',1,'ir_Neoclima.h']]], + ['kneoclimafanauto_6175',['kNeoclimaFanAuto',['../ir__Neoclima_8h.html#a7885fdbc4ae3336aac74d7ee3d8c3258',1,'ir_Neoclima.h']]], + ['kneoclimafanhigh_6176',['kNeoclimaFanHigh',['../ir__Neoclima_8h.html#a57ddf91c1cbb157b3a53b1082bac2d75',1,'ir_Neoclima.h']]], + ['kneoclimafanlow_6177',['kNeoclimaFanLow',['../ir__Neoclima_8h.html#ac9031328be51a46543ebd4360aaca55a',1,'ir_Neoclima.h']]], + ['kneoclimafanmed_6178',['kNeoclimaFanMed',['../ir__Neoclima_8h.html#a11faf2a34faf44460795b50bfbdab402',1,'ir_Neoclima.h']]], + ['kneoclimafanoffest_6179',['kNeoclimaFanOffest',['../ir__Neoclima_8h.html#a32f614475b5f00f8ccdf12498c519713',1,'ir_Neoclima.h']]], + ['kneoclimafansize_6180',['kNeoclimaFanSize',['../ir__Neoclima_8h.html#a888cbc3f0a38137cb909188b6fff91b1',1,'ir_Neoclima.h']]], + ['kneoclimafollowme_6181',['kNeoclimaFollowMe',['../ir__Neoclima_8h.html#a493c1e6b8b8909f4201cd506a1f4804a',1,'ir_Neoclima.h']]], + ['kneoclimafreshoffset_6182',['kNeoclimaFreshOffset',['../ir__Neoclima_8h.html#af19f0f77ece049bdef26930be1b0309f',1,'ir_Neoclima.h']]], + ['kneoclimahdrmark_6183',['kNeoclimaHdrMark',['../ir__Neoclima_8cpp.html#aa392821c0ce822a7b7d67efd202bedd5',1,'ir_Neoclima.cpp']]], + ['kneoclimahdrspace_6184',['kNeoclimaHdrSpace',['../ir__Neoclima_8cpp.html#a3714ad66d75162ccb286152b70375588',1,'ir_Neoclima.cpp']]], + ['kneoclimaheat_6185',['kNeoclimaHeat',['../ir__Neoclima_8h.html#a5a5e53801c0f8e554c391ed56404b926',1,'ir_Neoclima.h']]], + ['kneoclimaholdoffset_6186',['kNeoclimaHoldOffset',['../ir__Neoclima_8h.html#a3a91e7504c7820223021dcc2cbbf9f2a',1,'ir_Neoclima.h']]], + ['kneoclimaionoffset_6187',['kNeoclimaIonOffset',['../ir__Neoclima_8h.html#ad420932425fbe261368938e604dfb0c1',1,'ir_Neoclima.h']]], + ['kneoclimalightoffset_6188',['kNeoclimaLightOffset',['../ir__Neoclima_8h.html#af58a863257c5d436b299ac8cbcb57686',1,'ir_Neoclima.h']]], + ['kneoclimamaxtemp_6189',['kNeoclimaMaxTemp',['../ir__Neoclima_8h.html#a755ef8290df8a3e19f236839bee42412',1,'ir_Neoclima.h']]], + ['kneoclimamingap_6190',['kNeoclimaMinGap',['../ir__Neoclima_8cpp.html#a0e54c73eff563f6c3ec39a0951dd3d2d',1,'ir_Neoclima.cpp']]], + ['kneoclimaminrepeat_6191',['kNeoclimaMinRepeat',['../IRremoteESP8266_8h.html#a16fc26a3ff66a66068ac9638554df847',1,'IRremoteESP8266.h']]], + ['kneoclimamintemp_6192',['kNeoclimaMinTemp',['../ir__Neoclima_8h.html#adc979ad2ac64481f13b1085b1fdd13c4',1,'ir_Neoclima.h']]], + ['kneoclimamodeoffset_6193',['kNeoclimaModeOffset',['../ir__Neoclima_8h.html#a823a960610ef3387099d2a2103dd0b56',1,'ir_Neoclima.h']]], + ['kneoclimaonespace_6194',['kNeoclimaOneSpace',['../ir__Neoclima_8cpp.html#a5fd5f3b7f04134190aafc65762528da0',1,'ir_Neoclima.cpp']]], + ['kneoclimapoweroffset_6195',['kNeoclimaPowerOffset',['../ir__Neoclima_8h.html#a9b881e5400fe9bcd3b1422aeb355cf7c',1,'ir_Neoclima.h']]], + ['kneoclimasleepoffset_6196',['kNeoclimaSleepOffset',['../ir__Neoclima_8h.html#ac0c978cdc30827c7390b93a9a4f05d24',1,'ir_Neoclima.h']]], + ['kneoclimastatelength_6197',['kNeoclimaStateLength',['../IRremoteESP8266_8h.html#a5a871ed6d145c5ea3d50e96600c02e31',1,'IRremoteESP8266.h']]], + ['kneoclimaswinghoffset_6198',['kNeoclimaSwingHOffset',['../ir__Neoclima_8h.html#a5f2e8ccaa590386b0947b0f291ebcb09',1,'ir_Neoclima.h']]], + ['kneoclimaswingvoff_6199',['kNeoclimaSwingVOff',['../ir__Neoclima_8h.html#ad230a8c18e6edb5709cb29033f1fd221',1,'ir_Neoclima.h']]], + ['kneoclimaswingvoffset_6200',['kNeoclimaSwingVOffset',['../ir__Neoclima_8h.html#a91b63c4712093684625a16c76bcc6784',1,'ir_Neoclima.h']]], + ['kneoclimaswingvon_6201',['kNeoclimaSwingVOn',['../ir__Neoclima_8h.html#a7021804eb30e7a7c5b9c9ababb1b8cad',1,'ir_Neoclima.h']]], + ['kneoclimaswingvsize_6202',['kNeoclimaSwingVSize',['../ir__Neoclima_8h.html#ab4b49ec2c326d0e94eba23e7a93b6fc6',1,'ir_Neoclima.h']]], + ['kneoclimatempoffset_6203',['kNeoclimaTempOffset',['../ir__Neoclima_8h.html#a5c3470f6c773b4c557e6996f8c29a573',1,'ir_Neoclima.h']]], + ['kneoclimatempsize_6204',['kNeoclimaTempSize',['../ir__Neoclima_8h.html#af848fc3f4ce46c8786fd2b3e129b1e48',1,'ir_Neoclima.h']]], + ['kneoclimaturbooffset_6205',['kNeoclimaTurboOffset',['../ir__Neoclima_8h.html#ae23c6faf5f54ff12d592360b42d69971',1,'ir_Neoclima.h']]], + ['kneoclimazerospace_6206',['kNeoclimaZeroSpace',['../ir__Neoclima_8cpp.html#a0b98d84da4651d8d31f8f1d84621c21e',1,'ir_Neoclima.cpp']]], + ['knibblesize_6207',['kNibbleSize',['../IRutils_8h.html#aa72cd082cdde3d8d7473ed9d11ff6846',1,'IRutils.h']]], + ['knightstr_6208',['kNightStr',['../IRtext_8cpp.html#a01908d3c0f79bc015a699fc0576a8771',1,'kNightStr(): IRtext.cpp'],['../IRtext_8h.html#afe6519eaae5b1fb4d110529ce98f05b0',1,'kNightStr(): IRtext.cpp']]], + ['knikaibitmark_6209',['kNikaiBitMark',['../ir__Nikai_8cpp.html#ad665145b0ee9cc722d9fde43cbd3fd82',1,'ir_Nikai.cpp']]], + ['knikaibitmarkticks_6210',['kNikaiBitMarkTicks',['../ir__Nikai_8cpp.html#ac10d1b4c45af3ddbf3c50b85dbb0c2f0',1,'ir_Nikai.cpp']]], + ['knikaibits_6211',['kNikaiBits',['../IRremoteESP8266_8h.html#a9fce002592f9e2488b1b717d0b1a6a40',1,'IRremoteESP8266.h']]], + ['knikaihdrmark_6212',['kNikaiHdrMark',['../ir__Nikai_8cpp.html#ae0656b931e18e6e011a7c74cfaf4384b',1,'ir_Nikai.cpp']]], + ['knikaihdrmarkticks_6213',['kNikaiHdrMarkTicks',['../ir__Nikai_8cpp.html#a11671cee9a312ece8f1c90596eddd7ac',1,'ir_Nikai.cpp']]], + ['knikaihdrspace_6214',['kNikaiHdrSpace',['../ir__Nikai_8cpp.html#ae801e20e669f3039888bf48074988b84',1,'ir_Nikai.cpp']]], + ['knikaihdrspaceticks_6215',['kNikaiHdrSpaceTicks',['../ir__Nikai_8cpp.html#a83885a2fc573f947afe5015cd2f4d953',1,'ir_Nikai.cpp']]], + ['knikaimingap_6216',['kNikaiMinGap',['../ir__Nikai_8cpp.html#ad88846eaa7559df7fb944283fd292da1',1,'ir_Nikai.cpp']]], + ['knikaimingapticks_6217',['kNikaiMinGapTicks',['../ir__Nikai_8cpp.html#afdf938a763f30e3c5e534eba269dff1f',1,'ir_Nikai.cpp']]], + ['knikaionespace_6218',['kNikaiOneSpace',['../ir__Nikai_8cpp.html#a4bb69ab22b2abcd20ffff90f9267fa43',1,'ir_Nikai.cpp']]], + ['knikaionespaceticks_6219',['kNikaiOneSpaceTicks',['../ir__Nikai_8cpp.html#a25a4d289b7fad06c31312df552ee81ab',1,'ir_Nikai.cpp']]], + ['knikaitick_6220',['kNikaiTick',['../ir__Nikai_8cpp.html#a70eb8953509420081d0a294203eeb34b',1,'ir_Nikai.cpp']]], + ['knikaizerospace_6221',['kNikaiZeroSpace',['../ir__Nikai_8cpp.html#aa9af57c5c936107b00096e16cc6f57d9',1,'ir_Nikai.cpp']]], + ['knikaizerospaceticks_6222',['kNikaiZeroSpaceTicks',['../ir__Nikai_8cpp.html#a8df777a744c018e27c6969c2109d6d79',1,'ir_Nikai.cpp']]], + ['knorepeat_6223',['kNoRepeat',['../IRremoteESP8266_8h.html#a1a49dde7ffbd753f7756cf0c9dc6d826',1,'IRremoteESP8266.h']]], + ['knostr_6224',['kNoStr',['../IRtext_8cpp.html#a07897ceb4a6607d87ef37a517908a4b5',1,'kNoStr(): IRtext.cpp'],['../IRtext_8h.html#a51c9fb58ee7d01e96e2571018aea746d',1,'kNoStr(): IRtext.cpp']]], + ['knowstr_6225',['kNowStr',['../IRtext_8cpp.html#a09d8590020bcf998746528d0e50f7a20',1,'kNowStr(): IRtext.cpp'],['../IRtext_8h.html#a6a3c0965a32c36d9b5aa4918b473cc12',1,'kNowStr(): IRtext.cpp']]], + ['koffstr_6226',['kOffStr',['../IRtext_8cpp.html#a9ce19a214db45b8cff83032ffa1ccdd8',1,'kOffStr(): IRtext.cpp'],['../IRtext_8h.html#a95f119413a113c9a2e8c246892b8c52a',1,'kOffStr(): IRtext.cpp']]], + ['kofftimerstr_6227',['kOffTimerStr',['../IRtext_8cpp.html#ae5faab97b26f9e877f79f49002bbba2c',1,'kOffTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a818275085f8a8d7c083b66f081689b1f',1,'kOffTimerStr(): IRtext.cpp']]], + ['konstr_6228',['kOnStr',['../IRtext_8cpp.html#ab3f42c8df156baa46326a57193f78c51',1,'kOnStr(): IRtext.cpp'],['../IRtext_8h.html#aaf4ffad7f827a2ce8512e644bc9c25c7',1,'kOnStr(): IRtext.cpp']]], + ['kontimerstr_6229',['kOnTimerStr',['../IRtext_8cpp.html#adaecb1b5526f2bb3a1334e816a414273',1,'kOnTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a9f355a0d834790287d95eea30b57564d',1,'kOnTimerStr(): IRtext.cpp']]], + ['koutsidequietstr_6230',['kOutsideQuietStr',['../IRtext_8cpp.html#a103f2a8a2a6d351cd8ea259de3c454ef',1,'kOutsideQuietStr(): IRtext.cpp'],['../IRtext_8h.html#afaf12ae53365f790b47ff3790e94cc1c',1,'kOutsideQuietStr(): IRtext.cpp']]], + ['koutsidestr_6231',['kOutsideStr',['../IRtext_8cpp.html#a8465ee1e8b1e5dd58a9cf872c9569e01',1,'kOutsideStr(): IRtext.cpp'],['../IRtext_8h.html#ada5c81e0fcc4073d6f51e7447e8c5da0',1,'kOutsideStr(): IRtext.cpp']]], + ['kpanasonicacauto_6232',['kPanasonicAcAuto',['../ir__Panasonic_8h.html#aa7c839a4342205c384870e8a4f5ec36b',1,'ir_Panasonic.h']]], + ['kpanasonicacbits_6233',['kPanasonicAcBits',['../IRremoteESP8266_8h.html#a210f5c78b0f90b64dd5037698141433a',1,'IRremoteESP8266.h']]], + ['kpanasonicacchecksuminit_6234',['kPanasonicAcChecksumInit',['../ir__Panasonic_8h.html#a49329b4fef403696effcbcc5c8a86cd2',1,'ir_Panasonic.h']]], + ['kpanasonicaccool_6235',['kPanasonicAcCool',['../ir__Panasonic_8h.html#acfaa3d61fbb13fc6cd8d354f1c0a8dc7',1,'ir_Panasonic.h']]], + ['kpanasonicacdefaultrepeat_6236',['kPanasonicAcDefaultRepeat',['../IRremoteESP8266_8h.html#af6b7c6ad564253cb128ac92c00e86f0c',1,'IRremoteESP8266.h']]], + ['kpanasonicacdry_6237',['kPanasonicAcDry',['../ir__Panasonic_8h.html#a2d211bd2150a67819453f3220dc0cc91',1,'ir_Panasonic.h']]], + ['kpanasonicacexcess_6238',['kPanasonicAcExcess',['../ir__Panasonic_8h.html#adde8b69377faa9a4566dc15e95711257',1,'ir_Panasonic.h']]], + ['kpanasonicacfan_6239',['kPanasonicAcFan',['../ir__Panasonic_8h.html#a87e4dd423bbd1f879a9d5da31e1fea5e',1,'ir_Panasonic.h']]], + ['kpanasonicacfanauto_6240',['kPanasonicAcFanAuto',['../ir__Panasonic_8h.html#a7d4486fd68969af4f7230f12e865c698',1,'ir_Panasonic.h']]], + ['kpanasonicacfandelta_6241',['kPanasonicAcFanDelta',['../ir__Panasonic_8h.html#a2210f85a17fba2bbdfbb883e9fb57e52',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmax_6242',['kPanasonicAcFanMax',['../ir__Panasonic_8h.html#aa4599c84d72ab9c622b642870efb9cf1',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmed_6243',['kPanasonicAcFanMed',['../ir__Panasonic_8h.html#a978004e8e2c4122fec81c5a972b842a0',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmin_6244',['kPanasonicAcFanMin',['../ir__Panasonic_8h.html#a450c7951a525817d27351fb7c8ff2df9',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmodetemp_6245',['kPanasonicAcFanModeTemp',['../ir__Panasonic_8h.html#a76543f9d81c2d109e04359f0c61dcb99',1,'ir_Panasonic.h']]], + ['kpanasonicacheat_6246',['kPanasonicAcHeat',['../ir__Panasonic_8h.html#ac37bb7dd975a9aa803edfc108a5071ed',1,'ir_Panasonic.h']]], + ['kpanasonicacionfilterbyte_6247',['kPanasonicAcIonFilterByte',['../ir__Panasonic_8h.html#a16c946660d2ee3821dd2e30a69144a38',1,'ir_Panasonic.h']]], + ['kpanasonicacionfilteroffset_6248',['kPanasonicAcIonFilterOffset',['../ir__Panasonic_8h.html#a5c1b18d1b834e9d46cbd29c74a1b8269',1,'ir_Panasonic.h']]], + ['kpanasonicacmaxtemp_6249',['kPanasonicAcMaxTemp',['../ir__Panasonic_8h.html#a95fe6bc5b2565bf29d1a6dcee2f0c39f',1,'ir_Panasonic.h']]], + ['kpanasonicacmessagegap_6250',['kPanasonicAcMessageGap',['../ir__Panasonic_8cpp.html#a962cde97e8d98ad32f0b59172b641d6d',1,'ir_Panasonic.cpp']]], + ['kpanasonicacmintemp_6251',['kPanasonicAcMinTemp',['../ir__Panasonic_8h.html#a7861e8477904e1a572bcf35286fd3733',1,'ir_Panasonic.h']]], + ['kpanasonicacofftimeroffset_6252',['kPanasonicAcOffTimerOffset',['../ir__Panasonic_8h.html#a477b61044f1db5c296f13a404c536046',1,'ir_Panasonic.h']]], + ['kpanasonicacontimeroffset_6253',['kPanasonicAcOnTimerOffset',['../ir__Panasonic_8h.html#a64350202f82aabfd1673f0dda4d3c13d',1,'ir_Panasonic.h']]], + ['kpanasonicacpowerfulckpoffset_6254',['kPanasonicAcPowerfulCkpOffset',['../ir__Panasonic_8h.html#aa839301a08c8e49548f497e786dbb6fa',1,'ir_Panasonic.h']]], + ['kpanasonicacpowerfuloffset_6255',['kPanasonicAcPowerfulOffset',['../ir__Panasonic_8h.html#a27e9b1af4b65830015576beed69cb27d',1,'ir_Panasonic.h']]], + ['kpanasonicacpoweroffset_6256',['kPanasonicAcPowerOffset',['../ir__Panasonic_8h.html#a9e9b3d0c77ef93ab472ce14ed1534c77',1,'ir_Panasonic.h']]], + ['kpanasonicacquietckpoffset_6257',['kPanasonicAcQuietCkpOffset',['../ir__Panasonic_8h.html#a5a3779cd6fd8d573ae14ed4a6d676dba',1,'ir_Panasonic.h']]], + ['kpanasonicacquietoffset_6258',['kPanasonicAcQuietOffset',['../ir__Panasonic_8h.html#a1ec8db8798f79dead05233ee6333700d',1,'ir_Panasonic.h']]], + ['kpanasonicacsection1length_6259',['kPanasonicAcSection1Length',['../ir__Panasonic_8cpp.html#a34c6c085d468ed4b35f814452335d334',1,'ir_Panasonic.cpp']]], + ['kpanasonicacsectiongap_6260',['kPanasonicAcSectionGap',['../ir__Panasonic_8cpp.html#a3cf28f1268e8a35da220d42deda7c456',1,'ir_Panasonic.cpp']]], + ['kpanasonicacshortbits_6261',['kPanasonicAcShortBits',['../IRremoteESP8266_8h.html#a2fd1f84669f7994bb3c235a508333c6c',1,'IRremoteESP8266.h']]], + ['kpanasonicacstatelength_6262',['kPanasonicAcStateLength',['../IRremoteESP8266_8h.html#ab21d86545b57738354e7a3b833d38f94',1,'IRremoteESP8266.h']]], + ['kpanasonicacstateshortlength_6263',['kPanasonicAcStateShortLength',['../IRremoteESP8266_8h.html#a0a6ca8c1dfa6f313421ddf268d76d8e6',1,'IRremoteESP8266.h']]], + ['kpanasonicacswinghauto_6264',['kPanasonicAcSwingHAuto',['../ir__Panasonic_8h.html#a91e2933692ad98acf054c7a69f6c2018',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghfullleft_6265',['kPanasonicAcSwingHFullLeft',['../ir__Panasonic_8h.html#abf1d8c53a1b69d99019c6878f9ec220d',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghfullright_6266',['kPanasonicAcSwingHFullRight',['../ir__Panasonic_8h.html#a0e1b7a7591a0f14b2f8be3cb222f1187',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghleft_6267',['kPanasonicAcSwingHLeft',['../ir__Panasonic_8h.html#a853f2c2922e03a975bdd11efc474fa7e',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghmiddle_6268',['kPanasonicAcSwingHMiddle',['../ir__Panasonic_8h.html#afad8a7257fc178321867f16939fff7c7',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghright_6269',['kPanasonicAcSwingHRight',['../ir__Panasonic_8h.html#a282900f1c494efdc6ee057357e624d2e',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvauto_6270',['kPanasonicAcSwingVAuto',['../ir__Panasonic_8h.html#a218e2ea8c76966105c71edcb6e46cd12',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvhigh_6271',['kPanasonicAcSwingVHigh',['../ir__Panasonic_8h.html#a25c63195112c5aedc5b5bad40441c55a',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvhighest_6272',['kPanasonicAcSwingVHighest',['../ir__Panasonic_8h.html#ac1cea523d6e1da08d333e0b4acec81af',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvlow_6273',['kPanasonicAcSwingVLow',['../ir__Panasonic_8h.html#a3ae9b6c5581f1bfb5b31e252052a6c9d',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvlowest_6274',['kPanasonicAcSwingVLowest',['../ir__Panasonic_8h.html#af269e81dae5989c33199d607adcc04a0',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvmiddle_6275',['kPanasonicAcSwingVMiddle',['../ir__Panasonic_8h.html#a5d46c8234f97e10695507b17a7483d51',1,'ir_Panasonic.h']]], + ['kpanasonicactempoffset_6276',['kPanasonicAcTempOffset',['../ir__Panasonic_8h.html#a203e0351cd53db8376312a3289503175',1,'ir_Panasonic.h']]], + ['kpanasonicactempsize_6277',['kPanasonicAcTempSize',['../ir__Panasonic_8h.html#af30649a3489a4a1dc1f655d15c00e991',1,'ir_Panasonic.h']]], + ['kpanasonicactimemax_6278',['kPanasonicAcTimeMax',['../ir__Panasonic_8h.html#a61378ccad09d1a2e900123a8cbd34858',1,'ir_Panasonic.h']]], + ['kpanasonicactimeoverflowsize_6279',['kPanasonicAcTimeOverflowSize',['../ir__Panasonic_8h.html#ad7942b5ffbb2b1f7a5d9b3719592622b',1,'ir_Panasonic.h']]], + ['kpanasonicactimesize_6280',['kPanasonicAcTimeSize',['../ir__Panasonic_8h.html#a16577844a2f5ca46e2dff076952f2963',1,'ir_Panasonic.h']]], + ['kpanasonicactimespecial_6281',['kPanasonicAcTimeSpecial',['../ir__Panasonic_8h.html#aefb20e7cdbbc27e3c0725a8660a84a28',1,'ir_Panasonic.h']]], + ['kpanasonicactolerance_6282',['kPanasonicAcTolerance',['../ir__Panasonic_8h.html#a586a655b3afd82c38588fc1b61089aa1',1,'ir_Panasonic.h']]], + ['kpanasonicbitmark_6283',['kPanasonicBitMark',['../ir__Panasonic_8cpp.html#a428cd02c5dc3dc571e495efa0707cc99',1,'ir_Panasonic.cpp']]], + ['kpanasonicbitmarkticks_6284',['kPanasonicBitMarkTicks',['../ir__Panasonic_8cpp.html#aa0b259da4bc3dbf6c8b2ca31de759f55',1,'ir_Panasonic.cpp']]], + ['kpanasonicbits_6285',['kPanasonicBits',['../IRremoteESP8266_8h.html#aa148f54492be1cf8a8b285a96861a0b7',1,'IRremoteESP8266.h']]], + ['kpanasonicendgap_6286',['kPanasonicEndGap',['../ir__Panasonic_8cpp.html#a3cb2f7a925bb8374a90e3156febabb39',1,'ir_Panasonic.cpp']]], + ['kpanasonicfreq_6287',['kPanasonicFreq',['../ir__Panasonic_8h.html#af344612d7f1c0d3f8271c312f310243e',1,'ir_Panasonic.h']]], + ['kpanasonichdrmark_6288',['kPanasonicHdrMark',['../ir__Panasonic_8cpp.html#a0d36b699fead0e229c583dae94f5e8f9',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrmarkticks_6289',['kPanasonicHdrMarkTicks',['../ir__Panasonic_8cpp.html#a0f2d448b87f30840ee38c27032cd10bd',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrspace_6290',['kPanasonicHdrSpace',['../ir__Panasonic_8cpp.html#ae56b3eb80f186a63b0f69c6b4e9efce8',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrspaceticks_6291',['kPanasonicHdrSpaceTicks',['../ir__Panasonic_8cpp.html#a5fa430a5612bd21eb859356cc9c62a3c',1,'ir_Panasonic.cpp']]], + ['kpanasonicknowngoodstate_6292',['kPanasonicKnownGoodState',['../ir__Panasonic_8h.html#a88a9678f8b00efa173b800b0b8441f87',1,'ir_Panasonic.h']]], + ['kpanasonicmanufacturer_6293',['kPanasonicManufacturer',['../IRremoteESP8266_8h.html#a1dd1a9799e5d20d39e82ff678bf07b47',1,'IRremoteESP8266.h']]], + ['kpanasonicmincommandlength_6294',['kPanasonicMinCommandLength',['../ir__Panasonic_8cpp.html#a5f191fff3eeb722cb03bee859a016132',1,'ir_Panasonic.cpp']]], + ['kpanasonicmincommandlengthticks_6295',['kPanasonicMinCommandLengthTicks',['../ir__Panasonic_8cpp.html#aba420f9aa4c3e6f261e422962362ce31',1,'ir_Panasonic.cpp']]], + ['kpanasonicmingap_6296',['kPanasonicMinGap',['../ir__Panasonic_8cpp.html#a61592f3569c0ee4825cca185fb43236d',1,'ir_Panasonic.cpp']]], + ['kpanasonicmingapticks_6297',['kPanasonicMinGapTicks',['../ir__Panasonic_8cpp.html#aa605847e951b22f1f31b82e6b04c4bab',1,'ir_Panasonic.cpp']]], + ['kpanasoniconespace_6298',['kPanasonicOneSpace',['../ir__Panasonic_8cpp.html#a9069f2ab94cacbd301d7615795c155b1',1,'ir_Panasonic.cpp']]], + ['kpanasoniconespaceticks_6299',['kPanasonicOneSpaceTicks',['../ir__Panasonic_8cpp.html#aa7a8cb818a098bb8ec395af7f5dbc6d7',1,'ir_Panasonic.cpp']]], + ['kpanasonictick_6300',['kPanasonicTick',['../ir__Panasonic_8cpp.html#ab2fddd81fb53066257aeaa60069527a8',1,'ir_Panasonic.cpp']]], + ['kpanasoniczerospace_6301',['kPanasonicZeroSpace',['../ir__Panasonic_8cpp.html#a43f64a8326fd2447653c81488673fd21',1,'ir_Panasonic.cpp']]], + ['kpanasoniczerospaceticks_6302',['kPanasonicZeroSpaceTicks',['../ir__Panasonic_8cpp.html#a58fef1468dbd4c3963be58754f38b125',1,'ir_Panasonic.cpp']]], + ['kperiodoffset_6303',['kPeriodOffset',['../IRsend_8h.html#a3a451a4e72e39a4bbf75c62af0ac62f5',1,'IRsend.h']]], + ['kpioneerbitmark_6304',['kPioneerBitMark',['../ir__Pioneer_8cpp.html#a6117fd080ad88efcf943aef53dadd1ad',1,'ir_Pioneer.cpp']]], + ['kpioneerbitmarkticks_6305',['kPioneerBitMarkTicks',['../ir__Pioneer_8cpp.html#a1cd60e52b21df3b10ac5f668cf61df16',1,'ir_Pioneer.cpp']]], + ['kpioneerbits_6306',['kPioneerBits',['../IRremoteESP8266_8h.html#a6a7ccd31e0a6f967a219b1a53b89653b',1,'IRremoteESP8266.h']]], + ['kpioneerhdrmark_6307',['kPioneerHdrMark',['../ir__Pioneer_8cpp.html#a03c4df7d9eba6ab56df0451a18e5adbd',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrmarkticks_6308',['kPioneerHdrMarkTicks',['../ir__Pioneer_8cpp.html#a9fc6ba8a158cae2d0d67af8e6cddd169',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrspace_6309',['kPioneerHdrSpace',['../ir__Pioneer_8cpp.html#a1308ff993ce7d030bdef919d65f35e62',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrspaceticks_6310',['kPioneerHdrSpaceTicks',['../ir__Pioneer_8cpp.html#a6c2ab5c384101f9184fd0960f21d13a5',1,'ir_Pioneer.cpp']]], + ['kpioneermincommandlength_6311',['kPioneerMinCommandLength',['../ir__Pioneer_8cpp.html#a22cb7d70bb0eb3b0ce6c7da3631d832f',1,'ir_Pioneer.cpp']]], + ['kpioneermincommandlengthticks_6312',['kPioneerMinCommandLengthTicks',['../ir__Pioneer_8cpp.html#a472ab59d00c439cc8832081492e742cc',1,'ir_Pioneer.cpp']]], + ['kpioneermingap_6313',['kPioneerMinGap',['../ir__Pioneer_8cpp.html#adc67bf557bd3474f18dfaa3125c1af41',1,'ir_Pioneer.cpp']]], + ['kpioneermingapticks_6314',['kPioneerMinGapTicks',['../ir__Pioneer_8cpp.html#abe0ebf83502225b39926ab745a8f8be2',1,'ir_Pioneer.cpp']]], + ['kpioneeronespace_6315',['kPioneerOneSpace',['../ir__Pioneer_8cpp.html#a5238b059346168128184bca93de16a54',1,'ir_Pioneer.cpp']]], + ['kpioneeronespaceticks_6316',['kPioneerOneSpaceTicks',['../ir__Pioneer_8cpp.html#af637842c88b54a022ac1ba3fef3fa041',1,'ir_Pioneer.cpp']]], + ['kpioneertick_6317',['kPioneerTick',['../ir__Pioneer_8cpp.html#a63de2364627344f86537ac82447c5cb4',1,'ir_Pioneer.cpp']]], + ['kpioneerzerospace_6318',['kPioneerZeroSpace',['../ir__Pioneer_8cpp.html#a3c6428f201dd3e32c171d6db44269d67',1,'ir_Pioneer.cpp']]], + ['kpioneerzerospaceticks_6319',['kPioneerZeroSpaceTicks',['../ir__Pioneer_8cpp.html#acdeea63204ce47f1556fa31bbed8a4a4',1,'ir_Pioneer.cpp']]], + ['kpowerbuttonstr_6320',['kPowerButtonStr',['../IRtext_8cpp.html#a69d36084b1410a06aa780edcda9428dd',1,'kPowerButtonStr(): IRtext.cpp'],['../IRtext_8h.html#adb54b8d070a4ba7f08b7d2d0f1c03d1c',1,'kPowerButtonStr(): IRtext.cpp']]], + ['kpowerfulstr_6321',['kPowerfulStr',['../IRtext_8cpp.html#a5dfc12bfa12ddf7da3ab6c216258284a',1,'kPowerfulStr(): IRtext.cpp'],['../IRtext_8h.html#a7980630cd028febca8245730dffa684b',1,'kPowerfulStr(): IRtext.cpp']]], + ['kpowerstr_6322',['kPowerStr',['../IRtext_8cpp.html#a5b4b43efe1f1c27d6aee90ebb3500792',1,'kPowerStr(): IRtext.cpp'],['../IRtext_8h.html#a47a76dc8d87d9694a36c6417d7e19dda',1,'kPowerStr(): IRtext.cpp']]], + ['kpowertogglestr_6323',['kPowerToggleStr',['../IRtext_8cpp.html#a2f7e242dc28cf61fb718bb5c1b681642',1,'kPowerToggleStr(): IRtext.cpp'],['../IRtext_8h.html#afd802a94c6146efb7812ef89f3bf0cc5',1,'kPowerToggleStr(): IRtext.cpp']]], + ['kpreviouspowerstr_6324',['kPreviousPowerStr',['../IRtext_8cpp.html#a2a5cd83ac519798debd7065eb03d5d72',1,'kPreviousPowerStr(): IRtext.cpp'],['../IRtext_8h.html#a9833364e538f50be227ff6c0b01f8f7c',1,'kPreviousPowerStr(): IRtext.cpp']]], + ['kprontodataoffset_6325',['kProntoDataOffset',['../ir__Pronto_8cpp.html#ac073b9ac759e09091b3d80af747656a1',1,'ir_Pronto.cpp']]], + ['kprontofreqfactor_6326',['kProntoFreqFactor',['../ir__Pronto_8cpp.html#aa63eef9baeb563c8494d85d13b956db8',1,'ir_Pronto.cpp']]], + ['kprontofreqoffset_6327',['kProntoFreqOffset',['../ir__Pronto_8cpp.html#a2fae4105559199e292121bcb847d9d52',1,'ir_Pronto.cpp']]], + ['kprontominlength_6328',['kProntoMinLength',['../IRremoteESP8266_8h.html#a25dd42234e21d41b0b4bc97e1fe921c4',1,'IRremoteESP8266.h']]], + ['kprontoseq1lenoffset_6329',['kProntoSeq1LenOffset',['../ir__Pronto_8cpp.html#a1df51305dddf233fc3963856e288366f',1,'ir_Pronto.cpp']]], + ['kprontoseq2lenoffset_6330',['kProntoSeq2LenOffset',['../ir__Pronto_8cpp.html#a708744a9f82547e5abc17d7ed866a648',1,'ir_Pronto.cpp']]], + ['kprontotypeoffset_6331',['kProntoTypeOffset',['../ir__Pronto_8cpp.html#a603ff34f28f270a98bf0bebdaf19bfbc',1,'ir_Pronto.cpp']]], + ['kprotocolstr_6332',['kProtocolStr',['../IRtext_8cpp.html#afb9e901ded9e88a48218282a7446ff63',1,'kProtocolStr(): IRtext.cpp'],['../IRtext_8h.html#ac50f97a0d33041fe4bba6e02c500c8ef',1,'kProtocolStr(): IRtext.cpp']]], + ['kpurifystr_6333',['kPurifyStr',['../IRtext_8cpp.html#a85c2b59f6cba1878648d3d8fe9d7f9a4',1,'kPurifyStr(): IRtext.cpp'],['../IRtext_8h.html#aae574dbb4b9f70db0e64386d61c21beb',1,'kPurifyStr(): IRtext.cpp']]], + ['kquietstr_6334',['kQuietStr',['../IRtext_8cpp.html#a6f85e3119eb884455f474ff909be6b53',1,'kQuietStr(): IRtext.cpp'],['../IRtext_8h.html#a7086660370d73d6f499972cf802db8f7',1,'kQuietStr(): IRtext.cpp']]], + ['krawbuf_6335',['kRawBuf',['../IRrecv_8h.html#aadfa37def10a1adeaf2cf4c09d7504e3',1,'IRrecv.h']]], + ['krawtick_6336',['kRawTick',['../IRrecv_8h.html#a373dde69c312b0122665e581eea1297b',1,'IRrecv.h']]], + ['krc5bits_6337',['kRC5Bits',['../IRremoteESP8266_8h.html#ad0935984e6518e340562665742199483',1,'IRremoteESP8266.h']]], + ['krc5mincommandlength_6338',['kRc5MinCommandLength',['../ir__RC5__RC6_8cpp.html#a32b5997148b53fd2984388f6d0384c35',1,'ir_RC5_RC6.cpp']]], + ['krc5mingap_6339',['kRc5MinGap',['../ir__RC5__RC6_8cpp.html#a26580409f593179d838c465647e35c41',1,'ir_RC5_RC6.cpp']]], + ['krc5rawbits_6340',['kRC5RawBits',['../IRremoteESP8266_8h.html#a955183d3358fcafea853014ddd890574',1,'IRremoteESP8266.h']]], + ['krc5samplesmin_6341',['kRc5SamplesMin',['../ir__RC5__RC6_8cpp.html#aa206173838597c760b4a01c36bbc771a',1,'ir_RC5_RC6.cpp']]], + ['krc5t1_6342',['kRc5T1',['../ir__RC5__RC6_8cpp.html#aa42cae15fa77a196eb8f198de09e19eb',1,'ir_RC5_RC6.cpp']]], + ['krc5togglemask_6343',['kRc5ToggleMask',['../ir__RC5__RC6_8cpp.html#ae3485c1c157d6d84a0385cb1bfb8833a',1,'ir_RC5_RC6.cpp']]], + ['krc5xbits_6344',['kRC5XBits',['../IRremoteESP8266_8h.html#abec3ebb217126560e824fa8b66d495bc',1,'IRremoteESP8266.h']]], + ['krc6_5f36bits_6345',['kRC6_36Bits',['../IRremoteESP8266_8h.html#a30a2cb328aa0d47f53aba56055ac74e0',1,'IRremoteESP8266.h']]], + ['krc6_5f36togglemask_6346',['kRc6_36ToggleMask',['../ir__RC5__RC6_8cpp.html#a31ae862ce2a43edd99bda647262b18fa',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrmark_6347',['kRc6HdrMark',['../ir__RC5__RC6_8cpp.html#ae05bbb9f690cc92feb0a9c14b3b8c477',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrmarkticks_6348',['kRc6HdrMarkTicks',['../ir__RC5__RC6_8cpp.html#aff2a5bc05ddf61d289c44a4fd093009c',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrspace_6349',['kRc6HdrSpace',['../ir__RC5__RC6_8cpp.html#a0196311c9b116cf48c8f901fb6c93ac3',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrspaceticks_6350',['kRc6HdrSpaceTicks',['../ir__RC5__RC6_8cpp.html#a35a9cc59fe5251a34c88e34b6a507fd3',1,'ir_RC5_RC6.cpp']]], + ['krc6mode0bits_6351',['kRC6Mode0Bits',['../IRremoteESP8266_8h.html#a84a6d3e15e98f7a4917d252d5665534a',1,'IRremoteESP8266.h']]], + ['krc6rptlength_6352',['kRc6RptLength',['../ir__RC5__RC6_8cpp.html#a4989f36b790a99545e708c8681b6b961',1,'ir_RC5_RC6.cpp']]], + ['krc6rptlengthticks_6353',['kRc6RptLengthTicks',['../ir__RC5__RC6_8cpp.html#acf2dc0074bfe7671deb8985eba4396e3',1,'ir_RC5_RC6.cpp']]], + ['krc6tick_6354',['kRc6Tick',['../ir__RC5__RC6_8cpp.html#aad98dc2541039634817609d4e297322f',1,'ir_RC5_RC6.cpp']]], + ['krc6togglemask_6355',['kRc6ToggleMask',['../ir__RC5__RC6_8cpp.html#a4df09270c1e9cda504026189e30829ff',1,'ir_RC5_RC6.cpp']]], + ['krcmmbitmark_6356',['kRcmmBitMark',['../ir__RCMM_8cpp.html#ad768f62bbd7e4df567c3e53ea0a8ed06',1,'ir_RCMM.cpp']]], + ['krcmmbitmarkticks_6357',['kRcmmBitMarkTicks',['../ir__RCMM_8cpp.html#a48aeb7992d30f8c7cfa04dbd14ea0996',1,'ir_RCMM.cpp']]], + ['krcmmbits_6358',['kRCMMBits',['../IRremoteESP8266_8h.html#a2bfaf393c2d77a594f2a0a5a763e84f5',1,'IRremoteESP8266.h']]], + ['krcmmbitspace0_6359',['kRcmmBitSpace0',['../ir__RCMM_8cpp.html#a34a7b22107461be18500f6d1ddf979e3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace0ticks_6360',['kRcmmBitSpace0Ticks',['../ir__RCMM_8cpp.html#a0864042e8c098169d1d221fbd798cda3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace1_6361',['kRcmmBitSpace1',['../ir__RCMM_8cpp.html#a812b9895f0eccaaf78752dc7030022aa',1,'ir_RCMM.cpp']]], + ['krcmmbitspace1ticks_6362',['kRcmmBitSpace1Ticks',['../ir__RCMM_8cpp.html#a89f945e0a91feccd505f0b8310a9ebb9',1,'ir_RCMM.cpp']]], + ['krcmmbitspace2_6363',['kRcmmBitSpace2',['../ir__RCMM_8cpp.html#aff0db6a8f28d3a307cd7bbb6dc90e3e3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace2ticks_6364',['kRcmmBitSpace2Ticks',['../ir__RCMM_8cpp.html#a592dda1dd9239c9a015163b80cddf859',1,'ir_RCMM.cpp']]], + ['krcmmbitspace3_6365',['kRcmmBitSpace3',['../ir__RCMM_8cpp.html#a5e6351cbcb4c576871584dbf61d87d33',1,'ir_RCMM.cpp']]], + ['krcmmbitspace3ticks_6366',['kRcmmBitSpace3Ticks',['../ir__RCMM_8cpp.html#aa3f7d7e37ffa6bf9649eef7720770767',1,'ir_RCMM.cpp']]], + ['krcmmexcess_6367',['kRcmmExcess',['../ir__RCMM_8cpp.html#a3845e23031e92fd008157b0f95827432',1,'ir_RCMM.cpp']]], + ['krcmmhdrmark_6368',['kRcmmHdrMark',['../ir__RCMM_8cpp.html#a7fc5d5c1dc89ef0615fcaebaacc504df',1,'ir_RCMM.cpp']]], + ['krcmmhdrmarkticks_6369',['kRcmmHdrMarkTicks',['../ir__RCMM_8cpp.html#a00e93c94548ac081083ed2cabd614330',1,'ir_RCMM.cpp']]], + ['krcmmhdrspace_6370',['kRcmmHdrSpace',['../ir__RCMM_8cpp.html#af4dc2548c8069caf889612b3b28895ea',1,'ir_RCMM.cpp']]], + ['krcmmhdrspaceticks_6371',['kRcmmHdrSpaceTicks',['../ir__RCMM_8cpp.html#a87cd8bb5322fb38aecd20362a7df5016',1,'ir_RCMM.cpp']]], + ['krcmmmingap_6372',['kRcmmMinGap',['../ir__RCMM_8cpp.html#a94f9533bf18c0a2c2b6511ffa95ff5dc',1,'ir_RCMM.cpp']]], + ['krcmmmingapticks_6373',['kRcmmMinGapTicks',['../ir__RCMM_8cpp.html#aacb274f2da878aed511f6ab400cd51e9',1,'ir_RCMM.cpp']]], + ['krcmmrptlength_6374',['kRcmmRptLength',['../ir__RCMM_8cpp.html#a1dccf2b944d4eeb8b7dd2a1f66548a68',1,'ir_RCMM.cpp']]], + ['krcmmrptlengthticks_6375',['kRcmmRptLengthTicks',['../ir__RCMM_8cpp.html#a4cd637fa0a6071f9ea0b52c346ffe7f0',1,'ir_RCMM.cpp']]], + ['krcmmtick_6376',['kRcmmTick',['../ir__RCMM_8cpp.html#a9e1a3a26185d58ff675eec7485bc671f',1,'ir_RCMM.cpp']]], + ['krcmmtolerance_6377',['kRcmmTolerance',['../ir__RCMM_8cpp.html#a4b95480078186b3498ca6426e5bbc428',1,'ir_RCMM.cpp']]], + ['krcz01channelmask_6378',['kRcz01ChannelMask',['../ir__Doshisha_8cpp.html#a085b3d47e4cf8d8b4ba999ae58ec3533',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel1_6379',['kRcz01CommandLevel1',['../ir__Doshisha_8cpp.html#a436b801a282374de0f28e27828e1c4bf',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel2_6380',['kRcz01CommandLevel2',['../ir__Doshisha_8cpp.html#a311ef41fff985236216238565219bfe7',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel3_6381',['kRcz01CommandLevel3',['../ir__Doshisha_8cpp.html#a879bd44f482c87fbaf9fecaad8ed4c6d',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel4_6382',['kRcz01CommandLevel4',['../ir__Doshisha_8cpp.html#a52bad85f1a3918e3031297a6c6074b45',1,'ir_Doshisha.cpp']]], + ['krcz01commandleveldown_6383',['kRcz01CommandLevelDown',['../ir__Doshisha_8cpp.html#a1678269506503f1abf871ed0af6dcc2b',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevelup_6384',['kRcz01CommandLevelUp',['../ir__Doshisha_8cpp.html#a4eba011d2b110a5348783534e957660e',1,'ir_Doshisha.cpp']]], + ['krcz01commandmask_6385',['kRcz01CommandMask',['../ir__Doshisha_8cpp.html#a148e2f676f895f4e3b77b39780e2ca94',1,'ir_Doshisha.cpp']]], + ['krcz01commandnightlight_6386',['kRcz01CommandNightLight',['../ir__Doshisha_8cpp.html#a47e9d5bf353cf8aef8199fb74693aa0f',1,'ir_Doshisha.cpp']]], + ['krcz01commandoff_6387',['kRcz01CommandOff',['../ir__Doshisha_8cpp.html#a97fd32975ab9fafa85e0704964780773',1,'ir_Doshisha.cpp']]], + ['krcz01commandon_6388',['kRcz01CommandOn',['../ir__Doshisha_8cpp.html#a7377eac8b1d938903fd43d7505dd8a49',1,'ir_Doshisha.cpp']]], + ['krcz01commandswitchchannel_6389',['kRcz01CommandSwitchChannel',['../ir__Doshisha_8cpp.html#afcd3fe98c34ef9572c1a68bd143e128b',1,'ir_Doshisha.cpp']]], + ['krcz01commandtimmer30_6390',['kRcz01CommandTimmer30',['../ir__Doshisha_8cpp.html#a3deebab67d01756f7776f0d11cbdef6e',1,'ir_Doshisha.cpp']]], + ['krcz01commandtimmer60_6391',['kRcz01CommandTimmer60',['../ir__Doshisha_8cpp.html#abac6b50227512508aeb5b6042a8380fd',1,'ir_Doshisha.cpp']]], + ['krcz01signature_6392',['kRcz01Signature',['../ir__Doshisha_8cpp.html#a35c6dff74ae1702933e33f02f743f616',1,'ir_Doshisha.cpp']]], + ['krcz01signaturemask_6393',['kRcz01SignatureMask',['../ir__Doshisha_8cpp.html#a1f3b9cdfba7cc7515611d7145b7318a5',1,'ir_Doshisha.cpp']]], + ['krepeat_6394',['kRepeat',['../IRrecv_8h.html#ae8b11750ba7f2e2d56343f770720ed89',1,'IRrecv.h']]], + ['krepeatstr_6395',['kRepeatStr',['../IRtext_8cpp.html#ad55ef2e023915f39c7ce77e7eeb1ad76',1,'kRepeatStr(): IRtext.cpp'],['../IRtext_8h.html#a74a53cc1564f75b36269eb1ca8c6235b',1,'kRepeatStr(): IRtext.cpp']]], + ['krightmaxstr_6396',['kRightMaxStr',['../IRtext_8cpp.html#af3e63659779f5fdb4aded4861521e564',1,'kRightMaxStr(): IRtext.cpp'],['../IRtext_8h.html#ac7a90008560fd1e7b4ed240f354d8fae',1,'kRightMaxStr(): IRtext.cpp']]], + ['krightstr_6397',['kRightStr',['../IRtext_8cpp.html#aacc9b0b21efb6053b75ed117d4ab9105',1,'kRightStr(): IRtext.cpp'],['../IRtext_8h.html#a953f9c48fcf87e81bf6f383e8fe8b1dd',1,'kRightStr(): IRtext.cpp']]], + ['kroomstr_6398',['kRoomStr',['../IRtext_8cpp.html#ab3f02ff54af9a94fd57d098838a4a642',1,'kRoomStr(): IRtext.cpp'],['../IRtext_8h.html#a5358a85538e4643c1cc109a7a0b90079',1,'kRoomStr(): IRtext.cpp']]], + ['ksamsung36bits_6399',['kSamsung36Bits',['../IRremoteESP8266_8h.html#a5e1e6f30a41f0d94652429a9e1034179',1,'IRremoteESP8266.h']]], + ['ksamsungacauto_6400',['kSamsungAcAuto',['../ir__Samsung_8h.html#a1b05ff970f45c57b13fc13d11e95396b',1,'ir_Samsung.h']]], + ['ksamsungacautotemp_6401',['kSamsungAcAutoTemp',['../ir__Samsung_8h.html#a87bb469afc0e2b6bad44634f3ba5e0ef',1,'ir_Samsung.h']]], + ['ksamsungacbeepoffset_6402',['kSamsungAcBeepOffset',['../ir__Samsung_8h.html#a12ae1e43d05d39c39d335c97223e003e',1,'ir_Samsung.h']]], + ['ksamsungacbitmark_6403',['kSamsungAcBitMark',['../ir__Samsung_8cpp.html#a37e6f36939f1a12ffe52907bbb64a4cf',1,'ir_Samsung.cpp']]], + ['ksamsungacbits_6404',['kSamsungAcBits',['../IRremoteESP8266_8h.html#adebe85ab48eb876ec15daacca246797c',1,'IRremoteESP8266.h']]], + ['ksamsungacbreezeoffset_6405',['kSamsungAcBreezeOffset',['../ir__Samsung_8h.html#a31d5463b3819fe41ce078b085c395a40',1,'ir_Samsung.h']]], + ['ksamsungacbreezeon_6406',['kSamsungAcBreezeOn',['../ir__Samsung_8h.html#a06299ba6942969f7b9472e752b50d4d7',1,'ir_Samsung.h']]], + ['ksamsungacbreezesize_6407',['kSamsungAcBreezeSize',['../ir__Samsung_8h.html#a1f6ec492aa58cb704147213e3b6f9f24',1,'ir_Samsung.h']]], + ['ksamsungacclean10offset_6408',['kSamsungAcClean10Offset',['../ir__Samsung_8h.html#a0982038a8c3e27972e69b83c350a0ff3',1,'ir_Samsung.h']]], + ['ksamsungacclean11offset_6409',['kSamsungAcClean11Offset',['../ir__Samsung_8h.html#a87666330f9a410ced00bf15c5f22daf2',1,'ir_Samsung.h']]], + ['ksamsungaccool_6410',['kSamsungAcCool',['../ir__Samsung_8h.html#a24d40e01f046f887b7d41dad67ad7555',1,'ir_Samsung.h']]], + ['ksamsungacdefaultrepeat_6411',['kSamsungAcDefaultRepeat',['../IRremoteESP8266_8h.html#a973f4e0189fc10805f67b67f708be1e4',1,'IRremoteESP8266.h']]], + ['ksamsungacdisplayoffset_6412',['kSamsungAcDisplayOffset',['../ir__Samsung_8h.html#af47c9229cbe569b93ad5f4986c4484ab',1,'ir_Samsung.h']]], + ['ksamsungacdry_6413',['kSamsungAcDry',['../ir__Samsung_8h.html#a6423976c7a41f526e7a878cecb257bbd',1,'ir_Samsung.h']]], + ['ksamsungacextendedbits_6414',['kSamsungAcExtendedBits',['../IRremoteESP8266_8h.html#a296e700965e70a622fe99675ff0438af',1,'IRremoteESP8266.h']]], + ['ksamsungacextendedstatelength_6415',['kSamsungAcExtendedStateLength',['../IRremoteESP8266_8h.html#a28039071f1130e9bc86efddd8265cbf9',1,'IRremoteESP8266.h']]], + ['ksamsungacfan_6416',['kSamsungAcFan',['../ir__Samsung_8h.html#a61d825254b26894a2f097ad92a7dbff2',1,'ir_Samsung.h']]], + ['ksamsungacfanauto_6417',['kSamsungAcFanAuto',['../ir__Samsung_8h.html#a37b29911f4d2b71dcdbd18a5d6dc301a',1,'ir_Samsung.h']]], + ['ksamsungacfanauto2_6418',['kSamsungAcFanAuto2',['../ir__Samsung_8h.html#aafa4319fb523b14d58371f757497e82a',1,'ir_Samsung.h']]], + ['ksamsungacfanhigh_6419',['kSamsungAcFanHigh',['../ir__Samsung_8h.html#a52cccad28fad5b9886ef408af02f56f9',1,'ir_Samsung.h']]], + ['ksamsungacfanlow_6420',['kSamsungAcFanLow',['../ir__Samsung_8h.html#a6f16b5b3f2dea3461f5d44379e8b8634',1,'ir_Samsung.h']]], + ['ksamsungacfanmed_6421',['kSamsungAcFanMed',['../ir__Samsung_8h.html#a798c3544dbd6bb6c8622cf45f88abc14',1,'ir_Samsung.h']]], + ['ksamsungacfanoffest_6422',['kSamsungAcFanOffest',['../ir__Samsung_8h.html#a1dd4a351c1a036972f741fbdafb05a7e',1,'ir_Samsung.h']]], + ['ksamsungacfansize_6423',['kSamsungAcFanSize',['../ir__Samsung_8h.html#a5b055e9951e23ba44bf1fdeed805b332',1,'ir_Samsung.h']]], + ['ksamsungacfanturbo_6424',['kSamsungAcFanTurbo',['../ir__Samsung_8h.html#af6c1432748eaa19df35531b87d197095',1,'ir_Samsung.h']]], + ['ksamsungachdrmark_6425',['kSamsungAcHdrMark',['../ir__Samsung_8cpp.html#ab7385ca5b7b417753b253a0f7cb3721b',1,'ir_Samsung.cpp']]], + ['ksamsungachdrspace_6426',['kSamsungAcHdrSpace',['../ir__Samsung_8cpp.html#a1b1f903fff13b10fb2431be9373e27cb',1,'ir_Samsung.cpp']]], + ['ksamsungacheat_6427',['kSamsungAcHeat',['../ir__Samsung_8h.html#a44ce6be7046ec4b4fe9caba7b71b8f0d',1,'ir_Samsung.h']]], + ['ksamsungacionoffset_6428',['kSamsungAcIonOffset',['../ir__Samsung_8h.html#aa7bbd222553072c092158421d1b9977f',1,'ir_Samsung.h']]], + ['ksamsungacmaxtemp_6429',['kSamsungAcMaxTemp',['../ir__Samsung_8h.html#a0a994796db81a3d56dd2c27cad448a71',1,'ir_Samsung.h']]], + ['ksamsungacmintemp_6430',['kSamsungAcMinTemp',['../ir__Samsung_8h.html#ad5f46ccb96335519f5633c33de0d8018',1,'ir_Samsung.h']]], + ['ksamsungacmodeoffset_6431',['kSamsungAcModeOffset',['../ir__Samsung_8h.html#a64b2aceb5c0d4dbea2d4697efe65aef2',1,'ir_Samsung.h']]], + ['ksamsungaconespace_6432',['kSamsungAcOneSpace',['../ir__Samsung_8cpp.html#ab106d9b7efb165eed83ae2ccef9a49b4',1,'ir_Samsung.cpp']]], + ['ksamsungacpower1offset_6433',['kSamsungAcPower1Offset',['../ir__Samsung_8h.html#aa6a4ff05acfabf24e4dfc126e583c46c',1,'ir_Samsung.h']]], + ['ksamsungacpower6offset_6434',['kSamsungAcPower6Offset',['../ir__Samsung_8h.html#a90591c7d6069d81493f894328d595187',1,'ir_Samsung.h']]], + ['ksamsungacpower6size_6435',['kSamsungAcPower6Size',['../ir__Samsung_8h.html#ace0a7a2cfedbb77d05de53abc5906992',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10offset_6436',['kSamsungAcPowerful10Offset',['../ir__Samsung_8h.html#a7f92d734af799e058723e898d3ebdd30',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10on_6437',['kSamsungAcPowerful10On',['../ir__Samsung_8h.html#aa05bb4788febba1f56b2b3929ac273a3',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10size_6438',['kSamsungAcPowerful10Size',['../ir__Samsung_8h.html#a19ede17e420f68ea552497461e69006a',1,'ir_Samsung.h']]], + ['ksamsungacpowerfulmask8_6439',['kSamsungAcPowerfulMask8',['../ir__Samsung_8h.html#a39e23325e35688a3641c467b720381ce',1,'ir_Samsung.h']]], + ['ksamsungacpowersection_6440',['kSamsungAcPowerSection',['../ir__Samsung_8h.html#a9264b5d640d9052c153562fd38415676',1,'ir_Samsung.h']]], + ['ksamsungacquiet1offset_6441',['kSamsungAcQuiet1Offset',['../ir__Samsung_8h.html#ab029485b433f7eef6413d8194790c566',1,'ir_Samsung.h']]], + ['ksamsungacquiet5offset_6442',['kSamsungAcQuiet5Offset',['../ir__Samsung_8h.html#ae10abd66772da9bab4ba266f29e7ec75',1,'ir_Samsung.h']]], + ['ksamsungacsectiongap_6443',['kSamsungAcSectionGap',['../ir__Samsung_8cpp.html#a9752fc615c215a93c1ee65edca3a359e',1,'ir_Samsung.cpp']]], + ['ksamsungacsectionlength_6444',['kSamsungAcSectionLength',['../ir__Samsung_8h.html#ad3faedf7b111f1b91d671666e38ce6f3',1,'ir_Samsung.h']]], + ['ksamsungacsectionmark_6445',['kSamsungAcSectionMark',['../ir__Samsung_8cpp.html#a4304073cddaa2da9613dedce499fee56',1,'ir_Samsung.cpp']]], + ['ksamsungacsections_6446',['kSamsungAcSections',['../ir__Samsung_8cpp.html#a86185d98d6e891a17688d9d2a0fa7114',1,'ir_Samsung.cpp']]], + ['ksamsungacsectionspace_6447',['kSamsungAcSectionSpace',['../ir__Samsung_8cpp.html#a4837f502ef9b7c972ec409cf4fc3c605',1,'ir_Samsung.cpp']]], + ['ksamsungacstatelength_6448',['kSamsungAcStateLength',['../IRremoteESP8266_8h.html#a2d07d8c8917fee072a261d00e67e0d36',1,'IRremoteESP8266.h']]], + ['ksamsungacswingmove_6449',['kSamsungAcSwingMove',['../ir__Samsung_8h.html#ab2d2b422e3972f77aef23f77c7cfbbac',1,'ir_Samsung.h']]], + ['ksamsungacswingoffset_6450',['kSamsungAcSwingOffset',['../ir__Samsung_8h.html#ab71772d77c56cf4d01f3ce4ab751a55c',1,'ir_Samsung.h']]], + ['ksamsungacswingsize_6451',['kSamsungAcSwingSize',['../ir__Samsung_8h.html#a1b50618058108826f9103f46bf7677ee',1,'ir_Samsung.h']]], + ['ksamsungacswingstop_6452',['kSamsungAcSwingStop',['../ir__Samsung_8h.html#a37c1720d66c4ba02e368946e53036367',1,'ir_Samsung.h']]], + ['ksamsungaczerospace_6453',['kSamsungAcZeroSpace',['../ir__Samsung_8cpp.html#a7492a25e730f93f22c099ab687621b18',1,'ir_Samsung.cpp']]], + ['ksamsungbitmark_6454',['kSamsungBitMark',['../ir__Samsung_8cpp.html#a03f9ae317a7a701437c8015dfde4401f',1,'ir_Samsung.cpp']]], + ['ksamsungbitmarkticks_6455',['kSamsungBitMarkTicks',['../ir__Samsung_8cpp.html#afe1663f83396f7e5cf9bfc32f321e539',1,'ir_Samsung.cpp']]], + ['ksamsungbits_6456',['kSamsungBits',['../IRremoteESP8266_8h.html#a7c1c015cce09284799cbf5a2f21ee170',1,'IRremoteESP8266.h']]], + ['ksamsunghdrmark_6457',['kSamsungHdrMark',['../ir__Samsung_8cpp.html#a3d0598585af609af4c8d5004789d2df7',1,'ir_Samsung.cpp']]], + ['ksamsunghdrmarkticks_6458',['kSamsungHdrMarkTicks',['../ir__Samsung_8cpp.html#a0c81f486877d24bfd40215b089c52f2a',1,'ir_Samsung.cpp']]], + ['ksamsunghdrspace_6459',['kSamsungHdrSpace',['../ir__Samsung_8cpp.html#a2f55c53bfc72de06ff202c8ec401163d',1,'ir_Samsung.cpp']]], + ['ksamsunghdrspaceticks_6460',['kSamsungHdrSpaceTicks',['../ir__Samsung_8cpp.html#a1ae96cedfa4ed26869d295cfbb8056dd',1,'ir_Samsung.cpp']]], + ['ksamsungmingap_6461',['kSamsungMinGap',['../ir__Samsung_8cpp.html#ab13edb242547803b386aa8539a4b9470',1,'ir_Samsung.cpp']]], + ['ksamsungmingapticks_6462',['kSamsungMinGapTicks',['../ir__Samsung_8cpp.html#a55d79dcfcd43f05ebe456a9a2fce3ff0',1,'ir_Samsung.cpp']]], + ['ksamsungminmessagelength_6463',['kSamsungMinMessageLength',['../ir__Samsung_8cpp.html#ae2ec2e45f91f872e85c250c7aac0efc1',1,'ir_Samsung.cpp']]], + ['ksamsungminmessagelengthticks_6464',['kSamsungMinMessageLengthTicks',['../ir__Samsung_8cpp.html#a6d436a1b71158ff9b5d7ae21344cd7d2',1,'ir_Samsung.cpp']]], + ['ksamsungonespace_6465',['kSamsungOneSpace',['../ir__Samsung_8cpp.html#ab486b048d13f44623ee291d4221c2a1b',1,'ir_Samsung.cpp']]], + ['ksamsungonespaceticks_6466',['kSamsungOneSpaceTicks',['../ir__Samsung_8cpp.html#a484a1e3ce3dcbbef15be559bfb5822d0',1,'ir_Samsung.cpp']]], + ['ksamsungrptspace_6467',['kSamsungRptSpace',['../ir__Samsung_8cpp.html#a1cc2f3bcd7f2ca36f0a726828c14aa74',1,'ir_Samsung.cpp']]], + ['ksamsungrptspaceticks_6468',['kSamsungRptSpaceTicks',['../ir__Samsung_8cpp.html#a6864f78ad1428358acbc8b46796e50cc',1,'ir_Samsung.cpp']]], + ['ksamsungtick_6469',['kSamsungTick',['../ir__Samsung_8cpp.html#accd7d51c2714bd383170831372f57bc5',1,'ir_Samsung.cpp']]], + ['ksamsungzerospace_6470',['kSamsungZeroSpace',['../ir__Samsung_8cpp.html#ae2c828a3d099d6195208a3794022587e',1,'ir_Samsung.cpp']]], + ['ksamsungzerospaceticks_6471',['kSamsungZeroSpaceTicks',['../ir__Samsung_8cpp.html#aea63a73a5b0af2c173bc473ee2447a93',1,'ir_Samsung.cpp']]], + ['ksanyolc7461addressbits_6472',['kSanyoLC7461AddressBits',['../IRremoteESP8266_8h.html#a7e15e988acbea0fb4dfaee6f5bfa12d0',1,'IRremoteESP8266.h']]], + ['ksanyolc7461addressmask_6473',['kSanyoLc7461AddressMask',['../ir__Sanyo_8cpp.html#a785ccc066e433f11791f8a30243944d3',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461bitmark_6474',['kSanyoLc7461BitMark',['../ir__Sanyo_8cpp.html#a1360ba5ac3f30715c00a6a65155cfec8',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461bits_6475',['kSanyoLC7461Bits',['../IRremoteESP8266_8h.html#ad067db05b273337e0df38d529094c9e8',1,'IRremoteESP8266.h']]], + ['ksanyolc7461commandbits_6476',['kSanyoLC7461CommandBits',['../IRremoteESP8266_8h.html#a5cd69a192be51634ce72a40398a6c0d7',1,'IRremoteESP8266.h']]], + ['ksanyolc7461commandmask_6477',['kSanyoLc7461CommandMask',['../ir__Sanyo_8cpp.html#abdd072e210a7616d564a9d4a7f798ad3',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461hdrmark_6478',['kSanyoLc7461HdrMark',['../ir__Sanyo_8cpp.html#a0b2e520442dd96f8cd77969230713277',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461hdrspace_6479',['kSanyoLc7461HdrSpace',['../ir__Sanyo_8cpp.html#aa9ca2469e22f66d6e5e3f4ef952484ba',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461mincommandlength_6480',['kSanyoLc7461MinCommandLength',['../ir__Sanyo_8cpp.html#a237fac9264bba0014124a815133868b2',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461mingap_6481',['kSanyoLc7461MinGap',['../ir__Sanyo_8cpp.html#aff7f31500dbe9939e223bed6b6c631a8',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461onespace_6482',['kSanyoLc7461OneSpace',['../ir__Sanyo_8cpp.html#a52716e37d6943b01e9df37956f1a83de',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461zerospace_6483',['kSanyoLc7461ZeroSpace',['../ir__Sanyo_8cpp.html#a4e386992c8fca642c259e86e34729a4d',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bbits_6484',['kSanyoSA8650BBits',['../IRremoteESP8266_8h.html#a2c572c8bfa811b7dc3a8a537cc642b85',1,'IRremoteESP8266.h']]], + ['ksanyosa8650bdoublespaceusecs_6485',['kSanyoSa8650bDoubleSpaceUsecs',['../ir__Sanyo_8cpp.html#a828caf6fd05e81cedee67c558b88a0b6',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bhdrmark_6486',['kSanyoSa8650bHdrMark',['../ir__Sanyo_8cpp.html#a9d0472d183a96b8ca71a2b704a06cac8',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bhdrspace_6487',['kSanyoSa8650bHdrSpace',['../ir__Sanyo_8cpp.html#ab432df3bd299b72b4449672d611798b7',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bonemark_6488',['kSanyoSa8650bOneMark',['../ir__Sanyo_8cpp.html#a8854c7bd32c1ec53e8e1869cd9dd8cdd',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650brptlength_6489',['kSanyoSa8650bRptLength',['../ir__Sanyo_8cpp.html#a327ee6de7027aacfa9aa6ee8bdc74e3e',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bzeromark_6490',['kSanyoSa8650bZeroMark',['../ir__Sanyo_8cpp.html#a516a45a7934f23274fa302d7e711b43c',1,'ir_Sanyo.cpp']]], + ['ksavestr_6491',['kSaveStr',['../IRtext_8cpp.html#a24f9462727ee596a3ae16393c33e3ebc',1,'kSaveStr(): IRtext.cpp'],['../IRtext_8h.html#acb40b78a5269c43cc3e4f44d3da01069',1,'kSaveStr(): IRtext.cpp']]], + ['ksecondsstr_6492',['kSecondsStr',['../IRtext_8cpp.html#a282cb9785839a9da66a9333d788c0fb1',1,'kSecondsStr(): IRtext.cpp'],['../IRtext_8h.html#ad736b59d3fe45b3c06bd301af4d7b455',1,'kSecondsStr(): IRtext.cpp']]], + ['ksecondstr_6493',['kSecondStr',['../IRtext_8cpp.html#a5ec55e16709cbd2c4b1ff8c72c01c1f5',1,'kSecondStr(): IRtext.cpp'],['../IRtext_8h.html#ad3489e1c008bc517b8bf0271c40252d1',1,'kSecondStr(): IRtext.cpp']]], + ['ksensorstr_6494',['kSensorStr',['../IRtext_8cpp.html#aa7e6eab2fbc832f98d6560f62453c934',1,'kSensorStr(): IRtext.cpp'],['../IRtext_8h.html#a56ee9a96dd0a7ee0a5f95c286f6ea7e8',1,'kSensorStr(): IRtext.cpp']]], + ['ksensortempstr_6495',['kSensorTempStr',['../IRtext_8cpp.html#a756daa989457676d2af255428a01e1d5',1,'kSensorTempStr(): IRtext.cpp'],['../IRtext_8h.html#a03e76a09bade0c229fea1ce31fe8c9a1',1,'kSensorTempStr(): IRtext.cpp']]], + ['ksetstr_6496',['kSetStr',['../IRtext_8cpp.html#a27b5e437df44d4d41db9b296a1f236a1',1,'kSetStr(): IRtext.cpp'],['../IRtext_8h.html#a31d3426b8a8d1a35c47c88ef00023fce',1,'kSetStr(): IRtext.cpp']]], + ['ksharpacauto_6497',['kSharpAcAuto',['../ir__Sharp_8h.html#ad4e228b234598a84e11a76e7f2d27199',1,'ir_Sharp.h']]], + ['ksharpacbitcleanoffset_6498',['kSharpAcBitCleanOffset',['../ir__Sharp_8h.html#a3460827972f31d05070c638a57782286',1,'ir_Sharp.h']]], + ['ksharpacbitionoffset_6499',['kSharpAcBitIonOffset',['../ir__Sharp_8h.html#a73f967e9950d04941ed9f6815815fb23',1,'ir_Sharp.h']]], + ['ksharpacbitmark_6500',['kSharpAcBitMark',['../ir__Sharp_8h.html#ae73dd2c91b531bf3a52641b36f56ead7',1,'ir_Sharp.h']]], + ['ksharpacbits_6501',['kSharpAcBits',['../IRremoteESP8266_8h.html#a6c106a982acced5d8aeef98644002ca2',1,'IRremoteESP8266.h']]], + ['ksharpacbittimerenabled_6502',['kSharpAcBitTimerEnabled',['../ir__Sharp_8h.html#a083863299df4ff081be0add9d5082700',1,'ir_Sharp.h']]], + ['ksharpacbittimertype_6503',['kSharpAcBitTimerType',['../ir__Sharp_8h.html#ad47cf2f20c4589b9cbe6b583d62b4675',1,'ir_Sharp.h']]], + ['ksharpacbyteclean_6504',['kSharpAcByteClean',['../ir__Sharp_8h.html#a2f4a4ddf407413a52d45c955ebd5bcd5',1,'ir_Sharp.h']]], + ['ksharpacbytefan_6505',['kSharpAcByteFan',['../ir__Sharp_8h.html#a24139aa535ca54dcf45558da5ee2ac56',1,'ir_Sharp.h']]], + ['ksharpacbyteion_6506',['kSharpAcByteIon',['../ir__Sharp_8h.html#aaceee11c539050ba5ac368b9612131a4',1,'ir_Sharp.h']]], + ['ksharpacbytemode_6507',['kSharpAcByteMode',['../ir__Sharp_8h.html#af7d8a2ab79ae4f2ad48e569576fd34e8',1,'ir_Sharp.h']]], + ['ksharpacbytepowerspecial_6508',['kSharpAcBytePowerSpecial',['../ir__Sharp_8h.html#a44d180bd3babec15143ba8ea8aa18906',1,'ir_Sharp.h']]], + ['ksharpacbytespecial_6509',['kSharpAcByteSpecial',['../ir__Sharp_8h.html#a78ba1ef4993661f9dfaad776dff1b43e',1,'ir_Sharp.h']]], + ['ksharpacbyteswing_6510',['kSharpAcByteSwing',['../ir__Sharp_8h.html#aee580a3c6cfd75f75f46852d0f3df0db',1,'ir_Sharp.h']]], + ['ksharpacbytetemp_6511',['kSharpAcByteTemp',['../ir__Sharp_8h.html#a1b67ab12ed664517124fe3c1d7325927',1,'ir_Sharp.h']]], + ['ksharpacbytetimer_6512',['kSharpAcByteTimer',['../ir__Sharp_8h.html#af2fc9b6abae8ca6ca0d01b8c924386be',1,'ir_Sharp.h']]], + ['ksharpaccool_6513',['kSharpAcCool',['../ir__Sharp_8h.html#ae828d7e915f69cc1e9538839fc51c895',1,'ir_Sharp.h']]], + ['ksharpacdefaultrepeat_6514',['kSharpAcDefaultRepeat',['../IRremoteESP8266_8h.html#a7f0438831899e3df16f9002717c818b9',1,'IRremoteESP8266.h']]], + ['ksharpacdry_6515',['kSharpAcDry',['../ir__Sharp_8h.html#a50ae949b473ed4a6482fa00d747b2c0f',1,'ir_Sharp.h']]], + ['ksharpacfanauto_6516',['kSharpAcFanAuto',['../ir__Sharp_8h.html#a2ef78269271593420ea2bdc20025ca69',1,'ir_Sharp.h']]], + ['ksharpacfanhigh_6517',['kSharpAcFanHigh',['../ir__Sharp_8h.html#af29136d64c2f2a2515918ccf0ff0f594',1,'ir_Sharp.h']]], + ['ksharpacfanmax_6518',['kSharpAcFanMax',['../ir__Sharp_8h.html#a8b0aaa58a5f4caabea84e3b448793054',1,'ir_Sharp.h']]], + ['ksharpacfanmed_6519',['kSharpAcFanMed',['../ir__Sharp_8h.html#a7607f054da76f5e1508abf42d9cd71fc',1,'ir_Sharp.h']]], + ['ksharpacfanmin_6520',['kSharpAcFanMin',['../ir__Sharp_8h.html#a2372fdfbb0d8c2163a3eae5b8eda570a',1,'ir_Sharp.h']]], + ['ksharpacfanoffset_6521',['kSharpAcFanOffset',['../ir__Sharp_8h.html#ae95f02db8d9799ce726f5f467922a36c',1,'ir_Sharp.h']]], + ['ksharpacfansize_6522',['kSharpAcFanSize',['../ir__Sharp_8h.html#a2640f5c4eb0b4e62b9e2124a1fbfb6d2',1,'ir_Sharp.h']]], + ['ksharpacgap_6523',['kSharpAcGap',['../ir__Sharp_8h.html#a777eb0358ce3ef4528f086ff9ff7cd8d',1,'ir_Sharp.h']]], + ['ksharpachdrmark_6524',['kSharpAcHdrMark',['../ir__Sharp_8h.html#aff6f1e55de051762a0def881a5bb555c',1,'ir_Sharp.h']]], + ['ksharpachdrspace_6525',['kSharpAcHdrSpace',['../ir__Sharp_8h.html#a0ea5ff96afd358a8ad1be8d8ed808f04',1,'ir_Sharp.h']]], + ['ksharpacheat_6526',['kSharpAcHeat',['../ir__Sharp_8h.html#ab546d06a0b1f3477f88282f764f208cb',1,'ir_Sharp.h']]], + ['ksharpacmaxtemp_6527',['kSharpAcMaxTemp',['../ir__Sharp_8h.html#a6cfb060ea8c2f650fdd73b055cfda00a',1,'ir_Sharp.h']]], + ['ksharpacmintemp_6528',['kSharpAcMinTemp',['../ir__Sharp_8h.html#ad9ac5214b6cc780d9424ec7d038fe837',1,'ir_Sharp.h']]], + ['ksharpacmodesize_6529',['kSharpAcModeSize',['../ir__Sharp_8h.html#a7dfcf91a08bc37884cc4882c60004736',1,'ir_Sharp.h']]], + ['ksharpacofftimertype_6530',['kSharpAcOffTimerType',['../ir__Sharp_8h.html#ada633bea9c6c2ffd234c8262e92cebd5',1,'ir_Sharp.h']]], + ['ksharpaconespace_6531',['kSharpAcOneSpace',['../ir__Sharp_8h.html#a20e8eb7c8763fbddb20530badbaab38b',1,'ir_Sharp.h']]], + ['ksharpacontimertype_6532',['kSharpAcOnTimerType',['../ir__Sharp_8h.html#adce8625b00931645c7ccf54edf263c59',1,'ir_Sharp.h']]], + ['ksharpacpoweroff_6533',['kSharpAcPowerOff',['../ir__Sharp_8h.html#a5c13882a47bdd289507e8a5a23ec99d6',1,'ir_Sharp.h']]], + ['ksharpacpoweron_6534',['kSharpAcPowerOn',['../ir__Sharp_8h.html#af485487ea50dd2f9bc153e5f83dc5cf9',1,'ir_Sharp.h']]], + ['ksharpacpoweronfromoff_6535',['kSharpAcPowerOnFromOff',['../ir__Sharp_8h.html#ae484cf776fa47542f4d693c29052fc9f',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialoff_6536',['kSharpAcPowerSetSpecialOff',['../ir__Sharp_8h.html#a93b22ba4b5e68f8185ed28a6bb7c05dd',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialoffset_6537',['kSharpAcPowerSetSpecialOffset',['../ir__Sharp_8h.html#a0603455573e1dd203a5f6718efc12085',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialon_6538',['kSharpAcPowerSetSpecialOn',['../ir__Sharp_8h.html#a67aff6b22c0cfb89debb8ade7239f07e',1,'ir_Sharp.h']]], + ['ksharpacpowerspecialsize_6539',['kSharpAcPowerSpecialSize',['../ir__Sharp_8h.html#a233d545e942de27ec9e96d0d5e7afdb3',1,'ir_Sharp.h']]], + ['ksharpacpowertimersetting_6540',['kSharpAcPowerTimerSetting',['../ir__Sharp_8h.html#a208cb9446ea1f42db42a1f6e24b61219',1,'ir_Sharp.h']]], + ['ksharpacpowerunknown_6541',['kSharpAcPowerUnknown',['../ir__Sharp_8h.html#ab20172b860fa1401607f0678c682640f',1,'ir_Sharp.h']]], + ['ksharpacspecialfan_6542',['kSharpAcSpecialFan',['../ir__Sharp_8h.html#a6c1a1c535150f973eecb1a131d0c4780',1,'ir_Sharp.h']]], + ['ksharpacspecialpower_6543',['kSharpAcSpecialPower',['../ir__Sharp_8h.html#a843585897995ee15e39af0d452d8660d',1,'ir_Sharp.h']]], + ['ksharpacspecialswing_6544',['kSharpAcSpecialSwing',['../ir__Sharp_8h.html#a34127a7df393d2a5a84ca90e60e8507a',1,'ir_Sharp.h']]], + ['ksharpacspecialtempecono_6545',['kSharpAcSpecialTempEcono',['../ir__Sharp_8h.html#af2dcb54fc26802d1818ef88e6ddfc819',1,'ir_Sharp.h']]], + ['ksharpacspecialtimer_6546',['kSharpAcSpecialTimer',['../ir__Sharp_8h.html#a539b21c344db53fbfd4f17c91ab98139',1,'ir_Sharp.h']]], + ['ksharpacspecialtimerhalfhour_6547',['kSharpAcSpecialTimerHalfHour',['../ir__Sharp_8h.html#a1f9bf40a4af95689947c09559ed049bf',1,'ir_Sharp.h']]], + ['ksharpacspecialturbo_6548',['kSharpAcSpecialTurbo',['../ir__Sharp_8h.html#a270bb2bc83d4eb8974f498dd8eb299bb',1,'ir_Sharp.h']]], + ['ksharpacstatelength_6549',['kSharpAcStateLength',['../IRremoteESP8266_8h.html#a5192edb9406a8572e393918bab69e3c6',1,'IRremoteESP8266.h']]], + ['ksharpacswingnotoggle_6550',['kSharpAcSwingNoToggle',['../ir__Sharp_8h.html#a9c56d4f694ea69921ba2cb75f67426d6',1,'ir_Sharp.h']]], + ['ksharpacswingoffset_6551',['kSharpAcSwingOffset',['../ir__Sharp_8h.html#a61c5356e645867fa2eeda02c83e5b9ae',1,'ir_Sharp.h']]], + ['ksharpacswingsize_6552',['kSharpAcSwingSize',['../ir__Sharp_8h.html#aafec87d2ddea0fd56d176f1b5f80a6fa',1,'ir_Sharp.h']]], + ['ksharpacswingtoggle_6553',['kSharpAcSwingToggle',['../ir__Sharp_8h.html#aa6db653d25f67214819292b8f86af0e6',1,'ir_Sharp.h']]], + ['ksharpactimerhoursmax_6554',['kSharpAcTimerHoursMax',['../ir__Sharp_8h.html#a63af01993ba1e539dfb8dae67f42b9ae',1,'ir_Sharp.h']]], + ['ksharpactimerhoursoff_6555',['kSharpAcTimerHoursOff',['../ir__Sharp_8h.html#a462c10c12d828ba58d589cc365bd7be3',1,'ir_Sharp.h']]], + ['ksharpactimerhoursoffset_6556',['kSharpAcTimerHoursOffset',['../ir__Sharp_8h.html#aeb8d6ca49ba029bdb3663ff6b9c2cc4d',1,'ir_Sharp.h']]], + ['ksharpactimerhourssize_6557',['kSharpAcTimerHoursSize',['../ir__Sharp_8h.html#a965ed2ef8ba32a325ec41a351d88c17d',1,'ir_Sharp.h']]], + ['ksharpactimerincrement_6558',['kSharpAcTimerIncrement',['../ir__Sharp_8h.html#af32638e308a7034eb013b7ea9569273e',1,'ir_Sharp.h']]], + ['ksharpaczerospace_6559',['kSharpAcZeroSpace',['../ir__Sharp_8h.html#a5310e0404daae1a6e534dbaeaa9a9939',1,'ir_Sharp.h']]], + ['ksharpaddressbits_6560',['kSharpAddressBits',['../IRremoteESP8266_8h.html#a79c2f3cc459267cf0261124ddef47f5e',1,'IRremoteESP8266.h']]], + ['ksharpaddressmask_6561',['kSharpAddressMask',['../ir__Sharp_8cpp.html#a84fba003383cd4652fc804b97002f464',1,'ir_Sharp.cpp']]], + ['ksharpbitmark_6562',['kSharpBitMark',['../ir__Sharp_8cpp.html#ae2adc2bffb2b024faab8da363621733f',1,'ir_Sharp.cpp']]], + ['ksharpbitmarkticks_6563',['kSharpBitMarkTicks',['../ir__Sharp_8cpp.html#aa64bd0c359add4038c0143b5774627bb',1,'ir_Sharp.cpp']]], + ['ksharpbits_6564',['kSharpBits',['../IRremoteESP8266_8h.html#a8a74f9d7cec751cc0945fd89fa6237ae',1,'IRremoteESP8266.h']]], + ['ksharpcommandbits_6565',['kSharpCommandBits',['../IRremoteESP8266_8h.html#ae4cdfc8e358ec738d20c1bda49842ccf',1,'IRremoteESP8266.h']]], + ['ksharpcommandmask_6566',['kSharpCommandMask',['../ir__Sharp_8cpp.html#ad44eda54ade4bef4fdf4451fdb784950',1,'ir_Sharp.cpp']]], + ['ksharpgap_6567',['kSharpGap',['../ir__Sharp_8cpp.html#a77015be2a04274bcb332ec21cb75251e',1,'ir_Sharp.cpp']]], + ['ksharpgapticks_6568',['kSharpGapTicks',['../ir__Sharp_8cpp.html#a4aa110ec2934797f71ddf9bcd34498d1',1,'ir_Sharp.cpp']]], + ['ksharponespace_6569',['kSharpOneSpace',['../ir__Sharp_8cpp.html#a3359539480a203db37c2cf2efd88fdcc',1,'ir_Sharp.cpp']]], + ['ksharponespaceticks_6570',['kSharpOneSpaceTicks',['../ir__Sharp_8cpp.html#a12e18dfd195faae6ca581936434c9063',1,'ir_Sharp.cpp']]], + ['ksharptick_6571',['kSharpTick',['../ir__Sharp_8cpp.html#af417ab19220576243753903657923ba7',1,'ir_Sharp.cpp']]], + ['ksharptogglemask_6572',['kSharpToggleMask',['../ir__Sharp_8cpp.html#a2701123f01683c6927c23c7699bce13a',1,'ir_Sharp.cpp']]], + ['ksharpzerospace_6573',['kSharpZeroSpace',['../ir__Sharp_8cpp.html#ac2ad6123d938999e234896e1635e3063',1,'ir_Sharp.cpp']]], + ['ksharpzerospaceticks_6574',['kSharpZeroSpaceTicks',['../ir__Sharp_8cpp.html#af8c638f77ff29c2d20555343be80e5f0',1,'ir_Sharp.cpp']]], + ['ksherwoodbits_6575',['kSherwoodBits',['../IRremoteESP8266_8h.html#a94abd640c9e7aa225f4a8873a1ddea6a',1,'IRremoteESP8266.h']]], + ['ksherwoodminrepeat_6576',['kSherwoodMinRepeat',['../IRremoteESP8266_8h.html#a2e00b92b55657fc4e140eb85e3a414dc',1,'IRremoteESP8266.h']]], + ['ksilentstr_6577',['kSilentStr',['../IRtext_8cpp.html#a398d3c627c5b95c5d7adfb5308fc7de0',1,'kSilentStr(): IRtext.cpp'],['../IRtext_8h.html#a8efb4256a49dc0acd27d6995851d585e',1,'kSilentStr(): IRtext.cpp']]], + ['ksinglerepeat_6578',['kSingleRepeat',['../IRremoteESP8266_8h.html#a46835b1e2d279570fd818749e88180d4',1,'IRremoteESP8266.h']]], + ['ksleepstr_6579',['kSleepStr',['../IRtext_8cpp.html#a38068788c0ef50e6034dbcffeec1eb36',1,'kSleepStr(): IRtext.cpp'],['../IRtext_8h.html#af9ac743c367e179723b128ad69f124c5',1,'kSleepStr(): IRtext.cpp']]], + ['ksleeptimerstr_6580',['kSleepTimerStr',['../IRtext_8cpp.html#a3402e1f6d78e3c59b71bd0dfdf020b51',1,'kSleepTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a86639857f884487cf3bedc91e71d6faa',1,'kSleepTimerStr(): IRtext.cpp']]], + ['kslowstr_6581',['kSlowStr',['../IRtext_8cpp.html#a3131a17a06dff31058579b301227a04f',1,'kSlowStr(): IRtext.cpp'],['../IRtext_8h.html#a171736ab5e3d59198ed740ea5fd93473',1,'kSlowStr(): IRtext.cpp']]], + ['ksony12bits_6582',['kSony12Bits',['../IRremoteESP8266_8h.html#aa16fdf708a67dbe22c85ad4bac9b05b6',1,'IRremoteESP8266.h']]], + ['ksony15bits_6583',['kSony15Bits',['../IRremoteESP8266_8h.html#ad868d68d289d618ace266519afa059f4',1,'IRremoteESP8266.h']]], + ['ksony20bits_6584',['kSony20Bits',['../IRremoteESP8266_8h.html#aa9cd1ff8036f6c3a288c4f34af4a5eb4',1,'IRremoteESP8266.h']]], + ['ksonyaltfreq_6585',['kSonyAltFreq',['../ir__Sony_8cpp.html#a05912a15a9a6a4a78416600adc7e526b',1,'ir_Sony.cpp']]], + ['ksonyhdrmark_6586',['kSonyHdrMark',['../ir__Sony_8cpp.html#afac5a232c82e81ac257ddfc94aa4f379',1,'ir_Sony.cpp']]], + ['ksonyhdrmarkticks_6587',['kSonyHdrMarkTicks',['../ir__Sony_8cpp.html#a89abc5f0556f38d462202d1de78cbddb',1,'ir_Sony.cpp']]], + ['ksonyminbits_6588',['kSonyMinBits',['../IRremoteESP8266_8h.html#a6f0794107a7643e0bec8de6de9e7621b',1,'IRremoteESP8266.h']]], + ['ksonymingap_6589',['kSonyMinGap',['../ir__Sony_8cpp.html#abfe3a5e1fa2a38ee556326b1ea0e7e11',1,'ir_Sony.cpp']]], + ['ksonymingapticks_6590',['kSonyMinGapTicks',['../ir__Sony_8cpp.html#a150d62f71f79295153bac4694bae0aa3',1,'ir_Sony.cpp']]], + ['ksonyminrepeat_6591',['kSonyMinRepeat',['../IRremoteESP8266_8h.html#a112408429fb4a5cca22a66a351453bad',1,'IRremoteESP8266.h']]], + ['ksonyonemark_6592',['kSonyOneMark',['../ir__Sony_8cpp.html#a490e7ca2b0f81848ae42eb57d0023d13',1,'ir_Sony.cpp']]], + ['ksonyonemarkticks_6593',['kSonyOneMarkTicks',['../ir__Sony_8cpp.html#ad41c0d0496661c2e066056de6974bfe9',1,'ir_Sony.cpp']]], + ['ksonyrptlength_6594',['kSonyRptLength',['../ir__Sony_8cpp.html#a24578b92cf53caa48fa3660f16ec90ec',1,'ir_Sony.cpp']]], + ['ksonyrptlengthticks_6595',['kSonyRptLengthTicks',['../ir__Sony_8cpp.html#a0a7f67ba27e03c35d5df35a2a14a1e19',1,'ir_Sony.cpp']]], + ['ksonyspace_6596',['kSonySpace',['../ir__Sony_8cpp.html#ad09a9eb0dc0b809cea0d0a2a8ff6b9fb',1,'ir_Sony.cpp']]], + ['ksonyspaceticks_6597',['kSonySpaceTicks',['../ir__Sony_8cpp.html#a80dccfab869821cadaf02df664d91eda',1,'ir_Sony.cpp']]], + ['ksonystdfreq_6598',['kSonyStdFreq',['../ir__Sony_8cpp.html#a5e5b14c45909411d160e051f0bc7c63d',1,'ir_Sony.cpp']]], + ['ksonytick_6599',['kSonyTick',['../ir__Sony_8cpp.html#a7ced75a5e9f06f5c68132665d27e01b8',1,'ir_Sony.cpp']]], + ['ksonyzeromark_6600',['kSonyZeroMark',['../ir__Sony_8cpp.html#a7808995a9d2755681f1461d578d5480b',1,'ir_Sony.cpp']]], + ['ksonyzeromarkticks_6601',['kSonyZeroMarkTicks',['../ir__Sony_8cpp.html#a542aed17f98a11ca89456eec507a5225',1,'ir_Sony.cpp']]], + ['kspace_6602',['kSpace',['../ir__Lasertag_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_Lasertag.cpp'],['../ir__MWM_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_MWM.cpp'],['../ir__RC5__RC6_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_RC5_RC6.cpp']]], + ['kspacelbracestr_6603',['kSpaceLBraceStr',['../IRtext_8cpp.html#a156ef0014809a3509e7b254a9585e0a1',1,'kSpaceLBraceStr(): IRtext.cpp'],['../IRtext_8h.html#a42a2d6b1e764138a5e20b7a34e0cff03',1,'kSpaceLBraceStr(): IRtext.cpp']]], + ['kspacestate_6604',['kSpaceState',['../IRrecv_8h.html#acc0d1931164a8967c210eb03a2d03e2a',1,'IRrecv.h']]], + ['kstartoffset_6605',['kStartOffset',['../IRrecv_8h.html#a44a836a34428f8f75b1ae566de4bb972',1,'IRrecv.h']]], + ['kstartstr_6606',['kStartStr',['../IRtext_8cpp.html#a2075a48eed571455a88e7dfbc3a547ef',1,'kStartStr(): IRtext.cpp'],['../IRtext_8h.html#ad030c0930697d3c295f3783e8519995c',1,'kStartStr(): IRtext.cpp']]], + ['kstatesizemax_6607',['kStateSizeMax',['../IRrecv_8h.html#ab7d82cf4c0937c9b1d59d75f6f347ab2',1,'IRrecv.h']]], + ['kstepstr_6608',['kStepStr',['../IRtext_8cpp.html#ac6c64c4bdc955b6528616db3a4b303c1',1,'kStepStr(): IRtext.cpp'],['../IRtext_8h.html#ad8cc5f179089e8497a9670492429d7e3',1,'kStepStr(): IRtext.cpp']]], + ['kstopstate_6609',['kStopState',['../IRrecv_8h.html#a0e87ae8496a061e394bc9f7f3415a9b3',1,'IRrecv.h']]], + ['kstopstr_6610',['kStopStr',['../IRtext_8cpp.html#a0466188f9064d18622304cd375b18390',1,'kStopStr(): IRtext.cpp'],['../IRtext_8h.html#a7037a67c71778fe06f9dc9b4363f6f9b',1,'kStopStr(): IRtext.cpp']]], + ['ksuperstr_6611',['kSuperStr',['../IRtext_8cpp.html#a81e6c76017bc819882a043ac8fcc2854',1,'kSuperStr(): IRtext.cpp'],['../IRtext_8h.html#af83fbe756a22ef800d40bc738be886c7',1,'kSuperStr(): IRtext.cpp']]], + ['kswinghstr_6612',['kSwingHStr',['../IRtext_8cpp.html#a12d4e0afe0f6b96af817ebc95eb0b6f4',1,'kSwingHStr(): IRtext.cpp'],['../IRtext_8h.html#acfad569446290c1da0c102b98344411c',1,'kSwingHStr(): IRtext.cpp']]], + ['kswingstr_6613',['kSwingStr',['../IRtext_8cpp.html#a106174aef3a46450c0a16bef7c36a8c5',1,'kSwingStr(): IRtext.cpp'],['../IRtext_8h.html#a56d1a94eae3422758b2762da008e243c',1,'kSwingStr(): IRtext.cpp']]], + ['kswingvmodestr_6614',['kSwingVModeStr',['../IRtext_8cpp.html#ab71be957190939e2b4643f2e56e1201f',1,'kSwingVModeStr(): IRtext.cpp'],['../IRtext_8h.html#a0c801e35becc1eab4cdf0076e1c99485',1,'kSwingVModeStr(): IRtext.cpp']]], + ['kswingvstr_6615',['kSwingVStr',['../IRtext_8cpp.html#a6dc1ec788e0659e82219534b5dbb79bc',1,'kSwingVStr(): IRtext.cpp'],['../IRtext_8h.html#a8415af77afcb671c3729d604be51fd22',1,'kSwingVStr(): IRtext.cpp']]], + ['kswingvtogglestr_6616',['kSwingVToggleStr',['../IRtext_8cpp.html#a3efcf06e5ac4d6309bad1b1d0e49a933',1,'kSwingVToggleStr(): IRtext.cpp'],['../IRtext_8h.html#a27ae4d475898878bd8e71111066629c6',1,'kSwingVToggleStr(): IRtext.cpp']]], + ['ksymphonybits_6617',['kSymphonyBits',['../IRremoteESP8266_8h.html#abb5b89578ab0757999530c0383f38533',1,'IRremoteESP8266.h']]], + ['ksymphonydefaultrepeat_6618',['kSymphonyDefaultRepeat',['../IRremoteESP8266_8h.html#a219b8495f77932c200680f7a2b133880',1,'IRremoteESP8266.h']]], + ['ksymphonyfootergap_6619',['kSymphonyFooterGap',['../ir__Symphony_8cpp.html#a363cf54f4e752932d5e341975c2445f4',1,'ir_Symphony.cpp']]], + ['ksymphonyonemark_6620',['kSymphonyOneMark',['../ir__Symphony_8cpp.html#a469bfa8046ba75f9ba7cda4996dd785d',1,'ir_Symphony.cpp']]], + ['ksymphonyonespace_6621',['kSymphonyOneSpace',['../ir__Symphony_8cpp.html#ab699747bdf28d5a89920041e9c5bb01b',1,'ir_Symphony.cpp']]], + ['ksymphonyzeromark_6622',['kSymphonyZeroMark',['../ir__Symphony_8cpp.html#a58f27b1b9da16ffe73448c7ae3998fc9',1,'ir_Symphony.cpp']]], + ['ksymphonyzerospace_6623',['kSymphonyZeroSpace',['../ir__Symphony_8cpp.html#a9aaf8db419618de847573d2019155287',1,'ir_Symphony.cpp']]], + ['ktcl112acauto_6624',['kTcl112AcAuto',['../ir__Tcl_8h.html#a11a982cc182e446d53ded658cb7a08b6',1,'ir_Tcl.h']]], + ['ktcl112acbiteconooffset_6625',['kTcl112AcBitEconoOffset',['../ir__Tcl_8h.html#a97c8948de72d702b859a7abccfbc423e',1,'ir_Tcl.h']]], + ['ktcl112acbithealthoffset_6626',['kTcl112AcBitHealthOffset',['../ir__Tcl_8h.html#a2acb2c5cd2f8b729047f9eecf93f96af',1,'ir_Tcl.h']]], + ['ktcl112acbitlightoffset_6627',['kTcl112AcBitLightOffset',['../ir__Tcl_8h.html#ad87c878f7a30a05418a5babfc52c0e9e',1,'ir_Tcl.h']]], + ['ktcl112acbitmark_6628',['kTcl112AcBitMark',['../ir__Tcl_8h.html#a45360de532d2262246bf57cb7c08604d',1,'ir_Tcl.h']]], + ['ktcl112acbits_6629',['kTcl112AcBits',['../IRremoteESP8266_8h.html#a4a60d79056d70d3d56067b0bb2ec00f4',1,'IRremoteESP8266.h']]], + ['ktcl112acbitswinghoffset_6630',['kTcl112AcBitSwingHOffset',['../ir__Tcl_8h.html#ad807894f92249e44d1725f18de013369',1,'ir_Tcl.h']]], + ['ktcl112acbitturbooffset_6631',['kTcl112AcBitTurboOffset',['../ir__Tcl_8h.html#a7a6e09c1b4620e96820b3b3c54fb0e18',1,'ir_Tcl.h']]], + ['ktcl112accool_6632',['kTcl112AcCool',['../ir__Tcl_8h.html#a4a4b778086b3ebf856b750fe0c4bd2c0',1,'ir_Tcl.h']]], + ['ktcl112acdefaultrepeat_6633',['kTcl112AcDefaultRepeat',['../IRremoteESP8266_8h.html#a97c82cec6d72845d9ab8a201b0fa5034',1,'IRremoteESP8266.h']]], + ['ktcl112acdry_6634',['kTcl112AcDry',['../ir__Tcl_8h.html#a1d9ec40c278fedf87acb7420ef861101',1,'ir_Tcl.h']]], + ['ktcl112acfan_6635',['kTcl112AcFan',['../ir__Tcl_8h.html#ae07f3dd0a84be27bcb13ba60f4fd025b',1,'ir_Tcl.h']]], + ['ktcl112acfanauto_6636',['kTcl112AcFanAuto',['../ir__Tcl_8h.html#a099935d6d2bf6ebb28332005036c59c0',1,'ir_Tcl.h']]], + ['ktcl112acfanhigh_6637',['kTcl112AcFanHigh',['../ir__Tcl_8h.html#aab9672bac3e83b2e3b3d2cc5f1aa0e1f',1,'ir_Tcl.h']]], + ['ktcl112acfanlow_6638',['kTcl112AcFanLow',['../ir__Tcl_8h.html#a5114fe3f978672fc62c0cd16f6d46dd7',1,'ir_Tcl.h']]], + ['ktcl112acfanmed_6639',['kTcl112AcFanMed',['../ir__Tcl_8h.html#ad8f34f1972da347a169e2eb4ddf3d835',1,'ir_Tcl.h']]], + ['ktcl112acfansize_6640',['kTcl112AcFanSize',['../ir__Tcl_8h.html#a802bbb6258edf6dcdd05a383db28e9d3',1,'ir_Tcl.h']]], + ['ktcl112acgap_6641',['kTcl112AcGap',['../ir__Tcl_8h.html#a9ccdf5ce9ce325b9813dadbdc855a469',1,'ir_Tcl.h']]], + ['ktcl112achalfdegreeoffset_6642',['kTcl112AcHalfDegreeOffset',['../ir__Tcl_8h.html#a1ba7d7fa8df2243330eafce097209651',1,'ir_Tcl.h']]], + ['ktcl112achdrmark_6643',['kTcl112AcHdrMark',['../ir__Tcl_8h.html#a56f9f7daf3ada77f8f844afd46a80de9',1,'ir_Tcl.h']]], + ['ktcl112achdrmarktolerance_6644',['kTcl112AcHdrMarkTolerance',['../ir__Tcl_8h.html#ab9d980747b2ddd1b7fb04f00d71af1e7',1,'ir_Tcl.h']]], + ['ktcl112achdrspace_6645',['kTcl112AcHdrSpace',['../ir__Tcl_8h.html#a9135b4d7496383ad3a7da7c3ac7c92b4',1,'ir_Tcl.h']]], + ['ktcl112acheat_6646',['kTcl112AcHeat',['../ir__Tcl_8h.html#ae573f856f0bdf50406e9be84b1aa8ade',1,'ir_Tcl.h']]], + ['ktcl112acmodesize_6647',['kTcl112AcModeSize',['../ir__Tcl_8h.html#a07e49881d14cb1c84cfbf3695ae64580',1,'ir_Tcl.h']]], + ['ktcl112aconespace_6648',['kTcl112AcOneSpace',['../ir__Tcl_8h.html#af1e67019978260ba3f514cd895b54dad',1,'ir_Tcl.h']]], + ['ktcl112acpoweroffset_6649',['kTcl112AcPowerOffset',['../ir__Tcl_8h.html#ad36204b310ec8a069f631322d806aa7f',1,'ir_Tcl.h']]], + ['ktcl112acstatelength_6650',['kTcl112AcStateLength',['../IRremoteESP8266_8h.html#a23ba2f5af02242e14ae7eefcd066152e',1,'IRremoteESP8266.h']]], + ['ktcl112acswingvoff_6651',['kTcl112AcSwingVOff',['../ir__Tcl_8h.html#aa78e1b544f392c251093d458e5d21e12',1,'ir_Tcl.h']]], + ['ktcl112acswingvoffset_6652',['kTcl112AcSwingVOffset',['../ir__Tcl_8h.html#ab0412b0d865eaf788a5672300575b1d8',1,'ir_Tcl.h']]], + ['ktcl112acswingvon_6653',['kTcl112AcSwingVOn',['../ir__Tcl_8h.html#a5406fbabd66478d601aebc6939a3788f',1,'ir_Tcl.h']]], + ['ktcl112acswingvsize_6654',['kTcl112AcSwingVSize',['../ir__Tcl_8h.html#a7bacb40b18b280da13b2d1b781c825e5',1,'ir_Tcl.h']]], + ['ktcl112actempmax_6655',['kTcl112AcTempMax',['../ir__Tcl_8h.html#a60efbe31031e1e9c3a17c7d80cac54cb',1,'ir_Tcl.h']]], + ['ktcl112actempmin_6656',['kTcl112AcTempMin',['../ir__Tcl_8h.html#a30fe65ec015bc4d91cd35ead9cc43dcc',1,'ir_Tcl.h']]], + ['ktcl112actolerance_6657',['kTcl112AcTolerance',['../ir__Tcl_8h.html#a13bbe794b2b59763f7f93f15a3f26820',1,'ir_Tcl.h']]], + ['ktcl112aczerospace_6658',['kTcl112AcZeroSpace',['../ir__Tcl_8h.html#abc05edaeb1a4fa7e6ccf9bda1f66b483',1,'ir_Tcl.h']]], + ['ktecoauto_6659',['kTecoAuto',['../ir__Teco_8h.html#a79178aa25d9f60c0a838285369e1b910',1,'ir_Teco.h']]], + ['ktecobitmark_6660',['kTecoBitMark',['../ir__Teco_8cpp.html#a0aa2e352f4a61027b17467e92863883b',1,'ir_Teco.cpp']]], + ['ktecobits_6661',['kTecoBits',['../IRremoteESP8266_8h.html#aee01958e9d97a70a6881cf560ca0ca9d',1,'IRremoteESP8266.h']]], + ['ktecocool_6662',['kTecoCool',['../ir__Teco_8h.html#a554686c72b6bc487d03c9461f9633a6b',1,'ir_Teco.h']]], + ['ktecodefaultrepeat_6663',['kTecoDefaultRepeat',['../IRremoteESP8266_8h.html#a095362359f34c1ee5ab71d56e6d64f64',1,'IRremoteESP8266.h']]], + ['ktecodry_6664',['kTecoDry',['../ir__Teco_8h.html#af7efcf371967eb97fd31d54016a82006',1,'ir_Teco.h']]], + ['ktecofan_6665',['kTecoFan',['../ir__Teco_8h.html#a7385fe198242c9203e3a5d5ffb7beb4d',1,'ir_Teco.h']]], + ['ktecofanauto_6666',['kTecoFanAuto',['../ir__Teco_8h.html#a43e58c0158efac1c4e5497c619b5674c',1,'ir_Teco.h']]], + ['ktecofanhigh_6667',['kTecoFanHigh',['../ir__Teco_8h.html#a0a73f5f892e7f9812793fbf5dab458dd',1,'ir_Teco.h']]], + ['ktecofanlow_6668',['kTecoFanLow',['../ir__Teco_8h.html#abac7443a86fb304376dd94a9c10e6940',1,'ir_Teco.h']]], + ['ktecofanmed_6669',['kTecoFanMed',['../ir__Teco_8h.html#a35f313943f9e2f5b69d5237fdaa64914',1,'ir_Teco.h']]], + ['ktecofanoffset_6670',['kTecoFanOffset',['../ir__Teco_8h.html#ae70841ad987ac89abaaf99b11655eaae',1,'ir_Teco.h']]], + ['ktecofansize_6671',['kTecoFanSize',['../ir__Teco_8h.html#a45734d2be952e3faa796d86245eaf241',1,'ir_Teco.h']]], + ['ktecogap_6672',['kTecoGap',['../ir__Teco_8cpp.html#a6a153d84287fba3bd11e3e5054fd7e30',1,'ir_Teco.cpp']]], + ['ktecohdrmark_6673',['kTecoHdrMark',['../ir__Teco_8cpp.html#ada983ce2d6f03949cddfe06191ab05d9',1,'ir_Teco.cpp']]], + ['ktecohdrspace_6674',['kTecoHdrSpace',['../ir__Teco_8cpp.html#acf417d42fd39dbaf06282162ab5b17e2',1,'ir_Teco.cpp']]], + ['ktecoheat_6675',['kTecoHeat',['../ir__Teco_8h.html#ab6f9dbeb2838b124be12d08fd9b209bb',1,'ir_Teco.h']]], + ['ktecohumidoffset_6676',['kTecoHumidOffset',['../ir__Teco_8h.html#ad95126f6815d24b5d1b38e44677f3d7e',1,'ir_Teco.h']]], + ['ktecolightoffset_6677',['kTecoLightOffset',['../ir__Teco_8h.html#a5dc2cb366974b2baa9f7cbfb26d90415',1,'ir_Teco.h']]], + ['ktecomaxtemp_6678',['kTecoMaxTemp',['../ir__Teco_8h.html#a1c24aa0cc4d475a5eb97d5208f4dcf06',1,'ir_Teco.h']]], + ['ktecomintemp_6679',['kTecoMinTemp',['../ir__Teco_8h.html#a54da99bfcbea5e076c3ca2934e769ab1',1,'ir_Teco.h']]], + ['ktecomodeoffset_6680',['kTecoModeOffset',['../ir__Teco_8h.html#a1aca7a8a2822cd1494dabeda5b11b9be',1,'ir_Teco.h']]], + ['ktecoonespace_6681',['kTecoOneSpace',['../ir__Teco_8cpp.html#a62eccbf6773ea8fbc18432627c62d0d5',1,'ir_Teco.cpp']]], + ['ktecopoweroffset_6682',['kTecoPowerOffset',['../ir__Teco_8h.html#a4eec88582ed29e424549497deb9eceef',1,'ir_Teco.h']]], + ['ktecoreset_6683',['kTecoReset',['../ir__Teco_8h.html#acf559a2cd772835ce46c3f673cd95806',1,'ir_Teco.h']]], + ['ktecosaveoffset_6684',['kTecoSaveOffset',['../ir__Teco_8h.html#a63d5efa7cfc84ee22d3575cc713d1f62',1,'ir_Teco.h']]], + ['ktecosleepoffset_6685',['kTecoSleepOffset',['../ir__Teco_8h.html#ae7da65034a8a84e79ebb1497e56e38fe',1,'ir_Teco.h']]], + ['ktecoswingoffset_6686',['kTecoSwingOffset',['../ir__Teco_8h.html#aaa821eb3ad9a5edadba2b83b6d2094b6',1,'ir_Teco.h']]], + ['ktecotempoffset_6687',['kTecoTempOffset',['../ir__Teco_8h.html#ae887d9c5702d63e4b4fa5250ed5bf0d9',1,'ir_Teco.h']]], + ['ktecotempsize_6688',['kTecoTempSize',['../ir__Teco_8h.html#a635db8dbba35e4326958fca6dfe67603',1,'ir_Teco.h']]], + ['ktecotimerhalfhouroffset_6689',['kTecoTimerHalfHourOffset',['../ir__Teco_8h.html#a2692a59900c10b6da6662fac5a312e04',1,'ir_Teco.h']]], + ['ktecotimeronoffset_6690',['kTecoTimerOnOffset',['../ir__Teco_8h.html#a7bcf79fa5e5280ad35c9a9512b2fdc7f',1,'ir_Teco.h']]], + ['ktecotimertenshoursoffset_6691',['kTecoTimerTensHoursOffset',['../ir__Teco_8h.html#adaa73601e31fa7217d371645d835f0ca',1,'ir_Teco.h']]], + ['ktecotimertenshourssize_6692',['kTecoTimerTensHoursSize',['../ir__Teco_8h.html#a57bf1b777b9b56aad4f224b6bba1218c',1,'ir_Teco.h']]], + ['ktecotimerunithoursoffset_6693',['kTecoTimerUnitHoursOffset',['../ir__Teco_8h.html#ac47fc38319e7e1d90d42c789b806cdbd',1,'ir_Teco.h']]], + ['ktecotimerunithourssize_6694',['kTecoTimerUnitHoursSize',['../ir__Teco_8h.html#a54ac664e32ce0d8b4d8d4d4d459dbc46',1,'ir_Teco.h']]], + ['ktecozerospace_6695',['kTecoZeroSpace',['../ir__Teco_8cpp.html#a8dc1f6ea44519a0930b48f69a83a7363',1,'ir_Teco.cpp']]], + ['ktempdownstr_6696',['kTempDownStr',['../IRtext_8cpp.html#a3fa3262c5631c9357a5723c70dc3be12',1,'kTempDownStr(): IRtext.cpp'],['../IRtext_8h.html#a3d367a899d7e8ed20844bb3c48bf6395',1,'kTempDownStr(): IRtext.cpp']]], + ['ktempstr_6697',['kTempStr',['../IRtext_8cpp.html#a487bd9a4225536aba2595be0b5cb8039',1,'kTempStr(): IRtext.cpp'],['../IRtext_8h.html#a87652df1cf724353547f27a9ebde5edb',1,'kTempStr(): IRtext.cpp']]], + ['ktempupstr_6698',['kTempUpStr',['../IRtext_8cpp.html#a7c4f18322b600aaaf5a8716654d05dc3',1,'kTempUpStr(): IRtext.cpp'],['../IRtext_8h.html#a71687df5bc94e4ca18cf59c9ff238e86',1,'kTempUpStr(): IRtext.cpp']]], + ['kthreeletterdayofweekstr_6699',['kThreeLetterDayOfWeekStr',['../IRtext_8cpp.html#ae16da0464743313a1fbeae92dcfcebbd',1,'kThreeLetterDayOfWeekStr(): IRtext.cpp'],['../IRtext_8h.html#a837ecfeff9a1bc7546016229e9f2ddfb',1,'kThreeLetterDayOfWeekStr(): IRtext.cpp']]], + ['ktimeoutms_6700',['kTimeoutMs',['../IRrecv_8h.html#ad37e9659aaef29c541802d9759e0ab7b',1,'IRrecv.h']]], + ['ktimerstr_6701',['kTimerStr',['../IRtext_8cpp.html#a2b5219ba887cfbc578fb880ebada832a',1,'kTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a36fa3584a89f6e48757eba8f3df7e109',1,'kTimerStr(): IRtext.cpp']]], + ['ktimesep_6702',['kTimeSep',['../IRtext_8cpp.html#a277b588db53ec31ab7b0d287310c6d50',1,'kTimeSep(): IRtext.cpp'],['../IRtext_8h.html#a277b588db53ec31ab7b0d287310c6d50',1,'kTimeSep(): IRtext.cpp']]], + ['ktogglestr_6703',['kToggleStr',['../IRtext_8cpp.html#a33860b90859d19191c9759b099283b37',1,'kToggleStr(): IRtext.cpp'],['../IRtext_8h.html#a05b1e2f809dadf05e22e1cb1d1a7f07e',1,'kToggleStr(): IRtext.cpp']]], + ['ktolerance_6704',['kTolerance',['../IRrecv_8h.html#a7884008b3a738dfc7bd8658655e10272',1,'IRrecv.h']]], + ['ktopstr_6705',['kTopStr',['../IRtext_8cpp.html#a65a8bf89c9dd0277607478277c0c7088',1,'kTopStr(): IRtext.cpp'],['../IRtext_8h.html#a6bb6abfc54409b801dcb591f036635d2',1,'kTopStr(): IRtext.cpp']]], + ['ktoshibaacauto_6706',['kToshibaAcAuto',['../ir__Toshiba_8h.html#a4730189595a884ae6535805948e096aa',1,'ir_Toshiba.h']]], + ['ktoshibaacbitmark_6707',['kToshibaAcBitMark',['../ir__Toshiba_8cpp.html#adff1c244103ff274243b8e20ca209866',1,'ir_Toshiba.cpp']]], + ['ktoshibaacbits_6708',['kToshibaACBits',['../IRremoteESP8266_8h.html#a172dde7867fa9a68902c3ad7ea9629b0',1,'IRremoteESP8266.h']]], + ['ktoshibaaccool_6709',['kToshibaAcCool',['../ir__Toshiba_8h.html#a2f30e65bb092365d1a8bcb1f3395333a',1,'ir_Toshiba.h']]], + ['ktoshibaacdry_6710',['kToshibaAcDry',['../ir__Toshiba_8h.html#a10b77d1038efc59775398789c33af91e',1,'ir_Toshiba.h']]], + ['ktoshibaacfanauto_6711',['kToshibaAcFanAuto',['../ir__Toshiba_8h.html#a69f52e19a5b0e68abda00b680fbef7f6',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmax_6712',['kToshibaAcFanMax',['../ir__Toshiba_8h.html#a0f6ffde3491f464166d6064d7dfe5ba4',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmed_6713',['kToshibaAcFanMed',['../ir__Toshiba_8h.html#a3ff967af7d1a30c7c5cb958eaa5cbd58',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmin_6714',['kToshibaAcFanMin',['../ir__Toshiba_8h.html#ab2c5eea9ccabf2e0e56bc03baec5d898',1,'ir_Toshiba.h']]], + ['ktoshibaacfanoffset_6715',['kToshibaAcFanOffset',['../ir__Toshiba_8h.html#a8276d25876329968bbf36eac3598972c',1,'ir_Toshiba.h']]], + ['ktoshibaacfansize_6716',['kToshibaAcFanSize',['../ir__Toshiba_8h.html#a5a91c19e799721560a5a9ef77a245888',1,'ir_Toshiba.h']]], + ['ktoshibaachdrmark_6717',['kToshibaAcHdrMark',['../ir__Toshiba_8cpp.html#a2eac25ff2a381ad6690623641153a780',1,'ir_Toshiba.cpp']]], + ['ktoshibaachdrspace_6718',['kToshibaAcHdrSpace',['../ir__Toshiba_8cpp.html#a0ae9047d5a204f320c06736fa40d0a7d',1,'ir_Toshiba.cpp']]], + ['ktoshibaacheat_6719',['kToshibaAcHeat',['../ir__Toshiba_8h.html#aa9ec24f9a5e460aa7017f642ce7a4c0d',1,'ir_Toshiba.h']]], + ['ktoshibaacmaxtemp_6720',['kToshibaAcMaxTemp',['../ir__Toshiba_8h.html#a475028a2a519e3310506ceac0a5dc4e6',1,'ir_Toshiba.h']]], + ['ktoshibaacmingap_6721',['kToshibaAcMinGap',['../ir__Toshiba_8cpp.html#ade7642284aa7c6a638b9fab45610cc59',1,'ir_Toshiba.cpp']]], + ['ktoshibaacminrepeat_6722',['kToshibaACMinRepeat',['../IRremoteESP8266_8h.html#a8fca6a7c3cd608ff49cab35f24af0546',1,'IRremoteESP8266.h']]], + ['ktoshibaacmintemp_6723',['kToshibaAcMinTemp',['../ir__Toshiba_8h.html#ad0e8e76aabc38ac7ba2f13a009de98e0',1,'ir_Toshiba.h']]], + ['ktoshibaacmodeoffset_6724',['kToshibaAcModeOffset',['../ir__Toshiba_8h.html#a4e097e34b0f2dd9eaacf94d043f726d0',1,'ir_Toshiba.h']]], + ['ktoshibaacmodesize_6725',['kToshibaAcModeSize',['../ir__Toshiba_8h.html#a920d55af8e499a7c2293a7d8180104da',1,'ir_Toshiba.h']]], + ['ktoshibaaconespace_6726',['kToshibaAcOneSpace',['../ir__Toshiba_8cpp.html#a787330c9e5f9d30e8df157acc15f56dd',1,'ir_Toshiba.cpp']]], + ['ktoshibaacpoweroffset_6727',['kToshibaAcPowerOffset',['../ir__Toshiba_8h.html#adfd3caac2bd0b636508afbbf67b04dcd',1,'ir_Toshiba.h']]], + ['ktoshibaacstatelength_6728',['kToshibaACStateLength',['../IRremoteESP8266_8h.html#ad3be6a1b9241c20bb1464a2cb80b97d2',1,'IRremoteESP8266.h']]], + ['ktoshibaactempoffset_6729',['kToshibaAcTempOffset',['../ir__Toshiba_8h.html#a68be75c21288e249d7b44fe9648de91f',1,'ir_Toshiba.h']]], + ['ktoshibaactempsize_6730',['kToshibaAcTempSize',['../ir__Toshiba_8h.html#a89ec8108586e0d5b9f58a160f4db37c8',1,'ir_Toshiba.h']]], + ['ktoshibaaczerospace_6731',['kToshibaAcZeroSpace',['../ir__Toshiba_8cpp.html#ab2fc2833cfb31d872894073687eebd99',1,'ir_Toshiba.cpp']]], + ['ktrotecauto_6732',['kTrotecAuto',['../ir__Trotec_8h.html#a53b2687b96f8e69ec6f57dd2ac7a6dfa',1,'ir_Trotec.h']]], + ['ktrotecbitmark_6733',['kTrotecBitMark',['../ir__Trotec_8cpp.html#a870b2da19855eff625a2834ca7fd8765',1,'ir_Trotec.cpp']]], + ['ktrotecbits_6734',['kTrotecBits',['../IRremoteESP8266_8h.html#ab819cb0a34937714dcb10059799c26e2',1,'IRremoteESP8266.h']]], + ['ktroteccool_6735',['kTrotecCool',['../ir__Trotec_8h.html#add33a35046e4270ad9ff3b998526d5d1',1,'ir_Trotec.h']]], + ['ktrotecdefaultrepeat_6736',['kTrotecDefaultRepeat',['../IRremoteESP8266_8h.html#a4c0411462f2854a8606deca09ed15df5',1,'IRremoteESP8266.h']]], + ['ktrotecdeftemp_6737',['kTrotecDefTemp',['../ir__Trotec_8h.html#ac28d1d0ea6db18716a7d9d21e84178c0',1,'ir_Trotec.h']]], + ['ktrotecdry_6738',['kTrotecDry',['../ir__Trotec_8h.html#abdaa1836c6bc90b1d5813df028a76e21',1,'ir_Trotec.h']]], + ['ktrotecfan_6739',['kTrotecFan',['../ir__Trotec_8h.html#a9309d528d50dd542a5184a51fb101a6a',1,'ir_Trotec.h']]], + ['ktrotecfanhigh_6740',['kTrotecFanHigh',['../ir__Trotec_8h.html#ae780f0bb6b9b83f3dbcc1c1e282e5436',1,'ir_Trotec.h']]], + ['ktrotecfanlow_6741',['kTrotecFanLow',['../ir__Trotec_8h.html#aa1c3695c1becc935d2a3b2691996a17b',1,'ir_Trotec.h']]], + ['ktrotecfanmed_6742',['kTrotecFanMed',['../ir__Trotec_8h.html#abae1944f529099ff4736b6cb13bcbeda',1,'ir_Trotec.h']]], + ['ktrotecfanoffset_6743',['kTrotecFanOffset',['../ir__Trotec_8h.html#a3b9034b96268707f7b6fc45a16499479',1,'ir_Trotec.h']]], + ['ktrotecfansize_6744',['kTrotecFanSize',['../ir__Trotec_8h.html#a89d7de622d0f53f800c1a5a2887a81e4',1,'ir_Trotec.h']]], + ['ktrotecgap_6745',['kTrotecGap',['../ir__Trotec_8cpp.html#a753ba93d7b757dc58fcf1b4a6bb65ff6',1,'ir_Trotec.cpp']]], + ['ktrotecgapend_6746',['kTrotecGapEnd',['../ir__Trotec_8cpp.html#a5fcc4a020bcebfe90abe12d4a47de372',1,'ir_Trotec.cpp']]], + ['ktrotechdrmark_6747',['kTrotecHdrMark',['../ir__Trotec_8cpp.html#a809faed7ee2fef78a5b8271a2c5ddd10',1,'ir_Trotec.cpp']]], + ['ktrotechdrspace_6748',['kTrotecHdrSpace',['../ir__Trotec_8cpp.html#a5d42cd98bf737dd8161572afa393be1e',1,'ir_Trotec.cpp']]], + ['ktrotecintro1_6749',['kTrotecIntro1',['../ir__Trotec_8h.html#aabc5c6a9b4867c25d84ffe2839e88564',1,'ir_Trotec.h']]], + ['ktrotecintro2_6750',['kTrotecIntro2',['../ir__Trotec_8h.html#ac33de8b2fc4b70bb272a56f6bbb68e34',1,'ir_Trotec.h']]], + ['ktrotecmaxtemp_6751',['kTrotecMaxTemp',['../ir__Trotec_8h.html#abfe4004dcac892f575ec1efb09567595',1,'ir_Trotec.h']]], + ['ktrotecmaxtimer_6752',['kTrotecMaxTimer',['../ir__Trotec_8h.html#a8467d1b9983d5750a61817cacb148efd',1,'ir_Trotec.h']]], + ['ktrotecmintemp_6753',['kTrotecMinTemp',['../ir__Trotec_8h.html#a091904af9fee2384e137feab274af7f8',1,'ir_Trotec.h']]], + ['ktrotecmodeoffset_6754',['kTrotecModeOffset',['../ir__Trotec_8h.html#aa0d48802845d5cf0410550bb98e4cbb5',1,'ir_Trotec.h']]], + ['ktrotecmodesize_6755',['kTrotecModeSize',['../ir__Trotec_8h.html#ae45ea2f0f8b5d09568c0322e1735ca85',1,'ir_Trotec.h']]], + ['ktroteconespace_6756',['kTrotecOneSpace',['../ir__Trotec_8cpp.html#a570aa73a82089906971932212d99a283',1,'ir_Trotec.cpp']]], + ['ktrotecpowerbitoffset_6757',['kTrotecPowerBitOffset',['../ir__Trotec_8h.html#a11fcdfe886385de6363d06371cdcff43',1,'ir_Trotec.h']]], + ['ktrotecsleepbitoffset_6758',['kTrotecSleepBitOffset',['../ir__Trotec_8h.html#af81754a025119a3dc9924df5508b18c0',1,'ir_Trotec.h']]], + ['ktrotecstatelength_6759',['kTrotecStateLength',['../IRremoteESP8266_8h.html#ae1d2aa52fef81f03b92c35f4970728d2',1,'IRremoteESP8266.h']]], + ['ktrotectempoffset_6760',['kTrotecTempOffset',['../ir__Trotec_8h.html#a08a844aefec8d0440365c9204a01034c',1,'ir_Trotec.h']]], + ['ktrotectempsize_6761',['kTrotecTempSize',['../ir__Trotec_8h.html#a1141680a808f41513548a8747c37f975',1,'ir_Trotec.h']]], + ['ktrotectimerbitoffset_6762',['kTrotecTimerBitOffset',['../ir__Trotec_8h.html#aad59f1284ec04736a3c6629c3cd87731',1,'ir_Trotec.h']]], + ['ktroteczerospace_6763',['kTrotecZeroSpace',['../ir__Trotec_8cpp.html#a8e8f85e7b8a8157eb425316b5108d717',1,'ir_Trotec.cpp']]], + ['ktruestr_6764',['kTrueStr',['../IRtext_8cpp.html#a28a627d6f48d7d06a560f9613e4550fa',1,'kTrueStr(): IRtext.cpp'],['../IRtext_8h.html#aca6e78a25b9dacd2508069f0a6b919c0',1,'kTrueStr(): IRtext.cpp']]], + ['kturbostr_6765',['kTurboStr',['../IRtext_8cpp.html#a9f3f7395d980887699ac5a0c146d37d2',1,'kTurboStr(): IRtext.cpp'],['../IRtext_8h.html#a3ced6d2a545174133308d7803157f7f8',1,'kTurboStr(): IRtext.cpp']]], + ['kunknownstr_6766',['kUnknownStr',['../IRtext_8cpp.html#a9c6c6d47ce3eb07cc607faa600978029',1,'kUnknownStr(): IRtext.cpp'],['../IRtext_8h.html#aa59176b31741b60729d4279817a7da1b',1,'kUnknownStr(): IRtext.cpp']]], + ['kunknownthreshold_6767',['kUnknownThreshold',['../IRrecv_8h.html#aa6b5a940c7a0432aa82a8d823202cd7f',1,'IRrecv.h']]], + ['kupperstr_6768',['kUpperStr',['../IRtext_8cpp.html#a887bb7c61f38014d21b025c67102fa0b',1,'kUpperStr(): IRtext.cpp'],['../IRtext_8h.html#a5aea60591627481d90688f655b2eb82a',1,'kUpperStr(): IRtext.cpp']]], + ['kupstr_6769',['kUpStr',['../IRtext_8cpp.html#ab970b3d5239f08f21a8e5e2eae49739f',1,'kUpStr(): IRtext.cpp'],['../IRtext_8h.html#a8672abbd2a279c032f0435ed75143b1a',1,'kUpStr(): IRtext.cpp']]], + ['kusedeftol_6770',['kUseDefTol',['../IRrecv_8h.html#a05025e8bd724ae2d0c7fea6e924ca84c',1,'IRrecv.h']]], + ['kvestelacauto_6771',['kVestelAcAuto',['../ir__Vestel_8h.html#a157e879cbe3b216075e3b7b2db5fdc3c',1,'ir_Vestel.h']]], + ['kvestelacbitmark_6772',['kVestelAcBitMark',['../ir__Vestel_8h.html#a70d7198002c61529956625986aa533f0',1,'ir_Vestel.h']]], + ['kvestelacbits_6773',['kVestelAcBits',['../IRremoteESP8266_8h.html#ae31945a1ce90b2d4c33b5c91d980d3a7',1,'IRremoteESP8266.h']]], + ['kvestelacchecksumoffset_6774',['kVestelAcChecksumOffset',['../ir__Vestel_8h.html#ac3fa10d1dba540a82b77cc88b01f9a7e',1,'ir_Vestel.h']]], + ['kvestelacchecksumsize_6775',['kVestelAcChecksumSize',['../ir__Vestel_8h.html#a61979a3b944ce7309c5b3f5b24b0a14c',1,'ir_Vestel.h']]], + ['kvestelaccool_6776',['kVestelAcCool',['../ir__Vestel_8h.html#aa2ec681dd63a976a6b2b182ae590e020',1,'ir_Vestel.h']]], + ['kvestelacdry_6777',['kVestelAcDry',['../ir__Vestel_8h.html#a21a255842a75a932a3a0735851d9c197',1,'ir_Vestel.h']]], + ['kvestelacfan_6778',['kVestelAcFan',['../ir__Vestel_8h.html#aeabf5404a3f66fd1428b6e4c09f24c08',1,'ir_Vestel.h']]], + ['kvestelacfanauto_6779',['kVestelAcFanAuto',['../ir__Vestel_8h.html#ac2f3175c25844414de2c2489595dd851',1,'ir_Vestel.h']]], + ['kvestelacfanautocool_6780',['kVestelAcFanAutoCool',['../ir__Vestel_8h.html#ab40dc2ebe05c77e701e2d5acf16b2658',1,'ir_Vestel.h']]], + ['kvestelacfanautohot_6781',['kVestelAcFanAutoHot',['../ir__Vestel_8h.html#a95dee8baacedb7aa62edbdecf766cdc1',1,'ir_Vestel.h']]], + ['kvestelacfanhigh_6782',['kVestelAcFanHigh',['../ir__Vestel_8h.html#acae63d91ee2a2b448fe1a68b2472e4a3',1,'ir_Vestel.h']]], + ['kvestelacfanlow_6783',['kVestelAcFanLow',['../ir__Vestel_8h.html#a21ce5e539ecb764be8dbad33914f4b87',1,'ir_Vestel.h']]], + ['kvestelacfanmed_6784',['kVestelAcFanMed',['../ir__Vestel_8h.html#a265fa70e0e38caefb45ed007eb25a430',1,'ir_Vestel.h']]], + ['kvestelacfanoffset_6785',['kVestelAcFanOffset',['../ir__Vestel_8h.html#af0f1c1989322f256b7b1b5dba613feba',1,'ir_Vestel.h']]], + ['kvestelacfansize_6786',['kVestelAcFanSize',['../ir__Vestel_8h.html#ae61e23edfb71206e736497ab479c08ad',1,'ir_Vestel.h']]], + ['kvestelachdrmark_6787',['kVestelAcHdrMark',['../ir__Vestel_8h.html#a32871ab992bfee13918a50f04508a95a',1,'ir_Vestel.h']]], + ['kvestelachdrspace_6788',['kVestelAcHdrSpace',['../ir__Vestel_8h.html#a2389409048e409b411ea8416829c06ef',1,'ir_Vestel.h']]], + ['kvestelacheat_6789',['kVestelAcHeat',['../ir__Vestel_8h.html#a33d36614992862c41f5e48548b0a45f1',1,'ir_Vestel.h']]], + ['kvestelachouroffset_6790',['kVestelAcHourOffset',['../ir__Vestel_8h.html#af4c3729a4b9df092e01d74109f539cca',1,'ir_Vestel.h']]], + ['kvestelachoursize_6791',['kVestelAcHourSize',['../ir__Vestel_8h.html#a2c0fd442d92620ca062637d01258bacf',1,'ir_Vestel.h']]], + ['kvestelacion_6792',['kVestelAcIon',['../ir__Vestel_8h.html#a6a661c914fd67e261e2148d797789339',1,'ir_Vestel.h']]], + ['kvestelacionoffset_6793',['kVestelAcIonOffset',['../ir__Vestel_8h.html#a9b1cd19c4b0037714f1c47ba031edd0b',1,'ir_Vestel.h']]], + ['kvestelacmaxtemp_6794',['kVestelAcMaxTemp',['../ir__Vestel_8h.html#a4e49902b2e4fe049fd5969b4532cc7b4',1,'ir_Vestel.h']]], + ['kvestelacmintempc_6795',['kVestelAcMinTempC',['../ir__Vestel_8h.html#ae597f05d0886a5a2aa8c43db187a657b',1,'ir_Vestel.h']]], + ['kvestelacmintemph_6796',['kVestelAcMinTempH',['../ir__Vestel_8h.html#a06977d297c84adac7927c80c7b0e7297',1,'ir_Vestel.h']]], + ['kvestelacminuteoffset_6797',['kVestelAcMinuteOffset',['../ir__Vestel_8h.html#a7c5f318a30e86394af19265e73b68034',1,'ir_Vestel.h']]], + ['kvestelacminutesize_6798',['kVestelAcMinuteSize',['../ir__Vestel_8h.html#a8abd51cd0d0404ae8bb139690bf55eb0',1,'ir_Vestel.h']]], + ['kvestelacmodeoffset_6799',['kVestelAcModeOffset',['../ir__Vestel_8h.html#a5334689cb0fbeaee67133f1f86bdce58',1,'ir_Vestel.h']]], + ['kvestelacnormal_6800',['kVestelAcNormal',['../ir__Vestel_8h.html#afa4c0fafcc806cd22dfb45475631d754',1,'ir_Vestel.h']]], + ['kvestelacofftimeoffset_6801',['kVestelAcOffTimeOffset',['../ir__Vestel_8h.html#a64ce11367a28d6481801ac3ac641df4b',1,'ir_Vestel.h']]], + ['kvestelacofftimerflagoffset_6802',['kVestelAcOffTimerFlagOffset',['../ir__Vestel_8h.html#ab36bed197f2c2b65599667b4cdf8225b',1,'ir_Vestel.h']]], + ['kvestelaconespace_6803',['kVestelAcOneSpace',['../ir__Vestel_8h.html#a507a849ef5e031f40ecc0e5db6ac8dd6',1,'ir_Vestel.h']]], + ['kvestelacontimeoffset_6804',['kVestelAcOnTimeOffset',['../ir__Vestel_8h.html#a51e257abca02cb1c97de4a5418fb7e61',1,'ir_Vestel.h']]], + ['kvestelacontimerflagoffset_6805',['kVestelAcOnTimerFlagOffset',['../ir__Vestel_8h.html#a8aa66163683538129fbdaf21746a9144',1,'ir_Vestel.h']]], + ['kvestelacpoweroffset_6806',['kVestelAcPowerOffset',['../ir__Vestel_8h.html#ab1c5709fa37fc711929688bd72c300be',1,'ir_Vestel.h']]], + ['kvestelacpowersize_6807',['kVestelAcPowerSize',['../ir__Vestel_8h.html#a884236b7213902c5e7d79327effc8f97',1,'ir_Vestel.h']]], + ['kvestelacsleep_6808',['kVestelAcSleep',['../ir__Vestel_8h.html#abc4701f0a44ed48a139d192f86a7169b',1,'ir_Vestel.h']]], + ['kvestelacstatedefault_6809',['kVestelAcStateDefault',['../ir__Vestel_8h.html#a4207797ae1043280ec6364de5981a791',1,'ir_Vestel.h']]], + ['kvestelacswing_6810',['kVestelAcSwing',['../ir__Vestel_8h.html#aeb764aa28cb134348e64fde5cb4d40f0',1,'ir_Vestel.h']]], + ['kvestelacswingoffset_6811',['kVestelAcSwingOffset',['../ir__Vestel_8h.html#ad3249b7c42070013c7c81d3feb0b1a43',1,'ir_Vestel.h']]], + ['kvestelactempoffset_6812',['kVestelAcTempOffset',['../ir__Vestel_8h.html#a9cf24276d722ee54a17c8beaf2b415cd',1,'ir_Vestel.h']]], + ['kvestelactimerflagoffset_6813',['kVestelAcTimerFlagOffset',['../ir__Vestel_8h.html#a0e53cb471d133b13cfa8fd3204d70776',1,'ir_Vestel.h']]], + ['kvestelactimerhoursize_6814',['kVestelAcTimerHourSize',['../ir__Vestel_8h.html#ad52ad7c6b1efb7eee74a276dbca330e3',1,'ir_Vestel.h']]], + ['kvestelactimerminssize_6815',['kVestelAcTimerMinsSize',['../ir__Vestel_8h.html#a7696fac000df0fd5136b7cbd96393b9e',1,'ir_Vestel.h']]], + ['kvestelactimersize_6816',['kVestelAcTimerSize',['../ir__Vestel_8h.html#a43f134a4db94790c671380be29fb8e2c',1,'ir_Vestel.h']]], + ['kvestelactimestatedefault_6817',['kVestelAcTimeStateDefault',['../ir__Vestel_8h.html#aaf4d9b6a41269ede2101d45cc1549794',1,'ir_Vestel.h']]], + ['kvestelactolerance_6818',['kVestelAcTolerance',['../ir__Vestel_8h.html#a4abe236ac8a801aa03ab843c3e418711',1,'ir_Vestel.h']]], + ['kvestelacturbo_6819',['kVestelAcTurbo',['../ir__Vestel_8h.html#a85b8b744f201b1666f9608f693a61059',1,'ir_Vestel.h']]], + ['kvestelacturbosleepoffset_6820',['kVestelAcTurboSleepOffset',['../ir__Vestel_8h.html#a97c21dc060558aa4f543f2d05385f674',1,'ir_Vestel.h']]], + ['kvestelaczerospace_6821',['kVestelAcZeroSpace',['../ir__Vestel_8h.html#a2094b0ff279fb1696b51e57d657efd13',1,'ir_Vestel.h']]], + ['kwallstr_6822',['kWallStr',['../IRtext_8cpp.html#a860a71561b888c82318daad9f2c34592',1,'kWallStr(): IRtext.cpp'],['../IRtext_8h.html#add1af6d900b500ca7affff3c9ff02d29',1,'kWallStr(): IRtext.cpp']]], + ['kweeklytimerstr_6823',['kWeeklyTimerStr',['../IRtext_8cpp.html#aaf0b7bf26b4710a4c032cec9e55c545a',1,'kWeeklyTimerStr(): IRtext.cpp'],['../IRtext_8h.html#ab59fa6f63401196c0ff32aba6da9d9aa',1,'kWeeklyTimerStr(): IRtext.cpp']]], + ['kwhirlpoolacalttempoffset_6824',['kWhirlpoolAcAltTempOffset',['../ir__Whirlpool_8h.html#a5cdc8be18d6489572d7c16dbbcc0c838',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacalttemppos_6825',['kWhirlpoolAcAltTempPos',['../ir__Whirlpool_8h.html#a019206ce06ef164cc3abb586183d0789',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacauto_6826',['kWhirlpoolAcAuto',['../ir__Whirlpool_8h.html#a2f3cc5447f8042e9c2eae0c2e0dc1b80',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacautotemp_6827',['kWhirlpoolAcAutoTemp',['../ir__Whirlpool_8h.html#a314b66dc86a7f622d73d3973d9dca86d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacbitmark_6828',['kWhirlpoolAcBitMark',['../ir__Whirlpool_8cpp.html#a5c076ca2e18927f8b0594cb74a7de1ff',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacbits_6829',['kWhirlpoolAcBits',['../IRremoteESP8266_8h.html#a149bd4f3fb9c83e683095d393209ede3',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacchecksumbyte1_6830',['kWhirlpoolAcChecksumByte1',['../ir__Whirlpool_8h.html#ab199c13354730c715debbeed63182cbd',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacchecksumbyte2_6831',['kWhirlpoolAcChecksumByte2',['../ir__Whirlpool_8h.html#a37d1a2fd814ccf83062325225bddb9be',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacclockpos_6832',['kWhirlpoolAcClockPos',['../ir__Whirlpool_8h.html#ad624453fc485adaaa156bfde374208a4',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommand6thsense_6833',['kWhirlpoolAcCommand6thSense',['../ir__Whirlpool_8h.html#a48b1309aab30dd871ce047881680efa2',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandfanspeed_6834',['kWhirlpoolAcCommandFanSpeed',['../ir__Whirlpool_8h.html#a4712f7dd6c5631f6aa692eeb99fa3963',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandifeel_6835',['kWhirlpoolAcCommandIFeel',['../ir__Whirlpool_8h.html#a5cb95c379d033d7f5b0c81755f1d376f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandlight_6836',['kWhirlpoolAcCommandLight',['../ir__Whirlpool_8h.html#af6ae6f50d9dbfa610b7033181e4f7eb1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandmode_6837',['kWhirlpoolAcCommandMode',['../ir__Whirlpool_8h.html#ab03770a941b7277a66fe65003497e183',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandofftimer_6838',['kWhirlpoolAcCommandOffTimer',['../ir__Whirlpool_8h.html#a072883e3780aa0970183ab330db26118',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandontimer_6839',['kWhirlpoolAcCommandOnTimer',['../ir__Whirlpool_8h.html#a54cbadf2ded73e66d6d12b6622249bdc',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandpos_6840',['kWhirlpoolAcCommandPos',['../ir__Whirlpool_8h.html#a1a3bc2210991ccfd418a5137dc7e0aa8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandpower_6841',['kWhirlpoolAcCommandPower',['../ir__Whirlpool_8h.html#ac215c2827ebfe25a896d53e576b643d1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandsleep_6842',['kWhirlpoolAcCommandSleep',['../ir__Whirlpool_8h.html#a695c9d69953ad2663512ede38e619b09',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandsuper_6843',['kWhirlpoolAcCommandSuper',['../ir__Whirlpool_8h.html#a4da2162e70a7257c5f4149e8556816d4',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandswing_6844',['kWhirlpoolAcCommandSwing',['../ir__Whirlpool_8h.html#a320e57c0727a74f049883c77233647a9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandtemp_6845',['kWhirlpoolAcCommandTemp',['../ir__Whirlpool_8h.html#a6e567d58af9bc3fb246e3d47a09fb065',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccool_6846',['kWhirlpoolAcCool',['../ir__Whirlpool_8h.html#a9574c0a604ffee1df43222344f649db8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacdefaultrepeat_6847',['kWhirlpoolAcDefaultRepeat',['../IRremoteESP8266_8h.html#a3b41358898f69d96bdeece17ead13ee0',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacdry_6848',['kWhirlpoolAcDry',['../ir__Whirlpool_8h.html#ab7433a4e3e8ad7ee665ab234df43e45f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfan_6849',['kWhirlpoolAcFan',['../ir__Whirlpool_8h.html#a91ecddbde81174268fdde3679565daeb',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanauto_6850',['kWhirlpoolAcFanAuto',['../ir__Whirlpool_8h.html#a133a436db244935a812beba78a1a9d05',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanhigh_6851',['kWhirlpoolAcFanHigh',['../ir__Whirlpool_8h.html#a93affe2700e13830ff09ee16801be56d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanlow_6852',['kWhirlpoolAcFanLow',['../ir__Whirlpool_8h.html#abdbd00636661a234d9e30521144d76e1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanmedium_6853',['kWhirlpoolAcFanMedium',['../ir__Whirlpool_8h.html#acf1ae9526d2fd3f49d484608730f607d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanoffset_6854',['kWhirlpoolAcFanOffset',['../ir__Whirlpool_8h.html#a2cbca4b466aab8816efa70d1653bc895',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanpos_6855',['kWhirlpoolAcFanPos',['../ir__Whirlpool_8h.html#a02d5f4fe0837c9f9738cfb46f83c2ed9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfansize_6856',['kWhirlpoolAcFanSize',['../ir__Whirlpool_8h.html#ae26fab46c0f06c04f4d51b61e623873c',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacgap_6857',['kWhirlpoolAcGap',['../ir__Whirlpool_8cpp.html#a5946b0c81f68442645f795f4f6518972',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolachdrmark_6858',['kWhirlpoolAcHdrMark',['../ir__Whirlpool_8cpp.html#ad2f759eb7426cfe5fb3421f101c926bb',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolachdrspace_6859',['kWhirlpoolAcHdrSpace',['../ir__Whirlpool_8cpp.html#a7a83a305cc6ebb7be7163bd1c3fb679d',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacheat_6860',['kWhirlpoolAcHeat',['../ir__Whirlpool_8h.html#a1e9290ec94cca537b5c44d2e4326b59c',1,'ir_Whirlpool.h']]], + ['kwhirlpoolachouroffset_6861',['kWhirlpoolAcHourOffset',['../ir__Whirlpool_8h.html#a8940e79b0e5b9f4bcf2a3e518cc59432',1,'ir_Whirlpool.h']]], + ['kwhirlpoolachoursize_6862',['kWhirlpoolAcHourSize',['../ir__Whirlpool_8h.html#ac50066e7e496cb7af6ecdb21cee7f2c9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaclightoffset_6863',['kWhirlpoolAcLightOffset',['../ir__Whirlpool_8h.html#a5a5fbcfa7f383fb72f96c414adea8966',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmaxtemp_6864',['kWhirlpoolAcMaxTemp',['../ir__Whirlpool_8h.html#a08171b333f214963e21a0c574783299f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmingap_6865',['kWhirlpoolAcMinGap',['../ir__Whirlpool_8cpp.html#aa6e5e114daf18d77914a08f831c37c7d',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacmintemp_6866',['kWhirlpoolAcMinTemp',['../ir__Whirlpool_8h.html#aeffef97e3247609d5731b525692f1e7b',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacminuteoffset_6867',['kWhirlpoolAcMinuteOffset',['../ir__Whirlpool_8h.html#ae22595d5d1ffdc4c6b02080cd38d14d7',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacminutesize_6868',['kWhirlpoolAcMinuteSize',['../ir__Whirlpool_8h.html#a3a5cecc4480a1cb3da19f246902ab1d9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmodeoffset_6869',['kWhirlpoolAcModeOffset',['../ir__Whirlpool_8h.html#a662d0ab4b5f2b40bc2427e2b8d18351e',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmodepos_6870',['kWhirlpoolAcModePos',['../ir__Whirlpool_8h.html#a6a7e8449c00a260c1ef740ebc4a08d50',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacofftimerpos_6871',['kWhirlpoolAcOffTimerPos',['../ir__Whirlpool_8h.html#a48a18046ded6bae11cd87d41d615d05f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaconespace_6872',['kWhirlpoolAcOneSpace',['../ir__Whirlpool_8cpp.html#a7680ed11a0bc6b2f9340e3557681a470',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacontimerpos_6873',['kWhirlpoolAcOnTimerPos',['../ir__Whirlpool_8h.html#ad10d9924f4d57547f7dc8ea085e1666f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacpowertoggleoffset_6874',['kWhirlpoolAcPowerToggleOffset',['../ir__Whirlpool_8h.html#a1db76f65f3f10e73a0fdee65850934a2',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacpowertogglepos_6875',['kWhirlpoolAcPowerTogglePos',['../ir__Whirlpool_8h.html#a353f4f6101a152fdcfe7f13b8f8764d8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsections_6876',['kWhirlpoolAcSections',['../ir__Whirlpool_8cpp.html#a75ebed07d288ac32a0138035279b41c7',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacsleepoffset_6877',['kWhirlpoolAcSleepOffset',['../ir__Whirlpool_8h.html#a83961870cfae146cbb519560ff609fc3',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsleeppos_6878',['kWhirlpoolAcSleepPos',['../ir__Whirlpool_8h.html#a739f14122bce3a130d441bb0a47b4666',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacstatelength_6879',['kWhirlpoolAcStateLength',['../IRremoteESP8266_8h.html#a0fff60a43f776fb999d0f1f91d88154f',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacsupermask_6880',['kWhirlpoolAcSuperMask',['../ir__Whirlpool_8h.html#a1946501e50abd9e1c0a3e07007a98c24',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsuperpos_6881',['kWhirlpoolAcSuperPos',['../ir__Whirlpool_8h.html#a68e051a102449fc6712f709b166a99b9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacswing1offset_6882',['kWhirlpoolAcSwing1Offset',['../ir__Whirlpool_8h.html#adeba9b215f8044e64df2bf805eecaa3b',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacswing2offset_6883',['kWhirlpoolAcSwing2Offset',['../ir__Whirlpool_8h.html#a3290f0b70f3eafdd885d4a08c6d5d5a3',1,'ir_Whirlpool.h']]], + ['kwhirlpoolactemppos_6884',['kWhirlpoolAcTempPos',['../ir__Whirlpool_8h.html#a15a3ef7abed2fca2881d4f5ccc969522',1,'ir_Whirlpool.h']]], + ['kwhirlpoolactimerenableoffset_6885',['kWhirlpoolAcTimerEnableOffset',['../ir__Whirlpool_8h.html#ab4694ec5e153e41f6cf56920e2291970',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaczerospace_6886',['kWhirlpoolAcZeroSpace',['../ir__Whirlpool_8cpp.html#af03c9ee4d432bbce7d2ee214dd5ca095',1,'ir_Whirlpool.cpp']]], + ['kwhynterbitmark_6887',['kWhynterBitMark',['../ir__Whynter_8cpp.html#a032043e058989b6402d8af99d2c20552',1,'ir_Whynter.cpp']]], + ['kwhynterbitmarkticks_6888',['kWhynterBitMarkTicks',['../ir__Whynter_8cpp.html#acfd8f04e0453ec1b9cd85837053a47e2',1,'ir_Whynter.cpp']]], + ['kwhynterbits_6889',['kWhynterBits',['../IRremoteESP8266_8h.html#a4553f6670e241a67104d45216a4ebd98',1,'IRremoteESP8266.h']]], + ['kwhynterhdrmark_6890',['kWhynterHdrMark',['../ir__Whynter_8cpp.html#a7d62b0e658fe6f697d41d6932e4e6662',1,'ir_Whynter.cpp']]], + ['kwhynterhdrmarkticks_6891',['kWhynterHdrMarkTicks',['../ir__Whynter_8cpp.html#a34da808cebff09fc038589c035f2d2fe',1,'ir_Whynter.cpp']]], + ['kwhynterhdrspace_6892',['kWhynterHdrSpace',['../ir__Whynter_8cpp.html#ad20c874e642238e299a44ead2ea592f1',1,'ir_Whynter.cpp']]], + ['kwhynterhdrspaceticks_6893',['kWhynterHdrSpaceTicks',['../ir__Whynter_8cpp.html#a8090f73380ea212e904402555156364d',1,'ir_Whynter.cpp']]], + ['kwhyntermincommandlength_6894',['kWhynterMinCommandLength',['../ir__Whynter_8cpp.html#a5e584a8d6aa8a146c9c8e74839b28e8f',1,'ir_Whynter.cpp']]], + ['kwhyntermincommandlengthticks_6895',['kWhynterMinCommandLengthTicks',['../ir__Whynter_8cpp.html#a65e8195824053403967573b7603059e7',1,'ir_Whynter.cpp']]], + ['kwhyntermingap_6896',['kWhynterMinGap',['../ir__Whynter_8cpp.html#ad09957f4c9c76d76ab55a74f440dad5f',1,'ir_Whynter.cpp']]], + ['kwhyntermingapticks_6897',['kWhynterMinGapTicks',['../ir__Whynter_8cpp.html#a89af5f0ab7af456f58052bf9256620a2',1,'ir_Whynter.cpp']]], + ['kwhynteronespace_6898',['kWhynterOneSpace',['../ir__Whynter_8cpp.html#a78993c22d94b107a37f61cddad728003',1,'ir_Whynter.cpp']]], + ['kwhynteronespaceticks_6899',['kWhynterOneSpaceTicks',['../ir__Whynter_8cpp.html#a95a5903a8f057df2b6587a331fec6f18',1,'ir_Whynter.cpp']]], + ['kwhyntertick_6900',['kWhynterTick',['../ir__Whynter_8cpp.html#a8f704cdf6cfd11455101919d7a772389',1,'ir_Whynter.cpp']]], + ['kwhynterzerospace_6901',['kWhynterZeroSpace',['../ir__Whynter_8cpp.html#a426deb9a35a1a6afdcbcfa58c6943490',1,'ir_Whynter.cpp']]], + ['kwhynterzerospaceticks_6902',['kWhynterZeroSpaceTicks',['../ir__Whynter_8cpp.html#ae38da416cd065b561287ebd2fe0257f0',1,'ir_Whynter.cpp']]], + ['kwidestr_6903',['kWideStr',['../IRtext_8cpp.html#a19875c78e68ba6fdd78df3526f82969c',1,'kWideStr(): IRtext.cpp'],['../IRtext_8h.html#a6fe3dbd6899e85e79e517f71cc74a87b',1,'kWideStr(): IRtext.cpp']]], + ['kwifistr_6904',['kWifiStr',['../IRtext_8cpp.html#a3f2dddbcbc03e31ed6f1081fce001ea4',1,'kWifiStr(): IRtext.cpp'],['../IRtext_8h.html#a8bc9343f209803dbab3e765e39b41b4d',1,'kWifiStr(): IRtext.cpp']]], + ['kxfanstr_6905',['kXFanStr',['../IRtext_8cpp.html#ada36ab4b7555d38a76c4477971736cb7',1,'kXFanStr(): IRtext.cpp'],['../IRtext_8h.html#a7ddc859861308f2f9077abcec2a4b571',1,'kXFanStr(): IRtext.cpp']]], + ['kyesstr_6906',['kYesStr',['../IRtext_8cpp.html#a96492aa94d18702db41a639ae2a45423',1,'kYesStr(): IRtext.cpp'],['../IRtext_8h.html#a95ca78b5cc3caa31c564a28480379fae',1,'kYesStr(): IRtext.cpp']]], + ['kzepealbits_6907',['kZepealBits',['../IRremoteESP8266_8h.html#af09c9402a1c4fa24f692994498641296',1,'IRremoteESP8266.h']]], + ['kzepealcommandoffon_6908',['kZepealCommandOffOn',['../ir__Zepeal_8cpp.html#a37af9800da3144c218d422e54066e837',1,'ir_Zepeal.cpp']]], + ['kzepealcommandofftimer_6909',['kZepealCommandOffTimer',['../ir__Zepeal_8cpp.html#a87b136a95af4437182530d6f7cbc69ee',1,'ir_Zepeal.cpp']]], + ['kzepealcommandontimer_6910',['kZepealCommandOnTimer',['../ir__Zepeal_8cpp.html#aed4491019bb6575c113404a095e8b116',1,'ir_Zepeal.cpp']]], + ['kzepealcommandrhythm_6911',['kZepealCommandRhythm',['../ir__Zepeal_8cpp.html#aa3960b3bdaa77c060543881bdf71e46c',1,'ir_Zepeal.cpp']]], + ['kzepealcommandspeed_6912',['kZepealCommandSpeed',['../ir__Zepeal_8cpp.html#a1189a81901daaf4b8b45e8f45caf0f49',1,'ir_Zepeal.cpp']]], + ['kzepealfootermark_6913',['kZepealFooterMark',['../ir__Zepeal_8cpp.html#a83167e93978d9cec8cf2dfac980582ba',1,'ir_Zepeal.cpp']]], + ['kzepealgap_6914',['kZepealGap',['../ir__Zepeal_8cpp.html#ab5bea0fe08e14fa3d1812bea018f44f0',1,'ir_Zepeal.cpp']]], + ['kzepealhdrmark_6915',['kZepealHdrMark',['../ir__Zepeal_8cpp.html#abee2a1537cfff9481d3060fba94a4b04',1,'ir_Zepeal.cpp']]], + ['kzepealhdrspace_6916',['kZepealHdrSpace',['../ir__Zepeal_8cpp.html#ad49be13d3dd108a18e4e641a40ff0408',1,'ir_Zepeal.cpp']]], + ['kzepealminrepeat_6917',['kZepealMinRepeat',['../IRremoteESP8266_8h.html#afb5c734e808d8f108f976f0556bf6e58',1,'IRremoteESP8266.h']]], + ['kzepealonemark_6918',['kZepealOneMark',['../ir__Zepeal_8cpp.html#a4d9919883561086dd3e3060e93983480',1,'ir_Zepeal.cpp']]], + ['kzepealonespace_6919',['kZepealOneSpace',['../ir__Zepeal_8cpp.html#a88702dbff33a9dddcfd4b255637460a0',1,'ir_Zepeal.cpp']]], + ['kzepealsignature_6920',['kZepealSignature',['../ir__Zepeal_8cpp.html#a7994e564096ac01b77d9ebe3a753167d',1,'ir_Zepeal.cpp']]], + ['kzepealtolerance_6921',['kZepealTolerance',['../ir__Zepeal_8cpp.html#ab35f666ef98b24b8b4bacdf462a9fbe6',1,'ir_Zepeal.cpp']]], + ['kzepealzeromark_6922',['kZepealZeroMark',['../ir__Zepeal_8cpp.html#a94eac58ef78ea4e39687f54e381c3a00',1,'ir_Zepeal.cpp']]], + ['kzepealzerospace_6923',['kZepealZeroSpace',['../ir__Zepeal_8cpp.html#a1af802b587e8f0a88ae87ab964fde690',1,'ir_Zepeal.cpp']]], + ['kzonefollowstr_6924',['kZoneFollowStr',['../IRtext_8cpp.html#a9a112fb47e39e35d096fe09266d37db1',1,'kZoneFollowStr(): IRtext.cpp'],['../IRtext_8h.html#a100dc6d7c4d53bffa00a24a582ace80f',1,'kZoneFollowStr(): IRtext.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.html new file mode 100644 index 000000000..1f6505537 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.js new file mode 100644 index 000000000..20f9d2d12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['ledflag_6925',['ledFlag',['../classIRCoolixAC.html#a03ba5e0a6cb47a7bb054155c2111a69c',1,'IRCoolixAC']]], + ['light_6926',['light',['../structstdAc_1_1state__t.html#a51c3a5c4703ea49b420d70aeb18b6b9b',1,'stdAc::state_t']]], + ['llword_6927',['llword',['../unionmagiquest.html#ad57fbc75ab289c3e93b94be0b2187d65',1,'magiquest']]], + ['lword_6928',['lword',['../unionmagiquest.html#ac87102145311831a232002b52fe2d02c',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.html new file mode 100644 index 000000000..c02d066f5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.js new file mode 100644 index 000000000..161ca5933 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['magnitude_6929',['magnitude',['../unionmagiquest.html#a8f687419a00322a04aab223dec093d6e',1,'magiquest']]], + ['mode_6930',['mode',['../structstdAc_1_1state__t.html#ae5e4b17fac2ea36300f796670337d7a7',1,'stdAc::state_t']]], + ['mode_5fstate_6931',['mode_state',['../classIRToshibaAC.html#a5bb8b6cef598bb8273369b3fa7ade1b0',1,'IRToshibaAC']]], + ['model_6932',['model',['../structstdAc_1_1state__t.html#aa1a57a63b2ea80c1f9c4a1bcf16a4c62',1,'stdAc::state_t']]], + ['modulation_6933',['modulation',['../classIRsend.html#a11e26c03c87e2bed756eb7f318570bd8',1,'IRsend']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.html new file mode 100644 index 000000000..4b866c6ce --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.js new file mode 100644 index 000000000..051529e01 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['next_6934',['next',['../classIRac.html#ae85d7ac0c58028b2547518f88d3e98fe',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.html new file mode 100644 index 000000000..84d878b81 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.js new file mode 100644 index 000000000..9f444e314 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['offtimeperiod_6935',['offTimePeriod',['../classIRsend.html#a9e45c9e4f54db86c1f3e506cd72fe4c1',1,'IRsend']]], + ['ontimeperiod_6936',['onTimePeriod',['../classIRsend.html#aaaa65f31dbea033f8130e847b0366d94',1,'IRsend']]], + ['outputoff_6937',['outputOff',['../classIRsend.html#a5e80df8b2ee534dbd6ddc30a852a2791',1,'IRsend']]], + ['outputon_6938',['outputOn',['../classIRsend.html#a4acfc45b339e724e2dbdff24762dfa7d',1,'IRsend']]], + ['overflow_6939',['overflow',['../structirparams__t.html#aa39b4f38e0ffcd470766373e03548e58',1,'irparams_t::overflow()'],['../classdecode__results.html#a821bc53c006bab3283c6b8592f0c43d3',1,'decode_results::overflow()']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.html new file mode 100644 index 000000000..b0d9b7b20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.js new file mode 100644 index 000000000..d2027848f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['padding_6940',['padding',['../unionmagiquest.html#a28ca4be56c78ef762f87171506dc6e93',1,'magiquest']]], + ['periodoffset_6941',['periodOffset',['../classIRsend.html#a1b5180cbf4f88f19fca3f677e1e91b96',1,'IRsend']]], + ['power_6942',['power',['../structstdAc_1_1state__t.html#ab85d37cc99bbbc4915331369c4ea622e',1,'stdAc::state_t']]], + ['powerflag_6943',['powerFlag',['../classIRCoolixAC.html#a5984ff64ff14df92291618a647da08f9',1,'IRCoolixAC']]], + ['protocol_6944',['protocol',['../structstdAc_1_1state__t.html#af59897778be0e571f77dd11337352c27',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.html new file mode 100644 index 000000000..a708dbf04 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.js new file mode 100644 index 000000000..7f57cab0a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['quiet_6945',['quiet',['../structstdAc_1_1state__t.html#a251ad14e187a9905137e9e4e010c3e34',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/splitbar.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/splitbar.png new file mode 100644 index 0000000000000000000000000000000000000000..fe895f2c58179b471a22d8320b39a4bd7312ec8e GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t-members.html new file mode 100644 index 000000000..0c526f445 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t-members.html @@ -0,0 +1,87 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    +
    +
    irparams_t Member List
    +
    +
    + +

    This is the complete list of members for irparams_t, including all inherited members.

    + + + + + + + + + +
    bufsizeirparams_t
    overflowirparams_t
    rawbufirparams_t
    rawlenirparams_t
    rcvstateirparams_t
    recvpinirparams_t
    timeoutirparams_t
    timerirparams_t
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t.html new file mode 100644 index 000000000..74d3bcddf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t.html @@ -0,0 +1,222 @@ + + + + + + + +IRremoteESP8266: irparams_t Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    irparams_t Struct Reference
    +
    +
    + +

    Information for the interrupt handler. + More...

    + +

    #include <IRrecv.h>

    + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    uint8_t recvpin
     
    uint8_t rcvstate
     
    uint16_t timer
     
    uint16_t bufsize
     
    uint16_t * rawbuf
     
    uint16_t rawlen
     
    uint8_t overflow
     
    uint8_t timeout
     
    +

    Detailed Description

    +

    Information for the interrupt handler.

    +

    Member Data Documentation

    + +

    ◆ bufsize

    + +
    +
    + + + + +
    uint16_t irparams_t::bufsize
    +
    + +
    +
    + +

    ◆ overflow

    + +
    +
    + + + + +
    uint8_t irparams_t::overflow
    +
    + +
    +
    + +

    ◆ rawbuf

    + +
    +
    + + + + +
    uint16_t* irparams_t::rawbuf
    +
    + +
    +
    + +

    ◆ rawlen

    + +
    +
    + + + + +
    uint16_t irparams_t::rawlen
    +
    + +
    +
    + +

    ◆ rcvstate

    + +
    +
    + + + + +
    uint8_t irparams_t::rcvstate
    +
    + +
    +
    + +

    ◆ recvpin

    + +
    +
    + + + + +
    uint8_t irparams_t::recvpin
    +
    + +
    +
    + +

    ◆ timeout

    + +
    +
    + + + + +
    uint8_t irparams_t::timeout
    +
    + +
    +
    + +

    ◆ timer

    + +
    +
    + + + + +
    uint16_t irparams_t::timer
    +
    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t-members.html new file mode 100644 index 000000000..4a624fb26 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t-members.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    +
    +
    match_result_t Member List
    +
    +
    + +

    This is the complete list of members for match_result_t, including all inherited members.

    + + + + +
    datamatch_result_t
    successmatch_result_t
    usedmatch_result_t
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t.html new file mode 100644 index 000000000..db08c0b2f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t.html @@ -0,0 +1,142 @@ + + + + + + + +IRremoteESP8266: match_result_t Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    match_result_t Struct Reference
    +
    +
    + +

    Results from a data match. + More...

    + +

    #include <IRrecv.h>

    + + + + + + + + +

    +Public Attributes

    bool success
     
    uint64_t data
     
    uint16_t used
     
    +

    Detailed Description

    +

    Results from a data match.

    +

    Member Data Documentation

    + +

    ◆ data

    + +
    +
    + + + + +
    uint64_t match_result_t::data
    +
    + +
    +
    + +

    ◆ success

    + +
    +
    + + + + +
    bool match_result_t::success
    +
    + +
    +
    + +

    ◆ used

    + +
    +
    + + + + +
    uint16_t match_result_t::used
    +
    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t-members.html new file mode 100644 index 000000000..00b774f43 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t-members.html @@ -0,0 +1,101 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    stdAc::state_t Member List
    +
    + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t.html new file mode 100644 index 000000000..28ece11ce --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t.html @@ -0,0 +1,386 @@ + + + + + + + +IRremoteESP8266: stdAc::state_t Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    stdAc::state_t Struct Reference
    +
    +
    + +

    Structure to hold a common A/C state. + More...

    + +

    #include <IRsend.h>

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    decode_type_t protocol
     
    int16_t model
     
    bool power
     
    stdAc::opmode_t mode
     
    float degrees
     
    bool celsius
     
    stdAc::fanspeed_t fanspeed
     
    stdAc::swingv_t swingv
     
    stdAc::swingh_t swingh
     
    bool quiet
     
    bool turbo
     
    bool econo
     
    bool light
     
    bool filter
     
    bool clean
     
    bool beep
     
    int16_t sleep
     
    int16_t clock
     
    +

    Detailed Description

    +

    Structure to hold a common A/C state.

    +

    Member Data Documentation

    + +

    ◆ beep

    + +
    +
    + + + + +
    bool stdAc::state_t::beep
    +
    + +
    +
    + +

    ◆ celsius

    + +
    +
    + + + + +
    bool stdAc::state_t::celsius
    +
    + +
    +
    + +

    ◆ clean

    + +
    +
    + + + + +
    bool stdAc::state_t::clean
    +
    + +
    +
    + +

    ◆ clock

    + +
    +
    + + + + +
    int16_t stdAc::state_t::clock
    +
    + +
    +
    + +

    ◆ degrees

    + +
    +
    + + + + +
    float stdAc::state_t::degrees
    +
    + +
    +
    + +

    ◆ econo

    + +
    +
    + + + + +
    bool stdAc::state_t::econo
    +
    + +
    +
    + +

    ◆ fanspeed

    + +
    +
    + + + + +
    stdAc::fanspeed_t stdAc::state_t::fanspeed
    +
    + +
    +
    + +

    ◆ filter

    + +
    +
    + + + + +
    bool stdAc::state_t::filter
    +
    + +
    +
    + +

    ◆ light

    + +
    +
    + + + + +
    bool stdAc::state_t::light
    +
    + +
    +
    + +

    ◆ mode

    + +
    +
    + + + + +
    stdAc::opmode_t stdAc::state_t::mode
    +
    + +
    +
    + +

    ◆ model

    + +
    +
    + + + + +
    int16_t stdAc::state_t::model
    +
    + +
    +
    + +

    ◆ power

    + +
    +
    + + + + +
    bool stdAc::state_t::power
    +
    + +
    +
    + +

    ◆ protocol

    + +
    +
    + + + + +
    decode_type_t stdAc::state_t::protocol
    +
    + +
    +
    + +

    ◆ quiet

    + +
    +
    + + + + +
    bool stdAc::state_t::quiet
    +
    + +
    +
    + +

    ◆ sleep

    + +
    +
    + + + + +
    int16_t stdAc::state_t::sleep
    +
    + +
    +
    + +

    ◆ swingh

    + +
    +
    + + + + +
    stdAc::swingh_t stdAc::state_t::swingh
    +
    + +
    +
    + +

    ◆ swingv

    + +
    +
    + + + + +
    stdAc::swingv_t stdAc::state_t::swingv
    +
    + +
    +
    + +

    ◆ turbo

    + +
    +
    + + + + +
    bool stdAc::state_t::turbo
    +
    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_off.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_on.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_a.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_b.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_b.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b4a8638cb3496a016eaed9e16ffc12846dea18 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QU#tajv*C{Z}0l@H7kg?K0Lnr z!j&C6_(~HV9oQ0Pa6x{-v0AGV_E?vLn=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tabs.css b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tabs.css new file mode 100644 index 000000000..7d45d36c1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255,255,255,0.9);color:#283A5D;outline:none}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a:hover span.sub-arrow{border-color:#fff transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #fff}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/todo.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/todo.html new file mode 100644 index 000000000..8331a61db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/todo.html @@ -0,0 +1,99 @@ + + + + + + + +IRremoteESP8266: Todo List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    +
    +
    Todo List
    +
    +
    +
    +
    Member IRrecv::decodeLasertag (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLasertagBits, const bool strict=true)
    +
    Convert to using matchManchester() if we can.
    +
    Member IRrecv::decodeRC5 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC5XBits, const bool strict=true)
    +
    Serious testing of the RC-5X and strict aspects needs to be done.
    +
    Member IRrecv::decodeRC6 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC6Mode0Bits, const bool strict=false)
    +
    Testing of the strict compliance aspects.
    +
    Member IRrecv::decodeSharp (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpBits, const bool strict=true, const bool expansion=true)
    +
    Need to ensure capture of the inverted message as it can be missed due to the interrupt timeout used to detect an end of message. Several compliance checks are disabled until that is resolved.
    +
    Member IRrecv::matchManchesterData (volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t half_period, const uint16_t starting_balance=0, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
    +
    Clean up and optimise this. It is just "get it working code" atm.
    +
    Member IRSamsungAc::getSwing (void)
    +
    (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. e.g. 0xAE or 0XAF for swing move.
    +
    Member IRSamsungAc::setSwing (const bool on)
    +
    (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. e.g. 0xAE or 0XAF for swing move.
    +
    Member IRsend::sendLasertag (uint64_t data, uint16_t nbits=kLasertagBits, uint16_t repeat=kLasertagMinRepeat)
    +
    Convert this to use sendManchester() if we can.`
    +
    Member IRsend::sendRC5 (const uint64_t data, uint16_t nbits=kRC5XBits, const uint16_t repeat=kNoRepeat)
    +
    Testing of the RC-5X components.
    +
    Member IRsend::sendSAMSUNG (const uint64_t data, const uint16_t nbits=kSamsungBits, const uint16_t repeat=kNoRepeat)
    +
    Confirm that is actually how Samsung sends a repeat. The refdoc doesn't indicate it is true.
    +
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest-members.html new file mode 100644 index 000000000..0976ba9fe --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest-members.html @@ -0,0 +1,87 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    +
    +
    magiquest Member List
    +
    +
    + +

    This is the complete list of members for magiquest, including all inherited members.

    + + + + + + + + + +
    bytemagiquest
    cmdmagiquest
    llwordmagiquest
    lwordmagiquest
    magnitudemagiquest
    paddingmagiquest
    scrapmagiquest
    wand_idmagiquest
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest.html new file mode 100644 index 000000000..fb5f336ff --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest.html @@ -0,0 +1,223 @@ + + + + + + + +IRremoteESP8266: magiquest Union Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    magiquest Union Reference
    +
    +
    + +

    MagiQuest packet is both Wand ID and magnitude of swish and flick. + More...

    + +

    #include <ir_Magiquest.h>

    + + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    uint64_t llword
     
    uint8_t byte [8]
     
    uint32_t lword [2]
     
    struct {
       uint16_t   magnitude
     
       uint32_t   wand_id
     
       uint8_t   padding
     
       uint8_t   scrap
     
    cmd
     
    +

    Detailed Description

    +

    MagiQuest packet is both Wand ID and magnitude of swish and flick.

    +

    Member Data Documentation

    + +

    ◆ byte

    + +
    +
    + + + + +
    uint8_t magiquest::byte[8]
    +
    + +
    +
    + +

    ◆ cmd

    + +
    +
    + + + + +
    struct { ... } magiquest::cmd
    +
    + +
    +
    + +

    ◆ llword

    + +
    +
    + + + + +
    uint64_t magiquest::llword
    +
    + +
    +
    + +

    ◆ lword

    + +
    +
    + + + + +
    uint32_t magiquest::lword[2]
    +
    + +
    +
    + +

    ◆ magnitude

    + +
    +
    + + + + +
    uint16_t magiquest::magnitude
    +
    + +
    +
    + +

    ◆ padding

    + +
    +
    + + + + +
    uint8_t magiquest::padding
    +
    + +
    +
    + +

    ◆ scrap

    + +
    +
    + + + + +
    uint8_t magiquest::scrap
    +
    + +
    +
    + +

    ◆ wand_id

    + +
    +
    + + + + +
    uint32_t magiquest::wand_id
    +
    + +
    +
    +
    The documentation for this union was generated from the following file: +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h.html new file mode 100644 index 000000000..30e00c752 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/zh-CN.h File Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    zh-CN.h File Reference
    +
    + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h_source.html new file mode 100644 index 000000000..a5b0277da --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h_source.html @@ -0,0 +1,545 @@ + + + + + + + +IRremoteESP8266: src/locale/zh-CN.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    zh-CN.h
    +
    +
    +Go to the documentation of this file.
    1 // Copyright 2020 - MiaoYi (@Caffreyfans)
    +
    2 // Locale/language file for China / Simplified.
    +
    3 // This file will override the default values located in `defaults.h`.
    +
    4 #ifndef LOCALE_ZH_CN_H_
    +
    5 #define LOCALE_ZH_CN_H_
    +
    6 
    +
    7 #ifndef D_STR_UNKNOWN
    +
    8 #define D_STR_UNKNOWN "未知"
    +
    9 #endif // D_STR_UNKNOWN
    +
    10 #ifndef D_STR_PROTOCOL
    +
    11 #define D_STR_PROTOCOL "åè®®"
    +
    12 #endif // D_STR_PROTOCOL
    +
    13 #ifndef D_STR_POWER
    +
    14 #define D_STR_POWER "电æº"
    +
    15 #endif // D_STR_POWER
    +
    16 #ifndef D_STR_PREVIOUS
    +
    17 #define D_STR_PREVIOUS "以å‰"
    +
    18 #endif // D_STR_PREVIOUS
    +
    19 #ifndef D_STR_ON
    +
    20 #define D_STR_ON "å¼€"
    +
    21 #endif // D_STR_ON
    +
    22 #ifndef D_STR_OFF
    +
    23 #define D_STR_OFF "å…³"
    +
    24 #endif // D_STR_OFF
    +
    25 #ifndef D_STR_MODE
    +
    26 #define D_STR_MODE "模å¼"
    +
    27 #endif // D_STR_MODE
    +
    28 #ifndef D_STR_TOGGLE
    +
    29 #define D_STR_TOGGLE "切æ¢"
    +
    30 #endif // D_STR_TOGGLE
    +
    31 #ifndef D_STR_TURBO
    +
    32 #define D_STR_TURBO "强力"
    +
    33 #endif // D_STR_TURBO
    +
    34 #ifndef D_STR_SUPER
    +
    35 #define D_STR_SUPER "超级"
    +
    36 #endif // D_STR_SUPER
    +
    37 #ifndef D_STR_SLEEP
    +
    38 #define D_STR_SLEEP "ç¡çœ "
    +
    39 #endif // D_STR_SLEEP
    +
    40 #ifndef D_STR_LIGHT
    +
    41 #define D_STR_LIGHT "ç¯å…‰"
    +
    42 #endif // D_STR_LIGHT
    +
    43 #ifndef D_STR_POWERFUL
    +
    44 #define D_STR_POWERFUL "强劲模å¼"
    +
    45 #endif // D_STR_POWERFUL
    +
    46 #ifndef D_STR_QUIET
    +
    47 #define D_STR_QUIET "安é™"
    +
    48 #endif // D_STR_QUIET
    +
    49 #ifndef D_STR_ECONO
    +
    50 #define D_STR_ECONO "ç»æµŽ"
    +
    51 #endif // D_STR_ECONO
    +
    52 #ifndef D_STR_SWING
    +
    53 #define D_STR_SWING "扫风"
    +
    54 #endif // D_STR_SWING
    +
    55 #ifndef D_STR_SWINGH
    +
    56 #define D_STR_SWINGH D_STR_SWING"(H)" // Set `D_STR_SWING` first!
    +
    57 #endif // D_STR_SWINGH
    +
    58 #ifndef D_STR_SWINGV
    +
    59 #define D_STR_SWINGV D_STR_SWING"(V)" // Set `D_STR_SWING` first!
    +
    60 #endif // D_STR_SWINGV
    +
    61 #ifndef D_STR_BEEP
    +
    62 #define D_STR_BEEP "蜂鸣"
    +
    63 #endif // D_STR_BEEP
    +
    64 #ifndef D_STR_MOULD
    +
    65 #define D_STR_MOULD "模å­"
    +
    66 #endif // D_STR_MOULD
    +
    67 #ifndef D_STR_CLEAN
    +
    68 #define D_STR_CLEAN "清æ´"
    +
    69 #endif // D_STR_CLEAN
    +
    70 #ifndef D_STR_PURIFY
    +
    71 #define D_STR_PURIFY "净化"
    +
    72 #endif // D_STR_PURIFY
    +
    73 #ifndef D_STR_TIMER
    +
    74 #define D_STR_TIMER "计时器"
    +
    75 #endif // D_STR_TIMER
    +
    76 #ifndef D_STR_ONTIMER
    +
    77 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER // Set `D_STR_ON` first!
    +
    78 #endif // D_STR_ONTIMER
    +
    79 #ifndef D_STR_OFFTIMER
    +
    80 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER // Set `D_STR_OFF` first!
    +
    81 #endif // D_STR_OFFTIMER
    +
    82 #ifndef D_STR_CLOCK
    +
    83 #define D_STR_CLOCK "æ—¶é’Ÿ"
    +
    84 #endif // D_STR_CLOCK
    +
    85 #ifndef D_STR_COMMAND
    +
    86 #define D_STR_COMMAND "命令"
    +
    87 #endif // D_STR_COMMAND
    +
    88 #ifndef D_STR_XFAN
    +
    89 #define D_STR_XFAN "XFan"
    +
    90 #endif // D_STR_XFAN
    +
    91 #ifndef D_STR_HEALTH
    +
    92 #define D_STR_HEALTH "å¥åº·"
    +
    93 #endif // D_STR_HEALTH
    +
    94 #ifndef D_STR_MODEL
    +
    95 #define D_STR_MODEL "模å¼"
    +
    96 #endif // D_STR_MODEL
    +
    97 #ifndef D_STR_TEMP
    +
    98 #define D_STR_TEMP "温度"
    +
    99 #endif // D_STR_TEMP
    +
    100 #ifndef D_STR_IFEEL
    +
    101 #define D_STR_IFEEL "IFeel"
    +
    102 #endif // D_STR_IFEEL
    +
    103 #ifndef D_STR_HUMID
    +
    104 #define D_STR_HUMID "湿度"
    +
    105 #endif // D_STR_HUMID
    +
    106 #ifndef D_STR_SAVE
    +
    107 #define D_STR_SAVE "ä¿å­˜"
    +
    108 #endif // D_STR_SAVE
    +
    109 #ifndef D_STR_EYE
    +
    110 #define D_STR_EYE "眼"
    +
    111 #endif // D_STR_EYE
    +
    112 #ifndef D_STR_FOLLOW
    +
    113 #define D_STR_FOLLOW "è·Ÿéš"
    +
    114 #endif // D_STR_FOLLOW
    +
    115 #ifndef D_STR_ION
    +
    116 #define D_STR_ION "Ion"
    +
    117 #endif // D_STR_ION
    +
    118 #ifndef D_STR_FRESH
    +
    119 #define D_STR_FRESH "刷新"
    +
    120 #endif // D_STR_FRESH
    +
    121 #ifndef D_STR_HOLD
    +
    122 #define D_STR_HOLD "ä¿æŒ"
    +
    123 #endif // D_STR_HOLD
    +
    124 #ifndef D_STR_8C_HEAT
    +
    125 #define D_STR_8C_HEAT "8C " D_STR_HEAT // Set `D_STR_HEAT` first!
    +
    126 #endif // D_STR_8C_HEAT
    +
    127 #ifndef D_STR_BUTTON
    +
    128 #define D_STR_BUTTON "按钮"
    +
    129 #endif // D_STR_BUTTON
    +
    130 #ifndef D_STR_NIGHT
    +
    131 #define D_STR_NIGHT "夜间"
    +
    132 #endif // D_STR_NIGHT
    +
    133 #ifndef D_STR_SILENT
    +
    134 #define D_STR_SILENT "安é™"
    +
    135 #endif // D_STR_SILENT
    +
    136 #ifndef D_STR_FILTER
    +
    137 #define D_STR_FILTER "过滤"
    +
    138 #endif // D_STR_FILTER
    +
    139 #ifndef D_STR_3D
    +
    140 #define D_STR_3D "3D"
    +
    141 #endif // D_STR_3D
    +
    142 #ifndef D_STR_CELSIUS
    +
    143 #define D_STR_CELSIUS "æ‘„æ°åº¦"
    +
    144 #endif // D_STR_CELSIUS
    +
    145 #ifndef D_STR_UP
    +
    146 #define D_STR_UP "上"
    +
    147 #endif // D_STR_UP
    +
    148 #ifndef D_STR_TEMPUP
    +
    149 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP // Set `D_STR_TEMP` first!
    +
    150 #endif // D_STR_TEMPUP
    +
    151 #ifndef D_STR_DOWN
    +
    152 #define D_STR_DOWN "下"
    +
    153 #endif // D_STR_DOWN
    +
    154 #ifndef D_STR_TEMPDOWN
    +
    155 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN // Set `D_STR_TEMP` first!
    +
    156 #endif // D_STR_TEMPDOWN
    +
    157 #ifndef D_STR_CHANGE
    +
    158 #define D_STR_CHANGE "改å˜"
    +
    159 #endif // D_STR_CHANGE
    +
    160 #ifndef D_STR_START
    +
    161 #define D_STR_START "开始"
    +
    162 #endif // D_STR_START
    +
    163 #ifndef D_STR_STOP
    +
    164 #define D_STR_STOP "结æŸ"
    +
    165 #endif // D_STR_STOP
    +
    166 #ifndef D_STR_MOVE
    +
    167 #define D_STR_MOVE "移动"
    +
    168 #endif // D_STR_MOVE
    +
    169 #ifndef D_STR_SET
    +
    170 #define D_STR_SET "设置"
    +
    171 #endif // D_STR_SET
    +
    172 #ifndef D_STR_CANCEL
    +
    173 #define D_STR_CANCEL "å–æ¶ˆ"
    +
    174 #endif // D_STR_CANCEL
    +
    175 #ifndef D_STR_COMFORT
    +
    176 #define D_STR_COMFORT "舒适"
    +
    177 #endif // D_STR_COMFORT
    +
    178 #ifndef D_STR_SENSOR
    +
    179 #define D_STR_SENSOR "传感器"
    +
    180 #endif // D_STR_SENSOR
    +
    181 #ifndef D_STR_WEEKLY
    +
    182 #define D_STR_WEEKLY "æ¯å‘¨"
    +
    183 #endif // D_STR_WEEKLY
    +
    184 #ifndef D_STR_WEEKLYTIMER
    +
    185 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER // Needs `D_STR_WEEKLY`!
    +
    186 #endif // D_STR_WEEKLYTIMER
    +
    187 #ifndef D_STR_WIFI
    +
    188 #define D_STR_WIFI "WiFi"
    +
    189 #endif // D_STR_WIFI
    +
    190 #ifndef D_STR_LAST
    +
    191 #define D_STR_LAST "最近"
    +
    192 #endif // D_STR_LAST
    +
    193 #ifndef D_STR_FAST
    +
    194 #define D_STR_FAST "å¿«"
    +
    195 #endif // D_STR_FAST
    +
    196 #ifndef D_STR_SLOW
    +
    197 #define D_STR_SLOW "æ…¢"
    +
    198 #endif // D_STR_SLOW
    +
    199 #ifndef D_STR_AIRFLOW
    +
    200 #define D_STR_AIRFLOW "空气æµåЍ"
    +
    201 #endif // D_STR_AIRFLOW
    +
    202 #ifndef D_STR_STEP
    +
    203 #define D_STR_STEP "æ­¥"
    +
    204 #endif // D_STR_STEP
    +
    205 #ifndef D_STR_NA
    +
    206 #define D_STR_NA "ä¸é€‚用"
    +
    207 #endif // D_STR_NA
    +
    208 #ifndef D_STR_OUTSIDE
    +
    209 #define D_STR_OUTSIDE "室外"
    +
    210 #endif // D_STR_OUTSIDE
    +
    211 #ifndef D_STR_LOUD
    +
    212 #define D_STR_LOUD "大声"
    +
    213 #endif // D_STR_LOUD
    +
    214 #ifndef D_STR_UPPER
    +
    215 #define D_STR_UPPER "更高"
    +
    216 #endif // D_STR_UPPER
    +
    217 #ifndef D_STR_LOWER
    +
    218 #define D_STR_LOWER "更低"
    +
    219 #endif // D_STR_LOWER
    +
    220 #ifndef D_STR_BREEZE
    +
    221 #define D_STR_BREEZE "微风"
    +
    222 #endif // D_STR_BREEZE
    +
    223 #ifndef D_STR_CIRCULATE
    +
    224 #define D_STR_CIRCULATE "æµé€š"
    +
    225 #endif // D_STR_CIRCULATE
    +
    226 #ifndef D_STR_CEILING
    +
    227 #define D_STR_CEILING "天花æ¿"
    +
    228 #endif // D_STR_CEILING
    +
    229 #ifndef D_STR_WALL
    +
    230 #define D_STR_WALL "墙"
    +
    231 #endif // D_STR_WALL
    +
    232 #ifndef D_STR_ROOM
    +
    233 #define D_STR_ROOM "房间"
    +
    234 #endif // D_STR_ROOM
    +
    235 #ifndef D_STR_6THSENSE
    +
    236 #define D_STR_6THSENSE "第六感"
    +
    237 #endif // D_STR_6THSENSE
    +
    238 #ifndef D_STR_ZONEFOLLOW
    +
    239 #define D_STR_ZONEFOLLOW "区域跟éš"
    +
    240 #endif // D_STR_ZONEFOLLOW
    +
    241 #ifndef D_STR_FIXED
    +
    242 #define D_STR_FIXED "固定"
    +
    243 #endif // D_STR_FIXED
    +
    244 
    +
    245 #ifndef D_STR_AUTO
    +
    246 #define D_STR_AUTO "自动"
    +
    247 #endif // D_STR_AUTO
    +
    248 #ifndef D_STR_AUTOMATIC
    +
    249 #define D_STR_AUTOMATIC "自动的"
    +
    250 #endif // D_STR_AUTOMATIC
    +
    251 #ifndef D_STR_MANUAL
    +
    252 #define D_STR_MANUAL "手动"
    +
    253 #endif // D_STR_MANUAL
    +
    254 #ifndef D_STR_COOL
    +
    255 #define D_STR_COOL "制冷"
    +
    256 #endif // D_STR_COOL
    +
    257 #ifndef D_STR_HEAT
    +
    258 #define D_STR_HEAT "加热"
    +
    259 #endif // D_STR_HEAT
    +
    260 #ifndef D_STR_FAN
    +
    261 #define D_STR_FAN "风扇"
    +
    262 #endif // D_STR_FAN
    +
    263 #ifndef D_STR_FANONLY
    +
    264 #define D_STR_FANONLY "仅风扇"
    +
    265 #endif // D_STR_FANONLY
    +
    266 #ifndef D_STR_DRY
    +
    267 #define D_STR_DRY "干燥"
    +
    268 #endif // D_STR_DRY
    +
    269 
    +
    270 #ifndef D_STR_MAX
    +
    271 #define D_STR_MAX "最大"
    +
    272 #endif // D_STR_MAX
    +
    273 #ifndef D_STR_MAXIMUM
    +
    274 #define D_STR_MAXIMUM "最å°"
    +
    275 #endif // D_STR_MAXIMUM
    +
    276 #ifndef D_STR_MIN
    +
    277 #define D_STR_MIN "最低"
    +
    278 #endif // D_STR_MIN
    +
    279 #ifndef D_STR_MINIMUM
    +
    280 #define D_STR_MINIMUM "最低"
    +
    281 #endif // D_STR_MINIMUM
    +
    282 #ifndef D_STR_MED
    +
    283 #define D_STR_MED "中"
    +
    284 #endif // D_STR_MED
    +
    285 #ifndef D_STR_MEDIUM
    +
    286 #define D_STR_MEDIUM "中"
    +
    287 #endif // D_STR_MEDIUM
    +
    288 
    +
    289 #ifndef D_STR_HIGHEST
    +
    290 #define D_STR_HIGHEST "最高"
    +
    291 #endif // D_STR_HIGHEST
    +
    292 #ifndef D_STR_HIGH
    +
    293 #define D_STR_HIGH "高"
    +
    294 #endif // D_STR_HIGH
    +
    295 #ifndef D_STR_HI
    +
    296 #define D_STR_HI "å—¨"
    +
    297 #endif // D_STR_HI
    +
    298 #ifndef D_STR_MID
    +
    299 #define D_STR_MID "中"
    +
    300 #endif // D_STR_MID
    +
    301 #ifndef D_STR_MIDDLE
    +
    302 #define D_STR_MIDDLE "居中"
    +
    303 #endif // D_STR_MIDDLE
    +
    304 #ifndef D_STR_LOW
    +
    305 #define D_STR_LOW "低"
    +
    306 #endif // D_STR_LOW
    +
    307 #ifndef D_STR_LO
    +
    308 #define D_STR_LO "低"
    +
    309 #endif // D_STR_LO
    +
    310 #ifndef D_STR_LOWEST
    +
    311 #define D_STR_LOWEST "最低"
    +
    312 #endif // D_STR_LOWEST
    +
    313 #ifndef D_STR_RIGHT
    +
    314 #define D_STR_RIGHT "å³"
    +
    315 #endif // D_STR_RIGHT
    +
    316 #ifndef D_STR_MAXRIGHT
    +
    317 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT // Set `D_STR_MAX` first!
    +
    318 #endif // D_STR_MAXRIGHT
    +
    319 #ifndef D_STR_RIGHTMAX_NOSPACE
    +
    320 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX // Set `D_STR_MAX` first!
    +
    321 #endif // D_STR_RIGHTMAX_NOSPACE
    +
    322 #ifndef D_STR_LEFT
    +
    323 #define D_STR_LEFT "å·¦"
    +
    324 #endif // D_STR_LEFT
    +
    325 #ifndef D_STR_MAXLEFT
    +
    326 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT // Set `D_STR_MAX` first!
    +
    327 #endif // D_STR_MAXLEFT
    +
    328 #ifndef D_STR_LEFTMAX_NOSPACE
    +
    329 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX // Set `D_STR_MAX` first!
    +
    330 #endif // D_STR_LEFTMAX_NOSPACE
    +
    331 #ifndef D_STR_WIDE
    +
    332 #define D_STR_WIDE "扫风"
    +
    333 #endif // D_STR_WIDE
    +
    334 #ifndef D_STR_CENTRE
    +
    335 #define D_STR_CENTRE "中间"
    +
    336 #endif // D_STR_CENTRE
    +
    337 #ifndef D_STR_TOP
    +
    338 #define D_STR_TOP "上部"
    +
    339 #endif // D_STR_TOP
    +
    340 #ifndef D_STR_BOTTOM
    +
    341 #define D_STR_BOTTOM "底部"
    +
    342 #endif // D_STR_BOTTOM
    +
    343 
    +
    344 // Compound words/phrases/descriptions from pre-defined words.
    +
    345 // Note: Obviously these need to be defined *after* their component words.
    +
    346 #ifndef D_STR_EYEAUTO
    +
    347 #define D_STR_EYEAUTO D_STR_EYE " " D_STR_AUTO
    +
    348 #endif // D_STR_EYEAUTO
    +
    349 #ifndef D_STR_LIGHTTOGGLE
    +
    350 #define D_STR_LIGHTTOGGLE D_STR_LIGHT " " D_STR_TOGGLE
    +
    351 #endif // D_STR_LIGHTTOGGLE
    +
    352 #ifndef D_STR_OUTSIDEQUIET
    +
    353 #define D_STR_OUTSIDEQUIET D_STR_OUTSIDE " " D_STR_QUIET
    +
    354 #endif // D_STR_OUTSIDEQUIET
    +
    355 #ifndef D_STR_POWERTOGGLE
    +
    356 #define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE
    +
    357 #endif // D_STR_POWERTOGGLE
    +
    358 #ifndef D_STR_PREVIOUSPOWER
    +
    359 #define D_STR_PREVIOUSPOWER D_STR_PREVIOUS " " D_STR_POWER
    +
    360 #endif // D_STR_PREVIOUSPOWER
    +
    361 #ifndef D_STR_SENSORTEMP
    +
    362 #define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP
    +
    363 #endif // D_STR_SENSORTEMP
    +
    364 #ifndef D_STR_SLEEP_TIMER
    +
    365 #define D_STR_SLEEP_TIMER D_STR_SLEEP " " D_STR_TIMER
    +
    366 #endif // D_STR_SLEEP_TIMER
    +
    367 #ifndef D_STR_SWINGVMODE
    +
    368 #define D_STR_SWINGVMODE D_STR_SWINGV " " D_STR_MODE
    +
    369 #endif // D_STR_SWINGVMODE
    +
    370 #ifndef D_STR_SWINGVTOGGLE
    +
    371 #define D_STR_SWINGVTOGGLE D_STR_SWINGV " " D_STR_TOGGLE
    +
    372 #endif // D_STR_SWINGVTOGGLE
    +
    373 
    +
    374 // Separators
    +
    375 #ifndef D_CHR_TIME_SEP
    +
    376 #define D_CHR_TIME_SEP ':'
    +
    377 #endif // D_CHR_TIME_SEP
    +
    378 #ifndef D_STR_SPACELBRACE
    +
    379 #define D_STR_SPACELBRACE " ("
    +
    380 #endif // D_STR_SPACELBRACE
    +
    381 #ifndef D_STR_COMMASPACE
    +
    382 #define D_STR_COMMASPACE ", "
    +
    383 #endif // D_STR_COMMASPACE
    +
    384 #ifndef D_STR_COLONSPACE
    +
    385 #define D_STR_COLONSPACE ": "
    +
    386 #endif // D_STR_COLONSPACE
    +
    387 
    +
    388 #ifndef D_STR_DAY
    +
    389 #define D_STR_DAY "天"
    +
    390 #endif // D_STR_DAY
    +
    391 #ifndef D_STR_DAYS
    +
    392 #define D_STR_DAYS D_STR_DAY "s"
    +
    393 #endif // D_STR_DAYS
    +
    394 #ifndef D_STR_HOUR
    +
    395 #define D_STR_HOUR "æ—¶"
    +
    396 #endif // D_STR_HOUR
    +
    397 #ifndef D_STR_HOURS
    +
    398 #define D_STR_HOURS D_STR_HOUR "s"
    +
    399 #endif // D_STR_HOURS
    +
    400 #ifndef D_STR_MINUTE
    +
    401 #define D_STR_MINUTE "分"
    +
    402 #endif // D_STR_MINUTE
    +
    403 #ifndef D_STR_MINUTES
    +
    404 #define D_STR_MINUTES D_STR_MINUTE "s"
    +
    405 #endif // D_STR_MINUTES
    +
    406 #ifndef D_STR_SECOND
    +
    407 #define D_STR_SECOND "ç§’"
    +
    408 #endif // D_STR_SECOND
    +
    409 #ifndef D_STR_SECONDS
    +
    410 #define D_STR_SECONDS D_STR_SECOND "s"
    +
    411 #endif // D_STR_SECONDS
    +
    412 #ifndef D_STR_NOW
    +
    413 #define D_STR_NOW "现在"
    +
    414 #endif // D_STR_NOW
    +
    415 /* This is not three letter days. Disabled.
    +
    416 #ifndef D_STR_THREELETTERDAYS
    +
    417 #define D_STR_THREELETTERDAYS "周一至周末"
    +
    418 #endif // D_STR_THREELETTERDAYS
    +
    419 */
    +
    420 
    +
    421 #ifndef D_STR_YES
    +
    422 #define D_STR_YES "是"
    +
    423 #endif // D_STR_YES
    +
    424 #ifndef D_STR_NO
    +
    425 #define D_STR_NO "å¦"
    +
    426 #endif // D_STR_NO
    +
    427 #ifndef D_STR_TRUE
    +
    428 #define D_STR_TRUE "正确"
    +
    429 #endif // D_STR_TRUE
    +
    430 #ifndef D_STR_FALSE
    +
    431 #define D_STR_FALSE "错误"
    +
    432 #endif // D_STR_FALSE
    +
    433 
    +
    434 #ifndef D_STR_REPEAT
    +
    435 #define D_STR_REPEAT "é‡å¤"
    +
    436 #endif // D_STR_REPEAT
    +
    437 #ifndef D_STR_CODE
    +
    438 #define D_STR_CODE "代ç "
    +
    439 #endif // D_STR_CODE
    +
    440 #ifndef D_STR_BITS
    +
    441 #define D_STR_BITS "ä½"
    +
    442 #endif // D_STR_BITS
    +
    443 
    +
    444 // IRrecvDumpV2+
    +
    445 #ifndef D_STR_TIMESTAMP
    +
    446 #define D_STR_TIMESTAMP "时间戳记"
    +
    447 #endif // D_STR_TIMESTAMP
    +
    448 #ifndef D_STR_LIBRARY
    +
    449 #define D_STR_LIBRARY "库文件"
    +
    450 #endif // D_STR_LIBRARY
    +
    451 #ifndef D_STR_MESGDESC
    +
    452 #define D_STR_MESGDESC "等等信æ¯"
    +
    453 #endif // D_STR_MESGDESC
    +
    454 #ifndef D_STR_IRRECVDUMP_STARTUP
    +
    455 #define D_STR_IRRECVDUMP_STARTUP \
    +
    456  "IRrecvDump è¿è¡Œå½“中,等待红外信æ¯è¾“å…¥ä½äºŽå¼•脚 %d"
    +
    457 #endif // D_STR_IRRECVDUMP_STARTUP
    +
    458 #ifndef D_WARN_BUFFERFULL
    +
    459 #define D_WARN_BUFFERFULL \
    +
    460  "警告: çº¢å¤–ç¼–ç æ•°ç»„过大(>= %d). " \
    +
    461  "在解决此问题之å‰ï¼Œä¸åº”信任此结果. " \
    +
    462  "编辑并增加 `kCaptureBufferSize` å˜é‡."
    +
    463 #endif // D_WARN_BUFFERFULL
    +
    464 
    +
    465 #endif // LOCALE_ZH_CN_H_
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen_index.md b/lib/IRremoteESP8266-2.7.8/docs/doxygen_index.md new file mode 100644 index 000000000..95607645e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen_index.md @@ -0,0 +1,60 @@ +# IRremoteESP8266 Library API Documentation {#mainpage} + +## Getting Started + +### The basics +For sending messages, look at the IRsend class. + +For receiving messages, look at the IRrecv & decode_results classes. + +### Air Conditioners +For _generic_ Air Conditioner control, look at the IRac class & the +stdAc::state_t structure. + +For _detailed_ Air Conditioner control, you need to determine what protocol the +library detects your remote/Air Conditioner to be, look into the appropriate +`src/ir_Protocol.[h|cpp]` files and use the appropriate class object. +e.g. if `IRrecvDumpV2` (or better) detects the protocol as `KELVINATOR`, +open the `src/ir_Kelvinator.*` files, and examine the IRKelvinatorAC class the +methods available to create/decode/send `KELVINATOR` messages with all the +abilities the library offers. You can also select it from the +[Classes](annotated.html) menu above. + +Various native constants & options for a given Protocol's class object can be +found in the associated header file for that protocol. + +## Examples +Most of the common uses of this library's APIs have demonstration code +available under the [examples](https://github.com/crankyoldgit/IRremoteESP8266/tree/master/examples) +directory. It ranges from trivial examples to complex real-world project code. + +## Tuning +The most commonly used & needed knobs for controlling aspects of this library +are available via run-time class methods or at class-object instantiation. +Again, you are referred to the IRsend & IRrecv classes. + +### Advanced +Certain addition constants and options are available as compile-time tweaks. +You should inspect [IRremoteESP8266.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRremoteESP8266.h), +[IRsend.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRsend.h), +& [IRrecv.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRrecv.h) +for General, Sending, & Receiving tweaks respectively. + +#### Protocol timings +Generally you should never need to adjust the timing parameters for a given +protocol or device. However, occasionally some individual devices just want to +be special. +If you are having problems decoding/receiving a message, look into the +`tolerance`, `kTolerance`, or IRrecv::setTolerance constants/methods etc first. +However, if your problems is sending, or adjusting the tolerance doesn't work +you may need to tweak per-protocol timing values. These are stored as +constants in the `ir_ProtocolName.cpp` file for the given protocol. This is +typically a step of last resort. + +#### Reducing code size & flash usage. +You can disable most protocols by either modifying the appropriate `#‍define`s +in [IRremoteESP8266.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRremoteESP8266.h) +or passing the appropriate compile-time flags, as documented in the same file. + +Avoid using the A/C classes, especially the IRac class as they will force the +compiler to include large amounts of code you may not need. diff --git a/lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/BlynkIrRemote.ino b/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/BlynkIrRemote.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/BlynkIrRemote.ino rename to lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/BlynkIrRemote.ino diff --git a/lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/platformio.ini similarity index 96% rename from lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/platformio.ini index 58f6b0f30..c89beccfa 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/BlynkIrRemote/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/platformio.ini @@ -7,6 +7,7 @@ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino platform = espressif8266 +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [common] diff --git a/lib/IRremoteESP8266-2.7.7/examples/CommonAcControl/CommonAcControl.ino b/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/CommonAcControl.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/CommonAcControl/CommonAcControl.ino rename to lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/CommonAcControl.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/platformio.ini new file mode 100644 index 000000000..b71195045 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/platformio.ini @@ -0,0 +1,26 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev + +; Build the program forcing the compiler to treat all warnings as errors. +[env:shakedown_all_protocols] +platform = espressif8266 +board = nodemcuv2 +build_flags = + ${env.build_flags} + -Werror diff --git a/lib/IRremoteESP8266-2.7.7/examples/ControlSamsungAC/ControlSamsungAC.ino b/lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/ControlSamsungAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/ControlSamsungAC/ControlSamsungAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/ControlSamsungAC.ino diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRGCSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/platformio.ini similarity index 92% rename from lib/IRremoteESP8266-2.7.7/examples/IRGCSendDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/platformio.ini index e6f6320da..6bda1bb71 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/IRGCSendDemo/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] diff --git a/lib/IRremoteESP8266-2.7.7/examples/DumbIRRepeater/DumbIRRepeater.ino b/lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/DumbIRRepeater.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/DumbIRRepeater/DumbIRRepeater.ino rename to lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/DumbIRRepeater.ino diff --git a/lib/IRremoteESP8266-2.7.7/examples/CommonAcControl/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/platformio.ini similarity index 92% rename from lib/IRremoteESP8266-2.7.7/examples/CommonAcControl/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/platformio.ini index e6f6320da..6bda1bb71 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/CommonAcControl/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRGCSendDemo/IRGCSendDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/IRGCSendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRGCSendDemo/IRGCSendDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/IRGCSendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.7/examples/ControlSamsungAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/platformio.ini similarity index 92% rename from lib/IRremoteESP8266-2.7.7/examples/ControlSamsungAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/platformio.ini index e6f6320da..6bda1bb71 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/ControlSamsungAC/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/IRGCTCPServer.ino b/lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/IRGCTCPServer.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRGCTCPServer/IRGCTCPServer.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/IRGCTCPServer.ino diff --git a/lib/IRremoteESP8266-2.7.7/examples/DumbIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/platformio.ini similarity index 92% rename from lib/IRremoteESP8266-2.7.7/examples/DumbIRRepeater/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/platformio.ini index e6f6320da..6bda1bb71 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/DumbIRRepeater/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.h b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.h similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.h rename to lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.h diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.ino b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/IRMQTTServer.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.ino diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/platformio.ini similarity index 97% rename from lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/platformio.ini index 1a22b09af..7920c930e 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/IRMQTTServer/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/platformio.ini @@ -8,6 +8,7 @@ lib_ignore = examples build_flags = -DMQTT_MAX_PACKET_SIZE=768 ; -D_IR_LOCALE_=en-AU framework = arduino platform = espressif8266 +monitor_speed = 115200 [common] lib_deps_builtin = diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRServer/IRServer.ino b/lib/IRremoteESP8266-2.7.8/examples/IRServer/IRServer.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRServer/IRServer.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRServer/IRServer.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRServer/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRServer/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRServer/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/IRrecvDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/IRrecvDemo.ino similarity index 95% rename from lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/IRrecvDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/IRrecvDemo.ino index 945f94055..2ae2e1410 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDemo/IRrecvDemo.ino +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/IRrecvDemo.ino @@ -2,7 +2,7 @@ * IRremoteESP8266: IRrecvDemo - demonstrates receiving IR codes with IRrecv * This is very simple teaching code to show you how to use the library. * If you are trying to decode your Infra-Red remote(s) for later replay, - * use the IRrecvDumpV2.ino example code instead of this. + * use the IRrecvDumpV2.ino (or later) example code instead of this. * An IR detector/demodulator must be connected to the input kRecvPin. * Copyright 2009 Ken Shirriff, http://arcfn.com * Example circuit diagram: diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/platformio.ini new file mode 100644 index 000000000..7130e886a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +build_flags = ; -D_IR_LOCALE_=en-AU +monitor_speed = 115200 + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/IRrecvDump.ino b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/IRrecvDump.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRrecvDump/IRrecvDump.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/IRrecvDump.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/IRrecvDumpV2.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV2/IRrecvDumpV2.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/IRrecvDumpV2.ino diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/platformio.ini similarity index 81% rename from lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/platformio.ini index 62fa06d3a..fb04eb4b1 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/platformio.ini @@ -10,6 +10,7 @@ framework = arduino lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] @@ -50,3 +51,8 @@ build_flags = -D_IR_LOCALE_=it-IT ; Italian [env:zh-CN] build_flags = -D_IR_LOCALE_=zh-CN ; Chinese (Simplified) + +; Build the library with all protocols disabled to flush out #if/#ifdef issues & +; any compiler warnings, by turning them into errors. +[env:shakedown_no_protocols] +build_flags = -D_IR_ENABLE_DEFAULT_=false -Werror diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/BaseOTA.h b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/BaseOTA.h similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/BaseOTA.h rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/BaseOTA.h diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/IRrecvDumpV3.ino b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/IRrecvDumpV3.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV3/IRrecvDumpV3.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/IRrecvDumpV3.ino diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV2/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/platformio.ini similarity index 97% rename from lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV2/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/platformio.ini index 62fa06d3a..95a90ac86 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/IRrecvDumpV2/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/platformio.ini @@ -10,6 +10,7 @@ framework = arduino lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/IRsendDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/IRsendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRsendDemo/IRsendDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/IRsendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/IRsendProntoDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/IRsendProntoDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/IRsendProntoDemo/IRsendProntoDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/IRsendProntoDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/LGACSend/LGACSend.ino b/lib/IRremoteESP8266-2.7.8/examples/LGACSend/LGACSend.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/LGACSend/LGACSend.ino rename to lib/IRremoteESP8266-2.7.8/examples/LGACSend/LGACSend.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/LGACSend/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/LGACSend/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/LGACSend/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/SmartIRRepeater.ino b/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/SmartIRRepeater.ino similarity index 99% rename from lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/SmartIRRepeater.ino rename to lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/SmartIRRepeater.ino index 576abb516..d35c4cef6 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/SmartIRRepeater/SmartIRRepeater.ino +++ b/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/SmartIRRepeater.ino @@ -121,8 +121,10 @@ void loop() { uint16_t *raw_array = resultToRawArray(&results); // Find out how many elements are in the array. size = getCorrectedRawLength(&results); +#if SEND_RAW // Send it out via the IR LED circuit. irsend.sendRaw(raw_array, size, kFrequency); +#endif // SEND_RAW // Deallocate the memory allocated by resultToRawArray(). delete [] raw_array; } else if (hasACState(protocol)) { // Does the message require a state[]? diff --git a/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/platformio.ini new file mode 100644 index 000000000..0e8f173f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/platformio.ini @@ -0,0 +1,36 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev + +; Build the program forcing the compiler to treat all warnings as errors. +[env:shakedown_all_protocols] +platform = espressif8266 +board = nodemcuv2 +build_flags = + ${env.build_flags} + -Werror + +; Disable all protocols to see if we can force any errors. +; Build the program forcing the compiler to treat all warnings as errors. +[env:shakedown_no_protocols] +platform = espressif8266 +board = nodemcuv2 +build_flags = + ${env.build_flags} + -Werror + -D_IR_ENABLE_DEFAULT_=false diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/TurnOnArgoAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/TurnOnArgoAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnArgoAC/TurnOnArgoAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/TurnOnArgoAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/TurnOnGreeAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/TurnOnGreeAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnGreeAC/TurnOnGreeAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/TurnOnGreeAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/README.md b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/README.md similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/README.md rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/README.md diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/Web-AC-control.ino b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/Web-AC-control.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/Web-AC-control.ino rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/Web-AC-control.ino diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/platformio.ini similarity index 96% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/platformio.ini index 731442831..19ff9c277 100644 --- a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [common] diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/printscreen.png b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/printscreen.png similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/printscreen.png rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/printscreen.png diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/favicon.ico b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/favicon.ico similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/favicon.ico rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/favicon.ico diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_1_off.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_1_off.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_off.svg diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_1_on.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_1_on.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_on.svg diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_2_off.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_2_off.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_off.svg diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_2_on.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_2_on.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_on.svg diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_3_off.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_3_off.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_off.svg diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_3_on.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_3_on.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_on.svg diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_4_off.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_4_off.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_off.svg diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_4_on.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/level_4_on.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_on.svg diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/ui.html b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.html similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/ui.html rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.html diff --git a/lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/ui.js b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.js similarity index 100% rename from lib/IRremoteESP8266-2.7.7/examples/Web-AC-control/upload/ui.js rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.js diff --git a/lib/IRremoteESP8266-2.7.7/keywords.txt b/lib/IRremoteESP8266-2.7.8/keywords.txt similarity index 95% rename from lib/IRremoteESP8266-2.7.7/keywords.txt rename to lib/IRremoteESP8266-2.7.8/keywords.txt index 907cba220..c05482770 100644 --- a/lib/IRremoteESP8266-2.7.7/keywords.txt +++ b/lib/IRremoteESP8266-2.7.8/keywords.txt @@ -22,7 +22,9 @@ IRAmcorAc KEYWORD1 IRArgoAC KEYWORD1 +IRCarrierAc64 KEYWORD1 IRCoolixAC KEYWORD1 +IRCoronaAc KEYWORD1 IRDaikin128 KEYWORD1 IRDaikin152 KEYWORD1 IRDaikin160 KEYWORD1 @@ -41,6 +43,7 @@ IRHaierACYRW02 KEYWORD1 IRHitachiAc KEYWORD1 IRHitachiAc1 KEYWORD1 IRHitachiAc3 KEYWORD1 +IRHitachiAc344: KEYWORD1 IRHitachiAc424 KEYWORD1 IRKelvinatorAC KEYWORD1 IRLgAc KEYWORD1 @@ -85,15 +88,19 @@ whirlpool_ac_remote_model_t KEYWORD1 # Methods and Functions (KEYWORD2) ####################################### +_cancelOffTimer KEYWORD2 +_cancelOnTimer KEYWORD2 _delayMicroseconds KEYWORD2 _getTime KEYWORD2 _getTimer KEYWORD2 _matchGeneric KEYWORD2 _sendSony KEYWORD2 _setMode KEYWORD2 +_setPower KEYWORD2 _setTemp KEYWORD2 _setTime KEYWORD2 _setTimer KEYWORD2 +_toString KEYWORD2 _validTolerance KEYWORD2 add KEYWORD2 addBoolToString KEYWORD2 @@ -114,7 +121,6 @@ buildState KEYWORD2 calcBlockChecksum KEYWORD2 calcChecksum KEYWORD2 calcFirstChecksum KEYWORD2 -calcLGChecksum KEYWORD2 calcSecondChecksum KEYWORD2 calcUSecPeriod KEYWORD2 calculateChecksum KEYWORD2 @@ -122,6 +128,7 @@ calibrate KEYWORD2 cancelOffTimer KEYWORD2 cancelOnTimer KEYWORD2 cancelTimers KEYWORD2 +carrier64 KEYWORD2 celsiusToFahrenheit KEYWORD2 checkZjsSig KEYWORD2 checkZmsSig KEYWORD2 @@ -138,6 +145,7 @@ convertSwingH KEYWORD2 convertSwingV KEYWORD2 coolix KEYWORD2 copyIrParams KEYWORD2 +corona KEYWORD2 countBits KEYWORD2 crudeNoiseFilter KEYWORD2 daikin KEYWORD2 @@ -157,6 +165,7 @@ decodeCOOLIX KEYWORD2 decodeCarrierAC KEYWORD2 decodeCarrierAC40 KEYWORD2 decodeCarrierAC64 KEYWORD2 +decodeCoronaAc KEYWORD2 decodeDISH KEYWORD2 decodeDaikin KEYWORD2 decodeDaikin128 KEYWORD2 @@ -191,6 +200,7 @@ decodeLutron KEYWORD2 decodeMWM KEYWORD2 decodeMagiQuest KEYWORD2 decodeMidea KEYWORD2 +decodeMidea24 KEYWORD2 decodeMitsubishi KEYWORD2 decodeMitsubishi112 KEYWORD2 decodeMitsubishi136 KEYWORD2 @@ -223,6 +233,7 @@ decodeTrotec KEYWORD2 decodeVestelAc KEYWORD2 decodeWhirlpoolAC KEYWORD2 decodeWhynter KEYWORD2 +decodeZepeal KEYWORD2 defaultBits KEYWORD2 delonghiac KEYWORD2 disableIRIn KEYWORD2 @@ -311,6 +322,7 @@ getOnTimer KEYWORD2 getOnTimerEnabled KEYWORD2 getOutsideQuiet KEYWORD2 getPower KEYWORD2 +getPowerButton KEYWORD2 getPowerSpecial KEYWORD2 getPowerToggle KEYWORD2 getPowerful KEYWORD2 @@ -320,6 +332,7 @@ getRClevel KEYWORD2 getRaw KEYWORD2 getRoomTemp KEYWORD2 getSave KEYWORD2 +getSectionByte KEYWORD2 getSensor KEYWORD2 getSensorTemp KEYWORD2 getSilent KEYWORD2 @@ -371,6 +384,7 @@ hasInvertedStates KEYWORD2 hasStateChanged KEYWORD2 hitachi KEYWORD2 hitachi1 KEYWORD2 +hitachi344 KEYWORD2 hitachi424 KEYWORD2 htmlEscape KEYWORD2 initState KEYWORD2 @@ -400,6 +414,7 @@ matchData KEYWORD2 matchGeneric KEYWORD2 matchGenericConstBitTime KEYWORD2 matchManchester KEYWORD2 +matchManchesterData KEYWORD2 matchMark KEYWORD2 matchSpace KEYWORD2 midea KEYWORD2 @@ -438,6 +453,7 @@ sendCOOLIX KEYWORD2 sendCarrierAC KEYWORD2 sendCarrierAC40 KEYWORD2 sendCarrierAC64 KEYWORD2 +sendCoronaAc KEYWORD2 sendDISH KEYWORD2 sendDaikin KEYWORD2 sendDaikin128 KEYWORD2 @@ -466,6 +482,7 @@ sendHitachiAC KEYWORD2 sendHitachiAC1 KEYWORD2 sendHitachiAC2 KEYWORD2 sendHitachiAc3 KEYWORD2 +sendHitachiAc344 KEYWORD2 sendHitachiAc424 KEYWORD2 sendInax KEYWORD2 sendJVC KEYWORD2 @@ -480,6 +497,7 @@ sendMagiQuest KEYWORD2 sendManchester KEYWORD2 sendManchesterData KEYWORD2 sendMidea KEYWORD2 +sendMidea24 KEYWORD2 sendMitsubishi KEYWORD2 sendMitsubishi112 KEYWORD2 sendMitsubishi136 KEYWORD2 @@ -520,6 +538,7 @@ sendTrotec KEYWORD2 sendVestelAc KEYWORD2 sendWhirlpoolAC KEYWORD2 sendWhynter KEYWORD2 +sendZepeal KEYWORD2 serialPrintUint64 KEYWORD2 set3D KEYWORD2 set8CHeat KEYWORD2 @@ -579,6 +598,7 @@ setOnTimerActive KEYWORD2 setOnTimerEnabled KEYWORD2 setOutsideQuiet KEYWORD2 setPower KEYWORD2 +setPowerButton KEYWORD2 setPowerSpecial KEYWORD2 setPowerToggle KEYWORD2 setPowerful KEYWORD2 @@ -651,6 +671,7 @@ uint64ToString KEYWORD2 uint8ToBcd KEYWORD2 updateSavedState KEYWORD2 validChecksum KEYWORD2 +validSection KEYWORD2 vestel KEYWORD2 whirlpool KEYWORD2 xorBytes KEYWORD2 @@ -701,6 +722,7 @@ CARRIER_AC64 LITERAL1 CARRIER_AC_BITS LITERAL1 COOLIX LITERAL1 COOLIX_BITS LITERAL1 +CORONA_AC LITERAL1 DAIKIN LITERAL1 DAIKIN128 LITERAL1 DAIKIN152 LITERAL1 @@ -730,6 +752,7 @@ DECODE_CARRIER_AC LITERAL1 DECODE_CARRIER_AC40 LITERAL1 DECODE_CARRIER_AC64 LITERAL1 DECODE_COOLIX LITERAL1 +DECODE_CORONA_AC LITERAL1 DECODE_DAIKIN LITERAL1 DECODE_DAIKIN128 LITERAL1 DECODE_DAIKIN152 LITERAL1 @@ -756,6 +779,7 @@ DECODE_HITACHI_AC LITERAL1 DECODE_HITACHI_AC1 LITERAL1 DECODE_HITACHI_AC2 LITERAL1 DECODE_HITACHI_AC3 LITERAL1 +DECODE_HITACHI_AC344 LITERAL1 DECODE_HITACHI_AC424 LITERAL1 DECODE_INAX LITERAL1 DECODE_JVC LITERAL1 @@ -766,6 +790,7 @@ DECODE_LG LITERAL1 DECODE_LUTRON LITERAL1 DECODE_MAGIQUEST LITERAL1 DECODE_MIDEA LITERAL1 +DECODE_MIDEA24 LITERAL1 DECODE_MITSUBISHI LITERAL1 DECODE_MITSUBISHI112 LITERAL1 DECODE_MITSUBISHI136 LITERAL1 @@ -800,6 +825,7 @@ DECODE_TROTEC LITERAL1 DECODE_VESTEL_AC LITERAL1 DECODE_WHIRLPOOL_AC LITERAL1 DECODE_WHYNTER LITERAL1 +DECODE_ZEPEAL LITERAL1 DELONGHI_AC LITERAL1 DENON LITERAL1 DENON_48_BITS LITERAL1 @@ -932,6 +958,7 @@ HITACHI_AC2 LITERAL1 HITACHI_AC2_BITS LITERAL1 HITACHI_AC2_STATE_LENGTH LITERAL1 HITACHI_AC3 LITERAL1 +HITACHI_AC344 LITERAL1 HITACHI_AC424 LITERAL1 HITACHI_AC_BITS LITERAL1 HITACHI_AC_STATE_LENGTH LITERAL1 @@ -964,6 +991,7 @@ LUTRON LITERAL1 MAGIQUEST LITERAL1 MAGIQUEST_BITS LITERAL1 MIDEA LITERAL1 +MIDEA24 LITERAL1 MIDEA_AC_AUTO LITERAL1 MIDEA_AC_COOL LITERAL1 MIDEA_AC_DRY LITERAL1 @@ -1046,6 +1074,7 @@ SEND_CARRIER_AC LITERAL1 SEND_CARRIER_AC40 LITERAL1 SEND_CARRIER_AC64 LITERAL1 SEND_COOLIX LITERAL1 +SEND_CORONA_AC LITERAL1 SEND_DAIKIN LITERAL1 SEND_DAIKIN128 LITERAL1 SEND_DAIKIN152 LITERAL1 @@ -1071,6 +1100,7 @@ SEND_HITACHI_AC LITERAL1 SEND_HITACHI_AC1 LITERAL1 SEND_HITACHI_AC2 LITERAL1 SEND_HITACHI_AC3 LITERAL1 +SEND_HITACHI_AC344 LITERAL1 SEND_HITACHI_AC424 LITERAL1 SEND_INAX LITERAL1 SEND_JVC LITERAL1 @@ -1081,6 +1111,7 @@ SEND_LG LITERAL1 SEND_LUTRON LITERAL1 SEND_MAGIQUEST LITERAL1 SEND_MIDEA LITERAL1 +SEND_MIDEA24 LITERAL1 SEND_MITSUBISHI LITERAL1 SEND_MITSUBISHI112 LITERAL1 SEND_MITSUBISHI136 LITERAL1 @@ -1116,6 +1147,7 @@ SEND_TROTEC LITERAL1 SEND_VESTEL_AC LITERAL1 SEND_WHIRLPOOL_AC LITERAL1 SEND_WHYNTER LITERAL1 +SEND_ZEPEAL LITERAL1 SHARP LITERAL1 SHARP_AC LITERAL1 SHARP_BITS LITERAL1 @@ -1162,6 +1194,7 @@ WHYNTER LITERAL1 WHYNTER_BITS LITERAL1 YAW1F LITERAL1 YBOFB LITERAL1 +ZEPEAL LITERAL1 k3DStr LITERAL1 k6thSenseStr LITERAL1 k8CHeatStr LITERAL1 @@ -1299,6 +1332,7 @@ kButtonStr LITERAL1 kCancelStr LITERAL1 kCarrierAc40BitMark LITERAL1 kCarrierAc40Bits LITERAL1 +kCarrierAc40Gap LITERAL1 kCarrierAc40HdrMark LITERAL1 kCarrierAc40HdrSpace LITERAL1 kCarrierAc40MinRepeat LITERAL1 @@ -1306,11 +1340,38 @@ kCarrierAc40OneSpace LITERAL1 kCarrierAc40ZeroSpace LITERAL1 kCarrierAc64BitMark LITERAL1 kCarrierAc64Bits LITERAL1 +kCarrierAc64ChecksumOffset LITERAL1 +kCarrierAc64ChecksumSize LITERAL1 +kCarrierAc64Cool LITERAL1 +kCarrierAc64Fan LITERAL1 +kCarrierAc64FanAuto LITERAL1 +kCarrierAc64FanHigh LITERAL1 +kCarrierAc64FanLow LITERAL1 +kCarrierAc64FanMedium LITERAL1 +kCarrierAc64FanOffset LITERAL1 +kCarrierAc64FanSize LITERAL1 kCarrierAc64Gap LITERAL1 kCarrierAc64HdrMark LITERAL1 kCarrierAc64HdrSpace LITERAL1 +kCarrierAc64Heat LITERAL1 +kCarrierAc64MaxTemp LITERAL1 kCarrierAc64MinRepeat LITERAL1 +kCarrierAc64MinTemp LITERAL1 +kCarrierAc64ModeOffset LITERAL1 +kCarrierAc64ModeSize LITERAL1 +kCarrierAc64OffTimerEnableOffset LITERAL1 +kCarrierAc64OffTimerOffset LITERAL1 +kCarrierAc64OnTimerEnableOffset LITERAL1 +kCarrierAc64OnTimerOffset LITERAL1 kCarrierAc64OneSpace LITERAL1 +kCarrierAc64PowerOffset LITERAL1 +kCarrierAc64SleepOffset LITERAL1 +kCarrierAc64SwingVOffset LITERAL1 +kCarrierAc64TempOffset LITERAL1 +kCarrierAc64TempSize LITERAL1 +kCarrierAc64TimerMax LITERAL1 +kCarrierAc64TimerMin LITERAL1 +kCarrierAc64TimerSize LITERAL1 kCarrierAc64ZeroSpace LITERAL1 kCarrierAcBitMark LITERAL1 kCarrierAcBits LITERAL1 @@ -1391,6 +1452,61 @@ kCoolixUnknown LITERAL1 kCoolixZeroSpace LITERAL1 kCoolixZeroSpaceTicks LITERAL1 kCoolixZoneFollowMaskOffset LITERAL1 +kCoronaAcAutoD0 LITERAL1 +kCoronaAcAutoD1 LITERAL1 +kCoronaAcBitMark LITERAL1 +kCoronaAcBits LITERAL1 +kCoronaAcBitsShort LITERAL1 +kCoronaAcFanAuto LITERAL1 +kCoronaAcFanHigh LITERAL1 +kCoronaAcFanLow LITERAL1 +kCoronaAcFanMedium LITERAL1 +kCoronaAcFanOffset LITERAL1 +kCoronaAcFanSize LITERAL1 +kCoronaAcFreq LITERAL1 +kCoronaAcHdrMark LITERAL1 +kCoronaAcHdrSpace LITERAL1 +kCoronaAcMaxTemp LITERAL1 +kCoronaAcMinTemp LITERAL1 +kCoronaAcModeCool LITERAL1 +kCoronaAcModeDry LITERAL1 +kCoronaAcModeFan LITERAL1 +kCoronaAcModeHeat LITERAL1 +kCoronaAcModeOffset LITERAL1 +kCoronaAcModeSize LITERAL1 +kCoronaAcOffTimerSection LITERAL1 +kCoronaAcOnTimerSection LITERAL1 +kCoronaAcOneSpace LITERAL1 +kCoronaAcOverhead LITERAL1 +kCoronaAcOverheadShort LITERAL1 +kCoronaAcPowerButtonOffset LITERAL1 +kCoronaAcPowerOffset LITERAL1 +kCoronaAcPowerSaveOffset LITERAL1 +kCoronaAcSectionBytes LITERAL1 +kCoronaAcSectionData0Base LITERAL1 +kCoronaAcSectionData0InvPos LITERAL1 +kCoronaAcSectionData0Pos LITERAL1 +kCoronaAcSectionData1InvPos LITERAL1 +kCoronaAcSectionData1Pos LITERAL1 +kCoronaAcSectionHeader0 LITERAL1 +kCoronaAcSectionHeader0Pos LITERAL1 +kCoronaAcSectionHeader1 LITERAL1 +kCoronaAcSectionHeader1Pos LITERAL1 +kCoronaAcSectionLabelBase LITERAL1 +kCoronaAcSectionLabelPos LITERAL1 +kCoronaAcSections LITERAL1 +kCoronaAcSettingsSection LITERAL1 +kCoronaAcSpaceGap LITERAL1 +kCoronaAcStateLength LITERAL1 +kCoronaAcStateLengthShort LITERAL1 +kCoronaAcSwingVToggleOffset LITERAL1 +kCoronaAcTempOffset LITERAL1 +kCoronaAcTempSize LITERAL1 +kCoronaAcTimerMax LITERAL1 +kCoronaAcTimerOff LITERAL1 +kCoronaAcTimerUnitsPerMin LITERAL1 +kCoronaAcZeroSpace LITERAL1 +kCoronaTolerance LITERAL1 kDaikin128Auto LITERAL1 kDaikin128BitCeiling LITERAL1 kDaikin128BitEcono LITERAL1 @@ -1844,11 +1960,9 @@ kDishZeroSpaceTicks LITERAL1 kDisplayTempStr LITERAL1 kDoshishaBitMark LITERAL1 kDoshishaBits LITERAL1 -kDoshishaFreq LITERAL1 kDoshishaHdrMark LITERAL1 kDoshishaHdrSpace LITERAL1 kDoshishaOneSpace LITERAL1 -kDoshishaOverhead LITERAL1 kDoshishaZeroSpace LITERAL1 kDownStr LITERAL1 kDry LITERAL1 @@ -2233,6 +2347,37 @@ kHitachiAc1TempSize LITERAL1 kHitachiAc1TimerSize LITERAL1 kHitachiAc2Bits LITERAL1 kHitachiAc2StateLength LITERAL1 +kHitachiAc344Bits LITERAL1 +kHitachiAc344ButtonFan LITERAL1 +kHitachiAc344ButtonPowerMode LITERAL1 +kHitachiAc344ButtonSwingH LITERAL1 +kHitachiAc344ButtonSwingV LITERAL1 +kHitachiAc344ButtonTempDown LITERAL1 +kHitachiAc344ButtonTempUp LITERAL1 +kHitachiAc344Cool LITERAL1 +kHitachiAc344Dry LITERAL1 +kHitachiAc344Fan LITERAL1 +kHitachiAc344FanAuto LITERAL1 +kHitachiAc344FanHigh LITERAL1 +kHitachiAc344FanLow LITERAL1 +kHitachiAc344FanMax LITERAL1 +kHitachiAc344FanMedium LITERAL1 +kHitachiAc344FanMin LITERAL1 +kHitachiAc344Heat LITERAL1 +kHitachiAc344MaxTemp LITERAL1 +kHitachiAc344MinTemp LITERAL1 +kHitachiAc344StateLength LITERAL1 +kHitachiAc344SwingHAuto LITERAL1 +kHitachiAc344SwingHByte LITERAL1 +kHitachiAc344SwingHLeft LITERAL1 +kHitachiAc344SwingHLeftMax LITERAL1 +kHitachiAc344SwingHMiddle LITERAL1 +kHitachiAc344SwingHOffset LITERAL1 +kHitachiAc344SwingHRight LITERAL1 +kHitachiAc344SwingHRightMax LITERAL1 +kHitachiAc344SwingHSize LITERAL1 +kHitachiAc344SwingVByte LITERAL1 +kHitachiAc344SwingVOffset LITERAL1 kHitachiAc3BitMark LITERAL1 kHitachiAc3Bits LITERAL1 kHitachiAc3HdrMark LITERAL1 @@ -2247,6 +2392,7 @@ kHitachiAc424Bits LITERAL1 kHitachiAc424ButtonByte LITERAL1 kHitachiAc424ButtonFan LITERAL1 kHitachiAc424ButtonPowerMode LITERAL1 +kHitachiAc424ButtonSwingH LITERAL1 kHitachiAc424ButtonSwingV LITERAL1 kHitachiAc424ButtonTempDown LITERAL1 kHitachiAc424ButtonTempUp LITERAL1 @@ -2512,6 +2658,9 @@ kMediumStr LITERAL1 kMidStr LITERAL1 kMiddle LITERAL1 kMiddleStr LITERAL1 +kMidea24Bits LITERAL1 +kMidea24MinGap LITERAL1 +kMidea24MinRepeat LITERAL1 kMideaACAuto LITERAL1 kMideaACCelsiusOffset LITERAL1 kMideaACCool LITERAL1 @@ -2995,6 +3144,7 @@ kPioneerOneSpaceTicks LITERAL1 kPioneerTick LITERAL1 kPioneerZeroSpace LITERAL1 kPioneerZeroSpaceTicks LITERAL1 +kPowerButtonStr LITERAL1 kPowerStr LITERAL1 kPowerToggleStr LITERAL1 kPowerfulStr LITERAL1 @@ -3053,8 +3203,6 @@ kRcmmRptLengthTicks LITERAL1 kRcmmTick LITERAL1 kRcmmTolerance LITERAL1 kRcz01ChannelMask LITERAL1 -kRcz01CheckExpected LITERAL1 -kRcz01CheckMask LITERAL1 kRcz01CommandLevel1 LITERAL1 kRcz01CommandLevel2 LITERAL1 kRcz01CommandLevel3 LITERAL1 @@ -3068,6 +3216,8 @@ kRcz01CommandOn LITERAL1 kRcz01CommandSwitchChannel LITERAL1 kRcz01CommandTimmer30 LITERAL1 kRcz01CommandTimmer60 LITERAL1 +kRcz01Signature LITERAL1 +kRcz01SignatureMask LITERAL1 kRepeat LITERAL1 kRepeatStr LITERAL1 kRight LITERAL1 @@ -3583,4 +3733,21 @@ kWideStr LITERAL1 kWifiStr LITERAL1 kXFanStr LITERAL1 kYesStr LITERAL1 +kZepealBits LITERAL1 +kZepealCommandOffOn LITERAL1 +kZepealCommandOffTimer LITERAL1 +kZepealCommandOnTimer LITERAL1 +kZepealCommandRhythm LITERAL1 +kZepealCommandSpeed LITERAL1 +kZepealFooterMark LITERAL1 +kZepealGap LITERAL1 +kZepealHdrMark LITERAL1 +kZepealHdrSpace LITERAL1 +kZepealMinRepeat LITERAL1 +kZepealOneMark LITERAL1 +kZepealOneSpace LITERAL1 +kZepealSignature LITERAL1 +kZepealTolerance LITERAL1 +kZepealZeroMark LITERAL1 +kZepealZeroSpace LITERAL1 kZoneFollowStr LITERAL1 diff --git a/lib/IRremoteESP8266-2.7.7/library.json b/lib/IRremoteESP8266-2.7.8/library.json similarity index 98% rename from lib/IRremoteESP8266-2.7.7/library.json rename to lib/IRremoteESP8266-2.7.8/library.json index abf2f8070..c92323c46 100644 --- a/lib/IRremoteESP8266-2.7.7/library.json +++ b/lib/IRremoteESP8266-2.7.8/library.json @@ -1,6 +1,6 @@ { "name": "IRremoteESP8266", - "version": "2.7.7", + "version": "2.7.8", "keywords": "infrared, ir, remote, esp8266, esp32", "description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)", "repository": diff --git a/lib/IRremoteESP8266-2.7.7/library.properties b/lib/IRremoteESP8266-2.7.8/library.properties similarity index 97% rename from lib/IRremoteESP8266-2.7.7/library.properties rename to lib/IRremoteESP8266-2.7.8/library.properties index 16c4f3bc6..785252195 100644 --- a/lib/IRremoteESP8266-2.7.7/library.properties +++ b/lib/IRremoteESP8266-2.7.8/library.properties @@ -1,5 +1,5 @@ name=IRremoteESP8266 -version=2.7.7 +version=2.7.8 author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto, Christian Nilsson sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32) diff --git a/lib/IRremoteESP8266-2.7.7/platformio.ini b/lib/IRremoteESP8266-2.7.8/platformio.ini similarity index 94% rename from lib/IRremoteESP8266-2.7.7/platformio.ini rename to lib/IRremoteESP8266-2.7.8/platformio.ini index 67dbeb606..76c2f3b40 100644 --- a/lib/IRremoteESP8266-2.7.7/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/platformio.ini @@ -9,6 +9,7 @@ lib_ignore = examples framework = arduino platform = espressif8266 build_flags = ; -D_IR_LOCALE_=en-AU +monitor_speed = 115200 [env:nodemcuv2] board = nodemcuv2 diff --git a/lib/IRremoteESP8266-2.7.7/pylintrc b/lib/IRremoteESP8266-2.7.8/pylintrc similarity index 100% rename from lib/IRremoteESP8266-2.7.7/pylintrc rename to lib/IRremoteESP8266-2.7.8/pylintrc diff --git a/lib/IRremoteESP8266-2.7.7/src/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.8/src/CPPLINT.cfg similarity index 100% rename from lib/IRremoteESP8266-2.7.7/src/CPPLINT.cfg rename to lib/IRremoteESP8266-2.7.8/src/CPPLINT.cfg diff --git a/lib/IRremoteESP8266-2.7.7/src/IRac.cpp b/lib/IRremoteESP8266-2.7.8/src/IRac.cpp similarity index 68% rename from lib/IRremoteESP8266-2.7.7/src/IRac.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRac.cpp index 3e56b0a46..fda16aba5 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRac.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRac.cpp @@ -2,7 +2,7 @@ // Provide a universal/standard interface for sending A/C nessages. // It does not provide complete and maximum granular control but tries -// to off most common functionallity across all supported devices. +// to offer most common functionality across all supported devices. #include "IRac.h" #ifndef UNIT_TEST @@ -18,7 +18,9 @@ #include "IRutils.h" #include "ir_Amcor.h" #include "ir_Argo.h" +#include "ir_Carrier.h" #include "ir_Coolix.h" +#include "ir_Corona.h" #include "ir_Daikin.h" #include "ir_Electra.h" #include "ir_Fujitsu.h" @@ -40,6 +42,10 @@ #include "ir_Vestel.h" #include "ir_Whirlpool.h" +/// Class constructor +/// @param[in] pin Gpio pin to use when transmitting IR messages. +/// @param[in] inverted true, gpio output defaults to high. false, to low. +/// @param[in] use_modulation true means use frequency modulation. false, don't. IRac::IRac(const uint16_t pin, const bool inverted, const bool use_modulation) { _pin = pin; _inverted = inverted; @@ -48,6 +54,29 @@ IRac::IRac(const uint16_t pin, const bool inverted, const bool use_modulation) { this->markAsSent(); } +/// Initialse the given state with the supplied settings. +/// @param[out] state A Ptr to where the settings will be stored. +/// @param[in] vendor The vendor/protocol type. +/// @param[in] model The A/C model if applicable. +/// @param[in] power The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @param[in] beep Enable/Disable beeps when receiving IR messages. +/// @param[in] sleep Nr. of minutes for sleep mode. +/// -1 is Off, >= 0 is on. Some devices it is the nr. of mins to run for. +/// Others it may be the time to enter/exit sleep mode. +/// i.e. Time in Nr. of mins since midnight. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, @@ -78,6 +107,9 @@ void IRac::initState(stdAc::state_t *state, state->clock = clock; } +/// Initialse the given state with the supplied settings. +/// @param[out] state A Ptr to where the settings will be stored. +/// @note Sets all the parameters to reasonable base/automatic defaults. void IRac::initState(stdAc::state_t *state) { initState(state, decode_type_t::UNKNOWN, -1, false, stdAc::opmode_t::kOff, 25, true, // 25 degrees Celsius @@ -86,11 +118,18 @@ void IRac::initState(stdAc::state_t *state) { false, -1, -1); } +/// Get the current internal A/C climate state. +/// @return A Ptr to a state containing the current (to be sent) settings. stdAc::state_t IRac::getState(void) { return next; } +/// Get the previous internal A/C climate state that should have already been +/// sent to the device. i.e. What the A/C unit should already be set to. +/// @return A Ptr to a state containing the previously sent settings. stdAc::state_t IRac::getStatePrev(void) { return _prev; } -// Is the given protocol supported by the IRac class? +/// Is the given protocol supported by the IRac class? +/// @param[in] protocol The vendor/protocol type. +/// @return true if the protocol is supported by this class, otherwise false. bool IRac::isProtocolSupported(const decode_type_t protocol) { switch (protocol) { #if SEND_AMCOR @@ -99,9 +138,15 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_ARGO case decode_type_t::ARGO: #endif +#if SEND_CARRIER_AC64 + case decode_type_t::CARRIER_AC64: +#endif // SEND_CARRIER_AC64 #if SEND_COOLIX case decode_type_t::COOLIX: #endif +#if SEND_CORONA_AC + case decode_type_t::CORONA_AC: +#endif #if SEND_DAIKIN case decode_type_t::DAIKIN: #endif @@ -153,6 +198,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_HITACHI_AC1 case decode_type_t::HITACHI_AC1: #endif +#if SEND_HITACHI_AC344 + case decode_type_t::HITACHI_AC344: +#endif #if SEND_HITACHI_AC424 case decode_type_t::HITACHI_AC424: #endif @@ -209,13 +257,25 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_WHIRLPOOL_AC case decode_type_t::WHIRLPOOL_AC: #endif +// Note: Compiler Warning is disabled because someone could disable all +// the protocols before this and it is then unreachable. +// "-Wswitch-unreachable" not used as it appears to be an unknown option. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wall" return true; +#pragma GCC diagnostic pop default: return false; } } #if SEND_AMCOR +/// Send an Amcor A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRAmcorAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. void IRac::amcor(IRAmcorAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan) { @@ -238,6 +298,16 @@ void IRac::amcor(IRAmcorAc *ac, #endif // SEND_AMCOR #if SEND_ARGO +/// Send an Argo A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRArgoAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] sleep Nr. of minutes for sleep mode. +/// @note -1 is Off, >= 0 is on. void IRac::argo(IRArgoAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, @@ -260,7 +330,53 @@ void IRac::argo(IRArgoAC *ac, } #endif // SEND_ARGO +#if SEND_CARRIER_AC64 +/// Send a Carrier 64-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRCarrierAc64 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] sleep Nr. of minutes for sleep mode. +/// @note -1 is Off, >= 0 is on. +void IRac::carrier64(IRCarrierAc64 *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const int16_t sleep) { + ac->begin(); + ac->setPower(on); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees); + ac->setFan(ac->convertFan(fan)); + ac->setSwingV((int8_t)swingv >= 0); + // No Quiet setting available. + // No Light setting available. + // No Filter setting available. + // No Turbo setting available. + // No Economy setting available. + // No Clean setting available. + // No Beep setting available. + ac->setSleep(sleep >= 0); // Convert to a boolean. + ac->send(); +} +#endif // SEND_CARRIER_AC64 + #if SEND_COOLIX +/// Send a Coolix A/C message with the supplied settings. +/// @note May result in multiple messages being sent. +/// @param[in, out] ac A Ptr to an IRCoolixAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @param[in] sleep Nr. of minutes for sleep mode. +/// @note -1 is Off, >= 0 is on. void IRac::coolix(IRCoolixAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -312,7 +428,51 @@ void IRac::coolix(IRCoolixAC *ac, } #endif // SEND_COOLIX +#if SEND_CORONA_AC +/// Send a Corona A/C message with the supplied settings. +/// @note May result in multiple messages being sent. +/// @param[in, out] ac A Ptr to an IRCoronaAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] econo Run the device in economical mode. +void IRac::corona(IRCoronaAc *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool econo) { + ac->begin(); + ac->setPower(on); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees); + ac->setFan(ac->convertFan(fan)); + ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff); + // No Quiet setting available. + // No Light setting available. + // No Filter setting available. + // No Turbo setting available. + ac->setEcono(econo); + // No Clean setting available. + // No Beep setting available. + // No Sleep setting available. + ac->send(); +} +#endif // SEND_CARRIER_AC64 + #if SEND_DAIKIN +/// Send a Daikin A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikinESP object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc void IRac::daikin(IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -340,6 +500,19 @@ void IRac::daikin(IRDaikinESP *ac, #endif // SEND_DAIKIN #if SEND_DAIKIN128 +/// Send a Daikin 128-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin128 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::daikin128(IRDaikin128 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -367,6 +540,16 @@ void IRac::daikin128(IRDaikin128 *ac, #endif // SEND_DAIKIN128 #if SEND_DAIKIN152 +/// Send a Daikin 152-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin152 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. void IRac::daikin152(IRDaikin152 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -393,6 +576,13 @@ void IRac::daikin152(IRDaikin152 *ac, #endif // SEND_DAIKIN152 #if SEND_DAIKIN160 +/// Send a Daikin 160-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin160 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. void IRac::daikin160(IRDaikin160 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -408,6 +598,13 @@ void IRac::daikin160(IRDaikin160 *ac, #endif // SEND_DAIKIN160 #if SEND_DAIKIN176 +/// Send a Daikin 176-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin176 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingh The horizontal swing setting. void IRac::daikin176(IRDaikin176 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -423,6 +620,23 @@ void IRac::daikin176(IRDaikin176 *ac, #endif // SEND_DAIKIN176 #if SEND_DAIKIN2 +/// Send a Daikin2 A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin2 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @param[in] beep Enable/Disable beeps when receiving IR messages. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::daikin2(IRDaikin2 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -452,6 +666,16 @@ void IRac::daikin2(IRDaikin2 *ac, #endif // SEND_DAIKIN2 #if SEND_DAIKIN216 +/// Send a Daikin 216-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin216 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. void IRac::daikin216(IRDaikin216 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -471,6 +695,17 @@ void IRac::daikin216(IRDaikin216 *ac, #endif // SEND_DAIKIN216 #if SEND_DAIKIN64 +/// Send a Daikin 64-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin64 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::daikin64(IRDaikin64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -492,6 +727,15 @@ void IRac::daikin64(IRDaikin64 *ac, #endif // SEND_DAIKIN64 #if SEND_DELONGHI_AC +/// Send a Delonghi A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDelonghiAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. void IRac::delonghiac(IRDelonghiAc *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, @@ -508,6 +752,17 @@ void IRac::delonghiac(IRDelonghiAc *ac, #endif // SEND_DELONGHI_AC #if SEND_ELECTRA_AC +/// Send an Electra A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRElectraAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] lighttoggle Should we toggle the LED/Display? +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc void IRac::electra(IRElectraAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -536,6 +791,20 @@ void IRac::electra(IRElectraAc *ac, #endif // SEND_ELECTRA_AC #if SEND_FUJITSU_AC +/// Send a Fujitsu A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRFujitsuAC object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc void IRac::fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -589,6 +858,16 @@ void IRac::fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, #endif // SEND_FUJITSU_AC #if SEND_GOODWEATHER +/// Send a Goodweather A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRGoodweatherAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. void IRac::goodweather(IRGoodweatherAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -618,6 +897,19 @@ void IRac::goodweather(IRGoodweatherAc *ac, #endif // SEND_GOODWEATHER #if SEND_GREE +/// Send a Gree A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRGreeAC object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, @@ -646,6 +938,16 @@ void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model, #endif // SEND_GREE #if SEND_HAIER_AC +/// Send a Haier A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRGreeAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::haier(IRHaierAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, @@ -673,6 +975,16 @@ void IRac::haier(IRHaierAC *ac, #endif // SEND_HAIER_AC #if SEND_HAIER_AC_YRW02 +/// Send a Haier YRWO2 A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHaierACYRW02 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. void IRac::haierYrwo2(IRHaierACYRW02 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -697,6 +1009,14 @@ void IRac::haierYrwo2(IRHaierACYRW02 *ac, #endif // SEND_HAIER_AC_YRW02 #if SEND_HITACHI_AC +/// Send a Hitachi A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHitachiAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. void IRac::hitachi(IRHitachiAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -721,6 +1041,19 @@ void IRac::hitachi(IRHitachiAc *ac, #endif // SEND_HITACHI_AC #if SEND_HITACHI_AC1 +/// Send a Hitachi1 A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHitachiAc1 object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] power_toggle The power toggle setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] swing_toggle The swing_toggle setting. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. +/// @note The sleep mode used is the "Sleep 2" setting. void IRac::hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, const bool on, const bool power_toggle, const stdAc::opmode_t mode, @@ -751,7 +1084,49 @@ void IRac::hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, } #endif // SEND_HITACHI_AC1 +#if SEND_HITACHI_AC344 +/// Send a Hitachi 344-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHitachiAc344 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +void IRac::hitachi344(IRHitachiAc344 *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, + const stdAc::swingh_t swingh) { + ac->begin(); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees); + ac->setFan(ac->convertFan(fan)); + ac->setSwingH(ac->convertSwingH(swingh)); + ac->setPower(on); + // No Quiet setting available. + // No Turbo setting available. + // No Light setting available. + // No Filter setting available. + // No Clean setting available. + // No Beep setting available. + // No Sleep setting available. + // No Clock setting available. + + // SwingVToggle is special. Needs to be last method called. + ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff); + ac->send(); +} +#endif // SEND_HITACHI_AC344 + #if SEND_HITACHI_AC424 +/// Send a Hitachi 424-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHitachiAc424 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. void IRac::hitachi424(IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -777,6 +1152,19 @@ void IRac::hitachi424(IRHitachiAc424 *ac, #endif // SEND_HITACHI_AC424 #if SEND_KELVINATOR +/// Send a Kelvinator A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRKelvinatorAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. XFan, dry filters etc void IRac::kelvinator(IRKelvinatorAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -804,6 +1192,13 @@ void IRac::kelvinator(IRKelvinatorAC *ac, #endif // SEND_KELVINATOR #if SEND_LG +/// Send a LG A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRLgAc object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan) { @@ -828,6 +1223,15 @@ void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model, #endif // SEND_LG #if SEND_MIDEA +/// Send a Midea A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMideaAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. void IRac::midea(IRMideaAC *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, @@ -853,6 +1257,17 @@ void IRac::midea(IRMideaAC *ac, #endif // SEND_MIDEA #if SEND_MITSUBISHI_AC +/// Send a Mitsubishi A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishiAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. +/// @note Clock can only be set in 10 minute increments. i.e. % 10. void IRac::mitsubishi(IRMitsubishiAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -879,6 +1294,15 @@ void IRac::mitsubishi(IRMitsubishiAC *ac, #endif // SEND_MITSUBISHI_AC #if SEND_MITSUBISHI112 +/// Send a Mitsubishi 112-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishi112 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. void IRac::mitsubishi112(IRMitsubishi112 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -907,6 +1331,14 @@ void IRac::mitsubishi112(IRMitsubishi112 *ac, #endif // SEND_MITSUBISHI112 #if SEND_MITSUBISHI136 +/// Send a Mitsubishi 136-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishi136 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. void IRac::mitsubishi136(IRMitsubishi136 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -931,6 +1363,17 @@ void IRac::mitsubishi136(IRMitsubishi136 *ac, #endif // SEND_MITSUBISHI136 #if SEND_MITSUBISHIHEAVY +/// Send a Mitsubishi Heavy 88-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishiHeavy88Ac object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc void IRac::mitsubishiHeavy88(IRMitsubishiHeavy88Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -958,6 +1401,20 @@ void IRac::mitsubishiHeavy88(IRMitsubishiHeavy88Ac *ac, ac->send(); } +/// Send a Mitsubishi Heavy 152-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishiHeavy152Ac object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. void IRac::mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -988,6 +1445,18 @@ void IRac::mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac, #endif // SEND_MITSUBISHIHEAVY #if SEND_NEOCLIMA +/// Send a Neoclima A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRNeoclimaAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. void IRac::neoclima(IRNeoclimaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -1015,6 +1484,19 @@ void IRac::neoclima(IRNeoclimaAc *ac, #endif // SEND_NEOCLIMA #if SEND_PANASONIC_AC +/// Send a Panasonic A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRPanasonicAc object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::panasonic(IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -1043,6 +1525,22 @@ void IRac::panasonic(IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, #endif // SEND_PANASONIC_AC #if SEND_SAMSUNG_AC +/// Send a Samsung A/C message with the supplied settings. +/// @note Multiple IR messages may be generated & sent. +/// @param[in, out] ac A Ptr to an IRSamsungAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @param[in] beep Enable/Disable beeps when receiving IR messages. +/// @param[in] prevpower The power setting from the previous A/C state. +/// @param[in] forcepower Do we force send the special power message? void IRac::samsung(IRSamsungAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -1075,6 +1573,18 @@ void IRac::samsung(IRSamsungAc *ac, #endif // SEND_SAMSUNG_AC #if SEND_SHARP_AC +/// Send a Sharp A/C message with the supplied settings. +/// @note Multiple IR messages may be generated & sent. +/// @param[in, out] ac A Ptr to an IRSharpAc object to use. +/// @param[in] on The power setting. +/// @param[in] prev_power The power setting from the previous A/C state. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc void IRac::sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, @@ -1115,6 +1625,18 @@ void IRac::sharp(IRSharpAc *ac, #endif // SEND_SHARP_AC #if SEND_TCL112AC +/// Send a TCL 112-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRTcl112Ac object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. void IRac::tcl112(IRTcl112Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -1142,6 +1664,15 @@ void IRac::tcl112(IRTcl112Ac *ac, #endif // SEND_TCL112AC #if SEND_TECO +/// Send a Teco A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRTecoAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. void IRac::teco(IRTecoAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, @@ -1166,6 +1697,12 @@ void IRac::teco(IRTecoAc *ac, #endif // SEND_TECO #if SEND_TOSHIBA_AC +/// Send a Toshiba A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRToshibaAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. void IRac::toshiba(IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan) { @@ -1189,6 +1726,13 @@ void IRac::toshiba(IRToshibaAC *ac, #endif // SEND_TOSHIBA_AC #if SEND_TROTEC +/// Send a Trotec A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRTrotecESP object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. void IRac::trotec(IRTrotecESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -1213,6 +1757,19 @@ void IRac::trotec(IRTrotecESP *ac, #endif // SEND_TROTEC #if SEND_VESTEL_AC +/// Send a Vestel A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRVestelAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. +/// @param[in] sendNormal Do we send a Normal settings message at all? +/// i.e In addition to the clock/time/timer message void IRac::vestel(IRVestelAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -1242,6 +1799,18 @@ void IRac::vestel(IRVestelAc *ac, #endif // SEND_VESTEL_AC #if SEND_WHIRLPOOL_AC +/// Send a Whirlpool A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRWhirlpoolAc object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -1268,12 +1837,11 @@ void IRac::whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, } #endif // SEND_WHIRLPOOL_AC -// Create a new state base on the provided state that has been suitably fixed. -// Args: -// state: The state_t structure describing the desired a/c state. -// -// Returns: -// A stdAc::state_t with the needed settings. +/// Create a new state base on the provided state that has been suitably fixed. +/// @note This is for use with Home Assistant, which requires mode to be off if +/// the power is off. +/// @param[in] state The state_t structure describing the desired a/c state. +/// @return A stdAc::state_t with the needed settings. stdAc::state_t IRac::cleanState(const stdAc::state_t state) { stdAc::state_t result = state; // A hack for Home Assistant, it appears to need/want an Off opmode. @@ -1282,14 +1850,11 @@ stdAc::state_t IRac::cleanState(const stdAc::state_t state) { return result; } -// Create a new state base on desired & previous states but handle -// any state changes for options that need to be toggled. -// Args: -// desired: The state_t structure describing the desired a/c state. -// prev: Ptr to the previous state_t structure. -// -// Returns: -// A stdAc::state_t with the needed settings. +/// Create a new state base on desired & previous states but handle +/// any state changes for options that need to be toggled. +/// @param[in] desired The state_t structure describing the desired a/c state. +/// @param[in] prev A Ptr to the previous state_t structure. +/// @return A stdAc::state_t with the needed settings. stdAc::state_t IRac::handleToggles(const stdAc::state_t desired, const stdAc::state_t *prev) { stdAc::state_t result = desired; @@ -1316,6 +1881,8 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired, case decode_type_t::ELECTRA_AC: result.light = desired.light ^ prev->light; break; + case decode_type_t::CORONA_AC: + case decode_type_t::HITACHI_AC344: case decode_type_t::HITACHI_AC424: case decode_type_t::MIDEA: case decode_type_t::SHARP_AC: @@ -1341,29 +1908,30 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired, return result; } -// Send A/C message for a given device using common A/C settings. -// Args: -// vendor: The type of A/C protocol to use. -// model: The specific model of A/C if supported/applicable. -// on: Should the unit be powered on? (or in some cases, toggled) -// mode: What operating mode should the unit perform? e.g. Cool, Heat etc. -// degrees: What temperature should the unit be set to? -// celsius: Use degrees Celsius, otherwise Fahrenheit. -// fan: Fan speed. -// The following args are all "if supported" by the underlying A/C classes. -// swingv: Control the vertical swing of the vanes. -// swingh: Control the horizontal swing of the vanes. -// quiet: Set the unit to quiet (fan) operation mode. -// turbo: Set the unit to turbo operating mode. e.g. Max fan & cooling etc. -// econo: Set the unit to economical operating mode. -// light: Turn on the display/LEDs etc. -// filter: Turn on any particle/ion/allergy filter etc. -// clean: Turn on any settings to reduce mold etc. (Not self-clean mode.) -// beep: Control if the unit beeps upon receiving commands. -// sleep: Nr. of mins of sleep mode, or use sleep mode. (< 0 means off.) -// clock: Nr. of mins past midnight to set the clock to. (< 0 means off.) -// Returns: -// boolean: True, if accepted/converted/attempted. False, if unsupported. +/// Send A/C message for a given device using common A/C settings. +/// @param[in] vendor The vendor/protocol type. +/// @param[in] model The A/C model if applicable. +/// @param[in] power The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit. +/// @param[in] fan The speed setting for the fan. +/// @note The following are all "if supported" by the underlying A/C classes. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @param[in] beep Enable/Disable beeps when receiving IR messages. +/// @param[in] sleep Nr. of minutes for sleep mode. +/// -1 is Off, >= 0 is on. Some devices it is the nr. of mins to run for. +/// Others it may be the time to enter/exit sleep mode. +/// i.e. Time in Nr. of mins since midnight. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. +/// @return True, if accepted/converted/attempted etc. False, if unsupported. bool IRac::sendAc(const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, @@ -1379,17 +1947,14 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model, return this->sendAc(to_send, &to_send); } -// Send A/C message for a given device using state_t structures. -// Args: -// desired: The state_t structure describing the desired new a/c state. -// prev: Ptr to the previous state_t structure. -// -// Returns: -// boolean: True, if accepted/converted/attempted. False, if unsupported. +/// Send A/C message for a given device using state_t structures. +/// @param[in] desired The state_t structure describing the desired new ac state +/// @param[in] prev A Ptr to the state_t structure containing the previous state +/// @return True, if accepted/converted/attempted etc. False, if unsupported. bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { // Convert the temp from Fahrenheit to Celsius if we are not in Celsius mode. - float degC = desired.celsius ? desired.degrees - : fahrenheitToCelsius(desired.degrees); + float degC __attribute__((unused)) = + desired.celsius ? desired.degrees : fahrenheitToCelsius(desired.degrees); // special `state_t` that is required to be sent based on that. stdAc::state_t send = this->handleToggles(this->cleanState(desired), prev); // Per vendor settings & setup. @@ -1411,6 +1976,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { break; } #endif // SEND_ARGO +#if SEND_CARRIER_AC64 + case CARRIER_AC64: + { + IRCarrierAc64 ac(_pin, _inverted, _modulation); + carrier64(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv, + send.sleep); + break; + } +#endif // SEND_CARRIER_AC64 #if SEND_COOLIX case COOLIX: { @@ -1420,6 +1994,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { break; } #endif // SEND_COOLIX +#if SEND_CORONA_AC + case CORONA_AC: + { + IRCoronaAc ac(_pin, _inverted, _modulation); + corona(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv, + send.econo); + break; + } +#endif // SEND_CORONA_AC #if SEND_DAIKIN case DAIKIN: { @@ -1585,6 +2168,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { break; } #endif // SEND_HITACHI_AC1 +#if SEND_HITACHI_AC344 + case HITACHI_AC344: + { + IRHitachiAc344 ac(_pin, _inverted, _modulation); + hitachi344(&ac, send.power, send.mode, degC, send.fanspeed, + send.swingv, send.swingh); + break; + } +#endif // SEND_HITACHI_AC344 #if SEND_HITACHI_AC424 case HITACHI_AC424: { @@ -1766,24 +2358,24 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { return true; // Success. } -// Update the previous state to the current one. +/// Update the previous state to the current one. void IRac::markAsSent(void) { _prev = next; } -// Send an A/C message based soley on our internal state. -// -// Returns: -// boolean: True, if accepted/converted/attempted. False, if unsupported. +/// Send an A/C message based soley on our internal state. +/// @return True, if accepted/converted/attempted. False, if unsupported. bool IRac::sendAc(void) { bool success = this->sendAc(next, &_prev); if (success) this->markAsSent(); return success; } -// Compare two AirCon states. -// Returns: True if they differ, False if they don't. -// Note: Excludes clock. +/// Compare two AirCon states. +/// @note The comparison excludes the clock. +/// @param a A state_t to be compared. +/// @param b A state_t to be compared. +/// @return True if they differ, False if they don't. bool IRac::cmpStates(const stdAc::state_t a, const stdAc::state_t b) { return a.protocol != b.protocol || a.model != b.model || a.power != b.power || a.mode != b.mode || a.degrees != b.degrees || a.celsius != b.celsius || @@ -1793,10 +2385,17 @@ bool IRac::cmpStates(const stdAc::state_t a, const stdAc::state_t b) { a.clean != b.clean || a.beep != b.beep || a.sleep != b.sleep; } +/// Check if the internal state has changed from what was previously sent. +/// @note The comparison excludes the clock. +/// @return True if it has changed, False if not. bool IRac::hasStateChanged(void) { return cmpStates(next, _prev); } +/// Convert the supplied str into the appropriate enum. +/// @param[in] str A Ptr to a C-style string to be converted. +/// @param[in] def The enum to return if no conversion was possible. +/// @return The equivilent enum. stdAc::opmode_t IRac::strToOpmode(const char *str, - const stdAc::opmode_t def) { + const stdAc::opmode_t def) { if (!strcasecmp(str, kAutoStr) || !strcasecmp(str, kAutomaticStr)) return stdAc::opmode_t::kAuto; @@ -1821,6 +2420,10 @@ stdAc::opmode_t IRac::strToOpmode(const char *str, return def; } +/// Convert the supplied str into the appropriate enum. +/// @param[in] str A Ptr to a C-style string to be converted. +/// @param[in] def The enum to return if no conversion was possible. +/// @return The equivilent enum. stdAc::fanspeed_t IRac::strToFanspeed(const char *str, const stdAc::fanspeed_t def) { if (!strcasecmp(str, kAutoStr) || @@ -1848,6 +2451,10 @@ stdAc::fanspeed_t IRac::strToFanspeed(const char *str, return def; } +/// Convert the supplied str into the appropriate enum. +/// @param[in] str A Ptr to a C-style string to be converted. +/// @param[in] def The enum to return if no conversion was possible. +/// @return The equivilent enum. stdAc::swingv_t IRac::strToSwingV(const char *str, const stdAc::swingv_t def) { if (!strcasecmp(str, kAutoStr) || @@ -1885,6 +2492,10 @@ stdAc::swingv_t IRac::strToSwingV(const char *str, return def; } +/// Convert the supplied str into the appropriate enum. +/// @param[in] str A Ptr to a C-style string to be converted. +/// @param[in] def The enum to return if no conversion was possible. +/// @return The equivilent enum. stdAc::swingh_t IRac::strToSwingH(const char *str, const stdAc::swingh_t def) { if (!strcasecmp(str, kAutoStr) || @@ -1920,7 +2531,11 @@ stdAc::swingh_t IRac::strToSwingH(const char *str, return def; } -// Assumes str is the model code or an integer >= 1. +/// Convert the supplied str into the appropriate enum. +/// @note Assumes str is the model code or an integer >= 1. +/// @param[in] str A Ptr to a C-style string to be converted. +/// @param[in] def The enum to return if no conversion was possible. +/// @return The equivilent enum. int16_t IRac::strToModel(const char *str, const int16_t def) { // Gree if (!strcasecmp(str, "YAW1F")) { @@ -1972,6 +2587,10 @@ int16_t IRac::strToModel(const char *str, const int16_t def) { } } +/// Convert the supplied str into the appropriate boolean value. +/// @param[in] str A Ptr to a C-style string to be converted. +/// @param[in] def The boolean value to return if no conversion was possible. +/// @return The equivilent boolean value. bool IRac::strToBool(const char *str, const bool def) { if (!strcasecmp(str, kOnStr) || !strcasecmp(str, "1") || @@ -1987,10 +2606,16 @@ bool IRac::strToBool(const char *str, const bool def) { return def; } +/// Convert the supplied boolean into the appropriate String. +/// @param[in] value The boolean value to be converted. +/// @return The equivilent String for the locale. String IRac::boolToString(const bool value) { return value ? kOnStr : kOffStr; } +/// Convert the supplied operation mode into the appropriate String. +/// @param[in] mode The enum to be converted. +/// @return The equivilent String for the locale. String IRac::opmodeToString(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kOff: @@ -2010,6 +2635,9 @@ String IRac::opmodeToString(const stdAc::opmode_t mode) { } } +/// Convert the supplied fan speed enum into the appropriate String. +/// @param[in] speed The enum to be converted. +/// @return The equivilent String for the locale. String IRac::fanspeedToString(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kAuto: @@ -2029,6 +2657,9 @@ String IRac::fanspeedToString(const stdAc::fanspeed_t speed) { } } +/// Convert the supplied enum into the appropriate String. +/// @param[in] swingv The enum to be converted. +/// @return The equivilent String for the locale. String IRac::swingvToString(const stdAc::swingv_t swingv) { switch (swingv) { case stdAc::swingv_t::kOff: @@ -2050,6 +2681,9 @@ String IRac::swingvToString(const stdAc::swingv_t swingv) { } } +/// Convert the supplied enum into the appropriate String. +/// @param[in] swingh The enum to be converted. +/// @return The equivilent String for the locale. String IRac::swinghToString(const stdAc::swingh_t swingh) { switch (swingh) { case stdAc::swingh_t::kOff: @@ -2074,11 +2708,11 @@ String IRac::swinghToString(const stdAc::swingh_t swingh) { } namespace IRAcUtils { - // Display the human readable state of an A/C message if we can. - // Args: - // result: A Ptr to the captured `decode_results` that contains an A/C mesg. - // Returns: - // A string with the human description of the A/C message. "" if we can't. + /// Display the human readable state of an A/C message if we can. + /// @param[in] result A Ptr to the captured `decode_results` that contains an + /// A/C mesg. + /// @return A string with the human description of the A/C message. + /// An empty string if we can't. String resultAcToString(const decode_results * const result) { switch (result->decode_type) { #if DECODE_AMCOR @@ -2095,6 +2729,13 @@ namespace IRAcUtils { return ac.toString(); } #endif // DECODE_ARGO +#if DECODE_CARRIER_AC64 + case decode_type_t::CARRIER_AC64: { + IRCarrierAc64 ac(kGpioUnused); + ac.setRaw(result->value); // CARRIER_AC64 uses value instead of state. + return ac.toString(); + } +#endif // DECODE_CARRIER_AC64 #if DECODE_DAIKIN case decode_type_t::DAIKIN: { IRDaikinESP ac(0); @@ -2290,6 +2931,13 @@ namespace IRAcUtils { return ac.toString(); } #endif // DECODE_COOLIX +#if DECODE_CORONA_AC + case decode_type_t::CORONA_AC: { + IRCoronaAc ac(kGpioUnused); + ac.setRaw(result->state, result->bits / 8); + return ac.toString(); + } +#endif // DECODE_CORONA_AC #if DECODE_PANASONIC_AC case decode_type_t::PANASONIC_AC: { if (result->bits > kPanasonicAcShortBits) { @@ -2314,6 +2962,13 @@ namespace IRAcUtils { return ac.toString(); } #endif // DECODE_HITACHI_AC1 +#if DECODE_HITACHI_AC344 + case decode_type_t::HITACHI_AC344: { + IRHitachiAc344 ac(kGpioUnused); + ac.setRaw(result->state); + return ac.toString(); + } +#endif // DECODE_HITACHI_AC344 #if DECODE_HITACHI_AC424 case decode_type_t::HITACHI_AC424: { IRHitachiAc424 ac(0); @@ -2369,17 +3024,20 @@ namespace IRAcUtils { } } - // Convert a valid IR A/C remote message that we understand enough into a - // Common A/C state. - // - // Args: - // decode: A PTR to a successful raw IR decode object. - // result: A PTR to a state structure to store the result in. - // prev: A PTR to a state structure which has the prev. state. (optional) - // Returns: - // A boolean indicating success or failure. + /// Convert a valid IR A/C remote message that we understand enough into a + /// Common A/C state. + /// @param[in] decode A PTR to a successful raw IR decode object. + /// @param[in] result A PTR to a state structure to store the result in. + /// @param[in] prev A PTR to a state structure which has the prev. state. + /// @return A boolean indicating success or failure. bool decodeToState(const decode_results *decode, stdAc::state_t *result, - const stdAc::state_t *prev) { + const stdAc::state_t *prev +/// @cond IGNORE +// *prev flagged as "unused" due to potential compiler warning when some +// protocols that use it are disabled. It really is used. + __attribute__((unused)) +/// @endcond + ) { if (decode == NULL || result == NULL) return false; // Safety check. switch (decode->decode_type) { #if DECODE_AMCOR @@ -2406,6 +3064,22 @@ namespace IRAcUtils { break; } #endif // DECODE_COOLIX +#if DECODE_CORONA_AC + case decode_type_t::CORONA_AC: { + IRCoronaAc ac(kGpioUnused); + ac.setRaw(decode->state, decode->bits / 8); + *result = ac.toCommon(); + break; + } +#endif // DECODE_CARRIER_AC64 +#if DECODE_CARRIER_AC64 + case decode_type_t::CARRIER_AC64: { + IRCarrierAc64 ac(kGpioUnused); + ac.setRaw(decode->value); // Uses value instead of state. + *result = ac.toCommon(); + break; + } +#endif // DECODE_CARRIER_AC64 #if DECODE_DAIKIN case decode_type_t::DAIKIN: { IRDaikinESP ac(kGpioUnused); @@ -2542,6 +3216,14 @@ namespace IRAcUtils { break; } #endif // DECODE_HITACHI_AC1 +#if DECODE_HITACHI_AC344 + case decode_type_t::HITACHI_AC344: { + IRHitachiAc344 ac(kGpioUnused); + ac.setRaw(decode->state); + *result = ac.toCommon(); + break; + } +#endif // DECODE_HITACHI_AC344 #if DECODE_HITACHI_AC424 case decode_type_t::HITACHI_AC424: { IRHitachiAc424 ac(kGpioUnused); diff --git a/lib/IRremoteESP8266-2.7.7/src/IRac.h b/lib/IRremoteESP8266-2.7.8/src/IRac.h similarity index 94% rename from lib/IRremoteESP8266-2.7.7/src/IRac.h rename to lib/IRremoteESP8266-2.7.8/src/IRac.h index 42c59321c..01365a180 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRac.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRac.h @@ -9,7 +9,9 @@ #include "IRremoteESP8266.h" #include "ir_Amcor.h" #include "ir_Argo.h" +#include "ir_Carrier.h" #include "ir_Coolix.h" +#include "ir_Corona.h" #include "ir_Daikin.h" #include "ir_Delonghi.h" #include "ir_Fujitsu.h" @@ -86,7 +88,7 @@ class IRac { stdAc::state_t getState(void); stdAc::state_t getStatePrev(void); bool hasStateChanged(void); - stdAc::state_t next; // The state we want the device to be in after we send. + stdAc::state_t next; ///< The state we want the device to be in after we send #ifndef UNIT_TEST private: @@ -106,6 +108,12 @@ class IRac { const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const int16_t sleep = -1); #endif // SEND_ARGO +#if SEND_CARRIER_AC64 +void carrier64(IRCarrierAc64 *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const int16_t sleep = -1); +#endif // SEND_CARRIER_AC64 #if SEND_COOLIX void coolix(IRCoolixAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -114,6 +122,12 @@ class IRac { const bool turbo, const bool light, const bool clean, const int16_t sleep = -1); #endif // SEND_COOLIX +#if SEND_CORONA_AC + void corona(IRCoronaAc *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool econo); +#endif // SEND_CORONA_AC #if SEND_DAIKIN void daikin(IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -242,6 +256,13 @@ void electra(IRElectraAc *ac, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool swing_toggle, const int16_t sleep = -1); #endif // SEND_HITACHI_AC1 +#if SEND_HITACHI_AC344 + void hitachi344(IRHitachiAc344 *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, + const stdAc::swingh_t swingh); +#endif // SEND_HITACHI_AC344 #if SEND_HITACHI_AC424 void hitachi424(IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, diff --git a/lib/IRremoteESP8266-2.7.7/src/IRrecv.cpp b/lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp similarity index 61% rename from lib/IRremoteESP8266-2.7.7/src/IRrecv.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp index 316cf59c6..efddcc17c 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRrecv.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp @@ -62,11 +62,19 @@ irparams_t *irparams_save; // A copy of the interrupt state while decoding. #ifndef UNIT_TEST #if defined(ESP8266) +/// Interrupt handler for when the timer runs out. +/// It signals to the library that capturing of IR data has stopped. +/// @param[in] arg Unused. (ESP8266 Only) static void USE_IRAM_ATTR read_timeout(void *arg __attribute__((unused))) { os_intr_lock(); #endif // ESP8266 +/// @cond IGNORE #if defined(ESP32) +/// Interrupt handler for when the timer runs out. +/// It signals to the library that capturing of IR data has stopped. +/// @note ESP32 version static void USE_IRAM_ATTR read_timeout(void) { +/// @endcond portENTER_CRITICAL(&irremote_mux); #endif // ESP32 if (irparams.rawlen) irparams.rcvstate = kStopState; @@ -78,6 +86,7 @@ static void USE_IRAM_ATTR read_timeout(void) { #endif // ESP32 } +/// Interrupt handler for changes on the GPIO pin handling incoming IR messages. static void USE_IRAM_ATTR gpio_intr() { uint32_t now = micros(); static uint32_t start = 0; @@ -128,17 +137,17 @@ static void USE_IRAM_ATTR gpio_intr() { // Start of IRrecv class ------------------- -// Class constructor -// Args: -// recvpin: GPIO pin the IR receiver module's data pin is connected to. -// bufsize: Nr. of entries to have in the capture buffer. (Default: kRawBuf) -// timeout: Nr. of milli-Seconds of no signal before we stop capturing data. -// (Default: kTimeoutMs) -// save_buffer: Use a second (save) buffer to decode from. (Default: false) -// timer_num: Which ESP32 timer number to use? ESP32 only, otherwise unused. -// (Range: 0-3. Default: kDefaultESP32Timer) -// Returns: -// An IRrecv class object. +/// Class constructor +/// Args: +/// @param[in] recvpin The GPIO pin the IR receiver module's data pin is +/// connected to. +/// @param[in] bufsize Nr. of entries to have in the capture buffer. +/// (Default: kRawBuf) +/// @param[in] timeout Nr. of milli-Seconds of no signal before we stop +/// capturing data. (Default: kTimeoutMs) +/// @param[in] save_buffer Use a second (save) buffer to decode from. +/// (Default: false) +/// @param[in] timer_num Nr. of the ESP32 timer to use (0 to 3) (ESP32 Only) #if defined(ESP32) IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, const uint8_t timeout, const bool save_buffer, @@ -146,8 +155,20 @@ IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, // There are only 4 timers. 0 to 3. _timer_num = std::min(timer_num, (uint8_t)3); #else // ESP32 +/// @cond IGNORE +/// Class constructor +/// Args: +/// @param[in] recvpin The GPIO pin the IR receiver module's data pin is +/// connected to. +/// @param[in] bufsize Nr. of entries to have in the capture buffer. +/// (Default: kRawBuf) +/// @param[in] timeout Nr. of milli-Seconds of no signal before we stop +/// capturing data. (Default: kTimeoutMs) +/// @param[in] save_buffer Use a second (save) buffer to decode from. +/// (Default: false) IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, const uint8_t timeout, const bool save_buffer) { +/// @endcond #endif // ESP32 irparams.recvpin = recvpin; irparams.bufsize = bufsize; @@ -185,24 +206,25 @@ IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, _tolerance = kTolerance; } -// Class destructor +/// Class destructor +/// Cleans up after the object is no longer needed. +/// e.g. Frees up all memory used by the various buffers, and disables any +/// timers or interrupts used. IRrecv::~IRrecv(void) { + disableIRIn(); +#if defined(ESP32) + if (timer != NULL) timerEnd(timer); // Cleanup the ESP32 timeout timer. +#endif // ESP32 delete[] irparams.rawbuf; if (irparams_save != NULL) { delete[] irparams_save->rawbuf; delete irparams_save; } - disableIRIn(); -#if defined(ESP32) - if (timer != NULL) timerEnd(timer); // Cleanup the ESP32 timeout timer. -#endif // ESP32 } -// Set up and (re)start the IR capture mechanism. -// -// Args: -// pullup: A flag indicating should the GPIO use the internal pullup resistor. -// (Default: `false`. i.e. No.) +/// Set up and (re)start the IR capture mechanism. +/// @param[in] pullup A flag indicating should the GPIO use the internal pullup +/// resistor. (Default: `false`. i.e. No.) void IRrecv::enableIRIn(const bool pullup) { // ESP32's seem to require explicitly setting the GPIO to INPUT etc. // This wasn't required on the ESP8266s, but it shouldn't hurt to make sure. @@ -237,6 +259,8 @@ void IRrecv::enableIRIn(const bool pullup) { #endif // UNIT_TEST } +/// Stop collection of any received IR data. +/// Disable any timers and interrupts. void IRrecv::disableIRIn(void) { #ifndef UNIT_TEST #if defined(ESP8266) @@ -249,6 +273,10 @@ void IRrecv::disableIRIn(void) { #endif // UNIT_TEST } +/// Resume collection of received IR data. +/// @note This is required if `decode()` is successful and `save_buffer` was +/// not set when the class was instanciated. +/// @see IRrecv class constructor void IRrecv::resume(void) { irparams.rcvstate = kIdleState; irparams.rawlen = 0; @@ -258,14 +286,12 @@ void IRrecv::resume(void) { #endif // ESP32 } -// Make a copy of the interrupt state & buffer data. -// Needed because irparams is marked as volatile, thus memcpy() isn't allowed. -// Only call this when you know the interrupt handlers won't modify anything. -// i.e. In kStopState. -// -// Args: -// src: Pointer to an irparams_t structure to copy from. -// dst: Pointer to an irparams_t structure to copy to. +/// Make a copy of the interrupt state & buffer data. +/// Needed because irparams is marked as volatile, thus memcpy() isn't allowed. +/// Only call this when you know the interrupt handlers won't modify anything. +/// i.e. In kStopState. +/// @param[in] src Pointer to an irparams_t structure to copy from. +/// @param[out] dst Pointer to an irparams_t structure to copy to. void IRrecv::copyIrParams(volatile irparams_t *src, irparams_t *dst) { // Typecast src and dst addresses to (char *) char *csrc = (char *)src; // NOLINT(readability/casting) @@ -287,31 +313,35 @@ void IRrecv::copyIrParams(volatile irparams_t *src, irparams_t *dst) { for (uint16_t i = 0; i < dst->bufsize; i++) dst->rawbuf[i] = src->rawbuf[i]; } -// Obtain the maximum number of entries possible in the capture buffer. -// i.e. It's size. +/// Obtain the maximum number of entries possible in the capture buffer. +/// i.e. It's size. +/// @return The size of the buffer that is in use by the object. uint16_t IRrecv::getBufSize(void) { return irparams.bufsize; } #if DECODE_HASH -// Set the minimum length we will consider for reporting UNKNOWN message types. +/// Set the minimum length we will consider for reporting UNKNOWN message types. +/// @param[in] length Min nr. of mark/space pulses required to be considered. void IRrecv::setUnknownThreshold(const uint16_t length) { _unknown_threshold = length; } #endif // DECODE_HASH -// Set the base tolerance percentage for matching incoming IR messages. +/// Set the base tolerance percentage for matching incoming IR messages. +/// @param[in] percent An integer percentage. (0-100) void IRrecv::setTolerance(const uint8_t percent) { _tolerance = std::min(percent, (uint8_t)100); } -// Get the base tolerance percentage for matching incoming IR messages. +/// Get the base tolerance percentage for matching incoming IR messages. +/// @return A integer percentage. uint8_t IRrecv::getTolerance(void) { return _tolerance; } #if ENABLE_NOISE_FILTER_OPTION -// Remove or merge pulses in the capture buffer that are too short. -// Args: -// results: Ptr to the decode_results we are going to filter/modify. -// floor: Only allow values in the buffer large than this. (in micro seconds) +/// Remove or merge pulses in the capture buffer that are too short. +/// @param[in,out] results Ptr to the decode_results we are going to filter. +/// @param[in] floor Only allow values in the buffer large than this. +/// (in microSeconds) void IRrecv::crudeNoiseFilter(decode_results *results, const uint16_t floor) { if (floor == 0) return; // Nothing to do. const uint16_t kTickFloor = floor / kRawTick; @@ -338,49 +368,44 @@ void IRrecv::crudeNoiseFilter(decode_results *results, const uint16_t floor) { } #endif // ENABLE_NOISE_FILTER_OPTION -// Decodes the received IR message. -// If the interrupt state is saved, we will immediately resume waiting -// for the next IR message to avoid missing messages. -// Note: There is a trade-off here. Saving the state means less time lost until -// we can receiving the next message vs. using more RAM. Choose appropriately. -// -// Args: -// results: A pointer to where the decoded IR message will be stored. -// save: A pointer to an irparams_t instance in which to save -// the interrupt's memory/state. NULL means don't save it. -// max_skip: Maximum Nr. of pulses at the begining of a capture we can skip -// when attempting to find a protocol we can successfully decode. -// This parameter can dramatically improve detection of protocols -// when there is light IR interference just before an incoming IR -// message, however, it comes at a steep performace price. -// CAUTION: Increasing this value will dramatically (linnearly) -// increase the cpu time & usage to decode protocols. -// e.g. 0 -> 1 will be a 2x increase in cpu usage/time. -// 0 -> 2 will be a 3x increase etc. -// If you are going to do this, consider disabling -// protocol decoding for protocols you are not expecting. -// (Default is 0. No skipping.) -// noise_floor: Pulses below this size (in usecs) will be removed or merged -// prior to any decoding. This is to try to remove noise/poor -// readings & slighly increase the chances of a successful -// decode but at the cost of data fidelity & integrity. -// (Defaults to 0 usecs. i.e. Don't filter; which is safe!) -// DANGER: **Here Be Dragons!** -// If you set the `filter_floor` value too high, it **WILL** -// break decoding of some protocols. You have been warned! -// **Any** non-zero value has the potential to **cook** the -// captured raw data. i.e. The data is going to lie to you. -// It may obscure hardware, circuit, & environment issues thus -// making it impossible to support you accurately or -// confidently. -// Values of <= 50 usecs will probably be safe. -// 51 - 100 usecs **might** be okay. -// 100 - 150 usecs is "Danger, Will Robinson!". -// 150 - 200 usecs expect broken protocols. -// At 200+ usecs, you **have** protocols you can't decode!! -// -// Returns: -// A boolean indicating if an IR message is ready or not. +/// Decodes the received IR message. +/// If the interrupt state is saved, we will immediately resume waiting +/// for the next IR message to avoid missing messages. +/// @note There is a trade-off here. Saving the state means less time lost until +/// we can receiving the next message vs. using more RAM. Choose appropriately. +/// @param[out] results A PTR to where the decoded IR message will be stored. +/// @param[out] save A PTR to an irparams_t instance in which to save +/// the interrupt's memory/state. NULL means don't save it. +/// @param[in] max_skip Maximum Nr. of pulses at the begining of a capture we +/// can skip when attempting to find a protocol we can successfully decode. +/// This parameter can dramatically improve detection of protocols +/// when there is light IR interference just before an incoming IR +/// message, however, it comes at a steep performace price. +/// (Default is 0. No skipping.) +/// @warning Increasing the `max_skip` value will dramatically (linearly) +/// increase the cpu time & usage to decode protocols. +/// e.g. 0 -> 1 will be a 2x increase in cpu usage/time. +/// 0 -> 2 will be a 3x increase etc. +/// If you are going to do this, consider disabling protocol decoding for +/// protocols you are not expecting. +/// @param[in] noise_floor Pulses below this size (in usecs) will be removed or +/// merged prior to any decoding. This is to try to remove noise/poor +/// readings & slighly increase the chances of a successful decode but at the +/// cost of data fidelity & integrity. +/// (Defaults to 0 usecs. i.e. Don't filter; which is safe!) +/// @warning DANGER: **Here Be Dragons!** +/// If you set the `noise_floor` value too high, it **WILL** break decoding +/// of some protocols. You have been warned! +/// **Any** non-zero value has the potential to **cook** the captured raw data +/// i.e. The raw data is going to lie to you. +/// It may obscure hardware, circuit, & environment issues thus making it +/// impossible to support you accurately or confidently. +/// Values of <= 50 usecs will probably be safe. +/// 51 - 100 usecs **might** be okay. +/// 100 - 150 usecs is "Danger, Will Robinson!". +/// 150 - 200 usecs expect broken protocols. +/// At 200+ usecs, you **have** protocols you can't decode!! +/// @return A boolean indicating if an IR message is ready or not. bool IRrecv::decode(decode_results *results, irparams_t *save, uint8_t max_skip, uint16_t noise_floor) { // Proceed only if an IR message been received. @@ -663,6 +688,12 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, decodeHitachiAc3(results, offset, kHitachiAc3MinBits)) return true; #endif // DECODE_HITACHI_AC3 +#if DECODE_HITACHI_AC344 + // HitachiAC344 should be checked before HitachiAC + DPRINTLN("Attempting Hitachi AC344 decode"); + if (decodeHitachiAC(results, offset, kHitachiAc344Bits, true, false)) + return true; +#endif // DECODE_HITACHI_AC344 #if DECODE_HITACHI_AC2 // HitachiAC2 should be checked before HitachiAC DPRINTLN("Attempting Hitachi AC2 decode"); @@ -809,6 +840,18 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, DPRINTLN("Attempting Carrier 64bit decode"); if (decodeCarrierAC64(results, offset)) return true; #endif // DECODE_CARRIER_AC64 +#if DECODE_CORONA_AC + DPRINTLN("Attempting CoronaAc decode"); + if (decodeCoronaAc(results, offset)) return true; +#endif // DECODE_CORONA_AC +#if DECODE_MIDEA24 + DPRINTLN("Attempting Midea-Nec decode"); + if (decodeMidea24(results, offset)) return true; +#endif // DECODE_MIDEA24 +#if DECODE_ZEPEAL + DPRINTLN("Attempting Zepeal decode"); + if (decodeZepeal(results, offset)) return true; +#endif // DECODE_ZEPEAL // Typically new protocols are added above this line. } #if DECODE_HASH @@ -825,19 +868,17 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, return false; } -// Convert the tolerance percentage into something valid. +/// Convert the tolerance percentage into something valid. +/// @param[in] percentage An integer percentage. uint8_t IRrecv::_validTolerance(const uint8_t percentage) { return (percentage > 100) ? _tolerance : percentage; } -// Calculate the lower bound of the nr. of ticks. -// -// Args: -// usecs: Nr. of uSeconds. -// tolerance: Percent as an integer. e.g. 10 is 10% -// delta: A non-scaling amount to reduce usecs by. -// Returns: -// Nr. of ticks. +/// Calculate the lower bound of the nr. of ticks. +/// @param[in] usecs Nr. of uSeconds. +/// @param[in] tolerance Percent as an integer. e.g. 10 is 10% +/// @param[in] delta A non-scaling amount to reduce usecs by. +/// @return Nr. of ticks. uint32_t IRrecv::ticksLow(const uint32_t usecs, const uint8_t tolerance, const uint16_t delta) { // max() used to ensure the result can't drop below 0 before the cast. @@ -846,31 +887,24 @@ uint32_t IRrecv::ticksLow(const uint32_t usecs, const uint8_t tolerance, 0)); } -// Calculate the upper bound of the nr. of ticks. -// -// Args: -// usecs: Nr. of uSeconds. -// tolerance: Percent as an integer. e.g. 10 is 10% -// delta: A non-scaling amount to increase usecs by. -// Returns: -// Nr. of ticks. +/// Calculate the upper bound of the nr. of ticks. +/// @param[in] usecs Nr. of uSeconds. +/// @param[in] tolerance Percent as an integer. e.g. 10 is 10% +/// @param[in] delta A non-scaling amount to increase usecs by. +/// @return Nr. of ticks. uint32_t IRrecv::ticksHigh(const uint32_t usecs, const uint8_t tolerance, const uint16_t delta) { return ((uint32_t)(usecs * (1.0 + _validTolerance(tolerance) / 100.0)) + 1 + delta); } -// Check if we match a pulse(measured) with the desired within -// +/-tolerance percent and/or +/- a fixed delta range. -// -// Args: -// measured: The recorded period of the signal pulse. -// desired: The expected period (in useconds) we are matching against. -// tolerance: A percentage expressed as an integer. e.g. 10 is 10%. -// delta: A non-scaling (+/-) error margin (in useconds). -// -// Returns: -// Boolean: true if it matches, false if it doesn't. +/// Check if we match a pulse(measured) with the desired within +/// +/-tolerance percent and/or +/- a fixed delta range. +/// @param[in] measured The recorded period of the signal pulse. +/// @param[in] desired The expected period (in usecs) we are matching against. +/// @param[in] tolerance A percentage expressed as an integer. e.g. 10 is 10%. +/// @param[in] delta A non-scaling (+/-) error margin (in useconds). +/// @return A Boolean. true if it matches, false if it doesn't. bool IRrecv::match(uint32_t measured, uint32_t desired, uint8_t tolerance, uint16_t delta) { measured *= kRawTick; // Convert to uSecs. @@ -895,18 +929,13 @@ bool IRrecv::match(uint32_t measured, uint32_t desired, uint8_t tolerance, measured <= ticksHigh(desired, tolerance, delta)); } -// Check if we match a pulse(measured) of at least desired within -// tolerance percent and/or a fixed delta margin. -// -// Args: -// measured: The recorded period of the signal pulse. -// desired: The expected period (in useconds) we are matching against. -// tolerance: A percentage expressed as an integer. e.g. 10 is 10%. -// delta: A non-scaling amount to reduce usecs by. - -// -// Returns: -// Boolean: true if it matches, false if it doesn't. +/// Check if we match a pulse(measured) of at least desired within +/// tolerance percent and/or a fixed delta margin. +/// @param[in] measured The recorded period of the signal pulse. +/// @param[in] desired The expected period (in usecs) we are matching against. +/// @param[in] tolerance A percentage expressed as an integer. e.g. 10 is 10%. +/// @param[in] delta A non-scaling amount to reduce usecs by. +/// @return A Boolean. true if it matches, false if it doesn't. bool IRrecv::matchAtLeast(uint32_t measured, uint32_t desired, uint8_t tolerance, uint16_t delta) { measured *= kRawTick; // Convert to uSecs. @@ -942,17 +971,13 @@ bool IRrecv::matchAtLeast(uint32_t measured, uint32_t desired, tolerance, delta); } -// Check if we match a mark signal(measured) with the desired within -// +/-tolerance percent, after an expected is excess is added. -// -// Args: -// measured: The recorded period of the signal pulse. -// desired: The expected period (in useconds) we are matching against. -// tolerance: A percentage expressed as an integer. e.g. 10 is 10%. -// excess: Nr. of useconds. -// -// Returns: -// Boolean: true if it matches, false if it doesn't. +/// Check if we match a mark signal(measured) with the desired within +/// +/-tolerance percent, after an expected is excess is added. +/// @param[in] measured The recorded period of the signal pulse. +/// @param[in] desired The expected period (in usecs) we are matching against. +/// @param[in] tolerance A percentage expressed as an integer. e.g. 10 is 10%. +/// @param[in] excess A non-scaling amount to reduce usecs by. +/// @return A Boolean. true if it matches, false if it doesn't. bool IRrecv::matchMark(uint32_t measured, uint32_t desired, uint8_t tolerance, int16_t excess) { DPRINT("Matching MARK "); @@ -965,17 +990,13 @@ bool IRrecv::matchMark(uint32_t measured, uint32_t desired, uint8_t tolerance, return match(measured, desired + excess, tolerance); } -// Check if we match a space signal(measured) with the desired within -// +/-tolerance percent, after an expected is excess is removed. -// -// Args: -// measured: The recorded period of the signal pulse. -// desired: The expected period (in useconds) we are matching against. -// tolerance: A percentage expressed as an integer. e.g. 10 is 10%. -// excess: Nr. of useconds. -// -// Returns: -// Boolean: true if it matches, false if it doesn't. +/// Check if we match a space signal(measured) with the desired within +/// +/-tolerance percent, after an expected is excess is removed. +/// @param[in] measured The recorded period of the signal pulse. +/// @param[in] desired The expected period (in usecs) we are matching against. +/// @param[in] tolerance A percentage expressed as an integer. e.g. 10 is 10%. +/// @param[in] excess A non-scaling amount to reduce usecs by. +/// @return A Boolean. true if it matches, false if it doesn't. bool IRrecv::matchSpace(uint32_t measured, uint32_t desired, uint8_t tolerance, int16_t excess) { DPRINT("Matching SPACE "); @@ -988,23 +1009,12 @@ bool IRrecv::matchSpace(uint32_t measured, uint32_t desired, uint8_t tolerance, return match(measured, desired - excess, tolerance); } -/* ----------------------------------------------------------------------- - * hashdecode - decode an arbitrary IR code. - * Instead of decoding using a standard encoding scheme - * (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. - * - * The algorithm: look at the sequence of MARK signals, and see if each one - * is shorter (0), the same length (1), or longer (2) than the previous. - * Do the same with the SPACE signals. Hash the resulting sequence of 0's, - * 1's, and 2's to a 32-bit value. This will give a unique value for each - * different code (probably), for most code systems. - * - * http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html - */ - -// Compare two tick values, returning 0 if newval is shorter, -// 1 if newval is equal, and 2 if newval is longer -// Use a tolerance of 20% +#if DECODE_HASH +/// Compare two tick values. +/// @param[in] oldval Nr. of ticks. +/// @param[in] newval Nr. of ticks. +/// @return 0 if newval is shorter, 1 if it is equal, & 2 if it is longer. +/// @note Use a tolerance of 20% uint16_t IRrecv::compare(const uint16_t oldval, const uint16_t newval) { if (newval < oldval * 0.8) return 0; @@ -1014,11 +1024,18 @@ uint16_t IRrecv::compare(const uint16_t oldval, const uint16_t newval) { return 1; } -#if DECODE_HASH -/* Converts the raw code values into a 32-bit hash code. - * Hopefully this code is unique for each button. - * This isn't a "real" decoding, just an arbitrary value. - */ +/// Decode any arbitrary IR message into a 32-bit code value. +/// Instead of decoding using a standard encoding scheme +/// (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. +/// +/// The algorithm: look at the sequence of MARK signals, and see if each one +/// is shorter (0), the same length (1), or longer (2) than the previous. +/// Do the same with the SPACE signals. Hash the resulting sequence of 0's, +/// 1's, and 2's to a 32-bit value. This will give a unique value for each +/// different code (probably), for most code systems. +/// @see http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html +/// @note This isn't a "real" decoding, just an arbitrary value. +/// Hopefully this code is unique for each button. bool IRrecv::decodeHash(decode_results *results) { // Require at least some samples to prevent triggering on noise if (results->rawlen < _unknown_threshold) return false; @@ -1041,23 +1058,21 @@ bool IRrecv::decodeHash(decode_results *results) { } #endif // DECODE_HASH -// Match & decode the typical data section of an IR message. -// The data value is stored in the least significant bits reguardless of the -// bit ordering requested. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// nbits: Nr. of data bits we expect. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A match_result_t structure containing the success (or not), the data value, -// and how many buffer entries were used. +/// Match & decode the typical data section of an IR message. +/// The data value is stored in the least significant bits reguardless of the +/// bit ordering requested. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return A match_result_t structure containing the success (or not), the +/// data value, and how many buffer entries were used. match_result_t IRrecv::matchData( volatile uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -1084,24 +1099,22 @@ match_result_t IRrecv::matchData( return result; } -// Match & decode the typical data section of an IR message. -// The bytes are stored at result_ptr. The first byte in the result equates to -// the first byte encountered, and so on. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// result_ptr: A pointer to where to start storing the bytes we decoded. -// remaining: The size of the capture buffer are remaining. -// nbytes: Nr. of data bytes we expect. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. +/// Match & decode the typical data section of an IR message. +/// The bytes are stored at result_ptr. The first byte in the result equates to +/// the first byte encountered, and so on. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @param[out] result_ptr A ptr to where to start storing the bytes we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbytes Nr. of data bytes we expect. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. uint16_t IRrecv::matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, @@ -1122,33 +1135,36 @@ uint16_t IRrecv::matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, return offset; } -// Match & decode a generic/typical IR message. -// The data is stored in result_bits_ptr or result_bytes_ptr depending on flag -// `use_bits`. -// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip -// that requirement. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// result_bits_ptr: A pointer to where to start storing the bits we decoded. -// result_bytes_ptr: A pointer to where to start storing the bytes we decoded. -// use_bits: A flag indicating if we are to decode bits or bytes. -// remaining: The size of the capture buffer are remaining. -// nbits: Nr. of data bits we expect. -// hdrmark: Nr. of uSeconds for the expected header mark signal. -// hdrspace: Nr. of uSeconds for the expected header space signal. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// footermark: Nr. of uSeconds for the expected footer mark signal. -// footerspace: Nr. of uSeconds for the expected footer space/gap signal. -// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. +/// Match & decode a generic/typical IR message. +/// The data is stored in result_bits_ptr or result_bytes_ptr depending on flag +/// `use_bits`. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @param[out] result_bits_ptr A pointer to where to start storing the bits we +/// decoded. +/// @param[out] result_bytes_ptr A pointer to where to start storing the bytes +/// we decoded. +/// @param[in] use_bits A flag indicating if we are to decode bits or bytes. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. uint16_t IRrecv::_matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_bytes_ptr, @@ -1224,30 +1240,31 @@ uint16_t IRrecv::_matchGeneric(volatile uint16_t *data_ptr, return offset; } -// Match & decode a generic/typical <= 64bit IR message. -// The data is stored at result_ptr. -// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip -// that requirement. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// result_ptr: A pointer to where to start storing the bits we decoded. -// remaining: The size of the capture buffer are remaining. -// nbits: Nr. of data bits we expect. -// hdrmark: Nr. of uSeconds for the expected header mark signal. -// hdrspace: Nr. of uSeconds for the expected header space signal. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// footermark: Nr. of uSeconds for the expected footer mark signal. -// footerspace: Nr. of uSeconds for the expected footer space/gap signal. -// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. +/// Match & decode a generic/typical <= 64bit IR message. +/// The data is stored at result_ptr. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// +/// @param[in] data_ptr: A pointer to where we are at in the capture buffer. +/// @param[out] result_ptr A ptr to where to start storing the bits we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, @@ -1270,31 +1287,31 @@ uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, tolerance, excess, MSBfirst); } -// Match & decode a generic/typical > 64bit IR message. -// The bytes are stored at result_ptr. The first byte in the result equates to -// the first byte encountered, and so on. -// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip -// that requirement. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// result_ptr: A pointer to where to start storing the bytes we decoded. -// remaining: The size of the capture buffer are remaining. -// nbits: Nr. of data bits we expect. -// hdrmark: Nr. of uSeconds for the expected header mark signal. -// hdrspace: Nr. of uSeconds for the expected header space signal. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// footermark: Nr. of uSeconds for the expected footer mark signal. -// footerspace: Nr. of uSeconds for the expected footer space/gap signal. -// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. +/// Match & decode a generic/typical > 64bit IR message. +/// The bytes are stored at result_ptr. The first byte in the result equates to +/// the first byte encountered, and so on. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// @param[in] data_ptr: A pointer to where we are at in the capture buffer. +/// @param[out] result_ptr A ptr to where to start storing the bytes we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, @@ -1317,31 +1334,31 @@ uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, tolerance, excess, MSBfirst); } -// Match & decode a generic/typical constant bit time <= 64bit IR message. -// The data is stored at result_ptr. -// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip -// that requirement. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// result_ptr: A pointer to where to start storing the bits we decoded. -// remaining: The size of the capture buffer are remaining. -// nbits: Nr. of data bits we expect. -// hdrmark: Nr. of uSeconds for the expected header mark signal. -// hdrspace: Nr. of uSeconds for the expected header space signal. -// one: Nr. of uSeconds in an expected mark signal for a '1' bit. -// zero: Nr. of uSeconds in an expected mark signal for a '0' bit. -// footermark: Nr. of uSeconds for the expected footer mark signal. -// footerspace: Nr. of uSeconds for the expected footer space/gap signal. -// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. -// -// Note: one + zero add up to the total time for a bit. -// e.g. mark(one) + space(zero) is a `1`, mark(zero) + space(one) is a `0`. +/// Match & decode a generic/typical constant bit time <= 64bit IR message. +/// The data is stored at result_ptr. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @note `data_ptr` is assumed to be pointing to a "Mark", not a "Space". +/// @param[out] result_ptr A ptr to where to start storing the bits we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] one Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] zero Nr. of uSeconds in an expected mark signal for a '0' bit. +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. +/// @note Parameters one + zero add up to the total time for a bit. +/// e.g. mark(one) + space(zero) is a `1`, mark(zero) + space(one) is a `0`. uint16_t IRrecv::matchGenericConstBitTime(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, @@ -1403,33 +1420,32 @@ uint16_t IRrecv::matchGenericConstBitTime(volatile uint16_t *data_ptr, return offset; } -// Match & decode a Manchester Code <= 64bit IR message. -// The data is stored at result_ptr. -// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip -// that requirement. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// NOTE: It is assumed to be pointing to a "Mark", not a "Space". -// result_ptr: A pointer to where to start storing the bits we decoded. -// remaining: The size of the capture buffer are remaining. -// nbits: Nr. of data bits we expect. -// hdrmark: Nr. of uSeconds for the expected header mark signal. -// hdrspace: Nr. of uSeconds for the expected header space signal. -// half_period: Nr. of uSeconds for half the clock's period. (1/2 wavelength) -// footermark: Nr. of uSeconds for the expected footer mark signal. -// footerspace: Nr. of uSeconds for the expected footer space/gap signal. -// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// GEThomas: Use G.E. Thomas (true/default) or IEEE 802.3 (false) convention? -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. -// -// Ref: -// https://en.wikipedia.org/wiki/Manchester_code -// http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf +/// Match & decode a Manchester Code <= 64bit IR message. +/// The data is stored at result_ptr. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @note `data_ptr` is assumed to be pointing to a "Mark", not a "Space". +/// @param[out] result_ptr A ptr to where to start storing the bits we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] half_period Nr. of uSeconds for half the clock's period. +/// i.e. 1/2 wavelength +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @param[in] GEThomas Use G.E. Thomas (true) or IEEE 802.3 (false) convention? +/// @return If successful, how many buffer entries were used. Otherwise 0. +/// @see https://en.wikipedia.org/wiki/Manchester_code +/// @see http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, @@ -1445,15 +1461,12 @@ uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, const bool MSBfirst, const bool GEThomas) { uint16_t offset = 0; - uint64_t data = 0; - uint16_t nr_of_half_periods = GEThomas; - // 2 per bit, and 4 extra for the timing sync. - uint16_t expected_half_periods = 2 * nbits + 4; - bool currentBit = false; + uint16_t bank = 0; + uint16_t entry = 0; // Calculate how much remaining buffer is required. - // Shortest case. Longest case is 2 * nbits. - uint16_t min_remaining = nbits + 2; + // Shortest case is nbits. Longest case is 2 * nbits. + uint16_t min_remaining = nbits; if (hdrmark) min_remaining++; if (hdrspace) min_remaining++; @@ -1464,86 +1477,45 @@ uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, if (remaining < min_remaining) return 0; // Nope, so abort. // Header - if (hdrmark && !matchMark(*(data_ptr + offset++), hdrmark, tolerance, excess)) - return 0; - // Manchester Code always has a guaranteed 2x half_period (T2) at the start - // of the data section. e.g. a sync header. If it is a GEThomas-style, then - // it is space(T);mark(2xT);space(T), thus we need to check for that space - // plus any requested "header" space. - if ((hdrspace || GEThomas) && - !matchSpace(*(data_ptr + offset++), - hdrspace + ((GEThomas) ? half_period : 0), tolerance, excess)) - return 0; - - // Data - // Loop until we find a 'long' pulse. This is the timing sync per protocol. - while ((offset < remaining) && (nr_of_half_periods < expected_half_periods) && - !match(*(data_ptr + offset), half_period * 2, tolerance, excess)) { - // Was it not a short pulse? - if (!match(*(data_ptr + offset), half_period, tolerance, excess)) - return 0; - nr_of_half_periods++; - offset++; - } - - // Data (cont.) - - // We are now pointing to the first 'long' pulse. - // Loop through the buffer till we run out of buffer, or nr of half periods. - while (offset < remaining && nr_of_half_periods < expected_half_periods) { - // Only if there is enough half_periods left for a long pulse & - // Is it a 'long' pulse? - if (nr_of_half_periods < expected_half_periods - 1 && - match(*(data_ptr + offset), half_period * 2, tolerance, excess)) { - // Yes, so invert the value we will append. - currentBit = !currentBit; - nr_of_half_periods += 2; // A 'long' pulse is two half periods. - offset++; - // Append the bit value. - data <<= 1; - data |= currentBit; - } else if (match(*(data_ptr + offset), half_period, tolerance, excess)) { - // or is it part of a 'short' pulse pair? - nr_of_half_periods++; - offset++; - // Look for the second half of the 'short' pulse pair. - // Do we have enough buffer or nr of half periods? - if (offset < remaining && nr_of_half_periods < expected_half_periods) { - // We do, so look for it. - if (match(*(data_ptr + offset), half_period, tolerance, excess)) { - // Found it! - nr_of_half_periods++; - // No change of the polarity of the bit we will append. - // Append the bit value. - data <<= 1; - data |= currentBit; - offset++; - } else { - // It's not what we expected. - return 0; - } + if (hdrmark) { + entry = *(data_ptr + offset++); + if (!hdrspace) { // If we have no Header Space ... + // Do we have a data 'mark' half period merged with the header mark? + if (matchMark(entry, hdrmark + half_period, + tolerance, excess)) { + // Looks like we do. + bank = entry * kRawTick - hdrmark; + } else if (!matchMark(entry, hdrmark, tolerance, excess)) { + return 0; // It's not a normal header mark, so fail. } - } else if (nr_of_half_periods == expected_half_periods - 1 && - matchAtLeast(*(data_ptr + offset), half_period, tolerance, - excess)) { - // Special case when we are at the end of the expected nr of periods. - // i.e. The pulse could be merged with the footer. - nr_of_half_periods++; - break; - } else { - // It's neither, so abort. - return 0; + } else if (!matchMark(entry, hdrmark, tolerance, excess)) { + return 0; // It's not a normal header mark, so fail. + } + } + if (hdrspace) { + entry = *(data_ptr + offset++); + // Check to see if the header space has merged with a data space half period + if (matchSpace(entry, hdrspace + half_period, tolerance, excess)) { + // Looks like we do. + bank = entry * kRawTick - hdrspace; + } else if (!matchSpace(entry, hdrspace, tolerance, excess)) { + return 0; // It's not a normal header space, so fail. } } - // Did we collect the expected amount of data? - if (nr_of_half_periods < expected_half_periods) return 0; + if (!match(bank / kRawTick, half_period, tolerance, excess)) bank = 0; + // Data + uint16_t used = matchManchesterData(data_ptr + offset, result_ptr, + remaining - offset, nbits, half_period, + bank, tolerance, excess, MSBfirst, + GEThomas); + if (!used) return 0; // Data did match. + offset += used; // Footer if (footermark && !(matchMark(*(data_ptr + offset), footermark + half_period, tolerance, excess) || - matchMark(*(data_ptr + offset), footermark, - tolerance, excess))) + matchMark(*(data_ptr + offset), footermark, tolerance, excess))) return 0; offset++; // If we have something still to match & haven't reached the end of the buffer @@ -1552,15 +1524,127 @@ uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, if (!matchAtLeast(*(data_ptr + offset), footerspace, tolerance, excess)) return 0; } else { - if (!matchSpace(*(data_ptr + offset), footerspace, tolerance, excess)) + if (!matchSpace(*(data_ptr + offset), footerspace, tolerance, excess) && + !matchSpace(*(data_ptr + offset), footerspace + half_period, + tolerance, excess)) return 0; } offset++; } + return offset; +} + +/// Match & decode a Manchester Code data (<= 64bits. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @note `data_ptr` is assumed to be pointing to a "Mark", not a "Space". +/// @param[out] result_ptr A ptr to where to start storing the bits we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] half_period Nr. of uSeconds for half the clock's period. +/// i.e. 1/2 wavelength +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] starting_balance Amount of uSeconds to assume exists prior to +/// the current value pointed too. +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @param[in] GEThomas Use G.E. Thomas (true) or IEEE 802.3 (false) convention? +/// @return If successful, how many buffer entries were used. Otherwise 0. +/// @see https://en.wikipedia.org/wiki/Manchester_code +/// @see http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf +/// @todo Clean up and optimise this. It is just "get it working code" atm. +uint16_t IRrecv::matchManchesterData(volatile const uint16_t *data_ptr, + uint64_t *result_ptr, + const uint16_t remaining, + const uint16_t nbits, + const uint16_t half_period, + const uint16_t starting_balance, + const uint8_t tolerance, + const int16_t excess, + const bool MSBfirst, + const bool GEThomas) { + uint16_t offset = 0; + uint64_t data = 0; + uint16_t nr_half_periods = 0; + const uint16_t expected_half_periods = nbits * 2; + // Flip the bit if we have a starting balance. ie. Carry over from the header. + bool currentBit = starting_balance ? !GEThomas : GEThomas; + const uint16_t raw_half_period = half_period / kRawTick; + + // Calculate how much remaining buffer is required. + // Shortest case is nbits. Longest case is 2 * nbits. + uint16_t min_remaining = nbits; + + // Check if there is enough capture buffer to possibly have the message. + if (remaining < min_remaining) return 0; // Nope, so abort. + + // Convert to ticks. Optimisation: Saves on math/extra instructions later. + uint16_t bank = starting_balance / kRawTick; + + // Data + // Loop through the buffer till we run out of buffer, or nr of half periods. + // Possible patterns are: + // short + short = 1 bit (Add the value of the previous bit again) + // short + long + short = 2 bits (Add the previous bit again, then flip & add) + // short + long + long + short = 3 bits (add prev, flip & add, flip & add) + // We can't start with a long. + // + // The general approach is thus: + // Check we have a short interval, next or in the bank. + // If the next timing value is long, act according and reset the bank to + // a short balance. + // or + // If it is short, act accordingly and declare the bank empty. + // Repeat. + while ((offset < remaining || bank) && + nr_half_periods < expected_half_periods) { + // Get the next entry if we haven't anything existing to process. + if (!bank) bank = *(data_ptr + offset++); + // Check if we don't have a short interval. + if (!match(bank, half_period, tolerance, excess)) return 0; // Not valid. + // We've succeeded in matching half a period, so count it. + nr_half_periods++; + // We've now used up our bank, so refill it with the next item, unless we + // are at the end of the capture buffer. + // If we are assume a single half period of "space". + if (offset < remaining) + bank = *(data_ptr + offset++); + else if (offset == remaining) + bank = raw_half_period; + else + return 0; // We are out of buffer, so abort! + + // Shift the data along and add our new bit. + data <<= 1; + data |= currentBit; + + // Check if we have a long interval. + if (match(bank, half_period * 2, tolerance, excess)) { + // It is, so flip the bit we need to append, and remove a half_period of + // time from the bank. + currentBit = !currentBit; + bank -= raw_half_period; + } else if (match(bank, half_period, tolerance, excess)) { + // It is a short interval, so eat up all the time and move on. + bank = 0; + } else if (nr_half_periods == expected_half_periods - 1 && + matchAtLeast(bank, half_period, tolerance, excess)) { + // We are at the end of the data & it is a short interval, so eat up all + // the time and move on. + bank = 0; + // Reduce the offset as we are at the end of the data doing a + // matchAtLeast() because we could be processing part of a footer. + offset--; + } else { + // The length isn't what we expected (neither long or short), so bail. + return 0; + } + nr_half_periods++; + } // Clean up and process the data. if (!MSBfirst) data = reverseBits(data, nbits); - // Trim the data to size to remove timing sync. + // Trim the data to size. *result_ptr = GETBITS64(data, 0, nbits); return offset; } diff --git a/lib/IRremoteESP8266-2.7.7/src/IRrecv.h b/lib/IRremoteESP8266-2.7.8/src/IRrecv.h similarity index 93% rename from lib/IRremoteESP8266-2.7.7/src/IRrecv.h rename to lib/IRremoteESP8266-2.7.8/src/IRrecv.h index 2894683ac..36da8df1b 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRrecv.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRrecv.h @@ -64,7 +64,8 @@ const uint16_t kStateSizeMax = 0; #endif // Types -// information for the interrupt handler + +/// Information for the interrupt handler typedef struct { uint8_t recvpin; // pin for IR data from detector uint8_t rcvstate; // state machine @@ -78,7 +79,7 @@ typedef struct { uint8_t timeout; // Nr. of milliSeconds before we give up. } irparams_t; -// results from a data match +/// Results from a data match typedef struct { bool success; // Was the match successful? uint64_t data; // The data found. @@ -87,7 +88,7 @@ typedef struct { // Classes -// Results returned from the decoder +/// Results returned from the decoder class decode_results { public: decode_type_t decode_type; // NEC, SONY, RC5, UNKNOWN @@ -109,7 +110,7 @@ class decode_results { bool repeat; // Is the result a repeat code? }; -// main class for receiving IR +/// Class for receiving IR messages. class IRrecv { public: #if defined(ESP32) @@ -235,6 +236,16 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); + uint16_t matchManchesterData(volatile const uint16_t *data_ptr, + uint64_t *result_ptr, + const uint16_t remaining, + const uint16_t nbits, + const uint16_t half_period, + const uint16_t starting_balance = 0, + const uint8_t tolerance = kUseDefTol, + const int16_t excess = kMarkExcess, + const bool MSBfirst = true, + const bool GEThomas = true); uint16_t matchManchester(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, @@ -251,7 +262,7 @@ class IRrecv { const bool GEThomas = true); void crudeNoiseFilter(decode_results *results, const uint16_t floor = 0); bool decodeHash(decode_results *results); -#if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || SEND_SANYO) +#if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || DECODE_SANYO) bool decodeNEC(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kNECBits, const bool strict = true); #endif @@ -311,9 +322,9 @@ class IRrecv { #endif #if (DECODE_RC5 || DECODE_R6 || DECODE_LASERTAG || DECODE_MWM) int16_t getRClevel(decode_results *results, uint16_t *offset, uint16_t *used, - uint16_t bitTime, uint8_t tolerance = kUseDefTol, - int16_t excess = kMarkExcess, uint16_t delta = 0, - uint8_t maxwidth = 3); + uint16_t bitTime, const uint8_t tolerance = kUseDefTol, + const int16_t excess = kMarkExcess, + const uint16_t delta = 0, const uint8_t maxwidth = 3); #endif #if DECODE_RC5 bool decodeRC5(decode_results *results, uint16_t offset = kStartOffset, @@ -470,7 +481,12 @@ class IRrecv { bool decodeMidea(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kMideaBits, const bool strict = true); -#endif +#endif // DECODE_MIDEA +#if DECODE_MIDEA24 + bool decodeMidea24(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kMidea24Bits, + const bool strict = true); +#endif // DECODE_MIDEA24 #if DECODE_FUJITSU_AC bool decodeFujitsuAC(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kFujitsuAcBits, @@ -520,10 +536,10 @@ class IRrecv { const uint16_t nbits = kHaierACYRW02Bits, const bool strict = true); #endif -#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2) +#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC344) bool decodeHitachiAC(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kHitachiAcBits, - const bool strict = true); + const bool strict = true, const bool MSBfirst = true); #endif #if DECODE_HITACHI_AC1 bool decodeHitachiAC1(decode_results *results, uint16_t offset = kStartOffset, @@ -635,6 +651,16 @@ class IRrecv { const uint16_t nbits = kMultibracketsBits, const bool strict = true); #endif // DECODE_MULTIBRACKETS +#if DECODE_CORONA_AC + bool decodeCoronaAc(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kCoronaAcBitsShort, + const bool strict = true); +#endif // DECODE_CORONA_AC +#if DECODE_ZEPEAL +bool decodeZepeal(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kZepealBits, + const bool strict = true); +#endif // DECODE_ZEPEAL }; #endif // IRRECV_H_ diff --git a/lib/IRremoteESP8266-2.7.7/src/IRremoteESP8266.h b/lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h similarity index 94% rename from lib/IRremoteESP8266-2.7.7/src/IRremoteESP8266.h rename to lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h index deef5e5e5..4490baa3b 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRremoteESP8266.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h @@ -52,7 +52,7 @@ #endif // UNIT_TEST // Library Version -#define _IRREMOTEESP8266_VERSION_ "2.7.7" +#define _IRREMOTEESP8266_VERSION_ "2.7.8" // Set the language & locale for the library. See the `locale` dir for options. #ifndef _IR_LOCALE_ @@ -369,6 +369,13 @@ #define SEND_MIDEA _IR_ENABLE_DEFAULT_ #endif // SEND_MIDEA +#ifndef DECODE_MIDEA24 +#define DECODE_MIDEA24 _IR_ENABLE_DEFAULT_ +#endif // DECODE_MIDEA24 +#ifndef SEND_MIDEA24 +#define SEND_MIDEA24 _IR_ENABLE_DEFAULT_ +#endif // SEND_MIDEA24 + #ifndef DECODE_LASERTAG #define DECODE_LASERTAG _IR_ENABLE_DEFAULT_ #endif // DECODE_LASERTAG @@ -432,6 +439,13 @@ #define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_ #endif // SEND_HITACHI_AC3 +#ifndef DECODE_HITACHI_AC344 +#define DECODE_HITACHI_AC344 _IR_ENABLE_DEFAULT_ +#endif // DECODE_HITACHI_AC344 +#ifndef SEND_HITACHI_AC344 +#define SEND_HITACHI_AC344 _IR_ENABLE_DEFAULT_ +#endif // SEND_HITACHI_AC344 + #ifndef DECODE_HITACHI_AC424 #define DECODE_HITACHI_AC424 _IR_ENABLE_DEFAULT_ #endif // DECODE_HITACHI_AC424 @@ -635,6 +649,20 @@ #define SEND_MULTIBRACKETS _IR_ENABLE_DEFAULT_ #endif // SEND_MULTIBRACKETS +#ifndef DECODE_CORONA_AC +#define DECODE_CORONA_AC _IR_ENABLE_DEFAULT_ +#endif // DECODE_CORONA_AC +#ifndef SEND_CORONA_AC +#define SEND_CORONA_AC _IR_ENABLE_DEFAULT_ +#endif // SEND_CORONA_AC + +#ifndef DECODE_ZEPEAL +#define DECODE_ZEPEAL _IR_ENABLE_DEFAULT_ +#endif // DECODE_ZEPEAL +#ifndef SEND_ZEPEAL +#define SEND_ZEPEAL _IR_ENABLE_DEFAULT_ +#endif // SEND_ZEPEAL + #if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \ DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \ DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \ @@ -645,7 +673,10 @@ DECODE_DAIKIN216 || DECODE_SHARP_AC || DECODE_DAIKIN160 || \ DECODE_NEOCLIMA || DECODE_DAIKIN176 || DECODE_DAIKIN128 || \ DECODE_AMCOR || DECODE_DAIKIN152 || DECODE_MITSUBISHI136 || \ - DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3) + DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3 || \ + DECODE_HITACHI_AC344 || DECODE_CORONA_AC) + // Add any DECODE to the above if it uses result->state (see kStateSizeMax) + // you might also want to add the protocol to hasACState function #define DECODE_AC true // We need some common infrastructure for decoding A/Cs. #else #define DECODE_AC false // We don't need that infrastructure. @@ -675,11 +706,11 @@ #ifndef ENABLE_NOISE_FILTER_OPTION #define ENABLE_NOISE_FILTER_OPTION true #endif // ENABLE_NOISE_FILTER_OPTION -/* - * Always add to the end of the list and should never remove entries - * or change order. Projects may save the type number for later usage - * so numbering should always stay the same. - */ + +/// Enumerator for defining and numbering of supported IR protocol. +/// @note Always add to the end of the list and should never remove entries +/// or change order. Projects may save the type number for later usage +/// so numbering should always stay the same. enum decode_type_t { UNKNOWN = -1, UNUSED = 0, @@ -767,15 +798,19 @@ enum decode_type_t { MULTIBRACKETS, CARRIER_AC40, CARRIER_AC64, + HITACHI_AC344, // 85 + CORONA_AC, + MIDEA24, + ZEPEAL, // Add new entries before this one, and update it to point to the last entry. - kLastDecodeType = CARRIER_AC64, + kLastDecodeType = ZEPEAL, }; // Message lengths & required repeat values const uint16_t kNoRepeat = 0; const uint16_t kSingleRepeat = 1; -const uint16_t kAirwellBits = 32; +const uint16_t kAirwellBits = 34; const uint16_t kAirwellMinRepeats = 2; const uint16_t kAiwaRcT501Bits = 15; const uint16_t kAiwaRcT501MinRepeats = kSingleRepeat; @@ -794,6 +829,10 @@ const uint16_t kCarrierAc40Bits = 40; const uint16_t kCarrierAc40MinRepeat = 2; const uint16_t kCarrierAc64Bits = 64; const uint16_t kCarrierAc64MinRepeat = kNoRepeat; +const uint16_t kCoronaAcStateLengthShort = 7; +const uint16_t kCoronaAcStateLength = kCoronaAcStateLengthShort * 3; +const uint16_t kCoronaAcBitsShort = kCoronaAcStateLengthShort * 8; +const uint16_t kCoronaAcBits = kCoronaAcStateLength * 8; const uint16_t kDaikinStateLength = 35; const uint16_t kDaikinBits = kDaikinStateLength * 8; const uint16_t kDaikinStateLengthShort = kDaikinStateLength - 8; @@ -861,6 +900,8 @@ const uint16_t kHitachiAc3StateLength = 27; const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8; const uint16_t kHitachiAc3MinStateLength = 15; const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8; +const uint16_t kHitachiAc344StateLength = 43; +const uint16_t kHitachiAc344Bits = kHitachiAc344StateLength * 8; const uint16_t kHitachiAc424StateLength = 53; const uint16_t kHitachiAc424Bits = kHitachiAc424StateLength * 8; const uint16_t kInaxBits = 24; @@ -880,6 +921,8 @@ const uint16_t kLutronBits = 35; const uint16_t kMagiquestBits = 56; const uint16_t kMideaBits = 48; const uint16_t kMideaMinRepeat = kNoRepeat; +const uint16_t kMidea24Bits = 24; +const uint16_t kMidea24MinRepeat = kSingleRepeat; const uint16_t kMitsubishiBits = 16; // TODO(anyone): Verify that the Mitsubishi repeat is really needed. // Based on marcosamarinho's code. @@ -964,6 +1007,8 @@ const uint16_t kWhirlpoolAcBits = kWhirlpoolAcStateLength * 8; const uint16_t kWhirlpoolAcDefaultRepeat = kNoRepeat; const uint16_t kWhynterBits = 32; const uint8_t kVestelAcBits = 56; +const uint16_t kZepealBits = 16; +const uint16_t kZepealMinRepeat = 4; // Legacy defines. (Deprecated) diff --git a/lib/IRremoteESP8266-2.7.7/src/IRsend.cpp b/lib/IRremoteESP8266-2.7.8/src/IRsend.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.7/src/IRsend.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRsend.cpp index 8995e2d33..d3e097839 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRsend.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRsend.cpp @@ -15,25 +15,16 @@ #endif #include "IRtimer.h" -// Originally from https://github.com/shirriff/Arduino-IRremote/ -// Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for -// sending IR code on ESP8266 - -// IRsend ---------------------------------------------------------------------- -// Create an IRsend object. -// -// Args: -// IRsendPin: Which GPIO pin to use when sending an IR command. -// inverted: *DANGER* Optional flag to invert the output. (default = false) -// e.g. LED is illuminated when GPIO is LOW rather than HIGH. -// Setting this to something other than the default could -// easily destroy your IR LED if you are overdriving it. -// Unless you *REALLY* know what you are doing, don't change this. -// use_modulation: Do we do frequency modulation during transmission? -// i.e. If not, assume a 100% duty cycle. Ignore attempts -// to change the duty cycle etc. -// Returns: -// An IRsend object. +/// Constructor for an IRsend object. +/// @param[in] IRsendPin Which GPIO pin to use when sending an IR command. +/// @param[in] inverted Optional flag to invert the output. (default = false) +/// e.g. LED is illuminated when GPIO is LOW rather than HIGH. +/// @warning Setting `inverted` to something other than the default could +/// easily destroy your IR LED if you are overdriving it. +/// Unless you *REALLY* know what you are doing, don't change this. +/// @param[in] use_modulation Do we do frequency modulation during transmission? +/// i.e. If not, assume a 100% duty cycle. Ignore attempts to change the +/// duty cycle etc. IRsend::IRsend(uint16_t IRsendPin, bool inverted, bool use_modulation) : IRpin(IRsendPin), periodOffset(kPeriodOffset) { if (inverted) { @@ -50,7 +41,7 @@ IRsend::IRsend(uint16_t IRsendPin, bool inverted, bool use_modulation) _dutycycle = kDutyMax; } -// Enable the pin for output. +/// Enable the pin for output. void IRsend::begin() { #ifndef UNIT_TEST pinMode(IRpin, OUTPUT); @@ -58,27 +49,25 @@ void IRsend::begin() { ledOff(); // Ensure the LED is in a known safe state when we start. } -// Turn off the IR LED. +/// Turn off the IR LED. void IRsend::ledOff() { #ifndef UNIT_TEST digitalWrite(IRpin, outputOff); #endif } -// Turn on the IR LED. +/// Turn on the IR LED. void IRsend::ledOn() { #ifndef UNIT_TEST digitalWrite(IRpin, outputOn); #endif } -// Calculate the period for a given frequency. (T = 1/f) -// -// Args: -// freq: Frequency in Hz. -// use_offset: Should we use the calculated offset or not? -// Returns: -// nr. of uSeconds. +/// Calculate the period for a given frequency. +/// @param[in] hz Frequency in Hz. +/// @param[in] use_offset Should we use the calculated offset or not? +/// @return nr. of uSeconds. +/// @note (T = 1/f) uint32_t IRsend::calcUSecPeriod(uint32_t hz, bool use_offset) { if (hz == 0) hz = 1; // Avoid Zero hz. Divide by Zero is nasty. uint32_t period = @@ -90,17 +79,16 @@ uint32_t IRsend::calcUSecPeriod(uint32_t hz, bool use_offset) { return std::max((uint32_t)1, period); } -// Set the output frequency modulation and duty cycle. -// -// Args: -// freq: The freq we want to modulate at. Assumes < 1000 means kHz else Hz. -// duty: Percentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. -// This is ignored if modulation is disabled at object instantiation. -// -// Note: -// Integer timing functions & math mean we can't do fractions of -// microseconds timing. Thus minor changes to the freq & duty values may have -// limited effect. You've been warned. +/// Set the output frequency modulation and duty cycle. +/// @param[in] freq The freq we want to modulate at. +/// Assumes < 1000 means kHz else Hz. +/// @param[in] duty Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// This is ignored if modulation is disabled at object instantiation. +/// @note Integer timing functions & math mean we can't do fractions of +/// microseconds timing. Thus minor changes to the freq & duty values may have +/// limited effect. You've been warned. void IRsend::enableIROut(uint32_t freq, uint8_t duty) { // Set the duty cycle to use if we want freq. modulation. if (modulation) { @@ -121,9 +109,8 @@ void IRsend::enableIROut(uint32_t freq, uint8_t duty) { } #if ALLOW_DELAY_CALLS -// An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds(). -// Args: -// usec: Nr. of uSeconds to delay for. +/// An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds(). +/// @param[in] usec Nr. of uSeconds to delay for. void IRsend::_delayMicroseconds(uint32_t usec) { // delayMicroseconds() is only accurate to 16383us. // Ref: https://www.arduino.cc/en/Reference/delayMicroseconds @@ -141,13 +128,10 @@ void IRsend::_delayMicroseconds(uint32_t usec) { } } #else // ALLOW_DELAY_CALLS -// A version of delayMicroseconds() that handles large values and does NOT use -// the watch-dog friendly delay() calls where appropriate. -// Args: -// usec: Nr. of uSeconds to delay for. -// -// NOTE: Use this only if you know what you are doing as it may cause the WDT -// to reset the ESP8266. +/// A version of delayMicroseconds() that handles large values and does NOT use +/// the watch-dog friendly delay() calls where appropriate. +/// @note Use this only if you know what you are doing as it may cause the WDT +/// to reset the ESP8266. void IRsend::_delayMicroseconds(uint32_t usec) { for (; usec > kMaxAccurateUsecDelay; usec -= kMaxAccurateUsecDelay) #ifndef UNIT_TEST @@ -157,22 +141,19 @@ void IRsend::_delayMicroseconds(uint32_t usec) { } #endif // ALLOW_DELAY_CALLS -// Modulate the IR LED for the given period (usec) and at the duty cycle set. -// -// Args: -// usec: The period of time to modulate the IR LED for, in microseconds. -// Returns: -// Nr. of pulses actually sent. -// -// Note: -// The ESP8266 has no good way to do hardware PWM, so we have to do it all -// in software. There is a horrible kludge/brilliant hack to use the second -// serial TX line to do fairly accurate hardware PWM, but it is only -// available on a single specific GPIO and only available on some modules. -// e.g. It's not available on the ESP-01 module. -// Hence, for greater compatibility & choice, we don't use that method. -// Ref: -// https://www.analysir.com/blog/2017/01/29/updated-esp8266-nodemcu-backdoor-upwm-hack-for-ir-signals/ +/// Modulate the IR LED for the given period (usec) and at the duty cycle set. +/// @param[in] usec The period of time to modulate the IR LED for, in +/// microseconds. +/// @return Nr. of pulses actually sent. +/// @note +/// The ESP8266 has no good way to do hardware PWM, so we have to do it all +/// in software. There is a horrible kludge/brilliant hack to use the second +/// serial TX line to do fairly accurate hardware PWM, but it is only +/// available on a single specific GPIO and only available on some modules. +/// e.g. It's not available on the ESP-01 module. +/// Hence, for greater compatibility & choice, we don't use that method. +/// Ref: +/// https://www.analysir.com/blog/2017/01/29/updated-esp8266-nodemcu-backdoor-upwm-hack-for-ir-signals/ uint16_t IRsend::mark(uint16_t usec) { // Handle the simple case of no required frequency modulation. if (!modulation || _dutycycle >= 100) { @@ -206,31 +187,23 @@ uint16_t IRsend::mark(uint16_t usec) { return counter; } -// Turn the pin (LED) off for a given time. -// Sends an IR space for the specified number of microseconds. -// A space is no output, so the PWM output is disabled. -// -// Args: -// time: Time in microseconds (us). +/// Turn the pin (LED) off for a given time. +/// Sends an IR space for the specified number of microseconds. +/// A space is no output, so the PWM output is disabled. +/// @param[in] time Time in microseconds (us). void IRsend::space(uint32_t time) { ledOff(); if (time == 0) return; _delayMicroseconds(time); } -// Calculate & set any offsets to account for execution times. -// -// Args: -// hz: The frequency to calibrate at >= 1000Hz. Default is 38000Hz. -// -// Returns: -// The calculated period offset (in uSeconds) which is now in use. e.g. -5. -// -// Status: Stable / Working. -// -// NOTE: -// This will generate an 65535us mark() IR LED signal. -// This only needs to be called once, if at all. +/// Calculate & set any offsets to account for execution times during sending. +/// +/// @param[in] hz The frequency to calibrate at >= 1000Hz. Default is 38000Hz. +/// @return The calculated period offset (in uSeconds) which is now in use. +/// e.g. -5. +/// @note This will generate an 65535us mark() IR LED signal. +/// This only needs to be called once, if at all. int8_t IRsend::calibrate(uint16_t hz) { if (hz < 1000) // Were we given kHz? Supports the old call usage. hz *= 1000; @@ -259,18 +232,17 @@ int8_t IRsend::calibrate(uint16_t hz) { return periodOffset; } -// Generic method for sending data that is common to most protocols. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// onemark: Nr. of usecs for the led to be pulsed for a '1' bit. -// onespace: Nr. of usecs for the led to be fully off for a '1' bit. -// zeromark: Nr. of usecs for the led to be pulsed for a '0' bit. -// zerospace: Nr. of usecs for the led to be fully off for a '0' bit. -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. +/// Generic method for sending data that is common to most protocols. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// of bits in data. +/// @param[in] onemark Nr. of usecs for the led to be pulsed for a '1' bit. +/// @param[in] onespace Nr. of usecs for the led to be fully off for a '1' bit. +/// @param[in] zeromark Nr. of usecs for the led to be pulsed for a '0' bit. +/// @param[in] zerospace Nr. of usecs for the led to be fully off for a '0' bit. +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. void IRsend::sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark, uint32_t zerospace, uint64_t data, uint16_t nbits, bool MSBfirst) { @@ -304,35 +276,34 @@ void IRsend::sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark, } } -// Generic method for sending simple protocol messages. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// headermark: Nr. of usecs for the led to be pulsed for the header mark. -// A value of 0 means no header mark. -// headerspace: Nr. of usecs for the led to be off after the header mark. -// A value of 0 means no header space. -// onemark: Nr. of usecs for the led to be pulsed for a '1' bit. -// onespace: Nr. of usecs for the led to be fully off for a '1' bit. -// zeromark: Nr. of usecs for the led to be pulsed for a '0' bit. -// zerospace: Nr. of usecs for the led to be fully off for a '0' bit. -// footermark: Nr. of usecs for the led to be pulsed for the footer mark. -// A value of 0 means no footer mark. -// gap: Nr. of usecs for the led to be off after the footer mark. -// This is effectively the gap between messages. -// A value of 0 means no gap space. -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// frequency: The frequency we want to modulate at. -// Assumes < 1000 means kHz otherwise it is in Hz. -// Most common value is 38000 or 38, for 38kHz. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// repeat: Nr. of extra times the message will be sent. -// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages -// dutycycle: Percentage duty cycle of the LED. -// e.g. 25 = 25% = 1/4 on, 3/4 off. -// If you are not sure, try 50 percent. +/// Generic method for sending simple protocol messages. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// of bits in data. +/// @param[in] headermark Nr. of usecs for the led to be pulsed for the header +/// mark. A value of 0 means no header mark. +/// @param[in] headerspace Nr. of usecs for the led to be off after the header +/// mark. A value of 0 means no header space. +/// @param[in] onemark Nr. of usecs for the led to be pulsed for a '1' bit. +/// @param[in] onespace Nr. of usecs for the led to be fully off for a '1' bit. +/// @param[in] zeromark Nr. of usecs for the led to be pulsed for a '0' bit. +/// @param[in] zerospace Nr. of usecs for the led to be fully off for a '0' bit. +/// @param[in] footermark Nr. of usecs for the led to be pulsed for the footer +/// mark. A value of 0 means no footer mark. +/// @param[in] gap Nr. of usecs for the led to be off after the footer mark. +/// This is effectively the gap between messages. +/// A value of 0 means no gap space. +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] frequency The frequency we want to modulate at. (Hz/kHz) +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] repeat Nr. of extra times the message will be sent. +/// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages +/// @param[in] dutycycle Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// @note Assumes a frequency < 1000 means kHz otherwise it is in Hz. +/// Most common value is 38000 or 38, for 38kHz. void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -345,36 +316,36 @@ void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, dutycycle); } -// Generic method for sending simple protocol messages. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// headermark: Nr. of usecs for the led to be pulsed for the header mark. -// A value of 0 means no header mark. -// headerspace: Nr. of usecs for the led to be off after the header mark. -// A value of 0 means no header space. -// onemark: Nr. of usecs for the led to be pulsed for a '1' bit. -// onespace: Nr. of usecs for the led to be fully off for a '1' bit. -// zeromark: Nr. of usecs for the led to be pulsed for a '0' bit. -// zerospace: Nr. of usecs for the led to be fully off for a '0' bit. -// footermark: Nr. of usecs for the led to be pulsed for the footer mark. -// A value of 0 means no footer mark. -// gap: Min. nr. of usecs for the led to be off after the footer mark. -// This is effectively the absolute minimum gap between messages. -// mesgtime: Min. nr. of usecs a single message needs to be. -// This is effectively the min. total length of a single message. -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// frequency: The frequency we want to modulate at. -// Assumes < 1000 means kHz otherwise it is in Hz. -// Most common value is 38000 or 38, for 38kHz. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// repeat: Nr. of extra times the message will be sent. -// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages -// dutycycle: Percentage duty cycle of the LED. -// e.g. 25 = 25% = 1/4 on, 3/4 off. -// If you are not sure, try 50 percent. +/// Generic method for sending simple protocol messages. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// of bits in data. +/// @param[in] headermark Nr. of usecs for the led to be pulsed for the header +/// mark. A value of 0 means no header mark. +/// @param[in] headerspace Nr. of usecs for the led to be off after the header +/// mark. A value of 0 means no header space. +/// @param[in] onemark Nr. of usecs for the led to be pulsed for a '1' bit. +/// @param[in] onespace Nr. of usecs for the led to be fully off for a '1' bit. +/// @param[in] zeromark Nr. of usecs for the led to be pulsed for a '0' bit. +/// @param[in] zerospace Nr. of usecs for the led to be fully off for a '0' bit. +/// @param[in] footermark Nr. of usecs for the led to be pulsed for the footer +/// mark. A value of 0 means no footer mark. +/// @param[in] gap Nr. of usecs for the led to be off after the footer mark. +/// This is effectively the gap between messages. +/// A value of 0 means no gap space. +/// @param[in] mesgtime Min. nr. of usecs a single message needs to be. +/// This is effectively the min. total length of a single message. +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] frequency The frequency we want to modulate at. (Hz/kHz) +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] repeat Nr. of extra times the message will be sent. +/// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages +/// @param[in] dutycycle Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// @note Assumes a frequency < 1000 means kHz otherwise it is in Hz. +/// Most common value is 38000 or 38, for 38kHz. void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -409,33 +380,32 @@ void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, } } -// Generic method for sending simple protocol messages. -// -// Args: -// headermark: Nr. of usecs for the led to be pulsed for the header mark. -// A value of 0 means no header mark. -// headerspace: Nr. of usecs for the led to be off after the header mark. -// A value of 0 means no header space. -// onemark: Nr. of usecs for the led to be pulsed for a '1' bit. -// onespace: Nr. of usecs for the led to be fully off for a '1' bit. -// zeromark: Nr. of usecs for the led to be pulsed for a '0' bit. -// zerospace: Nr. of usecs for the led to be fully off for a '0' bit. -// footermark: Nr. of usecs for the led to be pulsed for the footer mark. -// A value of 0 means no footer mark. -// gap: Nr. of usecs for the led to be off after the footer mark. -// This is effectively the gap between messages. -// A value of 0 means no gap space. -// dataptr: Pointer to the data to be transmitted. -// nbytes: Nr. of bytes of data to be sent. -// frequency: The frequency we want to modulate at. -// Assumes < 1000 means kHz otherwise it is in Hz. -// Most common value is 38000 or 38, for 38kHz. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// repeat: Nr. of extra times the message will be sent. -// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages -// dutycycle: Percentage duty cycle of the LED. -// e.g. 25 = 25% = 1/4 on, 3/4 off. -// If you are not sure, try 50 percent. +/// Generic method for sending simple protocol messages. +/// @param[in] headermark Nr. of usecs for the led to be pulsed for the header +/// mark. A value of 0 means no header mark. +/// @param[in] headerspace Nr. of usecs for the led to be off after the header +/// mark. A value of 0 means no header space. +/// @param[in] onemark Nr. of usecs for the led to be pulsed for a '1' bit. +/// @param[in] onespace Nr. of usecs for the led to be fully off for a '1' bit. +/// @param[in] zeromark Nr. of usecs for the led to be pulsed for a '0' bit. +/// @param[in] zerospace Nr. of usecs for the led to be fully off for a '0' bit. +/// @param[in] footermark Nr. of usecs for the led to be pulsed for the footer +/// mark. A value of 0 means no footer mark. +/// @param[in] gap Nr. of usecs for the led to be off after the footer mark. +/// This is effectively the gap between messages. +/// A value of 0 means no gap space. +/// @param[in] dataptr Pointer to the data to be transmitted. +/// @param[in] nbytes Nr. of bytes of data to be sent. +/// @param[in] frequency The frequency we want to modulate at. (Hz/kHz) +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] repeat Nr. of extra times the message will be sent. +/// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages +/// @param[in] dutycycle Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// @note Assumes a frequency < 1000 means kHz otherwise it is in Hz. +/// Most common value is 38000 or 38, for 38kHz. void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -462,16 +432,16 @@ void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, } } -// Generic method for sending Manchester code data. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// half_period: Nr. of uSeconds for half the clock's period. (1/2 wavelength) -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// GEThomas: Use G.E. Thomas (true/default) or IEEE 802.3 (false). +/// Generic method for sending Manchester code data. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// of bits in data. +/// @param[in] half_period Nr. of uSeconds for half the clock's period. +/// (1/2 wavelength) +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] GEThomas Use G.E. Thomas (true/default) or IEEE 802.3 (false). void IRsend::sendManchesterData(const uint16_t half_period, const uint64_t data, const uint16_t nbits, const bool MSBfirst, @@ -508,32 +478,31 @@ void IRsend::sendManchesterData(const uint16_t half_period, } } -// Generic method for sending Manchester code messages. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// headermark: Nr. of usecs for the led to be pulsed for the header mark. -// A value of 0 means no header mark. -// headerspace: Nr. of usecs for the led to be off after the header mark. -// A value of 0 means no header space. -// half_period: Nr. of uSeconds for half the clock's period. (1/2 wavelength) -// footermark: Nr. of usecs for the led to be pulsed for the footer mark. -// A value of 0 means no footer mark. -// gap: Min. nr. of usecs for the led to be off after the footer mark. -// This is effectively the absolute minimum gap between messages. -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// frequency: The frequency we want to modulate at. -// Assumes < 1000 means kHz otherwise it is in Hz. -// Most common value is 38000 or 38, for 38kHz. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// repeat: Nr. of extra times the message will be sent. -// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages -// dutycycle: Percentage duty cycle of the LED. -// e.g. 25 = 25% = 1/4 on, 3/4 off. -// If you are not sure, try 50 percent. -// GEThomas: Use G.E. Thomas (true/default) or IEEE 802.3 (false). +/// Generic method for sending Manchester code messages. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// @param[in] headermark Nr. of usecs for the led to be pulsed for the header +/// mark. A value of 0 means no header mark. +/// @param[in] headerspace Nr. of usecs for the led to be off after the header +/// mark. A value of 0 means no header space. +/// @param[in] half_period Nr. of uSeconds for half the clock's period. +/// (1/2 wavelength) +/// @param[in] footermark Nr. of usecs for the led to be pulsed for the footer +/// mark. A value of 0 means no footer mark. +/// @param[in] gap Min. nr. of usecs for the led to be off after the footer +/// mark. This is effectively the absolute minimum gap between messages. +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] frequency The frequency we want to modulate at. (Hz/kHz) +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] repeat Nr. of extra times the message will be sent. +/// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages +/// @param[in] dutycycle Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// @param[in] GEThomas Use G.E. Thomas (true/default) or IEEE 802.3 (false). +/// @note Assumes a frequency < 1000 means kHz otherwise it is in Hz. +/// Most common value is 38000 or 38, for 38kHz. void IRsend::sendManchester(const uint16_t headermark, const uint32_t headerspace, const uint16_t half_period, @@ -550,9 +519,6 @@ void IRsend::sendManchester(const uint16_t headermark, // Header if (headermark) mark(headermark); if (headerspace) space(headerspace); - // Data Marker/sync - // This guarantees a double width half_period. i.e. a Period or T2. - sendManchesterData(half_period, 0b01, 2, true, GEThomas); // Data sendManchesterData(half_period, data, nbits, MSBfirst, GEThomas); // Footer @@ -562,20 +528,14 @@ void IRsend::sendManchester(const uint16_t headermark, } #if SEND_RAW -// Send a raw IRremote message. -// -// Args: -// buf: An array of uint16_t's that has microseconds elements. -// len: Nr. of elements in the buf[] array. -// hz: Frequency to send the message at. (kHz < 1000; Hz >= 1000) -// -// Status: STABLE / Known working. -// -// Notes: -// Even elements are Mark times (On), Odd elements are Space times (Off). -// -// Ref: -// examples/IRrecvDumpV2/IRrecvDumpV2.ino +/// Send a raw IRremote message. +/// +/// @param[in] buf An array of uint16_t's that has microseconds elements. +/// @param[in] len Nr. of elements in the buf[] array. +/// @param[in] hz Frequency to send the message at. (kHz < 1000; Hz >= 1000) +/// @note Even elements are Mark times (On), Odd elements are Space times (Off). +/// Ref: +/// examples/IRrecvDumpV2/IRrecvDumpV2.ino (or later) void IRsend::sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz) { // Set IR carrier frequency @@ -591,11 +551,9 @@ void IRsend::sendRaw(const uint16_t buf[], const uint16_t len, } #endif // SEND_RAW -// Get the minimum number of repeats for a given protocol. -// Args: -// protocol: Protocol number/type of the message you want to send. -// Returns: -// int16_t: The number of repeats required. +/// Get the minimum number of repeats for a given protocol. +/// @param[in] protocol Protocol number/type of the message you want to send. +/// @return The number of repeats required. uint16_t IRsend::minRepeats(const decode_type_t protocol) { switch (protocol) { // Single repeats @@ -604,6 +562,7 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) { case COOLIX: case GICABLE: case INAX: + case MIDEA24: case MITSUBISHI: case MITSUBISHI2: case MITSUBISHI_AC: @@ -626,16 +585,16 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) { return kSonyMinRepeat + 1; case SYMPHONY: return kSymphonyDefaultRepeat; + case ZEPEAL: + return kZepealMinRepeat; default: return kNoRepeat; } } -// Get the default number of bits for a given protocol. -// Args: -// protocol: Protocol number/type you want the default nr. of bits for. -// Returns: -// int16_t: The number of bits. +/// Get the default number of bits for a given protocol. +/// @param[in] protocol Protocol number/type you want the default bit size for. +/// @return The number of bits. uint16_t IRsend::defaultBits(const decode_type_t protocol) { switch (protocol) { case MULTIBRACKETS: @@ -656,6 +615,7 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { case LEGOPF: case MITSUBISHI: case MITSUBISHI2: + case ZEPEAL: return 16; case RC6: case SONY: @@ -663,13 +623,13 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return 20; case COOLIX: case INAX: + case MIDEA24: case NIKAI: case RCMM: return 24; case LG: case LG2: return 28; - case AIRWELL: case CARRIER_AC: case EPSON: case NEC: @@ -678,6 +638,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { case SHERWOOD: case WHYNTER: return 32; + case AIRWELL: + return 34; case LUTRON: case TECO: return 35; @@ -703,6 +665,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return 64; case ARGO: return kArgoBits; + case CORONA_AC: + return kCoronaAcBits; case DAIKIN: return kDaikinBits; case DAIKIN128: @@ -735,6 +699,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return kHitachiAc2Bits; case HITACHI_AC3: return kHitachiAc3Bits; + case HITACHI_AC344: + return kHitachiAc344Bits; case HITACHI_AC424: return kHitachiAc424Bits; case KELVINATOR: @@ -773,18 +739,17 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { } } -// Send a simple (up to 64 bits) IR message of a given type. -// An unknown/unsupported type will do nothing. -// Args: -// type: Protocol number/type of the message you want to send. -// data: The data you want to send (up to 64 bits). -// nbits: How many bits long the message is to be. -// repeat: How many repeats to do? -// Returns: -// bool: True if it is a type we can attempt to send, false if not. +/// Send a simple (up to 64 bits) IR message of a given type. +/// An unknown/unsupported type will send nothing. +/// @param[in] type Protocol number/type of the message you want to send. +/// @param[in] data The data you want to send (up to 64 bits). +/// @param[in] nbits How many bits long the message is to be. +/// @param[in] repeat How many repeats to do? +/// @return True if it is a type we can attempt to send, false if not. bool IRsend::send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat) { - uint16_t min_repeat = std::max(IRsend::minRepeats(type), repeat); + uint16_t min_repeat __attribute__((unused)) = + std::max(IRsend::minRepeats(type), repeat); switch (type) { #if SEND_AIRWELL case AIRWELL: @@ -903,7 +868,12 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, case MIDEA: sendMidea(data, nbits, min_repeat); break; -#endif +#endif // SEND_MIDEA +#if SEND_MIDEA24 + case MIDEA24: + sendMidea24(data, nbits, min_repeat); + break; +#endif // SEND_MIDEA24 #if SEND_MITSUBISHI case MITSUBISHI: sendMitsubishi(data, nbits, min_repeat); @@ -1008,6 +978,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, case WHYNTER: sendWhynter(data, nbits, min_repeat); break; +#endif +#if SEND_ZEPEAL + case ZEPEAL: + sendZepeal(data, nbits, min_repeat); + break; #endif default: return false; @@ -1015,15 +990,13 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, return true; } -// Send a complex (>= 64 bits) IR message of a given type. -// An unknown/unsupported type will do nothing. -// Args: -// type: Protocol number/type of the message you want to send. -// state: A pointer to the array of bytes that make up the state[]. -// nbytes: How many bytes are in the state. -// Returns: -// bool: True if it is a type we can attempt to send, false if not. -bool IRsend::send(const decode_type_t type, const unsigned char *state, +/// Send a complex (>= 64 bits) IR message of a given type. +/// An unknown/unsupported type will send nothing. +/// @param[in] type Protocol number/type of the message you want to send. +/// @param[in] state A pointer to the array of bytes that make up the state[]. +/// @param[in] nbytes How many bytes are in the state. +/// @return True if it is a type we can attempt to send, false if not. +bool IRsend::send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes) { switch (type) { #if SEND_AMCOR @@ -1036,6 +1009,11 @@ bool IRsend::send(const decode_type_t type, const unsigned char *state, sendArgo(state, nbytes); break; #endif // SEND_ARGO +#if SEND_CORONA_AC + case CORONA_AC: + sendCoronaAc(state, nbytes); + break; +#endif // SEND_ARGO #if SEND_DAIKIN case DAIKIN: sendDaikin(state, nbytes); @@ -1116,6 +1094,11 @@ bool IRsend::send(const decode_type_t type, const unsigned char *state, sendHitachiAc3(state, nbytes); break; #endif // SEND_HITACHI_AC3 +#if SEND_HITACHI_AC344 + case HITACHI_AC344: + sendHitachiAc344(state, nbytes); + break; +#endif // SEND_HITACHI_AC344 #if SEND_HITACHI_AC424 case HITACHI_AC424: sendHitachiAc424(state, nbytes); diff --git a/lib/IRremoteESP8266-2.7.7/src/IRsend.h b/lib/IRremoteESP8266-2.7.8/src/IRsend.h similarity index 87% rename from lib/IRremoteESP8266-2.7.7/src/IRsend.h rename to lib/IRremoteESP8266-2.7.8/src/IRsend.h index 85a3dde62..fe206583f 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRsend.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRsend.h @@ -40,8 +40,9 @@ const uint16_t kMaxAccurateUsecDelay = 16383; // Usecs to wait between messages we don't know the proper gap time. const uint32_t kDefaultMessageGap = 100000; - +/// Enumerators and Structures for the Common A/C API. namespace stdAc { + /// Common A/C settings for A/C operating modes. enum class opmode_t { kOff = -1, kAuto = 0, @@ -53,6 +54,7 @@ namespace stdAc { kLastOpmodeEnum = kFan, }; + /// Common A/C settings for Fan Speeds. enum class fanspeed_t { kAuto = 0, kMin = 1, @@ -64,6 +66,7 @@ namespace stdAc { kLastFanspeedEnum = kMax, }; + /// Common A/C settings for Vertical Swing. enum class swingv_t { kOff = -1, kAuto = 0, @@ -76,6 +79,7 @@ namespace stdAc { kLastSwingvEnum = kLowest, }; + /// Common A/C settings for Horizontal Swing. enum class swingh_t { kOff = -1, kAuto = 0, // a.k.a. On. @@ -89,7 +93,7 @@ namespace stdAc { kLastSwinghEnum = kWide, }; - // Structure to hold a common A/C state. + /// Structure to hold a common A/C state. typedef struct { decode_type_t protocol; int16_t model; @@ -112,7 +116,7 @@ namespace stdAc { } state_t; }; // namespace stdAc - +/// Fujitsu A/C model numbers enum fujitsu_ac_remote_model_t { ARRAH2E = 1, // (1) AR-RAH2E, AR-RAC1E, AR-RAE1E (Default) ARDB1, // (2) AR-DB1, AR-DL10 (AR-DL10 swing doesn't work) @@ -121,16 +125,19 @@ enum fujitsu_ac_remote_model_t { ARRY4, // (5) AR-RY4 (Same as AR-RAH2E but with clean & filter) }; +/// Gree A/C model numbers enum gree_ac_remote_model_t { YAW1F = 1, // (1) Ultimate, EKOKAI, RusClimate (Default) YBOFB, // (2) Green, YBOFB2, YAPOF3 }; +/// HITACHI_AC1 A/C model numbers enum hitachi_ac1_remote_model_t { R_LT0541_HTA_A = 1, // (1) R-LT0541-HTA Remote in "A" setting. (Default) R_LT0541_HTA_B, // (2) R-LT0541-HTA Remote in "B" setting. }; +/// Panasonic A/C model numbers enum panasonic_ac_remote_model_t { kPanasonicUnknown = 0, kPanasonicLke = 1, @@ -141,11 +148,13 @@ enum panasonic_ac_remote_model_t { kPanasonicRkr = 6, }; +/// Whirlpool A/C model numbers enum whirlpool_ac_remote_model_t { DG11J13A = 1, // DG11J1-04 too DG11J191, }; +/// LG A/C model numbers enum lg_ac_remote_model_t { GE6711AR2853M = 1, // (1) LG 28-bit Protocol (default) AKB75215403, // (2) LG2 28-bit Protocol @@ -153,6 +162,11 @@ enum lg_ac_remote_model_t { // Classes + +/// Class for sending all basic IR protocols. +/// @note Originally from https://github.com/shirriff/Arduino-IRremote/ +/// Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for +/// sending IR code on ESP8266 class IRsend { public: explicit IRsend(uint16_t IRsendPin, bool inverted = false, @@ -204,9 +218,10 @@ class IRsend { static uint16_t defaultBits(const decode_type_t protocol); bool send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat = kNoRepeat); - bool send(const decode_type_t type, const uint8_t state[], + bool send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes); -#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO) +#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO || \ + SEND_MIDEA24) void sendNEC(uint64_t data, uint16_t nbits = kNECBits, uint16_t repeat = kNoRepeat); uint32_t encodeNEC(uint16_t address, uint16_t command); @@ -217,13 +232,13 @@ class IRsend { // Legacy use of this procedure was to only send a single code so call it with // repeat=0 for backward compatibility. As of v2.0 it defaults to sending // a Sony command that will be accepted be a device. - void sendSony(uint64_t data, uint16_t nbits = kSony20Bits, - uint16_t repeat = kSonyMinRepeat); - void sendSony38(uint64_t data, uint16_t nbits = kSony20Bits, - uint16_t repeat = kSonyMinRepeat + 1); - uint32_t encodeSony(uint16_t nbits, uint16_t command, uint16_t address, - uint16_t extended = 0); -#endif + void sendSony(const uint64_t data, const uint16_t nbits = kSony20Bits, + const uint16_t repeat = kSonyMinRepeat); + void sendSony38(const uint64_t data, const uint16_t nbits = kSony20Bits, + const uint16_t repeat = kSonyMinRepeat + 1); + uint32_t encodeSony(const uint16_t nbits, const uint16_t command, + const uint16_t address, const uint16_t extended = 0); +#endif // SEND_SONY #if SEND_SHERWOOD void sendSherwood(uint64_t data, uint16_t nbits = kSherwoodBits, uint16_t repeat = kSherwoodMinRepeat); @@ -275,8 +290,9 @@ class IRsend { #endif #if SEND_SANYO uint64_t encodeSanyoLC7461(uint16_t address, uint8_t command); - void sendSanyoLC7461(uint64_t data, uint16_t nbits = kSanyoLC7461Bits, - uint16_t repeat = kNoRepeat); + void sendSanyoLC7461(const uint64_t data, + const uint16_t nbits = kSanyoLC7461Bits, + const uint16_t repeat = kNoRepeat); #endif #if SEND_DISH // sendDISH() should typically be called with repeat=3 as DISH devices @@ -297,20 +313,20 @@ class IRsend { const uint8_t subdevice, const uint8_t function); #endif #if SEND_RC5 - void sendRC5(uint64_t data, uint16_t nbits = kRC5XBits, - uint16_t repeat = kNoRepeat); - uint16_t encodeRC5(uint8_t address, uint8_t command, - bool key_released = false); - uint16_t encodeRC5X(uint8_t address, uint8_t command, - bool key_released = false); - uint64_t toggleRC5(uint64_t data); + void sendRC5(const uint64_t data, uint16_t nbits = kRC5XBits, + const uint16_t repeat = kNoRepeat); + uint16_t encodeRC5(const uint8_t address, const uint8_t command, + const bool key_released = false); + uint16_t encodeRC5X(const uint8_t address, const uint8_t command, + const bool key_released = false); + uint64_t toggleRC5(const uint64_t data); #endif #if SEND_RC6 - void sendRC6(uint64_t data, uint16_t nbits = kRC6Mode0Bits, - uint16_t repeat = kNoRepeat); - uint64_t encodeRC6(uint32_t address, uint8_t command, - uint16_t mode = kRC6Mode0Bits); - uint64_t toggleRC6(uint64_t data, uint16_t nbits = kRC6Mode0Bits); + void sendRC6(const uint64_t data, const uint16_t nbits = kRC6Mode0Bits, + const uint16_t repeat = kNoRepeat); + uint64_t encodeRC6(const uint32_t address, const uint8_t command, + const uint16_t mode = kRC6Mode0Bits); + uint64_t toggleRC6(const uint64_t data, const uint16_t nbits = kRC6Mode0Bits); #endif #if SEND_RCMM void sendRCMM(uint64_t data, uint16_t nbits = kRCMMBits, @@ -321,8 +337,8 @@ class IRsend { uint16_t repeat = kCoolixDefaultRepeat); #endif #if SEND_WHYNTER - void sendWhynter(uint64_t data, uint16_t nbits = kWhynterBits, - uint16_t repeat = kNoRepeat); + void sendWhynter(const uint64_t data, const uint16_t nbits = kWhynterBits, + const uint16_t repeat = kNoRepeat); #endif #if SEND_MITSUBISHI void sendMitsubishi(uint64_t data, uint16_t nbits = kMitsubishiBits, @@ -452,11 +468,15 @@ class IRsend { #if SEND_MIDEA void sendMidea(uint64_t data, uint16_t nbits = kMideaBits, uint16_t repeat = kMideaMinRepeat); -#endif +#endif // SEND_MIDEA +#if SEND_MIDEA24 + void sendMidea24(const uint64_t data, const uint16_t nbits = kMidea24Bits, + const uint16_t repeat = kMidea24MinRepeat); +#endif // SEND_MIDEA24 #if SEND_MAGIQUEST - void sendMagiQuest(uint64_t data, uint16_t nbits = kMagiquestBits, - uint16_t repeat = kNoRepeat); - uint64_t encodeMagiQuest(uint32_t wand_id, uint16_t magnitude); + void sendMagiQuest(const uint64_t data, const uint16_t nbits = kMagiquestBits, + const uint16_t repeat = kNoRepeat); + uint64_t encodeMagiQuest(const uint32_t wand_id, const uint16_t magnitude); #endif #if SEND_LASERTAG void sendLasertag(uint64_t data, uint16_t nbits = kLasertagBits, @@ -505,6 +525,11 @@ class IRsend { // different sizes const uint16_t repeat = kHitachiAcDefaultRepeat); #endif // SEND_HITACHI_AC3 +#if SEND_HITACHI_AC344 + void sendHitachiAc344(const unsigned char data[], + const uint16_t nbytes = kHitachiAc344StateLength, + const uint16_t repeat = kHitachiAcDefaultRepeat); +#endif // SEND_HITACHI_AC344 #if SEND_HITACHI_AC424 void sendHitachiAc424(const unsigned char data[], const uint16_t nbytes = kHitachiAc424StateLength, @@ -595,6 +620,16 @@ class IRsend { const uint16_t nbits = kMultibracketsBits, const uint16_t repeat = kMultibracketsDefaultRepeat); #endif +#if SEND_CORONA_AC + void sendCoronaAc(const uint8_t data[], + const uint16_t nbytes = kCoronaAcStateLength, + const uint16_t repeat = kNoRepeat); +#endif // SEND_CORONA_AC +#if SEND_ZEPEAL + void sendZepeal(const uint64_t data, + const uint16_t nbits = kZepealBits, + const uint16_t repeat = kZepealMinRepeat); +#endif protected: #ifdef UNIT_TEST @@ -623,9 +658,9 @@ class IRsend { bool modulation; uint32_t calcUSecPeriod(uint32_t hz, bool use_offset = true); #if SEND_SONY - void _sendSony(uint64_t data, uint16_t nbits, - uint16_t repeat, uint16_t freq); -#endif + void _sendSony(const uint64_t data, const uint16_t nbits, + const uint16_t repeat, const uint16_t freq); +#endif // SEND_SONY }; #endif // IRSEND_H_ diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp b/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp new file mode 100644 index 000000000..7af2ffd0b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp @@ -0,0 +1,268 @@ +// Copyright 2019-2020 - David Conran (@crankyoldgit) + +/// @file IRtext.cpp +/// @warning If you add or remove an entry in this file, you should run: +/// '../tools/generate_irtext_h.sh' to rebuild the `IRtext.h` file. + +#ifndef UNIT_TEST +#include +#endif // UNIT_TEST +#include "IRremoteESP8266.h" +#include "i18n.h" + +#ifndef PROGMEM +#define PROGMEM // Pretend we have the PROGMEM macro even if we really don't. +#endif + +// Common +const PROGMEM char* kUnknownStr = D_STR_UNKNOWN; ///< "Unknown" +const PROGMEM char* kProtocolStr = D_STR_PROTOCOL; ///< "Protocol" +const PROGMEM char* kPowerStr = D_STR_POWER; ///< "Power" +const PROGMEM char* kOnStr = D_STR_ON; ///< "On" +const PROGMEM char* kOffStr = D_STR_OFF; ///< "Off" +const PROGMEM char* kModeStr = D_STR_MODE; ///< "Mode" +const PROGMEM char* kToggleStr = D_STR_TOGGLE; ///< "Toggle" +const PROGMEM char* kTurboStr = D_STR_TURBO; ///< "Turbo" +const PROGMEM char* kSuperStr = D_STR_SUPER; ///< "Super" +const PROGMEM char* kSleepStr = D_STR_SLEEP; ///< "Sleep" +const PROGMEM char* kLightStr = D_STR_LIGHT; ///< "Light" +const PROGMEM char* kPowerfulStr = D_STR_POWERFUL; ///< "Powerful" +const PROGMEM char* kQuietStr = D_STR_QUIET; ///< "Quiet" +const PROGMEM char* kEconoStr = D_STR_ECONO; ///< "Econo" +const PROGMEM char* kSwingStr = D_STR_SWING; ///< "Swing" +const PROGMEM char* kSwingHStr = D_STR_SWINGH; ///< "SwingH" +const PROGMEM char* kSwingVStr = D_STR_SWINGV; ///< "SwingV" +const PROGMEM char* kBeepStr = D_STR_BEEP; ///< "Beep" +const PROGMEM char* kZoneFollowStr = D_STR_ZONEFOLLOW; ///< "Zone Follow" +const PROGMEM char* kFixedStr = D_STR_FIXED; ///< "Fixed" +const PROGMEM char* kMouldStr = D_STR_MOULD; ///< "Mould" +const PROGMEM char* kCleanStr = D_STR_CLEAN; ///< "Clean" +const PROGMEM char* kPurifyStr = D_STR_PURIFY; ///< "Purify" +const PROGMEM char* kTimerStr = D_STR_TIMER; ///< "Timer" +const PROGMEM char* kOnTimerStr = D_STR_ONTIMER; ///< "OnTimer" +const PROGMEM char* kOffTimerStr = D_STR_OFFTIMER; ///< "OffTimer" +const PROGMEM char* kClockStr = D_STR_CLOCK; ///< "Clock" +const PROGMEM char* kCommandStr = D_STR_COMMAND; ///< "Command" +const PROGMEM char* kXFanStr = D_STR_XFAN; ///< "XFan" +const PROGMEM char* kHealthStr = D_STR_HEALTH; ///< "Health" +const PROGMEM char* kModelStr = D_STR_MODEL; ///< "Model" +const PROGMEM char* kTempStr = D_STR_TEMP; ///< "Temp" +const PROGMEM char* kIFeelStr = D_STR_IFEEL; ///< "IFeel" +const PROGMEM char* kHumidStr = D_STR_HUMID; ///< "Humid" +const PROGMEM char* kSaveStr = D_STR_SAVE; ///< "Save" +const PROGMEM char* kEyeStr = D_STR_EYE; ///< "Eye" +const PROGMEM char* kFollowStr = D_STR_FOLLOW; ///< "Follow" +const PROGMEM char* kIonStr = D_STR_ION; ///< "Ion" +const PROGMEM char* kFreshStr = D_STR_FRESH; ///< "Fresh" +const PROGMEM char* kHoldStr = D_STR_HOLD; ///< "Hold" +const PROGMEM char* kButtonStr = D_STR_BUTTON; ///< "Button" +const PROGMEM char* k8CHeatStr = D_STR_8C_HEAT; ///< "8CHeat" +const PROGMEM char* kNightStr = D_STR_NIGHT; ///< "Night" +const PROGMEM char* kSilentStr = D_STR_SILENT; ///< "Silent" +const PROGMEM char* kFilterStr = D_STR_FILTER; ///< "Filter" +const PROGMEM char* k3DStr = D_STR_3D; ///< "3D" +const PROGMEM char* kCelsiusStr = D_STR_CELSIUS; ///< "Celsius" +const PROGMEM char* kTempUpStr = D_STR_TEMPUP; ///< "Temp Up" +const PROGMEM char* kTempDownStr = D_STR_TEMPDOWN; ///< "Temp Down" +const PROGMEM char* kStartStr = D_STR_START; ///< "Start" +const PROGMEM char* kStopStr = D_STR_STOP; ///< "Stop" +const PROGMEM char* kMoveStr = D_STR_MOVE; ///< "Move" +const PROGMEM char* kSetStr = D_STR_SET; ///< "Set" +const PROGMEM char* kCancelStr = D_STR_CANCEL; ///< "Cancel" +const PROGMEM char* kUpStr = D_STR_UP; ///< "Up" +const PROGMEM char* kDownStr = D_STR_DOWN; ///< "Down" +const PROGMEM char* kChangeStr = D_STR_CHANGE; ///< "Change" +const PROGMEM char* kComfortStr = D_STR_COMFORT; ///< "Comfort" +const PROGMEM char* kSensorStr = D_STR_SENSOR; ///< "Sensor" +const PROGMEM char* kWeeklyTimerStr = D_STR_WEEKLYTIMER; ///< "WeeklyTimer" +const PROGMEM char* kWifiStr = D_STR_WIFI; ///< "Wifi" +const PROGMEM char* kLastStr = D_STR_LAST; ///< "Last" +const PROGMEM char* kFastStr = D_STR_FAST; ///< "Fast" +const PROGMEM char* kSlowStr = D_STR_SLOW; ///< "Slow" +const PROGMEM char* kAirFlowStr = D_STR_AIRFLOW; ///< "Air Flow" +const PROGMEM char* kStepStr = D_STR_STEP; ///< "Step" +const PROGMEM char* kNAStr = D_STR_NA; ///< "N/A" +const PROGMEM char* kInsideStr = D_STR_INSIDE; ///< "Inside" +const PROGMEM char* kOutsideStr = D_STR_OUTSIDE; ///< "Outside" +const PROGMEM char* kLoudStr = D_STR_LOUD; ///< "Loud" +const PROGMEM char* kLowerStr = D_STR_LOWER; ///< "Lower" +const PROGMEM char* kUpperStr = D_STR_UPPER; ///< "Upper" +const PROGMEM char* kBreezeStr = D_STR_BREEZE; ///< "Breeze" +const PROGMEM char* kCirculateStr = D_STR_CIRCULATE; ///< "Circulate" +const PROGMEM char* kCeilingStr = D_STR_CEILING; ///< "Ceiling" +const PROGMEM char* kWallStr = D_STR_WALL; ///< "Wall" +const PROGMEM char* kRoomStr = D_STR_ROOM; ///< "Room" +const PROGMEM char* k6thSenseStr = D_STR_6THSENSE; ///< "6th Sense" + +const PROGMEM char* kAutoStr = D_STR_AUTO; ///< "Auto" +const PROGMEM char* kAutomaticStr = D_STR_AUTOMATIC; ///< "Automatic" +const PROGMEM char* kManualStr = D_STR_MANUAL; ///< "Manual" +const PROGMEM char* kCoolStr = D_STR_COOL; ///< "Cool" +const PROGMEM char* kHeatStr = D_STR_HEAT; ///< "Heat" +const PROGMEM char* kFanStr = D_STR_FAN; ///< "Fan" +const PROGMEM char* kDryStr = D_STR_DRY; ///< "Dry" +const PROGMEM char* kFanOnlyStr = D_STR_FANONLY; ///< "fan_only" + +const PROGMEM char* kMaxStr = D_STR_MAX; ///< "Max" +const PROGMEM char* kMaximumStr = D_STR_MAXIMUM; ///< "Maximum" +const PROGMEM char* kMinStr = D_STR_MIN; ///< "Min" +const PROGMEM char* kMinimumStr = D_STR_MINIMUM; ///< "Minimum" +const PROGMEM char* kMedStr = D_STR_MED; ///< "Med" +const PROGMEM char* kMediumStr = D_STR_MEDIUM; ///< "Medium" + +const PROGMEM char* kHighestStr = D_STR_HIGHEST; ///< "Highest" +const PROGMEM char* kHighStr = D_STR_HIGH; ///< "High" +const PROGMEM char* kHiStr = D_STR_HI; ///< "Hi" +const PROGMEM char* kMidStr = D_STR_MID; ///< "Mid" +const PROGMEM char* kMiddleStr = D_STR_MIDDLE; ///< "Middle" +const PROGMEM char* kLowStr = D_STR_LOW; ///< "Low" +const PROGMEM char* kLoStr = D_STR_LO; ///< "Lo" +const PROGMEM char* kLowestStr = D_STR_LOWEST; ///< "Lowest" +const PROGMEM char* kMaxRightStr = D_STR_MAXRIGHT; ///< "Max Right" +const PROGMEM char* kRightMaxStr = D_STR_RIGHTMAX_NOSPACE; ///< "RightMax" +const PROGMEM char* kRightStr = D_STR_RIGHT; ///< "Right" +const PROGMEM char* kLeftStr = D_STR_LEFT; ///< "Left" +const PROGMEM char* kMaxLeftStr = D_STR_MAXLEFT; ///< "Max Left" +const PROGMEM char* kLeftMaxStr = D_STR_LEFTMAX_NOSPACE; ///< "LeftMax" +const PROGMEM char* kWideStr = D_STR_WIDE; ///< "Wide" +const PROGMEM char* kCentreStr = D_STR_CENTRE; ///< "Centre" +const PROGMEM char* kTopStr = D_STR_TOP; ///< "Top" +const PROGMEM char* kBottomStr = D_STR_BOTTOM; ///< "Bottom" + +// Compound words/phrases/descriptions from pre-defined words. +const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO; ///< "Eye Auto" +const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE; ///< "Light Toggle" +const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET; ///< "Outside Quiet" +const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE; ///< "Power Toggle" +const PROGMEM char* kPowerButtonStr = D_STR_POWERBUTTON; ///< "Power Button" +const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER; ///< +///< "Previous Power" +const PROGMEM char* kDisplayTempStr = D_STR_DISPLAYTEMP; ///< "Display Temp" +const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP; ///< "Sensor Temp" +const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER; ///< "Sleep Timer" +const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE; ///< "Swing(V) Mode" +const PROGMEM char* kSwingVToggleStr = D_STR_SWINGVTOGGLE; ///< +///< "Swing(V) Toggle" + +// Separators +char kTimeSep = D_CHR_TIME_SEP; ///< ':' +const PROGMEM char* kSpaceLBraceStr = D_STR_SPACELBRACE; ///< " (" +const PROGMEM char* kCommaSpaceStr = D_STR_COMMASPACE; ///< ", " +const PROGMEM char* kColonSpaceStr = D_STR_COLONSPACE; ///< ": " + +// IRutils +// - Time +const PROGMEM char* kDayStr = D_STR_DAY; ///< "Day" +const PROGMEM char* kDaysStr = D_STR_DAYS; ///< "Days" +const PROGMEM char* kHourStr = D_STR_HOUR; ///< "Hour" +const PROGMEM char* kHoursStr = D_STR_HOURS; ///< "Hours" +const PROGMEM char* kMinuteStr = D_STR_MINUTE; ///< "Minute" +const PROGMEM char* kMinutesStr = D_STR_MINUTES; ///< "Minutes" +const PROGMEM char* kSecondStr = D_STR_SECOND; ///< "Second" +const PROGMEM char* kSecondsStr = D_STR_SECONDS; ///< "Seconds" +const PROGMEM char* kNowStr = D_STR_NOW; ///< "Now" +const PROGMEM char* kThreeLetterDayOfWeekStr = D_STR_THREELETTERDAYS; ///< +///< "SunMonTueWedThuFriSat" +const PROGMEM char* kYesStr = D_STR_YES; ///< "Yes" +const PROGMEM char* kNoStr = D_STR_NO; ///< "No" +const PROGMEM char* kTrueStr = D_STR_TRUE; ///< "True" +const PROGMEM char* kFalseStr = D_STR_FALSE; ///< "False" + +const PROGMEM char* kRepeatStr = D_STR_REPEAT; ///< "Repeat" +const PROGMEM char* kCodeStr = D_STR_CODE; ///< "Code" +const PROGMEM char* kBitsStr = D_STR_BITS; ///< "Bits" + +// Protocol Names +// Needs to be in decode_type_t order. +const PROGMEM char *kAllProtocolNamesStr = + D_STR_UNUSED "\x0" + D_STR_RC5 "\x0" + D_STR_RC6 "\x0" + D_STR_NEC "\x0" + D_STR_SONY "\x0" + D_STR_PANASONIC "\x0" + D_STR_JVC "\x0" + D_STR_SAMSUNG "\x0" + D_STR_WHYNTER "\x0" + D_STR_AIWA_RC_T501 "\x0" + D_STR_LG "\x0" + D_STR_SANYO "\x0" + D_STR_MITSUBISHI "\x0" + D_STR_DISH "\x0" + D_STR_SHARP "\x0" + D_STR_COOLIX "\x0" + D_STR_DAIKIN "\x0" + D_STR_DENON "\x0" + D_STR_KELVINATOR "\x0" + D_STR_SHERWOOD "\x0" + D_STR_MITSUBISHI_AC "\x0" + D_STR_RCMM "\x0" + D_STR_SANYO_LC7461 "\x0" + D_STR_RC5X "\x0" + D_STR_GREE "\x0" + D_STR_PRONTO "\x0" + D_STR_NEC_LIKE "\x0" + D_STR_ARGO "\x0" + D_STR_TROTEC "\x0" + D_STR_NIKAI "\x0" + D_STR_RAW "\x0" + D_STR_GLOBALCACHE "\x0" + D_STR_TOSHIBA_AC "\x0" + D_STR_FUJITSU_AC "\x0" + D_STR_MIDEA "\x0" + D_STR_MAGIQUEST "\x0" + D_STR_LASERTAG "\x0" + D_STR_CARRIER_AC "\x0" + D_STR_HAIER_AC "\x0" + D_STR_MITSUBISHI2 "\x0" + D_STR_HITACHI_AC "\x0" + D_STR_HITACHI_AC1 "\x0" + D_STR_HITACHI_AC2 "\x0" + D_STR_GICABLE "\x0" + D_STR_HAIER_AC_YRW02 "\x0" + D_STR_WHIRLPOOL_AC "\x0" + D_STR_SAMSUNG_AC "\x0" + D_STR_LUTRON "\x0" + D_STR_ELECTRA_AC "\x0" + D_STR_PANASONIC_AC "\x0" + D_STR_PIONEER "\x0" + D_STR_LG2 "\x0" + D_STR_MWM "\x0" + D_STR_DAIKIN2 "\x0" + D_STR_VESTEL_AC "\x0" + D_STR_TECO "\x0" + D_STR_SAMSUNG36 "\x0" + D_STR_TCL112AC "\x0" + D_STR_LEGOPF "\x0" + D_STR_MITSUBISHI_HEAVY_88 "\x0" + D_STR_MITSUBISHI_HEAVY_152 "\x0" + D_STR_DAIKIN216 "\x0" + D_STR_SHARP_AC "\x0" + D_STR_GOODWEATHER "\x0" + D_STR_INAX "\x0" + D_STR_DAIKIN160 "\x0" + D_STR_NEOCLIMA "\x0" + D_STR_DAIKIN176 "\x0" + D_STR_DAIKIN128 "\x0" + D_STR_AMCOR "\x0" + D_STR_DAIKIN152 "\x0" + D_STR_MITSUBISHI136 "\x0" + D_STR_MITSUBISHI112 "\x0" + D_STR_HITACHI_AC424 "\x0" + D_STR_SONY_38K "\x0" + D_STR_EPSON "\x0" + D_STR_SYMPHONY "\x0" + D_STR_HITACHI_AC3 "\x0" + D_STR_DAIKIN64 "\x0" + D_STR_AIRWELL "\x0" + D_STR_DELONGHI_AC "\x0" + D_STR_DOSHISHA "\x0" + D_STR_MULTIBRACKETS "\x0" + D_STR_CARRIER_AC40 "\x0" + D_STR_CARRIER_AC64 "\x0" + D_STR_HITACHI_AC344 "\x0" + D_STR_CORONA_AC "\x0" + D_STR_MIDEA24 "\x0" + D_STR_ZEPEAL "\x0" + ///< New protocol strings should be added just above this line. + "\x0"; ///< This string requires double null termination. diff --git a/lib/IRremoteESP8266-2.7.7/src/IRtext.h b/lib/IRremoteESP8266-2.7.8/src/IRtext.h similarity index 99% rename from lib/IRremoteESP8266-2.7.7/src/IRtext.h rename to lib/IRremoteESP8266-2.7.8/src/IRtext.h index 112162f65..57ba2858b 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRtext.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRtext.h @@ -107,6 +107,7 @@ extern const char* kOutsideStr; extern const char* kPowerfulStr; extern const char* kPowerStr; extern const char* kPowerToggleStr; +extern const char* kPowerButtonStr; extern const char* kPreviousPowerStr; extern const char* kProtocolStr; extern const char* kPurifyStr; diff --git a/lib/IRremoteESP8266-2.7.7/src/IRtimer.cpp b/lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.7/src/IRtimer.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp index 4173d763b..edd98a2d7 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRtimer.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp @@ -11,10 +11,10 @@ uint32_t _IRtimer_unittest_now = 0; uint32_t _TimerMs_unittest_now = 0; #endif // UNIT_TEST -// This class performs a simple time in useconds since instantiated. -// Handles when the system timer wraps around (once). +/// Class constructor. IRtimer::IRtimer() { reset(); } +/// Resets the IRtimer object. void IRtimer::reset() { #ifndef UNIT_TEST start = micros(); @@ -23,6 +23,8 @@ void IRtimer::reset() { #endif } +/// Calculate how many microseconds have elapsed since the timer was started. +/// @return Nr. of microseconds. uint32_t IRtimer::elapsed() { #ifndef UNIT_TEST uint32_t now = micros(); @@ -35,15 +37,17 @@ uint32_t IRtimer::elapsed() { return UINT32_MAX - start + now; // Has wrapped. } -// Only used in unit testing. +/// Add time to the timer to simulate elapsed time. +/// @param[in] usecs Nr. of uSeconds to be added. +/// @note Only used in unit testing. #ifdef UNIT_TEST void IRtimer::add(uint32_t usecs) { _IRtimer_unittest_now += usecs; } #endif // UNIT_TEST -// This class performs a simple time in milli-seoncds since instantiated. -// Handles when the system timer wraps around (once). +/// Class constructor. TimerMs::TimerMs() { reset(); } +/// Resets the TimerMs object. void TimerMs::reset() { #ifndef UNIT_TEST start = millis(); @@ -52,6 +56,8 @@ void TimerMs::reset() { #endif } +/// Calculate how many milliseconds have elapsed since the timer was started. +/// @return Nr. of milliseconds. uint32_t TimerMs::elapsed() { #ifndef UNIT_TEST uint32_t now = millis(); @@ -64,7 +70,9 @@ uint32_t TimerMs::elapsed() { return UINT32_MAX - start + now; // Has wrapped. } -// Only used in unit testing. +/// Add time to the timer to simulate elapsed time. +/// @param[in] msecs Nr. of mSeconds to be added. +/// @note Only used in unit testing. #ifdef UNIT_TEST void TimerMs::add(uint32_t msecs) { _IRtimer_unittest_now += msecs; } #endif // UNIT_TEST diff --git a/lib/IRremoteESP8266-2.7.7/src/IRtimer.h b/lib/IRremoteESP8266-2.7.8/src/IRtimer.h similarity index 65% rename from lib/IRremoteESP8266-2.7.7/src/IRtimer.h rename to lib/IRremoteESP8266-2.7.8/src/IRtimer.h index d00e1d0fa..1a2215fd5 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRtimer.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRtimer.h @@ -7,6 +7,9 @@ #include // Classes + +/// This class performs a simple timer in useconds since instantiated. +/// @note Handles when the system timer wraps around (once). class IRtimer { public: IRtimer(); @@ -20,6 +23,8 @@ class IRtimer { uint32_t start; }; +/// This class performs a simple timer in milli-seoncds since instantiated. +/// @note Handles when the system timer wraps around (once). class TimerMs { public: TimerMs(); diff --git a/lib/IRremoteESP8266-2.7.7/src/IRutils.cpp b/lib/IRremoteESP8266-2.7.8/src/IRutils.cpp similarity index 61% rename from lib/IRremoteESP8266-2.7.7/src/IRutils.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRutils.cpp index 39d9973ed..9393fcf2d 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRutils.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRutils.cpp @@ -17,12 +17,10 @@ #include "IRsend.h" #include "IRtext.h" -// Reverse the order of the requested least significant nr. of bits. -// Args: -// input: Bit pattern/integer to reverse. -// nbits: Nr. of bits to reverse. -// Returns: -// The reversed bit pattern. +/// Reverse the order of the requested least significant nr. of bits. +/// @param[in] input Bit pattern/integer to reverse. +/// @param[in] nbits Nr. of bits to reverse. (LSB -> MSB) +/// @return The reversed bit pattern. uint64_t reverseBits(uint64_t input, uint16_t nbits) { if (nbits <= 1) return input; // Reversing <= 1 bits makes no change at all. // Cap the nr. of bits to rotate to the max nr. of bits in the input. @@ -37,15 +35,12 @@ uint64_t reverseBits(uint64_t input, uint16_t nbits) { return (input << nbits) | output; } -// Convert a uint64_t (unsigned long long) to a string. -// Arduino String/toInt/Serial.print() can't handle printing 64 bit values. -// -// Args: -// input: The value to print -// base: The output base. -// Returns: -// A string representation of the integer. -// Note: Based on Arduino's Print::printNumber() +/// Convert a uint64_t (unsigned long long) to a string. +/// Arduino String/toInt/Serial.print() can't handle printing 64 bit values. +/// @param[in] input The value to print +/// @param[in] base The output base. +/// @returns A String representation of the integer. +/// @note Based on Arduino's Print::printNumber() String uint64ToString(uint64_t input, uint8_t base) { String result = ""; // prevent issues if called with base <= 1 @@ -73,23 +68,18 @@ String uint64ToString(uint64_t input, uint8_t base) { } #ifdef ARDUINO -// Print a uint64_t/unsigned long long to the Serial port -// Serial.print() can't handle printing long longs. (uint64_t) -// -// Args: -// input: The value to print -// base: The output base. +/// Print a uint64_t/unsigned long long to the Serial port +/// Serial.print() can't handle printing long longs. (uint64_t) +/// @param[in] input The value to print +/// @param[in] base The output base. void serialPrintUint64(uint64_t input, uint8_t base) { Serial.print(uint64ToString(input, base)); } #endif -// Convert a C-style str to a decode_type_t -// -// Args: -// str: A C-style string containing a protocol name or number. -// Returns: -// A decode_type_t enum. +/// Convert a C-style string to a decode_type_t. +/// @param[in] str A C-style string containing a protocol name or number. +/// @return A decode_type_t enum. (decode_type_t::UNKNOWN if no match.) decode_type_t strToDecodeType(const char * const str) { const char *ptr = kAllProtocolNamesStr; uint16_t length = strlen(ptr); @@ -108,12 +98,10 @@ decode_type_t strToDecodeType(const char * const str) { return decode_type_t::UNKNOWN; } -// Convert a protocol type (enum etc) to a human readable string. -// Args: -// protocol: Nr. (enum) of the protocol. -// isRepeat: A flag indicating if it is a repeat message of the protocol. -// Returns: -// A string containing the protocol name. +/// Convert a protocol type (enum etc) to a human readable string. +/// @param[in] protocol Nr. (enum) of the protocol. +/// @param[in] isRepeat A flag indicating if it is a repeat message. +/// @return A String containing the protocol name. kUnknownStr if no match. String typeToString(const decode_type_t protocol, const bool isRepeat) { String result = ""; const char *ptr = kAllProtocolNamesStr; @@ -136,11 +124,15 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) { return result; } -// Does the given protocol use a complex state as part of the decode? +/// Does the given protocol use a complex state as part of the decode? +/// @param[in] protocol The decode_type_t protocol we are enquiring about. +/// @return True if the protocol uses a state array. False if just an integer. bool hasACState(const decode_type_t protocol) { switch (protocol) { + // This is keept sorted by name case AMCOR: case ARGO: + case CORONA_AC: case DAIKIN: case DAIKIN128: case DAIKIN152: @@ -157,6 +149,7 @@ bool hasACState(const decode_type_t protocol) { case HITACHI_AC1: case HITACHI_AC2: case HITACHI_AC3: + case HITACHI_AC344: case HITACHI_AC424: case KELVINATOR: case MITSUBISHI136: @@ -179,12 +172,10 @@ bool hasACState(const decode_type_t protocol) { } } -// Return the corrected length of a 'raw' format array structure -// after over-large values are converted into multiple entries. -// Args: -// results: A ptr to a decode result. -// Returns: -// A uint16_t containing the length. +/// Return the corrected length of a 'raw' format array structure +/// after over-large values are converted into multiple entries. +/// @param[in] results A ptr to a decode_results structure. +/// @return The corrected length. uint16_t getCorrectedRawLength(const decode_results * const results) { uint16_t extended_length = results->rawlen - 1; for (uint16_t i = 0; i < results->rawlen - 1; i++) { @@ -195,8 +186,10 @@ uint16_t getCorrectedRawLength(const decode_results * const results) { return extended_length; } -// Return a string containing the key values of a decode_results structure -// in a C/C++ code style format. +/// Return a String containing the key values of a decode_results structure +/// in a C/C++ code style format. +/// @param[in] results A ptr to a decode_results structure. +/// @return A String containing the code-ified result. String resultToSourceCode(const decode_results * const results) { String output = ""; // Reserve some space for the string to reduce heap fragmentation. @@ -274,8 +267,10 @@ String resultToSourceCode(const decode_results * const results) { return output; } -// Dump out the decode_results structure. -// +/// Dump out the decode_results structure. +/// @param[in] results A ptr to a decode_results structure. +/// @return A String containing the legacy information format. +/// @deprecated This is only for those that want this legacy format. String resultToTimingInfo(const decode_results * const results) { String output = ""; String value = ""; @@ -303,8 +298,9 @@ String resultToTimingInfo(const decode_results * const results) { return output; } -// Convert the decode_results structure's value/state to simple hexadecimal. -// +/// Convert the decode_results structure's value/state to simple hexadecimal. +/// @param[in] result A ptr to a decode_results structure. +/// @return A String containing the output. String resultToHexidecimal(const decode_results * const result) { String output = F("0x"); // Reserve some space for the string to reduce heap fragmentation. @@ -322,8 +318,9 @@ String resultToHexidecimal(const decode_results * const result) { return output; } -// Dump out the decode_results structure. -// +/// Dump out the decode_results structure into a human readable format. +/// @param[in] results A ptr to a decode_results structure. +/// @return A String containing the output. String resultToHumanReadableBasic(const decode_results * const results) { String output = ""; // Reserve some space for the string to reduce heap fragmentation. @@ -346,13 +343,11 @@ String resultToHumanReadableBasic(const decode_results * const results) { return output; } -// Convert a decode_results into an array suitable for `sendRaw()`. -// Args: -// decode: A pointer to an IR decode_results structure that contains a mesg. -// Returns: -// A pointer to a dynamically allocated uint16_t sendRaw compatible array. -// Note: -// Result needs to be delete[]'ed/free()'ed (deallocated) after use by caller. +/// Convert a decode_results into an array suitable for `sendRaw()`. +/// @param[in] decode A ptr to a decode_results structure that contains a mesg. +/// @return A PTR to a dynamically allocated uint16_t sendRaw compatible array. +/// @note The returned array needs to be delete[]'ed/free()'ed (deallocated) +/// after use by caller. uint16_t* resultToRawArray(const decode_results * const decode) { uint16_t *result = new uint16_t[getCorrectedRawLength(decode)]; if (result != NULL) { // The memory was allocated successfully. @@ -371,6 +366,12 @@ uint16_t* resultToRawArray(const decode_results * const decode) { return result; } +/// Sum all the bytes of an array and return the least significant 8-bits of +/// the result. +/// @param[in] start A ptr to the start of the byte array to calculate over. +/// @param[in] length How many bytes to use in the calculation. +/// @param[in] init Starting value of the calculation to use. (Default is 0) +/// @return The 8-bit calculated result of all the bytes and init value. uint8_t sumBytes(const uint8_t * const start, const uint16_t length, const uint8_t init) { uint8_t checksum = init; @@ -379,6 +380,11 @@ uint8_t sumBytes(const uint8_t * const start, const uint16_t length, return checksum; } +/// Calculate a rolling XOR of all the bytes of an array. +/// @param[in] start A ptr to the start of the byte array to calculate over. +/// @param[in] length How many bytes to use in the calculation. +/// @param[in] init Starting value of the calculation to use. (Default is 0) +/// @return The 8-bit calculated result of all the bytes and init value. uint8_t xorBytes(const uint8_t * const start, const uint16_t length, const uint8_t init) { uint8_t checksum = init; @@ -387,14 +393,12 @@ uint8_t xorBytes(const uint8_t * const start, const uint16_t length, return checksum; } -// Count the number of bits of a certain type. -// Args: -// start: Ptr to the start of data to count bits in. -// length: How many bytes to count. -// ones: Count the binary 1 bits. False for counting the 0 bits. -// init: Start the counting from this value. -// Returns: -// Nr. of bits found. +/// Count the number of bits of a certain type in an array. +/// @param[in] start A ptr to the start of the byte array to calculate over. +/// @param[in] length How many bytes to use in the calculation. +/// @param[in] ones Count the binary nr of `1` bits. False is count the `0`s. +/// @param[in] init Starting value of the calculation to use. (Default is 0) +/// @return The nr. of bits found of the given type found in the array. uint16_t countBits(const uint8_t * const start, const uint16_t length, const bool ones, const uint16_t init) { uint16_t count = init; @@ -409,14 +413,12 @@ uint16_t countBits(const uint8_t * const start, const uint16_t length, return (length * 8) - count; } -// Count the number of bits of a certain type. -// Args: -// data: The value you want bits counted for, starting from the LSB. -// length: How many bits to count. -// ones: Count the binary 1 bits. False for counting the 0 bits. -// init: Start the counting from this value. -// Returns: -// Nr. of bits found. +/// Count the number of bits of a certain type in an Integer. +/// @param[in] data The value you want bits counted for. Starting from the LSB. +/// @param[in] length How many bits to use in the calculation? Starts at the LSB +/// @param[in] ones Count the binary nr of `1` bits. False is count the `0`s. +/// @param[in] init Starting value of the calculation to use. (Default is 0) +/// @return The nr. of bits found of the given type found in the Integer. uint16_t countBits(const uint64_t data, const uint8_t length, const bool ones, const uint16_t init) { uint16_t count = init; @@ -430,6 +432,10 @@ uint16_t countBits(const uint64_t data, const uint8_t length, const bool ones, return length - count; } +/// Invert/Flip the bits in an Integer. +/// @param[in] data The Integer that will be inverted. +/// @param[in] nbits How many bits are to be inverted. Starting from the LSB. +/// @return An Integer with the appropriate bits inverted/flipped. uint64_t invertBits(const uint64_t data, const uint16_t nbits) { // No change if we are asked to invert no bits. if (nbits == 0) return data; @@ -440,11 +446,19 @@ uint64_t invertBits(const uint64_t data, const uint16_t nbits) { return (result & ((1ULL << nbits) - 1)); } +/// Convert degrees Celsius to degrees Fahrenheit. float celsiusToFahrenheit(const float deg) { return (deg * 9.0) / 5.0 + 32.0; } +/// Convert degrees Fahrenheit to degrees Celsius. float fahrenheitToCelsius(const float deg) { return (deg - 32.0) * 5.0 / 9.0; } namespace irutils { + /// Create a String with a colon separated "label: value" pair suitable for + /// Humans. + /// @param[in] value The value to come after the label. + /// @param[in] label The label to precede the value. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addLabeledString(const String value, const String label, const bool precomma) { String result = ""; @@ -454,16 +468,33 @@ namespace irutils { return result + value; } + /// Create a String with a colon separated flag suitable for Humans. + /// e.g. "Power: On" + /// @param[in] value The value to come after the label. + /// @param[in] label The label to precede the value. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addBoolToString(const bool value, const String label, const bool precomma) { return addLabeledString((value ? kOnStr : kOffStr), label, precomma); } + /// Create a String with a colon separated labeled Integer suitable for + /// Humans. + /// e.g. "Foo: 23" + /// @param[in] value The value to come after the label. + /// @param[in] label The label to precede the value. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addIntToString(const uint16_t value, const String label, const bool precomma) { return addLabeledString(uint64ToString(value), label, precomma); } + /// Generate the model string for a given Protocol/Model pair. + /// @param[in] protocol The IR protocol. + /// @param[in] model The model number for that protocol. + /// @return The resulting String. String modelToStr(const decode_type_t protocol, const int16_t model) { switch (protocol) { case decode_type_t::FUJITSU_AC: @@ -522,6 +553,12 @@ namespace irutils { } } + /// Create a String of human output for a given protocol model number. + /// e.g. "Model: JKE" + /// @param[in] protocol The IR protocol. + /// @param[in] model The model number for that protocol. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addModelToString(const decode_type_t protocol, const int16_t model, const bool precomma) { String result = addIntToString(model, kModelStr, precomma); @@ -530,6 +567,13 @@ namespace irutils { return result + ')'; } + /// Create a String of human output for a given temperature. + /// e.g. "Temp: 25C" + /// @param[in] degrees The temperature in degrees. + /// @param[in] celsius Is the temp Celsius or Fahrenheit. + /// true is C, false is F + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addTempToString(const uint16_t degrees, const bool celsius, const bool precomma) { String result = addIntToString(degrees, kTempStr, precomma); @@ -537,6 +581,15 @@ namespace irutils { return result; } + /// Create a String of human output for the given operating mode. + /// e.g. "Mode: 1 (Cool)" + /// @param[in] mode The operating mode to display. + /// @param[in] automatic The numeric value for Auto mode. + /// @param[in] cool The numeric value for Cool mode. + /// @param[in] heat The numeric value for Heat mode. + /// @param[in] dry The numeric value for Dry mode. + /// @param[in] fan The numeric value for Fan mode. + /// @return The resulting String. String addModeToString(const uint8_t mode, const uint8_t automatic, const uint8_t cool, const uint8_t heat, const uint8_t dry, const uint8_t fan) { @@ -552,6 +605,14 @@ namespace irutils { return result + ')'; } + /// Create a String of the 3-letter day of the week from a numerical day of + /// the week. e.g. "Day: 1 (Mon)" + /// @param[in] day_of_week A numerical version of the sequential day of the + /// week. e.g. Saturday = 7 etc. + /// @param[in] offset Days to offset by. + /// e.g. For different day starting the week. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addDayToString(const uint8_t day_of_week, const int8_t offset, const bool precomma) { String result = addIntToString(day_of_week, kDayStr, precomma); @@ -569,6 +630,15 @@ namespace irutils { return result + ')'; } + /// Create a String of human output for the given fan speed. + /// e.g. "Fan: 0 (Auto)" + /// @param[in] speed The numeric speed of the fan to display. + /// @param[in] high The numeric value for High speed. + /// @param[in] low The numeric value for Low speed. + /// @param[in] automatic The numeric value for Auto speed. + /// @param[in] quiet The numeric value for Quiet speed. + /// @param[in] medium The numeric value for Medium speed. + /// @return The resulting String. String addFanToString(const uint8_t speed, const uint8_t high, const uint8_t low, const uint8_t automatic, const uint8_t quiet, const uint8_t medium) { @@ -584,11 +654,9 @@ namespace irutils { return result + ')'; } - // Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS. - // Args: - // unescaped: A string containing text to make HTML safe. - // Returns: - // A string that is HTML safe. + /// Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS. + /// @param[in] unescaped A String containing text to make HTML safe. + /// @return A string that is HTML safe. String htmlEscape(const String unescaped) { String result = ""; uint16_t ulen = unescaped.length(); @@ -597,55 +665,30 @@ namespace irutils { char c = unescaped[i]; switch (c) { // ';!-"<>=&#{}() are all unsafe. - case '\'': - result += F("'"); - break; - case ';': - result += F(";"); - break; - case '!': - result += F("!"); - break; - case '-': - result += F("‐"); - break; - case '\"': - result += F("""); - break; - case '<': - result += F("<"); - break; - case '>': - result += F(">"); - break; - case '=': - result += F("&#equals;"); - break; - case '&': - result += F("&"); - break; - case '#': - result += F("#"); - break; - case '{': - result += F("{"); - break; - case '}': - result += F("}"); - break; - case '(': - result += F("("); - break; - case ')': - result += F(")"); - break; - default: - result += c; + case '\'': result += F("'"); break; + case ';': result += F(";"); break; + case '!': result += F("!"); break; + case '-': result += F("‐"); break; + case '\"': result += F("""); break; + case '<': result += F("<"); break; + case '>': result += F(">"); break; + case '=': result += F("&#equals;"); break; + case '&': result += F("&"); break; + case '#': result += F("#"); break; + case '{': result += F("{"); break; + case '}': result += F("}"); break; + case '(': result += F("("); break; + case ')': result += F(")"); break; + default: result += c; } } return result; } + /// Convert a nr. of milliSeconds into a Human-readable string. + /// e.g. "1 Day 6 Hours 34 Minutes 17 Seconds" + /// @param[in] msecs Nr. of milliSeconds (ms). + /// @return A human readable string. String msToString(uint32_t const msecs) { uint32_t totalseconds = msecs / 1000; if (totalseconds == 0) return kNowStr; @@ -678,6 +721,10 @@ namespace irutils { return result; } + /// Convert a nr. of minutes into a 24h clock format Human-readable string. + /// e.g. "23:59" + /// @param[in] mins Nr. of Minutes. + /// @return A human readable string. String minsToString(const uint16_t mins) { String result = ""; result.reserve(5); // 23:59 is the typical worst case. @@ -688,13 +735,11 @@ namespace irutils { return result; } - // Sum all the nibbles together in a series of bytes. - // Args: - // start: PTR to the start of the bytes. - // length: Nr of bytes to sum the nibbles of. - // init: Starting value of the sum. - // Returns: - // A uint8_t sum of all the nibbles inc the init. + /// Sum all the nibbles together in a series of bytes. + /// @param[in] start A ptr to the start of the byte array to calculate over. + /// @param[in] length How many bytes to use in the calculation. + /// @param[in] init Starting value of the calculation to use. (Default is 0) + /// @return The 8-bit calculated result of all the bytes and init value. uint8_t sumNibbles(const uint8_t * const start, const uint16_t length, const uint8_t init) { uint8_t sum = init; @@ -704,41 +749,62 @@ namespace irutils { return sum; } + /// Sum all the nibbles together in an integer. + /// @param[in] data The integer to be summed. + /// @param[in] count The number of nibbles to sum. Starts from LSB. Max of 16. + /// @param[in] init Starting value of the calculation to use. (Default is 0) + /// @param[in] nibbleonly true, the result is 4 bits. false, it's 8 bits. + /// @return The 4/8-bit calculated result of all the nibbles and init value. + uint8_t sumNibbles(const uint64_t data, const uint8_t count, + const uint8_t init, const bool nibbleonly) { + uint8_t sum = init; + uint64_t copy = data; + const uint8_t nrofnibbles = (count < 16) ? count : (64 / 4); + for (uint8_t i = 0; i < nrofnibbles; i++, copy >>= 4) sum += copy & 0xF; + return nibbleonly ? sum & 0xF : sum; + } + + /// Convert a byte of Binary Coded Decimal(BCD) into an Integer. + /// @param[in] bcd The BCD value. + /// @return A normal Integer value. uint8_t bcdToUint8(const uint8_t bcd) { if (bcd > 0x99) return 255; // Too big. return (bcd >> 4) * 10 + (bcd & 0xF); } + /// Convert an Integer into a byte of Binary Coded Decimal(BCD). + /// @param[in] integer The number to convert. + /// @return An 8-bit BCD value. uint8_t uint8ToBcd(const uint8_t integer) { if (integer > 99) return 255; // Too big. return ((integer / 10) << 4) + (integer % 10); } - // Return the value of `position`th bit of `data`. - // Args: - // data: Value to be examined. - // position: Nr. of the nth bit to be examined. `0` is the LSB. - // size: Nr. of bits in data. + /// Return the value of `position`th bit of an Integer. + /// @param[in] data Value to be examined. + /// @param[in] position Nr. of the Nth bit to be examined. `0` is the LSB. + /// @param[in] size Nr. of bits in data. + /// @return The bit's value. bool getBit(const uint64_t data, const uint8_t position, const uint8_t size) { if (position >= size) return false; // Outside of range. return data & (1ULL << position); } - // Return the value of `position`th bit of `data`. - // Args: - // data: Value to be examined. - // position: Nr. of the nth bit to be examined. `0` is the LSB. + /// Return the value of `position`th bit of an Integer. + /// @param[in] data Value to be examined. + /// @param[in] position Nr. of the Nth bit to be examined. `0` is the LSB. + /// @return The bit's value. bool getBit(const uint8_t data, const uint8_t position) { if (position >= 8) return false; // Outside of range. return data & (1 << position); } - // Return the value of `data` with the `position`th bit changed to `on` - // Args: - // data: Value to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. - // size: Nr. of bits in data. + /// Return the value of an Integer with the `position`th bit changed. + /// @param[in] data Value to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. + /// @param[in] size Nr. of bits in data. + /// @return A suitably modified integer. uint64_t setBit(const uint64_t data, const uint8_t position, const bool on, const uint8_t size) { if (position >= size) return data; // Outside of range. @@ -749,11 +815,11 @@ namespace irutils { return data & ~mask; } - // Return the value of `data` with the `position`th bit changed to `on` - // Args: - // data: Value to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. + /// Return the value of an Integer with the `position`th bit changed. + /// @param[in] data Value to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. + /// @return A suitably modified integer. uint8_t setBit(const uint8_t data, const uint8_t position, const bool on) { if (position >= 8) return data; // Outside of range. uint8_t mask = 1 << position; @@ -763,12 +829,10 @@ namespace irutils { return data & ~mask; } - // Change the value at the location `data_ptr` with the `position`th bit - // changed to `on` - // Args: - // data: Ptr to the data to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. + /// Alter the value of an Integer with the `position`th bit changed. + /// @param[in,out] data A pointer to the 8-bit integer to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. void setBit(uint8_t * const data, const uint8_t position, const bool on) { uint8_t mask = 1 << position; if (on) @@ -777,12 +841,10 @@ namespace irutils { *data &= ~mask; } - // Change the value at the location `data_ptr` with the `position`th bit - // changed to `on` - // Args: - // data: Ptr to the data to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. + /// Alter the value of an Integer with the `position`th bit changed. + /// @param[in,out] data A pointer to the 32-bit integer to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. void setBit(uint32_t * const data, const uint8_t position, const bool on) { uint32_t mask = (uint32_t)1 << position; if (on) @@ -791,12 +853,10 @@ namespace irutils { *data &= ~mask; } - // Change the value at the location `data_ptr` with the `position`th bit - // changed to `on` - // Args: - // data: Ptr to the data to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. + /// Alter the value of an Integer with the `position`th bit changed. + /// @param[in,out] data A pointer to the 64-bit integer to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. void setBit(uint64_t * const data, const uint8_t position, const bool on) { uint64_t mask = (uint64_t)1 << position; if (on) @@ -805,13 +865,11 @@ namespace irutils { *data &= ~mask; } - // Change the uint8_t pointed to by `dst` starting at the `offset`th bit - // and for `nbits` bits, with the contents of `data`. - // Args: - // dst: Ptr to the uint8_t to be changed. - // offset: Nr. of bits from the Least Significant Bit to be ignored. - // nbits: Nr of bits of `data` to be placed into the destination uint8_t. - // data: Value to be placed into dst. + /// Alter an uint8_t value by overwriting an arbitary given number of bits. + /// @param[in,out] dst A pointer to the value to be changed. + /// @param[in] offset Nr. of bits from the Least Significant Bit to be ignored + /// @param[in] nbits Nr of bits of data to be placed into the destination. + /// @param[in] data The value to be placed. void setBits(uint8_t * const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data) { if (offset >= 8 || !nbits) return; // Short circuit as it won't change. @@ -824,13 +882,11 @@ namespace irutils { *dst |= ((data & mask) << offset); } - // Change the uint32_t pointed to by `dst` starting at the `offset`th bit - // and for `nbits` bits, with the contents of `data`. - // Args: - // dst: Ptr to the uint32_t to be changed. - // offset: Nr. of bits from the Least Significant Bit to be ignored. - // nbits: Nr of bits of `data` to be placed into the destination uint32_t. - // data: Value to be placed into dst. + /// Alter an uint32_t value by overwriting an arbitary given number of bits. + /// @param[in,out] dst A pointer to the value to be changed. + /// @param[in] offset Nr. of bits from the Least Significant Bit to be ignored + /// @param[in] nbits Nr of bits of data to be placed into the destination. + /// @param[in] data The value to be placed. void setBits(uint32_t * const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data) { if (offset >= 32 || !nbits) return; // Short circuit as it won't change. @@ -843,13 +899,11 @@ namespace irutils { *dst |= ((data & mask) << offset); } - // Change the uint64_t pointed to by `dst` starting at the `offset`th bit - // and for `nbits` bits, with the contents of `data`. - // Args: - // dst: Ptr to the uint64_t to be changed. - // offset: Nr. of bits from the Least Significant Bit to be ignored. - // nbits: Nr of bits of `data` to be placed into the destination uint64_t. - // data: Value to be placed into dst. + /// Alter an uint64_t value by overwriting an arbitary given number of bits. + /// @param[in,out] dst A pointer to the value to be changed. + /// @param[in] offset Nr. of bits from the Least Significant Bit to be ignored + /// @param[in] nbits Nr of bits of data to be placed into the destination. + /// @param[in] data The value to be placed. void setBits(uint64_t * const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data) { if (offset >= 64 || !nbits) return; // Short circuit as it won't change. diff --git a/lib/IRremoteESP8266-2.7.7/src/IRutils.h b/lib/IRremoteESP8266-2.7.8/src/IRutils.h similarity index 95% rename from lib/IRremoteESP8266-2.7.7/src/IRutils.h rename to lib/IRremoteESP8266-2.7.8/src/IRutils.h index 34319134a..3c865dfcf 100644 --- a/lib/IRremoteESP8266-2.7.7/src/IRutils.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRutils.h @@ -42,6 +42,8 @@ uint64_t invertBits(const uint64_t data, const uint16_t nbits); decode_type_t strToDecodeType(const char *str); float celsiusToFahrenheit(const float deg); float fahrenheitToCelsius(const float deg); +/// Namespace for covering common functions & procedures for advancd protocol +/// handlers namespace irutils { String addBoolToString(const bool value, const String label, const bool precomma = true); @@ -67,6 +69,8 @@ namespace irutils { String minsToString(const uint16_t mins); uint8_t sumNibbles(const uint8_t * const start, const uint16_t length, const uint8_t init = 0); + uint8_t sumNibbles(const uint64_t data, const uint8_t count = 16, + const uint8_t init = 0, const bool nibbleonly = true); uint8_t bcdToUint8(const uint8_t bcd); uint8_t uint8ToBcd(const uint8_t integer); bool getBit(const uint64_t data, const uint8_t position, diff --git a/lib/IRremoteESP8266-2.7.7/src/i18n.h b/lib/IRremoteESP8266-2.7.8/src/i18n.h similarity index 100% rename from lib/IRremoteESP8266-2.7.7/src/i18n.h rename to lib/IRremoteESP8266-2.7.8/src/i18n.h diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Airwell.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp similarity index 55% rename from lib/IRremoteESP8266-2.7.7/src/ir_Airwell.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp index 5eb103b84..2bf0a2db8 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Airwell.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp @@ -3,35 +3,32 @@ #include "IRrecv.h" #include "IRsend.h" -// Airwell "Manchester code" based protocol. -// Some other Airwell products use the COOLIX protocol. -// +/// @file +/// @brief Airwell "Manchester code" based protocol. +/// Some other Airwell products use the COOLIX protocol. + // Supports: // Brand: Airwell, Model: RC08W remote +// Brand: Airwell, Model: RC04 remote +// Brand: Airwell, Model: DLS 21 DCI R410 AW A/C const uint8_t kAirwellOverhead = 4; const uint16_t kAirwellHalfClockPeriod = 950; // uSeconds const uint16_t kAirwellHdrMark = 3 * kAirwellHalfClockPeriod; // uSeconds -const uint16_t kAirwellHdrSpace = 4 * kAirwellHalfClockPeriod; // uSeconds +const uint16_t kAirwellHdrSpace = 3 * kAirwellHalfClockPeriod; // uSeconds const uint16_t kAirwellFooterMark = 5 * kAirwellHalfClockPeriod; // uSeconds #if SEND_AIRWELL -// Send an Airwell Manchester Code formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kAirwellBits. -// repeat: The number of times the command is to be repeated. -// -// Status: BETA / Appears to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 +/// Send an Airwell Manchester Code formatted message. +/// Status: BETA / Appears to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of the message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 void IRsend::sendAirwell(uint64_t data, uint16_t nbits, uint16_t repeat) { // Header + Data sendManchester(kAirwellHdrMark, kAirwellHdrMark, kAirwellHalfClockPeriod, - 0, 0, data, nbits, 38000, true, repeat); + 0, 0, data, nbits, 38000, true, repeat, kDutyDefault, false); // Footer mark(kAirwellHdrMark + kAirwellHalfClockPeriod); space(kDefaultMessageGap); // A guess. @@ -39,21 +36,17 @@ void IRsend::sendAirwell(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif #if DECODE_AIRWELL -// Decode the supplied Airwell "Manchester code" message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kAirwellBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Appears to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 +/// Decode the supplied Airwell "Manchester code" message. +/// +/// Status: BETA / Appears to be working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 bool IRrecv::decodeAirwell(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < nbits + kAirwellOverhead - offset) @@ -69,7 +62,7 @@ bool IRrecv::decodeAirwell(decode_results *results, uint16_t offset, kAirwellHdrMark, kAirwellHdrMark, kAirwellHalfClockPeriod, kAirwellHdrMark, kAirwellHdrSpace, - true); + true, kUseDefTol, kMarkExcess, true, false); if (used == 0) return false; offset += used; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Aiwa.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Aiwa.cpp similarity index 63% rename from lib/IRremoteESP8266-2.7.7/src/ir_Aiwa.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Aiwa.cpp index 95dffe1aa..2b989c6ae 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Aiwa.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Aiwa.cpp @@ -3,15 +3,12 @@ #include "IRrecv.h" #include "IRsend.h" -// AAA IIIII W W AAA -// A A I W W A A -// AAAAA I W W W AAAAA -// A A I W W W A A -// A A IIIII WWW A A +/// @file +/// @brief Aiwa based protocol. +/// Based off the RC-T501 RCU +/// Inspired by IRremoteESP8266's implementation +/// @see https://github.com/z3t0/Arduino-IRremote -// Based off the RC-T501 RCU -// Added by David Conran. (Inspired by IRremoteESP8266's implementation: -// https://github.com/z3t0/Arduino-IRremote) // Supports: // Brand: Aiwa, Model: RC-T501 RCU @@ -23,18 +20,13 @@ const uint64_t kAiwaRcT501PreData = 0x1D8113FULL; // 26-bits const uint64_t kAiwaRcT501PostData = 1ULL; #if SEND_AIWA_RC_T501 -// Send an Aiwa RC T501 formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kAiwaRcT501Bits. Max is 37 = (64 - 27) -// repeat: The number of times the command is to be repeated. -// -// Status: BETA / Should work. -// -// Ref: -// http://lirc.sourceforge.net/remotes/aiwa/RC-T501 +/// Send an Aiwa RC T501 formatted message. +/// Status: BETA / Should work. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of the message to be sent. +/// Typically kAiwaRcT501Bits. Max is 37 = (64 - 27) +/// @param[in] repeat The number of times the command is to be repeated. +/// @see http://lirc.sourceforge.net/remotes/aiwa/RC-T501 void IRsend::sendAiwaRCT501(uint64_t data, uint16_t nbits, uint16_t repeat) { // Appears to be an extended NEC1 protocol. i.e. 42 bits instead of 32 bits. // So use sendNEC instead, however the twist is it has a fixed 26 bit @@ -49,28 +41,23 @@ void IRsend::sendAiwaRCT501(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif #if DECODE_AIWA_RC_T501 -// Decode the supplied Aiwa RC T501 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kAiwaRcT501Bits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Should work. -// -// Notes: -// Aiwa RC T501 appears to be a 42 bit variant of the NEC1 protocol. -// However, we historically (original Arduino IRremote project) treats it as -// a 15 bit (data) protocol. So, we expect nbits to typically be 15, and we -// will remove the prefix and postfix from the raw data, and use that as -// the result. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php +/// Decode the supplied Aiwa RC T501 message. +/// Status: BETA / Should work. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @note +/// Aiwa RC T501 appears to be a 42 bit variant of the NEC1 protocol. +/// However, we historically (original Arduino IRremote project) treats it as +/// a 15 bit (data) protocol. So, we expect nbits to typically be 15, and we +/// will remove the prefix and postfix from the raw data, and use that as +/// the result. +/// @see http://www.sbprojects.com/knowledge/ir/nec.php +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 bool IRrecv::decodeAiwaRCT501(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Amcor.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.cpp similarity index 68% rename from lib/IRremoteESP8266-2.7.7/src/ir_Amcor.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Amcor.cpp index b29933906..668280133 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Amcor.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.cpp @@ -1,9 +1,9 @@ // Copyright 2019 David Conran -// Supports: -// Brand: Amcor, Model: ADR-853H A/C -// Brand: Amcor, Model: TAC-495 remote -// Brand: Amcor, Model: TAC-444 remote +/// @file +/// @brief Amcor A/C protocol. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/385 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/834 #include "ir_Amcor.h" #include @@ -14,8 +14,6 @@ #include "IRutils.h" // Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/385 const uint16_t kAmcorHdrMark = 8200; const uint16_t kAmcorHdrSpace = 4200; const uint16_t kAmcorOneMark = 1500; @@ -33,15 +31,11 @@ using irutils::addTempToString; using irutils::setBits; #if SEND_AMCOR -// Send a Amcor HVAC formatted message. -// -// Args: -// data: The message to be sent. -// nbytes: The byte size of the array being sent. typically kAmcorStateLength. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Reported as working. -// +/// Send a Amcor HVAC formatted message. +/// Status: STABLE / Reported as working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendAmcor(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { // Check if we have enough bytes to send a proper message. @@ -53,19 +47,15 @@ void IRsend::sendAmcor(const unsigned char data[], const uint16_t nbytes, #endif #if DECODE_AMCOR -// Decode the supplied Amcor HVAC message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kAmcorBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// +/// Decode the supplied Amcor HVAC message. +/// Status: STABLE / Reported as working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeAmcor(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + kHeader - 1 + offset) @@ -99,31 +89,48 @@ bool IRrecv::decodeAmcor(decode_results *results, uint16_t offset, } #endif +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRAmcorAc::IRAmcorAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRAmcorAc::begin(void) { _irsend.begin(); } #if SEND_AMCOR +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRAmcorAc::send(const uint16_t repeat) { _irsend.sendAmcor(getRaw(), kAmcorStateLength, repeat); } #endif // SEND_AMCOR +/// Calculate the checksum for the supplied state. +/// @param[in] state The source state to generate the checksum from. +/// @param[in] length Length of the supplied state to checksum. +/// @return The checksum value. uint8_t IRAmcorAc::calcChecksum(const uint8_t state[], const uint16_t length) { return irutils::sumNibbles(state, length - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The size of the state. +/// @return A boolean indicating if it's checksum is valid. bool IRAmcorAc::validChecksum(const uint8_t state[], const uint16_t length) { return (state[length - 1] == IRAmcorAc::calcChecksum(state, length)); } +/// Update the checksum value for the internal state. void IRAmcorAc::checksum(void) { remote_state[kAmcorChecksumByte] = IRAmcorAc::calcChecksum(remote_state, kAmcorStateLength); } +/// Reset the internals of the object to a known good state. void IRAmcorAc::stateReset(void) { for (uint8_t i = 1; i < kAmcorStateLength; i++) remote_state[i] = 0x0; remote_state[0] = 0x01; @@ -132,30 +139,42 @@ void IRAmcorAc::stateReset(void) { setTemp(25); // 25C } +/// Get the raw state of the object, suitable to be sent with the appropriate +/// IRsend object method. +/// @return A PTR to the internal state. uint8_t* IRAmcorAc::getRaw(void) { this->checksum(); // Ensure correct bit array before returning return remote_state; } +/// Set the raw state of the object. +/// @param[in] state The raw state from the native IR message. void IRAmcorAc::setRaw(const uint8_t state[]) { memcpy(remote_state, state, kAmcorStateLength); } +/// Set the internal state to have the power on. void IRAmcorAc::on(void) { setPower(true); } +/// Set the internal state to have the power off. void IRAmcorAc::off(void) { setPower(false); } +/// Set the internal state to have the desired power. +/// @param[in] on The desired power state. void IRAmcorAc::setPower(const bool on) { setBits(&remote_state[kAmcorPowerByte], kAmcorPowerOffset, kAmcorPowerSize, on ? kAmcorPowerOn : kAmcorPowerOff); } +/// Get the power setting from the internal state. +/// @return A boolean indicating the power setting. bool IRAmcorAc::getPower(void) { return GETBITS8(remote_state[kAmcorPowerByte], kAmcorPowerOffset, kAmcorPowerSize) == kAmcorPowerOn; } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRAmcorAc::setTemp(const uint8_t degrees) { uint8_t temp = std::max(kAmcorMinTemp, degrees); temp = std::min(kAmcorMaxTemp, temp); @@ -163,12 +182,16 @@ void IRAmcorAc::setTemp(const uint8_t degrees) { temp); } +/// Get the current temperature setting. +/// @return Get current setting for temp. in degrees celsius. uint8_t IRAmcorAc::getTemp(void) { return GETBITS8(remote_state[kAmcorTempByte], kAmcorTempOffset, kAmcorTempSize); } -// Maximum Cooling or Hearing +/// Control the current Maximum Cooling or Heating setting. (i.e. Turbo) +/// @note Only allowed in Cool or Heat mode. +/// @param[in] on The desired setting. void IRAmcorAc::setMax(const bool on) { if (on) { switch (getMode()) { @@ -182,12 +205,15 @@ void IRAmcorAc::setMax(const bool on) { on ? kAmcorMax : 0); } +/// Is the Maximum Cooling or Heating setting (i.e. Turbo) setting on? +/// @return The current value. bool IRAmcorAc::getMax(void) { return GETBITS8(remote_state[kAmcorSpecialByte], kAmcorMaxOffset, kAmcorMaxSize) == kAmcorMax; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRAmcorAc::setFan(const uint8_t speed) { switch (speed) { case kAmcorFanAuto: @@ -202,16 +228,22 @@ void IRAmcorAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRAmcorAc::getFan(void) { return GETBITS8(remote_state[kAmcorModeFanByte], kAmcorFanOffset, kAmcorFanSize); } +/// Get the current operation mode setting. +/// @return The current operation mode. uint8_t IRAmcorAc::getMode(void) { return GETBITS8(remote_state[kAmcorModeFanByte], kAmcorModeOffset, kAmcorModeSize); } +/// Set the desired operation mode. +/// @param[in] mode The desired operation mode. void IRAmcorAc::setMode(const uint8_t mode) { switch (mode) { case kAmcorFan: @@ -229,7 +261,9 @@ void IRAmcorAc::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRAmcorAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: @@ -245,7 +279,9 @@ uint8_t IRAmcorAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRAmcorAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -261,7 +297,9 @@ uint8_t IRAmcorAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRAmcorAc::toCommonMode(const uint8_t mode) { switch (mode) { case kAmcorCool: return stdAc::opmode_t::kCool; @@ -272,7 +310,9 @@ stdAc::opmode_t IRAmcorAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRAmcorAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kAmcorFanMax: return stdAc::fanspeed_t::kMax; @@ -282,7 +322,8 @@ stdAc::fanspeed_t IRAmcorAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRAmcorAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::AMCOR; @@ -307,7 +348,8 @@ stdAc::state_t IRAmcorAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRAmcorAc::toString(void) { String result = ""; result.reserve(70); // Reserve some heap for the string to reduce fragging. diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Amcor.h b/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.h similarity index 85% rename from lib/IRremoteESP8266-2.7.7/src/ir_Amcor.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Amcor.h index 401bb787c..f3ac1bad6 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Amcor.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.h @@ -1,7 +1,14 @@ -// Amcor A/C -// // Copyright 2019 David Conran +/// @file +/// @brief Amcor A/C protocol. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/834 +/// @remark Kudos to ldellus; For the breakdown and mapping of the bit values. +// Supports: +// Brand: Amcor, Model: ADR-853H A/C +// Brand: Amcor, Model: TAC-495 remote +// Brand: Amcor, Model: TAC-444 remote + #ifndef IR_AMCOR_H_ #define IR_AMCOR_H_ @@ -16,18 +23,9 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Amcor, Model: ADR-853H A/C -// Brand: Amcor, Model: TAC-495 remote -// Brand: Amcor, Model: TAC-444 remote -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/834 -// Kudos: -// ldellus: For the breakdown and mapping of the bit values. // Constants - // state[1] const uint8_t kAmcorModeFanByte = 1; // Fan Control @@ -78,6 +76,8 @@ const uint8_t kAmcorVentSize = 2; const uint8_t kAmcorChecksumByte = kAmcorStateLength - 1; // Classes + +/// Class for handling detailed Amcor A/C messages. class IRAmcorAc { public: explicit IRAmcorAc(const uint16_t pin, const bool inverted = false, @@ -86,6 +86,10 @@ class IRAmcorAc { void stateReset(); #if SEND_AMCOR void send(const uint16_t repeat = kAmcorDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_AMCOR void begin(); @@ -118,7 +122,9 @@ class IRAmcorAc { private: IRsend _irsend; #else + /// @cond IGNORE IRsendTest _irsend; + /// @endcond #endif uint8_t remote_state[kAmcorStateLength]; // The state of the IR remote. void checksum(void); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Argo.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Argo.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.7/src/ir_Argo.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Argo.cpp index 0c4656cb5..cbe32487e 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Argo.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Argo.cpp @@ -1,9 +1,8 @@ -/* -Node MCU/ESP8266 Sketch to emulate Argo Ulisse 13 DCI remote -Controls Argo Ulisse 13 DCI A/C -Copyright 2017 Schmolders -Copyright 2019 crankyoldgit -*/ +// Copyright 2017 Schmolders +// Copyright 2019 crankyoldgit +/// @file +/// @brief Argo A/C protocol. +/// Controls an Argo Ulisse 13 DCI A/C #include "ir_Argo.h" #include @@ -33,13 +32,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_ARGO -// Send an Argo A/C message. -// -// Args: -// data: An array of kArgoStateLength bytes containing the IR command. -// -// Status: BETA / Probably works. - +/// Send a Argo A/C formatted message. +/// Status: BETA / Probably works. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendArgo(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { // Check if we have enough bytes to send a proper message. @@ -51,18 +48,29 @@ void IRsend::sendArgo(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_ARGO +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRArgoAC::IRArgoAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRArgoAC::begin(void) { _irsend.begin(); } #if SEND_ARGO +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRArgoAC::send(const uint16_t repeat) { _irsend.sendArgo(getRaw(), kArgoStateLength, repeat); } #endif // SEND_ARGO +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The size of the state. +/// @return A boolean indicating if it's checksum is valid. uint8_t IRArgoAC::calcChecksum(const uint8_t state[], const uint16_t length) { // Corresponds to byte 11 being constant 0b01 // Only add up bytes to 9. byte 10 is 0b01 constant anyway. @@ -70,11 +78,16 @@ uint8_t IRArgoAC::calcChecksum(const uint8_t state[], const uint16_t length) { return sumBytes(state, length - 2, 2); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The size of the state. +/// @return A boolean indicating if it's checksum is valid. bool IRArgoAC::validChecksum(const uint8_t state[], const uint16_t length) { return ((state[length - 2] >> 2) + (state[length - 1] << 6)) == IRArgoAC::calcChecksum(state, length); } +/// Update the checksum for the internal state. void IRArgoAC::checksum(void) { uint8_t sum = IRArgoAC::calcChecksum(argo, kArgoStateLength); // Append sum to end of array @@ -84,6 +97,7 @@ void IRArgoAC::checksum(void) { argo[11] = sum >> 6; // Shift down 6 bits and add in two LSBs of bit 11 } +/// Reset the internals of the object to a known good state. void IRArgoAC::stateReset(void) { for (uint8_t i = 0; i < kArgoStateLength; i++) argo[i] = 0x0; @@ -102,33 +116,49 @@ void IRArgoAC::stateReset(void) { this->setFan(kArgoFanAuto); } +/// Get the raw state of the object, suitable to be sent with the appropriate +/// IRsend object method. +/// @return A PTR to the internal state. uint8_t* IRArgoAC::getRaw(void) { this->checksum(); // Ensure correct bit array before returning return argo; } +/// Set the raw state of the object. +/// @param[in] state The raw state from the native IR message. void IRArgoAC::setRaw(const uint8_t state[]) { memcpy(argo, state, kArgoStateLength); } +/// Set the internal state to have the power on. void IRArgoAC::on(void) { setPower(true); } +/// Set the internal state to have the power off. void IRArgoAC::off(void) { setPower(false); } +/// Set the internal state to have the desired power. +/// @param[in] on The desired power state. void IRArgoAC::setPower(const bool on) { setBit(&argo[9], kArgoPowerBitOffset, on); } +/// Get the power setting from the internal state. +/// @return A boolean indicating the power setting. bool IRArgoAC::getPower(void) { return GETBIT8(argo[9], kArgoPowerBitOffset); } +/// Control the current Max setting. (i.e. Turbo) +/// @param[in] on The desired setting. void IRArgoAC::setMax(const bool on) { setBit(&argo[9], kArgoMaxBitOffset, on); } +/// Is the Max (i.e. Turbo) setting on? +/// @return The current value. bool IRArgoAC::getMax(void) { return GETBIT8(argo[9], kArgoMaxBitOffset); } -// Set the temp in deg C -// Sending 0 equals +4 +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. +/// @note Sending 0 equals +4 void IRArgoAC::setTemp(const uint8_t degrees) { uint8_t temp = std::max(kArgoMinTemp, degrees); // delta 4 degrees. "If I want 12 degrees, I need to send 8" @@ -141,6 +171,8 @@ void IRArgoAC::setTemp(const uint8_t degrees) { temp >> kArgoTempLowSize); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRArgoAC::getTemp(void) { return ((GETBITS8(argo[3], kArgoTempHighOffset, kArgoTempHighSize) << kArgoTempLowSize) | @@ -148,26 +180,39 @@ uint8_t IRArgoAC::getTemp(void) { kArgoTempDelta; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] fan The desired setting. void IRArgoAC::setFan(const uint8_t fan) { setBits(&argo[3], kArgoFanOffset, kArgoFanSize, std::min(fan, kArgoFan3)); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRArgoAC::getFan(void) { return GETBITS8(argo[3], kArgoFanOffset, kArgoFanSize); } +/// Set the flap position. i.e. Swing. +/// @warning Not yet working! +/// @param[in] flap The desired setting. void IRArgoAC::setFlap(const uint8_t flap) { flap_mode = flap; // TODO(kaschmo): set correct bits for flap mode } +/// Get the flap position. i.e. Swing. +/// @warning Not yet working! +/// @return The current flap setting. uint8_t IRArgoAC::getFlap(void) { return flap_mode; } +/// Get the current operation mode setting. +/// @return The current operation mode. uint8_t IRArgoAC::getMode(void) { return GETBITS8(argo[2], kArgoModeOffset, kArgoModeSize); } +/// Set the desired operation mode. +/// @param[in] mode The desired operation mode. void IRArgoAC::setMode(const uint8_t mode) { switch (mode) { case kArgoCool: @@ -183,22 +228,34 @@ void IRArgoAC::setMode(const uint8_t mode) { } } +/// Turn on/off the Night mode. i.e. Sleep. +/// @param[in] on The desired setting. void IRArgoAC::setNight(const bool on) { setBit(&argo[9], kArgoNightBitOffset, on); } +/// Get the status of Night mode. i.e. Sleep. +/// @return true if on, false if off. bool IRArgoAC::getNight(void) { return GETBIT8(argo[9], kArgoNightBitOffset); } +/// Turn on/off the iFeel mode. +/// @param[in] on The desired setting. void IRArgoAC::setiFeel(const bool on) { setBit(&argo[9], kArgoIFeelBitOffset, on); } +/// Get the status of iFeel mode. +/// @return true if on, false if off. bool IRArgoAC::getiFeel(void) { return GETBIT8(argo[9], kArgoIFeelBitOffset); } +/// Set the time for the A/C +/// @warning Not yet working! void IRArgoAC::setTime(void) { // TODO(kaschmo): use function call from checksum to set time first } +/// Set the value for the current room temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRArgoAC::setRoomTemp(const uint8_t degrees) { uint8_t temp = std::min(degrees, kArgoMaxRoomTemp); temp = std::max(temp, kArgoTempDelta) - kArgoTempDelta; @@ -207,6 +264,8 @@ void IRArgoAC::setRoomTemp(const uint8_t degrees) { temp >> kArgoRoomTempLowSize); } +/// Get the currently stored value for the room temperature setting. +/// @return The current setting for the room temp. in degrees celsius. uint8_t IRArgoAC::getRoomTemp(void) { return ((GETBITS8(argo[4], kArgoRoomTempHighOffset, kArgoRoomTempHighSize) << kArgoRoomTempLowSize) | @@ -214,7 +273,9 @@ uint8_t IRArgoAC::getRoomTemp(void) { kArgoTempDelta; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRArgoAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: @@ -231,7 +292,9 @@ uint8_t IRArgoAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRArgoAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -247,7 +310,9 @@ uint8_t IRArgoAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRArgoAC::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -265,7 +330,9 @@ uint8_t IRArgoAC::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRArgoAC::toCommonMode(const uint8_t mode) { switch (mode) { case kArgoCool: return stdAc::opmode_t::kCool; @@ -276,7 +343,9 @@ stdAc::opmode_t IRArgoAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRArgoAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kArgoFan3: return stdAc::fanspeed_t::kMax; @@ -286,7 +355,8 @@ stdAc::fanspeed_t IRArgoAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRArgoAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::ARGO; @@ -311,7 +381,8 @@ stdAc::state_t IRArgoAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRArgoAC::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -374,22 +445,17 @@ String IRArgoAC::toString(void) { } #if DECODE_ARGO -// Decode the supplied Argo message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kArgoBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works. -// -// Note: -// This decoder is based soley off sendArgo(). We have no actual captures -// to test this against. If you have one of these units, please let us know. +/// Decode the supplied Argo message. +/// Status: BETA / Probably works. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @note This decoder is based soley off sendArgo(). We have no actual captures +/// to test this against. If you have one of these units, please let us know. bool IRrecv::decodeArgo(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Argo.h b/lib/IRremoteESP8266-2.7.8/src/ir_Argo.h similarity index 91% rename from lib/IRremoteESP8266-2.7.7/src/ir_Argo.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Argo.h index af674d46f..9104a051b 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Argo.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Argo.h @@ -1,5 +1,6 @@ // Copyright 2017 Schmolders -// Adds support for Argo Ulisse 13 DCI Mobile Split ACs. +/// @file +/// @brief Support for Argo Ulisse 13 DCI Mobile Split ACs. // Supports: // Brand: Argo, Model: Ulisse 13 DCI Mobile Split A/C @@ -124,6 +125,7 @@ const uint8_t kArgoFlapFull = 7; #define ARGO_FLAP_FULL kArgoFlapFull +/// Class for handling detailed Argo A/C messages. class IRArgoAC { public: explicit IRArgoAC(const uint16_t pin, const bool inverted = false, @@ -131,6 +133,10 @@ class IRArgoAC { #if SEND_ARGO void send(const uint16_t repeat = kArgoDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_ARGO void begin(void); @@ -181,9 +187,11 @@ class IRArgoAC { #ifndef UNIT_TEST private: - IRsend _irsend; // instance of the IR send class + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; // instance of the testing IR send class + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command uint8_t argo[kArgoStateLength]; // Defined in IRremoteESP8266.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp new file mode 100644 index 000000000..ab6b8176b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp @@ -0,0 +1,545 @@ +// Copyright 2018, 2020 David Conran +/// @file +/// @brief Carrier protocols. +/// @see CarrierAc https://github.com/crankyoldgit/IRremoteESP8266/issues/385 +/// @see CarrierAc64 https://github.com/crankyoldgit/IRremoteESP8266/issues/1127 + +#include "ir_Carrier.h" +#include +#include "IRac.h" +#include "IRrecv.h" +#include "IRsend.h" +#include "IRtext.h" +#include "IRutils.h" + +using irutils::addBoolToString; +using irutils::addIntToString; +using irutils::addLabeledString; +using irutils::addModeToString; +using irutils::addTempToString; +using irutils::addFanToString; +using irutils::minsToString; +using irutils::setBit; +using irutils::setBits; +using irutils::sumNibbles; + +// Constants +const uint16_t kCarrierAcHdrMark = 8532; +const uint16_t kCarrierAcHdrSpace = 4228; +const uint16_t kCarrierAcBitMark = 628; +const uint16_t kCarrierAcOneSpace = 1320; +const uint16_t kCarrierAcZeroSpace = 532; +const uint16_t kCarrierAcGap = 20000; +const uint16_t kCarrierAcFreq = 38; // kHz. (An educated guess) + +const uint16_t kCarrierAc40HdrMark = 8402; +const uint16_t kCarrierAc40HdrSpace = 4166; +const uint16_t kCarrierAc40BitMark = 547; +const uint16_t kCarrierAc40OneSpace = 1540; +const uint16_t kCarrierAc40ZeroSpace = 497; +const uint32_t kCarrierAc40Gap = 150000; ///< +///< @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1190#issuecomment-643380155 + +const uint16_t kCarrierAc64HdrMark = 8940; +const uint16_t kCarrierAc64HdrSpace = 4556; +const uint16_t kCarrierAc64BitMark = 503; +const uint16_t kCarrierAc64OneSpace = 1736; +const uint16_t kCarrierAc64ZeroSpace = 615; +const uint32_t kCarrierAc64Gap = kDefaultMessageGap; // A guess. + + +#if SEND_CARRIER_AC +/// Send a Carrier HVAC formatted message. +/// Status: STABLE / Works on real devices. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +void IRsend::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) { + for (uint16_t r = 0; r <= repeat; r++) { + uint64_t temp_data = data; + // Carrier sends the data block three times. normal + inverted + normal. + for (uint16_t i = 0; i < 3; i++) { + sendGeneric(kCarrierAcHdrMark, kCarrierAcHdrSpace, kCarrierAcBitMark, + kCarrierAcOneSpace, kCarrierAcBitMark, kCarrierAcZeroSpace, + kCarrierAcBitMark, kCarrierAcGap, temp_data, nbits, 38, true, + 0, kDutyDefault); + temp_data = invertBits(temp_data, nbits); + } + } +} +#endif + +#if DECODE_CARRIER_AC +/// Decode the supplied Carrier HVAC message. +/// @note Carrier HVAC messages contain only 32 bits, but it is sent three(3) +/// times. i.e. normal + inverted + normal +/// Status: BETA / Probably works. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +bool IRrecv::decodeCarrierAC(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < ((2 * nbits + kHeader + kFooter) * 3) - 1 + offset) + return false; // Can't possibly be a valid Carrier message. + if (strict && nbits != kCarrierAcBits) + return false; // We expect Carrier to be 32 bits of message. + + uint64_t data = 0; + uint64_t prev_data = 0; + + for (uint8_t i = 0; i < 3; i++) { + prev_data = data; + // Match Header + Data + Footer + uint16_t used; + used = matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kCarrierAcHdrMark, kCarrierAcHdrSpace, + kCarrierAcBitMark, kCarrierAcOneSpace, + kCarrierAcBitMark, kCarrierAcZeroSpace, + kCarrierAcBitMark, kCarrierAcGap, true); + if (!used) return false; + offset += used; + // Compliance. + if (strict) { + // Check if the data is an inverted copy of the previous data. + if (i > 0 && prev_data != invertBits(data, nbits)) return false; + } + } + + // Success + results->bits = nbits; + results->value = data; + results->decode_type = CARRIER_AC; + results->address = data >> 16; + results->command = data & 0xFFFF; + return true; +} +#endif // DECODE_CARRIER_AC + +#if SEND_CARRIER_AC40 +/// Send a Carrier 40bit HVAC formatted message. +/// Status: STABLE / Tested against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The bit size of the message being sent. +/// @param[in] repeat The number of times the message is to be repeated. +void IRsend::sendCarrierAC40(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kCarrierAc40HdrMark, kCarrierAc40HdrSpace, kCarrierAc40BitMark, + kCarrierAc40OneSpace, kCarrierAc40BitMark, kCarrierAc40ZeroSpace, + kCarrierAc40BitMark, kCarrierAc40Gap, + data, nbits, kCarrierAcFreq, true, repeat, kDutyDefault); +} +#endif // SEND_CARRIER_AC40 + +#if DECODE_CARRIER_AC40 +/// Decode the supplied Carrier 40-bit HVAC message. +/// Carrier HVAC messages contain only 40 bits, but it is sent three(3) times. +/// Status: STABLE / Tested against a real device. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +bool IRrecv::decodeCarrierAC40(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid Carrier message. + if (strict && nbits != kCarrierAc40Bits) + return false; // We expect Carrier to be 40 bits of message. + + if (!matchGeneric(results->rawbuf + offset, &(results->value), + results->rawlen - offset, nbits, + kCarrierAc40HdrMark, kCarrierAc40HdrSpace, + kCarrierAc40BitMark, kCarrierAc40OneSpace, + kCarrierAc40BitMark, kCarrierAc40ZeroSpace, + kCarrierAc40BitMark, kCarrierAc40Gap, true)) return false; + + // Success + results->bits = nbits; + results->decode_type = CARRIER_AC40; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_CARRIER_AC40 + +#if SEND_CARRIER_AC64 +/// Send a Carrier 64bit HVAC formatted message. +/// Status: STABLE / Known to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The bit size of the message being sent. +/// @param[in] repeat The number of times the message is to be repeated. +void IRsend::sendCarrierAC64(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kCarrierAc64HdrMark, kCarrierAc64HdrSpace, kCarrierAc64BitMark, + kCarrierAc64OneSpace, kCarrierAc64BitMark, kCarrierAc64ZeroSpace, + kCarrierAc64BitMark, kCarrierAc64Gap, + data, nbits, kCarrierAcFreq, false, repeat, kDutyDefault); +} +#endif // SEND_CARRIER_AC64 + +#if DECODE_CARRIER_AC64 +/// Decode the supplied Carrier 64-bit HVAC message. +/// Status: STABLE / Known to be working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +bool IRrecv::decodeCarrierAC64(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid Carrier message. + if (strict && nbits != kCarrierAc64Bits) + return false; // We expect Carrier to be 64 bits of message. + + if (!matchGeneric(results->rawbuf + offset, &(results->value), + results->rawlen - offset, nbits, + kCarrierAc64HdrMark, kCarrierAc64HdrSpace, + kCarrierAc64BitMark, kCarrierAc64OneSpace, + kCarrierAc64BitMark, kCarrierAc64ZeroSpace, + kCarrierAc64BitMark, kCarrierAc64Gap, true, + kUseDefTol, kMarkExcess, false)) return false; + + // Compliance + if (strict && !IRCarrierAc64::validChecksum(results->value)) return false; + + // Success + results->bits = nbits; + results->decode_type = CARRIER_AC64; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_CARRIER_AC64 + +/// Class constructor. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? +IRCarrierAc64::IRCarrierAc64(const uint16_t pin, const bool inverted, + const bool use_modulation) + : _irsend(pin, inverted, use_modulation) { stateReset(); } + +/// Reset the internal state to a fixed known good state. +/// @note The state is powered off. +void IRCarrierAc64::stateReset(void) { remote_state = 0x109000002C2A5584; } + +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return The 4-bit checksum stored in a uint_8. +uint8_t IRCarrierAc64::calcChecksum(const uint64_t state) { + uint64_t data = GETBITS64(state, + kCarrierAc64ChecksumOffset + kCarrierAc64ChecksumSize, kCarrierAc64Bits - + (kCarrierAc64ChecksumOffset + kCarrierAc64ChecksumSize)); + uint8_t result = 0; + for (; data; data >>= 4) // Add each nibble together. + result += GETBITS64(data, 0, 4); + return result & 0xF; +} + +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. +bool IRCarrierAc64::validChecksum(const uint64_t state) { + // Validate the checksum of the given state. + return (GETBITS64(state, kCarrierAc64ChecksumOffset, + kCarrierAc64ChecksumSize) == calcChecksum(state)); +} + +/// Calculate and set the checksum values for the internal state. +void IRCarrierAc64::checksum(void) { + setBits(&remote_state, kCarrierAc64ChecksumOffset, kCarrierAc64ChecksumSize, + calcChecksum(remote_state)); +} + +/// Set up hardware to be able to send a message. +void IRCarrierAc64::begin(void) { _irsend.begin(); } + +#if SEND_CARRIER_AC64 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRCarrierAc64::send(const uint16_t repeat) { + _irsend.sendCarrierAC64(getRaw(), kCarrierAc64Bits, repeat); +} +#endif // SEND_CARRIER_AC64 + +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. +uint64_t IRCarrierAc64::getRaw(void) { + checksum(); // Ensure correct settings before sending. + return remote_state; +} + +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. +void IRCarrierAc64::setRaw(const uint64_t state) { remote_state = state; } + +/// Set the temp in deg C. +/// @param[in] temp The desired temperature in Celsius. +void IRCarrierAc64::setTemp(const uint8_t temp) { + uint8_t degrees = std::max(temp, kCarrierAc64MinTemp); + degrees = std::min(degrees, kCarrierAc64MaxTemp); + setBits(&remote_state, kCarrierAc64TempOffset, kCarrierAc64TempSize, + degrees - kCarrierAc64MinTemp); +} + +/// Get the current temperature from the internal state. +/// @return The current temperature in Celsius. +uint8_t IRCarrierAc64::getTemp(void) { + return GETBITS64(remote_state, kCarrierAc64TempOffset, kCarrierAc64TempSize) + + kCarrierAc64MinTemp; +} + +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCarrierAc64::setPower(const bool on) { + setBit(&remote_state, kCarrierAc64PowerOffset, on); +} + +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. +bool IRCarrierAc64::getPower(void) { + return GETBIT64(remote_state, kCarrierAc64PowerOffset); +} + +/// Change the power setting to On. +void IRCarrierAc64::on(void) { setPower(true); } + +/// Change the power setting to Off. +void IRCarrierAc64::off(void) { setPower(false); } + +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. +uint8_t IRCarrierAc64::getMode(void) { + return GETBITS64(remote_state, kCarrierAc64ModeOffset, kCarrierAc64ModeSize); +} + +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +void IRCarrierAc64::setMode(const uint8_t mode) { + switch (mode) { + case kCarrierAc64Heat: + case kCarrierAc64Cool: + case kCarrierAc64Fan: + setBits(&remote_state, kCarrierAc64ModeOffset, kCarrierAc64ModeSize, + mode); + return; + default: + this->setMode(kCarrierAc64Cool); + } +} + +/// Convert a standard A/C mode into its native mode. +/// @param[in] mode A stdAc::opmode_t to be converted to it's native equivalent. +/// @return The corresponding native mode. +uint8_t IRCarrierAc64::convertMode(const stdAc::opmode_t mode) { + switch (mode) { + case stdAc::opmode_t::kHeat: return kCarrierAc64Heat; + case stdAc::opmode_t::kFan: return kCarrierAc64Fan; + default: return kCarrierAc64Cool; + } +} + +/// Convert a native mode to it's common stdAc::opmode_t equivalent. +/// @param[in] mode A native operation mode to be converted. +/// @return The corresponding common stdAc::opmode_t mode. +stdAc::opmode_t IRCarrierAc64::toCommonMode(const uint8_t mode) { + switch (mode) { + case kCarrierAc64Heat: return stdAc::opmode_t::kHeat; + case kCarrierAc64Fan: return stdAc::opmode_t::kFan; + default: return stdAc::opmode_t::kCool; + } +} + +/// Get the current fan speed setting. +/// @return The current fan speed. +uint8_t IRCarrierAc64::getFan(void) { + return GETBITS64(remote_state, kCarrierAc64FanOffset, kCarrierAc64FanSize); +} + +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +void IRCarrierAc64::setFan(const uint8_t speed) { + if (speed > kCarrierAc64FanHigh) + setFan(kCarrierAc64FanAuto); + else + setBits(&remote_state, kCarrierAc64FanOffset, kCarrierAc64FanSize, speed); +} + +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRCarrierAc64::convertFan(const stdAc::fanspeed_t speed) { + switch (speed) { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: return kCarrierAc64FanLow; + case stdAc::fanspeed_t::kMedium: return kCarrierAc64FanMedium; + case stdAc::fanspeed_t::kHigh: + case stdAc::fanspeed_t::kMax: return kCarrierAc64FanHigh; + default: return kCarrierAc64FanAuto; + } +} + +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::fanspeed_t IRCarrierAc64::toCommonFanSpeed(const uint8_t speed) { + switch (speed) { + case kCarrierAc64FanHigh: return stdAc::fanspeed_t::kHigh; + case kCarrierAc64FanMedium: return stdAc::fanspeed_t::kMedium; + case kCarrierAc64FanLow: return stdAc::fanspeed_t::kLow; + default: return stdAc::fanspeed_t::kAuto; + } +} + +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCarrierAc64::setSwingV(const bool on) { + setBit(&remote_state, kCarrierAc64SwingVOffset, on); +} + +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRCarrierAc64::getSwingV(void) { + return GETBIT64(remote_state, kCarrierAc64SwingVOffset); +} + +/// Set the Sleep mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCarrierAc64::setSleep(const bool on) { + if (on) { + // Sleep sets a default value in the Off timer, and disables both timers. + setOffTimer(2 * 60); + // Clear the enable bits for each timer. + _cancelOnTimer(); + _cancelOffTimer(); + } + setBit(&remote_state, kCarrierAc64SleepOffset, on); +} + +/// Get the Sleep mode of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRCarrierAc64::getSleep(void) { + return GETBIT64(remote_state, kCarrierAc64SleepOffset); +} + +/// Clear the On Timer enable bit. +void IRCarrierAc64::_cancelOnTimer(void) { + setBit(&remote_state, kCarrierAc64OnTimerEnableOffset, false); +} + +/// Get the current On Timer time. +/// @return The number of minutes it is set for. 0 means it's off. +/// @note The A/C protocol only supports one hour increments. +uint16_t IRCarrierAc64::getOnTimer(void) { + if (GETBIT64(remote_state, kCarrierAc64OnTimerEnableOffset)) + return GETBITS64(remote_state, kCarrierAc64OnTimerOffset, + kCarrierAc64TimerSize) * 60; + else + return 0; +} + +/// Set the On Timer time. +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (< 60 is disable). +/// @note The A/C protocol only supports one hour increments. +void IRCarrierAc64::setOnTimer(const uint16_t nr_of_mins) { + uint8_t hours = std::min((uint8_t)(nr_of_mins / 60), kCarrierAc64TimerMax); + setBit(&remote_state, kCarrierAc64OnTimerEnableOffset, hours); // Enable + setBits(&remote_state, kCarrierAc64OnTimerOffset, kCarrierAc64TimerSize, + std::max(kCarrierAc64TimerMin, hours)); // Hours + if (hours) { // If enabled, disable the Off Timer & Sleep mode. + _cancelOffTimer(); + setSleep(false); + } +} + +/// Clear the Off Timer enable bit. +void IRCarrierAc64::_cancelOffTimer(void) { + setBit(&remote_state, kCarrierAc64OffTimerEnableOffset, false); +} + +/// Get the current Off Timer time. +/// @return The number of minutes it is set for. 0 means it's off. +/// @note The A/C protocol only supports one hour increments. +uint16_t IRCarrierAc64::getOffTimer(void) { + if (GETBIT64(remote_state, kCarrierAc64OffTimerEnableOffset)) + return GETBITS64(remote_state, kCarrierAc64OffTimerOffset, + kCarrierAc64TimerSize) * 60; + else + return 0; +} + +/// Set the Off Timer time. +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (< 60 is disable). +/// @note The A/C protocol only supports one hour increments. +void IRCarrierAc64::setOffTimer(const uint16_t nr_of_mins) { + uint8_t hours = std::min((uint8_t)(nr_of_mins / 60), kCarrierAc64TimerMax); + // The time can be changed in sleep mode, but doesn't set the flag. + setBit(&remote_state, kCarrierAc64OffTimerEnableOffset, hours && !getSleep()); + setBits(&remote_state, kCarrierAc64OffTimerOffset, kCarrierAc64TimerSize, + std::max(kCarrierAc64TimerMin, hours)); // Hours + if (hours) { // If enabled, disable the On Timer & Sleep mode. + _cancelOnTimer(); + setSleep(false); + } +} + +/// Convert the internal state into a human readable string. +/// @return The current internal state expressed as a human readable String. +String IRCarrierAc64::toString(void) { + String result = ""; + result.reserve(120); // Reserve some heap for the string to reduce fragging. + result += addBoolToString(getPower(), kPowerStr, false); + result += addModeToString(getMode(), 0xFF, kCarrierAc64Cool, + kCarrierAc64Heat, 0xFF, kCarrierAc64Fan); + result += addTempToString(getTemp()); + result += addFanToString(getFan(), kCarrierAc64FanHigh, kCarrierAc64FanLow, + kCarrierAc64FanAuto, kCarrierAc64FanAuto, + kCarrierAc64FanMedium); + result += addBoolToString(getSwingV(), kSwingVStr); + result += addBoolToString(getSleep(), kSleepStr); + result += addLabeledString(getOnTimer() + ? minsToString(getOnTimer()) : kOffStr, + kOnTimerStr); + result += addLabeledString(getOffTimer() + ? minsToString(getOffTimer()) : kOffStr, + kOffTimerStr); + return result; +} + +/// Convert the A/C state to it's common stdAc::state_t equivalent. +/// @return A stdAc::state_t state. +stdAc::state_t IRCarrierAc64::toCommon(void) { + stdAc::state_t result; + result.protocol = decode_type_t::CARRIER_AC64; + result.model = -1; // No models used. + result.power = getPower(); + result.mode = toCommonMode(getMode()); + result.celsius = true; + result.degrees = getTemp(); + result.fanspeed = toCommonFanSpeed(getFan()); + result.swingv = getSwingV() ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff; + result.sleep = getSleep() ? 0 : -1; + // Not supported. + result.swingh = stdAc::swingh_t::kOff; + result.turbo = false; + result.quiet = false; + result.clean = false; + result.filter = false; + result.beep = false; + result.econo = false; + result.light = false; + result.clock = -1; + return result; +} diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h b/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h new file mode 100644 index 000000000..e2f4b7895 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h @@ -0,0 +1,131 @@ +// Copyright 2020 David Conran +/// @file +/// @brief Carrier A/C +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1127 +/// @see https://docs.google.com/spreadsheets/d/1EZy78L0cn1KDIX1aKq2biptejFqCjD5HO3tLiRvXf48/edit#gid=0 + +// Supports: +// Brand: Carrier/Surrey, Model: 42QG5A55970 remote +// Brand: Carrier/Surrey, Model: 619EGX0090E0 A/C +// Brand: Carrier/Surrey, Model: 619EGX0120E0 A/C +// Brand: Carrier/Surrey, Model: 619EGX0180E0 A/C +// Brand: Carrier/Surrey, Model: 619EGX0220E0 A/C +// Brand: Carrier/Surrey, Model: 53NGK009/012 Inverter + +#ifndef IR_CARRIER_H_ +#define IR_CARRIER_H_ + +#define __STDC_LIMIT_MACROS +#include +#ifndef UNIT_TEST +#include +#endif +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif + + +// Constants + +// CARRIER_AC64 +const uint8_t kCarrierAc64ChecksumOffset = 16; +const uint8_t kCarrierAc64ChecksumSize = 4; +const uint8_t kCarrierAc64ModeOffset = kCarrierAc64ChecksumOffset + + kCarrierAc64ChecksumSize; // 20 +const uint8_t kCarrierAc64ModeSize = 2; +const uint8_t kCarrierAc64Heat = 0b01; // 1 +const uint8_t kCarrierAc64Cool = 0b10; // 2 +const uint8_t kCarrierAc64Fan = 0b11; // 3 +const uint8_t kCarrierAc64FanOffset = kCarrierAc64ModeOffset + + kCarrierAc64ModeSize; // 22 +const uint8_t kCarrierAc64FanSize = 2; +const uint8_t kCarrierAc64FanAuto = 0b00; // 0 +const uint8_t kCarrierAc64FanLow = 0b01; // 1 +const uint8_t kCarrierAc64FanMedium = 0b10; // 2 +const uint8_t kCarrierAc64FanHigh = 0b11; // 3 +const uint8_t kCarrierAc64TempOffset = kCarrierAc64FanOffset + + kCarrierAc64FanSize; // 24 +const uint8_t kCarrierAc64TempSize = 4; +const uint8_t kCarrierAc64MinTemp = 16; // Celsius +const uint8_t kCarrierAc64MaxTemp = 30; // Celsius +const uint8_t kCarrierAc64SwingVOffset = kCarrierAc64TempOffset + + kCarrierAc64TempSize + 1; // 29 +const uint8_t kCarrierAc64PowerOffset = kCarrierAc64SwingVOffset + 6 + 1; // 36 +const uint8_t kCarrierAc64OffTimerEnableOffset = + kCarrierAc64PowerOffset + 1; // 37 +const uint8_t kCarrierAc64OnTimerEnableOffset = + kCarrierAc64OffTimerEnableOffset + 1; // 38 +const uint8_t kCarrierAc64SleepOffset = + kCarrierAc64OnTimerEnableOffset + 1; // 39 +const uint8_t kCarrierAc64TimerSize = 4; +const uint8_t kCarrierAc64TimerMax = 9; // Hours. +const uint8_t kCarrierAc64TimerMin = 1; // Hours. +const uint8_t kCarrierAc64OnTimerOffset = + kCarrierAc64SleepOffset + 12 + 1; // 52 +const uint8_t kCarrierAc64OffTimerOffset = kCarrierAc64OnTimerOffset + + kCarrierAc64TimerSize + 4; // 60 + + +// Classes + +/// Class for handling detailed Carrier 64 bit A/C messages. +class IRCarrierAc64 { + public: + explicit IRCarrierAc64(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + + void stateReset(); +#if SEND_CARRIER_AC64 + void send(const uint16_t repeat = kCarrierAc64MinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. + int8_t calibrate(void) { return _irsend.calibrate(); } +#endif // SEND_CARRIER_AC64 + void begin(); + static uint8_t calcChecksum(const uint64_t state); + static bool validChecksum(const uint64_t state); + void setPower(const bool on); + bool getPower(); + void on(); + void off(); + void setTemp(const uint8_t temp); + uint8_t getTemp(); + void setSwingV(const bool on); + bool getSwingV(void); + void setSleep(const bool on); + bool getSleep(void); + void setFan(const uint8_t speed); + uint8_t getFan(); + void setMode(const uint8_t mode); + uint8_t getMode(); + void setOnTimer(const uint16_t nr_of_mins); + uint16_t getOnTimer(void); + void setOffTimer(const uint16_t nr_of_mins); + uint16_t getOffTimer(void); + uint64_t getRaw(); + void setRaw(const uint64_t state); + uint8_t convertMode(const stdAc::opmode_t mode); + uint8_t convertFan(const stdAc::fanspeed_t speed); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + stdAc::state_t toCommon(void); + String toString(); +#ifndef UNIT_TEST + + private: + IRsend _irsend; ///< Instance of the IR send class +#else + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif + uint64_t remote_state; ///< The state of the IR remote. + void checksum(void); + void _cancelOnTimer(void); + void _cancelOffTimer(void); +}; +#endif // IR_CARRIER_H_ diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Coolix.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.cpp similarity index 75% rename from lib/IRremoteESP8266-2.7.7/src/ir_Coolix.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Coolix.cpp index 65535442a..b33a3cf43 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Coolix.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.cpp @@ -1,5 +1,9 @@ // Copyright bakrus // Copyright 2017,2019 David Conran +// added by (send) bakrus & (decode) crankyoldgit +/// @file +/// @brief Coolix A/C / heatpump +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/484 #include "ir_Coolix.h" #include @@ -11,18 +15,6 @@ #include "IRtext.h" #include "IRutils.h" -// Coolix A/C / heatpump added by (send) bakrus & (decode) crankyoldgit -// -// Supports: -// Brand: Beko, Model: RG57K7(B)/BGEF Remote -// Brand: Beko, Model: BINR 070/071 split-type A/C -// Brand: Midea, Model: RG52D/BGE Remote -// Brand: Midea, Model: MS12FU-10HRDN1-QRD0GW(B) A/C -// Brand: Midea, Model: MSABAU-07HRFN1-QRD0GW A/C (circa 2016) -// Brand: Tokio, Model: AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/484 - // Constants // Pulse parms are *50-100 for the Mark and *50+100 for the space // First MARK is the one after the long gap @@ -50,17 +42,12 @@ using irutils::setBit; using irutils::setBits; #if SEND_COOLIX -// Send a Coolix message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kCoolixBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE / Confirmed Working. -// -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_COOLIX.cpp +/// Send a Coolix message +/// Status: STABLE / Confirmed Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_COOLIX.cpp void IRsend::sendCOOLIX(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits % 8 != 0) return; // nbits is required to be a multiple of 8. @@ -94,15 +81,15 @@ void IRsend::sendCOOLIX(uint64_t data, uint16_t nbits, uint16_t repeat) { } #endif -// IRCoolixAC class -// Supports: -// RG57K7(B)/BGEF remote control for Beko BINR 070/071 split-type aircon. -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/484 +/// Class constructor. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRCoolixAC::IRCoolixAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Reset the internal state to a fixed known good state. void IRCoolixAC::stateReset() { setRaw(kCoolixDefaultState); clearSensorTemp(); @@ -116,9 +103,12 @@ void IRCoolixAC::stateReset() { swingVFlag = false; } +/// Set up hardware to be able to send a message. void IRCoolixAC::begin() { _irsend.begin(); } #if SEND_COOLIX +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRCoolixAC::send(const uint16_t repeat) { _irsend.sendCOOLIX(remote_state, kCoolixBits, repeat); // make sure to remove special state from remote_state @@ -127,8 +117,12 @@ void IRCoolixAC::send(const uint16_t repeat) { } #endif // SEND_COOLIX +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. uint32_t IRCoolixAC::getRaw() { return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRCoolixAC::setRaw(const uint32_t new_code) { powerFlag = true; // Everything that is not the special power off mesg is On. if (!handleSpecialState(new_code)) { @@ -143,7 +137,8 @@ void IRCoolixAC::setRaw(const uint32_t new_code) { remote_state = new_code; } -// Return true if the current state is a special state. +/// Is the current state is a special state? +/// @return true, if it is. false if it isn't. bool IRCoolixAC::isSpecialState(void) { switch (remote_state) { case kCoolixClean: @@ -156,8 +151,12 @@ bool IRCoolixAC::isSpecialState(void) { } } -// Special state means commands that are not -// affecting Temperature/Mode/Fan +/// Adjust any internal settings based on the type of special state we are +/// supplied. Does nothing if it isn't a special state. +/// @param[in] data The state we need to act upon. +/// @note Special state means commands that are not affecting +/// Temperature/Mode/Fan +/// @return true, if it is a special state. false if it isn't. bool IRCoolixAC::handleSpecialState(const uint32_t data) { switch (data) { case kCoolixClean: @@ -184,12 +183,15 @@ bool IRCoolixAC::handleSpecialState(const uint32_t data) { return true; } -// must be called before every special state -// to make sure the remote_state is safe +/// Backup the current internal state as long as it isn't a special state. +/// @note: Must be called before every special state to make sure the +/// remote_state is safe void IRCoolixAC::updateSavedState(void) { if (!isSpecialState()) saved_state = remote_state; } +/// Restore the current internal state from backup as long as it isn't a +/// special state. void IRCoolixAC::recoverSavedState(void) { // If the current state is a special one, last known normal one. if (isSpecialState()) remote_state = saved_state; @@ -198,14 +200,21 @@ void IRCoolixAC::recoverSavedState(void) { if (isSpecialState()) stateReset(); } +/// Set the raw (native) temperature value. +/// @note Bypasses any checks. +/// @param[in] code The desired native temperature. void IRCoolixAC::setTempRaw(const uint8_t code) { setBits(&remote_state, kCoolixTempOffset, kCoolixTempSize, code); } +/// Get the raw (native) temperature value. +/// @return The native temperature value. uint8_t IRCoolixAC::getTempRaw() { return GETBITS32(remote_state, kCoolixTempOffset, kCoolixTempSize); } +/// Set the temperature. +/// @param[in] desired The temperature in degrees celsius. void IRCoolixAC::setTemp(const uint8_t desired) { // Range check. uint8_t temp = std::min(desired, kCoolixTempMax); @@ -213,6 +222,8 @@ void IRCoolixAC::setTemp(const uint8_t desired) { setTempRaw(kCoolixTempMap[temp - kCoolixTempMin]); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRCoolixAC::getTemp() { const uint8_t code = getTempRaw(); for (uint8_t i = 0; i < kCoolixTempRange; i++) @@ -220,10 +231,15 @@ uint8_t IRCoolixAC::getTemp() { return kCoolixTempMax; // Not a temp we expected. } +/// Set the raw (native) sensor temperature value. +/// @note Bypasses any checks or additional actions. +/// @param[in] code The desired native sensor temperature. void IRCoolixAC::setSensorTempRaw(const uint8_t code) { setBits(&remote_state, kCoolixSensorTempOffset, kCoolixSensorTempSize, code); } +/// Set the sensor temperature. +/// @param[in] desired The temperature in degrees celsius. void IRCoolixAC::setSensorTemp(const uint8_t desired) { uint8_t temp = desired; temp = std::min(temp, kCoolixSensorTempMax); @@ -232,16 +248,22 @@ void IRCoolixAC::setSensorTemp(const uint8_t desired) { setZoneFollow(true); // Setting a Sensor temp means you want to Zone Follow. } +/// Get the sensor temperature setting. +/// @return The current setting for sensor temp. in degrees celsius. uint8_t IRCoolixAC::getSensorTemp() { return GETBITS32(remote_state, kCoolixSensorTempOffset, kCoolixSensorTempSize) + kCoolixSensorTempMin; } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getPower() { // There is only an off state. Everything else is "on". return powerFlag; } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRCoolixAC::setPower(const bool on) { if (!on) { updateSavedState(); @@ -254,12 +276,17 @@ void IRCoolixAC::setPower(const bool on) { powerFlag = on; } +/// Change the power setting to On. void IRCoolixAC::on(void) { this->setPower(true); } +/// Change the power setting to Off. void IRCoolixAC::off(void) { this->setPower(false); } +/// Get the Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getSwing() { return swingFlag; } +/// Toggle the Swing mode of the A/C. void IRCoolixAC::setSwing() { // Assumes that repeated sending "swing" toggles the action on the device. updateSavedState(); @@ -267,16 +294,22 @@ void IRCoolixAC::setSwing() { swingFlag = !swingFlag; } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getSleep() { return sleepFlag; } +/// Toggle the Sleep mode of the A/C. void IRCoolixAC::setSleep() { updateSavedState(); remote_state = kCoolixSleep; sleepFlag = !sleepFlag; } +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getTurbo() { return turboFlag; } +/// Toggle the Turbo mode of the A/C. void IRCoolixAC::setTurbo() { // Assumes that repeated sending "turbo" toggles the action on the device. updateSavedState(); @@ -284,8 +317,11 @@ void IRCoolixAC::setTurbo() { turboFlag = !turboFlag; } +/// Get the Led (light) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getLed() { return ledFlag; } +/// Toggle the Led (light) mode of the A/C. void IRCoolixAC::setLed() { // Assumes that repeated sending "Led" toggles the action on the device. updateSavedState(); @@ -293,29 +329,39 @@ void IRCoolixAC::setLed() { ledFlag = !ledFlag; } +/// Get the Clean setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getClean() { return cleanFlag; } +/// Toggle the Clean mode of the A/C. void IRCoolixAC::setClean() { updateSavedState(); remote_state = kCoolixClean; cleanFlag = !cleanFlag; } +/// Get the Zone Follow setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getZoneFollow() { return zoneFollowFlag; } -// Internal use only. +/// Change the Zone Follow setting. +/// @note Internal use only. +/// @param[in] on true, the setting is on. false, the setting is off. void IRCoolixAC::setZoneFollow(bool on) { zoneFollowFlag = on; setBit(&remote_state, kCoolixZoneFollowMaskOffset, on); } +/// Clear the Sensor Temperature setting.. void IRCoolixAC::clearSensorTemp() { setZoneFollow(false); setSensorTempRaw(kCoolixSensorTempIgnoreCode); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRCoolixAC::setMode(const uint8_t mode) { uint32_t actualmode = mode; switch (actualmode) { @@ -342,6 +388,8 @@ void IRCoolixAC::setMode(const uint8_t mode) { setBits(&remote_state, kCoolixModeOffset, kCoolixModeSize, actualmode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRCoolixAC::getMode() { uint8_t mode = GETBITS32(remote_state, kCoolixModeOffset, kCoolixModeSize); @@ -350,10 +398,15 @@ uint8_t IRCoolixAC::getMode() { return mode; } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRCoolixAC::getFan() { return GETBITS32(remote_state, kCoolixFanOffset, kCoolixFanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @param[in] modecheck Do we enforce any mode limitations before setting? void IRCoolixAC::setFan(const uint8_t speed, const bool modecheck) { uint8_t newspeed = speed; switch (speed) { @@ -389,7 +442,9 @@ void IRCoolixAC::setFan(const uint8_t speed, const bool modecheck) { setBits(&remote_state, kCoolixFanOffset, kCoolixFanSize, newspeed); } -// Convert a standard A/C mode into its native mode. +/// Convert a standard A/C mode into its native mode. +/// @param[in] mode A stdAc::opmode_t to be converted to it's native equivalent. +/// @return The corresponding native mode. uint8_t IRCoolixAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kCoolixCool; @@ -400,7 +455,9 @@ uint8_t IRCoolixAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRCoolixAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -412,7 +469,9 @@ uint8_t IRCoolixAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode to it's common stdAc::opmode_t equivalent. +/// @param[in] mode A native operation mode to be converted. +/// @return The corresponding common stdAc::opmode_t mode. stdAc::opmode_t IRCoolixAC::toCommonMode(const uint8_t mode) { switch (mode) { case kCoolixCool: return stdAc::opmode_t::kCool; @@ -423,7 +482,9 @@ stdAc::opmode_t IRCoolixAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRCoolixAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kCoolixFanMax: return stdAc::fanspeed_t::kMax; @@ -433,8 +494,9 @@ stdAc::fanspeed_t IRCoolixAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. Utilise the previous -// state if supplied. +/// Convert the A/C state to it's common stdAc::state_t equivalent. +/// @param[in] prev Ptr to the previous state if required. +/// @return A stdAc::state_t state. stdAc::state_t IRCoolixAC::toCommon(const stdAc::state_t *prev) { stdAc::state_t result; // Start with the previous state if given it. @@ -492,7 +554,8 @@ stdAc::state_t IRCoolixAC::toCommon(const stdAc::state_t *prev) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return The current internal state expressed as a human readable String. String IRCoolixAC::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -575,18 +638,15 @@ String IRCoolixAC::toString(void) { } #if DECODE_COOLIX -// Decode the supplied Coolix message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kCoolixBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known Working. +/// Decode the supplied Coolix A/C message. +/// Status: STABLE / Known Working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeCOOLIX(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // The protocol sends the data normal + inverted, alternating on diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Coolix.h b/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.h similarity index 88% rename from lib/IRremoteESP8266-2.7.7/src/ir_Coolix.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Coolix.h index 7ffcf01a9..3b95aa2e4 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Coolix.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.h @@ -2,6 +2,15 @@ // // Copyright 2018 David Conran +// Supports: +// Brand: Beko, Model: RG57K7(B)/BGEF Remote +// Brand: Beko, Model: BINR 070/071 split-type A/C +// Brand: Midea, Model: RG52D/BGE Remote +// Brand: Midea, Model: MS12FU-10HRDN1-QRD0GW(B) A/C +// Brand: Midea, Model: MSABAU-07HRFN1-QRD0GW A/C (circa 2016) +// Brand: Tokio, Model: AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote +// Brand: Airwell, Model: RC08B remote + #ifndef IR_COOLIX_H_ #define IR_COOLIX_H_ @@ -16,14 +25,6 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Beko, Model: RG57K7(B)/BGEF Remote -// Brand: Beko, Model: BINR 070/071 split-type A/C -// Brand: Midea, Model: RG52D/BGE Remote -// Brand: Midea, Model: MS12FU-10HRDN1-QRD0GW(B) A/C -// Brand: Midea, Model: MSABAU-07HRFN1-QRD0GW A/C (circa 2016) -// Brand: Tokio, Model: AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote -// Brand: Airwell, Model: RC08B remote // Ref: // https://github.com/crankyoldgit/IRremoteESP8266/issues/484 // Kudos: @@ -98,14 +99,20 @@ const uint32_t kCoolixCmdFan = 0b101100101011111111100100; // 0xB2BFE4 const uint32_t kCoolixDefaultState = 0b101100100001111111001000; // 0xB21FC8 // Classes + +/// Class for handling detailed Coolix A/C messages. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/484 class IRCoolixAC { public: explicit IRCoolixAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(); #if SEND_COOLIX void send(const uint16_t repeat = kCoolixDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_COOLIX void begin(); @@ -144,9 +151,11 @@ class IRCoolixAC { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif // internal state bool powerFlag; @@ -159,8 +168,8 @@ class IRCoolixAC { bool swingHFlag; bool swingVFlag; - uint32_t remote_state; // The state of the IR remote in IR code form. - uint32_t saved_state; // Copy of the state if we required a special mode. + uint32_t remote_state; ///< The state of the IR remote in IR code form. + uint32_t saved_state; ///< Copy of the state if we required a special mode. void setTempRaw(const uint8_t code); uint8_t getTempRaw(); void setSensorTempRaw(const uint8_t code); diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp new file mode 100644 index 000000000..2ba6044bf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp @@ -0,0 +1,598 @@ +// Copyright 2020 Christian Nilsson +// +/// @file +/// @brief Corona A/C protocol +/// @note Unsupported: +/// - Auto/Max button press (special format) + +#include "ir_Corona.h" +#include +#include +#include "IRac.h" +#include "IRrecv.h" +#include "IRsend.h" +#include "IRtext.h" +#include "IRutils.h" + +using irutils::addBoolToString; +using irutils::addLabeledString; +using irutils::addModeToString; +using irutils::addTempToString; +using irutils::addFanToString; +using irutils::minsToString; +using irutils::setBit; +using irutils::setBits; + +// Constants +const uint16_t kCoronaAcHdrMark = 3500; +const uint16_t kCoronaAcHdrSpace = 1680; +const uint16_t kCoronaAcBitMark = 450; +const uint16_t kCoronaAcOneSpace = 1270; +const uint16_t kCoronaAcZeroSpace = 420; +const uint16_t kCoronaAcSpaceGap = 10800; +const uint16_t kCoronaAcFreq = 38000; // Hz. +const uint16_t kCoronaAcOverheadShort = 3; +const uint16_t kCoronaAcOverhead = 11; // full message +const uint8_t kCoronaTolerance = 5; // +5% + +#if SEND_CORONA_AC +/// Send a CoronaAc formatted message. +/// Status: STABLE / Working on real device. +/// @param[in] data An array of bytes containing the IR command. +/// @param[in] nbytes Nr. of bytes of data in the array. +/// e.g. +/// @code +/// uint8_t data[kCoronaAcStateLength] = { +/// 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8, +/// 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, +/// 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; +/// @endcode +/// @param[in] repeat Nr. of times the message is to be repeated. +void IRsend::sendCoronaAc(const uint8_t data[], + const uint16_t nbytes, const uint16_t repeat) { + if (nbytes < kCoronaAcSectionBytes) return; + if (kCoronaAcSectionBytes < nbytes && + nbytes < kCoronaAcStateLength) return; + for (uint16_t r = 0; r <= repeat; r++) { + uint16_t pos = 0; + // Data Section #1 - 3 loop + // e.g. + // bits = 56; bytes = 7; + // #1 *(data + pos) = {0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8}; + // #2 *(data + pos) = {0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00}; + // #3 *(data + pos) = {0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + for (uint8_t section = 0; section < kCoronaAcSections; section++) { + sendGeneric(kCoronaAcHdrMark, kCoronaAcHdrSpace, + kCoronaAcBitMark, kCoronaAcOneSpace, + kCoronaAcBitMark, kCoronaAcZeroSpace, + kCoronaAcBitMark, kCoronaAcSpaceGap, + data + pos, kCoronaAcSectionBytes, + kCoronaAcFreq, false, kNoRepeat, kDutyDefault); + pos += kCoronaAcSectionBytes; // Adjust by how many bytes was sent + // don't send more data then what we have + if (nbytes <= pos) + break; + } + } +} +#endif // SEND_CORONA_AC + +#if DECODE_CORONA_AC +/// Decode the supplied CoronaAc message. +/// Status: STABLE / Appears to be working. +/// @param[in,out] results Ptr to the data to decode & where to store it +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +bool IRrecv::decodeCoronaAc(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + bool isLong = results->rawlen >= kCoronaAcBits * 2; + if (results->rawlen < 2 * nbits + + (isLong ? kCoronaAcOverhead : kCoronaAcOverheadShort) + - offset) + return false; // Too short a message to match. + if (strict && nbits != kCoronaAcBits && nbits != kCoronaAcBitsShort) + return false; + + uint16_t pos = 0; + uint16_t used = 0; + + // Data Section #1 - 3 loop + // e.g. + // bits = 56; bytes = 7; + // #1 *(results->state + pos) = {0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8}; + // #2 *(results->state + pos) = {0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00}; + // #3 *(results->state + pos) = {0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + for (uint8_t section = 0; section < kCoronaAcSections; section++) { + DPRINT(uint64ToString(section)); + used = matchGeneric(results->rawbuf + offset, results->state + pos, + results->rawlen - offset, kCoronaAcBitsShort, + kCoronaAcHdrMark, kCoronaAcHdrSpace, + kCoronaAcBitMark, kCoronaAcOneSpace, + kCoronaAcBitMark, kCoronaAcZeroSpace, + kCoronaAcBitMark, kCoronaAcSpaceGap, true, + _tolerance + kCoronaTolerance, kMarkExcess, false); + if (used == 0) return false; // We failed to find any data. + // short versions section 0 is special + if (strict && !IRCoronaAc::validSection(results->state, pos, + isLong ? section : 3)) + return false; + offset += used; // Adjust for how much of the message we read. + pos += kCoronaAcSectionBytes; // Adjust by how many bytes of data was read + // don't read more data then what we have + if (results->rawlen <= offset) + break; + } + + // Re-check we got the correct size/length due to the way we read the data. + if (strict && pos * 8 != kCoronaAcBits && pos * 8 != kCoronaAcBitsShort) { + DPRINTLN("strict bit match fail"); + return false; + } + + // Success + results->decode_type = decode_type_t::CORONA_AC; + results->bits = pos * 8; + // No need to record the state as we stored it as we decoded it. + // As we use result->state, we don't record value, address, or command as it + // is a union data type. + return true; +} +#endif // DECODE_CORONA_AC + +/// Class constructor for handling detailed Corona A/C messages. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? +IRCoronaAc::IRCoronaAc(const uint16_t pin, const bool inverted, + const bool use_modulation) + : _irsend(pin, inverted, use_modulation) { stateReset(); } + +/// Reset the internal state to a fixed known good state. +/// @note The state is powered off. +void IRCoronaAc::stateReset(void) { + // known good state + remote_state[kCoronaAcSectionData0Pos] = kCoronaAcSectionData0Base; + remote_state[kCoronaAcSectionData1Pos] = 0x00; // ensure no unset mem + setPowerButton(true); // we default to this on, any timer removes it + setTemp(kCoronaAcMinTemp); + setMode(kCoronaAcModeCool); + setFan(kCoronaAcFanAuto); + setOnTimer(kCoronaAcTimerOff); + setOffTimer(kCoronaAcTimerOff); + // headers and checks are fixed in getRaw by checksum(remote_state) +} + +/// Get the byte that identifies the section +/// @param[in] section Index of the section 0-2, +/// 3 and above is used as the special case for short message +/// @return The byte used for the section +uint8_t IRCoronaAc::getSectionByte(const uint8_t section) { + // base byte + uint8_t b = kCoronaAcSectionLabelBase; + // 2 enabled bits shifted 0-2 bits depending on section + if (section >= 3) + return 0b10010000 | b; + setBits(&b, kHighNibble, kNibbleSize, 0b11 << section); + return b; +} + +/// Check that a CoronaAc Section part is valid with section byte and inverted +/// @param[in] state An array of bytes containing the section +/// @param[in] pos Where to start in the state array +/// @param[in] section Which section to work with +/// Used to get the section byte, and is validated against pos +/// @return true if section is valid, otherwise false +bool IRCoronaAc::validSection(const uint8_t state[], const uint16_t pos, + const uint8_t section) { + // sanity check, pos must match section, section 4 is at pos 0 + if ((section % kCoronaAcSections) * kCoronaAcSectionBytes != pos) + return false; + // all individual sections has the same prefix + if (state[pos + kCoronaAcSectionHeader0Pos] != kCoronaAcSectionHeader0) { + DPRINT("State "); + DPRINT(pos + kCoronaAcSectionHeader0Pos); + DPRINT(" expected 0x28 was "); + DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionHeader0Pos], 16)); + return false; + } + if (state[pos + kCoronaAcSectionHeader1Pos] != kCoronaAcSectionHeader1) { + DPRINT("State "); + DPRINT(pos + kCoronaAcSectionHeader1Pos); + DPRINT(" expected 0x61 was "); + DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionHeader1Pos], 16)); + return false; + } + + // checking section byte + if (state[pos + kCoronaAcSectionLabelPos] != getSectionByte(section)) { + DPRINT("check 2 not matching, got "); + DPRINT(uint64ToString(state[pos + kCoronaAcSectionLabelPos], 16)); + DPRINT(" expected "); + DPRINTLN(uint64ToString(getSectionByte(section), 16)); + return false; + } + + // checking inverts + uint8_t d0invinv = ~state[pos + kCoronaAcSectionData0InvPos]; + if (state[pos + kCoronaAcSectionData0Pos] != d0invinv) { + DPRINT("inverted 3 - 4 not matching, got "); + DPRINT(uint64ToString(state[pos + kCoronaAcSectionData0Pos], 16)); + DPRINT(" vs "); + DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionData0InvPos], 16)); + return false; + } + uint8_t d1invinv = ~state[pos + kCoronaAcSectionData1InvPos]; + if (state[pos + kCoronaAcSectionData1Pos] != d1invinv) { + DPRINT("inverted 5 - 6 not matching, got "); + DPRINT(uint64ToString(state[pos + kCoronaAcSectionData1Pos], 16)); + DPRINT(" vs "); + DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionData1InvPos], 16)); + return false; + } + return true; +} + +/// Calculate and set the check values for the internal state. +/// @param[in,out] data The array to be modified +void IRCoronaAc::checksum(uint8_t* data) { + uint8_t pos; + for (uint8_t section = 0; section < kCoronaAcSections; section++) { + pos = section * kCoronaAcSectionBytes; + data[pos + kCoronaAcSectionHeader0Pos] = kCoronaAcSectionHeader0; + data[pos + kCoronaAcSectionHeader1Pos] = kCoronaAcSectionHeader1; + data[pos + kCoronaAcSectionLabelPos] = getSectionByte(section); + data[pos + kCoronaAcSectionData0InvPos] = + ~data[pos + kCoronaAcSectionData0Pos]; + data[pos + kCoronaAcSectionData1InvPos] = + ~data[pos + kCoronaAcSectionData1Pos]; + } +} + +/// Set up hardware to be able to send a message. +void IRCoronaAc::begin(void) { _irsend.begin(); } + +#if SEND_CORONA_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRCoronaAc::send(const uint16_t repeat) { + // if no timer, always send once without power press + if (!getOnTimer() && !getOffTimer()) { + setPowerButton(false); + _irsend.sendCoronaAc(getRaw(), kCoronaAcStateLength, repeat); + // and then with power press + setPowerButton(true); + } + _irsend.sendCoronaAc(getRaw(), kCoronaAcStateLength, repeat); +} +#endif // SEND_CORONA_AC + +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A Ptr to a valid code for this protocol based on the current +/// internal state. +/// @note To get stable AC state, if no timers, send once +/// without PowerButton set, and once with +uint8_t* IRCoronaAc::getRaw(void) { + checksum(remote_state); // Ensure correct check bits before sending. + return remote_state; +} + +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid state for this protocol. +/// @param[in] length of the new_code array. +void IRCoronaAc::setRaw(const uint8_t new_code[], const uint16_t length) { + memcpy(remote_state, new_code, std::min(length, kCoronaAcStateLength)); +} + +/// Set the temp in deg C. +/// @param[in] temp The desired temperature in Celsius. +void IRCoronaAc::setTemp(const uint8_t temp) { + uint8_t degrees = std::max(temp, kCoronaAcMinTemp); + degrees = std::min(degrees, kCoronaAcMaxTemp); + setBits(&remote_state[kCoronaAcSectionData1Pos], kCoronaAcTempOffset, + kCoronaAcTempSize, degrees - kCoronaAcMinTemp + 1); +} + +/// Get the current temperature from the internal state. +/// @return The current temperature in Celsius. +uint8_t IRCoronaAc::getTemp(void) { + return GETBITS8(remote_state[kCoronaAcSectionData1Pos], kCoronaAcTempOffset, + kCoronaAcTempSize) + kCoronaAcMinTemp - 1; +} + +/// Change the power setting. (in practice Standby, remote power) +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCoronaAc::_setPower(const bool on) { + setBit(&remote_state[kCoronaAcSectionData1Pos], kCoronaAcPowerOffset, on); +} + +/// Change the power setting. (in practice Standby, remote power) +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note If changed, setPowerButton is also needed, +/// unless timer is or was active +void IRCoronaAc::setPower(const bool on) { + _setPower(on); + // setting power state resets timers that would cause the state + if (on) + setOnTimer(kCoronaAcTimerOff); + else + setOffTimer(kCoronaAcTimerOff); +} + +/// Get the current power setting. (in practice Standby, remote power) +/// @return true, the setting is on. false, the setting is off. +bool IRCoronaAc::getPower(void) { + return GETBIT8(remote_state[kCoronaAcSectionData1Pos], kCoronaAcPowerOffset); +} + +/// Change the power button setting. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note this sets that the AC should set power, +/// use setPower to define if the AC should end up as on or off +/// When no timer is active, the below is a truth table +/// With AC On, a command with setPower and setPowerButton gives nothing +/// With AC On, a command with setPower but not setPowerButton is ok +/// With AC Off, a command with setPower but not setPowerButton gives nothing +/// With AC Off, a command with setPower and setPowerButton is ok +void IRCoronaAc::setPowerButton(const bool on) { + setBit(&remote_state[kCoronaAcSectionData1Pos], + kCoronaAcPowerButtonOffset, on); +} + +/// Get the value of the current power button setting. +/// @return true, the setting is on. false, the setting is off. +bool IRCoronaAc::getPowerButton(void) { + return GETBIT8(remote_state[kCoronaAcSectionData1Pos], + kCoronaAcPowerButtonOffset); +} + +/// Change the power setting to On. +void IRCoronaAc::on(void) { setPower(true); } + +/// Change the power setting to Off. +void IRCoronaAc::off(void) { setPower(false); } + +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. +uint8_t IRCoronaAc::getMode(void) { + return GETBITS8(remote_state[kCoronaAcSectionData1Pos], + kCoronaAcModeOffset, kCoronaAcModeSize); +} + +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +void IRCoronaAc::setMode(const uint8_t mode) { + switch (mode) { + case kCoronaAcModeCool: + case kCoronaAcModeDry: + case kCoronaAcModeFan: + case kCoronaAcModeHeat: + setBits(&remote_state[kCoronaAcSectionData1Pos], + kCoronaAcModeOffset, kCoronaAcModeSize, + mode); + return; + default: + this->setMode(kCoronaAcModeCool); + } +} + +/// Convert a standard A/C mode into its native mode. +/// @param[in] mode A stdAc::opmode_t mode to be +/// converted to it's native equivalent +/// @return The corresponding native mode. +uint8_t IRCoronaAc::convertMode(const stdAc::opmode_t mode) { + switch (mode) { + case stdAc::opmode_t::kFan: return kCoronaAcModeFan; + case stdAc::opmode_t::kDry: return kCoronaAcModeDry; + case stdAc::opmode_t::kHeat: return kCoronaAcModeHeat; + default: return kCoronaAcModeCool; + } +} + +/// Convert a native mode to it's common stdAc::opmode_t equivalent. +/// @param[in] mode A native operation mode to be converted. +/// @return The corresponding common stdAc::opmode_t mode. +stdAc::opmode_t IRCoronaAc::toCommonMode(const uint8_t mode) { + switch (mode) { + case kCoronaAcModeFan: return stdAc::opmode_t::kFan; + case kCoronaAcModeDry: return stdAc::opmode_t::kDry; + case kCoronaAcModeHeat: return stdAc::opmode_t::kHeat; + default: return stdAc::opmode_t::kCool; + } +} + +/// Get the operating speed of the A/C Fan +/// @return The current operating fan speed setting +uint8_t IRCoronaAc::getFan(void) { + return GETBITS8(remote_state[kCoronaAcSectionData0Pos], + kCoronaAcFanOffset, kCoronaAcFanSize); +} + +/// Set the operating speed of the A/C Fan +/// @param[in] speed The desired fan speed +void IRCoronaAc::setFan(const uint8_t speed) { + if (speed > kCoronaAcFanHigh) + setFan(kCoronaAcFanAuto); + else + setBits(&remote_state[kCoronaAcSectionData0Pos], + kCoronaAcFanOffset, kCoronaAcFanSize, speed); +} + +/// Change the powersave setting. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCoronaAc::setEcono(const bool on) { + setBit(&remote_state[kCoronaAcSectionData0Pos], kCoronaAcPowerSaveOffset, on); +} + +/// Get the value of the current powersave setting. +/// @return true, the setting is on. false, the setting is off. +bool IRCoronaAc::getEcono(void) { + return GETBIT8(remote_state[kCoronaAcSectionData0Pos], + kCoronaAcPowerSaveOffset); +} + +/// Convert a standard A/C Fan speed into its native fan speed. +/// @param[in] speed The desired stdAc::fanspeed_t fan speed +/// @return The given fan speed in native format +uint8_t IRCoronaAc::convertFan(const stdAc::fanspeed_t speed) { + switch (speed) { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: return kCoronaAcFanLow; + case stdAc::fanspeed_t::kMedium: return kCoronaAcFanMedium; + case stdAc::fanspeed_t::kHigh: + case stdAc::fanspeed_t::kMax: return kCoronaAcFanHigh; + default: return kCoronaAcFanAuto; + } +} + +/// Convert a native fan speed to it's common equivalent. +/// @param[in] speed The desired native fan speed +/// @return The given fan speed in stdAc::fanspeed_t format +stdAc::fanspeed_t IRCoronaAc::toCommonFanSpeed(const uint8_t speed) { + switch (speed) { + case kCoronaAcFanHigh: return stdAc::fanspeed_t::kHigh; + case kCoronaAcFanMedium: return stdAc::fanspeed_t::kMedium; + case kCoronaAcFanLow: return stdAc::fanspeed_t::kLow; + default: return stdAc::fanspeed_t::kAuto; + } +} + +/// Set the Vertical Swing toggle setting +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note This is a button press, and not a state +/// after sending it once you should turn it off +void IRCoronaAc::setSwingVToggle(const bool on) { + setBit(&remote_state[kCoronaAcSectionData0Pos], + kCoronaAcSwingVToggleOffset, on); +} + +/// Get the Vertical Swing toggle setting +/// @return true, the setting is on. false, the setting is off. +bool IRCoronaAc::getSwingVToggle(void) { + return GETBIT64(remote_state[kCoronaAcSectionData0Pos], + kCoronaAcSwingVToggleOffset); +} + +/// Set the Timer time +/// @param[in] section index of section, used for offset. +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (non in range value is disable). +/// Valid is from 1 minute to 12 hours +void IRCoronaAc::_setTimer(const uint8_t section, const uint16_t nr_of_mins) { + // default to off + uint16_t hsecs = kCoronaAcTimerOff; + if (1 <= nr_of_mins && nr_of_mins <= kCoronaAcTimerMax) + hsecs = nr_of_mins * kCoronaAcTimerUnitsPerMin; + + uint8_t pos = section * kCoronaAcSectionBytes; + // convert 16 bit value to separate 8 bit parts + remote_state[pos + kCoronaAcSectionData1Pos] = hsecs >> 8; + remote_state[pos + kCoronaAcSectionData0Pos] = hsecs; + + // if any timer is enabled, then (remote) ac must be on (Standby) + if (hsecs != kCoronaAcTimerOff) { + _setPower(true); + setPowerButton(false); + } +} + +/// Get the current Timer time +/// @return The number of minutes it is set for. 0 means it's off. +/// @note The A/C protocol supports 2 second increments +uint16_t IRCoronaAc::_getTimer(const uint8_t section) { + uint8_t pos = section * kCoronaAcSectionBytes; + // combine separate 8 bit parts to 16 bit value + uint16_t hsecs = remote_state[pos + kCoronaAcSectionData1Pos] << 8 | + remote_state[pos + kCoronaAcSectionData0Pos]; + + if (hsecs == kCoronaAcTimerOff) + return 0; + + return hsecs / kCoronaAcTimerUnitsPerMin; +} + +/// Get the current On Timer time +/// @return The number of minutes it is set for. 0 means it's off. +uint16_t IRCoronaAc::getOnTimer(void) { + return _getTimer(kCoronaAcOnTimerSection); +} + +/// Set the On Timer time +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (0 or kCoronaAcTimerOff is disable). +void IRCoronaAc::setOnTimer(const uint16_t nr_of_mins) { + _setTimer(kCoronaAcOnTimerSection, nr_of_mins); + // if we set a timer value, clear the other timer + if (getOnTimer()) + setOffTimer(kCoronaAcTimerOff); +} + +/// Get the current Off Timer time +/// @return The number of minutes it is set for. 0 means it's off. +uint16_t IRCoronaAc::getOffTimer(void) { + return _getTimer(kCoronaAcOffTimerSection); +} + +/// Set the Off Timer time +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (0 or kCoronaAcTimerOff is disable). +void IRCoronaAc::setOffTimer(const uint16_t nr_of_mins) { + _setTimer(kCoronaAcOffTimerSection, nr_of_mins); + // if we set a timer value, clear the other timer + if (getOffTimer()) + setOnTimer(kCoronaAcTimerOff); +} + +/// Convert the internal state into a human readable string. +/// @return The current internal state expressed as a human readable String. +String IRCoronaAc::toString(void) { + String result = ""; + result.reserve(140); // Reserve some heap for the string to reduce fragging. + result += addBoolToString(getPower(), kPowerStr, false); + result += addBoolToString(getPowerButton(), kPowerButtonStr); + result += addModeToString(getMode(), 0xFF, kCoronaAcModeCool, + kCoronaAcModeHeat, kCoronaAcModeDry, + kCoronaAcModeFan); + result += addTempToString(getTemp()); + result += addFanToString(getFan(), kCoronaAcFanHigh, kCoronaAcFanLow, + kCoronaAcFanAuto, kCoronaAcFanAuto, + kCoronaAcFanMedium); + result += addBoolToString(getSwingVToggle(), kSwingVToggleStr); + result += addBoolToString(getEcono(), kEconoStr); + result += addLabeledString(getOnTimer() + ? minsToString(getOnTimer()) : kOffStr, + kOnTimerStr); + result += addLabeledString(getOffTimer() + ? minsToString(getOffTimer()) : kOffStr, + kOffTimerStr); + return result; +} + +/// Convert the A/C state to it's common stdAc::state_t equivalent. +/// @return A stdAc::state_t state. +stdAc::state_t IRCoronaAc::toCommon() { + stdAc::state_t result; + result.protocol = decode_type_t::CORONA_AC; + result.model = -1; // No models used. + result.power = getPower(); + result.mode = toCommonMode(getMode()); + result.celsius = true; + result.degrees = getTemp(); + result.fanspeed = toCommonFanSpeed(getFan()); + result.swingv = getSwingVToggle() ? + stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff; + result.econo = getEcono(); + // Not supported. + result.sleep = -1; + result.swingh = stdAc::swingh_t::kOff; + result.turbo = false; + result.quiet = false; + result.clean = false; + result.filter = false; + result.beep = false; + result.light = false; + result.clock = -1; + return result; +} diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Corona.h b/lib/IRremoteESP8266-2.7.8/src/ir_Corona.h new file mode 100644 index 000000000..871fc4c87 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Corona.h @@ -0,0 +1,155 @@ +// Corona A/C +// +// Copyright 2020 Christian Nilsson + +// Supports: +// Brand: Corona, Model: CSH-N2211 A/C +// Brand: Corona, Model: CSH-N2511 A/C +// Brand: Corona, Model: CSH-N2811 A/C +// Brand: Corona, Model: CSH-N4011 A/C +// Brand: Corona, Model: AR-01 remote +// +// Ref: https://docs.google.com/spreadsheets/d/1zzDEUQ52y7MZ7_xCU3pdjdqbRXOwZLsbTGvKWcicqCI/ +// Ref: https://www.corona.co.jp/box/download.php?id=145060636229 + +#ifndef IR_CORONA_H_ +#define IR_CORONA_H_ + +#define __STDC_LIMIT_MACROS +#include +#ifndef UNIT_TEST +#include +#endif +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif + +// Constants + +// CORONA_AC +const uint8_t kCoronaAcSectionBytes = 7; // kCoronaAcStateLengthShort +const uint8_t kCoronaAcSections = 3; +const uint8_t kCoronaAcSectionHeader0Pos = 0; +const uint8_t kCoronaAcSectionHeader0 = 0x28; +const uint8_t kCoronaAcSectionHeader1Pos = 1; +const uint8_t kCoronaAcSectionHeader1 = 0x61; +const uint8_t kCoronaAcSectionLabelPos = 2; +const uint8_t kCoronaAcSectionLabelBase = 0x0D; // 0b1101 +const uint8_t kCoronaAcSectionData0Pos = 3; +const uint8_t kCoronaAcSectionData0InvPos = 4; +const uint8_t kCoronaAcSectionData1Pos = 5; +const uint8_t kCoronaAcSectionData1InvPos = 6; +const uint8_t kCoronaAcSectionData0Base = 0x10; // D0 Pos 4 always on + +const uint8_t kCoronaAcSettingsSection = 0; +// D0 +const uint8_t kCoronaAcFanOffset = 0; // D0 LSB Pos 0-1 +const uint8_t kCoronaAcFanSize = 2; +const uint8_t kCoronaAcFanAuto = 0b00; // 0 +const uint8_t kCoronaAcFanLow = 0b01; // 1 +const uint8_t kCoronaAcFanMedium = 0b10; // 2 +const uint8_t kCoronaAcFanHigh = 0b11; // 3 + +// One bit unknown // D0 Pos 2 +const uint8_t kCoronaAcPowerSaveOffset = 3; // D0 Pos 3 +// One bit unknown always on // D0 Pos 4 +// One bit unknown // D0 Pos 5 +const uint8_t kCoronaAcSwingVToggleOffset = 6; // D0 Pos 6 +// One bit unknown // D0 MSB Pos 7 + +// D1 +/* full auto mode not supported by this code yet +const uint8_t kCoronaAcAutoD0 = 0b00010100; // only combined with power save +const uint8_t kCoronaAcAutoD1 = 0b10000011; // only combined with power +*/ +const uint8_t kCoronaAcTempOffset = 0; // D1 LSB Pos 0 +const uint8_t kCoronaAcTempSize = 4; +const uint8_t kCoronaAcMinTemp = 17; // Celsius = 0b0001 +const uint8_t kCoronaAcMaxTemp = 30; // Celsius = 0b1110 +const uint8_t kCoronaAcPowerOffset = + kCoronaAcTempOffset + kCoronaAcTempSize; // D1 Pos 4 +const uint8_t kCoronaAcPowerButtonOffset = + kCoronaAcPowerOffset + 1; // D1 Pos 5 +const uint8_t kCoronaAcModeOffset = + kCoronaAcPowerButtonOffset + 1; // D1 MSB Pos 6-7 +const uint8_t kCoronaAcModeSize = 2; +const uint8_t kCoronaAcModeHeat = 0b00; // 0 +const uint8_t kCoronaAcModeDry = 0b01; // 1 +const uint8_t kCoronaAcModeCool = 0b10; // 2 +const uint8_t kCoronaAcModeFan = 0b11; // 3 + +const uint8_t kCoronaAcOnTimerSection = 1; +const uint8_t kCoronaAcOffTimerSection = 2; +const uint16_t kCoronaAcTimerMax = 12 * 60; // 12H in Minutes +// Min value on remote is 1 hour, actual sent value can be 2 secs +const uint16_t kCoronaAcTimerOff = 0xffff; +const uint16_t kCoronaAcTimerUnitsPerMin = 30; // 30 units = 1 minute + +// Classes + +/// Class for handling detailed Corona A/C messages. +class IRCoronaAc { + public: + explicit IRCoronaAc(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + + void stateReset(); +#if SEND_CORONA_AC + void send(const uint16_t repeat = kNoRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. + int8_t calibrate(void) { return _irsend.calibrate(); } +#endif // SEND_CORONA_AC + void begin(); + static bool validSection(const uint8_t state[], const uint16_t pos, + const uint8_t section); + void setPower(const bool on); + bool getPower(); + bool getPowerButton(); + void on(); + void off(); + void setTemp(const uint8_t temp); + uint8_t getTemp(); + void setSwingVToggle(const bool on); + bool getSwingVToggle(void); + void setFan(const uint8_t speed); + uint8_t getFan(); + void setMode(const uint8_t mode); + uint8_t getMode(); + void setEcono(const bool on); + bool getEcono(void); + void setOnTimer(const uint16_t nr_of_mins); + uint16_t getOnTimer(void); + void setOffTimer(const uint16_t nr_of_mins); + uint16_t getOffTimer(void); + uint8_t* getRaw(); + void setRaw(const uint8_t new_code[], + const uint16_t length = kCoronaAcStateLength); + uint8_t convertMode(const stdAc::opmode_t mode); + uint8_t convertFan(const stdAc::fanspeed_t speed); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + stdAc::state_t toCommon(); + String toString(); +#ifndef UNIT_TEST + + private: + IRsend _irsend; ///< Instance of the IR send class +#else + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif + uint8_t remote_state[kCoronaAcStateLength]; ///< The state of the IR remote. + static uint8_t getSectionByte(const uint8_t section); + static void checksum(uint8_t* data); + void setPowerButton(const bool on); + void _setPower(const bool on); + void _setTimer(const uint8_t section, const uint16_t nr_of_mins); + uint16_t _getTimer(const uint8_t section); +}; +#endif // IR_CORONA_H_ diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Daikin.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.7/src/ir_Daikin.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Daikin.cpp index 2bc0518ec..8aa6a73a2 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Daikin.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.cpp @@ -1,13 +1,25 @@ -/* -An Arduino sketch to emulate IR Daikin ARC433** & ARC477A1 remote control unit -Read more at: -http://harizanov.com/2012/02/control-daikin-air-conditioner-over-the-internet/ +// Copyright 2016 sillyfrog +// Copyright 2017 sillyfrog, crankyoldgit +// Copyright 2018-2020 crankyoldgit +// Copyright 2019 pasna (IRDaikin160 class / Daikin176 class) -Copyright 2016 sillyfrog -Copyright 2017 sillyfrog, crankyoldgit -Copyright 2018-2019 crankyoldgit -Copyright 2019 pasna (IRDaikin160 class / Daikin176 class) -*/ +/// @file +/// @brief Support for Daikin A/C protocols. +/// @see Daikin http://harizanov.com/2012/02/control-daikin-air-conditioner-over-the-internet/ +/// @see Daikin https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// @see Daikin http://rdlab.cdmt.vn/project-2013/daikin-ir-protocol +/// @see Daikin https://github.com/blafois/Daikin-IR-Reverse +/// @see Daikin128 https://github.com/crankyoldgit/IRremoteESP8266/issues/827 +/// @see Daikin152 https://github.com/crankyoldgit/IRremoteESP8266/issues/873 +/// @see Daikin152 https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.cpp +/// @see Daikin152 https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.h +/// @see Daikin160 https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// @see Daikin2 https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit#gid=236366525&range=B25:D32 +/// @see Daikin2 https://github.com/crankyoldgit/IRremoteESP8266/issues/582 +/// @see Daikin2 https://www.daikin.co.nz/sites/default/files/daikin-split-system-US7-FTXZ25-50NV1B.pdf +/// @see Daikin216 https://github.com/crankyoldgit/IRremoteESP8266/issues/689 +/// @see Daikin216 https://github.com/danny-source/Arduino_DY_IRDaikin +/// @see Daikin64 https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 #include "ir_Daikin.h" #include @@ -24,12 +36,6 @@ Copyright 2019 pasna (IRDaikin160 class / Daikin176 class) #include "IRtext.h" #include "IRutils.h" -// Constants -// Ref: -// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote -// http://rdlab.cdmt.vn/project-2013/daikin-ir-protocol -// https://github.com/crankyoldgit/IRremoteESP8266/issues/582 - using irutils::addBoolToString; using irutils::addDayToString; using irutils::addIntToString; @@ -44,19 +50,14 @@ using irutils::setBits; using irutils::sumNibbles; using irutils::uint8ToBcd; - #if SEND_DAIKIN -// Send a Daikin A/C message. -// -// Args: -// data: An array of kDaikinStateLength bytes containing the IR command. -// -// Status: STABLE -// -// Ref: -// IRDaikinESP.cpp -// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote -// https://github.com/blafois/Daikin-IR-Reverse +/// Send a Daikin 280-bit A/C formatted message. +/// Status: STABLE +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// @see https://github.com/blafois/Daikin-IR-Reverse void IRsend::sendDaikin(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikinStateLengthShort) @@ -98,24 +99,29 @@ void IRsend::sendDaikin(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN +/// Class constructor. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRDaikinESP::IRDaikinESP(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikinESP::begin(void) { _irsend.begin(); } #if SEND_DAIKIN +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikinESP::send(const uint16_t repeat) { _irsend.sendDaikin(getRaw(), kDaikinStateLength, repeat); } #endif // SEND_DAIKIN -// Verify the checksums are valid for a given state. -// Args: -// state: The array to verify the checksums of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikinESP::validChecksum(uint8_t state[], const uint16_t length) { // Data #1 if (length < kDaikinSection1Length || @@ -136,7 +142,7 @@ bool IRDaikinESP::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikinESP::checksum(void) { remote[kDaikinByteChecksum1] = sumBytes(remote, kDaikinSection1Length - 1); remote[kDaikinByteChecksum2] = sumBytes(remote + kDaikinSection1Length, @@ -146,6 +152,7 @@ void IRDaikinESP::checksum(void) { kDaikinSection3Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikinESP::stateReset(void) { for (uint8_t i = 0; i < kDaikinStateLength; i++) remote[i] = 0x0; @@ -173,11 +180,16 @@ void IRDaikinESP::stateReset(void) { this->checksum(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikinESP::getRaw(void) { this->checksum(); // Ensure correct settings before sending. return remote; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length Length of the code in bytes. void IRDaikinESP::setRaw(const uint8_t new_code[], const uint16_t length) { uint8_t offset = 0; if (length == kDaikinStateLengthShort) { // Handle the "short" length case. @@ -188,28 +200,39 @@ void IRDaikinESP::setRaw(const uint8_t new_code[], const uint16_t length) { remote[i + offset] = new_code[i]; } +/// Change the power setting to On. void IRDaikinESP::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikinESP::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setPower(const bool on) { setBit(&remote[kDaikinBytePower], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getPower(void) { return GETBIT8(remote[kDaikinBytePower], kDaikinBitPowerOffset); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikinESP::setTemp(const uint8_t temp) { uint8_t degrees = std::max(temp, kDaikinMinTemp); degrees = std::min(degrees, kDaikinMaxTemp); remote[kDaikinByteTemp] = degrees << 1; } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikinESP::getTemp(void) { return remote[kDaikinByteTemp] >> 1; } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikinESP::setFan(const uint8_t fan) { // Set the fan speed bits, leave low 4 bits alone uint8_t fanset; @@ -222,6 +245,8 @@ void IRDaikinESP::setFan(const uint8_t fan) { setBits(&remote[kDaikinByteFan], kDaikinFanOffset, kDaikinFanSize, fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikinESP::getFan(void) { uint8_t fan = GETBITS8(remote[kDaikinByteFan], kDaikinFanOffset, kDaikinFanSize); @@ -229,10 +254,14 @@ uint8_t IRDaikinESP::getFan(void) { return fan; } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikinESP::getMode(void) { return GETBITS8(remote[kDaikinBytePower], kDaikinModeOffset, kDaikinModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikinESP::setMode(const uint8_t mode) { switch (mode) { case kDaikinAuto: @@ -248,35 +277,49 @@ void IRDaikinESP::setMode(const uint8_t mode) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setSwingVertical(const bool on) { setBits(&remote[kDaikinByteFan], kDaikinSwingOffset, kDaikinSwingSize, on ? kDaikinSwingOn : kDaikinSwingOff); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getSwingVertical(void) { return GETBITS8(remote[kDaikinByteFan], kDaikinSwingOffset, kDaikinSwingSize); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setSwingHorizontal(const bool on) { setBits(&remote[kDaikinByteSwingH], kDaikinSwingOffset, kDaikinSwingSize, on ? kDaikinSwingOn : kDaikinSwingOff); } +/// Get the Horizontal Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getSwingHorizontal(void) { return GETBITS8(remote[kDaikinByteSwingH], kDaikinSwingOffset, kDaikinSwingSize); } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setQuiet(const bool on) { setBit(&remote[kDaikinByteSilent], kDaikinBitSilentOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) this->setPowerful(false); } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getQuiet(void) { return GETBIT8(remote[kDaikinByteSilent], kDaikinBitSilentOffset); } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setPowerful(const bool on) { setBit(&remote[kDaikinBytePowerful], kDaikinBitPowerfulOffset, on); if (on) { @@ -286,45 +329,64 @@ void IRDaikinESP::setPowerful(const bool on) { } } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getPowerful(void) { return GETBIT8(remote[kDaikinBytePowerful], kDaikinBitPowerfulOffset); } +/// Set the Sensor mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setSensor(const bool on) { setBit(&remote[kDaikinByteSensor], kDaikinBitSensorOffset, on); } +/// Get the Sensor mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getSensor(void) { return GETBIT8(remote[kDaikinByteSensor], kDaikinBitSensorOffset); } +/// Set the Economy mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setEcono(const bool on) { setBit(&remote[kDaikinByteEcono], kDaikinBitEconoOffset, on); // Powerful & Econo mode being on are mutually exclusive. if (on) this->setPowerful(false); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getEcono(void) { return GETBIT8(remote[kDaikinByteEcono], kDaikinBitEconoOffset); } +/// Set the Mould mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setMold(const bool on) { setBit(&remote[kDaikinByteMold], kDaikinBitMoldOffset, on); } +/// Get the Mould mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getMold(void) { return GETBIT8(remote[kDaikinByteMold], kDaikinBitMoldOffset); } +/// Set the Comfort mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setComfort(const bool on) { setBit(&remote[kDaikinByteComfort], kDaikinBitComfortOffset, on); } +/// Get the Comfort mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getComfort(void) { return GETBIT8(remote[kDaikinByteComfort], kDaikinBitComfortOffset); } -// starttime: Number of minutes after midnight. +/// Set the enable status & time of the On Timer. +/// @param[in] starttime The number of minutes past midnight. void IRDaikinESP::enableOnTimer(const uint16_t starttime) { setBit(&remote[kDaikinByteOnTimer], kDaikinBitOnTimerOffset); remote[kDaikinByteOnTimerMinsLow] = starttime; @@ -333,11 +395,14 @@ void IRDaikinESP::enableOnTimer(const uint16_t starttime) { kDaikinOnTimerMinsHighSize, starttime >> 8); } +/// Clear and disable the On timer. void IRDaikinESP::disableOnTimer(void) { this->enableOnTimer(kDaikinUnusedTime); setBit(&remote[kDaikinByteOnTimer], kDaikinBitOnTimerOffset, false); } +/// Get the On Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikinESP::getOnTime(void) { return (GETBITS8(remote[kDaikinByteOnTimerMinsHigh], kDaikinOnTimerMinsHighOffset, @@ -345,11 +410,14 @@ uint16_t IRDaikinESP::getOnTime(void) { remote[kDaikinByteOnTimerMinsLow]; } +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getOnTimerEnabled(void) { return GETBIT8(remote[kDaikinByteOnTimer], kDaikinBitOnTimerOffset); } -// endtime: Number of minutes after midnight. +/// Set the enable status & time of the Off Timer. +/// @param[in] endtime The number of minutes past midnight. void IRDaikinESP::enableOffTimer(const uint16_t endtime) { setBit(&remote[kDaikinByteOffTimer], kDaikinBitOffTimerOffset); remote[kDaikinByteOffTimerMinsHigh] = endtime >> kNibbleSize; @@ -357,20 +425,27 @@ void IRDaikinESP::enableOffTimer(const uint16_t endtime) { endtime); } +/// Clear and disable the Off timer. void IRDaikinESP::disableOffTimer(void) { this->enableOffTimer(kDaikinUnusedTime); setBit(&remote[kDaikinByteOffTimer], kDaikinBitOffTimerOffset, false); } +/// Get the Off Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikinESP::getOffTime(void) { return (remote[kDaikinByteOffTimerMinsHigh] << kNibbleSize) + GETBITS8(remote[kDaikinByteOffTimerMinsLow], kHighNibble, kNibbleSize); } +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getOffTimerEnabled(void) { return GETBIT8(remote[kDaikinByteOffTimer], kDaikinBitOffTimerOffset); } +/// Set the clock on the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikinESP::setCurrentTime(const uint16_t mins_since_midnight) { uint16_t mins = mins_since_midnight; if (mins > 24 * 60) mins = 0; // If > 23:59, set to 00:00 @@ -380,33 +455,46 @@ void IRDaikinESP::setCurrentTime(const uint16_t mins_since_midnight) { kDaikinClockMinsHighSize, mins >> 8); } +/// Get the clock time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikinESP::getCurrentTime(void) { return (GETBITS8(remote[kDaikinByteClockMinsHigh], kDaikinClockMinsHighOffset, kDaikinClockMinsHighSize) << 8) + remote[kDaikinByteClockMinsLow]; } +/// Set the current day of the week to be sent to the A/C unit. +/// @param[in] day_of_week The numerical representation of the day of the week. +/// @note 1 is SUN, 2 is MON, ..., 7 is SAT void IRDaikinESP::setCurrentDay(const uint8_t day_of_week) { - // 1 is SUN, 2 is MON, ..., 7 is SAT setBits(&remote[kDaikinByteClockMinsHigh], kDaikinDoWOffset, kDaikinDoWSize, day_of_week); } +/// Get the current day of the week to be sent to the A/C unit. +/// @return The numerical representation of the day of the week. +/// @note 1 is SUN, 2 is MON, ..., 7 is SAT uint8_t IRDaikinESP::getCurrentDay(void) { return GETBITS8(remote[kDaikinByteClockMinsHigh], kDaikinDoWOffset, kDaikinDoWSize); } +/// Set the enable status of the Weekly Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setWeeklyTimerEnable(const bool on) { // Bit is cleared for `on`. setBit(&remote[kDaikinByteWeeklyTimer], kDaikinBitWeeklyTimerOffset, !on); } +/// Get the enable status of the Weekly Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getWeeklyTimerEnable(void) { return !GETBIT8(remote[kDaikinByteWeeklyTimer], kDaikinBitWeeklyTimerOffset); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikinESP::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kDaikinCool; @@ -417,7 +505,9 @@ uint8_t IRDaikinESP::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikinESP::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kDaikinFanQuiet; @@ -429,7 +519,9 @@ uint8_t IRDaikinESP::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDaikinESP::toCommonMode(const uint8_t mode) { switch (mode) { case kDaikinCool: return stdAc::opmode_t::kCool; @@ -440,7 +532,9 @@ stdAc::opmode_t IRDaikinESP::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRDaikinESP::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kDaikinFanMax: return stdAc::fanspeed_t::kMax; @@ -453,7 +547,8 @@ stdAc::fanspeed_t IRDaikinESP::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikinESP::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN; @@ -480,7 +575,8 @@ stdAc::state_t IRDaikinESP::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikinESP::toString(void) { String result = ""; result.reserve(230); // Reserve some heap for the string to reduce fragging. @@ -510,20 +606,16 @@ String IRDaikinESP::toString(void) { } #if DECODE_DAIKIN -// Decode the supplied Daikin A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikinBits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// -// Ref: -// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// Decode the supplied Daikin 280-bit message. (DAIKIN) +/// Status: STABLE / Reported as working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote bool IRrecv::decodeDaikin(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Is there enough data to match successfully? @@ -588,15 +680,12 @@ bool IRrecv::decodeDaikin(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN #if SEND_DAIKIN2 -// Send a Daikin2 A/C message. -// -// Args: -// data: An array of kDaikin2StateLength bytes containing the IR command. -// -// Status: STABLE / Expected to work. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/582 +/// Send a Daikin2 (312-bit) A/C formatted message. +/// Status: STABLE / Expected to work. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/582 void IRsend::sendDaikin2(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin2Section1Length) @@ -622,34 +711,29 @@ void IRsend::sendDaikin2(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN2 -// Class for handling Daikin2 A/C messages. -// -// Code by crankyoldgit, Reverse engineering analysis by sheppy99 -// -// Supported Remotes: Daikin ARC477A1 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/582 -// https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit?usp=sharing -// https://www.daikin.co.nz/sites/default/files/daikin-split-system-US7-FTXZ25-50NV1B.pdf +/// Class constructor. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRDaikin2::IRDaikin2(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin2::begin(void) { _irsend.begin(); } #if SEND_DAIKIN2 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin2::send(const uint16_t repeat) { _irsend.sendDaikin2(getRaw(), kDaikin2StateLength, repeat); } #endif // SEND_DAIKIN2 -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin2::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of section #1. if (length <= kDaikin2Section1Length - 1 || @@ -664,7 +748,7 @@ bool IRDaikin2::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin2::checksum(void) { remote_state[kDaikin2Section1Length - 1] = sumBytes( remote_state, kDaikin2Section1Length - 1); @@ -672,6 +756,7 @@ void IRDaikin2::checksum(void) { remote_state + kDaikin2Section1Length, kDaikin2Section2Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin2::stateReset(void) { for (uint8_t i = 0; i < kDaikin2StateLength; i++) remote_state[i] = 0x0; @@ -706,33 +791,47 @@ void IRDaikin2::stateReset(void) { checksum(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin2::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin2::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin2StateLength); } +/// Change the power setting to On. void IRDaikin2::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikin2::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setPower(const bool on) { setBit(&remote_state[25], kDaikinBitPowerOffset, on); setBit(&remote_state[6], kDaikin2BitPowerOffset, !on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getPower(void) { return GETBIT8(remote_state[25], kDaikinBitPowerOffset) && !GETBIT8(remote_state[6], kDaikin2BitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin2::getMode(void) { return GETBITS8(remote_state[25], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] desired_mode The desired operating mode. void IRDaikin2::setMode(const uint8_t desired_mode) { uint8_t mode = desired_mode; switch (mode) { @@ -747,7 +846,8 @@ void IRDaikin2::setMode(const uint8_t desired_mode) { if (mode == kDaikinCool) this->setTemp(this->getTemp()); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] desired The temperature in degrees celsius. void IRDaikin2::setTemp(const uint8_t desired) { // The A/C has a different min temp if in cool mode. uint8_t temp = std::max( @@ -756,7 +856,9 @@ void IRDaikin2::setTemp(const uint8_t desired) { remote_state[26] = std::min(kDaikinMaxTemp, temp) << 1; } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikin2::setFan(const uint8_t fan) { // Set the fan speed bits, leave low 4 bits alone uint8_t fanset; @@ -769,6 +871,8 @@ void IRDaikin2::setFan(const uint8_t fan) { setBits(&remote_state[kDaikin2FanByte], kHighNibble, kNibbleSize, fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin2::getFan(void) { const uint8_t fan = GETBITS8(remote_state[kDaikin2FanByte], kHighNibble, kNibbleSize); @@ -779,8 +883,12 @@ uint8_t IRDaikin2::getFan(void) { } } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin2::getTemp(void) { return remote_state[26] >> 1; } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRDaikin2::setSwingVertical(const uint8_t position) { switch (position) { case kDaikin2SwingVHigh: @@ -797,11 +905,15 @@ void IRDaikin2::setSwingVertical(const uint8_t position) { } } +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRDaikin2::getSwingVertical(void) { return GETBITS8(remote_state[18], kLowNibble, kNibbleSize); } -// Convert a standard A/C vertical swing into its native version. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin2::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -815,7 +927,9 @@ uint8_t IRDaikin2::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] setting A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRDaikin2::toCommonSwingV(const uint8_t setting) { switch (setting) { case kDaikin2SwingVHigh: return stdAc::swingv_t::kHighest; @@ -829,12 +943,18 @@ stdAc::swingv_t IRDaikin2::toCommonSwingV(const uint8_t setting) { } } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRDaikin2::setSwingHorizontal(const uint8_t position) { remote_state[17] = position; } +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRDaikin2::getSwingHorizontal(void) { return remote_state[17]; } +/// Set the clock on the A/C unit. +/// @param[in] numMins Nr. of minutes past midnight. void IRDaikin2::setCurrentTime(const uint16_t numMins) { uint16_t mins = numMins; if (numMins > 24 * 60) mins = 0; // If > 23:59, set to 00:00 @@ -842,13 +962,16 @@ void IRDaikin2::setCurrentTime(const uint16_t numMins) { setBits(&remote_state[6], kLowNibble, kNibbleSize, mins >> 8); } +/// Get the clock time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin2::getCurrentTime(void) { return (GETBITS8(remote_state[6], kLowNibble, kNibbleSize) << 8) | remote_state[5]; } -// starttime: Number of minutes after midnight. -// Note: Timer location is shared with sleep timer. +/// Set the enable status & time of the On Timer. +/// @param[in] starttime The number of minutes past midnight. +/// @note Timer location is shared with sleep timer. void IRDaikin2::enableOnTimer(const uint16_t starttime) { clearSleepTimerFlag(); setBit(&remote_state[25], kDaikinBitOnTimerOffset); // Set the On Timer flag. @@ -856,26 +979,33 @@ void IRDaikin2::enableOnTimer(const uint16_t starttime) { setBits(&remote_state[31], kLowNibble, kNibbleSize, starttime >> 8); } +/// Clear the On Timer flag. void IRDaikin2::clearOnTimerFlag(void) { setBit(&remote_state[25], kDaikinBitOnTimerOffset, false); } +/// Disable the On timer. void IRDaikin2::disableOnTimer(void) { enableOnTimer(kDaikinUnusedTime); clearOnTimerFlag(); clearSleepTimerFlag(); } +/// Get the On Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin2::getOnTime(void) { return (GETBITS8(remote_state[31], kLowNibble, kNibbleSize) << 8) + remote_state[30]; } +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getOnTimerEnabled(void) { return GETBIT8(remote_state[25], kDaikinBitOnTimerOffset); } -// endtime: Number of minutes after midnight. +/// Set the enable status & time of the Off Timer. +/// @param[in] endtime The number of minutes past midnight. void IRDaikin2::enableOffTimer(const uint16_t endtime) { // Set the Off Timer flag. setBit(&remote_state[25], kDaikinBitOffTimerOffset); @@ -883,97 +1013,137 @@ void IRDaikin2::enableOffTimer(const uint16_t endtime) { setBits(&remote_state[31], kHighNibble, kNibbleSize, endtime); } +/// Disable the Off timer. void IRDaikin2::disableOffTimer(void) { enableOffTimer(kDaikinUnusedTime); // Clear the Off Timer flag. setBit(&remote_state[25], kDaikinBitOffTimerOffset, false); } +/// Get the Off Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin2::getOffTime(void) { return (remote_state[32] << 4) + GETBITS8(remote_state[31], kHighNibble, kNibbleSize); } +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getOffTimerEnabled(void) { return GETBIT8(remote_state[25], kDaikinBitOffTimerOffset); } +/// Get the Beep status of the A/C. +/// @return true, the setting is on. false, the setting is off. uint8_t IRDaikin2::getBeep(void) { return GETBITS8(remote_state[7], kDaikin2BeepOffset, kDaikin2BeepSize); } +/// Set the Beep mode of the A/C. +/// @param[in] beep true, the setting is on. false, the setting is off. void IRDaikin2::setBeep(const uint8_t beep) { setBits(&remote_state[7], kDaikin2BeepOffset, kDaikin2BeepSize, beep); } +/// Get the Light status of the A/C. +/// @return true, the setting is on. false, the setting is off. uint8_t IRDaikin2::getLight(void) { return GETBITS8(remote_state[7], kDaikin2LightOffset, kDaikin2LightSize); } +/// Set the Light (LED) mode of the A/C. +/// @param[in] light true, the setting is on. false, the setting is off. void IRDaikin2::setLight(const uint8_t light) { setBits(&remote_state[7], kDaikin2LightOffset, kDaikin2LightSize, light); } +/// Set the Mould (filter) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setMold(const bool on) { setBit(&remote_state[8], kDaikin2BitMoldOffset, on); } +/// Get the Mould (filter) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getMold(void) { return GETBIT8(remote_state[8], kDaikin2BitMoldOffset); } -// Auto clean setting. +/// Set the Auto clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setClean(const bool on) { setBit(&remote_state[8], kDaikin2BitCleanOffset, on); } +/// Get the Auto Clean mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getClean(void) { return GETBIT8(remote_state[8], kDaikin2BitCleanOffset); } -// Fresh Air settings. +/// Set the Fresh Air mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setFreshAir(const bool on) { setBit(&remote_state[8], kDaikin2BitFreshAirOffset, on); } +/// Get the Fresh Air mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getFreshAir(void) { return GETBIT8(remote_state[8], kDaikin2BitFreshAirOffset); } +/// Set the (High) Fresh Air mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setFreshAirHigh(const bool on) { setBit(&remote_state[8], kDaikin2BitFreshAirHighOffset, on); } +/// Get the (High) Fresh Air mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getFreshAirHigh(void) { return GETBIT8(remote_state[8], kDaikin2BitFreshAirHighOffset); } +/// Set the Automatic Eye (Sensor) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setEyeAuto(bool on) { setBit(&remote_state[13], kDaikin2BitEyeAutoOffset, on); } +/// Get the Automaitc Eye (Sensor) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getEyeAuto(void) { return GETBIT8(remote_state[13], kDaikin2BitEyeAutoOffset); } +/// Set the Eye (Sensor) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setEye(bool on) { setBit(&remote_state[36], kDaikin2BitEyeOffset, on); } +/// Get the Eye (Sensor) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getEye(void) { return GETBIT8(remote_state[36], kDaikin2BitEyeOffset); } +/// Set the Economy mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setEcono(bool on) { setBit(&remote_state[36], kDaikinBitEconoOffset, on); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getEcono(void) { return GETBIT8(remote_state[36], kDaikinBitEconoOffset); } -// sleeptime: Number of minutes. -// Note: Timer location is shared with On Timer. +/// Set the enable status & time of the Sleep Timer. +/// @param[in] sleeptime The number of minutes past midnight. +/// @note The Timer location is shared with On Timer. void IRDaikin2::enableSleepTimer(const uint16_t sleeptime) { enableOnTimer(sleeptime); clearOnTimerFlag(); @@ -981,61 +1151,85 @@ void IRDaikin2::enableSleepTimer(const uint16_t sleeptime) { setBit(&remote_state[36], kDaikin2BitSleepTimerOffset); } +/// Clear the sleep timer flag. void IRDaikin2::clearSleepTimerFlag(void) { setBit(&remote_state[36], kDaikin2BitSleepTimerOffset, false); } +/// Disable the sleep timer. void IRDaikin2::disableSleepTimer(void) { disableOnTimer(); } +/// Get the Sleep Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin2::getSleepTime(void) { return getOnTime(); } +/// Get the Sleep timer enabled status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getSleepTimerEnabled(void) { return GETBIT8(remote_state[36], kDaikin2BitSleepTimerOffset); } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setQuiet(const bool on) { setBit(&remote_state[33], kDaikinBitSilentOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) setPowerful(false); } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getQuiet(void) { return GETBIT8(remote_state[33], kDaikinBitSilentOffset); } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setPowerful(const bool on) { setBit(&remote_state[33], kDaikinBitPowerfulOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) setQuiet(false); } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getPowerful(void) { return GETBIT8(remote_state[33], kDaikinBitPowerfulOffset); } +/// Set the Purify (Filter) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setPurify(const bool on) { setBit(&remote_state[36], kDaikin2BitPurifyOffset, on); } +/// Get the Purify (Filter) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getPurify(void) { return GETBIT8(remote_state[36], kDaikin2BitPurifyOffset); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin2::convertMode(const stdAc::opmode_t mode) { return IRDaikinESP::convertMode(mode); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin2::convertFan(const stdAc::fanspeed_t speed) { return IRDaikinESP::convertFan(speed); } -// Convert a standard A/C horizontal swing into its native version. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin2::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kAuto: return kDaikin2SwingHSwing; @@ -1049,7 +1243,9 @@ uint8_t IRDaikin2::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native horizontal swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] setting A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRDaikin2::toCommonSwingH(const uint8_t setting) { switch (setting) { case kDaikin2SwingHSwing: return stdAc::swingh_t::kAuto; @@ -1063,7 +1259,8 @@ stdAc::swingh_t IRDaikin2::toCommonSwingH(const uint8_t setting) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin2::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN2; @@ -1088,7 +1285,8 @@ stdAc::state_t IRDaikin2::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin2::toString(void) { String result = ""; result.reserve(310); // Reserve some heap for the string to reduce fragging. @@ -1205,24 +1403,15 @@ String IRDaikin2::toString(void) { } #if DECODE_DAIKIN2 -// Decode the supplied Daikin2 A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin2Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin FTXZ25NV1B, FTXZ35NV1B, FTXZ50NV1B Aircon -// - Daikin ARC477A1 remote -// -// Status: STABLE / Works as expected. -// -// Ref: -// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// Decode the supplied Daikin 312-bit message. (DAIKIN2) +/// Status: STABLE / Works as expected. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeDaikin2(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader + kFooter) + kHeader - 1 + offset) @@ -1277,19 +1466,13 @@ bool IRrecv::decodeDaikin2(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN2 #if SEND_DAIKIN216 -// Send a Daikin 216 bit A/C message. -// -// Args: -// data: An array of kDaikin216StateLength bytes containing the IR command. -// -// Status: Alpha/Untested on a real device. -// -// Supported devices: -// - Daikin ARC433B69 remote. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/689 -// https://github.com/danny-source/Arduino_DY_IRDaikin +/// Send a Daikin216 (216-bit) A/C formatted message. +/// Status: Alpha / Untested on a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/689 +/// @see https://github.com/danny-source/Arduino_DY_IRDaikin void IRsend::sendDaikin216(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin216Section1Length) @@ -1313,33 +1496,29 @@ void IRsend::sendDaikin216(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN216 -// Class for handling Daikin 216 bit / 27 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin ARC433B69 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/689 -// https://github.com/danny-source/Arduino_DY_IRDaikin +/// Class Constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRDaikin216::IRDaikin216(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin216::begin(void) { _irsend.begin(); } #if SEND_DAIKIN216 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin216::send(const uint16_t repeat) { _irsend.sendDaikin216(getRaw(), kDaikin216StateLength, repeat); } #endif // SEND_DAIKIN216 -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin216::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of section #1. if (length <= kDaikin216Section1Length - 1 || @@ -1354,7 +1533,7 @@ bool IRDaikin216::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin216::checksum(void) { remote_state[kDaikin216Section1Length - 1] = sumBytes( remote_state, kDaikin216Section1Length - 1); @@ -1362,6 +1541,7 @@ void IRDaikin216::checksum(void) { remote_state + kDaikin216Section1Length, kDaikin216Section2Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin216::stateReset(void) { for (uint8_t i = 0; i < kDaikin216StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x11; @@ -1376,31 +1556,45 @@ void IRDaikin216::stateReset(void) { // remote_state[26] is a checksum byte, it will be set by checksum(). } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin216::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin216::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin216StateLength); } +/// Change the power setting to On. void IRDaikin216::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikin216::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin216::setPower(const bool on) { setBit(&remote_state[kDaikin216BytePower], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin216::getPower(void) { return GETBIT8(remote_state[kDaikin216BytePower], kDaikinBitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin216::getMode(void) { return GETBITS8(remote_state[kDaikin216ByteMode], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin216::setMode(const uint8_t mode) { switch (mode) { case kDaikinAuto: @@ -1416,12 +1610,15 @@ void IRDaikin216::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin216::convertMode(const stdAc::opmode_t mode) { return IRDaikinESP::convertMode(mode); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin216::setTemp(const uint8_t temp) { uint8_t degrees = std::max(temp, kDaikinMinTemp); degrees = std::min(degrees, kDaikinMaxTemp); @@ -1429,12 +1626,16 @@ void IRDaikin216::setTemp(const uint8_t temp) { kDaikin216TempSize, degrees); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin216::getTemp(void) { return GETBITS8(remote_state[kDaikin216ByteTemp], kDaikin216TempOffset, kDaikin216TempSize); } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikin216::setFan(const uint8_t fan) { // Set the fan speed bits, leave low 4 bits alone uint8_t fanset; @@ -1448,6 +1649,8 @@ void IRDaikin216::setFan(const uint8_t fan) { fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin216::getFan(void) { uint8_t fan = GETBITS8(remote_state[kDaikin216ByteFan], kHighNibble, kDaikinFanSize); @@ -1455,32 +1658,44 @@ uint8_t IRDaikin216::getFan(void) { return fan; } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin216::convertFan(const stdAc::fanspeed_t speed) { return IRDaikinESP::convertFan(speed); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin216::setSwingVertical(const bool on) { setBits(&remote_state[kDaikin216ByteSwingV], kLowNibble, kDaikin216SwingSize, on ? kDaikin216SwingOn : kDaikin216SwingOff); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin216::getSwingVertical(void) { return GETBITS8(remote_state[kDaikin216ByteSwingV], kLowNibble, kDaikin216SwingSize); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin216::setSwingHorizontal(const bool on) { setBits(&remote_state[kDaikin216ByteSwingH], kLowNibble, kDaikin216SwingSize, on ? kDaikin216SwingOn : kDaikin216SwingOff); } +/// Get the Horizontal Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin216::getSwingHorizontal(void) { return GETBITS8(remote_state[kDaikin216ByteSwingH], kLowNibble, kDaikin216SwingSize); } -// This is a horrible hack till someone works out the quiet mode bit. +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note This is a horrible hack till someone works out the quiet mode bit. void IRDaikin216::setQuiet(const bool on) { if (on) { this->setFan(kDaikinFanQuiet); @@ -1491,23 +1706,30 @@ void IRDaikin216::setQuiet(const bool on) { } } -// This is a horrible hack till someone works out the quiet mode bit. +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. +/// @note This is a horrible hack till someone works out the quiet mode bit. bool IRDaikin216::getQuiet(void) { return this->getFan() == kDaikinFanQuiet; } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin216::setPowerful(const bool on) { setBit(&remote_state[kDaikin216BytePowerful], kDaikinBitPowerfulOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) this->setQuiet(false); } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin216::getPowerful(void) { return GETBIT8(remote_state[kDaikin216BytePowerful], kDaikinBitPowerfulOffset); } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin216::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN216; @@ -1534,7 +1756,8 @@ stdAc::state_t IRDaikin216::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin216::toString(void) { String result = ""; result.reserve(120); // Reserve some heap for the string to reduce fragging. @@ -1552,24 +1775,17 @@ String IRDaikin216::toString(void) { } #if DECODE_DAIKIN216 -// Decode the supplied Daikin 216 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin216Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin ARC433B69 remote. -// -// Status: STABLE / Should be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/689 -// https://github.com/danny-source/Arduino_DY_IRDaikin +/// Decode the supplied Daikin 216-bit message. (DAIKIN216) +/// Status: STABLE / Should be working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/689 +/// @see https://github.com/danny-source/Arduino_DY_IRDaikin bool IRrecv::decodeDaikin216(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1 + offset) @@ -1615,18 +1831,12 @@ bool IRrecv::decodeDaikin216(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN216 #if SEND_DAIKIN160 -// Send a Daikin 160 bit A/C message. -// -// Args: -// data: An array of kDaikin160StateLength bytes containing the IR command. -// -// Status: STABLE / Confirmed working. -// -// Supported devices: -// - Daikin ARC423A5 remote. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// Send a Daikin160 (160-bit) A/C formatted message. +/// Status: STABLE / Confirmed working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/731 void IRsend::sendDaikin160(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin160Section1Length) @@ -1650,26 +1860,21 @@ void IRsend::sendDaikin160(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN160 -// Class for handling Daikin 160 bit / 20 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin ARC423A5 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRDaikin160::IRDaikin160(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin160::begin(void) { _irsend.begin(); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin160::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of section #1. if (length <= kDaikin160Section1Length - 1 || @@ -1684,7 +1889,7 @@ bool IRDaikin160::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin160::checksum(void) { remote_state[kDaikin160Section1Length - 1] = sumBytes( remote_state, kDaikin160Section1Length - 1); @@ -1692,6 +1897,7 @@ void IRDaikin160::checksum(void) { remote_state + kDaikin160Section1Length, kDaikin160Section2Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin160::stateReset(void) { for (uint8_t i = 0; i < kDaikin160StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x11; @@ -1712,37 +1918,53 @@ void IRDaikin160::stateReset(void) { // remote_state[19] is a checksum byte, it will be set by checksum(). } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin160::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin160::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin160StateLength); } #if SEND_DAIKIN160 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin160::send(const uint16_t repeat) { _irsend.sendDaikin160(getRaw(), kDaikin160StateLength, repeat); } #endif // SEND_DAIKIN160 +/// Change the power setting to On. void IRDaikin160::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikin160::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin160::setPower(const bool on) { setBit(&remote_state[kDaikin160BytePower], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin160::getPower(void) { return GETBIT8(remote_state[kDaikin160BytePower], kDaikinBitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin160::getMode(void) { return GETBITS8(remote_state[kDaikin160ByteMode], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin160::setMode(const uint8_t mode) { switch (mode) { case kDaikinAuto: @@ -1757,12 +1979,15 @@ void IRDaikin160::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin160::convertMode(const stdAc::opmode_t mode) { return IRDaikinESP::convertMode(mode); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin160::setTemp(const uint8_t temp) { uint8_t degrees = std::max(temp, kDaikinMinTemp); degrees = std::min(degrees, kDaikinMaxTemp) - 10; @@ -1770,12 +1995,16 @@ void IRDaikin160::setTemp(const uint8_t temp) { kDaikin160TempSize, degrees); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin160::getTemp(void) { return GETBITS8(remote_state[kDaikin160ByteTemp], kDaikin160TempOffset, kDaikin160TempSize) + 10; } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikin160::setFan(const uint8_t fan) { uint8_t fanset; if (fan == kDaikinFanQuiet || fan == kDaikinFanAuto) @@ -1788,6 +2017,8 @@ void IRDaikin160::setFan(const uint8_t fan) { setBits(&remote_state[kDaikin160ByteFan], kLowNibble, kDaikinFanSize, fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin160::getFan(void) { uint8_t fan = GETBITS8(remote_state[kDaikin160ByteFan], kLowNibble, kDaikinFanSize); @@ -1795,7 +2026,9 @@ uint8_t IRDaikin160::getFan(void) { return fan; } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin160::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kDaikinFanMin; @@ -1808,6 +2041,8 @@ uint8_t IRDaikin160::convertFan(const stdAc::fanspeed_t speed) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRDaikin160::setSwingVertical(const uint8_t position) { switch (position) { case kDaikin160SwingVLowest: @@ -1823,12 +2058,16 @@ void IRDaikin160::setSwingVertical(const uint8_t position) { } } +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRDaikin160::getSwingVertical(void) { return GETBITS8(remote_state[kDaikin160ByteSwingV], kHighNibble, kDaikinSwingSize); } -// Convert a standard A/C vertical swing into its native version. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin160::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -1842,7 +2081,9 @@ uint8_t IRDaikin160::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] setting A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRDaikin160::toCommonSwingV(const uint8_t setting) { switch (setting) { case kDaikin160SwingVHighest: return stdAc::swingv_t::kHighest; @@ -1855,7 +2096,8 @@ stdAc::swingv_t IRDaikin160::toCommonSwingV(const uint8_t setting) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin160::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN160; @@ -1880,7 +2122,8 @@ stdAc::state_t IRDaikin160::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin160::toString(void) { String result = ""; result.reserve(150); // Reserve some heap for the string to reduce fragging. @@ -1906,23 +2149,16 @@ String IRDaikin160::toString(void) { } #if DECODE_DAIKIN160 -// Decode the supplied Daikin 160 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin160Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin ARC423A5 remote. -// -// Status: STABLE / Confirmed working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// Decode the supplied Daikin 160-bit message. (DAIKIN160) +/// Status: STABLE / Confirmed working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/731 bool IRrecv::decodeDaikin160(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1 + offset) @@ -1968,16 +2204,11 @@ bool IRrecv::decodeDaikin160(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN160 #if SEND_DAIKIN176 -// Send a Daikin 176 bit A/C message. -// -// Args: -// data: An array of kDaikin176StateLength bytes containing the IR command. -// -// Status: Alpha/Untested on a real device. -// -// Supported devices: -// - Daikin BRC4C153 remote. -// +/// Send a Daikin176 (176-bit) A/C formatted message. +/// Status: Alpha / Untested on a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendDaikin176(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin176Section1Length) @@ -2001,24 +2232,21 @@ void IRsend::sendDaikin176(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN176 -// Class for handling Daikin 176 bit / 22 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin BRC4C153 remote -// +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRDaikin176::IRDaikin176(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin176::begin(void) { _irsend.begin(); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin176::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of section #1. if (length <= kDaikin176Section1Length - 1 || @@ -2033,7 +2261,7 @@ bool IRDaikin176::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin176::checksum(void) { remote_state[kDaikin176Section1Length - 1] = sumBytes( remote_state, kDaikin176Section1Length - 1); @@ -2041,6 +2269,7 @@ void IRDaikin176::checksum(void) { remote_state + kDaikin176Section1Length, kDaikin176Section2Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin176::stateReset(void) { for (uint8_t i = 0; i < kDaikin176StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x11; @@ -2061,39 +2290,55 @@ void IRDaikin176::stateReset(void) { _saved_temp = getTemp(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin176::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin176::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin176StateLength); _saved_temp = getTemp(); } #if SEND_DAIKIN176 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin176::send(const uint16_t repeat) { _irsend.sendDaikin176(getRaw(), kDaikin176StateLength, repeat); } #endif // SEND_DAIKIN176 +/// Change the power setting to On. void IRDaikin176::on(void) { setPower(true); } +/// Change the power setting to Off.. void IRDaikin176::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin176::setPower(const bool on) { remote_state[kDaikin176ByteModeButton] = 0; setBit(&remote_state[kDaikin176BytePower], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin176::getPower(void) { return GETBIT8(remote_state[kDaikin176BytePower], kDaikinBitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin176::getMode(void) { return GETBITS8(remote_state[kDaikin176ByteMode], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin176::setMode(const uint8_t mode) { uint8_t altmode = 0; switch (mode) { @@ -2111,7 +2356,9 @@ void IRDaikin176::setMode(const uint8_t mode) { remote_state[kDaikin176ByteModeButton] = kDaikin176ModeButton; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin176::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kDry: return kDaikinDry; @@ -2121,7 +2368,9 @@ uint8_t IRDaikin176::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDaikin176::toCommonMode(const uint8_t mode) { switch (mode) { case kDaikinDry: return stdAc::opmode_t::kDry; @@ -2131,7 +2380,8 @@ stdAc::opmode_t IRDaikin176::toCommonMode(const uint8_t mode) { } } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin176::setTemp(const uint8_t temp) { uint8_t degrees = std::min(kDaikinMaxTemp, std::max(temp, kDaikinMinTemp)); _saved_temp = degrees; @@ -2145,12 +2395,16 @@ void IRDaikin176::setTemp(const uint8_t temp) { remote_state[kDaikin176ByteModeButton] = 0; } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin176::getTemp(void) { return GETBITS8(remote_state[kDaikin176ByteTemp], kDaikin176TempOffset, kDaikin176TempSize) + 9; } -// Set the speed of the fan, 1 for Min or 3 for Max +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1 for Min or 3 for Max void IRDaikin176::setFan(const uint8_t fan) { switch (fan) { case kDaikinFanMin: @@ -2164,11 +2418,15 @@ void IRDaikin176::setFan(const uint8_t fan) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin176::getFan(void) { return GETBITS8(remote_state[kDaikin176ByteFan], kHighNibble, kDaikinFanSize); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin176::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -2177,6 +2435,8 @@ uint8_t IRDaikin176::convertFan(const stdAc::fanspeed_t speed) { } } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRDaikin176::setSwingHorizontal(const uint8_t position) { switch (position) { case kDaikin176SwingHOff: @@ -2188,12 +2448,16 @@ void IRDaikin176::setSwingHorizontal(const uint8_t position) { } } +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRDaikin176::getSwingHorizontal(void) { return GETBITS8(remote_state[kDaikin176ByteSwingH], kLowNibble, kDaikinSwingSize); } -// Convert a standard A/C horizontal swing into its native version. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin176::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kOff: return kDaikin176SwingHOff; @@ -2201,7 +2465,10 @@ uint8_t IRDaikin176::convertSwingH(const stdAc::swingh_t position) { default: return kDaikin176SwingHAuto; } } -// Convert a native horizontal swing to it's common equivalent. + +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] setting A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRDaikin176::toCommonSwingH(const uint8_t setting) { switch (setting) { case kDaikin176SwingHOff: return stdAc::swingh_t::kOff; @@ -2211,13 +2478,16 @@ stdAc::swingh_t IRDaikin176::toCommonSwingH(const uint8_t setting) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRDaikin176::toCommonFanSpeed(const uint8_t speed) { return (speed == kDaikinFanMin) ? stdAc::fanspeed_t::kMin : stdAc::fanspeed_t::kMax; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin176::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN176; @@ -2243,7 +2513,8 @@ stdAc::state_t IRDaikin176::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin176::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. @@ -2270,22 +2541,15 @@ String IRDaikin176::toString(void) { } #if DECODE_DAIKIN176 -// Decode the supplied Daikin 176 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin176Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin BRC4C153 remote. -// -// Status: STABLE / Expected to work. -// - +/// Decode the supplied Daikin 176-bit message. (DAIKIN176) +/// Status: STABLE / Expected to work. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeDaikin176(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -2332,17 +2596,12 @@ bool IRrecv::decodeDaikin176(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN176 #if SEND_DAIKIN128 -// Send a Daikin 128 bit A/C message. -// -// Args: -// data: An array of kDaikin128StateLength bytes containing the IR command. -// -// Status: STABLE / Known Working. -// -// Supported devices: -// - Daikin BRC52B63 remote. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827 +/// Send a Daikin128 (128-bit) A/C formatted message. +/// Status: STABLE / Known Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/827 void IRsend::sendDaikin128(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin128SectionLength) @@ -2372,19 +2631,15 @@ void IRsend::sendDaikin128(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN128 -// Class for handling Daikin 128 bit / 16 byte A/C messages. -// -// Code by crankyoldgit. -// Analysis by Daniel Vena -// -// Status: STABLE / Known Working. -// -// Supported Remotes: Daikin BRC52B63 remote -// +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRDaikin128::IRDaikin128(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin128::begin(void) { _irsend.begin(); } uint8_t IRDaikin128::calcFirstChecksum(const uint8_t state[]) { @@ -2397,11 +2652,9 @@ uint8_t IRDaikin128::calcSecondChecksum(const uint8_t state[]) { kDaikin128SectionLength - 1); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin128::validChecksum(uint8_t state[]) { // Validate the checksum of section #1. if (state[kDaikin128SectionLength - 1] >> 4 != calcFirstChecksum(state)) @@ -2412,7 +2665,7 @@ bool IRDaikin128::validChecksum(uint8_t state[]) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin128::checksum(void) { remote_state[kDaikin128SectionLength - 1] &= 0x0F; // Clear upper half. remote_state[kDaikin128SectionLength - 1] |= @@ -2420,6 +2673,7 @@ void IRDaikin128::checksum(void) { remote_state[kDaikin128StateLength - 1] = calcSecondChecksum(remote_state); } +/// Reset the internal state to a fixed known good state. void IRDaikin128::stateReset(void) { for (uint8_t i = 0; i < kDaikin128StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x16; @@ -2428,36 +2682,50 @@ void IRDaikin128::stateReset(void) { // remote_state[15] is a checksum byte, it will be set by checksum(). } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin128::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin128::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin128StateLength); } #if SEND_DAIKIN128 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin128::send(const uint16_t repeat) { _irsend.sendDaikin128(getRaw(), kDaikin128StateLength, repeat); } #endif // SEND_DAIKIN128 +/// Set the Power toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRDaikin128::setPowerToggle(const bool toggle) { setBit(&remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitPowerToggleOffset, toggle); } +/// Get the Power toggle setting of the A/C. +/// @return The current operating mode setting. bool IRDaikin128::getPowerToggle(void) { return GETBIT8(remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitPowerToggleOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin128::getMode(void) { return GETBITS8(remote_state[kDaikin128ByteModeFan], kLowNibble, kDaikin128ModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin128::setMode(const uint8_t mode) { switch (mode) { case kDaikin128Auto: @@ -2477,7 +2745,9 @@ void IRDaikin128::setMode(const uint8_t mode) { setEcono(getEcono()); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin128::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kDaikin128Cool; @@ -2488,7 +2758,9 @@ uint8_t IRDaikin128::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDaikin128::toCommonMode(const uint8_t mode) { switch (mode) { case kDaikin128Cool: return stdAc::opmode_t::kCool; @@ -2499,21 +2771,28 @@ stdAc::opmode_t IRDaikin128::toCommonMode(const uint8_t mode) { } } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin128::setTemp(const uint8_t temp) { remote_state[kDaikin128ByteTemp] = uint8ToBcd( std::min(kDaikin128MaxTemp, std::max(temp, kDaikin128MinTemp))); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin128::getTemp(void) { return bcdToUint8(remote_state[kDaikin128ByteTemp]); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin128::getFan(void) { return GETBITS8(remote_state[kDaikin128ByteModeFan], kHighNibble, kDaikinFanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRDaikin128::setFan(const uint8_t speed) { uint8_t new_speed = speed; uint8_t mode = getMode(); @@ -2534,7 +2813,9 @@ void IRDaikin128::setFan(const uint8_t speed) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin128::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kDaikinFanQuiet; @@ -2546,7 +2827,9 @@ uint8_t IRDaikin128::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRDaikin128::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kDaikin128FanPowerful: return stdAc::fanspeed_t::kMax; @@ -2558,37 +2841,51 @@ stdAc::fanspeed_t IRDaikin128::toCommonFanSpeed(const uint8_t speed) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setSwingVertical(const bool on) { setBit(&remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitSwingOffset, on); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getSwingVertical(void) { return GETBIT8(remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitSwingOffset); } +/// Set the Sleep mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setSleep(const bool on) { setBit(&remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitSleepOffset, on); } +/// Get the Sleep mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getSleep(void) { return GETBIT8(remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitSleepOffset); } +/// Set the Economy mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setEcono(const bool on) { uint8_t mode = getMode(); setBit(&remote_state[kDaikin128ByteEconoLight], kDaikin128BitEconoOffset, on && (mode == kDaikin128Cool || mode == kDaikin128Heat)); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getEcono(void) { return GETBIT8(remote_state[kDaikin128ByteEconoLight], kDaikin128BitEconoOffset); } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setQuiet(const bool on) { uint8_t mode = getMode(); if (on && (mode == kDaikin128Cool || mode == kDaikin128Heat)) @@ -2597,10 +2894,14 @@ void IRDaikin128::setQuiet(const bool on) { setFan(kDaikin128FanAuto); } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getQuiet(void) { return getFan() == kDaikin128FanQuiet; } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setPowerful(const bool on) { uint8_t mode = getMode(); if (on && (mode == kDaikin128Cool || mode == kDaikin128Heat)) @@ -2609,11 +2910,14 @@ void IRDaikin128::setPowerful(const bool on) { setFan(kDaikin128FanAuto); } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getPowerful(void) { return getFan() == kDaikin128FanPowerful; } -// Set the clock in mins since midnight +/// Set the clock on the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin128::setClock(const uint16_t mins_since_midnight) { uint16_t mins = mins_since_midnight; if (mins_since_midnight >= 24 * 60) mins = 0; // Bounds check. @@ -2623,25 +2927,32 @@ void IRDaikin128::setClock(const uint16_t mins_since_midnight) { remote_state[kDaikin128ByteClockMins] = uint8ToBcd(mins % 60); } +/// Get the clock time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin128::getClock(void) { return bcdToUint8(remote_state[kDaikin128ByteClockHours]) * 60 + bcdToUint8(remote_state[kDaikin128ByteClockMins]); } +/// Set the enable status of the On Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setOnTimerEnabled(const bool on) { setBit(&remote_state[kDaikin128ByteOnTimer], kDaikin128BitTimerEnabledOffset, on); } +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getOnTimerEnabled(void) { return GETBIT8(remote_state[kDaikin128ByteOnTimer], kDaikin128BitTimerEnabledOffset); } -// Timer is rounds down to the nearest half hour. -// Args: -// ptr: A PTR to the byte containing the Timer value to be updated. -// mins_since_midnight: The number of minutes the new timer should be set to. +/// Set the time for a timer at the given location. +/// @param[in,out] ptr Ptr to the byte containing the Timer value to be updated. +/// @param[in] mins_since_midnight The number of minutes the new timer should +/// be set to. +/// @note Timer is rounds down to the nearest half hour. void IRDaikin128::setTimer(uint8_t *ptr, const uint16_t mins_since_midnight) { uint16_t mins = mins_since_midnight; if (mins_since_midnight >= 24 * 60) mins = 0; // Bounds check. @@ -2652,43 +2963,57 @@ void IRDaikin128::setTimer(uint8_t *ptr, const uint16_t mins_since_midnight) { uint8ToBcd(mins / 60)); } -// Timer is stored in nr of half hours internally. -// Args: -// ptr: A PTR to the byte containing the Timer value. -// Returns: -// A uint16_t containing the number of minutes since midnight. +/// Get the time for a timer at the given location. +/// @param[in] ptr A Ptr to the byte containing the Timer value. +/// @return The number of minutes since midnight that the timer is set to. +/// @note Timer is stored in nr. of half hours internally. uint16_t IRDaikin128::getTimer(const uint8_t *ptr) { return bcdToUint8(GETBITS8(*ptr, kDaikin128HoursOffset, kDaikin128HoursSize)) * 60 + (GETBIT8(*ptr, kDaikin128HalfHourOffset) ? 30 : 0); } +/// Set the On Timer time for the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin128::setOnTimer(const uint16_t mins_since_midnight) { setTimer(remote_state + kDaikin128ByteOnTimer, mins_since_midnight); } +/// Get the On Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin128::getOnTimer(void) { return getTimer(remote_state + kDaikin128ByteOnTimer); } +/// Set the enable status of the Off Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setOffTimerEnabled(const bool on) { setBit(&remote_state[kDaikin128ByteOffTimer], kDaikin128BitTimerEnabledOffset, on); } +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getOffTimerEnabled(void) { return GETBIT8(remote_state[kDaikin128ByteOffTimer], kDaikin128BitTimerEnabledOffset); } +/// Set the Off Timer time for the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin128::setOffTimer(const uint16_t mins_since_midnight) { setTimer(remote_state + kDaikin128ByteOffTimer, mins_since_midnight); } +/// Get the Off Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin128::getOffTimer(void) { return getTimer(remote_state + kDaikin128ByteOffTimer); } +/// Set the Light toggle setting of the A/C. +/// @param[in] unit Device to show the LED (Light) Display info about. +/// @note 0 is off. void IRDaikin128::setLightToggle(const uint8_t unit) { switch (unit) { case 0: @@ -2701,11 +3026,14 @@ void IRDaikin128::setLightToggle(const uint8_t unit) { } } +/// Get the Light toggle setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin128::getLightToggle(void) { return remote_state[kDaikin128ByteEconoLight] & kDaikin128MaskLight; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin128::toString(void) { String result = ""; result.reserve(240); // Reserve some heap for the string to reduce fragging. @@ -2738,7 +3066,9 @@ String IRDaikin128::toString(void) { return result; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @param[in] prev Ptr to a previous state. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin128::toCommon(const stdAc::state_t *prev) { stdAc::state_t result; if (prev != NULL) result = *prev; @@ -2766,22 +3096,16 @@ stdAc::state_t IRDaikin128::toCommon(const stdAc::state_t *prev) { } #if DECODE_DAIKIN128 -// Decode the supplied Daikin 128 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin128Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin BRC52B63 remote. -// -// Status: STABLE / Known Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827 +/// Decode the supplied Daikin 128-bit message. (DAIKIN128) +/// Status: STABLE / Known Working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/827 bool IRrecv::decodeDaikin128(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader) + kFooter - 1 + offset) @@ -2836,17 +3160,12 @@ bool IRrecv::decodeDaikin128(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN128 #if SEND_DAIKIN152 -// Send a Daikin 152 bit A/C message. -// -// Args: -// data: An array of kDaikin152StateLength bytes containing the IR command. -// -// Supported devices: -// - Daikin ARC480A5 remote. -// -// Status: STABLE / Known working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/873 +/// Send a Daikin152 (152-bit) A/C formatted message. +/// Status: STABLE / Known Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/873 void IRsend::sendDaikin152(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { for (uint16_t r = 0; r <= repeat; r++) { @@ -2866,22 +3185,16 @@ void IRsend::sendDaikin152(const unsigned char data[], const uint16_t nbytes, #endif // SEND_DAIKIN152 #if DECODE_DAIKIN152 -// Decode the supplied Daikin 152 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin152Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin ARC480A5 remote. -// -// Status: STABLE / Known working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/873 +/// Decode the supplied Daikin 152-bit message. (DAIKIN152) +/// Status: STABLE / Known Working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/873 bool IRrecv::decodeDaikin152(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (5 + nbits + kFooter) + kHeader - 1 + offset) @@ -2930,34 +3243,29 @@ bool IRrecv::decodeDaikin152(decode_results *results, uint16_t offset, } #endif // DECODE_DAIKIN152 -// Class for handling Daikin 152 bit / 19 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin ARC480A5 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/873 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.cpp -// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.h +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRDaikin152::IRDaikin152(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin152::begin(void) { _irsend.begin(); } #if SEND_DAIKIN152 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin152::send(const uint16_t repeat) { _irsend.sendDaikin152(getRaw(), kDaikin152StateLength, repeat); } #endif // SEND_DAIKIN152 -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin152::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of the given state. if (length <= 1 || state[length - 1] != sumBytes(state, length - 1)) @@ -2966,12 +3274,13 @@ bool IRDaikin152::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin152::checksum(void) { remote_state[kDaikin152StateLength - 1] = sumBytes( remote_state, kDaikin152StateLength - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin152::stateReset(void) { for (uint8_t i = 3; i < kDaikin152StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x11; @@ -2981,32 +3290,46 @@ void IRDaikin152::stateReset(void) { // remote_state[19] is a checksum byte, it will be set by checksum(). } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin152::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin152::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin152StateLength); } +/// Change the power setting to On. void IRDaikin152::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikin152::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setPower(const bool on) { setBit(&remote_state[kDaikin152PowerByte], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getPower(void) { return GETBIT8(remote_state[kDaikin152PowerByte], kDaikinBitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin152::getMode(void) { return GETBITS8(remote_state[kDaikin152ModeByte], kDaikinModeOffset, kDaikinModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin152::setMode(const uint8_t mode) { switch (mode) { case kDaikinFan: @@ -3027,12 +3350,15 @@ void IRDaikin152::setMode(const uint8_t mode) { kDaikinModeSize, mode); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin152::convertMode(const stdAc::opmode_t mode) { return IRDaikinESP::convertMode(mode); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin152::setTemp(const uint8_t temp) { uint8_t degrees = std::max( temp, (getMode() == kDaikinHeat) ? kDaikinMinTemp : kDaikin2MinCoolTemp); @@ -3042,12 +3368,16 @@ void IRDaikin152::setTemp(const uint8_t temp) { kDaikin152TempSize, degrees); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin152::getTemp(void) { return GETBITS8(remote_state[kDaikin152TempByte], kDaikinTempOffset, kDaikin152TempSize); } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikin152::setFan(const uint8_t fan) { // Set the fan speed bits, leave low 4 bits alone uint8_t fanset; @@ -3060,6 +3390,8 @@ void IRDaikin152::setFan(const uint8_t fan) { setBits(&remote_state[kDaikin152FanByte], kHighNibble, kNibbleSize, fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin152::getFan(void) { const uint8_t fan = GETBITS8(remote_state[kDaikin152FanByte], kHighNibble, kNibbleSize); @@ -3070,31 +3402,43 @@ uint8_t IRDaikin152::getFan(void) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin152::convertFan(const stdAc::fanspeed_t speed) { return IRDaikinESP::convertFan(speed); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setSwingV(const bool on) { setBits(&remote_state[kDaikin152SwingVByte], kDaikinSwingOffset, kDaikinSwingSize, on ? kDaikinSwingOn : kDaikinSwingOff); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getSwingV(void) { return GETBITS8(remote_state[kDaikin152SwingVByte], kDaikinSwingOffset, kDaikinSwingSize); } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setQuiet(const bool on) { setBit(&remote_state[kDaikin152QuietByte], kDaikinBitSilentOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) this->setPowerful(false); } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getQuiet(void) { return GETBIT8(remote_state[kDaikin152QuietByte], kDaikinBitSilentOffset); } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setPowerful(const bool on) { setBit(&remote_state[kDaikin152PowerfulByte], kDaikinBitPowerfulOffset, on); if (on) { @@ -3105,29 +3449,41 @@ void IRDaikin152::setPowerful(const bool on) { } } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getPowerful(void) { return GETBIT8(remote_state[kDaikin152PowerfulByte], kDaikinBitPowerfulOffset); } +/// Set the Economy mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setEcono(const bool on) { setBit(&remote_state[kDaikin152EconoByte], kDaikinBitEconoOffset, on); // Powerful & Econo mode being on are mutually exclusive. if (on) this->setPowerful(false); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getEcono(void) { return GETBIT8(remote_state[kDaikin152EconoByte], kDaikinBitEconoOffset); } +/// Set the Sensor mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setSensor(const bool on) { setBit(&remote_state[kDaikin152SensorByte], kDaikin152SensorOffset, on); } +/// Get the Sensor mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getSensor(void) { return GETBIT8(remote_state[kDaikin152SensorByte], kDaikin152SensorOffset); } +/// Set the Comfort mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setComfort(const bool on) { setBit(&remote_state[kDaikin152ComfortByte], kDaikin152ComfortOffset, on); if (on) { @@ -3139,11 +3495,14 @@ void IRDaikin152::setComfort(const bool on) { } } +/// Get the Comfort mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getComfort(void) { return GETBIT8(remote_state[kDaikin152ComfortByte], kDaikin152ComfortOffset); } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin152::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN152; @@ -3169,7 +3528,8 @@ stdAc::state_t IRDaikin152::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin152::toString(void) { String result = ""; result.reserve(180); // Reserve some heap for the string to reduce fragging. @@ -3189,17 +3549,12 @@ String IRDaikin152::toString(void) { } #if SEND_DAIKIN64 -// Send a Daikin 64 bit A/C message. -// -// Args: -// data: A uint64_t containing the IR command/code. -// -// Supported devices: -// - Daikin FFN-C. -// -// Status: Beta / Probably Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 +/// Send a Daikin64 (64-bit) A/C formatted message. +/// Status: Beta / Probably Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 void IRsend::sendDaikin64(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { enableIROut(kDaikin64Freq); @@ -3223,22 +3578,16 @@ void IRsend::sendDaikin64(const uint64_t data, const uint16_t nbits, #endif // SEND_DAIKIN64 #if DECODE_DAIKIN64 -// Decode the supplied Daikin 64 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin64Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin FFN-C. -// -// Status: Beta / Probably Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 +/// Decode the supplied Daikin 64-bit message. (DAIKIN64) +/// Status: Beta / Probably Working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 bool IRrecv::decodeDaikin64(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * nbits + kDaikin64Overhead - offset) @@ -3280,33 +3629,28 @@ bool IRrecv::decodeDaikin64(decode_results *results, uint16_t offset, } #endif // DAIKIN64 -// Class for handling Daikin 64 bit / 19 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin ARC480A5 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/873 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.cpp -// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.h +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRDaikin64::IRDaikin64(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin64::begin(void) { _irsend.begin(); } #if SEND_DAIKIN64 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin64::send(const uint16_t repeat) { _irsend.sendDaikin64(getRaw(), kDaikin64Bits, repeat); } #endif // SEND_DAIKIN64 -// Calc the checksum for a given state. -// Args: -// state: The value to calc the checksum of. -// Returns: -// A 4-bit checksum stored in a uint_8. +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return The 4-bit checksum stored in a uint_8. uint8_t IRDaikin64::calcChecksum(const uint64_t state) { uint64_t data = GETBITS64(state, 0, kDaikin64ChecksumOffset); uint8_t result = 0; @@ -3315,44 +3659,51 @@ uint8_t IRDaikin64::calcChecksum(const uint64_t state) { return result & 0xF; } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin64::validChecksum(const uint64_t state) { // Validate the checksum of the given state. return (GETBITS64(state, kDaikin64ChecksumOffset, kDaikin64ChecksumSize) == calcChecksum(state)); } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin64::checksum(void) { setBits(&remote_state, kDaikin64ChecksumOffset, kDaikin64ChecksumSize, calcChecksum(remote_state)); } +/// Reset the internal state to a fixed known good state. void IRDaikin64::stateReset(void) { remote_state = kDaikin64KnownGoodState; } +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. uint64_t IRDaikin64::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_state A valid code for this protocol. void IRDaikin64::setRaw(const uint64_t new_state) { remote_state = new_state; } +/// Set the Power toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setPowerToggle(const bool on) { setBit(&remote_state, kDaikin64PowerToggleBit, on); } +/// Get the Power toggle setting of the A/C. +/// @return The current operating mode setting. bool IRDaikin64::getPowerToggle(void) { return GETBIT64(remote_state, kDaikin64PowerToggleBit); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin64::setTemp(const uint8_t temp) { uint8_t degrees = std::max(temp, kDaikin64MinTemp); degrees = std::min(degrees, kDaikin64MaxTemp); @@ -3360,15 +3711,21 @@ void IRDaikin64::setTemp(const uint8_t temp) { kDaikin64TempSize, uint8ToBcd(degrees)); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin64::getTemp(void) { return bcdToUint8(GETBITS64(remote_state, kDaikin64TempOffset, kDaikin64TempSize)); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin64::getMode(void) { return GETBITS64(remote_state, kDaikin64ModeOffset, kDaikin64ModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin64::setMode(const uint8_t mode) { switch (mode) { case kDaikin64Fan: @@ -3382,7 +3739,9 @@ void IRDaikin64::setMode(const uint8_t mode) { setBits(&remote_state, kDaikin64ModeOffset, kDaikin64ModeSize, mode); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin64::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kDry: return kDaikin64Dry; @@ -3391,7 +3750,9 @@ uint8_t IRDaikin64::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDaikin64::toCommonMode(const uint8_t mode) { switch (mode) { case kDaikin64Cool: return stdAc::opmode_t::kCool; @@ -3401,10 +3762,14 @@ stdAc::opmode_t IRDaikin64::toCommonMode(const uint8_t mode) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin64::getFan(void) { return GETBITS64(remote_state, kDaikin64FanOffset, kDaikin64FanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRDaikin64::setFan(const uint8_t speed) { switch (speed) { case kDaikin64FanQuiet: @@ -3420,7 +3785,9 @@ void IRDaikin64::setFan(const uint8_t speed) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin64::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kDaikin64FanQuiet; @@ -3432,7 +3799,9 @@ uint8_t IRDaikin64::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRDaikin64::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kDaikin64FanTurbo: return stdAc::fanspeed_t::kMax; @@ -3444,10 +3813,14 @@ stdAc::fanspeed_t IRDaikin64::toCommonFanSpeed(const uint8_t speed) { } } +/// Get the Turbo (Powerful) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getTurbo(void) { return getFan() == kDaikin64FanTurbo; } +/// Set the Turbo (Powerful) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setTurbo(const bool on) { if (on) { setFan(kDaikin64FanTurbo); @@ -3456,10 +3829,14 @@ void IRDaikin64::setTurbo(const bool on) { } } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getQuiet(void) { return getFan() == kDaikin64FanQuiet; } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setQuiet(const bool on) { if (on) { setFan(kDaikin64FanQuiet); @@ -3468,22 +3845,32 @@ void IRDaikin64::setQuiet(const bool on) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setSwingVertical(const bool on) { setBit(&remote_state, kDaikin64SwingVBit, on); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getSwingVertical(void) { return GETBIT64(remote_state, kDaikin64SwingVBit); } +/// Set the Sleep mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setSleep(const bool on) { setBit(&remote_state, kDaikin64SleepBit, on); } +/// Get the Sleep mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getSleep(void) { return GETBIT64(remote_state, kDaikin64SleepBit); } +/// Set the clock on the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin64::setClock(const uint16_t mins_since_midnight) { uint16_t mins = mins_since_midnight; if (mins_since_midnight >= 24 * 60) mins = 0; // Bounds check. @@ -3493,6 +3880,8 @@ void IRDaikin64::setClock(const uint16_t mins_since_midnight) { kDaikin64ClockHoursSize, uint8ToBcd(mins / 60)); // Hours } +/// Get the clock time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin64::getClock(void) { return bcdToUint8(GETBITS64(remote_state, kDaikin64ClockOffset + kDaikin64ClockMinsSize, @@ -3501,20 +3890,28 @@ uint16_t IRDaikin64::getClock(void) { kDaikin64ClockMinsSize)); } +/// Set the enable status of the On Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setOnTimeEnabled(const bool on) { setBit(&remote_state, kDaikin64OnTimeEnableBit, on); } +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getOnTimeEnabled(void) { return GETBIT64(remote_state, kDaikin64OnTimeEnableBit); } +/// Get the On Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin64::getOnTime(void) { return bcdToUint8(GETBITS64(remote_state, kDaikin64OnTimeOffset, kDaikin64OnTimeSize)) * 60 + (GETBIT64(remote_state, kDaikin64OnTimeHalfHourBit) ? 30 : 0); } +/// Set the On Timer time for the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin64::setOnTime(const uint16_t mins_since_midnight) { uint16_t halfhours = mins_since_midnight / 30; if (mins_since_midnight >= 24 * 60) halfhours = 0; // Bounds check. @@ -3524,20 +3921,28 @@ void IRDaikin64::setOnTime(const uint16_t mins_since_midnight) { setBit(&remote_state, kDaikin64OnTimeHalfHourBit, halfhours % 2); } +/// Set the enable status of the Off Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setOffTimeEnabled(const bool on) { setBit(&remote_state, kDaikin64OffTimeEnableBit, on); } +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getOffTimeEnabled(void) { return GETBIT64(remote_state, kDaikin64OffTimeEnableBit); } +/// Get the Off Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin64::getOffTime(void) { return bcdToUint8(GETBITS64(remote_state, kDaikin64OffTimeOffset, kDaikin64OffTimeSize)) * 60 + (GETBIT64(remote_state, kDaikin64OffTimeHalfHourBit) ? 30 : 0); } +/// Set the Off Timer time for the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin64::setOffTime(const uint16_t mins_since_midnight) { uint16_t halfhours = mins_since_midnight / 30; if (mins_since_midnight >= 24 * 60) halfhours = 0; // Bounds check. @@ -3547,7 +3952,8 @@ void IRDaikin64::setOffTime(const uint16_t mins_since_midnight) { setBit(&remote_state, kDaikin64OffTimeHalfHourBit, halfhours % 2); } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin64::toString(void) { String result = ""; result.reserve(120); // Reserve some heap for the string to reduce fragging. @@ -3579,7 +3985,9 @@ String IRDaikin64::toString(void) { return result; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @param[in] prev Ptr to a previous state. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin64::toCommon(const stdAc::state_t *prev) { stdAc::state_t result; if (prev != NULL) result = *prev; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Daikin.h b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h similarity index 84% rename from lib/IRremoteESP8266-2.7.7/src/ir_Daikin.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h index 3c6f542ff..8c11dfb9f 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Daikin.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h @@ -1,17 +1,36 @@ // Copyright 2016 sillyfrog // Copyright 2017 sillyfrog, crankyoldgit -// Copyright 2018-2019 crankyoldgit +// Copyright 2018-2020 crankyoldgit +// Copyright 2019 pasna (IRDaikin160 class / Daikin176 class) + +/// @file +/// @brief Support for Daikin A/C protocols. +/// @see Daikin http://harizanov.com/2012/02/control-daikin-air-conditioner-over-the-internet/ +/// @see Daikin https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// @see Daikin http://rdlab.cdmt.vn/project-2013/daikin-ir-protocol +/// @see Daikin https://github.com/blafois/Daikin-IR-Reverse +/// @see Daikin128 https://github.com/crankyoldgit/IRremoteESP8266/issues/827 +/// @see Daikin152 https://github.com/crankyoldgit/IRremoteESP8266/issues/873 +/// @see Daikin152 https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.cpp +/// @see Daikin152 https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.h +/// @see Daikin160 https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// @see Daikin2 https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit#gid=236366525&range=B25:D32 +/// @see Daikin2 https://github.com/crankyoldgit/IRremoteESP8266/issues/582 +/// @see Daikin2 https://www.daikin.co.nz/sites/default/files/daikin-split-system-US7-FTXZ25-50NV1B.pdf +/// @see Daikin216 https://github.com/crankyoldgit/IRremoteESP8266/issues/689 +/// @see Daikin216 https://github.com/danny-source/Arduino_DY_IRDaikin +/// @see Daikin64 https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 // Supports: -// Brand: Daikin, Model: ARC433** remote -// Brand: Daikin, Model: ARC477A1 remote -// Brand: Daikin, Model: FTXZ25NV1B A/C -// Brand: Daikin, Model: FTXZ35NV1B A/C -// Brand: Daikin, Model: FTXZ50NV1B A/C -// Brand: Daikin, Model: ARC433B69 remote -// Brand: Daikin, Model: ARC423A5 remote +// Brand: Daikin, Model: ARC433** remote (DAIKIN) +// Brand: Daikin, Model: ARC477A1 remote (DAIKIN2) +// Brand: Daikin, Model: FTXZ25NV1B A/C (DAIKIN2) +// Brand: Daikin, Model: FTXZ35NV1B A/C (DAIKIN2) +// Brand: Daikin, Model: FTXZ50NV1B A/C (DAIKIN2) +// Brand: Daikin, Model: ARC433B69 remote (DAIKIN216) +// Brand: Daikin, Model: ARC423A5 remote (DAIKIN160) // Brand: Daikin, Model: FTE12HV2S A/C -// Brand: Daikin, Model: BRC4C153 remote +// Brand: Daikin, Model: BRC4C153 remote (DAIKIN176) // Brand: Daikin, Model: 17 Series A/C (DAIKIN128) // Brand: Daikin, Model: FTXB12AXVJU A/C (DAIKIN128) // Brand: Daikin, Model: FTXB09AXVJU A/C (DAIKIN128) @@ -194,7 +213,7 @@ const uint16_t kDaikinGap = 29000; const uint64_t kDaikinFirstHeader64 = 0b1101011100000000000000001100010100000000001001111101101000010001; -// Another variant of the protocol for the Daikin ARC477A1 remote. + const uint16_t kDaikin2Freq = 36700; // Modulation Frequency in Hz. const uint16_t kDaikin2LeaderMark = 10024; const uint16_t kDaikin2LeaderSpace = 25180; @@ -240,8 +259,6 @@ const uint8_t kDaikin2SwingVBreeze = 0xC; const uint8_t kDaikin2SwingVCirculate = 0xD; const uint8_t kDaikin2FanByte = 28; -// Ref: -// https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit#gid=236366525&range=B25:D32 const uint8_t kDaikin2SwingHWide = 0xA3; const uint8_t kDaikin2SwingHLeftMax = 0xA8; const uint8_t kDaikin2SwingHLeft = 0xA9; @@ -253,7 +270,7 @@ const uint8_t kDaikin2SwingHSwing = 0xBF; const uint8_t kDaikin2MinCoolTemp = 18; // Min temp (in C) when in Cool mode. -// Another variant of the protocol for the Daikin ARC433B69 remote. + const uint16_t kDaikin216Freq = 38000; // Modulation Frequency in Hz. const uint16_t kDaikin216HdrMark = 3440; const uint16_t kDaikin216HdrSpace = 1750; @@ -283,7 +300,7 @@ const uint8_t kDaikin216SwingOff = 0b0000; const uint8_t kDaikin216ByteSwingH = 17; const uint8_t kDaikin216BytePowerful = 21; -// Another variant of the protocol for the Daikin ARC423A5 remote. + const uint16_t kDaikin160Freq = 38000; // Modulation Frequency in Hz. const uint16_t kDaikin160HdrMark = 5000; const uint16_t kDaikin160HdrSpace = 2145; @@ -313,7 +330,7 @@ const uint8_t kDaikin160SwingVHigh = 0x4; const uint8_t kDaikin160SwingVHighest = 0x5; const uint8_t kDaikin160SwingVAuto = 0xF; -// Another variant of the protocol for the Daikin BRC4C153 remote. + const uint16_t kDaikin176Freq = 38000; // Modulation Frequency in Hz. const uint16_t kDaikin176HdrMark = 5070; const uint16_t kDaikin176HdrSpace = 2140; @@ -344,8 +361,7 @@ const uint8_t kDaikin176ByteSwingH = 18; const uint8_t kDaikin176SwingHAuto = 0x5; const uint8_t kDaikin176SwingHOff = 0x6; -// Another variant of the protocol for the Daikin BRC52B63 remote. -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827 + const uint16_t kDaikin128Freq = 38000; // Modulation Frequency in Hz. const uint16_t kDaikin128LeaderMark = 9800; const uint16_t kDaikin128LeaderSpace = 9800; @@ -403,8 +419,7 @@ const uint8_t kDaikin128BitWall = 0b00001000; const uint8_t kDaikin128BitCeiling = 0b00000001; const uint8_t kDaikin128MaskLight = kDaikin128BitWall | kDaikin128BitCeiling; -// Another variant of the protocol for the Daikin ARC480A5 remote. -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/873 + const uint16_t kDaikin152Freq = 38000; // Modulation Frequency in Hz. const uint8_t kDaikin152LeaderBits = 5; const uint16_t kDaikin152HdrMark = 3492; @@ -435,6 +450,7 @@ const uint8_t kDaikin152ComfortOffset = 1; // Mask 0b00000010 const uint8_t kDaikin152SensorByte = kDaikin152EconoByte; // Mask 0b00001000 const uint8_t kDaikin152SensorOffset = 3; // Mask 0b00001000 + const uint16_t kDaikin64HdrMark = kDaikin128HdrMark; const uint16_t kDaikin64BitMark = kDaikin128BitMark; const uint16_t kDaikin64HdrSpace = kDaikin128HdrSpace; @@ -500,6 +516,7 @@ const uint8_t kDaikin64ChecksumSize = 4; // Mask 0b1111 << 59 #define DAIKIN_FAN_AUTO kDaikinFanAuto #define DAIKIN_FAN_QUIET kDaikinFanQuiet +/// Class for handling detailed Daikin 280-bit A/C messages. class IRDaikinESP { public: explicit IRDaikinESP(const uint16_t pin, const bool inverted = false, @@ -507,6 +524,10 @@ class IRDaikinESP { #if SEND_DAIKIN void send(const uint16_t repeat = kDaikinDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(void); @@ -564,17 +585,20 @@ class IRDaikinESP { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote[kDaikinStateLength]; + uint8_t remote[kDaikinStateLength]; ///< The state of the IR remote. void stateReset(void); void checksum(void); }; -// Class to emulate a Daikin ARC477A1 remote. +/// Class for handling detailed Daikin 312-bit A/C messages. +/// Code by crankyoldgit, Reverse engineering analysis by sheppy99 class IRDaikin2 { public: explicit IRDaikin2(const uint16_t pin, const bool inverted = false, @@ -582,6 +606,10 @@ class IRDaikin2 { #if SEND_DAIKIN2 void send(const uint16_t repeat = kDaikin2DefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); @@ -603,8 +631,6 @@ class IRDaikin2 { void setQuiet(const bool on); bool getPowerful(); void setPowerful(const bool on); - void setSensor(const bool on); - bool getSensor(); void setEcono(const bool on); bool getEcono(); void setEye(const bool on); @@ -641,8 +667,6 @@ class IRDaikin2 { bool getFreshAirHigh(); uint8_t* getRaw(); void setRaw(const uint8_t new_code[]); - uint32_t getCommand(); - void setCommand(uint32_t value); static bool validChecksum(uint8_t state[], const uint16_t length = kDaikin2StateLength); static uint8_t convertMode(const stdAc::opmode_t mode); @@ -656,19 +680,21 @@ class IRDaikin2 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin2StateLength]; + uint8_t remote_state[kDaikin2StateLength]; ///< The state of the IR remote. void stateReset(); void checksum(); void clearOnTimerFlag(); void clearSleepTimerFlag(); }; -// Class to emulate a Daikin ARC433B69 remote. +/// Class for handling detailed Daikin 216-bit A/C messages. class IRDaikin216 { public: explicit IRDaikin216(const uint16_t pin, const bool inverted = false, @@ -676,6 +702,10 @@ class IRDaikin216 { #if SEND_DAIKIN216 void send(const uint16_t repeat = kDaikin216DefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); @@ -708,17 +738,19 @@ class IRDaikin216 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin216StateLength]; + uint8_t remote_state[kDaikin216StateLength]; ///< The state of the IR remote. void stateReset(); void checksum(); }; -// Class to emulate a Daikin ARC423A5 remote. +/// Class for handling detailed Daikin 160-bit A/C messages. class IRDaikin160 { public: explicit IRDaikin160(const uint16_t pin, const bool inverted = false, @@ -726,6 +758,10 @@ class IRDaikin160 { #if SEND_DAIKIN160 void send(const uint16_t repeat = kDaikin160DefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); @@ -754,17 +790,19 @@ class IRDaikin160 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin160StateLength]; + uint8_t remote_state[kDaikin160StateLength]; ///< The state of the IR remote. void stateReset(); void checksum(); }; -// Class to emulate a Daikin BRC4C153 remote. +/// Class for handling detailed Daikin 176-bit A/C messages. class IRDaikin176 { public: explicit IRDaikin176(const uint16_t pin, const bool inverted = false, @@ -772,6 +810,10 @@ class IRDaikin176 { #if SEND_DAIKIN176 void send(const uint16_t repeat = kDaikin176DefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); @@ -803,24 +845,32 @@ class IRDaikin176 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin176StateLength]; + uint8_t remote_state[kDaikin176StateLength]; ///< The state of the IR remote. uint8_t _saved_temp; void stateReset(); void checksum(); }; -// Class to emulate a Daikin BRC52B63 remote / Daikin 17 series A/C. +/// Class for handling detailed Daikin 128-bit A/C messages. +/// Code by crankyoldgit. +/// Analysis by Daniel Vena class IRDaikin128 { public: explicit IRDaikin128(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); #if SEND_DAIKIN128 void send(const uint16_t repeat = kDaikin128DefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_DAIKIN128 void begin(); @@ -866,12 +916,14 @@ class IRDaikin128 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin128StateLength]; + uint8_t remote_state[kDaikin128StateLength]; ///< The state of the IR remote. void stateReset(void); static uint8_t calcFirstChecksum(const uint8_t state[]); static uint8_t calcSecondChecksum(const uint8_t state[]); @@ -882,7 +934,7 @@ class IRDaikin128 { void clearSleepTimerFlag(void); }; -// Class to emulate a Daikin ARC480A5 remote. +/// Class for handling detailed Daikin 152-bit A/C messages. class IRDaikin152 { public: explicit IRDaikin152(const uint16_t pin, const bool inverted = false, @@ -890,6 +942,10 @@ class IRDaikin152 { #if SEND_DAIKIN152 void send(const uint16_t repeat = kDaikin152DefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif void begin(); @@ -921,24 +977,24 @@ class IRDaikin152 { bool getComfort(void); static uint8_t convertMode(const stdAc::opmode_t mode); static uint8_t convertFan(const stdAc::fanspeed_t speed); - static stdAc::opmode_t toCommonMode(const uint8_t mode); - static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); stdAc::state_t toCommon(void); String toString(void); #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin152StateLength]; + uint8_t remote_state[kDaikin152StateLength]; ///< The state of the IR remote. void stateReset(); void checksum(); }; -// Class to emulate a Daikin DGS01 remote. +/// Class for handling detailed Daikin 64-bit A/C messages. class IRDaikin64 { public: explicit IRDaikin64(const uint16_t pin, const bool inverted = false, @@ -946,6 +1002,10 @@ class IRDaikin64 { #if SEND_DAIKIN64 void send(const uint16_t repeat = kDaikin64DefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_DAIKIN64 void begin(); @@ -988,11 +1048,13 @@ class IRDaikin64 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif - uint64_t remote_state; + uint64_t remote_state; ///< The state of the IR remote. void stateReset(); void checksum(); }; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.cpp index 7f6c3158a..df915ca35 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.cpp @@ -1,5 +1,6 @@ // Copyright 2020 David Conran -// Delonghi based protocol. +/// @file +/// @brief Delonghi based protocol. #include "ir_Delonghi.h" #include "IRrecv.h" @@ -28,18 +29,12 @@ const uint16_t kDelonghiAcOverhead = 3; #if SEND_DELONGHI_AC -// Send an Delonghi AC formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kDelonghiAcBits. -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE / Reported as working on a real device. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 +/// Send a Delonghi A/C formatted message. +/// Status: STABLE / Reported as working on a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 void IRsend::sendDelonghiAc(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kDelonghiAcHdrMark, kDelonghiAcHdrSpace, @@ -52,21 +47,16 @@ void IRsend::sendDelonghiAc(const uint64_t data, const uint16_t nbits, #endif // SEND_DELONGHI_AC #if DECODE_DELONGHI_AC -// Decode the supplied DELONGHI_AC message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kDelonghiAcBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Expected to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 +/// Decode the supplied Delonghi A/C message. +/// Status: STABLE / Expected to be working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 bool IRrecv::decodeDelonghiAc(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * nbits + kDelonghiAcOverhead - offset) @@ -98,21 +88,28 @@ bool IRrecv::decodeDelonghiAc(decode_results *results, uint16_t offset, } #endif // DECODE_DELONGHI_AC - -// Class for controlling the settings of a Delonghi A/C - +/// Class constructor. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRDelonghiAc::IRDelonghiAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRDelonghiAc::begin(void) { _irsend.begin(); } #if SEND_DELONGHI_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDelonghiAc::send(const uint16_t repeat) { _irsend.sendDelonghiAc(getRaw(), kDelonghiAcBits, repeat); } #endif // SEND_DELONGHI_AC +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return A valid checksum value. uint8_t IRDelonghiAc::calcChecksum(const uint64_t state) { uint8_t sum = 0; // Add up all the 8 bit chunks except for Most-significant 8 bits. @@ -122,51 +119,73 @@ uint8_t IRDelonghiAc::calcChecksum(const uint64_t state) { return sum; } +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDelonghiAc::validChecksum(const uint64_t state) { return (GETBITS64(state, kDelonghiAcChecksumOffset, kDelonghiAcChecksumSize) == IRDelonghiAc::calcChecksum(state)); } +/// Calculate and set the checksum values for the internal state. void IRDelonghiAc::checksum(void) { setBits(&remote_state, kDelonghiAcChecksumOffset, kDelonghiAcChecksumSize, calcChecksum(remote_state)); } +/// Reset the internal state to a fixed known good state. void IRDelonghiAc::stateReset(void) { remote_state = 0x5400000000000153; _saved_temp = 23; // DegC (Random reasonable default value) _saved_temp_units = 0; // Celsius } +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. uint64_t IRDelonghiAc::getRaw(void) { checksum(); // Ensure correct bit array before returning return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. void IRDelonghiAc::setRaw(const uint64_t state) { remote_state = state; } +/// Change the power setting to On. void IRDelonghiAc::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDelonghiAc::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDelonghiAc::setPower(const bool on) { setBit(&remote_state, kDelonghiAcPowerBit, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDelonghiAc::getPower(void) { return GETBIT64(remote_state, kDelonghiAcPowerBit); } +/// Change the temperature scale units. +/// @param[in] fahrenheit true, use Fahrenheit. false, use Celsius. void IRDelonghiAc::setTempUnit(const bool fahrenheit) { setBit(&remote_state, kDelonghiAcTempUnitBit, fahrenheit); } +/// Get the temperature scale unit of measure currently in use. +/// @return true, is Fahrenheit. false, is Celsius. bool IRDelonghiAc::getTempUnit(void) { return GETBIT64(remote_state, kDelonghiAcTempUnitBit); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees. +/// @param[in] fahrenheit Use Fahrenheit as the temperature scale. +/// @param[in] force Do we ignore any sanity checks? void IRDelonghiAc::setTemp(const uint8_t degrees, const bool fahrenheit, const bool force) { uint8_t temp; @@ -190,12 +209,15 @@ void IRDelonghiAc::setTemp(const uint8_t degrees, const bool fahrenheit, temp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in currently configured units/scale. uint8_t IRDelonghiAc::getTemp(void) { return GETBITS64(remote_state, kDelonghiAcTempOffset, kDelonghiAcTempSize) + (getTempUnit() ? kDelonghiAcTempMinF : kDelonghiAcTempMinC) - 1; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired native setting. void IRDelonghiAc::setFan(const uint8_t speed) { // Mode fan speed rules. switch (getMode()) { @@ -222,11 +244,15 @@ void IRDelonghiAc::setFan(const uint8_t speed) { setBits(&remote_state, kDelonghiAcFanOffset, kDelonghiAcFanSize, speed); } +/// Get the current native fan speed setting. +/// @return The current fan speed. uint8_t IRDelonghiAc::getFan(void) { return GETBITS64(remote_state, kDelonghiAcFanOffset, kDelonghiAcFanSize); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDelonghiAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -242,7 +268,9 @@ uint8_t IRDelonghiAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRDelonghiAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kDelonghiAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -252,10 +280,14 @@ stdAc::fanspeed_t IRDelonghiAc::toCommonFanSpeed(const uint8_t speed) { } } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDelonghiAc::getMode(void) { return GETBITS64(remote_state, kDelonghiAcModeOffset, kDelonghiAcModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired native operating mode. void IRDelonghiAc::setMode(const uint8_t mode) { switch (mode) { case kDelonghiAcAuto: @@ -279,7 +311,9 @@ void IRDelonghiAc::setMode(const uint8_t mode) { if (mode == kDelonghiAcCool) setTemp(_saved_temp, _saved_temp_units); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDelonghiAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: @@ -293,7 +327,9 @@ uint8_t IRDelonghiAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDelonghiAc::toCommonMode(const uint8_t mode) { switch (mode) { case kDelonghiAcCool: return stdAc::opmode_t::kCool; @@ -303,36 +339,45 @@ stdAc::opmode_t IRDelonghiAc::toCommonMode(const uint8_t mode) { } } -// Aka Turbo. +/// Set the Boost (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDelonghiAc::setBoost(const bool on) { setBit(&remote_state, kDelonghiAcBoostBit, on); } -// Aka Turbo. +/// Get the Boost (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDelonghiAc::getBoost(void) { return GETBIT64(remote_state, kDelonghiAcBoostBit); } +/// Set the Sleep mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDelonghiAc::setSleep(const bool on) { setBit(&remote_state, kDelonghiAcSleepBit, on); } +/// Get the Sleep mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDelonghiAc::getSleep(void) { return GETBIT64(remote_state, kDelonghiAcSleepBit); } +/// Set the enable status of the On Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDelonghiAc::setOnTimerEnabled(const bool on) { setBit(&remote_state, kDelonghiAcOnTimerEnableBit, on); } +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDelonghiAc::getOnTimerEnabled(void) { return GETBIT64(remote_state, kDelonghiAcOnTimerEnableBit); } -// Set the On timer to activate in nr of minutes. -// Args: -// nr_of_mins: Total nr of mins to wait before waking the device. -// (Max 23 hrs and 59 minutes. i.e. 1439 mins) +/// Set the On timer to activate in nr of minutes. +/// @param[in] nr_of_mins Total nr of mins to wait before waking the device. +/// @note Max 23 hrs and 59 minutes. i.e. 1439 mins. void IRDelonghiAc::setOnTimer(const uint16_t nr_of_mins) { uint16_t value = std::min(kDelonghiAcTimerMax, nr_of_mins); setBits(&remote_state, kDelonghiAcOnTimerMinsOffset, kDelonghiAcMinsSize, @@ -343,6 +388,8 @@ void IRDelonghiAc::setOnTimer(const uint16_t nr_of_mins) { setOnTimerEnabled(value > 0); } +/// Get the On timer time. +/// @return Total nr of mins before the device turns on. uint16_t IRDelonghiAc::getOnTimer(void) { return GETBITS64(remote_state, kDelonghiAcOnTimerHoursOffset, kDelonghiAcHoursSize) * 60 + @@ -350,18 +397,21 @@ uint16_t IRDelonghiAc::getOnTimer(void) { kDelonghiAcMinsSize); } +/// Set the enable status of the Off Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDelonghiAc::setOffTimerEnabled(const bool on) { setBit(&remote_state, kDelonghiAcOffTimerEnableBit, on); } +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDelonghiAc::getOffTimerEnabled(void) { return GETBIT64(remote_state, kDelonghiAcOffTimerEnableBit); } -// Set the Off timer to activate in nr of minutes. -// Args: -// nr_of_mins: Total nr of mins to wait before waking the device. -// (Max 23 hrs and 59 minutes. i.e. 1439 mins) +/// Set the Off timer to activate in nr of minutes. +/// @param[in] nr_of_mins Total nr of mins to wait before turning off the device +/// @note Max 23 hrs and 59 minutes. i.e. 1439 mins. void IRDelonghiAc::setOffTimer(const uint16_t nr_of_mins) { uint16_t value = std::min(kDelonghiAcTimerMax, nr_of_mins); setBits(&remote_state, kDelonghiAcOffTimerMinsOffset, kDelonghiAcMinsSize, @@ -372,6 +422,8 @@ void IRDelonghiAc::setOffTimer(const uint16_t nr_of_mins) { setOffTimerEnabled(value > 0); } +/// Get the Off timer time. +/// @return Total nr of mins before the device turns off. uint16_t IRDelonghiAc::getOffTimer(void) { return GETBITS64(remote_state, kDelonghiAcOffTimerHoursOffset, kDelonghiAcHoursSize) * 60 + @@ -379,7 +431,8 @@ uint16_t IRDelonghiAc::getOffTimer(void) { kDelonghiAcMinsSize); } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDelonghiAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DELONGHI_AC; @@ -404,7 +457,8 @@ stdAc::state_t IRDelonghiAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDelonghiAc::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.h b/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.h similarity index 85% rename from lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.h index 8ba8e90f4..da3a6f618 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Delonghi.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.h @@ -1,7 +1,13 @@ -// Delonghi A/C -// // Copyright 2020 David Conran +/// @file +/// @brief Delonghi A/C +/// @note Kudos to TheMaxxz For the breakdown and mapping of the bit values. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 + +// Supports: +// Brand: Delonghi, Model: PAC A95 + #ifndef IR_DELONGHI_H_ #define IR_DELONGHI_H_ @@ -16,15 +22,6 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Delonghi, Model: PAC A95 - -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 - -// Kudos: -// TheMaxxz: For the breakdown and mapping of the bit values. - /* State bit map: +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------+ @@ -100,14 +97,19 @@ const uint8_t kDelonghiAcChecksumSize = 8; // Classes + +/// Class for handling detailed Delonghi A/C messages. class IRDelonghiAc { public: explicit IRDelonghiAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(); #if SEND_DELONGHI_AC void send(const uint16_t repeat = kDelonghiAcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_DELONGHI_AC void begin(); @@ -149,13 +151,15 @@ class IRDelonghiAc { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif - uint64_t remote_state; // The state of the IR remote. - uint8_t _saved_temp; // The previously user requested temp value. - uint8_t _saved_temp_units; // The previously user requested temp units. + uint64_t remote_state; ///< The state of the IR remote. + uint8_t _saved_temp; ///< The previously user requested temp value. + uint8_t _saved_temp_units; ///< The previously user requested temp units. void checksum(void); }; #endif // IR_DELONGHI_H_ diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Denon.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Denon.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.7/src/ir_Denon.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Denon.cpp index 6dd4cd839..700fd31cb 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Denon.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Denon.cpp @@ -1,17 +1,22 @@ // Copyright 2016 Massimiliano Pinto // Copyright 2017 David Conran +/// @file +/// @brief Denon support +/// Original Denon support added by https://github.com/csBlueChip +/// Ported over by Massimiliano Pinto +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp +/// @see http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls + +// Supports: +// Brand: Denon, Model: AVR-3801 A/V Receiver (probably) #include #include "IRrecv.h" #include "IRsend.h" #include "IRutils.h" -// Original Denon support added by https://github.com/csBlueChip -// Ported over by Massimiliano Pinto // Constants -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp const uint16_t kDenonTick = 263; const uint16_t kDenonHdrMarkTicks = 1; const uint16_t kDenonHdrMark = kDenonHdrMarkTicks * kDenonTick; @@ -33,21 +38,13 @@ const uint32_t kDenonMinGap = kDenonMinGapTicks * kDenonTick; const uint64_t kDenonManufacturer = 0x2A4CULL; #if SEND_DENON -// Send a Denon message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kDenonBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE / Should be working. -// -// Notes: -// Some Denon devices use a Kaseikyo/Panasonic 48-bit format -// Others use the Sharp protocol. -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp -// http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls +/// Send a Denon formatted message. +/// Status: STABLE / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note Some Denon devices use a Kaseikyo/Panasonic 48-bit format +/// Others use the Sharp protocol. void IRsend::sendDenon(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits >= kPanasonicBits) // Is this really Panasonic? sendPanasonic64(data, nbits, repeat); @@ -60,21 +57,16 @@ void IRsend::sendDenon(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif #if DECODE_DENON -// Decode a Denon message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Expected nr. of data bits. (Typically kDenonBits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should work fine. -// -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp +/// Decode the supplied Delonghi A/C message. +/// Status: STABLE / Should work fine. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp bool IRrecv::decodeDenon(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Dish.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Dish.cpp similarity index 56% rename from lib/IRremoteESP8266-2.7.7/src/ir_Dish.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Dish.cpp index 291201ed6..94f5450b8 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Dish.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Dish.cpp @@ -1,20 +1,21 @@ // Copyright Todd Treece // Copyright 2017 David Conran +/// @file +/// @brief DISH Network protocol support +/// DISH support originally by Todd Treece +/// @see http://unionbridge.org/design/ircommand +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp +/// @see http://www.hifi-remote.com/wiki/index.php?title=Dish + +// Supports: +// Brand: DISH NETWORK, Model: echostar 301 #include "IRrecv.h" #include "IRsend.h" #include "IRutils.h" -// DISH support originally by Todd Treece -// http://unionbridge.org/design/ircommand - -// Supports: -// Brand: DISH NETWORK, Model: echostar 301 // Constants -// Ref: -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp -// http://www.hifi-remote.com/wiki/index.php?title=Dish const uint16_t kDishTick = 100; const uint16_t kDishHdrMarkTicks = 4; const uint16_t kDishHdrMark = kDishHdrMarkTicks * kDishTick; @@ -30,27 +31,20 @@ const uint16_t kDishRptSpaceTicks = kDishHdrSpaceTicks; const uint16_t kDishRptSpace = kDishRptSpaceTicks * kDishTick; #if SEND_DISH -// Send an IR command to a DISH NETWORK device. -// -// Args: -// data: The contents of the command you want to send. -// nbits: The bit size of the command being sent. -// repeat: The number of times you want the command to be repeated. -// -// Status: STABLE / Working. -// -// Note: -// Dishplayer is a different protocol. -// Typically a DISH device needs to get a command a total of at least 4 -// times to accept it. e.g. repeat=3 -// -// Here is the LIRC file I found that seems to match the remote codes from the -// oscilloscope: -// DISH NETWORK (echostar 301): -// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx -// -// Ref: -// http://www.hifi-remote.com/wiki/index.php?title=Dish +/// Send a DISH NETWORK formatted message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note Dishplayer is a different protocol. +/// Typically a DISH device needs to get a command a total of at least 4 +/// times to accept it. e.g. repeat=3 +/// +/// Here is the LIRC file I found that seems to match the remote codes from the +/// oscilloscope: +/// DISH NETWORK (echostar 301): +/// @see http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx +/// @see http://www.hifi-remote.com/wiki/index.php?title=Dish void IRsend::sendDISH(uint64_t data, uint16_t nbits, uint16_t repeat) { enableIROut(57600); // Set modulation freq. to 57.6kHz. // Header is only ever sent once. @@ -65,27 +59,21 @@ void IRsend::sendDISH(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif #if DECODE_DISH -// Decode the supplied DISH NETWORK message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. Typically kDishBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: ALPHA (untested and unconfirmed.) -// -// Note: -// Dishplayer is a different protocol. -// Typically a DISH device needs to get a command a total of at least 4 -// times to accept it. -// Ref: -// http://www.hifi-remote.com/wiki/index.php?title=Dish -// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp +/// Decode the supplied DISH NETWORK message. +/// Status: ALPHA (untested and unconfirmed.) +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @note Dishplayer is a different protocol. +/// Typically a DISH device needs to get a command a total of at least 4 +/// times to accept it. +/// @see http://www.hifi-remote.com/wiki/index.php?title=Dish +/// @see http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp bool IRrecv::decodeDISH(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kDishBits) return false; // Not strictly compliant. diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Doshisha.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Doshisha.cpp similarity index 66% rename from lib/IRremoteESP8266-2.7.7/src/ir_Doshisha.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Doshisha.cpp index 7352c2c84..0a5fadedb 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Doshisha.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Doshisha.cpp @@ -1,29 +1,28 @@ // Copyright 2020 Christian (nikize) -// Support for Doshisha protocol - -#include "IRrecv.h" -#include "IRsend.h" -#include "IRutils.h" +/// @file +/// @brief Doshisha protocol support +/// @see https://www.doshisha-led.com/ // Supports: // Brand: Doshisha, Model: CZ-S32D LED Light // Brand: Doshisha, Model: CZ-S38D LED Light // Brand: Doshisha, Model: CZ-S50D LED Light // Brand: Doshisha, Model: RCZ01 remote -// -// Ref: https://www.doshisha-led.com/ + +#include "IRrecv.h" +#include "IRsend.h" +#include "IRutils.h" + const uint16_t kDoshishaHdrMark = 3412; const uint16_t kDoshishaHdrSpace = 1722; const uint16_t kDoshishaBitMark = 420; const uint16_t kDoshishaOneSpace = 1310; const uint16_t kDoshishaZeroSpace = 452; -const uint16_t kDoshishaFreq = 38000; -const uint16_t kDoshishaOverhead = 3; // basic structure of bits, and mask -const uint64_t kRcz01CheckMask = 0xffffffff00; -const uint64_t kRcz01CheckExpected = 0x800B304800; +const uint64_t kRcz01SignatureMask = 0xffffffff00; +const uint64_t kRcz01Signature = 0x800B304800; const uint8_t kRcz01CommandMask = 0xFE; const uint8_t kRcz01ChannelMask = 0x01; @@ -46,33 +45,27 @@ const uint8_t kRcz01CommandNightLight = 0xC8; // end Known commands #if SEND_DOSHISHA -// Send an Doshisha formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kDelonghiAcBits. -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE / working on a real device. +/// Send a Doshisha formatted message. +/// Status: STABLE / Works on real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendDoshisha(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kDoshishaHdrMark, kDoshishaHdrSpace, kDoshishaBitMark, kDoshishaOneSpace, kDoshishaBitMark, kDoshishaZeroSpace, kDoshishaBitMark, kDefaultMessageGap, - data, nbits, kDoshishaFreq, true, repeat, kDutyDefault); + data, nbits, 38, true, repeat, kDutyDefault); } -// Encode Doshisha combining constant values with command and channel. -// -// Args: -// command: The commandcode to be sent. -// channel: The one bit channel 0 for CH1 and 1 for CH2 -// -// Status: STABLE / Working. +/// Encode Doshisha combining constant values with command and channel. +/// Status: STABLE / Working. +/// @param[in] command The command code to be sent. +/// @param[in] channel The one bit channel 0 for CH1 and 1 for CH2 +/// @return The corresponding Doshisha code. uint64_t IRsend::encodeDoshisha(const uint8_t command, const uint8_t channel) { - uint64_t data = kRcz01CheckExpected | + uint64_t data = kRcz01Signature | (command & kRcz01CommandMask) | (channel & kRcz01ChannelMask); return data; @@ -80,20 +73,19 @@ uint64_t IRsend::encodeDoshisha(const uint8_t command, const uint8_t channel) { #endif // SEND_DOSHISHA #if DECODE_DOSHISHA -// Decode the supplied Doshisha message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kDelonghiAcBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Expected to be working. +/// Decode the supplied Doshisha message. +/// Status: STABLE / Works on real device. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeDoshisha(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid message. if (strict && nbits != kDoshishaBits) return false; @@ -110,13 +102,13 @@ bool IRrecv::decodeDoshisha(decode_results *results, uint16_t offset, // e.g. data = 0x800B3048C0, nbits = 40 // RCZ01 remote commands starts with a lead bit set - if ((data & kRcz01CheckMask) != kRcz01CheckExpected) { + if ((data & kRcz01SignatureMask) != kRcz01Signature) { DPRINT(" decodeDoshisha data "); DPRINT(uint64ToString(data, 16)); DPRINT(" masked "); - DPRINT(uint64ToString(data & kRcz01CheckMask, 16)); + DPRINT(uint64ToString(data & kRcz01SignatureMask, 16)); DPRINT(" not matching "); - DPRINT(uint64ToString(kRcz01CheckExpected, 16)); + DPRINT(uint64ToString(kRcz01Signature, 16)); DPRINTLN(" ."); return false; // expected lead bits not matching } diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Electra.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Electra.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.7/src/ir_Electra.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Electra.cpp index 16c753f35..0008a79a4 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Electra.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Electra.cpp @@ -1,4 +1,10 @@ // Copyright 2018, 2019 David Conran +/// @file +/// @brief Support for Electra A/C protocols. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/527 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/642 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/778 #include "ir_Electra.h" #include @@ -8,15 +14,6 @@ #include "IRtext.h" #include "IRutils.h" -// Electra A/C added by crankyoldgit -// - -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/527 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/642 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/778 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp - // Constants const uint16_t kElectraAcHdrMark = 9166; const uint16_t kElectraAcBitMark = 646; @@ -35,15 +32,12 @@ using irutils::setBit; using irutils::setBits; #if SEND_ELECTRA_AC -// Send a Electra message -// -// Args: -// data: Contents of the message to be sent. (Guessing MSBF order) -// nbits: Nr. of bits of data to be sent. Typically kElectraAcBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: Alpha / Needs testing against a real device. -// +/// Send a Electra A/C formatted message. +/// Status: Alpha / Needs testing against a real device. +/// @param[in] data The message to be sent. +/// @note Guessing MSBF order. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendElectraAC(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { for (uint16_t r = 0; r <= repeat; r++) @@ -56,13 +50,17 @@ void IRsend::sendElectraAC(const uint8_t data[], const uint16_t nbytes, } #endif - +/// Class constructor. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRElectraAc::IRElectraAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the internal state to a fixed known good state. void IRElectraAc::stateReset(void) { for (uint8_t i = 1; i < kElectraAcStateLength - 2; i++) remote_state[i] = 0; remote_state[0] = 0xC3; @@ -70,54 +68,78 @@ void IRElectraAc::stateReset(void) { // [12] is the checksum. } +/// Set up hardware to be able to send a message. void IRElectraAc::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @param[in] length The length of the state array. +/// @return The calculated checksum stored in a uint_8. uint8_t IRElectraAc::calcChecksum(const uint8_t state[], - const uint16_t length) { + const uint16_t length) { if (length == 0) return state[0]; return sumBytes(state, length - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRElectraAc::validChecksum(const uint8_t state[], const uint16_t length) { if (length < 2) return true; // No checksum to compare with. Assume okay. return (state[length - 1] == calcChecksum(state, length)); } -// Update the checksum for the internal state. +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The length of the state array. void IRElectraAc::checksum(uint16_t length) { if (length < 2) return; remote_state[length - 1] = calcChecksum(remote_state, length); } #if SEND_ELECTRA_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRElectraAc::send(const uint16_t repeat) { - this->checksum(); - _irsend.sendElectraAC(remote_state, kElectraAcStateLength, repeat); + _irsend.sendElectraAC(getRaw(), kElectraAcStateLength, repeat); } #endif // SEND_ELECTRA_AC +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRElectraAc::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the code array. void IRElectraAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kElectraAcStateLength)); } +/// Change the power setting to On. void IRElectraAc::on(void) { this->setPower(true); } +/// Change the power setting to Off. void IRElectraAc::off(void) { this->setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setPower(const bool on) { setBit(&remote_state[9], kElectraAcPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getPower(void) { return GETBIT8(remote_state[9], kElectraAcPowerOffset); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRElectraAc::setMode(const uint8_t mode) { switch (mode) { case kElectraAcAuto: @@ -133,11 +155,15 @@ void IRElectraAc::setMode(const uint8_t mode) { } } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRElectraAc::getMode(void) { return GETBITS8(remote_state[6], kElectraAcModeOffset, kModeBitsSize); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRElectraAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kElectraAcCool; @@ -148,7 +174,9 @@ uint8_t IRElectraAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRElectraAc::toCommonMode(const uint8_t mode) { switch (mode) { case kElectraAcCool: return stdAc::opmode_t::kCool; @@ -159,20 +187,24 @@ stdAc::opmode_t IRElectraAc::toCommonMode(const uint8_t mode) { } } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRElectraAc::setTemp(const uint8_t temp) { uint8_t newtemp = std::max(kElectraAcMinTemp, temp); newtemp = std::min(kElectraAcMaxTemp, newtemp) - kElectraAcTempDelta; setBits(&remote_state[1], kElectraAcTempOffset, kElectraAcTempSize, newtemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRElectraAc::getTemp(void) { return GETBITS8(remote_state[1], kElectraAcTempOffset, kElectraAcTempSize) + kElectraAcTempDelta; } -// Set the speed of the fan, 0-3, 0 is auto, 1-3 is the speed +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @note 0 is auto, 1-3 is the speed void IRElectraAc::setFan(const uint8_t speed) { switch (speed) { case kElectraAcFanAuto: @@ -187,11 +219,15 @@ void IRElectraAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRElectraAc::getFan(void) { return GETBITS8(remote_state[4], kElectraAcFanOffset, kElectraAcFanSize); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRElectraAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -203,7 +239,9 @@ uint8_t IRElectraAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRElectraAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kElectraAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -213,51 +251,73 @@ stdAc::fanspeed_t IRElectraAc::toCommonFanSpeed(const uint8_t speed) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setSwingV(const bool on) { setBits(&remote_state[1], kElectraAcSwingVOffset, kElectraAcSwingSize, on ? kElectraAcSwingOn : kElectraAcSwingOff); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getSwingV(void) { return !GETBITS8(remote_state[1], kElectraAcSwingVOffset, kElectraAcSwingSize); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setSwingH(const bool on) { setBits(&remote_state[2], kElectraAcSwingHOffset, kElectraAcSwingSize, on ? kElectraAcSwingOn : kElectraAcSwingOff); } +/// Get the Horizontal Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getSwingH(void) { return !GETBITS8(remote_state[2], kElectraAcSwingHOffset, kElectraAcSwingSize); } +/// Set the Light (LED) Toggle mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setLightToggle(const bool on) { remote_state[11] = on ? kElectraAcLightToggleOn : kElectraAcLightToggleOff; } +/// Get the Light (LED) Toggle mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getLightToggle(void) { return (remote_state[11] & kElectraAcLightToggleMask) == kElectraAcLightToggleMask; } +/// Set the Clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setClean(const bool on) { setBit(&remote_state[9], kElectraAcCleanOffset, on); } +/// Get the Clean mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getClean(void) { return GETBIT8(remote_state[9], kElectraAcCleanOffset); } +/// Set the Turbo mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setTurbo(const bool on) { setBit(&remote_state[5], kElectraAcTurboOffset, on); } +/// Get the Turbo mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getTurbo(void) { return GETBIT8(remote_state[5], kElectraAcTurboOffset); } -// Convert the A/C state to it's common equivalent. + +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRElectraAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::ELECTRA_AC; @@ -284,7 +344,8 @@ stdAc::state_t IRElectraAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRElectraAc::toString(void) { String result = ""; result.reserve(130); // Reserve some heap for the string to reduce fragging. @@ -304,19 +365,15 @@ String IRElectraAc::toString(void) { } #if DECODE_ELECTRA_AC -// Decode the supplied Electra A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kElectraAcBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known working. -// +/// Decode the supplied Electra A/C message. +/// Status: STABLE / Known working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeElectraAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Electra.h b/lib/IRremoteESP8266-2.7.8/src/ir_Electra.h similarity index 85% rename from lib/IRremoteESP8266-2.7.7/src/ir_Electra.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Electra.h index 0f0e119f7..86f082a76 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Electra.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Electra.h @@ -1,6 +1,13 @@ -// Electra A/C -// // Copyright 2019 David Conran +/// @file +/// @brief Support for Electra A/C protocols. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp + +// Supports: +// Brand: AUX, Model: KFR-35GW/BpNFW=3 A/C +// Brand: AUX, Model: YKR-T/011 remote +// Brand: Electra, Model: Classic INV 17 / AXW12DCS A/C +// Brand: Electra, Model: YKR-M/003E remote #ifndef IR_ELECTRA_H_ #define IR_ELECTRA_H_ @@ -16,15 +23,6 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: AUX, Model: KFR-35GW/BpNFW=3 A/C -// Brand: AUX, Model: YKR-T/011 remote -// Brand: Electra, Model: Classic INV 17 / AXW12DCS A/C -// Brand: Electra, Model: YKR-M/003E remote - -// Ref: -// https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp - // Constants // state[1] // Temp 0b11111000 @@ -78,14 +76,18 @@ const uint8_t kElectraAcLightToggleOff = 0x08; // Classes +/// Class for handling detailed Electra A/C messages. class IRElectraAc { public: explicit IRElectraAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_ELECTRA_AC void send(const uint16_t repeat = kElectraAcMinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_ELECTRA_AC void begin(void); @@ -125,12 +127,13 @@ class IRElectraAc { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kElectraAcStateLength]; + uint8_t remote_state[kElectraAcStateLength]; ///< The state of the IR remote void checksum(const uint16_t length = kElectraAcStateLength); }; #endif // IR_ELECTRA_H_ diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Epson.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Epson.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.7/src/ir_Epson.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Epson.cpp index 40973a947..4f92704bc 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Epson.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Epson.cpp @@ -1,6 +1,11 @@ // Copyright 2020 David Conran +/// @file +/// @brief Support for Epson protocols. +/// Epson is an NEC-like protocol, except it doesn't use the NEC style repeat. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1034 -// Epson is an NEC-like protocol, except it doesn't use the NEC style repeat. +// Supports: +// Brand: Epson, Model: EN-TW9100W Projector #define __STDC_LIMIT_MACROS #include @@ -11,17 +16,11 @@ #include "ir_NEC.h" #if SEND_EPSON -// Send an Epson formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. Typically kEpsonBits. -// repeat: The number of times the command is to be repeated. -// -// Status: Beta / Probably works. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1034 +/// Send an Epson formatted message. +/// Status: Beta / Probably works. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of nbits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendEpson(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(kNecHdrMark, kNecHdrSpace, kNecBitMark, kNecOneSpace, kNecBitMark, kNecZeroSpace, kNecBitMark, kNecMinGap, kNecMinCommandLength, @@ -31,27 +30,18 @@ void IRsend::sendEpson(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_EPSON #if DECODE_EPSON -// Decode the supplied Epson message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kNECBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Beta / Probably works. -// -// Notes: -// Experimental data indicates there are at least three -// messages (first + 2 repeats). We only require the first + a single repeat -// to match. This helps us distinguish it from NEC messages which are near -// identical. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1034 +/// Decode the supplied Epson message. +/// Status: Beta / Probably works. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @note Experimental data indicates there are at least three messages +/// (first + 2 repeats). We only require the first + a single repeat to match. +/// This helps us distinguish it from NEC messages which are near identical. bool IRrecv::decodeEpson(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { const uint8_t kEpsonMinMesgsForDecode = 2; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.cpp similarity index 79% rename from lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.cpp index 583a441ba..a4bd90fa8 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.cpp @@ -1,5 +1,10 @@ // Copyright 2017 Jonny Graham // Copyright 2017-2019 David Conran + +/// @file +/// @brief Support for Fujitsu A/C protocols. +/// Fujitsu A/C support added by Jonny Graham & David Conran + #include "ir_Fujitsu.h" #include #ifndef ARDUINO @@ -9,16 +14,6 @@ #include "IRtext.h" #include "IRutils.h" -// Fujitsu A/C support added by Jonny Graham & David Conran - -// Equipment it seems compatible with: -// * Fujitsu ASYG30LFCA with remote AR-RAH2E -// * Fujitsu AST9RSGCW with remote AR-DB1 -// * Fujitsu ASYG7LMCA with remote AR-REB1E -// * Fujitsu AR-RAE1E remote. -// * Fujitsu General with remote AR-JW2 -// * - // Ref: // These values are based on averages of measurements const uint16_t kFujitsuAcHdrMark = 3324; @@ -39,20 +34,16 @@ using irutils::setBit; using irutils::setBits; #if SEND_FUJITSU_AC -// Send a Fujitsu A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. Typically one of: -// kFujitsuAcStateLength -// kFujitsuAcStateLength - 1 -// kFujitsuAcStateLengthShort -// kFujitsuAcStateLengthShort - 1 -// repeat: Nr. of times the message is to be repeated. -// (Default = kFujitsuAcMinRepeat). -// -// Status: STABLE / Known Good. -// +/// Send a Fujitsu A/C formatted message. +/// Status: STABLE / Known Good. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// Typically one of: +/// kFujitsuAcStateLength, +/// kFujitsuAcStateLength - 1, +/// kFujitsuAcStateLengthShort, +/// kFujitsuAcStateLengthShort - 1 +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendFujitsuAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { sendGeneric(kFujitsuAcHdrMark, kFujitsuAcHdrSpace, kFujitsuAcBitMark, @@ -64,7 +55,11 @@ void IRsend::sendFujitsuAC(const unsigned char data[], const uint16_t nbytes, // Code to emulate Fujitsu A/C IR remote control unit. -// Initialise the object. +/// Class Constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] model The enum for the model of A/C to be emulated. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRFujitsuAC::IRFujitsuAC(const uint16_t pin, const fujitsu_ac_remote_model_t model, const bool inverted, const bool use_modulation) @@ -73,6 +68,8 @@ IRFujitsuAC::IRFujitsuAC(const uint16_t pin, this->stateReset(); } +/// Set the currently emulated model of the A/C. +/// @param[in] model An enum representing the model to support/emulate. void IRFujitsuAC::setModel(const fujitsu_ac_remote_model_t model) { _model = model; switch (model) { @@ -90,9 +87,11 @@ void IRFujitsuAC::setModel(const fujitsu_ac_remote_model_t model) { } } +/// Get the currently emulated/detected model of the A/C. +/// @return The enum representing the model of A/C. fujitsu_ac_remote_model_t IRFujitsuAC::getModel(void) { return _model; } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRFujitsuAC::stateReset(void) { _temp = 24; _fanSpeed = kFujitsuAcFanHigh; @@ -104,17 +103,19 @@ void IRFujitsuAC::stateReset(void) { this->buildState(); } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRFujitsuAC::begin(void) { _irsend.begin(); } #if SEND_FUJITSU_AC -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRFujitsuAC::send(const uint16_t repeat) { this->buildState(); _irsend.sendFujitsuAC(remote_state, getStateLength(), repeat); } #endif // SEND_FUJITSU_AC +/// (Re)Build the state from the currently configured settings. void IRFujitsuAC::buildState(void) { remote_state[0] = 0x14; remote_state[1] = 0x63; @@ -208,6 +209,8 @@ void IRFujitsuAC::buildState(void) { } } +/// Get the length (size) of the state code for the current configuration. +/// @return The length of the state array required for this config. uint8_t IRFujitsuAC::getStateLength(void) { this->buildState(); // Force an update of the internal state. if (((_model == fujitsu_ac_remote_model_t::ARRAH2E || @@ -221,12 +224,15 @@ uint8_t IRFujitsuAC::getStateLength(void) { return _state_length; } -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRFujitsuAC::getRaw(void) { this->buildState(); return remote_state; } +/// Build the internal state/config from the current (raw) A/C message. +/// @param[in] length Size of the current/used (raw) A/C message array. void IRFujitsuAC::buildFromState(const uint16_t length) { switch (length) { case kFujitsuAcStateLength - 1: @@ -285,6 +291,10 @@ void IRFujitsuAC::buildFromState(const uint16_t length) { _outsideQuiet = this->getOutsideQuiet(true); } +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. +/// @param[in] length Size of the newState array. +/// @return true, if successful; Otherwise false. (i.e. size check) bool IRFujitsuAC::setRaw(const uint8_t newState[], const uint16_t length) { if (length > kFujitsuAcStateLength) return false; for (uint16_t i = 0; i < kFujitsuAcStateLength; i++) { @@ -297,8 +307,11 @@ bool IRFujitsuAC::setRaw(const uint8_t newState[], const uint16_t length) { return true; } +/// Request the A/C to step the Horizontal Swing. void IRFujitsuAC::stepHoriz(void) { this->setCmd(kFujitsuAcCmdStepHoriz); } +/// Request the A/C to toggle the Horizontal Swing mode. +/// @param[in] update Do we need to update the general swing config? void IRFujitsuAC::toggleSwingHoriz(const bool update) { // Toggle the current setting. if (update) this->setSwing(this->getSwing() ^ kFujitsuAcSwingHoriz); @@ -306,8 +319,11 @@ void IRFujitsuAC::toggleSwingHoriz(const bool update) { this->setCmd(kFujitsuAcCmdToggleSwingHoriz); } +/// Request the A/C to step the Vertical Swing. void IRFujitsuAC::stepVert(void) { this->setCmd(kFujitsuAcCmdStepVert); } +/// Request the A/C to toggle the Vertical Swing mode. +/// @param[in] update Do we need to update the general swing config? void IRFujitsuAC::toggleSwingVert(const bool update) { // Toggle the current setting. if (update) this->setSwing(this->getSwing() ^ kFujitsuAcSwingVert); @@ -315,7 +331,8 @@ void IRFujitsuAC::toggleSwingVert(const bool update) { this->setCmd(kFujitsuAcCmdToggleSwingVert); } -// Set the requested command of the A/C. +/// Set the requested (special) command part for the A/C message. +/// @param[in] cmd The special command code. void IRFujitsuAC::setCmd(const uint8_t cmd) { switch (cmd) { case kFujitsuAcCmdTurnOff: @@ -353,39 +370,40 @@ void IRFujitsuAC::setCmd(const uint8_t cmd) { } } -// Get the special command part of the message. -// Args: -// raw: Do we need to get it from first principles from the raw data? -// Returns: -// A uint8_t containing the contents of the special command byte. +/// Set the requested (special) command part for the A/C message. +/// @param[in] raw Do we need to get it from first principles from the raw data? +/// @return The special command code. uint8_t IRFujitsuAC::getCmd(const bool raw) { if (raw) return remote_state[5]; return _cmd; } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRFujitsuAC::setPower(const bool on) { this->setCmd(on ? kFujitsuAcCmdTurnOn : kFujitsuAcCmdTurnOff); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRFujitsuAC::off(void) { this->setPower(false); } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRFujitsuAC::on(void) { this->setPower(true); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRFujitsuAC::getPower(void) { return _cmd != kFujitsuAcCmdTurnOff; } +/// Set the Outside Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRFujitsuAC::setOutsideQuiet(const bool on) { _outsideQuiet = on; this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } -// Get the status of the Outside Quiet setting. -// Args: -// raw: Do we get the result from base data? -// Returns: -// A boolean for if it is set or not. +/// Get the Outside Quiet mode status of the A/C. +/// @param[in] raw Do we get the result from base data? +/// @return true, the setting is on. false, the setting is off. bool IRFujitsuAC::getOutsideQuiet(const bool raw) { if (_state_length == kFujitsuAcStateLength && raw) { _outsideQuiet = GETBIT8(remote_state[14], kFujitsuAcOutsideQuietOffset); @@ -395,16 +413,20 @@ bool IRFujitsuAC::getOutsideQuiet(const bool raw) { return _outsideQuiet; } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRFujitsuAC::setTemp(const uint8_t temp) { _temp = std::max((uint8_t)kFujitsuAcMinTemp, temp); _temp = std::min((uint8_t)kFujitsuAcMaxTemp, _temp); this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRFujitsuAC::getTemp(void) { return _temp; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] fanSpeed The desired setting. void IRFujitsuAC::setFanSpeed(const uint8_t fanSpeed) { if (fanSpeed > kFujitsuAcFanQuiet) _fanSpeed = kFujitsuAcFanHigh; // Set the fan to maximum if out of range. @@ -412,9 +434,13 @@ void IRFujitsuAC::setFanSpeed(const uint8_t fanSpeed) { _fanSpeed = fanSpeed; this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } + +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRFujitsuAC::getFanSpeed(void) { return _fanSpeed; } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRFujitsuAC::setMode(const uint8_t mode) { if (mode > kFujitsuAcModeHeat) _mode = kFujitsuAcModeHeat; // Set the mode to maximum if out of range. @@ -423,9 +449,14 @@ void IRFujitsuAC::setMode(const uint8_t mode) { this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRFujitsuAC::getMode(void) { return _mode; } -// Set the requested swing operation mode of the a/c unit. +/// Set the requested swing operation mode of the A/C unit. +/// @param[in] swingMode The swingMode code for the A/C. +/// Vertical, Horizon, or Both. See constants for details. +/// @note Not all models support all possible swing modes. void IRFujitsuAC::setSwing(const uint8_t swingMode) { _swingMode = swingMode; switch (_model) { @@ -446,22 +477,25 @@ void IRFujitsuAC::setSwing(const uint8_t swingMode) { this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } -// Get what the swing part of the message should be. -// Args: -// raw: Do we need to get it from first principles from the raw data? -// Returns: -// A uint8_t containing the contents of the swing state. +/// Get the requested swing operation mode of the A/C unit. +/// @param[in] raw Do we need to get it from first principles from the raw data? +/// @return The contents of the swing state/mode. uint8_t IRFujitsuAC::getSwing(const bool raw) { if (raw) _swingMode = GETBITS8(remote_state[10], kHighNibble, kFujitsuAcSwingSize); return _swingMode; } +/// Set the Clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRFujitsuAC::setClean(const bool on) { _clean = on; this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } +/// Get the Clean mode status of the A/C. +/// @param[in] raw Do we get the result from base data? +/// @return true, the setting is on. false, the setting is off. bool IRFujitsuAC::getClean(const bool raw) { if (raw) { return GETBIT8(remote_state[9], kFujitsuAcCleanOffset); @@ -473,11 +507,16 @@ bool IRFujitsuAC::getClean(const bool raw) { } } +/// Set the Filter mode status of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRFujitsuAC::setFilter(const bool on) { _filter = on; this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } +/// Get the Filter mode status of the A/C. +/// @param[in] raw Do we get the result from base data? +/// @return true, the setting is on. false, the setting is off. bool IRFujitsuAC::getFilter(const bool raw) { if (raw) { return GETBIT8(remote_state[14], kFujitsuAcFilterOffset); @@ -489,6 +528,10 @@ bool IRFujitsuAC::getFilter(const bool raw) { } } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRFujitsuAC::validChecksum(uint8_t state[], const uint16_t length) { uint8_t sum = 0; uint8_t sum_complement = 0; @@ -510,7 +553,9 @@ bool IRFujitsuAC::validChecksum(uint8_t state[], const uint16_t length) { return checksum == (uint8_t)(sum_complement - sum); // Does it match? } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRFujitsuAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kFujitsuAcModeCool; @@ -521,7 +566,9 @@ uint8_t IRFujitsuAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRFujitsuAC::convertFan(stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kFujitsuAcFanQuiet; @@ -533,7 +580,9 @@ uint8_t IRFujitsuAC::convertFan(stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRFujitsuAC::toCommonMode(const uint8_t mode) { switch (mode) { case kFujitsuAcModeCool: return stdAc::opmode_t::kCool; @@ -544,7 +593,9 @@ stdAc::opmode_t IRFujitsuAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRFujitsuAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kFujitsuAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -555,7 +606,8 @@ stdAc::fanspeed_t IRFujitsuAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRFujitsuAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::FUJITSU_AC; @@ -597,7 +649,8 @@ stdAc::state_t IRFujitsuAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRFujitsuAC::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -680,21 +733,15 @@ String IRFujitsuAC::toString(void) { } #if DECODE_FUJITSU_AC -// Decode a Fujitsu AC IR message if possible. -// Places successful decode information in the results pointer. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kFujitsuAcBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Ref: -// +/// Decode the supplied Fujitsu AC IR message if possible. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeFujitsuAC(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.h b/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.h similarity index 86% rename from lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.h index 17e791ac8..0c1069566 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Fujitsu.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.h @@ -1,13 +1,17 @@ // Copyright 2017 Jonny Graham // Copyright 2018-2019 David Conran +/// @file +/// @brief Support for Fujitsu A/C protocols. +/// Fujitsu A/C support added by Jonny Graham + // Supports: // Brand: Fujitsu, Model: AR-RAH2E remote -// Brand: Fujitsu, Model: ASYG30LFCA A/C +// Brand: Fujitsu, Model: ASYG30LFCA A/C (ARRAH2E) // Brand: Fujitsu, Model: AR-DB1 remote -// Brand: Fujitsu, Model: AST9RSGCW A/C +// Brand: Fujitsu, Model: AST9RSGCW A/C (ARDB1) // Brand: Fujitsu, Model: AR-REB1E remote -// Brand: Fujitsu, Model: ASYG7LMCA A/C +// Brand: Fujitsu, Model: ASYG7LMCA A/C (ARREB1E) // Brand: Fujitsu, Model: AR-RAE1E remote // Brand: Fujitsu, Model: AGTV14LAC A/C // Brand: Fujitsu, Model: AR-RAC1E remote @@ -32,7 +36,6 @@ #include "IRsend_test.h" #endif -// FUJITSU A/C support added by Jonny Graham // Constants const uint8_t kFujitsuAcModeAuto = 0x00; @@ -94,19 +97,22 @@ const uint8_t kFujitsuAcFilterOffset = 3; #define FUJITSU_AC_SWING_HORIZ kFujitsuAcSwingHoriz #define FUJITSU_AC_SWING_BOTH kFujitsuAcSwingBoth - +/// Class for handling detailed Fujitsu A/C messages. class IRFujitsuAC { public: explicit IRFujitsuAC(const uint16_t pin, const fujitsu_ac_remote_model_t model = ARRAH2E, const bool inverted = false, const bool use_modulation = true); - void setModel(const fujitsu_ac_remote_model_t model); fujitsu_ac_remote_model_t getModel(void); void stateReset(void); #if SEND_FUJITSU_AC void send(const uint16_t repeat = kFujitsuAcMinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_FUJITSU_AC void begin(void); @@ -149,11 +155,13 @@ class IRFujitsuAC { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif - uint8_t remote_state[kFujitsuAcStateLength]; + uint8_t remote_state[kFujitsuAcStateLength]; ///< The state of the IR remote. uint8_t _temp; uint8_t _fanSpeed; uint8_t _mode; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_GICable.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_GICable.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.7/src/ir_GICable.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_GICable.cpp index ef68199cb..7b29d71db 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_GICable.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_GICable.cpp @@ -1,5 +1,12 @@ // Copyright 2018 David Conran -// G.I. Cable + +/// @file +/// @brief G.I. Cable +/// @see https://github.com/cyborg5/IRLib2/blob/master/IRLibProtocols/IRLib_P09_GICable.h +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/447 + +// Supports: +// Brand: G.I. Cable, Model: XRC-200 remote #define __STDC_LIMIT_MACROS #include @@ -8,10 +15,6 @@ #include "IRsend.h" #include "IRutils.h" -// Ref: -// https://github.com/cyborg5/IRLib2/blob/master/IRLibProtocols/IRLib_P09_GICable.h -// https://github.com/crankyoldgit/IRremoteESP8266/issues/447 - // Constants const uint16_t kGicableHdrMark = 9000; const uint16_t kGicableHdrSpace = 4400; @@ -26,17 +29,11 @@ const uint32_t kGicableMinGap = kGicableBits * (kGicableBitMark + kGicableOneSpace) + kGicableBitMark); #if SEND_GICABLE -// Send a raw G.I. Cable formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kGicableBits. -// repeat: The number of times the command is to be repeated. -// -// Status: Alpha / Untested. -// -// Ref: +/// Send a raw G.I. Cable formatted message. +/// Status: Alpha / Untested. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendGICable(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(kGicableHdrMark, kGicableHdrSpace, kGicableBitMark, kGicableOneSpace, kGicableBitMark, kGicableZeroSpace, @@ -54,18 +51,15 @@ void IRsend::sendGICable(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_GICABLE #if DECODE_GICABLE -// Decode the supplied G.I. Cable message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kGicableBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Not tested against a real device. +/// Decode the supplied G.I. Cable message. +/// Status: Alpha / Not tested against a real device. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeGICable(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kGicableBits) diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_GlobalCache.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_GlobalCache.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.7/src/ir_GlobalCache.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_GlobalCache.cpp index 8c9646970..e8ebac4af 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_GlobalCache.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_GlobalCache.cpp @@ -1,8 +1,13 @@ // Copyright 2016 Hisham Khalifa // Copyright 2017 David Conran -// Global Cache IR format sender originally added by Hisham Khalifa -// (http://www.hishamkhalifa.com) +/// @file +/// @brief Global Cache IR format sender +/// Originally added by Hisham Khalifa (http://www.hishamkhalifa.com) +/// @see https://irdb.globalcache.com/Home/Database + +// Supports: +// Brand: Global Cache, Model: Control Tower IR DB #include #include "IRsend.h" @@ -16,23 +21,17 @@ const uint8_t kGlobalCacheRptStartIndex = kGlobalCacheRptIndex + 1; const uint8_t kGlobalCacheStartIndex = kGlobalCacheRptStartIndex + 1; #if SEND_GLOBALCACHE -// Send a shortened GlobalCache (GC) IRdb/control tower formatted message. -// -// Args: -// buf: An array of uint16_t containing the shortened GlobalCache data. -// len: Nr. of entries in the buf[] array. -// -// Status: STABLE / Known working. -// -// Note: -// Global Cache format without the emitter ID or request ID. -// Starts at the frequency (Hertz), followed by nr. of times to emit (count), -// then the offset for repeats (where a repeat will start from), -// then the rest of entries are the actual IR message as units of periodic -// time. -// e.g. sendir,1:1,1,38000,1,1,9,70,9,30,9,... -> 38000,1,1,9,70,9,30,9,... -// Ref: -// https://irdb.globalcache.com/Home/Database +/// Send a shortened GlobalCache (GC) IRdb/control tower formatted message. +/// Status: STABLE / Known working. +/// @param[in] buf Array of uint16_t containing the shortened GlobalCache data. +/// @param[in] len Nr. of entries in the buf[] array. +/// @note Global Cache format without the emitter ID or request ID. +/// Starts at the frequency (Hertz), followed by nr. of times to emit (count), +/// then the offset for repeats (where a repeat will start from), +/// then the rest of entries are the actual IR message as units of periodic +/// time. +/// e.g. sendir,1:1,1,38000,1,1,9,70,9,30,9,... -> 38000,1,1,9,70,9,30,9,... +/// @see https://irdb.globalcache.com/Home/Database void IRsend::sendGC(uint16_t buf[], uint16_t len) { uint16_t hz = buf[kGlobalCacheFreqIndex]; // GC frequency is in Hz. enableIROut(hz); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.cpp similarity index 74% rename from lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.cpp index 97a4a9277..290f90ad8 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.cpp @@ -1,10 +1,8 @@ // Copyright 2019 ribeirodanielf // Copyright 2019 David Conran -// -// Code to emulate Goodweather protocol compatible HVAC devices. -// Should be compatible with: -// * ZH/JT-03 remote control -// +/// @file +/// @brief Support for Goodweather compatible HVAC protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/697 #include "ir_Goodweather.h" #include @@ -27,17 +25,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_GOODWEATHER -// Send a Goodweather message. -// -// Args: -// data: The raw message to be sent. -// nbits: Nr. of bits of data in the message. (Default is kGoodweatherBits) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: BETA / Needs testing on real device. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/697 +/// Send a Goodweather HVAC formatted message. +/// Status: BETA / Needs testing on real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendGoodweather(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { if (nbits != kGoodweatherBits) @@ -67,38 +59,57 @@ void IRsend::sendGoodweather(const uint64_t data, const uint16_t nbits, } #endif // SEND_GOODWEATHER +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRGoodweatherAc::IRGoodweatherAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Reset the internal state to a fixed known good state. void IRGoodweatherAc::stateReset(void) { remote = kGoodweatherStateInit; } +/// Set up hardware to be able to send a message. void IRGoodweatherAc::begin(void) { _irsend.begin(); } #if SEND_GOODWEATHER +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRGoodweatherAc::send(const uint16_t repeat) { _irsend.sendGoodweather(remote, kGoodweatherBits, repeat); } #endif // SEND_GOODWEATHER +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. uint64_t IRGoodweatherAc::getRaw(void) { return remote; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. void IRGoodweatherAc::setRaw(const uint64_t state) { remote = state; } +/// Change the power setting to On. void IRGoodweatherAc::on(void) { this->setPower(true); } +/// Change the power setting to Off. void IRGoodweatherAc::off(void) { this->setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGoodweatherAc::setPower(const bool on) { this->setCommand(kGoodweatherCmdPower); setBit(&remote, kGoodweatherBitPower, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRGoodweatherAc::getPower(void) { return GETBIT64(remote, kGoodweatherBitPower); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRGoodweatherAc::setTemp(const uint8_t temp) { uint8_t new_temp = std::max(kGoodweatherTempMin, temp); new_temp = std::min(kGoodweatherTempMax, new_temp); @@ -108,13 +119,15 @@ void IRGoodweatherAc::setTemp(const uint8_t temp) { new_temp - kGoodweatherTempMin); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRGoodweatherAc::getTemp(void) { return GETBITS64(remote, kGoodweatherBitTemp, kGoodweatherTempSize) + kGoodweatherTempMin; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRGoodweatherAc::setFan(const uint8_t speed) { switch (speed) { case kGoodweatherFanAuto: @@ -129,10 +142,14 @@ void IRGoodweatherAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRGoodweatherAc::getFan() { return GETBITS64(remote, kGoodweatherBitFan, kGoodweatherFanSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRGoodweatherAc::setMode(const uint8_t mode) { switch (mode) { case kGoodweatherAuto: @@ -149,37 +166,53 @@ void IRGoodweatherAc::setMode(const uint8_t mode) { } } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRGoodweatherAc::getMode() { return GETBITS64(remote, kGoodweatherBitMode, kModeBitsSize); } +/// Set the Light (LED) Toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRGoodweatherAc::setLight(const bool toggle) { this->setCommand(kGoodweatherCmdLight); setBit(&remote, kGoodweatherBitLight, toggle); } -bool IRGoodweatherAc::getLight() { +/// Get the Light (LED) Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRGoodweatherAc::getLight(void) { return GETBIT64(remote, kGoodweatherBitLight); } +/// Set the Sleep Toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRGoodweatherAc::setSleep(const bool toggle) { this->setCommand(kGoodweatherCmdSleep); setBit(&remote, kGoodweatherBitSleep, toggle); } -bool IRGoodweatherAc::getSleep() { +/// Get the Sleep Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRGoodweatherAc::getSleep(void) { return GETBIT64(remote, kGoodweatherBitSleep); } +/// Set the Turbo Toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRGoodweatherAc::setTurbo(const bool toggle) { this->setCommand(kGoodweatherCmdTurbo); setBit(&remote, kGoodweatherBitTurbo, toggle); } -bool IRGoodweatherAc::getTurbo() { +/// Get the Turbo Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRGoodweatherAc::getTurbo(void) { return GETBIT64(remote, kGoodweatherBitTurbo); } +/// Set the Vertical Swing speed of the A/C. +/// @param[in] speed The speed to set the swing to. void IRGoodweatherAc::setSwing(const uint8_t speed) { switch (speed) { case kGoodweatherSwingOff: @@ -193,20 +226,28 @@ void IRGoodweatherAc::setSwing(const uint8_t speed) { } } +/// Get the Vertical Swing speed of the A/C. +/// @return The native swing speed setting. uint8_t IRGoodweatherAc::getSwing() { return GETBITS64(remote, kGoodweatherBitSwing, kGoodweatherSwingSize); } +/// Set the remote Command type/button pressed. +/// @param[in] cmd The command/button that was issued/pressed. void IRGoodweatherAc::setCommand(const uint8_t cmd) { if (cmd <= kGoodweatherCmdLight) setBits(&remote, kGoodweatherBitCommand, kGoodweatherCommandSize, cmd); } +/// Get the Command type/button pressed from the current settings +/// @return The command/button that was issued/pressed. uint8_t IRGoodweatherAc::getCommand() { return GETBITS64(remote, kGoodweatherBitCommand, kGoodweatherCommandSize); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGoodweatherAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kGoodweatherCool; @@ -217,7 +258,9 @@ uint8_t IRGoodweatherAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGoodweatherAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -229,7 +272,9 @@ uint8_t IRGoodweatherAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C Vertical Swing into its native version. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] swingv The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGoodweatherAc::convertSwingV(const stdAc::swingv_t swingv) { switch (swingv) { case stdAc::swingv_t::kHighest: @@ -242,7 +287,9 @@ uint8_t IRGoodweatherAc::convertSwingV(const stdAc::swingv_t swingv) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRGoodweatherAc::toCommonMode(const uint8_t mode) { switch (mode) { case kGoodweatherCool: return stdAc::opmode_t::kCool; @@ -253,7 +300,9 @@ stdAc::opmode_t IRGoodweatherAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRGoodweatherAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kGoodweatherFanHigh: return stdAc::fanspeed_t::kMax; @@ -263,7 +312,8 @@ stdAc::fanspeed_t IRGoodweatherAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRGoodweatherAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::GOODWEATHER; @@ -289,7 +339,8 @@ stdAc::state_t IRGoodweatherAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRGoodweatherAc::toString(void) { String result = ""; result.reserve(150); // Reserve some heap for the string to reduce fragging. @@ -366,18 +417,15 @@ String IRGoodweatherAc::toString(void) { } #if DECODE_GOODWEATHER -// Decode the supplied Goodweather message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kGoodweatherBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works. +/// Decode the supplied Goodweather message. +/// Status: BETA / Probably works. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeGoodweather(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.h b/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.h similarity index 85% rename from lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.h index 7e1d6115d..1fd5579cf 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Goodweather.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.h @@ -1,8 +1,10 @@ -// Goodweather A/C -// // Copyright 2019 ribeirodanielf // Copyright 2019 David Conran +/// @file +/// @brief Support for Goodweather compatible HVAC protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/697 + // Supports: // Brand: Goodweather, Model: ZH/JT-03 remote @@ -20,11 +22,8 @@ #include "IRsend_test.h" #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/697 // Constants - // Timing const uint16_t kGoodweatherBitMark = 580; const uint16_t kGoodweatherOneSpace = 580; @@ -87,14 +86,18 @@ const uint64_t kGoodweatherStateInit = 0xD50000000000; // Classes +/// Class for handling detailed Goodweather A/C messages. class IRGoodweatherAc { public: explicit IRGoodweatherAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_GOODWEATHER void send(const uint16_t repeat = kGoodweatherMinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_GOODWEATHER void begin(void); @@ -130,10 +133,12 @@ class IRGoodweatherAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint64_t remote; // The state of the IR remote in IR code form. + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint64_t remote; ///< The state of the IR remote in IR code form. }; #endif // IR_GOODWEATHER_H_ diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Gree.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Gree.cpp similarity index 72% rename from lib/IRremoteESP8266-2.7.7/src/ir_Gree.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Gree.cpp index 66eb3a2f0..d9ff269d5 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Gree.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Gree.cpp @@ -1,11 +1,9 @@ // Copyright 2017 Ville Skyttä (scop) // Copyright 2017, 2018 David Conran -// -// Code to emulate Gree protocol compatible HVAC devices. -// Should be compatible with: -// * Heat pumps carrying the "Ultimate" brand name. -// * EKOKAI air conditioners. -// + +/// @file +/// @brief Support for Gree A/C protocols. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.h #include "ir_Gree.h" #include @@ -21,9 +19,8 @@ #include "ir_Kelvinator.h" // Constants -// Ref: https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.h const uint16_t kGreeHdrMark = 9000; -const uint16_t kGreeHdrSpace = 4500; // See #684 and real example in unit tests +const uint16_t kGreeHdrSpace = 4500; ///< See #684 & real example in unit tests const uint16_t kGreeBitMark = 620; const uint16_t kGreeOneSpace = 1600; const uint16_t kGreeZeroSpace = 540; @@ -43,18 +40,12 @@ using irutils::setBit; using irutils::setBits; #if SEND_GREE -// Send a Gree Heat Pump message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kGreeStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Working. -// -// Ref: -// https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp -void IRsend::sendGree(const unsigned char data[], const uint16_t nbytes, +/// Send a Gree Heat Pump formatted message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +void IRsend::sendGree(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kGreeStateLength) return; // Not enough bytes to send a proper message. @@ -77,17 +68,11 @@ void IRsend::sendGree(const unsigned char data[], const uint16_t nbytes, } } -// Send a Gree Heat Pump message. -// -// Args: -// data: The raw message to be sent. -// nbits: Nr. of bits of data in the message. (Default is kGreeBits) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Working. -// -// Ref: -// https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp +/// Send a Gree Heat Pump formatted message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendGree(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { if (nbits != kGreeBits) @@ -119,6 +104,11 @@ void IRsend::sendGree(const uint64_t data, const uint16_t nbits, } #endif // SEND_GREE +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] model The enum of the model to be emulated. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRGreeAC::IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { @@ -126,6 +116,7 @@ IRGreeAC::IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model, setModel(model); } +/// Reset the internal state to a fixed known good state. void IRGreeAC::stateReset(void) { // This resets to a known-good state to Power Off, Fan Auto, Mode Auto, 25C. for (uint8_t i = 0; i < kGreeStateLength; i++) remote_state[i] = 0x0; @@ -136,25 +127,34 @@ void IRGreeAC::stateReset(void) { remote_state[7] = 0x50; } +/// Fix up the internal state so it is correct. +/// @note Internal use only. void IRGreeAC::fixup(void) { setPower(getPower()); // Redo the power bits as they differ between models. checksum(); // Calculate the checksums } +/// Set up hardware to be able to send a message. void IRGreeAC::begin(void) { _irsend.begin(); } #if SEND_GREE +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRGreeAC::send(const uint16_t repeat) { fixup(); // Ensure correct settings before sending. _irsend.sendGree(remote_state, kGreeStateLength, repeat); } #endif // SEND_GREE +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRGreeAC::getRaw(void) { fixup(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRGreeAC::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kGreeStateLength); // We can only detect the difference between models when the power is on. @@ -166,24 +166,26 @@ void IRGreeAC::setRaw(const uint8_t new_code[]) { } } +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The size/length of the state array to fix the checksum of. void IRGreeAC::checksum(const uint16_t length) { // Gree uses the same checksum alg. as Kelvinator's block checksum. setBits(&remote_state[length - 1], kHighNibble, kNibbleSize, IRKelvinatorAC::calcBlockChecksum(remote_state, length)); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRGreeAC::validChecksum(const uint8_t state[], const uint16_t length) { // Top 4 bits of the last byte in the state is the state's checksum. return GETBITS8(state[length - 1], kHighNibble, kNibbleSize) == IRKelvinatorAC::calcBlockChecksum(state, length); } +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRGreeAC::setModel(const gree_ac_remote_model_t model) { switch (model) { case gree_ac_remote_model_t::YAW1F: @@ -192,12 +194,19 @@ void IRGreeAC::setModel(const gree_ac_remote_model_t model) { } } +/// Get/Detect the model of the A/C. +/// @return The enum of the compatible model. gree_ac_remote_model_t IRGreeAC::getModel(void) { return _model; } +/// Change the power setting to On. void IRGreeAC::on(void) { setPower(true); } +/// Change the power setting to Off. void IRGreeAC::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/814 void IRGreeAC::setPower(const bool on) { setBit(&remote_state[0], kGreePower1Offset, on); // May not be needed. See #814 @@ -205,6 +214,9 @@ void IRGreeAC::setPower(const bool on) { on && _model != gree_ac_remote_model_t::YBOFB); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/814 bool IRGreeAC::getPower(void) { // See #814. Not checking/requiring: (remote_state[2] & kGreePower2Mask) return GETBIT8(remote_state[0], kGreePower1Offset); @@ -212,7 +224,7 @@ bool IRGreeAC::getPower(void) { /// Set the default temperature units to use. /// @param[in] on Use Fahrenheit as the units. -/// true is Fahrenheit, false is Celsius. +/// true is Fahrenheit, false is Celsius. void IRGreeAC::setUseFahrenheit(const bool on) { setBit(&remote_state[3], kGreeUseFahrenheitOffset, on); } @@ -226,9 +238,9 @@ bool IRGreeAC::getUseFahrenheit(void) { /// Set the temp. in degrees /// @param[in] temp Desired temperature in Degrees. /// @param[in] fahrenheit Use units of Fahrenheit and set that as units used. -/// false is Celsius (Default), true is Fahrenheit. +/// false is Celsius (Default), true is Fahrenheit. /// @note The unit actually works in Celsius with a special optional -/// "extra degree" when sing Fahrenheit. +/// "extra degree" when sending Fahrenheit. void IRGreeAC::setTemp(const uint8_t temp, const bool fahrenheit) { float safecelsius = temp; if (fahrenheit) @@ -252,21 +264,22 @@ void IRGreeAC::setTemp(const uint8_t temp, const bool fahrenheit) { (uint8_t)(safecelsius * 2) & 1); } -/// Return the set temperature +/// Get the set temperature /// @return The temperature in degrees in the current units (C/F) set. uint8_t IRGreeAC::getTemp(void) { uint8_t deg = kGreeMinTempC + GETBITS8(remote_state[1], kGreeTempOffset, kGreeTempSize); if (getUseFahrenheit()) { deg = celsiusToFahrenheit(deg); - // Retreive the "extra" fahrenheit from elsewhere in the code. + // Retrieve the "extra" fahrenheit from elsewhere in the code. if (GETBIT8(remote_state[3], kGreeTempExtraDegreeFOffset)) deg++; deg = std::max(deg, kGreeMinTempF); // Cover the fact that 61F is < 16C } return deg; } -// Set the speed of the fan, 0-3, 0 is auto, 1-3 is the speed +/// Set the speed of the fan. +/// @param[in] speed The desired setting. 0 is auto, 1-3 is the speed. void IRGreeAC::setFan(const uint8_t speed) { uint8_t fan = std::min((uint8_t)kGreeFanMax, speed); // Bounds check if (getMode() == kGreeDry) fan = 1; // DRY mode is always locked to fan 1. @@ -274,10 +287,14 @@ void IRGreeAC::setFan(const uint8_t speed) { setBits(&remote_state[0], kGreeFanOffset, kGreeFanSize, fan); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRGreeAC::getFan(void) { return GETBITS8(remote_state[0], kGreeFanOffset, kGreeFanSize); } +/// Set the operating mode of the A/C. +/// @param[in] new_mode The desired operating mode. void IRGreeAC::setMode(const uint8_t new_mode) { uint8_t mode = new_mode; switch (mode) { @@ -294,58 +311,87 @@ void IRGreeAC::setMode(const uint8_t new_mode) { setBits(&remote_state[0], kLowNibble, kModeBitsSize, mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRGreeAC::getMode(void) { return GETBITS8(remote_state[0], kLowNibble, kModeBitsSize); } +/// Set the Light (LED) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setLight(const bool on) { setBit(&remote_state[2], kGreeLightOffset, on); } +/// Get the Light (LED) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getLight(void) { return GETBIT8(remote_state[2], kGreeLightOffset); } +/// Set the IFeel setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setIFeel(const bool on) { setBit(&remote_state[5], kGreeIFeelOffset, on); } +/// Get the IFeel setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getIFeel(void) { return GETBIT8(remote_state[5], kGreeIFeelOffset); } +/// Set the Wifi (enabled) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setWiFi(const bool on) { setBit(&remote_state[5], kGreeWiFiOffset, on); } +/// Get the Wifi (enabled) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getWiFi(void) { return GETBIT8(remote_state[5], kGreeWiFiOffset); } +/// Set the XFan (Mould) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setXFan(const bool on) { setBit(&remote_state[2], kGreeXfanOffset, on); } +/// Get the XFan (Mould) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getXFan(void) { return GETBIT8(remote_state[2], kGreeXfanOffset); } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setSleep(const bool on) { setBit(&remote_state[0], kGreeSleepOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getSleep(void) { return GETBIT8(remote_state[0], kGreeSleepOffset); } +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setTurbo(const bool on) { setBit(&remote_state[2], kGreeTurboOffset, on); } +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getTurbo(void) { return GETBIT8(remote_state[2], kGreeTurboOffset); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] automatic Do we use the automatic setting? +/// @param[in] position The position/mode to set the vanes to. void IRGreeAC::setSwingVertical(const bool automatic, const uint8_t position) { setBit(&remote_state[0], kGreeSwingAutoOffset, automatic); uint8_t new_position = position; @@ -374,23 +420,32 @@ void IRGreeAC::setSwingVertical(const bool automatic, const uint8_t position) { setBits(&remote_state[4], kLowNibble, kGreeSwingSize, new_position); } +/// Get the Vertical Swing Automatic mode setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getSwingVerticalAuto(void) { return GETBIT8(remote_state[0], kGreeSwingAutoOffset); } +/// Get the Vertical Swing position setting of the A/C. +/// @return The native position/mode. uint8_t IRGreeAC::getSwingVerticalPosition(void) { return GETBITS8(remote_state[4], kLowNibble, kGreeSwingSize); } +/// Set the timer enable setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setTimerEnabled(const bool on) { setBit(&remote_state[1], kGreeTimerEnabledOffset, on); } +/// Get the timer enabled setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getTimerEnabled(void) { return GETBIT8(remote_state[1], kGreeTimerEnabledOffset); } -// Returns the number of minutes the timer is set for. +/// Get the timer time value from the A/C. +/// @return The number of minutes the timer is set for. uint16_t IRGreeAC::getTimer(void) { uint16_t hrs = irutils::bcdToUint8( (GETBITS8(remote_state[1], kGreeTimerTensHrOffset, @@ -399,12 +454,10 @@ uint16_t IRGreeAC::getTimer(void) { return hrs * 60 + (GETBIT8(remote_state[1], kGreeTimerHalfHrOffset) ? 30 : 0); } -// Set the A/C's timer to turn off in X many minutes. -// Stores time internally in 30 min units. -// e.g. 5 mins means 0 (& Off), 95 mins is 90 mins (& On). Max is 24 hours. -// -// Args: -// minutes: The number of minutes the timer should be set for. +/// Set the A/C's timer to turn off in X many minutes. +/// @param[in] minutes The number of minutes the timer should be set for. +/// @note Stores time internally in 30 min units. +/// e.g. 5 mins means 0 (& Off), 95 mins is 90 mins (& On). Max is 24 hours. void IRGreeAC::setTimer(const uint16_t minutes) { uint16_t mins = std::min(kGreeTimerMax, minutes); // Bounds check. setTimerEnabled(mins >= 30); // Timer is enabled when >= 30 mins. @@ -423,16 +476,17 @@ void IRGreeAC::setTimer(const uint16_t minutes) { /// i.e. Internal, External temperature sensing. /// @param[in] mode The desired temp source to display. /// @note In order for the A/C unit properly accept these settings. You must -/// cycle (send) in the following order: -/// kGreeDisplayTempOff(0) -> kGreeDisplayTempSet(1) -> -/// kGreeDisplayTempInside(2) ->kGreeDisplayTempOutside(3) -> -/// kGreeDisplayTempOff(0). -/// The unit will no behave correctly if the changes of this setting are sent -/// out of order. -/// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1118#issuecomment-628242152 +/// cycle (send) in the following order: +/// kGreeDisplayTempOff(0) -> kGreeDisplayTempSet(1) -> +/// kGreeDisplayTempInside(2) ->kGreeDisplayTempOutside(3) -> +/// kGreeDisplayTempOff(0). +/// The unit will no behave correctly if the changes of this setting are sent +/// out of order. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1118#issuecomment-628242152 void IRGreeAC::setDisplayTempSource(const uint8_t mode) { setBits(&remote_state[5], kGreeDisplayTempOffset, kGreeDisplayTempSize, mode); } + /// Get the temperature display mode. /// i.e. Internal, External temperature sensing. /// @return The current temp source being displayed. @@ -441,7 +495,9 @@ uint8_t IRGreeAC::getDisplayTempSource(void) { kGreeDisplayTempSize); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGreeAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kGreeCool; @@ -452,7 +508,9 @@ uint8_t IRGreeAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGreeAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kGreeFanMin; @@ -464,7 +522,9 @@ uint8_t IRGreeAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C Vertical Swing into its native version. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] swingv The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGreeAC::convertSwingV(const stdAc::swingv_t swingv) { switch (swingv) { case stdAc::swingv_t::kHighest: return kGreeSwingUp; @@ -476,7 +536,9 @@ uint8_t IRGreeAC::convertSwingV(const stdAc::swingv_t swingv) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRGreeAC::toCommonMode(const uint8_t mode) { switch (mode) { case kGreeCool: return stdAc::opmode_t::kCool; @@ -487,7 +549,9 @@ stdAc::opmode_t IRGreeAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRGreeAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kGreeFanMax: return stdAc::fanspeed_t::kMax; @@ -497,7 +561,9 @@ stdAc::fanspeed_t IRGreeAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] pos The enum to be converted. +/// @return The native equivilant of the enum. stdAc::swingv_t IRGreeAC::toCommonSwingV(const uint8_t pos) { switch (pos) { case kGreeSwingUp: return stdAc::swingv_t::kHighest; @@ -509,7 +575,8 @@ stdAc::swingv_t IRGreeAC::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRGreeAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::GREE; @@ -537,7 +604,8 @@ stdAc::state_t IRGreeAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRGreeAC::toString(void) { String result = ""; result.reserve(220); // Reserve some heap for the string to reduce fragging. @@ -593,18 +661,15 @@ String IRGreeAC::toString(void) { } #if DECODE_GREE -// Decode the supplied Gree message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kGreeBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. +/// Decode the supplied Gree HVAC message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeGree(decode_results* results, uint16_t offset, const uint16_t nbits, bool const strict) { if (results->rawlen <= diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Gree.h b/lib/IRremoteESP8266-2.7.8/src/ir_Gree.h similarity index 89% rename from lib/IRremoteESP8266-2.7.7/src/ir_Gree.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Gree.h index 4748c4769..8fb74aa7f 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Gree.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Gree.h @@ -1,6 +1,9 @@ // Copyright 2016 David Conran -// Gree A/C -// + +/// @file +/// @brief Support for Gree A/C protocols. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.h + // Supports: // Brand: Ultimate, Model: Heat Pump // Brand: EKOKAI, Model: A/C @@ -110,16 +113,20 @@ const uint8_t kGreeDisplayTempOutside = 0b11; // 3 #define GREE_SWING_UP_AUTO kGreeSwingUpAuto // Classes +/// Class for handling detailed Gree A/C messages. class IRGreeAC { public: explicit IRGreeAC( const uint16_t pin, const gree_ac_remote_model_t model = gree_ac_remote_model_t::YAW1F, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_GREE void send(const uint16_t repeat = kGreeDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_GREE void begin(void); @@ -171,12 +178,13 @@ class IRGreeAC { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else // UNIT_TEST - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif // UNIT_TEST - // The state of the IR remote in IR code form. - uint8_t remote_state[kGreeStateLength]; + uint8_t remote_state[kGreeStateLength]; ///< The state in native IR code form gree_ac_remote_model_t _model; void checksum(const uint16_t length = kGreeStateLength); void fixup(void); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Haier.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Haier.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.7/src/ir_Haier.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Haier.cpp index cac4320cf..5f2172696 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Haier.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Haier.cpp @@ -1,8 +1,13 @@ // Copyright 2018 crankyoldgit -// Code to emulate Haier protocol compatible devices. -// The specifics of reverse engineering the protocols details: -// * HSU07-HEA03 by kuzin2006. -// * YR-W02/HSU-09HMC203 by non7top. +/// @file +/// @brief Support for Haier A/C protocols. +/// The specifics of reverse engineering the protocols details: +/// * HSU07-HEA03 by kuzin2006. +/// * YR-W02/HSU-09HMC203 by non7top. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/404 +/// @see https://www.dropbox.com/s/mecyib3lhdxc8c6/IR%20data%20reverse%20engineering.xlsx?dl=0 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/485 +/// @see https://www.dropbox.com/sh/w0bt7egp0fjger5/AADRFV6Wg4wZskJVdFvzb8Z0a?dl=0&preview=haer2.ods #include "ir_Haier.h" #include @@ -13,17 +18,6 @@ #include "IRtext.h" #include "IRutils.h" -// Supported devices: -// * Haier HSU07-HEA03 Remote control. -// * Haier YR-W02 Remote control -// * Haier HSU-09HMC203 A/C unit. - -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/404 -// https://www.dropbox.com/s/mecyib3lhdxc8c6/IR%20data%20reverse%20engineering.xlsx?dl=0 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/485 -// https://www.dropbox.com/sh/w0bt7egp0fjger5/AADRFV6Wg4wZskJVdFvzb8Z0a?dl=0&preview=haer2.ods - // Constants const uint16_t kHaierAcHdr = 3000; const uint16_t kHaierAcHdrGap = 4300; @@ -43,15 +37,11 @@ using irutils::setBit; using irutils::setBits; #if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02) -// Send a Haier A/C message. (HSU07-HEA03 remote) -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHaierACStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Known to be working. -// +/// Send a Haier A/C formatted message. (HSU07-HEA03 remote) +/// Status: STABLE / Known to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendHaierAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kHaierACStateLength) return; @@ -70,43 +60,51 @@ void IRsend::sendHaierAC(const unsigned char data[], const uint16_t nbytes, #endif // (SEND_HAIER_AC || SEND_HAIER_AC_YRW02) #if SEND_HAIER_AC_YRW02 -// Send a Haier YR-W02 remote A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHaierACYRW02StateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: Alpha / Untested on a real device. -// +/// Send a Haier YR-W02 remote A/C formatted message. +/// Status: Alpha / Untested on a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendHaierACYRW02(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes >= kHaierACYRW02StateLength) sendHaierAC(data, nbytes, repeat); } #endif // SEND_HAIER_AC_YRW02 -// Class for emulating a Haier HSU07-HEA03 remote +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRHaierAC::IRHaierAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRHaierAC::begin(void) { _irsend.begin(); } #if SEND_HAIER_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHaierAC::send(const uint16_t repeat) { _irsend.sendHaierAC(getRaw(), kHaierACStateLength, repeat); } #endif // SEND_HAIER_AC +/// Calculate and set the checksum values for the internal state. void IRHaierAC::checksum(void) { remote_state[8] = sumBytes(remote_state, kHaierACStateLength - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRHaierAC::validChecksum(uint8_t state[], const uint16_t length) { if (length < 2) return false; // 1 byte of data can't have a checksum. return (state[length - 1] == sumBytes(state, length - 1)); } +/// Reset the internal state to a fixed known good state. void IRHaierAC::stateReset(void) { for (uint8_t i = 1; i < kHaierACStateLength; i++) remote_state[i] = 0x0; remote_state[0] = kHaierAcPrefix; @@ -120,15 +118,21 @@ void IRHaierAC::stateReset(void) { setCommand(kHaierAcCmdOn); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRHaierAC::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRHaierAC::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kHaierACStateLength); } +/// Set the Command/Button setting of the A/C. +/// @param[in] command The value of the command/button that was pressed. void IRHaierAC::setCommand(const uint8_t command) { switch (command) { case kHaierAcCmdOff: @@ -146,10 +150,14 @@ void IRHaierAC::setCommand(const uint8_t command) { } } +/// Get the Command/Button setting of the A/C. +/// @return The value of the command/button that was pressed. uint8_t IRHaierAC::getCommand(void) { return GETBITS8(remote_state[1], kLowNibble, kNibbleSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRHaierAC::setFan(const uint8_t speed) { uint8_t new_speed = kHaierAcFanAuto; switch (speed) { @@ -164,6 +172,8 @@ void IRHaierAC::setFan(const uint8_t speed) { setBits(&remote_state[5], kLowNibble, kHaierAcSwingSize, new_speed); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHaierAC::getFan(void) { switch (GETBITS8(remote_state[5], kLowNibble, kHaierAcSwingSize)) { case 1: return kHaierAcFanMed; @@ -173,6 +183,8 @@ uint8_t IRHaierAC::getFan(void) { } } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHaierAC::setMode(uint8_t mode) { uint8_t new_mode = mode; setCommand(kHaierAcCmdMode); @@ -181,10 +193,14 @@ void IRHaierAC::setMode(uint8_t mode) { setBits(&remote_state[6], kHaierAcModeOffset, kModeBitsSize, new_mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHaierAC::getMode(void) { return GETBITS8(remote_state[6], kHaierAcModeOffset, kModeBitsSize); } +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRHaierAC::setTemp(const uint8_t degrees) { uint8_t temp = degrees; if (temp < kHaierAcMinTemp) @@ -201,33 +217,47 @@ void IRHaierAC::setTemp(const uint8_t degrees) { setBits(&remote_state[1], kHighNibble, kNibbleSize, temp - kHaierAcMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHaierAC::getTemp(void) { return GETBITS8(remote_state[1], kHighNibble, kNibbleSize) + kHaierAcMinTemp; } +/// Set the Health (filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierAC::setHealth(const bool on) { setCommand(kHaierAcCmdHealth); setBit(&remote_state[4], kHaierAcHealthBitOffset, on); } +/// Get the Health (filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHaierAC::getHealth(void) { return GETBIT8(remote_state[4], kHaierAcHealthBitOffset); } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierAC::setSleep(const bool on) { setCommand(kHaierAcCmdSleep); setBit(&remote_state[7], kHaierAcSleepBitOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHaierAC::getSleep(void) { return GETBIT8(remote_state[7], kHaierAcSleepBitOffset); } +/// Get the Time value at the given pointer. +/// @param[in] ptr A Ptr to a location in the internal state to get the time. uint16_t IRHaierAC::getTime(const uint8_t ptr[]) { return GETBITS8(ptr[0], kHaierAcTimeOffset, kHaierAcHoursSize) * 60 + GETBITS8(ptr[1], kHaierAcTimeOffset, kHaierAcMinsSize); } +/// Get the On Timer value/setting of the A/C. +/// @return Nr of minutes the timer is set to. -1 is Off/not set etc. int16_t IRHaierAC::getOnTimer(void) { // Check if the timer is turned on. if (GETBIT8(remote_state[3], kHaierAcOnTimerOffset)) @@ -236,6 +266,8 @@ int16_t IRHaierAC::getOnTimer(void) { return -1; } +/// Get the Off Timer value/setting of the A/C. +/// @return Nr of minutes the timer is set to. -1 is Off/not set etc. int16_t IRHaierAC::getOffTimer(void) { // Check if the timer is turned on. if (GETBIT8(remote_state[3], kHaierAcOffTimerOffset)) @@ -244,8 +276,13 @@ int16_t IRHaierAC::getOffTimer(void) { return -1; } +/// Get the clock value of the A/C. +/// @return The clock time, in Nr of minutes past midnight. uint16_t IRHaierAC::getCurrTime(void) { return getTime(remote_state + 2); } +/// Set the Time value at the given pointer. +/// @param[out] ptr A Ptr to a location in the internal state to set the time. +/// @param[in] nr_mins The time expressed in total number of minutes. void IRHaierAC::setTime(uint8_t ptr[], const uint16_t nr_mins) { uint16_t mins = nr_mins; if (nr_mins > kHaierAcMaxTime) mins = kHaierAcMaxTime; @@ -253,31 +290,42 @@ void IRHaierAC::setTime(uint8_t ptr[], const uint16_t nr_mins) { setBits(ptr + 1, kHaierAcTimeOffset, kHaierAcMinsSize, mins % 60); // Minutes } +/// Set & enable the On Timer. +/// @param[in] nr_mins The time expressed in total number of minutes. void IRHaierAC::setOnTimer(const uint16_t nr_mins) { setCommand(kHaierAcCmdTimerSet); setBit(&remote_state[3], kHaierAcOnTimerOffset); setTime(remote_state + 6, nr_mins); } +/// Set & enable the Off Timer. +/// @param[in] nr_mins The time expressed in total number of minutes. void IRHaierAC::setOffTimer(const uint16_t nr_mins) { setCommand(kHaierAcCmdTimerSet); setBit(&remote_state[3], kHaierAcOffTimerOffset); setTime(remote_state + 4, nr_mins); } +/// Cancel/disable the On & Off timers. void IRHaierAC::cancelTimers(void) { setCommand(kHaierAcCmdTimerCancel); setBits(&remote_state[3], kHaierAcOffTimerOffset, 2, 0); } +/// Set the clock value for the A/C. +/// @param[in] nr_mins The clock time, in Nr of minutes past midnight. void IRHaierAC::setCurrTime(const uint16_t nr_mins) { setTime(remote_state + 2, nr_mins); } +/// Get the Vertical Swing position setting of the A/C. +/// @return The native swing mode. uint8_t IRHaierAC::getSwing(void) { return GETBITS8(remote_state[2], kHaierAcSwingOffset, kHaierAcSwingSize); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] cmd The mode to set the vanes to. void IRHaierAC::setSwing(const uint8_t cmd) { if (cmd == getSwing()) return; // Nothing to do. switch (cmd) { @@ -291,7 +339,9 @@ void IRHaierAC::setSwing(const uint8_t cmd) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHaierAcCool; @@ -302,7 +352,9 @@ uint8_t IRHaierAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -314,7 +366,9 @@ uint8_t IRHaierAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierAC::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -327,7 +381,9 @@ uint8_t IRHaierAC::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHaierAC::toCommonMode(const uint8_t mode) { switch (mode) { case kHaierAcCool: return stdAc::opmode_t::kCool; @@ -338,7 +394,9 @@ stdAc::opmode_t IRHaierAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHaierAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHaierAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -348,7 +406,9 @@ stdAc::fanspeed_t IRHaierAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] pos The enum to be converted. +/// @return The native equivilant of the enum. stdAc::swingv_t IRHaierAC::toCommonSwingV(const uint8_t pos) { switch (pos) { case kHaierAcSwingUp: return stdAc::swingv_t::kHighest; @@ -358,7 +418,8 @@ stdAc::swingv_t IRHaierAC::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHaierAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HAIER_AC; @@ -384,7 +445,8 @@ stdAc::state_t IRHaierAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRHaierAC::toString(void) { String result = ""; result.reserve(150); // Reserve some heap for the string to reduce fragging. @@ -469,29 +531,41 @@ String IRHaierAC::toString(void) { } // End of IRHaierAC class. -// Class for emulating a Haier YRW02 remote +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRHaierACYRW02::IRHaierACYRW02(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRHaierACYRW02::begin(void) { _irsend.begin(); } #if SEND_HAIER_AC_YRW02 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHaierACYRW02::send(const uint16_t repeat) { _irsend.sendHaierACYRW02(getRaw(), kHaierACYRW02StateLength, repeat); } #endif // SEND_HAIER_AC_YRW02 +/// Calculate and set the checksum values for the internal state. void IRHaierACYRW02::checksum(void) { remote_state[kHaierACYRW02StateLength - 1] = sumBytes(remote_state, kHaierACYRW02StateLength - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRHaierACYRW02::validChecksum(uint8_t state[], const uint16_t length) { if (length < 2) return false; // 1 byte of data can't have a checksum. return (state[length - 1] == sumBytes(state, length - 1)); } +/// Reset the internal state to a fixed known good state. void IRHaierACYRW02::stateReset(void) { for (uint8_t i = 1; i < kHaierACYRW02StateLength; i++) remote_state[i] = 0x0; remote_state[0] = kHaierAcYrw02Prefix; @@ -506,15 +580,21 @@ void IRHaierACYRW02::stateReset(void) { setPower(true); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRHaierACYRW02::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRHaierACYRW02::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kHaierACYRW02StateLength); } +/// Set the Button/Command setting of the A/C. +/// @param[in] button The value of the button/command that was pressed. void IRHaierACYRW02::setButton(uint8_t button) { switch (button) { case kHaierAcYrw02ButtonTempUp: @@ -530,10 +610,14 @@ void IRHaierACYRW02::setButton(uint8_t button) { } } +/// Get the Button/Command setting of the A/C. +/// @return The value of the button/command that was pressed. uint8_t IRHaierACYRW02::getButton(void) { return GETBITS8(remote_state[12], kLowNibble, kNibbleSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHaierACYRW02::setMode(uint8_t mode) { uint8_t new_mode = mode; setButton(kHaierAcYrw02ButtonMode); @@ -548,10 +632,14 @@ void IRHaierACYRW02::setMode(uint8_t mode) { setBits(&remote_state[7], kHaierAcYrw02ModeOffset, kModeBitsSize, new_mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHaierACYRW02::getMode(void) { return GETBITS8(remote_state[7], kHaierAcYrw02ModeOffset, kModeBitsSize); } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. void IRHaierACYRW02::setTemp(const uint8_t celsius) { uint8_t temp = celsius; if (temp < kHaierAcMinTemp) @@ -568,46 +656,68 @@ void IRHaierACYRW02::setTemp(const uint8_t celsius) { setBits(&remote_state[1], kHighNibble, kNibbleSize, temp - kHaierAcMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHaierACYRW02::getTemp(void) { return GETBITS8(remote_state[1], kHighNibble, kNibbleSize) + kHaierAcMinTemp; } +/// Set the Health (filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierACYRW02::setHealth(const bool on) { setButton(kHaierAcYrw02ButtonHealth); setBit(&remote_state[3], kHaierAcYrw02HealthOffset, on); } +/// Get the Health (filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHaierACYRW02::getHealth(void) { return GETBIT8(remote_state[3], kHaierAcYrw02HealthOffset); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRHaierACYRW02::getPower(void) { return GETBIT8(remote_state[4], kHaierAcYrw02PowerOffset); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierACYRW02::setPower(const bool on) { setButton(kHaierAcYrw02ButtonPower); setBit(&remote_state[4], kHaierAcYrw02PowerOffset, on); } +/// Change the power setting to On. void IRHaierACYRW02::on(void) { setPower(true); } +/// Change the power setting to Off. void IRHaierACYRW02::off(void) { setPower(false); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHaierACYRW02::getSleep(void) { return GETBIT8(remote_state[8], kHaierAcYrw02SleepOffset); } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierACYRW02::setSleep(const bool on) { setButton(kHaierAcYrw02ButtonSleep); setBit(&remote_state[8], kHaierAcYrw02SleepOffset, on); } +/// Get the Turbo setting of the A/C. +/// @return The current turbo speed setting. uint8_t IRHaierACYRW02::getTurbo(void) { return GETBITS8(remote_state[6], kHaierAcYrw02TurboOffset, kHaierAcYrw02TurboSize); } +/// Set the Turbo setting of the A/C. +/// @param[in] speed The desired turbo speed setting. +/// @note Valid speeds are kHaierAcYrw02TurboOff, kHaierAcYrw02TurboLow, & +/// kHaierAcYrw02TurboHigh. void IRHaierACYRW02::setTurbo(uint8_t speed) { switch (speed) { case kHaierAcYrw02TurboOff: @@ -619,11 +729,15 @@ void IRHaierACYRW02::setTurbo(uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHaierACYRW02::getFan(void) { return GETBITS8(remote_state[5], kHaierAcYrw02FanOffset, kHaierAcYrw02FanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRHaierACYRW02::setFan(uint8_t speed) { switch (speed) { case kHaierAcYrw02FanLow: @@ -636,10 +750,14 @@ void IRHaierACYRW02::setFan(uint8_t speed) { } } +/// Get the Vertical Swing position setting of the A/C. +/// @return The native position/mode. uint8_t IRHaierACYRW02::getSwing(void) { return GETBITS8(remote_state[1], kLowNibble, kNibbleSize); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] pos The position/mode to set the vanes to. void IRHaierACYRW02::setSwing(uint8_t pos) { uint8_t newpos = pos; switch (pos) { @@ -660,7 +778,9 @@ void IRHaierACYRW02::setSwing(uint8_t pos) { setBits(&remote_state[1], kLowNibble, kNibbleSize, newpos); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierACYRW02::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHaierAcYrw02Cool; @@ -671,7 +791,9 @@ uint8_t IRHaierACYRW02::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierACYRW02::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -683,7 +805,9 @@ uint8_t IRHaierACYRW02::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierACYRW02::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -696,7 +820,9 @@ uint8_t IRHaierACYRW02::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHaierACYRW02::toCommonMode(const uint8_t mode) { switch (mode) { case kHaierAcYrw02Cool: return stdAc::opmode_t::kCool; @@ -707,7 +833,9 @@ stdAc::opmode_t IRHaierACYRW02::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHaierACYRW02::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHaierAcYrw02FanHigh: return stdAc::fanspeed_t::kMax; @@ -717,7 +845,9 @@ stdAc::fanspeed_t IRHaierACYRW02::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] pos The enum to be converted. +/// @return The native equivilant of the enum. stdAc::swingv_t IRHaierACYRW02::toCommonSwingV(const uint8_t pos) { switch (pos) { case kHaierAcYrw02SwingTop: return stdAc::swingv_t::kHighest; @@ -729,7 +859,8 @@ stdAc::swingv_t IRHaierACYRW02::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHaierACYRW02::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HAIER_AC_YRW02; @@ -754,7 +885,8 @@ stdAc::state_t IRHaierACYRW02::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRHaierACYRW02::toString(void) { String result = ""; result.reserve(130); // Reserve some heap for the string to reduce fragging. @@ -849,19 +981,15 @@ String IRHaierACYRW02::toString(void) { // End of IRHaierACYRW02 class. #if (DECODE_HAIER_AC || DECODE_HAIER_AC_YRW02) -// Decode the supplied Haier HSU07-HEA03 remote message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kHaierACBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known to be working. -// +/// Decode the supplied Haier HSU07-HEA03 remote message. +/// Status: STABLE / Known to be working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeHaierAC(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict) { @@ -899,19 +1027,15 @@ bool IRrecv::decodeHaierAC(decode_results* results, uint16_t offset, #endif // (DECODE_HAIER_AC || DECODE_HAIER_AC_YRW02) #if DECODE_HAIER_AC_YRW02 -// Decode the supplied Haier YR-W02 remote A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kHaierACYRW02Bits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Appears to be working. -// +/// Decode the supplied Haier YR-W02 remote A/C message. +/// Status: BETA / Appears to be working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeHaierACYRW02(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict) { diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Haier.h b/lib/IRremoteESP8266-2.7.8/src/ir_Haier.h similarity index 83% rename from lib/IRremoteESP8266-2.7.7/src/ir_Haier.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Haier.h index 92eb3b05c..e1dd84e15 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Haier.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Haier.h @@ -1,10 +1,18 @@ // Copyright 2018 crankyoldgit -// The specifics of reverse engineering the protocol details by kuzin2006 +/// @file +/// @brief Support for Haier A/C protocols. +/// The specifics of reverse engineering the protocols details: +/// * HSU07-HEA03 by kuzin2006. +/// * YR-W02/HSU-09HMC203 by non7top. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/404 +/// @see https://www.dropbox.com/s/mecyib3lhdxc8c6/IR%20data%20reverse%20engineering.xlsx?dl=0 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/485 +/// @see https://www.dropbox.com/sh/w0bt7egp0fjger5/AADRFV6Wg4wZskJVdFvzb8Z0a?dl=0&preview=haer2.ods // Supports: -// Brand: Haier, Model: HSU07-HEA03 remote -// Brand: Haier, Model: YR-W02 remote -// Brand: Haier, Model: HSU-09HMC203 A/C +// Brand: Haier, Model: HSU07-HEA03 remote (HAIER_AC) +// Brand: Haier, Model: YR-W02 remote (HAIER_AC_YRW02) +// Brand: Haier, Model: HSU-09HMC203 A/C (HAIER_AC_YRW02) #ifndef IR_HAIER_H_ #define IR_HAIER_H_ @@ -18,12 +26,6 @@ #include "IRsend_test.h" #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/404 -// https://www.dropbox.com/s/mecyib3lhdxc8c6/IR%20data%20reverse%20engineering.xlsx?dl=0 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/485 -// https://www.dropbox.com/sh/w0bt7egp0fjger5/AADRFV6Wg4wZskJVdFvzb8Z0a?dl=0&preview=haer2.ods - // Constants // Haier HSU07-HEA03 remote @@ -210,13 +212,18 @@ const uint8_t kHaierAcYrw02ButtonSleep = 0xB; #define HAIER_AC_YRW02_BUTTON_TURBO kHaierAcYrw02ButtonTurbo #define HAIER_AC_YRW02_BUTTON_SLEEP kHaierAcYrw02ButtonSleep +// Classes +/// Class for handling detailed Haier A/C messages. class IRHaierAC { public: explicit IRHaierAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - #if SEND_HAIER_AC void send(const uint16_t repeat = kHaierAcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HAIER_AC void begin(void); @@ -265,24 +272,31 @@ class IRHaierAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif - uint8_t remote_state[kHaierACStateLength]; + uint8_t remote_state[kHaierACStateLength]; ///< The state in native code form void stateReset(void); void checksum(void); static uint16_t getTime(const uint8_t ptr[]); static void setTime(uint8_t ptr[], const uint16_t nr_mins); }; +/// Class for handling detailed Haier ACYRW02 A/C messages. class IRHaierACYRW02 { public: explicit IRHaierACYRW02(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - #if SEND_HAIER_AC_YRW02 void send(const uint16_t repeat = kHaierAcYrw02DefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HAIER_AC_YRW02 void begin(void); @@ -312,7 +326,7 @@ class IRHaierACYRW02 { void setTurbo(const uint8_t speed); uint8_t getSwing(void); - void setSwing(const uint8_t state); + void setSwing(const uint8_t pos); uint8_t* getRaw(void); void setRaw(const uint8_t new_code[]); @@ -329,13 +343,14 @@ class IRHaierACYRW02 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kHaierACYRW02StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHaierACYRW02StateLength]; ///< The state in native form void stateReset(void); void checksum(void); }; - #endif // IR_HAIER_H_ diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp similarity index 60% rename from lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp index 01cc49d28..368f9995a 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp @@ -1,9 +1,12 @@ // Copyright 2018-2019 David Conran -// -// Code to emulate Hitachi protocol compatible devices. -// Should be compatible with: -// * Hitachi RAS-35THA6 remote -// +/// @file +/// @brief Support for Hitachi A/C protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/973 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 #include "ir_Hitachi.h" #include @@ -18,7 +21,6 @@ #include "IRutils.h" // Constants -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/417 const uint16_t kHitachiAcHdrMark = 3300; const uint16_t kHitachiAcHdrSpace = 1700; const uint16_t kHitachiAc1HdrMark = 3400; @@ -28,7 +30,6 @@ const uint16_t kHitachiAcOneSpace = 1250; const uint16_t kHitachiAcZeroSpace = 500; const uint32_t kHitachiAcMinGap = kDefaultMessageGap; // Just a guess. // Support for HitachiAc424 protocol -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/973 const uint16_t kHitachiAc424LdrMark = 29784; // Leader const uint16_t kHitachiAc424LdrSpace = 49290; // Leader const uint16_t kHitachiAc424HdrMark = 3416; // Header @@ -38,7 +39,6 @@ const uint16_t kHitachiAc424OneSpace = 1208; const uint16_t kHitachiAc424ZeroSpace = 372; // Support for HitachiAc3 protocol -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 const uint16_t kHitachiAc3HdrMark = 3400; // Header const uint16_t kHitachiAc3HdrSpace = 1660; // Header const uint16_t kHitachiAc3BitMark = 460; @@ -56,45 +56,34 @@ using irutils::minsToString; using irutils::setBit; using irutils::setBits; -#if (SEND_HITACHI_AC || SEND_HITACHI_AC2) -// Send a Hitachi A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHitachiAcStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/417 +#if (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC344) +/// Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 void IRsend::sendHitachiAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kHitachiAcStateLength) return; // Not enough bytes to send a proper message. + + const bool MSBfirst = (nbytes == kHitachiAc344StateLength) ? false : true; sendGeneric(kHitachiAcHdrMark, kHitachiAcHdrSpace, kHitachiAcBitMark, kHitachiAcOneSpace, kHitachiAcBitMark, kHitachiAcZeroSpace, - kHitachiAcBitMark, kHitachiAcMinGap, data, nbytes, 38, true, + kHitachiAcBitMark, kHitachiAcMinGap, data, nbytes, 38, MSBfirst, repeat, 50); } -#endif // (SEND_HITACHI_AC || SEND_HITACHI_AC2) +#endif // (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC344) #if SEND_HITACHI_AC1 -// Send a Hitachi A/C 13-byte message. -// -// For devices: -// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc1StateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Confirmed Working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/453 -// Basically the same as sendHitatchiAC() except different size and header. +/// Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) +/// Status: STABLE / Confirmed Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note Basically the same as sendHitatchiAC() except different size & header. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kHitachiAc1StateLength) @@ -107,21 +96,12 @@ void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes, #endif // SEND_HITACHI_AC1 #if SEND_HITACHI_AC2 -// Send a Hitachi A/C 53-byte message. -// -// For devices: -// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc2StateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Expected to work. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/417 -// Basically the same as sendHitatchiAC() except different size. +/// Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) +/// Basically the same as sendHitatchiAC() except different size. +/// Status: STABLE / Expected to work. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendHitachiAC2(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kHitachiAc2StateLength) @@ -130,14 +110,31 @@ void IRsend::sendHitachiAC2(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_HITACHI_AC2 -// Class for handling the remote control on a Hitachi 28 byte A/C message. -// Inspired by: -// https://github.com/ToniA/arduino-heatpumpir/blob/master/HitachiHeatpumpIR.cpp +#if SEND_HITACHI_AC344 +/// Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) +/// Basically the same as sendHitatchiAC() except different size. +/// Status: Beta / Probably works. +/// @param[in] data An array of bytes containing the IR command. +/// @param[in] nbytes Nr. of bytes of data in the array. +/// @param[in] repeat Nr. of times the message is to be repeated. (Default = 0). +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 +void IRsend::sendHitachiAc344(const unsigned char data[], const uint16_t nbytes, + const uint16_t repeat) { + if (nbytes < kHitachiAc344StateLength) + return; // Not enough bytes to send a proper message. + sendHitachiAC(data, nbytes, repeat); +} +#endif // SEND_HITACHI_AC344 +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRHitachiAc::IRHitachiAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Reset the internal state to a fixed known good state. void IRHitachiAc::stateReset(void) { remote_state[0] = 0x80; remote_state[1] = 0x08; @@ -156,8 +153,13 @@ void IRHitachiAc::stateReset(void) { setTemp(23); } +/// Set up hardware to be able to send a message. void IRHitachiAc::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @param[in] length The size/length of the state. +/// @return The calculated checksum value. uint8_t IRHitachiAc::calcChecksum(const uint8_t state[], const uint16_t length) { uint8_t sum = 62; @@ -165,44 +167,67 @@ uint8_t IRHitachiAc::calcChecksum(const uint8_t state[], return reverseBits(sum, 8); } +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The size/length of the state. void IRHitachiAc::checksum(const uint16_t length) { remote_state[length - 1] = calcChecksum(remote_state, length); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRHitachiAc::validChecksum(const uint8_t state[], const uint16_t length) { if (length < 2) return true; // Assume true for lengths that are too short. return (state[length - 1] == calcChecksum(state, length)); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRHitachiAc::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the new_code array. void IRHitachiAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kHitachiAcStateLength)); } #if SEND_HITACHI_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHitachiAc::send(const uint16_t repeat) { _irsend.sendHitachiAC(getRaw(), kHitachiAcStateLength, repeat); } #endif // SEND_HITACHI_AC +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc::getPower(void) { return GETBIT8(remote_state[17], kHitachiAcPowerOffset); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc::setPower(const bool on) { setBit(&remote_state[17], kHitachiAcPowerOffset, on); } +/// Change the power setting to On. void IRHitachiAc::on(void) { setPower(true); } +/// Change the power setting to Off. void IRHitachiAc::off(void) { setPower(false); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHitachiAc::getMode(void) { return reverseBits(remote_state[10], 8); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHitachiAc::setMode(const uint8_t mode) { uint8_t newmode = mode; switch (mode) { @@ -219,10 +244,14 @@ void IRHitachiAc::setMode(const uint8_t mode) { setFan(getFan()); // Reset the fan speed after the mode change. } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHitachiAc::getTemp(void) { return reverseBits(remote_state[11], 8) >> 1; } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. void IRHitachiAc::setTemp(const uint8_t celsius) { uint8_t temp; if (celsius != 64) _previoustemp = celsius; @@ -241,8 +270,12 @@ void IRHitachiAc::setTemp(const uint8_t celsius) { remote_state[9] = 0x10; } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHitachiAc::getFan(void) { return reverseBits(remote_state[13], 8); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRHitachiAc::setFan(const uint8_t speed) { uint8_t fanmin = kHitachiAcFanAuto; uint8_t fanmax = kHitachiAcFanHigh; @@ -260,23 +293,33 @@ void IRHitachiAc::setFan(const uint8_t speed) { remote_state[13] = reverseBits(newspeed, 8); } +/// Get the Vertical Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc::getSwingVertical(void) { return GETBIT8(remote_state[14], kHitachiAcSwingOffset); } +/// Set the Vertical Swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc::setSwingVertical(const bool on) { setBit(&remote_state[14], kHitachiAcSwingOffset, on); } +/// Get the Horizontal Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc::getSwingHorizontal(void) { return GETBIT8(remote_state[15], kHitachiAcSwingOffset); } +/// Set the Horizontal Swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc::setSwingHorizontal(const bool on) { setBit(&remote_state[15], kHitachiAcSwingOffset, on); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHitachiAcCool; @@ -287,7 +330,9 @@ uint8_t IRHitachiAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -299,7 +344,9 @@ uint8_t IRHitachiAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHitachiAc::toCommonMode(const uint8_t mode) { switch (mode) { case kHitachiAcCool: return stdAc::opmode_t::kCool; @@ -310,7 +357,9 @@ stdAc::opmode_t IRHitachiAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHitachiAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHitachiAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -321,7 +370,8 @@ stdAc::fanspeed_t IRHitachiAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHitachiAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HITACHI_AC; @@ -348,7 +398,8 @@ stdAc::state_t IRHitachiAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRHitachiAc::toString(void) { String result = ""; result.reserve(110); // Reserve some heap for the string to reduce fragging. @@ -364,14 +415,15 @@ String IRHitachiAc::toString(void) { return result; } -// Class for handling the remote control on a Hitachi 13 byte A/C message. -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 - +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRHitachiAc1::IRHitachiAc1(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Reset the internal state to a fixed known good state. void IRHitachiAc1::stateReset(void) { for (uint8_t i = 0; i < kHitachiAc1StateLength; i++) remote_state[i] = 0x00; // Copy in a known good state. @@ -386,8 +438,13 @@ void IRHitachiAc1::stateReset(void) { remote_state[12] = 0x24; } +/// Set up hardware to be able to send a message. void IRHitachiAc1::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @param[in] length The size/length of the state. +/// @return The calculated checksum value. uint8_t IRHitachiAc1::calcChecksum(const uint8_t state[], const uint16_t length) { uint8_t sum = 0; @@ -400,25 +457,38 @@ uint8_t IRHitachiAc1::calcChecksum(const uint8_t state[], return reverseBits(sum, 8); } +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The size/length of the state. void IRHitachiAc1::checksum(const uint16_t length) { remote_state[length - 1] = calcChecksum(remote_state, length); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRHitachiAc1::validChecksum(const uint8_t state[], const uint16_t length) { if (length < 2) return true; // Assume true for lengths that are too short. return (state[length - 1] == calcChecksum(state, length)); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRHitachiAc1::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the new_code array. void IRHitachiAc1::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kHitachiAc1StateLength)); } #if SEND_HITACHI_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHitachiAc1::send(const uint16_t repeat) { _irsend.sendHitachiAC1(getRaw(), kHitachiAc1StateLength, repeat); // Clear the toggle bits as we have actioned them by sending them. @@ -427,6 +497,8 @@ void IRHitachiAc1::send(const uint16_t repeat) { } #endif // SEND_HITACHI_AC +/// Get/Detect the model of the A/C. +/// @return The enum of the compatible model. hitachi_ac1_remote_model_t IRHitachiAc1::getModel(void) { switch (GETBITS8(remote_state[kHitachiAc1ModelByte], kHitachiAc1ModelOffset, kHitachiAc1ModelSize)) { @@ -435,6 +507,8 @@ hitachi_ac1_remote_model_t IRHitachiAc1::getModel(void) { } } +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRHitachiAc1::setModel(const hitachi_ac1_remote_model_t model) { uint8_t value = 0; switch (model) { @@ -448,34 +522,48 @@ void IRHitachiAc1::setModel(const hitachi_ac1_remote_model_t model) { kHitachiAc1ModelSize, value); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getPower(void) { return GETBIT8(remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerOffset); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc1::setPower(const bool on) { // If the power changes, set the power toggle bit. if (on != getPower()) setPowerToggle(true); setBit(&remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerOffset, on); } +/// Get the value of the current power toggle setting. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getPowerToggle(void) { return GETBIT8(remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerToggleOffset); } +/// Change the power toggle setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc1::setPowerToggle(const bool on) { setBit(&remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerToggleOffset, on); } +/// Change the power setting to On. void IRHitachiAc1::on(void) { setPower(true); } +/// Change the power setting to Off. void IRHitachiAc1::off(void) { setPower(false); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHitachiAc1::getMode(void) { return GETBITS8(remote_state[kHitachiAc1ModeByte], kHitachiAc1ModeOffset, kHitachiAc1ModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHitachiAc1::setMode(const uint8_t mode) { switch (mode) { case kHitachiAc1Auto: @@ -500,12 +588,16 @@ void IRHitachiAc1::setMode(const uint8_t mode) { } } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHitachiAc1::getTemp(void) { return reverseBits(GETBITS8(remote_state[kHitachiAc1TempByte], kHitachiAc1TempOffset, kHitachiAc1TempSize), kHitachiAc1TempSize) + kHitachiAc1TempDelta; } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. void IRHitachiAc1::setTemp(const uint8_t celsius) { if (getMode() == kHitachiAc1Auto) return; // Can't change temp in Auto mode. uint8_t temp = std::min(celsius, kHitachiAcMaxTemp); @@ -516,11 +608,16 @@ void IRHitachiAc1::setTemp(const uint8_t celsius) { kHitachiAc1TempSize, temp); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHitachiAc1::getFan(void) { return GETBITS8(remote_state[kHitachiAc1FanByte], kHitachiAc1FanOffset, kHitachiAc1FanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @param[in] force Do we allow setting the speed regardless of restrictions? void IRHitachiAc1::setFan(const uint8_t speed, const bool force) { if (!force) { switch (getMode()) { @@ -549,39 +646,56 @@ void IRHitachiAc1::setFan(const uint8_t speed, const bool force) { } } +/// Get the Swing Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getSwingToggle(void) { return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingToggleOffset); } +/// Set the Swing toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRHitachiAc1::setSwingToggle(const bool toggle) { setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingToggleOffset, toggle); } +/// Get the Vertical Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getSwingV(void) { return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingVOffset); } +/// Set the Vertical Swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc1::setSwingV(const bool on) { setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingVOffset, on); } +/// Get the Horizontal Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getSwingH(void) { return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingHOffset); } +/// Set the Horizontal Swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc1::setSwingH(const bool on) { setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingHOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return The currently configured sleep mode. +/// @note Sleep modes only available in Auto & Cool modes, otherwise it's off. uint8_t IRHitachiAc1::getSleep(void) { return GETBITS8(remote_state[kHitachiAc1SleepByte], kHitachiAc1SleepOffset, kHitachiAc1SleepSize); } +/// Set the Sleep setting of the A/C. +/// @param[in] mode The mode of sleep to set the A/C to. +/// @note Sleep modes only available in Auto & Cool modes, otherwise it's off. void IRHitachiAc1::setSleep(const uint8_t mode) { - // Sleep modes only available in Auto & Cool modes, otherwise it's off. switch (getMode()) { case kHitachiAc1Auto: case kHitachiAc1Cool: @@ -594,31 +708,41 @@ void IRHitachiAc1::setSleep(const uint8_t mode) { } } +/// Set the On Timer time. +/// @param[in] mins The time expressed in total number of minutes. void IRHitachiAc1::setOnTimer(const uint16_t mins) { const uint16_t mins_lsb = reverseBits(mins, kHitachiAc1TimerSize); remote_state[kHitachiAc1OnTimerLowByte] = GETBITS16(mins_lsb, 8, 8); remote_state[kHitachiAc1OnTimerHighByte] = GETBITS16(mins_lsb, 0, 8); } +/// Get the On Timer vtime of the A/C. +/// @return Nr of minutes the timer is set to. uint16_t IRHitachiAc1::getOnTimer(void) { return reverseBits( (remote_state[kHitachiAc1OnTimerLowByte] << 8) | remote_state[kHitachiAc1OnTimerHighByte], kHitachiAc1TimerSize); } +/// Set the Off Timer time. +/// @param[in] mins The time expressed in total number of minutes. void IRHitachiAc1::setOffTimer(const uint16_t mins) { const uint16_t mins_lsb = reverseBits(mins, kHitachiAc1TimerSize); remote_state[kHitachiAc1OffTimerLowByte] = GETBITS16(mins_lsb, 8, 8); remote_state[kHitachiAc1OffTimerHighByte] = GETBITS16(mins_lsb, 0, 8); } +/// Get the Off Timer vtime of the A/C. +/// @return Nr of minutes the timer is set to. uint16_t IRHitachiAc1::getOffTimer(void) { return reverseBits( (remote_state[kHitachiAc1OffTimerLowByte] << 8) | remote_state[kHitachiAc1OffTimerHighByte], kHitachiAc1TimerSize); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc1::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHitachiAc1Cool; @@ -629,7 +753,9 @@ uint8_t IRHitachiAc1::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc1::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -641,7 +767,9 @@ uint8_t IRHitachiAc1::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHitachiAc1::toCommonMode(const uint8_t mode) { switch (mode) { case kHitachiAc1Cool: return stdAc::opmode_t::kCool; @@ -652,7 +780,9 @@ stdAc::opmode_t IRHitachiAc1::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHitachiAc1::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHitachiAc1FanHigh: return stdAc::fanspeed_t::kMax; @@ -662,7 +792,8 @@ stdAc::fanspeed_t IRHitachiAc1::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHitachiAc1::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HITACHI_AC1; @@ -689,7 +820,8 @@ stdAc::state_t IRHitachiAc1::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRHitachiAc1::toString(void) { String result = ""; result.reserve(170); // Reserve some heap for the string to reduce fragging. @@ -716,29 +848,26 @@ String IRHitachiAc1::toString(void) { return result; } -#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2) -// Decode the supplied Hitachi A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Expected to work. -// -// Supported devices: -// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/417 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/453 +#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || \ + DECODE_HITACHI_AC344) +/// Decode the supplied Hitachi A/C message. +/// Status: STABLE / Expected to work. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, +/// kHitachiAc344Bits +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @param[in] MSBfirst Is the data per byte stored in MSB First (true) or +/// LSB First order(false)? +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict) { + const uint16_t nbits, const bool strict, + const bool MSBfirst) { const uint8_t k_tolerance = _tolerance + 5; if (strict) { @@ -746,6 +875,7 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, case kHitachiAcBits: case kHitachiAc1Bits: case kHitachiAc2Bits: + case kHitachiAc344Bits: break; // Okay to continue. default: return false; // Not strictly a Hitachi message. @@ -767,7 +897,7 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, kHitachiAcBitMark, kHitachiAcOneSpace, kHitachiAcBitMark, kHitachiAcZeroSpace, kHitachiAcBitMark, kHitachiAcMinGap, true, - k_tolerance)) return false; + k_tolerance, kMarkExcess, MSBfirst)) return false; // Compliance if (strict) { @@ -777,19 +907,26 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, if (nbits / 8 == kHitachiAc1StateLength && !IRHitachiAc1::validChecksum(results->state, kHitachiAc1StateLength)) return false; + if (nbits / 8 == kHitachiAc344StateLength && + !IRHitachiAc3::hasInvertedStates(results->state, + kHitachiAc344StateLength)) + return false; } // Success switch (nbits) { case kHitachiAc1Bits: - results->decode_type = HITACHI_AC1; + results->decode_type = decode_type_t::HITACHI_AC1; break; case kHitachiAc2Bits: - results->decode_type = HITACHI_AC2; + results->decode_type = decode_type_t::HITACHI_AC2; + break; + case kHitachiAc344Bits: + results->decode_type = decode_type_t::HITACHI_AC344; break; case kHitachiAcBits: default: - results->decode_type = HITACHI_AC; + results->decode_type = decode_type_t::HITACHI_AC; } results->bits = nbits; // No need to record the state as we stored it as we decoded it. @@ -797,22 +934,18 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, // is a union data type. return true; } -#endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2) +#endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || + // DECODE_HITACHI_AC344) #if SEND_HITACHI_AC424 -// Send HITACHI_AC424 messages -// -// Note: This protocol is almost exactly the same as HitachiAC2 except this -// variant has a leader section as well, and subtle timing differences. -// It is also in LSBF order (per byte), rather than MSBF order. -// -// Args: -// data: An array of bytes containing the IR command. -// It is assumed to be in LSBF order for this code. -// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc424StateLength) -// repeat: Nr. of times the message is to be repeated. -// -// Status: STABLE / Reported as working. +/// Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) +/// Status: STABLE / Reported as working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol is almost exactly the same as HitachiAC2 except this +/// variant has a leader section as well, and subtle timing differences. +/// It is also in LSBF order (per byte), rather than MSBF order. void IRsend::sendHitachiAc424(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { enableIROut(kHitachiAcFreq); @@ -832,30 +965,19 @@ void IRsend::sendHitachiAc424(const uint8_t data[], const uint16_t nbytes, #endif // SEND_HITACHI_AC424 #if DECODE_HITACHI_AC424 -// Decode the supplied Hitachi 424 bit A/C message. -// -// Note: This protocol is almost exactly the same as HitachiAC2 except this -// variant has a leader section as well, and subtle timing differences. -// It is also in LSBF order (per byte), rather than MSBF order. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kHitachiAc424Bits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// -// Supported devices: -// Hitachi Shirokumakun / AC Model: RAS-AJ25H / AC Remote Model: RAR-8P2 -// Manual (Japanese): -// https://kadenfan.hitachi.co.jp/support/raj/item/docs/ras_aj22h_a_tori.pdf -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/973 +/// Decode the supplied Hitachi 53-byte/424-bit A/C message. +/// Status: STABLE / Reported as working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol is almost exactly the same as HitachiAC2 except this +/// variant has a leader section as well, and subtle timing differences. +/// It is also in LSBF order (per byte), rather than MSBF order. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/973 +/// @see (Japanese Manual) https://kadenfan.hitachi.co.jp/support/raj/item/docs/ras_aj22h_a_tori.pdf bool IRrecv::decodeHitachiAc424(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -889,12 +1011,16 @@ bool IRrecv::decodeHitachiAc424(decode_results *results, uint16_t offset, } #endif // DECODE_HITACHI_AC424 -// Class for handling the remote control on a Hitachi_AC424 53 byte A/C message +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRHitachiAc424::IRHitachiAc424(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } -// Reset to auto fan, cooling, 23° Celcius +/// Reset the internal state to a fixed known good state. +/// @note Reset to auto fan, cooling, 23° Celsius void IRHitachiAc424::stateReset(void) { for (uint8_t i = 0; i < kHitachiAc424StateLength; i++) remote_state[i] = 0x00; @@ -919,46 +1045,65 @@ void IRHitachiAc424::stateReset(void) { setFan(kHitachiAc424FanAuto); } +/// Update the internal consistency check for the protocol. void IRHitachiAc424::setInvertedStates(void) { for (uint8_t i = 3; i < kHitachiAc424StateLength - 1; i += 2) remote_state[i + 1] = ~remote_state[i]; } +/// Set up hardware to be able to send a message. void IRHitachiAc424::begin(void) { _irsend.begin(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRHitachiAc424::getRaw(void) { setInvertedStates(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the new_code array. void IRHitachiAc424::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kHitachiAc424StateLength)); } #if SEND_HITACHI_AC424 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHitachiAc424::send(const uint16_t repeat) { _irsend.sendHitachiAc424(getRaw(), kHitachiAc424StateLength, repeat); } #endif // SEND_HITACHI_AC424 +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc424::getPower(void) { return remote_state[kHitachiAc424PowerByte] == kHitachiAc424PowerOn; } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc424::setPower(const bool on) { setButton(kHitachiAc424ButtonPowerMode); remote_state[kHitachiAc424PowerByte] = on ? kHitachiAc424PowerOn : kHitachiAc424PowerOff; } +/// Change the power setting to On. void IRHitachiAc424::on(void) { setPower(true); } +/// Change the power setting to Off. void IRHitachiAc424::off(void) { setPower(false); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHitachiAc424::getMode(void) { return GETBITS8(remote_state[kHitachiAc424ModeByte], kLowNibble, kNibbleSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHitachiAc424::setMode(const uint8_t mode) { uint8_t newMode = mode; switch (mode) { @@ -976,11 +1121,16 @@ void IRHitachiAc424::setMode(const uint8_t mode) { setButton(kHitachiAc424ButtonPowerMode); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHitachiAc424::getTemp(void) { return GETBITS8(remote_state[kHitachiAc424TempByte], kHitachiAc424TempOffset, kHitachiAc424TempSize); } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. +/// @param[in] setPrevious true, remember this if we change mode. false, don't. void IRHitachiAc424::setTemp(const uint8_t celsius, bool setPrevious) { uint8_t temp; temp = std::min(celsius, kHitachiAc424MaxTemp); @@ -994,10 +1144,14 @@ void IRHitachiAc424::setTemp(const uint8_t celsius, bool setPrevious) { if (setPrevious) _previoustemp = temp; } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHitachiAc424::getFan(void) { return GETBITS8(remote_state[kHitachiAc424FanByte], kHighNibble, kNibbleSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRHitachiAc424::setFan(const uint8_t speed) { uint8_t newSpeed = std::max(speed, kHitachiAc424FanMin); uint8_t fanMax = kHitachiAc424FanMax; @@ -1029,17 +1183,22 @@ void IRHitachiAc424::setFan(const uint8_t speed) { } } +/// Get the Button/Command setting of the A/C. +/// @return The value of the button/command that was pressed. uint8_t IRHitachiAc424::getButton(void) { return remote_state[kHitachiAc424ButtonByte]; } -// The remote sends the type of button pressed on send +/// Set the Button/Command pressed setting of the A/C. +/// @param[in] button The value of the button/command that was pressed. void IRHitachiAc424::setButton(const uint8_t button) { remote_state[kHitachiAc424ButtonByte] = button; } -// The remote does not keep state of the vertical swing. -// A byte is sent indicating the swing button is pressed on the remote +/// Set the Vertical Swing toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note The remote does not keep state of the vertical swing. +/// A byte is sent indicating the swing button is pressed on the remote void IRHitachiAc424::setSwingVToggle(const bool on) { uint8_t button = getButton(); // Get the current button value. if (on) @@ -1050,11 +1209,15 @@ void IRHitachiAc424::setSwingVToggle(const bool on) { setButton(button); } +/// Get the Vertical Swing toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc424::getSwingVToggle(void) { return getButton() == kHitachiAc424ButtonSwingV; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc424::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHitachiAc424Cool; @@ -1065,7 +1228,9 @@ uint8_t IRHitachiAc424::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc424::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kHitachiAc424FanMin; @@ -1077,7 +1242,9 @@ uint8_t IRHitachiAc424::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHitachiAc424::toCommonMode(const uint8_t mode) { switch (mode) { case kHitachiAc424Cool: return stdAc::opmode_t::kCool; @@ -1088,7 +1255,9 @@ stdAc::opmode_t IRHitachiAc424::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHitachiAc424::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHitachiAc424FanMax: return stdAc::fanspeed_t::kMax; @@ -1100,7 +1269,8 @@ stdAc::fanspeed_t IRHitachiAc424::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHitachiAc424::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HITACHI_AC424; @@ -1126,8 +1296,10 @@ stdAc::state_t IRHitachiAc424::toCommon(void) { return result; } -// Convert the internal state into a human readable string. -String IRHitachiAc424::toString(void) { +/// Convert the internal state into a human readable string for the settings +/// that are common to protocols of this nature. +/// @return A string containing the common settings in human-readable form. +String IRHitachiAc424::_toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. result += addBoolToString(getPower(), kPowerStr, false); @@ -1147,7 +1319,6 @@ String IRHitachiAc424::toString(void) { default: result += kUnknownStr; } result += ')'; - result += addBoolToString(getSwingVToggle(), kSwingVToggleStr); result += addIntToString(getButton(), kButtonStr); result += kSpaceLBraceStr; switch (getButton()) { @@ -1158,6 +1329,7 @@ String IRHitachiAc424::toString(void) { break; case kHitachiAc424ButtonFan: result += kFanStr; break; case kHitachiAc424ButtonSwingV: result += kSwingVStr; break; + case kHitachiAc344ButtonSwingH: result += kSwingHStr; break; case kHitachiAc424ButtonTempDown: result += kTempDownStr; break; case kHitachiAc424ButtonTempUp: result += kTempUpStr; break; default: result += kUnknownStr; @@ -1166,26 +1338,26 @@ String IRHitachiAc424::toString(void) { return result; } +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. +String IRHitachiAc424::toString(void) { + return _toString() + addBoolToString(getSwingVToggle(), kSwingVToggleStr); +} + #if SEND_HITACHI_AC3 -// Send HITACHI_AC3 messages -// -// Note: This protocol is almost exactly the same as HitachiAC424 except this -// variant has subtle timing differences. -// There are five(5) typical sizes: -// * kHitachiAc3MinStateLength (Cancel Timer) -// * kHitachiAc3MinStateLength + 2 (Change Temp) -// * kHitachiAc3StateLength - 6 (Change Mode) -// * kHitachiAc3StateLength- 4 (Normal) -// * kHitachiAc3StateLength (Set Timer) -// -// Args: -// data: An array of bytes containing the IR command. -// It is assumed to be in LSBF order for this code. -// nbytes: Nr. of bytes of data in the array. -// repeat: Nr. of times the message is to be repeated. -// -// Status: STABLE / Working fine. +/// Send a Hitachi(3) A/C formatted message. (HITACHI_AC3) +/// Status: STABLE / Working fine. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol is almost exactly the same as HitachiAC424 except this +/// variant has subtle timing differences. There are five(5) typical sizes: +/// kHitachiAc3MinStateLength (Cancel Timer), +/// kHitachiAc3MinStateLength + 2 (Change Temp), +/// kHitachiAc3StateLength - 6 (Change Mode), +/// kHitachiAc3StateLength - 4 (Normal), & +/// kHitachiAc3StateLength (Set Timer) void IRsend::sendHitachiAc3(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { // Header + Data + Footer @@ -1199,12 +1371,16 @@ void IRsend::sendHitachiAc3(const uint8_t data[], const uint16_t nbytes, #endif // SEND_HITACHI_AC3 -// Class for handling the remote control on a Hitachi_AC3 53 A/C message +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRHitachiAc3::IRHitachiAc3(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } -// Reset to auto fan, cooling, 23° Celcius +/// Reset the internal state to a fixed known good state. +/// @note Reset to auto fan, cooling, 23° Celsius void IRHitachiAc3::stateReset(void) { for (uint8_t i = 0; i < kHitachiAc3StateLength; i++) remote_state[i] = 0x00; @@ -1222,11 +1398,19 @@ void IRHitachiAc3::stateReset(void) { setInvertedStates(); } +/// Invert every second byte of the internal state, after the fixed header. +/// @param[in] length The size of the state array. +/// @note This is this protocols integrity check. void IRHitachiAc3::setInvertedStates(const uint16_t length) { for (uint8_t i = 3; i < length - 1; i += 2) remote_state[i + 1] = ~remote_state[i]; } +/// Check if every second byte of the state, after the fixed header +/// is inverted to the previous byte. +/// @param[in] state The state array to be checked. +/// @param[in] length The size of the state array. +/// @note This is this protocols integrity check. bool IRHitachiAc3::hasInvertedStates(const uint8_t state[], const uint16_t length) { for (uint8_t i = 3; i < length - 1; i += 2) @@ -1234,39 +1418,41 @@ bool IRHitachiAc3::hasInvertedStates(const uint8_t state[], return true; } +/// Set up hardware to be able to send a message. void IRHitachiAc3::begin(void) { _irsend.begin(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRHitachiAc3::getRaw(void) { setInvertedStates(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the new_code array. void IRHitachiAc3::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kHitachiAc3StateLength)); } #if DECODE_HITACHI_AC3 -// Decode the supplied HitachiAc3 A/C message. -// -// Note: This protocol is almost exactly the same as HitachiAC424 except this -// variant has subtle timing differences and multiple lengths. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kHitachiAc3Bits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Works fine. -// -// Supported devices: -// Hitachi PC-LH3B -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 +/// Decode the supplied Hitachi 15to27-byte/120to216-bit A/C message. +/// Status: STABLE / Works fine. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol is almost exactly the same as HitachiAC424 except this +/// variant has subtle timing differences and multiple lengths. +/// There are five(5) typical lengths: +/// kHitachiAc3MinStateLength (Cancel Timer), +/// kHitachiAc3MinStateLength + 2 (Change Temp), +/// kHitachiAc3StateLength - 6 (Change Mode), +/// kHitachiAc3StateLength - 4 (Normal), & +/// kHitachiAc3StateLength (Set Timer) +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 bool IRrecv::decodeHitachiAc3(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -1304,3 +1490,124 @@ bool IRrecv::decodeHitachiAc3(decode_results *results, uint16_t offset, return true; } #endif // DECODE_HITACHI_AC3 + +/// Class constructor for handling detailed Hitachi_AC344 43 byte A/C messages. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? +IRHitachiAc344::IRHitachiAc344(const uint16_t pin, const bool inverted, + const bool use_modulation) + : IRHitachiAc424(pin, inverted, use_modulation) { stateReset(); } + +/// Reset the internal state to auto fan, cooling, 23° Celsius +void IRHitachiAc344::stateReset(void) { + IRHitachiAc424::stateReset(); + remote_state[37] = 0x00; + remote_state[39] = 0x00; +} + +#if SEND_HITACHI_AC344 +/// Create and send the IR message to the A/C. +/// @param[in] repeat Nr. of times to repeat the message. +void IRHitachiAc344::send(const uint16_t repeat) { + _irsend.sendHitachiAc344(getRaw(), kHitachiAc344StateLength, repeat); +} +#endif // SEND_HITACHI_AC344 + +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length Size (in bytes) of the code for this protocol. +void IRHitachiAc344::setRaw(const uint8_t new_code[], const uint16_t length) { + memcpy(remote_state, new_code, std::min(length, kHitachiAc344StateLength)); +} + +/// Control the vertical swing setting. +/// @param[in] on True, turns on the feature. False, turns off the feature. +void IRHitachiAc344::setSwingV(const bool on) { + setSwingVToggle(on); // Set the button value. + setBit(&remote_state[kHitachiAc344SwingVByte], kHitachiAc344SwingVOffset, on); +} + +/// Get the current vertical swing setting. +/// @return True, if the setting is on. False, it is off. +bool IRHitachiAc344::getSwingV(void) { + return GETBIT8(remote_state[kHitachiAc344SwingVByte], + kHitachiAc344SwingVOffset); +} + +/// Control the horizontal swing setting. +/// @param[in] position The position to set the horizontal swing to. +void IRHitachiAc344::setSwingH(const uint8_t position) { + if (position > kHitachiAc344SwingHLeftMax) + return setSwingH(kHitachiAc344SwingHMiddle); + setBits(&remote_state[kHitachiAc344SwingHByte], kHitachiAc344SwingHOffset, + kHitachiAc344SwingHSize, position); + setButton(kHitachiAc344ButtonSwingH); +} + +/// Get the current horizontal swing setting. +/// @return The current position horizontal swing is set to. +uint8_t IRHitachiAc344::getSwingH(void) { + return GETBITS8(remote_state[kHitachiAc344SwingHByte], + kHitachiAc344SwingHOffset, kHitachiAc344SwingHSize); +} + +/// Convert a standard A/C horizontal swing into its native setting. +/// @param[in] position A stdAc::swingh_t position to convert. +/// @return The equivilent native horizontal swing position. +uint8_t IRHitachiAc344::convertSwingH(const stdAc::swingh_t position) { + switch (position) { + case stdAc::swingh_t::kAuto: return kHitachiAc344SwingHAuto; + case stdAc::swingh_t::kLeftMax: return kHitachiAc344SwingHLeftMax; + case stdAc::swingh_t::kLeft: return kHitachiAc344SwingHLeft; + case stdAc::swingh_t::kRight: return kHitachiAc344SwingHRight; + case stdAc::swingh_t::kRightMax: return kHitachiAc344SwingHRightMax; + default: return kHitachiAc344SwingHMiddle; + } +} + +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. +stdAc::swingh_t IRHitachiAc344::toCommonSwingH(const uint8_t pos) { + switch (pos) { + case kHitachiAc344SwingHLeftMax: return stdAc::swingh_t::kLeftMax; + case kHitachiAc344SwingHLeft: return stdAc::swingh_t::kLeft; + case kHitachiAc344SwingHRight: return stdAc::swingh_t::kRight; + case kHitachiAc344SwingHRightMax: return stdAc::swingh_t::kRightMax; + case kHitachiAc344SwingHAuto: return stdAc::swingh_t::kAuto; + default: return stdAc::swingh_t::kOff; + } +} + +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. +stdAc::state_t IRHitachiAc344::toCommon(void) { + stdAc::state_t result = IRHitachiAc424::toCommon(); + result.protocol = decode_type_t::HITACHI_AC344; + result.swingv = getSwingV() ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff; + result.swingh = toCommonSwingH(getSwingH()); + return result; +} + +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. +String IRHitachiAc344::toString(void) { + String result; + result.reserve(120); // Reserve some heap for the string to reduce fragging. + result += _toString(); + result += addBoolToString(getSwingV(), kSwingVStr); + result += addIntToString(getSwingH(), kSwingHStr); + result += kSpaceLBraceStr; + switch (getSwingH()) { + case kHitachiAc344SwingHLeftMax: result += kLeftMaxStr; break; + case kHitachiAc344SwingHLeft: result += kLeftStr; break; + case kHitachiAc344SwingHMiddle: result += kMiddleStr; break; + case kHitachiAc344SwingHRight: result += kRightStr; break; + case kHitachiAc344SwingHRightMax: result += kRightMaxStr; break; + case kHitachiAc344SwingHAuto: result += kAutoStr; break; + default: result += kUnknownStr; + } + result += ')'; + return result; +} diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.h b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.h similarity index 62% rename from lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.h index 47fbb9b02..408d4784f 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Hitachi.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.h @@ -1,16 +1,24 @@ -// Hitachi A/C -// // Copyright 2018-2020 David Conran +/// @file +/// @brief Support for Hitachi A/C protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/973 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 // Supports: // Brand: Hitachi, Model: RAS-35THA6 remote -// Brand: Hitachi, Model: LT0541-HTA remote -// Brand: Hitachi, Model: Series VI A/C (Circa 2007) -// Brand: Hitachi, Model: RAR-8P2 remote -// Brand: Hitachi, Model: RAS-AJ25H A/C +// Brand: Hitachi, Model: LT0541-HTA remote (HITACHI_AC1) +// Brand: Hitachi, Model: Series VI A/C (Circa 2007) (HITACHI_AC1) +// Brand: Hitachi, Model: RAR-8P2 remote (HITACHI_AC424) +// Brand: Hitachi, Model: RAS-AJ25H A/C (HITACHI_AC424) // Brand: Hitachi, Model: PC-LH3B (HITACHI_AC3) // Brand: Hitachi, Model: KAZE-312KSDP A/C (HITACHI_AC1) // Brand: Hitachi, Model: R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1) +// Brand: Hitachi, Model: RAS-22NK A/C (HITACHI_AC344) +// Brand: Hitachi, Model: RF11T1 remote (HITACHI_AC344) #ifndef IR_HITACHI_H_ #define IR_HITACHI_H_ @@ -43,7 +51,7 @@ const uint8_t kHitachiAcAutoTemp = 23; // 23C const uint8_t kHitachiAcPowerOffset = 0; const uint8_t kHitachiAcSwingOffset = 7; -// HitachiAc424 +// HitachiAc424 & HitachiAc344 // Byte[11] const uint8_t kHitachiAc424ButtonByte = 11; const uint8_t kHitachiAc424ButtonPowerMode = 0x13; @@ -51,6 +59,13 @@ const uint8_t kHitachiAc424ButtonFan = 0x42; const uint8_t kHitachiAc424ButtonTempDown = 0x43; const uint8_t kHitachiAc424ButtonTempUp = 0x44; const uint8_t kHitachiAc424ButtonSwingV = 0x81; +const uint8_t kHitachiAc424ButtonSwingH = 0x8C; +const uint8_t kHitachiAc344ButtonPowerMode = kHitachiAc424ButtonPowerMode; +const uint8_t kHitachiAc344ButtonFan = kHitachiAc424ButtonFan; +const uint8_t kHitachiAc344ButtonTempDown = kHitachiAc424ButtonTempDown; +const uint8_t kHitachiAc344ButtonTempUp = kHitachiAc424ButtonTempUp; +const uint8_t kHitachiAc344ButtonSwingV = kHitachiAc424ButtonSwingV; +const uint8_t kHitachiAc344ButtonSwingH = kHitachiAc424ButtonSwingH; // Byte[13] const uint8_t kHitachiAc424TempByte = 13; @@ -58,6 +73,8 @@ const uint8_t kHitachiAc424TempOffset = 2; const uint8_t kHitachiAc424TempSize = 6; const uint8_t kHitachiAc424MinTemp = 16; // 16C const uint8_t kHitachiAc424MaxTemp = 32; // 32C +const uint8_t kHitachiAc344MinTemp = kHitachiAc424MinTemp; +const uint8_t kHitachiAc344MaxTemp = kHitachiAc424MaxTemp; const uint8_t kHitachiAc424FanTemp = 27; // 27C // Byte[25] @@ -66,6 +83,11 @@ const uint8_t kHitachiAc424Fan = 1; const uint8_t kHitachiAc424Cool = 3; const uint8_t kHitachiAc424Dry = 5; const uint8_t kHitachiAc424Heat = 6; +const uint8_t kHitachiAc344Fan = kHitachiAc424Fan; +const uint8_t kHitachiAc344Cool = kHitachiAc424Cool; +const uint8_t kHitachiAc344Dry = kHitachiAc424Dry; +const uint8_t kHitachiAc344Heat = kHitachiAc424Heat; + const uint8_t kHitachiAc424FanByte = kHitachiAc424ModeByte; const uint8_t kHitachiAc424FanMin = 1; const uint8_t kHitachiAc424FanLow = 2; @@ -74,11 +96,33 @@ const uint8_t kHitachiAc424FanHigh = 4; const uint8_t kHitachiAc424FanAuto = 5; const uint8_t kHitachiAc424FanMax = 6; const uint8_t kHitachiAc424FanMaxDry = 2; +const uint8_t kHitachiAc344FanMin = kHitachiAc424FanMin; +const uint8_t kHitachiAc344FanLow = kHitachiAc424FanLow; +const uint8_t kHitachiAc344FanMedium = kHitachiAc424FanMedium; +const uint8_t kHitachiAc344FanHigh = kHitachiAc424FanHigh; +const uint8_t kHitachiAc344FanAuto = kHitachiAc424FanAuto; +const uint8_t kHitachiAc344FanMax = kHitachiAc424FanMax; + // Byte[27] const uint8_t kHitachiAc424PowerByte = 27; const uint8_t kHitachiAc424PowerOn = 0xF1; const uint8_t kHitachiAc424PowerOff = 0xE1; +// Byte[35] +const uint8_t kHitachiAc344SwingHByte = 35; +const uint8_t kHitachiAc344SwingHOffset = 0; // Mask 0b00000xxx +const uint8_t kHitachiAc344SwingHSize = 3; // Mask 0b00000xxx +const uint8_t kHitachiAc344SwingHAuto = 0; // 0b000 +const uint8_t kHitachiAc344SwingHRightMax = 1; // 0b001 +const uint8_t kHitachiAc344SwingHRight = 2; // 0b010 +const uint8_t kHitachiAc344SwingHMiddle = 3; // 0b011 +const uint8_t kHitachiAc344SwingHLeft = 4; // 0b100 +const uint8_t kHitachiAc344SwingHLeftMax = 5; // 0b101 + +// Byte[37] +const uint8_t kHitachiAc344SwingVByte = 37; +const uint8_t kHitachiAc344SwingVOffset = 5; // Mask 0b00x00000 + // HitachiAc1 // Byte[3] (Model) const uint8_t kHitachiAc1ModelByte = 3; @@ -139,14 +183,19 @@ const uint8_t kHitachiAc1ChecksumStartByte = 5; // Classes +/// Class for handling detailed Hitachi 224-bit A/C messages. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/HitachiHeatpumpIR.cpp class IRHitachiAc { public: explicit IRHitachiAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_HITACHI_AC void send(const uint16_t repeat = kHitachiAcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HITACHI_AC void begin(void); @@ -180,16 +229,19 @@ class IRHitachiAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kHitachiAcStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHitachiAcStateLength]; ///< The state in native code. void checksum(const uint16_t length = kHitachiAcStateLength); uint8_t _previoustemp; }; +/// Class for handling detailed Hitachi 104-bit A/C messages. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 class IRHitachiAc1 { public: explicit IRHitachiAc1(const uint16_t pin, const bool inverted = false, @@ -198,6 +250,10 @@ class IRHitachiAc1 { void stateReset(void); #if SEND_HITACHI_AC1 void send(const uint16_t repeat = kHitachiAcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HITACHI_AC1 void begin(void); @@ -243,23 +299,29 @@ class IRHitachiAc1 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kHitachiAc1StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHitachiAc1StateLength]; ///< The state in native code. void checksum(const uint16_t length = kHitachiAc1StateLength); }; +/// Class for handling detailed Hitachi 53-byte/424-bit A/C messages. class IRHitachiAc424 { + friend class IRHitachiAc344; public: explicit IRHitachiAc424(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - - void stateReset(void); + virtual void stateReset(void); #if SEND_HITACHI_AC424 - void send(const uint16_t repeat = kHitachiAcDefaultRepeat); + virtual void send(const uint16_t repeat = kHitachiAcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HITACHI_AC424 void begin(void); @@ -278,35 +340,42 @@ class IRHitachiAc424 { void setMode(const uint8_t mode); uint8_t getMode(void); uint8_t* getRaw(void); - void setRaw(const uint8_t new_code[], - const uint16_t length = kHitachiAc424StateLength); + virtual void setRaw(const uint8_t new_code[], + const uint16_t length = kHitachiAc424StateLength); uint8_t convertMode(const stdAc::opmode_t mode); uint8_t convertFan(const stdAc::fanspeed_t speed); static stdAc::opmode_t toCommonMode(const uint8_t mode); static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); - stdAc::state_t toCommon(void); + virtual stdAc::state_t toCommon(void); String toString(void); #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kHitachiAc424StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHitachiAc424StateLength]; ///< The state in native code void setInvertedStates(void); + String _toString(void); uint8_t _previoustemp; }; +/// Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages. class IRHitachiAc3 { public: explicit IRHitachiAc3(const uint16_t pin, const bool inverted = false, - const bool use_modulation = true); + const bool use_modulation = true); void stateReset(void); #if SEND_HITACHI_AC3 void send(const uint16_t repeat = kHitachiAcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_HITACHI_AC3 void begin(void); @@ -318,13 +387,34 @@ class IRHitachiAc3 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kHitachiAc3StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHitachiAc3StateLength]; ///< The state in native code. void setInvertedStates(const uint16_t length = kHitachiAc3StateLength); }; +/// Class for handling detailed Hitachi 344-bit A/C messages. +class IRHitachiAc344: public IRHitachiAc424 { + public: + explicit IRHitachiAc344(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + void stateReset(void); + void setRaw(const uint8_t new_code[], + const uint16_t length = kHitachiAc344StateLength); + stdAc::state_t toCommon(void); +#if SEND_HITACHI_AC344 + void send(const uint16_t repeat = kHitachiAcDefaultRepeat); +#endif // SEND_HITACHI_AC344 + void setSwingV(const bool on); + bool getSwingV(void); + void setSwingH(const uint8_t position); + uint8_t getSwingH(void); + static uint8_t convertSwingH(const stdAc::swingh_t position); + static stdAc::swingh_t toCommonSwingH(const uint8_t pos); + String toString(void); +}; #endif // IR_HITACHI_H_ diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Inax.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Inax.cpp similarity index 57% rename from lib/IRremoteESP8266-2.7.7/src/ir_Inax.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Inax.cpp index b57742a12..bb68ff30d 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Inax.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Inax.cpp @@ -1,20 +1,18 @@ // Copyright 2019 David Conran (crankyoldgit) -// Support for an IR controlled Robot Toilet +/// @file +/// @brief Support for the Inax Robot Toilet IR protocols. +/// @see https://www.lixil-manual.com/GCW-1365-16050/GCW-1365-16050.pdf +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/706 + +// Supports: +// Brand: Lixil, Model: Inax DT-BA283 Toilet #include #include "IRrecv.h" #include "IRsend.h" #include "IRutils.h" -// Supports: -// Brand: Lixil, Model: Inax DT-BA283 Toilet - -// Documentation: -// https://www.lixil-manual.com/GCW-1365-16050/GCW-1365-16050.pdf - // Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/706 const uint16_t kInaxTick = 500; const uint16_t kInaxHdrMark = 9000; const uint16_t kInaxHdrSpace = 4500; @@ -24,16 +22,12 @@ const uint16_t kInaxZeroSpace = kInaxBitMark; const uint16_t kInaxMinGap = 40000; #if SEND_INAX -// Send a Inax Toilet formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kInaxBits. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/706 +/// Send a Inax Toilet formatted message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/706 void IRsend::sendInax(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kInaxHdrMark, kInaxHdrSpace, @@ -42,23 +36,18 @@ void IRsend::sendInax(const uint64_t data, const uint16_t nbits, kInaxBitMark, kInaxMinGap, data, nbits, 38, true, repeat, kDutyDefault); } -#endif +#endif // SEND_INAX #if DECODE_INAX -// Decode the supplied Inax Toilet message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kInaxBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Stable / Known working. -// +/// Decode the supplied Inax Toilet message. +/// Status: Stable / Known working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/706 bool IRrecv::decodeInax(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kInaxBits) @@ -76,9 +65,9 @@ bool IRrecv::decodeInax(decode_results *results, uint16_t offset, // Success results->bits = nbits; results->value = data; - results->decode_type = INAX; + results->decode_type = decode_type_t::INAX; results->command = 0; results->address = 0; return true; } -#endif +#endif // DECODE_INAX diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_JVC.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_JVC.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.7/src/ir_JVC.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_JVC.cpp index 7e1e5de27..cdd302a77 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_JVC.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_JVC.cpp @@ -1,18 +1,22 @@ // Copyright 2015 Kristian Lauszus // Copyright 2017 David Conran +/// @file +/// @brief Support for JVC protocols. +/// Originally added by Kristian Lauszus +/// Thanks to zenwheel and other people at the original blog post. +/// @see http://www.sbprojects.com/knowledge/ir/jvc.php + +// Supports: +// Brand: JVC, Model: PTU94023B remote + #include #include "IRrecv.h" #include "IRsend.h" #include "IRtimer.h" #include "IRutils.h" -// JVC originally added by Kristian Lauszus -// (Thanks to zenwheel and other people at the original blog post) - // Constants -// Ref: -// http://www.sbprojects.com/knowledge/ir/jvc.php const uint16_t kJvcTick = 75; const uint16_t kJvcHdrMarkTicks = 112; const uint16_t kJvcHdrMark = kJvcHdrMarkTicks * kJvcTick; @@ -33,17 +37,12 @@ const uint16_t kJvcMinGapTicks = const uint16_t kJvcMinGap = kJvcMinGapTicks * kJvcTick; #if SEND_JVC -// Send a JVC message. -// -// Args: -// data: The contents of the command you want to send. -// nbits: The bit size of the command being sent. (kJvcBits) -// repeat: The number of times you want the command to be repeated. -// -// Status: STABLE. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/jvc.php +/// Send a JVC formatted message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see http://www.sbprojects.com/knowledge/ir/jvc.php void IRsend::sendJVC(uint64_t data, uint16_t nbits, uint16_t repeat) { // Set 38kHz IR carrier frequency & a 1/3 (33%) duty cycle. enableIROut(38, 33); @@ -70,41 +69,28 @@ void IRsend::sendJVC(uint64_t data, uint16_t nbits, uint16_t repeat) { } } -// Calculate the raw JVC data based on address and command. -// -// Args: -// address: An 8-bit address value. -// command: An 8-bit command value. -// Returns: -// A raw JVC message. -// -// Status: STABLE / Works fine. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/jvc.php +/// Calculate the raw JVC data based on address and command. +/// Status: STABLE / Works fine. +/// @param[in] address An 8-bit address value. +/// @param[in] command An 8-bit command value. +/// @return A raw JVC message code, suitable for sendJVC().. +/// @see http://www.sbprojects.com/knowledge/ir/jvc.php uint16_t IRsend::encodeJVC(uint8_t address, uint8_t command) { return reverseBits((command << 8) | address, 16); } -#endif +#endif // SEND_JVC #if DECODE_JVC -// Decode the supplied JVC message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits of data to expect. Typically kJvcBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE -// -// Note: -// JVC repeat codes don't have a header. -// Ref: -// http://www.sbprojects.com/knowledge/ir/jvc.php +/// Decode the supplied JVC message. +/// Status: Stable / Known working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note JVC repeat codes don't have a header. +/// @see http://www.sbprojects.com/knowledge/ir/jvc.php bool IRrecv::decodeJVC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kJvcBits) @@ -142,4 +128,4 @@ bool IRrecv::decodeJVC(decode_results *results, uint16_t offset, results->repeat = isRepeat; return true; } -#endif +#endif // DECODE_JVC diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.cpp similarity index 75% rename from lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.cpp index 4a4fac276..18702dad8 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.cpp @@ -1,18 +1,18 @@ // Copyright 2016 David Conran -// -// Code to emulate IR Kelvinator YALIF remote control unit, which should control -// at least the following Kelvinator A/C units: -// KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, -// KSV70HRC, KSV80HRC. -// -// Note: -// * Unsupported: -// - All Sleep modes. -// - All Timer modes. -// - "I Feel" button & mode. -// - Energy Saving mode. -// - Low Heat mode. -// - Fahrenheit. +/// @file +/// @brief Support for Kelvinator A/C protocols. +/// Code to emulate IR Kelvinator YALIF remote control unit, which should +/// control at least the following Kelvinator A/C units: +/// KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, +/// KSV70HRC, KSV80HRC. +/// +/// @note Unsupported: +/// - All Sleep modes. +/// - All Timer modes. +/// - "I Feel" button & mode. +/// - Energy Saving mode. +/// - Low Heat mode. +/// - Fahrenheit. #include "ir_Kelvinator.h" #include @@ -27,7 +27,6 @@ #include "IRutils.h" // Constants - const uint16_t kKelvinatorTick = 85; const uint16_t kKelvinatorHdrMarkTicks = 106; const uint16_t kKelvinatorHdrMark = kKelvinatorHdrMarkTicks * kKelvinatorTick; @@ -71,15 +70,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_KELVINATOR -// Send a Kelvinator A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kKelvinatorStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Known working. -// +/// Send a Kelvinator A/C message. +/// Status: STABLE / Known working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendKelvinator(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kKelvinatorStateLength) @@ -122,18 +117,25 @@ void IRsend::sendKelvinator(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_KELVINATOR +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRKelvinatorAC::IRKelvinatorAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the internals of the object to a known good state. void IRKelvinatorAC::stateReset(void) { for (uint8_t i = 0; i < kKelvinatorStateLength; i++) remote_state[i] = 0x0; remote_state[3] = 0x50; remote_state[11] = 0x70; } +/// Set up hardware to be able to send a message. void IRKelvinatorAC::begin(void) { _irsend.begin(); } +/// Fix up any odd conditions for the current state. void IRKelvinatorAC::fixup(void) { // X-Fan mode is only valid in COOL or DRY modes. if (this->getMode() != kKelvinatorCool && this->getMode() != kKelvinatorDry) @@ -142,21 +144,33 @@ void IRKelvinatorAC::fixup(void) { } #if SEND_KELVINATOR +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRKelvinatorAC::send(const uint16_t repeat) { this->fixup(); // Ensure correct settings before sending. _irsend.sendKelvinator(remote_state, kKelvinatorStateLength, repeat); } #endif // SEND_KELVINATOR +/// Get the raw state of the object, suitable to be sent with the appropriate +/// IRsend object method. +/// @return A PTR to the internal state. uint8_t *IRKelvinatorAC::getRaw(void) { this->fixup(); // Ensure correct settings before sending. return remote_state; } +/// Set the raw state of the object. +/// @param[in] new_code The raw state from the native IR message. void IRKelvinatorAC::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kKelvinatorStateLength); } +/// Calculate the checksum for a given block of state. +/// @param[in] block A pointer to a block to calc the checksum of. +/// @param[in] length Length of the block array to checksum. +/// @return The calculated checksum value. +/// @note Many Bothans died to bring us this information. uint8_t IRKelvinatorAC::calcBlockChecksum(const uint8_t *block, const uint16_t length) { uint8_t sum = kKelvinatorChecksumStart; @@ -169,7 +183,8 @@ uint8_t IRKelvinatorAC::calcBlockChecksum(const uint8_t *block, return sum & 0b1111; } -// Many Bothans died to bring us this information. +/// Calculate the checksum for the internal state. +/// @param[in] length Length of the internal state to checksum. void IRKelvinatorAC::checksum(const uint16_t length) { // For each command + options block. for (uint16_t offset = 0; offset + 7 < length; offset += 8) { @@ -178,12 +193,10 @@ void IRKelvinatorAC::checksum(const uint16_t length) { } } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The size of the state. +/// @return A boolean indicating if it is valid. bool IRKelvinatorAC::validChecksum(const uint8_t state[], const uint16_t length) { for (uint16_t offset = 0; offset + 7 < length; offset += 8) { @@ -195,20 +208,27 @@ bool IRKelvinatorAC::validChecksum(const uint8_t state[], return true; } +/// Set the internal state to have the power on. void IRKelvinatorAC::on(void) { setPower(true); } +/// Set the internal state to have the power off. void IRKelvinatorAC::off(void) {setPower(false); } +/// Set the internal state to have the desired power. +/// @param[in] on The desired power state. void IRKelvinatorAC::setPower(const bool on) { setBit(&remote_state[0], kKelvinatorPowerOffset, on); remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk. } +/// Get the power setting from the internal state. +/// @return A boolean indicating if the power setting. bool IRKelvinatorAC::getPower(void) { return GETBIT8(remote_state[0], kKelvinatorPowerOffset); } -// Set the temp. in deg C +/// Set the temperature setting. +/// @param[in] degrees The temperature in degrees celsius. void IRKelvinatorAC::setTemp(const uint8_t degrees) { uint8_t temp = std::max(kKelvinatorMinTemp, degrees); temp = std::min(kKelvinatorMaxTemp, temp); @@ -216,13 +236,15 @@ void IRKelvinatorAC::setTemp(const uint8_t degrees) { remote_state[9] = remote_state[1]; // Duplicate to the 2nd command chunk. } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return Get current setting for temp. in degrees celsius. uint8_t IRKelvinatorAC::getTemp(void) { return GETBITS8(remote_state[1], kLowNibble, kNibbleSize) + kKelvinatorMinTemp; } -// Set the speed of the fan, 0-5, 0 is auto, 1-5 is the speed +/// Set the speed of the fan. +/// @param[in] speed 0 is auto, 1-5 is the speed void IRKelvinatorAC::setFan(const uint8_t speed) { uint8_t fan = std::min(kKelvinatorFanMax, speed); // Bounds check @@ -239,14 +261,20 @@ void IRKelvinatorAC::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRKelvinatorAC::getFan(void) { return GETBITS8(remote_state[14], kKelvinatorFanOffset, kKelvinatorFanSize); } +/// Get the current operation mode setting. +/// @return The current operation mode. uint8_t IRKelvinatorAC::getMode(void) { return GETBITS8(remote_state[0], kKelvinatorModeOffset, kModeBitsSize); } +/// Set the desired operation mode. +/// @param[in] mode The desired operation mode. void IRKelvinatorAC::setMode(const uint8_t mode) { switch (mode) { case kKelvinatorAuto: @@ -266,6 +294,8 @@ void IRKelvinatorAC::setMode(const uint8_t mode) { } } +/// Control the current vertical swing setting. +/// @param[in] on The desired setting. void IRKelvinatorAC::setSwingVertical(const bool on) { setBit(&remote_state[4], kKelvinatorVentSwingVOffset, on); setBit(&remote_state[0], kKelvinatorVentSwingOffset, @@ -273,10 +303,14 @@ void IRKelvinatorAC::setSwingVertical(const bool on) { remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk. } +/// Is the vertical swing setting on? +/// @return The current value. bool IRKelvinatorAC::getSwingVertical(void) { return GETBIT8(remote_state[4], kKelvinatorVentSwingVOffset); } +/// Control the current horizontal swing setting. +/// @param[in] on The desired setting. void IRKelvinatorAC::setSwingHorizontal(const bool on) { setBit(&remote_state[4], kKelvinatorVentSwingHOffset, on); setBit(&remote_state[0], kKelvinatorVentSwingOffset, @@ -284,57 +318,84 @@ void IRKelvinatorAC::setSwingHorizontal(const bool on) { remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk. } +/// Is the horizontal swing setting on? +/// @return The current value. bool IRKelvinatorAC::getSwingHorizontal(void) { return GETBIT8(remote_state[4], kKelvinatorVentSwingHOffset); } +/// Control the current Quiet setting. +/// @param[in] on The desired setting. void IRKelvinatorAC::setQuiet(const bool on) { setBit(&remote_state[12], kKelvinatorQuietOffset, on); } +/// Is the Quiet setting on? +/// @return The current value. bool IRKelvinatorAC::getQuiet(void) { return GETBIT8(remote_state[12], kKelvinatorQuietOffset); } +/// Control the current Ion Filter setting. +/// @param[in] on The desired setting. void IRKelvinatorAC::setIonFilter(const bool on) { setBit(&remote_state[2], kKelvinatorIonFilterOffset, on); remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk. } +/// Is the Ion Filter setting on? +/// @return The current value. bool IRKelvinatorAC::getIonFilter(void) { return GETBIT8(remote_state[2], kKelvinatorIonFilterOffset); } +/// Control the current Light setting. +/// i.e. The LED display on the A/C unit that shows the basic settings. +/// @param[in] on The desired setting. void IRKelvinatorAC::setLight(const bool on) { setBit(&remote_state[2], kKelvinatorLightOffset, on); remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk. } +/// Is the Light (Display) setting on? +/// @return The current value. bool IRKelvinatorAC::getLight(void) { return GETBIT8(remote_state[2], kKelvinatorLightOffset); } -// Note: XFan mode is only valid in Cool or Dry mode. +/// Control the current XFan setting. +/// This setting will cause the unit blow air after power off to dry out the +/// A/C device. +/// @note XFan mode is only valid in Cool or Dry mode. +/// @param[in] on The desired setting. void IRKelvinatorAC::setXFan(const bool on) { setBit(&remote_state[2], kKelvinatorXfanOffset, on); remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk. } +/// Is the XFan setting on? +/// @return The current value. bool IRKelvinatorAC::getXFan(void) { return GETBIT8(remote_state[2], kKelvinatorXfanOffset); } -// Note: Turbo mode is turned off if the fan speed is changed. +/// Control the current Turbo setting. +/// @note Turbo mode is turned off if the fan speed is changed. +/// @param[in] on The desired setting. void IRKelvinatorAC::setTurbo(const bool on) { setBit(&remote_state[2], kKelvinatorTurboOffset, on); remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk. } +/// Is the Turbo setting on? +/// @return The current value. bool IRKelvinatorAC::getTurbo(void) { return GETBIT8(remote_state[2], kKelvinatorTurboOffset); } -// Convert a standard A/C mode into its native mode. +/// Convert a standard A/C mode (stdAc::opmode_t) into it a native mode. +/// @param[in] mode A stdAc::opmode_t operation mode. +/// @return The native mode equivilant. uint8_t IRKelvinatorAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kKelvinatorCool; @@ -345,7 +406,9 @@ uint8_t IRKelvinatorAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode to it's stdAc::opmode_t equivalent. +/// @param[in] mode A native operating mode value. +/// @return The stdAc::opmode_t equivilant. stdAc::opmode_t IRKelvinatorAC::toCommonMode(const uint8_t mode) { switch (mode) { case kKelvinatorCool: return stdAc::opmode_t::kCool; @@ -356,12 +419,15 @@ stdAc::opmode_t IRKelvinatorAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed to it's stdAc::fanspeed_t equivalent. +/// @param[in] speed A native fan speed value. +/// @return The stdAc::fanspeed_t equivilant. stdAc::fanspeed_t IRKelvinatorAC::toCommonFanSpeed(const uint8_t speed) { return (stdAc::fanspeed_t)speed; } -// Convert the A/C state to it's common equivalent. +/// Convert the internal A/C object state to it's stdAc::state_t equivalent. +/// @return A stdAc::state_t containing the current settings. stdAc::state_t IRKelvinatorAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::KELVINATOR; @@ -388,7 +454,8 @@ stdAc::state_t IRKelvinatorAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal settings into a human readable string. +/// @return A String. String IRKelvinatorAC::toString(void) { String result = ""; result.reserve(160); // Reserve some heap for the string to reduce fragging. @@ -410,18 +477,15 @@ String IRKelvinatorAC::toString(void) { } #if DECODE_KELVINATOR -// Decode the supplied Kelvinator message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kKelvinatorBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known working. +/// Decode the supplied Kelvinator message. +/// Status: STABLE / Known working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. bool IRrecv::decodeKelvinator(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.h b/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.h similarity index 89% rename from lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.h index cd3a000dd..a75f6b534 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Kelvinator.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.h @@ -1,6 +1,6 @@ -// Kelvinator A/C -// // Copyright 2016 David Conran +/// @file +/// @brief Support for Kelvinator A/C protocols. // Supports: // Brand: Kelvinator, Model: YALIF Remote @@ -133,14 +133,18 @@ const uint8_t kKelvinatorAutoTemp = 25; // 25C */ // Classes +/// Class for handling detailed Kelvinator A/C messages. class IRKelvinatorAC { public: explicit IRKelvinatorAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_KELVINATOR void send(const uint16_t repeat = kKelvinatorDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_KELVINATOR void begin(void); @@ -182,12 +186,13 @@ class IRKelvinatorAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kKelvinatorStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kKelvinatorStateLength]; ///< The state in IR code form. void checksum(const uint16_t length = kKelvinatorStateLength); void fixup(void); }; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_LG.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.7/src/ir_LG.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp index 1024548ca..65fe91883 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_LG.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp @@ -2,9 +2,11 @@ // Copyright 2015 cheaplin // Copyright 2017, 2018 David Conran -// Supports: -// Brand: LG, Model: 6711A20083V remote -// Brand: LG, Model: AKB74395308 remote +/// @file +/// @brief Support for LG protocols. +/// LG decode originally added by Darryl Smith (based on the JVC protocol) +/// LG send originally added by https://github.com/chaeplin +/// @see https://github.com/arendst/Tasmota/blob/54c2eb283a02e4287640a4595e506bc6eadbd7f2/sonoff/xdrv_05_irremote.ino#L327-438 #include "ir_LG.h" #include @@ -22,8 +24,6 @@ using irutils::addTempToString; using irutils::setBit; using irutils::setBits; -// LG decode originally added by Darryl Smith (based on the JVC protocol) -// LG send originally added by https://github.com/chaeplin // Constants const uint16_t kLgTick = 50; @@ -58,34 +58,14 @@ const uint16_t kLg2HdrSpace = kLg2HdrSpaceTicks * kLgTick; // 9850 const uint16_t kLg2BitMarkTicks = 10; const uint16_t kLg2BitMark = kLg2BitMarkTicks * kLgTick; // 500 -#if (SEND_LG || DECODE_LG) -// Calculate the rolling 4-bit wide checksum over all of the data. -// Args: -// data: The value to be checksum'ed. -// Returns: -// A 4-bit checksum. -uint8_t calcLGChecksum(uint16_t data) { - return (((data >> 12) + ((data >> 8) & 0xF) + ((data >> 4) & 0xF) + - (data & 0xF)) & - 0xF); -} -#endif - #if SEND_LG -// Send an LG formatted message. -// -// Args: -// data: The contents of the message you want to send. -// nbits: The bit size of the message being sent. -// Typically kLgBits or kLg32Bits. -// repeat: The number of times you want the message to be repeated. -// -// Status: Beta / Should be working. -// -// Notes: -// LG has a separate message to indicate a repeat, like NEC does. -// Supports: -// IR Remote models: 6711A20083V +/// Send an LG formatted message. (LG) +/// Status: Beta / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// Typically kLgBits or kLg32Bits. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note LG has a separate message to indicate a repeat, like NEC does. void IRsend::sendLG(uint64_t data, uint16_t nbits, uint16_t repeat) { uint16_t repeatHeaderMark = 0; uint8_t duty = kDutyDefault; @@ -113,20 +93,13 @@ void IRsend::sendLG(uint64_t data, uint16_t nbits, uint16_t repeat) { 38, true, repeat - 1, duty); } -// Send an LG Variant-2 formatted message. -// -// Args: -// data: The contents of the message you want to send. -// nbits: The bit size of the message being sent. -// Typically kLgBits or kLg32Bits. -// repeat: The number of times you want the message to be repeated. -// -// Status: Beta / Should be working. -// -// Notes: -// LG has a separate message to indicate a repeat, like NEC does. -// Supports: -// IR Remote models: AKB74395308 +/// Send an LG Variant-2 formatted message. (LG2) +/// Status: Beta / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// Typically kLgBits or kLg32Bits. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note LG has a separate message to indicate a repeat, like NEC does. void IRsend::sendLG2(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits >= kLg32Bits) { // Let the original routine handle it. @@ -149,52 +122,35 @@ void IRsend::sendLG2(uint64_t data, uint16_t nbits, uint16_t repeat) { 38, true, repeat - 1, 50); } -// Construct a raw 28-bit LG message code from the supplied address & command. -// -// Args: -// address: The address code. -// command: The command code. -// Returns: -// A raw 28-bit LG message code suitable for sendLG() etc. -// -// Status: STABLE / Works. -// -// Notes: -// e.g. Sequence of bits = address + command + checksum. +/// Construct a raw 28-bit LG message code from the supplied address & command. +/// Status: STABLE / Works. +/// @param[in] address The address code. +/// @param[in] command The command code. +/// @return A raw 28-bit LG message code suitable for sendLG() etc. +/// @note Sequence of bits = address + command + checksum. uint32_t IRsend::encodeLG(uint16_t address, uint16_t command) { - return ((address << 20) | (command << 4) | calcLGChecksum(command)); + return ((address << 20) | (command << 4) | irutils::sumNibbles(command, 4)); } -#endif +#endif // SEND_LG #if DECODE_LG -// Decode the supplied LG message. -// LG protocol has a repeat code which is 4 items long. -// Even though the protocol has 28/32 bits of data, only 24/28 bits are -// distinct. -// In transmission order, the 28/32 bits are constructed as follows: -// 8/12 bits of address + 16 bits of command + 4 bits of checksum. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kLgBits or kLg32Bits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Note: -// LG 32bit protocol appears near identical to the Samsung protocol. -// They possibly differ on how they repeat and initial HDR mark. -// -// Supports: -// IR Remote models: 6711A20083V, AKB74395308 - -// Ref: -// https://funembedded.wordpress.com/2014/11/08/ir-remote-control-for-lg-conditioner-using-stm32f302-mcu-on-mbed-platform/ +/// Decode the supplied LG message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// Typically kLgBits or kLg32Bits. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note LG protocol has a repeat code which is 4 items long. +/// Even though the protocol has 28/32 bits of data, only 24/28 bits are +/// distinct. +/// In transmission order, the 28/32 bits are constructed as follows: +/// 8/12 bits of address + 16 bits of command + 4 bits of checksum. +/// @note LG 32bit protocol appears near identical to the Samsung protocol. +/// They possibly differ on how they repeat and initial HDR mark. +/// @see https://funembedded.wordpress.com/2014/11/08/ir-remote-control-for-lg-conditioner-using-stm32f302-mcu-on-mbed-platform/ bool IRrecv::decodeLG(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (nbits >= kLg32Bits) { @@ -279,7 +235,7 @@ bool IRrecv::decodeLG(decode_results *results, uint16_t offset, // Compliance uint16_t command = (data >> 4) & 0xFFFF; // The 16 bits before the checksum. - if (strict && (data & 0xF) != calcLGChecksum(command)) + if (strict && (data & 0xF) != irutils::sumNibbles(command, 4)) return false; // The last 4 bits sent are the expected checksum. // Success if (isLg2) @@ -295,21 +251,27 @@ bool IRrecv::decodeLG(decode_results *results, uint16_t offset, #endif // LG A/C Class -// Support for LG-type A/C units. -// Ref: -// https://github.com/arendst/Tasmota/blob/54c2eb283a02e4287640a4595e506bc6eadbd7f2/sonoff/xdrv_05_irremote.ino#L327-438 + +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRLgAc::IRLgAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the internals of the object to a known good state. void IRLgAc::stateReset(void) { setRaw(kLgAcOffCommand); setModel(lg_ac_remote_model_t::GE6711AR2853M); } +/// Set up hardware to be able to send a message. void IRLgAc::begin(void) { _irsend.begin(); } #if SEND_LG +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRLgAc::send(const uint16_t repeat) { if (this->getPower()) _irsend.send(this->_protocol, this->getRaw(), kLgBits, repeat); @@ -320,6 +282,8 @@ void IRLgAc::send(const uint16_t repeat) { } #endif // SEND_LG +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRLgAc::setModel(const lg_ac_remote_model_t model) { switch (model) { case lg_ac_remote_model_t::AKB75215403: @@ -332,6 +296,8 @@ void IRLgAc::setModel(const lg_ac_remote_model_t model) { } } +/// Get the model of the A/C. +/// @return The enum of the compatible model. lg_ac_remote_model_t IRLgAc::getModel(void) { switch (_protocol) { case LG2: @@ -343,45 +309,50 @@ lg_ac_remote_model_t IRLgAc::getModel(void) { } } +/// Get a copy of the internal state/code for this protocol. +/// @return The code for this protocol based on the current internal state. uint32_t IRLgAc::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRLgAc::setRaw(const uint32_t new_code) { remote_state = new_code; _temp = 15; // Ensure there is a "sane" previous temp. _temp = getTemp(); } -// Calculate the checksum for a given state. -// Args: -// state: The value to calculate the checksum of. -// Returns: -// A uint8_t of the checksum. +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return The calculated checksum value. uint8_t IRLgAc::calcChecksum(const uint32_t state) { - return calcLGChecksum(state >> 4); + return irutils::sumNibbles(state >> 4, 4); } -// Verify the checksum is valid for a given state. -// Args: -// state: The value to verify the checksum of. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The value to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRLgAc::validChecksum(const uint32_t state) { return calcChecksum(state) == GETBITS32(state, kLgAcChecksumOffset, kLgAcChecksumSize); } +/// Calculate and set the checksum values for the internal state. void IRLgAc::checksum(void) { setBits(&remote_state, kLgAcChecksumOffset, kLgAcChecksumSize, calcChecksum(remote_state)); } +/// Change the power setting to On. void IRLgAc::on(void) { setPower(true); } +/// Change the power setting to Off. void IRLgAc::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRLgAc::setPower(const bool on) { setBits(&remote_state, kLgAcPowerOffset, kLgAcPowerSize, on ? kLgAcPowerOn : kLgAcPowerOff); @@ -391,17 +362,22 @@ void IRLgAc::setPower(const bool on) { _setTemp(0); // Off clears the temp. } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRLgAc::getPower(void) { return GETBITS32(remote_state, kLgAcPowerOffset, kLgAcPowerSize) == kLgAcPowerOn; } -// Set the temp. (Internal use only) +/// Set the temperature. +/// @param[in] value The native temperature. +/// @note Internal use only. void IRLgAc::_setTemp(const uint8_t value) { setBits(&remote_state, kLgAcTempOffset, kLgAcTempSize, value); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRLgAc::setTemp(const uint8_t degrees) { uint8_t temp = std::max(kLgAcMinTemp, degrees); temp = std::min(kLgAcMaxTemp, temp); @@ -409,7 +385,8 @@ void IRLgAc::setTemp(const uint8_t degrees) { _setTemp(temp - kLgAcTempAdjust); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRLgAc::getTemp(void) { if (getPower()) return GETBITS32(remote_state, kLgAcTempOffset, kLgAcTempSize) + @@ -418,7 +395,8 @@ uint8_t IRLgAc::getTemp(void) { return _temp; } -// Set the speed of the fan. +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRLgAc::setFan(const uint8_t speed) { switch (speed) { case kLgAcFanAuto: @@ -432,14 +410,20 @@ void IRLgAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRLgAc::getFan(void) { return GETBITS32(remote_state, kLgAcFanOffset, kLgAcFanSize); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRLgAc::getMode(void) { return GETBITS32(remote_state, kLgAcModeOffset, kLgAcModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRLgAc::setMode(const uint8_t mode) { switch (mode) { case kLgAcAuto: @@ -454,7 +438,9 @@ void IRLgAc::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRLgAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kLgAcCool; @@ -465,7 +451,9 @@ uint8_t IRLgAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRLgAc::toCommonMode(const uint8_t mode) { switch (mode) { case kLgAcCool: return stdAc::opmode_t::kCool; @@ -476,7 +464,9 @@ stdAc::opmode_t IRLgAc::toCommonMode(const uint8_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRLgAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -488,7 +478,9 @@ uint8_t IRLgAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRLgAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kLgAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -498,7 +490,8 @@ stdAc::fanspeed_t IRLgAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRLgAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::LG; @@ -523,7 +516,8 @@ stdAc::state_t IRLgAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRLgAc::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. @@ -539,6 +533,8 @@ String IRLgAc::toString(void) { return result; } +/// Check if the internal state looks like a valud LG A/C message. +/// @return true, the internal state is a valid LG A/C mesg. Otherwise, false. bool IRLgAc::isValidLgAc(void) { return validChecksum(remote_state) && (GETBITS32(remote_state, kLgAcSignatureOffset, kLgAcSignatureSize) == diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_LG.h b/lib/IRremoteESP8266-2.7.8/src/ir_LG.h similarity index 78% rename from lib/IRremoteESP8266-2.7.7/src/ir_LG.h rename to lib/IRremoteESP8266-2.7.8/src/ir_LG.h index 64b6a0b7c..bf0cdd0b6 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_LG.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_LG.h @@ -1,8 +1,13 @@ // Copyright 2017, 2019 David Conran +/// @file +/// @brief Support for LG protocols. +/// @see https://github.com/arendst/Tasmota/blob/54c2eb283a02e4287640a4595e506bc6eadbd7f2/sonoff/xdrv_05_irremote.ino#L327-438 + + // Supports: -// Brand: LG, Model: 6711A20083V remote -// Brand: LG, Model: AKB74395308 remote +// Brand: LG, Model: 6711A20083V remote (LG) +// Brand: LG, Model: AKB74395308 remote (LG2) // Brand: LG, Model: S4-W12JA3AA A/C (LG2) // Brand: LG, Model: AKB75215403 remote (LG2) // Brand: General Electric, Model: AG1BH09AW101 Split A/C @@ -53,20 +58,22 @@ const uint8_t kLgAcSignature = 0x88; const uint32_t kLgAcOffCommand = 0x88C0051; -uint8_t calcLGChecksum(uint16_t data); - // Classes +/// Class for handling detailed LG A/C messages. class IRLgAc { public: explicit IRLgAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); static uint8_t calcChecksum(const uint32_t state); static bool validChecksum(const uint32_t state); bool isValidLgAc(void); #if SEND_LG void send(const uint16_t repeat = kLgDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_LG void begin(void); @@ -93,12 +100,13 @@ class IRLgAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint32_t remote_state; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint32_t remote_state; ///< The state of the IR remote in IR code form. uint8_t _temp; decode_type_t _protocol; void checksum(void); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Lasertag.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Lasertag.cpp similarity index 67% rename from lib/IRremoteESP8266-2.7.7/src/ir_Lasertag.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Lasertag.cpp index 14a059084..5285acd4a 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Lasertag.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Lasertag.cpp @@ -1,5 +1,11 @@ // Copyright 2017 David Conran -// Lasertag + +/// @file +/// @brief Support for Lasertag protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/366 + +// Supports: +// Brand: Lasertag, Model: Phaser emitters #include #include "IRrecv.h" @@ -17,16 +23,13 @@ const int16_t kSpace = 1; const int16_t kMark = 0; #if SEND_LASERTAG -// Send a Lasertag packet. -// This protocol is pretty much just raw Manchester encoding. -// -// Args: -// data: The message you wish to send. -// nbits: Bit size of the protocol you want to send. -// repeat: Nr. of extra times the data will be sent. -// -// Status: STABLE / Working. -// +/// Send a Lasertag packet/message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol is pretty much just raw Manchester encoding. +/// @todo Convert this to use `sendManchester()` if we can.` void IRsend::sendLasertag(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits > sizeof(data) * 8) return; // We can't send something that big. @@ -51,24 +54,19 @@ void IRsend::sendLasertag(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_LASERTAG #if DECODE_LASERTAG -// Decode the supplied Lasertag message. -// This protocol is pretty much just raw Manchester encoding. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Appears to be working 90% of the time. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -// https://en.wikipedia.org/wiki/Manchester_code +/// Decode the supplied Lasertag message. +/// Status: BETA / Appears to be working 90% of the time. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol is pretty much just raw Manchester encoding. +/// @see http://www.sbprojects.com/knowledge/ir/rc5.php +/// @see https://en.wikipedia.org/wiki/RC-5 +/// @see https://en.wikipedia.org/wiki/Manchester_code +/// @todo Convert to using `matchManchester()` if we can. bool IRrecv::decodeLasertag(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= kLasertagMinSamples + offset) return false; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Lego.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Lego.cpp similarity index 72% rename from lib/IRremoteESP8266-2.7.7/src/ir_Lego.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Lego.cpp index b2d2f2d0e..3b7144768 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Lego.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Lego.cpp @@ -1,19 +1,19 @@ // Copyright 2019 David Conran +/// @file +/// @brief Support for LEGO protocols. +/// @note LEGO is a Registrated Trademark of the Lego Group. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/641 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/files/2974525/LEGO_Power_Functions_RC_v120.pdf + +// Supports: +// Brand: LEGO Power Functions, Model: IR Receiver + #include #include "IRrecv.h" #include "IRsend.h" #include "IRutils.h" -// LEGO -// (LEGO is a Registrated Trademark of the Lego Group.) -// -// Supports: -// Brand: LEGO Power Functions, Model: IR Receiver -// -// Ref: -// - https://github.com/crankyoldgit/IRremoteESP8266/issues/641 -// - https://github.com/crankyoldgit/IRremoteESP8266/files/2974525/LEGO_Power_Functions_RC_v120.pdf // Constants const uint16_t kLegoPfBitMark = 158; @@ -24,15 +24,12 @@ const uint32_t kLegoPfMinCommandLength = 16000; // 16ms #if SEND_LEGOPF -// Send a LEGO Power Functions message. -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kLegoPfBits. -// repeat: Nr. of additional times the message is to be sent. -// Note: Non-zero repeats results in at least 5 messages per spec. -// -// Status: Beta / Should work. +/// Send a LEGO Power Functions message. +/// Status: Beta / Should work. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note Non-zero repeats results in at least 5 messages per spec. void IRsend::sendLegoPf(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { uint8_t channelid = ((data >> (nbits - 4)) & 0b11) + 1; @@ -63,18 +60,14 @@ void IRsend::sendLegoPf(const uint64_t data, const uint16_t nbits, #endif // SEND_LEGO #if DECODE_LEGOPF -// Decode the supplied LEGO Power Functions message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kLegoPfBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Appears to work. +/// Decode the supplied LEGO Power Functions message. +/// Status: STABLE / Appears to work. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeLegoPf(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { // Check if can possibly be a valid LEGO message. diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Lutron.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Lutron.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.7/src/ir_Lutron.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Lutron.cpp index 8ea4f0b3a..5d0424784 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Lutron.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Lutron.cpp @@ -1,5 +1,20 @@ // Copyright 2018 David Conran -// Lutron + +/// @file +/// @brief Support for Lutron protocols. +/// @note The Lutron protocol uses a sort of Run Length encoding to encode +/// its data. There is no header or footer per-se. +/// As a mark is the first data we will notice, we always assume the First +/// bit of the technically 36-bit protocol is '1'. So it is assumed, and thus +/// we only care about the 35 bits of data. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/515 +/// @see http://www.lutron.com/TechnicalDocumentLibrary/048158.doc + +// Supports: +// Brand: Lutron, Model: SP-HT remote +// Brand: Lutron, Model: MIR-ITFS remote +// Brand: Lutron, Model: MIR-ITFS-LF remote +// Brand: Lutron, Model: MIR-ITFS-F remote #define __STDC_LIMIT_MACROS #include @@ -8,36 +23,21 @@ #include "IRsend.h" #include "IRutils.h" -// Notes: -// The Lutron protocol uses a sort of Run Length encoding to encode -// its data. There is no header or footer per-se. -// As a mark is the first data we will notice, we always assume the First -// bit of the technically 36-bit protocol is '1'. So it is assumed, and thus -// we only care about the 35 bits of data. // Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/515 const uint16_t kLutronTick = 2288; const uint32_t kLutronGap = 150000; // Completely made up value. const uint16_t kLutronDelta = 400; // +/- 300 usecs. #if SEND_LUTRON -// Send a Lutron formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. Typically kLutronBits -// repeat: The number of times the command is to be repeated. -// -// Status: Stable / Appears to be working for real devices. - -// Notes: -// Protocol is really 36 bits long, but the first bit is always a 1. -// So, assume the 1 and only have a normal payload of 35 bits. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/515 +/// Send a Lutron formatted message. +/// Status: Stable / Appears to be working for real devices. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note The protocol is really 36 bits long, but the first bit is always a 1. +/// So, assume the 1 and only have a normal payload of 35 bits. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/515 void IRsend::sendLutron(uint64_t data, uint16_t nbits, uint16_t repeat) { enableIROut(40000, 40); // 40Khz & 40% dutycycle. for (uint16_t r = 0; r <= repeat; r++) { @@ -54,23 +54,14 @@ void IRsend::sendLutron(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_LUTRON #if DECODE_LUTRON -// Decode the supplied Lutron message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kLutronBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Notes: -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/515 +/// Decode the supplied Lutron message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeLutron(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Technically the smallest number of entries for the smallest message is '1'. diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_MWM.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_MWM.cpp similarity index 80% rename from lib/IRremoteESP8266-2.7.7/src/ir_MWM.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_MWM.cpp index eefc4a57e..8aca4a4fd 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_MWM.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_MWM.cpp @@ -1,8 +1,12 @@ // Copyright 2018 Brett T. Warden -// MWM +/// @file +/// @brief Disney Made With Magic (MWM) Support +/// derived from ir_Lasertag.cpp +/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/557 -// derived from ir_Lasertag.cpp, Copyright 2017 David Conran +// Supports: +// Brand: Disney, Model: Made With Magic (Glow With The Show) wand #include #include "IRrecv.h" @@ -23,17 +27,13 @@ const int16_t kSpace = 1; const int16_t kMark = 0; #if SEND_MWM -// Send a MWM packet. -// This protocol is 2400 bps serial, 1 start bit (mark), 1 stop bit (space), no -// parity -// -// Args: -// data: The message you wish to send. -// nbits: Bit size of the protocol you want to send. -// repeat: Nr. of extra times the data will be sent. -// -// Status: Implemented. -// +/// Send a MWM packet/message. +/// Status: Implemented. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol is 2400 bps serial, 1 start bit (mark), +/// 1 stop bit (space), no parity void IRsend::sendMWM(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < 3) return; // Shortest possible message is 3 bytes @@ -68,21 +68,16 @@ void IRsend::sendMWM(const uint8_t data[], const uint16_t nbytes, #endif // SEND_MWM #if DECODE_MWM -// Decode the supplied MWM message. -// This protocol is 2400 bps serial, 1 start bit (mark), 1 stop bit (space), no -// parity -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Implemented. -// +/// Decode the supplied MWM message. +/// Status: Implemented. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol is 2400 bps serial, 1 start bit (mark), +/// 1 stop bit (space), no parity bool IRrecv::decodeMWM(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { DPRINTLN("DEBUG: decodeMWM"); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.cpp similarity index 63% rename from lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.cpp index 2c15612f4..3f79a18f6 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.cpp @@ -2,6 +2,11 @@ // Copyright 2015 kitlaan // Copyright 2017 Jason kendall, David Conran +/// @file +/// @brief Support for MagiQuest protocols. +/// @see https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp +/// @see https://github.com/mpflaga/Arduino-IRremote + #include "ir_Magiquest.h" #include #include "IRrecv.h" @@ -11,25 +16,14 @@ #define IS_ZERO(m, s) (((m)*100 / ((m) + (s))) <= kMagiQuestZeroRatio) #define IS_ONE(m, s) (((m)*100 / ((m) + (s))) >= kMagiQuestOneRatio) -// Strips taken from: -// https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp -// and -// https://github.com/mpflaga/Arduino-IRremote - -// Source: https://github.com/mpflaga/Arduino-IRremote - #if SEND_MAGIQUEST -// Send a MagiQuest formatted message. -// -// Args: -// data: The contents of the message you want to send. -// nbits: The bit size of the message being sent. -// Typically kMagiquestBits. -// repeat: The number of times you want the message to be repeated. -// -// Status: Alpha / Should be working. -// -void IRsend::sendMagiQuest(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a MagiQuest formatted message. +/// Status: Beta / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +void IRsend::sendMagiQuest(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { sendGeneric(0, 0, // No Headers - Technically it's included in the data. // i.e. 8 zeros. kMagiQuestMarkOne, kMagiQuestSpaceOne, kMagiQuestMarkZero, @@ -38,11 +32,15 @@ void IRsend::sendMagiQuest(uint64_t data, uint16_t nbits, uint16_t repeat) { kMagiQuestGap, data, nbits, 36, true, repeat, 50); } -// Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. -// (Only 48 bits of real data + 8 leading zero bits) -// This is suitable for calling sendMagiQuest() with. -// e.g. sendMagiQuest(encodeMagiQuest(wand_id, magnitude)); -uint64_t IRsend::encodeMagiQuest(uint32_t wand_id, uint16_t magnitude) { +/// Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. +/// (Only 48 bits of real data + 8 leading zero bits) +/// This is suitable for calling sendMagiQuest() with. +/// e.g. sendMagiQuest(encodeMagiQuest(wand_id, magnitude)) +/// @param[in] wand_id The value for the wand ID. +/// @param[in] magnitude The value for the magnitude +/// @return A code suitable for calling sendMagiQuest() with. +uint64_t IRsend::encodeMagiQuest(const uint32_t wand_id, + const uint16_t magnitude) { uint64_t result = 0; result = wand_id; result <<= 16; @@ -51,34 +49,23 @@ uint64_t IRsend::encodeMagiQuest(uint32_t wand_id, uint16_t magnitude) { result &= 0xFFFFFFFFFFFFULL; return result; } -#endif - -// Source: -// https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp +#endif // SEND_MAGIQUEST #if DECODE_MAGIQUEST -// Decode the supplied MagiQuest message. -// MagiQuest protocol appears to be a header of 8 'zero' bits, followed -// by 32 bits of "wand ID" and finally 16 bits of "magnitude". -// Even though we describe this protocol as 56 bits, it really only has -// 48 bits of data that matter. -// -// In transmission order, 8 zeros + 32 wand_id + 16 magnitude. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion, inc. the 8 bit header. -// Typically kMagiquestBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Should work. -// -// Ref: -// https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp +/// Decode the supplied MagiQuest message. +/// Status: Beta / Should work. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note MagiQuest protocol appears to be a header of 8 'zero' bits, followed +/// by 32 bits of "wand ID" and finally 16 bits of "magnitude". +/// Even though we describe this protocol as 56 bits, it really only has +/// 48 bits of data that matter. +/// In transmission order, 8 zeros + 32 wand_id + 16 magnitude. +/// @see https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp bool IRrecv::decodeMagiQuest(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint16_t bits = 0; @@ -164,4 +151,4 @@ bool IRrecv::decodeMagiQuest(decode_results *results, uint16_t offset, results->command = data & 0xFFFF; // Magnitude return true; } -#endif +#endif // DECODE_MAGIQUEST diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.h b/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.h similarity index 73% rename from lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.h index 81fff53ad..399904375 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Magiquest.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.h @@ -2,6 +2,14 @@ // Copyright 2015 kitlaan // Copyright 2017 Jason kendall, David Conran +/// @file +/// @brief Support for MagiQuest protocols. +/// @see https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp +/// @see https://github.com/mpflaga/Arduino-IRremote + +// Supports: +// Brand: MagiQuest, Model: Wand + #ifndef IR_MAGIQUEST_H_ #define IR_MAGIQUEST_H_ @@ -10,7 +18,7 @@ #include "IRremoteESP8266.h" #include "IRsend.h" -// MagiQuest packet is both Wand ID and magnitude of swish and flick +/// MagiQuest packet is both Wand ID and magnitude of swish and flick union magiquest { uint64_t llword; uint8_t byte[8]; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Midea.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp similarity index 58% rename from lib/IRremoteESP8266-2.7.7/src/ir_Midea.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp index bbf9bedfa..5d270d3d4 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Midea.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp @@ -1,7 +1,12 @@ // Copyright 2017 bwze, crankyoldgit -// Midea +/// @file +/// @brief Support for Midea protocols. +/// Midea added by crankyoldgit & bwze. +/// send: bwze/crankyoldgit, decode: crankyoldgit +/// @see https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing #include "ir_Midea.h" +#include "ir_NEC.h" #include #ifndef ARDUINO #include @@ -11,16 +16,6 @@ #include "IRtext.h" #include "IRutils.h" -// Midea A/C added by (send) bwze/crankyoldgit & (decode) crankyoldgit -// -// Equipment it seems compatible with: -// * Pioneer System Model RYBO12GMFILCAD (12K BTU) -// * Pioneer System Model RUBO18GMFILCAD (18K BTU) -// * - -// Ref: -// https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing - // Constants const uint16_t kMideaTick = 80; const uint16_t kMideaBitMarkTicks = 7; @@ -37,6 +32,7 @@ const uint16_t kMideaMinGapTicks = kMideaHdrMarkTicks + kMideaZeroSpaceTicks + kMideaBitMarkTicks; const uint16_t kMideaMinGap = kMideaMinGapTicks * kMideaTick; const uint8_t kMideaTolerance = 30; // Percent +const uint16_t kMidea24MinGap = 13000; ///< uSecs using irutils::addBoolToString; using irutils::addFanToString; @@ -48,15 +44,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_MIDEA -// Send a Midea message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMideaBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: Alpha / Needs testing against a real device. -// +/// Send a Midea message +/// Status: Alpha / Needs testing against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendMidea(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits % 8 != 0) return; // nbits is required to be a multiple of 8. @@ -90,28 +82,31 @@ void IRsend::sendMidea(uint64_t data, uint16_t nbits, uint16_t repeat) { } } } -#endif +#endif // SEND_MIDEA // Code to emulate Midea A/C IR remote control unit. -// Warning: Consider this very alpha code. -// Initialise the object. +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRMideaAC::IRMideaAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRMideaAC::stateReset(void) { // Power On, Mode Auto, Fan Auto, Temp = 25C/77F remote_state = 0xA1826FFFFF62; _SwingVToggle = false; } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRMideaAC::begin(void) { _irsend.begin(); } #if SEND_MIDEA -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMideaAC::send(const uint16_t repeat) { this->checksum(); // Ensure correct checksum before sending. _irsend.sendMidea(remote_state, kMideaBits, repeat); @@ -123,37 +118,43 @@ void IRMideaAC::send(const uint16_t repeat) { } #endif // SEND_MIDEA -// Return a pointer to the internal state date of the remote. +/// Get a copy of the internal state/code for this protocol. +/// @return The code for this protocol based on the current internal state. uint64_t IRMideaAC::getRaw(void) { this->checksum(); return GETBITS64(remote_state, 0, kMideaBits); } -// Override the internal state with the new state. +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. void IRMideaAC::setRaw(const uint64_t newState) { remote_state = newState; } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRMideaAC::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMideaAC::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMideaAC::setPower(const bool on) { setBit(&remote_state, kMideaACPowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMideaAC::getPower(void) { return GETBIT64(remote_state, kMideaACPowerOffset); } -// Returns true if we want the A/C unit to work natively in Celsius. +/// Is the device currently using Celsius or the Fahrenheit temp scale? +/// @return true, the A/C unit uses Celsius natively, false, is Fahrenheit. bool IRMideaAC::getUseCelsius(void) { return !GETBIT64(remote_state, kMideaACCelsiusOffset); } -// Set the A/C unit to use Celsius natively. +/// Set the A/C unit to use Celsius natively. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMideaAC::setUseCelsius(const bool on) { if (on != getUseCelsius()) { // We need to change. uint8_t native_temp = getTemp(!on); // Get the old native temp. @@ -162,10 +163,9 @@ void IRMideaAC::setUseCelsius(const bool on) { } } -// Set the temperature. -// Args: -// temp: Temp. in degrees. -// useCelsius: Degree type to use. Celsius (true) or Fahrenheit (false) +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. +/// @param[in] useCelsius true, use the Celsius temp scale. false, is Fahrenheit void IRMideaAC::setTemp(const uint8_t temp, const bool useCelsius) { uint8_t max_temp = kMideaACMaxTempF; uint8_t min_temp = kMideaACMinTempF; @@ -184,11 +184,9 @@ void IRMideaAC::setTemp(const uint8_t temp, const bool useCelsius) { setBits(&remote_state, kMideaACTempOffset, kMideaACTempSize, new_temp); } -// Return the set temp. -// Args: -// celsius: Flag indicating if the results are in Celsius or Fahrenheit. -// Returns: -// A uint8_t containing the temperature. +/// Get the current temperature setting. +/// @param[in] celsius true, the results are in Celsius. false, in Fahrenheit. +/// @return The current setting for temp. in the requested units/scale. uint8_t IRMideaAC::getTemp(const bool celsius) { uint8_t temp = GETBITS64(remote_state, kMideaACTempOffset, kMideaACTempSize); if (getUseCelsius()) @@ -200,26 +198,27 @@ uint8_t IRMideaAC::getTemp(const bool celsius) { return temp; } -// Set the speed of the fan, -// 1-3 set the speed, 0 or anything else set it to auto. +/// Set the speed of the fan. +/// @param[in] fan The desired setting. 1-3 set the speed, 0 for auto. void IRMideaAC::setFan(const uint8_t fan) { setBits(&remote_state, kMideaACFanOffset, kMideaACFanSize, (fan > kMideaACFanHigh) ? kMideaACFanAuto : fan); } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRMideaAC::getFan(void) { return GETBITS64(remote_state, kMideaACFanOffset, kMideaACFanSize); } -// Get the requested climate operation mode of the a/c unit. -// Returns: -// A uint8_t containing the A/C mode. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMideaAC::getMode(void) { return GETBITS64(remote_state, kMideaACModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMideaAC::setMode(const uint8_t mode) { switch (mode) { case kMideaACAuto: @@ -234,35 +233,38 @@ void IRMideaAC::setMode(const uint8_t mode) { } } -// Set the Sleep state of the A/C. +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMideaAC::setSleep(const bool on) { setBit(&remote_state, kMideaACSleepOffset, on); } -// Return the Sleep state of the A/C. +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMideaAC::getSleep(void) { return GETBIT64(remote_state, kMideaACSleepOffset); } -// Set the A/C to toggle the vertical swing toggle for the next send. +/// Set the A/C to toggle the vertical swing toggle for the next send. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMideaAC::setSwingVToggle(const bool on) { _SwingVToggle = on; } -// Return if the message/state is just a Swing V toggle message/command. +/// Is the current state a vertical swing toggle message? +/// @return true, it is. false, it isn't. bool IRMideaAC::isSwingVToggle(void) { return remote_state == kMideaACToggleSwingV; } -// Return the Swing V toggle state of the A/C. +// Get the vertical swing toggle state of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMideaAC::getSwingVToggle(void) { _SwingVToggle |= isSwingVToggle(); return _SwingVToggle; } -// Calculate the checksum for a given array. -// Args: -// state: The state to calculate the checksum over. -// Returns: -// The 8 bit checksum value. +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return The calculated checksum value. uint8_t IRMideaAC::calcChecksum(const uint64_t state) { uint8_t sum = 0; uint64_t temp_state = state; @@ -275,23 +277,22 @@ uint8_t IRMideaAC::calcChecksum(const uint64_t state) { return reverseBits(sum, 8); } -// Verify the checksum is valid for a given state. -// Args: -// state: The state to verify the checksum of. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRMideaAC::validChecksum(const uint64_t state) { return GETBITS64(state, 0, 8) == calcChecksum(state); } -// Calculate & set the checksum for the current internal state of the remote. +/// Calculate & set the checksum for the current internal state of the remote. void IRMideaAC::checksum(void) { // Stored the checksum value in the last byte. setBits(&remote_state, 0, 8, calcChecksum(remote_state)); } - -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMideaAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMideaACCool; @@ -302,7 +303,9 @@ uint8_t IRMideaAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMideaAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -314,7 +317,9 @@ uint8_t IRMideaAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMideaAC::toCommonMode(const uint8_t mode) { switch (mode) { case kMideaACCool: return stdAc::opmode_t::kCool; @@ -325,7 +330,9 @@ stdAc::opmode_t IRMideaAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMideaAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMideaACFanHigh: return stdAc::fanspeed_t::kMax; @@ -335,26 +342,28 @@ stdAc::fanspeed_t IRMideaAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @param[in] prev A Ptr to the previous state. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) { stdAc::state_t result; if (prev != NULL) { result = *prev; } else { - // Fixed/Not supported/Non-zero defaults. - result.protocol = decode_type_t::MIDEA; - result.model = -1; // No models used. - result.swingh = stdAc::swingh_t::kOff; - result.swingv = stdAc::swingv_t::kOff; - result.quiet = false; - result.turbo = false; - result.clean = false; - result.econo = false; - result.filter = false; - result.light = false; - result.beep = false; - result.sleep = -1; - result.clock = -1; + // Fixed/Not supported/Non-zero defaults. + result.protocol = decode_type_t::MIDEA; + result.model = -1; // No models used. + result.swingh = stdAc::swingh_t::kOff; + result.swingv = stdAc::swingv_t::kOff; + result.quiet = false; + result.turbo = false; + result.clean = false; + result.econo = false; + result.filter = false; + result.light = false; + result.beep = false; + result.sleep = -1; + result.clock = -1; } if (this->isSwingVToggle()) { result.swingv = result.swingv != stdAc::swingv_t::kOff ? @@ -370,7 +379,8 @@ stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRMideaAC::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -393,19 +403,15 @@ String IRMideaAC::toString(void) { } #if DECODE_MIDEA -// Decode the supplied Midea message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kMideaBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Needs testing against a real device. -// +/// Decode the supplied Midea message. +/// Status: Alpha / Needs testing against a real device. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, +/// kHitachiAc344Bits +/// @param[in] strict Flag indicating if we should perform strict matching. bool IRrecv::decodeMidea(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint8_t min_nr_of_messages = 1; @@ -458,3 +464,80 @@ bool IRrecv::decodeMidea(decode_results *results, uint16_t offset, return true; } #endif // DECODE_MIDEA + +#if SEND_MIDEA24 +/// Send a Midea24 formatted message. +/// Status: STABLE / Confirmed working on a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1170 +/// @note This protocol is basically a 48-bit version of the NEC protocol with +/// alternate bytes inverted, thus only 24 bits of real data, and with at +/// least a single repeat. +/// @warning Can't be used beyond 32 bits. +void IRsend::sendMidea24(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + uint64_t newdata = 0; + // Construct the data into bye & inverted byte pairs. + for (int16_t i = nbits - 8; i >= 0; i -= 8) { + // Shuffle the data to be sent so far. + newdata <<= 16; + uint8_t next = GETBITS64(data, i, 8); + newdata |= ((next << 8) | (next ^ 0xFF)); + } + sendNEC(newdata, nbits * 2, repeat); +} +#endif // SEND_MIDEA24 + +#if DECODE_MIDEA24 +/// Decode the supplied Midea24 message. +/// Status: STABLE / Confirmed working on a real device. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @note This protocol is basically a 48-bit version of the NEC protocol with +/// alternate bytes inverted, thus only 24 bits of real data. +/// @warning Can't be used beyond 32 bits. +bool IRrecv::decodeMidea24(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + // Not strictly a MIDEA24 message. + if (strict && nbits != kMidea24Bits) return false; + if (nbits > 32) return false; // Can't successfully match something that big. + + uint64_t longdata = 0; + if (!matchGeneric(results->rawbuf + offset, &longdata, + results->rawlen - offset, nbits * 2, + kNecHdrMark, kNecHdrSpace, + kNecBitMark, kNecOneSpace, + kNecBitMark, kNecZeroSpace, + kNecBitMark, kMidea24MinGap, true)) return false; + + // Build the result by checking every second byte is a complement(inversion) + // of the previous one. + uint32_t data = 0; + for (uint8_t i = nbits * 2; i >= 16;) { + // Shuffle the data collected so far. + data <<= 8; + i -= 8; + uint8_t current = GETBITS64(longdata, i, 8); + i -= 8; + uint8_t next = GETBITS64(longdata, i, 8); + // Check they are an inverted pair. + if (current != (next ^ 0xFF)) return false; // They are not, so abort. + data |= current; + } + + // Success + results->decode_type = decode_type_t::MIDEA24; + results->bits = nbits; + results->value = data; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_MIDEA24 diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Midea.h b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.h similarity index 76% rename from lib/IRremoteESP8266-2.7.7/src/ir_Midea.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Midea.h index be43a4df6..b7825f569 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Midea.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.h @@ -1,11 +1,16 @@ // Copyright 2017 David Conran -// Midea + +/// @file +/// @brief Support for Midea protocols. +/// Midea added by crankyoldgit & bwze +/// @see https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing // Supports: -// Brand: Pioneer System, Model: RYBO12GMFILCAD A/C (12K BTU) -// Brand: Pioneer System, Model: RUBO18GMFILCAD A/C (18K BTU) -// Brand: Comfee, Model: MPD1-12CRN7 A/C -// Brand: Keystone, Model: RG57H4(B)BGEF remote +// Brand: Pioneer System, Model: RYBO12GMFILCAD A/C (12K BTU) (MIDEA) +// Brand: Pioneer System, Model: RUBO18GMFILCAD A/C (18K BTU) (MIDEA) +// Brand: Comfee, Model: MPD1-12CRN7 A/C (MIDEA) +// Brand: Keystone, Model: RG57H4(B)BGEF remote (MIDEA) +// Brand: Midea, Model: FS40-7AR Stand Fan (MIDEA24) #ifndef IR_MIDEA_H_ #define IR_MIDEA_H_ @@ -21,10 +26,6 @@ #include "IRsend_test.h" #endif -// Midea added by crankyoldgit & bwze -// Ref: -// https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing - // Constants const uint8_t kMideaACTempOffset = 24; const uint8_t kMideaACTempSize = 5; // Bits @@ -66,14 +67,20 @@ const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C; #define MIDEA_AC_MIN_TEMP_C kMideaACMinTempC #define MIDEA_AC_MAX_TEMP_C kMideaACMaxTempC +// Classes +/// Class for handling detailed Midea A/C messages. +/// @warning Consider this very alpha code. class IRMideaAC { public: explicit IRMideaAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_MIDEA void send(const uint16_t repeat = kMideaMinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MIDEA void begin(void); @@ -106,11 +113,13 @@ class IRMideaAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint64_t remote_state; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint64_t remote_state; ///< The state of the IR remote in IR code form. bool _SwingVToggle; void checksum(void); static uint8_t calcChecksum(const uint64_t state); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.cpp index b8d62e109..1f9f25c1e 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.cpp @@ -3,7 +3,18 @@ // Copyright 2019 Mark Kuchel // Copyright 2018 Denes Varga -// Mitsubishi +/// @file +/// @brief Support for Mitsubishi protocols. +/// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote +/// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran +/// @see GlobalCache's Control Tower's Mitsubishi TV data. +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/441 +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L84 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/619 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/888 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/947 +/// @see https://github.com/kuchel77 #include "ir_Mitsubishi.h" #include @@ -17,15 +28,9 @@ #include "IRutils.h" #include "ir_Tcl.h" -// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote -// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran - // Constants // Mitsubishi TV // period time is 1/33000Hz = 30.303 uSeconds (T) -// Ref: -// GlobalCache's Control Tower's Mitsubishi TV data. -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp const uint16_t kMitsubishiTick = 30; const uint16_t kMitsubishiBitMarkTicks = 10; const uint16_t kMitsubishiBitMark = kMitsubishiBitMarkTicks * kMitsubishiTick; @@ -41,9 +46,6 @@ const uint16_t kMitsubishiMinGapTicks = 936; const uint16_t kMitsubishiMinGap = kMitsubishiMinGapTicks * kMitsubishiTick; // Mitsubishi Projector (HC3000) -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/441 - const uint16_t kMitsubishi2HdrMark = 8400; const uint16_t kMitsubishi2HdrSpace = kMitsubishi2HdrMark / 2; const uint16_t kMitsubishi2BitMark = 560; @@ -52,9 +54,6 @@ const uint16_t kMitsubishi2OneSpace = kMitsubishi2ZeroSpace * 3; const uint16_t kMitsubishi2MinGap = 28500; // Mitsubishi A/C -// Ref: -// https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L84 - const uint16_t kMitsubishiAcHdrMark = 3400; const uint16_t kMitsubishiAcHdrSpace = 1750; const uint16_t kMitsubishiAcBitMark = 450; @@ -65,9 +64,6 @@ const uint16_t kMitsubishiAcRptSpace = 17100; const uint8_t kMitsubishiAcExtraTolerance = 5; // Mitsubishi 136 bit A/C -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/888 - const uint16_t kMitsubishi136HdrMark = 3324; const uint16_t kMitsubishi136HdrSpace = 1474; const uint16_t kMitsubishi136BitMark = 467; @@ -76,9 +72,6 @@ const uint16_t kMitsubishi136ZeroSpace = 351; const uint32_t kMitsubishi136Gap = kDefaultMessageGap; // Mitsubishi 112 bit A/C -// Ref: -// https://github.com/kuchel77 - const uint16_t kMitsubishi112HdrMark = 3450; const uint16_t kMitsubishi112HdrSpace = 1696; const uint16_t kMitsubishi112BitMark = 450; @@ -100,20 +93,14 @@ using irutils::setBit; using irutils::setBits; #if SEND_MITSUBISHI -// Send a Mitsubishi message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMitsubishiBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE / Working. -// -// Notes: -// This protocol appears to have no header. -// Ref: -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp -// GlobalCache's Control Tower's Mitsubishi TV data. +/// Send the supplied Mitsubishi 16-bit message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol appears to have no header. +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp +/// @see GlobalCache's Control Tower's Mitsubishi TV data. void IRsend::sendMitsubishi(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(0, 0, // No Header kMitsubishiBitMark, kMitsubishiOneSpace, kMitsubishiBitMark, @@ -123,24 +110,16 @@ void IRsend::sendMitsubishi(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_MITSUBISHI #if DECODE_MITSUBISHI -// Decode the supplied Mitsubishi message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Notes: -// This protocol appears to have no header. -// -// Ref: -// GlobalCache's Control Tower's Mitsubishi TV data. +/// Decode the supplied Mitsubishi 16-bit message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol appears to have no header. +/// @see GlobalCache's Control Tower's Mitsubishi TV data. bool IRrecv::decodeMitsubishi(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kMitsubishiBits) @@ -167,24 +146,18 @@ bool IRrecv::decodeMitsubishi(decode_results *results, uint16_t offset, #endif // DECODE_MITSUBISHI #if SEND_MITSUBISHI2 -// Send a Mitsubishi2 message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMitsubishiBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: BETA / Probably works. -// -// Notes: -// Based on a Mitsubishi HC3000 projector's remote. -// This protocol appears to have a manditory in-protocol repeat. -// That is in *addition* to the entire message needing to be sent twice -// for the device to accept the command. That is separate from the repeat. -// i.e. Allegedly, the real remote requires the "Off" button pressed twice. -// You will need to add a suitable gap yourself. -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/441 +/// Send a supplied second variant Mitsubishi 16-bit message. +/// Status: BETA / Probably works. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note Based on a Mitsubishi HC3000 projector's remote. +/// This protocol appears to have a manditory in-protocol repeat. +/// That is in *addition* to the entire message needing to be sent twice +/// for the device to accept the command. That is separate from the repeat. +/// i.e. Allegedly, the real remote requires the "Off" button pressed twice. +/// You will need to add a suitable gap yourself. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/441 void IRsend::sendMitsubishi2(uint64_t data, uint16_t nbits, uint16_t repeat) { for (uint16_t i = 0; i <= repeat; i++) { // First half of the data. @@ -203,25 +176,15 @@ void IRsend::sendMitsubishi2(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_MITSUBISHI2 #if DECODE_MITSUBISHI2 -// Decode the supplied Mitsubishi2 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Works. -// -// Notes: -// Hardware supported: -// * Mitsubishi HC3000 projector's remote. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/441 +/// Decode the supplied second variation of a Mitsubishi 16-bit message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/441 bool IRrecv::decodeMitsubishi2(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + kHeader + (kFooter * 2) - 1 + offset) @@ -262,16 +225,11 @@ bool IRrecv::decodeMitsubishi2(decode_results *results, uint16_t offset, #endif // DECODE_MITSUBISHI2 #if SEND_MITSUBISHI_AC -// Send a Mitsubishi A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kMitsubishiACStateLength) -// repeat: Nr. of times the message is to be repeated. -// (Default = kMitsubishiACMinRepeat). -// -// Status: STABLE / Working. -// +/// Send a Mitsubishi 144-bit A/C formatted message. (MITSUBISHI_AC) +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kMitsubishiACStateLength) @@ -285,21 +243,14 @@ void IRsend::sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes, #endif // SEND_MITSUBISHI_AC #if DECODE_MITSUBISHI_AC -// Decode the supplied Mitsubishi message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works -// -// Ref: -// https://www.analysir.com/blog/2015/01/06/reverse-engineering-mitsubishi-ac-infrared-protocol/ +/// Decode the supplied Mitsubish 144-bit A/C message. +/// Status: BETA / Probably works +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @see https://www.analysir.com/blog/2015/01/06/reverse-engineering-mitsubishi-ac-infrared-protocol/ bool IRrecv::decodeMitsubishiAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -423,17 +374,17 @@ bool IRrecv::decodeMitsubishiAC(decode_results *results, uint16_t offset, // Code to emulate Mitsubishi A/C IR remote control unit. // Inspired and derived from the work done at: // https://github.com/r45635/HVAC-IR-Control -// -// Warning: Consider this very alpha code. Seems to work, but not validated. -// -// Equipment it seems compatible with: -// * -// Initialise the object. + +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? +/// @warning Consider this very alpha code. Seems to work, but not validated. IRMitsubishiAC::IRMitsubishiAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishiAC::stateReset(void) { // The state of the IR remote in IR code form. // Known good state obtained from: @@ -443,69 +394,83 @@ void IRMitsubishiAC::stateReset(void) { setRaw(kReset); } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRMitsubishiAC::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHI_AC -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishiAC::send(const uint16_t repeat) { _irsend.sendMitsubishiAC(getRaw(), kMitsubishiACStateLength, repeat); } #endif // SEND_MITSUBISHI_AC -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishiAC::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishiAC::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishiACStateLength); } -// Calculate the checksum for the current internal state of the remote. +/// Calculate and set the checksum values for the internal state. void IRMitsubishiAC::checksum(void) { remote_state[kMitsubishiACStateLength - 1] = calculateChecksum(remote_state); } +/// Verify the checksum is valid for a given state. +/// @param[in] data The array to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRMitsubishiAC::validChecksum(const uint8_t *data) { return calculateChecksum(data) == data[kMitsubishiACStateLength - 1]; } +/// Calculate the checksum for a given state. +/// @param[in] data The value to calc the checksum of. +/// @return The calculated checksum value. uint8_t IRMitsubishiAC::calculateChecksum(const uint8_t *data) { return sumBytes(data, kMitsubishiACStateLength - 1); } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRMitsubishiAC::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMitsubishiAC::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiAC::setPower(bool on) { setBit(&remote_state[5], kMitsubishiAcPowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiAC::getPower(void) { return GETBIT8(remote_state[5], kMitsubishiAcPowerOffset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRMitsubishiAC::setTemp(const uint8_t degrees) { uint8_t temp = std::max((uint8_t)kMitsubishiAcMinTemp, degrees); temp = std::min((uint8_t)kMitsubishiAcMaxTemp, temp); remote_state[7] = temp - kMitsubishiAcMinTemp; } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishiAC::getTemp(void) { return (remote_state[7] + kMitsubishiAcMinTemp); } -// Set the speed of the fan, 0-6. -// 0 is auto, 1-5 is the speed, 6 is silent. +/// Set the speed of the fan. +/// @param[in] speed The desired setting. 0 is auto, 1-5 is speed, 6 is silent. void IRMitsubishiAC::setFan(const uint8_t speed) { uint8_t fan = speed; // Bounds check @@ -519,7 +484,8 @@ void IRMitsubishiAC::setFan(const uint8_t speed) { setBits(&remote_state[9], kMitsubishiAcFanOffset, kMitsubishiAcFanSize, fan); } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishiAC::getFan(void) { uint8_t fan = GETBITS8(remote_state[9], kMitsubishiAcFanOffset, kMitsubishiAcFanSize); @@ -527,12 +493,14 @@ uint8_t IRMitsubishiAC::getFan(void) { return fan; } -// Return the requested climate operation mode of the a/c unit. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishiAC::getMode(void) { return GETBITS8(remote_state[6], kMitsubishiAcModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishiAC::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. switch (mode) { @@ -547,7 +515,8 @@ void IRMitsubishiAC::setMode(const uint8_t mode) { setBits(&remote_state[6], kMitsubishiAcModeOffset, kModeBitsSize, mode); } -// Set the requested vane operation mode of the a/c unit. +/// Set the requested vane (Vertical Swing) operation mode of the a/c unit. +/// @param[in] position The position/mode to set the vane to. void IRMitsubishiAC::setVane(const uint8_t position) { uint8_t pos = std::min(position, kMitsubishiAcVaneAutoMove); // bounds check setBit(&remote_state[9], kMitsubishiAcVaneBitOffset); @@ -555,62 +524,83 @@ void IRMitsubishiAC::setVane(const uint8_t position) { pos); } -// Set the requested wide-vane operation mode of the a/c unit. +/// Set the requested wide-vane (Horizontal Swing) operation mode of the a/c. +/// @param[in] position The position/mode to set the wide vane to. void IRMitsubishiAC::setWideVane(const uint8_t position) { setBits(&remote_state[8], kHighNibble, kNibbleSize, std::min(position, kMitsubishiAcWideVaneAuto)); } -// Return the requested vane operation mode of the a/c unit. +/// Get the Vane (Vertical Swing) mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiAC::getVane(void) { return GETBITS8(remote_state[9], kMitsubishiAcVaneOffset, kMitsubishiAcVaneSize); } -// Return the requested wide vane operation mode of the a/c unit. +/// Get the Wide Vane (Horizontal Swing) mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiAC::getWideVane(void) { return GETBITS8(remote_state[8], kHighNibble, kNibbleSize); } -// Return the clock setting of the message. 1=1/6 hour. e.g. 4pm = 48 +/// Get the clock time of the A/C unit. +/// @return Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 4pm = 48. uint8_t IRMitsubishiAC::getClock(void) { return remote_state[10]; } -// Set the current time. 1 = 1/6 hour. e.g. 6am = 36. +/// Set the clock time on the A/C unit. +/// @param[in] clock Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 6am = 36. void IRMitsubishiAC::setClock(const uint8_t clock) { remote_state[10] = clock; } -// Return the desired start time. 1 = 1/6 hour. e.g. 1am = 6 +/// Get the desired start time of the A/C unit. +/// @return Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 4pm = 48. uint8_t IRMitsubishiAC::getStartClock(void) { return remote_state[12]; } -// Set the desired start time of the AC. 1 = 1/6 hour. e.g. 8pm = 120 +/// Set the desired start time of the A/C unit. +/// @param[in] clock Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 8pm = 120. void IRMitsubishiAC::setStartClock(const uint8_t clock) { remote_state[12] = clock; } -// Return the desired stop time of the AC. 1 = 1/6 hour. e.g 10pm = 132 +/// Get the desired stop time of the A/C unit. +/// @return Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 10pm = 132. uint8_t IRMitsubishiAC::getStopClock(void) { return remote_state[11]; } -// Set the desired stop time of the AC. 1 = 1/6 hour. e.g 10pm = 132 +/// Set the desired stop time of the A/C unit. +/// @param[in] clock Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 10pm = 132. void IRMitsubishiAC::setStopClock(const uint8_t clock) { remote_state[11] = clock; } -// Return the timer setting. Possible values: kMitsubishiAcNoTimer, -// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, -// kMitsubishiAcStartStopTimer +/// Get the timers active setting of the A/C. +/// @return The current timers enabled. +/// @note Possible values: kMitsubishiAcNoTimer, +/// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, +/// kMitsubishiAcStartStopTimer uint8_t IRMitsubishiAC::getTimer(void) { return GETBITS8(remote_state[13], 0, 3); } -// Set the timer setting. Possible values: kMitsubishiAcNoTimer, -// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, -// kMitsubishiAcStartStopTimer +/// Set the timers active setting of the A/C. +/// @param[in] timer The timer code indicating which ones are active. +/// @note Possible values: kMitsubishiAcNoTimer, +/// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, +/// kMitsubishiAcStartStopTimer void IRMitsubishiAC::setTimer(uint8_t timer) { setBits(&remote_state[13], 0, 3, timer); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMitsubishiAcCool; @@ -620,7 +610,9 @@ uint8_t IRMitsubishiAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kMitsubishiAcFanSilent; @@ -632,7 +624,10 @@ uint8_t IRMitsubishiAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. + +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiAC::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: return kMitsubishiAcVaneAutoMove - 6; @@ -645,7 +640,9 @@ uint8_t IRMitsubishiAC::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C wide wane swing into its native setting. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiAC::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kLeftMax: return kMitsubishiAcWideVaneAuto - 7; @@ -659,7 +656,9 @@ uint8_t IRMitsubishiAC::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMitsubishiAC::toCommonMode(const uint8_t mode) { switch (mode) { case kMitsubishiAcCool: return stdAc::opmode_t::kCool; @@ -669,7 +668,9 @@ stdAc::opmode_t IRMitsubishiAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishiAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMitsubishiAcFanRealMax: return stdAc::fanspeed_t::kMax; @@ -681,7 +682,9 @@ stdAc::fanspeed_t IRMitsubishiAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishiAC::toCommonSwingV(const uint8_t pos) { switch (pos) { case 1: return stdAc::swingv_t::kHighest; @@ -693,7 +696,9 @@ stdAc::swingv_t IRMitsubishiAC::toCommonSwingV(const uint8_t pos) { } } -// Convert a native horizontal swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRMitsubishiAC::toCommonSwingH(const uint8_t pos) { switch (pos) { case 1: return stdAc::swingh_t::kLeftMax; @@ -706,7 +711,8 @@ stdAc::swingh_t IRMitsubishiAC::toCommonSwingH(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishiAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI_AC; @@ -731,7 +737,8 @@ stdAc::state_t IRMitsubishiAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishiAC::toString(void) { String result = ""; result.reserve(110); // Reserve some heap for the string to reduce fragging. @@ -796,18 +803,12 @@ String IRMitsubishiAC::toString(void) { } #if SEND_MITSUBISHI136 -// Send a Mitsubishi136 A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kMitsubishi136StateLength) -// repeat: Nr. of times the message is to be repeated. -// (Default = kMitsubishi136MinRepeat). -// -// Status: BETA / Probably working. Needs to be tested against a real device. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/888 +/// Send a Mitsubishi 136-bit A/C message. (MITSUBISHI136) +/// Status: BETA / Probably working. Needs to be tested against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/888 void IRsend::sendMitsubishi136(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { @@ -823,21 +824,14 @@ void IRsend::sendMitsubishi136(const unsigned char data[], #endif // SEND_MITSUBISHI136 #if DECODE_MITSUBISHI136 -// Decode the supplied Mitsubishi136 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/888 +/// Decode the supplied Mitsubishi 136-bit A/C message. (MITSUBISHI136) +/// Status: STABLE / Reported as working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/888 bool IRrecv::decodeMitsubishi136(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -867,17 +861,16 @@ bool IRrecv::decodeMitsubishi136(decode_results *results, uint16_t offset, #endif // DECODE_MITSUBISHI136 // Code to emulate Mitsubishi 136bit A/C IR remote control unit. -// -// Equipment it seems compatible with: -// Brand: Mitsubishi Electric, Model: PEAD-RP71JAA Ducted A/C -// Brand: Mitsubishi Electric, Model: 001CP T7WE10714 remote -// Initialise the object. +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRMitsubishi136::IRMitsubishi136(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishi136::stateReset(void) { // The state of the IR remote in IR code form. // Known good state obtained from: @@ -887,13 +880,17 @@ void IRMitsubishi136::stateReset(void) { memcpy(remote_state, kReset, kMitsubishi136StateLength); } -// Calculate the checksum for the current internal state of the remote. +/// Calculate the checksum for the current internal state of the remote. void IRMitsubishi136::checksum(void) { for (uint8_t i = 0; i < 6; i++) remote_state[kMitsubishi136PowerByte + 6 + i] = ~remote_state[kMitsubishi136PowerByte + i]; } +/// Verify the checksum is valid for a given state. +/// @param[in] data The array to verify the checksum of. +/// @param[in] len The length of the data array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRMitsubishi136::validChecksum(const uint8_t *data, const uint16_t len) { if (len < kMitsubishi136StateLength) return false; const uint16_t half = (len - kMitsubishi136PowerByte) / 2; @@ -906,44 +903,51 @@ bool IRMitsubishi136::validChecksum(const uint8_t *data, const uint16_t len) { return true; } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRMitsubishi136::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHI136 -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishi136::send(const uint16_t repeat) { _irsend.sendMitsubishi136(getRaw(), kMitsubishi136StateLength, repeat); } #endif // SEND_MITSUBISHI136 -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishi136::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishi136::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishi136StateLength); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to on. void IRMitsubishi136::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMitsubishi136::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishi136::setPower(bool on) { setBit(&remote_state[kMitsubishi136PowerByte], kMitsubishi136PowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishi136::getPower(void) { return GETBIT8(remote_state[kMitsubishi136PowerByte], kMitsubishi136PowerOffset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRMitsubishi136::setTemp(const uint8_t degrees) { uint8_t temp = std::max((uint8_t)kMitsubishi136MinTemp, degrees); temp = std::min((uint8_t)kMitsubishi136MaxTemp, temp); @@ -951,30 +955,36 @@ void IRMitsubishi136::setTemp(const uint8_t degrees) { temp - kMitsubishiAcMinTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishi136::getTemp(void) { return GETBITS8(remote_state[kMitsubishi136TempByte], kHighNibble, kNibbleSize) + kMitsubishiAcMinTemp; } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRMitsubishi136::setFan(const uint8_t speed) { setBits(&remote_state[kMitsubishi136FanByte], kMitsubishi136FanOffset, kMitsubishi136FanSize, std::min(speed, kMitsubishi136FanMax)); } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishi136::getFan(void) { return GETBITS8(remote_state[kMitsubishi136FanByte], kMitsubishi136FanOffset, kMitsubishi136FanSize); } -// Return the requested climate operation mode of the a/c unit. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishi136::getMode(void) { return GETBITS8(remote_state[kMitsubishi136ModeByte], kMitsubishi136ModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishi136::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. switch (mode) { @@ -991,7 +1001,8 @@ void IRMitsubishi136::setMode(const uint8_t mode) { } } -// Set the requested vane operation mode of the a/c unit. +/// Set the Vertical Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRMitsubishi136::setSwingV(const uint8_t position) { // If we get an unexpected mode, default to auto. switch (position) { @@ -1008,24 +1019,30 @@ void IRMitsubishi136::setSwingV(const uint8_t position) { } } -// Return the requested vane operation mode of the a/c unit. +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishi136::getSwingV(void) { return GETBITS8(remote_state[kMitsubishi136SwingVByte], kHighNibble, kNibbleSize); } -// Emulate a quiet setting. There is no true quiet setting on this a/c +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishi136::setQuiet(bool on) { if (on) setFan(kMitsubishi136FanQuiet); else if (getQuiet()) setFan(kMitsubishi136FanLow); } -// Return the requested power state of the A/C. + +/// Get the Quiet mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishi136::getQuiet(void) { return getFan() == kMitsubishi136FanQuiet; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi136::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMitsubishi136Cool; @@ -1036,7 +1053,9 @@ uint8_t IRMitsubishi136::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi136::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kMitsubishi136FanMin; @@ -1047,7 +1066,9 @@ uint8_t IRMitsubishi136::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi136::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: return kMitsubishi136SwingVHighest; @@ -1059,7 +1080,9 @@ uint8_t IRMitsubishi136::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMitsubishi136::toCommonMode(const uint8_t mode) { switch (mode) { case kMitsubishi136Cool: return stdAc::opmode_t::kCool; @@ -1070,7 +1093,9 @@ stdAc::opmode_t IRMitsubishi136::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishi136::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMitsubishi136FanMax: return stdAc::fanspeed_t::kMax; @@ -1081,7 +1106,9 @@ stdAc::fanspeed_t IRMitsubishi136::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishi136::toCommonSwingV(const uint8_t pos) { switch (pos) { case kMitsubishi136SwingVHighest: return stdAc::swingv_t::kHighest; @@ -1092,7 +1119,8 @@ stdAc::swingv_t IRMitsubishi136::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishi136::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI136; @@ -1117,7 +1145,8 @@ stdAc::state_t IRMitsubishi136::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishi136::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. @@ -1146,18 +1175,12 @@ String IRMitsubishi136::toString(void) { #if SEND_MITSUBISHI112 -// Send a Mitsubishi112 A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kMitsubishi112StateLength) -// repeat: Nr. of times the message is to be repeated. -// (Default = kMitsubishi112MinRepeat). -// -// Status: Stable / Reported as working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/947 +/// Send a Mitsubishi 112-bit A/C formatted message. (MITSUBISHI112) +/// Status: Stable / Reported as working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/947 void IRsend::sendMitsubishi112(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { @@ -1173,29 +1196,23 @@ void IRsend::sendMitsubishi112(const unsigned char data[], #endif // SEND_MITSUBISHI112 #if DECODE_MITSUBISHI112 || DECODE_TCL112AC -// Decode the supplied Mitsubishi112 / Tcl112Ac message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// -// Note: Mitsubishi112 & Tcl112Ac are basically the same protocol. -// The only significant difference I can see is Mitsubishi112 has a -// slightly longer header mark. We will use that to determine which -// varient it should be. The other differences require full decoding and -// only only with certain settings. -// There are some other timing differences too, but the tolerances will -// overlap. -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/619 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/947 +/// Decode the supplied Mitsubishi/TCL 112-bit A/C message. +/// (MITSUBISHI112, TCL112AC) +/// Status: STABLE / Reported as working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @note Note Mitsubishi112 & Tcl112Ac are basically the same protocol. +/// The only significant difference I can see is Mitsubishi112 has a +/// slightly longer header mark. We will use that to determine which +/// variant it should be. The other differences require full decoding and +/// only only with certain settings. +/// There are some other timing differences too, but the tolerances will +/// overlap. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/619 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/947 bool IRrecv::decodeMitsubishi112(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < (2 * nbits) + kHeader + kFooter - 1 + offset) @@ -1265,17 +1282,16 @@ bool IRrecv::decodeMitsubishi112(decode_results *results, uint16_t offset, #endif // DECODE_MITSUBISHI112 || DECODE_TCL112AC // Code to emulate Mitsubishi 112bit A/C IR remote control unit. -// -// Equipment it seems compatible with: -// Brand: Mitsubishi Electric, Model: MSH-A24WV / MUH-A24WV A/C -// Brand: Mitsubishi Electric, Model: KPOA remote -// Initialise the object. +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRMitsubishi112::IRMitsubishi112(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishi112::stateReset(void) { const uint8_t kReset[kMitsubishi112StateLength] = { 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03, 0x0B, 0x10, @@ -1283,50 +1299,57 @@ void IRMitsubishi112::stateReset(void) { setRaw(kReset); } -// Calculate the checksum for the current internal state of the remote. +/// Calculate the checksum for the current internal state of the remote. void IRMitsubishi112::checksum(void) { remote_state[kMitsubishi112StateLength - 1] = IRTcl112Ac::calcChecksum( remote_state, kMitsubishi112StateLength); } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRMitsubishi112::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHI112 -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishi112::send(const uint16_t repeat) { _irsend.sendMitsubishi112(getRaw(), kMitsubishi112StateLength, repeat); } #endif // SEND_MITSUBISHI112 -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishi112::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishi112::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishi112StateLength); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMitsubishi112::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMitsubishi112::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishi112::setPower(bool on) { setBit(&remote_state[kMitsubishi112PowerByte], kMitsubishi112PowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishi112::getPower(void) { return GETBIT8(remote_state[kMitsubishi112PowerByte], kMitsubishi112PowerOffset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRMitsubishi112::setTemp(const uint8_t degrees) { uint8_t temp = std::max((uint8_t)kMitsubishi112MinTemp, degrees); temp = std::min((uint8_t)kMitsubishi112MaxTemp, temp); @@ -1334,12 +1357,15 @@ void IRMitsubishi112::setTemp(const uint8_t degrees) { kMitsubishi112TempSize, kMitsubishiAcMaxTemp - temp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishi112::getTemp(void) { return kMitsubishiAcMaxTemp - GETBITS8(remote_state[kMitsubishi112TempByte], kLowNibble, kMitsubishi112TempSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRMitsubishi112::setFan(const uint8_t speed) { switch (speed) { case kMitsubishi112FanMin: @@ -1354,19 +1380,22 @@ void IRMitsubishi112::setFan(const uint8_t speed) { } } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishi112::getFan(void) { return GETBITS8(remote_state[kMitsubishi112FanByte], kMitsubishi112FanOffset, kMitsubishi112FanSize); } -// Return the requested climate operation mode of the a/c unit. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishi112::getMode(void) { return GETBITS8(remote_state[kMitsubishi112ModeByte], kMitsubishi112ModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishi112::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. switch (mode) { @@ -1383,7 +1412,8 @@ void IRMitsubishi112::setMode(const uint8_t mode) { } } -// Set the requested vane operation mode of the a/c unit. +/// Set the Vertical Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRMitsubishi112::setSwingV(const uint8_t position) { // If we get an unexpected mode, default to auto. switch (position) { @@ -1401,13 +1431,15 @@ void IRMitsubishi112::setSwingV(const uint8_t position) { } } -// Return the requested vane operation mode of the a/c unit. +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishi112::getSwingV(void) { return GETBITS8(remote_state[kMitsubishi112SwingVByte], kMitsubishi112SwingVOffset, kMitsubishi112SwingVSize); } -// Set the requested vane operation mode of the a/c unit. +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRMitsubishi112::setSwingH(const uint8_t position) { // If we get an unexpected mode, default to auto. switch (position) { @@ -1426,26 +1458,34 @@ void IRMitsubishi112::setSwingH(const uint8_t position) { } } -// Return the requested vane operation mode of the a/c unit. + +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishi112::getSwingH(void) { return GETBITS8(remote_state[kMitsubishi112SwingHByte], kMitsubishi112SwingHOffset, kMitsubishi112SwingHSize); } -// Emulate a quiet setting. There is no true quiet setting on this a/c +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note There is no true quiet setting on this A/C. void IRMitsubishi112::setQuiet(bool on) { if (on) setFan(kMitsubishi112FanQuiet); else if (getQuiet()) setFan(kMitsubishi112FanLow); } -// Return the requested power state of the A/C. + +/// Get the Quiet mode of the A/C. +/// @return true, the setting is on. false, the setting is off. +/// @note There is no true quiet setting on this A/C. bool IRMitsubishi112::getQuiet(void) { return getFan() == kMitsubishi112FanQuiet; } - -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi112::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMitsubishi112Cool; @@ -1456,7 +1496,9 @@ uint8_t IRMitsubishi112::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi112::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kMitsubishi112FanMin; @@ -1468,7 +1510,9 @@ uint8_t IRMitsubishi112::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi112::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: return kMitsubishi112SwingVHighest; @@ -1480,7 +1524,9 @@ uint8_t IRMitsubishi112::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi112::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kLeftMax: return kMitsubishi112SwingHLeftMax; @@ -1494,7 +1540,9 @@ uint8_t IRMitsubishi112::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMitsubishi112::toCommonMode(const uint8_t mode) { switch (mode) { case kMitsubishi112Cool: return stdAc::opmode_t::kCool; @@ -1504,7 +1552,9 @@ stdAc::opmode_t IRMitsubishi112::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishi112::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMitsubishi112FanMax: return stdAc::fanspeed_t::kMax; @@ -1515,7 +1565,9 @@ stdAc::fanspeed_t IRMitsubishi112::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishi112::toCommonSwingV(const uint8_t pos) { switch (pos) { case kMitsubishi112SwingVHighest: return stdAc::swingv_t::kHighest; @@ -1527,7 +1579,9 @@ stdAc::swingv_t IRMitsubishi112::toCommonSwingV(const uint8_t pos) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRMitsubishi112::toCommonSwingH(const uint8_t pos) { switch (pos) { case kMitsubishi112SwingHLeftMax: return stdAc::swingh_t::kLeftMax; @@ -1540,8 +1594,8 @@ stdAc::swingh_t IRMitsubishi112::toCommonSwingH(const uint8_t pos) { } } - -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishi112::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI112; @@ -1568,7 +1622,8 @@ stdAc::state_t IRMitsubishi112::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishi112::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.h b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h similarity index 77% rename from lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h index b9cc7b349..04c7bf57d 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Mitsubishi.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h @@ -2,17 +2,29 @@ // Copyright 2017-2019 David Conran // Copyright 2019 Mark Kuchel -// Mitsubishi +/// @file +/// @brief Support for Mitsubishi protocols. +/// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote +/// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran +/// @see GlobalCache's Control Tower's Mitsubishi TV data. +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/441 +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L84 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/619 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/888 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/947 +/// @see https://github.com/kuchel77 // Supports: -// Brand: Mitsubishi, Model: TV -// Brand: Mitsubishi, Model: HC3000 Projector +// Brand: Mitsubishi, Model: TV (MITSUBISHI) +// Brand: Mitsubishi, Model: HC3000 Projector (MITSUBISHI2) // Brand: Mitsubishi, Model: MS-GK24VA A/C // Brand: Mitsubishi, Model: KM14A 0179213 remote -// Brand: Mitsubishi Electric, Model: PEAD-RP71JAA Ducted A/C -// Brand: Mitsubishi Electric, Model: 001CP T7WE10714 remote -// Brand: Mitsubishi Electric, Model: MSH-A24WV / MUH-A24WV A/C -// Brand: Mitsubishi Electric, Model: KPOA remote +// Brand: Mitsubishi Electric, Model: PEAD-RP71JAA Ducted A/C (MITSUBISHI136) +// Brand: Mitsubishi Electric, Model: 001CP T7WE10714 remote (MITSUBISHI136) +// Brand: Mitsubishi Electric, Model: MSH-A24WV A/C (MITSUBISHI112) +// Brand: Mitsubishi Electric, Model: MUH-A24WV A/C (MITSUBISHI112) +// Brand: Mitsubishi Electric, Model: KPOA remote (MITSUBISHI112) #ifndef IR_MITSUBISHI_H_ #define IR_MITSUBISHI_H_ @@ -28,8 +40,6 @@ #include "IRsend_test.h" #endif -// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote -// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran // Constants const uint8_t kMitsubishiAcModeOffset = 3; @@ -151,6 +161,10 @@ const uint8_t kMitsubishi112SwingHAuto = 0b1100; #define MITSUBISHI_AC_COOL kMitsubishiAcCool #define MITSUBISHI_AC_AUTO kMitsubishiAcAuto + +/// Class for handling detailed Mitsubishi 144-bit A/C messages. +/// Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control +/// @warning Consider this very alpha code. Seems to work, but not validated. class IRMitsubishiAC { public: explicit IRMitsubishiAC(const uint16_t pin, const bool inverted = false, @@ -159,6 +173,10 @@ class IRMitsubishiAC { static bool validChecksum(const uint8_t* data); #if SEND_MITSUBISHI_AC void send(const uint16_t repeat = kMitsubishiACMinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MITSUBISHI_AC void begin(void); @@ -199,24 +217,29 @@ class IRMitsubishiAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kMitsubishiACStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kMitsubishiACStateLength]; ///< The state in code form. void checksum(void); static uint8_t calculateChecksum(const uint8_t* data); }; +/// Class for handling detailed Mitsubishi 136-bit A/C messages. class IRMitsubishi136 { public: explicit IRMitsubishi136(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - - void stateReset(void); #if SEND_MITSUBISHI136 void send(const uint16_t repeat = kMitsubishi136MinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MITSUBISHI136 void begin(void); @@ -249,11 +272,13 @@ class IRMitsubishi136 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kMitsubishi136StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kMitsubishi136StateLength]; ///< The state in code form. void checksum(void); }; @@ -262,11 +287,13 @@ class IRMitsubishi112 { public: explicit IRMitsubishi112(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - - void stateReset(void); #if SEND_MITSUBISHI112 void send(const uint16_t repeat = kMitsubishi112MinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MITSUBISHI112 void begin(void); @@ -301,11 +328,13 @@ class IRMitsubishi112 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kMitsubishi112StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kMitsubishi112StateLength]; ///< The state in code form. void checksum(void); }; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp similarity index 73% rename from lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp index 39bd3d8d6..7747ded6d 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp @@ -1,17 +1,14 @@ // Copyright 2019 David Conran -// Mitsubishi Heavy Industries A/C remote emulation. -// Code to emulate Mitsubishi Heavy Industries A/C IR remote control units, -// which should control at least the following A/C units: -// Remote Control RLA502A700B: -// Model SRKxxZM-S -// Model SRKxxZMXA-S -// Remote Control RKX502A001C: -// Model SRKxxZJ-S - -// Note: This code was *heavily* influenced by @ToniA's great work & code, -// but it has been written from scratch. -// Nothing was copied other than constants and message analysis. +/// @file +/// @brief Support for Mitsubishi Heavy Industry protocols. +/// Code to emulate Mitsubishi Heavy Industries A/C IR remote control units. +/// @note This code was *heavily* influenced by ToniA's great work & code, +/// but it has been written from scratch. +/// Nothing was copied other than constants and message analysis. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/660 +/// @see https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp #include "ir_MitsubishiHeavy.h" #include @@ -23,11 +20,6 @@ #include #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/660 -// https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp -// https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp - // Constants const uint16_t kMitsubishiHeavyHdrMark = 3140; const uint16_t kMitsubishiHeavyHdrSpace = 1630; @@ -45,14 +37,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_MITSUBISHIHEAVY -// Send a MitsubishiHeavy 88 bit A/C message. -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMitsubishiHeavy88Bits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: BETA / Appears to be working. Needs testing against a real device. +/// Send a MitsubishiHeavy 88-bit A/C message. +/// Status: BETA / Appears to be working. Needs testing against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendMitsubishiHeavy88(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { @@ -65,14 +54,11 @@ void IRsend::sendMitsubishiHeavy88(const unsigned char data[], data, nbytes, 38000, false, repeat, kDutyDefault); } -// Send a MitsubishiHeavy 152 bit A/C message. -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMitsubishiHeavy152Bits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: BETA / Appears to be working. Needs testing against a real device. +/// Send a MitsubishiHeavy 152-bit A/C message. +/// Status: BETA / Appears to be working. Needs testing against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendMitsubishiHeavy152(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { @@ -83,20 +69,29 @@ void IRsend::sendMitsubishiHeavy152(const unsigned char data[], #endif // SEND_MITSUBISHIHEAVY // Class for decoding and constructing MitsubishiHeavy152 AC messages. + +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRMitsubishiHeavy152Ac::IRMitsubishiHeavy152Ac(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRMitsubishiHeavy152Ac::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHIHEAVY +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishiHeavy152Ac::send(const uint16_t repeat) { _irsend.sendMitsubishiHeavy152(this->getRaw(), kMitsubishiHeavy152StateLength, repeat); } #endif // SEND_MITSUBISHIHEAVY +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishiHeavy152Ac::stateReset(void) { memcpy(remote_state, kMitsubishiHeavyZmsSig, kMitsubishiHeavySigLength); for (uint8_t i = kMitsubishiHeavySigLength; @@ -104,27 +99,39 @@ void IRMitsubishiHeavy152Ac::stateReset(void) { remote_state[17] = 0x80; } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishiHeavy152Ac::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishiHeavy152Ac::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishiHeavy152StateLength); } +/// Set the requested power state of the A/C to on. void IRMitsubishiHeavy152Ac::on(void) { setPower(true); } +/// Set the requested power state of the A/C to off. void IRMitsubishiHeavy152Ac::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setPower(const bool on) { setBit(&remote_state[5], kMitsubishiHeavyPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getPower(void) { return GETBIT8(remote_state[5], kMitsubishiHeavyPowerOffset); } +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRMitsubishiHeavy152Ac::setTemp(const uint8_t temp) { uint8_t newtemp = temp; newtemp = std::min(newtemp, kMitsubishiHeavyMaxTemp); @@ -133,12 +140,15 @@ void IRMitsubishiHeavy152Ac::setTemp(const uint8_t temp) { newtemp - kMitsubishiHeavyMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishiHeavy152Ac::getTemp(void) { return GETBITS8(remote_state[7], kLowNibble, kNibbleSize) + kMitsubishiHeavyMinTemp; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRMitsubishiHeavy152Ac::setFan(const uint8_t speed) { uint8_t newspeed = speed; switch (speed) { @@ -153,10 +163,14 @@ void IRMitsubishiHeavy152Ac::setFan(const uint8_t speed) { setBits(&remote_state[9], kLowNibble, kNibbleSize, newspeed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishiHeavy152Ac::getFan(void) { return GETBITS8(remote_state[9], kLowNibble, kNibbleSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishiHeavy152Ac::setMode(const uint8_t mode) { uint8_t newmode = mode; switch (mode) { @@ -171,38 +185,54 @@ void IRMitsubishiHeavy152Ac::setMode(const uint8_t mode) { setBits(&remote_state[5], kMitsubishiHeavyModeOffset, kModeBitsSize, newmode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishiHeavy152Ac::getMode(void) { return GETBITS8(remote_state[5], kMitsubishiHeavyModeOffset, kModeBitsSize); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] pos The position/mode to set the swing to. void IRMitsubishiHeavy152Ac::setSwingVertical(const uint8_t pos) { setBits(&remote_state[11], kMitsubishiHeavy152SwingVOffset, kMitsubishiHeavy152SwingVSize, std::min(pos, kMitsubishiHeavy152SwingVOff)); } +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiHeavy152Ac::getSwingVertical(void) { return GETBITS8(remote_state[11], kMitsubishiHeavy152SwingVOffset, kMitsubishiHeavy152SwingVSize); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] pos The position/mode to set the swing to. void IRMitsubishiHeavy152Ac::setSwingHorizontal(const uint8_t pos) { setBits(&remote_state[13], kLowNibble, kNibbleSize, std::min(pos, kMitsubishiHeavy152SwingHOff)); } +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiHeavy152Ac::getSwingHorizontal(void) { return GETBITS8(remote_state[13], kLowNibble, kNibbleSize); } +/// Set the Night (Sleep) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setNight(const bool on) { setBit(&remote_state[15], kMitsubishiHeavyNightOffset, on); } +/// Get the Night (Sleep) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getNight(void) { return GETBIT8(remote_state[15], kMitsubishiHeavyNightOffset); } +/// Set the 3D mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::set3D(const bool on) { if (on) remote_state[11] |= kMitsubishiHeavy3DMask; @@ -210,63 +240,88 @@ void IRMitsubishiHeavy152Ac::set3D(const bool on) { remote_state[11] &= ~kMitsubishiHeavy3DMask; } +/// Get the 3D mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::get3D(void) { return (remote_state[11] & kMitsubishiHeavy3DMask) == kMitsubishiHeavy3DMask; } +/// Set the Silent (Quiet) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setSilent(const bool on) { setBit(&remote_state[15], kMitsubishiHeavySilentOffset, on); } +/// Get the Silent (Quiet) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getSilent(void) { return GETBIT8(remote_state[15], kMitsubishiHeavySilentOffset); } +/// Set the Filter mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setFilter(const bool on) { setBit(&remote_state[5], kMitsubishiHeavyFilterOffset, on); } +/// Get the Filter mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getFilter(void) { return GETBIT8(remote_state[5], kMitsubishiHeavyFilterOffset); } +/// Set the Clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setClean(const bool on) { this->setFilter(on); setBit(&remote_state[5], kMitsubishiHeavyCleanOffset, on); } +/// Get the Clean mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getClean(void) { return GETBIT8(remote_state[5], kMitsubishiHeavyCleanOffset) && getFilter(); } +/// Set the Turbo mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setTurbo(const bool on) { if (on) this->setFan(kMitsubishiHeavy152FanTurbo); else if (this->getTurbo()) this->setFan(kMitsubishiHeavy152FanAuto); } +/// Get the Turbo mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getTurbo(void) { return this->getFan() == kMitsubishiHeavy152FanTurbo; } +/// Set the Economical mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setEcono(const bool on) { if (on) this->setFan(kMitsubishiHeavy152FanEcono); else if (this->getEcono()) this->setFan(kMitsubishiHeavy152FanAuto); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getEcono(void) { return this->getFan() == kMitsubishiHeavy152FanEcono; } -// Verify the given state has a ZM-S signature. +/// Verify the given state has a ZM-S signature. +/// @param[in] state A ptr to a state to be checked. +/// @return true, the check passed. Otherwise, false. bool IRMitsubishiHeavy152Ac::checkZmsSig(const uint8_t *state) { for (uint8_t i = 0; i < kMitsubishiHeavySigLength; i++) if (state[i] != kMitsubishiHeavyZmsSig[i]) return false; return true; } -// Protocol technically has no checksum, but does has inverted byte pairs. +/// Calculate the checksum for the current internal state of the remote. +/// Note: Technically it has no checksum, but does has inverted byte pairs. void IRMitsubishiHeavy152Ac::checksum(void) { for (uint8_t i = kMitsubishiHeavySigLength - 2; i < kMitsubishiHeavy152StateLength; @@ -275,7 +330,11 @@ void IRMitsubishiHeavy152Ac::checksum(void) { } } -// Protocol technically has no checksum, but does has inverted byte pairs. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. +/// Note: Technically it has no checksum, but does has inverted byte pairs. bool IRMitsubishiHeavy152Ac::validChecksum(const uint8_t *state, const uint16_t length) { // Assume anything too short is fine. @@ -290,7 +349,9 @@ bool IRMitsubishiHeavy152Ac::validChecksum(const uint8_t *state, return true; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy152Ac::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMitsubishiHeavyCool; @@ -301,7 +362,9 @@ uint8_t IRMitsubishiHeavy152Ac::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy152Ac::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { // Assumes Econo is slower than Low. @@ -314,7 +377,9 @@ uint8_t IRMitsubishiHeavy152Ac::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy152Ac::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kAuto: return kMitsubishiHeavy152SwingVAuto; @@ -327,7 +392,9 @@ uint8_t IRMitsubishiHeavy152Ac::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C horizontal swing into its native setting. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy152Ac::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kAuto: return kMitsubishiHeavy152SwingHAuto; @@ -340,7 +407,9 @@ uint8_t IRMitsubishiHeavy152Ac::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMitsubishiHeavy152Ac::toCommonMode(const uint8_t mode) { switch (mode) { case kMitsubishiHeavyCool: return stdAc::opmode_t::kCool; @@ -351,7 +420,9 @@ stdAc::opmode_t IRMitsubishiHeavy152Ac::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishiHeavy152Ac::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kMitsubishiHeavy152FanMax: return stdAc::fanspeed_t::kMax; @@ -363,7 +434,9 @@ stdAc::fanspeed_t IRMitsubishiHeavy152Ac::toCommonFanSpeed(const uint8_t spd) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRMitsubishiHeavy152Ac::toCommonSwingH(const uint8_t pos) { switch (pos) { case kMitsubishiHeavy152SwingHLeftMax: return stdAc::swingh_t::kLeftMax; @@ -376,7 +449,9 @@ stdAc::swingh_t IRMitsubishiHeavy152Ac::toCommonSwingH(const uint8_t pos) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishiHeavy152Ac::toCommonSwingV(const uint8_t pos) { switch (pos) { case kMitsubishiHeavy152SwingVHighest: return stdAc::swingv_t::kHighest; @@ -389,7 +464,8 @@ stdAc::swingv_t IRMitsubishiHeavy152Ac::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishiHeavy152Ac::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI_HEAVY_152; @@ -414,7 +490,8 @@ stdAc::state_t IRMitsubishiHeavy152Ac::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishiHeavy152Ac::toString(void) { String result = ""; result.reserve(180); // Reserve some heap for the string to reduce fragging. @@ -529,47 +606,68 @@ String IRMitsubishiHeavy152Ac::toString(void) { // Class for decoding and constructing MitsubishiHeavy88 AC messages. + +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRMitsubishiHeavy88Ac::IRMitsubishiHeavy88Ac(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRMitsubishiHeavy88Ac::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHIHEAVY +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishiHeavy88Ac::send(const uint16_t repeat) { _irsend.sendMitsubishiHeavy88(this->getRaw(), kMitsubishiHeavy88StateLength, repeat); } #endif // SEND_MITSUBISHIHEAVY +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishiHeavy88Ac::stateReset(void) { memcpy(remote_state, kMitsubishiHeavyZjsSig, kMitsubishiHeavySigLength); for (uint8_t i = kMitsubishiHeavySigLength; i < kMitsubishiHeavy88StateLength; i++) remote_state[i] = 0; } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishiHeavy88Ac::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishiHeavy88Ac::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishiHeavy88StateLength); } +/// Set the requested power state of the A/C to on. void IRMitsubishiHeavy88Ac::on(void) { setPower(true); } +/// Set the requested power state of the A/C to off. void IRMitsubishiHeavy88Ac::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::setPower(const bool on) { setBit(&remote_state[9], kMitsubishiHeavyPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::getPower(void) { return GETBIT8(remote_state[9], kMitsubishiHeavyPowerOffset); } +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRMitsubishiHeavy88Ac::setTemp(const uint8_t temp) { uint8_t newtemp = temp; newtemp = std::min(newtemp, kMitsubishiHeavyMaxTemp); @@ -578,12 +676,15 @@ void IRMitsubishiHeavy88Ac::setTemp(const uint8_t temp) { newtemp - kMitsubishiHeavyMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishiHeavy88Ac::getTemp(void) { return GETBITS8(remote_state[9], kHighNibble, kNibbleSize) + kMitsubishiHeavyMinTemp; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRMitsubishiHeavy88Ac::setFan(const uint8_t speed) { uint8_t newspeed = speed; switch (speed) { @@ -598,11 +699,15 @@ void IRMitsubishiHeavy88Ac::setFan(const uint8_t speed) { kMitsubishiHeavy88FanSize, newspeed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishiHeavy88Ac::getFan(void) { return GETBITS8(remote_state[7], kMitsubishiHeavy88FanOffset, kMitsubishiHeavy88FanSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishiHeavy88Ac::setMode(const uint8_t mode) { uint8_t newmode = mode; switch (mode) { @@ -617,10 +722,14 @@ void IRMitsubishiHeavy88Ac::setMode(const uint8_t mode) { setBits(&remote_state[9], kMitsubishiHeavyModeOffset, kModeBitsSize, newmode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishiHeavy88Ac::getMode(void) { return GETBITS8(remote_state[9], kMitsubishiHeavyModeOffset, kModeBitsSize); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] pos The position/mode to set the swing to. void IRMitsubishiHeavy88Ac::setSwingVertical(const uint8_t pos) { uint8_t newpos; switch (pos) { @@ -639,6 +748,8 @@ void IRMitsubishiHeavy88Ac::setSwingVertical(const uint8_t pos) { newpos >> kMitsubishiHeavy88SwingVByte5Size); } +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiHeavy88Ac::getSwingVertical(void) { return GETBITS8(remote_state[5], kMitsubishiHeavy88SwingVByte5Offset, kMitsubishiHeavy88SwingVByte5Size) | @@ -647,6 +758,8 @@ uint8_t IRMitsubishiHeavy88Ac::getSwingVertical(void) { kMitsubishiHeavy88SwingVByte5Size); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] pos The position/mode to set the swing to. void IRMitsubishiHeavy88Ac::setSwingHorizontal(const uint8_t pos) { uint8_t newpos; switch (pos) { @@ -668,6 +781,8 @@ void IRMitsubishiHeavy88Ac::setSwingHorizontal(const uint8_t pos) { newpos >> kMitsubishiHeavy88SwingHSize); } +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiHeavy88Ac::getSwingHorizontal(void) { return GETBITS8(remote_state[5], kMitsubishiHeavy88SwingHOffset1, kMitsubishiHeavy88SwingHSize) | @@ -676,26 +791,36 @@ uint8_t IRMitsubishiHeavy88Ac::getSwingHorizontal(void) { kMitsubishiHeavy88SwingHSize); } +/// Set the Turbo mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::setTurbo(const bool on) { if (on) this->setFan(kMitsubishiHeavy88FanTurbo); else if (this->getTurbo()) this->setFan(kMitsubishiHeavy88FanAuto); } +/// Get the Turbo mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::getTurbo(void) { return this->getFan() == kMitsubishiHeavy88FanTurbo; } +/// Set the Economical mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::setEcono(const bool on) { if (on) this->setFan(kMitsubishiHeavy88FanEcono); else if (this->getEcono()) this->setFan(kMitsubishiHeavy88FanAuto); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::getEcono(void) { return this->getFan() == kMitsubishiHeavy88FanEcono; } +/// Set the 3D mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::set3D(const bool on) { if (on) this->setSwingHorizontal(kMitsubishiHeavy88SwingH3D); @@ -703,26 +828,35 @@ void IRMitsubishiHeavy88Ac::set3D(const bool on) { this->setSwingHorizontal(kMitsubishiHeavy88SwingHOff); } +/// Get the 3D mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::get3D(void) { return this->getSwingHorizontal() == kMitsubishiHeavy88SwingH3D; } +/// Set the Clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::setClean(const bool on) { setBit(&remote_state[5], kMitsubishiHeavy88CleanOffset, on); } +/// Get the Clean mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::getClean(void) { return GETBIT8(remote_state[5], kMitsubishiHeavy88CleanOffset); } -// Verify the given state has a ZJ-S signature. +/// Verify the given state has a ZJ-S signature. +/// @param[in] state A ptr to a state to be checked. +/// @return true, the check passed. Otherwise, false. bool IRMitsubishiHeavy88Ac::checkZjsSig(const uint8_t *state) { for (uint8_t i = 0; i < kMitsubishiHeavySigLength; i++) if (state[i] != kMitsubishiHeavyZjsSig[i]) return false; return true; } -// Protocol technically has no checksum, but does has inverted byte pairs. +/// Calculate the checksum for the current internal state of the remote. +/// Note: Technically it has no checksum, but does has inverted byte pairs. void IRMitsubishiHeavy88Ac::checksum(void) { for (uint8_t i = kMitsubishiHeavySigLength - 2; i < kMitsubishiHeavy88StateLength; @@ -731,18 +865,26 @@ void IRMitsubishiHeavy88Ac::checksum(void) { } } -// Protocol technically has no checksum, but does has inverted byte pairs. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. +/// Note: Technically it has no checksum, but does has inverted byte pairs. bool IRMitsubishiHeavy88Ac::validChecksum(const uint8_t *state, const uint16_t length) { return IRMitsubishiHeavy152Ac::validChecksum(state, length); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy88Ac::convertMode(const stdAc::opmode_t mode) { return IRMitsubishiHeavy152Ac::convertMode(mode); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy88Ac::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { // Assumes Econo is slower than Low. @@ -755,7 +897,9 @@ uint8_t IRMitsubishiHeavy88Ac::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy88Ac::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kAuto: return kMitsubishiHeavy88SwingVAuto; @@ -768,7 +912,9 @@ uint8_t IRMitsubishiHeavy88Ac::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C horizontal swing into its native setting. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy88Ac::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kAuto: return kMitsubishiHeavy88SwingHAuto; @@ -781,7 +927,9 @@ uint8_t IRMitsubishiHeavy88Ac::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishiHeavy88Ac::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMitsubishiHeavy88FanTurbo: return stdAc::fanspeed_t::kMax; @@ -793,7 +941,9 @@ stdAc::fanspeed_t IRMitsubishiHeavy88Ac::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRMitsubishiHeavy88Ac::toCommonSwingH(const uint8_t pos) { switch (pos) { case kMitsubishiHeavy88SwingHLeftMax: return stdAc::swingh_t::kLeftMax; @@ -806,7 +956,9 @@ stdAc::swingh_t IRMitsubishiHeavy88Ac::toCommonSwingH(const uint8_t pos) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishiHeavy88Ac::toCommonSwingV(const uint8_t pos) { switch (pos) { case kMitsubishiHeavy88SwingVHighest: return stdAc::swingv_t::kHighest; @@ -819,7 +971,8 @@ stdAc::swingv_t IRMitsubishiHeavy88Ac::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishiHeavy88Ac::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI_HEAVY_88; @@ -844,7 +997,8 @@ stdAc::state_t IRMitsubishiHeavy88Ac::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishiHeavy88Ac::toString(void) { String result = ""; result.reserve(140); // Reserve some heap for the string to reduce fragging. @@ -955,19 +1109,15 @@ String IRMitsubishiHeavy88Ac::toString(void) { } #if DECODE_MITSUBISHIHEAVY -// Decode the supplied MitsubishiHeavy message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// Typically kMitsubishiHeavy88Bits or kMitsubishiHeavy152Bits (def). -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Appears to be working. Needs testing against a real device. +/// Decode the supplied Mitsubishi Heavy Industries A/C message. +/// Status: BETA / Appears to be working. Needs testing against a real device. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// Typically kMitsubishiHeavy88Bits or kMitsubishiHeavy152Bits (def). +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeMitsubishiHeavy(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict) { diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.h b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.h similarity index 82% rename from lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.h rename to lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.h index 39c30e0ac..2d9d4ff73 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_MitsubishiHeavy.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.h @@ -1,11 +1,21 @@ // Copyright 2019 David Conran +/// @file +/// @brief Support for Mitsubishi Heavy Industry protocols. +/// Code to emulate Mitsubishi Heavy Industries A/C IR remote control units. +/// @note This code was *heavily* influenced by ToniA's great work & code, +/// but it has been written from scratch. +/// Nothing was copied other than constants and message analysis. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/660 +/// @see https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp + // Supports: -// Brand: Mitsubishi Heavy Industries, Model: RLA502A700B remote -// Brand: Mitsubishi Heavy Industries, Model: SRKxxZM-S A/C -// Brand: Mitsubishi Heavy Industries, Model: SRKxxZMXA-S A/C -// Brand: Mitsubishi Heavy Industries, Model: RKX502A001C remote -// Brand: Mitsubishi Heavy Industries, Model: SRKxxZJ-S A/C +// Brand: Mitsubishi Heavy Industries, Model: RLA502A700B remote (152 bit) +// Brand: Mitsubishi Heavy Industries, Model: SRKxxZM-S A/C (152 bit) +// Brand: Mitsubishi Heavy Industries, Model: SRKxxZMXA-S A/C (152 bit) +// Brand: Mitsubishi Heavy Industries, Model: RKX502A001C remote (88 bit) +// Brand: Mitsubishi Heavy Industries, Model: SRKxxZJ-S A/C (88 bit) #ifndef IR_MITSUBISHIHEAVY_H_ #define IR_MITSUBISHIHEAVY_H_ @@ -19,15 +29,9 @@ #include "IRsend_test.h" #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/660 -// https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp -// https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp - // Constants. const uint8_t kMitsubishiHeavySigLength = 5; - // ZMS (152 bit) const uint8_t kMitsubishiHeavyZmsSig[kMitsubishiHeavySigLength] = { 0xAD, 0x51, 0x3C, 0xE5, 0x1A}; @@ -124,15 +128,20 @@ const uint8_t kMitsubishiHeavy88SwingVLowest = 0b111; // 7 // Classes + +/// Class for handling detailed Mitsubishi Heavy 152-bit A/C messages. class IRMitsubishiHeavy152Ac { public: explicit IRMitsubishiHeavy152Ac(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_MITSUBISHIHEAVY void send(const uint16_t repeat = kMitsubishiHeavy152MinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MITSUBISHIHEAVY void begin(void); @@ -197,24 +206,30 @@ class IRMitsubishiHeavy152Ac { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else // UNIT_TEST - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif // UNIT_TEST - // The state of the IR remote in IR code form. - uint8_t remote_state[kMitsubishiHeavy152StateLength]; + uint8_t remote_state[kMitsubishiHeavy152StateLength]; ///< State in code form void checksum(void); }; +/// Class for handling detailed Mitsubishi Heavy 88-bit A/C messages. class IRMitsubishiHeavy88Ac { public: explicit IRMitsubishiHeavy88Ac(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_MITSUBISHIHEAVY void send(const uint16_t repeat = kMitsubishiHeavy88MinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_MITSUBISHIHEAVY void begin(void); void on(void); @@ -268,12 +283,13 @@ class IRMitsubishiHeavy88Ac { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else // UNIT_TEST - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif // UNIT_TEST - // The state of the IR remote in IR code form. - uint8_t remote_state[kMitsubishiHeavy152StateLength]; + uint8_t remote_state[kMitsubishiHeavy88StateLength]; ///< State in code form void checksum(void); }; #endif // IR_MITSUBISHIHEAVY_H_ diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Multibrackets.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Multibrackets.cpp similarity index 74% rename from lib/IRremoteESP8266-2.7.7/src/ir_Multibrackets.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Multibrackets.cpp index 0a0dfbe71..2367b49bc 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Multibrackets.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Multibrackets.cpp @@ -1,13 +1,16 @@ // Copyright 2020 David Conran +/// @file +/// @brief Support for Multibrackets protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1103 +/// @see http://info.multibrackets.com/data/common/manuals/4500_code.pdf + +// Supports: +// Brand: Multibrackets, Model: Motorized Swing mount large - 4500 + #include "IRrecv.h" #include "IRsend.h" -// Multibrackets protocol. -// -// Supports: -// Brand: Multibrackets, Model: Motorized Swing mount large - 4500 - const uint16_t kMultibracketsTick = 5000; // uSeconds const uint16_t kMultibracketsHdrMark = 3 * kMultibracketsTick; // uSeconds const uint16_t kMultibracketsFooterSpace = 6 * kMultibracketsTick; // uSeconds @@ -15,19 +18,11 @@ const uint8_t kMultibracketsTolerance = 5; // Percent const uint16_t kMultibracketsFreq = 38000; // Hertz #if SEND_MULTIBRACKETS -// Send a Miltibrackets formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kMultibracketsBits. -// repeat: The number of times the command is to be repeated. -// -// Status: BETA / Appears to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1103 -// http://info.multibrackets.com/data/common/manuals/4500_code.pdf +/// Send a Multibrackets formatted message. +/// Status: BETA / Appears to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendMultibrackets(uint64_t data, uint16_t nbits, uint16_t repeat) { enableIROut(kMultibracketsFreq); for (uint16_t r = 0; r <= repeat; r++) { @@ -53,22 +48,14 @@ void IRsend::sendMultibrackets(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_MULTIBRACKETS #if DECODE_MULTIBRACKETS -// Decode the Multibrackets message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kMultibracketsBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Appears to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1103 -// http://info.multibrackets.com/data/common/manuals/4500_code.pdf +/// Decode the Multibrackets message. +/// Status: BETA / Appears to be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeMultibrackets(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_NEC.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_NEC.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.7/src/ir_NEC.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_NEC.cpp index 9145f5c24..ac816f2ed 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_NEC.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_NEC.cpp @@ -1,7 +1,10 @@ // Copyright 2009 Ken Shirriff // Copyright 2017 David Conran -// NEC originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @file +/// @brief Support for NEC (Renesas) protocols. +/// NEC originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @see http://www.sbprojects.com/knowledge/ir/nec.php #define __STDC_LIMIT_MACROS #include "ir_NEC.h" @@ -11,18 +14,17 @@ #include "IRsend.h" #include "IRutils.h" -#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO) -// Send a raw NEC(Renesas) formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. Typically kNECBits. -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE / Known working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php +// This protocol is used by a lot of other protocols, hence the long list. +#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO || \ + SEND_MIDEA24) + +/// Send a raw NEC(Renesas) formatted message. +/// Status: STABLE / Known working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol appears to have no header. +/// @see http://www.sbprojects.com/knowledge/ir/nec.php void IRsend::sendNEC(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(kNecHdrMark, kNecHdrSpace, kNecBitMark, kNecOneSpace, kNecBitMark, kNecZeroSpace, kNecBitMark, kNecMinGap, kNecMinCommandLength, @@ -37,17 +39,12 @@ void IRsend::sendNEC(uint64_t data, uint16_t nbits, uint16_t repeat) { 33); } -// Calculate the raw NEC data based on address and command. -// Args: -// address: An address value. -// command: An 8-bit command value. -// Returns: -// A raw 32-bit NEC message. -// -// Status: STABLE / Expected to work. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php +/// Calculate the raw NEC data based on address and command. +/// Status: STABLE / Expected to work. +/// @param[in] address An address value. +/// @param[in] command An 8-bit command value. +/// @return A raw 32-bit NEC message suitable for use with `sendNEC()`. +/// @see http://www.sbprojects.com/knowledge/ir/nec.php uint32_t IRsend::encodeNEC(uint16_t address, uint16_t command) { command &= 0xFF; // We only want the least significant byte of command. // sendNEC() sends MSB first, but protocol says this is LSB first. @@ -61,32 +58,26 @@ uint32_t IRsend::encodeNEC(uint16_t address, uint16_t command) { return (address << 24) + ((address ^ 0xFF) << 16) + command; // Normal. } } -#endif // (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO ) +#endif // (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO || + // SEND_MIDEA24) +// This protocol is used by a lot of other protocols, hence the long list. #if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || DECODE_SANYO) -// Decode the supplied NEC message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kNECBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known good. -// -// Notes: -// NEC protocol has three varients/forms. -// Normal: an 8 bit address & an 8 bit command in 32 bit data form. -// i.e. address + inverted(address) + command + inverted(command) -// Extended: a 16 bit address & an 8 bit command in 32 bit data form. -// i.e. address + command + inverted(command) -// Repeat: a 0-bit code. i.e. No data bits. Just the header + footer. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php +/// Decode the supplied NEC (Renesas) message. +/// Status: STABLE / Known good. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note NEC protocol has three variants/forms. +/// Normal: an 8 bit address & an 8 bit command in 32 bit data form. +/// i.e. address + inverted(address) + command + inverted(command) +/// Extended: a 16 bit address & an 8 bit command in 32 bit data form. +/// i.e. address + command + inverted(command) +/// Repeat: a 0-bit code. i.e. No data bits. Just the header + footer. +/// @see http://www.sbprojects.com/knowledge/ir/nec.php bool IRrecv::decodeNEC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < kNecRptLength + offset - 1) @@ -145,4 +136,5 @@ bool IRrecv::decodeNEC(decode_results *results, uint16_t offset, results->address = reverseBits((data >> 16) & UINT16_MAX, 16); return true; } -#endif // DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || DECODE_SANYO +#endif // (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || + // DECODE_SANYO) diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_NEC.h b/lib/IRremoteESP8266-2.7.8/src/ir_NEC.h similarity index 88% rename from lib/IRremoteESP8266-2.7.7/src/ir_NEC.h rename to lib/IRremoteESP8266-2.7.8/src/ir_NEC.h index cf6191100..48b1c09a2 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_NEC.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_NEC.h @@ -1,7 +1,19 @@ // Copyright 2009 Ken Shirriff // Copyright 2017, 2018 David Conran -// NEC originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @file +/// @brief Support for NEC (Renesas) protocols. +/// NEC originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @see http://www.sbprojects.com/knowledge/ir/nec.php + +// Supports: +// Brand: Yamaha, Model: RAV561 remote +// Brand: Yamaha, Model: RXV585B A/V Receiver +// Brand: Aloka, Model: SleepyLights LED Lamp +// Brand: Toshiba, Model: 42TL838 LCD TV +// Brand: Duux, Model: Blizzard Smart 10K / DXMA04 A/C +// Brand: Duux, Model: YJ-A081 TR Remote +// Brand: Silan Microelectronics, Model: SC6121-001 IC #ifndef IR_NEC_H_ #define IR_NEC_H_ @@ -9,15 +21,7 @@ #include #include "IRremoteESP8266.h" -// Supports: -// Brand: Yamaha, Model: RAV561 remote -// Brand: Yamaha, Model: RXV585B A/V Receiver -// Brand: Aloka, Model: SleepyLights LED Lamp -// Brand: Toshiba, Model: 42TL838 LCD TV - // Constants -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php const uint16_t kNecTick = 560; const uint16_t kNecHdrMarkTicks = 16; const uint16_t kNecHdrMark = kNecHdrMarkTicks * kNecTick; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.cpp similarity index 68% rename from lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.cpp index 8c93ef26f..c81a69e02 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.cpp @@ -1,17 +1,11 @@ // Copyright 2019 David Conran -// Neoclima A/C support - -// Analysis by crankyoldgit & AndreyShpilevoy -// Code by crankyoldgit -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/764 -// https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view - - -// Supports: -// Brand: Neoclima, Model: NS-09AHTI A/C -// Brand: Neoclima, Model: ZH/TY-01 remote +/// @file +/// @brief Support for Neoclima protocols. +/// Analysis by crankyoldgit & AndreyShpilevoy +/// Code by crankyoldgit +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/764 +/// @see https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view #include "ir_Neoclima.h" #include @@ -22,7 +16,6 @@ #include "IRutils.h" // Constants - const uint16_t kNeoclimaHdrMark = 6112; const uint16_t kNeoclimaHdrSpace = 7391; const uint16_t kNeoclimaBitMark = 537; @@ -40,17 +33,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_NEOCLIMA -// Send a Neoclima message. -// -// Args: -// data: message to be sent. -// nbytes: Nr. of bytes of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: Beta / Known to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/764 +/// Send a Neoclima message. +/// Status: STABLE / Known to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendNeoclima(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { // Set IR carrier frequency @@ -70,54 +57,77 @@ void IRsend::sendNeoclima(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_NEOCLIMA +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRNeoclimaAc::IRNeoclimaAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the state of the remote to a known good state/sequence. void IRNeoclimaAc::stateReset(void) { static const uint8_t kReset[kNeoclimaStateLength] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x2A, 0xA5}; setRaw(kReset); } +/// Set up hardware to be able to send a message. void IRNeoclimaAc::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRNeoclimaAc::calcChecksum(const uint8_t state[], const uint16_t length) { if (length == 0) return state[0]; return sumBytes(state, length - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRNeoclimaAc::validChecksum(const uint8_t state[], const uint16_t length) { if (length < 2) return true; // No checksum to compare with. Assume okay. return (state[length - 1] == calcChecksum(state, length)); } -// Update the checksum for the internal state. +/// Calculate & update the checksum for the internal state. +/// @param[in] length The length/size of the internal state. void IRNeoclimaAc::checksum(uint16_t length) { if (length < 2) return; remote_state[length - 1] = calcChecksum(remote_state, length); } #if SEND_NEOCLIMA +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRNeoclimaAc::send(const uint16_t repeat) { _irsend.sendNeoclima(getRaw(), kNeoclimaStateLength, repeat); } #endif // SEND_NEOCLIMA +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRNeoclimaAc::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. void IRNeoclimaAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kNeoclimaStateLength)); } - +/// Set the Button/Command pressed setting of the A/C. +/// @param[in] button The value of the button/command that was pressed. void IRNeoclimaAc::setButton(const uint8_t button) { switch (button) { case kNeoclimaButtonPower: @@ -144,23 +154,33 @@ void IRNeoclimaAc::setButton(const uint8_t button) { } } +/// Get the Button/Command setting of the A/C. +/// @return The value of the button/command that was pressed. uint8_t IRNeoclimaAc::getButton(void) { return GETBITS8(remote_state[5], kNeoclimaButtonOffset, kNeoclimaButtonSize); } +/// Set the requested power state of the A/C to on. void IRNeoclimaAc::on(void) { this->setPower(true); } +/// Set the requested power state of the A/C to off. void IRNeoclimaAc::off(void) { this->setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setPower(const bool on) { this->setButton(kNeoclimaButtonPower); setBit(&remote_state[7], kNeoclimaPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getPower(void) { return GETBIT8(remote_state[7], kNeoclimaPowerOffset); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRNeoclimaAc::setMode(const uint8_t mode) { switch (mode) { case kNeoclimaDry: @@ -180,11 +200,15 @@ void IRNeoclimaAc::setMode(const uint8_t mode) { } } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRNeoclimaAc::getMode(void) { return GETBITS8(remote_state[9], kNeoclimaModeOffset, kModeBitsSize); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRNeoclimaAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kNeoclimaCool; @@ -195,7 +219,9 @@ uint8_t IRNeoclimaAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRNeoclimaAc::toCommonMode(const uint8_t mode) { switch (mode) { case kNeoclimaCool: return stdAc::opmode_t::kCool; @@ -206,7 +232,8 @@ stdAc::opmode_t IRNeoclimaAc::toCommonMode(const uint8_t mode) { } } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRNeoclimaAc::setTemp(const uint8_t temp) { uint8_t oldtemp = this->getTemp(); uint8_t newtemp = std::max(kNeoclimaMinTemp, temp); @@ -219,13 +246,15 @@ void IRNeoclimaAc::setTemp(const uint8_t temp) { newtemp - kNeoclimaMinTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRNeoclimaAc::getTemp(void) { return GETBITS8(remote_state[9], kNeoclimaTempOffset, kNeoclimaTempSize) + kNeoclimaMinTemp; } -// Set the speed of the fan, 0-3, 0 is auto, 1-3 is the speed +/// Set the speed of the fan. +/// @param[in] speed The desired setting. 0-3, 0 is auto, 1-3 is the speed void IRNeoclimaAc::setFan(const uint8_t speed) { switch (speed) { case kNeoclimaFanAuto: @@ -246,11 +275,15 @@ void IRNeoclimaAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRNeoclimaAc::getFan(void) { return GETBITS8(remote_state[7], kNeoclimaFanOffest, kNeoclimaFanSize); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRNeoclimaAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -262,7 +295,9 @@ uint8_t IRNeoclimaAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRNeoclimaAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kNeoclimaFanHigh: return stdAc::fanspeed_t::kMax; @@ -272,99 +307,138 @@ stdAc::fanspeed_t IRNeoclimaAc::toCommonFanSpeed(const uint8_t speed) { } } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setSleep(const bool on) { this->setButton(kNeoclimaButtonSleep); setBit(&remote_state[7], kNeoclimaSleepOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getSleep(void) { return GETBIT8(remote_state[7], kNeoclimaSleepOffset); } -// A.k.a. Swing +/// Set the vertical swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setSwingV(const bool on) { this->setButton(kNeoclimaButtonSwing); setBits(&remote_state[7], kNeoclimaSwingVOffset, kNeoclimaSwingVSize, on ? kNeoclimaSwingVOn : kNeoclimaSwingVOff); } +/// Get the vertical swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getSwingV(void) { return GETBITS8(remote_state[7], kNeoclimaSwingVOffset, kNeoclimaSwingVSize) == kNeoclimaSwingVOn; } -// A.k.a. Air Flow +/// Set the horizontal swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setSwingH(const bool on) { this->setButton(kNeoclimaButtonAirFlow); setBit(&remote_state[7], kNeoclimaSwingHOffset, !on); // Cleared when `on` } +/// Get the horizontal swing (Air Flow) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getSwingH(void) { return !GETBIT8(remote_state[7], kNeoclimaSwingHOffset); } +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setTurbo(const bool on) { this->setButton(kNeoclimaButtonTurbo); setBit(&remote_state[3], kNeoclimaTurboOffset, on); } +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getTurbo(void) { return GETBIT8(remote_state[3], kNeoclimaTurboOffset); } +/// Set the Fresh (air) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setFresh(const bool on) { this->setButton(kNeoclimaButtonFresh); setBit(&remote_state[5], kNeoclimaFreshOffset, on); } +/// Get the Frsh (air) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getFresh(void) { return GETBIT8(remote_state[5], kNeoclimaFreshOffset); } +/// Set the Hold setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setHold(const bool on) { this->setButton(kNeoclimaButtonHold); setBit(&remote_state[3], kNeoclimaHoldOffset, on); } +/// Get the Hold setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getHold(void) { return GETBIT8(remote_state[3], kNeoclimaHoldOffset); } +/// Set the Ion (filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setIon(const bool on) { this->setButton(kNeoclimaButtonIon); setBit(&remote_state[1], kNeoclimaIonOffset, on); } +/// Get the Ion (filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getIon(void) { return GETBIT8(remote_state[1], kNeoclimaIonOffset); } +/// Set the Light(LED display) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setLight(const bool on) { this->setButton(kNeoclimaButtonLight); setBit(&remote_state[3], kNeoclimaLightOffset, on); } +/// Get the Light (LED display) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getLight(void) { return GETBIT8(remote_state[3], kNeoclimaLightOffset); } -// This feature maintains the room temperature steadily at 8°C and prevents the -// room from freezing by activating the heating operation automatically when -// nobody is at home over a longer period during severe winter. +/// Set the 8°C Heat setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note This feature maintains the room temperature steadily at 8°C and +/// prevents the room from freezing by activating the heating operation +/// automatically when nobody is at home over a longer period during severe +/// winter. void IRNeoclimaAc::set8CHeat(const bool on) { this->setButton(kNeoclimaButton8CHeat); setBit(&remote_state[1], kNeoclima8CHeatOffset, on); } +/// Get the 8°C Heat setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::get8CHeat(void) { return GETBIT8(remote_state[1], kNeoclima8CHeatOffset); } +/// Set the Eye (Sensor) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setEye(const bool on) { this->setButton(kNeoclimaButtonEye); setBit(&remote_state[3], kNeoclimaEyeOffset, on); } +/// Get the Eye (Sensor) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getEye(void) { return GETBIT8(remote_state[3], kNeoclimaEyeOffset); } @@ -380,11 +454,14 @@ void IRNeoclimaAc::setFollow(const bool on) { } */ +/// Get the Follow Me setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getFollow(void) { return (remote_state[8] & kNeoclimaFollowMe) == kNeoclimaFollowMe; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRNeoclimaAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::NEOCLIMA; @@ -411,7 +488,8 @@ stdAc::state_t IRNeoclimaAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRNeoclimaAc::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -459,21 +537,14 @@ String IRNeoclimaAc::toString(void) { } #if DECODE_NEOCLIMA -// Decode the supplied Neoclima message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. Typically kNeoclimaBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known working -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/764 +/// Decode the supplied Neoclima message. +/// Status: STABLE / Known working +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeNeoclima(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.h b/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.h similarity index 84% rename from lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.h index e1555e917..cdec89fce 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Neoclima.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.h @@ -1,8 +1,14 @@ -// Neoclima A/C -// // Copyright 2019 David Conran -// Analysis by crankyoldgit & AndreyShpilevoy +/// @file +/// @brief Support for Neoclima protocols. +/// Analysis by crankyoldgit & AndreyShpilevoy +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/764 +/// @see https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view + +// Supports: +// Brand: Neoclima, Model: NS-09AHTI A/C +// Brand: Neoclima, Model: ZH/TY-01 remote #ifndef IR_NEOCLIMA_H_ #define IR_NEOCLIMA_H_ @@ -18,14 +24,6 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Neoclima, Model: NS-09AHTI A/C -// Brand: Neoclima, Model: ZH/TY-01 remote - -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/764 -// https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view - // Constants // state[1] const uint8_t kNeoclima8CHeatOffset = 1; @@ -84,14 +82,18 @@ const uint8_t kNeoclimaFan = 0b011; const uint8_t kNeoclimaHeat = 0b100; // Classes +/// Class for handling detailed Neoclima A/C messages. class IRNeoclimaAc { public: explicit IRNeoclimaAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_NEOCLIMA void send(const uint16_t repeat = kNeoclimaMinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_NEOCLIMA void begin(void); @@ -146,12 +148,13 @@ class IRNeoclimaAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kNeoclimaStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kNeoclimaStateLength]; ///< State of the remote in code. void checksum(const uint16_t length = kNeoclimaStateLength); }; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Nikai.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Nikai.cpp similarity index 66% rename from lib/IRremoteESP8266-2.7.7/src/ir_Nikai.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Nikai.cpp index 5e6f9fbe5..01c789d70 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Nikai.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Nikai.cpp @@ -1,7 +1,12 @@ // Copyright 2009 Ken Shirriff // Copyright 2017 David Conran -// Nikai +/// @file +/// @brief Nikai +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/309 + +// Supports: +// Brand: Nikai, Model: Unknown LCD TV #include #include "IRrecv.h" @@ -9,8 +14,6 @@ #include "IRutils.h" // Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/309 const uint16_t kNikaiTick = 500; const uint16_t kNikaiHdrMarkTicks = 8; const uint16_t kNikaiHdrMark = kNikaiHdrMarkTicks * kNikaiTick; @@ -26,38 +29,26 @@ const uint16_t kNikaiMinGapTicks = 17; const uint16_t kNikaiMinGap = kNikaiMinGapTicks * kNikaiTick; #if SEND_NIKAI -// Send a Nikai TV formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kNikaiBits. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/309 +/// Send a Nikai formatted message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendNikai(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(kNikaiHdrMark, kNikaiHdrSpace, kNikaiBitMark, kNikaiOneSpace, kNikaiBitMark, kNikaiZeroSpace, kNikaiBitMark, kNikaiMinGap, data, nbits, 38, true, repeat, 33); } -#endif +#endif // SEND_NIKAI #if DECODE_NIKAI -// Decode the supplied Nikai message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kNikaiBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// +/// Decode the supplied Nikai message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. bool IRrecv::decodeNikai(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kNikaiBits) @@ -80,4 +71,4 @@ bool IRrecv::decodeNikai(decode_results *results, uint16_t offset, results->address = 0; return true; } -#endif +#endif // DECODE_NIKAI diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.cpp index d8b627c9f..b1702824f 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.cpp @@ -1,7 +1,16 @@ // Copyright 2015 Kristian Lauszus // Copyright 2017, 2018 David Conran -// Panasonic devices +/// @file +/// @brief Support for Panasonic protocols. +/// Panasonic protocol originally added by Kristian Lauszus +/// (Thanks to zenwheel and other people at the original blog post) +/// @see Panasonic https://github.com/z3t0/Arduino-IRremote +/// @see http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615 +/// @see Panasonic A/C support heavily influenced by https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp +/// Panasonic A/C Clock & Timer support: +/// Reverse Engineering by MikkelTb +/// Code by crankyoldgit #include "ir_Panasonic.h" #include @@ -14,29 +23,8 @@ #include "IRtext.h" #include "IRutils.h" -// Panasonic protocol originally added by Kristian Lauszus from: -// https://github.com/z3t0/Arduino-IRremote -// (Thanks to zenwheel and other people at the original blog post) -// -// Panasonic A/C support add by crankyoldgit but heavily influenced by: -// https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp -// Panasonic A/C Clock & Timer support: -// Reverse Engineering by MikkelTb -// Code by crankyoldgit -// Panasonic A/C models supported: -// A/C Series/models: -// JKE, LKE, DKE, CKP, PKR, RKR, & NKE series. (In theory) -// CS-YW9MKD, CS-Z9RKR, CS-E7PKR (confirmed) -// CS-ME14CKPG / CS-ME12CKPG / CS-ME10CKPG -// A/C Remotes: -// A75C3747 (confirmed) -// A75C3704 -// A75C2311 (CKP) - // Constants -// Ref: -// http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152 - +/// @see http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152 const uint16_t kPanasonicTick = 432; const uint16_t kPanasonicHdrMarkTicks = 8; const uint16_t kPanasonicHdrMark = kPanasonicHdrMarkTicks * kPanasonicTick; @@ -74,18 +62,15 @@ using irutils::minsToString; using irutils::setBit; using irutils::setBits; +// Used by Denon as well. #if (SEND_PANASONIC || SEND_DENON) -// Send a Panasonic formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. (kPanasonicBits). -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE / Should be working. -// -// Note: -// This protocol is a modified version of Kaseikyo. +/// Send a Panasonic formatted message. +/// Status: STABLE / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol is a modified version of Kaseikyo. +/// @note Use this method if you want to send the results of `decodePanasonic`. void IRsend::sendPanasonic64(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kPanasonicHdrMark, kPanasonicHdrSpace, kPanasonicBitMark, @@ -94,39 +79,29 @@ void IRsend::sendPanasonic64(const uint64_t data, const uint16_t nbits, data, nbits, kPanasonicFreq, true, repeat, 50); } -// Send a Panasonic formatted message. -// -// Args: -// address: The manufacturer code. -// data: The data portion to be sent. -// nbits: The number of bits of the message to be sent. (kPanasonicBits). -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE. -// -// Note: -// This protocol is a modified version of Kaseikyo. +/// Send a Panasonic formatted message. +/// Status: STABLE, but DEPRECATED +/// @deprecated This is only for legacy use only, please use `sendPanasonic64()` +/// instead. +/// @param[in] address The 16-bit manufacturer code. +/// @param[in] data The 32-bit data portion of the message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol is a modified version of Kaseikyo. void IRsend::sendPanasonic(const uint16_t address, const uint32_t data, const uint16_t nbits, const uint16_t repeat) { sendPanasonic64(((uint64_t)address << 32) | (uint64_t)data, nbits, repeat); } -// Calculate the raw Panasonic data based on device, subdevice, & function. -// -// Args: -// manufacturer: A 16-bit manufacturer code. e.g. 0x4004 is Panasonic. -// device: An 8-bit code. -// subdevice: An 8-bit code. -// function: An 8-bit code. -// Returns: -// A raw uint64_t Panasonic message. -// -// Status: STABLE / Should be working.. -// -// Note: -// Panasonic 48-bit protocol is a modified version of Kaseikyo. -// Ref: -// http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615 +/// Calculate the raw Panasonic data based on device, subdevice, & function. +/// Status: STABLE / Should be working. +/// @param[in] manufacturer A 16-bit manufacturer code. e.g. 0x4004 is Panasonic +/// @param[in] device An 8-bit code. +/// @param[in] subdevice An 8-bit code. +/// @param[in] function An 8-bit code. +/// @return A value suitable for use with `sendPanasonic64()`. +/// @note Panasonic 48-bit protocol is a modified version of Kaseikyo. +/// @see http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615 uint64_t IRsend::encodePanasonic(const uint16_t manufacturer, const uint8_t device, const uint8_t subdevice, @@ -137,24 +112,21 @@ uint64_t IRsend::encodePanasonic(const uint16_t manufacturer, } #endif // (SEND_PANASONIC || SEND_DENON) +// Used by Denon as well. #if (DECODE_PANASONIC || DECODE_DENON) -// Decode the supplied Panasonic message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. -// Note: -// Panasonic 48-bit protocol is a modified version of Kaseikyo. -// Ref: -// http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152 -// http://www.hifi-remote.com/wiki/index.php?title=Panasonic +/// Decode the supplied Panasonic message. +/// Status: STABLE / Should be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] manufacturer A 16-bit manufacturer code. e.g. 0x4004 is Panasonic +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @warning Results to be used with `sendPanasonic64()`, not `sendPanasonic()`. +/// @note Panasonic 48-bit protocol is a modified version of Kaseikyo. +/// @see http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615 +/// @see http://www.hifi-remote.com/wiki/index.php?title=Panasonic bool IRrecv::decodePanasonic(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict, const uint32_t manufacturer) { @@ -193,24 +165,11 @@ bool IRrecv::decodePanasonic(decode_results *results, uint16_t offset, #endif // (DECODE_PANASONIC || DECODE_DENON) #if SEND_PANASONIC_AC -// Send a Panasonic A/C message. -// -// Args: -// data: Contents of the message to be sent. (Guessing MSBF order) -// nbits: Nr. of bits of data to be sent. Typically kPanasonicAcBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: Beta / Appears to work with real device(s). -//: -// Panasonic A/C models supported: -// A/C Series/models: -// JKE, LKE, DKE, CKP, PKR, RKR, & NKE series. -// CS-YW9MKD -// CS-E7PKR -// A/C Remotes: -// A75C3747 -// A75C3704 -// +/// Send a Panasonic A/C message. +/// Status: STABLE / Work with real device(s). +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendPanasonicAC(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kPanasonicAcSection1Length) return; @@ -231,44 +190,59 @@ void IRsend::sendPanasonicAC(const uint8_t data[], const uint16_t nbytes, } #endif // SEND_PANASONIC_AC +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRPanasonicAc::IRPanasonicAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the state of the remote to a known good state/sequence. void IRPanasonicAc::stateReset(void) { memcpy(remote_state, kPanasonicKnownGoodState, kPanasonicAcStateLength); _temp = 25; // An initial saved desired temp. Completely made up. _swingh = kPanasonicAcSwingHMiddle; // A similar made up value for H Swing. } +/// Set up hardware to be able to send a message. void IRPanasonicAc::begin(void) { _irsend.begin(); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. -bool IRPanasonicAc::validChecksum(uint8_t state[], const uint16_t length) { +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. +bool IRPanasonicAc::validChecksum(const uint8_t *state, const uint16_t length) { if (length < 2) return false; // 1 byte of data can't have a checksum. return (state[length - 1] == sumBytes(state, length - 1, kPanasonicAcChecksumInit)); } -uint8_t IRPanasonicAc::calcChecksum(uint8_t state[], const uint16_t length) { +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @param[in] length The size/length of the state. +/// @return The calculated checksum value. +uint8_t IRPanasonicAc::calcChecksum(const uint8_t *state, + const uint16_t length) { return sumBytes(state, length - 1, kPanasonicAcChecksumInit); } +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The size/length of the state. void IRPanasonicAc::fixChecksum(const uint16_t length) { remote_state[length - 1] = this->calcChecksum(remote_state, length); } #if SEND_PANASONIC_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRPanasonicAc::send(const uint16_t repeat) { _irsend.sendPanasonicAC(getRaw(), kPanasonicAcStateLength, repeat); } #endif // SEND_PANASONIC_AC +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRPanasonicAc::setModel(const panasonic_ac_remote_model_t model) { switch (model) { case panasonic_ac_remote_model_t::kPanasonicDke: @@ -317,6 +291,8 @@ void IRPanasonicAc::setModel(const panasonic_ac_remote_model_t model) { setIon(getIon()); } +/// Get/Detect the model of the A/C. +/// @return The enum of the compatible model. panasonic_ac_remote_model_t IRPanasonicAc::getModel(void) { if (remote_state[23] == 0x89) return kPanasonicRkr; if (remote_state[17] == 0x00) { @@ -334,45 +310,55 @@ panasonic_ac_remote_model_t IRPanasonicAc::getModel(void) { return panasonic_ac_remote_model_t::kPanasonicUnknown; // Default } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRPanasonicAc::getRaw(void) { this->fixChecksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. void IRPanasonicAc::setRaw(const uint8_t state[]) { memcpy(remote_state, state, kPanasonicAcStateLength); } -// Control the power state of the A/C unit. -// -// For CKP models, the remote has no memory of the power state the A/C unit -// should be in. For those models setting this on/true will toggle the power -// state of the Panasonic A/C unit with the next meessage. -// e.g. If the A/C unit is already on, setPower(true) will turn it off. -// If the A/C unit is already off, setPower(true) will turn it on. -// setPower(false) will leave the A/C power state as it was. -// -// For all other models, setPower(true) should set the internal state to -// turn it on, and setPower(false) should turn it off. +/// Control the power state of the A/C unit. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @warning For CKP models, the remote has no memory of the power state the A/C +/// unit should be in. For those models setting this on/true will toggle the +/// power state of the Panasonic A/C unit with the next meessage. +/// e.g. If the A/C unit is already on, setPower(true) will turn it off. +/// If the A/C unit is already off, setPower(true) will turn it on. +/// `setPower(false)` will leave the A/C power state as it was. +/// For all other models, setPower(true) should set the internal state to +/// turn it on, and setPower(false) should turn it off. void IRPanasonicAc::setPower(const bool on) { setBit(&remote_state[13], kPanasonicAcPowerOffset, on); } -// Return the A/C power state of the remote. -// Except for CKP models, where it returns if the power state will be toggled -// on the A/C unit when the next message is sent. +/// Get the A/C power state of the remote. +/// @return true, the setting is on. false, the setting is off. +/// @warning Except for CKP models, where it returns if the power state will be +/// toggled on the A/C unit when the next message is sent. bool IRPanasonicAc::getPower(void) { return GETBIT8(remote_state[13], kPanasonicAcPowerOffset); } +/// Change the power setting to On. void IRPanasonicAc::on(void) { setPower(true); } +/// Change the power setting to Off. void IRPanasonicAc::off(void) { setPower(false); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRPanasonicAc::getMode(void) { return GETBITS8(remote_state[13], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] desired The desired operating mode. void IRPanasonicAc::setMode(const uint8_t desired) { uint8_t mode = kPanasonicAcAuto; // Default to Auto mode. switch (desired) { @@ -394,17 +380,17 @@ void IRPanasonicAc::setMode(const uint8_t desired) { setBits(&remote_state[13], kHighNibble, kModeBitsSize, mode); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRPanasonicAc::getTemp(void) { return GETBITS8(remote_state[14], kPanasonicAcTempOffset, kPanasonicAcTempSize); } -// Set the desitred temperature in Celsius. -// Args: -// celsius: The temperature to set the A/C unit to. -// remember: A boolean flag for the class to remember the temperature. -// -// Automatically safely limits the temp to the operating range supported. +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. +/// @param[in] remember: A flag for the class to remember the temperature. +/// @note Automatically safely limits the temp to the operating range supported. void IRPanasonicAc::setTemp(const uint8_t celsius, const bool remember) { uint8_t temperature; temperature = std::max(celsius, kPanasonicAcMinTemp); @@ -414,10 +400,14 @@ void IRPanasonicAc::setTemp(const uint8_t celsius, const bool remember) { temperature); } +/// Get the current vertical swing setting. +/// @return The current position it is set to. uint8_t IRPanasonicAc::getSwingVertical(void) { return GETBITS8(remote_state[16], kLowNibble, kNibbleSize); } +/// Control the vertical swing setting. +/// @param[in] desired_elevation The position to set the vertical swing to. void IRPanasonicAc::setSwingVertical(const uint8_t desired_elevation) { uint8_t elevation = desired_elevation; if (elevation != kPanasonicAcSwingVAuto) { @@ -427,10 +417,14 @@ void IRPanasonicAc::setSwingVertical(const uint8_t desired_elevation) { setBits(&remote_state[16], kLowNibble, kNibbleSize, elevation); } +/// Get the current horizontal swing setting. +/// @return The current position it is set to. uint8_t IRPanasonicAc::getSwingHorizontal(void) { return GETBITS8(remote_state[17], kLowNibble, kNibbleSize); } +/// Control the horizontal swing setting. +/// @param[in] desired_direction The position to set the horizontal swing to. void IRPanasonicAc::setSwingHorizontal(const uint8_t desired_direction) { switch (desired_direction) { case kPanasonicAcSwingHAuto: @@ -458,6 +452,8 @@ void IRPanasonicAc::setSwingHorizontal(const uint8_t desired_direction) { setBits(&remote_state[17], kLowNibble, kNibbleSize, direction); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRPanasonicAc::setFan(const uint8_t speed) { switch (speed) { case kPanasonicAcFanMin: @@ -471,11 +467,15 @@ void IRPanasonicAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRPanasonicAc::getFan(void) { return GETBITS8(remote_state[16], kHighNibble, kNibbleSize) - kPanasonicAcFanDelta; } +/// Get the Quiet setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::getQuiet(void) { switch (this->getModel()) { case kPanasonicRkr: @@ -486,6 +486,8 @@ bool IRPanasonicAc::getQuiet(void) { } } +/// Set the Quiet setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRPanasonicAc::setQuiet(const bool on) { uint8_t offset; switch (this->getModel()) { @@ -497,6 +499,8 @@ void IRPanasonicAc::setQuiet(const bool on) { setBit(&remote_state[21], offset, on); } +/// Get the Powerful (Turbo) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::getPowerful(void) { switch (this->getModel()) { case kPanasonicRkr: @@ -507,6 +511,8 @@ bool IRPanasonicAc::getPowerful(void) { } } +/// Set the Powerful (Turbo) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRPanasonicAc::setPowerful(const bool on) { uint8_t offset; switch (this->getModel()) { @@ -519,11 +525,18 @@ void IRPanasonicAc::setPowerful(const bool on) { setBit(&remote_state[21], offset, on); } -// Convert standard (military/24hr) time to nr. of minutes since midnight. +/// Convert standard (military/24hr) time to nr. of minutes since midnight. +/// @param[in] hours The hours component of the time. +/// @param[in] mins The minutes component of the time. +/// @return The nr of minutes since midnight. uint16_t IRPanasonicAc::encodeTime(const uint8_t hours, const uint8_t mins) { return std::min(hours, (uint8_t)23) * 60 + std::min(mins, (uint8_t)59); } +/// Get the time from a given pointer location. +/// @param[in] ptr A pointer to a time location in a state. +/// @return The time expressed as nr. of minutes past midnight. +/// @note Internal use only. uint16_t IRPanasonicAc::_getTime(const uint8_t ptr[]) { uint16_t result = (GETBITS8( ptr[1], kLowNibble, kPanasonicAcTimeOverflowSize) << @@ -532,8 +545,15 @@ uint16_t IRPanasonicAc::_getTime(const uint8_t ptr[]) { return result; } +/// Get the current clock time value. +/// @return The time expressed as nr. of minutes past midnight. uint16_t IRPanasonicAc::getClock(void) { return _getTime(&remote_state[24]); } +/// Set the time at a given pointer location. +/// @param[in, out] ptr A pointer to a time location in a state. +/// @param[in] mins_since_midnight The time as nr. of minutes past midnight. +/// @param[in] round_down Do we round to the nearest 10 minute mark? +/// @note Internal use only. void IRPanasonicAc::_setTime(uint8_t * const ptr, const uint16_t mins_since_midnight, const bool round_down) { @@ -546,12 +566,19 @@ void IRPanasonicAc::_setTime(uint8_t * const ptr, corrected >> (kPanasonicAcTimeSize - kPanasonicAcTimeOverflowSize)); } +/// Set the current clock time value. +/// @param[in] mins_since_midnight The time as nr. of minutes past midnight. void IRPanasonicAc::setClock(const uint16_t mins_since_midnight) { _setTime(&remote_state[24], mins_since_midnight, false); } +/// Get the On Timer time value. +/// @return The time expressed as nr. of minutes past midnight. uint16_t IRPanasonicAc::getOnTimer(void) { return _getTime(&remote_state[18]); } +/// Set/Enable the On Timer. +/// @param[in] mins_since_midnight The time as nr. of minutes past midnight. +/// @param[in] enable Do we enable the timer or not? void IRPanasonicAc::setOnTimer(const uint16_t mins_since_midnight, const bool enable) { // Set the timer flag. @@ -560,12 +587,17 @@ void IRPanasonicAc::setOnTimer(const uint16_t mins_since_midnight, _setTime(&remote_state[18], mins_since_midnight, true); } +/// Cancel the On Timer. void IRPanasonicAc::cancelOnTimer(void) { this->setOnTimer(0, false); } +/// Check if the On Timer is Enabled. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::isOnTimerEnabled(void) { return GETBIT8(remote_state[13], kPanasonicAcOnTimerOffset); } +/// Get the Off Timer time value. +/// @return The time expressed as nr. of minutes past midnight. uint16_t IRPanasonicAc::getOffTimer(void) { uint16_t result = (GETBITS8(remote_state[20], 0, 7) << kNibbleSize) | GETBITS8(remote_state[19], kHighNibble, kNibbleSize); @@ -573,6 +605,9 @@ uint16_t IRPanasonicAc::getOffTimer(void) { return result; } +/// Set/Enable the Off Timer. +/// @param[in] mins_since_midnight The time as nr. of minutes past midnight. +/// @param[in] enable Do we enable the timer or not? void IRPanasonicAc::setOffTimer(const uint16_t mins_since_midnight, const bool enable) { // Ensure its on a 10 minute boundary and no overflow. @@ -587,12 +622,17 @@ void IRPanasonicAc::setOffTimer(const uint16_t mins_since_midnight, setBits(&remote_state[20], 0, 7, corrected >> kNibbleSize); } +/// Cancel the Off Timer. void IRPanasonicAc::cancelOffTimer(void) { this->setOffTimer(0, false); } +/// Check if the Off Timer is Enabled. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::isOffTimerEnabled(void) { return GETBIT8(remote_state[13], kPanasonicAcOffTimerOffset); } +/// Get the Ion (filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::getIon(void) { switch (this->getModel()) { case kPanasonicDke: @@ -603,13 +643,17 @@ bool IRPanasonicAc::getIon(void) { } } +/// Set the Ion (filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRPanasonicAc::setIon(const bool on) { if (this->getModel() == kPanasonicDke) setBit(&remote_state[kPanasonicAcIonFilterByte], kPanasonicAcIonFilterOffset, on); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRPanasonicAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kPanasonicAcCool; @@ -620,7 +664,9 @@ uint8_t IRPanasonicAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRPanasonicAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kPanasonicAcFanMin; @@ -632,7 +678,9 @@ uint8_t IRPanasonicAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a standard A/C vertical swing into its native setting. +/// @param[in] position A stdAc::swingv_t position to convert. +/// @return The equivilent native horizontal swing position. uint8_t IRPanasonicAc::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -644,7 +692,9 @@ uint8_t IRPanasonicAc::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C horizontal swing into its native setting. +/// Convert a standard A/C horizontal swing into its native setting. +/// @param[in] position A stdAc::swingh_t position to convert. +/// @return The equivilent native horizontal swing position. uint8_t IRPanasonicAc::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kLeftMax: return kPanasonicAcSwingHFullLeft; @@ -656,7 +706,9 @@ uint8_t IRPanasonicAc::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRPanasonicAc::toCommonMode(const uint8_t mode) { switch (mode) { case kPanasonicAcCool: return stdAc::opmode_t::kCool; @@ -667,7 +719,9 @@ stdAc::opmode_t IRPanasonicAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRPanasonicAc::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kPanasonicAcFanMax: return stdAc::fanspeed_t::kMax; @@ -679,7 +733,9 @@ stdAc::fanspeed_t IRPanasonicAc::toCommonFanSpeed(const uint8_t spd) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRPanasonicAc::toCommonSwingH(const uint8_t pos) { switch (pos) { case kPanasonicAcSwingHFullLeft: return stdAc::swingh_t::kLeftMax; @@ -691,7 +747,9 @@ stdAc::swingh_t IRPanasonicAc::toCommonSwingH(const uint8_t pos) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRPanasonicAc::toCommonSwingV(const uint8_t pos) { if (pos >= kPanasonicAcSwingVHighest && pos <= kPanasonicAcSwingVLowest) return (stdAc::swingv_t)pos; @@ -699,7 +757,8 @@ stdAc::swingv_t IRPanasonicAc::toCommonSwingV(const uint8_t pos) { return stdAc::swingv_t::kAuto; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRPanasonicAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::PANASONIC_AC; @@ -724,7 +783,8 @@ stdAc::state_t IRPanasonicAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRPanasonicAc::toString(void) { String result = ""; result.reserve(180); // Reserve some heap for the string to reduce fragging. @@ -808,27 +868,14 @@ String IRPanasonicAc::toString(void) { } #if DECODE_PANASONIC_AC -// Decode the supplied Panasonic AC message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kPanasonicAcBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Beta / Appears to work with real device(s). -// -// Panasonic A/C models supported: -// A/C Series/models: -// JKE, LKE, DKE, PKR, & NKE series. -// CS-YW9MKD -// CS-E7PKR -// A/C Remotes: -// A75C3747 (Confirmed) -// A75C3704 +/// Decode the supplied Panasonic AC message. +/// Status: STABLE / Works with real device(s). +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodePanasonicAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint8_t min_nr_of_messages = 1; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.h b/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.h similarity index 73% rename from lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.h index c97f69fde..4098993f9 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Panasonic.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.h @@ -1,24 +1,28 @@ // Copyright 2018 David Conran +/// @file +/// @brief Support for Panasonic protocols. +/// @see Panasonic A/C support heavily influenced by https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp + // Supports: -// Brand: Panasonic, Model: TV -// Brand: Panasonic, Model: JKE series A/C -// Brand: Panasonic, Model: DKE series A/C -// Brand: Panasonic, Model: DKW series A/C (DKE) -// Brand: Panasonic, Model: PKR series A/C (DKE) -// Brand: Panasonic, Model: CKP series A/C -// Brand: Panasonic, Model: NKE series A/C -// Brand: Panasonic, Model: RKR series A/C -// Brand: Panasonic, Model: CS-ME10CKPG A/C -// Brand: Panasonic, Model: CS-ME12CKPG A/C -// Brand: Panasonic, Model: CS-ME14CKPG A/C -// Brand: Panasonic, Model: CS-E7PKR A/C (DKE) -// Brand: Panasonic, Model: CS-Z9RKR A/C -// Brand: Panasonic, Model: CS-YW9MKD A/C -// Brand: Panasonic, Model: A75C2311 remote (CKP) -// Brand: Panasonic, Model: A75C2616-1 remote (DKE) -// Brand: Panasonic, Model: A75C3704 remote -// Brand: Panasonic, Model: A75C3747 remote +// Brand: Panasonic, Model: TV (PANASONIC) +// Brand: Panasonic, Model: NKE series A/C (PANASONIC_AC NKE/2) +// Brand: Panasonic, Model: DKE series A/C (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: DKW series A/C (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: PKR series A/C (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: JKE series A/C (PANASONIC_AC JKE/4) +// Brand: Panasonic, Model: CKP series A/C (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: RKR series A/C (PANASONIC_AC RKR/6) +// Brand: Panasonic, Model: CS-ME10CKPG A/C (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: CS-ME12CKPG A/C (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: CS-ME14CKPG A/C (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: CS-E7PKR A/C (PANASONIC_AC DKE/2) +// Brand: Panasonic, Model: CS-Z9RKR A/C (PANASONIC_AC RKR/6) +// Brand: Panasonic, Model: CS-YW9MKD A/C (PANASONIC_AC JKE/4) +// Brand: Panasonic, Model: A75C2311 remote (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: A75C2616-1 remote (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: A75C3704 remote (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: A75C3747 remote (PANASONIC_AC JKE/4) #ifndef IR_PANASONIC_H_ #define IR_PANASONIC_H_ @@ -34,9 +38,6 @@ #include "IRsend_test.h" #endif -// Panasonic A/C support heavily influenced by: -// https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp - // Constants const uint16_t kPanasonicFreq = 36700; const uint16_t kPanasonicAcExcess = 0; @@ -93,15 +94,18 @@ const uint8_t kPanasonicKnownGoodState[kPanasonicAcStateLength] = { 0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0E, 0xE0, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00}; - +/// Class for handling detailed Panasonic A/C messages. class IRPanasonicAc { public: explicit IRPanasonicAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_PANASONIC void send(const uint16_t repeat = kPanasonicAcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_PANASONIC void begin(void); @@ -117,9 +121,9 @@ class IRPanasonicAc { uint8_t getMode(void); void setRaw(const uint8_t state[]); uint8_t *getRaw(void); - static bool validChecksum(uint8_t *state, + static bool validChecksum(const uint8_t *state, const uint16_t length = kPanasonicAcStateLength); - static uint8_t calcChecksum(uint8_t *state, + static uint8_t calcChecksum(const uint8_t *state, const uint16_t length = kPanasonicAcStateLength); void setQuiet(const bool on); bool getQuiet(void); @@ -158,16 +162,16 @@ class IRPanasonicAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kPanasonicAcStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kPanasonicAcStateLength]; ///< The state in code form. uint8_t _swingh; uint8_t _temp; void fixChecksum(const uint16_t length = kPanasonicAcStateLength); - static uint8_t calcChecksum(const uint8_t *state, - const uint16_t length = kPanasonicAcStateLength); static uint16_t _getTime(const uint8_t ptr[]); static void _setTime(uint8_t * const ptr, const uint16_t mins_since_midnight, const bool round_down); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Pioneer.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.7/src/ir_Pioneer.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp index 08bbf3c06..d5ac89765 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Pioneer.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp @@ -3,7 +3,14 @@ // Copyright 2018 Kamil Palczewski // Copyright 2019 s-hadinger -// Pioneer remote emulation +/// @file +/// @brief Pioneer remote emulation +/// @see http://www.adrian-kingston.com/IRFormatPioneer.htm +/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/547 +/// @see https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers + +// Supports: +// Brand: Pioneer, Model: AV Receivers #define __STDC_LIMIT_MACROS #include @@ -13,8 +20,6 @@ #include "IRutils.h" // Constants -// Ref: -// http://www.adrian-kingston.com/IRFormatPioneer.htm const uint16_t kPioneerTick = 534; const uint16_t kPioneerHdrMarkTicks = 16; const uint16_t kPioneerHdrMark = kPioneerHdrMarkTicks * kPioneerTick; @@ -33,18 +38,11 @@ const uint16_t kPioneerMinGapTicks = 47; const uint32_t kPioneerMinGap = kPioneerMinGapTicks * kPioneerTick; #if SEND_PIONEER -// Send a raw Pioneer formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kPioneerBits. -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE / Expected to be working. -// -// Ref: -// http://adrian-kingston.com/IRFormatPioneer.htm +/// Send a raw Pioneer formatted message. +/// Status: STABLE / Expected to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendPioneer(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { // If nbits is to big, abort. @@ -68,23 +66,18 @@ void IRsend::sendPioneer(const uint64_t data, const uint16_t nbits, } } -// Calculate the raw Pioneer data code based on two NEC sub-codes -// Args: -// address A 16-bit "published" NEC value. -// command: A 16-bit "published" NEC value. -// Returns: -// A raw 64-bit Pioneer message code. -// -// Status: STABLE / Expected to work. -// -// Note: -// Address & Command can be take from a decode result OR from the spreadsheets -// located at: -// https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers -// where the first part is considered the address, -// and the second the command. -// e.g. -// "A556+AF20" is an Address of 0xA556 & a Command of 0xAF20. +/// Calculate the raw Pioneer data code based on two NEC sub-codes +/// Status: STABLE / Expected to work. +/// @param[in] address A 16-bit "published" NEC value. +/// @param[in] command A 16-bit "published" NEC value. +/// @return A raw 64-bit Pioneer message code for use with `sendPioneer()`` +/// @note Address & Command can be take from a decode result OR from the +/// spreadsheets located at: +/// https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers +/// where the first part is considered the address, +/// and the second the command. +/// e.g. +/// "A556+AF20" is an Address of 0xA556 & a Command of 0xAF20. uint64_t IRsend::encodePioneer(const uint16_t address, const uint16_t command) { return (((uint64_t)encodeNEC(address >> 8, address & 0xFF)) << 32) | encodeNEC(command >> 8, command & 0xFF); @@ -92,19 +85,14 @@ uint64_t IRsend::encodePioneer(const uint16_t address, const uint16_t command) { #endif // SEND_PIONEER #if DECODE_PIONEER -// Decode the supplied Pioneer message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kPioneerBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. (Self decodes & real examples) -// +/// Decode the supplied Pioneer message. +/// Status: STABLE / Should be working. (Self decodes & real examples) +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodePioneer(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1 + offset) diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Pronto.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Pronto.cpp similarity index 54% rename from lib/IRremoteESP8266-2.7.7/src/ir_Pronto.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Pronto.cpp index 4a9a45d97..2d4ffa759 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Pronto.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Pronto.cpp @@ -1,6 +1,14 @@ // Copyright 2017 David Conran -// Pronto code message generation +/// @file +/// @brief Pronto code message generation +/// @see http://www.etcwiki.org/wiki/Pronto_Infrared_Format +/// @see http://www.remotecentral.com/features/irdisp2.htm +/// @see http://harctoolbox.org/Glossary.html#ProntoSemantics +/// @see https://irdb.globalcache.com/ + +// Supports: +// Brand: Pronto, Model: Pronto Hex #include #include "IRsend.h" @@ -14,42 +22,37 @@ const uint16_t kProntoSeq2LenOffset = 3; const uint16_t kProntoDataOffset = 4; #if SEND_PRONTO -// Send a Pronto Code formatted message. -// -// Args: -// data: An array of uint16_t containing the pronto codes. -// len: Nr. of entries in the data[] array. -// repeat: Nr. of times to repeat the message. -// -// Status: STABLE / Known working. -// -// Note: -// Pronto codes are typically represented in hexadecimal. -// You will need to convert the code to an array of integers, and calculate -// it's length. -// e.g. -// A Sony 20 bit DVD remote command. -// "0000 0067 0000 0015 0060 0018 0018 0018 0030 0018 0030 0018 0030 0018 -// 0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0030 0018 -// 0030 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018 -// 0030 0018 0018 03f6" -// -// converts to: -// -// uint16_t prontoCode[46] = { -// 0x0000, 0x0067, 0x0000, 0x0015, -// 0x0060, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0030, 0x0018, -// 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, -// 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, -// 0x0030, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, -// 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, -// 0x0018, 0x03f6}; -// // Send the Pronto(Sony) code. Repeat twice as Sony's require that. -// sendPronto(prontoCode, 46, kSonyMinRepeat); -// -// Ref: -// http://www.etcwiki.org/wiki/Pronto_Infrared_Format -// http://www.remotecentral.com/features/irdisp2.htm +/// Send a Pronto Code formatted message. +/// Status: STABLE / Known working. +/// @param[in] data An array of uint16_t containing the pronto codes. +/// @param[in] len Nr. of entries in the data[] array. +/// @param[in] repeat Nr. of times to repeat the message. +/// @note Pronto codes are typically represented in hexadecimal. +/// You will need to convert the code to an array of integers, and calculate +/// it's length. +/// e.g. +/// @code +/// A Sony 20 bit DVD remote command. +/// "0000 0067 0000 0015 0060 0018 0018 0018 0030 0018 0030 0018 0030 0018 +/// 0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0030 0018 +/// 0030 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018 +/// 0030 0018 0018 03f6" +/// @endcode +/// converts to: +/// @code{.cpp} +/// uint16_t prontoCode[46] = { +/// 0x0000, 0x0067, 0x0000, 0x0015, +/// 0x0060, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0030, 0x0018, +/// 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, +/// 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, +/// 0x0030, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, +/// 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, +/// 0x0018, 0x03f6}; +/// // Send the Pronto(Sony) code. Repeat twice as Sony's require that. +/// sendPronto(prontoCode, 46, kSonyMinRepeat); +/// @endcode +/// @see http://www.etcwiki.org/wiki/Pronto_Infrared_Format +/// @see http://www.remotecentral.com/features/irdisp2.htm void IRsend::sendPronto(uint16_t data[], uint16_t len, uint16_t repeat) { // Check we have enough data to work out what to send. if (len < kProntoMinLength) return; @@ -101,4 +104,4 @@ void IRsend::sendPronto(uint16_t data[], uint16_t len, uint16_t repeat) { } } } -#endif +#endif // SEND_PRONTO diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_RC5_RC6.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_RC5_RC6.cpp similarity index 59% rename from lib/IRremoteESP8266-2.7.7/src/ir_RC5_RC6.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_RC5_RC6.cpp index 370100f9e..cb00c5a67 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_RC5_RC6.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_RC5_RC6.cpp @@ -1,8 +1,22 @@ // Copyright 2009 Ken Shirriff // Copyright 2017 David Conran -// RC-5 & RC-6 support added from https://github.com/z3t0/Arduino-IRremote -// RC-5X support added by David Conran +/// @file +/// @brief RC-5 & RC-6 support +/// RC-5 & RC-6 support added from https://github.com/z3t0/Arduino-IRremote +/// RC-5X support added by David Conran +/// @see https://en.wikipedia.org/wiki/RC-5 +/// @see http://www.sbprojects.com/knowledge/ir/rc5.php +/// @see https://en.wikipedia.org/wiki/Manchester_code +/// @see https://en.wikipedia.org/wiki/RC-6 +/// @see https://www.sbprojects.net/knowledge/ir/rc6.php +/// @see http://www.pcbheaven.com/userpages/The_Philips_RC6_Protocol/ +/// @see http://www.righto.com/2010/12/64-bit-rc6-codes-arduino-and-xbox.html + +// Supports: +// Brand: Philips, Model: Standard RC-5 (RC5) +// Brand: Philips, Model: RC-5X (RC5X) +// Brand: Philips, Model: Standard RC-6 (RC6) #include #include "IRrecv.h" @@ -12,10 +26,6 @@ // Constants // RC-5/RC-5X -// Ref: -// https://en.wikipedia.org/wiki/RC-5 -// http://www.sbprojects.com/knowledge/ir/rc5.php - const uint16_t kRc5T1 = 889; const uint32_t kRc5MinCommandLength = 113778; const uint32_t kRc5MinGap = kRc5MinCommandLength - kRC5RawBits * (2 * kRc5T1); @@ -23,10 +33,6 @@ const uint16_t kRc5ToggleMask = 0x800; // The 12th bit. const uint16_t kRc5SamplesMin = 11; // RC-6 -// Ref: -// https://en.wikipedia.org/wiki/RC-6 -// http://www.pcbheaven.com/userpages/The_Philips_RC6_Protocol/ - const uint16_t kRc6Tick = 444; const uint16_t kRc6HdrMarkTicks = 6; const uint16_t kRc6HdrMark = kRc6HdrMarkTicks * kRc6Tick; @@ -42,27 +48,18 @@ const int16_t kMark = 0; const int16_t kSpace = 1; #if SEND_RC5 -// Send a Philips RC-5/RC-5X packet. -// -// Args: -// data: The message you wish to send. -// nbits: Bit size of the protocol you want to send. -// repeat: Nr. of extra times the data will be sent. -// -// Status: RC-5 (stable), RC-5X (alpha) -// -// Note: -// Caller needs to take care of flipping the toggle bit. -// That bit differentiates between key press & key release. -// For RC-5 it is the MSB of the data. -// For RC-5X it is the 2nd MSB of the data. -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -// https://en.wikipedia.org/wiki/Manchester_code -// TODO(anyone): -// Testing of the RC-5X components. -void IRsend::sendRC5(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a Philips RC-5/RC-5X packet. +/// Status: RC-5 (stable), RC-5X (alpha) +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note Caller needs to take care of flipping the toggle bit. +/// That bit differentiates between key press & key release. +/// For RC-5 it is the MSB of the data. +/// For RC-5X it is the 2nd MSB of the data. +/// @todo Testing of the RC-5X components. +void IRsend::sendRC5(const uint64_t data, uint16_t nbits, + const uint16_t repeat) { if (nbits > sizeof(data) * 8) return; // We can't send something that big. bool skipSpace = true; bool field_bit = true; @@ -109,44 +106,26 @@ void IRsend::sendRC5(uint64_t data, uint16_t nbits, uint16_t repeat) { } } -// Encode a Philips RC-5 data message. -// -// Args: -// address: The 5-bit address value for the message. -// command: The 6-bit command value for the message. -// key_released: Boolean flag indicating if the remote key has been released. -// -// Returns: -// A data message suitable for use in sendRC5(). -// -// Status: Beta / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -uint16_t IRsend::encodeRC5(uint8_t address, uint8_t command, - bool key_released) { +/// Encode a Philips RC-5 data message. +/// Status: Beta / Should be working. +/// @param[in] address The 5-bit address value for the message. +/// @param[in] command The 6-bit command value for the message. +/// @param[in] key_released Indicate if the remote key has been released. +/// @return A message suitable for use in sendRC5(). +uint16_t IRsend::encodeRC5(const uint8_t address, const uint8_t command, + const bool key_released) { return (key_released << (kRC5Bits - 1)) | ((address & 0x1f) << 6) | (command & 0x3F); } -// Encode a Philips RC-5X data message. -// -// Args: -// address: The 5-bit address value for the message. -// command: The 7-bit command value for the message. -// key_released: Boolean flag indicating if the remote key has been released. -// -// Returns: -// A data message suitable for use in sendRC5(). -// -// Status: Beta / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -uint16_t IRsend::encodeRC5X(uint8_t address, uint8_t command, - bool key_released) { +/// Encode a Philips RC-5X data message. +/// Status: Beta / Should be working. +/// @param[in] address The 5-bit address value for the message. +/// @param[in] command The 7-bit command value for the message. +/// @param[in] key_released Indicate if the remote key has been released. +/// @return A message suitable for use in sendRC5(). +uint16_t IRsend::encodeRC5X(const uint8_t address, const uint8_t command, + const bool key_released) { // The 2nd start/field bit (MSB of the return value) is the value of the 7th // command bit. bool s2 = (command >> 6) & 1; @@ -154,64 +133,43 @@ uint16_t IRsend::encodeRC5X(uint8_t address, uint8_t command, encodeRC5(address, command, key_released); } -// Flip the toggle bit of a Philips RC-5/RC-5X data message. -// Used to indicate a change of remote button's state. -// -// Args: -// data: The existing RC-5/RC-5X message. -// -// Returns: -// A data message suitable for use in sendRC5() with the toggle bit flipped. -// -// Status: STABLE. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -uint64_t IRsend::toggleRC5(uint64_t data) { return data ^ kRc5ToggleMask; } +/// Flip the toggle bit of a Philips RC-5/RC-5X data message. +/// Used to indicate a change of remote button's state. +/// Status: STABLE. +/// @param[in] data The existing RC-5/RC-5X message. +/// @return A data message suitable for use in sendRC5() with the toggle bit +/// flipped. +uint64_t IRsend::toggleRC5(const uint64_t data) { + return data ^ kRc5ToggleMask; +} #endif // SEND_RC5 #if SEND_RC6 -// Flip the toggle bit of a Philips RC-6 data message. -// Used to indicate a change of remote button's state. -// For RC-6 (20-bits), it is the 17th least significant bit. -// for RC-6 (36-bits/Xbox-360), it is the 16th least significant bit. -// -// Args: -// data: The existing RC-6 message. -// nbits: Nr. of bits in the RC-6 protocol. -// -// Returns: -// A data message suitable for use in sendRC6() with the toggle bit flipped. -// -// Status: STABLE / Should work fine. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc6.php -// http://www.righto.com/2010/12/64-bit-rc6-codes-arduino-and-xbox.html -uint64_t IRsend::toggleRC6(uint64_t data, uint16_t nbits) { +/// Flip the toggle bit of a Philips RC-6 data message. +/// Used to indicate a change of remote button's state. +/// Status: STABLE / Should work fine. +/// @param[in] data The existing RC-6 message. +/// @param [in] nbits Nr. of bits in the RC-6 protocol. +/// @return A data message suitable for use in sendRC6() with the toggle bit +/// flipped. +/// @note For RC-6 (20-bits), it is the 17th least significant bit. +/// @note For RC-6 (36-bits/Xbox-360), it is the 16th least significant bit. +uint64_t IRsend::toggleRC6(const uint64_t data, const uint16_t nbits) { if (nbits == kRC6_36Bits) return data ^ kRc6_36ToggleMask; return data ^ kRc6ToggleMask; } -// Encode a Philips RC-6 data message. -// -// Args: -// address: The address (aka. control) value for the message. -// Includes the field/mode/toggle bits. -// command: The 8-bit command value for the message. (aka. information) -// mode: Which protocol to use. Defined by nr. of bits in the protocol. -// -// Returns: -// A data message suitable for use in sendRC6(). -// -// Status: Beta / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc6.php -// http://www.righto.com/2010/12/64-bit-rc6-codes-arduino-and-xbox.html -// http://www.pcbheaven.com/userpages/The_Philips_RC6_Protocol/ -uint64_t IRsend::encodeRC6(uint32_t address, uint8_t command, uint16_t mode) { +/// Encode a Philips RC-6 data message. +/// Status: Beta / Should be working. +/// @param[in] address The address (aka. control) value for the message. +/// Includes the field/mode/toggle bits. +/// @param[in] command The 8-bit command value for the message. +/// (aka. information) +/// @param[in] mode Which protocol to use. +/// Defined by nr. of bits in the protocol. +/// @return A data message suitable for use in `sendRC6()`. +uint64_t IRsend::encodeRC6(const uint32_t address, const uint8_t command, + const uint16_t mode) { switch (mode) { case kRC6Mode0Bits: return ((address & 0xFFF) << 8) | (command & 0xFF); @@ -222,22 +180,15 @@ uint64_t IRsend::encodeRC6(uint32_t address, uint8_t command, uint16_t mode) { } } -// Send a Philips RC-6 packet. -// Note: Caller needs to take care of flipping the toggle bit (The 4th Most -// Significant Bit). That bit differentiates between key press & key release. -// -// Args: -// data: The message you wish to send. -// nbits: Bit size of the protocol you want to send. -// repeat: Nr. of extra times the data will be sent. -// -// Status: Stable. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc6.php -// http://www.righto.com/2010/12/64-bit-rc6-codes-arduino-and-xbox.html -// https://en.wikipedia.org/wiki/Manchester_code -void IRsend::sendRC6(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a Philips RC-6 packet. +/// Status: Stable. +/// @note Caller needs to take care of flipping the toggle bit (The 4th Most +/// Significant Bit). That bit differentiates between key press & key release. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +void IRsend::sendRC6(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { // Check we can send the number of bits requested. if (nbits > sizeof(data) * 8) return; // Set 36kHz IR carrier frequency & a 1/3 (33%) duty cycle. @@ -271,27 +222,28 @@ void IRsend::sendRC6(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_RC6 #if (DECODE_RC5 || DECODE_RC6 || DECODE_LASERTAG) -// Gets one undecoded level at a time from the raw buffer. -// The RC5/6 decoding is easier if the data is broken into time intervals. -// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, -// successive calls to getRClevel will return MARK, MARK, SPACE. -// offset and used are updated to keep track of the current position. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: Ptr to the currect offset to the rawbuf. -// used: Ptr to the current used counter. -// bitTime: Time interval of single bit in microseconds. -// maxwidth: Maximum number of successive levels to find in a single level -// (default 3) -// Returns: -// int: MARK, SPACE, or -1 for error (The measured time interval is not a -// multiple of t1.) -// Ref: -// https://en.wikipedia.org/wiki/Manchester_code +/// Gets one undecoded level at a time from the raw buffer. +/// The RC5/6 decoding is easier if the data is broken into time intervals. +/// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, +/// successive calls to getRClevel will return MARK, MARK, SPACE. +/// offset and used are updated to keep track of the current position. +/// @param[in,out] results Ptr to the data to decode and where to store the +/// decode result. +/// @param[in,out] offset Ptr to the currect offset to the rawbuf. +/// @param[in,out] used Ptr to the current used counter. +/// @param[in] bitTime Time interval of single bit in microseconds. +/// @param[in] tolerance Percent tolerance to be used in matching. +/// @param[in] excess Extra useconds to add to Marks & removed from Spaces. +/// @param[in] delta A non-scaling (+/-) error margin (in useconds). +/// @param[in] maxwidth Maximum number of successive levels to find in a single +/// level (default is 3) +/// @return MARK, SPACE, or -1 for error. +/// (The measured time interval is not a multiple of t1.) +/// @see https://en.wikipedia.org/wiki/Manchester_code int16_t IRrecv::getRClevel(decode_results *results, uint16_t *offset, - uint16_t *used, uint16_t bitTime, uint8_t tolerance, - int16_t excess, uint16_t delta, uint8_t maxwidth) { + uint16_t *used, const uint16_t bitTime, + const uint8_t tolerance, const int16_t excess, + const uint16_t delta, const uint8_t maxwidth) { DPRINT("DEBUG: getRClevel: offset = "); DPRINTLN(uint64ToString(*offset)); DPRINT("DEBUG: getRClevel: rawlen = "); @@ -343,28 +295,17 @@ int16_t IRrecv::getRClevel(decode_results *results, uint16_t *offset, #endif // (DECODE_RC5 || DECODE_RC6 || DECODE_LASERTAG) #if DECODE_RC5 -// Decode the supplied RC-5/RC5X message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: RC-5 (stable), RC-5X (alpha) -// -// Note: -// The 'toggle' bit is included as the 6th (MSB) address bit, the MSB of data, -// & in the count of bits decoded. -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -// https://en.wikipedia.org/wiki/Manchester_code -// TODO(anyone): -// Serious testing of the RC-5X and strict aspects needs to be done. +/// Decode the supplied RC-5/RC5X message. +/// Status: RC-5 (stable), RC-5X (alpha) +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note The 'toggle' bit is included as the 6th (MSB) address bit, the MSB of +/// data, & in the count of bits decoded. +/// @todo Serious testing of the RC-5X and strict aspects needs to be done. bool IRrecv::decodeRC5(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= kRc5SamplesMin + kHeader - 1 + offset) return false; @@ -430,24 +371,15 @@ bool IRrecv::decodeRC5(decode_results *results, uint16_t offset, #endif // DECODE_RC5 #if DECODE_RC6 -// Decode the supplied RC6 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Stable. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc6.php -// https://en.wikipedia.org/wiki/Manchester_code -// TODO(anyone): -// Testing of the strict compliance aspects. +/// Decode the supplied RC6 message. +/// Status: Stable. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @todo Testing of the strict compliance aspects. bool IRrecv::decodeRC6(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= kHeader + 2 + 4 + offset) diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_RCMM.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_RCMM.cpp similarity index 80% rename from lib/IRremoteESP8266-2.7.7/src/ir_RCMM.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_RCMM.cpp index ea0e05e9d..023b82517 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_RCMM.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_RCMM.cpp @@ -1,6 +1,8 @@ // Copyright 2017 David Conran -// Send & decode support for Phillips RC-MM added by David Conran +/// @file +/// @brief Support for the Phillips RC-MM protocol. +/// @see http://www.sbprojects.com/knowledge/ir/rcmm.php // Supports: // Brand: Microsoft, Model: XBOX 360 @@ -12,8 +14,6 @@ #include "IRutils.h" // Constants -// Ref: -// http://www.sbprojects.com/knowledge/ir/rcmm.php const uint16_t kRcmmTick = 28; // Technically it would be 27.777* const uint16_t kRcmmHdrMarkTicks = 15; const uint16_t kRcmmHdrMark = 416; @@ -38,17 +38,11 @@ const uint8_t kRcmmTolerance = 10; const uint16_t kRcmmExcess = 50; #if SEND_RCMM -// Send a Philips RC-MM packet. -// -// Args: -// data: The data we want to send. MSB first. -// nbits: The number of bits of data to send. (Typically 12, 24, or 32[Nokia]) -// repeat: The nr. of times the message should be sent. -// -// Status: STABLE / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rcmm.php +/// Send a Philips RC-MM packet. +/// Status: STABLE / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendRCMM(uint64_t data, uint16_t nbits, uint16_t repeat) { // Set 36kHz IR carrier frequency & a 1/3 (33%) duty cycle. enableIROut(36, 33); @@ -88,24 +82,17 @@ void IRsend::sendRCMM(uint64_t data, uint16_t nbits, uint16_t repeat) { space(std::max(kRcmmRptLength - usecs.elapsed(), kRcmmMinGap)); } } -#endif +#endif // SEND_RCMM #if DECODE_RCMM -// Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. -// Places successful decode information in the results pointer. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. Typically kRCMMBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rcmm.php +/// Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. +/// Status: STABLE / Should be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeRCMM(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint64_t data = 0; @@ -174,4 +161,4 @@ bool IRrecv::decodeRCMM(decode_results *results, uint16_t offset, results->command = 0; return true; } -#endif +#endif // DECODE_RCMM diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Samsung.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.7/src/ir_Samsung.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp index 78b36e146..02aa4abdd 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Samsung.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp @@ -1,7 +1,12 @@ // Copyright 2009 Ken Shirriff // Copyright 2017, 2018, 2019 David Conran - -// Samsung remote emulation +/// @file +/// @brief Support for Samsung protocols. +/// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/621 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 +/// @see http://elektrolab.wz.cz/katalog/samsung_protocol.pdf #include "ir_Samsung.h" #include @@ -14,11 +19,7 @@ #include "IRtext.h" #include "IRutils.h" -// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/ - // Constants -// Ref: -// http://elektrolab.wz.cz/katalog/samsung_protocol.pdf const uint16_t kSamsungTick = 560; const uint16_t kSamsungHdrMarkTicks = 8; const uint16_t kSamsungHdrMark = kSamsungHdrMarkTicks * kSamsungTick; @@ -62,19 +63,15 @@ using irutils::setBit; using irutils::setBits; #if SEND_SAMSUNG -// Send a Samsung formatted message. -// Samsung has a separate message to indicate a repeat, like NEC does. -// TODO(crankyoldgit): Confirm that is actually how Samsung sends a repeat. -// The refdoc doesn't indicate it is true. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kSamsungBits. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Should be working. -// -// Ref: http://elektrolab.wz.cz/katalog/samsung_protocol.pdf +/// Send a 32-bit Samsung formatted message. +/// Status: STABLE / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see http://elektrolab.wz.cz/katalog/samsung_protocol.pdf +/// @note Samsung has a separate message to indicate a repeat, like NEC does. +/// @todo Confirm that is actually how Samsung sends a repeat. +/// The refdoc doesn't indicate it is true. void IRsend::sendSAMSUNG(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kSamsungHdrMark, kSamsungHdrSpace, kSamsungBitMark, @@ -83,16 +80,12 @@ void IRsend::sendSAMSUNG(const uint64_t data, const uint16_t nbits, nbits, 38, true, repeat, 33); } -// Construct a raw Samsung message from the supplied customer(address) & -// command. -// -// Args: -// customer: The customer code. (aka. Address) -// command: The command code. -// Returns: -// A raw 32-bit Samsung message suitable for sendSAMSUNG(). -// -// Status: STABLE / Should be working. +/// Construct a raw Samsung message from the supplied customer(address) & +/// command. +/// Status: STABLE / Should be working. +/// @param[in] customer The customer code. (aka. Address) +/// @param[in] command The command code. +/// @return A raw 32-bit Samsung message suitable for `sendSAMSUNG()`. uint32_t IRsend::encodeSAMSUNG(const uint8_t customer, const uint8_t command) { uint8_t revcustomer = reverseBits(customer, sizeof(customer) * 8); uint8_t revcommand = reverseBits(command, sizeof(command) * 8); @@ -102,27 +95,20 @@ uint32_t IRsend::encodeSAMSUNG(const uint8_t customer, const uint8_t command) { #endif #if DECODE_SAMSUNG -// Decode the supplied Samsung message. -// Samsung messages whilst 32 bits in size, only contain 16 bits of distinct -// data. e.g. In transmition order: -// customer_byte + customer_byte(same) + address_byte + invert(address_byte) -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. Typically kSamsungBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE -// -// Note: -// LG 32bit protocol appears near identical to the Samsung protocol. -// They differ on their compliance criteria and how they repeat. -// Ref: -// http://elektrolab.wz.cz/katalog/samsung_protocol.pdf +/// Decode the supplied Samsung 32-bit message. +/// Status: STABLE +/// @note Samsung messages whilst 32 bits in size, only contain 16 bits of +/// distinct data. e.g. In transmition order: +/// customer_byte + customer_byte(same) + address_byte + invert(address_byte) +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note LG 32bit protocol appears near identical to the Samsung protocol. +/// They differ on their compliance criteria and how they repeat. +/// @see http://elektrolab.wz.cz/katalog/samsung_protocol.pdf bool IRrecv::decodeSAMSUNG(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kSamsungBits) @@ -159,20 +145,12 @@ bool IRrecv::decodeSAMSUNG(decode_results *results, uint16_t offset, #endif #if SEND_SAMSUNG36 -// Send a Samsung 36-bit formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kSamsung36Bits. -// repeat: The number of times the message is to be repeated. -// -// Status: Alpha / Experimental. -// -// Note: -// Protocol is used by Samsung Bluray Remote: ak59-00167a -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/621 +/// Send a Samsung 36-bit formatted message. +/// Status: Alpha / Experimental. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/621 void IRsend::sendSamsung36(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { if (nbits < 16) return; // To small to send. @@ -196,25 +174,15 @@ void IRsend::sendSamsung36(const uint64_t data, const uint16_t nbits, #endif // SEND_SAMSUNG36 #if DECODE_SAMSUNG36 -// Decode the supplied Samsung36 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kSamsung36Bits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Experimental -// -// Note: -// Protocol is used by Samsung Bluray Remote: ak59-00167a -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/621 +/// Decode the supplied Samsung36 message. +/// Status: Alpha / Experimental +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/621 bool IRrecv::decodeSamsung36(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * nbits + kHeader + kFooter * 2 - 1 + offset) @@ -258,17 +226,12 @@ bool IRrecv::decodeSamsung36(decode_results *results, uint16_t offset, #endif // DECODE_SAMSUNG36 #if SEND_SAMSUNG_AC -// Send a Samsung A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kSamsungAcStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: Stable / Known working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// Send a Samsung A/C message. +/// Status: Stable / Known working. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendSamsungAC(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kSamsungAcStateLength && nbytes % kSamsungAcSectionLength) @@ -294,16 +257,20 @@ void IRsend::sendSamsungAC(const uint8_t data[], const uint16_t nbytes, } #endif // SEND_SAMSUNG_AC +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRSamsungAc::IRSamsungAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the internal state of the emulation. -// Args: -// forcepower: A flag indicating if force sending a special power message -// with the first `send()` call. Default: true +/// Reset the internal state of the emulation. +/// @param[in] forcepower A flag indicating if force sending a special power +/// message with the first `send()` call. +/// @param[in] initialPower Set the initial power state. True, on. False, off. void IRSamsungAc::stateReset(const bool forcepower, const bool initialPower) { static const uint8_t kReset[kSamsungAcExtendedStateLength] = { 0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x02, 0xAE, 0x71, 0x00, @@ -314,8 +281,13 @@ void IRSamsungAc::stateReset(const bool forcepower, const bool initialPower) { setPower(initialPower); } +/// Set up hardware to be able to send a message. void IRSamsungAc::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRSamsungAc::calcChecksum(const uint8_t state[], const uint16_t length) { uint8_t sum = 0; @@ -331,6 +303,10 @@ uint8_t IRSamsungAc::calcChecksum(const uint8_t state[], return GETBITS8(28 - sum, kLowNibble, kNibbleSize); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRSamsungAc::validChecksum(const uint8_t state[], const uint16_t length) { if (length < kSamsungAcStateLength) return true; // No checksum to compare with. Assume okay. @@ -342,7 +318,8 @@ bool IRSamsungAc::validChecksum(const uint8_t state[], const uint16_t length) { IRSamsungAc::calcChecksum(state, length - (7 + offset))); } -// Update the checksum for the internal state. +/// Update the checksum for the internal state. +/// @param[in] length The length/size of the internal array to checksum. void IRSamsungAc::checksum(uint16_t length) { if (length < 13) return; setBits(&remote_state[length - 6], kHighNibble, kNibbleSize, @@ -352,8 +329,11 @@ void IRSamsungAc::checksum(uint16_t length) { } #if SEND_SAMSUNG_AC -// Use for most function/mode/settings changes to the unit. -// i.e. When the device is already running. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @param[in] calcchecksum Do we update the checksum before sending? +/// @note Use for most function/mode/settings changes to the unit. +/// i.e. When the device is already running. void IRSamsungAc::send(const uint16_t repeat, const bool calcchecksum) { if (calcchecksum) this->checksum(); // Do we need to send a the special power on/off message? @@ -369,9 +349,12 @@ void IRSamsungAc::send(const uint16_t repeat, const bool calcchecksum) { _irsend.sendSamsungAC(remote_state, kSamsungAcStateLength, repeat); } -// Use this for when you need to power on/off the device. -// Samsung A/C requires an extended length message when you want to -// change the power operating mode of the A/C unit. +/// Send the extended current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @param[in] calcchecksum Do we update the checksum before sending? +/// @note Use this for when you need to power on/off the device. +/// Samsung A/C requires an extended length message when you want to +/// change the power operating mode of the A/C unit. void IRSamsungAc::sendExtended(const uint16_t repeat, const bool calcchecksum) { if (calcchecksum) this->checksum(); uint8_t extended_state[kSamsungAcExtendedStateLength] = { @@ -389,9 +372,10 @@ void IRSamsungAc::sendExtended(const uint16_t repeat, const bool calcchecksum) { _irsend.sendSamsungAC(extended_state, kSamsungAcExtendedStateLength, repeat); } -// Send the special extended "On" message as the library can't seem to reproduce -// this message automatically. -// See: https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036 +/// Send the special extended "On" message as the library can't seem to +/// reproduce this message automatically. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036 void IRSamsungAc::sendOn(const uint16_t repeat) { const uint8_t extended_state[21] = { 0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, @@ -401,9 +385,10 @@ void IRSamsungAc::sendOn(const uint16_t repeat) { _lastsentpowerstate = true; // On } -// Send the special extended "Off" message as the library can't seem to -// reproduce this message automatically. -// See: https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036 +/// Send the special extended "Off" message as the library can't seem to +/// reproduce this message automatically. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036 void IRSamsungAc::sendOff(const uint16_t repeat) { const uint8_t extended_state[21] = { 0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0, @@ -414,11 +399,16 @@ void IRSamsungAc::sendOff(const uint16_t repeat) { } #endif // SEND_SAMSUNG_AC +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRSamsungAc::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. void IRSamsungAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kSamsungAcExtendedStateLength)); @@ -429,23 +419,30 @@ void IRSamsungAc::setRaw(const uint8_t new_code[], const uint16_t length) { } } +/// Set the requested power state of the A/C to on. void IRSamsungAc::on(void) { setPower(true); } +/// Set the requested power state of the A/C to off. void IRSamsungAc::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setPower(const bool on) { setBit(&remote_state[1], kSamsungAcPower1Offset, !on); // Cleared when on. setBits(&remote_state[6], kSamsungAcPower6Offset, kSamsungAcPower6Size, on ? 0b11 : 0b00); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getPower(void) { return (GETBITS8(remote_state[6], kSamsungAcPower6Offset, kSamsungAcPower6Size) == 0b11) && !GETBIT8(remote_state[1], kSamsungAcPower1Offset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRSamsungAc::setTemp(const uint8_t temp) { uint8_t newtemp = std::max(kSamsungAcMinTemp, temp); newtemp = std::min(kSamsungAcMaxTemp, newtemp); @@ -453,12 +450,15 @@ void IRSamsungAc::setTemp(const uint8_t temp) { newtemp - kSamsungAcMinTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRSamsungAc::getTemp(void) { return GETBITS8(remote_state[11], kHighNibble, kNibbleSize) + kSamsungAcMinTemp; } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRSamsungAc::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. uint8_t newmode = mode; @@ -475,10 +475,14 @@ void IRSamsungAc::setMode(const uint8_t mode) { } } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRSamsungAc::getMode(void) { return GETBITS8(remote_state[12], kSamsungAcModeOffset, kModeBitsSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRSamsungAc::setFan(const uint8_t speed) { switch (speed) { case kSamsungAcFanAuto: @@ -497,47 +501,65 @@ void IRSamsungAc::setFan(const uint8_t speed) { setBits(&remote_state[12], kSamsungAcFanOffest, kSamsungAcFanSize, speed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRSamsungAc::getFan(void) { return GETBITS8(remote_state[12], kSamsungAcFanOffest, kSamsungAcFanSize); } +/// Get the vertical swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +/// @todo (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. +/// e.g. 0xAE or 0XAF for swing move. bool IRSamsungAc::getSwing(void) { - // TODO(Hollako): Explain why sometimes the LSB of remote_state[9] is a 1. - // e.g. 0xAE or 0XAF for swing move. return GETBITS8(remote_state[9], kSamsungAcSwingOffset, kSamsungAcSwingSize) == kSamsungAcSwingMove; } +/// Set the vertical swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @todo (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. +/// e.g. 0xAE or 0XAF for swing move. void IRSamsungAc::setSwing(const bool on) { - // TODO(Hollako): Explain why sometimes the LSB of remote_state[9] is a 1. - // e.g. 0xAE or 0XAF for swing move. setBits(&remote_state[9], kSamsungAcSwingOffset, kSamsungAcSwingSize, on ? kSamsungAcSwingMove : kSamsungAcSwingStop); } +/// Get the Beep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getBeep(void) { return GETBIT8(remote_state[13], kSamsungAcBeepOffset); } +/// Set the Beep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setBeep(const bool on) { setBit(&remote_state[13], kSamsungAcBeepOffset, on); } +/// Get the Clean setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getClean(void) { return GETBIT8(remote_state[10], kSamsungAcClean10Offset) && GETBIT8(remote_state[11], kSamsungAcClean11Offset); } +/// Set the Clean setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setClean(const bool on) { setBit(&remote_state[10], kSamsungAcClean10Offset, on); setBit(&remote_state[11], kSamsungAcClean11Offset, on); } +/// Get the Quiet setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getQuiet(void) { return !GETBIT8(remote_state[1], kSamsungAcQuiet1Offset) && GETBIT8(remote_state[5], kSamsungAcQuiet5Offset); } +/// Set the Quiet setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setQuiet(const bool on) { setBit(&remote_state[1], kSamsungAcQuiet1Offset, !on); // Cleared when on. setBit(&remote_state[5], kSamsungAcQuiet5Offset, on); @@ -548,6 +570,8 @@ void IRSamsungAc::setQuiet(const bool on) { } } +/// Get the Powerful (Turbo) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getPowerful(void) { return !(remote_state[8] & kSamsungAcPowerfulMask8) && (GETBITS8(remote_state[10], kSamsungAcPowerful10Offset, @@ -555,6 +579,8 @@ bool IRSamsungAc::getPowerful(void) { (this->getFan() == kSamsungAcFanTurbo); } +/// Set the Powerful (Turbo) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setPowerful(const bool on) { uint8_t off_value = this->getBreeze() ? kSamsungAcBreezeOn : 0b000; setBits(&remote_state[10], kSamsungAcPowerful10Offset, @@ -571,16 +597,18 @@ void IRSamsungAc::setPowerful(const bool on) { } } -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 -// Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree +/// Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree +/// @return true, the setting is on. false, the setting is off. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 bool IRSamsungAc::getBreeze(void) { return (GETBITS8(remote_state[10], kSamsungAcBreezeOffset, kSamsungAcBreezeSize) == kSamsungAcBreezeOn) && (this->getFan() == kSamsungAcFanAuto && !getSwing()); } -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 -// Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree +/// Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree +/// @param[in] on true, the setting is on. false, the setting is off. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 void IRSamsungAc::setBreeze(const bool on) { uint8_t off_value = this->getPowerful() ? kSamsungAcPowerful10On : 0b000; setBits(&remote_state[10], kSamsungAcBreezeOffset, @@ -591,23 +619,33 @@ void IRSamsungAc::setBreeze(const bool on) { } } +/// Get the Display (Light/LED) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getDisplay(void) { return GETBIT8(remote_state[10], kSamsungAcDisplayOffset); } +/// Set the Display (Light/LED) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setDisplay(const bool on) { setBit(&remote_state[10], kSamsungAcDisplayOffset, on); } +/// Get the Ion (Filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getIon(void) { return GETBIT8(remote_state[11], kSamsungAcIonOffset); } +/// Set the Ion (Filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setIon(const bool on) { setBit(&remote_state[11], kSamsungAcIonOffset, on); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRSamsungAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kSamsungAcCool; @@ -618,7 +656,9 @@ uint8_t IRSamsungAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRSamsungAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -630,7 +670,9 @@ uint8_t IRSamsungAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRSamsungAc::toCommonMode(const uint8_t mode) { switch (mode) { case kSamsungAcCool: return stdAc::opmode_t::kCool; @@ -641,7 +683,9 @@ stdAc::opmode_t IRSamsungAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRSamsungAc::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kSamsungAcFanTurbo: return stdAc::fanspeed_t::kMax; @@ -652,7 +696,8 @@ stdAc::fanspeed_t IRSamsungAc::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRSamsungAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::SAMSUNG_AC; @@ -678,7 +723,8 @@ stdAc::state_t IRSamsungAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRSamsungAc::toString(void) { String result = ""; result.reserve(115); // Reserve some heap for the string to reduce fragging. @@ -723,21 +769,15 @@ String IRSamsungAc::toString(void) { } #if DECODE_SAMSUNG_AC -// Decode the supplied Samsung A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kSamsungAcBits -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Stable / Known to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// Decode the supplied Samsung A/C message. +/// Status: Stable / Known to be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/505 bool IRrecv::decodeSamsungAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * nbits + kHeader * 3 + kFooter * 2 - 1 + offset) diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Samsung.h b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h similarity index 76% rename from lib/IRremoteESP8266-2.7.7/src/ir_Samsung.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h index 9c9e6ab8e..fa6f9f2f3 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Samsung.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h @@ -1,6 +1,23 @@ -// Samsung A/C -// // Copyright 2018 David Conran +/// @file +/// @brief Support for Samsung protocols. +/// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/621 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 +/// @see http://elektrolab.wz.cz/katalog/samsung_protocol.pdf + +// Supports: +// Brand: Samsung, Model: UA55H6300 TV (SAMSUNG) +// Brand: Samsung, Model: BN59-01178B TV remote (SAMSUNG) +// Brand: Samsung, Model: DB63-03556X003 remote +// Brand: Samsung, Model: DB93-16761C remote +// Brand: Samsung, Model: IEC-R03 remote +// Brand: Samsung, Model: AK59-00167A Bluray remote (SAMSUNG36) +// Brand: Samsung, Model: AR09FSSDAWKNFA A/C (SAMSUNG_AC) +// Brand: Samsung, Model: AR12KSFPEWQNET A/C (SAMSUNG_AC) +// Brand: Samsung, Model: AR12HSSDBWKNEU A/C (SAMSUNG_AC) +// Brand: Samsung, Model: AR12NXCXAWKXEU A/C (SAMSUNG_AC) #ifndef IR_SAMSUNG_H_ #define IR_SAMSUNG_H_ @@ -16,21 +33,9 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Samsung, Model: UA55H6300 TV -// Brand: Samsung, Model: DB63-03556X003 remote -// Brand: Samsung, Model: DB93-16761C remote -// Brand: Samsung, Model: IEC-R03 remote -// Brand: Samsung, Model: AR09FSSDAWKNFA A/C -// Brand: Samsung, Model: AR12KSFPEWQNET A/C -// Brand: Samsung, Model: AR12HSSDBWKNEU A/C -// Brand: Samsung, Model: AR12NXCXAWKXEU A/C - -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/505 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 - // Constants + +// SamsungAc // Byte[1] // Checksum 0b11110000 ??? const uint8_t kSamsungAcPower1Offset = 5; // Mask 0b00100000 @@ -86,11 +91,11 @@ const uint16_t kSamsungAcSectionLength = 7; const uint64_t kSamsungAcPowerSection = 0x1D20F00000000; // Classes +/// Class for handling detailed Samsung A/C messages. class IRSamsungAc { public: explicit IRSamsungAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(const bool forcepower = true, const bool initialPower = true); #if SEND_SAMSUNG_AC void send(const uint16_t repeat = kSamsungAcDefaultRepeat, @@ -99,6 +104,10 @@ class IRSamsungAc { const bool calcchecksum = true); void sendOn(const uint16_t repeat = kSamsungAcDefaultRepeat); void sendOff(const uint16_t repeat = kSamsungAcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_SAMSUNG_AC void begin(void); @@ -128,7 +137,6 @@ class IRSamsungAc { bool getDisplay(void); void setIon(const bool on); bool getIon(void); - uint8_t* getRaw(void); void setRaw(const uint8_t new_code[], const uint16_t length = kSamsungAcStateLength); @@ -145,13 +153,14 @@ class IRSamsungAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kSamsungAcExtendedStateLength]; - bool _forcepower; // Hack to know when we need to send a special power mesg. + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kSamsungAcExtendedStateLength]; ///< State in code form. + bool _forcepower; ///< Hack to know when we need to send a special power mesg bool _lastsentpowerstate; void checksum(const uint16_t length = kSamsungAcStateLength); }; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Sanyo.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp similarity index 55% rename from lib/IRremoteESP8266-2.7.7/src/ir_Sanyo.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp index f797fb678..25baf380b 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Sanyo.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp @@ -2,19 +2,27 @@ // Copyright 2016 marcosamarinho // Copyright 2017 David Conran +/// @file +/// @brief Support for Sanyo protocols. +/// Sanyo LC7461 support originally by marcosamarinho +/// Sanyo SA 8650B originally added from +/// https://github.com/shirriff/Arduino-IRremote/ +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp +/// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp +/// @see http://slydiman.narod.ru/scr/kb/sanyo.htm + +// Supports: +// Brand: Sanyo, Model: SA 8650B - disabled +// Brand: Sanyo, Model: LC7461 transmitter IC (SANYO_LC7461) + #include #include "IRrecv.h" #include "IRsend.h" -// Sanyo SA 8650B originally added from: -// https://github.com/shirriff/Arduino-IRremote/ -// Sanyo LC7461 support originally by marcosamarinho // Constants // Sanyo SA 8650B -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp - const uint16_t kSanyoSa8650bHdrMark = 3500; // seen range 3500 const uint16_t kSanyoSa8650bHdrSpace = 950; // seen 950 const uint16_t kSanyoSa8650bOneMark = 2400; // seen 2400 @@ -22,12 +30,8 @@ const uint16_t kSanyoSa8650bZeroMark = 700; // seen 700 // usually see 713 - not using ticks as get number wrapround const uint16_t kSanyoSa8650bDoubleSpaceUsecs = 800; const uint16_t kSanyoSa8650bRptLength = 45000; -// Sanyo LC7461 -// Ref: -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp -// http://slydiman.narod.ru/scr/kb/sanyo.htm -// http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf +// Sanyo LC7461 const uint16_t kSanyoLc7461AddressMask = (1 << kSanyoLC7461AddressBits) - 1; const uint16_t kSanyoLc7461CommandMask = (1 << kSanyoLC7461CommandBits) - 1; const uint16_t kSanyoLc7461HdrMark = 9000; @@ -45,18 +49,15 @@ const uint16_t kSanyoLc7461MinGap = kSanyoLc7461BitMark); #if SEND_SANYO -// Construct a Sanyo LC7461 message. -// -// Args: -// address: The 13 bit value of the address(Custom) portion of the protocol. -// command: The 8 bit value of the command(Key) portion of the protocol. -// Returns: -// An uint64_t with the encoded raw 42 bit Sanyo LC7461 data value. -// -// Notes: -// This protocol uses the NEC protocol timings. However, data is -// formatted as : address(13 bits), !address, command(8 bits), !command. -// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon +/// Construct a Sanyo LC7461 message. +/// @param[in] address The 13 bit value of the address(Custom) portion of the +/// protocol. +/// @param[in] command The 8 bit value of the command(Key) portion of the +/// protocol. +/// @return An uint64_t with the encoded raw 42 bit Sanyo LC7461 data value. +/// @note This protocol uses the NEC protocol timings. However, data is +/// formatted as : address(13 bits), !address, command(8 bits), !command. +/// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon uint64_t IRsend::encodeSanyoLC7461(uint16_t address, uint8_t command) { // Mask our input values to ensure the correct bit sizes. address &= kSanyoLc7461AddressMask; @@ -75,56 +76,44 @@ uint64_t IRsend::encodeSanyoLC7461(uint16_t address, uint8_t command) { return data; } -// Send a Sanyo LC7461 message. -// -// Args: -// data: The contents of the command you want to send. -// nbits: The bit size of the command being sent. -// repeat: The number of times you want the command to be repeated. -// -// Status: BETA / Probably works. -// -// Notes: -// Based on @marcosamarinho's work. -// This protocol uses the NEC protocol timings. However, data is -// formatted as : address(13 bits), !address, command (8 bits), !command. -// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon -// Information for this protocol is available at the Sanyo LC7461 datasheet. -// Repeats are performed similar to the NEC method of sending a special -// repeat message, rather than duplicating the entire message. -// Ref: -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp -// http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf -void IRsend::sendSanyoLC7461(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a Sanyo LC7461 message. +/// Status: BETA / Probably works. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note Based on \@marcosamarinho's work. +/// This protocol uses the NEC protocol timings. However, data is +/// formatted as : address(13 bits), !address, command (8 bits), !command. +/// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon +/// Information for this protocol is available at the Sanyo LC7461 datasheet. +/// Repeats are performed similar to the NEC method of sending a special +/// repeat message, rather than duplicating the entire message. +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp +/// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf +void IRsend::sendSanyoLC7461(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { // This protocol appears to be another 42-bit variant of the NEC protocol. sendNEC(data, nbits, repeat); } #endif // SEND_SANYO #if DECODE_SANYO -// Decode the supplied SANYO LC7461 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works. -// -// Notes: -// Based on @marcosamarinho's work. -// This protocol uses the NEC protocol. However, data is -// formatted as : address(13 bits), !address, command (8 bits), !command. -// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon -// Information for this protocol is available at the Sanyo LC7461 datasheet. -// Ref: -// http://slydiman.narod.ru/scr/kb/sanyo.htm -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp -// http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf +/// Decode the supplied SANYO LC7461 message. +/// Status: BETA / Probably works. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note Based on \@marcosamarinho's work. +/// This protocol uses the NEC protocol. However, data is +/// formatted as : address(13 bits), !address, command (8 bits), !command. +/// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon +/// Information for this protocol is available at the Sanyo LC7461 datasheet. +/// @see http://slydiman.narod.ru/scr/kb/sanyo.htm +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp +/// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf bool IRrecv::decodeSanyoLC7461(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kSanyoLC7461Bits) @@ -162,24 +151,21 @@ bool IRrecv::decodeSanyoLC7461(decode_results *results, uint16_t offset, } /* NOTE: Disabled due to poor quality. -// Decode the supplied Sanyo SA 8650B message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Depricated. -// -// NOTE: This decoder looks like rubbish. Only keeping it for compatibility -// with the Arduino IRremote library. Seriously, don't trust it. -// If someone has a device that this is supposed to be for, please log an -// Issue on github with a rawData dump please. We should probably remove -// it. We think this is a Sanyo decoder - serial = SA 8650B -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp +/// Decode the supplied Sanyo SA 8650B message. +/// Status: Depricated. +/// @depricated Disabled due to poor quality. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @warning This decoder looks like rubbish. Only keeping it for compatibility +/// with the Arduino IRremote library. Seriously, don't trust it. +/// If someone has a device that this is supposed to be for, please log an +/// Issue on github with a rawData dump please. We should probably remove it. +/// We think this is a Sanyo decoder - serial = SA 8650B +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp bool IRrecv::decodeSanyo(decode_results *results, uint16_t nbits, bool strict) { if (results->rawlen < 2 * nbits + kHeader - 1) return false; // Shorter than shortest possible. diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Sharp.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.cpp similarity index 64% rename from lib/IRremoteESP8266-2.7.7/src/ir_Sharp.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Sharp.cpp index 95a3de5cc..4ba23ac89 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Sharp.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.cpp @@ -1,7 +1,15 @@ // Copyright 2009 Ken Shirriff // Copyright 2017, 2019 David Conran -// Sharp remote emulation +/// @file +/// @brief Support for Sharp protocols. +/// @see http://www.sbprojects.com/knowledge/ir/sharp.htm +/// @see http://lirc.sourceforge.net/remotes/sharp/GA538WJSA +/// @see http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf +/// @see http://www.hifi-remote.com/johnsfine/DecodeIR.html#Sharp +/// @see GlobalCache's IR Control Tower data. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/638 +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp #include "ir_Sharp.h" #include @@ -14,17 +22,8 @@ #include "IRtext.h" #include "IRutils.h" -// Equipment it seems compatible with: -// * Sharp LC-52D62U -// * Sharp AH-AxSAY A/C (Remote CRMC-A907 JBEZ) -// * -// - // Constants // period time = 1/38000Hz = 26.316 microseconds. -// Ref: -// GlobalCache's IR Control Tower data. -// http://www.sbprojects.com/knowledge/ir/sharp.php const uint16_t kSharpTick = 26; const uint16_t kSharpBitMarkTicks = 10; const uint16_t kSharpBitMark = kSharpBitMarkTicks * kSharpTick; @@ -50,28 +49,18 @@ using irutils::minsToString; using irutils::setBit; using irutils::setBits; +// Also used by Denon protocol #if (SEND_SHARP || SEND_DENON) -// Send a (raw) Sharp message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kSharpBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE / Working fine. -// -// Notes: -// This procedure handles the inversion of bits required per protocol. -// The protocol spec says to send the LSB first, but legacy code & usage -// has us sending the MSB first. Grrrr. Normal invocation of encodeSharp() -// handles this for you, assuming you are using the correct/standard values. -// e.g. sendSharpRaw(encodeSharp(address, command)); -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sharp.htm -// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA -// http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf -// http://www.hifi-remote.com/johnsfine/DecodeIR.html#Sharp +/// Send a (raw) Sharp message +/// @note Status: STABLE / Working fine. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note his procedure handles the inversion of bits required per protocol. +/// The protocol spec says to send the LSB first, but legacy code & usage +/// has us sending the MSB first. Grrrr. Normal invocation of encodeSharp() +/// handles this for you, assuming you are using the correct/standard values. +/// e.g. sendSharpRaw(encodeSharp(address, command)); void IRsend::sendSharpRaw(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { uint64_t tempdata = data; @@ -93,30 +82,20 @@ void IRsend::sendSharpRaw(const uint64_t data, const uint16_t nbits, } } -// Encode a (raw) Sharp message from it's components. -// -// Args: -// address: The value of the address to be sent. -// command: The value of the address to be sent. (8 bits) -// expansion: The value of the expansion bit to use. (0 or 1, typically 1) -// check: The value of the check bit to use. (0 or 1, typically 0) -// MSBfirst: Flag indicating MSB first or LSB first order. (Default: false) -// Returns: -// An uint32_t containing the raw Sharp message for sendSharpRaw(). -// -// Status: STABLE / Works okay. -// -// Notes: -// Assumes the standard Sharp bit sizes. -// Historically sendSharp() sends address & command in -// MSB first order. This is actually incorrect. It should be sent in LSB -// order. The behaviour of sendSharp() hasn't been changed to maintain -// backward compatibility. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sharp.htm -// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA -// http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf +/// Encode a (raw) Sharp message from it's components. +/// Status: STABLE / Works okay. +/// @param[in] address The value of the address to be sent. +/// @param[in] command The value of the address to be sent. (8 bits) +/// @param[in] expansion The value of the expansion bit to use. +/// (0 or 1, typically 1) +/// @param[in] check The value of the check bit to use. (0 or 1, typically 0) +/// @param[in] MSBfirst Flag indicating MSB first or LSB first order. +/// @return A uint32_t containing the raw Sharp message for `sendSharpRaw()`. +/// @note Assumes the standard Sharp bit sizes. +/// Historically sendSharp() sends address & command in +/// MSB first order. This is actually incorrect. It should be sent in LSB +/// order. The behaviour of sendSharp() hasn't been changed to maintain +/// backward compatibility. uint32_t IRsend::encodeSharp(const uint16_t address, const uint16_t command, const uint16_t expansion, const uint16_t check, const bool MSBfirst) { @@ -135,60 +114,45 @@ uint32_t IRsend::encodeSharp(const uint16_t address, const uint16_t command, (tempexpansion << 1) | tempcheck; } -// Send a Sharp message -// -// Args: -// address: Address value to be sent. -// command: Command value to be sent. -// nbits: Nr. of bits of data to be sent. Typically kSharpBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: DEPRICATED / Previously working fine. -// -// Notes: -// This procedure has a non-standard invocation style compared to similar -// sendProtocol() routines. This is due to legacy, compatibility, & historic -// reasons. Normally the calling syntax version is like sendSharpRaw(). -// This procedure transmits the address & command in MSB first order, which is -// incorrect. This behaviour is left as-is to maintain backward -// compatibility with legacy code. -// In short, you should use sendSharpRaw(), encodeSharp(), and the correct -// values of address & command instead of using this, & the wrong values. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sharp.htm -// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA -// http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf +/// Send a Sharp message +/// Status: DEPRECATED / Previously working fine. +/// @deprecated Only use this if you are using legacy from the original +/// Arduino-IRremote library. 99% of the time, you will want to use +/// `sendSharpRaw()` instead +/// @param[in] address Address value to be sent. +/// @param[in] command Command value to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This procedure has a non-standard invocation style compared to similar +/// sendProtocol() routines. This is due to legacy, compatibility, & historic +/// reasons. Normally the calling syntax version is like sendSharpRaw(). +/// This procedure transmits the address & command in MSB first order, which is +/// incorrect. This behaviour is left as-is to maintain backward +/// compatibility with legacy code. +/// In short, you should use sendSharpRaw(), encodeSharp(), and the correct +/// values of address & command instead of using this, & the wrong values. void IRsend::sendSharp(const uint16_t address, uint16_t const command, const uint16_t nbits, const uint16_t repeat) { sendSharpRaw(encodeSharp(address, command, 1, 0, true), nbits, repeat); } #endif // (SEND_SHARP || SEND_DENON) +// Used by decodeDenon too. #if (DECODE_SHARP || DECODE_DENON) -// Decode the supplied Sharp message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. Typically kSharpBits. -// strict: Flag indicating if we should perform strict matching. -// expansion: Should we expect the expansion bit to be set. Default is true. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working fine. -// -// Note: -// This procedure returns a value suitable for use in sendSharpRaw(). -// TODO(crankyoldgit): Need to ensure capture of the inverted message as it can -// be missed due to the interrupt timeout used to detect an end of message. -// Several compliance checks are disabled until that is resolved. -// Ref: -// http://www.sbprojects.com/knowledge/ir/sharp.php -// http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf -// http://www.hifi-remote.com/johnsfine/DecodeIR.html#Sharp +/// Decode the supplied Sharp message. +/// Status: STABLE / Working fine. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @param[in] expansion Should we expect the expansion bit to be set. +/// Default is true. +/// @return True if it can decode it, false if it can't. +/// @note This procedure returns a value suitable for use in `sendSharpRaw()`. +/// @todo Need to ensure capture of the inverted message as it can +/// be missed due to the interrupt timeout used to detect an end of message. +/// Several compliance checks are disabled until that is resolved. bool IRrecv::decodeSharp(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict, const bool expansion) { @@ -253,18 +217,13 @@ bool IRrecv::decodeSharp(decode_results *results, uint16_t offset, #endif // (DECODE_SHARP || DECODE_DENON) #if SEND_SHARP_AC -// Send a Sharp A/C message. -// -// Args: -// data: An array of kSharpAcStateLength bytes containing the IR command. -// nbytes: Nr. of bytes of data to send. i.e. length of `data`. -// repeat: Nr. of times the message should be repeated. -// -// Status: Alpha / Untested. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/638 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp +/// Send a Sharp A/C message. +/// Status: Alpha / Untested. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/638 +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp void IRsend::sendSharpAc(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kSharpAcStateLength) @@ -278,24 +237,29 @@ void IRsend::sendSharpAc(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_SHARP_AC +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRSharpAc::IRSharpAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRSharpAc::begin(void) { _irsend.begin(); } #if SEND_SHARP_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRSharpAc::send(const uint16_t repeat) { _irsend.sendSharpAc(getRaw(), kSharpAcStateLength, repeat); } #endif // SEND_SHARP_AC -// Calculate the checksum for a given state. -// Args: -// state: The array to verify the checksums of. -// length: The size of the state. -// Returns: -// The 4 bit checksum. +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated 4-bit checksum value. uint8_t IRSharpAc::calcChecksum(uint8_t state[], const uint16_t length) { uint8_t xorsum = xorBytes(state, length - 1); xorsum ^= GETBITS8(state[length - 1], kLowNibble, kNibbleSize); @@ -303,23 +267,22 @@ uint8_t IRSharpAc::calcChecksum(uint8_t state[], const uint16_t length) { return GETBITS8(xorsum, kLowNibble, kNibbleSize); } -// Verify the checksums are valid for a given state. -// Args: -// state: The array to verify the checksums of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRSharpAc::validChecksum(uint8_t state[], const uint16_t length) { return GETBITS8(state[length - 1], kHighNibble, kNibbleSize) == IRSharpAc::calcChecksum(state, length); } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRSharpAc::checksum(void) { setBits(&remote[kSharpAcStateLength - 1], kHighNibble, kNibbleSize, this->calcChecksum(remote)); } +/// Reset the state of the remote to a known good state/sequence. void IRSharpAc::stateReset(void) { static const uint8_t reset[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x01, 0x00, 0x00, 0x08, 0x80, 0x00, 0xE0, @@ -330,31 +293,42 @@ void IRSharpAc::stateReset(void) { _fan = getFan(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRSharpAc::getRaw(void) { this->checksum(); // Ensure correct settings before sending. return remote; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. void IRSharpAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote, new_code, std::min(length, kSharpAcStateLength)); } +/// Set the value of the Power Special setting without any checks. +/// @param[in] value The value to set Power Special to. void IRSharpAc::setPowerSpecial(const uint8_t value) { setBits(&remote[kSharpAcBytePowerSpecial], kSharpAcPowerSetSpecialOffset, kSharpAcPowerSpecialSize, value); } +/// Get the value of the Power Special setting. +/// @return The setting's value. uint8_t IRSharpAc::getPowerSpecial(void) { return GETBITS8(remote[kSharpAcBytePowerSpecial], kSharpAcPowerSetSpecialOffset, kSharpAcPowerSpecialSize); } -// Clear the "special"/non-normal bits in the power section. -// e.g. for normal/common command modes. +/// Clear the "special"/non-normal bits in the power section. +/// e.g. for normal/common command modes. void IRSharpAc::clearPowerSpecial(void) { setPowerSpecial(getPowerSpecial() & kSharpAcPowerOn); } +/// Is one of the special power states in use? +/// @return true, it is. false, it isn't. bool IRSharpAc::isPowerSpecial(void) { switch (getPowerSpecial()) { case kSharpAcPowerSetSpecialOff: @@ -364,10 +338,15 @@ bool IRSharpAc::isPowerSpecial(void) { } } +/// Set the requested power state of the A/C to on. void IRSharpAc::on(void) { setPower(true); } +/// Set the requested power state of the A/C to off. void IRSharpAc::off(void) { setPower(false); } +/// Change the power setting, including the previous power state. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @param[in] prev_on true, the setting is on. false, the setting is off. void IRSharpAc::setPower(const bool on, const bool prev_on) { setPowerSpecial(on ? (prev_on ? kSharpAcPowerOn : kSharpAcPowerOnFromOff) : kSharpAcPowerOff); @@ -376,6 +355,8 @@ void IRSharpAc::setPower(const bool on, const bool prev_on) { setSpecial(kSharpAcSpecialPower); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRSharpAc::getPower(void) { switch (getPowerSpecial()) { case kSharpAcPowerUnknown: @@ -384,6 +365,8 @@ bool IRSharpAc::getPower(void) { } } +/// Set the value of the Special (button/command?) setting. +/// @param[in] mode The value to set Special to. void IRSharpAc::setSpecial(const uint8_t mode) { switch (mode) { case kSharpAcSpecialPower: @@ -400,12 +383,13 @@ void IRSharpAc::setSpecial(const uint8_t mode) { } } +/// Get the value of the Special (button/command?) setting. +/// @return The setting's value. uint8_t IRSharpAc::getSpecial(void) { return remote[kSharpAcByteSpecial]; } -// Set the temp in deg C -// Args: -// temp: Desired Temperature (Celsius) -// save: Do we save this Temperature as a user set temp? (Default: true) +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. +/// @param[in] save Do we save this setting as a user set one? void IRSharpAc::setTemp(const uint8_t temp, const bool save) { switch (this->getMode()) { // Auto & Dry don't allow temp changes and have a special temp. @@ -425,15 +409,22 @@ void IRSharpAc::setTemp(const uint8_t temp, const bool save) { clearPowerSpecial(); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRSharpAc::getTemp(void) { return GETBITS8(remote[kSharpAcByteTemp], kLowNibble, kNibbleSize) + kSharpAcMinTemp; } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRSharpAc::getMode(void) { return GETBITS8(remote[kSharpAcByteMode], kLowNibble, kSharpAcModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @param[in] save Do we save this setting as a user set one? void IRSharpAc::setMode(const uint8_t mode, const bool save) { switch (mode) { case kSharpAcAuto: @@ -458,7 +449,9 @@ void IRSharpAc::setMode(const uint8_t mode, const bool save) { clearPowerSpecial(); } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @param[in] save Do we save this setting as a user set one? void IRSharpAc::setFan(const uint8_t speed, const bool save) { switch (speed) { case kSharpAcFanAuto: @@ -478,57 +471,76 @@ void IRSharpAc::setFan(const uint8_t speed, const bool save) { clearPowerSpecial(); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRSharpAc::getFan(void) { return GETBITS8(remote[kSharpAcByteFan], kSharpAcFanOffset, kSharpAcFanSize); } +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSharpAc::getTurbo(void) { return (getPowerSpecial() == kSharpAcPowerSetSpecialOn) && (getSpecial() == kSharpAcSpecialTurbo); } -// Note: If you use this method, you will need to send it before making -// other changes to the settings, as they may overwrite some of the bits -// used by this setting. +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note If you use this method, you will need to send it before making +/// other changes to the settings, as they may overwrite some of the bits +/// used by this setting. void IRSharpAc::setTurbo(const bool on) { if (on) setFan(kSharpAcFanMax); setPowerSpecial(on ? kSharpAcPowerSetSpecialOn : kSharpAcPowerSetSpecialOff); setSpecial(kSharpAcSpecialTurbo); } +/// Get the (vertical) Swing Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSharpAc::getSwingToggle(void) { return GETBITS8(remote[kSharpAcByteSwing], kSharpAcSwingOffset, kSharpAcSwingSize) == kSharpAcSwingToggle; } +/// Set the (vertical) Swing Toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSharpAc::setSwingToggle(const bool on) { setBits(&remote[kSharpAcByteSwing], kSharpAcSwingOffset, kSharpAcSwingSize, on ? kSharpAcSwingToggle : kSharpAcSwingNoToggle); if (on) setSpecial(kSharpAcSpecialSwing); } +/// Get the Ion (Filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSharpAc::getIon(void) { return GETBIT8(remote[kSharpAcByteIon], kSharpAcBitIonOffset); } +/// Set the Ion (Filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSharpAc::setIon(const bool on) { setBit(&remote[kSharpAcByteIon], kSharpAcBitIonOffset, on); clearPowerSpecial(); if (on) setSpecial(kSharpAcSpecialSwing); } +/// Get the Economical mode toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSharpAc::getEconoToggle(void) { return (getPowerSpecial() == kSharpAcPowerSetSpecialOn) && (getSpecial() == kSharpAcSpecialTempEcono); } -// Warning: Probably incompatible with `setTurbo()` +/// Set the Economical mode toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @warning Probably incompatible with `setTurbo()` void IRSharpAc::setEconoToggle(const bool on) { if (on) setSpecial(kSharpAcSpecialTempEcono); setPowerSpecial(on ? kSharpAcPowerSetSpecialOn : kSharpAcPowerSetSpecialOff); } -// Returns how long the timer is set for, in minutes. +/// Get how long the timer is set for, in minutes. +/// @return The time in nr of minutes. uint16_t IRSharpAc::getTimerTime(void) { return GETBITS8(remote[kSharpAcByteTimer], kSharpAcTimerHoursOffset, kSharpAcTimerHoursSize) * kSharpAcTimerIncrement * 2 + @@ -536,21 +548,23 @@ uint16_t IRSharpAc::getTimerTime(void) { : 0); } +/// Is the Timer enabled? +/// @return true, the setting is on. false, the setting is off. bool IRSharpAc::getTimerEnabled(void) { return GETBIT8(remote[kSharpAcByteTimer], kSharpAcBitTimerEnabled); } +/// Get the current timer type. +/// @return true, It's an "On" timer. false, It's an "Off" timer. bool IRSharpAc::getTimerType(void) { return GETBIT8(remote[kSharpAcByteTimer], kSharpAcBitTimerType); } -// Set or cancel the timer function. -// Args: -// enable: Is the timer to be enabled (true) or canceled(false)? -// timer_type: An On (true) or an Off (false). Ignored if canceled. -// mins: Nr. of minutes the timer is to be set to. -// Rounds down to 30 min increments. -// (max: 720 mins (12h), 0 is Off) +/// Set or cancel the timer function. +/// @param[in] enable Is the timer to be enabled (true) or canceled(false)? +/// @param[in] timer_type An On (true) or an Off (false). Ignored if canceled. +/// @param[in] mins Nr. of minutes the timer is to be set to. +/// @note Rounds down to 30 min increments. (max: 720 mins (12h), 0 is Off) void IRSharpAc::setTimer(bool enable, bool timer_type, uint16_t mins) { uint8_t half_hours = std::min(mins / kSharpAcTimerIncrement, kSharpAcTimerHoursMax * 2); @@ -569,11 +583,15 @@ void IRSharpAc::setTimer(bool enable, bool timer_type, uint16_t mins) { setPowerSpecial(kSharpAcPowerTimerSetting); } +/// Get the Clean setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSharpAc::getClean(void) { return GETBIT8(remote[kSharpAcByteClean], kSharpAcBitCleanOffset); } -// Note: Officially A/C unit needs to be "Off" before clean mode can be entered. +/// Set the Economical mode toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note Officially A/C unit needs to be "Off" before clean mode can be entered void IRSharpAc::setClean(const bool on) { // Clean mode appears to be just default dry mode, with an extra bit set. if (on) { @@ -588,7 +606,9 @@ void IRSharpAc::setClean(const bool on) { clearPowerSpecial(); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRSharpAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kSharpAcCool; @@ -599,7 +619,9 @@ uint8_t IRSharpAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRSharpAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -611,7 +633,9 @@ uint8_t IRSharpAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRSharpAc::toCommonMode(const uint8_t mode) { switch (mode) { case kSharpAcCool: return stdAc::opmode_t::kCool; @@ -621,7 +645,9 @@ stdAc::opmode_t IRSharpAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRSharpAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kSharpAcFanMax: return stdAc::fanspeed_t::kMax; @@ -632,7 +658,8 @@ stdAc::fanspeed_t IRSharpAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRSharpAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::SHARP_AC; @@ -658,7 +685,8 @@ stdAc::state_t IRSharpAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRSharpAc::toString(void) { String result = ""; result.reserve(135); // Reserve some heap for the string to reduce fragging. @@ -682,21 +710,16 @@ String IRSharpAc::toString(void) { } #if DECODE_SHARP_AC -// Decode the supplied Sharp A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kSharpAcBits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/638 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp +/// Decode the supplied Sharp A/C message. +/// Status: STABLE / Known working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/638 +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp bool IRrecv::decodeSharpAc(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Sharp.h b/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.h similarity index 82% rename from lib/IRremoteESP8266-2.7.7/src/ir_Sharp.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Sharp.h index 31f340817..38d01a0b0 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Sharp.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.h @@ -1,9 +1,20 @@ // Copyright 2019 crankyoldgit +/// @file +/// @brief Support for Sharp protocols. +/// @see http://www.sbprojects.com/knowledge/ir/sharp.htm +/// @see http://lirc.sourceforge.net/remotes/sharp/GA538WJSA +/// @see http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf +/// @see http://www.hifi-remote.com/johnsfine/DecodeIR.html#Sharp +/// @see GlobalCache's IR Control Tower data. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/638 +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp + // Supports: // Brand: Sharp, Model: LC-52D62U TV // Brand: Sharp, Model: AY-ZP40KR A/C // Brand: Sharp, Model: AH-AxSAY A/C +// Brand: Sharp, Model: CRMC-A907 JBEZ remote // Brand: Sharp, Model: AH-XP10NRY A/C // Brand: Sharp, Model: CRMC-820JBEZ remote @@ -92,14 +103,18 @@ const uint8_t kSharpAcByteIon = 11; const uint8_t kSharpAcBitIonOffset = 2; // Mask 0b00000x00 // Byte[12] (Checksum) - +// Classes +/// Class for handling detailed Sharp A/C messages. class IRSharpAc { public: explicit IRSharpAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - #if SEND_SHARP_AC void send(const uint16_t repeat = kSharpAcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_SHARP_AC void begin(void); @@ -144,15 +159,16 @@ class IRSharpAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // # of bytes per command - uint8_t remote[kSharpAcStateLength]; - uint8_t _temp; // Saved copy of the desired temp. - uint8_t _mode; // Saved copy of the desired mode. - uint8_t _fan; // Saved copy of the desired fan speed. + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote[kSharpAcStateLength]; ///< State of the remote in IR code form + uint8_t _temp; ///< Saved copy of the desired temp. + uint8_t _mode; ///< Saved copy of the desired mode. + uint8_t _fan; ///< Saved copy of the desired fan speed. void stateReset(void); void checksum(void); static uint8_t calcChecksum(uint8_t state[], diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp new file mode 100644 index 000000000..475168721 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp @@ -0,0 +1,24 @@ +// Copyright 2017 David Conran + +/// @file +/// @brief Support for Sherwood protocols. + +// Supports: +// Brand: Sherwood, Model: RC-138 remote +// Brand: Sherwood, Model: RD6505(B) Receiver + +#include +#include "IRsend.h" + +#if SEND_SHERWOOD +/// Send an IR command to a Sherwood device. +/// Status: STABLE / Known working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note Sherwood remote codes appear to be NEC codes with a manditory repeat +/// code. i.e. repeat should be >= kSherwoodMinRepeat (1). +void IRsend::sendSherwood(uint64_t data, uint16_t nbits, uint16_t repeat) { + sendNEC(data, nbits, std::max((uint16_t)kSherwoodMinRepeat, repeat)); +} +#endif // SEND_SHERWOOD diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Sony.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Sony.cpp similarity index 57% rename from lib/IRremoteESP8266-2.7.7/src/ir_Sony.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Sony.cpp index 9ff0c50cc..357fde504 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Sony.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sony.cpp @@ -2,7 +2,12 @@ // Copyright 2016 marcosamarinho // Copyright 2017,2020 David Conran -// Sony Remote Emulation +/// @file +/// @brief Support for Sony SIRC(Serial Infra-Red Control) protocols. +/// Sony originally added from https://github.com/shirriff/Arduino-IRremote/ +/// Updates from marcosamarinho +/// @see http://www.sbprojects.com/knowledge/ir/sirc.php +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1018 // Supports: // Brand: Sony, Model: HT-CT380 Soundbar (Uses 38kHz & 3 repeats) @@ -12,12 +17,8 @@ #include "IRsend.h" #include "IRutils.h" -// Sony originally added from https://github.com/shirriff/Arduino-IRremote/ -// Updates from marcosamarinho // Constants -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php const uint16_t kSonyTick = 200; const uint16_t kSonyHdrMarkTicks = 12; const uint16_t kSonyHdrMark = kSonyHdrMarkTicks * kSonyTick; @@ -35,80 +36,57 @@ const uint16_t kSonyStdFreq = 40000; // kHz const uint16_t kSonyAltFreq = 38000; // kHz #if SEND_SONY -// Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) -// -// Args: -// data: message to be sent. -// nbits: Nr. of bits of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. (Default: 2) -// -// Status: STABLE / Known working. -// -// Notes: -// sendSony() should typically be called with repeat=2 as Sony devices -// expect the message to be sent at least 3 times. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php -void IRsend::sendSony(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) +/// Status: STABLE / Known working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note sendSony() should typically be called with repeat=2 as Sony devices +/// expect the message to be sent at least 3 times. +void IRsend::sendSony(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { _sendSony(data, nbits, repeat, kSonyStdFreq); } -// Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. -// -// Args: -// data: message to be sent. -// nbits: Nr. of bits of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. (Default: 3) -// -// Status: STABLE / Known working. -// -// Notes: -// - `sendSony38()`` should typically be called with repeat=3 as these Sony -// devices expect the message to be sent at least 4 times. -// - Messages send via this method will be detected by this library as just -// `SONY`, not `SONY_38K` as the library has no way to determine the -// modulation frequency used. Hence, there is no `decodeSony38()`. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1018 -void IRsend::sendSony38(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. +/// Status: STABLE / Known working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note `sendSony38()` should typically be called with repeat=3 as these Sony +/// devices expect the message to be sent at least 4 times. +/// @warning Messages send via this method will be detected by this library as +/// just `SONY`, not `SONY_38K` as the library has no way to determine the +/// modulation frequency used. Hence, there is no `decodeSony38()`. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1018 +void IRsend::sendSony38(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { _sendSony(data, nbits, repeat, kSonyAltFreq); } -// Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message. -// -// Args: -// data: message to be sent. -// nbits: Nr. of bits of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. -// freq: Frequency of the modulation to transmit at. (Hz or kHz) -// -// Status: STABLE / Known working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php -void IRsend::_sendSony(uint64_t data, uint16_t nbits, uint16_t repeat, - uint16_t freq) { +/// Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message +/// Status: STABLE / Known working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @param[in] freq Frequency of the modulation to transmit at. (Hz or kHz) +void IRsend::_sendSony(const uint64_t data, const uint16_t nbits, + const uint16_t repeat, const uint16_t freq) { sendGeneric(kSonyHdrMark, kSonySpace, kSonyOneMark, kSonySpace, kSonyZeroMark, kSonySpace, 0, // No Footer mark. kSonyMinGap, kSonyRptLength, data, nbits, freq, true, repeat, 33); } -// Convert Sony/SIRC command, address, & extended bits into sendSony format. -// Args: -// nbits: Sony protocol bit size. -// command: Sony command bits. -// address: Sony address bits. -// extended: Sony extended bits. -// Returns: -// A sendSony compatible data message. -// -// Status: STABLE / Should be working. -uint32_t IRsend::encodeSony(uint16_t nbits, uint16_t command, uint16_t address, - uint16_t extended) { +/// Convert Sony/SIRC command, address, & extended bits into sendSony format. +/// Status: STABLE / Should be working. +/// @param[in] nbits Sony protocol bit size. +/// @param[in] command Sony command bits. +/// @param[in] address Sony address bits. +/// @param[in] extended Sony extended bits. +/// @return A `sendSony()` etc compatible data message. +uint32_t IRsend::encodeSony(const uint16_t nbits, const uint16_t command, + const uint16_t address, const uint16_t extended) { uint32_t result = 0; switch (nbits) { case 12: // 5 address bits. @@ -127,26 +105,19 @@ uint32_t IRsend::encodeSony(uint16_t nbits, uint16_t command, uint16_t address, result = (result << 7) | (command & 0x7F); // All sizes have 7 command bits. return reverseBits(result, nbits); // sendSony uses reverse ordered bits. } -#endif +#endif // SEND_SONY #if DECODE_SONY -// Decode the supplied Sony/SIRC message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. strict mode is ALPHA / Untested. -// -// Notes: -// SONY protocol, SIRC (Serial Infra-Red Control) can be 12,15,20 bits long. -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php +/// Decode the supplied Sony/SIRC message. +/// Status: STABLE / Should be working. strict mode is ALPHA / Untested. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note SONY protocol, SIRC (Serial Infra-Red Control) can be 12, 15, or 20 +/// bits long. bool IRrecv::decodeSony(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + kHeader - 1 + offset) @@ -217,4 +188,4 @@ bool IRrecv::decodeSony(decode_results *results, uint16_t offset, } return true; } -#endif +#endif // DECODE_SONY diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Symphony.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Symphony.cpp similarity index 62% rename from lib/IRremoteESP8266-2.7.7/src/ir_Symphony.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Symphony.cpp index a65821c33..d5fedb29b 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Symphony.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Symphony.cpp @@ -1,6 +1,10 @@ // Copyright 2020 David Conran -// Send & decode support for Symphony added by David Conran +/// @file +/// @brief Support for Symphony protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1105 +/// @see https://www.alldatasheet.com/datasheet-pdf/pdf/124369/ANALOGICTECH/SM5021B.html // Supports: // Brand: Symphony, Model: Air Cooler 3Di @@ -22,8 +26,6 @@ #include "IRutils.h" // Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 const uint16_t kSymphonyZeroMark = 400; const uint16_t kSymphonyZeroSpace = 1250; const uint16_t kSymphonyOneMark = kSymphonyZeroSpace; @@ -32,19 +34,11 @@ const uint32_t kSymphonyFooterGap = 4 * (kSymphonyZeroMark + kSymphonyZeroSpace); #if SEND_SYMPHONY -// Send a Symphony packet. -// -// Args: -// data: The data we want to send. MSB first. -// nbits: The number of bits of data to send. (Typically 12, 24, or 32[Nokia]) -// repeat: The nr. of times the message should be sent. -// -// Status: STABLE / Should be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1105 -// https://www.alldatasheet.com/datasheet-pdf/pdf/124369/ANALOGICTECH/SM5021B.html +/// Send a Symphony packet. +/// Status: STABLE / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendSymphony(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(0, 0, kSymphonyOneMark, kSymphonyOneSpace, @@ -55,23 +49,14 @@ void IRsend::sendSymphony(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_SYMPHONY #if DECODE_SYMPHONY -// Decode a Symphony packet if possible. -// Places successful decode information in the results pointer. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. Typically kSymphonyBits -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1105 -// https://www.alldatasheet.com/datasheet-pdf/pdf/124369/ANALOGICTECH/SM5021B.html +/// Decode the supplied Symphony packet/message. +/// Status: STABLE / Should be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeSymphony(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint64_t data = 0; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Tcl.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.cpp similarity index 64% rename from lib/IRremoteESP8266-2.7.7/src/ir_Tcl.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Tcl.cpp index ff144e9c1..a818377fd 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Tcl.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.cpp @@ -1,5 +1,8 @@ // Copyright 2019 David Conran +/// @file +/// @brief Support for TCL protocols. + #include "ir_Tcl.h" #include #include @@ -22,6 +25,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_TCL112AC +/// Send a TCL 112-bit A/C message. +/// Status: Beta / Probably working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendTcl112Ac(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { sendGeneric(kTcl112AcHdrMark, kTcl112AcHdrSpace, @@ -32,24 +40,29 @@ void IRsend::sendTcl112Ac(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_TCL112AC +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRTcl112Ac::IRTcl112Ac(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRTcl112Ac::begin(void) { this->_irsend.begin(); } #if SEND_TCL112AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRTcl112Ac::send(const uint16_t repeat) { this->_irsend.sendTcl112Ac(getRaw(), kTcl112AcStateLength, repeat); } #endif // SEND_TCL112AC -// Calculate the checksum for a given array. -// Args: -// state: The array to calculate the checksum over. -// length: The size of the array. -// Returns: -// The 8 bit checksum value. +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRTcl112Ac::calcChecksum(uint8_t state[], const uint16_t length) { if (length) return sumBytes(state, length - 1); @@ -57,23 +70,23 @@ uint8_t IRTcl112Ac::calcChecksum(uint8_t state[], const uint16_t length) { return 0; } -// Calculate & set the checksum for the current internal state of the remote. +/// Calculate & set the checksum for the current internal state of the remote. +/// @param[in] length The length/size of the internal array to checksum. void IRTcl112Ac::checksum(const uint16_t length) { // Stored the checksum value in the last byte. if (length > 1) remote_state[length - 1] = calcChecksum(remote_state, length); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRTcl112Ac::validChecksum(uint8_t state[], const uint16_t length) { return (length > 1 && state[length - 1] == calcChecksum(state, length)); } +/// Reset the internal state of the emulation. (On, Cool, 24C) void IRTcl112Ac::stateReset(void) { // A known good state. (On, Cool, 24C) static const uint8_t reset[kTcl112AcStateLength] = { @@ -82,41 +95,48 @@ void IRTcl112Ac::stateReset(void) { memcpy(remote_state, reset, kTcl112AcStateLength); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRTcl112Ac::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. void IRTcl112Ac::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kTcl112AcStateLength)); } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRTcl112Ac::on(void) { this->setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRTcl112Ac::off(void) { this->setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setPower(const bool on) { setBit(&remote_state[5], kTcl112AcPowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getPower(void) { return GETBIT8(remote_state[5], kTcl112AcPowerOffset); } -// Get the requested climate operation mode of the a/c unit. -// Returns: -// A uint8_t containing the A/C mode. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRTcl112Ac::getMode(void) { return remote_state[6] & 0xF; } -// Set the requested climate operation mode of the a/c unit. -// Note: Fan/Ventilation mode sets the fan speed to high. -// Unknown values default to Auto. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @note Fan/Ventilation mode sets the fan speed to high. +/// Unknown values default to Auto. void IRTcl112Ac::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. switch (mode) { @@ -134,6 +154,9 @@ void IRTcl112Ac::setMode(const uint8_t mode) { } } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. +/// @note The temperature resolution is 0.5 of a degree. void IRTcl112Ac::setTemp(const float celsius) { // Make sure we have desired temp in the correct range. float safecelsius = std::max(celsius, kTcl112AcTempMin); @@ -146,6 +169,9 @@ void IRTcl112Ac::setTemp(const float celsius) { (uint8_t)kTcl112AcTempMax - nrHalfDegrees / 2); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. +/// @note The temperature resolution is 0.5 of a degree. float IRTcl112Ac::getTemp(void) { float result = kTcl112AcTempMax - GETBITS8(remote_state[7], kLowNibble, kNibbleSize); @@ -153,8 +179,9 @@ float IRTcl112Ac::getTemp(void) { return result; } -// Set the speed of the fan. -// Unknown speeds will default to Auto. +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @note Unknown speeds will default to Auto. void IRTcl112Ac::setFan(const uint8_t speed) { switch (speed) { case kTcl112AcFanAuto: @@ -168,63 +195,75 @@ void IRTcl112Ac::setFan(const uint8_t speed) { } } -// Return the currect fan speed. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRTcl112Ac::getFan(void) { return GETBITS8(remote_state[8], kLowNibble, kTcl112AcFanSize); } -// Control economy mode. +/// Set the economy setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setEcono(const bool on) { setBit(&remote_state[5], kTcl112AcBitEconoOffset, on); } -// Return the economy state of the A/C. +/// Get the economy setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getEcono(void) { return GETBIT8(remote_state[5], kTcl112AcBitEconoOffset); } -// Control Health mode. +/// Set the Health (Filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setHealth(const bool on) { setBit(&remote_state[6], kTcl112AcBitHealthOffset, on); } -// Return the Health mode state of the A/C. +/// Get the Health (Filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getHealth(void) { return GETBIT8(remote_state[6], kTcl112AcBitHealthOffset); } -// Control Light/Display mode. +/// Set the Light (LED/Display) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setLight(const bool on) { setBit(&remote_state[5], kTcl112AcBitLightOffset, !on); // Cleared when on. } -// Return the Light/Display mode state of the A/C. +/// Get the Light (LED/Display) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getLight(void) { return !GETBIT8(remote_state[5], kTcl112AcBitLightOffset); } -// Control Horizontal Swing. +/// Set the horizontal swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setSwingHorizontal(const bool on) { setBit(&remote_state[12], kTcl112AcBitSwingHOffset, on); } -// Return the Horizontal Swing state of the A/C. +/// Get the horizontal swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getSwingHorizontal(void) { return GETBIT8(remote_state[12], kTcl112AcBitSwingHOffset); } -// Control Vertical Swing. +/// Set the vertical swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setSwingVertical(const bool on) { setBits(&remote_state[8], kTcl112AcSwingVOffset, kTcl112AcSwingVSize, on ? kTcl112AcSwingVOn : kTcl112AcSwingVOff); } -// Return the Vertical Swing state of the A/C. +/// Get the vertical swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getSwingVertical(void) { return GETBITS8(remote_state[8], kTcl112AcSwingVOffset, kTcl112AcSwingVSize); } -// Control the Turbo setting. +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setTurbo(const bool on) { setBit(&remote_state[6], kTcl112AcBitTurboOffset, on); if (on) { @@ -233,12 +272,15 @@ void IRTcl112Ac::setTurbo(const bool on) { } } -// Return the Turbo setting state of the A/C. +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getTurbo(void) { return GETBIT8(remote_state[6], kTcl112AcBitTurboOffset); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTcl112Ac::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kTcl112AcCool; @@ -249,7 +291,9 @@ uint8_t IRTcl112Ac::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTcl112Ac::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -261,7 +305,9 @@ uint8_t IRTcl112Ac::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRTcl112Ac::toCommonMode(const uint8_t mode) { switch (mode) { case kTcl112AcCool: return stdAc::opmode_t::kCool; @@ -272,7 +318,9 @@ stdAc::opmode_t IRTcl112Ac::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRTcl112Ac::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kTcl112AcFanHigh: return stdAc::fanspeed_t::kMax; @@ -282,7 +330,8 @@ stdAc::fanspeed_t IRTcl112Ac::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRTcl112Ac::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::TCL112AC; @@ -309,7 +358,8 @@ stdAc::state_t IRTcl112Ac::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRTcl112Ac::toString(void) { String result = ""; result.reserve(140); // Reserve some heap for the string to reduce fragging. @@ -332,7 +382,8 @@ String IRTcl112Ac::toString(void) { } #if DECODE_TCL112AC -// NOTE: There is no `decodedecodeTcl112Ac()`. -// It's the same as `decodeMitsubishi112()`. A shared routine is used. -// You can find it in: ir_Mitsubishi.cpp +/// @file +/// @note There is no `decodedecodeTcl112Ac()`. +/// It's the same as `decodeMitsubishi112()`. A shared routine is used. +/// You can find it in: ir_Mitsubishi.cpp #endif // DECODE_TCL112AC diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Tcl.h b/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.h similarity index 84% rename from lib/IRremoteESP8266-2.7.7/src/ir_Tcl.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Tcl.h index 3eef6838a..940b68113 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Tcl.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.h @@ -1,5 +1,8 @@ // Copyright 2019 David Conran +/// @file +/// @brief Support for TCL protocols. + // Supports: // Brand: Leberg, Model: LBS-TOR07 A/C @@ -55,17 +58,22 @@ const uint8_t kTcl112AcSwingVOn = 0b111; const uint8_t kTcl112AcSwingVOff = 0b000; const uint8_t kTcl112AcBitTurboOffset = 6; - +// Classes +/// Class for handling detailed TCL A/C messages. class IRTcl112Ac { public: explicit IRTcl112Ac(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - #if SEND_TCL112AC void send(const uint16_t repeat = kTcl112AcDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_TCL void begin(void); + void stateReset(void); uint8_t* getRaw(void); void setRaw(const uint8_t new_code[], const uint16_t length = kTcl112AcStateLength); @@ -104,12 +112,13 @@ class IRTcl112Ac { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kTcl112AcStateLength]; - void stateReset(void); + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kTcl112AcStateLength]; ///< The State in IR code form. void checksum(const uint16_t length = kTcl112AcStateLength); }; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Teco.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Teco.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.7/src/ir_Teco.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Teco.cpp index 8e33e04ec..733be6247 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Teco.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Teco.cpp @@ -1,7 +1,7 @@ // Copyright 2019 Fabien Valthier -/* -Node MCU/ESP8266 Sketch to emulate Teco -*/ + +/// @file +/// @brief Support for Teco protocols. #include "ir_Teco.h" #include @@ -31,12 +31,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_TECO -// Send a Teco A/C message. -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kTecoBits. -// repeat: Nr. of additional times the message is to be sent. +/// Send a Teco A/C message. +/// Status: Beta / Probably working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendTeco(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kTecoHdrMark, kTecoHdrSpace, kTecoBitMark, kTecoOneSpace, @@ -45,40 +44,59 @@ void IRsend::sendTeco(const uint64_t data, const uint16_t nbits, } #endif // SEND_TECO -// Class for decoding and constructing Teco AC messages. +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRTecoAc::IRTecoAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRTecoAc::begin(void) { _irsend.begin(); } #if SEND_TECO +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRTecoAc::send(const uint16_t repeat) { _irsend.sendTeco(remote_state, kTecoBits, repeat); } #endif // SEND_TECO +/// Reset the internal state of the emulation. +/// @note Mode:auto, Power:Off, fan:auto, temp:16, swing:off, sleep:off void IRTecoAc::stateReset(void) { - // Mode:auto, Power:Off, fan:auto, temp:16, swing:off, sleep:off remote_state = kTecoReset; } +/// Get a copy of the internal state/code for this protocol. +/// @return A code for this protocol based on the current internal state. uint64_t IRTecoAc::getRaw(void) { return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRTecoAc::setRaw(const uint64_t new_code) { remote_state = new_code; } +/// Set the requested power state of the A/C to on. void IRTecoAc::on(void) { setPower(true); } +/// Set the requested power state of the A/C to off. void IRTecoAc::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setPower(const bool on) { setBit(&remote_state, kTecoPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getPower(void) { return GETBIT64(remote_state, kTecoPowerOffset); } +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRTecoAc::setTemp(const uint8_t temp) { uint8_t newtemp = temp; newtemp = std::min(newtemp, kTecoMaxTemp); @@ -87,11 +105,14 @@ void IRTecoAc::setTemp(const uint8_t temp) { newtemp - kTecoMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRTecoAc::getTemp(void) { return GETBITS64(remote_state, kTecoTempOffset, kTecoTempSize) + kTecoMinTemp; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRTecoAc::setFan(const uint8_t speed) { uint8_t newspeed = speed; switch (speed) { @@ -104,10 +125,14 @@ void IRTecoAc::setFan(const uint8_t speed) { setBits(&remote_state, kTecoFanOffset, kTecoFanSize, newspeed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRTecoAc::getFan(void) { return GETBITS64(remote_state, kTecoFanOffset, kTecoFanSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRTecoAc::setMode(const uint8_t mode) { uint8_t newmode = mode; switch (mode) { @@ -121,54 +146,80 @@ void IRTecoAc::setMode(const uint8_t mode) { setBits(&remote_state, kTecoModeOffset, kModeBitsSize, newmode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRTecoAc::getMode(void) { return GETBITS64(remote_state, kTecoModeOffset, kModeBitsSize); } +/// Set the (vertical) swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setSwing(const bool on) { setBit(&remote_state, kTecoSwingOffset, on); } +/// Get the (vertical) swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getSwing(void) { return GETBIT64(remote_state, kTecoSwingOffset); } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setSleep(const bool on) { setBit(&remote_state, kTecoSleepOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getSleep(void) { return GETBIT64(remote_state, kTecoSleepOffset); } +/// Set the Light (LED/Display) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setLight(const bool on) { setBit(&remote_state, kTecoLightOffset, on); } +/// Get the Light (LED/Display) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getLight(void) { return GETBIT64(remote_state, kTecoLightOffset); } +/// Set the Humid setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setHumid(const bool on) { setBit(&remote_state, kTecoHumidOffset, on); } +/// Get the Humid setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getHumid(void) { return GETBIT64(remote_state, kTecoHumidOffset); } +/// Set the Save setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setSave(const bool on) { setBit(&remote_state, kTecoSaveOffset, on); } +/// Get the Save setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getSave(void) { return GETBIT64(remote_state, kTecoSaveOffset); } +/// Is the timer function enabled? +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getTimerEnabled(void) { return GETBIT64(remote_state, kTecoTimerOnOffset); } +/// Get the timer time for when the A/C unit will switch power state. +/// @return The number of minutes left on the timer. `0` means off. uint16_t IRTecoAc::getTimer(void) { uint16_t mins = 0; if (getTimerEnabled()) { @@ -181,11 +232,10 @@ uint16_t IRTecoAc::getTimer(void) { return mins; } -// Set the timer for when the A/C unit will switch power state. -// Args: -// nr_mins: Number of minutes before power state change. -// `0` will clear the timer. Max is 24 hrs. -// Time is stored internaly in increments of 30 mins. +/// Set the timer for when the A/C unit will switch power state. +/// @param[in] nr_mins Number of minutes before power state change. +/// `0` will clear the timer. Max is 24 hrs. +/// @note Time is stored internaly in increments of 30 mins. void IRTecoAc::setTimer(const uint16_t nr_mins) { uint16_t mins = std::min(nr_mins, (uint16_t)(24 * 60)); // Limit to 24 hrs. uint8_t hours = mins / 60; @@ -200,7 +250,9 @@ void IRTecoAc::setTimer(const uint16_t nr_mins) { hours / 10); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTecoAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kTecoCool; @@ -211,7 +263,9 @@ uint8_t IRTecoAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTecoAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -223,7 +277,9 @@ uint8_t IRTecoAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRTecoAc::toCommonMode(const uint8_t mode) { switch (mode) { case kTecoCool: return stdAc::opmode_t::kCool; @@ -234,7 +290,9 @@ stdAc::opmode_t IRTecoAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRTecoAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kTecoFanHigh: return stdAc::fanspeed_t::kMax; @@ -244,7 +302,8 @@ stdAc::fanspeed_t IRTecoAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRTecoAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::TECO; @@ -270,7 +329,8 @@ stdAc::state_t IRTecoAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRTecoAc::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -294,18 +354,14 @@ String IRTecoAc::toString(void) { } #if DECODE_TECO -// Decode the supplied Teco message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kTecoBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Tested. +/// Decode the supplied Teco message. +/// Status: STABLE / Tested. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeTeco(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kTecoBits) return false; // Not what is expected diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Teco.h b/lib/IRremoteESP8266-2.7.8/src/ir_Teco.h similarity index 85% rename from lib/IRremoteESP8266-2.7.7/src/ir_Teco.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Teco.h index 8bee1b72b..770890caa 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Teco.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Teco.h @@ -1,5 +1,12 @@ // Copyright 2019 Fabien Valthier +/// @file +/// @brief Support for Teco protocols. + +// Supports: +// Brand: Alaska, Model: SAC9010QC A/C +// Brand: Alaska, Model: SAC9010QC remote + #ifndef IR_TECO_H_ #define IR_TECO_H_ @@ -12,10 +19,6 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Alaska, Model: SAC9010QC A/C -// Brand: Alaska, Model: SAC9010QC remote - // Constants. const uint8_t kTecoAuto = 0; const uint8_t kTecoCool = 1; @@ -100,14 +103,19 @@ const uint64_t kTecoReset = 0b01001010000000000000010000000000000; */ // Classes +/// Class for handling detailed Teco A/C messages. class IRTecoAc { public: explicit IRTecoAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_TECO void send(const uint16_t repeat = kTecoDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. + int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_TECO void begin(void); void on(void); @@ -155,12 +163,13 @@ class IRTecoAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint64_t remote_state; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint64_t remote_state; ///< The state of the IR remote in IR code form. bool getTimerEnabled(void); }; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp similarity index 68% rename from lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp index 3113e1b09..c28b700f8 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp @@ -1,7 +1,9 @@ // Copyright 2017 David Conran -// Toshiba A/C support added by David Conran - +/// @file +/// @brief Support for Toshiba protocols. +/// @see https://github.com/r45635/HVAC-IR-Control +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77 #include "ir_Toshiba.h" #include @@ -14,18 +16,9 @@ #include "IRtext.h" #include "IRutils.h" -// -// Equipment it seems compatible with: -// * Toshiba RAS-B13N3KV2 / Akita EVO II -// * Toshiba RAS-B13N3KVP-E, RAS 18SKP-ES -// * Toshiba WH-TA04NE, WC-L03SE -// * - // Constants // Toshiba A/C -// Ref: -// https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77 const uint16_t kToshibaAcHdrMark = 4400; const uint16_t kToshibaAcHdrSpace = 4300; const uint16_t kToshibaAcBitMark = 543; @@ -43,16 +36,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_TOSHIBA_AC -// Send a Toshiba A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kToshibaACStateLength) -// repeat: Nr. of times the message is to be repeated. -// (Default = kToshibaACMinRepeat). -// -// Status: StABLE / Working. -// +/// Send a Toshiba A/C message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendToshibaAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kToshibaACStateLength) @@ -64,56 +52,52 @@ void IRsend::sendToshibaAC(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_TOSHIBA_AC -// Code to emulate Toshiba A/C IR remote control unit. -// Inspired and derived from the work done at: -// https://github.com/r45635/HVAC-IR-Control -// -// Status: STABLE / Working. -// -// Initialise the object. +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRToshibaAC::IRToshibaAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L103 void IRToshibaAC::stateReset(void) { - // The state of the IR remote in IR code form. - // Known good state obtained from: - // https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L103 static const uint8_t kReset[kToshibaACStateLength] = { 0xF2, 0x0D, 0x03, 0xFC, 0x01}; memcpy(remote_state, kReset, kToshibaACStateLength); mode_state = getMode(true); } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRToshibaAC::begin(void) { _irsend.begin(); } #if SEND_TOSHIBA_AC -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRToshibaAC::send(const uint16_t repeat) { _irsend.sendToshibaAC(getRaw(), kToshibaACStateLength, repeat); } #endif // SEND_TOSHIBA_AC -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRToshibaAC::getRaw(void) { this->checksum(); return remote_state; } -// Override the internal state with the new state. +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. void IRToshibaAC::setRaw(const uint8_t newState[]) { memcpy(remote_state, newState, kToshibaACStateLength); mode_state = this->getMode(true); } -// Calculate the checksum for a given array. -// Args: -// state: The array to calculate the checksum over. -// length: The size of the array. -// Returns: -// The 8 bit checksum value. +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRToshibaAC::calcChecksum(const uint8_t state[], const uint16_t length) { uint8_t checksum = 0; @@ -125,31 +109,32 @@ uint8_t IRToshibaAC::calcChecksum(const uint8_t state[], return checksum; } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRToshibaAC::validChecksum(const uint8_t state[], const uint16_t length) { return (length > 1 && state[length - 1] == IRToshibaAC::calcChecksum(state, length)); } -// Calculate & set the checksum for the current internal state of the remote. +/// Calculate & set the checksum for the current internal state of the remote. +/// @param[in] length The length/size of the internal array to checksum. + void IRToshibaAC::checksum(const uint16_t length) { // Stored the checksum value in the last byte. if (length > 1) remote_state[length - 1] = this->calcChecksum(remote_state, length); } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRToshibaAC::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRToshibaAC::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRToshibaAC::setPower(const bool on) { setBit(&remote_state[6], kToshibaAcPowerOffset, !on); // Cleared when on. if (on) @@ -159,12 +144,15 @@ void IRToshibaAC::setPower(const bool on) { kToshibaAcHeat); } -// Return the requested power state of the A/C. + +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRToshibaAC::getPower(void) { return !GETBIT8(remote_state[6], kToshibaAcPowerOffset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRToshibaAC::setTemp(const uint8_t degrees) { uint8_t temp = std::max((uint8_t)kToshibaAcMinTemp, degrees); temp = std::min((uint8_t)kToshibaAcMaxTemp, temp); @@ -172,14 +160,15 @@ void IRToshibaAC::setTemp(const uint8_t degrees) { temp - kToshibaAcMinTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRToshibaAC::getTemp(void) { return GETBITS8(remote_state[5], kToshibaAcTempOffset, kToshibaAcTempSize) + kToshibaAcMinTemp; } -// Set the speed of the fan, 0-5. -// 0 is auto, 1-5 is the speed, 5 is Max. +/// Set the speed of the fan. +/// @param[in] speed The desired setting (0 is Auto, 1-5 is the speed, 5 is Max) void IRToshibaAC::setFan(const uint8_t speed) { uint8_t fan = speed; // Bounds check @@ -189,7 +178,8 @@ void IRToshibaAC::setFan(const uint8_t speed) { setBits(&remote_state[6], kToshibaAcFanOffset, kToshibaAcFanSize, fan); } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRToshibaAC::getFan(void) { uint8_t fan = GETBITS8(remote_state[6], kToshibaAcFanOffset, kToshibaAcFanSize); @@ -197,11 +187,9 @@ uint8_t IRToshibaAC::getFan(void) { return --fan; } -// Get the requested climate operation mode of the a/c unit. -// Args: -// useRaw: Indicate to get the mode from the state array. (Default: false) -// Returns: -// A uint8_t containing the A/C mode. +/// Get the operating mode setting of the A/C. +/// @param[in] useRaw Indicate to get the mode from the internal state array. +/// @return The current operating mode setting. uint8_t IRToshibaAC::getMode(const bool useRaw) { if (useRaw) return GETBITS8(remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize); @@ -209,9 +197,10 @@ uint8_t IRToshibaAC::getMode(const bool useRaw) { return mode_state; } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @note If we get an unexpected mode, default to AUTO. void IRToshibaAC::setMode(const uint8_t mode) { - // If we get an unexpected mode, default to AUTO. switch (mode) { case kToshibaAcAuto: case kToshibaAcCool: @@ -227,7 +216,9 @@ void IRToshibaAC::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRToshibaAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kToshibaAcCool; @@ -238,7 +229,9 @@ uint8_t IRToshibaAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRToshibaAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kToshibaAcFanMax - 4; @@ -250,7 +243,9 @@ uint8_t IRToshibaAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRToshibaAC::toCommonMode(const uint8_t mode) { switch (mode) { case kToshibaAcCool: return stdAc::opmode_t::kCool; @@ -260,7 +255,9 @@ stdAc::opmode_t IRToshibaAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRToshibaAC::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kToshibaAcFanMax: return stdAc::fanspeed_t::kMax; @@ -272,7 +269,8 @@ stdAc::fanspeed_t IRToshibaAC::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRToshibaAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::TOSHIBA_AC; @@ -297,7 +295,8 @@ stdAc::state_t IRToshibaAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRToshibaAC::toString(void) { String result = ""; result.reserve(40); @@ -312,21 +311,14 @@ String IRToshibaAC::toString(void) { } #if DECODE_TOSHIBA_AC -// Decode a Toshiba AC IR message if possible. -// Places successful decode information in the results pointer. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kToshibaACBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Ref: -// +/// Decode the supplied Toshiba A/C message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeToshibaAC(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.h b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h similarity index 78% rename from lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h index 22fbd7240..0e5022ae7 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Toshiba.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h @@ -1,6 +1,9 @@ // Copyright 2017 David Conran -// Toshiba A/C support added by David Conran +/// @file +/// @brief Support for Toshiba protocols. +/// @see https://github.com/r45635/HVAC-IR-Control +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77 // Supports: // Brand: Toshiba, Model: RAS-B13N3KV2 @@ -54,14 +57,19 @@ const uint8_t kToshibaAcMaxTemp = 30; // 30C #define TOSHIBA_AC_MIN_TEMP kToshibaAcMinTemp #define TOSHIBA_AC_MAX_TEMP kToshibaAcMaxTemp +// Classes +/// Class for handling detailed Toshiba A/C messages. class IRToshibaAC { public: explicit IRToshibaAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_TOSHIBA_AC void send(const uint16_t repeat = kToshibaACMinRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_TOSHIBA_AC void begin(void); @@ -88,11 +96,13 @@ class IRToshibaAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kToshibaACStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kToshibaACStateLength]; ///< The state in IR code form. void checksum(const uint16_t length = kToshibaACStateLength); static uint8_t calcChecksum(const uint8_t state[], const uint16_t length = kToshibaACStateLength); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Trotec.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.7/src/ir_Trotec.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Trotec.cpp index d8b87e034..c2e4d5c00 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Trotec.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.cpp @@ -1,6 +1,11 @@ // Copyright 2017 stufisher // Copyright 2019 crankyoldgit +/// @file +/// @brief Support for Trotec protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/279 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1176 + #include "ir_Trotec.h" #include #include @@ -30,7 +35,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_TROTEC - +/// Send a Trotec message. +/// Status: Beta / Probably Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendTrotec(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kTrotecStateLength) return; @@ -49,33 +58,49 @@ void IRsend::sendTrotec(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_TROTEC +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRTrotecESP::IRTrotecESP(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRTrotecESP::begin(void) { _irsend.begin(); } #if SEND_TROTEC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRTrotecESP::send(const uint16_t repeat) { - this->checksum(); - _irsend.sendTrotec(remote_state, kTrotecStateLength, repeat); + _irsend.sendTrotec(getRaw(), kTrotecStateLength, repeat); } #endif // SEND_TROTEC +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRTrotecESP::calcChecksum(const uint8_t state[], const uint16_t length) { return sumBytes(state + 2, length - 3); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRTrotecESP::validChecksum(const uint8_t state[], const uint16_t length) { return state[length - 1] == calcChecksum(state, length); } +/// Calculate & set the checksum for the current internal state of the remote. void IRTrotecESP::checksum(void) { remote_state[kTrotecStateLength - 1] = sumBytes(remote_state + 2, kTrotecStateLength - 3); } +/// Reset the state of the remote to a known good state/sequence. void IRTrotecESP::stateReset(void) { for (uint8_t i = 2; i < kTrotecStateLength; i++) remote_state[i] = 0x0; @@ -88,41 +113,65 @@ void IRTrotecESP::stateReset(void) { this->setMode(kTrotecAuto); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRTrotecESP::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. void IRTrotecESP::setRaw(const uint8_t state[]) { memcpy(remote_state, state, kTrotecStateLength); } +/// Set the requested power state of the A/C to on. +void IRTrotecESP::on(void) { this->setPower(true); } + +/// Set the requested power state of the A/C to off. +void IRTrotecESP::off(void) { this->setPower(false); } + +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTrotecESP::setPower(const bool on) { setBit(&remote_state[2], kTrotecPowerBitOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRTrotecESP::getPower(void) { return GETBIT8(remote_state[2], kTrotecPowerBitOffset); } +/// Set the speed of the fan. +/// @param[in] fan The desired setting. void IRTrotecESP::setSpeed(const uint8_t fan) { uint8_t speed = std::min(fan, kTrotecFanHigh); setBits(&remote_state[2], kTrotecFanOffset, kTrotecFanSize, speed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRTrotecESP::getSpeed(void) { return GETBITS8(remote_state[2], kTrotecFanOffset, kTrotecFanSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRTrotecESP::setMode(const uint8_t mode) { setBits(&remote_state[2], kTrotecModeOffset, kTrotecModeSize, (mode > kTrotecFan) ? kTrotecAuto : mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRTrotecESP::getMode(void) { return GETBITS8(remote_state[2], kTrotecModeOffset, kTrotecModeSize); } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. void IRTrotecESP::setTemp(const uint8_t celsius) { uint8_t temp = std::max(celsius, kTrotecMinTemp); temp = std::min(temp, kTrotecMaxTemp); @@ -130,27 +179,39 @@ void IRTrotecESP::setTemp(const uint8_t celsius) { temp - kTrotecMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRTrotecESP::getTemp(void) { return GETBITS8(remote_state[3], kTrotecTempOffset, kTrotecTempSize) + kTrotecMinTemp; } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTrotecESP::setSleep(const bool on) { setBit(&remote_state[3], kTrotecSleepBitOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTrotecESP::getSleep(void) { return GETBIT8(remote_state[3], kTrotecSleepBitOffset); } +/// Set the timer time in nr. of Hours. +/// @param[in] timer Nr. of Hours. Max is `kTrotecMaxTimer` void IRTrotecESP::setTimer(const uint8_t timer) { setBit(&remote_state[5], kTrotecTimerBitOffset, timer); remote_state[6] = (timer > kTrotecMaxTimer) ? kTrotecMaxTimer : timer; } +/// Get the timer time in nr. of Hours. +/// @return Nr. of Hours. uint8_t IRTrotecESP::getTimer(void) { return remote_state[6]; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTrotecESP::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kTrotecCool; @@ -161,7 +222,9 @@ uint8_t IRTrotecESP::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTrotecESP::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -173,8 +236,9 @@ uint8_t IRTrotecESP::convertFan(const stdAc::fanspeed_t speed) { } } - -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRTrotecESP::toCommonMode(const uint8_t mode) { switch (mode) { case kTrotecCool: return stdAc::opmode_t::kCool; @@ -184,7 +248,9 @@ stdAc::opmode_t IRTrotecESP::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRTrotecESP::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kTrotecFanHigh: return stdAc::fanspeed_t::kMax; @@ -194,7 +260,8 @@ stdAc::fanspeed_t IRTrotecESP::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRTrotecESP::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::TROTEC; @@ -219,7 +286,8 @@ stdAc::state_t IRTrotecESP::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRTrotecESP::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -234,24 +302,18 @@ String IRTrotecESP::toString(void) { } #if DECODE_TROTEC -// Decode the supplied Trotec message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kTrotecBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Works. Untested on real devices. -// -// Ref: +/// Decode the supplied Trotec message. +/// Status: STABLE / Works. Untested on real devices. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeTrotec(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + kHeader + 2 * kFooter - 1 + offset) - return false; // Can't possibly be a valid Samsung A/C message. + return false; // Can't possibly be a valid Trotec A/C message. if (strict && nbits != kTrotecBits) return false; uint16_t used; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Trotec.h b/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.h similarity index 75% rename from lib/IRremoteESP8266-2.7.7/src/ir_Trotec.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Trotec.h index cc7f0b2fd..951bdf7b2 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Trotec.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.h @@ -1,6 +1,15 @@ // Copyright 2017 stufisher // Copyright 2019 crankyoldgit +/// @file +/// @brief Support for Trotec protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/279 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1176 + +// Supports: +// Brand: Trotec, Model: PAC 3200 A/C +// Brand: Duux, Model: Blizzard Smart 10K / DXMA04 A/C + #ifndef IR_TROTEC_H_ #define IR_TROTEC_H_ @@ -62,17 +71,25 @@ const uint8_t kTrotecMaxTimer = 23; #define TROTEC_MAX_TEMP kTrotecMaxTemp #define TROTEC_MAX_TIMER kTrotecMaxTimer +// Class +/// Class for handling detailed Trotec A/C messages. class IRTrotecESP { public: explicit IRTrotecESP(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - #if SEND_TROTEC void send(const uint16_t repeat = kTrotecDefaultRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_TROTEC void begin(void); + void stateReset(void); + void on(void); + void off(void); void setPower(const bool state); bool getPower(void); @@ -104,14 +121,15 @@ class IRTrotecESP { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kTrotecStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kTrotecStateLength]; ///< Remote state in IR code form. static uint8_t calcChecksum(const uint8_t state[], const uint16_t length = kTrotecStateLength); - void stateReset(void); void checksum(void); }; diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Vestel.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.cpp similarity index 67% rename from lib/IRremoteESP8266-2.7.7/src/ir_Vestel.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Vestel.cpp index 4378497e0..0a67c4e59 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Vestel.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.cpp @@ -1,7 +1,9 @@ // Copyright 2018 Erdem U. Altinyurt // Copyright 2019 David Conran -// Vestel added by Erdem U. Altinyurt +/// @file +/// @brief Support for Vestel protocols. +/// Vestel added by Erdem U. Altinyurt #include "ir_Vestel.h" #include @@ -15,10 +17,6 @@ #include "IRutils.h" #include "ir_Haier.h" -// Equipment it seems compatible with: -// * Vestel AC Model BIOX CXP-9 (9K BTU) -// * - // Ref: // None. Totally reverse engineered. @@ -32,14 +30,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_VESTEL_AC -// Send a Vestel message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kVestelBits. -// -// Status: STABLE / Working. -// +/// Send a Vestel message +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendVestelAc(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { if (nbits % 8 != 0) return; // nbits is required to be a multiple of 8. @@ -50,41 +45,45 @@ void IRsend::sendVestelAc(const uint64_t data, const uint16_t nbits, kVestelAcBitMark, 100000, // Footer + repeat gap data, nbits, 38, false, repeat, 50); } -#endif +#endif // SEND_VESTEL_AC -// Code to emulate Vestel A/C IR remote control unit. - -// Initialise the object. +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRVestelAc::IRVestelAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. +/// @note Power On, Mode Auto, Fan Auto, Temp = 25C/77F void IRVestelAc::stateReset(void) { - // Power On, Mode Auto, Fan Auto, Temp = 25C/77F remote_state = kVestelAcStateDefault; remote_time_state = kVestelAcTimeStateDefault; use_time_state = false; } -// Configure the pin for output. -void IRVestelAc::begin(void) { - _irsend.begin(); -} +/// Set up hardware to be able to send a message. +void IRVestelAc::begin(void) { _irsend.begin(); } #if SEND_VESTEL_AC -// Send the current desired state to the IR LED. -void IRVestelAc::send(void) { _irsend.sendVestelAc(getRaw()); } +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRVestelAc::send(const uint16_t repeat) { + _irsend.sendVestelAc(getRaw(), kVestelAcBits, repeat); +} #endif // SEND_VESTEL_AC -// Return the internal state date of the remote. +/// Get a copy of the internal state/code for this protocol. +/// @return A code for this protocol based on the current internal state. uint64_t IRVestelAc::getRaw(void) { this->checksum(); if (use_time_state) return remote_time_state; return remote_state; } -// Override the internal state with the new state. +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. void IRVestelAc::setRaw(const uint8_t* newState) { uint64_t upState = 0; for (int i = 0; i < 7; i++) @@ -92,6 +91,8 @@ void IRVestelAc::setRaw(const uint8_t* newState) { this->setRaw(upState); } +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. void IRVestelAc::setRaw(const uint64_t newState) { use_time_state = false; remote_state = newState; @@ -104,25 +105,28 @@ void IRVestelAc::setRaw(const uint64_t newState) { } } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRVestelAc::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRVestelAc::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setPower(const bool on) { setBits(&remote_state, kVestelAcPowerOffset, kVestelAcPowerSize, on ? 0b11 : 0b00); use_time_state = false; } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getPower(void) { return GETBITS64(remote_state, kVestelAcPowerOffset, kVestelAcPowerSize); } -// Set the temperature in Celsius degrees. +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRVestelAc::setTemp(const uint8_t temp) { uint8_t new_temp = std::max(kVestelAcMinTempC, temp); new_temp = std::min(kVestelAcMaxTemp, new_temp); @@ -131,13 +135,15 @@ void IRVestelAc::setTemp(const uint8_t temp) { use_time_state = false; } -// Return the set temperature. +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRVestelAc::getTemp(void) { return GETBITS64(remote_state, kVestelAcTempOffset, kNibbleSize) + kVestelAcMinTempH; } -// Set the speed of the fan, +/// Set the speed of the fan. +/// @param[in] fan The desired setting. void IRVestelAc::setFan(const uint8_t fan) { switch (fan) { case kVestelAcFanLow: @@ -154,21 +160,22 @@ void IRVestelAc::setFan(const uint8_t fan) { use_time_state = false; } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRVestelAc::getFan(void) { return GETBITS64(remote_state, kVestelAcFanOffset, kVestelAcFanSize); } -// Get the requested climate operation mode of the a/c unit. -// Returns: -// A uint8_t containing the A/C mode. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRVestelAc::getMode(void) { return GETBITS64(remote_state, kVestelAcModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @note If we get an unexpected mode, default to AUTO. void IRVestelAc::setMode(const uint8_t mode) { - // If we get an unexpected mode, default to AUTO. switch (mode) { case kVestelAcAuto: case kVestelAcCool: @@ -183,7 +190,8 @@ void IRVestelAc::setMode(const uint8_t mode) { use_time_state = false; } -// Set Auto mode of AC. +/// Set Auto mode/level of the A/C. +/// @param[in] autoLevel The auto mode/level setting. void IRVestelAc::setAuto(const int8_t autoLevel) { if (autoLevel < -2 || autoLevel > 2) return; setMode(kVestelAcAuto); @@ -200,18 +208,23 @@ void IRVestelAc::setAuto(const int8_t autoLevel) { setTemp(17); } +/// Set the timer to be active on the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setTimerActive(const bool on) { setBit(&remote_time_state, kVestelAcTimerFlagOffset, on); use_time_state = true; } +/// Get if the Timer is active on the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::isTimerActive(void) { return GETBIT64(remote_time_state, kVestelAcTimerFlagOffset); } -// Set Timer option of AC. -// Valid time arguments are 0, 0.5, 1, 2, 3 and 5 hours (in min). 0 disables the -// timer. +/// Set Timer option of A/C. +/// @param[in] minutes Nr of minutes the timer is to be set for. +/// @note Valid arguments are 0, 0.5, 1, 2, 3 and 5 hours (in minutes). +/// 0 disables the timer. void IRVestelAc::setTimer(const uint16_t minutes) { // Clear both On & Off timers. remote_time_state &= ~((uint64_t)0xFFFF << kVestelAcOffTimeOffset); @@ -225,9 +238,12 @@ void IRVestelAc::setTimer(const uint16_t minutes) { use_time_state = true; } +/// Get the Timer time of A/C. +/// @return The number of minutes of time on the timer. uint16_t IRVestelAc::getTimer(void) { return getOffTimer(); } -// Set the AC's internal clock +/// Set the A/C's internal clock. +/// @param[in] minutes The time expressed in nr. of minutes past midnight. void IRVestelAc::setTime(const uint16_t minutes) { setBits(&remote_time_state, kVestelAcHourOffset, kVestelAcHourSize, minutes / 60); @@ -236,22 +252,30 @@ void IRVestelAc::setTime(const uint16_t minutes) { use_time_state = true; } +/// Get the A/C's internal clock's time. +/// @return The time expressed in nr. of minutes past midnight. uint16_t IRVestelAc::getTime(void) { return GETBITS64(remote_time_state, kVestelAcHourOffset, kVestelAcHourSize) * 60 + GETBITS64(remote_time_state, kVestelAcMinuteOffset, kVestelAcMinuteSize); } +/// Set the On timer to be active on the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setOnTimerActive(const bool on) { setBit(&remote_time_state, kVestelAcOnTimerFlagOffset, on); use_time_state = true; } +/// Get if the On Timer is active on the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::isOnTimerActive(void) { return GETBIT64(remote_time_state, kVestelAcOnTimerFlagOffset); } -// Set a given timer (via offset). Takes time in nr. of minutes. +/// Set a given timer time at a given bit offset. +/// @param[in] minutes Time in nr. of minutes. +/// @param[in] offset Nr. of bits offset from the start of the state. void IRVestelAc::_setTimer(const uint16_t minutes, const uint8_t offset) { setBits(&remote_time_state, offset, kVestelAcTimerSize, ((minutes / 60) << 3) + (minutes % 60) / 10); @@ -259,112 +283,129 @@ void IRVestelAc::_setTimer(const uint16_t minutes, const uint8_t offset) { use_time_state = true; } -// Get the number of mins a timer is set for. +/// Get the number of minutes a timer is set for. +/// @param[in] offset Nr. of bits offset from the start of the state. +/// @return The time expressed in nr. of minutes. uint16_t IRVestelAc::_getTimer(const uint8_t offset) { return GETBITS64(remote_time_state, offset + kVestelAcTimerMinsSize, kVestelAcTimerHourSize) * 60 + // Hrs GETBITS64(remote_time_state, offset, kVestelAcTimerMinsSize) * 10; // Min } -// Set AC's wake up time. Takes time in minute. + +/// Set the On timer time on the A/C. +/// @param[in] minutes Time in nr. of minutes. void IRVestelAc::setOnTimer(const uint16_t minutes) { setOnTimerActive(minutes); _setTimer(minutes, kVestelAcOnTimeOffset); } +/// Get the A/C's On Timer time. +/// @return The time expressed in nr. of minutes. uint16_t IRVestelAc::getOnTimer(void) { return _getTimer(kVestelAcOnTimeOffset); } +/// Set the Off timer to be active on the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setOffTimerActive(const bool on) { setBit(&remote_time_state, kVestelAcOffTimerFlagOffset, on); use_time_state = true; } +/// Get if the Off Timer is active on the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::isOffTimerActive(void) { return GETBIT64(remote_time_state, kVestelAcOffTimerFlagOffset); } -// Set AC's turn off time. Takes time in minute. +/// Set the Off timer time on the A/C. +/// @param[in] minutes Time in nr. of minutes. void IRVestelAc::setOffTimer(const uint16_t minutes) { setOffTimerActive(minutes); _setTimer(minutes, kVestelAcOffTimeOffset); } +/// Get the A/C's Off Timer time. +/// @return The time expressed in nr. of minutes. uint16_t IRVestelAc::getOffTimer(void) { return _getTimer(kVestelAcOffTimeOffset); } -// Set the Sleep state of the A/C. +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setSleep(const bool on) { setBits(&remote_state, kVestelAcTurboSleepOffset, kNibbleSize, on ? kVestelAcSleep : kVestelAcNormal); use_time_state = false; } -// Return the Sleep state of the A/C. +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getSleep(void) { return GETBITS64(remote_state, kVestelAcTurboSleepOffset, kNibbleSize) == kVestelAcSleep; } -// Set the Turbo state of the A/C. +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setTurbo(const bool on) { setBits(&remote_state, kVestelAcTurboSleepOffset, kNibbleSize, on ? kVestelAcTurbo : kVestelAcNormal); use_time_state = false; } -// Return the Turbo state of the A/C. +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getTurbo(void) { return GETBITS64(remote_state, kVestelAcTurboSleepOffset, kNibbleSize) == kVestelAcTurbo; } -// Set the Ion state of the A/C. +/// Set the Ion (Filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setIon(const bool on) { setBit(&remote_state, kVestelAcIonOffset, on); use_time_state = false; } -// Return the Ion state of the A/C. +/// Get the Ion (Filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getIon(void) { return GETBIT64(remote_state, kVestelAcIonOffset); } -// Set the Swing Roaming state of the A/C. +/// Set the Swing Roaming setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setSwing(const bool on) { setBits(&remote_state, kVestelAcSwingOffset, kNibbleSize, on ? kVestelAcSwing : 0xF); use_time_state = false; } -// Return the Swing Roaming state of the A/C. +/// Get the Swing Roaming setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getSwing(void) { return GETBITS64(remote_state, kVestelAcSwingOffset, kNibbleSize) == kVestelAcSwing; } -// Calculate the checksum for a given array. -// Args: -// state: The state to calculate the checksum over. -// Returns: -// The 8 bit checksum value. +/// Calculate the checksum for a given state. +/// @param[in] state The state to calc the checksum of. +/// @return The calculated checksum value. uint8_t IRVestelAc::calcChecksum(const uint64_t state) { // Just counts the set bits +1 on stream and take inverse after mask return 0xFF - countBits(GETBITS64(state, 20, 44), 44, true, 2); } -// Verify the checksum is valid for a given state. -// Args: -// state: The state to verify the checksum of. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRVestelAc::validChecksum(const uint64_t state) { return GETBITS64(state, kVestelAcChecksumOffset, kVestelAcChecksumSize) == IRVestelAc::calcChecksum(state); } -// Calculate & set the checksum for the current internal state of the remote. +/// Calculate & set the checksum for the current internal state of the remote. void IRVestelAc::checksum(void) { // Stored the checksum value in the last byte. setBits(&remote_state, kVestelAcChecksumOffset, kVestelAcChecksumSize, @@ -373,12 +414,16 @@ void IRVestelAc::checksum(void) { this->calcChecksum(remote_time_state)); } +/// Is the current state a time command? +/// @return true, if the state is a time message. Otherwise, false. bool IRVestelAc::isTimeCommand(void) { return !GETBITS64(remote_state, kVestelAcPowerOffset, kNibbleSize) || use_time_state; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRVestelAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kVestelAcCool; @@ -389,7 +434,9 @@ uint8_t IRVestelAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRVestelAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -401,7 +448,9 @@ uint8_t IRVestelAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRVestelAc::toCommonMode(const uint8_t mode) { switch (mode) { case kVestelAcCool: return stdAc::opmode_t::kCool; @@ -412,7 +461,9 @@ stdAc::opmode_t IRVestelAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRVestelAc::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kVestelAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -422,7 +473,8 @@ stdAc::fanspeed_t IRVestelAc::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRVestelAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::VESTEL_AC; @@ -448,7 +500,8 @@ stdAc::state_t IRVestelAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRVestelAc::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -508,19 +561,14 @@ String IRVestelAc::toString(void) { } #if DECODE_VESTEL_AC -// Decode the supplied Vestel message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kVestelBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Needs testing against a real device. -// +/// Decode the supplied Vestel message. +/// Status: Alpha / Needs testing against a real device. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeVestelAc(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (nbits % 8 != 0) // nbits has to be a multiple of nr. of bits in a byte. diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Vestel.h b/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.h similarity index 87% rename from lib/IRremoteESP8266-2.7.7/src/ir_Vestel.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Vestel.h index 5facdc278..b545a5a2f 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Vestel.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.h @@ -1,6 +1,10 @@ // Copyright 2018 Erdem U. Altinyurt // Copyright 2019 David Conran +/// @file +/// @brief Support for Vestel protocols. +/// Vestel added by Erdem U. Altinyurt + // Supports: // Brand: Vestel, Model: BIOX CXP-9 A/C (9K BTU) @@ -18,7 +22,6 @@ #include "IRsend_test.h" #endif -// Vestel added by Erdem U. Altinyurt // Structure of a Command message (56 bits) // Signature: 12 bits. e.g. 0x201 @@ -108,14 +111,19 @@ const uint8_t kVestelAcMinuteSize = 8; // Nr. of bits const uint64_t kVestelAcStateDefault = 0x0F00D9001FEF201ULL; const uint64_t kVestelAcTimeStateDefault = 0x201ULL; +// Classes +/// Class for handling detailed Vestel A/C messages. class IRVestelAc { public: explicit IRVestelAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_VESTEL_AC - void send(void); + void send(const uint16_t repeat = kNoRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_VESTEL_AC void begin(void); @@ -167,12 +175,14 @@ class IRVestelAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint64_t remote_state; - uint64_t remote_time_state; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint64_t remote_state; ///< The state of the IR remote in IR code form. + uint64_t remote_time_state; ///< The time state of the remote in code form. bool use_time_state; void checksum(void); void _setTimer(const uint16_t minutes, const uint8_t offset); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.cpp index 3ba781c4c..c04e32300 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.cpp @@ -1,18 +1,12 @@ // Copyright 2018 David Conran -// -// Code to emulate Whirlpool protocol compatible devices. -// Should be compatible with: -// * SPIS409L, SPIS412L, SPIW409L, SPIW412L, SPIW418L -// Remotes: -// * DG11J1-3A / DG11J1-04 -// * DG11J1-91 -// -// Note: Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. -// Advanced 6thSense, Dehumidify, & Sleep modes are not supported. -// FYI: -// Dim == !Light -// Jet == Super == Turbo -// + +/// @file +/// @brief Support for Whirlpool protocols. +/// Decoding help from: \@redmusicxd, \@josh929800, \@raducostea +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/509 +/// @note Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. +/// Advanced 6thSense, Dehumidify, & Sleep modes are not supported. +/// @note Dim == !Light, Jet == Super == Turbo #include "ir_Whirlpool.h" #include @@ -27,7 +21,6 @@ #include "IRutils.h" // Constants -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/509 const uint16_t kWhirlpoolAcHdrMark = 8950; const uint16_t kWhirlpoolAcHdrSpace = 4484; const uint16_t kWhirlpoolAcBitMark = 597; @@ -49,17 +42,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_WHIRLPOOL_AC -// Send a Whirlpool A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kWhirlpoolAcStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: BETA / Probably works. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/509 +/// Send a Whirlpool A/C message. +/// Status: BETA / Probably works. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendWhirlpoolAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kWhirlpoolAcStateLength) @@ -89,13 +76,16 @@ void IRsend::sendWhirlpoolAC(const unsigned char data[], const uint16_t nbytes, #endif // SEND_WHIRLPOOL_AC // Class for emulating a Whirlpool A/C remote. -// Decoding help from: -// @redmusicxd, @josh929800, @raducostea +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRWhirlpoolAc::IRWhirlpoolAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the state of the remote to a known good state/sequence. void IRWhirlpoolAc::stateReset(void) { for (uint8_t i = 2; i < kWhirlpoolAcStateLength; i++) remote_state[i] = 0x0; remote_state[0] = 0x83; @@ -104,9 +94,15 @@ void IRWhirlpoolAc::stateReset(void) { this->_setTemp(kWhirlpoolAcAutoTemp); // Default to a sane value. } +/// Set up hardware to be able to send a message. void IRWhirlpoolAc::begin(void) { _irsend.begin(); } -bool IRWhirlpoolAc::validChecksum(uint8_t state[], const uint16_t length) { +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. +bool IRWhirlpoolAc::validChecksum(const uint8_t state[], + const uint16_t length) { if (length > kWhirlpoolAcChecksumByte1 && state[kWhirlpoolAcChecksumByte1] != xorBytes(state + 2, kWhirlpoolAcChecksumByte1 - 1 - 2)) { @@ -124,7 +120,8 @@ bool IRWhirlpoolAc::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Update the checksum for the internal state. +/// Calculate & set the checksum for the current internal state of the remote. +/// @param[in] length The length/size of the internal state array. void IRWhirlpoolAc::checksum(uint16_t length) { if (length >= kWhirlpoolAcChecksumByte1) remote_state[kWhirlpoolAcChecksumByte1] = @@ -136,21 +133,32 @@ void IRWhirlpoolAc::checksum(uint16_t length) { } #if SEND_WHIRLPOOL_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @param[in] calcchecksum Do we need to calculate the checksum?. void IRWhirlpoolAc::send(const uint16_t repeat, const bool calcchecksum) { if (calcchecksum) this->checksum(); _irsend.sendWhirlpoolAC(remote_state, kWhirlpoolAcStateLength, repeat); } #endif // SEND_WHIRLPOOL_AC +/// Get a copy of the internal state/code for this protocol. +/// @param[in] calcchecksum Do we need to calculate the checksum?. +/// @return A code for this protocol based on the current internal state. uint8_t *IRWhirlpoolAc::getRaw(const bool calcchecksum) { if (calcchecksum) this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. void IRWhirlpoolAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kWhirlpoolAcStateLength)); } +/// Get/Detect the model of the A/C. +/// @return The enum of the compatible model. whirlpool_ac_remote_model_t IRWhirlpoolAc::getModel(void) { if (GETBIT8(remote_state[kWhirlpoolAcAltTempPos], kWhirlpoolAcAltTempOffset)) return DG11J191; @@ -158,6 +166,8 @@ whirlpool_ac_remote_model_t IRWhirlpoolAc::getModel(void) { return DG11J13A; } +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRWhirlpoolAc::setModel(const whirlpool_ac_remote_model_t model) { switch (model) { case DG11J191: @@ -172,7 +182,8 @@ void IRWhirlpoolAc::setModel(const whirlpool_ac_remote_model_t model) { this->_setTemp(_desiredtemp); // Different models have different temp values. } -// Return the temp. offset in deg C for the current model. +/// Calculate the temp. offset in deg C for the current model. +/// @return The temperature offset. int8_t IRWhirlpoolAc::getTempOffset(void) { switch (this->getModel()) { case whirlpool_ac_remote_model_t::DG11J191: return -2; @@ -180,7 +191,10 @@ int8_t IRWhirlpoolAc::getTempOffset(void) { } } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. +/// @param[in] remember Do we save this temperature? +/// @note Internal use only. void IRWhirlpoolAc::_setTemp(const uint8_t temp, const bool remember) { if (remember) _desiredtemp = temp; int8_t offset = this->getTempOffset(); // Cache the min temp for the model. @@ -190,19 +204,24 @@ void IRWhirlpoolAc::_setTemp(const uint8_t temp, const bool remember) { newtemp - (kWhirlpoolAcMinTemp + offset)); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRWhirlpoolAc::setTemp(const uint8_t temp) { this->_setTemp(temp); this->setSuper(false); // Changing temp cancels Super/Jet mode. this->setCommand(kWhirlpoolAcCommandTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRWhirlpoolAc::getTemp(void) { return GETBITS8(remote_state[kWhirlpoolAcTempPos], kHighNibble, kNibbleSize) + kWhirlpoolAcMinTemp + this->getTempOffset(); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @note Internal use only. void IRWhirlpoolAc::_setMode(const uint8_t mode) { switch (mode) { case kWhirlpoolAcAuto: @@ -224,16 +243,22 @@ void IRWhirlpoolAc::_setMode(const uint8_t mode) { if (mode == kWhirlpoolAcAuto) this->setCommand(kWhirlpoolAcCommand6thSense); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRWhirlpoolAc::setMode(const uint8_t mode) { this->setSuper(false); // Changing mode cancels Super/Jet mode. this->_setMode(mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRWhirlpoolAc::getMode(void) { return GETBITS8(remote_state[kWhirlpoolAcModePos], kWhirlpoolAcModeOffset, kModeBitsSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRWhirlpoolAc::setFan(const uint8_t speed) { switch (speed) { case kWhirlpoolAcFanAuto: @@ -248,32 +273,45 @@ void IRWhirlpoolAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRWhirlpoolAc::getFan(void) { return GETBITS8(remote_state[kWhirlpoolAcFanPos], kWhirlpoolAcFanOffset, kWhirlpoolAcFanSize); } +/// Set the (vertical) swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setSwing(const bool on) { setBit(&remote_state[kWhirlpoolAcFanPos], kWhirlpoolAcSwing1Offset, on); setBit(&remote_state[kWhirlpoolAcOffTimerPos], kWhirlpoolAcSwing2Offset, on); setCommand(kWhirlpoolAcCommandSwing); } +/// Get the (vertical) swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getSwing(void) { return GETBIT8(remote_state[kWhirlpoolAcFanPos], kWhirlpoolAcSwing1Offset) && GETBIT8(remote_state[kWhirlpoolAcOffTimerPos], kWhirlpoolAcSwing2Offset); } +/// Set the Light (Display/LED) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setLight(const bool on) { // Cleared when on. setBit(&remote_state[kWhirlpoolAcClockPos], kWhirlpoolAcLightOffset, !on); } +/// Get the Light (Display/LED) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getLight(void) { return !GETBIT8(remote_state[kWhirlpoolAcClockPos], kWhirlpoolAcLightOffset); } +/// Set the time in nr. of minutes past midnight. +/// @param[in] pos The byte offset to write to. +/// @param[in] minspastmidnight Nr. of minutes past midnight. void IRWhirlpoolAc::setTime(const uint16_t pos, const uint16_t minspastmidnight) { // Hours @@ -284,6 +322,9 @@ void IRWhirlpoolAc::setTime(const uint16_t pos, kWhirlpoolAcMinuteSize, minspastmidnight % 60); } +/// Get the time in nr. of minutes past midnight. +/// @param[in] pos The byte offset to read from. +/// @return The time in Nr. of minutes past midnight. uint16_t IRWhirlpoolAc::getTime(const uint16_t pos) { return GETBITS8(remote_state[pos], kWhirlpoolAcHourOffset, kWhirlpoolAcHourSize) * 60 + @@ -291,56 +332,84 @@ uint16_t IRWhirlpoolAc::getTime(const uint16_t pos) { kWhirlpoolAcMinuteSize); } +/// Is the timer enabled at the given byte offset? +/// @param[in] pos The byte offset to read from. +/// @return true, the Timer is on. false, the Timer is off. bool IRWhirlpoolAc::isTimerEnabled(const uint16_t pos) { return GETBIT8(remote_state[pos - 1], kWhirlpoolAcTimerEnableOffset); } +/// Enable the timer enabled at the given byte offset. +/// @param[in] pos The byte offset to write to. +/// @param[in] on true, the timer is enabled. false, the timer is disabled. void IRWhirlpoolAc::enableTimer(const uint16_t pos, const bool on) { setBit(&remote_state[pos - 1], kWhirlpoolAcTimerEnableOffset, on); } +/// Set the clock time in nr. of minutes past midnight. +/// @param[in] minspastmidnight The time expressed as minutes past midnight. void IRWhirlpoolAc::setClock(const uint16_t minspastmidnight) { this->setTime(kWhirlpoolAcClockPos, minspastmidnight); } +/// Get the clock time in nr. of minutes past midnight. +/// @return The time expressed as the Nr. of minutes past midnight. uint16_t IRWhirlpoolAc::getClock(void) { return this->getTime(kWhirlpoolAcClockPos); } +/// Set the Off Timer time. +/// @param[in] minspastmidnight The time expressed as minutes past midnight. void IRWhirlpoolAc::setOffTimer(const uint16_t minspastmidnight) { this->setTime(kWhirlpoolAcOffTimerPos, minspastmidnight); } +/// Get the Off Timer time.. +/// @return The time expressed as the Nr. of minutes past midnight. uint16_t IRWhirlpoolAc::getOffTimer(void) { return this->getTime(kWhirlpoolAcOffTimerPos); } +/// Is the Off timer enabled? +/// @return true, the Timer is enabled. false, the Timer is disabled. bool IRWhirlpoolAc::isOffTimerEnabled(void) { return this->isTimerEnabled(kWhirlpoolAcOffTimerPos); } +/// Enable the Off Timer. +/// @param[in] on true, the timer is enabled. false, the timer is disabled. void IRWhirlpoolAc::enableOffTimer(const bool on) { this->enableTimer(kWhirlpoolAcOffTimerPos, on); this->setCommand(kWhirlpoolAcCommandOffTimer); } +/// Set the On Timer time. +/// @param[in] minspastmidnight The time expressed as minutes past midnight. void IRWhirlpoolAc::setOnTimer(const uint16_t minspastmidnight) { this->setTime(kWhirlpoolAcOnTimerPos, minspastmidnight); } +/// Get the On Timer time.. +/// @return The time expressed as the Nr. of minutes past midnight. uint16_t IRWhirlpoolAc::getOnTimer(void) { return this->getTime(kWhirlpoolAcOnTimerPos); } +/// Is the On timer enabled? +/// @return true, the Timer is enabled. false, the Timer is disabled. bool IRWhirlpoolAc::isOnTimerEnabled(void) { return this->isTimerEnabled(kWhirlpoolAcOnTimerPos); } +/// Enable the On Timer. +/// @param[in] on true, the timer is enabled. false, the timer is disabled. void IRWhirlpoolAc::enableOnTimer(const bool on) { this->enableTimer(kWhirlpoolAcOnTimerPos, on); this->setCommand(kWhirlpoolAcCommandOnTimer); } +/// Change the power toggle setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setPowerToggle(const bool on) { setBit(&remote_state[kWhirlpoolAcPowerTogglePos], kWhirlpoolAcPowerToggleOffset, on); @@ -348,15 +417,21 @@ void IRWhirlpoolAc::setPowerToggle(const bool on) { this->setCommand(kWhirlpoolAcCommandPower); } +/// Get the value of the current power toggle setting. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getPowerToggle(void) { return GETBIT8(remote_state[kWhirlpoolAcPowerTogglePos], kWhirlpoolAcPowerToggleOffset); } +/// Get the Command (Button) setting of the A/C. +/// @return The current Command (Button) of the A/C. uint8_t IRWhirlpoolAc::getCommand(void) { return remote_state[kWhirlpoolAcCommandPos]; } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setSleep(const bool on) { setBit(&remote_state[kWhirlpoolAcSleepPos], kWhirlpoolAcSleepOffset, on); @@ -364,11 +439,14 @@ void IRWhirlpoolAc::setSleep(const bool on) { this->setCommand(kWhirlpoolAcCommandSleep); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getSleep(void) { return GETBIT8(remote_state[kWhirlpoolAcSleepPos], kWhirlpoolAcSleepOffset); } -// AKA Jet/Turbo mode. +/// Set the Super (Turbo/Jet) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setSuper(const bool on) { if (on) { this->setFan(kWhirlpoolAcFanHigh); @@ -389,15 +467,21 @@ void IRWhirlpoolAc::setSuper(const bool on) { this->setCommand(kWhirlpoolAcCommandSuper); } +/// Get the Super (Turbo/Jet) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getSuper(void) { return remote_state[kWhirlpoolAcSuperPos] & kWhirlpoolAcSuperMask; } +/// Set the Command (Button) setting of the A/C. +/// @param[in] code The current Command (Button) of the A/C. void IRWhirlpoolAc::setCommand(const uint8_t code) { remote_state[kWhirlpoolAcCommandPos] = code; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRWhirlpoolAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kWhirlpoolAcCool; @@ -408,7 +492,9 @@ uint8_t IRWhirlpoolAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRWhirlpoolAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -420,7 +506,9 @@ uint8_t IRWhirlpoolAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRWhirlpoolAc::toCommonMode(const uint8_t mode) { switch (mode) { case kWhirlpoolAcCool: return stdAc::opmode_t::kCool; @@ -431,7 +519,9 @@ stdAc::opmode_t IRWhirlpoolAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRWhirlpoolAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kWhirlpoolAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -441,7 +531,8 @@ stdAc::fanspeed_t IRWhirlpoolAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRWhirlpoolAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::WHIRLPOOL_AC; @@ -467,7 +558,8 @@ stdAc::state_t IRWhirlpoolAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRWhirlpoolAc::toString(void) { String result = ""; result.reserve(200); // Reserve some heap for the string to reduce fragging. @@ -538,22 +630,15 @@ String IRWhirlpoolAc::toString(void) { } #if DECODE_WHIRLPOOL_AC -// Decode the supplied Whirlpool A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kWhirlpoolAcBits -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working as intended. -// -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/509 + +/// Decode the supplied Whirlpool A/C message. +/// Status: STABLE / Working as intended. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeWhirlpoolAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * nbits + 4 + kHeader + kFooter - 1 + offset) diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.h b/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.h similarity index 83% rename from lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.h index d0cf95bef..3fd4e86dd 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Whirlpool.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.h @@ -1,7 +1,13 @@ -// Whirlpool A/C -// // Copyright 2018 David Conran +/// @file +/// @brief Support for Whirlpool protocols. +/// Decoding help from: \@redmusicxd, \@josh929800, \@raducostea +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/509 +/// @note Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. +/// Advanced 6thSense, Dehumidify, & Sleep modes are not supported. +/// @note Dim == !Light, Jet == Super == Turbo + // Supports: // Brand: Whirlpool, Model: DG11J1-3A remote // Brand: Whirlpool, Model: DG11J1-04 remote @@ -26,9 +32,6 @@ #include "IRsend_test.h" #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/509 - // Constants const uint8_t kWhirlpoolAcChecksumByte1 = 13; const uint8_t kWhirlpoolAcChecksumByte2 = kWhirlpoolAcStateLength - 1; @@ -84,20 +87,22 @@ const uint8_t kWhirlpoolAcAltTempOffset = 3; const uint8_t kWhirlpoolAcAltTempPos = 18; // Classes +/// Class for handling detailed Whirlpool A/C messages. class IRWhirlpoolAc { public: explicit IRWhirlpoolAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_WHIRLPOOL_AC void send(const uint16_t repeat = kWhirlpoolAcDefaultRepeat, const bool calcchecksum = true); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. int8_t calibrate(void) { return _irsend.calibrate(); } #endif // SEND_WHIRLPOOL_AC void begin(void); - void on(void); - void off(void); void setPowerToggle(const bool on); bool getPowerToggle(void); void setSleep(const bool on); @@ -131,7 +136,7 @@ class IRWhirlpoolAc { uint8_t* getRaw(const bool calcchecksum = true); void setRaw(const uint8_t new_code[], const uint16_t length = kWhirlpoolAcStateLength); - static bool validChecksum(uint8_t state[], + static bool validChecksum(const uint8_t state[], const uint16_t length = kWhirlpoolAcStateLength); uint8_t convertMode(const stdAc::opmode_t mode); uint8_t convertFan(const stdAc::fanspeed_t speed); @@ -142,13 +147,14 @@ class IRWhirlpoolAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kWhirlpoolAcStateLength]; - uint8_t _desiredtemp; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kWhirlpoolAcStateLength]; ///< The state in IR code form + uint8_t _desiredtemp; ///< The last user explicitly set temperature. void checksum(const uint16_t length = kWhirlpoolAcStateLength); uint16_t getTime(const uint16_t pos); void setTime(const uint16_t pos, const uint16_t minspastmidnight); diff --git a/lib/IRremoteESP8266-2.7.7/src/ir_Whynter.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Whynter.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.7/src/ir_Whynter.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Whynter.cpp index 92bad25ce..7b184eb0b 100644 --- a/lib/IRremoteESP8266-2.7.7/src/ir_Whynter.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Whynter.cpp @@ -1,8 +1,10 @@ // Copyright 2009 Ken Shirriff // Copyright 2017 David Conran -// Whynter A/C ARC-110WD added by Francesco Meschia -// Whynter originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @file +/// @brief Support for Whynter protocols. +/// Whynter A/C ARC-110WD added by Francesco Meschia +/// Whynter originally added from https://github.com/shirriff/Arduino-IRremote/ // Supports: // Brand: Whynter, Model: ARC-110WD A/C @@ -13,7 +15,6 @@ #include "IRutils.h" // Constants - const uint16_t kWhynterTick = 50; const uint16_t kWhynterHdrMarkTicks = 57; const uint16_t kWhynterHdrMark = kWhynterHdrMarkTicks * kWhynterTick; @@ -35,18 +36,14 @@ const uint16_t kWhynterMinGapTicks = const uint16_t kWhynterMinGap = kWhynterMinGapTicks * kWhynterTick; #if SEND_WHYNTER -// Send a Whynter message. -// -// Args: -// data: message to be sent. -// nbits: Nr. of bits of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE -// -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp -void IRsend::sendWhynter(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a Whynter message. +/// Status: STABLE +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp +void IRsend::sendWhynter(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { // Set IR carrier frequency enableIROut(38); @@ -62,24 +59,18 @@ void IRsend::sendWhynter(uint64_t data, uint16_t nbits, uint16_t repeat) { 50); } } -#endif +#endif // SEND_WHYNTER #if DECODE_WHYNTER -// Decode the supplied Whynter message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. Strict mode is ALPHA. -// -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp +/// Decode the supplied Whynter message. +/// Status: STABLE / Working. Strict mode is ALPHA. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp bool IRrecv::decodeWhynter(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + 2 * kHeader + kFooter - 1 + offset) @@ -109,4 +100,4 @@ bool IRrecv::decodeWhynter(decode_results *results, uint16_t offset, results->command = 0; return true; } -#endif +#endif // DECODE_WHYNTER diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp new file mode 100644 index 000000000..96017226c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp @@ -0,0 +1,94 @@ +// Copyright 2020 Christian Nilsson (nikize) + +/// @file +/// @brief Support for Zepeal protocol. +/// This protocol uses fixed length bit encoding. +/// Most official information about Zepeal seems to be from Denkyosha +/// @see https://www.denkyosha.co.jp/ + +// Supports: +// Brand: Zepeal, Model: DRT-A3311(BG) floor fan +// Brand: Zepeal, Model: DRT-A3311(BG) 5 button remote + +#include "IRrecv.h" +#include "IRsend.h" +#include "IRutils.h" + +// Constants + +const uint16_t kZepealHdrMark = 2330; +const uint16_t kZepealHdrSpace = 3380; +const uint16_t kZepealOneMark = 1300; +const uint16_t kZepealZeroMark = 420; +const uint16_t kZepealOneSpace = kZepealZeroMark; +const uint16_t kZepealZeroSpace = kZepealOneMark; +const uint16_t kZepealFooterMark = 420; +const uint16_t kZepealGap = 6750; + +const uint8_t kZepealTolerance = 40; + +// Signature limits possible false possitvies, +// but might need change (removal) if more devices are detected +const uint8_t kZepealSignature = 0x6C; + +// Known Zepeal DRT-A3311(BG) Buttons - documentation rather than actual usage +const uint16_t kZepealCommandSpeed = 0x6C82; +const uint16_t kZepealCommandOffOn = 0x6C81; +const uint16_t kZepealCommandRhythm = 0x6C84; +const uint16_t kZepealCommandOffTimer = 0x6C88; +const uint16_t kZepealCommandOnTimer = 0x6CC3; + +#if SEND_ZEPEAL +/// Send a Zepeal formatted message. +/// Status: STABLE / Works on real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The bit size of the message being sent. +/// @param[in] repeat The number of times the message is to be repeated. +void IRsend::sendZepeal(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kZepealHdrMark, kZepealHdrSpace, + kZepealOneMark, kZepealOneSpace, + kZepealZeroMark, kZepealZeroSpace, + kZepealFooterMark, kZepealGap, + data, nbits, 38, true, repeat, kDutyDefault); +} +#endif // SEND_ZEPEAL + +#if DECODE_ZEPEAL +/// Decode the supplied Zepeal message. +/// Status: STABLE / Works on real device. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// result. +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. Typically kZepealBits. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +bool IRrecv::decodeZepeal(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid message. + if (strict && nbits != kZepealBits) + return false; // Not strictly a message. + + uint64_t data = 0; + uint16_t used; + used = matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kZepealHdrMark, kZepealHdrSpace, + kZepealOneMark, kZepealOneSpace, + kZepealZeroMark, kZepealZeroSpace, + kZepealFooterMark, kZepealGap, true, + kZepealTolerance); + if (!used) return false; + if (strict && (data >> 8) != kZepealSignature) return false; + + // Success + results->value = data; + results->decode_type = decode_type_t::ZEPEAL; + results->bits = nbits; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_ZEPEAL diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/README.md b/lib/IRremoteESP8266-2.7.8/src/locale/README.md similarity index 68% rename from lib/IRremoteESP8266-2.7.7/src/locale/README.md rename to lib/IRremoteESP8266-2.7.8/src/locale/README.md index 6b55571bf..b8689f34a 100644 --- a/lib/IRremoteESP8266-2.7.7/src/locale/README.md +++ b/lib/IRremoteESP8266-2.7.8/src/locale/README.md @@ -10,7 +10,7 @@ There is _no_ runtime option to change locales. ### Change `_IR_LOCALE_` in the `src/IRremoteESP8266.h` file. In the [IRremoteESP8266.h](../IRremoteESP8266.h#L57-L59) file, find and locate the lines that look like: -``` +```c++ #ifndef _IR_LOCALE_ #define _IR_LOCALE_ en-AU #endif // _IR_LOCALE_ @@ -52,19 +52,19 @@ e.g. `en` is English. `de` is German etc. and `YY` is the ISO country code. e.g. Modify the comments and all `LOCALE_EN_AU_H_`s in the file to `LOCALE_XX_YY_H_` for your locale. -### Override any `#define` values that reside in `defaults.h` -Go through the [defaults.h](defaults.h) file, and find any `#define` lines that define a macro starting with `D_` that has text +### Override any `#‍define` values that reside in `defaults.h` +Go through the [defaults.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/defaults.h) file, and find any `#‍define` lines that define a macro starting with `D_` that has text that needs to change for your locale. -Copy or create a corresponding `#define D_STR_HELLOWORLD "Hello World"` in your `xx-YY.h` file, and translate the text appropriately -e.g. `#define D_STR_HELLOWORLD "Bonjour le monde"` (French) +Copy or create a corresponding `#‍define D_STR_HELLOWORLD "Hello World"` in your `xx-YY.h` file, and translate the text appropriately +e.g. `#‍define D_STR_HELLOWORLD "Bonjour le monde"` (French) -Any values you `#define` in `xx-YY.h` will override the corresponding value in the [defaults.h](defaults.h) file. +Any values you `#‍define` in `xx-YY.h` will override the corresponding value in the [defaults.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/defaults.h) file. -### Supporting a dialect/regional varient of another _existing_ language/locale. +### Supporting a dialect/regional variant of another _existing_ language/locale. Similar to the previous step, if you only need to modify a small subset of the strings used in another locale file, then include the -other locale file and then make sure to `#undef` any strings that need to be (re-)changed. -See the [Swiss-German](de-CH.h) for an example of how to do this. i.e. It `#include "locale/de-DE.h"`s the German locale, and -redefines any strings that are not standard [German](de-DE.h). +other locale file and then make sure to `#‍undef` any strings that need to be (re-)changed. +See the [Swiss-German](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/de-CH.h) for an example of how to do this. i.e. It `#‍include "locale/de-DE.h"`s the German locale, and +redefines any strings that are not standard [German](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/de-DE.h). ## Adding new text strings to the library. If you need to add an entirely new string to the library to support some feature etc. e.g. _"Widget"_. @@ -72,26 +72,26 @@ You should first understand how the library tries to do this such that it is eas 1. Use a constant named `kWidgetStr` in the appropriate statement in the `.cpp` file. 2. Edit [IRtext.cpp](IRtext.cpp), and add the appropriate line for your new constant. e.g. -``` +```c++ String kWidgetStr = D_STR_WIDGET; ``` The `kWidgetStr` variable will house the sole copy of the string for the entire library. This limits any duplication. The `D_STR_WIDGET` macro will be what is targeted by the different language / locales files. -3. Edit [locale/defaults.h](defaults.h), and add the appropriate stanza for your new string. e.g. -``` +3. Edit [locale/defaults.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/defaults.h), and add the appropriate stanza for your new string. e.g. +```c++ #ifndef D_STR_WIDGET #define D_STR_WIDGET "Turbo" #endif // D_STR_WIDGET ``` -4. _(Manual)_ Update [IRtext.h](../IRtext.h), and add the appropriate line for your new constant. e.g. -``` +4. _(Manual)_ Update [IRtext.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRtext.h), and add the appropriate line for your new constant. e.g. +```c++ extern const String kWidgetStr; ``` -For any file that `#include `s this file, it will tell it that the string is stored elsewhere, +For any file that `#‍include `s this file, it will tell it that the string is stored elsewhere, and to look for it elsewhere at the object linking stage of the build. This is what makes the string be referenced from a central location. -4. _(Automatic)_ Run `tools/generate_irtext_h.sh` to update [IRtext.h](../IRtext.h). -In the [src/locale](../locale) directory. Run the `../../tools/generate_irtext_h.sh` command. It will update the file for you automatically. +4. _(Automatic)_ Run `tools/generate_irtext_h.sh` to update [IRtext.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRtext.h). +In the [src/locale](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/) directory. Run the `../../tools/generate_irtext_h.sh` command. It will update the file for you automatically. diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/de-CH.h b/lib/IRremoteESP8266-2.7.8/src/locale/de-CH.h similarity index 98% rename from lib/IRremoteESP8266-2.7.7/src/locale/de-CH.h rename to lib/IRremoteESP8266-2.7.8/src/locale/de-CH.h index 2c34ca97b..875ffd394 100644 --- a/lib/IRremoteESP8266-2.7.7/src/locale/de-CH.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/de-CH.h @@ -143,12 +143,12 @@ #undef D_STR_REPEAT #define D_STR_REPEAT "Wiederhole" -// IRrecvDumpV2 +// IRrecvDumpV2+ #undef D_STR_TIMESTAMP #define D_STR_TIMESTAMP "Ziitstämpfel" #undef D_STR_IRRECVDUMP_STARTUP #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 lauft und wartet uf IR Iigab ufem Pin %d" + "IRrecvDump lauft und wartet uf IR Iigab ufem Pin %d" #undef D_WARN_BUFFERFULL #define D_WARN_BUFFERFULL \ "WARNUNG: IR Code isch zgross für de Buffer (>= %d). " \ diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/de-DE.h b/lib/IRremoteESP8266-2.7.8/src/locale/de-DE.h similarity index 97% rename from lib/IRremoteESP8266-2.7.7/src/locale/de-DE.h rename to lib/IRremoteESP8266-2.7.8/src/locale/de-DE.h index f366936b0..70ebc4854 100644 --- a/lib/IRremoteESP8266-2.7.7/src/locale/de-DE.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/de-DE.h @@ -112,12 +112,12 @@ #define D_STR_REPEAT "Wiederholen" -// IRrecvDumpV2 +// IRrecvDumpV2+ #define D_STR_TIMESTAMP "Zeitstempel" #define D_STR_LIBRARY "Bibliothek" #define D_STR_MESGDESC "Nachr. Beschr." #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 läuft und wartet auf IR Eingabe auf Pin %d" + "IRrecvDump läuft und wartet auf IR Eingabe auf Pin %d" #define D_WARN_BUFFERFULL \ "WARNUNG: IR Code ist zu gross für Buffer (>= %d). " \ "Dem Resultat sollte nicht vertraut werden bevor das behoben ist. " \ diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/defaults.h b/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h similarity index 97% rename from lib/IRremoteESP8266-2.7.7/src/locale/defaults.h rename to lib/IRremoteESP8266-2.7.8/src/locale/defaults.h index 5df78f7b9..340e2b8fe 100644 --- a/lib/IRremoteESP8266-2.7.7/src/locale/defaults.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h @@ -372,6 +372,9 @@ #ifndef D_STR_POWERTOGGLE #define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE #endif // D_STR_POWERTOGGLE +#ifndef D_STR_POWERBUTTON +#define D_STR_POWERBUTTON D_STR_POWER " " D_STR_BUTTON +#endif // D_STR_POWERBUTTON #ifndef D_STR_PREVIOUSPOWER #define D_STR_PREVIOUSPOWER D_STR_PREVIOUS " " D_STR_POWER #endif // D_STR_PREVIOUSPOWER @@ -484,6 +487,9 @@ #ifndef D_STR_COOLIX #define D_STR_COOLIX "COOLIX" #endif // D_STR_COOLIX +#ifndef D_STR_CORONA_AC +#define D_STR_CORONA_AC "CORONA_AC" +#endif // D_STR_CORONA_AC #ifndef D_STR_DAIKIN #define D_STR_DAIKIN "DAIKIN" #endif // D_STR_DAIKIN @@ -559,6 +565,9 @@ #ifndef D_STR_HITACHI_AC3 #define D_STR_HITACHI_AC3 "HITACHI_AC3" #endif // D_STR_HITACHI_AC3 +#ifndef D_STR_HITACHI_AC344 +#define D_STR_HITACHI_AC344 "HITACHI_AC344" +#endif // D_STR_HITACHI_AC344 #ifndef D_STR_HITACHI_AC424 #define D_STR_HITACHI_AC424 "HITACHI_AC424" #endif // D_STR_HITACHI_AC424 @@ -592,6 +601,9 @@ #ifndef D_STR_MIDEA #define D_STR_MIDEA "MIDEA" #endif // D_STR_MIDEA +#ifndef D_STR_MIDEA24 +#define D_STR_MIDEA24 "MIDEA24" +#endif // D_STR_MIDEA24 #ifndef D_STR_MITSUBISHI #define D_STR_MITSUBISHI "MITSUBISHI" #endif // D_STR_MITSUBISHI @@ -718,8 +730,11 @@ #ifndef D_STR_WHYNTER #define D_STR_WHYNTER "WHYNTER" #endif // D_STR_WHYNTER +#ifndef D_STR_ZEPEAL +#define D_STR_ZEPEAL "ZEPEAL" +#endif // D_STR_ZEPEAL -// IRrecvDumpV2 +// IRrecvDumpV2+ #ifndef D_STR_TIMESTAMP #define D_STR_TIMESTAMP "Timestamp" #endif // D_STR_TIMESTAMP @@ -731,7 +746,7 @@ #endif // D_STR_MESGDESC #ifndef D_STR_IRRECVDUMP_STARTUP #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 is now running and waiting for IR input on Pin %d" + "IRrecvDump is now running and waiting for IR input on Pin %d" #endif // D_STR_IRRECVDUMP_STARTUP #ifndef D_WARN_BUFFERFULL #define D_WARN_BUFFERFULL \ diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/en-AU.h b/lib/IRremoteESP8266-2.7.8/src/locale/en-AU.h similarity index 100% rename from lib/IRremoteESP8266-2.7.7/src/locale/en-AU.h rename to lib/IRremoteESP8266-2.7.8/src/locale/en-AU.h diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/en-IE.h b/lib/IRremoteESP8266-2.7.8/src/locale/en-IE.h similarity index 100% rename from lib/IRremoteESP8266-2.7.7/src/locale/en-IE.h rename to lib/IRremoteESP8266-2.7.8/src/locale/en-IE.h diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/en-UK.h b/lib/IRremoteESP8266-2.7.8/src/locale/en-UK.h similarity index 100% rename from lib/IRremoteESP8266-2.7.7/src/locale/en-UK.h rename to lib/IRremoteESP8266-2.7.8/src/locale/en-UK.h diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/en-US.h b/lib/IRremoteESP8266-2.7.8/src/locale/en-US.h similarity index 100% rename from lib/IRremoteESP8266-2.7.7/src/locale/en-US.h rename to lib/IRremoteESP8266-2.7.8/src/locale/en-US.h diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/es-ES.h b/lib/IRremoteESP8266-2.7.8/src/locale/es-ES.h similarity index 97% rename from lib/IRremoteESP8266-2.7.7/src/locale/es-ES.h rename to lib/IRremoteESP8266-2.7.8/src/locale/es-ES.h index 52f22333d..e8e54e5b2 100644 --- a/lib/IRremoteESP8266-2.7.7/src/locale/es-ES.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/es-ES.h @@ -121,11 +121,11 @@ #define D_STR_REPEAT "Repetir" #define D_STR_CODE "Codigo" -// IRrecvDumpV2 +// IRrecvDumpV2+ #define D_STR_TIMESTAMP "marca de tiempo" #define D_STR_LIBRARY "Libreria" #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 esta ahora corriendo y esperando por comando IR en Pin %d" + "IRrecvDump esta ahora corriendo y esperando por comando IR en Pin %d" #ifndef D_WARN_BUFFERFULL #define D_WARN_BUFFERFULL \ "WARNING: Codigo IR es muy grande para el buffer (>= %d). "\ diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/fr-FR.h b/lib/IRremoteESP8266-2.7.8/src/locale/fr-FR.h similarity index 97% rename from lib/IRremoteESP8266-2.7.7/src/locale/fr-FR.h rename to lib/IRremoteESP8266-2.7.8/src/locale/fr-FR.h index 0eae39e2e..f8c2f8235 100644 --- a/lib/IRremoteESP8266-2.7.7/src/locale/fr-FR.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/fr-FR.h @@ -103,12 +103,12 @@ #define D_STR_REPEAT "Répetition" -// IRrecvDumpV2 +// IRrecvDumpV2+ #define D_STR_TIMESTAMP "Horodatage" #define D_STR_LIBRARY "Bibliothèque" #define D_STR_MESGDESC "Rèférence" #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 fonctionne et attend l’entrée IR sur la broche %d" + "IRrecvDump fonctionne et attend l’entrée IR sur la broche %d" #define D_WARN_BUFFERFULL \ "ATTENTION: IR Code est trop gros pour le buffer (>= %d). " \ "Le résultat ne doit pas être approuvé avant que cela soit résolu. " \ diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/it-IT.h b/lib/IRremoteESP8266-2.7.8/src/locale/it-IT.h similarity index 98% rename from lib/IRremoteESP8266-2.7.7/src/locale/it-IT.h rename to lib/IRremoteESP8266-2.7.8/src/locale/it-IT.h index b04a129d2..9457b6e40 100644 --- a/lib/IRremoteESP8266-2.7.7/src/locale/it-IT.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/it-IT.h @@ -141,12 +141,12 @@ #define D_STR_REPEAT "Ripeti" #define D_STR_CODE "Codice" #define D_STR_BITS "Bit" -// IRrecvDumpV2 +// IRrecvDumpV2+ #define D_STR_LIBRARY "Libreria" #define D_STR_MESGDESC "Desc. Mess." #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 è ora attivo e in attesa di segnali IR dal pin %d" + "IRrecvDump è ora attivo e in attesa di segnali IR dal pin %d" #ifndef D_WARN_BUFFERFULL #define D_WARN_BUFFERFULL \ diff --git a/lib/IRremoteESP8266-2.7.7/src/locale/zh-CN.h b/lib/IRremoteESP8266-2.7.8/src/locale/zh-CN.h similarity index 99% rename from lib/IRremoteESP8266-2.7.7/src/locale/zh-CN.h rename to lib/IRremoteESP8266-2.7.8/src/locale/zh-CN.h index bcb30392c..5330c93e3 100644 --- a/lib/IRremoteESP8266-2.7.7/src/locale/zh-CN.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/zh-CN.h @@ -416,7 +416,7 @@ #ifndef D_STR_THREELETTERDAYS #define D_STR_THREELETTERDAYS "周一至周末" #endif // D_STR_THREELETTERDAYS -*/ +*/ #ifndef D_STR_YES #define D_STR_YES "是" @@ -441,7 +441,7 @@ #define D_STR_BITS "ä½" #endif // D_STR_BITS -// IRrecvDumpV2 +// IRrecvDumpV2+ #ifndef D_STR_TIMESTAMP #define D_STR_TIMESTAMP "时间戳记" #endif // D_STR_TIMESTAMP @@ -453,7 +453,7 @@ #endif // D_STR_MESGDESC #ifndef D_STR_IRRECVDUMP_STARTUP #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 è¿è¡Œå½“中,等待红外信æ¯è¾“å…¥ä½äºŽå¼•脚 %d" + "IRrecvDump è¿è¡Œå½“中,等待红外信æ¯è¾“å…¥ä½äºŽå¼•脚 %d" #endif // D_STR_IRRECVDUMP_STARTUP #ifndef D_WARN_BUFFERFULL #define D_WARN_BUFFERFULL \ diff --git a/lib/IRremoteESP8266-2.7.7/test/IRac_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp similarity index 93% rename from lib/IRremoteESP8266-2.7.7/test/IRac_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp index 93b8a73cb..a0f975666 100644 --- a/lib/IRremoteESP8266-2.7.7/test/IRac_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp @@ -3,6 +3,9 @@ #include #include "ir_Amcor.h" #include "ir_Argo.h" +#include "ir_Carrier.h" +#include "ir_Coolix.h" +#include "ir_Corona.h" #include "ir_Daikin.h" #include "ir_Delonghi.h" #include "ir_Electra.h" @@ -80,6 +83,40 @@ TEST(TestIRac, Argo) { EXPECT_FALSE(ac.getNight()); // Sleep } +TEST(TestIRac, Carrier64) { + IRCarrierAc64 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + + char expected[] = + "Power: On, Mode: 1 (Heat), Temp: 21C, Fan: 3 (High), Swing(V): On, " + "Sleep: On, On Timer: Off, Off Timer: Off"; + + ac.begin(); + irac.carrier64(&ac, + true, // Power + stdAc::opmode_t::kHeat, // Mode + 21, // Celsius + stdAc::fanspeed_t::kHigh, // Fan speed + stdAc::swingv_t::kAuto, // Veritcal swing + 1); // Sleep + EXPECT_TRUE(ac.getPower()); // Power. + EXPECT_EQ(kCarrierAc64Heat, ac.getMode()); // Operating mode. + EXPECT_EQ(21, ac.getTemp()); // Temperature. + EXPECT_EQ(kCarrierAc64FanHigh, ac.getFan()); // Fan Speed + EXPECT_TRUE(ac.getSwingV()); // SwingV + EXPECT_TRUE(ac.getSleep()); // Sleep + + ASSERT_EQ(expected, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(CARRIER_AC64, ac._irsend.capture.decode_type); + ASSERT_EQ(kCarrierAc64Bits, ac._irsend.capture.bits); + ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); +} + TEST(TestIRac, Coolix) { IRCoolixAC ac(0); IRac irac(0); @@ -141,6 +178,48 @@ TEST(TestIRac, Coolix) { ac._irsend.outputStr()); } +TEST(TestIRac, Corona) { + IRCoronaAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + + char expectedAfterSent[] = + "Power: On, Power Button: On, Mode: 0 (Heat), Temp: 21C, " + "Fan: 3 (High), Swing(V) Toggle: On, Econo: On, " + "On Timer: Off, Off Timer: Off"; + + char expectedCapture[] = + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 21C, " + "Fan: 3 (High), Swing(V) Toggle: On, Econo: On, " + "On Timer: Off, Off Timer: Off"; + + ac.begin(); + // this sends as well + irac.corona(&ac, + true, // Power + stdAc::opmode_t::kHeat, // Mode + 21, // Celsius + stdAc::fanspeed_t::kHigh, // Fan speed + stdAc::swingv_t::kAuto, // Veritcal swing + true); // Econo (PowerSave) + EXPECT_TRUE(ac.getPower()); // Power. + EXPECT_TRUE(ac.getPowerButton()); // Power.button + EXPECT_EQ(kCoronaAcModeHeat, ac.getMode()); // Operating mode. + EXPECT_EQ(21, ac.getTemp()); // Temperature. + EXPECT_EQ(kCoronaAcFanHigh, ac.getFan()); // Fan Speed + EXPECT_TRUE(ac.getSwingVToggle()); // SwingV + EXPECT_TRUE(ac.getEcono()); // Econo (PowerSave) + + ASSERT_EQ(expectedAfterSent, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(CORONA_AC, ac._irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, ac._irsend.capture.bits); + ASSERT_EQ(expectedCapture, IRAcUtils::resultAcToString(&ac._irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); +} + TEST(TestIRac, Daikin) { IRDaikinESP ac(0); IRac irac(0); @@ -690,16 +769,67 @@ TEST(TestIRac, Hitachi1) { ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); } +TEST(TestIRac, Hitachi344) { + IRHitachiAc344 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + char expected_swingon[] = + "Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), " + "Button: 129 (Swing(V)), Swing(V): Off, Swing(H): 2 (Right)"; + + ac.begin(); + irac.hitachi344(&ac, + true, // Power + stdAc::opmode_t::kHeat, // Mode + 25, // Celsius + stdAc::fanspeed_t::kMax, // Fan speed + stdAc::swingv_t::kAuto, // Swing(V) + stdAc::swingh_t::kRight); // Swing(H) + + ASSERT_EQ(expected_swingon, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(HITACHI_AC344, ac._irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc344Bits, ac._irsend.capture.bits); + ASSERT_EQ(expected_swingon, IRAcUtils::resultAcToString(&ac._irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); + EXPECT_EQ(decode_type_t::HITACHI_AC344, r.protocol); + EXPECT_TRUE(r.power); + EXPECT_EQ(stdAc::opmode_t::kHeat, r.mode); + EXPECT_EQ(25, r.degrees); + + char expected_swingoff[] = + "Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), " + "Button: 19 (Power/Mode), Swing(V): Off, Swing(H): 2 (Right)"; + + ac._irsend.reset(); + irac.hitachi344(&ac, + true, // Power + stdAc::opmode_t::kHeat, // Mode + 25, // Celsius + stdAc::fanspeed_t::kMax, // Fan speed + stdAc::swingv_t::kOff, // Swing(V) + stdAc::swingh_t::kRight); // Swing(H) + ASSERT_EQ(expected_swingoff, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(HITACHI_AC344, ac._irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc344Bits, ac._irsend.capture.bits); + ASSERT_EQ(expected_swingoff, + IRAcUtils::resultAcToString(&ac._irsend.capture)); +} + TEST(TestIRac, Hitachi424) { IRHitachiAc424 ac(0); IRac irac(0); IRrecv capture(0); char expected[] = "Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), " - "Swing(V) Toggle: Off, Button: 19 (Power/Mode)"; + "Button: 19 (Power/Mode), Swing(V) Toggle: Off"; char expected_swingv[] = "Power: On, Mode: 3 (Cool), Temp: 26C, Fan: 1 (Min), " - "Swing(V) Toggle: On, Button: 129 (Swing(V))"; + "Button: 129 (Swing(V)), Swing(V) Toggle: On"; ac.begin(); irac.hitachi424(&ac, diff --git a/lib/IRremoteESP8266-2.7.7/test/IRrecv_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRrecv_test.cpp similarity index 85% rename from lib/IRremoteESP8266-2.7.7/test/IRrecv_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/IRrecv_test.cpp index e66866be1..08649978c 100644 --- a/lib/IRremoteESP8266-2.7.7/test/IRrecv_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRrecv_test.cpp @@ -1595,11 +1595,37 @@ TEST(TestManchesterCode, matchManchester) { IRrecv irrecv(0); const uint16_t rawData[163] = { + // 0 2860, 3862, + // 11 00 11 00 1 0 11 0 1 0 1 0 1 + // 0 1 0 1 0 0 1 1 1 + // 1 4 + // 1 0 1 0 1 1 0 0 0 + // 2 B 1924, 1952, 1926, 1952, 956, 984, 1924, 1028, 952, 958, 980, 956, 982, + // 00 1 0 11 00 11 0 1 0 1 0 1 0 + // 1 0 0 1 0 1 1 1 1 + // F 2 F + // 0 1 1 0 1 0 0 0 0 + // 0 D 0 1882, 1016, 950, 1958, 1920, 1948, 1004, 954, 956, 984, 956, 952, 984, + // 1 0 1 0 1 00 1 0 11 0 1 0 1 + // 1 1 1 0 0 1 1 + // E + // 0 0 0 1 1 0 0 + // 1 974, 966, 974, 964, 974, 1888, 1010, 960, 1948, 1002, 946, 962, 978, + // 0 1 0 1 0 1 00 1 0 11 00 1 0 + // 1 1 1 1 0 0 1 0 + // 7 E + // 0 0 0 0 1 1 0 1 + // 8 1 962, 976, 960, 948, 992, 978, 1886, 982, 984, 1924, 1954, 952, 986, + // 1 + // 0 + // 4 + // 1 + // B 3892, 3862, 1924, 1954, 1924, 1954, 984, 952, 1956, 996, 954, 990, 948, 958, 980, 1882, 1016, 952, 1958, 1920, 1956, 994, 944, 962, 986, 956, 972, 962, @@ -1616,11 +1642,11 @@ TEST(TestManchesterCode, matchManchester) { uint16_t offset = 1; uint64_t result = 0; - uint16_t nbits = 32; + uint16_t nbits = 34; EXPECT_EQ(56, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, - 2860, 3800, 1000, 0, 3800)); - EXPECT_EQ(0x4F2FE7E4, result); + 2860, 2860, 1000, 2860, 2860)); + EXPECT_EQ(0x14F2FE7E4, result); irsend.reset(); irsend.sendRaw(rawData, 55, 38); // Send just the bare minimum. @@ -1628,8 +1654,8 @@ TEST(TestManchesterCode, matchManchester) { EXPECT_EQ(55, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, - 2860, 3800, 1000, 0, 3800)); - EXPECT_EQ(0x4F2FE7E4, result); + 2860, 2860, 1000, 2860, 2860)); + EXPECT_EQ(0x14F2FE7E4, result); irsend.reset(); irsend.sendRaw(rawData, 52, 38); // Now, just too short. @@ -1637,7 +1663,7 @@ TEST(TestManchesterCode, matchManchester) { EXPECT_EQ(0, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, - 2860, 3800, 1000, 0, 0)); + 2860, 2860, 1000, 2860, 2860)); } TEST(TestManchesterCode, ManchesterLoopBackGEThomasTest) { @@ -1650,7 +1676,7 @@ TEST(TestManchesterCode, ManchesterLoopBackGEThomasTest) { irsend.reset(); irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x12345678, nbits); irsend.makeDecodeResult(); - EXPECT_EQ(52, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, + EXPECT_EQ(50, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, 5000, 7000, 1000, 0, 10000, true, kUseDefTol, kMarkExcess, true, true)); @@ -1659,7 +1685,7 @@ TEST(TestManchesterCode, ManchesterLoopBackGEThomasTest) { irsend.reset(); irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x87654321, nbits); irsend.makeDecodeResult(); - EXPECT_EQ(52, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, + EXPECT_EQ(50, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, 5000, 7000, 1000, 0, 10000, true, kUseDefTol, kMarkExcess, true, true)); @@ -1677,7 +1703,7 @@ TEST(TestManchesterCode, ManchesterLoopBackIEEE802_3Test) { irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x12345678, nbits, 38000, true, kNoRepeat, kDutyDefault, false); irsend.makeDecodeResult(); - EXPECT_EQ(52, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, + EXPECT_EQ(50, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, 5000, 7000, 1000, 0, 10000, true, kUseDefTol, kMarkExcess, true, false)); @@ -1687,9 +1713,198 @@ TEST(TestManchesterCode, ManchesterLoopBackIEEE802_3Test) { irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x87654321, nbits, 38000, true, kNoRepeat, kDutyDefault, false); irsend.makeDecodeResult(); - EXPECT_EQ(54, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, + EXPECT_EQ(50, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, 5000, 7000, 1000, 0, 10000, true, kUseDefTol, kMarkExcess, true, false)); EXPECT_EQ(0x87654321, result); } + +TEST(TestMatchManchesterData, Normal) { + IRsendTest irsend(0); + IRrecv irrecv(0); + uint16_t offset = 1; + uint64_t result = 0; + irsend.begin(); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1111, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(8, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1111, result); + EXPECT_EQ("f38000d50m1000s1000m1000s1000m1000s1000m1000s1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1011, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(6, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1011, result); + EXPECT_EQ("f38000d50m1000s2000m2000s1000m1000s1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1010, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(5, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1010, result); + EXPECT_EQ("f38000d50m1000s2000m2000s2000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1000, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(7, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1000, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m1000s1000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1001, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(6, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1001, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m2000s1000", + irsend.outputStr()); +} + +TEST(TestMatchManchesterData, SimulateAtEndOfARealMessage) { + IRsendTest irsend(0); + IRrecv irrecv(0); + uint16_t offset = 1; + uint64_t result = 0; + irsend.begin(); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1111, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(7, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1111, result); + EXPECT_EQ("f38000d50m1000s1000m1000s1000m1000s1000m1000s1000", + irsend.outputStr()); + + uint16_t rawData[7] = {1000, 1000, 1000, 1000, 1000, 1000, 1000}; + irsend.reset(); + irsend.enableIROut(38); + irsend.sendRaw(rawData, 7, 38); + irsend.makeDecodeResult(); + EXPECT_EQ(7, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1111, result); + EXPECT_EQ("f38000d50m1000s1000m1000s1000m1000s1000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1011, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(5, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1011, result); + EXPECT_EQ("f38000d50m1000s2000m2000s1000m1000s1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1010, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(4, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1010, result); + EXPECT_EQ("f38000d50m1000s2000m2000s2000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1000, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(6, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1000, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m1000s1000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1001, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(5, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1001, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m2000s1000", + irsend.outputStr()); +} + +TEST(TestMatchManchesterData, SimulateLongFooter) { + IRsendTest irsend(0); + IRrecv irrecv(0); + uint16_t offset = 1; + uint64_t result = 0; + irsend.begin(); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1110, 4); + irsend.mark(4000); + irsend.makeDecodeResult(); + EXPECT_EQ(6, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1110, result); + EXPECT_EQ("f38000d50m1000s1000m1000s1000m1000s2000m5000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1001, 4); + irsend.space(4000); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(5, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1001, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m2000s5000", + irsend.outputStr()); +} diff --git a/lib/IRremoteESP8266-2.7.7/test/IRrecv_test.h b/lib/IRremoteESP8266-2.7.8/test/IRrecv_test.h similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/IRrecv_test.h rename to lib/IRremoteESP8266-2.7.8/test/IRrecv_test.h diff --git a/lib/IRremoteESP8266-2.7.7/test/IRsend_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRsend_test.cpp similarity index 96% rename from lib/IRremoteESP8266-2.7.7/test/IRsend_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/IRsend_test.cpp index 2f39e323d..51fae7499 100644 --- a/lib/IRremoteESP8266-2.7.7/test/IRsend_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRsend_test.cpp @@ -794,9 +794,9 @@ TEST(TestSendManchester, SendZeroBits) { IRsendTest irsend(0); irsend.begin(); irsend.sendManchester(0, 0, 1, 0, 0, 0b1, 0); - EXPECT_EQ("f36000d25m0f38000d50s1m2s1", irsend.outputStr()); + EXPECT_EQ("", irsend.outputStr()); irsend.sendManchester(1, 2, 100, 3, 4, 0b1, 0); - EXPECT_EQ("f38000d50m1s102m200s100m3s4", irsend.outputStr()); + EXPECT_EQ("f38000d50m1s2m3s4", irsend.outputStr()); } // Test sending zero and one. @@ -804,10 +804,10 @@ TEST(TestSendManchester, SendSingleBit) { IRsendTest irsend(0); irsend.begin(); irsend.sendManchester(1000, 2000, 100, 3000, 4000, 0b0, 1); - EXPECT_EQ("f38000d50m1000s2100m200s200m3100s4000", irsend.outputStr()); + EXPECT_EQ("f38000d50m1000s2100m3100s4000", irsend.outputStr()); irsend.sendManchester(1000, 2000, 100, 3000, 4000, 0b0, 1, 38, true, kNoRepeat, kDutyDefault, false); - EXPECT_EQ("f38000d50m1000s2000m100s200m200s100m3000s4000", + EXPECT_EQ("f38000d50m1000s2000m100s100m3000s4000", irsend.outputStr()); } @@ -816,14 +816,14 @@ TEST(TestSendManchester, TestingBitSendOrder) { IRsendTest irsend(0); irsend.begin(); irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b10, 2); - EXPECT_EQ("f38000d50m1000s2100m200s100m100s200m3100", irsend.outputStr()); + EXPECT_EQ("f38000d50m1000s2000m100s200m3100", irsend.outputStr()); irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b10, 2, 38, false); - EXPECT_EQ("f38000d50m1000s2100m200s200m200s100m3000", irsend.outputStr()); + EXPECT_EQ("f38000d50m1000s2100m200s100m3000", irsend.outputStr()); irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b0001, 4, 38, true); - EXPECT_EQ("f38000d50m1000s2100m200s200m100s100m100s100m200s100m3000", + EXPECT_EQ("f38000d50m1000s2100m100s100m100s100m200s100m3000", irsend.outputStr()); irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b0001, 4, 38, false); - EXPECT_EQ("f38000d50m1000s2100m200s100m100s200m100s100m100s100m3100", + EXPECT_EQ("f38000d50m1000s2000m100s200m100s100m100s100m3100", irsend.outputStr()); } @@ -835,16 +835,16 @@ TEST(TestSendManchester, SendTypicalData) { irsend.sendManchester(0, 0, 100, 0, 0, 0b10100111001, 11, 38, true); EXPECT_EQ( "f38000d50" - "m0s100m200s100" "m100s200m200s200m100s100m200s100m100s100m100s200m100s100m200s100", irsend.outputStr()); irsend.sendManchester(100, 200, 1, 300, 0, 0x1234567890ABCDEF, 64, 38, true); EXPECT_EQ( "f38000d50" "m100s201" - "m2s2m1s1m1s1m2s2m1s1m2s2m1s1m1s1m2s1m1s2m2s2m1s1m1s1m2s2m2s2m2s1m1s2m1s1" - "m2s1m1s1m1s1m1s2m1s1m1s1m2s2m1s1m2s2m1s1m1s1m1s1m2s2m2s2m2s2m2s1m1s1m1s1" - "m1s2m1s1m2s1m1s2m2s1m1s1m1s1m1s2m2s1m1s1m1s1m1s1m300", + "m1s1m1s1m2s2m1s1m2s2m1s1m1s1m2s1m1s2m2s2m1s1m1s1m2s2m2s2m2s1m1s2m1s1m2s1" + "m1s1m1s1m1s2m1s1m1s1m2s2m1s1m2s2m1s1m1s1m1s1m2s2m2s2m2s2m2s1m1s1m1s1m1s2" + "m1s1m2s1m1s2m2s1m1s1m1s1m1s2m2s1m1s1m1s1m1s1" + "m300", irsend.outputStr()); } @@ -856,7 +856,7 @@ TEST(TestSendManchester, SendOverLargeData) { EXPECT_EQ( "f38000d50" "m100s201" - "m2s2m1s1m1s1m1s1m1s1m1s1m2s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" + "m1s1m1s1m1s1m1s1m1s1m2s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" "m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" "m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" "m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" diff --git a/lib/IRremoteESP8266-2.7.7/test/IRsend_test.h b/lib/IRremoteESP8266-2.7.8/test/IRsend_test.h similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/IRsend_test.h rename to lib/IRremoteESP8266-2.7.8/test/IRsend_test.h diff --git a/lib/IRremoteESP8266-2.7.7/test/IRutils_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp similarity index 95% rename from lib/IRremoteESP8266-2.7.7/test/IRutils_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp index b079893cd..ecb23dbbf 100644 --- a/lib/IRremoteESP8266-2.7.7/test/IRutils_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp @@ -518,6 +518,7 @@ TEST(TestUtils, MinsToString) { } TEST(TestUtils, sumNibbles) { + // PTR/Array variant. uint8_t testdata[] = {0x01, 0x23, 0x45}; EXPECT_EQ(0, irutils::sumNibbles(testdata, 0)); EXPECT_EQ(1, irutils::sumNibbles(testdata, 0, 1)); @@ -525,6 +526,30 @@ TEST(TestUtils, sumNibbles) { EXPECT_EQ(2, irutils::sumNibbles(testdata, 1, 1)); EXPECT_EQ(15, irutils::sumNibbles(testdata, 3)); EXPECT_EQ(115, irutils::sumNibbles(testdata, 3, 100)); + + // Integer variant. + EXPECT_EQ(0x0, irutils::sumNibbles(0x0)); + EXPECT_EQ(0x1, irutils::sumNibbles(0x1)); + EXPECT_EQ(0xF, irutils::sumNibbles(0xF)); + EXPECT_EQ(0x4, irutils::sumNibbles(0x1111)); + EXPECT_EQ(0x8, irutils::sumNibbles(0x2222)); + EXPECT_EQ(0x0, irutils::sumNibbles(0x4444)); + EXPECT_EQ(0xA, irutils::sumNibbles(0x1234)); + EXPECT_EQ(0xA, irutils::sumNibbles(0x4321)); + EXPECT_EQ(0xE, irutils::sumNibbles(0xABCD)); + EXPECT_EQ(0x1, irutils::sumNibbles(0x4AE5)); + EXPECT_EQ(0xC, irutils::sumNibbles(0xFFFF)); + EXPECT_EQ(0x1, irutils::sumNibbles(0xC005)); + EXPECT_EQ(0x4, irutils::sumNibbles(0xC035)); + EXPECT_EQ(0x2, irutils::sumNibbles(0x88C0051)); + EXPECT_EQ(0x1, irutils::sumNibbles(0x88C0051, 1)); + EXPECT_EQ(0x2, irutils::sumNibbles(0x88C0051, 1, 1)); + EXPECT_EQ(0x6, irutils::sumNibbles(0x88C0051, 2)); + EXPECT_EQ(0x6, irutils::sumNibbles(0x88C0051, 4)); + EXPECT_EQ(0x2, irutils::sumNibbles(0x88C0051, 5)); + EXPECT_EQ(0x22, irutils::sumNibbles(0x88C0051, 16, 0, false)); + EXPECT_EQ(0x12, irutils::sumNibbles(0x88C0051, 5, 0, false)); + EXPECT_EQ(0x22, irutils::sumNibbles(0x88C0051, 255, 0, false)); } TEST(TestUtils, BCD) { diff --git a/lib/IRremoteESP8266-2.7.7/test/Makefile b/lib/IRremoteESP8266-2.7.8/test/Makefile similarity index 99% rename from lib/IRremoteESP8266-2.7.7/test/Makefile rename to lib/IRremoteESP8266-2.7.8/test/Makefile index 7b36c5743..ab64e28ed 100644 --- a/lib/IRremoteESP8266-2.7.7/test/Makefile +++ b/lib/IRremoteESP8266-2.7.8/test/Makefile @@ -24,7 +24,7 @@ INCLUDES = -I$(USER_DIR) -I. CPPFLAGS += -isystem $(GTEST_DIR)/include -DUNIT_TEST -D_IR_LOCALE_=en-AU # Flags passed to the C++ compiler. -CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 +CXXFLAGS += -g -Wall -Wextra -Werror -pthread -std=gnu++11 # All tests produced by this Makefile. generated from all *_test.cpp files TESTS = $(patsubst %.cpp,%,$(wildcard *_test.cpp)) diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Airwell_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp similarity index 72% rename from lib/IRremoteESP8266-2.7.7/test/ir_Airwell_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp index b58bceced..09300bac2 100644 --- a/lib/IRremoteESP8266-2.7.7/test/ir_Airwell_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp @@ -41,7 +41,7 @@ TEST(TestDecodeAirwell, RealExample) { ASSERT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); ASSERT_EQ(kAirwellBits, irsend.capture.bits); - EXPECT_EQ(0x4F2FE7E4, irsend.capture.value); + EXPECT_EQ(0x2B0D0181B, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); @@ -73,7 +73,7 @@ TEST(TestDecodeAirwell, RealExample) { ASSERT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); ASSERT_EQ(kAirwellBits, irsend.capture.bits); - EXPECT_EQ(0x8F07E7E4, irsend.capture.value); + EXPECT_EQ(0x270F8181B, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); } @@ -83,46 +83,16 @@ TEST(TestDecodeAirwell, SyntheticExample) { IRrecv irrecv(kGpioUnused); irsend.begin(); irsend.reset(); - irsend.sendAirwell(0xB0D0181B); + irsend.sendAirwell(0x2B0D0181B); irsend.makeDecodeResult(); ASSERT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); EXPECT_EQ(kAirwellBits, irsend.capture.bits); - EXPECT_EQ(0xB0D0181B, irsend.capture.value); + EXPECT_EQ(0x2B0D0181B, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); - EXPECT_EQ( - "f38000d50" - "m2850s3800" - "m1900s950m950s1900m1900s950m950s1900m950s950m950s950m950s950" - "m1900s950m950s1900m1900s1900m950s950m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m1900s950m950s950" - "m2850s3800" - "m1900s950m950s1900m1900s950m950s1900m950s950m950s950m950s950" - "m1900s950m950s1900m1900s1900m950s950m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m1900s950m950s950" - "m2850s3800" - "m1900s950m950s1900m1900s950m950s1900m950s950m950s950m950s950" - "m1900s950m950s1900m1900s1900m950s950m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m1900s950m950s950" - "m3800s100000", - irsend.outputStr()); - - irsend.reset(); - irsend.sendAirwell(0x4F2FE7E4); - irsend.makeDecodeResult(); - - ASSERT_TRUE(irrecv.decode(&irsend.capture)); - EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); - EXPECT_EQ(kAirwellBits, irsend.capture.bits); - EXPECT_EQ(0x4F2FE7E4, irsend.capture.value); - EXPECT_EQ(0x0, irsend.capture.address); - EXPECT_EQ(0x0, irsend.capture.command); EXPECT_EQ( "f38000d50" "m2850s3800" @@ -143,6 +113,36 @@ TEST(TestDecodeAirwell, SyntheticExample) { "m4750s100000", irsend.outputStr()); + irsend.reset(); + irsend.sendAirwell(0x60080002); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); + EXPECT_EQ(kAirwellBits, irsend.capture.bits); + EXPECT_EQ(0x60080002, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "f38000d50" + "m2850s2850" + "m950s950m950s950m950s1900m950s950m1900s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s1900m1900s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s1900m1900s950" + "m2850s2850" + "m950s950m950s950m950s1900m950s950m1900s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s1900m1900s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s1900m1900s950" + "m2850s2850" + "m950s950m950s950m950s1900m950s950m1900s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s1900m1900s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s1900m1900s950" + "m3800s100000", + irsend.outputStr()); + irsend.reset(); irsend.sendAirwell(0x70F8181B); irsend.makeDecodeResult(); @@ -214,3 +214,40 @@ TEST(TestUtils, Housekeeping) { ASSERT_EQ(kAirwellBits, IRsend::defaultBits(decode_type_t::AIRWELL)); ASSERT_EQ(kAirwellMinRepeats, IRsend::minRepeats(decode_type_t::AIRWELL)); } + +// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 +// Data from: +// https://docs.google.com/spreadsheets/d/1MeqVsgXQAMSiAx7zNunG8qbFcIT8tqZtcjLmMa0GEng/edit#gid=1053299474&range=M2:GW2 +TEST(TestDecodeAirwell, RealExample3) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + const uint16_t rawData[193] = { + 3010, 2852, + 904, 1042, 872, 1052, 872, 1932, 904, 956, 1878, 1050, 874, 1046, 872, + 956, 876, 1048, 872, 1044, 876, 1046, 874, 958, 872, 1050, 872, 1966, + 1880, 956, 872, 1048, 874, 1048, 872, 1050, 872, 958, 872, 1050, 872, + 1048, 872, 1050, 872, 958, 872, 1048, 872, 1050, 872, 1048, 872, 958, 872, + 1050, 872, 1048, 872, 1050, 872, 1872, 1880, 1048, + 2978, 2880, + 872, 1048, 872, 1050, 872, 1964, 872, 958, 1880, 1050, 872, 1050, 872, + 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, 1050, 872, 1964, + 1882, 958, 870, 1050, 872, 1048, 872, 1050, 872, 958, 872, 1048, 872, + 1050, 872, 1050, 872, 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, + 1050, 872, 1050, 872, 1050, 872, 1874, 1880, 1050, + 2978, 2880, + 872, 1050, 872, 1050, 872, 1964, 872, 958, 1880, 1050, 872, 1050, 872, + 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, 1050, 872, 1964, + 1880, 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, 1052, 870, + 1050, 872, 1050, 872, 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, + 1050, 872, 1050, 872, 1050, 872, 1874, 1880, 1050, 3894}; + irsend.reset(); + irsend.sendRaw(rawData, 193, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decodeAirwell(&irsend.capture)); + ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); + ASSERT_EQ(kAirwellBits, irsend.capture.bits); + EXPECT_EQ(0x60080002, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +} diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Aiwa_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Aiwa_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Aiwa_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Aiwa_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Amcor_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Amcor_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Amcor_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Amcor_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Argo_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Argo_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Argo_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Argo_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Carrier_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Carrier_test.cpp similarity index 75% rename from lib/IRremoteESP8266-2.7.7/test/ir_Carrier_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Carrier_test.cpp index 5e7a53220..fb6fb1b1b 100644 --- a/lib/IRremoteESP8266-2.7.7/test/ir_Carrier_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Carrier_test.cpp @@ -1,5 +1,6 @@ // Copyright 2018, 2020 David Conran +#include "ir_Carrier.h" #include "IRac.h" #include "IRrecv.h" #include "IRsend.h" @@ -256,7 +257,7 @@ TEST(TestUtils, Housekeeping) { ASSERT_EQ("CARRIER_AC64", typeToString(decode_type_t::CARRIER_AC64)); ASSERT_EQ(decode_type_t::CARRIER_AC64, strToDecodeType("CARRIER_AC64")); ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC64)); - ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC64)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC64)); ASSERT_EQ(kCarrierAc64Bits, IRsend::defaultBits(decode_type_t::CARRIER_AC64)); ASSERT_EQ(kCarrierAc64MinRepeat, @@ -318,7 +319,7 @@ TEST(TestDecodeCarrierAC40, SyntheticExample) { "m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497" "m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497" "m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497" - "m547s20000" + "m547s150000" // Repeat #1 "m8402s4166" "m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497" @@ -326,7 +327,7 @@ TEST(TestDecodeCarrierAC40, SyntheticExample) { "m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497" "m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497" "m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497" - "m547s20000" + "m547s150000" // Repeat #2 "m8402s4166" "m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497" @@ -334,7 +335,7 @@ TEST(TestDecodeCarrierAC40, SyntheticExample) { "m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497" "m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497" "m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497" - "m547s20000", + "m547s150000", irsend.outputStr()); } @@ -368,6 +369,10 @@ TEST(TestDecodeCarrierAC64, RealExample) { EXPECT_EQ(0x404000102E5E5584, irsend.capture.value); EXPECT_EQ(0, irsend.capture.address); EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ( + "Power: On, Mode: 1 (Heat), Temp: 30C, Fan: 1 (Low), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); } /// Send & Decode a synthetic message. @@ -403,3 +408,207 @@ TEST(TestDecodeCarrierAC64, SyntheticExample) { "m503s100000", irsend.outputStr()); } + +// Tests for IRCarrierAc64 class. + +TEST(TestCarrierAc64Class, Power) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + + ac.on(); + EXPECT_TRUE(ac.getPower()); + + ac.off(); + EXPECT_FALSE(ac.getPower()); + + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); + + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); + + ASSERT_EQ(36, kCarrierAc64PowerOffset); +} + +TEST(TestCarrierAc64Class, Temperature) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + + ac.setTemp(0); + EXPECT_EQ(kCarrierAc64MinTemp, ac.getTemp()); + + ac.setTemp(255); + EXPECT_EQ(kCarrierAc64MaxTemp, ac.getTemp()); + + ac.setTemp(kCarrierAc64MinTemp); + EXPECT_EQ(kCarrierAc64MinTemp, ac.getTemp()); + + ac.setTemp(kCarrierAc64MaxTemp); + EXPECT_EQ(kCarrierAc64MaxTemp, ac.getTemp()); + + ac.setTemp(kCarrierAc64MinTemp - 1); + EXPECT_EQ(kCarrierAc64MinTemp, ac.getTemp()); + + ac.setTemp(kCarrierAc64MaxTemp + 1); + EXPECT_EQ(kCarrierAc64MaxTemp, ac.getTemp()); + + ac.setTemp(17); + EXPECT_EQ(17, ac.getTemp()); + + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); + + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); + + ac.setTemp(29); + EXPECT_EQ(29, ac.getTemp()); +} + +TEST(TestCarrierAc64Class, OperatingMode) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + + ac.setMode(kCarrierAc64Cool); + EXPECT_EQ(kCarrierAc64Cool, ac.getMode()); + + ac.setMode(kCarrierAc64Fan); + EXPECT_EQ(kCarrierAc64Fan, ac.getMode()); + + ac.setMode(kCarrierAc64Heat); + EXPECT_EQ(kCarrierAc64Heat, ac.getMode()); + + ac.setMode(kCarrierAc64Fan + 1); + EXPECT_EQ(kCarrierAc64Cool, ac.getMode()); + + ac.setMode(255); + EXPECT_EQ(kCarrierAc64Cool, ac.getMode()); + ac.setMode(0); + EXPECT_EQ(kCarrierAc64Cool, ac.getMode()); +} + +TEST(TestCarrierAc64Class, Sleep) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); + ac.setSleep(false); + EXPECT_FALSE(ac.getSleep()); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); +} + +TEST(TestCarrierAc64Class, SwingVertical) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + ac.setSwingV(true); + EXPECT_TRUE(ac.getSwingV()); + ac.setSwingV(false); + EXPECT_FALSE(ac.getSwingV()); + ac.setSwingV(true); + EXPECT_TRUE(ac.getSwingV()); +} + +TEST(TestCarrierAc64Class, FanSpeed) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + + // Unexpected value should default to Auto. + ac.setFan(255); + EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan()); + ac.setFan(5); + EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan()); + + ac.setFan(kCarrierAc64FanHigh); + EXPECT_EQ(kCarrierAc64FanHigh, ac.getFan()); + + // Beyond High should default to Auto. + ac.setFan(kCarrierAc64FanHigh + 1); + EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan()); + + ac.setFan(kCarrierAc64FanMedium); + EXPECT_EQ(kCarrierAc64FanMedium, ac.getFan()); + + ac.setFan(kCarrierAc64FanLow); + EXPECT_EQ(kCarrierAc64FanLow, ac.getFan()); + + ac.setFan(kCarrierAc64FanAuto); + EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan()); +} + +TEST(TestCarrierAc64Class, ChecksumAndSetGetRaw) { + IRCarrierAc64 ac(kGpioUnused); + + const uint64_t valid = 0x90900030205C5584; + const uint64_t invalid = 0x9090003020505584; + ASSERT_NE(valid, invalid); + ASSERT_EQ(0x0C, IRCarrierAc64::calcChecksum(valid)); + ASSERT_TRUE(IRCarrierAc64::validChecksum(valid)); + ASSERT_FALSE(IRCarrierAc64::validChecksum(invalid)); + ac.setRaw(valid); + ASSERT_EQ(valid, ac.getRaw()); + ac.setRaw(invalid); + ASSERT_EQ(valid, ac.getRaw()); + + // Additional known states. + ASSERT_TRUE(IRCarrierAc64::validChecksum(0x109000002C2A5584)); + ASSERT_TRUE(IRCarrierAc64::validChecksum(0x109000102C2B5584)); +} + +// Test human readable output. +TEST(TestCarrierAc64Class, HumanReadable) { + IRCarrierAc64 ac(kGpioUnused); + EXPECT_EQ( + "Power: Off, Mode: 2 (Cool), Temp: 28C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setPower(true); + ac.setMode(kCarrierAc64Fan); + ac.setTemp(30); + ac.setFan(kCarrierAc64FanAuto); + ac.setSwingV(true); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setOffTimer(8* 60 + 37); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: 08:00", + ac.toString()); + ac.setOnTimer(5 * 60 + 59); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: 05:00, Off Timer: Off", + ac.toString()); + ac.setOnTimer(59); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setSleep(true); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: On, On Timer: Off, Off Timer: Off", + ac.toString()); +} + +TEST(TestCarrierAc64Class, ReconstructKnownState) { + IRCarrierAc64 ac(kGpioUnused); + const uint64_t expected = 0x2030009020555584; + ac.begin(); + ac.stateReset(); + ASSERT_NE(expected, ac.getRaw()); + ac.on(); + ac.setMode(kCarrierAc64Heat); + ac.setTemp(16); + ac.setFan(kCarrierAc64FanLow); + ac.setSwingV(true); + ac.setOnTimer(3 * 60); + ac.setSleep(true); + EXPECT_EQ(expected, ac.getRaw()); + EXPECT_EQ( + "Power: On, Mode: 1 (Heat), Temp: 16C, Fan: 1 (Low), Swing(V): On, " + "Sleep: On, On Timer: Off, Off Timer: Off", + ac.toString()); +} diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Coolix_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Coolix_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Coolix_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Coolix_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Corona_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Corona_test.cpp new file mode 100644 index 000000000..4bada0854 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Corona_test.cpp @@ -0,0 +1,1690 @@ +// Copyright 2020 Christian Nilsson + +#include "ir_Corona.h" +#include "IRac.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "gtest/gtest.h" + +// Tests for decodeCoronaAc(). +TEST(TestDecodeCoronaAc, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + + const uint16_t rawData_On[347] = { + 3520, 1686, + 460, 386, 452, 454, 408, 452, 410, 1320, 434, 428, 434, 1296, + 410, 452, 490, 374, 438, 1292, 434, 430, 434, 428, 438, 424, + 438, 426, 438, 1266, 464, 1266, 462, 402, 462, 1266, 464, 400, + 462, 1268, 464, 1266, 462, 1266, 464, 1268, 486, 376, 462, 402, + 472, 1256, 488, 378, 514, 346, 464, 1266, 488, 1240, 462, 404, + 462, 426, 460, 376, 462, 402, 488, 1240, 464, 1266, 462, 402, + 462, 400, 490, 1240, 462, 1266, 486, 1244, 460, 1268, 462, 1266, + 462, 1266, 462, 404, 458, 1270, 458, 1268, 462, 400, 464, 428, + 434, 402, 460, 402, 462, 398, 462, 1268, 462, 404, 460, 402, + 460, 1266, 466, 1264, + 462, 10808, + 3502, 1686, + 462, 400, 462, 400, 462, 400, 464, 1266, 462, 404, 458, 1266, + 464, 402, 460, 402, 462, 1266, 464, 404, 458, 402, 460, 400, + 488, 374, 464, 1266, 462, 1266, 466, 398, 462, 1268, 462, 400, + 518, 1208, 438, 1292, 440, 426, 488, 1242, 466, 1264, 460, 402, + 490, 1238, 490, 1238, 490, 1242, 514, 1212, 464, 1268, 490, 1238, + 464, 1266, 490, 1238, 462, 406, 458, 400, 464, 398, 464, 402, + 488, 374, 486, 376, 460, 402, 488, 372, 464, 1268, 462, 1264, + 464, 1266, 462, 1268, 462, 1266, 466, 1266, 490, 1242, 458, 1264, + 516, 348, 462, 404, 460, 404, 462, 398, 516, 344, 462, 400, + 464, 402, 488, 376, + 460, 10810, + 3526, 1658, + 462, 404, 460, 400, 488, 374, 464, 1264, 462, 402, 464, 1266, + 462, 402, 486, 374, 462, 1266, 546, 318, 462, 400, 464, 400, + 462, 402, 460, 1268, 466, 1262, 492, 374, 516, 1212, 464, 400, + 462, 1266, 516, 1212, 464, 402, 462, 424, 462, 1242, 460, 1268, + 488, 1242, 462, 1268, 490, 1236, 466, 1264, 462, 1268, 464, 1266, + 460, 1268, 464, 1266, 462, 338, 528, 402, 486, 374, 462, 402, + 460, 402, 490, 374, 458, 406, 458, 402, 488, 1240, 490, 1238, + 462, 1268, 464, 1268, 490, 1238, 488, 1242, 462, 1264, 464, 1270, + 462, 398, 436, 426, 460, 406, 458, 404, 434, 424, 464, 400, + 462, 400, 460, 402, + 462}; // UNKNOWN 94D81276 * ON + const uint8_t expectedState_On[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_On, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_On, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: On, Mode: 0 (Heat), Temp: 23C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_Off[347] = { + 3520, 1686, + 462, 400, 460, 402, 462, 382, 482, 1266, 462, 400, 462, 1268, + 462, 404, 488, 372, 462, 1266, 464, 402, 458, 404, 458, 382, + 482, 400, 462, 1266, 438, 1294, 488, 376, 460, 1268, 460, 400, + 470, 1260, 460, 1270, 462, 1268, 460, 1268, 462, 404, 458, 402, + 460, 1266, 462, 402, 462, 400, 462, 1268, 464, 1264, 462, 384, + 480, 400, 460, 404, 448, 414, 460, 1268, 462, 1268, 460, 402, + 490, 372, 462, 1268, 464, 1266, 462, 1268, 460, 1266, 464, 1266, + 464, 1266, 462, 404, 460, 400, 438, 1294, 486, 376, 462, 400, + 462, 402, 462, 400, 460, 402, 462, 1268, 460, 1268, 462, 404, + 486, 1240, 464, 1268, + 460, 10788, + 3524, 1682, + 462, 402, 462, 402, 460, 404, 460, 1266, 490, 374, 460, 1268, + 464, 400, 460, 406, 460, 1268, 464, 400, 458, 402, 462, 404, + 458, 404, 460, 1268, 460, 1268, 464, 400, 466, 1268, 456, 404, + 460, 1268, 460, 1268, 462, 402, 462, 1268, 462, 1266, 462, 402, + 462, 1268, 462, 1266, 488, 1242, 462, 1264, 460, 1270, 462, 1266, + 464, 1264, 462, 1270, 460, 402, 462, 402, 462, 400, 460, 402, + 462, 402, 462, 400, 462, 400, 460, 402, 462, 1266, 462, 1266, + 460, 1270, 462, 1268, 462, 1266, 460, 1268, 462, 1268, 462, 1268, + 462, 400, 458, 404, 466, 396, 436, 428, 460, 402, 460, 404, + 460, 402, 436, 428, + 462, 10794, + 3520, 1682, + 490, 376, 460, 402, 462, 402, 462, 1266, 462, 400, 462, 1268, + 460, 402, 460, 400, 462, 1266, 464, 400, 460, 402, 488, 378, + 456, 384, 482, 1268, 460, 1268, 462, 402, 460, 1268, 460, 404, + 460, 1268, 436, 1276, 480, 404, 456, 404, 460, 1268, 462, 1268, + 460, 1268, 462, 1270, 462, 1268, 462, 1268, 462, 1266, 460, 1268, + 462, 1268, 462, 1268, 462, 400, 462, 384, 478, 404, 460, 384, + 480, 400, 488, 376, 460, 404, 458, 404, 460, 1268, 464, 1264, + 462, 1268, 462, 1268, 462, 1270, 462, 1268, 486, 1244, 460, 1266, + 462, 400, 462, 400, 462, 402, 460, 404, 460, 400, 460, 404, + 486, 374, 462, 400, + 464}; // UNKNOWN A37A38D7 * Off + const uint8_t expectedState_Off[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x27, 0xD8, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_Off, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_Off, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: Off, Power Button: On, Mode: 0 (Heat), Temp: 23C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_17C[347] = { + 3522, 1686, + 458, 404, 486, 374, 434, 432, 482, 1244, 462, 400, 460, 1268, + 462, 400, 462, 386, 478, 1268, 462, 402, 462, 404, 458, 400, + 464, 400, 462, 1272, 456, 1268, 460, 402, 460, 1270, 434, 428, + 462, 1268, 460, 1268, 464, 1268, 460, 1266, 462, 402, 460, 382, + 482, 1264, 464, 400, 462, 402, 460, 1268, 460, 1270, 462, 404, + 460, 400, 460, 402, 462, 382, 506, 1242, 462, 1268, 464, 398, + 460, 398, 466, 1268, 458, 1268, 462, 1266, 462, 1266, 462, 402, + 458, 406, 460, 402, 460, 1270, 460, 406, 432, 428, 462, 402, + 438, 424, 460, 1268, 462, 1270, 460, 1266, 462, 402, 462, 1266, + 462, 1270, 460, 1268, + 438, 10814, + 3522, 1684, + 462, 402, 464, 402, 460, 400, 462, 1266, 462, 400, 462, 1266, + 466, 398, 462, 402, 460, 1270, 460, 384, 478, 402, 434, 428, + 462, 402, 516, 1212, 436, 1294, 460, 402, 460, 1268, 464, 400, + 460, 1268, 462, 1268, 434, 428, 462, 1266, 462, 1266, 462, 400, + 460, 1270, 462, 1268, 458, 1268, 436, 1274, 480, 1268, 460, 1266, + 490, 1240, 462, 1268, 460, 404, 460, 402, 488, 376, 462, 402, + 460, 402, 492, 370, 462, 400, 464, 402, 458, 1268, 490, 1240, + 460, 1268, 464, 1266, 462, 1266, 460, 1272, 460, 1266, 462, 1266, + 464, 400, 462, 404, 462, 400, 462, 402, 458, 384, 480, 402, + 458, 402, 460, 402, + 464, 10810, + 3528, 1660, + 490, 374, 462, 404, 458, 400, 462, 1268, 460, 404, 460, 1270, + 458, 402, 460, 402, 462, 1266, 486, 378, 460, 382, 506, 376, + 458, 404, 460, 1270, 460, 1270, 460, 402, 460, 1268, 464, 402, + 456, 1268, 462, 1268, 462, 402, 460, 402, 462, 1266, 462, 1266, + 464, 1266, 460, 1272, 460, 1266, 464, 1266, 462, 1266, 462, 1268, + 462, 1266, 462, 1268, 462, 402, 460, 404, 462, 402, 512, 352, + 512, 346, 438, 426, 462, 402, 460, 400, 462, 1268, 462, 1268, + 462, 1268, 460, 1270, 434, 1292, 464, 1266, 462, 1268, 460, 1270, + 514, 350, 432, 430, 460, 402, 460, 404, 460, 384, 480, 400, + 490, 374, 458, 404, + 462}; // UNKNOWN 8CC3C997 * 17C + const uint8_t expectedState_17C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x11, 0xEE, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_17C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_17C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 17C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_18C[347] = { + 3520, 1686, + 462, 400, 460, 402, 436, 426, 488, 1242, 460, 402, 460, 1270, + 460, 404, 462, 398, 462, 1268, 462, 402, 462, 402, 436, 326, + 536, 430, 458, 1266, 462, 1268, 486, 380, 456, 1270, 462, 400, + 462, 1268, 462, 1266, 490, 1240, 438, 1292, 462, 404, 462, 400, + 462, 1266, 460, 404, 458, 404, 484, 1244, 466, 1264, 460, 402, + 436, 430, 458, 400, 436, 426, 460, 1268, 462, 1268, 438, 426, + 434, 428, 462, 1268, 462, 1266, 464, 1266, 462, 428, 436, 1268, + 436, 406, 480, 402, 462, 1270, 458, 404, 460, 402, 488, 374, + 464, 1246, 480, 400, 436, 1292, 488, 1242, 462, 402, 460, 1268, + 462, 1250, 480, 1268, + 462, 10790, + 3520, 1684, + 464, 402, 460, 404, 462, 398, 462, 1266, 464, 400, 462, 1270, + 460, 402, 458, 406, 456, 1268, 436, 424, 464, 400, 460, 404, + 462, 400, 462, 1268, 462, 1268, 464, 398, 488, 1238, 464, 400, + 462, 1268, 462, 1248, 478, 384, 482, 1264, 436, 1292, 462, 402, + 462, 1266, 464, 1266, 460, 1268, 464, 1268, 462, 1266, 462, 1266, + 464, 1266, 462, 1268, 462, 402, 486, 376, 464, 398, 460, 404, + 462, 402, 436, 426, 462, 428, 408, 428, 460, 1268, 460, 1268, + 436, 1290, 466, 1264, 464, 1266, 460, 1270, 462, 1264, 462, 1268, + 460, 404, 462, 402, 460, 400, 462, 404, 458, 404, 460, 404, + 460, 382, 482, 400, + 460, 10812, + 3480, 1706, + 464, 402, 482, 376, 460, 404, 458, 1270, 462, 402, 462, 1268, + 462, 400, 460, 402, 462, 1268, 462, 400, 462, 400, 464, 400, + 436, 426, 436, 1294, 462, 1268, 462, 402, 516, 1212, 462, 402, + 464, 1266, 460, 1266, 438, 428, 460, 402, 460, 1268, 462, 1268, + 488, 1242, 462, 1264, 460, 1270, 462, 1266, 462, 1266, 462, 1268, + 462, 1268, 460, 1270, 462, 400, 462, 402, 460, 400, 462, 400, + 488, 378, 458, 402, 462, 400, 516, 348, 460, 1268, 436, 1276, + 478, 1268, 436, 1292, 462, 1270, 460, 1268, 462, 1248, 484, 1266, + 460, 400, 464, 402, 460, 404, 432, 426, 436, 430, 462, 400, + 432, 428, 434, 426, + 464}; // UNKNOWN 513BFA3A * 18C + const uint8_t expectedState_18C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x12, 0xED, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_18C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_18C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 18C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_19C[347] = { + 3508, 1682, + 490, 350, 488, 372, 514, 372, 466, 1262, 468, 398, 464, 1262, + 466, 396, 466, 396, 496, 1234, 442, 400, 488, 396, 470, 396, + 464, 396, 466, 1262, 468, 1260, 466, 396, 468, 1262, 466, 396, + 520, 1210, 474, 1254, 470, 1260, 466, 1266, 464, 396, 494, 368, + 468, 1260, 468, 364, 498, 396, 466, 1264, 470, 1260, 466, 394, + 466, 398, 468, 392, 494, 370, 466, 1262, 524, 1206, 466, 398, + 466, 396, 520, 1210, 492, 1238, 464, 1268, 466, 1260, 492, 1236, + 494, 350, 484, 398, 466, 1262, 468, 1264, 466, 396, 468, 396, + 492, 350, 486, 398, 466, 1262, 494, 1236, 466, 394, 468, 396, + 492, 1236, 494, 1236, + 466, 10804, + 3508, 1680, + 466, 292, 572, 396, 464, 396, 466, 1262, 466, 398, 466, 1264, + 468, 374, 488, 296, 568, 1262, 464, 396, 524, 288, 520, 396, + 468, 396, 492, 1234, 466, 1266, 464, 398, 464, 1262, 468, 398, + 492, 1234, 468, 1262, 466, 396, 442, 1286, 468, 1264, 466, 394, + 468, 1264, 518, 1210, 492, 1238, 466, 1264, 520, 1206, 468, 1262, + 468, 1260, 472, 1260, 466, 394, 468, 396, 494, 348, 488, 376, + 484, 396, 470, 396, 464, 396, 494, 346, 492, 1260, 468, 1262, + 468, 1262, 492, 1236, 494, 1236, 492, 1236, 466, 1262, 468, 1262, + 468, 394, 466, 398, 492, 370, 466, 396, 468, 394, 496, 368, + 492, 370, 466, 398, + 490, 10780, + 3510, 1680, + 468, 374, 486, 396, 494, 348, 486, 1264, 492, 368, 492, 1236, + 468, 398, 466, 394, 468, 1262, 464, 304, 536, 402, 512, 370, + 492, 370, 492, 1236, 468, 1262, 468, 394, 492, 1238, 466, 398, + 466, 1264, 468, 1262, 490, 372, 492, 290, 546, 1262, 522, 1208, + 466, 1264, 466, 1264, 468, 1258, 494, 1236, 468, 1264, 466, 1264, + 520, 1208, 494, 1238, 494, 370, 466, 396, 464, 396, 520, 292, + 518, 394, 468, 398, 464, 376, 490, 394, 468, 1264, 464, 1264, + 466, 1260, 466, 1264, 496, 1232, 466, 1262, 468, 1262, 466, 1264, + 466, 396, 492, 372, 468, 374, 486, 398, 464, 396, 468, 398, + 464, 398, 466, 396, + 464}; // CORONA_AC * On 19C + const uint8_t expectedState_19C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x33, 0xCC, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_19C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_19C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: On, Mode: 0 (Heat), Temp: 19C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_20C[347] = { + 3522, 1684, + 466, 398, 462, 402, 462, 382, 480, 1266, 460, 404, 462, 1266, + 464, 400, 464, 398, 462, 1268, 462, 400, 462, 404, 460, 402, + 458, 402, 466, 1266, 434, 1292, 462, 402, 460, 1268, 460, 386, + 478, 1266, 462, 1268, 460, 1268, 460, 1268, 462, 404, 460, 402, + 462, 1266, 462, 384, 480, 404, 460, 1268, 436, 1294, 460, 402, + 462, 400, 464, 402, 456, 406, 460, 1268, 464, 1264, 468, 398, + 460, 402, 460, 1270, 488, 1240, 460, 1270, 434, 430, 458, 402, + 458, 1270, 462, 402, 462, 1268, 462, 400, 462, 400, 462, 402, + 462, 1266, 464, 1264, 462, 404, 432, 1296, 438, 426, 462, 1268, + 458, 1270, 460, 1268, + 464, 10788, + 3518, 1686, + 488, 376, 462, 400, 462, 402, 460, 1268, 436, 426, 438, 1292, + 462, 402, 518, 344, 462, 1266, 462, 400, 460, 402, 436, 428, + 460, 402, 458, 1268, 438, 1292, 438, 424, 464, 1266, 460, 404, + 460, 1266, 462, 1268, 462, 400, 462, 1268, 462, 1266, 462, 400, + 462, 1268, 462, 1268, 464, 1264, 462, 1266, 460, 1270, 486, 1242, + 462, 1268, 436, 1294, 508, 292, 526, 400, 462, 402, 460, 402, + 488, 374, 462, 404, 436, 424, 462, 402, 438, 1292, 460, 1266, + 462, 1268, 460, 1266, 464, 1268, 460, 1268, 436, 1294, 490, 1240, + 434, 428, 438, 424, 460, 404, 436, 426, 462, 404, 484, 374, + 462, 404, 462, 400, + 460, 10792, + 3546, 1658, + 436, 430, 460, 400, 462, 404, 460, 1266, 462, 402, 438, 1292, + 462, 402, 458, 404, 436, 1290, 494, 374, 460, 402, 460, 402, + 462, 398, 436, 1292, 462, 1268, 462, 402, 436, 1290, 464, 400, + 462, 1266, 438, 1292, 462, 402, 490, 374, 434, 1296, 432, 1298, + 432, 1292, 464, 1266, 460, 1268, 462, 1268, 490, 1240, 436, 1292, + 464, 1266, 438, 1290, 462, 402, 436, 426, 462, 400, 460, 402, + 460, 402, 436, 426, 488, 374, 436, 428, 460, 1270, 462, 1268, + 462, 1268, 436, 1292, 462, 1266, 462, 1268, 460, 1266, 462, 1268, + 460, 406, 458, 402, 462, 402, 436, 408, 482, 400, 438, 426, + 434, 428, 460, 404, + 434}; // UNKNOWN 48F17976 * 20C + const uint8_t expectedState_20C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x14, 0xEB, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_20C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_20C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 20C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_21C[347] = { + 3522, 1684, + 434, 430, 430, 412, 460, 418, 462, 1268, 460, 386, 452, 1296, + 460, 426, 432, 386, 480, 1268, 458, 404, 432, 430, 434, 428, + 434, 428, 460, 1266, 490, 1240, 462, 402, 460, 1268, 460, 386, + 452, 1296, 458, 1272, 460, 1266, 462, 1270, 460, 404, 434, 428, + 458, 1270, 434, 430, 432, 430, 460, 1268, 462, 1270, 458, 430, + 406, 432, 456, 404, 458, 404, 466, 1262, 460, 1270, 458, 406, + 456, 406, 458, 1268, 460, 1270, 488, 1240, 490, 1240, 460, 384, + 478, 1268, 436, 430, 432, 1294, 462, 384, 450, 456, 432, 404, + 436, 430, 458, 1270, 434, 430, 460, 1268, 460, 404, 464, 1264, + 460, 1268, 460, 1270, + 460, 10808, + 3504, 1682, + 462, 402, 460, 430, 430, 406, 460, 1268, 462, 428, 436, 1268, + 434, 432, 458, 404, 458, 1272, 458, 426, 432, 406, 460, 404, + 460, 428, 406, 1296, 462, 1268, 434, 454, 408, 1278, 480, 426, + 408, 1294, 460, 1268, 460, 404, 432, 1294, 462, 1268, 458, 384, + 480, 1272, 460, 1266, 460, 1270, 460, 1268, 462, 1266, 462, 1268, + 460, 1268, 462, 1268, 436, 428, 436, 428, 464, 424, 434, 386, + 478, 428, 434, 406, 432, 410, 478, 386, 476, 1270, 462, 1270, + 462, 1266, 460, 1270, 458, 1272, 458, 1270, 436, 1292, 464, 1266, + 434, 430, 460, 428, 408, 430, 458, 404, 484, 378, 432, 430, + 460, 404, 458, 406, + 458, 10796, + 3542, 1662, + 460, 402, 434, 456, 430, 406, 458, 1270, 458, 408, 432, 1294, + 462, 382, 480, 384, 450, 1296, 488, 374, 458, 406, 432, 430, + 432, 456, 432, 1270, 436, 1292, 462, 402, 434, 1294, 434, 428, + 460, 1268, 460, 1270, 458, 402, 464, 400, 462, 1266, 460, 1270, + 460, 1270, 434, 1294, 464, 1268, 486, 1242, 464, 1266, 460, 1270, + 486, 1244, 458, 1268, 464, 402, 458, 402, 460, 404, 434, 452, + 410, 428, 432, 432, 456, 432, 408, 426, 462, 1268, 462, 1268, + 434, 1296, 462, 1268, 458, 1270, 466, 1262, 464, 1272, 456, 1268, + 460, 406, 458, 402, 460, 404, 460, 404, 460, 402, 458, 430, + 430, 386, 480, 402, + 460}; // UNKNOWN D1869C5B * 21C + const uint8_t expectedState_21C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x15, 0xEA, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_21C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_21C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 21C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_22C[347] = { + 3524, 1686, + 460, 404, 458, 402, 462, 400, 462, 1248, 482, 400, 460, 1268, + 436, 428, 488, 374, 460, 1268, 460, 404, 460, 402, 462, 402, + 460, 402, 462, 1268, 458, 1270, 458, 404, 460, 1248, 480, 402, + 462, 1268, 436, 1292, 462, 1270, 460, 1268, 462, 400, 460, 402, + 462, 1266, 460, 404, 436, 428, 462, 1266, 462, 1268, 460, 402, + 462, 402, 460, 404, 434, 428, 462, 1266, 438, 1290, 462, 404, + 460, 404, 434, 1292, 466, 1266, 436, 1294, 462, 400, 462, 1268, + 436, 1294, 460, 402, 462, 1268, 436, 426, 492, 374, 458, 400, + 464, 1266, 462, 400, 436, 428, 460, 1266, 492, 372, 462, 1268, + 460, 1268, 462, 1268, + 488, 10762, + 3496, 1710, + 462, 400, 462, 400, 460, 402, 460, 1270, 434, 426, 462, 1268, + 460, 400, 438, 424, 438, 1292, 436, 426, 460, 402, 436, 426, + 438, 426, 460, 1268, 464, 1266, 462, 400, 462, 1268, 464, 400, + 434, 1294, 464, 1268, 488, 372, 462, 1268, 464, 1264, 436, 426, + 490, 1240, 438, 1292, 464, 1264, 460, 1270, 436, 1294, 460, 1268, + 434, 1294, 462, 1266, 438, 426, 460, 402, 462, 400, 462, 402, + 462, 400, 460, 402, 462, 402, 460, 382, 482, 1268, 436, 1294, + 462, 1266, 436, 1294, 460, 1268, 438, 1290, 462, 1268, 462, 1268, + 462, 400, 462, 400, 464, 400, 462, 402, 462, 400, 488, 372, + 492, 372, 460, 402, + 460, 10810, + 3528, 1660, + 462, 404, 434, 426, 464, 400, 434, 1294, 462, 400, 464, 1266, + 462, 400, 464, 398, 466, 1264, 462, 402, 460, 402, 464, 398, + 464, 398, 462, 1268, 462, 1266, 440, 422, 462, 1268, 462, 404, + 462, 1264, 436, 1294, 460, 402, 462, 400, 438, 1292, 464, 1266, + 460, 1268, 462, 1266, 464, 1268, 462, 1266, 462, 1266, 462, 1266, + 438, 1292, 464, 1266, 460, 400, 462, 384, 480, 402, 460, 404, + 434, 428, 462, 402, 434, 428, 460, 402, 458, 1270, 462, 1266, + 464, 1266, 464, 1266, 464, 1264, 464, 1266, 462, 1246, 484, 1266, + 438, 424, 438, 424, 462, 402, 462, 400, 438, 424, 460, 402, + 462, 400, 436, 428, + 434}; // UNKNOWN 21DD90BB * 22C + const uint8_t expectedState_22C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x16, 0xE9, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_22C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_22C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 22C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_23C[347] = { + 3522, 1684, + 460, 402, 462, 428, 406, 430, 458, 1270, 462, 400, 460, 1268, + 462, 402, 462, 402, 462, 1266, 462, 404, 432, 428, 434, 428, + 462, 402, 458, 1266, 464, 1268, 458, 402, 516, 1216, 460, 404, + 458, 1268, 462, 1268, 462, 1266, 462, 1266, 462, 402, 460, 406, + 456, 1268, 462, 402, 460, 402, 462, 1268, 462, 1266, 462, 402, + 460, 402, 488, 374, 490, 398, 434, 1270, 460, 1268, 460, 404, + 460, 430, 408, 1292, 462, 1268, 462, 1266, 462, 1268, 460, 1250, + 506, 1242, 462, 400, 460, 1268, 462, 400, 460, 408, 456, 404, + 458, 404, 460, 398, 462, 404, 458, 1268, 434, 430, 460, 1268, + 462, 1266, 462, 1268, + 464, 10790, + 3520, 1682, + 464, 402, 460, 428, 406, 430, 458, 1270, 462, 402, 460, 1268, + 462, 406, 488, 374, 430, 1296, 460, 402, 462, 402, 462, 400, + 462, 402, 458, 1268, 490, 1242, 460, 402, 460, 1272, 460, 400, + 460, 1268, 462, 1266, 462, 404, 462, 1264, 462, 1266, 490, 374, + 464, 1268, 458, 1268, 492, 1236, 462, 1266, 464, 1264, 462, 1250, + 478, 1266, 462, 1268, 462, 402, 460, 384, 478, 402, 434, 428, + 460, 404, 460, 402, 462, 400, 460, 430, 430, 1270, 490, 1240, + 460, 1268, 462, 1268, 460, 1272, 460, 1268, 436, 1294, 462, 1264, + 464, 400, 460, 386, 504, 400, 434, 404, 460, 402, 462, 384, + 476, 384, 454, 426, + 462, 10792, + 3548, 1656, + 462, 404, 460, 400, 516, 350, 458, 1268, 462, 400, 434, 1294, + 464, 424, 434, 382, 480, 1270, 462, 406, 454, 406, 458, 402, + 462, 402, 434, 1294, 514, 1216, 462, 400, 434, 1298, 458, 404, + 460, 1268, 460, 1270, 460, 402, 464, 398, 460, 1268, 464, 1266, + 436, 1294, 460, 1268, 460, 1270, 462, 1264, 436, 1292, 462, 1268, + 436, 1294, 460, 1268, 460, 402, 460, 402, 486, 376, 462, 402, + 460, 402, 462, 428, 408, 430, 464, 426, 430, 1272, 460, 1270, + 462, 1268, 434, 1292, 462, 1268, 464, 1266, 464, 1268, 462, 1266, + 464, 402, 458, 432, 434, 402, 434, 430, 488, 398, 410, 428, + 460, 402, 460, 428, + 410}; // UNKNOWN F68FE737 * 23C + const uint8_t expectedState_23C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x17, 0xE8, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_23C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_23C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 23C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_24C[347] = { + 3522, 1686, + 460, 428, 406, 454, 410, 454, 432, 1272, 458, 432, 432, 1270, + 434, 454, 436, 424, 436, 1270, 458, 388, 474, 432, 406, 458, + 432, 384, 452, 1296, 434, 1294, 458, 428, 436, 1270, 432, 412, + 476, 1270, 456, 1272, 434, 1292, 462, 1296, 434, 428, 410, 454, + 408, 1320, 434, 428, 432, 432, 408, 1296, 434, 1320, 408, 454, + 410, 454, 434, 428, 408, 454, 436, 1268, 436, 1296, 442, 418, + 464, 384, 450, 1298, 458, 1296, 408, 1296, 462, 424, 434, 428, + 434, 430, 406, 1322, 434, 1270, 460, 384, 452, 412, 474, 430, + 434, 1296, 432, 1272, 436, 1320, 434, 428, 434, 430, 434, 1298, + 430, 1294, 464, 1266, + 410, 10816, + 3516, 1716, + 408, 454, 412, 450, 408, 454, 408, 1322, 432, 430, 434, 1296, + 406, 456, 408, 454, 434, 1296, 408, 454, 434, 430, 408, 452, + 408, 454, 410, 1294, 434, 1296, 460, 428, 436, 1270, 458, 430, + 408, 1296, 462, 1292, 434, 430, 408, 1322, 408, 1322, 434, 430, + 432, 1270, 438, 1322, 406, 1322, 432, 1272, 434, 1294, 436, 1318, + 408, 1324, 406, 1296, 450, 394, 480, 428, 432, 388, 450, 456, + 408, 454, 432, 430, 408, 454, 408, 456, 432, 1274, 486, 1240, + 434, 1296, 436, 1292, 458, 1270, 460, 1268, 462, 1270, 458, 1270, + 438, 450, 434, 430, 434, 428, 410, 452, 434, 430, 434, 384, + 476, 430, 432, 406, + 432, 10822, + 3516, 1690, + 456, 386, 480, 430, 428, 430, 434, 1272, 456, 430, 408, 1296, + 458, 426, 410, 454, 408, 1294, 464, 426, 434, 430, 412, 450, + 436, 428, 406, 1324, 434, 1294, 432, 408, 456, 1272, 458, 384, + 506, 1242, 458, 1272, 458, 430, 434, 428, 432, 1296, 408, 1296, + 458, 1272, 456, 1272, 460, 1292, 434, 1270, 462, 1294, 434, 1298, + 430, 1272, 460, 1294, 406, 454, 434, 430, 432, 430, 432, 430, + 410, 454, 406, 456, 408, 456, 432, 428, 436, 1270, 458, 1296, + 434, 1294, 436, 1294, 406, 1322, 410, 1294, 460, 1294, 432, 1298, + 432, 430, 408, 456, 406, 414, 476, 430, 434, 428, 434, 428, + 436, 426, 410, 454, + 434}; // UNKNOWN 914A12BF * 24C + const uint8_t expectedState_24C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x18, 0xE7, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_24C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_24C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 24C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_25C[347] = { + 3518, 1690, + 458, 426, 436, 384, 478, 432, 432, 1270, 460, 384, 480, 1268, + 458, 386, 452, 430, 432, 1294, 462, 428, 434, 404, 458, 432, + 432, 428, 436, 1268, 458, 1270, 458, 386, 454, 1294, 486, 360, + 480, 1268, 436, 1296, 460, 1270, 434, 1294, 460, 430, 408, 454, + 436, 1268, 434, 454, 406, 456, 408, 1276, 480, 1268, 460, 428, + 410, 426, 460, 430, 430, 406, 462, 1266, 460, 1274, 430, 456, + 434, 384, 450, 1296, 460, 1268, 434, 1298, 460, 1266, 460, 386, + 510, 350, 452, 1296, 434, 1296, 486, 404, 434, 424, 436, 426, + 434, 432, 430, 1298, 408, 1296, 434, 454, 408, 454, 434, 1270, + 434, 1296, 432, 1296, + 434, 10816, + 3516, 1690, + 458, 426, 408, 458, 432, 388, 476, 1296, 434, 428, 458, 1244, + 462, 430, 406, 430, 460, 1270, 458, 386, 476, 384, 476, 386, + 478, 386, 450, 1296, 460, 1270, 460, 382, 478, 1270, 460, 426, + 410, 1294, 462, 1270, 434, 454, 434, 1270, 432, 1296, 458, 386, + 478, 1294, 432, 1272, 436, 1294, 460, 1272, 432, 1298, 434, 1294, + 462, 1250, 452, 1298, 432, 432, 486, 400, 410, 454, 408, 414, + 476, 430, 430, 386, 476, 404, 460, 428, 410, 1296, 456, 1274, + 432, 1294, 460, 1250, 480, 1268, 436, 1292, 462, 1268, 488, 1242, + 458, 406, 482, 380, 458, 428, 408, 456, 414, 448, 410, 428, + 458, 430, 432, 404, + 434, 10822, + 3516, 1688, + 460, 428, 436, 424, 410, 428, 460, 1270, 460, 428, 410, 1276, + 478, 384, 476, 430, 408, 1296, 460, 432, 414, 418, 436, 454, + 434, 406, 456, 1270, 456, 1270, 462, 428, 408, 1298, 458, 430, + 406, 1296, 460, 1296, 408, 428, 460, 430, 432, 1268, 460, 1270, + 434, 1296, 432, 1294, 460, 1272, 432, 1298, 456, 1272, 460, 1268, + 460, 1270, 458, 1270, 460, 430, 432, 430, 434, 388, 476, 404, + 456, 430, 406, 458, 406, 456, 406, 412, 476, 1270, 460, 1270, + 460, 1270, 460, 1270, 434, 1294, 462, 1268, 460, 1296, 436, 1268, + 460, 428, 432, 430, 432, 430, 408, 440, 448, 388, 450, 452, + 410, 428, 460, 428, + 408}; // UNKNOWN 7A72A3B * 25C + const uint8_t expectedState_25C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x19, 0xE6, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_25C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_25C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 25C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_26C[347] = { + 3516, 1668, + 480, 402, 458, 386, 504, 380, 458, 1266, 462, 402, 462, 1268, + 460, 402, 462, 402, 458, 1270, 460, 402, 462, 400, 486, 376, + 460, 404, 436, 1292, 460, 1268, 460, 404, 462, 1268, 460, 402, + 458, 1270, 460, 1268, 462, 1266, 436, 1294, 458, 404, 488, 358, + 480, 1268, 460, 402, 488, 374, 458, 1270, 462, 1266, 462, 404, + 462, 400, 460, 404, 486, 376, 460, 1268, 460, 1270, 462, 400, + 458, 404, 458, 1270, 460, 1270, 462, 1266, 462, 400, 460, 1270, + 462, 402, 460, 1268, 462, 1268, 460, 402, 462, 402, 460, 402, + 460, 1270, 460, 402, 460, 1268, 460, 402, 482, 380, 460, 1268, + 490, 1244, 462, 1264, + 460, 10792, + 3518, 1686, + 460, 402, 462, 402, 460, 402, 460, 1270, 470, 388, 466, 1268, + 462, 402, 460, 402, 462, 1266, 462, 402, 460, 402, 460, 384, + 480, 400, 488, 1242, 460, 1268, 462, 402, 462, 1266, 462, 402, + 460, 1270, 460, 1268, 462, 384, 482, 1266, 462, 1266, 462, 402, + 460, 1266, 462, 1270, 460, 1266, 462, 1268, 462, 1268, 460, 1270, + 462, 1268, 458, 1268, 462, 402, 460, 402, 458, 402, 464, 400, + 460, 402, 462, 402, 460, 402, 462, 402, 458, 1270, 462, 1268, + 460, 1268, 462, 1266, 462, 1268, 462, 1268, 458, 1270, 460, 1266, + 462, 402, 516, 346, 460, 404, 460, 402, 488, 376, 458, 404, + 460, 402, 460, 400, + 460, 10794, + 3520, 1684, + 464, 400, 462, 402, 460, 400, 462, 1268, 462, 402, 462, 1270, + 458, 402, 462, 402, 460, 1268, 462, 402, 460, 402, 460, 404, + 460, 402, 462, 1268, 462, 1268, 460, 384, 480, 1266, 462, 404, + 458, 1272, 458, 1268, 462, 402, 460, 402, 460, 1270, 460, 1268, + 462, 1268, 462, 1266, 464, 1266, 462, 1266, 462, 1268, 462, 1268, + 488, 1240, 486, 1242, 466, 400, 462, 402, 460, 400, 460, 404, + 462, 398, 486, 380, 458, 406, 458, 404, 458, 1268, 436, 1292, + 462, 1268, 462, 1268, 460, 1272, 460, 1268, 486, 1242, 460, 1270, + 462, 400, 460, 404, 436, 428, 464, 398, 460, 402, 462, 404, + 458, 404, 458, 404, + 458}; // UNKNOWN 881F925B * 26C + const uint8_t expectedState_26C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1A, 0xE5, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_26C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_26C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 26C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_30C[347] = { + 3520, 1688, + 462, 400, 460, 404, 460, 404, 456, 1270, 462, 402, 462, 1266, + 490, 374, 464, 398, 462, 1266, 464, 400, 460, 402, 490, 376, + 460, 402, 462, 1248, 478, 1268, 462, 382, 534, 1214, 462, 402, + 458, 1268, 464, 1266, 458, 1270, 462, 1266, 462, 400, 464, 400, + 464, 1264, 462, 406, 456, 402, 460, 1268, 462, 1266, 462, 404, + 460, 402, 462, 400, 462, 404, 458, 1270, 464, 1266, 460, 402, + 462, 402, 434, 1294, 462, 1248, 480, 1270, 490, 372, 462, 1272, + 456, 1268, 464, 1268, 458, 1268, 464, 400, 464, 400, 460, 402, + 462, 1268, 462, 398, 462, 402, 458, 404, 462, 400, 462, 1266, + 438, 1292, 462, 1270, + 460, 10790, + 3520, 1684, + 462, 402, 462, 402, 458, 404, 458, 1272, 462, 400, 460, 1270, + 462, 400, 436, 428, 484, 1244, 462, 380, 482, 402, 486, 376, + 490, 372, 462, 1266, 460, 1270, 462, 402, 460, 1268, 490, 372, + 460, 1270, 460, 1268, 488, 378, 458, 1268, 436, 1296, 488, 374, + 462, 1268, 434, 1292, 462, 1268, 460, 1268, 460, 1270, 436, 1292, + 460, 1268, 462, 1270, 456, 404, 460, 402, 464, 398, 460, 402, + 462, 402, 486, 374, 460, 402, 460, 404, 460, 1270, 460, 1268, + 460, 1268, 462, 1266, 460, 1268, 460, 1268, 462, 1268, 462, 1250, + 504, 376, 462, 400, 436, 428, 458, 404, 460, 400, 462, 406, + 458, 400, 460, 384, + 478, 10796, + 3570, 1632, + 464, 400, 458, 406, 456, 404, 486, 1242, 460, 384, 482, 1264, + 462, 402, 460, 402, 458, 1270, 462, 402, 462, 402, 460, 402, + 462, 400, 490, 1240, 486, 1242, 438, 424, 488, 1242, 462, 402, + 458, 1270, 462, 1266, 464, 400, 460, 404, 462, 1268, 458, 1270, + 462, 1266, 462, 1266, 462, 1270, 460, 1266, 462, 1268, 460, 1268, + 462, 1250, 478, 1268, 464, 400, 462, 404, 458, 400, 488, 378, + 458, 402, 488, 374, 462, 404, 512, 350, 460, 1270, 488, 1242, + 488, 1240, 462, 1266, 464, 1264, 490, 1240, 490, 1240, 462, 1266, + 462, 400, 462, 400, 460, 404, 460, 402, 462, 400, 460, 404, + 458, 382, 480, 402, + 462}; // UNKNOWN B0D0585F * 30C + const uint8_t expectedState_30C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1E, 0xE1, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_30C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_30C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 30C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestDecodeCoronaAc, RealExample2) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + const uint16_t rawData_TOn5[347] = { + 3520, 1684, + 436, 452, 410, 412, 476, 430, 434, 1294, 410, 454, 406, 1296, + 458, 430, 436, 424, 436, 1270, 434, 454, 408, 454, 410, 454, + 434, 428, 434, 1296, 436, 1270, 432, 454, 462, 1268, 434, 386, + 452, 1320, 434, 1270, 434, 1294, 458, 1272, 458, 428, 410, 452, + 436, 1268, 434, 412, 450, 454, 434, 1270, 458, 1274, 456, 388, + 476, 426, 410, 454, 408, 454, 410, 1318, 410, 1296, 458, 430, + 408, 412, 452, 1322, 430, 1298, 434, 1296, 434, 434, 428, 1272, + 458, 1296, 410, 1296, 460, 1294, 432, 430, 408, 452, 434, 430, + 408, 1296, 458, 386, 478, 428, 410, 454, 434, 428, 434, 1272, + 456, 1294, 432, 1272, + 458, 10794, + 3518, 1684, + 464, 426, 410, 454, 488, 374, 434, 1296, 436, 382, 452, 1320, + 436, 428, 406, 454, 410, 1296, 458, 384, 482, 384, 454, 450, + 434, 386, 478, 1268, 460, 1298, 404, 454, 434, 1270, 458, 430, + 410, 1292, 462, 1296, 436, 426, 436, 1270, 434, 1320, 430, 388, + 476, 384, 478, 386, 452, 454, 434, 1294, 412, 452, 432, 1270, + 434, 456, 406, 456, 410, 1292, 460, 1272, 460, 1266, 462, 428, + 434, 1294, 434, 430, 434, 1294, 434, 1272, 460, 1266, 464, 1292, + 438, 426, 434, 428, 408, 432, 460, 1294, 436, 384, 452, 454, + 410, 454, 436, 426, 436, 1270, 458, 1296, 410, 1322, 432, 430, + 434, 1294, 408, 1322, + 436, 10812, + 3478, 1736, + 406, 416, 472, 430, 410, 452, 410, 1322, 408, 454, 436, 1270, + 434, 454, 410, 408, 478, 1268, 460, 430, 434, 428, 408, 454, + 432, 406, 432, 1322, 432, 1296, 434, 430, 408, 1294, 458, 430, + 406, 1322, 434, 1272, 460, 426, 438, 426, 408, 1320, 408, 1296, + 460, 1270, 434, 1296, 434, 1322, 406, 1320, 434, 1252, 476, 1296, + 438, 1268, 432, 1296, 488, 400, 410, 410, 476, 430, 432, 386, + 452, 410, 458, 420, 488, 400, 436, 428, 434, 1294, 408, 1296, + 460, 1294, 410, 1296, 458, 1270, 432, 1298, 432, 1296, 434, 1296, + 460, 428, 408, 452, 462, 402, 432, 430, 406, 430, 438, 450, + 408, 454, 410, 454, + 412}; // UNKNOWN 96CCC404 * On Timer 5H 30C + const uint8_t expectedState_TOn5[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1E, 0xE1, + 0x28, 0x61, 0x6D, 0x28, 0xD7, 0x23, 0xDC, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_TOn5, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_TOn5, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 30C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: 05:00, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_TOn1[347] = { + 3522, 1684, + 462, 428, 434, 426, 434, 428, 408, 1296, 462, 424, 436, 1266, + 464, 402, 488, 400, 440, 1264, 460, 402, 434, 454, 434, 404, + 460, 404, 460, 1264, 464, 1268, 460, 404, 460, 1266, 462, 404, + 434, 1294, 436, 1292, 464, 1268, 460, 1268, 462, 402, 460, 402, + 458, 1268, 462, 404, 434, 452, 436, 1266, 462, 1268, 462, 402, + 462, 400, 462, 428, 436, 400, 460, 1266, 490, 1240, 492, 372, + 488, 376, 458, 1270, 486, 1242, 464, 1266, 460, 402, 462, 1266, + 464, 1268, 462, 1266, 464, 1270, 462, 396, 464, 400, 460, 402, + 436, 1292, 464, 402, 462, 400, 434, 428, 486, 378, 460, 1266, + 462, 1268, 460, 1266, + 464, 10804, + 3506, 1682, + 462, 402, 462, 400, 460, 428, 438, 1268, 460, 428, 462, 1242, + 460, 428, 436, 400, 462, 1268, 460, 428, 436, 400, 460, 430, + 466, 368, 464, 1266, 438, 1292, 462, 400, 462, 1268, 462, 426, + 410, 1296, 460, 1266, 464, 398, 490, 1242, 488, 1238, 462, 428, + 438, 424, 436, 400, 462, 404, 460, 1266, 462, 404, 460, 404, + 460, 402, 460, 402, 464, 1264, 464, 1264, 464, 1266, 488, 376, + 464, 1266, 458, 1268, 464, 1264, 462, 1266, 466, 1264, 488, 1244, + 462, 1262, 468, 422, 434, 402, 464, 402, 462, 400, 462, 424, + 438, 400, 462, 402, 462, 402, 486, 1242, 460, 1268, 464, 1264, + 436, 1292, 462, 1268, + 460, 10810, + 3504, 1684, + 462, 428, 436, 398, 492, 374, 460, 1268, 462, 404, 462, 1264, + 462, 404, 460, 400, 460, 1266, 490, 400, 438, 424, 438, 400, + 462, 428, 410, 1292, 464, 1268, 460, 428, 460, 1242, 464, 402, + 460, 1266, 460, 1270, 462, 426, 462, 402, 412, 1272, 482, 1266, + 436, 1292, 436, 1294, 462, 1268, 462, 1266, 464, 1264, 464, 1270, + 488, 1238, 464, 1266, 464, 396, 464, 426, 438, 402, 458, 402, + 464, 398, 462, 430, 408, 426, 460, 428, 492, 1210, 440, 1292, + 464, 1266, 438, 1292, 460, 1266, 464, 1266, 464, 1268, 460, 1266, + 438, 430, 458, 402, 458, 406, 460, 406, 456, 400, 434, 426, + 464, 400, 460, 402, + 462}; // UNKNOWN 446E2F48 * On Timer 1H 30C + const uint8_t expectedState_TOn1[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1E, 0xE1, + 0x28, 0x61, 0x6D, 0x08, 0xF7, 0x07, 0xF8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_TOn1, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_TOn1, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 30C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: 01:00, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_TOn2[347] = { + 3516, 1716, + 410, 452, 408, 454, 412, 450, 434, 1270, 460, 430, 432, 1272, + 456, 406, 460, 384, 452, 1298, 458, 428, 406, 456, 436, 428, + 434, 430, 432, 1298, 434, 1298, 408, 428, 458, 1298, 432, 430, + 434, 1294, 434, 1296, 432, 1272, 458, 1296, 408, 454, 436, 428, + 436, 1268, 458, 430, 436, 428, 434, 1272, 432, 1320, 460, 402, + 410, 454, 432, 388, 474, 388, 452, 1296, 460, 1270, 458, 386, + 450, 412, 478, 1296, 430, 1272, 458, 1298, 434, 428, 434, 1254, + 474, 1296, 410, 1320, 434, 1270, 460, 384, 478, 428, 434, 428, + 434, 1272, 460, 384, 478, 428, 432, 430, 434, 428, 410, 1296, + 458, 1274, 454, 1270, + 460, 10810, + 3500, 1716, + 432, 430, 408, 452, 434, 430, 410, 1294, 456, 428, 434, 1298, + 408, 432, 544, 314, 462, 1270, 430, 454, 436, 430, 458, 404, + 432, 386, 478, 1268, 460, 1270, 458, 388, 450, 1322, 430, 434, + 458, 1268, 434, 1294, 410, 454, 434, 1270, 460, 1294, 432, 430, + 410, 454, 434, 428, 406, 456, 432, 430, 408, 1320, 408, 456, + 432, 430, 434, 428, 410, 1294, 434, 1294, 486, 1268, 432, 1272, + 460, 426, 414, 1292, 462, 1294, 432, 1298, 430, 388, 478, 1296, + 408, 1296, 458, 1270, 458, 386, 452, 456, 408, 454, 436, 426, + 434, 1272, 432, 430, 458, 430, 434, 430, 406, 1320, 436, 1294, + 434, 1296, 410, 1320, + 434, 10812, + 3504, 1686, + 432, 452, 434, 430, 436, 428, 406, 1296, 460, 404, 460, 1292, + 436, 428, 436, 428, 436, 1268, 436, 454, 412, 452, 408, 454, + 434, 428, 408, 1296, 462, 1266, 462, 384, 480, 1266, 458, 430, + 410, 1320, 434, 1270, 434, 428, 436, 452, 412, 1294, 432, 1320, + 432, 1274, 458, 1270, 434, 1294, 460, 1270, 460, 1296, 434, 1268, + 436, 1294, 434, 1296, 460, 430, 434, 424, 436, 428, 434, 426, + 410, 410, 478, 430, 432, 408, 456, 428, 408, 1298, 458, 1268, + 436, 1296, 460, 1292, 462, 1268, 436, 1270, 460, 1294, 434, 1294, + 436, 402, 488, 400, 408, 456, 432, 386, 478, 428, 408, 452, + 408, 456, 410, 454, + 406}; // UNKNOWN D49AF170 * On Timer 2H 30C + const uint8_t expectedState_TOn2[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1E, 0xE1, + 0x28, 0x61, 0x6D, 0x10, 0xEF, 0x0E, 0xF1, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_TOn2, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_TOn2, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 30C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: 02:00, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_21C2[347] = { + 3522, 1682, + 438, 426, 460, 402, 462, 402, 434, 1296, 434, 426, 460, 1270, + 436, 430, 460, 400, 436, 1294, 462, 398, 436, 428, 462, 400, + 462, 400, 438, 1292, 460, 1270, 460, 404, 434, 1294, 462, 402, + 462, 1268, 434, 1294, 462, 1268, 490, 1240, 462, 400, 460, 404, + 460, 1268, 436, 426, 462, 402, 462, 1266, 460, 1268, 438, 428, + 458, 404, 460, 402, 462, 398, 462, 1272, 460, 1266, 462, 404, + 458, 402, 436, 1294, 460, 1268, 436, 1292, 464, 1266, 436, 428, + 462, 1268, 462, 400, 438, 1290, 460, 404, 460, 402, 462, 404, + 434, 424, 462, 1268, 436, 426, 462, 1272, 456, 404, 460, 1270, + 434, 1292, 438, 1292, + 462, 10786, + 3498, 1714, + 458, 404, 458, 402, 462, 400, 464, 1264, 466, 398, 462, 1266, + 438, 428, 436, 424, 462, 1266, 490, 374, 436, 424, 436, 428, + 434, 426, 464, 1266, 464, 1268, 434, 428, 462, 1266, 466, 396, + 436, 1294, 462, 1270, 460, 402, 460, 1266, 462, 1268, 460, 404, + 458, 1270, 434, 1294, 460, 1268, 464, 1266, 462, 1266, 464, 1266, + 462, 1268, 462, 1266, 464, 400, 434, 426, 438, 426, 460, 402, + 436, 426, 464, 400, 470, 370, 486, 398, 464, 1264, 440, 1292, + 462, 1266, 464, 1266, 464, 1266, 462, 1266, 462, 1268, 460, 1270, + 462, 398, 462, 400, 438, 426, 462, 400, 462, 402, 434, 430, + 458, 402, 460, 400, + 436, 10820, + 3496, 1708, + 462, 402, 464, 400, 438, 422, 438, 1294, 460, 400, 462, 1266, + 464, 400, 462, 400, 464, 1266, 462, 402, 436, 426, 460, 404, + 436, 426, 462, 1266, 436, 1294, 462, 400, 462, 1266, 462, 400, + 460, 1268, 464, 1266, 462, 402, 436, 426, 436, 1294, 436, 1294, + 438, 1290, 462, 1268, 462, 1266, 436, 1292, 462, 1268, 460, 1248, + 482, 1268, 462, 1270, 458, 404, 434, 426, 464, 400, 460, 406, + 434, 426, 462, 402, 460, 384, 480, 400, 436, 1294, 460, 1268, + 492, 1238, 462, 1268, 460, 1272, 434, 1292, 462, 1266, 438, 1292, + 464, 400, 462, 400, 436, 426, 438, 424, 488, 374, 462, 402, + 462, 400, 464, 400, + 438}; // UNKNOWN D1869C5B * 21C + const uint8_t expectedState_21C2[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x15, 0xEA, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_21C2, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_21C2, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 21C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_20C2[347] = { + 3498, 1708, + 436, 430, 434, 426, 464, 398, 460, 1268, 456, 388, 482, 1266, + 436, 426, 436, 426, 438, 1292, 436, 426, 436, 428, 436, 424, + 460, 404, 436, 1290, 438, 1292, 462, 404, 434, 1292, 438, 426, + 462, 1266, 516, 1212, 438, 1292, 436, 1292, 438, 424, 438, 424, + 462, 1268, 438, 424, 436, 426, 438, 1292, 460, 1268, 460, 402, + 436, 428, 436, 426, 438, 426, 434, 1294, 436, 1294, 436, 428, + 436, 426, 464, 1264, 436, 1274, 484, 1264, 440, 424, 460, 402, + 438, 1292, 434, 426, 438, 1292, 436, 428, 436, 426, 464, 398, + 492, 1238, 438, 1292, 436, 428, 460, 1248, 456, 426, 438, 1294, + 434, 1296, 434, 1296, + 434, 10812, + 3498, 1710, + 436, 428, 434, 426, 438, 424, 438, 1294, 438, 424, 438, 1292, + 434, 426, 442, 420, 438, 1290, 438, 426, 466, 396, 462, 400, + 436, 428, 436, 1294, 438, 1290, 466, 398, 436, 1294, 436, 426, + 460, 1268, 462, 1268, 436, 426, 438, 1290, 438, 1294, 462, 402, + 462, 1266, 462, 1266, 462, 1266, 436, 1294, 440, 1290, 464, 1266, + 436, 1292, 436, 1294, 436, 426, 462, 400, 438, 424, 436, 426, + 462, 400, 438, 426, 462, 400, 436, 426, 438, 1292, 438, 1292, + 438, 1292, 462, 1266, 438, 1270, 458, 1292, 438, 1294, 462, 1266, + 438, 428, 434, 426, 464, 398, 436, 426, 436, 428, 436, 426, + 492, 370, 438, 426, + 436, 10818, + 3492, 1712, + 462, 402, 460, 402, 438, 426, 440, 1292, 436, 424, 464, 1266, + 438, 424, 462, 400, 438, 1288, 438, 428, 434, 428, 486, 376, + 462, 402, 434, 1292, 436, 1292, 438, 424, 462, 1268, 436, 426, + 438, 1294, 462, 1266, 436, 428, 436, 424, 438, 1292, 438, 1290, + 440, 1292, 434, 1294, 436, 1294, 436, 1294, 514, 1212, 438, 1292, + 436, 1296, 458, 1268, 438, 424, 460, 404, 460, 400, 462, 400, + 462, 400, 438, 426, 434, 430, 434, 426, 466, 1266, 464, 1262, + 436, 1294, 434, 1294, 464, 1266, 464, 1264, 460, 1268, 464, 1266, + 462, 404, 460, 402, 436, 428, 434, 428, 436, 428, 462, 400, + 462, 400, 462, 400, + 464}; // UNKNOWN 27CBC9D7 * 20C + const uint8_t expectedState_20C2[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x14, 0xEB, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_20C2, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_20C2, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 20C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_Off2[347] = { + 3522, 1684, + 436, 428, 460, 404, 436, 424, 464, 1266, 436, 426, 462, 1270, + 452, 390, 480, 404, 462, 1268, 436, 424, 462, 402, 462, 400, + 434, 428, 436, 1292, 462, 1268, 462, 402, 460, 1268, 460, 402, + 436, 1292, 462, 1266, 436, 1294, 438, 1292, 436, 426, 460, 402, + 462, 1268, 438, 424, 462, 400, 462, 1270, 458, 1270, 436, 428, + 458, 404, 460, 400, 436, 426, 464, 1268, 460, 1266, 464, 398, + 464, 398, 462, 1270, 434, 1292, 438, 1292, 460, 404, 436, 1296, + 458, 402, 462, 402, 460, 404, 460, 1268, 460, 402, 436, 426, + 434, 1274, 482, 400, 438, 1292, 490, 1240, 462, 1268, 460, 402, + 436, 1292, 438, 1294, + 460, 10808, + 3474, 1692, + 482, 400, 462, 402, 460, 402, 460, 1268, 464, 400, 488, 1240, + 462, 400, 462, 402, 460, 1270, 434, 426, 462, 402, 462, 402, + 462, 400, 462, 1268, 462, 1266, 462, 400, 436, 1294, 460, 402, + 436, 1292, 438, 1292, 436, 428, 460, 1268, 462, 1268, 436, 428, + 438, 1290, 466, 1266, 462, 1266, 464, 1266, 460, 1268, 462, 1268, + 436, 1292, 462, 1266, 452, 390, 482, 400, 436, 428, 462, 400, + 464, 400, 462, 402, 434, 428, 460, 402, 462, 1266, 462, 1266, + 462, 1270, 436, 1294, 460, 1268, 460, 1268, 438, 1296, 432, 1294, + 464, 398, 462, 402, 434, 430, 460, 400, 462, 400, 460, 402, + 460, 402, 438, 426, + 436, 10816, + 3522, 1686, + 436, 428, 434, 426, 464, 400, 460, 1270, 460, 400, 438, 1294, + 460, 400, 464, 400, 438, 1296, 436, 424, 460, 402, 460, 402, + 464, 400, 462, 1266, 438, 1292, 462, 402, 434, 1296, 432, 428, + 460, 1270, 462, 1266, 436, 428, 436, 428, 458, 1268, 438, 1290, + 438, 1292, 460, 1270, 434, 1294, 460, 1268, 462, 1246, 456, 1294, + 438, 1290, 460, 1268, 446, 388, 490, 400, 436, 426, 462, 400, + 438, 424, 462, 402, 436, 428, 434, 430, 460, 1270, 458, 1266, + 462, 1268, 438, 1292, 438, 1290, 436, 1294, 462, 1268, 462, 1266, + 460, 404, 434, 428, 460, 400, 462, 402, 436, 426, 434, 428, + 434, 426, 438, 430, + 458}; // UNKNOWN FBD27697 * OFF + const uint8_t expectedState_Off2[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x22, 0xDD, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_Off2, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_Off2, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: Off, Power Button: On, Mode: 0 (Heat), Temp: 18C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_U[347] = { + 3520, 1686, + 462, 402, 460, 402, 462, 402, 436, 1276, 478, 402, 462, 1266, + 464, 400, 460, 402, 462, 1268, 452, 392, 478, 402, 464, 380, + 480, 404, 432, 1296, 462, 1266, 460, 404, 460, 1270, 460, 402, + 460, 1270, 458, 1270, 460, 1270, 456, 1270, 462, 402, 460, 402, + 460, 1270, 460, 400, 464, 400, 460, 1268, 464, 1264, 462, 404, + 458, 402, 434, 428, 464, 402, 456, 1270, 462, 1270, 460, 404, + 458, 402, 438, 1292, 460, 1268, 464, 1266, 464, 1264, 462, 404, + 458, 1272, 458, 1270, 460, 1268, 464, 402, 458, 402, 462, 400, + 462, 400, 462, 1270, 458, 406, 430, 430, 458, 400, 462, 1270, + 460, 1266, 464, 1266, + 462, 10790, + 3520, 1682, + 462, 404, 434, 428, 464, 400, 460, 1270, 460, 400, 464, 1266, + 462, 404, 460, 402, 464, 1264, 460, 406, 460, 402, 458, 406, + 460, 402, 458, 1270, 464, 1266, 460, 404, 460, 1270, 462, 402, + 488, 1240, 460, 1268, 462, 400, 462, 1268, 462, 1266, 462, 400, + 462, 1268, 460, 1250, 482, 1266, 462, 1270, 462, 1266, 462, 1268, + 458, 1270, 462, 1268, 460, 400, 462, 402, 460, 400, 462, 402, + 462, 398, 462, 404, 486, 374, 460, 404, 458, 1270, 460, 1270, + 486, 1244, 458, 1270, 464, 1266, 460, 1268, 462, 1268, 460, 1270, + 462, 400, 460, 406, 458, 402, 462, 400, 462, 404, 458, 400, + 516, 350, 458, 402, + 462, 10794, + 3520, 1684, + 460, 402, 460, 402, 460, 406, 460, 1268, 458, 406, 458, 1268, + 462, 400, 464, 400, 460, 1268, 462, 402, 460, 402, 464, 426, + 436, 400, 462, 1264, 462, 1270, 460, 402, 460, 1266, 464, 400, + 460, 1268, 464, 1266, 460, 406, 456, 404, 462, 1268, 462, 1268, + 460, 1266, 490, 1240, 464, 1266, 460, 1270, 438, 1294, 460, 1250, + 478, 1266, 462, 1270, 460, 404, 462, 400, 462, 400, 462, 402, + 462, 398, 460, 404, 460, 402, 460, 402, 460, 1268, 460, 1270, + 460, 1272, 458, 1270, 460, 1268, 464, 1268, 434, 1296, 462, 1266, + 464, 398, 462, 402, 434, 426, 462, 404, 460, 402, 462, 404, + 456, 406, 460, 400, + 462}; // UNKNOWN 2D1BA8F7 * unk + const uint8_t expectedState_U[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_U, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_U, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 29C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestDecodeCoronaAc, RealExampleShort) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + const uint16_t rawData_A1[115] = { + 3548, 1658, + 462, 400, 464, 424, 436, 428, 436, 1272, 460, 400, 462, 1266, + 464, 426, 436, 426, 434, 1270, 432, 454, 436, 402, 460, 384, + 482, 400, 486, 1244, 460, 1268, 462, 404, 484, 1242, 460, 428, + 460, 1250, 430, 1292, 462, 1266, 464, 404, 456, 384, 480, 1266, + 462, 428, 436, 1270, 460, 1268, 462, 428, 434, 1270, 460, 430, + 434, 404, 460, 1294, 460, 1242, 462, 382, 478, 428, 436, 1268, + 458, 406, 460, 1268, 460, 1268, 460, 404, 458, 404, 434, 430, + 462, 426, 434, 430, 432, 1268, 462, 426, 436, 402, 460, 404, + 458, 1268, 464, 1270, 432, 1294, 464, 1266, 458, 404, 462, 1268, + 460, 1268, 464, 1266, + 462}; // UNKNOWN AEDD5409 * Auto1 + const uint8_t expectedState_A1[kCoronaAcStateLengthShort] = { + 0x28, 0x61, 0x9D, 0x96, 0x69, 0x10, 0xEF}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_A1, 115, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBitsShort, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_A1, irsend.capture.state, irsend.capture.bits); + // this is special, but showing what it might be + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 16C, " + "Fan: 2 (Medium), Swing(V) Toggle: Off, Econo: Off, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestDecodeCoronaAc, SyntheticExample1) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + const uint8_t state[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(state); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + EXPECT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(state, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 29C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + EXPECT_EQ( + "f38000d50" + "m3500s1680" + "m450s420m450s420m450s420m450s1270m450s420m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s420m450s420m450s1270m450s1270m450s420" + "m450s1270m450s420m450s1270m450s1270m450s1270m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s1270m450s1270m450s420m450s420m450s420" + "m450s420m450s1270m450s1270m450s420m450s420m450s1270m450s1270m450s1270" + "m450s1270m450s420m450s1270m450s1270m450s1270m450s420m450s420m450s420" + "m450s420m450s1270m450s420m450s420m450s420m450s1270m450s1270m450s1270" + "m450s10800" + "m3500s1680" + "m450s420m450s420m450s420m450s1270m450s420m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s420m450s420m450s1270m450s1270m450s420" + "m450s1270m450s420m450s1270m450s1270m450s420m450s1270m450s1270m450s420" + "m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270" + "m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420" + "m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270" + "m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420" + "m450s10800" + "m3500s1680" + "m450s420m450s420m450s420m450s1270m450s420m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s420m450s420m450s1270m450s1270m450s420" + "m450s1270m450s420m450s1270m450s1270m450s420m450s420m450s1270m450s1270" + "m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270" + "m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420" + "m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270" + "m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420" + "m450s10800", + irsend.outputStr()); + + irsend.reset(); + const uint8_t stateShort[kCoronaAcStateLengthShort] = { + 0x28, 0x61, 0x9D, 0x96, 0x69, 0x10, 0xEF}; + irsend.sendCoronaAc(stateShort, kCoronaAcStateLengthShort); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBitsShort, irsend.capture.bits); + EXPECT_STATE_EQ(stateShort, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 16C, " + "Fan: 2 (Medium), Swing(V) Toggle: Off, Econo: Off, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + EXPECT_EQ( + "f38000d50" + "m3500s1680" + "m450s420m450s420m450s420m450s1270m450s420m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s420m450s420m450s1270m450s1270m450s420" + "m450s1270m450s420m450s1270m450s1270m450s1270m450s420m450s420m450s1270" + "m450s420m450s1270m450s1270m450s420m450s1270m450s420m450s420m450s1270" + "m450s1270m450s420m450s420m450s1270m450s420m450s1270m450s1270m450s420" + "m450s420m450s420m450s420m450s420m450s1270m450s420m450s420m450s420" + "m450s1270m450s1270m450s1270m450s1270m450s420m450s1270m450s1270m450s1270" + "m450s10800", + irsend.outputStr()); +} + +TEST(TestDecodeCoronaAc, SyntheticExampleNonMatch) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + + // Test checksum and prefix + // first base example match + irsend.begin(); + irsend.reset(); + const uint8_t stateOk[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateOk); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona header section 1 + const uint8_t stateHeaderFail1[kCoronaAcStateLength] = { + 0x00, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateHeaderFail1); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona header section 1 b2 + const uint8_t stateHeaderFail12[kCoronaAcStateLength] = { + 0x28, 0x00, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateHeaderFail12); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona section number + const uint8_t stateSection1NumFail[kCoronaAcStateLength] = { + 0x28, 0x61, 0x2D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateSection1NumFail); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona invert D0 + const uint8_t stateInvertD0Fail[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0x19, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateInvertD0Fail); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona invert D1 + const uint8_t stateInvertD1Fail[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0x1D, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateInvertD1Fail); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("CORONA_AC", typeToString(decode_type_t::CORONA_AC)); + ASSERT_EQ(decode_type_t::CORONA_AC, strToDecodeType("CORONA_AC")); + ASSERT_TRUE(hasACState(decode_type_t::CORONA_AC)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::CORONA_AC)); + ASSERT_EQ(kCoronaAcBits, IRsend::defaultBits(decode_type_t::CORONA_AC)); + ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::CORONA_AC)); + ASSERT_EQ(kCoronaAcStateLength, 7 * 3); + ASSERT_EQ(kCoronaAcStateLengthShort, 7); + ASSERT_EQ(kCoronaAcSectionBytes, 7); + ASSERT_EQ(kCoronaAcSections, 3); +} + +// Tests for IRCoronaAc class. + +TEST(TestCoronaAcClass, Power) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + + ac.on(); + EXPECT_TRUE(ac.getPower()); + EXPECT_TRUE(ac.getPowerButton()); + + ac.off(); + EXPECT_FALSE(ac.getPower()); + EXPECT_TRUE(ac.getPowerButton()); + + ac.setOnTimer(60); + EXPECT_FALSE(ac.getPowerButton()); + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); + EXPECT_EQ(0, ac.getOnTimer()); + EXPECT_FALSE(ac.getPowerButton()); + + ac.setOffTimer(60); + EXPECT_FALSE(ac.getPowerButton()); + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); + EXPECT_EQ(0, ac.getOffTimer()); + EXPECT_FALSE(ac.getPowerButton()); + + ASSERT_EQ(4, kCoronaAcPowerOffset); + ASSERT_EQ(5, kCoronaAcPowerButtonOffset); +} + +TEST(TestCoronaAcClass, Temperature) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + + ac.setTemp(0); + EXPECT_EQ(kCoronaAcMinTemp, ac.getTemp()); + + ac.setTemp(255); + EXPECT_EQ(kCoronaAcMaxTemp, ac.getTemp()); + + ac.setTemp(kCoronaAcMinTemp); + EXPECT_EQ(kCoronaAcMinTemp, ac.getTemp()); + + ac.setTemp(kCoronaAcMaxTemp); + EXPECT_EQ(kCoronaAcMaxTemp, ac.getTemp()); + + ac.setTemp(kCoronaAcMinTemp - 1); + EXPECT_EQ(kCoronaAcMinTemp, ac.getTemp()); + + ac.setTemp(kCoronaAcMaxTemp + 1); + EXPECT_EQ(kCoronaAcMaxTemp, ac.getTemp()); + + ac.setTemp(17); + EXPECT_EQ(17, ac.getTemp()); + + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); + + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); + + ac.setTemp(29); + EXPECT_EQ(29, ac.getTemp()); +} + +TEST(TestCoronaAcClass, OperatingMode) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + + ac.setMode(kCoronaAcModeCool); + EXPECT_EQ(kCoronaAcModeCool, ac.getMode()); + + ac.setMode(kCoronaAcModeFan); + EXPECT_EQ(kCoronaAcModeFan, ac.getMode()); + + ac.setMode(kCoronaAcModeHeat); + EXPECT_EQ(kCoronaAcModeHeat, ac.getMode()); + + ac.setMode(kCoronaAcModeFan + 1); + EXPECT_EQ(kCoronaAcModeCool, ac.getMode()); + + ac.setMode(255); + EXPECT_EQ(kCoronaAcModeCool, ac.getMode()); + ac.setMode(0); + EXPECT_EQ(kCoronaAcModeHeat, ac.getMode()); +} + +TEST(TestCoronaAcClass, EconoPowerSave) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + ac.setEcono(true); + EXPECT_TRUE(ac.getEcono()); + ac.setEcono(false); + EXPECT_FALSE(ac.getEcono()); + ac.setEcono(true); + EXPECT_TRUE(ac.getEcono()); +} + +TEST(TestCoronaAcClass, SwingVerticalToggle) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + ac.setSwingVToggle(true); + EXPECT_TRUE(ac.getSwingVToggle()); + ac.setSwingVToggle(false); + EXPECT_FALSE(ac.getSwingVToggle()); + ac.setSwingVToggle(true); + EXPECT_TRUE(ac.getSwingVToggle()); +} + +TEST(TestCoronaAcClass, Timer) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + ac.setPowerButton(false); + ac.setMode(kCoronaAcModeHeat); + const uint8_t expectedStateNoTimer[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x10, 0xEF, 0x01, 0xFE, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + ASSERT_FALSE(ac.getPower()); + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateNoTimer, ac.getRaw(), kCoronaAcBits); + + ac.setOnTimer(3 * 60); + EXPECT_EQ(3 * 60, ac.getOnTimer()); + const uint8_t expectedStateOnTimer3H[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x10, 0xEF, 0x11, 0xEE, + 0x28, 0x61, 0x6D, 0x18, 0xE7, 0x15, 0xEA, // 5400 + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + ASSERT_TRUE(ac.getPower()); // remote should be on from timer + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateOnTimer3H, ac.getRaw(), kCoronaAcBits); + + ac.setOnTimer(0); + EXPECT_EQ(0, ac.getOnTimer()); + ASSERT_FALSE(ac.getPowerButton()); + ASSERT_TRUE(ac.getPower()); // remote should still be on + ac.off(); // set it to off + EXPECT_STATE_EQ(expectedStateNoTimer, ac.getRaw(), kCoronaAcBits); + ac.setOnTimer(kCoronaAcTimerOff); + EXPECT_EQ(0, ac.getOnTimer()); + EXPECT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateNoTimer, ac.getRaw(), kCoronaAcBits); + + ac.setOffTimer(1); + EXPECT_EQ(1, ac.getOffTimer()); + ASSERT_TRUE(ac.getPower()); // remote should be on from timer + const uint8_t expectedStateOffTimer1m[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x10, 0xEF, 0x11, 0xEE, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0x1E, 0xE1, 0x00, 0xFF}; // 30 + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateOffTimer1m, ac.getRaw(), kCoronaAcBits); + + ac.setOnTimer(2); + EXPECT_EQ(2, ac.getOnTimer()); + ASSERT_TRUE(ac.getPower()); // remote should be on from timer + // setting any of the timers needs to reset the other one + ASSERT_EQ(0, ac.getOffTimer()); + const uint8_t expectedStateOnTimer2m[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x10, 0xEF, 0x11, 0xEE, + 0x28, 0x61, 0x6D, 0x3C, 0xC3, 0x00, 0xFF, // 60 + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateOnTimer2m, ac.getRaw(), kCoronaAcBits); + + // setting a higher value than max should instead disable + ac.setOnTimer(kCoronaAcTimerMax + 1); + ASSERT_EQ(0, ac.getOnTimer()); + ASSERT_FALSE(ac.getPowerButton()); + ASSERT_TRUE(ac.getPower()); // remote should still be on + ac.off(); + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateNoTimer, ac.getRaw(), kCoronaAcBits); +} + + +TEST(TestCoronaAcClass, FanSpeed) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + + // Unexpected value should default to Auto. + ac.setFan(255); + EXPECT_EQ(kCoronaAcFanAuto, ac.getFan()); + ac.setFan(5); + EXPECT_EQ(kCoronaAcFanAuto, ac.getFan()); + + ac.setFan(kCoronaAcFanHigh); + EXPECT_EQ(kCoronaAcFanHigh, ac.getFan()); + + // Beyond High should default to Auto. + ac.setFan(kCoronaAcFanHigh + 1); + EXPECT_EQ(kCoronaAcFanAuto, ac.getFan()); + + ac.setFan(kCoronaAcFanMedium); + EXPECT_EQ(kCoronaAcFanMedium, ac.getFan()); + + ac.setFan(kCoronaAcFanLow); + EXPECT_EQ(kCoronaAcFanLow, ac.getFan()); + + ac.setFan(kCoronaAcFanAuto); + EXPECT_EQ(kCoronaAcFanAuto, ac.getFan()); +} + +// Test human readable output. +TEST(TestCoronaAcClass, HumanReadable) { + IRCoronaAc ac(kGpioUnused); + EXPECT_EQ( + "Power: Off, Power Button: On, Mode: 2 (Cool), Temp: 17C, " + "Fan: 0 (Auto), Swing(V) Toggle: Off, Econo: Off, " + "On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setPower(true); + ac.setMode(kCoronaAcModeFan); + ac.setTemp(30); + ac.setFan(kCoronaAcFanAuto); + ac.setSwingVToggle(true); + EXPECT_EQ( + "Power: On, Power Button: On, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: Off, " + "On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setOffTimer(8 * 60 + 37); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: Off, " + "On Timer: Off, Off Timer: 08:37", + ac.toString()); + ac.setOnTimer(5 * 60 + 59); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: Off, " + "On Timer: 05:59, Off Timer: Off", + ac.toString()); + ac.setOnTimer(59); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: Off, " + "On Timer: 00:59, Off Timer: Off", + ac.toString()); + ac.setEcono(true); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: On, " + "On Timer: 00:59, Off Timer: Off", + ac.toString()); +} + +TEST(TestCoronaAcClass, ReconstructKnownState) { + IRCoronaAc ac(kGpioUnused); + const uint8_t expectedState[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x59, 0xA6, 0xD3, 0x2C, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0x18, 0xE7, 0x15, 0xEA}; + ASSERT_TRUE(IRCoronaAc::validSection(expectedState, + 0 * kCoronaAcSectionBytes, 0)); + ASSERT_TRUE(IRCoronaAc::validSection(expectedState, + 1 * kCoronaAcSectionBytes, 1)); + ASSERT_TRUE(IRCoronaAc::validSection(expectedState, + 2 * kCoronaAcSectionBytes, 2)); + ac.begin(); + ac.stateReset(); + // ASSERT_STATE_NE(expectedState, ac.getRaw()); + ac.on(); + ac.setMode(kCoronaAcModeFan); + ac.setTemp(19); + ac.setFan(kCoronaAcFanLow); + ac.setSwingVToggle(true); + ac.setOffTimer(3 * 60); + ac.setEcono(true); + EXPECT_STATE_EQ(expectedState, ac.getRaw(), kCoronaAcBits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 19C, " + "Fan: 1 (Low), Swing(V) Toggle: On, Econo: On, " + "On Timer: Off, Off Timer: 03:00", + ac.toString()); +} + +TEST(TestCoronaAcClass, toCommon) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + ac.stateReset(); + ac.on(); + ac.setMode(kCoronaAcModeFan); + ac.setTemp(20); + ac.setFan(kCoronaAcFanLow); + ac.setSwingVToggle(true); + ac.setOffTimer(3 * 60); + ac.setEcono(true); + // Now test it. + ASSERT_EQ(decode_type_t::CORONA_AC, ac.toCommon().protocol); + ASSERT_EQ(-1, ac.toCommon().model); + ASSERT_TRUE(ac.toCommon().power); + ASSERT_TRUE(ac.toCommon().celsius); + ASSERT_EQ(20, ac.toCommon().degrees); + ASSERT_EQ(stdAc::opmode_t::kFan, ac.toCommon().mode); + ASSERT_EQ(stdAc::fanspeed_t::kLow, ac.toCommon().fanspeed); + ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv); + ASSERT_TRUE(ac.toCommon().econo); + // Unsupported. + ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh); + ASSERT_FALSE(ac.toCommon().turbo); + ASSERT_FALSE(ac.toCommon().quiet); + ASSERT_FALSE(ac.toCommon().clean); + ASSERT_FALSE(ac.toCommon().light); + ASSERT_FALSE(ac.toCommon().filter); + ASSERT_FALSE(ac.toCommon().beep); + ASSERT_EQ(-1, ac.toCommon().sleep); + ASSERT_EQ(-1, ac.toCommon().clock); +} diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Daikin_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Daikin_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Daikin_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Daikin_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Delonghi_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Delonghi_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Delonghi_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Delonghi_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Denon_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Denon_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Denon_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Denon_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Dish_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Dish_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Dish_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Dish_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Doshisha_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Doshisha_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Doshisha_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Doshisha_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Electra_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Electra_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Electra_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Electra_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Epson_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Epson_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Epson_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Epson_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Fujitsu_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Fujitsu_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Fujitsu_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Fujitsu_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_GICable_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_GICable_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_GICable_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_GICable_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_GlobalCache_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_GlobalCache_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_GlobalCache_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_GlobalCache_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Goodweather_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Goodweather_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Goodweather_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Goodweather_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Gree_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Gree_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Gree_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Gree_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Haier_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Haier_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Haier_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Haier_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Hitachi_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Hitachi_test.cpp similarity index 89% rename from lib/IRremoteESP8266-2.7.7/test/ir_Hitachi_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Hitachi_test.cpp index aef8008ff..2bbbd29e9 100644 --- a/lib/IRremoteESP8266-2.7.7/test/ir_Hitachi_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Hitachi_test.cpp @@ -811,16 +811,28 @@ TEST(TestUtils, Housekeeping) { ASSERT_EQ(decode_type_t::HITACHI_AC, strToDecodeType("HITACHI_AC")); ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC)); ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC)); + ASSERT_EQ(kHitachiAcBits, + IRsend::defaultBits(decode_type_t::HITACHI_AC)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC)); ASSERT_EQ("HITACHI_AC1", typeToString(decode_type_t::HITACHI_AC1)); ASSERT_EQ(decode_type_t::HITACHI_AC1, strToDecodeType("HITACHI_AC1")); ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC1)); ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC1)); + ASSERT_EQ(kHitachiAc1Bits, + IRsend::defaultBits(decode_type_t::HITACHI_AC1)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC1)); ASSERT_EQ("HITACHI_AC2", typeToString(decode_type_t::HITACHI_AC2)); ASSERT_EQ(decode_type_t::HITACHI_AC2, strToDecodeType("HITACHI_AC2")); ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC2)); ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC2)); + ASSERT_EQ(kHitachiAc2Bits, + IRsend::defaultBits(decode_type_t::HITACHI_AC2)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC2)); ASSERT_EQ("HITACHI_AC3", typeToString(decode_type_t::HITACHI_AC3)); ASSERT_EQ(decode_type_t::HITACHI_AC3, strToDecodeType("HITACHI_AC3")); @@ -831,6 +843,19 @@ TEST(TestUtils, Housekeeping) { ASSERT_EQ(decode_type_t::HITACHI_AC424, strToDecodeType("HITACHI_AC424")); ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC424)); ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC424)); + ASSERT_EQ(kHitachiAc424Bits, + IRsend::defaultBits(decode_type_t::HITACHI_AC424)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC424)); + + ASSERT_EQ("HITACHI_AC344", typeToString(decode_type_t::HITACHI_AC344)); + ASSERT_EQ(decode_type_t::HITACHI_AC344, strToDecodeType("HITACHI_AC344")); + ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC344)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC344)); + ASSERT_EQ(kHitachiAc344Bits, + IRsend::defaultBits(decode_type_t::HITACHI_AC344)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC344)); } // Decode a 'real' HitachiAc424 message. @@ -924,7 +949,7 @@ TEST(TestDecodeHitachiAc424, RealExample) { ac.setRaw(irsend.capture.state); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 23C, Fan: 5 (Auto), " - "Swing(V) Toggle: Off, Button: 19 (Power/Mode)", + "Button: 19 (Power/Mode), Swing(V) Toggle: Off", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); @@ -1099,29 +1124,29 @@ TEST(TestIRHitachiAc424Class, HumanReadable) { ac.setFan(kHitachiAc424FanHigh); EXPECT_EQ( "Power: On, Mode: 6 (Heat), Temp: 32C, Fan: 4 (High), " - "Swing(V) Toggle: Off, Button: 66 (Fan)", + "Button: 66 (Fan), Swing(V) Toggle: Off", ac.toString()); ac.setMode(kHitachiAc424Cool); ac.setFan(kHitachiAc424FanMin); ac.setTemp(kHitachiAc424MinTemp); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 1 (Min), " - "Swing(V) Toggle: Off, Button: 67 (Temp Down)", + "Button: 67 (Temp Down), Swing(V) Toggle: Off", ac.toString()); ac.setSwingVToggle(true); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 1 (Min), " - "Swing(V) Toggle: On, Button: 129 (Swing(V))", + "Button: 129 (Swing(V)), Swing(V) Toggle: On", ac.toString()); ac.setTemp(ac.getTemp() + 1); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 17C, Fan: 1 (Min), " - "Swing(V) Toggle: Off, Button: 68 (Temp Up)", + "Button: 68 (Temp Up), Swing(V) Toggle: Off", ac.toString()); ac.setTemp(ac.getTemp() - 1); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 1 (Min), " - "Swing(V) Toggle: Off, Button: 67 (Temp Down)", + "Button: 67 (Temp Down), Swing(V) Toggle: Off", ac.toString()); } @@ -1801,3 +1826,161 @@ TEST(TestIRHitachiAc1Class, FanSpeedInDryMode) { "On Timer: Off, Off Timer: Off", ac.toString()); } + +// Decode a 'real' HitachiAc344 message. +TEST(TestDecodeHitachiAc344, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + uint8_t expected[kHitachiAc344StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x98, 0x67, 0x13, + 0xEC, 0x68, 0x97, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x13, 0xEC, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x20, 0xDF, 0x00, 0xFF, 0x00, 0xFF}; + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1134#issue-622516158 + const uint16_t rawData[691] = {3410, 1624, 482, 1226, 458, 464, 458, 462, 456, + 464, 460, 460, 462, 460, 460, 462, 460, 460, 460, 462, 460, 462, 456, 466, + 458, 462, 456, 1228, 462, 460, 460, 462, 460, 462, 458, 462, 456, 466, + 456, 464, 458, 464, 456, 466, 460, 460, 460, 462, 460, 460, 458, 464, 456, + 464, 458, 464, 456, 464, 460, 462, 454, 466, 458, 1226, 460, 462, 456, + 1226, 456, 1230, 456, 1228, 456, 1230, 458, 1228, 456, 1228, 456, 464, + 456, 1230, 454, 1230, 458, 1228, 458, 1226, 454, 1230, 454, 1230, 454, + 1230, 458, 1228, 458, 1230, 452, 468, 456, 464, 454, 468, 456, 464, 418, + 502, 456, 466, 458, 464, 458, 462, 458, 464, 454, 468, 456, 1230, 454, + 1230, 454, 466, 456, 464, 456, 1228, 456, 1230, 456, 1230, 456, 1230, 456, + 464, 458, 464, 458, 1228, 456, 1230, 456, 464, 454, 466, 456, 466, 456, + 464, 458, 462, 458, 1228, 458, 1228, 458, 464, 454, 468, 456, 1228, 458, + 1228, 458, 1228, 456, 1228, 456, 464, 454, 468, 456, 1228, 458, 1226, 458, + 464, 458, 1226, 456, 1230, 454, 468, 458, 462, 452, 1232, 460, 462, 458, + 460, 460, 462, 456, 466, 458, 462, 456, 1230, 456, 1228, 460, 462, 460, + 1226, 458, 1228, 458, 1226, 460, 460, 456, 468, 458, 464, 456, 1226, 460, + 462, 458, 1228, 456, 1228, 458, 462, 462, 1224, 460, 1226, 458, 1226, 460, + 464, 458, 1228, 456, 462, 460, 462, 460, 1226, 460, 460, 462, 460, 458, + 462, 458, 462, 456, 464, 460, 460, 462, 460, 462, 460, 460, 1224, 462, + 1224, 462, 1224, 458, 1226, 462, 1224, 460, 1224, 400, 1284, 446, 1240, + 446, 476, 458, 462, 464, 458, 462, 460, 460, 460, 458, 462, 462, 462, 456, + 464, 460, 1226, 460, 1226, 460, 1224, 462, 1224, 460, 1224, 460, 1224, + 460, 1224, 462, 1224, 462, 460, 460, 462, 460, 460, 458, 464, 458, 462, + 458, 464, 458, 462, 460, 460, 462, 1224, 460, 1226, 458, 1228, 456, 1226, + 462, 1222, 460, 1228, 458, 1226, 460, 1226, 460, 460, 458, 462, 460, 462, + 460, 460, 460, 462, 460, 462, 458, 464, 460, 458, 460, 1226, 456, 1228, + 462, 1224, 460, 1224, 458, 1228, 458, 1226, 458, 1228, 462, 1224, 460, + 462, 460, 462, 458, 464, 460, 460, 456, 466, 458, 462, 460, 460, 462, + 458, 460, 1224, 460, 1224, 458, 1226, 460, 1224, 460, 1226, 460, 1226, + 458, 1228, 456, 1230, 456, 1228, 462, 1224, 460, 460, 458, 462, 458, + 1228, 456, 466, 458, 462, 454, 468, 458, 462, 458, 462, 460, 1226, 456, + 1228, 458, 464, 420, 1264, 458, 1228, 458, 1228, 456, 1228, 454, 468, 456, + 464, 456, 466, 456, 1228, 460, 1226, 456, 1230, 456, 1228, 456, 464, 456, + 1230, 458, 1226, 458, 1226, 452, 468, 456, 466, 376, 546, 456, 466, 456, + 464, 456, 466, 458, 464, 458, 464, 456, 466, 424, 496, 456, 464, 416, 504, + 454, 1230, 454, 1232, 456, 1228, 456, 1228, 456, 1230, 456, 1230, 454, + 1230, 460, 1226, 426, 496, 424, 496, 456, 466, 374, 546, 454, 468, 374, + 544, 458, 464, 456, 464, 458, 1228, 424, 1262, 454, 1232, 426, 1258, 458, + 1228, 426, 1260, 454, 1230, 456, 1228, 426, 496, 374, 546, 426, 494, 426, + 496, 424, 496, 426, 496, 424, 496, 456, 1230, 456, 1230, 456, 1228, 458, + 1228, 456, 1230, 456, 1230, 456, 1230, 424, 1260, 458, 464, 426, 1258, + 456, 1230, 422, 500, 456, 466, 418, 504, 424, 496, 426, 496, 456, 464, + 420, 500, 454, 468, 456, 1230, 424, 1260, 420, 1264, 422, 1264, 418, + 1266, 420, 1264, 420, 500, 456, 466, 426, 494, 454, 468, 456, 464, 420, + 1266, 452, 470, 454, 466, 374, 1310, 456, 1228, 456, 1230, 452, 1232, 420, + 1266, 424, 498, 456, 1230, 456, 1230, 456, 466, 450, 470, 456, 464, 376, + 546, 456, 466, 422, 498, 426, 496, 458, 464, 424, 1260, 454, 1232, 454, + 1232, 454, 1232, 458, 1228, 422, 1262, 456, 1228, 454, 1230, 456, 468, + 416, 504, 422, 498, 424, 498, 454, 466, 456, 466, 422, 500, 456, 466, 374, + 1310, 418, 1266, 424, 1262, 422, 1262, 376, 1310, 376, 1308, 422, 1264, + 424, 1262, 350}; // UNKNOWN 919B8582 + + irsend.reset(); + irsend.sendRaw(rawData, 691, kHitachiAcFreq); + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(HITACHI_AC344, irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc344Bits, irsend.capture.bits); + EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits); +} + +// Decode a synthetic HitachiAc344 message. +TEST(TestDecodeHitachiAc344, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + uint8_t expected[kHitachiAc344StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x98, 0x67, 0x13, + 0xEC, 0x68, 0x97, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x13, 0xEC, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x20, 0xDF, 0x00, 0xFF, 0x00, 0xFF}; + + irsend.reset(); + irsend.sendHitachiAc344(expected); + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(HITACHI_AC344, irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc344Bits, irsend.capture.bits); + EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Mode: 3 (Cool), Temp: 26C, Fan: 1 (Min), " + "Button: 19 (Power/Mode), Swing(V): On, Swing(H): 3 (Middle)", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestDecodeIRHitachiAc344, ExampleMessages) { + IRHitachiAc344 ac(kGpioUnused); + + // On, 17, Hot, Auto + // Ref: https://docs.google.com/spreadsheets/d/1LPd8K9V437oyEMZT6JDv5LlPXh61RPmgeoVcHLWWr7k/edit#gid=1093727366&range=E21 + // but bit order revered. + const uint8_t state[kHitachiAc344StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, 0x6D, 0x13, + 0xEC, 0x44, 0xBB, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x56, 0xA9, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF}; + ac.setRaw(state); + EXPECT_EQ( + "Power: On, Mode: 6 (Heat), Temp: 17C, Fan: 5 (Auto), " + "Button: 19 (Power/Mode), Swing(V): Off, Swing(H): 3 (Middle)", + ac.toString()); +} + +TEST(TestIRHitachiAc344Class, ReconstructKnownState) { + IRHitachiAc344 ac(kGpioUnused); + + // On, 17, Hot, Auto + const uint8_t expected[kHitachiAc344StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, 0x6D, 0x13, + 0xEC, 0x44, 0xBB, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x56, 0xA9, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF}; + ac.setMode(kHitachiAc344Heat); + ac.setTemp(17); + ac.setFan(kHitachiAc344FanAuto); + ac.setButton(kHitachiAc344ButtonPowerMode); + EXPECT_STATE_EQ(expected, ac.getRaw(), kHitachiAc344Bits); +} + +TEST(TestIRHitachiAc344Class, SwingV) { + IRHitachiAc344 ac(kGpioUnused); + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1134#issuecomment-635760537 + + // https://docs.google.com/spreadsheets/d/1LPd8K9V437oyEMZT6JDv5LlPXh61RPmgeoVcHLWWr7k/edit#gid=874235844&range=G4 + // aka. On 17 Cool Auto SwingV off SwingH off + const uint8_t start[43] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, 0x6D, 0x44, + 0xBB, 0x44, 0xBB, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x53, 0xAC, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF}; + ac.setRaw(start); + EXPECT_FALSE(ac.getSwingV()); + const uint8_t turn_on_swingv[43] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, 0x6D, 0x81, + 0x7E, 0x44, 0xBB, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x53, 0xAC, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x20, 0xDF, 0x00, 0xFF, 0x00, 0xFF}; + ac.setSwingV(true); // Turn it on. + EXPECT_TRUE(ac.getSwingV()); + EXPECT_STATE_EQ(turn_on_swingv, ac.getRaw(), kHitachiAc344Bits); + ac.setSwingV(false); + EXPECT_FALSE(ac.getSwingV()); +} diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Inax_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Inax_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Inax_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Inax_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_JVC_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_JVC_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_JVC_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_JVC_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Kelvinator_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Kelvinator_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Kelvinator_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Kelvinator_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_LG_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp similarity index 97% rename from lib/IRremoteESP8266-2.7.7/test/ir_LG_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp index 3c04c902f..d899576b9 100644 --- a/lib/IRremoteESP8266-2.7.7/test/ir_LG_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp @@ -6,24 +6,6 @@ #include "IRsend_test.h" #include "gtest/gtest.h" -// Tests for calcLGChecksum() -TEST(TestCalcLGChecksum, General) { - EXPECT_EQ(0x0, calcLGChecksum(0x0)); - EXPECT_EQ(0x1, calcLGChecksum(0x1)); - EXPECT_EQ(0xF, calcLGChecksum(0xF)); - EXPECT_EQ(0x4, calcLGChecksum(0x1111)); - EXPECT_EQ(0x8, calcLGChecksum(0x2222)); - EXPECT_EQ(0x0, calcLGChecksum(0x4444)); - EXPECT_EQ(0xA, calcLGChecksum(0x1234)); - EXPECT_EQ(0xA, calcLGChecksum(0x4321)); - EXPECT_EQ(0xE, calcLGChecksum(0xABCD)); - EXPECT_EQ(0x1, calcLGChecksum(0x4AE5)); - EXPECT_EQ(0xC, calcLGChecksum(0xFFFF)); - EXPECT_EQ(0x1, calcLGChecksum(0xC005)); - EXPECT_EQ(0x1, IRLgAc::calcChecksum(0x88C0051)); - EXPECT_EQ(0x4, calcLGChecksum(0xC035)); - EXPECT_EQ(0x4, IRLgAc::calcChecksum(0x88C0354)); -} // Tests for sendLG(). @@ -670,6 +652,11 @@ TEST(TestIRLgAcClass, isValidLgAc) { ASSERT_FALSE(ac.isValidLgAc()); } +TEST(TestIRLgAcClass, calcChecksum) { + EXPECT_EQ(0x1, IRLgAc::calcChecksum(0x88C0051)); + EXPECT_EQ(0x4, IRLgAc::calcChecksum(0x88C0354)); +} + TEST(TestUtils, Housekeeping) { ASSERT_EQ("LG", typeToString(decode_type_t::LG)); ASSERT_EQ(decode_type_t::LG, strToDecodeType("LG")); diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Lasertag_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Lasertag_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Lasertag_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Lasertag_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Lego_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Lego_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Lego_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Lego_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Lutron_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Lutron_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Lutron_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Lutron_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_MWM_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_MWM_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_MWM_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_MWM_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Magiquest_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Magiquest_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Magiquest_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Magiquest_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Midea_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp similarity index 79% rename from lib/IRremoteESP8266-2.7.7/test/ir_Midea_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp index 4c437a576..24c2610a4 100644 --- a/lib/IRremoteESP8266-2.7.7/test/ir_Midea_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp @@ -790,3 +790,165 @@ TEST(TestDecodeMidea, Issue887) { EXPECT_EQ(kMideaBits, irsend.capture.bits); EXPECT_EQ(hwaddr, irsend.capture.value); } + +// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170 +TEST(TestDecodeMidea24, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + + const uint16_t rawData[103] = { + 8928, 4412, 590, 1630, 588, 538, 538, 544, 610, 516, 592, 516, 590, 538, + 568, 536, 538, 568, 592, 518, 588, 1630, 588, 1630, 560, 1680, 592, 1628, + 594, 1628, 592, 1650, 568, 1630, 558, 1680, 594, 1652, 568, 514, 592, 536, + 538, 568, 594, 516, 588, 538, 566, 518, 560, 566, 588, 514, 594, 1630, + 588, 1630, 590, 1630, 560, 1680, 594, 1630, 588, 1652, 568, 1650, 540, + 1680, 590, 512, 594, 518, 586, 538, 566, 538, 536, 568, 592, 540, 564, + 540, 566, 540, 538, 1680, 590, 1626, 592, 1630, 588, 1628, 538, 1702, 590, + 1630, 590, 13318, 8916, 2166, 638}; // UNKNOWN 774B249A + + irsend.sendRaw(rawData, 103, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); +} + +TEST(TestDecodeMidea24, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + + irsend.sendMidea24(0x80C0C0); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ( + "f38000d33" + "m8960s4480" + "m560s1680m560s560m560s560m560s560m560s560m560s560m560s560m560s560" + "m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680" + "m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560" + "m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680" + "m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560" + "m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680" + "m560s22400" + "m8960s2240m560s96320", + irsend.outputStr()); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("MIDEA", typeToString(decode_type_t::MIDEA)); + ASSERT_EQ(decode_type_t::MIDEA, strToDecodeType("MIDEA")); + ASSERT_FALSE(hasACState(decode_type_t::MIDEA)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::MIDEA)); + ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::MIDEA)); + ASSERT_EQ(kMideaBits, IRsend::defaultBits(decode_type_t::MIDEA)); + + ASSERT_EQ("MIDEA24", typeToString(decode_type_t::MIDEA24)); + ASSERT_EQ(decode_type_t::MIDEA24, strToDecodeType("MIDEA24")); + ASSERT_FALSE(hasACState(decode_type_t::MIDEA24)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::MIDEA24)); + ASSERT_EQ(kSingleRepeat, IRsend::minRepeats(decode_type_t::MIDEA24)); + ASSERT_EQ(kMidea24Bits, IRsend::defaultBits(decode_type_t::MIDEA24)); +} + +TEST(TestDecodeMidea24, RealExample2) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639271003 + const uint16_t rawData[103] = { + 8926, 4412, 590, 1630, 536, 570, 608, 518, 594, 516, 588, 518, 588, 538, + 538, 568, 592, 514, 590, 518, 588, 1630, 536, 1684, 610, 1628, 594, 1630, + 588, 1630, 590, 1630, 560, 1680, 592, 1630, 588, 1650, 568, 538, 538, 568, + 590, 514, 594, 538, 566, 518, 536, 594, 584, 516, 594, 518, 586, 1630, + 588, 1650, 538, 1682, 592, 1630, 588, 1628, 588, 1630, 560, 1680, 590, + 1626, 594, 538, 566, 538, 568, 536, 538, 570, 590, 538, 566, 538, 568, + 538, 538, 568, 590, 1626, 594, 1650, 568, 1628, 558, 1662, 558, 1680, 592, + 1650, 568, 13312, 8924, 2186, 588}; // UNKNOWN 774B249A + + irsend.sendRaw(rawData, 103, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); + + // ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639349316 + const uint16_t rawData639349316[105] = { + 8924, 4410, 596, 1628, 590, 538, 538, 568, 588, 520, 592, 516, 588, 518, + 588, 516, 558, 568, 594, 538, 566, 1652, 568, 1650, 540, 1680, 590, 1628, + 592, 1628, 590, 1628, 590, 1650, 540, 1680, 592, 1630, 590, 518, 586, 538, + 538, 568, 590, 514, 616, 494, 588, 516, 588, 516, 560, 566, 590, 1630, + 586, 1634, 564, 1652, 538, 1704, 566, 948, 254, 450, 564, 1654, 566, + 1652, 540, 1682, 610, 518, 588, 516, 590, 514, 590, 514, 582, 526, 614, + 436, 670, 512, 592, 514, 538, 1578, 718, 1602, 614, 1542, 676, 1626, 538, + 1678, 586, 1634, 616, 13308, 8920, 2158, 626}; // UNKNOWN CBEC0079 + irsend.reset(); + irsend.sendRaw(rawData639349316, 105, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(MIDEA24, irsend.capture.decode_type); + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639358566 + const uint16_t rawData639358566[103] = { + 8920, 4412, 620, 1606, 614, 512, 592, 512, 536, 568, 618, 512, 590, 492, + 614, 514, 514, 590, 594, 510, 620, 1624, 592, 1604, 590, 1632, 608, 1626, + 606, 1616, 618, 1602, 618, 1602, 560, 1682, 622, 1602, 618, 512, 592, 510, + 538, 568, 590, 512, 622, 488, 616, 490, 614, 488, 560, 568, 620, 1624, + 594, 1604, 616, 1602, 536, 1684, 640, 1600, 618, 1598, 618, 1602, 590, + 1630, 612, 512, 622, 510, 594, 514, 592, 512, 534, 568, 620, 512, 594, + 488, 616, 488, 536, 1702, 594, 1622, 622, 1604, 614, 1624, 594, 1602, 610, + 1630, 620, 13294, 8914, 2184, 596}; // UNKNOWN 774B249A + irsend.reset(); + irsend.sendRaw(rawData639358566, 103, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); +} + +// See https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639468620 +// for why this test exists. +TEST(TestDecodeMidea24, LargeTimeout) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused, 1000, 90); // Test with a large timeout value + irsend.begin(); + irsend.reset(); + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639358566 + const uint16_t rawData639358566[103] = { + 8920, 4412, 620, 1606, 614, 512, 592, 512, 536, 568, 618, 512, 590, 492, + 614, 514, 514, 590, 594, 510, 620, 1624, 592, 1604, 590, 1632, 608, 1626, + 606, 1616, 618, 1602, 618, 1602, 560, 1682, 622, 1602, 618, 512, 592, 510, + 538, 568, 590, 512, 622, 488, 616, 490, 614, 488, 560, 568, 620, 1624, + 594, 1604, 616, 1602, 536, 1684, 640, 1600, 618, 1598, 618, 1602, 590, + 1630, 612, 512, 622, 510, 594, 514, 592, 512, 534, 568, 620, 512, 594, + 488, 616, 488, 536, 1702, 594, 1622, 622, 1604, 614, 1624, 594, 1602, 610, + 1630, 620, 13294, 8914, 2184, 596}; // UNKNOWN 774B249A + irsend.reset(); + irsend.sendRaw(rawData639358566, 103, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); +} diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_MitsubishiHeavy_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_MitsubishiHeavy_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_MitsubishiHeavy_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_MitsubishiHeavy_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Mitsubishi_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Mitsubishi_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Mitsubishi_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Mitsubishi_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Multibrackets_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Multibrackets_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Multibrackets_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Multibrackets_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_NEC_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_NEC_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_NEC_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_NEC_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Neoclima_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Neoclima_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Neoclima_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Neoclima_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Nikai_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Nikai_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Nikai_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Nikai_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Panasonic_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Panasonic_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Panasonic_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Panasonic_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Pioneer_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Pioneer_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Pronto_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Pronto_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Pronto_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Pronto_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_RC5_RC6_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_RC5_RC6_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_RC5_RC6_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_RC5_RC6_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_RCMM_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_RCMM_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_RCMM_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_RCMM_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Samsung_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Samsung_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Sanyo_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Sanyo_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Sharp_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Sharp_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Sharp_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Sharp_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Sherwood_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Sherwood_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Sherwood_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Sherwood_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Sony_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Sony_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Sony_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Sony_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Symphony_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Symphony_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Symphony_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Symphony_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Tcl_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Tcl_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Tcl_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Tcl_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Teco_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Teco_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Teco_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Teco_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Toshiba_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Toshiba_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Trotec_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Trotec_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Trotec_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Trotec_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Vestel_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Vestel_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Vestel_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Vestel_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Whirlpool_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Whirlpool_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Whirlpool_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Whirlpool_test.cpp diff --git a/lib/IRremoteESP8266-2.7.7/test/ir_Whynter_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Whynter_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/test/ir_Whynter_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Whynter_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Zepeal_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Zepeal_test.cpp new file mode 100644 index 000000000..12240d2f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Zepeal_test.cpp @@ -0,0 +1,312 @@ +// Copyright 2020 Christian Nilsson + +#include "IRac.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "gtest/gtest.h" + +// Tests for decodeZepeal(). + +TEST(TestDecodeZepeal, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + // fuuryou (speed) one of 5 repeats + const uint16_t rawData_1[35] = { + 2328, 3412, + 424, 1314, 1302, 436, 1276, 454, 424, 1316, + 1274, 464, 1274, 458, 454, 1278, 450, 1288, + 1302, 432, 424, 1306, 424, 1306, 424, 1306, + 428, 1304, 450, 1290, 1298, 430, 426, 1308, + 426}; // UNKNOWN B5E66F84 + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_1, 35, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C82, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // kiri/iri (off/on) short press + const uint16_t rawData_2[179] = { + 2338, 3384, + 426, 1314, 1300, 436, 1304, 428, 424, 1314, + 1302, 440, 1300, 428, 424, 1306, 424, 1314, + 1300, 432, 400, 1330, 400, 1332, 418, 1316, + 422, 1308, 424, 1308, 400, 1338, 1300, 432, + 426, 6728, + 2352, 3384, + 426, 1312, 1302, 436, 1276, 438, 442, 1316, + 1300, 434, 1302, 430, 424, 1308, 422, 1298, + 1318, 414, 468, 1280, 426, 1306, 452, 1280, + 450, 1282, 400, 1332, 400, 1338, 1302, 412, + 416, 6760, + 2350, 3384, + 400, 1340, 1300, 438, 1300, 412, 444, 1312, + 1302, 434, 1302, 412, 442, 1308, 426, 1312, + 1302, 430, 422, 1308, 424, 1304, 400, 1332, + 424, 1306, 402, 1332, 422, 1318, 1300, 430, + 398, 6754, + 2354, 3364, + 442, 1316, 1300, 438, 1300, 430, 422, 1316, + 1328, 410, 1302, 430, 400, 1332, 400, 1338, + 1302, 412, 418, 1334, 398, 1314, 444, 1306, + 400, 1330, 424, 1308, 424, 1314, 1300, 430, + 428, 6774, + 2334, 3384, + 400, 1338, 1302, 436, 1304, 430, 396, 1340, + 1300, 436, 1302, 432, 452, 1280, 398, 1338, + 1302, 428, 402, 1330, 426, 1310, 422, 1306, + 426, 1306, 426, 1306, 404, 1336, 1274, 458, + 424}; // UNKNOWN C2DCDDE5 + + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_2, 179, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C81, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + EXPECT_EQ( + "f38000d50" + "m2338s3384" + "m426s1314m1300s436m1304s428m424s1314m1302s440m1300s428m424s1306m424s1314" + "m1300s432m400s1330m400s1332m418s1316m422s1308m424s1308m400s1338m1300s432" + "m426s6728" + "m2352s3384" + "m426s1312m1302s436m1276s438m442s1316m1300s434m1302s430m424s1308m422s1298" + "m1318s414m468s1280m426s1306m452s1280m450s1282m400s1332m400s1338m1302s412" + "m416s6760" + "m2350s3384" + "m400s1340m1300s438m1300s412m444s1312m1302s434m1302s412m442s1308m426s1312" + "m1302s430m422s1308m424s1304m400s1332m424s1306m402s1332m422s1318m1300s430" + "m398s6754" + "m2354s3364" + "m442s1316m1300s438m1300s430m422s1316m1328s410m1302s430m400s1332m400s1338" + "m1302s412m418s1334m398s1314m444s1306m400s1330m424s1308m424s1314m1300s430" + "m428s6774" + "m2334s3384" + "m400s1338m1302s436m1304s430m396s1340m1300s436m1302s432m452s1280m398s1338" + "m1302s428m402s1330m426s1310m422s1306m426s1306m426s1306m404s1336m1274s458" + "m424", + irsend.outputStr()); + + // rizumu/oyasumi (rhythm/sleep - mode) + const uint16_t rawData_3[143] = { + 2354, 3386, + 422, 1312, 1278, 462, 1300, 410, 442, 1316, + 1300, 436, 1302, 412, 448, 1304, 398, 1338, + 1300, 430, 426, 1306, 426, 1304, 400, 1332, + 400, 1340, 1300, 430, 400, 1334, 426, 1304, + 398, 6756, + 2354, 3382, + 424, 1294, 1346, 410, 1302, 410, 418, 1340, + 1300, 434, 1304, 430, 398, 1332, 400, 1338, + 1276, 456, 400, 1334, 400, 1330, 400, 1332, + 398, 1342, 1298, 430, 422, 1308, 400, 1332, + 398, 6754, + 2356, 3382, + 400, 1340, 1274, 464, 1298, 412, 444, 1314, + 1300, 438, 1300, 412, 442, 1308, 400, 1338, + 1300, 414, 418, 1330, 400, 1332, 400, 1330, + 426, 1312, 1332, 380, 446, 1306, 424, 1308, + 424, 6736, + 2352, 3380, + 402, 1338, 1302, 436, 1300, 412, 420, 1338, + 1300, 436, 1300, 412, 418, 1332, 402, 1336, + 1302, 408, 418, 1332, 424, 1308, 424, 1306, + 398, 1340, 1276, 454, 400, 1314, 418, 1332, + 426}; // UNKNOWN 712E7A7F + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_3, 143, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C84, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // kiri taimaa (off timer) + const uint16_t rawData_4[143] = { + 2308, 3392, + 444, 1314, 1302, 436, 1330, 382, 420, 1338, + 1302, 436, 1302, 408, 444, 1308, 450, 1288, + 1300, 410, 420, 1332, 424, 1308, 400, 1338, + 1302, 430, 428, 1286, 444, 1306, 452, 1282, + 424, 6728, + 2354, 3362, + 444, 1314, 1274, 464, 1302, 410, 420, 1338, + 1300, 438, 1328, 384, 444, 1308, 398, 1338, + 1274, 456, 424, 1306, 402, 1332, 424, 1312, + 1302, 412, 442, 1308, 424, 1308, 398, 1334, + 422, 6752, + 2336, 3382, + 422, 1316, 1302, 434, 1302, 430, 400, 1340, + 1302, 434, 1302, 410, 444, 1310, 422, 1314, + 1302, 410, 444, 1304, 428, 1304, 426, 1312, + 1302, 428, 424, 1308, 424, 1308, 426, 1304, + 426, 6736, + 2354, 3382, + 424, 1314, 1302, 438, 1300, 410, 418, 1338, + 1304, 436, 1304, 406, 418, 1336, 398, 1338, + 1300, 432, 424, 1306, 426, 1306, 450, 1286, + 1302, 412, 418, 1336, 396, 1334, 424, 1306, + 424}; // UNKNOWN AAD01FEF + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_4, 143, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C88, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // iri taimaa (on timer) + const uint16_t rawData_5[143] = { + 2364, 3358, + 424, 1316, 1298, 438, 1300, 432, 424, 1314, + 1298, 440, 1300, 430, 424, 1310, 424, 1312, + 1300, 436, 1302, 430, 424, 1308, 422, 1308, + 424, 1308, 424, 1314, 1302, 438, 1302, 430, + 422, 6730, + 2354, 3384, + 422, 1314, 1300, 438, 1302, 426, 426, 1312, + 1300, 438, 1302, 412, 418, 1330, 426, 1316, + 1302, 434, 1302, 430, 426, 1306, 424, 1306, + 424, 1308, 426, 1312, 1302, 436, 1302, 430, + 428, 6752, + 2364, 3354, + 428, 1308, 1304, 436, 1302, 428, 426, 1314, + 1330, 408, 1304, 428, 402, 1330, 398, 1338, + 1306, 432, 1280, 454, 426, 1302, 428, 1304, + 430, 1302, 428, 1310, 1306, 434, 1304, 428, + 428, 6788, + 2336, 3382, + 428, 1310, 1302, 434, 1304, 430, 426, 1310, + 1306, 434, 1304, 430, 424, 1306, 402, 1336, + 1302, 438, 1304, 426, 426, 1304, 402, 1330, + 426, 1304, 400, 1336, 1306, 434, 1304, 428, + 424}; // UNKNOWN F8FC587 + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_5, 143, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6CC3, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +} + +TEST(TestDecodeZepeal, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + // power + irsend.sendZepeal(0x6C81); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + EXPECT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C81, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + EXPECT_EQ( + "f38000d50" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750", + irsend.outputStr()); + + irsend.reset(); + irsend.sendZepeal(0x6Cff, kZepealBits, kNoRepeat); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + EXPECT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6Cff, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "f38000d50" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420" + "m420s6750", + irsend.outputStr()); + + irsend.reset(); + // testing a non valid value + irsend.sendZepeal(0xffff, kZepealBits, kNoRepeat); + irsend.makeDecodeResult(); + + // strict check should fail + ASSERT_FALSE(irrecv.decodeZepeal(&irsend.capture, kStartOffset, + kZepealBits, true)); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(-1, irsend.capture.decode_type); + + // non strict check should be ok + ASSERT_TRUE(irrecv.decodeZepeal(&irsend.capture, kStartOffset, + kZepealBits, false)); + EXPECT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + EXPECT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0xffff, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "f38000d50" + "m2330s3380" + "m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420" + "m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420" + "m420s6750", + irsend.outputStr()); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("ZEPEAL", typeToString(decode_type_t::ZEPEAL)); + ASSERT_EQ(decode_type_t::ZEPEAL, strToDecodeType("ZEPEAL")); + ASSERT_FALSE(hasACState(decode_type_t::ZEPEAL)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::ZEPEAL)); + ASSERT_EQ(kZepealBits, IRsend::defaultBits(decode_type_t::ZEPEAL)); + ASSERT_EQ(kZepealMinRepeat, IRsend::minRepeats(decode_type_t::ZEPEAL)); +} diff --git a/lib/IRremoteESP8266-2.7.7/tools/Makefile b/lib/IRremoteESP8266-2.7.8/tools/Makefile similarity index 100% rename from lib/IRremoteESP8266-2.7.7/tools/Makefile rename to lib/IRremoteESP8266-2.7.8/tools/Makefile diff --git a/lib/IRremoteESP8266-2.7.7/tools/RawToGlobalCache.sh b/lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh similarity index 100% rename from lib/IRremoteESP8266-2.7.7/tools/RawToGlobalCache.sh rename to lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh diff --git a/lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data.py b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py similarity index 92% rename from lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data.py rename to lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py index 4dc4cb698..3b22ea12d 100755 --- a/lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data.py +++ b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py @@ -7,6 +7,8 @@ import argparse import sys +SAFE64NOTE = "--safe64note--" +CODEGEN = "--codegen--" class RawIRMessage(): """Basic analyse functions & structure for raw IR messages.""" @@ -359,10 +361,14 @@ def parse_and_report(rawdata_str, margin, gen_code=False, name="", """Analyse the rawdata c++ definition of a IR message.""" defines = [] code = {} + code["sendcomhead"] = [] code["send"] = [] code["send64+"] = [] + code["sendcomfoot"] = [] + code["recvcomhead"] = [] code["recv"] = [] code["recv64+"] = [] + code["recvcomfoot"] = [] # Parse the input. rawdata = convert_rawdata(rawdata_str) @@ -401,11 +407,13 @@ def decode_data(message, defines, code, name="", output=sys.stdout): else: def_name = "TBD" - code["send"].extend([ + code["sendcomhead"].extend([ + "", "#if SEND_%s" % def_name.upper(), + SAFE64NOTE, "/// Send a %s formatted message." % name, - "/// Function should be safe up to 64 bits.", - "/// Status: ALPHA / Untested.", + "/// Status: ALPHA / Untested."]) + code["send"].extend([ "/// @param[in] data containing the IR command.", "/// @param[in] nbits Nr. of bits to send. usually k%sBits" % name, "/// @param[in] repeat Nr. of times the message is to be repeated.", @@ -417,6 +425,10 @@ def decode_data(message, defines, code, name="", output=sys.stdout): code["send64+"].extend([ "/// @param[in] data An array of bytes containing the IR command.", "/// It is assumed to be in MSB order for this code.", + "/// e.g.", + "/// @code", + CODEGEN, + "/// @endcode", "/// @param[in] nbytes Nr. of bytes of data in the array." " (>=k%sStateLength)" % name, "/// @param[in] repeat Nr. of times the message is to be repeated.", @@ -424,10 +436,15 @@ def decode_data(message, defines, code, name="", output=sys.stdout): " const uint16_t repeat) {" % def_name, " for (uint16_t r = 0; r <= repeat; r++) {", " uint16_t pos = 0;"]) - code["recv"].extend([ + code["sendcomfoot"].extend([ + " }", + "}", + "#endif // SEND_%s" % def_name.upper()]) + code["recvcomhead"].extend([ + "", "#if DECODE_%s" % def_name.upper(), + SAFE64NOTE, "/// Decode the supplied %s message." % name, - "/// Function should be safe up to 64 bits.", "/// Status: ALPHA / Untested.", "/// @param[in,out] results Ptr to the data to decode &" " where to store the decode", @@ -444,32 +461,17 @@ def decode_data(message, defines, code, name="", output=sys.stdout): " return false; // Too short a message to match.", " if (strict && nbits != k%sBits)" % name, " return false;", - "", + ""]) + code["recv"].extend([ " uint64_t data = 0;", " match_result_t data_result;"]) code["recv64+"].extend([ - "#if DECODE_%s" % def_name.upper(), - "/// Decode the supplied %s message." % name, - "/// Function should be safe over 64 bits.", - "/// Status: ALPHA / Untested.", - "/// @param[in,out] results Ptr to the data to decode &" - " where to store the decode", - "/// @param[in] offset The starting index to use when" - " attempting to decode the", - "/// raw data. Typically/Defaults to kStartOffset.", - "/// @param[in] nbits The number of data bits to expect.", - "/// @param[in] strict Flag indicating if we should perform" - " strict matching.", - "/// @return A boolean. True if it can decode it, false if it can't.", - "bool IRrecv::decode%s(decode_results *results, uint16_t offset," - " const uint16_t nbits, const bool strict) {" % def_name, - " if (results->rawlen < 2 * nbits + k%sOverhead - offset)" % name, - " return false; // Too short a message to match.", - " if (strict && nbits != k%sBits)" % name, - " return false;", - "", " uint16_t pos = 0;", " uint16_t used = 0;"]) + code["recvcomfoot"].extend([ + " return true;", + "}", + "#endif // DECODE_%s" % def_name.upper()]) # states are: # HM: Header/Leader mark @@ -604,14 +606,7 @@ def decode_data(message, defines, code, name="", output=sys.stdout): message.section_count = message.section_count + 1 code["send"].extend([ " space(kDefaultMessageGap); // A 100% made up guess of the gap" - " between messages.", - " }", - "}", - "#endif // SEND_%s" % def_name.upper()]) - code["send64+"].extend([ - " }", - "}", - "#endif // SEND_%s" % def_name.upper()]) + " between messages."]) code["recv"].extend([ "", " // Success", @@ -619,18 +614,12 @@ def decode_data(message, defines, code, name="", output=sys.stdout): " results->bits = nbits;", " results->value = data;", " results->command = 0;", - " results->address = 0;", - " return true;", - "}", - "#endif // DECODE_%s" % def_name.upper()]) + " results->address = 0;"]) code["recv64+"].extend([ "", " // Success", " results->decode_type = decode_type_t::%s;" % def_name.upper(), - " results->bits = nbits;", - " return true;", - "}", - "#endif // DECODE_%s" % def_name.upper()]) + " results->bits = nbits;"]) total_bits = total_bits + binary_value output.write("\nTotal Nr. of suspected bits: %d\n" % len(total_bits)) @@ -647,13 +636,17 @@ def decode_data(message, defines, code, name="", output=sys.stdout): def generate_code(defines, code, bits_str, name="", output=sys.stdout): """Output the estimated C++ code to reproduce & decode the IR message.""" + # pylint: disable=too-many-branches if name: def_name = name else: def_name = "TBD" output.write("\nGenerating a VERY rough code outline:\n\n" "// Copyright 2020 David Conran (crankyoldgit)\n" - "// Support for %s protocol\n\n" + "/// @file\n" + "/// @brief Support for %s protocol\n\n" + "// Supports:\n" + "// Brand: %s, Model: TODO add device and remote\n\n" '#include "IRrecv.h"\n' '#include "IRsend.h"\n' '#include "IRutils.h"\n\n' @@ -662,7 +655,7 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout): "// See https://github.com/crankyoldgit/IRremoteESP8266/wiki/" "Adding-support-for-a-new-IR-protocol\n" "// for details of how to include this in the library." - "\n" % def_name) + "\n" % (def_name, def_name)) for line in defines: output.write("%s\n" % line) @@ -671,39 +664,40 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout): "'data' won't work!\n") # Display the "normal" version's send code incase there are some # oddities in it. - for line in code["send"]: + for line in code["sendcomhead"] + code["send"] + code["sendcomfoot"]: + if line == SAFE64NOTE: + line = "// Function should be safe up to 64 bits." output.write("%s\n" % line) if len(bits_str) > 64: # Will it fit in a uint64_t? - code["send64+"] = [ - "", - "#if SEND_%s" % def_name.upper(), - "/// Send a %s formatted message." % name, - "/// Alternative >64bit function to send %s messages" % - def_name.upper(), - "/// Status: ALPHA / Untested.", - "/// Where data is:", - "/// uint8_t data[k%sStateLength] = {0x%s};" % ( + for line in code["sendcomhead"] + code["send64+"] + code["sendcomfoot"]: + if line == SAFE64NOTE: + line = "// Alternative >64bit function to send %s messages\n" % \ + def_name.upper() + "// Function should be safe over 64 bits." + elif line == CODEGEN: + line = "/// uint8_t data[k%sStateLength] = {0x%s};" % ( name, ", 0x".join("%02X" % int(bits_str[i:i + 8], 2) - for i in range(0, len(bits_str), 8))), - "///"] + code["send64+"] - for line in code["send64+"]: + for i in range(0, len(bits_str), 8))) output.write("%s\n" % line) - output.write("\n") if len(bits_str) > 64: # Will it fit in a uint64_t? - output.write("// DANGER: More than 64 bits detected. A uint64_t for " - "'data' won't work!\n") + output.write("\n// DANGER: More than 64 bits detected. A uint64_t for " + "'data' won't work!") + # Display the "normal" version's decode code incase there are some # oddities in it. - for line in code["recv"]: + for line in code["recvcomhead"] + code["recv"] + code["recvcomfoot"]: + if line == SAFE64NOTE: + line = "// Function should be safe up to 64 bits." output.write("%s\n" % line) + # Display the > 64bit version's decode code if len(bits_str) > 64: # Is it too big for a uint64_t? - output.write("\n// Note: This should be 64+ bit safe.\n") if len(bits_str) % 8: output.write("\n// WARNING: Data is not a multiple of bytes. " "This won't work!\n") - for line in code["recv64+"]: + for line in code["recvcomhead"] + code["recv64+"] + code["recvcomfoot"]: + if line == SAFE64NOTE: + line = "// Function should be safe over 64 bits." output.write("%s\n" % line) def add_rawdata_args(parser): @@ -711,7 +705,7 @@ def add_rawdata_args(parser): arg_group = parser.add_mutually_exclusive_group(required=True) arg_group.add_argument( "rawdata", - help="A rawData line from IRrecvDumpV2. e.g. 'uint16_t rawbuf[37] = {" + help="A rawData line from IRrecvDumpV2+. e.g. 'uint16_t rawbuf[37] = {" "7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494, " "520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, " "494, 520, 520, 520, 494, 520, 494, 520, 494, 520, 494};'", @@ -765,7 +759,13 @@ def main(): add_rawdata_args(arg_parser) arg_options = arg_parser.parse_args() - parse_and_report(get_rawdata(arg_options), arg_options.margin, + raw_data = get_rawdata(arg_options).strip() + if not raw_data: + arg_parser.print_help(sys.stderr) + sys.stderr.write("error: no rawdata content\n") + sys.exit(1) + + parse_and_report(raw_data, arg_options.margin, arg_options.gen_code, arg_options.name) diff --git a/lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data_test.py b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py similarity index 97% rename from lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data_test.py rename to lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py index 1f90c4661..1b080c5a8 100755 --- a/lib/IRremoteESP8266-2.7.7/tools/auto_analyse_raw_data_test.py +++ b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py @@ -280,7 +280,11 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'Generating a VERY rough code outline:\n' '\n' '// Copyright 2020 David Conran (crankyoldgit)\n' - '// Support for FOO protocol\n' + '/// @file\n' + '/// @brief Support for FOO protocol\n' + '\n' + '// Supports:\n' + '// Brand: FOO, Model: TODO add device and remote\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' @@ -300,9 +304,10 @@ class TestAutoAnalyseRawData(unittest.TestCase): ' frequency.)\n' 'const uint16_t kFOOBits = 16; // Move to IRremoteESP8266.h\n' 'const uint16_t kFOOOverhead = 5;\n' + '\n' '#if SEND_FOO\n' + '// Function should be safe up to 64 bits.\n' '/// Send a FOO formatted message.\n' - '/// Function should be safe up to 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in] data containing the IR command.\n' '/// @param[in] nbits Nr. of bits to send. usually kFOOBits\n' @@ -337,8 +342,8 @@ class TestAutoAnalyseRawData(unittest.TestCase): '#endif // SEND_FOO\n' '\n' '#if DECODE_FOO\n' + '// Function should be safe up to 64 bits.\n' '/// Decode the supplied FOO message.\n' - '/// Function should be safe up to 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in,out] results Ptr to the data to decode &' ' where to store the decode\n' @@ -556,7 +561,11 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'Generating a VERY rough code outline:\n' '\n' '// Copyright 2020 David Conran (crankyoldgit)\n' - '// Support for Hitachi protocol\n' + '/// @file\n' + '/// @brief Support for Hitachi protocol\n' + '\n' + '// Supports:\n' + '// Brand: Hitachi, Model: TODO add device and remote\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' @@ -582,9 +591,10 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'const uint16_t kHitachiOverhead = 5;\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' + '\n' '#if SEND_HITACHI\n' + '// Function should be safe up to 64 bits.\n' '/// Send a Hitachi formatted message.\n' - '/// Function should be safe up to 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in] data containing the IR command.\n' '/// @param[in] nbits Nr. of bits to send. usually kHitachiBits\n' @@ -617,19 +627,21 @@ class TestAutoAnalyseRawData(unittest.TestCase): '#endif // SEND_HITACHI\n' '\n' '#if SEND_HITACHI\n' + '// Alternative >64bit function to send HITACHI messages\n' + '// Function should be safe over 64 bits.\n' '/// Send a Hitachi formatted message.\n' - '/// Alternative >64bit function to send HITACHI messages\n' '/// Status: ALPHA / Untested.\n' - '/// Where data is:\n' + '/// @param[in] data An array of bytes containing the IR command.\n' + '/// It is assumed to be in MSB order for this code.\n' + '/// e.g.\n' + '/// @code\n' '/// uint8_t data[kHitachiStateLength] = {0x80, 0x08, 0x00, 0x02,' ' 0xFD, 0xFF, 0x00, 0x33, 0xCC, 0x49, 0xB6, 0xC8, 0x37, 0x3A, 0xC5,' ' 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xCA,' ' 0x35, 0x8F, 0x70, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0xFE, 0xC0, 0x3F,' ' 0x80, 0x7F, 0x11, 0xEE, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,' ' 0x00, 0xFF, 0x00, 0xFF, 0x00};\n' - '///\n' - '/// @param[in] data An array of bytes containing the IR command.\n' - '/// It is assumed to be in MSB order for this code.\n' + '/// @endcode\n' '/// @param[in] nbytes Nr. of bytes of data in the array.' ' (>=kHitachiStateLength)\n' '/// @param[in] repeat Nr. of times the message is to be repeated.\n' @@ -660,8 +672,8 @@ class TestAutoAnalyseRawData(unittest.TestCase): "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '#if DECODE_HITACHI\n' + '// Function should be safe up to 64 bits.\n' '/// Decode the supplied Hitachi message.\n' - '/// Function should be safe up to 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in,out] results Ptr to the data to decode &' ' where to store the decode\n' @@ -722,10 +734,9 @@ class TestAutoAnalyseRawData(unittest.TestCase): '}\n' '#endif // DECODE_HITACHI\n' '\n' - '// Note: This should be 64+ bit safe.\n' '#if DECODE_HITACHI\n' + '// Function should be safe over 64 bits.\n' '/// Decode the supplied Hitachi message.\n' - '/// Function should be safe over 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in,out] results Ptr to the data to decode &' ' where to store the decode\n' @@ -864,7 +875,11 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'Generating a VERY rough code outline:\n' '\n' '// Copyright 2020 David Conran (crankyoldgit)\n' - '// Support for FOO protocol\n' + '/// @file\n' + '/// @brief Support for FOO protocol\n' + '\n' + '// Supports:\n' + '// Brand: FOO, Model: TODO add device and remote\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' @@ -888,9 +903,10 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'const uint16_t kFOOOverhead = 16;\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' + '\n' '#if SEND_FOO\n' + '// Function should be safe up to 64 bits.\n' '/// Send a FOO formatted message.\n' - '/// Function should be safe up to 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in] data containing the IR command.\n' '/// @param[in] nbits Nr. of bits to send. usually kFOOBits\n' @@ -951,15 +967,17 @@ class TestAutoAnalyseRawData(unittest.TestCase): '#endif // SEND_FOO\n' '\n' '#if SEND_FOO\n' + '// Alternative >64bit function to send FOO messages\n' + '// Function should be safe over 64 bits.\n' '/// Send a FOO formatted message.\n' - '/// Alternative >64bit function to send FOO messages\n' '/// Status: ALPHA / Untested.\n' - '/// Where data is:\n' - '/// uint8_t data[kFOOStateLength] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,' - ' 0x5F, 0x40, 0x40, 0x2F, 0x2F, 0x6C, 0x6C, 0x2F, 0x2F, 0x6C, 0x6C};\n' - '///\n' '/// @param[in] data An array of bytes containing the IR command.\n' '/// It is assumed to be in MSB order for this code.\n' + '/// e.g.\n' + '/// @code\n' + '/// uint8_t data[kFOOStateLength] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,' + ' 0x5F, 0x40, 0x40, 0x2F, 0x2F, 0x6C, 0x6C, 0x2F, 0x2F, 0x6C, 0x6C};\n' + '/// @endcode\n' '/// @param[in] nbytes Nr. of bytes of data in the array.' ' (>=kFOOStateLength)\n' '/// @param[in] repeat Nr. of times the message is to be repeated.\n' @@ -1018,8 +1036,8 @@ class TestAutoAnalyseRawData(unittest.TestCase): "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't " 'work!\n' '#if DECODE_FOO\n' + '// Function should be safe up to 64 bits.\n' '/// Decode the supplied FOO message.\n' - '/// Function should be safe up to 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in,out] results Ptr to the data to decode &' ' where to store the decode\n' @@ -1138,10 +1156,9 @@ class TestAutoAnalyseRawData(unittest.TestCase): '}\n' '#endif // DECODE_FOO\n' '\n' - '// Note: This should be 64+ bit safe.\n' '#if DECODE_FOO\n' + '// Function should be safe over 64 bits.\n' '/// Decode the supplied FOO message.\n' - '/// Function should be safe over 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in,out] results Ptr to the data to decode &' ' where to store the decode\n' @@ -1294,7 +1311,11 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'Generating a VERY rough code outline:\n' '\n' '// Copyright 2020 David Conran (crankyoldgit)\n' - '// Support for TBD protocol\n' + '/// @file\n' + '/// @brief Support for TBD protocol\n' + '\n' + '// Supports:\n' + '// Brand: TBD, Model: TODO add device and remote\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' @@ -1317,9 +1338,10 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'const uint16_t kOverhead = 1;\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' + '\n' '#if SEND_TBD\n' + '// Function should be safe up to 64 bits.\n' '/// Send a formatted message.\n' - '/// Function should be safe up to 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in] data containing the IR command.\n' '/// @param[in] nbits Nr. of bits to send. usually kBits\n' @@ -1343,15 +1365,17 @@ class TestAutoAnalyseRawData(unittest.TestCase): '#endif // SEND_TBD\n' '\n' '#if SEND_TBD\n' + '// Alternative >64bit function to send TBD messages\n' + '// Function should be safe over 64 bits.\n' '/// Send a formatted message.\n' - '/// Alternative >64bit function to send TBD messages\n' '/// Status: ALPHA / Untested.\n' - '/// Where data is:\n' - '/// uint8_t data[kStateLength] = {0xA5, 0x5A, 0x00, 0x00, 0x40,' - ' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};\n' - '///\n' '/// @param[in] data An array of bytes containing the IR command.\n' '/// It is assumed to be in MSB order for this code.\n' + '/// e.g.\n' + '/// @code\n' + '/// uint8_t data[kStateLength] = {0xA5, 0x5A, 0x00, 0x00, 0x40,' + ' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};\n' + '/// @endcode\n' '/// @param[in] nbytes Nr. of bytes of data in the array.' ' (>=kStateLength)\n' '/// @param[in] repeat Nr. of times the message is to be repeated.\n' @@ -1378,8 +1402,8 @@ class TestAutoAnalyseRawData(unittest.TestCase): "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' '#if DECODE_TBD\n' + '// Function should be safe up to 64 bits.\n' '/// Decode the supplied message.\n' - '/// Function should be safe up to 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in,out] results Ptr to the data to decode &' ' where to store the decode\n' @@ -1425,10 +1449,9 @@ class TestAutoAnalyseRawData(unittest.TestCase): '}\n' '#endif // DECODE_TBD\n' '\n' - '// Note: This should be 64+ bit safe.\n' '#if DECODE_TBD\n' + '// Function should be safe over 64 bits.\n' '/// Decode the supplied message.\n' - '/// Function should be safe over 64 bits.\n' '/// Status: ALPHA / Untested.\n' '/// @param[in,out] results Ptr to the data to decode &' ' where to store the decode\n' diff --git a/lib/IRremoteESP8266-2.7.7/tools/gc_decode.cpp b/lib/IRremoteESP8266-2.7.8/tools/gc_decode.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/tools/gc_decode.cpp rename to lib/IRremoteESP8266-2.7.8/tools/gc_decode.cpp diff --git a/lib/IRremoteESP8266-2.7.7/tools/generate_irtext_h.sh b/lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh similarity index 100% rename from lib/IRremoteESP8266-2.7.7/tools/generate_irtext_h.sh rename to lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh diff --git a/lib/IRremoteESP8266-2.7.7/tools/mkkeywords b/lib/IRremoteESP8266-2.7.8/tools/mkkeywords similarity index 100% rename from lib/IRremoteESP8266-2.7.7/tools/mkkeywords rename to lib/IRremoteESP8266-2.7.8/tools/mkkeywords diff --git a/lib/IRremoteESP8266-2.7.7/tools/mode2_decode.cpp b/lib/IRremoteESP8266-2.7.8/tools/mode2_decode.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.7/tools/mode2_decode.cpp rename to lib/IRremoteESP8266-2.7.8/tools/mode2_decode.cpp diff --git a/lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code.py b/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code.py similarity index 100% rename from lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code.py rename to lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code.py diff --git a/lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code_test.py b/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code_test.py similarity index 100% rename from lib/IRremoteESP8266-2.7.7/tools/raw_to_pronto_code_test.py rename to lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code_test.py diff --git a/lib/IRremoteESP8266-2.7.7/tools/scrape_supported_devices.py b/lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py similarity index 57% rename from lib/IRremoteESP8266-2.7.7/tools/scrape_supported_devices.py rename to lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py index 4beb6c9c3..a9cd10f0a 100755 --- a/lib/IRremoteESP8266-2.7.7/tools/scrape_supported_devices.py +++ b/lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py @@ -2,6 +2,8 @@ """Generate SupportedProtocols.md by scraping source code files""" import pathlib import argparse +import subprocess +from io import StringIO import sys import re import time @@ -21,10 +23,28 @@ ALL_FN = re.compile(r"ir_(.+)\.(h|cpp)") EXCLUDED_PROTOCOLS = ["UNKNOWN", "UNUSED", "kLastDecodeType", "typeguess"] EXCLUDED_ACS = ["Magiquest", "NEC"] -MARKDOWN_HEADER = """""".format( - time.strftime("%a %d %b %Y %H:%M:%S +0000", time.gmtime())) + time.strftime("%a %d %b %Y %H:%M:%S +0000", time.gmtime(srctime))) def getallprotocols(): @@ -43,7 +63,7 @@ def getdecodedprotocols(): for path in ARGS.directory.iterdir(): if path.suffix != ".cpp": continue - matches = DECODED_PROTOCOLS.finditer(path.open().read()) + matches = DECODED_PROTOCOLS.finditer(path.open(encoding="utf-8").read()) for match in matches: protocol = match.group(1) if protocol not in EXCLUDED_PROTOCOLS: @@ -86,37 +106,88 @@ def getallacs(): ret[acprotocol] = models return ret +class FnSets(): + """Container for getalldevices""" + def __init__(self): + self.allcodes = {} + self.fnnomatch = set() + self.allhfileprotos = set() + self.fnhmatch = set() + self.fncppmatch = set() + + def add(self, supports, path): + """add the path to correct set based on supports""" + if path.suffix == ".h": + self.allhfileprotos.add(path.stem) + if supports: + if path.suffix == ".h": + self.fnhmatch.add(path.stem) + elif path.suffix == ".cpp": + self.fncppmatch.add(path.stem) + else: + self.fnnomatch.add(path.stem) + + def printwarnings(self): + """print warnings""" + # all protos with support in .cpp file, when there is a .h file + # meaning that the documentation should probably be moved to .h + # in the future, with doxygen, that might change + protosincppwithh = list(self.fncppmatch & self.allhfileprotos) + if protosincppwithh: + protosincppwithh.sort() + print("The following files has supports section in .cpp, expected in .h") + for path in protosincppwithh: + print("\t{}".format(path)) + + protosincppandh = list(self.fncppmatch & self.fnhmatch) + if protosincppandh: + protosincppandh.sort() + print("The following files has supports section in both .h and .cpp") + for path in protosincppandh: + print("\t{}".format(path)) + + nosupports = self.getnosupports() + if nosupports: + nosupports.sort() + print("The following files had no supports section:") + for path in nosupports: + print("\t{}".format(path)) + + return protosincppwithh or protosincppandh or nosupports + + def getnosupports(self): + """get protos without supports sections""" + return list(self.fnnomatch - self.fnhmatch - self.fncppmatch) + def getalldevices(): """All devices and associated branding and model information (if available) """ - allcodes = {} - fnnomatch = set() - fnmatch = set() + sets = FnSets() for path in ARGS.directory.iterdir(): match = ALL_FN.match(path.name) if not match: continue supports = extractsupports(path) - if supports: - fnmatch.add(path.stem) - else: - fnnomatch.add(path.stem) + sets.add(supports, path) protocol = match.group(1) for brand, model in supports: protocolbrand = (protocol, brand) - allcodes[protocolbrand] = allcodes.get(protocolbrand, list()) + [model] - nosupports = fnnomatch - fnmatch - for fnprotocol in nosupports: - allcodes[(fnprotocol[3:], "Unknown")] = [] - return allcodes, nosupports + pbset = sets.allcodes.get(protocolbrand, list()) + if model in pbset: + print("Model %s is duplicated for %s, %s" % (model, protocol, brand)) + sets.allcodes[protocolbrand] = pbset + [model] + + for fnprotocol in sets.getnosupports(): + sets.allcodes[(fnprotocol[3:], "Unknown")] = [] + return sets def getenums(path): """Returns the keys for the first enum type in path - """ + """ ret = {} - for enums in ENUMS.finditer(path.open().read()): + for enums in ENUMS.finditer(path.open(encoding="utf-8").read()): if enums: enum_name = AC_MODEL_ENUM_RE.search(enums.group(1)) if enum_name: @@ -139,6 +210,12 @@ def initargs(): """Init the command line arguments""" global ARGS # pylint: disable=global-statement parser = argparse.ArgumentParser() + parser.add_argument( + "-n", + "--noout", + help="generate no output data, combine with --alert to only check", + action="store_true", + ) parser.add_argument( "-s", "--stdout", @@ -152,7 +229,8 @@ def initargs(): parser.add_argument( "-a", "--alert", - help="alert if a file does not have a supports section", + help="alert if a file does not have a supports section, " + "non zero exit code if issues where found", action="store_true", ) parser.add_argument( @@ -173,6 +251,10 @@ def initargs(): ARGS.directory = src return ARGS +def getmdfile(): + """Resolves SupportedProtocols.md path""" + foutpath = ARGS.directory / "../SupportedProtocols.md" + return foutpath.resolve() def errorexit(msg): """Print an error and exit on critical error""" @@ -185,7 +267,7 @@ def extractsupports(path): """ supports = [] insupports = False - for line in path.open(): + for line in path.open(encoding="utf-8"): if not line.startswith("//"): continue line = line[2:].strip() @@ -199,6 +281,12 @@ def extractsupports(path): else: insupports = False continue + # search and inform about any legacy formated supports data + elif any(x in line for x in [ \ + "seems compatible with", + "be compatible with", + "it working with here"]): + print("\t%s Legacy supports format found\n\t\t%s" % (path.name, line)) return supports @@ -215,28 +303,18 @@ def outputprotocols(fout, protocols): fout.write("- {}\n".format(protocol)) -def main(): - """Standard boiler plate""" - initargs() - if ARGS.verbose: - print("Looking for files in: {}".format(str(ARGS.directory.resolve()))) - if ARGS.stdout: - fout = sys.stdout - else: - foutpath = ARGS.directory / "../SupportedProtocols.md" - foutpath = foutpath.resolve() - if ARGS.verbose: - print("Output path: {}".format(str(foutpath))) - fout = foutpath.open("w") +def generate(fout): + """Generate data to fout + return True on any issues (when alert is active)""" decodedprotocols = getdecodedprotocols() sendonly = getallprotocols() - decodedprotocols allacs = getallacs() - allcodes, nosupports = getalldevices() + sets = getalldevices() + allcodes = sets.allcodes allbrands = list(allcodes.keys()) allbrands.sort() - fout.write(MARKDOWN_HEADER) fout.write("\n# IR Protocols supported by this library\n\n") fout.write( "| Protocol | Brand | Model | A/C Model | Detailed A/C Support |\n") @@ -269,13 +347,60 @@ def main(): fout.write("\n\n## Send & decodable protocols:\n\n") outputprotocols(fout, decodedprotocols) - if ARGS.alert: - nosupports = list(nosupports) - nosupports.sort() - print("The following files had no supports section:") - for path in nosupports: - print("\t{}".format(path)) + return ARGS.alert and sets.printwarnings() + +def generatenone(): + """No out write + return True on any issues""" + return generate(StringIO()) + +def generatestdout(): + """Standard out write + return True on any issues""" + fout = sys.stdout + fout.write(getmarkdownheader()) + return generate(fout) + +def generatefile(): + """File write, extra detection of changes in existing file + return True on any issues, but only if there is changes""" + # get file path + foutpath = getmdfile() + if ARGS.verbose: + print("Output path: {}".format(str(foutpath))) + # write data to temp memorystream + ftemp = StringIO() + ret = generate(ftemp) + # get old filedata, skipping header + with getmdfile().open("r", encoding="utf-8") as forg: + olddata = forg.readlines()[3:] + # get new data, skip first empty line + ftemp.seek(0) + newdata = ftemp.readlines()[1:] + # if new data is same as old we don't need to write anything + if newdata == olddata: + print("No changes, exit without write") + return False + # write output + with foutpath.open("w", encoding="utf-8") as fout: + fout.write(getmarkdownheader()) + fout.write(ftemp.getvalue()) + + return ret + +def main(): + """Default main function + return True on any issues""" + initargs() + if ARGS.verbose: + print("Looking for files in: {}".format(str(ARGS.directory.resolve()))) + if ARGS.noout: + return generatenone() + if ARGS.stdout: + return generatestdout() + # default file + return generatefile() if __name__ == "__main__": - main() + sys.exit(1 if main() else 0) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index ce16e0478..95fdf9efd 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -12,6 +12,7 @@ - Change ESP32 USER GPIO template representation decreasing template message size - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT - Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` +- Change IRremoteESP8266 library updated to v2.7.8 ### 8.3.1.5 20200616 From 1cbfbc697a2b0444943578ae6d48e8446b4a45f1 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Thu, 25 Jun 2020 07:34:00 +0200 Subject: [PATCH 345/581] fix sml counter irq mode --- tasmota/xsns_53_sml.ino | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index 18fd53bf5..bf46ace85 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -49,6 +49,7 @@ #define SPECIAL_SS #endif +#undef TMSBSIZ #define TMSBSIZ 256 // addresses a bug in meter DWS74 @@ -1785,6 +1786,7 @@ struct SML_COUNTER { uint32_t sml_cnt_last_ts; uint32_t sml_counter_ltime; uint16_t sml_debounce; + uint8_t sml_cnt_updated; #ifdef ANALOG_OPTO_SENSOR int16_t ana_curr; @@ -1813,7 +1815,8 @@ void SML_CounterUpd(uint8_t index) { sml_counters[index].sml_counter_ltime=millis(); if (ltime>sml_counters[index].sml_debounce) { RtcSettings.pulse_counter[index]++; - InjektCounterValue(sml_counters[index].sml_cnt_old_state,RtcSettings.pulse_counter[index]); + sml_counters[index].sml_cnt_updated=1; + //InjektCounterValue(sml_counters[index].sml_cnt_old_state,RtcSettings.pulse_counter[index]); } } else { // rising edge @@ -2310,6 +2313,13 @@ uint32_t ctime=millis(); if (cindex==1) SetDBGLed(meter_desc_p[meters].srcpin,DEBUG_CNT_LED2); #endif } + + if (sml_counters[cindex].sml_cnt_updated) { + InjektCounterValue(sml_counters[cindex].sml_cnt_old_state,RtcSettings.pulse_counter[cindex]); + sml_counters[cindex].sml_cnt_updated=0; + } + + } cindex++; } From 956e6f5a5c5901de4563f4cc823e08125379556d Mon Sep 17 00:00:00 2001 From: Mark Hansen Date: Thu, 25 Jun 2020 20:06:24 +1000 Subject: [PATCH 346/581] Add uptime metric to prometheus exporter I'm following the naming practices: https://prometheus.io/docs/practices/naming/ - an application prefix (tasmota_) - a unit suffix in plural form Tested building and flashing: looks like ``` tasmota_uptime_seconds 78 ``` --- tasmota/xsns_91_prometheus.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/xsns_91_prometheus.ino b/tasmota/xsns_91_prometheus.ino index 2a361b550..9e29afe75 100644 --- a/tasmota/xsns_91_prometheus.ino +++ b/tasmota/xsns_91_prometheus.ino @@ -37,6 +37,8 @@ void HandleMetrics(void) char parameter[FLOATSZ]; + WSContentSend_P(PSTR("# TYPE tasmota_uptime_seconds gauge\ntasmota_uptime_seconds %d\n"), uptime); + if (!isnan(global_temperature)) { dtostrfd(global_temperature, Settings.flag2.temperature_resolution, parameter); WSContentSend_P(PSTR("# TYPE global_temperature gauge\nglobal_temperature %s\n"), parameter); From b0cebcbef8a752a78ee0f0518638a9e49d97be7f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 25 Jun 2020 15:36:25 +0200 Subject: [PATCH 347/581] Shrink tasmota-ir Disable Counter and DHT and DS18x20 sensors. Use ADC_VCC --- tasmota/tasmota_configurations.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 10f183ec5..be5f3a4f1 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -347,6 +347,10 @@ #undef USE_ELECTRIQ_MOODL // Disable support for ElectriQ iQ-wifiMOODL RGBW LED controller #undef USE_LIGHT_PALETTE // Disable support for color palette (+0k9 code) +#undef USE_COUNTER // Disable counters +#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices +#undef USE_DS18x20 // Disable DS18x20 sensor + #undef USE_ENERGY_SENSOR // Disable energy sensors (-14k code) #undef USE_PZEM004T // Disable PZEM004T energy sensor #undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor @@ -386,7 +390,7 @@ #undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) -//#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor +#undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI #undef USE_MAX31865 // Disable support for MAX31865 RTD sensors using softSPI #undef USE_SR04 // Disable support for for HC-SR04 ultrasonic devices From 9ecef62e8bec16c18a1751d5c8d404d8a79a661c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 25 Jun 2020 15:43:17 +0200 Subject: [PATCH 348/581] Update BUILDS.md --- BUILDS.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BUILDS.md b/BUILDS.md index 700407907..97bef3901 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -70,10 +70,10 @@ | USE_LE01MR | - | - | - | - | - | - | - | | USE_TELEINFO | - | - | - | - | - | - | - | | | | | | | | | | -| USE_ADC_VCC | x | x | - | - | - | - | - | -| USE_COUNTER | - | - | x | x | x | x | x | -| USE_DS18x20 | - | - | x | x | x | x | x | -| USE_DHT | - | - | x | x | x | x | x | +| USE_ADC_VCC | x | x | - | - | - | x | - | +| USE_COUNTER | - | - | x | x | x | - | x | +| USE_DS18x20 | - | - | x | x | x | - | x | +| USE_DHT | - | - | x | x | x | - | x | | USE_MAX31855 | - | - | - | - | x | - | - | | USE_MAX31865 | - | - | - | - | - | - | - | | USE_THERMOSTAT | - | - | - | - | - | - | - | From f5fb209e9dea0699ee884cb96eda06779587719e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 26 Jun 2020 08:03:11 +0200 Subject: [PATCH 349/581] Updated instructions --- tasmota/user_config_override_sample.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasmota/user_config_override_sample.h b/tasmota/user_config_override_sample.h index 5bd99175a..227006776 100644 --- a/tasmota/user_config_override_sample.h +++ b/tasmota/user_config_override_sample.h @@ -29,8 +29,7 @@ * (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' + * All done. * for Arduino IDE: * enable define USE_CONFIG_OVERRIDE in my_user_config.h ****************************************************************************************************** From 6553a775f46ec8d43d84cd300ef200930518915d Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Fri, 26 Jun 2020 09:22:57 +0200 Subject: [PATCH 350/581] scripter update fix unishox define conflict fix for next loop exit bugs add full pagewebserver (also support for jpg, html and txt files from filesystem) --- tasmota/xdrv_10_scripter.ino | 259 ++++++++++++++++++++++++++++++++--- 1 file changed, 240 insertions(+), 19 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 951730785..e6c515b5d 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -67,14 +67,16 @@ keywords if then else endif, or, and are better readable for beginners (others m uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); - +#ifdef USE_UNISHOX_COMPRESSION +#define USE_SCRIPT_COMPRESSION +#endif // solve conficting defines // highest priority #ifdef USE_SCRIPT_FATFS #undef LITTLEFS_SCRIPT_SIZE #undef EEP_SCRIPT_SIZE -#undef USE_UNISHOX_COMPRESSION +#undef USE_SCRIPT_COMPRESSION #if USE_SCRIPT_FATFS==-1 #ifdef ESP32 #error "script fat file option -1 currently not supported for ESP32" @@ -89,13 +91,13 @@ uint32_t DecodeLightId(uint32_t hue_id); // lfs on esp8266 spiffs on esp32 #ifdef LITTLEFS_SCRIPT_SIZE #undef EEP_SCRIPT_SIZE -#undef USE_UNISHOX_COMPRESSION +#undef USE_SCRIPT_COMPRESSION #pragma message "script little file system option used" #endif // LITTLEFS_SCRIPT_SIZE // eeprom script #ifdef EEP_SCRIPT_SIZE -#undef USE_UNISHOX_COMPRESSION +#undef USE_SCRIPT_COMPRESSION #ifdef USE_24C256 #pragma message "script 24c256 file option used" #else @@ -105,12 +107,12 @@ uint32_t DecodeLightId(uint32_t hue_id); #endif // EEP_SCRIPT_SIZE // compression last option before default -#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SCRIPT_COMPRESSION #pragma message "script compression option used" #endif // USE_UNISHOX_COMPRESSION -#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SCRIPT_COMPRESSION #include #define SCRIPT_COMPRESS compressor.unishox_compress @@ -118,7 +120,7 @@ uint32_t DecodeLightId(uint32_t hue_id); #ifndef UNISHOXRSIZE #define UNISHOXRSIZE 2560 #endif -#endif // USE_UNISHOX_COMPRESSION +#endif // USE_SCRIPT_COMPRESSION #ifdef USE_SCRIPT_TIMER #include @@ -3370,7 +3372,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { lp=GetNumericResult(lp,OPER_EQU,&cv_inc,0); //SCRIPT_SKIP_EOL cv_ptr=lp; - if (*cv_count 0) { @@ -4577,7 +4581,7 @@ void SaveScriptEnd(void) { } else { AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); } -#endif // USE_UNISHOX_COMPRESSION +#endif // USE_SCRIPT_COMPRESSION if (bitRead(Settings.rule_enabled, 0)) { int16_t res=Init_Scripter(); @@ -5400,12 +5404,181 @@ String ScriptUnsubscribe(const char * data, int data_len) #ifdef USE_SCRIPT_WEB_DISPLAY +#ifdef SCRIPT_FULL_WEBPAGE +const char HTTP_WEB_FULL_DISPLAY[] PROGMEM = + "

    "; + +const char HTTP_SCRIPT_FULLPAGE1[] PROGMEM = + "" + "" + "" + "" + "%s - %s" + ""; + + +#ifdef USE_SCRIPT_FATFS + +const char HTTP_SCRIPT_MIMES[] PROGMEM = + "HTTP/1.1 200 OK\r\n" + "Content-disposition: inline; filename=%s" + "Content-type: %s\r\n\r\n"; + +void ScriptGetSDCard(void) { + if (!HttpCheckPriviledgedAccess()) { return; } + + String stmp = Webserver->uri(); + char *cp=strstr(stmp.c_str(),"/sdc/"); +// if (cp) Serial.printf(">>>%s\n",cp); + if (cp) { +#ifdef ESP32 + cp+=4 +#else + cp+=5; +#endif + if (fsp->exists(cp)) { + SendFile(cp); + return; + } + } + HandleNotFound(); +} +#endif // USE_SCRIPT_FATFS + +void SendFile(char *fname) { +char buff[512]; + const char *mime; + char *jpg=strstr(fname,".jpg"); + if (jpg) { + mime="image/jpeg"; + } + char *html=strstr(fname,".html"); + if (html) { + mime="text/html"; + } + char *txt=strstr(fname,".txt"); + if (txt) { + mime="text/plain"; + } + + WSContentSend_P(HTTP_SCRIPT_MIMES,fname,mime); + + + File file=fsp->open(fname,FILE_READ); + uint32_t siz = file.size(); + uint32_t len=sizeof(buff); + while (siz > 0) { + if (len>siz) len=siz; + file.read((uint8_t *)buff,len ); + Webserver->client().write((const char*)buff, len); + siz -= len; + } + file.close(); + + Webserver->client().stop(); +} + +void ScriptFullWebpage(void) { + uint32_t fullpage_refresh=10000; + if (!HttpCheckPriviledgedAccess()) { return; } + + String stmp = Webserver->uri(); + + if (Webserver->hasArg("m")) { // Status refresh requested + if (Webserver->hasArg("sv")) { + Script_Check_HTML_Setvars(); + } + WSContentBegin(200, CT_HTML); + ScriptWebShow('w'); + WSContentEnd(); + Serial.printf("fwp update sv %s\n",stmp.c_str() ); + return; //goto redraw; +// } else { + // Serial.printf("fwp update %s\n",stmp.c_str() ); + // } + + return; + } else { + Serial.printf("fwp other %s\n",stmp.c_str() ); + } + + WSContentBegin(200, CT_HTML); + const char *title="Full Screen"; + WSContentSend_P(HTTP_SCRIPT_FULLPAGE1, SettingsText(SET_DEVICENAME), title, fullpage_refresh); + WSContentSend_P(HTTP_SCRIPT_FULLPAGE2, fullpage_refresh); + //WSContentSend_P(PSTR("
    ")); + + //WSContentSendStyle(); + + + WSContentSend_P(PSTR("
    ")); + ScriptWebShow('w'); + WSContentSend_P(PSTR("
    ")); + + ScriptWebShow('x'); + + WSContentStop(); +} +#endif //SCRIPT_FULL_WEBPAGE + void Script_Check_HTML_Setvars(void) { if (!HttpCheckPriviledgedAccess()) { return; } if (Webserver->hasArg("sv")) { String stmp = Webserver->arg("sv"); + Serial.printf("fwp has arg dv %s\n",stmp.c_str()); char cmdbuf[64]; memset(cmdbuf,0,sizeof(cmdbuf)); char *cp=cmdbuf; @@ -5610,13 +5783,29 @@ uint32_t cnt; } void ScriptWebShow(char mc) { - uint8_t web_script=Run_Scripter(">W",-2,0); + uint8_t web_script,xflg=0; + if (mc=='w' || mc=='x') { + if (mc=='x') { + xflg=1; + mc='$'; + } + web_script=Run_Scripter(">w",-2,0); + } else { + web_script=Run_Scripter(">W",-2,0); + } + if (web_script==99) { char tmp[256]; uint8_t optflg=0; uint8_t chartindex=1; uint8_t google_libs=0; char *lp=glob_script_mem.section_ptr+2; + if (mc=='w') { + while (*lp) { + if (*lp=='\n') break; + lp++; + } + } while (lp) { while (*lp==SCRIPT_EOL) { lp++; @@ -5628,7 +5817,7 @@ void ScriptWebShow(char mc) { // send this line to web Replace_Cmd_Vars(lp,1,tmp,sizeof(tmp)); char *lin=tmp; - if (!mc && (*lin!='$')) { + if ((!mc && (*lin!='$')) || (mc=='w' && (*lin!='$'))) { // normal web section if (*lin=='@') { lin++; @@ -5788,18 +5977,24 @@ void ScriptWebShow(char mc) { WSContentSend_PD(SCRIPT_MSG_NUMINP,label,minstr,maxstr,stepstr,vstr,vname); } else { - if (optflg) { - WSContentSend_PD(PSTR("
    %s
    "),tmp); + if (mc=='w') { + WSContentSend_PD(PSTR("%s"),tmp); } else { - WSContentSend_PD(PSTR("{s}%s{e}"),tmp); + if (optflg) { + WSContentSend_PD(PSTR("
    %s
    "),tmp); + } else { + WSContentSend_PD(PSTR("{s}%s{e}"),tmp); + } } } // end standard web interface } else { // main section interface if (*lin==mc) { + #ifdef USE_GOOGLE_CHARTS lin++; +exgc: char *lp; if (!strncmp(lin,"gc(",3)) { // get google table @@ -6007,6 +6202,8 @@ void ScriptWebShow(char mc) { WSContentSend_PD(PSTR("%s"),lin); } #else + lin++; + WSContentSend_PD(PSTR("%s"),lin); } else { // WSContentSend_PD(PSTR("%s"),lin); #endif //USE_GOOGLE_CHARTS @@ -6258,6 +6455,18 @@ uint32_t call2https(const char *host, const char *path) { #endif // SCRIPT_GET_HTTPS_JP + +void cpy2lf(char *dst,uint32_t dstlen, char *src) { + for (uint32_t cnt=0; cnt0) glob_script_mem.script_ram[len_decompressed]=0; //AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); -#endif // USE_UNISHOX_COMPRESSION +#endif // USE_SCRIPT_COMPRESSION #ifdef USE_BUTTON_EVENT for (uint32_t cnt=0;cntw",-2,0); + if (web_script==99) { + char bname[48]; + cpy2lf(bname,sizeof(bname),glob_script_mem.section_ptr+3); + WSContentSend_PD(HTTP_WEB_FULL_DISPLAY,bname); + Webserver->on("/sfd", ScriptFullWebpage); +#ifdef USE_SCRIPT_FATFS + Webserver->onNotFound(ScriptGetSDCard); +#endif + } +#endif // SCRIPT_FULL_WEBPAGE } break; #endif // USE_SCRIPT_WEB_DISPLAY From b802d34c42b672fbd9ae9b46803db6fce613ae5c Mon Sep 17 00:00:00 2001 From: Mark Hansen Date: Sat, 27 Jun 2020 12:04:32 +1000 Subject: [PATCH 351/581] Move #define USE_PROMETHEUS to my_user_config.h This is where all the other #defines live. This should make it easier to find the #define for enabling prometheus. --- tasmota/my_user_config.h | 3 +++ tasmota/xsns_91_prometheus.ino | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 45345c771..e1e75e4b1 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -741,6 +741,9 @@ #define THERMOSTAT_TEMP_BAND_NO_PEAK_DET 1 // Default temperature band in thenths of degrees celsius within no peak will be detected #define THERMOSTAT_TIME_STD_DEV_PEAK_DET_OK 10 // Default standard deviation in minutes of the oscillation periods within the peak detection is successful +// -- Prometheus exporter --------------------------- +//#define USE_PROMETHEUS // Add support for https://prometheus.io/ metrics exporting over HTTP /metrics endpoint + // -- End of general directives ------------------- /*********************************************************************************************\ diff --git a/tasmota/xsns_91_prometheus.ino b/tasmota/xsns_91_prometheus.ino index 9e29afe75..aa4d02ad4 100644 --- a/tasmota/xsns_91_prometheus.ino +++ b/tasmota/xsns_91_prometheus.ino @@ -17,8 +17,6 @@ along with this program. If not, see . */ -//#define USE_PROMETHEUS // Enable retrieval of metrics - #ifdef USE_PROMETHEUS /*********************************************************************************************\ * Prometheus support From f741f432628f01ba47dde876c185c51cdadaa85e Mon Sep 17 00:00:00 2001 From: Mark Hansen Date: Sat, 27 Jun 2020 12:10:00 +1000 Subject: [PATCH 352/581] Add tasmota_boot_count prometheus metric --- tasmota/xsns_91_prometheus.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/xsns_91_prometheus.ino b/tasmota/xsns_91_prometheus.ino index 9e29afe75..a2e03557f 100644 --- a/tasmota/xsns_91_prometheus.ino +++ b/tasmota/xsns_91_prometheus.ino @@ -38,6 +38,7 @@ void HandleMetrics(void) char parameter[FLOATSZ]; WSContentSend_P(PSTR("# TYPE tasmota_uptime_seconds gauge\ntasmota_uptime_seconds %d\n"), uptime); + WSContentSend_P(PSTR("# TYPE tasmota_boot_count counter\ntasmota_boot_count %d\n"), Settings.bootcount); if (!isnan(global_temperature)) { dtostrfd(global_temperature, Settings.flag2.temperature_resolution, parameter); From 1866938cbd74f5aafa6ab942ca4cce447e372200 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 27 Jun 2020 11:52:44 +0200 Subject: [PATCH 353/581] Integrate prometheus --- tasmota/support_features.ino | 5 +++-- tasmota/{xsns_91_prometheus.ino => xsns_75_prometheus.ino} | 6 +++--- tools/decode-status.py | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) rename tasmota/{xsns_91_prometheus.ino => xsns_75_prometheus.ino} (96%) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index abd5f4236..4dc1ee416 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -590,8 +590,9 @@ void GetFeatures(void) #ifdef USE_LMT01 feature6 |= 0x00080000; // xsns_74_lmt01.ino #endif - -// feature6 |= 0x00100000; +#ifdef USE_PROMETHEUS + feature6 |= 0x00100000; // xsns_75_prometheus.ino +#endif // feature6 |= 0x00200000; // feature6 |= 0x00400000; // feature6 |= 0x00800000; diff --git a/tasmota/xsns_91_prometheus.ino b/tasmota/xsns_75_prometheus.ino similarity index 96% rename from tasmota/xsns_91_prometheus.ino rename to tasmota/xsns_75_prometheus.ino index 16d98fc64..5f50f8a2d 100644 --- a/tasmota/xsns_91_prometheus.ino +++ b/tasmota/xsns_75_prometheus.ino @@ -1,5 +1,5 @@ /* - xsns_91_prometheus.ino - Web based information for Tasmota + xsns_75_prometheus.ino - Web based information for Tasmota Copyright (C) 2020 Theo Arends @@ -22,7 +22,7 @@ * Prometheus support \*********************************************************************************************/ -#define XSNS_91 91 +#define XSNS_75 75 void HandleMetrics(void) { @@ -85,7 +85,7 @@ void HandleMetrics(void) * Interface \*********************************************************************************************/ -bool Xsns91(uint8_t function) +bool Xsns75(uint8_t function) { bool result = false; diff --git a/tools/decode-status.py b/tools/decode-status.py index cdceced48..bdffa4ba3 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -207,7 +207,7 @@ a_features = [[ "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", "USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM", "USE_HP303B","USE_TCP_BRIDGE","USE_TELEINFO","USE_LMT01", - "","","","", + "USE_PROMETHEUS","","","", "","","","", "","","USE_ETHERNET","USE_WEBCAM" ]] @@ -243,7 +243,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200617 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200627 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From 76c61e85b3a1464173acb70849957a9decc3f9c8 Mon Sep 17 00:00:00 2001 From: Mark Hansen Date: Sat, 27 Jun 2020 21:21:11 +1000 Subject: [PATCH 354/581] Add tasmota_info prometheus psuedo-metric. Exports version, image type, and build timestamp. It's common to export something like this to show version numbers across the fleet. For example, the golang exporter exposes version: ``` go_info{version="go1.14.4"} 1 ``` And prometheus exposes: ``` prometheus_build_info{branch="HEAD",goversion="go1.14.4",revision="eba3fdcbf0d378b66600281903e3aab515732b39",version="2.19.1"} 1 ``` --- tasmota/xsns_75_prometheus.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasmota/xsns_75_prometheus.ino b/tasmota/xsns_75_prometheus.ino index 5f50f8a2d..542755f80 100644 --- a/tasmota/xsns_75_prometheus.ino +++ b/tasmota/xsns_75_prometheus.ino @@ -35,6 +35,9 @@ void HandleMetrics(void) char parameter[FLOATSZ]; + // Pseudo-metric providing metadata about the running firmware version. + WSContentSend_P(PSTR("# TYPE tasmota_info gauge\ntasmota_info{version=\"%s\",image=\"%s\",build_timestamp=\"%s\"} 1\n"), + my_version, my_image, GetBuildDateAndTime().c_str()); WSContentSend_P(PSTR("# TYPE tasmota_uptime_seconds gauge\ntasmota_uptime_seconds %d\n"), uptime); WSContentSend_P(PSTR("# TYPE tasmota_boot_count counter\ntasmota_boot_count %d\n"), Settings.bootcount); From 2e50cc507d5f5f01c304f1a08c63711905f73b76 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 27 Jun 2020 14:55:55 +0200 Subject: [PATCH 355/581] Minor Zigbee changes --- tasmota/xdrv_23_zigbee_5_converters.ino | 70 ++++++++++++----------- tasmota/xdrv_23_zigbee_7_statemachine.ino | 11 ++++ 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 7494715f3..98ad2dc5e 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -230,7 +230,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zstring, Cx0000, 0x0006, Z(DateCode), 1, Z_Nop }, { Zenum8, Cx0000, 0x0007, Z(PowerSource), 1, Z_Nop }, { Zstring, Cx0000, 0x4000, Z(SWBuildID), 1, Z_Nop }, - { Zunk, Cx0000, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values + // { Zunk, Cx0000, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Cmd 0x0A - Cluster 0x0000, attribute 0xFF01 - proprietary { Zmap8, Cx0000, 0xFF01, nullptr, 0, Z_AqaraSensor }, // Occupancy (map8) @@ -1220,38 +1220,44 @@ int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu // Aqara Cube int32_t Z_AqaraCubeFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { json[new_name] = value; // copy the original value - int32_t val = value; - const __FlashStringHelper *aqara_cube = F("AqaraCube"); - const __FlashStringHelper *aqara_cube_side = F("AqaraCubeSide"); - const __FlashStringHelper *aqara_cube_from_side = F("AqaraCubeFromSide"); - switch (val) { - case 0: - json[aqara_cube] = F("shake"); - break; - case 2: - json[aqara_cube] = F("wakeup"); - break; - case 3: - json[aqara_cube] = F("fall"); - break; - case 64 ... 127: - json[aqara_cube] = F("flip90"); - json[aqara_cube_side] = val % 8; - json[aqara_cube_from_side] = (val - 64) / 8; - break; - case 128 ... 132: - json[aqara_cube] = F("flip180"); - json[aqara_cube_side] = val - 128; - break; - case 256 ... 261: - json[aqara_cube] = F("slide"); - json[aqara_cube_side] = val - 256; - break; - case 512 ... 517: - json[aqara_cube] = F("tap"); - json[aqara_cube_side] = val - 512; - break; + const char * modelId_c = zigbee_devices.getModelId(shortaddr); // null if unknown + String modelId((char*) modelId_c); + + if (modelId.startsWith(F("lumi.sensor_cube."))) { // only for Aqara cube + int32_t val = value; + const __FlashStringHelper *aqara_cube = F("AqaraCube"); + const __FlashStringHelper *aqara_cube_side = F("AqaraCubeSide"); + const __FlashStringHelper *aqara_cube_from_side = F("AqaraCubeFromSide"); + + switch (val) { + case 0: + json[aqara_cube] = F("shake"); + break; + case 2: + json[aqara_cube] = F("wakeup"); + break; + case 3: + json[aqara_cube] = F("fall"); + break; + case 64 ... 127: + json[aqara_cube] = F("flip90"); + json[aqara_cube_side] = val % 8; + json[aqara_cube_from_side] = (val - 64) / 8; + break; + case 128 ... 132: + json[aqara_cube] = F("flip180"); + json[aqara_cube_side] = val - 128; + break; + case 256 ... 261: + json[aqara_cube] = F("slide"); + json[aqara_cube_side] = val - 256; + break; + case 512 ... 517: + json[aqara_cube] = F("tap"); + json[aqara_cube_side] = val - 512; + break; + } } // Source: https://github.com/kirovilya/ioBroker.zigbee diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index 16896fd0c..912a493ca 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -111,6 +111,8 @@ const uint8_t ZIGBEE_LABEL_START_ROUTER = 13; // Start ZNP as router const uint8_t ZIGBEE_LABEL_INIT_DEVICE = 14; // Init ZNP as end-device const uint8_t ZIGBEE_LABEL_START_DEVICE = 15; // Start ZNP as end-device const uint8_t ZIGBEE_LABEL_START_ROUTER_DEVICE = 16; // Start common to router and device +const uint8_t ZIGBEE_LABEL_BOOT_OK = 17; // MCU has rebooted +const uint8_t ZIGBEE_LABEL_BOOT_TIME_OUT = 18; // MCU has not rebooted const uint8_t ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST = 19; // common post configuration for router and device const uint8_t ZIGBEE_LABEL_READY = 20; // goto label 20 for main loop const uint8_t ZIGBEE_LABEL_MAIN_LOOP = 21; // main loop @@ -421,8 +423,17 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { //ZI_MQTT_STATE(ZIGBEE_STATUS_BOOT, "Booting") //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting device") + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_BOOT_TIME_OUT) // give a second chance ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &Z_Reboot) // timeout 5s + ZI_GOTO(ZIGBEE_LABEL_BOOT_OK) + + ZI_LABEL(ZIGBEE_LABEL_BOOT_TIME_OUT) + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) + ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 + ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &Z_Reboot) // timeout 5s + + ZI_LABEL(ZIGBEE_LABEL_BOOT_OK) ZI_WAIT(100) ZI_LOG(LOG_LEVEL_DEBUG, kCheckingDeviceConfiguration) // Log Debug: checking device configuration ZI_SEND(ZBS_VERSION) // check ZNP software version From a05e939be9fbf630f7cebb2e17c27037ce2ae059 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 27 Jun 2020 18:17:40 +0200 Subject: [PATCH 356/581] Add some zigbee webinfo --- tasmota/xdrv_01_webserver.ino | 2 - tasmota/xdrv_23_zigbee_5_converters.ino | 2 +- tasmota/xdrv_23_zigbee_8_parsers.ino | 7 ++- tasmota/xdrv_23_zigbee_A_impl.ino | 76 +++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index b5e5c9571..8ba98f91e 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1595,9 +1595,7 @@ bool HandleRootStatusRefresh(void) WSContentBegin(200, CT_HTML); WSContentSend_P(PSTR("{t}")); XsnsCall(FUNC_WEB_SENSOR); -#ifdef USE_SCRIPT_WEB_DISPLAY XdrvCall(FUNC_WEB_SENSOR); -#endif WSContentSend_P(PSTR("")); diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 98ad2dc5e..4835306a5 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -1223,7 +1223,7 @@ int32_t Z_AqaraCubeFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObjec const char * modelId_c = zigbee_devices.getModelId(shortaddr); // null if unknown String modelId((char*) modelId_c); - + if (modelId.startsWith(F("lumi.sensor_cube."))) { // only for Aqara cube int32_t val = value; const __FlashStringHelper *aqara_cube = F("AqaraCube"); diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index d7e1ba565..5699801d8 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -757,15 +757,18 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { linkquality, securityuse, seqnumber, timestamp); zcl_received.log(); + + ZdSetLinkQuality(srcaddr, linkquality); + char shortaddr[8]; snprintf_P(shortaddr, sizeof(shortaddr), PSTR("0x%04X"), srcaddr); DynamicJsonBuffer jsonBuffer; JsonObject& json = jsonBuffer.createObject(); - + if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_DEFAULT_RESPONSE == zcl_received.getCmdId())) { zcl_received.parseResponse(); // Zigbee general "Degault Response", publish ZbResponse message - } else { + } else { // Build the ZbReceive json if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_REPORT_ATTRIBUTES == zcl_received.getCmdId())) { zcl_received.parseReportAttributes(json); // Zigbee report attributes from sensors diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index bfb3015d4..c8c28e995 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1068,6 +1068,77 @@ void CmndZbConfig(void) { hex_precfgkey_l, hex_precfgkey_h); } +/*********************************************************************************************\ + * Database of linkqualities - there must be a better way to implement this ... +\*********************************************************************************************/ + +const uint8_t MAX_ZBRECORDS = 16; + +typedef struct Z_DevRecord_t { + uint16_t shortaddr; + uint8_t linkquality; +} Z_DevRecord_t; + +Z_DevRecord_t Z_DevRecord[MAX_ZBRECORDS]; +uint8_t Z_DevIndex = 0; + +void ZdSetLinkQuality(uint16_t shortaddr, uint8_t linkquality) { + if (Z_DevIndex < MAX_ZBRECORDS) { + uint32_t i; + for (i = 0; i < Z_DevIndex; i++) { + if (shortaddr == Z_DevRecord[i].shortaddr) { + Z_DevRecord[i].linkquality = linkquality; + return; + } + } + Z_DevRecord[i].shortaddr = shortaddr; + Z_DevRecord[i].linkquality = linkquality; + Z_DevIndex++; + } +} + +uint8_t ZdGetLinkQuality(uint16_t shortaddr) { + for (uint32_t i = 0; i < Z_DevIndex; i++) { + if (shortaddr == Z_DevRecord[i].shortaddr) { + return Z_DevRecord[i].linkquality; + } + } + return 0; +} + +/*********************************************************************************************\ + * Presentation +\*********************************************************************************************/ + +void ZigbeeShow(bool json) +{ + if (json) { + return; +#ifdef USE_WEBSERVER + } else { + char spart1[33]; + char spart2[8]; + + uint32_t zigbee_num = zigbee_devices.devicesSize(); + for (uint32_t i = 0; i < zigbee_num; i++) { + uint16_t shortaddr = zigbee_devices.devicesAt(i).shortaddr; + char *name = (char*)zigbee_devices.getFriendlyName(shortaddr); + if (nullptr == name) { + snprintf_P(spart1, sizeof(spart1), PSTR(D_DEVICE " 0x%04X"), shortaddr); + name = spart1; + } + snprintf_P(spart2, sizeof(spart2), PSTR("-")); + uint8_t lq = ZdGetLinkQuality(shortaddr); + if (lq) { + snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lq); + } + + WSContentSend_PD(PSTR("{s}%s{m}LQ %s{e}"), name, spart2); + } +#endif + } +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -1089,6 +1160,11 @@ bool Xdrv23(uint8_t function) ZigbeeStateMachine_Run(); } break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + ZigbeeShow(false); + break; +#endif // USE_WEBSERVER case FUNC_PRE_INIT: ZigbeeInit(); break; From a212b3ca7da9343275b8b25137410cfe703f3a50 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 27 Jun 2020 22:20:32 +0200 Subject: [PATCH 357/581] Change zigbee LQ to LQI --- tasmota/xdrv_23_zigbee_A_impl.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index c8c28e995..935257e8e 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1083,7 +1083,7 @@ Z_DevRecord_t Z_DevRecord[MAX_ZBRECORDS]; uint8_t Z_DevIndex = 0; void ZdSetLinkQuality(uint16_t shortaddr, uint8_t linkquality) { - if (Z_DevIndex < MAX_ZBRECORDS) { + if (Z_DevIndex < MAX_ZBRECORDS -1) { uint32_t i; for (i = 0; i < Z_DevIndex; i++) { if (shortaddr == Z_DevRecord[i].shortaddr) { @@ -1133,7 +1133,7 @@ void ZigbeeShow(bool json) snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lq); } - WSContentSend_PD(PSTR("{s}%s{m}LQ %s{e}"), name, spart2); + WSContentSend_PD(PSTR("{s}%s{m}LQI %s{e}"), name, spart2); } #endif } From e9f88af959de6c783661dd180e7361a06ded96b0 Mon Sep 17 00:00:00 2001 From: Mark Hansen Date: Sun, 28 Jun 2020 11:43:29 +1000 Subject: [PATCH 358/581] Add WiFi metrics to prometheus exporter --- tasmota/xsns_75_prometheus.ino | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tasmota/xsns_75_prometheus.ino b/tasmota/xsns_75_prometheus.ino index 542755f80..7bdaa7995 100644 --- a/tasmota/xsns_75_prometheus.ino +++ b/tasmota/xsns_75_prometheus.ino @@ -41,6 +41,13 @@ void HandleMetrics(void) WSContentSend_P(PSTR("# TYPE tasmota_uptime_seconds gauge\ntasmota_uptime_seconds %d\n"), uptime); WSContentSend_P(PSTR("# TYPE tasmota_boot_count counter\ntasmota_boot_count %d\n"), Settings.bootcount); + + // Pseudo-metric providing metadata about the WiFi station. + WSContentSend_P(PSTR("# TYPE tasmota_wifi_station_info gauge\ntasmota_wifi_station_info{bssid=\"%s\",ssid=\"%s\"} 1\n"), WiFi.BSSIDstr().c_str(), WiFi.SSID().c_str()); + + // Wi-Fi Signal strength + WSContentSend_P(PSTR("# TYPE tasmota_wifi_station_signal_dbm gauge\ntasmota_wifi_station_signal_dbm{mac_address=\"%s\"} %d\n"), WiFi.BSSIDstr().c_str(), WiFi.RSSI()); + if (!isnan(global_temperature)) { dtostrfd(global_temperature, Settings.flag2.temperature_resolution, parameter); WSContentSend_P(PSTR("# TYPE global_temperature gauge\nglobal_temperature %s\n"), parameter); From 7dafeb280e08d64b7603d7204aebb816fb17714d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 28 Jun 2020 12:23:18 +0200 Subject: [PATCH 359/581] Rename global temp and pressure - Rename global temp and pressure (#8808, #8810) - Fix SGP30 calculation (#8808) --- tasmota/support.ino | 8 ++++---- tasmota/support_command.ino | 2 +- tasmota/tasmota.ino | 4 ++-- tasmota/xdrv_03_energy.ino | 4 ++-- tasmota/xdrv_10_scripter.ino | 4 ++-- tasmota/xsns_21_sgp30.ino | 14 +++++--------- tasmota/xsns_31_ccs811.ino | 4 ++-- tasmota/xsns_75_prometheus.ino | 12 ++++++------ 8 files changed, 24 insertions(+), 28 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 427a47dcf..1d05ae2d1 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -601,7 +601,7 @@ float ConvertTemp(float c) float result = c; global_update = uptime; - global_temperature = c; + global_temperature_celsius = c; if (!isnan(c) && Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit result = c * 1.8 + 32; // Fahrenheit @@ -661,7 +661,7 @@ float ConvertPressure(float p) float result = p; global_update = uptime; - global_pressure = p; + global_pressure_hpa = p; if (!isnan(p) && Settings.flag.pressure_conversion) { // SetOption24 - Switch between hPa or mmHg pressure unit result = p * 0.75006375541921; // mmHg @@ -690,9 +690,9 @@ void ResetGlobalValues(void) { if ((uptime - global_update) > GLOBAL_VALUES_VALID) { // Reset after 5 minutes global_update = 0; - global_temperature = NAN; + global_temperature_celsius = NAN; global_humidity = 0.0f; - global_pressure = 0.0f; + global_pressure_hpa = 0.0f; } } diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 9c4c858cc..2df30eb25 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -631,7 +631,7 @@ void CmndGlobalTemp(void) global_update = 1; // Keep global values just entered valid } } - ResponseCmndFloat(global_temperature, 1); + ResponseCmndFloat(global_temperature_celsius, 1); } void CmndGlobalHum(void) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index abc95d5d9..24b100541 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -111,9 +111,9 @@ uint32_t uptime = 0; // Counting every second until 42949 uint32_t loop_load_avg = 0; // Indicative loop load average uint32_t global_update = 0; // Timestamp of last global temperature and humidity update uint32_t web_log_index = 1; // Index in Web log buffer (should never be 0) -float global_temperature = NAN; // Provide a global temperature to be used by some sensors +float global_temperature_celsius = NAN; // Provide a global temperature to be used by some sensors float global_humidity = 0.0f; // Provide a global humidity to be used by some sensors -float global_pressure = 0.0f; // Provide a global pressure to be used by some sensors +float global_pressure_hpa = 0.0f; // Provide a global pressure to be used by some sensors uint16_t tele_period = 9999; // Tele period timer uint16_t blink_counter = 0; // Number of blink cycles uint16_t seriallog_timer = 0; // Timer to disable Seriallog diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index b84d69407..f38265bb8 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -459,10 +459,10 @@ void EnergyEverySecond(void) { // Overtemp check if (global_update) { - if (power && !isnan(global_temperature) && (global_temperature > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays + if (power && !isnan(global_temperature_celsius) && (global_temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays char temperature[33]; - dtostrfd(global_temperature, 1, temperature); + dtostrfd(global_temperature_celsius, 1, temperature); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %s"), temperature); SetAllPower(POWER_ALL_OFF, SRC_OVERTEMP); diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index e6c515b5d..cbd1c9d46 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -1898,7 +1898,7 @@ chknext: break; case 'g': if (!strncmp(vname,"gtmp",4)) { - fvar=global_temperature; + fvar=global_temperature_celsius; goto exit; } if (!strncmp(vname,"ghum",4)) { @@ -1906,7 +1906,7 @@ chknext: goto exit; } if (!strncmp(vname,"gprs",4)) { - fvar=global_pressure; + fvar=global_pressure_hpa; goto exit; } if (!strncmp(vname,"gtopic",6)) { diff --git a/tasmota/xsns_21_sgp30.ino b/tasmota/xsns_21_sgp30.ino index ec1e85258..6f52f14a4 100644 --- a/tasmota/xsns_21_sgp30.ino +++ b/tasmota/xsns_21_sgp30.ino @@ -55,7 +55,7 @@ void sgp30_Init(void) //#define POW_FUNC pow #define POW_FUNC FastPrecisePow -float sgp30_AbsoluteHumidity(float temperature, float humidity,char tempUnit) { +float sgp30_AbsoluteHumidity(float temperature, float humidity) { //taken from https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/ //precision is about 0.1°C in range -30 to 35°C //August-Roche-Magnus 6.1094 exp(17.625 x T)/(T + 243.04) @@ -69,10 +69,6 @@ float sgp30_AbsoluteHumidity(float temperature, float humidity,char tempUnit) { return NAN; } - if (tempUnit != 'C') { - temperature = (temperature - 32.0) * (5.0 / 9.0); /*conversion to [°C]*/ - } - temp = POW_FUNC(2.718281828, (17.67 * temperature) / (temperature + 243.5)); //return (6.112 * temp * humidity * 2.1674) / (273.15 + temperature); //simplified version @@ -87,9 +83,9 @@ void Sgp30Update(void) // Perform every second to ensure proper operation of th if (!sgp.IAQmeasure()) { return; // Measurement failed } - if (global_update && (global_humidity > 0) && !isnan(global_temperature)) { + if (global_update && (global_humidity > 0) && !isnan(global_temperature_celsius)) { // abs hum in mg/m3 - sgp30_abshum=sgp30_AbsoluteHumidity(global_temperature,global_humidity,TempUnit()); + sgp30_abshum = sgp30_AbsoluteHumidity(global_temperature_celsius, global_humidity); sgp.setHumidity(sgp30_abshum*1000); } sgp30_ready = true; @@ -119,13 +115,13 @@ void Sgp30Show(bool json) if (sgp30_ready) { char abs_hum[33]; - if (global_update && (global_humidity > 0) && !isnan(global_temperature)) { + if (global_update && (global_humidity > 0) && !isnan(global_temperature_celsius)) { // has humidity + temperature dtostrfd(sgp30_abshum,4,abs_hum); } if (json) { ResponseAppend_P(PSTR(",\"SGP30\":{\"" D_JSON_ECO2 "\":%d,\"" D_JSON_TVOC "\":%d"), sgp.eCO2, sgp.TVOC); - if (global_update && global_humidity>0 && !isnan(global_temperature)) { + if (global_update && global_humidity>0 && !isnan(global_temperature_celsius)) { ResponseAppend_P(PSTR(",\"" D_JSON_AHUM "\":%s"),abs_hum); } ResponseJsonEnd(); diff --git a/tasmota/xsns_31_ccs811.ino b/tasmota/xsns_31_ccs811.ino index aada03d04..71bac8240 100644 --- a/tasmota/xsns_31_ccs811.ino +++ b/tasmota/xsns_31_ccs811.ino @@ -65,8 +65,8 @@ void CCS811Update(void) // Perform every n second TVOC = ccs.getTVOC(); eCO2 = ccs.geteCO2(); CCS811_ready = 1; - if (global_update && (global_humidity > 0) && !isnan(global_temperature)) { - ccs.setEnvironmentalData((uint8_t)global_humidity, global_temperature); + if (global_update && (global_humidity > 0) && !isnan(global_temperature_celsius)) { + ccs.setEnvironmentalData((uint8_t)global_humidity, global_temperature_celsius); } ecnt = 0; } diff --git a/tasmota/xsns_75_prometheus.ino b/tasmota/xsns_75_prometheus.ino index 7bdaa7995..fd4396a75 100644 --- a/tasmota/xsns_75_prometheus.ino +++ b/tasmota/xsns_75_prometheus.ino @@ -48,17 +48,17 @@ void HandleMetrics(void) // Wi-Fi Signal strength WSContentSend_P(PSTR("# TYPE tasmota_wifi_station_signal_dbm gauge\ntasmota_wifi_station_signal_dbm{mac_address=\"%s\"} %d\n"), WiFi.BSSIDstr().c_str(), WiFi.RSSI()); - if (!isnan(global_temperature)) { - dtostrfd(global_temperature, Settings.flag2.temperature_resolution, parameter); - WSContentSend_P(PSTR("# TYPE global_temperature gauge\nglobal_temperature %s\n"), parameter); + if (!isnan(global_temperature_celsius)) { + dtostrfd(global_temperature_celsius, Settings.flag2.temperature_resolution, parameter); + WSContentSend_P(PSTR("# TYPE global_temperature_celsius gauge\nglobal_temperature_celsius %s\n"), parameter); } if (global_humidity != 0) { dtostrfd(global_humidity, Settings.flag2.humidity_resolution, parameter); WSContentSend_P(PSTR("# TYPE global_humidity gauge\nglobal_humidity %s\n"), parameter); } - if (global_pressure != 0) { - dtostrfd(global_pressure, Settings.flag2.pressure_resolution, parameter); - WSContentSend_P(PSTR("# TYPE global_pressure gauge\nglobal_pressure %s\n"), parameter); + if (global_pressure_hpa != 0) { + dtostrfd(global_pressure_hpa, Settings.flag2.pressure_resolution, parameter); + WSContentSend_P(PSTR("# TYPE global_pressure_hpa gauge\nglobal_pressure_hpa %s\n"), parameter); } #ifdef USE_ENERGY_SENSOR From 609b0309faa2342d4f67584cbb520ed29a55f26b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 28 Jun 2020 12:54:44 +0200 Subject: [PATCH 360/581] Try to fix mi desk lamp Try to fix mi desk lamp (#8748) --- tasmota/support_rotary.ino | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 6d79744f4..f7543be0b 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -127,7 +127,9 @@ void RotaryHandler(void) DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), Rotary.position - Rotary.last_position); LightSetColorTemp((uint16_t)t); } else { - int8_t d = Settings.light_dimmer; +// int8_t d = Settings.light_dimmer; + int8_t d = LightGetDimmer(0); + d = d + (Rotary.position - Rotary.last_position); if (d < 1) { d = 1; @@ -135,10 +137,11 @@ void RotaryHandler(void) if (d > 100) { d = 100; } - DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), Rotary.position - Rotary.last_position); +// DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), Rotary.position - Rotary.last_position); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), d); LightSetDimmer((uint8_t)d); - Settings.light_dimmer = d; +// Settings.light_dimmer = d; } } Rotary.last_position = 128; From 4af6b7d5404f5e47f92a3416aadbec52e0de3330 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 28 Jun 2020 17:53:59 +0200 Subject: [PATCH 361/581] Moved LQI to Zigbee devices --- tasmota/xdrv_23_zigbee_2_devices.ino | 38 +++++++++++++++++++++ tasmota/xdrv_23_zigbee_5_converters.ino | 41 ++++++++++------------- tasmota/xdrv_23_zigbee_8_parsers.ino | 2 +- tasmota/xdrv_23_zigbee_A_impl.ino | 44 ++----------------------- 4 files changed, 60 insertions(+), 65 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 23a9343d4..991646d06 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -71,6 +71,8 @@ typedef struct Z_Device { uint16_t ct; // last CT: 153-500 uint16_t hue; // last Hue: 0..359 uint16_t x, y; // last color [x,y] + uint8_t linkquality; // lqi from last message, 0xFF means unknown + uint8_t batterypercentx2;// battery percentage x 2 (0..200), 0xFF means unknwon } Z_Device; /*********************************************************************************************\ @@ -147,6 +149,10 @@ public: const char * getModelId(uint16_t shortaddr) const; const char * getManufacturerId(uint16_t shortaddr) const; void setReachable(uint16_t shortaddr, bool reachable); + void setLQI(uint16_t shortaddr, uint8_t lqi); + uint8_t getLQI(uint16_t shortaddr) const; + void setBatteryPercentx2(uint16_t shortaddr, uint8_t bpx2); + uint8_t getBatteryPercentx2(uint16_t shortaddr) const; // get next sequence number for (increment at each all) uint8_t getNextSeqNumber(uint16_t shortaddr); @@ -294,6 +300,8 @@ Z_Device & Z_Devices::createDeviceEntry(uint16_t shortaddr, uint64_t longaddr) { 200, // ct 0, // hue 0, 0, // x, y + 0xFF, // lqi, 0xFF = unknown + 0xFF // battery percentage x 2, 0xFF means unknown }; device_alloc->json_buffer = new DynamicJsonBuffer(16); @@ -619,6 +627,36 @@ void Z_Devices::setReachable(uint16_t shortaddr, bool reachable) { bitWrite(device.power, 7, reachable); } +void Z_Devices::setLQI(uint16_t shortaddr, uint8_t lqi) { + Z_Device & device = getShortAddr(shortaddr); + if (&device == nullptr) { return; } // don't crash if not found + device.linkquality = lqi; +} + +uint8_t Z_Devices::getLQI(uint16_t shortaddr) const { + int32_t found = findShortAddr(shortaddr); + if (found >= 0) { + const Z_Device & device = devicesAt(found); + return device.linkquality; + } + return 0xFF; +} + +void Z_Devices::setBatteryPercentx2(uint16_t shortaddr, uint8_t bpx2) { + Z_Device & device = getShortAddr(shortaddr); + if (&device == nullptr) { return; } // don't crash if not found + device.batterypercentx2 = bpx2; +} + +uint8_t Z_Devices::getBatteryPercentx2(uint16_t shortaddr) const { + int32_t found = findShortAddr(shortaddr); + if (found >= 0) { + const Z_Device & device = devicesAt(found); + return device.batterypercentx2; + } + return 0xFF; +} + // get the next sequance number for the device, or use the global seq number if device is unknown uint8_t Z_Devices::getNextSeqNumber(uint16_t shortaddr) { int32_t short_found = findShortAddr(shortaddr); diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 4835306a5..9488918b3 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -128,6 +128,7 @@ enum Z_ConvOperators { Z_AqaraSensor, // decode prioprietary Aqara Sensor message Z_AqaraVibration, // decode Aqara vibration modes Z_AqaraCube, // decode Aqara cube + Z_BatteryPercentage, // memorize Battery Percentage in RAM }; ZF(ZCLVersion) ZF(AppVersion) ZF(StackVersion) ZF(HWVersion) ZF(Manufacturer) ZF(ModelId) @@ -238,7 +239,7 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = { { Zuint16, Cx0001, 0x0000, Z(MainsVoltage), 1, Z_Nop }, { Zuint8, Cx0001, 0x0001, Z(MainsFrequency), 1, Z_Nop }, { Zuint8, Cx0001, 0x0020, Z(BatteryVoltage), -10,Z_Nop }, // divide by 10 - { Zuint8, Cx0001, 0x0021, Z(BatteryPercentage), -2, Z_Nop }, // divide by 2 + { Zuint8, Cx0001, 0x0021, Z(BatteryPercentage), -2, Z_BatteryPercentage }, // divide by 2 // Device Temperature Configuration cluster { Zint16, Cx0002, 0x0000, Z(CurrentTemperature), 1, Z_Nop }, @@ -1176,16 +1177,19 @@ void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) { // ====================================================================== // Record Manuf int32_t Z_ManufKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = value; zigbee_devices.setManufId(shortaddr, value.as()); return 1; } -// +// Record ModelId int32_t Z_ModelKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = value; zigbee_devices.setModelId(shortaddr, value.as()); return 1; } +// Record BatteryPercentage +int32_t Z_BatteryPercentageKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { + zigbee_devices.setBatteryPercentx2(shortaddr, value.as()); + return 1; +} // Add pressure unit int32_t Z_AddPressureUnitFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { @@ -1193,22 +1197,6 @@ int32_t Z_AddPressureUnitFunc(const class ZCLFrame *zcl, uint16_t shortaddr, Jso return 0; // keep original key } -// Convert int to float and divide by 100 -int32_t Z_FloatDiv100Func(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = ((float)value) / 100.0f; - return 1; // remove original key -} -// Convert int to float and divide by 10 -int32_t Z_FloatDiv10Func(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = ((float)value) / 10.0f; - return 1; // remove original key -} -// Convert int to float and divide by 10 -int32_t Z_FloatDiv2Func(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = ((float)value) / 2.0f; - return 1; // remove original key -} - // Publish a message for `"Occupancy":0` when the timer expired int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) { DynamicJsonBuffer jsonBuffer; @@ -1219,8 +1207,6 @@ int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu // Aqara Cube int32_t Z_AqaraCubeFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = value; // copy the original value - const char * modelId_c = zigbee_devices.getModelId(shortaddr); // null if unknown String modelId((char*) modelId_c); @@ -1353,7 +1339,13 @@ int32_t Z_AqaraSensorFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObj json.remove(tmp); bool translated = false; // were we able to translate to a known format? if (0x01 == attrid) { - json[F(D_JSON_VOLTAGE)] = val / 1000.0f; + float batteryvoltage = val / 1000.0f; + json[F("BatteryVoltage")] = batteryvoltage; + uint8_t batterypercentage = toPercentageCR2032(val); + json[F("BatteryPercentage")] = batterypercentage; + zigbee_devices.setBatteryPercentx2(shortaddr, batterypercentage * 2); + // deprecated + json[F(D_JSON_VOLTAGE)] = batteryvoltage; json[F("Battery")] = toPercentageCR2032(val); } else if ((nullptr != modelId) && (0 == zcl->getManufCode())) { translated = true; @@ -1431,6 +1423,9 @@ int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObje case Z_AqaraCube: func = &Z_AqaraCubeFunc; break; + case Z_BatteryPercentage: + func = &Z_BatteryPercentageKeepFunc; + break; }; if (func) { diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 5699801d8..548c09a25 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -758,7 +758,7 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { timestamp); zcl_received.log(); - ZdSetLinkQuality(srcaddr, linkquality); + zigbee_devices.setLQI(srcaddr, linkquality); char shortaddr[8]; snprintf_P(shortaddr, sizeof(shortaddr), PSTR("0x%04X"), srcaddr); diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 935257e8e..489aece50 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1068,44 +1068,6 @@ void CmndZbConfig(void) { hex_precfgkey_l, hex_precfgkey_h); } -/*********************************************************************************************\ - * Database of linkqualities - there must be a better way to implement this ... -\*********************************************************************************************/ - -const uint8_t MAX_ZBRECORDS = 16; - -typedef struct Z_DevRecord_t { - uint16_t shortaddr; - uint8_t linkquality; -} Z_DevRecord_t; - -Z_DevRecord_t Z_DevRecord[MAX_ZBRECORDS]; -uint8_t Z_DevIndex = 0; - -void ZdSetLinkQuality(uint16_t shortaddr, uint8_t linkquality) { - if (Z_DevIndex < MAX_ZBRECORDS -1) { - uint32_t i; - for (i = 0; i < Z_DevIndex; i++) { - if (shortaddr == Z_DevRecord[i].shortaddr) { - Z_DevRecord[i].linkquality = linkquality; - return; - } - } - Z_DevRecord[i].shortaddr = shortaddr; - Z_DevRecord[i].linkquality = linkquality; - Z_DevIndex++; - } -} - -uint8_t ZdGetLinkQuality(uint16_t shortaddr) { - for (uint32_t i = 0; i < Z_DevIndex; i++) { - if (shortaddr == Z_DevRecord[i].shortaddr) { - return Z_DevRecord[i].linkquality; - } - } - return 0; -} - /*********************************************************************************************\ * Presentation \*********************************************************************************************/ @@ -1128,9 +1090,9 @@ void ZigbeeShow(bool json) name = spart1; } snprintf_P(spart2, sizeof(spart2), PSTR("-")); - uint8_t lq = ZdGetLinkQuality(shortaddr); - if (lq) { - snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lq); + uint8_t lqi = zigbee_devices.getLQI(shortaddr); + if (0xFF != lqi) { + snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lqi); } WSContentSend_PD(PSTR("{s}%s{m}LQI %s{e}"), name, spart2); From ac80807c4ed4ba4b082bbc6b8508abc9b70a03cd Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 28 Jun 2020 18:04:36 +0200 Subject: [PATCH 362/581] Removed the x2 to battery percentage --- tasmota/xdrv_23_zigbee_2_devices.ino | 14 +++++++------- tasmota/xdrv_23_zigbee_5_converters.ino | 4 ++-- tasmota/xdrv_23_zigbee_A_impl.ino | 5 +++++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 991646d06..9a71075c0 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -72,7 +72,7 @@ typedef struct Z_Device { uint16_t hue; // last Hue: 0..359 uint16_t x, y; // last color [x,y] uint8_t linkquality; // lqi from last message, 0xFF means unknown - uint8_t batterypercentx2;// battery percentage x 2 (0..200), 0xFF means unknwon + uint8_t batterypercent; // battery percentage (0..100), 0xFF means unknwon } Z_Device; /*********************************************************************************************\ @@ -151,8 +151,8 @@ public: void setReachable(uint16_t shortaddr, bool reachable); void setLQI(uint16_t shortaddr, uint8_t lqi); uint8_t getLQI(uint16_t shortaddr) const; - void setBatteryPercentx2(uint16_t shortaddr, uint8_t bpx2); - uint8_t getBatteryPercentx2(uint16_t shortaddr) const; + void setBatteryPercent(uint16_t shortaddr, uint8_t bp); + uint8_t getBatteryPercent(uint16_t shortaddr) const; // get next sequence number for (increment at each all) uint8_t getNextSeqNumber(uint16_t shortaddr); @@ -642,17 +642,17 @@ uint8_t Z_Devices::getLQI(uint16_t shortaddr) const { return 0xFF; } -void Z_Devices::setBatteryPercentx2(uint16_t shortaddr, uint8_t bpx2) { +void Z_Devices::setBatteryPercent(uint16_t shortaddr, uint8_t bp) { Z_Device & device = getShortAddr(shortaddr); if (&device == nullptr) { return; } // don't crash if not found - device.batterypercentx2 = bpx2; + device.batterypercent = bp; } -uint8_t Z_Devices::getBatteryPercentx2(uint16_t shortaddr) const { +uint8_t Z_Devices::getBatteryPercent(uint16_t shortaddr) const { int32_t found = findShortAddr(shortaddr); if (found >= 0) { const Z_Device & device = devicesAt(found); - return device.batterypercentx2; + return device.batterypercent; } return 0xFF; } diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 9488918b3..4456c177f 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -1187,7 +1187,7 @@ int32_t Z_ModelKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObjec } // Record BatteryPercentage int32_t Z_BatteryPercentageKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - zigbee_devices.setBatteryPercentx2(shortaddr, value.as()); + zigbee_devices.setBatteryPercent(shortaddr, json[new_name]); return 1; } @@ -1343,7 +1343,7 @@ int32_t Z_AqaraSensorFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObj json[F("BatteryVoltage")] = batteryvoltage; uint8_t batterypercentage = toPercentageCR2032(val); json[F("BatteryPercentage")] = batterypercentage; - zigbee_devices.setBatteryPercentx2(shortaddr, batterypercentage * 2); + zigbee_devices.setBatteryPercent(shortaddr, batterypercentage); // deprecated json[F(D_JSON_VOLTAGE)] = batteryvoltage; json[F("Battery")] = toPercentageCR2032(val); diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 489aece50..315ad7d74 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1094,6 +1094,11 @@ void ZigbeeShow(bool json) if (0xFF != lqi) { snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lqi); } + // uint8_t bp = zigbee_devices.getBatteryPercentx2(shortaddr); + // Be aware that bp + // if (0xFF != bp) { + // snprintf_P(spart2, sizeof(spart2), PSTR("%d"), bp); + // } WSContentSend_PD(PSTR("{s}%s{m}LQI %s{e}"), name, spart2); } From 908fca70ab5718e19c229dd8b812a1ae5b76b466 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 28 Jun 2020 18:06:25 +0200 Subject: [PATCH 363/581] Relax detection of Aqara Cuve --- tasmota/xdrv_23_zigbee_5_converters.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 4456c177f..497f867e8 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -1210,7 +1210,7 @@ int32_t Z_AqaraCubeFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObjec const char * modelId_c = zigbee_devices.getModelId(shortaddr); // null if unknown String modelId((char*) modelId_c); - if (modelId.startsWith(F("lumi.sensor_cube."))) { // only for Aqara cube + if (modelId.startsWith(F("lumi.sensor_cube"))) { // only for Aqara cube int32_t val = value; const __FlashStringHelper *aqara_cube = F("AqaraCube"); const __FlashStringHelper *aqara_cube_side = F("AqaraCubeSide"); From c9f3a2d563c4e443669d06765e683fdc8db78c8a Mon Sep 17 00:00:00 2001 From: Mark Hansen Date: Mon, 29 Jun 2020 10:35:27 +1000 Subject: [PATCH 364/581] Add tasmota_flash_writes_total to Prometheus Follows prometheus naming best practices for unitless accumulating counts: https://prometheus.io/docs/practices/naming/#metric-names (cf http_requests_total). --- tasmota/xsns_75_prometheus.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/xsns_75_prometheus.ino b/tasmota/xsns_75_prometheus.ino index fd4396a75..934c01dd8 100644 --- a/tasmota/xsns_75_prometheus.ino +++ b/tasmota/xsns_75_prometheus.ino @@ -40,6 +40,7 @@ void HandleMetrics(void) my_version, my_image, GetBuildDateAndTime().c_str()); WSContentSend_P(PSTR("# TYPE tasmota_uptime_seconds gauge\ntasmota_uptime_seconds %d\n"), uptime); WSContentSend_P(PSTR("# TYPE tasmota_boot_count counter\ntasmota_boot_count %d\n"), Settings.bootcount); + WSContentSend_P(PSTR("# TYPE tasmota_flash_writes_total counter\ntasmota_flash_writes_total %d\n"), Settings.save_flag); // Pseudo-metric providing metadata about the WiFi station. From df125f2c07042b9699eb104bf3c790edf0bb1159 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 29 Jun 2020 07:06:08 +0200 Subject: [PATCH 365/581] scripter support for string array --- tasmota/xdrv_10_scripter.ino | 96 +++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 12 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index cbd1c9d46..fec64caa7 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -363,6 +363,10 @@ struct SCRIPT_MEM { uint8_t max_ssize; uint8_t script_loglevel; uint8_t flags; + uint8_t si_num; + uint8_t siro_num; + char *last_index_string; + #ifdef USE_SCRIPT_FATFS File files[SFS_MAX]; FILE_FLAGS file_flags[SFS_MAX]; @@ -374,12 +378,15 @@ struct SCRIPT_MEM { #endif } glob_script_mem; + + #ifdef USE_SCRIPT_GLOBVARS IPAddress last_udp_ip; WiFiUDP Script_PortUdp; #endif int16_t last_findex; +int16_t last_sindex; uint8_t tasm_cmd_activ=0; uint8_t fast_script=0; uint8_t glob_script=0; @@ -1312,6 +1319,7 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso strcpy (dvnam,vname); uint8_t olen=len; last_findex=-1; + last_sindex=-1; char *ja=strchr(dvnam,'['); if (ja) { *ja=0; @@ -1981,6 +1989,7 @@ chknext: //#endif #endif break; +#define MAX_SARRAY_NUM 32 case 'i': if (!strncmp(vname,"int(",4)) { lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); @@ -1996,21 +2005,74 @@ chknext: break; } lp++; - char *sstr=lp; + + if (glob_script_mem.si_num>0 && glob_script_mem.last_index_string) { + free(glob_script_mem.last_index_string); + } + char *sstart=lp; + uint8_t slen=0; for (uint32_t cnt=0; cnt<256; cnt++) { - if (lp[cnt]='\n' || lp[cnt]=='"') { - lp+=cnt+1; + if (*lp=='\n' || *lp=='"' || *lp==0) { + lp++; + if (cnt>0 && !slen) { + slen++; + } + glob_script_mem.siro_num=slen; break; } + if (*lp=='|') { + slen++; + } + lp++; } - char str[SCRIPT_MAXSSIZE]; - GetTextIndexed(str, sizeof(str), fvar, sstr); + + glob_script_mem.si_num = fvar; + if (glob_script_mem.si_num>0) { + if (glob_script_mem.si_num>MAX_SARRAY_NUM) { + glob_script_mem.si_num=MAX_SARRAY_NUM; + } + + glob_script_mem.last_index_string=(char*)calloc(glob_script_mem.max_ssize*glob_script_mem.si_num,1); + for (uint32_t cnt=0; cntglob_script_mem.si_num) { + fvar=glob_script_mem.si_num; + } + strlcpy(str,glob_script_mem.last_index_string+(index*glob_script_mem.max_ssize),glob_script_mem.max_ssize); + } + } + lp++; + if (sp) strlcpy(sp,str,glob_script_mem.max_ssize); + len=0; + goto strexit; + } break; case 'l': if (!strncmp(vname,"lip",3)) { @@ -3219,7 +3281,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { uint8_t vtype=0,sindex,xflg,floop=0,globvindex,fromscriptcmd=0; char *lp_next; - int8_t globaindex; + int8_t globaindex,saindex; struct T_INDEX ind; uint8_t operand,lastop,numeric=1,if_state[IF_NEST],if_exe[IF_NEST],if_result[IF_NEST],and_or,ifstck=0; if_state[ifstck]=0; @@ -3778,6 +3840,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { // string result numeric=0; sindex=index; + saindex=last_sindex; // string result char str[SCRIPT_MAXSSIZE]; lp=getop(lp,&lastop); @@ -3799,10 +3862,19 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { script_udp_sendvar(varname,0,str); } #endif - if (lastop==OPER_EQU) { - strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); - } else if (lastop==OPER_PLSEQU) { - strncat(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); + if (saindex>=0) { + if (lastop==OPER_EQU) { + strlcpy(glob_script_mem.last_index_string+(saindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); + } else if (lastop==OPER_PLSEQU) { + strncat(glob_script_mem.last_index_string+(saindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); + } + last_sindex=-1; + } else { + if (lastop==OPER_EQU) { + strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); + } else if (lastop==OPER_PLSEQU) { + strncat(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); + } } } } @@ -5494,7 +5566,6 @@ void ScriptGetSDCard(void) { } HandleNotFound(); } -#endif // USE_SCRIPT_FATFS void SendFile(char *fname) { char buff[512]; @@ -5528,6 +5599,7 @@ char buff[512]; Webserver->client().stop(); } +#endif // USE_SCRIPT_FATFS void ScriptFullWebpage(void) { uint32_t fullpage_refresh=10000; From bc1f91041cda8b2e69122e9e42e5379b3897a3b1 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Mon, 29 Jun 2020 10:48:24 +0200 Subject: [PATCH 366/581] fix scripter USE_SCRIPT_GLOBVARS without USE_DEVICE_GROUPS --- tasmota/xdrv_10_scripter.ino | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index fec64caa7..347428284 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -383,6 +383,14 @@ struct SCRIPT_MEM { #ifdef USE_SCRIPT_GLOBVARS IPAddress last_udp_ip; WiFiUDP Script_PortUdp; + +#ifndef USE_DEVICE_GROUPS +char * IPAddressToString(const IPAddress& ip_address) { + static char buffer[16]; + sprintf_P(buffer, PSTR("%u.%u.%u.%u"), ip_address[0], ip_address[1], ip_address[2], ip_address[3]); + return buffer; +} +#endif #endif int16_t last_findex; From a63604bd10064b7e8e5a23d8dd9d67607508d4ab Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 29 Jun 2020 11:53:31 +0200 Subject: [PATCH 367/581] Add Battery status to Zigbee GUI Add Battery status to Zigbee GUI --- tasmota/language/bg_BG.h | 2 ++ tasmota/language/cs_CZ.h | 2 ++ tasmota/language/de_DE.h | 2 ++ tasmota/language/el_GR.h | 2 ++ tasmota/language/en_GB.h | 2 ++ tasmota/language/es_ES.h | 2 ++ tasmota/language/fr_FR.h | 2 ++ tasmota/language/he_HE.h | 2 ++ tasmota/language/hu_HU.h | 2 ++ tasmota/language/it_IT.h | 2 ++ tasmota/language/ko_KO.h | 2 ++ tasmota/language/nl_NL.h | 2 ++ tasmota/language/pl_PL.h | 2 ++ tasmota/language/pt_BR.h | 2 ++ tasmota/language/pt_PT.h | 2 ++ tasmota/language/ro_RO.h | 2 ++ tasmota/language/ru_RU.h | 2 ++ tasmota/language/sk_SK.h | 2 ++ tasmota/language/sv_SE.h | 2 ++ tasmota/language/tr_TR.h | 2 ++ tasmota/language/uk_UA.h | 2 ++ tasmota/language/zh_CN.h | 2 ++ tasmota/language/zh_TW.h | 2 ++ tasmota/xdrv_23_zigbee_A_impl.ino | 43 +++++++++++++++++++++---------- 24 files changed, 76 insertions(+), 13 deletions(-) diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 165e4f82a..8f2c626c4 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -56,6 +56,7 @@ #define D_AP "Точка за доÑтъп" // Access Point #define D_AS "като" #define D_AUTO "ÐВТОМÐТИЧÐО" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Мигане вкл." #define D_BLINKOFF "Мигане изкл." #define D_BOOT_COUNT "Брой на ÑтартираниÑта" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP адреÑ" #define D_LIGHT "Светлина" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Модул" #define D_MOISTURE "Влага" #define D_MQTT "MQTT" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 7b53e6274..e857b8e69 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "jako" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blikání" #define D_BLINKOFF "BlikáníVyp" #define D_BOOT_COUNT "PoÄítadlo spuÅ¡tÄ›ní" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "Adresa IP" #define D_LIGHT "SvÄ›tlo" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 4804ea7ba..b31e07901 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "als" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blinken" #define D_BLINKOFF "BlinkenAus" #define D_BOOT_COUNT "Anzahl Startvorgänge" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP-Adresse" #define D_LIGHT "Licht" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 3efac89e8..709c8f6c3 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "ως" #define D_AUTO "ΑΥΤΟΜΑΤΟ" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "ΚαταμέτÏηση εκκινήσεων" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "ΔιεÏθυνση IP" #define D_LIGHT "Φως" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Μονάδα" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 1dd0429d8..1586a0f92 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "as" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Boot Count" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP Address" #define D_LIGHT "Light" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Module" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index e0141cf83..b23f71915 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "como" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Conteo Reinicios" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "Dirección IP" #define D_LIGHT "Luz" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Módulo" #define D_MOISTURE "Humedad del Suelo" #define D_MQTT "MQTT" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 28e9e28b9..a1ceba0a2 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "comme" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Nombre de boot" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "Adresse IP" #define D_LIGHT "Lumière" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Module" #define D_MOISTURE "Humidité" #define D_MQTT "MQTT" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 7cbc64acf..d9cf1e435 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "-×›" #define D_AUTO "×וטומטי" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "מהבהב" #define D_BLINKOFF "כיבוי היבהוב" #define D_BOOT_COUNT "מונה הפעלה מחדש" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP כתובת" #define D_LIGHT "×ור" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "מודול" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 07dfe6349..1df3e0a4e 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "mint" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Villogás" #define D_BLINKOFF "Villogás ki" #define D_BOOT_COUNT "Újraindulások száma" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP cím" #define D_LIGHT "Fény" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index ebd7addfe..5d5365222 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "come" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Lampeggia" #define D_BLINKOFF "Lampeggia OFF" #define D_BOOT_COUNT "Numero di boot" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "Indirizzo IP" #define D_LIGHT "Luce" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modulo" #define D_MOISTURE "Umidità" #define D_MQTT "MQTT" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 0a4cb7633..a26dba20e 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "as" #define D_AUTO "ìžë™" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "깜박임" #define D_BLINKOFF "깜박임 ë„기" #define D_BOOT_COUNT "부팅 횟수" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP 주소" #define D_LIGHT "ë°ê²Œ" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "모듈" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 819b39045..15d5c715b 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "als" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Knipper" #define D_BLINKOFF "KnipperUit" #define D_BOOT_COUNT "Herstarts" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP Adres" #define D_LIGHT "Licht" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Module" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 2cb92290e..446660469 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "jak" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Miganie" #define D_BLINKOFF "Miganie - WyÅ‚." #define D_BOOT_COUNT "Licznik restartów" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "Adres IP" #define D_LIGHT "ÅšwiatÅ‚o" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "ModuÅ‚" #define D_MOISTURE "Wilgotność" #define D_MQTT "MQTT" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 5e866f809..56c5811e6 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -56,6 +56,7 @@ #define D_AP "Ponto de acesso" // Ponto de Acesso #define D_AS "como" #define D_AUTO "Auto" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Pulsar" #define D_BLINKOFF "Pulsar desligado" #define D_BOOT_COUNT "Contagem de inicialização" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "Endereço IP" #define D_LIGHT "Luz" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Módulo" #define D_MOISTURE "Umidade" #define D_MQTT "MQTT" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index af5e2f7aa..930ac2b1b 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Ponto de Acesso #define D_AS "como" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Piscar" #define D_BLINKOFF "Piscar Desligado" #define D_BOOT_COUNT "Contagem de Inicialização" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "Endereço IP" #define D_LIGHT "Luz" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Módulo" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 3e8418960..6f38bffe7 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "as" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Boot Count" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "Adresă IP" #define D_LIGHT "Lumină" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Umezeală" #define D_MQTT "MQTT" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index af5ef942d..051395ed7 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "как" #define D_AUTO "ÐВТО" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Мигать" #define D_BLINKOFF "Ðе Мигать" #define D_BOOT_COUNT "КоличеÑтво загрузок" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP ÐдреÑ" #define D_LIGHT "Свет" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Модуль" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 06251277c..d0109c930 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "ako" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blikanie" #define D_BLINKOFF "BlikanieVyp" #define D_BOOT_COUNT "PoÄítadlo spustení" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "Adresa IP" #define D_LIGHT "Svetlo" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 74c30ef32..76385a4f6 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "som" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blinka" #define D_BLINKOFF "BlinkaAv" #define D_BOOT_COUNT "Uppstartsräknare" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP-adress" #define D_LIGHT "Ljus" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 97a03b15b..8e7d34d2f 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "as" #define D_AUTO "OTOMATIK" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Yeniden baÅŸlama sayısı" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP Adresi" #define D_LIGHT "Işık" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modül" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 07a60ee5b..d4763bcfa 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -56,6 +56,7 @@ #define D_AP "Точка доÑтупу" // Access Point #define D_AS "Ñк" #define D_AUTO "ÐВТО" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Блимати" #define D_BLINKOFF "Ðе блимати" #define D_BOOT_COUNT "К-Ñть завант." @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP адреÑа" #define D_LIGHT "Світло" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Модуль" #define D_MOISTURE "Волога" #define D_MQTT "MQTT" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 92dc25766..84ce0991f 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "åç§°:" #define D_AUTO "自动" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "é—ªçƒ" #define D_BLINKOFF "é—ªçƒå…³" #define D_BOOT_COUNT "å¯åŠ¨æ¬¡æ•°" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP地å€" #define D_LIGHT "ç¯" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "模å—" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 91339b304..4762b9c16 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "å稱:" #define D_AUTO "自動" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "é–ƒçˆ" #define D_BLINKOFF "é–ƒçˆé—œ" #define D_BOOT_COUNT "啟動次數" @@ -116,6 +117,7 @@ #define D_IP_ADDRESS "IP地å€" #define D_LIGHT "燈" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "模組" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 315ad7d74..e776ab875 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1078,30 +1078,47 @@ void ZigbeeShow(bool json) return; #ifdef USE_WEBSERVER } else { - char spart1[33]; - char spart2[8]; - uint32_t zigbee_num = zigbee_devices.devicesSize(); + if (!zigbee_num) { return; } + + // Calculate fixed column width for best visual result (Theos opinion) + uint8_t px_batt = (strlen(D_BATT) + 5 + 1) * 10; // Batt 100% = 100px + uint8_t px_lqi = (strlen(D_LQI) + 4) * 10; // LQI 254 = 70px + + WSContentSend_P(PSTR("{t}")); // Terminate current two column table and open new table +// WSContentSend_PD(PSTR("{s}Device 0x1234" D_BATT " 100%%" D_LQI " 254{e}")); +// WSContentSend_PD(PSTR("{s}Device 0x1234" D_BATT " 100%%" D_LQI " 254{e}")); +// WSContentSend_PD(PSTR("{s}Device 0x1234" D_BATT " 100%%" D_LQI " 254{e}"), px_batt, px_lqi); + + char sdevice[33]; + char sbatt[20]; + char slqi[20]; + for (uint32_t i = 0; i < zigbee_num; i++) { uint16_t shortaddr = zigbee_devices.devicesAt(i).shortaddr; char *name = (char*)zigbee_devices.getFriendlyName(shortaddr); if (nullptr == name) { - snprintf_P(spart1, sizeof(spart1), PSTR(D_DEVICE " 0x%04X"), shortaddr); - name = spart1; + snprintf_P(sdevice, sizeof(sdevice), PSTR(D_DEVICE " 0x%04X"), shortaddr); + name = sdevice; } - snprintf_P(spart2, sizeof(spart2), PSTR("-")); + + snprintf_P(slqi, sizeof(slqi), PSTR("-")); uint8_t lqi = zigbee_devices.getLQI(shortaddr); if (0xFF != lqi) { - snprintf_P(spart2, sizeof(spart2), PSTR("%d"), lqi); + snprintf_P(slqi, sizeof(slqi), PSTR("%d"), lqi); } - // uint8_t bp = zigbee_devices.getBatteryPercentx2(shortaddr); - // Be aware that bp - // if (0xFF != bp) { - // snprintf_P(spart2, sizeof(spart2), PSTR("%d"), bp); - // } - WSContentSend_PD(PSTR("{s}%s{m}LQI %s{e}"), name, spart2); + snprintf_P(sbatt, sizeof(sbatt), PSTR(" ")); + uint8_t bp = zigbee_devices.getBatteryPercent(shortaddr); + if (0xFF != bp) { + snprintf_P(sbatt, sizeof(sbatt), PSTR(D_BATT " %d%%"), bp); + } + + WSContentSend_PD(PSTR("{s}%s%s" D_LQI " %s{e}"), + name, px_batt, sbatt, px_lqi, slqi); } + + WSContentSend_P(PSTR("{t}")); // Terminate current multi column table and open new table #endif } } From 2a587302199f128b48a6232497960e2eda472a6d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 29 Jun 2020 13:52:24 +0200 Subject: [PATCH 368/581] Shrink ajax package --- tasmota/xdrv_23_zigbee_A_impl.ino | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index e776ab875..11ac8e5ad 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1114,8 +1114,12 @@ void ZigbeeShow(bool json) snprintf_P(sbatt, sizeof(sbatt), PSTR(D_BATT " %d%%"), bp); } - WSContentSend_PD(PSTR("{s}%s%s" D_LQI " %s{e}"), - name, px_batt, sbatt, px_lqi, slqi); + if (!i) { + WSContentSend_PD(PSTR("{s}%s%s" D_LQI " %s{e}"), + name, px_batt, sbatt, px_lqi, slqi); + } else { + WSContentSend_PD(PSTR("{s}%s{m}%s" D_LQI " %s{e}"), name, sbatt, slqi); + } } WSContentSend_P(PSTR("{t}")); // Terminate current multi column table and open new table From 8afba311071ff6e43b64711058bcf4f79fde14df Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 29 Jun 2020 14:43:43 +0200 Subject: [PATCH 369/581] Add some comments --- tasmota/xdrv_23_zigbee_A_impl.ino | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 11ac8e5ad..c59daf114 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1082,10 +1082,12 @@ void ZigbeeShow(bool json) if (!zigbee_num) { return; } // Calculate fixed column width for best visual result (Theos opinion) - uint8_t px_batt = (strlen(D_BATT) + 5 + 1) * 10; // Batt 100% = 100px - uint8_t px_lqi = (strlen(D_LQI) + 4) * 10; // LQI 254 = 70px + const uint8_t px_batt = (strlen(D_BATT) + 5 + 1) * 10; // Batt 100% = 90px + 10px column separator + const uint8_t px_lqi = (strlen(D_LQI) + 4) * 10; // LQI 254 = 70px WSContentSend_P(PSTR("{t}")); // Terminate current two column table and open new table +// WSContentSend_P(PSTR("{t}")); // Insert multi column table + // WSContentSend_PD(PSTR("{s}Device 0x1234" D_BATT " 100%%" D_LQI " 254{e}")); // WSContentSend_PD(PSTR("{s}Device 0x1234" D_BATT " 100%%" D_LQI " 254{e}")); // WSContentSend_PD(PSTR("{s}Device 0x1234" D_BATT " 100%%" D_LQI " 254{e}"), px_batt, px_lqi); @@ -1114,15 +1116,16 @@ void ZigbeeShow(bool json) snprintf_P(sbatt, sizeof(sbatt), PSTR(D_BATT " %d%%"), bp); } - if (!i) { + if (!i) { // First row needs style info WSContentSend_PD(PSTR("{s}%s%s" D_LQI " %s{e}"), name, px_batt, sbatt, px_lqi, slqi); - } else { + } else { // Following rows don't need style info so reducing ajax package WSContentSend_PD(PSTR("{s}%s{m}%s" D_LQI " %s{e}"), name, sbatt, slqi); } } WSContentSend_P(PSTR("{t}")); // Terminate current multi column table and open new table +// WSContentSend_P(PSTR("{e}")); // Terminate multi column table #endif } } From 03db100197e2865e4f3c498b23c95106e0f1dc1e Mon Sep 17 00:00:00 2001 From: Federico Leoni Date: Mon, 29 Jun 2020 11:01:55 -0300 Subject: [PATCH 370/581] TuyaMCU baud rate --- tasmota/settings.h | 2 +- tasmota/support_command.ino | 1 + tasmota/xdrv_16_tuyamcu.ino | 7 +++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 0704f426f..68e4a9db3 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -116,7 +116,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t max6675 : 1; // bit 12 (v8.3.1.2) - SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855 uint32_t network_wifi : 1; // bit 13 (v8.3.1.3) - CMND_WIFI uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) = CMND_ETHERNET - uint32_t spare15 : 1; + uint32_t tuyamcu_baudrate : 1; // bit 15 (v8.3.1.6) - SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) uint32_t spare16 : 1; uint32_t spare17 : 1; uint32_t spare18 : 1; diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 2df30eb25..44844ff1f 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -899,6 +899,7 @@ void CmndSetoption(void) switch (pindex) { case 3: // SetOption85 - Enable Device Groups case 6: // SetOption88 - PWM Dimmer Buttons control remote devices + case 15: // SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) restart_flag = 2; break; } diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 8b19e1259..fcc6848db 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -641,13 +641,16 @@ bool TuyaModuleSelected(void) void TuyaInit(void) { + int baudrate = 9600; + if (Settings.flag4.tuyamcu_baudrate) { baudrate = 115200; } // SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) + Tuya.buffer = (char*)(malloc(TUYA_BUFFER_SIZE)); if (Tuya.buffer != nullptr) { TuyaSerial = new TasmotaSerial(Pin(GPIO_TUYA_RX), Pin(GPIO_TUYA_TX), 2); - if (TuyaSerial->begin(9600)) { + if (TuyaSerial->begin(baudrate)) { if (TuyaSerial->hardwareSerial()) { ClaimSerial(); } // Get MCU Configuration - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Request MCU configuration")); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Request MCU configuration at %d baud rate")); TuyaSendCmd(TUYA_CMD_QUERY_PRODUCT); } From acc05624220cdb98fdd1396f6a10a379270c2a2a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 29 Jun 2020 16:34:35 +0200 Subject: [PATCH 371/581] Try to fix Mi Desk Lamp Try to fix Mi Desk Lamp (#8748) --- tasmota/support_rotary.ino | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index f7543be0b..ad13bf1f1 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -127,9 +127,7 @@ void RotaryHandler(void) DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), Rotary.position - Rotary.last_position); LightSetColorTemp((uint16_t)t); } else { -// int8_t d = Settings.light_dimmer; - int8_t d = LightGetDimmer(0); - + int8_t d = Settings.light_dimmer; d = d + (Rotary.position - Rotary.last_position); if (d < 1) { d = 1; @@ -138,10 +136,11 @@ void RotaryHandler(void) d = 100; } // DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), Rotary.position - Rotary.last_position); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), d); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), d); - LightSetDimmer((uint8_t)d); -// Settings.light_dimmer = d; + char scmnd[20]; + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER "0 %d"), d); + ExecuteCommand(scmnd, SRC_SWITCH); } } Rotary.last_position = 128; From 074bef9f7094cd1ce6b432ccf41c783c220e84c1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 29 Jun 2020 17:35:02 +0200 Subject: [PATCH 372/581] Try to fix Mi Desk Lamp Try to fix Mi Desk Lamp (#8748) --- tasmota/support_rotary.ino | 42 +++++++++++++++----------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index ad13bf1f1..713ab4871 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -30,8 +30,8 @@ struct ROTARY { uint8_t state = 0; uint8_t position = 128; uint8_t last_position = 128; - uint8_t interrupts_in_use_count = 0; uint8_t changed = 0; + bool busy = false; } Rotary; /********************************************************************************************/ @@ -43,7 +43,7 @@ void update_rotary(void) ICACHE_RAM_ATTR; void update_rotary(void) { if (MI_DESK_LAMP == my_module_type) { - if (LightPowerIRAM()) { + if (LightPowerIRAM() && !Rotary.busy) { /* * https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h */ @@ -83,19 +83,9 @@ void RotaryInit(void) if (PinUsed(GPIO_ROT1A) && PinUsed(GPIO_ROT1B)) { Rotary.present++; pinMode(Pin(GPIO_ROT1A), INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(Pin(GPIO_ROT1A)), update_rotary, CHANGE); pinMode(Pin(GPIO_ROT1B), INPUT_PULLUP); - - // GPIO6-GPIO11 are typically used to interface with the flash memory IC on - // most esp8266 modules, so we should avoid adding interrupts to these pins. - - if ((Pin(GPIO_ROT1A) < 6) || (Pin(GPIO_ROT1A) > 11)) { - attachInterrupt(digitalPinToInterrupt(Pin(GPIO_ROT1A)), update_rotary, CHANGE); - Rotary.interrupts_in_use_count++; - } - if ((Pin(GPIO_ROT1B) < 6) || (Pin(GPIO_ROT1B) > 11)) { - attachInterrupt(digitalPinToInterrupt(Pin(GPIO_ROT1B)), update_rotary, CHANGE); - Rotary.interrupts_in_use_count++; - } + attachInterrupt(digitalPinToInterrupt(Pin(GPIO_ROT1B)), update_rotary, CHANGE); } } @@ -105,38 +95,38 @@ void RotaryInit(void) void RotaryHandler(void) { - if (Rotary.interrupts_in_use_count < 2) { - noInterrupts(); - update_rotary(); - } else { - noInterrupts(); - } if (Rotary.last_position != Rotary.position) { + Rotary.busy = true; + int rotary_position = Rotary.position - Rotary.last_position; + if (MI_DESK_LAMP == my_module_type) { // Mi Desk lamp if (Button.hold_timer[0]) { Rotary.changed = 1; // button1 is pressed: set color temperature int16_t t = LightGetColorTemp(); - t = t + ((Rotary.position - Rotary.last_position) * 4); + t = t + ((rotary_position) * 4); if (t < 153) { t = 153; } if (t > 500) { t = 500; } - DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), Rotary.position - Rotary.last_position); + DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), rotary_position); LightSetColorTemp((uint16_t)t); + +// char scmnd[20]; +// snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLORTEMPERATURE " %d"), t); +// ExecuteCommand(scmnd, SRC_SWITCH); } else { int8_t d = Settings.light_dimmer; - d = d + (Rotary.position - Rotary.last_position); + d = d + rotary_position; if (d < 1) { d = 1; } if (d > 100) { d = 100; } -// DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), Rotary.position - Rotary.last_position); -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), d); + DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position); char scmnd[20]; snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER "0 %d"), d); @@ -145,8 +135,8 @@ void RotaryHandler(void) } Rotary.last_position = 128; Rotary.position = 128; + Rotary.busy = false; } - interrupts(); } void RotaryLoop(void) From fc40a0945d065a764190773165867ff0b4d3c0c6 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 29 Jun 2020 22:21:32 +0200 Subject: [PATCH 373/581] Zigbee EZSP milestone 3 --- tasmota/xdrv_23_zigbee_0_constants.ino | 201 ++++++++++- tasmota/xdrv_23_zigbee_2_devices.ino | 1 + tasmota/xdrv_23_zigbee_5_converters.ino | 33 +- tasmota/xdrv_23_zigbee_6_commands.ino | 13 +- tasmota/xdrv_23_zigbee_7_statemachine.ino | 152 ++++++-- tasmota/xdrv_23_zigbee_8_parsers.ino | 412 ++++++++++++++++------ tasmota/xdrv_23_zigbee_9_serial.ino | 2 +- tasmota/xdrv_23_zigbee_A_impl.ino | 14 +- 8 files changed, 655 insertions(+), 173 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index 467f70e35..92af3a046 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -57,7 +57,53 @@ enum ZnpSubsystem { #ifdef USE_ZIGBEE_EZSP -enum EZSPCondigId { +enum EZSPNodeType { + EMBER_UNKNOWN_DEVICE = 0x00, + EMBER_COORDINATOR = 0x01, + EMBER_ROUTER = 0x02, + EMBER_END_DEVICE = 0x03, + EMBER_SLEEPY_END_DEVICE = 0x04 +}; + +enum EZSPDeviceUpdate { + EMBER_STANDARD_SECURITY_SECURED_REJOIN = 0x00, + EMBER_STANDARD_SECURITY_UNSECURED_JOIN = 0x01, + EMBER_DEVICE_LEFT = 0x02, + EMBER_STANDARD_SECURITY_UNSECURED_REJOIN = 0x03, +}; + +enum EZSPJoinDecision { + EMBER_USE_PRECONFIGURED_KEY = 0x00, + EMBER_SEND_KEY_IN_THE_CLEAR = 0x01, + EMBER_DENY_JOIN = 0x02, + EMBER_NO_ACTION = 0x03 +}; + +enum EZSPCurrentSecurytBitMask { + EMBER_STANDARD_SECURITY_MODE = 0x0000, + EMBER_DISTRIBUTED_TRUST_CENTER_MODE = 0x0002, + EMBER_GLOBAL_LINK_KEY = 0x0004, + EMBER_TRUST_CENTER_GLOBAL_LINK_KEY = 0x0004, + EMBER_PRECONFIGURED_NETWORK_KEY_MODE = 0x0008, + EMBER_HAVE_TRUST_CENTER_LINK_KEY = 0x0010, + EMBER_TRUST_CENTER_USES_HASHED_LINK_KEY = 0x0084, + EMBER_HAVE_PRECONFIGURED_KEY = 0x0100, + EMBER_HAVE_NETWORK_KEY = 0x0200, + EMBER_GET_LINK_KEY_WHEN_JOINING = 0x0400, + EMBER_REQUIRE_ENCRYPTED_KEY = 0x0800, + EMBER_NO_FRAME_COUNTER_RESET = 0x1000, + EMBER_GET_PRECONFIGURED_KEY_FROM_INSTALL_CODE = 0x2000, + EMBER_HAVE_TRUST_CENTER_EUI64 = 0x0040 +}; + +enum EZSPJoinMethod { + EMBER_USE_MAC_ASSOCIATION = 0x0, + EMBER_USE_NWK_REJOIN = 0x1, + EMBER_USE_NWK_REJOIN_HAVE_NWK_KEY = 0x2, + EMBER_USE_CONFIGURED_NWK_STATE = 0x3 +}; + +enum EZSPConfigId { EZSP_CONFIG_PACKET_BUFFER_COUNT = 0x01, EZSP_CONFIG_NEIGHBOR_TABLE_SIZE = 0x02, EZSP_CONFIG_APS_UNICAST_MESSAGE_COUNT = 0x03, @@ -301,6 +347,159 @@ enum EZSPStatusId { EZSP_NO_ERROR = 0xFF }; +enum EZSPPolicyId { + EZSP_TRUST_CENTER_POLICY = 0x00, + EZSP_BINDING_MODIFICATION_POLICY = 0x01, + EZSP_UNICAST_REPLIES_POLICY = 0x02, + EZSP_POLL_HANDLER_POLICY = 0x03, + EZSP_MESSAGE_CONTENTS_IN_CALLBACK_POLICY = 0x04, + EZSP_TC_KEY_REQUEST_POLICY = 0x05, + EZSP_APP_KEY_REQUEST_POLICY = 0x06, + EZSP_PACKET_VALIDATE_LIBRARY_POLICY = 0x07, + EZSP_ZLL_POLICY = 0x08, + EZSP_TC_REJOINS_USING_WELL_KNOWN_KEY_POLICY = 0x09 +}; + +enum EZSPDecisionBitmask { + EZSP_DECISION_BITMASK_DEFAULT_CONFIGURATION = 0x0000, + EZSP_DECISION_ALLOW_JOINS = 0x0001, + EZSP_DECISION_ALLOW_UNSECURED_REJOINS = 0x0002, + EZSP_DECISION_SEND_KEY_IN_CLEAR = 0x0004, + EZSP_DECISION_IGNORE_UNSECURED_REJOINS = 0x0008, + EZSP_DECISION_JOINS_USE_INSTALL_CODE_KEY = 0x0010, + EZSP_DECISION_DEFER_JOINS = 0x0020 +}; + +enum EZSPDecisionId { + EZSP_DEFER_JOINS_REJOINS_HAVE_LINK_KEY = 0x07, + EZSP_DISALLOW_BINDING_MODIFICATION = 0x10, + EZSP_ALLOW_BINDING_MODIFICATION = 0x11, + EZSP_CHECK_BINDING_MODIFICATIONS_ARE_VALID_ENDPOINT_CLUSTERS = 0x12, + EZSP_HOST_WILL_NOT_SUPPLY_REPLY = 0x20, + EZSP_HOST_WILL_SUPPLY_REPLY = 0x21, + EZSP_POLL_HANDLER_IGNORE = 0x30, + EZSP_POLL_HANDLER_CALLBACK = 0x31, + EZSP_MESSAGE_TAG_ONLY_IN_CALLBACK = 0x40, + EZSP_MESSAGE_TAG_AND_CONTENTS_IN_CALLBACK = 0x41, + EZSP_DENY_TC_KEY_REQUESTS = 0x50, + EZSP_ALLOW_TC_KEY_REQUESTS_AND_SEND_CURRENT_KEY = 0x51, + EZSP_ALLOW_TC_KEY_REQUEST_AND_GENERATE_NEW_KEY = 0x52, + EZSP_DENY_APP_KEY_REQUESTS = 0x60, + EZSP_ALLOW_APP_KEY_REQUESTS = 0x61, + EZSP_PACKET_VALIDATE_LIBRARY_CHECKS_ENABLED = 0x62, + EZSP_PACKET_VALIDATE_LIBRARY_CHECKS_DISABLED = 0x63 +}; + +enum EZSP_ZdoConfigurationFlags { + EMBER_APP_RECEIVES_SUPPORTED_ZDO_REQUESTS = 0x01, + EMBER_APP_HANDLES_UNSUPPORTED_ZDO_REQUESTS = 0x02, + EMBER_APP_HANDLES_ZDO_ENDPOINT_REQUESTS = 0x04, + EMBER_APP_HANDLES_ZDO_BINDING_REQUESTS = 0x08 +}; + +enum EZSP_EmberIncomingMessageType { + EMBER_INCOMING_UNICAST = 0x00, + EMBER_INCOMING_UNICAST_REPLY = 0x01, + EMBER_INCOMING_MULTICAST = 0x02, + EMBER_INCOMING_MULTICAST_LOOPBACK = 0x03, + EMBER_INCOMING_BROADCAST = 0x04, + EMBER_INCOMING_BROADCAST_LOOPBACK = 0x05, + EMBER_INCOMING_MANY_TO_ONE_ROUTE_REQUEST = 0x06 +}; + +enum EZSP_EmberApsOption { + EMBER_APS_OPTION_NONE = 0x0000, + EMBER_APS_OPTION_ENCRYPTION = 0x0020, + EMBER_APS_OPTION_RETRY = 0x0040, + EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY = 0x0100, + EMBER_APS_OPTION_FORCE_ROUTE_DISCOVERY = 0x0200, + EMBER_APS_OPTION_SOURCE_EUI64 = 0x0400, + EMBER_APS_OPTION_DESTINATION_EUI64 = 0x0800, + EMBER_APS_OPTION_ENABLE_ADDRESS_DISCOVERY = 0x1000, + EMBER_APS_OPTION_POLL_RESPONSE = 0x2000, + EMBER_APS_OPTION_ZDO_RESPONSE_REQUIRED = 0x4000, + EMBER_APS_OPTION_FRAGMENT = 0x8000 +}; + +enum EZSP_EmberOutgoingMessageType { + EMBER_OUTGOING_DIRECT = 0x00, + EMBER_OUTGOING_VIA_ADDRESS_TABLE = 0x01, + EMBER_OUTGOING_VIA_BINDING = 0x02, + EMBER_OUTGOING_MULTICAST = 0x03, + EMBER_OUTGOING_BROADCAST = 0x04 +}; + +// inspired from https://github.com/zigpy/zigpy/blob/dev/zigpy/zdo/types.py +enum EZSP_ZDO { + ZDO_NWK_addr_req = 0x0000, + ZDO_IEEE_addr_req = 0x0001, + ZDO_Node_Desc_req = 0x0002, + ZDO_Power_Desc_req = 0x0003, + ZDO_Simple_Desc_req = 0x0004, + ZDO_Active_EP_req = 0x0005, + ZDO_Match_Desc_req = 0x0006, + ZDO_Complex_Desc_req = 0x0010, + ZDO_User_Desc_req = 0x0011, + ZDO_Discovery_Cache_req = 0x0012, + ZDO_Device_annce = 0x0013, + ZDO_User_Desc_set = 0x0014, + ZDO_System_Server_Discovery_req = 0x0015, + ZDO_Discovery_store_req = 0x0016, + ZDO_Node_Desc_store_req = 0x0017, + ZDO_Active_EP_store_req = 0x0019, + ZDO_Simple_Desc_store_req = 0x001A, + ZDO_Remove_node_cache_req = 0x001B, + ZDO_Find_node_cache_req = 0x001C, + ZDO_Extended_Simple_Desc_req = 0x001D, + ZDO_Extended_Active_EP_req = 0x001E, + ZDO_Parent_annce = 0x001F, + // Bind Management Server Services Responses + ZDO_End_Device_Bind_req = 0x0020, + ZDO_Bind_req = 0x0021, + ZDO_Unbind_req = 0x0022, + // Network Management Server Services Requests + ZDO_Mgmt_Lqi_req = 0x0031, + ZDO_Mgmt_Rtg_req = 0x0032, + ZDO_Mgmt_Leave_req = 0x0034, + ZDO_Mgmt_Permit_Joining_req = 0x0036, + ZDO_Mgmt_NWK_Update_req = 0x0038, + + // Responses + // Device and Service Discovery Server Responses + ZDO_NWK_addr_rsp = 0x8000, + ZDO_IEEE_addr_rsp = 0x8001, + ZDO_Node_Desc_rsp = 0x8002, + ZDO_Power_Desc_rsp = 0x8003, + ZDO_Simple_Desc_rsp = 0x8004, + ZDO_Active_EP_rsp = 0x8005, + ZDO_Match_Desc_rsp = 0x8006, + ZDO_Complex_Desc_rsp = 0x8010, + ZDO_User_Desc_rsp = 0x8011, + ZDO_Discovery_Cache_rsp = 0x8012, + ZDO_User_Desc_conf = 0x8014, + ZDO_System_Server_Discovery_rsp = 0x8015, + ZDO_Discovery_Store_rsp = 0x8016, + ZDO_Node_Desc_store_rsp = 0x8017, + ZDO_Power_Desc_store_rsp = 0x8018, + ZDO_Active_EP_store_rsp = 0x8019, + ZDO_Simple_Desc_store_rsp = 0x801A, + ZDO_Remove_node_cache_rsp = 0x801B, + ZDO_Find_node_cache_rsp = 0x801C, + ZDO_Extended_Simple_Desc_rsp = 0x801D, + ZDO_Extended_Active_EP_rsp = 0x801E, + ZDO_Parent_annce_rsp = 0x801F, + // Bind Management Server Services Responses + ZDO_End_Device_Bind_rsp = 0x8020, + ZDO_Bind_rsp = 0x8021, + ZDO_Unbind_rsp = 0x8022, + // Network Management Server Services Responses + ZDO_Mgmt_Lqi_rsp = 0x8031, + ZDO_Mgmt_Rtg_rsp = 0x8032, + ZDO_Mgmt_Leave_rsp = 0x8034, + ZDO_Mgmt_Permit_Joining_rsp = 0x8036, + ZDO_Mgmt_NWK_Update_rsp = 0x8038, +}; + enum EZSP_Commands { EZSP_version = 0x0000, EZSP_getLibraryStatus = 0x0001, diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 9a71075c0..d570c4560 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -244,6 +244,7 @@ Z_Devices zigbee_devices = Z_Devices(); // Local coordinator information uint64_t localIEEEAddr = 0; +uint16_t localShortAddr = 0; /*********************************************************************************************\ * Implementation diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 497f867e8..4cba00500 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -595,14 +595,12 @@ public: ZCLFrame(uint8_t frame_control, uint16_t manuf_code, uint8_t transact_seq, uint8_t cmd_id, const char *buf, size_t buf_len, uint16_t clusterid, uint16_t groupaddr, uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, - uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber, - uint32_t timestamp): + uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber): _manuf_code(manuf_code), _transact_seq(transact_seq), _cmd_id(cmd_id), _payload(buf_len ? buf_len : 250), // allocate the data frame from source or preallocate big enough _cluster_id(clusterid), _groupaddr(groupaddr), _srcaddr(srcaddr), _srcendpoint(srcendpoint), _dstendpoint(dstendpoint), _wasbroadcast(wasbroadcast), - _linkquality(linkquality), _securityuse(securityuse), _seqnumber(seqnumber), - _timestamp(timestamp) + _linkquality(linkquality), _securityuse(securityuse), _seqnumber(seqnumber) { _frame_control.d8 = frame_control; _payload.addBuffer(buf, buf_len); @@ -616,13 +614,11 @@ public: "\"groupid\":%d," "\"clusterid\":%d," "\"srcaddr\":\"0x%04X\"," "\"srcendpoint\":%d," "\"dstendpoint\":%d," "\"wasbroadcast\":%d," "\"" D_CMND_ZIGBEE_LINKQUALITY "\":%d," "\"securityuse\":%d," "\"seqnumber\":%d," - "\"timestamp\":%d," "\"fc\":\"0x%02X\",\"manuf\":\"0x%04X\",\"transact\":%d," "\"cmdid\":\"0x%02X\",\"payload\":\"%s\"}}"), _groupaddr, _cluster_id, _srcaddr, _srcendpoint, _dstendpoint, _wasbroadcast, _linkquality, _securityuse, _seqnumber, - _timestamp, _frame_control, _manuf_code, _transact_seq, _cmd_id, hex_char); if (Settings.flag3.tuya_serial_mqtt_publish) { @@ -635,8 +631,7 @@ public: static ZCLFrame parseRawFrame(const SBuffer &buf, uint8_t offset, uint8_t len, uint16_t clusterid, uint16_t groupid, uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, - uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber, - uint32_t timestamp) { // parse a raw frame and build the ZCL frame object + uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber) { // parse a raw frame and build the ZCL frame object uint32_t i = offset; ZCLHeaderFrameControl_t frame_control; uint16_t manuf_code = 0; @@ -654,8 +649,7 @@ public: (const char *)(buf.buf() + i), len + offset - i, clusterid, groupid, srcaddr, srcendpoint, dstendpoint, wasbroadcast, - linkquality, securityuse, seqnumber, - timestamp); + linkquality, securityuse, seqnumber); return zcl_frame; } @@ -679,17 +673,12 @@ public: _cluster_id = clusterid; } - inline uint8_t getCmdId(void) const { - return _cmd_id; - } - - inline uint16_t getClusterId(void) const { - return _cluster_id; - } - - inline uint16_t getSrcEndpoint(void) const { - return _srcendpoint; - } + inline uint16_t getSrcAddr(void) const { return _srcaddr; } + inline uint16_t getGroupAddr(void) const { return _groupaddr; } + inline uint16_t getClusterId(void) const { return _cluster_id; } + inline uint8_t getLinkQuality(void) const { return _linkquality; } + inline uint8_t getCmdId(void) const { return _cmd_id; } + inline uint16_t getSrcEndpoint(void) const { return _srcendpoint; } const SBuffer &getPayload(void) const { return _payload; @@ -699,6 +688,7 @@ public: return _manuf_code; } + private: ZCLHeaderFrameControl_t _frame_control = { .d8 = 0 }; uint16_t _manuf_code = 0; // optional @@ -715,7 +705,6 @@ private: uint8_t _linkquality; uint8_t _securityuse; uint8_t _seqnumber; - uint32_t _timestamp; }; // Zigbee ZCL converters diff --git a/tasmota/xdrv_23_zigbee_6_commands.ino b/tasmota/xdrv_23_zigbee_6_commands.ino index 949f4acb8..1f6c4e3a1 100644 --- a/tasmota/xdrv_23_zigbee_6_commands.ino +++ b/tasmota/xdrv_23_zigbee_6_commands.ino @@ -50,12 +50,15 @@ ZF(HueSat) ZF(Color) ZF(ShutterOpen) ZF(ShutterClose) ZF(ShutterStop) ZF(ShutterLift) ZF(ShutterTilt) ZF(Shutter) //ZF(Occupancy) ZF(DimmerMove) ZF(DimmerStep) ZF(DimmerStepUp) ZF(DimmerStepDown) -ZF(HueMove) ZF(HueStep) ZF(HueStepUp) ZF(HueStepDown) ZF(SatMove) ZF(SatStep) ZF(ColorMove) ZF(ColorStep) ZF(ColorTempStep) ZF(ColorTempStepUp) ZF(ColorTempStepDown) +ZF(HueMove) ZF(HueStep) ZF(HueStepUp) ZF(HueStepDown) ZF(SatMove) ZF(SatStep) ZF(ColorMove) ZF(ColorStep) +ZF(ColorTempMoveUp) ZF(ColorTempMoveDown) ZF(ColorTempMoveStop) ZF(ColorTempMove) +ZF(ColorTempStep) ZF(ColorTempStepUp) ZF(ColorTempStepDown) ZF(ArrowClick) ZF(ArrowHold) ZF(ArrowRelease) ZF(ZoneStatusChange) ZF(xxxx00) ZF(xxxx) ZF(01xxxx) ZF(03xxxx) ZF(00) ZF(01) ZF() ZF(xxxxyy) ZF(00190200) ZF(01190200) ZF(xxyyyy) ZF(xx) ZF(xx000A00) ZF(xx0A00) ZF(xxyy0A00) ZF(xxxxyyyy0A00) ZF(xxxx0A00) ZF(xx0A) ZF(xx190A00) ZF(xx19) ZF(xx190A) ZF(xxxxyyyy) ZF(xxxxyyzz) ZF(xxyyzzzz) ZF(xxyyyyzz) +ZF(01xxxx000000000000) ZF(03xxxx000000000000) ZF(00xxxx000000000000) ZF(xxyyyy000000000000) ZF(00xx0A00) ZF(01xx0A00) ZF(03xx0A00) ZF(01xxxx0A0000000000) ZF(03xxxx0A0000000000) ZF(xxyyyy0A0000000000) // Cluster specific commands @@ -119,8 +122,12 @@ const Z_CommandConverter Z_Commands[] PROGMEM = { { Z(SatStep), 0x0300, 0x05, 0x01, Z(xx190A) }, { Z(ColorMove), 0x0300, 0x08, 0x01, Z(xxxxyyyy) }, { Z(ColorStep), 0x0300, 0x09, 0x01, Z(xxxxyyyy0A00) }, - { Z(ColorTempStepUp), 0x0300, 0x4C, 0x01, Z(01xxxx0A0000000000) }, //xxxx = step - { Z(ColorTempStepDown),0x0300, 0x4C, 0x01, Z(03xxxx0A0000000000) }, //xxxx = step + { Z(ColorTempMoveUp), 0x0300, 0x4B, 0x01, Z(01xxxx000000000000) }, + { Z(ColorTempMoveDown),0x0300, 0x4B, 0x01, Z(03xxxx000000000000) }, + { Z(ColorTempMoveStop),0x0300, 0x4B, 0x01, Z(00xxxx000000000000) }, + { Z(ColorTempMove), 0x0300, 0x4B, 0x01, Z(xxyyyy000000000000) }, + { Z(ColorTempStepUp), 0x0300, 0x4C, 0x01, Z(01xxxx0A0000000000) }, + { Z(ColorTempStepDown),0x0300, 0x4C, 0x01, Z(03xxxx0A0000000000) }, { Z(ColorTempStep), 0x0300, 0x4C, 0x01, Z(xxyyyy0A0000000000) }, //xx = 0x01 up, 0x03 down, yyyy = step // Tradfri { Z(ArrowClick), 0x0005, 0x07, 0x01, Z(xx) }, // xx == 0x01 = left, 0x00 = right diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index 912a493ca..dd09cd18b 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -36,6 +36,8 @@ const uint8_t ZIGBEE_STATUS_DEVICE_INDICATION = 34; // Device announces its const uint8_t ZIGBEE_STATUS_SCANNING = 40; // State change const uint8_t ZIGBEE_STATUS_CC_VERSION = 50; // Status: CC2530 ZNP Version const uint8_t ZIGBEE_STATUS_CC_INFO = 51; // Status: CC2530 Device Configuration +const uint8_t ZIGBEE_STATUS_EZ_VERSION = 55; // Status: EFR32 EZ Version +const uint8_t ZIGBEE_STATUS_EZ_INFO = 56; // Status: EFR32 EZ Device Configuration const uint8_t ZIGBEE_STATUS_UNSUPPORTED_VERSION = 98; // Unsupported ZNP version const uint8_t ZIGBEE_STATUS_ABORT = 99; // Fatal error, Zigbee not working @@ -170,6 +172,19 @@ SBuffer *zigbee_buffer = nullptr; #define USE_ZIGBEE_CHANNEL_MASK (1 << (USE_ZIGBEE_CHANNEL)) +const char kCheckingDeviceConfiguration[] PROGMEM = D_LOG_ZIGBEE "checking device configuration"; +const char kConfiguredCoord[] PROGMEM = "Configured, starting coordinator"; +const char kConfiguredRouter[] PROGMEM = "Configured, starting router"; +const char kConfiguredDevice[] PROGMEM = "Configured, starting device"; +const char kStarted[] PROGMEM = "Started"; +const char kZigbeeStarted[] PROGMEM = D_LOG_ZIGBEE "Zigbee started"; +const char kResetting[] PROGMEM = "Resetting configuration"; +const char kResettingDevice[] PROGMEM = D_LOG_ZIGBEE "Resetting EZSP device"; +const char kZNP12[] PROGMEM = "Only ZNP 1.2 is currently supported"; +const char kEZ8[] PROGMEM = "Only EZSP protocol v8 is currently supported"; +const char kAbort[] PROGMEM = "Abort"; +const char kZigbeeAbort[] PROGMEM = D_LOG_ZIGBEE "Abort"; + #ifdef USE_ZIGBEE_ZNP // ZBS_* Zigbee Send @@ -402,17 +417,6 @@ void Z_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_pani ) // 2605621001030507090B0D0F00020406080A0C0D } -const char kCheckingDeviceConfiguration[] PROGMEM = D_LOG_ZIGBEE "checking device configuration"; -const char kConfiguredCoord[] PROGMEM = "Configured, starting coordinator"; -const char kConfiguredRouter[] PROGMEM = "Configured, starting router"; -const char kConfiguredDevice[] PROGMEM = "Configured, starting device"; -const char kStarted[] PROGMEM = "Started"; -const char kZigbeeStarted[] PROGMEM = D_LOG_ZIGBEE "Zigbee started"; -const char kResetting[] PROGMEM = "Resetting configuration"; -const char kZNP12[] PROGMEM = "Only ZNP 1.2 is currently supported"; -const char kAbort[] PROGMEM = "Abort"; -const char kZigbeeAbort[] PROGMEM = D_LOG_ZIGBEE "Abort"; - static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_LABEL(0) ZI_NOOP() @@ -543,7 +547,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { // ====================================================================== // Start as Zigbee Router // ====================================================================== - ZI_LABEL(ZIGBEE_LABEL_INIT_ROUTER) // Init as a router + ZI_LABEL(ZIGBEE_LABEL_INIT_ROUTER) // Init as a router // Check the configuration as Router ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_FACT_RESET_ROUTER) ZI_SEND(ZBS_ZNPHC) // check value of ZNP Has Configured @@ -654,8 +658,7 @@ ZBM(ZBS_SET_TC_CACHE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG ZBM(ZBS_SET_ROUTE_TBL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SOURCE_ROUTE_TABLE_SIZE, 0x10, 0x00) // 53001A1000 ZBM(ZBS_SET_KEY_TBL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_KEY_TABLE_SIZE, 0x04, 0x00) // 53001E0400 ZBM(ZBS_SET_PANID_CNFLCT, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_PAN_ID_CONFLICT_REPORT_THRESHOLD, 0x02, 0x00)// 5300220200 -// TODO APP_RECEIVES_SUPPORTED_ZDO_REQUESTS -ZBM(ZBS_SET_ZDO_REQ, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_APPLICATION_ZDO_FLAGS, 0x03, 0x00) // 53002A0300 +ZBM(ZBS_SET_ZDO_REQ, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_APPLICATION_ZDO_FLAGS, EMBER_APP_RECEIVES_SUPPORTED_ZDO_REQUESTS | EMBER_APP_HANDLES_UNSUPPORTED_ZDO_REQUESTS, 0x00) // 53002A0300 ZBM(ZBS_SET_NETWORKS, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SUPPORTED_NETWORKS, 0x01, 0x00) // 53002D0100 ZBM(ZBS_SET_PACKET_BUF, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_PACKET_BUFFER_COUNT, 0xFF, 0x00) // 530001FF00 @@ -667,23 +670,24 @@ ZBM(ZBS_GET_APS_UNI, EZSP_getConfigurationValue, 0x00 /*high*/, EZSP_CONFIG ZBM(ZBR_GET_OK, EZSP_getConfigurationValue, 0x00 /*high*/, 0x00 /*ok*/) // 5200 - followed by the value // Add Endpoints -// ZBM(ZBS_ADD_ENDPOINT1, EZSP_addEndpoint, 0x00 /*high*/, 0x01 /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), -// 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, -// 0x0E /* inputClusterCount */, // actually all clusters will be received -// 0X00 /* outputClusterCount */, -// 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 -// 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 -// 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 -// 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 -// ) ZBM(ZBS_ADD_ENDPOINT1, EZSP_addEndpoint, 0x00 /*high*/, 0x01 /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, - 0x00 /* inputClusterCount */, // actually all clusters will be received - 0X00 /* outputClusterCount */ ) // 02000104010500000000 + 0x0E /* inputClusterCount */, // actually all clusters will be received + 0X00 /* outputClusterCount */, // 02000104010500000000 + 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 + 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 + 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 + 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 + ) ZBM(ZBS_ADD_ENDPOINTB, EZSP_addEndpoint, 0x00 /*high*/, 0x0B /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, - 0x00 /* inputClusterCount */, // actually all clusters will be received - 0X00 /* outputClusterCount */ ) // 02000B04010500000000 + 0x0E /* inputClusterCount */, // actually all clusters will be received + 0X00 /* outputClusterCount */, // 02000B04010500000000 + 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 + 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 + 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 + 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 + ) ZBM(ZBR_ADD_ENDPOINT, EZSP_addEndpoint, 0x00 /*high*/, 0x00 /*ok*/) // 020000 // set concentrator false @@ -691,11 +695,58 @@ ZBM(ZBS_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*false*/, 0 0x58,0x02 /*minTime*/, 0x08,0x07 /*maxTime*/, 0x02 /*errThr*/, 0x05 /*failThr*/, 0x00 /*maxHops*/) // 100000F9FF58020807020500 ZBM(ZBR_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*ok*/) // 100000 -//False, , 600, 1800, 2, 5, 0) +// setInitialSecurityState +#define EZ_SECURITY_MODE EMBER_TRUST_CENTER_GLOBAL_LINK_KEY | EMBER_PRECONFIGURED_NETWORK_KEY_MODE | EMBER_HAVE_NETWORK_KEY | EMBER_HAVE_PRECONFIGURED_KEY +ZBM(ZBS_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, + Z_B0(EZ_SECURITY_MODE), Z_B1(EZ_SECURITY_MODE), + // preConfiguredKey + 0x5A, 0x69, 0x67, 0x42, 0x65, 0x65, 0x41, 0x6C, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x30, 0x39, // well known key "ZigBeeAlliance09" + // networkKey + Z_B0(USE_ZIGBEE_PRECFGKEY_L), Z_B1(USE_ZIGBEE_PRECFGKEY_L), Z_B2(USE_ZIGBEE_PRECFGKEY_L), Z_B3(USE_ZIGBEE_PRECFGKEY_L), + Z_B4(USE_ZIGBEE_PRECFGKEY_L), Z_B5(USE_ZIGBEE_PRECFGKEY_L), Z_B6(USE_ZIGBEE_PRECFGKEY_L), Z_B7(USE_ZIGBEE_PRECFGKEY_L), + Z_B0(USE_ZIGBEE_PRECFGKEY_H), Z_B1(USE_ZIGBEE_PRECFGKEY_H), Z_B2(USE_ZIGBEE_PRECFGKEY_H), Z_B3(USE_ZIGBEE_PRECFGKEY_H), + Z_B4(USE_ZIGBEE_PRECFGKEY_H), Z_B5(USE_ZIGBEE_PRECFGKEY_H), Z_B6(USE_ZIGBEE_PRECFGKEY_H), Z_B7(USE_ZIGBEE_PRECFGKEY_H), + 0x00 /*sequence*/, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*trustcenter*/ + ) +ZBM(ZBR_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, 0x00 /*status*/) + +// setIndividual policies +ZBM(ZBS_SET_POLICY_00, EZSP_setPolicy, 0x00 /*high*/, EZSP_TRUST_CENTER_POLICY, + EZSP_DECISION_ALLOW_JOINS | EZSP_DECISION_ALLOW_UNSECURED_REJOINS) // 55000003 +ZBM(ZBS_SET_POLICY_02, EZSP_setPolicy, 0x00 /*high*/, EZSP_UNICAST_REPLIES_POLICY, + EZSP_HOST_WILL_NOT_SUPPLY_REPLY) // 550002210 +ZBM(ZBS_SET_POLICY_03, EZSP_setPolicy, 0x00 /*high*/, EZSP_POLL_HANDLER_POLICY, + EZSP_POLL_HANDLER_IGNORE) // 55000330 +ZBM(ZBS_SET_POLICY_05, EZSP_setPolicy, 0x00 /*high*/, EZSP_TC_KEY_REQUEST_POLICY, + EZSP_ALLOW_TC_KEY_REQUESTS_AND_SEND_CURRENT_KEY) // 55000551 +ZBM(ZBS_SET_POLICY_06, EZSP_setPolicy, 0x00 /*high*/, EZSP_APP_KEY_REQUEST_POLICY, + EZSP_DENY_APP_KEY_REQUESTS) // 55000660 +ZBM(ZBR_SET_POLICY_XX, EZSP_setPolicy, 0x00 /*high*/, 0x00 /*status*/) + +// formNetwork - i.e. start zigbee network as coordinator +ZBM(ZBS_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, + Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), + Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID), + Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID), + 20 /*radioTxPower*/, + USE_ZIGBEE_CHANNEL /*channel*/, + EMBER_USE_MAC_ASSOCIATION, + 0xFF,0xFF, /*nwkManagerId, unused*/ + 0x00, /*nwkUpdateId, unused*/ + 0x00,0x00,0x00,0x00, /*NWK channel mask, unused*/ + ) // 1E00... +ZBM(ZBR_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, 0x00 /*status*/) // 1E0000 +ZBM(ZBR_NETWORK_UP, EZSP_stackStatusHandler, 0x00 /*high*/, EMBER_NETWORK_UP) // 190090 + +// read configuration details +ZBM(ZBS_GET_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/) // 2800 +ZBM(ZBR_GET_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/, 0x00 /*ok*/) // 2800 +ZBM(ZBS_GET_EUI64, EZSP_getEui64, 0x00 /*high*/) // 2600 +ZBM(ZBR_GET_EUI64, EZSP_getEui64, 0x00 /*high*/) // 2600 +ZBM(ZBS_GET_NODEID, EZSP_getNodeId, 0x00 /*high*/) // 2700 +ZBM(ZBR_GET_NODEID, EZSP_getNodeId, 0x00 /*high*/) // 2700 -const char kResetingDevice[] PROGMEM = D_LOG_ZIGBEE "resetting EZSP device"; -const char kAbort[] PROGMEM = "Abort"; -const char kZigbeeAbort[] PROGMEM = D_LOG_ZIGBEE "Abort"; static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_LABEL(0) @@ -706,7 +757,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize // Hardware reset - ZI_LOG(LOG_LEVEL_INFO, kResetingDevice) // Log Debug: resetting EZSP device + ZI_LOG(LOG_LEVEL_INFO, kResettingDevice) // Log Debug: resetting EZSP device ZI_CALL(&Z_Reset_Device, 0) // LOW = reset ZI_WAIT(100) // wait for .1 second ZI_CALL(&Z_Reset_Device, 1) // HIGH = release reset @@ -715,9 +766,10 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_WAIT_UNTIL(5000, ZBR_RSTACK) // wait for RSTACK message // Init device and probe version - ZI_SEND(ZBS_VERSION) ZI_WAIT_RECV(1000, ZBR_VERSION) // check EXT PAN ID + ZI_SEND(ZBS_VERSION) ZI_WAIT_RECV_FUNC(1000, ZBR_VERSION, &Z_ReceiveCheckVersion) // check EXT PAN ID // configure EFR32 + ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredCoord) ZI_SEND(ZBS_SET_ADDR_TABLE) ZI_WAIT_RECV(500, ZBR_SET_OK) // Address table size ZI_SEND(ZBS_SET_MCAST_TABLE) ZI_WAIT_RECV(500, ZBR_SET_OK) ZI_SEND(ZBS_SET_STK_PROF) ZI_WAIT_RECV(500, ZBR_SET_OK) @@ -733,7 +785,8 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_SEND(ZBS_SET_PACKET_BUF) ZI_WAIT_RECV(500, ZBR_SET_OK2) // read configuration - ZI_SEND(ZBS_GET_APS_UNI) ZI_WAIT_RECV_FUNC(500, ZBR_GET_OK, &Z_ReadAPSUnicastMessage) + // TODO - not sure it's useful + //ZI_SEND(ZBS_GET_APS_UNI) ZI_WAIT_RECV_FUNC(500, ZBR_GET_OK, &Z_ReadAPSUnicastMessage) // add endpoint 0x01 and 0x0B ZI_SEND(ZBS_ADD_ENDPOINT1) ZI_WAIT_RECV(500, ZBR_ADD_ENDPOINT) @@ -742,9 +795,38 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { // set Concentrator ZI_SEND(ZBS_SET_CONCENTRATOR) ZI_WAIT_RECV(500, ZBR_SET_CONCENTRATOR) + // setInitialSecurityState + ZI_SEND(ZBS_SET_SECURITY) ZI_WAIT_RECV(500, ZBR_SET_SECURITY) + ZI_SEND(ZBS_SET_POLICY_00) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + ZI_SEND(ZBS_SET_POLICY_02) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + ZI_SEND(ZBS_SET_POLICY_03) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + ZI_SEND(ZBS_SET_POLICY_05) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + ZI_SEND(ZBS_SET_POLICY_06) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + + // formNetwork + ZI_SEND(ZBS_FORM_NETWORK) ZI_WAIT_RECV(500, ZBR_FORM_NETWORK) + ZI_WAIT_RECV(5000, ZBR_NETWORK_UP) // wait for network to start + + // Query device information + ZI_SEND(ZBS_GET_EUI64) ZI_WAIT_RECV_FUNC(500, ZBR_GET_EUI64, &Z_EZSPGetEUI64) + ZI_SEND(ZBS_GET_NODEID) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NODEID, &Z_EZSPGetNodeId) + ZI_SEND(ZBS_GET_NETW_PARM) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NETW_PARM, &Z_EZSPNetworkParameters) + + ZI_LABEL(ZIGBEE_LABEL_READY) + ZI_MQTT_STATE(ZIGBEE_STATUS_OK, kStarted) + ZI_LOG(LOG_LEVEL_INFO, kZigbeeStarted) + ZI_CALL(&Z_State_Ready, 1) // Now accept incoming messages + ZI_CALL(&Z_Load_Devices, 0) + ZI_CALL(&Z_Query_Bulbs, 0) + ZI_LABEL(ZIGBEE_LABEL_MAIN_LOOP) ZI_WAIT_FOREVER() - ZI_GOTO(ZIGBEE_LABEL_READY) + ZI_GOTO(ZIGBEE_LABEL_MAIN_LOOP) + + // Error: version of Z-Stack is not supported + ZI_LABEL(ZIGBEE_LABEL_UNSUPPORTED_VERSION) + ZI_MQTT_STATE(ZIGBEE_STATUS_UNSUPPORTED_VERSION, kEZ8) + ZI_GOTO(ZIGBEE_LABEL_ABORT) // Abort state machine, general error ZI_LABEL(ZIGBEE_LABEL_ABORT) // Label 99: abort diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 548c09a25..870caaa7d 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -64,26 +64,6 @@ int32_t Z_EZSP_ERROR(uint8_t error_code) { XdrvRulesProcess(); } -/*********************************************************************************************\ - * Default resolver -\*********************************************************************************************/ - -int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { - // Default message handler for new messages - if (zigbee.init_phase) { - // if still during initialization phase, ignore any unexpected message - return -1; // ignore message - } else { - // TODO - // for (uint32_t i = 0; i < sizeof(Z_DispatchTable)/sizeof(Z_Dispatcher); i++) { - // if (Z_ReceiveMatchPrefix(buf, Z_DispatchTable[i].match)) { - // (*Z_DispatchTable[i].func)(res, buf); - // } - // } - return -1; - } -} - int32_t Z_ReadAPSUnicastMessage(int32_t res, class SBuffer &buf) { // Called when receiving a response from getConfigurationValue // Value is in bytes 2+3 @@ -94,6 +74,53 @@ int32_t Z_ReadAPSUnicastMessage(int32_t res, class SBuffer &buf) { #endif // USE_ZIGBEE_EZSP +/*********************************************************************************************\ + * Parsers for incoming EZSP messages +\*********************************************************************************************/ + +// +// Handle a "getEui64" incoming message +// +int32_t Z_EZSPGetEUI64(int32_t res, class SBuffer &buf) { + localIEEEAddr = buf.get64(2); + return res; +} + +// +// Handle a "getEui64" incoming message +// +int32_t Z_EZSPGetNodeId(int32_t res, class SBuffer &buf) { + localShortAddr = buf.get8(2); + return res; +} + +// +// Handle a "getNetworkParameters" incoming message +// +int32_t Z_EZSPNetworkParameters(int32_t res, class SBuffer &buf) { + uint8_t node_type = buf.get8(3); + // ext panid: 4->11 + // panid: 12->13 + // radioTxPower: 14 + // radioChannel: 15 + + // Local short and long addresses are supposed to be already retrieved + // localIEEEAddr = long_adr; + // localShortAddr = short_adr; + + char hex[20]; + Uint64toHex(localIEEEAddr, hex, 64); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"IEEEAddr\":\"0x%s\",\"ShortAddr\":\"0x%04X\"" + ",\"DeviceType\":%d}}"), + ZIGBEE_STATUS_EZ_INFO, hex, localShortAddr, node_type); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); + + return res; +} + /*********************************************************************************************\ * Parsers for incoming ZNP messages \*********************************************************************************************/ @@ -117,6 +144,7 @@ int32_t Z_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { // keep track of the local IEEE address localIEEEAddr = long_adr; + localShortAddr = short_adr; char hex[20]; Uint64toHex(long_adr, hex, 64); @@ -194,6 +222,7 @@ int32_t Z_Reboot(int32_t res, class SBuffer &buf) { } int32_t Z_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP // check that the version is supported // typical version for ZNP 1.2 // 61020200-02.06.03.D9143401.0200000000 @@ -222,6 +251,34 @@ int32_t Z_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { } else { return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort } +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + uint8_t protocol_version = buf.get8(2); + uint8_t stack_type = buf.get8(3); + uint16_t stack_version = buf.get16(4); + + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"Version\":\"%d.%d.%d.%d\",\"Protocol\":%d" + ",\"Stack\":%d}}"), + ZIGBEE_STATUS_EZ_VERSION, + (stack_version & 0xF000) >> 12, + (stack_version & 0x0F00) >> 8, + (stack_version & 0x00F0) >> 4, + stack_version & 0x000F, + protocol_version, + stack_type + ); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); + + if (0x08 == protocol_version) { + return 0; // protocol v8 is ok + } else { + return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort + } +#endif // USE_ZIGBEE_EZSP } // checks the device type (coordinator, router, end-device) @@ -466,10 +523,18 @@ int32_t Z_ReceiveStateChange(int32_t res, const class SBuffer &buf) { // Send back Active Ep Req message // int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) { - Z_ShortAddress srcAddr = buf.get16(2); +#ifdef USE_ZIGBEE_ZNP + // Z_ShortAddress srcAddr = buf.get16(2); Z_ShortAddress nwkAddr = buf.get16(4); Z_IEEEAddress ieeeAddr = buf.get64(6); uint8_t capabilities = buf.get8(14); +#endif +#ifdef USE_ZIGBEE_EZSP + // uint8_t seq = buf.get8(0); + Z_ShortAddress nwkAddr = buf.get16(1); + Z_IEEEAddress ieeeAddr = buf.get64(3); + uint8_t capabilities = buf.get8(11); +#endif zigbee_devices.updateDevice(nwkAddr, ieeeAddr); @@ -627,7 +692,6 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { return -1; } -#ifdef USE_ZIGBEE_ZNP /*********************************************************************************************\ * Send specific ZNP messages \*********************************************************************************************/ @@ -636,24 +700,32 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { // Send ZDO_IEEE_ADDR_REQ request to get IEEE long address // void Z_SendIEEEAddrReq(uint16_t shortaddr) { +#ifdef USE_ZIGBEE_ZNP uint8_t IEEEAddrReq[] = { Z_SREQ | Z_ZDO, ZDO_IEEE_ADDR_REQ, Z_B0(shortaddr), Z_B1(shortaddr), 0x00, 0x00 }; ZigbeeZNPSend(IEEEAddrReq, sizeof(IEEEAddrReq)); +#endif } // // Send ACTIVE_EP_REQ to collect active endpoints for this address // void Z_SendActiveEpReq(uint16_t shortaddr) { +#ifdef USE_ZIGBEE_ZNP uint8_t ActiveEpReq[] = { Z_SREQ | Z_ZDO, ZDO_ACTIVE_EP_REQ, Z_B0(shortaddr), Z_B1(shortaddr), Z_B0(shortaddr), Z_B1(shortaddr) }; - ZigbeeZNPSend(ActiveEpReq, sizeof(ActiveEpReq)); +#endif +#ifdef USE_ZIGBEE_EZSP + uint8_t ActiveEpReq[] = { Z_B0(shortaddr), Z_B1(shortaddr) }; + EZ_SendZDO(shortaddr, ZDO_Active_EP_req, ActiveEpReq, sizeof(ActiveEpReq)); +#endif } // // Send AF Info Request // void Z_SendAFInfoRequest(uint16_t shortaddr) { +#ifdef USE_ZIGBEE_ZNP uint8_t endpoint = zigbee_devices.findFirstEndpoint(shortaddr); if (0x00 == endpoint) { endpoint = 0x01; } // if we don't know the endpoint, try 0x01 uint8_t transacid = zigbee_devices.getNextSeqNumber(shortaddr); @@ -663,106 +735,63 @@ void Z_SendAFInfoRequest(uint16_t shortaddr) { 0x00, transacid, ZCL_READ_ATTRIBUTES, 0x04, 0x00, 0x05, 0x00 }; ZigbeeZNPSend(AFInfoReq, sizeof(AFInfoReq)); +#endif } -#endif // USE_ZIGBEE_ZNP +// +// Handle trustCenterJoinHandler +// 2400 +// #ifdef USE_ZIGBEE_EZSP -/*********************************************************************************************\ - * Send specific EZS¨ messages -\*********************************************************************************************/ +int32_t EZ_ReceiveTCJoinHandler(int32_t res, const class SBuffer &buf) { + uint16_t srcAddr = buf.get16(2); + uint64_t ieeeAddr = buf.get64(4); + uint8_t status = buf.get8(12); + uint8_t decision = buf.get8(13); + uint16_t parentNw = buf.get16(14); -// -// Callback for loading Zigbee configuration from Flash, called by the state machine -// -int32_t Z_Reset_Device(uint8_t value) { - // TODO - GPIO is hardwired to GPIO4 - digitalWrite(4, value ? HIGH : LOW); - return 0; // continue + if (EMBER_DEVICE_LEFT != status) { // ignore message if the device is leaving + zigbee_devices.updateDevice(srcAddr, ieeeAddr); + + char hex[20]; + Uint64toHex(ieeeAddr, hex, 64); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"IEEEAddr\":\"0x%s\",\"ShortAddr\":\"0x%04X\"" + ",\"ParentNetwork\":\"0x%04X\"" + ",\"Status\":%d,\"Decision\":%d" + "}}"), + ZIGBEE_STATUS_DEVICE_INDICATION, hex, srcAddr, parentNw, + status, decision + ); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); + XdrvRulesProcess(); + } + return -1; } - -// -// Send ZDO_IEEE_ADDR_REQ request to get IEEE long address -// -void Z_SendIEEEAddrReq(uint16_t shortaddr) { -} - -// -// Send ACTIVE_EP_REQ to collect active endpoints for this address -// -void Z_SendActiveEpReq(uint16_t shortaddr) { -} - -// -// Send AF Info Request -// -void Z_SendAFInfoRequest(uint16_t shortaddr) { -} - #endif // USE_ZIGBEE_EZSP -/*********************************************************************************************\ - * Callbacks -\*********************************************************************************************/ - - -// Aqara Occupancy behavior: the Aqara device only sends Occupancy: true events every 60 seconds. -// Here we add a timer so if we don't receive a Occupancy event for 90 seconds, we send Occupancy:false -void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, const JsonObject &json) { - static const uint32_t OCCUPANCY_TIMEOUT = 90 * 1000; // 90 s - // Read OCCUPANCY value if any - const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR(OCCUPANCY)); - if (nullptr != &val_endpoint) { - uint32_t occupancy = strToUInt(val_endpoint); - - if (occupancy) { - zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, OCCUPANCY_TIMEOUT, cluster, endpoint, Z_CAT_VIRTUAL_OCCUPANCY, 0, &Z_OccupancyCallback); - } else { - zigbee_devices.resetTimersForDevice(shortaddr, 0 /* groupaddr */, Z_CAT_VIRTUAL_OCCUPANCY); - } - } -} - - -// Publish the received values once they have been coalesced -int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) { - const JsonObject *json = zigbee_devices.jsonGet(shortaddr); - if (json == nullptr) { return 0; } // don't crash if not found - - zigbee_devices.jsonPublishFlush(shortaddr); - return 1; -} - -/*********************************************************************************************\ - * Global dispatcher for incoming messages -\*********************************************************************************************/ - -int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { - uint16_t groupid = buf.get16(2); - uint16_t clusterid = buf.get16(4); - uint16_t srcaddr = buf.get16(6); - uint8_t srcendpoint = buf.get8(8); - uint8_t dstendpoint = buf.get8(9); - uint8_t wasbroadcast = buf.get8(10); - uint8_t linkquality = buf.get8(11); - uint8_t securityuse = buf.get8(12); - uint32_t timestamp = buf.get32(13); - uint8_t seqnumber = buf.get8(17); +// +// Parse incoming ZCL message. This code is common to ZNP and EZSP +// +void Z_IncomingMessage(ZCLFrame &zcl_received) { + uint16_t srcaddr = zcl_received.getSrcAddr(); + uint16_t groupid = zcl_received.getGroupAddr(); + uint16_t clusterid = zcl_received.getClusterId(); + uint8_t linkquality = zcl_received.getLinkQuality(); + uint8_t srcendpoint = zcl_received.getSrcEndpoint(); bool defer_attributes = false; // do we defer attributes reporting to coalesce - ZCLFrame zcl_received = ZCLFrame::parseRawFrame(buf, 19, buf.get8(18), clusterid, groupid, - srcaddr, - srcendpoint, dstendpoint, wasbroadcast, - linkquality, securityuse, seqnumber, - timestamp); + // log the packet details zcl_received.log(); - zigbee_devices.setLQI(srcaddr, linkquality); + zigbee_devices.setLQI(srcaddr, linkquality != 0xFF ? linkquality : 0xFE); // EFR32 has a different scale for LQI char shortaddr[8]; snprintf_P(shortaddr, sizeof(shortaddr), PSTR("0x%04X"), srcaddr); - + DynamicJsonBuffer jsonBuffer; JsonObject& json = jsonBuffer.createObject(); @@ -823,17 +852,180 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { Z_AutoResponder(srcaddr, clusterid, srcendpoint, json[F("ReadNames")]); } } +} + + +#ifdef USE_ZIGBEE_EZSP + +/*********************************************************************************************\ + * Send ZDO Message +\*********************************************************************************************/ + +void EZ_SendZDO(uint16_t shortaddr, uint16_t cmd, const unsigned char *payload, size_t payload_len) { + SBuffer buf(payload_len + 20); + uint8_t seq = zigbee_devices.getNextSeqNumber(0x0000); + + buf.add8(EMBER_OUTGOING_DIRECT); // 00 + buf.add16(shortaddr); // dest addr + // ApsFrame + buf.add16(0x0000); // ZOD profile + buf.add16(cmd); // ZDO cmd in cluster + buf.add8(0); // srcEp + buf.add8(0); // dstEp + buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame + buf.add16(0x0000); // groupId + buf.add8(seq); + // end of ApsFrame + buf.add8(0x01); // tag TODO + buf.add8(payload_len + 1); // insert seq number + buf.add8(seq); + buf.addBuffer(payload, payload_len); +} + +/*********************************************************************************************\ + * Send specific EZSP messages +\*********************************************************************************************/ + +int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { + uint8_t msgtype = buf.get8(2); // see EZSP_EmberIncomingMessageType + bool wasbroadcast = (msgtype >= EMBER_INCOMING_MULTICAST) && (msgtype <= EMBER_INCOMING_BROADCAST_LOOPBACK); + uint16_t profileid = buf.get16(3); // HA = 0x0104, ZDO = 0x0000 + uint16_t clusterid = buf.get16(5); + uint8_t srcendpoint = buf.get8(7); + uint8_t dstendpoint = buf.get8(8); + uint16_t apsoptions = buf.get16(9); // see EZSP_EmberApsOption, usually EMBER_APS_OPTION_ENABLE_ADDRESS_DISCOVERY + bool securityuse = (apsoptions & EMBER_APS_OPTION_ENCRYPTION) ? true : false; + uint16_t groupid = buf.get16(11); + uint8_t seqnumber = buf.get8(13); + uint8_t linkquality = buf.get8(14); + // uint8_t linkrsssi = buf.get8(15); // probably not used as there is no equivalent in Z-Stack + uint16_t srcaddr = buf.get16(16); + uint8_t bindingindex = buf.get8(18); // TODO not sure we need this one as a coordinator + uint8_t addressindex = buf.get8(19); // TODO not sure how to handle this one + // offset 20 is len, and buffer starts at offset 21 + + + if ((0x0000 == profileid) && (0x00 == srcendpoint)) { + // ZDO request + SBuffer zdo_buf = buf.subBuffer(21, buf.get8(20)); + switch (clusterid) { + case ZDO_Device_annce: + Z_ReceiveEndDeviceAnnonce(res, zdo_buf); + break; + } + } else { + bool defer_attributes = false; // do we defer attributes reporting to coalesce + ZCLFrame zcl_received = ZCLFrame::parseRawFrame(buf, 21, buf.get8(20), clusterid, groupid, + srcaddr, + srcendpoint, dstendpoint, wasbroadcast, + linkquality, securityuse, seqnumber); + // + Z_IncomingMessage(zcl_received); + } return -1; } +// +// Callback for loading Zigbee configuration from Flash, called by the state machine +// +int32_t Z_Reset_Device(uint8_t value) { + // TODO - GPIO is hardwired to GPIO4 + digitalWrite(4, value ? HIGH : LOW); + return 0; // continue +} + +/*********************************************************************************************\ + * Default resolver +\*********************************************************************************************/ + +int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { + // Default message handler for new messages + if (zigbee.init_phase) { + // if still during initialization phase, ignore any unexpected message + return -1; // ignore message + } else { + switch (buf.get8(0)) { + case EZSP_incomingMessageHandler: + return EZ_IncomingMessage(res, buf); + break; + case EZSP_trustCenterJoinHandler: + return EZ_ReceiveTCJoinHandler(res, buf); + break; + } + return -1; + } +} + +#endif // USE_ZIGBEE_EZSP + +/*********************************************************************************************\ + * Callbacks +\*********************************************************************************************/ + + +// Aqara Occupancy behavior: the Aqara device only sends Occupancy: true events every 60 seconds. +// Here we add a timer so if we don't receive a Occupancy event for 90 seconds, we send Occupancy:false +void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, const JsonObject &json) { + static const uint32_t OCCUPANCY_TIMEOUT = 90 * 1000; // 90 s + // Read OCCUPANCY value if any + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR(OCCUPANCY)); + if (nullptr != &val_endpoint) { + uint32_t occupancy = strToUInt(val_endpoint); + + if (occupancy) { + zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, OCCUPANCY_TIMEOUT, cluster, endpoint, Z_CAT_VIRTUAL_OCCUPANCY, 0, &Z_OccupancyCallback); + } else { + zigbee_devices.resetTimersForDevice(shortaddr, 0 /* groupaddr */, Z_CAT_VIRTUAL_OCCUPANCY); + } + } +} + + +// Publish the received values once they have been coalesced +int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) { + const JsonObject *json = zigbee_devices.jsonGet(shortaddr); + if (json == nullptr) { return 0; } // don't crash if not found + + zigbee_devices.jsonPublishFlush(shortaddr); + return 1; +} + +/*********************************************************************************************\ + * Global dispatcher for incoming messages +\*********************************************************************************************/ + +int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { + uint16_t groupid = buf.get16(2); + uint16_t clusterid = buf.get16(4); + uint16_t srcaddr = buf.get16(6); + uint8_t srcendpoint = buf.get8(8); + uint8_t dstendpoint = buf.get8(9); + uint8_t wasbroadcast = buf.get8(10); + uint8_t linkquality = buf.get8(11); + uint8_t securityuse = buf.get8(12); + // uint32_t timestamp = buf.get32(13); + uint8_t seqnumber = buf.get8(17); + + bool defer_attributes = false; // do we defer attributes reporting to coalesce + + ZCLFrame zcl_received = ZCLFrame::parseRawFrame(buf, 19, buf.get8(18), clusterid, groupid, + srcaddr, + srcendpoint, dstendpoint, wasbroadcast, + linkquality, securityuse, seqnumber); + // + Z_IncomingMessage(zcl_received); + + return -1; +} + +#ifdef USE_ZIGBEE_ZNP + // Structure for the Dispatcher callbacks table typedef struct Z_Dispatcher { const uint8_t* match; ZB_RecvMsgFunc func; } Z_Dispatcher; -#ifdef USE_ZIGBEE_ZNP - // Ffilters based on ZNP frames ZBM(AREQ_AF_DATA_CONFIRM, Z_AREQ | Z_AF, AF_DATA_CONFIRM) // 4480 ZBM(AREQ_AF_INCOMING_MESSAGE, Z_AREQ | Z_AF, AF_INCOMING_MSG) // 4481 @@ -874,7 +1066,7 @@ int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { // if still during initialization phase, ignore any unexpected message return -1; // ignore message } else { - for (uint32_t i = 0; i < sizeof(Z_DispatchTable)/sizeof(Z_Dispatcher); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Z_DispatchTable); i++) { if (Z_ReceiveMatchPrefix(buf, Z_DispatchTable[i].match)) { (*Z_DispatchTable[i].func)(res, buf); } diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index 5c492e007..5fb60de56 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -495,7 +495,7 @@ int32_t ZigbeeProcessInputEZSP(class SBuffer &buf) { bool overflow = frame_control & 0x01; bool callbackPending = frame_control & 0x04; bool security_enabled = frame_control & 0x8000; - if (frame_control != 0x0180) { + if (truncated || overflow || security_enabled) { AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: specific frame_control 0x%04X"), frame_control); } diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index c59daf114..1370db3cc 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -954,8 +954,8 @@ void CmndZbRestore(void) { // void CmndZbPermitJoin(void) { if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + uint32_t payload = XdrvMailbox.payload; - uint16_t dstAddr = 0xFFFC; // default addr uint8_t duration = 60; // default 60s if (payload <= 0) { @@ -964,7 +964,10 @@ void CmndZbPermitJoin(void) { duration = 0xFF; // unlimited time } +// ZNP Version #ifdef USE_ZIGBEE_ZNP + uint16_t dstAddr = 0xFFFC; // default addr + SBuffer buf(34); buf.add8(Z_SREQ | Z_ZDO); // 25 buf.add8(ZDO_MGMT_PERMIT_JOIN_REQ); // 36 @@ -974,8 +977,17 @@ void CmndZbPermitJoin(void) { buf.add8(0x00); // TCSignificance ZigbeeZNPSend(buf.getBuffer(), buf.len()); + #endif // USE_ZIGBEE_ZNP +// EZSP VERSION +#ifdef USE_ZIGBEE_EZSP + SBuffer buf(3); + buf.add16(EZSP_permitJoining); + buf.add8(duration); + ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); +#endif // USE_ZIGBEE_EZSP + ResponseCmndDone(); } From 6853926948a40dcf8e5029efbdef2ad835bad799 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 30 Jun 2020 15:05:07 +0200 Subject: [PATCH 374/581] Fix array index Fix array index (#8823) --- tasmota/xdrv_27_shutter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index d4a384672..4e0f02945 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -174,7 +174,7 @@ void ShutterInit(void) bool relay_in_interlock = false; // if shutter 4 is unused - if (Settings.shutter_startrelay[MAX_SHUTTERS] == 0) { + if (Settings.shutter_startrelay[MAX_SHUTTERS -1] == 0) { Shutter.max_pwm_frequency = Settings.shuttercoeff[4][3] > 0 ? Settings.shuttercoeff[4][3] : Shutter.max_pwm_frequency; } for (uint32_t i = 0; i < MAX_SHUTTERS; i++) { From e52961b3b46b5dc0846d1eb93913c92e87cc5bef Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 30 Jun 2020 16:58:36 +0200 Subject: [PATCH 375/581] Add rotary encoder support - Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) - Fix Mi Desk Lamp brightness control (#8748) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/my_user_config.h | 2 +- tasmota/support_rotary.ino | 105 ++++++++++--------------------- tasmota/tasmota_configurations.h | 2 +- tasmota/xdrv_04_light.ino | 26 +++++++- 6 files changed, 61 insertions(+), 76 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index d8c865fdb..45a026fe5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -91,3 +91,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) - Add compile time interlock parameters (#8759) - Add compile time user template (#8766) +- Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 95fdf9efd..f40ebd895 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -8,6 +8,7 @@ - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) - Add compile time interlock parameters (#8759) - Add compile time user template (#8766) +- Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) - Fix exception or watchdog on rule re-entry (#8757) - Change ESP32 USER GPIO template representation decreasing template message size - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index e1e75e4b1..fa1d90afd 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -429,7 +429,7 @@ // #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code) // -- Optional modules ---------------------------- -//#define ROTARY_V1 // Add support for MI Desk Lamp +#define ROTARY_V1 // Add support for Rotary Encoder as used in MI Desk Lamp (+0k8 code) #define USE_SONOFF_RF // Add support for Sonoff Rf Bridge (+3k2 code) #define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+2k7 code) #define USE_SONOFF_SC // Add support for Sonoff Sc (+1k1 code) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 713ab4871..ec804173e 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -18,7 +18,6 @@ */ #ifdef USE_LIGHT -//#define ROTARY_V1 #ifdef ROTARY_V1 /*********************************************************************************************\ * Rotary support @@ -36,49 +35,40 @@ struct ROTARY { /********************************************************************************************/ -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception void update_rotary(void) ICACHE_RAM_ATTR; -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 +void update_rotary(void) { + if (Rotary.busy || !LightPowerIRAM()) { return; } -void update_rotary(void) -{ - if (MI_DESK_LAMP == my_module_type) { - if (LightPowerIRAM() && !Rotary.busy) { - /* - * https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h - */ - - uint8_t s = Rotary.state & 3; - if (digitalRead(Pin(GPIO_ROT1A))) { s |= 4; } - if (digitalRead(Pin(GPIO_ROT1B))) { s |= 8; } - switch (s) { - case 0: case 5: case 10: case 15: - break; - case 1: case 7: case 8: case 14: - Rotary.position++; break; - case 2: case 4: case 11: case 13: - Rotary.position--; break; - case 3: case 12: - Rotary.position = Rotary.position + 2; break; - default: - Rotary.position = Rotary.position - 2; break; - } - Rotary.state = (s >> 2); - } + /* + * https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h + */ + uint8_t s = Rotary.state & 3; + if (digitalRead(Pin(GPIO_ROT1A))) { s |= 4; } + if (digitalRead(Pin(GPIO_ROT1B))) { s |= 8; } + switch (s) { + case 0: case 5: case 10: case 15: + break; + case 1: case 7: case 8: case 14: + Rotary.position++; break; + case 2: case 4: case 11: case 13: + Rotary.position--; break; + case 3: case 12: + Rotary.position = Rotary.position + 2; break; + default: + Rotary.position = Rotary.position - 2; break; } + Rotary.state = (s >> 2); } -bool RotaryButtonPressed(void) -{ - if ((MI_DESK_LAMP == my_module_type) && (Rotary.changed) && LightPower()) { +bool RotaryButtonPressed(void) { + if (Rotary.changed && LightPower()) { Rotary.changed = 0; // Color temp changed, no need to turn of the light return true; } return false; } -void RotaryInit(void) -{ +void RotaryInit(void) { Rotary.present = 0; if (PinUsed(GPIO_ROT1A) && PinUsed(GPIO_ROT1B)) { Rotary.present++; @@ -93,57 +83,30 @@ void RotaryInit(void) * Rotary handler \*********************************************************************************************/ -void RotaryHandler(void) -{ +void RotaryHandler(void) { if (Rotary.last_position != Rotary.position) { Rotary.busy = true; int rotary_position = Rotary.position - Rotary.last_position; - if (MI_DESK_LAMP == my_module_type) { // Mi Desk lamp - if (Button.hold_timer[0]) { - Rotary.changed = 1; - // button1 is pressed: set color temperature - int16_t t = LightGetColorTemp(); - t = t + ((rotary_position) * 4); - if (t < 153) { - t = 153; - } - if (t > 500) { - t = 500; - } - DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), rotary_position); - LightSetColorTemp((uint16_t)t); - -// char scmnd[20]; -// snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLORTEMPERATURE " %d"), t); -// ExecuteCommand(scmnd, SRC_SWITCH); - } else { - int8_t d = Settings.light_dimmer; - d = d + rotary_position; - if (d < 1) { - d = 1; - } - if (d > 100) { - d = 100; - } - DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position); - - char scmnd[20]; - snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER "0 %d"), d); - ExecuteCommand(scmnd, SRC_SWITCH); - } + if (Button.hold_timer[0]) { // Button1 is pressed: set color temperature +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), rotary_position); + Rotary.changed = 1; + LightColorTempOffset(rotary_position * 4); + } else { +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position); + LightDimmerOffset(rotary_position); } + Rotary.last_position = 128; Rotary.position = 128; Rotary.busy = false; } } -void RotaryLoop(void) -{ +void RotaryLoop(void) { if (Rotary.present) { if (TimeReached(Rotary.debounce)) { - SetNextTimeInterval(Rotary.debounce, Settings.button_debounce); // Using button_debounce setting for this as well + SetNextTimeInterval(Rotary.debounce, Settings.button_debounce); // Using button_debounce setting for this as well RotaryHandler(); } } diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index be5f3a4f1..58d08d543 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -33,7 +33,7 @@ #undef USE_DISCOVERY // Disable mDNS (+8k code or +23.5k code with core 2_5_x, +0.3k mem) // -- Optional modules ---------------------------- -//#define ROTARY_V1 // Add support for MI Desk Lamp +#define ROTARY_V1 // Add support for Rotary Encoder as used in MI Desk Lamp #define USE_SONOFF_RF // Add support for Sonoff Rf Bridge (+3k2 code) #define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+2k7 code) #define USE_SONOFF_SC // Add support for Sonoff Sc (+1k1 code) diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index a47787f90..9755d3904 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -895,7 +895,7 @@ void LightStateClass::XyToRgb(float x, float y, uint8_t *rr, uint8_t *rg, uint8_ 0.0557f, -0.2040f, 1.0570f }; mat3x3(rgb_factors, XYZ, rgb); float max = (rgb[0] > rgb[1] && rgb[0] > rgb[2]) ? rgb[0] : (rgb[1] > rgb[2]) ? rgb[1] : rgb[2]; - + for (uint32_t i = 0; i < 3; i++) { rgb[i] = rgb[i] / max; // normalize to max == 1.0 rgb[i] = (rgb[i] <= 0.0031308f) ? 12.92f * rgb[i] : 1.055f * POW(rgb[i], (1.0f / 2.4f)) - 0.055f; // gamma @@ -1478,12 +1478,22 @@ void LightSetBri(uint8_t device, uint8_t bri) { } } +void LightColorTempOffset(int32_t offset) { + int32_t ct = LightGetColorTemp(); + if (0 == ct) { return; } // CT not supported + ct += offset; + if (ct < CT_MIN) { ct = CT_MIN; } + else if (ct > CT_MAX) { ct = CT_MAX; } + + LightSetColorTemp(ct); +} + void LightSetColorTemp(uint16_t ct) { /* Color Temperature (https://developers.meethue.com/documentation/core-concepts) * - * ct = 153 = 6500K = Cold = CCWW = FF00 - * ct = 600 = 2000K = Warm = CCWW = 00FF + * ct = 153 mirek = 6500K = Cold = CCWW = FF00 + * ct = 500 mirek = 2000K = Warm = CCWW = 00FF */ // don't set CT if not supported if ((LST_COLDWARM != Light.subtype) && (LST_RGBCW != Light.subtype)) { @@ -2745,6 +2755,16 @@ void CmndColorTemperature(void) } } +void LightDimmerOffset(int32_t offset) { + int32_t dimmer = light_state.getDimmer() + offset; + if (dimmer < 1) { dimmer = 1; } + if (dimmer > 100) { dimmer = 100; } + + XdrvMailbox.index = 0; + XdrvMailbox.payload = dimmer; + CmndDimmer(); +} + void CmndDimmer(void) { // Dimmer - Show current Dimmer state From 828a64815b77e1f0390888c59652041eea0b88bb Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 30 Jun 2020 17:48:38 +0200 Subject: [PATCH 376/581] Add rotary encoder color control Add rotary encoder color control when button pressed and postpone flash writes while turning rotary. --- tasmota/support_rotary.ino | 10 +++++++++- tasmota/xdrv_04_light.ino | 27 ++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index ec804173e..58f9925b3 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -88,10 +88,18 @@ void RotaryHandler(void) { Rotary.busy = true; int rotary_position = Rotary.position - Rotary.last_position; + if (Settings.save_data) { + if (save_data_counter < 2) { + save_data_counter = 2; // Postpone flash writes while rotary is turned + } + } + if (Button.hold_timer[0]) { // Button1 is pressed: set color temperature // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), rotary_position); Rotary.changed = 1; - LightColorTempOffset(rotary_position * 4); + if (!LightColorTempOffset(rotary_position * 4)) { // Ct from 153 - 500 + LightColorOffset(rotary_position * 4); // Hue from 0 - 359 + } } else { // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position); LightDimmerOffset(rotary_position); diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 9755d3904..0562cc900 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1478,14 +1478,31 @@ void LightSetBri(uint8_t device, uint8_t bri) { } } -void LightColorTempOffset(int32_t offset) { +void LightColorOffset(int32_t offset) { + uint16_t hue; + uint8_t sat; + light_state.getHSB(&hue, &sat, nullptr); // Allow user control over Saturation + hue += offset; + if (hue < 0) { hue = 0; } + if (hue > 359) { hue = 359; } + if (!Light.pwm_multi_channels) { + light_state.setHS(hue, sat); + } else { + light_state.setHS(hue, 255); + light_state.setBri(255); // If multi-channel, force bri to max, it will be later dimmed to correct value + } + light_controller.calcLevels(Light.new_color); +} + +bool LightColorTempOffset(int32_t offset) { int32_t ct = LightGetColorTemp(); - if (0 == ct) { return; } // CT not supported + if (0 == ct) { return false; } // CT not supported ct += offset; if (ct < CT_MIN) { ct = CT_MIN; } else if (ct > CT_MAX) { ct = CT_MAX; } LightSetColorTemp(ct); + return true; } void LightSetColorTemp(uint16_t ct) @@ -1769,9 +1786,9 @@ void LightCycleColor(int8_t direction) // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("LGT: random %d, wheel %d, hue %d"), Light.random, Light.wheel, hue); if (!Light.pwm_multi_channels) { - uint8_t sat; - light_state.getHSB(nullptr, &sat, nullptr); // Allow user control over Saturation - light_state.setHS(hue, sat); + uint8_t sat; + light_state.getHSB(nullptr, &sat, nullptr); // Allow user control over Saturation + light_state.setHS(hue, sat); } else { light_state.setHS(hue, 255); light_state.setBri(255); // If multi-channel, force bri to max, it will be later dimmed to correct value From b6495598de81e558ea93b8dd86a5d83ba48be884 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 30 Jun 2020 18:00:14 +0200 Subject: [PATCH 377/581] Tune rotary encoder color control --- tasmota/support_rotary.ino | 2 +- tasmota/xdrv_04_light.ino | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 58f9925b3..66fd1cd5c 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -98,7 +98,7 @@ void RotaryHandler(void) { // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), rotary_position); Rotary.changed = 1; if (!LightColorTempOffset(rotary_position * 4)) { // Ct from 153 - 500 - LightColorOffset(rotary_position * 4); // Hue from 0 - 359 + LightColorOffset(rotary_position * 2); // Hue from 0 - 359 } } else { // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position); diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 0562cc900..00cdd96b6 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1483,8 +1483,8 @@ void LightColorOffset(int32_t offset) { uint8_t sat; light_state.getHSB(&hue, &sat, nullptr); // Allow user control over Saturation hue += offset; - if (hue < 0) { hue = 0; } - if (hue > 359) { hue = 359; } + if (hue < 0) { hue += 359; } + if (hue > 359) { hue -= 359; } if (!Light.pwm_multi_channels) { light_state.setHS(hue, sat); } else { From 24669bb674dae4e99dbb6b16a1623c937159ce7e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 30 Jun 2020 18:09:18 +0200 Subject: [PATCH 378/581] Fix rule mem events Fix rule mem events (#8826) --- tasmota/xdrv_10_rules.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index ddeb82403..8d81df774 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -166,7 +166,7 @@ struct RULES { uint16_t last_minute = 60; uint16_t vars_event = 0; - uint8_t mems_event = 0; + uint16_t mems_event = 0; bool teleperiod = false; bool busy = false; From 8ff609b37171cccf9165ed18918452273deec617 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 30 Jun 2020 18:13:38 +0200 Subject: [PATCH 379/581] Add comment --- tasmota/xdrv_10_rules.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 8d81df774..adf29d13a 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -165,8 +165,8 @@ struct RULES { long old_dimm = -1; uint16_t last_minute = 60; - uint16_t vars_event = 0; - uint16_t mems_event = 0; + uint16_t vars_event = 0; // Bitmask supporting MAX_RULE_VARS bits + uint16_t mems_event = 0; // Bitmask supporting MAX_RULE_MEMS bits bool teleperiod = false; bool busy = false; From 9ac4502c782b0fee2c8861620f7b1b6a726aa468 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 1 Jul 2020 10:22:20 +0200 Subject: [PATCH 380/581] Rotary experiments --- tasmota/support_rotary.ino | 126 +++++++++++++++++++++++-------------- tasmota/tasmota.ino | 6 +- 2 files changed, 83 insertions(+), 49 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 66fd1cd5c..882131aee 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -23,12 +23,28 @@ * Rotary support \*********************************************************************************************/ +#define ROTARY_OPTION1 +//#define ROTARY_OPTION2 + +#ifdef ROTARY_OPTION1 +const uint8_t rotary_dimmer_increment = 1; +const uint8_t rotary_ct_increment = 2; +const uint8_t rotary_color_increment = 4; +#endif + +#ifdef ROTARY_OPTION2 +const uint8_t rotary_dimmer_increment = 2; +const uint8_t rotary_ct_increment = 8; +const uint8_t rotary_color_increment = 8; +#endif + struct ROTARY { - unsigned long debounce = 0; // Rotary debounce timer uint8_t present = 0; uint8_t state = 0; - uint8_t position = 128; - uint8_t last_position = 128; + uint8_t prevNextCode; + uint16_t store; + int8_t position = 128; + int8_t last_position = 128; uint8_t changed = 0; bool busy = false; } Rotary; @@ -39,25 +55,52 @@ void update_rotary(void) ICACHE_RAM_ATTR; void update_rotary(void) { if (Rotary.busy || !LightPowerIRAM()) { return; } - /* - * https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h - */ - uint8_t s = Rotary.state & 3; - if (digitalRead(Pin(GPIO_ROT1A))) { s |= 4; } - if (digitalRead(Pin(GPIO_ROT1B))) { s |= 8; } - switch (s) { - case 0: case 5: case 10: case 15: - break; +#ifdef ROTARY_OPTION1 + // https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h + uint8_t p1val = digitalRead(Pin(GPIO_ROT1A)); + uint8_t p2val = digitalRead(Pin(GPIO_ROT1B)); + uint8_t state = Rotary.state & 3; + if (p1val) { state |= 4; } + if (p2val) { state |= 8; } + Rotary.state = (state >> 2); + switch (state) { case 1: case 7: case 8: case 14: - Rotary.position++; break; + Rotary.position++; + return; case 2: case 4: case 11: case 13: - Rotary.position--; break; + Rotary.position--; + return; case 3: case 12: - Rotary.position = Rotary.position + 2; break; - default: - Rotary.position = Rotary.position - 2; break; + Rotary.position += 2; + return; + case 6: case 9: + Rotary.position -= 2; + return; } - Rotary.state = (s >> 2); +#endif + +#ifdef ROTARY_OPTION2 + // https://github.com/FrankBoesing/EncoderBounce/blob/master/EncoderBounce.h + const uint16_t rot_enc = 0b0110100110010110; + + uint8_t p1val = digitalRead(Pin(GPIO_ROT1B)); + uint8_t p2val = digitalRead(Pin(GPIO_ROT1A)); + uint8_t t = Rotary.prevNextCode; + t <<= 2; + if (p1val) { t |= 0x02; } + if (p2val) { t |= 0x01; } + t &= 0x0f; + Rotary.prevNextCode = t; + + // If valid then store as 16 bit data. + if (rot_enc & (1 << t)) { + Rotary.store = (Rotary.store << 4) | Rotary.prevNextCode; + if (Rotary.store == 0xd42b) { Rotary.position++; } + else if (Rotary.store == 0xe817) { Rotary.position--; } + else if ((Rotary.store & 0xff) == 0x2b) { Rotary.position--; } + else if ((Rotary.store & 0xff) == 0x17) { Rotary.position++; } + } +#endif } bool RotaryButtonPressed(void) { @@ -84,40 +127,31 @@ void RotaryInit(void) { \*********************************************************************************************/ void RotaryHandler(void) { - if (Rotary.last_position != Rotary.position) { - Rotary.busy = true; - int rotary_position = Rotary.position - Rotary.last_position; + if (Rotary.last_position == Rotary.position) { return; } - if (Settings.save_data) { - if (save_data_counter < 2) { - save_data_counter = 2; // Postpone flash writes while rotary is turned - } - } + Rotary.busy = true; + int rotary_position = Rotary.position - Rotary.last_position; + Rotary.last_position = Rotary.position; - if (Button.hold_timer[0]) { // Button1 is pressed: set color temperature -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), rotary_position); - Rotary.changed = 1; - if (!LightColorTempOffset(rotary_position * 4)) { // Ct from 153 - 500 - LightColorOffset(rotary_position * 2); // Hue from 0 - 359 - } - } else { -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: " D_CMND_DIMMER " %d"), rotary_position); - LightDimmerOffset(rotary_position); - } - - Rotary.last_position = 128; - Rotary.position = 128; - Rotary.busy = false; + if (Settings.save_data && (save_data_counter < 2)) { + save_data_counter = 2; // Postpone flash writes while rotary is turned } -} -void RotaryLoop(void) { - if (Rotary.present) { - if (TimeReached(Rotary.debounce)) { - SetNextTimeInterval(Rotary.debounce, Settings.button_debounce); // Using button_debounce setting for this as well - RotaryHandler(); + if (Button.hold_timer[0]) { // Button1 is pressed: set color temperature + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: CT/Color position %d"), rotary_position); + Rotary.changed = 1; + if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { // Ct 153..500 = (500 - 153) / 8 = 43 steps + LightColorOffset(rotary_position * rotary_color_increment); // Hue 0..359 = 360 / 8 = 45 steps } + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Dimmer position %d"), rotary_position); + LightDimmerOffset(rotary_position * rotary_dimmer_increment); // Dimmer 1..100 = 100 / 2 = 50 steps } + +// Rotary.last_position = 128; +// Rotary.position = 128; + + Rotary.busy = false; } #endif // ROTARY_V1 diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 24b100541..fec5706d4 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -365,9 +365,6 @@ void loop(void) { ButtonLoop(); SwitchLoop(); -#ifdef ROTARY_V1 - RotaryLoop(); -#endif #ifdef USE_DEVICE_GROUPS DeviceGroupsLoop(); #endif // USE_DEVICE_GROUPS @@ -375,6 +372,9 @@ void loop(void) { if (TimeReached(state_50msecond)) { SetNextTimeInterval(state_50msecond, 50); +#ifdef ROTARY_V1 + RotaryHandler(); +#endif XdrvCall(FUNC_EVERY_50_MSECOND); XsnsCall(FUNC_EVERY_50_MSECOND); } From 83b6665c39310be50c777bc64bed7721437a578a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 1 Jul 2020 10:24:46 +0200 Subject: [PATCH 381/581] Rotary experiments --- tasmota/tasmota.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index fec5706d4..b89c63a48 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -372,9 +372,11 @@ void loop(void) { if (TimeReached(state_50msecond)) { SetNextTimeInterval(state_50msecond, 50); +#ifdef USE_LIGHT #ifdef ROTARY_V1 RotaryHandler(); -#endif +#endif // ROTARY_V1 +#endif // USE_LIGHT XdrvCall(FUNC_EVERY_50_MSECOND); XsnsCall(FUNC_EVERY_50_MSECOND); } From 767eba7e8c5660de4c725daa0a6ac7c28ccecc3b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 1 Jul 2020 10:27:04 +0200 Subject: [PATCH 382/581] Rotary experiments --- tasmota/support_rotary.ino | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 882131aee..2dd8aad9c 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -130,27 +130,26 @@ void RotaryHandler(void) { if (Rotary.last_position == Rotary.position) { return; } Rotary.busy = true; + int rotary_position = Rotary.position - Rotary.last_position; - Rotary.last_position = Rotary.position; + Rotary.last_position = 128; + Rotary.position = 128; if (Settings.save_data && (save_data_counter < 2)) { save_data_counter = 2; // Postpone flash writes while rotary is turned } if (Button.hold_timer[0]) { // Button1 is pressed: set color temperature - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: CT/Color position %d"), rotary_position); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: CT/Color position %d"), rotary_position); Rotary.changed = 1; if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { // Ct 153..500 = (500 - 153) / 8 = 43 steps LightColorOffset(rotary_position * rotary_color_increment); // Hue 0..359 = 360 / 8 = 45 steps } } else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Dimmer position %d"), rotary_position); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Dimmer position %d"), rotary_position); LightDimmerOffset(rotary_position * rotary_dimmer_increment); // Dimmer 1..100 = 100 / 2 = 50 steps } -// Rotary.last_position = 128; -// Rotary.position = 128; - Rotary.busy = false; } From 618d86078c26ae924d94e35d3a1175fdc1ad6dd6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 1 Jul 2020 10:34:39 +0200 Subject: [PATCH 383/581] Rotary experiments --- tasmota/support_rotary.ino | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 2dd8aad9c..1eb6bbcdb 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -27,15 +27,15 @@ //#define ROTARY_OPTION2 #ifdef ROTARY_OPTION1 -const uint8_t rotary_dimmer_increment = 1; -const uint8_t rotary_ct_increment = 2; -const uint8_t rotary_color_increment = 4; +const int8_t rotary_dimmer_increment = 1; +const int8_t rotary_ct_increment = 2; +const int8_t rotary_color_increment = 4; #endif #ifdef ROTARY_OPTION2 -const uint8_t rotary_dimmer_increment = 2; -const uint8_t rotary_ct_increment = 8; -const uint8_t rotary_color_increment = 8; +const int8_t rotary_dimmer_increment = 2; +const int8_t rotary_ct_increment = 8; +const int8_t rotary_color_increment = 8; #endif struct ROTARY { @@ -131,7 +131,7 @@ void RotaryHandler(void) { Rotary.busy = true; - int rotary_position = Rotary.position - Rotary.last_position; + int8_t rotary_position = Rotary.position - Rotary.last_position; Rotary.last_position = 128; Rotary.position = 128; @@ -140,13 +140,13 @@ void RotaryHandler(void) { } if (Button.hold_timer[0]) { // Button1 is pressed: set color temperature -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: CT/Color position %d"), rotary_position); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: CT/Color position %d"), rotary_position); Rotary.changed = 1; if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { // Ct 153..500 = (500 - 153) / 8 = 43 steps LightColorOffset(rotary_position * rotary_color_increment); // Hue 0..359 = 360 / 8 = 45 steps } } else { -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Dimmer position %d"), rotary_position); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Dimmer position %d"), rotary_position); LightDimmerOffset(rotary_position * rotary_dimmer_increment); // Dimmer 1..100 = 100 / 2 = 50 steps } From dcb57d11e3e22705fe666b150541f81a9aa06791 Mon Sep 17 00:00:00 2001 From: Justifiably Date: Wed, 1 Jul 2020 13:58:31 +0100 Subject: [PATCH 384/581] Spurious low LMT01 pulse are sometimes seen, ignore them. --- tasmota/xsns_74_lmt01.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_74_lmt01.ino b/tasmota/xsns_74_lmt01.ino index 8bd23ca4a..d52e6dae2 100644 --- a/tasmota/xsns_74_lmt01.ino +++ b/tasmota/xsns_74_lmt01.ino @@ -81,7 +81,8 @@ int LMT01_getPulses(void) { hold = lmt01_pulseCount; delay(1); } - if (timeout > 0) { + // discard spurious low counts + if (timeout > 0 && hold >= 10) { return hold; } return -1; From 4fe216f3c77e894136edad7db5cfa4f3e6464795 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 1 Jul 2020 17:37:32 +0200 Subject: [PATCH 385/581] Support for AC Dimmer --- tasmota/core_esp8266_wiring_pwm.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tasmota/core_esp8266_wiring_pwm.cpp b/tasmota/core_esp8266_wiring_pwm.cpp index f74334e43..95ac7aefc 100644 --- a/tasmota/core_esp8266_wiring_pwm.cpp +++ b/tasmota/core_esp8266_wiring_pwm.cpp @@ -31,6 +31,7 @@ extern "C" { static uint32_t analogMap = 0; static int32_t analogScale = PWMRANGE; static uint16_t analogFreq = 1000; +static uint32_t analogDrift = 10000; extern void __analogWriteRange(uint32_t range) { if (range > 0) { @@ -48,11 +49,19 @@ extern void __analogWriteFreq(uint32_t freq) { } } -extern void __analogWrite(uint8_t pin, int val) { + +extern void __analogWriteCCyPeriod(uint8_t pin, int val, uint32_t period) { if (pin > 16) { return; } - uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq; + uint32_t analogPeriod; + if (period == 0) { + analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq; + } else { + analogPeriod = period; + } + + //uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq; if (val < 0) { val = 0; } else if (val > analogScale) { @@ -72,12 +81,18 @@ extern void __analogWrite(uint8_t pin, int val) { if (startWaveformClockCycles(pin, high, low, 0, phaseReference, 0, true)) { analogMap |= (1 << pin); } + //Serial.printf("phase: %d, high %d, low %d, drift %d, apr: %u\n", phaseReference,high,low, analogDrift, analogPeriod ); } +extern void __analogWrite(uint8_t pin, int val) { + __analogWriteCCyPeriod( pin, val, 0); +} + +extern void analogWriteCCyPeriod(uint8_t pin, int val, uint32_t priod) __attribute__((weak, alias("__analogWriteCCyPeriod"))); extern void analogWrite(uint8_t pin, int val) __attribute__((weak, alias("__analogWrite"))); extern void analogWriteFreq(uint32_t freq) __attribute__((weak, alias("__analogWriteFreq"))); extern void analogWriteRange(uint32_t range) __attribute__((weak, alias("__analogWriteRange"))); }; -#endif // ESP8266 +#endif // ESP8266 From 2d3d4863b4ef5d6f761e1b9cfa0cf729f446db51 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 1 Jul 2020 17:38:49 +0200 Subject: [PATCH 386/581] Update core_esp8266_wiring_pwm.cpp --- tasmota/core_esp8266_wiring_pwm.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tasmota/core_esp8266_wiring_pwm.cpp b/tasmota/core_esp8266_wiring_pwm.cpp index 95ac7aefc..1c7704b46 100644 --- a/tasmota/core_esp8266_wiring_pwm.cpp +++ b/tasmota/core_esp8266_wiring_pwm.cpp @@ -31,7 +31,6 @@ extern "C" { static uint32_t analogMap = 0; static int32_t analogScale = PWMRANGE; static uint16_t analogFreq = 1000; -static uint32_t analogDrift = 10000; extern void __analogWriteRange(uint32_t range) { if (range > 0) { From c11e948b81a543dbcbb47cdfbccaad64fbd863f4 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 1 Jul 2020 17:46:13 +0200 Subject: [PATCH 387/581] Update xsns_01_counter.ino --- tasmota/xsns_01_counter.ino | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index 3dfbdfaaf..0af9ee8a3 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -44,6 +44,9 @@ struct COUNTER { bool any_counter = false; } Counter; +uint32_t last_cycle; +uint32_t cycle_time; + #ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception void CounterUpdate(uint8_t index) ICACHE_RAM_ATTR; void CounterUpdate1(void) ICACHE_RAM_ATTR; @@ -75,7 +78,32 @@ void CounterUpdate(uint8_t index) Counter.timer_low_high[index] = time; Counter.pin_state ^= (1< Date: Wed, 1 Jul 2020 17:46:53 +0200 Subject: [PATCH 388/581] Add files via upload --- tasmota/Arduino.h | 300 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 tasmota/Arduino.h diff --git a/tasmota/Arduino.h b/tasmota/Arduino.h new file mode 100644 index 000000000..d5db76310 --- /dev/null +++ b/tasmota/Arduino.h @@ -0,0 +1,300 @@ +/* + Arduino.h - Main include file for the Arduino SDK + Copyright (c) 2005-2013 Arduino Team. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Arduino_h +#define Arduino_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stdlib_noniso.h" +#include "binary.h" +#include "esp8266_peri.h" +#include "twi.h" +#include "core_esp8266_features.h" +#include "core_esp8266_version.h" + +#define HIGH 0x1 +#define LOW 0x0 + +#define PWMRANGE 1023 + +//GPIO FUNCTIONS +#define INPUT 0x00 +#define INPUT_PULLUP 0x02 +#define INPUT_PULLDOWN_16 0x04 // PULLDOWN only possible for pin16 +#define OUTPUT 0x01 +#define OUTPUT_OPEN_DRAIN 0x03 +#define WAKEUP_PULLUP 0x05 +#define WAKEUP_PULLDOWN 0x07 +#define SPECIAL 0xF8 //defaults to the usable BUSes uart0rx/tx uart1tx and hspi +#define FUNCTION_0 0x08 +#define FUNCTION_1 0x18 +#define FUNCTION_2 0x28 +#define FUNCTION_3 0x38 +#define FUNCTION_4 0x48 + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define EULER 2.718281828459045235360287471352 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#define LSBFIRST 0 +#define MSBFIRST 1 + +//Interrupt Modes +#define RISING 0x01 +#define FALLING 0x02 +#define CHANGE 0x03 +#define ONLOW 0x04 +#define ONHIGH 0x05 +#define ONLOW_WE 0x0C +#define ONHIGH_WE 0x0D + +#define DEFAULT 1 +#define EXTERNAL 0 + +//timer dividers +enum TIM_DIV_ENUM { + TIM_DIV1 = 0, //80MHz (80 ticks/us - 104857.588 us max) + TIM_DIV16 = 1, //5MHz (5 ticks/us - 1677721.4 us max) + TIM_DIV256 = 3 //312.5Khz (1 tick = 3.2us - 26843542.4 us max) +}; + + +//timer int_types +#define TIM_EDGE 0 +#define TIM_LEVEL 1 +//timer reload values +#define TIM_SINGLE 0 //on interrupt routine you need to write a new value to start the timer again +#define TIM_LOOP 1 //on interrupt the counter will start with the same value again + +#define timer1_read() (T1V) +#define timer1_enabled() ((T1C & (1 << TCTE)) != 0) +#define timer1_interrupted() ((T1C & (1 << TCIS)) != 0) + +typedef void(*timercallback)(void); + +void timer1_isr_init(void); +void timer1_enable(uint8_t divider, uint8_t int_type, uint8_t reload); +void timer1_disable(void); +void timer1_attachInterrupt(timercallback userFunc); +void timer1_detachInterrupt(void); +void timer1_write(uint32_t ticks); //maximum ticks 8388607 + +// timer0 is a special CPU timer that has very high resolution but with +// limited control. +// it uses CCOUNT (ESP.GetCycleCount()) as the non-resetable timer counter +// it does not support divide, type, or reload flags +// it is auto-disabled when the compare value matches CCOUNT +// it is auto-enabled when the compare value changes +#define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM))) +#define timer0_read() ((__extension__({uint32_t count;__asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count));count;}))) +#define timer0_write(count) __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory") + +void timer0_isr_init(void); +void timer0_attachInterrupt(timercallback userFunc); +void timer0_detachInterrupt(void); + +// Use stdlib abs() and round() to avoid issues with the C++ libraries +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +void ets_intr_lock(); +void ets_intr_unlock(); + +#define interrupts() xt_rsil(0) +#define noInterrupts() xt_rsil(15) + +#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) +#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) +#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + +// avr-libc defines _NOP() since 1.6.2 +#ifndef _NOP +#define _NOP() do { __asm__ volatile ("nop"); } while (0) +#endif + +typedef uint16_t word; + +#define bit(b) (1UL << (b)) +#define _BV(b) (1UL << (b)) + +typedef bool boolean; +typedef uint8_t byte; + +void init(void); +void initVariant(void); + +int atexit(void (*func)()) __attribute__((weak)); + +void pinMode(uint8_t pin, uint8_t mode); +void digitalWrite(uint8_t pin, uint8_t val); +int digitalRead(uint8_t pin); +int analogRead(uint8_t pin); +void analogReference(uint8_t mode); +void analogWrite(uint8_t pin, int val); +void analogWriteCCyPeriod(uint8_t pin, int val, uint32_t period); +void analogWriteFreq(uint32_t freq); +void analogWriteRange(uint32_t range); + +unsigned long millis(void); +unsigned long micros(void); +uint64_t micros64(void); +void delay(unsigned long); +void delayMicroseconds(unsigned int us); +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); +unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); + +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); + +void attachInterrupt(uint8_t pin, void (*)(void), int mode); +void detachInterrupt(uint8_t pin); +void attachInterruptArg(uint8_t pin, void (*)(void*), void* arg, int mode); + +void preinit(void); +void setup(void); +void loop(void); + +void yield(void); + +void optimistic_yield(uint32_t interval_us); + +#define _PORT_GPIO16 1 +#define digitalPinToPort(pin) (((pin)==16)?(_PORT_GPIO16):(0)) +#define digitalPinToBitMask(pin) (((pin)==16)?(1):(1UL << (pin))) +#define digitalPinToTimer(pin) (0) +#define portOutputRegister(port) (((port)==_PORT_GPIO16)?((volatile uint32_t*) &GP16O):((volatile uint32_t*) &GPO)) +#define portInputRegister(port) (((port)==_PORT_GPIO16)?((volatile uint32_t*) &GP16I):((volatile uint32_t*) &GPI)) +#define portModeRegister(port) (((port)==_PORT_GPIO16)?((volatile uint32_t*) &GP16E):((volatile uint32_t*) &GPE)) + +#define NOT_A_PIN -1 +#define NOT_A_PORT -1 +#define NOT_AN_INTERRUPT -1 +#define NOT_ON_TIMER 0 + +#ifdef __cplusplus +} // extern "C" +#endif + + +//for compatibility, below 4 lines to be removed in release 3.0.0 +#ifdef __cplusplus +extern "C" +#endif +const int TIM_DIV265 __attribute__((deprecated, weak)) = TIM_DIV256; + + + +#ifdef __cplusplus + +#include +#include +#include + +#include "WCharacter.h" +#include "WString.h" + +#include "HardwareSerial.h" +#include "Esp.h" +#include "Updater.h" +#include "debug.h" + +using std::min; +using std::max; +using std::round; +using std::isinf; +using std::isnan; + +#define _min(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a < _b? _a : _b; }) +#define _max(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a > _b? _a : _b; }) + +uint16_t makeWord(uint16_t w); +uint16_t makeWord(byte h, byte l); + +#define word(...) makeWord(__VA_ARGS__) + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); +unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); + +void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); +void tone(uint8_t _pin, int frequency, unsigned long duration = 0); +void tone(uint8_t _pin, double frequency, unsigned long duration = 0); +void noTone(uint8_t _pin); + +// WMath prototypes +long random(long); +long random(long, long); +void randomSeed(unsigned long); +long secureRandom(long); +long secureRandom(long, long); +long map(long, long, long, long, long); + +void setTZ(const char* tz); + +void configTime(int timezone, int daylightOffset_sec, const char* server1, + const char* server2 = nullptr, const char* server3 = nullptr); + +void configTime(const char* tz, const char* server1, + const char* server2 = nullptr, const char* server3 = nullptr); + +// esp32 api compatibility +inline void configTzTime(const char* tz, const char* server1, + const char* server2 = nullptr, const char* server3 = nullptr) +{ + configTime(tz, server1, server2, server3); +} + +#endif // __cplusplus + +#include "pins_arduino.h" + +#endif + +#ifdef DEBUG_ESP_OOM +// reinclude *alloc redefinition because of undefining them +// this is mandatory for allowing OOM *alloc definitions in .ino files +#include "umm_malloc/umm_malloc_cfg.h" +#endif From 533f3142776e40dff6d7e3db8207e2eb783b21bd Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 1 Jul 2020 18:45:36 +0200 Subject: [PATCH 389/581] Update Arduino.h --- tasmota/Arduino.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/Arduino.h b/tasmota/Arduino.h index d5db76310..a4ef77535 100644 --- a/tasmota/Arduino.h +++ b/tasmota/Arduino.h @@ -17,6 +17,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef ESP8266 + #ifndef Arduino_h #define Arduino_h @@ -298,3 +300,5 @@ inline void configTzTime(const char* tz, const char* server1, // this is mandatory for allowing OOM *alloc definitions in .ino files #include "umm_malloc/umm_malloc_cfg.h" #endif + +#endif From 64bd9f1974279dac0e870fc4c907f047e814d9db Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Thu, 2 Jul 2020 06:46:04 +0200 Subject: [PATCH 390/581] scripter fixes --- tasmota/tasmota.ino | 10 ++--- tasmota/xdrv_10_scripter.ino | 86 +++++++++++++++++++++++++----------- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index b89c63a48..0a0901d56 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -319,7 +319,7 @@ void setup(void) { XdrvCall(FUNC_INIT); XsnsCall(FUNC_INIT); #ifdef USE_SCRIPT - Run_Scripter(">BS",3,0); + if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">BS",3,0); #endif rules_flag.system_init = 1; @@ -365,6 +365,9 @@ void loop(void) { ButtonLoop(); SwitchLoop(); +#ifdef ROTARY_V1 + RotaryLoop(); +#endif #ifdef USE_DEVICE_GROUPS DeviceGroupsLoop(); #endif // USE_DEVICE_GROUPS @@ -372,11 +375,6 @@ void loop(void) { if (TimeReached(state_50msecond)) { SetNextTimeInterval(state_50msecond, 50); -#ifdef USE_LIGHT -#ifdef ROTARY_V1 - RotaryHandler(); -#endif // ROTARY_V1 -#endif // USE_LIGHT XdrvCall(FUNC_EVERY_50_MSECOND); XsnsCall(FUNC_EVERY_50_MSECOND); } diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 347428284..ddb818a91 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -101,8 +101,9 @@ uint32_t DecodeLightId(uint32_t hue_id); #ifdef USE_24C256 #pragma message "script 24c256 file option used" #else -#warning "EEP_SCRIPT_SIZE also needs USE_24C256" -#define USE_24C256 +//#warning "EEP_SCRIPT_SIZE also needs USE_24C256" +#pragma message "internal eeprom script buffer used" +//#define USE_24C256 #endif #endif // EEP_SCRIPT_SIZE @@ -491,7 +492,7 @@ char *script; if (*lp==';') goto next_line; if (init) { // init section - if (*lp=='>') { + if (*lp=='>' || !*lp) { init=0; break; } @@ -1370,10 +1371,12 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso if (jo) { // look for json input + char jvname[32]; + strcpy(jvname,vname); const char* str_value; uint8_t aindex; String vn; - char *ja=strchr(vname,'['); + char *ja=strchr(jvname,'['); if (ja) { // json array *ja=0; @@ -1386,7 +1389,7 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso aindex--; } if (jo->success()) { - char *subtype=strchr(vname,'#'); + char *subtype=strchr(jvname,'#'); char *subtype2; if (subtype) { *subtype=0; @@ -1397,7 +1400,7 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso *subtype2++; } } - vn=vname; + vn=jvname; str_value = (*jo)[vn]; if ((*jo)[vn].success()) { if (subtype) { @@ -2191,6 +2194,22 @@ chknext: len=0; goto exit; } +#ifdef USE_MORITZ + if (!strncmp(vname,"mo(",3)) { + float fvar1; + lp=GetNumericResult(lp+3,OPER_EQU,&fvar1,0); + SCRIPT_SKIP_SPACES + float fvar2; + lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); + SCRIPT_SKIP_SPACES + char rbuff[64]; + fvar=mo_getvars(fvar1,fvar2,rbuff); + lp++; + if (sp) strlcpy(sp,rbuff,glob_script_mem.max_ssize); + len=0; + goto strexit; + } +#endif break; case 'p': if (!strncmp(vname,"pin[",4)) { @@ -3285,8 +3304,25 @@ void esp32_beep(int32_t freq ,uint32_t len) { // execute section of scripter int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { + if (!glob_script_mem.scriptptr) { + return -99; + } + if (tasm_cmd_activ && tlen>0) return 0; + JsonObject *jo=0; + DynamicJsonBuffer jsonBuffer; // on heap + JsonObject &jobj=jsonBuffer.parseObject(js); + if (js) { + jo=&jobj; + } else { + jo=0; + } + + return Run_script_sub(type, tlen, jo); +} + +int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) { uint8_t vtype=0,sindex,xflg,floop=0,globvindex,fromscriptcmd=0; char *lp_next; int8_t globaindex,saindex; @@ -3307,19 +3343,6 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { float fvar=0,fvar1,sysvar,swvar; uint8_t section=0,sysv_type=0,swflg=0; - if (!glob_script_mem.scriptptr) { - return -99; - } - - JsonObject *jo=0; - DynamicJsonBuffer jsonBuffer; // on heap - JsonObject &jobj=jsonBuffer.parseObject(js); - if (js) { - jo=&jobj; - } else { - jo=0; - } - char *lp=glob_script_mem.scriptptr; while (1) { @@ -3442,10 +3465,15 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { lp=GetNumericResult(lp,OPER_EQU,&cv_inc,0); //SCRIPT_SKIP_EOL cv_ptr=lp; - if (*cv_count<=cv_max) { + if (*cv_count<=cv_max && cv_inc>0) { + // inc loop floop=1; } else { + // dec loop floop=2; + if (cv_inc>0) { + floop=1; + } } } else { // error @@ -3726,7 +3754,12 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { str[0]='>'; lp=GetStringResult(lp,OPER_EQU,&str[1],0); lp++; - execute_script(str); + //execute_script(str); + char *svd_sp=glob_script_mem.scriptptr; + strcat(str,"\n#"); + glob_script_mem.scriptptr=str; + Run_script_sub(">",1,jo); + glob_script_mem.scriptptr=svd_sp; } // check for variable result @@ -3783,7 +3816,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { switch (lastop) { case OPER_EQU: if (glob_script_mem.var_not_found) { - if (!js) toLogEOL("var not found: ",lp); + if (!jo) toLogEOL("var not found: ",lp); goto next_line; } *dfvar=fvar; @@ -3855,7 +3888,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { char *slp=lp; glob_script_mem.glob_error=0; lp=GetStringResult(lp,OPER_EQU,str,jo); - if (!js && glob_script_mem.glob_error) { + if (!jo && glob_script_mem.glob_error) { // mismatch lp=GetNumericResult(slp,OPER_EQU,&fvar,0); dtostrfd(fvar,6,str); @@ -4669,7 +4702,10 @@ void SaveScriptEnd(void) { AddLog_P2(LOG_LEVEL_INFO, PSTR("script init error: %d"), res); return; } - Run_Scripter(">B",2,0); + + Run_Scripter(">B\n",3,0); + Run_Scripter(">BS",3,0); + fast_script=Run_Scripter(">F",-2,0); } } @@ -6694,7 +6730,7 @@ bool Xdrv10(uint8_t function) break; case FUNC_INIT: if (bitRead(Settings.rule_enabled, 0)) { - Run_Scripter(">B",2,0); + Run_Scripter(">B\n",3,0); fast_script=Run_Scripter(">F",-2,0); #if defined(USE_SCRIPT_HUE) && defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) && defined(USE_LIGHT) Script_Check_Hue(0); From 67b3702b0b8e9a61287aa369e3045eaecb690393 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Thu, 2 Jul 2020 06:48:07 +0200 Subject: [PATCH 391/581] Update tasmota.ino --- tasmota/tasmota.ino | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 0a0901d56..ab632f01b 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -365,9 +365,6 @@ void loop(void) { ButtonLoop(); SwitchLoop(); -#ifdef ROTARY_V1 - RotaryLoop(); -#endif #ifdef USE_DEVICE_GROUPS DeviceGroupsLoop(); #endif // USE_DEVICE_GROUPS @@ -375,6 +372,11 @@ void loop(void) { if (TimeReached(state_50msecond)) { SetNextTimeInterval(state_50msecond, 50); +#ifdef USE_LIGHT +#ifdef ROTARY_V1 + RotaryHandler(); +#endif // ROTARY_V1 +#endif // USE_LIGHT XdrvCall(FUNC_EVERY_50_MSECOND); XsnsCall(FUNC_EVERY_50_MSECOND); } From 862262c34950977c87630537851e7cd83ff45ee8 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Thu, 2 Jul 2020 08:37:32 +0200 Subject: [PATCH 392/581] Update Arduino.h --- tasmota/Arduino.h | 191 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 1 deletion(-) diff --git a/tasmota/Arduino.h b/tasmota/Arduino.h index a4ef77535..2dd8b22e2 100644 --- a/tasmota/Arduino.h +++ b/tasmota/Arduino.h @@ -16,7 +16,6 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #ifdef ESP8266 #ifndef Arduino_h @@ -301,4 +300,194 @@ inline void configTzTime(const char* tz, const char* server1, #include "umm_malloc/umm_malloc_cfg.h" #endif +#else + +/* + Arduino.h - Main include file for the Arduino SDK + Copyright (c) 2005-2013 Arduino Team. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef Arduino_h +#define Arduino_h + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "esp32-hal.h" +#include "esp8266-compat.h" +#include "soc/gpio_reg.h" + +#include "stdlib_noniso.h" +#include "binary.h" + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define EULER 2.718281828459045235360287471352 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#define LSBFIRST 0 +#define MSBFIRST 1 + +//Interrupt Modes +#define RISING 0x01 +#define FALLING 0x02 +#define CHANGE 0x03 +#define ONLOW 0x04 +#define ONHIGH 0x05 +#define ONLOW_WE 0x0C +#define ONHIGH_WE 0x0D + +#define DEFAULT 1 +#define EXTERNAL 0 + +#ifndef __STRINGIFY +#define __STRINGIFY(a) #a +#endif + +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define sei() +#define cli() +#define interrupts() sei() +#define noInterrupts() cli() + +#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) +#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) +#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + +// avr-libc defines _NOP() since 1.6.2 +#ifndef _NOP +#define _NOP() do { __asm__ volatile ("nop"); } while (0) +#endif + +#define bit(b) (1UL << (b)) +#define _BV(b) (1UL << (b)) + +#define digitalPinToPort(pin) (((pin)>31)?1:0) +#define digitalPinToBitMask(pin) (1UL << (((pin)>31)?((pin)-32):(pin))) +#define digitalPinToTimer(pin) (0) +#define analogInPinToBit(P) (P) +#define portOutputRegister(port) ((volatile uint32_t*)((port)?GPIO_OUT1_REG:GPIO_OUT_REG)) +#define portInputRegister(port) ((volatile uint32_t*)((port)?GPIO_IN1_REG:GPIO_IN_REG)) +#define portModeRegister(port) ((volatile uint32_t*)((port)?GPIO_ENABLE1_REG:GPIO_ENABLE_REG)) + +#define NOT_A_PIN -1 +#define NOT_A_PORT -1 +#define NOT_AN_INTERRUPT -1 +#define NOT_ON_TIMER 0 + +typedef bool boolean; +typedef uint8_t byte; +typedef unsigned int word; + +void setup(void); +void loop(void); + +long random(long, long); +void randomSeed(unsigned long); +long map(long, long, long, long, long); + +#ifdef __cplusplus +extern "C" { +#endif + +void init(void); +void initVariant(void); +void initArduino(void); + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); +unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); + +uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); + +#ifdef __cplusplus +} + +#include +#include + +#include "WCharacter.h" +#include "WString.h" +#include "Stream.h" +#include "Printable.h" +#include "Print.h" +#include "IPAddress.h" +#include "Client.h" +#include "Server.h" +#include "Udp.h" +#include "HardwareSerial.h" +#include "Esp.h" + +using std::abs; +using std::isinf; +using std::isnan; +using std::max; +using std::min; +using ::round; + +uint16_t makeWord(uint16_t w); +uint16_t makeWord(byte h, byte l); + +#define word(...) makeWord(__VA_ARGS__) + +unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); +unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); + +extern "C" bool getLocalTime(struct tm * info, uint32_t ms = 5000); +extern "C" void configTime(long gmtOffset_sec, int daylightOffset_sec, + const char* server1, const char* server2 = nullptr, const char* server3 = nullptr); +extern "C" void configTzTime(const char* tz, + const char* server1, const char* server2 = nullptr, const char* server3 = nullptr); + +// WMath prototypes +long random(long); +#endif /* __cplusplus */ + +#define _min(a,b) ((a)<(b)?(a):(b)) +#define _max(a,b) ((a)>(b)?(a):(b)) + +#include "pins_arduino.h" + +#endif /* _ESP32_CORE_ARDUINO_H_ */ + #endif From 0509eee6a5da04ce95bd8ff49c7b3c8f56ebaa27 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Thu, 2 Jul 2020 08:42:43 +0200 Subject: [PATCH 393/581] Update xsns_01_counter.ino --- tasmota/xsns_01_counter.ino | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index 0af9ee8a3..18f1ed461 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -98,7 +98,11 @@ void CounterUpdate(uint8_t index) // add 100.000 cpu ticks to ensure right step calculation uint32_t steps = (current_cycle-last_cycle+100000)/(clockCyclesPerMicrosecond() * 10000); cycle_time = (current_cycle-last_cycle)/steps; - analogWriteCCyPeriod(Pin(GPIO_PWM1, index), 5, cycle_time ); + #ifdef ESP8266 + analogWriteCCyPeriod(Pin(GPIO_PWM1, index), 5, cycle_time ); + #else + analogWrite(Pin(GPIO_PWM1, index), 5); + #endif } last_cycle = current_cycle; } From 0cc1dd957b1bd0b035d63784867b6a2fe1b0ee4b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 2 Jul 2020 18:13:14 +0200 Subject: [PATCH 394/581] Add SO98 to control user rotary support --- BUILDS.md | 2 +- RELEASENOTES.md | 2 + tasmota/CHANGELOG.md | 2 + tasmota/my_user_config.h | 1 + tasmota/settings.h | 4 +- tasmota/support_button.ino | 4 +- tasmota/support_rotary.ino | 222 ++++++++++++++++++++++++++++++------- tasmota/tasmota.ino | 2 - 8 files changed, 193 insertions(+), 46 deletions(-) diff --git a/BUILDS.md b/BUILDS.md index 97bef3901..c1aa5e2e3 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -29,7 +29,7 @@ | USE_HOTPLUG | - | - | - | - | - | - | - | | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks -| ROTARY_V1 | - | - | - | - | - | - | - | +| ROTARY_V1 | - | - | x | - | x | - | - | | USE_SONOFF_RF | - | - | x | x | x | - | - | | USE_RF_FLASH | - | - | x | x | x | - | - | | USE_SONOFF_SC | - | - | x | x | x | - | - | diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 45a026fe5..a9413ce6b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -66,6 +66,8 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``Rule0`` to change global rule parameters - Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) +- Add command ``SetOption97 0/1`` to switch between Tuya serial speeds 9600 bps (0) or 115200 bps (1) +- Add command ``SetOption98 0/1`` to provide rotary rule triggers (1) instead of controlling light (0) - Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index f40ebd895..2535eafeb 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,6 +3,8 @@ ### 8.3.1.6 20200617 - Add command ``Module2`` to configure fallback module on fast reboot (#8464) +- Add command ``SetOption97 0/1`` to switch between Tuya serial speeds 9600 bps (0) or 115200 bps (1) +- Add command ``SetOption98 0/1`` to provide rotary rule triggers (1) instead of controlling light (0) - Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff - Add library to be used for decoding Teleinfo (French Metering Smart Meter) - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index fa1d90afd..c073447fe 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -430,6 +430,7 @@ // -- Optional modules ---------------------------- #define ROTARY_V1 // Add support for Rotary Encoder as used in MI Desk Lamp (+0k8 code) + #define ROTARY_MAX_STEPS 10 // Rotary step boundary #define USE_SONOFF_RF // Add support for Sonoff Rf Bridge (+3k2 code) #define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+2k7 code) #define USE_SONOFF_SC // Add support for Sonoff Sc (+1k1 code) diff --git a/tasmota/settings.h b/tasmota/settings.h index 68e4a9db3..7fd279ab6 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -115,9 +115,9 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t compress_rules_cpu : 1; // bit 11 (v8.2.0.6) - SetOption93 - Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick uint32_t max6675 : 1; // bit 12 (v8.3.1.2) - SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855 uint32_t network_wifi : 1; // bit 13 (v8.3.1.3) - CMND_WIFI - uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) = CMND_ETHERNET + uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) - CMND_ETHERNET uint32_t tuyamcu_baudrate : 1; // bit 15 (v8.3.1.6) - SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) - uint32_t spare16 : 1; + uint32_t rotary_uses_rules : 1; // bit 16 (v8.3.1.6) - SetOption98 - Use rules instead of light control uint32_t spare17 : 1; uint32_t spare18 : 1; uint32_t spare19 : 1; diff --git a/tasmota/support_button.ino b/tasmota/support_button.ino index bf058db4e..2d7c6a415 100644 --- a/tasmota/support_button.ino +++ b/tasmota/support_button.ino @@ -302,7 +302,7 @@ void ButtonHandler(void) } } } -#if defined(USE_LIGHT) && defined(ROTARY_V1) +#ifdef ROTARY_V1 if (!((0 == button_index) && RotaryButtonPressed())) { #endif if (!Settings.flag3.mqtt_buttons && single_press && SendKey(KEY_BUTTON, button_index + Button.press_counter[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set @@ -344,7 +344,7 @@ void ButtonHandler(void) } } } -#if defined(USE_LIGHT) && defined(ROTARY_V1) +#ifdef ROTARY_V1 } #endif Button.press_counter[button_index] = 0; diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 1eb6bbcdb..cd80b4484 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -17,35 +17,72 @@ along with this program. If not, see . */ -#ifdef USE_LIGHT #ifdef ROTARY_V1 /*********************************************************************************************\ * Rotary support + * + * Supports full range in 10 steps of the Rotary Encoder: + * - Light Dimmer + * - Light Color for RGB lights when Button1 pressed + * - Light Color Temperature for CW lights when Button1 pressed + * + * _______ _______ + * GPIO_ROT1A ______| |_______| |______ GPIO_ROT1A + * negative <-- _______ _______ __ --> positive + * GPIO_ROT1B __| |_______| |_______| GPIO_ROT1B + * \*********************************************************************************************/ -#define ROTARY_OPTION1 -//#define ROTARY_OPTION2 +#ifndef ROTARY_MAX_STEPS +#define ROTARY_MAX_STEPS 10 // Rotary step boundary +#endif + +//#define ROTARY_OPTION1 // Up to 4 interrupts and pulses per step +//#define ROTARY_OPTION2 // Up to 4 interrupts but 1 pulse per step +#define ROTARY_OPTION3 // 1 interrupt and pulse per step #ifdef ROTARY_OPTION1 -const int8_t rotary_dimmer_increment = 1; -const int8_t rotary_ct_increment = 2; -const int8_t rotary_color_increment = 4; -#endif +// up to 4 pulses per step +const uint8_t rotary_dimmer_increment = 100 / (ROTARY_MAX_STEPS * 3); // Dimmer 1..100 = 100 +const uint8_t rotary_ct_increment = 350 / (ROTARY_MAX_STEPS * 3); // Ct 153..500 = 347 +const uint8_t rotary_color_increment = 360 / (ROTARY_MAX_STEPS * 3); // Hue 0..359 = 360 +#endif // ROTARY_OPTION1 #ifdef ROTARY_OPTION2 -const int8_t rotary_dimmer_increment = 2; -const int8_t rotary_ct_increment = 8; -const int8_t rotary_color_increment = 8; -#endif +// 1 pulse per step +const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100 +const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347 +const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 +#endif // ROTARY_OPTION2 + +#ifdef ROTARY_OPTION3 +// 1 pulse per step +const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100 +const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347 +const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 +#endif // ROTARY_OPTION3 + +const uint8_t ROTARY_TIMEOUT = 10; // 10 * RotaryHandler() call which is usually 10 * 0.05 seconds struct ROTARY { - uint8_t present = 0; +#ifdef ROTARY_OPTION1 uint8_t state = 0; - uint8_t prevNextCode; +#endif // ROTARY_OPTION1 +#ifdef ROTARY_OPTION2 uint16_t store; - int8_t position = 128; - int8_t last_position = 128; - uint8_t changed = 0; + uint8_t prev_next_code; +#endif // ROTARY_OPTION2 +#ifdef ROTARY_OPTION3 + uint32_t debounce = 0; +#endif // ROTARY_OPTION3 + int8_t abs_position1 = 0; + int8_t abs_position2 = 0; + int8_t direction = 0; // Control consistent direction + uint8_t present = 0; + uint8_t position = 128; + uint8_t last_position = 128; + uint8_t timeout = 0; // Disallow direction change within 0.5 second + bool changed = false; bool busy = false; } Rotary; @@ -53,10 +90,18 @@ struct ROTARY { void update_rotary(void) ICACHE_RAM_ATTR; void update_rotary(void) { - if (Rotary.busy || !LightPowerIRAM()) { return; } + if (Rotary.busy) { return; } + bool powered_on = (power); +#ifdef USE_LIGHT + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + powered_on = (LightPowerIRAM()); + } +#endif // USE_LIGHT + if (!powered_on) { return; } #ifdef ROTARY_OPTION1 // https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h +/* uint8_t p1val = digitalRead(Pin(GPIO_ROT1A)); uint8_t p2val = digitalRead(Pin(GPIO_ROT1B)); uint8_t state = Rotary.state & 3; @@ -77,35 +122,105 @@ void update_rotary(void) { Rotary.position -= 2; return; } -#endif +*/ + uint8_t p1val = digitalRead(Pin(GPIO_ROT1A)); + uint8_t p2val = digitalRead(Pin(GPIO_ROT1B)); + uint8_t state = Rotary.state & 3; + if (p1val) { state |= 4; } + if (p2val) { state |= 8; } + Rotary.state = (state >> 2); + int direction = 0; + int multiply = 1; + switch (state) { + case 3: case 12: + multiply = 2; + case 1: case 7: case 8: case 14: + direction = 1; + break; + case 6: case 9: + multiply = 2; + case 2: case 4: case 11: case 13: + direction = -1; + break; + } + if ((0 == Rotary.direction) || (direction == Rotary.direction)) { + Rotary.position += (direction * multiply); + Rotary.direction = direction; + } +#endif // ROTARY_OPTION1 #ifdef ROTARY_OPTION2 // https://github.com/FrankBoesing/EncoderBounce/blob/master/EncoderBounce.h +/* const uint16_t rot_enc = 0b0110100110010110; uint8_t p1val = digitalRead(Pin(GPIO_ROT1B)); uint8_t p2val = digitalRead(Pin(GPIO_ROT1A)); - uint8_t t = Rotary.prevNextCode; + uint8_t t = Rotary.prev_next_code; t <<= 2; if (p1val) { t |= 0x02; } if (p2val) { t |= 0x01; } t &= 0x0f; - Rotary.prevNextCode = t; + Rotary.prev_next_code = t; // If valid then store as 16 bit data. if (rot_enc & (1 << t)) { - Rotary.store = (Rotary.store << 4) | Rotary.prevNextCode; + Rotary.store = (Rotary.store << 4) | Rotary.prev_next_code; if (Rotary.store == 0xd42b) { Rotary.position++; } else if (Rotary.store == 0xe817) { Rotary.position--; } else if ((Rotary.store & 0xff) == 0x2b) { Rotary.position--; } else if ((Rotary.store & 0xff) == 0x17) { Rotary.position++; } } -#endif +*/ + const uint16_t rot_enc = 0b0110100110010110; + + uint8_t p1val = digitalRead(Pin(GPIO_ROT1B)); + uint8_t p2val = digitalRead(Pin(GPIO_ROT1A)); + uint8_t t = Rotary.prev_next_code; + t <<= 2; + if (p1val) { t |= 0x02; } + if (p2val) { t |= 0x01; } + t &= 0x0f; + Rotary.prev_next_code = t; + + // If valid then store as 16 bit data. + if (rot_enc & (1 << t)) { + Rotary.store = (Rotary.store << 4) | Rotary.prev_next_code; + int direction = 0; + if (Rotary.store == 0xd42b) { direction = 1; } + else if (Rotary.store == 0xe817) { direction = -1; } + else if ((Rotary.store & 0xff) == 0x2b) { direction = -1; } + else if ((Rotary.store & 0xff) == 0x17) { direction = 1; } + if ((0 == Rotary.direction) || (direction == Rotary.direction)) { + Rotary.position += direction; + Rotary.direction = direction; + } + } +#endif // ROTARY_OPTION2 + +#ifdef ROTARY_OPTION3 + // Theo Arends + uint32_t time = micros(); + if (Rotary.debounce < time) { + int direction = (digitalRead(Pin(GPIO_ROT1B))) ? 1 : -1; + if ((0 == Rotary.direction) || (direction == Rotary.direction)) { + Rotary.position += direction; + Rotary.direction = direction; + } + Rotary.debounce = time +20; // Experimental debounce + } +#endif // ROTARY_OPTION3 } bool RotaryButtonPressed(void) { - if (Rotary.changed && LightPower()) { - Rotary.changed = 0; // Color temp changed, no need to turn of the light + bool powered_on = (power); +#ifdef USE_LIGHT + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + powered_on = LightPower(); + } +#endif // USE_LIGHT + if (Rotary.changed && powered_on) { + Rotary.changed = false; // Color (temp) changed, no need to turn of the light return true; } return false; @@ -116,9 +231,13 @@ void RotaryInit(void) { if (PinUsed(GPIO_ROT1A) && PinUsed(GPIO_ROT1B)) { Rotary.present++; pinMode(Pin(GPIO_ROT1A), INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(Pin(GPIO_ROT1A)), update_rotary, CHANGE); pinMode(Pin(GPIO_ROT1B), INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(Pin(GPIO_ROT1B)), update_rotary, CHANGE); +#ifdef ROTARY_OPTION3 + attachInterrupt(Pin(GPIO_ROT1A), update_rotary, RISING); +#else + attachInterrupt(Pin(GPIO_ROT1A), update_rotary, CHANGE); + attachInterrupt(Pin(GPIO_ROT1B), update_rotary, CHANGE); +#endif } } @@ -127,31 +246,56 @@ void RotaryInit(void) { \*********************************************************************************************/ void RotaryHandler(void) { + if (Rotary.timeout) { + Rotary.timeout--; + if (!Rotary.timeout) { + Rotary.direction = 0; + } + } if (Rotary.last_position == Rotary.position) { return; } - Rotary.busy = true; - int8_t rotary_position = Rotary.position - Rotary.last_position; - Rotary.last_position = 128; - Rotary.position = 128; + Rotary.timeout = ROTARY_TIMEOUT; // Prevent fast direction changes within 0.5 second + + int rotary_position = Rotary.position - Rotary.last_position; if (Settings.save_data && (save_data_counter < 2)) { - save_data_counter = 2; // Postpone flash writes while rotary is turned + save_data_counter = 2; // Postpone flash writes while rotary is turned } - if (Button.hold_timer[0]) { // Button1 is pressed: set color temperature - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: CT/Color position %d"), rotary_position); - Rotary.changed = 1; - if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { // Ct 153..500 = (500 - 153) / 8 = 43 steps - LightColorOffset(rotary_position * rotary_color_increment); // Hue 0..359 = 360 / 8 = 45 steps + bool button_pressed = (Button.hold_timer[0]); // Button1 is pressed: set color temperature + if (button_pressed) { Rotary.changed = true; } +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Button1 %d, Position %d"), button_pressed, rotary_position); + +#ifdef USE_LIGHT + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + if (button_pressed) { + if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { + LightColorOffset(rotary_position * rotary_color_increment); + } + } else { + LightDimmerOffset(rotary_position * rotary_dimmer_increment); } } else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Dimmer position %d"), rotary_position); - LightDimmerOffset(rotary_position * rotary_dimmer_increment); // Dimmer 1..100 = 100 / 2 = 50 steps +#endif // USE_LIGHT + if (button_pressed) { + Rotary.abs_position2 += rotary_position; + if (Rotary.abs_position2 < 0) { Rotary.abs_position2 = 0; } + if (Rotary.abs_position2 > ROTARY_MAX_STEPS) { Rotary.abs_position2 = ROTARY_MAX_STEPS; } + } else { + Rotary.abs_position1 += rotary_position; + if (Rotary.abs_position1 < 0) { Rotary.abs_position1 = 0; } + if (Rotary.abs_position1 > ROTARY_MAX_STEPS) { Rotary.abs_position1 = ROTARY_MAX_STEPS; } + } + Response_P(PSTR("{\"Rotary1\":{\"Pos1\":%d,\"Pos2\":%d}}"), Rotary.abs_position1, Rotary.abs_position2); + XdrvRulesProcess(); +#ifdef USE_LIGHT } +#endif // USE_LIGHT + Rotary.last_position = 128; + Rotary.position = 128; Rotary.busy = false; } #endif // ROTARY_V1 -#endif // USE_LIGHT diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index b89c63a48..c677d4e57 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -372,11 +372,9 @@ void loop(void) { if (TimeReached(state_50msecond)) { SetNextTimeInterval(state_50msecond, 50); -#ifdef USE_LIGHT #ifdef ROTARY_V1 RotaryHandler(); #endif // ROTARY_V1 -#endif // USE_LIGHT XdrvCall(FUNC_EVERY_50_MSECOND); XsnsCall(FUNC_EVERY_50_MSECOND); } From 8bfd7533340ff18fee40de068b4be8ed4c6c18c9 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 2 Jul 2020 22:56:37 +0200 Subject: [PATCH 395/581] Zigbee EZSP milestone 4 --- tasmota/my_user_config.h | 1 + tasmota/settings.h | 2 +- tasmota/xdrv_23_zigbee_7_statemachine.ino | 167 +++++++++++--- tasmota/xdrv_23_zigbee_8_parsers.ino | 258 ++++++++++++++++------ tasmota/xdrv_23_zigbee_9_serial.ino | 36 ++- tasmota/xdrv_23_zigbee_A_impl.ino | 22 +- 6 files changed, 382 insertions(+), 104 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index c073447fe..a097b6154 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -679,6 +679,7 @@ // if PANID == 0xFFFE, then the device will act as a Zigbee end-device (non-router), the parameters below are ignored #define USE_ZIGBEE_EXTPANID 0xCCCCCCCCCCCCCCCCL // arbitrary extended PAN ID #define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26) + #define USE_ZIGBEE_TXRADIO_DBM 20 // Tx Radio power in dBm (only for EZSP, EFR32 can go up to 20 dBm) #define USE_ZIGBEE_PRECFGKEY_L 0x0F0D0B0907050301L // note: changing requires to re-pair all devices #define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices diff --git a/tasmota/settings.h b/tasmota/settings.h index 7fd279ab6..d5baaed93 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -559,7 +559,7 @@ struct { uint64_t zb_precfgkey_h; // F28 uint16_t zb_pan_id; // F30 uint8_t zb_channel; // F32 - uint8_t zb_free_byte; // F33 + uint8_t zb_txradio_dbm; // F33 uint16_t pms_wake_interval; // F34 uint8_t config_version; // F36 uint8_t windmeter_pulses_x_rot; // F37 diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index dd09cd18b..bfc07793e 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -106,6 +106,7 @@ enum Zigbee_StateMachine_Instruction_Set { #define ZI_WAIT_RECV_FUNC(x, m, f) { .i = { ZGB_INSTR_WAIT_RECV_CALL, sizeof(m), (x)} }, { .p = (const void*)(m) }, { .p = (const void*)(f) }, // Labels used in the State Machine -- internal only +const uint8_t ZIGBEE_LABEL_RESTART = 1; // Restart the state_machine in a different mode const uint8_t ZIGBEE_LABEL_INIT_COORD = 10; // Start ZNP as coordinator const uint8_t ZIGBEE_LABEL_START_COORD = 11; // Start ZNP as coordinator const uint8_t ZIGBEE_LABEL_INIT_ROUTER = 12; // Init ZNP as router @@ -118,13 +119,16 @@ const uint8_t ZIGBEE_LABEL_BOOT_TIME_OUT = 18; // MCU has not rebooted const uint8_t ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST = 19; // common post configuration for router and device const uint8_t ZIGBEE_LABEL_READY = 20; // goto label 20 for main loop const uint8_t ZIGBEE_LABEL_MAIN_LOOP = 21; // main loop +const uint8_t ZIGBEE_LABEL_NETWORK_CONFIGURED = 22; // main loop +const uint8_t ZIGBEE_LABEL_BAD_CONFIG = 23; // EZSP configuration is not the right one const uint8_t ZIGBEE_LABEL_PERMIT_JOIN_CLOSE = 30; // disable permit join const uint8_t ZIGBEE_LABEL_PERMIT_JOIN_OPEN_60 = 31; // enable permit join for 60 seconds const uint8_t ZIGBEE_LABEL_PERMIT_JOIN_OPEN_XX = 32; // enable permit join for 60 seconds -// factory reset +// factory reset or reconfiguration const uint8_t ZIGBEE_LABEL_FACT_RESET_COORD = 50; // main loop const uint8_t ZIGBEE_LABEL_FACT_RESET_ROUTER = 51; // main loop const uint8_t ZIGBEE_LABEL_FACT_RESET_DEVICE = 52; // main loop +const uint8_t ZIGBEE_LABEL_CONFIGURE_EZSP = 53; // main loop // errors const uint8_t ZIGBEE_LABEL_ABORT = 99; // goto label 99 in case of fatal error const uint8_t ZIGBEE_LABEL_UNSUPPORTED_VERSION = 98; // Unsupported ZNP version @@ -371,7 +375,7 @@ ZBM(ZBR_PERMITJOINREQ, Z_SRSP | Z_ZDO, ZDO_MGMT_PERMIT_JOIN_REQ, Z_SUCCESS) / ZBM(ZBR_PERMITJOIN_AREQ_RSP, Z_AREQ | Z_ZDO, ZDO_MGMT_PERMIT_JOIN_RSP, 0x00, 0x00 /* srcAddr*/, Z_SUCCESS ) // 45B6000000 // Update the relevant commands with Settings -void Z_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h) { +void ZNP_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h) { uint32_t zb_channel_mask = (1 << zb_channel); ZBW(ZBR_PAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PANID, 0x02 /* len */, @@ -422,26 +426,26 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_NOOP() ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) - ZI_ON_RECV_UNEXPECTED(&Z_Recv_Default) + ZI_ON_RECV_UNEXPECTED(&ZNP_Recv_Default) ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize //ZI_MQTT_STATE(ZIGBEE_STATUS_BOOT, "Booting") //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting device") ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_BOOT_TIME_OUT) // give a second chance ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 - ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &Z_Reboot) // timeout 5s + ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &ZNP_Reboot) // timeout 5s ZI_GOTO(ZIGBEE_LABEL_BOOT_OK) ZI_LABEL(ZIGBEE_LABEL_BOOT_TIME_OUT) ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 - ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &Z_Reboot) // timeout 5s + ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &ZNP_Reboot) // timeout 5s ZI_LABEL(ZIGBEE_LABEL_BOOT_OK) ZI_WAIT(100) ZI_LOG(LOG_LEVEL_DEBUG, kCheckingDeviceConfiguration) // Log Debug: checking device configuration ZI_SEND(ZBS_VERSION) // check ZNP software version - ZI_WAIT_RECV_FUNC(2000, ZBR_VERSION, &Z_ReceiveCheckVersion) // Check if version is valid + ZI_WAIT_RECV_FUNC(2000, ZBR_VERSION, &ZNP_ReceiveCheckVersion) // Check if version is valid // Dispatching whether coordinator, router or end-device ZI_CALL(&Z_SwitchDeviceType, 0) // goto ZIGBEE_LABEL_INIT_ROUTER, ZIGBEE_LABEL_INIT_DEVICE or continue if coordinator @@ -476,9 +480,9 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "starting zigbee coordinator") ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator ZI_WAIT_RECV(2000, ZBR_STARTUPFROMAPP) // wait for sync ack of command - ZI_WAIT_UNTIL_FUNC(10000, AREQ_STARTUPFROMAPP, &Z_ReceiveStateChange) // wait for async message that coordinator started + ZI_WAIT_UNTIL_FUNC(10000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started ZI_SEND(ZBS_GETDEVICEINFO) // GetDeviceInfo - ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &Z_ReceiveDeviceInfo) + ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &ZNP_ReceiveDeviceInfo) //ZI_WAIT_RECV(2000, ZBR_GETDEVICEINFO) // memorize info ZI_SEND(ZBS_ZDO_NODEDESCREQ) // Z_ZDO:nodeDescReq ZI_WAIT_RECV(1000, ZBR_ZDO_NODEDESCREQ) @@ -537,7 +541,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_WAIT_RECV(1000, ZBR_W_OK) // Now mark the device as ready, writing 0x55 in memory slot 0x0F00 ZI_SEND(ZBS_WNV_INITZNPHC) // Init NV ZNP Has Configured - ZI_WAIT_RECV_FUNC(1000, ZBR_WNV_INIT_OK, &Z_CheckNVWrite) + ZI_WAIT_RECV_FUNC(1000, ZBR_WNV_INIT_OK, &ZNP_CheckNVWrite) ZI_SEND(ZBS_WNV_ZNPHC) // Write NV ZNP Has Configured ZI_WAIT_RECV(1000, ZBR_WNV_OK) @@ -563,9 +567,9 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_WAIT_RECV(1000, ZBR_AF_REGISTER) ZI_SEND(ZBS_STARTUPFROMAPP) // start router ZI_WAIT_RECV(2000, ZBR_STARTUPFROMAPP) // wait for sync ack of command - ZI_WAIT_UNTIL_FUNC(0xFFFF, AREQ_STARTUPFROMAPP, &Z_ReceiveStateChange) // wait for async message that coordinator started + ZI_WAIT_UNTIL_FUNC(0xFFFF, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started ZI_SEND(ZBS_GETDEVICEINFO) // GetDeviceInfo - ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &Z_ReceiveDeviceInfo) + ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &ZNP_ReceiveDeviceInfo) ZI_GOTO(ZIGBEE_LABEL_READY) ZI_LABEL(ZIGBEE_LABEL_FACT_RESET_ROUTER) // Factory reset for router @@ -585,7 +589,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { // Now mark the device as ready, writing 0x55 in memory slot 0x0F00 ZI_SEND(ZBS_WNV_INITZNPHC) // Init NV ZNP Has Configured - ZI_WAIT_RECV_FUNC(1000, ZBR_WNV_INIT_OK, &Z_CheckNVWrite) + ZI_WAIT_RECV_FUNC(1000, ZBR_WNV_INIT_OK, &ZNP_CheckNVWrite) ZI_SEND(ZBS_WNV_ZNPHC) // Write NV ZNP Has Configured ZI_WAIT_RECV(1000, ZBR_WNV_OK) @@ -632,11 +636,6 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { #ifdef USE_ZIGBEE_EZSP -// Update the relevant commands with Settings -void Z_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h) { -} - - // patterns for EZSP // wait for RSTACK, meaning the device booted @@ -666,8 +665,8 @@ ZBM(ZBR_SET_OK, EZSP_setConfigurationValue, 0x00 /*high*/, 0x00 /*ok*/) // 53 ZBM(ZBR_SET_OK2, 0x00, 0x00 /*high*/, 0x00 /*ok*/) // 000000 - TODO why does setting EZSP_CONFIG_PACKET_BUFFER_COUNT has a different response? // Read some configuration values -ZBM(ZBS_GET_APS_UNI, EZSP_getConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_APS_UNICAST_MESSAGE_COUNT) // 520003 -ZBM(ZBR_GET_OK, EZSP_getConfigurationValue, 0x00 /*high*/, 0x00 /*ok*/) // 5200 - followed by the value +// ZBM(ZBS_GET_APS_UNI, EZSP_getConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_APS_UNICAST_MESSAGE_COUNT) // 520003 +// ZBM(ZBR_GET_OK, EZSP_getConfigurationValue, 0x00 /*high*/, 0x00 /*ok*/) // 5200 - followed by the value // Add Endpoints ZBM(ZBS_ADD_ENDPOINT1, EZSP_addEndpoint, 0x00 /*high*/, 0x01 /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), @@ -697,7 +696,7 @@ ZBM(ZBR_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*ok*/) // setInitialSecurityState #define EZ_SECURITY_MODE EMBER_TRUST_CENTER_GLOBAL_LINK_KEY | EMBER_PRECONFIGURED_NETWORK_KEY_MODE | EMBER_HAVE_NETWORK_KEY | EMBER_HAVE_PRECONFIGURED_KEY -ZBM(ZBS_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, +ZBR(ZBS_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, Z_B0(EZ_SECURITY_MODE), Z_B1(EZ_SECURITY_MODE), // preConfiguredKey 0x5A, 0x69, 0x67, 0x42, 0x65, 0x65, 0x41, 0x6C, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x30, 0x39, // well known key "ZigBeeAlliance09" @@ -715,7 +714,7 @@ ZBM(ZBR_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, 0x00 /*st ZBM(ZBS_SET_POLICY_00, EZSP_setPolicy, 0x00 /*high*/, EZSP_TRUST_CENTER_POLICY, EZSP_DECISION_ALLOW_JOINS | EZSP_DECISION_ALLOW_UNSECURED_REJOINS) // 55000003 ZBM(ZBS_SET_POLICY_02, EZSP_setPolicy, 0x00 /*high*/, EZSP_UNICAST_REPLIES_POLICY, - EZSP_HOST_WILL_NOT_SUPPLY_REPLY) // 550002210 + EZSP_HOST_WILL_NOT_SUPPLY_REPLY) // 55000220 ZBM(ZBS_SET_POLICY_03, EZSP_setPolicy, 0x00 /*high*/, EZSP_POLL_HANDLER_POLICY, EZSP_POLL_HANDLER_IGNORE) // 55000330 ZBM(ZBS_SET_POLICY_05, EZSP_setPolicy, 0x00 /*high*/, EZSP_TC_KEY_REQUEST_POLICY, @@ -724,12 +723,16 @@ ZBM(ZBS_SET_POLICY_06, EZSP_setPolicy, 0x00 /*high*/, EZSP_APP_KEY_REQUEST_PO EZSP_DENY_APP_KEY_REQUESTS) // 55000660 ZBM(ZBR_SET_POLICY_XX, EZSP_setPolicy, 0x00 /*high*/, 0x00 /*status*/) +// networkInit - restart the network from previous settings +ZBM(ZBS_NETWORK_INIT, EZSP_networkInit, 0x00 /*high*/, 0x00, 0x00) // 17000000 +ZBM(ZBR_NETWORK_INIT, EZSP_networkInit, 0x00 /*high*/, 0x00 /*status*/) // 170000 + // formNetwork - i.e. start zigbee network as coordinator -ZBM(ZBS_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, +ZBR(ZBS_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID), Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID), - 20 /*radioTxPower*/, + USE_ZIGBEE_TXRADIO_DBM /*radioTxPower*/, USE_ZIGBEE_CHANNEL /*channel*/, EMBER_USE_MAC_ASSOCIATION, 0xFF,0xFF, /*nwkManagerId, unused*/ @@ -739,34 +742,103 @@ ZBM(ZBS_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, ZBM(ZBR_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, 0x00 /*status*/) // 1E0000 ZBM(ZBR_NETWORK_UP, EZSP_stackStatusHandler, 0x00 /*high*/, EMBER_NETWORK_UP) // 190090 +// leaveNetwork +ZBR(ZBS_LEAVE_NETWORK, EZSP_leaveNetwork, 0x00 /*high*/) // 2000 +ZBM(ZBR_LEAVE_NETWORK, EZSP_leaveNetwork, 0x00 /*high*/) // 2000, we don't care whether it succeeeded or the network was not up + // read configuration details ZBM(ZBS_GET_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/) // 2800 ZBM(ZBR_GET_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/, 0x00 /*ok*/) // 2800 +ZBR(ZBR_CHECK_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/, + 0x00 /*status*/, + EMBER_COORDINATOR /*0x01*/, + Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), + Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID), + Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID), + USE_ZIGBEE_TXRADIO_DBM /*radioTxPower*/, + USE_ZIGBEE_CHANNEL /*channel*/, + ) // 2800... + ZBM(ZBS_GET_EUI64, EZSP_getEui64, 0x00 /*high*/) // 2600 ZBM(ZBR_GET_EUI64, EZSP_getEui64, 0x00 /*high*/) // 2600 ZBM(ZBS_GET_NODEID, EZSP_getNodeId, 0x00 /*high*/) // 2700 ZBM(ZBR_GET_NODEID, EZSP_getNodeId, 0x00 /*high*/) // 2700 +// getCurrentSecurityState +// TODO double check the security bitmask +ZBM(ZBS_GET_CURR_SEC, EZSP_getCurrentSecurityState, 0x00 /*high*/) // 6900 +ZBR(ZBR_GET_CURR_SEC, EZSP_getCurrentSecurityState, 0x00 /*high*/, + 0x00 /*status*/, + 0x7C, 0x00 /*Current Security Bitmask*/, + ) // 6900... + +/*********************************************************************************************\ + * Update the relevant commands with Settings +\*********************************************************************************************/ +// +void EZ_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h, uint8_t zb_txradio_dbm) { + uint8_t txradio = zb_txradio_dbm; + // restrict txradio to acceptable range, and use default otherwise + if (txradio == 0) { txradio = USE_ZIGBEE_TXRADIO_DBM; } + if (txradio > 20) { txradio = USE_ZIGBEE_TXRADIO_DBM; } + + ZBW(ZBS_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, + Z_B0(EZ_SECURITY_MODE), Z_B1(EZ_SECURITY_MODE), + // preConfiguredKey + 0x5A, 0x69, 0x67, 0x42, 0x65, 0x65, 0x41, 0x6C, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x30, 0x39, // well known key "ZigBeeAlliance09" + // networkKey + Z_B0(zb_precfgkey_l), Z_B1(zb_precfgkey_l), Z_B2(zb_precfgkey_l), Z_B3(zb_precfgkey_l), + Z_B4(zb_precfgkey_l), Z_B5(zb_precfgkey_l), Z_B6(zb_precfgkey_l), Z_B7(zb_precfgkey_l), + Z_B0(zb_precfgkey_h), Z_B1(zb_precfgkey_h), Z_B2(zb_precfgkey_h), Z_B3(zb_precfgkey_h), + Z_B4(zb_precfgkey_h), Z_B5(zb_precfgkey_h), Z_B6(zb_precfgkey_h), Z_B7(zb_precfgkey_h), + 0x00 /*sequence*/, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*trustcenter*/ + ) + + ZBW(ZBS_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, + Z_B0(zb_ext_panid), Z_B1(zb_ext_panid), Z_B2(zb_ext_panid), Z_B3(zb_ext_panid), + Z_B4(zb_ext_panid), Z_B5(zb_ext_panid), Z_B6(zb_ext_panid), Z_B7(zb_ext_panid), + Z_B0(zb_pan_id), Z_B1(zb_pan_id), + txradio /*radioTxPower*/, + zb_channel /*channel*/, + EMBER_USE_MAC_ASSOCIATION, + 0xFF,0xFF, /*nwkManagerId, unused*/ + 0x00, /*nwkUpdateId, unused*/ + 0x00,0x00,0x00,0x00, /*NWK channel mask, unused*/ + ) // 1E00... + +ZBW(ZBR_CHECK_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/, + 0x00 /*status*/, + EMBER_COORDINATOR /*0x01*/, + Z_B0(zb_ext_panid), Z_B1(zb_ext_panid), Z_B2(zb_ext_panid), Z_B3(zb_ext_panid), + Z_B4(zb_ext_panid), Z_B5(zb_ext_panid), Z_B6(zb_ext_panid), Z_B7(zb_ext_panid), + Z_B0(zb_pan_id), Z_B1(zb_pan_id), + txradio /*radioTxPower*/, + zb_channel /*channel*/, + ) // 2800... +} static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_LABEL(0) ZI_NOOP() + ZI_CALL(EZ_Set_ResetConfig, 0) // for the firt pass, don't do a reset_config + ZI_LABEL(ZIGBEE_LABEL_RESTART) ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) - ZI_ON_RECV_UNEXPECTED(&Z_Recv_Default) + ZI_ON_RECV_UNEXPECTED(&EZ_Recv_Default) ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize // Hardware reset ZI_LOG(LOG_LEVEL_INFO, kResettingDevice) // Log Debug: resetting EZSP device - ZI_CALL(&Z_Reset_Device, 0) // LOW = reset + ZI_CALL(&EZ_Reset_Device, 0) // LOW = reset ZI_WAIT(100) // wait for .1 second - ZI_CALL(&Z_Reset_Device, 1) // HIGH = release reset + ZI_CALL(&EZ_Reset_Device, 1) // HIGH = release reset // wait for device to start ZI_WAIT_UNTIL(5000, ZBR_RSTACK) // wait for RSTACK message // Init device and probe version - ZI_SEND(ZBS_VERSION) ZI_WAIT_RECV_FUNC(1000, ZBR_VERSION, &Z_ReceiveCheckVersion) // check EXT PAN ID + ZI_SEND(ZBS_VERSION) ZI_WAIT_RECV_FUNC(1000, ZBR_VERSION, &EZ_ReceiveCheckVersion) // check EXT PAN ID // configure EFR32 ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredCoord) @@ -786,7 +858,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { // read configuration // TODO - not sure it's useful - //ZI_SEND(ZBS_GET_APS_UNI) ZI_WAIT_RECV_FUNC(500, ZBR_GET_OK, &Z_ReadAPSUnicastMessage) + //ZI_SEND(ZBS_GET_APS_UNI) ZI_WAIT_RECV_FUNC(500, ZBR_GET_OK, &EZ_ReadAPSUnicastMessage) // add endpoint 0x01 and 0x0B ZI_SEND(ZBS_ADD_ENDPOINT1) ZI_WAIT_RECV(500, ZBR_ADD_ENDPOINT) @@ -796,21 +868,52 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_SEND(ZBS_SET_CONCENTRATOR) ZI_WAIT_RECV(500, ZBR_SET_CONCENTRATOR) // setInitialSecurityState - ZI_SEND(ZBS_SET_SECURITY) ZI_WAIT_RECV(500, ZBR_SET_SECURITY) ZI_SEND(ZBS_SET_POLICY_00) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) ZI_SEND(ZBS_SET_POLICY_02) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) ZI_SEND(ZBS_SET_POLICY_03) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) ZI_SEND(ZBS_SET_POLICY_05) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) ZI_SEND(ZBS_SET_POLICY_06) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + // set encryption keys + ZI_SEND(ZBS_SET_SECURITY) ZI_WAIT_RECV(500, ZBR_SET_SECURITY) + + // Decide whether we try 'networkInit()' to restore configuration, or create a new network + ZI_CALL(&EZ_GotoIfResetConfig, ZIGBEE_LABEL_CONFIGURE_EZSP) // goto ZIGBEE_LABEL_CONFIGURE_EZSP if reset_config is set + + // ZI_GOTO(ZIGBEE_LABEL_CONFIGURE_EZSP) + + // // Try networkInit to restore settings, and check if network comes up + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_BAD_CONFIG) // + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_BAD_CONFIG) + ZI_SEND(ZBS_NETWORK_INIT) ZI_WAIT_RECV(500, ZBR_NETWORK_INIT) + ZI_WAIT_RECV(1500, ZBR_NETWORK_UP) // wait for network to start + // check if configuration is ok + ZI_SEND(ZBS_GET_CURR_SEC) ZI_WAIT_RECV(500, ZBR_GET_CURR_SEC) + ZI_SEND(ZBS_GET_NETW_PARM) ZI_WAIT_RECV(500, ZBR_CHECK_NETW_PARM) + // all ok, proceed to next step + ZI_GOTO(ZIGBEE_LABEL_NETWORK_CONFIGURED) + + ZI_LABEL(ZIGBEE_LABEL_BAD_CONFIG) + ZI_MQTT_STATE(ZIGBEE_STATUS_RESET_CONF, kResetting) + ZI_CALL(EZ_Set_ResetConfig, 1) // change mode to reset_config + ZI_GOTO(ZIGBEE_LABEL_RESTART) // restart state_machine + + ZI_LABEL(ZIGBEE_LABEL_CONFIGURE_EZSP) + // Set back normal error handlers + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) // formNetwork ZI_SEND(ZBS_FORM_NETWORK) ZI_WAIT_RECV(500, ZBR_FORM_NETWORK) ZI_WAIT_RECV(5000, ZBR_NETWORK_UP) // wait for network to start + ZI_LABEL(ZIGBEE_LABEL_NETWORK_CONFIGURED) + // Set back normal error handlers + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) // Query device information - ZI_SEND(ZBS_GET_EUI64) ZI_WAIT_RECV_FUNC(500, ZBR_GET_EUI64, &Z_EZSPGetEUI64) - ZI_SEND(ZBS_GET_NODEID) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NODEID, &Z_EZSPGetNodeId) - ZI_SEND(ZBS_GET_NETW_PARM) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NETW_PARM, &Z_EZSPNetworkParameters) + ZI_SEND(ZBS_GET_EUI64) ZI_WAIT_RECV_FUNC(500, ZBR_GET_EUI64, &EZ_GetEUI64) + ZI_SEND(ZBS_GET_NODEID) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NODEID, &EZ_GetNodeId) + ZI_SEND(ZBS_GET_NETW_PARM) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NETW_PARM, &EZ_NetworkParameters) ZI_LABEL(ZIGBEE_LABEL_READY) ZI_MQTT_STATE(ZIGBEE_STATUS_OK, kStarted) diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 870caaa7d..57313f687 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -24,8 +24,8 @@ * Parsers for incoming EZSP messages \*********************************************************************************************/ -// EZSP: received ASH RSTACK frame, indicating that the MCU finished boot -int32_t Z_EZSP_RSTACK(uint8_t reset_code) { +// EZSP: received ASH "RSTACK" frame, indicating that the MCU finished boot +int32_t EZ_RSTACK(uint8_t reset_code) { const char *reason_str; switch (reset_code) { @@ -47,8 +47,8 @@ int32_t Z_EZSP_RSTACK(uint8_t reset_code) { XdrvRulesProcess(); } -// EZSP: received ASH ERROR frame, indicating that the MCU finished boot -int32_t Z_EZSP_ERROR(uint8_t error_code) { +// EZSP: received ASH "ERROR" frame, indicating that the MCU finished boot +int32_t EZ_ERROR(uint8_t error_code) { const char *reason_str; switch (error_code) { @@ -64,13 +64,59 @@ int32_t Z_EZSP_ERROR(uint8_t error_code) { XdrvRulesProcess(); } -int32_t Z_ReadAPSUnicastMessage(int32_t res, class SBuffer &buf) { +int32_t EZ_ReadAPSUnicastMessage(int32_t res, class SBuffer &buf) { // Called when receiving a response from getConfigurationValue // Value is in bytes 2+3 uint16_t value = buf.get16(2); return res; } +/*********************************************************************************************\ + * Parsers for incoming EZSP messages +\*********************************************************************************************/ + +// +// Handle a "getEui64" incoming message +// +int32_t EZ_GetEUI64(int32_t res, class SBuffer &buf) { + localIEEEAddr = buf.get64(2); + return res; +} + +// +// Handle a "getEui64" incoming message +// +int32_t EZ_GetNodeId(int32_t res, class SBuffer &buf) { + localShortAddr = buf.get8(2); + return res; +} + +// +// Handle a "getNetworkParameters" incoming message +// +int32_t EZ_NetworkParameters(int32_t res, class SBuffer &buf) { + uint8_t node_type = buf.get8(3); + // ext panid: 4->11 + // panid: 12->13 + // radioTxPower: 14 + // radioChannel: 15 + + // Local short and long addresses are supposed to be already retrieved + // localIEEEAddr = long_adr; + // localShortAddr = short_adr; + + char hex[20]; + Uint64toHex(localIEEEAddr, hex, 64); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"IEEEAddr\":\"0x%s\",\"ShortAddr\":\"0x%04X\"" + ",\"DeviceType\":%d}}"), + ZIGBEE_STATUS_EZ_INFO, hex, localShortAddr, node_type); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); + + return res; +} #endif // USE_ZIGBEE_EZSP @@ -128,7 +174,7 @@ int32_t Z_EZSPNetworkParameters(int32_t res, class SBuffer &buf) { // // Handle a "Receive Device Info" incoming message // -int32_t Z_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { +int32_t ZNP_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { // Ex= 6700.00.6263151D004B1200.0000.07.09.02.83869991 // IEEE Adr (8 bytes) = 0x00124B001D156362 // Short Addr (2 bytes) = 0x0000 @@ -174,7 +220,7 @@ int32_t Z_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { return res; } -int32_t Z_CheckNVWrite(int32_t res, class SBuffer &buf) { +int32_t ZNP_CheckNVWrite(int32_t res, class SBuffer &buf) { // Check the status after NV Init "ZNP Has Configured" // Good response should be 610700 or 610709 (Success or Created) // We only filter the response on 6107 and check the code in this function @@ -186,7 +232,7 @@ int32_t Z_CheckNVWrite(int32_t res, class SBuffer &buf) { } } -int32_t Z_Reboot(int32_t res, class SBuffer &buf) { +int32_t ZNP_Reboot(int32_t res, class SBuffer &buf) { // print information about the reboot of device // 4180.02.02.00.02.06.03 // @@ -221,8 +267,8 @@ int32_t Z_Reboot(int32_t res, class SBuffer &buf) { } } -int32_t Z_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { #ifdef USE_ZIGBEE_ZNP +int32_t ZNP_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { // check that the version is supported // typical version for ZNP 1.2 // 61020200-02.06.03.D9143401.0200000000 @@ -251,9 +297,11 @@ int32_t Z_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { } else { return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort } +} #endif // USE_ZIGBEE_ZNP #ifdef USE_ZIGBEE_EZSP +int32_t EZ_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { uint8_t protocol_version = buf.get8(2); uint8_t stack_type = buf.get8(3); uint16_t stack_version = buf.get16(4); @@ -278,9 +326,25 @@ int32_t Z_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { } else { return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort } -#endif // USE_ZIGBEE_EZSP } +static bool EZ_reset_config = false; + +// Set or clear reset_config +int32_t EZ_Set_ResetConfig(uint8_t value) { + EZ_reset_config = value ? true : false; + return 0; +} +// checks if we need to reset the configuration of the device +// if reset_config == 0, continue +// if reset_config == 1, goto ZIGBEE_LABEL_CONFIGURE_EZSP +int32_t EZ_GotoIfResetConfig(uint8_t value) { + if (EZ_reset_config) { return ZIGBEE_LABEL_CONFIGURE_EZSP; } + else { return 0; } +} + +#endif // USE_ZIGBEE_EZSP + // checks the device type (coordinator, router, end-device) // If coordinator continue // If router goto ZIGBEE_LABEL_START_ROUTER @@ -308,7 +372,7 @@ bool Z_ReceiveMatchPrefix(const class SBuffer &buf, const uint8_t *match) { // // Handle Permit Join response // -int32_t Z_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) { +int32_t ZNP_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) { // we received a PermitJoin status change uint8_t duration = buf.get8(2); uint8_t status_code; @@ -335,7 +399,10 @@ int32_t Z_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) { return -1; } -int32_t Z_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) { +// +// ZNP only +// +int32_t ZNP_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) { // Received ZDO_NODE_DESC_RSP Z_ShortAddress srcAddr = buf.get16(2); uint8_t status = buf.get8(4); @@ -380,11 +447,19 @@ int32_t Z_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) { // int32_t Z_ReceiveActiveEp(int32_t res, const class SBuffer &buf) { // Received ZDO_ACTIVE_EP_RSP - Z_ShortAddress srcAddr = buf.get16(2); +#ifdef USE_ZIGBEE_ZNP + // Z_ShortAddress srcAddr = buf.get16(2); uint8_t status = buf.get8(4); Z_ShortAddress nwkAddr = buf.get16(5); uint8_t activeEpCount = buf.get8(7); uint8_t* activeEpList = (uint8_t*) buf.charptr(8); +#endif +#ifdef USE_ZIGBEE_EZSP + uint8_t status = buf.get8(0); + Z_ShortAddress nwkAddr = buf.get16(1); + uint8_t activeEpCount = buf.get8(3); + uint8_t* activeEpList = (uint8_t*) buf.charptr(4); +#endif for (uint32_t i = 0; i < activeEpCount; i++) { zigbee_devices.addEndpoint(nwkAddr, activeEpList[i]); @@ -409,12 +484,22 @@ int32_t Z_ReceiveActiveEp(int32_t res, const class SBuffer &buf) { // // Handle IEEEAddr incoming message // +// Same works for both ZNP and EZSP int32_t Z_ReceiveIEEEAddr(int32_t res, const class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP uint8_t status = buf.get8(2); Z_IEEEAddress ieeeAddr = buf.get64(3); Z_ShortAddress nwkAddr = buf.get16(11); // uint8_t startIndex = buf.get8(13); // not used // uint8_t numAssocDev = buf.get8(14); +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + uint8_t status = buf.get8(0); + Z_IEEEAddress ieeeAddr = buf.get64(1); + Z_ShortAddress nwkAddr = buf.get16(9); + // uint8_t numAssocDev = buf.get8(11); + // uint8_t startIndex = buf.get8(12); // not used +#endif // USE_ZIGBEE_EZSP if (0 == status) { // SUCCESS zigbee_devices.updateDevice(nwkAddr, ieeeAddr); @@ -439,7 +524,7 @@ int32_t Z_ReceiveIEEEAddr(int32_t res, const class SBuffer &buf) { // Report any AF_DATA_CONFIRM message // Ex: {"ZbConfirm":{"Endpoint":1,"Status":0,"StatusMessage":"SUCCESS"}} // -int32_t Z_DataConfirm(int32_t res, const class SBuffer &buf) { +int32_t ZNP_DataConfirm(int32_t res, const class SBuffer &buf) { uint8_t status = buf.get8(2); uint8_t endpoint = buf.get8(3); //uint8_t transId = buf.get8(4); // unused @@ -471,7 +556,7 @@ int32_t Z_DataConfirm(int32_t res, const class SBuffer &buf) { // 0x08: Starting as ZigBee Coordinator // 0x09: Started as ZigBee Coordinator // 0x0A: Device has lost information about its parent -int32_t Z_ReceiveStateChange(int32_t res, const class SBuffer &buf) { +int32_t ZNP_ReceiveStateChange(int32_t res, const class SBuffer &buf) { uint8_t state = buf.get8(2); const char * msg = nullptr; @@ -531,9 +616,9 @@ int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) { #endif #ifdef USE_ZIGBEE_EZSP // uint8_t seq = buf.get8(0); - Z_ShortAddress nwkAddr = buf.get16(1); - Z_IEEEAddress ieeeAddr = buf.get64(3); - uint8_t capabilities = buf.get8(11); + Z_ShortAddress nwkAddr = buf.get16(0); + Z_IEEEAddress ieeeAddr = buf.get64(2); + uint8_t capabilities = buf.get8(10); #endif zigbee_devices.updateDevice(nwkAddr, ieeeAddr); @@ -562,7 +647,7 @@ int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) { // Handle Receive TC Dev Ind incoming message // 45CA // -int32_t Z_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) { +int32_t ZNP_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) { Z_ShortAddress srcAddr = buf.get16(2); Z_IEEEAddress ieeeAddr = buf.get64(4); Z_ShortAddress parentNw = buf.get16(12); @@ -585,7 +670,7 @@ int32_t Z_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) { // // Handle Bind Rsp incoming message // -int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) { +int32_t ZNP_BindRsp(int32_t res, const class SBuffer &buf) { Z_ShortAddress nwkAddr = buf.get16(2); uint8_t status = buf.get8(4); @@ -608,7 +693,7 @@ int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) { // // Handle Unbind Rsp incoming message // -int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) { +int32_t ZNP_UnbindRsp(int32_t res, const class SBuffer &buf) { Z_ShortAddress nwkAddr = buf.get16(2); uint8_t status = buf.get8(4); @@ -629,7 +714,7 @@ int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) { // // Handle MgMt Bind Rsp incoming message // -int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { +int32_t ZNP_MgmtBindRsp(int32_t res, const class SBuffer &buf) { uint16_t shortaddr = buf.get16(2); uint8_t status = buf.get8(4); uint8_t bind_total = buf.get8(5); @@ -667,7 +752,7 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { dstep = buf.get8(idx + 20); idx += 21; } else { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Z_MgmtBindRsp unknwon address mode %d"), addrmode); + //AddLog_P2(LOG_LEVEL_INFO, PSTR("ZNP_MgmtBindRsp unknwon address mode %d"), addrmode); break; // abort for any other value since we don't know the length of the field } @@ -705,6 +790,9 @@ void Z_SendIEEEAddrReq(uint16_t shortaddr) { ZigbeeZNPSend(IEEEAddrReq, sizeof(IEEEAddrReq)); #endif +#ifdef USE_ZIGBEE_EZSP + // TODO +#endif } // @@ -725,17 +813,15 @@ void Z_SendActiveEpReq(uint16_t shortaddr) { // Send AF Info Request // void Z_SendAFInfoRequest(uint16_t shortaddr) { -#ifdef USE_ZIGBEE_ZNP uint8_t endpoint = zigbee_devices.findFirstEndpoint(shortaddr); if (0x00 == endpoint) { endpoint = 0x01; } // if we don't know the endpoint, try 0x01 uint8_t transacid = zigbee_devices.getNextSeqNumber(shortaddr); - uint8_t AFInfoReq[] = { Z_SREQ | Z_AF, AF_DATA_REQUEST, Z_B0(shortaddr), Z_B1(shortaddr), endpoint, - 0x01, 0x00, 0x00, transacid, 0x30, 0x1E, 3 + 2*sizeof(uint16_t), - 0x00, transacid, ZCL_READ_ATTRIBUTES, 0x04, 0x00, 0x05, 0x00 - }; - ZigbeeZNPSend(AFInfoReq, sizeof(AFInfoReq)); -#endif + uint8_t InfoReq[] = { 0x04, 0x00, 0x05, 0x00 }; + + ZigbeeZCLSend_Raw(shortaddr, 0x0000 /*group*/, 0x0000 /*cluster*/, endpoint, ZCL_READ_ATTRIBUTES, + false /*clusterSpecific*/, 0x0000 /*manuf*/, + InfoReq, sizeof(InfoReq), true /*needResponse*/, transacid); } @@ -773,8 +859,9 @@ int32_t EZ_ReceiveTCJoinHandler(int32_t res, const class SBuffer &buf) { #endif // USE_ZIGBEE_EZSP // -// Parse incoming ZCL message. This code is common to ZNP and EZSP +// Parse incoming ZCL message. // +// This code is common to ZNP and EZSP void Z_IncomingMessage(ZCLFrame &zcl_received) { uint16_t srcaddr = zcl_received.getSrcAddr(); uint16_t groupid = zcl_received.getGroupAddr(); @@ -862,9 +949,11 @@ void Z_IncomingMessage(ZCLFrame &zcl_received) { \*********************************************************************************************/ void EZ_SendZDO(uint16_t shortaddr, uint16_t cmd, const unsigned char *payload, size_t payload_len) { - SBuffer buf(payload_len + 20); + SBuffer buf(payload_len + 22); uint8_t seq = zigbee_devices.getNextSeqNumber(0x0000); + buf.add16(EZSP_sendUnicast); + buf.add8(EMBER_OUTGOING_DIRECT); // 00 buf.add16(shortaddr); // dest addr // ApsFrame @@ -880,6 +969,8 @@ void EZ_SendZDO(uint16_t shortaddr, uint16_t cmd, const unsigned char *payload, buf.add8(payload_len + 1); // insert seq number buf.add8(seq); buf.addBuffer(payload, payload_len); + + ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true); } /*********************************************************************************************\ @@ -907,10 +998,17 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { if ((0x0000 == profileid) && (0x00 == srcendpoint)) { // ZDO request - SBuffer zdo_buf = buf.subBuffer(21, buf.get8(20)); + // Since ZDO messages start with a sequence number, we skip it + SBuffer zdo_buf = buf.subBuffer(22, buf.get8(20) - 1); switch (clusterid) { case ZDO_Device_annce: - Z_ReceiveEndDeviceAnnonce(res, zdo_buf); + return Z_ReceiveEndDeviceAnnonce(res, zdo_buf); + break; + case ZDO_Active_EP_rsp: + return Z_ReceiveActiveEp(res, zdo_buf); + break; + case ZDO_IEEE_addr_rsp: + return Z_ReceiveIEEEAddr(res, zdo_buf); break; } } else { @@ -928,7 +1026,7 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { // // Callback for loading Zigbee configuration from Flash, called by the state machine // -int32_t Z_Reset_Device(uint8_t value) { +int32_t EZ_Reset_Device(uint8_t value) { // TODO - GPIO is hardwired to GPIO4 digitalWrite(4, value ? HIGH : LOW); return 0; // continue @@ -938,13 +1036,15 @@ int32_t Z_Reset_Device(uint8_t value) { * Default resolver \*********************************************************************************************/ -int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { +int32_t EZ_Recv_Default(int32_t res, const class SBuffer &buf) { // Default message handler for new messages if (zigbee.init_phase) { // if still during initialization phase, ignore any unexpected message return -1; // ignore message } else { - switch (buf.get8(0)) { + uint16_t ezsp_command_index = buf.get16(0); + + switch (ezsp_command_index) { case EZSP_incomingMessageHandler: return EZ_IncomingMessage(res, buf); break; @@ -990,6 +1090,48 @@ int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu return 1; } +/*********************************************************************************************\ + * Global dispatcher for incoming messages +\*********************************************************************************************/ + +#ifdef USE_ZIGBEE_ZNP + +int32_t ZNP_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { + uint16_t groupid = buf.get16(2); + uint16_t clusterid = buf.get16(4); + uint16_t srcaddr = buf.get16(6); + uint8_t srcendpoint = buf.get8(8); + uint8_t dstendpoint = buf.get8(9); + uint8_t wasbroadcast = buf.get8(10); + uint8_t linkquality = buf.get8(11); + uint8_t securityuse = buf.get8(12); + // uint32_t timestamp = buf.get32(13); + uint8_t seqnumber = buf.get8(17); + + bool defer_attributes = false; // do we defer attributes reporting to coalesce + + ZCLFrame zcl_received = ZCLFrame::parseRawFrame(buf, 19, buf.get8(18), clusterid, groupid, + srcaddr, + srcendpoint, dstendpoint, wasbroadcast, + linkquality, securityuse, seqnumber); + // + Z_IncomingMessage(zcl_received); + + return -1; +} + +// +// Callback for loading Zigbee configuration from Flash, called by the state machine +// +int32_t Z_Reset_Device(uint8_t value) { + // TODO - GPIO is hardwired to GPIO4 + digitalWrite(4, value ? HIGH : LOW); + return 0; // continue +} + +#endif // USE_ZIGBEE_ZNP + + /*********************************************************************************************\ * Global dispatcher for incoming messages \*********************************************************************************************/ @@ -1022,45 +1164,31 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { // Structure for the Dispatcher callbacks table typedef struct Z_Dispatcher { - const uint8_t* match; + uint8_t match[2]; ZB_RecvMsgFunc func; } Z_Dispatcher; -// Ffilters based on ZNP frames -ZBM(AREQ_AF_DATA_CONFIRM, Z_AREQ | Z_AF, AF_DATA_CONFIRM) // 4480 -ZBM(AREQ_AF_INCOMING_MESSAGE, Z_AREQ | Z_AF, AF_INCOMING_MSG) // 4481 -// ZBM(AREQ_STATE_CHANGE_IND, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND) // 45C0 -ZBM(AREQ_END_DEVICE_ANNCE_IND, Z_AREQ | Z_ZDO, ZDO_END_DEVICE_ANNCE_IND) // 45C1 -ZBM(AREQ_END_DEVICE_TC_DEV_IND, Z_AREQ | Z_ZDO, ZDO_TC_DEV_IND) // 45CA -ZBM(AREQ_PERMITJOIN_OPEN_XX, Z_AREQ | Z_ZDO, ZDO_PERMIT_JOIN_IND ) // 45CB -ZBM(AREQ_ZDO_ACTIVEEPRSP, Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP) // 4585 -ZBM(AREQ_ZDO_SIMPLEDESCRSP, Z_AREQ | Z_ZDO, ZDO_SIMPLE_DESC_RSP) // 4584 -ZBM(AREQ_ZDO_IEEE_ADDR_RSP, Z_AREQ | Z_ZDO, ZDO_IEEE_ADDR_RSP) // 4581 -ZBM(AREQ_ZDO_BIND_RSP, Z_AREQ | Z_ZDO, ZDO_BIND_RSP) // 45A1 -ZBM(AREQ_ZDO_UNBIND_RSP, Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP) // 45A2 -ZBM(AREQ_ZDO_MGMT_BIND_RSP, Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP) // 45B3 - // Dispatcher callbacks table const Z_Dispatcher Z_DispatchTable[] PROGMEM = { - { AREQ_AF_DATA_CONFIRM, &Z_DataConfirm }, - { AREQ_AF_INCOMING_MESSAGE, &Z_ReceiveAfIncomingMessage }, - // { AREQ_STATE_CHANGE_IND, &Z_ReceiveStateChange }, - { AREQ_END_DEVICE_ANNCE_IND, &Z_ReceiveEndDeviceAnnonce }, - { AREQ_END_DEVICE_TC_DEV_IND, &Z_ReceiveTCDevInd }, - { AREQ_PERMITJOIN_OPEN_XX, &Z_ReceivePermitJoinStatus }, - { AREQ_ZDO_NODEDESCRSP, &Z_ReceiveNodeDesc }, - { AREQ_ZDO_ACTIVEEPRSP, &Z_ReceiveActiveEp }, - { AREQ_ZDO_IEEE_ADDR_RSP, &Z_ReceiveIEEEAddr }, - { AREQ_ZDO_BIND_RSP, &Z_BindRsp }, - { AREQ_ZDO_UNBIND_RSP, &Z_UnbindRsp }, - { AREQ_ZDO_MGMT_BIND_RSP, &Z_MgmtBindRsp }, + { { Z_AREQ | Z_AF, AF_DATA_CONFIRM }, &ZNP_DataConfirm }, // 4480 + { { Z_AREQ | Z_AF, AF_INCOMING_MSG }, &ZNP_ReceiveAfIncomingMessage }, // 4481 + // { { Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND }, &ZNP_ReceiveStateChange }, // 45C0 + { { Z_AREQ | Z_ZDO, ZDO_END_DEVICE_ANNCE_IND }, &Z_ReceiveEndDeviceAnnonce }, // 45C1 + { { Z_AREQ | Z_ZDO, ZDO_TC_DEV_IND }, &ZNP_ReceiveTCDevInd }, // 45CA + { { Z_AREQ | Z_ZDO, ZDO_PERMIT_JOIN_IND }, &ZNP_ReceivePermitJoinStatus }, // 45CB + { { Z_AREQ | Z_ZDO, ZDO_NODE_DESC_RSP }, &ZNP_ReceiveNodeDesc }, // 4582 + { { Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP }, &Z_ReceiveActiveEp }, // 4585 + { { Z_AREQ | Z_ZDO, ZDO_IEEE_ADDR_RSP }, &Z_ReceiveIEEEAddr }, // 4581 + { { Z_AREQ | Z_ZDO, ZDO_BIND_RSP }, &ZNP_BindRsp }, // 45A1 + { { Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP }, &ZNP_UnbindRsp }, // 45A2 + { { Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP }, &ZNP_MgmtBindRsp }, // 45B3 }; /*********************************************************************************************\ * Default resolver \*********************************************************************************************/ -int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { +int32_t ZNP_Recv_Default(int32_t res, const class SBuffer &buf) { // Default message handler for new messages if (zigbee.init_phase) { // if still during initialization phase, ignore any unexpected message diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index 5fb60de56..75c33e387 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -542,7 +542,7 @@ int32_t ZigbeeProcessInputRaw(class SBuffer &buf) { // RSTACK // received just after boot, either because of Power up, hardware reset or RST - Z_EZSP_RSTACK(buf.get8(2)); + EZ_RSTACK(buf.get8(2)); EZSP_Serial.from_ack = 0; EZSP_Serial.to_ack = 0; @@ -555,7 +555,7 @@ int32_t ZigbeeProcessInputRaw(class SBuffer &buf) { } else if (control_byte == 0xC2) { // ERROR - Z_EZSP_ERROR(buf.get8(2)); + EZ_ERROR(buf.get8(2)); zigbee.active = false; // stop all zigbee activities } else { @@ -691,6 +691,38 @@ void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterI ZigbeeZNPSend(buf.getBuffer(), buf.len()); #endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + SBuffer buf(32+len); + + buf.add16(EZSP_sendUnicast); // 3400 + buf.add8(EMBER_OUTGOING_DIRECT); // 00 + buf.add16(shortaddr); // dest addr + // ApsFrame + buf.add16(Z_PROF_HA); // Home Automation profile + buf.add16(clusterId); // cluster + buf.add8(0x01); // srcEp + buf.add8(endpoint); // dstEp + buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame + buf.add16(groupaddr); // groupId + buf.add8(transacId); + // end of ApsFrame + buf.add8(0x01); // tag TODO + + buf.add8(3 + len + (manuf ? 2 : 0)); + buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field + if (manuf) { + buf.add16(manuf); // add Manuf Id if not null + } + buf.add8(transacId); // Transaction Sequance Number + buf.add8(cmdId); + if (len > 0) { + buf.addBuffer(msg, len); // add the payload + } + + ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true); + +#endif // USE_ZIGBEE_EZSP } #endif // USE_ZIGBEE diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 1370db3cc..569f522fe 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -64,10 +64,16 @@ void ZigbeeInit(void) Settings.zb_precfgkey_h = USE_ZIGBEE_PRECFGKEY_H; Settings.zb_pan_id = USE_ZIGBEE_PANID; Settings.zb_channel = USE_ZIGBEE_CHANNEL; - Settings.zb_free_byte = 0; + Settings.zb_txradio_dbm = USE_ZIGBEE_TXRADIO_DBM; } + // update commands with the current settings - Z_UpdateConfig(Settings.zb_channel, Settings.zb_pan_id, Settings.zb_ext_panid, Settings.zb_precfgkey_l, Settings.zb_precfgkey_h); +#ifdef USE_ZIGBEE_ZNP + ZNP_UpdateConfig(Settings.zb_channel, Settings.zb_pan_id, Settings.zb_ext_panid, Settings.zb_precfgkey_l, Settings.zb_precfgkey_h); +#endif +#ifdef USE_ZIGBEE_EZSP + EZ_UpdateConfig(Settings.zb_channel, Settings.zb_pan_id, Settings.zb_ext_panid, Settings.zb_precfgkey_l, Settings.zb_precfgkey_h, Settings.zb_txradio_dbm); +#endif ZigbeeInitSerial(); } @@ -1018,6 +1024,7 @@ void CmndZbConfig(void) { uint64_t zb_ext_panid = Settings.zb_ext_panid; uint64_t zb_precfgkey_l = Settings.zb_precfgkey_l; uint64_t zb_precfgkey_h = Settings.zb_precfgkey_h; + uint8_t zb_txradio_dbm = Settings.zb_txradio_dbm; // if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } RemoveAllSpaces(XdrvMailbox.data); @@ -1043,18 +1050,23 @@ void CmndZbConfig(void) { // KeyH const JsonVariant &val_key_h = GetCaseInsensitive(json, PSTR("KeyH")); if (nullptr != &val_key_h) { zb_precfgkey_h = strtoull(val_key_h.as(), nullptr, 0); } + // TxRadio dBm + const JsonVariant &val_txradio = GetCaseInsensitive(json, PSTR("TxRadio")); + if (nullptr != &val_txradio) { zb_txradio_dbm = strToUInt(val_txradio); } // Check if a parameter was changed after all if ( (zb_channel != Settings.zb_channel) || (zb_pan_id != Settings.zb_pan_id) || (zb_ext_panid != Settings.zb_ext_panid) || (zb_precfgkey_l != Settings.zb_precfgkey_l) || - (zb_precfgkey_h != Settings.zb_precfgkey_h) ) { + (zb_precfgkey_h != Settings.zb_precfgkey_h) || + (zb_txradio_dbm != Settings.zb_txradio_dbm) ) { Settings.zb_channel = zb_channel; Settings.zb_pan_id = zb_pan_id; Settings.zb_ext_panid = zb_ext_panid; Settings.zb_precfgkey_l = zb_precfgkey_l; Settings.zb_precfgkey_h = zb_precfgkey_h; + Settings.zb_txradio_dbm = zb_txradio_dbm; restart_flag = 2; // save and reboot } } @@ -1074,10 +1086,12 @@ void CmndZbConfig(void) { ",\"ExtPanID\":\"%s\"" ",\"KeyL\":\"%s\"" ",\"KeyH\":\"%s\"" + ",\"TxRadio\":%d" "}}"), zb_channel, zb_pan_id, hex_ext_panid, - hex_precfgkey_l, hex_precfgkey_h); + hex_precfgkey_l, hex_precfgkey_h, + zb_txradio_dbm); } /*********************************************************************************************\ From fa4680bb616f27f9ab305ea33859922083f39aee Mon Sep 17 00:00:00 2001 From: stefanbode Date: Fri, 3 Jul 2020 08:59:48 +0200 Subject: [PATCH 396/581] Delete Arduino.h --- tasmota/Arduino.h | 493 ---------------------------------------------- 1 file changed, 493 deletions(-) delete mode 100644 tasmota/Arduino.h diff --git a/tasmota/Arduino.h b/tasmota/Arduino.h deleted file mode 100644 index 2dd8b22e2..000000000 --- a/tasmota/Arduino.h +++ /dev/null @@ -1,493 +0,0 @@ -/* - Arduino.h - Main include file for the Arduino SDK - Copyright (c) 2005-2013 Arduino Team. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifdef ESP8266 - -#ifndef Arduino_h -#define Arduino_h - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "stdlib_noniso.h" -#include "binary.h" -#include "esp8266_peri.h" -#include "twi.h" -#include "core_esp8266_features.h" -#include "core_esp8266_version.h" - -#define HIGH 0x1 -#define LOW 0x0 - -#define PWMRANGE 1023 - -//GPIO FUNCTIONS -#define INPUT 0x00 -#define INPUT_PULLUP 0x02 -#define INPUT_PULLDOWN_16 0x04 // PULLDOWN only possible for pin16 -#define OUTPUT 0x01 -#define OUTPUT_OPEN_DRAIN 0x03 -#define WAKEUP_PULLUP 0x05 -#define WAKEUP_PULLDOWN 0x07 -#define SPECIAL 0xF8 //defaults to the usable BUSes uart0rx/tx uart1tx and hspi -#define FUNCTION_0 0x08 -#define FUNCTION_1 0x18 -#define FUNCTION_2 0x28 -#define FUNCTION_3 0x38 -#define FUNCTION_4 0x48 - -#define PI 3.1415926535897932384626433832795 -#define HALF_PI 1.5707963267948966192313216916398 -#define TWO_PI 6.283185307179586476925286766559 -#define DEG_TO_RAD 0.017453292519943295769236907684886 -#define RAD_TO_DEG 57.295779513082320876798154814105 -#define EULER 2.718281828459045235360287471352 - -#define SERIAL 0x0 -#define DISPLAY 0x1 - -#define LSBFIRST 0 -#define MSBFIRST 1 - -//Interrupt Modes -#define RISING 0x01 -#define FALLING 0x02 -#define CHANGE 0x03 -#define ONLOW 0x04 -#define ONHIGH 0x05 -#define ONLOW_WE 0x0C -#define ONHIGH_WE 0x0D - -#define DEFAULT 1 -#define EXTERNAL 0 - -//timer dividers -enum TIM_DIV_ENUM { - TIM_DIV1 = 0, //80MHz (80 ticks/us - 104857.588 us max) - TIM_DIV16 = 1, //5MHz (5 ticks/us - 1677721.4 us max) - TIM_DIV256 = 3 //312.5Khz (1 tick = 3.2us - 26843542.4 us max) -}; - - -//timer int_types -#define TIM_EDGE 0 -#define TIM_LEVEL 1 -//timer reload values -#define TIM_SINGLE 0 //on interrupt routine you need to write a new value to start the timer again -#define TIM_LOOP 1 //on interrupt the counter will start with the same value again - -#define timer1_read() (T1V) -#define timer1_enabled() ((T1C & (1 << TCTE)) != 0) -#define timer1_interrupted() ((T1C & (1 << TCIS)) != 0) - -typedef void(*timercallback)(void); - -void timer1_isr_init(void); -void timer1_enable(uint8_t divider, uint8_t int_type, uint8_t reload); -void timer1_disable(void); -void timer1_attachInterrupt(timercallback userFunc); -void timer1_detachInterrupt(void); -void timer1_write(uint32_t ticks); //maximum ticks 8388607 - -// timer0 is a special CPU timer that has very high resolution but with -// limited control. -// it uses CCOUNT (ESP.GetCycleCount()) as the non-resetable timer counter -// it does not support divide, type, or reload flags -// it is auto-disabled when the compare value matches CCOUNT -// it is auto-enabled when the compare value changes -#define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM))) -#define timer0_read() ((__extension__({uint32_t count;__asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count));count;}))) -#define timer0_write(count) __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory") - -void timer0_isr_init(void); -void timer0_attachInterrupt(timercallback userFunc); -void timer0_detachInterrupt(void); - -// Use stdlib abs() and round() to avoid issues with the C++ libraries -#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) -#define radians(deg) ((deg)*DEG_TO_RAD) -#define degrees(rad) ((rad)*RAD_TO_DEG) -#define sq(x) ((x)*(x)) - -void ets_intr_lock(); -void ets_intr_unlock(); - -#define interrupts() xt_rsil(0) -#define noInterrupts() xt_rsil(15) - -#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) -#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) -#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) - -#define lowByte(w) ((uint8_t) ((w) & 0xff)) -#define highByte(w) ((uint8_t) ((w) >> 8)) - -#define bitRead(value, bit) (((value) >> (bit)) & 0x01) -#define bitSet(value, bit) ((value) |= (1UL << (bit))) -#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) -#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) - -// avr-libc defines _NOP() since 1.6.2 -#ifndef _NOP -#define _NOP() do { __asm__ volatile ("nop"); } while (0) -#endif - -typedef uint16_t word; - -#define bit(b) (1UL << (b)) -#define _BV(b) (1UL << (b)) - -typedef bool boolean; -typedef uint8_t byte; - -void init(void); -void initVariant(void); - -int atexit(void (*func)()) __attribute__((weak)); - -void pinMode(uint8_t pin, uint8_t mode); -void digitalWrite(uint8_t pin, uint8_t val); -int digitalRead(uint8_t pin); -int analogRead(uint8_t pin); -void analogReference(uint8_t mode); -void analogWrite(uint8_t pin, int val); -void analogWriteCCyPeriod(uint8_t pin, int val, uint32_t period); -void analogWriteFreq(uint32_t freq); -void analogWriteRange(uint32_t range); - -unsigned long millis(void); -unsigned long micros(void); -uint64_t micros64(void); -void delay(unsigned long); -void delayMicroseconds(unsigned int us); -unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); -unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); - -void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); -uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); - -void attachInterrupt(uint8_t pin, void (*)(void), int mode); -void detachInterrupt(uint8_t pin); -void attachInterruptArg(uint8_t pin, void (*)(void*), void* arg, int mode); - -void preinit(void); -void setup(void); -void loop(void); - -void yield(void); - -void optimistic_yield(uint32_t interval_us); - -#define _PORT_GPIO16 1 -#define digitalPinToPort(pin) (((pin)==16)?(_PORT_GPIO16):(0)) -#define digitalPinToBitMask(pin) (((pin)==16)?(1):(1UL << (pin))) -#define digitalPinToTimer(pin) (0) -#define portOutputRegister(port) (((port)==_PORT_GPIO16)?((volatile uint32_t*) &GP16O):((volatile uint32_t*) &GPO)) -#define portInputRegister(port) (((port)==_PORT_GPIO16)?((volatile uint32_t*) &GP16I):((volatile uint32_t*) &GPI)) -#define portModeRegister(port) (((port)==_PORT_GPIO16)?((volatile uint32_t*) &GP16E):((volatile uint32_t*) &GPE)) - -#define NOT_A_PIN -1 -#define NOT_A_PORT -1 -#define NOT_AN_INTERRUPT -1 -#define NOT_ON_TIMER 0 - -#ifdef __cplusplus -} // extern "C" -#endif - - -//for compatibility, below 4 lines to be removed in release 3.0.0 -#ifdef __cplusplus -extern "C" -#endif -const int TIM_DIV265 __attribute__((deprecated, weak)) = TIM_DIV256; - - - -#ifdef __cplusplus - -#include -#include -#include - -#include "WCharacter.h" -#include "WString.h" - -#include "HardwareSerial.h" -#include "Esp.h" -#include "Updater.h" -#include "debug.h" - -using std::min; -using std::max; -using std::round; -using std::isinf; -using std::isnan; - -#define _min(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a < _b? _a : _b; }) -#define _max(a,b) ({ decltype(a) _a = (a); decltype(b) _b = (b); _a > _b? _a : _b; }) - -uint16_t makeWord(uint16_t w); -uint16_t makeWord(byte h, byte l); - -#define word(...) makeWord(__VA_ARGS__) - -unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); -unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); - -void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); -void tone(uint8_t _pin, int frequency, unsigned long duration = 0); -void tone(uint8_t _pin, double frequency, unsigned long duration = 0); -void noTone(uint8_t _pin); - -// WMath prototypes -long random(long); -long random(long, long); -void randomSeed(unsigned long); -long secureRandom(long); -long secureRandom(long, long); -long map(long, long, long, long, long); - -void setTZ(const char* tz); - -void configTime(int timezone, int daylightOffset_sec, const char* server1, - const char* server2 = nullptr, const char* server3 = nullptr); - -void configTime(const char* tz, const char* server1, - const char* server2 = nullptr, const char* server3 = nullptr); - -// esp32 api compatibility -inline void configTzTime(const char* tz, const char* server1, - const char* server2 = nullptr, const char* server3 = nullptr) -{ - configTime(tz, server1, server2, server3); -} - -#endif // __cplusplus - -#include "pins_arduino.h" - -#endif - -#ifdef DEBUG_ESP_OOM -// reinclude *alloc redefinition because of undefining them -// this is mandatory for allowing OOM *alloc definitions in .ino files -#include "umm_malloc/umm_malloc_cfg.h" -#endif - -#else - -/* - Arduino.h - Main include file for the Arduino SDK - Copyright (c) 2005-2013 Arduino Team. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef Arduino_h -#define Arduino_h - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "esp32-hal.h" -#include "esp8266-compat.h" -#include "soc/gpio_reg.h" - -#include "stdlib_noniso.h" -#include "binary.h" - -#define PI 3.1415926535897932384626433832795 -#define HALF_PI 1.5707963267948966192313216916398 -#define TWO_PI 6.283185307179586476925286766559 -#define DEG_TO_RAD 0.017453292519943295769236907684886 -#define RAD_TO_DEG 57.295779513082320876798154814105 -#define EULER 2.718281828459045235360287471352 - -#define SERIAL 0x0 -#define DISPLAY 0x1 - -#define LSBFIRST 0 -#define MSBFIRST 1 - -//Interrupt Modes -#define RISING 0x01 -#define FALLING 0x02 -#define CHANGE 0x03 -#define ONLOW 0x04 -#define ONHIGH 0x05 -#define ONLOW_WE 0x0C -#define ONHIGH_WE 0x0D - -#define DEFAULT 1 -#define EXTERNAL 0 - -#ifndef __STRINGIFY -#define __STRINGIFY(a) #a -#endif - -#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) -#define radians(deg) ((deg)*DEG_TO_RAD) -#define degrees(rad) ((rad)*RAD_TO_DEG) -#define sq(x) ((x)*(x)) - -#define sei() -#define cli() -#define interrupts() sei() -#define noInterrupts() cli() - -#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) -#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) -#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) - -#define lowByte(w) ((uint8_t) ((w) & 0xff)) -#define highByte(w) ((uint8_t) ((w) >> 8)) - -#define bitRead(value, bit) (((value) >> (bit)) & 0x01) -#define bitSet(value, bit) ((value) |= (1UL << (bit))) -#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) -#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) - -// avr-libc defines _NOP() since 1.6.2 -#ifndef _NOP -#define _NOP() do { __asm__ volatile ("nop"); } while (0) -#endif - -#define bit(b) (1UL << (b)) -#define _BV(b) (1UL << (b)) - -#define digitalPinToPort(pin) (((pin)>31)?1:0) -#define digitalPinToBitMask(pin) (1UL << (((pin)>31)?((pin)-32):(pin))) -#define digitalPinToTimer(pin) (0) -#define analogInPinToBit(P) (P) -#define portOutputRegister(port) ((volatile uint32_t*)((port)?GPIO_OUT1_REG:GPIO_OUT_REG)) -#define portInputRegister(port) ((volatile uint32_t*)((port)?GPIO_IN1_REG:GPIO_IN_REG)) -#define portModeRegister(port) ((volatile uint32_t*)((port)?GPIO_ENABLE1_REG:GPIO_ENABLE_REG)) - -#define NOT_A_PIN -1 -#define NOT_A_PORT -1 -#define NOT_AN_INTERRUPT -1 -#define NOT_ON_TIMER 0 - -typedef bool boolean; -typedef uint8_t byte; -typedef unsigned int word; - -void setup(void); -void loop(void); - -long random(long, long); -void randomSeed(unsigned long); -long map(long, long, long, long, long); - -#ifdef __cplusplus -extern "C" { -#endif - -void init(void); -void initVariant(void); -void initArduino(void); - -unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); -unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); - -uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); -void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); - -#ifdef __cplusplus -} - -#include -#include - -#include "WCharacter.h" -#include "WString.h" -#include "Stream.h" -#include "Printable.h" -#include "Print.h" -#include "IPAddress.h" -#include "Client.h" -#include "Server.h" -#include "Udp.h" -#include "HardwareSerial.h" -#include "Esp.h" - -using std::abs; -using std::isinf; -using std::isnan; -using std::max; -using std::min; -using ::round; - -uint16_t makeWord(uint16_t w); -uint16_t makeWord(byte h, byte l); - -#define word(...) makeWord(__VA_ARGS__) - -unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); -unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); - -extern "C" bool getLocalTime(struct tm * info, uint32_t ms = 5000); -extern "C" void configTime(long gmtOffset_sec, int daylightOffset_sec, - const char* server1, const char* server2 = nullptr, const char* server3 = nullptr); -extern "C" void configTzTime(const char* tz, - const char* server1, const char* server2 = nullptr, const char* server3 = nullptr); - -// WMath prototypes -long random(long); -#endif /* __cplusplus */ - -#define _min(a,b) ((a)<(b)?(a):(b)) -#define _max(a,b) ((a)>(b)?(a):(b)) - -#include "pins_arduino.h" - -#endif /* _ESP32_CORE_ARDUINO_H_ */ - -#endif From 6bd4edcdae34b57aa349b87b7085b9c7942c6339 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Fri, 3 Jul 2020 09:01:02 +0200 Subject: [PATCH 397/581] Update xsns_01_counter.ino --- tasmota/xsns_01_counter.ino | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index 18f1ed461..c3584f111 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -99,7 +99,11 @@ void CounterUpdate(uint8_t index) uint32_t steps = (current_cycle-last_cycle+100000)/(clockCyclesPerMicrosecond() * 10000); cycle_time = (current_cycle-last_cycle)/steps; #ifdef ESP8266 - analogWriteCCyPeriod(Pin(GPIO_PWM1, index), 5, cycle_time ); + pinMode(Pin(GPIO_PWM1, index), OUTPUT); + uint32_t high = (cycle_time * 5) / 1023; + uint32_t low = cycle_time - high; + // Find the first GPIO being generated by checking GCC's find-first-set (returns 1 + the bit of the first 1 in an int32_t + startWaveformClockCycles(Pin(GPIO_PWM1, index), high, low, 0, -1, 0, true); #else analogWrite(Pin(GPIO_PWM1, index), 5); #endif From d3a9413a7c909e8f4d1eaf4f3950fbaf6407c9a1 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Fri, 3 Jul 2020 09:01:53 +0200 Subject: [PATCH 398/581] Update tasmota_globals.h --- tasmota/tasmota_globals.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 791896ac3..a4df0c4f7 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -42,6 +42,8 @@ void DomoticzTempHumPressureSensor(float temp, float hum, float baro = -1); char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0'); extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end); extern "C" void resetPins(); +extern "C" int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys, + uint32_t runTimeCcys, int8_t alignPhase, uint32_t phaseOffsetCcys, bool autoPwm); #ifdef ESP32 From 041be8882e642edb0cd3c9bc7265fb9f35476df2 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Fri, 3 Jul 2020 09:04:14 +0200 Subject: [PATCH 399/581] Update core_esp8266_wiring_pwm.cpp --- tasmota/core_esp8266_wiring_pwm.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/tasmota/core_esp8266_wiring_pwm.cpp b/tasmota/core_esp8266_wiring_pwm.cpp index 1c7704b46..6141649da 100644 --- a/tasmota/core_esp8266_wiring_pwm.cpp +++ b/tasmota/core_esp8266_wiring_pwm.cpp @@ -49,18 +49,13 @@ extern void __analogWriteFreq(uint32_t freq) { } -extern void __analogWriteCCyPeriod(uint8_t pin, int val, uint32_t period) { +extern void __analogWrite(uint8_t pin, int val) { if (pin > 16) { return; } uint32_t analogPeriod; - if (period == 0) { - analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq; - } else { - analogPeriod = period; - } - - //uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq; +{ + uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq; if (val < 0) { val = 0; } else if (val > analogScale) { @@ -80,14 +75,8 @@ extern void __analogWriteCCyPeriod(uint8_t pin, int val, uint32_t period) { if (startWaveformClockCycles(pin, high, low, 0, phaseReference, 0, true)) { analogMap |= (1 << pin); } - //Serial.printf("phase: %d, high %d, low %d, drift %d, apr: %u\n", phaseReference,high,low, analogDrift, analogPeriod ); } -extern void __analogWrite(uint8_t pin, int val) { - __analogWriteCCyPeriod( pin, val, 0); -} - -extern void analogWriteCCyPeriod(uint8_t pin, int val, uint32_t priod) __attribute__((weak, alias("__analogWriteCCyPeriod"))); extern void analogWrite(uint8_t pin, int val) __attribute__((weak, alias("__analogWrite"))); extern void analogWriteFreq(uint32_t freq) __attribute__((weak, alias("__analogWriteFreq"))); extern void analogWriteRange(uint32_t range) __attribute__((weak, alias("__analogWriteRange"))); From 22fec3202a911a13ebfd3946dae8568549f60db4 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Fri, 3 Jul 2020 09:07:43 +0200 Subject: [PATCH 400/581] Update core_esp8266_wiring_pwm.cpp --- tasmota/core_esp8266_wiring_pwm.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasmota/core_esp8266_wiring_pwm.cpp b/tasmota/core_esp8266_wiring_pwm.cpp index 6141649da..d81928a5d 100644 --- a/tasmota/core_esp8266_wiring_pwm.cpp +++ b/tasmota/core_esp8266_wiring_pwm.cpp @@ -53,8 +53,7 @@ extern void __analogWrite(uint8_t pin, int val) { if (pin > 16) { return; } - uint32_t analogPeriod; -{ + uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq; if (val < 0) { val = 0; From a6dcffab9bf697b145f68cea9dd0266ce4b73d34 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 3 Jul 2020 12:30:09 +0200 Subject: [PATCH 401/581] Fix PROGMEM related exceptions Fix PROGMEM related exceptions (#8828) --- tasmota/support_json.ino | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tasmota/support_json.ino b/tasmota/support_json.ino index 902a6e926..b78c68eab 100644 --- a/tasmota/support_json.ino +++ b/tasmota/support_json.ino @@ -35,19 +35,21 @@ char EscapeJSONChar(char c) { } String EscapeJSONString(const char *str) { + // As this function is used in ResponseCmndChar() and ResponseCmndIdxChar() + // it needs to be PROGMEM safe! String r(""); if (nullptr == str) { return r; } bool needs_escape = false; size_t len_out = 1; - const char * c = str; - - while (*c) { - if (EscapeJSONChar(*c)) { + const char* c = str; + char ch = '.'; + while (ch != '\0') { + ch = pgm_read_byte(c++); + if (EscapeJSONChar(ch)) { len_out++; needs_escape = true; } - c++; len_out++; } @@ -57,20 +59,21 @@ String EscapeJSONString(const char *str) { r.reserve(len_out); c = str; char *d = r.begin(); - while (*c) { - char c2 = EscapeJSONChar(*c); + char ch = '.'; + while (ch != '\0') { + ch = pgm_read_byte(c++); + char c2 = EscapeJSONChar(ch); if (c2) { - c++; *d++ = '\\'; *d++ = c2; } else { - *d++ = *c++; + *d++ = ch; } } *d = 0; // add NULL terminator r = (char*) r.begin(); // assign the buffer to the string } else { - r = str; + r = FPSTR(str); } return r; From e5127d8e8ed7de4ff3f2521d273116cc1d344183 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 3 Jul 2020 17:17:57 +0200 Subject: [PATCH 402/581] Fix possible watchdog/exception Fix possible watchdog/exception (#8828) --- tasmota/support_rotary.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index cd80b4484..cfe549a5f 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -213,6 +213,8 @@ void update_rotary(void) { } bool RotaryButtonPressed(void) { + if (!Rotary.present) { return false; } + bool powered_on = (power); #ifdef USE_LIGHT if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control @@ -246,6 +248,8 @@ void RotaryInit(void) { \*********************************************************************************************/ void RotaryHandler(void) { + if (!Rotary.present) { return; } + if (Rotary.timeout) { Rotary.timeout--; if (!Rotary.timeout) { From 0cebf9a28fc0e5c7243e8650d0b29f65eab67908 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Sat, 4 Jul 2020 10:43:02 +0200 Subject: [PATCH 403/581] Fix shutter target == 255 on close --- tasmota/xdrv_27_shutter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index 4e0f02945..331678eb9 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -161,7 +161,7 @@ uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index) break; } } - return realpercent; + return (int16_t)realpercent < 0 ? 0 : realpercent; } } From fca3c1357c9d64b028c9991c45c568a27288d90f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 4 Jul 2020 12:00:15 +0200 Subject: [PATCH 404/581] Add build flag -DFIRMWARE_IR_CUSTOM to env tasmota-ir. --- platformio_tasmota_env.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_tasmota_env.ini b/platformio_tasmota_env.ini index 3d08d5cd6..4a447da82 100644 --- a/platformio_tasmota_env.ini +++ b/platformio_tasmota_env.ini @@ -36,7 +36,7 @@ build_flags = ${common.build_flags} -DFIRMWARE_DISPLAYS build_flags = ${common.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_IR [env:tasmota-ircustom] -build_flags = ${common.build_flags} ${irremoteesp_full.build_flags} +build_flags = ${common.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_IR_CUSTOM [env:tasmota-BG] build_flags = ${common.build_flags} -DMY_LANGUAGE=bg_BG From 3e46e6169e2f1b21e44bdaa7769ebd9f5e90645e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 4 Jul 2020 12:18:45 +0200 Subject: [PATCH 405/581] Update platformio_tasmota_env32.ini --- platformio_tasmota_env32.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 4398dcb04..6d6a0ebc0 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -50,7 +50,7 @@ build_flags = ${common32.build_flags} ${irremoteesp_full.build_flags [env:tasmota32-ircustom] extends = env:tasmota32 -build_flags = ${common32.build_flags} ${irremoteesp_full.build_flags} +build_flags = ${common32.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_IR_CUSTOM [env:tasmota32-BG] extends = env:tasmota32 From 9df9d38c3adea0be81ff3db9a3f285af538d6695 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 4 Jul 2020 12:23:12 +0200 Subject: [PATCH 406/581] Release 8.4.0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 686d7d550..ed85f1737 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ In addition to the [release webpage](https://github.com/arendst/Tasmota/releases ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v8.3.1.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v8.4.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) [![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) From cbe8887ca7df9ae55070ea1d74e367304925ae56 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 4 Jul 2020 12:29:48 +0200 Subject: [PATCH 407/581] Revert development --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ed85f1737..f5d40a631 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ In addition to the [release webpage](https://github.com/arendst/Tasmota/releases ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v8.4.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v8.3.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) [![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) From c0c19ea3dab55220dd2d6469deaab5d82d2ea13a Mon Sep 17 00:00:00 2001 From: Ryan Castellucci Date: Sat, 4 Jul 2020 11:56:05 +0100 Subject: [PATCH 408/581] Transparent default value for MqttFingerprint2 I was unable to find any information on where the existing default MqttFingerprint2 value came from, and can't be sure that someone doesn't have a key matching it. For transparency, this patch replaces the default MqttFingerprint2 value with the result of SHA1("Tasmota") as a "nothing-up-my-sleeve number". --- tasmota/my_user_config.h | 4 ++-- tasmota/tasmota_globals.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index a097b6154..0ab09d224 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -97,8 +97,8 @@ #define MQTT_USE true // [SetOption3] Select default MQTT use (false = Off, true = On) #define MQTT_HOST "" // [MqttHost] -#define MQTT_FINGERPRINT1 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" // [MqttFingerprint1] -#define MQTT_FINGERPRINT2 "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07" // [MqttFingerprint2] +#define MQTT_FINGERPRINT1 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" // [MqttFingerprint1] (auto-learn) +#define MQTT_FINGERPRINT2 "DA 39 A3 EE 5E 6B 4B 0D 32 55 BF EF 95 60 18 90 AF D8 07 09" // [MqttFingerprint2] (invalid) #define MQTT_PORT 1883 // [MqttPort] MQTT port (10123 on CloudMQTT) #define MQTT_USER "DVES_USER" // [MqttUser] MQTT user #define MQTT_PASS "DVES_PASS" // [MqttPassword] MQTT password diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index a4df0c4f7..42e63f206 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -114,8 +114,8 @@ String EthernetMacAddress(void); // Set an all-zeros default fingerprint to activate auto-learning on first connection (AWS IoT) #define MQTT_FINGERPRINT1 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" #endif -#ifndef MQTT_FINGERPRINT2 -#define MQTT_FINGERPRINT2 "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07" +#ifndef MQTT_FINGERPRINT2 // SHA1('') +#define MQTT_FINGERPRINT2 "DA 39 A3 EE 5E 6B 4B 0D 32 55 BF EF 95 60 18 90 AF D8 07 09" #endif #ifndef WS2812_LEDS From 46542e4cbb41e2912d3338a81a3f0acc5c41dde7 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Sat, 4 Jul 2020 13:20:53 +0200 Subject: [PATCH 409/581] Shutter change loglevels+1 --- tasmota/xdrv_27_shutter.ino | 80 ++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index 331678eb9..4b132338e 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -84,7 +84,7 @@ void ShutterLogPos(uint32_t i) { char stemp2[10]; dtostrfd((float)Shutter.time[i] / steps_per_second, 2, stemp2); - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter%d Real %d, Start %d, Stop %d, Dir %d, Delay %d, Rtc %s [s], Freq %d"), + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter%d Real %d, Start %d, Stop %d, Dir %d, Delay %d, Rtc %s [s], Freq %d"), i+1, Shutter.real_position[i], Shutter.start_position[i], Shutter.target_position[i], Shutter.direction[i], Shutter.motordelay[i], stemp2, Shutter.pwm_frequency[i]); } @@ -93,7 +93,7 @@ void ShutterRtc50mS(void) for (uint8_t i = 0; i < shutters_present; i++) { Shutter.time[i]++; if (Shutter.accelerator[i]) { - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: accelerator i=%d -> %d"),i, Shutter.accelerator[i]); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: accelerator i=%d -> %d"),i, Shutter.accelerator[i]); Shutter.pwm_frequency[i] += Shutter.accelerator[i]; Shutter.pwm_frequency[i] = tmax(0,tmin(Shutter.direction[i]==1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i],Shutter.pwm_frequency[i])); analogWriteFreq(Shutter.pwm_frequency[i]); @@ -122,13 +122,13 @@ int32_t ShutterPercentToRealPosition(uint32_t percent, uint32_t index) for (uint32_t i = 0; i < 5; i++) { if ((percent * 10) >= Settings.shuttercoeff[i][index]) { realpos = SHT_DIV_ROUND(Shutter.open_max[index] * calibrate_pos[i+1], 100); - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Realposition TEMP1: %d, %% %d, coeff %d"), realpos, percent, Settings.shuttercoeff[i][index]); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Realposition TEMP1: %d, %% %d, coeff %d"), realpos, percent, Settings.shuttercoeff[i][index]); } else { if (0 == i) { realpos = SHT_DIV_ROUND(SHT_DIV_ROUND(percent * Shutter.open_max[index] * calibrate_pos[i+1], Settings.shuttercoeff[i][index]), 10); } else { //uint16_t addon = ( percent*10 - Settings.shuttercoeff[i-1][index] ) * Shutter_Open_Max[index] * (calibrate_pos[i+1] - calibrate_pos[i]) / (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index]) / 100; - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Realposition TEMP2: %d, %% %d, coeff %d"), addon, (calibrate_pos[i+1] - calibrate_pos[i]), (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index])); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Realposition TEMP2: %d, %% %d, coeff %d"), addon, (calibrate_pos[i+1] - calibrate_pos[i]), (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index])); realpos += SHT_DIV_ROUND(SHT_DIV_ROUND((percent*10 - Settings.shuttercoeff[i-1][index] ) * Shutter.open_max[index] * (calibrate_pos[i+1] - calibrate_pos[i]), Settings.shuttercoeff[i][index] - Settings.shuttercoeff[i-1][index]), 100); } break; @@ -148,14 +148,14 @@ uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index) for (uint32_t i = 0; i < 5; i++) { if (realpos >= Shutter.open_max[index] * calibrate_pos[i+1] / 100) { realpercent = SHT_DIV_ROUND(Settings.shuttercoeff[i][index], 10); - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Realpercent TEMP1: %d, %% %d, coeff %d"), realpercent, realpos, Shutter_Open_Max[index] * calibrate_pos[i+1] / 100); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Realpercent TEMP1: %d, %% %d, coeff %d"), realpercent, realpos, Shutter_Open_Max[index] * calibrate_pos[i+1] / 100); } else { if (0 == i) { realpercent = SHT_DIV_ROUND(SHT_DIV_ROUND((realpos - SHT_DIV_ROUND(Shutter.open_max[index] * calibrate_pos[i], 100)) * 10 * Settings.shuttercoeff[i][index], calibrate_pos[i+1]), Shutter.open_max[index]); } else { //uint16_t addon = ( realpos - (Shutter_Open_Max[index] * calibrate_pos[i] / 100) ) * 10 * (Settings.shuttercoeff[i][index] - Settings.shuttercoeff[i-1][index]) / (calibrate_pos[i+1] - calibrate_pos[i])/ Shutter_Open_Max[index]; //uint16_t addon = ( percent*10 - Settings.shuttercoeff[i-1][index] ) * Shutter_Open_Max[index] * (calibrate_pos[i+1] - calibrate_pos[i]) / (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index]) / 100; - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Realpercent TEMP2: %d, delta %d, %% %d, coeff %d"), addon,( realpos - (Shutter_Open_Max[index] * calibrate_pos[i] / 100) ) , (calibrate_pos[i+1] - calibrate_pos[i])* Shutter_Open_Max[index]/100, (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index])); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Realpercent TEMP2: %d, delta %d, %% %d, coeff %d"), addon,( realpos - (Shutter_Open_Max[index] * calibrate_pos[i] / 100) ) , (calibrate_pos[i+1] - calibrate_pos[i])* Shutter_Open_Max[index]/100, (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index])); realpercent += SHT_DIV_ROUND(SHT_DIV_ROUND((realpos - SHT_DIV_ROUND(Shutter.open_max[index] * calibrate_pos[i], 100)) * 10 * (Settings.shuttercoeff[i][index] - Settings.shuttercoeff[i-1][index]), (calibrate_pos[i+1] - calibrate_pos[i])), Shutter.open_max[index]) ; } break; @@ -187,9 +187,9 @@ void ShutterInit(void) Shutter.mask |= 3 << (Settings.shutter_startrelay[i] -1) ; for (uint32_t j = 0; j < MAX_INTERLOCKS * Settings.flag.interlock; j++) { // CMND_INTERLOCK - Enable/disable interlock - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Interlock state i=%d %d, flag %d, , shuttermask %d, maskedIL %d"),i, Settings.interlock[i], Settings.flag.interlock,Shutter.mask, Settings.interlock[i]&Shutter.mask); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Interlock state i=%d %d, flag %d, , shuttermask %d, maskedIL %d"),i, Settings.interlock[i], Settings.flag.interlock,Shutter.mask, Settings.interlock[i]&Shutter.mask); if (Settings.interlock[j] && (Settings.interlock[j] & Shutter.mask)) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Relay in Interlock group")); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Relay in Interlock group")); relay_in_interlock = true; } } @@ -223,7 +223,7 @@ void ShutterInit(void) Shutter.open_max[i] = 200 * Shutter.open_time[i]; Shutter.close_velocity[i] = Shutter.open_max[i] / Shutter.close_time[i] / 2 ; Shutter.max_close_pwm_frequency[i] = Shutter.max_pwm_frequency*Shutter.open_time[i] / Shutter.close_time[i]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d Closefreq: %d"),i, Shutter.max_close_pwm_frequency[i]); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d Closefreq: %d"),i, Shutter.max_close_pwm_frequency[i]); // calculate a ramp slope at the first 5 percent to compensate that shutters move with down part later than the upper part if (Settings.shutter_set50percent[i] != 50) { @@ -242,7 +242,7 @@ void ShutterInit(void) dtostrfd((float)Shutter.open_time[i] / 10 , 1, shutter_open_chr); char shutter_close_chr[10]; dtostrfd((float)Shutter.close_time[i] / 10, 1, shutter_close_chr); - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d (Relay:%d): Init. Pos: %d [%d %%], Open Vel.: 100, Close Vel.: %d , Max Way: %d, Opentime %s [s], Closetime %s [s], CoeffCalc: c0: %d, c1 %d, c2: %d, c3: %d, c4: %d, binmask %d, is inverted %d, is locked %d, end stop time enabled %d, webButtons inverted %d, shuttermode %d, motordelay %d"), + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d (Relay:%d): Init. Pos: %d [%d %%], Open Vel.: 100, Close Vel.: %d , Max Way: %d, Opentime %s [s], Closetime %s [s], CoeffCalc: c0: %d, c1 %d, c2: %d, c3: %d, c4: %d, binmask %d, is inverted %d, is locked %d, end stop time enabled %d, webButtons inverted %d, shuttermode %d, motordelay %d"), i+1, Settings.shutter_startrelay[i], Shutter.real_position[i], Settings.shutter_position[i], Shutter.close_velocity[i], Shutter.open_max[i], shutter_open_chr, shutter_close_chr, Settings.shuttercoeff[0][i], Settings.shuttercoeff[1][i], Settings.shuttercoeff[2][i], Settings.shuttercoeff[3][i], Settings.shuttercoeff[4][i], Shutter.mask, (Settings.shutter_options[i]&1) ? 1 : 0, (Settings.shutter_options[i]&2) ? 1 : 0, (Settings.shutter_options[i]&4) ? 1 : 0, (Settings.shutter_options[i]&8) ? 1 : 0, Shutter.mode, Shutter.motordelay[i]); @@ -267,7 +267,7 @@ void ShutterReportPosition(bool always, uint32_t index) n = index+1; } for (i; i < n; i++) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d: Real Pos: %d"), i+1,Shutter.real_position[i]); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Real Pos: %d"), i+1,Shutter.real_position[i]); uint32_t position = ShutterRealToPercentPosition(Shutter.real_position[i], i); if (Shutter.direction[i] != 0) { rules_flag.shutter_moving = 1; @@ -283,7 +283,7 @@ void ShutterReportPosition(bool always, uint32_t index) //XdrvRulesProcess(); //removed because to many exceptions and reboots. } - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: rules_flag.shutter_moving: %d, moved %d"), rules_flag.shutter_moving, rules_flag.shutter_moved); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: rules_flag.shutter_moving: %d, moved %d"), rules_flag.shutter_moving, rules_flag.shutter_moved); } @@ -339,7 +339,7 @@ void ShutterUpdatePosition(void) } if ( Shutter.real_position[i] * Shutter.direction[i] + stop_position_delta >= Shutter.target_position[i] * Shutter.direction[i] ) { // calculate relay number responsible for current movement. - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Stop Condition detected: real: %d, Target: %d, direction: %d"),Shutter.real_position[i], Shutter.target_position[i],Shutter.direction[i]); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Stop Condition detected: real: %d, Target: %d, direction: %d"),Shutter.real_position[i], Shutter.target_position[i],Shutter.direction[i]); uint8_t cur_relay = Settings.shutter_startrelay[i] + (Shutter.direction[i] == 1 ? 0 : 1) ; int16_t missing_steps; @@ -355,7 +355,7 @@ void ShutterUpdatePosition(void) case SHT_OFF_ON__OPEN_CLOSE_STEPPER: missing_steps = ((Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) - RtcSettings.pulse_counter[i]; //prepare for stop PWM - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Remain steps %d, counter %d, freq %d"), missing_steps, RtcSettings.pulse_counter[i] ,Shutter.pwm_frequency[i]); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain steps %d, counter %d, freq %d"), missing_steps, RtcSettings.pulse_counter[i] ,Shutter.pwm_frequency[i]); Shutter.accelerator[i] = 0; Shutter.pwm_frequency[i] = Shutter.pwm_frequency[i] > 250 ? 250 : Shutter.pwm_frequency[i]; analogWriteFreq(Shutter.pwm_frequency[i]); @@ -368,7 +368,7 @@ void ShutterUpdatePosition(void) analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8.3 because of reset caused by watchog // ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); Shutter.real_position[i] = ShutterCounterBasedPosition(i); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Real %d, pulsecount %d, start %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i]); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Real %d, pulsecount %d, start %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i]); if ((1 << (Settings.shutter_startrelay[i]-1)) & power) { ExecuteCommandPower(Settings.shutter_startrelay[i], 0, SRC_SHUTTER); @@ -421,7 +421,7 @@ bool ShutterState(uint32_t device) void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) { - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: dir %d, delta1 %d, delta2 %d, grant %d"),direction, (Shutter.open_max[i] - Shutter.real_position[i]) / Shutter.close_velocity[i], Shutter.real_position[i] / Shutter.close_velocity[i], 2+Shutter.motordelay[i]); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: dir %d, delta1 %d, delta2 %d, grant %d"),direction, (Shutter.open_max[i] - Shutter.real_position[i]) / Shutter.close_velocity[i], Shutter.real_position[i] / Shutter.close_velocity[i], 2+Shutter.motordelay[i]); if ( ( (1 == direction) && ((Shutter.open_max[i] - Shutter.real_position[i]) / 100 <= 2) ) || ( (-1 == direction) && (Shutter.real_position[i] / Shutter.close_velocity[i] <= 2)) ) { Shutter.skip_relay_change = 1; @@ -432,7 +432,7 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) analogWrite(Pin(GPIO_PWM1, i), 0); RtcSettings.pulse_counter[i] = 0; Shutter.accelerator[i] = Shutter.max_pwm_frequency / (Shutter.motordelay[i]>0 ? Shutter.motordelay[i] : 1); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Ramp up: %d"), Shutter.accelerator[i]); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Ramp up: %d"), Shutter.accelerator[i]); } Shutter.target_position[i] = target_pos; Shutter.start_position[i] = Shutter.real_position[i]; @@ -442,17 +442,17 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) rules_flag.shutter_moving = 1; rules_flag.shutter_moved = 0; Shutter.start_reported = 0; - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: real %d, start %d, counter %d, max_freq %d, dir %d, freq %d"),Shutter.real_position[i], Shutter.start_position[i] ,RtcSettings.pulse_counter[i],Shutter.max_pwm_frequency , Shutter.direction[i] ,Shutter.max_pwm_frequency ); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: real %d, start %d, counter %d, max_freq %d, dir %d, freq %d"),Shutter.real_position[i], Shutter.start_position[i] ,RtcSettings.pulse_counter[i],Shutter.max_pwm_frequency , Shutter.direction[i] ,Shutter.max_pwm_frequency ); } - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start shutter: %d from %d to %d in directin %d"), i, Shutter.start_position[i], Shutter.target_position[i], Shutter.direction[i]); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Start shutter: %d from %d to %d in directin %d"), i, Shutter.start_position[i], Shutter.target_position[i], Shutter.direction[i]); } void ShutterWaitForMotorStop(uint32_t i) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Wait for Motorstop..")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Wait for Motorstop..")); if ((SHT_OFF_ON__OPEN_CLOSE == Shutter.mode) || (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode)) { if (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Frequency change %d"), Shutter.pwm_frequency); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Frequency change %d"), Shutter.pwm_frequency); while (Shutter.pwm_frequency[i] > 0) { //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Frequency: %ld, delta: %d"), Shutter.pwm_frequency[i], (int32_t)((Shutter.direction[i] == 1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i])/(Shutter.motordelay[i]+1)) ); Shutter.pwm_frequency[i] = tmax(Shutter.pwm_frequency[i]-((Shutter.direction[i] == 1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i])/(Shutter.motordelay[i]+1)) , 0); @@ -490,7 +490,7 @@ void ShutterRelayChanged(void) power_t powerstate_local = (power >> (Settings.shutter_startrelay[i] -1)) & 3; //uint8 manual_relays_changed = ((Shutter.switched_relay >> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_IGNORE != last_source && SRC_SHUTTER != last_source && SRC_PULSETIMER != last_source ; uint8 manual_relays_changed = ((Shutter.switched_relay >> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_SHUTTER != last_source && SRC_PULSETIMER != last_source ; - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: source: %s, powerstate_local %ld, Shutter.switched_relay %d, manual change %d"), i+1, GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,Shutter.switched_relay,manual_relays_changed); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: source: %s, powerstate_local %ld, Shutter.switched_relay %d, manual change %d"), i+1, GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,Shutter.switched_relay,manual_relays_changed); if (manual_relays_changed) { //Shutter.skip_relay_change = true; ShutterLimitRealAndTargetPositions(i); @@ -504,13 +504,13 @@ void ShutterRelayChanged(void) ShutterStartInit(i, -1, 0); break; default: - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Switch OFF motor."),i); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Switch OFF motor."),i); Shutter.target_position[i] = Shutter.real_position[i]; } } else { if (Shutter.direction[i] != 0 && (!powerstate_local || (powerstate_local && Shutter.mode == SHT_PULSE_OPEN__PULSE_CLOSE))) { Shutter.target_position[i] = Shutter.real_position[i]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Switch OFF motor. Target: %ld, source: %s, powerstate_local %ld, Shutter.switched_relay %d, manual change %d"), i+1, Shutter.target_position[i], GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,Shutter.switched_relay,manual_relays_changed); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Switch OFF motor. Target: %ld, source: %s, powerstate_local %ld, Shutter.switched_relay %d, manual change %d"), i+1, Shutter.target_position[i], GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,Shutter.switched_relay,manual_relays_changed); } else { last_source = SRC_SHUTTER; // avoid switch off in the next loop if (powerstate_local == 2) { // testing on CLOSE relay, if ON @@ -523,7 +523,7 @@ void ShutterRelayChanged(void) ShutterStartInit(i, 1, Shutter.open_max[i]); } } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Target: %ld, powerstatelocal %d"), i+1, Shutter.target_position[i], powerstate_local); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Target: %ld, powerstatelocal %d"), i+1, Shutter.target_position[i], powerstate_local); } } } @@ -615,15 +615,15 @@ void ShutterButtonHandler(void) // check for simultaneous shutter button press uint32 min_shutterbutton_press_counter = -1; // -1 == max(uint32) for (uint32_t i = 0; i < MAX_KEYS; i++) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Settings.shutter_button[i] %ld, shutter_index %d, Button.press_counter[i] %d, min_shutterbutton_press_counter %d, i %d"), Settings.shutter_button[i], shutter_index, Button.press_counter[i] , min_shutterbutton_press_counter, i); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Settings.shutter_button[i] %ld, shutter_index %d, Button.press_counter[i] %d, min_shutterbutton_press_counter %d, i %d"), Settings.shutter_button[i], shutter_index, Button.press_counter[i] , min_shutterbutton_press_counter, i); if ((button_index != i) && (Settings.shutter_button[i] & (1<<31)) && ((Settings.shutter_button[i] & 0x03) == shutter_index) && (i != button_index) && (Button.press_counter[i] < min_shutterbutton_press_counter)) { min_shutterbutton_press_counter = Button.press_counter[i]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: min_shutterbutton_press_counter %d"), min_shutterbutton_press_counter); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: min_shutterbutton_press_counter %d"), min_shutterbutton_press_counter); } } if (min_shutterbutton_press_counter == Button.press_counter[button_index]) { // simultaneous shutter button press detected - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: simultanous presss deteced")); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: simultanous presss deteced")); press_index = Button.press_counter[button_index]; for (uint32_t i = 0; i < MAX_KEYS; i++) if ((Settings.shutter_button[i] & (1<<31)) && ((Settings.shutter_button[i] & 0x03) != shutter_index)) @@ -670,7 +670,7 @@ void ShutterButtonHandler(void) if (Settings.shutter_startrelay[shutter_index] && Settings.shutter_startrelay[shutter_index] <9) { uint8_t pos_press_index = (buttonState == SHT_PRESSED_HOLD) ? 3 : (press_index-1); if (pos_press_index>3) pos_press_index=3; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: shutter %d, button %d = %d (single=1, double=2, tripple=3, hold=4)"), shutter_index+1, button_index+1, pos_press_index+1); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: shutter %d, button %d = %d (single=1, double=2, tripple=3, hold=4)"), shutter_index+1, button_index+1, pos_press_index+1); XdrvMailbox.index = shutter_index +1; last_source = SRC_BUTTON; XdrvMailbox.data_len = 0; @@ -688,7 +688,7 @@ void ShutterButtonHandler(void) CmndShutterStop(); } else { XdrvMailbox.payload = position = (position-1)<<1; - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: shutter %d -> %d"), shutter_index+1, position); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: shutter %d -> %d"), shutter_index+1, position); if (102 == position) { XdrvMailbox.payload = XdrvMailbox.index; CmndShutterToggle(); @@ -734,7 +734,7 @@ void ShutterSetPosition(uint32_t device, uint32_t position) void CmndShutterOpen(void) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload open: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Payload open: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) { XdrvMailbox.index = XdrvMailbox.payload; } @@ -757,7 +757,7 @@ void CmndShutterStopOpen(void) void CmndShutterClose(void) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload close: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Payload close: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) { XdrvMailbox.index = XdrvMailbox.payload; } @@ -781,7 +781,7 @@ void CmndShutterStopClose(void) void CmndShutterToggle(void) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload toggle: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Payload toggle: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) { XdrvMailbox.index = XdrvMailbox.payload; } @@ -816,7 +816,7 @@ void CmndShutterStop(void) uint32_t i = XdrvMailbox.index -1; if (Shutter.direction[i] != 0) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Stop moving %d: dir: %d"), XdrvMailbox.index, Shutter.direction[i]); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Stop moving %d: dir: %d"), XdrvMailbox.index, Shutter.direction[i]); // set stop position 10 steps ahead (0.5sec to allow normal stop) int32_t temp_realpos = Shutter.start_position[i] + ( (Shutter.time[i]+10) * (Shutter.direction[i] > 0 ? 100 : -Shutter.close_velocity[i])); XdrvMailbox.payload = ShutterRealToPercentPosition(temp_realpos, i); @@ -840,7 +840,7 @@ void CmndShutterPosition(void) if (!(Settings.shutter_options[XdrvMailbox.index-1] & 2)) { uint32_t index = XdrvMailbox.index-1; //limit the payload - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Pos. in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, last_source ); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Pos. in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, last_source ); // value 0 with data_len > 0 can mean Open // special handling fo UP,DOWN,TOGGLE,STOP command comming with payload -99 @@ -873,7 +873,7 @@ void CmndShutterPosition(void) Shutter.target_position[index] = ShutterPercentToRealPosition(target_pos_percent, index); //Shutter.accelerator[index] = Shutter.max_pwm_frequency / ((Shutter.motordelay[index] > 0) ? Shutter.motordelay[index] : 1); //Shutter.target_position[index] = XdrvMailbox.payload < 5 ? Settings.shuttercoeff[2][index] * XdrvMailbox.payload : Settings.shuttercoeff[1][index] * XdrvMailbox.payload + Settings.shuttercoeff[0,index]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: lastsource %d:, real %d, target %d, payload %d"), last_source, Shutter.real_position[index] ,Shutter.target_position[index],target_pos_percent); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: lastsource %d:, real %d, target %d, payload %d"), last_source, Shutter.real_position[index] ,Shutter.target_position[index],target_pos_percent); } if ( (target_pos_percent >= 0) && (target_pos_percent <= 100) && abs(Shutter.target_position[index] - Shutter.real_position[index] ) / Shutter.close_velocity[index] > 2) { if (Settings.shutter_options[index] & 4) { @@ -896,7 +896,7 @@ void CmndShutterPosition(void) } if (Shutter.direction[index] != new_shutterdirection) { if ((SHT_OFF_ON__OPEN_CLOSE == Shutter.mode) || (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode)) { - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay5 5s, xdrv %d"), XdrvMailbox.payload); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay5 5s, xdrv %d"), XdrvMailbox.payload); ShutterWaitForMotorStop(index); ExecuteCommandPower(Settings.shutter_startrelay[index], 0, SRC_SHUTTER); ShutterStartInit(index, new_shutterdirection, Shutter.target_position[index]); @@ -911,12 +911,12 @@ void CmndShutterPosition(void) } } else { // now start the motor for the right direction, work for momentary and normal shutters. - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start in dir %d"), Shutter.direction[index]); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Start in dir %d"), Shutter.direction[index]); ShutterStartInit(index, new_shutterdirection, Shutter.target_position[index]); if (Shutter.skip_relay_change == 0) { ExecuteCommandPower(Settings.shutter_startrelay[index] + (new_shutterdirection == 1 ? 0 : 1), 1, SRC_SHUTTER); } - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay6 5s, xdrv %d"), XdrvMailbox.payload); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay6 5s, xdrv %d"), XdrvMailbox.payload); } Shutter.switched_relay = 0; } @@ -1219,7 +1219,7 @@ void CmndShutterCalibration(void) } for (i = 0; i < 5; i++) { Settings.shuttercoeff[i][XdrvMailbox.index -1] = SHT_DIV_ROUND((uint32_t)messwerte[i] * 1000, messwerte[4]); - AddLog_P2(LOG_LEVEL_INFO, PSTR("Settings.shuttercoeff: %d, i: %d, value: %d, messwert %d"), i,XdrvMailbox.index -1,Settings.shuttercoeff[i][XdrvMailbox.index -1], messwerte[i]); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Settings.shuttercoeff: %d, i: %d, value: %d, messwert %d"), i,XdrvMailbox.index -1,Settings.shuttercoeff[i][XdrvMailbox.index -1], messwerte[i]); } ShutterInit(); ResponseCmndIdxChar(XdrvMailbox.data); From e7cd96689f4960772fbd1d5a492582ed5362be75 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Sat, 4 Jul 2020 13:23:35 +0200 Subject: [PATCH 410/581] Shutter reactivate rule trigger during move --- tasmota/xdrv_27_shutter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index 4b132338e..6d0c6e5ce 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -280,7 +280,7 @@ void ShutterReportPosition(bool always, uint32_t index) ResponseJsonEnd(); if (always || (rules_flag.shutter_moving)) { MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); - //XdrvRulesProcess(); //removed because to many exceptions and reboots. + XdrvRulesProcess(); //RulesProcess() now re-entry protected } //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: rules_flag.shutter_moving: %d, moved %d"), rules_flag.shutter_moving, rules_flag.shutter_moved); From c3a056a78f79c25990166f681c396549f2de9b05 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 4 Jul 2020 14:29:15 +0200 Subject: [PATCH 411/581] Minor refactor --- tasmota/xdrv_10_rules.ino | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index adf29d13a..db22183c5 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -749,37 +749,37 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved) bool RulesProcessEvent(char *json_event) { + if (Rules.busy) { return false; } + + Rules.busy = true; bool serviced = false; - if (!Rules.busy) { - Rules.busy = true; - #ifdef USE_DEBUG_DRIVER - ShowFreeMem(PSTR("RulesProcessEvent")); + ShowFreeMem(PSTR("RulesProcessEvent")); #endif - String event_saved = json_event; - // json_event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} - // json_event = {"System":{"Boot":1}} - // json_event = {"SerialReceived":"on"} - invalid but will be expanded to {"SerialReceived":{"Data":"on"}} - char *p = strchr(json_event, ':'); - if ((p != NULL) && !(strchr(++p, ':'))) { // Find second colon - event_saved.replace(F(":"), F(":{\"Data\":")); - event_saved += F("}"); - // event_saved = {"SerialReceived":{"Data":"on"}} - } - event_saved.toUpperCase(); + String event_saved = json_event; + // json_event = {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} + // json_event = {"System":{"Boot":1}} + // json_event = {"SerialReceived":"on"} - invalid but will be expanded to {"SerialReceived":{"Data":"on"}} + char *p = strchr(json_event, ':'); + if ((p != NULL) && !(strchr(++p, ':'))) { // Find second colon + event_saved.replace(F(":"), F(":{\"Data\":")); + event_saved += F("}"); + // event_saved = {"SerialReceived":{"Data":"on"}} + } + event_saved.toUpperCase(); //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Event %s"), event_saved.c_str()); - for (uint32_t i = 0; i < MAX_RULE_SETS; i++) { - if (GetRuleLen(i) && bitRead(Settings.rule_enabled, i)) { - if (RuleSetProcess(i, event_saved)) { serviced = true; } - } + for (uint32_t i = 0; i < MAX_RULE_SETS; i++) { + if (GetRuleLen(i) && bitRead(Settings.rule_enabled, i)) { + if (RuleSetProcess(i, event_saved)) { serviced = true; } } - - Rules.busy = false; } + + Rules.busy = false; + return serviced; } From 0315ef3a3ca23202f0d823a885be706193e0654a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 4 Jul 2020 15:40:38 +0200 Subject: [PATCH 412/581] Add some comments to led commands --- tasmota/support_command.ino | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 44844ff1f..a54b50e89 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1775,8 +1775,9 @@ void CmndAltitude(void) ResponseCmndNumber(Settings.altitude); } -void CmndLedPower(void) -{ +void CmndLedPower(void) { + // If GPIO_LEDLINK (used for network status) then allow up to 4 GPIO_LEDx control using led_power + // If no GPIO_LEDLINK then allow legacy single led GPIO_LED1 control using Settings.ledstate if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_LEDS)) { if (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; } if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { @@ -1811,8 +1812,7 @@ void CmndLedPower(void) } } -void CmndLedState(void) -{ +void CmndLedState(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < MAX_LED_OPTION)) { Settings.ledstate = XdrvMailbox.payload; if (!Settings.ledstate) { @@ -1823,8 +1823,7 @@ void CmndLedState(void) ResponseCmndNumber(Settings.ledstate); } -void CmndLedMask(void) -{ +void CmndLedMask(void) { if (XdrvMailbox.data_len > 0) { Settings.ledmask = XdrvMailbox.payload; } @@ -1833,8 +1832,7 @@ void CmndLedMask(void) ResponseCmndChar(stemp1); } -void CmndLedPwmOff(void) -{ +void CmndLedPwmOff(void) { if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.payload < 0) { Settings.ledpwm_off = 0; @@ -1849,8 +1847,7 @@ void CmndLedPwmOff(void) ResponseCmndNumber(Settings.ledpwm_off); } -void CmndLedPwmOn(void) -{ +void CmndLedPwmOn(void) { if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.payload < 0) { Settings.ledpwm_on = 0; @@ -1865,8 +1862,7 @@ void CmndLedPwmOn(void) ResponseCmndNumber(Settings.ledpwm_on); } -void CmndLedPwmMode(void) -{ +void CmndLedPwmMode(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_LEDS)) { if (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; } if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { From b8afa117434bbf13c4a90cbb2cc167341af76e7f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 4 Jul 2020 17:39:56 +0200 Subject: [PATCH 413/581] Update decode-status.py to python 3.x --- tools/decode-status.py | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/tools/decode-status.py b/tools/decode-status.py index bdffa4ba3..e6e4138bd 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -20,7 +20,7 @@ Requirements: - Python - - pip json pycurl + - pip json requests Instructions: Execute command with option -d to retrieve status report from device or @@ -42,11 +42,10 @@ Example: import io import os.path import json -import pycurl -import urllib2 +import requests +import urllib from sys import exit from optparse import OptionParser -from StringIO import StringIO a_on_off = ["OFF","ON "] @@ -146,11 +145,14 @@ a_setoption = [[ "Distinct MQTT topics per device for Zigbee", "Disable non-json MQTT response", "Enable light fading at start/power on", - "Set PWM Mode from regular PWM to ColorTemp control","", + "Set PWM Mode from regular PWM to ColorTemp control", "Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick", "Implement simpler MAX6675 protocol instead of MAX31855", - "","", - "","","","", + "Enable Wifi", + "Enable Ethernet (ESP32)", + "Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200)", + "Rotary encoder uses rules instead of light control", + "","","", "","","","", "","","","", "","","","" @@ -225,25 +227,19 @@ parser.add_option("-f", "--file", metavar="FILE", (options, args) = parser.parse_args() if (options.device): - buffer = StringIO() loginstr = "" if options.password is not None: - loginstr = "user={}&password={}&".format(urllib2.quote(options.username), urllib2.quote(options.password)) + loginstr = "user={}&password={}&".format(urllib.parse.quote(options.username), urllib.parse.quote(options.password)) url = str("http://{}/cm?{}cmnd=status%200".format(options.device, loginstr)) - c = pycurl.Curl() - c.setopt(c.URL, url) - c.setopt(c.WRITEDATA, buffer) - c.perform() - c.close() - body = buffer.getvalue() - obj = json.loads(body) + res = requests.get(url) + obj = json.loads(res.content) else: jsonfile = options.jsonfile with open(jsonfile, "r") as fp: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200627 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200704 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From 407d36c0550ec0d985c7c9252bd345ddbc00f9a1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 4 Jul 2020 18:34:23 +0200 Subject: [PATCH 414/581] Update support_features.ino --- tasmota/support_features.ino | 168 +++++++++++++++++------------------ 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 4dc1ee416..3d58d00d0 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -25,7 +25,7 @@ void GetFeatures(void) { feature_drv1 = 0x00000000; -#ifdef USE_ENERGY_MARGIN_DETECTION +#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_MARGIN_DETECTION) feature_drv1 |= 0x00000001; // xdrv_03_energy.ino #endif #ifdef USE_LIGHT @@ -49,10 +49,10 @@ void GetFeatures(void) #ifdef USE_WEBSERVER feature_drv1 |= 0x00000080; // xdrv_01_webserver.ino #endif -#ifdef WEBSERVER_ADVERTISE +#if defined(USE_WEBSERVER) && defined(WEBSERVER_ADVERTISE) feature_drv1 |= 0x00000100; // xdrv_01_webserver.ino #endif -#ifdef USE_EMULATION_HUE +#if defined(USE_WEBSERVER) && defined(USE_EMULATION_HUE) feature_drv1 |= 0x00000200; // xdrv_20_hue.ino #endif //#if (MQTT_LIBRARY_TYPE == MQTT_PUBSUBCLIENT) @@ -67,13 +67,13 @@ void GetFeatures(void) #ifdef MQTT_HOST_DISCOVERY feature_drv1 |= 0x00002000; // xdrv_02_mqtt.ino #endif -#ifdef USE_ARILUX_RF +#if defined(USE_LIGHT) && defined(USE_ARILUX_RF) feature_drv1 |= 0x00004000; // xdrv_04_light.ino #endif #if defined(USE_LIGHT) && defined(USE_WS2812) feature_drv1 |= 0x00008000; // xdrv_04_light.ino #endif -#ifdef USE_WS2812_DMA +#if defined(USE_LIGHT) && defined(USE_WS2812) && defined(USE_WS2812_DMA) feature_drv1 |= 0x00010000; // xdrv_04_light.ino #endif #if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) @@ -82,7 +82,7 @@ void GetFeatures(void) #ifdef USE_IR_HVAC feature_drv1 |= 0x00040000; // xdrv_05_irremote.ino #endif -#ifdef USE_IR_RECEIVE +#if defined(USE_IR_REMOTE) && defined(USE_IR_RECEIVE) feature_drv1 |= 0x00080000; // xdrv_05_irremote.ino #endif #ifdef USE_DOMOTICZ @@ -100,10 +100,10 @@ void GetFeatures(void) #ifdef USE_TIMERS feature_drv1 |= 0x01000000; // xdrv_09_timers.ino #endif -#ifdef USE_SUNRISE +#if defined(USE_TIMERS) && defined(USE_SUNRISE) feature_drv1 |= 0x02000000; // xdrv_09_timers.ino #endif -#ifdef USE_TIMERS_WEB +#if defined(USE_TIMERS) && defined(USE_TIMERS_WEB) feature_drv1 |= 0x04000000; // xdrv_09_timers.ino #endif #ifdef USE_RULES @@ -118,7 +118,7 @@ void GetFeatures(void) #ifdef USE_SMARTCONFIG feature_drv1 |= 0x40000000; // support.ino - removed with version 6.6.0.21 #endif -#ifdef USE_ENERGY_POWER_LIMIT +#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_POWER_LIMIT) feature_drv1 |= 0x80000000; // xdrv_03_energy.ino #endif @@ -141,28 +141,28 @@ void GetFeatures(void) #ifdef FIRMWARE_KNX_NO_EMULATION feature_drv2 |= 0x00000010; // user_config(_override).h #endif -#ifdef USE_DISPLAY_MODES1TO5 +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_MODES1TO5) feature_drv2 |= 0x00000020; // xdrv_13_display.ino #endif -#ifdef USE_DISPLAY_GRAPH +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_GRAPH) feature_drv2 |= 0x00000040; // xdrv_13_display.ino #endif -#ifdef USE_DISPLAY_LCD +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_LCD) feature_drv2 |= 0x00000080; // xdsp_01_lcd.ino #endif -#ifdef USE_DISPLAY_SSD1306 +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_SSD1306) feature_drv2 |= 0x00000100; // xdsp_02_ssd1306.ino #endif -#ifdef USE_DISPLAY_MATRIX +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_MATRIX) feature_drv2 |= 0x00000200; // xdsp_03_matrix.ino #endif -#ifdef USE_DISPLAY_ILI9341 +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_ILI9341) feature_drv2 |= 0x00000400; // xdsp_04_ili9341.ino #endif -#ifdef USE_DISPLAY_EPAPER_29 +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_EPAPER_29) feature_drv2 |= 0x00000800; // xdsp_05_epaper.ino #endif -#ifdef USE_DISPLAY_SH1106 +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_SH1106) feature_drv2 |= 0x00001000; // xdsp_06_sh1106.ino #endif #ifdef USE_MP3_PLAYER @@ -236,7 +236,7 @@ void GetFeatures(void) #ifdef USE_ENERGY_SENSOR feature_sns1 |= 0x00000004; // xdrv_03_energy.ino #endif -#ifdef USE_PZEM004T +#if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM004T) feature_sns1 |= 0x00000008; // xnrg_03_pzem004t.ino #endif #ifdef USE_DS18B20 @@ -251,40 +251,40 @@ void GetFeatures(void) #ifdef USE_DHT feature_sns1 |= 0x00000080; // xsns_06_dht.ino #endif -#ifdef USE_SHT +#if defined(USE_I2C) && defined(USE_SHT) feature_sns1 |= 0x00000100; // xsns_07_sht1x.ino #endif -#ifdef USE_HTU +#if defined(USE_I2C) && defined(USE_HTU) feature_sns1 |= 0x00000200; // xsns_08_htu21.ino #endif -#ifdef USE_BMP +#if defined(USE_I2C) && defined(USE_BMP) feature_sns1 |= 0x00000400; // xsns_09_bmp.ino #endif -#ifdef USE_BME680 +#if defined(USE_I2C) && defined(USE_BMP) && defined(USE_BME680) feature_sns1 |= 0x00000800; // xsns_09_bmp.ino - BME680 #endif -#ifdef USE_BH1750 +#if defined(USE_I2C) && defined(USE_BH1750) feature_sns1 |= 0x00001000; // xsns_10_bh1750.ino #endif -#ifdef USE_VEML6070 +#if defined(USE_I2C) && defined(USE_VEML6070) feature_sns1 |= 0x00002000; // xsns_11_veml6070.ino #endif -#ifdef USE_ADS1115_I2CDEV +#if defined(USE_I2C) && defined(USE_ADS1115_I2CDEV) feature_sns1 |= 0x00004000; // xsns_12_ads1115_i2cdev.ino #endif -#ifdef USE_ADS1115 +#if defined(USE_I2C) && defined(USE_ADS1115) feature_sns1 |= 0x00008000; // xsns_12_ads1115.ino #endif -#ifdef USE_INA219 +#if defined(USE_I2C) && defined(USE_INA219) feature_sns1 |= 0x00010000; // xsns_13_ina219.ino #endif -#ifdef USE_SHT3X +#if defined(USE_I2C) && defined(USE_SHT3X) feature_sns1 |= 0x00020000; // xsns_14_sht3x.ino #endif #ifdef USE_MHZ19 feature_sns1 |= 0x00040000; // xsns_15_mhz19.ino #endif -#ifdef USE_TSL2561 +#if defined(USE_I2C) && defined(USE_TSL2561) feature_sns1 |= 0x00080000; // xsns_16_tsl2561.ino #endif #ifdef USE_SENSEAIR @@ -293,31 +293,31 @@ void GetFeatures(void) #ifdef USE_PMS5003 feature_sns1 |= 0x00200000; // xsns_18_pms5003.ino #endif -#ifdef USE_MGS +#if defined(USE_I2C) && defined(USE_MGS) feature_sns1 |= 0x00400000; // xsns_19_mgs.ino #endif #ifdef USE_NOVA_SDS feature_sns1 |= 0x00800000; // xsns_20_novasds.ino #endif -#ifdef USE_SGP30 +#if defined(USE_I2C) && defined(USE_SGP30) feature_sns1 |= 0x01000000; // xsns_21_sgp30.ino #endif #ifdef USE_SR04 feature_sns1 |= 0x02000000; // xsns_22_sr04.ino #endif -#ifdef USE_SDM120 +#if defined(USE_ENERGY_SENSOR) && defined(USE_SDM120) feature_sns1 |= 0x04000000; // xnrg_08_sdm120.ino #endif -#ifdef USE_SI1145 +#if defined(USE_I2C) && defined(USE_SI1145) feature_sns1 |= 0x08000000; // xsns_24_si1145.ino #endif -#ifdef USE_SDM630 +#if defined(USE_ENERGY_SENSOR) && defined(USE_SDM630) feature_sns1 |= 0x10000000; // xnrg_10_sdm630.ino #endif -#ifdef USE_LM75AD +#if defined(USE_I2C) && defined(USE_LM75AD) feature_sns1 |= 0x20000000; // xsns_26_lm75ad.ino #endif -#ifdef USE_APDS9960 +#if defined(USE_I2C) && defined(USE_APDS9960) feature_sns1 |= 0x40000000; // xsns_27_apds9960.ino #endif #ifdef USE_TM1638 @@ -328,58 +328,58 @@ void GetFeatures(void) feature_sns2 = 0x00000000; -#ifdef USE_MCP230xx +#if defined(USE_I2C) && defined(USE_MCP230xx) feature_sns2 |= 0x00000001; // xsns_29_mcp230xx.ino #endif -#ifdef USE_MPR121 +#if defined(USE_I2C) && defined(USE_MPR121) feature_sns2 |= 0x00000002; // xsns_30_mpr121.ino #endif -#ifdef USE_CCS811 +#if defined(USE_I2C) && defined(USE_CCS811) feature_sns2 |= 0x00000004; // xsns_31_ccs811.ino #endif -#ifdef USE_MPU6050 +#if defined(USE_I2C) && defined(USE_MPU6050) feature_sns2 |= 0x00000008; // xsns_32_mpu6050.ino #endif -#ifdef USE_MCP230xx_OUTPUT +#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_OUTPUT) feature_sns2 |= 0x00000010; // xsns_29_mcp230xx.ino #endif -#ifdef USE_MCP230xx_DISPLAYOUTPUT +#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_DISPLAYOUTPUT) feature_sns2 |= 0x00000020; // xsns_29_mcp230xx.ino #endif -#ifdef USE_HLW8012 +#if defined(USE_ENERGY_SENSOR) && defined(USE_HLW8012) feature_sns2 |= 0x00000040; // xnrg_01_hlw8012.ino #endif -#ifdef USE_CSE7766 +#if defined(USE_ENERGY_SENSOR) && defined(USE_CSE7766) feature_sns2 |= 0x00000080; // xnrg_02_cse7766.ino #endif -#ifdef USE_MCP39F501 +#if defined(USE_ENERGY_SENSOR) && defined(USE_MCP39F501) feature_sns2 |= 0x00000100; // xnrg_04_mcp39f501.ino #endif -#ifdef USE_PZEM_AC +#if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM_AC) feature_sns2 |= 0x00000200; // xnrg_05_pzem_ac.ino #endif -#ifdef USE_DS3231 +#if defined(USE_I2C) && defined(USE_DS3231) feature_sns2 |= 0x00000400; // xsns_33_ds3231.ino #endif #ifdef USE_HX711 feature_sns2 |= 0x00000800; // xsns_34_hx711.ino #endif -#ifdef USE_PZEM_DC +#if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM_DC) feature_sns2 |= 0x00001000; // xnrg_06_pzem_dc.ino #endif #if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) feature_sns2 |= 0x00002000; // xsns_35_tx20.ino #endif -#ifdef USE_MGC3130 +#if defined(USE_I2C) && defined(USE_MGC3130) feature_sns2 |= 0x00004000; // xsns_36_mgc3130.ino #endif #ifdef USE_RF_SENSOR feature_sns2 |= 0x00008000; // xsns_37_rfsensor.ino #endif -#ifdef USE_THEO_V2 +#if defined(USE_RF_SENSOR) && defined(USE_THEO_V2) feature_sns2 |= 0x00010000; // xsns_37_rfsensor.ino #endif -#ifdef USE_ALECTO_V2 +#if defined(USE_RF_SENSOR) && defined(USE_ALECTO_V2) feature_sns2 |= 0x00020000; // xsns_37_rfsensor.ino #endif #ifdef USE_AZ7798 @@ -391,37 +391,37 @@ void GetFeatures(void) #ifdef USE_PN532_HSU feature_sns2 |= 0x00100000; // xsns_40_pn532.ino #endif -#ifdef USE_MAX44009 +#if defined(USE_I2C) && defined(USE_MAX44009) feature_sns2 |= 0x00200000; // xsns_41_max44009.ino #endif -#ifdef USE_SCD30 +#if defined(USE_I2C) && defined(USE_SCD30) feature_sns2 |= 0x00400000; // xsns_42_scd30.ino #endif #ifdef USE_HRE feature_sns2 |= 0x00800000; // xsns_43_hre.ino #endif -#ifdef USE_ADE7953 +#if defined(USE_ENERGY_SENSOR) && defined(USE_ADE7953) feature_sns2 |= 0x01000000; // xnrg_07_ade7953.ino #endif -#ifdef USE_SPS30 +#if defined(USE_I2C) && defined(USE_SPS30) feature_sns2 |= 0x02000000; // xsns_44_sps30.ino #endif -#ifdef USE_VL53L0X +#if defined(USE_I2C) && defined(USE_VL53L0X) feature_sns2 |= 0x04000000; // xsns_45_vl53l0x.ino #endif -#ifdef USE_MLX90614 +#if defined(USE_I2C) && defined(USE_MLX90614) feature_sns2 |= 0x08000000; // xsns_46_MLX90614.ino #endif #ifdef USE_MAX31865 feature_sns2 |= 0x10000000; // xsns_47-max31865.ino #endif -#ifdef USE_CHIRP +#if defined(USE_I2C) && defined(USE_CHIRP) feature_sns2 |= 0x20000000; // xsns_48_chirp.ino #endif -#ifdef USE_SOLAX_X1 +#if defined(USE_ENERGY_SENSOR) && defined(USE_SOLAX_X1) feature_sns2 |= 0x40000000; // xnrg_12_solaxX1.ino #endif -#ifdef USE_PAJ7620 +#if defined(USE_I2C) && defined(USE_PAJ7620) feature_sns2 |= 0x80000000; // xsns_50_paj7620.ino #endif @@ -441,13 +441,13 @@ void GetFeatures(void) #ifdef USE_SML_M feature5 |= 0x00000008; // xsns_53_sml.ino #endif -#ifdef USE_INA226 +#if defined(USE_I2C) && defined(USE_INA226) feature5 |= 0x00000010; // xsns_54_ina226.ino #endif #ifdef USE_A4988_STEPPER feature5 |= 0x00000020; // xdrv_25_A4988.ino #endif -#ifdef USE_DDS2382 +#if defined(USE_ENERGY_SENSOR) && defined(USE_DDS2382) feature5 |= 0x00000040; // xnrg_09_dds2382.ino #endif #ifdef USE_SM2135 @@ -456,10 +456,10 @@ void GetFeatures(void) #ifdef USE_SHUTTER feature5 |= 0x00000100; // xdrv_027_shutter.ino #endif -#ifdef USE_PCF8574 +#if defined(USE_I2C) && defined(USE_PCF8574) feature5 |= 0x00000200; // xdrv_028_pcf8574.ino #endif -#ifdef USE_DDSU666 +#if defined(USE_ENERGY_SENSOR) && defined(USE_DDSU666) feature5 |= 0x00000400; // xnrg_11_ddsu666.ino #endif #ifdef USE_DEEPSLEEP @@ -471,7 +471,7 @@ void GetFeatures(void) #ifdef USE_SONOFF_RF feature5 |= 0x00002000; // xdrv_06_snfbridge.ino #endif -#ifdef USE_SONOFF_L1 +#if defined(USE_LIGHT) && defined(USE_SONOFF_L1) feature5 |= 0x00004000; // xlgt_05_sonoff_l1.ino #endif #ifdef USE_EXS_DIMMER @@ -480,19 +480,19 @@ void GetFeatures(void) #ifdef USE_TASMOTA_CLIENT feature5 |= 0x00010000; // xdrv_31_tasmota_client.ino #endif -#ifdef USE_HIH6 +#if defined(USE_I2C) && defined(USE_HIH6) feature5 |= 0x00020000; // xsns_55_hih_series.ino #endif #ifdef USE_HPMA feature5 |= 0x00040000; // xsns_56_hpma.ino #endif -#ifdef USE_TSL2591 +#if defined(USE_I2C) && defined(USE_TSL2591) feature5 |= 0x00080000; // xsns_57_tsl2591.ino #endif -#ifdef USE_DHT12 +#if defined(USE_I2C) && defined(USE_DHT12) feature5 |= 0x00100000; // xsns_58_dht12.ino #endif -#ifdef USE_DS1624 +#if defined(USE_I2C) && defined(USE_DS1624) feature5 |= 0x00200000; // xsns_59_ds1624.ino #endif #ifdef USE_GPS @@ -510,13 +510,13 @@ void GetFeatures(void) #ifdef USE_HM10 feature5 |= 0x04000000; // xsns_62_MI_HM10.ino #endif -#ifdef USE_LE01MR +#if defined(USE_ENERGY_SENSOR) && defined(USE_LE01MR) feature5 |= 0x08000000; // xnrg_13_fif_le01mr.ino #endif -#ifdef USE_AHT1x +#if defined(USE_I2C) && defined(USE_AHT1x) feature5 |= 0x10000000; // xsns_63_aht1x.ino #endif -#ifdef USE_WEMOS_MOTOR_V1 +#if defined(USE_I2C) && defined(USE_WEMOS_MOTOR_V1) feature5 |= 0x20000000; // xdrv_34_wemos_motor_v1.ino #endif #ifdef USE_DEVICE_GROUPS @@ -539,16 +539,16 @@ void GetFeatures(void) #ifdef USE_SONOFF_D1 feature6 |= 0x00000004; // xdrv_37_sonoff_d1.ino #endif -#ifdef USE_HDC1080 +#if defined(USE_I2C) && defined(USE_HDC1080) feature6 |= 0x00000008; // xsns_65_hdc1080.ino #endif -#ifdef USE_IAQ +#if defined(USE_I2C) && defined(USE_IAQ) feature6 |= 0x00000010; // xsns_66_iAQ.ino #endif -#ifdef USE_DISPLAY_SEVENSEG +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_SEVENSEG) feature6 |= 0x00000020; // xdsp_11_sevenseg.ino #endif -#ifdef USE_AS3935 +#if defined(USE_I2C) && defined(USE_AS3935) feature6 |= 0x00000040; // xsns_67_as3935.ino #endif #ifdef USE_PING @@ -563,28 +563,28 @@ void GetFeatures(void) #ifdef USE_THERMOSTAT feature6 |= 0x00000400; // xdrv_39_heating.ino #endif -#ifdef USE_VEML6075 +#if defined(USE_I2C) && defined(USE_VEML6075) feature6 |= 0x00000800; // xsns_70_veml6075.ino #endif -#ifdef USE_VEML7700 +#if defined(USE_I2C) && defined(USE_VEML7700) feature6 |= 0x00001000; // xsns_71_veml7700.ino #endif -#ifdef USE_MCP9808 +#if defined(USE_I2C) && defined(USE_MCP9808) feature6 |= 0x00002000; // xsns_72_mcp9808.ino #endif -#ifdef USE_BL0940 +#if defined(USE_ENERGY_SENSOR) && defined(USE_BL0940) feature6 |= 0x00004000; // xnrg_14_bl0940.ino #endif #ifdef USE_TELEGRAM feature6 |= 0x00008000; // xdrv_40_telegram.ino #endif -#ifdef USE_HP303B +#if defined(USE_I2C) && defined(USE_HP303B) feature6 |= 0x00010000; // xsns_73_hp303b.ino #endif #ifdef USE_TCP_BRIDGE feature6 |= 0x00020000; // xdrv_41_tcp_bridge.ino #endif -#ifdef USE_TELEINFO +#if defined(USE_ENERGY_SENSOR) && defined(USE_TELEINFO) feature6 |= 0x00040000; // xnrg_15_teleinfo.ino #endif #ifdef USE_LMT01 @@ -604,10 +604,10 @@ void GetFeatures(void) // feature6 |= 0x10000000; // feature6 |= 0x20000000; -#ifdef USE_ETHERNET +#if defined(ESP32) && defined(USE_ETHERNET) feature6 |= 0x40000000; // xdrv_82_ethernet.ino #endif -#ifdef USE_WEBCAM +#if defined(ESP32) && defined(USE_WEBCAM) feature6 |= 0x80000000; // xdrv_81_webcam.ino #endif } From 173a6d917b61da223992a3c29e6fe47c34b1dfea Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 4 Jul 2020 19:59:59 +0200 Subject: [PATCH 415/581] Zigbee EZSP minor improvements --- tasmota/xdrv_23_zigbee_0_constants.ino | 1 + tasmota/xdrv_23_zigbee_7_statemachine.ino | 24 +++++++++++------------ tasmota/xdrv_23_zigbee_8_parsers.ino | 14 +++++++++++-- tasmota/xdrv_23_zigbee_9_serial.ino | 23 ++++++++++++++++++++++ 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index 92af3a046..ac63d9878 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -27,6 +27,7 @@ #endif #define OCCUPANCY "Occupancy" // global define for Aqara +#define ZIGBEE_EZSP_RESET_LED 4 // Led number to drive the EZSP Reset pin typedef uint64_t Z_IEEEAddress; typedef uint16_t Z_ShortAddress; diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index bfc07793e..bc7fccf06 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -647,11 +647,11 @@ ZBM(ZBR_VERSION, EZSP_version, 0x00, 0x08, 0x02) // 00000802 - expect v8, p // general configuration // inspired from bellows: https://github.com/zigpy/bellows/blob/dev/bellows/config/ezsp.py -ZBM(ZBS_SET_ADDR_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_KEY_TABLE_SIZE, 0x04, 0x00) // 53001E0400 +ZBM(ZBS_SET_ADDR_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_KEY_TABLE_SIZE, 0x02, 0x00) // 53001E0400 ZBM(ZBS_SET_MCAST_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MULTICAST_TABLE_SIZE, 0x10, 0x00) // 5300061000 ZBM(ZBS_SET_STK_PROF, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_STACK_PROFILE, 0x02, 0x00) // 53000C0200 ZBM(ZBS_SET_SEC_LEVEL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SECURITY_LEVEL, 0x05, 0x00) // 53000D0500 -ZBM(ZBS_SET_MAX_DEVICES, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MAX_END_DEVICE_CHILDREN, 0x18, 0x00) // 5300111800 +ZBM(ZBS_SET_MAX_DEVICES, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MAX_END_DEVICE_CHILDREN, 0x20, 0x00) // 5300111800 ZBM(ZBS_SET_INDIRECT_TMO, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_INDIRECT_TRANSMISSION_TIMEOUT, 0x00, 0x1E) // 530012001E ZBM(ZBS_SET_TC_CACHE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_TRUST_CENTER_ADDRESS_CACHE_SIZE, 0x02, 0x00) // 5300190200 ZBM(ZBS_SET_ROUTE_TBL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SOURCE_ROUTE_TABLE_SIZE, 0x10, 0x00) // 53001A1000 @@ -671,21 +671,21 @@ ZBM(ZBR_SET_OK2, 0x00, 0x00 /*high*/, 0x00 /*ok*/) // 000000 - TODO why does // Add Endpoints ZBM(ZBS_ADD_ENDPOINT1, EZSP_addEndpoint, 0x00 /*high*/, 0x01 /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, - 0x0E /* inputClusterCount */, // actually all clusters will be received + 0x00 /* inputClusterCount */, // actually all clusters will be received 0X00 /* outputClusterCount */, // 02000104010500000000 - 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 - 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 - 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 - 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 + // 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 + // 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 + // 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 + // 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 ) ZBM(ZBS_ADD_ENDPOINTB, EZSP_addEndpoint, 0x00 /*high*/, 0x0B /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, - 0x0E /* inputClusterCount */, // actually all clusters will be received + 0x00 /* inputClusterCount */, // actually all clusters will be received 0X00 /* outputClusterCount */, // 02000B04010500000000 - 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 - 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 - 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 - 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 + // 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 + // 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 + // 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 + // 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 ) ZBM(ZBR_ADD_ENDPOINT, EZSP_addEndpoint, 0x00 /*high*/, 0x00 /*ok*/) // 020000 diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 57313f687..d1b5d6b05 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -1026,9 +1026,19 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { // // Callback for loading Zigbee configuration from Flash, called by the state machine // +// value = 0 : drive reset pin and halt MCU +// value = 1 : release the reset pin, restart int32_t EZ_Reset_Device(uint8_t value) { - // TODO - GPIO is hardwired to GPIO4 - digitalWrite(4, value ? HIGH : LOW); + // we use Led4i to drive the reset pin. Since it is reverted we need to pass 1 to start reset, and 0 to release reset + if (PinUsed(GPIO_LED4, ZIGBEE_EZSP_RESET_LED - 1)) { + SetLedPowerIdx(ZIGBEE_EZSP_RESET_LED - 1, value ? 0 : 1); + } else { + // no GPIO so we use software Reset instead + if (value) { // send reset only when we are supposed to release reset + uint8_t ezsp_reset[1] = { 0xC0 }; // EZSP ASH Reset + ZigbeeEZSPSendRaw(ezsp_reset, sizeof(ezsp_reset), true); + } + } return 0; // continue } diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index 75c33e387..354bb507a 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -31,6 +31,9 @@ const uint8_t ZIGBEE_EZSP_CANCEL = 0x1A; // cancel byte const uint8_t ZIGBEE_EZSP_EOF = 0x7E; // end of frame const uint8_t ZIGBEE_EZSP_ESCAPE = 0x7D; // escape byte +const uint32_t ZIGBEE_LED_RECEIVE = 0; // LED<1> blinks when receiving +const uint32_t ZIGBEE_LED_SEND = 0; // LED<2> blinks when receiving + class EZSP_Serial_t { public: uint8_t to_ack = 0; // 0..7, frame number of next id to send @@ -144,12 +147,17 @@ void ZigbeeInputLoop(void) { static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte static bool escape = false; // was the previous byte an escape? bool frame_complete = false; // frame is ready and complete + bool led_status_on = false; // did we turn on the led receive led // Receive only valid EZSP frames: // 1A - Cancel - cancel all previous bytes // 7D - Escape byte - following byte is escaped // 7E - end of frame while (ZigbeeSerial->available()) { + // turn on receive LED<1> + SetLedPowerIdx(ZIGBEE_LED_RECEIVE, 1); + led_status_on = true; // don't forget to switch it off + yield(); uint8_t zigbee_in_byte = ZigbeeSerial->read(); AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len()); @@ -194,6 +202,10 @@ void ZigbeeInputLoop(void) { zigbee_polling_window = millis(); // Wait for more data } // adding bytes } // while (ZigbeeSerial->available()) + // turn receive led off + if (led_status_on) { + SetLedPowerIdx(ZIGBEE_LED_RECEIVE, 0); + } uint32_t frame_len = zigbee_buffer->len(); if (frame_complete || (frame_len && (millis() > (zigbee_polling_window + ZIGBEE_POLLING)))) { @@ -402,6 +414,8 @@ void ZigbeeEZSPSend_Out(uint8_t out_byte) { // - send frame // send_cancel: should we first send a EZSP_CANCEL (0x1A) before the message to clear any leftover void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { + bool led_status_on = false; + if ((len < 1) || (len > 252)) { // abort, message cannot be less than 2 bytes for CMD1 and CMD2 AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEE_EZSP_SENT ": bad message len %d"), len); @@ -409,6 +423,10 @@ void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { } uint8_t data_len = len - 2; // removing CMD1 and CMD2 + // turn send led on + SetLedPowerIdx(ZIGBEE_LED_SEND, 1); + led_status_on = true; + if (ZigbeeSerial) { if (send_cancel) { ZigbeeSerial->write(ZIGBEE_EZSP_CANCEL); // 0x1A @@ -448,6 +466,11 @@ void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { // finally send End of Frame ZigbeeSerial->write(ZIGBEE_EZSP_EOF); // 0x1A } + // turn send led off + if (led_status_on) { + SetLedPowerIdx(ZIGBEE_LED_SEND, 0); + } + // Now send a MQTT message to report the sent message char hex_char[(len * 2) + 2]; AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT_RAW " %s"), From 41a32200b63fe7b97a54453734390c1bdc97bba9 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 4 Jul 2020 20:24:04 +0200 Subject: [PATCH 416/581] Use Tasmota freezed stage version... identified as core 2.8.0. Give the opportunity in future to do all core related optimizations in this build --- platformio_override_sample.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 902675fe4..9b43cd6a3 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -88,7 +88,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage platform = espressif8266@2.5.3 -platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#52b3e5b7b3ccedcede665682f7896b637b64dbf5 +platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.8.0-tasmota/esp8266-2.8.0.zip build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From afa20ca1f728c64e28e3bac9979ed7db1b348c1c Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 5 Jul 2020 08:55:34 +0200 Subject: [PATCH 417/581] fix ed300l bug, fix esp32 set bd bug --- tasmota/xsns_53_sml.ino | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index bf46ace85..6a7019381 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -958,6 +958,9 @@ double dval; if (*cp==0x64 && *cpx==0 && *(cpx+1)==0x01 && *(cpx+2)==0x08 && *(cpx+3)==0) { sml_status[g_mindex]=*(cp+3); } + if (*cp==0x63 && *cpx==0 && *(cpx+1)==0x01 && *(cpx+2)==0x08 && *(cpx+3)==0) { + sml_status[g_mindex]=*(cp+2); + } #endif cp=skip_sml(cp,&result); @@ -2197,11 +2200,13 @@ uint32_t SML_SetBaud(uint32_t meter, uint32_t br) { #ifdef ESP32 meter_ss[meter]->flush(); + meter_ss[meter]->updateBaudRate(br); + /* if (meter_desc_p[meter].type=='M') { meter_ss[meter]->begin(br,SERIAL_8E1,meter_desc_p[meter].srcpin,meter_desc_p[meter].trxpin); } else { meter_ss[meter]->begin(br,SERIAL_8N1,meter_desc_p[meter].srcpin,meter_desc_p[meter].trxpin); - } + }*/ #else if (meter_ss[meter]->begin(br)) { meter_ss[meter]->flush(); From 876505a2c3f5220314ca3c205edba7b5766b4a9c Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sun, 5 Jul 2020 08:59:42 +0200 Subject: [PATCH 418/581] Update xsns_53_sml.ino --- tasmota/xsns_53_sml.ino | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index 6a7019381..65d788d8c 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -2201,12 +2201,6 @@ uint32_t SML_SetBaud(uint32_t meter, uint32_t br) { #ifdef ESP32 meter_ss[meter]->flush(); meter_ss[meter]->updateBaudRate(br); - /* - if (meter_desc_p[meter].type=='M') { - meter_ss[meter]->begin(br,SERIAL_8E1,meter_desc_p[meter].srcpin,meter_desc_p[meter].trxpin); - } else { - meter_ss[meter]->begin(br,SERIAL_8N1,meter_desc_p[meter].srcpin,meter_desc_p[meter].trxpin); - }*/ #else if (meter_ss[meter]->begin(br)) { meter_ss[meter]->flush(); From 997e85b54a42e3d561ddc4c6f8cc2f407fe9bbb5 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Sun, 5 Jul 2020 09:57:10 +0200 Subject: [PATCH 419/581] Update Italian language Fix some typos (space between words or uppercase/lowercase) Tuining text strings. --- tasmota/language/it_IT.h | 82 ++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 5d5365222..3623f861b 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -59,7 +59,7 @@ #define D_BATT "Batt" // Short for Battery #define D_BLINK "Lampeggia" #define D_BLINKOFF "Lampeggia OFF" -#define D_BOOT_COUNT "Numero di boot" +#define D_BOOT_COUNT "Numero boot" #define D_BRIGHTLIGHT "Luminoso" #define D_BSSID "BSSId" #define D_BUTTON "Pulsante" @@ -81,13 +81,13 @@ #define D_DARKLIGHT "Scuro" #define D_DEBUG "Debug" #define D_DEWPOINT "Punto rugiada" // -#define D_DISABLED "Disabilitato" +#define D_DISABLED "Disabilitato/a" #define D_DISTANCE "Distanza" #define D_DNS_SERVER "Server DNS" #define D_DONE "Completato" #define D_DST_TIME "DST" #define D_ECO2 "eCOâ‚‚" -#define D_EMULATION "Emulazione" +#define D_EMULATION "Tipo emulazione" #define D_ENABLED "Abilitato" #define D_ERASE "Cancella" #define D_ERROR "Errore" @@ -138,13 +138,13 @@ #define D_POWERUSAGE_REACTIVE "Potenza reattiva" #define D_PRESSURE "Pressione" #define D_PRESSUREATSEALEVEL "Pressione al livello del mare" -#define D_PROGRAM_FLASH_SIZE "Dimensione flash programma" +#define D_PROGRAM_FLASH_SIZE "Dimensione flash" #define D_PROGRAM_SIZE "Dimensione programma" #define D_PROJECT "Progetto" #define D_RAIN "Pioggia" #define D_RANGE "Intervallo" #define D_RECEIVED "Ricevuto" -#define D_RESTART "Riavvio" +#define D_RESTART "Riavvia" #define D_RESTARTING "Riavvio" #define D_RESTART_REASON "Causa riavvio" #define D_RESTORE "ripristino" @@ -153,7 +153,7 @@ #define D_SAVE "Salva" #define D_SENSOR "Sensore" #define D_SSID "SSID" -#define D_START "Avvia" +#define D_START "Esegui" #define D_STD_TIME "STD" #define D_STOP "Stop" #define D_SUBNET_MASK "Maschera sottorete" @@ -170,8 +170,8 @@ #define D_TRANSMIT "Trasmesso" #define D_TRUE "Vero" #define D_TVOC "TVOC" -#define D_UPGRADE "Aggiorna" -#define D_UPLOAD "Invio" +#define D_UPGRADE "aggiornamento" +#define D_UPLOAD "Caricamento" #define D_UPTIME "Tempo accensione" #define D_USER "Utente" #define D_UTC_TIME "UTC" @@ -237,8 +237,8 @@ #define D_WEBSERVER_STOPPED "Server web arrestato" #define D_FILE_NOT_FOUND "File non trovato" #define D_REDIRECTED "Redirezione al captive portal" -#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Impostazione Wifimanager come AccessPoint e Station" -#define D_WIFIMANAGER_SET_ACCESSPOINT "Impostazione Wifimanager come AccessPoint" +#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Impostazione Wifimanager come Access Point e Station" +#define D_WIFIMANAGER_SET_ACCESSPOINT "Impostazione Wifimanager come Access Point" #define D_TRYING_TO_CONNECT "Tentativo connessione dispositivo alla rete" #define D_RESTART_IN "Riavvio tra" @@ -247,7 +247,7 @@ #define D_BUTTON_TOGGLE "ON/OFF" #define D_CONFIGURATION "Configurazione" #define D_INFORMATION "Informazioni" -#define D_FIRMWARE_UPGRADE "Aggiornamento firmware" +#define D_FIRMWARE_UPGRADE "Aggiorna firmware" #define D_CONSOLE "Console" #define D_CONFIRM_RESTART "Conferma riavvio" @@ -255,8 +255,8 @@ #define D_CONFIGURE_WIFI "Configura WiFi" #define D_CONFIGURE_MQTT "Configura MQTT" #define D_CONFIGURE_DOMOTICZ "Configura Domoticz" -#define D_CONFIGURE_LOGGING "Configura registrazione" -#define D_CONFIGURE_OTHER "Configura extra" +#define D_CONFIGURE_LOGGING "Livello registro" +#define D_CONFIGURE_OTHER "Altre impostazioni" #define D_CONFIRM_RESET_CONFIGURATION "Conferma ripristino configurazione" #define D_RESET_CONFIGURATION "Ripristino configurazione" #define D_BACKUP_CONFIGURATION "Backup configurazione" @@ -276,7 +276,7 @@ #define D_SCAN_DONE "Scansione completata" #define D_NO_NETWORKS_FOUND "Nessuna rete trovata" #define D_REFRESH_TO_SCAN_AGAIN "Aggiorna per nuova scansione" -#define D_DUPLICATE_ACCESSPOINT "AccessPoint duplicato" +#define D_DUPLICATE_ACCESSPOINT "Access Point duplicato" #define D_SKIPPING_LOW_QUALITY "Ignorato a causa di bassa qualità" #define D_RSSI "RSSI" #define D_WEP "WEP" @@ -289,17 +289,17 @@ #define D_MQTT_PARAMETERS "Parametri MQTT" #define D_CLIENT "Client" -#define D_FULL_TOPIC "Full Topic" +#define D_FULL_TOPIC "Full topic" -#define D_LOGGING_PARAMETERS "Parametri registrazione" -#define D_SERIAL_LOG_LEVEL "Livello registrazione seriale" -#define D_MQTT_LOG_LEVEL "Livello registrazione MQTT" -#define D_WEB_LOG_LEVEL "Livello registrazione web" -#define D_SYS_LOG_LEVEL "Livello registrazione Sys" +#define D_LOGGING_PARAMETERS "Livelli registro eventi" +#define D_SERIAL_LOG_LEVEL "Livello registro seriale" +#define D_MQTT_LOG_LEVEL "Livello registro MQTT" +#define D_WEB_LOG_LEVEL "Livello registro web" +#define D_SYS_LOG_LEVEL "Livello registro Sys" #define D_MORE_DEBUG "Debug aggiuntivo" #define D_SYSLOG_HOST "Host Syslog" #define D_SYSLOG_PORT "Porta Syslog" -#define D_TELEMETRY_PERIOD "Periodo Telemetria" +#define D_TELEMETRY_PERIOD "Periodo telemetria" #define D_OTHER_PARAMETERS "Altri parametri" #define D_TEMPLATE "Modello" @@ -324,9 +324,9 @@ #define D_CONFIGURATION_RESET "Configurazione ripristinata" #define D_PROGRAM_VERSION "Versione programma" -#define D_BUILD_DATE_AND_TIME "Data e ora compilazione" +#define D_BUILD_DATE_AND_TIME "Data/ora compilazione" #define D_CORE_AND_SDK_VERSION "Versione core/SDK" -#define D_FLASH_WRITE_COUNT "Contatore scritture flash" +#define D_FLASH_WRITE_COUNT "Numero scritture flash" #define D_MAC_ADDRESS "Indirizzo MAC" #define D_MQTT_HOST "Host MQTT" #define D_MQTT_PORT "Porta MQTT" @@ -340,15 +340,15 @@ #define D_ESP_CHIP_ID "ID chip ESP" #define D_FLASH_CHIP_ID "ID chip flash" #define D_FLASH_CHIP_SIZE "Dimensione flash" -#define D_FREE_PROGRAM_SPACE "Spazio libero memoria programma" +#define D_FREE_PROGRAM_SPACE "Memoria libera programma" #define D_UPGRADE_BY_WEBSERVER "Aggiornamento via server web" -#define D_OTA_URL "OTA URL" -#define D_START_UPGRADE "Avvio aggiornamento" -#define D_UPGRADE_BY_FILE_UPLOAD "Aggiornamento tramite upload file" -#define D_UPLOAD_STARTED "Upload iniziato" -#define D_UPGRADE_STARTED "Aggiornamento avviato" -#define D_UPLOAD_DONE "Upload completato" +#define D_OTA_URL "URL OTA" +#define D_START_UPGRADE "Esegui aggiornamento" +#define D_UPGRADE_BY_FILE_UPLOAD "Aggiornamento tramite file locale" +#define D_UPLOAD_STARTED "Caricamento..." +#define D_UPGRADE_STARTED "Aggiornamento..." +#define D_UPLOAD_DONE "Caricamento completato" #define D_UPLOAD_ERR_1 "Nessun file selezionato" #define D_UPLOAD_ERR_2 "Spazio insufficiente" #define D_UPLOAD_ERR_3 "Magic byte non corrispondente a 0xE9" @@ -400,9 +400,9 @@ // xdrv_07_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Parametri Domoticz" #define D_DOMOTICZ_IDX "Idx" -#define D_DOMOTICZ_KEY_IDX "Idx chiave" -#define D_DOMOTICZ_SWITCH_IDX "Idx switch" -#define D_DOMOTICZ_SENSOR_IDX "Idx sensore" +#define D_DOMOTICZ_KEY_IDX "Idx - chiave" +#define D_DOMOTICZ_SWITCH_IDX "Idx - switch" +#define D_DOMOTICZ_SENSOR_IDX "Idx - sensore" #define D_DOMOTICZ_TEMP "Temp" #define D_DOMOTICZ_TEMP_HUM "Temp,Umd" #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Umd,Baro" @@ -411,7 +411,7 @@ #define D_DOMOTICZ_COUNT "Cont/PM1" #define D_DOMOTICZ_VOLTAGE "Tensione/PM2.5" #define D_DOMOTICZ_CURRENT "Corrente/PM10" - #define D_DOMOTICZ_AIRQUALITY "QualitàAria" + #define D_DOMOTICZ_AIRQUALITY "Qualità aria" #define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter" #define D_DOMOTICZ_UPDATE_TIMER "Intervallo aggiornamento" @@ -667,9 +667,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 - DATI" #define D_SENSOR_DEEPSLEEP "Deep sleep" #define D_SENSOR_EXS_ENABLE "EXS - Abilita" -#define D_SENSOR_CLIENT_TX "Client - TX" -#define D_SENSOR_CLIENT_RX "Client - RX" -#define D_SENSOR_CLIENT_RESET "Client - RST" +#define D_SENSOR_CLIENT_TX "Client - TX" +#define D_SENSOR_CLIENT_RX "Client - RX" +#define D_SENSOR_CLIENT_RESET "Client - RST" #define D_SENSOR_GPS_RX "GPS - RX" #define D_SENSOR_GPS_TX "GPS - TX" #define D_SENSOR_HM10_RX "HM10 - RX" @@ -681,9 +681,9 @@ #define D_SENSOR_CC1101_GDO2 "CC1101 - GDO2" #define D_SENSOR_HRXL_RX "HRXL - RX" #define D_SENSOR_ELECTRIQ_MOODL "MOODL - TX" -#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "Velocità vento" -#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" @@ -789,8 +789,8 @@ #define D_SCRIPT_CHARS_NO_MORE "nessun altro carattere" #define D_SCRIPT_DOWNLOAD "Download" #define D_SCRIPT_ENABLE "abilita script" -#define D_SCRIPT_UPLOAD "Upload" -#define D_SCRIPT_UPLOAD_FILES "Upload file" +#define D_SCRIPT_UPLOAD "Carica" +#define D_SCRIPT_UPLOAD_FILES "Carica file" //xsns_67_as3935.ino #define D_AS3935_GAIN "guadagno:" From 299b9a71941fd217f772f3b80efd6a645d111d20 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 5 Jul 2020 12:15:26 +0200 Subject: [PATCH 420/581] Update support_features.ino --- tasmota/support_features.ino | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 3d58d00d0..6dfb5ee0e 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -64,7 +64,7 @@ void GetFeatures(void) //#if (MQTT_LIBRARY_TYPE == MQTT_ESPMQTTARDUINO) // Obsolete since 6.2.1.11 // feature_drv1 |= 0x00001000; // xdrv_02_mqtt.ino //#endif -#ifdef MQTT_HOST_DISCOVERY +#if defined(USE_DISCOVERY) && defined(MQTT_HOST_DISCOVERY) feature_drv1 |= 0x00002000; // xdrv_02_mqtt.ino #endif #if defined(USE_LIGHT) && defined(USE_ARILUX_RF) @@ -147,28 +147,28 @@ void GetFeatures(void) #if defined(USE_DISPLAY) && defined(USE_DISPLAY_GRAPH) feature_drv2 |= 0x00000040; // xdrv_13_display.ino #endif -#if defined(USE_DISPLAY) && defined(USE_DISPLAY_LCD) +#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_LCD) feature_drv2 |= 0x00000080; // xdsp_01_lcd.ino #endif -#if defined(USE_DISPLAY) && defined(USE_DISPLAY_SSD1306) +#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_SSD1306) feature_drv2 |= 0x00000100; // xdsp_02_ssd1306.ino #endif -#if defined(USE_DISPLAY) && defined(USE_DISPLAY_MATRIX) +#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_MATRIX) feature_drv2 |= 0x00000200; // xdsp_03_matrix.ino #endif -#if defined(USE_DISPLAY) && defined(USE_DISPLAY_ILI9341) +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_ILI9341) feature_drv2 |= 0x00000400; // xdsp_04_ili9341.ino #endif -#if defined(USE_DISPLAY) && defined(USE_DISPLAY_EPAPER_29) +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_EPAPER_29) feature_drv2 |= 0x00000800; // xdsp_05_epaper.ino #endif -#if defined(USE_DISPLAY) && defined(USE_DISPLAY_SH1106) +#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_SH1106) feature_drv2 |= 0x00001000; // xdsp_06_sh1106.ino #endif #ifdef USE_MP3_PLAYER feature_drv2 |= 0x00002000; // xdrv_14_mp3.ino #endif -#ifdef USE_PCA9685 +#if defined(USE_I2C) && defined(USE_PCA9685) feature_drv2 |= 0x00004000; // xdrv_15_pca9685.ino #endif #if defined(USE_LIGHT) && defined(USE_TUYA_MCU) @@ -186,7 +186,7 @@ void GetFeatures(void) #ifdef USE_SCRIPT feature_drv2 |= 0x00080000; // xdrv_10_scripter.ino #endif -#ifdef USE_EMULATION_WEMO +#if defined(USE_WEBSERVER) && defined(USE_EMULATION_WEMO) feature_drv2 |= 0x00100000; // xdrv_21_wemo.ino #endif #ifdef USE_SONOFF_IFAN @@ -450,7 +450,7 @@ void GetFeatures(void) #if defined(USE_ENERGY_SENSOR) && defined(USE_DDS2382) feature5 |= 0x00000040; // xnrg_09_dds2382.ino #endif -#ifdef USE_SM2135 +#if defined(USE_LIGHT) && defined(USE_SM2135) feature5 |= 0x00000080; // xdrv_026_sm2135.ino #endif #ifdef USE_SHUTTER @@ -474,7 +474,7 @@ void GetFeatures(void) #if defined(USE_LIGHT) && defined(USE_SONOFF_L1) feature5 |= 0x00004000; // xlgt_05_sonoff_l1.ino #endif -#ifdef USE_EXS_DIMMER +#if defined(USE_LIGHT) && defined(USE_EXS_DIMMER) feature5 |= 0x00008000; // xdrv_30_exs_dimmer.ino #endif #ifdef USE_TASMOTA_CLIENT @@ -498,7 +498,7 @@ void GetFeatures(void) #ifdef USE_GPS feature5 |= 0x00400000; // xsns_60_GPS.ino #endif -#ifdef USE_HOTPLUG +#if defined(USE_I2C) && defined(USE_HOTPLUG) feature5 |= 0x00800000; // xdrv_32_hotplug.ino #endif #ifdef USE_NRF24 From acee1e568683fcd136f11a01ebb63f624be06b58 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 5 Jul 2020 12:35:54 +0200 Subject: [PATCH 421/581] Fix Zigbee reset pin --- tasmota/xdrv_23_zigbee_8_parsers.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index d1b5d6b05..0429b82fa 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -309,7 +309,7 @@ int32_t EZ_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" "\"Status\":%d,\"Version\":\"%d.%d.%d.%d\",\"Protocol\":%d" ",\"Stack\":%d}}"), - ZIGBEE_STATUS_EZ_VERSION, + ZIGBEE_STATUS_EZ_VERSION, (stack_version & 0xF000) >> 12, (stack_version & 0x0F00) >> 8, (stack_version & 0x00F0) >> 4, @@ -878,7 +878,7 @@ void Z_IncomingMessage(ZCLFrame &zcl_received) { char shortaddr[8]; snprintf_P(shortaddr, sizeof(shortaddr), PSTR("0x%04X"), srcaddr); - + DynamicJsonBuffer jsonBuffer; JsonObject& json = jsonBuffer.createObject(); @@ -1030,7 +1030,7 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { // value = 1 : release the reset pin, restart int32_t EZ_Reset_Device(uint8_t value) { // we use Led4i to drive the reset pin. Since it is reverted we need to pass 1 to start reset, and 0 to release reset - if (PinUsed(GPIO_LED4, ZIGBEE_EZSP_RESET_LED - 1)) { + if (PinUsed(GPIO_LED1, ZIGBEE_EZSP_RESET_LED - 1)) { SetLedPowerIdx(ZIGBEE_EZSP_RESET_LED - 1, value ? 0 : 1); } else { // no GPIO so we use software Reset instead From d4f8234780ee8da1e13e1d8ab303464bcec96ffe Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 5 Jul 2020 14:51:55 +0200 Subject: [PATCH 422/581] Prep ESP32 zigbee support --- tasmota/support_esp32.ino | 10 +++++ tasmota/xdrv_23_zigbee_4_persistence.ino | 48 ++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/tasmota/support_esp32.ino b/tasmota/support_esp32.ino index fbd99ad67..9e07cb9d4 100644 --- a/tasmota/support_esp32.ino +++ b/tasmota/support_esp32.ino @@ -60,6 +60,8 @@ void ESP_Restart(void) { #ifdef ESP32 +// Handle 20k of NVM + #include #include @@ -120,6 +122,14 @@ void QPCWrite(const void *pSettings, unsigned nSettingsLen) { NvmSave("qpc", "pcreg", pSettings, nSettingsLen); } +void ZigbeeRead(void *pSettings, unsigned nSettingsLen) { + NvmLoad("zb", "zigbee", pSettings, nSettingsLen); +} + +void ZigbeeWrite(const void *pSettings, unsigned nSettingsLen) { + NvmSave("zb", "zigbee", pSettings, nSettingsLen); +} + // // sntp emulation // diff --git a/tasmota/xdrv_23_zigbee_4_persistence.ino b/tasmota/xdrv_23_zigbee_4_persistence.ino index ef67221c9..72dc94065 100644 --- a/tasmota/xdrv_23_zigbee_4_persistence.ino +++ b/tasmota/xdrv_23_zigbee_4_persistence.ino @@ -49,12 +49,19 @@ // int8_t - bulbtype // Memory footprint +#ifdef ESP8266 const static uint16_t z_spi_start_sector = 0xFF; // Force last bank of first MB const static uint8_t* z_spi_start = (uint8_t*) 0x402FF000; // 0x402FF000 -const static uint8_t* z_dev_start = z_spi_start + 0x0800; // 0x402FF800 - 2KB -const static size_t z_spi_len = 0x1000; // 4kb blocs +const static uint8_t* z_dev_start = z_spi_start + 0x0800; // 0x402FF800 - 2KB +const static size_t z_spi_len = 0x1000; // 4kb blocks const static size_t z_block_offset = 0x0800; const static size_t z_block_len = 0x0800; // 2kb +#else // ESP32 +uint8_t* z_dev_start; +const static size_t z_spi_len = 0x1000; // 4kb blocks +const static size_t z_block_offset = 0x0000; // No offset needed +const static size_t z_block_len = 0x1000; // 4kb +#endif class z_flashdata_t { public: @@ -229,6 +236,18 @@ void hydrateDevices(const SBuffer &buf) { } void loadZigbeeDevices(void) { + +#ifdef ESP32 + // first copy SPI buffer into ram + uint8_t *spi_buffer = (uint8_t*) malloc(z_spi_len); + if (!spi_buffer) { + AddLog_P2(LOG_LEVEL_ERROR, PSTR(D_LOG_ZIGBEE "Cannot allocate 4KB buffer")); + return; + } + ZigbeeRead(&spi_buffer, z_spi_len); + z_dev_start = spi_buffer; +#endif // ESP32 + z_flashdata_t flashdata; memcpy_P(&flashdata, z_dev_start, sizeof(z_flashdata_t)); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Memory %d"), ESP_getFreeHeap()); @@ -247,6 +266,9 @@ void loadZigbeeDevices(void) { AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "No zigbee devices data in Flash")); } // AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Memory %d"), ESP_getFreeHeap()); +#ifdef ESP32 + free(spi_buffer); +#endif } void saveZigbeeDevices(void) { @@ -264,7 +286,11 @@ void saveZigbeeDevices(void) { return; } // copy the flash into RAM to make local change, and write back the whole buffer +#ifdef ESP8266 ESP.flashRead(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); +#else // ESP32 + ZigbeeRead(&spi_buffer, z_spi_len); +#endif z_flashdata_t *flashdata = (z_flashdata_t*)(spi_buffer + z_block_offset); flashdata->name = ZIGB_NAME; @@ -274,12 +300,17 @@ void saveZigbeeDevices(void) { memcpy(spi_buffer + z_block_offset + sizeof(z_flashdata_t), buf.getBuffer(), buf_len); // buffer is now ready, write it back +#ifdef ESP8266 if (ESP.flashEraseSector(z_spi_start_sector)) { ESP.flashWrite(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); } + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data store in Flash (0x%08X - %d bytes)"), z_dev_start, buf_len); +#else // ESP32 + ZigbeeWrite(&spi_buffer, z_spi_len); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data saved (%d bytes)"), buf_len); +#endif free(spi_buffer); - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data store in Flash (0x%08X - %d bytes)"), z_dev_start, buf_len); } // Erase the flash area containing the ZigbeeData @@ -292,18 +323,27 @@ void eraseZigbeeDevices(void) { return; } // copy the flash into RAM to make local change, and write back the whole buffer +#ifdef ESP8266 ESP.flashRead(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); +#else // ESP32 + ZigbeeRead(&spi_buffer, z_spi_len); +#endif // Fill the Zigbee area with 0xFF memset(spi_buffer + z_block_offset, 0xFF, z_block_len); // buffer is now ready, write it back +#ifdef ESP8266 if (ESP.flashEraseSector(z_spi_start_sector)) { ESP.flashWrite(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); } + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (0x%08X - %d bytes)"), z_dev_start, z_block_len); +#else // ESP32 + ZigbeeWrite(&spi_buffer, z_spi_len); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (%d bytes)"), z_block_len); +#endif free(spi_buffer); - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (0x%08X - %d bytes)"), z_dev_start, z_block_len); } #endif // USE_ZIGBEE From bd302f9a64213a2aebc7cf8675997349620f8876 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 5 Jul 2020 15:13:57 +0200 Subject: [PATCH 423/581] Prep ESP32 zigbee support --- tasmota/support_esp32.ino | 4 ++++ tasmota/xdrv_23_zigbee_4_persistence.ino | 25 +++++++++--------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/tasmota/support_esp32.ino b/tasmota/support_esp32.ino index 9e07cb9d4..2c7bd243f 100644 --- a/tasmota/support_esp32.ino +++ b/tasmota/support_esp32.ino @@ -122,6 +122,10 @@ void QPCWrite(const void *pSettings, unsigned nSettingsLen) { NvmSave("qpc", "pcreg", pSettings, nSettingsLen); } +void ZigbeeErase(void) { + NvmErase("zb"); +} + void ZigbeeRead(void *pSettings, unsigned nSettingsLen) { NvmLoad("zb", "zigbee", pSettings, nSettingsLen); } diff --git a/tasmota/xdrv_23_zigbee_4_persistence.ino b/tasmota/xdrv_23_zigbee_4_persistence.ino index 72dc94065..88126d2fc 100644 --- a/tasmota/xdrv_23_zigbee_4_persistence.ino +++ b/tasmota/xdrv_23_zigbee_4_persistence.ino @@ -236,7 +236,6 @@ void hydrateDevices(const SBuffer &buf) { } void loadZigbeeDevices(void) { - #ifdef ESP32 // first copy SPI buffer into ram uint8_t *spi_buffer = (uint8_t*) malloc(z_spi_len); @@ -247,7 +246,6 @@ void loadZigbeeDevices(void) { ZigbeeRead(&spi_buffer, z_spi_len); z_dev_start = spi_buffer; #endif // ESP32 - z_flashdata_t flashdata; memcpy_P(&flashdata, z_dev_start, sizeof(z_flashdata_t)); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Memory %d"), ESP_getFreeHeap()); @@ -268,7 +266,7 @@ void loadZigbeeDevices(void) { // AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Memory %d"), ESP_getFreeHeap()); #ifdef ESP32 free(spi_buffer); -#endif +#endif // ESP32 } void saveZigbeeDevices(void) { @@ -290,7 +288,7 @@ void saveZigbeeDevices(void) { ESP.flashRead(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); #else // ESP32 ZigbeeRead(&spi_buffer, z_spi_len); -#endif +#endif // ESP8266 - ESP32 z_flashdata_t *flashdata = (z_flashdata_t*)(spi_buffer + z_block_offset); flashdata->name = ZIGB_NAME; @@ -308,14 +306,14 @@ void saveZigbeeDevices(void) { #else // ESP32 ZigbeeWrite(&spi_buffer, z_spi_len); AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data saved (%d bytes)"), buf_len); -#endif - +#endif // ESP8266 - ESP32 free(spi_buffer); } // Erase the flash area containing the ZigbeeData void eraseZigbeeDevices(void) { zigbee_devices.clean(); // avoid writing data to flash after erase +#ifdef ESP8266 // first copy SPI buffer into ram uint8_t *spi_buffer = (uint8_t*) malloc(z_spi_len); if (!spi_buffer) { @@ -323,27 +321,22 @@ void eraseZigbeeDevices(void) { return; } // copy the flash into RAM to make local change, and write back the whole buffer -#ifdef ESP8266 ESP.flashRead(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); -#else // ESP32 - ZigbeeRead(&spi_buffer, z_spi_len); -#endif // Fill the Zigbee area with 0xFF memset(spi_buffer + z_block_offset, 0xFF, z_block_len); // buffer is now ready, write it back -#ifdef ESP8266 if (ESP.flashEraseSector(z_spi_start_sector)) { ESP.flashWrite(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); } - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (0x%08X - %d bytes)"), z_dev_start, z_block_len); -#else // ESP32 - ZigbeeWrite(&spi_buffer, z_spi_len); - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (%d bytes)"), z_block_len); -#endif free(spi_buffer); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (0x%08X - %d bytes)"), z_dev_start, z_block_len); +#else // ESP32 + ZigbeeErase(); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (%d bytes)"), z_block_len); +#endif // ESP8266 - ESP32 } #endif // USE_ZIGBEE From d56f5ebbdfec62c5814df089652fac0d02de0a80 Mon Sep 17 00:00:00 2001 From: Staars Date: Sun, 5 Jul 2020 19:48:47 +0200 Subject: [PATCH 424/581] add lights and yeerc --- tasmota/xsns_61_MI_NRF24.ino | 707 +++++++++++++++++++++++++---------- 1 file changed, 514 insertions(+), 193 deletions(-) diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index f68c29054..c24bd07da 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -21,7 +21,9 @@ Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- - 0.9.7.0 20200624 integrate - use BEARSSL-lib for decryption as default, make decryption optional + 0.9.8.0 20200705 integrate - add YEE-RC, NLIGHT and MJYD2S, add NRFUSE + --- + 0.9.7.0 20200624 integrate - fix BEARSSL-decryption, remove MBEDTLS, prepare night light sensors --- 0.9.6.1 20200622 integrate - use BEARSSL-lib for decryption as default, make decryption optional --- @@ -60,7 +62,7 @@ #define USE_MI_DECRYPTION /*********************************************************************************************\ * MINRF -* BLE-Sniffer/Bridge for MIJIA/XIAOMI Temperatur/Humidity-Sensor, Mi Flora, LYWSD02, GCx +* BLE-Sniffer/Bridge for MIJIA/XIAOMI Temperatur/Humidity-Sensor, Mi Flora, LYWSD02, GCx, ... * * Usage: Configure NRF24 \*********************************************************************************************/ @@ -80,50 +82,56 @@ #define CGD1 6 #define NLIGHT 7 #define MJYD2S 8 +#define YEERC 9 -#define MI_TYPES 8 //count this manually +#define MI_TYPES 9 //count this manually #define D_CMND_NRF "NRF" const char S_JSON_NRF_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_NRF "%s\":%d}"; const char S_JSON_NRF_COMMAND[] PROGMEM = "{\"" D_CMND_NRF "%s\":\"%s\"}"; -const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan|Nlight" +const char kNRF_Commands[] PROGMEM = "Ignore|Use|Page|Scan|Beacon|Chan|Nlight" #ifdef USE_MI_DECRYPTION + "|Mjyd2s" "|Key" #endif //USE_MI_DECRYPTION ; enum NRF_Commands { // commands useable in console or rules - CMND_NRF_IGNORE, // ignore specific sensor type (1-6) + CMND_NRF_IGNORE, // ignore specific sensor type (1-9) --- DEPRECATED!!!! + CMND_NRF_USE, // use specific sensor type (1-9) CMND_NRF_PAGE, // sensor entries per web page, which will be shown alternated CMND_NRF_SCAN, // simplified passive BLE adv scan CMND_NRF_BEACON, // even more simplified Beacon, reports time since last sighting CMND_NRF_CHAN, // ignore channel 0-2 (translates to 37-39) - CMND_NRF_NLIGHT // add Philips night light via MAC + CMND_NRF_NLIGHT // add Philips night light via MAC #ifdef USE_MI_DECRYPTION + , CMND_NRF_MJYD2S // add MJYD2S night light via bind_key to a MAC for payload decryption , CMND_NRF_KEY // add bind_key to a MAC for payload decryption #endif //USE_MI_DECRYPTION }; -const uint16_t kMINRFSlaveID[8]={ 0x0098, // Flora - 0x01aa, // MJ_HT_V1 - 0x045b, // LYWSD02 - 0x055b, // LYWSD03 - 0x0347, // CGG1 - 0x0576, // CGD1 - 0x03dd, // NLIGHT - 0x07f6 // MJYD2S - }; +const uint16_t kMINRFDeviceID[MI_TYPES]={ 0x0098, // Flora + 0x01aa, // MJ_HT_V1 + 0x045b, // LYWSD02 + 0x055b, // LYWSD03 + 0x0347, // CGG1 + 0x0576, // CGD1 + 0x03dd, // NLIGHT + 0x07f6, // MJYD2S + 0x0153 // yee-rc + }; -const char kMINRFSlaveType1[] PROGMEM = "Flora"; -const char kMINRFSlaveType2[] PROGMEM = "MJ_HT_V1"; -const char kMINRFSlaveType3[] PROGMEM = "LYWSD02"; -const char kMINRFSlaveType4[] PROGMEM = "LYWSD03"; -const char kMINRFSlaveType5[] PROGMEM = "CGG1"; -const char kMINRFSlaveType6[] PROGMEM = "CGD1"; -const char kMINRFSlaveType7[] PROGMEM = "NLIGHT"; -const char kMINRFSlaveType8[] PROGMEM = "MJYD2S"; -const char * kMINRFSlaveType[] PROGMEM = {kMINRFSlaveType1,kMINRFSlaveType2,kMINRFSlaveType3,kMINRFSlaveType4,kMINRFSlaveType5,kMINRFSlaveType6,kMINRFSlaveType7,kMINRFSlaveType8}; +const char kMINRFDeviceType1[] PROGMEM = "Flora"; +const char kMINRFDeviceType2[] PROGMEM = "MJ_HT_V1"; +const char kMINRFDeviceType3[] PROGMEM = "LYWSD02"; +const char kMINRFDeviceType4[] PROGMEM = "LYWSD03"; +const char kMINRFDeviceType5[] PROGMEM = "CGG1"; +const char kMINRFDeviceType6[] PROGMEM = "CGD1"; +const char kMINRFDeviceType7[] PROGMEM = "NLIGHT"; +const char kMINRFDeviceType8[] PROGMEM = "MJYD2S"; +const char kMINRFDeviceType9[] PROGMEM = "YEERC"; +const char * kMINRFDeviceType[] PROGMEM = {kMINRFDeviceType1,kMINRFDeviceType2,kMINRFDeviceType3,kMINRFDeviceType4,kMINRFDeviceType5,kMINRFDeviceType6,kMINRFDeviceType7,kMINRFDeviceType8,kMINRFDeviceType9}; // PDU's or different channels 37-39 const uint32_t kMINRFFloPDU[3] = {0x3eaa857d,0xef3b8730,0x71da7b46}; @@ -134,17 +142,19 @@ const uint32_t kMINRFL3PDU[3] = {0x4760dd78,0xdbcc1ccd,0x33049deb}; //encrypted const uint32_t kMINRFCGGPDU[3] = {0x4760cd6e,0xdbcc0cdb,0x33048dfd}; const uint32_t kMINRFCGDPDU[3] = {0x5da0d752,0xc10c16e7,0x29c497c1}; // const uint32_t kMINRFNLIPDU[3] = {0x4760C56E,0xDBCC04DB,0x0330485FD}; //NLIGHT +const uint32_t kMINRFYRCPDU[3] = {0x216D63E2,0x5C3DD47E,0x0A5D0E96}; //yee-rc - 50 30 // start-LSFR for different channels 37-39 const uint8_t kMINRFlsfrList_A[3] = {0x4b,0x17,0x23}; // Flora, LYWSD02 const uint8_t kMINRFlsfrList_B[3] = {0x21,0x72,0x43}; // MJ_HT_V1, LYWSD03, CGx +const uint8_t kMINRFlsfrList_C[3] = {0x38,0x25,0x2e}; // yee-rc #pragma pack(1) // important!! struct mi_beacon_t{ - uint16_t productID; + uint16_t PID; uint8_t counter; - uint8_t Mac[6]; + uint8_t MAC[6]; uint8_t spare; // not on MJ_HT_V1 and CGG1 uint8_t type; uint8_t ten; @@ -160,11 +170,15 @@ struct mi_beacon_t{ uint32_t lux:24; //07 uint8_t moist; //08 uint16_t fert; //09 + struct{ //01 + uint16_t num; + uint8_t longPress; + }Btn; }; }; struct CGDPacket_t { // related to the whole 32-byte-packet/buffer - uint8_t serial[6]; + uint8_t MAC[6]; uint16_t mode; union { struct { @@ -178,7 +192,7 @@ struct CGDPacket_t { // related to the whole 32-byte-packet/buffer struct bleAdvPacket_t { // for nRF24L01 max 32 bytes = 2+6+24 uint8_t pduType; uint8_t payloadSize; - uint8_t mac[6]; + uint8_t MAC[6]; }; #ifdef USE_MI_DECRYPTION @@ -196,6 +210,17 @@ struct encPacket_t{ encPayload_t payload; }; +struct mjysd02_Packet_t{ + uint8_t padding[11]; + uint8_t payloadSize; + uint8_t padding3; + uint16_t UUID; + uint16_t frameCtrl; + uint16_t PID; + uint8_t frameCnt; + uint8_t data[18]; +}; + union mi_bindKey_t{ struct{ uint8_t key[16]; @@ -222,21 +247,22 @@ struct { uint8_t currentChan=0; uint8_t channelIgnore = 0; //bitfield: 2^channel (0=37,1=38,2=39) uint8_t confirmedSensors = 0; - uint8_t packetMode; // 0 - normal BLE-advertisements, 1 - 6 "special" sensor packets + uint8_t packetMode; // 0 - normal BLE-advertisements, 1 - 9 "special" sensor packets uint8_t perPage = 4; uint8_t firstUsedPacketMode = 1; - uint8_t activeNlight = 0; + uint8_t activeLight = 0; FIFO_t buffer; struct { - uint8_t mac[6]; + uint8_t MAC[6]; uint32_t time; uint32_t PDU[3]; bool active = false; } beacon; bool activeScan = false; bool stopScan = false; + bool triggeredTELE = false; #ifdef DEBUG_TASMOTA_SENSOR uint8_t streamBuffer[sizeof(buffer)]; // raw data stream bytes @@ -246,8 +272,8 @@ struct { } MINRF; struct mi_sensor_t{ - uint8_t type; //Flora = 1; MJ_HT_V1=2; LYWSD02=3; LYWSD03=4; CGG1=5; CGD1=6 - uint8_t serial[6]; + uint8_t type; //Flora = 1; MJ_HT_V1=2; LYWSD02=3; LYWSD03=4; CGG1=5; CGD1=6; YEERC=9 + uint8_t MAC[6]; uint8_t showedUp; float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx union { @@ -260,22 +286,33 @@ struct mi_sensor_t{ float hum; uint8_t bat; }; // MJ_HT_V1, LYWSD0x, CGx + struct { + uint8_t btn; + uint8_t shallSendMQTT; + uint8_t lastCnt; + }; // yee-rc }; }; -struct mi_nlight_t{ +struct mi_light_t{ uint8_t MAC[6]; uint32_t PDU[3]; - uint8_t type; // NLIGHT=7 + uint8_t type; // NLIGHT=7, MJYD2S=8 + uint8_t bat; struct { uint16_t events; //"alarms" since boot uint8_t lastCnt; //device generated counter of the packet + uint8_t shallSendMQTT; }; + uint32_t NMT; // no motion time in seconds for the MJYD2S + uint32_t lastTime; + uint8_t lux; //1 or 64 for the MJYD2S + uint8_t eventType; //internal type of actual event for the MJYD2S + }; - struct scan_entry_t { - uint8_t mac[6]; + uint8_t MAC[6]; uint16_t cid; uint16_t svc; uint16_t uuid; @@ -287,7 +324,7 @@ std::vector MINRFscanResult; #ifdef USE_MI_DECRYPTION std::vector MIBLEbindKeys; #endif //USE_MI_DECRYPTION -std::vector MIBLEnlights; +std::vector MIBLElights; static union{ scan_entry_t MINRFdummyEntry; @@ -299,7 +336,7 @@ static union{ /** * @brief * - * @param _mode Packet mode 0-6 + * @param _mode Packet mode 0-9 * @return true If no error occured * @return false If NRF24L01 is not connected */ @@ -368,29 +405,17 @@ bool MINRFreceivePacket(void) // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: _lsfrlist: %x, chan: %u, mode: %u"),_lsfrlist[MINRF.currentChan],MINRF.currentChan, MINRF.packetMode); switch (MINRF.packetMode) { - case 0: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); + case 0: case 7: case 8: + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); // "BEACON" mode, "NLIGHT" mode, "MJYD2S" mode break; - case 1: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_A[MINRF.currentChan]); // "flora" mode + case 1: case 3: + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_A[MINRF.currentChan]); // "flora" mode, "LYWSD02" mode break; - case 2: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "MJ_HT_V1" mode + case 2: case 4: case 5: case 6: + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "MJ_HT_V1" mode, LYWSD03" mode, "CGG1" mode, "CGD1" mode break; - case 3: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_A[MINRF.currentChan]); // "LYWSD02" mode - break; - case 4: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "LYWSD03" mode - break; - case 5: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "CGG1" mode - break; - case 6: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "CGD1" mode - break; - case 7: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); // "NLIGHT" mode + case 9: + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_C[MINRF.currentChan]); // "YEE-RC" mode break; } // DEBUG_SENSOR_LOG(PSTR("MINRF: LSFR:%x"),_lsfr); @@ -400,7 +425,7 @@ bool MINRFreceivePacket(void) return true; } -#ifdef DEBUG_TASMOTA_SENSOR +// #ifdef DEBUG_TASMOTA_SENSOR void MINRFshowBuffer(uint8_t (&buf)[32]){ // we use this only for the 32-byte-FIFO-buffer, so 32 is hardcoded // DEBUG_SENSOR_LOG(PSTR("MINRF: Buffer: %c %c %c %c %c %c %c %c" // " %c %c %c %c %c %c %c %c" @@ -415,7 +440,7 @@ void MINRFshowBuffer(uint8_t (&buf)[32]){ // we use this only for the 32-byte-FI buf[24],buf[25],buf[26],buf[27],buf[28],buf[29],buf[30],buf[31] ); } -#endif // DEBUG_TASMOTA_SENSOR +// #endif // DEBUG_TASMOTA_SENSOR /** * @brief change lsfrBuffer content to "wire bit order" @@ -483,7 +508,7 @@ void MINRFhandleScan(void){ MINRFscanResult.erase(std::remove_if(MINRFscanResult.begin(), MINRFscanResult.end(), [&i](scan_entry_t e) { - if(e.showedUp>2) AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: Beacon %02u: %02X%02X%02X%02X%02X%02X Cid: %04X Svc: %04X UUID: %04X"),i,e.mac[0],e.mac[1],e.mac[2],e.mac[3],e.mac[4],e.mac[5],e.cid,e.svc,e.uuid); + if(e.showedUp>2) AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: Beacon %02u: %02X%02X%02X%02X%02X%02X Cid: %04X Svc: %04X UUID: %04X"),i,e.MAC[0],e.MAC[1],e.MAC[2],e.MAC[3],e.MAC[4],e.MAC[5],e.cid,e.svc,e.uuid); i++; return ((e.showedUp < 3)); }), @@ -492,11 +517,11 @@ void MINRFhandleScan(void){ return; } - MINRFreverseMAC(MINRF.buffer.bleAdv.mac); + MINRFreverseMAC(MINRF.buffer.bleAdv.MAC); for(uint32_t i=0; iMAC,MIBLEbindKeys[i].MAC,sizeof(packet->MAC))==0){ - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("have key")); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("have key")); memcpy(_bindkey,MIBLEbindKeys[i].key,sizeof(_bindkey)); break; } // else{ - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mac in packet: %02x %02x %02x %02x %02x %02x"), packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mac in vector: %02x %02x %02x %02x %02x %02x"), MIBLEbindKeys[i].MAC[0], MIBLEbindKeys[i].MAC[1], MIBLEbindKeys[i].MAC[2], MIBLEbindKeys[i].MAC[3], MIBLEbindKeys[i].MAC[4], MIBLEbindKeys[i].MAC[5]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MAC in packet: %02x %02x %02x %02x %02x %02x"), packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MAC in vector: %02x %02x %02x %02x %02x %02x"), MIBLEbindKeys[i].MAC[0], MIBLEbindKeys[i].MAC[1], MIBLEbindKeys[i].MAC[2], MIBLEbindKeys[i].MAC[3], MIBLEbindKeys[i].MAC[4], MIBLEbindKeys[i].MAC[5]); // } } @@ -686,7 +711,80 @@ int MINRFdecryptPacket(char *_buf){ ret = br_ccm_check_tag(&ctx, packet->payload.tag); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("BEARSSL: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, output[0],output[1],output[2],output[3],output[4]); memcpy((uint8_t*)(packet->payload.cipher)+1,output,sizeof(packet->payload.cipher)); - return (ret-1); + return ret; +} + +int MINRFdecryptMJYD2SPacket(char *_buf, uint8_t _light, char* _output){ + int ret = 0; + uint8_t nonce[12]; + const unsigned char authData[1] = {0x11}; + uint8_t tag[4]; + mjysd02_Packet_t *packet = (mjysd02_Packet_t*)_buf; + + // nonce: device MAC, device type, frame cnt, ext. cnt + for (uint32_t i = 0; i<6; i++){ + nonce[i] = MIBLElights[_light-1].MAC[5-i]; + } + memcpy((uint8_t*)&nonce+6,(uint8_t*)&packet->PID,2); + nonce[8] = packet->frameCnt; + memcpy((uint8_t*)&nonce+9,(uint8_t*)&packet->padding[0] + packet->payloadSize + 5, 3); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("nonce: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"), nonce[0], nonce[1], nonce[2], nonce[3], nonce[4], nonce[5], nonce[6], nonce[7], nonce[8], nonce[9], nonce[10], nonce[11]); + + uint8_t _bindkey[16]; + for(uint32_t i=0; iMAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MAC in vector: %02x %02x %02x %02x %02x %02x"), MIBLEbindKeys[i].MAC[0], MIBLEbindKeys[i].MAC[1], MIBLEbindKeys[i].MAC[2], MIBLEbindKeys[i].MAC[3], MIBLEbindKeys[i].MAC[4], MIBLEbindKeys[i].MAC[5]); + // } + } + + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("size %u"),packet->payloadSize); + uint32_t _size; + int32_t _offset; + uint32_t _tagSize; + switch (packet->payloadSize){ + case 22: + _size = 7; + _offset = 2; + _tagSize = 4; + break; + case 25: + _size = packet->payloadSize - 21; + _offset = -1; + _tagSize = 4; + break; + case 27: + _size = packet->payloadSize - 21; + _offset = 1; + _tagSize = 3; + break; + default: + return 0; + break; + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("size %u , offset %u"),_size,_offset); + memcpy(_output,(uint8_t*)&packet->padding[0] + packet->payloadSize - _offset, _size); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("BEARSSL: Output : %02x %02x %02x %02x %02x %02x %02x"), _output[0], _output[1],_output[2],_output[3],_output[4],_output[5],_output[6]); + + br_aes_small_ctrcbc_keys keyCtx; + br_aes_small_ctrcbc_init(&keyCtx, _bindkey, sizeof(_bindkey)); + + br_ccm_context ctx; + br_ccm_init(&ctx, &keyCtx.vtable); + br_ccm_reset(&ctx, nonce, sizeof(nonce), sizeof(authData),_size,4); + br_ccm_aad_inject(&ctx, authData, sizeof(authData)); + br_ccm_flip(&ctx); + br_ccm_run(&ctx, 0, _output, _size); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("BEARSSL: Err:%i, Decrypted : %02x %02x %02x %02x %02x %02x %02x"), ret, _output[0], _output[1],_output[2],_output[3],_output[4],_output[5],_output[6]); + + br_ccm_get_tag(&ctx, tag); + ret = memcmp(tag,(uint8_t*)&packet->padding[0] + packet->payloadSize + 8, _tagSize); + return ret; } #endif //USE_MI_DECRYPTION @@ -697,14 +795,14 @@ int MINRFdecryptPacket(char *_buf){ /** * @brief reverse 6-byte-array, hard-coded size of 6 * - * @param _mac pass an uint_t[6] + * @param _MAC pass an uint_t[6] */ -void MINRFreverseMAC(uint8_t _mac[]){ +void MINRFreverseMAC(uint8_t _MAC[]){ uint8_t _reversedMAC[6]; for (uint8_t i=0; i<6; i++){ - _reversedMAC[5-i] = _mac[i]; + _reversedMAC[5-i] = _MAC[i]; } - memcpy(_mac,_reversedMAC, sizeof(_reversedMAC)); + memcpy(_MAC,_reversedMAC, sizeof(_reversedMAC)); } #ifdef USE_MI_DECRYPTION void MINRFAddKey(char* payload){ @@ -728,9 +826,9 @@ void MINRFAddKey(char* payload){ * @brief Convert combined key-MAC-string to * * @param _string input string in format: AABBCCDDEEFF... (upper case!), must be 44 chars!! - * @param _mac target byte array with fixed size of 16 + 6 + * @param _MAC target byte array with fixed size of 16 + 6 */ -void MINRFKeyMACStringToBytes(char* _string,uint8_t _keyMac[]) { //uppercase +void MINRFKeyMACStringToBytes(char* _string,uint8_t _keyMAC[]) { //uppercase uint32_t index = 0; while (index < 44) { char c = _string[index]; @@ -739,21 +837,21 @@ void MINRFKeyMACStringToBytes(char* _string,uint8_t _keyMac[]) { //uppercase value = (c - '0'); else if (c >= 'A' && c <= 'F') value = (10 + (c - 'A')); - _keyMac[(index/2)] += value << (((index + 1) % 2) * 4); + _keyMAC[(index/2)] += value << (((index + 1) % 2) * 4); index++; } DEBUG_SENSOR_LOG(PSTR("MINRF: %s to:"),_string); - DEBUG_SENSOR_LOG(PSTR("MINRF: key-array: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"),_keyMac[0],_keyMac[1],_keyMac[2],_keyMac[3],_keyMac[4],_keyMac[5],_keyMac[6],_keyMac[7],_keyMac[8],_keyMac[9],_keyMac[10],_keyMac[11],_keyMac[12],_keyMac[13],_keyMac[14],_keyMac[15]); - DEBUG_SENSOR_LOG(PSTR("MINRF: MAC-array: %02X%02X%02X%02X%02X%02X"),_keyMac[16],_keyMac[17],_keyMac[18],_keyMac[19],_keyMac[20],_keyMac[21]); + DEBUG_SENSOR_LOG(PSTR("MINRF: key-array: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"),_keyMAC[0],_keyMAC[1],_keyMAC[2],_keyMAC[3],_keyMAC[4],_keyMAC[5],_keyMAC[6],_keyMAC[7],_keyMAC[8],_keyMAC[9],_keyMAC[10],_keyMAC[11],_keyMAC[12],_keyMAC[13],_keyMAC[14],_keyMAC[15]); + DEBUG_SENSOR_LOG(PSTR("MINRF: MAC-array: %02X%02X%02X%02X%02X%02X"),_keyMAC[16],_keyMAC[17],_keyMAC[18],_keyMAC[19],_keyMAC[20],_keyMAC[21]); } #endif //USE_MI_DECRYPTION /** * @brief * * @param _string input string in format: AABBCCDDEEFF (upper case!) - * @param _mac target byte array with fixed size of 6 + * @param _MAC target byte array with fixed size of 6 */ -void MINRFMACStringToBytes(char* _string, uint8_t _mac[]) { //uppercase +void MINRFMACStringToBytes(char* _string, uint8_t _MAC[]) { //uppercase uint32_t index = 0; while (index < 12) { char c = _string[index]; @@ -762,10 +860,10 @@ void MINRFMACStringToBytes(char* _string, uint8_t _mac[]) { //uppercase value = (c - '0'); else if (c >= 'A' && c <= 'F') value = (10 + (c - 'A')); - _mac[(index/2)] += value << (((index + 1) % 2) * 4); + _MAC[(index/2)] += value << (((index + 1) % 2) * 4); index++; } - // DEBUG_SENSOR_LOG(PSTR("MINRF: %s to MAC-array: %02X%02X%02X%02X%02X%02X"),_string,_mac[0],_mac[1],_mac[2],_mac[3],_mac[4],_mac[5]); + // DEBUG_SENSOR_LOG(PSTR("MINRF: %s to MAC-array: %02X%02X%02X%02X%02X%02X"),_string,_MAC[0],_MAC[1],_MAC[2],_MAC[3],_MAC[4],_MAC[5]); } /** @@ -783,6 +881,22 @@ void MINRFcomputefirstUsedPacketMode(void){ } } +/** + * @brief Recalculates the receive buffer with an offset in relation to a standard BLE advertisement. + * Used for custom PDU, typically based on a MAC + * + * @param _buf - The receive buffer + * @param offset - in bytes + */ + +void MINRFrecalcBuffer(uint8_t *_buf, uint32_t offset){ + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); + MINRFswapbuf((uint8_t*)&MINRF.buffer,sizeof(MINRF.buffer)); + memcpy(_buf+offset,MINRF.buffer.raw,32); + MINRFswapbuf(_buf,32+offset); + MINRFwhiten(_buf, 32+offset, MINRF.channel[MINRF.currentChan] | 0x40); +} + /** * @brief Set packet mode and fitting PDU-type of the NRF24L01 * @@ -806,7 +920,7 @@ void MINRFchangePacketModeTo(uint8_t _mode) { NRF24radio.openReadingPipe(0,kMINRFL2PDU[_nextchannel]);// 95 fe 70 20 -> LYWSD02 break; case 4: // special LYWSD03 packet - NRF24radio.openReadingPipe(0,kMINRFL3PDU[_nextchannel]);// 95 fe 58 30 -> LYWSD03 (= no data message) + NRF24radio.openReadingPipe(0,kMINRFL3PDU[_nextchannel]);// 95 fe 58 58 -> LYWSD03 (= encrypted data message) break; case 5: // special CGG1 packet NRF24radio.openReadingPipe(0,kMINRFCGGPDU[_nextchannel]); // 95 fe 50 30 -> CGG1 @@ -814,10 +928,13 @@ void MINRFchangePacketModeTo(uint8_t _mode) { case 6: // special CGD1 packet NRF24radio.openReadingPipe(0,kMINRFCGDPDU[_nextchannel]); // cd fd 08 0c -> CGD1 break; - case 7: // MAC based NLIGHT packet - if (MIBLEnlights.size()==0) break; - NRF24radio.openReadingPipe(0,MIBLEnlights[MINRF.activeNlight].PDU[_nextchannel]); // computed from MAC -> NLIGHT - MINRF.activeNlight++; + case 7: case 8:// MAC based LIGHT packet + if (MIBLElights.size()==0) break; + NRF24radio.openReadingPipe(0,MIBLElights[MINRF.activeLight].PDU[_nextchannel]); // computed from MAC -> NLIGHT and MJYSD2S + MINRF.activeLight++; + break; + case 9: // YEE-RC packet + NRF24radio.openReadingPipe(0,kMINRFYRCPDU[_nextchannel]);// 95 fe 50 30 -> YEE-RC break; } // DEBUG_SENSOR_LOG(PSTR("MINRF: Change Mode to %u"),_mode); @@ -827,29 +944,29 @@ void MINRFchangePacketModeTo(uint8_t _mode) { /** * @brief Return the slot number of a known sensor or return create new sensor slot * - * @param _serial BLE address of the sensor + * @param _MAC BLE address of the sensor * @param _type Type number of the sensor * @return uint32_t Known or new slot in the sensors-vector */ -uint32_t MINRFgetSensorSlot(uint8_t (&_serial)[6], uint16_t _type){ +uint32_t MINRFgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type){ DEBUG_SENSOR_LOG(PSTR("MINRF: will test ID-type: %x"), _type); bool _success = false; - for (uint32_t i=0;i<6;i++){ // i < sizeof(kMINRFSlaveID) gives compiler warning - if(_type == kMINRFSlaveID[i]){ + for (uint32_t i=0;itype,MINRF.buffer.miBeacon.type); float _tempFloat; + int decryptRet; - if (_sensorVec->type==MJ_HT_V1 || _sensorVec->type==CGG1){ + switch(_sensorVec->type){ + case MJ_HT_V1: case CGG1: case YEERC: memcpy(MINRFtempBuf,(uint8_t*)&MINRF.buffer.miBeacon.spare, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 memcpy((uint8_t*)&MINRF.buffer.miBeacon.type,MINRFtempBuf, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 - } + break; #ifdef USE_MI_DECRYPTION - if(_sensorVec->type==LYWSD03){ - int decryptRet = -1; + case LYWSD03: decryptRet = MINRFdecryptPacket((char*)&MINRF.buffer); //start with PID - if(decryptRet==0) _sensorVec->showedUp=255; // if decryption worked, this must be a valid sensor - } + if(decryptRet==1) _sensorVec->showedUp=255; // if decryption worked, this must be a valid sensor + break; #endif //USE_MI_DECRYPTION + } + DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kNRFSlaveType[_sensorVec->type-1],_slot); switch(MINRF.buffer.miBeacon.type){ + case 0x1: + if(MINRF.buffer.miBeacon.counter==_sensorVec->lastCnt) break; + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: YEE-RC button: %u Long: %u"), MINRF.buffer.miBeacon.Btn.num, MINRF.buffer.miBeacon.Btn.longPress); + _sensorVec->lastCnt=MINRF.buffer.miBeacon.counter; + _sensorVec->btn=MINRF.buffer.miBeacon.Btn.num + (MINRF.buffer.miBeacon.Btn.longPress/2)*6; + _sensorVec->shallSendMQTT = 1; + MINRFtriggerTele(); + break; case 0x04: _tempFloat=(float)(MINRF.buffer.miBeacon.temp)/10.0f; if(_tempFloat<60){ @@ -1006,8 +1149,8 @@ void MINRFhandleMiBeaconPacket(void){ * Note: battery section is based on "internet data" -> not confirmed yet */ void MINRFhandleCGD1Packet(void){ // no MiBeacon - MINRFreverseMAC(MINRF.buffer.CGDPacket.serial); - uint32_t _slot = MINRFgetSensorSlot(MINRF.buffer.CGDPacket.serial, 0x0576); // This must be hard-coded, no object-id in Cleargrass-packet + MINRFreverseMAC(MINRF.buffer.CGDPacket.MAC); + uint32_t _slot = MINRFgetSensorSlot(MINRF.buffer.CGDPacket.MAC, 0x0576); // This must be hard-coded, no object-id in Cleargrass-packet DEBUG_SENSOR_LOG(PSTR("MINRF: Sensor slot: %u"), _slot); if(_slot==0xff) return; @@ -1041,39 +1184,119 @@ void MINRFhandleCGD1Packet(void){ // no MiBeacon void MINRFhandleNlightPacket(void){ // no MiBeacon uint32_t offset = 6; uint8_t _buf[32+offset]; - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); - MINRFswapbuf((uint8_t*)&MINRF.buffer,sizeof(MINRF.buffer)); - memcpy((uint8_t*)&_buf+offset,MINRF.buffer.raw,32); - MINRFswapbuf((uint8_t*)&_buf,sizeof(_buf)); - MINRFwhiten((uint8_t *)&_buf, sizeof(_buf), MINRF.channel[MINRF.currentChan] | 0x40); - if (offset == 6) MINRFreverseMAC((uint8_t*)&_buf[2]); + MINRFrecalcBuffer((uint8_t*)&_buf,offset); // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"),_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6],_buf[7],_buf[8],_buf[9],_buf[10],_buf[11],_buf[12],_buf[13],_buf[14],_buf[15],_buf[16],_buf[17],_buf[18]); uint32_t _frame_PID = _buf[15]<<24 | _buf[16]<<16 | _buf[17]<<8 | _buf[18]; - if(_frame_PID!=0x4030dd03) return; - AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT:%x"),_frame_PID); - uint32_t _idx = MINRF.activeNlight-1; - if(_buf[19]!=MIBLEnlights[_idx].lastCnt){ - MIBLEnlights[_idx].lastCnt = _buf[19]; - MIBLEnlights[_idx].events++; - AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT %u: events: %u, Cnt:%u"), _idx,MIBLEnlights[_idx].events, MIBLEnlights[_idx].lastCnt); + if(_frame_PID!=0x4030dd03) return; // invalid packet + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT:%x"),_frame_PID); + uint32_t _idx = MINRF.activeLight-1; + if((millis() - MIBLElights[_idx].lastTime)<1500) return; + if(_buf[19]!=MIBLElights[_idx].lastCnt){ + MIBLElights[_idx].lastCnt = _buf[19]; + MIBLElights[_idx].events++; + MIBLElights[_idx].shallSendMQTT = 1; + MIBLElights[_idx].lastTime = millis(); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MINRF: NLIGHT %u: events: %u, Cnt:%u"), _idx,MIBLElights[_idx].events, MIBLElights[_idx].lastCnt); } } -void MINRFaddNlight(uint8_t _mac[]){ // no MiBeacon - for(uint32_t i=0; iPID!=0x07f6) return; // invalid packet + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: MJYD2S: %02u %04x %04x %04x %02x"),_packet->payloadSize,_packet->UUID,_packet->frameCtrl,_packet->PID,_packet->frameCnt); + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: PAYLOAD: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"),_packet->data[0],_packet->data[1],_packet->data[2],_packet->data[3],_packet->data[4],_packet->data[5],_packet->data[6],_packet->data[7],_packet->data[8],_packet->data[9],_packet->data[10],_packet->data[11],_packet->data[12],_packet->data[13],_packet->data[14],_packet->data[15],_packet->data[16],_packet->data[17]); + uint32_t _idx = MINRF.activeLight-1; + switch(_packet->frameCtrl){ + case 0x5910: + if(_packet->frameCnt!=MIBLElights[_idx].lastCnt){ + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: MJYD2S after motion:%x"),_packet->frameCnt); + MIBLElights[_idx].lastCnt = _packet->frameCnt; + if(millis()-MIBLElights[_idx].lastTime>120000){ + MIBLElights[_idx].eventType = 1; + MIBLElights[_idx].events++; + MIBLElights[_idx].shallSendMQTT = 1; + MIBLElights[_idx].lastTime = millis(); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MINRF: MJYD2S secondary PIR")); + } + } + break; + case 0x5948: case 0x5958: + uint8_t output[16]; + if(_packet->frameCnt==MIBLElights[_idx].lastCnt) break; + int32_t ret = MINRFdecryptMJYD2SPacket((char*)&_buf, MINRF.activeLight,(char*)&output); + if(ret==0){ + MIBLElights[_idx].lastCnt = _packet->frameCnt; + switch(output[0]){ + case 0x0f: + if(output[1] == 0){ + if(millis()-MIBLElights[_idx].lastTime>1000){ + MIBLElights[_idx].eventType = 1; //PIR + MIBLElights[_idx].shallSendMQTT = 1; + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MINRF: MJYD2S primary PIR")); + MIBLElights[_idx].events++; + } + MIBLElights[_idx].lastTime = millis(); + MIBLElights[_idx].lux = output[3]; + } + break; + case 0x07: + if(output[1] == 0x10){ + MIBLElights[_idx].eventType = 2; //No PIR + MIBLElights[_idx].lux = output[3]; + MIBLElights[_idx].shallSendMQTT = 1; + } + break; + case 0x0a: + MIBLElights[_idx].bat = output[3]; + break; + case 0x17: + MIBLElights[_idx].NMT = output[6]<<24 | output[5]<<16 | output[4]<<8 | output[3]; + MIBLElights[_idx].eventType = 3; // NMT 0, 120, 300, 600, 1800, ... seconds + MIBLElights[_idx].shallSendMQTT = 1; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MINRF: MJYD2S NMT: %u"), MIBLElights[_idx].NMT ); + break; + } + } + } + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT:%x"),_frame_PID); +} + + +void MINRFhandleLightPacket(void){ + switch(MIBLElights[MINRF.activeLight-1].type){ + case NLIGHT: + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT!!")); + MINRFhandleNlightPacket(); + break; + case MJYD2S: + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: MJYD2S !!")); + MINRFhandleMJYD2SPacket(); + break; + } + if(MIBLElights[MINRF.activeLight-1].shallSendMQTT==1) MINRFtriggerTele(); +} + +void MINRFaddLight(uint8_t _MAC[], uint8_t _type){ // no MiBeacon + for(uint32_t i=0; iMIBLEnlights.size()){ - MINRF.activeNlight=0; - MINRF.packetMode=MINRF.firstUsedPacketMode; + if(MINRF.packetMode==NLIGHT){ + if(MINRF.activeLight+1>MIBLElights.size()){ + MINRF.activeLight=0; + MINRF.packetMode+=2; } + else MINRF.packetMode+=2; } else{ MINRF.packetMode = (MINRF.packetMode+1>MI_TYPES) ? MINRF.firstUsedPacketMode : MINRF.packetMode+1; @@ -1170,15 +1394,34 @@ bool NRFCmd(void) { if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.payload == 0){ MINRF.ignore = 0; + MINRF.firstUsedPacketMode = 1; } else if (XdrvMailbox.payload < MI_TYPES+1) { bitSet(MINRF.ignore,XdrvMailbox.payload); MINRFcomputefirstUsedPacketMode(); MINRF.timer = 5900; - Response_P(S_JSON_NRF_COMMAND, command, kMINRFSlaveType[XdrvMailbox.payload-1]); + Response_P(S_JSON_NRF_COMMAND, command, kMINRFDeviceType[XdrvMailbox.payload-1]); } - else if (XdrvMailbox.payload == 255) { - MINRF.ignore = 255; + else if (XdrvMailbox.payload == 65535) { + MINRF.ignore = 65535; + } + } + Response_P(S_JSON_NRF_COMMAND_NVALUE, command, MINRF.ignore); + break; + case CMND_NRF_USE: + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload == 0){ + MINRF.ignore = 65535; + MINRF.firstUsedPacketMode = 1; + } + else if (XdrvMailbox.payload < MI_TYPES+1) { + bitClear(MINRF.ignore,XdrvMailbox.payload); + MINRFcomputefirstUsedPacketMode(); + MINRF.timer = 5900; + Response_P(S_JSON_NRF_COMMAND, command, kMINRFDeviceType[XdrvMailbox.payload-1]); + } + else if (XdrvMailbox.payload == 65535) { + MINRF.ignore = 0; } } Response_P(S_JSON_NRF_COMMAND_NVALUE, command, MINRF.ignore); @@ -1215,22 +1458,22 @@ bool NRFCmd(void) { } } if (XdrvMailbox.data_len==12){ // a MAC-string - memset(MINRF.beacon.mac,0,sizeof(MINRF.beacon.mac)); - MINRFMACStringToBytes(XdrvMailbox.data, MINRF.beacon.mac); + memset(MINRF.beacon.MAC,0,sizeof(MINRF.beacon.MAC)); + MINRFMACStringToBytes(XdrvMailbox.data, MINRF.beacon.MAC); MINRF.beacon.time=0; MINRF.beacon.active=true; Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); } - MINRFcomputeBeaconPDU(MINRF.beacon.mac,MINRF.beacon.PDU); + MINRFcomputeBeaconPDU(MINRF.beacon.MAC,MINRF.beacon.PDU,0); } break; case CMND_NRF_NLIGHT: if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len==12){ // a MAC-string - uint8_t _mac[6] = {0}; - MINRFMACStringToBytes(XdrvMailbox.data, _mac); + uint8_t _MAC[6] = {0}; + MINRFMACStringToBytes(XdrvMailbox.data, _MAC); Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); - MINRFaddNlight(_mac); + MINRFaddLight(_MAC, 7); } } break; @@ -1245,6 +1488,16 @@ bool NRFCmd(void) { Response_P(S_JSON_NRF_COMMAND_NVALUE, command, MINRF.channelIgnore); break; #ifdef USE_MI_DECRYPTION + case CMND_NRF_MJYD2S: + if (XdrvMailbox.data_len==44){ // a KEY-MAC-string + MINRFAddKey(XdrvMailbox.data); + uint8_t _MAC[6] = {0}; + MINRFMACStringToBytes((XdrvMailbox.data)+32, _MAC); + MINRFaddLight(_MAC, 8); + Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); + } + break; + case CMND_NRF_KEY: if (XdrvMailbox.data_len==44){ // a KEY-MAC-string MINRFAddKey(XdrvMailbox.data); @@ -1279,40 +1532,98 @@ void MINRFShow(bool json) for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { if(MIBLEsensors[i].showedUp < 3){ DEBUG_SENSOR_LOG(PSTR("MINRF: sensor not fully registered yet")); - break; + if(MIBLEsensors[i].type != YEERC) break; // send every RC code, even if there is a potentially false MAC } - ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"),kMINRFSlaveType[MIBLEsensors[i].type-1],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]); - if (MIBLEsensors[i].type==FLORA && !isnan(MIBLEsensors[i].temp)){ - char stemp[FLOATSZ]; - dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, stemp); - ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), stemp); + switch(MIBLEsensors[i].type){ + case YEERC: + if(MIBLEsensors[i].shallSendMQTT==0) continue; + break; + default: + if(MINRF.triggeredTELE) continue; + break; + } + ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"),kMINRFDeviceType[MIBLEsensors[i].type-1],MIBLEsensors[i].MAC[3],MIBLEsensors[i].MAC[4],MIBLEsensors[i].MAC[5]); + switch(MIBLEsensors[i].type){ + case FLORA: + if(MINRF.triggeredTELE) { + ResponseJsonEnd(); + break; + } + char stemp[FLOATSZ]; + dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, stemp); + ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), stemp); - if(MIBLEsensors[i].lux!=0xffffffff){ // this is the error code -> no lux - ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); - } - if(!isnan(MIBLEsensors[i].moisture)){ - dtostrfd(MIBLEsensors[i].moisture, 0, stemp); - ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%s"), stemp); - } - if(!isnan(MIBLEsensors[i].fertility)){ - dtostrfd(MIBLEsensors[i].fertility, 0, stemp); - ResponseAppend_P(PSTR(",\"Fertility\":%s"), stemp); - } - ResponseJsonEnd(); + if(MIBLEsensors[i].lux!=0xffffffff){ // this is the error code -> no lux + ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); + } + if(!isnan(MIBLEsensors[i].moisture)){ + dtostrfd(MIBLEsensors[i].moisture, 0, stemp); + ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%s"), stemp); + } + if(!isnan(MIBLEsensors[i].fertility)){ + dtostrfd(MIBLEsensors[i].fertility, 0, stemp); + ResponseAppend_P(PSTR(",\"Fertility\":%s"), stemp); + } + ResponseJsonEnd(); + break; + case YEERC: + if(MIBLEsensors[i].shallSendMQTT == 1){ + ResponseAppend_P(PSTR("\"Btn\":%u"), MIBLEsensors[i].btn); + MIBLEsensors[i].shallSendMQTT = 0; + } + ResponseJsonEnd(); + break; + default: + if(MINRF.triggeredTELE) { + ResponseJsonEnd(); + break; + } + if(!isnan(MIBLEsensors[i].temp) && !isnan(MIBLEsensors[i].hum)){ + ResponseAppendTHD(MIBLEsensors[i].temp,MIBLEsensors[i].hum); + } + if(MIBLEsensors[i].bat!=0x00){ // this is the error code -> no battery + ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); + } + ResponseJsonEnd(); + break; } - if (MIBLEsensors[i].type>FLORA){ - if(!isnan(MIBLEsensors[i].temp) && !isnan(MIBLEsensors[i].hum)){ - ResponseAppendTHD(MIBLEsensors[i].temp,MIBLEsensors[i].hum); + } + for(uint32_t i=0; i no battery - ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); - } - ResponseJsonEnd(); + MIBLElights[i].eventType=0; + MIBLElights[i].shallSendMQTT = 0; } + else{ + if(MIBLElights[i].type==MJYD2S){ + if(MIBLElights[i].bat!=0) ResponseAppend_P(PSTR("\"Battery\":%u,\"" D_JSON_ILLUMINANCE "\":%u,"), MIBLElights[i].bat, MIBLElights[i].lux); + } + ResponseAppend_P(PSTR("\"Events\":%u"),MIBLElights[i].events); + } + ResponseJsonEnd(); } if(MINRF.beacon.active){ ResponseAppend_P(PSTR(",\"Beacon\":{\"Timer\":%u}"),MINRF.beacon.time); } + if(MINRF.triggeredTELE) MINRF.triggeredTELE = false; // ResponseJsonEnd(); #ifdef USE_WEBSERVER } else { @@ -1338,41 +1649,51 @@ void MINRFShow(bool json) continue; } WSContentSend_PD(HTTP_MINRF_HL); - WSContentSend_PD(HTTP_MINRF_MAC, kMINRFSlaveType[MIBLEsensors[i].type-1], D_MAC_ADDRESS, MIBLEsensors[i].serial[0], MIBLEsensors[i].serial[1],MIBLEsensors[i].serial[2],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]); + WSContentSend_PD(HTTP_MINRF_MAC, kMINRFDeviceType[MIBLEsensors[i].type-1], D_MAC_ADDRESS, MIBLEsensors[i].MAC[0], MIBLEsensors[i].MAC[1],MIBLEsensors[i].MAC[2],MIBLEsensors[i].MAC[3],MIBLEsensors[i].MAC[4],MIBLEsensors[i].MAC[5]); + if (MIBLEsensors[i].type==YEERC) continue; if (MIBLEsensors[i].type==FLORA){ if(!isnan(MIBLEsensors[i].temp)){ char temperature[FLOATSZ]; dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); - WSContentSend_PD(HTTP_SNS_TEMP, kMINRFSlaveType[MIBLEsensors[i].type-1], temperature, TempUnit()); + WSContentSend_PD(HTTP_SNS_TEMP, kMINRFDeviceType[MIBLEsensors[i].type-1], temperature, TempUnit()); } if(MIBLEsensors[i].lux!=0xffffffff){ // this is the error code -> no valid value - WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); } if(!isnan(MIBLEsensors[i].moisture)){ // this is the error code -> no valid value - WSContentSend_PD(HTTP_SNS_MOISTURE, kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].moisture); + WSContentSend_PD(HTTP_SNS_MOISTURE, kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].moisture); } if(!isnan(MIBLEsensors[i].fertility)){ // this is the error code -> no valid value - WSContentSend_PD(HTTP_MINRF_FLORA_DATA, kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].fertility); + WSContentSend_PD(HTTP_MINRF_FLORA_DATA, kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].fertility); } } if (MIBLEsensors[i].type>FLORA){ // everything "above" Flora - WSContentSend_THD(kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum); + WSContentSend_THD(kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum); if(MIBLEsensors[i].bat!=0x00){ // without "juice" nothing can be done - WSContentSend_PD(HTTP_BATTERY, kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat); + WSContentSend_PD(HTTP_BATTERY, kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat); } } } if(MINRF.beacon.active){ WSContentSend_PD(HTTP_MINRF_HL); WSContentSend_PD(HTTP_MINRF_HL); - WSContentSend_PD(HTTP_MINRF_MAC, F("Beacon"), D_MAC_ADDRESS, MINRF.beacon.mac[0], MINRF.beacon.mac[1],MINRF.beacon.mac[2],MINRF.beacon.mac[3],MINRF.beacon.mac[4],MINRF.beacon.mac[5]); + WSContentSend_PD(HTTP_MINRF_MAC, F("Beacon"), D_MAC_ADDRESS, MINRF.beacon.MAC[0], MINRF.beacon.MAC[1],MINRF.beacon.MAC[2],MINRF.beacon.MAC[3],MINRF.beacon.MAC[4],MINRF.beacon.MAC[5]); WSContentSend_PD(PSTR("{s}Beacon Time{m}%u seconds{e}"),MINRF.beacon.time); } - for(uint32_t i=0; i0){ + WSContentSend_PD(HTTP_BATTERY, kMINRFDeviceType[MIBLElights[i].type-1], MIBLElights[i].bat); + } + if(MIBLElights[i].lux>0){ + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMINRFDeviceType[MIBLElights[i].type-1], MIBLElights[i].lux); + } + } } if(counter>3) { From 5384c0190b7c08a07ef950aff2cd98efc564f4c3 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 5 Jul 2020 21:01:26 +0200 Subject: [PATCH 425/581] Zigbee EZSP support for bindings and groups --- tasmota/xdrv_23_zigbee_0_constants.ino | 30 ++++++++++ tasmota/xdrv_23_zigbee_8_parsers.ino | 78 +++++++++++++++++--------- tasmota/xdrv_23_zigbee_9_serial.ino | 74 ++++++++++++++++-------- tasmota/xdrv_23_zigbee_A_impl.ino | 27 +++++++++ 4 files changed, 160 insertions(+), 49 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index ac63d9878..da2dd5119 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -461,6 +461,7 @@ enum EZSP_ZDO { // Network Management Server Services Requests ZDO_Mgmt_Lqi_req = 0x0031, ZDO_Mgmt_Rtg_req = 0x0032, + ZDO_Mgmt_Bind_req = 0x0033, ZDO_Mgmt_Leave_req = 0x0034, ZDO_Mgmt_Permit_Joining_req = 0x0036, ZDO_Mgmt_NWK_Update_req = 0x0038, @@ -496,6 +497,7 @@ enum EZSP_ZDO { // Network Management Server Services Responses ZDO_Mgmt_Lqi_rsp = 0x8031, ZDO_Mgmt_Rtg_rsp = 0x8032, + ZDO_Mgmt_Bind_rsp = 0x8033, ZDO_Mgmt_Leave_rsp = 0x8034, ZDO_Mgmt_Permit_Joining_rsp = 0x8036, ZDO_Mgmt_NWK_Update_rsp = 0x8038, @@ -1106,6 +1108,34 @@ typedef struct Z_StatusLine { const char * status_msg; } Z_StatusLine; + +// ZDP Enumeration, see Zigbee spec 2.4.5 +String getZDPStatusMessage(uint8_t status) { + static const char StatusMsg[] PROGMEM = "SUCCESS|INV_REQUESTTYPE|DEVICE_NOT_FOUND|INVALID_EP|NOT_ACTIVE|NOT_SUPPORTED" + "|TIMEOUT|NO_MATCH|NO_ENTRY|NO_DESCRIPTOR|INSUFFICIENT_SPACE|NOT_PERMITTED" + "|TABLE_FULL|NOT_AUTHORIZED|DEVICE_BINDING_TABLE_FULL" + ; + static const uint8_t StatusIdx[] PROGMEM = { 0x00, 0x80, 0x81, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x88, 0x89, 0x8A, 0x8B, + 0x8C, 0x8D, 0x8E }; + + char msg[32]; + int32_t idx = -1; + for (uint32_t i = 0; i < sizeof(StatusIdx); i++) { + if (status == pgm_read_byte(&StatusIdx[i])) { + idx = i; + break; + } + } + if (idx >= 0) { + GetTextIndexed(msg, sizeof(msg), idx, StatusMsg); + } else { + *msg = 0x00; // empty string + } + return String(msg); +} + + // Undocumented Zigbee ZCL code here: https://github.com/dresden-elektronik/deconz-rest-plugin/wiki/Zigbee-Error-Codes-in-the-Log String getZigbeeStatusMessage(uint8_t status) { static const char StatusMsg[] PROGMEM = "SUCCESS|FAILURE|NOT_AUTHORIZED|RESERVED_FIELD_NOT_ZERO|MALFORMED_COMMAND|UNSUP_CLUSTER_COMMAND|UNSUP_GENERAL_COMMAND" diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 0429b82fa..14e62b603 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -670,9 +670,17 @@ int32_t ZNP_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) { // // Handle Bind Rsp incoming message // -int32_t ZNP_BindRsp(int32_t res, const class SBuffer &buf) { +int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP Z_ShortAddress nwkAddr = buf.get16(2); uint8_t status = buf.get8(4); + String msg = getZigbeeStatusMessage(status); +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + uint8_t status = buf.get8(0); + Z_ShortAddress nwkAddr = buf.get16(buf.len()-2); // last 2 bytes + String msg = getZDPStatusMessage(status); +#endif // USE_ZIGBEE_EZSP const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr); @@ -682,7 +690,7 @@ int32_t ZNP_BindRsp(int32_t res, const class SBuffer &buf) { } ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d" ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" - "}}"), status, getZigbeeStatusMessage(status).c_str()); + "}}"), status, msg.c_str()); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); XdrvRulesProcess(); @@ -693,9 +701,17 @@ int32_t ZNP_BindRsp(int32_t res, const class SBuffer &buf) { // // Handle Unbind Rsp incoming message // -int32_t ZNP_UnbindRsp(int32_t res, const class SBuffer &buf) { +int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP Z_ShortAddress nwkAddr = buf.get16(2); uint8_t status = buf.get8(4); + String msg = getZigbeeStatusMessage(status); +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + uint8_t status = buf.get8(0); + Z_ShortAddress nwkAddr = buf.get16(buf.len()-2); // last 2 bytes + String msg = getZDPStatusMessage(status); +#endif // USE_ZIGBEE_EZSP const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr); @@ -703,8 +719,9 @@ int32_t ZNP_UnbindRsp(int32_t res, const class SBuffer &buf) { if (friendlyName) { ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName); } - ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" - "}}"), status, getZigbeeStatusMessage(status).c_str()); + ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d" + ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" + "}}"), status, msg.c_str()); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); XdrvRulesProcess(); @@ -714,12 +731,23 @@ int32_t ZNP_UnbindRsp(int32_t res, const class SBuffer &buf) { // // Handle MgMt Bind Rsp incoming message // -int32_t ZNP_MgmtBindRsp(int32_t res, const class SBuffer &buf) { +int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP uint16_t shortaddr = buf.get16(2); uint8_t status = buf.get8(4); uint8_t bind_total = buf.get8(5); uint8_t bind_start = buf.get8(6); uint8_t bind_len = buf.get8(7); + const size_t prefix_len = 8; +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + uint16_t shortaddr = buf.get16(buf.len()-2); + uint8_t status = buf.get8(0); + uint8_t bind_total = buf.get8(1); + uint8_t bind_start = buf.get8(2); + uint8_t bind_len = buf.get8(3); + const size_t prefix_len = 4; +#endif // USE_ZIGBEE_EZSP const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr); @@ -733,7 +761,7 @@ int32_t ZNP_MgmtBindRsp(int32_t res, const class SBuffer &buf) { ",\"Bindings\":[" ), status, getZigbeeStatusMessage(status).c_str(), bind_total); - uint32_t idx = 8; + uint32_t idx = prefix_len; for (uint32_t i = 0; i < bind_len; i++) { if (idx + 14 > buf.len()) { break; } // overflow, frame size is between 14 and 21 @@ -791,7 +819,8 @@ void Z_SendIEEEAddrReq(uint16_t shortaddr) { ZigbeeZNPSend(IEEEAddrReq, sizeof(IEEEAddrReq)); #endif #ifdef USE_ZIGBEE_EZSP - // TODO + uint8_t IEEEAddrReq[] = { Z_B0(shortaddr), Z_B1(shortaddr), 0x00, 0x00 }; + EZ_SendZDO(shortaddr, ZDO_IEEE_addr_req, IEEEAddrReq, sizeof(IEEEAddrReq)); #endif } @@ -991,25 +1020,31 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { uint8_t linkquality = buf.get8(14); // uint8_t linkrsssi = buf.get8(15); // probably not used as there is no equivalent in Z-Stack uint16_t srcaddr = buf.get16(16); - uint8_t bindingindex = buf.get8(18); // TODO not sure we need this one as a coordinator - uint8_t addressindex = buf.get8(19); // TODO not sure how to handle this one + // uint8_t bindingindex = buf.get8(18); // not sure we need this one as a coordinator + // uint8_t addressindex = buf.get8(19); // not sure how to handle this one // offset 20 is len, and buffer starts at offset 21 if ((0x0000 == profileid) && (0x00 == srcendpoint)) { // ZDO request // Since ZDO messages start with a sequence number, we skip it - SBuffer zdo_buf = buf.subBuffer(22, buf.get8(20) - 1); + // but we add the source address in the last 2 bytes + SBuffer zdo_buf(buf.get8(20) - 1 + 2); + zdo_buf.addBuffer(buf.buf(22), buf.get8(20) - 1); + zdo_buf.add16(srcaddr); switch (clusterid) { case ZDO_Device_annce: return Z_ReceiveEndDeviceAnnonce(res, zdo_buf); - break; case ZDO_Active_EP_rsp: return Z_ReceiveActiveEp(res, zdo_buf); - break; case ZDO_IEEE_addr_rsp: return Z_ReceiveIEEEAddr(res, zdo_buf); - break; + case ZDO_Bind_rsp: + return Z_BindRsp(res, zdo_buf); + case ZDO_Unbind_rsp: + return Z_UnbindRsp(res, zdo_buf); + case ZDO_Mgmt_Bind_rsp: + return Z_MgmtBindRsp(res, zdo_buf); } } else { bool defer_attributes = false; // do we defer attributes reporting to coalesce @@ -1130,15 +1165,6 @@ int32_t ZNP_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { return -1; } -// -// Callback for loading Zigbee configuration from Flash, called by the state machine -// -int32_t Z_Reset_Device(uint8_t value) { - // TODO - GPIO is hardwired to GPIO4 - digitalWrite(4, value ? HIGH : LOW); - return 0; // continue -} - #endif // USE_ZIGBEE_ZNP @@ -1189,9 +1215,9 @@ const Z_Dispatcher Z_DispatchTable[] PROGMEM = { { { Z_AREQ | Z_ZDO, ZDO_NODE_DESC_RSP }, &ZNP_ReceiveNodeDesc }, // 4582 { { Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP }, &Z_ReceiveActiveEp }, // 4585 { { Z_AREQ | Z_ZDO, ZDO_IEEE_ADDR_RSP }, &Z_ReceiveIEEEAddr }, // 4581 - { { Z_AREQ | Z_ZDO, ZDO_BIND_RSP }, &ZNP_BindRsp }, // 45A1 - { { Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP }, &ZNP_UnbindRsp }, // 45A2 - { { Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP }, &ZNP_MgmtBindRsp }, // 45B3 + { { Z_AREQ | Z_ZDO, ZDO_BIND_RSP }, &Z_BindRsp }, // 45A1 + { { Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP }, &Z_UnbindRsp }, // 45A2 + { { Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP }, &Z_MgmtBindRsp }, // 45B3 }; /*********************************************************************************************\ diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index 354bb507a..aeefe8ae4 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -718,33 +718,61 @@ void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterI #ifdef USE_ZIGBEE_EZSP SBuffer buf(32+len); - buf.add16(EZSP_sendUnicast); // 3400 - buf.add8(EMBER_OUTGOING_DIRECT); // 00 - buf.add16(shortaddr); // dest addr - // ApsFrame - buf.add16(Z_PROF_HA); // Home Automation profile - buf.add16(clusterId); // cluster - buf.add8(0x01); // srcEp - buf.add8(endpoint); // dstEp - buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame - buf.add16(groupaddr); // groupId - buf.add8(transacId); - // end of ApsFrame - buf.add8(0x01); // tag TODO + if (BAD_SHORTADDR != shortaddr) { + // send unicast message to an address + buf.add16(EZSP_sendUnicast); // 3400 + buf.add8(EMBER_OUTGOING_DIRECT); // 00 + buf.add16(shortaddr); // dest addr + // ApsFrame + buf.add16(Z_PROF_HA); // Home Automation profile + buf.add16(clusterId); // cluster + buf.add8(0x01); // srcEp + buf.add8(endpoint); // dstEp + buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame + buf.add16(groupaddr); // groupId + buf.add8(transacId); + // end of ApsFrame + buf.add8(0x01); // tag TODO - buf.add8(3 + len + (manuf ? 2 : 0)); - buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field - if (manuf) { - buf.add16(manuf); // add Manuf Id if not null - } - buf.add8(transacId); // Transaction Sequance Number - buf.add8(cmdId); - if (len > 0) { - buf.addBuffer(msg, len); // add the payload + buf.add8(3 + len + (manuf ? 2 : 0)); + buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field + if (manuf) { + buf.add16(manuf); // add Manuf Id if not null + } + buf.add8(transacId); // Transaction Sequance Number + buf.add8(cmdId); + if (len > 0) { + buf.addBuffer(msg, len); // add the payload + } + } else { + // send broadcast group address, aka groupcast + buf.add16(EZSP_sendMulticast); // 3800 + // ApsFrame + buf.add16(Z_PROF_HA); // Home Automation profile + buf.add16(clusterId); // cluster + buf.add8(0x01); // srcEp + buf.add8(endpoint); // broadcast endpoint for groupcast + buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame + buf.add16(groupaddr); // groupId + buf.add8(transacId); + // end of ApsFrame + buf.add8(0); // hops, 0x00 = EMBER_MAX_HOPS + buf.add8(7); // nonMemberRadius, 7 = infinite + buf.add8(0x01); // tag TODO + + buf.add8(3 + len + (manuf ? 2 : 0)); + buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field + if (manuf) { + buf.add16(manuf); // add Manuf Id if not null + } + buf.add8(transacId); // Transaction Sequance Number + buf.add8(cmdId); + if (len > 0) { + buf.addBuffer(msg, len); // add the payload + } } ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true); - #endif // USE_ZIGBEE_EZSP } diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 569f522fe..7eeae7c15 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -713,6 +713,25 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind ZigbeeZNPSend(buf.getBuffer(), buf.len()); #endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + SBuffer buf(24); + + // ZDO message payload (see Zigbee spec 2.4.3.2.2) + buf.add64(srcLongAddr); + buf.add8(endpoint); + buf.add16(cluster); + if (dstLongAddr) { + buf.add8(Z_Addr_IEEEAddress); // DstAddrMode - 0x03 = ADDRESS_64_BIT + buf.add64(dstLongAddr); + buf.add8(toendpoint); + } else { + buf.add8(Z_Addr_Group); // DstAddrMode - 0x01 = GROUP_ADDRESS + buf.add16(toGroup); + } + + EZ_SendZDO(srcDevice, unbind ? ZDO_UNBIND_REQ : ZDO_BIND_REQ, buf.buf(), buf.len()); +#endif // USE_ZIGBEE_EZSP + ResponseCmndDone(); } @@ -748,6 +767,14 @@ void CmndZbBindState(void) { ZigbeeZNPSend(buf.getBuffer(), buf.len()); #endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + // ZDO message payload (see Zigbee spec 2.4.3.3.4) + uint8_t buf[] = { 0x00 }; // index = 0 + + EZ_SendZDO(shortaddr, ZDO_Mgmt_Bind_req, buf, sizeof(buf)); +#endif // USE_ZIGBEE_EZSP + ResponseCmndDone(); } From f12468e2c423bc12ba8128a5ad511767d72f013e Mon Sep 17 00:00:00 2001 From: Staars Date: Mon, 6 Jul 2020 20:09:32 +0200 Subject: [PATCH 426/581] update NimBLE-Arduino --- libesp32/NimBLE-Arduino/API_DIFFERENCES.md | 18 +- libesp32/NimBLE-Arduino/README.md | 70 ++- libesp32/NimBLE-Arduino/src/NimBLE2902.h | 9 +- libesp32/NimBLE-Arduino/src/NimBLE2904.h | 1 + libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp | 6 + libesp32/NimBLE-Arduino/src/NimBLEAddress.h | 1 + .../src/NimBLEAdvertisedDevice.cpp | 18 + .../src/NimBLEAdvertisedDevice.h | 28 +- .../NimBLE-Arduino/src/NimBLEAdvertising.cpp | 59 +- .../NimBLE-Arduino/src/NimBLEAdvertising.h | 3 +- .../src/NimBLECharacteristic.cpp | 393 +++++-------- .../NimBLE-Arduino/src/NimBLECharacteristic.h | 147 ++--- .../src/NimBLECharacteristicMap.cpp | 132 ----- libesp32/NimBLE-Arduino/src/NimBLEClient.cpp | 212 +++---- libesp32/NimBLE-Arduino/src/NimBLEClient.h | 22 +- .../NimBLE-Arduino/src/NimBLEDescriptor.cpp | 40 +- .../NimBLE-Arduino/src/NimBLEDescriptor.h | 54 +- .../src/NimBLEDescriptorMap.cpp | 149 ----- libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp | 13 +- libesp32/NimBLE-Arduino/src/NimBLEDevice.h | 2 +- libesp32/NimBLE-Arduino/src/NimBLELog.h | 8 +- .../src/NimBLERemoteCharacteristic.cpp | 362 ++++++------ .../src/NimBLERemoteCharacteristic.h | 64 ++- .../src/NimBLERemoteDescriptor.cpp | 235 ++++---- .../src/NimBLERemoteDescriptor.h | 29 +- .../src/NimBLERemoteService.cpp | 113 ++-- .../NimBLE-Arduino/src/NimBLERemoteService.h | 5 +- libesp32/NimBLE-Arduino/src/NimBLEScan.cpp | 144 +++-- libesp32/NimBLE-Arduino/src/NimBLEScan.h | 11 +- libesp32/NimBLE-Arduino/src/NimBLEServer.cpp | 313 ++++------ libesp32/NimBLE-Arduino/src/NimBLEServer.h | 109 ++-- libesp32/NimBLE-Arduino/src/NimBLEService.cpp | 117 ++-- libesp32/NimBLE-Arduino/src/NimBLEService.h | 62 +- .../NimBLE-Arduino/src/NimBLEServiceMap.cpp | 145 ----- libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp | 7 +- libesp32/NimBLE-Arduino/src/NimBLEUtils.h | 14 + libesp32/NimBLE-Arduino/src/NimBLEValue.cpp | 143 ----- libesp32/NimBLE-Arduino/src/NimBLEValue.h | 52 -- .../NimBLE-Arduino/src/host/ble_hs_pvcy.h | 43 +- libesp32/NimBLE-Arduino/src/mesh/glue.h | 3 + .../src/nimble/host/mesh/pkg.yml | 49 -- .../nimble/host/mesh/src/src/ble_gap_priv.h | 2 +- .../nimble/host/mesh/src/src/ble_hs_id_priv.h | 1 + .../nimble/host/mesh/src/src/ble_hs_priv.h | 6 +- .../host/mesh/src/src/ble_hs_resolv_priv.h | 4 +- .../nimble/host/mesh/src/src/ble_sm_priv.h | 8 +- .../src/nimble/host/mesh/syscfg.yml | 540 ------------------ .../src/nimble/host/services/ans/pkg.yml | 34 -- .../src/nimble/host/services/ans/syscfg.yml | 30 - .../src/nimble/host/services/bas/pkg.yml | 34 -- .../src/nimble/host/services/bas/syscfg.yml | 34 -- .../src/nimble/host/services/gap/pkg.yml | 34 -- .../src/nimble/host/services/gap/syscfg.yml | 83 --- .../src/nimble/host/services/gatt/pkg.yml | 34 -- .../src/nimble/host/services/gatt/syscfg.yml | 24 - .../src/nimble/host/services/ias/pkg.yml | 34 -- .../src/nimble/host/services/ias/syscfg.yml | 23 - .../host/services/ipss/src/ble_svc_ipss.c | 51 ++ .../src/nimble/host/services/lls/pkg.yml | 34 -- .../src/nimble/host/services/lls/syscfg.yml | 22 - .../src/nimble/host/services/tps/pkg.yml | 34 -- .../src/nimble/host/services/tps/syscfg.yml | 23 - .../src/nimble/host/src/ble_hs_id.c | 31 + .../src/nimble/host/src/ble_hs_id_priv.h | 1 + .../src/nimble/host/src/ble_hs_pvcy.c | 12 +- .../src/nimble/host/src/ble_hs_resolv.c | 45 +- .../src/nimble/host/src/ble_hs_resolv_priv.h | 4 +- .../src/nimble/host/src/ble_uuid.c | 3 + .../src/nimble/host/store/config/pkg.yml | 38 -- .../config/src/ble_store_config_conf.unused | 231 -------- .../src/nimble/host/store/config/syscfg.yml | 27 - .../src/nimble/host/store/ram/pkg.yml | 37 -- .../src/nimble/host/store/ram/syscfg.yml | 23 - .../src/nimble/host/util/pkg.yml | 29 - .../src/nimble/host/util/syscfg.yml | 19 - libesp32/NimBLE-Arduino/src/nimconfig.h | 22 +- .../src/porting/nimble/Makefile.controller | 32 -- .../src/porting/nimble/Makefile.defs | 68 --- .../src/porting/nimble/Makefile.mesh | 24 - .../src/porting/nimble/Makefile.tinycrypt | 26 - .../NimBLE-Arduino/src/porting/nimble/pkg.yml | 43 -- .../src/porting/nimble/src/os_mbuf.c | 9 + .../src/services/ipss/ble_svc_ipss.h | 38 ++ libesp32/NimBLE-Arduino/src/src/ble_sm_priv.h | 12 +- 84 files changed, 1547 insertions(+), 3721 deletions(-) delete mode 100644 libesp32/NimBLE-Arduino/src/NimBLECharacteristicMap.cpp delete mode 100644 libesp32/NimBLE-Arduino/src/NimBLEDescriptorMap.cpp delete mode 100644 libesp32/NimBLE-Arduino/src/NimBLEServiceMap.cpp delete mode 100644 libesp32/NimBLE-Arduino/src/NimBLEValue.cpp delete mode 100644 libesp32/NimBLE-Arduino/src/NimBLEValue.h delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/mesh/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/mesh/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/ans/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/ans/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/bas/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/bas/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/gap/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/gap/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/gatt/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/gatt/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/ias/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/ias/syscfg.yml create mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/ipss/src/ble_svc_ipss.c delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/lls/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/lls/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/tps/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/services/tps/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/store/config/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_config_conf.unused delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/store/config/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/store/ram/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/store/ram/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/util/pkg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/nimble/host/util/syscfg.yml delete mode 100644 libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.controller delete mode 100644 libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.defs delete mode 100644 libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.mesh delete mode 100644 libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.tinycrypt delete mode 100644 libesp32/NimBLE-Arduino/src/porting/nimble/pkg.yml create mode 100644 libesp32/NimBLE-Arduino/src/services/ipss/ble_svc_ipss.h diff --git a/libesp32/NimBLE-Arduino/API_DIFFERENCES.md b/libesp32/NimBLE-Arduino/API_DIFFERENCES.md index 32bf4a2f0..91b0fd78f 100644 --- a/libesp32/NimBLE-Arduino/API_DIFFERENCES.md +++ b/libesp32/NimBLE-Arduino/API_DIFFERENCES.md @@ -122,21 +122,20 @@ Has been removed from the API as it is no longer maintained in the library. The last two above changes reduce the heap usage significantly with minimal application code adjustments. -**NEW** on May 23, 2020 +**UPDATED** on June 21, 2020 > ``` > NimBLEClient::getServices(bool refresh = false) > NimBLERemoteService::getCharacteristics(bool refresh = false) > NimBLERemoteCharacteristic::getDecriptors(bool refresh = false) >``` -> These methods now take an optional (bool) parameter. +These methods now take an optional (bool) parameter. If true it will clear the respective vector and retrieve all the respective attributes from the peripheral. -If false it will retrieve the attributes only if the vector is empty, otherwise the vector is returned -with the currently stored attributes. +If false(default) it will return the respective vector empty or otherwise with the currently stored attributes. -> Removed the automatic discovery of all peripheral attributes as they consumed time and resources for data +**Removed:** the automatic discovery of all peripheral attributes as they consumed time and resources for data the user may not be interested in. -> Added `NimBLEClient::discoverAtrributes()` for the user to discover all the peripheral attributes +**Added:** `NimBLEClient::discoverAtrributes()` for the user to discover all the peripheral attributes to replace the the former functionality. @@ -145,12 +144,11 @@ to replace the the former functionality. >getCharacteristic(NimBLEUUID) >getDescriptor(NimBLEUUID) >``` ->These methods will now check the respective vectors for the attribute object and, if not found, will retrieve (only) +These methods will now check the respective vectors for the attribute object and, if not found, will retrieve (only) the specified attribute from the peripheral. -> These changes allow more control for the user to manage the resources used for the attributes. - - +These changes allow more control for the user to manage the resources used for the attributes. +*** #### Client Security: The client will automatically initiate security when the peripheral responds that it's required. The default configuration will use "just-works" pairing with no bonding, if you wish to enable bonding see below. diff --git a/libesp32/NimBLE-Arduino/README.md b/libesp32/NimBLE-Arduino/README.md index 514416e29..04c3a80c5 100644 --- a/libesp32/NimBLE-Arduino/README.md +++ b/libesp32/NimBLE-Arduino/README.md @@ -1,5 +1,17 @@ -# *** UPDATE *** -**Breaking change:** Client and scan now use `std::vector` instead of `std::map` for storing the remote attribute database. +# *** UPDATES *** +**Breaking changes:** +**NEW** on June 21, 2020 +> ``` +> NimBLEClient::getServices(bool refresh = false) +> NimBLERemoteService::getCharacteristics(bool refresh = false) +> NimBLERemoteCharacteristic::getDecriptors(bool refresh = false) +>``` +These methods now take an optional (bool) parameter. +If true it will clear the respective vector and retrieve all the respective attributes from the peripheral. +If false(default) it will return the respective vector empty or otherwise with the currently stored attributes. + +**NEW** on May 23, 2020 +Client and scan now use `std::vector` instead of `std::map` for storing the remote attribute database. This change will affect your application code if you use `NimBLEClient::getServices()` or `NimBLERemoteService::getCharacteristics()` in your application as they now return a pointer to `std::vector` of the respective attributes. @@ -13,30 +25,33 @@ It is expected that there will be minimal impact on most applications, if you ne # NimBLE-Arduino A fork of the NimBLE stack restructured for compilation in the Ardruino IDE with a CPP library for use with ESP32. -Why? Because the Bluedroid library is too bulky. +This library **significantly** reduces resource usage and improves performance for ESP32 BLE applications as compared +with the bluedroid based library. The goal is to maintain, as much as reasonable, compatibility with the original +library but refactored to use the NimBLE stack. In addition, this library will be more actively developed and maintained +to provide improved capabilites and stability over the original. -Initial client code testing has resulted in code size reduction of ~115k and reduced ram consumption of ~37k. +## Resource use improvement: -Server code testing results from @beegee-toyo [from the project here](https://github.com/beegee-tokyo/ESP32WiFiBLE-NimBLE): +### (Original) BLE_client example comparison (Debug): +#### Arduino BLE Library +Sketch uses **1216377** bytes (58%) of program storage space. +Memory after connection: Free Heap: **171548** - -### Memory usage (compilation output) -#### Arduino BLE library -```log -RAM: [== ] 17.7% (used 58156 bytes from 327680 bytes) -Flash: [======== ] 76.0% (used 1345630 bytes from 1769472 bytes) -``` #### NimBLE-Arduino library -```log -RAM: [= ] 14.5% (used 47476 bytes from 327680 bytes) -Flash: [======= ] 69.5% (used 911378 bytes from 1310720 bytes) -``` -### Memory usage after **`setup()`** function -#### Arduino BLE library -**`Internal Total heap 259104, internal Free Heap 91660`** -#### NimBLE-Arduino library -**`Internal Total heap 290288, internal Free Heap 182344`** - +Sketch uses **617256** bytes (29%) of program storage space. +Memory after connection: Free Heap: **270336** +*** +### (Original) BLE_notify example comparison (Debug): +#### Arduino BLE Library +Sketch uses **1208409** bytes (57%) of program storage space. +Memory after connection: Free Heap: **173300** + +#### NimBLE-Arduino library +Sketch uses **603432** bytes (28%) of program storage space. +Memory after connection: Free Heap: **269792** + +**As shown: there is nearly a 50% reduction in flash use and approx. 100kB less ram consumed!** + # Installation: @@ -62,20 +77,21 @@ Change the settings in the `nimconfig.h` file to customize NimBLE to your projec # Continuing development: -This Library is tracking the esp-nimble repo, nimble-1.2.0-idf master branch, currently [@fead24e.](https://github.com/espressif/esp-nimble) +This Library is tracking the esp-nimble repo, nimble-1.2.0-idf master branch, currently [@46c1d9f.](https://github.com/espressif/esp-nimble) -Also tracking the NimBLE related changes in esp-idf, master branch, currently [@2bc28bb.](https://github.com/espressif/esp-idf/tree/master/components/bt/host/nimble) +Also tracking the NimBLE related changes in esp-idf, master branch, currently [@2ef4890.](https://github.com/espressif/esp-idf/tree/master/components/bt/host/nimble) # Acknowledgments: * @nkolban and @chegewara for the [original esp32 BLE library](https://github.com/nkolban/esp32-snippets) this project was derived from. * @beegee-tokyo for contributing your time to test/debug and contributing the beacon examples. +* @Jeroen88 for the amazing help debugging and improving the client code. # Todo: -1. Code cleanup. -2. Create documentation. +1. Create documentation. +2. Add BLE Mesh code. 3. Expose more NimBLE features. -4. Add BLE Mesh code. + diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2902.h b/libesp32/NimBLE-Arduino/src/NimBLE2902.h index f7fc55569..2d84b73dc 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLE2902.h +++ b/libesp32/NimBLE-Arduino/src/NimBLE2902.h @@ -22,11 +22,16 @@ #include "NimBLEDescriptor.h" -#include +#include #define NIMBLE_DESC_FLAG_NOTIFY 0x0001 #define NIMBLE_DESC_FLAG_INDICATE 0x0002 +typedef struct { + uint16_t conn_id; + uint16_t sub_val; +} chr_sub_status_t; + /** * @brief Descriptor for Client Characteristic Configuration. @@ -45,7 +50,7 @@ public: private: NimBLE2902(NimBLECharacteristic* pCharacterisitic); friend class NimBLECharacteristic; - std::map m_subscribedMap; + std::vector m_subscribedVec; }; // NimBLE2902 diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2904.h b/libesp32/NimBLE-Arduino/src/NimBLE2904.h index dd665a2bb..0a6d036a4 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLE2904.h +++ b/libesp32/NimBLE-Arduino/src/NimBLE2904.h @@ -31,6 +31,7 @@ struct BLE2904_Data { } __attribute__((packed)); + /** * @brief Descriptor for Characteristic Presentation Format. * diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp b/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp index b6bc9526b..8c2c68f79 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp @@ -142,4 +142,10 @@ NimBLEAddress::operator std::string() const { return std::string(buffer); } +NimBLEAddress::operator uint64_t() const { + uint64_t address = 0; + memcpy(&address, m_address, sizeof m_address); + return address; +} + #endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAddress.h b/libesp32/NimBLE-Arduino/src/NimBLEAddress.h index e81a2bdf3..778ff8644 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAddress.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEAddress.h @@ -44,6 +44,7 @@ public: bool operator ==(const NimBLEAddress & rhs) const; bool operator !=(const NimBLEAddress & rhs) const; operator std::string() const; + operator uint64_t() const; private: uint8_t m_address[6]; diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp index 3634bac8a..c53bb688b 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp @@ -37,6 +37,8 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() { m_serviceData = ""; m_txPower = 0; m_pScan = nullptr; + m_payloadLength = 0; + m_payload = nullptr; m_haveAppearance = false; m_haveManufacturerData = false; @@ -45,6 +47,7 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() { m_haveServiceData = false; m_haveServiceUUID = false; m_haveTXPower = false; + m_callbackSent = false; } // NimBLEAdvertisedDevice @@ -62,6 +65,16 @@ NimBLEAddress NimBLEAdvertisedDevice::getAddress() { } // getAddress +/** + * @brief Get the advertised type. + * + * @return The advertised type of the advertised device. + */ +uint8_t NimBLEAdvertisedDevice::getAdvType() { + return m_advType; +} // getAddress + + /** * @brief Get the appearance. * @@ -536,6 +549,11 @@ uint8_t NimBLEAdvertisedDevice::getAddressType() { } +time_t NimBLEAdvertisedDevice::getTimestamp() { + return m_timestamp; +} + + void NimBLEAdvertisedDevice::setAddressType(uint8_t type) { m_addressType = type; } diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h index 7a4115f28..c38d7001d 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h @@ -42,19 +42,39 @@ public: NimBLEAdvertisedDevice(); NimBLEAddress getAddress(); + uint8_t getAdvType(); uint16_t getAppearance(); std::string getManufacturerData(); + + template + T getManufacturerData(bool skipSizeCheck = false) { + std::string data = getManufacturerData(); + if(!skipSizeCheck && data.size() < sizeof(T)) return T(); + const char *pData = data.data(); + return *((T *)pData); + } + std::string getName(); int getRSSI(); NimBLEScan* getScan(); std::string getServiceData(); + + template + T getServiceData(bool skipSizeCheck = false) { + std::string data = getServiceData(); + if(!skipSizeCheck && data.size() < sizeof(T)) return T(); + const char *pData = data.data(); + return *((T *)pData); + } + NimBLEUUID getServiceDataUUID(); NimBLEUUID getServiceUUID(); int8_t getTXPower(); uint8_t* getPayload(); size_t getPayloadLength(); uint8_t getAddressType(); - void setAddressType(uint8_t type); + time_t getTimestamp(); + void setAddressType(uint8_t type); bool isAdvertisingService(const NimBLEUUID &uuid); @@ -95,7 +115,7 @@ private: bool m_haveTXPower; - NimBLEAddress m_address = NimBLEAddress(""); + NimBLEAddress m_address = NimBLEAddress(""); uint8_t m_advType; uint16_t m_appearance; int m_deviceType; @@ -108,8 +128,10 @@ private: std::string m_serviceData; NimBLEUUID m_serviceDataUUID; uint8_t* m_payload; - size_t m_payloadLength = 0; + size_t m_payloadLength; uint8_t m_addressType; + time_t m_timestamp; + bool m_callbackSent; }; /** diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp index 7c930bfc6..7e1e07ae3 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp @@ -100,7 +100,8 @@ void NimBLEAdvertising::setMaxInterval(uint16_t maxinterval) { m_advParams.itvl_max = maxinterval; } // setMaxInterval -// These are dummy functions for now for compatibility + +/* These are dummy functions for now for compatibility */ void NimBLEAdvertising::setMinPreferred(uint16_t mininterval) { //m_advData.min_interval = mininterval; } // @@ -108,7 +109,8 @@ void NimBLEAdvertising::setMinPreferred(uint16_t mininterval) { void NimBLEAdvertising::setMaxPreferred(uint16_t maxinterval) { //m_advData.max_interval = maxinterval; } // -////////////////////////////////////////////////////////// +/*******************************************************/ + void NimBLEAdvertising::setScanResponse(bool set) { m_scanResp = set; @@ -204,19 +206,19 @@ void NimBLEAdvertising::start() { } #endif - int numServices = m_serviceUUIDs.size(); - int rc = 0; - uint8_t addressType; - uint8_t payloadLen = 3; //start with 3 bytes for the flags data - // If already advertising just return if(ble_gap_adv_active()) { return; } - if (!m_customAdvData && !m_advSvcsSet && numServices > 0) { - for (int i = 0; i < numServices; i++) { - if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_16) { + int rc = 0; + + if (!m_customAdvData && !m_advDataSet) { + //start with 3 bytes for the flags data + uint8_t payloadLen = 3; + + for(auto &it : m_serviceUUIDs) { + if(it.getNative()->u.type == BLE_UUID_TYPE_16) { int add = (m_advData.num_uuids16 > 0) ? 2 : 4; if((payloadLen + add) > 31){ m_advData.uuids16_is_complete = 0; @@ -225,19 +227,19 @@ void NimBLEAdvertising::start() { payloadLen += add; if(nullptr == (m_advData.uuids16 = (ble_uuid16_t*)realloc(m_advData.uuids16, - (m_advData.num_uuids16 + 1) * sizeof(ble_uuid16_t)))) + (m_advData.num_uuids16 + 1) * sizeof(ble_uuid16_t)))) { NIMBLE_LOGE(LOG_TAG, "Error, no mem"); abort(); } memcpy(&m_advData.uuids16[m_advData.num_uuids16].value, - &m_serviceUUIDs[i].getNative()->u16.value, sizeof(uint16_t)); + &it.getNative()->u16.value, 2); m_advData.uuids16[m_advData.num_uuids16].u.type = BLE_UUID_TYPE_16; m_advData.uuids16_is_complete = 1; m_advData.num_uuids16++; } - if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_32) { + if(it.getNative()->u.type == BLE_UUID_TYPE_32) { int add = (m_advData.num_uuids32 > 0) ? 4 : 6; if((payloadLen + add) > 31){ m_advData.uuids32_is_complete = 0; @@ -246,19 +248,19 @@ void NimBLEAdvertising::start() { payloadLen += add; if(nullptr == (m_advData.uuids32 = (ble_uuid32_t*)realloc(m_advData.uuids32, - (m_advData.num_uuids32 + 1) * sizeof(ble_uuid32_t)))) + (m_advData.num_uuids32 + 1) * sizeof(ble_uuid32_t)))) { NIMBLE_LOGE(LOG_TAG, "Error, no mem"); abort(); } memcpy(&m_advData.uuids32[m_advData.num_uuids32].value, - &m_serviceUUIDs[i].getNative()->u32.value, sizeof(uint32_t)); + &it.getNative()->u32.value, 4); m_advData.uuids32[m_advData.num_uuids32].u.type = BLE_UUID_TYPE_32; m_advData.uuids32_is_complete = 1; m_advData.num_uuids32++; } - if(m_serviceUUIDs[i].getNative()->u.type == BLE_UUID_TYPE_128){ + if(it.getNative()->u.type == BLE_UUID_TYPE_128){ int add = (m_advData.num_uuids128 > 0) ? 16 : 18; if((payloadLen + add) > 31){ m_advData.uuids128_is_complete = 0; @@ -267,12 +269,13 @@ void NimBLEAdvertising::start() { payloadLen += add; if(nullptr == (m_advData.uuids128 = (ble_uuid128_t*)realloc(m_advData.uuids128, - (m_advData.num_uuids128 + 1) * sizeof(ble_uuid128_t)))) { + (m_advData.num_uuids128 + 1) * sizeof(ble_uuid128_t)))) + { NIMBLE_LOGE(LOG_TAG, "Error, no mem"); abort(); } memcpy(&m_advData.uuids128[m_advData.num_uuids128].value, - &m_serviceUUIDs[i].getNative()->u128.value, 16); + &it.getNative()->u128.value, 16); m_advData.uuids128[m_advData.num_uuids128].u.type = BLE_UUID_TYPE_128; m_advData.uuids128_is_complete = 1; @@ -315,11 +318,11 @@ void NimBLEAdvertising::start() { rc = ble_gap_adv_rsp_set_fields(&m_scanData); if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "error setting scan response data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + NIMBLE_LOGC(LOG_TAG, "error setting scan response data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); abort(); } // if not using scan response and there is room, - // throw the tx power data into the advertisment + // put the tx power data into the advertisment } else if (payloadLen < 29) { m_advData.tx_pwr_lvl_is_present = 1; m_advData.tx_pwr_lvl = NimBLEDevice::getPower(); @@ -327,7 +330,7 @@ void NimBLEAdvertising::start() { rc = ble_gap_adv_set_fields(&m_advData); if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "error setting advertisement data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + NIMBLE_LOGC(LOG_TAG, "error setting advertisement data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); abort(); } @@ -349,22 +352,16 @@ void NimBLEAdvertising::start() { m_advData.num_uuids16 = 0; } - m_advSvcsSet = true; - } - - rc = ble_hs_id_infer_auto(0, &addressType); - if (rc != 0) { - NIMBLE_LOGC(LOG_TAG, "Error determining address type; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); - abort(); + m_advDataSet = true; } #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - rc = ble_gap_adv_start(addressType, NULL, BLE_HS_FOREVER, + rc = ble_gap_adv_start(0, NULL, BLE_HS_FOREVER, &m_advParams, (pServer != nullptr) ? NimBLEServer::handleGapEvent : NULL, pServer); #else - rc = ble_gap_adv_start(addressType, NULL, BLE_HS_FOREVER, + rc = ble_gap_adv_start(0, NULL, BLE_HS_FOREVER, &m_advParams, NULL,NULL); #endif if (rc != 0) { @@ -398,7 +395,7 @@ void NimBLEAdvertising::stop() { * we need clear the flag so it reloads it. */ void NimBLEAdvertising::onHostReset() { - m_advSvcsSet = false; + m_advDataSet = false; } diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h index f30b1581c..ad76d7eec 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h @@ -27,7 +27,6 @@ /**************************/ #include "NimBLEUUID.h" -#include "FreeRTOS.h" #include @@ -103,7 +102,7 @@ private: bool m_customAdvData = false; // Are we using custom advertising data? bool m_customScanResponseData = false; // Are we using custom scan response data? bool m_scanResp = true; - bool m_advSvcsSet = false; + bool m_advDataSet = false; }; diff --git a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp index dd1be3bf0..0bd11f6ba 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp @@ -19,21 +19,18 @@ #include "NimBLE2902.h" #include "NimBLE2904.h" #include "NimBLEDevice.h" -#include "NimBLEUtils.h" #include "NimBLELog.h" -#include - #define NULL_HANDLE (0xffff) static NimBLECharacteristicCallbacks defaultCallback; - static const char* LOG_TAG = "NimBLECharacteristic"; /** * @brief Construct a characteristic * @param [in] uuid - UUID (const char*) for the characteristic. * @param [in] properties - Properties for the characteristic. + * @param [in] pService - pointer to the service instance this characteristic belongs to. */ NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties, NimBLEService* pService) : NimBLECharacteristic(NimBLEUUID(uuid), properties, pService) { @@ -43,6 +40,7 @@ NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties * @brief Construct a characteristic * @param [in] uuid - UUID for the characteristic. * @param [in] properties - Properties for the characteristic. + * @param [in] pService - pointer to the service instance this characteristic belongs to. */ NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties, NimBLEService* pService) { m_uuid = uuid; @@ -50,15 +48,10 @@ NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t prop m_properties = properties; m_pCallbacks = &defaultCallback; m_pService = pService; -// Backward Compatibility - to be removed -/* setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0); - setReadProperty((properties & PROPERTY_READ) != 0); - setWriteProperty((properties & PROPERTY_WRITE) != 0); - setNotifyProperty((properties & PROPERTY_NOTIFY) != 0); - setIndicateProperty((properties & PROPERTY_INDICATE) != 0); - setWriteNoResponseProperty((properties & PROPERTY_WRITE_NR) != 0); -*/ -/////////////////////////////////////////// + m_value = ""; + m_valMux = portMUX_INITIALIZER_UNLOCKED; + m_pTaskData = nullptr; + m_timestamp = 0; } // NimBLECharacteristic /** @@ -68,23 +61,6 @@ NimBLECharacteristic::~NimBLECharacteristic() { } // ~NimBLECharacteristic -/** - * @brief Associate a descriptor with this characteristic. - * @param [in] pDescriptor - * @return N/A. - */ -void NimBLECharacteristic::addDescriptor(NimBLEDescriptor* pDescriptor) { - NIMBLE_LOGD(LOG_TAG, ">> addDescriptor(): Adding %s to %s", pDescriptor->toString().c_str(), toString().c_str()); - // Check that we don't add the same descriptor twice. - if (m_descriptorMap.getByUUID(pDescriptor->getUUID()) != nullptr) { - NIMBLE_LOGW(LOG_TAG, "<< Adding a new descriptor with the same UUID as a previous one"); - //return; - } - m_descriptorMap.setByUUID(pDescriptor->getUUID(), pDescriptor); - NIMBLE_LOGD(LOG_TAG, "<< addDescriptor()"); -} // addDescriptor - - /** * @brief Create a new BLE Descriptor associated with this characteristic. * @param [in] uuid - The UUID of the descriptor. @@ -104,25 +80,26 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint3 */ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, uint32_t properties, uint16_t max_len) { NimBLEDescriptor* pDescriptor = nullptr; - if(uuid.equals(NimBLEUUID((uint16_t)0x2902))) { + if(uuid == NimBLEUUID(uint16_t(0x2902))) { if(!(m_properties & BLE_GATT_CHR_F_NOTIFY) && !(m_properties & BLE_GATT_CHR_F_INDICATE)) { assert(0 && "Cannot create 2902 descriptior without characteristic notification or indication property set"); } // We cannot have more than one 2902 descriptor, if it's already been created just return a pointer to it. - pDescriptor = m_descriptorMap.getByUUID(uuid); + pDescriptor = getDescriptorByUUID(uuid); if(pDescriptor == nullptr) { pDescriptor = new NimBLE2902(this); } else { return pDescriptor; } - } else if (uuid.equals(NimBLEUUID((uint16_t)0x2904))) { + } else if (uuid == NimBLEUUID(uint16_t(0x2904))) { pDescriptor = new NimBLE2904(this); } else { pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this); } - addDescriptor(pDescriptor); + + m_dscVec.push_back(pDescriptor); return pDescriptor; } // createCharacteristic @@ -132,8 +109,8 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, * @param [in] descriptorUUID The UUID of the descriptor that we wish to retrieve. * @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned. */ -NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* descriptorUUID) { - return m_descriptorMap.getByUUID(NimBLEUUID(descriptorUUID)); +NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* uuid) { + return getDescriptorByUUID(NimBLEUUID(uuid)); } // getDescriptorByUUID @@ -142,8 +119,13 @@ NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* descript * @param [in] descriptorUUID The UUID of the descriptor that we wish to retrieve. * @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned. */ -NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID &descriptorUUID) { - return m_descriptorMap.getByUUID(descriptorUUID); +NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID &uuid) { + for (auto &it : m_dscVec) { + if (it->getUUID() == uuid) { + return it; + } + } + return nullptr; } // getDescriptorByUUID @@ -155,13 +137,8 @@ uint16_t NimBLECharacteristic::getHandle() { return m_handle; } // getHandle -/* -void NimBLECharacteristic::setAccessPermissions(uint16_t perm) { - m_permissions = perm; -} -*/ -uint8_t NimBLECharacteristic::getProperties() { +uint16_t NimBLECharacteristic::getProperties() { return m_properties; } // getProperties @@ -187,26 +164,28 @@ NimBLEUUID NimBLECharacteristic::getUUID() { * @brief Retrieve the current value of the characteristic. * @return A pointer to storage containing the current characteristic value. */ -std::string NimBLECharacteristic::getValue() { - return m_value.getValue(); +std::string NimBLECharacteristic::getValue(time_t *timestamp) { + portENTER_CRITICAL(&m_valMux); + std::string retVal = m_value; + if(timestamp != nullptr) { + *timestamp = m_timestamp; + } + portEXIT_CRITICAL(&m_valMux); + + return retVal; } // getValue -/** - * @brief Retrieve the current raw data of the characteristic. - * @return A pointer to storage containing the current characteristic data. - */ -uint8_t* NimBLECharacteristic::getData() { - return m_value.getData(); -} // getData - - /** * @brief Retrieve the the current data length of the characteristic. * @return The length of the current characteristic data. */ -size_t NimBLECharacteristic:: getDataLength() { - return m_value.getLength(); +size_t NimBLECharacteristic::getDataLength() { + portENTER_CRITICAL(&m_valMux); + size_t len = m_value.length(); + portEXIT_CRITICAL(&m_valMux); + + return len; } @@ -225,32 +204,41 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){ switch(ctxt->op) { case BLE_GATT_ACCESS_OP_READ_CHR: { - //NIMBLE_LOGD(LOG_TAG, "read char pkthdr len:%d flags:%d", ctxt->om->om_pkthdr_len, ctxt->om->om_flags); // If the packet header is only 8 bytes this is a follow up of a long read // so we don't want to call the onRead() callback again. if(ctxt->om->om_pkthdr_len > 8) { pCharacteristic->m_pCallbacks->onRead(pCharacteristic); } - rc = os_mbuf_append(ctxt->om, pCharacteristic->getData(), pCharacteristic->m_value.getLength()); + + portENTER_CRITICAL(&pCharacteristic->m_valMux); + rc = os_mbuf_append(ctxt->om, (uint8_t*)pCharacteristic->m_value.data(), + pCharacteristic->m_value.length()); + portEXIT_CRITICAL(&pCharacteristic->m_valMux); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } case BLE_GATT_ACCESS_OP_WRITE_CHR: { - //NIMBLE_LOGD(LOG_TAG, "write char pkthdr len:%d datalen:%d", ctxt->om->om_pkthdr_len, ctxt->om->om_len); if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - //pCharacteristic->setValue(ctxt->om->om_data, ctxt->om->om_len); - pCharacteristic->m_value.addPart(ctxt->om->om_data, ctxt->om->om_len); + uint8_t buf[BLE_ATT_ATTR_MAX_LEN]; + size_t len = ctxt->om->om_len; + memcpy(buf, ctxt->om->om_data,len); + os_mbuf *next; next = SLIST_NEXT(ctxt->om, om_next); while(next != NULL){ - //NIMBLE_LOGD(LOG_TAG, "Found long write data, len:%d", next->om_len); - pCharacteristic->m_value.addPart(next->om_data, next->om_len); + if((len + next->om_len) > BLE_ATT_ATTR_MAX_LEN) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + memcpy(&buf[len-1], next->om_data, next->om_len); + len += next->om_len; next = SLIST_NEXT(next, om_next); } - pCharacteristic->m_value.commit(); + + pCharacteristic->setValue(buf, len); pCharacteristic->m_pCallbacks->onWrite(pCharacteristic); return 0; @@ -278,14 +266,19 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { subVal |= NIMBLE_DESC_FLAG_INDICATE; } - m_semaphoreConfEvt.give((subVal | NIMBLE_DESC_FLAG_INDICATE) ? 0 : - NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED); + if(m_pTaskData != nullptr) { + m_pTaskData->rc = (subVal & NIMBLE_DESC_FLAG_INDICATE) ? 0 : + NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED; + xTaskNotifyGive(m_pTaskData->task); + } - NIMBLE_LOGI(LOG_TAG, "New subscribe value for conn: %d val: %d", event->subscribe.conn_handle, subVal); + NIMBLE_LOGI(LOG_TAG, "New subscribe value for conn: %d val: %d", + event->subscribe.conn_handle, subVal); - NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID((uint16_t)0x2902); + NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID(uint16_t(0x2902)); if(p2902 == nullptr){ - ESP_LOGE(LOG_TAG, "No 2902 descriptor found for %s", getUUID().toString().c_str()); + ESP_LOGE(LOG_TAG, "No 2902 descriptor found for %s", + std::string(getUUID()).c_str()); return; } @@ -294,21 +287,28 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { p2902->m_pCallbacks->onWrite(p2902); - auto it = p2902->m_subscribedMap.find(event->subscribe.conn_handle); - if(subVal > 0 && it == p2902->m_subscribedMap.cend()) { - p2902->m_subscribedMap.insert(std::pair(event->subscribe.conn_handle, subVal)); - return; - } else if(it != p2902->m_subscribedMap.cend()) { - p2902->m_subscribedMap.erase(event->subscribe.conn_handle); - return; + auto it = p2902->m_subscribedVec.begin(); + for(;it != p2902->m_subscribedVec.end(); ++it) { + if((*it).conn_id == event->subscribe.conn_handle) { + break; + } } -/* - if(event->subscribe.reason == BLE_GAP_SUBSCRIBE_REASON_TERM) { - p2902->m_subscribedMap.erase(event->subscribe.conn_handle); - return; + + if(subVal > 0) { + if(it == p2902->m_subscribedVec.end()) { + chr_sub_status_t client_sub; + client_sub.conn_id = event->subscribe.conn_handle; + client_sub.sub_val = subVal; + p2902->m_subscribedVec.push_back(client_sub); + return; + } + + (*it).sub_val = subVal; + + } else if(it != p2902->m_subscribedVec.end()) { + p2902->m_subscribedVec.erase(it); + p2902->m_subscribedVec.shrink_to_fit(); } -*/ - (*it).second = subVal; } @@ -319,7 +319,7 @@ void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { * @return N/A */ void NimBLECharacteristic::indicate() { - NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", m_value.getValue().length()); + NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", getDataLength()); notify(false); NIMBLE_LOGD(LOG_TAG, "<< indicate"); } // indicate @@ -331,91 +331,102 @@ void NimBLECharacteristic::indicate() { * @return N/A. */ void NimBLECharacteristic::notify(bool is_notification) { - NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", m_value.getValue().length()); + NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", getDataLength()); - assert(getService() != nullptr); - assert(getService()->getServer() != nullptr); + NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID(uint16_t(0x2902)); + if(p2902 == nullptr) { + NIMBLE_LOGE(LOG_TAG, + "<< notify-Error; Notify/indicate not enabled for characterisitc: %s", + std::string(getUUID()).c_str()); + } - if (getService()->getServer()->getConnectedCount() == 0) { - NIMBLE_LOGD(LOG_TAG, "<< notify: No connected clients."); + if (p2902->m_subscribedVec.size() == 0) { + NIMBLE_LOGD(LOG_TAG, "<< notify: No clients subscribed."); return; } m_pCallbacks->onNotify(this); + std::string value = getValue(); + size_t length = value.length(); + bool reqSec = (m_properties & BLE_GATT_CHR_F_READ_AUTHEN) || + (m_properties & BLE_GATT_CHR_F_READ_AUTHOR) || + (m_properties & BLE_GATT_CHR_F_READ_ENC); int rc = 0; - NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID((uint16_t)0x2902); - for (auto it = p2902->m_subscribedMap.cbegin(); it != p2902->m_subscribedMap.cend(); ++it) { - uint16_t _mtu = getService()->getServer()->getPeerMTU((*it).first); - // Must rebuild the data on each loop iteration as NimBLE will release it. - size_t length = m_value.getValue().length(); - uint8_t* data = (uint8_t*)m_value.getValue().data(); - os_mbuf *om; + for (auto &it : p2902->m_subscribedVec) { + uint16_t _mtu = getService()->getServer()->getPeerMTU(it.conn_id); - if(_mtu == 0) { - //NIMBLE_LOGD(LOG_TAG, "peer not connected, removing from map"); - p2902->m_subscribedMap.erase((*it).first); - it = p2902->m_subscribedMap.cbegin(); - if(it == p2902->m_subscribedMap.cend()) { - return; - } + // check if connected and subscribed + if(_mtu == 0 || it.sub_val == 0) { continue; } + // check if security requirements are satisfied + if(reqSec) { + struct ble_gap_conn_desc desc; + rc = ble_gap_conn_find(it.conn_id, &desc); + if(rc != 0 || !desc.sec_state.encrypted) { + continue; + } + } + if (length > _mtu - 3) { NIMBLE_LOGW(LOG_TAG, "- Truncating to %d bytes (maximum notify size)", _mtu - 3); } - if((*it).second == 0) { - //NIMBLE_LOGI(LOG_TAG, "Skipping unsubscribed client"); - continue; - } - - if(is_notification && (!((*it).second & NIMBLE_DESC_FLAG_NOTIFY))) { + if(is_notification && (!(it.sub_val & NIMBLE_DESC_FLAG_NOTIFY))) { NIMBLE_LOGW(LOG_TAG, "Sending notification to client subscribed to indications, sending indication instead"); is_notification = false; } - if(!is_notification && (!((*it).second & NIMBLE_DESC_FLAG_INDICATE))) { + if(!is_notification && (!(it.sub_val & NIMBLE_DESC_FLAG_INDICATE))) { NIMBLE_LOGW(LOG_TAG, - "Sending indication to client subscribed to notifications, sending notifications instead"); + "Sending indication to client subscribed to notification, sending notification instead"); is_notification = true; } // don't create the m_buf until we are sure to send the data or else // we could be allocating a buffer that doesn't get released. // We also must create it in each loop iteration because it is consumed with each host call. - om = ble_hs_mbuf_from_flat(data, length); + os_mbuf *om = ble_hs_mbuf_from_flat((uint8_t*)value.data(), length); - if(!is_notification) { - m_semaphoreConfEvt.take("indicate"); - rc = ble_gattc_indicate_custom((*it).first, m_handle, om); + NimBLECharacteristicCallbacks::Status statusRC; + + if(!is_notification && (m_properties & NIMBLE_PROPERTY::INDICATE)) { + ble_task_data_t taskData = {nullptr, xTaskGetCurrentTaskHandle(),0, nullptr}; + m_pTaskData = &taskData; + + rc = ble_gattc_indicate_custom(it.conn_id, m_handle, om); if(rc != 0){ - m_semaphoreConfEvt.give(); - m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_GATT, rc); - return; + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_GATT; + } else { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = m_pTaskData->rc; } - rc = m_semaphoreConfEvt.wait(); + m_pTaskData = nullptr; - if(rc == BLE_HS_ETIMEOUT) { - m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT, rc); - } else if(rc == BLE_HS_EDONE) { - m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::SUCCESS_INDICATE, rc); + if(rc == BLE_HS_EDONE) { + rc = 0; + statusRC = NimBLECharacteristicCallbacks::Status::SUCCESS_INDICATE; + } else if(rc == BLE_HS_ETIMEOUT) { + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT; } else { - m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_FAILURE, rc); + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_FAILURE; } } else { - rc = ble_gattc_notify_custom((*it).first, m_handle, om); + rc = ble_gattc_notify_custom(it.conn_id, m_handle, om); if(rc == 0) { - m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::SUCCESS_NOTIFY, 0); + statusRC = NimBLECharacteristicCallbacks::Status::SUCCESS_NOTIFY; } else { - m_pCallbacks->onStatus(this, NimBLECharacteristicCallbacks::Status::ERROR_GATT, rc); + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_GATT; } } + + m_pCallbacks->onStatus(this, statusRC, rc); } NIMBLE_LOGD(LOG_TAG, "<< notify"); @@ -434,87 +445,6 @@ void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallback } } // setCallbacks -// Backward compatibility - to be removed //////////////////////////////// -/** - * @brief Set the permission to broadcast. - * A characteristics has properties associated with it which define what it is capable of doing. - * One of these is the broadcast flag. - * @param [in] value The flag value of the property. - * @return N/A - */ -void NimBLECharacteristic::setBroadcastProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_BROADCAST); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_BROADCAST); - } -} // setBroadcastProperty - - -/** - * @brief Set the Indicate property value. - * @param [in] value Set to true if we are to allow indicate messages. - */ -void NimBLECharacteristic::setIndicateProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_INDICATE); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_INDICATE); - } -} // setIndicateProperty - - -/** - * @brief Set the Notify property value. - * @param [in] value Set to true if we are to allow notification messages. - */ -void NimBLECharacteristic::setNotifyProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_NOTIFY); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_NOTIFY); - } -} // setNotifyProperty - - -/** - * @brief Set the Read property value. - * @param [in] value Set to true if we are to allow reads. - */ -void NimBLECharacteristic::setReadProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_READ); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_READ); - } -} // setReadProperty - - -/** - * @brief Set the Write No Response property value. - * @param [in] value Set to true if we are to allow writes with no response. - */ -void NimBLECharacteristic::setWriteNoResponseProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_WRITE_NO_RSP); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE_NO_RSP); - } -} // setWriteNoResponseProperty - - -/** - * @brief Set the Write property value. - * @param [in] value Set to true if we are to allow writes. - */ -void NimBLECharacteristic::setWriteProperty(bool value) { - if (value) { - m_properties = (m_properties | BLE_GATT_CHR_F_WRITE ); - } else { - m_properties = (m_properties & ~BLE_GATT_CHR_F_WRITE ); - } -} // setWriteProperty -////////////////////////////////////////////////////////////////////////////////// /** * @brief Set the value of the characteristic. @@ -522,21 +452,21 @@ void NimBLECharacteristic::setWriteProperty(bool value) { * @param [in] length The length of the data in bytes. */ void NimBLECharacteristic::setValue(const uint8_t* data, size_t length) { +#if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4) char* pHex = NimBLEUtils::buildHexData(nullptr, data, length); NIMBLE_LOGD(LOG_TAG, ">> setValue: length=%d, data=%s, characteristic UUID=%s", length, pHex, getUUID().toString().c_str()); free(pHex); +#endif if (length > BLE_ATT_ATTR_MAX_LEN) { NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN); return; } - m_value.setValue(data, length); - - // if(m_handle != NULL_HANDLE) { - //ble_gatts_chr_updated(m_handle); - // ble_gattc_notify(getService()->getServer()->m_connId, m_handle); - // } + portENTER_CRITICAL(&m_valMux); + m_value = std::string((char*)data, length); + m_timestamp = time(nullptr); + portEXIT_CRITICAL(&m_valMux); NIMBLE_LOGD(LOG_TAG, "<< setValue"); } // setValue @@ -553,41 +483,6 @@ void NimBLECharacteristic::setValue(const std::string &value) { setValue((uint8_t*)(value.data()), value.length()); } // setValue -void NimBLECharacteristic::setValue(uint16_t& data16) { - uint8_t temp[2]; - temp[0] = data16; - temp[1] = data16 >> 8; - setValue(temp, 2); -} // setValue - -void NimBLECharacteristic::setValue(uint32_t& data32) { - uint8_t temp[4]; - temp[0] = data32; - temp[1] = data32 >> 8; - temp[2] = data32 >> 16; - temp[3] = data32 >> 24; - setValue(temp, 4); -} // setValue - -void NimBLECharacteristic::setValue(int& data32) { - uint8_t temp[4]; - temp[0] = data32; - temp[1] = data32 >> 8; - temp[2] = data32 >> 16; - temp[3] = data32 >> 24; - setValue(temp, 4); -} // setValue - -void NimBLECharacteristic::setValue(float& data32) { - float temp = data32; - setValue((uint8_t*)&temp, 4); -} // setValue - -void NimBLECharacteristic::setValue(double& data64) { - double temp = data64; - setValue((uint8_t*)&temp, 8); -} // setValue - /** * @brief Return a string representation of the characteristic. diff --git a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h index 25e1ec7f7..4474e5f29 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h +++ b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h @@ -42,42 +42,15 @@ typedef enum { #include "NimBLEService.h" #include "NimBLEDescriptor.h" -#include "NimBLEUUID.h" -#include "NimBLEValue.h" -#include "FreeRTOS.h" #include -#include - +#include class NimBLEService; class NimBLEDescriptor; class NimBLECharacteristicCallbacks; -/** - * @brief A management structure for %BLE descriptors. - */ -class NimBLEDescriptorMap { -public: - void setByUUID(const char* uuid, NimBLEDescriptor* pDescriptor); - void setByUUID(const NimBLEUUID &uuid, NimBLEDescriptor* pDescriptor); -// void setByHandle(uint16_t handle, NimBLEDescriptor* pDescriptor); - NimBLEDescriptor* getByUUID(const char* uuid); - NimBLEDescriptor* getByUUID(const NimBLEUUID &uuid); -// NimBLEDescriptor* getByHandle(uint16_t handle); - std::string toString(); - NimBLEDescriptor* getFirst(); - NimBLEDescriptor* getNext(); - uint8_t getSize(); - -private: - std::map m_uuidMap; -// std::map m_handleMap; - std::map::iterator m_iterator; -}; - - /** * @brief The model of a %BLE Characteristic. * @@ -87,84 +60,78 @@ private: class NimBLECharacteristic { public: NimBLEDescriptor* createDescriptor(const char* uuid, - uint32_t properties = NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE, - uint16_t max_len = 100); + uint32_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + uint16_t max_len = 100); NimBLEDescriptor* createDescriptor(const NimBLEUUID &uuid, - uint32_t properties = NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE, - uint16_t max_len = 100); + uint32_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + uint16_t max_len = 100); - NimBLEDescriptor* getDescriptorByUUID(const char* descriptorUUID); - NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &descriptorUUID); + NimBLEDescriptor* getDescriptorByUUID(const char* uuid); + NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid); NimBLEUUID getUUID(); - std::string getValue(); - uint8_t* getData(); + std::string getValue(time_t *timestamp = nullptr); + + template + T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { + std::string value = getValue(); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + size_t getDataLength(); + void indicate(); + void notify(bool is_notification = true); + void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks); + void setValue(const uint8_t* data, size_t size); + void setValue(const std::string &value); - void indicate(); - void notify(bool is_notification = true); - void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks); -// Backward Compatibility - to be removed - void setBroadcastProperty(bool value); - void setIndicateProperty(bool value); - void setNotifyProperty(bool value); - void setReadProperty(bool value); - void setWriteProperty(bool value); - void setWriteNoResponseProperty(bool value); -////////////////////////////////////////////////////// - void setValue(const uint8_t* data, size_t size); - void setValue(const std::string &value); - void setValue(uint16_t& data16); - void setValue(uint32_t& data32); - void setValue(int& data32); - void setValue(float& data32); - void setValue(double& data64); + template + void setValue(const T &s) { + setValue((uint8_t*)&s, sizeof(T)); + } - std::string toString(); - uint16_t getHandle(); -// void setAccessPermissions(uint16_t perm); - -// Backward Compatibility - to be removed -/* static const uint32_t PROPERTY_READ = 1<<0; - static const uint32_t PROPERTY_WRITE = 1<<1; - static const uint32_t PROPERTY_NOTIFY = 1<<2; - static const uint32_t PROPERTY_BROADCAST = 1<<3; - static const uint32_t PROPERTY_INDICATE = 1<<4; - static const uint32_t PROPERTY_WRITE_NR = 1<<5; -*/ -////////////////////////////////////////////////////// + std::string toString(); + uint16_t getHandle(); private: - friend class NimBLEServer; - friend class NimBLEService; -// friend class NimBLEDescriptor; -// friend class NimBLECharacteristicMap; + friend class NimBLEServer; + friend class NimBLEService; - NimBLECharacteristic(const char* uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE, - NimBLEService* pService = nullptr); - NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE, - NimBLEService* pService = nullptr); - virtual ~NimBLECharacteristic(); + NimBLECharacteristic(const char* uuid, + uint16_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + NimBLECharacteristic(const NimBLEUUID &uuid, + uint16_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + + ~NimBLECharacteristic(); + + NimBLEService* getService(); + uint16_t getProperties(); + void setSubscribe(struct ble_gap_event *event); + static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); NimBLEUUID m_uuid; - NimBLEDescriptorMap m_descriptorMap; uint16_t m_handle; uint16_t m_properties; NimBLECharacteristicCallbacks* m_pCallbacks; NimBLEService* m_pService; - NimBLEValue m_value; -// uint16_t m_permissions; - - void addDescriptor(NimBLEDescriptor* pDescriptor); - NimBLEService* getService(); - uint8_t getProperties(); - void setSubscribe(struct ble_gap_event *event); - static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, void *arg); - - FreeRTOS::Semaphore m_semaphoreConfEvt = FreeRTOS::Semaphore("ConfEvt"); + std::string m_value; + std::vector m_dscVec; + ble_task_data_t *m_pTaskData; + portMUX_TYPE m_valMux; + time_t m_timestamp; }; // NimBLECharacteristic diff --git a/libesp32/NimBLE-Arduino/src/NimBLECharacteristicMap.cpp b/libesp32/NimBLE-Arduino/src/NimBLECharacteristicMap.cpp deleted file mode 100644 index b3cdcf9c6..000000000 --- a/libesp32/NimBLE-Arduino/src/NimBLECharacteristicMap.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * NimBLECharacteristicMap.cpp - * - * Created: on March 3, 2020 - * Author H2zero - * - * BLECharacteristicMap.cpp - * - * Created on: Jun 22, 2017 - * Author: kolban - */ -#include "sdkconfig.h" -#if defined(CONFIG_BT_ENABLED) - -#include "nimconfig.h" -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - -#include "NimBLEService.h" -#include "NimBLELog.h" - - -/** - * @brief Return the characteristic by handle. - * @param [in] handle The handle to look up the characteristic. - * @return The characteristic. - */ -NimBLECharacteristic* NimBLECharacteristicMap::getByHandle(uint16_t handle) { - return m_handleMap.at(handle); -} // getByHandle - - -/** - * @brief Return the characteristic by UUID. - * @param [in] UUID The UUID to look up the characteristic. - * @return The characteristic. - */ -NimBLECharacteristic* NimBLECharacteristicMap::getByUUID(const char* uuid) { - return getByUUID(NimBLEUUID(uuid)); -} - - -/** - * @brief Return the characteristic by UUID. - * @param [in] UUID The UUID to look up the characteristic. - * @return The characteristic. - */ -NimBLECharacteristic* NimBLECharacteristicMap::getByUUID(const NimBLEUUID &uuid) { - for (auto &myPair : m_uuidMap) { - if (myPair.first->getUUID().equals(uuid)) { - return myPair.first; - } - } - - return nullptr; -} // getByUUID - -/** - * @brief Get the number of characteristics in the map. - */ -uint8_t NimBLECharacteristicMap::getSize() { - return (uint8_t)m_uuidMap.size(); -} // getSize - -/** - * @brief Get the first characteristic in the map. - * @return The first characteristic in the map. - */ -NimBLECharacteristic* NimBLECharacteristicMap::getFirst() { - m_iterator = m_uuidMap.begin(); - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLECharacteristic* pRet = m_iterator->first; - m_iterator++; - return pRet; -} // getFirst - - -/** - * @brief Get the next characteristic in the map. - * @return The next characteristic in the map. - */ -NimBLECharacteristic* NimBLECharacteristicMap::getNext() { - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLECharacteristic* pRet = m_iterator->first; - m_iterator++; - return pRet; -} // getNext - - -/** - * @brief Set the characteristic by handle. - * @param [in] handle The handle of the characteristic. - * @param [in] characteristic The characteristic to cache. - * @return N/A. - */ -void NimBLECharacteristicMap::setByHandle(uint16_t handle, NimBLECharacteristic* characteristic) { - m_handleMap.insert(std::pair(handle, characteristic)); -} // setByHandle - - -/** - * @brief Set the characteristic by UUID. - * @param [in] uuid The uuid of the characteristic. - * @param [in] characteristic The characteristic to cache. - * @return N/A. - */ -void NimBLECharacteristicMap::setByUUID(NimBLECharacteristic* pCharacteristic, const NimBLEUUID &uuid) { - m_uuidMap.insert(std::pair(pCharacteristic, uuid.toString())); -} // setByUUID - - -/** - * @brief Return a string representation of the characteristic map. - * @return A string representation of the characteristic map. - */ -std::string NimBLECharacteristicMap::toString() { - std::string res; - int count = 0; - char hex[5]; - for (auto &myPair: m_uuidMap) { - if (count > 0) {res += "\n";} - snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle()); - count++; - res += "handle: 0x"; - res += hex; - res += ", uuid: " + myPair.first->getUUID().toString(); - } - return res; -} // toString - - -#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp b/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp index a385126d2..71f1c9afc 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp @@ -18,7 +18,6 @@ #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #include "NimBLEClient.h" -#include "NimBLEUtils.h" #include "NimBLEDevice.h" #include "NimBLELog.h" @@ -54,7 +53,10 @@ NimBLEClient::NimBLEClient() m_pClientCallbacks = &defaultCallbacks; m_conn_id = BLE_HS_CONN_HANDLE_NONE; m_isConnected = false; + m_waitingToConnect = false; m_connectTimeout = 30000; + m_deleteCallbacks = false; + m_pTaskData = nullptr; m_pConnParams.scan_itvl = 16; // Scan interval in 0.625ms units (NimBLE Default) m_pConnParams.scan_window = 16; // Scan window in 0.625ms units (NimBLE Default) @@ -74,7 +76,7 @@ NimBLEClient::NimBLEClient() NimBLEClient::~NimBLEClient() { // We may have allocated service references associated with this client. // Before we are finished with the client, we must release resources. - clearServices(); + deleteServices(); if(m_deleteCallbacks && m_pClientCallbacks != &defaultCallbacks) { delete m_pClientCallbacks; @@ -84,18 +86,40 @@ NimBLEClient::~NimBLEClient() { /** - * @brief Clear any existing services. + * @brief Delete any existing services. */ -void NimBLEClient::clearServices() { - NIMBLE_LOGD(LOG_TAG, ">> clearServices"); +void NimBLEClient::deleteServices() { + NIMBLE_LOGD(LOG_TAG, ">> deleteServices"); // Delete all the services. for(auto &it: m_servicesVector) { delete it; } m_servicesVector.clear(); - NIMBLE_LOGD(LOG_TAG, "<< clearServices"); -} // clearServices + NIMBLE_LOGD(LOG_TAG, "<< deleteServices"); +} // deleteServices + + +/** + * @brief Delete service by UUID + * @param [in] uuid The UUID of the service to be deleted from the local database. + * @return Number of services left. + */ +size_t NimBLEClient::deleteService(const NimBLEUUID &uuid) { + NIMBLE_LOGD(LOG_TAG, ">> deleteService"); + // Delete the requested service. + for(auto it = m_servicesVector.begin(); it != m_servicesVector.end(); ++it) { + if((*it)->getUUID() == uuid) { + delete *it; + m_servicesVector.erase(it); + break; + } + } + + NIMBLE_LOGD(LOG_TAG, "<< deleteService"); + + return m_servicesVector.size(); +} // deleteServices /** @@ -135,6 +159,10 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr return false; } + if(!NimBLEDevice::getScan()->stop()) { + return false; + } + int rc = 0; m_peerAddress = address; @@ -142,7 +170,8 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr memcpy(&peerAddrt.val, address.getNative(),6); peerAddrt.type = type; - m_semaphoreOpenEvt.take("connect"); + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + m_pTaskData = &taskData; /** Try to connect the the advertiser. Allow 30 seconds (30000 ms) for * timeout (default value of m_connectTimeout). @@ -152,7 +181,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peerAddrt, m_connectTimeout, &m_pConnParams, NimBLEClient::handleGapEvent, this); if(rc == BLE_HS_EBUSY) { - vTaskDelay(1); + vTaskDelay(1 / portTICK_PERIOD_MS); } }while(rc == BLE_HS_EBUSY); @@ -162,23 +191,23 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr type, m_peerAddress.toString().c_str(), rc, NimBLEUtils::returnCodeToString(rc)); - - m_semaphoreOpenEvt.give(); + m_pTaskData = nullptr; m_waitingToConnect = false; return false; } m_waitingToConnect = true; - rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete. + // Wait for the connection to complete. + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - if(rc != 0){ + if(taskData.rc != 0){ return false; } if(refreshServices) { NIMBLE_LOGD(LOG_TAG, "Refreshing Services for: (%s)", address.toString().c_str()); - clearServices(); + deleteServices(); } m_pClientCallbacks->onConnect(this); @@ -194,17 +223,18 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr * @return True on success. */ bool NimBLEClient::secureConnection() { - - m_semeaphoreSecEvt.take("secureConnection"); + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + m_pTaskData = &taskData; int rc = NimBLEDevice::startSecurity(m_conn_id); if(rc != 0){ - m_semeaphoreSecEvt.give(); + m_pTaskData = nullptr; return false; } - rc = m_semeaphoreSecEvt.wait("secureConnection"); - if(rc != 0){ + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if(taskData.rc != 0){ return false; } @@ -220,15 +250,11 @@ int NimBLEClient::disconnect(uint8_t reason) { NIMBLE_LOGD(LOG_TAG, ">> disconnect()"); int rc = 0; if(m_isConnected){ - m_isConnected = false; // flag the disconnect now so no calls are performed after rc = ble_gap_terminate(m_conn_id, reason); if(rc != 0){ NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); } - // Sometimes a disconnect event is not sent so we need to make sure - // the device can be found again. - NimBLEDevice::removeIgnored(m_peerAddress); } NIMBLE_LOGD(LOG_TAG, "<< disconnect()"); @@ -394,15 +420,13 @@ NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) { * @param [in] bool value to indicate if the current vector should be cleared and * subsequently all services retrieved from the peripheral. * If false the vector will be returned with the currently stored services, - * if vector is empty it will retrieve all services from the peripheral. + * If true it will retrieve all services from the peripheral and return the vector with all services * @return a pointer to the vector of available services. */ std::vector* NimBLEClient::getServices(bool refresh) { if(refresh) { - clearServices(); - } + deleteServices(); - if(m_servicesVector.empty()) { if (!retrieveServices()) { NIMBLE_LOGE(LOG_TAG, "Error: Failed to get services"); } @@ -442,30 +466,31 @@ bool NimBLEClient::retrieveServices(const NimBLEUUID *uuid_filter) { */ NIMBLE_LOGD(LOG_TAG, ">> retrieveServices"); - int rc = 0; if(!m_isConnected){ NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve services -aborting"); return false; } - m_semaphoreSearchCmplEvt.take("retrieveServices"); + int rc = 0; + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; if(uuid_filter == nullptr) { - rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, this); + rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, &taskData); } else { rc = ble_gattc_disc_svc_by_uuid(m_conn_id, &uuid_filter->getNative()->u, - NimBLEClient::serviceDiscoveredCB, this); + NimBLEClient::serviceDiscoveredCB, &taskData); } if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_svcs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); - m_semaphoreSearchCmplEvt.give(); return false; } // wait until we have all the services - if(m_semaphoreSearchCmplEvt.wait("retrieveServices") == 0){ + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if(taskData.rc == 0){ NIMBLE_LOGD(LOG_TAG, "<< retrieveServices"); return true; } @@ -489,41 +514,34 @@ int NimBLEClient::serviceDiscoveredCB( NIMBLE_LOGD(LOG_TAG,"Service Discovered >> status: %d handle: %d", error->status, (error->status == 0) ? service->start_handle : -1); - NimBLEClient *peer = (NimBLEClient*)arg; - int rc=0; + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLEClient *client = (NimBLEClient*)pTaskData->pATT; // Make sure the service discovery is for this device - if(peer->getConnId() != conn_handle){ + if(client->getConnId() != conn_handle){ return 0; } - switch (error->status) { - case 0: { - // Found a service - add it to the vector - NimBLERemoteService* pRemoteService = new NimBLERemoteService(peer, service); - peer->m_servicesVector.push_back(pRemoteService); - break; - } - case BLE_HS_EDONE:{ - // All services discovered; start discovering characteristics. - - //NIMBLE_LOGD(LOG_TAG,"Giving search semaphore - completed"); - peer->m_semaphoreSearchCmplEvt.give(0); - rc = 0; - break; - } - default: - // Error; abort discovery. - rc = error->status; - break; + if(error->status == 0) { + // Found a service - add it to the vector + NimBLERemoteService* pRemoteService = new NimBLERemoteService(client, service); + client->m_servicesVector.push_back(pRemoteService); + return 0; } - if (rc != 0) { - // pass non-zero to semaphore on error to indicate an error finding services - peer->m_semaphoreSearchCmplEvt.give(1); + if(error->status == BLE_HS_EDONE) { + pTaskData->rc = 0; + } else { + NIMBLE_LOGE(LOG_TAG, "characteristicDiscCB() rc=%d %s", + error->status, + NimBLEUtils::returnCodeToString(error->status)); + pTaskData->rc = error->status; } - NIMBLE_LOGD(LOG_TAG,"<< Service Discovered. status: %d", rc); - return rc; + + xTaskNotifyGive(pTaskData->task); + + NIMBLE_LOGD(LOG_TAG,"<< << Service Discovered"); + return error->status; } @@ -595,15 +613,11 @@ uint16_t NimBLEClient::getMTU() { * @param [in] arg = pointer to the client instance */ /*STATIC*/ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) { - NimBLEClient* client = (NimBLEClient*)arg; - //struct ble_gap_conn_desc desc; - //struct ble_hs_adv_fields fields; int rc; NIMBLE_LOGD(LOG_TAG, "Got Client event %s", NimBLEUtils::gapEventToString(event->type)); - // Execute handler code based on the type of event received. switch(event->type) { case BLE_GAP_EVENT_DISCONNECT: { @@ -620,9 +634,6 @@ uint16_t NimBLEClient::getMTU() { NIMBLE_LOGI(LOG_TAG, "disconnect; reason=%d, %s", event->disconnect.reason, NimBLEUtils::returnCodeToString(event->disconnect.reason)); - //print_conn_desc(&event->disconnect.conn); - //MODLOG_DFLT(INFO, "\n"); - // If Host reset tell the device now before returning to prevent // any errors caused by calling host functions before resyncing. @@ -639,15 +650,9 @@ uint16_t NimBLEClient::getMTU() { } //client->m_conn_id = BLE_HS_CONN_HANDLE_NONE; - - // Indicate a non-success return value to any semaphores waiting - client->m_semaphoreOpenEvt.give(1); - client->m_semaphoreSearchCmplEvt.give(1); - client->m_semeaphoreSecEvt.give(1); - client->m_pClientCallbacks->onDisconnect(client); - - return 0; + rc = event->disconnect.reason; + break; } // BLE_GAP_EVENT_DISCONNECT case BLE_GAP_EVENT_CONNECT: { @@ -667,30 +672,25 @@ uint16_t NimBLEClient::getMTU() { client->m_conn_id = event->connect.conn_handle; - // rc = ble_gap_conn_find(event->connect.conn_handle, &desc); - // assert(rc == 0); - // print_conn_desc(&desc); - // MODLOG_DFLT(INFO, "\n"); - - - // In the case of a multiconnecting device we ignore this device when - // scanning since we are already connected to it - NimBLEDevice::addIgnored(client->m_peerAddress); - rc = ble_gattc_exchange_mtu(client->m_conn_id, NULL,NULL); if(rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gattc_exchange_mtu: rc=%d %s",rc, NimBLEUtils::returnCodeToString(rc)); - // if error getting mtu indicate a connection error. - client->m_semaphoreOpenEvt.give(rc); + break; } + + // In the case of a multiconnecting device we ignore this device when + // scanning since we are already connected to it + NimBLEDevice::addIgnored(client->m_peerAddress); } else { - // Connection attempt failed NIMBLE_LOGE(LOG_TAG, "Error: Connection failed; status=%d %s", event->connect.status, NimBLEUtils::returnCodeToString(event->connect.status)); + + client->m_isConnected = false; + rc = event->connect.status; + break; } - client->m_semaphoreOpenEvt.give(event->connect.status); return 0; } // BLE_GAP_EVENT_CONNECT @@ -701,7 +701,7 @@ uint16_t NimBLEClient::getMTU() { NIMBLE_LOGD(LOG_TAG, "Notify Recieved for handle: %d",event->notify_rx.attr_handle); for(auto &it: client->m_servicesVector) { - // Dont waste cycles searching services without this handle in their range + // Dont waste cycles searching services without this handle in its range if(it->getEndHandle() < event->notify_rx.attr_handle) { continue; } @@ -720,6 +720,11 @@ uint16_t NimBLEClient::getMTU() { if(characteristic != cVector->cend()) { NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", (*characteristic)->toString().c_str()); + portENTER_CRITICAL(&(*characteristic)->m_valMux); + (*characteristic)->m_value = std::string((char *)event->notify_rx.om->om_data, event->notify_rx.om->om_len); + (*characteristic)->m_timestamp = time(nullptr); + portEXIT_CRITICAL(&(*characteristic)->m_valMux); + if ((*characteristic)->m_notifyCallback != nullptr) { NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s", (*characteristic)->toString().c_str()); @@ -727,7 +732,6 @@ uint16_t NimBLEClient::getMTU() { event->notify_rx.om->om_len, !event->notify_rx.indication); } - break; } } @@ -738,7 +742,7 @@ uint16_t NimBLEClient::getMTU() { case BLE_GAP_EVENT_CONN_UPDATE_REQ: case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: { if(client->m_conn_id != event->conn_update_req.conn_handle){ - return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE + return 0; } NIMBLE_LOGD(LOG_TAG, "Peer requesting to update connection parameters"); NIMBLE_LOGD(LOG_TAG, "MinInterval: %d, MaxInterval: %d, Latency: %d, Timeout: %d", @@ -764,7 +768,7 @@ uint16_t NimBLEClient::getMTU() { case BLE_GAP_EVENT_CONN_UPDATE: { if(client->m_conn_id != event->conn_update.conn_handle){ - return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE + return 0; } if(event->conn_update.status == 0) { NIMBLE_LOGI(LOG_TAG, "Connection parameters updated."); @@ -776,7 +780,7 @@ uint16_t NimBLEClient::getMTU() { case BLE_GAP_EVENT_ENC_CHANGE: { if(client->m_conn_id != event->enc_change.conn_handle){ - return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE + return 0; } if(event->enc_change.status == 0) { @@ -791,23 +795,23 @@ uint16_t NimBLEClient::getMTU() { } } - client->m_semeaphoreSecEvt.give(event->enc_change.status); - return 0; + rc = event->enc_change.status; + break; } //BLE_GAP_EVENT_ENC_CHANGE case BLE_GAP_EVENT_MTU: { if(client->m_conn_id != event->mtu.conn_handle){ - return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE + return 0; } NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d", event->mtu.conn_handle, event->mtu.value); - client->m_semaphoreOpenEvt.give(0); - return 0; + rc = 0; + break; } // BLE_GAP_EVENT_MTU case BLE_GAP_EVENT_PASSKEY_ACTION: { - struct ble_sm_io pkey = {0}; + struct ble_sm_io pkey = {0,0}; if(client->m_conn_id != event->passkey.conn_handle) return 0; @@ -868,6 +872,14 @@ uint16_t NimBLEClient::getMTU() { return 0; } } // Switch + + if(client->m_pTaskData != nullptr) { + client->m_pTaskData->rc = rc; + xTaskNotifyGive(client->m_pTaskData->task); + client->m_pTaskData = nullptr; + } + + return 0; } // handleGapEvent diff --git a/libesp32/NimBLE-Arduino/src/NimBLEClient.h b/libesp32/NimBLE-Arduino/src/NimBLEClient.h index 4bf2c33d2..888b42d02 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEClient.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEClient.h @@ -21,17 +21,14 @@ #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) #include "NimBLEAddress.h" +#include "NimBLEUUID.h" +#include "NimBLEUtils.h" #include "NimBLEAdvertisedDevice.h" #include "NimBLERemoteService.h" #include #include -typedef struct { - const NimBLEUUID *uuid; - const void *attribute; -} disc_filter_t; - class NimBLERemoteService; class NimBLEClientCallbacks; class NimBLEAdvertisedDevice; @@ -52,6 +49,8 @@ public: std::vector::iterator end(); NimBLERemoteService* getService(const char* uuid); NimBLERemoteService* getService(const NimBLEUUID &uuid); + void deleteServices(); + size_t deleteService(const NimBLEUUID &uuid); std::string getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID); bool setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID, const std::string &value); @@ -82,19 +81,16 @@ private: const struct ble_gatt_error *error, const struct ble_gatt_svc *service, void *arg); - void clearServices(); bool retrieveServices(const NimBLEUUID *uuid_filter = nullptr); NimBLEAddress m_peerAddress = NimBLEAddress(""); uint16_t m_conn_id; - bool m_isConnected = false; - bool m_waitingToConnect =false; - bool m_deleteCallbacks = true; + bool m_isConnected; + bool m_waitingToConnect; + bool m_deleteCallbacks; int32_t m_connectTimeout; - NimBLEClientCallbacks* m_pClientCallbacks = nullptr; - FreeRTOS::Semaphore m_semaphoreOpenEvt = FreeRTOS::Semaphore("OpenEvt"); - FreeRTOS::Semaphore m_semaphoreSearchCmplEvt = FreeRTOS::Semaphore("SearchCmplEvt"); - FreeRTOS::Semaphore m_semeaphoreSecEvt = FreeRTOS::Semaphore("Security"); + NimBLEClientCallbacks* m_pClientCallbacks; + ble_task_data_t *m_pTaskData; std::vector m_servicesVector; diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp index 0d414d316..e8f7f9f8b 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp @@ -50,6 +50,7 @@ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_ m_pCharacteristic = nullptr; // No initial characteristic. m_pCallbacks = &defaultCallbacks; // No initial callback. m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value. + m_valMux = portMUX_INITIALIZER_UNLOCKED; m_properties = 0; if (properties & BLE_GATT_CHR_F_READ) { // convert uint16_t properties to uint8_t @@ -137,17 +138,37 @@ int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, if(ble_uuid_cmp(uuid, &pDescriptor->getUUID().getNative()->u) == 0){ switch(ctxt->op) { case BLE_GATT_ACCESS_OP_READ_DSC: { - pDescriptor->m_pCallbacks->onRead(pDescriptor); + // If the packet header is only 8 bytes this is a follow up of a long read + // so we don't want to call the onRead() callback again. + if(ctxt->om->om_pkthdr_len > 8) { + pDescriptor->m_pCallbacks->onRead(pDescriptor); + } + portENTER_CRITICAL(&pDescriptor->m_valMux); rc = os_mbuf_append(ctxt->om, pDescriptor->getValue(), pDescriptor->getLength()); + portEXIT_CRITICAL(&pDescriptor->m_valMux); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } case BLE_GATT_ACCESS_OP_WRITE_DSC: { - if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) { + if (ctxt->om->om_len > pDescriptor->m_value.attr_max_len) { return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } - pDescriptor->setValue(ctxt->om->om_data, ctxt->om->om_len); + uint8_t buf[pDescriptor->m_value.attr_max_len]; + size_t len = ctxt->om->om_len; + memcpy(buf, ctxt->om->om_data,len); + os_mbuf *next; + next = SLIST_NEXT(ctxt->om, om_next); + while(next != NULL){ + if((len + next->om_len) > pDescriptor->m_value.attr_max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + memcpy(&buf[len-1], next->om_data, next->om_len); + len += next->om_len; + next = SLIST_NEXT(next, om_next); + } + + pDescriptor->setValue(buf, len); pDescriptor->m_pCallbacks->onWrite(pDescriptor); return 0; } @@ -191,12 +212,14 @@ void NimBLEDescriptor::setHandle(uint16_t handle) { * @param [in] length The length of the data in bytes. */ void NimBLEDescriptor::setValue(const uint8_t* data, size_t length) { - if (length > BLE_ATT_ATTR_MAX_LEN) { - NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN); + if (length > m_value.attr_max_len) { + NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, m_value.attr_max_len); return; } + portENTER_CRITICAL(&m_valMux); m_value.attr_len = length; memcpy(m_value.attr_value, data, length); + portEXIT_CRITICAL(&m_valMux); } // setValue @@ -209,13 +232,6 @@ void NimBLEDescriptor::setValue(const std::string &value) { } // setValue -/* -void NimBLEDescriptor::setAccessPermissions(uint8_t perm) { - m_permissions = perm; -} -*/ - - /** * @brief Return a string representation of the descriptor. * @return A string representation of the descriptor. diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h index 8af3560d3..f4978f570 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h @@ -22,20 +22,17 @@ #include "NimBLECharacteristic.h" #include "NimBLEUUID.h" -#include "FreeRTOS.h" #include typedef struct { - uint16_t attr_max_len; /*!< attribute max value length */ - uint16_t attr_len; /*!< attribute current value length */ - uint8_t *attr_value; /*!< the pointer to attribute value */ + uint16_t attr_max_len; /*!< attribute max value length */ + uint16_t attr_len; /*!< attribute current value length */ + uint8_t *attr_value; /*!< the pointer to attribute value */ } attr_value_t; -typedef attr_value_t esp_attr_value_t; /*!< compatibility for esp32 */ - class NimBLEService; class NimBLECharacteristic; class NimBLEDescriptorCallbacks; @@ -46,32 +43,39 @@ class NimBLEDescriptorCallbacks; */ class NimBLEDescriptor { public: - virtual ~NimBLEDescriptor(); - uint16_t getHandle(); // Get the handle of the descriptor. - size_t getLength(); // Get the length of the value of the descriptor. - NimBLEUUID getUUID(); // Get the UUID of the descriptor. - uint8_t* getValue(); // Get a pointer to the value of the descriptor. -// void setAccessPermissions(uint8_t perm); // Set the permissions of the descriptor. - void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); // Set callbacks to be invoked for the descriptor. - void setValue(const uint8_t* data, size_t size); // Set the value of the descriptor as a pointer to data. - void setValue(const std::string &value); // Set the value of the descriptor as a data buffer. + uint16_t getHandle(); + size_t getLength(); + NimBLEUUID getUUID(); + uint8_t* getValue(); + void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); + void setValue(const uint8_t* data, size_t size); + void setValue(const std::string &value); + std::string toString(); - std::string toString(); // Convert the descriptor to a string representation. + template + void setValue(const T &s) { + setValue((uint8_t*)&s, sizeof(T)); + } private: - friend class NimBLEDescriptorMap; friend class NimBLECharacteristic; friend class NimBLEService; friend class NimBLE2902; friend class NimBLE2904; NimBLEDescriptor(const char* uuid, uint16_t properties, - uint16_t max_len, - NimBLECharacteristic* pCharacteristic); + uint16_t max_len, + NimBLECharacteristic* pCharacteristic); NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, - uint16_t max_len, - NimBLECharacteristic* pCharacteristic); + uint16_t max_len, + NimBLECharacteristic* pCharacteristic); + + ~NimBLEDescriptor(); + + static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + void setHandle(uint16_t handle); NimBLEUUID m_uuid; uint16_t m_handle; @@ -79,12 +83,8 @@ private: NimBLECharacteristic* m_pCharacteristic; uint8_t m_properties; attr_value_t m_value; - - static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, void *arg); - - void setHandle(uint16_t handle); -}; // BLEDescriptor + portMUX_TYPE m_valMux; +}; // NimBLEDescriptor /** diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDescriptorMap.cpp b/libesp32/NimBLE-Arduino/src/NimBLEDescriptorMap.cpp deleted file mode 100644 index 0ca1cbeeb..000000000 --- a/libesp32/NimBLE-Arduino/src/NimBLEDescriptorMap.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * NimBLEDescriptorMap.cpp - * - * Created: on March 10, 2020 - * Author H2zero - * - * Originally: - * - * BLEDescriptorMap.cpp - * - * Created on: Jun 22, 2017 - * Author: kolban - */ -#include "sdkconfig.h" -#if defined(CONFIG_BT_ENABLED) - -#include "nimconfig.h" -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - -#include "NimBLECharacteristic.h" -#include "NimBLEDescriptor.h" - - -/** - * @brief Return the descriptor by UUID. - * @param [in] UUID The UUID to look up the descriptor. - * @return The descriptor. If not present, then nullptr is returned. - */ -NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(const char* uuid) { - return getByUUID(NimBLEUUID(uuid)); -} - - -/** - * @brief Return the descriptor by UUID. - * @param [in] UUID The UUID to look up the descriptor. - * @return The descriptor. If not present, then nullptr is returned. - */ -NimBLEDescriptor* NimBLEDescriptorMap::getByUUID(const NimBLEUUID &uuid) { - for (auto &myPair : m_uuidMap) { - if (myPair.first->getUUID().equals(uuid)) { - return myPair.first; - } - } - return nullptr; -} // getByUUID - - -/** - * @brief Return the descriptor by handle. - * @param [in] handle The handle to look up the descriptor. - * @return The descriptor. - */ - /* -NimBLEDescriptor* NimBLEDescriptorMap::getByHandle(uint16_t handle) { - return m_handleMap.at(handle); -} // getByHandle -*/ - -/** - * @brief Set the descriptor by UUID. - * @param [in] uuid The uuid of the descriptor. - * @param [in] characteristic The descriptor to cache. - * @return N/A. - */ -void NimBLEDescriptorMap::setByUUID(const char* uuid, NimBLEDescriptor* pDescriptor){ - m_uuidMap.insert(std::pair(pDescriptor, uuid)); -} // setByUUID - - - -/** - * @brief Set the descriptor by UUID. - * @param [in] uuid The uuid of the descriptor. - * @param [in] characteristic The descriptor to cache. - * @return N/A. - */ -void NimBLEDescriptorMap::setByUUID(const NimBLEUUID &uuid, NimBLEDescriptor* pDescriptor) { - m_uuidMap.insert(std::pair(pDescriptor, uuid.toString())); -} // setByUUID - - -/** - * @brief Set the descriptor by handle. - * @param [in] handle The handle of the descriptor. - * @param [in] descriptor The descriptor to cache. - * @return N/A. - */ - /* -void NimBLEDescriptorMap::setByHandle(uint16_t handle, NimBLEDescriptor* pDescriptor) { - m_handleMap.insert(std::pair(handle, pDescriptor)); -} // setByHandle -*/ - - -/** - * @brief Get the number of descriptors in the map. - */ -uint8_t NimBLEDescriptorMap::getSize() { - return (uint8_t)m_uuidMap.size(); -} // getSize - - -/** - * @brief Return a string representation of the descriptor map. - * @return A string representation of the descriptor map. - */ -std::string NimBLEDescriptorMap::toString() { - std::string res; - char hex[5]; - int count = 0; - for (auto &myPair : m_uuidMap) { - if (count > 0) {res += "\n";} - snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle()); - count++; - res += "handle: 0x"; - res += hex; - res += ", uuid: " + myPair.first->getUUID().toString(); - } - return res; -} // toString - - -/** - * @brief Get the first descriptor in the map. - * @return The first descriptor in the map. - */ -NimBLEDescriptor* NimBLEDescriptorMap::getFirst() { - m_iterator = m_uuidMap.begin(); - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLEDescriptor* pRet = m_iterator->first; - m_iterator++; - return pRet; -} // getFirst - - -/** - * @brief Get the next descriptor in the map. - * @return The next descriptor in the map. - */ -NimBLEDescriptor* NimBLEDescriptorMap::getNext() { - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLEDescriptor* pRet = m_iterator->first; - m_iterator++; - return pRet; -} // getNext - -#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp b/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp index 1695a5177..b3d882ba3 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp @@ -152,21 +152,26 @@ void NimBLEDevice::stopAdvertising() { return false; } + int rc =0; + if(pClient->m_isConnected) { - if (pClient->disconnect() != 0) { + rc = pClient->disconnect(); + if (rc != 0 && rc != BLE_HS_EALREADY && rc != BLE_HS_ENOTCONN) { return false; } + while(pClient->m_isConnected) { - vTaskDelay(1); + vTaskDelay(10); } } if(pClient->m_waitingToConnect) { - if(ble_gap_conn_cancel() != 0){ + rc = ble_gap_conn_cancel(); + if (rc != 0 && rc != BLE_HS_EALREADY) { return false; } while(pClient->m_waitingToConnect) { - vTaskDelay(1); + vTaskDelay(10); } } diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDevice.h b/libesp32/NimBLE-Arduino/src/NimBLEDevice.h index c4a6d0417..412647987 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEDevice.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEDevice.h @@ -116,6 +116,7 @@ public: static void setSecurityPasskey(uint32_t pin); static uint32_t getSecurityPasskey(); static void setSecurityCallbacks(NimBLESecurityCallbacks* pCallbacks); + static int startSecurity(uint16_t conn_id); static int setMTU(uint16_t mtu); static uint16_t getMTU(); static bool isIgnored(const NimBLEAddress &address); @@ -159,7 +160,6 @@ private: static void onReset(int reason); static void onSync(void); static void host_task(void *param); - static int startSecurity(uint16_t conn_id); static bool m_synced; #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) diff --git a/libesp32/NimBLE-Arduino/src/NimBLELog.h b/libesp32/NimBLE-Arduino/src/NimBLELog.h index b519c0faa..6e9ed97f3 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLELog.h +++ b/libesp32/NimBLE-Arduino/src/NimBLELog.h @@ -25,25 +25,25 @@ #if CORE_DEBUG_LEVEL >= 4 #define NIMBLE_LOGD( tag, format, ... ) MODLOG_DFLT(ERROR, "D %s: "#format"\n",tag,##__VA_ARGS__) #else -#define NIMBLE_LOGD( tag, format, ... ) +#define NIMBLE_LOGD( tag, format, ... ) (void)tag #endif #if CORE_DEBUG_LEVEL >= 3 #define NIMBLE_LOGI( tag, format, ... ) MODLOG_DFLT(ERROR, "I %s: "#format"\n",tag,##__VA_ARGS__) #else -#define NIMBLE_LOGI( tag, format, ... ) +#define NIMBLE_LOGI( tag, format, ... ) (void)tag #endif #if CORE_DEBUG_LEVEL >= 2 #define NIMBLE_LOGW( tag, format, ... ) MODLOG_DFLT(ERROR, "W %s: "#format"\n",tag,##__VA_ARGS__) #else -#define NIMBLE_LOGW( tag, format, ... ) +#define NIMBLE_LOGW( tag, format, ... ) (void)tag #endif #if CORE_DEBUG_LEVEL >= 1 #define NIMBLE_LOGE( tag, format, ... ) MODLOG_DFLT(ERROR, "E %s: "#format"\n",tag,##__VA_ARGS__) #else -#define NIMBLE_LOGE( tag, format, ... ) +#define NIMBLE_LOGE( tag, format, ... ) (void)tag #endif #define NIMBLE_LOGC( tag, format, ... ) MODLOG_DFLT(CRITICAL, "CRIT %s: "#format"\n",tag,##__VA_ARGS__) diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp index 85760b433..23089ca77 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp @@ -53,13 +53,14 @@ static const char* LOG_TAG = "NimBLERemoteCharacteristic"; m_uuid = nullptr; break; } + m_handle = chr->val_handle; m_defHandle = chr->def_handle; m_charProp = chr->properties; m_pRemoteService = pRemoteService; m_notifyCallback = nullptr; - m_rawData = nullptr; - m_dataLen = 0; + m_timestamp = 0; + m_valMux = portMUX_INITIALIZER_UNLOCKED; } // NimBLERemoteCharacteristic @@ -67,10 +68,7 @@ static const char* LOG_TAG = "NimBLERemoteCharacteristic"; *@brief Destructor. */ NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() { - removeDescriptors(); // Release resources for any descriptor information we may have allocated. - if(m_rawData != nullptr) { - free(m_rawData); - } + deleteDescriptors(); } // ~NimBLERemoteCharacteristic /* @@ -150,12 +148,12 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, NIMBLE_LOGD(LOG_TAG,"Descriptor Discovered >> status: %d handle: %d", error->status, (error->status == 0) ? dsc->handle : -1); - disc_filter_t *filter = (disc_filter_t*)arg; - NimBLEUUID *uuid_filter = (NimBLEUUID*)filter->uuid; - NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)filter->attribute; + desc_filter_t *filter = (desc_filter_t*)arg; + const NimBLEUUID *uuid_filter = filter->uuid; + ble_task_data_t *pTaskData = (ble_task_data_t*)filter->task_data; + NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT; int rc=0; - // Make sure the discovery is for this device if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ return 0; } @@ -175,7 +173,7 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, rc = BLE_HS_EDONE; } } - // Found a descriptor - add it to the vector + NimBLERemoteDescriptor* pNewRemoteDescriptor = new NimBLERemoteDescriptor(characteristic, dsc); characteristic->m_descriptorVector.push_back(pNewRemoteDescriptor); break; @@ -185,18 +183,20 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, break; } - /** If rc == BLE_HS_EDONE, release the semaphore with a success error code and stop the discovery process. + /** If rc == BLE_HS_EDONE, resume the task with a success error code and stop the discovery process. * Else if rc == 0, just return 0 to continue the discovery until we get BLE_HS_EDONE. - * If we get any other error code tell the application to abort by returning non-zero in the semaphore rc. + * If we get any other error code tell the application to abort by returning non-zero in the rc. */ if (rc == BLE_HS_EDONE) { - characteristic->m_semaphoreGetDescEvt.give(0); + pTaskData->rc = 0; + xTaskNotifyGive(pTaskData->task); } else if(rc != 0) { - /* Error; abort discovery. */ - // pass error code to semaphore waiting - characteristic->m_semaphoreGetDescEvt.give(rc); + // Error; abort discovery. + pTaskData->rc = rc; + xTaskNotifyGive(pTaskData->task); } - NIMBLE_LOGD(LOG_TAG,"<< Descriptor Discovered. status: %d", rc); + + NIMBLE_LOGD(LOG_TAG,"<< Descriptor Discovered. status: %d", pTaskData->rc); return rc; } @@ -209,11 +209,8 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filt NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str()); int rc = 0; - disc_filter_t filter; - filter.uuid = uuid_filter; - filter.attribute = this; - - m_semaphoreGetDescEvt.take("retrieveDescriptors"); + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + desc_filter_t filter = {uuid_filter, &taskData}; rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(), m_handle, @@ -222,11 +219,12 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filt &filter); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); - m_semaphoreGetDescEvt.give(); return false; } - if(m_semaphoreGetDescEvt.wait("retrieveDescriptors") != 0) { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if(taskData.rc != 0) { return false; } @@ -272,10 +270,8 @@ NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUU */ std::vector* NimBLERemoteCharacteristic::getDescriptors(bool refresh) { if(refresh) { - removeDescriptors(); - } + deleteDescriptors(); - if(m_descriptorVector.empty()) { if (!retrieveDescriptors()) { NIMBLE_LOGE(LOG_TAG, "Error: Failed to get descriptors"); } @@ -340,16 +336,28 @@ NimBLEUUID NimBLERemoteCharacteristic::getUUID() { } // getUUID +/** + * @brief Get the value of the remote characteristic. + * @return The value of the remote characteristic. + */ +std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) { + portENTER_CRITICAL(&m_valMux); + std::string value = m_value; + if(timestamp != nullptr) { + *timestamp = m_timestamp; + } + portEXIT_CRITICAL(&m_valMux); + + return value; +} + + /** * @brief Read an unsigned 16 bit value * @return The unsigned 16 bit value. */ uint16_t NimBLERemoteCharacteristic::readUInt16() { - std::string value = readValue(); - if (value.length() >= 2) { - return *(uint16_t*)(value.data()); - } - return 0; + return readValue(); } // readUInt16 @@ -358,11 +366,7 @@ uint16_t NimBLERemoteCharacteristic::readUInt16() { * @return the unsigned 32 bit value. */ uint32_t NimBLERemoteCharacteristic::readUInt32() { - std::string value = readValue(); - if (value.length() >= 4) { - return *(uint32_t*)(value.data()); - } - return 0; + return readValue(); } // readUInt32 @@ -371,49 +375,52 @@ uint32_t NimBLERemoteCharacteristic::readUInt32() { * @return The value as a byte */ uint8_t NimBLERemoteCharacteristic::readUInt8() { - std::string value = readValue(); - if (value.length() >= 1) { - return (uint8_t)value[0]; - } - return 0; + return readValue(); } // readUInt8 +/** + * @brief Read a float value. + * @return the float value. + */ +float NimBLERemoteCharacteristic::readFloat() { + return readValue(); +} // readFloat + + /** * @brief Read the value of the remote characteristic. * @return The value of the remote characteristic. */ -std::string NimBLERemoteCharacteristic::readValue() { +std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) { NIMBLE_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x", getUUID().toString().c_str(), getHandle(), getHandle()); - int rc = 0; - int retryCount = 1; - // Clear the value before reading. - m_value = ""; - NimBLEClient* pClient = getRemoteService()->getClient(); + std::string value; - // Check to see that we are connected. if (!pClient->isConnected()) { NIMBLE_LOGE(LOG_TAG, "Disconnected"); - return ""; + return value; } - do { - m_semaphoreReadCharEvt.take("readValue"); + int rc = 0; + int retryCount = 1; + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(),0, &value}; + do { rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, NimBLERemoteCharacteristic::onReadCB, - this); + &taskData); if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "Error: Failed to read characteristic; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); - m_semaphoreReadCharEvt.give(0); - return ""; + return value; } - rc = m_semaphoreReadCharEvt.wait("readValue"); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = taskData.rc; + switch(rc){ case 0: case BLE_HS_EDONE: @@ -431,12 +438,21 @@ std::string NimBLERemoteCharacteristic::readValue() { break; /* Else falls through. */ default: - return ""; + NIMBLE_LOGE(LOG_TAG, "<< readValue rc=%d", rc); + return value; } } while(rc != 0 && retryCount--); - NIMBLE_LOGD(LOG_TAG, "<< readValue(): length: %d", m_value.length()); - return m_value; + portENTER_CRITICAL(&m_valMux); + m_value = value; + m_timestamp = time(nullptr); + if(timestamp != nullptr) { + *timestamp = m_timestamp; + } + portEXIT_CRITICAL(&m_valMux); + + NIMBLE_LOGD(LOG_TAG, "<< readValue length: %d rc=%d", value.length(), rc); + return value; } // readValue @@ -448,31 +464,91 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg) { - NimBLERemoteCharacteristic* characteristic = (NimBLERemoteCharacteristic*)arg; + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT; uint16_t conn_id = characteristic->getRemoteService()->getClient()->getConnId(); - // Make sure the read is for this client if(conn_id != conn_handle) { return 0; } + NIMBLE_LOGI(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle); - if(error->status == 0) { - if(attr) { - NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len); + std::string *strBuf = (std::string*)pTaskData->buf; + int rc = error->status; - characteristic->m_value += std::string((char*) attr->om->om_data, attr->om->om_len); - return 0; + if(rc == 0) { + if(attr) { + if(((*strBuf).length() + attr->om->om_len) > BLE_ATT_ATTR_MAX_LEN) { + rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } else { + NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len); + (*strBuf) += std::string((char*) attr->om->om_data, attr->om->om_len); + return 0; + } } } - // Read complete release semaphore and let the app can continue. - characteristic->m_semaphoreReadCharEvt.give(error->status); - return 0; + + pTaskData->rc = rc; + xTaskNotifyGive(pTaskData->task); + + return rc; } /** - * @brief Register for notifications. + * @brief Subscribe or unsubscribe for notifications or indications. + * @param [in] uint16_t val 0x00 to unsubscribe, 0x01 for notifications, 0x02 for indications. + * @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then no callback + * is performed for notifications. + * @return true if successful. + */ +bool NimBLERemoteCharacteristic::setNotify(uint16_t val, bool response, notify_callback notifyCallback) { + NIMBLE_LOGD(LOG_TAG, ">> setNotify(): %s, %02x", toString().c_str(), val); + + NimBLERemoteDescriptor* desc = getDescriptor(NimBLEUUID((uint16_t)0x2902)); + if(desc == nullptr) { + NIMBLE_LOGE(LOG_TAG, "<< setNotify(): Could not get descriptor"); + return false; + } + + m_notifyCallback = notifyCallback; + + NIMBLE_LOGD(LOG_TAG, "<< setNotify()"); + + return desc->writeValue((uint8_t *)&val, 2, response); +} // setNotify + + +/** + * @brief Subscribe for notifications or indications. + * @param [in] bool if true, subscribe for notifications, false subscribe for indications. + * @param [in] bool if true, require a write response from the descriptor write operation. + * @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then no callback + * is performed for notifications. + * @return true if successful. + */ +bool NimBLERemoteCharacteristic::subscribe(bool notifications, bool response, notify_callback notifyCallback) { + if(notifications) { + return setNotify(0x01, response, notifyCallback); + } else { + return setNotify(0x02, response, notifyCallback); + } +} // subscribe + + +/** + * @brief Unsubscribe for notifications or indications. + * @param [in] bool if true, require a write response from the descriptor write operation. + * @return true if successful. + */ +bool NimBLERemoteCharacteristic::unsubscribe(bool response) { + return setNotify(0x00, response); +} // unsubscribe + + + /** + * @brief backward-compatibility method for subscribe/unsubscribe notifications/indications * @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then we are * unregistering for notifications. * @param [in] bool if true, register for notifications, false register for indications. @@ -480,46 +556,54 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle, * @return true if successful. */ bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback, bool notifications, bool response) { - NIMBLE_LOGD(LOG_TAG, ">> registerForNotify(): %s", toString().c_str()); - - m_notifyCallback = notifyCallback; // Save the notification callback. - - uint8_t val[] = {0x01, 0x00}; - - NimBLERemoteDescriptor* desc = getDescriptor(NimBLEUUID((uint16_t)0x2902)); - if(desc == nullptr) - return false; - - if(notifyCallback != nullptr){ - if(!notifications){ - val[0] = 0x02; - } + bool success; + if(notifyCallback != nullptr) { + success = subscribe(notifications, response, notifyCallback); + } else { + success = unsubscribe(response); } - - else if (notifyCallback == nullptr){ - val[0] = 0x00; - } - - NIMBLE_LOGD(LOG_TAG, "<< registerForNotify()"); - - return desc->writeValue(val, 2, response); + return success; } // registerForNotify /** * @brief Delete the descriptors in the descriptor vector. * We maintain a vector called m_descriptorVector that contains pointers to BLERemoteDescriptors - * object references. Since we allocated these in this class, we are also responsible for deleteing + * object references. Since we allocated these in this class, we are also responsible for deleting * them. This method does just that. * @return N/A. */ -void NimBLERemoteCharacteristic::removeDescriptors() { - // Iterate through all the descriptors releasing their storage and erasing them from the vector. +void NimBLERemoteCharacteristic::deleteDescriptors() { + NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptors"); + for(auto &it: m_descriptorVector) { delete it; } m_descriptorVector.clear(); -} // removeCharacteristics + NIMBLE_LOGD(LOG_TAG, "<< deleteDescriptors"); +} // deleteDescriptors + + +/** + * @brief Delete descriptor by UUID + * @param [in] uuid The UUID of the descriptor to be deleted. + * @return Number of services left. + */ +size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID &uuid) { + NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptor"); + + for(auto it = m_descriptorVector.begin(); it != m_descriptorVector.end(); ++it) { + if((*it)->getUUID() == uuid) { + delete *it; + m_descriptorVector.erase(it); + break; + } + } + + NIMBLE_LOGD(LOG_TAG, "<< deleteDescriptor"); + + return m_descriptorVector.size(); +} // deleteDescriptor /** @@ -559,19 +643,6 @@ bool NimBLERemoteCharacteristic::writeValue(const std::string &newValue, bool re } // writeValue -/** - * @brief Write the new value for the characteristic. - * - * This is a convenience function. Many BLE characteristics are a single byte of data. - * @param [in] newValue The new byte value to write. - * @param [in] response Whether we require a response from the write. - * @return false if not connected or cant perform write for some reason. - */ -bool NimBLERemoteCharacteristic::writeValue(uint8_t newValue, bool response) { - return writeValue(&newValue, 1, response); -} // writeValue - - /** * @brief Write the new value for the characteristic from a data buffer. * @param [in] data A pointer to a data buffer. @@ -584,47 +655,45 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length, NIMBLE_LOGD(LOG_TAG, ">> writeValue(), length: %d", length); NimBLEClient* pClient = getRemoteService()->getClient(); - int rc = 0; - int retryCount = 1; - uint16_t mtu; - // Check to see that we are connected. if (!pClient->isConnected()) { NIMBLE_LOGE(LOG_TAG, "Disconnected"); return false; } - mtu = ble_att_mtu(pClient->getConnId()) - 3; + int rc = 0; + int retryCount = 1; + uint16_t mtu = ble_att_mtu(pClient->getConnId()) - 3; - // Check if the data length is longer than we can write in 1 connection event. + // Check if the data length is longer than we can write in one connection event. // If so we must do a long write which requires a response. if(length <= mtu && !response) { rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length); return (rc==0); } - do { - m_semaphoreWriteCharEvt.take("writeValue"); + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + do { if(length > mtu) { NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length); os_mbuf *om = ble_hs_mbuf_from_flat(data, length); rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om, NimBLERemoteCharacteristic::onWriteCB, - this); + &taskData); } else { rc = ble_gattc_write_flat(pClient->getConnId(), m_handle, data, length, NimBLERemoteCharacteristic::onWriteCB, - this); + &taskData); } if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "Error: Failed to write characteristic; rc=%d", rc); - m_semaphoreWriteCharEvt.give(); return false; } - rc = m_semaphoreWriteCharEvt.wait("writeValue"); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = taskData.rc; switch(rc){ case 0: @@ -644,11 +713,12 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length, break; /* Else falls through. */ default: + NIMBLE_LOGE(LOG_TAG, "<< writeValue, rc: %d", rc); return false; } } while(rc != 0 && retryCount--); - NIMBLE_LOGD(LOG_TAG, "<< writeValue, rc: %d",rc); + NIMBLE_LOGD(LOG_TAG, "<< writeValue, rc: %d", rc); return (rc == 0); } // writeValue @@ -661,59 +731,21 @@ int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg) { - NimBLERemoteCharacteristic* characteristic = (NimBLERemoteCharacteristic*)arg; + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT; - // Make sure the discovery is for this device if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ return 0; } NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle); - characteristic->m_semaphoreWriteCharEvt.give(error->status); + pTaskData->rc = error->status; + xTaskNotifyGive(pTaskData->task); return 0; } -/** - * @brief Read raw data from remote characteristic as hex bytes - * @return uint8_t pointer to the data read. - */ -uint8_t* NimBLERemoteCharacteristic::readRawData() { - if(m_rawData != nullptr) { - free(m_rawData); - m_rawData = nullptr; - } - - m_dataLen = m_value.length(); - // If we have data copy it to rawData - if(m_dataLen) { - m_rawData = (uint8_t*) calloc(m_dataLen, sizeof(uint8_t)); - memcpy(m_rawData, m_value.data(), m_dataLen); - } - - return m_rawData; -} - - -/** - * @brief Get the length of the data read from the remote characteristic. - * @return size_t length of the data in bytes. - */ -size_t NimBLERemoteCharacteristic::getDataLength() { - return m_value.length(); -} - - -void NimBLERemoteCharacteristic::releaseSemaphores() { - for (auto &it: m_descriptorVector) { - it->releaseSemaphores(); - } - m_semaphoreWriteCharEvt.give(1); - m_semaphoreGetDescEvt.give(1); - m_semaphoreReadCharEvt.give(1); -} - #endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h index 0b7d490d6..364efb59d 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h @@ -32,6 +32,12 @@ class NimBLERemoteDescriptor; typedef void (*notify_callback)(NimBLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify); +typedef struct { + const NimBLEUUID *uuid; + void *task_data; +} desc_filter_t; + + /** * @brief A model of a remote %BLE characteristic. */ @@ -50,26 +56,54 @@ public: std::vector::iterator end(); NimBLERemoteDescriptor* getDescriptor(const NimBLEUUID &uuid); std::vector* getDescriptors(bool refresh = false); + void deleteDescriptors(); + size_t deleteDescriptor(const NimBLEUUID &uuid); uint16_t getHandle(); uint16_t getDefHandle(); NimBLEUUID getUUID(); - std::string readValue(); - uint8_t readUInt8(); - uint16_t readUInt16(); - uint32_t readUInt32(); - bool registerForNotify(notify_callback _callback, + std::string readValue(time_t *timestamp = nullptr); + + template + T readValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { + std::string value = readValue(timestamp); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + + uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue()"))); + uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue()"))); + uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue()"))); + float readFloat() __attribute__ ((deprecated("Use template readValue()"))); + std::string getValue(time_t *timestamp = nullptr); + + template + T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { + std::string value = getValue(timestamp); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + + bool subscribe(bool notifications = true, + bool response = true, + notify_callback notifyCallback = nullptr); + bool unsubscribe(bool response = true); + bool registerForNotify(notify_callback notifyCallback, bool notifications = true, - bool response = true); + bool response = true) + __attribute__ ((deprecated("Use subscribe()/unsubscribe()"))); bool writeValue(const uint8_t* data, size_t length, bool response = false); bool writeValue(const std::string &newValue, bool response = false); - bool writeValue(uint8_t newValue, - bool response = false); + template + bool writeValue(const T &s, bool response = false) { + return writeValue((uint8_t*)&s, sizeof(T), response); + } + std::string toString(); - uint8_t* readRawData(); - size_t getDataLength(); NimBLERemoteService* getRemoteService(); private: @@ -81,13 +115,12 @@ private: friend class NimBLERemoteDescriptor; // Private member functions - void removeDescriptors(); + bool setNotify(uint16_t val, bool response = true, notify_callback notifyCallback = nullptr); bool retrieveDescriptors(const NimBLEUUID *uuid_filter = nullptr); static int onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg); static int onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg); - void releaseSemaphores(); static int descriptorDiscCB(uint16_t conn_handle, const struct ble_gatt_error *error, uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, void *arg); @@ -98,13 +131,10 @@ private: uint16_t m_handle; uint16_t m_defHandle; NimBLERemoteService* m_pRemoteService; - FreeRTOS::Semaphore m_semaphoreGetDescEvt = FreeRTOS::Semaphore("GetDescEvt"); - FreeRTOS::Semaphore m_semaphoreReadCharEvt = FreeRTOS::Semaphore("ReadCharEvt"); - FreeRTOS::Semaphore m_semaphoreWriteCharEvt = FreeRTOS::Semaphore("WriteCharEvt"); std::string m_value; - uint8_t* m_rawData; - size_t m_dataLen; notify_callback m_notifyCallback; + time_t m_timestamp; + portMUX_TYPE m_valMux; // We maintain a vector of descriptors owned by this characteristic. std::vector m_descriptorVector; diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp index 057a68a1c..d17ae6a0e 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp @@ -45,9 +45,9 @@ NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemo m_uuid = nullptr; break; } + m_handle = dsc->handle; m_pRemoteCharacteristic = pRemoteCharacteristic; - } @@ -78,96 +78,6 @@ NimBLEUUID NimBLERemoteDescriptor::getUUID() { } // getUUID -/** - * @brief Callback for Descriptor read operation. - * @return 0 or error code. - */ -int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, void *arg) -{ - NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)arg; - uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId(); - - // Make sure the discovery is for this device - if(conn_id != conn_handle){ - return 0; - } - - NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle); - - if(error->status == 0){ - if(attr){ - NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len); - - desc->m_value += std::string((char*) attr->om->om_data, attr->om->om_len); - return 0; - } - } - - // Read complete release semaphore and let the app can continue. - desc->m_semaphoreReadDescrEvt.give(error->status); - return 0; -} - - -std::string NimBLERemoteDescriptor::readValue() { - NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str()); - - int rc = 0; - int retryCount = 1; - // Clear the value before reading. - m_value = ""; - - NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient(); - - // Check to see that we are connected. - if (!pClient->isConnected()) { - NIMBLE_LOGE(LOG_TAG, "Disconnected"); - return ""; - } - - do { - m_semaphoreReadDescrEvt.take("ReadDescriptor"); - - rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, - NimBLERemoteDescriptor::onReadCB, - this); - if (rc != 0) { - NIMBLE_LOGE(LOG_TAG, "Error: Failed to read descriptor; rc=%d, %s", - rc, NimBLEUtils::returnCodeToString(rc)); - m_semaphoreReadDescrEvt.give(0); - return ""; - } - - rc = m_semaphoreReadDescrEvt.wait("ReadDescriptor"); - - switch(rc){ - case 0: - case BLE_HS_EDONE: - rc = 0; - break; - // Descriptor is not long-readable, return with what we have. - case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): - NIMBLE_LOGI(LOG_TAG, "Attribute not long"); - rc = 0; - break; - case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): - case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): - case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): - if (retryCount && pClient->secureConnection()) - break; - /* Else falls through. */ - default: - return ""; - } - } while(rc != 0 && retryCount--); - - NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %d", m_value.length()); - return m_value; -} // readValue - - uint8_t NimBLERemoteDescriptor::readUInt8() { std::string value = readValue(); if (value.length() >= 1) { @@ -195,6 +105,100 @@ uint32_t NimBLERemoteDescriptor::readUInt32() { } // readUInt32 +std::string NimBLERemoteDescriptor::readValue() { + NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str()); + + NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient(); + std::string value; + + if (!pClient->isConnected()) { + NIMBLE_LOGE(LOG_TAG, "Disconnected"); + return value; + } + + int rc = 0; + int retryCount = 1; + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(),0, &value}; + + do { + rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, + NimBLERemoteDescriptor::onReadCB, + &taskData); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to read descriptor; rc=%d, %s", + rc, NimBLEUtils::returnCodeToString(rc)); + return value; + } + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = taskData.rc; + + switch(rc){ + case 0: + case BLE_HS_EDONE: + rc = 0; + break; + // Descriptor is not long-readable, return with what we have. + case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): + NIMBLE_LOGI(LOG_TAG, "Attribute not long"); + rc = 0; + break; + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): + if (retryCount && pClient->secureConnection()) + break; + /* Else falls through. */ + default: + return value; + } + } while(rc != 0 && retryCount--); + + NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %d rc=%d", value.length(), rc); + return value; +} // readValue + + +/** + * @brief Callback for Descriptor read operation. + * @return 0 or error code. + */ +int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)pTaskData->pATT; + uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId(); + + if(conn_id != conn_handle){ + return 0; + } + + NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle); + + std::string *strBuf = (std::string*)pTaskData->buf; + int rc = error->status; + + if(rc == 0) { + if(attr) { + if(((*strBuf).length() + attr->om->om_len) > BLE_ATT_ATTR_MAX_LEN) { + rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } else { + NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len); + (*strBuf) += std::string((char*) attr->om->om_data, attr->om->om_len); + return 0; + } + } + } + + pTaskData->rc = rc; + xTaskNotifyGive(pTaskData->task); + + return rc; +} + + /** * @brief Return a string representation of this BLE Remote Descriptor. * @retun A string representation of this BLE Remote Descriptor. @@ -218,16 +222,17 @@ int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg) { - NimBLERemoteDescriptor* descriptor = (NimBLERemoteDescriptor*)arg; + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteDescriptor* descriptor = (NimBLERemoteDescriptor*)pTaskData->pATT; - // Make sure the discovery is for this device if(descriptor->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId() != conn_handle){ return 0; } - NIMBLE_LOGD(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle); + NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle); - descriptor->m_semaphoreDescWrite.give(error->status); + pTaskData->rc = error->status; + xTaskNotifyGive(pTaskData->task); return 0; } @@ -245,17 +250,15 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient(); - int rc = 0; - int retryCount = 1; - uint16_t mtu; - // Check to see that we are connected. if (!pClient->isConnected()) { NIMBLE_LOGE(LOG_TAG, "Disconnected"); return false; } - mtu = ble_att_mtu(pClient->getConnId()) - 3; + int rc = 0; + int retryCount = 1; + uint16_t mtu = ble_att_mtu(pClient->getConnId()) - 3; // Check if the data length is longer than we can write in 1 connection event. // If so we must do a long write which requires a response. @@ -264,31 +267,31 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool return (rc == 0); } - do { - m_semaphoreDescWrite.take("WriteDescriptor"); + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + do { if(length > mtu) { NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length); os_mbuf *om = ble_hs_mbuf_from_flat(data, length); rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om, NimBLERemoteDescriptor::onWriteCB, - this); + &taskData); } else { rc = ble_gattc_write_flat(pClient->getConnId(), m_handle, data, length, NimBLERemoteDescriptor::onWriteCB, - this); + &taskData); } if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "Error: Failed to write descriptor; rc=%d", rc); - m_semaphoreDescWrite.give(); return false; } - rc = m_semaphoreDescWrite.wait("WriteDescriptor"); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = taskData.rc; - switch(rc){ + switch(rc) { case 0: case BLE_HS_EDONE: rc = 0; @@ -325,23 +328,5 @@ bool NimBLERemoteDescriptor::writeValue(const std::string &newValue, bool respon } // writeValue -/** - * @brief Write a byte value to the Descriptor. - * @param [in] The single byte to write. - * @param [in] True if we expect a response. - */ -bool NimBLERemoteDescriptor::writeValue(uint8_t newValue, bool response) { - return writeValue(&newValue, 1, response); -} // writeValue - - -/** - * @brief In the event of an error this is called to make sure we don't block. - */ -void NimBLERemoteDescriptor::releaseSemaphores() { - m_semaphoreDescWrite.give(1); - m_semaphoreReadDescrEvt.give(1); -} - #endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h index 23fe13f6b..554e9dc16 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h @@ -31,15 +31,26 @@ public: uint16_t getHandle(); NimBLERemoteCharacteristic* getRemoteCharacteristic(); NimBLEUUID getUUID(); - std::string readValue(void); - uint8_t readUInt8(void); - uint16_t readUInt16(void); - uint32_t readUInt32(void); + std::string readValue(); + + template + T readValue(bool skipSizeCheck = false) { + std::string value = readValue(); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + + uint8_t readUInt8() __attribute__ ((deprecated)); + uint16_t readUInt16() __attribute__ ((deprecated)); + uint32_t readUInt32() __attribute__ ((deprecated)); std::string toString(void); bool writeValue(const uint8_t* data, size_t length, bool response = false); bool writeValue(const std::string &newValue, bool response = false); - bool writeValue(uint8_t newValue, bool response = false); - + template + bool writeValue(const T &s, bool response = false) { + return writeValue((uint8_t*)&s, sizeof(T), response); + } private: friend class NimBLERemoteCharacteristic; @@ -50,16 +61,10 @@ private: struct ble_gatt_attr *attr, void *arg); static int onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, struct ble_gatt_attr *attr, void *arg); - void releaseSemaphores(); uint16_t m_handle; NimBLEUUID m_uuid; - std::string m_value; NimBLERemoteCharacteristic* m_pRemoteCharacteristic; - FreeRTOS::Semaphore m_semaphoreReadDescrEvt = FreeRTOS::Semaphore("ReadDescrEvt"); - FreeRTOS::Semaphore m_semaphoreDescWrite = FreeRTOS::Semaphore("WriteDescEvt"); - - }; #endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp index 193a40b1a..db9eabca1 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp @@ -58,7 +58,7 @@ NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble * Also release any semaphores they may be holding. */ NimBLERemoteService::~NimBLERemoteService() { - removeCharacteristics(); + deleteCharacteristics(); } @@ -118,17 +118,15 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEU * @param [in] bool value to indicate if the current vector should be cleared and * subsequently all characteristics for this service retrieved from the peripheral. * If false the vector will be returned with the currently stored characteristics, - * if the vector is empty it will retrieve all characteristics of this service - * from the peripheral. + * If true it will retrieve all characteristics of this service from the peripheral + * and return the vector with all characteristics for this service. * @return a pointer to the vector of descriptors for this characteristic. */ std::vector* NimBLERemoteService::getCharacteristics(bool refresh) { if(refresh) { - removeCharacteristics(); - } + deleteCharacteristics(); - if(m_characteristicVector.empty()) { if (!retrieveCharacteristics()) { NIMBLE_LOGE(LOG_TAG, "Error: Failed to get characteristics"); } @@ -150,43 +148,34 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, NIMBLE_LOGD(LOG_TAG,"Characteristic Discovered >> status: %d handle: %d", error->status, (error->status == 0) ? chr->val_handle : -1); - NimBLERemoteService *service = (NimBLERemoteService*)arg; - int rc=0; + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteService *service = (NimBLERemoteService*)pTaskData->pATT; // Make sure the discovery is for this device if(service->getClient()->getConnId() != conn_handle){ return 0; } - switch (error->status) { - case 0: { - // Found a service - add it to the vector - NimBLERemoteCharacteristic* pRemoteCharacteristic = new NimBLERemoteCharacteristic(service, chr); - service->m_characteristicVector.push_back(pRemoteCharacteristic); - break; - } - case BLE_HS_EDONE:{ - /** All characteristics in this service discovered; start discovering - * characteristics in the next service. - */ - service->m_semaphoreGetCharEvt.give(0); - rc = 0; - break; - } - default: - rc = error->status; - break; + if(error->status == 0) { + // Found a service - add it to the vector + NimBLERemoteCharacteristic* pRemoteCharacteristic = new NimBLERemoteCharacteristic(service, chr); + service->m_characteristicVector.push_back(pRemoteCharacteristic); + return 0; } - if (rc != 0) { - /* Error; abort discovery. */ - // pass non-zero to semaphore on error to indicate an error finding characteristics - // release memory from any characteristics we created - //service->removeCharacteristics(); --this will now be done when we clear services on returning with error - NIMBLE_LOGE(LOG_TAG, "characteristicDiscCB() rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); - service->m_semaphoreGetCharEvt.give(1); + + if(error->status == BLE_HS_EDONE) { + pTaskData->rc = 0; + } else { + NIMBLE_LOGE(LOG_TAG, "characteristicDiscCB() rc=%d %s", + error->status, + NimBLEUtils::returnCodeToString(error->status)); + pTaskData->rc = error->status; } - NIMBLE_LOGD(LOG_TAG,"<< Characteristic Discovered. status: %d", rc); - return rc; + + xTaskNotifyGive(pTaskData->task); + + NIMBLE_LOGD(LOG_TAG,"<< Characteristic Discovered"); + return error->status; } @@ -199,32 +188,31 @@ bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter) NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str()); int rc = 0; - //removeCharacteristics(); // Forget any previous characteristics. - - m_semaphoreGetCharEvt.take("retrieveCharacteristics"); + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; if(uuid_filter == nullptr) { rc = ble_gattc_disc_all_chrs(m_pClient->getConnId(), m_startHandle, m_endHandle, NimBLERemoteService::characteristicDiscCB, - this); + &taskData); } else { rc = ble_gattc_disc_chrs_by_uuid(m_pClient->getConnId(), m_startHandle, m_endHandle, &uuid_filter->getNative()->u, NimBLERemoteService::characteristicDiscCB, - this); + &taskData); } if (rc != 0) { NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); - m_semaphoreGetCharEvt.give(); return false; } - if(m_semaphoreGetCharEvt.wait("retrieveCharacteristics") == 0){ + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if(taskData.rc == 0){ NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()"); return true; } @@ -316,12 +304,36 @@ bool NimBLERemoteService::setValue(const NimBLEUUID &characteristicUuid, const s * them. This method does just that. * @return N/A. */ -void NimBLERemoteService::removeCharacteristics() { +void NimBLERemoteService::deleteCharacteristics() { + NIMBLE_LOGD(LOG_TAG, ">> deleteCharacteristics"); for(auto &it: m_characteristicVector) { delete it; } - m_characteristicVector.clear(); // Clear the vector -} // removeCharacteristics + m_characteristicVector.clear(); + NIMBLE_LOGD(LOG_TAG, "<< deleteCharacteristics"); +} // deleteCharacteristics + + +/** + * @brief Delete characteristic by UUID + * @param [in] uuid The UUID of the characteristic to be cleared. + * @return Number of characteristics left. + */ +size_t NimBLERemoteService::deleteCharacteristic(const NimBLEUUID &uuid) { + NIMBLE_LOGD(LOG_TAG, ">> deleteCharacteristic"); + + for(auto it = m_characteristicVector.begin(); it != m_characteristicVector.end(); ++it) { + if((*it)->getUUID() == uuid) { + delete *it; + m_characteristicVector.erase(it); + break; + } + } + + NIMBLE_LOGD(LOG_TAG, "<< deleteCharacteristic"); + + return m_characteristicVector.size(); +} // deleteCharacteristic /** @@ -352,16 +364,5 @@ std::string NimBLERemoteService::toString() { } // toString -/** - * @brief called when an error occurrs and we need to release the semaphores to resume operations. - * Will release all characteristic and subsequently all descriptor semaphores for this service. - */ -void NimBLERemoteService::releaseSemaphores() { - for(auto &it: m_characteristicVector) { - it->releaseSemaphores(); - } - m_semaphoreGetCharEvt.give(1); -} - #endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h index 3803498d0..2d63c5d70 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h @@ -22,7 +22,6 @@ #include "NimBLEClient.h" #include "NimBLEUUID.h" -#include "FreeRTOS.h" #include "NimBLERemoteCharacteristic.h" #include @@ -43,6 +42,8 @@ public: std::vector::iterator end(); NimBLERemoteCharacteristic* getCharacteristic(const char* uuid); NimBLERemoteCharacteristic* getCharacteristic(const NimBLEUUID &uuid); + void deleteCharacteristics(); + size_t deleteCharacteristic(const NimBLEUUID &uuid); NimBLEClient* getClient(void); uint16_t getHandle(); NimBLEUUID getUUID(void); @@ -70,7 +71,6 @@ private: uint16_t getStartHandle(); uint16_t getEndHandle(); void releaseSemaphores(); - void removeCharacteristics(); // Properties @@ -78,7 +78,6 @@ private: std::vector m_characteristicVector; NimBLEClient* m_pClient; - FreeRTOS::Semaphore m_semaphoreGetCharEvt = FreeRTOS::Semaphore("GetCharEvt"); NimBLEUUID m_uuid; uint16_t m_startHandle; uint16_t m_endHandle; diff --git a/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp b/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp index 6d738f951..dbf88741d 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp @@ -18,7 +18,6 @@ #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) #include "NimBLEScan.h" -#include "NimBLEUtils.h" #include "NimBLEDevice.h" #include "NimBLELog.h" @@ -26,41 +25,12 @@ static const char* LOG_TAG = "NimBLEScan"; -/* - * Scanning filter policy - * NO_WL: - * Scanner processes all advertising packets (white list not used) except - * directed, connectable advertising packets not sent to the scanner. - * USE_WL: - * Scanner processes advertisements from white list only. A connectable, - * directed advertisment is ignored unless it contains scanners address. - * NO_WL_INITA: - * Scanner process all advertising packets (white list not used). A - * connectable, directed advertisement shall not be ignored if the InitA - * is a resolvable private address. - * USE_WL_INITA: - * Scanner process advertisements from white list only. A connectable, - * directed advertisement shall not be ignored if the InitA is a - * resolvable private address. - */ - -//#define BLE_HCI_SCAN_FILT_NO_WL (0) -//#define BLE_HCI_SCAN_FILT_USE_WL (1) -//#define BLE_HCI_SCAN_FILT_NO_WL_INITA (2) -//#define BLE_HCI_SCAN_FILT_USE_WL_INITA (3) -//#define BLE_HCI_SCAN_FILT_MAX (3) - /** * @brief Scan constuctor. */ NimBLEScan::NimBLEScan() { - uint8_t own_addr_type; - if(ble_hs_id_infer_auto(0, &own_addr_type) !=0){ - NIMBLE_LOGE(LOG_TAG, "error determining address type\n"); - return; - } - m_own_addr_type = own_addr_type; + m_own_addr_type = 0; m_scan_params.filter_policy = BLE_HCI_SCAN_FILT_NO_WL; m_scan_params.passive = 1; // If set, don’t send scan requests to advertisers (i.e., don’t request additional advertising data). m_scan_params.itvl = 0; // This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. (units=0.625 msec) @@ -70,6 +40,7 @@ NimBLEScan::NimBLEScan() { m_pAdvertisedDeviceCallbacks = nullptr; m_stopped = true; m_wantDuplicates = false; + m_pTaskData = nullptr; } @@ -101,14 +72,6 @@ NimBLEScan::NimBLEScan() { NimBLEAddress advertisedAddress(event->disc.addr); - // Print advertisement data - // print_adv_fields(&fields); - - // If we are not scanning, nothing to do with the extra results. - if (pScan->m_stopped) { - return 0; - } - // Examine our list of ignored addresses and stop processing if we don't want to see it or are already connected if(NimBLEDevice::isIgnored(advertisedAddress)) { NIMBLE_LOGI(LOG_TAG, "Ignoring device: address: %s", advertisedAddress.toString().c_str()); @@ -131,7 +94,6 @@ NimBLEScan::NimBLEScan() { advertisedDevice = new NimBLEAdvertisedDevice(); advertisedDevice->setAddressType(event->disc.addr.type); advertisedDevice->setAddress(advertisedAddress); - //NIMBLE_LOGE(LOG_TAG, "advertisement type: %d, %s",event->disc.event_type, NimBLEUtils::advTypeToString(event->disc.event_type)); advertisedDevice->setAdvType(event->disc.event_type); pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice); NIMBLE_LOGI(LOG_TAG, "NEW DEVICE FOUND: %s", advertisedAddress.toString().c_str()); @@ -143,16 +105,21 @@ NimBLEScan::NimBLEScan() { advertisedDevice->parseAdvertisement(&fields); advertisedDevice->setScan(pScan); advertisedDevice->setAdvertisementResult(event->disc.data, event->disc.length_data); + advertisedDevice->m_timestamp = time(nullptr); if (pScan->m_pAdvertisedDeviceCallbacks) { - // If not active scanning report the result to the listener. - if(pScan->m_scan_params.passive || event->disc.event_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) { - pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice); - // Otherwise wait for the scan response so we can report all of the data at once. - } else if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) { - pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice); + if(pScan->m_wantDuplicates || !advertisedDevice->m_callbackSent) { + // If not active scanning report the result to the listener. + if(pScan->m_scan_params.passive || event->disc.event_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) { + advertisedDevice->m_callbackSent = true; + pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice); + + // Otherwise wait for the scan response so we can report all of the data at once. + } else if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) { + advertisedDevice->m_callbackSent = true; + pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice); + } } - //m_pAdvertisedDeviceCallbacks->onResult(*advertisedDevice); } return 0; @@ -166,7 +133,11 @@ NimBLEScan::NimBLEScan() { } pScan->m_stopped = true; - pScan->m_semaphoreScanEnd.give(); + if(pScan->m_pTaskData != nullptr) { + pScan->m_pTaskData->rc = event->disc_complete.reason; + xTaskNotifyGive(pScan->m_pTaskData->task); + } + return 0; } @@ -191,13 +162,59 @@ void NimBLEScan::setActiveScan(bool active) { } // setActiveScan +/** + * @brief Set whether or not the BLE controller should only report results + * from devices it has not already seen. + * @param [in] active If true, scanned devices will only be reported once. + * @details The controller has a limited buffer and will start reporting + * dupicate devices once the limit is reached. + */ +void NimBLEScan::setDuplicateFilter(bool active) { + m_scan_params.filter_duplicates = active; +} // setDuplicateFilter + + +/** + * @brief Set whether or not the BLE controller only report scan results + * from devices advertising in limited discovery mode, i.e. directed advertising. + * @param [in] active If true, only limited discovery devices will be in scan results. + */ +void NimBLEScan::setLimitedOnly(bool active) { + m_scan_params.limited = active; +} // setLimited + + +/** + * @brief Sets the scan filter policy. + * @param [in] filter Can be one of: + * BLE_HCI_SCAN_FILT_NO_WL (0) + * Scanner processes all advertising packets (white list not used) except + * directed, connectable advertising packets not sent to the scanner. + * BLE_HCI_SCAN_FILT_USE_WL (1) + * Scanner processes advertisements from white list only. A connectable, + * directed advertisment is ignored unless it contains scanners address. + * BLE_HCI_SCAN_FILT_NO_WL_INITA (2) + * Scanner process all advertising packets (white list not used). A + * connectable, directed advertisement shall not be ignored if the InitA + * is a resolvable private address. + * BLE_HCI_SCAN_FILT_USE_WL_INITA (3) + * Scanner process advertisements from white list only. A connectable, + * directed advertisement shall not be ignored if the InitA is a + * resolvable private address. + */ +void NimBLEScan::setFilterPolicy(uint8_t filter) { + m_scan_params.filter_policy = filter; +} // setFilterPolicy + + /** * @brief Set the call backs to be invoked. * @param [in] pAdvertisedDeviceCallbacks Call backs to be invoked. * @param [in] wantDuplicates True if we wish to be called back with duplicates. Default is false. */ -void NimBLEScan::setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks/*, bool wantDuplicates*/) { - //m_wantDuplicates = wantDuplicates; +void NimBLEScan::setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, + bool wantDuplicates) { + m_wantDuplicates = wantDuplicates; m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks; } // setAdvertisedDeviceCallbacks @@ -248,7 +265,6 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul } m_stopped = false; - m_semaphoreScanEnd.take("start"); // Save the callback to be invoked when the scan completes. m_scanCompleteCB = scanCompleteCB; @@ -274,7 +290,7 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params, NimBLEScan::handleGapEvent, this); if(rc == BLE_HS_EBUSY) { - vTaskDelay(2); + vTaskDelay(1 / portTICK_PERIOD_MS); } } while(rc == BLE_HS_EBUSY); @@ -282,7 +298,6 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul NIMBLE_LOGE(LOG_TAG, "Error initiating GAP discovery procedure; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); m_stopped = true; - m_semaphoreScanEnd.give(); return false; } @@ -297,9 +312,18 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul * @return The BLEScanResults. */ NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) { - if(start(duration, nullptr, is_continue)) { - m_semaphoreScanEnd.wait("start"); // Wait for the semaphore to release. + if(duration == 0) { + NIMBLE_LOGW(LOG_TAG, "Blocking scan called with duration = forever"); } + + ble_task_data_t taskData = {nullptr, xTaskGetCurrentTaskHandle(),0, nullptr}; + m_pTaskData = &taskData; + + if(start(duration, nullptr, is_continue)) { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + } + + m_pTaskData = nullptr; return m_scanResults; } // start @@ -308,13 +332,13 @@ NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) { * @brief Stop an in progress scan. * @return N/A. */ -void NimBLEScan::stop() { +bool NimBLEScan::stop() { NIMBLE_LOGD(LOG_TAG, ">> stop()"); int rc = ble_gap_disc_cancel(); if (rc != 0 && rc != BLE_HS_EALREADY) { NIMBLE_LOGE(LOG_TAG, "Failed to cancel scan; rc=%d\n", rc); - return; + return false; } m_stopped = true; @@ -323,9 +347,12 @@ void NimBLEScan::stop() { m_scanCompleteCB(m_scanResults); } - m_semaphoreScanEnd.give(); + if(m_pTaskData != nullptr) { + xTaskNotifyGive(m_pTaskData->task); + } NIMBLE_LOGD(LOG_TAG, "<< stop()"); + return true; } // stop @@ -349,7 +376,6 @@ void NimBLEScan::erase(const NimBLEAddress &address) { */ void NimBLEScan::onHostReset() { m_stopped = true; - m_semaphoreScanEnd.give(); } diff --git a/libesp32/NimBLE-Arduino/src/NimBLEScan.h b/libesp32/NimBLE-Arduino/src/NimBLEScan.h index 3cab25784..5bc7bcf35 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEScan.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEScan.h @@ -20,7 +20,7 @@ #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) #include "NimBLEAdvertisedDevice.h" -#include "FreeRTOS.h" +#include "NimBLEUtils.h" #include "host/ble_gap.h" @@ -62,11 +62,14 @@ class NimBLEScan { public: bool start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue = false); NimBLEScanResults start(uint32_t duration, bool is_continue = false); - void setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks/*, bool wantDuplicates = false*/); + void setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, bool wantDuplicates = false); void setActiveScan(bool active); void setInterval(uint16_t intervalMSecs); void setWindow(uint16_t windowMSecs); - void stop(); + void setDuplicateFilter(bool active); + void setLimitedOnly(bool active); + void setFilterPolicy(uint8_t filter); + bool stop(); void clearResults(); NimBLEScanResults getResults(); void erase(const NimBLEAddress &address); @@ -85,8 +88,8 @@ private: bool m_stopped; bool m_wantDuplicates; NimBLEScanResults m_scanResults; - FreeRTOS::Semaphore m_semaphoreScanEnd = FreeRTOS::Semaphore("ScanEnd"); uint32_t m_duration; + ble_task_data_t *m_pTaskData; }; #endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) diff --git a/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp b/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp index d731bad5b..376b02144 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp @@ -19,8 +19,6 @@ #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #include "NimBLEServer.h" -#include "NimBLE2902.h" -#include "NimBLEUtils.h" #include "NimBLEDevice.h" #include "NimBLELog.h" @@ -32,51 +30,46 @@ static NimBLEServerCallbacks defaultCallbacks; * @brief Construct a %BLE Server * * This class is not designed to be individually instantiated. Instead one should create a server by asking - * the BLEDevice class. + * the NimBLEDevice class. */ NimBLEServer::NimBLEServer() { - m_connId = BLE_HS_CONN_HANDLE_NONE; - m_svcChgChrHdl = 0xffff; - m_pServerCallbacks = &defaultCallbacks; - m_gattsStarted = false; -} // BLEServer +// m_svcChgChrHdl = 0xffff; // Future Use + m_pServerCallbacks = &defaultCallbacks; + m_gattsStarted = false; + m_advertiseOnDisconnect = true; +} // NimBLEServer /** * @brief Create a %BLE Service. - * - * With a %BLE server, we can host one or more services. Invoking this function causes the creation of a definition - * of a new service. Every service must have a unique UUID. * @param [in] uuid The UUID of the new service. * @return A reference to the new service object. */ NimBLEService* NimBLEServer::createService(const char* uuid) { return createService(NimBLEUUID(uuid)); -} +} // createService /** * @brief Create a %BLE Service. - * - * With a %BLE server, we can host one or more services. Invoking this function causes the creation of a definition - * of a new service. Every service must have a unique UUID. * @param [in] uuid The UUID of the new service. * @param [in] numHandles The maximum number of handles associated with this service. - * @param [in] inst_id With multiple services with the same UUID we need to provide inst_id value different for each service. + * @param [in] inst_id if we have multiple services with the same UUID we need + * to provide inst_id value different for each service. * @return A reference to the new service object. */ NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid, uint32_t numHandles, uint8_t inst_id) { NIMBLE_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str()); - + // TODO: add functionality to use inst_id for multiple services with same uuid + (void)inst_id; // Check that a service with the supplied UUID does not already exist. - if (m_serviceMap.getByUUID(uuid) != nullptr) { - NIMBLE_LOGW(LOG_TAG, "<< Attempt to create a new service with uuid %s but a service with that UUID already exists.", - uuid.toString().c_str()); + if(getServiceByUUID(uuid) != nullptr) { + NIMBLE_LOGW(LOG_TAG, "Warning creating a duplicate service UUID: %s", + std::string(uuid).c_str()); } NimBLEService* pService = new NimBLEService(uuid, numHandles, this); - pService->m_instId = inst_id; - m_serviceMap.setByUUID(uuid, pService); // Save a reference to this service being on this server. + m_svcVec.push_back(pService); // Save a reference to this service being on this server. NIMBLE_LOGD(LOG_TAG, "<< createService"); return pService; @@ -89,8 +82,8 @@ NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid, uint32_t numH * @return A reference to the service object. */ NimBLEService* NimBLEServer::getServiceByUUID(const char* uuid) { - return m_serviceMap.getByUUID(uuid); -} + return getServiceByUUID(NimBLEUUID(uuid)); +} // getServiceByUUID /** @@ -99,8 +92,13 @@ NimBLEService* NimBLEServer::getServiceByUUID(const char* uuid) { * @return A reference to the service object. */ NimBLEService* NimBLEServer::getServiceByUUID(const NimBLEUUID &uuid) { - return m_serviceMap.getByUUID(uuid); -} + for (auto &it : m_svcVec) { + if (it->getUUID() == uuid) { + return it; + } + } + return nullptr; +} // getServiceByUUID /** @@ -109,18 +107,8 @@ NimBLEService* NimBLEServer::getServiceByUUID(const NimBLEUUID &uuid) { * @return An advertising object. */ NimBLEAdvertising* NimBLEServer::getAdvertising() { - return BLEDevice::getAdvertising(); -} - - -/** - * @brief Retrieve the connection id of the last connected client. - * @todo Not very useful, should refactor or remove. - * @return Client connection id. - */ -uint16_t NimBLEServer::getConnId() { - return m_connId; -} + return NimBLEDevice::getAdvertising(); +} // getAdvertising /** @@ -143,6 +131,8 @@ void NimBLEServer::start() { #if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4) ble_gatts_show_local(); #endif +/*** Future use *** + * TODO: implement service changed handling ble_uuid16_t svc = {BLE_UUID_TYPE_16, 0x1801}; ble_uuid16_t chr = {BLE_UUID_TYPE_16, 0x2a05}; @@ -155,36 +145,25 @@ void NimBLEServer::start() { } NIMBLE_LOGI(LOG_TAG, "Service changed characterisic handle: %d", m_svcChgChrHdl); +*/ + // Build a vector of characteristics with Notify / Indicate capabilities for event handling + for(auto &svc : m_svcVec) { + for(auto &chr : svc->m_chrVec) { + // if Notify / Indicate is enabled but we didn't create the descriptor + // we do it now. + if((chr->m_properties & BLE_GATT_CHR_F_INDICATE) || + (chr->m_properties & BLE_GATT_CHR_F_NOTIFY)) { - // Build a map of characteristics with Notify / Indicate capabilities for event handling - uint8_t numSvcs = m_serviceMap.getRegisteredServiceCount(); - NimBLEService* pService = m_serviceMap.getFirst(); - - for(int i = 0; i < numSvcs; i++) { - uint8_t numChrs = pService->m_characteristicMap.getSize(); - NimBLECharacteristic* pChr = pService->m_characteristicMap.getFirst(); - - if(pChr != nullptr) { - for( int d = 0; d < numChrs; d++) { - // if Notify / Indicate is enabled but we didn't create the descriptor - // we do it now. - if((pChr->m_properties & BLE_GATT_CHR_F_INDICATE) || - (pChr->m_properties & BLE_GATT_CHR_F_NOTIFY)) { - - if(nullptr == pChr->getDescriptorByUUID("2902")) { - pChr->createDescriptor("2902"); - } - m_notifyChrMap.insert(std::pair - (pChr->getHandle(), pChr)); + if(nullptr == chr->getDescriptorByUUID(uint16_t(0x2902))) { + chr->createDescriptor(uint16_t(0x2902)); } - pChr = pService->m_characteristicMap.getNext(); + m_notifyChrVec.push_back(chr); } } - pService = m_serviceMap.getNext(); } m_gattsStarted = true; -} +} // start /** @@ -202,17 +181,26 @@ int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) { NimBLEUtils::returnCodeToString(rc)); } - return rc; NIMBLE_LOGD(LOG_TAG, "<< disconnect()"); -} + return rc; +} // disconnect + + +/** + * @brief Set the server to automatically start advertising when a client disconnects. + * @param [in] bool true == advertise, false == don't advertise. + */ +void NimBLEServer::advertiseOnDisconnect(bool aod) { + m_advertiseOnDisconnect = aod; +} // advertiseOnDisconnect /** * @brief Return the number of connected clients. * @return The number of connected clients. */ -uint32_t NimBLEServer::getConnectedCount() { - return m_connectedServersMap.size(); +size_t NimBLEServer::getConnectedCount() { + return m_connectedPeersVec.size(); } // getConnectedCount @@ -227,7 +215,7 @@ uint32_t NimBLEServer::getConnectedCount() { /*STATIC*/int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) { NimBLEServer* server = (NimBLEServer*)arg; NIMBLE_LOGD(LOG_TAG, ">> handleGapEvent: %s", - NimBLEUtils::gapEventToString(event->type)); + NimBLEUtils::gapEventToString(event->type)); int rc = 0; struct ble_gap_conn_desc desc; @@ -236,15 +224,12 @@ uint32_t NimBLEServer::getConnectedCount() { case BLE_GAP_EVENT_CONNECT: { if (event->connect.status != 0) { /* Connection failed; resume advertising */ - NIMBLE_LOGC(LOG_TAG, "Connection failed"); + NIMBLE_LOGE(LOG_TAG, "Connection failed"); NimBLEDevice::startAdvertising(); - server->m_connId = BLE_HS_CONN_HANDLE_NONE; } else { - server->m_connId = event->connect.conn_handle; - server->addPeerDevice((void*)server, false, server->m_connId); + server->m_connectedPeersVec.push_back(event->connect.conn_handle); - ble_gap_conn_desc desc; rc = ble_gap_conn_find(event->connect.conn_handle, &desc); assert(rc == 0); @@ -271,10 +256,15 @@ uint32_t NimBLEServer::getConnectedCount() { break; } - server->removePeerDevice(event->disconnect.conn.conn_handle, false); - server->m_connId = BLE_HS_CONN_HANDLE_NONE; + server->m_connectedPeersVec.erase(std::remove(server->m_connectedPeersVec.begin(), + server->m_connectedPeersVec.end(), + event->disconnect.conn.conn_handle), + server->m_connectedPeersVec.end()); server->m_pServerCallbacks->onDisconnect(server); + if(server->m_advertiseOnDisconnect) { + server->startAdvertising(); + } return 0; } // BLE_GAP_EVENT_DISCONNECT @@ -283,9 +273,23 @@ uint32_t NimBLEServer::getConnectedCount() { "val_handle=%d\n", event->subscribe.cur_notify, event->subscribe.attr_handle); - auto it = server->m_notifyChrMap.find(event->subscribe.attr_handle); - if(it != server->m_notifyChrMap.cend()) { - (*it).second->setSubscribe(event); + for(auto &it : server->m_notifyChrVec) { + if(it->getHandle() == event->subscribe.attr_handle) { + if((it->getProperties() & BLE_GATT_CHR_F_READ_AUTHEN) || + (it->getProperties() & BLE_GATT_CHR_F_READ_AUTHOR) || + (it->getProperties() & BLE_GATT_CHR_F_READ_ENC)) + { + rc = ble_gap_conn_find(event->subscribe.conn_handle, &desc); + assert(rc == 0); + + if(!desc.sec_state.encrypted) { + NimBLEDevice::startSecurity(event->subscribe.conn_handle); + } + } + + it->setSubscribe(event); + break; + } } return 0; @@ -295,15 +299,19 @@ uint32_t NimBLEServer::getConnectedCount() { NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d", event->mtu.conn_handle, event->mtu.value); - server->updatePeerMTU(event->mtu.conn_handle, event->mtu.value); return 0; } // BLE_GAP_EVENT_MTU case BLE_GAP_EVENT_NOTIFY_TX: { if(event->notify_tx.indication && event->notify_tx.status != 0) { - auto it = server->m_notifyChrMap.find(event->notify_tx.attr_handle); - if(it != server->m_notifyChrMap.cend()) { - (*it).second->m_semaphoreConfEvt.give(event->notify_tx.status); + for(auto &it : server->m_notifyChrVec) { + if(it->getHandle() == event->notify_tx.attr_handle) { + if(it->m_pTaskData != nullptr) { + it->m_pTaskData->rc = event->notify_tx.status; + xTaskNotifyGive(it->m_pTaskData->task); + } + break; + } } } @@ -333,7 +341,7 @@ uint32_t NimBLEServer::getConnectedCount() { } // BLE_GAP_EVENT_REPEAT_PAIRING case BLE_GAP_EVENT_ENC_CHANGE: { - rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); if(rc != 0) { return BLE_ATT_ERR_INVALID_HANDLE; } @@ -349,7 +357,7 @@ uint32_t NimBLEServer::getConnectedCount() { } // BLE_GAP_EVENT_ENC_CHANGE case BLE_GAP_EVENT_PASSKEY_ACTION: { - struct ble_sm_io pkey = {0}; + struct ble_sm_io pkey = {0,0}; if (event->passkey.params.action == BLE_SM_IOACT_DISP) { pkey.action = event->passkey.params.action; @@ -416,7 +424,7 @@ uint32_t NimBLEServer::getConnectedCount() { NIMBLE_LOGD(LOG_TAG, "<< handleGATTServerEvent"); return 0; -} // handleGATTServerEvent +} // handleGapEvent /** @@ -437,18 +445,6 @@ void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks) { } // setCallbacks -/* - * Remove service - */ -/* -void BLEServer::removeService(BLEService* service) { - service->stop(); - service->executeDelete(); - m_serviceMap.removeService(service); -} -*/ - - /** * @brief Start advertising. * @@ -456,9 +452,7 @@ void BLEServer::removeService(BLEService* service) { * retrieving the advertising object and invoking start upon it. */ void NimBLEServer::startAdvertising() { - NIMBLE_LOGD(LOG_TAG, ">> startAdvertising"); NimBLEDevice::startAdvertising(); - NIMBLE_LOGD(LOG_TAG, "<< startAdvertising"); } // startAdvertising @@ -466,38 +460,43 @@ void NimBLEServer::startAdvertising() { * @brief Stop advertising. */ void NimBLEServer::stopAdvertising() { - NIMBLE_LOGD(LOG_TAG, ">> stopAdvertising"); NimBLEDevice::stopAdvertising(); - NIMBLE_LOGD(LOG_TAG, "<< stopAdvertising"); } // startAdvertising /** - * Allow to connect GATT server to peer device - * Probably can be used in ANCS for iPhone + * @brief Get the MTU of the client. + * @returns The client MTU or 0 if not found/connected. */ - /* -bool BLEServer::connect(BLEAddress address) { - esp_bd_addr_t addr; - memcpy(&addr, address.getNative(), 6); - // Perform the open connection request against the target BLE Server. - m_semaphoreOpenEvt.take("connect"); - esp_err_t errRc = ::esp_ble_gatts_open( - getGattsIf(), - addr, // address - 1 // direct connection - ); - if (errRc != ESP_OK) { - ESP_LOGE(LOG_TAG, "esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); - return false; +uint16_t NimBLEServer::getPeerMTU(uint16_t conn_id) { + return ble_att_mtu(conn_id); +} //getPeerMTU + + +/** + * Update connection parameters can be called only after connection has been established + */ +void NimBLEServer::updateConnParams(uint16_t conn_handle, + uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout) +{ + ble_gap_upd_params params; + + params.latency = latency; + params.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms + params.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms + params.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms + params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; // Minimum length of connection event in 0.625ms units + params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; // Maximum length of connection event in 0.625ms units + + int rc = ble_gap_update_params(conn_handle, ¶ms); + if(rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); } +} // updateConnParams - uint32_t rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete. - ESP_LOGD(LOG_TAG, "<< connect(), rc=%d", rc==ESP_GATT_OK); - return rc == ESP_GATT_OK; -} // connect -*/ +/** Default callback handlers */ void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer) { NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default"); @@ -534,80 +533,6 @@ bool NimBLEServerCallbacks::onConfirmPIN(uint32_t pin){ return true; } -/* multi connect support */ -void NimBLEServer::updatePeerMTU(uint16_t conn_id, uint16_t mtu) { - const std::map::iterator it = m_connectedServersMap.find(conn_id); - if (it != m_connectedServersMap.end()) { - it->second.mtu = mtu; - } -} - -std::map NimBLEServer::getPeerDevices() { - return m_connectedServersMap; -} - - -/** - * @brief Get the MTU of the client. - * @returns The client MTU or 0 if not found/connected. - */ -uint16_t NimBLEServer::getPeerMTU(uint16_t conn_id) { - auto it = m_connectedServersMap.find(conn_id); - if(it != m_connectedServersMap.cend()) { - return (*it).second.mtu; - } else { - return 0; - } -} - -void NimBLEServer::addPeerDevice(void* peer, bool _client, uint16_t conn_id) { - conn_status_t status = { - .peer_device = peer, - .connected = true, - .mtu = 23 - }; - - m_connectedServersMap.insert(std::pair(conn_id, status)); -} - -void NimBLEServer::removePeerDevice(uint16_t conn_id, bool _client) { - m_connectedServersMap.erase(conn_id); -} -/* multi connect support */ - - -/** - * Update connection parameters can be called only after connection has been established - */ -void NimBLEServer::updateConnParams(uint16_t conn_handle, - uint16_t minInterval, uint16_t maxInterval, - uint16_t latency, uint16_t timeout, - uint16_t minConnTime, uint16_t maxConnTime) -{ - ble_gap_upd_params params; - - params.latency = latency; - params.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms - params.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms - params.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms - params.min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units - params.max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units - - int rc = ble_gap_update_params(conn_handle, ¶ms); - if(rc != 0) { - NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); - } -} - -/* Don't think this is needed - -void NimBLEServer::onHostReset() { - for(auto it = m_notifyChrMap.cbegin(); it != m_notifyChrMap.cend(); ++it) { - (*it).second->m_semaphoreConfEvt.give(0); - } - -} -*/ #endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEServer.h b/libesp32/NimBLE-Arduino/src/NimBLEServer.h index 903eb2392..cfaa8acc7 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEServer.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEServer.h @@ -20,103 +20,60 @@ #include "nimconfig.h" #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#include "NimBLEUtils.h" #include "NimBLEAddress.h" -#include "NimBLEUUID.h" #include "NimBLEAdvertising.h" #include "NimBLEService.h" #include "NimBLESecurity.h" -#include "FreeRTOS.h" -#include class NimBLEService; class NimBLECharacteristic; class NimBLEServerCallbacks; -/* TODO possibly refactor this struct */ -typedef struct { - void *peer_device; // peer device BLEClient or BLEServer - maybe its better to have 2 structures or union here - bool connected; // do we need it? - uint16_t mtu; // every peer device negotiate own mtu -} conn_status_t; - - -/** - * @brief A data structure that manages the %BLE servers owned by a BLE server. - */ -class NimBLEServiceMap { -public: -// NimBLEService* getByHandle(uint16_t handle); - NimBLEService* getByUUID(const char* uuid); - NimBLEService* getByUUID(const NimBLEUUID &uuid, uint8_t inst_id = 0); -// void setByHandle(uint16_t handle, NimBLEService* service); - void setByUUID(const char* uuid, NimBLEService* service); - void setByUUID(const NimBLEUUID &uuid, NimBLEService* service); - std::string toString(); - NimBLEService* getFirst(); - NimBLEService* getNext(); - void removeService(NimBLEService *service); - int getRegisteredServiceCount(); - -private: -// std::map m_handleMap; - std::map m_uuidMap; - std::map::iterator m_iterator; -}; - /** * @brief The model of a %BLE server. */ class NimBLEServer { public: - uint32_t getConnectedCount(); - NimBLEService* createService(const char* uuid); - NimBLEService* createService(const NimBLEUUID &uuid, uint32_t numHandles=15, uint8_t inst_id=0); - NimBLEAdvertising* getAdvertising(); - void setCallbacks(NimBLEServerCallbacks* pCallbacks); - void startAdvertising(); - void stopAdvertising(); - void start(); -// void removeService(BLEService* service); - NimBLEService* getServiceByUUID(const char* uuid); - NimBLEService* getServiceByUUID(const NimBLEUUID &uuid); - int disconnect(uint16_t connID, uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); -// bool connect(BLEAddress address); - void updateConnParams(uint16_t conn_handle, - uint16_t minInterval, uint16_t maxInterval, - uint16_t latency, uint16_t timeout, - uint16_t minConnTime=0, uint16_t maxConnTime=0); - - /* multi connection support */ - std::map getPeerDevices(); - void addPeerDevice(void* peer, bool is_client, uint16_t conn_id); - void removePeerDevice(uint16_t conn_id, bool client); - NimBLEServer* getServerByConnId(uint16_t conn_id); - void updatePeerMTU(uint16_t connId, uint16_t mtu); - uint16_t getPeerMTU(uint16_t conn_id); - uint16_t getConnId(); - + size_t getConnectedCount(); + NimBLEService* createService(const char* uuid); + NimBLEService* createService(const NimBLEUUID &uuid, uint32_t numHandles=15, + uint8_t inst_id=0); + NimBLEAdvertising* getAdvertising(); + void setCallbacks(NimBLEServerCallbacks* pCallbacks); + void startAdvertising(); + void stopAdvertising(); + void start(); + NimBLEService* getServiceByUUID(const char* uuid); + NimBLEService* getServiceByUUID(const NimBLEUUID &uuid); + int disconnect(uint16_t connID, + uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); + void updateConnParams(uint16_t conn_handle, + uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout); + uint16_t getPeerMTU(uint16_t conn_id); + std::vector getPeerDevices(); + void advertiseOnDisconnect(bool); private: NimBLEServer(); - //friend class BLEService; - friend class NimBLECharacteristic; - friend class NimBLEDevice; - friend class NimBLEAdvertising; - // void onHostReset(); - // BLEAdvertising m_bleAdvertising; - uint16_t m_connId; - uint16_t m_svcChgChrHdl; + friend class NimBLECharacteristic; + friend class NimBLEDevice; + friend class NimBLEAdvertising; + bool m_gattsStarted; - - std::map m_connectedServersMap; - std::map m_notifyChrMap; - - NimBLEServiceMap m_serviceMap; + bool m_advertiseOnDisconnect; NimBLEServerCallbacks* m_pServerCallbacks; + std::vector m_connectedPeersVec; - static int handleGapEvent(struct ble_gap_event *event, void *arg); +// uint16_t m_svcChgChrHdl; // Future use + + std::vector m_svcVec; + std::vector m_notifyChrVec; + + static int handleGapEvent(struct ble_gap_event *event, void *arg); }; // NimBLEServer @@ -149,7 +106,7 @@ public: virtual bool onSecurityRequest(); //{return true;} virtual void onAuthenticationComplete(ble_gap_conn_desc* desc);//{}; virtual bool onConfirmPIN(uint32_t pin);//{return true;} -}; // BLEServerCallbacks +}; // NimBLEServerCallbacks #endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) diff --git a/libesp32/NimBLE-Arduino/src/NimBLEService.cpp b/libesp32/NimBLE-Arduino/src/NimBLEService.cpp index 6036a38ad..c2631ab36 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEService.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEService.cpp @@ -32,9 +32,10 @@ static const char* LOG_TAG = "NimBLEService"; // Tag for logging. /** - * @brief Construct an instance of the BLEService + * @brief Construct an instance of the NimBLEService * @param [in] uuid The UUID of the service. * @param [in] numHandles The maximum number of handles associated with the service. + * @param [in] a pointer to the server instance that this service belongs to. */ NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer) : NimBLEService(NimBLEUUID(uuid), numHandles, pServer) { @@ -45,11 +46,12 @@ NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer * @brief Construct an instance of the BLEService * @param [in] uuid The UUID of the service. * @param [in] numHandles The maximum number of handles associated with the service. + * @param [in] a pointer to the server instance that this service belongs to. */ NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer) { - m_uuid = uuid; - m_handle = NULL_HANDLE; - m_pServer = pServer; + m_uuid = uuid; + m_handle = NULL_HANDLE; + m_pServer = pServer; m_numHandles = numHandles; } // NimBLEService @@ -59,10 +61,22 @@ NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLE * @return N/A. */ void NimBLEService::dump() { - NIMBLE_LOGD(LOG_TAG, "Service: uuid:%s, handle: 0x%.2x", + NIMBLE_LOGD(LOG_TAG, "Service: uuid:%s, handle: 0x%2x", m_uuid.toString().c_str(), m_handle); - NIMBLE_LOGD(LOG_TAG, "Characteristics:\n%s", m_characteristicMap.toString().c_str()); + + std::string res; + int count = 0; + char hex[5]; + for (auto &it: m_chrVec) { + if (count > 0) {res += "\n";} + snprintf(hex, sizeof(hex), "%04x", it->getHandle()); + count++; + res += "handle: 0x"; + res += hex; + res += ", uuid: " + std::string(it->getUUID()); + } + NIMBLE_LOGD(LOG_TAG, "Characteristics:\n%s", res.c_str()); } // dump @@ -76,10 +90,9 @@ NimBLEUUID NimBLEService::getUUID() { /** - * @brief Start the service. - * Here we wish to start the service which means that we will respond to partner requests about it. - * Starting a service also means that we can create the corresponding characteristics. - * @return Start the service. + * @brief Builds the database of characteristics/descriptors for the service + * and registers it with the NimBLE stack. + * @return bool success/failure . */ bool NimBLEService::start() { @@ -96,7 +109,7 @@ bool NimBLEService::start() { svc[0].uuid = &m_uuid.getNative()->u; svc[0].includes = NULL; - uint8_t numChrs = m_characteristicMap.getSize(); + size_t numChrs = m_chrVec.size(); NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str()); @@ -107,16 +120,17 @@ bool NimBLEService::start() { // of the characteristics for the service. We create 1 extra and set it to null // for this purpose. pChr_a = new ble_gatt_chr_def[numChrs+1]; - NimBLECharacteristic* pCharacteristic = m_characteristicMap.getFirst(); + NimBLECharacteristic* pCharacteristic = *m_chrVec.begin(); - for(uint8_t i=0; i < numChrs; i++) { - uint8_t numDscs = pCharacteristic->m_descriptorMap.getSize(); + for(uint8_t i=0; i < numChrs;) { + uint8_t numDscs = pCharacteristic->m_dscVec.size(); if(numDscs) { // skip 2902 as it's automatically created by NimBLE // if Indicate or Notify flags are set if(((pCharacteristic->m_properties & BLE_GATT_CHR_F_INDICATE) || (pCharacteristic->m_properties & BLE_GATT_CHR_F_NOTIFY)) && - pCharacteristic->getDescriptorByUUID("2902") != nullptr) { + pCharacteristic->getDescriptorByUUID("2902") != nullptr) + { numDscs--; } } @@ -127,12 +141,12 @@ bool NimBLEService::start() { // Must have last descriptor uuid = 0 so we have to create 1 extra //NIMBLE_LOGD(LOG_TAG, "Adding %d descriptors", numDscs); pDsc_a = new ble_gatt_dsc_def[numDscs+1]; - NimBLEDescriptor* pDescriptor = pCharacteristic->m_descriptorMap.getFirst(); + NimBLEDescriptor* pDescriptor = *pCharacteristic->m_dscVec.begin(); for(uint8_t d=0; d < numDscs;) { // skip 2902 - if(pDescriptor->m_uuid.equals(NimBLEUUID((uint16_t)0x2902))) { + if(pDescriptor->m_uuid == NimBLEUUID(uint16_t(0x2902))) { //NIMBLE_LOGD(LOG_TAG, "Skipped 0x2902"); - pDescriptor = pCharacteristic->m_descriptorMap.getNext(); + pDescriptor = *(pCharacteristic->m_dscVec.begin()+d+1); continue; } pDsc_a[d].uuid = &pDescriptor->m_uuid.getNative()->u; @@ -140,8 +154,8 @@ bool NimBLEService::start() { pDsc_a[d].min_key_size = 0; pDsc_a[d].access_cb = NimBLEDescriptor::handleGapEvent; pDsc_a[d].arg = pDescriptor; - pDescriptor = pCharacteristic->m_descriptorMap.getNext(); d++; + pDescriptor = *(pCharacteristic->m_dscVec.begin() + d); } pDsc_a[numDscs].uuid = NULL; @@ -154,7 +168,8 @@ bool NimBLEService::start() { pChr_a[i].flags = pCharacteristic->m_properties; pChr_a[i].min_key_size = 0; pChr_a[i].val_handle = &pCharacteristic->m_handle; - pCharacteristic = m_characteristicMap.getNext(); + i++; + pCharacteristic = *(m_chrVec.begin() + i); } pChr_a[numChrs].uuid = NULL; @@ -182,21 +197,6 @@ bool NimBLEService::start() { } // start -/** - * @brief Set the handle associated with this service. - * @param [in] handle The handle associated with the service. - */ -void NimBLEService::setHandle(uint16_t handle) { - NIMBLE_LOGD(LOG_TAG, ">> setHandle - Handle=0x%.2x, service UUID=%s)", handle, getUUID().toString().c_str()); - if (m_handle != NULL_HANDLE) { - NIMBLE_LOGE(LOG_TAG, "!!! Handle is already set %.2x", m_handle); - return; - } - m_handle = handle; - NIMBLE_LOGD(LOG_TAG, "<< setHandle"); -} // setHandle - - /** * @brief Get the handle associated with this service. * @return The handle associated with this service. @@ -206,34 +206,6 @@ uint16_t NimBLEService::getHandle() { } // getHandle -/** - * @brief Add a characteristic to the service. - * @param [in] pCharacteristic A pointer to the characteristic to be added. - */ -void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) { - // We maintain a mapping of characteristics owned by this service. These are managed by the - // BLECharacteristicMap class instance found in m_characteristicMap. We add the characteristic - // to the map and then ask the service to add the characteristic at the BLE level (ESP-IDF). - - NIMBLE_LOGD(LOG_TAG, ">> addCharacteristic()"); - NIMBLE_LOGD(LOG_TAG, "Adding characteristic: uuid=%s to service: %s", - pCharacteristic->getUUID().toString().c_str(), - toString().c_str()); - - // Check that we don't add the same characteristic twice. - if (m_characteristicMap.getByUUID(pCharacteristic->getUUID()) != nullptr) { - NIMBLE_LOGW(LOG_TAG, "<< Adding a new characteristic with the same UUID as a previous one"); - //return; - } - - // Remember this characteristic in our map of characteristics. At this point, we can lookup by UUID - // but not by handle. The handle is allocated to us on the ESP_GATTS_ADD_CHAR_EVT. - m_characteristicMap.setByUUID(pCharacteristic, pCharacteristic->getUUID()); - - NIMBLE_LOGD(LOG_TAG, "<< addCharacteristic()"); -} // addCharacteristic - - /** * @brief Create a new BLE Characteristic associated with this service. * @param [in] uuid - The UUID of the characteristic. @@ -253,8 +225,15 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const char* uuid, uint */ NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid, uint32_t properties) { NimBLECharacteristic* pCharacteristic = new NimBLECharacteristic(uuid, properties, this); - addCharacteristic(pCharacteristic); - //pCharacteristic->executeCreate(this); + // Check that we don't add the same characteristic twice. + if (getCharacteristic(uuid) != nullptr) { + NIMBLE_LOGW(LOG_TAG, "<< Adding a duplicate characteristic with UUID: %s", + std::string(uuid).c_str()); + } + + // Remember this characteristic in our vector of characteristics. + m_chrVec.push_back(pCharacteristic); + return pCharacteristic; } // createCharacteristic @@ -265,7 +244,13 @@ NimBLECharacteristic* NimBLEService::getCharacteristic(const char* uuid) { NimBLECharacteristic* NimBLEService::getCharacteristic(const NimBLEUUID &uuid) { - return m_characteristicMap.getByUUID(uuid); + for (auto &it : m_chrVec) { + if (it->getUUID() == uuid) { + return it; + } + } + + return nullptr; } diff --git a/libesp32/NimBLE-Arduino/src/NimBLEService.h b/libesp32/NimBLE-Arduino/src/NimBLEService.h index 1cb0f6153..4c1fa2adf 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEService.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEService.h @@ -20,37 +20,14 @@ #include "nimconfig.h" #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#include "NimBLECharacteristic.h" #include "NimBLEServer.h" +#include "NimBLECharacteristic.h" #include "NimBLEUUID.h" -#include "FreeRTOS.h" class NimBLEServer; class NimBLECharacteristic; -/** - * @brief A data mapping used to manage the set of %BLE characteristics known to the server. - */ -class NimBLECharacteristicMap { -public: - void setByUUID(NimBLECharacteristic* pCharacteristic, const char* uuid); - void setByUUID(NimBLECharacteristic* pCharacteristic, const NimBLEUUID &uuid); - void setByHandle(uint16_t handle, NimBLECharacteristic* pCharacteristic); - NimBLECharacteristic* getByUUID(const char* uuid); - NimBLECharacteristic* getByUUID(const NimBLEUUID &uuid); - NimBLECharacteristic* getByHandle(uint16_t handle); - NimBLECharacteristic* getFirst(); - NimBLECharacteristic* getNext(); - uint8_t getSize(); - std::string toString(); - -private: - std::map m_uuidMap; - std::map m_handleMap; - std::map::iterator m_iterator; -}; - /** * @brief The model of a %BLE service. @@ -59,40 +36,39 @@ private: class NimBLEService { public: NimBLECharacteristic* createCharacteristic(const char* uuid, - uint32_t properties = NIMBLE_PROPERTY::READ | + uint32_t properties = + NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE); NimBLECharacteristic* createCharacteristic(const NimBLEUUID &uuid, - uint32_t properties = NIMBLE_PROPERTY::READ | - NIMBLE_PROPERTY::WRITE); + uint32_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE); - void dump(); + void dump(); NimBLECharacteristic* getCharacteristic(const char* uuid); NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid); NimBLEUUID getUUID(); NimBLEServer* getServer(); - bool start(); -// void stop(); - std::string toString(); - uint16_t getHandle(); - uint8_t m_instId = 0; + bool start(); + std::string toString(); + uint16_t getHandle(); private: NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer); NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer); - friend class NimBLEServer; - friend class NimBLEDevice; - void addCharacteristic(NimBLECharacteristic* pCharacteristic); + friend class NimBLEServer; + friend class NimBLEDevice; - NimBLECharacteristicMap m_characteristicMap; - uint16_t m_handle; - NimBLEServer* m_pServer = nullptr; - NimBLEUUID m_uuid; + uint16_t m_handle; + NimBLEServer* m_pServer; + NimBLEUUID m_uuid; + uint16_t m_numHandles; - uint16_t m_numHandles; - void setHandle(uint16_t handle); -}; // BLEService + std::vector m_chrVec; + +}; // NimBLEService #endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) diff --git a/libesp32/NimBLE-Arduino/src/NimBLEServiceMap.cpp b/libesp32/NimBLE-Arduino/src/NimBLEServiceMap.cpp deleted file mode 100644 index e5b96e676..000000000 --- a/libesp32/NimBLE-Arduino/src/NimBLEServiceMap.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * NimBLEService.cpp - * - * Created: on March 7, 2020 - * Author H2zero - * - * Originally: - * - * BLEServiceMap.cpp - * - * Created on: Jun 22, 2017 - * Author: kolban - */ -#include "sdkconfig.h" -#if defined(CONFIG_BT_ENABLED) - -#include "nimconfig.h" -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - -#include "NimBLEService.h" - - -/** - * @brief Return the service by UUID. - * @param [in] UUID The UUID to look up the service. - * @return The characteristic. - */ -NimBLEService* NimBLEServiceMap::getByUUID(const char* uuid) { - return getByUUID(NimBLEUUID(uuid)); -} - -/** - * @brief Return the service by UUID. - * @param [in] UUID The UUID to look up the service. - * @return The characteristic. - */ -NimBLEService* NimBLEServiceMap::getByUUID(const NimBLEUUID &uuid, uint8_t inst_id) { - for (auto &myPair : m_uuidMap) { - if (myPair.first->getUUID().equals(uuid)) { - return myPair.first; - } - } - //return m_uuidMap.at(uuid.toString()); - return nullptr; -} // getByUUID - - -/** - * @brief Return the service by handle. - * @param [in] handle The handle to look up the service. - * @return The service. - */ -/* -NimBLEService* NimBLEServiceMap::getByHandle(uint16_t handle) { - return m_handleMap.at(handle); -} // getByHandle -*/ - -/** - * @brief Set the service by UUID. - * @param [in] uuid The uuid of the service. - * @param [in] characteristic The service to cache. - * @return N/A. - */ -void NimBLEServiceMap::setByUUID(const NimBLEUUID &uuid, NimBLEService* service) { - m_uuidMap.insert(std::pair(service, uuid.toString())); -} // setByUUID - - -/** - * @brief Set the service by handle. - * @param [in] handle The handle of the service. - * @param [in] service The service to cache. - * @return N/A. - */ - /* -void NimBLEServiceMap::setByHandle(uint16_t handle, NimBLEService* service) { - m_handleMap.insert(std::pair(handle, service)); -} // setByHandle -*/ - -/** - * @brief Return a string representation of the service map. - * @return A string representation of the service map. - */ -std::string NimBLEServiceMap::toString() { - std::string res; - //char hex[5]; - for (auto &myPair: m_uuidMap) { - // res += "handle: 0x"; - // snprintf(hex, sizeof(hex), "%04x", myPair.first); - // res += hex; - res += ", uuid: " + myPair.second + "\n"; - } - return res; -} // toString - - -/** - * @brief Get the first service in the map. - * @return The first service in the map. - */ -NimBLEService* NimBLEServiceMap::getFirst() { - m_iterator = m_uuidMap.begin(); - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLEService* pRet = m_iterator->first; - m_iterator++; - return pRet; -} // getFirst - - -/** - * @brief Get the next service in the map. - * @return The next service in the map. - */ -NimBLEService* NimBLEServiceMap::getNext() { - if (m_iterator == m_uuidMap.end()) return nullptr; - NimBLEService* pRet = m_iterator->first; - m_iterator++; - return pRet; -} // getNext - - -/** - * @brief Removes service from maps. - * @return N/A. - */ -void NimBLEServiceMap::removeService(NimBLEService* service) { - //m_handleMap.erase(service->getHandle()); - m_uuidMap.erase(service); -} // removeService - - -/** - * @brief Returns the amount of registered services - * @return amount of registered services - */ -int NimBLEServiceMap::getRegisteredServiceCount(){ - //return m_handleMap.size(); - return m_uuidMap.size(); -} - - -#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp b/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp index 9036d4d30..1f1f22c25 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp +++ b/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp @@ -502,8 +502,13 @@ void print_bytes(const uint8_t *bytes, int len) int i; for (i = 0; i < len; i++) { - MODLOG_DFLT(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + MODLOG_DFLT(ERROR, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + if(i % 30 == 0){ + MODLOG_DFLT(ERROR, "\n"); + } } + + MODLOG_DFLT(ERROR, "\n"); } void print_mbuf(const struct os_mbuf *om) diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUtils.h b/libesp32/NimBLE-Arduino/src/NimBLEUtils.h index b26d41a51..891f83596 100644 --- a/libesp32/NimBLE-Arduino/src/NimBLEUtils.h +++ b/libesp32/NimBLE-Arduino/src/NimBLEUtils.h @@ -13,6 +13,20 @@ #include "host/ble_gap.h" +/**** FIX COMPILATION ****/ +#undef min +#undef max +/**************************/ + +#include + +typedef struct { + void *pATT; + TaskHandle_t task; + int rc; + std::string *buf; +} ble_task_data_t; + extern "C"{ char *addr_str(const void *addr); void print_conn_desc(const struct ble_gap_conn_desc *desc); diff --git a/libesp32/NimBLE-Arduino/src/NimBLEValue.cpp b/libesp32/NimBLE-Arduino/src/NimBLEValue.cpp deleted file mode 100644 index aa437c60c..000000000 --- a/libesp32/NimBLE-Arduino/src/NimBLEValue.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * NimNimBLEValue.cpp - * - * Created: on March 6, 2020 - * Author H2zero - * - * Originally: - * - * BLEValue.cpp - * - * Created on: Jul 17, 2017 - * Author: kolban - */ -#include "sdkconfig.h" -#if defined(CONFIG_BT_ENABLED) - -#include "nimconfig.h" -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - -#include "NimBLEValue.h" -#include "NimBLELog.h" - -static const char* LOG_TAG="NimBLEValue"; - -NimBLEValue::NimBLEValue() { - m_accumulation = ""; - m_value = ""; - m_readOffset = 0; -} // NimBLEValue - - -/** - * @brief Add a message part to the accumulation. - * The accumulation is a growing set of data that is added to until a commit or cancel. - * @param [in] part A message part being added. - */ -void NimBLEValue::addPart(const std::string &part) { - NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", part.length()); - m_accumulation += part; -} // addPart - - -/** - * @brief Add a message part to the accumulation. - * The accumulation is a growing set of data that is added to until a commit or cancel. - * @param [in] pData A message part being added. - * @param [in] length The number of bytes being added. - */ -void NimBLEValue::addPart(const uint8_t* pData, size_t length) { - NIMBLE_LOGD(LOG_TAG, ">> addPart: length=%d", length); - m_accumulation += std::string((char*) pData, length); -} // addPart - - -/** - * @brief Cancel the current accumulation. - */ -void NimBLEValue::cancel() { - NIMBLE_LOGD(LOG_TAG, ">> cancel"); - m_accumulation = ""; - m_readOffset = 0; -} // cancel - - -/** - * @brief Commit the current accumulation. - * When writing a value, we may find that we write it in "parts" meaning that the writes come in in pieces - * of the overall message. After the last part has been received, we may perform a commit which means that - * we now have the complete message and commit the change as a unit. - */ -void NimBLEValue::commit() { - NIMBLE_LOGD(LOG_TAG, ">> commit"); - // If there is nothing to commit, do nothing. - if (m_accumulation.length() == 0) return; - setValue(m_accumulation); - m_accumulation = ""; - m_readOffset = 0; -} // commit - - -/** - * @brief Get a pointer to the data. - * @return A pointer to the data. - */ -uint8_t* NimBLEValue::getData() { - return (uint8_t*) m_value.data(); -} - - -/** - * @brief Get the length of the data in bytes. - * @return The length of the data in bytes. - */ -size_t NimBLEValue::getLength() { - return m_value.length(); -} // getLength - - -/** - * @brief Get the read offset. - * @return The read offset into the read. - */ -uint16_t NimBLEValue::getReadOffset() { - return m_readOffset; -} // getReadOffset - - -/** - * @brief Get the current value. - */ -std::string NimBLEValue::getValue() { - return m_value; -} // getValue - - -/** - * @brief Set the read offset - * @param [in] readOffset The offset into the read. - */ -void NimBLEValue::setReadOffset(uint16_t readOffset) { - m_readOffset = readOffset; -} // setReadOffset - - -/** - * @brief Set the current value. - */ -void NimBLEValue::setValue(const std::string &value) { - m_value = value; -} // setValue - - -/** - * @brief Set the current value. - * @param [in] pData The data for the current value. - * @param [in] The length of the new current value. - */ -void NimBLEValue::setValue(const uint8_t* pData, size_t length) { - m_value = std::string((char*) pData, length); -} // setValue - -#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEValue.h b/libesp32/NimBLE-Arduino/src/NimBLEValue.h deleted file mode 100644 index 4fdeb9bc4..000000000 --- a/libesp32/NimBLE-Arduino/src/NimBLEValue.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * NimBLEValue.h - * - * Created: on March 6, 2020 - * Author H2zero - * - * Originally: - * - * BLEValue.h - * - * Created on: Jul 17, 2017 - * Author: kolban - */ - -#ifndef MAIN_BLEVALUE_H_ -#define MAIN_BLEVALUE_H_ -#include "sdkconfig.h" -#if defined(CONFIG_BT_ENABLED) - -#include "nimconfig.h" -#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) - -#include - -/** - * @brief The model of a %BLE value. - */ -class NimBLEValue { -public: - NimBLEValue(); - void addPart(const std::string &part); - void addPart(const uint8_t* pData, size_t length); - void cancel(); - void commit(); - uint8_t* getData(); - size_t getLength(); - uint16_t getReadOffset(); - std::string getValue(); - void setReadOffset(uint16_t readOffset); - void setValue(const std::string &value); - void setValue(const uint8_t* pData, size_t length); - -private: - std::string m_accumulation; - uint16_t m_readOffset; - std::string m_value; - -}; - -#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) -#endif // CONFIG_BT_ENABLED -#endif /* MAIN_BLEVALUE_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/host/ble_hs_pvcy.h b/libesp32/NimBLE-Arduino/src/host/ble_hs_pvcy.h index 0ff32b80b..19087f220 100644 --- a/libesp32/NimBLE-Arduino/src/host/ble_hs_pvcy.h +++ b/libesp32/NimBLE-Arduino/src/host/ble_hs_pvcy.h @@ -19,6 +19,9 @@ * under the License. */ +#ifndef H_BLE_HS_PVCY_ +#define H_BLE_HS_PVCY_ + #include "host/ble_hs.h" #ifdef __cplusplus @@ -26,15 +29,45 @@ extern "C" { #endif #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) -/* Called to configure local(own) privacy (RPA) when using host based privacy. In - * Host based privacy as controller is not aware of RPA, we do it via - * 'BLE_ADDR_RANDOM' addr_type route. + +#define NIMBLE_HOST_DISABLE_PRIVACY 0x00 +#define NIMBLE_HOST_ENABLE_RPA 0x01 +#define NIMBLE_HOST_ENABLE_NRPA 0x02 + +/* Called to configure local(own) privacy (RPA/NRPA) when using Host based privacy. + * In Host based privacy, as controller is not aware of RPA/NRPA address is in use, + * we do it through 'BLE_ADDR_RANDOM (0x01)' addr_type route. This is necessary + * so as to set the private address as random address in controller. + * Remember to configure `BLE_SM_PAIR_KEY_DIST_ID` in our & their + * key distributions for using RPA. For NRPA part of privacy it is not + * necessary to configure key distributions in host, as anyway NRPA is non-resolvable. + * Please call this API once host-controller are synced as we set the private + * (RPA/NRPA) address using host-controller HCI commands. * - * @param enable RPA when enable is not 0 - * disable RPA otherwise + * To give brief information on how to use this feature, + * please refer to following steps while using RPA feature: + * + * 1. Include "host/ble_hs_pvcy.h". + * 2. Set own_addr_type to `BLE_OWN_ADDR_RANDOM`. + * 3. Add `BLE_SM_PAIR_KEY_DIST_ID` to key distribution in + * `ble_hs_cfg.sm_our_key_dist` & `ble_hs_cfg.sm_their_key_dist`. + * 4. Call `ble_hs_pvcy_rpa_config(1)` in Host-Controller sync callback. + * + * In case of NRPA, steps 1, 2 and calling ble_hs_pvcy_rpa_config(2) will + * suffice. + * + * @param enable RPA when param = 1 (NIMBLE_HOST_ENABLE_RPA) + * enable NRPA when param = 2 (NIMBLE_HOST_ENABLE_NRPA) + * disable privacy when param = 0 (NIMBLE_HOST_DISABLE_PRIVACY) * * @return return 0 when successful. * return appropriate error code otherwise */ int ble_hs_pvcy_rpa_config(uint8_t enable); #endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/mesh/glue.h b/libesp32/NimBLE-Arduino/src/mesh/glue.h index 08e81fa41..d6aee21f9 100644 --- a/libesp32/NimBLE-Arduino/src/mesh/glue.h +++ b/libesp32/NimBLE-Arduino/src/mesh/glue.h @@ -332,6 +332,8 @@ static inline void net_buf_simple_restore(struct os_mbuf *buf, static inline void sys_memcpy_swap(void *dst, const void *src, size_t length) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-arith" __ASSERT(((src < dst && (src + length) <= dst) || (src > dst && (dst + length) <= src)), "Source and destination buffers must not overlap"); @@ -341,6 +343,7 @@ static inline void sys_memcpy_swap(void *dst, const void *src, size_t length) for (; length > 0; length--) { *((u8_t *)dst++) = *((u8_t *)src--); } +#pragma GCC diagnostic pop } #define popcount(x) __builtin_popcount(x) diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/pkg.yml deleted file mode 100644 index 44cc0c732..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/pkg.yml +++ /dev/null @@ -1,49 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/mesh -pkg.description: Bluetooth Mesh -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - mesh - -pkg.deps: - - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/util/mem" - - "@apache-mynewt-core/crypto/tinycrypt" - - nimble - - nimble/host - -pkg.deps.BLE_MESH_SHELL: - - "@apache-mynewt-core/sys/shell" - -pkg.deps.BLE_MESH_SETTINGS: - - "@apache-mynewt-core/encoding/base64" - - "@apache-mynewt-core/sys/config" - -pkg.req_apis: - - log - - stats - -pkg.init: - bt_mesh_register_gatt: 'MYNEWT_VAL(BLE_MESH_SYSINIT_STAGE)' - ble_mesh_shell_init: 'MYNEWT_VAL(BLE_MESH_SYSINIT_STAGE_SHELL)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h index c80872898..90c32e22a 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_gap_priv.h @@ -99,7 +99,7 @@ int ble_gap_rx_l2cap_update_req(uint16_t conn_handle, struct ble_gap_upd_params *params); void ble_gap_rx_phy_update_complete(struct hci_le_phy_upd_complete *evt); void ble_gap_enc_event(uint16_t conn_handle, int status, - int security_restored); + int security_restored, int bonded); void ble_gap_passkey_event(uint16_t conn_handle, struct ble_gap_passkey_params *passkey_params); void ble_gap_notify_rx_event(uint16_t conn_handle, uint16_t attr_handle, diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_id_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_id_priv.h index c031b9511..85260ec48 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_id_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_id_priv.h @@ -36,6 +36,7 @@ void ble_hs_id_rnd_reset(void); #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) bool ble_hs_is_rpa(uint8_t *addr, uint8_t addr_type); int ble_hs_id_set_pseudo_rnd(const uint8_t *); +int ble_hs_id_set_nrpa_rnd(void); #endif #ifdef __cplusplus } diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_priv.h index 27bf904b7..49269546c 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_priv.h @@ -115,9 +115,9 @@ int ble_hs_hci_evt_acl_process(struct os_mbuf *om); int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid, struct ble_hs_conn **out_conn, struct ble_l2cap_chan **out_chan); -void ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, - struct ble_hs_conn **out_conn, - struct ble_l2cap_chan **out_chan); +int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid, + struct ble_hs_conn **out_conn, + struct ble_l2cap_chan **out_chan); uint8_t ble_hs_misc_addr_type_to_id(uint8_t addr_type); int ble_hs_misc_restore_irks(void); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h index 568aa89ab..e76a26a55 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_hs_resolv_priv.h @@ -61,7 +61,7 @@ struct ble_hs_dev_records { /* Add a device to the resolving list */ int ble_hs_resolv_list_add(uint8_t *cmdbuf); -int ble_hs_gen_own_rpa_random(void); +int ble_hs_gen_own_private_rnd(void); uint8_t *ble_hs_get_rpa_local(void); /* Remove a device from the resolving list */ @@ -71,6 +71,8 @@ void ble_hs_resolv_list_clear_all(void); /* Address resolution enable command */ void ble_hs_resolv_enable(bool); +void ble_hs_resolv_nrpa_enable(void); +void ble_hs_resolv_nrpa_disable(void); /* Finds 'addr' in resolving list. Doesnt check if address resolution enabled */ struct ble_hs_resolv_entry * diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h index 74205bd0c..bbb4b03ae 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/src/ble_sm_priv.h @@ -277,10 +277,10 @@ struct ble_sm_result { uint8_t sm_err; struct ble_gap_passkey_params passkey_params; void *state_arg; - unsigned execute:1; - unsigned enc_cb:1; - unsigned persist_keys:1; - unsigned restore:1; + unsigned execute : 1; + unsigned enc_cb : 1; + unsigned bonded : 1; + unsigned restore : 1; }; #if MYNEWT_VAL(BLE_HS_DEBUG) diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/syscfg.yml deleted file mode 100644 index 7d5a36a71..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/syscfg.yml +++ /dev/null @@ -1,540 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - BLE_MESH_PROV: - description: > - Enable provisioning. It is automatically enabled whenever - BLE_MESH_PB_ADV or BLE_MESH_PB_GATT is set. - value: 1 - - BLE_MESH_PB_ADV: - description: > - Enable this option to allow the device to be provisioned over - the advertising bearer. - value: 1 - - BLE_MESH_PROXY: - description: > - Enable proxy. This is automatically set whenever BLE_MESH_PB_GATT or - BLE_MESH_GATT_PROXY is set. - value: 0 - - BLE_MESH_PB_GATT: - description: > - Enable this option to allow the device to be provisioned over - the GATT bearer. - value: 1 - - BLE_MESH_GATT_PROXY: - description: > - This option enables support for the Mesh GATT Proxy Service, - i.e. the ability to act as a proxy between a Mesh GATT Client - and a Mesh network. - value: 1 - - BLE_MESH_NODE_ID_TIMEOUT: - description: > - This option determines for how long the local node advertises - using Node Identity. The given value is in seconds. The - specification limits this to 60 seconds, and implies that to - be the appropriate value as well, so just leaving this as the - default is the safest option. - value: 60 - - BLE_MESH_PROXY_FILTER_SIZE: - descryption: > - This option specifies how many Proxy Filter entries the local - node supports. - value: 1 - - BLE_MESH_SUBNET_COUNT: - description: > - This option specifies how many subnets a Mesh network can - participate in at the same time. - value: 1 - - BLE_MESH_APP_KEY_COUNT: - description: > - This option specifies how many application keys the device can - store per network. - value: 1 - - BLE_MESH_MODEL_KEY_COUNT: - description: > - This option specifies how many application keys each model can - at most be bound to. - value: 1 - - BLE_MESH_MODEL_GROUP_COUNT: - description: > - This option specifies how many group addresses each model can - at most be subscribed to. - value: 1 - - BLE_MESH_LABEL_COUNT: - description: > - This option specifies how many Label UUIDs can be stored. - value: 1 - - BLE_MESH_CRPL: - description: > - This options specifies the maximum capacity of the replay - protection list. This option is similar to the network message - cache size, but has a different purpose. - value: 10 - - BLE_MESH_ADV_TASK_PRIO: - description: > - Advertising task prio (FIXME) - type: task_priority - value: 9 - - BLE_MESH_MSG_CACHE_SIZE: - description: > - Number of messages that are cached for the network. This description - prevent unnecessary decryption operations and unnecessary - relays. This option is similar to the replay protection list, - but has a different purpose. - value: 10 - - BLE_MESH_ADV_BUF_COUNT: - description: > - Number of advertising buffers available. This should be chosen - based on what kind of features the local node shoule have. E.g. - a relay will perform better the more buffers it has. Another - thing to consider is outgoing segmented messages. There must - be at least three more advertising buffers than the maximum - supported outgoing segment count (BT_MESH_TX_SEG_MAX). - value: 6 - - BLE_MESH_IVU_DIVIDER: - description: > - When the IV Update state enters Normal operation or IV Update - in Progress, we need to keep track of how many hours has passed - in the state, since the specification requires us to remain in - the state at least for 96 hours (Update in Progress has an - additional upper limit of 144 hours). - - In order to fulfil the above requirement, even if the node might - be powered off once in a while, we need to store persistently - how many hours the node has been in the state. This doesn't - necessarily need to happen every hour (thanks to the flexible - duration range). The exact cadence will depend a lot on the - ways that the node will be used and what kind of power source it - has. - - Since there is no single optimal answer, this configuration - option allows specifying a divider, i.e. how many intervals - the 96 hour minimum gets split into. After each interval the - duration that the node has been in the current state gets - stored to flash. E.g. the default value of 4 means that the - state is saved every 24 hours (96 / 4). - value: 4 - - BLE_MESH_TX_SEG_MSG_COUNT: - description: > - Maximum number of simultaneous outgoing multi-segment and/or - reliable messages. - value: 4 - - BLE_MESH_RX_SEG_MSG_COUNT: - description: > - Maximum number of simultaneous incoming multi-segment and/or - reliable messages. - value: 2 - - BLE_MESH_RX_SDU_MAX: - description: > - Maximum incoming Upper Transport Access PDU length. This - determines also how many segments incoming segmented messages - can have. Each segment can contain 12 bytes, so this value should - be set to a multiple of 12 to avoid wasted memory. The minimum - requirement is 2 segments (24 bytes) whereas the maximum supported - by the Mesh specification is 32 segments (384 bytes). - value: 72 - - BLE_MESH_TX_SEG_MAX: - description: > - Maximum number of segments supported for outgoing messages. - This value should typically be fine-tuned based on what - models the local node supports, i.e. what's the largest - message payload that the node needs to be able to send. - This value affects memory and call stack consumption, which - is why the default is lower than the maximum that the - specification would allow (32 segments). - - The maximum outgoing SDU size is 12 times this number (out of - which 4 or 8 bytes is used for the Transport Layer MIC). For - example, 5 segments means the maximum SDU size is 60 bytes, - which leaves 56 bytes for application layer data using a - 4-byte MIC and 52 bytes using an 8-byte MIC. - - Be sure to specify a sufficient number of advertising buffers - when setting this option to a higher value. There must be at - least three more advertising buffers (BT_MESH_ADV_BUF_COUNT) - as there are outgoing segments. - value: 3 - - BLE_MESH_RELAY: - description: > - Support for acting as a Mesh Relay Node. - value: 0 - - BLE_MESH_LOW_POWER: - description: > - Enable this option to be able to act as a Low Power Node. - value: 0 - - BLE_MESH_LPN_ESTABLISHMENT: - description: > - Perform the Friendship establishment using low power, with - the help of a reduced scan duty cycle. The downside of this - is that the node may miss out on messages intended for it - until it has successfully set up Friendship with a Friend - node. - value: 1 - - BLE_MESH_LPN_AUTO: - description: > - Automatically enable LPN functionality once provisioned and start - looking for Friend nodes. If this option is disabled LPN mode - needs to be manually enabled by calling bt_mesh_lpn_set(true). - node. - value: 1 - - BLE_MESH_LPN_AUTO_TIMEOUT: - description: > - Time in seconds from the last received message, that the node - will wait before starting to look for Friend nodes. - value: 15 - - BLE_MESH_LPN_RETRY_TIMEOUT: - description: > - Time in seconds between Friend Requests, if a previous Friend - Request did not receive any acceptable Friend Offers. - value: 8 - - BLE_MESH_LPN_RSSI_FACTOR: - description: > - The contribution of the RSSI measured by the Friend node used - in Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. - value: 0 - - BLE_MESH_LPN_RECV_WIN_FACTOR: - description: > - The contribution of the supported Receive Window used in - Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. - value: 0 - - BLE_MESH_LPN_MIN_QUEUE_SIZE: - description: > - The MinQueueSizeLog field is defined as log_2(N), where N is - the minimum number of maximum size Lower Transport PDUs that - the Friend node can store in its Friend Queue. As an example, - MinQueueSizeLog value 1 gives N = 2, and value 7 gives N = 128. - value: 1 - - BLE_MESH_LPN_RECV_DELAY: - description: > - The ReceiveDelay is the time between the Low Power node - sending a request and listening for a response. This delay - allows the Friend node time to prepare the response. The value - is in units of milliseconds. - value: 100 - - BLE_MESH_LPN_POLL_TIMEOUT: - description: > - PollTimeout timer is used to measure time between two - consecutive requests sent by the Low Power node. If no - requests are received by the Friend node before the - PollTimeout timer expires, then the friendship is considered - terminated. The value is in units of 100 milliseconds, so e.g. - a value of 300 means 30 seconds. - value: 300 - - BLE_MESH_LPN_INIT_POLL_TIMEOUT: - description: > - The initial value of the PollTimeout timer when Friendship - gets established for the first time. After this the timeout - will gradually grow toward the actual PollTimeout, doubling - in value for each iteration. The value is in units of 100 - milliseconds, so e.g. a value of 300 means 3 seconds. - value: MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT - - BLE_MESH_LPN_SCAN_LATENCY: - description: > - Latency in milliseconds that it takes to enable scanning. This - is in practice how much time in advance before the Receive Window - that scanning is requested to be enabled. - value: 10 - - BLE_MESH_LPN_GROUPS: - description: > - Maximum number of groups that the LPN can subscribe to. - value: 10 - - BLE_MESH_FRIEND: - description: > - Enable this option to be able to act as a Friend Node. - value: 0 - - BLE_MESH_FRIEND_RECV_WIN: - description: > - Receive Window in milliseconds supported by the Friend node. - value: 255 - - BLE_MESH_FRIEND_QUEUE_SIZE: - description: > - Minimum number of buffers available to be stored for each - local Friend Queue. - value: 16 - - BLE_MESH_FRIEND_SUB_LIST_SIZE: - description: > - Size of the Subscription List that can be supported by a - Friend node for a Low Power node. - value: 3 - - BLE_MESH_FRIEND_LPN_COUNT: - description: > - Number of Low Power Nodes the Friend can have a Friendship - with simultaneously. - value: 2 - - BLE_MESH_FRIEND_SEG_RX: - description: > - Number of incomplete segment lists that we track for each LPN - that we are Friends for. In other words, this determines how - many elements we can simultaneously be receiving segmented - messages from when the messages are going into the Friend queue. - value: 1 - - BLE_MESH_CFG_CLI: - description: > - Enable support for the configuration client model. - value: 0 - - BLE_MESH_HEALTH_CLI: - description: > - Enable support for the health client model. - value: 0 - - BLE_MESH_SHELL: - description: > - Activate shell module that provides Bluetooth Mesh commands to - the console. - value: 0 - - BLE_MESH_DEBUG: - description: > - Use this option to enable debug logs for the Bluetooth - Mesh functionality. - value: 0 - - BLE_MESH_DEBUG_NET: - description: > - Use this option to enable Network layer debug logs for the - Bluetooth Mesh functionality. - value: 0 - - BLE_MESH_DEBUG_TRANS: - description: > - Use this option to enable Transport layer debug logs for the - Bluetooth Mesh functionality. - value: 0 - - BLE_MESH_DEBUG_BEACON: - description: > - Use this option to enable Beacon-related debug logs for the - Bluetooth Mesh functionality. - value: 0 - - BLE_MESH_DEBUG_CRYPTO: - description: > - Use this option to enable cryptographic debug logs for the - Bluetooth Mesh functionality. - value: 0 - - BLE_MESH_DEBUG_PROV: - description: > - Use this option to enable Provisioning debug logs for the - Bluetooth Mesh functionality. - value: 0 - - BLE_MESH_DEBUG_ACCESS: - description: > - Use this option to enable Access layer and device composition - related debug logs for Bluetooth Mesh. - value: 0 - - BLE_MESH_DEBUG_MODEL: - description: > - Use this option to enable debug logs for the Foundation - Models. - value: 0 - - BLE_MESH_DEBUG_ADV: - description: > - Use this option to enable advertising debug logs for - the Bluetooth Mesh functionality. - value: 0 - - BLE_MESH_DEBUG_LOW_POWER: - description: > - Use this option to enable Low Power debug logs for the - Bluetooth Mesh functionality. - value: 0 - - BLE_MESH_DEBUG_FRIEND: - description: > - Use this option to enable Friend debug logs for the - Bluetooth Mesh functionality. - value: 0 - - BLE_MESH_DEBUG_PROXY: - description: > - Use this option to enable Proxy protocol debug logs. - value: 0 - - BLE_MESH_DEBUG_SETTINGS: - description: > - Use this option to enable persistent settings debug logs. - value: 1 - - BLE_MESH_IV_UPDATE_TEST: - description: > - This option removes the 96 hour limit of the IV Update - Procedure and lets the state be changed at any time. - value: 0 - - BLE_MESH_TESTING: - description: > - This option enables testing API. - value: 0 - - BLE_MESH_DEV_UUID: - description: > - Device UUID - value: ((uint8_t[16]){0x11, 0x22, 0}) - - BLE_MESH_SHELL_MODELS: - description: > - Include implementation of some demo models. - value: 0 - - BLE_MESH_OOB_OUTPUT_ACTIONS: - description: > - Supported Output OOB Actions - BT_MESH_NO_OUTPUT = 0, - BT_MESH_BLINK = BIT(0) - BT_MESH_BEEP = BIT(1) - BT_MESH_VIBRATE = BIT(2) - BT_MESH_DISPLAY_NUMBER = BIT(3) - BT_MESH_DISPLAY_STRING = BIT(4) - value: ((BT_MESH_DISPLAY_NUMBER)) - - BLE_MESH_OOB_OUTPUT_SIZE: - description: > - Output OOB size - value: 4 - - BLE_MESH_OOB_INPUT_ACTIONS: - description: > - Supported Input OOB Actions - BT_MESH_NO_INPUT = 0, - BT_MESH_PUSH = BIT(0) - BT_MESH_TWIST = BIT(1) - BT_MESH_ENTER_NUMBER = BIT(2) - BT_MESH_ENTER_STRING = BIT(3) - value: ((BT_MESH_NO_INPUT)) - - BLE_MESH_OOB_INPUT_SIZE: - description: > - Input OOB size - value: 4 - - BLE_MESH_SETTINGS: - description: > - This option enables Mesh settings storage. - value: 1 - - BLE_MESH_STORE_TIMEOUT: - description: > - This value defines in seconds how soon any pending changes - are actually written into persistent storage (flash) after - a change occurs. - value: 2 - - BLE_MESH_SEQ_STORE_RATE: - description: > - This value defines how often the local sequence number gets - updated in persistent storage (i.e. flash). E.g. a value of 100 - means that the sequence number will be stored to flash on every - 100th increment. If the node sends messages very frequently a - higher value makes more sense, whereas if the node sends - infrequently a value as low as 0 (update storage for every - increment) can make sense. When the stack gets initialized it - will add this number to the last stored one, so that it starts - off with a value that's guaranteed to be larger than the last - one used before power off. - value: 128 - - BLE_MESH_RPL_STORE_TIMEOUT: - description: > - This value defines in seconds how soon the RPL gets written to - persistent storage after a change occurs. If the node receives - messages frequently it may make sense to have this set to a - large value, whereas if the RPL gets updated infrequently a - value as low as 0 (write immediately) may make sense. Note that - if the node operates a security sensitive use case, and there's - a risk of sudden power loss, it may be a security vulnerability - to set this value to anything else than 0 (a power loss before - writing to storage exposes the node to potential message - replay attacks). - value: 5 - - BLE_MESH_DEVICE_NAME: - description: > - This value defines BLE Mesh device/node name. - value: '"nimble-mesh-node"' - - BLE_MESH_SYSINIT_STAGE: - description: > - Primary sysinit stage for BLE mesh functionality. - value: 500 - - BLE_MESH_SYSINIT_STAGE_SHELL: - description: > - Secondary sysinit stage for BLE mesh functionality. - value: 1000 - -syscfg.vals.BLE_MESH_SHELL: - BLE_MESH_CFG_CLI: 1 - BLE_MESH_HEALTH_CLI: 1 - BLE_MESH_IV_UPDATE_TEST: 1 - -syscfg.vals.BLE_MESH_GATT_PROXY: - BLE_MESH_PROXY: 1 - -syscfg.vals.BLE_MESH_PB_GATT: - BLE_MESH_PROXY: 1 - BLE_MESH_PROV: 1 - -syscfg.vals.BLE_MESH_PB_ADV: - BLE_MESH_PROV: 1 diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/ans/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/ans/pkg.yml deleted file mode 100644 index 691e566e1..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/ans/pkg.yml +++ /dev/null @@ -1,34 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/services/ans -pkg.description: Alert Notification Service Server. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - ans - - nimble - -pkg.deps: - - nimble/host - -pkg.init: - ble_svc_ans_init: 'MYNEWT_VAL(BLE_SVC_ANS_SYSINIT_STAGE)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/ans/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/ans/syscfg.yml deleted file mode 100644 index 74de8d963..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/ans/syscfg.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -syscfg.defs: - BLE_SVC_ANS_NEW_ALERT_CAT: - description: "Initial supported new alert category bitmask." - value: 0 - - BLE_SVC_ANS_UNR_ALERT_CAT: - description: "Initial supported unread alert category bitmask." - value: 0 - - BLE_SVC_ANS_SYSINIT_STAGE: - description: > - Sysinit stage for the alert notification service. - value: 303 diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/bas/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/bas/pkg.yml deleted file mode 100644 index afdc69421..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/bas/pkg.yml +++ /dev/null @@ -1,34 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/services/bas -pkg.description: Battery Service -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - bas - - nimble - -pkg.deps: - - nimble/host - -pkg.init: - ble_svc_bas_init: 'MYNEWT_VAL(BLE_SVC_BAS_SYSINIT_STAGE)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/bas/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/bas/syscfg.yml deleted file mode 100644 index 279930f14..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/bas/syscfg.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -syscfg.defs: - BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM: - description: > - Defines permissions for reading "Battery Level" characteristics. Can - be zero to allow read without extra permissions or combination of: - BLE_GATT_CHR_F_READ_ENC - BLE_GATT_CHR_F_READ_AUTHEN - BLE_GATT_CHR_F_READ_AUTHOR - value: 0 - BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE: - description: > - Set to 1 to support notification or 0 to disable it. - value: 1 - BLE_SVC_BAS_SYSINIT_STAGE: - description: > - Sysinit stage for the battery level service. - value: 303 diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/gap/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/gap/pkg.yml deleted file mode 100644 index a2ef756e3..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/gap/pkg.yml +++ /dev/null @@ -1,34 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/services/gap -pkg.description: Implements the GAP Service. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - nimble - - gap - -pkg.deps: - - nimble/host - -pkg.init: - ble_svc_gap_init: 'MYNEWT_VAL(BLE_SVC_GAP_SYSINIT_STAGE)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/gap/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/gap/syscfg.yml deleted file mode 100644 index ad6aa7ef3..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/gap/syscfg.yml +++ /dev/null @@ -1,83 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - BLE_SVC_GAP_DEVICE_NAME: - description: > - Default value for "Device Name" characteristics, unless overwritten - by application. - value: '"nimble"' - BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM: - description: > - Defines permissions for writing "Device Name" characteristics. Can - be zero to allow write without extra permissions or combination of: - BLE_GATT_CHR_F_WRITE_ENC - BLE_GATT_CHR_F_WRITE_AUTHEN - BLE_GATT_CHR_F_WRITE_AUTHOR - Set to '-1' to make characteristic read only. - value: -1 - BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH: - description: Maximum length for "Device Name" characteristics - value: 31 - BLE_SVC_GAP_APPEARANCE: - description: 'Device appearance' - value: 0 - BLE_SVC_GAP_APPEARANCE_WRITE_PERM: - description: > - Defines permissions for writing "Appearance" characteristics. Can - be zero to allow write without extra permissions or combination of: - BLE_GATT_CHR_F_WRITE_ENC - BLE_GATT_CHR_F_WRITE_AUTHEN - BLE_GATT_CHR_F_WRITE_AUTHOR - Set to '-1' to make characteristic read only. - value: -1 - - # Setting all values for PPCP to '0' will disable characteristic! - BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL: - description: > - Value of "minimum connection interval" of PPCP characteristic as - defined by Core specification 5.0, Vol 3, Part C, section 12.3. - value: 0 - BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL: - description: > - Value of "maximum connection interval" of PPCP characteristic as - defined by Core specification 5.0, Vol 3, Part C, section 12.3. - value: 0 - BLE_SVC_GAP_PPCP_SLAVE_LATENCY: - description: > - Value of "slave latency" of PPCP characteristic as defined by Core - specification 5.0, Vol 3, Part C, section 12.3. - value: 0 - BLE_SVC_GAP_PPCP_SUPERVISION_TMO: - description: > - Value of "connection supervision timeout multiplier" of PPCP - characteristic as defined by Core specification 5.0, Vol 3, Part C, - section 12.3. - value: 0 - - BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION: - description: > - Value of "Central Address Resolution" characteristics, as defined - by Core specification 5.0, Vol 3, Part C, section 12. - Set to '-1' to disable. - value: -1 - - BLE_SVC_GAP_SYSINIT_STAGE: - description: > - Sysinit stage for the GAP BLE service. - value: 301 diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/gatt/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/gatt/pkg.yml deleted file mode 100644 index e3704bc18..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/gatt/pkg.yml +++ /dev/null @@ -1,34 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/services/gatt -pkg.description: Implements the GATT service. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - nimble - - gatt - -pkg.deps: - - nimble/host - -pkg.init: - ble_svc_gatt_init: 'MYNEWT_VAL(BLE_SVC_GATT_SYSINIT_STAGE)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/gatt/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/gatt/syscfg.yml deleted file mode 100644 index 6ba1b333e..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/gatt/syscfg.yml +++ /dev/null @@ -1,24 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - BLE_SVC_GATT_SYSINIT_STAGE: - description: > - Sysinit stage for the GATT BLE service - value: 302 diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/ias/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/ias/pkg.yml deleted file mode 100644 index 3b0ca0745..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/ias/pkg.yml +++ /dev/null @@ -1,34 +0,0 @@ - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/services/ias -pkg.description: Immediate Alert Service Implementation. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - ias - - nimble - -pkg.deps: - - nimble/host - -pkg.init: - ble_svc_ias_init: 'MYNEWT_VAL(BLE_SVC_IAS_SYSINIT_STAGE)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/ias/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/ias/syscfg.yml deleted file mode 100644 index 2cbed3ab4..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/ias/syscfg.yml +++ /dev/null @@ -1,23 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - BLE_SVC_IAS_SYSINIT_STAGE: - description: > - Sysinit stage for the immediate alert BLE service. - value: 303 diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/ipss/src/ble_svc_ipss.c b/libesp32/NimBLE-Arduino/src/nimble/host/services/ipss/src/ble_svc_ipss.c new file mode 100644 index 000000000..f42ca1e9e --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/services/ipss/src/ble_svc_ipss.c @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +#include "sysinit/sysinit.h" +#include "host/ble_hs.h" +#include "services/ipss/ble_svc_ipss.h" + +static const struct ble_gatt_svc_def ble_svc_ipss_defs[] = { + { + /*** Service: GATT */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BLE_SVC_IPSS_UUID16), + .characteristics = NULL, + }, + { + 0, /* No more services. */ + }, +}; + +void +ble_svc_ipss_init(void) +{ + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = ble_gatts_count_cfg(ble_svc_ipss_defs); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_gatts_add_svcs(ble_svc_ipss_defs); + SYSINIT_PANIC_ASSERT(rc == 0); +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/lls/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/lls/pkg.yml deleted file mode 100644 index 6160f020e..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/lls/pkg.yml +++ /dev/null @@ -1,34 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/services/lls -pkg.description: Link Loss Service Implementation. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - lls - - nimble - -pkg.deps: - - nimble/host - -pkg.init: - ble_svc_lls_init: 'MYNEWT_VAL(BLE_SVC_LLS_SYSINIT_STAGE)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/lls/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/lls/syscfg.yml deleted file mode 100644 index 312b08a2f..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/lls/syscfg.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -syscfg.defs: - BLE_SVC_LLS_SYSINIT_STAGE: - description: > - Sysinit stage for the link loss BLE service. - value: 303 diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/tps/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/tps/pkg.yml deleted file mode 100644 index 3d4c5e98e..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/tps/pkg.yml +++ /dev/null @@ -1,34 +0,0 @@ - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/services/tps -pkg.description: Tx Power Service adopted specification. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - tps - - nimble - -pkg.deps: - - nimble/host - -pkg.init: - ble_svc_tps_init: 'MYNEWT_VAL(BLE_SVC_TPS_SYSINIT_STAGE)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/services/tps/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/services/tps/syscfg.yml deleted file mode 100644 index 0391e8b1d..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/services/tps/syscfg.yml +++ /dev/null @@ -1,23 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -syscfg.defs: - BLE_SVC_TPS_SYSINIT_STAGE: - description: > - Sysinit stage for the transmit power BLE service. - value: 303 - diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_id.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_id.c index 43380d1f6..db32f90df 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_id.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_id.c @@ -67,6 +67,37 @@ ble_hs_id_gen_rnd(int nrpa, ble_addr_t *out_addr) } #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) +/** + * Sets the device's pseudo Non Resolvable Private Address when 'Host based + * privacy' is in use. + * + * @return 0 on success; + * Appropriate error code if failure. + */ +int +ble_hs_id_set_nrpa_rnd() +{ + + ble_addr_t nrpa_addr; + int rc; + + ble_hs_id_gen_rnd(1, &nrpa_addr); + + ble_hs_lock(); + + /* set the NRPA address as pseudo random address in controller */ + rc = ble_hs_hci_util_set_random_addr(nrpa_addr.val); + if (rc != 0) { + goto done; + } + + memcpy(ble_hs_id_rnd, nrpa_addr.val, BLE_DEV_ADDR_LEN); + +done: + ble_hs_unlock(); + return rc; +} + /** * Sets the device's pseudo RPA address when 'Host based privacy' is in use. * The address type (RPA) is inferred from the most-significant bits. The diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_id_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_id_priv.h index c031b9511..85260ec48 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_id_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_id_priv.h @@ -36,6 +36,7 @@ void ble_hs_id_rnd_reset(void); #if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) bool ble_hs_is_rpa(uint8_t *addr, uint8_t addr_type); int ble_hs_id_set_pseudo_rnd(const uint8_t *); +int ble_hs_id_set_nrpa_rnd(void); #endif #ifdef __cplusplus } diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_pvcy.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_pvcy.c index 32f15974b..69f3da543 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_pvcy.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_pvcy.c @@ -22,6 +22,7 @@ #include "stats/stats.h" #include "ble_hs_priv.h" #include "ble_hs_resolv_priv.h" +#include "host/ble_hs_pvcy.h" static uint8_t ble_hs_pvcy_started; static uint8_t ble_hs_pvcy_irk[16]; @@ -329,7 +330,7 @@ ble_hs_pvcy_rpa_config(uint8_t enable) { int rc = 0; - if (enable != 0) { + if (enable != NIMBLE_HOST_DISABLE_PRIVACY) { rc = ble_hs_pvcy_ensure_started(); if (rc != 0) { return rc; @@ -337,8 +338,15 @@ ble_hs_pvcy_rpa_config(uint8_t enable) ble_hs_resolv_enable(true); + /* Configure NRPA address related flags according to input parameter */ + if (enable == NIMBLE_HOST_ENABLE_NRPA) { + ble_hs_resolv_nrpa_enable(); + } else { + ble_hs_resolv_nrpa_disable(); + } + /* Generate local RPA address and set it in controller */ - rc = ble_hs_gen_own_rpa_random(); + rc = ble_hs_gen_own_private_rnd(); } else { ble_hs_resolv_enable(false); } diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv.c index 7f2413898..60c77c9b8 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv.c @@ -50,6 +50,9 @@ struct ble_hs_resolv_data { struct ble_npl_callout rpa_timer; }; +/* NRPA bit: Enables NRPA as private address. */ +static bool nrpa_pvcy; + /*** APIs for Peer Device Records. * * These Peer records are necessary to take care of Peers with RPA address when @@ -305,6 +308,10 @@ is_ble_hs_resolv_enabled(void) bool ble_host_rpa_enabled(void) { + if (nrpa_pvcy) { + return false; + } + if (is_ble_hs_resolv_enabled() && ble_hs_pvcy_enabled()) { return true; } @@ -385,12 +392,16 @@ ble_hs_resolv_gen_priv_addr(struct ble_hs_resolv_entry *rl, int local) addr[2] = ecb.cipher_text[13]; } -/* Called to generate RPA address and this address is set in controller as - * Random address. This is necessary in Host based privacy because controller is unaware of RPA - * address is being used */ +/* Called to generate private (RPA/NRPA) address and this address is set in controller as + * Random address. This is necessary in Host based privacy because controller + * is unaware of private address is being used */ int -ble_hs_gen_own_rpa_random(void) +ble_hs_gen_own_private_rnd(void) { + if (nrpa_pvcy) { + return ble_hs_id_set_nrpa_rnd(); + } + struct ble_hs_resolv_entry *rl = &g_ble_hs_resolv_list[0]; ble_hs_resolv_gen_priv_addr(rl, 1); @@ -412,12 +423,11 @@ ble_hs_get_rpa_local(void) static void ble_hs_resolv_rpa_timer_cb(struct ble_npl_event *ev) { - if (ble_host_rpa_enabled()) { - BLE_HS_LOG(DEBUG, "RPA Timeout; start active adv & scan with new RPA\n"); - + if (ble_host_rpa_enabled() || (nrpa_pvcy)) { + BLE_HS_LOG(DEBUG, "RPA/NRPA Timeout; start active adv & scan with new Private address \n"); ble_gap_preempt(); - /* Generate local RPA */ - ble_hs_gen_own_rpa_random(); + /* Generate local private address */ + ble_hs_gen_own_private_rnd(); ble_npl_callout_reset(&g_ble_hs_resolv_data.rpa_timer, (int32_t)g_ble_hs_resolv_data.rpa_tmo); ble_gap_preempt_done(); @@ -595,6 +605,23 @@ ble_hs_resolv_list_clear_all(void) return; } +/** +* Called by host stack to enable NRPA privacy flag for future reference +*/ +void +ble_hs_resolv_nrpa_enable(void) +{ + nrpa_pvcy = true; +} + +/** +* Called by host stack to disable NRPA privacy flag +*/ +void +ble_hs_resolv_nrpa_disable(void) +{ + nrpa_pvcy = false; +} /** * Called to enable or disable address resolution in the host * diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv_priv.h index 568aa89ab..e76a26a55 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv_priv.h +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_hs_resolv_priv.h @@ -61,7 +61,7 @@ struct ble_hs_dev_records { /* Add a device to the resolving list */ int ble_hs_resolv_list_add(uint8_t *cmdbuf); -int ble_hs_gen_own_rpa_random(void); +int ble_hs_gen_own_private_rnd(void); uint8_t *ble_hs_get_rpa_local(void); /* Remove a device from the resolving list */ @@ -71,6 +71,8 @@ void ble_hs_resolv_list_clear_all(void); /* Address resolution enable command */ void ble_hs_resolv_enable(bool); +void ble_hs_resolv_nrpa_enable(void); +void ble_hs_resolv_nrpa_disable(void); /* Finds 'addr' in resolving list. Doesnt check if address resolution enabled */ struct ble_hs_resolv_entry * diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_uuid.c b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_uuid.c index 16352cf6e..3a1642480 100644 --- a/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_uuid.c +++ b/libesp32/NimBLE-Arduino/src/nimble/host/src/ble_uuid.c @@ -239,7 +239,10 @@ ble_uuid_flat(const ble_uuid_t *uuid, void *dst) break; case BLE_UUID_TYPE_32: memcpy(dst, ble_uuid_base, 16); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-arith" put_le32(dst + 12, BLE_UUID32(uuid)->value); +#pragma GCC diagnostic pop break; case BLE_UUID_TYPE_128: memcpy(dst, BLE_UUID128(uuid)->value, 16); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/store/config/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/store/config/pkg.yml deleted file mode 100644 index db80d1df8..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/store/config/pkg.yml +++ /dev/null @@ -1,38 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/store/config -pkg.description: sys/config-based persistence layer for the NimBLE host. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - nimble - - persistence - -pkg.deps: - - "@apache-mynewt-core/encoding/base64" - - nimble/host - -pkg.deps.BLE_STORE_CONFIG_PERSIST: - - "@apache-mynewt-core/sys/config" - -pkg.init: - ble_store_config_init: 'MYNEWT_VAL(BLE_STORE_SYSINIT_STAGE)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_config_conf.unused b/libesp32/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_config_conf.unused deleted file mode 100644 index e74127ae9..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/store/config/src/ble_store_config_conf.unused +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include "syscfg/syscfg.h" - -#if MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST) - -#include -#include - -#include "sysinit/sysinit.h" -#include "host/ble_hs.h" -#include "config/config.h" -#include "base64/base64.h" -#include "store/config/ble_store_config.h" -#include "ble_store_config_priv.h" - -static int -ble_store_config_conf_set(int argc, char **argv, char *val); -static int -ble_store_config_conf_export(void (*func)(char *name, char *val), - enum conf_export_tgt tgt); - -static struct conf_handler ble_store_config_conf_handler = { - .ch_name = "ble_hs", - .ch_get = NULL, - .ch_set = ble_store_config_conf_set, - .ch_commit = NULL, - .ch_export = ble_store_config_conf_export -}; - -#define BLE_STORE_CONFIG_SEC_ENCODE_SZ \ - BASE64_ENCODE_SIZE(sizeof (struct ble_store_value_sec)) - -#define BLE_STORE_CONFIG_SEC_SET_ENCODE_SZ \ - (MYNEWT_VAL(BLE_STORE_MAX_BONDS) * BLE_STORE_CONFIG_SEC_ENCODE_SZ + 1) - -#define BLE_STORE_CONFIG_CCCD_ENCODE_SZ \ - BASE64_ENCODE_SIZE(sizeof (struct ble_store_value_cccd)) - -#define BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ \ - (MYNEWT_VAL(BLE_STORE_MAX_CCCDS) * BLE_STORE_CONFIG_CCCD_ENCODE_SZ + 1) - -static void -ble_store_config_serialize_arr(const void *arr, int obj_sz, int num_objs, - char *out_buf, int buf_sz) -{ - int arr_size; - - arr_size = obj_sz * num_objs; - assert(arr_size <= buf_sz); - - base64_encode(arr, arr_size, out_buf, 1); -} - -static int -ble_store_config_deserialize_arr(const char *enc, - void *out_arr, - int obj_sz, - int *out_num_objs) -{ - int len; - - len = base64_decode(enc, out_arr); - if (len < 0) { - return OS_EINVAL; - } - - *out_num_objs = len / obj_sz; - return 0; -} - -static int -ble_store_config_conf_set(int argc, char **argv, char *val) -{ - int rc; - - if (argc == 1) { - if (strcmp(argv[0], "our_sec") == 0) { - rc = ble_store_config_deserialize_arr( - val, - ble_store_config_our_secs, - sizeof *ble_store_config_our_secs, - &ble_store_config_num_our_secs); - return rc; - } else if (strcmp(argv[0], "peer_sec") == 0) { - rc = ble_store_config_deserialize_arr( - val, - ble_store_config_peer_secs, - sizeof *ble_store_config_peer_secs, - &ble_store_config_num_peer_secs); - return rc; - } else if (strcmp(argv[0], "cccd") == 0) { - rc = ble_store_config_deserialize_arr( - val, - ble_store_config_cccds, - sizeof *ble_store_config_cccds, - &ble_store_config_num_cccds); - return rc; - } - } - return OS_ENOENT; -} - -static int -ble_store_config_conf_export(void (*func)(char *name, char *val), - enum conf_export_tgt tgt) -{ - union { - char sec[BLE_STORE_CONFIG_SEC_SET_ENCODE_SZ]; - char cccd[BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ]; - } buf; - - ble_store_config_serialize_arr(ble_store_config_our_secs, - sizeof *ble_store_config_our_secs, - ble_store_config_num_our_secs, - buf.sec, - sizeof buf.sec); - func("ble_hs/our_sec", buf.sec); - - ble_store_config_serialize_arr(ble_store_config_peer_secs, - sizeof *ble_store_config_peer_secs, - ble_store_config_num_peer_secs, - buf.sec, - sizeof buf.sec); - func("ble_hs/peer_sec", buf.sec); - - ble_store_config_serialize_arr(ble_store_config_cccds, - sizeof *ble_store_config_cccds, - ble_store_config_num_cccds, - buf.cccd, - sizeof buf.cccd); - func("ble_hs/cccd", buf.cccd); - - return 0; -} - -static int -ble_store_config_persist_sec_set(const char *setting_name, - const struct ble_store_value_sec *secs, - int num_secs) -{ - char buf[BLE_STORE_CONFIG_SEC_SET_ENCODE_SZ]; - int rc; - - ble_store_config_serialize_arr(secs, sizeof *secs, num_secs, - buf, sizeof buf); - rc = conf_save_one(setting_name, buf); - if (rc != 0) { - return BLE_HS_ESTORE_FAIL; - } - - return 0; -} - -int -ble_store_config_persist_our_secs(void) -{ - int rc; - - rc = ble_store_config_persist_sec_set("ble_hs/our_sec", - ble_store_config_our_secs, - ble_store_config_num_our_secs); - if (rc != 0) { - return rc; - } - - return 0; -} - -int -ble_store_config_persist_peer_secs(void) -{ - int rc; - - rc = ble_store_config_persist_sec_set("ble_hs/peer_sec", - ble_store_config_peer_secs, - ble_store_config_num_peer_secs); - if (rc != 0) { - return rc; - } - - return 0; -} - -int -ble_store_config_persist_cccds(void) -{ - char buf[BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ]; - int rc; - - ble_store_config_serialize_arr(ble_store_config_cccds, - sizeof *ble_store_config_cccds, - ble_store_config_num_cccds, - buf, - sizeof buf); - rc = conf_save_one("ble_hs/cccd", buf); - if (rc != 0) { - return BLE_HS_ESTORE_FAIL; - } - - return 0; -} - -void -ble_store_config_conf_init(void) -{ - int rc; - - rc = conf_register(&ble_store_config_conf_handler); - SYSINIT_PANIC_ASSERT_MSG(rc == 0, - "Failed to register ble_store_config conf"); -} - -#endif /* MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST) */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/store/config/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/store/config/syscfg.yml deleted file mode 100644 index ff0689c6d..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/store/config/syscfg.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: - BLE_STORE_CONFIG_PERSIST: - description: > - Whether to save data to sys/config, or just keep it in RAM. - value: 1 - BLE_STORE_SYSINIT_STAGE: - description: > - Sysinit stage for BLE host store. - value: 500 diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/store/ram/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/store/ram/pkg.yml deleted file mode 100644 index 68765fddf..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/store/ram/pkg.yml +++ /dev/null @@ -1,37 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/store/ram -pkg.description: > - DEPRECATED; for a RAM-only BLE store, use store/config and set - BLE_STORE_CONFIG_PERSIST to 0. RAM-based persistence layer for the NimBLE - host. -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - - nimble - - persistence - -pkg.deps: - - nimble/host - -pkg.init: - ble_store_ram_init: 'MYNEWT_VAL(BLE_STORE_RAM_SYSINIT_STAGE)' diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/store/ram/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/store/ram/syscfg.yml deleted file mode 100644 index 442211ddd..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/store/ram/syscfg.yml +++ /dev/null @@ -1,23 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -syscfg.defs: - BLE_STORE_RAM_SYSINIT_STAGE: - description: > - Sysinit stage for the RAM BLE store. - value: 500 - diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/util/pkg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/util/pkg.yml deleted file mode 100644 index 0f5f3a5de..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/util/pkg.yml +++ /dev/null @@ -1,29 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: nimble/host/util -pkg.description: Supplementary utilities for the NimBLE host -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - - ble - - bluetooth - -pkg.deps: - - nimble/host diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/util/syscfg.yml b/libesp32/NimBLE-Arduino/src/nimble/host/util/syscfg.yml deleted file mode 100644 index 2cdd57468..000000000 --- a/libesp32/NimBLE-Arduino/src/nimble/host/util/syscfg.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -syscfg.defs: diff --git a/libesp32/NimBLE-Arduino/src/nimconfig.h b/libesp32/NimBLE-Arduino/src/nimconfig.h index 0be27c198..907e6bc26 100644 --- a/libesp32/NimBLE-Arduino/src/nimconfig.h +++ b/libesp32/NimBLE-Arduino/src/nimconfig.h @@ -9,27 +9,27 @@ /* Detect if using ESP-IDF or Arduino (Arduino won't have these defines in sdkconfig)*/ #if defined(CONFIG_BT_NIMBLE_TASK_STACK_SIZE) || defined(CONFIG_NIMBLE_TASK_STACK_SIZE) -#if defined(CONFIG_NIMBLE_ENABLED) +#if defined(CONFIG_NIMBLE_ENABLED) && !defined(CONFIG_BT_NIMBLE_ENABLED) #define CONFIG_BT_NIMBLE_ENABLED #endif -#if defined(CONFIG_NIMBLE_ROLE_OBSERVER) +#if defined(CONFIG_NIMBLE_ROLE_OBSERVER) && !defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) #define CONFIG_BT_NIMBLE_ROLE_OBSERVER #endif -#if defined(CONFIG_NIMBLE_ROLE_BROADCASTER) +#if defined(CONFIG_NIMBLE_ROLE_BROADCASTER) && !defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) #define CONFIG_BT_NIMBLE_ROLE_BROADCASTER #endif -#if defined(CONFIG_NIMBLE_ROLE_CENTRAL) +#if defined(CONFIG_NIMBLE_ROLE_CENTRAL) && !defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) #define CONFIG_BT_NIMBLE_ROLE_CENTRAL #endif -#if defined(CONFIG_NIMBLE_ROLE_PERIPHERAL) +#if defined(CONFIG_NIMBLE_ROLE_PERIPHERAL) && !defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) #define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL #endif -#if defined(CONFIG_NIMBLE_DEBUG) +#if defined(CONFIG_NIMBLE_DEBUG) && !defined(CONFIG_BT_NIMBLE_DEBUG) #define CONFIG_BT_NIMBLE_DEBUG #endif @@ -52,12 +52,12 @@ /** Comment out if not using NimBLE Server functions * Reduces flash size by approx. 16kB. */ -// #define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL // Tasmota +// #define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL /** Comment out if not using NimBLE Advertising functions * Reduces flash size by approx. 5kB. */ -// #define CONFIG_BT_NIMBLE_ROLE_BROADCASTER // Tasmota +// #define CONFIG_BT_NIMBLE_ROLE_BROADCASTER /** Uncomment to see debug log messages from the NimBLE host * Uses approx. 32kB of flash memory. @@ -89,12 +89,12 @@ #define CONFIG_BT_NIMBLE_MAX_CONNECTIONS 3 /** Sets the number of devices allowed to store/bond with */ -#define CONFIG_BT_NIMBLE_MAX_BONDS 3 // Tasmota +#define CONFIG_BT_NIMBLE_MAX_BONDS 3 /** Sets the number of CCCD's to store per bonded device */ -#define CONFIG_BT_NIMBLE_MAX_CCCDS 3 // Tasmota +#define CONFIG_BT_NIMBLE_MAX_CCCDS 8 -#define CONFIG_BT_NIMBLE_NVS_PERSIST 0 // Tasmota +#define CONFIG_BT_NIMBLE_NVS_PERSIST 0 #define CONFIG_BT_NIMBLE_SM_LEGACY 1 #define CONFIG_BT_NIMBLE_SM_SC 1 #define CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME "nimble" diff --git a/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.controller b/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.controller deleted file mode 100644 index 8479ac1c5..000000000 --- a/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.controller +++ /dev/null @@ -1,32 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# * http://www.apache.org/licenses/LICENSE-2.0 -# * Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -NIMBLE_CFLAGS += \ - -DNIMBLE_CFG_CONTROLLER=1 \ - -NIMBLE_INCLUDE += \ - $(NIMBLE_ROOT)/nimble/transport/ram/include \ - $(NIMBLE_ROOT)/nimble/controller/include \ - $(NIMBLE_ROOT)/nimble/drivers/nrf52/include \ - $(NULL) - -NIMBLE_SRC += \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/transport/ram/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/controller/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/drivers/nrf52/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/porting/nimble/controller/src/*.c)) \ - $(NULL) diff --git a/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.defs b/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.defs deleted file mode 100644 index ffb531fb6..000000000 --- a/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.defs +++ /dev/null @@ -1,68 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# * http://www.apache.org/licenses/LICENSE-2.0 -# * Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -ifeq (,$(NIMBLE_ROOT)) -$(error NIMBLE_ROOT shall be defined) -endif - -NIMBLE_CFLAGS := - -NIMBLE_INCLUDE := \ - $(NIMBLE_ROOT)/nimble/include \ - $(NIMBLE_ROOT)/nimble/host/include \ - $(NIMBLE_ROOT)/nimble/host/services/ans/include \ - $(NIMBLE_ROOT)/nimble/host/services/bas/include \ - $(NIMBLE_ROOT)/nimble/host/services/bleuart/include \ - $(NIMBLE_ROOT)/nimble/host/services/gap/include \ - $(NIMBLE_ROOT)/nimble/host/services/gatt/include \ - $(NIMBLE_ROOT)/nimble/host/services/ias/include \ - $(NIMBLE_ROOT)/nimble/host/services/lls/include \ - $(NIMBLE_ROOT)/nimble/host/services/tps/include \ - $(NIMBLE_ROOT)/nimble/host/store/ram/include \ - $(NIMBLE_ROOT)/nimble/host/util/include \ - $(NIMBLE_ROOT)/porting/nimble/include \ - $(NULL) - -NIMBLE_SRC := \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/porting/nimble/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/util/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/ans/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/bas/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/gap/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/gatt/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/ias/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/lls/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/services/tps/src/*.c)) \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/store/ram/src/*.c)) \ - $(NULL) - -ifneq (,$(NIMBLE_CFG_CONTROLLER)) -include $(NIMBLE_ROOT)/porting/nimble/Makefile.controller -endif - -# TinyCrypt (for SM) -ifneq (,$(NIMBLE_CFG_TINYCRYPT)) -include $(NIMBLE_ROOT)/porting/nimble/Makefile.tinycrypt -endif - -ifneq (,$(NIMBLE_CFG_MESH)) -include $(NIMBLE_ROOT)/porting/nimble/Makefile.mesh -endif - -NIMBLE_OBJ := $(NIMBLE_SRC:.c=.o) diff --git a/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.mesh b/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.mesh deleted file mode 100644 index e7f6ccec6..000000000 --- a/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.mesh +++ /dev/null @@ -1,24 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# * http://www.apache.org/licenses/LICENSE-2.0 -# * Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -NIMBLE_INCLUDE += \ - $(NIMBLE_ROOT)/nimble/host/mesh/include \ - $(NULL) - -NIMBLE_SRC += \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/nimble/host/mesh/src/*.c)) \ - $(NULL) diff --git a/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.tinycrypt b/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.tinycrypt deleted file mode 100644 index 2333e6188..000000000 --- a/libesp32/NimBLE-Arduino/src/porting/nimble/Makefile.tinycrypt +++ /dev/null @@ -1,26 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# * http://www.apache.org/licenses/LICENSE-2.0 -# * Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -TINYCRYPT_CFLAGS := -std=c99 - -TINYCRYPT_INCLUDE := \ - $(NIMBLE_ROOT)/ext/tinycrypt/include \ - $(NULL) - -TINYCRYPT_SRC := \ - $(filter-out $(NIMBLE_IGNORE), $(wildcard $(NIMBLE_ROOT)/ext/tinycrypt/src/*.c)) \ - $(NULL) diff --git a/libesp32/NimBLE-Arduino/src/porting/nimble/pkg.yml b/libesp32/NimBLE-Arduino/src/porting/nimble/pkg.yml deleted file mode 100644 index d56c90dbe..000000000 --- a/libesp32/NimBLE-Arduino/src/porting/nimble/pkg.yml +++ /dev/null @@ -1,43 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: porting/nimble -pkg.type: app -pkg.description: Stub for NimBLE porting -pkg.author: "Apache Mynewt " -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - -pkg.deps: - - nimble/host - - nimble/host/services/ans - - nimble/host/services/bas - - nimble/host/services/gap - - nimble/host/services/gatt - - nimble/host/services/ias - - nimble/host/services/lls - - nimble/host/services/tps - - nimble/transport - - "@apache-mynewt-core/sys/console/stub" - - "@apache-mynewt-core/sys/log/stub" - - "@apache-mynewt-core/sys/stats/stub" - -# No need to build files from this package -pkg.ign_files: - - ".*\\.c" \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/src/porting/nimble/src/os_mbuf.c b/libesp32/NimBLE-Arduino/src/porting/nimble/src/os_mbuf.c index 4ac6bbb7c..4da8b9625 100644 --- a/libesp32/NimBLE-Arduino/src/porting/nimble/src/os_mbuf.c +++ b/libesp32/NimBLE-Arduino/src/porting/nimble/src/os_mbuf.c @@ -385,7 +385,10 @@ os_mbuf_append(struct os_mbuf *om, const void *data, uint16_t len) memcpy(OS_MBUF_DATA(last, uint8_t *) + last->om_len , data, space); last->om_len += space; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-arith" data += space; +#pragma GCC diagnostic pop remainder -= space; } @@ -400,7 +403,10 @@ os_mbuf_append(struct os_mbuf *om, const void *data, uint16_t len) new->om_len = min(omp->omp_databuf_len, remainder); memcpy(OS_MBUF_DATA(new, void *), data, new->om_len); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-arith" data += new->om_len; +#pragma GCC diagnostic pop remainder -= new->om_len; SLIST_NEXT(last, om_next) = new; last = new; @@ -651,7 +657,10 @@ os_mbuf_cmpf(const struct os_mbuf *om, int off, const void *data, int len) chunk_sz = min(om->om_len - om_off, len - data_off); if (chunk_sz > 0) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-arith" rc = memcmp(om->om_data + om_off, data + data_off, chunk_sz); +#pragma GCC diagnostic pop if (rc != 0) { return rc; } diff --git a/libesp32/NimBLE-Arduino/src/services/ipss/ble_svc_ipss.h b/libesp32/NimBLE-Arduino/src/services/ipss/ble_svc_ipss.h new file mode 100644 index 000000000..d894732c9 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/services/ipss/ble_svc_ipss.h @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_SVC_IPSS_ +#define H_BLE_SVC_IPSS_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_SVC_IPSS_UUID16 0x1820 + +/** + * @brief Initialize the IPSS service + */ +void ble_svc_ipss_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/src/ble_sm_priv.h b/libesp32/NimBLE-Arduino/src/src/ble_sm_priv.h index 3f64b7786..bbb4b03ae 100644 --- a/libesp32/NimBLE-Arduino/src/src/ble_sm_priv.h +++ b/libesp32/NimBLE-Arduino/src/src/ble_sm_priv.h @@ -277,10 +277,10 @@ struct ble_sm_result { uint8_t sm_err; struct ble_gap_passkey_params passkey_params; void *state_arg; - unsigned execute:1; - unsigned enc_cb:1; - unsigned persist_keys:1; - unsigned restore:1; + unsigned execute : 1; + unsigned enc_cb : 1; + unsigned bonded : 1; + unsigned restore : 1; }; #if MYNEWT_VAL(BLE_HS_DEBUG) @@ -399,6 +399,7 @@ int ble_sm_slave_initiate(uint16_t conn_handle); int ble_sm_enc_initiate(uint16_t conn_handle, uint8_t key_size, const uint8_t *ltk, uint16_t ediv, uint64_t rand_val, int auth); +int ble_sm_alg_encrypt(uint8_t *key, uint8_t *plaintext, uint8_t *enc_data); int ble_sm_init(void); #define BLE_SM_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ @@ -419,6 +420,9 @@ int ble_sm_init(void); #define ble_sm_init() 0 +#define ble_sm_alg_encrypt(key, plaintext, enc_data) \ + BLE_HS_ENOTSUP + #endif struct ble_l2cap_chan *ble_sm_create_chan(uint16_t handle); From 7fe99a5e04006512e341df0c7bd31ce8d9985933 Mon Sep 17 00:00:00 2001 From: Staars Date: Mon, 6 Jul 2020 20:10:43 +0200 Subject: [PATCH 427/581] minimal API-changes, tweak scan process --- tasmota/xsns_62_MI_ESP32.ino | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 264ffbb52..f8942f138 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -20,6 +20,7 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.0.1 20200706 changed - adapt to new NimBLE-API, tweak scan process 0.9.0.0 20200413 started - initial development by Christian Baars forked - from arendst/tasmota - https://github.com/arendst/Tasmota @@ -232,7 +233,6 @@ class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); if (advertisedDevice->getServiceData().length() == 0) { // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); - MI32Scan->erase(advertisedDevice->getAddress()); return; } uint16_t uuid = advertisedDevice->getServiceDataUUID().getNative()->u16.value; @@ -242,13 +242,14 @@ class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { MI32_ReverseMAC(addr); if(uuid==0xfe95) { MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); + MI32Scan->erase(advertisedDevice->getAddress()); } else if(uuid==0xfdcd) { MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); + MI32Scan->erase(advertisedDevice->getAddress()); } else { // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); - MI32Scan->erase(advertisedDevice->getAddress()); } }; }; @@ -551,7 +552,7 @@ bool MI32connectLYWSD03forNotification(){ } if (pChr){ if(pChr->canNotify()) { - if(pChr->registerForNotify(MI32notifyCB)) { + if(pChr->subscribe(true,false,MI32notifyCB)) { return true; } } From 20d89944e9bcd1c6ac0046a60da8881688b9bdb0 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 7 Jul 2020 12:09:30 +0200 Subject: [PATCH 428/581] Unishox python uncompress fix --- lib/Unishox-1.0-shadinger/python/unishox.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/Unishox-1.0-shadinger/python/unishox.py b/lib/Unishox-1.0-shadinger/python/unishox.py index 1cce14706..087932daa 100644 --- a/lib/Unishox-1.0-shadinger/python/unishox.py +++ b/lib/Unishox-1.0-shadinger/python/unishox.py @@ -344,15 +344,16 @@ class Unishox: #print("getCodeIdx not found = {r}".format(r=1)) return 1, bit_no_p - def getNumFromBits(self, inn, bit_no, count): + def getNumFromBits(self, inn, bit_no_p, count): ret = 0 while count: count -= 1 - if self.ESCAPE_MARKER == inn[bit_no >> 3]: - bit_no += 8 # skip marker - ret += self.getBitVal(inn, bit_no, count) - bit_no += 1 - return ret + if self.ESCAPE_MARKER == inn[bit_no_p >> 3]: + bit_no_p += 8 # skip marker + ret += self.getBitVal(inn, bit_no_p, count) + bit_no_p += 1 + # print("getNumFromBits = {r}".format(r=ret)) + return ret, bit_no_p def readCount(self, inn, bit_no_p, len_): (idx, bit_no_p) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no_p) @@ -372,10 +373,10 @@ class Unishox: till += (1 << bit_len_idx) i += 1 - count = self.getNumFromBits(inn, bit_no_p, bit_len_idx) + base + (count, bit_no_p) = self.getNumFromBits(inn, bit_no_p, bit_len_idx) + count = count + base #print("readCount getNumFromBits = {count} ({bl})".format(count=count,bl=bit_len_idx)) - bit_no_p += bit_len_idx return count, bit_no_p def decodeRepeat(self, inn, len_, out, ol, bit_no): From f2e686ab266ab7bbae68a7d556af1ba88a62bdc0 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Tue, 7 Jul 2020 16:17:43 +0200 Subject: [PATCH 429/581] Fixes some reboots on change the dimmer --- tasmota/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index d5baaed93..cc0fd9bf3 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -118,7 +118,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) - CMND_ETHERNET uint32_t tuyamcu_baudrate : 1; // bit 15 (v8.3.1.6) - SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) uint32_t rotary_uses_rules : 1; // bit 16 (v8.3.1.6) - SetOption98 - Use rules instead of light control - uint32_t spare17 : 1; + uint32_t zerocross_dimmer : 1; // bit 17 (v8.3.1.4) = SetOption99 - Enable zerocross dimmer on PWM DIMMER uint32_t spare18 : 1; uint32_t spare19 : 1; uint32_t spare20 : 1; From debd2b7562ce8a10586c4420fce1586962bc05ef Mon Sep 17 00:00:00 2001 From: stefanbode Date: Tue, 7 Jul 2020 16:19:26 +0200 Subject: [PATCH 430/581] Update xdrv_04_light.ino --- tasmota/xdrv_04_light.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 00cdd96b6..86293c2b2 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -2185,7 +2185,9 @@ void LightSetOutputs(const uint16_t *cur_col_10) { if (!isChannelCT(i)) { // if CT don't use pwm_min and pwm_max cur_col = cur_col > 0 ? changeUIntScale(cur_col, 0, Settings.pwm_range, Light.pwm_min, Light.pwm_max) : 0; // shrink to the range of pwm_min..pwm_max } - analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range - cur_col : cur_col); + if (!Settings.flag4.zerocross_dimmer) { + analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range - cur_col : cur_col); + } } } } From 7c2d9673a1d8aedf4a7fe6739193970d4cff2d30 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Tue, 7 Jul 2020 16:22:55 +0200 Subject: [PATCH 431/581] Update xsns_01_counter.ino --- tasmota/xsns_01_counter.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index c3584f111..54463648f 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -83,11 +83,12 @@ void CounterUpdate(uint8_t index) // restart PWM each second (german 50Hz has to up to 0.01% deviation) // set COUNTERDEBOUNCELOW 1 to catch the raising edge // Zero-HIGH is typical 2ms - if (RtcSettings.pulse_counter[index]%100 == 0 && PinUsed(GPIO_PWM1, index)) { + if (bitRead(Counter.pin_state, index) && Settings.flag4.zerocross_dimmer) { const uint32_t current_cycle = ESP.getCycleCount(); // stop pwm on PIN to start in Sync with rising edge // calculate timeoffset to fire PWM - uint16_t dimm_time= 10000 * (100 - light_state.getDimmer(index)) / Settings.pwm_frequency; + uint16_t cur_col = Light.fade_start_10[0 + Light.pwm_offset]; + uint32_t dimm_time= 1000000 / Settings.pwm_frequency * (1024 - cur_col) / 1024; digitalWrite(Pin(GPIO_PWM1, index), LOW); // 1000µs to ensure not to fire on the next sinus wave if (dimm_time < (1000000 / Settings.pwm_frequency)-1000) { From ce7070b0a5c26354de894e96ce5fa4b2b496deaf Mon Sep 17 00:00:00 2001 From: stefanbode Date: Tue, 7 Jul 2020 16:26:44 +0200 Subject: [PATCH 432/581] Update xsns_01_counter.ino --- tasmota/xsns_01_counter.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index 54463648f..fb61a05d6 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -81,9 +81,8 @@ void CounterUpdate(uint8_t index) if bitRead(Counter.pin_state, index) { // PWMfrequency 100 // restart PWM each second (german 50Hz has to up to 0.01% deviation) - // set COUNTERDEBOUNCELOW 1 to catch the raising edge // Zero-HIGH is typical 2ms - if (bitRead(Counter.pin_state, index) && Settings.flag4.zerocross_dimmer) { + if (RtcSettings.pulse_counter[index]%100 == 0 && PinUsed(GPIO_PWM1, index) && Settings.flag4.zerocross_dimmer) { const uint32_t current_cycle = ESP.getCycleCount(); // stop pwm on PIN to start in Sync with rising edge // calculate timeoffset to fire PWM From 90f29695bbba0aa957fe192b226cf569ac03a5c5 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Tue, 7 Jul 2020 16:31:35 +0200 Subject: [PATCH 433/581] Update xsns_01_counter.ino --- tasmota/xsns_01_counter.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index fb61a05d6..ae03ef324 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -166,7 +166,7 @@ void CounterInit(void) if (PinUsed(GPIO_CNTR1, i)) { Counter.any_counter = true; pinMode(Pin(GPIO_CNTR1, i), bitRead(Counter.no_pullup, i) ? INPUT : INPUT_PULLUP); - if ((0 == Settings.pulse_counter_debounce_low) && (0 == Settings.pulse_counter_debounce_high)) { + if ((0 == Settings.pulse_counter_debounce_low) && (0 == Settings.pulse_counter_debounce_high) && !Settings.flag4.zerocross_dimmer) { Counter.pin_state = 0; attachInterrupt(Pin(GPIO_CNTR1, i), counter_callbacks[i], FALLING); } else { From 9ac3cce61daf3dae8fc606ebc93ebc5d9d953b26 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Thu, 9 Jul 2020 12:31:37 +0200 Subject: [PATCH 434/581] Update python unishox tool from lib --- tools/unishox/unishox.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tools/unishox/unishox.py b/tools/unishox/unishox.py index 1cce14706..087932daa 100644 --- a/tools/unishox/unishox.py +++ b/tools/unishox/unishox.py @@ -344,15 +344,16 @@ class Unishox: #print("getCodeIdx not found = {r}".format(r=1)) return 1, bit_no_p - def getNumFromBits(self, inn, bit_no, count): + def getNumFromBits(self, inn, bit_no_p, count): ret = 0 while count: count -= 1 - if self.ESCAPE_MARKER == inn[bit_no >> 3]: - bit_no += 8 # skip marker - ret += self.getBitVal(inn, bit_no, count) - bit_no += 1 - return ret + if self.ESCAPE_MARKER == inn[bit_no_p >> 3]: + bit_no_p += 8 # skip marker + ret += self.getBitVal(inn, bit_no_p, count) + bit_no_p += 1 + # print("getNumFromBits = {r}".format(r=ret)) + return ret, bit_no_p def readCount(self, inn, bit_no_p, len_): (idx, bit_no_p) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no_p) @@ -372,10 +373,10 @@ class Unishox: till += (1 << bit_len_idx) i += 1 - count = self.getNumFromBits(inn, bit_no_p, bit_len_idx) + base + (count, bit_no_p) = self.getNumFromBits(inn, bit_no_p, bit_len_idx) + count = count + base #print("readCount getNumFromBits = {count} ({bl})".format(count=count,bl=bit_len_idx)) - bit_no_p += bit_len_idx return count, bit_no_p def decodeRepeat(self, inn, len_, out, ol, bit_no): From 387800adc57d4fc1b4ec277b93362db17260f219 Mon Sep 17 00:00:00 2001 From: halfbakery <54818270+halfbakery@users.noreply.github.com> Date: Thu, 9 Jul 2020 19:39:11 +0200 Subject: [PATCH 435/581] Update RELEASENOTES.md More devices supported without additional scripting --- RELEASENOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5790242d2..038f20687 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -94,3 +94,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add compile time interlock parameters (#8759) - Add compile time user template (#8766) - Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) +- Add support for switches/relays using an AC detection circuitry e.g. MOES MS-104B / BlitzWolf SS5 / etc. (#8606) From 881cd5e580c1f239aa1403f2d9fe86ee722cda2e Mon Sep 17 00:00:00 2001 From: d0m1n1qu3 Date: Thu, 9 Jul 2020 20:47:01 +0200 Subject: [PATCH 436/581] repair float int problems for MI Flora moisture and fertility --- tasmota/xsns_62_MI_ESP32.ino | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index f8942f138..1128c6ec3 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -1189,9 +1189,9 @@ bool MI32Cmd(void) { const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 {m}%u%s / %u{e}"; const char HTTP_MI32_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; -const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u%%{e}"; +const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; const char HTTP_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{m}%s V{e}"; -const char HTTP_MI32_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%uus/cm{e}"; +const char HTTP_MI32_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%u us/cm{e}"; const char HTTP_MI32_HL[] PROGMEM = "{s}
    {m}
    {e}"; void MI32Show(bool json) @@ -1222,10 +1222,10 @@ void MI32Show(bool json) ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); } if (!isnan(MIBLEsensors[i].moisture)) { - ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%d"), MIBLEsensors[i].moisture); + ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%f"), MIBLEsensors[i].moisture); } if (!isnan(MIBLEsensors[i].fertility)) { - ResponseAppend_P(PSTR(",\"Fertility\":%d"), MIBLEsensors[i].fertility); + ResponseAppend_P(PSTR(",\"Fertility\":%f"), MIBLEsensors[i].fertility); } } if (MIBLEsensors[i].type > FLORA){ @@ -1273,10 +1273,10 @@ void MI32Show(bool json) WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); } if (!isnan(MIBLEsensors[i].moisture)) { - WSContentSend_PD(HTTP_SNS_MOISTURE, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].moisture); + WSContentSend_PD(HTTP_SNS_MOISTURE, kMI32SlaveType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].moisture)); } if (!isnan(MIBLEsensors[i].fertility)) { - WSContentSend_PD(HTTP_MI32_FLORA_DATA, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].fertility); + WSContentSend_PD(HTTP_MI32_FLORA_DATA, kMI32SlaveType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].fertility)); } } if (MIBLEsensors[i].type>FLORA) { // everything "above" Flora From 481d26ce5f52a831408e674652cd0d571372837f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 9 Jul 2020 20:58:17 +0200 Subject: [PATCH 437/581] Use core 2.7.2 --- platformio.ini | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index d03de291d..7a0a051b4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -110,8 +110,7 @@ build_flags = ${esp_defaults.build_flags} ; No exception code in firmware -fno-exceptions -lstdc++ - ; the following removes the 4-bytes alignment for PSTR(), waiting for a cleaner flag from Arduino Core - -DPSTR\(s\)=\(__extension__\(\{static\ const\ char\ __c\[\]\ __attribute__\(\(__aligned__\(1\)\)\)\ __attribute__\(\(section\(\ \"\\\\\".irom0.pstr.\"\ __FILE__\ \".\"\ __STRINGIZE\(__LINE__\)\ \".\"\ \ __STRINGIZE\(__COUNTER__\)\ \"\\\\\"\,\ \\\\\"aSM\\\\\"\,\ \@progbits\,\ 1\ \#\"\)\)\)\ =\ \(s\)\;\ \&__c\[0\]\;\}\)\) + ; the following removes the 4-bytes alignment for PSTR() -DPSTR_ALIGN=1 ; restrict to minimal mime-types -DMIMETYPE_MINIMAL @@ -123,8 +122,8 @@ build_flags = -DUSE_IR_REMOTE_FULL [core] -; *** Esp8266 Arduino core 2.7.1 -platform = espressif8266@2.5.3 +; *** Esp8266 Arduino core 2.7.2 +platform = espressif8266@2.6.0 platform_packages = build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From 7f2ed318114a7f20c582a38f1fb7d978ffb414a8 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 9 Jul 2020 21:00:20 +0200 Subject: [PATCH 438/581] Use core 2.7.2 --- platformio_override_sample.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 9b43cd6a3..e8aedc5d7 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -87,7 +87,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage -platform = espressif8266@2.5.3 +platform = espressif8266@2.6.0 platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.8.0-tasmota/esp8266-2.8.0.zip build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} @@ -123,7 +123,7 @@ build_flags = ${esp82xx_defaults.build_flags} [core_stage] ; *** Esp8266 core for Arduino version latest development version -platform = espressif8266@2.5.3 +platform = espressif8266@2.6.0 platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From 19aa95f7fb6958ee78443e58f65da0a3bb3b252d Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 9 Jul 2020 21:01:01 +0200 Subject: [PATCH 439/581] Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 20d80249a..597c69eff 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,7 +6,7 @@ - [ ] The pull request is done against the latest dev branch - [ ] Only relevant files were touched - [ ] Only one feature/fix was added per PR. - - [ ] The code change is tested and works on core ESP8266 V.2.7.1 + - [ ] The code change is tested and works on core ESP8266 V.2.7.2 - [ ] The code change is tested and works on core ESP32 V.1.12.2 - [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). From 151686d2e1e936d264556d4fc85e1e2f9703c460 Mon Sep 17 00:00:00 2001 From: d0m1n1qu3 Date: Fri, 10 Jul 2020 13:16:01 +0200 Subject: [PATCH 440/581] read firmware verion for FLORA devices the FLORA sensors send the firmware version number while they send the battery info so we parse it and send it via mqtt (json) and also present it in the webinterface --- tasmota/xsns_62_MI_ESP32.ino | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 1128c6ec3..a9f8a0979 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -141,6 +141,7 @@ struct mi_sensor_t{ uint8_t bat; // many values seem to be hard-coded garbage (LYWSD0x, GCD1) uint16_t volt; // LYWSD03MMC }; + char firmware[6]; // actually only for FLORA but hopefully we can add for more devices }; std::vector MIBLEsensors; @@ -773,6 +774,8 @@ void MI32batteryFLORA(){ if(pChr->canRead()) { const char *buf = pChr->readValue().c_str(); MI32readBat((char*)buf); + //we also can read the firmware from response no extra request needed + MI32readFirmwareFLORA((char*)buf); } } MI32.mode.readingDone = 1; @@ -1012,6 +1015,23 @@ bool MI32readBat(char *_buf){ return false; } +bool MI32readFirmwareFLORA(char *_buf){ + DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_MI32,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); + if(_buf[0] != 0){ + char _firmware[5]; // FLORA send 5 byte for firmware version + strncpy(_firmware, _buf+2, 5); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Firmware: %s"),D_CMND_MI32,_firmware); + + uint32_t _slot = MI32.state.sensor; + DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); + + memcpy(MIBLEsensors[_slot].firmware, _firmware, 5); + MIBLEsensors[_slot].firmware[5] = '\0'; + return true; + } + return false; +} + /** * @brief Main loop of the driver, "high level"-loop * @@ -1190,6 +1210,7 @@ bool MI32Cmd(void) { const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 {m}%u%s / %u{e}"; const char HTTP_MI32_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; +const char HTTP_FIRMWARE[] PROGMEM = "{s}%s" " Firmware" "{m}%s{e}"; const char HTTP_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{m}%s V{e}"; const char HTTP_MI32_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%u us/cm{e}"; const char HTTP_MI32_HL[] PROGMEM = "{s}
    {m}
    {e}"; @@ -1241,6 +1262,9 @@ void MI32Show(bool json) dtostrfd((MIBLEsensors[i].volt)/1000.0f, Settings.flag2.voltage_resolution, voltage); ResponseAppend_P(PSTR(",\"" D_VOLTAGE "\":%s"), voltage); } + if (MIBLEsensors[i].type == FLORA) { //actually we can only read FLORA + ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); + } } ResponseAppend_P(PSTR("}")); } @@ -1292,6 +1316,9 @@ void MI32Show(bool json) dtostrfd((MIBLEsensors[i].volt)/1000.0f, Settings.flag2.voltage_resolution, voltage); WSContentSend_PD(HTTP_VOLTAGE, kMI32SlaveType[MIBLEsensors[i].type-1], voltage); } + if (MIBLEsensors[i].type == FLORA) { + WSContentSend_PD(HTTP_FIRMWARE, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].firmware); + } } } _counter++; From 115ed5642438b0f79aa2f2248764553ed8fccb99 Mon Sep 17 00:00:00 2001 From: d0m1n1qu3 Date: Fri, 10 Jul 2020 17:00:45 +0200 Subject: [PATCH 441/581] send firmware version only via mqtt not shown on GUI anymore --- tasmota/xsns_62_MI_ESP32.ino | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index a9f8a0979..9fa6a71d8 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -1210,7 +1210,6 @@ bool MI32Cmd(void) { const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 {m}%u%s / %u{e}"; const char HTTP_MI32_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; -const char HTTP_FIRMWARE[] PROGMEM = "{s}%s" " Firmware" "{m}%s{e}"; const char HTTP_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{m}%s V{e}"; const char HTTP_MI32_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%u us/cm{e}"; const char HTTP_MI32_HL[] PROGMEM = "{s}
    {m}
    {e}"; @@ -1316,9 +1315,6 @@ void MI32Show(bool json) dtostrfd((MIBLEsensors[i].volt)/1000.0f, Settings.flag2.voltage_resolution, voltage); WSContentSend_PD(HTTP_VOLTAGE, kMI32SlaveType[MIBLEsensors[i].type-1], voltage); } - if (MIBLEsensors[i].type == FLORA) { - WSContentSend_PD(HTTP_FIRMWARE, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].firmware); - } } } _counter++; From 55653f0c3346acac9f6e75e82dfbf1990b1fd56c Mon Sep 17 00:00:00 2001 From: d0m1n1qu3 Date: Fri, 10 Jul 2020 18:03:07 +0200 Subject: [PATCH 442/581] read the rssi from the sensor sometimes it is hard to find out why a sensor sends no data with the rssi you got a value of the BLE signal strenght and can optimize the location of the sensor or the ESP32 if the rssi got worse over time the battery could be the problem rssi monitoring is a must have feature for radio signals :-) --- tasmota/xsns_62_MI_ESP32.ino | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 9fa6a71d8..9cea6b513 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -125,6 +125,7 @@ struct mi_sensor_t{ uint8_t type; //Flora = 1; MI-HT_V1=2; LYWSD02=3; LYWSD03=4; CGG1=5; CGD1=6 uint8_t serial[6]; uint8_t showedUp; + int rssi; float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx union { struct { @@ -242,11 +243,11 @@ class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { memcpy(addr,advertisedDevice->getAddress().getNative(),6); MI32_ReverseMAC(addr); if(uuid==0xfe95) { - MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); + MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr, advertisedDevice->getRSSI()); MI32Scan->erase(advertisedDevice->getAddress()); } else if(uuid==0xfdcd) { - MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); + MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr, advertisedDevice->getRSSI()); MI32Scan->erase(advertisedDevice->getAddress()); } else { @@ -925,12 +926,13 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ } } -void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6]){ // no MiBeacon +void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi){ // no MiBeacon uint8_t _addr[6]; memcpy(_addr,addr,6); uint32_t _slot = MIBLEgetSensorSlot(_addr, 0x0576); // This must be hard-coded, no object-id in Cleargrass-packet DEBUG_SENSOR_LOG(PSTR("MI32: Sensor slot: %u"), _slot); if(_slot==0xff) return; + MIBLEsensors[_slot].rssi=rssi; cg_packet_t _packet; memcpy((char*)&_packet,_buf,sizeof(_packet)); switch (_packet.mode){ @@ -959,7 +961,7 @@ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6]){ // no M } } -void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6]) { +void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int rssi) { if(bufsize<10) { return; } @@ -969,7 +971,10 @@ void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6]) { uint8_t _addr[6]; memcpy(_addr,addr,6); uint16_t _slot = MIBLEgetSensorSlot(_addr, _type); - if(_slot!=0xff) MI32parseMiBeacon(_pos,_slot); + if(_slot!=0xff) { + MIBLEsensors[_slot].rssi=rssi; + MI32parseMiBeacon(_pos,_slot); + } } /***********************************************************************\ @@ -1209,6 +1214,7 @@ bool MI32Cmd(void) { const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 {m}%u%s / %u{e}"; const char HTTP_MI32_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; +const char HTTP_RSSI[] PROGMEM = "{s}%s" " RSSI" "{m}%d dBm{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; const char HTTP_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{m}%s V{e}"; const char HTTP_MI32_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%u us/cm{e}"; @@ -1229,14 +1235,13 @@ void MI32Show(bool json) kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].serial[3], MIBLEsensors[i].serial[4], MIBLEsensors[i].serial[5]); + ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].rssi); // all sensors have rssi + if (MIBLEsensors[i].type == FLORA) { if (!isnan(MIBLEsensors[i].temp)) { char temperature[FLOATSZ]; // all sensors have temperature dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); - ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), temperature); - } else { - ResponseAppend_P(PSTR("}")); - continue; + ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%s"), temperature); } if (MIBLEsensors[i].lux!=0x0ffffff) { // this is the error code -> no lux ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); @@ -1250,6 +1255,7 @@ void MI32Show(bool json) } if (MIBLEsensors[i].type > FLORA){ if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { + ResponseAppend_P(PSTR(",")); ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum); } } @@ -1286,6 +1292,7 @@ void MI32Show(bool json) for (i; i Date: Fri, 10 Jul 2020 20:15:12 +0200 Subject: [PATCH 443/581] Zigbee EZSP better support for groups --- tasmota/i18n.h | 1 + tasmota/xdrv_23_zigbee_0_constants.ino | 4 ++- tasmota/xdrv_23_zigbee_7_statemachine.ino | 3 ++ tasmota/xdrv_23_zigbee_8_parsers.ino | 6 ++++ tasmota/xdrv_23_zigbee_A_impl.ino | 34 +++++++++++++++++++++-- 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 194ff4bc6..eeedbfc57 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -509,6 +509,7 @@ #define D_CMND_ZIGBEEZNPRECEIVE "ZNPReceive" // only for debug #define D_CMND_ZIGBEE_EZSP_RECEIVE "EZSPReceive" // only for debug #define D_CMND_ZIGBEE_EZSP_RECEIVE_RAW "EZSPReceiveRaw" // only for debug +#define D_CMND_ZIGBEE_EZSP_LISTEN "Listen" // only for EZSP #define D_CMND_ZIGBEEZNPSEND "ZNPSend" #define D_CMND_ZIGBEE_EZSP_SEND "EZSPSend" #define D_CMND_ZIGBEE_EZSP_SEND_RAW "EZSPSendRaw" diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index da2dd5119..ea087e70f 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -427,7 +427,9 @@ enum EZSP_EmberOutgoingMessageType { EMBER_OUTGOING_VIA_ADDRESS_TABLE = 0x01, EMBER_OUTGOING_VIA_BINDING = 0x02, EMBER_OUTGOING_MULTICAST = 0x03, - EMBER_OUTGOING_BROADCAST = 0x04 + EMBER_OUTGOING_MULTICAST_WITH_ALIAS = 0x04, + EMBER_OUTGOING_BROADCAST_WITH_ALIAS = 0x05, + EMBER_OUTGOING_BROADCAST = 0x06 }; // inspired from https://github.com/zigpy/zigpy/blob/dev/zigpy/zdo/types.py diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index bc7fccf06..7b0c1adc6 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -717,6 +717,8 @@ ZBM(ZBS_SET_POLICY_02, EZSP_setPolicy, 0x00 /*high*/, EZSP_UNICAST_REPLIES_PO EZSP_HOST_WILL_NOT_SUPPLY_REPLY) // 55000220 ZBM(ZBS_SET_POLICY_03, EZSP_setPolicy, 0x00 /*high*/, EZSP_POLL_HANDLER_POLICY, EZSP_POLL_HANDLER_IGNORE) // 55000330 +ZBM(ZBS_SET_POLICY_04, EZSP_setPolicy, 0x00 /*high*/, EZSP_MESSAGE_CONTENTS_IN_CALLBACK_POLICY, + EZSP_MESSAGE_TAG_AND_CONTENTS_IN_CALLBACK) // 55000441 ZBM(ZBS_SET_POLICY_05, EZSP_setPolicy, 0x00 /*high*/, EZSP_TC_KEY_REQUEST_POLICY, EZSP_ALLOW_TC_KEY_REQUESTS_AND_SEND_CURRENT_KEY) // 55000551 ZBM(ZBS_SET_POLICY_06, EZSP_setPolicy, 0x00 /*high*/, EZSP_APP_KEY_REQUEST_POLICY, @@ -871,6 +873,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_SEND(ZBS_SET_POLICY_00) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) ZI_SEND(ZBS_SET_POLICY_02) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) ZI_SEND(ZBS_SET_POLICY_03) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + // ZI_SEND(ZBS_SET_POLICY_04) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) ZI_SEND(ZBS_SET_POLICY_05) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) ZI_SEND(ZBS_SET_POLICY_06) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 14e62b603..a94a07aeb 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -935,6 +935,12 @@ void Z_IncomingMessage(ZCLFrame &zcl_received) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZCL_RAW_RECEIVED ": {\"0x%04X\":%s}"), srcaddr, msg.c_str()); } + // discard the message if it was sent by us (broadcast or group loopback) + if (srcaddr == localShortAddr) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "loopback message, ignoring")); + return; // abort the rest of message management + } + zcl_received.postProcessAttributes(srcaddr, json); // Add Endpoint json[F(D_CMND_ZIGBEE_ENDPOINT)] = srcendpoint; diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 7eeae7c15..e46d847eb 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -26,7 +26,7 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEEZNPRECEIVE "|" #endif // USE_ZIGBEE_ZNP #ifdef USE_ZIGBEE_EZSP - D_CMND_ZIGBEE_EZSP_SEND "|" D_CMND_ZIGBEE_EZSP_RECEIVE "|" + D_CMND_ZIGBEE_EZSP_SEND "|" D_CMND_ZIGBEE_EZSP_RECEIVE "|" D_CMND_ZIGBEE_EZSP_LISTEN "|" #endif // USE_ZIGBEE_EZSP D_CMND_ZIGBEE_PERMITJOIN "|" D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" D_CMND_ZIGBEE_PROBE "|" @@ -41,7 +41,7 @@ void (* const ZigbeeCommand[])(void) PROGMEM = { &CmndZbZNPSend, &CmndZbZNPReceive, #endif // USE_ZIGBEE_ZNP #ifdef USE_ZIGBEE_EZSP - &CmndZbEZSPSend, &CmndZbEZSPReceive, + &CmndZbEZSPSend, &CmndZbEZSPReceive, &CmndZbEZSPListen, #endif // USE_ZIGBEE_EZSP &CmndZbPermitJoin, &CmndZbStatus, &CmndZbReset, &CmndZbSend, &CmndZbProbe, @@ -1024,6 +1024,36 @@ void CmndZbPermitJoin(void) { ResponseCmndDone(); } +#ifdef USE_ZIGBEE_EZSP +// +// `ZbListen`: add a multicast group to listen to +// Overcomes a current limitation that EZSP only shows messages from multicast groups it listens too +// +// Ex: `ZbListen 99`, `ZbListen2 100` +void CmndZbEZSPListen(void) { + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + + int32_t index = XdrvMailbox.index - 1; // 0 based + int32_t group = XdrvMailbox.payload; + + if (group <= 0) { + group = 0; + } else if (group > 0xFFFF) { + group = 0xFFFF; + } + + SBuffer buf(8); + buf.add16(EZSP_setMulticastTableEntry); + buf.add8(index); + buf.add16(group); // group + buf.add8(0x01); // endpoint + buf.add8(0x00); // network index + ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); + + ResponseCmndDone(); +} +#endif // USE_ZIGBEE_EZSP + // // Command `ZbStatus` // From 5d7ff375165a74fd4478f40f1a6c0a4ef583e0d5 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 11 Jul 2020 12:29:51 +0200 Subject: [PATCH 444/581] Core stage is now built with GCC10.1 toolchain --- platformio_override_sample.ini | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index e8aedc5d7..7afadf502 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -122,9 +122,9 @@ build_flags = ${esp82xx_defaults.build_flags} ; -lstdc++-exc [core_stage] -; *** Esp8266 core for Arduino version latest development version -platform = espressif8266@2.6.0 -platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git +; *** Esp8266 core version. Tasmota stage or Arduino stage version. Built with GCC 10.1 toolchain +platform = https://github.com/Jason2866/platform-espressif8266/releases/download/2.9.0/platform-espressif8266-2.9.0.tar.gz +platform_packages = ;framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} @@ -203,3 +203,4 @@ lib_extra_dirs = lib_ignore = cc1101 + From 5a2e7c5aa72a001c18f556d202e0a7c44884041a Mon Sep 17 00:00:00 2001 From: d0m1n1qu3 Date: Sat, 11 Jul 2020 22:09:26 +0200 Subject: [PATCH 445/581] add some checks is rssi is available and init variables at object creation --- tasmota/xsns_62_MI_ESP32.ino | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 9cea6b513..8441b8c86 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -242,12 +242,17 @@ class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { uint8_t addr[6]; memcpy(addr,advertisedDevice->getAddress().getNative(),6); MI32_ReverseMAC(addr); + int rssi = 0xffff; + if(advertisedDevice->haveRSSI()) { + rssi = advertisedDevice->getRSSI(); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("RSSI: %d"),rssi); // actually i never got a 0xffff if(uuid==0xfe95) { - MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr, advertisedDevice->getRSSI()); + MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr, rssi); MI32Scan->erase(advertisedDevice->getAddress()); } else if(uuid==0xfdcd) { - MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr, advertisedDevice->getRSSI()); + MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr, rssi); MI32Scan->erase(advertisedDevice->getAddress()); } else { @@ -341,6 +346,8 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint16_t _type){ _newSensor.showedUp = 255; _newSensor.temp =NAN; _newSensor.bat=0x00; + _newSensor.rssi=0xffff; + _newSensor.firmware[0]='\0'; switch (_type) { case 1: @@ -1235,8 +1242,11 @@ void MI32Show(bool json) kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].serial[3], MIBLEsensors[i].serial[4], MIBLEsensors[i].serial[5]); - ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].rssi); // all sensors have rssi - + if (MIBLEsensors[i].rssi!=0xffff) { // this is the error code -> no valid value + ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].rssi); // all sensors have rssi + } else { + ResponseAppend_P(PSTR("\"RSSI\":null")); // to know that it is sometimes out of range + } if (MIBLEsensors[i].type == FLORA) { if (!isnan(MIBLEsensors[i].temp)) { char temperature[FLOATSZ]; // all sensors have temperature @@ -1292,7 +1302,9 @@ void MI32Show(bool json) for (i; i no valid value + WSContentSend_PD(HTTP_RSSI, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].rssi); + } if (MIBLEsensors[i].type==FLORA) { if (!isnan(MIBLEsensors[i].temp)) { char temperature[FLOATSZ]; From 833f47fd1518c73b79d9d720bfc87d970cc2011f Mon Sep 17 00:00:00 2001 From: Khoa Ton Date: Sat, 11 Jul 2020 23:16:29 -0700 Subject: [PATCH 446/581] Support up to 8 I2C Seven Segment Displays --- tasmota/my_user_config.h | 2 +- tasmota/xdsp_11_sevenseg.ino | 95 ++++++++++++++++++++++++------------ 2 files changed, 65 insertions(+), 32 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 0ab09d224..3447295a0 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -559,7 +559,7 @@ #define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module #define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module #define USE_DISPLAY_SEVENSEG // [DisplayModel 11] [I2cDriver47] Enable sevenseg display (I2C 0x70-0x77) (<+11k code) - #define SEVENSEG_ADDRESS1 0x70 // [DisplayAddress1] I2C address of first sevenseg matrix module + // #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays // #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D) #endif // USE_I2C diff --git a/tasmota/xdsp_11_sevenseg.ino b/tasmota/xdsp_11_sevenseg.ino index 20193e54e..0978cc466 100644 --- a/tasmota/xdsp_11_sevenseg.ino +++ b/tasmota/xdsp_11_sevenseg.ino @@ -28,20 +28,24 @@ #include #include // Seven segment LED -Adafruit_7segment sevenseg = Adafruit_7segment(); - +Adafruit_7segment *sevenseg[8]; +uint8_t sevensegs = 0; uint8_t sevenseg_state = 0; /*********************************************************************************************/ void SevensegWrite(void) { - sevenseg.writeDisplay(); + for (uint32_t i = 0; i < sevensegs; i++) { + sevenseg[i]->writeDisplay(); + } } void SevensegClear(void) { - sevenseg.clear(); + for (uint32_t i = 0; i < sevensegs; i++) { + sevenseg[i]->clear(); + } SevensegWrite(); } @@ -50,8 +54,10 @@ void SevensegClear(void) void SevensegInitMode(void) { - sevenseg.setBrightness(Settings.display_dimmer); - sevenseg.blinkRate(0); // 0 - 3 + for (uint32_t i = 0; i < sevensegs; i++) { + sevenseg[i]->setBrightness(Settings.display_dimmer); + sevenseg[i]->blinkRate(0); + } SevensegClear(); } @@ -69,17 +75,25 @@ void SevensegInit(uint8_t mode) void SevensegInitDriver(void) { if (!Settings.display_model) { - if (I2cSetDevice(SEVENSEG_ADDRESS1)) { + if (I2cSetDevice(Settings.display_address[0])) { Settings.display_model = XDSP_11; } } if (XDSP_11 == Settings.display_model) { sevenseg_state = 1; - sevenseg.begin(SEVENSEG_ADDRESS1); - + for (sevensegs = 0; sevensegs < 8; sevensegs++) { + if (Settings.display_address[sevensegs]) { + I2cSetActiveFound(Settings.display_address[sevensegs], "SevenSeg"); + sevenseg[sevensegs] = new Adafruit_7segment(); + sevenseg[sevensegs]->begin(Settings.display_address[sevensegs]); + } else { + break; + } + } + Settings.display_width = 4; - Settings.display_height = 1; + Settings.display_height = sevensegs; SevensegInitMode(); } @@ -101,15 +115,34 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin boolean hex=false; boolean done=false; boolean s=false; + uint8_t unit=y; + if ((unit>=sevensegs) || (unit<0)) { + unit=0; + } + for (int i=0; (str[i]!='\0') && (!done); i++) { - // [prefix(es) chars]digits + // [optional prefix(es) chars]digits // Some combinations won't make sense. // Reference: https://learn.adafruit.com/adafruit-led-backpack/1-2-inch-7-segment-backpack-arduino-wiring-and-setup + // + // Prefixes: + // x upcoming number decimal integer displayed as hex + // : turn on middle colon + // ^ turh on top left dot + // v turn on bottom left dot + // . turn on AM/PM/Degree dot + // s upcoming number is seconds, print as HH:MM or MM:SS + // z clear this display + // // Some sample valid combinations: - // 787 -> 787 - // x47 -> 2F - // st:241 -> 04:01 - // sT241 -> 4 01 + // 787 -> 787 + // x47 -> 2F + // s:241 -> 04:01 + // s241 -> 4 01 + // s1241 -> 20:41 + // z -> + // x88 -> 58 + switch (str[i]) { case 'x': // print given dec value as hex hex = true; @@ -126,12 +159,6 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin case '.': // print ampm dots |= 0x10; break; - case 'T': // print as time 12 format - t = true; - break; - case 't': // print as time 24 format - T = true; - break; case 's': // duration in seconds s = true; break; @@ -149,6 +176,12 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin number = atoi(str+i); done = true; break; + case 'z': // Clear this display + hasnumber=false; + dots=0; + s=false; + sevenseg[unit]->clear(); + break; default: // unknown format, ignore break; } @@ -171,17 +204,17 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin if (hasnumber) { if (hex) { - sevenseg.print(number, HEX); + sevenseg[unit]->print(number, HEX); } else { - sevenseg.print(number, DEC); + sevenseg[unit]->print(number, DEC); } } if (dots) { - sevenseg.writeDigitRaw(2, dots); + sevenseg[unit]->writeDigitRaw(2, dots); } - sevenseg.writeDisplay(); + sevenseg[unit]->writeDisplay(); } /*********************************************************************************************/ @@ -210,7 +243,7 @@ void SevensegTime(boolean time_24) // Now print the time value to the display. - sevenseg.print(displayValue, DEC); + sevenseg[0]->print(displayValue, DEC); // Add zero padding when in 24 hour mode and it's midnight. // In this case the print function above won't have leading 0's @@ -218,15 +251,15 @@ void SevensegTime(boolean time_24) if (time_24) { if (hours == 0) { // Pad hour 0. - sevenseg.writeDigitNum(1, 0); + sevenseg[0]->writeDigitNum(1, 0); // Also pad when the 10's minute is 0 and should be padded. if (minutes < 10) { - sevenseg.writeDigitNum(3, 0); + sevenseg[0]->writeDigitNum(3, 0); } } if (hours < 10) { // Always have 4 digits time - sevenseg.writeDigitNum(0, 0); + sevenseg[0]->writeDigitNum(0, 0); } } else { // Identify and display AM/PM @@ -235,8 +268,8 @@ void SevensegTime(boolean time_24) } } - sevenseg.writeDigitRaw(2, dots |= ((second%2) << 1)); - sevenseg.writeDisplay(); + sevenseg[0]->writeDigitRaw(2, dots |= ((second%2) << 1)); + sevenseg[0]->writeDisplay(); } void SevensegRefresh(void) // Every second From 7de43e6233f17347ed74b966719bd8b97cca2ef1 Mon Sep 17 00:00:00 2001 From: Khoa Ton Date: Sat, 11 Jul 2020 23:33:25 -0700 Subject: [PATCH 447/581] Added comments on multiple sevenseg display layout --- tasmota/my_user_config.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 3447295a0..3d9e904ca 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -559,6 +559,10 @@ #define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module #define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module #define USE_DISPLAY_SEVENSEG // [DisplayModel 11] [I2cDriver47] Enable sevenseg display (I2C 0x70-0x77) (<+11k code) + // Multiple sevenseg displays are logically arranged vertically with MTX_ADDRESS1 at y=0, + // MTX_ADDRESS2 at y=1, up to MTX_ADDRESS8 at y=7 + // Command: DisplayText [yn]8888 + // will display 8888 at sevenseg display at I2C address MTX_ADDRESS(n-1) // #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays // #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D) #endif // USE_I2C From 3462c7f31b76ffb341b16dbb2d10171d3cdc1d44 Mon Sep 17 00:00:00 2001 From: Khoa Ton Date: Sun, 12 Jul 2020 00:02:39 -0700 Subject: [PATCH 448/581] Fix mispelling in comment --- tasmota/xdsp_11_sevenseg.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdsp_11_sevenseg.ino b/tasmota/xdsp_11_sevenseg.ino index 0978cc466..d01637204 100644 --- a/tasmota/xdsp_11_sevenseg.ino +++ b/tasmota/xdsp_11_sevenseg.ino @@ -128,7 +128,7 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin // Prefixes: // x upcoming number decimal integer displayed as hex // : turn on middle colon - // ^ turh on top left dot + // ^ turn on top left dot // v turn on bottom left dot // . turn on AM/PM/Degree dot // s upcoming number is seconds, print as HH:MM or MM:SS From e3fd1b7850974ef9d28e10420410be0249fd1eee Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 12 Jul 2020 15:24:42 +0200 Subject: [PATCH 449/581] Fix DS18S20 temp calculation Fix DS18S20 temp calculation (#8777) --- tasmota/xsns_05_ds18x20.ino | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tasmota/xsns_05_ds18x20.ino b/tasmota/xsns_05_ds18x20.ino index a762014c7..361847932 100644 --- a/tasmota/xsns_05_ds18x20.ino +++ b/tasmota/xsns_05_ds18x20.ino @@ -375,12 +375,19 @@ bool Ds18x20Read(uint8_t sensor) if (OneWireCrc8(data)) { switch(ds18x20_sensor[index].address[0]) { case DS18S20_CHIPID: { +/* if (data[1] > 0x80) { data[0] = (~data[0]) +1; sign = -1; // App-Note fix possible sign error } float temp9 = (float)(data[0] >> 1) * sign; ds18x20_sensor[index].temperature = ConvertTemp((temp9 - 0.25) + ((16.0 - data[6]) / 16.0)); + + Replaced by below based on issue #8777 +*/ + int16_t tempS = (((data[1] << 8) | (data[0] & 0xFE)) << 3) | ((0x10 - data[6]) & 0x0F); + ds18x20_sensor[index].temperature = ConvertTemp(tempS * 0.0625 - 0.250); + ds18x20_sensor[index].valid = SENSOR_MAX_MISS; return true; } From 202326c5f3fd6cc6158c94f54da93d708aedfc9d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 12 Jul 2020 15:34:02 +0200 Subject: [PATCH 450/581] Update changelog --- RELEASENOTES.md | 8 ++++---- tasmota/CHANGELOG.md | 13 +++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 038f20687..fdafb0535 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -21,7 +21,7 @@ While fallback or downgrading is common practice it was never supported due to S ## Supported Core versions -This release will be supported from ESP8266/Arduino library Core version **2.7.1** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. +This release will be supported from ESP8266/Arduino library Core version **2.7.2** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. Although it might still compile on previous Core versions all support will be removed in the near future. @@ -35,7 +35,7 @@ For initial configuration this release supports Webserver based **WifiManager** ## Provided Binary Downloads -The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.1**. +The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.2**. - **tasmota.bin** = The Tasmota version with most drivers. **RECOMMENDED RELEASE BINARY** - **tasmota-BG.bin** to **tasmota-TW.bin** = The Tasmota version in different languages. @@ -52,7 +52,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.4.0 George +### Version 8.3.1.6 - Change IRremoteESP8266 library updated to v2.7.7 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) @@ -94,4 +94,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add compile time interlock parameters (#8759) - Add compile time user template (#8766) - Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) -- Add support for switches/relays using an AC detection circuitry e.g. MOES MS-104B / BlitzWolf SS5 / etc. (#8606) +- Add support for switches/relays using an AC detection circuitry e.g. MOES MS-104B or BlitzWolf SS5 (#8606) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 0d98612e1..a459c2aac 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,9 +1,3 @@ -## Released - -### 8.4.0 20200716 - -- Release George - ## Unreleased (development) ### 8.3.1.6 20200617 @@ -17,6 +11,7 @@ - Add compile time interlock parameters (#8759) - Add compile time user template (#8766) - Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) +- Add support for switches/relays using an AC detection circuitry e.g. MOES MS-104B or BlitzWolf SS5 (#8606) - Fix exception or watchdog on rule re-entry (#8757) - Change ESP32 USER GPIO template representation decreasing template message size - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT @@ -67,6 +62,8 @@ - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) - Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) +## Released + ### 8.3.1 20200518 - Release Fred @@ -83,6 +80,8 @@ - Change Quick Power Cycle detection from 4 to 7 power interrupts (#4066) - Fix default state of ``SetOption73 0`` for button decoupling and send multi-press and hold MQTT messages +## Released + ### 8.3.0 20200514 - Release Fred @@ -167,6 +166,8 @@ - Add support for unreachable (unplugged) Zigbee devices in Philips Hue emulation and Alexa - Add support for 64x48 SSD1306 OLED (#6740) +## Released + ### 8.2.0 20200321 - Release Elliot From 277df060dd61c61f18ebbb9f3d81d572f1fb172b Mon Sep 17 00:00:00 2001 From: Marius Bezuidenhout Date: Sun, 12 Jul 2020 17:52:24 +0200 Subject: [PATCH 451/581] Schneider iEM3xxx Modbus feature Feature to read modbus data from Schneider Electric iEM energy monitor devices --- tasmota/language/bg_BG.h | 2 + tasmota/language/cs_CZ.h | 2 + tasmota/language/de_DE.h | 2 + tasmota/language/el_GR.h | 2 + tasmota/language/en_GB.h | 2 + tasmota/language/es_ES.h | 2 + tasmota/language/fr_FR.h | 2 + tasmota/language/he_HE.h | 2 + tasmota/language/hu_HU.h | 2 + tasmota/language/it_IT.h | 2 + tasmota/language/ko_KO.h | 2 + tasmota/language/nl_NL.h | 2 + tasmota/language/pl_PL.h | 2 + tasmota/language/pt_BR.h | 2 + tasmota/language/pt_PT.h | 2 + tasmota/language/ro_RO.h | 2 + tasmota/language/ru_RU.h | 2 + tasmota/language/sk_SK.h | 2 + tasmota/language/sv_SE.h | 2 + tasmota/language/tr_TR.h | 2 + tasmota/language/uk_UA.h | 2 + tasmota/language/zh_CN.h | 2 + tasmota/language/zh_TW.h | 2 + tasmota/my_user_config.h | 3 + tasmota/support_features.ino | 5 +- tasmota/tasmota_template.h | 9 +- tasmota/tasmota_template_ESP32.h | 8 +- tasmota/xnrg_17_iem3000.ino | 208 +++++++++++++++++++++++++++++++ tasmota/xnrg_interface.ino | 6 +- 29 files changed, 280 insertions(+), 5 deletions(-) create mode 100644 tasmota/xnrg_17_iem3000.ino diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 8f2c626c4..ca4afb0bc 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index e857b8e69..b07d032e7 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index b31e07901..3517251be 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 709c8f6c3..8eaff86f0 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 1586a0f92..98badad64 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index b23f71915..04116ea2a 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index a1ceba0a2..8aea1b4cc 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index d9cf1e435..f7a721739 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 1df3e0a4e..f521c06fd 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 3623f861b..788cee051 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP - TX" #define D_SENSOR_TCP_RXD "TCP - RX" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index a26dba20e..d635d1d65 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 15d5c715b..b024dc538 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 446660469..0ecea1a77 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 56c5811e6..be5d98464 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 930ac2b1b..c489327a7 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 6f38bffe7..23f160f19 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 051395ed7..b033ebcd1 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "Ð" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index d0109c930..9e5cc35e0 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 76385a4f6..ac416e9b5 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 8e7d34d2f..f402cf803 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index d4763bcfa..97cd77f91 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "Ð" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 84ce0991f..10f609c64 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "安" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 4762b9c16..e2382764b 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -703,6 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP Tx" #define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" // Units #define D_UNIT_AMPERE "安" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 3d9e904ca..57ebbd121 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -640,6 +640,9 @@ #define USE_BL0940 // Add support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code) //#define USE_TELEINFO // Add support for Teleinfo via serial RX interface (+5k2 code, +168 RAM + SmartMeter LinkedList Values RAM) // #define USE_TELEINFO_STANDARD // Use standard mode (9600 bps) else it's historical mode (1200 bps) +//#define USE_IEM3000 // Add support for Schneider Electric iEM3000-Modbus series energy monitor (+0k8 code) + #define IEM3000_SPEED 19200 // iEM3000-Modbus RS485 serial speed (default: 19200 baud) + #define IEM3000_ADDR 1 // iEM3000-Modbus modbus address (default: 0x01) // -- Low level interface devices ----------------- #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 6dfb5ee0e..0561eac6b 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -323,7 +323,6 @@ void GetFeatures(void) #ifdef USE_TM1638 feature_sns1 |= 0x80000000; // xsns_28_tm1638.ino #endif - /*********************************************************************************************/ feature_sns2 = 0x00000000; @@ -593,7 +592,9 @@ void GetFeatures(void) #ifdef USE_PROMETHEUS feature6 |= 0x00100000; // xsns_75_prometheus.ino #endif -// feature6 |= 0x00200000; +#if defined(USE_ENERGY_SENSOR) && defined(USE_IEM3000) + feature6 |= 0x00200000; // xnrg_16_iem3000.ino +#endif // feature6 |= 0x00400000; // feature6 |= 0x00800000; diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index bd1c009de..7ccd1fd0e 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -239,6 +239,8 @@ enum UserSelectablePins { GPIO_TELEINFO_RX, // TELEINFO serial interface GPIO_TELEINFO_ENABLE,// TELEINFO Enable PIN GPIO_LMT01, // LMT01 input counting pin + GPIO_IEM3000_TX, // IEM3000 Serial interface + GPIO_IEM3000_RX, // IEM3000 Serial interface GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -332,7 +334,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BL0940_RX "|" D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" - D_SENSOR_LMT01_PULSE + D_SENSOR_LMT01_PULSE "|" + D_SENSOR_IEM3000_TX "|" D_SENSOR_IEM3000_RX ; const char kSensorNamesFixed[] PROGMEM = @@ -578,6 +581,10 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_BL0940 GPIO_BL0940_RX, // BL0940 Serial interface #endif +#ifdef USE_IEM3000 + GPIO_IEM3000_TX, // IEM3000 Serial interface + GPIO_IEM3000_RX, // IEM3000 Serial interface +#endif #endif // USE_ENERGY_SENSOR // Serial diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index e5b30a5b1..7da1ba827 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -134,6 +134,7 @@ enum UserSelectablePins { GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin GPIO_LMT01, // LMT01 input counting pin + GPIO_IEM3000_TX, GPIO_IEM3000_RX, // IEM3000 Serial interface GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -227,7 +228,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|" D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" - D_SENSOR_LMT01_PULSE + D_SENSOR_LMT01_PULSE "|" + D_SENSOR_IEM3000_TX "|" D_SENSOR_IEM3000_RX ; const char kSensorNamesFixed[] PROGMEM = @@ -421,6 +423,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_BL0940 AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface #endif +#ifdef USE_IEM3000 + AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface + AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface +#endif #endif // USE_ENERGY_SENSOR // Serial diff --git a/tasmota/xnrg_17_iem3000.ino b/tasmota/xnrg_17_iem3000.ino new file mode 100644 index 000000000..040938dbc --- /dev/null +++ b/tasmota/xnrg_17_iem3000.ino @@ -0,0 +1,208 @@ +/* + xnrg_17_iem3000.ino - Schneider Electric iEM3000 series Modbus energy meter support for Tasmota + + Copyright (C) 2020 Marius Bezuidenhout + + 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_ENERGY_SENSOR +#ifdef USE_IEM3000 +/*********************************************************************************************\ + * Schneider Electric iEM3000 series Modbus energy meter + * iEM3150 / iEM3155 / iEM3250 / iEM3255 / iEM3350 / iEM3355 / iEM3455 / iEM3555 + * Important! Set meter Commnication -> Parity to None +\*********************************************************************************************/ + +#define XNRG_17 17 + +// can be user defined in my_user_config.h +#ifndef IEM3000_SPEED + #define IEM3000_SPEED 19200 // default IEM3000 Modbus address +#endif +// can be user defined in my_user_config.h +#ifndef IEM3000_ADDR + #define IEM3000_ADDR 1 // default IEM3000 Modbus address +#endif + +#include +TasmotaModbus *Iem3000Modbus; + +const uint16_t Iem3000_start_addresses[] { + // ID (reg count/datatype) [unit] Description + 0x0bb7, // 0 . IEM3000_I1_CURRENT (2/Float32) [A] I1: phase 1 current + 0x0bb9, // 1 . IEM3000_I2_CURRENT (2/Float32) [A] I2: phase 2 current + 0x0bbb, // 2 . IEM3000_I3_CURRENT (2/Float32) [A] I3: phase 3 current + 0x0bd3, // 3 . IEM3000_L1_VOLTAGE (2/Float32) [V] Voltage L1–N + 0x0bd5, // 4 . IEM3000_L2_VOLTAGE (2/Float32) [V] Voltage L2–N + 0x0bd7, // 5 . IEM3000_L3_VOLTAGE (2/Float32) [V] Voltage L3–N + 0x0bed, // 6 . IEM3000_P1_POWER (2/Float32) [KW] Active Power Phase 1 + 0x0bef, // 7 . IEM3000_P2_POWER (2/Float32) [KW] Active Power Phase 2 + 0x0bf1, // 8 . IEM3000_P3_POWER (2/Float32) [KW] Active Power Phase 3 + 0x0c25, // 9 . IEM3000_FREQUENCY (2/Float32) [Hz] Frequency + 0xb02b, // 10 . IEM3000_TOTAL_ACTIVE (4/Int64) [Wh] Total Active Energy Import +}; + +struct IEM3000 { + uint8_t read_state = 0; + uint8_t send_retry = 0; +} Iem3000; + +/*********************************************************************************************/ + +void IEM3000Every250ms(void) +{ + bool data_ready = Iem3000Modbus->ReceiveReady(); + uint8_t reg_count = 4; + if (Iem3000.read_state < 10) { + reg_count = 2; + } + + if (data_ready) { + uint8_t buffer[14]; // At least 5 + sizeof(int64_t) = 13 + + uint32_t error = Iem3000Modbus->ReceiveBuffer(buffer, reg_count); + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, Iem3000Modbus->ReceiveCount()); + + if (error) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SDM: Iem3000 error %d"), error); + } else { + Energy.data_valid[0] = 0; + + // 0 1 2 3 4 5 6 7 8 + // SA FC BC Fh Fl Sh Sl Cl Ch + // 01 04 04 43 66 33 34 1B 38 = 230.2 Volt + float value; + int64_t value64; + if(Iem3000.read_state >= 0 && Iem3000.read_state < 10) { + ((uint8_t*)&value)[3] = buffer[3]; // Get float values + ((uint8_t*)&value)[2] = buffer[4]; + ((uint8_t*)&value)[1] = buffer[5]; + ((uint8_t*)&value)[0] = buffer[6]; + } else { + ((uint8_t*)&value64)[7] = buffer[3]; // Get int values + ((uint8_t*)&value64)[6] = buffer[4]; + ((uint8_t*)&value64)[5] = buffer[5]; + ((uint8_t*)&value64)[4] = buffer[6]; + ((uint8_t*)&value64)[3] = buffer[7]; + ((uint8_t*)&value64)[2] = buffer[8]; + ((uint8_t*)&value64)[1] = buffer[9]; + ((uint8_t*)&value64)[0] = buffer[10]; + } + + switch(Iem3000.read_state) { + case 0: + Energy.current[0] = value; + break; + + case 1: + Energy.current[1] = value; + break; + + case 2: + Energy.current[2] = value; + break; + + case 3: + Energy.voltage[0] = value; + break; + + case 4: + Energy.voltage[1] = value; + break; + + case 5: + Energy.voltage[2] = value; + break; + + case 6: + Energy.active_power[0] = value; + break; + + case 7: + Energy.active_power[1] = value; + break; + + case 8: + Energy.active_power[2] = value; + break; + + case 9: + Energy.frequency[0] = value; + break; + + case 10: + EnergyUpdateTotal(value64 * 0.001f, true); // 1125 => 1.125 + break; + } + + Iem3000.read_state++; + if (sizeof(Iem3000_start_addresses)/2 == Iem3000.read_state) { + Iem3000.read_state = 0; + } + } + } // end data ready + + if (0 == Iem3000.send_retry || data_ready) { + Iem3000.send_retry = 5; + Iem3000Modbus->Send(IEM3000_ADDR, 0x03, Iem3000_start_addresses[Iem3000.read_state], reg_count); + } else { + Iem3000.send_retry--; + } +} + +void Iem3000SnsInit(void) +{ + Iem3000Modbus = new TasmotaModbus(Pin(GPIO_IEM3000_RX), Pin(GPIO_IEM3000_TX)); + uint8_t result = Iem3000Modbus->Begin(IEM3000_SPEED); + if (result) { + if (2 == result) { ClaimSerial(); } + Energy.phase_count = 3; + Energy.frequency_common = true; // Use common frequency + } else { + energy_flg = ENERGY_NONE; + } +} + +void Iem3000DrvInit(void) +{ + if (PinUsed(GPIO_IEM3000_RX) && PinUsed(GPIO_IEM3000_TX)) { + energy_flg = XNRG_17; + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xnrg17(uint8_t function) +{ + bool result = false; + + switch (function) { + case FUNC_EVERY_250_MSECOND: + if (uptime > 4) { IEM3000Every250ms(); } + break; + case FUNC_INIT: + Iem3000SnsInit(); + break; + case FUNC_PRE_INIT: + Iem3000DrvInit(); + break; + } + return result; +} + +#endif // USE_IEM3000 +#endif // USE_ENERGY_SENSOR diff --git a/tasmota/xnrg_interface.ino b/tasmota/xnrg_interface.ino index b0a4784f5..8e5bbf836 100644 --- a/tasmota/xnrg_interface.ino +++ b/tasmota/xnrg_interface.ino @@ -86,7 +86,11 @@ bool (* const xnrg_func_ptr[])(uint8_t) = { // Energy driver Function Pointers #endif #ifdef XNRG_16 - &Xnrg16 + &Xnrg16, +#endif + +#ifdef XNRG_17 + &Xnrg17 #endif }; From 39705a2e059cf616199c1e18eb04a87d00482b7c Mon Sep 17 00:00:00 2001 From: Staars Date: Sun, 12 Jul 2020 18:17:27 +0200 Subject: [PATCH 452/581] add lights, yeerc, decryption and more --- tasmota/xsns_62_MI_ESP32.ino | 809 +++++++++++++++++++++++------------ 1 file changed, 535 insertions(+), 274 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 9fa6a71d8..6ec2d6f83 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -20,7 +20,11 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.1.0 20200712 changed - add lights and yeerc, add pure passive mode with decryption, + lots of refactoring + ------- 0.9.0.1 20200706 changed - adapt to new NimBLE-API, tweak scan process + ------- 0.9.0.0 20200413 started - initial development by Christian Baars forked - from arendst/tasmota - https://github.com/arendst/Tasmota @@ -30,9 +34,13 @@ #ifdef USE_MI_ESP32 #define XSNS_62 62 +#define USE_MI_DECRYPTION #include #include +#ifdef USE_MI_DECRYPTION +#include +#endif //USE_MI_DECRYPTION void MI32scanEndedCB(NimBLEScanResults results); void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify); @@ -56,6 +64,10 @@ struct { uint32_t willReadBatt:1; uint32_t shallSetUnit:1; uint32_t willSetUnit:1; + uint32_t triggeredTele:1; + uint32_t shallClearResults:1; + uint32_t directMQTT:1; // TODO: direct bridging of every single sensor message + } mode; struct { uint8_t sensor; // points to to the number 0...255 @@ -87,7 +99,7 @@ struct mi_beacon_t{ uint16_t frame; uint16_t productID; uint8_t counter; - uint8_t Mac[6]; + uint8_t MAC[6]; uint8_t spare; uint8_t type; uint8_t ten; @@ -103,12 +115,18 @@ struct mi_beacon_t{ uint32_t lux; //07 uint8_t moist; //08 uint16_t fert; //09 + uint32_t NMT; //17 + struct{ //01 + uint16_t num; + uint8_t longPress; + }Btn; }; + uint8_t padding[12]; }; struct cg_packet_t { uint16_t frameID; - uint8_t serial[6]; + uint8_t MAC[6]; uint16_t mode; union { struct { @@ -119,34 +137,58 @@ struct cg_packet_t { }; }; +struct encPacket_t{ + // the packet is longer, but this part is enough to decrypt + uint16_t PID; + uint8_t frameCnt; + uint8_t MAC[6]; + uint8_t payload[16]; // only a pointer to the address, size is variable +}; + +union mi_bindKey_t{ + struct{ + uint8_t key[16]; + uint8_t MAC[6]; + }; + uint8_t buf[22]; +}; + #pragma pack(0) struct mi_sensor_t{ uint8_t type; //Flora = 1; MI-HT_V1=2; LYWSD02=3; LYWSD03=4; CGG1=5; CGD1=6 - uint8_t serial[6]; - uint8_t showedUp; + uint8_t lastCnt; //device generated counter of the packet + uint8_t shallSendMQTT; + uint8_t MAC[6]; + // uint8_t showedUp; + uint32_t lastTime; + uint32_t lux; float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx union { struct { float moisture; float fertility; - uint32_t lux; + char firmware[6]; // actually only for FLORA but hopefully we can add for more devices }; // Flora struct { float hum; }; // MJ_HT_V1, LYWSD0x + struct { + uint16_t events; //"alarms" since boot + uint32_t NMT; // no motion time in seconds for the MJYD2S + uint8_t eventType; //internal type of actual event for the MJYD2S -> 1: PIR, 2: No PIR, 3: NMT + }; + uint16_t Btn; }; - union - { - uint8_t bat; // many values seem to be hard-coded garbage (LYWSD0x, GCD1) - uint16_t volt; // LYWSD03MMC + union { + uint8_t bat; // many values seem to be hard-coded garbage (LYWSD0x, GCD1) }; - char firmware[6]; // actually only for FLORA but hopefully we can add for more devices }; std::vector MIBLEsensors; -BLEScan* MI32Scan; -BLEScanResults MI32foundDevices; +std::vector MIBLEbindKeys; + +static BLEScan* MI32Scan; /*********************************************************************************************\ * constants @@ -156,7 +198,7 @@ BLEScanResults MI32foundDevices; const char S_JSON_MI32_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%d}"; const char S_JSON_MI32_COMMAND[] PROGMEM = "{\"" D_CMND_MI32 "%s%s\"}"; -const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit"; +const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit|Key"; #define FLORA 1 #define MJ_HT_V1 2 @@ -164,22 +206,31 @@ const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit #define LYWSD03MMC 4 #define CGG1 5 #define CGD1 6 +#define NLIGHT 7 +#define MJYD2S 8 +#define YEERC 9 -const uint16_t kMI32SlaveID[6]={ 0x0098, // Flora +const uint16_t kMI32DeviceID[9]={ 0x0098, // Flora 0x01aa, // MJ_HT_V1 0x045b, // LYWSD02 0x055b, // LYWSD03 0x0347, // CGG1 - 0x0576 // CGD1 + 0x0576, // CGD1 + 0x03dd, // NLIGHT + 0x07f6, // MJYD2S + 0x0153 // yee-rc }; -const char kMI32SlaveType1[] PROGMEM = "Flora"; -const char kMI32SlaveType2[] PROGMEM = "MJ_HT_V1"; -const char kMI32SlaveType3[] PROGMEM = "LYWSD02"; -const char kMI32SlaveType4[] PROGMEM = "LYWSD03"; -const char kMI32SlaveType5[] PROGMEM = "CGG1"; -const char kMI32SlaveType6[] PROGMEM = "CGD1"; -const char * kMI32SlaveType[] PROGMEM = {kMI32SlaveType1,kMI32SlaveType2,kMI32SlaveType3,kMI32SlaveType4,kMI32SlaveType5,kMI32SlaveType6}; +const char kMI32DeviceType1[] PROGMEM = "Flora"; +const char kMI32DeviceType2[] PROGMEM = "MJ_HT_V1"; +const char kMI32DeviceType3[] PROGMEM = "LYWSD02"; +const char kMI32DeviceType4[] PROGMEM = "LYWSD03"; +const char kMI32DeviceType5[] PROGMEM = "CGG1"; +const char kMI32DeviceType6[] PROGMEM = "CGD1"; +const char kMI32DeviceType7[] PROGMEM = "NLIGHT"; +const char kMI32DeviceType8[] PROGMEM = "MJYD2S"; +const char kMI32DeviceType9[] PROGMEM = "YEERC"; +const char * kMI32DeviceType[] PROGMEM = {kMI32DeviceType1,kMI32DeviceType2,kMI32DeviceType3,kMI32DeviceType4,kMI32DeviceType5,kMI32DeviceType6,kMI32DeviceType7,kMI32DeviceType8,kMI32DeviceType9}; /*********************************************************************************************\ * enumerations @@ -190,7 +241,8 @@ enum MI32_Commands { // commands useable in console or rules CMND_MI32_TIME, // set LYWSD02-Time from ESP8266-time CMND_MI32_PAGE, // sensor entries per web page, which will be shown alternated CMND_MI32_BATTERY, // read all battery levels - CMND_MI32_UNIT // toggles the displayed unit between C/F (LYWSD02) + CMND_MI32_UNIT, // toggles the displayed unit between C/F (LYWSD02) + CMND_MI32_KEY // add bind key to a mac for packet decryption }; enum MI32_TASK { @@ -207,13 +259,13 @@ enum MI32_TASK { class MI32SensorCallback : public NimBLEClientCallbacks { void onConnect(NimBLEClient* pclient) { - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("connected %s"), kMI32SlaveType[(MIBLEsensors[MI32.state.sensor].type)-1]); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("connected %s"), kMI32DeviceType[(MIBLEsensors[MI32.state.sensor].type)-1]); MI32.mode.willConnect = 0; MI32.mode.connected = 1; } void onDisconnect(NimBLEClient* pclient) { MI32.mode.connected = 0; - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("disconnected %s"), kMI32SlaveType[(MIBLEsensors[MI32.state.sensor].type)-1]); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("disconnected %s"), kMI32DeviceType[(MIBLEsensors[MI32.state.sensor].type)-1]); } bool onConnParamsUpdateRequest(NimBLEClient* MI32Client, const ble_gap_upd_params* params) { if(params->itvl_min < 24) { /** 1.25ms units */ @@ -234,6 +286,7 @@ class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); if (advertisedDevice->getServiceData().length() == 0) { // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + MI32Scan->erase(advertisedDevice->getAddress()); return; } uint16_t uuid = advertisedDevice->getServiceDataUUID().getNative()->u16.value; @@ -243,13 +296,12 @@ class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { MI32_ReverseMAC(addr); if(uuid==0xfe95) { MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); - MI32Scan->erase(advertisedDevice->getAddress()); } else if(uuid==0xfdcd) { MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); - MI32Scan->erase(advertisedDevice->getAddress()); } else { + MI32Scan->erase(advertisedDevice->getAddress()); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); } }; @@ -293,6 +345,125 @@ void MI32_ReverseMAC(uint8_t _mac[]){ memcpy(_mac,_reversedMAC, sizeof(_reversedMAC)); } +#ifdef USE_MI_DECRYPTION +void MI32AddKey(char* payload){ + mi_bindKey_t keyMAC; + memset(keyMAC.buf,0,sizeof(keyMAC)); + MI32KeyMACStringToBytes(payload,keyMAC.buf); + bool unknownKey = true; + for(uint32_t i=0; i= '0' && c <= '9') + value = (c - '0'); + else if (c >= 'A' && c <= 'F') + value = (10 + (c - 'A')); + _keyMAC[(index/2)] += value << (((index + 1) % 2) * 4); + index++; + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: %s to:"),_string); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: key-array: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"),_keyMAC[0],_keyMAC[1],_keyMAC[2],_keyMAC[3],_keyMAC[4],_keyMAC[5],_keyMAC[6],_keyMAC[7],_keyMAC[8],_keyMAC[9],_keyMAC[10],_keyMAC[11],_string,_keyMAC[12],_keyMAC[13],_keyMAC[14],_keyMAC[15]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MAC-array: %02X%02X%02X%02X%02X%02X"),_keyMAC[16],_keyMAC[17],_keyMAC[18],_keyMAC[19],_keyMAC[20],_keyMAC[21]); +} + +/** + * @brief Decrypts payload in place + * + * @param _buf - pointer to the buffer at position of PID + * @param _bufSize - buffersize (last position is last byte of TAG) + * @param _type - sensor type + * @return int - error code, 0 for success + */ +int MI32_decryptPacket(char *_buf, uint16_t _bufSize, uint32_t _type){ + encPacket_t *packet = (encPacket_t*)_buf; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("to decrypt: %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" : %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" : %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[16],(uint8_t)_buf[17],(uint8_t)_buf[18],(uint8_t)_buf[19],(uint8_t)_buf[20],(uint8_t)_buf[21],(uint8_t)_buf[22],(uint8_t)_buf[23]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("as packet: MAC: %02x %02x %02x %02x %02x %02x"), packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); + + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Decrypt Size of Buffer: %u"), _bufSize); + int ret = 0; + unsigned char output[10] = {0}; + uint8_t nonce[12]; + uint8_t tag[4 ]; + const unsigned char authData[1] = {0x11}; + + // nonce: device MAC, device type, frame cnt, ext. cnt + for (uint32_t i = 0; i<6; i++){ + nonce[i] = packet->MAC[i]; + } + memcpy((uint8_t*)&nonce+6,(uint8_t*)&packet->PID,2); + nonce[8] = packet->frameCnt; + memcpy((uint8_t*)&nonce+9,(char*)&_buf[_bufSize-9],3); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("nonceCnt1 and 2: %02x %02x %02x"),nonce[9],nonce[10],nonce[11]); + memcpy((uint8_t*)&tag,(char*)&_buf[_bufSize-6],4); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("tag: %02x %02x %02x %02x"),tag[0],tag[1],tag[2],tag[3]); + + MI32_ReverseMAC(packet->MAC); + uint8_t _bindkey[16] = {0x0}; + for(uint32_t i=0; iMAC,MIBLEbindKeys[i].MAC,sizeof(packet->MAC))==0){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("have key")); + memcpy(_bindkey,MIBLEbindKeys[i].key,sizeof(_bindkey)); + } + else{ + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mac in packet: %02x %02x %02x %02x %02x %02x"), packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mac in vector: %02x %02x %02x %02x %02x %02x"), MIBLEbindKeys[i].MAC[0], MIBLEbindKeys[i].MAC[1], MIBLEbindKeys[i].MAC[2], MIBLEbindKeys[i].MAC[3], MIBLEbindKeys[i].MAC[4], MIBLEbindKeys[i].MAC[5]); + } + } + + // init + mbedtls_ccm_context ctx; + mbedtls_ccm_init(&ctx); + // set bind key + ret = mbedtls_ccm_setkey(&ctx, + MBEDTLS_CIPHER_ID_AES, + _bindkey, + 16 * 8 //bits + ); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("set key: %i, MAC: %02x %02x %02x %02x %02x %02x"),ret, packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); + +/*int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ) +*/ + ret = mbedtls_ccm_auth_decrypt(&ctx,_bufSize-18, + (const unsigned char*)&nonce, sizeof(nonce), + authData, sizeof(authData), + (const unsigned char*)packet->payload, output, + tag,sizeof(tag)); + + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Decrypted %i: %02x %02x %02x %02x %02x %02x %02x"), ret, output[0],output[1],output[2],output[3],output[4],output[5],output[6]); + // put decrypted data in place + memcpy((uint8_t*)(packet->payload)+1,output,_bufSize-18); + // clean up + mbedtls_ccm_free(&ctx); + return ret; +} +#endif // USE_MI_DECRYPTION + /*********************************************************************************************\ * common functions \*********************************************************************************************/ @@ -301,63 +472,82 @@ void MI32_ReverseMAC(uint8_t _mac[]){ /** * @brief Return the slot number of a known sensor or return create new sensor slot * - * @param _serial BLE address of the sensor + * @param _MAC BLE address of the sensor * @param _type Type number of the sensor * @return uint32_t Known or new slot in the sensors-vector */ -uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint16_t _type){ +uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter){ DEBUG_SENSOR_LOG(PSTR("%s: will test ID-type: %x"),D_CMND_MI32, _type); bool _success = false; - for (uint32_t i=0;i<6;i++){ // i < sizeof(kMI32SlaveID) gives compiler warning - if(_type == kMI32SlaveID[i]){ + for (uint32_t i=0;i<9;i++){ // i < sizeof(kMI32DeviceID) gives compiler warning + if(_type == kMI32DeviceID[i]){ DEBUG_SENSOR_LOG(PSTR("MI32: ID is type %u"), i); _type = i+1; _success = true; } else { - DEBUG_SENSOR_LOG(PSTR("%s: ID-type is not: %x"),D_CMND_MI32,kMI32SlaveID[i]); + DEBUG_SENSOR_LOG(PSTR("%s: ID-type is not: %x"),D_CMND_MI32,kMI32DeviceID[i]); } } if(!_success) return 0xff; DEBUG_SENSOR_LOG(PSTR("%s: vector size %u"),D_CMND_MI32, MIBLEsensors.size()); for(uint32_t i=0; isetClientCallbacks(&MI32SensorCB , false); MI32Client->setConnectionParams(12,12,0,48); MI32Client->setConnectTimeout(30); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: did create new client"),D_CMND_MI32); } + vTaskDelay(300/ portTICK_PERIOD_MS); if (!MI32Client->connect(_address,false)) { MI32.mode.willConnect = 0; - NimBLEDevice::deleteClient(MI32Client); - DEBUG_SENSOR_LOG(PSTR("%s: did not connect client"),D_CMND_MI32); + // NimBLEDevice::deleteClient(MI32Client); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: did not connect client"),D_CMND_MI32); return false; } - DEBUG_SENSOR_LOG(PSTR("%s: did create new client"),D_CMND_MI32); return true; // } } - void MI32StartScanTask(){ if (MI32.mode.connected) return; MI32.mode.runningScan = 1; - // Wifi.counter = Wifi.counter + 3; xTaskCreatePinnedToCore( MI32ScanTask, /* Function to implement the task */ "MI32ScanTask", /* Name of the task */ - 8192, /* Stack size in words */ + 4096, /* Stack size in words */ NULL, /* Task input parameter */ 0, /* Priority of the task */ NULL, /* Task handle. */ @@ -470,26 +658,33 @@ void MI32StartScanTask(){ void MI32ScanTask(void *pvParameters){ if (MI32Scan == nullptr) MI32Scan = NimBLEDevice::getScan(); DEBUG_SENSOR_LOG(PSTR("%s: Scan Cache Length: %u"),D_CMND_MI32, MI32Scan->getResults().getCount()); - MI32Scan->setAdvertisedDeviceCallbacks(&MI32ScanCallbacks); + MI32Scan->setInterval(70); + MI32Scan->setWindow(50); + MI32Scan->setAdvertisedDeviceCallbacks(&MI32ScanCallbacks,true); MI32Scan->setActiveScan(false); - MI32Scan->start(5, MI32scanEndedCB, true); // hard coded duration + MI32Scan->start(0, MI32scanEndedCB, true); // never stop scanning, will pause automaically while connecting + uint32_t timer = 0; - while (MI32.mode.runningScan){ - if (timer>15){ - vTaskDelete( NULL ); + for(;;){ + if(MI32.mode.shallClearResults){ + MI32Scan->clearResults(); + MI32.mode.shallClearResults=0; } - timer++; - vTaskDelay(1000/ portTICK_PERIOD_MS); + vTaskDelay(10000/ portTICK_PERIOD_MS); } vTaskDelete( NULL ); } void MI32StartSensorTask(){ MI32.mode.willConnect = 1; + if (MIBLEsensors[MI32.state.sensor].type != LYWSD03MMC) { + MI32.mode.willConnect = 0; + return; + } xTaskCreatePinnedToCore( MI32SensorTask, /* Function to implement the task */ "MI32SensorTask", /* Name of the task */ - 8192, /* Stack size in words */ + 4096, /* Stack size in words */ NULL, /* Task input parameter */ 15, /* Priority of the task */ NULL, /* Task handle. */ @@ -499,16 +694,12 @@ void MI32StartSensorTask(){ } void MI32SensorTask(void *pvParameters){ - if (MIBLEsensors[MI32.state.sensor].type != LYWSD03MMC) { - MI32.mode.willConnect = 0; - vTaskDelete( NULL ); - } if (MI32ConnectActiveSensor()){ uint32_t timer = 0; while (MI32.mode.connected == 0){ if (timer>1000){ MI32Client->disconnect(); - NimBLEDevice::deleteClient(MI32Client); + // NimBLEDevice::deleteClient(MI32Client); MI32.mode.willConnect = 0; vTaskDelay(100/ portTICK_PERIOD_MS); vTaskDelete( NULL ); @@ -537,7 +728,7 @@ void MI32SensorTask(void *pvParameters){ MI32Client->disconnect(); DEBUG_SENSOR_LOG(PSTR("%s: requested disconnect"),D_CMND_MI32); } - vTaskDelay(500/ portTICK_PERIOD_MS); + MI32.mode.connected = 0; vTaskDelete( NULL ); } @@ -566,7 +757,7 @@ void MI32StartTimeTask(){ xTaskCreatePinnedToCore( MI32TimeTask, /* Function to implement the task */ "MI32TimeTask", /* Name of the task */ - 8912, /* Stack size in words */ + 4096, /* Stack size in words */ NULL, /* Task input parameter */ 15, /* Priority of the task */ NULL, /* Task handle. */ @@ -621,8 +812,9 @@ void MI32TimeTask(void *pvParameters){ } MI32Client->disconnect(); } - vTaskDelay(500/ portTICK_PERIOD_MS); + MI32.mode.connected = 0; + MI32.mode.canScan = 1; vTaskDelete( NULL ); } @@ -631,7 +823,7 @@ void MI32StartUnitTask(){ xTaskCreatePinnedToCore( MI32UnitTask, /* Function to implement the task */ "MI32UnitTask", /* Name of the task */ - 8912, /* Stack size in words */ + 4096, /* Stack size in words */ NULL, /* Task input parameter */ 15, /* Priority of the task */ NULL, /* Task handle. */ @@ -658,8 +850,8 @@ void MI32UnitTask(void *pvParameters){ NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); - static BLEUUID charUUID("EBE0CCBE-7A0A-4B0C-8A1A-6FF2997DA3A6"); + static BLEUUID serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + static BLEUUID charUUID(0xEBE0CCBE,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); pSvc = MI32Client->getService(serviceUUID); if(pSvc) { pChr = pSvc->getCharacteristic(charUUID); @@ -687,8 +879,9 @@ void MI32UnitTask(void *pvParameters){ } MI32Client->disconnect(); } - vTaskDelay(500/ portTICK_PERIOD_MS); + MI32.mode.connected = 0; + MI32.mode.canScan = 1; vTaskDelete( NULL ); } @@ -697,10 +890,18 @@ void MI32StartBatteryTask(){ MI32.mode.willReadBatt = 1; MI32.mode.willConnect = 1; MI32.mode.canScan = 0; + + switch (MIBLEsensors[MI32.state.sensor].type){ + case LYWSD03MMC: case MJ_HT_V1: case CGG1: case NLIGHT: case MJYD2S: case YEERC: + MI32.mode.willConnect = 0; + MI32.mode.willReadBatt = 0; + return; + } + xTaskCreatePinnedToCore( MI32BatteryTask, /* Function to implement the task */ "MI32BatteryTask", /* Name of the task */ - 8192, /* Stack size in words */ + 4096, /* Stack size in words */ NULL, /* Task input parameter */ 15, /* Priority of the task */ NULL, /* Task handle. */ @@ -709,15 +910,6 @@ void MI32StartBatteryTask(){ void MI32BatteryTask(void *pvParameters){ // all reported battery values are probably crap, but we allow the reading on demand - switch (MIBLEsensors[MI32.state.sensor].type){ - case LYWSD03MMC: case MJ_HT_V1: case CGG1: - MI32.mode.willConnect = 0; - MI32.mode.willReadBatt = 0; - vTaskDelete( NULL ); - break; - default: - break; - } MI32.mode.connected = 0; if(MI32ConnectActiveSensor()){ @@ -731,26 +923,18 @@ void MI32BatteryTask(void *pvParameters){ } switch(MIBLEsensors[MI32.state.sensor].type){ - case FLORA: - MI32batteryFLORA(); - break; - case LYWSD02: - MI32batteryLYWSD02(); - break; - case CGD1: - MI32batteryCGD1(); + case FLORA: case LYWSD02: case CGD1: + MI32batteryRead(MIBLEsensors[MI32.state.sensor].type); break; } MI32Client->disconnect(); } MI32.mode.willReadBatt = 0; - // Wifi.counter = 0; // Now check it - vTaskDelay(500/ portTICK_PERIOD_MS); MI32.mode.connected = 0; vTaskDelete( NULL ); } -void MI32batteryFLORA(){ +void MI32batteryRead(uint32_t _type){ uint32_t timer = 0; while (!MI32.mode.connected){ if (timer>1000){ @@ -759,79 +943,45 @@ void MI32batteryFLORA(){ timer++; vTaskDelay(10/ portTICK_PERIOD_MS); } - DEBUG_SENSOR_LOG(PSTR("%s connected for battery"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); + DEBUG_SENSOR_LOG(PSTR("%s connected for battery"),kMI32DeviceType[MIBLEsensors[MI32.state.sensor].type-1] ); NimBLERemoteService* pSvc = nullptr; NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID FLserviceUUID(0x00001204,0x0000,0x1000,0x800000805f9b34fb); - static BLEUUID FLcharUUID(0x00001a02,0x0000,0x1000,0x800000805f9b34fb); - pSvc = MI32Client->getService(FLserviceUUID); - if(pSvc) { - pChr = pSvc->getCharacteristic(FLcharUUID); - } - if (pChr){ - DEBUG_SENSOR_LOG(PSTR("%s: got Flora char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); - if(pChr->canRead()) { - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); - //we also can read the firmware from response no extra request needed - MI32readFirmwareFLORA((char*)buf); - } - } - MI32.mode.readingDone = 1; -} - -void MI32batteryLYWSD02(){ - uint32_t timer = 0; - while (!MI32.mode.connected){ - if (timer>1000){ - break; + switch(_type){ + case FLORA: + { + static BLEUUID _serviceUUID(0x00001204,0x0000,0x1000,0x800000805f9b34fb); + static BLEUUID _charUUID(0x00001a02,0x0000,0x1000,0x800000805f9b34fb); + pSvc = MI32Client->getService(_serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(_charUUID); } - timer++; - vTaskDelay(10/ portTICK_PERIOD_MS); } - - NimBLERemoteService* pSvc = nullptr; - NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID LY2serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); - static BLEUUID LY2charUUID(0xEBE0CCC4,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); - - pSvc = MI32Client->getService(LY2serviceUUID); - if(pSvc) { - pChr = pSvc->getCharacteristic(LY2charUUID); - } - if (pChr){ - DEBUG_SENSOR_LOG( PSTR("%s: got LYWSD02 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); - if(pChr->canRead()) { - DEBUG_SENSOR_LOG(PSTR("LYWSD02 char")); - const char *buf = pChr->readValue().c_str(); - MI32readBat((char*)buf); - } - } - MI32.mode.readingDone = 1; -} - -void MI32batteryCGD1(){ - uint32_t timer = 0; - while (!MI32.mode.connected){ - if (timer>1000){ - break; + break; + case LYWSD02: + { + static BLEUUID _serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + static BLEUUID _charUUID(0xEBE0CCC4,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + pSvc = MI32Client->getService(_serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(_charUUID); } - timer++; - vTaskDelay(10/ portTICK_PERIOD_MS); } - - NimBLERemoteService* pSvc = nullptr; - NimBLERemoteCharacteristic* pChr = nullptr; - static BLEUUID CGD1serviceUUID((uint16_t)0x180F); - static BLEUUID CGD1charUUID((uint16_t)0x2A19); - - pSvc = MI32Client->getService(CGD1serviceUUID); - if(pSvc) { - pChr = pSvc->getCharacteristic(CGD1charUUID); + break; + case CGD1: + { + static BLEUUID _serviceUUID((uint16_t)0x180F); + static BLEUUID _charUUID((uint16_t)0x2A19); + pSvc = MI32Client->getService(_serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(_charUUID); + } + } + break; } + if (pChr){ - DEBUG_SENSOR_LOG(PSTR("%s: got CGD1 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + DEBUG_SENSOR_LOG(PSTR("%s: got %s char %s"),D_CMND_MI32, kMI32DeviceType[MIBLEsensors[MI32.state.sensor].type-1], pChr->getUUID().toString().c_str()); if(pChr->canRead()) { const char *buf = pChr->readValue().c_str(); MI32readBat((char*)buf); @@ -840,87 +990,166 @@ void MI32batteryCGD1(){ MI32.mode.readingDone = 1; } - /*********************************************************************************************\ * parse the response from advertisements \*********************************************************************************************/ -void MI32parseMiBeacon(char * _buf, uint32_t _slot){ +void MI32parseMiBeacon(char * _buf, uint32_t _slot, uint16_t _bufSize){ float _tempFloat; mi_beacon_t _beacon; - if (MIBLEsensors[_slot].type==MJ_HT_V1 || MIBLEsensors[_slot].type==CGG1){ - memcpy((uint8_t*)&_beacon+1,(uint8_t*)_buf, sizeof(_beacon)); // shift by one byte for the MJ_HT_V1 - memcpy((uint8_t*)&_beacon.Mac,(uint8_t*)&_beacon.Mac+1,6); // but shift back the MAC + + if (MIBLEsensors[_slot].type==MJ_HT_V1 || MIBLEsensors[_slot].type==CGG1 || MIBLEsensors[_slot].type==YEERC){ + memcpy((uint8_t*)&_beacon+1,(uint8_t*)_buf, sizeof(_beacon)-1); // shift by one byte for the MJ_HT_V1 DANGER!!! + memcpy((uint8_t*)&_beacon.MAC,(uint8_t*)&_beacon.MAC+1,6); // but shift back the MAC + _beacon.counter = _buf[4]; // restore the counter } else{ - memcpy((void*)&_beacon,(void*)_buf, sizeof(_beacon)); + memcpy((char *)&_beacon, _buf, _bufSize); } - MI32_ReverseMAC(_beacon.Mac); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); + MIBLEsensors[_slot].lastCnt = _beacon.counter; +#ifdef USE_MI_DECRYPTION + switch(MIBLEsensors[_slot].type){ + case LYWSD03MMC: + if (_beacon.frame == 0x5858){ + int decryptRet = MI32_decryptPacket((char*)&_beacon.productID,_bufSize, LYWSD03MMC); //start with PID + } + break; + case MJYD2S: + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MJYD2S: %x"),_beacon.frame); + if (_beacon.frame == 0x5948){ // Now let's build/recreate a special MiBeacon + memmove((uint8_t*)&_beacon.MAC+6,(uint8_t*)&_beacon.MAC, _bufSize); // shift payload by the size of the MAC = 6 bytes + memcpy((uint8_t*)&_beacon.MAC,MIBLEsensors[_slot].MAC,6); // now insert the real MAC from our internal vector + _bufSize+=6; // the packet has grown + MI32_ReverseMAC(_beacon.MAC); // payload MAC is always reversed + } + if (_beacon.frame != 0x5910){ + int decryptRet = MI32_decryptPacket((char*)&_beacon.productID,_bufSize,MJYD2S); //start with PID + } + else{ + if(millis()-MIBLEsensors[_slot].lastTime>120000){ + MIBLEsensors[_slot].eventType = 1; + MIBLEsensors[_slot].events++; + MIBLEsensors[_slot].shallSendMQTT = 1; + MIBLEsensors[_slot].lastTime = millis(); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MJYD2S secondary PIR")); + MIBLEsensors[_slot].NMT = 0; + MI32triggerTele(); + } + } + break; + } +#endif //USE_MI_DECRYPTION - if(MIBLEsensors[_slot].type==4 || MIBLEsensors[_slot].type==6){ +if (MIBLEsensors[_slot].type==NLIGHT){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); +} + + if(MIBLEsensors[_slot].type==6){ DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type); return; } - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32SlaveType[MIBLEsensors[_slot].type-1],_slot); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); switch(_beacon.type){ + case 0x01: + MIBLEsensors[_slot].Btn=_beacon.Btn.num + (_beacon.Btn.longPress/2)*6; + MIBLEsensors[_slot].shallSendMQTT = 1; + MI32triggerTele(); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 1: U16: %u Button"), MIBLEsensors[_slot].Btn ); + break; case 0x04: - _tempFloat=(float)(_beacon.temp)/10.0f; - if(_tempFloat<60){ - MIBLEsensors[_slot].temp=_tempFloat; - DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); - } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); + _tempFloat=(float)(_beacon.temp)/10.0f; + if(_tempFloat<60){ + MIBLEsensors[_slot].temp=_tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); break; case 0x06: - _tempFloat=(float)(_beacon.hum)/10.0f; - if(_tempFloat<101){ - MIBLEsensors[_slot].hum=_tempFloat; - DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); - } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _beacon.hum); + _tempFloat=(float)(_beacon.hum)/10.0f; + if(_tempFloat<101){ + MIBLEsensors[_slot].hum=_tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _beacon.hum); break; case 0x07: - MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff; - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); + MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff; + if(MIBLEsensors[_slot].type==MJYD2S){ + MIBLEsensors[_slot].eventType = 2; //No PIR + MIBLEsensors[_slot].shallSendMQTT = 1; + MIBLEsensors[_slot].lastTime = millis(); + MI32triggerTele(); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); break; case 0x08: - _tempFloat =(float)_beacon.moist; - if(_tempFloat<100){ - MIBLEsensors[_slot].moisture=_tempFloat; - DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); - } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); + _tempFloat =(float)_beacon.moist; + if(_tempFloat<100){ + MIBLEsensors[_slot].moisture=_tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); break; case 0x09: - _tempFloat=(float)(_beacon.fert); - if(_tempFloat<65535){ // ??? - MIBLEsensors[_slot].fertility=_tempFloat; - DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); - } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); + _tempFloat=(float)(_beacon.fert); + if(_tempFloat<65535){ // ??? + MIBLEsensors[_slot].fertility=_tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); break; case 0x0a: - if(_beacon.bat<101){ - MIBLEsensors[_slot].bat = _beacon.bat; - DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); - } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode a: U8: %u %%"), _beacon.bat); + if(_beacon.bat<101){ + MIBLEsensors[_slot].bat = _beacon.bat; + DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode a: U8: %u %%"), _beacon.bat); break; case 0x0d: - _tempFloat=(float)(_beacon.HT.temp)/10.0f; - if(_tempFloat<60){ - MIBLEsensors[_slot].temp = _tempFloat; - DEBUG_SENSOR_LOG(PSTR("Mode d: temp updated")); - } - _tempFloat=(float)(_beacon.HT.hum)/10.0f; - if(_tempFloat<100){ - MIBLEsensors[_slot].hum = _tempFloat; - DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated")); - } - // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); + _tempFloat=(float)(_beacon.HT.temp)/10.0f; + if(_tempFloat<60){ + MIBLEsensors[_slot].temp = _tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode d: temp updated")); + } + _tempFloat=(float)(_beacon.HT.hum)/10.0f; + if(_tempFloat<100){ + MIBLEsensors[_slot].hum = _tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); + break; +#ifdef USE_MI_DECRYPTION + case 0x0f: + if (_beacon.ten!=0) break; + MIBLEsensors[_slot].eventType = 1; //PIR + MIBLEsensors[_slot].shallSendMQTT = 1; + MIBLEsensors[_slot].lastTime = millis(); + MIBLEsensors[_slot].events++; + MIBLEsensors[_slot].lux = _beacon.lux; + MIBLEsensors[_slot].NMT = 0; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("PIR: primary"),MIBLEsensors[_slot].lux ); + MI32triggerTele(); + break; + case 0x17: + MIBLEsensors[_slot].NMT = _beacon.NMT; + MIBLEsensors[_slot].eventType = 3; // NMT + MIBLEsensors[_slot].shallSendMQTT = 1; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 17: NMT: %u seconds"), _beacon.NMT); + MI32triggerTele(); + break; +#endif //USE_MI_DECRYPTION + default: + if (MIBLEsensors[_slot].type==NLIGHT){ + MIBLEsensors[_slot].eventType = 1; //PIR + MIBLEsensors[_slot].shallSendMQTT = 1; + MIBLEsensors[_slot].events++; + MIBLEsensors[_slot].NMT = 0; + MIBLEsensors[_slot].lastTime = millis(); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("PIR: primary"),MIBLEsensors[_slot].lux ); + MI32triggerTele(); + } break; } } @@ -928,8 +1157,8 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot){ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6]){ // no MiBeacon uint8_t _addr[6]; memcpy(_addr,addr,6); - uint32_t _slot = MIBLEgetSensorSlot(_addr, 0x0576); // This must be hard-coded, no object-id in Cleargrass-packet - DEBUG_SENSOR_LOG(PSTR("MI32: Sensor slot: %u"), _slot); + uint32_t _slot = MIBLEgetSensorSlot(_addr, 0x0576, 0); // This must be hard-coded, no object-id in Cleargrass-packet, we have no packet counter too + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); if(_slot==0xff) return; cg_packet_t _packet; memcpy((char*)&_packet,_buf,sizeof(_packet)); @@ -960,16 +1189,15 @@ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6]){ // no M } void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6]) { - if(bufsize<10) { + if(bufsize<9) { //9 is from the NLIGHT return; } - char * _pos = buf; - uint16_t _type= _pos[3]*256 + _pos[2]; + uint16_t _type= buf[3]*256 + buf[2]; // AddLog_P2(LOG_LEVEL_INFO, PSTR("%02x %02x %02x %02x"),(uint8_t)buf[0], (uint8_t)buf[1],(uint8_t)buf[2],(uint8_t)buf[3]); uint8_t _addr[6]; memcpy(_addr,addr,6); - uint16_t _slot = MIBLEgetSensorSlot(_addr, _type); - if(_slot!=0xff) MI32parseMiBeacon(_pos,_slot); + uint16_t _slot = MIBLEgetSensorSlot(_addr, _type, buf[4]); + if(_slot!=0xff) MI32parseMiBeacon(buf,_slot,bufsize); } /***********************************************************************\ @@ -988,7 +1216,7 @@ void MI32readHT_LY(char *_buf){ _tempFloat=(float)(LYWSD0x_HT.temp)/100.0f; if(_tempFloat<60){ MIBLEsensors[_slot].temp=_tempFloat; - MIBLEsensors[_slot].showedUp=255; // this sensor is real + // MIBLEsensors[_slot].showedUp=255; // this sensor is real } _tempFloat=(float)LYWSD0x_HT.hum; if(_tempFloat<100){ @@ -996,7 +1224,7 @@ void MI32readHT_LY(char *_buf){ DEBUG_SENSOR_LOG(PSTR("LYWSD0x: hum updated")); } if (MIBLEsensors[_slot].type == LYWSD03MMC){ - MIBLEsensors[_slot].volt = LYWSD0x_HT.volt; + MIBLEsensors[_slot].bat = ((float)LYWSD0x_HT.volt-2100.0f)/12.0f; } } } @@ -1009,29 +1237,17 @@ bool MI32readBat(char *_buf){ DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); if(_buf[0]<101){ MIBLEsensors[_slot].bat=_buf[0]; + if(MIBLEsensors[_slot].type==FLORA){ + memcpy(MIBLEsensors[_slot].firmware, _buf+2, 5); + MIBLEsensors[_slot].firmware[5] = '\0'; + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Firmware: %s"),D_CMND_MI32,MIBLEsensors[_slot].firmware); + } return true; } } return false; } -bool MI32readFirmwareFLORA(char *_buf){ - DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_MI32,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); - if(_buf[0] != 0){ - char _firmware[5]; // FLORA send 5 byte for firmware version - strncpy(_firmware, _buf+2, 5); - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Firmware: %s"),D_CMND_MI32,_firmware); - - uint32_t _slot = MI32.state.sensor; - DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); - - memcpy(MIBLEsensors[_slot].firmware, _firmware, 5); - MIBLEsensors[_slot].firmware[5] = '\0'; - return true; - } - return false; -} - /** * @brief Main loop of the driver, "high level"-loop * @@ -1041,6 +1257,12 @@ void MI32EverySecond(bool restart){ static uint32_t _counter = MI32.period - 15; static uint32_t _nextSensorSlot = 0; + for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { + if(MIBLEsensors[i].type==NLIGHT || MIBLEsensors[i].type==MJYD2S){ + MIBLEsensors[i].NMT++; + } + } + if(restart){ _counter = 0; MI32.mode.canScan = 0; @@ -1084,22 +1306,25 @@ void MI32EverySecond(bool restart){ } if(_counter==0) { + MI32.state.sensor = _nextSensorSlot; AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u of %u"),D_CMND_MI32, MI32.state.sensor, MIBLEsensors.size()-1); MI32.mode.canScan = 0; - if (MI32.mode.runningScan|| MI32.mode.connected || MI32.mode.willConnect) return; + // if (MI32.mode.runningScan|| MI32.mode.connected || MI32.mode.willConnect) return; + if (MI32.mode.connected || MI32.mode.willConnect) return; _nextSensorSlot++; MI32.mode.canConnect = 1; if(MI32.mode.connected == 0) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("will connect to %s"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("will connect to %s"),kMI32DeviceType[MIBLEsensors[MI32.state.sensor].type-1] ); if (MI32.mode.shallReadBatt) { MI32StartTask(MI32_TASK_BATT); - } + } +#ifndef USE_MI_DECRYPTION // turn off connections, because we only listen to advertisements else{ MI32StartTask(MI32_TASK_CONN); - } - + } +#endif //USE_MI_DECRYPTION } if (_nextSensorSlot>(MIBLEsensors.size()-1)) { _nextSensorSlot= 0; @@ -1191,6 +1416,14 @@ bool MI32Cmd(void) { XdrvMailbox.payload = MI32.period; Response_P(S_JSON_MI32_COMMAND, command, ""); break; +#ifdef USE_MI_DECRYPTION + case CMND_MI32_KEY: + if (XdrvMailbox.data_len==44){ // a KEY-MAC-string + MI32AddKey(XdrvMailbox.data); + Response_P(S_JSON_MI32_COMMAND, command, XdrvMailbox.data); + } + break; +#endif //USE_MI_DECRYPTION default: // else for Unknown command serviced = false; @@ -1211,23 +1444,36 @@ const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 {m}%u%s / %u{e}"; const char HTTP_MI32_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; const char HTTP_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{m}%s V{e}"; +const char HTTP_LASTBUTTON[] PROGMEM = "{s}%s Last Button{m}%u {e}"; +const char HTTP_EVENTS[] PROGMEM = "{s}%s Events{m}%u {e}"; +const char HTTP_NMT[] PROGMEM = "{s}%s No motion{m}> %u seconds{e}"; const char HTTP_MI32_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%u us/cm{e}"; const char HTTP_MI32_HL[] PROGMEM = "{s}
    {m}
    {e}"; void MI32Show(bool json) { - if (json) { + if(!MI32.mode.triggeredTele){ + MI32.mode.shallClearResults=1; + } for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { + switch(MIBLEsensors[i].type){ + case YEERC: + if(MIBLEsensors[i].shallSendMQTT==0) continue; + break; + default: + if(MI32.mode.triggeredTele) continue; + break; + } /* char slave[33]; snprintf_P(slave, sizeof(slave), PSTR("%s-%02x%02x%02x"), - kMI32SlaveType[MIBLEsensors[i].type-1],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]); + kMI32DeviceType[MIBLEsensors[i].type-1],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]); ResponseAppend_P(PSTR(",\"%s\":{"), slave); */ ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"), - kMI32SlaveType[MIBLEsensors[i].type-1], - MIBLEsensors[i].serial[3], MIBLEsensors[i].serial[4], MIBLEsensors[i].serial[5]); + kMI32DeviceType[MIBLEsensors[i].type-1], + MIBLEsensors[i].MAC[3], MIBLEsensors[i].MAC[4], MIBLEsensors[i].MAC[5]); if (MIBLEsensors[i].type == FLORA) { if (!isnan(MIBLEsensors[i].temp)) { @@ -1247,25 +1493,35 @@ void MI32Show(bool json) if (!isnan(MIBLEsensors[i].fertility)) { ResponseAppend_P(PSTR(",\"Fertility\":%f"), MIBLEsensors[i].fertility); } + ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); } if (MIBLEsensors[i].type > FLORA){ if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum); } } +#ifdef USE_MI_DECRYPTION + if (MIBLEsensors[i].type == MJYD2S){ + ResponseAppend_P(PSTR("\"Events\":%u"),MIBLEsensors[i].events); + if(MIBLEsensors[i].shallSendMQTT && MIBLEsensors[i].eventType<3) ResponseAppend_P(PSTR(",\"PIR\":%u"), 2 - MIBLEsensors[i].eventType); + if(MIBLEsensors[i].eventType==3) ResponseAppend_P(PSTR(",\"NMT\":%u"), MIBLEsensors[i].NMT); + MIBLEsensors[i].eventType=0; + if(MIBLEsensors[i].lux!=0x0ffffff) ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); + } +#endif //USE_MI_DECRYPTION + if (MIBLEsensors[i].type == NLIGHT){ + ResponseAppend_P(PSTR("\"Events\":%u"),MIBLEsensors[i].events); + if(MIBLEsensors[i].shallSendMQTT) ResponseAppend_P(PSTR(",\"PIR\":1")); + } + if (MIBLEsensors[i].type == YEERC){ + if(MIBLEsensors[i].shallSendMQTT) ResponseAppend_P(PSTR("\"Btn\":%u"),MIBLEsensors[i].Btn); + } if (MIBLEsensors[i].bat != 0x00) { // this is the error code -> no battery - if (MIBLEsensors[i].type != LYWSD03MMC) { - ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); - } else { - char voltage[FLOATSZ]; - dtostrfd((MIBLEsensors[i].volt)/1000.0f, Settings.flag2.voltage_resolution, voltage); - ResponseAppend_P(PSTR(",\"" D_VOLTAGE "\":%s"), voltage); - } - if (MIBLEsensors[i].type == FLORA) { //actually we can only read FLORA - ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); - } + ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); } ResponseAppend_P(PSTR("}")); + MIBLEsensors[i].shallSendMQTT = 0; + MI32.mode.triggeredTele = 0; } #ifdef USE_WEBSERVER } else { @@ -1285,36 +1541,41 @@ void MI32Show(bool json) WSContentSend_PD(HTTP_MI32, i+1,stemp,MIBLEsensors.size()); for (i; i no valid value - WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); + WSContentSend_PD(HTTP_SNS_TEMP, kMI32DeviceType[MIBLEsensors[i].type-1], temperature, TempUnit()); } if (!isnan(MIBLEsensors[i].moisture)) { - WSContentSend_PD(HTTP_SNS_MOISTURE, kMI32SlaveType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].moisture)); + WSContentSend_PD(HTTP_SNS_MOISTURE, kMI32DeviceType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].moisture)); } if (!isnan(MIBLEsensors[i].fertility)) { - WSContentSend_PD(HTTP_MI32_FLORA_DATA, kMI32SlaveType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].fertility)); + WSContentSend_PD(HTTP_MI32_FLORA_DATA, kMI32DeviceType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].fertility)); } } if (MIBLEsensors[i].type>FLORA) { // everything "above" Flora if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { - WSContentSend_THD(kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum); + WSContentSend_THD(kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum); } } +#ifdef USE_MI_DECRYPTION + if (MIBLEsensors[i].type==NLIGHT || MIBLEsensors[i].type==MJYD2S) { +#else + if (MIBLEsensors[i].type==NLIGHT) { +#endif //USE_MI_DECRYPTION + WSContentSend_PD(HTTP_EVENTS, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].events); + if(MIBLEsensors[i].NMT>0) WSContentSend_PD(HTTP_NMT, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].NMT); + } + if (MIBLEsensors[i].lux!=0x00ffffff) { // this is the error code -> no valid value + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); + } if(MIBLEsensors[i].bat!=0x00){ - if (MIBLEsensors[i].type != LYWSD03MMC) { - WSContentSend_PD(HTTP_BATTERY, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat); - } else { - char voltage[FLOATSZ]; - dtostrfd((MIBLEsensors[i].volt)/1000.0f, Settings.flag2.voltage_resolution, voltage); - WSContentSend_PD(HTTP_VOLTAGE, kMI32SlaveType[MIBLEsensors[i].type-1], voltage); - } + WSContentSend_PD(HTTP_BATTERY, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat); + } + if (MIBLEsensors[i].type==YEERC){ + WSContentSend_PD(HTTP_LASTBUTTON, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].Btn); } } _counter++; @@ -1360,4 +1621,4 @@ bool Xsns62(uint8_t function) return result; } #endif // USE_MI_ESP32 -#endif // ESP32 \ No newline at end of file +#endif // ESP32 From 96d37ec535846232e63f7ecf09d1b4e3849255b5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 12 Jul 2020 18:53:57 +0200 Subject: [PATCH 453/581] Add Rotary features Add On/Off functionality to rotary dial (#8263) --- tasmota/support_button.ino | 2 +- tasmota/support_rotary.ino | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/tasmota/support_button.ino b/tasmota/support_button.ino index 2d7c6a415..e6e6e27ea 100644 --- a/tasmota/support_button.ino +++ b/tasmota/support_button.ino @@ -303,7 +303,7 @@ void ButtonHandler(void) } } #ifdef ROTARY_V1 - if (!((0 == button_index) && RotaryButtonPressed())) { + if (!RotaryButtonPressed(button_index)) { #endif if (!Settings.flag3.mqtt_buttons && single_press && SendKey(KEY_BUTTON, button_index + Button.press_counter[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set // Success diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index cfe549a5f..3367b70d4 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -91,13 +91,6 @@ struct ROTARY { void update_rotary(void) ICACHE_RAM_ATTR; void update_rotary(void) { if (Rotary.busy) { return; } - bool powered_on = (power); -#ifdef USE_LIGHT - if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control - powered_on = (LightPowerIRAM()); - } -#endif // USE_LIGHT - if (!powered_on) { return; } #ifdef ROTARY_OPTION1 // https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h @@ -212,8 +205,10 @@ void update_rotary(void) { #endif // ROTARY_OPTION3 } -bool RotaryButtonPressed(void) { +//bool RotaryButtonPressed(void) { +bool RotaryButtonPressed(uint32_t button_index) { if (!Rotary.present) { return false; } + if (0 != button_index) { return false; } bool powered_on = (power); #ifdef USE_LIGHT @@ -254,6 +249,13 @@ void RotaryHandler(void) { Rotary.timeout--; if (!Rotary.timeout) { Rotary.direction = 0; +#ifdef USE_LIGHT + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + LightState(0); + MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_DIMMER)); + XdrvRulesProcess(); + } +#endif // USE_LIGHT } } if (Rotary.last_position == Rotary.position) { return; } From 41d0f3117fb26a1c2f9c1803b3435a637b0db245 Mon Sep 17 00:00:00 2001 From: Staars Date: Sun, 12 Jul 2020 21:12:42 +0200 Subject: [PATCH 454/581] add MHO-C401 --- tasmota/xsns_61_MI_NRF24.ino | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index c24bd07da..44456a6a7 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -83,8 +83,9 @@ #define NLIGHT 7 #define MJYD2S 8 #define YEERC 9 +#define MHOC401 10 -#define MI_TYPES 9 //count this manually +#define MI_TYPES 10 //count this manually #define D_CMND_NRF "NRF" @@ -119,7 +120,8 @@ const uint16_t kMINRFDeviceID[MI_TYPES]={ 0x0098, // Flora 0x0576, // CGD1 0x03dd, // NLIGHT 0x07f6, // MJYD2S - 0x0153 // yee-rc + 0x0153, // yee-rc + 0x0387 // MHO-C401 }; const char kMINRFDeviceType1[] PROGMEM = "Flora"; @@ -131,7 +133,8 @@ const char kMINRFDeviceType6[] PROGMEM = "CGD1"; const char kMINRFDeviceType7[] PROGMEM = "NLIGHT"; const char kMINRFDeviceType8[] PROGMEM = "MJYD2S"; const char kMINRFDeviceType9[] PROGMEM = "YEERC"; -const char * kMINRFDeviceType[] PROGMEM = {kMINRFDeviceType1,kMINRFDeviceType2,kMINRFDeviceType3,kMINRFDeviceType4,kMINRFDeviceType5,kMINRFDeviceType6,kMINRFDeviceType7,kMINRFDeviceType8,kMINRFDeviceType9}; +const char kMINRFDeviceType10[] PROGMEM = "MHOC401"; +const char * kMINRFDeviceType[] PROGMEM = {kMINRFDeviceType1,kMINRFDeviceType2,kMINRFDeviceType3,kMINRFDeviceType4,kMINRFDeviceType5,kMINRFDeviceType6,kMINRFDeviceType7,kMINRFDeviceType8,kMINRFDeviceType9,kMINRFDeviceType10}; // PDU's or different channels 37-39 const uint32_t kMINRFFloPDU[3] = {0x3eaa857d,0xef3b8730,0x71da7b46}; @@ -411,7 +414,7 @@ bool MINRFreceivePacket(void) case 1: case 3: MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_A[MINRF.currentChan]); // "flora" mode, "LYWSD02" mode break; - case 2: case 4: case 5: case 6: + case 2: case 4: case 5: case 6: case MHOC401: MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "MJ_HT_V1" mode, LYWSD03" mode, "CGG1" mode, "CGD1" mode break; case 9: @@ -919,7 +922,7 @@ void MINRFchangePacketModeTo(uint8_t _mode) { case 3: // special LYWSD02 packet NRF24radio.openReadingPipe(0,kMINRFL2PDU[_nextchannel]);// 95 fe 70 20 -> LYWSD02 break; - case 4: // special LYWSD03 packet + case 4: case MHOC401: // special LYWSD03 packet, MHOC401 has the same NRF24radio.openReadingPipe(0,kMINRFL3PDU[_nextchannel]);// 95 fe 58 58 -> LYWSD03 (= encrypted data message) break; case 5: // special CGG1 packet @@ -1068,7 +1071,7 @@ void MINRFhandleMiBeaconPacket(void){ memcpy((uint8_t*)&MINRF.buffer.miBeacon.type,MINRFtempBuf, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 break; #ifdef USE_MI_DECRYPTION - case LYWSD03: + case LYWSD03: case MHOC401: decryptRet = MINRFdecryptPacket((char*)&MINRF.buffer); //start with PID if(decryptRet==1) _sensorVec->showedUp=255; // if decryption worked, this must be a valid sensor break; @@ -1324,7 +1327,7 @@ void MINRF_EVERY_50_MSECOND() { // Every 50mseconds } else MINRFhandleScan(); break; - case FLORA: case MJ_HT_V1: case LYWSD02: case CGG1: case LYWSD03: case YEERC: + case FLORA: case MJ_HT_V1: case LYWSD02: case CGG1: case LYWSD03: case YEERC: case MHOC401: MINRFhandleMiBeaconPacket(); break; case CGD1: From 4f10a15a6530e0368881bb2f6f93ad246a970004 Mon Sep 17 00:00:00 2001 From: d0m1n1qu3 Date: Sun, 12 Jul 2020 21:19:40 +0200 Subject: [PATCH 455/581] shift the init or the variable firmware to FLORA only because of changes from Staars --- tasmota/xsns_62_MI_ESP32.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index e86f93fff..b110cb57f 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -520,13 +520,13 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter) _newSensor.temp =NAN; _newSensor.bat=0x00; _newSensor.rssi=0xffff; - _newSensor.firmware[0]='\0'; _newSensor.lux = 0x00ffffff; switch (_type) { case FLORA: _newSensor.moisture =NAN; _newSensor.fertility =NAN; + _newSensor.firmware[0]='\0'; break; case 2: case 3: case 4: case 5: case 6: _newSensor.hum=NAN; From 84ee6393a508a50d397ba90e0b67bb213b304c25 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 13 Jul 2020 15:10:23 +0200 Subject: [PATCH 456/581] Add second rotary support Add second rotary support default used for CW light control when first rotary is used for RGB light control (#8864) --- tasmota/support_rotary.ino | 330 +++++++++++-------------------- tasmota/support_tasmota.ino | 2 +- tasmota/tasmota.h | 1 + tasmota/tasmota_template.h | 12 +- tasmota/tasmota_template_ESP32.h | 20 +- tasmota/xdrv_04_light.ino | 26 +-- 6 files changed, 147 insertions(+), 244 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 3367b70d4..d58ebd560 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -34,207 +34,98 @@ \*********************************************************************************************/ #ifndef ROTARY_MAX_STEPS -#define ROTARY_MAX_STEPS 10 // Rotary step boundary +#define ROTARY_MAX_STEPS 10 // Rotary step boundary #endif -//#define ROTARY_OPTION1 // Up to 4 interrupts and pulses per step -//#define ROTARY_OPTION2 // Up to 4 interrupts but 1 pulse per step -#define ROTARY_OPTION3 // 1 interrupt and pulse per step - -#ifdef ROTARY_OPTION1 -// up to 4 pulses per step -const uint8_t rotary_dimmer_increment = 100 / (ROTARY_MAX_STEPS * 3); // Dimmer 1..100 = 100 -const uint8_t rotary_ct_increment = 350 / (ROTARY_MAX_STEPS * 3); // Ct 153..500 = 347 -const uint8_t rotary_color_increment = 360 / (ROTARY_MAX_STEPS * 3); // Hue 0..359 = 360 -#endif // ROTARY_OPTION1 - -#ifdef ROTARY_OPTION2 // 1 pulse per step -const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100 -const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347 -const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 -#endif // ROTARY_OPTION2 +const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100 +const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347 +const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 -#ifdef ROTARY_OPTION3 -// 1 pulse per step -const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100 -const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347 -const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 -#endif // ROTARY_OPTION3 - -const uint8_t ROTARY_TIMEOUT = 10; // 10 * RotaryHandler() call which is usually 10 * 0.05 seconds +const uint8_t ROTARY_TIMEOUT = 10; // 10 * RotaryHandler() call which is usually 10 * 0.05 seconds struct ROTARY { -#ifdef ROTARY_OPTION1 - uint8_t state = 0; -#endif // ROTARY_OPTION1 -#ifdef ROTARY_OPTION2 - uint16_t store; - uint8_t prev_next_code; -#endif // ROTARY_OPTION2 -#ifdef ROTARY_OPTION3 + bool present = false; +} Rotary; + +struct ENCODER { uint32_t debounce = 0; -#endif // ROTARY_OPTION3 int8_t abs_position1 = 0; int8_t abs_position2 = 0; - int8_t direction = 0; // Control consistent direction - uint8_t present = 0; + int8_t direction = 0; // Control consistent direction + int8_t pin = -1; uint8_t position = 128; uint8_t last_position = 128; - uint8_t timeout = 0; // Disallow direction change within 0.5 second + uint8_t timeout = 0; // Disallow direction change within 0.5 second bool changed = false; bool busy = false; -} Rotary; +} Encoder[MAX_ROTARIES]; /********************************************************************************************/ -void update_rotary(void) ICACHE_RAM_ATTR; -void update_rotary(void) { - if (Rotary.busy) { return; } +void ICACHE_RAM_ATTR RotaryIsr(uint32_t index) { + if (Encoder[index].busy) { return; } -#ifdef ROTARY_OPTION1 - // https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h -/* - uint8_t p1val = digitalRead(Pin(GPIO_ROT1A)); - uint8_t p2val = digitalRead(Pin(GPIO_ROT1B)); - uint8_t state = Rotary.state & 3; - if (p1val) { state |= 4; } - if (p2val) { state |= 8; } - Rotary.state = (state >> 2); - switch (state) { - case 1: case 7: case 8: case 14: - Rotary.position++; - return; - case 2: case 4: case 11: case 13: - Rotary.position--; - return; - case 3: case 12: - Rotary.position += 2; - return; - case 6: case 9: - Rotary.position -= 2; - return; - } -*/ - uint8_t p1val = digitalRead(Pin(GPIO_ROT1A)); - uint8_t p2val = digitalRead(Pin(GPIO_ROT1B)); - uint8_t state = Rotary.state & 3; - if (p1val) { state |= 4; } - if (p2val) { state |= 8; } - Rotary.state = (state >> 2); - int direction = 0; - int multiply = 1; - switch (state) { - case 3: case 12: - multiply = 2; - case 1: case 7: case 8: case 14: - direction = 1; - break; - case 6: case 9: - multiply = 2; - case 2: case 4: case 11: case 13: - direction = -1; - break; - } - if ((0 == Rotary.direction) || (direction == Rotary.direction)) { - Rotary.position += (direction * multiply); - Rotary.direction = direction; - } -#endif // ROTARY_OPTION1 - -#ifdef ROTARY_OPTION2 - // https://github.com/FrankBoesing/EncoderBounce/blob/master/EncoderBounce.h -/* - const uint16_t rot_enc = 0b0110100110010110; - - uint8_t p1val = digitalRead(Pin(GPIO_ROT1B)); - uint8_t p2val = digitalRead(Pin(GPIO_ROT1A)); - uint8_t t = Rotary.prev_next_code; - t <<= 2; - if (p1val) { t |= 0x02; } - if (p2val) { t |= 0x01; } - t &= 0x0f; - Rotary.prev_next_code = t; - - // If valid then store as 16 bit data. - if (rot_enc & (1 << t)) { - Rotary.store = (Rotary.store << 4) | Rotary.prev_next_code; - if (Rotary.store == 0xd42b) { Rotary.position++; } - else if (Rotary.store == 0xe817) { Rotary.position--; } - else if ((Rotary.store & 0xff) == 0x2b) { Rotary.position--; } - else if ((Rotary.store & 0xff) == 0x17) { Rotary.position++; } - } -*/ - const uint16_t rot_enc = 0b0110100110010110; - - uint8_t p1val = digitalRead(Pin(GPIO_ROT1B)); - uint8_t p2val = digitalRead(Pin(GPIO_ROT1A)); - uint8_t t = Rotary.prev_next_code; - t <<= 2; - if (p1val) { t |= 0x02; } - if (p2val) { t |= 0x01; } - t &= 0x0f; - Rotary.prev_next_code = t; - - // If valid then store as 16 bit data. - if (rot_enc & (1 << t)) { - Rotary.store = (Rotary.store << 4) | Rotary.prev_next_code; - int direction = 0; - if (Rotary.store == 0xd42b) { direction = 1; } - else if (Rotary.store == 0xe817) { direction = -1; } - else if ((Rotary.store & 0xff) == 0x2b) { direction = -1; } - else if ((Rotary.store & 0xff) == 0x17) { direction = 1; } - if ((0 == Rotary.direction) || (direction == Rotary.direction)) { - Rotary.position += direction; - Rotary.direction = direction; - } - } -#endif // ROTARY_OPTION2 - -#ifdef ROTARY_OPTION3 - // Theo Arends uint32_t time = micros(); - if (Rotary.debounce < time) { - int direction = (digitalRead(Pin(GPIO_ROT1B))) ? 1 : -1; - if ((0 == Rotary.direction) || (direction == Rotary.direction)) { - Rotary.position += direction; - Rotary.direction = direction; + if (Encoder[index].debounce < time) { + int direction = (digitalRead(Encoder[index].pin)) ? -1 : 1; + if ((0 == Encoder[index].direction) || (direction == Encoder[index].direction)) { + Encoder[index].position += direction; + Encoder[index].direction = direction; } - Rotary.debounce = time +20; // Experimental debounce + Encoder[index].debounce = time +50; // Experimental debounce in microseconds } -#endif // ROTARY_OPTION3 } -//bool RotaryButtonPressed(void) { +void ICACHE_RAM_ATTR RotaryIsr1(void) { + RotaryIsr(0); +} + +void ICACHE_RAM_ATTR RotaryIsr2(void) { + RotaryIsr(1); +} + bool RotaryButtonPressed(uint32_t button_index) { if (!Rotary.present) { return false; } - if (0 != button_index) { return false; } - bool powered_on = (power); + for (uint32_t index = 0; index < MAX_ROTARIES; index++) { + if (-1 == Encoder[index].pin) { continue; } + if (index != button_index) { continue; } + + bool powered_on = (power); #ifdef USE_LIGHT - if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control - powered_on = LightPower(); - } + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + powered_on = LightPower(); + } #endif // USE_LIGHT - if (Rotary.changed && powered_on) { - Rotary.changed = false; // Color (temp) changed, no need to turn of the light - return true; + if (Encoder[index].changed && powered_on) { + Encoder[index].changed = false; // Color (temp) changed, no need to turn of the light + return true; + } + return false; } return false; } void RotaryInit(void) { - Rotary.present = 0; - if (PinUsed(GPIO_ROT1A) && PinUsed(GPIO_ROT1B)) { - Rotary.present++; - pinMode(Pin(GPIO_ROT1A), INPUT_PULLUP); - pinMode(Pin(GPIO_ROT1B), INPUT_PULLUP); -#ifdef ROTARY_OPTION3 - attachInterrupt(Pin(GPIO_ROT1A), update_rotary, RISING); -#else - attachInterrupt(Pin(GPIO_ROT1A), update_rotary, CHANGE); - attachInterrupt(Pin(GPIO_ROT1B), update_rotary, CHANGE); -#endif + Rotary.present = false; + for (uint32_t index = 0; index < MAX_ROTARIES; index++) { +#ifdef ESP8266 + uint32_t idx = index *2; +#else // ESP32 + uint32_t idx = index; +#endif // ESP8266 or ESP32 + if (PinUsed(GPIO_ROT1A, idx) && PinUsed(GPIO_ROT1B, idx)) { + Encoder[index].pin = Pin(GPIO_ROT1B, idx); + pinMode(Encoder[index].pin, INPUT_PULLUP); + pinMode(Pin(GPIO_ROT1A, idx), INPUT_PULLUP); + if (0 == index) { + attachInterrupt(Pin(GPIO_ROT1A, idx), RotaryIsr1, FALLING); + } else { + attachInterrupt(Pin(GPIO_ROT1A, idx), RotaryIsr2, FALLING); + } + } + Rotary.present |= (Encoder[index].pin > -1); } } @@ -245,63 +136,80 @@ void RotaryInit(void) { void RotaryHandler(void) { if (!Rotary.present) { return; } - if (Rotary.timeout) { - Rotary.timeout--; - if (!Rotary.timeout) { - Rotary.direction = 0; + for (uint32_t index = 0; index < MAX_ROTARIES; index++) { + if (-1 == Encoder[index].pin) { continue; } + + if (Encoder[index].timeout) { + Encoder[index].timeout--; + if (!Encoder[index].timeout) { #ifdef USE_LIGHT - if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control - LightState(0); - MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_DIMMER)); - XdrvRulesProcess(); - } + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + ResponseLightState(0); + MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_STATE)); + XdrvRulesProcess(); + } #endif // USE_LIGHT + Encoder[index].direction = 0; + } } - } - if (Rotary.last_position == Rotary.position) { return; } - Rotary.busy = true; + if (Encoder[index].last_position == Encoder[index].position) { continue; } + Encoder[index].busy = true; - Rotary.timeout = ROTARY_TIMEOUT; // Prevent fast direction changes within 0.5 second + Encoder[index].timeout = ROTARY_TIMEOUT; // Prevent fast direction changes within 0.5 second - int rotary_position = Rotary.position - Rotary.last_position; + int rotary_position = Encoder[index].position - Encoder[index].last_position; - if (Settings.save_data && (save_data_counter < 2)) { - save_data_counter = 2; // Postpone flash writes while rotary is turned - } + if (Settings.save_data && (save_data_counter < 2)) { + save_data_counter = 2; // Postpone flash writes while rotary is turned + } - bool button_pressed = (Button.hold_timer[0]); // Button1 is pressed: set color temperature - if (button_pressed) { Rotary.changed = true; } -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Button1 %d, Position %d"), button_pressed, rotary_position); + bool button_pressed = (Button.hold_timer[index]); // Button is pressed: set color temperature + if (button_pressed) { Encoder[index].changed = true; } +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Button1 %d, Position %d"), button_pressed, rotary_position); #ifdef USE_LIGHT - if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control - if (button_pressed) { - if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { - LightColorOffset(rotary_position * rotary_color_increment); + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + bool second_rotary = (Encoder[1].pin > -1); + if (0 == index) { // Rotary1 + if (button_pressed) { + if (second_rotary) { // Color RGB + LightColorOffset(rotary_position * rotary_color_increment); + } else { // Color Temperature or Color RGB + if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { + LightColorOffset(rotary_position * rotary_color_increment); + } + } + } else { // Dimmer RGBCW or RGB only if second rotary + LightDimmerOffset(second_rotary ? 1 : 0, rotary_position * rotary_dimmer_increment); + } + } else { // Rotary2 + if (button_pressed) { // Color Temperature + LightColorTempOffset(rotary_position * rotary_ct_increment); + } else { // Dimmer CW + LightDimmerOffset(2, rotary_position * rotary_dimmer_increment); + } } } else { - LightDimmerOffset(rotary_position * rotary_dimmer_increment); - } - } else { #endif // USE_LIGHT - if (button_pressed) { - Rotary.abs_position2 += rotary_position; - if (Rotary.abs_position2 < 0) { Rotary.abs_position2 = 0; } - if (Rotary.abs_position2 > ROTARY_MAX_STEPS) { Rotary.abs_position2 = ROTARY_MAX_STEPS; } - } else { - Rotary.abs_position1 += rotary_position; - if (Rotary.abs_position1 < 0) { Rotary.abs_position1 = 0; } - if (Rotary.abs_position1 > ROTARY_MAX_STEPS) { Rotary.abs_position1 = ROTARY_MAX_STEPS; } - } - Response_P(PSTR("{\"Rotary1\":{\"Pos1\":%d,\"Pos2\":%d}}"), Rotary.abs_position1, Rotary.abs_position2); - XdrvRulesProcess(); + if (button_pressed) { + Encoder[index].abs_position2 += rotary_position; + if (Encoder[index].abs_position2 < 0) { Encoder[index].abs_position2 = 0; } + if (Encoder[index].abs_position2 > ROTARY_MAX_STEPS) { Encoder[index].abs_position2 = ROTARY_MAX_STEPS; } + } else { + Encoder[index].abs_position1 += rotary_position; + if (Encoder[index].abs_position1 < 0) { Encoder[index].abs_position1 = 0; } + if (Encoder[index].abs_position1 > ROTARY_MAX_STEPS) { Encoder[index].abs_position1 = ROTARY_MAX_STEPS; } + } + Response_P(PSTR("{\"Rotary%d\":{\"Pos1\":%d,\"Pos2\":%d}}"), index +1, Encoder[index].abs_position1, Encoder[index].abs_position2); + XdrvRulesProcess(); #ifdef USE_LIGHT - } + } #endif // USE_LIGHT - Rotary.last_position = 128; - Rotary.position = 128; - Rotary.busy = false; + Encoder[index].last_position = 128; + Encoder[index].position = 128; + Encoder[index].busy = false; + } } #endif // ROTARY_V1 diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 68edd6a7a..70d7f66af 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -663,7 +663,7 @@ void MqttShowState(void) for (uint32_t i = 1; i <= devices_present; i++) { #ifdef USE_LIGHT if ((LightDevice()) && (i >= LightDevice())) { - if (i == LightDevice()) { LightState(1); } // call it only once + if (i == LightDevice()) { ResponseLightState(1); } // call it only once } else { #endif ResponseAppend_P(PSTR(",\"%s\":\"%s\""), GetPowerDevice(stemp1, i, sizeof(stemp1), Settings.flag.device_index_enable), // SetOption26 - Switch between POWER or POWER1 diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 4eceddb5c..21a7b5b00 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -84,6 +84,7 @@ const uint8_t MAX_GROUP_TOPICS = 4; // Max number of Group Topics const uint8_t MAX_DEV_GROUP_NAMES = 4; // Max number of Device Group names const uint8_t MAX_HUE_DEVICES = 15; // Max number of Philips Hue device per emulation +const uint8_t MAX_ROTARIES = 2; // Max number of Rotary Encoders const char MQTT_TOKEN_PREFIX[] PROGMEM = "%prefix%"; // To be substituted by mqtt_prefix[x] const char MQTT_TOKEN_TOPIC[] PROGMEM = "%topic%"; // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index bd1c009de..d287d7e01 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -373,6 +373,12 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_SWT7_NP, GPIO_SWT8, GPIO_SWT8_NP, +#ifdef ROTARY_V1 + GPIO_ROT1A, // Rotary switch1 A Pin + GPIO_ROT1B, // Rotary switch1 B Pin + GPIO_ROT2A, // Rotary switch2 A Pin + GPIO_ROT2B, // Rotary switch2 B Pin +#endif GPIO_REL1, // Relays GPIO_REL1_INV, GPIO_REL2, @@ -665,12 +671,6 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_MAX31855CLK, // MAX31855 Serial interface GPIO_MAX31855DO, // MAX31855 Serial interface #endif -#ifdef ROTARY_V1 - GPIO_ROT1A, // Rotary switch1 A Pin - GPIO_ROT1B, // Rotary switch1 B Pin - GPIO_ROT2A, // Rotary switch2 A Pin - GPIO_ROT2B, // Rotary switch2 B Pin -#endif #ifdef USE_HRE GPIO_HRE_CLOCK, GPIO_HRE_DATA, diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index e5b30a5b1..72c72e48b 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -88,7 +88,10 @@ enum UserSelectablePins { GPIO_CSE7766_TX, GPIO_CSE7766_RX, // CSE7766 Serial interface (S31 and Pow R2) GPIO_ARIRFRCV, GPIO_ARIRFSEL, // Arilux RF Receive input GPIO_TXD, GPIO_RXD, // Serial interface - GPIO_ROT1A, GPIO_ROT1B, GPIO_ROT2A, GPIO_ROT2B, // Rotary switch + GPIO_ROT1A, GPIO_ROT1B, // Rotary switch + + GPIO_SPARE1, GPIO_SPARE2, // Spare GPIOs + GPIO_HRE_CLOCK, GPIO_HRE_DATA, // HR-E Water Meter GPIO_ADE7953_IRQ, // ADE7953 IRQ GPIO_SOLAXX1_TX, GPIO_SOLAXX1_RX, // Solax Inverter Serial interface @@ -188,7 +191,10 @@ const char kSensorNames[] PROGMEM = D_SENSOR_CSE7766_TX "|" D_SENSOR_CSE7766_RX "|" D_SENSOR_ARIRFRCV "|" D_SENSOR_ARIRFSEL "|" D_SENSOR_TXD "|" D_SENSOR_RXD "|" - D_SENSOR_ROTARY "_1a|" D_SENSOR_ROTARY "_1b|" D_SENSOR_ROTARY "_2a|" D_SENSOR_ROTARY "_2b|" + D_SENSOR_ROTARY "_a|" D_SENSOR_ROTARY "_b|" + + "Spare1|Spare2|" + D_SENSOR_HRE_CLOCK "|" D_SENSOR_HRE_DATA "|" D_SENSOR_ADE7953_IRQ "|" D_SENSOR_SOLAXX1_TX "|" D_SENSOR_SOLAXX1_RX "|" @@ -245,6 +251,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_KEY1_TC) + MAX_KEYS, // Touch button AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES, +#ifdef ROTARY_V1 + AGPIO(GPIO_ROT1A) + MAX_ROTARIES, // Rotary A Pin + AGPIO(GPIO_ROT1B) + MAX_ROTARIES, // Rotary B Pin +#endif AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays AGPIO(GPIO_REL1_INV) + MAX_RELAYS, AGPIO(GPIO_LED1) + MAX_LEDS, // Leds @@ -508,12 +518,6 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface #endif -#ifdef ROTARY_V1 - AGPIO(GPIO_ROT1A), // Rotary switch1 A Pin - AGPIO(GPIO_ROT1B), // Rotary switch1 B Pin - AGPIO(GPIO_ROT2A), // Rotary switch2 A Pin - AGPIO(GPIO_ROT2B), // Rotary switch2 B Pin -#endif #ifdef USE_HRE AGPIO(GPIO_HRE_CLOCK), AGPIO(GPIO_HRE_DATA), diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 86293c2b2..d284e71fe 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -314,16 +314,6 @@ power_t LightPower(void) return Light.power; // Make external } -// IRAM variant for rotary -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception -power_t LightPowerIRAM(void) ICACHE_RAM_ATTR; -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 - -power_t LightPowerIRAM(void) -{ - return Light.power; // Make external -} - uint8_t LightDevice(void) { return Light.device; // Make external @@ -1568,7 +1558,7 @@ void LightPowerOn(void) } } -void LightState(uint8_t append) +void ResponseLightState(uint8_t append) { char scolor[LIGHT_COLOR_SIZE]; char scommand[33]; @@ -1718,7 +1708,7 @@ void LightPreparePower(power_t channels = 0xFFFFFFFF) { // 1 = only RGB, 2 = AddLog_P2(LOG_LEVEL_DEBUG, "LightPreparePower End power=%d Light.power=%d", power, Light.power); #endif Light.power = power >> (Light.device - 1); // reset next state, works also with unlinked RGB/CT - LightState(0); + ResponseLightState(0); } #ifdef USE_LIGHT_PALETTE @@ -1886,7 +1876,7 @@ void LightAnimate(void) MqttPublishPrefixTopic_P(TELE, PSTR(D_CMND_WAKEUP)); */ Response_P(PSTR("{\"" D_CMND_WAKEUP "\":\"" D_JSON_DONE "\"")); - LightState(1); + ResponseLightState(1); ResponseJsonEnd(); MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_WAKEUP)); XdrvRulesProcess(); @@ -2689,7 +2679,7 @@ void CmndHsbColor(void) light_controller.changeHSB(HSB[0], HSB[1], HSB[2]); LightPreparePower(1); } else { - LightState(0); + ResponseLightState(0); } } } @@ -2774,12 +2764,12 @@ void CmndColorTemperature(void) } } -void LightDimmerOffset(int32_t offset) { - int32_t dimmer = light_state.getDimmer() + offset; - if (dimmer < 1) { dimmer = 1; } +void LightDimmerOffset(uint32_t index, int32_t offset) { + int32_t dimmer = light_state.getDimmer(index) + offset; + if (dimmer < 1) { dimmer = Settings.flag3.slider_dimmer_stay_on; } // SetOption77 - Do not power off if slider moved to far left if (dimmer > 100) { dimmer = 100; } - XdrvMailbox.index = 0; + XdrvMailbox.index = index; XdrvMailbox.payload = dimmer; CmndDimmer(); } From e468f941dbaa708bc60893151ba2c16f1281f802 Mon Sep 17 00:00:00 2001 From: d0m1n1qu3 Date: Mon, 13 Jul 2020 17:57:30 +0200 Subject: [PATCH 457/581] using D_RSSI instead of new String --- tasmota/xsns_62_MI_ESP32.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index b110cb57f..a46f516d3 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -1454,7 +1454,7 @@ bool MI32Cmd(void) { const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 {m}%u%s / %u{e}"; const char HTTP_MI32_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; -const char HTTP_RSSI[] PROGMEM = "{s}%s" " RSSI" "{m}%d dBm{e}"; +const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; const char HTTP_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{m}%s V{e}"; const char HTTP_LASTBUTTON[] PROGMEM = "{s}%s Last Button{m}%u {e}"; From e0f075afb1eb086accae2966bbd09eba74550a03 Mon Sep 17 00:00:00 2001 From: Javier Arigita Date: Mon, 13 Jul 2020 20:22:37 +0200 Subject: [PATCH 458/581] Bugfix local temperature sensor in fahrenheit --- tasmota/xdrv_39_thermostat.ino | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_39_thermostat.ino b/tasmota/xdrv_39_thermostat.ino index 768088117..8e863822d 100644 --- a/tasmota/xdrv_39_thermostat.ino +++ b/tasmota/xdrv_39_thermostat.ino @@ -1333,7 +1333,13 @@ void ThermostatGetLocalSensor(uint8_t ctr_output) { if (root.success()) { const char* value_c = root[THERMOSTAT_SENSOR_NAME]["Temperature"]; if (value_c != NULL && strlen(value_c) > 0 && (isdigit(value_c[0]) || (value_c[0] == '-' && isdigit(value_c[1])) ) ) { - int16_t value = (int16_t)(CharToFloat(value_c) * 10); + int16_t value; + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = (int16_t)ThermostatFahrenheitToCelsius((int32_t)(CharToFloat(value_c) * 10), TEMP_CONV_ABSOLUTE); + } + else { + value = (int16_t)(CharToFloat(value_c) * 10); + } if ( (value >= -1000) && (value <= 1000) && (Thermostat[ctr_output].status.sensor_type == SENSOR_LOCAL)) { From 3640372fd08740a1fb03dab2c877d9c2a2172781 Mon Sep 17 00:00:00 2001 From: d0m1n1qu3 Date: Mon, 13 Jul 2020 21:08:10 +0200 Subject: [PATCH 459/581] fix that firmware is send everytime since commit 39705a2e059cf616199c1e18eb04a87d00482b7c --- tasmota/xsns_62_MI_ESP32.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index a46f516d3..efbf1a78a 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -1508,7 +1508,9 @@ void MI32Show(bool json) if (!isnan(MIBLEsensors[i].fertility)) { ResponseAppend_P(PSTR(",\"Fertility\":%f"), MIBLEsensors[i].fertility); } - ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); + if (MIBLEsensors[i].firmware != 0x00) { // this is the error code -> no firmware + ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); + } } if (MIBLEsensors[i].type > FLORA){ if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { From 032c87c7a965644935dfba622381a6e1e633d7eb Mon Sep 17 00:00:00 2001 From: d0m1n1qu3 Date: Mon, 13 Jul 2020 21:24:38 +0200 Subject: [PATCH 460/581] fix that firmware is send everytime since commit 39705a2e059cf616199c1e18eb04a87d00482b7c --- tasmota/xsns_62_MI_ESP32.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index efbf1a78a..0211d276d 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -1508,7 +1508,7 @@ void MI32Show(bool json) if (!isnan(MIBLEsensors[i].fertility)) { ResponseAppend_P(PSTR(",\"Fertility\":%f"), MIBLEsensors[i].fertility); } - if (MIBLEsensors[i].firmware != 0x00) { // this is the error code -> no firmware + if (MIBLEsensors[i].firmware[0] != '\0') { // this is the error code -> no firmware ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); } } From 60584d9423675f8d2dfebe1656fefcda48d3a548 Mon Sep 17 00:00:00 2001 From: Khoa Ton Date: Tue, 14 Jul 2020 01:42:41 -0700 Subject: [PATCH 461/581] Add 0.56" sevenseg support, floating point, raw output --- tasmota/my_user_config.h | 3 + tasmota/xdsp_11_sevenseg.ino | 108 ++++++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 34 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 3d9e904ca..99aa37b3d 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -563,6 +563,9 @@ // MTX_ADDRESS2 at y=1, up to MTX_ADDRESS8 at y=7 // Command: DisplayText [yn]8888 // will display 8888 at sevenseg display at I2C address MTX_ADDRESS(n-1) + // Each segment may be address Command: DisplayText [xn]m + // where n is 0..4 (4 digits and middle :) and m is decimal for bitmap of which segment to turn on. + // Reference: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-led-backpack.pdf // #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays // #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D) #endif // USE_I2C diff --git a/tasmota/xdsp_11_sevenseg.ino b/tasmota/xdsp_11_sevenseg.ino index d01637204..701c83e7d 100644 --- a/tasmota/xdsp_11_sevenseg.ino +++ b/tasmota/xdsp_11_sevenseg.ino @@ -106,16 +106,18 @@ void SevensegOnOff(void) void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag) { - uint16_t number = 0; + enum OutNumType {DECIMAL, HEXADECIMAL, FLOAT, SEGMENTS}; + int16_t number = 0; + double numberf = 0; boolean hasnumber= false; uint8_t dots= 0; - boolean t=false; - boolean T=false; - boolean d=false; - boolean hex=false; - boolean done=false; - boolean s=false; - uint8_t unit=y; + OutNumType outnumtype= DECIMAL; + uint8 fds = 0; // number of fractional digits for fp number + boolean done= false; + boolean s= false; + uint8_t unit= y; + char *buf; + if ((unit>=sevensegs) || (unit<0)) { unit=0; } @@ -123,29 +125,41 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin for (int i=0; (str[i]!='\0') && (!done); i++) { // [optional prefix(es) chars]digits // Some combinations won't make sense. - // Reference: https://learn.adafruit.com/adafruit-led-backpack/1-2-inch-7-segment-backpack-arduino-wiring-and-setup + // Reference: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-led-backpack.pdf + // This code has been tested on 1.2" and 0.56" 7-Segment LED displays, but should mostly work for others. // // Prefixes: - // x upcoming number decimal integer displayed as hex + // x upcoming decimal integer number displayed as hex // : turn on middle colon // ^ turn on top left dot // v turn on bottom left dot // . turn on AM/PM/Degree dot // s upcoming number is seconds, print as HH:MM or MM:SS // z clear this display + // f upcoming number is floating point + // r raw segment based on bitmap of upcoming integer number (see reference document above) // // Some sample valid combinations: - // 787 -> 787 - // x47 -> 2F - // s:241 -> 04:01 - // s241 -> 4 01 - // s1241 -> 20:41 - // z -> - // x88 -> 58 + // 787 -> 787 + // x47 -> 2F + // s:241 -> 04:01 + // s241 -> 4 01 + // s1241 -> 20:41 + // z -> + // x88 -> 58 + // f8.5 -> 8.5 + // f-9.34 -> -9.34 + // f:-9.34 -> -9.34 + // r255 -> 8. (all 8 segments on) switch (str[i]) { case 'x': // print given dec value as hex - hex = true; + // hex = true; + outnumtype = HEXADECIMAL; + break; + case 'f': // given number is floating point number + // fp = true; + outnumtype = FLOAT; break; case ':': // print colon dots |= 0x02; @@ -162,6 +176,7 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin case 's': // duration in seconds s = true; break; + case '-': case '0': case '1': case '2': @@ -173,7 +188,21 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin case '8': case '9': hasnumber= true; - number = atoi(str+i); + if (outnumtype == FLOAT) { + // Floating point number is given + numberf = atof(str+i); + // Find number of fractional digits + buf= str+i; + char *cp= strchr(buf, '.'); + if (cp == NULL) { + fds= 0; + } else { + fds= buf+strlen(buf) - 1 - cp; + } + } else { + // Integer is given + number = atoi(str+i); + } done = true; break; case 'z': // Clear this display @@ -182,30 +211,41 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin s=false; sevenseg[unit]->clear(); break; + case 'r': // Raw segment + outnumtype= SEGMENTS; + break; default: // unknown format, ignore break; } } - if (s) { - // number is duration in seconds - hex = false; - int hour = number/60/60; - int minute = (number/60)%60; - - if (hour) { - // HH:MM - number = hour*100 + minute; - } else { - // MM:SS - number = minute*100 + number%60; - } - } if (hasnumber) { - if (hex) { + if (s) { + // number is duration in seconds + int hour = number/60/60; + int minute = (number/60)%60; + + if (hour) { + // HH:MM + number = hour*100 + minute; + } else { + // MM:SS + number = minute*100 + number%60; + } + } + + if (outnumtype == HEXADECIMAL) { + // Hex sevenseg[unit]->print(number, HEX); + } else if (outnumtype == FLOAT) { + // Floating point + sevenseg[unit]->printFloat(numberf, fds, 10); + } else if (outnumtype == SEGMENTS) { + // Raw segments + sevenseg[unit]->writeDigitRaw(x, number); } else { + // Decimal sevenseg[unit]->print(number, DEC); } } From 30a0e66589b7dd37949e51f02f7f328a2a3e9b8a Mon Sep 17 00:00:00 2001 From: gui Date: Tue, 14 Jul 2020 17:06:50 +0800 Subject: [PATCH 462/581] Optimizations for zh_TW translations --- tasmota/language/zh_TW.h | 450 +++++++++++++++++++-------------------- 1 file changed, 225 insertions(+), 225 deletions(-) diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 4762b9c16..b6ab27b3e 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -53,69 +53,69 @@ // Common #define D_ADMIN "Admin" #define D_AIR_QUALITY "空氣å“質" -#define D_AP "AP" // Access Point +#define D_AP "å­˜å–點" // Access Point #define D_AS "å稱:" #define D_AUTO "自動" -#define D_BATT "Batt" // Short for Battery +#define D_BATT "電池" // Short for Battery #define D_BLINK "é–ƒçˆ" #define D_BLINKOFF "é–ƒçˆé—œ" -#define D_BOOT_COUNT "啟動次數" +#define D_BOOT_COUNT "啟動計數" #define D_BRIGHTLIGHT "亮度" #define D_BSSID "BSSId" #define D_BUTTON "按鈕" -#define D_BY "by" // Written by me +#define D_BY "ç”±" // Written by me #define D_BYTES "大å°:" #define D_CELSIUS "æ”æ°" #define D_CHANNEL "Channel" #define D_CO2 "二氧化碳" #define D_CODE "代碼" // Button code -#define D_COLDLIGHT "冷" +#define D_COLDLIGHT "冷光" #define D_COMMAND "命令:" -#define D_CONNECTED "已連接" +#define D_CONNECTED "已連線" #define D_CORS_DOMAIN "CORS Domain" #define D_COUNT "數é‡:" #define D_COUNTER "Counter" #define D_CT_POWER "CT Power" #define D_CURRENT "é›»æµ" // As in Voltage and Current #define D_DATA "數據:" -#define D_DARKLIGHT "Dark" -#define D_DEBUG "除錯" +#define D_DARKLIGHT "æš—å…‰" +#define D_DEBUG "åµéŒ¯" #define D_DEWPOINT "Dew point" -#define D_DISABLED "åœç”¨" -#define D_DISTANCE "Distance" +#define D_DISABLED "å·²åœç”¨" +#define D_DISTANCE "è·é›¢" #define D_DNS_SERVER "DNS伺æœå™¨" #define D_DONE "完æˆ" #define D_DST_TIME "DST" #define D_ECO2 "eCOâ‚‚" -#define D_EMULATION "設備模擬" -#define D_ENABLED "啟用" -#define D_ERASE "刪除" +#define D_EMULATION "模擬" +#define D_ENABLED "已啟用" +#define D_ERASE "抹除" #define D_ERROR "錯誤" #define D_FAHRENHEIT "è¯æ°" -#define D_FAILED "失敗" +#define D_FAILED "失敗了" #define D_FALLBACK "Fallback" #define D_FALLBACK_TOPIC "Fallback Topic" #define D_FALSE "False" -#define D_FILE "文件:" +#define D_FILE "檔案:" #define D_FLOW_RATE "Flow rate" -#define D_FREE_MEMORY "å¯ç”¨è¨˜æ†¶é«”" +#define D_FREE_MEMORY "å¯ç”¨çš„記憶體" #define D_PSR_MAX_MEMORY "PS-RAM Memory" #define D_PSR_FREE_MEMORY "PS-RAM free Memory" -#define D_FREQUENCY "Frequency" +#define D_FREQUENCY "頻率" #define D_GAS "氣體" -#define D_GATEWAY "網關" -#define D_GROUP "組:" +#define D_GATEWAY "é–˜é“器" +#define D_GROUP "群組:" #define D_HOST "主機" -#define D_HOSTNAME "主機å" +#define D_HOSTNAME "主機å稱" #define D_HUMIDITY "濕度" #define D_ILLUMINANCE "照度" -#define D_IMMEDIATE "immediate" // Button immediate +#define D_IMMEDIATE "ç«‹å³" // Button immediate #define D_INDEX "索引:" -#define D_INFO "ä¿¡æ¯" -#define D_INFRARED "Infrared" -#define D_INITIALIZED "åˆå§‹åŒ–完æˆ" -#define D_IP_ADDRESS "IP地å€" -#define D_LIGHT "燈" +#define D_INFO "資訊" +#define D_INFRARED "紅外線" +#define D_INITIALIZED "å·²åˆå§‹åŒ–" +#define D_IP_ADDRESS "IPä½å€" +#define D_LIGHT "燈光" #define D_LWT "LWT" #define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "模組" @@ -124,240 +124,240 @@ #define D_MULTI_PRESS "多次按éµ" #define D_NOISE "雜訊" #define D_NONE "ç„¡" -#define D_OFF "é—œ" +#define D_OFF "關閉" #define D_OFFLINE "離線" #define D_OK "好" -#define D_ON "é–‹" -#define D_ONLINE "在線" +#define D_ON "開啟" +#define D_ONLINE "線上" #define D_PASSWORD "密碼" -#define D_PORT "端å£" +#define D_PORT "通訊埠" #define D_POWER_FACTOR "功率因數" -#define D_POWERUSAGE "功率" +#define D_POWERUSAGE "用電é‡" #define D_POWERUSAGE_ACTIVE "Active Power" #define D_POWERUSAGE_APPARENT "Apparent Power" #define D_POWERUSAGE_REACTIVE "Reactive Power" #define D_PRESSURE "氣壓" #define D_PRESSUREATSEALEVEL "æµ·å¹³é¢æ°£å£“" -#define D_PROGRAM_FLASH_SIZE "韌體 Flash 大å°" -#define D_PROGRAM_SIZE "韌體大å°" +#define D_PROGRAM_FLASH_SIZE "程å¼è¨˜æ†¶é«”大å°" +#define D_PROGRAM_SIZE "程å¼å¤§å°" #define D_PROJECT "é …ç›®:" #define D_RAIN "Rain" #define D_RANGE "Range" #define D_RECEIVED "已接收" -#define D_RESTART "é‡å•Ÿ" -#define D_RESTARTING "正在é‡å•Ÿ" -#define D_RESTART_REASON "é‡å•ŸåŽŸå› " -#define D_RESTORE "æ¢è¦†" +#define D_RESTART "釿–°å•Ÿå‹•" +#define D_RESTARTING "æ­£åœ¨é‡æ–°å•Ÿå‹•" +#define D_RESTART_REASON "釿–°å•Ÿå‹•的原因" +#define D_RESTORE "讀å–設定" #define D_RETAINED "å·²ä¿ç•™" -#define D_RULE "Rule" -#define D_SAVE "存檔" -#define D_SENSOR "感測器" -#define D_SSID "å稱" -#define D_START "é–‹å§‹" -#define D_STD_TIME "STD" +#define D_RULE "è¦å‰‡" +#define D_SAVE "儲存" +#define D_SENSOR "感應器" +#define D_SSID "SSID" +#define D_START "啟動" +#define D_STD_TIME "標準時間" #define D_STOP "åœæ­¢" -#define D_SUBNET_MASK "å­ç¶²é®ç½©" +#define D_SUBNET_MASK "å­ç¶²åŸŸé®ç½©" #define D_SUBSCRIBE_TO "訂閱" -#define D_UNSUBSCRIBE_FROM "退訂" -#define D_SUCCESSFUL "æˆåŠŸ" -#define D_SUNRISE "Sunrise" -#define D_SUNSET "Sunset" +#define D_UNSUBSCRIBE_FROM "退出訂閱自" +#define D_SUCCESSFUL "å·²æˆåŠŸ" +#define D_SUNRISE "日出" +#define D_SUNSET "æ—¥è½" #define D_TEMPERATURE "溫度" #define D_TO "to" #define D_TOGGLE "切æ›" #define D_TOPIC "主題" -#define D_TOTAL_USAGE "Total Usage" +#define D_TOTAL_USAGE "總使用é‡" #define D_TRANSMIT "發é€" #define D_TRUE "True" #define D_TVOC "TVOC" #define D_UPGRADE "å‡ç´š" #define D_UPLOAD "上傳" -#define D_UPTIME "é‹è¡Œæ™‚é–“" -#define D_USER "用戶å" -#define D_UTC_TIME "UTC" -#define D_UV_INDEX "UV Index" -#define D_UV_INDEX_1 "Low" -#define D_UV_INDEX_2 "Mid" -#define D_UV_INDEX_3 "High" -#define D_UV_INDEX_4 "Danger" +#define D_UPTIME "啟動時間" +#define D_USER "使用者å稱" +#define D_UTC_TIME "世界å”調時間(UTC)" +#define D_UV_INDEX "紫外線指數" +#define D_UV_INDEX_1 "低" +#define D_UV_INDEX_2 "中" +#define D_UV_INDEX_3 "高" +#define D_UV_INDEX_4 "å±éšª" #define D_UV_INDEX_5 "BurnL1/2" #define D_UV_INDEX_6 "BurnL3" -#define D_UV_INDEX_7 "OoR" +#define D_UV_INDEX_7 "超出範åœ" #define D_UV_LEVEL "紫外線等級" -#define D_UV_POWER "UV Power" +#define D_UV_POWER "紫外線能é‡" #define D_VERSION "版本" #define D_VOLTAGE "電壓" -#define D_WEIGHT "Weight" -#define D_WARMLIGHT "æš–" -#define D_WEB_SERVER "Web Server" +#define D_WEIGHT "é‡é‡" +#define D_WARMLIGHT "æš–å…‰" +#define D_WEB_SERVER "ç¶²é ä¼ºæœå™¨" // tasmota.ino -#define D_WARNING_MINIMAL_VERSION "警告:精簡產å“䏿”¯æŒé…置寫入ä¿å­˜" -#define D_LEVEL_10 "level 1-0" -#define D_LEVEL_01 "level 0-1" -#define D_SERIAL_LOGGING_DISABLED "䏲壿—¥èªŒå·²ç¦ç”¨" -#define D_SYSLOG_LOGGING_REENABLED "Syslog 日誌已開啟" +#define D_WARNING_MINIMAL_VERSION "è­¦å‘Šï¼Œé€™å€‹ç‰ˆæœ¬ä¸¦ä¸æ”¯æ´å°‡è¨­å®šæ°¸ä¹…的儲存!" +#define D_LEVEL_10 "等級 1-0" +#define D_LEVEL_01 "等其 0-1" +#define D_SERIAL_LOGGING_DISABLED "å·²åœç”¨åºåˆ—埠日誌" +#define D_SYSLOG_LOGGING_REENABLED "ç³»çµ±æ—¥èªŒå·²ç¶“é‡æ–°å•Ÿç”¨" -#define D_SET_BAUDRATE_TO "設置波特率為:" +#define D_SET_BAUDRATE_TO "將鮑率設定為:" #define D_RECEIVED_TOPIC "接收到的主題:" -#define D_DATA_SIZE "數據大å°:" -#define D_ANALOG_INPUT "Analog" +#define D_DATA_SIZE "資料大å°:" +#define D_ANALOG_INPUT "類比" // support.ino #define D_OSWATCH "osWatch" #define D_BLOCKED_LOOP "Blocked Loop" #define D_WPS_FAILED_WITH_STATUS "WPSconfig FAILED with status" #define D_ACTIVE_FOR_3_MINUTES "active for 3 minutes" -#define D_FAILED_TO_START "未能啟動" +#define D_FAILED_TO_START "無法啟動" #define D_PATCH_ISSUE_2186 "Patch issue 2186" -#define D_CONNECTING_TO_AP "連接到 AP" -#define D_IN_MODE "模å¼:" -#define D_CONNECT_FAILED_NO_IP_ADDRESS "連接失敗,因為沒有ç²å–到IP地å€" -#define D_CONNECT_FAILED_AP_NOT_REACHED "連接失敗,無法連接AP" -#define D_CONNECT_FAILED_WRONG_PASSWORD "連接失敗" -#define D_CONNECT_FAILED_AP_TIMEOUT "連接失敗,AP超時" -#define D_ATTEMPTING_CONNECTION "嘗試連接..." -#define D_CHECKING_CONNECTION "檢查連接..." -#define D_QUERY_DONE "查詢完æˆã€‚ 發ç¾MQTTæœå‹™" -#define D_MQTT_SERVICE_FOUND "發ç¾MQTTæœå‹™:" -#define D_FOUND_AT "found at" -#define D_SYSLOG_HOST_NOT_FOUND "Syslog主機未找到" +#define D_CONNECTING_TO_AP "正在連線至存å–點" +#define D_IN_MODE "in模å¼:" +#define D_CONNECT_FAILED_NO_IP_ADDRESS "連線失敗:未收到IPä½ç½®" +#define D_CONNECT_FAILED_AP_NOT_REACHED "連線失敗:無法連線至存å–點" +#define D_CONNECT_FAILED_WRONG_PASSWORD "連線失敗" +#define D_CONNECT_FAILED_AP_TIMEOUT "連線失敗:å­˜å–點超時" +#define D_ATTEMPTING_CONNECTION "正在試圖連線中..." +#define D_CHECKING_CONNECTION "正在檢查連線中..." +#define D_QUERY_DONE "å·²å®ŒæˆæŸ¥è©¢ï¼Œæ‰¾åˆ°MQTTæœå‹™äº†" +#define D_MQTT_SERVICE_FOUND "MQTTæœå‹™ä½æ–¼:" +#define D_FOUND_AT "使–¼" +#define D_SYSLOG_HOST_NOT_FOUND "找ä¸åˆ°ç³»çµ±æ—¥èªŒä¸»æ©Ÿ" // settings.ino -#define D_SAVED_TO_FLASH_AT "ä¿å­˜åˆ° flash:" -#define D_LOADED_FROM_FLASH_AT "從 flash 載入" -#define D_USE_DEFAULTS "使用默èªè¨­ç½®" -#define D_ERASED_SECTOR "擦除刪除" +#define D_SAVED_TO_FLASH_AT "å„²å­˜è‡³å¿«é–ƒè¨˜æ†¶é«”ï¼Œä½æ–¼:" +#define D_LOADED_FROM_FLASH_AT "已從快閃記憶體中讀å–ï¼Œä½æ–¼:" +#define D_USE_DEFAULTS "使用é è¨­å€¼" +#define D_ERASED_SECTOR "抹除ç£å€" // xdrv_02_webserver.ino -#define D_NOSCRIPT "To use Tasmota, please enable JavaScript" -#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "固件版本éŽä½Ž
    è«‹å‡ç´š" -#define D_WEBSERVER_ACTIVE_ON "Webæœå‹™å™¨:" -#define D_WITH_IP_ADDRESS "IP地å€:" -#define D_WEBSERVER_STOPPED "Web æœå‹™å™¨å·²åœæ­¢" -#define D_FILE_NOT_FOUND "文件未找到" -#define D_REDIRECTED "é‡å®šå‘到èªè­‰é é¢" +#define D_NOSCRIPT "為了使用 Tasmota,請啟用 JavaScript" +#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL韌體
    è«‹å‡ç´š" +#define D_WEBSERVER_ACTIVE_ON "ç¶²é ä¼ºæœå™¨å·²ç¶“å•Ÿå‹•ï¼Œä½æ–¼:" +#define D_WITH_IP_ADDRESS "IPä½å€:" +#define D_WEBSERVER_STOPPED "ç¶²é ä¼ºæœå™¨å·²ç¶“åœæ­¢" +#define D_FILE_NOT_FOUND "ç…§ä¸åˆ°æª”案" +#define D_REDIRECTED "已釿–°å®šå‘至閘é“èªè­‰é é¢" #define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager set AccessPoint and keep Station" -#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager 設置接入點" -#define D_TRYING_TO_CONNECT "嘗試將設備連接到網絡" +#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager 已設定存å–點" +#define D_TRYING_TO_CONNECT "正在將è£ç½®é€£ç·šè‡³ç¶²è·¯" -#define D_RESTART_IN "é‡å•Ÿéœ€è¦" -#define D_SECONDS "ç§’" -#define D_DEVICE_WILL_RESTART "設備將在幾分é˜å…§é‡å•Ÿ" -#define D_BUTTON_TOGGLE "狀態切æ›" -#define D_CONFIGURATION "設置" -#define D_INFORMATION "ä¿¡æ¯" -#define D_FIRMWARE_UPGRADE "固件å‡ç´š" +#define D_RESTART_IN "釿–°å•Ÿå‹•倒數 " +#define D_SECONDS " ç§’" +#define D_DEVICE_WILL_RESTART "è£ç½®å°‡æœƒåœ¨å¹¾ç§’內釿–°å•Ÿå‹•" +#define D_BUTTON_TOGGLE "切æ›" +#define D_CONFIGURATION "設定" +#define D_INFORMATION "資訊" +#define D_FIRMWARE_UPGRADE "韌體å‡ç´š" #define D_CONSOLE "控制å°" -#define D_CONFIRM_RESTART "確èªé‡å•Ÿ" +#define D_CONFIRM_RESTART "確èªé‡æ–°å•Ÿå‹•" -#define D_CONFIGURE_MODULE "模塊設置" -#define D_CONFIGURE_WIFI "WiFi設置" -#define D_CONFIGURE_MQTT "MQTT設置" -#define D_CONFIGURE_DOMOTICZ "Domoticz設置" -#define D_CONFIGURE_LOGGING "日志設置" -#define D_CONFIGURE_OTHER "其他設置" -#define D_CONFIRM_RESET_CONFIGURATION "確èªé‡ç½®é…ç½®" -#define D_RESET_CONFIGURATION "é‡ç½®é…ç½®" -#define D_BACKUP_CONFIGURATION "備份é…ç½®" -#define D_RESTORE_CONFIGURATION "還原é…ç½®" -#define D_MAIN_MENU "主èœå–®" +#define D_CONFIGURE_MODULE "模組設定" +#define D_CONFIGURE_WIFI "WiF設定i" +#define D_CONFIGURE_MQTT "MQTT設定" +#define D_CONFIGURE_DOMOTICZ "Domoticz設定" +#define D_CONFIGURE_LOGGING "日誌設定" +#define D_CONFIGURE_OTHER "其他設定" +#define D_CONFIRM_RESET_CONFIGURATION "確定é‡è¨­è¨­å®š" +#define D_RESET_CONFIGURATION "é‡è¨­è¨­å®š" +#define D_BACKUP_CONFIGURATION "備份設定" +#define D_RESTORE_CONFIGURATION "回復設定" +#define D_MAIN_MENU "主é¸å–®" -#define D_MODULE_PARAMETERS "模塊設置" -#define D_MODULE_TYPE "模塊類型" -#define D_PULLUP_ENABLE "No Button/Switch pull-up" -#define D_ADC "ADC" +#define D_MODULE_PARAMETERS "æ¨¡çµ„åƒæ•¸" +#define D_MODULE_TYPE "模組類型" +#define D_PULLUP_ENABLE "無按鈕/上拉å¼é–‹é—œ(Switch pull-up)" +#define D_ADC "é¡žæ¯”è½‰æ›æ•¸ä½(ADC)" #define D_GPIO "GPIO" -#define D_SERIAL_IN "串å£è¼¸å…¥(RX)" -#define D_SERIAL_OUT "串å£è¼¸å‡º(TX)" +#define D_SERIAL_IN "åºåˆ—埠輸入(RX)" +#define D_SERIAL_OUT "åºåˆ—埠輸出(TX)" -#define D_WIFI_PARAMETERS "Wifi設置" +#define D_WIFI_PARAMETERS "Wifi設定" #define D_SCAN_FOR_WIFI_NETWORKS "掃æç„¡ç·šç¶²çµ¡" #define D_SCAN_DONE "掃æå®Œç•¢" -#define D_NO_NETWORKS_FOUND "未找到任何網絡" -#define D_REFRESH_TO_SCAN_AGAIN "刷新並é‡è©¦" -#define D_DUPLICATE_ACCESSPOINT "é‡è¦†AP" -#define D_SKIPPING_LOW_QUALITY "忽略弱信號網絡" +#define D_NO_NETWORKS_FOUND "找ä¸åˆ°ä»»ä½•網絡" +#define D_REFRESH_TO_SCAN_AGAIN "釿–°æ•´ç†ä»¥é‡æ–°æŽƒæ" +#define D_DUPLICATE_ACCESSPOINT "é‡è¦†çš„å­˜å–點" +#define D_SKIPPING_LOW_QUALITY "正在忽略訊號å“質ä¸ä½³çš„訊號" #define D_RSSI "RSSI" #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 å稱" +#define D_AP1_SSID "AP1 SSID" #define D_AP1_PASSWORD "AP1 密碼" -#define D_AP2_SSID "AP2 å稱" +#define D_AP2_SSID "AP2 SSID" #define D_AP2_PASSWORD "AP2 密碼" -#define D_MQTT_PARAMETERS "MQTT設置" +#define D_MQTT_PARAMETERS "MQTT設定" #define D_CLIENT "客戶端" #define D_FULL_TOPIC "完整主題" -#define D_LOGGING_PARAMETERS "日志設置" -#define D_SERIAL_LOG_LEVEL "䏲壿—¥å¿—級別" -#define D_MQTT_LOG_LEVEL "Mqtt log level" -#define D_WEB_LOG_LEVEL "Web 日志級別" -#define D_SYS_LOG_LEVEL "Syslog 日志級別" -#define D_MORE_DEBUG "全部調試" -#define D_SYSLOG_HOST "Syslog 主機地å€" -#define D_SYSLOG_PORT "Syslog 端å£" -#define D_TELEMETRY_PERIOD "上報周期" +#define D_LOGGING_PARAMETERS "æ—¥èªŒåƒæ•¸" +#define D_SERIAL_LOG_LEVEL "åºåˆ—埠日誌等級" +#define D_MQTT_LOG_LEVEL "Mqtt 日誌等級" +#define D_WEB_LOG_LEVEL "Web 日誌等級" +#define D_SYS_LOG_LEVEL "Syslog 日誌等級" +#define D_MORE_DEBUG "More debug" +#define D_SYSLOG_HOST "Syslog 主機ä½å€" +#define D_SYSLOG_PORT "Syslog 通訊埠" +#define D_TELEMETRY_PERIOD "Telemetry period" -#define D_OTHER_PARAMETERS "其他設置" -#define D_TEMPLATE "Template" -#define D_ACTIVATE "Activate" -#define D_DEVICE_NAME "Device Name" -#define D_WEB_ADMIN_PASSWORD "WEB管ç†å¯†ç¢¼" -#define D_MQTT_ENABLE "啟用MQTT" -#define D_FRIENDLY_NAME "昵稱" +#define D_OTHER_PARAMETERS "å…¶ä»–åƒæ•¸" +#define D_TEMPLATE "模æ¿" +#define D_ACTIVATE "啟動" +#define D_DEVICE_NAME "è£ç½®å稱" +#define D_WEB_ADMIN_PASSWORD "ç¶²é ä¸Šçš„管ç†å“¡å¯†ç¢¼" +#define D_MQTT_ENABLE "MQTT的啟用" +#define D_FRIENDLY_NAME "暱稱" #define D_BELKIN_WEMO "è²çˆ¾é‡‘ WeMo" -#define D_HUE_BRIDGE "飛利浦 Hue 網橋" -#define D_SINGLE_DEVICE "單設備" -#define D_MULTI_DEVICE "多設備" +#define D_HUE_BRIDGE "Hue 橋接器" +#define D_SINGLE_DEVICE "單個è£ç½®" +#define D_MULTI_DEVICE "多é‡è£ç½®" -#define D_CONFIGURE_TEMPLATE "Configure Template" -#define D_TEMPLATE_PARAMETERS "Template parameters" +#define D_CONFIGURE_TEMPLATE "模æ¿è¨­å®š" +#define D_TEMPLATE_PARAMETERS "模æ¿åƒæ•¸" #define D_TEMPLATE_NAME "Name" #define D_BASE_TYPE "Based on" #define D_TEMPLATE_FLAGS "Options" -#define D_SAVE_CONFIGURATION "ä¿å­˜è¨­ç½®" -#define D_CONFIGURATION_SAVED "設置已ä¿å­˜" -#define D_CONFIGURATION_RESET "設置已é‡ç½®" +#define D_SAVE_CONFIGURATION "儲存設定" +#define D_CONFIGURATION_SAVED "設定已儲存" +#define D_CONFIGURATION_RESET "設定已é‡è¨­" -#define D_PROGRAM_VERSION "固件版本" -#define D_BUILD_DATE_AND_TIME "編譯時間" -#define D_CORE_AND_SDK_VERSION "內核版本" -#define D_FLASH_WRITE_COUNT "刷機次數" -#define D_MAC_ADDRESS "MAC地å€" +#define D_PROGRAM_VERSION "軟體版本" +#define D_BUILD_DATE_AND_TIME "編譯日期與時間" +#define D_CORE_AND_SDK_VERSION "核心與SDK版本" +#define D_FLASH_WRITE_COUNT "快閃記憶體寫入計數" +#define D_MAC_ADDRESS "MACä½å€" #define D_MQTT_HOST "MQTT主機" -#define D_MQTT_PORT "MQTT端å£" +#define D_MQTT_PORT "MQTT通訊埠" #define D_MQTT_CLIENT "MQTT客戶端" -#define D_MQTT_USER "MQTT用戶å" +#define D_MQTT_USER "MQTT使用者å稱" #define D_MQTT_TOPIC "MQTT 主題(Topic)" -#define D_MQTT_GROUP_TOPIC "MQTT 主題組(Group Topic)" -#define D_MQTT_FULL_TOPIC "MQTT 完整主題(Full Topic)" -#define D_MDNS_DISCOVERY "mDNS 發ç¾" +#define D_MQTT_GROUP_TOPIC "MQTT 群組主題" +#define D_MQTT_FULL_TOPIC "MQTT 完整主題" +#define D_MDNS_DISCOVERY "mDNS 探索" #define D_MDNS_ADVERTISE "mDNS 廣播" -#define D_ESP_CHIP_ID "ESP芯片ID" -#define D_FLASH_CHIP_ID "Flash芯片ID" -#define D_FLASH_CHIP_SIZE "Flash大å°" -#define D_FREE_PROGRAM_SPACE "空閑程åºç©ºé–“" +#define D_ESP_CHIP_ID "ESP晶片ID" +#define D_FLASH_CHIP_ID "快閃記憶體ID" +#define D_FLASH_CHIP_SIZE "快閃記憶體大å°" +#define D_FREE_PROGRAM_SPACE "å¯ç”¨çš„程å¼ç©ºé–“" -#define D_UPGRADE_BY_WEBSERVER "通éŽWebå‡ç´š" -#define D_OTA_URL "OTA地å€" +#define D_UPGRADE_BY_WEBSERVER "é€éŽç¶²é å‡ç´š" +#define D_OTA_URL "OTAç¶²å€" #define D_START_UPGRADE "é–‹å§‹å‡ç´š" -#define D_UPGRADE_BY_FILE_UPLOAD "é€šéŽæ–‡ä»¶å‡ç´š" -#define D_UPLOAD_STARTED "開始上傳" -#define D_UPGRADE_STARTED "é–‹å§‹å‡ç´š" -#define D_UPLOAD_DONE "上傳完æˆ" -#define D_UPLOAD_ERR_1 "æ²’æœ‰é¸æ“‡æ–‡ä»¶" -#define D_UPLOAD_ERR_2 "沒有足夠空間" -#define D_UPLOAD_ERR_3 "å›ºä»¶é ­ä¸æ˜¯ 0xE9" -#define D_UPLOAD_ERR_4 "固件太大" -#define D_UPLOAD_ERR_5 "上傳緩沖å€ä¸åŒ¹é…" -#define D_UPLOAD_ERR_6 "上傳失敗。 啟用日志記錄 3" +#define D_UPGRADE_BY_FILE_UPLOAD "é€éŽæª”案å‡ç´š" +#define D_UPLOAD_STARTED "已開始上傳" +#define D_UPGRADE_STARTED "已開始å‡ç´š" +#define D_UPLOAD_DONE "已上傳完æˆ" +#define D_UPLOAD_ERR_1 "æ²’é¸æ“‡ä»»ä½•檔案" +#define D_UPLOAD_ERR_2 "å¯ç”¨ç©ºé–“ä¸è¶³" +#define D_UPLOAD_ERR_3 "魔術數字(Magic byte)䏿˜¯ 0xE9" +#define D_UPLOAD_ERR_4 "軟體刷入(Program flash)的大å°è¶…出實際記憶體的大å°" +#define D_UPLOAD_ERR_5 "Upload buffer miscompare" +#define D_UPLOAD_ERR_6 "上傳失敗。 啟用日誌記錄 3" #define D_UPLOAD_ERR_7 "ä¸Šå‚³å–æ¶ˆ" -#define D_UPLOAD_ERR_8 "錯誤的固件" -#define D_UPLOAD_ERR_9 "固件太大" +#define D_UPLOAD_ERR_8 "檔案無效" +#define D_UPLOAD_ERR_9 "檔案太大了" #define D_UPLOAD_ERR_10 "Failed to init RF chip" #define D_UPLOAD_ERR_11 "Failed to erase RF chip" #define D_UPLOAD_ERR_12 "Failed to write to RF chip" @@ -366,49 +366,49 @@ #define D_UPLOAD_ERROR_CODE "上傳錯誤代碼" #define D_ENTER_COMMAND "輸入命令" -#define D_ENABLE_WEBLOG_FOR_RESPONSE "å¦‚æžœé æœŸéŸ¿æ‡‰ï¼Œå‰‡å•Ÿç”¨Weblog 2" -#define D_NEED_USER_AND_PASSWORD "éœ€è¦ user=<用戶å>&password=<密碼>" +#define D_ENABLE_WEBLOG_FOR_RESPONSE "å¦‚æžœå›žæ‡‰å¦‚é æœŸï¼Œå•Ÿç”¨Weblog 2" +#define D_NEED_USER_AND_PASSWORD "éœ€è¦ user=<使用者å稱>&password=<密碼>" // xdrv_01_mqtt.ino -#define D_FINGERPRINT "é©—è­‰ TLS 指紋..." -#define D_TLS_CONNECT_FAILED_TO "TLS 連接失敗" -#define D_RETRY_IN "é‡è©¦å€’計時:" +#define D_FINGERPRINT "é©—è­‰ TLS 指紋碼..." +#define D_TLS_CONNECT_FAILED_TO "TLS 連線失敗,因為" +#define D_RETRY_IN "釿–°å˜—試倒數" #define D_VERIFIED "é©—è­‰æˆåŠŸ" -#define D_INSECURE "指紋無效導致連接ä¸å®‰å…¨" -#define D_CONNECT_FAILED_TO "連接失敗:" +#define D_INSECURE "由於指紋碼無效,因此連線並未加密" +#define D_CONNECT_FAILED_TO "連線失敗:" // xplg_wemohue.ino -#define D_MULTICAST_DISABLED "組播已ç¦ç”¨" -#define D_MULTICAST_REJOINED "組播已(釿–°)加入" -#define D_MULTICAST_JOIN_FAILED "組播加入失敗" -#define D_FAILED_TO_SEND_RESPONSE "請求發é€å¤±æ•—" +#define D_MULTICAST_DISABLED "群播已åœç”¨" +#define D_MULTICAST_REJOINED "å·²(釿–°)加入群播" +#define D_MULTICAST_JOIN_FAILED "加入群播失敗" +#define D_FAILED_TO_SEND_RESPONSE "發é€è«‹æ±‚失敗" #define D_WEMO "WeMo" -#define D_WEMO_BASIC_EVENT "WeMo 基礎事件" +#define D_WEMO_BASIC_EVENT "WeMo 基本事件" #define D_WEMO_EVENT_SERVICE "WeMo 事件æœå‹™" #define D_WEMO_META_SERVICE "WeMo meta æœå‹™" -#define D_WEMO_SETUP "WeMo 設置" -#define D_RESPONSE_SENT "發é€è«‹æ±‚" +#define D_WEMO_SETUP "WeMo 設定" +#define D_RESPONSE_SENT "請求已發é€" #define D_HUE "Hue" -#define D_HUE_BRIDGE_SETUP "Hue 設置" -#define D_HUE_API_NOT_IMPLEMENTED "Hue API 未實ç¾" +#define D_HUE_BRIDGE_SETUP "Hue 設定" +#define D_HUE_API_NOT_IMPLEMENTED "Hue API 尚未實ç¾" #define D_HUE_API "Hue API" #define D_HUE_POST_ARGS "Hue POST åƒæ•¸" -#define D_3_RESPONSE_PACKETS_SENT "3 請求包發é€" +#define D_3_RESPONSE_PACKETS_SENT "3 請求å°åŒ…已發é€" // xdrv_07_domoticz.ino -#define D_DOMOTICZ_PARAMETERS "Domoticz 設置" +#define D_DOMOTICZ_PARAMETERS "Domoticz 設定" #define D_DOMOTICZ_IDX "Idx" #define D_DOMOTICZ_KEY_IDX "Key idx" #define D_DOMOTICZ_SWITCH_IDX "é–‹é—œ idx" -#define D_DOMOTICZ_SENSOR_IDX "傳感器 idx" +#define D_DOMOTICZ_SENSOR_IDX "感應器 idx" #define D_DOMOTICZ_TEMP "溫度" - #define D_DOMOTICZ_TEMP_HUM "溫度,濕度" - #define D_DOMOTICZ_TEMP_HUM_BARO "溫度,濕度,氣壓" - #define D_DOMOTICZ_POWER_ENERGY "功率,é›»é‡" + #define D_DOMOTICZ_TEMP_HUM "æº«åº¦ã€æ¿•度" + #define D_DOMOTICZ_TEMP_HUM_BARO "æº«åº¦ã€æ¿•åº¦ã€æ°£å£“" + #define D_DOMOTICZ_POWER_ENERGY "功率ã€é›»é‡" #define D_DOMOTICZ_ILLUMINANCE "照度" - #define D_DOMOTICZ_COUNT "數值/PM1" + #define D_DOMOTICZ_COUNT "計數/PM1" #define D_DOMOTICZ_VOLTAGE "電壓/PM2.5" #define D_DOMOTICZ_CURRENT "é›»æµ/PM10" #define D_DOMOTICZ_AIRQUALITY "空氣å“質" @@ -469,25 +469,25 @@ #define D_DEVICE_OUTPUT "Output" // xsns_05_ds18b20.ino -#define D_SENSOR_BUSY "傳感器正忙" -#define D_SENSOR_CRC_ERROR "傳感器 CRC 校驗錯誤" -#define D_SENSORS_FOUND "發ç¾å‚³æ„Ÿå™¨" +#define D_SENSOR_BUSY "感應器忙碌中" +#define D_SENSOR_CRC_ERROR "感應器 CRC 校驗錯誤" +#define D_SENSORS_FOUND "找到感應器了" // xsns_06_dht.ino #define D_TIMEOUT_WAITING_FOR "等待超時" -#define D_START_SIGNAL_LOW "開始低電平" -#define D_START_SIGNAL_HIGH "開始高電平" -#define D_PULSE "pulse" +#define D_START_SIGNAL_LOW "開始低電平(signal low)" +#define D_START_SIGNAL_HIGH "開始高電平(signal high)" +#define D_PULSE "脈è¡" #define D_CHECKSUM_FAILURE "校驗失敗" // xsns_07_sht1x.ino -#define D_SENSOR_DID_NOT_ACK_COMMAND "傳感器沒有確èªå‘½ä»¤" -#define D_SHT1X_FOUND "ç™¼ç¾ SHT1X 傳感器" +#define D_SENSOR_DID_NOT_ACK_COMMAND "感應器並未確èªå‘½ä»¤" +#define D_SHT1X_FOUND "ç™¼ç¾ SHT1X 感應器了" // xsns_18_pms5003.ino #define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter -#define D_PARTICALS_BEYOND "顆粒物直徑大於" +#define D_PARTICALS_BEYOND "ç²’å­" // xsns_27_apds9960.ino #define D_GESTURE "Gesture" @@ -705,7 +705,7 @@ #define D_SENSOR_TCP_RXD "TCP Rx" // Units -#define D_UNIT_AMPERE "安" +#define D_UNIT_AMPERE "安培" #define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" #define D_UNIT_DEGREE "°" @@ -719,13 +719,13 @@ #define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" -#define D_UNIT_KILOOHM "åƒæ­" -#define D_UNIT_KILOWATTHOUR "åƒç“¦æ™‚" -#define D_UNIT_LUX "å‹’å…‹æ–¯" -#define D_UNIT_MICROGRAM_PER_CUBIC_METER "微克/立方米" +#define D_UNIT_KILOOHM "åƒæ­å§†" +#define D_UNIT_KILOWATTHOUR "åƒç“¦å°æ™‚" +#define D_UNIT_LUX "lux" +#define D_UNIT_MICROGRAM_PER_CUBIC_METER "微克/立方公尺" #define D_UNIT_MICROMETER "微米" #define D_UNIT_MICROSECOND "微秒" -#define D_UNIT_MILLIAMPERE "毫安" +#define D_UNIT_MILLIAMPERE "毫安培" #define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "毫秒" @@ -736,15 +736,15 @@ #define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "百帕" #define D_UNIT_SECOND "ç§’" -#define D_UNIT_SECTORS "扇å€" +#define D_UNIT_SECTORS "ç£å€" #define D_UNIT_VA "VA" #define D_UNIT_VAR "VAr" -#define D_UNIT_VOLT "ä¼" -#define D_UNIT_WATT "瓦" -#define D_UNIT_WATTHOUR "瓦時" +#define D_UNIT_VOLT "ä¼ç‰¹" +#define D_UNIT_WATT "瓦特" +#define D_UNIT_WATTHOUR "ç“¦å°æ™‚" #define D_UNIT_WATT_METER_QUADRAT "W/m²" -//SDM220, SDM120, LE01MR +//SDM220〠SDM120〠LE01MR #define D_PHASE_ANGLE "Phase Angle" #define D_IMPORT_ACTIVE "Import Active" #define D_EXPORT_ACTIVE "Export Active" @@ -819,4 +819,4 @@ #define D_SENSOR_BOILER_OT_RX "OpenTherm RX" #define D_SENSOR_BOILER_OT_TX "OpenTherm TX" -#endif // _LANGUAGE_ZH_TW_H_ +#endif // _LANGUAGE_ZH_TW_H_ \ No newline at end of file From 414982603b85ab09155e1e910c7dae9450539042 Mon Sep 17 00:00:00 2001 From: Khoa Ton Date: Tue, 14 Jul 2020 02:35:49 -0700 Subject: [PATCH 463/581] Fix error in example comment --- tasmota/xdsp_11_sevenseg.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdsp_11_sevenseg.ino b/tasmota/xdsp_11_sevenseg.ino index 701c83e7d..1db043ef2 100644 --- a/tasmota/xdsp_11_sevenseg.ino +++ b/tasmota/xdsp_11_sevenseg.ino @@ -149,7 +149,7 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin // x88 -> 58 // f8.5 -> 8.5 // f-9.34 -> -9.34 - // f:-9.34 -> -9.34 + // f:-9.34 -> -9.:34 // r255 -> 8. (all 8 segments on) switch (str[i]) { From c62679c3c851b073a0c10b562ee355b7a90eddc5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 11:57:10 +0200 Subject: [PATCH 464/581] Prep for more NRG drivers --- tasmota/xnrg_interface.ino | 62 +++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/tasmota/xnrg_interface.ino b/tasmota/xnrg_interface.ino index 8e5bbf836..f6a9a051f 100644 --- a/tasmota/xnrg_interface.ino +++ b/tasmota/xnrg_interface.ino @@ -90,7 +90,67 @@ bool (* const xnrg_func_ptr[])(uint8_t) = { // Energy driver Function Pointers #endif #ifdef XNRG_17 - &Xnrg17 + &Xnrg17, +#endif + +#ifdef XNRG_18 + &Xnrg18, +#endif + +#ifdef XNRG_19 + &Xnrg19, +#endif + +#ifdef XNRG_20 + &Xnrg20, +#endif + +#ifdef XNRG_21 + &Xnrg21, +#endif + +#ifdef XNRG_22 + &Xnrg22, +#endif + +#ifdef XNRG_23 + &Xnrg23, +#endif + +#ifdef XNRG_24 + &Xnrg24, +#endif + +#ifdef XNRG_25 + &Xnrg25, +#endif + +#ifdef XNRG_26 + &Xnrg26, +#endif + +#ifdef XNRG_27 + &Xnrg27, +#endif + +#ifdef XNRG_28 + &Xnrg28, +#endif + +#ifdef XNRG_29 + &Xnrg29, +#endif + +#ifdef XNRG_30 + &Xnrg30, +#endif + +#ifdef XNRG_31 + &Xnrg31, +#endif + +#ifdef XNRG_32 + &Xnrg32 #endif }; From cd6e23757cdf57968dc6c0df339c773b2f6da822 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 15:01:41 +0200 Subject: [PATCH 465/581] Refactor rotary encoder --- tasmota/support_rotary.ino | 71 ++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 41 deletions(-) diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index d58ebd560..4fc776511 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -43,15 +43,15 @@ const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 const uint8_t ROTARY_TIMEOUT = 10; // 10 * RotaryHandler() call which is usually 10 * 0.05 seconds +const uint8_t ROTARY_DEBOUNCE = 10; // Debounce time in milliseconds struct ROTARY { bool present = false; } Rotary; -struct ENCODER { +struct tEncoder { uint32_t debounce = 0; - int8_t abs_position1 = 0; - int8_t abs_position2 = 0; + int8_t abs_position[2] = { 0 }; int8_t direction = 0; // Control consistent direction int8_t pin = -1; uint8_t position = 128; @@ -59,32 +59,11 @@ struct ENCODER { uint8_t timeout = 0; // Disallow direction change within 0.5 second bool changed = false; bool busy = false; -} Encoder[MAX_ROTARIES]; +}; +tEncoder Encoder[MAX_ROTARIES]; /********************************************************************************************/ -void ICACHE_RAM_ATTR RotaryIsr(uint32_t index) { - if (Encoder[index].busy) { return; } - - uint32_t time = micros(); - if (Encoder[index].debounce < time) { - int direction = (digitalRead(Encoder[index].pin)) ? -1 : 1; - if ((0 == Encoder[index].direction) || (direction == Encoder[index].direction)) { - Encoder[index].position += direction; - Encoder[index].direction = direction; - } - Encoder[index].debounce = time +50; // Experimental debounce in microseconds - } -} - -void ICACHE_RAM_ATTR RotaryIsr1(void) { - RotaryIsr(0); -} - -void ICACHE_RAM_ATTR RotaryIsr2(void) { - RotaryIsr(1); -} - bool RotaryButtonPressed(uint32_t button_index) { if (!Rotary.present) { return false; } @@ -107,6 +86,22 @@ bool RotaryButtonPressed(uint32_t button_index) { return false; } +void ICACHE_RAM_ATTR RotaryIsrArg(void *arg) { + tEncoder* encoder = static_cast(arg); + + if (encoder->busy) { return; } + + uint32_t time = millis(); + if ((encoder->debounce < time) || (encoder->debounce > time + ROTARY_DEBOUNCE)) { + int direction = (digitalRead(encoder->pin)) ? -1 : 1; + if ((0 == encoder->direction) || (direction == encoder->direction)) { + encoder->position += direction; + encoder->direction = direction; + } + encoder->debounce = time + ROTARY_DEBOUNCE; // Experimental debounce + } +} + void RotaryInit(void) { Rotary.present = false; for (uint32_t index = 0; index < MAX_ROTARIES; index++) { @@ -119,11 +114,7 @@ void RotaryInit(void) { Encoder[index].pin = Pin(GPIO_ROT1B, idx); pinMode(Encoder[index].pin, INPUT_PULLUP); pinMode(Pin(GPIO_ROT1A, idx), INPUT_PULLUP); - if (0 == index) { - attachInterrupt(Pin(GPIO_ROT1A, idx), RotaryIsr1, FALLING); - } else { - attachInterrupt(Pin(GPIO_ROT1A, idx), RotaryIsr2, FALLING); - } + attachInterruptArg(Pin(GPIO_ROT1A, idx), RotaryIsrArg, &Encoder[index], FALLING); } Rotary.present |= (Encoder[index].pin > -1); } @@ -160,7 +151,7 @@ void RotaryHandler(void) { int rotary_position = Encoder[index].position - Encoder[index].last_position; if (Settings.save_data && (save_data_counter < 2)) { - save_data_counter = 2; // Postpone flash writes while rotary is turned + save_data_counter = 3; // Postpone flash writes while rotary is turned } bool button_pressed = (Button.hold_timer[index]); // Button is pressed: set color temperature @@ -191,16 +182,14 @@ void RotaryHandler(void) { } } else { #endif // USE_LIGHT - if (button_pressed) { - Encoder[index].abs_position2 += rotary_position; - if (Encoder[index].abs_position2 < 0) { Encoder[index].abs_position2 = 0; } - if (Encoder[index].abs_position2 > ROTARY_MAX_STEPS) { Encoder[index].abs_position2 = ROTARY_MAX_STEPS; } - } else { - Encoder[index].abs_position1 += rotary_position; - if (Encoder[index].abs_position1 < 0) { Encoder[index].abs_position1 = 0; } - if (Encoder[index].abs_position1 > ROTARY_MAX_STEPS) { Encoder[index].abs_position1 = ROTARY_MAX_STEPS; } + Encoder[index].abs_position[button_pressed] += rotary_position; + if (Encoder[index].abs_position[button_pressed] < 0) { + Encoder[index].abs_position[button_pressed] = 0; } - Response_P(PSTR("{\"Rotary%d\":{\"Pos1\":%d,\"Pos2\":%d}}"), index +1, Encoder[index].abs_position1, Encoder[index].abs_position2); + if (Encoder[index].abs_position[button_pressed] > ROTARY_MAX_STEPS) { + Encoder[index].abs_position[button_pressed] = ROTARY_MAX_STEPS; + } + Response_P(PSTR("{\"Rotary%d\":{\"Pos1\":%d,\"Pos2\":%d}}"), index +1, Encoder[index].abs_position[0], Encoder[index].abs_position[1]); XdrvRulesProcess(); #ifdef USE_LIGHT } From b7c7943b00ba879cf153e8df132193f25ef01cc3 Mon Sep 17 00:00:00 2001 From: Sammy BAUER Date: Tue, 14 Jul 2020 16:07:35 +0200 Subject: [PATCH 466/581] ESP32 port: JSON error A double quote is missing in the JSON response of the status command, so the result is not valid for ESP32. --- tasmota/support_command.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index a54b50e89..abd75960e 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -470,7 +470,7 @@ void CmndStatus(void) if ((0 == payload) || (4 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_JSON_PROGRAMSIZE "\":%d,\"" D_JSON_FREEMEMORY "\":%d,\"" D_JSON_HEAPSIZE "\":%d,\"" #ifdef ESP32 - D_JSON_PSRMAXMEMORY "\":%d,\"" D_JSON_PSRFREEMEMORY "\":%d," + D_JSON_PSRMAXMEMORY "\":%d,\"" D_JSON_PSRFREEMEMORY "\":%d,\"" #endif D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d" #ifdef ESP8266 @@ -2016,4 +2016,4 @@ void CmndTouchNum(void) } -#endif //ESP32 \ No newline at end of file +#endif //ESP32 From f3c391b160f2058f68b1e60577d4aa0465bf68c1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 16:21:11 +0200 Subject: [PATCH 467/581] Fix GCC 10.1 errors and warnings --- .../src/epd2in9.cpp | 1 + .../src/epd4in2.cpp | 11 ++-- .../src/epdpaint.cpp | 2 +- lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp | 2 + lib/esp-knx-ip-0.5.2/esp-knx-ip.h | 3 +- tasmota/support_float.ino | 2 + tasmota/support_network.ino | 3 + tasmota/xdrv_04_light.ino | 2 +- tasmota/xdrv_10_rules.ino | 1 + tasmota/xdrv_22_sonoff_ifan.ino | 62 +++++++++---------- tasmota/xnrg_02_cse7766.ino | 4 +- tasmota/xnrg_14_bl0940.ino | 4 +- 12 files changed, 54 insertions(+), 43 deletions(-) diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp index 90e257483..81fa618a8 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp @@ -81,6 +81,7 @@ int16_t Epd::Begin(int16_t cs,int16_t mosi,int16_t sclk) { cs_pin=cs; mosi_pin=mosi; sclk_pin=sclk; + return 0; } diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp index 8450a9647..923e72106 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp @@ -94,6 +94,7 @@ int16_t Epd42::Begin(int16_t cs,int16_t mosi,int16_t sclk) { cs_pin=cs; mosi_pin=mosi; sclk_pin=sclk; + return 0; } void Epd42::Init(int8_t p) { @@ -130,14 +131,14 @@ int Epd42::Init(void) { SendCommand(PANEL_SETTING); // SendData(0xbf); // KW-BF KWR-AF BWROTP 0f // SendData(0x0b); -// SendData(0x0F); //300x400 Red mode, LUT from OTP -// SendData(0x1F); //300x400 B/W mode, LUT from OTP - SendData(0x3F); //300x400 B/W mode, LUT set by register -// SendData(0x2F); //300x400 Red mode, LUT set by register +// SendData(0x0F); //300x400 Red mode, LUT from OTP +// SendData(0x1F); //300x400 B/W mode, LUT from OTP + SendData(0x3F); //300x400 B/W mode, LUT set by register +// SendData(0x2F); //300x400 Red mode, LUT set by register SendCommand(PLL_CONTROL); SendData(0x3C); // 3A 100Hz 29 150Hz 39 200Hz 31 171Hz 3C 50Hz (default) 0B 10Hz - //SendData(0x0B); //0B is 10Hz + //SendData(0x0B); //0B is 10Hz /* EPD hardware init end */ return 0; } diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.cpp index 7b6db3206..d201c3d63 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.cpp @@ -38,7 +38,7 @@ void Paint::DisplayOnff(int8_t on) { } int16_t Paint::Begin(int16_t p1,int16_t p2,int16_t p3) { - + return 0; } void Paint::Updateframe() { diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp b/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp index 96f4e1c73..35cbb2161 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp @@ -247,6 +247,7 @@ callback_assignment_id_t ESPKNXIP::__callback_register_assignment(address_t addr return id; } } + return -1; } void ESPKNXIP::__callback_delete_assignment(callback_assignment_id_t id) @@ -358,6 +359,7 @@ callback_id_t ESPKNXIP::callback_register(String name, callback_fptr_t cb, void return id; } } + return -1; } void ESPKNXIP::callback_deregister(callback_id_t id) diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h index 7150706bb..6834a6125 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h @@ -270,7 +270,8 @@ typedef struct __cemi_msg uint8_t additional_info_len; union { - cemi_addi_t additional_info[]; +// cemi_addi_t additional_info[]; // Errors in GCC 10.1 + cemi_addi_t additional_info[10]; // Changed to arbitrary number to fix compilation cemi_service_t service_information; } data; } cemi_msg_t; diff --git a/tasmota/support_float.ino b/tasmota/support_float.ino index 98553d183..a72712632 100644 --- a/tasmota/support_float.ino +++ b/tasmota/support_float.ino @@ -218,6 +218,7 @@ float cos_52(float x) case 2: return -cos_52s(x-(float)f_pi); case 3: return cos_52s((float)f_twopi - x); } + return 0.0; // Never reached. Fixes compiler warning } // // The sine is just cosine shifted a half-f_pi, so @@ -278,6 +279,7 @@ float tan_56(float x) case 6: return -1.0f / tan_56s((x-(float)f_threehalfpi) * (float)f_four_over_pi); case 7: return - tan_56s(((float)f_twopi - x) * (float)f_four_over_pi); } + return 0.0; // Never reached. Fixes compiler warning } // ******************************************************************* diff --git a/tasmota/support_network.ino b/tasmota/support_network.ino index 4f6da4d88..efbd0be92 100644 --- a/tasmota/support_network.ino +++ b/tasmota/support_network.ino @@ -99,6 +99,7 @@ char* NetworkHostname(void) { } #endif #endif + return nullptr; // Never reached. Fix GCC10 warning } IPAddress NetworkAddress(void) { @@ -112,6 +113,7 @@ IPAddress NetworkAddress(void) { } #endif #endif + return 0; // Never reached. Fix GCC10 warning } String NetworkMacAddress(void) { @@ -125,4 +127,5 @@ String NetworkMacAddress(void) { } #endif #endif + return ""; // Never reached. Fix GCC10 warning } diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index d284e71fe..ab311d6f0 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -477,7 +477,7 @@ class LightStateClass { if (w) { *w = ct_channels_on ? changeUIntScale(_ww, 0, 255, 0, _briCT) : 0; } } - uint8_t getChannels(uint8_t *channels) { + void getChannels(uint8_t *channels) { getActualRGBCW(&channels[0], &channels[1], &channels[2], &channels[3], &channels[4]); } diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index db22183c5..782116fc0 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -294,6 +294,7 @@ String GetRule(uint32_t idx) { return rule; #endif } + return ""; // Fix GCC10 warning } #ifdef USE_UNISHOX_COMPRESSION diff --git a/tasmota/xdrv_22_sonoff_ifan.ino b/tasmota/xdrv_22_sonoff_ifan.ino index 8c6ceffb6..a51265f99 100644 --- a/tasmota/xdrv_22_sonoff_ifan.ino +++ b/tasmota/xdrv_22_sonoff_ifan.ino @@ -156,38 +156,38 @@ void SonoffIfanReceived(void) bool SonoffIfanSerialInput(void) { - if (SONOFF_IFAN03 == my_module_type) { - if (0xAA == serial_in_byte) { // 0xAA - Start of text - serial_in_byte_counter = 0; - ifan_receive_flag = true; - } - if (ifan_receive_flag) { - serial_in_buffer[serial_in_byte_counter++] = serial_in_byte; - if (serial_in_byte_counter == 8) { - // AA 55 01 01 00 01 01 04 - Wifi long press - start wifi setup - // AA 55 01 01 00 01 02 05 - Rf and Wifi short press - // AA 55 01 04 00 01 00 06 - Fan 0 - // AA 55 01 04 00 01 01 07 - Fan 1 - // AA 55 01 04 00 01 02 08 - Fan 2 - // AA 55 01 04 00 01 03 09 - Fan 3 - // AA 55 01 04 00 01 04 0A - Light - // AA 55 01 06 00 01 01 09 - Buzzer - // AA 55 01 07 00 01 01 0A - Rf long press - forget RF codes - AddLogSerial(LOG_LEVEL_DEBUG); - uint8_t crc = 0; - for (uint32_t i = 2; i < 7; i++) { - crc += serial_in_buffer[i]; - } - if (crc == serial_in_buffer[7]) { - SonoffIfanReceived(); - ifan_receive_flag = false; - return true; - } - } - serial_in_byte = 0; - } - return false; + if (SONOFF_IFAN03 != my_module_type) { return false; } + + if (0xAA == serial_in_byte) { // 0xAA - Start of text + serial_in_byte_counter = 0; + ifan_receive_flag = true; } + if (ifan_receive_flag) { + serial_in_buffer[serial_in_byte_counter++] = serial_in_byte; + if (serial_in_byte_counter == 8) { + // AA 55 01 01 00 01 01 04 - Wifi long press - start wifi setup + // AA 55 01 01 00 01 02 05 - Rf and Wifi short press + // AA 55 01 04 00 01 00 06 - Fan 0 + // AA 55 01 04 00 01 01 07 - Fan 1 + // AA 55 01 04 00 01 02 08 - Fan 2 + // AA 55 01 04 00 01 03 09 - Fan 3 + // AA 55 01 04 00 01 04 0A - Light + // AA 55 01 06 00 01 01 09 - Buzzer + // AA 55 01 07 00 01 01 0A - Rf long press - forget RF codes + AddLogSerial(LOG_LEVEL_DEBUG); + uint8_t crc = 0; + for (uint32_t i = 2; i < 7; i++) { + crc += serial_in_buffer[i]; + } + if (crc == serial_in_buffer[7]) { + SonoffIfanReceived(); + ifan_receive_flag = false; + return true; + } + } + serial_in_byte = 0; + } + return false; } /*********************************************************************************************\ diff --git a/tasmota/xnrg_02_cse7766.ino b/tasmota/xnrg_02_cse7766.ino index 9c8417bc6..053c4c6ba 100644 --- a/tasmota/xnrg_02_cse7766.ino +++ b/tasmota/xnrg_02_cse7766.ino @@ -141,7 +141,7 @@ void CseReceived(void) { } } -bool CseSerialInput(void) { +void CseSerialInput(void) { while (CseSerial->available()) { yield(); uint8_t serial_in_byte = CseSerial->read(); @@ -158,7 +158,7 @@ bool CseSerialInput(void) { Energy.data_valid[0] = 0; CseReceived(); Cse.received = false; - return true; + return; } else { do { // Sync buffer with data (issue #1907 and #3425) memmove(Cse.rx_buffer, Cse.rx_buffer +1, 24); diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino index fae36ea3a..7b021106f 100644 --- a/tasmota/xnrg_14_bl0940.ino +++ b/tasmota/xnrg_14_bl0940.ino @@ -121,7 +121,7 @@ void Bl0940Received(void) { } } -bool Bl0940SerialInput(void) { +void Bl0940SerialInput(void) { while (Bl0940Serial->available()) { yield(); uint8_t serial_in_byte = Bl0940Serial->read(); @@ -142,7 +142,7 @@ bool Bl0940SerialInput(void) { Energy.data_valid[0] = 0; Bl0940Received(); Bl0940.received = false; - return true; + return; } else { do { // Sync buffer with data (issue #1907 and #3425) memmove(Bl0940.rx_buffer, Bl0940.rx_buffer +1, BL0940_BUFFER_SIZE -1); From 95a6e483d8a0bd6bcb9c50e9b34aefd5eb48391a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 16:46:01 +0200 Subject: [PATCH 468/581] Fix GCC 10.1 warnings --- lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.cpp | 2 +- lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.h | 2 +- lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp | 3 +-- lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h | 2 +- lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp | 3 +-- lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.h | 2 +- lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.cpp | 3 +-- lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.h | 2 +- lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp | 5 +++-- lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.h | 2 +- 10 files changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.cpp b/lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.cpp index fac803b53..7f368c5d5 100644 --- a/lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.cpp +++ b/lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.cpp @@ -72,7 +72,7 @@ void Adafruit_SH1106::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { //} } -int16_t Adafruit_SH1106::Begin(int16_t p1,int16_t p2,int16_t p3) { +void Adafruit_SH1106::Begin(int16_t p1,int16_t p2,int16_t p3) { begin(p1,p2,p3); } diff --git a/lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.h b/lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.h index b0562629b..efa14e8f1 100644 --- a/lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.h +++ b/lib/Adafruit_SH1106-gemu-1.0/Adafruit_SH1106.h @@ -144,7 +144,7 @@ class Adafruit_SH1106 : public Renderer { void DisplayOnff(int8_t on); void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); - int16_t Begin(int16_t p1,int16_t p2,int16_t p3); + void Begin(int16_t p1,int16_t p2,int16_t p3); void Updateframe(); void dim(uint8_t contrast); diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp index 81fa618a8..556f9624f 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp @@ -77,11 +77,10 @@ void Epd::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { fillScreen(BLACK); } -int16_t Epd::Begin(int16_t cs,int16_t mosi,int16_t sclk) { +void Epd::Begin(int16_t cs,int16_t mosi,int16_t sclk) { cs_pin=cs; mosi_pin=mosi; sclk_pin=sclk; - return 0; } diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h index 3fc8ea190..bf0863cd0 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h @@ -91,7 +91,7 @@ public: void DisplayOnff(int8_t on); void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); - int16_t Begin(int16_t p1,int16_t p2,int16_t p3); + void Begin(int16_t p1,int16_t p2,int16_t p3); void Updateframe(); private: diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp index 923e72106..85da5848d 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp @@ -90,11 +90,10 @@ void Epd42::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { fillScreen(BLACK); } -int16_t Epd42::Begin(int16_t cs,int16_t mosi,int16_t sclk) { +void Epd42::Begin(int16_t cs,int16_t mosi,int16_t sclk) { cs_pin=cs; mosi_pin=mosi; sclk_pin=sclk; - return 0; } void Epd42::Init(int8_t p) { diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.h b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.h index 9b140c0d8..1ca993873 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.h +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.h @@ -113,7 +113,7 @@ public: void DisplayOnff(int8_t on); void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); - int16_t Begin(int16_t p1,int16_t p2,int16_t p3); + void Begin(int16_t p1,int16_t p2,int16_t p3); void Updateframe(); private: diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.cpp index d201c3d63..4d27e00a4 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.cpp @@ -37,8 +37,7 @@ Renderer(width,height) { void Paint::DisplayOnff(int8_t on) { } -int16_t Paint::Begin(int16_t p1,int16_t p2,int16_t p3) { - return 0; +void Paint::Begin(int16_t p1,int16_t p2,int16_t p3) { } void Paint::Updateframe() { diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.h b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.h index c70d762d1..b54634f74 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.h +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epdpaint.h @@ -49,7 +49,7 @@ public: void DisplayOnff(int8_t on); void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); - int16_t Begin(int16_t p1,int16_t p2,int16_t p3); + void Begin(int16_t p1,int16_t p2,int16_t p3); void Updateframe(); }; diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp index 722d5ffb1..01b8dc7c3 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp @@ -71,12 +71,13 @@ void Renderer::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) void Renderer::DisplayOnff(int8_t on) { } + void Renderer::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { } -int16_t Renderer::Begin(int16_t p1,int16_t p2,int16_t p3) { - return 0; +void Renderer::Begin(int16_t p1,int16_t p2,int16_t p3) { + } void Renderer::Updateframe() { diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.h b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.h index 3f87f2a89..09347ae29 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.h +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.h @@ -30,7 +30,7 @@ public: virtual void DisplayOnff(int8_t on); virtual void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); - virtual int16_t Begin(int16_t p1,int16_t p2,int16_t p3); + virtual void Begin(int16_t p1,int16_t p2,int16_t p3); virtual void Updateframe(); virtual void dim(uint8_t contrast); virtual void pushColors(uint16_t *data, uint8_t len, boolean first); From 7e03cbedda4ff5caac12998c4324ff3ce0f88571 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 16:57:49 +0200 Subject: [PATCH 469/581] Fix GCC 10.1 errors and warnings --- tasmota/support_network.ino | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tasmota/support_network.ino b/tasmota/support_network.ino index efbd0be92..7bf7df30c 100644 --- a/tasmota/support_network.ino +++ b/tasmota/support_network.ino @@ -103,17 +103,18 @@ char* NetworkHostname(void) { } IPAddress NetworkAddress(void) { + IPAddress result; if (global_state.eth_down) { - return WiFi.localIP(); + result = WiFi.localIP(); } #ifdef ESP32 #ifdef USE_ETHERNET else { - return EthernetLocalIP(); + result = EthernetLocalIP(); } #endif #endif - return 0; // Never reached. Fix GCC10 warning + return result; } String NetworkMacAddress(void) { @@ -127,5 +128,5 @@ String NetworkMacAddress(void) { } #endif #endif - return ""; // Never reached. Fix GCC10 warning + return String(""); // Never reached. Fix GCC10 warning } From 6843f58a91058ed01c8591b7e137b70871f38ff2 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 17:37:14 +0200 Subject: [PATCH 470/581] Add support for Schneider Electric iEM3000 Add support for Schneider Electric iEM3000 series Modbus energy meter by Marius Bezuidenhout --- RELEASENOTES.md | 7 ++++--- tasmota/CHANGELOG.md | 1 + tasmota/xdrv_16_tuyamcu.ino | 8 ++++---- tasmota/{xnrg_17_iem3000.ino => xnrg_16_iem3000.ino} | 12 ++++++------ tasmota/xnrg_interface.ino | 2 +- tools/decode-status.py | 4 ++-- 6 files changed, 18 insertions(+), 16 deletions(-) rename tasmota/{xnrg_17_iem3000.ino => xnrg_16_iem3000.ino} (97%) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index fdafb0535..7e0208ef1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -71,6 +71,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` +- Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet - Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) - Add more functionality to ``Switchmode`` 11 and 12 (#8450) - Add wildcard pattern ``?`` for JSON matching in rules @@ -84,14 +85,14 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) - Add support for up to eight MCP9808 temperature sensors by device111 (#8594) - Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) -- Add initial support for Telegram bot (#8619) +- Add support for Telegram bot (#8619) - Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) -- Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet - Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff - Add Library to be used for decoding Teleinfo (French Metering Smart Meter) -- Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON +- Add support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) - Add compile time interlock parameters (#8759) - Add compile time user template (#8766) - Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) - Add support for switches/relays using an AC detection circuitry e.g. MOES MS-104B or BlitzWolf SS5 (#8606) +- Add support for Schneider Electric iEM3000 series Modbus energy meter by Marius Bezuidenhout diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index a459c2aac..854969579 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -12,6 +12,7 @@ - Add compile time user template (#8766) - Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) - Add support for switches/relays using an AC detection circuitry e.g. MOES MS-104B or BlitzWolf SS5 (#8606) +- Add support for Schneider Electric iEM3000 series Modbus energy meter by Marius Bezuidenhout - Fix exception or watchdog on rule re-entry (#8757) - Change ESP32 USER GPIO template representation decreasing template message size - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index fcc6848db..7165126f5 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -21,7 +21,7 @@ #ifdef USE_TUYA_MCU #define XDRV_16 16 -#define XNRG_16 16 // Needs to be the last XNRG_xx +#define XNRG_32 32 // Needs to be the last XNRG_xx #ifndef TUYA_DIMMER_ID #define TUYA_DIMMER_ID 0 @@ -455,7 +455,7 @@ void TuyaProcessStatePacket(void) { } else if (Tuya.buffer[dpidStart + 1] == 2) { // Data Type 2 - bool tuya_energy_enabled = (XNRG_16 == energy_flg); + bool tuya_energy_enabled = (XNRG_32 == energy_flg); uint16_t packetValue = Tuya.buffer[dpidStart + 6] << 8 | Tuya.buffer[dpidStart + 7]; if (fnId == TUYA_MCU_FUNC_DIMMER) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Dim State=%d"), packetValue); @@ -827,7 +827,7 @@ void TuyaSetTime(void) * Energy Interface \*********************************************************************************************/ -bool Xnrg16(uint8_t function) +bool Xnrg32(uint8_t function) { bool result = false; @@ -840,7 +840,7 @@ bool Xnrg16(uint8_t function) if (TuyaGetDpId(TUYA_MCU_FUNC_VOLTAGE) == 0) { Energy.voltage_available = false; } - energy_flg = XNRG_16; + energy_flg = XNRG_32; } } } diff --git a/tasmota/xnrg_17_iem3000.ino b/tasmota/xnrg_16_iem3000.ino similarity index 97% rename from tasmota/xnrg_17_iem3000.ino rename to tasmota/xnrg_16_iem3000.ino index 040938dbc..807d142e3 100644 --- a/tasmota/xnrg_17_iem3000.ino +++ b/tasmota/xnrg_16_iem3000.ino @@ -1,5 +1,5 @@ /* - xnrg_17_iem3000.ino - Schneider Electric iEM3000 series Modbus energy meter support for Tasmota + xnrg_16_iem3000.ino - Schneider Electric iEM3000 series Modbus energy meter support for Tasmota Copyright (C) 2020 Marius Bezuidenhout @@ -25,7 +25,7 @@ * Important! Set meter Commnication -> Parity to None \*********************************************************************************************/ -#define XNRG_17 17 +#define XNRG_16 16 // can be user defined in my_user_config.h #ifndef IEM3000_SPEED @@ -105,11 +105,11 @@ void IEM3000Every250ms(void) case 0: Energy.current[0] = value; break; - + case 1: Energy.current[1] = value; break; - + case 2: Energy.current[2] = value; break; @@ -178,7 +178,7 @@ void Iem3000SnsInit(void) void Iem3000DrvInit(void) { if (PinUsed(GPIO_IEM3000_RX) && PinUsed(GPIO_IEM3000_TX)) { - energy_flg = XNRG_17; + energy_flg = XNRG_16; } } @@ -186,7 +186,7 @@ void Iem3000DrvInit(void) * Interface \*********************************************************************************************/ -bool Xnrg17(uint8_t function) +bool Xnrg16(uint8_t function) { bool result = false; diff --git a/tasmota/xnrg_interface.ino b/tasmota/xnrg_interface.ino index f6a9a051f..97ab5aec2 100644 --- a/tasmota/xnrg_interface.ino +++ b/tasmota/xnrg_interface.ino @@ -149,7 +149,7 @@ bool (* const xnrg_func_ptr[])(uint8_t) = { // Energy driver Function Pointers &Xnrg31, #endif -#ifdef XNRG_32 +#ifdef XNRG_32 // Reserved for use by xdrv_16_tuyamcu.ino &Xnrg32 #endif }; diff --git a/tools/decode-status.py b/tools/decode-status.py index e6e4138bd..22329c5f6 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -209,7 +209,7 @@ a_features = [[ "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", "USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM", "USE_HP303B","USE_TCP_BRIDGE","USE_TELEINFO","USE_LMT01", - "USE_PROMETHEUS","","","", + "USE_PROMETHEUS","USE_IEM3000","","", "","","","", "","","USE_ETHERNET","USE_WEBCAM" ]] @@ -239,7 +239,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200704 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200714 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From 151dc5f6b80b3571c4df508c9150a36c8f74c86e Mon Sep 17 00:00:00 2001 From: SODAIS69 <6829907+SODAIS69@users.noreply.github.com> Date: Tue, 14 Jul 2020 23:58:10 +0800 Subject: [PATCH 471/581] Add translations for zh_TW --- tasmota/language/zh_TW.h | 310 +++++++++++++++++++-------------------- 1 file changed, 155 insertions(+), 155 deletions(-) diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index b6ab27b3e..04d39dd91 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -32,7 +32,7 @@ \*********************************************************************/ //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) - +// https://www.science.co.il/language/Locale-codes.php #define LANGUAGE_LCID 1028 // HTML (ISO 639-1) Language Code #define D_HTML_LANGUAGE "zh" @@ -44,8 +44,8 @@ #define D_HOUR_MINUTE_SEPARATOR ":" #define D_MINUTE_SECOND_SEPARATOR ":" -#define D_DAY3LIST "SunMonTueWedThuFriSat" -#define D_MONTH3LIST "JanFebMarAprMayJunJulAugSepOctNovDec" +#define D_DAY3LIST "æ—¥ 一 二 三 å›› 五 å…­ " +#define D_MONTH3LIST "1月 2月 3月 4月 5月 6月 7月 8月 9月 10月11月12月" // Non JSON decimal separator #define D_DECIMAL_SEPARATOR "." @@ -66,13 +66,13 @@ #define D_BY "ç”±" // Written by me #define D_BYTES "大å°:" #define D_CELSIUS "æ”æ°" -#define D_CHANNEL "Channel" +#define D_CHANNEL "é »é“" #define D_CO2 "二氧化碳" #define D_CODE "代碼" // Button code #define D_COLDLIGHT "冷光" #define D_COMMAND "命令:" #define D_CONNECTED "已連線" -#define D_CORS_DOMAIN "CORS Domain" +#define D_CORS_DOMAIN "跨來æºè³‡æºå…±äº«çš„網域(CORS Domain)" #define D_COUNT "數é‡:" #define D_COUNTER "Counter" #define D_CT_POWER "CT Power" @@ -95,12 +95,12 @@ #define D_FAILED "失敗了" #define D_FALLBACK "Fallback" #define D_FALLBACK_TOPIC "Fallback Topic" -#define D_FALSE "False" +#define D_FALSE "å‡" #define D_FILE "檔案:" -#define D_FLOW_RATE "Flow rate" +#define D_FLOW_RATE "æµé‡" #define D_FREE_MEMORY "å¯ç”¨çš„記憶體" -#define D_PSR_MAX_MEMORY "PS-RAM Memory" -#define D_PSR_FREE_MEMORY "PS-RAM free Memory" +#define D_PSR_MAX_MEMORY "å½éœæ…‹éš¨æ©Ÿå­˜å–記憶體(PS-RAM)容é‡" +#define D_PSR_FREE_MEMORY "å½éœæ…‹éš¨æ©Ÿå­˜å–記憶體(PS-RAM)å¯ç”¨ç©ºé–“" #define D_FREQUENCY "頻率" #define D_GAS "氣體" #define D_GATEWAY "é–˜é“器" @@ -119,9 +119,9 @@ #define D_LWT "LWT" #define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "模組" -#define D_MOISTURE "Moisture" +#define D_MOISTURE "濕度"" #define D_MQTT "MQTT" -#define D_MULTI_PRESS "多次按éµ" +#define D_MULTI_PRESS "多é‡é»žæ“Š" #define D_NOISE "雜訊" #define D_NONE "ç„¡" #define D_OFF "關閉" @@ -133,16 +133,16 @@ #define D_PORT "通訊埠" #define D_POWER_FACTOR "功率因數" #define D_POWERUSAGE "用電é‡" -#define D_POWERUSAGE_ACTIVE "Active Power" -#define D_POWERUSAGE_APPARENT "Apparent Power" -#define D_POWERUSAGE_REACTIVE "Reactive Power" +#define D_POWERUSAGE_ACTIVE "有功功率" +#define D_POWERUSAGE_APPARENT "視在功率" +#define D_POWERUSAGE_REACTIVE "虛功率" #define D_PRESSURE "氣壓" #define D_PRESSUREATSEALEVEL "æµ·å¹³é¢æ°£å£“" #define D_PROGRAM_FLASH_SIZE "程å¼è¨˜æ†¶é«”大å°" #define D_PROGRAM_SIZE "程å¼å¤§å°" #define D_PROJECT "é …ç›®:" -#define D_RAIN "Rain" -#define D_RANGE "Range" +#define D_RAIN "雨" +#define D_RANGE "範åœ" #define D_RECEIVED "已接收" #define D_RESTART "釿–°å•Ÿå‹•" #define D_RESTARTING "æ­£åœ¨é‡æ–°å•Ÿå‹•" @@ -163,12 +163,12 @@ #define D_SUNRISE "日出" #define D_SUNSET "æ—¥è½" #define D_TEMPERATURE "溫度" -#define D_TO "to" +#define D_TO "到" #define D_TOGGLE "切æ›" #define D_TOPIC "主題" #define D_TOTAL_USAGE "總使用é‡" #define D_TRANSMIT "發é€" -#define D_TRUE "True" +#define D_TRUE "真" #define D_TVOC "TVOC" #define D_UPGRADE "å‡ç´š" #define D_UPLOAD "上傳" @@ -194,7 +194,7 @@ // tasmota.ino #define D_WARNING_MINIMAL_VERSION "è­¦å‘Šï¼Œé€™å€‹ç‰ˆæœ¬ä¸¦ä¸æ”¯æ´å°‡è¨­å®šæ°¸ä¹…的儲存!" #define D_LEVEL_10 "等級 1-0" -#define D_LEVEL_01 "等其 0-1" +#define D_LEVEL_01 "等級 0-1" #define D_SERIAL_LOGGING_DISABLED "å·²åœç”¨åºåˆ—埠日誌" #define D_SYSLOG_LOGGING_REENABLED "ç³»çµ±æ—¥èªŒå·²ç¶“é‡æ–°å•Ÿç”¨" @@ -207,7 +207,7 @@ #define D_OSWATCH "osWatch" #define D_BLOCKED_LOOP "Blocked Loop" #define D_WPS_FAILED_WITH_STATUS "WPSconfig FAILED with status" -#define D_ACTIVE_FOR_3_MINUTES "active for 3 minutes" +#define D_ACTIVE_FOR_3_MINUTES "啟動三分é˜" #define D_FAILED_TO_START "無法啟動" #define D_PATCH_ISSUE_2186 "Patch issue 2186" #define D_CONNECTING_TO_AP "正在連線至存å–點" @@ -225,12 +225,12 @@ // settings.ino #define D_SAVED_TO_FLASH_AT "å„²å­˜è‡³å¿«é–ƒè¨˜æ†¶é«”ï¼Œä½æ–¼:" -#define D_LOADED_FROM_FLASH_AT "已從快閃記憶體中讀å–ï¼Œä½æ–¼:" +#define D_LOADED_FROM_FLASH_AT "已從快閃記憶體中讀å–,從:" #define D_USE_DEFAULTS "使用é è¨­å€¼" #define D_ERASED_SECTOR "抹除ç£å€" // xdrv_02_webserver.ino -#define D_NOSCRIPT "為了使用 Tasmota,請啟用 JavaScript" +#define D_NOSCRIPT "為了è¦ä½¿ç”¨ Tasmota,請啟用 JavaScript" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL韌體
    è«‹å‡ç´š" #define D_WEBSERVER_ACTIVE_ON "ç¶²é ä¼ºæœå™¨å·²ç¶“å•Ÿå‹•ï¼Œä½æ–¼:" #define D_WITH_IP_ADDRESS "IPä½å€:" @@ -252,12 +252,12 @@ #define D_CONFIRM_RESTART "確èªé‡æ–°å•Ÿå‹•" #define D_CONFIGURE_MODULE "模組設定" -#define D_CONFIGURE_WIFI "WiF設定i" +#define D_CONFIGURE_WIFI "WiFi設定" #define D_CONFIGURE_MQTT "MQTT設定" #define D_CONFIGURE_DOMOTICZ "Domoticz設定" #define D_CONFIGURE_LOGGING "日誌設定" #define D_CONFIGURE_OTHER "其他設定" -#define D_CONFIRM_RESET_CONFIGURATION "確定é‡è¨­è¨­å®š" +#define D_CONFIRM_RESET_CONFIGURATION "確定è¦é‡è¨­è¨­å®š" #define D_RESET_CONFIGURATION "é‡è¨­è¨­å®š" #define D_BACKUP_CONFIGURATION "備份設定" #define D_RESTORE_CONFIGURATION "回復設定" @@ -282,10 +282,10 @@ #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "AP1 SSID" -#define D_AP1_PASSWORD "AP1 密碼" -#define D_AP2_SSID "AP2 SSID" -#define D_AP2_PASSWORD "AP2 密碼" +#define D_AP1_SSID "å­˜å–點1 SSID" +#define D_AP1_PASSWORD "å­˜å–點1 密碼" +#define D_AP2_SSID "å­˜å–點2 SSID" +#define D_AP2_PASSWORD "å­˜å–點2 密碼" #define D_MQTT_PARAMETERS "MQTT設定" #define D_CLIENT "客戶端" @@ -315,9 +315,9 @@ #define D_CONFIGURE_TEMPLATE "模æ¿è¨­å®š" #define D_TEMPLATE_PARAMETERS "模æ¿åƒæ•¸" -#define D_TEMPLATE_NAME "Name" -#define D_BASE_TYPE "Based on" -#define D_TEMPLATE_FLAGS "Options" +#define D_TEMPLATE_NAME "å稱" +#define D_BASE_TYPE "基於" +#define D_TEMPLATE_FLAGS "é¸é …" #define D_SAVE_CONFIGURATION "儲存設定" #define D_CONFIGURATION_SAVED "設定已儲存" @@ -353,16 +353,16 @@ #define D_UPLOAD_ERR_2 "å¯ç”¨ç©ºé–“ä¸è¶³" #define D_UPLOAD_ERR_3 "魔術數字(Magic byte)䏿˜¯ 0xE9" #define D_UPLOAD_ERR_4 "軟體刷入(Program flash)的大å°è¶…出實際記憶體的大å°" -#define D_UPLOAD_ERR_5 "Upload buffer miscompare" +#define D_UPLOAD_ERR_5 "上傳緩è¡å™¨ä¸ç›¸ç¬¦" #define D_UPLOAD_ERR_6 "上傳失敗。 啟用日誌記錄 3" #define D_UPLOAD_ERR_7 "ä¸Šå‚³å–æ¶ˆ" #define D_UPLOAD_ERR_8 "檔案無效" #define D_UPLOAD_ERR_9 "檔案太大了" -#define D_UPLOAD_ERR_10 "Failed to init RF chip" -#define D_UPLOAD_ERR_11 "Failed to erase RF chip" -#define D_UPLOAD_ERR_12 "Failed to write to RF chip" -#define D_UPLOAD_ERR_13 "Failed to decode RF firmware" -#define D_UPLOAD_ERR_14 "Not compatible" +#define D_UPLOAD_ERR_10 "無法åˆå§‹åŒ– RF 晶片" +#define D_UPLOAD_ERR_11 "無法抹除 RF 晶片" +#define D_UPLOAD_ERR_12 "無法寫入 RF 晶片" +#define D_UPLOAD_ERR_13 "無法解碼 RF 韌體" +#define D_UPLOAD_ERR_14 "ä¸ç›¸å®¹" #define D_UPLOAD_ERROR_CODE "上傳錯誤代碼" #define D_ENTER_COMMAND "輸入命令" @@ -416,35 +416,35 @@ #define D_DOMOTICZ_UPDATE_TIMER "更新計時器" // xdrv_09_timers.ino -#define D_CONFIGURE_TIMER "Configure Timer" -#define D_TIMER_PARAMETERS "Timer parameters" -#define D_TIMER_ENABLE "Enable Timers" +#define D_CONFIGURE_TIMER "設定計時器" +#define D_TIMER_PARAMETERS "è¨ˆæ™‚å™¨åƒæ•¸" +#define D_TIMER_ENABLE "啟用" #define D_TIMER_ARM "Arm" -#define D_TIMER_TIME "Time" -#define D_TIMER_DAYS "Days" -#define D_TIMER_REPEAT "Repeat" -#define D_TIMER_OUTPUT "Output" -#define D_TIMER_ACTION "Action" +#define D_TIMER_TIME "時間" +#define D_TIMER_DAYS "日數" +#define D_TIMER_REPEAT "é‡è¤‡" +#define D_TIMER_OUTPUT "輸出" +#define D_TIMER_ACTION "採å–行動" // xdrv_10_knx.ino -#define D_CONFIGURE_KNX "Configure KNX" -#define D_KNX_PARAMETERS "KNX Parameters" -#define D_KNX_GENERAL_CONFIG "General" -#define D_KNX_PHYSICAL_ADDRESS "Physical Address" -#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Must be unique on the KNX network )" -#define D_KNX_ENABLE "Enable KNX" -#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data to Send to Group Addresses" -#define D_ADD "Add" -#define D_DELETE "Delete" -#define D_REPLY "Reply" -#define D_KNX_GROUP_ADDRESS_TO_READ "Group Addresses to Receive Data from" -#define D_RECEIVED_FROM "Received from" -#define D_KNX_COMMAND_WRITE "Write" -#define D_KNX_COMMAND_READ "Read" -#define D_KNX_COMMAND_OTHER "Other" -#define D_SENT_TO "sent to" -#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." -#define D_KNX_ENHANCEMENT "Communication Enhancement" +#define D_CONFIGURE_KNX "設定 KNX" +#define D_KNX_PARAMETERS "KNX åƒæ•¸" +#define D_KNX_GENERAL_CONFIG "一般" +#define D_KNX_PHYSICAL_ADDRESS "實體ä½å€" +#define D_KNX_PHYSICAL_ADDRESS_NOTE "( 在KNX網路中必須是ç¨ä¸€ç„¡äºŒçš„值 )" +#define D_KNX_ENABLE "啟用 KNX" +#define D_KNX_GROUP_ADDRESS_TO_WRITE "è¦å‚³å‘群組ä½å€çš„資料" +#define D_ADD "加入" +#define D_DELETE "移除"" +#define D_REPLY "回覆" +#define D_KNX_GROUP_ADDRESS_TO_READ "è¦æŽ¥æ”¶è³‡æ–™çš„ç¾¤çµ„ä½å€" +#define D_RECEIVED_FROM "接收自" +#define D_KNX_COMMAND_WRITE "寫入" +#define D_KNX_COMMAND_READ "讀å–" +#define D_KNX_COMMAND_OTHER "å…¶ä»–" +#define D_SENT_TO "傳é€è‡³" +#define D_KNX_WARNING "群組ä½å€ ( 0 / 0 / 0 ) 已經被ä¿ç•™äº†ï¼Œç„¡æ³•使用" +#define D_KNX_ENHANCEMENT "增強通訊" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" #define D_KNX_TX_SCENE "KNX SCENE TX" @@ -456,17 +456,17 @@ #define D_ENERGY_TOTAL "總用電é‡" // xdrv_27_shutter.ino -#define D_OPEN "Open" -#define D_CLOSE "Close" -#define D_DOMOTICZ_SHUTTER "Shutter" +#define D_OPEN "é–‹" +#define D_CLOSE "é—œ" +#define D_DOMOTICZ_SHUTTER "百葉窗" // xdrv_28_pcf8574.ino -#define D_CONFIGURE_PCF8574 "Configure PCF8574" -#define D_PCF8574_PARAMETERS "PCF8574 parameters" +#define D_CONFIGURE_PCF8574 "設定PCF8574" +#define D_PCF8574_PARAMETERS "PCF8574åƒæ•¸" #define D_INVERT_PORTS "Invert Ports" -#define D_DEVICE "Device" -#define D_DEVICE_INPUT "Input" -#define D_DEVICE_OUTPUT "Output" +#define D_DEVICE "è£ç½®" +#define D_DEVICE_INPUT "輸入" +#define D_DEVICE_OUTPUT "輸出" // xsns_05_ds18b20.ino #define D_SENSOR_BUSY "感應器忙碌中" @@ -490,43 +490,43 @@ #define D_PARTICALS_BEYOND "ç²’å­" // xsns_27_apds9960.ino -#define D_GESTURE "Gesture" -#define D_COLOR_RED "Red" -#define D_COLOR_GREEN "Green" -#define D_COLOR_BLUE "Blue" +#define D_GESTURE "手勢" +#define D_COLOR_RED "ç´…" +#define D_COLOR_GREEN "ç¶ " +#define D_COLOR_BLUE "è—" #define D_CCT "CCT" -#define D_PROXIMITY "Proximity" +#define D_PROXIMITY "è·é›¢" // xsns_32_mpu6050.ino -#define D_AX_AXIS "Accel. X-Axis" -#define D_AY_AXIS "Accel. Y-Axis" -#define D_AZ_AXIS "Accel. Z-Axis" -#define D_GX_AXIS "Gyro X-Axis" -#define D_GY_AXIS "Gyro Y-Axis" -#define D_GZ_AXIS "Gyro Z-Axis" +#define D_AX_AXIS "加速度. X-軸" +#define D_AY_AXIS "加速度. Y-軸" +#define D_AZ_AXIS "加速度. Z-軸" +#define D_GX_AXIS "陀螺儀 X-軸" +#define D_GY_AXIS "陀螺儀 Y-軸" +#define D_GZ_AXIS "陀螺儀 Z-軸" // xsns_34_hx711.ino -#define D_HX_CAL_REMOVE "Remove weigth" -#define D_HX_CAL_REFERENCE "Load reference weigth" -#define D_HX_CAL_DONE "Calibrated" -#define D_HX_CAL_FAIL "Calibration failed" -#define D_RESET_HX711 "Reset Scale" -#define D_CONFIGURE_HX711 "Configure Scale" -#define D_HX711_PARAMETERS "Scale parameters" -#define D_ITEM_WEIGHT "Item weight" -#define D_REFERENCE_WEIGHT "Reference weigth" -#define D_CALIBRATE "Calibrate" -#define D_CALIBRATION "Calibration" +#define D_HX_CAL_REMOVE "移除é‡é‡" +#define D_HX_CAL_REFERENCE "載入åƒè€ƒé‡é‡" +#define D_HX_CAL_DONE "å·²åŒæ­¥"" +#define D_HX_CAL_FAIL "åŒæ­¥å¤±æ•—" +#define D_RESET_HX711 "é‡è¨­æ¯”例" +#define D_CONFIGURE_HX711 "設定比例" +#define D_HX711_PARAMETERS "æ¯”ä¾‹åƒæ•¸" +#define D_ITEM_WEIGHT "物å“é‡é‡" +#define D_REFERENCE_WEIGHT "åƒè€ƒé‡é‡" +#define D_CALIBRATE "åŒæ­¥" +#define D_CALIBRATION "åŒæ­¥" //xsns_35_tx20.ino -#define D_TX20_WIND_DIRECTION "Wind Direction" -#define D_TX20_WIND_SPEED "Wind Speed" -#define D_TX20_WIND_SPEED_MIN "Wind Speed Min" -#define D_TX20_WIND_SPEED_MAX "Wind Speed Max" -#define D_TX20_NORTH "N" -#define D_TX20_EAST "E" -#define D_TX20_SOUTH "S" -#define D_TX20_WEST "W" +#define D_TX20_WIND_DIRECTION "風å‘" +#define D_TX20_WIND_SPEED "風速" +#define D_TX20_WIND_SPEED_MIN "最低風速" +#define D_TX20_WIND_SPEED_MAX "最高風速" +#define D_TX20_NORTH "北" +#define D_TX20_EAST "æ±" +#define D_TX20_SOUTH "å—" +#define D_TX20_WEST "西" // xsns_53_sml.ino #define D_TPWRIN "Energy Total-In" @@ -541,16 +541,16 @@ #define D_Spannung_L1 "Voltage L1" #define D_Spannung_L2 "Voltage L2" #define D_Spannung_L3 "Voltage L3" -#define D_METERNR "Meter_number" -#define D_METERSID "Service ID" -#define D_GasIN "Counter" -#define D_H2oIN "Counter" +#define D_METERNR "表號" +#define D_METERSID "æœå‹™ID" +#define D_GasIN "計數器" +#define D_H2oIN "計數器" #define D_StL1L2L3 "Current L1+L2+L3" #define D_SpL1L2L3 "Voltage L1+L2+L3/3" // tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box -#define D_SENSOR_NONE "None" -#define D_SENSOR_USER "User" +#define D_SENSOR_NONE "ç„¡" +#define D_SENSOR_USER "使用者" #define D_SENSOR_DHT11 "DHT11" #define D_SENSOR_AM2301 "AM2301" #define D_SENSOR_SI7021 "SI7021" @@ -737,15 +737,15 @@ #define D_UNIT_PRESSURE "百帕" #define D_UNIT_SECOND "ç§’" #define D_UNIT_SECTORS "ç£å€" -#define D_UNIT_VA "VA" -#define D_UNIT_VAR "VAr" +#define D_UNIT_VA "ä¼å®‰(VA)" +#define D_UNIT_VAR "ä¹çˆ¾(VAr)" #define D_UNIT_VOLT "ä¼ç‰¹" #define D_UNIT_WATT "瓦特" #define D_UNIT_WATTHOUR "ç“¦å°æ™‚" #define D_UNIT_WATT_METER_QUADRAT "W/m²" //SDM220〠SDM120〠LE01MR -#define D_PHASE_ANGLE "Phase Angle" +#define D_PHASE_ANGLE "相é‡(Phase Angle)" #define D_IMPORT_ACTIVE "Import Active" #define D_EXPORT_ACTIVE "Export Active" #define D_IMPORT_REACTIVE "Import Reactive" @@ -762,58 +762,58 @@ #define D_PV2_VOLTAGE "PV2 Voltage" #define D_PV2_CURRENT "PV2 Current" #define D_PV2_POWER "PV2 Power" -#define D_SOLAR_POWER "Solar Power" +#define D_SOLAR_POWER "太陽能" #define D_INVERTER_POWER "Inverter Power" -#define D_STATUS "Status" -#define D_WAITING "Waiting" -#define D_CHECKING "Checking" -#define D_WORKING "Working" -#define D_FAILURE "Failure" -#define D_SOLAX_ERROR_0 "No Error Code" -#define D_SOLAX_ERROR_1 "Grid Lost Fault" -#define D_SOLAX_ERROR_2 "Grid Voltage Fault" -#define D_SOLAX_ERROR_3 "Grid Frequency Fault" -#define D_SOLAX_ERROR_4 "Pv Voltage Fault" -#define D_SOLAX_ERROR_5 "Isolation Fault" -#define D_SOLAX_ERROR_6 "Over Temperature Fault" -#define D_SOLAX_ERROR_7 "Fan Fault" -#define D_SOLAX_ERROR_8 "Other Device Fault" +#define D_STATUS "狀態" +#define D_WAITING "等待中" +#define D_CHECKING "確èªä¸­"" +#define D_WORKING "é‹ä½œä¸­" +#define D_FAILURE "錯誤" +#define D_SOLAX_ERROR_0 "無錯誤碼" +#define D_SOLAX_ERROR_1 "電網失è¯(Grid Lost)錯誤" +#define D_SOLAX_ERROR_2 "電網(Grid)電壓錯誤" +#define D_SOLAX_ERROR_3 "電網(Grid)頻率錯誤" +#define D_SOLAX_ERROR_4 "å…‰ä¼é›»å£“(Pv Voltage)錯誤" +#define D_SOLAX_ERROR_5 "隔離錯誤" +#define D_SOLAX_ERROR_6 "éŽç†±éŒ¯èª¤" +#define D_SOLAX_ERROR_7 "風扇錯誤" +#define D_SOLAX_ERROR_8 "å…¶ä»–è£ç½®éŒ¯èª¤" //xdrv_10_scripter.ino -#define D_CONFIGURE_SCRIPT "Edit script" -#define D_SCRIPT "edit script" -#define D_SDCARD_UPLOAD "file upload" -#define D_SDCARD_DIR "sd card directory" -#define D_UPL_DONE "Done" -#define D_SCRIPT_CHARS_LEFT "chars left" -#define D_SCRIPT_CHARS_NO_MORE "no more chars" -#define D_SCRIPT_DOWNLOAD "Download" -#define D_SCRIPT_ENABLE "script enable" -#define D_SCRIPT_UPLOAD "Upload" -#define D_SCRIPT_UPLOAD_FILES "Upload files" +#define D_CONFIGURE_SCRIPT "編輯腳本" +#define D_SCRIPT "編輯腳本" +#define D_SDCARD_UPLOAD "上傳檔案" +#define D_SDCARD_DIR "記憶å¡ç›®éŒ„" +#define D_UPL_DONE "完æˆ" +#define D_SCRIPT_CHARS_LEFT "剩餘字元"" +#define D_SCRIPT_CHARS_NO_MORE "放ä¸ä¸‹æ›´å¤šå­—元了" +#define D_SCRIPT_DOWNLOAD "下載" +#define D_SCRIPT_ENABLE "啟用腳本" +#define D_SCRIPT_UPLOAD "上傳" +#define D_SCRIPT_UPLOAD_FILES "上傳檔案" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" -#define D_AS3935_ENERGY "energy:" -#define D_AS3935_DISTANCE "distance:" -#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_ENERGY "能é‡:" +#define D_AS3935_DISTANCE "è·é›¢:" +#define D_AS3935_DISTURBER "干擾物:" #define D_AS3935_VRMS "µVrms:" -#define D_AS3935_APRX "aprx.:" -#define D_AS3935_AWAY "away" -#define D_AS3935_LIGHT "lightning" -#define D_AS3935_OUT "lightning out of range" -#define D_AS3935_NOT "distance not determined" -#define D_AS3935_ABOVE "lightning overhead" -#define D_AS3935_NOISE "noise detected" -#define D_AS3935_DISTDET "disturber detected" -#define D_AS3935_INTNOEV "Interrupt with no Event!" -#define D_AS3935_NOMESS "listening..." -#define D_AS3935_ON "On" -#define D_AS3935_OFF "Off" -#define D_AS3935_INDOORS "Indoors" -#define D_AS3935_OUTDOORS "Outdoors" -#define D_AS3935_CAL_FAIL "calibration failed" -#define D_AS3935_CAL_OK "calibration set to:" +#define D_AS3935_APRX "大約:" +#define D_AS3935_AWAY "é é›¢" +#define D_AS3935_LIGHT "閃電" +#define D_AS3935_OUT "閃電在範åœå¤–" +#define D_AS3935_NOT "è·é›¢ä¸ç¢ºå®š" +#define D_AS3935_ABOVE "閃電在頭上" +#define D_AS3935_NOISE "嵿¸¬åˆ°é›œè¨Š" +#define D_AS3935_DISTDET "嵿¸¬åˆ°å¹²æ“¾ç‰©" +#define D_AS3935_INTNOEV "沒有任何事件觸發中斷!" +#define D_AS3935_NOMESS "è½å–中..." +#define D_AS3935_ON "開啟" +#define D_AS3935_OFF "關閉" +#define D_AS3935_INDOORS "室內" +#define D_AS3935_OUTDOORS "戶外" +#define D_AS3935_CAL_FAIL "åŒæ­¥å¤±æ•—" +#define D_AS3935_CAL_OK "å·²åŒæ­¥ç‚º:" //xsns_68_opentherm.ino #define D_SENSOR_BOILER_OT_RX "OpenTherm RX" From 9bbba049250bb92b8f9f535568e0feb456d1677a Mon Sep 17 00:00:00 2001 From: SODAIS <6829907+SODAIS69@users.noreply.github.com> Date: Wed, 15 Jul 2020 00:05:13 +0800 Subject: [PATCH 472/581] Update zh_TW.h Removing string accidentally added --- tasmota/language/zh_TW.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 04d39dd91..64df93eda 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -32,7 +32,7 @@ \*********************************************************************/ //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) -// https://www.science.co.il/language/Locale-codes.php + #define LANGUAGE_LCID 1028 // HTML (ISO 639-1) Language Code #define D_HTML_LANGUAGE "zh" @@ -819,4 +819,4 @@ #define D_SENSOR_BOILER_OT_RX "OpenTherm RX" #define D_SENSOR_BOILER_OT_TX "OpenTherm TX" -#endif // _LANGUAGE_ZH_TW_H_ \ No newline at end of file +#endif // _LANGUAGE_ZH_TW_H_ From c8d0f397f7f0d43a7299b14ae41f6faa46bf14fa Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 18:09:39 +0200 Subject: [PATCH 473/581] Fix GCC 10.1 errors --- lib/UdpListener/src/UdpListener.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/UdpListener/src/UdpListener.h b/lib/UdpListener/src/UdpListener.h index a369a5d81..b4f5af93b 100644 --- a/lib/UdpListener/src/UdpListener.h +++ b/lib/UdpListener/src/UdpListener.h @@ -48,7 +48,7 @@ * only the first bytes (200 by default) of each packet. * The number of packets treated is limited (3 by default), any * new packet arriving is dropped. - * + * * This class does only receiving multicast packets for LWIP2 */ @@ -175,7 +175,7 @@ private: if (buf != dst) memcpy(dst, buf, packet_len); _buffers[next_slot].len = packet_len; - + _buffers[next_slot].srcaddr = srcaddr; _buffers[next_slot].dstaddr = ip_current_dest_addr(); _buffers[next_slot].srcport = srcport; @@ -187,7 +187,7 @@ private: static void _s_recv(void *arg, udp_pcb *upcb, pbuf *p, - CONST ip_addr_t *srcaddr, u16_t srcport) + const ip_addr_t *srcaddr, u16_t srcport) { reinterpret_cast(arg)->_recv(upcb, p, srcaddr, srcport); } From d86fb6f58497e62d3bbeb57535d03778e1e23bf8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 18:19:13 +0200 Subject: [PATCH 474/581] Fix GCC 10.1 warnings --- tasmota/xdrv_30_exs_dimmer.ino | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_30_exs_dimmer.ino b/tasmota/xdrv_30_exs_dimmer.ino index 485112977..a6b14ca9a 100644 --- a/tasmota/xdrv_30_exs_dimmer.ino +++ b/tasmota/xdrv_30_exs_dimmer.ino @@ -205,19 +205,19 @@ void ExsSendCmd(uint8_t cmd, uint8_t value) ExsSerialSend(buffer, len); } -uint8_t ExsSetPower(uint8_t device, uint8_t power) +void ExsSetPower(uint8_t device, uint8_t power) { Exs.dimmer.channel[device].dimm = power; ExsSendCmd(EXS_DIMM_1_ON + 0x10 * device + power ^ 1, 0); } -uint8_t ExsSetBri(uint8_t device, uint8_t bri) +void ExsSetBri(uint8_t device, uint8_t bri) { Exs.dimmer.channel[device].bright_tbl = bri; ExsSendCmd(EXS_DIMM_1_TBL + 0x10 * device, bri); } -uint8_t ExsSyncState(uint8_t device) +void ExsSyncState(uint8_t device) { #ifdef EXS_DEBUG AddLog_P2(LOG_LEVEL_DEBUG, PSTR("EXS: Channel %d Power Want %d, Is %d"), @@ -249,6 +249,7 @@ bool ExsSyncState() ExsSyncState(0); ExsSyncState(1); + return true; } void ExsDebugState() From 35e570ca9703017e4e1aae7b72064ce34f22833e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 18:30:23 +0200 Subject: [PATCH 475/581] Fix GCC 10.1 error --- tasmota/xsns_42_scd30.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_42_scd30.ino b/tasmota/xsns_42_scd30.ino index 4a10fa8f0..3aeb00218 100644 --- a/tasmota/xsns_42_scd30.ino +++ b/tasmota/xsns_42_scd30.ino @@ -101,7 +101,7 @@ void Scd30Update(void) { scd30Loop_count++; if (scd30Loop_count > (scd30Interval_sec - 1)) { - int error = 0; + uint32_t error = 0; switch (scd30ErrorState) { case SCD30_STATE_NO_ERROR: { error = scd30.readMeasurement(&scd30_CO2, &scd30_CO2EAvg, &scd30_Temp, &scd30_Humid); From 2fe532682182218a335f842671b057c4ab219fcc Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 18:34:59 +0200 Subject: [PATCH 476/581] Fix buffer overflow --- tasmota/xsns_62_MI_HM10.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_62_MI_HM10.ino b/tasmota/xsns_62_MI_HM10.ino index 6b5a797eb..8424ab6cd 100644 --- a/tasmota/xsns_62_MI_HM10.ino +++ b/tasmota/xsns_62_MI_HM10.ino @@ -427,7 +427,7 @@ void HM10parseMiBeacon(char * _buf, uint32_t _slot){ float _tempFloat; mi_beacon_t _beacon; if (MIBLEsensors[_slot].type==MJ_HT_V1 || MIBLEsensors[_slot].type==CGG1){ - memcpy((uint8_t*)&_beacon+1,(uint8_t*)_buf, sizeof(_beacon)); // shift by one byte for the MJ_HT_V1 + memcpy((uint8_t*)&_beacon+1,(uint8_t*)_buf, sizeof(_beacon)-1); // shift by one byte for the MJ_HT_V1 memcpy((uint8_t*)&_beacon.Mac,(uint8_t*)&_beacon.Mac+1,6); // but shift back the MAC } else{ From 58a4a12b22f2c52230f3c302745f36c9534a9da1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 14 Jul 2020 18:35:29 +0200 Subject: [PATCH 477/581] Fix GCC 10.1 warning --- tasmota/xsns_59_ds1624.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_59_ds1624.ino b/tasmota/xsns_59_ds1624.ino index 60b176c6e..96adc4938 100644 --- a/tasmota/xsns_59_ds1624.ino +++ b/tasmota/xsns_59_ds1624.ino @@ -63,7 +63,7 @@ uint32_t DS1624_Idx2Addr(uint32_t idx) { return 0x48 + idx; } -int DS1624_Restart(uint8_t config, uint32_t idx) { +void DS1624_Restart(uint8_t config, uint32_t idx) { uint32_t addr = DS1624_Idx2Addr(idx); if ((config & 1) == 1) { config &= ~(DS1621_CFG_DONE|DS1621_CFG_1SHOT); From 7cd8696946b8eee62869caa0c59bee0cc8302957 Mon Sep 17 00:00:00 2001 From: SODAIS69 <6829907+SODAIS69@users.noreply.github.com> Date: Wed, 15 Jul 2020 01:06:45 +0800 Subject: [PATCH 478/581] Remove redundant quotes that causes cl fails. --- tasmota/language/zh_TW.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 04d39dd91..350533744 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -119,7 +119,7 @@ #define D_LWT "LWT" #define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "模組" -#define D_MOISTURE "濕度"" +#define D_MOISTURE "濕度" #define D_MQTT "MQTT" #define D_MULTI_PRESS "多é‡é»žæ“Š" #define D_NOISE "雜訊" @@ -435,7 +435,7 @@ #define D_KNX_ENABLE "啟用 KNX" #define D_KNX_GROUP_ADDRESS_TO_WRITE "è¦å‚³å‘群組ä½å€çš„資料" #define D_ADD "加入" -#define D_DELETE "移除"" +#define D_DELETE "移除" #define D_REPLY "回覆" #define D_KNX_GROUP_ADDRESS_TO_READ "è¦æŽ¥æ”¶è³‡æ–™çš„ç¾¤çµ„ä½å€" #define D_RECEIVED_FROM "接收自" @@ -508,7 +508,7 @@ // xsns_34_hx711.ino #define D_HX_CAL_REMOVE "移除é‡é‡" #define D_HX_CAL_REFERENCE "載入åƒè€ƒé‡é‡" -#define D_HX_CAL_DONE "å·²åŒæ­¥"" +#define D_HX_CAL_DONE "å·²åŒæ­¥" #define D_HX_CAL_FAIL "åŒæ­¥å¤±æ•—" #define D_RESET_HX711 "é‡è¨­æ¯”例" #define D_CONFIGURE_HX711 "設定比例" @@ -766,7 +766,7 @@ #define D_INVERTER_POWER "Inverter Power" #define D_STATUS "狀態" #define D_WAITING "等待中" -#define D_CHECKING "確èªä¸­"" +#define D_CHECKING "確èªä¸­" #define D_WORKING "é‹ä½œä¸­" #define D_FAILURE "錯誤" #define D_SOLAX_ERROR_0 "無錯誤碼" @@ -785,7 +785,7 @@ #define D_SDCARD_UPLOAD "上傳檔案" #define D_SDCARD_DIR "記憶å¡ç›®éŒ„" #define D_UPL_DONE "完æˆ" -#define D_SCRIPT_CHARS_LEFT "剩餘字元"" +#define D_SCRIPT_CHARS_LEFT "剩餘字元" #define D_SCRIPT_CHARS_NO_MORE "放ä¸ä¸‹æ›´å¤šå­—元了" #define D_SCRIPT_DOWNLOAD "下載" #define D_SCRIPT_ENABLE "啟用腳本" From f6314bcf6ec127508d7d45c7b59f7a08793ba580 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 14 Jul 2020 21:45:52 +0200 Subject: [PATCH 479/581] Add in env. debug stack usage >=300 bytes maybe usefull --- platformio_override_sample.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 7afadf502..c55bafa94 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -163,6 +163,7 @@ build_flags = ${esp82xx_defaults.build_flags} build_type = debug build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} + -Wstack-usage=300 ; *** Experimental ESP32 Tasmota version *** From e43d1828f6ec8b12bda29b98415771ccd3c6acac Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Wed, 15 Jul 2020 09:44:52 +0200 Subject: [PATCH 480/581] some gcc fixes, etc --- .../src/renderer.cpp | 2 + tasmota/xdrv_10_scripter.ino | 30 +++++++++- tasmota/xsns_53_sml.ino | 56 +++++++++++++++++-- 3 files changed, 83 insertions(+), 5 deletions(-) diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp index 01b8dc7c3..10806220f 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/renderer.cpp @@ -36,6 +36,8 @@ uint8_t wr_redir=0; uint8_t *buffer; +#define register + #define SPRINT(A) char str[32];sprintf(str,"val: %d ",A);Serial.println((char*)str); #define OLED_FONT_WIDTH 6 diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index ddb818a91..06e482a4d 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -1237,6 +1237,7 @@ uint32_t match_vars(char *dvnam, float **fp, char **sp, uint32_t *ind) { } #endif + // vtype => ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number // no flash strings here for performance reasons!!! char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,JsonObject *jo) { @@ -1486,6 +1487,14 @@ chknext: goto exit; } #endif + if (!strncmp(vname,"asc(",4)) { + char str[SCRIPT_MAXSSIZE]; + lp=GetStringResult(lp+4,OPER_EQU,str,0); + fvar=str[0]; + lp++; + len=0; + goto exit; + } break; case 'b': @@ -1975,6 +1984,14 @@ chknext: } goto strexit; } + if (!strncmp(vname,"hd(",3)) { + char str[SCRIPT_MAXSSIZE]; + lp=GetStringResult(lp+3,OPER_EQU,str,0); + fvar=strtol(str,NULL,16); + lp++; + len=0; + goto exit; + } #ifdef USE_LIGHT //#ifdef USE_WS2812 if (!strncmp(vname,"hsvrgb(",7)) { @@ -2505,6 +2522,15 @@ chknext: char str[SCRIPT_MAXSSIZE]; lp=GetStringResult(lp,OPER_EQU,str,0); fvar=SML_Write(fvar1,str); + } else if (fvar2==2) { + char str[SCRIPT_MAXSSIZE]; + str[0]=0; + fvar=SML_Read(fvar1,str,SCRIPT_MAXSSIZE); + if (sp) strlcpy(sp,str,glob_script_mem.max_ssize); + lp++; + len=0; + goto strexit; + } else { #ifdef ED300L fvar=SML_Status(fvar1); @@ -2914,7 +2940,7 @@ char *GetStringResult(char *lp,uint8_t lastop,char *cp,JsonObject *jo) { strlcpy(str,str1,sizeof(str)); break; case OPER_PLS: - strncat(str,str1,sizeof(str)); + strncat(str,str1,sizeof(str)-strlen(str1)); break; } slp=lp; @@ -2939,6 +2965,7 @@ char *GetStringResult(char *lp,uint8_t lastop,char *cp,JsonObject *jo) { return lp; } } + return lp; } char *GetNumericResult(char *lp,uint8_t lastop,float *fp,JsonObject *jo) { @@ -6408,6 +6435,7 @@ void ScriptJsonAppend(void) { bool RulesProcessEvent(char *json_event) { if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">E",2,json_event); + return true; } #ifdef ESP32 diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index 65d788d8c..a75a8fbd8 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -467,7 +467,9 @@ TasmotaSerial *meter_ss[MAX_METERS]; #endif // serial buffers, may be made larger depending on telegram lenght +#ifndef SML_BSIZ #define SML_BSIZ 48 +#endif uint8_t smltbuf[MAX_METERS][SML_BSIZ]; // meter nr as string @@ -1186,7 +1188,7 @@ void sml_empty_receiver(uint32_t meters) { void sml_shift_in(uint32_t meters,uint32_t shard) { uint32_t count; - if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p') { + if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R') { // shift in for (count=0; count=SML_BSIZ) { + meter_spos[meters]=0; + } + } + else { if (iob==EBUS_SYNC) { // should be end of telegramm // QQ,ZZ,PB,SB,NN ..... CRC, ACK SYNC @@ -1243,7 +1252,7 @@ void sml_shift_in(uint32_t meters,uint32_t shard) { } } sb_counter++; - if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p') SML_Decode(meters); + if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R') SML_Decode(meters); } @@ -1271,6 +1280,7 @@ void SML_Decode(uint8_t index) { delay(0); while (mp != NULL) { // check list of defines + if (*mp==0) break; // new section mindex=((*mp)&7)-1; @@ -1648,6 +1658,7 @@ void SML_Show(boolean json) { int8_t lastmind=((*mp)&7)-1; if (lastmind<0 || lastmind>=meters_used) lastmind=0; while (mp != NULL) { + if (*mp==0) break; // setup sections mindex=((*mp)&7)-1; if (mindex<0 || mindex>=meters_used) mindex=0; @@ -2151,7 +2162,7 @@ init10: } else { // serial input, init #ifdef SPECIAL_SS - if (meter_desc_p[meters].type=='m' || meter_desc_p[meters].type=='M' || meter_desc_p[meters].type=='p') { + if (meter_desc_p[meters].type=='m' || meter_desc_p[meters].type=='M' || meter_desc_p[meters].type=='p' || meter_desc_p[meters].type=='R') { meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,0,TMSBSIZ); } else { meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,1,TMSBSIZ); @@ -2201,6 +2212,12 @@ uint32_t SML_SetBaud(uint32_t meter, uint32_t br) { #ifdef ESP32 meter_ss[meter]->flush(); meter_ss[meter]->updateBaudRate(br); + /* + if (meter_desc_p[meter].type=='M') { + meter_ss[meter]->begin(br,SERIAL_8E1,meter_desc_p[meter].srcpin,meter_desc_p[meter].trxpin); + } else { + meter_ss[meter]->begin(br,SERIAL_8N1,meter_desc_p[meter].srcpin,meter_desc_p[meter].trxpin); + }*/ #else if (meter_ss[meter]->begin(br)) { meter_ss[meter]->flush(); @@ -2233,6 +2250,37 @@ uint32_t SML_Write(uint32_t meter,char *hstr) { return 1; } +uint32_t SML_Read(int32_t meter,char *str, uint32_t slen) { +uint8_t hflg=0; + if (meter<0) { + meter=abs(meter); + hflg=1; + } + if (meter<1 || meter>meters_used) return 0; + meter--; + if (!meter_ss[meter]) return 0; + + if (!meter_spos[meter]) { + return 0; + } + + smltbuf[meter][meter_spos[meter]]=0; + + if (!hflg) { + strlcpy(str,(char*)&smltbuf[meter][0],slen); + } else { + uint32_t index=0; + for (uint32_t cnt=0; cnt=slen-2) break; + } + } + meter_spos[meter]=0; + return 1; +} + float SML_GetVal(uint32_t index) { if (index<1 && index>SML_MAX_VARS) { index = 1;} return meter_vars[index-1]; From 214b2279427dbd1fea6acac6a04e5b9deefe7b46 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Jul 2020 10:50:54 +0200 Subject: [PATCH 481/581] Better fix GCC 10.1 warnings --- tasmota/support_network.ino | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/tasmota/support_network.ino b/tasmota/support_network.ino index 7bf7df30c..da6512acb 100644 --- a/tasmota/support_network.ino +++ b/tasmota/support_network.ino @@ -89,44 +89,34 @@ void MdnsUpdate(void) { \*********************************************************************************************/ char* NetworkHostname(void) { - if (global_state.eth_down) { - return my_hostname; - } #ifdef ESP32 #ifdef USE_ETHERNET - else { + if (!global_state.eth_down) { return EthernetHostname(); } #endif #endif - return nullptr; // Never reached. Fix GCC10 warning + return my_hostname; } IPAddress NetworkAddress(void) { - IPAddress result; - if (global_state.eth_down) { - result = WiFi.localIP(); - } #ifdef ESP32 #ifdef USE_ETHERNET - else { - result = EthernetLocalIP(); + if (!global_state.eth_down) { + return EthernetLocalIP(); } #endif #endif - return result; + return WiFi.localIP(); } String NetworkMacAddress(void) { - if (global_state.eth_down) { - return WiFi.macAddress(); - } #ifdef ESP32 #ifdef USE_ETHERNET - else { + if (!global_state.eth_down) { return EthernetMacAddress(); } #endif #endif - return String(""); // Never reached. Fix GCC10 warning + return WiFi.macAddress(); } From 8c58d8cd3b89ad51c8819c94300cdc305817d396 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 15 Jul 2020 11:00:02 +0200 Subject: [PATCH 482/581] suppress Gcc10.1 warning... in lib IRremoteESP8266-2.7.8 --- platformio_override_sample.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index c55bafa94..1c11f63d0 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -126,6 +126,7 @@ build_flags = ${esp82xx_defaults.build_flags} platform = https://github.com/Jason2866/platform-espressif8266/releases/download/2.9.0/platform-espressif8266-2.9.0.tar.gz platform_packages = ;framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git build_unflags = ${esp_defaults.build_unflags} + -Wswitch-unreachable build_flags = ${esp82xx_defaults.build_flags} ; *********** Alternative Options, enable only if you know exactly what you do ******** From 608d05f0bb5c54a94485a3e14574ca9d6ef79dba Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Jul 2020 11:04:29 +0200 Subject: [PATCH 483/581] Fix GCC 10.1 warnings --- tasmota/xsns_42_scd30.ino | 2 ++ tasmota/xsns_67_as3935.ino | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tasmota/xsns_42_scd30.ino b/tasmota/xsns_42_scd30.ino index 3aeb00218..4c73d3b15 100644 --- a/tasmota/xsns_42_scd30.ino +++ b/tasmota/xsns_42_scd30.ino @@ -249,6 +249,7 @@ int Scd30GetCommand(int command_code, uint16_t *pvalue) // else for Unknown command break; } + return 0; // Fix GCC 10.1 warning } int Scd30SetCommand(int command_code, uint16_t value) @@ -291,6 +292,7 @@ int Scd30SetCommand(int command_code, uint16_t value) // else for Unknown command break; } + return 0; // Fix GCC 10.1 warning } /*********************************************************************************************\ diff --git a/tasmota/xsns_67_as3935.ino b/tasmota/xsns_67_as3935.ino index 3e795b91a..3723079b4 100644 --- a/tasmota/xsns_67_as3935.ino +++ b/tasmota/xsns_67_as3935.ino @@ -218,6 +218,7 @@ uint8_t AS3935TranslMinLightsInt(uint8_t min_lights) { case 2: return 9; case 3: return 16; } + return 0; // Fix GCC 10.1 warning } uint8_t AS3935TranslIrq(uint8_t irq, uint8_t distance) { @@ -231,6 +232,7 @@ uint8_t AS3935TranslIrq(uint8_t irq, uint8_t distance) { else if (distance == 1) return 4; // Storm is Overhead else return 1; // Lightning with Distance detected } + return 0; // Fix GCC 10.1 warning } void AS3935CalcVrmsLevel(uint16_t &vrms, uint8_t &stage) @@ -346,7 +348,7 @@ uint8_t AS3935GetDisturber() { return AS3935ReadRegister(DISTURBER); } -uint8_t AS3935SetDisturber(uint8_t stat) { +void AS3935SetDisturber(uint8_t stat) { AS3935WriteRegister(DISTURBER, stat); } @@ -354,7 +356,7 @@ uint8_t AS3935GetMinLights() { return AS3935ReadRegister(MIN_NUM_LIGH); } -uint8_t AS3935SetMinLights(uint8_t stat) { +void AS3935SetMinLights(uint8_t stat) { AS3935WriteRegister(MIN_NUM_LIGH, stat); } @@ -362,7 +364,7 @@ uint8_t AS3935GetNoiseFloor() { return AS3935ReadRegister(NF_LEVEL); } -uint8_t AS3935SetNoiseFloor(uint8_t noise) { +void AS3935SetNoiseFloor(uint8_t noise) { AS3935WriteRegister(NF_LEVEL , noise); } @@ -372,7 +374,7 @@ uint8_t AS3935GetGain() { return INDOORS; } -uint8_t AS3935SetGain(uint8_t room) { +void AS3935SetGain(uint8_t room) { AS3935WriteRegister(AFE_GB, room); } From b68260a164c5b7fcb70478efb1e685cca6451391 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 15 Jul 2020 11:10:10 +0200 Subject: [PATCH 484/581] missing "-Wno-switch-unreachable" --- platformio_override_sample.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 1c11f63d0..3ec6c3a57 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -128,6 +128,7 @@ platform_packages = ;framework-arduinoespressif8266 @ https://github.com build_unflags = ${esp_defaults.build_unflags} -Wswitch-unreachable build_flags = ${esp82xx_defaults.build_flags} + -Wno-switch-unreachable ; *********** Alternative Options, enable only if you know exactly what you do ******** ; NONOSDK221 From fec0fa47cac5c79b291dd931132ef0c9ca04f50c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Jul 2020 12:07:19 +0200 Subject: [PATCH 485/581] Update RELEASENOTES.md --- RELEASENOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7e0208ef1..12b3a5b24 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -54,7 +54,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ### Version 8.3.1.6 -- Change IRremoteESP8266 library updated to v2.7.7 +- Change IRremoteESP8266 library from v2.7.6 to v2.7.8 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` From 23057c94ac90e0e1efcce214a35ad0f9e1843760 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Jul 2020 12:26:58 +0200 Subject: [PATCH 486/581] Update TEMPLATES.md --- TEMPLATES.md | 360 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 272 insertions(+), 88 deletions(-) diff --git a/TEMPLATES.md b/TEMPLATES.md index 84937c5bd..d39a55b92 100644 --- a/TEMPLATES.md +++ b/TEMPLATES.md @@ -2,7 +2,7 @@ # Templates -Find below the available templates as of May 2020. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) +Find below the available templates as of July 2020. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) ## Aromatherapy Diffuser ``` @@ -17,6 +17,11 @@ Mirabella Genio Glass Aroma Diffuser 250ml {"NAME":"Genio Diffuser","GPIO":[0,0 Wood Grain 550ML {"NAME":"MY-KCL01800FB","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} ``` +## Bluetooth Bridge +``` +Arlec Smart Home Hub {"NAME":"Arlec Hub","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +``` + ## Bulb Socket ``` Elegant Choice E27/E26 {"NAME":"name","GPIO":[0,0,0,0,0,0,0,0,0,0,0,21,0],"FLAG":0,"BASE":18} @@ -33,26 +38,33 @@ Anoopsyche 9W 800lm {"NAME":"Anoop-CW-WW","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0 Arlec Smart 1350lm PAR38 {"NAME":"Arlec GLD302HA","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Arlec Smart 9.5W 806lm {"NAME":"Arlec GLD110HA","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} Arlec Smart 9.5W 806lm {"NAME":"Arlec CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} -BrilliantSmart 20696 9W 900lm {"NAME":"Brilliant20696","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":48} -BrilliantSmart 20697 9W 900lm {"NAME":"Brilliant20699","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":48} +BrilliantSmart 20696 9W 900lm {"NAME":"Brilliant20696","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +BrilliantSmart 20697 9W 900lm {"NAME":"Brilliant20696","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Bulbrite Solana A19 Edison Filament {"NAME":"BulbBrite01","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":18} +Bulbrite Solana G25 5.5W 600lm Filament {"NAME":"BulbBrite01","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Calex G125 7,5W 1055lm {"NAME":"Calex G125 E27","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} Calex G125 7.5W 1055lm Globe {"NAME":"Calex G125 E27","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Deltaco SH-LE14W 470lm {"NAME":"SH-LE14W","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} -Deltaco SH-LE27W 810lm {"NAME":"SH-LE27W","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} +Connect Smart GU5.3 5W {"NAME":"Connect CSH-GU53WW5W","GPIO":[0,0,0,0,37,38,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Deltaco SH-LE14W 470lm {"NAME":"SH-LE14W","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Deltaco SH-LE27W 810lm {"NAME":"SH-LE27W","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} DORESshop A60 720lm Filament {"NAME":"DORESshop-A60","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Energizer A19 10W {"NAME":"Energizer CCT ","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Energizer A19 10W Smart White {"NAME":"Energizer CCT ","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} Euri Lighting A19 10W 800lm {"NAME":"Euri Lighting ","GPIO":[0,0,0,0,37,38,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Geeni LUX 1050lm {"NAME":"Geeni-1050-WW","GPIO":[0,0,0,0,37,37,0,0,38,0,0,0,0],"FLAG":1,"BASE":18} -Globe 34208 A19 800lm {"NAME":"GlobeCCT","GPIO":[0,0,0,0,38,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Globe 34919 ST19 Edison 500lm {"NAME":"Globe 34919","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Globe A19 10W 800lm {"NAME":"GlobeCCT","GPIO":[0,0,0,0,38,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Globe G25 Edison 500lm {"NAME":"Globe 34920","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Globe ST19 Edison 500lm {"NAME":"Globe 34919","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Hama 806lm {"NAME":"Hama 00176550","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} Hykker SL-0392 650lm {"NAME":"Hykker 7W","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} Iotton 9W 700lm {"NAME":"Iotton Light","GPIO":[0,0,0,0,37,38,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Kogan 10W Cool & Warm White 1050lm {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Kogan 10W Cool & Warm White 1050lm {"NAME":"Kogan 10W CCT","GPIO":[0,0,0,0,0,37,0,0,0,47,0,0,0],"FLAG":0,"BASE":48} +Kogan 4.5W 330lm CCT {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Kogan 5W {"NAME":"Kogan Co/Wa","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} LE lampUX 380lm Candle {"NAME":"LE Bulb","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} LE LampUX 4.5W 410lm {"NAME":"LE LampUX","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":48} ledscom.de 4.5W 430lm {"NAME":"GX53","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":0} +Lenovo 800lm {"NAME":"LenovoLB","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Lohas ZN051 5W 420lm {"NAME":"Lohas ZN051","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Lohas ZN070 720lm {"NAME":"Lohas ZN070","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Lumiman A19 7.5W 800lm {"NAME":"Lumiman LM520","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} Luminea ZX-2831 {"NAME":"Luminea CCT","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} @@ -65,33 +77,33 @@ Mirabella Genio 9W 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0 Mirabella Genio I002745 SES 470lm {"NAME":"Mirabella Candle","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Mirabella Genio I002746 500lm {"NAME":"GenioGU10","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Mirabella Genio I002747 G95 470lm {"NAME":"Genio Filament","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Nedis A60 5.5W 350lm Twisted Filament {"NAME":"WIFILT10GDA60","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Nedis A60 800lm {"NAME":"WIFILW10WTE27","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} Nedis C10 350lm {"NAME":"WIFILW10WTE14","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Nedis G125 5.5W 350lm Twisted Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Nedis PAR16 330lm {"NAME":"Nedis WIFILW30","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Nedis PAR16 4.5W 330lm 110° {"NAME":"WIFILW30","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Nedis PAR16 4.5W 330lm {"NAME":"WIFILW30","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} Philips Zhirui Candle 250lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,38,0,0,37,0],"FLAG":0,"BASE":48} Phillips Zhirui 450lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,38,0,0,37,0],"FLAG":0,"BASE":48} SmartDGM L-WT9W1 9W 800lm {"NAME":"L-WT9W1","GPIO":[0,0,0,0,0,37,0,0,9,38,0,0,0],"FLAG":0,"BASE":18} Swisstone SH 330 806lm {"NAME":"SwisstoneSH330","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} Vestaiot BR30 800lm {"NAME":"Vesta BR30 CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} -Wipro Garnet NS9100 810lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,38,38,0,0,37,37,0,0,0],"FLAG":0,"BASE":18} +Wipro Garnet NS9100 810lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,38,0,0,0,37,0,0,0,0],"FLAG":0,"BASE":18} Wyze WLPA19 A19 800lm {"NAME":"Wyze Bulb","GPIO":[0,0,0,0,0,0,0,0,0,37,38,0,0],"FLAG":0,"BASE":48} ``` -## Curtain Motor -``` -Zemismart BCM300D-TY {"NAME":"Zemistart_Curt","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} -``` - ## Curtain Switch ``` Anccy Relax {"NAME":"Tuya Shutter","GPIO":[157,0,54,10,22,19,0,0,17,21,53,23,52],"FLAG":0,"BASE":18} +Avatto SYS-CS01 {"NAME":"Avatto","GPIO":[56,158,0,18,22,0,0,0,0,21,57,0,17],"FLAG":0,"BASE":18} Etersky WF-CS01 {"NAME":"Etersky","GPIO":[157,0,53,19,23,18,0,0,17,21,54,22,52],"FLAG":0,"BASE":18} -Homecube Blinds and Curtains {"NAME":"Jinvoo Curtain","GPIO":[52,0,0,18,22,19,0,0,17,21,0,23,0],"FLAG":1,"BASE":18} +Homecube {"NAME":"Jinvoo Curtain","GPIO":[52,0,0,18,22,19,0,0,17,21,0,23,0],"FLAG":1,"BASE":18} Jinvoo SM-SW101-C {"NAME":"Jinvoo Curtain","GPIO":[52,0,0,18,22,19,0,0,17,21,0,23,0],"FLAG":1,"BASE":18} LoraTap SC400W-EU {"NAME":"Loratap SC400W","GPIO":[0,0,0,19,0,17,0,0,18,22,0,21,0],"FLAG":0,"BASE":18} LoraTap SC411WSC-EU RF Remote {"NAME":"Loratap","GPIO":[0,0,0,19,23,17,0,0,18,22,0,21,0],"FLAG":0,"BASE":18} +LoraTap SC500W Roller Shutter {"NAME":"SC500W","GPIO":[0,0,0,158,9,10,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} LoraTap SC511WSC Roller Shutter {"NAME":"SC511WSC","GPIO":[0,255,0,56,17,18,0,0,21,19,22,0,0],"FLAG":0,"BASE":18} +SCS86-03AJAI {"NAME":"ESE86-03AJAI","GPIO":[157,0,58,18,22,19,0,0,17,21,57,23,56],"FLAG":0,"BASE":18} Teekar SYS-CS 01 {"NAME":"Teekar-Tag","GPIO":[56,0,157,18,22,11,0,0,0,21,57,31,17],"FLAG":0,"BASE":18} Teepao {"NAME":"Taopao","GPIO":[255,255,255,18,22,19,0,0,255,21,255,255,17],"FLAG":1,"BASE":18} WF-CS01 {"NAME":"Tuya Shutter","GPIO":[157,0,54,10,22,19,0,0,17,21,53,23,52],"FLAG":0,"BASE":18} @@ -107,9 +119,11 @@ Heltec WiFi Kit 8 {"NAME":"HTIT-W8266","GPIO":[255,255,255,255,6,5,0,0,25 LC Tech relay and PZEM-004T {"NAME":"HW-655 PZEM","GPIO":[0,63,0,62,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Luani HVIO {"NAME":"Luani HVIO","GPIO":[0,255,255,255,21,22,0,0,9,10,255,52,0],"FLAG":1,"BASE":35} OLED Display Module 0.66" for Wemos D1 Mini {"NAME":"OLED 64x48","GPIO":[255,255,255,255,6,5,0,0,255,255,255,255,162],"FLAG":15,"BASE":18} +QuinLED 2 Channel {"NAME":"QuinLED 2 channel","GPIO":[37,0,38,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Splatura USB Device Power Switch {"NAME":"Splatura USB","GPIO":[0,0,52,0,0,0,0,0,0,21,0,122,0],"FLAG":0,"BASE":18} SUPLA inCan by Espablo {"NAME":"Supla Espablo","GPIO":[0,255,4,255,17,21,0,0,255,22,255,0,52],"FLAG":1,"BASE":31} Witty Cloud {"NAME":"Witty Cloud","GPIO":[255,255,56,255,17,255,0,0,38,39,255,37,255],"FLAG":1,"BASE":32} +Yison ESP-01/ESP-202 Development Board {"NAME":"Yison Dev Board","GPIO":[32,157,31,255,33,34,255,255,37,39,30,38,29],"FLAG":15,"BASE":18} ``` ## Dimmable @@ -122,13 +136,17 @@ Arlec Smart 9W 950lm 4000K {"NAME":"Arlec-GLD124HA","GPIO":[0,0,0,0,0,37,0,0,0, Avatar ALS15L Candle {"NAME":"AVATAR","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} Cleverio 51396 800lm {"NAME":"Cleverio E27","GPIO":[0,0,0,0,0,0,0,0,0,0,46,0,0],"FLAG":0,"BASE":18} Connect Smart 10W {"NAME":"CSH-B22WW10W","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Digma DiLight E27 W1 {"NAME":"DiLight E27 W1","GPIO":[0,0,0,0,37,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} DORESshop B11 600lm Filament {"NAME":"Doresshop-cand","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} DORESshop ST64 720lm Filament {"NAME":"DORESshop-ST64","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Feit Electric 800lm {"NAME":" Feit P_A800_2","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Feit Electric 8.8W 800lm Vintage {"NAME":"FEIT A1960CL","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} Feit Electric BR30 650lm {"NAME":"Feit BR30 WW","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Feit Electric BR30 650lm {"NAME":"Feit BR30 CW","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Geeni LUX 800 {"NAME":"Geeni-LUX-800","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Geeni LUX Edison {"NAME":"Geeni-Edison","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -Globe 34209 800lm {"NAME":"Globe WW 800lm","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Globe A19 10W 800lm {"NAME":"Globe WW 800lm","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Gosund A19 8W 2700K {"NAME":"Gosund Wifi Dimmable Bulb","GPIO":[0,0,0,0,37,0,0,0,0,52,0,0,0],"FLAG":0,"BASE":18} Hama 7W 900lm Filament {"NAME":"Hama Filament","GPIO":[255,255,255,255,255,255,255,255,255,255,46,255,255],"FLAG":15,"BASE":18} KMC 70113 A19 7.5W {"NAME":"Generic","GPIO":[0,0,0,0,0,0,37,38,0,0,0,0,0],"FLAG":15,"BASE":18} Kogan ST-20 Filament {"NAME":"Kogan Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":15,"BASE":18} @@ -137,10 +155,10 @@ LeDesign 8W ST21 Filament {"NAME":"Edison Bulb","GPIO":[0,0,0,0,0,0,0,0,0,37,0, Lohas LZN127 G25 800lm {"NAME":"Lohas Globe","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} Lohas ZN014 550lm {"NAME":"Lohas MR16","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} Lohas ZN124 980lm {"NAME":"Lohas LH-ZN124","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect Filament A60 {"NAME":"LSC Filam E27","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect Filament C35 {"NAME":"LSC Filam E14","GPIO":[0,255,0,255,0,0,0,0,38,0,37,0,0],"FLAG":15,"BASE":18} -LSC Smart Connect Filament G125 {"NAME":"LSC Filam Huge","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect Filament ST64 {"NAME":"LSC Filam Big","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +LSC Filament A60 {"NAME":"LSC Filam E27","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +LSC Filament C35 {"NAME":"LSC Filam E14","GPIO":[0,255,0,255,0,0,0,0,38,0,37,0,0],"FLAG":15,"BASE":18} +LSC Filament G125 {"NAME":"LSC Filam Huge","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +LSC Filament ST64 5.5W 470lm {"NAME":"LSC Filam Big","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Lumary 6W 700lm Edison {"NAME":"Lumary TS3Y","GPIO":[0,0,0,0,0,0,0,0,0,37,0,0,0],"FLAG":0,"BASE":18} Luminea ZX-2880 A60 800lm {"NAME":"LAV-110.w","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Luminea ZX-2982 ST64 Filament {"NAME":"Luminea ZX2982","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} @@ -153,6 +171,7 @@ Mirabella Genio 800lm {"NAME":"GenioBulbCW","GPIO":[0,0,0,0,38,37,0,0,0,40,39 Mirabella Genio 9W 800lm {"NAME":"GenioB22","GPIO":[0,0,0,0,0,0,0,0,0,37,0,0,0],"FLAG":0,"BASE":18} Mirabella Genio A70 1400lm {"NAME":"GenioB_CW2744","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Nedis A60 Filament {"NAME":"WIFILF10WTA60","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Nedis A60 Warm White 9W 800lm {"NAME":"WIFILW11WTE27","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Nedis G125 Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} Nedis PAR16 330lm {"NAME":"Nedis WIFILW31","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Sealight Vintage Edison A19 {"NAME":"SealightEdison","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} @@ -167,8 +186,10 @@ Acenx SD03 {"NAME":"SD03","GPIO":[19,18,0,59,158,58,0,0,57,37,56,1 Armtronix AC Dimmer One Triac Board {"NAME":"ARMTR Dimmer","GPIO":[0,148,0,149,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":56} Armtronix AC Dimmer Two Triac Board {"NAME":"ARMTR Dimmer","GPIO":[0,148,0,149,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":56} BrilliantSmart D350W {"NAME":"Generic","GPIO":[255,107,255,108,255,255,0,0,255,0,255,0,255],"FLAG":0,"BASE":54} +BrilliantSmart Jupiter {"NAME":"BrSm Jupiter","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +CE Smart Home {"NAME":"CE-WF500D","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} CE Smart Home CFW500D-3W 3 Way {"NAME":"CE-WF500D-3W","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} -CE Smart Home WF500D {"NAME":"CE-WF500D","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} +CNSKOU Touch {"NAME":"CNSKOU Dimmer Switch","GPIO":[0,0,0,0,0,0,0,0,0,0,54,0,0],"FLAG":0,"BASE":54} Eva Logik WF31 {"NAME":"WF31 Dimmer","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} EX-Store 2 Kanal RS232 V4 {"NAME":"EXS Dimmer","GPIO":[0,148,0,149,0,0,0,0,0,183,0,0,0],"FLAG":0,"BASE":72} Feit Electric DIM/WIFI {"NAME":"Generic","GPIO":[255,107,255,108,255,255,0,0,255,0,255,0,255],"FLAG":0,"BASE":54} @@ -195,10 +216,13 @@ Zemismart KS-7011 {"NAME":"KS-7011 Dimmer","GPIO":[255,107,255,108,255,25 Anko HEGSM40 {"NAME":"Anko HEGSM40","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} Arlec Smart 45cm Smart DC Wall {"NAME":"Arlec 45cm Fan","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} BrilliantSmart 99111 {"NAME":"Brilliant Fan","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +Geek Aire AF1s {"NAME":"Geek Aire Fan","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Goldair SleepSmart GCPF315 {"NAME":"Goldair Fan","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} Lucci Connect Remote Control {"NAME":"Lucci Fan","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} +Sichler Haushaltsgeraete Column {"NAME":"Sichler Fan","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Sonoff IFan02 {"NAME":"Sonoff iFan02","GPIO":[17,255,0,255,23,22,18,19,21,56,20,24,0],"FLAG":0,"BASE":44} Sonoff IFan03 {"NAME":"SonoffiFan03","GPIO":[17,148,0,149,0,0,29,161,23,56,22,24,0],"FLAG":0,"BASE":71} +Technical Pro FXA16 {"NAME":"FXA16 Fan","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} ``` ## IR Bridge @@ -212,9 +236,12 @@ Cusam CS-IRC-1 {"NAME":"YTF IR Bridge","GPIO":[255,255,255,255,56,51,0 Eachen IR DC6 {"NAME":"Eachen IR","GPIO":[0,0,0,0,56,51,0,0,255,17,8,0,0],"FLAG":0,"BASE":18} Geeklink GK01 {"NAME":"GL IR Blaster","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} Jinvoo AC/TV Box Controller {"NAME":"Jinvoo IR Bridge","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} +JS-IR1 Universal Remote {"NAME":"JS-IR1","GPIO":[255,255,255,255,52,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":18} +Lenovo Smart IR Controller {"NAME":"Lenovo IR","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} Mirabella Genio I002577 {"NAME":"Genio IR TxRx","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} Nedis Universal Remote Control {"NAME":"Nedis IR Bridge","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} -NEO Coolcam NAS-IR03W0 {"NAME":"Neo Coolcam IR","GPIO":[0,0,0,0,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} +NEO Coolcam Remote Controller {"NAME":"Neo Coolcam IR","GPIO":[255,148,255,149,158,51,0,0,56,17,8,0,0],"FLAG":0,"BASE":62} +Orvibo Magic Cube {"NAME":"Orvibo","GPIO":[0,0,0,0,17,7,0,0,52,0,51,53,0],"FLAG":0,"BASE":18} RM mini {"NAME":"RM mini","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} STITCH by Monoprice 35753 {"NAME":"Stitch 35753","GPIO":[0,0,0,0,52,51,0,0,0,90,8,0,0],"FLAG":0,"BASE":18} SZMDLX IR Remote Controller {"NAME":"SZMDLX WiFi IR","GPIO":[0,0,0,0,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} @@ -230,11 +257,13 @@ ProfiCook PC-WKS 1167G 1.5L {"NAME":"PC-WKS 1167G","GPIO":[0,107,0,108,0,0,0,0, ## LED Controller ``` Anncoe C350 RGB {"NAME":"TUYA LED","GPIO":[0,0,0,0,0,38,0,0,39,17,37,0,0],"FLAG":0,"BASE":18} +Anncoe C350 RGBW {"NAME":"TUYA LED","GPIO":[0,0,0,0,0,38,0,0,39,17,37,40,0],"FLAG":0,"BASE":18} Arilux AL-LC01 {"NAME":"Arilux LC01","GPIO":[17,0,59,0,147,37,0,0,38,39,0,0,0],"FLAG":0,"BASE":37} Arilux AL-LC06 {"NAME":"Arilux LC06","GPIO":[17,0,0,0,0,0,0,0,38,39,37,41,40],"FLAG":0,"BASE":18} Arilux AL-LC11 {"NAME":"Arilux LC11","GPIO":[17,0,59,0,38,37,0,0,41,40,39,147,0],"FLAG":0,"BASE":38} Arilux SL-LC 03 {"NAME":"Arilux LC03","GPIO":[0,0,0,0,51,38,0,0,37,39,0,40,0],"FLAG":0,"BASE":34} Arilux SL-LC 09 {"NAME":"Arilux LC09","GPIO":[0,0,0,0,106,37,0,0,39,0,38,0,0],"FLAG":0,"BASE":18} +CIN-03 96W RGB {"NAME":"CIN03-03 Strip","GPIO":[0,0,0,0,38,0,0,0,37,0,39,0,0],"FLAG":0,"BASE":18} DD001-MINI(G)-IR-V08 {"NAME":"WIFI-RGB","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Electrodragon ESP LED Strip Board, Mosfet Drive {"NAME":"LEDBoard RGBW","GPIO":[0,0,0,0,0,0,0,0,39,38,40,37,52],"FLAG":0,"BASE":18} H801 {"NAME":"H801","GPIO":[0,52,0,0,41,57,0,0,39,38,40,37,0],"FLAG":0,"BASE":20} @@ -244,15 +273,16 @@ Luminea ZX-2844 {"NAME":"Luminea ZX-284","GPIO":[40,0,0,0,0,39,0,0,38,1 Luminea ZX-2844-675 {"NAME":"ZX-2844-675","GPIO":[17,0,0,0,38,40,0,0,37,0,39,0,0],"FLAG":0,"BASE":18} Lustreon {"NAME":"Lustreon WiFi ","GPIO":[17,0,55,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":38} Magic UFO RGBW {"NAME":"Magic UFO","GPIO":[17,0,157,0,0,37,0,0,39,40,38,56,0],"FLAG":0,"BASE":18} -MagicHome RGB ZJ-WFMN-A V1.1 {"NAME":"MagicHome RGB","GPIO":[0,0,0,0,0,37,0,0,38,39,0,0,0],"FLAG":0,"BASE":34} +MagicHome RGB ZJ-WFMN-B V1.1 {"NAME":"MagicHome RGB","GPIO":[0,0,0,0,0,37,0,0,38,39,0,0,0],"FLAG":0,"BASE":34} MagicHome RGBW ESP-IR-B-v2.3 {"NAME":"ESP-IR-B-v2.3","GPIO":[0,0,51,0,0,38,0,0,37,39,0,40,0],"FLAG":0,"BASE":18} +MagicHome RGBW RF {"NAME":"MagicHome RF","GPIO":[0,0,0,0,0,38,0,0,39,40,37,0,0],"FLAG":0,"BASE":18} MagicHome RGBW ZJ-WFMN-A V1.1 {"NAME":"MagicHome RGBW","GPIO":[0,0,0,0,51,38,0,0,37,39,0,40,0],"FLAG":0,"BASE":34} MagicHome RGBWW w/ RF {"NAME":"MagicHome RF","GPIO":[0,0,159,0,37,38,0,0,41,40,39,147,0],"FLAG":0,"BASE":38} MagicHome RGBWW w/ RF {"NAME":"MagicHome RF","GPIO":[0,0,0,0,147,40,0,0,38,39,37,41,159],"FLAG":0,"BASE":18} MagicHome Single Color 5-28V {"NAME":"MagicHome","GPIO":[0,0,0,0,0,0,0,0,37,0,0,0,0],"FLAG":0,"BASE":18} MagicHome ZJ-ESP-IR-F V1 {"NAME":"ZJ-ESP-IR-F V1","GPIO":[0,0,0,0,51,38,0,0,37,39,0,40,0],"FLAG":0,"BASE":18} -Maxonar Lightstrip Pro XS-SLD001 {"NAME":"Maxonar LED","GPIO":[0,0,0,0,0,37,0,0,39,17,38,0,0],"FLAG":0,"BASE":18} Nexlux {"NAME":"MagicHome V1.1","GPIO":[0,0,0,0,51,37,0,0,38,39,0,0,0],"FLAG":0,"BASE":34} +QS-WIFI-RGBCW {"NAME":"QS-WIFI-RGBCW","GPIO":[0,0,17,0,157,38,0,0,39,0,53,37,0],"FLAG":0,"BASE":18} Shelly RGBW2 {"NAME":"Shelly RGBW2","GPIO":[0,0,52,0,40,255,0,0,37,17,39,38,0],"FLAG":0,"BASE":18} ZJ-WF-ESP-A v1.1 {"NAME":"RGB2","GPIO":[0,0,0,0,0,0,0,0,38,37,39,0,0],"FLAG":0,"BASE":18} ``` @@ -265,39 +295,57 @@ BlitzWolf BW-LT11 {"NAME":"BW-LT11 Strip","GPIO":[17,0,0,0,37,40,0,0,38,0 BrilliantSmart 20743 RGB+W {"NAME":"BrilliantStrip","GPIO":[17,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Briloner 2256-150 RGB {"NAME":"Briloner2256-1","GPIO":[51,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Cocoon Smart {"NAME":"Cocoon Smart","GPIO":[17,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Deltaco 3m RGBCCT {"NAME":"Deltaco Led Strip","GPIO":[0,0,0,0,37,17,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +electriQ 3m RGBCCT {"NAME":"ElectricQ wifiRGBWLEDSTR","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} +Elfeland 10m RGB {"NAME":"Elfeland RGB","GPIO":[0,0,0,0,0,38,0,0,39,51,0,37,0],"FLAG":0,"BASE":18} +Gosund 2.8m RGB {"NAME":"Gosund LED Strip","GPIO":[17,0,0,0,0,0,0,0,37,39,38,0,0],"FLAG":3,"BASE":18} HitLights L1012V-MC1 {"NAME":"HitLights RBG","GPIO":[17,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +HomeMate 10m RGB {"NAME":"Homemate Strip","GPIO":[0,0,0,0,0,37,0,0,39,17,38,0,0],"FLAG":0,"BASE":18} Hykker 3m RGB {"NAME":"HYKKER Strip","GPIO":[0,0,0,0,0,37,0,0,39,17,38,0,0],"FLAG":0,"BASE":18} INDARUN RGB String Lights {"NAME":"STAR301","GPIO":[0,0,0,0,51,37,0,0,38,39,0,0,0],"FLAG":0,"BASE":34} +Kogan RGB + Cool & Warm White 2m {"NAME":"RGB+W+C Strip","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} LE LampUX 16.4ft RGB {"NAME":"LampUX","GPIO":[0,18,17,0,0,38,0,0,39,51,0,37,0],"FLAG":0,"BASE":18} LE LampUX 2m RGB TV Backlight {"NAME":"LE 904102","GPIO":[0,17,18,0,0,38,0,0,39,19,0,37,0],"FLAG":0,"BASE":18} LE LampUX 5m RGB {"NAME":"LampUX","GPIO":[17,0,0,0,0,38,0,0,39,0,0,37,0],"FLAG":0,"BASE":18} LE LampUX 5m RGB {"NAME":"LE LampUx","GPIO":[0,0,0,0,0,38,0,0,39,0,0,37,0],"FLAG":0,"BASE":34} LE lampUX 5m RGBW {"NAME":"LampUX","GPIO":[0,0,17,0,0,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} Lohas ZN022 5m RGBW {"NAME":"LOHAS M5-022","GPIO":[0,0,0,0,38,37,0,0,17,39,0,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect RGBW {"NAME":"LSC RGBW Strip","GPIO":[51,0,0,0,37,0,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} +LSC RGBW {"NAME":"LSC RGBW Strip","GPIO":[51,0,0,0,37,0,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} Lumary RGBCCT {"NAME":"Lumary LED","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Lumary RGBCCT {"NAME":"Lumary LED","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Maxonar Lightstrip Pro XS-SLD001 {"NAME":"Maxonar LED","GPIO":[0,0,0,0,0,37,0,0,39,17,38,0,0],"FLAG":0,"BASE":18} Merkury Innovations MI-EW003-999W {"NAME":"MI-EW003-999W ","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Mirabella Genio I002579 {"NAME":"MirabellaStrip","GPIO":[17,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Monster Smart IlluminEssence {"NAME":"MI-EW003-999W ","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Powertech 5m RGBW {"NAME":"Jaycar ST3992 LED Strip","GPIO":[122,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Sonoff L1 {"NAME":"SonoffL1","GPIO":[0,148,0,149,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":70} Teckin SL02 {"NAME":"Teckin SL02","GPIO":[51,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":52} +Teckin SL07 32.8ft RGB {"NAME":"WIFI RGB","GPIO":[51,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +TORCHSTAR CCT 30W Lighting Kit {"NAME":"Torchstar CCT ","GPIO":[0,0,0,0,52,38,0,0,0,17,0,37,53],"FLAG":0,"BASE":18} Torchstar Safe Lighting Kit {"NAME":"Torchstar","GPIO":[0,0,0,0,52,0,0,0,0,0,0,37,53],"FLAG":1,"BASE":18} -Zemismart RGBW {"NAME":"Zemismart LED","GPIO":[0,0,0,0,38,37,0,0,0,39,40,0,0],"FLAG":0,"BASE":18} +Woox 5m RGBW {"NAME":"GardenLedstrip1","GPIO":[0,0,0,0,0,38,0,0,39,9,37,0,0],"FLAG":0,"BASE":18} +Zemismart 3m Extendable RGBW {"NAME":"Zemismart LED","GPIO":[0,0,0,0,38,37,0,0,0,39,40,0,0],"FLAG":0,"BASE":18} ``` ## Light ``` Arlec Smart 15W Security Floodlight {"NAME":"ArlecFlood","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":15,"BASE":18} +Arlec Smart 20W Movement Activated Security {"NAME":"Arlec MAL300HA","GPIO":[0,0,0,0,21,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Arlec Smart 40W 4000lm LED Batten {"NAME":"Arlec Batten","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Arlec Smart Portable Floodlight 10.5W {"NAME":"Arlec GLD301HA","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Arlec Smart Up & Down LED Wall {"NAME":"Arlec Up Down CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +BAZZ 14" RGBCCT Ceiling Fixture {"NAME":"WF19129W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +BAZZ 4 in. RGB Recessed Fixture {"NAME":"SLMR4RGBWWFW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-LT20 {"NAME":"BW-LT20","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":15,"BASE":18} +Brelong USB Charging Night {"NAME":"Brelong Smart USB Charging Lamp","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,40],"FLAG":0,"BASE":18} Brilex Nightstand Lamp {"NAME":"Smart Table La","GPIO":[0,0,18,0,37,157,0,0,38,17,39,0,40],"FLAG":0,"BASE":18} -Brilliant CORDIA Colour Temperature Changing LED Flush Ceiling Light {"NAME":"Brilliant Oyst","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +BrilliantSmart 12W 290mm Salisbury CCT Ceiling {"NAME":"Brilliant Smart Salisbury","GPIO":[0,0,0,0,0,0,0,0,47,0,37,0,0],"FLAG":0,"BASE":18} BrilliantSmart 20695 Downlight CCT {"NAME":"SmartCCTDwnLgt","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} +BrilliantSmart 24W 410mm Salisbury CCT Ceiling {"NAME":"Salisbury","GPIO":[0,0,0,0,0,0,0,0,47,0,37,0,0],"FLAG":0,"BASE":48} +BrilliantSmart Cordia 24W CCT Ceiling {"NAME":"Cordia","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} BrilliantSmart Prism LED RGBCCT Downlight {"NAME":"Prism","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} BrilliantSmart RGB Garden Kit {"NAME":"Brilliant Gard","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Calex 429250 Ceiling {"NAME":"Calex_LED","GPIO":[0,0,0,0,0,0,0,0,52,37,38,54,0],"FLAG":0,"BASE":18} +Calex 429250 Ceiling {"NAME":"Calex_LED","GPIO":[0,0,0,0,0,0,0,0,0,47,37,0,0],"FLAG":0,"BASE":18} Connect SmartHome CSH-240RGB10W {"NAME":"Connect1","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Connect SmartHome CSH-FSTN12 {"NAME":"CSH-FSTN12","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Deta 18W 1900lm T8 Tube {"NAME":"DETA Smart LED","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} @@ -312,9 +360,12 @@ iHomma Downlight {"NAME":"iHommaLEDDownl","GPIO":[0,0,0,0,0,40,0,0,37,38 Kogan 9W Downlight RGBCCT {"NAME":"Kogan_SMARTLED","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} LE lampUX 15W RGBCCT Ceiling {"NAME":"LE lampUX 15W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Lohas ZN026CL10 RGBCCT {"NAME":"Lohas LED Lamp","GPIO":[0,0,0,0,38,37,0,0,40,39,41,0,0],"FLAG":0,"BASE":18} +LSC 20W 1400lm White Ambiance Ceiling {"NAME":"LSC RGBCW LED","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} Lumary 18W RGBCCT Recessed Panel {"NAME":"LumaryDLghtRGB","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +LVL 300mm Round Ceiling {"NAME":"LVL 300m Round 24W Ceiling LED","GPIO":[0,0,0,0,0,37,0,0,0,47,0,0,0],"FLAG":0,"BASE":48} Mi LED Desk Lamp MJTD01YL {"NAME":"Mi Desk Lamp","GPIO":[0,0,17,0,37,38,0,0,150,151,0,0,0],"FLAG":0,"BASE":66} MiraBella Genio 6 Pack 30mm Stainless Steel Deck Kit {"NAME":"Genio RGB Deck Lights","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Mirabella Genio CCT Deck Lights {"NAME":"Mirabella Deck CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} Mirabella Genio I002741 {"NAME":"GenioDLightRGB","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Mirabella Genio I002742 {"NAME":"GenioDLightCCT","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":48} Mirabella Genio I002798 Warm White Filament Festoon {"NAME":"GenioFestoon","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} @@ -323,7 +374,7 @@ Novostella UT88835 20W Floodlight {"NAME":"Novo 20W Flood","GPIO":[0,0,0,0,37,4 SMRTLite LED Panel {"NAME":"SMRTLite","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Sonoff BN-SZ01 {"NAME":"Sonoff BN-SZ","GPIO":[0,0,0,0,0,0,0,0,37,56,0,0,0],"FLAG":0,"BASE":22} Spotlight 9cm RGB+W 7W {"NAME":"Spotlight RGBW","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} -Teckin FL41 {"NAME":"Teckin FL41","GPIO":[0,0,0,0,0,17,0,0,0,0,21,0,0],"FLAG":0,"BASE":18} +Teckin FL41 {"NAME":"Teckin FL41","GPIO":[0,0,0,0,0,17,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} Utorch PZE-911 {"NAME":"Utorch PZE-911","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":1} Utorch UT40 {"NAME":"Utorch UT40","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":1} Verve Design Angie 18W Ceiling Light With RGB Ring {"NAME":"ACL12HA Light","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} @@ -338,18 +389,28 @@ Zemismart 6" 14W RGBCCT {"NAME":"ZemiDownLight6","GPIO":[0,0,0,0,37,40,0,0,38,4 ## Miscellaneous ``` iLONDA Fish feeder {"NAME":"Feeder","GPIO":[0,0,0,0,17,56,0,0,42,0,21,0,0],"FLAG":0,"BASE":18} +Kogan 1500w Panel Heater {"NAME":"Kogan Panel Heater","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} Mosquito Killer Lamp {"NAME":"MosquitoKiller","GPIO":[17,0,0,0,0,0,0,0,37,56,0,0,0],"FLAG":0,"BASE":18} Proscenic 807C Humidifier {"NAME":"Generic","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} Sonoff RM433 RF Remote Controller {"NAME":"REQUIRES RF DEVICE"} ``` +## Motor +``` +Zemismart BCM300D-TY {"NAME":"Zemistart_Curt","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} +Zemismart Blinds Controller {"NAME":"Zemismart Blin","GPIO":[255,255,255,255,255,255,0,0,255,108,255,107,255],"FLAG":0,"BASE":54} +Zemismart Roller Shade {"NAME":"M2805EIGB","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} +Zemismart Updated RF Remote Roller Shade {"NAME":"Zemismart M515EGB","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} +``` + ## Outdoor Plug ``` Acenx SOP04-US Dual {"NAME":"SOP04-US Dual","GPIO":[255,255,255,255,56,57,0,0,21,17,22,255,255],"FLAG":0,"BASE":18} Aicliv SOP03-US {"NAME":"AICLIV SOP03US","GPIO":[0,0,0,23,57,0,0,0,21,18,22,0,0],"FLAG":15,"BASE":18} Albohes PC-1606 {"NAME":"Albohes PC1606","GPIO":[17,0,0,0,0,22,18,0,21,0,0,0,0],"FLAG":1,"BASE":39} Albohes PS-1602 {"NAME":"Albohes PC1606","GPIO":[17,0,0,0,0,22,18,0,21,0,0,0,0],"FLAG":1,"BASE":39} -Aoycocr X13 {"NAME":"Aoycocr X13","GPIO":[0,0,56,0,0,0,0,0,21,17,0,22,0],"FLAG":0,"BASE":18} +Aoycocr X13 {"NAME":"Aoycocr X13","GPIO":[0,0,56,0,0,0,0,0,22,17,0,21,0],"FLAG":0,"BASE":18} +Atomi AT1320 {"NAME":"AT1320","GPIO":[0,0,0,0,57,52,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Brennenstuhl WA 3000 XS02 {"NAME":"WA 3000 XS02","GPIO":[0,0,0,0,21,17,0,0,158,52,0,0,0],"FLAG":0,"BASE":61} C137 IP55 {"NAME":"C137 Outdoor","GPIO":[0,17,0,56,134,132,0,0,21,131,22,0,0],"FLAG":15,"BASE":18} C168 IP64 {"NAME":"C188","GPIO":[56,0,57,0,18,0,0,0,21,17,157,22,0],"FLAG":0,"BASE":18} @@ -359,6 +420,7 @@ Feit Electric PLUG/WIFI/WP {"NAME":"Prime Smart ou","GPIO":[0,255,0,255,157,56, Forrinx SH-18EU-A {"NAME":"SH-18EU-A","GPIO":[0,0,0,0,22,52,21,57,17,0,0,0,0],"FLAG":0,"BASE":18} Geeni Outdoor {"NAME":"Geeni Outdoor","GPIO":[17,0,0,0,0,57,0,0,0,52,21,0,0],"FLAG":0,"BASE":18} Geeni Outdoor DUO Dual Outlet {"NAME":"Geeni Dual Out","GPIO":[17,0,0,0,0,57,0,0,0,56,21,0,22],"FLAG":0,"BASE":18} +Globe 2-Outlet {"NAME":"Globe SK509W2S","GPIO":[0,0,0,0,22,0,0,0,17,21,56,0,0],"FLAG":0,"BASE":18} HA109US {"NAME":"HA109US","GPIO":[17,0,0,0,52,53,0,0,21,0,22,0,0],"FLAG":0,"BASE":18} iClever IC-BS06 {"NAME":"iClever Switch","GPIO":[0,0,0,0,157,56,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} King-Link C128 {"NAME":"King-Link C128","GPIO":[0,0,58,0,22,56,0,0,23,157,17,21,57],"FLAG":0,"BASE":18} @@ -367,12 +429,13 @@ LEPOWER {"NAME":"LEPOWER Outdoo","GPIO":[255,255,255,255,56,57, Luminea NX-4458 {"NAME":"Luminea NX4458","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":65} Maxcio EOP03-EU {"NAME":"Maxcio EOP03-EU","GPIO":[0,0,0,0,22,57,0,0,21,52,17,0,58],"FLAG":0,"BASE":18} Maxcio SOP02-US {"NAME":"Maxcio SOP02US","GPIO":[0,0,0,0,0,157,0,0,21,17,22,0,0],"FLAG":15,"BASE":18} -Merkury MI-OW101-101W {"NAME":"Merkury Switch","GPIO":[17,255,255,255,0,56,0,0,0,54,21,255,255],"FLAG":1,"BASE":18} +Merkury MI-OW101-101W {"NAME":"Merkury Switch","GPIO":[17,0,0,0,0,57,0,0,0,52,21,0,0],"FLAG":0,"BASE":18} Minoston MP22W {"NAME":"Minoston MP22W","GPIO":[0,0,0,0,56,0,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} -Nedis PO120 IP44 {"NAME":"WIFIPO120FWT","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} +Nedis PO120 IP44 {"NAME":"WIFIPO120FWT","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} Obi Stecker IP44 {"NAME":"OBI Socket 2","GPIO":[0,0,0,0,21,17,0,0,56,53,0,0,0],"FLAG":0,"BASE":61} Oittm Outdoor {"NAME":"Oittm Outdoor","GPIO":[17,0,0,0,0,0,0,0,0,0,56,21,255],"FLAG":0,"BASE":18} Peteme PS-1602 {"NAME":"Peteme Outdoor","GPIO":[17,0,0,0,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":18} +Poweradd {"NAME":"POWERADD","GPIO":[0,0,0,0,56,57,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} Prime RCWFIO 2-Outlet {"NAME":"Prime Outdoor","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Signstek EOP03-EU {"NAME":"Signstek EOP03","GPIO":[0,0,0,0,56,57,0,0,21,17,22,0,0],"FLAG":15,"BASE":18} SK03 {"NAME":"SK03 Outdoor","GPIO":[17,0,0,0,133,132,0,0,131,57,56,21,0],"FLAG":0,"BASE":57} @@ -383,6 +446,8 @@ Teckin SS42 {"NAME":"Teckin SS42","GPIO":[0,0,0,0,56,57,0,0,21,17,2 Top-Max PS-1602 {"NAME":"PS-1602","GPIO":[17,255,255,255,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":29} Torchstar LITEdge 2-in-1 {"NAME":"LITEdge Plug","GPIO":[0,0,0,0,56,57,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} Ucomen PA-GEBA-01SWP {"NAME":"PA-GEBA-01SWP","GPIO":[0,0,0,0,52,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Woox R4051 {"NAME":"Woox R4051","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":18} +Woox R4052 {"NAME":"Woox R4052","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":18} ``` ## Plug @@ -423,13 +488,15 @@ Aoycocr X5P {"NAME":"Aoycocr X5P","GPIO":[56,0,57,0,0,0,0,0,0,17,0, Aoycocr X6 {"NAME":"Aoycocr X6","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Aquiv S1 {"NAME":"Aquiv S1","GPIO":[0,0,157,0,56,0,0,0,21,17,0,0,0],"FLAG":15,"BASE":18} Arlec 10m Smart Extension Lead {"NAME":"Arlec Ext Cord","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +Arlec Heavy Duty 20m Extension Lead {"NAME":"Arlec Ext Cord","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Arlec Smart 2.1A USB Charger {"NAME":"Arlec Single","GPIO":[0,0,0,0,57,0,0,0,21,0,90,0,0],"FLAG":0,"BASE":18} Arlec Smart PC189HA {"NAME":"Arlec Single","GPIO":[0,0,0,0,57,0,0,0,21,0,90,0,0],"FLAG":0,"BASE":18} -Arlec Smart PC190HA {"NAME":"Arlec-PC190HA","GPIO":[0,0,0,0,0,0,0,0,21,56,17,0,0],"FLAG":0,"BASE":18} +Arlec Smart PC190HA {"NAME":"Arlec-PC190HA","GPIO":[0,0,0,0,56,0,0,0,21,158,17,0,0],"FLAG":0,"BASE":18} Arlec Smart PC399HA Plug {"NAME":"PC399HA","GPIO":[0,0,0,17,134,132,0,0,131,158,21,0,0],"FLAG":0,"BASE":52} Arlec Twin PC288HA {"NAME":"Arlec Twin","GPIO":[0,17,0,22,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Atomi AT1217 {"NAME":"AT1217","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Aukey SH-PA1 {"NAME":"AUKEY SH-PA1","GPIO":[56,0,57,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} +Aukey SH-PA2 {"NAME":"AUKEY SH-PA2","GPIO":[0,0,0,0,158,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} Aukey SH-PA3 {"NAME":"Aukey SH-PA3","GPIO":[0,0,158,0,57,17,0,0,22,0,0,21,0],"FLAG":0,"BASE":18} Aunics Smart EU {"NAME":"AUNICS","GPIO":[0,0,0,17,134,132,0,0,131,157,21,0,0],"FLAG":0,"BASE":18} Aunics Smart IT {"NAME":"AUNICS","GPIO":[0,0,0,17,134,132,0,0,131,157,21,0,0],"FLAG":0,"BASE":18} @@ -444,16 +511,18 @@ Avatar AWP14H {"NAME":"Avatar UK 10A","GPIO":[0,0,56,0,0,134,0,0,131, Avatto JH-G01E {"NAME":"AVATTO JH-G01E","GPIO":[0,145,0,146,0,0,0,0,17,56,21,0,0],"FLAG":0,"BASE":41} Avatto NAS-WR01W 10A {"NAME":"AvattoNAS-WR01W","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Avatto OT06 16A {"NAME":"Avatto OT06","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} -Avatto OT08 {"NAME":"Avatto OT08","GPIO":[37,0,39,0,38,134,0,0,130,132,21,0,0],"FLAG":0,"BASE":18} +Avatto OT08 {"NAME":"Avatto OT08","GPIO":[37,0,39,0,38,134,0,0,130,17,132,21,0],"FLAG":0,"BASE":18} +Awow EU3S {"NAME":"AWOW BSD33","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} Awow X5P {"NAME":"Awow","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} AWP02L-N {"NAME":"AWP02L-N","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} AzpenHome Smart {"NAME":"Socket2Me","GPIO":[52,255,255,255,22,255,0,0,21,255,17,255,255],"FLAG":0,"BASE":18} Bakibo TP22Y {"NAME":"Bakibo TP22Y","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":52} Bardi 16A {"NAME":"BARDI","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57,131],"FLAG":0,"BASE":18} -Bauhn ASPU-1019 {"NAME":"Buahn Smart Pl","GPIO":[0,0,0,0,21,22,0,0,0,56,17,0,0],"FLAG":0,"BASE":18} +Bauhn ASPU-1019 {"NAME":"Bauhn Smart Pl","GPIO":[0,0,0,0,21,22,0,0,0,56,17,0,0],"FLAG":0,"BASE":18} Bearware 303492 3AC+2USB {"NAME":"Bearware 30349","GPIO":[0,56,0,17,22,23,0,0,24,21,157,0,0],"FLAG":0,"BASE":18} Bestek MRJ1011 {"NAME":"BestekMRJ1011","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} BlitzWolf BW-SHP10 {"NAME":"BW-SHP10","GPIO":[0,0,0,0,157,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} +BlitzWolf BW-SHP10-P {"NAME":"BW-SHP10 PM","GPIO":[0,148,0,207,158,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-SHP2 {"NAME":"BlitzWolf SHP","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} BlitzWolf BW-SHP3 {"NAME":"BlitzWolf SHP3","GPIO":[56,0,57,0,22,134,0,0,131,18,132,21,17],"FLAG":0,"BASE":45} BlitzWolf BW-SHP3 alt {"NAME":"BlitzWolf SHP3","GPIO":[18,56,0,131,134,132,0,0,17,0,22,21,0],"FLAG":0,"BASE":18} @@ -468,7 +537,9 @@ Brennenstuhl WA 3000 XS01 {"NAME":"WA 3000 XS01","GPIO":[0,0,0,0,21,17,0,0,158, Bright {"NAME":"Bright Wi-Fi Smart Plug","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} Brilliant HK17654S05 {"NAME":"HK17654S05","GPIO":[17,255,255,255,133,132,255,255,131,56,21,255,255],"FLAG":0,"BASE":18} Brilliant Lighting BL20925 {"NAME":"BL20925","GPIO":[0,0,0,17,133,132,0,0,131,158,21,0,0],"FLAG":0,"BASE":52} +Brilliant Smart Double Adaptor {"NAME":"Brilliant_2Plg","GPIO":[0,0,0,52,21,22,255,255,157,17,18,0,0],"FLAG":0,"BASE":18} BrilliantSmart 20676 USB Charger {"NAME":"Brilliant","GPIO":[0,0,0,0,0,21,0,0,0,52,90,0,0],"FLAG":0,"BASE":18} +BSD01 {"NAME":"BSD01","GPIO":[255,56,255,255,255,255,0,0,21,17,57,255,255],"FLAG":0,"BASE":18} BSD13 {"NAME":"TuyaPlugBSD13","GPIO":[0,57,0,0,0,0,0,0,21,17,52,0,0],"FLAG":0,"BASE":18} BSD15 {"NAME":"TuyaPlugBSD15","GPIO":[255,255,255,255,255,255,0,0,21,17,56,255,255],"FLAG":1,"BASE":18} BSD25 {"NAME":"Tuya Wifi Plug","GPIO":[255,255,255,255,56,255,0,0,21,17,255,255,255],"FLAG":0,"BASE":18} @@ -478,8 +549,10 @@ BSD33 16A {"NAME":"Generic","GPIO":[0,255,0,131,134,132,0,0,21,17 BSD34 {"NAME":"BSD34 Plug","GPIO":[0,0,0,0,0,0,0,0,21,17,56,0,0],"FLAG":0,"BASE":18} BSD34-1-16A {"NAME":"BSD34-1 16A","GPIO":[0,53,0,131,134,132,0,0,21,17,52,0,0],"FLAG":0,"BASE":18} BSD48 16A {"NAME":"BSD48 Plug","GPIO":[0,52,0,0,0,0,0,0,21,17,57,0,0],"FLAG":0,"BASE":18} +Bytech {"NAME":"BYTECH B POWERED","GPIO":[0,57,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Calex 429198 {"NAME":"Calex Pwr Plug","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":1} +CE Smart Home {"NAME":"LITESUN LA-WF7","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":18} CE Smart Home LA-WF3 {"NAME":"CE LA-WF3","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} -CE Smart Home LA-WF7 {"NAME":"LITESUN LA-WF7","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":18} Conico SM-PW70 {"NAME":"Conico SM-PW70","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":1,"BASE":18} Connex CC-P1000 {"NAME":"Connex Smart T","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} Coosa {"NAME":"COOSA","GPIO":[0,0,0,0,57,52,0,0,21,17,255,0,0],"FLAG":0,"BASE":1} @@ -493,6 +566,8 @@ Deltaco SH-P01E {"NAME":"DELTACO SH-P01E","GPIO":[0,56,0,17,134,132,0,0 Deltaco SH-P02 {"NAME":"Deltaco SH-P02","GPIO":[18,0,0,0,134,132,0,0,131,56,21,22,17],"FLAG":0,"BASE":18} DETA 62120HA Smart Plug Base {"NAME":"DetaPlugBase","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Deta 6930HA {"NAME":"DetaSmartPlug","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +Digma DiPlug 100S {"NAME":"Digma DiPlug 100s","GPIO":[56,0,157,255,0,134,255,255,255,17,132,21,0],"FLAG":15,"BASE":18} +Digma DiPlug 160M {"NAME":"DiPlug 160M","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":55} Digoo DG-SP01 {"NAME":"DG-SP01","GPIO":[255,17,255,21,56,37,0,0,38,39,40,255,255],"FLAG":0,"BASE":18} Digoo NX-SP202 {"NAME":"Generic_SP202","GPIO":[52,0,0,131,91,134,0,0,22,17,132,21,0],"FLAG":0,"BASE":63} Dilisens NX-SP201 Mini 2 in 1 {"NAME":"NX-SP201","GPIO":[0,0,131,0,134,132,52,21,18,22,17,0,0],"FLAG":0,"BASE":18} @@ -500,7 +575,7 @@ DILISENS SP201 {"NAME":"Dilisens SP201","GPIO":[0,0,131,0,133,132,52,2 Dunnes Stores {"NAME":"SmartLifePlug","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} DWFeng AWP02L-N {"NAME":"AWP02L-N","GPIO":[255,255,56,255,255,255,0,0,255,17,255,21,255],"FLAG":0,"BASE":18} DWFeng BSD01 {"NAME":"DWFeng BSD01","GPIO":[255,255,255,255,255,255,255,255,21,17,56,255,255],"FLAG":15,"BASE":18} -ECO Plugs CT-065W {"NAME":"ECO/CT-065W","GPIO":[0,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} +ECO Plugs CT-065W {"NAME":"ECO/CT-065W","GPIO":[0,0,158,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} eco4life DPS1101S {"NAME":"Eco4Life Plug","GPIO":[0,0,0,0,52,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} ednet 84334 {"NAME":"84334","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} eFamilyCloud ASDFEE174 {"NAME":"eFamily Plug","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} @@ -536,25 +611,31 @@ Gosund SP1 {"NAME":"Gosund SP1 v23","GPIO":[0,56,0,17,134,132,0,0, Gosund SP111 {"NAME":"Gosund SP111","GPIO":[56,0,57,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} Gosund SP111 v1.1 {"NAME":"SP111 v1.1","GPIO":[56,0,158,0,132,134,0,0,131,17,0,21,0],"FLAG":0,"BASE":45} Gosund SP111 v1.4 {"NAME":"Gosund SP111","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} -Gosund SP112 {"NAME":"SHP5","GPIO":[57,145,56,146,255,22,0,0,255,255,21,255,18],"FLAG":0,"BASE":18} +Gosund SP112 {"NAME":"SHP5","GPIO":[57,145,56,146,255,22,0,0,255,255,21,255,17],"FLAG":0,"BASE":18} +Gosund SP112 {"NAME":"Gosund 112v3.4","GPIO":[56,0,57,0,132,134,0,0,131,30,21,0,0],"FLAG":4,"BASE":18} +Gosund SP211 {"NAME":"Gosund SP211","GPIO":[18,158,56,131,134,132,0,0,17,57,21,0,22],"FLAG":0,"BASE":18} Gosund UP111 {"NAME":"Gosund UP111","GPIO":[0,52,0,17,134,132,0,0,131,157,21,0,0],"FLAG":0,"BASE":18} Gosund WP1 {"NAME":"Gosund WP1-1","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} Gosund WP2 {"NAME":"Gosund WP2","GPIO":[17,158,57,0,18,0,0,0,22,56,21,0,0],"FLAG":0,"BASE":18} Gosund WP211 {"NAME":"Gosund wp211","GPIO":[0,0,0,0,21,0,0,0,0,17,0,22,18],"FLAG":0,"BASE":18} -Gosund WP212 {"NAME":"Gosund_WP212","GPIO":[17,0,0,0,18,0,0,0,21,0,22,0,0],"FLAG":0,"BASE":18} +Gosund WP212 {"NAME":"Gosund_WP212","GPIO":[17,0,0,0,18,0,0,0,22,0,21,0,0],"FLAG":0,"BASE":18} Gosund WP3 {"NAME":"Gosund WP3","GPIO":[0,0,0,0,17,0,0,0,56,57,21,0,0],"FLAG":0,"BASE":18} -Gosund WP5 {"NAME":"Gosund-WP5","GPIO":[255,255,255,255,17,255,0,0,56,158,21,255,255],"FLAG":0,"BASE":18} +Gosund WP5 {"NAME":"Gosund-WP5","GPIO":[0,0,0,0,17,0,0,0,56,57,21,0,0],"FLAG":0,"BASE":18} Gosund WP6 {"NAME":"Gosund WP6","GPIO":[0,0,0,17,0,0,0,0,56,57,21,0,0],"FLAG":0,"BASE":18} Grefic TE101 {"NAME":"Grefic TE101","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} +GSP1311 Series {"NAME":"GSP1311","GPIO":[57,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":15,"BASE":18} Gyman SM-PW701U {"NAME":"Gyman","GPIO":[255,255,157,255,56,255,0,0,21,17,255,255,255],"FLAG":0,"BASE":18} Hama 16A 3680W {"NAME":"Hama Plug","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":52} Hauppauge 01647 {"NAME":"SL-1642","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +HBN BNC-60/U152T {"NAME":"BNC-60/U152T","GPIO":[0,0,0,0,56,0,255,255,21,17,0,0,0],"FLAG":0,"BASE":18} HiHome WPP-10S1 {"NAME":"HIhome WPP-10S","GPIO":[56,0,158,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":49} HiHome WPP-10S2 {"NAME":"HiHome WPP-10S","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} HiHome WPP-16S {"NAME":"HIhome WPP-16S","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} HiHome WPP-16T {"NAME":"HiHome WPP-16T","GPIO":[17,56,255,255,134,132,0,0,18,255,22,130,21],"FLAG":1,"BASE":18} HIPER IoT P01 {"NAME":"HIPER IoT P01","GPIO":[0,0,0,0,0,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} hiwild W-US002 {"NAME":"W-US002","GPIO":[0,17,0,0,0,0,0,0,0,52,21,0,158],"FLAG":0,"BASE":18} +Hoin 10A {"NAME":"NIOH XS-SSC01","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +HomeMate 16A Heavy Duty {"NAME":"HMLPG16","GPIO":[0,52,0,17,134,132,0,0,131,157,21,0,0],"FLAG":0,"BASE":18} Houzetek AWP07L {"NAME":"AWP07L","GPIO":[56,0,0,130,0,134,0,0,0,17,132,21,0],"FLAG":0,"BASE":18} HS108 {"NAME":"HS108","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":1,"BASE":18} HS108A {"NAME":"HS108A","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":1,"BASE":18} @@ -565,8 +646,11 @@ Hyleton 313 {"NAME":"Hyleton 313","GPIO":[57,0,56,0,0,0,0,0,0,17,0, Hyleton 314 {"NAME":"hyleton-314","GPIO":[57,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Hyleton 315 {"NAME":"hyleton-315","GPIO":[0,0,0,0,57,56,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} Hyleton 317 {"NAME":"hyleton-317","GPIO":[56,0,57,0,58,0,0,0,0,90,0,21,0],"FLAG":0,"BASE":18} +Hyleton HLT-311 {"NAME":"HLT-311","GPIO":[56,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} iClever IC-BS08 {"NAME":"iClever BS08","GPIO":[0,0,0,0,157,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +iDIGITAL {"NAME":"Brilliant","GPIO":[0,0,0,0,52,0,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} Ihommate ZCH-02 {"NAME":"ZCH-02","GPIO":[0,0,0,17,133,132,0,0,130,56,21,0,0],"FLAG":1,"BASE":18} +Infray 16A {"NAME":"AWP08L","GPIO":[17,0,52,0,0,0,0,0,0,0,0,21,0],"FLAG":1,"BASE":18} iSwitch {"NAME":"Smart Plug XSA","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":0,"BASE":18} Jeeo TF-SH330 {"NAME":"Jeeo TF-SH330","GPIO":[56,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":1,"BASE":18} Jeeo TF-SH331W {"NAME":"Jeeo SH331W","GPIO":[56,0,158,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} @@ -576,9 +660,11 @@ Jinvoo SM-PW712UA 10A {"NAME":"SM-PW712UA","GPIO":[0,0,0,158,56,57,0,0,22,17, Jinvoo SM-PW762U {"NAME":"SM-PW762U","GPIO":[0,0,0,0,158,56,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} Jomarto SH1123 {"NAME":"SH1123","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Jules V (Upgrade Version) {"NAME":"Jules-V_UV","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57,131],"FLAG":0,"BASE":18} +JULES.V NX-SM200 V1.3 {"NAME":"NX-SM200","GPIO":[52,0,0,131,0,134,0,0,0,17,132,21,0],"FLAG":1,"BASE":45} Jules.V NX-SM300 {"NAME":"NX-SM300","GPIO":[52,0,0,0,0,130,0,0,21,132,133,52,0],"FLAG":0,"BASE":6} Jules.V NX-SP203 {"NAME":"NX-SP203","GPIO":[52,0,0,0,17,134,255,255,21,18,0,22,0],"FLAG":0,"BASE":18} JVMAC-EU01 {"NAME":"JVMAC","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +Kaforto KW-US-801 {"NAME":"Kaforto US-801","GPIO":[17,158,0,24,134,132,0,0,131,22,21,23,0],"FLAG":0,"BASE":18} Kimire S12 {"NAME":"Kimire S12","GPIO":[255,255,255,17,255,255,0,0,255,56,21,255,255],"FLAG":0,"BASE":18} King-Link KL-US-WF002 {"NAME":"Kinglink-plug","GPIO":[0,0,0,0,0,21,0,0,52,17,0,0,0],"FLAG":0,"BASE":18} Kisslink SP200 {"NAME":"Kisslink SP200","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":1,"BASE":18} @@ -590,20 +676,24 @@ Kogan Energy Meter & USB {"NAME":"KoganPOW","GPIO":[0,0,0,17,134,132,0,0,131,56 Koogeek KLSP1 {"NAME":"Koogeek-KLSP1","GPIO":[0,56,0,17,134,132,0,0,131,158,21,0,0],"FLAG":0,"BASE":18} Koogeek KLSP2 {"NAME":"KOOGEEK KLSP2","GPIO":[57,145,56,146,0,22,0,0,0,0,21,0,17],"FLAG":0,"BASE":45} Koogeek KLUP1 {"NAME":"Koogeek-KLUP1","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} +Koogeek KLWP1 {"NAME":"Koogeek-KLWP1","GPIO":[157,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":1} Koogeek W-DEXI {"NAME":"W-DEXI","GPIO":[0,90,0,0,134,132,0,0,130,52,21,0,0],"FLAG":0,"BASE":18} KULED K63 {"NAME":"KULED K63","GPIO":[0,0,0,0,21,17,0,0,56,0,0,0,0],"FLAG":0,"BASE":18} Laduo YX-DE01 {"NAME":"YX-DE01","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":0,"BASE":18} Lenovo SE-341A {"NAME":"Lenovo SE-341A","GPIO":[0,0,0,0,17,21,0,0,158,0,56,0,0],"FLAG":0,"BASE":18} LESHP KS-501 {"NAME":"LESHP KS-501","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} Loetad EU3S 16A {"NAME":"Loetad EU3S 16","GPIO":[0,255,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} +LogiLink PA0200 {"NAME":"LogilinkPA0200","GPIO":[0,0,0,90,0,0,0,0,0,56,21,0,0],"FLAG":7,"BASE":18} +Lohas Nightlight + USB {"NAME":"Lohas LED Mini Plug","GPIO":[0,57,0,52,58,23,255,255,21,17,22,0,157],"FLAG":0,"BASE":18} Lonsonho 10A Type E {"NAME":"Lonsonho10ALed","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} LoraTap SP400W-IT {"NAME":"LoraTap SP400W","GPIO":[0,0,0,0,157,56,0,0,21,17,0,0,0],"FLAG":15,"BASE":18} -LSC Smart Connect Power Plug {"NAME":"LSC Smart Plug","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +LSC Power {"NAME":"LSC Smart Plug","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Lumiman LM650 {"NAME":"Lumiman LM650","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Luminea NX-4491 {"NAME":"Luminea NX-449","GPIO":[56,0,158,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Luminea NX-4541 {"NAME":"NX-4451","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":55} Luminea ZX-2820 {"NAME":"ZX2820-675","GPIO":[0,0,0,17,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":65} Luminea ZX-2858 {"NAME":"Luminea SF-200","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +Martin Jerry V01 {"NAME":"MJ V01","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Martin Jerry XS-SSA01 {"NAME":"MJ_XS-SSA01","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Maxcio W-DE004 {"NAME":"Maxcio W-DE004","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":1,"BASE":18} Maxcio W-UK007 {"NAME":"Maxcio","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} @@ -616,11 +706,13 @@ MaxKare XKJJ-0218 {"NAME":"MaxKare XKJJ-0","GPIO":[0,0,0,0,18,133,0,0,21, Medion Life+ S85225 {"NAME":"Medion","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":52} Merkury MI-WW101-199 {"NAME":"merkury WW101","GPIO":[0,0,0,0,0,0,0,0,56,90,0,21,0],"FLAG":0,"BASE":18} Merkury MI-WW102-199L {"NAME":"MIC-WW102","GPIO":[17,0,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":36} -Merkury MI-WW105-199W {"NAME":"Merkury Switch","GPIO":[255,255,255,255,53,56,0,0,21,17,255,255,255],"FLAG":1,"BASE":18} +Merkury MI-WW105-199W {"NAME":"Merkury Switch","GPIO":[255,255,255,255,158,56,0,0,21,17,255,255,255],"FLAG":1,"BASE":18} Minleaf W-DEXI {"NAME":"W-DEXI","GPIO":[0,17,0,0,134,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} Mirabella Genio 1002341 {"NAME":"Genio 1","GPIO":[0,0,56,0,0,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} +Mirabella Genio USB {"NAME":"Mirabella Genio 1002826","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":1} Mistral {"NAME":"Mistral Smart ","GPIO":[56,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Moes NX-SP203 {"NAME":"Moes NX-SP203","GPIO":[52,0,0,0,17,134,0,0,21,18,0,22,0],"FLAG":0,"BASE":18} +Moes W-DE004S {"NAME":"Moes DE004S ","GPIO":[57,0,0,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} Moes WS-UEU {"NAME":"MoesHouse","GPIO":[0,0,0,21,17,0,0,0,57,0,0,0,0],"FLAG":0,"BASE":18} MoKo YX-WS01A {"NAME":"MoKo Plug","GPIO":[0,17,0,0,0,0,0,0,0,57,21,0,0],"FLAG":0,"BASE":18} Nanxin NX-SM400 {"NAME":"NX-SM400","GPIO":[0,0,0,17,134,132,0,0,130,52,21,0,0],"FLAG":0,"BASE":18} @@ -629,6 +721,7 @@ Nedis P110 {"NAME":"Nedis WIFIP110","GPIO":[17,0,0,0,134,132,0,0,1 Nedis P130 {"NAME":"WIFIP130FWT","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} NEO Coolcam NAS-WR01W {"NAME":"NAS-WR01W","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} NEO Coolcam NAS-WR01W 16A {"NAME":"Neo Coolcam 16","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} +NETVIP XS-SSA01 {"NAME":"XS-SSA01","GPIO":[0,0,0,0,0,0,0,0,56,17,0,21,0],"FLAG":0,"BASE":18} Nishica SM-PW701I {"NAME":"SM-PW701I","GPIO":[255,255,255,255,255,255,255,255,21,52,17,255,255],"FLAG":15,"BASE":18} NX-SM112 {"NAME":"NX-SM112v3","GPIO":[0,0,0,0,134,132,0,0,158,17,130,21,0],"FLAG":0,"BASE":45} NX-SM200 {"NAME":"NX-SM200","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57,131],"FLAG":0,"BASE":18} @@ -645,20 +738,26 @@ OxaOxe NX-SM200 {"NAME":"NX-SM200","GPIO":[17,0,0,0,133,132,0,0,131,158 Oxaoxe NX-SM800 {"NAME":"NX-SM800","GPIO":[0,0,0,131,0,134,0,0,21,17,132,0,0],"FLAG":0,"BASE":45} OxaOxe NX-SP202 {"NAME":"oxaoxe-dual","GPIO":[18,0,0,0,134,132,0,0,131,56,21,22,17],"FLAG":0,"BASE":18} OxaOxe NX-SP202 v2 {"NAME":"oxaoxe-dold","GPIO":[56,0,0,131,17,134,0,0,21,18,132,22,0],"FLAG":0,"BASE":18} +Panamalar Nightlight {"NAME":"Panamalar EWN0","GPIO":[17,0,0,0,0,0,255,255,37,0,0,21,0],"FLAG":0,"BASE":18} Panamalar NX-SM200 {"NAME":"NX-SM200","GPIO":[0,0,0,0,56,134,0,0,131,17,132,21,0],"FLAG":1,"BASE":18} Positivo PPW1000 {"NAME":"PPW1000","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} +Positivo Max {"NAME":"PPW1600","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":55} Powertech {"NAME":"Jaycar","GPIO":[56,0,0,0,0,0,0,0,0,9,0,21,0],"FLAG":0,"BASE":6} Powertech MS6104 {"NAME":"Jaycar MS6104","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":52} Powrui 3-Outlet with 4 USB {"NAME":"POWRUI AHR-077","GPIO":[0,0,0,20,19,18,0,0,22,23,17,21,157],"FLAG":0,"BASE":18} -Powrui AW-08 {"NAME":"POWRUI AW-08","GPIO":[0,0,0,0,9,21,0,0,0,52,57,0,0],"FLAG":1,"BASE":18} +Powrui AW-08 {"NAME":"POWRUI AW-08","GPIO":[0,0,0,0,17,21,0,0,0,52,57,0,0],"FLAG":1,"BASE":18} Premier PWIFPLG {"NAME":"Premier Plug","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":1,"BASE":18} Prime CCRCWFII113PK {"NAME":"Prime","GPIO":[0,0,0,0,57,56,0,0,21,122,0,0,0],"FLAG":0,"BASE":18} Prime RCWFII11 {"NAME":"Prime Plug","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} PrimeCables Cab-LA-WF4 {"NAME":"Mini Smart Outlet Wifi Socket with Timer Function","GPIO":[0,0,0,56,57,0,0,0,0,0,0,21,17],"FLAG":0,"BASE":18} +qnect 16A {"NAME":"QNECT QN-WP01E","GPIO":[0,0,0,17,133,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} RenPho RF-SM004 {"NAME":"RenPho RFSM004","GPIO":[0,0,0,0,157,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Robaxo {"NAME":"Robaxo RSP-025","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} RSH-WS007-EU {"NAME":"RSH-WS007","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":1,"BASE":18} +S126 {"NAME":"tuya-plug","GPIO":[0,0,0,0,0,0,0,0,21,20,0,0,0],"FLAG":0,"BASE":8} Shelly Plug S {"NAME":"Shelly Plug S","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":2,"BASE":45} Silvergear Slimme Stekker {"NAME":"Silvergear SmartHomePlug","GPIO":[0,0,0,122,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +SimpleHome {"NAME":"SimpleHome","GPIO":[53,0,0,0,0,0,0,0,21,56,17,0,0],"FLAG":0,"BASE":1} Slitinto NX-SM110 {"NAME":"Slitinto SM110","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} Slitinto NX-SM112 {"NAME":"NX-SM112","GPIO":[158,0,0,131,0,134,0,0,0,17,132,21,0],"FLAG":0,"BASE":45} Slitinto NX-SM112 v2 {"NAME":"Slitinto NX SM","GPIO":[56,255,158,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} @@ -684,7 +783,6 @@ Steren SHOME-100 {"NAME":"SHOME-100 V1.0","GPIO":[0,0,0,0,0,56,0,0,21,17 STITCH by Monoprice 27937 {"NAME":"Stitch 27937","GPIO":[17,0,56,0,133,132,0,0,131,0,21,0,57],"FLAG":0,"BASE":18} STITCH by Monoprice 35511 {"NAME":"Stitch 35511","GPIO":[56,0,57,0,0,133,0,0,0,17,132,21,131],"FLAG":0,"BASE":18} SuperNight Dual {"NAME":"SuperNight Dua","GPIO":[255,17,255,21,132,133,0,0,22,130,58,255,255],"FLAG":1,"BASE":18} -SWA1 {"NAME":"SWA1","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} SWA1 FR {"NAME":"SWA1","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} SWA1 UK {"NAME":"SWA1","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} SWA11 {"NAME":"SWA11","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} @@ -711,12 +809,15 @@ TomaxUSA HKWL-SO07W {"NAME":"HKWL-SO07W","GPIO":[17,255,255,255,255,255,0,0 Topersun WL-SC01 {"NAME":"Topersun ","GPIO":[0,0,0,0,52,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} TopGreener TGWF115APM {"NAME":"TGWF115APM","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":18} Torchstar LITEdge Smart {"NAME":"LITEdge Plug","GPIO":[0,17,0,0,0,0,0,0,0,52,21,0,0],"FLAG":0,"BASE":18} +TOVA Dual {"NAME":"TOVA","GPIO":[56,0,0,131,18,134,0,0,0,17,132,22,21],"FLAG":0,"BASE":45} TP20 {"NAME":"TP20","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} TP24 {"NAME":"TP24","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} U10 Series {"NAME":"WIFI-Socket","GPIO":[255,17,255,255,255,255,255,255,255,56,21,255,255],"FLAG":1,"BASE":18} Ultralink UL-P01W {"NAME":"UL-P01W","GPIO":[0,52,0,17,134,132,0,0,131,157,21,0,0],"FLAG":0,"BASE":18} +US212 {"NAME":"US212","GPIO":[56,0,0,131,0,134,0,0,21,17,132,22,0],"FLAG":0,"BASE":18} Varna Crafts 16A {"NAME":"VC Plug","GPIO":[157,0,0,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} Vaupan X6P {"NAME":"Vaupan 10a X6P","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} +Vettora Smart Plug {"NAME":"Vettora","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Vingo {"NAME":"Karpal-01","GPIO":[0,0,0,0,0,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Vivanco 39625 Smart Home Power Adapter {"NAME":"Vivianco","GPIO":[0,0,0,17,133,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} Vivitar HA-1003 {"NAME":"Vivitar HA1003","GPIO":[158,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} @@ -728,7 +829,7 @@ WAZA JH-G01B {"NAME":"Teckin SP27","GPIO":[255,255,255,255,53,255,0, WAZA JH-G01E 10A {"NAME":"Waza JH-G01E","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":1,"BASE":18} Waza JH-G01E 16A {"NAME":"Waza JH-G01E 2","GPIO":[0,0,0,0,0,0,0,0,17,52,21,0,0],"FLAG":1,"BASE":18} WiOn 50055 {"NAME":"WiOn","GPIO":[255,0,52,0,0,0,0,0,255,17,0,21,0],"FLAG":0,"BASE":17} -Wisdom ZY_ACU02 {"NAME":"ZY-ACU02","GPIO":[255,255,255,52,22,21,0,0,31,17,32,255,255],"FLAG":15,"BASE":18} +Wisdom ZY_ACU02 {"NAME":"ZY-ACU02","GPIO":[0,0,0,157,22,21,0,0,56,17,57,0,0],"FLAG":0,"BASE":18} WL-SC01 {"NAME":"WL-SC01","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":1} Woox R4026 {"NAME":"WOOX R4026","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Woox R4785 {"NAME":"WooxR4785","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} @@ -743,7 +844,7 @@ XS-A11 {"NAME":"THRUMM XS-A11","GPIO":[0,17,0,0,0,0,0,0,0,56,2 XS-A12 {"NAME":"XS-A12","GPIO":[37,0,39,0,38,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} XS-A14 {"NAME":"NETVIP XS-A14","GPIO":[37,0,38,0,0,17,0,0,39,21,0,0,0],"FLAG":0,"BASE":18} XS-A17 {"NAME":"XS-A18","GPIO":[37,0,38,0,0,39,0,0,0,17,0,21,0],"FLAG":0,"BASE":45} -XS-A18 {"NAME":"XS-A18","GPIO":[56,0,53,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":45} +XS-A18 {"NAME":"XS-A18","GPIO":[37,0,38,0,0,39,0,0,0,17,0,21,0],"FLAG":0,"BASE":45} XS-A23 {"NAME":"XS-A23","GPIO":[56,255,0,131,17,134,0,0,0,18,132,21,22],"FLAG":0,"BASE":45} XS-SSA01 {"NAME":"XS-SSA01","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":0,"BASE":18} XS-SSA01 v2 {"NAME":"XS-SSA01","GPIO":[255,17,255,255,255,255,0,0,56,255,255,21,255],"FLAG":0,"BASE":18} @@ -753,6 +854,7 @@ Yagala SWA9 {"NAME":"SWA9","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"F Yelomin JH-G01E {"NAME":"Yelomin","GPIO":[0,145,0,146,0,0,0,0,17,56,21,0,0],"FLAG":0,"BASE":18} YERON US101 {"NAME":"YERON_US101","GPIO":[255,255,255,17,133,132,0,0,131,56,21,255,255],"FLAG":0,"BASE":18} YM-WS-1 Mini {"NAME":"YM-WS1","GPIO":[0,0,0,0,0,0,0,0,56,17,0,21,0],"FLAG":0,"BASE":18} +YM-WS-3 16A {"NAME":"YM-WS-3","GPIO":[0,17,0,0,0,0,0,0,0,52,21,0,158],"FLAG":1,"BASE":18} YT-E003 {"NAME":"YT-E003-SP202","GPIO":[17,0,0,0,134,132,0,0,131,52,22,21,91],"FLAG":0,"BASE":64} Yuanguo KS-501 {"NAME":"Yuanguo_KS-501","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":18} YX-DE01 {"NAME":"YX-DE01","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} @@ -760,7 +862,7 @@ YX-WS02 {"NAME":"Amysen YX-WS02","GPIO":[255,17,255,255,255,255 ZBR-001 {"NAME":"ZBR-001","GPIO":[17,255,255,255,133,132,0,0,130,56,21,255,57],"FLAG":1,"BASE":18} ZooZee SA101 {"NAME":"ZooZee","GPIO":[57,255,56,255,255,255,0,0,255,17,255,21,255],"FLAG":0,"BASE":18} ZooZee SA102 {"NAME":"ZooZee","GPIO":[57,255,56,255,21,133,0,0,131,17,132,255,255],"FLAG":0,"BASE":18} -ZooZee SE131 {"NAME":"ZooZee SE131","GPIO":[255,0,56,0,0,0,0,0,255,17,0,21,0],"FLAG":0,"BASE":17} +ZooZee SE131 {"NAME":"ZOOZEE_SF131","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} ZSP-001 {"NAME":"ZSP-001","GPIO":[17,255,255,255,133,132,0,0,130,57,21,255,56],"FLAG":1,"BASE":18} ``` @@ -768,6 +870,8 @@ ZSP-001 {"NAME":"ZSP-001","GPIO":[17,255,255,255,133,132,0,0,13 ``` A0F0 ZLD-44EU-W {"NAME":"AOFO-4AC-4USB","GPIO":[0,56,0,17,22,21,0,0,23,24,33,0,0],"FLAG":1,"BASE":18} Acenx 3AC+3USB {"NAME":"ACENX 3-Outlet","GPIO":[56,55,54,53,0,21,0,0,23,24,22,0,17],"FLAG":0,"BASE":18} +AHRise 4+4AC+4USB {"NAME":"AHRise-083","GPIO":[0,0,0,0,52,17,0,0,22,21,23,24,0],"FLAG":0,"BASE":18} +AHRise AHR-085 {"NAME":"AHRise AHR-085","GPIO":[0,0,0,0,17,56,0,0,22,23,21,0,0],"FLAG":0,"BASE":18} Annhome 3AC + 2USB {"NAME":"1200W WiFi SPS","GPIO":[32,0,0,0,57,52,0,0,21,17,22,23,33],"FLAG":0,"BASE":18} AOFO 3AC+4USB {"NAME":"AOFO","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0,0],"FLAG":1,"BASE":18} AOFO 4AC+4USB {"NAME":"AOFO4AC4USB","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":0,"BASE":18} @@ -779,23 +883,28 @@ Arlec Smart PB89HA {"NAME":"Arlec PB89HA","GPIO":[0,56,0,17,22,21,0,0,24,2 Bauhn ASPBU-1019 {"NAME":"Bauhn 3AC+3USB","GPIO":[0,157,0,0,22,21,0,0,0,23,17,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-SHP9 {"NAME":"BlitzWolf SHP9","GPIO":[158,255,0,255,0,23,0,0,21,17,22,24,0],"FLAG":0,"BASE":45} BrilliantSmart 20691 Powerboard with USB Chargers {"NAME":"B_WiFi-4","GPIO":[56,0,0,57,29,17,0,0,31,30,32,0,25],"FLAG":1,"BASE":18} -CE Smart Home LTS-6A-W5 {"NAME":"CE Power Strip","GPIO":[52,0,0,0,22,21,0,0,24,23,25,26,17],"FLAG":0,"BASE":18} -CE Smart Home Garden Stake LH-7-1 {"NAME":"CE Power Stake","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +CE Smart Home {"NAME":"CE Power Strip","GPIO":[52,0,0,0,22,21,0,0,24,23,25,26,17],"FLAG":0,"BASE":18} +CE Smart Home Garden Stake {"NAME":"CE Power Stake","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} CRST LTS-4G-W {"NAME":"CRST LTS-4G-W","GPIO":[0,0,0,0,24,0,0,0,22,23,21,0,0],"FLAG":0,"BASE":18} Deltaco SH-P03USB {"NAME":"Deltaco SH-P03","GPIO":[0,56,0,0,0,21,0,0,23,17,22,24,0],"FLAG":1,"BASE":18} Digoo DG-PS01 {"NAME":"Digoo DG-PS01","GPIO":[0,56,0,17,23,22,0,0,0,24,21,0,0],"FLAG":1,"BASE":18} -Geekbes 4AC+4USB {"NAME":"Geekbes 4xStri","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":1,"BASE":18} +Geekbes 4AC+4USB {"NAME":"Geekbes 4xStri","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":1,"BASE":18} Geeni Surge {"NAME":"Geeni GNCSW003","GPIO":[52,0,0,0,22,21,0,0,24,25,23,26,17],"FLAG":0,"BASE":18} +Geeni SURGE 6-Outlet Surge Protector {"NAME":"Geeni 6 Strip","GPIO":[56,0,0,0,22,21,0,0,24,25,23,26,0],"FLAG":0,"BASE":18} Geeni Surge Mini {"NAME":"Geeni-GN-SW004","GPIO":[56,0,0,17,0,0,0,0,22,21,23,0,0],"FLAG":15,"BASE":18} Gosund P1 {"NAME":"Gosund_P1","GPIO":[0,145,157,146,0,32,0,0,22,23,21,0,17],"FLAG":1,"BASE":18} Gousund WP9 {"NAME":"Gosund WP9","GPIO":[56,55,54,53,0,21,0,0,23,24,22,0,17],"FLAG":0,"BASE":18} +Heyvalue 3AC+3USB {"NAME":"HeyvalueHLT-330","GPIO":[52,0,53,0,24,29,0,0,30,20,31,0,0],"FLAG":0,"BASE":18} +Heyvalue 4AC+4USB {"NAME":"Heyvalue HLT-331","GPIO":[56,0,57,0,25,22,0,0,24,9,23,21,0],"FLAG":0,"BASE":18} HIPER IoT PS44 {"NAME":"HIPER IoT PS44","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":0,"BASE":18} +HLT-333 {"NAME":"BEYAWL","GPIO":[0,0,56,24,0,0,0,0,0,30,29,31,0],"FLAG":0,"BASE":18} Hyleton 330 {"NAME":"Hyleton-330","GPIO":[57,0,0,56,29,17,0,0,31,30,32,0,25],"FLAG":0,"BASE":18} Hyleton 331 {"NAME":"HLT-331","GPIO":[52,255,255,57,29,17,0,0,31,30,32,255,58],"FLAG":0,"BASE":18} Hyleton 333 {"NAME":"HLT-333","GPIO":[52,0,0,57,29,17,0,0,31,30,0,0,24],"FLAG":0,"BASE":18} Hyleton 336 {"NAME":"HLT-336","GPIO":[52,0,0,57,29,17,0,0,31,30,0,0,32],"FLAG":0,"BASE":18} KMC 5 {"NAME":"KMC 5-Outlet","GPIO":[56,0,0,0,25,9,0,0,22,21,23,0,24],"FLAG":0,"BASE":18} Kogan Power Strip USB Ports & Energy Meter {"NAME":"Generic","GPIO":[90,56,0,24,134,132,0,0,131,22,23,21,0],"FLAG":0,"BASE":18} +Konesky Type 1 {"NAME":"Konesky","GPIO":[0,0,0,0,25,22,0,0,24,17,23,21,0],"FLAG":0,"BASE":18} Koogeek KLOE4 {"NAME":"Koogeek KLOE4","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":1,"BASE":18} LeFun SK2 {"NAME":"LeFun SK2","GPIO":[0,0,0,17,22,21,0,0,23,24,25,0,0],"FLAG":0,"BASE":18} Luminea 3AC+4USB 16A {"NAME":"Luminea-NX4473","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0,0],"FLAG":0,"BASE":18} @@ -804,6 +913,7 @@ Meross MSS425 {"NAME":"Meross MSS425","GPIO":[33,0,0,0,56,0,0,0,21,17 Mirabella Genio 4 Outlet Power Board with 2 USB {"NAME":"Genio i002340","GPIO":[56,0,0,0,21,22,0,0,23,17,24,25,0],"FLAG":0,"BASE":18} Mirabella Genio Powerboard I002578 {"NAME":"Genio Powerboa","GPIO":[21,52,0,0,23,22,0,0,25,17,26,24,0],"FLAG":0,"BASE":18} Nedis P310 {"NAME":"Nedis WIFIP310","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0,0],"FLAG":1,"BASE":18} +Nozdom 3AC+2USB {"NAME":"NOZDOM SWB3","GPIO":[157,0,53,0,0,23,0,0,21,17,22,24,0],"FLAG":0,"BASE":18} Powrui AHR-079 {"NAME":"Powrui Power S","GPIO":[56,0,0,17,19,21,0,0,23,20,22,24,18],"FLAG":0,"BASE":18} Powrui AW-39 {"NAME":"Powrui AW-39","GPIO":[56,0,0,0,21,255,0,0,23,24,22,0,9],"FLAG":0,"BASE":18} S2199EU {"NAME":"S2199EU","GPIO":[0,17,0,52,23,25,0,0,21,24,22,0,0],"FLAG":1,"BASE":18} @@ -816,9 +926,10 @@ Tellur TLL331031 {"NAME":"Tellur","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0, Tessan A4L-BK {"NAME":"TESSAN A4L-BK","GPIO":[0,0,0,24,23,0,0,0,21,0,22,0,0],"FLAG":0,"BASE":18} Tonbux SM-SO301-U {"NAME":"Tonbux SM-SO30","GPIO":[56,0,0,0,29,0,0,0,31,30,32,0,25],"FLAG":0,"BASE":18} Useelink SM-SO301AU {"NAME":"Useelink","GPIO":[56,0,0,0,29,0,0,0,31,30,32,0,25],"FLAG":0,"BASE":18} -Vivitar HA-1007 {"NAME":"Vivitar HA1007","GPIO":[56,0,0,0,30,17,0,0,32,31,33,0,21],"FLAG":15,"BASE":18} +Vivitar HA-1007 {"NAME":"Vivitar HA-1007 Power Strip","GPIO":[157,0,0,0,24,25,0,0,22,21,23,0,20],"FLAG":15,"BASE":18} Vivitar HA-1007-AU {"NAME":"HA-1007-AU","GPIO":[56,17,0,58,29,57,0,0,31,30,32,0,25],"FLAG":0,"BASE":18} wesmartify essentials 4AC+4USB {"NAME":"essential_4_po","GPIO":[56,0,0,0,24,25,0,0,22,21,23,0,17],"FLAG":0,"BASE":18} +Wipro Smart Extension {"NAME":"Generic","GPIO":[57,0,0,0,32,0,0,0,30,31,29,0,25],"FLAG":0,"BASE":18} Woox R4028 {"NAME":"Woox R4028","GPIO":[0,56,0,17,23,22,0,0,0,24,21,0,0],"FLAG":1,"BASE":18} Xenon SM-S0301 {"NAME":"SM-SO301","GPIO":[52,255,255,57,29,17,0,0,31,30,32,255,25],"FLAG":0,"BASE":18} Xenon SM-S0301-U {"NAME":"SM-SO301-U","GPIO":[52,255,255,57,29,17,0,0,31,30,32,255,25],"FLAG":0,"BASE":18} @@ -871,7 +982,8 @@ B.K.Licht BKL1253 9W 806lm {"NAME":"BKL1253","GPIO":[0,0,0,0,38,37,0,0,41,39,40 Bakibo TB95 9W 1000lm {"NAME":"Bakibo A19 9W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} BAZZ BR30 650lm {"NAME":"BAZZrgb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} BlitzWolf BW-LT27 w/ remote 850lm {"NAME":"BW-LT27","GPIO":[0,0,0,0,41,38,0,0,39,51,40,37,0],"FLAG":0,"BASE":18} -BNeta IO-WIFI60-E27P 800lm {"NAME":"OM60/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +BNETA 8.5W 800lm {"NAME":"BNETA IO-WIFI60-E27P","GPIO":[0,0,0,0,37,40,0,0,38,50,39,0,0],"FLAG":0,"BASE":18} +BNETA 8.5W 800lm {"NAME":"OM60/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} Bomcosy 600lm {"NAME":"Generic","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} Calex 429002 Reflector 350lm {"NAME":"Calex RGBW","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} Calex 429004 A60 806lm {"NAME":"Calex E27 RGB ","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} @@ -890,16 +1002,24 @@ Feit Electric A19 800lm {"NAME":"FE-OM60-15K-AG","GPIO":[0,0,0,0,141,140,0,0,37 Feit Electric A19 800lm {"NAME":"OM60/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} Fitop 9W {"NAME":"E27RGBCCT9w","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":15,"BASE":18} Fulighture 9W 810lm {"NAME":"Fulighture 9W","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Geeni Prisma 10W 1050lm {"NAME":"Geeni Prisma 1050 RGB","GPIO":[0,0,0,0,141,140,0,37,38,142,0,0,0],"FLAG":0,"BASE":18} Geeni Prisma Plus 800lm {"NAME":"Geeni Prisma P","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Globe 34207 800lm {"NAME":"GlobeRGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Generic GU10 5W 460lm {"NAME":"RGBCCT GU10","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Globe A19 10W 800lm {"NAME":"GlobeRGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Helloify BR30 9W 600lm {"NAME":"Helloify","GPIO":[255,255,255,255,37,40,255,255,38,41,39,255,255],"FLAG":0,"BASE":18} HIPER IoT A61 {"NAME":"HIPER IoT A61","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +HIPER IoT C1 {"NAME":"Hiper IoT C1 RGB","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} Infray 9W 900LM {"NAME":"InfrayRGBCCT","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Jeeo TF-QPZ13 800lm {"NAME":"Jeeo","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} Julun JL-021 5W Candle {"NAME":"E14 RGBCCT","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} Kogan 10W 1050lm {"NAME":"Kogan RGB+CCT","GPIO":[255,255,255,0,37,40,255,255,38,50,39,255,255],"FLAG":15,"BASE":18} Kohree 600lm {"NAME":"Kohree VHP560","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} +Lasco 9W 700lm {"NAME":"Lasco 7W","GPIO":[0,0,0,0,140,37,0,0,0,0,141,0,0],"FLAG":0,"BASE":1} +Laser 10W 1000lm {"NAME":"LSH-E27RGB10W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Laser 5W 460lm {"NAME":"LSH-E14RGB5W","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} LE lampUX 8.5W 806lm {"NAME":"lampUX","GPIO":[0,0,0,0,141,140,0,0,38,142,37,0,0],"FLAG":15,"BASE":18} LE lampUX A19 850lm {"NAME":"LE RGBWW 60W","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":1,"BASE":18} +LE lampUX A19 9.5W 806lm {"NAME":"LE lampUX 9W Bulb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} LE lampUX A19 9W 806lm {"NAME":"lampUX","GPIO":[0,0,0,0,141,140,0,0,38,142,37,0,0],"FLAG":15,"BASE":18} Ledmundo 6W 600lm {"NAME":"LEDMUNDO 6W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Legelite 5W Candle {"NAME":"Legelite E12","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} @@ -908,21 +1028,34 @@ Legelite A60 7W 600lm {"NAME":"Legelite E26","GPIO":[0,0,0,0,37,40,0,0,38,41, Lohas ZN011 5W 420lm {"NAME":"LohasZN011","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Lohas ZN014-2 5W 380lm {"NAME":"Lohas ZN014-2","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Lohas ZN031 650lm {"NAME":"Lohas ZN031","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Lohas ZN033 810lm {"NAME":"Lohas RGBWW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Lohas ZN033 9W 810lm {"NAME":"Lohas RGBWW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Lohas ZN033 9W 810lm {"NAME":"Lohas RGBCW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Lohas ZN036 900 lm {"NAME":"Lohas RGBCCT","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Lohas ZN037 450lm {"NAME":"Lohas LH-ZN037","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":20} +Lohas ZN038 BR20 8W 750lm {"NAME":"Lohas LH-ZN038","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Lohas ZN039 BR40 1450lm {"NAME":"Lohas ZN039","GPIO":[0,0,0,0,39,37,0,0,41,38,40,0,0],"FLAG":0,"BASE":18} +Longlifelamps A60 9W {"NAME":"longlifelamps A60 RGBWW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} Lumary 9W 800lm {"NAME":"Lumary / iLint","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Luminea 5.5W 470lm {"NAME":"Luminea ZX-2983","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} LVWIT A60 8.5W 806lm {"NAME":"LVWIT A60 8.5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -LVWIT A70 12W 1521lm {"NAME":"LVWIT A70 12W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +LVWIT A70 12W 1521lm {"NAME":"LVWIT A70 12W","GPIO":[0,0,0,0,37,40,0,0,38,50,39,0,0],"FLAG":0,"BASE":18} +LVWIT BR30 8.5W 650lm {"NAME":"LVWIT BR30 8.5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +LVWIT G45 5W 470Lm {"NAME":"LVWIT E14 5W G45 RGBWCCT","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +MagicHome 7W {"NAME":"MagicHome E27","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Nishica JBT 9W 806lm {"NAME":"Nishica","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Novostella HM-LB09 13W 1300lm {"NAME":"Novostella 13W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Novostella NTB10 9W 900lm {"NAME":"NTB10","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} Novostella UT55505 7W 600lm {"NAME":"Novostella B22","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} +Novostella UT55507 9W 900lm {"NAME":"Novostella UT55507","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Novostella UT55507 9W 900lm {"NAME":"Novostella UT55507","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Novostella UT55508 12W 1150lm {"NAME":"Novostella","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Novostella UT55509 13W 1300lm {"NAME":"Novostella 13W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Ohlux 5W 450lm Candle {"NAME":"OHLUX","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Ohlux A19 7W 600lm {"NAME":"OHLUX","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Ohlux BR30 10W 900lm {"NAME":"OHLUX","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} oobest 7W {"NAME":"E27_RGBCW_Bulb","GPIO":[0,0,0,0,38,37,0,0,40,41,39,0,0],"FLAG":0,"BASE":18} +PETEME 7.5W 750lm {"NAME":"PETEME","GPIO":[255,255,0,255,37,40,0,0,38,41,39,255,255],"FLAG":7,"BASE":18} +Polux A65 11W 1055lm {"NAME":"A65 SMDWWCW+RG","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Positivo 10W 806lm {"NAME":"Positivo Bulb","GPIO":[0,0,0,0,37,40,0,0,38,50,39,0,0],"FLAG":0,"BASE":18} Powertech SL225X 800lm {"NAME":"Jaycar SL225X","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Qualitel ALS08L 1100lm {"NAME":"Qualitel ALS08","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} @@ -936,12 +1069,17 @@ Sonoff B1 (R2) {"NAME":"Sonoff B1","GPIO":[17,0,0,0,0,0,0,0,143,0,144, Spectrum Smart GLS 9W 850lm {"NAME":"SPECTR. RGBCCT","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} Sunco G25 5W 450lm {"NAME":"Sunco G25","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Sunco PAR20 5W 400lm {"NAME":"Sunco PAR20","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Sunco PAR38 13W 1050lm {"NAME":"Sunco PAR38 RGBCCT","GPIO":[0,0,0,0,38,37,0,0,40,39,41,0,0],"FLAG":0,"BASE":18} +Techlux A19 9W 806lm {"NAME":"TECHLUX A19 RGBCW 806lm 9w","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Teckin SB50 v3 A19 800lm {"NAME":"Teckin SB50v3","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Teckin SB53 1300lm {"NAME":"Teckin SB53","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -V-Tac PAR16 4.5W 400lm 100° {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +Treatlife A19 8W 650lm {"NAME":"Treatlife RGBW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +V-Tac PAR16 4.5W 400lm {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} Vizia 5W GU10 {"NAME":"Vizia RGBWW","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":15,"BASE":18} Wipro Garnet 9W 810lm {"NAME":"Wipro","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Zemismart 5W 480lm {"NAME":"Zemismart 5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Zemismart 5W 480lm {"NAME":"Zemismart-E27-RGBCW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Zemismart 5W 480lm {"NAME":"Zemismart-E27-RGBCW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} ZZHXON 600lm {"NAME":"E27_RGB_Bulb","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} ``` @@ -957,11 +1095,10 @@ Aoycocr Q9WM A21 10W 900lm {"NAME":"Aoycocr Q9WM","GPIO":[0,0,0,0,0,39,0,0,38,4 Avatar ALS08L A19 910lm {"NAME":"Avatar E27 7W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} Avatar ALS09L A60 900lm {"NAME":"Avatar E14 9W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} Avatar ALS11L PAR16 500lm {"NAME":"Avatar_GU10","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} -AWOW A60 9W 800lm {"NAME":"AWOW 9W RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Axtee AI-003 A19 700lm {"NAME":"Axtee E26 7W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} Bawoo EUWL122130 925lm {"NAME":"Bawoo","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-LT21 900lm {"NAME":"BlitzWolf LT21","GPIO":[0,0,0,0,41,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} -BNeta IO-WIFI-GU10 380lm {"NAME":"BNeta","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} +BNeta 4.5W 380lm {"NAME":"BNeta","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} BriHome 6,5W 500lm {"NAME":"BRI E27 6,5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} Brilliant HK17653S72 350lm {"NAME":"HK17653S72","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} BrilliantSmart 20698 9W 800lm {"NAME":"Brilliant20698","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} @@ -973,9 +1110,12 @@ BrizLabs Candle 4,5W 350lm {"NAME":"BrizLabs RGBW","GPIO":[0,0,0,0,37,40,0,0,38 Brizlabs EBE-LZW10 350Lm {"NAME":"Brizlabs E14","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":15,"BASE":18} BrizLabs EBE-SHW03 380lm {"NAME":"BrizLabs","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} BTZ1 {"NAME":"WifiBulb","GPIO":[0,0,0,0,0,37,0,0,39,40,38,0,0],"FLAG":0,"BASE":18} +Cleverio 4.5W 350lm {"NAME":"HK17653S72","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Cleverio 51398 370lm {"NAME":"CleverioGU10","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} Cocoon DY180363-B 800lm {"NAME":"Cocoon RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Connect SmartHome 5W {"NAME":"Connect CSH-E1","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} Connex Connect A60 6W 470lm {"NAME":"Connex RGBW Bu","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Elari A60 6W 470lm {"NAME":"OM60/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} electriQ 600lm {"NAME":"ElectricQ B22","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} EleLight 350lm {"NAME":"EleLight 7wA19","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} Esicoo 810lm {"NAME":"Esicoo Bulb","GPIO":[0,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} @@ -986,9 +1126,8 @@ Fcmila Spotlight 460lm {"NAME":"Fcmila LED 6W","GPIO":[0,0,0,0,40,0,0,0,38,39, Feit Electric BR30 650lm {"NAME":"BR30/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} Feit Electric BR30 700lm {"NAME":"Feit BR30/RGBW","GPIO":[0,0,0,38,141,140,0,0,0,142,37,0,0],"FLAG":0,"BASE":18} Fulighture A60 810lm {"NAME":"Fulighture A60","GPIO":[0,0,0,0,38,37,0,0,0,39,40,0,0],"FLAG":0,"BASE":18} -Geeni Prisma 1050lm {"NAME":"Geeni 1050 RGB","GPIO":[37,0,0,0,140,38,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} -Generic 10W {"NAME":"10W E27 RGBW","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} Generic GU10 5W 450lm {"NAME":"RGBCW GU10","GPIO":[0,255,0,255,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":3} +Gosund 8W 800lm {"NAME":"Gosund RGBW 8W","GPIO":[0,0,0,0,41,40,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} Gosund WB3 8W 800lm {"NAME":"Gosund WB3","GPIO":[0,0,0,0,40,0,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} Hama 10W 1050lm {"NAME":"Hama Bulb RGBW","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} Hama 10W 806lm {"NAME":"Hama Smart WiF","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} @@ -996,14 +1135,16 @@ Hama 4.5W {"NAME":"hama E14 RGB","GPIO":[0,0,0,0,37,40,0,0,38,0,3 Hiiten A19 7W 650lm {"NAME":"Hiiten Bulb","GPIO":[37,0,0,0,140,38,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} Hykker SL-0492 810lm {"NAME":"Hykker RBGW 9W","GPIO":[0,0,0,0,0,40,0,0,37,0,39,38,0],"FLAG":0,"BASE":18} Kainsy 600lm {"NAME":"KAINSY","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} +Kkmoon 9W 800lm {"NAME":"KKMOON V21","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} Koaanw 650lm {"NAME":"KOAANW Bulb","GPIO":[0,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} Kogan 10W Ambient 1050lm {"NAME":"Kogan RGB","GPIO":[0,0,0,0,140,37,0,0,0,0,141,0,0],"FLAG":0,"BASE":18} +Kogan 4.5W 330lm 110� {"NAME":"Kogan_GU10","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":0,"BASE":18} Kogan Ambient Candle {"NAME":"Kogan_E14","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Kogan Ambient Spotlight 330lm {"NAME":"Kogan_GU10","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":0,"BASE":18} Kuled 800lm {"NAME":"KULED 60W RGB","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":1,"BASE":18} Laideyi 7W {"NAME":"7W-E14-RGBW-La","GPIO":[0,0,0,0,38,37,0,0,39,0,40,0,0],"FLAG":0,"BASE":18} -LE lampUX A19 9.5W 806lm {"NAME":"LE lampUX 9W Bulb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} LeCardio 10W 980lm {"NAME":"LeCardio RGBW","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +LEDLite 10W 800lm {"NAME":"LEDLite","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Linganzh LE7 6W 600lm {"NAME":"Linganzh LE7","GPIO":[0,0,0,0,0,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} Linganzh LWE3 7W 800lm {"NAME":"LINGANZH Smart ","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} LiteMate A90 810lm {"NAME":"LiteMate 9W","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} LOFTer 7W 450lm {"NAME":"Lofter","GPIO":[0,255,255,255,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} @@ -1013,8 +1154,9 @@ Lohas ZN005 420lm {"NAME":"Lohas E14 R50","GPIO":[17,0,0,0,0,0,0,0,0,143, Lohas ZN006 1380lm {"NAME":"Lohas100 RGBW","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":18} Lohas ZN012 450lm {"NAME":"LH-5W-ZN01204","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} Lonsonho 900lm {"NAME":"RGB+W+C Bulb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect C45 400lm {"NAME":"LSC RGBCW E14","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect MR16 380lm {"NAME":"LSC RGBCW GU10","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +LSC C45 400lm {"NAME":"LSC RGBCW E14","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +LSC MR16 380lm {"NAME":"LSC RGBCW GU10","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +LTC 10W {"NAME":"LTC LXU403","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} Lumiman LM530 7.5W 800lm {"NAME":"Lumiman LM530","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} Lumiman LM530 7.5W 800lm {"NAME":"Lumiman LM530","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} Lumiman LM530 7.5W 800lm {"NAME":"LM530","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} @@ -1024,21 +1166,22 @@ LWE3 600lm {"NAME":"Linganzh LWE3 ","GPIO":[0,0,0,0,0,38,0,0,39,0, MagicLight 4.5W 350lm {"NAME":"4.5W RGBW Bulb","GPIO":[0,0,0,0,0,37,0,0,39,40,38,0,0],"FLAG":0,"BASE":18} Manzoku XS-001 1050lm {"NAME":"Manzoku RGBW","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} Maxcio YX-L01P-E27-2P 9W {"NAME":"Maxcio YXL01P","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} +Melery 5W {"NAME":"MeleryMR16","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} Merkury 75W 1050lm {"NAME":"MIC-BW904-999W","GPIO":[38,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} -Merkury A21 10W 1050lm {"NAME":"MI-BW210-999W","GPIO":[0,0,0,0,140,37,0,0,142,38,141,0,0],"FLAG":0,"BASE":48} -Merkury A21 10W 1050lm {"NAME":"MI-BW210-999W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Merkury A21 10W 1050lm {"NAME":"MI-BW210-999W","GPIO":[38,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":69} Merkury MI-BW904-999W 1050lm {"NAME":"MI-BW904-999W","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} Merkury MI-BW904-999W v2 1050lm {"NAME":"MI-BW210-999W","GPIO":[0,0,0,0,38,37,0,0,141,142,140,0,0],"FLAG":0,"BASE":48} Merkury MI-BW904-999W v3 {"NAME":"MI-BW904-999W","GPIO":[0,0,0,0,37,38,0,0,141,142,140,0,0],"FLAG":0,"BASE":69} Merkury MI-BW906-999W BR30 750lm {"NAME":"MI-BW906-999W","GPIO":[0,0,0,0,38,37,0,0,141,142,140,0,0],"FLAG":0,"BASE":18} -Mirabella Genio 9W 800lm {"NAME":"GenioBulbRGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":1,"BASE":18} -Mirabella Genio 9W 800lm {"NAME":"GenioBulbRGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":1,"BASE":18} +Mirabella Genio 9W 800lm {"NAME":"GenioBulbRGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Mirabella Genio 9W 800lm {"NAME":"GenioBulbRGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Mirabella Genio 9W 800lm {"NAME":"MiraBellaGenio","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} Mixigoo 950lm {"NAME":"Mixigoo Bulb","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} MoKo GU10 {"NAME":"MoKo GU10","GPIO":[255,255,255,255,39,255,255,255,38,41,37,40,255],"FLAG":15,"BASE":18} MoKo JL81 5W 400lm {"NAME":"MoKo E14","GPIO":[0,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":27} MOKO YX-L01C-E14 A60 810lm {"NAME":"MOKO","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} Nedis 4.5W 380lm {"NAME":"Nedis RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Nedis 6W 470lm {"NAME":"nedis Bulb","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Nedis A60 800lm {"NAME":"Nedis RGBW","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":1,"BASE":18} Nedis C10 350lm {"NAME":"Nedis WIFILC10","GPIO":[0,0,0,0,39,37,0,0,40,38,41,0,0],"FLAG":1,"BASE":18} Nedis PAR16 330lm {"NAME":"Nedis GU10","GPIO":[0,0,0,0,39,37,0,0,40,38,41,0,0],"FLAG":0,"BASE":18} @@ -1046,13 +1189,15 @@ NiteBird TT-WB4 800lm {"NAME":"NiteBird TT-WB","GPIO":[0,0,0,0,40,0,0,0,37,38 Novostella UT55506 10W 1050lm {"NAME":"Novostella 10W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Onforu 7W 700lm {"NAME":"Onforu RGBW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Orbecco 5W 400lm {"NAME":"Orbecco Bulb","GPIO":[0,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":27} +Positivo 4.5W 350lm {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} Premier A19 10W {"NAME":"Premier Light","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":1,"BASE":18} Riversong Juno 10W {"NAME":"Juno10","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} Rogoei EBE-QPZ04 6.5W 450lm {"NAME":"EBE-QPZ04","GPIO":[0,0,0,0,180,0,0,0,0,0,181,0,0],"FLAG":0,"BASE":18} +Saudio 7W 700lm {"NAME":"X002BU0DOL","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Smart 810lm {"NAME":"OOOLED 60W RGB","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":1,"BASE":18} SmartLED 9W 400lm {"NAME":"SmartLED RGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Smartyfi 600lm {"NAME":"SMARTYFI 9W","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Solimo 12W {"NAME":"Solimo RGBWW12","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Solimo 12W {"NAME":"Solimo RGBCCT 12","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} Solimo 810lm {"NAME":"Solimo RGBWW 9","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Swisstone SH 320 350lm {"NAME":"SH 320","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Swisstone SH 340 806lm {"NAME":"SH 340","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":15,"BASE":18} @@ -1067,6 +1212,7 @@ Utorch LE7 600lm {"NAME":"Utorch LE7","GPIO":[0,0,0,0,0,38,0,0,39,0,40,3 V-Tac A60 11W 1055lm {"NAME":"V-TAC LED A60 ","GPIO":[0,0,0,0,180,0,0,0,0,0,181,0,0],"FLAG":0,"BASE":18} V-TAC A95 18W 1350lm {"NAME":"V-TAC VT-5021","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} Wallfire WF-05 {"NAME":"Wallfire E27","GPIO":[17,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +Wixann C37 5W 450lm {"NAME":"WIXANNE12","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Woopower 460lm {"NAME":"Woopower E14","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} WOOX R4553 650lm {"NAME":"WOOX R4553","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} WOOX R5076 4W 350lm {"NAME":"WOOX R4553","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} @@ -1079,6 +1225,8 @@ Zilotek A19 800lm {"NAME":"Zilotek RGBW","GPIO":[0,0,0,0,140,37,0,0,38,14 ## Relay ``` 1 Channel Inching/Self-Locking {"NAME":"1 Channel","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":12} +Anmbest 2 Channel Inching Self-locking Switch Module {"NAME":"Generic","GPIO":[17,255,255,255,255,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":1} +ATMS1601 230VAC DIN Timer/Switch {"NAME":"ATMS1601","GPIO":[255,255,255,255,157,56,255,255,21,17,255,255,255],"FLAG":15,"BASE":18} BlitzWolf BW-SS1 {"NAME":"BW-SS1","GPIO":[255,255,255,255,157,21,0,0,255,17,255,255,0],"FLAG":0,"BASE":18} BlitzWolf BW-SS5 2 Gang {"NAME":"BlitzWolf SS5 2 Gang","GPIO":[0,0,0,0,160,0,0,0,43,42,21,22,0],"FLAG":0,"BASE":18} BlitzWolf SS4 Two Gang {"NAME":"BlitzWolf SS4","GPIO":[0,0,0,0,56,21,0,0,22,17,0,0,0],"FLAG":0,"BASE":18} @@ -1091,6 +1239,7 @@ Eachen ST-DC2 {"NAME":"Garage Control","GPIO":[11,0,0,0,23,22,18,0,21 Eachen ST-UDC1 {"NAME":"ST-UDC1","GPIO":[9,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":1,"BASE":18} Electrodragon Board SPDT {"NAME":"ED Relay Board","GPIO":[255,255,255,255,255,255,0,0,21,22,255,255,52],"FLAG":1,"BASE":18} Electrodragon ESP8266 {"NAME":"ElectroDragon","GPIO":[18,255,17,255,255,255,0,0,22,21,255,255,52],"FLAG":1,"BASE":15} +eMylo 2 Channel {"NAME":"eMylo XL9252WI","GPIO":[0,255,0,0,56,22,0,0,21,0,12,0,0],"FLAG":0,"BASE":18} eMylo SS-8839-02 {"NAME":"SS-8839-02","GPIO":[0,255,0,255,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} eMylo SS-8839-03 {"NAME":"SS-8839-03","GPIO":[0,255,0,255,52,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} ESP-01 Relay V4.0 {"NAME":"ESP01v4","GPIO":[29,52,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} @@ -1113,23 +1262,26 @@ LinkNode R4 {"NAME":"LinkNode R4","GPIO":[0,0,0,0,0,0,0,0,21,22,23, LinkNode R8 {"NAME":"LinkNode R8","GPIO":[0,0,0,0,25,26,0,28,23,24,22,27,21],"FLAG":0,"BASE":18} LoraTap 10A {"NAME":"LoraTap RR400W","GPIO":[0,0,0,0,157,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} LoraTap RR500W {"NAME":"LoraTap RR500W","GPIO":[157,255,255,255,9,255,255,255,255,21,255,255,56],"FLAG":15,"BASE":18} -LoraTap SC500W Roller Shutter {"NAME":"SC500W","GPIO":[0,0,0,158,9,10,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} Mhcozy 5V {"NAME":"Portail","GPIO":[9,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":1,"BASE":18} Moes MS-104B-1 {"NAME":"Moes MS-104B","GPIO":[0,0,17,0,160,0,0,0,43,42,21,22,0],"FLAG":0,"BASE":18} Nova Digital Basic 1 MS101 {"NAME":"NovaDigBasic1","GPIO":[0,255,0,255,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} OpenEnergyMonitor WiFi MQTT Thermostat {"NAME":"MQTT-RELAY","GPIO":[17,0,255,0,0,21,0,0,0,0,0,0,56],"FLAG":0,"BASE":18} Protium PS-1604 {"NAME":"Protium16A","GPIO":[17,255,255,255,255,0,0,0,21,56,255,0,0],"FLAG":0,"BASE":1} QS-WIFI-S03 Module Switch {"NAME":"QS-WIFI-S03","GPIO":[17,255,255,255,255,0,0,0,82,21,0,0,0],"FLAG":0,"BASE":1} +QS-WIFI-S05 {"NAME":"QS-WIFI-S05","GPIO":[17,255,255,255,255,0,0,0,82,21,0,0,0],"FLAG":0,"BASE":1} Shelly 1 {"NAME":"Shelly 1","GPIO":[0,0,0,0,21,82,0,0,0,0,0,0,0],"FLAG":0,"BASE":46} Shelly 1PM {"NAME":"Shelly 1PM","GPIO":[56,0,0,0,82,134,0,0,0,0,0,21,0],"FLAG":2,"BASE":18} Shelly 2 {"NAME":"Shelly 2","GPIO":[0,135,0,136,21,22,0,0,9,0,10,137,0],"FLAG":0,"BASE":47} Shelly 2.5 {"NAME":"Shelly 2.5","GPIO":[56,0,17,0,21,83,0,0,6,82,5,22,156],"FLAG":2,"BASE":18} +Shelly EM {"NAME":"Shelly EM","GPIO":[0,0,0,0,0,0,0,0,6,156,5,21,0],"FLAG":15,"BASE":18} Sinilink XY-WF36V DC6V-36V Switch Module {"NAME":"Sinilink XY-WF5V","GPIO":[0,0,0,0,21,255,0,0,17,52,0,0,255],"FLAG":0,"BASE":18} Sinilink XY-WFMS MOS Switch Module {"NAME":"Sinilink MOS","GPIO":[0,0,0,0,21,255,0,0,17,52,0,0,255],"FLAG":0,"BASE":18} Sinilink XY-WFUSB USB Switch {"NAME":"XY-WFUSB","GPIO":[255,255,0,255,17,21,0,0,0,0,56,0,157],"FLAG":0,"BASE":18} Smart Home SS-8839-01 {"NAME":"SS-8839-01","GPIO":[0,255,0,255,21,0,0,0,17,57,0,56,0],"FLAG":0,"BASE":18} Sonoff 4CH (R2) {"NAME":"Sonoff 4CH","GPIO":[17,255,255,255,23,22,18,19,21,56,20,24,0],"FLAG":0,"BASE":7} Sonoff 4CH Pro (R2) {"NAME":"Sonoff 4CH Pro","GPIO":[17,255,255,255,23,22,18,19,21,56,20,24,0],"FLAG":0,"BASE":23} +Sonoff 4CHPROR3 {"NAME":"Sonoff 4CHPROR3","GPIO":[17,255,255,255,23,22,18,19,21,56,20,24,0],"FLAG":0,"BASE":23} +Sonoff 4CHR3 {"NAME":"Sonoff 4CHR3","GPIO":[17,255,255,255,23,22,18,19,21,56,20,24,0],"FLAG":0,"BASE":7} Sonoff 5V Inching/Selflock Module RE5V1C {"NAME":"Sonoff RE5V1C","GPIO":[17,255,255,255,255,255,0,0,21,56,0,0,0],"FLAG":0,"BASE":18} Sonoff Basic {"NAME":"Sonoff Basic","GPIO":[17,255,255,255,255,0,0,0,21,56,255,0,0],"FLAG":0,"BASE":1} Sonoff Basic R3 {"NAME":"Basic R3","GPIO":[17,255,0,255,255,0,0,0,21,56,255,0,255],"FLAG":0,"BASE":1} @@ -1145,6 +1297,7 @@ SS-8839-02 {"NAME":"SS-8839-02","GPIO":[0,255,0,255,56,0,0,0,21,0, SS311KWS RF Kinetic Switch and WiFi {"NAME":"SS311KWS","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} SW-R03 {"NAME":"SW-R03","GPIO":[0,0,0,0,0,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} WL-SW01_10 {"NAME":"WL-SW01_10","GPIO":[17,149,0,148,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} +Yuntong Smart {"NAME":"Yuntong Smart ","GPIO":[0,0,0,0,21,0,0,0,122,56,0,0,0],"FLAG":0,"BASE":18} Zemismart ERC309 Kinetic Switch {"NAME":"Kinetic Switch","GPIO":[255,255,255,255,255,255,0,0,255,108,255,107,255],"FLAG":0,"BASE":54} ZMAi-90 Digital Energy Meter {"NAME":"ZMAi-90","GPIO":[0,148,0,149,0,0,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} ``` @@ -1155,11 +1308,16 @@ Digoo DG-ZXD21 Door Detector {"NAME":"Digoo ZXD21","GPIO":[0,107,0,108,0,0,0,0, DP-WP001 PIR {"NAME":"TUYA PIR","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} DS18B20 ESP01 Module Temperature {"NAME":"ESP01S ds18b20","GPIO":[255,255,4,255,255,255,0,0,255,255,255,255,255],"FLAG":15,"BASE":18} Earykong TYMC-1 Door Window {"NAME":"TYMC-1","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +ESP01S DHT11 v1.0 Module Temperature {"NAME":"ESP01S DHT11","GPIO":[0,0,1,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":4} IOT4SH01DS Temperature {"NAME":"IOT4SH01DS","GPIO":[255,255,255,255,255,255,0,0,255,4,255,255,255],"FLAG":15,"BASE":18} +Lenovo Rechargable PIR Motion {"NAME":"Lenovo PIR","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} Mirabella Genio I002576 Motion {"NAME":"GenioPir","GPIO":[17,107,0,108,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":54} +Natural Gas (CH4) Alarm {"NAME":"PA-210WYS","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} Nedis Smoke Detector {"NAME":"Nedis Smoke","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Shelly Temperature Sensor Add-on {"NAME":"Shelly 1 Temp ","GPIO":[192,0,0,4,21,82,0,0,0,0,0,0,0],"FLAG":0,"BASE":46} +Smoke Alarm {"NAME":"YG400A","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} Sonoff SC {"NAME":"Sonoff SC","GPIO":[17,148,255,149,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":21} +TY01 Door Window {"NAME":"TY01","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Zemismart Door Window {"NAME":"Zemismart","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} ``` @@ -1168,6 +1326,8 @@ Zemismart Door Window {"NAME":"Zemismart","GPIO":[255,107,255,108,255,255,0,0 3A Smart Home HGZB-043 {"NAME":"3A Smart Home ","GPIO":[52,0,55,18,22,19,0,0,17,21,54,23,53],"FLAG":0,"BASE":18} Aoycocr SW1 {"NAME":"Aoycocr SW1","GPIO":[158,255,57,255,255,255,255,255,56,17,255,21,255],"FLAG":15,"BASE":18} Avatto 2 Gang {"NAME":"Avatto Wifi - ","GPIO":[0,0,52,0,0,17,0,0,21,22,0,0,18],"FLAG":0,"BASE":18} +Avatto Fan Light {"NAME":"AVATTO Smart Wifi Fan Light","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +Bardi Smart Wallswitch 1 {"NAME":"Bardi 1 Gang","GPIO":[57,56,157,0,0,17,0,0,0,0,0,21,0],"FLAG":0,"BASE":18} Bardi Smart Wallswitch 2 {"NAME":"BARDI 2 Gang","GPIO":[56,0,157,18,22,0,0,0,52,21,57,0,17],"FLAG":0,"BASE":18} Bardi Smart Wallswitch 3 {"NAME":"BARDI 3 Gang","GPIO":[56,57,157,19,23,18,0,0,52,21,58,22,17],"FLAG":0,"BASE":18} BAZZ SWTCHWFW1 {"NAME":"BAZZ KS-602S","GPIO":[17,0,0,0,0,0,21,52,29,56,0,0,0],"FLAG":0,"BASE":18} @@ -1176,10 +1336,10 @@ BlitzWolf BW-SS3 2 Gang {"NAME":"BW-SS3-2G-EU","GPIO":[157,255,255,255,22,18,25 BlitzWolf BW-SS3 3 Gang {"NAME":"BlitzWolf SS3","GPIO":[158,0,0,10,22,11,0,0,9,21,0,23,0],"FLAG":0,"BASE":18} CD303 3 Gang Touch {"NAME":"Touch Switch 3","GPIO":[54,57,255,19,23,18,255,255,17,21,255,22,52],"FLAG":15,"BASE":18} Connect Smart 2 Gang Wall {"NAME":"CSH-SWTCH2","GPIO":[0,0,52,0,0,18,0,0,22,21,0,0,17],"FLAG":0,"BASE":18} +Deta 1 Gang {"NAME":"Deta 1G Switch","GPIO":[0,0,0,0,157,0,0,0,0,21,0,0,90],"FLAG":0,"BASE":18} +Deta 2 Gang {"NAME":"DETA 2G Switch","GPIO":[0,0,0,0,157,0,0,0,91,21,22,0,90],"FLAG":0,"BASE":18} Deta 3 Gang {"NAME":"DETA 3G Switch","GPIO":[157,0,0,92,91,21,0,0,23,0,22,0,90],"FLAG":0,"BASE":18} -Deta 4 Gang {"NAME":"Deta 4G Switch","GPIO":[157,0,0,17,18,24,0,0,21,19,22,23,20],"FLAG":0,"BASE":18} -Deta 6911HA {"NAME":"Deta 1G Switch","GPIO":[0,0,0,0,157,0,0,0,0,21,0,0,90],"FLAG":0,"BASE":18} -Deta 6912HA {"NAME":"DETA 2G Switch","GPIO":[0,0,0,0,157,0,0,0,91,21,22,0,90],"FLAG":0,"BASE":18} +Deta 4 Gang {"NAME":"Deta 4G Switch","GPIO":[157,0,0,19,18,21,0,0,23,20,22,24,17],"FLAG":0,"BASE":18} Digoo DG-S811 3 Gang {"NAME":"DIGOO Switch","GPIO":[0,0,0,0,19,18,0,0,22,21,23,0,17],"FLAG":0,"BASE":18} DS-102 1 Gang {"NAME":"DS-102 1 Gang","GPIO":[57,0,0,17,0,0,0,0,0,21,56,0,0],"FLAG":1,"BASE":18} DS-102 2 Gang {"NAME":"DS-102 2 Gang","GPIO":[158,57,0,17,22,18,0,0,0,21,56,255,0],"FLAG":0,"BASE":18} @@ -1187,9 +1347,11 @@ DS-102 3 Gang {"NAME":"DS-102 3 Gang","GPIO":[158,58,0,18,22,19,0,0,1 Eachen CD303 3 Gang {"NAME":"ID Components","GPIO":[157,53,0,11,21,10,0,0,9,22,54,23,52],"FLAG":15,"BASE":18} Eachen SWT-2Gang {"NAME":"ID Components","GPIO":[157,255,255,255,255,10,255,255,9,21,53,22,52],"FLAG":15,"BASE":18} Enjowi WF-SK301 {"NAME":"Tuya 3 Channel","GPIO":[0,0,0,0,23,18,0,0,17,21,19,22,157],"FLAG":0,"BASE":18} +Esmlfe 3 Gang {"NAME":"Esmlfe DS-122","GPIO":[57,0,0,17,0,0,0,0,0,21,52,0,0],"FLAG":0,"BASE":18} Etekcity ESWL01 {"NAME":"EtekCityESWL01","GPIO":[0,255,0,255,52,53,0,0,0,21,122,0,0],"FLAG":1,"BASE":18} Etekcity ESWL03 3-way {"NAME":"Etekcity 3Way","GPIO":[0,0,0,0,23,29,0,0,82,22,10,0,0],"FLAG":0,"BASE":18} Eva Logik WF30 3-Way {"NAME":"WF30 Switch","GPIO":[0,0,0,0,18,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +FrankEver 4 Gang {"NAME":"FrankEver Wifi Smart Switch","GPIO":[0,0,0,17,21,18,255,255,19,23,24,22,20],"FLAG":0,"BASE":18} Freecube AWS01F {"NAME":"Freecube","GPIO":[0,0,0,17,21,0,0,0,0,0,22,0,0],"FLAG":0,"BASE":18} Geeni TAP 3-Way {"NAME":"Geeni 3-Way","GPIO":[157,0,0,0,0,0,0,0,17,21,0,0,0],"FLAG":0,"BASE":18} Girier EK01 RF433Mhz 1 Gang {"NAME":"Girier EK01","GPIO":[157,0,0,0,21,0,0,0,0,0,0,0,17],"FLAG":0,"BASE":18} @@ -1202,9 +1364,11 @@ Girier JRSWR-US01 No Neutral 1 Gang {"NAME":"Tuya 1 Channel","GPIO":[0,0,0,0,0, Girier JRSWR-US01 No Neutral 3 Gang {"NAME":"Girier JRSWR-U","GPIO":[0,0,0,0,21,18,0,0,19,23,17,22,157],"FLAG":0,"BASE":18} GoKlug Glass Touch 1 Gang {"NAME":"GoKlug 1x","GPIO":[56,57,0,0,0,9,0,0,0,0,0,21,0],"FLAG":0,"BASE":18} Gosund KS-602S {"NAME":"Gosund KS-602S","GPIO":[17,0,56,0,0,0,0,0,0,0,21,0,158],"FLAG":0,"BASE":18} -Gosund SW1 {"NAME":"Gosund SW1","GPIO":[17,0,56,0,0,0,0,0,0,0,21,0,57],"FLAG":0,"BASE":18} +Gosund SW1 {"NAME":"Gosund SW1","GPIO":[17,0,57,0,0,0,0,0,0,0,21,0,56],"FLAG":0,"BASE":18} Hama Flush-mounted {"NAME":"Hama WiFiTouch","GPIO":[157,0,0,0,0,18,0,0,17,22,0,21,0],"FLAG":0,"BASE":45} HBN Wall-Mounted Timer {"NAME":"HBN Timer Switch","GPIO":[0,0,0,0,54,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Innens 1 Gang 1 Way {"NAME":"Innens 1 Gang 1 Way","GPIO":[0,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} +iSwitch Light & Fan {"NAME":"iSwitchOZ Light Fan","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Jinvoo SM-SW101-1 {"NAME":"SM-SW101-1","GPIO":[52,0,0,18,0,0,0,0,17,21,0,0,0],"FLAG":1,"BASE":18} Jinvoo SM-SW101-2 {"NAME":"SM-SW101-2","GPIO":[52,0,0,18,22,0,0,0,17,21,0,0,0],"FLAG":1,"BASE":18} Jinvoo SM-SW101-3 {"NAME":"Jinvoo Wall Sw","GPIO":[52,0,0,18,22,19,0,0,17,21,0,23,0],"FLAG":1,"BASE":18} @@ -1215,13 +1379,15 @@ Koaanw CD302-EU-3 {"NAME":"CD302-EU-3","GPIO":[158,53,0,19,23,18,0,0,17,2 KS-601 2-way {"NAME":"2way Switch","GPIO":[255,255,158,255,255,83,0,0,22,21,255,82,255],"FLAG":0,"BASE":18} KS-602 {"NAME":"Gosund KS-602","GPIO":[17,0,0,0,0,0,0,0,21,157,0,0,0],"FLAG":0,"BASE":18} KS-605 {"NAME":"KS-605","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":18} +KS-611 3 Gang {"NAME":"KS-611 3 Gang","GPIO":[0,0,158,0,19,18,0,0,22,21,23,0,17],"FLAG":0,"BASE":18} +KTNN-KG-T100 2 Gang Switch {"NAME":"Sonoff T1 2CH","GPIO":[17,255,255,255,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":29} Kuled K36 {"NAME":"KULED-B","GPIO":[9,255,255,255,255,255,21,52,29,56,255,255,255],"FLAG":0,"BASE":18} Kuled KS602S {"NAME":"KULED","GPIO":[17,255,255,255,255,255,0,0,21,56,255,255,255],"FLAG":0,"BASE":18} Kygne CD-301 {"NAME":"KYGNE Touch","GPIO":[0,0,0,0,52,53,0,0,21,17,0,0,0],"FLAG":0,"BASE":10} Laghten SS02S {"NAME":"Laghten SS02S","GPIO":[0,0,0,0,52,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} LerLink X801A-L No Neutral {"NAME":"LerLink X801-L","GPIO":[0,0,0,0,17,0,0,0,21,56,0,0,0],"FLAG":15,"BASE":18} Lerlink X802A 2 Gang {"NAME":"Lerlink X802A","GPIO":[0,0,0,18,17,0,0,0,21,23,22,0,0],"FLAG":15,"BASE":18} -LerLink X802A-L No Neutral {"NAME":"LerLink X802-L","GPIO":[0,0,0,18,17,0,0,0,21,158,22,0,0],"FLAG":15,"BASE":18} +LerLink X802A-L No Neutral {"NAME":"LerLink X802-L","GPIO":[0,0,0,18,17,0,0,0,21,158,22,0,0],"FLAG":0,"BASE":18} Lightstory WT02S {"NAME":"WT02S","GPIO":[0,0,0,0,57,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":50} Lonsonho 3 Gang {"NAME":"Lonsonho X803A","GPIO":[0,0,0,18,17,19,0,0,21,29,22,23,0],"FLAG":0,"BASE":18} Lonsonho SK3-01 {"NAME":"Tuya 1 Channel","GPIO":[0,0,0,0,0,17,0,0,0,0,0,21,52],"FLAG":0,"BASE":18} @@ -1231,8 +1397,11 @@ LoraTap WH100W-US 20A {"NAME":"LoraTap Boiler","GPIO":[0,0,0,0,0,0,0,0,17,21, Luminea LHC-101.on {"NAME":"LHC-101.on","GPIO":[157,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} Luminea LHC-102.on {"NAME":"LHC-102.on","GPIO":[157,0,53,0,0,18,0,0,17,21,0,22,52],"FLAG":0,"BASE":18} LX-WIFI-00M 4 Gang {"NAME":"LX-WIFI-00M","GPIO":[17,25,255,255,23,22,18,19,21,0,20,24,0],"FLAG":0,"BASE":7} +MakeGood 2 Gang {"NAME":"MakeGood 2 Gang","GPIO":[0,0,0,0,0,0,0,0,0,0,54,0,0],"FLAG":0,"BASE":54} +MakeGood 4 Gang {"NAME":"MakeGood 4 Gang","GPIO":[0,0,0,0,0,0,0,0,0,0,54,0,0],"FLAG":0,"BASE":54} Markevina KS-602S {"NAME":"Markevina KS-6","GPIO":[17,255,0,255,0,0,0,0,21,52,0,0,0],"FLAG":0,"BASE":18} -Martin Jerry MJ-S01 15A {"NAME":"MJ Switch","GPIO":[0,0,0,0,57,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Martin Jerry 3 Way {"NAME":"MJ 3Way Switch","GPIO":[0,0,0,0,52,53,0,0,21,9,157,0,0],"FLAG":0,"BASE":18} +Martin Jerry MJ-S01 15A {"NAME":"MJ Switch","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Martin Jerry ST01 3 Way {"NAME":"MJ 3Way Switch","GPIO":[255,255,255,255,52,53,0,0,21,9,157,255,0],"FLAG":0,"BASE":18} Merkury MI-WW107-199W {"NAME":"MI-WW107-199W","GPIO":[52,0,0,0,0,0,0,0,17,21,0,0,0],"FLAG":0,"BASE":18} Micmi K38 {"NAME":"KS-605","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":18} @@ -1241,7 +1410,10 @@ Minitiger 1 Gang v2 {"NAME":"MiniTiger1Band","GPIO":[0,56,0,0,0,17,0,0,21,0 Minitiger 2 Gang {"NAME":"minitiger 2 Gang","GPIO":[17,255,255,255,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":28} Minitiger 2 Gang v2 {"NAME":"Minitiger2Band","GPIO":[0,0,0,17,18,0,0,0,0,21,22,0,0],"FLAG":0,"BASE":18} Minitiger 3 Gang {"NAME":"Minitiger3gang","GPIO":[0,0,0,9,11,10,255,255,22,21,23,0,0],"FLAG":0,"BASE":18} +Moes 2 Gang {"NAME":"Moes WS-EU2-W","GPIO":[157,0,53,0,0,18,0,0,17,21,0,22,52],"FLAG":15,"BASE":18} +Moes 3 Gang {"NAME":"Moes WS-EU3-W","GPIO":[157,0,54,18,22,19,0,0,17,21,53,23,52],"FLAG":15,"BASE":18} Moes BS-US-W Boiler {"NAME":"BS-US-W","GPIO":[54,0,0,17,21,0,0,0,0,0,52,0,55],"FLAG":0,"BASE":18} +Moes RF433 2 Gang Switch {"NAME":"WS-EUB2-WR","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Moes SS01-1 3-Way {"NAME":"Moes 3-Way","GPIO":[255,255,255,255,21,57,0,0,30,10,9,255,255],"FLAG":0,"BASE":18} Moes SS01S-1 {"NAME":"Moes Switch","GPIO":[255,255,255,255,56,0,0,0,21,17,255,255,255],"FLAG":0,"BASE":18} Moes WF-FL01 Light and Fan {"NAME":"Moes WF-FL01","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} @@ -1257,11 +1429,12 @@ Moes WS-US3-W 3 Gang {"NAME":"Tuya Moes 3 Ch","GPIO":[157,0,54,18,22,19,0,0, Moes WT02S {"NAME":"Moes WT02S","GPIO":[0,0,0,0,56,158,0,0,21,9,0,0,0],"FLAG":15,"BASE":18} MoesHouse RF433 3 Gang {"NAME":"WS-EUB3-WR","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} MoKo Scene Life {"NAME":"Moko Smart Swi","GPIO":[158,0,0,0,39,38,0,0,56,0,37,21,0],"FLAG":0,"BASE":18} -MoKo Smart Life {"NAME":"Moko Switch","GPIO":[0,0,0,17,21,134,0,0,0,0,0,0,0],"FLAG":0,"BASE":59} +MoKo Smart Life {"NAME":"Moko Switch","GPIO":[57,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":59} NaamaSmart KS602 {"NAME":"KS-602","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":18} Nedis Dual {"NAME":"SM-SW102U-2","GPIO":[158,0,0,18,22,0,0,0,17,21,0,0,0],"FLAG":1,"BASE":18} Nexete DS-123 {"NAME":"DS-123","GPIO":[157,57,255,17,21,18,0,0,255,22,56,255,255],"FLAG":0,"BASE":18} Nexete DS-123 Single {"NAME":"DS-123","GPIO":[157,0,255,18,0,17,0,0,255,21,56,255,255],"FLAG":0,"BASE":18} +RY-RSM104 Light Touch {"NAME":"RY-RSM104","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Sainko 1-Way {"NAME":"SAINKO 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} Sainko 2 Way {"NAME":"Sainko 2-Way","GPIO":[0,255,56,0,0,17,0,0,21,22,0,0,18],"FLAG":0,"BASE":18} SANA SASW-03 {"NAME":"SANA SASW-03","GPIO":[54,0,0,19,23,18,0,0,17,21,0,22,0],"FLAG":0,"BASE":18} @@ -1272,9 +1445,11 @@ Semicom LM-HP/GEVD-W {"NAME":"WaterHeater","GPIO":[158,56,0,0,0,17,0,0,0,0,0 Sesoo WIFI-EU-SK3-01 {"NAME":"Sensoo SK3-01","GPIO":[255,255,57,255,255,17,0,0,255,255,255,21,52],"FLAG":0,"BASE":18} Sesoo WIFI-EU-SK3-02 {"NAME":"Sesoo SK3-02","GPIO":[0,0,57,0,22,0,0,0,17,21,18,0,52],"FLAG":0,"BASE":18} Sesoo WIFI-US-SK3-04 {"NAME":"Tuya 4 Channel","GPIO":[52,255,255,19,23,17,0,0,20,24,22,21,18],"FLAG":0,"BASE":18} +SK-A801-01-US 1 Gang {"NAME":"jsankou US Switch 1 Gang","GPIO":[157,0,0,0,0,0,0,0,17,29,0,0,0],"FLAG":0,"BASE":18} +SK-W803-01-US 3 Gang {"NAME":"jsankou US Switch 3 Gang","GPIO":[157,0,0,18,30,19,0,0,17,29,0,31,0],"FLAG":0,"BASE":18} Smartlife Opard CD302 {"NAME":"CD302","GPIO":[0,0,0,0,52,57,0,0,29,17,0,0,0],"FLAG":0,"BASE":18} SmartPlex 3 Gang {"NAME":"Tuya 3 Channel","GPIO":[255,255,255,255,21,18,0,0,19,23,17,22,255],"FLAG":0,"BASE":18} -Sonoff IW101 {"NAME":"Sonoff IW100","GPIO":[17,145,0,146,0,0,0,0,21,157,0,0,0],"FLAG":0,"BASE":41} +Sonoff IW101 {"NAME":"Sonoff IW101","GPIO":[17,145,0,146,0,0,0,0,21,157,0,0,0],"FLAG":0,"BASE":41} Sonoff T1 EU 1 Gang {"NAME":"Sonoff T1 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} Sonoff T1 EU 2 Gang {"NAME":"Sonoff T1 2CH","GPIO":[17,255,255,255,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":29} Sonoff T1 UK 1 Gang {"NAME":"Sonoff T1 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} @@ -1283,15 +1458,17 @@ Sonoff T1 UK 3 Gang {"NAME":"Sonoff T1 3CH","GPIO":[17,255,255,255,23,22,18 Sonoff T1 US 1 Gang {"NAME":"Sonoff T1 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} Sonoff T1 US 2 Gang {"NAME":"Sonoff T1 2CH","GPIO":[17,255,255,255,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":29} Sonoff T1 US 3 Gang {"NAME":"Sonoff T1 3CH","GPIO":[17,255,255,255,23,22,18,19,21,56,0,0,0],"FLAG":0,"BASE":30} -Sonoff Touch {"NAME":"Sonoff Touch","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":10} -Sonoff Touch {"NAME":"Sonoff Touch","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":10} -Sonoff TX T3 3 Gang {"NAME":"TX T3EU3C","GPIO":[17,255,0,255,23,22,18,19,21,158,0,0,0],"FLAG":0,"BASE":30} +Sonoff Touch EU {"NAME":"Sonoff Touch","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":10} +Sonoff Touch US {"NAME":"Sonoff Touch","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":10} +Sonoff TX T3 EU 3 Gang {"NAME":"TX T3EU3C","GPIO":[17,255,0,255,23,22,18,19,21,158,0,0,0],"FLAG":0,"BASE":30} +Sonoff TX T3 US 3 Gang {"NAME":"TX T3US3C","GPIO":[17,255,0,255,23,22,18,19,21,158,0,0,0],"FLAG":0,"BASE":30} SPC Hera {"NAME":"SPC HERA","GPIO":[157,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} SRL 3-4WW 4 Gang {"NAME":"SRL 4WW Switch","GPIO":[0,0,0,19,23,18,0,0,17,21,24,22,20],"FLAG":0,"BASE":18} SS118-01K1 {"NAME":"SS118-01K1","GPIO":[255,255,255,17,21,255,0,0,255,255,56,255,255],"FLAG":0,"BASE":18} SS86-AI 3-Gang {"NAME":"SS86-AI 3 Gang","GPIO":[157,0,58,18,22,19,0,0,17,21,57,23,56],"FLAG":0,"BASE":18} SSMS118-01A1 Scene Light Smart {"NAME":"RGB Switch","GPIO":[30,0,32,10,39,38,0,0,31,9,37,21,0],"FLAG":0,"BASE":18} STITCH by Monoprice 35557 {"NAME":"Tuya WF15S ","GPIO":[255,255,0,0,255,255,0,0,255,108,255,107,0],"FLAG":0,"BASE":54} +Teckin SR-41 Single Pole {"NAME":"Teckin SR-41","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":18} Teckin SR43 {"NAME":"Teckin SR43","GPIO":[0,0,52,0,0,17,0,0,21,22,0,0,18],"FLAG":0,"BASE":18} Teekar 10 Way 1 Gang {"NAME":"Teekar 10way","GPIO":[9,10,11,20,13,14,0,0,15,16,0,0,0],"FLAG":0,"BASE":18} Teekar Wi-Fi Light 1 Gang {"NAME":"TeeKar Touch","GPIO":[0,0,255,0,255,21,0,0,0,255,17,0,255],"FLAG":0,"BASE":18} @@ -1299,11 +1476,13 @@ Teepao Smart-Rollladen-Schalter {"NAME":"Teepao","GPIO":[158,58,23,18,22,19,0,0 Tonbux AMZ180648-2 {"NAME":"Tonbux","GPIO":[17,255,255,255,255,0,0,0,21,56,255,0,0],"FLAG":0,"BASE":1} Touch 2 Gang {"NAME":"tuya_2_gang","GPIO":[52,0,0,0,18,0,0,0,17,21,255,22,29],"FLAG":0,"BASE":18} Touch 3 Gang {"NAME":"Switch 3-Gang","GPIO":[0,0,0,0,23,18,0,0,17,21,19,22,157],"FLAG":0,"BASE":18} +Treatlife SS01 3-Way {"NAME":"Treatlife SS01 3-Way","GPIO":[0,0,0,0,21,158,0,0,22,18,9,0,0],"FLAG":0,"BASE":18} TreatLife SS01S {"NAME":"TL SS01S Swtch","GPIO":[0,0,0,0,52,158,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} TreatLife SS02 3-Way {"NAME":"TreatLife 3Way","GPIO":[0,0,0,0,53,29,0,0,30,18,9,0,0],"FLAG":0,"BASE":18} TreatLife SS02S {"NAME":"Treatlife SS02","GPIO":[0,0,0,0,53,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} TY-US-L1-W {"NAME":"TY-US-L1-W","GPIO":[0,0,0,0,0,17,0,0,0,21,0,0,158],"FLAG":0,"BASE":18} TY-US-L3-W {"NAME":"TY-US-L3-W","GPIO":[0,0,0,0,21,18,0,0,19,23,17,22,158],"FLAG":15,"BASE":18} +Unbranded 2 Gang {"NAME":"Smart Life Switch 2","GPIO":[157,57,0,17,21,18,0,0,0,22,56,0,0],"FLAG":0,"BASE":18} Vaticas 1 {"NAME":"Vaticas","GPIO":[0,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} vhome RF433 3 Gang {"NAME":"VH-TB-US-003","GPIO":[0,0,0,0,21,18,0,0,19,23,17,22,158],"FLAG":15,"BASE":18} WiFi Smart Switch 2 Gang {"NAME":"Kingart N2","GPIO":[17,255,0,255,0,22,18,0,21,0,0,0,0],"FLAG":15,"BASE":18} @@ -1314,10 +1493,10 @@ Xenon SM-SW202 {"NAME":"SM-SW202","GPIO":[0,0,0,17,21,0,0,0,0,0,52,0,0 Yapmor 1-gang {"NAME":"YAPMOR 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} Youngzuth 2in1 {"NAME":"SW02 2W","GPIO":[52,0,0,9,21,0,0,0,10,22,0,0,0],"FLAG":0,"BASE":18} Youngzuth 3in1 {"NAME":"SW02 3W","GPIO":[56,0,0,19,23,18,0,0,17,21,0,22,0],"FLAG":0,"BASE":18} -Zemismart KS-611 3 Gang {"NAME":"Zemismart 3 Ga","GPIO":[0,0,56,0,19,18,0,0,22,21,23,0,17],"FLAG":0,"BASE":18} Zemismart KS-811 1 Gang {"NAME":"KS-811 Single","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":18} -Zemismart KS-811 2 Gang {"NAME":"KS-811 Dual","GPIO":[0,0,52,0,0,18,0,0,22,21,0,0,17],"FLAG":0,"BASE":18} +Zemismart KS-811 2 Gang {"NAME":"KS-811 Dual","GPIO":[0,0,158,0,0,18,0,0,22,21,0,0,17],"FLAG":0,"BASE":18} Zemismart KS-811 3 Gang {"NAME":"KS-811 Triple","GPIO":[0,0,56,0,19,18,0,0,22,21,23,0,17],"FLAG":0,"BASE":18} +Zemismart RF Remote No Neutral 2 Gang {"NAME":"DS-104-2","GPIO":[0,0,0,0,22,0,0,0,17,21,18,0,56],"FLAG":0,"BASE":18} ZemiSmart SS118-01K2 {"NAME":"SS118-01K2","GPIO":[0,0,0,17,21,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Zemismart WF-BS01 {"NAME":"WF-BS01","GPIO":[53,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} Zemismart ZM-L01E {"NAME":"ZSmart ZM-L01E","GPIO":[255,255,255,255,255,255,0,0,255,21,255,255,17],"FLAG":0,"BASE":18} @@ -1343,10 +1522,9 @@ Aseer THWFS01 {"NAME":"ASEER-THWFS01","GPIO":[56,18,157,59,134,132,0, Bestten LO-2-W {"NAME":"BESTTEN LO-2-W","GPIO":[0,0,0,0,158,17,0,0,21,0,0,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-SHP8 {"NAME":"SHP8","GPIO":[0,56,0,17,134,132,0,0,131,53,21,0,0],"FLAG":0,"BASE":64} BSEED Smart Socket / WIFI {"NAME":"BSEED Socket","GPIO":[0,0,0,0,157,52,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} -CE Smart Home LA-2-W3 {"NAME":"CE Smart Wall","GPIO":[255,255,255,255,157,17,0,0,21,255,255,255,255],"FLAG":15,"BASE":18} -CE Smart Home LQ-2-W3 {"NAME":"CE LQ-2-W3","GPIO":[255,255,255,255,255,17,255,255,21,255,255,255,255],"FLAG":15,"BASE":18} +CE Smart Home {"NAME":"CE Smart Wall","GPIO":[255,255,255,255,157,17,0,0,21,255,255,255,255],"FLAG":15,"BASE":18} CE Smart Home LQ-2-W3 {"NAME":"LITESUN","GPIO":[0,0,0,0,157,17,0,0,21,0,0,0,0],"FLAG":0,"BASE":18} -Deta 6922HA {"NAME":"DETA 2G GPO","GPIO":[0,0,0,17,157,0,0,0,91,21,22,0,90],"FLAG":0,"BASE":18} +Deta 6922HA {"NAME":"DETA 2G GPO","GPIO":[0,0,0,0,157,0,0,0,91,21,22,0,90],"FLAG":0,"BASE":18} Ener-J 13A Twin Wall Sockets with USB {"NAME":"Ener-J 2-Gang ","GPIO":[17,0,0,0,0,21,18,0,22,56,0,0,0],"FLAG":0,"BASE":18} Kapok T16 {"NAME":"tiltech-t16","GPIO":[0,56,0,17,82,0,0,0,21,22,0,0,0],"FLAG":0,"BASE":18} Kesen KS-604 {"NAME":"KS-604","GPIO":[255,255,52,255,255,18,0,0,22,21,255,255,17],"FLAG":0,"BASE":18} @@ -1361,7 +1539,13 @@ PS-1607 {"NAME":"PS-1607","GPIO":[17,0,0,0,0,22,18,0,21,0,0,0,0 Smanergy KA10 {"NAME":"KA10","GPIO":[0,56,0,17,134,132,0,0,131,53,21,0,0],"FLAG":0,"BASE":64} Sonoff IW100 {"NAME":"Sonoff IW100","GPIO":[17,145,0,146,0,0,0,0,21,157,0,0,0],"FLAG":0,"BASE":41} Sonoff S55 {"NAME":"Sonoff S55","GPIO":[17,255,0,255,255,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} +T16E Dual USB 10A {"NAME":"t16E 10A","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} Teckin SR40 {"NAME":"RF-SR40-US","GPIO":[158,0,0,17,56,18,0,0,22,21,57,23,0],"FLAG":0,"BASE":18} TopGreener TGWF15RM {"NAME":"TGWF15RM","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":55} Vigica VGSPK00815 {"NAME":"VIGICA outlet","GPIO":[17,255,255,255,255,22,18,255,21,255,255,255,255],"FLAG":1,"BASE":18} ``` + +## Zigbee Bridge +``` +Sonoff ZBBridge {"NAME":"Sonoff ZBBridge","GPIO":[56,165,0,166,59,58,0,0,0,158,0,0,17],"FLAG":0,"BASE":18} +``` From c66e5a4381529ae2281c370cda103ea83cd850e3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Jul 2020 14:11:41 +0200 Subject: [PATCH 487/581] Fix GCC 10.1 warnings --- tasmota/xdrv_23_zigbee_5_converters.ino | 2 ++ tasmota/xdrv_23_zigbee_6_commands.ino | 6 ++++-- tasmota/xdrv_23_zigbee_7_statemachine.ino | 5 +++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 4cba00500..26781d358 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -1192,6 +1192,7 @@ int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu JsonObject& json = jsonBuffer.createObject(); json[F(OCCUPANCY)] = 0; zigbee_devices.jsonPublishNow(shortaddr, json); + return 0; // Fix GCC 10.1 warning } // Aqara Cube @@ -1420,6 +1421,7 @@ int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObje if (func) { return (*func)(zcl, shortaddr, json, name, value, new_name, cluster, attr); } + return 1; // Fix GCC 10.1 warning } void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) { diff --git a/tasmota/xdrv_23_zigbee_6_commands.ino b/tasmota/xdrv_23_zigbee_6_commands.ino index 1f6c4e3a1..40545f737 100644 --- a/tasmota/xdrv_23_zigbee_6_commands.ino +++ b/tasmota/xdrv_23_zigbee_6_commands.ino @@ -42,7 +42,7 @@ typedef struct Z_XYZ_Var { // Holds values for vairables X, Y and Z ZF(AddGroup) ZF(ViewGroup) ZF(GetGroup) ZF(GetAllGroups) ZF(RemoveGroup) ZF(RemoveAllGroups) ZF(AddScene) ZF(ViewScene) ZF(RemoveScene) ZF(RemoveAllScenes) ZF(RecallScene) ZF(StoreScene) ZF(GetSceneMembership) -//ZF(Power) ZF(Dimmer) +//ZF(Power) ZF(Dimmer) ZF(DimmerUp) ZF(DimmerDown) ZF(DimmerStop) ZF(ResetAlarm) ZF(ResetAllAlarms) //ZF(Hue) ZF(Sat) ZF(CT) @@ -52,7 +52,7 @@ ZF(ShutterOpen) ZF(ShutterClose) ZF(ShutterStop) ZF(ShutterLift) ZF(ShutterTilt) ZF(DimmerMove) ZF(DimmerStep) ZF(DimmerStepUp) ZF(DimmerStepDown) ZF(HueMove) ZF(HueStep) ZF(HueStepUp) ZF(HueStepDown) ZF(SatMove) ZF(SatStep) ZF(ColorMove) ZF(ColorStep) ZF(ColorTempMoveUp) ZF(ColorTempMoveDown) ZF(ColorTempMoveStop) ZF(ColorTempMove) -ZF(ColorTempStep) ZF(ColorTempStepUp) ZF(ColorTempStepDown) +ZF(ColorTempStep) ZF(ColorTempStepUp) ZF(ColorTempStepDown) ZF(ArrowClick) ZF(ArrowHold) ZF(ArrowRelease) ZF(ZoneStatusChange) ZF(xxxx00) ZF(xxxx) ZF(01xxxx) ZF(03xxxx) ZF(00) ZF(01) ZF() ZF(xxxxyy) ZF(00190200) ZF(01190200) ZF(xxyyyy) ZF(xx) @@ -189,6 +189,7 @@ int32_t Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clus } ZigbeeZCLSend_Raw(shortaddr, groupaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, 0, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(shortaddr)); } + return 0; // Fix GCC 10.1 warning } @@ -197,6 +198,7 @@ int32_t Z_Unreachable(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, if (BAD_SHORTADDR != shortaddr) { zigbee_devices.setReachable(shortaddr, false); // mark device as reachable } + return 0; // Fix GCC 10.1 warning } // set a timer to read back the value in the future diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index 7b0c1adc6..fecf68fe9 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -838,7 +838,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { // wait for device to start ZI_WAIT_UNTIL(5000, ZBR_RSTACK) // wait for RSTACK message - + // Init device and probe version ZI_SEND(ZBS_VERSION) ZI_WAIT_RECV_FUNC(1000, ZBR_VERSION, &EZ_ReceiveCheckVersion) // check EXT PAN ID @@ -886,7 +886,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { // ZI_GOTO(ZIGBEE_LABEL_CONFIGURE_EZSP) // // Try networkInit to restore settings, and check if network comes up - ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_BAD_CONFIG) // + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_BAD_CONFIG) // ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_BAD_CONFIG) ZI_SEND(ZBS_NETWORK_INIT) ZI_WAIT_RECV(500, ZBR_NETWORK_INIT) ZI_WAIT_RECV(1500, ZBR_NETWORK_UP) // wait for network to start @@ -1217,6 +1217,7 @@ int32_t ZigbeeProcessInput(class SBuffer &buf) { // any other negative value means error ZigbeeGotoLabel(zigbee.on_error_goto); } + return 0; // Fix GCC 10.1 warning } #endif // USE_ZIGBEE From 6f52b0f7cc35bc7c6624538c05fabb85360df4de Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Jul 2020 14:35:30 +0200 Subject: [PATCH 488/581] Reset version --- tasmota/tasmota_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index d1601408a..6b64471b0 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08040000; +const uint32_t VERSION = 0x08030106; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; From 60fc491b4d2ffdb96c8bf61391d22dd942f1f5be Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 15 Jul 2020 15:41:11 +0200 Subject: [PATCH 489/581] Update RCSwitch.cpp Use DRAM for ESP32 protocol list and replace ICACHE_RAM_ATTR by IRAM_ATTR for ESP32, so as to avoid core dump when using in conjunction with Wifi Added support for Holtek's HT12E encoder/decoders Added 1ByOne Doorbell protocol --- lib/rc-switch-2.6.2.13/RCSwitch.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/rc-switch-2.6.2.13/RCSwitch.cpp b/lib/rc-switch-2.6.2.13/RCSwitch.cpp index 76ad3a133..ced09ceff 100644 --- a/lib/rc-switch-2.6.2.13/RCSwitch.cpp +++ b/lib/rc-switch-2.6.2.13/RCSwitch.cpp @@ -13,19 +13,20 @@ - Robert ter Vehn / .(at)gmail(dot)com - Johann Richard / .(at)gmail(dot)com - Vlad Gheorghe / .(at)gmail(dot)com https://github.com/vgheo + - Matias Cuenca-Acuna Project home: https://github.com/sui77/rc-switch/ - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + This library 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 Lesser General Public License for more details. - + You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -40,17 +41,22 @@ #define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) #endif -#if defined(ESP8266) || defined(ESP32) +#if defined(ESP8266) // interrupt handler and related code must be in RAM on ESP8266, // according to issue #46. #define RECEIVE_ATTR ICACHE_RAM_ATTR + #define VAR_ISR_ATTR +#elif defined(ESP32) + #define RECEIVE_ATTR IRAM_ATTR + #define VAR_ISR_ATTR DRAM_ATTR #else #define RECEIVE_ATTR + #define VAR_ISR_ATTR #endif /* Format for protocol definitions: - * {pulselength, Sync bit, "0" bit, "1" bit} + * {pulselength, Sync bit, "0" bit, "1" bit, invertedSignal} * * pulselength: pulse length in microseconds, e.g. 350 * Sync bit: {1, 31} means 1 high pulse and 31 low pulses @@ -69,7 +75,7 @@ * These are combined to form Tri-State bits when sending or receiving codes. */ #if defined(ESP8266) || defined(ESP32) -static const RCSwitch::Protocol proto[] = { +static const VAR_ISR_ATTR RCSwitch::Protocol proto[] = { #else static const RCSwitch::Protocol PROGMEM proto[] = { #endif @@ -81,7 +87,10 @@ static const RCSwitch::Protocol PROGMEM proto[] = { { 450, { 23, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 6 (HT6P20B) { 150, { 2, 62 }, { 1, 6 }, { 6, 1 }, false }, // protocol 7 (HS2303-PT, i. e. used in AUKEY Remote) { 200, { 3, 130}, { 7, 16 }, { 3, 16}, false}, // protocol 8 Conrad RS-200 RX - { 200, { 130, 7 }, { 16, 7 }, { 16, 3 }, true} // protocol 9 Conrad RS-200 TX + { 200, { 130, 7 }, { 16, 7 }, { 16, 3 }, true}, // protocol 9 Conrad RS-200 TX + { 365, { 18, 1 }, { 3, 1 }, { 1, 3 }, true }, // protocol 10 (1ByOne Doorbell) + { 270, { 36, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 11 (HT12E) + { 320, { 36, 1 }, { 1, 2 }, { 2, 1 }, true } // protocol 12 (SM5212) }; enum { From 06c06705dd55d8fdd851251b664dfb44bd8d2cb4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Jul 2020 16:09:32 +0200 Subject: [PATCH 490/581] Fix minimal binary fast reboot issue --- tasmota/tasmota.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 6dfcb2548..bf669aed5 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -211,7 +211,11 @@ void setup(void) { if (!RtcRebootValid()) { RtcReboot.fast_reboot_count = 0; } +#ifdef FIRMWARE_MINIMAL + RtcReboot.fast_reboot_count = 0; // Disable fast reboot and quick power cycle detection +#else RtcReboot.fast_reboot_count++; +#endif RtcRebootSave(); Serial.begin(APP_BAUDRATE); From d1078c5ce0b446b6c90b3ab8d029d768ce74d2fa Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 15 Jul 2020 17:30:42 +0200 Subject: [PATCH 491/581] Workaround device hangs Workaround device hangs by using core 2.7.1 (#8913) --- platformio.ini | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 7a0a051b4..80984a7fb 100644 --- a/platformio.ini +++ b/platformio.ini @@ -122,8 +122,10 @@ build_flags = -DUSE_IR_REMOTE_FULL [core] +; *** Esp8266 Arduino core 2.7.1 +platform = espressif8266@2.5.1 ; *** Esp8266 Arduino core 2.7.2 -platform = espressif8266@2.6.0 +;platform = espressif8266@2.6.0 platform_packages = build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From f6f208e65c231db9c35c81b903a75bc6809e16f5 Mon Sep 17 00:00:00 2001 From: Staars Date: Wed, 15 Jul 2020 17:41:12 +0200 Subject: [PATCH 492/581] add MHO-C401 --- tasmota/xsns_62_MI_ESP32.ino | 123 +++++++++++++++++------------------ 1 file changed, 59 insertions(+), 64 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 0211d276d..fbdc5bf6b 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -20,6 +20,8 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.1.1 20200715 changed - add MHO-C401, refactoring + ------- 0.9.1.0 20200712 changed - add lights and yeerc, add pure passive mode with decryption, lots of refactoring ------- @@ -167,8 +169,8 @@ struct mi_sensor_t{ float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx union { struct { - float moisture; - float fertility; + uint8_t moisture; + uint16_t fertility; char firmware[6]; // actually only for FLORA but hopefully we can add for more devices }; // Flora struct { @@ -210,8 +212,11 @@ const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit #define NLIGHT 7 #define MJYD2S 8 #define YEERC 9 +#define MHOC401 10 -const uint16_t kMI32DeviceID[9]={ 0x0098, // Flora +#define MI_TYPES 10 //count this manually + +const uint16_t kMI32DeviceID[MI_TYPES]={ 0x0098, // Flora 0x01aa, // MJ_HT_V1 0x045b, // LYWSD02 0x055b, // LYWSD03 @@ -219,7 +224,8 @@ const uint16_t kMI32DeviceID[9]={ 0x0098, // Flora 0x0576, // CGD1 0x03dd, // NLIGHT 0x07f6, // MJYD2S - 0x0153 // yee-rc + 0x0153, // yee-rc + 0x0387 // MHO-C401 }; const char kMI32DeviceType1[] PROGMEM = "Flora"; @@ -231,7 +237,8 @@ const char kMI32DeviceType6[] PROGMEM = "CGD1"; const char kMI32DeviceType7[] PROGMEM = "NLIGHT"; const char kMI32DeviceType8[] PROGMEM = "MJYD2S"; const char kMI32DeviceType9[] PROGMEM = "YEERC"; -const char * kMI32DeviceType[] PROGMEM = {kMI32DeviceType1,kMI32DeviceType2,kMI32DeviceType3,kMI32DeviceType4,kMI32DeviceType5,kMI32DeviceType6,kMI32DeviceType7,kMI32DeviceType8,kMI32DeviceType9}; +const char kMI32DeviceType10[] PROGMEM ="MHOC401"; +const char * kMI32DeviceType[] PROGMEM = {kMI32DeviceType1,kMI32DeviceType2,kMI32DeviceType3,kMI32DeviceType4,kMI32DeviceType5,kMI32DeviceType6,kMI32DeviceType7,kMI32DeviceType8,kMI32DeviceType9,kMI32DeviceType10}; /*********************************************************************************************\ * enumerations @@ -330,7 +337,7 @@ void MI32scanEndedCB(NimBLEScanResults results){ void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){ AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Notified length: %u"),length); switch(MIBLEsensors[MI32.state.sensor].type){ - case LYWSD03MMC: case LYWSD02: + case LYWSD03MMC: case LYWSD02: case MHOC401: MI32readHT_LY((char*)pData); MI32.mode.readingDone = 1; break; @@ -486,7 +493,7 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter) DEBUG_SENSOR_LOG(PSTR("%s: will test ID-type: %x"),D_CMND_MI32, _type); bool _success = false; - for (uint32_t i=0;i<9;i++){ // i < sizeof(kMI32DeviceID) gives compiler warning + for (uint32_t i=0;i120000){ - MIBLEsensors[_slot].eventType = 1; - MIBLEsensors[_slot].events++; - MIBLEsensors[_slot].shallSendMQTT = 1; - MIBLEsensors[_slot].lastTime = millis(); - AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MJYD2S secondary PIR")); - MIBLEsensors[_slot].NMT = 0; - MI32triggerTele(); - } + // This seems to be some kind of wake-up packet only, as it shows up before all kinds of messages, not only motion + // if(millis()-MIBLEsensors[_slot].lastTime>120000){ + // MIBLEsensors[_slot].eventType = 1; + // MIBLEsensors[_slot].events++; + // MIBLEsensors[_slot].shallSendMQTT = 1; + // MIBLEsensors[_slot].lastTime = millis(); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MJYD2S secondary PIR")); + // MIBLEsensors[_slot].NMT = 0; + // MI32triggerTele(); + // } } break; } @@ -1093,19 +1105,13 @@ if (MIBLEsensors[_slot].type==NLIGHT){ // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); break; case 0x08: - _tempFloat =(float)_beacon.moist; - if(_tempFloat<100){ - MIBLEsensors[_slot].moisture=_tempFloat; + MIBLEsensors[_slot].moisture=_beacon.moist; DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); - } // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); break; case 0x09: - _tempFloat=(float)(_beacon.fert); - if(_tempFloat<65535){ // ??? - MIBLEsensors[_slot].fertility=_tempFloat; + MIBLEsensors[_slot].fertility=_beacon.fert; DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); - } // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); break; case 0x0a: @@ -1235,7 +1241,7 @@ void MI32readHT_LY(char *_buf){ MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("LYWSD0x: hum updated")); } - if (MIBLEsensors[_slot].type == LYWSD03MMC){ + if (MIBLEsensors[_slot].type == LYWSD03MMC || MIBLEsensors[_slot].type == MHOC401){ MIBLEsensors[_slot].bat = ((float)LYWSD0x_HT.volt-2100.0f)/12.0f; } } @@ -1456,7 +1462,6 @@ const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 {m}%u%s / %u{e}"; const char HTTP_MI32_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; const char HTTP_RSSI[] PROGMEM = "{s}%s " D_RSSI "{m}%d dBm{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; -const char HTTP_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{m}%s V{e}"; const char HTTP_LASTBUTTON[] PROGMEM = "{s}%s Last Button{m}%u {e}"; const char HTTP_EVENTS[] PROGMEM = "{s}%s Events{m}%u {e}"; const char HTTP_NMT[] PROGMEM = "{s}%s No motion{m}> %u seconds{e}"; @@ -1471,28 +1476,20 @@ void MI32Show(bool json) } for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { switch(MIBLEsensors[i].type){ - case YEERC: + case NLIGHT: case MJYD2S: case YEERC: if(MIBLEsensors[i].shallSendMQTT==0) continue; break; default: if(MI32.mode.triggeredTele) continue; break; } -/* - char slave[33]; - snprintf_P(slave, sizeof(slave), PSTR("%s-%02x%02x%02x"), - kMI32DeviceType[MIBLEsensors[i].type-1],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]); - ResponseAppend_P(PSTR(",\"%s\":{"), slave); -*/ + ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"), kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].MAC[3], MIBLEsensors[i].MAC[4], MIBLEsensors[i].MAC[5]); - if (MIBLEsensors[i].rssi!=0xffff) { // this is the error code -> no valid value - ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].rssi); // all sensors have rssi - } else { - ResponseAppend_P(PSTR("\"RSSI\":null")); // to know that it is sometimes out of range - } + ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].rssi); + if (MIBLEsensors[i].type == FLORA) { if (!isnan(MIBLEsensors[i].temp)) { char temperature[FLOATSZ]; // all sensors have temperature @@ -1502,11 +1499,11 @@ void MI32Show(bool json) if (MIBLEsensors[i].lux!=0x0ffffff) { // this is the error code -> no lux ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); } - if (!isnan(MIBLEsensors[i].moisture)) { - ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%f"), MIBLEsensors[i].moisture); + if (MIBLEsensors[i].moisture!=0xff) { + ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%u"), MIBLEsensors[i].moisture); } - if (!isnan(MIBLEsensors[i].fertility)) { - ResponseAppend_P(PSTR(",\"Fertility\":%f"), MIBLEsensors[i].fertility); + if (MIBLEsensors[i].fertility!=0xffff) { + ResponseAppend_P(PSTR(",\"Fertility\":%u"), MIBLEsensors[i].fertility); } if (MIBLEsensors[i].firmware[0] != '\0') { // this is the error code -> no firmware ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); @@ -1520,7 +1517,7 @@ void MI32Show(bool json) } #ifdef USE_MI_DECRYPTION if (MIBLEsensors[i].type == MJYD2S){ - ResponseAppend_P(PSTR("\"Events\":%u"),MIBLEsensors[i].events); + ResponseAppend_P(PSTR(",\"Events\":%u"),MIBLEsensors[i].events); if(MIBLEsensors[i].shallSendMQTT && MIBLEsensors[i].eventType<3) ResponseAppend_P(PSTR(",\"PIR\":%u"), 2 - MIBLEsensors[i].eventType); if(MIBLEsensors[i].eventType==3) ResponseAppend_P(PSTR(",\"NMT\":%u"), MIBLEsensors[i].NMT); MIBLEsensors[i].eventType=0; @@ -1528,11 +1525,11 @@ void MI32Show(bool json) } #endif //USE_MI_DECRYPTION if (MIBLEsensors[i].type == NLIGHT){ - ResponseAppend_P(PSTR("\"Events\":%u"),MIBLEsensors[i].events); + ResponseAppend_P(PSTR(",\"Events\":%u"),MIBLEsensors[i].events); if(MIBLEsensors[i].shallSendMQTT) ResponseAppend_P(PSTR(",\"PIR\":1")); } if (MIBLEsensors[i].type == YEERC){ - if(MIBLEsensors[i].shallSendMQTT) ResponseAppend_P(PSTR("\"Btn\":%u"),MIBLEsensors[i].Btn); + if(MIBLEsensors[i].shallSendMQTT) ResponseAppend_P(PSTR(",\"Btn\":%u"),MIBLEsensors[i].Btn); } if (MIBLEsensors[i].bat != 0x00) { // this is the error code -> no battery ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); @@ -1560,20 +1557,18 @@ void MI32Show(bool json) for (i; i no valid value - WSContentSend_PD(HTTP_RSSI, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].rssi); - } + WSContentSend_PD(HTTP_RSSI, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].rssi); if (MIBLEsensors[i].type==FLORA) { if (!isnan(MIBLEsensors[i].temp)) { char temperature[FLOATSZ]; dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); WSContentSend_PD(HTTP_SNS_TEMP, kMI32DeviceType[MIBLEsensors[i].type-1], temperature, TempUnit()); } - if (!isnan(MIBLEsensors[i].moisture)) { - WSContentSend_PD(HTTP_SNS_MOISTURE, kMI32DeviceType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].moisture)); + if (MIBLEsensors[i].moisture!=0xff) { + WSContentSend_PD(HTTP_SNS_MOISTURE, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].moisture); } - if (!isnan(MIBLEsensors[i].fertility)) { - WSContentSend_PD(HTTP_MI32_FLORA_DATA, kMI32DeviceType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].fertility)); + if (MIBLEsensors[i].fertility!=0xffff) { + WSContentSend_PD(HTTP_MI32_FLORA_DATA, kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].fertility); } } if (MIBLEsensors[i].type>FLORA) { // everything "above" Flora From a0d731358fe780cd593aaea9490590bb3dd2ce3a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 15 Jul 2020 18:11:21 +0200 Subject: [PATCH 493/581] use modified Core 2.7.2... for Tasmota. Reverts faulty Arduino commit https://github.com/esp8266/Arduino/commit/51daecc236fbff0d1ed30a9c63a3af6e8b5c7392 and adds PR https://github.com/esp8266/Arduino/pull/7022 --- platformio.ini | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 80984a7fb..ad2b13c28 100644 --- a/platformio.ini +++ b/platformio.ini @@ -122,10 +122,8 @@ build_flags = -DUSE_IR_REMOTE_FULL [core] -; *** Esp8266 Arduino core 2.7.1 +; *** Esp8266 Tasmota modified Arduino core based on core 2.7.2 platform = espressif8266@2.5.1 -; *** Esp8266 Arduino core 2.7.2 -;platform = espressif8266@2.6.0 -platform_packages = +platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.8.0-tasmota/esp8266-2.8.0.zip build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From 125c6a4402647dc9e7706bbf2dc273515b5507f1 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Jul 2020 09:03:04 +0200 Subject: [PATCH 494/581] sync platformio_override.ini with platformio.ini Platform is `platform = espressif8266@2.5.1` no need to install `platform = espressif8266@2.6.0` too. It is overwritten anyway with Tasmota core `platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.8.0-tasmota/esp8266-2.8.0.zip` Delete lwIP 1.4 from core_stage because it is not anymore in core > 2.7.2 --- platformio_override_sample.ini | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 3ec6c3a57..8499764fa 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -87,7 +87,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage -platform = espressif8266@2.6.0 +platform = espressif8266@2.5.1 platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.8.0-tasmota/esp8266-2.8.0.zip build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} @@ -143,8 +143,6 @@ build_flags = ${esp82xx_defaults.build_flags} ; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191122 ; NONOSDK3V0 (known issues) ; -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK3 -; lwIP 1.4 -; -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH ; lwIP 2 - Low Memory ; -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY ; lwIP 2 - Higher Bandwidth From fe99143f1c42b9f1c867cfdb8583eb133fe6e7c8 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Jul 2020 09:06:14 +0200 Subject: [PATCH 495/581] Tasmota Core 2.8.0 --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 597c69eff..a8b712779 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,7 +6,7 @@ - [ ] The pull request is done against the latest dev branch - [ ] Only relevant files were touched - [ ] Only one feature/fix was added per PR. - - [ ] The code change is tested and works on core ESP8266 V.2.7.2 + - [ ] The code change is tested and works on Tasmota core ESP8266 V.2.8.0 - [ ] The code change is tested and works on core ESP32 V.1.12.2 - [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). From 02a30ae12bde246db2e3589194d3fb27986ca998 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Jul 2020 12:08:06 +0200 Subject: [PATCH 496/581] Update platformio.ini --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index ad2b13c28..c68991444 100644 --- a/platformio.ini +++ b/platformio.ini @@ -124,6 +124,6 @@ build_flags = -DUSE_IR_REMOTE_FULL [core] ; *** Esp8266 Tasmota modified Arduino core based on core 2.7.2 platform = espressif8266@2.5.1 -platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.8.0-tasmota/esp8266-2.8.0.zip +platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.7.2.1/esp8266-2.7.2.1.zip build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From 19c1bf2d7fd0ffbfe0699796827846cbbd5251b2 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Jul 2020 12:08:51 +0200 Subject: [PATCH 497/581] Update platformio_override_sample.ini --- platformio_override_sample.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 8499764fa..01aa03601 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -88,7 +88,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage platform = espressif8266@2.5.1 -platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.8.0-tasmota/esp8266-2.8.0.zip +platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.7.2.1/esp8266-2.7.2.1.zip build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From f65e4a381faac47a76234b6903cc03a24ba47ea8 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 16 Jul 2020 12:09:22 +0200 Subject: [PATCH 498/581] Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a8b712779..fa3a182c3 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,7 +6,7 @@ - [ ] The pull request is done against the latest dev branch - [ ] Only relevant files were touched - [ ] Only one feature/fix was added per PR. - - [ ] The code change is tested and works on Tasmota core ESP8266 V.2.8.0 + - [ ] The code change is tested and works on Tasmota core ESP8266 V.2.7.2.1 - [ ] The code change is tested and works on core ESP32 V.1.12.2 - [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). From 9d69c36355e03baf61358490085716719782357f Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Thu, 16 Jul 2020 14:24:41 +0200 Subject: [PATCH 499/581] Update Italian language --- tasmota/language/it_IT.h | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 788cee051..3d26d9f09 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -245,22 +245,22 @@ #define D_SECONDS "secondi" #define D_DEVICE_WILL_RESTART "Il dispositivo verrà riavviato tra pochi secondi" #define D_BUTTON_TOGGLE "ON/OFF" -#define D_CONFIGURATION "Configurazione" +#define D_CONFIGURATION "Impostazioni" #define D_INFORMATION "Informazioni" #define D_FIRMWARE_UPGRADE "Aggiorna firmware" #define D_CONSOLE "Console" #define D_CONFIRM_RESTART "Conferma riavvio" -#define D_CONFIGURE_MODULE "Configura modulo" -#define D_CONFIGURE_WIFI "Configura WiFi" -#define D_CONFIGURE_MQTT "Configura MQTT" -#define D_CONFIGURE_DOMOTICZ "Configura Domoticz" -#define D_CONFIGURE_LOGGING "Livello registro" +#define D_CONFIGURE_MODULE "Modulo" +#define D_CONFIGURE_WIFI "Rete WiFi" +#define D_CONFIGURE_MQTT "MQTT" +#define D_CONFIGURE_DOMOTICZ "Domoticz" +#define D_CONFIGURE_LOGGING "Livelli registri" #define D_CONFIGURE_OTHER "Altre impostazioni" -#define D_CONFIRM_RESET_CONFIGURATION "Conferma ripristino configurazione" -#define D_RESET_CONFIGURATION "Ripristino configurazione" -#define D_BACKUP_CONFIGURATION "Backup configurazione" -#define D_RESTORE_CONFIGURATION "Ripristino configurazione" +#define D_CONFIRM_RESET_CONFIGURATION "Conferma ripristino impostazioni" +#define D_RESET_CONFIGURATION "Ripristino impostazioni" +#define D_BACKUP_CONFIGURATION "Backup impostazioni" +#define D_RESTORE_CONFIGURATION "Ripristino impostazioni" #define D_MAIN_MENU "Menu principale" #define D_MODULE_PARAMETERS "Parametri modulo" @@ -291,7 +291,7 @@ #define D_CLIENT "Client" #define D_FULL_TOPIC "Full topic" -#define D_LOGGING_PARAMETERS "Livelli registro eventi" +#define D_LOGGING_PARAMETERS "Livelli registri eventi" #define D_SERIAL_LOG_LEVEL "Livello registro seriale" #define D_MQTT_LOG_LEVEL "Livello registro MQTT" #define D_WEB_LOG_LEVEL "Livello registro web" @@ -313,15 +313,15 @@ #define D_SINGLE_DEVICE "dispositivo singolo" #define D_MULTI_DEVICE "dispositivo multiplo" -#define D_CONFIGURE_TEMPLATE "Configura modello" +#define D_CONFIGURE_TEMPLATE "Modello" #define D_TEMPLATE_PARAMETERS "Parametri modello" #define D_TEMPLATE_NAME "Nome" #define D_BASE_TYPE "Basato su" #define D_TEMPLATE_FLAGS "Opzioni" -#define D_SAVE_CONFIGURATION "Salva configurazione" -#define D_CONFIGURATION_SAVED "Configurazione salvata" -#define D_CONFIGURATION_RESET "Configurazione ripristinata" +#define D_SAVE_CONFIGURATION "Salva impostazioni" +#define D_CONFIGURATION_SAVED "Impostazioni salvate" +#define D_CONFIGURATION_RESET "Impostazioni ripristinate" #define D_PROGRAM_VERSION "Versione programma" #define D_BUILD_DATE_AND_TIME "Data/ora compilazione" @@ -416,7 +416,7 @@ #define D_DOMOTICZ_UPDATE_TIMER "Intervallo aggiornamento" // xdrv_09_timers.ino -#define D_CONFIGURE_TIMER "Configura timer" +#define D_CONFIGURE_TIMER "Timer" #define D_TIMER_PARAMETERS "Parametri timer" #define D_TIMER_ENABLE "Abilita timer" #define D_TIMER_ARM "Attiva" @@ -427,7 +427,7 @@ #define D_TIMER_ACTION "Azione" // xdrv_10_knx.ino -#define D_CONFIGURE_KNX "Configura KNX" +#define D_CONFIGURE_KNX "KNX" #define D_KNX_PARAMETERS "Parametri KNX" #define D_KNX_GENERAL_CONFIG "Generale" #define D_KNX_PHYSICAL_ADDRESS "Indirizzo fisico" @@ -461,7 +461,7 @@ #define D_DOMOTICZ_SHUTTER "Serranda" // xdrv_28_pcf8574.ino -#define D_CONFIGURE_PCF8574 "Configura PCF8574" +#define D_CONFIGURE_PCF8574 "PCF8574" #define D_PCF8574_PARAMETERS "Parametri PCF8574" #define D_INVERT_PORTS "Inverti porte" #define D_DEVICE "Dispositivo" @@ -511,7 +511,7 @@ #define D_HX_CAL_DONE "Calibrato" #define D_HX_CAL_FAIL "Calibrazione fallita" #define D_RESET_HX711 "Ripristino scala" -#define D_CONFIGURE_HX711 "Configura scala" +#define D_CONFIGURE_HX711 "Scala" #define D_HX711_PARAMETERS "Parametri scala" #define D_ITEM_WEIGHT "Peso oggetto" #define D_REFERENCE_WEIGHT "Peso di riferimento" @@ -703,8 +703,8 @@ #define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" #define D_SENSOR_TCP_TXD "TCP - TX" #define D_SENSOR_TCP_RXD "TCP - RX" -#define D_SENSOR_IEM3000_TX "iEM3000 TX" -#define D_SENSOR_IEM3000_RX "iEM3000 RX" +#define D_SENSOR_IEM3000_TX "iEM3000 - TX" +#define D_SENSOR_IEM3000_RX "iEM3000 - RX" // Units #define D_UNIT_AMPERE "A" From 858d1503985b34e33732fba85d16fa4ef5e21c9c Mon Sep 17 00:00:00 2001 From: Walter Zengel Date: Thu, 16 Jul 2020 16:42:06 +0200 Subject: [PATCH 500/581] issues #8866 update tuyatime every 60sec --- tasmota/xdrv_16_tuyamcu.ino | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 7165126f5..47adaaf65 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -62,6 +62,9 @@ struct TUYA { uint8_t data_len = 0; // Data lenght of command uint8_t wifi_state = -2; // Keep MCU wifi-status in sync with WifiState() uint8_t heartbeat_timer = 0; // 10 second heartbeat timer for tuya module +#ifdef USE_TUYA_TIME + uint8_t settime_timer = 0; // 60 second settime timer for tuya module +#endif //USE_TUYA_TIME #ifdef USE_ENERGY_SENSOR uint32_t lastPowerCheckTime = 0; // Time when last power was checked #endif // USE_ENERGY_SENSOR @@ -881,6 +884,13 @@ bool Xdrv16(uint8_t function) Tuya.heartbeat_timer = 0; TuyaSendCmd(TUYA_CMD_HEARTBEAT); } + #ifdef USE_TUYA_TIME + Tuya.settime_timer++; + if (Tuya.settime_timer > 60) { + Tuya.settime_timer = 0; + TuyaSetTime(); + } + #endif } else { TuyaSendLowPowerSuccessIfNeeded(); } From 66b3dc1cf2109ea8fa1bb9a5f6d2e53e12f90e97 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 Jul 2020 16:46:30 +0200 Subject: [PATCH 501/581] Increase TLS fingerprint security --- tasmota/WiFiClientSecureLightBearSSL.cpp | 93 +++++++++++++++++++++++- tasmota/WiFiClientSecureLightBearSSL.h | 5 ++ tasmota/xdrv_02_mqtt.ino | 31 ++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) diff --git a/tasmota/WiFiClientSecureLightBearSSL.cpp b/tasmota/WiFiClientSecureLightBearSSL.cpp index d0907788e..0d69ff810 100755 --- a/tasmota/WiFiClientSecureLightBearSSL.cpp +++ b/tasmota/WiFiClientSecureLightBearSSL.cpp @@ -695,18 +695,56 @@ extern "C" { xc->done_cert = true; // first cert already processed } +// **** Start patch Castellucci +/* static void pubkeyfingerprint_pubkey_fingerprint(br_sha1_context *shactx, br_rsa_public_key rsakey) { br_sha1_init(shactx); br_sha1_update(shactx, "ssh-rsa", 7); // tag br_sha1_update(shactx, rsakey.e, rsakey.elen); // exponent br_sha1_update(shactx, rsakey.n, rsakey.nlen); // modulus } +*/ + // If `compat` id false, adds a u32be length prefixed value to the sha1 state. + // If `compat` is true, the length will be omitted for compatibility with + // data from older versions of Tasmota. + static void sha1_update_len(br_sha1_context *shactx, const void *msg, uint32_t len, bool compat) { + uint8_t buf[] = {0, 0, 0, 0}; + + if (!compat) { + buf[0] = (len >> 24) & 0xff; + buf[1] = (len >> 16) & 0xff; + buf[2] = (len >> 8) & 0xff; + buf[3] = (len >> 0) & 0xff; + br_sha1_update(shactx, buf, 4); // length + } + br_sha1_update(shactx, msg, len); // message + } + + // Update the received fingerprint based on the certificate's public key. + // If `compat` is true, an insecure version of the fingerprint will be + // calcualted for compatibility with older versions of Tasmota. Normally, + // `compat` should be false. + static void pubkeyfingerprint_pubkey_fingerprint(br_x509_pubkeyfingerprint_context *xc, bool compat) { + br_rsa_public_key rsakey = xc->ctx.pkey.key.rsa; + + br_sha1_context shactx; + + br_sha1_init(&shactx); + + sha1_update_len(&shactx, "ssh-rsa", 7, compat); // tag + sha1_update_len(&shactx, rsakey.e, rsakey.elen, compat); // exponent + sha1_update_len(&shactx, rsakey.n, rsakey.nlen, compat); // modulus + + br_sha1_out(&shactx, xc->pubkey_recv_fingerprint); // copy to fingerprint + } +// **** End patch Castellucci // Callback when complete chain has been parsed. // Return 0 on validation success, !0 on validation error static unsigned pubkeyfingerprint_end_chain(const br_x509_class **ctx) { br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - +// **** Start patch Castellucci +/* br_sha1_context sha1_context; pubkeyfingerprint_pubkey_fingerprint(&sha1_context, xc->ctx.pkey.key.rsa); br_sha1_out(&sha1_context, xc->pubkey_recv_fingerprint); // copy to fingerprint @@ -723,6 +761,59 @@ extern "C" { // Default (no validation at all) or no errors in prior checks = success. return 0; } +*/ + // set fingerprint status byte to zero + // FIXME: find a better way to pass this information + xc->pubkey_recv_fingerprint[20] = 0; + // Try matching using the the new fingerprint algorithm + pubkeyfingerprint_pubkey_fingerprint(xc, false); + if (!xc->fingerprint_all) { + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) { + return 0; + } + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) { + return 0; + } + + // No match under new algorithm, do some basic checking on the key. + // + // RSA keys normally have an e value of 65537, which is three bytes long. + // Other e values are suspicious, but if the modulus is a standard size + // (multiple of 512 bits/64 bytes), any public exponent up to eight bytes + // long will be allowed. + // + // A legitimate key could possibly be marked as bad by this check, but + // the user would have had to really worked at making a strange key. + if (!(xc->ctx.pkey.key.rsa.elen == 3 + && xc->ctx.pkey.key.rsa.e[0] == 1 + && xc->ctx.pkey.key.rsa.e[1] == 0 + && xc->ctx.pkey.key.rsa.e[2] == 1)) { + if (xc->ctx.pkey.key.rsa.nlen & 63 != 0 || xc->ctx.pkey.key.rsa.elen > 8) { + return 2; // suspicious key, return error + } + } + + // try the old algorithm and potentially mark for update + pubkeyfingerprint_pubkey_fingerprint(xc, true); + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) { + xc->pubkey_recv_fingerprint[20] |= 1; // mark for update + } + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) { + xc->pubkey_recv_fingerprint[20] |= 2; // mark for update + } + if (!xc->pubkey_recv_fingerprint[20]) { + return 1; // not marked for update because no match, error + } + + // the old fingerprint format matched, recompute new one for update + pubkeyfingerprint_pubkey_fingerprint(xc, false); + + return 0; + } else { + // Default (no validation at all) or no errors in prior checks = success. + return 0; + } +// **** End patch Castellucci } // Return the public key from the validator (set by x509_minimal) diff --git a/tasmota/WiFiClientSecureLightBearSSL.h b/tasmota/WiFiClientSecureLightBearSSL.h index e5908275e..274f1b2dc 100755 --- a/tasmota/WiFiClientSecureLightBearSSL.h +++ b/tasmota/WiFiClientSecureLightBearSSL.h @@ -121,7 +121,12 @@ class WiFiClientSecure_light : public WiFiClient { bool _fingerprint_any; // accept all fingerprints const uint8_t *_fingerprint1; // fingerprint1 to be checked against const uint8_t *_fingerprint2; // fingerprint2 to be checked against +// **** Start patch Castellucci +/* uint8_t _recv_fingerprint[20]; // fingerprint received +*/ + uint8_t _recv_fingerprint[21]; // fingerprint received +// **** End patch Castellucci unsigned char *_recvapp_buf; size_t _recvapp_len; diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 7a7eae075..a24d51de3 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -637,6 +637,8 @@ void MqttReconnect(void) AddLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR("MFLN not supported by TLS server")); } #ifndef USE_MQTT_TLS_CA_CERT // don't bother with fingerprints if using CA validation +// **** Start patch Castellucci +/* // create a printable version of the fingerprint received char buf_fingerprint[64]; ToHex_P((unsigned char *)tlsClient->getRecvPubKeyFingerprint(), 20, buf_fingerprint, sizeof(buf_fingerprint), ' '); @@ -665,6 +667,35 @@ void MqttReconnect(void) SettingsSaveAll(); // save settings } } +*/ + const uint8_t *recv_fingerprint = tlsClient->getRecvPubKeyFingerprint(); + // create a printable version of the fingerprint received + char buf_fingerprint[64]; + ToHex_P(recv_fingerprint, 20, buf_fingerprint, sizeof(buf_fingerprint), ' '); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT "Server fingerprint: %s"), buf_fingerprint); + + bool learned = false; + + // If the fingerprint slot is marked for update, we'll do so. + // Otherwise, if the fingerprint slot had the magic trust-on-first-use + // value, we will save the current fingerprint there, but only if the other fingerprint slot + // *didn't* match it. + if (recv_fingerprint[20] & 0x1 || (learn_fingerprint1 && 0 != memcmp(recv_fingerprint, Settings.mqtt_fingerprint[1], 20))) { + memcpy(Settings.mqtt_fingerprint[0], recv_fingerprint, 20); + learned = true; + } + // As above, but for the other slot. + if (recv_fingerprint[20] & 0x2 || (learn_fingerprint2 && 0 != memcmp(recv_fingerprint, Settings.mqtt_fingerprint[0], 20))) { + memcpy(Settings.mqtt_fingerprint[1], recv_fingerprint, 20); + learned = true; + } + + if (learned) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "Fingerprint learned: %s"), buf_fingerprint); + + SettingsSaveAll(); // save settings + } +// **** End patch Castellucci #endif // !USE_MQTT_TLS_CA_CERT #endif // USE_MQTT_TLS MqttConnected(); From 88138273766bceb6d16b36302aa45a900f03461a Mon Sep 17 00:00:00 2001 From: Walter Zengel Date: Thu, 16 Jul 2020 17:13:19 +0200 Subject: [PATCH 502/581] issues #8866 --- tasmota/xdrv_16_tuyamcu.ino | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 47adaaf65..982a5c796 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -62,9 +62,6 @@ struct TUYA { uint8_t data_len = 0; // Data lenght of command uint8_t wifi_state = -2; // Keep MCU wifi-status in sync with WifiState() uint8_t heartbeat_timer = 0; // 10 second heartbeat timer for tuya module -#ifdef USE_TUYA_TIME - uint8_t settime_timer = 0; // 60 second settime timer for tuya module -#endif //USE_TUYA_TIME #ifdef USE_ENERGY_SENSOR uint32_t lastPowerCheckTime = 0; // Time when last power was checked #endif // USE_ENERGY_SENSOR @@ -543,9 +540,6 @@ void TuyaNormalPowerModePacketProcess(void) if (Tuya.buffer[6] == 0) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Detected MCU restart")); Tuya.wifi_state = -2; - #ifdef USE_TUYA_TIME - TuyaSetTime(); - #endif } break; @@ -885,12 +879,10 @@ bool Xdrv16(uint8_t function) TuyaSendCmd(TUYA_CMD_HEARTBEAT); } #ifdef USE_TUYA_TIME - Tuya.settime_timer++; - if (Tuya.settime_timer > 60) { - Tuya.settime_timer = 0; + if (!(uptime % 60)) { TuyaSetTime(); - } - #endif + } + #endif //USE_TUYA_TIME } else { TuyaSendLowPowerSuccessIfNeeded(); } From 2ad758117d18e7a91bd0706020f4aaac9602589d Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Thu, 16 Jul 2020 17:15:12 +0200 Subject: [PATCH 503/581] scripter add event result --- lib/LinkedList-1.2.3/LinkedList.h | 98 ++++++++++++++++++++++++++++++- tasmota/xdrv_10_scripter.ino | 26 ++++++-- 2 files changed, 118 insertions(+), 6 deletions(-) mode change 100644 => 100755 lib/LinkedList-1.2.3/LinkedList.h diff --git a/lib/LinkedList-1.2.3/LinkedList.h b/lib/LinkedList-1.2.3/LinkedList.h old mode 100644 new mode 100755 index 371b14ac7..64321cf01 --- a/lib/LinkedList-1.2.3/LinkedList.h +++ b/lib/LinkedList-1.2.3/LinkedList.h @@ -39,8 +39,11 @@ protected: ListNode* getNode(int index); + ListNode* findEndOfSortedString(ListNode *p, int (*cmp)(T &, T &)); + public: LinkedList(); + LinkedList(int sizeIndex, T _t); //initiate list size and default value ~LinkedList(); /* @@ -65,7 +68,6 @@ public: virtual bool unshift(T); /* Set the object at index, with T; - Increment _size; */ virtual bool set(int index, T); /* @@ -94,6 +96,16 @@ public: */ virtual void clear(); + /* + Sort the list, given a comparison function + */ + virtual void sort(int (*cmp)(T &, T &)); + + // add support to array brakets [] operator + inline T& operator[](int index); + inline T& operator[](size_t& i) { return this->get(i); } + inline const T& operator[](const size_t& i) const { return this->get(i); } + }; // Initialize LinkedList with false values @@ -157,7 +169,7 @@ ListNode* LinkedList::getNode(int index){ return current; } - return false; + return NULL; } template @@ -165,6 +177,13 @@ int LinkedList::size(){ return _size; } +template +LinkedList::LinkedList(int sizeIndex, T _t){ + for (int i = 0; i < sizeIndex; i++){ + add(_t); + } +} + template bool LinkedList::add(int index, T _t){ @@ -226,6 +245,12 @@ bool LinkedList::unshift(T _t){ return true; } + +template +T& LinkedList::operator[](int index) { + return getNode(index)->data; +} + template bool LinkedList::set(int index, T _t){ // Check if index position is in bounds @@ -322,4 +347,73 @@ void LinkedList::clear(){ shift(); } +template +void LinkedList::sort(int (*cmp)(T &, T &)){ + if(_size < 2) return; // trivial case; + + for(;;) { + + ListNode **joinPoint = &root; + + while(*joinPoint) { + ListNode *a = *joinPoint; + ListNode *a_end = findEndOfSortedString(a, cmp); + + if(!a_end->next ) { + if(joinPoint == &root) { + last = a_end; + isCached = false; + return; + } + else { + break; + } + } + + ListNode *b = a_end->next; + ListNode *b_end = findEndOfSortedString(b, cmp); + + ListNode *tail = b_end->next; + + a_end->next = NULL; + b_end->next = NULL; + + while(a && b) { + if(cmp(a->data, b->data) <= 0) { + *joinPoint = a; + joinPoint = &a->next; + a = a->next; + } + else { + *joinPoint = b; + joinPoint = &b->next; + b = b->next; + } + } + + if(a) { + *joinPoint = a; + while(a->next) a = a->next; + a->next = tail; + joinPoint = &a->next; + } + else { + *joinPoint = b; + while(b->next) b = b->next; + b->next = tail; + joinPoint = &b->next; + } + } + } +} + +template +ListNode* LinkedList::findEndOfSortedString(ListNode *p, int (*cmp)(T &, T &)) { + while(p->next && cmp(p->data, p->next->data) <= 0) { + p = p->next; + } + + return p; +} + #endif diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 06e482a4d..b885feadf 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -194,7 +194,7 @@ void LoadFile(const char *name,uint8_t *buf,uint32_t len) { #define EPOCH_OFFSET 1546300800 enum {OPER_EQU=1,OPER_PLS,OPER_MIN,OPER_MUL,OPER_DIV,OPER_PLSEQU,OPER_MINEQU,OPER_MULEQU,OPER_DIVEQU,OPER_EQUEQU,OPER_NOTEQU,OPER_GRTEQU,OPER_LOWEQU,OPER_GRT,OPER_LOW,OPER_PERC,OPER_XOR,OPER_AND,OPER_OR,OPER_ANDEQU,OPER_OREQU,OPER_XOREQU,OPER_PERCEQU}; -enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD}; +enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD,SCRIPT_EVENT_HANDLED}; #ifdef USE_SCRIPT_FATFS @@ -379,6 +379,7 @@ struct SCRIPT_MEM { #endif } glob_script_mem; +bool event_handeled = false; #ifdef USE_SCRIPT_GLOBVARS @@ -1573,6 +1574,11 @@ chknext: fvar=UtcTime()-(uint32_t)EPOCH_OFFSET; goto exit; } + if (!strncmp(vname,"eres",4)) { + fvar=event_handeled; + tind->index=SCRIPT_EVENT_HANDLED; + goto exit_settable; + } #ifdef USE_ENERGY_SENSOR if (!strncmp(vname,"enrg[",5)) { lp+=5; @@ -3901,6 +3907,9 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) { if (*dfvar>300) *dfvar=300; Settings.tele_period=*dfvar; break; + case SCRIPT_EVENT_HANDLED: + event_handeled=*dfvar; + break; } sysv_type=0; } @@ -4063,7 +4072,9 @@ void ScripterEvery100ms(void) { Run_Scripter(">T",2, mqtt_data); } } - if (fast_script==99) Run_Scripter(">F",2,0); + if (Settings.rule_enabled) { + if (fast_script==99) Run_Scripter(">F",2,0); + } } //mems[5] is 50 bytes in 6.5 @@ -6619,6 +6630,7 @@ void cpy2lf(char *dst,uint32_t dstlen, char *src) { bool Xdrv10(uint8_t function) { bool result = false; + event_handeled = false; char *sprt; switch (function) { @@ -6778,11 +6790,17 @@ bool Xdrv10(uint8_t function) #ifdef SCRIPT_POWER_SECTION if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">P",2,0); #else - if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">E",2,0); + if (bitRead(Settings.rule_enabled, 0)) { + Run_Scripter(">E",2,0); + result=event_handeled; + } #endif break; case FUNC_RULES_PROCESS: - if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">E",2,mqtt_data); + if (bitRead(Settings.rule_enabled, 0)) { + Run_Scripter(">E",2,mqtt_data); + result=event_handeled; + } break; #ifdef USE_WEBSERVER case FUNC_WEB_ADD_BUTTON: From 031b04fb536c5f7dbb5985d401411b0eedf1e2f7 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 Jul 2020 17:28:47 +0200 Subject: [PATCH 504/581] Add check for valid time --- tasmota/xdrv_16_tuyamcu.ino | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 982a5c796..82bc4ef7f 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -802,8 +802,9 @@ void TuyaSetWifiLed(void) } #ifdef USE_TUYA_TIME -void TuyaSetTime(void) -{ +void TuyaSetTime(void) { + if (!RtcTime.valid) { return; } + uint16_t payload_len = 8; uint8_t payload_buffer[8]; payload_buffer[0] = 0x01; @@ -878,13 +879,13 @@ bool Xdrv16(uint8_t function) Tuya.heartbeat_timer = 0; TuyaSendCmd(TUYA_CMD_HEARTBEAT); } - #ifdef USE_TUYA_TIME +#ifdef USE_TUYA_TIME if (!(uptime % 60)) { TuyaSetTime(); } - #endif //USE_TUYA_TIME +#endif //USE_TUYA_TIME } else { - TuyaSendLowPowerSuccessIfNeeded(); + TuyaSendLowPowerSuccessIfNeeded(); } break; case FUNC_SET_CHANNELS: From 29e73b4291fc470981038fca1c6870ff1f2a25ab Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 Jul 2020 17:50:26 +0200 Subject: [PATCH 505/581] Fix GCC 10.1 warning --- tasmota/xsns_40_pn532.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/xsns_40_pn532.ino b/tasmota/xsns_40_pn532.ino index 8218d0b35..3c29d4c82 100644 --- a/tasmota/xsns_40_pn532.ino +++ b/tasmota/xsns_40_pn532.ino @@ -559,6 +559,7 @@ bool PN532_Command(void) return serviced; } } + return false; } #endif // USE_PN532_DATA_FUNCTION From 2705c8eb8bb44b6894e11d2c45260614250a841c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 Jul 2020 18:02:39 +0200 Subject: [PATCH 506/581] Fix GCC 10.1 warnings --- tasmota/xnrg_12_solaxX1.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/xnrg_12_solaxX1.ino b/tasmota/xnrg_12_solaxX1.ino index 418a92acb..513cf1317 100644 --- a/tasmota/xnrg_12_solaxX1.ino +++ b/tasmota/xnrg_12_solaxX1.ino @@ -236,6 +236,7 @@ uint8_t solaxX1_ParseErrorCode(uint32_t code){ if (ErrCode.TemperatureOverFault) return 6; if (ErrCode.FanFault) return 7; if (ErrCode.OtherDeviceFault) return 8; + return 0; } /*********************************************************************************************/ From 6b0870343ba6142e99335632382a8eef30f9c234 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 16 Jul 2020 18:21:19 +0200 Subject: [PATCH 507/581] Change to limited support of Arduino IDE Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE --- FIRMWARE.md | 4 ++-- README.md | 4 ++-- RELEASENOTES.md | 3 ++- tasmota/CHANGELOG.md | 4 ++++ tasmota/tasmota.ino | 27 +++++++++++++++------------ tasmota/tasmota_version.h | 2 +- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/FIRMWARE.md b/FIRMWARE.md index 4feb4126d..d66bd1ba1 100644 --- a/FIRMWARE.md +++ b/FIRMWARE.md @@ -1,14 +1,14 @@ ![Tasmota logo](https://github.com/arendst/Tasmota/blob/development/tools/logo/TASMOTA_FullLogo_Vector.svg) Alternative firmware for [ESP8266](https://en.wikipedia.org/wiki/ESP8266) based devices with **easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX**. -_Written for Arduino IDE and PlatformIO._ +_Written for PlatformIO with limited support for Arduino IDE._ [![GitHub version](https://img.shields.io/github/release/arendst/Tasmota.svg)](https://github.com/arendst/Tasmota/releases/latest) [![GitHub download](https://img.shields.io/github/downloads/arendst/Tasmota/total.svg)](https://github.com/arendst/Tasmota/releases/latest) [![License](https://img.shields.io/github/license/arendst/Tasmota.svg)](LICENSE.txt) [![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4) -If you like **Tasmota**, give it a star, or fork it and contribute! +If you like **Tasmota**, give it a star, or fork it and contribute! [![GitHub stars](https://img.shields.io/github/stars/arendst/Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Tasmota/stargazers) [![GitHub forks](https://img.shields.io/github/forks/arendst/Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Tasmota/network) diff --git a/README.md b/README.md index f5d40a631..19fbff041 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ ![Tasmota logo](/tools/logo/TASMOTA_FullLogo_Vector.svg) Alternative firmware for [ESP8266](https://en.wikipedia.org/wiki/ESP8266) based devices with **easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX**. -_Written for Arduino IDE and PlatformIO._ +_Written for PlatformIO with limited support for Arduino IDE._ [![GitHub version](https://img.shields.io/github/release/arendst/Tasmota.svg)](https://github.com/arendst/Tasmota/releases/latest) [![GitHub download](https://img.shields.io/github/downloads/arendst/Tasmota/total.svg)](https://github.com/arendst/Tasmota/releases/latest) [![License](https://img.shields.io/github/license/arendst/Tasmota.svg)](LICENSE.txt) [![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4) -If you like **Tasmota**, give it a star, or fork it and contribute! +If you like **Tasmota**, give it a star, or fork it and contribute! [![GitHub stars](https://img.shields.io/github/stars/arendst/Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Tasmota/stargazers) [![GitHub forks](https://img.shields.io/github/forks/arendst/Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Tasmota/network) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 12b3a5b24..57d7d68f0 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,8 +52,9 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.3.1.6 +### Version 8.3.1.7 +- Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE - Change IRremoteESP8266 library from v2.7.6 to v2.7.8 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 854969579..e397e2cc3 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased (development) +### 8.3.1.7 20200716 + +- Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE + ### 8.3.1.6 20200617 - Add command ``Module2`` to configure fallback module on fast reboot (#8464) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index bf669aed5..1da4e7606 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -16,19 +16,22 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -/*==================================================== - Prerequisites: - - Change libraries/PubSubClient/src/PubSubClient.h - #define MQTT_MAX_PACKET_SIZE 1200 - Arduino IDE 1.8.12 and up parameters - - Select IDE Tools - Board: "Generic ESP8266 Module" - - Select IDE Tools - Flash Mode: "DOUT (compatible)" - - Select IDE Tools - Flash Size: "1M (FS:none OTA:~502KB)" - - Select IDE Tools - LwIP Variant: "v2 Higher Bandwidth (no feature)" - - Select IDE Tools - VTables: "Flash" - - Select IDE Tools - Espressif FW: "nonos-sdk-2.2.1+100 (190703)" - ====================================================*/ +/*********************************************************************************************\ + * Preferred IDE is Visual Studio Code with PlatformIO extension which doesn't need prerequisites + * + * Limited support for Arduino IDE needs Prerequisites: + * - Change libraries/PubSubClient/src/PubSubClient.h + * #define MQTT_MAX_PACKET_SIZE 1200 + * + * Arduino IDE 1.8.12 and up parameters for partly support + * - Select IDE Tools - Board: "Generic ESP8266 Module" + * - Select IDE Tools - Flash Mode: "DOUT (compatible)" + * - Select IDE Tools - Flash Size: "1M (FS:none OTA:~502KB)" + * - Select IDE Tools - LwIP Variant: "v2 Higher Bandwidth (no feature)" + * - Select IDE Tools - VTables: "Flash" + * - Select IDE Tools - Espressif FW: "nonos-sdk-2.2.1+100 (190703)" +\*********************************************************************************************/ // Location specific includes #include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0) diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 6b64471b0..23105273e 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08030106; +const uint32_t VERSION = 0x08030107; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; From 934ca43463e33799ca023453a7b78757f09f7394 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Jul 2020 11:49:56 +0200 Subject: [PATCH 508/581] Remove Arduino ESP8266 Core support before 2.7.1 Remove Arduino ESP8266 Core support for versions before 2.7.1 --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/WiFiClientSecureLightBearSSL.cpp | 12 -- tasmota/sendemail.h | 4 - tasmota/settings.ino | 14 --- tasmota/support.ino | 8 +- tasmota/support_flash_log.ino | 4 - tasmota/support_float.ino | 4 - tasmota/support_legacy_cores.ino | 141 ----------------------- tasmota/support_tasmota.ino | 8 -- tasmota/support_wifi.ino | 11 -- tasmota/tasmota.ino | 9 +- tasmota/tasmota_configurations.h | 2 - tasmota/tasmota_globals.h | 4 +- tasmota/xdrv_01_webserver.ino | 34 +----- tasmota/xdrv_02_mqtt.ino | 4 - tasmota/xdrv_10_scripter.ino | 26 +---- tasmota/xdrv_26_ariluxrf.ino | 2 - tasmota/xdrv_99_debug.ino | 20 ---- tasmota/xsns_01_counter.ino | 18 +-- tasmota/xsns_35_tx20.ino | 6 +- tasmota/xsns_53_sml.ino | 19 +-- tasmota/xsns_68_windmeter.ino | 6 +- tasmota/xsns_74_lmt01.ino | 8 +- 24 files changed, 24 insertions(+), 342 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 57d7d68f0..ddb4bc8b2 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -54,6 +54,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ### Version 8.3.1.7 +- Remove Arduino ESP8266 Core support for versions before 2.7.1 - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE - Change IRremoteESP8266 library from v2.7.6 to v2.7.8 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index e397e2cc3..b67609a80 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -2,6 +2,7 @@ ### 8.3.1.7 20200716 +- Remove Arduino ESP8266 Core support for versions before 2.7.1 - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE ### 8.3.1.6 20200617 diff --git a/tasmota/WiFiClientSecureLightBearSSL.cpp b/tasmota/WiFiClientSecureLightBearSSL.cpp index 0d69ff810..7b92d4b6e 100755 --- a/tasmota/WiFiClientSecureLightBearSSL.cpp +++ b/tasmota/WiFiClientSecureLightBearSSL.cpp @@ -50,9 +50,7 @@ extern "C" { #include "c_types.h" #include -#ifndef ARDUINO_ESP8266_RELEASE_2_5_2 #undef DEBUG_TLS -#endif #ifdef DEBUG_TLS #include "coredecls.h" @@ -255,24 +253,14 @@ void WiFiClientSecure_light::setBufferSizes(int recv, int xmit) { } bool WiFiClientSecure_light::stop(unsigned int maxWaitMs) { -#ifdef ARDUINO_ESP8266_RELEASE_2_4_2 - WiFiClient::stop(); // calls our virtual flush() - _freeSSL(); - return true; -#else bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush() _freeSSL(); return ret; -#endif } bool WiFiClientSecure_light::flush(unsigned int maxWaitMs) { (void) _run_until(BR_SSL_SENDAPP); -#ifdef ARDUINO_ESP8266_RELEASE_2_4_2 - WiFiClient::flush(); -#else return WiFiClient::flush(maxWaitMs); -#endif } int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) { diff --git a/tasmota/sendemail.h b/tasmota/sendemail.h index d95ba9311..7b168b498 100644 --- a/tasmota/sendemail.h +++ b/tasmota/sendemail.h @@ -25,12 +25,8 @@ class SendEmail const bool ssl; const int auth_used; #ifdef ESP8266 -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) - WiFiClient* client; -#else // use bear ssl BearSSL::WiFiClientSecure_light *client; -#endif #else WiFiClient *client; #endif diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 1d7ab6d04..39b1249ad 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -159,14 +159,6 @@ extern "C" { #ifdef ESP8266 -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) || defined(ARDUINO_ESP8266_RELEASE_2_5_0) || defined(ARDUINO_ESP8266_RELEASE_2_5_1) || defined(ARDUINO_ESP8266_RELEASE_2_5_2) - -extern "C" uint32_t _SPIFFS_end; -// From libraries/EEPROM/EEPROM.cpp EEPROMClass -const uint32_t SPIFFS_END = ((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE; - -#else // Core > 2.5.2 and STAGE - #if AUTOFLASHSIZE #include "flash_hal.h" @@ -187,8 +179,6 @@ const uint32_t SPIFFS_END = ((uint32_t)&_FS_end - 0x40200000) / SPI_FLASH_SEC_SI // Version 4.2 config = eeprom area const uint32_t SETTINGS_LOCATION = SPIFFS_END; // No need for SPIFFS as it uses EEPROM area -#endif // ESP8266 - // Version 5.2 allow for more flash space const uint8_t CFG_ROTATES = 8; // Number of flash sectors used (handles uploads) @@ -632,11 +622,7 @@ void EspErase(uint32_t start_sector, uint32_t end_sector) // bool result = EsptoolEraseSector(sector); // Esptool - erases flash completely (slow) if (serial_output) { -#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 - Serial.printf(D_LOG_APPLICATION D_ERASED_SECTOR " %d %s\n", sector, (result) ? D_OK : D_ERROR); -#else Serial.printf_P(PSTR(D_LOG_APPLICATION D_ERASED_SECTOR " %d %s\n"), sector, (result) ? D_OK : D_ERROR); -#endif delay(10); } else { yield(); diff --git a/tasmota/support.ino b/tasmota/support.ino index 1d05ae2d1..50cc4f920 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1080,12 +1080,8 @@ int ResponseJsonEndEnd(void) * GPIO Module and Template management \*********************************************************************************************/ -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception -uint32_t Pin(uint32_t gpio, uint32_t index) ICACHE_RAM_ATTR; -#endif - -uint32_t Pin(uint32_t gpio, uint32_t index = 0); -uint32_t Pin(uint32_t gpio, uint32_t index) { +uint32_t ICACHE_RAM_ATTR Pin(uint32_t gpio, uint32_t index = 0); +uint32_t ICACHE_RAM_ATTR Pin(uint32_t gpio, uint32_t index) { #ifdef ESP8266 uint16_t real_gpio = gpio + index; #else // ESP32 diff --git a/tasmota/support_flash_log.ino b/tasmota/support_flash_log.ino index 5f73c4078..5055e5f21 100644 --- a/tasmota/support_flash_log.ino +++ b/tasmota/support_flash_log.ino @@ -112,11 +112,7 @@ DEBUG_SENSOR_LOG(PSTR("FLOG: init ...")); size = ESP.getSketchSize(); // round one sector up start = (size + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) || defined(ARDUINO_ESP8266_RELEASE_2_5_0) || defined(ARDUINO_ESP8266_RELEASE_2_5_1) || defined(ARDUINO_ESP8266_RELEASE_2_5_2) -end = (uint32_t)&_SPIFFS_start - 0x40200000; -#else // Core > 2.5.2 and STAGE end = (uint32_t)&_FS_start - 0x40200000; -#endif num_sectors = (end - start)/FLASH_SECTOR_SIZE; DEBUG_SENSOR_LOG(PSTR("FLOG: size: 0x%lx, start: 0x%lx, end: 0x%lx, num_sectors(dec): %lu"), size, start, end, num_sectors ); _findFirstErasedSector(); diff --git a/tasmota/support_float.ino b/tasmota/support_float.ino index a72712632..b99b95cd2 100644 --- a/tasmota/support_float.ino +++ b/tasmota/support_float.ino @@ -17,9 +17,6 @@ along with this program. If not, see . */ -//#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 -// Functions not available in 2.3.0 - float fmodf(float x, float y) { // https://github.com/micropython/micropython/blob/master/lib/libm/fmodf.c @@ -83,7 +80,6 @@ float fmodf(float x, float y) ux.i = uxi; return ux.f; } -//#endif // ARDUINO_ESP8266_RELEASE_2_3_0 double FastPrecisePow(double a, double b) { diff --git a/tasmota/support_legacy_cores.ino b/tasmota/support_legacy_cores.ino index 46546ff1d..e9a78e5ee 100644 --- a/tasmota/support_legacy_cores.ino +++ b/tasmota/support_legacy_cores.ino @@ -17,147 +17,6 @@ along with this program. If not, see . */ -#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 -/*********************************************************************************************\ - * Functions not available in core 2.3.0 -\*********************************************************************************************/ - -// http://clc-wiki.net/wiki/C_standard_library:string.h:memchr -void* memchr(const void* ptr, int value, size_t num) -{ - unsigned char *p = (unsigned char*)ptr; - while (num--) { - if (*p != (unsigned char)value) { - p++; - } else { - return p; - } - } - return 0; -} - -// http://clc-wiki.net/wiki/C_standard_library:string.h:strcspn -// Get span until any character in string -size_t strcspn(const char *str1, const char *str2) -{ - size_t ret = 0; - while (*str1) { - if (strchr(str2, *str1)) { // Slow - return ret; - } else { - str1++; - ret++; - } - } - return ret; -} - -// https://clc-wiki.net/wiki/C_standard_library:string.h:strpbrk -// Locate the first occurrence in the string pointed to by s1 of any character from the string pointed to by s2 -char* strpbrk(const char *s1, const char *s2) -{ - while(*s1) { - if (strchr(s2, *s1++)) { - return (char*)--s1; - } - } - return 0; -} - -// https://opensource.apple.com/source/Libc/Libc-583/stdlib/FreeBSD/strtoull.c -// Convert a string to an unsigned long long integer -#ifndef __LONG_LONG_MAX__ -#define __LONG_LONG_MAX__ 9223372036854775807LL -#endif -#ifndef ULLONG_MAX -#define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1) -#endif - -unsigned long long strtoull(const char *__restrict nptr, char **__restrict endptr, int base) -{ - const char *s = nptr; - char c; - do { c = *s++; } while (isspace((unsigned char)c)); // Trim leading spaces - - int neg = 0; - if (c == '-') { // Set minus flag and/or skip sign - neg = 1; - c = *s++; - } else { - if (c == '+') { - c = *s++; - } - } - - if ((base == 0 || base == 16) && (c == '0') && (*s == 'x' || *s == 'X')) { // Set Hexadecimal - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) { base = (c == '0') ? 8 : 10; } // Set Octal or Decimal - - unsigned long long acc = 0; - int any = 0; - if (base > 1 && base < 37) { - unsigned long long cutoff = ULLONG_MAX / base; - int cutlim = ULLONG_MAX % base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else - break; - - if (c >= base) - break; - - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = ULLONG_MAX; // Range error - } - else if (any && neg) { - acc = -acc; - } - } - - if (endptr != nullptr) { *endptr = (char *)(any ? s - 1 : nptr); } - - return acc; -} - -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 - - - -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) || defined(ARDUINO_ESP8266_RELEASE_2_5_0) || defined(ARDUINO_ESP8266_RELEASE_2_5_1) || defined(ARDUINO_ESP8266_RELEASE_2_5_2) -/*********************************************************************************************\ - * Functions not available in core before 2.6.0 -\*********************************************************************************************/ - -// https://github.com/arendst/Tasmota/issues/6856#issuecomment-554258914 -void* memmove_P(void *dest, const void *src, size_t n) -{ - if (src > (void*)0x40000000) { - return memcpy_P(dest, src, n); - } else { - return memmove(dest, src, n); - } -} - -#endif // ARDUINO_ESP8266_RELEASE < 2_6_0 - - - /*********************************************************************************************\ * Core overrides \*********************************************************************************************/ diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 70d7f66af..0fbcbb615 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -852,11 +852,8 @@ void PerformEverySecond(void) } } -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Wifi keep alive to send Gratuitous ARP wifiKeepAlive(); -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 - #ifdef ESP32 if (11 == uptime) { // Perform one-time ESP32 houskeeping @@ -1027,13 +1024,8 @@ void Every250mSeconds(void) } #endif // FIRMWARE_MINIMAL AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "%s"), mqtt_data); -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) - ota_result = (HTTP_UPDATE_FAILED != ESPhttpUpdate.update(mqtt_data)); -#else - // If using core stage or 2.5.0+ the syntax has changed WiFiClient OTAclient; ota_result = (HTTP_UPDATE_FAILED != ESPhttpUpdate.update(OTAclient, mqtt_data)); -#endif if (!ota_result) { #ifndef FIRMWARE_MINIMAL int ota_error = ESPhttpUpdate.getLastError(); diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino index 75de2523f..3274cfc4b 100644 --- a/tasmota/support_wifi.ino +++ b/tasmota/support_wifi.ino @@ -153,14 +153,11 @@ void WiFiSetSleepMode(void) */ // Sleep explanation: https://github.com/esp8266/Arduino/blob/3f0c601cfe81439ce17e9bd5d28994a7ed144482/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L255 -#if defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) -#else // Enabled in 2.3.0, 2.4.0 and stage if (ssleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times } else { WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) } -#endif WifiSetOutputPower(); } @@ -172,12 +169,6 @@ void WifiBegin(uint8_t flag, uint8_t channel) UdpDisconnect(); #endif // USE_EMULATION -#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 // (!strncmp_P(ESP.getSdkVersion(),PSTR("1.5.3"),5)) - AddLog_P(LOG_LEVEL_DEBUG, S_LOG_WIFI, PSTR(D_PATCH_ISSUE_2186)); -// WiFi.mode(WIFI_OFF); // See https://github.com/esp8266/Arduino/issues/2186 - WifiSetMode(WIFI_OFF); -#endif - WiFi.persistent(false); // Solve possible wifi init errors (re-add at 6.2.1.16 #4044, #4083) WiFi.disconnect(true); // Delete SDK wifi config delay(200); @@ -652,7 +643,6 @@ void EspRestart(void) ESP_Restart(); } -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // // Gratuitous ARP, backported from https://github.com/esp8266/Arduino/pull/6889 // @@ -700,4 +690,3 @@ void wifiKeepAlive(void) { SetNextTimeInterval(wifiTimer, wifiTimerSec * 1000); } } -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 1da4e7606..43e019e33 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -34,7 +34,7 @@ \*********************************************************************************************/ // Location specific includes -#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0) +#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_7_1) #include "tasmota_compat.h" #include "tasmota_version.h" // Tasmota version information #include "tasmota.h" // Enumeration used in my_user_config.h @@ -46,13 +46,6 @@ #include "i18n.h" // Language support configured by my_user_config.h #include "tasmota_template.h" // Hardware configuration -#ifdef ARDUINO_ESP8266_RELEASE_2_4_0 -#include "lwip/init.h" -#if LWIP_VERSION_MAJOR != 1 - #error Please use stable lwIP v1.4 -#endif -#endif - // Libraries #include // Ota #include // Ota diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 58d08d543..ad9d64d08 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -280,13 +280,11 @@ #define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC) #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code) -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // There is not enough spare RAM with core 2.3.0 to support the following #define USE_DISPLAY_EPAPER_29 // [DisplayModel 5] Enable e-paper 2.9 inch display (+19k code) #define USE_DISPLAY_EPAPER_42 // [DisplayModel 6] Enable e-paper 4.2 inch display // #define USE_DISPLAY_ILI9488 // [DisplayModel 8] // #define USE_DISPLAY_SSD1351 // [DisplayModel 9] // #define USE_DISPLAY_RA8876 // [DisplayModel 10] -#endif #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 42e63f206..e4312d0b3 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -128,8 +128,8 @@ String EthernetMacAddress(void); const uint16_t WEB_LOG_SIZE = 4000; // Max number of characters in weblog #endif -#if defined(USE_TLS) && defined(ARDUINO_ESP8266_RELEASE_2_3_0) - #error "TLS is no more supported on Core 2.3.0, use 2.4.2 or higher." +#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) || defined(ARDUINO_ESP8266_RELEASE_2_5_0) || defined(ARDUINO_ESP8266_RELEASE_2_5_1) || defined(ARDUINO_ESP8266_RELEASE_2_5_2) + #error "Arduino ESP8266 Core versions before 2.7.1 are not supported" #endif #ifndef MQTT_MAX_PACKET_SIZE diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 8ba98f91e..e42b17db4 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -913,14 +913,8 @@ void WifiManagerBegin(bool reset_only) int channel = WIFI_SOFT_AP_CHANNEL; if ((channel < 1) || (channel > 13)) { channel = 1; } -#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 - // bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0); - WiFi.softAP(my_hostname, WIFI_AP_PASSPHRASE, channel, 0); -#else // bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4); WiFi.softAP(my_hostname, WIFI_AP_PASSPHRASE, channel, 0, 1); -#endif - delay(500); // Without delay I've seen the IP address blank /* Setup the DNS server redirecting all the domains to the apIP */ DnsServer->setErrorReplyCode(DNSReplyCode::NoError); @@ -992,10 +986,6 @@ void WSContentBegin(int code, int ctype) { Webserver->client().flush(); WSHeaderSend(); -#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 - Webserver->sendHeader(F("Accept-Ranges"),F("none")); - Webserver->sendHeader(F("Transfer-Encoding"),F("chunked")); -#endif Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN); WSSend(code, ctype, ""); // Signal start of chunked content Web.chunk_buffer = ""; @@ -1004,15 +994,7 @@ void WSContentBegin(int code, int ctype) void _WSContentSend(const String& content) // Low level sendContent for all core versions { size_t len = content.length(); - -#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 - const char * footer = "\r\n"; - char chunk_size[11]; - sprintf(chunk_size, "%x\r\n", len); - Webserver->sendContent(String() + chunk_size + content + footer); -#else Webserver->sendContent(content); -#endif #ifdef USE_DEBUG_DRIVER ShowFreeMem(PSTR("WSContentSend")); @@ -1377,7 +1359,7 @@ void HandleRoot(void) "c", // c - Unique HTML id "#000", "#fff", // Black to White 4, // sl4 - Unique range HTML id - Used as source for Saturation begin color - Settings.flag3.slider_dimmer_stay_on, 100, // Range 0/1 to 100% + Settings.flag3.slider_dimmer_stay_on, 100, // Range 0/1 to 100% (SetOption77 - Do not power off if slider moved to far left) Settings.light_dimmer, 'd', 0); // d0 - Value id is related to lc("d0", value) and WebGetArg("d0", tmp, sizeof(tmp)); @@ -1389,7 +1371,7 @@ void HandleRoot(void) "f", // f - Unique HTML id "#000", "#fff", // Black to White 5, // sl5 - Unique range HTML id - Not used - Settings.flag3.slider_dimmer_stay_on, 100, // Range 0/1 to 100% + Settings.flag3.slider_dimmer_stay_on, 100, // Range 0/1 to 100% (SetOption77 - Do not power off if slider moved to far left) LightGetDimmer(2), 'w', 0); // w0 - Value id is related to lc("w0", value) and WebGetArg("w0", tmp, sizeof(tmp)); } @@ -2367,14 +2349,7 @@ void HandleBackupConfiguration(void) } } -#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 - size_t written = myClient.write((const char*)settings_buffer, sizeof(Settings)); - if (written < sizeof(Settings)) { // https://github.com/esp8266/Arduino/issues/3218 - myClient.write((const char*)settings_buffer +written, sizeof(Settings) -written); - } -#else myClient.write((const char*)settings_buffer, sizeof(Settings)); -#endif SettingsBufferFree(); @@ -3152,14 +3127,9 @@ int WebSend(char *buffer) DEBUG_CORE_LOG(PSTR("WEB: Uri |%s|"), url.c_str()); -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) - HTTPClient http; - if (http.begin(UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| -#else WiFiClient http_client; HTTPClient http; if (http.begin(http_client, UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| -#endif int http_code = http.GET(); // Start connection and send HTTP header if (http_code > 0) { // http_code will be negative on error if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) { diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index a24d51de3..1f232cff8 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -1217,11 +1217,7 @@ void CmndTlsDump(void) { uint32_t end = start + tls_block_len -1; for (uint32_t pos = start; pos < end; pos += 0x10) { uint32_t* values = (uint32_t*)(pos); -#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 - Serial.printf("%08x: %08x %08x %08x %08x\n", pos, bswap32(values[0]), bswap32(values[1]), bswap32(values[2]), bswap32(values[3])); -#else Serial.printf_P(PSTR("%08x: %08x %08x %08x %08x\n"), pos, bswap32(values[0]), bswap32(values[1]), bswap32(values[2]), bswap32(values[3])); -#endif } } #endif // DEBUG_DUMP_TLS diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index b885feadf..922e75ebc 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -1164,11 +1164,9 @@ uint32_t pulse_ltime_hl; uint32_t pulse_ltime_lh; uint8_t pt_pin; -void MP_Timer(void) ICACHE_RAM_ATTR; - #define MPT_DEBOUNCE 10 -void MP_Timer(void) { +void ICACHE_RAM_ATTR MP_Timer(void) { uint32_t level = digitalRead(pt_pin&0x3f); uint32_t ms = millis(); uint32_t time; @@ -2899,19 +2897,6 @@ char *getop(char *lp, uint8_t *operand) { #ifdef ESP8266 -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) -// All version before core 2.4.2 -// https://github.com/esp8266/Arduino/issues/2557 -extern "C" { -#include - extern cont_t g_cont; -} -uint16_t GetStack(void) { - register uint32_t *sp asm("a1"); - return (4 * (sp - g_cont.stack)); -} - -#else extern "C" { #include extern cont_t* g_pcont; @@ -2920,7 +2905,6 @@ uint16_t GetStack(void) { register uint32_t *sp asm("a1"); return (4 * (sp - g_pcont->stack)); } -#endif #else uint16_t GetStack(void) { register uint8_t *sp asm("a1"); @@ -4349,18 +4333,10 @@ uint8_t reject(char *name) { if (*name=='_') return 1; if (*name=='.') return 1; -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 if (!strncasecmp(name,"SPOTLI~1",REJCMPL)) return 1; if (!strncasecmp(name,"TRASHE~1",REJCMPL)) return 1; if (!strncasecmp(name,"FSEVEN~1",REJCMPL)) return 1; if (!strncasecmp(name,"SYSTEM~1",REJCMPL)) return 1; -#else - if (!strcasecmp(name,"SPOTLI~1")) return 1; - if (!strcasecmp(name,"TRASHE~1")) return 1; - if (!strcasecmp(name,"FSEVEN~1")) return 1; - if (!strcasecmp(name,"SYSTEM~1")) return 1; -#endif - if (!strncasecmp(name,"System Volume",13)) return 1; return 0; } diff --git a/tasmota/xdrv_26_ariluxrf.ino b/tasmota/xdrv_26_ariluxrf.ino index 5027dfdcb..b0f20e8a6 100644 --- a/tasmota/xdrv_26_ariluxrf.ino +++ b/tasmota/xdrv_26_ariluxrf.ino @@ -45,11 +45,9 @@ struct ARILUX { uint8_t rf_toggle = 0; } Arilux; -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception #ifndef USE_WS2812_DMA // Collides with Neopixelbus but solves RF misses void AriluxRfInterrupt(void) ICACHE_RAM_ATTR; // As iram is tight and it works this way too #endif // USE_WS2812_DMA -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 void AriluxRfInterrupt(void) { diff --git a/tasmota/xdrv_99_debug.ino b/tasmota/xdrv_99_debug.ino index 08f451c30..7471d3095 100644 --- a/tasmota/xdrv_99_debug.ino +++ b/tasmota/xdrv_99_debug.ino @@ -189,24 +189,6 @@ void CpuLoadLoop(void) /*******************************************************************************************/ #ifdef ESP8266 -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) -// All version before core 2.4.2 -// https://github.com/esp8266/Arduino/issues/2557 - -extern "C" { -#include - extern cont_t g_cont; -} - -void DebugFreeMem(void) -{ - register uint32_t *sp asm("a1"); - -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d, UnmodifiedStack %d (%s)"), ESP.getFreeHeap(), 4 * (sp - g_cont.stack), cont_get_free_stack(&g_cont), XdrvMailbox.data); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"), ESP.getFreeHeap(), 4 * (sp - g_cont.stack), XdrvMailbox.data); -} - -#else // All version from core 2.4.2 // https://github.com/esp8266/Arduino/pull/5018 // https://github.com/esp8266/Arduino/pull/4553 @@ -223,8 +205,6 @@ void DebugFreeMem(void) AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"), ESP.getFreeHeap(), 4 * (sp - g_pcont->stack), XdrvMailbox.data); } -#endif // ARDUINO_ESP8266_RELEASE_2_x_x - #else // ESP32 void DebugFreeMem(void) diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index ae03ef324..48452752f 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -47,15 +47,7 @@ struct COUNTER { uint32_t last_cycle; uint32_t cycle_time; -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception -void CounterUpdate(uint8_t index) ICACHE_RAM_ATTR; -void CounterUpdate1(void) ICACHE_RAM_ATTR; -void CounterUpdate2(void) ICACHE_RAM_ATTR; -void CounterUpdate3(void) ICACHE_RAM_ATTR; -void CounterUpdate4(void) ICACHE_RAM_ATTR; -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 - -void CounterUpdate(uint8_t index) +void ICACHE_RAM_ATTR CounterUpdate(uint8_t index) { uint32_t time = micros(); uint32_t debounce_time; @@ -125,22 +117,22 @@ void CounterUpdate(uint8_t index) } } -void CounterUpdate1(void) +void ICACHE_RAM_ATTR CounterUpdate1(void) { CounterUpdate(0); } -void CounterUpdate2(void) +void ICACHE_RAM_ATTR CounterUpdate2(void) { CounterUpdate(1); } -void CounterUpdate3(void) +void ICACHE_RAM_ATTR CounterUpdate3(void) { CounterUpdate(2); } -void CounterUpdate4(void) +void ICACHE_RAM_ATTR CounterUpdate4(void) { CounterUpdate(3); } diff --git a/tasmota/xsns_35_tx20.ino b/tasmota/xsns_35_tx20.ino index cf41a41fb..3ab33e402 100644 --- a/tasmota/xsns_35_tx20.ino +++ b/tasmota/xsns_35_tx20.ino @@ -150,11 +150,7 @@ uint32_t tx2x_last_available = 0; uint32_t tx23_stage = 0; #endif // USE_TX23_WIND_SENSOR -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception -void TX2xStartRead(void) ICACHE_RAM_ATTR; // As iram is tight and it works this way too -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 - -void TX2xStartRead(void) +void ICACHE_RAM_ATTR TX2xStartRead(void) { /** * La Crosse TX20 Anemometer datagram every 2 seconds diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index a75a8fbd8..66981d2ba 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -1811,16 +1811,7 @@ struct SML_COUNTER { #endif } sml_counters[MAX_COUNTERS]; - -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception -void SML_CounterUpd(uint8_t index) ICACHE_RAM_ATTR; -void SML_CounterUpd1(void) ICACHE_RAM_ATTR; -void SML_CounterUpd2(void) ICACHE_RAM_ATTR; -void SML_CounterUpd3(void) ICACHE_RAM_ATTR; -void SML_CounterUpd4(void) ICACHE_RAM_ATTR; -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 - -void SML_CounterUpd(uint8_t index) { +void ICACHE_RAM_ATTR SML_CounterUpd(uint8_t index) { uint8_t level=digitalRead(meter_desc_p[sml_counters[index].sml_cnt_old_state].srcpin); if (!level) { @@ -1838,19 +1829,19 @@ void SML_CounterUpd(uint8_t index) { } } -void SML_CounterUpd1(void) { +void ICACHE_RAM_ATTR SML_CounterUpd1(void) { SML_CounterUpd(0); } -void SML_CounterUpd2(void) { +void ICACHE_RAM_ATTR SML_CounterUpd2(void) { SML_CounterUpd(1); } -void SML_CounterUpd3(void) { +void ICACHE_RAM_ATTR SML_CounterUpd3(void) { SML_CounterUpd(2); } -void SML_CounterUpd4(void) { +void ICACHE_RAM_ATTR SML_CounterUpd4(void) { SML_CounterUpd(3); } diff --git a/tasmota/xsns_68_windmeter.ino b/tasmota/xsns_68_windmeter.ino index 5487c898c..677cfc8b3 100644 --- a/tasmota/xsns_68_windmeter.ino +++ b/tasmota/xsns_68_windmeter.ino @@ -72,11 +72,7 @@ struct WINDMETER { #endif // USE_WINDMETER_NOSTATISTICS } WindMeter; -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception -void WindMeterUpdateSpeed(void) ICACHE_RAM_ATTR; -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 - -void WindMeterUpdateSpeed(void) +void ICACHE_RAM_ATTR WindMeterUpdateSpeed(void) { uint32_t time = micros(); uint32_t time_diff = time - WindMeter.counter_time; diff --git a/tasmota/xsns_74_lmt01.ino b/tasmota/xsns_74_lmt01.ino index d52e6dae2..522b82281 100644 --- a/tasmota/xsns_74_lmt01.ino +++ b/tasmota/xsns_74_lmt01.ino @@ -40,13 +40,9 @@ void LMT01_Init(void) { } } -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception -void LMT01_countPulse(void) ICACHE_RAM_ATTR; -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 - volatile int lmt01_pulseCount = 0; -void LMT01_countPulse(void) { +void ICACHE_RAM_ATTR LMT01_countPulse(void) { lmt01_pulseCount++; } @@ -81,7 +77,7 @@ int LMT01_getPulses(void) { hold = lmt01_pulseCount; delay(1); } - // discard spurious low counts + // discard spurious low counts if (timeout > 0 && hold >= 10) { return hold; } From a9b05b08842d31b343b5da2239fb583712748d7a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Jul 2020 12:37:21 +0200 Subject: [PATCH 509/581] Change to attachInterruptArg() Change to attachInterruptArg() saving 76 bytes --- tasmota/xsns_01_counter.ino | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index 48452752f..dde9a420e 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -36,6 +36,8 @@ const char kCounterCommands[] PROGMEM = D_PRFX_COUNTER "|" // Prefix void (* const CounterCommand[])(void) PROGMEM = { &CmndCounter, &CmndCounterType, &CmndCounterDebounce, &CmndCounterDebounceLow, &CmndCounterDebounceHigh }; +uint8_t ctr_index[MAX_COUNTERS] = { 0, 1, 2, 3 }; + struct COUNTER { uint32_t timer[MAX_COUNTERS]; // Last counter time in micro seconds uint32_t timer_low_high[MAX_COUNTERS]; // Last low/high counter time in micro seconds @@ -47,8 +49,10 @@ struct COUNTER { uint32_t last_cycle; uint32_t cycle_time; -void ICACHE_RAM_ATTR CounterUpdate(uint8_t index) -{ +//void ICACHE_RAM_ATTR CounterUpdate(uint8_t index) { +void ICACHE_RAM_ATTR CounterIsrArg(void *arg) { + uint32_t index = *static_cast(arg); + uint32_t time = micros(); uint32_t debounce_time; @@ -116,7 +120,7 @@ void ICACHE_RAM_ATTR CounterUpdate(uint8_t index) } } } - +/* void ICACHE_RAM_ATTR CounterUpdate1(void) { CounterUpdate(0); @@ -136,7 +140,7 @@ void ICACHE_RAM_ATTR CounterUpdate4(void) { CounterUpdate(3); } - +*/ /********************************************************************************************/ bool CounterPinState(void) @@ -151,8 +155,8 @@ bool CounterPinState(void) void CounterInit(void) { - typedef void (*function) () ; - function counter_callbacks[] = { CounterUpdate1, CounterUpdate2, CounterUpdate3, CounterUpdate4 }; +// typedef void (*function) () ; +// function counter_callbacks[] = { CounterUpdate1, CounterUpdate2, CounterUpdate3, CounterUpdate4 }; for (uint32_t i = 0; i < MAX_COUNTERS; i++) { if (PinUsed(GPIO_CNTR1, i)) { @@ -160,10 +164,12 @@ void CounterInit(void) pinMode(Pin(GPIO_CNTR1, i), bitRead(Counter.no_pullup, i) ? INPUT : INPUT_PULLUP); if ((0 == Settings.pulse_counter_debounce_low) && (0 == Settings.pulse_counter_debounce_high) && !Settings.flag4.zerocross_dimmer) { Counter.pin_state = 0; - attachInterrupt(Pin(GPIO_CNTR1, i), counter_callbacks[i], FALLING); +// attachInterrupt(Pin(GPIO_CNTR1, i), counter_callbacks[i], FALLING); + attachInterruptArg(Pin(GPIO_CNTR1, i), CounterIsrArg, &ctr_index[i], FALLING); } else { Counter.pin_state = 0x8f; - attachInterrupt(Pin(GPIO_CNTR1, i), counter_callbacks[i], CHANGE); +// attachInterrupt(Pin(GPIO_CNTR1, i), counter_callbacks[i], CHANGE); + attachInterruptArg(Pin(GPIO_CNTR1, i), CounterIsrArg, &ctr_index[i], CHANGE); } } } From 25dcf447f3fc6f71cf2e409af88fe08867a168dc Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Jul 2020 12:49:42 +0200 Subject: [PATCH 510/581] First try to fix counter interrupt storm First try to fix counter interrupt storm during OTA (#8928) --- tasmota/xdrv_01_webserver.ino | 6 ++++++ tasmota/xsns_01_counter.ino | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index e42b17db4..7f510271c 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2598,6 +2598,9 @@ void HandleUploadDone(void) WifiConfigCounter(); restart_flag = 0; MqttRetryCounter(0); +#ifdef USE_COUNTER + CounterInterruptDisable(false); +#endif WSContentStart_P(S_INFORMATION); if (!Web.upload_error) { @@ -2673,6 +2676,9 @@ void HandleUploadLoop(void) } } else { MqttRetryCounter(60); +#ifdef USE_COUNTER + CounterInterruptDisable(true); +#endif #ifdef USE_EMULATION UdpDisconnect(); #endif // USE_EMULATION diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index dde9a420e..0337e17e5 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -44,6 +44,7 @@ struct COUNTER { uint8_t no_pullup = 0; // Counter input pullup flag (1 = No pullup) uint8_t pin_state = 0; // LSB0..3 Last state of counter pin; LSB7==0 IRQ is FALLING, LSB7==1 IRQ is CHANGE bool any_counter = false; + bool disable = false; } Counter; uint32_t last_cycle; @@ -51,6 +52,8 @@ uint32_t cycle_time; //void ICACHE_RAM_ATTR CounterUpdate(uint8_t index) { void ICACHE_RAM_ATTR CounterIsrArg(void *arg) { + if (Counter.disable) { return; } + uint32_t index = *static_cast(arg); uint32_t time = micros(); @@ -143,6 +146,10 @@ void ICACHE_RAM_ATTR CounterUpdate4(void) */ /********************************************************************************************/ +void CounterInterruptDisable(bool state) { + Counter.disable = state; +} + bool CounterPinState(void) { if ((XdrvMailbox.index >= AGPIO(GPIO_CNTR1_NP)) && (XdrvMailbox.index < (AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS))) { From 8dbe3c90da3da17ab9e49f8e71f11653a24c0f80 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Jul 2020 16:18:07 +0200 Subject: [PATCH 511/581] Second try to fix counter interrupt storm Second try to fix counter interrupt storm during OTA (#8928) --- tasmota/xdrv_01_webserver.ino | 3 +++ tasmota/xsns_01_counter.ino | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 7f510271c..112b9ac7f 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2874,6 +2874,9 @@ void HandleUploadLoop(void) } else if (UPLOAD_FILE_ABORTED == upload.status) { restart_flag = 0; MqttRetryCounter(0); +#ifdef USE_COUNTER + CounterInterruptDisable(false); +#endif Web.upload_error = 7; // Upload aborted if (UPL_TASMOTA == Web.upload_file_type) { Update.end(); } } diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index 0337e17e5..73c19322e 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -44,7 +44,6 @@ struct COUNTER { uint8_t no_pullup = 0; // Counter input pullup flag (1 = No pullup) uint8_t pin_state = 0; // LSB0..3 Last state of counter pin; LSB7==0 IRQ is FALLING, LSB7==1 IRQ is CHANGE bool any_counter = false; - bool disable = false; } Counter; uint32_t last_cycle; @@ -52,8 +51,6 @@ uint32_t cycle_time; //void ICACHE_RAM_ATTR CounterUpdate(uint8_t index) { void ICACHE_RAM_ATTR CounterIsrArg(void *arg) { - if (Counter.disable) { return; } - uint32_t index = *static_cast(arg); uint32_t time = micros(); @@ -147,7 +144,20 @@ void ICACHE_RAM_ATTR CounterUpdate4(void) /********************************************************************************************/ void CounterInterruptDisable(bool state) { - Counter.disable = state; + if (state) { // Disable interrupts + if (Counter.any_counter) { + for (uint32_t i = 0; i < MAX_COUNTERS; i++) { + if (PinUsed(GPIO_CNTR1, i)) { + detachInterrupt(Pin(GPIO_CNTR1, i)); + } + } + Counter.any_counter = false; + } + } else { // Enable interrupts + if (!Counter.any_counter) { + CounterInit(); + } + } } bool CounterPinState(void) From 7d0d9b7782a9ce1c5b2e4b34666754ca3ad6aa43 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Jul 2020 18:00:17 +0200 Subject: [PATCH 512/581] Remove Arduino ESP8266 Core support before 2.7.1 --- .../README.md | 0 .../examples/swsertest/swsertest.ino | 0 .../keywords.txt | 0 .../library.json | 2 +- .../library.properties | 2 +- .../src/TasmotaSerial.cpp | 89 ++----------------- .../src/TasmotaSerial.h | 5 -- 7 files changed, 10 insertions(+), 88 deletions(-) rename lib/{TasmotaSerial-3.0.0 => TasmotaSerial-3.1.0}/README.md (100%) rename lib/{TasmotaSerial-3.0.0 => TasmotaSerial-3.1.0}/examples/swsertest/swsertest.ino (100%) rename lib/{TasmotaSerial-3.0.0 => TasmotaSerial-3.1.0}/keywords.txt (100%) rename lib/{TasmotaSerial-3.0.0 => TasmotaSerial-3.1.0}/library.json (94%) rename lib/{TasmotaSerial-3.0.0 => TasmotaSerial-3.1.0}/library.properties (94%) rename lib/{TasmotaSerial-3.0.0 => TasmotaSerial-3.1.0}/src/TasmotaSerial.cpp (79%) rename lib/{TasmotaSerial-3.0.0 => TasmotaSerial-3.1.0}/src/TasmotaSerial.h (91%) diff --git a/lib/TasmotaSerial-3.0.0/README.md b/lib/TasmotaSerial-3.1.0/README.md similarity index 100% rename from lib/TasmotaSerial-3.0.0/README.md rename to lib/TasmotaSerial-3.1.0/README.md diff --git a/lib/TasmotaSerial-3.0.0/examples/swsertest/swsertest.ino b/lib/TasmotaSerial-3.1.0/examples/swsertest/swsertest.ino similarity index 100% rename from lib/TasmotaSerial-3.0.0/examples/swsertest/swsertest.ino rename to lib/TasmotaSerial-3.1.0/examples/swsertest/swsertest.ino diff --git a/lib/TasmotaSerial-3.0.0/keywords.txt b/lib/TasmotaSerial-3.1.0/keywords.txt similarity index 100% rename from lib/TasmotaSerial-3.0.0/keywords.txt rename to lib/TasmotaSerial-3.1.0/keywords.txt diff --git a/lib/TasmotaSerial-3.0.0/library.json b/lib/TasmotaSerial-3.1.0/library.json similarity index 94% rename from lib/TasmotaSerial-3.0.0/library.json rename to lib/TasmotaSerial-3.1.0/library.json index 19197cce4..17764a8f2 100644 --- a/lib/TasmotaSerial-3.0.0/library.json +++ b/lib/TasmotaSerial-3.1.0/library.json @@ -1,6 +1,6 @@ { "name": "TasmotaSerial", - "version": "3.0.0", + "version": "3.1.0", "keywords": [ "serial", "io", "TasmotaSerial" ], diff --git a/lib/TasmotaSerial-3.0.0/library.properties b/lib/TasmotaSerial-3.1.0/library.properties similarity index 94% rename from lib/TasmotaSerial-3.0.0/library.properties rename to lib/TasmotaSerial-3.1.0/library.properties index d1d9e718a..8229443e9 100644 --- a/lib/TasmotaSerial-3.0.0/library.properties +++ b/lib/TasmotaSerial-3.1.0/library.properties @@ -1,5 +1,5 @@ name=TasmotaSerial -version=3.0.0 +version=3.1.0 author=Theo Arends maintainer=Theo Arends sentence=Implementation of software serial with hardware serial fallback for ESP8266 and ESP32. diff --git a/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp b/lib/TasmotaSerial-3.1.0/src/TasmotaSerial.cpp similarity index 79% rename from lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp rename to lib/TasmotaSerial-3.1.0/src/TasmotaSerial.cpp index 6982779d5..0ceed70f5 100644 --- a/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp +++ b/lib/TasmotaSerial-3.1.0/src/TasmotaSerial.cpp @@ -29,66 +29,19 @@ extern "C" { #ifdef ESP8266 -// for STAGE and pre-2.6, we can have a single wrapper using attachInterruptArg() void ICACHE_RAM_ATTR callRxRead(void *self) { ((TasmotaSerial*)self)->rxRead(); }; // As the Arduino attachInterrupt has no parameter, lists of objects // and callbacks corresponding to each possible GPIO pins have to be defined TasmotaSerial *tms_obj_list[16]; -#ifdef TM_SERIAL_USE_IRAM -void ICACHE_RAM_ATTR tms_isr_0() { tms_obj_list[0]->rxRead(); }; -void ICACHE_RAM_ATTR tms_isr_1() { tms_obj_list[1]->rxRead(); }; -void ICACHE_RAM_ATTR tms_isr_2() { tms_obj_list[2]->rxRead(); }; -void ICACHE_RAM_ATTR tms_isr_3() { tms_obj_list[3]->rxRead(); }; -void ICACHE_RAM_ATTR tms_isr_4() { tms_obj_list[4]->rxRead(); }; -void ICACHE_RAM_ATTR tms_isr_5() { tms_obj_list[5]->rxRead(); }; -// Pin 6 to 11 can not be used -void ICACHE_RAM_ATTR tms_isr_12() { tms_obj_list[12]->rxRead(); }; -void ICACHE_RAM_ATTR tms_isr_13() { tms_obj_list[13]->rxRead(); }; -void ICACHE_RAM_ATTR tms_isr_14() { tms_obj_list[14]->rxRead(); }; -void ICACHE_RAM_ATTR tms_isr_15() { tms_obj_list[15]->rxRead(); }; -#else -void tms_isr_0() { tms_obj_list[0]->rxRead(); }; -void tms_isr_1() { tms_obj_list[1]->rxRead(); }; -void tms_isr_2() { tms_obj_list[2]->rxRead(); }; -void tms_isr_3() { tms_obj_list[3]->rxRead(); }; -void tms_isr_4() { tms_obj_list[4]->rxRead(); }; -void tms_isr_5() { tms_obj_list[5]->rxRead(); }; -// Pin 6 to 11 can not be used -void tms_isr_12() { tms_obj_list[12]->rxRead(); }; -void tms_isr_13() { tms_obj_list[13]->rxRead(); }; -void tms_isr_14() { tms_obj_list[14]->rxRead(); }; -void tms_isr_15() { tms_obj_list[15]->rxRead(); }; -#endif // TM_SERIAL_USE_IRAM - -static void (*ISRList[16])() = { - tms_isr_0, - tms_isr_1, - tms_isr_2, - tms_isr_3, - tms_isr_4, - tms_isr_5, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - tms_isr_12, - tms_isr_13, - tms_isr_14, - tms_isr_15 -}; - #else // ESP32 - static int tasmota_serial_index = 2; // Allow UART2 and UART1 only +static int tasmota_serial_index = 2; // Allow UART2 and UART1 only #endif // ESP8266 -TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback, int nwmode, int buffer_size) -{ +TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback, int nwmode, int buffer_size) { m_valid = false; m_hardserial = false; m_hardswap = false; @@ -118,11 +71,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal m_bit_start_time = m_bit_time + m_bit_time/3 - 500; // pre-compute first wait pinMode(m_rx_pin, INPUT); tms_obj_list[m_rx_pin] = this; -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) || defined(ARDUINO_ESP8266_RELEASE_2_5_2) - attachInterrupt(m_rx_pin, ISRList[m_rx_pin], (m_nwmode) ? CHANGE : FALLING); -#else attachInterruptArg(m_rx_pin, callRxRead, this, (m_nwmode) ? CHANGE : FALLING); -#endif } if (m_tx_pin > -1) { pinMode(m_tx_pin, OUTPUT); @@ -136,8 +85,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal m_valid = true; } -TasmotaSerial::~TasmotaSerial() -{ +TasmotaSerial::~TasmotaSerial() { #ifdef ESP8266 if (!m_hardserial) { if (m_rx_pin > -1) { @@ -151,8 +99,7 @@ TasmotaSerial::~TasmotaSerial() #endif // ESP8266 } -bool TasmotaSerial::isValidGPIOpin(int pin) -{ +bool TasmotaSerial::isValidGPIOpin(int pin) { return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15); } @@ -234,8 +181,7 @@ int TasmotaSerial::peek() { } } -int TasmotaSerial::read() -{ +int TasmotaSerial::read() { if (m_hardserial) { #ifdef ESP8266 return Serial.read(); @@ -250,8 +196,7 @@ int TasmotaSerial::read() } } -int TasmotaSerial::available() -{ +int TasmotaSerial::available() { if (m_hardserial) { #ifdef ESP8266 return Serial.available(); @@ -265,23 +210,12 @@ int TasmotaSerial::available() } } -#ifdef TM_SERIAL_USE_IRAM #define TM_SERIAL_WAIT_SND { while (ESP.getCycleCount() < (wait + start)) if (!m_high_speed) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts #define TM_SERIAL_WAIT_SND_FAST { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } #define TM_SERIAL_WAIT_RCV { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } #define TM_SERIAL_WAIT_RCV_LOOP { while (ESP.getCycleCount() < (wait + start)); } -#else -#define TM_SERIAL_WAIT_SND { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } -#define TM_SERIAL_WAIT_SND_FAST { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } -#define TM_SERIAL_WAIT_RCV { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } -#define TM_SERIAL_WAIT_RCV_LOOP { while (ESP.getCycleCount() < (wait + start)); } -#endif -#ifdef TM_SERIAL_USE_IRAM void ICACHE_RAM_ATTR TasmotaSerial::_fast_write(uint8_t b) { -#else -void TasmotaSerial::_fast_write(uint8_t b) { -#endif uint32_t wait = m_bit_time; uint32_t start = ESP.getCycleCount(); // Start bit; @@ -299,8 +233,7 @@ void TasmotaSerial::_fast_write(uint8_t b) { } } -size_t TasmotaSerial::write(uint8_t b) -{ +size_t TasmotaSerial::write(uint8_t b) { if (m_hardserial) { #ifdef ESP8266 return Serial.write(b); @@ -337,13 +270,7 @@ size_t TasmotaSerial::write(uint8_t b) } } -#ifdef TM_SERIAL_USE_IRAM -void ICACHE_RAM_ATTR TasmotaSerial::rxRead() -{ -#else -void TasmotaSerial::rxRead() -{ -#endif +void ICACHE_RAM_ATTR TasmotaSerial::rxRead() { if (!m_nwmode) { int32_t loop_read = m_very_high_speed ? serial_buffer_size : 1; // Advance the starting point for the samples but compensate for the diff --git a/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.h b/lib/TasmotaSerial-3.1.0/src/TasmotaSerial.h similarity index 91% rename from lib/TasmotaSerial-3.0.0/src/TasmotaSerial.h rename to lib/TasmotaSerial-3.1.0/src/TasmotaSerial.h index 42a3f120e..bc5161d65 100644 --- a/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.h +++ b/lib/TasmotaSerial-3.1.0/src/TasmotaSerial.h @@ -28,11 +28,6 @@ #define TM_SERIAL_BAUDRATE 9600 // Default baudrate #define TM_SERIAL_BUFFER_SIZE 64 // Receive buffer size -#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0) -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 - #define TM_SERIAL_USE_IRAM // Enable to use iram (+368 bytes) -#endif - #include #include From d2198ad8b6482381c7431d7efa21412168329bb8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 17 Jul 2020 18:40:06 +0200 Subject: [PATCH 513/581] Fix esp32 compile error --- tasmota/settings.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 39b1249ad..2e8852ae5 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -174,11 +174,11 @@ const uint32_t SPIFFS_END = ((uint32_t)&_FS_end - 0x40200000) / SPI_FLASH_SEC_SI #endif // AUTOFLASHSIZE -#endif // All cores < pre-2.6.0 - // Version 4.2 config = eeprom area const uint32_t SETTINGS_LOCATION = SPIFFS_END; // No need for SPIFFS as it uses EEPROM area +#endif // ESP8266 + // Version 5.2 allow for more flash space const uint8_t CFG_ROTATES = 8; // Number of flash sectors used (handles uploads) From 2c6198f27ca196614d9d80ec6798ef4379dc72c5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 18 Jul 2020 18:51:13 +0200 Subject: [PATCH 514/581] Fix spelling Fix spelling (#3410) --- tasmota/i18n.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index eeedbfc57..70ca42a7e 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -616,7 +616,7 @@ // xsns_70_veml6075.ino #define D_JSON_UVA_INTENSITY "UvaIntensity" -#define D_JSON_UVB_INTENSITY "UvbItensity" +#define D_JSON_UVB_INTENSITY "UvbIntensity" #define D_CMND_VEML6075_POWER "power" #define D_CMND_VEML6075_DYNAMIC "dynamic" #define D_CMND_VEML6075_INTTIME "inttime" From 63242de249de891e8a2869de6ba8370885f319f6 Mon Sep 17 00:00:00 2001 From: George Date: Sun, 19 Jul 2020 20:34:43 +1000 Subject: [PATCH 515/581] Serialsend6 * Adds serialsend6, allowing sending of binary data with comma-delimited string of decimal numbers. --- tasmota/support.ino | 11 +++++++++++ tasmota/support_command.ino | 3 +++ 2 files changed, 14 insertions(+) diff --git a/tasmota/support.ino b/tasmota/support.ino index 50cc4f920..ae42f3840 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -906,6 +906,17 @@ void SerialSendRaw(char *codes) } } +// values is a comma-delimited string: e.g. "72,101,108,108,111,32,87,111,114,108,100,33,10" +void SerialSendDecimal(char *values) +{ + char* &p; + uint8_t code; + for (str = strtok_r(values, ",", &p); str; str = strtok_r(nullptr, ",", &p)) { + code = (uint8_t)atoi(str); + Serial.write(code); + } +} + uint32_t GetHash(const char *buffer, size_t size) { uint32_t hash = 0; diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index abd75960e..5854c0ed1 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1354,6 +1354,9 @@ void CmndSerialSend(void) else if (5 == XdrvMailbox.index) { SerialSendRaw(RemoveSpace(XdrvMailbox.data)); // "AA004566" as hex values } + else if (6 == XdrvMailbox.index) { + SerialSendDecimal(XdrvMailbox.data); + } ResponseCmndDone(); } } From a7e057b8ba765364b0bc72b4c474588150090fd8 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 19 Jul 2020 13:21:45 +0200 Subject: [PATCH 516/581] Use Tasmota Stage Core 2.7.3.1... for Tasmota Stage build. Core is based on (soon released) Arduino ESP core 2.7.3. --- platformio_override_sample.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 01aa03601..b938fb888 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -88,7 +88,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage platform = espressif8266@2.5.1 -platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.7.2.1/esp8266-2.7.2.1.zip +platform_packages = framework-arduinoespressif8266 @ https://github.com/Jason2866/Arduino/releases/download/2.7.3.1/esp8266-2.7.3.1.zip build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From 528fe5333d7196f1e761f0dde7a8830a4b838379 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 19 Jul 2020 13:33:57 +0200 Subject: [PATCH 517/581] Shrink minimal a bit --- tasmota/tasmota_configurations.h | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index ad9d64d08..61baee7aa 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -176,7 +176,7 @@ #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram) #define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram) -#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) +#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) #define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code) #define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code) #define USE_HX711 // Add support for HX711 load cell (+1k5 code) @@ -537,16 +537,17 @@ #undef CODE_IMAGE_STR #define CODE_IMAGE_STR "minimal" -#undef FIRMWARE_LITE // Disable tasmota-lite with no sensors -#undef FIRMWARE_SENSORS // Disable tasmota-sensors with useful sensors enabled -#undef FIRMWARE_KNX_NO_EMULATION // Disable tasmota-knx with KNX but without Emulation -#undef FIRMWARE_DISPLAYS // Disable tasmota-display with display drivers enabled -#undef FIRMWARE_IR // Disable tasmota-ir with IR full protocols activated -#undef FIRMWARE_IR_CUSTOM // Disable tasmota customizable with special marker to add all IR protocols +#undef FIRMWARE_LITE // Disable tasmota-lite with no sensors +#undef FIRMWARE_SENSORS // Disable tasmota-sensors with useful sensors enabled +#undef FIRMWARE_KNX_NO_EMULATION // Disable tasmota-knx with KNX but without Emulation +#undef FIRMWARE_DISPLAYS // Disable tasmota-display with display drivers enabled +#undef FIRMWARE_IR // Disable tasmota-ir with IR full protocols activated +#undef FIRMWARE_IR_CUSTOM // Disable tasmota customizable with special marker to add all IR protocols #undef USE_ARDUINO_OTA // Disable support for Arduino OTA #undef USE_DOMOTICZ // Disable Domoticz #undef USE_HOME_ASSISTANT // Disable Home Assistant +#undef USE_TELEGRAM // Disable support for Telegram protocol (+49k code, +7.0k mem and +4.8k additional during connection handshake) //#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set #undef USE_KNX // Disable KNX IP Protocol Support //#undef USE_WEBSERVER // Disable Webserver @@ -559,6 +560,8 @@ #undef USE_TIMERS // Disable support for up to 16 timers #undef USE_TIMERS_WEB // Disable support for timer webpage #undef USE_SUNRISE // Disable support for Sunrise and sunset tools +#undef USE_PING // Disable Ping command (+2k code) +#undef USE_UNISHOX_COMPRESSION // Disable support for string compression in Rules or Scripts #undef USE_RULES // Disable support for rules #undef USE_SCRIPT // Disable support for script @@ -592,6 +595,7 @@ #undef USE_SONOFF_L1 // Disable support for Sonoff L1 led control #undef USE_ELECTRIQ_MOODL // Disable support for ElectriQ iQ-wifiMOODL RGBW LED controller #undef USE_LIGHT_PALETTE // Disable support for color palette (+0k9 code) +#undef USE_DGR_LIGHT_SEQUENCE // Disable support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code) #undef USE_COUNTER // Disable counters #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices @@ -607,6 +611,7 @@ #undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor #undef USE_HPMA // Disable support for Honeywell HPMA115S0 particle concentration sensor #undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge +#undef USE_TCP_BRIDGE // DIsable support for Serial to TCP bridge (+1.3k code) #undef USE_MP3_PLAYER // Disable DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop #undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger #undef USE_PN532_HSU // Disable support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) @@ -631,11 +636,14 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) +#undef USE_BL0940 // Disable support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code) #undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry +#undef USE_IEM3000 // Disable support for Schneider Electric iEM3000-Modbus series energy monitor (+0k8 code) #undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI #undef USE_MAX31865 // Disable support for MAX31865 RTD sensors using softSPI +#undef USE_LMT01 // Disable support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) #undef USE_IR_REMOTE // Disable IR driver #undef USE_SR04 // Disable support for for HC-SR04 ultrasonic devices #undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8 @@ -648,6 +656,7 @@ #undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code) #undef USE_A4988_STEPPER // Disable support for A4988_Stepper #undef USE_THERMOSTAT // Disable support for Thermostat +#undef USE_PROMETHEUS // Disable support for https://prometheus.io/ metrics exporting over HTTP /metrics endpoint #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code #endif // FIRMWARE_MINIMAL From 27ff269bcb332a5ebec3ef15add560c996ed268c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 19 Jul 2020 13:43:08 +0200 Subject: [PATCH 518/581] Fix regression build flags from #8932 --- platformio_override_sample.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index b938fb888..57d7498cb 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -90,7 +90,11 @@ extra_scripts = ${scripts_defaults.extra_scripts} platform = espressif8266@2.5.1 platform_packages = framework-arduinoespressif8266 @ https://github.com/Jason2866/Arduino/releases/download/2.7.3.1/esp8266-2.7.3.1.zip build_unflags = ${esp_defaults.build_unflags} + -std=c17 + -std=gnu++17 build_flags = ${esp82xx_defaults.build_flags} + -std=gnu99 + -std=c++11 ; *********** Alternative Options, enable only if you know exactly what you do ******** ; NONOSDK221 From 23da6285c12c8fb99100b795e32c247aaa4d9a4d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 19 Jul 2020 15:57:37 +0200 Subject: [PATCH 519/581] Add command ``SetOption100 0/1`` Add command ``SetOption100 0/1`` to remove ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message --- RELEASENOTES.md | 2 ++ tasmota/CHANGELOG.md | 2 ++ tasmota/settings.h | 4 ++-- tasmota/xdrv_23_zigbee_2_devices.ino | 18 +++++++++++++----- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ddb4bc8b2..5e5e3e549 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -70,6 +70,8 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) - Add command ``SetOption97 0/1`` to switch between Tuya serial speeds 9600 bps (0) or 115200 bps (1) - Add command ``SetOption98 0/1`` to provide rotary rule triggers (1) instead of controlling light (0) +- Add command ``SetOption99 0/1`` to enable zero cross detection on PWM dimmer +- Add command ``SetOption100 0/1`` to remove ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message - Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index b67609a80..7dbad0a37 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -4,12 +4,14 @@ - Remove Arduino ESP8266 Core support for versions before 2.7.1 - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE +- Add command ``SetOption100 0/1`` to remove ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message ### 8.3.1.6 20200617 - Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add command ``SetOption97 0/1`` to switch between Tuya serial speeds 9600 bps (0) or 115200 bps (1) - Add command ``SetOption98 0/1`` to provide rotary rule triggers (1) instead of controlling light (0) +- Add command ``SetOption99 0/1`` to enable zero cross detection on PWM dimmer - Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff - Add library to be used for decoding Teleinfo (French Metering Smart Meter) - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) diff --git a/tasmota/settings.h b/tasmota/settings.h index cc0fd9bf3..9d4466028 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -118,8 +118,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) - CMND_ETHERNET uint32_t tuyamcu_baudrate : 1; // bit 15 (v8.3.1.6) - SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) uint32_t rotary_uses_rules : 1; // bit 16 (v8.3.1.6) - SetOption98 - Use rules instead of light control - uint32_t zerocross_dimmer : 1; // bit 17 (v8.3.1.4) = SetOption99 - Enable zerocross dimmer on PWM DIMMER - uint32_t spare18 : 1; + uint32_t zerocross_dimmer : 1; // bit 17 (v8.3.1.4) - SetOption99 - Enable zerocross dimmer on PWM DIMMER + uint32_t remove_zbreceived : 1; // bit 18 (v8.3.1.7) - SetOption100 - Remove ZbReceived form JSON message uint32_t spare19 : 1; uint32_t spare20 : 1; uint32_t spare21 : 1; diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index d570c4560..abcf6440c 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -102,7 +102,7 @@ typedef struct Z_Deferred { uint16_t groupaddr; // group address (if needed) uint16_t cluster; // cluster to use for the timer uint8_t endpoint; // endpoint to use for timer - uint8_t category; // which category of deferred is it + uint8_t category; // which category of deferred is it uint32_t value; // any raw value to use for the timer Z_DeviceTimer func; // function to call when timer occurs } Z_Deferred; @@ -213,7 +213,7 @@ public: private: std::vector _devices = {}; std::vector _deferred = {}; // list of deferred calls - uint32_t _saveTimer = 0; + uint32_t _saveTimer = 0; uint8_t _seqNumber = 0; // global seqNumber if device is unknown template < typename T> @@ -738,7 +738,7 @@ bool Z_Devices::getHueState(uint16_t shortaddr, void Z_Devices::resetTimersForDevice(uint16_t shortaddr, uint16_t groupaddr, uint8_t category) { // iterate the list of deferred, and remove any linked to the shortaddr for (auto it = _deferred.begin(); it != _deferred.end(); it++) { - // Notice that the iterator is decremented after it is passed + // Notice that the iterator is decremented after it is passed // to erase() but before erase() is executed // see https://www.techiedelight.com/remove-elements-vector-inside-loop-cpp/ if ((it->shortaddr == shortaddr) && (it->groupaddr == groupaddr)) { @@ -937,9 +937,17 @@ void Z_Devices::jsonPublishFlush(uint16_t shortaddr) { zigbee_devices.jsonClear(shortaddr); if (use_fname) { - Response_P(PSTR("{\"" D_JSON_ZIGBEE_RECEIVED "\":{\"%s\":%s}}"), fname, msg.c_str()); + if (Settings.flag4.remove_zbreceived) { + Response_P(PSTR("{\"%s\":%s}"), fname, msg.c_str()); + } else { + Response_P(PSTR("{\"" D_JSON_ZIGBEE_RECEIVED "\":{\"%s\":%s}}"), fname, msg.c_str()); + } } else { - Response_P(PSTR("{\"" D_JSON_ZIGBEE_RECEIVED "\":{\"0x%04X\":%s}}"), shortaddr, msg.c_str()); + if (Settings.flag4.remove_zbreceived) { + Response_P(PSTR("{\"0x%04X\":%s}"), shortaddr, msg.c_str()); + } else { + Response_P(PSTR("{\"" D_JSON_ZIGBEE_RECEIVED "\":{\"0x%04X\":%s}}"), shortaddr, msg.c_str()); + } } if (Settings.flag4.zigbee_distinct_topics) { char subtopic[16]; From 8a4a0d67ff415ca59072f999a2ce1815304894d4 Mon Sep 17 00:00:00 2001 From: George Date: Mon, 20 Jul 2020 10:08:20 +1000 Subject: [PATCH 520/581] serialsend6 - fixes Forgot to fix top condition --- tasmota/support_command.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 5854c0ed1..61a0962b4 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1334,7 +1334,7 @@ void CmndSerialConfig(void) void CmndSerialSend(void) { - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 5)) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) { SetSeriallog(LOG_LEVEL_NONE); Settings.flag.mqtt_serial = 1; // CMND_SERIALSEND and CMND_SERIALLOG Settings.flag.mqtt_serial_raw = (XdrvMailbox.index > 3) ? 1 : 0; // CMND_SERIALSEND3 From 2ced749e4d48bdbdb8e0a6b7246bb8760499c9d2 Mon Sep 17 00:00:00 2001 From: George Date: Mon, 20 Jul 2020 10:14:01 +1000 Subject: [PATCH 521/581] serialsend6 - more fixes oops --- tasmota/support.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index ae42f3840..2e36793b0 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -909,9 +909,9 @@ void SerialSendRaw(char *codes) // values is a comma-delimited string: e.g. "72,101,108,108,111,32,87,111,114,108,100,33,10" void SerialSendDecimal(char *values) { - char* &p; + char *p; uint8_t code; - for (str = strtok_r(values, ",", &p); str; str = strtok_r(nullptr, ",", &p)) { + for (char* str = strtok_r(values, ",", &p); str; str = strtok_r(nullptr, ",", &p)) { code = (uint8_t)atoi(str); Serial.write(code); } From 1b380b5bc9e2a81c581ddf320b8dc121cdbcee42 Mon Sep 17 00:00:00 2001 From: Staars Date: Mon, 20 Jul 2020 08:51:17 +0200 Subject: [PATCH 522/581] update MQTT presentation --- tasmota/xsns_62_MI_ESP32.ino | 312 ++++++++++++++++++++++++++--------- 1 file changed, 233 insertions(+), 79 deletions(-) diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index fbdc5bf6b..612474172 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -66,14 +66,21 @@ struct { uint32_t willReadBatt:1; uint32_t shallSetUnit:1; uint32_t willSetUnit:1; + uint32_t shallTriggerTele:1; uint32_t triggeredTele:1; - uint32_t shallClearResults:1; - uint32_t directMQTT:1; // TODO: direct bridging of every single sensor message + uint32_t shallClearResults:1; // BLE scan results } mode; struct { uint8_t sensor; // points to to the number 0...255 } state; + struct { + uint32_t allwaysAggregate:1; + uint32_t showRSSI:1; + uint32_t ignoreBogusBattery:1; + uint32_t noSummary:1; + uint32_t minimalSummary:1; + } option; } MI32; #pragma pack(1) // byte-aligned structures to read the sensor data @@ -162,8 +169,39 @@ struct mi_sensor_t{ uint8_t lastCnt; //device generated counter of the packet uint8_t shallSendMQTT; uint8_t MAC[6]; + union { + struct { + uint32_t temp:1; + uint32_t hum:1; + uint32_t tempHum:1; //every hum sensor has temp too, easier to use Tasmota dew point functions + uint32_t lux:1; + uint32_t moist:1; + uint32_t fert:1; + uint32_t bat:1; + uint32_t NMT:1; + uint32_t PIR:1; + uint32_t Btn:1; + }; + uint32_t raw; + } feature; + union { + struct { + uint32_t temp:1; + uint32_t hum:1; + uint32_t tempHum:1; //can be combined from the sensor + uint32_t lux:1; + uint32_t moist:1; + uint32_t fert:1; + uint32_t bat:1; + uint32_t NMT:1; + uint32_t motion:1; + uint32_t noMotion:1; + uint32_t Btn:1; + }; + uint32_t raw; + } eventType; + int rssi; - // uint8_t showedUp; uint32_t lastTime; uint32_t lux; float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx @@ -179,7 +217,6 @@ struct mi_sensor_t{ struct { uint16_t events; //"alarms" since boot uint32_t NMT; // no motion time in seconds for the MJYD2S - uint8_t eventType; //internal type of actual event for the MJYD2S -> 1: PIR, 2: No PIR, 3: NMT }; uint16_t Btn; }; @@ -523,7 +560,8 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter) mi_sensor_t _newSensor; memcpy(_newSensor.MAC,_MAC, sizeof(_MAC)); _newSensor.type = _type; - + _newSensor.eventType.raw = 0; + _newSensor.feature.raw = 0; _newSensor.temp =NAN; _newSensor.bat=0x00; _newSensor.rssi=0xffff; @@ -534,14 +572,34 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter) _newSensor.moisture =0xff; _newSensor.fertility =0xffff; _newSensor.firmware[0]='\0'; + _newSensor.feature.temp=1; + _newSensor.feature.moist=1; + _newSensor.feature.fert=1; + _newSensor.feature.lux=1; + _newSensor.feature.bat=1; break; - case NLIGHT: case MJYD2S: + case NLIGHT: + _newSensor.events=0x00; + _newSensor.feature.PIR=1; + _newSensor.feature.NMT=1; + break; + case MJYD2S: _newSensor.NMT=0; _newSensor.events=0x00; - _newSensor.eventType=0x00; + _newSensor.feature.PIR=1; + _newSensor.feature.NMT=1; + _newSensor.feature.lux=1; + _newSensor.feature.bat=1; + break; + case YEERC: + _newSensor.feature.Btn=1; break; default: _newSensor.hum=NAN; + _newSensor.feature.temp=1; + _newSensor.feature.hum=1; + _newSensor.feature.tempHum=1; + _newSensor.feature.bat=1; break; } MIBLEsensors.push_back(_newSensor); @@ -554,7 +612,7 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type, uint8_t counter) * */ void MI32triggerTele(void){ - MI32.mode.triggeredTele = true; + MI32.mode.triggeredTele = 1; mqtt_data[0] = '\0'; if (MqttShowSensor()) { MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); @@ -576,6 +634,13 @@ void MI32Init(void) { MI32.mode.init = 1; MI32.period = Settings.tele_period; + //test section for options + MI32.option.allwaysAggregate = 1; + MI32.option.showRSSI = 1; + MI32.option.ignoreBogusBattery = 1; // from advertisements + MI32.option.noSummary = 0; + MI32.option.minimalSummary = 1; + MI32StartScanTask(); // Let's get started !! } return; @@ -603,7 +668,14 @@ void MI32StartTask(uint32_t task){ break; case MI32_TASK_BATT: if (MI32.mode.willReadBatt == 1) return; - MI32StartBatteryTask(); + switch(MIBLEsensors[MI32.state.sensor].type) { + case LYWSD03MMC: case MHOC401: // the "original" battery value is crap ... + MI32.mode.willReadBatt = 1; + MI32StartSensorTask(); // ... but the part of the temp/hum-message is good! + break; + default: + MI32StartBatteryTask(); + } break; case MI32_TASK_UNIT: if (MI32.mode.shallSetUnit == 0) return; @@ -720,6 +792,7 @@ void MI32SensorTask(void *pvParameters){ MI32Client->disconnect(); // NimBLEDevice::deleteClient(MI32Client); MI32.mode.willConnect = 0; + MI32.mode.willReadBatt = 0; //could be a "battery task" for LYWSD03MMC or MHO-C401 vTaskDelay(100/ portTICK_PERIOD_MS); vTaskDelete( NULL ); } @@ -1054,7 +1127,7 @@ void MI32parseMiBeacon(char * _buf, uint32_t _slot, uint16_t _bufSize){ // MIBLEsensors[_slot].lastTime = millis(); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MI32: MJYD2S secondary PIR")); // MIBLEsensors[_slot].NMT = 0; - // MI32triggerTele(); + // MI32.mode.shallTriggerTele = 1; // } } break; @@ -1067,56 +1140,63 @@ if (MIBLEsensors[_slot].type==NLIGHT){ } if(MIBLEsensors[_slot].type==6){ - DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type); + DEBUG_SENSOR_LOG(PSTR("CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type); return; } AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32DeviceType[MIBLEsensors[_slot].type-1],_slot); switch(_beacon.type){ case 0x01: MIBLEsensors[_slot].Btn=_beacon.Btn.num + (_beacon.Btn.longPress/2)*6; - MIBLEsensors[_slot].shallSendMQTT = 1; - MI32triggerTele(); + MIBLEsensors[_slot].eventType.Btn = 1; // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 1: U16: %u Button"), MIBLEsensors[_slot].Btn ); break; case 0x04: _tempFloat=(float)(_beacon.temp)/10.0f; if(_tempFloat<60){ - MIBLEsensors[_slot].temp=_tempFloat; - DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); + MIBLEsensors[_slot].temp=_tempFloat; + MIBLEsensors[_slot].eventType.temp = 1; + DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); } // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); break; case 0x06: _tempFloat=(float)(_beacon.hum)/10.0f; if(_tempFloat<101){ - MIBLEsensors[_slot].hum=_tempFloat; - DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); + MIBLEsensors[_slot].hum=_tempFloat; + MIBLEsensors[_slot].eventType.hum = 1; + DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); } // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _beacon.hum); break; case 0x07: MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff; if(MIBLEsensors[_slot].type==MJYD2S){ - MIBLEsensors[_slot].eventType = 2; //No PIR - MIBLEsensors[_slot].shallSendMQTT = 1; - MIBLEsensors[_slot].lastTime = millis(); - MI32triggerTele(); + MIBLEsensors[_slot].eventType.noMotion = 1; } + MIBLEsensors[_slot].eventType.lux = 1; // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); break; case 0x08: - MIBLEsensors[_slot].moisture=_beacon.moist; - DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); + MIBLEsensors[_slot].moisture=_beacon.moist; + MIBLEsensors[_slot].eventType.moist = 1; + DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); break; case 0x09: MIBLEsensors[_slot].fertility=_beacon.fert; + MIBLEsensors[_slot].eventType.fert = 1; DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); break; case 0x0a: + if(MI32.option.ignoreBogusBattery){ + if(MIBLEsensors[_slot].type==LYWSD03MMC || MIBLEsensors[_slot].type==MHOC401){ + break; + } + } if(_beacon.bat<101){ MIBLEsensors[_slot].bat = _beacon.bat; + MIBLEsensors[_slot].eventType.bat = 1; DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); } // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode a: U8: %u %%"), _beacon.bat); @@ -1132,40 +1212,39 @@ if (MIBLEsensors[_slot].type==NLIGHT){ MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated")); } + MIBLEsensors[_slot].eventType.tempHum = 1; // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); break; #ifdef USE_MI_DECRYPTION case 0x0f: if (_beacon.ten!=0) break; - MIBLEsensors[_slot].eventType = 1; //PIR - MIBLEsensors[_slot].shallSendMQTT = 1; + MIBLEsensors[_slot].eventType.motion = 1; MIBLEsensors[_slot].lastTime = millis(); MIBLEsensors[_slot].events++; MIBLEsensors[_slot].lux = _beacon.lux; + MIBLEsensors[_slot].eventType.lux = 1; MIBLEsensors[_slot].NMT = 0; // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("PIR: primary"),MIBLEsensors[_slot].lux ); - MI32triggerTele(); break; case 0x17: MIBLEsensors[_slot].NMT = _beacon.NMT; - MIBLEsensors[_slot].eventType = 3; // NMT - MIBLEsensors[_slot].shallSendMQTT = 1; + MIBLEsensors[_slot].eventType.NMT = 1; // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 17: NMT: %u seconds"), _beacon.NMT); - MI32triggerTele(); break; #endif //USE_MI_DECRYPTION default: if (MIBLEsensors[_slot].type==NLIGHT){ - MIBLEsensors[_slot].eventType = 1; //PIR - MIBLEsensors[_slot].shallSendMQTT = 1; + MIBLEsensors[_slot].eventType.motion = 1; //PIR MIBLEsensors[_slot].events++; MIBLEsensors[_slot].NMT = 0; MIBLEsensors[_slot].lastTime = millis(); // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("PIR: primary"),MIBLEsensors[_slot].lux ); - MI32triggerTele(); } break; } + if(MIBLEsensors[_slot].eventType.raw == 0) return; + MIBLEsensors[_slot].shallSendMQTT = 1; + MI32.mode.shallTriggerTele = 1; } void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi){ // no MiBeacon @@ -1183,11 +1262,13 @@ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi _tempFloat=(float)(_packet.temp)/10.0f; if(_tempFloat<60){ MIBLEsensors.at(_slot).temp = _tempFloat; + MIBLEsensors[_slot].eventType.temp = 1; DEBUG_SENSOR_LOG(PSTR("CGD1: temp updated")); } _tempFloat=(float)(_packet.hum)/10.0f; if(_tempFloat<100){ MIBLEsensors.at(_slot).hum = _tempFloat; + MIBLEsensors[_slot].eventType.hum = 1; DEBUG_SENSOR_LOG(PSTR("CGD1: hum updated")); } DEBUG_SENSOR_LOG(PSTR("CGD1: U16: %x Temp U16: %x Hum"), _packet.temp, _packet.hum); @@ -1195,12 +1276,16 @@ void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6], int rssi case 0x0102: if(_packet.bat<101){ MIBLEsensors.at(_slot).bat = _packet.bat; + MIBLEsensors[_slot].eventType.bat = 1; DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); } break; default: DEBUG_SENSOR_LOG(PSTR("MI32: unexpected CGD1-packet")); } + if(MIBLEsensors[_slot].eventType.raw == 0) return; + MIBLEsensors[_slot].shallSendMQTT = 1; + MI32.mode.shallTriggerTele = 1; } void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6], int rssi) { @@ -1241,9 +1326,14 @@ void MI32readHT_LY(char *_buf){ MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("LYWSD0x: hum updated")); } + MIBLEsensors[_slot].eventType.tempHum = 1; if (MIBLEsensors[_slot].type == LYWSD03MMC || MIBLEsensors[_slot].type == MHOC401){ MIBLEsensors[_slot].bat = ((float)LYWSD0x_HT.volt-2100.0f)/12.0f; + MI32.mode.willReadBatt = 0; + MIBLEsensors[_slot].eventType.bat = 1; } + MIBLEsensors[_slot].shallSendMQTT = 1; + MI32.mode.shallTriggerTele = 1; } } @@ -1260,12 +1350,27 @@ bool MI32readBat(char *_buf){ MIBLEsensors[_slot].firmware[5] = '\0'; AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Firmware: %s"),D_CMND_MI32,MIBLEsensors[_slot].firmware); } - return true; + MIBLEsensors[_slot].eventType.bat = 1; + MIBLEsensors[_slot].shallSendMQTT = 1; + MI32.mode.shallTriggerTele = 1; + return true; } } return false; } +/** + * @brief Launch functions from Core 1 to make race conditions less likely + * + */ + +void MI32Every50mSecond(){ + if(MI32.mode.shallTriggerTele){ + MI32.mode.shallTriggerTele = 0; + MI32triggerTele(); + } +} + /** * @brief Main loop of the driver, "high level"-loop * @@ -1473,71 +1578,117 @@ void MI32Show(bool json) if (json) { if(!MI32.mode.triggeredTele){ MI32.mode.shallClearResults=1; + if(MI32.option.noSummary) return; // no message at TELEPERIOD } - for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { - switch(MIBLEsensors[i].type){ - case NLIGHT: case MJYD2S: case YEERC: - if(MIBLEsensors[i].shallSendMQTT==0) continue; - break; - default: - if(MI32.mode.triggeredTele) continue; - break; - } - ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"), + for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { + if(MI32.mode.triggeredTele && MIBLEsensors[i].eventType.raw == 0) continue; + if(MI32.mode.triggeredTele && MIBLEsensors[i].shallSendMQTT==0) continue; + + ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":"), // do not add the '{' now ... kMI32DeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].MAC[3], MIBLEsensors[i].MAC[4], MIBLEsensors[i].MAC[5]); - ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].rssi); + uint32_t _positionCurlyBracket = strlen(mqtt_data); // ... this will be a ',' first, but later be replaced - if (MIBLEsensors[i].type == FLORA) { - if (!isnan(MIBLEsensors[i].temp)) { - char temperature[FLOATSZ]; // all sensors have temperature - dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); - ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%s"), temperature); + if((!MI32.mode.triggeredTele && !MI32.option.minimalSummary)||MI32.mode.triggeredTele){ + bool tempHumSended = false; + if(MIBLEsensors[i].feature.tempHum){ + if(MIBLEsensors[i].eventType.tempHum || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ + if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { + ResponseAppend_P(PSTR(",")); + ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum); + tempHumSended = true; + } + } } - if (MIBLEsensors[i].lux!=0x0ffffff) { // this is the error code -> no lux - ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); + if(MIBLEsensors[i].feature.temp && !tempHumSended){ + if(MIBLEsensors[i].eventType.temp || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate) { + if (!isnan(MIBLEsensors[i].temp)) { + char temperature[FLOATSZ]; + dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); + ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%s"), temperature); + } + } } - if (MIBLEsensors[i].moisture!=0xff) { - ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%u"), MIBLEsensors[i].moisture); + if(MIBLEsensors[i].feature.hum && !tempHumSended){ + if(MIBLEsensors[i].eventType.hum || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate) { + if (!isnan(MIBLEsensors[i].hum)) { + char hum[FLOATSZ]; + dtostrfd(MIBLEsensors[i].hum, Settings.flag2.humidity_resolution, hum); + ResponseAppend_P(PSTR(",\"" D_JSON_HUMIDITY "\":%s"), hum); + } + } } - if (MIBLEsensors[i].fertility!=0xffff) { - ResponseAppend_P(PSTR(",\"Fertility\":%u"), MIBLEsensors[i].fertility); + if (MIBLEsensors[i].feature.lux){ + if(MIBLEsensors[i].eventType.lux || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ + if (MIBLEsensors[i].lux!=0x0ffffff) { // this is the error code -> no lux + ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); + } + } } + if (MIBLEsensors[i].feature.moist){ + if(MIBLEsensors[i].eventType.moist || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ + if (MIBLEsensors[i].moisture!=0xff) { + ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%u"), MIBLEsensors[i].moisture); + } + } + } + if (MIBLEsensors[i].feature.fert){ + if(MIBLEsensors[i].eventType.fert || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ + if (MIBLEsensors[i].fertility!=0xffff) { + ResponseAppend_P(PSTR(",\"Fertility\":%u"), MIBLEsensors[i].fertility); + } + } + } + if (MIBLEsensors[i].feature.Btn){ + if(MIBLEsensors[i].eventType.Btn){ + ResponseAppend_P(PSTR(",\"Btn\":%u"),MIBLEsensors[i].Btn); + } + } + } // minimal summary + if (MIBLEsensors[i].feature.PIR){ + if(MIBLEsensors[i].eventType.motion || !MI32.mode.triggeredTele){ + if(MI32.mode.triggeredTele) ResponseAppend_P(PSTR(",\"PIR\":1")); // only real-time + ResponseAppend_P(PSTR(",\"Events\":%u"),MIBLEsensors[i].events); + } + else if(MIBLEsensors[i].eventType.noMotion && MI32.mode.triggeredTele){ + ResponseAppend_P(PSTR(",\"PIR\":0")); + } + } + + if (MIBLEsensors[i].type == FLORA && !MI32.mode.triggeredTele) { if (MIBLEsensors[i].firmware[0] != '\0') { // this is the error code -> no firmware ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); } } - if (MIBLEsensors[i].type > FLORA){ - if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { - ResponseAppend_P(PSTR(",")); - ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum); + + if (MIBLEsensors[i].feature.NMT || !MI32.mode.triggeredTele){ + if(MIBLEsensors[i].eventType.NMT){ + ResponseAppend_P(PSTR(",\"NMT\":%u"), MIBLEsensors[i].NMT); } } -#ifdef USE_MI_DECRYPTION - if (MIBLEsensors[i].type == MJYD2S){ - ResponseAppend_P(PSTR(",\"Events\":%u"),MIBLEsensors[i].events); - if(MIBLEsensors[i].shallSendMQTT && MIBLEsensors[i].eventType<3) ResponseAppend_P(PSTR(",\"PIR\":%u"), 2 - MIBLEsensors[i].eventType); - if(MIBLEsensors[i].eventType==3) ResponseAppend_P(PSTR(",\"NMT\":%u"), MIBLEsensors[i].NMT); - MIBLEsensors[i].eventType=0; - if(MIBLEsensors[i].lux!=0x0ffffff) ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); - } -#endif //USE_MI_DECRYPTION - if (MIBLEsensors[i].type == NLIGHT){ - ResponseAppend_P(PSTR(",\"Events\":%u"),MIBLEsensors[i].events); - if(MIBLEsensors[i].shallSendMQTT) ResponseAppend_P(PSTR(",\"PIR\":1")); - } - if (MIBLEsensors[i].type == YEERC){ - if(MIBLEsensors[i].shallSendMQTT) ResponseAppend_P(PSTR(",\"Btn\":%u"),MIBLEsensors[i].Btn); - } - if (MIBLEsensors[i].bat != 0x00) { // this is the error code -> no battery - ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); + if (MIBLEsensors[i].feature.bat){ + if(MIBLEsensors[i].eventType.bat || !MI32.mode.triggeredTele || MI32.option.allwaysAggregate){ + if (MIBLEsensors[i].bat != 0x00) { // this is the error code -> no battery + ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); + } + } } + if (MI32.option.showRSSI && MI32.mode.triggeredTele) ResponseAppend_P(PSTR(",\"RSSI\":%d"), MIBLEsensors[i].rssi); + + + if(_positionCurlyBracket==strlen(mqtt_data)) ResponseAppend_P(PSTR(",")); // write some random char, to be overwritten in the next step ResponseAppend_P(PSTR("}")); - MIBLEsensors[i].shallSendMQTT = 0; - MI32.mode.triggeredTele = 0; + mqtt_data[_positionCurlyBracket] = '{'; + MIBLEsensors[i].eventType.raw = 0; + if(MIBLEsensors[i].shallSendMQTT==1){ + MIBLEsensors[i].shallSendMQTT = 0; + break; + } } + MI32.mode.triggeredTele = 0; + // ResponseAppend_P(PSTR("}")); #ifdef USE_WEBSERVER } else { static uint16_t _page = 0; @@ -1618,6 +1769,9 @@ bool Xsns62(uint8_t function) if (MI32.mode.init) { switch (function) { + case FUNC_EVERY_50_MSECOND: + MI32Every50mSecond(); + break; case FUNC_EVERY_SECOND: MI32EverySecond(false); break; From 57fe4cf2482847ac24a3483f18907a10e7015e95 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 20 Jul 2020 10:04:39 +0200 Subject: [PATCH 523/581] Use Tasmota_stage core 2.7.3.1 from Tasmota Github and delete unneeded compiler flags --- platformio_override_sample.ini | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 57d7498cb..48298c782 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -88,13 +88,9 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage platform = espressif8266@2.5.1 -platform_packages = framework-arduinoespressif8266 @ https://github.com/Jason2866/Arduino/releases/download/2.7.3.1/esp8266-2.7.3.1.zip +platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.7.3.1/esp8266-2.7.3.1.zip build_unflags = ${esp_defaults.build_unflags} - -std=c17 - -std=gnu++17 build_flags = ${esp82xx_defaults.build_flags} - -std=gnu99 - -std=c++11 ; *********** Alternative Options, enable only if you know exactly what you do ******** ; NONOSDK221 From eeed6768d09640f9ff612491d7c8ee6657d54245 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 20 Jul 2020 11:20:58 +0200 Subject: [PATCH 524/581] Third try to fix counter interrupt storm --- tasmota/support_tasmota.ino | 15 ++++++--------- tasmota/xdrv_01_webserver.ino | 8 ++++---- tasmota/xsns_01_counter.ino | 32 +++----------------------------- 3 files changed, 13 insertions(+), 42 deletions(-) diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 0fbcbb615..054d830cc 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -969,6 +969,9 @@ void Every250mSeconds(void) SettingsSave(1); // Free flash for OTA update } if (ota_state_flag <= 0) { +#ifdef USE_COUNTER + CounterInterruptDisable(true); // Prevent OTA failures on 100Hz counter interrupts +#endif // USE_COUNTER #ifdef USE_WEBSERVER if (Settings.webserver) StopWebserver(); #endif // USE_WEBSERVER @@ -1000,15 +1003,6 @@ void Every250mSeconds(void) char *bch = strrchr(mqtt_data, '/'); // Only consider filename after last backslash prevent change of urls having "-" in it if (bch == nullptr) { bch = mqtt_data; } // No path found so use filename only -/* - char *ech = strrchr(bch, '.'); // Find file type in filename (none, .bin or .gz) - if ((ech != nullptr) && (0 == strncasecmp_P(ech, PSTR(".GZ"), 3))) { - char *fch = ech; - *fch = '\0'; - ech = strrchr(bch, '.'); // Find file type .bin.gz - *fch = '.'; - } -*/ char *ech = strchr(bch, '.'); // Find file type in filename (none, .ino.bin, .ino.bin.gz, .bin, .bin.gz or .gz) if (ech == nullptr) { ech = mqtt_data + strlen(mqtt_data); } // Point to '/0' at end of mqtt_data becoming an empty string @@ -1055,6 +1049,9 @@ void Every250mSeconds(void) ResponseAppend_P(PSTR("\"}")); // restart_flag = 2; // Restart anyway to keep memory clean webserver MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_UPGRADE)); +#ifdef USE_COUNTER + CounterInterruptDisable(false); +#endif // USE_COUNTER } } break; diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 112b9ac7f..b94a2a902 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2600,7 +2600,7 @@ void HandleUploadDone(void) MqttRetryCounter(0); #ifdef USE_COUNTER CounterInterruptDisable(false); -#endif +#endif // USE_COUNTER WSContentStart_P(S_INFORMATION); if (!Web.upload_error) { @@ -2677,8 +2677,8 @@ void HandleUploadLoop(void) } else { MqttRetryCounter(60); #ifdef USE_COUNTER - CounterInterruptDisable(true); -#endif + CounterInterruptDisable(true); // Prevent OTA failures on 100Hz counter interrupts +#endif // USE_COUNTER #ifdef USE_EMULATION UdpDisconnect(); #endif // USE_EMULATION @@ -2876,7 +2876,7 @@ void HandleUploadLoop(void) MqttRetryCounter(0); #ifdef USE_COUNTER CounterInterruptDisable(false); -#endif +#endif // USE_COUNTER Web.upload_error = 7; // Upload aborted if (UPL_TASMOTA == Web.upload_file_type) { Update.end(); } } diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index 73c19322e..5b6de4e4c 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -49,7 +49,6 @@ struct COUNTER { uint32_t last_cycle; uint32_t cycle_time; -//void ICACHE_RAM_ATTR CounterUpdate(uint8_t index) { void ICACHE_RAM_ATTR CounterIsrArg(void *arg) { uint32_t index = *static_cast(arg); @@ -94,15 +93,15 @@ void ICACHE_RAM_ATTR CounterIsrArg(void *arg) { // add 100.000 cpu ticks to ensure right step calculation uint32_t steps = (current_cycle-last_cycle+100000)/(clockCyclesPerMicrosecond() * 10000); cycle_time = (current_cycle-last_cycle)/steps; - #ifdef ESP8266 +#ifdef ESP8266 pinMode(Pin(GPIO_PWM1, index), OUTPUT); uint32_t high = (cycle_time * 5) / 1023; uint32_t low = cycle_time - high; // Find the first GPIO being generated by checking GCC's find-first-set (returns 1 + the bit of the first 1 in an int32_t startWaveformClockCycles(Pin(GPIO_PWM1, index), high, low, 0, -1, 0, true); - #else +#else // ESP32 analogWrite(Pin(GPIO_PWM1, index), 5); - #endif +#endif // ESP8266 - ESP32 } last_cycle = current_cycle; } @@ -120,27 +119,7 @@ void ICACHE_RAM_ATTR CounterIsrArg(void *arg) { } } } -/* -void ICACHE_RAM_ATTR CounterUpdate1(void) -{ - CounterUpdate(0); -} -void ICACHE_RAM_ATTR CounterUpdate2(void) -{ - CounterUpdate(1); -} - -void ICACHE_RAM_ATTR CounterUpdate3(void) -{ - CounterUpdate(2); -} - -void ICACHE_RAM_ATTR CounterUpdate4(void) -{ - CounterUpdate(3); -} -*/ /********************************************************************************************/ void CounterInterruptDisable(bool state) { @@ -172,20 +151,15 @@ bool CounterPinState(void) void CounterInit(void) { -// typedef void (*function) () ; -// function counter_callbacks[] = { CounterUpdate1, CounterUpdate2, CounterUpdate3, CounterUpdate4 }; - for (uint32_t i = 0; i < MAX_COUNTERS; i++) { if (PinUsed(GPIO_CNTR1, i)) { Counter.any_counter = true; pinMode(Pin(GPIO_CNTR1, i), bitRead(Counter.no_pullup, i) ? INPUT : INPUT_PULLUP); if ((0 == Settings.pulse_counter_debounce_low) && (0 == Settings.pulse_counter_debounce_high) && !Settings.flag4.zerocross_dimmer) { Counter.pin_state = 0; -// attachInterrupt(Pin(GPIO_CNTR1, i), counter_callbacks[i], FALLING); attachInterruptArg(Pin(GPIO_CNTR1, i), CounterIsrArg, &ctr_index[i], FALLING); } else { Counter.pin_state = 0x8f; -// attachInterrupt(Pin(GPIO_CNTR1, i), counter_callbacks[i], CHANGE); attachInterruptArg(Pin(GPIO_CNTR1, i), CounterIsrArg, &ctr_index[i], CHANGE); } } From cea8e169a428cc85bc97b57d07241f0df86ec670 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 20 Jul 2020 12:00:46 +0200 Subject: [PATCH 525/581] Adding maintained badges in readme. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 19fbff041..97413616e 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ _Written for PlatformIO with limited support for Arduino IDE._ [![GitHub download](https://img.shields.io/github/downloads/arendst/Tasmota/total.svg)](https://github.com/arendst/Tasmota/releases/latest) [![License](https://img.shields.io/github/license/arendst/Tasmota.svg)](LICENSE.txt) [![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4) +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/arendst/Tasmota.svg)](http://isitmaintained.com/project/arendst/Tasmota "Average time to resolve an issue") +[![Percentage of issues still open](http://isitmaintained.com/badge/open/arendst/Tasmota.svg)](http://isitmaintained.com/project/arendst/Tasmota "Percentage of issues still open") If you like **Tasmota**, give it a star, or fork it and contribute! From 0a64625e9a1486c75f07ea7ec2892112ed4bb576 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 20 Jul 2020 16:26:32 +0200 Subject: [PATCH 526/581] Allow rules on energy margins Allow rules on energy margins (#8935) --- tasmota/xdrv_03_energy.ino | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index f38265bb8..afa818913 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -110,7 +110,6 @@ struct ENERGY { #ifdef USE_ENERGY_MARGIN_DETECTION uint16_t power_history[3] = { 0 }; uint8_t power_steady_counter = 8; // Allow for power on stabilization - bool power_delta = false; bool min_power_flag = false; bool max_power_flag = false; bool min_voltage_flag = false; @@ -306,23 +305,30 @@ void EnergyMarginCheck(void) uint16_t energy_power_u = (uint16_t)(Energy.active_power[0]); + bool jsonflg = false; + Response_P(PSTR("{")); + if (Settings.energy_power_delta) { - uint16_t delta = abs(Energy.power_history[0] - energy_power_u); + int16_t power_diff = energy_power_u - Energy.power_history[0]; + uint16_t delta = abs(power_diff); if (delta > 0) { if (Settings.energy_power_delta < 101) { // 1..100 = Percentage uint16_t min_power = (Energy.power_history[0] > energy_power_u) ? energy_power_u : Energy.power_history[0]; if (0 == min_power) { min_power++; } // Fix divide by 0 exception (#6741) - if (((delta * 100) / min_power) > Settings.energy_power_delta) { - Energy.power_delta = true; + delta = (delta * 100) / min_power; + if (delta > Settings.energy_power_delta) { + jsonflg = true; } } else { // 101..32000 = Absolute if (delta > (Settings.energy_power_delta -100)) { - Energy.power_delta = true; + jsonflg = true; } } - if (Energy.power_delta) { + if (jsonflg) { Energy.power_history[1] = Energy.active_power[0]; // We only want one report so reset history Energy.power_history[2] = Energy.active_power[0]; + + ResponseAppend_P(PSTR("\"" D_CMND_POWERDELTA "\":%d"), power_diff); } } } @@ -336,9 +342,7 @@ void EnergyMarginCheck(void) DEBUG_DRIVER_LOG(PSTR("NRG: W %d, U %d, I %d"), energy_power_u, energy_voltage_u, energy_current_u); - Response_P(PSTR("{")); bool flag; - bool jsonflg = false; if (EnergyMargin(false, Settings.energy_min_power, energy_power_u, flag, Energy.min_power_flag)) { ResponseAppend_P(PSTR("%s\"" D_CMND_POWERLOW "\":\"%s\""), (jsonflg)?",":"", GetStateText(flag)); jsonflg = true; @@ -363,11 +367,12 @@ void EnergyMarginCheck(void) ResponseAppend_P(PSTR("%s\"" D_CMND_CURRENTHIGH "\":\"%s\""), (jsonflg)?",":"", GetStateText(flag)); jsonflg = true; } - if (jsonflg) { - ResponseJsonEnd(); - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_MARGINS), MQTT_TELE_RETAIN); - EnergyMqttShow(); - } + } + if (jsonflg) { + ResponseJsonEnd(); + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_MARGINS), MQTT_TELE_RETAIN); + XdrvRulesProcess(); + EnergyMqttShow(); } #ifdef USE_ENERGY_POWER_LIMIT @@ -436,8 +441,6 @@ void EnergyMarginCheck(void) } } #endif // USE_ENERGY_POWER_LIMIT - - if (Energy.power_delta) { EnergyMqttShow(); } } void EnergyMqttShow(void) @@ -451,7 +454,6 @@ void EnergyMqttShow(void) tele_period = tele_period_save; ResponseJsonEnd(); MqttPublishTeleSensor(); - Energy.power_delta = false; } #endif // USE_ENERGY_MARGIN_DETECTION From 59f50d04f2c0f1bca8d949d913a68dcfff3801e9 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 20 Jul 2020 16:41:05 +0200 Subject: [PATCH 527/581] Allow rules on energy margins Allow rules on energy margins (#8935) --- tasmota/xdrv_03_energy.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index afa818913..0afeec26b 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -306,7 +306,7 @@ void EnergyMarginCheck(void) uint16_t energy_power_u = (uint16_t)(Energy.active_power[0]); bool jsonflg = false; - Response_P(PSTR("{")); + Response_P(PSTR("{\"" D_RSLT_MARGINS "\":{")); if (Settings.energy_power_delta) { int16_t power_diff = energy_power_u - Energy.power_history[0]; @@ -369,7 +369,7 @@ void EnergyMarginCheck(void) } } if (jsonflg) { - ResponseJsonEnd(); + ResponseJsonEndEnd(); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_MARGINS), MQTT_TELE_RETAIN); XdrvRulesProcess(); EnergyMqttShow(); From bc3efb5696f6b3001856f88aae17fdfa9d22b359 Mon Sep 17 00:00:00 2001 From: Antonio Fernandez Date: Mon, 20 Jul 2020 10:57:38 -0400 Subject: [PATCH 528/581] Updated the D_TIMER_ARM variable to say "Enable" Arm has been a bit of a confusing term. I think it would help new users out to rename this to "Enable". It will make the button more intuitive. --- tasmota/language/en_GB.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 98badad64..1ae054f0e 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -419,7 +419,7 @@ #define D_CONFIGURE_TIMER "Configure Timer" #define D_TIMER_PARAMETERS "Timer parameters" #define D_TIMER_ENABLE "Enable Timers" -#define D_TIMER_ARM "Arm" +#define D_TIMER_ARM "Enable" #define D_TIMER_TIME "Time" #define D_TIMER_DAYS "Days" #define D_TIMER_REPEAT "Repeat" From a84ebe552adce2f482d906107554704c06a696f1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 20 Jul 2020 17:24:51 +0200 Subject: [PATCH 529/581] Refactor rules processing --- tasmota/support_command.ino | 3 +- tasmota/support_rotary.ino | 3 +- tasmota/support_tasmota.ino | 3 +- tasmota/xdrv_02_mqtt.ino | 14 ++++- tasmota/xdrv_03_energy.ino | 3 +- tasmota/xdrv_04_light.ino | 3 +- tasmota/xdrv_05_irremote.ino | 3 +- tasmota/xdrv_05_irremote_full.ino | 6 +-- tasmota/xdrv_06_snfbridge.ino | 7 +-- tasmota/xdrv_08_serial_bridge.ino | 3 +- tasmota/xdrv_17_rcswitch.ino | 3 +- tasmota/xdrv_23_zigbee_5_converters.ino | 6 +-- tasmota/xdrv_23_zigbee_7_statemachine.ino | 3 +- tasmota/xdrv_23_zigbee_8_parsers.ino | 63 ++++++++--------------- tasmota/xdrv_23_zigbee_9_serial.ino | 21 ++++---- tasmota/xdrv_23_zigbee_A_impl.ino | 7 ++- tasmota/xdrv_27_shutter.ino | 6 +-- tasmota/xdrv_31_tasmota_client.ino | 3 +- tasmota/xdrv_38_ping.ino | 11 ++-- 19 files changed, 68 insertions(+), 103 deletions(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index abd75960e..6d0f50f3a 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -288,8 +288,7 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) } if (mqtt_data[0] != '\0') { - MqttPublishPrefixTopic_P(RESULT_OR_STAT, type); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, type); } fallback_topic_flag = false; } diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 4fc776511..76c748203 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -136,8 +136,7 @@ void RotaryHandler(void) { #ifdef USE_LIGHT if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control ResponseLightState(0); - MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_CMND_STATE)); } #endif // USE_LIGHT Encoder[index].direction = 0; diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 054d830cc..9007d0157 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1429,8 +1429,7 @@ void SerialInput(void) } ResponseJsonEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED)); serial_in_byte_counter = 0; } } diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 1f232cff8..a9038a941 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -381,10 +381,20 @@ void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic) MqttPublishPrefixTopic_P(prefix, subtopic, false); } +void MqttPublishPrefixTopicRulesProcess_P(uint32_t prefix, const char* subtopic, bool retained) +{ + MqttPublishPrefixTopic_P(prefix, subtopic, retained); + XdrvRulesProcess(); +} + +void MqttPublishPrefixTopicRulesProcess_P(uint32_t prefix, const char* subtopic) +{ + MqttPublishPrefixTopicRulesProcess_P(prefix, subtopic, false); +} + void MqttPublishTeleSensor(void) { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); // CMND_SENSORRETAIN - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); // CMND_SENSORRETAIN } void MqttPublishPowerState(uint32_t device) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index 0afeec26b..4d53af77c 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -370,8 +370,7 @@ void EnergyMarginCheck(void) } if (jsonflg) { ResponseJsonEndEnd(); - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_MARGINS), MQTT_TELE_RETAIN); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_MARGINS), MQTT_TELE_RETAIN); EnergyMqttShow(); } diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index ab311d6f0..18881d119 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1878,8 +1878,7 @@ void LightAnimate(void) Response_P(PSTR("{\"" D_CMND_WAKEUP "\":\"" D_JSON_DONE "\"")); ResponseLightState(1); ResponseJsonEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_WAKEUP)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_CMND_WAKEUP)); Light.wakeup_active = 0; Settings.light_scheme = LS_POWER; diff --git a/tasmota/xdrv_05_irremote.ino b/tasmota/xdrv_05_irremote.ino index 87a51de53..bb5ce0c3c 100644 --- a/tasmota/xdrv_05_irremote.ino +++ b/tasmota/xdrv_05_irremote.ino @@ -155,9 +155,8 @@ void IrReceiveCheck(void) } ResponseJsonEndEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED)); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED)); - XdrvRulesProcess(); #ifdef USE_DOMOTICZ if (iridx) { unsigned long value = results.value | (iridx << 28); // [Protocol:4, Data:28] diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index 457ff63f4..9649e87b4 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -232,9 +232,7 @@ void IrReceiveCheck(void) } ResponseJsonEndEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED)); - - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_IRRECEIVED)); } irrecv->resume(); @@ -475,7 +473,7 @@ uint32_t IrRemoteCmndIrSendRaw(void) for (uint32_t i = 0; i <= count; i++) { GC[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); if (!GC[i]) { - return IE_INVALID_RAWDATA; + return IE_INVALID_RAWDATA; } } irsend_active = true; diff --git a/tasmota/xdrv_06_snfbridge.ino b/tasmota/xdrv_06_snfbridge.ino index 210ff87a3..af6f928bd 100644 --- a/tasmota/xdrv_06_snfbridge.ino +++ b/tasmota/xdrv_06_snfbridge.ino @@ -226,9 +226,7 @@ void SonoffBridgeReceivedRaw(void) } } ResponseAppend_P(PSTR("\"}}")); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_CMND_RFRAW)); - - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_CMND_RFRAW)); } /********************************************************************************************/ @@ -298,8 +296,7 @@ void SonoffBridgeReceived(void) } ResponseTime_P(PSTR(",\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_SYNC "\":%d,\"" D_JSON_LOW "\":%d,\"" D_JSON_HIGH "\":%d,\"" D_JSON_DATA "\":%s,\"" D_CMND_RFKEY "\":%s}}"), sync_time, low_time, high_time, stemp, rfkey); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED)); #ifdef USE_DOMOTICZ DomoticzSensor(DZ_COUNT, received_id); // Send rid as Domoticz Counter value #endif // USE_DOMOTICZ diff --git a/tasmota/xdrv_08_serial_bridge.ino b/tasmota/xdrv_08_serial_bridge.ino index 0dec9cb6b..b5a9143b7 100644 --- a/tasmota/xdrv_08_serial_bridge.ino +++ b/tasmota/xdrv_08_serial_bridge.ino @@ -93,8 +93,7 @@ void SerialBridgeInput(void) } ResponseJsonEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); serial_bridge_in_byte_counter = 0; } } diff --git a/tasmota/xdrv_17_rcswitch.ino b/tasmota/xdrv_17_rcswitch.ino index c5013828c..ac4111e83 100644 --- a/tasmota/xdrv_17_rcswitch.ino +++ b/tasmota/xdrv_17_rcswitch.ino @@ -69,8 +69,7 @@ void RfReceiveCheck(void) } ResponseTime_P(PSTR(",\"" D_JSON_RFRECEIVED "\":{\"" D_JSON_RF_DATA "\":%s,\"" D_JSON_RF_BITS "\":%d,\"" D_JSON_RF_PROTOCOL "\":%d,\"" D_JSON_RF_PULSE "\":%d}}"), stemp, bits, protocol, delay); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_RFRECEIVED)); #ifdef USE_DOMOTICZ DomoticzSensor(DZ_COUNT, data); // Send data as Domoticz Counter value #endif // USE_DOMOTICZ diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 26781d358..578e3c3bf 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -622,8 +622,7 @@ public: _frame_control, _manuf_code, _transact_seq, _cmd_id, hex_char); if (Settings.flag3.tuya_serial_mqtt_publish) { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR)); } else { AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); } @@ -1152,8 +1151,7 @@ void ZCLFrame::parseResponse(void) { msg.reserve(100); json.printTo(msg); Response_P(PSTR("{\"" D_JSON_ZIGBEE_RESPONSE "\":%s}"), msg.c_str()); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); } diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index fecf68fe9..50e67f91c 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -1097,8 +1097,7 @@ void ZigbeeStateMachine_Run(void) { const char *f_msg = (const char*) cur_ptr1; Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{\"Status\":%d,\"Message\":\"%s\"}}"), cur_d8, f_msg); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); } break; case ZGB_INSTR_SEND: diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index a94a07aeb..e0239f316 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -43,8 +43,7 @@ int32_t EZ_RSTACK(uint8_t reset_code) { ",\"Code\":%d}}"), ZIGBEE_STATUS_BOOT, reason_str, reset_code); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); } // EZSP: received ASH "ERROR" frame, indicating that the MCU finished boot @@ -60,8 +59,7 @@ int32_t EZ_ERROR(uint8_t error_code) { ",\"Code\":%d}}"), ZIGBEE_STATUS_ABORT, reason_str, error_code); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); } int32_t EZ_ReadAPSUnicastMessage(int32_t res, class SBuffer &buf) { @@ -112,8 +110,7 @@ int32_t EZ_NetworkParameters(int32_t res, class SBuffer &buf) { ",\"DeviceType\":%d}}"), ZIGBEE_STATUS_EZ_INFO, hex, localShortAddr, node_type); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); return res; } @@ -161,8 +158,7 @@ int32_t Z_EZSPNetworkParameters(int32_t res, class SBuffer &buf) { ",\"DeviceType\":%d}}"), ZIGBEE_STATUS_EZ_INFO, hex, localShortAddr, node_type); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); return res; } @@ -212,10 +208,8 @@ int32_t ZNP_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { ResponseAppend_P(PSTR("]")); } - ResponseJsonEnd(); // append '}' - ResponseJsonEnd(); // append '}' - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + ResponseJsonEndEnd(); // append '}}' + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); return res; } @@ -257,8 +251,7 @@ int32_t ZNP_Reboot(int32_t res, class SBuffer &buf) { ZIGBEE_STATUS_BOOT, reason_str, major_rel, minor_rel); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); if ((0x02 == major_rel) && (0x06 == minor_rel)) { return 0; // version 2.6.x is ok @@ -289,8 +282,7 @@ int32_t ZNP_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { ZIGBEE_STATUS_CC_VERSION, major_rel, minor_rel, maint_rel, revision); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); if ((0x02 == major_rel) && (0x06 == minor_rel)) { return 0; // version 2.6.x is ok @@ -318,8 +310,7 @@ int32_t EZ_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { stack_type ); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); if (0x08 == protocol_version) { return 0; // protocol v8 is ok @@ -394,8 +385,7 @@ int32_t ZNP_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) { ResponseAppend_P(message, duration); ResponseAppend_P(PSTR("\"}}")); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); return -1; } @@ -435,8 +425,7 @@ int32_t ZNP_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) { complexDescriptorAvailable ? PSTR("true") : PSTR("false") ); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); } return -1; @@ -473,8 +462,7 @@ int32_t Z_ReceiveActiveEp(int32_t res, const class SBuffer &buf) { ResponseAppend_P(PSTR("\"0x%02X\""), activeEpList[i]); } ResponseAppend_P(PSTR("]}}")); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); Z_SendAFInfoRequest(nwkAddr); // probe for ModelId and ManufId @@ -515,8 +503,7 @@ int32_t Z_ReceiveIEEEAddr(int32_t res, const class SBuffer &buf) { } ResponseAppend_P(PSTR("\"}}")); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); } return -1; } @@ -534,8 +521,7 @@ int32_t ZNP_DataConfirm(int32_t res, const class SBuffer &buf) { ",\"" D_JSON_ZIGBEE_STATUS "\":%d" ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" "}}"), endpoint, status, getZigbeeStatusMessage(status).c_str()); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); } return -1; @@ -591,8 +577,7 @@ int32_t ZNP_ReceiveStateChange(int32_t res, const class SBuffer &buf) { ZIGBEE_STATUS_SCANNING, state, msg ); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); } if ((ZDO_DEV_END_DEVICE == state) || (ZDO_DEV_ROUTER == state) || (ZDO_DEV_ZB_COORD == state)) { @@ -637,8 +622,7 @@ int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) { uint32_t wait_ms = 2000; // wait for 2s Z_Query_Bulb(nwkAddr, wait_ms); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); Z_SendActiveEpReq(nwkAddr); return -1; } @@ -662,8 +646,7 @@ int32_t ZNP_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) { ZIGBEE_STATUS_DEVICE_INDICATION, hex, srcAddr, parentNw ); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); return -1; } @@ -692,8 +675,7 @@ int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) { ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" "}}"), status, msg.c_str()); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); return -1; } @@ -723,8 +705,7 @@ int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) { ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" "}}"), status, msg.c_str()); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); return -1; } @@ -799,8 +780,7 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { ResponseAppend_P(PSTR("]}}")); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_BIND_STATE)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_BIND_STATE)); return -1; } @@ -880,8 +860,7 @@ int32_t EZ_ReceiveTCJoinHandler(int32_t res, const class SBuffer &buf) { status, decision ); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); } return -1; } diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index aeefe8ae4..cd5ef3c4f 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -131,8 +131,7 @@ void ZigbeeInputLoop(void) { ToHex_P((unsigned char*)znp_buffer.getBuffer(), znp_buffer.len(), hex_char, sizeof(hex_char)); Response_P(PSTR("{\"" D_JSON_ZIGBEEZNPRECEIVED "\":\"%s\"}"), hex_char); if (Settings.flag3.tuya_serial_mqtt_publish) { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR)); } else { AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); } @@ -194,7 +193,7 @@ void ZigbeeInputLoop(void) { if (zigbee_buffer->len() < ZIGBEE_BUFFER_SIZE) { if (escape) { // invert bit 5 - zigbee_in_byte ^= 0x20; + zigbee_in_byte ^= 0x20; escape = false; } @@ -252,8 +251,7 @@ void ZigbeeInputLoop(void) { ToHex_P((unsigned char*)ezsp_buffer.getBuffer(), ezsp_buffer.len(), hex_char, sizeof(hex_char)); Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "2\":\"%s\"}"), hex_char); if (Settings.flag3.tuya_serial_mqtt_publish) { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR)); } else { AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable } @@ -435,7 +433,7 @@ void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { bool data_frame = (0 == (msg[0] & 0x80)); uint8_t rand = 0x42; // pseudo-randomizer initial value uint16_t crc = 0xFFFF; // CRC16 CCITT initialization - + for (uint32_t i=0; i 0xFFFF) { group = 0xFFFF; } - + SBuffer buf(8); buf.add16(EZSP_setMulticastTableEntry); buf.add8(index); diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index 6d0c6e5ce..660c5e2c3 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -279,8 +279,7 @@ void ShutterReportPosition(bool always, uint32_t index) } ResponseJsonEnd(); if (always || (rules_flag.shutter_moving)) { - MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); - XdrvRulesProcess(); //RulesProcess() now re-entry protected + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); // RulesProcess() now re-entry protected } //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: rules_flag.shutter_moving: %d, moved %d"), rules_flag.shutter_moving, rules_flag.shutter_moved); @@ -716,8 +715,7 @@ void ShutterButtonHandler(void) Response_P(PSTR("{")); ResponseAppend_P(JSON_SHUTTER_BUTTON, shutter_index+1, (buttonState <= SHT_PRESSED_EXT_HOLD) ? (button_index+1) : 0, press_index); ResponseJsonEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); } } diff --git a/tasmota/xdrv_31_tasmota_client.ino b/tasmota/xdrv_31_tasmota_client.ino index 3fdbad076..86121475c 100644 --- a/tasmota/xdrv_31_tasmota_client.ino +++ b/tasmota/xdrv_31_tasmota_client.ino @@ -539,8 +539,7 @@ void TasmotaClient_ProcessIn(void) { Response_P(PSTR("{\"TasmotaClient\":")); ResponseAppend_P("%s", inbuf); ResponseJsonEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); - XdrvRulesProcess(); + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, mqtt_data); } if (CMND_EXECUTE_CMND == TClientCommand.command) { // We need to execute the incoming command ExecuteCommand(inbuf, SRC_IGNORE); diff --git a/tasmota/xdrv_38_ping.ino b/tasmota/xdrv_38_ping.ino index d30c0093d..4724ee310 100644 --- a/tasmota/xdrv_38_ping.ino +++ b/tasmota/xdrv_38_ping.ino @@ -35,7 +35,7 @@ void (* const PingCommand[])(void) PROGMEM = { }; extern "C" { - + extern uint32 system_relative_time(uint32 time); extern void ets_bzero(void *s, size_t n); @@ -130,7 +130,7 @@ extern "C" { if ((p->len == p->tot_len) && (p->next == nullptr)) { ip_addr_t ping_target; struct icmp_echo_hdr *iecho; - + ping_target.addr = ping->ip; iecho = (struct icmp_echo_hdr *) p->payload; @@ -177,7 +177,7 @@ extern "C" { iecho = (struct icmp_echo_hdr *)p->payload; if ((iecho->id == Ping_ID) && (iecho->seqno == htons(ping->seq_num)) && iecho->type == ICMP_ER) { - + if (iecho->seqno != ping->seqno){ // debounce already received packet /* do some ping result processing */ sys_untimeout(t_ping_timeout, ping); // remove time-out handler @@ -282,9 +282,8 @@ void PingResponsePoll(void) { success ? ping->min_time : 0, ping->max_time, success ? ping->sum_time / success : 0 ); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_PING)); - XdrvRulesProcess(); - + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_PING)); + // remove from linked list *prev_link = ping->next; // don't increment prev_link From 2da8f3c3934bbd8747545ea3700b8048fc0acef2 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 20 Jul 2020 19:30:32 +0200 Subject: [PATCH 530/581] Added `SO101 1` to suffix commands with source endpoint --- tasmota/settings.h | 2 +- tasmota/xdrv_23_zigbee_2_devices.ino | 18 +++++++++ tasmota/xdrv_23_zigbee_5_converters.ino | 9 ++++- tasmota/xdrv_23_zigbee_6_commands.ino | 24 +++++++++-- tasmota/xdrv_23_zigbee_8_parsers.ino | 53 +++++++++++++++++-------- tasmota/xdrv_23_zigbee_A_impl.ino | 16 +++++++- 6 files changed, 99 insertions(+), 23 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 9d4466028..57aa35860 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -120,7 +120,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t rotary_uses_rules : 1; // bit 16 (v8.3.1.6) - SetOption98 - Use rules instead of light control uint32_t zerocross_dimmer : 1; // bit 17 (v8.3.1.4) - SetOption99 - Enable zerocross dimmer on PWM DIMMER uint32_t remove_zbreceived : 1; // bit 18 (v8.3.1.7) - SetOption100 - Remove ZbReceived form JSON message - uint32_t spare19 : 1; + uint32_t zb_index_ep : 1; // bit 19 (v8.3.1.7) - SetOption101 - Add the source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 uint32_t spare20 : 1; uint32_t spare21 : 1; uint32_t spare22 : 1; diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index abcf6440c..d87fe4005 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -141,6 +141,7 @@ public: // Add an endpoint to a device void addEndpoint(uint16_t shortaddr, uint8_t endpoint); void clearEndpoints(uint16_t shortaddr); + uint32_t countEndpoints(uint16_t shortaddr) const; // return the number of known endpoints (0 if unknown) void setManufId(uint16_t shortaddr, const char * str); void setModelId(uint16_t shortaddr, const char * str); @@ -533,6 +534,23 @@ void Z_Devices::addEndpoint(uint16_t shortaddr, uint8_t endpoint) { } } +// +// Count the number of known endpoints +// +uint32_t Z_Devices::countEndpoints(uint16_t shortaddr) const { + uint32_t count_ep = 0; + int32_t found = findShortAddr(shortaddr); + if (found < 0) return 0; // avoid creating an entry if the device was never seen + const Z_Device &device = devicesAt(found); + + for (uint32_t i = 0; i < endpoints_max; i++) { + if (0 != device.endpoints[i]) { + count_ep++; + } + } + return count_ep; +} + // Find the first endpoint of the device uint8_t Z_Devices::findFirstEndpoint(uint16_t shortaddr) const { // When in router of end-device mode, the coordinator was not probed, in this case always talk to endpoint 1 diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 578e3c3bf..454e9b5cf 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -1157,7 +1157,7 @@ void ZCLFrame::parseResponse(void) { // Parse non-normalized attributes void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) { - convertClusterSpecific(json, _cluster_id, _cmd_id, _frame_control.b.direction, _payload); + convertClusterSpecific(json, _cluster_id, _cmd_id, _frame_control.b.direction, _srcaddr, _srcendpoint, _payload); sendHueUpdate(_srcaddr, _groupaddr, _cluster_id, _cmd_id, _frame_control.b.direction); } @@ -1423,6 +1423,8 @@ int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObje } void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) { + // source endpoint + uint8_t src_ep = _srcendpoint; // iterate on json elements for (auto kv : json) { String key_string = kv.key; @@ -1490,6 +1492,11 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) { ((conv_attribute == attribute) || (conv_attribute == 0xFFFF)) ) { String new_name_str = (const __FlashStringHelper*) converter->name; if (suffix > 1) { new_name_str += suffix; } // append suffix number + // else if (Settings.flag4.zb_index_ep) { + // if (zigbee_devices.countEndpoints(shortaddr) > 0) { + // new_name_str += _srcendpoint; + // } + // } // apply the transformation int32_t drop = Z_ApplyConverter(this, shortaddr, json, key, value, new_name_str, conv_cluster, conv_attribute, conv_multiplier, conv_cb); if (drop) { diff --git a/tasmota/xdrv_23_zigbee_6_commands.ino b/tasmota/xdrv_23_zigbee_6_commands.ino index 40545f737..c2ea81765 100644 --- a/tasmota/xdrv_23_zigbee_6_commands.ino +++ b/tasmota/xdrv_23_zigbee_6_commands.ino @@ -341,7 +341,7 @@ void sendHueUpdate(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uin // Parse a cluster specific command, and try to convert into human readable -void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, bool direction, const SBuffer &payload) { +void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, bool direction, uint16_t shortaddr, uint8_t srcendpoint, const SBuffer &payload) { size_t hex_char_len = payload.len()*2+2; char *hex_char = (char*) malloc(hex_char_len); if (!hex_char) { return; } @@ -414,11 +414,11 @@ void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, boo if (command_name) { // Now try to transform into a human readable format + String command_name2 = String(command_name); // if (direction & 0x80) then specific transform if (conv_direction & 0x80) { // TODO need to create a specific command // IAS - String command_name2 = String(command_name); if ((cluster == 0x0500) && (cmd == 0x00)) { // "ZoneStatusChange" json[command_name] = xyz.x; @@ -465,11 +465,21 @@ void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, boo String scene_payload = json[attrid_str]; json[F("ScenePayload")] = scene_payload.substring(8); // remove first 8 characters } - } else { + } else { // general case + bool extended_command = false; // do we send command with endpoint suffix + // if SO101 and multiple endpoints, append endpoint number + if (Settings.flag4.zb_index_ep) { + if (zigbee_devices.countEndpoints(shortaddr) > 0) { + command_name2 += srcendpoint; + extended_command = true; + } + } if (0 == xyz.x_type) { json[command_name] = true; // no parameter + if (extended_command) { json[command_name2] = true; } } else if (0 == xyz.y_type) { json[command_name] = xyz.x; // 1 parameter + if (extended_command) { json[command_name2] = xyz.x; } } else { // multiple answers, create an array JsonArray &arr = json.createNestedArray(command_name); @@ -478,6 +488,14 @@ void convertClusterSpecific(JsonObject& json, uint16_t cluster, uint8_t cmd, boo if (xyz.z_type) { arr.add(xyz.z); } + if (extended_command) { + JsonArray &arr = json.createNestedArray(command_name2); + arr.add(xyz.x); + arr.add(xyz.y); + if (xyz.z_type) { + arr.add(xyz.z); + } + } } } } diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index e0239f316..c08ff4d28 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -966,23 +966,44 @@ void EZ_SendZDO(uint16_t shortaddr, uint16_t cmd, const unsigned char *payload, SBuffer buf(payload_len + 22); uint8_t seq = zigbee_devices.getNextSeqNumber(0x0000); - buf.add16(EZSP_sendUnicast); + if (shortaddr < 0xFFFC) { + // send unicast + buf.add16(EZSP_sendUnicast); - buf.add8(EMBER_OUTGOING_DIRECT); // 00 - buf.add16(shortaddr); // dest addr - // ApsFrame - buf.add16(0x0000); // ZOD profile - buf.add16(cmd); // ZDO cmd in cluster - buf.add8(0); // srcEp - buf.add8(0); // dstEp - buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame - buf.add16(0x0000); // groupId - buf.add8(seq); - // end of ApsFrame - buf.add8(0x01); // tag TODO - buf.add8(payload_len + 1); // insert seq number - buf.add8(seq); - buf.addBuffer(payload, payload_len); + buf.add8(EMBER_OUTGOING_DIRECT); // 00 + buf.add16(shortaddr); // dest addr + // ApsFrame + buf.add16(0x0000); // ZOD profile + buf.add16(cmd); // ZDO cmd in cluster + buf.add8(0); // srcEp + buf.add8(0); // dstEp + buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame + buf.add16(0x0000); // groupId + buf.add8(seq); + // end of ApsFrame + buf.add8(0x01); // tag TODO + buf.add8(payload_len + 1); // insert seq number + buf.add8(seq); + buf.addBuffer(payload, payload_len); + } else { + // send broadcast + buf.add16(EZSP_sendBroadcast); + buf.add16(shortaddr); // dest addr + // ApsFrame + buf.add16(0x0000); // ZOD profile + buf.add16(cmd); // ZDO cmd in cluster + buf.add8(0); // srcEp + buf.add8(0); // dstEp + buf.add16(0x00); // APS frame + buf.add16(0x0000); // groupId + buf.add8(seq); + // end of ApsFrame + buf.add8(0x1E); // radius + buf.add8(0x01); // tag TODO + buf.add8(payload_len + 1); // insert seq number + buf.add8(seq); + buf.addBuffer(payload, payload_len); + } ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true); } diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 57ecd3764..5922b3ee3 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -992,12 +992,14 @@ void CmndZbPermitJoin(void) { if (payload <= 0) { duration = 0; - } else if (99 == payload) { - duration = 0xFF; // unlimited time } // ZNP Version #ifdef USE_ZIGBEE_ZNP + if (99 == payload) { + duration = 0xFF; // unlimited time + } + uint16_t dstAddr = 0xFFFC; // default addr SBuffer buf(34); @@ -1014,10 +1016,20 @@ void CmndZbPermitJoin(void) { // EZSP VERSION #ifdef USE_ZIGBEE_EZSP + if (99 == payload) { + ResponseCmndChar_P(PSTR("Unlimited time not supported")); return; + } + SBuffer buf(3); buf.add16(EZSP_permitJoining); buf.add8(duration); ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); + + // send ZDO_Mgmt_Permit_Joining_req to all routers + buf.setLen(0); + buf.add8(duration); + buf.add8(0x01); // TC_Significance - This field shall always have a value of 1, indicating a request to change the Trust Center policy. If a frame is received with a value of 0, it shall be treated as having a value of 1. + // EZ_SendZDO(0xFFFC, ZDO_Mgmt_Permit_Joining_req, buf.buf(), buf.len()); TODO fix NAK/ACK first #endif // USE_ZIGBEE_EZSP ResponseCmndDone(); From f0177f3c483e4da8967baa0d741cc6a3e78901b8 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Tue, 21 Jul 2020 07:24:14 +0200 Subject: [PATCH 531/581] Add ShutterToggleDir/ShutterStopToggleDir same function as ShutterToggle/ShutterStopToggle but based on last movement direction, not on current position (< or > 50%) --- tasmota/i18n.h | 2 ++ tasmota/xdrv_27_shutter.ino | 65 ++++++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 70ca42a7e..fb5cbceb3 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -576,11 +576,13 @@ #define D_CMND_SHUTTER_OPEN "Open" #define D_CMND_SHUTTER_CLOSE "Close" #define D_CMND_SHUTTER_TOGGLE "Toggle" +#define D_CMND_SHUTTER_TOGGLEDIR "ToggleDir" #define D_CMND_SHUTTER_UP "Up" #define D_CMND_SHUTTER_DOWN "Down" #define D_CMND_SHUTTER_STOPOPEN "StopOpen" #define D_CMND_SHUTTER_STOPCLOSE "StopClose" #define D_CMND_SHUTTER_STOPTOGGLE "StopToggle" +#define D_CMND_SHUTTER_STOPTOGGLEDIR "StopToggleDir" #define D_CMND_SHUTTER_STOPPOSITION "StopPosition" #define D_CMND_SHUTTER_STOP "Stop" #define D_CMND_SHUTTER_POSITION "Position" diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index 660c5e2c3..15d5143f1 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -37,18 +37,18 @@ enum ShutterModes { SHT_OFF_OPEN__OFF_CLOSE, SHT_OFF_ON__OPEN_CLOSE, SHT_PULSE_O enum ShutterButtonStates { SHT_NOT_PRESSED, SHT_PRESSED_MULTI, SHT_PRESSED_HOLD, SHT_PRESSED_IMMEDIATE, SHT_PRESSED_EXT_HOLD, SHT_PRESSED_MULTI_SIMULTANEOUS, SHT_PRESSED_HOLD_SIMULTANEOUS, SHT_PRESSED_EXT_HOLD_SIMULTANEOUS,}; const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|" - D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_TOGGLE "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|" + D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_TOGGLE "|" D_CMND_SHUTTER_TOGGLEDIR "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|" D_CMND_SHUTTER_OPENTIME "|" D_CMND_SHUTTER_CLOSETIME "|" D_CMND_SHUTTER_RELAY "|" D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_SETOPEN "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|" D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK "|" D_CMND_SHUTTER_ENABLEENDSTOPTIME "|" D_CMND_SHUTTER_INVERTWEBBUTTONS "|" - D_CMND_SHUTTER_STOPOPEN "|" D_CMND_SHUTTER_STOPCLOSE "|" D_CMND_SHUTTER_STOPTOGGLE "|" D_CMND_SHUTTER_STOPPOSITION; + D_CMND_SHUTTER_STOPOPEN "|" D_CMND_SHUTTER_STOPCLOSE "|" D_CMND_SHUTTER_STOPTOGGLE "|" D_CMND_SHUTTER_STOPTOGGLEDIR "|" D_CMND_SHUTTER_STOPPOSITION; void (* const ShutterCommand[])(void) PROGMEM = { - &CmndShutterOpen, &CmndShutterClose, &CmndShutterToggle, &CmndShutterStop, &CmndShutterPosition, + &CmndShutterOpen, &CmndShutterClose, &CmndShutterToggle, &CmndShutterToggleDir, &CmndShutterStop, &CmndShutterPosition, &CmndShutterOpenTime, &CmndShutterCloseTime, &CmndShutterRelay, &CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterSetOpen, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay, &CmndShutterFrequency, &CmndShutterButton, &CmndShutterLock, &CmndShutterEnableEndStopTime, &CmndShutterInvertWebButtons, - &CmndShutterStopOpen, &CmndShutterStopClose, &CmndShutterStopToggle, &CmndShutterStopPosition}; + &CmndShutterStopOpen, &CmndShutterStopClose, &CmndShutterStopToggle, &CmndShutterStopToggleDir, &CmndShutterStopPosition}; const char JSON_SHUTTER_POS[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Position\":%d,\"Direction\":%d,\"Target\":%d}"; const char JSON_SHUTTER_BUTTON[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Button%d\":%d}"; @@ -70,6 +70,7 @@ struct SHUTTER { uint16_t close_time[MAX_SHUTTERS]; // duration to close the shutter. 112 = 11.2sec uint16_t close_velocity[MAX_SHUTTERS]; // in relation to open velocity. higher value = faster int8_t direction[MAX_SHUTTERS]; // 1 == UP , 0 == stop; -1 == down + int8_t lastdirection[MAX_SHUTTERS]; // last direction (1 == UP , -1 == down) uint8_t mode = 0; // operation mode definition. see enum type above SHT_OFF_OPEN__OFF_CLOSE, SHT_OFF_ON__OPEN_CLOSE, SHT_PULSE_OPEN__PULSE_CLOSE int16_t motordelay[MAX_SHUTTERS]; // initial motorstarttime in 0.05sec. int16_t pwm_frequency[MAX_SHUTTERS]; // frequency of PWN for stepper motors @@ -401,6 +402,9 @@ void ShutterUpdatePosition(void) Response_P("%d", (Settings.shutter_options[i] & 1) ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i]); MqttPublish(stopic, Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN + if (Shutter.direction[i] != 0) { + Shutter.lastdirection[i] = Shutter.direction[i]; + } Shutter.direction[i] = 0; ShutterReportPosition(true, i); rules_flag.shutter_moved = 1; @@ -726,6 +730,26 @@ void ShutterSetPosition(uint32_t device, uint32_t position) ExecuteCommand(svalue, SRC_IGNORE); } +void ShutterToggle(bool dir) +{ + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Payload toggle: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); + if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) { + XdrvMailbox.index = XdrvMailbox.payload; + } + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { + uint32_t index = XdrvMailbox.index-1; + if (dir) { + XdrvMailbox.payload = (Shutter.lastdirection[index] > 0) ? 0 : 100; + } + else { + XdrvMailbox.payload = (50 < ShutterRealToPercentPosition(Shutter.real_position[index], index)) ? 0 : 100; + } + XdrvMailbox.data_len = 0; + last_source = SRC_WEBGUI; + CmndShutterPosition(); + } +} + /*********************************************************************************************\ * Commands \*********************************************************************************************/ @@ -779,17 +803,12 @@ void CmndShutterStopClose(void) void CmndShutterToggle(void) { - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Payload toggle: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); - if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) { - XdrvMailbox.index = XdrvMailbox.payload; - } - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { - uint32_t index = XdrvMailbox.index-1; - XdrvMailbox.payload = (50 < ShutterRealToPercentPosition(Shutter.real_position[index], index)) ? 0 : 100; - XdrvMailbox.data_len = 0; - last_source = SRC_WEBGUI; - CmndShutterPosition(); - } + ShutterToggle(false); +} + +void CmndShutterToggleDir(void) +{ + ShutterToggle(true); } void CmndShutterStopToggle(void) @@ -804,6 +823,18 @@ void CmndShutterStopToggle(void) } } +void CmndShutterStopToggleDir(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { + uint32_t index = XdrvMailbox.index-1; + if (Shutter.direction[index]) { + CmndShutterStop(); + } else { + CmndShutterToggleDir(); + } + } +} + void CmndShutterStop(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { @@ -856,6 +887,10 @@ void CmndShutterPosition(void) CmndShutterToggle(); return; } + if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEDIR)) { + CmndShutterToggleDir(); + return; + } if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOP) || ((Shutter.direction[index]) && (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPOPEN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPCLOSE)))) { XdrvMailbox.payload = -99; CmndShutterStop(); From 4584effbce672702e0cda3357bbea2de66e8bbee Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 21 Jul 2020 10:44:45 +0200 Subject: [PATCH 532/581] Change all timer references from ``Arm`` to ``Enable`` Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message --- RELEASENOTES.md | 4 +++- tasmota/CHANGELOG.md | 4 +++- tasmota/i18n.h | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 5e5e3e549..59b1a263c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -63,6 +63,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change ESP32 USER GPIO template representation decreasing template message size - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT - Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` +- Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message - Fix escape of non-JSON received serial data (#8329) - Fix exception or watchdog on rule re-entry (#8757) - Add command ``Rule0`` to change global rule parameters @@ -71,7 +72,8 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``SetOption97 0/1`` to switch between Tuya serial speeds 9600 bps (0) or 115200 bps (1) - Add command ``SetOption98 0/1`` to provide rotary rule triggers (1) instead of controlling light (0) - Add command ``SetOption99 0/1`` to enable zero cross detection on PWM dimmer -- Add command ``SetOption100 0/1`` to remove ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message +- Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message +- Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 - Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 7dbad0a37..901dfb7e8 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -4,7 +4,9 @@ - Remove Arduino ESP8266 Core support for versions before 2.7.1 - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE -- Add command ``SetOption100 0/1`` to remove ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message +- Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message +- Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message +- Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 ### 8.3.1.6 20200617 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index fb5cbceb3..a91ede963 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -481,7 +481,7 @@ // Commands xdrv_09_timers.ino #define D_CMND_TIMER "Timer" - #define D_JSON_TIMER_ARM "Arm" + #define D_JSON_TIMER_ARM "Enable" #define D_JSON_TIMER_MODE "Mode" #define D_JSON_TIMER_TIME "Time" #define D_JSON_TIMER_WINDOW "Window" From eb4164e713d86711b268dc9570759ade553389d1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 21 Jul 2020 11:03:03 +0200 Subject: [PATCH 533/581] Update RELEASENOTES.md --- RELEASENOTES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 59b1a263c..3127bf4db 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -21,9 +21,9 @@ While fallback or downgrading is common practice it was never supported due to S ## Supported Core versions -This release will be supported from ESP8266/Arduino library Core version **2.7.2** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. +This release will be supported from ESP8266/Arduino library Core version **2.7.2.1** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. -Although it might still compile on previous Core versions all support will be removed in the near future. +Support of Core versions before 2.7.1 has been removed. ## Support of TLS @@ -35,7 +35,7 @@ For initial configuration this release supports Webserver based **WifiManager** ## Provided Binary Downloads -The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.2**. +The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.2.1**. - **tasmota.bin** = The Tasmota version with most drivers. **RECOMMENDED RELEASE BINARY** - **tasmota-BG.bin** to **tasmota-TW.bin** = The Tasmota version in different languages. From 48c268a9200795a56c0bace19ec3e5104dedac67 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 21 Jul 2020 12:17:29 +0200 Subject: [PATCH 534/581] Update decode-status.py --- tools/decode-status.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/decode-status.py b/tools/decode-status.py index 22329c5f6..7539aa37a 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -152,7 +152,9 @@ a_setoption = [[ "Enable Ethernet (ESP32)", "Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200)", "Rotary encoder uses rules instead of light control", - "","","", + "Enable zerocross dimmer on PWM DIMMER", + "Remove ZbReceived form JSON message", + "Add the source endpoint as suffix to attributes", "","","","", "","","","", "","","","" @@ -239,7 +241,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200714 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200721 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) From 72e3765a552d590088cf3c54940a39b8a9a143ec Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 21 Jul 2020 12:42:18 +0200 Subject: [PATCH 535/581] Add command (``S``)``SerialSend6`` \ Add command (``S``)``SerialSend6`` \ (#8937) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/xdrv_08_serial_bridge.ino | 11 ++++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3127bf4db..490280e79 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -75,6 +75,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 - Add command ``Module2`` to configure fallback module on fast reboot (#8464) +- Add command (``S``)``SerialSend6`` \ (#8937) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` - Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 901dfb7e8..45967d240 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -7,6 +7,7 @@ - Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message - Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 +- Add command (``S``)``SerialSend6`` \ (#8937) ### 8.3.1.6 20200617 diff --git a/tasmota/xdrv_08_serial_bridge.ino b/tasmota/xdrv_08_serial_bridge.ino index b5a9143b7..210094048 100644 --- a/tasmota/xdrv_08_serial_bridge.ino +++ b/tasmota/xdrv_08_serial_bridge.ino @@ -124,7 +124,7 @@ void SerialBridgeInit(void) void CmndSSerialSend(void) { - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 5)) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) { serial_bridge_raw = (XdrvMailbox.index > 3); if (XdrvMailbox.data_len > 0) { if (1 == XdrvMailbox.index) { @@ -153,6 +153,15 @@ void CmndSSerialSend(void) codes += 2; } } + else if (6 == XdrvMailbox.index) { + char *p; + uint8_t code; + char *values = XdrvMailbox.data; + for (char* str = strtok_r(values, ",", &p); str; str = strtok_r(nullptr, ",", &p)) { + code = (uint8_t)atoi(str); + SerialBridgeSerial->write(code); // "72,101,108,108" + } + } ResponseCmndDone(); } } From bdcc630886de8ad4c8c7e1db1acd68f5064beec2 Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Tue, 21 Jul 2020 18:46:52 +0200 Subject: [PATCH 536/581] Update Italian language --- tasmota/language/it_IT.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 3d26d9f09..dcc53fd68 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -403,23 +403,23 @@ #define D_DOMOTICZ_KEY_IDX "Idx - chiave" #define D_DOMOTICZ_SWITCH_IDX "Idx - switch" #define D_DOMOTICZ_SENSOR_IDX "Idx - sensore" - #define D_DOMOTICZ_TEMP "Temp" - #define D_DOMOTICZ_TEMP_HUM "Temp,Umd" - #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Umd,Baro" - #define D_DOMOTICZ_POWER_ENERGY "Alim,Energia" - #define D_DOMOTICZ_ILLUMINANCE "Illuminazione" - #define D_DOMOTICZ_COUNT "Cont/PM1" - #define D_DOMOTICZ_VOLTAGE "Tensione/PM2.5" - #define D_DOMOTICZ_CURRENT "Corrente/PM10" - #define D_DOMOTICZ_AIRQUALITY "Qualità aria" - #define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter" +#define D_DOMOTICZ_TEMP "Temp" +#define D_DOMOTICZ_TEMP_HUM "Temp,Umd" +#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Umd,Baro" +#define D_DOMOTICZ_POWER_ENERGY "Alim,Energia" +#define D_DOMOTICZ_ILLUMINANCE "Illuminazione" +#define D_DOMOTICZ_COUNT "Cont/PM1" +#define D_DOMOTICZ_VOLTAGE "Tensione/PM2.5" +#define D_DOMOTICZ_CURRENT "Corrente/PM10" +#define D_DOMOTICZ_AIRQUALITY "Qualità aria" +#define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter" #define D_DOMOTICZ_UPDATE_TIMER "Intervallo aggiornamento" // xdrv_09_timers.ino #define D_CONFIGURE_TIMER "Timer" #define D_TIMER_PARAMETERS "Parametri timer" #define D_TIMER_ENABLE "Abilita timer" -#define D_TIMER_ARM "Attiva" +#define D_TIMER_ARM "Abilita" #define D_TIMER_TIME "Ora" #define D_TIMER_DAYS "Giorni" #define D_TIMER_REPEAT "Ripeti" From 93b36d5c469c2fb0a0d8269d21c0a1b614b3d5f7 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 21 Jul 2020 19:16:38 +0200 Subject: [PATCH 537/581] Change ``Ping`` now reports the hostname instead of IP address (#8948) --- tasmota/CHANGELOG.md | 1 + tasmota/xdrv_38_ping.ino | 45 +++++++++++++++++++++++++++------------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 45967d240..31231a6ad 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -8,6 +8,7 @@ - Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 - Add command (``S``)``SerialSend6`` \ (#8937) +- Change ``Ping`` now reports the hostname instead of IP address (#8948) ### 8.3.1.6 20200617 diff --git a/tasmota/xdrv_38_ping.ino b/tasmota/xdrv_38_ping.ino index 4724ee310..af6b634d5 100644 --- a/tasmota/xdrv_38_ping.ino +++ b/tasmota/xdrv_38_ping.ino @@ -58,6 +58,7 @@ extern "C" { uint32_t sum_time; // cumulated time in ms for all successful responses (used to compute the average) bool done; // indicates the ping campaign is finished bool fast; // fast mode, i.e. stop pings when first successful response + String hostname; // original hostname before convertion to IP address } Ping_t; // globals @@ -229,10 +230,22 @@ extern "C" { // ================================================================================ // Start pings // ================================================================================ - bool t_ping_start(uint32_t ip, uint32_t count) { + // returns: + // 0: OK + // -1: ping already ongoing for this address + // -2: unable to resolve address + int32_t t_ping_start(const char *hostname, uint32_t count) { + IPAddress ipfull; + if (!WiFi.hostByName(hostname, ipfull)) { + return -2; + } + + uint32_t ip = ipfull; + if (0xFFFFFFFF == ip) { return -2; } // invalid address + // check if pings are already ongoing for this IP if (t_ping_find(ip)) { - return false; + return -1; } Ping_t *ping = new Ping_t(); @@ -243,6 +256,7 @@ extern "C" { ping->min_time = UINT32_MAX; ping->ip = ip; ping->to_send_count = count - 1; + ping->hostname = hostname; // add to Linked List from head ping->next = ping_head; @@ -254,6 +268,8 @@ extern "C" { // set timers for time-out and cadence sys_timeout(Ping_timeout_ms, t_ping_timeout, ping); sys_timeout(Ping_coarse, t_ping_coarse_tmr, ping); + + return 0; } } @@ -268,18 +284,22 @@ void PingResponsePoll(void) { uint32_t success = ping->success_count; uint32_t ip = ping->ip; - Response_P(PSTR("{\"" D_JSON_PING "\":{\"%d.%d.%d.%d\":{" + Response_P(PSTR("{\"" D_JSON_PING "\":{\"%s\":{" "\"Reachable\":%s" + ",\"IP\":\"%d.%d.%d.%d\"" ",\"Success\":%d" ",\"Timeout\":%d" ",\"MinTime\":%d" ",\"MaxTime\":%d" ",\"AvgTime\":%d" "}}}"), - ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24, + ping->hostname.c_str(), success ? "true" : "false", - success, ping->timeout_count, - success ? ping->min_time : 0, ping->max_time, + ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24, + success, + ping->timeout_count, + success ? ping->min_time : 0, + ping->max_time, success ? ping->sum_time / success : 0 ); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_PING)); @@ -303,18 +323,15 @@ void PingResponsePoll(void) { void CmndPing(void) { uint32_t count = XdrvMailbox.index; - IPAddress ip; RemoveSpace(XdrvMailbox.data); if (count > 10) { count = 8; } // max 8 seconds - if (WiFi.hostByName(XdrvMailbox.data, ip)) { - bool ok = t_ping_start(ip, count); - if (ok) { - ResponseCmndDone(); - } else { - ResponseCmndChar_P(PSTR("Ping already ongoing for this IP")); - } + int32_t res = t_ping_start(XdrvMailbox.data, count); + if (0 == res) { + ResponseCmndDone(); + } else if (-1 == res) { + ResponseCmndChar_P(PSTR("Ping already ongoing for this IP")); } else { ResponseCmndChar_P(PSTR("Unable to resolve IP address")); } From 6d34813f45ac75be07a76dbc5eec6066ae82085d Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 21 Jul 2020 22:39:39 +0200 Subject: [PATCH 538/581] Zigbee CC2530 more robust reset --- tasmota/xdrv_23_zigbee_7_statemachine.ino | 16 ++++------------ tasmota/xdrv_23_zigbee_8_parsers.ino | 22 +++++++++++++++++++++- tasmota/xdrv_23_zigbee_9_serial.ino | 10 ++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index 50e67f91c..87bae5911 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -114,8 +114,6 @@ const uint8_t ZIGBEE_LABEL_START_ROUTER = 13; // Start ZNP as router const uint8_t ZIGBEE_LABEL_INIT_DEVICE = 14; // Init ZNP as end-device const uint8_t ZIGBEE_LABEL_START_DEVICE = 15; // Start ZNP as end-device const uint8_t ZIGBEE_LABEL_START_ROUTER_DEVICE = 16; // Start common to router and device -const uint8_t ZIGBEE_LABEL_BOOT_OK = 17; // MCU has rebooted -const uint8_t ZIGBEE_LABEL_BOOT_TIME_OUT = 18; // MCU has not rebooted const uint8_t ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST = 19; // common post configuration for router and device const uint8_t ZIGBEE_LABEL_READY = 20; // goto label 20 for main loop const uint8_t ZIGBEE_LABEL_MAIN_LOOP = 21; // main loop @@ -430,18 +428,12 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize //ZI_MQTT_STATE(ZIGBEE_STATUS_BOOT, "Booting") - //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting device") - ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_BOOT_TIME_OUT) // give a second chance - ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 - ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &ZNP_Reboot) // timeout 5s - ZI_GOTO(ZIGBEE_LABEL_BOOT_OK) + ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting device") - ZI_LABEL(ZIGBEE_LABEL_BOOT_TIME_OUT) - ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) - ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 + ZI_CALL(&ZNP_Reset_Device, 0) // LOW = reset + ZI_WAIT(100) // wait for .1 second + ZI_CALL(&ZNP_Reset_Device, 1) // HIGH = release reset ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &ZNP_Reboot) // timeout 5s - - ZI_LABEL(ZIGBEE_LABEL_BOOT_OK) ZI_WAIT(100) ZI_LOG(LOG_LEVEL_DEBUG, kCheckingDeviceConfiguration) // Log Debug: checking device configuration ZI_SEND(ZBS_VERSION) // check ZNP software version diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index c08ff4d28..2382a97a3 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -1065,7 +1065,7 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { } // -// Callback for loading Zigbee configuration from Flash, called by the state machine +// Callback for resetting the NCP, called by the state machine // // value = 0 : drive reset pin and halt MCU // value = 1 : release the reset pin, restart @@ -1147,6 +1147,26 @@ int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu #ifdef USE_ZIGBEE_ZNP +// +// Callback for resetting the NCP, called by the state machine +// +// value = 0 : drive reset pin and halt MCU +// value = 1 : release the reset pin, restart +int32_t ZNP_Reset_Device(uint8_t value) { + // we use Led4i to drive the reset pin. Since it is reverted we need to pass 1 to start reset, and 0 to release reset + if (PinUsed(GPIO_LED1, ZIGBEE_EZSP_RESET_LED - 1)) { + SetLedPowerIdx(ZIGBEE_EZSP_RESET_LED - 1, value ? 0 : 1); + } else { + // no GPIO so we use software Reset instead + if (value) { // send reset only when we are supposed to release reset + // flush the serial buffer, sending 0xFF 256 times. + ZigbeeZNPFlush(); + ZigbeeZNPSend(ZBS_RESET, sizeof(ZBS_RESET)); + } + } + return 0; // continue +} + int32_t ZNP_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { uint16_t groupid = buf.get16(2); uint16_t clusterid = buf.get16(4); diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index cd5ef3c4f..c4f214bcd 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -302,6 +302,16 @@ void ZigbeeInitSerial(void) #ifdef USE_ZIGBEE_ZNP +// flush any ongoing frame, sending 256 times 0xFF +void ZigbeeZNPFlush(void) { + if (ZigbeeSerial) { + for (uint32_t i = 0; i < 256; i++) { + ZigbeeSerial->write(0xFF); + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " 0xFF x 255")); + } +} + void ZigbeeZNPSend(const uint8_t *msg, size_t len) { if ((len < 2) || (len > 252)) { // abort, message cannot be less than 2 bytes for CMD1 and CMD2 From a1fc5d48909aa7f1799c3348fec647609c6ace09 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 22 Jul 2020 09:34:35 +0200 Subject: [PATCH 539/581] Fix telegram restart loop Fix telegram restart loop (#8619) --- tasmota/xdrv_40_telegram.ino | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino index a7beb5005..f99a121b7 100644 --- a/tasmota/xdrv_40_telegram.ino +++ b/tasmota/xdrv_40_telegram.ino @@ -57,7 +57,7 @@ BearSSL::WiFiClientSecure_light *telegramClient = nullptr; static const uint8_t Telegram_Fingerprint[] PROGMEM = USE_TELEGRAM_FINGERPRINT; struct { - String message[3][6]; // amount of messages read per time (update_id, name_id, name, lastname, chat_id, text) + String message[3][6]; // Amount of messages read per time (update_id, name_id, name, lastname, chat_id, text) uint8_t state = 0; uint8_t index = 0; uint8_t retry = 0; @@ -67,6 +67,7 @@ struct { bool recv_enable = false; bool echo_enable = false; bool recv_busy = false; + bool skip = true; // Skip first telegram if restarted } Telegram; bool TelegramInit(void) { @@ -172,7 +173,7 @@ void TelegramGetUpdates(String offset) { // } // ]} -// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); // parsing of reply from Telegram into separate received messages int i = 0; //messages received counter @@ -349,10 +350,14 @@ void TelegramLoop(void) { Telegram.state++; } } else { - if (Telegram.message[0][0].toInt() && (Telegram.message[Telegram.index][5].length() > 0)) { - String logging = TelegramExecuteCommand(Telegram.message[Telegram.index][5].c_str()); - if (logging.length() > 0) { - TelegramSendMessage(Telegram.message[Telegram.index][4], logging); + if (Telegram.skip) { // Skip first update as it may be a restart (again) + Telegram.skip = false; + } else { + if (Telegram.message[0][0].toInt() && (Telegram.message[Telegram.index][5].length() > 0)) { + String logging = TelegramExecuteCommand(Telegram.message[Telegram.index][5].c_str()); + if (logging.length() > 0) { + TelegramSendMessage(Telegram.message[Telegram.index][4], logging); + } } } Telegram.message[0][0] = ""; // All messages have been replied - reset new messages From 0fc41f302e38e68078e78f8ae6f5c603b6d01fc3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 22 Jul 2020 09:36:18 +0200 Subject: [PATCH 540/581] Update xdrv_40_telegram.ino --- tasmota/xdrv_40_telegram.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino index f99a121b7..92fca7c90 100644 --- a/tasmota/xdrv_40_telegram.ino +++ b/tasmota/xdrv_40_telegram.ino @@ -350,7 +350,7 @@ void TelegramLoop(void) { Telegram.state++; } } else { - if (Telegram.skip) { // Skip first update as it may be a restart (again) + if (Telegram.skip) { // Skip first update after restart as it may be a restart (again) Telegram.skip = false; } else { if (Telegram.message[0][0].toInt() && (Telegram.message[Telegram.index][5].length() > 0)) { From d8c4240656c1406c004d8b5223cf9602815a8417 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 22 Jul 2020 10:07:07 +0200 Subject: [PATCH 541/581] Prep Zigbee reset GPIO --- tasmota/language/bg_BG.h | 1 + tasmota/language/cs_CZ.h | 1 + tasmota/language/de_DE.h | 1 + tasmota/language/el_GR.h | 1 + tasmota/language/en_GB.h | 1 + tasmota/language/es_ES.h | 1 + tasmota/language/fr_FR.h | 1 + tasmota/language/he_HE.h | 1 + tasmota/language/hu_HU.h | 1 + tasmota/language/it_IT.h | 1 + tasmota/language/ko_KO.h | 1 + tasmota/language/nl_NL.h | 1 + tasmota/language/pl_PL.h | 1 + tasmota/language/pt_BR.h | 1 + tasmota/language/pt_PT.h | 1 + tasmota/language/ro_RO.h | 1 + tasmota/language/ru_RU.h | 1 + tasmota/language/sk_SK.h | 1 + tasmota/language/sv_SE.h | 1 + tasmota/language/tr_TR.h | 1 + tasmota/language/uk_UA.h | 1 + tasmota/language/zh_CN.h | 1 + tasmota/language/zh_TW.h | 1 + tasmota/tasmota_template.h | 5 ++++- tasmota/tasmota_template_ESP32.h | 5 ++++- tasmota/xdrv_23_zigbee_9_serial.ino | 6 ++++++ 26 files changed, 37 insertions(+), 2 deletions(-) diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index ca4afb0bc..f0ff9b818 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "Ðулиране OLED" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index b07d032e7..f85fc4439 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 3517251be..05d72f4db 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 8eaff86f0..ea2db9c98 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 1ae054f0e..9a79758d8 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 04116ea2a..02f41e118 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 8aea1b4cc..05bbf565e 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee TX" #define D_SENSOR_ZIGBEE_RXD "Zigbee RX" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 TX" #define D_SENSOR_SOLAXX1_RX "SolaxX1 RX" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index f7a721739..2db6b36ab 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index f521c06fd..917d2a155 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index dcc53fd68..4f74a9477 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "Ripristino OLED" #define D_SENSOR_ZIGBEE_TXD "Zigbee - TX" #define D_SENSOR_ZIGBEE_RXD "Zigbee - RX" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 - TX" #define D_SENSOR_SOLAXX1_RX "SolaxX1- RX" #define D_SENSOR_IBEACON_TX "iBeacon - TX" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index d635d1d65..61c9ba720 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index b024dc538..139bf4837 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 0ecea1a77..c31dc569a 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index be5d98464..dcb308ae9 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index c489327a7..a34d0e1d1 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 23f160f19..fa01b1705 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index b033ebcd1..3079c00ac 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 9e5cc35e0..09402307c 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index ac416e9b5..c6b3ef835 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index f402cf803..010228272 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 97cd77f91..1f8bb46b1 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 10f609c64..7b925abc6 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 4c52eef18..6031e82a8 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -647,6 +647,7 @@ #define D_SENSOR_OLED_RESET "OLED Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" #define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" #define D_SENSOR_IBEACON_TX "iBeacon TX" diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 25adf6b62..2247372d1 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -241,6 +241,7 @@ enum UserSelectablePins { GPIO_LMT01, // LMT01 input counting pin GPIO_IEM3000_TX, // IEM3000 Serial interface GPIO_IEM3000_RX, // IEM3000 Serial interface + GPIO_ZIGBEE_RST, // Zigbee reset GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -335,7 +336,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" D_SENSOR_LMT01_PULSE "|" - D_SENSOR_IEM3000_TX "|" D_SENSOR_IEM3000_RX + D_SENSOR_IEM3000_TX "|" D_SENSOR_IEM3000_RX "|" + D_SENSOR_ZIGBEE_RST ; const char kSensorNamesFixed[] PROGMEM = @@ -605,6 +607,7 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_ZIGBEE GPIO_ZIGBEE_TX, // Zigbee Serial interface GPIO_ZIGBEE_RX, // Zigbee Serial interface + GPIO_ZIGBEE_RST, // Zigbee reset #endif #ifdef USE_MHZ19 GPIO_MHZ_TXD, // MH-Z19 Serial interface diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index bb1574a77..ddd13d87b 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -138,6 +138,7 @@ enum UserSelectablePins { GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin GPIO_LMT01, // LMT01 input counting pin GPIO_IEM3000_TX, GPIO_IEM3000_RX, // IEM3000 Serial interface + GPIO_ZIGBEE_RST, // Zigbee reset GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -235,7 +236,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|" D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" D_SENSOR_LMT01_PULSE "|" - D_SENSOR_IEM3000_TX "|" D_SENSOR_IEM3000_RX + D_SENSOR_IEM3000_TX "|" D_SENSOR_IEM3000_RX "|" + D_SENSOR_ZIGBEE_RST ; const char kSensorNamesFixed[] PROGMEM = @@ -451,6 +453,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_ZIGBEE AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface + AGPIO(GPIO_ZIGBEE_RST), // Zigbee reset #endif #ifdef USE_MHZ19 AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index c4f214bcd..34555441f 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -292,6 +292,12 @@ void ZigbeeInitSerial(void) zigbee_buffer = new SBuffer(ZIGBEE_BUFFER_SIZE); // AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem3 = %d"), ESP_getFreeHeap()); } + + if (PinUsed(GPIO_ZIGBEE_RST)) { + pinMode(Pin(GPIO_ZIGBEE_RST), OUTPUT); + digitalWrite(Pin(GPIO_ZIGBEE_RST), 1); + } + zigbee.active = true; zigbee.init_phase = true; // start the state machine zigbee.state_machine = true; // start the state machine From 6f320780a043e0d0ac96d8d0d19852f1fc69a3ab Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 22 Jul 2020 10:12:24 +0200 Subject: [PATCH 542/581] Change zigbee reset using new GPIO --- tasmota/xdrv_23_zigbee_8_parsers.ino | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 2382a97a3..738a67c8b 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -1070,9 +1070,13 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { // value = 0 : drive reset pin and halt MCU // value = 1 : release the reset pin, restart int32_t EZ_Reset_Device(uint8_t value) { +/* // we use Led4i to drive the reset pin. Since it is reverted we need to pass 1 to start reset, and 0 to release reset if (PinUsed(GPIO_LED1, ZIGBEE_EZSP_RESET_LED - 1)) { SetLedPowerIdx(ZIGBEE_EZSP_RESET_LED - 1, value ? 0 : 1); +*/ + if (PinUsed(GPIO_ZIGBEE_RST)) { + digitalWrite(Pin(GPIO_ZIGBEE_RST), value); } else { // no GPIO so we use software Reset instead if (value) { // send reset only when we are supposed to release reset @@ -1153,9 +1157,13 @@ int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu // value = 0 : drive reset pin and halt MCU // value = 1 : release the reset pin, restart int32_t ZNP_Reset_Device(uint8_t value) { +/* // we use Led4i to drive the reset pin. Since it is reverted we need to pass 1 to start reset, and 0 to release reset if (PinUsed(GPIO_LED1, ZIGBEE_EZSP_RESET_LED - 1)) { SetLedPowerIdx(ZIGBEE_EZSP_RESET_LED - 1, value ? 0 : 1); +*/ + if (PinUsed(GPIO_ZIGBEE_RST)) { + digitalWrite(Pin(GPIO_ZIGBEE_RST), value); } else { // no GPIO so we use software Reset instead if (value) { // send reset only when we are supposed to release reset From eec6869a0a276d5057d78734a4894d345a37ad0d Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 22 Jul 2020 19:29:16 +0200 Subject: [PATCH 543/581] EZSP flow control --- tasmota/xdrv_23_zigbee_7_statemachine.ino | 2 +- tasmota/xdrv_23_zigbee_8_parsers.ino | 2 +- tasmota/xdrv_23_zigbee_9_serial.ino | 117 +++++++++++++++++----- tasmota/xdrv_23_zigbee_A_impl.ino | 11 +- 4 files changed, 100 insertions(+), 32 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index 87bae5911..f04c0ca34 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -1097,7 +1097,7 @@ void ZigbeeStateMachine_Run(void) { ZigbeeZNPSend((uint8_t*) cur_ptr1, cur_d8 /* len */); #endif // USE_ZIGBEE_ZNP #ifdef USE_ZIGBEE_EZSP - ZigbeeEZSPSendCmd((uint8_t*) cur_ptr1, cur_d8 /* len */, true); // send cancel byte + ZigbeeEZSPSendCmd((uint8_t*) cur_ptr1, cur_d8 /* len */); // send cancel byte #endif // USE_ZIGBEE_EZSP break; case ZGB_INSTR_WAIT_UNTIL: diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 738a67c8b..58d4e330b 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -1005,7 +1005,7 @@ void EZ_SendZDO(uint16_t shortaddr, uint16_t cmd, const unsigned char *payload, buf.addBuffer(payload, payload_len); } - ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true); + ZigbeeEZSPSendCmd(buf.buf(), buf.len()); } /*********************************************************************************************\ diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index 34555441f..bfec8c3bb 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -36,11 +36,15 @@ const uint32_t ZIGBEE_LED_SEND = 0; // LED<2> blinks when receiving class EZSP_Serial_t { public: - uint8_t to_ack = 0; // 0..7, frame number of next id to send + uint8_t to_send = 0; // 0..7, frame number of next packet to send, nothing to send if equal to to_end + uint8_t to_end = 0; // 0..7, frame number of next packet to send + uint8_t to_ack = 0; // 0..7, frame number of last packet acknowledged + 1 uint8_t from_ack = 0; // 0..7, frame to ack uint8_t ezsp_seq = 0; // 0..255, EZSP sequence number + SBuffer *to_packets[8] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; }; + EZSP_Serial_t EZSP_Serial; #endif // USE_ZIGBEE_EZSP @@ -493,7 +497,7 @@ void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { // Send an EZSP command and data // Ex: Version with min v8 = 000008 -void ZigbeeEZSPSendCmd(const uint8_t *msg, size_t len, bool send_cancel) { +void ZigbeeEZSPSendCmd(const uint8_t *msg, size_t len) { char hex_char[len*2 + 2]; ToHex_P(msg, len, hex_char, sizeof(hex_char)); AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZbEZSPSend %s"), hex_char); @@ -506,20 +510,45 @@ void ZigbeeEZSPSendCmd(const uint8_t *msg, size_t len, bool send_cancel) { cmd.addBuffer(msg, len); // send - ZigbeeEZSPSendDATA(cmd.getBuffer(), cmd.len(), send_cancel); + ZigbeeEZSPSendDATA(cmd.getBuffer(), cmd.len()); } // Send an EZSP DATA frame, automatically calculating the correct frame numbers -void ZigbeeEZSPSendDATA(const uint8_t *msg, size_t len, bool send_cancel) { - uint8_t control_byte = ((EZSP_Serial.to_ack & 0x07) << 4) + (EZSP_Serial.from_ack & 0x07); - // increment to_ack - EZSP_Serial.to_ack = (EZSP_Serial.to_ack + 1) & 0x07; - // build complete frame - SBuffer buf(len+1); - buf.add8(control_byte); - buf.addBuffer(msg, len); +void ZigbeeEZSPSendDATA_frm(bool send_cancel, uint8_t to_frm, uint8_t from_ack) { + SBuffer *buf = EZSP_Serial.to_packets[to_frm]; + if (!buf) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Buffer for packet %d is not allocated"), EZSP_Serial.to_send); + return; + } + + uint8_t control_byte = ((to_frm & 0x07) << 4) + (from_ack & 0x07); + buf->set8(0, control_byte); // change control_byte // send - ZigbeeEZSPSendRaw(buf.getBuffer(), buf.len(), send_cancel); + ZigbeeEZSPSendRaw(buf->getBuffer(), buf->len(), send_cancel); +} + +// Send an EZSP DATA frame, automatically calculating the correct frame numbers +void ZigbeeEZSPSendDATA(const uint8_t *msg, size_t len) { + // prepare buffer by adding 1 byte prefix + SBuffer *buf = new SBuffer(len+1); // prepare for control_byte prefix + buf->add8(0x00); // placeholder for control_byte + buf->addBuffer(msg, len); + // + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: adding packet to_send, to_ack:%d, to_send:%d, to_end:%d"), + EZSP_Serial.to_ack, EZSP_Serial.to_send, EZSP_Serial.to_end); + uint8_t to_frm = EZSP_Serial.to_end; + if (EZSP_Serial.to_packets[to_frm]) { + delete EZSP_Serial.to_packets[to_frm]; + EZSP_Serial.to_packets[to_frm] = nullptr; + } + EZSP_Serial.to_packets[to_frm] = buf; + EZSP_Serial.to_end = (to_frm + 1) & 0x07; // move cursor + + // ZigbeeEZSPSendDATA_frm(send_cancel, to_frm, EZSP_Serial.from_ack); + + // increment to_frame + //EZSP_Serial.to_ack = (EZSP_Serial.to_ack + 1) & 0x07; + //EZSP_Serial.to_frm = (EZSP_Serial.to_frm + 1) & 0x07; } // Receive a high-level EZSP command/response, starting with 16-bits frame ID @@ -557,23 +586,41 @@ int32_t ZigbeeProcessInputEZSP(class SBuffer &buf) { ZigbeeProcessInput(buf); } +// Check if we advanced in the ACKed frames, and free from memory packets acknowledged +void EZSP_HandleAck(uint8_t new_ack) { + if (EZSP_Serial.to_ack != new_ack) { // new ack receveid + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: new ack/data received, was %d now %d"), EZSP_Serial.to_ack, new_ack); + uint32_t i = EZSP_Serial.to_ack; + do { + if (EZSP_Serial.to_packets[i]) { + delete EZSP_Serial.to_packets[i]; + EZSP_Serial.to_packets[i] = nullptr; + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: freeing packet %d from memory"), i); + i = (i + 1) & 0x07; + } while (i != new_ack); + EZSP_Serial.to_ack = new_ack; + } +} // Receive raw ASH frame (CRC was removed, data unstuffed) but still contains frame numbers int32_t ZigbeeProcessInputRaw(class SBuffer &buf) { uint8_t control_byte = buf.get8(0); uint8_t ack_num = control_byte & 0x07; // keep 3 LSB - if (control_byte & 0x80) { + if (control_byte & 0x80) { // non DATA frame - // non DATA frame uint8_t frame_type = control_byte & 0xE0; // keep 3 MSB if (frame_type == 0x80) { // ACK - EZSP_Serial.from_ack = ack_num; // update ack num + EZSP_HandleAck(ack_num); } else if (frame_type == 0xA0) { // NAK - AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: Received NAK %d, resending not implemented"), ack_num); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Received NAK %d, to_ack:%d, to_send:%d, to_end:%d"), + ack_num, EZSP_Serial.to_ack, EZSP_Serial.to_send, EZSP_Serial.to_end); + EZSP_Serial.to_send = ack_num; + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: NAK, resending packet %d"), ack_num); } else if (control_byte == 0xC1) { // RSTACK @@ -581,6 +628,8 @@ int32_t ZigbeeProcessInputRaw(class SBuffer &buf) { EZ_RSTACK(buf.get8(2)); EZSP_Serial.from_ack = 0; EZSP_Serial.to_ack = 0; + EZSP_Serial.to_end = 0; + EZSP_Serial.to_send = 0; // pass it to state machine with a special 0xFFFE frame code (EZSP_RSTACK_ID) buf.set8(0, Z_B0(EZSP_rstAck)); @@ -598,14 +647,12 @@ int32_t ZigbeeProcessInputRaw(class SBuffer &buf) { // Unknown AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Received unknown control byte 0x%02X"), control_byte); } - } else { + } else { // DATA Frame + + // adjust to latest acked packet + uint8_t new_ack = control_byte & 0x07; + EZSP_HandleAck(new_ack); - // DATA Frame - // check the frame number, and send ACK or NAK - if ((control_byte & 0x07) != EZSP_Serial.to_ack) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: wrong ack, received %d, expected %d"), control_byte & 0x07, EZSP_Serial.to_ack); - //EZSP_Serial.to_ack = control_byte & 0x07; - } // MCU acknowledged the correct frame // we acknowledge the frame too EZSP_Serial.from_ack = ((control_byte >> 4) + 1) & 0x07; @@ -651,9 +698,9 @@ void CmndZbEZSPSendOrReceive(bool send) } if (send) { // Command was `ZbEZSPSend` - if (2 == XdrvMailbox.index) { ZigbeeEZSPSendDATA(buf.getBuffer(), buf.len(), true); } + if (2 == XdrvMailbox.index) { ZigbeeEZSPSendDATA(buf.getBuffer(), buf.len()); } else if (3 == XdrvMailbox.index) { ZigbeeEZSPSendRaw(buf.getBuffer(), buf.len(), true); } - else { ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); } + else { ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len()); } } else { // Command was `ZbEZSPReceive` @@ -785,7 +832,25 @@ void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterI } } - ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true); + ZigbeeEZSPSendCmd(buf.buf(), buf.len()); +#endif // USE_ZIGBEE_EZSP +} + +// +// Send any buffered data to the NCP +// +// Used only with EZSP, as there is no replay of procotol control with ZNP +void ZigbeeOutputLoop(void) { +#ifdef USE_ZIGBEE_EZSP + // while (EZSP_Serial.to_send != EZSP_Serial.to_end) { + if (EZSP_Serial.to_send != EZSP_Serial.to_end) { // we send only one packet per tick to lower the chance of NAK + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Something to_send, to_ack:%d, to_send:%d, to_end:%d"), + EZSP_Serial.to_ack, EZSP_Serial.to_send, EZSP_Serial.to_end); + // we have a frame waiting to be sent + ZigbeeEZSPSendDATA_frm(true, EZSP_Serial.to_send, EZSP_Serial.from_ack); + // increment sent counter + EZSP_Serial.to_send = (EZSP_Serial.to_send + 1) & 0x07; + } #endif // USE_ZIGBEE_EZSP } diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 5922b3ee3..6b23590cc 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1023,13 +1023,13 @@ void CmndZbPermitJoin(void) { SBuffer buf(3); buf.add16(EZSP_permitJoining); buf.add8(duration); - ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); + ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len()); // send ZDO_Mgmt_Permit_Joining_req to all routers buf.setLen(0); buf.add8(duration); buf.add8(0x01); // TC_Significance - This field shall always have a value of 1, indicating a request to change the Trust Center policy. If a frame is received with a value of 0, it shall be treated as having a value of 1. - // EZ_SendZDO(0xFFFC, ZDO_Mgmt_Permit_Joining_req, buf.buf(), buf.len()); TODO fix NAK/ACK first + EZ_SendZDO(0xFFFC, ZDO_Mgmt_Permit_Joining_req, buf.buf(), buf.len()); #endif // USE_ZIGBEE_EZSP ResponseCmndDone(); @@ -1059,7 +1059,7 @@ void CmndZbEZSPListen(void) { buf.add16(group); // group buf.add8(0x01); // endpoint buf.add8(0x00); // network index - ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); + ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len()); ResponseCmndDone(); } @@ -1240,7 +1240,10 @@ bool Xdrv23(uint8_t function) } break; case FUNC_LOOP: - if (ZigbeeSerial) { ZigbeeInputLoop(); } + if (ZigbeeSerial) { + ZigbeeInputLoop(); + ZigbeeOutputLoop(); // send any outstanding data + } if (zigbee.state_machine) { ZigbeeStateMachine_Run(); } From 1709d5f73ef3ba55e88c38d25720a245574facdb Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 22 Jul 2020 20:51:44 +0200 Subject: [PATCH 544/581] Prep for ZigbeeBridge build --- platformio_tasmota_env.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platformio_tasmota_env.ini b/platformio_tasmota_env.ini index 4a447da82..d0e28b990 100644 --- a/platformio_tasmota_env.ini +++ b/platformio_tasmota_env.ini @@ -38,6 +38,9 @@ build_flags = ${common.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_I [env:tasmota-ircustom] build_flags = ${common.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_IR_CUSTOM +[env:tasmota-zbbridge] +build_flags = ${common.build_flags} -DFIRMWARE_ZBBRIDGE + [env:tasmota-BG] build_flags = ${common.build_flags} -DMY_LANGUAGE=bg_BG From 246dcea2d1e590ce11f584d8290cf9a9e6286f30 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 22 Jul 2020 21:07:40 +0200 Subject: [PATCH 545/581] new build variant ZigbeeBridge --- tasmota/tasmota_configurations.h | 258 +++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 61baee7aa..f067a7cda 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -406,6 +406,264 @@ #undef USE_DEBUG_DRIVER // Disable debug code #endif // FIRMWARE_IR + +/*********************************************************************************************\ + * [tasmota-zbbridge.bin] + * Provide an image for the Sonoff Zigbee Bridge +\*********************************************************************************************/ + +#ifdef FIRMWARE_ZBBRIDGE // ******************************************************************* + +#undef CODE_IMAGE_STR +#define CODE_IMAGE_STR "zbbridge" + +//#define USE_ARDUINO_OTA // Add optional support for Arduino OTA (+13k code) +#define USE_DOMOTICZ // Enable Domoticz (+6k code, +0.3k mem) +//#define USE_HOME_ASSISTANT // Enable Home Assistant Discovery Support (+7k code) + +//#define USE_MQTT_TLS // Use TLS for MQTT connection (+34.5k code, +7.0k mem and +4.8k additional during connection handshake) +// #define USE_MQTT_TLS_CA_CERT // Force full CA validation instead of fingerprints, slower, but simpler to use (+2.2k code, +1.9k mem during connection handshake) +// #define USE_MQTT_TLS_FORCE_EC_CIPHER // Force Elliptic Curve cipher (higher security) required by some servers (automatically enabled with USE_MQTT_AWS_IOT) (+11.4k code, +0.4k mem) +// #define USE_MQTT_AWS_IOT // Enable MQTT for AWS IoT - requires a private key (+11.9k code, +0.4k mem) + +//#define USE_KNX // Enable KNX IP Protocol Support (+9.4k code, +3k7 mem) +#define USE_WEBSERVER // Enable web server and Wifi Manager (+66k code, +8k mem) + #define USE_JAVASCRIPT_ES6 // Enable ECMAScript6 syntax using less JavaScript code bytes (fails on IE11) +#define USE_WEBSEND_RESPONSE // Enable command WebSend response message (+1k code) +#define USE_EMULATION_HUE // Enable Hue Bridge emulation for Alexa (+14k code, +2k mem) +// #define USE_EMULATION_WEMO // Enable Belkin WeMo emulation for Alexa (+6k code, +2k mem) +// #define USE_SENDMAIL + +//#define USE_DISCOVERY // Enable mDNS for the following services (+8k code, +0.3k mem) +#define USE_TIMERS // Add support for up to 16 timers (+2k2 code) + #define USE_TIMERS_WEB // Add timer webpage support (+4k5 code) + #define USE_SUNRISE // Add support for Sunrise and sunset tools (+16k) + +// -- Compression --------------------------------- +#define USE_UNISHOX_COMPRESSION // Add support for string compression in Rules or Scripts + +#define USE_RULES // Add support for rules (+4k4 code) +// #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem) +// #define SUPPORT_IF_STATEMENT // Add support for IF statement in rules (+4k2 code, -332 bytes mem) +// #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code) + +//#define USE_SCRIPT // Add support for script + #define USE_SCRIPT_FATFS 4 // Add support for script storage on SD card (+12k code, +4k mem) + +// -- Optional modules ---------------------------- +//#define ROTARY_V1 // Add support for MI Desk Lamp +//#define USE_SONOFF_RF // Add support for Sonoff Rf Bridge +// #define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+3k code) +//#define USE_SONOFF_SC // Add support for Sonoff Sc (+1k1 code) +//#define USE_TUYA_MCU // Add support for Tuya Serial Dimmer +//#define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code) +//#define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer and Sonoff L1 (+2k code) +//#define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code) +//#define USE_BUZZER // Add support for a buzzer (+0k6 code) +//#define USE_ARILUX_RF // Add support for Arilux RF remote controller (+1k code, 252 iram (non 2.3.0)) +//#define USE_SHUTTER // Add Shutter support for up to 4 shutter with different motortypes (+6k code) +//#define USE_DEEPSLEEP // Add support for deepsleep (+1k code) +//#define USE_EXS_DIMMER // Add support for ES-Store WiFi Dimmer (+2k6 code) +//#define USE_HOTPLUG // Add support for HotPlug +//#define USE_DEVICE_GROUPS // Add support for device groups (+4k code) +//#define USE_PWM_DIMMER // Add support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+4k5 code) +// #define USE_PWM_DIMMER_REMOTE // Add support for remote switches to PWM Dimmer, also adds device groups support (+0k7 code, also includes device groups) +//#define USE_KEELOQ // Add support for Jarolift rollers by Keeloq algorithm (+4k5 code) +//#define USE_SONOFF_D1 // Add support for Sonoff D1 Dimmer + +// -- Optional light modules ---------------------- +#undef USE_LIGHT // DISABLES LIGHTS support +// #define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by // +// // #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow +// #define USE_WS2812_HARDWARE NEO_HW_WS2812 // Hardware type (NEO_HW_WS2812, NEO_HW_WS2812X, NEO_HW_WS2813, NEO_HW_SK6812, NEO_HW_LC8812, NEO_HW_APA106) +// // #define USE_WS2812_CTYPE NEO_GRB // WS2812 Color type (NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_RGBW, NEO_GRBW) +// #define USE_WS2812_CTYPE NEO_GRBW // WS2812 Color type (NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_RGBW, NEO_GRBW) +// #define USE_MY92X1 // Add support for MY92X1 RGBCW led controller as used in Sonoff B1, Ailight and Lohas +// #define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code) +// #define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code) +// #define USE_SONOFF_L1 // Add support for Sonoff L1 led control +//#define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller + +//#define USE_COUNTER // Enable counters +#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices + +// #define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code) +// #define W1_PARASITE_POWER // Optimize for parasite powered sensors + +// -- I2C sensors --------------------------------- +// #define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram) +#ifdef USE_I2C +// #define USE_SHT // Enable SHT1X sensor (+1k4 code) +// #define USE_HTU // Enable HTU21/SI7013/SI7020/SI7021 sensor (I2C address 0x40) (+1k5 code) +// #define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address 0x76 or 0x77) (+4k code) + #define USE_BME680 // Enable support for BME680 sensor using Bosch BME680 library (+4k code) +// #define USE_BH1750 // Enable BH1750 sensor (I2C address 0x23 or 0x5C) (+0k5 code) +// #define USE_VEML6070 // Enable VEML6070 sensor (I2C addresses 0x38 and 0x39) (+0k5 code) +// #define USE_ADS1115 // Enable ADS1115 16 bit A/D converter (I2C address 0x48, 0x49, 0x4A or 0x4B) based on Adafruit ADS1x15 library (no library needed) (+0k7 code) +// #define USE_INA219 // Enable INA219 (I2C address 0x40, 0x41 0x44 or 0x45) Low voltage and current sensor (+1k code) +// #define USE_INA226 // Enable INA226 (I2C address 0x40, 0x41 0x44 or 0x45) Low voltage and current sensor (+2k3 code) +// #define USE_SHT3X // Enable SHT3x (I2C address 0x44 or 0x45) or SHTC3 (I2C address 0x70) sensor (+0k7 code) +// #define USE_TSL2561 // Enable TSL2561 sensor (I2C address 0x29, 0x39 or 0x49) using library Joba_Tsl2561 (+2k3 code) +// #define USE_TSL2591 // Enable TSL2591 sensor (I2C address 0x29, 0x39 or 0x49) using library Adafruit_TSL2591 (+2k3 code) +// #define USE_MGS // Enable Xadow and Grove Mutichannel Gas sensor using library Multichannel_Gas_Sensor (+10k code) + #define MGS_SENSOR_ADDR 0x04 // Default Mutichannel Gas sensor i2c address +// #define USE_SGP30 // Enable SGP30 sensor (I2C address 0x58) (+1k1 code) +// #define USE_SI1145 // Enable SI1145/46/47 sensor (I2C address 0x60) (+1k code) +// #define USE_LM75AD // Enable LM75AD sensor (I2C addresses 0x48 - 0x4F) (+0k5 code) +// #define USE_APDS9960 // Enable APDS9960 Proximity Sensor (I2C address 0x39). Disables SHT and VEML6070 (+4k7 code) +// #define USE_MCP230xx // Enable MCP23008/MCP23017 for GP INPUT ONLY (I2C addresses 0x20 - 0x27) providing command Sensor29 for configuration (+2k2 code) +// #define USE_MCP230xx_ADDR 0x20 // Enable MCP23008/MCP23017 I2C Address to use (Must be within range 0x20 through 0x27 - set according to your wired setup) +// #define USE_MCP230xx_OUTPUT // Enable MCP23008/MCP23017 OUTPUT support through sensor29 commands (+1k code) +// #define USE_MCP230xx_DISPLAYOUTPUT // Enable MCP23008/MCP23017 to display state of OUTPUT pins on Web UI (+0k2 code) +// #define USE_PCA9685 // Enable PCA9685 I2C HW PWM Driver - Must define I2C Address in #define USE_PCA9685_ADDR below - range 0x40 - 0x47 (+1k4 code) +// #define USE_PCA9685_ADDR 0x40 // Enable PCA9685 I2C Address to use (Must be within range 0x40 through 0x47 - set according to your wired setup) +// #define USE_PCA9685_FREQ 50 // Define default PWM frequency in Hz to be used (must be within 24 to 1526) - If other value is used, it will rever to 50Hz +// #define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons (+1k3 code) +// #define USE_CCS811 // Enable CCS811 sensor (I2C address 0x5A) (+2k2 code) +// #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+2k6 code) +// #define USE_DS3231 // Enable DS3231 external RTC in case no Wifi is avaliable. See docs in the source file (+1k2 code) +// #define USE_RTC_ADDR 0x68 // Default I2C address 0x68 +// #define USE_MGC3130 // Enable MGC3130 Electric Field Effect Sensor (I2C address 0x42) (+2k7 code, 0k3 mem) +// #define USE_MAX44009 // Enable MAX44009 Ambient Light sensor (I2C addresses 0x4A and 0x4B) (+0k8 code) +// #define USE_SCD30 // Enable Sensiron SCd30 CO2 sensor (I2C address 0x61) (+3k3 code) +// #define USE_SPS30 // Enable Sensiron SPS30 particle sensor (I2C address 0x69) (+1.7 code) +// #define USE_ADE7953 // Enable ADE7953 Energy monitor as used on Shelly 2.5 (I2C address 0x38) (+1k5) +// #define USE_VL53L0X // Enable VL53L0x time of flight sensor (I2C address 0x29) (+4k code) +// #define USE_MLX90614 // Enable MLX90614 ir temp sensor (I2C address 0x5a) (+0.6k code) +// #define USE_CHIRP // Enable CHIRP soil moisture sensor (variable I2C address, default 0x20) +// #define USE_PAJ7620 // Enable PAJ7620 gesture sensor (I2C address 0x73) (+2.5k code) +// #define USE_PCF8574 // Enable PCF8574 I/O Expander (I2C addresses 0x20 - 0x27 and 0x38 - 0x3F) (+1k9 code) +// #define USE_HIH6 // Enable Honeywell HIH Humidity and Temperature sensor (I2C address 0x27) (+0k6) +// #define USE_DHT12 // [I2cDriver41] Enable DHT12 humidity and temperature sensor (I2C address 0x5C) (+0k7 code) +// #define USE_DS1624 // [I2cDriver42] Enable DS1624, DS1621 temperature sensor (I2C addresses 0x48 - 0x4F) +// #define USE_AHT1x // [I2cDriver43] Enable AHT10/15 humidity and temperature sensor (I2C address 0x38) (+0k8 code) +// #define USE_WEMOS_MOTOR_V1 // [I2cDriver44] Enable Wemos motor driver V1 () +// #define USE_HDC1080 // [I2cDriver45] Enable HDC1080 temperature/humidity sensor (I2C address 0x40) (+1k5 code) + +// #define USE_DISPLAY // Add I2C Display Support (+2k code) +// #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0 +// #define USE_DISPLAY_LCD // [DisplayModel 1] Enable Lcd display (I2C addresses 0x27 and 0x3F) (+6k code) +// #define USE_DISPLAY_SSD1306 // [DisplayModel 2] Enable SSD1306 Oled 128x64 display (I2C addresses 0x3C and 0x3D) (+16k code) +// #define USE_DISPLAY_MATRIX // [DisplayModel 3] Enable 8x8 Matrix display (I2C adresseses see below) (+11k code) +// #define MTX_ADDRESS1 0x71 // [DisplayAddress1] I2C address of first 8x8 matrix module +// #define MTX_ADDRESS2 0x74 // [DisplayAddress2] I2C address of second 8x8 matrix module +// #define MTX_ADDRESS3 0x75 // [DisplayAddress3] I2C address of third 8x8 matrix module +// #define MTX_ADDRESS4 0x72 // [DisplayAddress4] I2C address of fourth 8x8 matrix module +// #define MTX_ADDRESS5 0x73 // [DisplayAddress5] I2C address of fifth 8x8 matrix module +// #define MTX_ADDRESS6 0x76 // [DisplayAddress6] I2C address of sixth 8x8 matrix module +// #define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module +// #define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module +// #define USE_DISPLAY_SH1106 // [DisplayModel 7] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D) +#endif // USE_I2C + +// // -- SPI sensors --------------------------------- +// #define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC) +// #ifdef USE_SPI +// // #define USE_NRF24 // Add SPI support for NRF24L01(+) (+2k6 code) +// #ifdef USE_NRF24 +// #define USE_MIBLE // BLE-bridge for some Mijia-BLE-sensors (+4k7 code) +// #else +// #ifndef USE_DISPLAY +// #define USE_DISPLAY // Add SPI Display support for 320x240 and 480x320 TFT +// #endif +// #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code) +// // #define USE_DISPLAY_EPAPER_29 // [DisplayModel 5] Enable e-paper 2.9 inch display (+19k code) +// // #define USE_DISPLAY_EPAPER_42 // [DisplayModel 6] Enable e-paper 4.2 inch display +// // #define USE_DISPLAY_ILI9488 // [DisplayModel 8] [I2cDriver38] (Touch) +// // #define USE_DISPLAY_SSD1351 // [DisplayModel 9] +// // #define USE_DISPLAY_RA8876 // [DisplayModel 10] [I2cDriver39] (Touch) +// #endif // USE_NRF24 +// #endif // USE_SPI + +// -- Serial sensors ------------------------------ +//#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code) +//#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code) +//#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code) +//#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code) +//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor (+1k4) +//#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+1k1 code) +//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop +//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) +//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) +// #define USE_PN532_CAUSE_EVENTS // Cause event execution for PN532_UID= and PN532_DATA=[if defined] (+ 30 bytes code) + #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) + #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram) +//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8) +//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) +//#define USE_HM10 // Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +//#define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) + +// Power monitoring sensors ----------------------- +#undef USE_ENERGY_SENSOR // Disable energy sensors (-14k code) +// #define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) +// // #define USE_ENERGY_POWER_LIMIT // Add additional support for Energy Power Limit detection (+1k2 code) +// #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) +// #define USE_PZEM_AC // Add support for PZEM014,016 Modbus Energy monitor (+1k1 code) +// //#define USE_PZEM_DC // Add support for PZEM003,017 Modbus Energy monitor (+1k1 code) +// #define USE_MCP39F501 // Add support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code) +//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy monitor (+1k1 code) +//#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy monitor (+0k6 code) +//#define USE_DDS2382 // Add support for Hiking DDS2382 Modbus energy monitor (+0k6 code) +//#define USE_DDSU666 // Add support for Chint DDSU666 Modbus energy monitor (+0k6 code) +//#define USE_SOLAX_X1 // Add support for Solax X1 series Modbus log info (+4k1 code) +//#define USE_LE01MR // Add support for F&F LE-01MR modbus energy meter + +// -- Low level interface devices ----------------- +//#define USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor + +//#define USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI + +// -- IR Remote features -------------------------- +//#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k3 code, 0k3 mem, 48 iram) + #define USE_IR_SEND_NEC // Support IRsend NEC protocol + #define USE_IR_SEND_RC5 // Support IRsend Philips RC5 protocol + #define USE_IR_SEND_RC6 // Support IRsend Philips RC6 protocol + +// #define USE_IR_RECEIVE // Support for IR receiver (+7k2 code, 264 iram) + #define IR_RCV_BUFFER_SIZE 100 // Max number of packets allowed in capture buffer (default 100 (*2 bytes ram)) + #define IR_RCV_TIMEOUT 15 // Number of milli-Seconds of no-more-data before we consider a message ended (default 15) + #define IR_RCV_MIN_UNKNOWN_SIZE 6 // Set the smallest sized "UNKNOWN" message packets we actually care about (default 6, max 255) + +// -- Zigbee interface ---------------------------- +#define USE_ZIGBEE +#undef USE_ZIGBEE_ZNP +#define USE_ZIGBEE_EZSP +#define USE_TCP_BRIDGE + #define USE_ZIGBEE_PANID 0x1A63 // arbitrary PAN ID for Zigbee network, must be unique in the home + #define USE_ZIGBEE_EXTPANID 0xCCCCCCCCCCCCCCCCL // arbitrary extended PAN ID + #define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26) + #define USE_ZIGBEE_PRECFGKEY_L 0x0F0D0B0907050301L // note: changing requires to re-pair all devices + #define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices + #define USE_ZIGBEE_PERMIT_JOIN false // don't allow joining by default + #define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms) + + +// ------------------------------------------------ + +//#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code) + +//#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code) +//#define USE_HX711 // Add support for HX711 load cell (+1k5 code) + #define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code) + +//#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k6/0k8 code) +//#define USE_TX23_WIND_SENSOR // Add support for La Crosse TX23 anemometer (+2k7/1k code) + +//#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram) + +//#define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) +// #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) +// #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code) + +//#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code) +//#define USE_A4988_STEPPER // Add support for A4988 stepper-motor-driver-circuit (+10k5 code) + +//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) + +#endif // SONOFF_ZIGBEEBRIDGE ****************************************************************** + + + /*********************************************************************************************\ * [tasmota-lite.bin] * Provide an image without sensors From 785289234f7c67eec9bf03b8ee902dc1bd9c71e6 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 22 Jul 2020 21:25:20 +0200 Subject: [PATCH 546/581] Lights support needed for HUE Emulation --- tasmota/tasmota_configurations.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index f067a7cda..952b7b4f6 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -472,7 +472,7 @@ //#define USE_SONOFF_D1 // Add support for Sonoff D1 Dimmer // -- Optional light modules ---------------------- -#undef USE_LIGHT // DISABLES LIGHTS support +#define USE_LIGHT // Add LIGHTS support // #define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by // // // #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow // #define USE_WS2812_HARDWARE NEO_HW_WS2812 // Hardware type (NEO_HW_WS2812, NEO_HW_WS2812X, NEO_HW_WS2813, NEO_HW_SK6812, NEO_HW_LC8812, NEO_HW_APA106) From ced34fa858b9ccf2239f24a24a586a96cba6bae4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 22 Jul 2020 21:29:06 +0200 Subject: [PATCH 547/581] zbbridge --- .github/workflows/CI_github.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml index 0fe2fd9c5..1f4f79f38 100644 --- a/.github/workflows/CI_github.yml +++ b/.github/workflows/CI_github.yml @@ -110,6 +110,21 @@ jobs: - name: Run PlatformIO run: platformio run -e tasmota-ir + tasmota-zbbridge: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-zbbridge + tasmota-BG: runs-on: ubuntu-latest steps: From da09901d8b52209ce9a9dc614be100f7c35abc0c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 22 Jul 2020 21:32:48 +0200 Subject: [PATCH 548/581] Build firmware zbbridge --- .github/workflows/Tasmota_build.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index 819771059..46c7beefb 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -207,6 +207,28 @@ jobs: path: ./build_output/firmware + tasmota-zbbridge: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-zbbridge + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + tasmota-BG: needs: tasmota_pull runs-on: ubuntu-latest From 6f9715c0da2db85801861f24c783d807b18cc973 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 23 Jul 2020 09:26:10 +0200 Subject: [PATCH 549/581] needed undef added --- tasmota/tasmota_configurations.h | 317 ++++++++++--------------------- 1 file changed, 97 insertions(+), 220 deletions(-) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 952b7b4f6..ac0b629f2 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -417,214 +417,113 @@ #undef CODE_IMAGE_STR #define CODE_IMAGE_STR "zbbridge" -//#define USE_ARDUINO_OTA // Add optional support for Arduino OTA (+13k code) -#define USE_DOMOTICZ // Enable Domoticz (+6k code, +0.3k mem) -//#define USE_HOME_ASSISTANT // Enable Home Assistant Discovery Support (+7k code) +#undef USE_ARDUINO_OTA // Disable support for Arduino OTA +#define USE_DOMOTICZ // Disable Domoticz +#undef USE_HOME_ASSISTANT // Disable Home Assistant +#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set +#undef USE_KNX // Disable KNX IP Protocol Support +//#undef USE_WEBSERVER // Disable Webserver +//#undef USE_WEBSEND_RESPONSE // Disable command WebSend response message (+1k code) +#define USE_EMULATION // Disable Wemo or Hue emulation +#define USE_EMULATION_HUE // Disable Hue Bridge emulation for Alexa (+14k code, +2k mem common) +//#undef USE_EMULATION_WEMO // Disable Belkin WeMo emulation for Alexa (+6k code, +2k mem common) +#undef USE_CUSTOM // Disable Custom features +#undef USE_DISCOVERY // Disable Discovery services for both MQTT and web server +//#undef USE_TIMERS // Disable support for up to 16 timers +//#undef USE_TIMERS_WEB // Disable support for timer webpage +//#undef USE_SUNRISE // Disable support for Sunrise and sunset tools +//#undef USE_RULES // Disable support for rules +#undef USE_SCRIPT // Add support for script (+17k code) -//#define USE_MQTT_TLS // Use TLS for MQTT connection (+34.5k code, +7.0k mem and +4.8k additional during connection handshake) -// #define USE_MQTT_TLS_CA_CERT // Force full CA validation instead of fingerprints, slower, but simpler to use (+2.2k code, +1.9k mem during connection handshake) -// #define USE_MQTT_TLS_FORCE_EC_CIPHER // Force Elliptic Curve cipher (higher security) required by some servers (automatically enabled with USE_MQTT_AWS_IOT) (+11.4k code, +0.4k mem) -// #define USE_MQTT_AWS_IOT // Enable MQTT for AWS IoT - requires a private key (+11.9k code, +0.4k mem) - -//#define USE_KNX // Enable KNX IP Protocol Support (+9.4k code, +3k7 mem) -#define USE_WEBSERVER // Enable web server and Wifi Manager (+66k code, +8k mem) - #define USE_JAVASCRIPT_ES6 // Enable ECMAScript6 syntax using less JavaScript code bytes (fails on IE11) -#define USE_WEBSEND_RESPONSE // Enable command WebSend response message (+1k code) -#define USE_EMULATION_HUE // Enable Hue Bridge emulation for Alexa (+14k code, +2k mem) -// #define USE_EMULATION_WEMO // Enable Belkin WeMo emulation for Alexa (+6k code, +2k mem) -// #define USE_SENDMAIL - -//#define USE_DISCOVERY // Enable mDNS for the following services (+8k code, +0.3k mem) -#define USE_TIMERS // Add support for up to 16 timers (+2k2 code) - #define USE_TIMERS_WEB // Add timer webpage support (+4k5 code) - #define USE_SUNRISE // Add support for Sunrise and sunset tools (+16k) - -// -- Compression --------------------------------- -#define USE_UNISHOX_COMPRESSION // Add support for string compression in Rules or Scripts - -#define USE_RULES // Add support for rules (+4k4 code) -// #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem) -// #define SUPPORT_IF_STATEMENT // Add support for IF statement in rules (+4k2 code, -332 bytes mem) -// #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code) - -//#define USE_SCRIPT // Add support for script - #define USE_SCRIPT_FATFS 4 // Add support for script storage on SD card (+12k code, +4k mem) - -// -- Optional modules ---------------------------- -//#define ROTARY_V1 // Add support for MI Desk Lamp -//#define USE_SONOFF_RF // Add support for Sonoff Rf Bridge -// #define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+3k code) -//#define USE_SONOFF_SC // Add support for Sonoff Sc (+1k1 code) -//#define USE_TUYA_MCU // Add support for Tuya Serial Dimmer -//#define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code) -//#define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer and Sonoff L1 (+2k code) -//#define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code) -//#define USE_BUZZER // Add support for a buzzer (+0k6 code) -//#define USE_ARILUX_RF // Add support for Arilux RF remote controller (+1k code, 252 iram (non 2.3.0)) -//#define USE_SHUTTER // Add Shutter support for up to 4 shutter with different motortypes (+6k code) -//#define USE_DEEPSLEEP // Add support for deepsleep (+1k code) -//#define USE_EXS_DIMMER // Add support for ES-Store WiFi Dimmer (+2k6 code) -//#define USE_HOTPLUG // Add support for HotPlug -//#define USE_DEVICE_GROUPS // Add support for device groups (+4k code) -//#define USE_PWM_DIMMER // Add support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+4k5 code) -// #define USE_PWM_DIMMER_REMOTE // Add support for remote switches to PWM Dimmer, also adds device groups support (+0k7 code, also includes device groups) -//#define USE_KEELOQ // Add support for Jarolift rollers by Keeloq algorithm (+4k5 code) -//#define USE_SONOFF_D1 // Add support for Sonoff D1 Dimmer +// -- Optional modules ------------------------- +#undef ROTARY_V1 // Disable support for MI Desk Lamp +#undef USE_SONOFF_RF // Disable support for Sonoff Rf Bridge (+3k2 code) + #undef USE_RF_FLASH // Disable support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB +#undef USE_SONOFF_SC // Disable support for Sonoff Sc (+1k1 code) +#undef USE_TUYA_MCU // Disable support for Tuya Serial MCU +#undef USE_ARMTRONIX_DIMMERS // Disable support for Armtronix Dimmers (+1k4 code) +#undef USE_PS_16_DZ // Disable support for PS-16-DZ Dimmer and Sonoff L1 (+2k code) +#undef USE_SONOFF_IFAN // Disable support for Sonoff iFan02 and iFan03 (+2k code) +#undef USE_BUZZER // Disable support for a buzzer (+0k6 code) +#undef USE_ARILUX_RF // Disable support for Arilux RF remote controller +#undef USE_SHUTTER // Disable Shutter support for up to 4 shutter with different motortypes (+6k code) +#undef USE_DEEPSLEEP // Disable support for deepsleep (+1k code) +#undef USE_EXS_DIMMER // Disable support for EX-Store WiFi Dimmer +#undef USE_HOTPLUG // Disable support for HotPlug +#undef USE_DEVICE_GROUPS // Disable support for device groups (+3k5 code) +#undef USE_PWM_DIMMER // Disable support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+4k5 code) +#undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer +#undef USE_KEELOQ // Disable support for Jarolift rollers by Keeloq algorithm (+4k5 code) +#undef USE_SONOFF_D1 // Disable support for Sonoff D1 Dimmer (+0k7 code) // -- Optional light modules ---------------------- -#define USE_LIGHT // Add LIGHTS support -// #define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by // -// // #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow -// #define USE_WS2812_HARDWARE NEO_HW_WS2812 // Hardware type (NEO_HW_WS2812, NEO_HW_WS2812X, NEO_HW_WS2813, NEO_HW_SK6812, NEO_HW_LC8812, NEO_HW_APA106) -// // #define USE_WS2812_CTYPE NEO_GRB // WS2812 Color type (NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_RGBW, NEO_GRBW) -// #define USE_WS2812_CTYPE NEO_GRBW // WS2812 Color type (NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_RGBW, NEO_GRBW) -// #define USE_MY92X1 // Add support for MY92X1 RGBCW led controller as used in Sonoff B1, Ailight and Lohas -// #define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code) -// #define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code) -// #define USE_SONOFF_L1 // Add support for Sonoff L1 led control -//#define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller +//#undef USE_LIGHT // Enable Dimmer/Light support +#undef USE_WS2812 // Disable WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by // +#undef USE_MY92X1 // Disable support for MY92X1 RGBCW led controller as used in Sonoff B1, Ailight and Lohas +#undef USE_SM16716 // Disable support for SM16716 RGB LED controller (+0k7 code) +#undef USE_SM2135 // Disable support for SM2135 RGBCW led control as used in Action LSC (+0k6 code) +#undef USE_SONOFF_L1 // Disable support for Sonoff L1 led control +#undef USE_ELECTRIQ_MOODL // Disable support for ElectriQ iQ-wifiMOODL RGBW LED controller +#undef USE_LIGHT_PALETTE // Disable support for color palette (+0k9 code) -//#define USE_COUNTER // Enable counters +#undef USE_COUNTER // Disable counters #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices +#undef USE_DS18x20 // Disable DS18x20 sensor +#undef USE_I2C // Disable all I2C sensors and devices +#undef USE_SPI // Disable all SPI devices +#undef USE_DISPLAY // Disable Display support +#undef USE_MHZ19 // Disable support for MH-Z19 CO2 sensor +#undef USE_SENSEAIR // Disable support for SenseAir K30, K70 and S8 CO2 sensor +#undef USE_PMS5003 // Disable support for PMS5003 and PMS7003 particle concentration sensor +#undef USE_NOVA_SDS // Disable support for SDS011 and SDS021 particle concentration sensor +#undef USE_HPMA // Disable support for Honeywell HPMA115S0 particle concentration sensor +#undef USE_SERIAL_BRIDGE // Disable support for software Serial Bridge +#undef USE_MP3_PLAYER // Disable DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop +#undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger +#undef USE_PN532_HSU // Disable support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) +#undef USE_ZIGBEE // Disable serial communication with Zigbee CC2530 flashed with ZNP +#undef USE_RDM6300 // Disable support for RDM6300 125kHz RFID Reader (+0k8) +#undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) +#undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) +#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) +#undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) -// #define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code) -// #define W1_PARASITE_POWER // Optimize for parasite powered sensors +#undef USE_ENERGY_SENSOR // Disable energy sensors +#undef USE_PZEM004T // Disable PZEM004T energy sensor +#undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor +#undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor +#undef USE_MCP39F501 // Disable MCP39F501 Energy monitor as used in Shelly 2 +#undef USE_SDM120 // Disable support for Eastron SDM120-Modbus energy meter +#undef USE_SDM630 // Disable support for Eastron SDM630-Modbus energy monitor (+0k6 code) +#undef USE_DDS2382 // Disable support for Hiking DDS2382 Modbus energy monitor (+0k6 code) +#undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) +#undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) +#undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) +#undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry -// -- I2C sensors --------------------------------- -// #define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram) -#ifdef USE_I2C -// #define USE_SHT // Enable SHT1X sensor (+1k4 code) -// #define USE_HTU // Enable HTU21/SI7013/SI7020/SI7021 sensor (I2C address 0x40) (+1k5 code) -// #define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address 0x76 or 0x77) (+4k code) - #define USE_BME680 // Enable support for BME680 sensor using Bosch BME680 library (+4k code) -// #define USE_BH1750 // Enable BH1750 sensor (I2C address 0x23 or 0x5C) (+0k5 code) -// #define USE_VEML6070 // Enable VEML6070 sensor (I2C addresses 0x38 and 0x39) (+0k5 code) -// #define USE_ADS1115 // Enable ADS1115 16 bit A/D converter (I2C address 0x48, 0x49, 0x4A or 0x4B) based on Adafruit ADS1x15 library (no library needed) (+0k7 code) -// #define USE_INA219 // Enable INA219 (I2C address 0x40, 0x41 0x44 or 0x45) Low voltage and current sensor (+1k code) -// #define USE_INA226 // Enable INA226 (I2C address 0x40, 0x41 0x44 or 0x45) Low voltage and current sensor (+2k3 code) -// #define USE_SHT3X // Enable SHT3x (I2C address 0x44 or 0x45) or SHTC3 (I2C address 0x70) sensor (+0k7 code) -// #define USE_TSL2561 // Enable TSL2561 sensor (I2C address 0x29, 0x39 or 0x49) using library Joba_Tsl2561 (+2k3 code) -// #define USE_TSL2591 // Enable TSL2591 sensor (I2C address 0x29, 0x39 or 0x49) using library Adafruit_TSL2591 (+2k3 code) -// #define USE_MGS // Enable Xadow and Grove Mutichannel Gas sensor using library Multichannel_Gas_Sensor (+10k code) - #define MGS_SENSOR_ADDR 0x04 // Default Mutichannel Gas sensor i2c address -// #define USE_SGP30 // Enable SGP30 sensor (I2C address 0x58) (+1k1 code) -// #define USE_SI1145 // Enable SI1145/46/47 sensor (I2C address 0x60) (+1k code) -// #define USE_LM75AD // Enable LM75AD sensor (I2C addresses 0x48 - 0x4F) (+0k5 code) -// #define USE_APDS9960 // Enable APDS9960 Proximity Sensor (I2C address 0x39). Disables SHT and VEML6070 (+4k7 code) -// #define USE_MCP230xx // Enable MCP23008/MCP23017 for GP INPUT ONLY (I2C addresses 0x20 - 0x27) providing command Sensor29 for configuration (+2k2 code) -// #define USE_MCP230xx_ADDR 0x20 // Enable MCP23008/MCP23017 I2C Address to use (Must be within range 0x20 through 0x27 - set according to your wired setup) -// #define USE_MCP230xx_OUTPUT // Enable MCP23008/MCP23017 OUTPUT support through sensor29 commands (+1k code) -// #define USE_MCP230xx_DISPLAYOUTPUT // Enable MCP23008/MCP23017 to display state of OUTPUT pins on Web UI (+0k2 code) -// #define USE_PCA9685 // Enable PCA9685 I2C HW PWM Driver - Must define I2C Address in #define USE_PCA9685_ADDR below - range 0x40 - 0x47 (+1k4 code) -// #define USE_PCA9685_ADDR 0x40 // Enable PCA9685 I2C Address to use (Must be within range 0x40 through 0x47 - set according to your wired setup) -// #define USE_PCA9685_FREQ 50 // Define default PWM frequency in Hz to be used (must be within 24 to 1526) - If other value is used, it will rever to 50Hz -// #define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons (+1k3 code) -// #define USE_CCS811 // Enable CCS811 sensor (I2C address 0x5A) (+2k2 code) -// #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+2k6 code) -// #define USE_DS3231 // Enable DS3231 external RTC in case no Wifi is avaliable. See docs in the source file (+1k2 code) -// #define USE_RTC_ADDR 0x68 // Default I2C address 0x68 -// #define USE_MGC3130 // Enable MGC3130 Electric Field Effect Sensor (I2C address 0x42) (+2k7 code, 0k3 mem) -// #define USE_MAX44009 // Enable MAX44009 Ambient Light sensor (I2C addresses 0x4A and 0x4B) (+0k8 code) -// #define USE_SCD30 // Enable Sensiron SCd30 CO2 sensor (I2C address 0x61) (+3k3 code) -// #define USE_SPS30 // Enable Sensiron SPS30 particle sensor (I2C address 0x69) (+1.7 code) -// #define USE_ADE7953 // Enable ADE7953 Energy monitor as used on Shelly 2.5 (I2C address 0x38) (+1k5) -// #define USE_VL53L0X // Enable VL53L0x time of flight sensor (I2C address 0x29) (+4k code) -// #define USE_MLX90614 // Enable MLX90614 ir temp sensor (I2C address 0x5a) (+0.6k code) -// #define USE_CHIRP // Enable CHIRP soil moisture sensor (variable I2C address, default 0x20) -// #define USE_PAJ7620 // Enable PAJ7620 gesture sensor (I2C address 0x73) (+2.5k code) -// #define USE_PCF8574 // Enable PCF8574 I/O Expander (I2C addresses 0x20 - 0x27 and 0x38 - 0x3F) (+1k9 code) -// #define USE_HIH6 // Enable Honeywell HIH Humidity and Temperature sensor (I2C address 0x27) (+0k6) -// #define USE_DHT12 // [I2cDriver41] Enable DHT12 humidity and temperature sensor (I2C address 0x5C) (+0k7 code) -// #define USE_DS1624 // [I2cDriver42] Enable DS1624, DS1621 temperature sensor (I2C addresses 0x48 - 0x4F) -// #define USE_AHT1x // [I2cDriver43] Enable AHT10/15 humidity and temperature sensor (I2C address 0x38) (+0k8 code) -// #define USE_WEMOS_MOTOR_V1 // [I2cDriver44] Enable Wemos motor driver V1 () -// #define USE_HDC1080 // [I2cDriver45] Enable HDC1080 temperature/humidity sensor (I2C address 0x40) (+1k5 code) -// #define USE_DISPLAY // Add I2C Display Support (+2k code) -// #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0 -// #define USE_DISPLAY_LCD // [DisplayModel 1] Enable Lcd display (I2C addresses 0x27 and 0x3F) (+6k code) -// #define USE_DISPLAY_SSD1306 // [DisplayModel 2] Enable SSD1306 Oled 128x64 display (I2C addresses 0x3C and 0x3D) (+16k code) -// #define USE_DISPLAY_MATRIX // [DisplayModel 3] Enable 8x8 Matrix display (I2C adresseses see below) (+11k code) -// #define MTX_ADDRESS1 0x71 // [DisplayAddress1] I2C address of first 8x8 matrix module -// #define MTX_ADDRESS2 0x74 // [DisplayAddress2] I2C address of second 8x8 matrix module -// #define MTX_ADDRESS3 0x75 // [DisplayAddress3] I2C address of third 8x8 matrix module -// #define MTX_ADDRESS4 0x72 // [DisplayAddress4] I2C address of fourth 8x8 matrix module -// #define MTX_ADDRESS5 0x73 // [DisplayAddress5] I2C address of fifth 8x8 matrix module -// #define MTX_ADDRESS6 0x76 // [DisplayAddress6] I2C address of sixth 8x8 matrix module -// #define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module -// #define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module -// #define USE_DISPLAY_SH1106 // [DisplayModel 7] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D) -#endif // USE_I2C +#undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor +#undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI +#undef USE_MAX31865 // Disable support for MAX31865 RTD sensors using softSPI +#undef USE_IR_REMOTE // Disable IR driver -// // -- SPI sensors --------------------------------- -// #define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC) -// #ifdef USE_SPI -// // #define USE_NRF24 // Add SPI support for NRF24L01(+) (+2k6 code) -// #ifdef USE_NRF24 -// #define USE_MIBLE // BLE-bridge for some Mijia-BLE-sensors (+4k7 code) -// #else -// #ifndef USE_DISPLAY -// #define USE_DISPLAY // Add SPI Display support for 320x240 and 480x320 TFT -// #endif -// #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code) -// // #define USE_DISPLAY_EPAPER_29 // [DisplayModel 5] Enable e-paper 2.9 inch display (+19k code) -// // #define USE_DISPLAY_EPAPER_42 // [DisplayModel 6] Enable e-paper 4.2 inch display -// // #define USE_DISPLAY_ILI9488 // [DisplayModel 8] [I2cDriver38] (Touch) -// // #define USE_DISPLAY_SSD1351 // [DisplayModel 9] -// // #define USE_DISPLAY_RA8876 // [DisplayModel 10] [I2cDriver39] (Touch) -// #endif // USE_NRF24 -// #endif // USE_SPI +#undef USE_SR04 // Disable support for for HC-SR04 ultrasonic devices +#undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8 +#undef USE_HX711 // Disable support for HX711 load cell +#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer +#undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer +#undef USE_WINDMETER // Disable support for analog anemometer (+2k2 code) +#undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch +#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) +#undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code) +#undef USE_A4988_STEPPER // Disable support for A4988_Stepper +#undef USE_THERMOSTAT // Disable support for Thermostat +#undef DEBUG_THEO // Disable debug code +#undef USE_DEBUG_DRIVER // Disable debug code -// -- Serial sensors ------------------------------ -//#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code) -//#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code) -//#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code) -//#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code) -//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor (+1k4) -//#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+1k1 code) -//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop -//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) -//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) -// #define USE_PN532_CAUSE_EVENTS // Cause event execution for PN532_UID= and PN532_DATA=[if defined] (+ 30 bytes code) - #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem) - #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram) -//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8) -//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) -//#define USE_HM10 // Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) -//#define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) - -// Power monitoring sensors ----------------------- -#undef USE_ENERGY_SENSOR // Disable energy sensors (-14k code) -// #define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) -// // #define USE_ENERGY_POWER_LIMIT // Add additional support for Energy Power Limit detection (+1k2 code) -// #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) -// #define USE_PZEM_AC // Add support for PZEM014,016 Modbus Energy monitor (+1k1 code) -// //#define USE_PZEM_DC // Add support for PZEM003,017 Modbus Energy monitor (+1k1 code) -// #define USE_MCP39F501 // Add support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code) -//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy monitor (+1k1 code) -//#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy monitor (+0k6 code) -//#define USE_DDS2382 // Add support for Hiking DDS2382 Modbus energy monitor (+0k6 code) -//#define USE_DDSU666 // Add support for Chint DDSU666 Modbus energy monitor (+0k6 code) -//#define USE_SOLAX_X1 // Add support for Solax X1 series Modbus log info (+4k1 code) -//#define USE_LE01MR // Add support for F&F LE-01MR modbus energy meter - -// -- Low level interface devices ----------------- -//#define USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor - -//#define USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI - -// -- IR Remote features -------------------------- -//#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k3 code, 0k3 mem, 48 iram) - #define USE_IR_SEND_NEC // Support IRsend NEC protocol - #define USE_IR_SEND_RC5 // Support IRsend Philips RC5 protocol - #define USE_IR_SEND_RC6 // Support IRsend Philips RC6 protocol - -// #define USE_IR_RECEIVE // Support for IR receiver (+7k2 code, 264 iram) - #define IR_RCV_BUFFER_SIZE 100 // Max number of packets allowed in capture buffer (default 100 (*2 bytes ram)) - #define IR_RCV_TIMEOUT 15 // Number of milli-Seconds of no-more-data before we consider a message ended (default 15) - #define IR_RCV_MIN_UNKNOWN_SIZE 6 // Set the smallest sized "UNKNOWN" message packets we actually care about (default 6, max 255) - -// -- Zigbee interface ---------------------------- #define USE_ZIGBEE #undef USE_ZIGBEE_ZNP #define USE_ZIGBEE_EZSP @@ -638,28 +537,6 @@ #define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms) -// ------------------------------------------------ - -//#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code) - -//#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code) -//#define USE_HX711 // Add support for HX711 load cell (+1k5 code) - #define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code) - -//#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k6/0k8 code) -//#define USE_TX23_WIND_SENSOR // Add support for La Crosse TX23 anemometer (+2k7/1k code) - -//#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram) - -//#define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) -// #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) -// #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code) - -//#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code) -//#define USE_A4988_STEPPER // Add support for A4988 stepper-motor-driver-circuit (+10k5 code) - -//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) - #endif // SONOFF_ZIGBEEBRIDGE ****************************************************************** From 354b6375cdb54143fe59fb6e7fdc1e5838b02bd1 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 23 Jul 2020 10:31:37 +0200 Subject: [PATCH 550/581] mv firmware bridge to commit folder --- .github/workflows/Tasmota_build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index 46c7beefb..1a9a011de 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -1504,6 +1504,7 @@ jobs: [ ! -f ./mv_firmware/tasmota-ir*.* ] || mv ./mv_firmware/tasmota-ir*.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota-display.* ] || mv ./mv_firmware/tasmota-display.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota-knx.* ] || mv ./mv_firmware/tasmota-knx.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-zbbridge.* ] || mv ./mv_firmware/tasmota-zbbridge.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota32.* ] || mv ./mv_firmware/tasmota32.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-sensors.* ] || mv ./mv_firmware/tasmota32-sensors.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-minimal.* ] || mv ./mv_firmware/tasmota32-minimal.* ./firmware/tasmota32/ From 9adc4b420228c5534fc2dd7c6da05f892c07559b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 23 Jul 2020 11:39:51 +0200 Subject: [PATCH 551/581] Add new module 75 supporting Sonoff Zigbee Bridge Add new module 75 supporting Sonoff Zigbee Bridge (#8583) --- tasmota/tasmota_template.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 2247372d1..8c62a236b 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -799,7 +799,7 @@ enum SupportedModules { SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH, OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4, OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, - SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, + SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, SONOFF_ZB_BRIDGE, MAXMODULE}; #define USER_MODULE 255 @@ -812,7 +812,7 @@ const char kModuleNames[] PROGMEM = "Sonoff S31|Zengge WF017|Sonoff Pow R2|Sonoff iFan02|BlitzWolf SHP|Shelly 1|Shelly 2|Xiaomi Philips|Neo Coolcam|ESP Switch|" "OBI Socket|Teckin|AplicWDP303075|Tuya MCU|Gosund SP1 v23|ARMTR Dimmer|SK03 Outdoor|PS-16-DZ|Teckin US|Manzoku strip|" "OBI Socket 2|YTF IR Bridge|Digoo DG-SP202|KA10|Luminea ZX2820|Mi Desk Lamp|SP10|WAGA CHCZ02MB|SYF05|Sonoff L1|" - "Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1" + "Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1|Sonoff ZbBridge" ; const uint8_t kModuleNiceList[] PROGMEM = { @@ -850,6 +850,9 @@ const uint8_t kModuleNiceList[] PROGMEM = { #endif #ifdef USE_SONOFF_RF SONOFF_BRIDGE, // Sonoff Bridge +#endif +#ifdef USE_ZIGBEE_EZSP + SONOFF_ZB_BRIDGE, #endif SONOFF_SV, // Sonoff Development Devices SONOFF_DEV, @@ -2278,6 +2281,25 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, // GPIO12 GPIO_LED1_INV, // GPIO13 WiFi Blue Led - Link and Power status 0, 0, 0, 0 + }, + { // SONOFF_ZB_BRIDGE - Sonoff Zigbee Bridge (ESP8266) + GPIO_LED1_INV, // GPIO00 Led (0 = On, 1 = Off) - Status + GPIO_ZIGBEE_TX, // GPIO01 Zigbee Serial control + 0, // GPIO02 + GPIO_ZIGBEE_RX, // GPIO03 Zigbee Serial control + GPIO_ZIGBEE_RST, // GPIO04 ZIgbee Reset + 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + 0, // GPIO09 (SD_DATA2 Flash QIO) + 0, // GPIO10 (SD_DATA3 Flash QIO) + // GPIO11 (SD_CMD Flash) + 0, + GPIO_LEDLNK_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link status + 0, 0, + GPIO_KEY1, // GPIO16 Button + 0 } }; From efbcb9b80e61cb8d5e0044bef0aa5f1a9e3713dd Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 23 Jul 2020 12:06:29 +0200 Subject: [PATCH 552/581] Create readme.txt --- tools/fw_zbbridge/readme.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tools/fw_zbbridge/readme.txt diff --git a/tools/fw_zbbridge/readme.txt b/tools/fw_zbbridge/readme.txt new file mode 100644 index 000000000..38049cf62 --- /dev/null +++ b/tools/fw_zbbridge/readme.txt @@ -0,0 +1,2 @@ +The ncp-uart-sw_6.7.6_115200.ota is for EZSP v8 compatible hosts +The ncp-uart-sw_6.5.5_115200.ota its for older like current ZHA From 0c743e0901c95e06634b297963812e2054426f25 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 23 Jul 2020 12:08:32 +0200 Subject: [PATCH 553/581] EFR32 firmware for ZigbeeBridge --- tools/fw_zbbridge/ncp-uart-sw_6.5.5_115200.ota | Bin 0 -> 181500 bytes tools/fw_zbbridge/ncp-uart-sw_6.7.6_115200.ota | Bin 0 -> 190272 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tools/fw_zbbridge/ncp-uart-sw_6.5.5_115200.ota create mode 100644 tools/fw_zbbridge/ncp-uart-sw_6.7.6_115200.ota diff --git a/tools/fw_zbbridge/ncp-uart-sw_6.5.5_115200.ota b/tools/fw_zbbridge/ncp-uart-sw_6.5.5_115200.ota new file mode 100644 index 0000000000000000000000000000000000000000..3655bf8a42d76ca880f5f6ebcaef7c72b184ca67 GIT binary patch literal 181500 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 literal 0 HcmV?d00001 diff --git a/tools/fw_zbbridge/ncp-uart-sw_6.7.6_115200.ota b/tools/fw_zbbridge/ncp-uart-sw_6.7.6_115200.ota new file mode 100644 index 0000000000000000000000000000000000000000..e8fed03b06138e10cf5598fe6e0e44c795a6e9c2 GIT binary patch literal 190272 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 A{uLxMMC$+9m%BkR6kUUjrA75Xq~d%p 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 R^RoN|1pEX5001FSu#OA>=HdVV literal 0 HcmV?d00001 From 85755ea3dc2956b7090e9d5ff8e3c74349b988c7 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 23 Jul 2020 12:43:56 +0200 Subject: [PATCH 554/581] Enforce correct module for ZBBridge --- tasmota/tasmota_configurations.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index ac0b629f2..99fec781f 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -417,6 +417,11 @@ #undef CODE_IMAGE_STR #define CODE_IMAGE_STR "zbbridge" +#undef MODULE +#define MODULE SONOFF_ZB_BRIDGE // [Module] Select default module from tasmota_template.h +#undef FALLBACK_MODULE +#define FALLBACK_MODULE SONOFF_ZB_BRIDGE // [Module2] Select default module on fast reboot where USER_MODULE is user template + #undef USE_ARDUINO_OTA // Disable support for Arduino OTA #define USE_DOMOTICZ // Disable Domoticz #undef USE_HOME_ASSISTANT // Disable Home Assistant From 85ccdda5691fbba5a7395ede5f056ec2873ac52d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 23 Jul 2020 13:06:07 +0200 Subject: [PATCH 555/581] Fix MPU6050 temperature Fix MPU6050 temperature (#8964) --- tasmota/xsns_32_mpu6050.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_32_mpu6050.ino b/tasmota/xsns_32_mpu6050.ino index 702d23224..c1f792ae7 100644 --- a/tasmota/xsns_32_mpu6050.ino +++ b/tasmota/xsns_32_mpu6050.ino @@ -181,7 +181,7 @@ void MPU_6050Show(bool json) { MPU_6050PerformReading(); - double tempConv = (MPU_6050_temperature / 340.0 + 35.53); + float tempConv = ConvertTemp(MPU_6050_temperature / 340.0 + 35.53); char temperature[33]; dtostrfd(tempConv, Settings.flag2.temperature_resolution, temperature); char axis_ax[33]; From 51b9740a5d4e18fd34876086b92e3625a3056a5b Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Thu, 23 Jul 2020 13:23:16 +0200 Subject: [PATCH 556/581] Add script usage flags --- tasmota/settings.h | 2 +- tasmota/xdrv_10_rules.ino | 5 +++++ tasmota/xdrv_10_scripter.ino | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 57aa35860..913309393 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -422,7 +422,7 @@ struct { uint8_t light_correction; // 49D uint8_t light_dimmer; // 49E uint8_t rule_enabled; // 49F - uint8_t rule_once; // 4A0 + uint8_t rule_once; // 4A0 bit 6+7 used by xdrv_10_scripter uint8_t light_fade; // 4A1 uint8_t light_speed; // 4A2 uint8_t light_scheme; // 4A3 diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 782116fc0..47c789935 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -791,6 +791,11 @@ bool RulesProcess(void) void RulesInit(void) { + // indicates scripter not enabled + bitWrite(Settings.rule_once, 7, 0); + // and indicates scripter do not use compress + bitWrite(Settings.rule_once, 6, 0); + rules_flag.data = 0; for (uint32_t i = 0; i < MAX_RULE_SETS; i++) { if (0 == GetRuleLen(i)) { diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 922e75ebc..19f24e1aa 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -6619,6 +6619,8 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_pram=(uint8_t*)Settings.script_pram[0]; glob_script_mem.script_pram_size=PMEM_SIZE; + // indicates scripter enabled (use rules[][] as single array) + bitWrite(Settings.rule_once, 7, 1); #ifdef USE_SCRIPT_COMPRESSION int32_t len_decompressed; sprt=(char*)calloc(UNISHOXRSIZE+8,1); @@ -6627,7 +6629,12 @@ bool Xdrv10(uint8_t function) glob_script_mem.script_size=UNISHOXRSIZE; len_decompressed = SCRIPT_DECOMPRESS(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, glob_script_mem.script_size); if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed]=0; + // indicates scripter use compression + bitWrite(Settings.rule_once, 6, 1); //AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); +#else // USE_SCRIPT_COMPRESSION + // indicates scripter does not use compression + bitWrite(Settings.rule_once, 6, 0); #endif // USE_SCRIPT_COMPRESSION #ifdef USE_BUTTON_EVENT From 5f386cc164e11d616a7238d5ad77109392bda3a7 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 23 Jul 2020 14:52:29 +0200 Subject: [PATCH 557/581] Fix MCP230xx telemetry JSON message Fix MCP230xx telemetry JSON message (#8965) --- tasmota/xsns_29_mcp230xx.ino | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/tasmota/xsns_29_mcp230xx.ino b/tasmota/xsns_29_mcp230xx.ino index 208fbcdd8..c2e160476 100644 --- a/tasmota/xsns_29_mcp230xx.ino +++ b/tasmota/xsns_29_mcp230xx.ino @@ -330,12 +330,33 @@ void MCP230xx_Show(bool json) if (json) { uint8_t gpio = MCP230xx_readGPIO(0); ResponseAppend_P(PSTR(",\"MCP230XX\":{\"D0\":%i,\"D1\":%i,\"D2\":%i,\"D3\":%i,\"D4\":%i,\"D5\":%i,\"D6\":%i,\"D7\":%i"), - (gpio>>0)&1,(gpio>>1)&1,(gpio>>2)&1,(gpio>>3)&1,(gpio>>4)&1,(gpio>>5)&1,(gpio>>6)&1,(gpio>>7)&1); + (gpio>>0)&1, (gpio>>1)&1, (gpio>>2)&1, (gpio>>3)&1, (gpio>>4)&1, (gpio>>5)&1, (gpio>>6)&1, (gpio>>7)&1); + uint8_t gpiob = 0; if (2 == mcp230xx_type) { - gpio = MCP230xx_readGPIO(1); + gpiob = MCP230xx_readGPIO(1); ResponseAppend_P(PSTR(",\"D8\":%i,\"D9\":%i,\"D10\":%i,\"D11\":%i,\"D12\":%i,\"D13\":%i,\"D14\":%i,\"D15\":%i"), - (gpio>>0)&1,(gpio>>1)&1,(gpio>>2)&1,(gpio>>3)&1,(gpio>>4)&1,(gpio>>5)&1,(gpio>>6)&1,(gpio>>7)&1); + (gpiob>>0)&1, (gpiob>>1)&1, (gpiob>>2)&1, (gpiob>>3)&1, (gpiob>>4)&1, (gpiob>>5)&1, (gpiob>>6)&1, (gpiob>>7)&1); } + +#ifdef USE_MCP230xx_OUTPUT + uint8_t outputcount = 0; + for (uint32_t pinx = 0; pinx < mcp230xx_pincount; pinx++) { + if (Settings.mcp230xx_config[pinx].pinmode >= 5) { outputcount++; } + } + if (outputcount) { + uint16_t gpiototal = ((uint16_t)gpiob << 8) | gpio; + ResponseAppend_P(PSTR(",\"MCP230_OUT\":{")); + char stt[7]; + for (uint32_t pinx = 0; pinx < mcp230xx_pincount; pinx++) { + if (Settings.mcp230xx_config[pinx].pinmode >= 5) { + sprintf(stt, ConvertNumTxt(((gpiototal>>pinx)&1), Settings.mcp230xx_config[pinx].pinmode)); + ResponseAppend_P(PSTR("\"OUT_D%i\":\"%s\","), pinx, stt); + } + } + ResponseAppend_P(PSTR("\"END\":1}")); + } +#endif // USE_MCP230xx_OUTPUT + ResponseJsonEnd(); } } @@ -714,6 +735,7 @@ void MCP230xx_UpdateWebData(void) #endif // USE_MCP230xx_DISPLAYOUTPUT +/* #ifdef USE_MCP230xx_OUTPUT void MCP230xx_OutputTelemetry(void) @@ -743,6 +765,7 @@ void MCP230xx_OutputTelemetry(void) } #endif // USE_MCP230xx_OUTPUT +*/ void MCP230xx_Interrupt_Counter_Report(void) { ResponseTime_P(PSTR(",\"MCP230_INTTIMER\":{")); @@ -806,9 +829,11 @@ bool Xsns29(uint8_t function) if (mcp230xx_int_retainer_en) { // We have pins configured for interrupt retain reporting MCP230xx_Interrupt_Retain_Report(); } +/* #ifdef USE_MCP230xx_OUTPUT MCP230xx_OutputTelemetry(); #endif // USE_MCP230xx_OUTPUT +*/ } break; case FUNC_JSON_APPEND: From 8883ad4c29fd0ddc30abb3f9dff2f5e928f832fb Mon Sep 17 00:00:00 2001 From: bovirus <1262554+bovirus@users.noreply.github.com> Date: Fri, 24 Jul 2020 06:38:44 +0200 Subject: [PATCH 558/581] Update Italian language --- tasmota/language/it_IT.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 4f74a9477..c45dc094f 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -1,7 +1,7 @@ /* it-IT.h - localization for Italian - Italy for Tasmota - Copyright (C) 2020 Gennaro Tortone - some mods by Antonio Fragola + Copyright (C) 2020 Gennaro Tortone - some mods by Antonio Fragola - rev. 24.07.2020 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 @@ -625,7 +625,7 @@ #define D_SENSOR_HJL_CF "BL0937 - CF" #define D_SENSOR_MCP39F5_TX "MCP39F5 - TX" #define D_SENSOR_MCP39F5_RX "MCP39F5 - RX" -#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" +#define D_SENSOR_MCP39F5_RST "MCP39F5 - Reset" #define D_SENSOR_CSE7766_TX "CSE7766 - TX" #define D_SENSOR_CSE7766_RX "CSE7766 - RX" #define D_SENSOR_PN532_TX "PN532 - TX" @@ -644,10 +644,10 @@ #define D_SENSOR_HRE_DATA "HRE - Dati" #define D_SENSOR_ADE7953_IRQ "ADE7953 - IRQ" #define D_SENSOR_BUZZER "Cicalino" -#define D_SENSOR_OLED_RESET "Ripristino OLED" +#define D_SENSOR_OLED_RESET "OLED - Reset" #define D_SENSOR_ZIGBEE_TXD "Zigbee - TX" #define D_SENSOR_ZIGBEE_RXD "Zigbee - RX" -#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" +#define D_SENSOR_ZIGBEE_RST "Zigbee - Reset" #define D_SENSOR_SOLAXX1_TX "SolaxX1 - TX" #define D_SENSOR_SOLAXX1_RX "SolaxX1- RX" #define D_SENSOR_IBEACON_TX "iBeacon - TX" @@ -801,7 +801,7 @@ #define D_AS3935_DISTANCE "distanza:" #define D_AS3935_DISTURBER "disturbatore:" #define D_AS3935_VRMS "µVrms:" -#define D_AS3935_APRX "apross.:" +#define D_AS3935_APRX "appross.:" #define D_AS3935_AWAY "lontano" #define D_AS3935_LIGHT "illuminazione" #define D_AS3935_OUT "illuminazione fuori intervallo" From 959a8bb2347cf4e9ae41f5e73f44e8f17a2fe856 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Fri, 24 Jul 2020 12:17:19 +0200 Subject: [PATCH 559/581] disable serial log and enable I2C --- tasmota/tasmota_configurations.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 99fec781f..da1248f6e 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -422,6 +422,9 @@ #undef FALLBACK_MODULE #define FALLBACK_MODULE SONOFF_ZB_BRIDGE // [Module2] Select default module on fast reboot where USER_MODULE is user template +#undef SERIAL_LOG_LEVEL +#define SERIAL_LOG_LEVEL LOG_LEVEL_NONE // [SerialLog] (LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE) + #undef USE_ARDUINO_OTA // Disable support for Arduino OTA #define USE_DOMOTICZ // Disable Domoticz #undef USE_HOME_ASSISTANT // Disable Home Assistant @@ -474,7 +477,7 @@ #undef USE_COUNTER // Disable counters #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices #undef USE_DS18x20 // Disable DS18x20 sensor -#undef USE_I2C // Disable all I2C sensors and devices +//#undef USE_I2C // Enable I2C, zbbridge uses i2c EEprom #undef USE_SPI // Disable all SPI devices #undef USE_DISPLAY // Disable Display support #undef USE_MHZ19 // Disable support for MH-Z19 CO2 sensor @@ -497,6 +500,7 @@ #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_ENERGY_SENSOR // Disable energy sensors +#undef USE_ADE7953 // Disable ADE7953 Energy monitor as used on Shelly 2.5 (I2C address 0x38) (+1k5) #undef USE_PZEM004T // Disable PZEM004T energy sensor #undef USE_PZEM_AC // Disable PZEM014,016 Energy monitor #undef USE_PZEM_DC // Disable PZEM003,017 Energy monitor From 3acae81fc0ed5081330aa6454ce0b59e3e11356c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 24 Jul 2020 15:30:21 +0200 Subject: [PATCH 560/581] Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` - Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` - Add command ``DzSend ,`` to send values or state to Domoticz --- RELEASENOTES.md | 2 + tasmota/CHANGELOG.md | 2 + tasmota/xdrv_07_domoticz.ino | 157 +++++++++++++++++++---------------- 3 files changed, 91 insertions(+), 70 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 490280e79..e2170880c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -64,6 +64,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT - Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` - Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message +- Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` - Fix escape of non-JSON received serial data (#8329) - Fix exception or watchdog on rule re-entry (#8757) - Add command ``Rule0`` to change global rule parameters @@ -74,6 +75,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``SetOption99 0/1`` to enable zero cross detection on PWM dimmer - Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 +- Add command ``DzSend ,`` to send values or state to Domoticz - Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add command (``S``)``SerialSend6`` \ (#8937) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 31231a6ad..d30040e93 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -5,6 +5,8 @@ - Remove Arduino ESP8266 Core support for versions before 2.7.1 - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE - Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message +- Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` +- Add command ``DzSend ,`` to send values or state to Domoticz - Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 - Add command (``S``)``SerialSend6`` \ (#8937) diff --git a/tasmota/xdrv_07_domoticz.ino b/tasmota/xdrv_07_domoticz.ino index 556997bb9..4f26a2c8a 100644 --- a/tasmota/xdrv_07_domoticz.ino +++ b/tasmota/xdrv_07_domoticz.ino @@ -21,18 +21,20 @@ #define XDRV_07 7 -#define D_PRFX_DOMOTICZ "Domoticz" +//#define D_PRFX_DOMOTICZ "Domoticz" +#define D_PRFX_DOMOTICZ "Dz" #define D_CMND_IDX "Idx" #define D_CMND_KEYIDX "KeyIdx" #define D_CMND_SWITCHIDX "SwitchIdx" #define D_CMND_SENSORIDX "SensorIdx" #define D_CMND_UPDATETIMER "UpdateTimer" +#define D_CMND_DZSEND "Send" const char kDomoticzCommands[] PROGMEM = D_PRFX_DOMOTICZ "|" // Prefix - D_CMND_IDX "|" D_CMND_KEYIDX "|" D_CMND_SWITCHIDX "|" D_CMND_SENSORIDX "|" D_CMND_UPDATETIMER ; + D_CMND_IDX "|" D_CMND_KEYIDX "|" D_CMND_SWITCHIDX "|" D_CMND_SENSORIDX "|" D_CMND_UPDATETIMER "|" D_CMND_DZSEND ; void (* const DomoticzCommand[])(void) PROGMEM = { - &CmndDomoticzIdx, &CmndDomoticzKeyIdx, &CmndDomoticzSwitchIdx, &CmndDomoticzSensorIdx, &CmndDomoticzUpdateTimer }; + &CmndDomoticzIdx, &CmndDomoticzKeyIdx, &CmndDomoticzSwitchIdx, &CmndDomoticzSensorIdx, &CmndDomoticzUpdateTimer, &CmndDomoticzSend }; const char DOMOTICZ_MESSAGE[] PROGMEM = "{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%s\",\"Battery\":%d,\"RSSI\":%d}"; @@ -44,6 +46,8 @@ const char kDomoticzSensors[] PROGMEM = D_DOMOTICZ_TEMP "|" D_DOMOTICZ_TEMP_HUM "|" D_DOMOTICZ_TEMP_HUM_BARO "|" D_DOMOTICZ_POWER_ENERGY "|" D_DOMOTICZ_ILLUMINANCE "|" D_DOMOTICZ_COUNT "|" D_DOMOTICZ_VOLTAGE "|" D_DOMOTICZ_CURRENT "|" D_DOMOTICZ_AIRQUALITY "|" D_DOMOTICZ_P1_SMART_METER "|" D_DOMOTICZ_SHUTTER ; +const char kDomoticzCommand[] PROGMEM = "switchlight|switchscene"; + char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC; int domoticz_update_timer = 0; @@ -55,8 +59,7 @@ bool domoticz_update_flag = true; bool domoticz_is_shutter = false; #endif // USE_SHUTTER -int DomoticzBatteryQuality(void) -{ +int DomoticzBatteryQuality(void) { // 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) @@ -76,16 +79,14 @@ int DomoticzBatteryQuality(void) return quality; } -int DomoticzRssiQuality(void) -{ +int DomoticzRssiQuality(void) { // RSSI range: 0% to 10% (12 means disable RSSI in Domoticz) return WifiGetRssiAsQuality(WiFi.RSSI()) / 10; } #ifdef USE_SONOFF_IFAN -void MqttPublishDomoticzFanState(void) -{ +void MqttPublishDomoticzFanState(void) { if (Settings.flag.mqtt_enabled && Settings.domoticz_relay_idx[1]) { // SetOption3 - Enable MQTT char svalue[8]; // Fanspeed value @@ -98,8 +99,7 @@ void MqttPublishDomoticzFanState(void) } } -void DomoticzUpdateFanState(void) -{ +void DomoticzUpdateFanState(void) { if (domoticz_update_flag) { MqttPublishDomoticzFanState(); } @@ -107,8 +107,7 @@ void DomoticzUpdateFanState(void) } #endif // USE_SONOFF_IFAN -void MqttPublishDomoticzPowerState(uint8_t device) -{ +void MqttPublishDomoticzPowerState(uint8_t device) { if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT if (device < 1) { device = 1; } if ((device > devices_present) || (device > MAX_DOMOTICZ_IDX)) { return; } @@ -138,16 +137,14 @@ void MqttPublishDomoticzPowerState(uint8_t device) } } -void DomoticzUpdatePowerState(uint8_t device) -{ +void DomoticzUpdatePowerState(uint8_t device) { if (domoticz_update_flag) { MqttPublishDomoticzPowerState(device); } domoticz_update_flag = true; } -void DomoticzMqttUpdate(void) -{ +void DomoticzMqttUpdate(void) { if (domoticz_subscribe && (Settings.domoticz_update_timer || domoticz_update_timer)) { domoticz_update_timer--; if (domoticz_update_timer <= 0) { @@ -175,8 +172,7 @@ void DomoticzMqttUpdate(void) } } -void DomoticzMqttSubscribe(void) -{ +void DomoticzMqttSubscribe(void) { uint8_t maxdev = (devices_present > MAX_DOMOTICZ_IDX) ? MAX_DOMOTICZ_IDX : devices_present; for (uint32_t i = 0; i < maxdev; i++) { if (Settings.domoticz_relay_idx[i]) { @@ -217,8 +213,7 @@ void DomoticzMqttSubscribe(void) } */ -bool DomoticzMqttData(void) -{ +bool DomoticzMqttData(void) { domoticz_update_flag = true; if (strncasecmp_P(XdrvMailbox.topic, PSTR(DOMOTICZ_OUT_TOPIC), strlen(DOMOTICZ_OUT_TOPIC)) != 0) { @@ -359,15 +354,19 @@ bool DomoticzMqttData(void) /*********************************************************************************************/ -bool DomoticzSendKey(uint8_t key, uint8_t device, uint8_t state, uint8_t svalflg) -{ +void DomoticzSendSwitch(uint32_t type, uint32_t index, uint32_t state) { + char stemp[16]; // "switchlight" or "switchscene" + Response_P(PSTR("{\"command\":\"%s\",\"idx\":%d,\"switchcmd\":\"%s\"}"), + GetTextIndexed(stemp, sizeof(stemp), type, kDomoticzCommand), index, (state) ? (POWER_TOGGLE == state) ? "Toggle" : "On" : "Off"); // Domoticz case sensitive + MqttPublish(domoticz_in_topic); +} + +bool DomoticzSendKey(uint8_t key, uint8_t device, uint8_t state, uint8_t svalflg) { bool result = false; if (device <= MAX_DOMOTICZ_IDX) { if ((Settings.domoticz_key_idx[device -1] || Settings.domoticz_switch_idx[device -1]) && (svalflg)) { - Response_P(PSTR("{\"command\":\"switchlight\",\"idx\":%d,\"switchcmd\":\"%s\"}"), - (key) ? Settings.domoticz_switch_idx[device -1] : Settings.domoticz_key_idx[device -1], (state) ? (POWER_TOGGLE == state) ? "Toggle" : "On" : "Off"); - MqttPublish(domoticz_in_topic); + DomoticzSendSwitch(0, (key) ? Settings.domoticz_switch_idx[device -1] : Settings.domoticz_key_idx[device -1], state); result = true; } } @@ -391,46 +390,46 @@ bool DomoticzSendKey(uint8_t key, uint8_t device, uint8_t state, uint8_t svalflg * \*********************************************************************************************/ -uint8_t DomoticzHumidityState(float h) -{ - return (!h) ? 0 : (h < 40) ? 2 : (h > 70) ? 3 : 1; +void DomoticzSendData(uint32_t sensor_idx, uint32_t idx, char *data) { + if (DZ_AIRQUALITY == sensor_idx) { + Response_P(PSTR("{\"idx\":%d,\"nvalue\":%s,\"Battery\":%d,\"RSSI\":%d}"), + idx, data, DomoticzBatteryQuality(), DomoticzRssiQuality()); + } else { + uint8_t nvalue = 0; +#ifdef USE_SHUTTER + if (DZ_SHUTTER == sensor_idx) { + uint8_t position = atoi(data); + nvalue = position < 2 ? 0 : (position == 100 ? 1 : 2); + } +#endif // USE_SHUTTER + Response_P(DOMOTICZ_MESSAGE, + idx, nvalue, data, DomoticzBatteryQuality(), DomoticzRssiQuality()); + } + MqttPublish(domoticz_in_topic); } -void DomoticzSensor(uint8_t idx, char *data) -{ +void DomoticzSensor(uint8_t idx, char *data) { if (Settings.domoticz_sensor_idx[idx]) { char dmess[128]; // {"idx":26700,"nvalue":0,"svalue":"22330.1;10234.4;22000.5;10243.4;1006;3000","Battery":100,"RSSI":10} memcpy(dmess, mqtt_data, sizeof(dmess)); - if (DZ_AIRQUALITY == idx) { - Response_P(PSTR("{\"idx\":%d,\"nvalue\":%s,\"Battery\":%d,\"RSSI\":%d}"), - Settings.domoticz_sensor_idx[idx], data, DomoticzBatteryQuality(), DomoticzRssiQuality()); - } else { - uint8_t nvalue = 0; -#ifdef USE_SHUTTER - if (DZ_SHUTTER == idx) { - uint8_t position = atoi(data); - nvalue = position < 2 ? 0 : (position == 100 ? 1 : 2); - } -#endif // USE_SHUTTER - Response_P(DOMOTICZ_MESSAGE, - Settings.domoticz_sensor_idx[idx], nvalue, data, DomoticzBatteryQuality(), DomoticzRssiQuality()); - } - MqttPublish(domoticz_in_topic); + DomoticzSendData(idx, Settings.domoticz_sensor_idx[idx], data); memcpy(mqtt_data, dmess, sizeof(dmess)); } } -void DomoticzSensor(uint8_t idx, uint32_t value) -{ +uint8_t DomoticzHumidityState(float h) { + return (!h) ? 0 : (h < 40) ? 2 : (h > 70) ? 3 : 1; +} + +void DomoticzSensor(uint8_t idx, uint32_t value) { char data[16]; snprintf_P(data, sizeof(data), PSTR("%d"), value); DomoticzSensor(idx, data); } //void DomoticzTempHumPressureSensor(float temp, float hum, float baro = -1); -void DomoticzTempHumPressureSensor(float temp, float hum, float baro) -{ +void DomoticzTempHumPressureSensor(float temp, float hum, float baro) { char temperature[FLOATSZ]; dtostrfd(temp, 2, temperature); char humidity[FLOATSZ]; @@ -449,15 +448,13 @@ void DomoticzTempHumPressureSensor(float temp, float hum, float baro) } } -void DomoticzSensorPowerEnergy(int power, char *energy) -{ +void DomoticzSensorPowerEnergy(int power, char *energy) { char data[16]; snprintf_P(data, sizeof(data), PSTR("%d;%s"), power, energy); DomoticzSensor(DZ_POWER_ENERGY, data); } -void DomoticzSensorP1SmartMeter(char *usage1, char *usage2, char *return1, char *return2, int power) -{ +void DomoticzSensorP1SmartMeter(char *usage1, char *usage2, char *return1, char *return2, int power) { //usage1 = energy usage meter tariff 1, This is an incrementing counter //usage2 = energy usage meter tariff 2, This is an incrementing counter //return1 = energy return meter tariff 1, This is an incrementing counter @@ -478,8 +475,7 @@ void DomoticzSensorP1SmartMeter(char *usage1, char *usage2, char *return1, char * Commands \*********************************************************************************************/ -void CmndDomoticzIdx(void) -{ +void CmndDomoticzIdx(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) { if (XdrvMailbox.payload >= 0) { Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload; @@ -489,8 +485,7 @@ void CmndDomoticzIdx(void) } } -void CmndDomoticzKeyIdx(void) -{ +void CmndDomoticzKeyIdx(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) { if (XdrvMailbox.payload >= 0) { Settings.domoticz_key_idx[XdrvMailbox.index -1] = XdrvMailbox.payload; @@ -499,8 +494,7 @@ void CmndDomoticzKeyIdx(void) } } -void CmndDomoticzSwitchIdx(void) -{ +void CmndDomoticzSwitchIdx(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) { if (XdrvMailbox.payload >= 0) { Settings.domoticz_switch_idx[XdrvMailbox.index -1] = XdrvMailbox.payload; @@ -509,8 +503,7 @@ void CmndDomoticzSwitchIdx(void) } } -void CmndDomoticzSensorIdx(void) -{ +void CmndDomoticzSensorIdx(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= DZ_MAX_SENSORS)) { if (XdrvMailbox.payload >= 0) { Settings.domoticz_sensor_idx[XdrvMailbox.index -1] = XdrvMailbox.payload; @@ -519,14 +512,41 @@ void CmndDomoticzSensorIdx(void) } } -void CmndDomoticzUpdateTimer(void) -{ +void CmndDomoticzUpdateTimer(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { Settings.domoticz_update_timer = XdrvMailbox.payload; } ResponseCmndNumber(Settings.domoticz_update_timer); } +void CmndDomoticzSend(void) { + // DzSend1 , - {\"idx\":,\"nvalue\":0,\"svalue\":\"\",\"Battery\":xx,\"RSSI\":yy} + // DzSend2 , - USE_SHUTTER only - {\"idx\":,\"nvalue\":,\"svalue\":\"\",\"Battery\":xx,\"RSSI\":yy} + // DzSend3 , - {\"idx\":,\"nvalue\":,\"Battery\":xx,\"RSSI\":yy} + // DzSend4 , - {\"command\":\"switchlight\",\"idx\":,\"switchcmd\":\"\"} + // DzSend5 , - {\"command\":\"switchscene\",\"idx\":,\"switchcmd\":\"\"} + + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 5)) { + if (XdrvMailbox.data_len > 0) { + if (strstr(XdrvMailbox.data, ",") != nullptr) { // Process parameter entry + char *data; + uint32_t index = strtoul(strtok_r(XdrvMailbox.data, ",", &data), nullptr, 10); + if ((index > 0) && (data != nullptr)) { + if (XdrvMailbox.index > 3) { + uint32_t state = strtoul(data, nullptr, 10); // 0, 1 or 2 + DomoticzSendSwitch(XdrvMailbox.index -4, index, state); + } else { + uint32_t type = DZ_TEMP; + if (2 == XdrvMailbox.index) { type = DZ_SHUTTER; } + else if (3 == XdrvMailbox.index) { type = DZ_AIRQUALITY; } + DomoticzSendData(type, index, data); + } + } + } + } + } +} + /*********************************************************************************************\ * Presentation \*********************************************************************************************/ @@ -554,8 +574,7 @@ const char HTTP_FORM_DOMOTICZ_SENSOR[] PROGMEM = const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM = "" D_DOMOTICZ_UPDATE_TIMER " (" STR(DOMOTICZ_UPDATE_TIMER) ")"; -void HandleDomoticzConfiguration(void) -{ +void HandleDomoticzConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_DOMOTICZ); @@ -596,8 +615,7 @@ void HandleDomoticzConfiguration(void) WSContentStop(); } -void DomoticzSaveSettings(void) -{ +void DomoticzSaveSettings(void) { char stemp[20]; char ssensor_indices[6 * MAX_DOMOTICZ_SNS_IDX]; char tmp[100]; @@ -635,8 +653,7 @@ void DomoticzSaveSettings(void) * Interface \*********************************************************************************************/ -bool Xdrv07(uint8_t function) -{ +bool Xdrv07(uint8_t function) { bool result = false; if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT From 0467ffc62a2e33a69408d66b9ce0bdb61f0d56a8 Mon Sep 17 00:00:00 2001 From: bettman66 Date: Sat, 25 Jul 2020 09:21:56 +0200 Subject: [PATCH 561/581] millennium error --- tasmota/xdrv_16_tuyamcu.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 82bc4ef7f..a01881ac1 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -808,7 +808,7 @@ void TuyaSetTime(void) { uint16_t payload_len = 8; uint8_t payload_buffer[8]; payload_buffer[0] = 0x01; - payload_buffer[1] = (uint8_t)RtcTime.year; + payload_buffer[1] = RtcTime.year - 2000; payload_buffer[2] = RtcTime.month; payload_buffer[3] = RtcTime.day_of_month; payload_buffer[4] = RtcTime.hour; From 38179062aed0e8fe3a2224079790aba5c574f0d5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 25 Jul 2020 14:52:37 +0200 Subject: [PATCH 562/581] Refactor TuyaMcu year --- tasmota/xdrv_16_tuyamcu.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index a01881ac1..b4b9a5ff4 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -808,7 +808,7 @@ void TuyaSetTime(void) { uint16_t payload_len = 8; uint8_t payload_buffer[8]; payload_buffer[0] = 0x01; - payload_buffer[1] = RtcTime.year - 2000; + payload_buffer[1] = RtcTime.year %100; payload_buffer[2] = RtcTime.month; payload_buffer[3] = RtcTime.day_of_month; payload_buffer[4] = RtcTime.hour; From 781cb4d9c77744bccd58ef9a6380766235ea5b3c Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 25 Jul 2020 15:40:42 +0200 Subject: [PATCH 563/581] Zigbee EZSP improvements and reduced logging --- tasmota/i18n.h | 2 + tasmota/tasmota_template.h | 11 +- tasmota/xdrv_23_zigbee_0_constants.ino | 6 -- tasmota/xdrv_23_zigbee_7_statemachine.ino | 2 +- tasmota/xdrv_23_zigbee_8_parsers.ino | 117 ++++++++++++++++++++++ tasmota/xdrv_23_zigbee_9_serial.ino | 57 +++++++---- 6 files changed, 162 insertions(+), 33 deletions(-) diff --git a/tasmota/i18n.h b/tasmota/i18n.h index a91ede963..6b97badd5 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -514,6 +514,7 @@ #define D_CMND_ZIGBEE_EZSP_SEND "EZSPSend" #define D_CMND_ZIGBEE_EZSP_SEND_RAW "EZSPSendRaw" #define D_JSON_ZIGBEE_STATE "ZbState" + #define D_JSON_ZIGBEE_ROUTE_ERROR "ZbRouteError" #define D_JSON_ZIGBEEZNPRECEIVED "ZbZNPReceived" #define D_JSON_ZIGBEE_EZSP_RECEIVED "ZbEZSPReceived" #define D_JSON_ZIGBEEZNPSENT "ZbZNPSent" @@ -549,6 +550,7 @@ #define D_JSON_ZIGBEE_UNBIND "ZbUnbind" #define D_CMND_ZIGBEE_BIND_STATE "BindState" #define D_JSON_ZIGBEE_BIND_STATE "ZbBindState" +#define D_JSON_ZIGBEE_PARENT "ZbParent" #define D_CMND_ZIGBEE_PING "Ping" #define D_JSON_ZIGBEE_PING "ZbPing" #define D_JSON_ZIGBEE_IEEE "IEEEAddr" diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 8c62a236b..1c38f0420 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -2283,21 +2283,22 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { 0, 0, 0, 0 }, { // SONOFF_ZB_BRIDGE - Sonoff Zigbee Bridge (ESP8266) - GPIO_LED1_INV, // GPIO00 Led (0 = On, 1 = Off) - Status + GPIO_LED1_INV, // GPIO00 Green Led (0 = On, 1 = Off) - Traffic between ESP and EFR GPIO_ZIGBEE_TX, // GPIO01 Zigbee Serial control 0, // GPIO02 GPIO_ZIGBEE_RX, // GPIO03 Zigbee Serial control - GPIO_ZIGBEE_RST, // GPIO04 ZIgbee Reset - 0, + GPIO_ZIGBEE_RST, // GPIO04 Zigbee Reset + 0, // GPIO05 EFR32 Bootloader mode (drive Low for Gecko Bootloader, inactive or high for Zigbee EmberZNet) // GPIO06 (SD_CLK Flash) // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) 0, // GPIO09 (SD_DATA2 Flash QIO) 0, // GPIO10 (SD_DATA3 Flash QIO) // GPIO11 (SD_CMD Flash) - 0, + GPIO_I2C_SDA, // GPIO12 I2C SDA - connected to 512KB EEPROM GPIO_LEDLNK_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link status - 0, 0, + GPIO_I2C_SCL, // GPIO14 I2C SCL - connected to 512KB EEPROM + 0, // GPIO15 connected to IO15 pad, also used for logging GPIO_KEY1, // GPIO16 Button 0 } diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index ea087e70f..c24e5c091 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -1105,12 +1105,6 @@ enum ZCL_Global_Commands { #define ZF(s) static const char ZS_ ## s[] PROGMEM = #s; #define Z(s) ZS_ ## s -typedef struct Z_StatusLine { - uint32_t status; // no need to use uint8_t since it uses 32 bits anyways - const char * status_msg; -} Z_StatusLine; - - // ZDP Enumeration, see Zigbee spec 2.4.5 String getZDPStatusMessage(uint8_t status) { static const char StatusMsg[] PROGMEM = "SUCCESS|INV_REQUESTTYPE|DEVICE_NOT_FOUND|INVALID_EP|NOT_ACTIVE|NOT_SUPPORTED" diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index f04c0ca34..f46b34f7c 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -710,7 +710,7 @@ ZBM(ZBS_SET_POLICY_02, EZSP_setPolicy, 0x00 /*high*/, EZSP_UNICAST_REPLIES_PO ZBM(ZBS_SET_POLICY_03, EZSP_setPolicy, 0x00 /*high*/, EZSP_POLL_HANDLER_POLICY, EZSP_POLL_HANDLER_IGNORE) // 55000330 ZBM(ZBS_SET_POLICY_04, EZSP_setPolicy, 0x00 /*high*/, EZSP_MESSAGE_CONTENTS_IN_CALLBACK_POLICY, - EZSP_MESSAGE_TAG_AND_CONTENTS_IN_CALLBACK) // 55000441 + EZSP_MESSAGE_TAG_ONLY_IN_CALLBACK) // 55000440 ZBM(ZBS_SET_POLICY_05, EZSP_setPolicy, 0x00 /*high*/, EZSP_TC_KEY_REQUEST_POLICY, EZSP_ALLOW_TC_KEY_REQUESTS_AND_SEND_CURRENT_KEY) // 55000551 ZBM(ZBS_SET_POLICY_06, EZSP_setPolicy, 0x00 /*high*/, EZSP_APP_KEY_REQUEST_POLICY, diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 58d4e330b..7f1c98e0a 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -115,6 +115,43 @@ int32_t EZ_NetworkParameters(int32_t res, class SBuffer &buf) { return res; } +// +// Handle a "incomingRouteErrorHandler" incoming message +// +int32_t EZ_RouteError(int32_t res, const class SBuffer &buf) { + uint8_t status = buf.get8(2); + uint16_t shortaddr = buf.get16(3); + + Response_P(PSTR("{\"" D_JSON_ZIGBEE_ROUTE_ERROR "\":{" + "\"ShortAddr\":\"0x%04X\",\"" D_JSON_ZIGBEE_STATUS "\":%d,\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"0x%s\"}}"), + shortaddr, status, ""); + + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + + return -1; +} + +// +// Handle a "permitJoining" incoming message +// +int32_t EZ_PermitJoinRsp(int32_t res, const class SBuffer &buf) { + uint8_t status = buf.get8(2); + + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"Message\":\"%s"), + (0 == status) ? ZIGBEE_STATUS_PERMITJOIN_OPEN_60 : ZIGBEE_STATUS_PERMITJOIN_CLOSE, + (0 == status) ? PSTR("Pairing mode enabled") : PSTR("Pairing mode error") + ); + if (status) { + ResponseAppend_P("0x%02X", status); + } + ResponseAppend_P(PSTR("\"}}")); + + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + + return -1; +} + #endif // USE_ZIGBEE_EZSP /*********************************************************************************************\ @@ -785,6 +822,72 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { return -1; } +// +// Handle Parent Annonce Rsp incoming message +// +// rsp: true = ZDO_Parent_annce_rsp, false = ZDO_Parent_annce +int32_t Z_ParentAnnceRsp(int32_t res, const class SBuffer &buf, bool rsp) { +#ifdef USE_ZIGBEE_ZNP +// uint16_t shortaddr = buf.get16(2); +// uint8_t status = buf.get8(4); +// uint8_t bind_total = buf.get8(5); +// uint8_t bind_start = buf.get8(6); +// uint8_t bind_len = buf.get8(7); +// const size_t prefix_len = 8; +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + size_t prefix_len; + uint8_t status; + uint8_t num_children; + uint16_t shortaddr = buf.get16(buf.len()-2); + if (rsp) { + status = buf.get8(0); + num_children = buf.get8(1); + prefix_len = 2; + } else { + status = 0; + num_children = buf.get8(0); + prefix_len = 1; + } +#endif // USE_ZIGBEE_EZSP + + const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr); + + Response_P(PSTR("{\"" D_JSON_ZIGBEE_PARENT "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""), shortaddr); + if (friendlyName) { + ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName); + } + if (rsp) { + ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d" + ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" + ), status, getZigbeeStatusMessage(status).c_str()); + } + ResponseAppend_P(PSTR(",\"Children\":%d" + ",\"ChildInfo\":[" + ), num_children); + + uint32_t idx = prefix_len; + for (uint32_t i = 0; i < num_children; i++) { + if (idx + 8 > buf.len()) { break; } // overflow, frame size is between 14 and 21 + + uint64_t child_ieee = buf.get64(idx); + idx += 8; + + if (i > 0) { + ResponseAppend_P(PSTR(",")); + } + char hex[20]; + Uint64toHex(child_ieee, hex, 64); + ResponseAppend_P(PSTR("\"0x%s\""), hex); + } + + ResponseAppend_P(PSTR("]}}")); + + MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_BIND_STATE)); + + return -1; +} + /*********************************************************************************************\ * Send specific ZNP messages \*********************************************************************************************/ @@ -1051,6 +1154,14 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { return Z_UnbindRsp(res, zdo_buf); case ZDO_Mgmt_Bind_rsp: return Z_MgmtBindRsp(res, zdo_buf); + case ZDO_Parent_annce: + return Z_ParentAnnceRsp(res, zdo_buf, false); + case ZDO_Parent_annce_rsp: + return Z_ParentAnnceRsp(res, zdo_buf, true); + default: + // TODO move later to LOG_LEVEL_DEBUG + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: Internal ZDO message 0x%04X sent from 0x%04X %s"), clusterid, srcaddr, wasbroadcast ? PSTR("(broadcast)") : ""); + break; } } else { bool defer_attributes = false; // do we defer attributes reporting to coalesce @@ -1106,6 +1217,12 @@ int32_t EZ_Recv_Default(int32_t res, const class SBuffer &buf) { case EZSP_trustCenterJoinHandler: return EZ_ReceiveTCJoinHandler(res, buf); break; + case EZSP_incomingRouteErrorHandler: + return EZ_RouteError(res, buf); + break; + case EZSP_permitJoining: + return EZ_PermitJoinRsp(res, buf); + break; } return -1; } diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index bfec8c3bb..1715d6763 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -118,7 +118,7 @@ void ZigbeeInputLoop(void) { char hex_char[(zigbee_buffer->len() * 2) + 2]; ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); + // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); // buffer received, now check integrity if (zigbee_buffer->len() != zigbee_frame_len) { // Len is not correct, log and reject frame @@ -163,7 +163,7 @@ void ZigbeeInputLoop(void) { yield(); uint8_t zigbee_in_byte = ZigbeeSerial->read(); - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len()); + // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len()); // if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized // escape = false; @@ -175,13 +175,13 @@ void ZigbeeInputLoop(void) { } if (ZIGBEE_EZSP_ESCAPE == zigbee_in_byte) { - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Escape byte received")); + // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Escape byte received")); escape = true; continue; } if (ZIGBEE_EZSP_CANCEL == zigbee_in_byte) { - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x1A, cancel byte received, discarding %d bytes"), zigbee_buffer->len()); + // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x1A, cancel byte received, discarding %d bytes"), zigbee_buffer->len()); zigbee_buffer->setLen(0); // empty buffer escape = false; frame_complete = false; @@ -215,7 +215,7 @@ void ZigbeeInputLoop(void) { char hex_char[frame_len * 2 + 2]; ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); + // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); if ((frame_complete) && (frame_len >= 3)) { // frame received and has at least 3 bytes (without EOF), checking CRC // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": received raw frame %s"), hex_char); @@ -253,12 +253,7 @@ void ZigbeeInputLoop(void) { } ToHex_P((unsigned char*)ezsp_buffer.getBuffer(), ezsp_buffer.len(), hex_char, sizeof(hex_char)); - Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "2\":\"%s\"}"), hex_char); - if (Settings.flag3.tuya_serial_mqtt_publish) { - MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR)); - } else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable - } + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "2\":\"%s\"}"), hex_char); // now process the message ZigbeeProcessInputRaw(ezsp_buffer); } @@ -491,7 +486,7 @@ void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { // Now send a MQTT message to report the sent message char hex_char[(len * 2) + 2]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT_RAW " %s"), + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT_RAW " %s"), ToHex_P(msg, len, hex_char, sizeof(hex_char))); } @@ -500,7 +495,7 @@ void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { void ZigbeeEZSPSendCmd(const uint8_t *msg, size_t len) { char hex_char[len*2 + 2]; ToHex_P(msg, len, hex_char, sizeof(hex_char)); - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZbEZSPSend %s"), hex_char); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "ZbEZSPSend %s"), hex_char); SBuffer cmd(len+3); // prefix with seq number (1 byte) and frame control bytes (2 bytes) @@ -517,7 +512,7 @@ void ZigbeeEZSPSendCmd(const uint8_t *msg, size_t len) { void ZigbeeEZSPSendDATA_frm(bool send_cancel, uint8_t to_frm, uint8_t from_ack) { SBuffer *buf = EZSP_Serial.to_packets[to_frm]; if (!buf) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Buffer for packet %d is not allocated"), EZSP_Serial.to_send); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Buffer for packet %d is not allocated"), EZSP_Serial.to_send); return; } @@ -534,7 +529,7 @@ void ZigbeeEZSPSendDATA(const uint8_t *msg, size_t len) { buf->add8(0x00); // placeholder for control_byte buf->addBuffer(msg, len); // - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: adding packet to_send, to_ack:%d, to_send:%d, to_end:%d"), + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: adding packet to_send, to_ack:%d, to_send:%d, to_end:%d"), EZSP_Serial.to_ack, EZSP_Serial.to_send, EZSP_Serial.to_end); uint8_t to_frm = EZSP_Serial.to_end; if (EZSP_Serial.to_packets[to_frm]) { @@ -579,7 +574,27 @@ int32_t ZigbeeProcessInputEZSP(class SBuffer &buf) { if (Settings.flag3.tuya_serial_mqtt_publish) { MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR)); } else { - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable + // demote less interesting messages to LOG_LEVEL_DEBUG + uint32_t log_level = LOG_LEVEL_INFO; + switch (buf.get16(0)) { + case EZSP_version: // 0000 + case EZSP_addEndpoint: // 0200 + case EZSP_setConcentrator: // 1000 + case EZSP_networkInit: // 1700 + case EZSP_stackStatusHandler: // 1900 + case EZSP_permitJoining: // 2200 + case EZSP_getEui64: // 2600 + case EZSP_getNodeId: // 2700 + case EZSP_sendUnicast: // 3400 + case EZSP_sendBroadcast: // 3600 + case EZSP_messageSentHandler: // 3F00 + case EZSP_setConfigurationValue: // 5300 + case EZSP_setPolicy: // 5500 + case EZSP_setMulticastTableEntry: // 6400 + log_level = LOG_LEVEL_DEBUG; + break; + } + AddLog_P2(log_level, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable } // Pass message to state machine @@ -589,14 +604,14 @@ int32_t ZigbeeProcessInputEZSP(class SBuffer &buf) { // Check if we advanced in the ACKed frames, and free from memory packets acknowledged void EZSP_HandleAck(uint8_t new_ack) { if (EZSP_Serial.to_ack != new_ack) { // new ack receveid - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: new ack/data received, was %d now %d"), EZSP_Serial.to_ack, new_ack); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: new ack/data received, was %d now %d"), EZSP_Serial.to_ack, new_ack); uint32_t i = EZSP_Serial.to_ack; do { if (EZSP_Serial.to_packets[i]) { delete EZSP_Serial.to_packets[i]; EZSP_Serial.to_packets[i] = nullptr; } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: freeing packet %d from memory"), i); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: freeing packet %d from memory"), i); i = (i + 1) & 0x07; } while (i != new_ack); EZSP_Serial.to_ack = new_ack; @@ -617,10 +632,10 @@ int32_t ZigbeeProcessInputRaw(class SBuffer &buf) { } else if (frame_type == 0xA0) { // NAK - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Received NAK %d, to_ack:%d, to_send:%d, to_end:%d"), + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Received NAK %d, to_ack:%d, to_send:%d, to_end:%d"), ack_num, EZSP_Serial.to_ack, EZSP_Serial.to_send, EZSP_Serial.to_end); EZSP_Serial.to_send = ack_num; - AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: NAK, resending packet %d"), ack_num); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: NAK, resending packet %d"), ack_num); } else if (control_byte == 0xC1) { // RSTACK @@ -844,7 +859,7 @@ void ZigbeeOutputLoop(void) { #ifdef USE_ZIGBEE_EZSP // while (EZSP_Serial.to_send != EZSP_Serial.to_end) { if (EZSP_Serial.to_send != EZSP_Serial.to_end) { // we send only one packet per tick to lower the chance of NAK - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Something to_send, to_ack:%d, to_send:%d, to_end:%d"), + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Something to_send, to_ack:%d, to_send:%d, to_end:%d"), EZSP_Serial.to_ack, EZSP_Serial.to_send, EZSP_Serial.to_end); // we have a frame waiting to be sent ZigbeeEZSPSendDATA_frm(true, EZSP_Serial.to_send, EZSP_Serial.from_ack); From 520558d3817b458ec9d8e3384eeafe0d9cd3c2d9 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 25 Jul 2020 17:08:11 +0200 Subject: [PATCH 564/581] Fix no sensor issue --- tasmota/xsns_interface.ino | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tasmota/xsns_interface.ino b/tasmota/xsns_interface.ino index b6abce101..0c85854de 100644 --- a/tasmota/xsns_interface.ino +++ b/tasmota/xsns_interface.ino @@ -868,6 +868,11 @@ void XsnsSensorState(void) bool XsnsNextCall(uint8_t Function, uint8_t &xsns_index) { + if (0 == xsns_present) { + xsns_index = 0; + return false; + } + xsns_index++; if (xsns_index == xsns_present) { xsns_index = 0; } From 806a862cac21ace0b6c77dacb03460565b2d0b62 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 25 Jul 2020 18:25:06 +0200 Subject: [PATCH 565/581] Add EFR32 upload framework --- tasmota/xdrv_01_webserver.ino | 45 ++++++++-- tasmota/xdrv_23_zigbee_9a_upload.ino | 121 +++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 tasmota/xdrv_23_zigbee_9a_upload.ino diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index b94a2a902..384b38c6f 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -44,7 +44,7 @@ const uint16_t HTTP_OTA_RESTART_RECONNECT_TIME = 28000; // milliseconds - Allow uint8_t *efm8bb1_update = nullptr; #endif // USE_RF_FLASH -enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT }; +enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT, UPL_EFR32 }; static const char * HEADER_KEYS[] = { "User-Agent", }; @@ -2627,20 +2627,26 @@ void HandleUploadDone(void) WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "
    "), WebColor(COL_TEXT_SUCCESS)); WSContentSend_P(HTTP_MSG_RSTRT); ShowWebSource(SRC_WEBGUI); + restart_flag = 2; // Always restart to re-enable disabled features during update +#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP) + if (ZigbeeUploadOtaReady()) { + restart_flag = 0; // Hold restart as firmware still needs to be written to MCU EFR32 + } +#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP #ifdef USE_TASMOTA_CLIENT if (TasmotaClient_GetFlagFlashing()) { - restart_flag = 0; - } else { // It was a normal firmware file, or we are ready to restart device - restart_flag = 2; + restart_flag = 0; // Hold restart as code still needs to be trasnferred to Atmega } -#else - restart_flag = 2; // Always restart to re-enable disabled features during update -#endif +#endif // USE_TASMOTA_CLIENT } SettingsBufferFree(); WSContentSend_P(PSTR("

    ")); WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); + +#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP) + ZigbeeUploadXmodem(); +#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP #ifdef USE_TASMOTA_CLIENT if (TasmotaClient_GetFlagFlashing()) { TasmotaClient_Flash(); @@ -2707,6 +2713,15 @@ void HandleUploadLoop(void) Web.config_block_count = 0; } else { +#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP) + if ((SONOFF_ZB_BRIDGE == my_module_type) && (upload.buf[0] == 0xEB)) { // Check if this is a Zigbee bridge FW file + Update.end(); // End esp8266 update session + Web.upload_file_type = UPL_EFR32; + + Web.upload_error = ZigbeeUploadInit(); // 15 + if (Web.upload_error != 0) { return; } + } else +#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP #ifdef USE_RF_FLASH if ((SONOFF_BRIDGE == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a RF bridge FW file Update.end(); // End esp8266 update session @@ -2750,6 +2765,15 @@ void HandleUploadLoop(void) Web.config_block_count++; } } +#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP) + else if (UPL_EFR32 == Web.upload_file_type) { + // Write buffers to MCU EFR32 + if (!ZigbeeUploadWriteBuffer(upload.buf, upload.currentSize)) { + Web.upload_error = 9; // File too large + return; + } + } +#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP #ifdef USE_RF_FLASH else if (UPL_EFM8BB1 == Web.upload_file_type) { if (efm8bb1_update != nullptr) { // We have carry over data since last write, i. e. a start but not an end @@ -2844,6 +2868,13 @@ void HandleUploadLoop(void) return; } } +#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP) + else if (UPL_EFR32 == Web.upload_file_type) { + // Zigbee FW upload to ESP8266 flash is done + ZigbeeUploadDone(); // Signal upload done and ready for delayed upload to MCU EFR32 + Web.upload_file_type = UPL_TASMOTA; + } +#endif #ifdef USE_RF_FLASH else if (UPL_EFM8BB1 == Web.upload_file_type) { // RF FW flash done diff --git a/tasmota/xdrv_23_zigbee_9a_upload.ino b/tasmota/xdrv_23_zigbee_9a_upload.ino new file mode 100644 index 000000000..1e1ff935f --- /dev/null +++ b/tasmota/xdrv_23_zigbee_9a_upload.ino @@ -0,0 +1,121 @@ +/* + xdrv_23_zigbee_9_serial.ino - zigbee: serial communication with MCU + + Copyright (C) 2020 Theo Arends and Stephan Hadinger + + 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_ZIGBEE + +#ifdef USE_ZIGBEE_EZSP +/*********************************************************************************************\ + * MCU EFR32 firmware upload using xmodem + * + * Step 1 - Upload MCU firmware in ESP8266 flash free space (current size is about 200k) + * Step 2 - Upload MCU firmware from ESP8266 flash to MCU EFR32 using XMODEM protocol + * Step 3 - Restart +\*********************************************************************************************/ + +const uint8_t PIN_ZIGBEE_BOOTLOADER = 5; + +struct ZBUPLOAD { + uint32_t ota_size = 0; + uint32_t sector_cursor = 0; + uint32_t sector_counter = 0; + bool ota_ready = false; +} ZbUpload; + +bool ZigbeeUploadOtaReady(void) { + return ZbUpload.ota_ready; +} + +uint32_t ZigbeeUploadFlashStart(void) { + return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; +} + +uint8_t ZigbeeUploadInit(void) { + if (!PinUsed(GPIO_ZIGBEE_RST) && (ZigbeeSerial == nullptr)) { return 1; } // Wrong pin configuration - No file selected + + ZbUpload.sector_counter = ZigbeeUploadFlashStart(); + ZbUpload.sector_cursor = 0; + ZbUpload.ota_size = 0; + ZbUpload.ota_ready = false; + return 0; +} + +bool ZigbeeUploadWriteBuffer(uint8_t *buf, size_t size) { + // Read complete file into ESP8266 flash + // Current files are about 200k + if (0 == ZbUpload.sector_cursor) { // Starting a new sector write so we need to erase it first + ESP.flashEraseSector(ZbUpload.sector_counter); + } + ZbUpload.sector_cursor++; + ESP.flashWrite((ZbUpload.sector_counter * SPI_FLASH_SEC_SIZE) + ((ZbUpload.sector_cursor-1) * 2048), (uint32_t*)buf, size); + ZbUpload.ota_size += size; + if (2 == ZbUpload.sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase + ZbUpload.sector_cursor = 0; + ZbUpload.sector_counter++; + if (ZbUpload.sector_counter > (SPIFFS_END + 12)) { + return false; // File too large - Not enough free space + } + } + return true; +} + +void ZigbeeUploadDone(void) { + ZbUpload.ota_ready = true; +} + +void ZigbeeUploadSetBootloader(uint8_t state) { + pinMode(PIN_ZIGBEE_BOOTLOADER, OUTPUT); + digitalWrite(PIN_ZIGBEE_BOOTLOADER, state); // Toggle Gecko bootloader + digitalWrite(Pin(GPIO_ZIGBEE_RST), 0); + delay(100); // Need to experiment to find a value as low as possible + digitalWrite(Pin(GPIO_ZIGBEE_RST), 1); // Reboot MCU EFR32 +} + +void ZigbeeUploadXmodem(void) { + if (!ZbUpload.ota_ready) { return; } + + // Copy uploaded OTA file from ESP8266 flash to MCU EFR32 using xmodem + uint32_t sector_counter = ZigbeeUploadFlashStart() * SPI_FLASH_SEC_SIZE; + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Upload start 0x%08X, size 0x%08X"), sector_counter, ZbUpload.ota_size); + + // TODO - implement XMODEM upload + +// ZigbeeUploadSetBootloader(1); // Reboot MCU EFR32 which returns below text + // Gecko Bootloader v1.A.3 + // 1. upload gbl + // 2. run + // 3. ebl info + // BL > + // Use ZigbeeInputLoop to flush received data + + // Send option 1 to prepare for xmodem upload +// ZigbeeSerial->write('1'); +// ZigbeeSerial->write(0x0d); +// ZigbeeSerial->write(0x0a); + + // Start xmodem upload + + ZbUpload.ota_ready = false; +// ZigbeeUploadSetBootloader(0); // Disable bootloader and reset MCU + restart_flag = 2; // Restart to disable bootloader and use new firmware +} + +#endif // USE_ZIGBEE_EZSP + +#endif // USE_ZIGBEE From 267a49b140fc9e05b593de1d19df7da220afc9c4 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 26 Jul 2020 13:54:24 +0200 Subject: [PATCH 566/581] Fix compilation error for Zigbee ZNP --- tasmota/xdrv_23_zigbee_8_parsers.ino | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 7f1c98e0a..05b0b4b37 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -822,20 +822,12 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { return -1; } +#ifdef USE_ZIGBEE_EZSP // // Handle Parent Annonce Rsp incoming message // // rsp: true = ZDO_Parent_annce_rsp, false = ZDO_Parent_annce -int32_t Z_ParentAnnceRsp(int32_t res, const class SBuffer &buf, bool rsp) { -#ifdef USE_ZIGBEE_ZNP -// uint16_t shortaddr = buf.get16(2); -// uint8_t status = buf.get8(4); -// uint8_t bind_total = buf.get8(5); -// uint8_t bind_start = buf.get8(6); -// uint8_t bind_len = buf.get8(7); -// const size_t prefix_len = 8; -#endif // USE_ZIGBEE_ZNP -#ifdef USE_ZIGBEE_EZSP +int32_t EZ_ParentAnnceRsp(int32_t res, const class SBuffer &buf, bool rsp) { size_t prefix_len; uint8_t status; uint8_t num_children; @@ -849,7 +841,6 @@ int32_t Z_ParentAnnceRsp(int32_t res, const class SBuffer &buf, bool rsp) { num_children = buf.get8(0); prefix_len = 1; } -#endif // USE_ZIGBEE_EZSP const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr); @@ -887,6 +878,7 @@ int32_t Z_ParentAnnceRsp(int32_t res, const class SBuffer &buf, bool rsp) { return -1; } +#endif // USE_ZIGBEE_EZSP /*********************************************************************************************\ * Send specific ZNP messages @@ -1155,9 +1147,9 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { case ZDO_Mgmt_Bind_rsp: return Z_MgmtBindRsp(res, zdo_buf); case ZDO_Parent_annce: - return Z_ParentAnnceRsp(res, zdo_buf, false); + return EZ_ParentAnnceRsp(res, zdo_buf, false); case ZDO_Parent_annce_rsp: - return Z_ParentAnnceRsp(res, zdo_buf, true); + return EZ_ParentAnnceRsp(res, zdo_buf, true); default: // TODO move later to LOG_LEVEL_DEBUG AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: Internal ZDO message 0x%04X sent from 0x%04X %s"), clusterid, srcaddr, wasbroadcast ? PSTR("(broadcast)") : ""); From 30d0f050c7a2f5984542d2cd90e4454a40ae663a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 26 Jul 2020 18:55:31 +0200 Subject: [PATCH 567/581] POC Zigbee EFR32 xmodem upload POC Zigbee EFR32 xmodem upload (#8583) --- tasmota/xdrv_01_webserver.ino | 3 - tasmota/xdrv_23_zigbee_9a_upload.ino | 335 +++++++++++++++++++++++---- tasmota/xdrv_23_zigbee_A_impl.ino | 9 +- 3 files changed, 298 insertions(+), 49 deletions(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 384b38c6f..1f878ae6b 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -2644,9 +2644,6 @@ void HandleUploadDone(void) WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); -#if defined(USE_ZIGBEE) && defined(USE_ZIGBEE_EZSP) - ZigbeeUploadXmodem(); -#endif // USE_ZIGBEE and USE_ZIGBEE_EZSP #ifdef USE_TASMOTA_CLIENT if (TasmotaClient_GetFlagFlashing()) { TasmotaClient_Flash(); diff --git a/tasmota/xdrv_23_zigbee_9a_upload.ino b/tasmota/xdrv_23_zigbee_9a_upload.ino index 1e1ff935f..c2bb2dc11 100644 --- a/tasmota/xdrv_23_zigbee_9a_upload.ino +++ b/tasmota/xdrv_23_zigbee_9a_upload.ino @@ -28,30 +28,315 @@ * Step 3 - Restart \*********************************************************************************************/ +#define XM_SOH 0x01 +#define XM_STX 0x02 +#define XM_EOT 0x04 +#define XM_ENQ 0x05 +#define XM_ACK 0x06 +#define XM_LF 0x0a +#define XM_CR 0x0d +#define XM_DLE 0x10 +#define XM_XON 0x11 +#define XM_XOFF 0x13 +#define XM_NAK 0x15 +#define XM_CAN 0x18 +#define XM_EOF 0x1a + +enum ZbUploadSteps { ZBU_IDLE, ZBU_INIT, ZBU_PROMPT, ZBU_SYNC, ZBU_UPLOAD, ZBU_DONE, ZBU_COMPLETE }; + const uint8_t PIN_ZIGBEE_BOOTLOADER = 5; struct ZBUPLOAD { uint32_t ota_size = 0; uint32_t sector_cursor = 0; uint32_t sector_counter = 0; - bool ota_ready = false; + uint32_t byte_counter = 0; + char *buffer; + uint8_t ota_step = ZBU_IDLE; } ZbUpload; -bool ZigbeeUploadOtaReady(void) { - return ZbUpload.ota_ready; -} +/*********************************************************************************************\ + * Flash +\*********************************************************************************************/ uint32_t ZigbeeUploadFlashStart(void) { return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; } +uint32_t ZigbeeUploadAvailable(void) { + int available = ZbUpload.ota_size - ZbUpload.byte_counter; + if (available < 0) { available = 0; } + return available; +} + +char ZigbeeUploadFlashRead(void) { + if (0 == ZbUpload.byte_counter) { + if (!(ZbUpload.buffer = (char *)malloc(SPI_FLASH_SEC_SIZE))) { + return (-1); // Not enough (memory) space + } + ZbUpload.sector_counter = ZigbeeUploadFlashStart(); + } + + uint32_t index = ZbUpload.byte_counter % SPI_FLASH_SEC_SIZE; + if (0 == index) { + ESP.flashRead(ZbUpload.sector_counter * SPI_FLASH_SEC_SIZE, (uint32_t*)ZbUpload.buffer, SPI_FLASH_SEC_SIZE); + ZbUpload.sector_counter++; + } + + char data = ZbUpload.buffer[index]; + ZbUpload.byte_counter++; + + if (ZbUpload.byte_counter > ZbUpload.ota_size) { + data = XM_EOF; +// if (ZbUpload.buffer) { free(ZbUpload.buffer); } // Don't in case of retries + } + return data; +} + +/*********************************************************************************************\ + * XModem protocol +\*********************************************************************************************/ + +// Number of seconds until giving up hope of receiving sync packets from host. +const uint8_t XMODEM_SYNC_TIMEOUT = 30; +// Number of times we try to send a packet to the host until we give up sending.. +const uint8_t XMODEM_MAX_RETRY = 30; +// Packet size +const uint8_t XMODEM_PACKET_SIZE = 128; + +struct XMODEM { + uint32_t timeout = 0; + uint32_t filepos = 0; + int crcBuf = 0; + uint8_t packetNo = 1; + uint8_t checksumBuf = 0; + bool oldChecksum; +} XModem; + +// Send out a byte of payload data, includes checksumming +void XModemOutputByte(uint8_t out_char) { + XModem.checksumBuf += out_char; + + XModem.crcBuf = XModem.crcBuf ^ (int) out_char << 8; + for (uint32_t i = 0; i < 8; i++) { + if (XModem.crcBuf & 0x8000) { + XModem.crcBuf = XModem.crcBuf << 1 ^ 0x1021; + } else { + XModem.crcBuf = XModem.crcBuf << 1; + } + } + + ZigbeeSerial->write(out_char); +} + +// Wait for the remote to acknowledge or cancel. +// Returns the received char if no timeout occured or a CAN was received. In this cases, it returns -1. +char XModemWaitACK(void) +{ + char in_char; + do { + uint8_t i = 0; + while (!ZigbeeSerial->available()) { + delayMicroseconds(100); + i++; + if (i > 200) { return -1; } + } + in_char = ZigbeeSerial->read(); + if (in_char == XM_CAN) { return XM_CAN; } + } while ((in_char != XM_NAK) && (in_char != XM_ACK) && (in_char != 'C')); + return in_char; +} + +bool XModemSendPacket(uint32_t packet_no) { + XModem.filepos = ZbUpload.byte_counter; + + // Sending a packet will be retried + uint32_t retries = 0; + char in_char; + do { + // Seek to start of current data block, + // will advance through the file as block will be acked.. + ZbUpload.byte_counter = XModem.filepos; + + // Reset checksum stuff + XModem.checksumBuf = 0x00; + XModem.crcBuf = 0x00; + + // Try to send packet, so header first + ZigbeeSerial->write(XM_SOH); + ZigbeeSerial->write(packet_no); + ZigbeeSerial->write(~packet_no); + for (uint32_t i = 0; i < XMODEM_PACKET_SIZE; i++) { + in_char = ZigbeeUploadFlashRead(); + XModemOutputByte(in_char); + } + // Send out checksum, either CRC-16 CCITT or classical inverse of sum of bytes. + // Depending on how the received introduced himself + if (XModem.oldChecksum) { + ZigbeeSerial->write((char)XModem.checksumBuf); + } else { + ZigbeeSerial->write((char)(XModem.crcBuf >> 8)); + ZigbeeSerial->write((char)(XModem.crcBuf & 0xFF)); + } + in_char = XModemWaitACK(); + if (XM_CAN == in_char) { return false; } + retries++; + if (retries > XMODEM_MAX_RETRY) { return false; } + } while (in_char != XM_ACK); + return true; +} + +bool XModemSendEOT(void) { + // Send EOT and wait for ACK + uint32_t retries = 0; + char in_char; + do { + ZigbeeSerial->write(XM_EOT); + in_char = XModemWaitACK(); + retries++; + // When timed out, leave immediately + if (retries == XMODEM_SYNC_TIMEOUT) { return false; } + } while (in_char != XM_ACK); + return true; +} + +/*********************************************************************************************\ + * Step 2 - Upload MCU firmware from ESP8266 flash to MCU EFR32 using XMODEM protocol + * + * https://www.silabs.com/documents/public/application-notes/an760-using-legacy-standalone-bootloader.pdf +\*********************************************************************************************/ + +void ZigbeeUploadSetBootloader(uint8_t state) { + pinMode(PIN_ZIGBEE_BOOTLOADER, OUTPUT); + digitalWrite(PIN_ZIGBEE_BOOTLOADER, state); // Toggle Gecko bootloader + digitalWrite(Pin(GPIO_ZIGBEE_RST), 0); + delay(100); // Need to experiment to find a value as low as possible + digitalWrite(Pin(GPIO_ZIGBEE_RST), 1); // Reboot MCU EFR32 +} + +void ZigbeeUploadBootloaderDone(void) { + ZbUpload.ota_step = ZBU_COMPLETE; // Never return to zero without a restart to get a sane Zigbee environment + ZigbeeUploadSetBootloader(0); // Disable bootloader and reset MCU - should happen or restart + restart_flag = 2; // Restart to disable bootloader and use new firmware +} + +bool ZigbeeUploadBootloaderPrompt(void) { + // Scripts that interact with the bootloader should use only the “BL >†prompt to determine + // when the bootloader is ready for input. While current menu options should remain functionally + // unchanged, the menu title and options text is liable to change, and new options might be added. + while (ZigbeeSerial->available()) { + yield(); + char bootloader_byte = ZigbeeSerial->read(); + switch (ZbUpload.byte_counter) { + case 0: + if ('B' == bootloader_byte) { ZbUpload.byte_counter++; } break; + case 1: + if ('L' == bootloader_byte) { ZbUpload.byte_counter++; } break; + case 2: + if (' ' == bootloader_byte) { ZbUpload.byte_counter++; } break; + case 3: + if ('>' == bootloader_byte) { ZbUpload.byte_counter++; } + } + } + return (4 == ZbUpload.byte_counter); +} + +bool ZigbeeUploadXmodem(void) { + if (!ZbUpload.ota_step) { return false; } + + switch (ZbUpload.ota_step) { + case ZBU_INIT: { // Init ESF32 bootloader + ZbUpload.ota_step = ZBU_PROMPT; + + uint32_t sector_counter = ZigbeeUploadFlashStart() * SPI_FLASH_SEC_SIZE; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Upload 0x%08X, size 0x%08X"), sector_counter, ZbUpload.ota_size); + + ZigbeeUploadSetBootloader(1); // Reboot MCU EFR32 which returns below text + break; + } + case ZBU_PROMPT: { // Wait for prompt and select option upload ebl + if (!ZigbeeSerial->available()) { + // The target device’s bootloader sends output over its serial port after it receives a carriage return + // from the source device + ZigbeeSerial->write(XM_CR); + delay(1); + } else { + // After the bootloader receives a carriage return from the target device, it displays a menu + // Gecko Bootloader v1.A.3 + // 1. upload gbl + // 2. run + // 3. ebl info + // BL > + if (ZigbeeUploadBootloaderPrompt()) { + ZigbeeSerial->flush(); + ZigbeeSerial->write('1'); // upload ebl + XModem.timeout = millis() + (XMODEM_SYNC_TIMEOUT * 1000); + ZbUpload.ota_step = ZBU_SYNC; + } + } + break; + } + case ZBU_SYNC: { // Handle file upload using XModem - sync + if (millis() > XModem.timeout) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Initial sync failed")); + ZigbeeUploadBootloaderDone(); + return true; + } + // Wait for either C or NACK as a sync packet. + // Determines protocol details, checksum algorithm. + if (ZigbeeSerial->available()) { + char xmodem_sync = ZigbeeSerial->read(); + if ((xmodem_sync == 'C') || (xmodem_sync == XM_NAK)) { + // Determine which checksum algorithm to use + XModem.oldChecksum = (xmodem_sync == XM_NAK); + XModem.packetNo = 1; + ZbUpload.byte_counter = 0; + ZbUpload.ota_step = ZBU_UPLOAD; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Sync received")); + } + } + break; + } + case ZBU_UPLOAD: { // Handle file upload using XModem - upload + if (ZigbeeUploadAvailable()) { + if (!XModemSendPacket(XModem.packetNo)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Packet send failed")); + ZigbeeUploadBootloaderDone(); + return true; + } + XModem.packetNo++; + } else { + if (!XModemSendEOT()) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: EOT failed")); + ZigbeeUploadBootloaderDone(); + return true; + } + ZbUpload.ota_step = ZBU_DONE; + } + break; + } + case ZBU_DONE: { // Clean up and restart to disable bootloader and use new firmware + ZigbeeUploadBootloaderDone(); + } + } + return true; +} + +/*********************************************************************************************\ + * Step 1 - Upload MCU firmware in ESP8266 flash free space (current size is about 200k) +\*********************************************************************************************/ + +bool ZigbeeUploadOtaReady(void) { + return (ZBU_INIT == ZbUpload.ota_step); +} + uint8_t ZigbeeUploadInit(void) { if (!PinUsed(GPIO_ZIGBEE_RST) && (ZigbeeSerial == nullptr)) { return 1; } // Wrong pin configuration - No file selected ZbUpload.sector_counter = ZigbeeUploadFlashStart(); ZbUpload.sector_cursor = 0; ZbUpload.ota_size = 0; - ZbUpload.ota_ready = false; + ZbUpload.ota_step = ZBU_IDLE; return 0; } @@ -75,45 +360,7 @@ bool ZigbeeUploadWriteBuffer(uint8_t *buf, size_t size) { } void ZigbeeUploadDone(void) { - ZbUpload.ota_ready = true; -} - -void ZigbeeUploadSetBootloader(uint8_t state) { - pinMode(PIN_ZIGBEE_BOOTLOADER, OUTPUT); - digitalWrite(PIN_ZIGBEE_BOOTLOADER, state); // Toggle Gecko bootloader - digitalWrite(Pin(GPIO_ZIGBEE_RST), 0); - delay(100); // Need to experiment to find a value as low as possible - digitalWrite(Pin(GPIO_ZIGBEE_RST), 1); // Reboot MCU EFR32 -} - -void ZigbeeUploadXmodem(void) { - if (!ZbUpload.ota_ready) { return; } - - // Copy uploaded OTA file from ESP8266 flash to MCU EFR32 using xmodem - uint32_t sector_counter = ZigbeeUploadFlashStart() * SPI_FLASH_SEC_SIZE; - - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Upload start 0x%08X, size 0x%08X"), sector_counter, ZbUpload.ota_size); - - // TODO - implement XMODEM upload - -// ZigbeeUploadSetBootloader(1); // Reboot MCU EFR32 which returns below text - // Gecko Bootloader v1.A.3 - // 1. upload gbl - // 2. run - // 3. ebl info - // BL > - // Use ZigbeeInputLoop to flush received data - - // Send option 1 to prepare for xmodem upload -// ZigbeeSerial->write('1'); -// ZigbeeSerial->write(0x0d); -// ZigbeeSerial->write(0x0a); - - // Start xmodem upload - - ZbUpload.ota_ready = false; -// ZigbeeUploadSetBootloader(0); // Disable bootloader and reset MCU - restart_flag = 2; // Restart to disable bootloader and use new firmware + ZbUpload.ota_step = ZBU_INIT; } #endif // USE_ZIGBEE_EZSP diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 6b23590cc..a631432fc 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1240,13 +1240,18 @@ bool Xdrv23(uint8_t function) } break; case FUNC_LOOP: +#ifdef USE_ZIGBEE_EZSP + if (ZigbeeUploadXmodem()) { + return false; + } +#endif if (ZigbeeSerial) { ZigbeeInputLoop(); ZigbeeOutputLoop(); // send any outstanding data } - if (zigbee.state_machine) { + if (zigbee.state_machine) { ZigbeeStateMachine_Run(); - } + } break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: From 0875b6bab026c6ba992281b2765e4a9651fac169 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Mon, 27 Jul 2020 09:03:53 +0200 Subject: [PATCH 568/581] Tasmota Stage Core 2.7.3.2 includes Arduino backport #7488 backport #7487 backport #7486 backport #7464 backport #7434 backport #7433 Security fix and malloc fix --- platformio_override_sample.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 48298c782..500281096 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -88,7 +88,7 @@ extra_scripts = ${scripts_defaults.extra_scripts} [tasmota_stage] ; *** Esp8266 core for Arduino version Tasmota stage platform = espressif8266@2.5.1 -platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.7.3.1/esp8266-2.7.3.1.zip +platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.7.3.2/esp8266-2.7.3.2.zip build_unflags = ${esp_defaults.build_unflags} build_flags = ${esp82xx_defaults.build_flags} From a6fe5f859b546c9f0dd2517d555c4fdcb1988558 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 27 Jul 2020 11:01:20 +0200 Subject: [PATCH 569/581] POC2 Zigbee EFR32 xmodem upload POC2 Zigbee EFR32 xmodem upload (#8583) - Swap reset states - Speed up XMODEM upload by changing current loop sleep - Add more debug messages --- tasmota/xdrv_23_zigbee_9a_upload.ino | 40 +++++++++++++++++++--------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_9a_upload.ino b/tasmota/xdrv_23_zigbee_9a_upload.ino index c2bb2dc11..e5296152e 100644 --- a/tasmota/xdrv_23_zigbee_9a_upload.ino +++ b/tasmota/xdrv_23_zigbee_9a_upload.ino @@ -106,6 +106,7 @@ const uint8_t XMODEM_PACKET_SIZE = 128; struct XMODEM { uint32_t timeout = 0; + uint32_t delay = 0; uint32_t filepos = 0; int crcBuf = 0; uint8_t packetNo = 1; @@ -216,8 +217,11 @@ void ZigbeeUploadSetBootloader(uint8_t state) { void ZigbeeUploadBootloaderDone(void) { ZbUpload.ota_step = ZBU_COMPLETE; // Never return to zero without a restart to get a sane Zigbee environment - ZigbeeUploadSetBootloader(0); // Disable bootloader and reset MCU - should happen or restart - restart_flag = 2; // Restart to disable bootloader and use new firmware + ZigbeeUploadSetBootloader(1); // Disable bootloader and reset MCU - should happen or restart + if (1 == ssleep) { + ssleep = Settings.sleep; // Restore loop sleep + } + restart_flag = 2; // Restart to disable bootloader and use new firmware } bool ZigbeeUploadBootloaderPrompt(void) { @@ -246,20 +250,27 @@ bool ZigbeeUploadXmodem(void) { switch (ZbUpload.ota_step) { case ZBU_INIT: { // Init ESF32 bootloader + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Init bootloader")); + ZigbeeUploadSetBootloader(0); // Reboot MCU EFR32 which returns below text + XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt + XModem.delay = millis() + 500; ZbUpload.ota_step = ZBU_PROMPT; - - uint32_t sector_counter = ZigbeeUploadFlashStart() * SPI_FLASH_SEC_SIZE; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: Upload 0x%08X, size 0x%08X"), sector_counter, ZbUpload.ota_size); - - ZigbeeUploadSetBootloader(1); // Reboot MCU EFR32 which returns below text break; } case ZBU_PROMPT: { // Wait for prompt and select option upload ebl - if (!ZigbeeSerial->available()) { + if (millis() > XModem.timeout) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Bootloader timeout")); + ZigbeeUploadBootloaderDone(); + return true; + } + else if (!ZigbeeSerial->available()) { // The target device’s bootloader sends output over its serial port after it receives a carriage return // from the source device - ZigbeeSerial->write(XM_CR); - delay(1); + if (millis() > XModem.delay) { + ZigbeeSerial->write('a'); + ZigbeeSerial->write(XM_CR); + XModem.delay = millis() + 500; + } } else { // After the bootloader receives a carriage return from the target device, it displays a menu // Gecko Bootloader v1.A.3 @@ -268,8 +279,12 @@ bool ZigbeeUploadXmodem(void) { // 3. ebl info // BL > if (ZigbeeUploadBootloaderPrompt()) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Init sync")); ZigbeeSerial->flush(); ZigbeeSerial->write('1'); // upload ebl + if (ssleep > 0) { + ssleep = 1; // Speed up loop used for xmodem upload + } XModem.timeout = millis() + (XMODEM_SYNC_TIMEOUT * 1000); ZbUpload.ota_step = ZBU_SYNC; } @@ -278,7 +293,7 @@ bool ZigbeeUploadXmodem(void) { } case ZBU_SYNC: { // Handle file upload using XModem - sync if (millis() > XModem.timeout) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Initial sync failed")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Sync timeout")); ZigbeeUploadBootloaderDone(); return true; } @@ -292,7 +307,7 @@ bool ZigbeeUploadXmodem(void) { XModem.packetNo = 1; ZbUpload.byte_counter = 0; ZbUpload.ota_step = ZBU_UPLOAD; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Sync received")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Init packet send")); } } break; @@ -311,6 +326,7 @@ bool ZigbeeUploadXmodem(void) { ZigbeeUploadBootloaderDone(); return true; } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Complete")); ZbUpload.ota_step = ZBU_DONE; } break; From e8beeba651dbc6c49b5e3a4dcaf87c892a21ccd4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 27 Jul 2020 11:05:44 +0200 Subject: [PATCH 570/581] Remove obsolete debug info --- tasmota/xdrv_23_zigbee_9a_upload.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/tasmota/xdrv_23_zigbee_9a_upload.ino b/tasmota/xdrv_23_zigbee_9a_upload.ino index e5296152e..560445279 100644 --- a/tasmota/xdrv_23_zigbee_9a_upload.ino +++ b/tasmota/xdrv_23_zigbee_9a_upload.ino @@ -267,7 +267,6 @@ bool ZigbeeUploadXmodem(void) { // The target device’s bootloader sends output over its serial port after it receives a carriage return // from the source device if (millis() > XModem.delay) { - ZigbeeSerial->write('a'); ZigbeeSerial->write(XM_CR); XModem.delay = millis() + 500; } From 2012eaccf4c28aaacb85a62175334fae2b72ab6f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 27 Jul 2020 15:43:24 +0200 Subject: [PATCH 571/581] POC3 Zigbee EFR32 xmodem upload POC3 Zigbee EFR32 xmodem upload (#8583) - Extend ACK timeout after EOT --- tasmota/xdrv_23_zigbee_9a_upload.ino | 143 ++++++++++++++++----------- 1 file changed, 87 insertions(+), 56 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_9a_upload.ino b/tasmota/xdrv_23_zigbee_9a_upload.ino index 560445279..5280ea472 100644 --- a/tasmota/xdrv_23_zigbee_9a_upload.ino +++ b/tasmota/xdrv_23_zigbee_9a_upload.ino @@ -1,5 +1,5 @@ /* - xdrv_23_zigbee_9_serial.ino - zigbee: serial communication with MCU + xdrv_23_zigbee_9a_upload.ino - zigbee: serial xmodem upload to MCU Copyright (C) 2020 Theo Arends and Stephan Hadinger @@ -40,9 +40,9 @@ #define XM_XOFF 0x13 #define XM_NAK 0x15 #define XM_CAN 0x18 -#define XM_EOF 0x1a +#define XM_SUB 0x1a -enum ZbUploadSteps { ZBU_IDLE, ZBU_INIT, ZBU_PROMPT, ZBU_SYNC, ZBU_UPLOAD, ZBU_DONE, ZBU_COMPLETE }; +enum ZbUploadSteps { ZBU_IDLE, ZBU_INIT, ZBU_PROMPT, ZBU_SYNC, ZBU_UPLOAD, ZBU_EOT, ZBU_COMPLETE, ZBU_DONE, ZBU_FINISH }; const uint8_t PIN_ZIGBEE_BOOTLOADER = 5; @@ -87,7 +87,9 @@ char ZigbeeUploadFlashRead(void) { ZbUpload.byte_counter++; if (ZbUpload.byte_counter > ZbUpload.ota_size) { - data = XM_EOF; + // When the source device reaches the last XModem data block, it should be padded to 128 bytes + // of data using SUB (ASCII 0x1A) characters. + data = XM_SUB; // if (ZbUpload.buffer) { free(ZbUpload.buffer); } // Don't in case of retries } return data; @@ -143,7 +145,7 @@ char XModemWaitACK(void) if (i > 200) { return -1; } } in_char = ZigbeeSerial->read(); - if (in_char == XM_CAN) { return XM_CAN; } + if (XM_CAN == in_char) { return XM_CAN; } } while ((in_char != XM_NAK) && (in_char != XM_ACK) && (in_char != 'C')); return in_char; } @@ -187,20 +189,6 @@ bool XModemSendPacket(uint32_t packet_no) { return true; } -bool XModemSendEOT(void) { - // Send EOT and wait for ACK - uint32_t retries = 0; - char in_char; - do { - ZigbeeSerial->write(XM_EOT); - in_char = XModemWaitACK(); - retries++; - // When timed out, leave immediately - if (retries == XMODEM_SYNC_TIMEOUT) { return false; } - } while (in_char != XM_ACK); - return true; -} - /*********************************************************************************************\ * Step 2 - Upload MCU firmware from ESP8266 flash to MCU EFR32 using XMODEM protocol * @@ -215,15 +203,6 @@ void ZigbeeUploadSetBootloader(uint8_t state) { digitalWrite(Pin(GPIO_ZIGBEE_RST), 1); // Reboot MCU EFR32 } -void ZigbeeUploadBootloaderDone(void) { - ZbUpload.ota_step = ZBU_COMPLETE; // Never return to zero without a restart to get a sane Zigbee environment - ZigbeeUploadSetBootloader(1); // Disable bootloader and reset MCU - should happen or restart - if (1 == ssleep) { - ssleep = Settings.sleep; // Restore loop sleep - } - restart_flag = 2; // Restart to disable bootloader and use new firmware -} - bool ZigbeeUploadBootloaderPrompt(void) { // Scripts that interact with the bootloader should use only the “BL >†prompt to determine // when the bootloader is ready for input. While current menu options should remain functionally @@ -246,26 +225,28 @@ bool ZigbeeUploadBootloaderPrompt(void) { } bool ZigbeeUploadXmodem(void) { - if (!ZbUpload.ota_step) { return false; } - switch (ZbUpload.ota_step) { - case ZBU_INIT: { // Init ESF32 bootloader + case ZBU_IDLE: { // *** Upload disabled + return false; + } + case ZBU_INIT: { // *** Init ESF32 bootloader AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Init bootloader")); - ZigbeeUploadSetBootloader(0); // Reboot MCU EFR32 which returns below text + ZigbeeUploadSetBootloader(0); // Reboot MCU EFR32 which returns below text XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt XModem.delay = millis() + 500; + ZbUpload.byte_counter = 0; ZbUpload.ota_step = ZBU_PROMPT; break; } - case ZBU_PROMPT: { // Wait for prompt and select option upload ebl + case ZBU_PROMPT: { // *** Wait for prompt and select option upload ebl if (millis() > XModem.timeout) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Bootloader timeout")); - ZigbeeUploadBootloaderDone(); + ZbUpload.ota_step = ZBU_DONE; return true; } else if (!ZigbeeSerial->available()) { - // The target device’s bootloader sends output over its serial port after it receives a carriage return - // from the source device + // The target device’s bootloader sends output over its serial port after it receives a + // carriage return from the source device if (millis() > XModem.delay) { ZigbeeSerial->write(XM_CR); XModem.delay = millis() + 500; @@ -280,9 +261,9 @@ bool ZigbeeUploadXmodem(void) { if (ZigbeeUploadBootloaderPrompt()) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Init sync")); ZigbeeSerial->flush(); - ZigbeeSerial->write('1'); // upload ebl + ZigbeeSerial->write('1'); // upload ebl if (ssleep > 0) { - ssleep = 1; // Speed up loop used for xmodem upload + ssleep = 1; // Speed up loop used for xmodem upload } XModem.timeout = millis() + (XMODEM_SYNC_TIMEOUT * 1000); ZbUpload.ota_step = ZBU_SYNC; @@ -290,17 +271,16 @@ bool ZigbeeUploadXmodem(void) { } break; } - case ZBU_SYNC: { // Handle file upload using XModem - sync + case ZBU_SYNC: { // *** Handle file upload using XModem - sync if (millis() > XModem.timeout) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Sync timeout")); - ZigbeeUploadBootloaderDone(); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: SYNC timeout")); + ZbUpload.ota_step = ZBU_DONE; return true; } - // Wait for either C or NACK as a sync packet. - // Determines protocol details, checksum algorithm. + // Wait for either C or NACK as a sync packet. Determines protocol details, checksum algorithm. if (ZigbeeSerial->available()) { char xmodem_sync = ZigbeeSerial->read(); - if ((xmodem_sync == 'C') || (xmodem_sync == XM_NAK)) { + if (('C' == xmodem_sync) || (XM_NAK == xmodem_sync)) { // Determine which checksum algorithm to use XModem.oldChecksum = (xmodem_sync == XM_NAK); XModem.packetNo = 1; @@ -311,27 +291,78 @@ bool ZigbeeUploadXmodem(void) { } break; } - case ZBU_UPLOAD: { // Handle file upload using XModem - upload + case ZBU_UPLOAD: { // *** Handle file upload using XModem - upload if (ZigbeeUploadAvailable()) { if (!XModemSendPacket(XModem.packetNo)) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Packet send failed")); - ZigbeeUploadBootloaderDone(); + ZbUpload.ota_step = ZBU_DONE; return true; } XModem.packetNo++; } else { - if (!XModemSendEOT()) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: EOT failed")); - ZigbeeUploadBootloaderDone(); - return true; - } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Complete")); - ZbUpload.ota_step = ZBU_DONE; + // Once the last block is ACKed by the target, the transfer should be finalized by an + // EOT (ASCII 0x04) packet from the source. Once this packet is confirmed via XModem ACK + // from the target, the device will reboot, causing the new firmware to be launched. + ZigbeeSerial->write(XM_EOT); + XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EOT ACK + ZbUpload.ota_step = ZBU_EOT; } break; } - case ZBU_DONE: { // Clean up and restart to disable bootloader and use new firmware - ZigbeeUploadBootloaderDone(); + case ZBU_EOT: { // *** Send EOT and wait for ACK + // The ACK for the last XModem data packet may take much longer (1-3 seconds) than prior + // data packets to be received. This is due to the CRC32 checksum being performed across + // the received EBL file data prior to sending the ACK. The source device must ensure that + // its XModem state machine waits a sufficient amount of time to allow this checksum process + // to occur without timing out on the response just before the EOT is sent. + if (millis() > XModem.timeout) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: EOT ACK timeout")); + ZbUpload.ota_step = ZBU_DONE; + return true; + } + if (ZigbeeSerial->available()) { + char xmodem_ack = XModemWaitACK(); + if (XM_ACK == xmodem_ack) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: " D_SUCCESSFUL)); + XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt + ZbUpload.byte_counter = 0; +// ZbUpload.ota_step = ZBU_COMPLETE; + ZbUpload.ota_step = ZBU_DONE; // Skip prompt for now + } + } + break; + } +/* + case ZBU_COMPLETE: { // *** Wait for Serial upload complete EBL prompt + if (millis() > XModem.timeout) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Bootloader timeout")); + ZbUpload.ota_step = ZBU_DONE; + return true; + } else { + // After an image successfully uploads, the XModem transaction completes and the bootloader displays + // ‘Serial upload complete’ before redisplaying the menu + // Serial upload complete + // BL > + if (ZigbeeUploadBootloaderPrompt()) { + ZbUpload.ota_step = ZBU_DONE; + } + } + break; + } +*/ + case ZBU_DONE: { // *** Clean up and restart to disable bootloader and use new firmware + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: " D_RESTARTING)); + ZigbeeUploadSetBootloader(1); // Disable bootloader and reset MCU - should happen at restart + if (1 == ssleep) { + ssleep = Settings.sleep; // Restore loop sleep + } + restart_flag = 2; // Restart to disable bootloader and use new firmware + ZbUpload.ota_step = ZBU_FINISH; // Never return to zero without a restart to get a sane Zigbee environment + break; + } + case ZBU_FINISH: { // *** Wait for restart making sure not to start Zigbee serial again + // Wait for restart + break; } } return true; @@ -367,7 +398,7 @@ bool ZigbeeUploadWriteBuffer(uint8_t *buf, size_t size) { if (2 == ZbUpload.sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase ZbUpload.sector_cursor = 0; ZbUpload.sector_counter++; - if (ZbUpload.sector_counter > (SPIFFS_END + 12)) { + if (ZbUpload.sector_counter > (SPIFFS_END -2)) { return false; // File too large - Not enough free space } } From 0abe6c6a2bc48d42e5b29f56e8596109ab5a1286 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 27 Jul 2020 18:31:14 +0200 Subject: [PATCH 572/581] Zigbee EFR32 xmodem upload Zigbee EFR32 xmodem upload (#8583) - Now checks for upload complete - Add optional define ZIGBEE_BOOTLOADER_SOFTWARE_RESET_FIRST for software reset first --- tasmota/xdrv_23_zigbee_9a_upload.ino | 83 ++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/tasmota/xdrv_23_zigbee_9a_upload.ino b/tasmota/xdrv_23_zigbee_9a_upload.ino index 5280ea472..7c2feed26 100644 --- a/tasmota/xdrv_23_zigbee_9a_upload.ino +++ b/tasmota/xdrv_23_zigbee_9a_upload.ino @@ -28,21 +28,19 @@ * Step 3 - Restart \*********************************************************************************************/ +//#define ZIGBEE_BOOTLOADER_SOFTWARE_RESET_FIRST + #define XM_SOH 0x01 -#define XM_STX 0x02 #define XM_EOT 0x04 -#define XM_ENQ 0x05 #define XM_ACK 0x06 -#define XM_LF 0x0a #define XM_CR 0x0d -#define XM_DLE 0x10 -#define XM_XON 0x11 -#define XM_XOFF 0x13 #define XM_NAK 0x15 #define XM_CAN 0x18 #define XM_SUB 0x1a -enum ZbUploadSteps { ZBU_IDLE, ZBU_INIT, ZBU_PROMPT, ZBU_SYNC, ZBU_UPLOAD, ZBU_EOT, ZBU_COMPLETE, ZBU_DONE, ZBU_FINISH }; +enum ZbUploadSteps { ZBU_IDLE, ZBU_INIT, + ZBU_SOFTWARE_RESET, ZBU_SOFTWARE_SEND, ZBU_HARDWARE_RESET, ZBU_PROMPT, + ZBU_SYNC, ZBU_UPLOAD, ZBU_EOT, ZBU_COMPLETE, ZBU_DONE, ZBU_FINISH }; const uint8_t PIN_ZIGBEE_BOOTLOADER = 5; @@ -53,6 +51,7 @@ struct ZBUPLOAD { uint32_t byte_counter = 0; char *buffer; uint8_t ota_step = ZBU_IDLE; + uint8_t bootloader = 0; } ZbUpload; /*********************************************************************************************\ @@ -195,6 +194,14 @@ bool XModemSendPacket(uint32_t packet_no) { * https://www.silabs.com/documents/public/application-notes/an760-using-legacy-standalone-bootloader.pdf \*********************************************************************************************/ +void ZigbeeUploadSetSoftwareBootloader() { + // https://github.com/arendst/Tasmota/issues/8583#issuecomment-663967883 + SBuffer buf(4); + buf.add16(EZSP_launchStandaloneBootloader); + buf.add8(0x01); + ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len()); // Send software bootloader init +} + void ZigbeeUploadSetBootloader(uint8_t state) { pinMode(PIN_ZIGBEE_BOOTLOADER, OUTPUT); digitalWrite(PIN_ZIGBEE_BOOTLOADER, state); // Toggle Gecko bootloader @@ -229,6 +236,57 @@ bool ZigbeeUploadXmodem(void) { case ZBU_IDLE: { // *** Upload disabled return false; } +#ifdef ZIGBEE_BOOTLOADER_SOFTWARE_RESET_FIRST + case ZBU_INIT: { // *** Init ESF32 bootloader + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Init bootloader")); + ZbUpload.ota_step = ZBU_SOFTWARE_RESET; + return false; // Keep Zigbee serial active + } + case ZBU_SOFTWARE_RESET: { + SBuffer buf(4); + buf.add16(EZSP_launchStandaloneBootloader); + buf.add8(0x01); + ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len()); // Send software bootloader init + XModem.timeout = millis() + (10 * 1000); // Allow 10 seconds to send Zigbee command + ZbUpload.ota_step = ZBU_SOFTWARE_SEND; + return false; // Keep Zigbee serial active + } + case ZBU_SOFTWARE_SEND: { + if (millis() > XModem.timeout) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Bootloader software reset send timeout")); + ZbUpload.ota_step = ZBU_HARDWARE_RESET; + return true; + } + if (EZSP_Serial.to_send == EZSP_Serial.to_end) { + ZbUpload.bootloader = ZBU_SOFTWARE_RESET; + XModem.timeout = millis() + (10 * 1000); // Allow 10 seconds to receive EBL prompt + XModem.delay = millis() + 500; + ZbUpload.byte_counter = 0; + ZbUpload.ota_step = ZBU_PROMPT; + } + break; + } + case ZBU_HARDWARE_RESET: { + ZbUpload.bootloader = ZBU_HARDWARE_RESET; + ZigbeeUploadSetBootloader(0); // Reboot MCU EFR32 which returns below text + XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt + XModem.delay = millis() + 500; + ZbUpload.byte_counter = 0; + ZbUpload.ota_step = ZBU_PROMPT; + break; + } + case ZBU_PROMPT: { // *** Wait for prompt and select option upload ebl + if (millis() > XModem.timeout) { + if (ZBU_SOFTWARE_RESET == ZbUpload.bootloader) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Bootloader software reset timeout")); + ZbUpload.ota_step = ZBU_HARDWARE_RESET; + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Bootloader hardware reset timeout")); + ZbUpload.ota_step = ZBU_DONE; + } + return true; + } +#else // No ZIGBEE_BOOTLOADER_SOFTWARE_RESET_FIRST case ZBU_INIT: { // *** Init ESF32 bootloader AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Init bootloader")); ZigbeeUploadSetBootloader(0); // Reboot MCU EFR32 which returns below text @@ -244,6 +302,7 @@ bool ZigbeeUploadXmodem(void) { ZbUpload.ota_step = ZBU_DONE; return true; } +#endif // ZIGBEE_BOOTLOADER_SOFTWARE_RESET_FIRST else if (!ZigbeeSerial->available()) { // The target device’s bootloader sends output over its serial port after it receives a // carriage return from the source device @@ -326,13 +385,12 @@ bool ZigbeeUploadXmodem(void) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: " D_SUCCESSFUL)); XModem.timeout = millis() + (30 * 1000); // Allow 30 seconds to receive EBL prompt ZbUpload.byte_counter = 0; -// ZbUpload.ota_step = ZBU_COMPLETE; - ZbUpload.ota_step = ZBU_DONE; // Skip prompt for now + ZbUpload.ota_step = ZBU_COMPLETE; +// ZbUpload.ota_step = ZBU_DONE; // Skip prompt for now } } break; } -/* case ZBU_COMPLETE: { // *** Wait for Serial upload complete EBL prompt if (millis() > XModem.timeout) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: Bootloader timeout")); @@ -342,6 +400,10 @@ bool ZigbeeUploadXmodem(void) { // After an image successfully uploads, the XModem transaction completes and the bootloader displays // ‘Serial upload complete’ before redisplaying the menu // Serial upload complete + // Gecko Bootloader v1.A.3 + // 1. upload gbl + // 2. run + // 3. ebl info // BL > if (ZigbeeUploadBootloaderPrompt()) { ZbUpload.ota_step = ZBU_DONE; @@ -349,7 +411,6 @@ bool ZigbeeUploadXmodem(void) { } break; } -*/ case ZBU_DONE: { // *** Clean up and restart to disable bootloader and use new firmware AddLog_P2(LOG_LEVEL_DEBUG, PSTR("XMD: " D_RESTARTING)); ZigbeeUploadSetBootloader(1); // Disable bootloader and reset MCU - should happen at restart From b1f98f57112b47caa021120ed2edba96bfabe77d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 28 Jul 2020 09:25:48 +0200 Subject: [PATCH 573/581] Add tasmota-zbbridge support --- RELEASENOTES.md | 1 + platformio.ini | 1 + platformio_override_sample.ini | 1 + 3 files changed, 3 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e2170880c..468f761c6 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -44,6 +44,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - **tasmota-sensors.bin** = The Sensors version adds more useful sensors. - **tasmota-ir** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features. - **tasmota-display.bin** = The Display version without Energy Monitoring but adds display support. +- **tasmota-zbbridge.bin** = The dedicated Sonoff Zigbee Bridge version. - **tasmota-minimal.bin** = The Minimal version allows intermediate OTA uploads to support larger versions and does NOT change any persistent parameter. This version **should NOT be used for initial installation**. [List](MODULES.md) of embedded modules. diff --git a/platformio.ini b/platformio.ini index c68991444..e7284356b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,6 +26,7 @@ default_envs = ; tasmota-knx ; tasmota-sensors ; tasmota-display +; tasmota-zbbridge ; tasmota-ir ; tasmota-BG ; tasmota-BR diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 500281096..5ea714612 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -23,6 +23,7 @@ default_envs = ; tasmota-knx ; tasmota-sensors ; tasmota-display +; tasmota-zbbridge ; tasmota-ir ; tasmota32 ; tasmota32-webcam From beb4b6b3fe71e381b4d6cf7ed656ca04637de9f2 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 28 Jul 2020 09:29:26 +0200 Subject: [PATCH 574/581] Update MODULES.md --- MODULES.md | 153 +++++++++++++++++++++++++++-------------------------- 1 file changed, 77 insertions(+), 76 deletions(-) diff --git a/MODULES.md b/MODULES.md index e16dec401..1ca8ab473 100644 --- a/MODULES.md +++ b/MODULES.md @@ -2,81 +2,82 @@ The following hardware modules are supported. -Module | Description -------------------|----------------------- -01 Sonoff Basic | Sonoff Basic Wifi Smart Switch -02 Sonoff RF | Sonoff RF Wifi Smart Switch with RF (434MHz) receiver -03 Sonoff SV | Sonoff SV Safe Voltage Wifi Smart Switch -04 Sonoff TH | Sonoff TH10/TH16 Wifi Smart Switch with Sensor connection -05 Sonoff Dual | Sonoff Dual Wifi Smart Switch -06 Sonoff Pow | Sonoff Pow Wifi Smart Switch with Energy Monitoring -07 Sonoff 4CH | Sonoff 4CH 4-gang Wifi Smart Switch -08 Sonoff S2X | Sonoff S20/S26 Wifi Smart Socket -09 Slampher | Sonoff Slampher Wifi Smart Light Bulb Socket with RF (434MHz) receiver -10 Sonoff Touch | Sonoff Touch Wifi Light Switch -11 Sonoff LED | Sonoff Led Wifi Led Pack (Retired) -12 1 Channel | 1 Channel Inching/Self Locking Wifi Switch 5V/12V -13 4 Channel | 4 Channel Inching/Self Locking Wifi Switch (Retired) -14 Motor C/AC | Motor Clockwise/Antoclockwise Wifi Switch (Retired) -15 ElectroDragon | Electrodragon Wifi IoT Board -16 EXS Relay(s) | Electronic Experience Store 1 or 2-gang Wifi Module -17 WiOn | WiOn Wifi Smart Socket -18 Generic | Any ESP8266/ESP8285 device like WeMos and NodeMCU -19 Sonoff Dev | Sonoff Dev Wifi Development Board -20 H801 | H801 Wifi 5 Channel LED Controller -21 Sonoff SC | Sonoff SC Wifi Environmental Monitor -22 Sonoff BN-SZ | Sonoff BN-SZ01 Wifi Ceiling Led (Retired) -23 Sonoff 4CH Pro | Sonoff 4CH Pro 4-gang Wifi Smart Switch -24 Huafan SS | HuaFan Wifi Smart Socket -25 Sonoff Bridge | Sonoff RF (434MHz) transceive to Wifi Bridge -26 Sonoff B1 | Sonoff B1 Wifi RGBWW Led Bulb -27 AiLight | Ai-Thinker RGBW Led Bulb -28 Sonoff T1 1CH | Sonoff T1 1-gang Wifi Light Switch -29 Sonoff T1 2CH | Sonoff T1 2-gang Wifi Light Switch -30 Sonoff T1 3CH | Sonoff T1 3-gang Wifi Light Switch -31 Supla Espablo | 2-gang Wifi Module -32 Witty Cloud | Witty Cloud ESP8266 Wifi Development Board -33 Yunshan Relay | ESP8266 Wifi Network Relay Module -34 MagicHome | MagicHome, Flux-light and some Arilux LC10 RGB(W) Led Controller -35 Luani HVIO | Luani ESP8266 Wifi I/O Module -36 KMC 70011 | KMC Wifi Smart Socket with Energy Monitoring -37 Arilux LC01 | Arilux AL-LC01 RGB Led Controller -38 Arilux LC11 | Arilux AL-LC11 RGBWW Led Controller -39 Sonoff Dual R2 | Sonoff Dual R2 Wifi Smart Switch -40 Arilux LC06 | Arilux AL-LC06 RGB(WW) Led Controller -41 Sonoff S31 | Sonoff S31 Wifi Smart Socket with Energy Monitoring -42 Zengge WF017 | Zengge WF017 Wifi RGB(W) Led Controller -43 Sonoff Pow R2 | Sonoff Pow R2 Wifi Smart Switch with Energy Monitoring -44 Sonoff iFan02 | Sonoff iFan02 Wifi Smart Ceiling Fan with Light -45 BlitzWolf SHP | BlitzWolf BW-SHP2, BW-SHP6, HomeCube SP1, Gosund SP111, Teckin SP22 Wifi Smart Switch with Energy Monitoring -46 Shelly 1 | Shelly 1 Open Source Wifi Relay Module -47 Shelly 2 | Shelly 2 Wifi 2-gang Relay Module with Energy Monitoring -48 Xiaomi Philips | Xiaomi Philips Wifi WW Led Bulb -49 Neo Coolcam | Neo Coolcam Wifi Smart Socket -50 ESP Switch | ESP Switch 4-gang Wifi Switch with Leds -51 OBI Socket | OBI Wifi Smart Socket -52 Teckin | Teckin SP22 Wifi Smart Switch with Energy Monitoring -53 AplicWDP303075 | Aplic WDP 303075 CSL Wifi Smart Switch with Energy Monitoring -54 TuyaMCU | Devices with an MCU using Tuya communication protocol for control -55 Gosund SP1 v23 | Gosund SP1 v2.3 Wifi Smart Switch with Energy Monitoring -56 ARMTR Dimmer | ARMtronix Wifi dimmer for Incandescent Lights and Led -57 SK03 Outdoor | SK03 Outdoor Wifi Smart Switch with Energy Monitoring -58 PS-16-DZ | PS-16-DZ Wifi dimmer for Incandescent Lights and Led -59 Teckin US | Teckin SP20 and ZooZee SA102 Wifi Smart Switch with Energy Monitoring -60 Manzoku strip | Manzoku Wifi Smart Power Strip with four Relays -61 OBI Socket 2 | OBI 2 Wifi Smart Socket -62 YTF IR Bridge | YTF Universal IR Bridge -63 Digoo DG-SP202 | Digoo DG-SP202 Dual Wifi Smart Switch with Energy Monitoring -64 KA10 | Smanergy KA10 Wifi Smart Wall Switch with Energy Monitoring -65 Luminea ZX2820 | Luminea ZX2820 Wifi Smart Switch with Energy Monitoring -66 Mi Desk Lamp | Mi Desk Lamp with rotary switch and Wifi -67 SP10 | Tuya SP10 Wifi Smart Switch with Energy Monitoring -68 WAGA CHCZ02MB | WAGA life CHCZ02MB Wifi Smart Switch with Energy Monitoring -69 SYF05 | Sunyesmart SYF05 RGBWW Wifi Led Bulb -70 Sonoff L1 | Sonoff L1 light strip -71 Sonoff iFan03 | Sonoff iFan03 Wifi Smart Ceiling Fan with Light -72 EXS Dimmer | EXS Wifi Dimmer v4 -73 PWM Dimmer | Martin Jerry/acenx/Tessan/NTONPOWER SD0x PWM Dimmer Switches -74 Sonoff D1 | Sonoff D1 Wifi and RF Dimmer +Module | Description +-------------------|----------------------- +01 Sonoff Basic | Sonoff Basic Wifi Smart Switch +02 Sonoff RF | Sonoff RF Wifi Smart Switch with RF (434MHz) receiver +03 Sonoff SV | Sonoff SV Safe Voltage Wifi Smart Switch +04 Sonoff TH | Sonoff TH10/TH16 Wifi Smart Switch with Sensor connection +05 Sonoff Dual | Sonoff Dual Wifi Smart Switch +06 Sonoff Pow | Sonoff Pow Wifi Smart Switch with Energy Monitoring +07 Sonoff 4CH | Sonoff 4CH 4-gang Wifi Smart Switch +08 Sonoff S2X | Sonoff S20/S26 Wifi Smart Socket +09 Slampher | Sonoff Slampher Wifi Smart Light Bulb Socket with RF (434MHz) receiver +10 Sonoff Touch | Sonoff Touch Wifi Light Switch +11 Sonoff LED | Sonoff Led Wifi Led Pack (Retired) +12 1 Channel | 1 Channel Inching/Self Locking Wifi Switch 5V/12V +13 4 Channel | 4 Channel Inching/Self Locking Wifi Switch (Retired) +14 Motor C/AC | Motor Clockwise/Antoclockwise Wifi Switch (Retired) +15 ElectroDragon | Electrodragon Wifi IoT Board +16 EXS Relay(s) | Electronic Experience Store 1 or 2-gang Wifi Module +17 WiOn | WiOn Wifi Smart Socket +18 Generic | Any ESP8266/ESP8285 device like WeMos and NodeMCU +19 Sonoff Dev | Sonoff Dev Wifi Development Board +20 H801 | H801 Wifi 5 Channel LED Controller +21 Sonoff SC | Sonoff SC Wifi Environmental Monitor +22 Sonoff BN-SZ | Sonoff BN-SZ01 Wifi Ceiling Led (Retired) +23 Sonoff 4CH Pro | Sonoff 4CH Pro 4-gang Wifi Smart Switch +24 Huafan SS | HuaFan Wifi Smart Socket +25 Sonoff Bridge | Sonoff RF (434MHz) transceive to Wifi Bridge +26 Sonoff B1 | Sonoff B1 Wifi RGBWW Led Bulb +27 AiLight | Ai-Thinker RGBW Led Bulb +28 Sonoff T1 1CH | Sonoff T1 1-gang Wifi Light Switch +29 Sonoff T1 2CH | Sonoff T1 2-gang Wifi Light Switch +30 Sonoff T1 3CH | Sonoff T1 3-gang Wifi Light Switch +31 Supla Espablo | 2-gang Wifi Module +32 Witty Cloud | Witty Cloud ESP8266 Wifi Development Board +33 Yunshan Relay | ESP8266 Wifi Network Relay Module +34 MagicHome | MagicHome, Flux-light and some Arilux LC10 RGB(W) Led Controller +35 Luani HVIO | Luani ESP8266 Wifi I/O Module +36 KMC 70011 | KMC Wifi Smart Socket with Energy Monitoring +37 Arilux LC01 | Arilux AL-LC01 RGB Led Controller +38 Arilux LC11 | Arilux AL-LC11 RGBWW Led Controller +39 Sonoff Dual R2 | Sonoff Dual R2 Wifi Smart Switch +40 Arilux LC06 | Arilux AL-LC06 RGB(WW) Led Controller +41 Sonoff S31 | Sonoff S31 Wifi Smart Socket with Energy Monitoring +42 Zengge WF017 | Zengge WF017 Wifi RGB(W) Led Controller +43 Sonoff Pow R2 | Sonoff Pow R2 Wifi Smart Switch with Energy Monitoring +44 Sonoff iFan02 | Sonoff iFan02 Wifi Smart Ceiling Fan with Light +45 BlitzWolf SHP | BlitzWolf BW-SHP2, BW-SHP6, HomeCube SP1, Gosund SP111, Teckin SP22 Wifi Smart Switch with Energy Monitoring +46 Shelly 1 | Shelly 1 Open Source Wifi Relay Module +47 Shelly 2 | Shelly 2 Wifi 2-gang Relay Module with Energy Monitoring +48 Xiaomi Philips | Xiaomi Philips Wifi WW Led Bulb +49 Neo Coolcam | Neo Coolcam Wifi Smart Socket +50 ESP Switch | ESP Switch 4-gang Wifi Switch with Leds +51 OBI Socket | OBI Wifi Smart Socket +52 Teckin | Teckin SP22 Wifi Smart Switch with Energy Monitoring +53 AplicWDP303075 | Aplic WDP 303075 CSL Wifi Smart Switch with Energy Monitoring +54 TuyaMCU | Devices with an MCU using Tuya communication protocol for control +55 Gosund SP1 v23 | Gosund SP1 v2.3 Wifi Smart Switch with Energy Monitoring +56 ARMTR Dimmer | ARMtronix Wifi dimmer for Incandescent Lights and Led +57 SK03 Outdoor | SK03 Outdoor Wifi Smart Switch with Energy Monitoring +58 PS-16-DZ | PS-16-DZ Wifi dimmer for Incandescent Lights and Led +59 Teckin US | Teckin SP20 and ZooZee SA102 Wifi Smart Switch with Energy Monitoring +60 Manzoku strip | Manzoku Wifi Smart Power Strip with four Relays +61 OBI Socket 2 | OBI 2 Wifi Smart Socket +62 YTF IR Bridge | YTF Universal IR Bridge +63 Digoo DG-SP202 | Digoo DG-SP202 Dual Wifi Smart Switch with Energy Monitoring +64 KA10 | Smanergy KA10 Wifi Smart Wall Switch with Energy Monitoring +65 Luminea ZX2820 | Luminea ZX2820 Wifi Smart Switch with Energy Monitoring +66 Mi Desk Lamp | Mi Desk Lamp with rotary switch and Wifi +67 SP10 | Tuya SP10 Wifi Smart Switch with Energy Monitoring +68 WAGA CHCZ02MB | WAGA life CHCZ02MB Wifi Smart Switch with Energy Monitoring +69 SYF05 | Sunyesmart SYF05 RGBWW Wifi Led Bulb +70 Sonoff L1 | Sonoff L1 light strip +71 Sonoff iFan03 | Sonoff iFan03 Wifi Smart Ceiling Fan with Light +72 EXS Dimmer | EXS Wifi Dimmer v4 +73 PWM Dimmer | Martin Jerry/acenx/Tessan/NTONPOWER SD0x PWM Dimmer Switches +74 Sonoff D1 | Sonoff D1 Wifi and RF Dimmer +75 Sonoff ZbBridge | Sonoff Zigbee bridge Over 1000 additional devices are supported using [templates](TEMPLATES.md). From 59be0ce72967162257c3e90323c59d00d8cf2d54 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 29 Jul 2020 09:55:15 +0200 Subject: [PATCH 575/581] Prep release 8.4.0 --- TEMPLATES.md | 64 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/TEMPLATES.md b/TEMPLATES.md index d39a55b92..ff354aab7 100644 --- a/TEMPLATES.md +++ b/TEMPLATES.md @@ -42,9 +42,11 @@ BrilliantSmart 20696 9W 900lm {"NAME":"Brilliant20696","GPIO":[0,0,0,0,0,0,0,0, BrilliantSmart 20697 9W 900lm {"NAME":"Brilliant20696","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Bulbrite Solana A19 Edison Filament {"NAME":"BulbBrite01","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":18} Bulbrite Solana G25 5.5W 600lm Filament {"NAME":"BulbBrite01","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Bulbrite Solana ST18 16W 140lm Filament {"NAME":"BulbBrite02","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Calex G125 7,5W 1055lm {"NAME":"Calex G125 E27","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} Calex G125 7.5W 1055lm Globe {"NAME":"Calex G125 E27","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Connect Smart GU5.3 5W {"NAME":"Connect CSH-GU53WW5W","GPIO":[0,0,0,0,37,38,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Connect SmartHome 10W 900lm {"NAME":"Connect CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} Deltaco SH-LE14W 470lm {"NAME":"SH-LE14W","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Deltaco SH-LE27W 810lm {"NAME":"SH-LE27W","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} DORESshop A60 720lm Filament {"NAME":"DORESshop-A60","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} @@ -58,8 +60,10 @@ Hama 806lm {"NAME":"Hama 00176550","GPIO":[0,0,0,0,0,37,0,0,0,38,0 Hykker SL-0392 650lm {"NAME":"Hykker 7W","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} Iotton 9W 700lm {"NAME":"Iotton Light","GPIO":[0,0,0,0,37,38,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Kogan 10W Cool & Warm White 1050lm {"NAME":"Kogan 10W CCT","GPIO":[0,0,0,0,0,37,0,0,0,47,0,0,0],"FLAG":0,"BASE":48} -Kogan 4.5W 330lm CCT {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Kogan 4.5W 330lm 110C {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} Kogan 5W {"NAME":"Kogan Co/Wa","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Laser 10W 1000lm {"NAME":"Laser 10W CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} +Laser 10W 1000lm {"NAME":"Laster 10W CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} LE lampUX 380lm Candle {"NAME":"LE Bulb","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} LE LampUX 4.5W 410lm {"NAME":"LE LampUX","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":48} ledscom.de 4.5W 430lm {"NAME":"GX53","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":0} @@ -70,7 +74,7 @@ Lumiman A19 7.5W 800lm {"NAME":"Lumiman LM520","GPIO":[0,0,0,0,0,37,0,0,38,0,0 Luminea ZX-2831 {"NAME":"Luminea CCT","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} LVWIT A60 6.5W 806lm Filament {"NAME":"LVWIT-E27-WiFi-6.5","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Merkury MI-BW905-999W 700lm {"NAME":"MI-BW905-999W","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Mimoodz 1050lm {"NAME":"ID Components","GPIO":[0,0,0,0,21,22,0,0,23,24,25,26,27],"FLAG":0,"BASE":18} +Mimoodz A21 10.5W 1050lm {"NAME":"Mimoodz","GPIO":[0,0,0,0,21,22,0,0,23,24,25,26,27],"FLAG":0,"BASE":18} Mirabella Genio 9W 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} Mirabella Genio 9W 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} Mirabella Genio 9W 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} @@ -82,11 +86,12 @@ Nedis A60 800lm {"NAME":"WIFILW10WTE27","GPIO":[0,0,0,0,0,37,0,0,38,0,0 Nedis C10 350lm {"NAME":"WIFILW10WTE14","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} Nedis G125 5.5W 350lm Twisted Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Nedis PAR16 330lm {"NAME":"Nedis WIFILW30","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Nedis PAR16 4.5W 330lm {"NAME":"WIFILW30","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Nedis PAR16 4.5W 330lm 110C {"NAME":"WIFILW30","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} Philips Zhirui Candle 250lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,38,0,0,37,0],"FLAG":0,"BASE":48} Phillips Zhirui 450lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,38,0,0,37,0],"FLAG":0,"BASE":48} SmartDGM L-WT9W1 9W 800lm {"NAME":"L-WT9W1","GPIO":[0,0,0,0,0,37,0,0,9,38,0,0,0],"FLAG":0,"BASE":18} Swisstone SH 330 806lm {"NAME":"SwisstoneSH330","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +V-Tac PAR16 4.5W 300lm 110C {"NAME":"V-TAC VT-5174","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} Vestaiot BR30 800lm {"NAME":"Vesta BR30 CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} Wipro Garnet NS9100 810lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,38,0,0,0,37,0,0,0,0],"FLAG":0,"BASE":18} Wyze WLPA19 A19 800lm {"NAME":"Wyze Bulb","GPIO":[0,0,0,0,0,0,0,0,0,37,38,0,0],"FLAG":0,"BASE":48} @@ -108,6 +113,7 @@ Teekar SYS-CS 01 {"NAME":"Teekar-Tag","GPIO":[56,0,157,18,22,11,0,0,0,21 Teepao {"NAME":"Taopao","GPIO":[255,255,255,18,22,19,0,0,255,21,255,255,17],"FLAG":1,"BASE":18} WF-CS01 {"NAME":"Tuya Shutter","GPIO":[157,0,54,10,22,19,0,0,17,21,53,23,52],"FLAG":0,"BASE":18} WF-CS02 {"NAME":"WF-CS02 Tuya","GPIO":[157,0,53,11,23,18,0,0,17,21,54,22,52],"FLAG":0,"BASE":18} +Zemismart {"NAME":"Zemismart","GPIO":[157,0,0,11,54,10,0,0,9,21,23,22,0],"FLAG":0,"BASE":18} ``` ## DIY @@ -195,7 +201,7 @@ EX-Store 2 Kanal RS232 V4 {"NAME":"EXS Dimmer","GPIO":[0,148,0,149,0,0,0,0,0,18 Feit Electric DIM/WIFI {"NAME":"Generic","GPIO":[255,107,255,108,255,255,0,0,255,0,255,0,255],"FLAG":0,"BASE":54} Gosund SW2 {"NAME":"Gosund Dimmer","GPIO":[255,148,255,149,17,0,255,255,56,158,37,255,255],"FLAG":0,"BASE":18} iSwitch Touch Switch {"NAME":"iSwitchOZ Dimmer","GPIO":[0,0,0,0,0,0,0,0,0,0,54,0,0],"FLAG":0,"BASE":54} -Martin Jerry MJ-SD01 {"NAME":"MJ-SD02","GPIO":[19,18,0,59,158,58,0,0,57,37,56,122,29],"FLAG":0,"BASE":73} +Martin Jerry SD01 {"NAME":"MJ-SD02","GPIO":[19,18,0,59,158,58,0,0,57,37,56,122,29],"FLAG":0,"BASE":73} Moes DS01-1 {"NAME":"MOES DS01","GPIO":[255,255,255,255,255,255,0,0,255,108,255,107,255],"FLAG":0,"BASE":54} Moes MS-105-1 v2 {"NAME":"MS-105","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} PS-16-DZ {"NAME":"PS-16-DZ","GPIO":[255,148,255,149,255,255,0,0,255,52,255,255,255],"FLAG":0,"BASE":58} @@ -204,6 +210,7 @@ RJWF-02A {"NAME":"RJWF-02A","GPIO":[17,107,0,108,0,0,0,0,0,0,52, Sonoff D1 {"NAME":"Sonoff D1","GPIO":[255,148,0,149,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":74} Teekar UIW001-1 {"NAME":"Teekar UIW001-","GPIO":[0,149,37,148,6,5,0,0,9,0,0,0,0],"FLAG":0,"BASE":18} Tessan MJ-SD02 {"NAME":"MJ-SD02","GPIO":[19,18,0,59,158,58,0,0,57,37,56,122,29],"FLAG":0,"BASE":73} +TopGreener TGWF500D {"NAME":"TopGreener-Dimmer","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} TreatLife DS01 {"NAME":"DS02S Dimmer","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} TreatLife DS02S {"NAME":"DS02S Dimmer","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} WF-DS01 {"NAME":"Dimmer WF-DS01","GPIO":[255,255,255,255,255,255,0,0,255,255,54,255,255],"FLAG":0,"BASE":54} @@ -223,6 +230,7 @@ Sichler Haushaltsgeraete Column {"NAME":"Sichler Fan","GPIO":[0,107,0,108,0,0,0 Sonoff IFan02 {"NAME":"Sonoff iFan02","GPIO":[17,255,0,255,23,22,18,19,21,56,20,24,0],"FLAG":0,"BASE":44} Sonoff IFan03 {"NAME":"SonoffiFan03","GPIO":[17,148,0,149,0,0,29,161,23,56,22,24,0],"FLAG":0,"BASE":71} Technical Pro FXA16 {"NAME":"FXA16 Fan","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +Zemismart Bladeless {"NAME":"Bladeless Fan","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} ``` ## IR Bridge @@ -264,10 +272,12 @@ Arilux AL-LC11 {"NAME":"Arilux LC11","GPIO":[17,0,59,0,38,37,0,0,41,40 Arilux SL-LC 03 {"NAME":"Arilux LC03","GPIO":[0,0,0,0,51,38,0,0,37,39,0,40,0],"FLAG":0,"BASE":34} Arilux SL-LC 09 {"NAME":"Arilux LC09","GPIO":[0,0,0,0,106,37,0,0,39,0,38,0,0],"FLAG":0,"BASE":18} CIN-03 96W RGB {"NAME":"CIN03-03 Strip","GPIO":[0,0,0,0,38,0,0,0,37,0,39,0,0],"FLAG":0,"BASE":18} +DD001-MINI(G)-IR-V03 {"NAME":"WIFI-RGB","GPIO":[17,0,0,0,0,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":40} DD001-MINI(G)-IR-V08 {"NAME":"WIFI-RGB","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Electrodragon ESP LED Strip Board, Mosfet Drive {"NAME":"LEDBoard RGBW","GPIO":[0,0,0,0,0,0,0,0,39,38,40,37,52],"FLAG":0,"BASE":18} H801 {"NAME":"H801","GPIO":[0,52,0,0,41,57,0,0,39,38,40,37,0],"FLAG":0,"BASE":20} Jinvoo SM-WA104 RGB {"NAME":"Jinvoo LED Controller","GPIO":[0,0,0,0,29,39,0,0,37,17,38,0,30],"FLAG":0,"BASE":18} +Konesky 12V RGB {"NAME":"RGBwifi","GPIO":[0,0,0,0,37,0,0,0,38,56,39,0,0],"FLAG":0,"BASE":18} LEDEnet {"NAME":"LEDEnet","GPIO":[0,255,56,255,147,41,0,0,38,39,37,40,0],"FLAG":0,"BASE":34} Luminea ZX-2844 {"NAME":"Luminea ZX-284","GPIO":[40,0,0,0,0,39,0,0,38,17,37,0,0],"FLAG":0,"BASE":18} Luminea ZX-2844-675 {"NAME":"ZX-2844-675","GPIO":[17,0,0,0,38,40,0,0,37,0,39,0,0],"FLAG":0,"BASE":18} @@ -298,6 +308,7 @@ Cocoon Smart {"NAME":"Cocoon Smart","GPIO":[17,0,0,0,37,0,0,0,38,0,3 Deltaco 3m RGBCCT {"NAME":"Deltaco Led Strip","GPIO":[0,0,0,0,37,17,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} electriQ 3m RGBCCT {"NAME":"ElectricQ wifiRGBWLEDSTR","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} Elfeland 10m RGB {"NAME":"Elfeland RGB","GPIO":[0,0,0,0,0,38,0,0,39,51,0,37,0],"FLAG":0,"BASE":18} +Geeni Prisma Plus {"NAME":"Geeni Prisma Plus Strip","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Gosund 2.8m RGB {"NAME":"Gosund LED Strip","GPIO":[17,0,0,0,0,0,0,0,37,39,38,0,0],"FLAG":3,"BASE":18} HitLights L1012V-MC1 {"NAME":"HitLights RBG","GPIO":[17,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} HomeMate 10m RGB {"NAME":"Homemate Strip","GPIO":[0,0,0,0,0,37,0,0,39,17,38,0,0],"FLAG":0,"BASE":18} @@ -371,6 +382,7 @@ Mirabella Genio I002742 {"NAME":"GenioDLightCCT","GPIO":[0,0,0,0,0,0,0,0,38,0,3 Mirabella Genio I002798 Warm White Filament Festoon {"NAME":"GenioFestoon","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} Moes 7W RGBCCT Downlight {"NAME":"Moes Downlight","GPIO":[0,0,0,0,40,41,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} Novostella UT88835 20W Floodlight {"NAME":"Novo 20W Flood","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Reafoo A27 9W 810lm {"NAME":"ReaFooE27","GPIO":[0,0,0,0,41,40,0,0,37,0,39,38,0],"FLAG":0,"BASE":18} SMRTLite LED Panel {"NAME":"SMRTLite","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Sonoff BN-SZ01 {"NAME":"Sonoff BN-SZ","GPIO":[0,0,0,0,0,0,0,0,37,56,0,0,0],"FLAG":0,"BASE":22} Spotlight 9cm RGB+W 7W {"NAME":"Spotlight RGBW","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} @@ -425,6 +437,7 @@ HA109US {"NAME":"HA109US","GPIO":[17,0,0,0,52,53,0,0,21,0,22,0, iClever IC-BS06 {"NAME":"iClever Switch","GPIO":[0,0,0,0,157,56,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} King-Link C128 {"NAME":"King-Link C128","GPIO":[0,0,58,0,22,56,0,0,23,157,17,21,57],"FLAG":0,"BASE":18} Kogan Energy Meter IP44 {"NAME":"Kogan Smart Sw IP44","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} +Koolertron {"NAME":"C168 Outdoor","GPIO":[0,17,0,56,134,132,0,0,21,131,22,23,0],"FLAG":0,"BASE":18} LEPOWER {"NAME":"LEPOWER Outdoo","GPIO":[255,255,255,255,56,57,0,0,21,17,22,255,255],"FLAG":0,"BASE":18} Luminea NX-4458 {"NAME":"Luminea NX4458","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":65} Maxcio EOP03-EU {"NAME":"Maxcio EOP03-EU","GPIO":[0,0,0,0,22,57,0,0,21,52,17,0,58],"FLAG":0,"BASE":18} @@ -479,6 +492,7 @@ Anoopsyche AWP08L {"NAME":"AWP08L-Annopsy","GPIO":[0,0,0,0,17,56,0,0,21,0 Anoopsyche SP-G01 {"NAME":"SP-G01","GPIO":[0,145,0,146,0,0,0,0,17,56,21,0,0],"FLAG":0,"BASE":41} Anoopsyche SP15 {"NAME":"Anoop SP15","GPIO":[0,0,0,0,56,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} Anoopsyche UK1D {"NAME":"UK1D","GPIO":[0,17,0,0,133,132,0,0,130,52,21,0,0],"FLAG":0,"BASE":6} +AOFO 10A {"NAME":"AOFO Smart Plug Wifi","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Aoycocr EU5 16A {"NAME":"Aoycocr","GPIO":[255,0,56,0,0,0,0,0,255,17,0,21,0],"FLAG":0,"BASE":17} Aoycocr EU6S {"NAME":"Aoycocr EU6S","GPIO":[255,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":17} Aoycocr U2S {"NAME":"Aoycocr U2S","GPIO":[56,0,57,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} @@ -511,7 +525,7 @@ Avatar AWP14H {"NAME":"Avatar UK 10A","GPIO":[0,0,56,0,0,134,0,0,131, Avatto JH-G01E {"NAME":"AVATTO JH-G01E","GPIO":[0,145,0,146,0,0,0,0,17,56,21,0,0],"FLAG":0,"BASE":41} Avatto NAS-WR01W 10A {"NAME":"AvattoNAS-WR01W","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Avatto OT06 16A {"NAME":"Avatto OT06","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} -Avatto OT08 {"NAME":"Avatto OT08","GPIO":[37,0,39,0,38,134,0,0,130,17,132,21,0],"FLAG":0,"BASE":18} +Avatto OT08 {"NAME":"Avatto OT08","GPIO":[37,0,39,0,38,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} Awow EU3S {"NAME":"AWOW BSD33","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} Awow X5P {"NAME":"Awow","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} AWP02L-N {"NAME":"AWP02L-N","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} @@ -532,7 +546,7 @@ BlitzWolf BW-SHP6 10A {"NAME":"BW-SHP6 10A","GPIO":[158,255,56,255,0,134,0,0, Blitzwolf BW-SHP6 15A {"NAME":"Blitzwolf SHP6","GPIO":[56,255,158,255,132,134,0,0,131,17,0,21,0],"FLAG":0,"BASE":45} BlitzWolf BW-SHP7 {"NAME":"SHP7","GPIO":[17,158,57,131,134,132,0,0,18,56,21,0,22],"FLAG":0,"BASE":45} BN-LINK BNC-60/U133TJ-2P {"NAME":"BNC-60/U133TJ","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":18} -BNETA IoT {"NAME":"BNETA WifiPlug","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} +BNETA IO-WIFI-PlugSA {"NAME":"BNETA WifiPlug","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} Brennenstuhl WA 3000 XS01 {"NAME":"WA 3000 XS01","GPIO":[0,0,0,0,21,17,0,0,158,52,0,0,0],"FLAG":0,"BASE":61} Bright {"NAME":"Bright Wi-Fi Smart Plug","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} Brilliant HK17654S05 {"NAME":"HK17654S05","GPIO":[17,255,255,255,133,132,255,255,131,56,21,255,255],"FLAG":0,"BASE":18} @@ -559,6 +573,7 @@ Coosa {"NAME":"COOSA","GPIO":[0,0,0,0,57,52,0,0,21,17,255,0,0 Coosa SP1 {"NAME":"COOSA SP1","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} CrazyLynX WiFi {"NAME":"CrazyLynX","GPIO":[0,0,0,0,57,56,0,0,21,17,0,0,0],"FLAG":1,"BASE":18} CYYLTF BIFANS J23 {"NAME":"CYYLTD BIFANS J23","GPIO":[56,0,0,0,0,0,0,0,21,17,0,0,0],"FLAG":1,"BASE":18} +D3D Smart Plug with USB & Power Monitor {"NAME":"D3D d_SUM","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} DE-1 16A {"NAME":"DE-1","GPIO":[0,17,0,0,133,0,0,0,0,52,21,0,0],"FLAG":1,"BASE":18} DeLock 11826 {"NAME":"DeLock 11826","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":1} Deltaco SH-P01 {"NAME":"DELTACO SH-P01","GPIO":[0,0,0,0,0,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} @@ -651,6 +666,7 @@ iClever IC-BS08 {"NAME":"iClever BS08","GPIO":[0,0,0,0,157,56,0,0,21,17 iDIGITAL {"NAME":"Brilliant","GPIO":[0,0,0,0,52,0,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} Ihommate ZCH-02 {"NAME":"ZCH-02","GPIO":[0,0,0,17,133,132,0,0,130,56,21,0,0],"FLAG":1,"BASE":18} Infray 16A {"NAME":"AWP08L","GPIO":[17,0,52,0,0,0,0,0,0,0,0,21,0],"FLAG":1,"BASE":18} +Insmart WP5 {"NAME":"INSMART","GPIO":[0,0,46,0,0,0,0,0,0,9,0,21,0],"FLAG":0,"BASE":18} iSwitch {"NAME":"Smart Plug XSA","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":0,"BASE":18} Jeeo TF-SH330 {"NAME":"Jeeo TF-SH330","GPIO":[56,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":1,"BASE":18} Jeeo TF-SH331W {"NAME":"Jeeo SH331W","GPIO":[56,0,158,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} @@ -658,6 +674,7 @@ Jinli XS-SSA01 {"NAME":"JINLI","GPIO":[0,0,0,0,0,0,0,0,56,17,0,21,0]," Jinvoo SM-PW701U {"NAME":"SM-PW702","GPIO":[0,0,0,0,57,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Jinvoo SM-PW712UA 10A {"NAME":"SM-PW712UA","GPIO":[0,0,0,158,56,57,0,0,22,17,21,0,0],"FLAG":15,"BASE":18} Jinvoo SM-PW762U {"NAME":"SM-PW762U","GPIO":[0,0,0,0,158,56,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} +Jomarto SH0617 {"NAME":"Jomarto SH0617","GPIO":[57,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Jomarto SH1123 {"NAME":"SH1123","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Jules V (Upgrade Version) {"NAME":"Jules-V_UV","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57,131],"FLAG":0,"BASE":18} JULES.V NX-SM200 V1.3 {"NAME":"NX-SM200","GPIO":[52,0,0,131,0,134,0,0,0,17,132,21,0],"FLAG":1,"BASE":45} @@ -710,6 +727,7 @@ Merkury MI-WW105-199W {"NAME":"Merkury Switch","GPIO":[255,255,255,255,158,56 Minleaf W-DEXI {"NAME":"W-DEXI","GPIO":[0,17,0,0,134,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} Mirabella Genio 1002341 {"NAME":"Genio 1","GPIO":[0,0,56,0,0,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} Mirabella Genio USB {"NAME":"Mirabella Genio 1002826","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":1} +Mirabella Genio USB Port and Plug {"NAME":"Genio I002341","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} Mistral {"NAME":"Mistral Smart ","GPIO":[56,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Moes NX-SP203 {"NAME":"Moes NX-SP203","GPIO":[52,0,0,0,17,134,0,0,21,18,0,22,0],"FLAG":0,"BASE":18} Moes W-DE004S {"NAME":"Moes DE004S ","GPIO":[57,0,0,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} @@ -722,6 +740,7 @@ Nedis P130 {"NAME":"WIFIP130FWT","GPIO":[0,0,0,0,56,57,0,0,21,17,0 NEO Coolcam NAS-WR01W {"NAME":"NAS-WR01W","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} NEO Coolcam NAS-WR01W 16A {"NAME":"Neo Coolcam 16","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} NETVIP XS-SSA01 {"NAME":"XS-SSA01","GPIO":[0,0,0,0,0,0,0,0,56,17,0,21,0],"FLAG":0,"BASE":18} +Nightlight and AC Outlet {"NAME":"SWN03","GPIO":[17,0,0,0,0,0,255,255,37,0,0,21,0],"FLAG":0,"BASE":18} Nishica SM-PW701I {"NAME":"SM-PW701I","GPIO":[255,255,255,255,255,255,255,255,21,52,17,255,255],"FLAG":15,"BASE":18} NX-SM112 {"NAME":"NX-SM112v3","GPIO":[0,0,0,0,134,132,0,0,158,17,130,21,0],"FLAG":0,"BASE":45} NX-SM200 {"NAME":"NX-SM200","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57,131],"FLAG":0,"BASE":18} @@ -751,10 +770,12 @@ Prime CCRCWFII113PK {"NAME":"Prime","GPIO":[0,0,0,0,57,56,0,0,21,122,0,0,0] Prime RCWFII11 {"NAME":"Prime Plug","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} PrimeCables Cab-LA-WF4 {"NAME":"Mini Smart Outlet Wifi Socket with Timer Function","GPIO":[0,0,0,56,57,0,0,0,0,0,0,21,17],"FLAG":0,"BASE":18} qnect 16A {"NAME":"QNECT QN-WP01E","GPIO":[0,0,0,17,133,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} +Qualitel Mini {"NAME":"Qualitel HG01WT","GPIO":[56,0,57,0,0,133,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} RenPho RF-SM004 {"NAME":"RenPho RFSM004","GPIO":[0,0,0,0,157,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Robaxo {"NAME":"Robaxo RSP-025","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} RSH-WS007-EU {"NAME":"RSH-WS007","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":1,"BASE":18} S126 {"NAME":"tuya-plug","GPIO":[0,0,0,0,0,0,0,0,21,20,0,0,0],"FLAG":0,"BASE":8} +Sansui {"NAME":"Sansui YSP-1","GPIO":[52,0,53,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Shelly Plug S {"NAME":"Shelly Plug S","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":2,"BASE":45} Silvergear Slimme Stekker {"NAME":"Silvergear SmartHomePlug","GPIO":[0,0,0,122,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} SimpleHome {"NAME":"SimpleHome","GPIO":[53,0,0,0,0,0,0,0,21,56,17,0,0],"FLAG":0,"BASE":1} @@ -800,6 +821,7 @@ Teckin SP22 {"NAME":"Teckin","GPIO":[0,17,0,57,134,132,0,0,131,56,2 Teckin SP23 {"NAME":"Teckin SP23","GPIO":[56,255,57,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} Teckin SP25 {"NAME":"Teckin SP25","GPIO":[56,255,255,255,255,255,0,0,22,17,255,21,255],"FLAG":1,"BASE":18} Teckin SP27 {"NAME":"Teckin SP27","GPIO":[56,255,255,255,255,255,0,0,255,17,255,21,255],"FLAG":0,"BASE":18} +Tellur 16A 2 Ports {"NAME":"Tellur WiFi Smart Socket","GPIO":[18,0,0,131,134,132,0,0,157,21,22,0,17],"FLAG":0,"BASE":18} Tflag NX-SM100 {"NAME":"NX-SM100","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57,131],"FLAG":0,"BASE":18} TikLok TL650 {"NAME":"TikLok Mini","GPIO":[0,0,0,0,57,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Timethinker C338 {"NAME":"C338","GPIO":[17,0,255,0,0,0,0,0,21,52,255,0,0],"FLAG":0,"BASE":1} @@ -828,6 +850,7 @@ WAZA 10A {"NAME":"WAZA","GPIO":[0,0,0,0,21,17,0,0,56,0,0,0,0],"F WAZA JH-G01B {"NAME":"Teckin SP27","GPIO":[255,255,255,255,53,255,0,0,21,17,255,255,255],"FLAG":0,"BASE":18} WAZA JH-G01E 10A {"NAME":"Waza JH-G01E","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":1,"BASE":18} Waza JH-G01E 16A {"NAME":"Waza JH-G01E 2","GPIO":[0,0,0,0,0,0,0,0,17,52,21,0,0],"FLAG":1,"BASE":18} +Wily Electronics {"NAME":"VC Plug","GPIO":[157,0,0,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} WiOn 50055 {"NAME":"WiOn","GPIO":[255,0,52,0,0,0,0,0,255,17,0,21,0],"FLAG":0,"BASE":17} Wisdom ZY_ACU02 {"NAME":"ZY-ACU02","GPIO":[0,0,0,157,22,21,0,0,56,17,57,0,0],"FLAG":0,"BASE":18} WL-SC01 {"NAME":"WL-SC01","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":1} @@ -870,7 +893,7 @@ ZSP-001 {"NAME":"ZSP-001","GPIO":[17,255,255,255,133,132,0,0,13 ``` A0F0 ZLD-44EU-W {"NAME":"AOFO-4AC-4USB","GPIO":[0,56,0,17,22,21,0,0,23,24,33,0,0],"FLAG":1,"BASE":18} Acenx 3AC+3USB {"NAME":"ACENX 3-Outlet","GPIO":[56,55,54,53,0,21,0,0,23,24,22,0,17],"FLAG":0,"BASE":18} -AHRise 4+4AC+4USB {"NAME":"AHRise-083","GPIO":[0,0,0,0,52,17,0,0,22,21,23,24,0],"FLAG":0,"BASE":18} +AHRise 4+4AC+4USB {"NAME":"AHRise-083","GPIO":[0,0,0,0,56,17,0,0,22,21,23,24,0],"FLAG":0,"BASE":18} AHRise AHR-085 {"NAME":"AHRise AHR-085","GPIO":[0,0,0,0,17,56,0,0,22,23,21,0,0],"FLAG":0,"BASE":18} Annhome 3AC + 2USB {"NAME":"1200W WiFi SPS","GPIO":[32,0,0,0,57,52,0,0,21,17,22,23,33],"FLAG":0,"BASE":18} AOFO 3AC+4USB {"NAME":"AOFO","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0,0],"FLAG":1,"BASE":18} @@ -902,6 +925,7 @@ Hyleton 330 {"NAME":"Hyleton-330","GPIO":[57,0,0,56,29,17,0,0,31,30 Hyleton 331 {"NAME":"HLT-331","GPIO":[52,255,255,57,29,17,0,0,31,30,32,255,58],"FLAG":0,"BASE":18} Hyleton 333 {"NAME":"HLT-333","GPIO":[52,0,0,57,29,17,0,0,31,30,0,0,24],"FLAG":0,"BASE":18} Hyleton 336 {"NAME":"HLT-336","GPIO":[52,0,0,57,29,17,0,0,31,30,0,0,32],"FLAG":0,"BASE":18} +Jinvoo 4AC+2USB {"NAME":"JINVOO Model SM-SO306-2A","GPIO":[56,0,0,0,32,17,0,0,30,31,29,0,25],"FLAG":0,"BASE":18} KMC 5 {"NAME":"KMC 5-Outlet","GPIO":[56,0,0,0,25,9,0,0,22,21,23,0,24],"FLAG":0,"BASE":18} Kogan Power Strip USB Ports & Energy Meter {"NAME":"Generic","GPIO":[90,56,0,24,134,132,0,0,131,22,23,21,0],"FLAG":0,"BASE":18} Konesky Type 1 {"NAME":"Konesky","GPIO":[0,0,0,0,25,22,0,0,24,17,23,21,0],"FLAG":0,"BASE":18} @@ -1009,6 +1033,7 @@ Globe A19 10W 800lm {"NAME":"GlobeRGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39 Helloify BR30 9W 600lm {"NAME":"Helloify","GPIO":[255,255,255,255,37,40,255,255,38,41,39,255,255],"FLAG":0,"BASE":18} HIPER IoT A61 {"NAME":"HIPER IoT A61","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} HIPER IoT C1 {"NAME":"Hiper IoT C1 RGB","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +Holdpeak BR40 12W 1100lm {"NAME":"HP-BR40-12W","GPIO":[0,0,0,0,140,37,0,0,38,0,141,0,0],"FLAG":0,"BASE":18} Infray 9W 900LM {"NAME":"InfrayRGBCCT","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Jeeo TF-QPZ13 800lm {"NAME":"Jeeo","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} Julun JL-021 5W Candle {"NAME":"E14 RGBCCT","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} @@ -1042,10 +1067,12 @@ LVWIT A70 12W 1521lm {"NAME":"LVWIT A70 12W","GPIO":[0,0,0,0,37,40,0,0,38,50 LVWIT BR30 8.5W 650lm {"NAME":"LVWIT BR30 8.5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} LVWIT G45 5W 470Lm {"NAME":"LVWIT E14 5W G45 RGBWCCT","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} MagicHome 7W {"NAME":"MagicHome E27","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Moes 9W 800lm {"NAME":"Moes 9w","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Nishica JBT 9W 806lm {"NAME":"Nishica","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Novostella 7W 600lm {"NAME":"Novostella E27","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Novostella 7W 600lm {"NAME":"Novostella B22","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} Novostella HM-LB09 13W 1300lm {"NAME":"Novostella 13W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Novostella NTB10 9W 900lm {"NAME":"NTB10","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} -Novostella UT55505 7W 600lm {"NAME":"Novostella B22","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} Novostella UT55507 9W 900lm {"NAME":"Novostella UT55507","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Novostella UT55507 9W 900lm {"NAME":"Novostella UT55507","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Novostella UT55508 12W 1150lm {"NAME":"Novostella","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} @@ -1074,7 +1101,7 @@ Techlux A19 9W 806lm {"NAME":"TECHLUX A19 RGBCW 806lm 9w","GPIO":[0,0,0,0,37 Teckin SB50 v3 A19 800lm {"NAME":"Teckin SB50v3","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Teckin SB53 1300lm {"NAME":"Teckin SB53","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Treatlife A19 8W 650lm {"NAME":"Treatlife RGBW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -V-Tac PAR16 4.5W 400lm {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +V-Tac PAR16 4.5W 400lm 100C {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} Vizia 5W GU10 {"NAME":"Vizia RGBWW","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":15,"BASE":18} Wipro Garnet 9W 810lm {"NAME":"Wipro","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Zemismart 5W 480lm {"NAME":"Zemismart 5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} @@ -1173,6 +1200,7 @@ Merkury MI-BW904-999W 1050lm {"NAME":"MI-BW904-999W","GPIO":[0,0,0,0,140,37,0,0 Merkury MI-BW904-999W v2 1050lm {"NAME":"MI-BW210-999W","GPIO":[0,0,0,0,38,37,0,0,141,142,140,0,0],"FLAG":0,"BASE":48} Merkury MI-BW904-999W v3 {"NAME":"MI-BW904-999W","GPIO":[0,0,0,0,37,38,0,0,141,142,140,0,0],"FLAG":0,"BASE":69} Merkury MI-BW906-999W BR30 750lm {"NAME":"MI-BW906-999W","GPIO":[0,0,0,0,38,37,0,0,141,142,140,0,0],"FLAG":0,"BASE":18} +Mimoodz A19 6.5W {"NAME":"Miimoodz RGBCW LED","GPIO":[0,0,0,0,180,0,0,0,0,0,181,0,0],"FLAG":0,"BASE":18} Mirabella Genio 9W 800lm {"NAME":"GenioBulbRGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Mirabella Genio 9W 800lm {"NAME":"GenioBulbRGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Mirabella Genio 9W 800lm {"NAME":"MiraBellaGenio","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} @@ -1203,6 +1231,7 @@ Swisstone SH 320 350lm {"NAME":"SH 320","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0] Swisstone SH 340 806lm {"NAME":"SH 340","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":15,"BASE":18} Syska 720lm {"NAME":"SyskaSmartBulb","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} TCP Smart 806lm {"NAME":"TCP Smart RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Teckin 7.5W 800lm {"NAME":"Teckin SB60","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Teckin SB50 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} Teckin SB50 v2 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,37,0,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} Teckin SB51 800lm {"NAME":"Teckin SB51","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} @@ -1228,8 +1257,9 @@ Zilotek A19 800lm {"NAME":"Zilotek RGBW","GPIO":[0,0,0,0,140,37,0,0,38,14 Anmbest 2 Channel Inching Self-locking Switch Module {"NAME":"Generic","GPIO":[17,255,255,255,255,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":1} ATMS1601 230VAC DIN Timer/Switch {"NAME":"ATMS1601","GPIO":[255,255,255,255,157,56,255,255,21,17,255,255,255],"FLAG":15,"BASE":18} BlitzWolf BW-SS1 {"NAME":"BW-SS1","GPIO":[255,255,255,255,157,21,0,0,255,17,255,255,0],"FLAG":0,"BASE":18} +BlitzWolf BW-SS5 1 Gang {"NAME":"BlitzWolf SS5 1 Gang","GPIO":[0,0,0,0,0,0,0,0,9,21,0,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-SS5 2 Gang {"NAME":"BlitzWolf SS5 2 Gang","GPIO":[0,0,0,0,160,0,0,0,43,42,21,22,0],"FLAG":0,"BASE":18} -BlitzWolf SS4 Two Gang {"NAME":"BlitzWolf SS4","GPIO":[0,0,0,0,56,21,0,0,22,17,0,0,0],"FLAG":0,"BASE":18} +BlitzWolf SS4 {"NAME":"BlitzWolf SS4 Two Gang","GPIO":[0,0,0,0,56,21,0,0,22,17,0,0,0],"FLAG":0,"BASE":18} Canwing CW-001 {"NAME":"Canwing CW-001","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} Century Aoke Smart Switch {"NAME":"CenturyAoke","GPIO":[0,255,0,255,21,0,0,0,17,56,255,0,0],"FLAG":0,"BASE":18} Deta 6000HA Smart Inline Switch {"NAME":"DETA-6000HA","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} @@ -1314,6 +1344,7 @@ Lenovo Rechargable PIR Motion {"NAME":"Lenovo PIR","GPIO":[255,107,255,108,255, Mirabella Genio I002576 Motion {"NAME":"GenioPir","GPIO":[17,107,0,108,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":54} Natural Gas (CH4) Alarm {"NAME":"PA-210WYS","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} Nedis Smoke Detector {"NAME":"Nedis Smoke","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +Shelly i3 Action and Scenes Activation Device {"NAME":"Shelly i3","GPIO":[0,0,0,0,0,0,0,0,83,84,82,0,0],"FLAG":0,"BASE":18} Shelly Temperature Sensor Add-on {"NAME":"Shelly 1 Temp ","GPIO":[192,0,0,4,21,82,0,0,0,0,0,0,0],"FLAG":0,"BASE":46} Smoke Alarm {"NAME":"YG400A","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} Sonoff SC {"NAME":"Sonoff SC","GPIO":[17,148,255,149,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":21} @@ -1324,6 +1355,7 @@ Zemismart Door Window {"NAME":"Zemismart","GPIO":[255,107,255,108,255,255,0,0 ## Switch ``` 3A Smart Home HGZB-043 {"NAME":"3A Smart Home ","GPIO":[52,0,55,18,22,19,0,0,17,21,54,23,53],"FLAG":0,"BASE":18} +AGL 3 Gang {"NAME":"AGL WiFi 03","GPIO":[0,0,56,0,19,18,0,0,22,21,23,0,17],"FLAG":0,"BASE":18} Aoycocr SW1 {"NAME":"Aoycocr SW1","GPIO":[158,255,57,255,255,255,255,255,56,17,255,21,255],"FLAG":15,"BASE":18} Avatto 2 Gang {"NAME":"Avatto Wifi - ","GPIO":[0,0,52,0,0,17,0,0,21,22,0,0,18],"FLAG":0,"BASE":18} Avatto Fan Light {"NAME":"AVATTO Smart Wifi Fan Light","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} @@ -1365,6 +1397,7 @@ Girier JRSWR-US01 No Neutral 3 Gang {"NAME":"Girier JRSWR-U","GPIO":[0,0,0,0,21 GoKlug Glass Touch 1 Gang {"NAME":"GoKlug 1x","GPIO":[56,57,0,0,0,9,0,0,0,0,0,21,0],"FLAG":0,"BASE":18} Gosund KS-602S {"NAME":"Gosund KS-602S","GPIO":[17,0,56,0,0,0,0,0,0,0,21,0,158],"FLAG":0,"BASE":18} Gosund SW1 {"NAME":"Gosund SW1","GPIO":[17,0,57,0,0,0,0,0,0,0,21,0,56],"FLAG":0,"BASE":18} +Gosund SW6 3-Way {"NAME":"Gosund SW6","GPIO":[17,0,56,0,9,0,0,0,0,0,22,21,158],"FLAG":0,"BASE":18} Hama Flush-mounted {"NAME":"Hama WiFiTouch","GPIO":[157,0,0,0,0,18,0,0,17,22,0,21,0],"FLAG":0,"BASE":45} HBN Wall-Mounted Timer {"NAME":"HBN Timer Switch","GPIO":[0,0,0,0,54,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Innens 1 Gang 1 Way {"NAME":"Innens 1 Gang 1 Way","GPIO":[0,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} @@ -1400,8 +1433,7 @@ LX-WIFI-00M 4 Gang {"NAME":"LX-WIFI-00M","GPIO":[17,25,255,255,23,22,18,19 MakeGood 2 Gang {"NAME":"MakeGood 2 Gang","GPIO":[0,0,0,0,0,0,0,0,0,0,54,0,0],"FLAG":0,"BASE":54} MakeGood 4 Gang {"NAME":"MakeGood 4 Gang","GPIO":[0,0,0,0,0,0,0,0,0,0,54,0,0],"FLAG":0,"BASE":54} Markevina KS-602S {"NAME":"Markevina KS-6","GPIO":[17,255,0,255,0,0,0,0,21,52,0,0,0],"FLAG":0,"BASE":18} -Martin Jerry 3 Way {"NAME":"MJ 3Way Switch","GPIO":[0,0,0,0,52,53,0,0,21,9,157,0,0],"FLAG":0,"BASE":18} -Martin Jerry MJ-S01 15A {"NAME":"MJ Switch","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Martin Jerry S01 15A {"NAME":"MJ-S01 Switch","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Martin Jerry ST01 3 Way {"NAME":"MJ 3Way Switch","GPIO":[255,255,255,255,52,53,0,0,21,9,157,255,0],"FLAG":0,"BASE":18} Merkury MI-WW107-199W {"NAME":"MI-WW107-199W","GPIO":[52,0,0,0,0,0,0,0,17,21,0,0,0],"FLAG":0,"BASE":18} Micmi K38 {"NAME":"KS-605","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":18} @@ -1434,6 +1466,9 @@ NaamaSmart KS602 {"NAME":"KS-602","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0] Nedis Dual {"NAME":"SM-SW102U-2","GPIO":[158,0,0,18,22,0,0,0,17,21,0,0,0],"FLAG":1,"BASE":18} Nexete DS-123 {"NAME":"DS-123","GPIO":[157,57,255,17,21,18,0,0,255,22,56,255,255],"FLAG":0,"BASE":18} Nexete DS-123 Single {"NAME":"DS-123","GPIO":[157,0,255,18,0,17,0,0,255,21,56,255,255],"FLAG":0,"BASE":18} +Qualitel 1 Gang {"NAME":"Qualitel 1 Gang","GPIO":[157,0,0,9,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} +Qualitel 2-Gang {"NAME":"Qualitel 2 Gang","GPIO":[157,0,53,0,0,10,0,0,9,21,0,22,52],"FLAG":0,"BASE":18} +Qualitel 3 Gang {"NAME":"Qualitel 3 Gang","GPIO":[157,0,54,10,22,11,0,0,9,21,53,23,52],"FLAG":0,"BASE":18} RY-RSM104 Light Touch {"NAME":"RY-RSM104","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Sainko 1-Way {"NAME":"SAINKO 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} Sainko 2 Way {"NAME":"Sainko 2-Way","GPIO":[0,255,56,0,0,17,0,0,21,22,0,0,18],"FLAG":0,"BASE":18} @@ -1474,6 +1509,7 @@ Teekar 10 Way 1 Gang {"NAME":"Teekar 10way","GPIO":[9,10,11,20,13,14,0,0,15, Teekar Wi-Fi Light 1 Gang {"NAME":"TeeKar Touch","GPIO":[0,0,255,0,255,21,0,0,0,255,17,0,255],"FLAG":0,"BASE":18} Teepao Smart-Rollladen-Schalter {"NAME":"Teepao","GPIO":[158,58,23,18,22,19,0,0,56,21,57,0,17],"FLAG":0,"BASE":18} Tonbux AMZ180648-2 {"NAME":"Tonbux","GPIO":[17,255,255,255,255,0,0,0,21,56,255,0,0],"FLAG":0,"BASE":1} +TopGreener TGWF15S {"NAME":"TopGreener-Switch","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} Touch 2 Gang {"NAME":"tuya_2_gang","GPIO":[52,0,0,0,18,0,0,0,17,21,255,22,29],"FLAG":0,"BASE":18} Touch 3 Gang {"NAME":"Switch 3-Gang","GPIO":[0,0,0,0,23,18,0,0,17,21,19,22,157],"FLAG":0,"BASE":18} Treatlife SS01 3-Way {"NAME":"Treatlife SS01 3-Way","GPIO":[0,0,0,0,21,158,0,0,22,18,9,0,0],"FLAG":0,"BASE":18} @@ -1508,7 +1544,7 @@ ZUCZUG 3 Gang {"NAME":"2ph105626a x3","GPIO":[0,52,0,17,19,18,0,0,22, ## Valve ``` -Garden Water Timer BQ05 {"NAME":"BQ05","GPIO":[255,255,255,255,255,255,0,0,255,255,255,21,22],"FLAG":1,"BASE":18} +Garden Water Timer BQ05 {"NAME":"BQ05","GPIO":[17,0,0,0,0,0,0,0,21,157,0,0,0],"FLAG":1,"BASE":18} Hoenyzy DN20 3/4 {"NAME":"DN20 Valve","GPIO":[0,0,0,0,0,0,0,0,17,21,0,0,0],"FLAG":0,"BASE":18} Jinvoo SM-AW713 {"NAME":"Jinvoo Valve","GPIO":[0,0,0,0,0,52,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Jinvoo SM-AW713 v2 {"NAME":"Jinvoo Valve v2","GPIO":[0,0,0,0,52,53,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} @@ -1547,5 +1583,5 @@ Vigica VGSPK00815 {"NAME":"VIGICA outlet","GPIO":[17,255,255,255,255,22,1 ## Zigbee Bridge ``` -Sonoff ZBBridge {"NAME":"Sonoff ZBBridge","GPIO":[56,165,0,166,59,58,0,0,0,158,0,0,17],"FLAG":0,"BASE":18} +Sonoff ZBBridge {"NAME":"Sonoff ZbBridge","GPIO":[56,165,0,166,215,0,0,0,0,158,0,0,17],"FLAG":0,"BASE":75} ``` From c47d8d03a5c64d8a1dce3d986ed4b3a2ffcd784a Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 29 Jul 2020 10:02:04 +0200 Subject: [PATCH 576/581] Change Zigbee randomizing of parameters at first run or after Reset --- tasmota/CHANGELOG.md | 1 + tasmota/my_user_config.h | 6 --- tasmota/tasmota_configurations.h | 5 --- tasmota/xdrv_23_zigbee_0_constants.ino | 41 ++++++++++++++++++++ tasmota/xdrv_23_zigbee_7_statemachine.ino | 47 +++++++++-------------- tasmota/xdrv_23_zigbee_8_parsers.ino | 46 ++++++++-------------- tasmota/xdrv_23_zigbee_9_serial.ino | 3 ++ tasmota/xdrv_23_zigbee_A_impl.ino | 33 +++++++++++----- 8 files changed, 103 insertions(+), 79 deletions(-) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index d30040e93..939aad6ac 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -11,6 +11,7 @@ - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 - Add command (``S``)``SerialSend6`` \ (#8937) - Change ``Ping`` now reports the hostname instead of IP address (#8948) +- Change Zigbee randomizing of parameters at first run or after Reset ### 8.3.1.6 20200617 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index d7dd6b2cc..fff58d480 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -684,14 +684,8 @@ #define USE_ZIGBEE_ZNP // Enable ZNP protocol, needed for CC2530 based devices // #define USE_ZIGBEE_EZSP // [EXPERIMENTAL - DO NOT USE] Enable EZSP protocol, needed for EFR32 EmberZNet based devices, like Sonoff Zigbee bridge // Note: USE_ZIGBEE_ZNP and USE_ZIGBEE_EZSP are mutually incompatible, you must select exactly one - #define USE_ZIGBEE_PANID 0x1A63 // arbitrary PAN ID for Zigbee network, must be unique in the home - // if PANID == 0xFFFF, then the device will act as a Zigbee router, the parameters below are ignored - // if PANID == 0xFFFE, then the device will act as a Zigbee end-device (non-router), the parameters below are ignored - #define USE_ZIGBEE_EXTPANID 0xCCCCCCCCCCCCCCCCL // arbitrary extended PAN ID #define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26) #define USE_ZIGBEE_TXRADIO_DBM 20 // Tx Radio power in dBm (only for EZSP, EFR32 can go up to 20 dBm) - #define USE_ZIGBEE_PRECFGKEY_L 0x0F0D0B0907050301L // note: changing requires to re-pair all devices - #define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices #define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms) #define USE_ZIGBEE_MODELID "Tasmota Z2T" // reported "ModelId" (cluster 0000 / attribute 0005) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index da1248f6e..2ee368d84 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -537,12 +537,7 @@ #undef USE_ZIGBEE_ZNP #define USE_ZIGBEE_EZSP #define USE_TCP_BRIDGE - #define USE_ZIGBEE_PANID 0x1A63 // arbitrary PAN ID for Zigbee network, must be unique in the home - #define USE_ZIGBEE_EXTPANID 0xCCCCCCCCCCCCCCCCL // arbitrary extended PAN ID #define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26) - #define USE_ZIGBEE_PRECFGKEY_L 0x0F0D0B0907050301L // note: changing requires to re-pair all devices - #define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices - #define USE_ZIGBEE_PERMIT_JOIN false // don't allow joining by default #define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms) diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index c24e5c091..62b3652af 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -1131,6 +1131,47 @@ String getZDPStatusMessage(uint8_t status) { return String(msg); } +String getEmberStatus(uint8_t status) { + static const char StatusMsg[] PROGMEM = "SUCCESS|ERR_FATAL|BAD_ARGUMENT|EEPROM_MFG_STACK_VERSION_MISMATCH|INCOMPATIBLE_STATIC_MEMORY_DEFINITIONS|EEPROM_MFG_VERSION_MISMATCH|EEPROM_STACK_VERSION_MISMATCH" + "|NO_BUFFERS|SERIAL_INVALID_BAUD_RATE|SERIAL_INVALID_PORT|SERIAL_TX_OVERFLOW|SERIAL_RX_OVERFLOW|SERIAL_RX_FRAME_ERROR|SERIAL_RX_PARITY_ERROR|SERIAL_RX_EMPTY|SERIAL_RX_OVERRUN_ERROR" + "|MAC_TRANSMIT_QUEUE_FULL|MAC_UNKNOWN_HEADER_TYPE|MAC_SCANNING|MAC_NO_DATA|MAC_JOINED_NETWORK|MAC_BAD_SCAN_DURATION|MAC_INCORRECT_SCAN_TYPE|MAC_INVALID_CHANNEL_MASK|MAC_COMMAND_TRANSMIT_FAILURE" + "|MAC_NO_ACK_RECEIVED|MAC_INDIRECT_TIMEOUT|SIM_EEPROM_ERASE_PAGE_GREEN|SIM_EEPROM_ERASE_PAGE_RED|SIM_EEPROM_FULL|ERR_FLASH_WRITE_INHIBITED|ERR_FLASH_VERIFY_FAILED|SIM_EEPROM_INIT_1_FAILED|SIM_EEPROM_INIT_2_FAILED|SIM_EEPROM_INIT_3_FAILED|ERR_FLASH_PROG_FAIL|ERR_FLASH_ERASE_FAIL" + "|ERR_BOOTLOADER_TRAP_TABLE_BAD|ERR_BOOTLOADER_TRAP_UNKNOWN|ERR_BOOTLOADER_NO_IMAGE|DELIVERY_FAILED|BINDING_INDEX_OUT_OF_RANGE|ADDRESS_TABLE_INDEX_OUT_OF_RANGE|INVALID_BINDING_INDEX" + "|INVALID_CALL|COST_NOT_KNOWN|MAX_MESSAGE_LIMIT_REACHED|MESSAGE_TOO_LONG|BINDING_IS_ACTIVE|ADDRESS_TABLE_ENTRY_IS_ACTIVE" + "|ADC_CONVERSION_DONE|ADC_CONVERSION_BUSY|ADC_CONVERSION_DEFERRED|ADC_NO_CONVERSION_PENDING|SLEEP_INTERRUPTED|PHY_TX_UNDERFLOW|PHY_TX_INCOMPLETE|PHY_INVALID_CHANNEL|PHY_INVALID_POWER|PHY_TX_BUSY|PHY_TX_CCA_FAIL|PHY_OSCILLATOR_CHECK_FAILED|PHY_ACK_RECEIVED" + "|NETWORK_UP|NETWORK_DOWN|JOIN_FAILED|MOVE_FAILED|CANNOT_JOIN_AS_ROUTER|NODE_ID_CHANGED|PAN_ID_CHANGED|NO_BEACONS|RECEIVED_KEY_IN_THE_CLEAR|NO_NETWORK_KEY_RECEIVED|NO_LINK_KEY_RECEIVED|PRECONFIGURED_KEY_REQUIRED" + "|NOT_JOINED|INVALID_SECURITY_LEVEL|NETWORK_BUSY|INVALID_ENDPOINT|BINDING_HAS_CHANGED|INSUFFICIENT_RANDOM_DATA|APS_ENCRYPTION_ERROR|SECURITY_STATE_NOT_SET" + "|KEY_TABLE_INVALID_ADDRESS|SECURITY_CONFIGURATION_INVALID|TOO_SOON_FOR_SWITCH_KEY|KEY_NOT_AUTHORIZED|SECURITY_DATA_INVALID|SOURCE_ROUTE_FAILURE|MANY_TO_ONE_ROUTE_FAILURE" + "|STACK_AND_HARDWARE_MISMATCH|INDEX_OUT_OF_RANGE|TABLE_FULL|TABLE_ENTRY_ERASED|LIBRARY_NOT_PRESENT|OPERATION_IN_PROGRESS" + ; + static const uint8_t StatusIdx[] PROGMEM = { 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, + 0x18, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x39, 0x3A, 0x3D, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x40, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, + 0x58, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x6C, + 0x70, 0x71, 0x72, 0x74, 0x75, 0x76, + 0x80, 0x81, 0x82, 0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x94, 0x96, 0x98, 0x99, 0x9A, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0x93, 0x95, 0xA1, 0xA3, 0xA4, 0xA5, 0xA6, 0xA8, + 0xB3, 0xB7, 0xB8, 0xBB, 0xBD, 0xA9, 0xAA, + 0xB0, 0xB1, 0xB4, 0xB6, 0xB5, 0xBA }; + + char msg[32]; + int32_t idx = -1; + for (uint32_t i = 0; i < sizeof(StatusIdx); i++) { + if (status == pgm_read_byte(&StatusIdx[i])) { + idx = i; + break; + } + } + if (idx >= 0) { + GetTextIndexed(msg, sizeof(msg), idx, StatusMsg); + } else { + *msg = 0x00; // empty string + } + return String(msg); +} + // Undocumented Zigbee ZCL code here: https://github.com/dresden-elektronik/deconz-rest-plugin/wiki/Zigbee-Error-Codes-in-the-Log String getZigbeeStatusMessage(uint8_t status) { diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index f46b34f7c..784a5ebf3 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -204,13 +204,12 @@ ZBM(ZBR_ZNPHC, Z_SRSP | Z_SYS, SYS_OSAL_NV_READ, Z_SUCCESS, 0x01 /* len */, 0x55 ZBM(ZBS_PAN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_PANID ) // 260483 ZBR(ZBR_PAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PANID, 0x02 /* len */, - Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID) ) // 6604008302xxxx + 0x00, 0x00 /* pan_id */ ) // 6604008302xxxx ZBM(ZBS_EXTPAN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_EXTENDED_PAN_ID ) // 26042D ZBR(ZBR_EXTPAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_EXTENDED_PAN_ID, 0x08 /* len */, - Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), - Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ext_pan_id */ ) // 6604002D08xxxxxxxxxxxxxxxx ZBM(ZBS_CHANN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_CHANLIST ) // 260484 @@ -222,10 +221,8 @@ ZBR(ZBR_CHANN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_CHANLIS ZBM(ZBS_PFGK, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_PRECFGKEY ) // 260462 ZBR(ZBR_PFGK, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PRECFGKEY, 0x10 /* len */, - Z_B0(USE_ZIGBEE_PRECFGKEY_L), Z_B1(USE_ZIGBEE_PRECFGKEY_L), Z_B2(USE_ZIGBEE_PRECFGKEY_L), Z_B3(USE_ZIGBEE_PRECFGKEY_L), - Z_B4(USE_ZIGBEE_PRECFGKEY_L), Z_B5(USE_ZIGBEE_PRECFGKEY_L), Z_B6(USE_ZIGBEE_PRECFGKEY_L), Z_B7(USE_ZIGBEE_PRECFGKEY_L), - Z_B0(USE_ZIGBEE_PRECFGKEY_H), Z_B1(USE_ZIGBEE_PRECFGKEY_H), Z_B2(USE_ZIGBEE_PRECFGKEY_H), Z_B3(USE_ZIGBEE_PRECFGKEY_H), - Z_B4(USE_ZIGBEE_PRECFGKEY_H), Z_B5(USE_ZIGBEE_PRECFGKEY_H), Z_B6(USE_ZIGBEE_PRECFGKEY_H), Z_B7(USE_ZIGBEE_PRECFGKEY_H), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* key_l */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* key_h */ /*0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0D*/ ) // 660400621001030507090B0D0F00020406080A0C0D @@ -250,13 +247,12 @@ ZBM(ZBR_WNV_OK, Z_SRSP | Z_SYS, SYS_OSAL_NV_WRITE, Z_SUCCESS ) // 610900 - NV // Factory reset ZBM(ZBS_FACTRES, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x03 ) // 2605030103 // Write PAN ID -ZBR(ZBS_W_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID) ) // 26058302xxxx +ZBR(ZBS_W_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, 0x00, 0x00 /* pan_id */ ) // 26058302xxxx // Write Universal PAN ID ZBR(ZBS_W_ALL_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, Z_B0(0xFFFF), Z_B1(0xFFFF) ) // 26058302FFFF // Write EXT PAN ID ZBR(ZBS_W_EXTPAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_EXTENDED_PAN_ID, 0x08 /* len */, - Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), - Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ext_pan_id */ ) // 26052D086263151D004B1200 // Write Channel ID ZBR(ZBS_W_CHANN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_CHANLIST, 0x04 /* len */, @@ -276,11 +272,8 @@ ZBM(ZBS_W_LOGTYP_DEVICE, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_LOGICAL // Write precfgkey ZBR(ZBS_W_PFGK, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PRECFGKEY, 0x10 /* len */, - Z_B0(USE_ZIGBEE_PRECFGKEY_L), Z_B1(USE_ZIGBEE_PRECFGKEY_L), Z_B2(USE_ZIGBEE_PRECFGKEY_L), Z_B3(USE_ZIGBEE_PRECFGKEY_L), - Z_B4(USE_ZIGBEE_PRECFGKEY_L), Z_B5(USE_ZIGBEE_PRECFGKEY_L), Z_B6(USE_ZIGBEE_PRECFGKEY_L), Z_B7(USE_ZIGBEE_PRECFGKEY_L), - Z_B0(USE_ZIGBEE_PRECFGKEY_H), Z_B1(USE_ZIGBEE_PRECFGKEY_H), Z_B2(USE_ZIGBEE_PRECFGKEY_H), Z_B3(USE_ZIGBEE_PRECFGKEY_H), - Z_B4(USE_ZIGBEE_PRECFGKEY_H), Z_B5(USE_ZIGBEE_PRECFGKEY_H), Z_B6(USE_ZIGBEE_PRECFGKEY_H), Z_B7(USE_ZIGBEE_PRECFGKEY_H), - /*0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* key_l */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* key_h */ /*0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0D*/ ) // 2605621001030507090B0D0F00020406080A0C0D // Write precfgkey enable ZBM(ZBS_W_PFGKEN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PRECFGKEYS_ENABLE, 0x01 /* len */, 0x00 ) // 2605630100 @@ -428,7 +421,7 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize //ZI_MQTT_STATE(ZIGBEE_STATUS_BOOT, "Booting") - ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting device") + ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting CC2530 device") ZI_CALL(&ZNP_Reset_Device, 0) // LOW = reset ZI_WAIT(100) // wait for .1 second @@ -693,11 +686,8 @@ ZBR(ZBS_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, // preConfiguredKey 0x5A, 0x69, 0x67, 0x42, 0x65, 0x65, 0x41, 0x6C, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x30, 0x39, // well known key "ZigBeeAlliance09" // networkKey - Z_B0(USE_ZIGBEE_PRECFGKEY_L), Z_B1(USE_ZIGBEE_PRECFGKEY_L), Z_B2(USE_ZIGBEE_PRECFGKEY_L), Z_B3(USE_ZIGBEE_PRECFGKEY_L), - Z_B4(USE_ZIGBEE_PRECFGKEY_L), Z_B5(USE_ZIGBEE_PRECFGKEY_L), Z_B6(USE_ZIGBEE_PRECFGKEY_L), Z_B7(USE_ZIGBEE_PRECFGKEY_L), - Z_B0(USE_ZIGBEE_PRECFGKEY_H), Z_B1(USE_ZIGBEE_PRECFGKEY_H), Z_B2(USE_ZIGBEE_PRECFGKEY_H), Z_B3(USE_ZIGBEE_PRECFGKEY_H), - Z_B4(USE_ZIGBEE_PRECFGKEY_H), Z_B5(USE_ZIGBEE_PRECFGKEY_H), Z_B6(USE_ZIGBEE_PRECFGKEY_H), Z_B7(USE_ZIGBEE_PRECFGKEY_H), - 0x00 /*sequence*/, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* key_l */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* key_h */ 0x00 /*sequence*/, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*trustcenter*/ ) ZBM(ZBR_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, 0x00 /*status*/) @@ -723,9 +713,8 @@ ZBM(ZBR_NETWORK_INIT, EZSP_networkInit, 0x00 /*high*/, 0x00 /*status*/) // // formNetwork - i.e. start zigbee network as coordinator ZBR(ZBS_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, - Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), - Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID), - Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ext_pan_id */ + 0x00, 0x00, // pan_id USE_ZIGBEE_TXRADIO_DBM /*radioTxPower*/, USE_ZIGBEE_CHANNEL /*channel*/, EMBER_USE_MAC_ASSOCIATION, @@ -746,9 +735,8 @@ ZBM(ZBR_GET_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/, 0x00 /*ok*/) ZBR(ZBR_CHECK_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/, 0x00 /*status*/, EMBER_COORDINATOR /*0x01*/, - Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), - Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID), - Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ext_pan_id */ + 0x00, 0x00, // pan_id USE_ZIGBEE_TXRADIO_DBM /*radioTxPower*/, USE_ZIGBEE_CHANNEL /*channel*/, ) // 2800... @@ -884,7 +872,9 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_WAIT_RECV(1500, ZBR_NETWORK_UP) // wait for network to start // check if configuration is ok ZI_SEND(ZBS_GET_CURR_SEC) ZI_WAIT_RECV(500, ZBR_GET_CURR_SEC) - ZI_SEND(ZBS_GET_NETW_PARM) ZI_WAIT_RECV(500, ZBR_CHECK_NETW_PARM) + ZI_SEND(ZBS_GET_EUI64) ZI_WAIT_RECV_FUNC(500, ZBR_GET_EUI64, &EZ_GetEUI64) + ZI_SEND(ZBS_GET_NETW_PARM) ZI_WAIT_RECV_FUNC(500, ZBR_CHECK_NETW_PARM, &EZ_NetworkParameters) + // all ok, proceed to next step ZI_GOTO(ZIGBEE_LABEL_NETWORK_CONFIGURED) @@ -908,7 +898,6 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { // Query device information ZI_SEND(ZBS_GET_EUI64) ZI_WAIT_RECV_FUNC(500, ZBR_GET_EUI64, &EZ_GetEUI64) ZI_SEND(ZBS_GET_NODEID) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NODEID, &EZ_GetNodeId) - ZI_SEND(ZBS_GET_NETW_PARM) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NETW_PARM, &EZ_NetworkParameters) ZI_LABEL(ZIGBEE_LABEL_READY) ZI_MQTT_STATE(ZIGBEE_STATUS_OK, kStarted) diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 05b0b4b37..5814538ff 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -20,6 +20,16 @@ #ifdef USE_ZIGBEE #ifdef USE_ZIGBEE_EZSP +// +// Trying to get a uniform LQI measure, we are aligning with the definition of ZNP +// I.e. a linear projection from -87dBm to +10dB over 0..255 +// for ZNP, lqi is linear from -87 to +10 dBm (https://sunmaysky.blogspot.com/2017/02/conversion-between-rssi-and-lqi-in-z.html) +uint8_t ZNP_RSSI2Lqi(int8_t rssi) { + if (rssi < -87) { rssi = -87; } + if (rssi > 10) { rssi = 10; } + return changeUIntScale(rssi + 87, 0, 87+10, 0, 255); +} + /*********************************************************************************************\ * Parsers for incoming EZSP messages \*********************************************************************************************/ @@ -123,8 +133,8 @@ int32_t EZ_RouteError(int32_t res, const class SBuffer &buf) { uint16_t shortaddr = buf.get16(3); Response_P(PSTR("{\"" D_JSON_ZIGBEE_ROUTE_ERROR "\":{" - "\"ShortAddr\":\"0x%04X\",\"" D_JSON_ZIGBEE_STATUS "\":%d,\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"0x%s\"}}"), - shortaddr, status, ""); + "\"ShortAddr\":\"0x%04X\",\"" D_JSON_ZIGBEE_STATUS "\":%d,\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"}}"), + shortaddr, status, getEmberStatus(status).c_str()); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); @@ -776,8 +786,9 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d" ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" ",\"BindingsTotal\":%d" + ",\"BindingsStart\":%d" ",\"Bindings\":[" - ), status, getZigbeeStatusMessage(status).c_str(), bind_total); + ), status, getZigbeeStatusMessage(status).c_str(), bind_total, bind_start + 1); uint32_t idx = prefix_len; for (uint32_t i = 0; i < bind_len; i++) { @@ -1118,8 +1129,9 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { bool securityuse = (apsoptions & EMBER_APS_OPTION_ENCRYPTION) ? true : false; uint16_t groupid = buf.get16(11); uint8_t seqnumber = buf.get8(13); - uint8_t linkquality = buf.get8(14); - // uint8_t linkrsssi = buf.get8(15); // probably not used as there is no equivalent in Z-Stack + // uint8_t linkquality = buf.get8(14); + int8_t linkrssi = buf.get8(15); + uint8_t linkquality = ZNP_RSSI2Lqi(linkrssi); // don't take EZSP LQI but calculate our own based on ZNP uint16_t srcaddr = buf.get16(16); // uint8_t bindingindex = buf.get8(18); // not sure we need this one as a coordinator // uint8_t addressindex = buf.get8(19); // not sure how to handle this one @@ -1315,30 +1327,6 @@ int32_t ZNP_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { * Global dispatcher for incoming messages \*********************************************************************************************/ -int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { - uint16_t groupid = buf.get16(2); - uint16_t clusterid = buf.get16(4); - uint16_t srcaddr = buf.get16(6); - uint8_t srcendpoint = buf.get8(8); - uint8_t dstendpoint = buf.get8(9); - uint8_t wasbroadcast = buf.get8(10); - uint8_t linkquality = buf.get8(11); - uint8_t securityuse = buf.get8(12); - // uint32_t timestamp = buf.get32(13); - uint8_t seqnumber = buf.get8(17); - - bool defer_attributes = false; // do we defer attributes reporting to coalesce - - ZCLFrame zcl_received = ZCLFrame::parseRawFrame(buf, 19, buf.get8(18), clusterid, groupid, - srcaddr, - srcendpoint, dstendpoint, wasbroadcast, - linkquality, securityuse, seqnumber); - // - Z_IncomingMessage(zcl_received); - - return -1; -} - #ifdef USE_ZIGBEE_ZNP // Structure for the Dispatcher callbacks table diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index 1715d6763..c8a9953a1 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -585,12 +585,15 @@ int32_t ZigbeeProcessInputEZSP(class SBuffer &buf) { case EZSP_permitJoining: // 2200 case EZSP_getEui64: // 2600 case EZSP_getNodeId: // 2700 + case EZSP_getNetworkParameters: // 2800 case EZSP_sendUnicast: // 3400 case EZSP_sendBroadcast: // 3600 case EZSP_messageSentHandler: // 3F00 case EZSP_setConfigurationValue: // 5300 case EZSP_setPolicy: // 5500 case EZSP_setMulticastTableEntry: // 6400 + case EZSP_setInitialSecurityState: // 6800 + case EZSP_getCurrentSecurityState: // 6900 log_level = LOG_LEVEL_DEBUG; break; } diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index a631432fc..f48258031 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -57,14 +57,25 @@ void (* const ZigbeeCommand[])(void) PROGMEM = { void ZigbeeInit(void) { // Check if settings in Flash are set - if (0 == Settings.zb_channel) { - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Initializing Zigbee parameters from defaults")); - Settings.zb_ext_panid = USE_ZIGBEE_EXTPANID; - Settings.zb_precfgkey_l = USE_ZIGBEE_PRECFGKEY_L; - Settings.zb_precfgkey_h = USE_ZIGBEE_PRECFGKEY_H; - Settings.zb_pan_id = USE_ZIGBEE_PANID; - Settings.zb_channel = USE_ZIGBEE_CHANNEL; - Settings.zb_txradio_dbm = USE_ZIGBEE_TXRADIO_DBM; + if (PinUsed(GPIO_ZIGBEE_RX) && PinUsed(GPIO_ZIGBEE_TX)) { + if (0 == Settings.zb_channel) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Randomizing Zigbee parameters, please check with 'ZbConfig'")); + uint64_t mac64 = 0; // stuff mac address into 64 bits + WiFi.macAddress((uint8_t*) &mac64); + uint32_t esp_id = ESP.getChipId(); + uint32_t flash_id = ESP.getFlashChipId(); + + uint16_t pan_id = (mac64 & 0x3FFF); + if (0x0000 == pan_id) { pan_id = 0x0001; } // avoid extreme values + if (0x3FFF == pan_id) { pan_id = 0x3FFE; } // avoid extreme values + Settings.zb_pan_id = pan_id; + + Settings.zb_ext_panid = 0xCCCCCCCC00000000L | (mac64 & 0x00000000FFFFFFFFL); + Settings.zb_precfgkey_l = (mac64 << 32) | (esp_id << 16) | flash_id; + Settings.zb_precfgkey_h = (mac64 << 32) | (esp_id << 16) | flash_id; + Settings.zb_channel = USE_ZIGBEE_CHANNEL; + Settings.zb_txradio_dbm = USE_ZIGBEE_TXRADIO_DBM; + } } // update commands with the current settings @@ -751,18 +762,20 @@ void CmndZbUnbind(void) { // // Command `ZbBindState` +// `ZbBindState` as index if it does not fit. If default, `1` starts at the beginning // void CmndZbBindState(void) { if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } + uint8_t index = XdrvMailbox.index - 1; // change default 1 to 0 #ifdef USE_ZIGBEE_ZNP SBuffer buf(10); buf.add8(Z_SREQ | Z_ZDO); // 25 buf.add8(ZDO_MGMT_BIND_REQ); // 33 buf.add16(shortaddr); // shortaddr - buf.add8(0); // StartIndex = 0 + buf.add8(index); // StartIndex = 0 ZigbeeZNPSend(buf.getBuffer(), buf.len()); #endif // USE_ZIGBEE_ZNP @@ -770,7 +783,7 @@ void CmndZbBindState(void) { #ifdef USE_ZIGBEE_EZSP // ZDO message payload (see Zigbee spec 2.4.3.3.4) - uint8_t buf[] = { 0x00 }; // index = 0 + uint8_t buf[] = { index }; // index = 0 EZ_SendZDO(shortaddr, ZDO_Mgmt_Bind_req, buf, sizeof(buf)); #endif // USE_ZIGBEE_EZSP From 69e252b7d7b3bf9b901e2175c29555c1456a624f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 29 Jul 2020 10:31:38 +0200 Subject: [PATCH 577/581] Prep release 8.4.0 --- MODULES.md | 2 +- RELEASENOTES.md | 15 ++++++++------- tasmota/CHANGELOG.md | 5 +++-- tasmota/my_user_config.h | 10 +++++----- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/MODULES.md b/MODULES.md index 1ca8ab473..29575f5bb 100644 --- a/MODULES.md +++ b/MODULES.md @@ -80,4 +80,4 @@ Module | Description 74 Sonoff D1 | Sonoff D1 Wifi and RF Dimmer 75 Sonoff ZbBridge | Sonoff Zigbee bridge -Over 1000 additional devices are supported using [templates](TEMPLATES.md). +Over 1400 additional devices are supported using [templates](TEMPLATES.md). diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 468f761c6..bc9abff0c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -66,6 +66,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` - Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message - Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` +- Change Zigbee randomizing of parameters at first run or after Reset - Fix escape of non-JSON received serial data (#8329) - Fix exception or watchdog on rule re-entry (#8757) - Add command ``Rule0`` to change global rule parameters @@ -81,28 +82,28 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command (``S``)``SerialSend6`` \ (#8937) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` +- Add more functionality to command ``Switchmode`` 11 and 12 (#8450) - Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet - Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) -- Add more functionality to ``Switchmode`` 11 and 12 (#8450) - Add wildcard pattern ``?`` for JSON matching in rules -- Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) -- Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) - Add Three Phase Export Active Energy to SDM630 driver - Add Zigbee options to ``ZbSend`` to write and report attributes - Add Zigbee auto-responder for common attributes - Add ``CpuFrequency`` to ``status 2`` - Add ``FlashFrequency`` to ``status 4`` +- Add compile time interlock parameters (#8759) +- Add compile time user template (#8766) +- Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) +- Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) - Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) - Add support for up to eight MCP9808 temperature sensors by device111 (#8594) - Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) - Add support for Telegram bot (#8619) - Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) - Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff -- Add Library to be used for decoding Teleinfo (French Metering Smart Meter) - Add support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON - Add support for single wire LMT01 temperature Sensor by justifiably (#8713) -- Add compile time interlock parameters (#8759) -- Add compile time user template (#8766) -- Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) +- Add support for rotary encoder as light dimmer and optional color temperature if button1 still pressed (#8670) - Add support for switches/relays using an AC detection circuitry e.g. MOES MS-104B or BlitzWolf SS5 (#8606) - Add support for Schneider Electric iEM3000 series Modbus energy meter by Marius Bezuidenhout +- Add support for Sonoff Zigbee Bridge as module 75 (#8583) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 939aad6ac..6a9520fcc 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -6,12 +6,13 @@ - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE - Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message - Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` +- Change ``Ping`` now reports the hostname instead of IP address (#8948) +- Change Zigbee randomizing of parameters at first run or after Reset - Add command ``DzSend ,`` to send values or state to Domoticz - Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 - Add command (``S``)``SerialSend6`` \ (#8937) -- Change ``Ping`` now reports the hostname instead of IP address (#8948) -- Change Zigbee randomizing of parameters at first run or after Reset +- Add support for Sonoff Zigbee Bridge as module 75 (#8583) ### 8.3.1.6 20200617 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index fff58d480..69f51a546 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -681,11 +681,11 @@ // -- Zigbee interface ---------------------------- //#define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP (+49k code, +3k mem) - #define USE_ZIGBEE_ZNP // Enable ZNP protocol, needed for CC2530 based devices - // #define USE_ZIGBEE_EZSP // [EXPERIMENTAL - DO NOT USE] Enable EZSP protocol, needed for EFR32 EmberZNet based devices, like Sonoff Zigbee bridge - // Note: USE_ZIGBEE_ZNP and USE_ZIGBEE_EZSP are mutually incompatible, you must select exactly one - #define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26) - #define USE_ZIGBEE_TXRADIO_DBM 20 // Tx Radio power in dBm (only for EZSP, EFR32 can go up to 20 dBm) + #define USE_ZIGBEE_ZNP // Enable ZNP protocol, needed for CC2530 based devices +// #define USE_ZIGBEE_EZSP // Enable EZSP protocol, needed for EFR32 EmberZNet based devices, like Sonoff Zigbee bridge + // Note: USE_ZIGBEE_ZNP and USE_ZIGBEE_EZSP are mutually incompatible, you must select exactly one + #define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26) + #define USE_ZIGBEE_TXRADIO_DBM 20 // Tx Radio power in dBm (only for EZSP, EFR32 can go up to 20 dBm) #define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms) #define USE_ZIGBEE_MODELID "Tasmota Z2T" // reported "ModelId" (cluster 0000 / attribute 0005) From 25a187499b035fa0ca9aa69e29158a3830ecf0ed Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 29 Jul 2020 10:44:09 +0200 Subject: [PATCH 578/581] Prep release 8.4.0 --- BUILDS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BUILDS.md b/BUILDS.md index c1aa5e2e3..b27400c96 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -148,6 +148,8 @@ | USE_NRF24 | - | - | - | - | - | - | - | | USE_MIBLE | - | - | - | - | - | - | - | | USE_ZIGBEE | - | - | - | - | - | - | - | +| USE_ZIGBEE_ZNP | - | - | - | - | - | - | - | +| USE_ZIGBEE_EZSP | - | - | - | - | - | - | - | Sonoff ZbBridge | | | | | | | | | | USE_IR_REMOTE | - | - | x | x | x | x | x | | USE_IR_RECEIVE | - | - | x | x | x | x | x | From 9a3307a73f71cc11ba1d7aab0d8bf95741f17cf5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 29 Jul 2020 11:18:56 +0200 Subject: [PATCH 579/581] Prep release 8.4.0 --- .github/workflows/CI_github.yml | 457 -------- .github/workflows/CI_github_ESP32.yml | 517 --------- .github/workflows/Tasmota_build.yml | 1532 ------------------------- FIRMWARE.md | 2 +- README.md | 2 +- RELEASENOTES.md | 2 +- tasmota/CHANGELOG.md | 12 +- tasmota/tasmota_version.h | 2 +- 8 files changed, 10 insertions(+), 2516 deletions(-) delete mode 100644 .github/workflows/CI_github.yml delete mode 100644 .github/workflows/CI_github_ESP32.yml delete mode 100644 .github/workflows/Tasmota_build.yml diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml deleted file mode 100644 index 1f4f79f38..000000000 --- a/.github/workflows/CI_github.yml +++ /dev/null @@ -1,457 +0,0 @@ -name: Tasmota CI - -on: - pull_request: - -jobs: - tasmota: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota - - tasmota-minimal: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-minimal - - tasmota-lite: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-lite - - tasmota-knx: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-knx - - tasmota-sensors: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-sensors - - - tasmota-display: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-display - - tasmota-ir: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-ir - - tasmota-zbbridge: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-zbbridge - - tasmota-BG: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-BG - - tasmota-BR: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-BR - - tasmota-CN: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-CN - - tasmota-CZ: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-CZ - - tasmota-DE: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-DE - - tasmota-ES: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-ES - - - tasmota-FR: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-FR - - tasmota-GR: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-GR - - tasmota-HE: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-HE - - tasmota-HU: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-HU - - tasmota-IT: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-IT - - tasmota-KO: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-KO - - tasmota-NL: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-NL - - tasmota-PL: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-PL - - tasmota-PT: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-PT - - tasmota-RO: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-RO - - tasmota-RU: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-RU - - tasmota-SE: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-SE - - tasmota-SK: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-SK - - tasmota-TR: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-TR - - tasmota-TW: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-TW - - tasmota-UK: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: platformio run -e tasmota-UK diff --git a/.github/workflows/CI_github_ESP32.yml b/.github/workflows/CI_github_ESP32.yml deleted file mode 100644 index 5184aeb7a..000000000 --- a/.github/workflows/CI_github_ESP32.yml +++ /dev/null @@ -1,517 +0,0 @@ -name: Tasmota ESP32 CI - -on: - pull_request: - -jobs: - tasmota32: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32 - - - tasmota32-webcam: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-webcam - - tasmota32-minimal: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-minimal - - tasmota32-lite: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-lite - - tasmota32-knx: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-knx - - tasmota32-sensors: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-sensors - - tasmota32-display: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-display - - tasmota32-ir: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-ir - - tasmota32-BG: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-BG - - tasmota32-BR: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-BR - - tasmota32-CN: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-CN - - tasmota32-CZ: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-CZ - - tasmota32-DE: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-DE - - tasmota32-ES: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-ES - - - tasmota32-FR: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-FR - - tasmota32-GR: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-GR - - tasmota32-HE: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-HE - - tasmota32-HU: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-HU - - tasmota32-IT: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-IT - - tasmota32-KO: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-KO - - tasmota32-NL: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-NL - - tasmota32-PL: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-PL - - tasmota32-PT: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-PT - - tasmota32-RO: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-RO - - tasmota32-RU: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-RU - - tasmota32-SE: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-SE - - tasmota32-SK: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-SK - - tasmota32-TR: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-TR - - tasmota32-TW: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-TW - - tasmota32-UK: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - cp platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-UK diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml deleted file mode 100644 index 1a9a011de..000000000 --- a/.github/workflows/Tasmota_build.yml +++ /dev/null @@ -1,1532 +0,0 @@ -name: Build_firmware - -on: - push: - -jobs: - tasmota_pull: - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Use latest Tasmota development - run: | - git config --local user.name "Platformio BUILD" - git switch -c master - git remote add -f Tasmota "https://github.com/arendst/Tasmota.git" - git merge Tasmota/development --allow-unrelated-histories - - name: Push Tasmota # Push updates of latest Tasmota development to repo - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: 'development' - force: true - - - tasmota: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-minimal: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-minimal - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-lite: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-lite - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-knx: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-knx - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-sensors: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-sensors - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-display: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-display - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-ir: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-ir - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-ircustom: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-ircustom - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-zbbridge: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-zbbridge - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - tasmota-BG: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-BG - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-BR: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-BR - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-CN: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-CN - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-CZ: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-CZ - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-DE: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-DE - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-ES: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-ES - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-FR: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-FR - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-GR: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-GR - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-HE: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-HE - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-HU: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-HU - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-IT: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-IT - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-KO: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-KO - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-NL: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-NL - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-PL: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-PL - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-PT: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-PT - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-RO: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-RO - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-RU: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-RU - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-SE: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-SE - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-SK: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-SK - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-TR: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-TR - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-TW: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-TW - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota-UK: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - platformio run -e tasmota-UK - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32 - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-minimal: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-minimal - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-lite: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-lite - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-webcam: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-webcam - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-knx: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-knx - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-sensors: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-sensors - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-display: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-display - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-ir: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-ir - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-ircustom: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-ircustom - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-BG: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-BG - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-BR: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-BR - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-CN: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-CN - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-CZ: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-CZ - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-DE: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-DE - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-ES: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-ES - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-FR: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-FR - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-GR: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-GR - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-HE: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-HE - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-HU: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-HU - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-IT: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-IT - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-KO: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-KO - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-NL: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-NL - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-PL: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-PL - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-PT: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-PT - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-RO: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-RO - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-RU: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-RU - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-SE: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-SE - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-SK: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-SK - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-TR: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-TR - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-TW: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-TW - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - tasmota32-UK: - needs: tasmota_pull - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -U platformio - platformio upgrade --dev - platformio update - - name: Run PlatformIO - run: | - mv platformio_override_sample.ini platformio_override.ini - platformio run -e tasmota32-UK - - uses: actions/upload-artifact@v2 - with: - name: firmware - path: ./build_output/firmware - - - Upload: - needs: [tasmota-UK, tasmota32-ircustom, tasmota32-UK, tasmota32-TW, tasmota32-TR] - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v1 - - uses: actions/download-artifact@v2 - with: - name: firmware - path: ./mv_firmware - - name: Display structure of downloaded files - run: ls -R - working-directory: ./mv_firmware - - name: Move firmware files in sub-folders - run: | - mkdir -p ./firmware/tasmota/languages - mkdir -p ./firmware/tasmota32/languages - mkdir -p ./firmware/tasmota32/ESP32_needed_files/ - [ ! -f ./mv_firmware/tasmota.* ] || mv ./mv_firmware/tasmota.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/tasmota-sensors.* ] || mv ./mv_firmware/tasmota-sensors.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/tasmota-minimal.* ] || mv ./mv_firmware/tasmota-minimal.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/tasmota-lite.* ] || mv ./mv_firmware/tasmota-lite.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/tasmota-ir*.* ] || mv ./mv_firmware/tasmota-ir*.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/tasmota-display.* ] || mv ./mv_firmware/tasmota-display.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/tasmota-knx.* ] || mv ./mv_firmware/tasmota-knx.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/tasmota-zbbridge.* ] || mv ./mv_firmware/tasmota-zbbridge.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/tasmota32.* ] || mv ./mv_firmware/tasmota32.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/tasmota32-sensors.* ] || mv ./mv_firmware/tasmota32-sensors.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/tasmota32-minimal.* ] || mv ./mv_firmware/tasmota32-minimal.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/tasmota32-lite.* ] || mv ./mv_firmware/tasmota32-lite.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/tasmota32-ir*.* ] || mv ./mv_firmware/tasmota32-ir*.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/tasmota32-display.* ] || mv ./mv_firmware/tasmota32-display.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/tasmota32-web*.* ] || mv ./mv_firmware/tasmota32-web*.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/tasmota32-knx.* ] || mv ./mv_firmware/tasmota32-knx.* ./firmware/tasmota32/ - [ ! -f ./mv_firmware/tasmota32* ] || mv ./mv_firmware/tasmota32* ./firmware/tasmota32/languages/ - [ ! -f ./mv_firmware/* ] || mv ./mv_firmware/* ./firmware/tasmota/languages/ - [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ - [ ! -f ./FIRMWARE.md ] || mv -f ./FIRMWARE.md ./README.md - - name: Commit files # transfer the new binaries back into the repository - run: | - git config --local user.name "Platformio BUILD" - git rm -r --cached . - git add ./README.md - git add -f ./firmware/*.* - git commit -m "Tasmota ESP Binaries http://tasmota.com" - - name: Push changes # push the firmware files to branch firmware - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: 'firmware' - force: true diff --git a/FIRMWARE.md b/FIRMWARE.md index d66bd1ba1..9f05223e8 100644 --- a/FIRMWARE.md +++ b/FIRMWARE.md @@ -18,7 +18,7 @@ See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/tasmota/C ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v8.3.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v8.4.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) [![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) diff --git a/README.md b/README.md index 97413616e..0bdf2a9e9 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ In addition to the [release webpage](https://github.com/arendst/Tasmota/releases ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v8.3.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v8.4.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) [![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index bc9abff0c..4ee93ddfd 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -53,7 +53,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.3.1.7 +### Version 8.4.0 George - Remove Arduino ESP8266 Core support for versions before 2.7.1 - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 6a9520fcc..f0a571cb1 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,3 +1,9 @@ +## Released + +### 8.4.0 20200730 + +- Release George + ## Unreleased (development) ### 8.3.1.7 20200716 @@ -78,8 +84,6 @@ - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) - Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) -## Released - ### 8.3.1 20200518 - Release Fred @@ -96,8 +100,6 @@ - Change Quick Power Cycle detection from 4 to 7 power interrupts (#4066) - Fix default state of ``SetOption73 0`` for button decoupling and send multi-press and hold MQTT messages -## Released - ### 8.3.0 20200514 - Release Fred @@ -182,8 +184,6 @@ - Add support for unreachable (unplugged) Zigbee devices in Philips Hue emulation and Alexa - Add support for 64x48 SSD1306 OLED (#6740) -## Released - ### 8.2.0 20200321 - Release Elliot diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 23105273e..d1601408a 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08030107; +const uint32_t VERSION = 0x08040000; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; From e83351864ee8cba836eb15e70b67eee29b2f6483 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 29 Jul 2020 13:57:44 +0200 Subject: [PATCH 580/581] Change IRRemoteESP8266 IR lib to pre-2.7.9, fixing Samsung and Pioneer protocols (#8938) --- .../TurnOnToshibaAC/TurnOnToshibaAC.ino | 2 +- lib/IRremoteESP8266-2.7.8/src/IRac.cpp | 228 ++++-- lib/IRremoteESP8266-2.7.8/src/IRac.h | 31 +- lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp | 10 +- lib/IRremoteESP8266-2.7.8/src/IRrecv.h | 10 +- .../src/IRremoteESP8266.h | 18 +- lib/IRremoteESP8266-2.7.8/src/IRsend.cpp | 7 + lib/IRremoteESP8266-2.7.8/src/IRsend.h | 7 +- lib/IRremoteESP8266-2.7.8/src/IRtext.cpp | 2 + lib/IRremoteESP8266-2.7.8/src/IRtext.h | 3 +- lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp | 4 +- lib/IRremoteESP8266-2.7.8/src/IRtimer.h | 8 +- lib/IRremoteESP8266-2.7.8/src/IRutils.cpp | 32 + lib/IRremoteESP8266-2.7.8/src/IRutils.h | 2 + lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp | 217 ++++- lib/IRremoteESP8266-2.7.8/src/ir_Airwell.h | 97 +++ lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h | 5 +- lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp | 12 +- lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp | 10 +- lib/IRremoteESP8266-2.7.8/src/ir_LG.h | 3 +- lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp | 43 +- lib/IRremoteESP8266-2.7.8/src/ir_Midea.h | 15 + lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h | 4 +- .../src/ir_MitsubishiHeavy.cpp | 36 +- lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp | 28 +- lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp | 40 +- lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h | 2 + lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp | 480 ++++++++++- lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.h | 163 ++++ lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp | 282 +++++-- lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h | 89 ++- .../src/locale/defaults.h | 6 + lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp | 326 +++++--- .../test/IRutils_test.cpp | 84 +- .../test/ir_Airwell_test.cpp | 150 +++- lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp | 51 +- .../test/ir_Midea_test.cpp | 49 +- .../test/ir_Pioneer_test.cpp | 146 +++- .../test/ir_Samsung_test.cpp | 132 ++-- .../test/ir_Sanyo_test.cpp | 275 ++++++- .../test/ir_Toshiba_test.cpp | 743 +++++++++--------- .../tools/RawToGlobalCache.sh | 0 .../tools/auto_analyse_raw_data.py | 0 .../tools/auto_analyse_raw_data_test.py | 0 .../tools/generate_irtext_h.sh | 0 lib/IRremoteESP8266-2.7.8/tools/mkkeywords | 0 .../tools/scrape_supported_devices.py | 0 tasmota/CHANGELOG.md | 1 + 48 files changed, 2991 insertions(+), 862 deletions(-) create mode 100644 lib/IRremoteESP8266-2.7.8/src/ir_Airwell.h create mode 100644 lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.h mode change 100644 => 100755 lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh mode change 100644 => 100755 lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py mode change 100644 => 100755 lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py mode change 100644 => 100755 lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh mode change 100644 => 100755 lib/IRremoteESP8266-2.7.8/tools/mkkeywords mode change 100644 => 100755 lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino index a37a07e5c..fb71c0486 100644 --- a/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino @@ -38,7 +38,7 @@ void printState() { // Display the encoded IR sequence. unsigned char* ir_code = ac.getRaw(); Serial.print("IR Code: 0x"); - for (uint8_t i = 0; i < kToshibaACStateLength; i++) + for (uint8_t i = 0; i < ac.getStateLength(); i++) Serial.printf("%02X", ir_code[i]); Serial.println(); } diff --git a/lib/IRremoteESP8266-2.7.8/src/IRac.cpp b/lib/IRremoteESP8266-2.7.8/src/IRac.cpp index fda16aba5..4e54d26f0 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRac.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRac.cpp @@ -16,6 +16,7 @@ #include "IRremoteESP8266.h" #include "IRtext.h" #include "IRutils.h" +#include "ir_Airwell.h" #include "ir_Amcor.h" #include "ir_Argo.h" #include "ir_Carrier.h" @@ -34,6 +35,7 @@ #include "ir_Neoclima.h" #include "ir_Panasonic.h" #include "ir_Samsung.h" +#include "ir_Sanyo.h" #include "ir_Sharp.h" #include "ir_Tcl.h" #include "ir_Teco.h" @@ -132,6 +134,9 @@ stdAc::state_t IRac::getStatePrev(void) { return _prev; } /// @return true if the protocol is supported by this class, otherwise false. bool IRac::isProtocolSupported(const decode_type_t protocol) { switch (protocol) { +#if SEND_AIRWELL + case decode_type_t::AIRWELL: +#endif #if SEND_AMCOR case decode_type_t::AMCOR: #endif @@ -236,6 +241,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_SAMSUNG_AC case decode_type_t::SAMSUNG_AC: #endif +#if SEND_SANYO_AC + case decode_type_t::SANYO_AC: +#endif #if SEND_SHARP_AC case decode_type_t::SHARP_AC: #endif @@ -269,6 +277,34 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { } } +#if SEND_AIRWELL +/// Send an Airwell A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRAirwellAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +void IRac::airwell(IRAirwellAc *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan) { + ac->begin(); + ac->setPowerToggle(on); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees); + ac->setFan(ac->convertFan(fan)); + // No Swing setting available. + // No Quiet setting available. + // No Light setting available. + // No Filter setting available. + // No Turbo setting available. + // No Economy setting available. + // No Clean setting available. + // No Beep setting available. + // No Sleep setting available. + ac->send(); +} +#endif // SEND_AIRWELL + #if SEND_AMCOR /// Send an Amcor A/C message with the supplied settings. /// @param[in, out] ac A Ptr to an IRAmcorAc object to use. @@ -1231,11 +1267,14 @@ void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model, /// @param[in] degrees The temperature setting in degrees. /// @param[in] fan The speed setting for the fan. /// @param[in] swingv The vertical swing setting. +/// @param[in] econo Run the device in economical mode. /// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. +/// @note On Danby A/C units, swingv controls the Ion Filter instead. void IRac::midea(IRMideaAC *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, - const stdAc::swingv_t swingv, const int16_t sleep) { + const stdAc::swingv_t swingv, const bool econo, + const int16_t sleep) { ac->begin(); ac->setPower(on); ac->setMode(ac->convertMode(mode)); @@ -1246,6 +1285,7 @@ void IRac::midea(IRMideaAC *ac, // No Horizontal swing setting available. // No Quiet setting available. // No Turbo setting available. + ac->setEconoToggle(econo); // No Light setting available. // No Filter setting available. // No Clean setting available. @@ -1572,6 +1612,45 @@ void IRac::samsung(IRSamsungAc *ac, } #endif // SEND_SAMSUNG_AC +#if SEND_SANYO_AC +/// Send a Toshiba A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRSanyoAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] beep Enable/Disable beeps when receiving IR messages. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. +void IRac::sanyo(IRSanyoAc *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool beep, + const int16_t sleep) { + ac->begin(); + ac->setPower(on); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees); + ac->setFan(ac->convertFan(fan)); + ac->setSwingV(ac->convertSwingV(swingv)); + // No Horizontal swing setting available. + // No Quiet setting available. + // No Turbo setting available. + // No Econo setting available. + // No Light setting available. + // No Filter setting available. + // No Clean setting available. + ac->setBeep(beep); + ac->setSleep(sleep >= 0); // Sleep is either on/off, so convert to boolean. + // No Clock setting available. + + // Extra + ac->setSensor(true); // Set the A/C to use the temp sensor in the Unit/Wall. + ac->setSensorTemp(degrees); // Set the sensor temp to the desired temp. + ac->send(); +} +#endif // SEND_SANYO_AC + #if SEND_SHARP_AC /// Send a Sharp A/C message with the supplied settings. /// @note Multiple IR messages may be generated & sent. @@ -1703,18 +1782,26 @@ void IRac::teco(IRTecoAc *ac, /// @param[in] mode The operation mode setting. /// @param[in] degrees The temperature setting in degrees. /// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. void IRac::toshiba(IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, - const float degrees, const stdAc::fanspeed_t fan) { + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, + const bool turbo, const bool econo) { ac->begin(); ac->setPower(on); ac->setMode(ac->convertMode(mode)); ac->setTemp(degrees); ac->setFan(ac->convertFan(fan)); - // No Vertical swing setting available. + // The API has no "step" option, so off is off, anything else is on. + ac->setSwing((swingv == stdAc::swingv_t::kOff) ? kToshibaAcSwingOff + : kToshibaAcSwingOn); // No Horizontal swing setting available. // No Quiet setting available. - // No Turbo setting available. + ac->setTurbo(turbo); + ac->setEcono(econo); // No Light setting available. // No Filter setting available. // No Clean setting available. @@ -1881,10 +1968,12 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired, case decode_type_t::ELECTRA_AC: result.light = desired.light ^ prev->light; break; + case decode_type_t::MIDEA: + result.econo = desired.econo ^ prev->econo; + // FALL THRU case decode_type_t::CORONA_AC: case decode_type_t::HITACHI_AC344: case decode_type_t::HITACHI_AC424: - case decode_type_t::MIDEA: case decode_type_t::SHARP_AC: if ((desired.swingv == stdAc::swingv_t::kOff) ^ (prev->swingv == stdAc::swingv_t::kOff)) // It changed, so toggle. @@ -1892,6 +1981,7 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired, else result.swingv = stdAc::swingv_t::kOff; // No change, so no toggle. break; + case decode_type_t::AIRWELL: case decode_type_t::DAIKIN64: case decode_type_t::WHIRLPOOL_AC: result.power = desired.power ^ prev->power; @@ -1959,6 +2049,14 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { stdAc::state_t send = this->handleToggles(this->cleanState(desired), prev); // Per vendor settings & setup. switch (send.protocol) { +#if SEND_AIRWELL + case AIRWELL: + { + IRAirwellAc ac(_pin, _inverted, _modulation); + airwell(&ac, send.power, send.mode, degC, send.fanspeed); + break; + } +#endif // SEND_AIRWELL #if SEND_AMCOR case AMCOR: { @@ -2210,7 +2308,7 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { { IRMideaAC ac(_pin, _inverted, _modulation); midea(&ac, send.power, send.mode, send.celsius, send.degrees, - send.fanspeed, send.swingv, send.sleep); + send.fanspeed, send.swingv, send.econo, send.sleep); break; } #endif // SEND_MIDEA @@ -2288,6 +2386,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { break; } #endif // SEND_SAMSUNG_AC +#if SEND_SANYO_AC + case SANYO_AC: + { + IRSanyoAc ac(_pin, _inverted, _modulation); + sanyo(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv, + send.beep, send.sleep); + break; + } +#endif // SEND_SANYO_AC #if SEND_SHARP_AC case SHARP_AC: { @@ -2321,7 +2428,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { case TOSHIBA_AC: { IRToshibaAC ac(_pin, _inverted, _modulation); - toshiba(&ac, send.power, send.mode, degC, send.fanspeed); + toshiba(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv, + send.turbo, send.econo); break; } #endif // SEND_TOSHIBA_AC @@ -2715,16 +2823,23 @@ namespace IRAcUtils { /// An empty string if we can't. String resultAcToString(const decode_results * const result) { switch (result->decode_type) { +#if DECODE_AIRWELL + case decode_type_t::AIRWELL: { + IRAirwellAc ac(kGpioUnused); + ac.setRaw(result->value); // AIRWELL uses value instead of state. + return ac.toString(); + } +#endif // DECODE_AIRWELL #if DECODE_AMCOR case decode_type_t::AMCOR: { - IRAmcorAc ac(0); + IRAmcorAc ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_AMCOR #if DECODE_ARGO case decode_type_t::ARGO: { - IRArgoAC ac(0); + IRArgoAC ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } @@ -2738,49 +2853,49 @@ namespace IRAcUtils { #endif // DECODE_CARRIER_AC64 #if DECODE_DAIKIN case decode_type_t::DAIKIN: { - IRDaikinESP ac(0); + IRDaikinESP ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_DAIKIN #if DECODE_DAIKIN128 case decode_type_t::DAIKIN128: { - IRDaikin128 ac(0); + IRDaikin128 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_DAIKIN128 #if DECODE_DAIKIN152 case decode_type_t::DAIKIN152: { - IRDaikin152 ac(0); + IRDaikin152 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_DAIKIN152 #if DECODE_DAIKIN160 case decode_type_t::DAIKIN160: { - IRDaikin160 ac(0); + IRDaikin160 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_DAIKIN160 #if DECODE_DAIKIN176 case decode_type_t::DAIKIN176: { - IRDaikin176 ac(0); + IRDaikin176 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_DAIKIN160 #if DECODE_DAIKIN2 case decode_type_t::DAIKIN2: { - IRDaikin2 ac(0); + IRDaikin2 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_DAIKIN2 #if DECODE_DAIKIN216 case decode_type_t::DAIKIN216: { - IRDaikin216 ac(0); + IRDaikin216 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } @@ -2801,131 +2916,138 @@ namespace IRAcUtils { #endif // DECODE_DELONGHI_AC #if DECODE_ELECTRA_AC case decode_type_t::ELECTRA_AC: { - IRElectraAc ac(0); + IRElectraAc ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_ELECTRA_AC #if DECODE_FUJITSU_AC case decode_type_t::FUJITSU_AC: { - IRFujitsuAC ac(0); + IRFujitsuAC ac(kGpioUnused); ac.setRaw(result->state, result->bits / 8); return ac.toString(); } #endif // DECODE_FUJITSU_AC #if DECODE_KELVINATOR case decode_type_t::KELVINATOR: { - IRKelvinatorAC ac(0); + IRKelvinatorAC ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_KELVINATOR #if DECODE_MITSUBISHI_AC case decode_type_t::MITSUBISHI_AC: { - IRMitsubishiAC ac(0); + IRMitsubishiAC ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_MITSUBISHI_AC #if DECODE_MITSUBISHI112 case decode_type_t::MITSUBISHI112: { - IRMitsubishi112 ac(0); + IRMitsubishi112 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_MITSUBISHI112 #if DECODE_MITSUBISHI136 case decode_type_t::MITSUBISHI136: { - IRMitsubishi136 ac(0); + IRMitsubishi136 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_MITSUBISHI136 #if DECODE_MITSUBISHIHEAVY case decode_type_t::MITSUBISHI_HEAVY_88: { - IRMitsubishiHeavy88Ac ac(0); + IRMitsubishiHeavy88Ac ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } case decode_type_t::MITSUBISHI_HEAVY_152: { - IRMitsubishiHeavy152Ac ac(0); + IRMitsubishiHeavy152Ac ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_MITSUBISHIHEAVY #if DECODE_NEOCLIMA case decode_type_t::NEOCLIMA: { - IRNeoclimaAc ac(0); + IRNeoclimaAc ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_NEOCLIMA #if DECODE_TOSHIBA_AC case decode_type_t::TOSHIBA_AC: { - IRToshibaAC ac(0); + IRToshibaAC ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_TOSHIBA_AC #if DECODE_TROTEC case decode_type_t::TROTEC: { - IRTrotecESP ac(0); + IRTrotecESP ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_TROTEC #if DECODE_GOODWEATHER case decode_type_t::GOODWEATHER: { - IRGoodweatherAc ac(0); + IRGoodweatherAc ac(kGpioUnused); ac.setRaw(result->value); // Goodweather uses value instead of state. return ac.toString(); } #endif // DECODE_GOODWEATHER #if DECODE_GREE case decode_type_t::GREE: { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_GREE #if DECODE_MIDEA case decode_type_t::MIDEA: { - IRMideaAC ac(0); + IRMideaAC ac(kGpioUnused); ac.setRaw(result->value); // Midea uses value instead of state. return ac.toString(); } #endif // DECODE_MIDEA #if DECODE_HAIER_AC case decode_type_t::HAIER_AC: { - IRHaierAC ac(0); + IRHaierAC ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_HAIER_AC #if DECODE_HAIER_AC_YRW02 case decode_type_t::HAIER_AC_YRW02: { - IRHaierACYRW02 ac(0); + IRHaierACYRW02 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_HAIER_AC_YRW02 #if DECODE_SAMSUNG_AC case decode_type_t::SAMSUNG_AC: { - IRSamsungAc ac(0); + IRSamsungAc ac(kGpioUnused); ac.setRaw(result->state, result->bits / 8); return ac.toString(); } #endif // DECODE_SAMSUNG_AC +#if DECODE_SANYO_AC + case decode_type_t::SANYO_AC: { + IRSanyoAc ac(kGpioUnused); + ac.setRaw(result->state); + return ac.toString(); + } +#endif // DECODE_SANYO_AC #if DECODE_SHARP_AC case decode_type_t::SHARP_AC: { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_SHARP_AC #if DECODE_COOLIX case decode_type_t::COOLIX: { - IRCoolixAC ac(0); + IRCoolixAC ac(kGpioUnused); ac.on(); ac.setRaw(result->value); // Coolix uses value instead of state. return ac.toString(); @@ -2941,7 +3063,7 @@ namespace IRAcUtils { #if DECODE_PANASONIC_AC case decode_type_t::PANASONIC_AC: { if (result->bits > kPanasonicAcShortBits) { - IRPanasonicAc ac(0); + IRPanasonicAc ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } @@ -2950,7 +3072,7 @@ namespace IRAcUtils { #endif // DECODE_PANASONIC_AC #if DECODE_HITACHI_AC case decode_type_t::HITACHI_AC: { - IRHitachiAc ac(0); + IRHitachiAc ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } @@ -2971,35 +3093,35 @@ namespace IRAcUtils { #endif // DECODE_HITACHI_AC344 #if DECODE_HITACHI_AC424 case decode_type_t::HITACHI_AC424: { - IRHitachiAc424 ac(0); + IRHitachiAc424 ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_HITACHI_AC424 #if DECODE_WHIRLPOOL_AC case decode_type_t::WHIRLPOOL_AC: { - IRWhirlpoolAc ac(0); + IRWhirlpoolAc ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } #endif // DECODE_WHIRLPOOL_AC #if DECODE_VESTEL_AC case decode_type_t::VESTEL_AC: { - IRVestelAc ac(0); + IRVestelAc ac(kGpioUnused); ac.setRaw(result->value); // Like Coolix, use value instead of state. return ac.toString(); } #endif // DECODE_VESTEL_AC #if DECODE_TECO case decode_type_t::TECO: { - IRTecoAc ac(0); + IRTecoAc ac(kGpioUnused); ac.setRaw(result->value); // Like Coolix, use value instead of state. return ac.toString(); } #endif // DECODE_TECO #if DECODE_TCL112AC case decode_type_t::TCL112AC: { - IRTcl112Ac ac(0); + IRTcl112Ac ac(kGpioUnused); ac.setRaw(result->state); return ac.toString(); } @@ -3007,7 +3129,7 @@ namespace IRAcUtils { #if DECODE_LG case decode_type_t::LG: case decode_type_t::LG2: { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.setRaw(result->value); // Like Coolix, use value instead of state. switch (result->decode_type) { case decode_type_t::LG2: @@ -3040,6 +3162,14 @@ namespace IRAcUtils { ) { if (decode == NULL || result == NULL) return false; // Safety check. switch (decode->decode_type) { +#if DECODE_AIRWELL + case decode_type_t::AIRWELL: { + IRAirwellAc ac(kGpioUnused); + ac.setRaw(decode->value); // Uses value instead of state. + *result = ac.toCommon(); + break; + } +#endif // DECODE_AIRWELL #if DECODE_AMCOR case decode_type_t::AMCOR: { IRAmcorAc ac(kGpioUnused); @@ -3090,7 +3220,7 @@ namespace IRAcUtils { #endif // DECODE_DAIKIN #if DECODE_DAIKIN128 case decode_type_t::DAIKIN128: { - IRDaikin128 ac(0); + IRDaikin128 ac(kGpioUnused); ac.setRaw(decode->state); *result = ac.toCommon(); break; @@ -3098,7 +3228,7 @@ namespace IRAcUtils { #endif // DECODE_DAIKIN128 #if DECODE_DAIKIN152 case decode_type_t::DAIKIN152: { - IRDaikin152 ac(0); + IRDaikin152 ac(kGpioUnused); ac.setRaw(decode->state); *result = ac.toCommon(); break; @@ -3327,6 +3457,14 @@ namespace IRAcUtils { break; } #endif // DECODE_SAMSUNG_AC +#if DECODE_SANYO_AC + case decode_type_t::SANYO_AC: { + IRSanyoAc ac(kGpioUnused); + ac.setRaw(decode->state); + *result = ac.toCommon(); + break; + } +#endif // DECODE_SANYO_AC #if DECODE_SHARP_AC case decode_type_t::SHARP_AC: { IRSharpAc ac(kGpioUnused); diff --git a/lib/IRremoteESP8266-2.7.8/src/IRac.h b/lib/IRremoteESP8266-2.7.8/src/IRac.h index 01365a180..5721f2bd6 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRac.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRac.h @@ -7,6 +7,7 @@ #include #endif #include "IRremoteESP8266.h" +#include "ir_Airwell.h" #include "ir_Amcor.h" #include "ir_Argo.h" #include "ir_Carrier.h" @@ -28,6 +29,7 @@ #include "ir_Neoclima.h" #include "ir_Panasonic.h" #include "ir_Samsung.h" +#include "ir_Sanyo.h" #include "ir_Sharp.h" #include "ir_Tcl.h" #include "ir_Teco.h" @@ -37,9 +39,10 @@ #include "ir_Whirlpool.h" // Constants -const int8_t kGpioUnused = -1; +const int8_t kGpioUnused = -1; ///< A placeholder for not using an actual GPIO. // Class +/// A universal/common/generic interface for controling supported A/Cs. class IRac { public: explicit IRac(const uint16_t pin, const bool inverted = false, @@ -93,10 +96,15 @@ class IRac { private: #endif - uint16_t _pin; - bool _inverted; - bool _modulation; - stdAc::state_t _prev; // The state we expect the device to currently be in. + uint16_t _pin; ///< The GPIO to use to transmit messages from. + bool _inverted; ///< IR LED is lit when GPIO is LOW (true) or HIGH (false)? + bool _modulation; ///< Is frequency modulation to be used? + stdAc::state_t _prev; ///< The state we expect the device to currently be in. +#if SEND_AIRWELL + void airwell(IRAirwellAc *ac, + const bool on, const stdAc::opmode_t mode, const float degrees, + const stdAc::fanspeed_t fan); +#endif // SEND_AIRWELL #if SEND_AMCOR void amcor(IRAmcorAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -286,7 +294,8 @@ void electra(IRElectraAc *ac, void midea(IRMideaAC *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, - const stdAc::swingv_t swingv, const int16_t sleep = -1); + const stdAc::swingv_t swingv, const bool econo, + const int16_t sleep = -1); #endif // SEND_MIDEA #if SEND_MITSUBISHI_AC void mitsubishi(IRMitsubishiAC *ac, @@ -350,6 +359,12 @@ void electra(IRElectraAc *ac, const bool beep, const bool prevpower = true, const bool forcepower = true); #endif // SEND_SAMSUNG_AC +#if SEND_SANYO_AC + void sanyo(IRSanyoAc *ac, + const bool on, const stdAc::opmode_t mode, const float degrees, + const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, + const bool beep, const int16_t sleep = -1); +#endif // SEND_SANYO_AC #if SEND_SHARP_AC void sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, @@ -374,7 +389,8 @@ void electra(IRElectraAc *ac, #if SEND_TOSHIBA_AC void toshiba(IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, - const stdAc::fanspeed_t fan); + const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, + const bool turbo, const bool econo); #endif // SEND_TOSHIBA_AC #if SEND_TROTEC void trotec(IRTrotecESP *ac, @@ -401,6 +417,7 @@ static stdAc::state_t handleToggles(const stdAc::state_t desired, const stdAc::state_t *prev = NULL); }; // IRac class +/// Common functions for use with all A/Cs supported by the IRac class. namespace IRAcUtils { String resultAcToString(const decode_results * const results); bool decodeToState(const decode_results *decode, stdAc::state_t *result, diff --git a/lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp b/lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp index efddcc17c..24ea0b021 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp @@ -614,8 +614,12 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, if (decodeDaikin216(results, offset)) return true; #endif #if DECODE_TOSHIBA_AC - DPRINTLN("Attempting Toshiba AC decode"); + DPRINTLN("Attempting Toshiba AC 72bit decode"); if (decodeToshibaAC(results, offset)) return true; + DPRINTLN("Attempting Toshiba AC 80bit decode"); + if (decodeToshibaAC(results, offset, kToshibaACBitsLong)) return true; + DPRINTLN("Attempting Toshiba AC 56bit decode"); + if (decodeToshibaAC(results, offset, kToshibaACBitsShort)) return true; #endif #if DECODE_MIDEA DPRINTLN("Attempting Midea decode"); @@ -852,6 +856,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, DPRINTLN("Attempting Zepeal decode"); if (decodeZepeal(results, offset)) return true; #endif // DECODE_ZEPEAL +#if DECODE_SANYO_AC + DPRINTLN("Attempting Sanyo AC decode"); + if (decodeSanyoAc(results, offset)) return true; +#endif // DECODE_SANYO_AC // Typically new protocols are added above this line. } #if DECODE_HASH diff --git a/lib/IRremoteESP8266-2.7.8/src/IRrecv.h b/lib/IRremoteESP8266-2.7.8/src/IRrecv.h index 36da8df1b..62cdeed6b 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRrecv.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRrecv.h @@ -283,8 +283,14 @@ class IRrecv { bool decodeSanyoLC7461(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kSanyoLC7461Bits, - bool strict = true); + const bool strict = true); #endif +#if DECODE_SANYO_AC + bool decodeSanyoAc(decode_results *results, + uint16_t offset = kStartOffset, + const uint16_t nbits = kSanyoAcBits, + const bool strict = true); +#endif // DECODE_SANYO_AC #if DECODE_MITSUBISHI bool decodeMitsubishi(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kMitsubishiBits, @@ -469,7 +475,7 @@ class IRrecv { #endif #if DECODE_TOSHIBA_AC bool decodeToshibaAC(decode_results *results, uint16_t offset = kStartOffset, - const uint16_t nbytes = kToshibaACBits, + const uint16_t nbits = kToshibaACBits, const bool strict = true); #endif #if DECODE_TROTEC diff --git a/lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h b/lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h index 4490baa3b..007645073 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h @@ -201,6 +201,13 @@ #define SEND_SANYO _IR_ENABLE_DEFAULT_ #endif // SEND_SANYO +#ifndef DECODE_SANYO_AC +#define DECODE_SANYO_AC _IR_ENABLE_DEFAULT_ +#endif // DECODE_SANYO_AC +#ifndef SEND_SANYO_AC +#define SEND_SANYO_AC _IR_ENABLE_DEFAULT_ +#endif // SEND_SANYO_AC + #ifndef DECODE_MITSUBISHI #define DECODE_MITSUBISHI _IR_ENABLE_DEFAULT_ #endif // DECODE_MITSUBISHI @@ -674,7 +681,7 @@ DECODE_NEOCLIMA || DECODE_DAIKIN176 || DECODE_DAIKIN128 || \ DECODE_AMCOR || DECODE_DAIKIN152 || DECODE_MITSUBISHI136 || \ DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3 || \ - DECODE_HITACHI_AC344 || DECODE_CORONA_AC) + DECODE_HITACHI_AC344 || DECODE_CORONA_AC || DECODE_SANYO_AC) // Add any DECODE to the above if it uses result->state (see kStateSizeMax) // you might also want to add the protocol to hasACState function #define DECODE_AC true // We need some common infrastructure for decoding A/Cs. @@ -802,8 +809,9 @@ enum decode_type_t { CORONA_AC, MIDEA24, ZEPEAL, + SANYO_AC, // Add new entries before this one, and update it to point to the last entry. - kLastDecodeType = ZEPEAL, + kLastDecodeType = SANYO_AC, }; // Message lengths & required repeat values @@ -971,6 +979,8 @@ const uint16_t kSamsungAcBits = kSamsungAcStateLength * 8; const uint16_t kSamsungAcExtendedStateLength = 21; const uint16_t kSamsungAcExtendedBits = kSamsungAcExtendedStateLength * 8; const uint16_t kSamsungAcDefaultRepeat = kNoRepeat; +const uint16_t kSanyoAcStateLength = 9; +const uint16_t kSanyoAcBits = kSanyoAcStateLength * 8; const uint16_t kSanyoSA8650BBits = 12; const uint16_t kSanyoLC7461AddressBits = 13; const uint16_t kSanyoLC7461CommandBits = 8; @@ -999,6 +1009,10 @@ const uint16_t kTecoDefaultRepeat = kNoRepeat; const uint16_t kToshibaACStateLength = 9; const uint16_t kToshibaACBits = kToshibaACStateLength * 8; const uint16_t kToshibaACMinRepeat = kSingleRepeat; +const uint16_t kToshibaACStateLengthShort = kToshibaACStateLength - 2; +const uint16_t kToshibaACBitsShort = kToshibaACStateLengthShort * 8; +const uint16_t kToshibaACStateLengthLong = kToshibaACStateLength + 1; +const uint16_t kToshibaACBitsLong = kToshibaACStateLengthLong * 8; const uint16_t kTrotecStateLength = 9; const uint16_t kTrotecBits = kTrotecStateLength * 8; const uint16_t kTrotecDefaultRepeat = kNoRepeat; diff --git a/lib/IRremoteESP8266-2.7.8/src/IRsend.cpp b/lib/IRremoteESP8266-2.7.8/src/IRsend.cpp index d3e097839..e3537381f 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRsend.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRsend.cpp @@ -721,6 +721,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return kNeoclimaBits; case SAMSUNG_AC: return kSamsungAcBits; + case SANYO_AC: + return kSanyoAcBits; case SHARP_AC: return kSharpAcBits; case TCL112AC: @@ -1152,6 +1154,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state, sendSamsungAC(state, nbytes); break; #endif // SEND_SAMSUNG_AC +#if SEND_SANYO_AC + case SANYO_AC: + sendSanyoAc(state, nbytes); + break; +#endif // SEND_SANYO_AC #if SEND_SHARP_AC case SHARP_AC: sendSharpAc(state, nbytes); diff --git a/lib/IRremoteESP8266-2.7.8/src/IRsend.h b/lib/IRremoteESP8266-2.7.8/src/IRsend.h index fe206583f..0b237ecc0 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRsend.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRsend.h @@ -294,6 +294,11 @@ class IRsend { const uint16_t nbits = kSanyoLC7461Bits, const uint16_t repeat = kNoRepeat); #endif +#if SEND_SANYO_AC + void sendSanyoAc(const uint8_t *data, + const uint16_t nbytes = kSanyoAcStateLength, + const uint16_t repeat = kNoRepeat); +#endif // SEND_SANYO_AC #if SEND_DISH // sendDISH() should typically be called with repeat=3 as DISH devices // expect the code to be sent at least 4 times. (code + 3 repeats = 4 codes) @@ -461,7 +466,7 @@ class IRsend { uint16_t repeat = kNoRepeat); #endif #if SEND_TOSHIBA_AC - void sendToshibaAC(const unsigned char data[], + void sendToshibaAC(const uint8_t data[], const uint16_t nbytes = kToshibaACStateLength, const uint16_t repeat = kToshibaACMinRepeat); #endif diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp b/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp index 7af2ffd0b..80e39b0a1 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp @@ -130,6 +130,7 @@ const PROGMEM char* kTopStr = D_STR_TOP; ///< "Top" const PROGMEM char* kBottomStr = D_STR_BOTTOM; ///< "Bottom" // Compound words/phrases/descriptions from pre-defined words. +const PROGMEM char* kEconoToggleStr = D_STR_ECONOTOGGLE; ///< "Econo Toggle" const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO; ///< "Eye Auto" const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE; ///< "Light Toggle" const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET; ///< "Outside Quiet" @@ -264,5 +265,6 @@ const PROGMEM char *kAllProtocolNamesStr = D_STR_CORONA_AC "\x0" D_STR_MIDEA24 "\x0" D_STR_ZEPEAL "\x0" + D_STR_SANYO_AC "\x0" ///< New protocol strings should be added just above this line. "\x0"; ///< This string requires double null termination. diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtext.h b/lib/IRremoteESP8266-2.7.8/src/IRtext.h index 57ba2858b..73b42edc1 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRtext.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRtext.h @@ -45,6 +45,7 @@ extern const char* kDisplayTempStr; extern const char* kDownStr; extern const char* kDryStr; extern const char* kEconoStr; +extern const char* kEconoToggleStr; extern const char* kEyeAutoStr; extern const char* kEyeStr; extern const char* kFalseStr; @@ -104,10 +105,10 @@ extern const char* kOnStr; extern const char* kOnTimerStr; extern const char* kOutsideQuietStr; extern const char* kOutsideStr; +extern const char* kPowerButtonStr; extern const char* kPowerfulStr; extern const char* kPowerStr; extern const char* kPowerToggleStr; -extern const char* kPowerButtonStr; extern const char* kPreviousPowerStr; extern const char* kProtocolStr; extern const char* kPurifyStr; diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp b/lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp index edd98a2d7..e1f098b28 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp @@ -14,7 +14,7 @@ uint32_t _TimerMs_unittest_now = 0; /// Class constructor. IRtimer::IRtimer() { reset(); } -/// Resets the IRtimer object. +/// Resets the IRtimer object. I.e. The counter starts again from now. void IRtimer::reset() { #ifndef UNIT_TEST start = micros(); @@ -47,7 +47,7 @@ void IRtimer::add(uint32_t usecs) { _IRtimer_unittest_now += usecs; } /// Class constructor. TimerMs::TimerMs() { reset(); } -/// Resets the TimerMs object. +/// Resets the TimerMs object. I.e. The counter starts again from now. void TimerMs::reset() { #ifndef UNIT_TEST start = millis(); diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtimer.h b/lib/IRremoteESP8266-2.7.8/src/IRtimer.h index 1a2215fd5..659819d8f 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRtimer.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRtimer.h @@ -8,7 +8,7 @@ // Classes -/// This class performs a simple timer in useconds since instantiated. +/// This class offers a simple counter in micro-seconds since instantiated. /// @note Handles when the system timer wraps around (once). class IRtimer { public: @@ -20,10 +20,10 @@ class IRtimer { #endif // UNIT_TEST private: - uint32_t start; + uint32_t start; ///< Time in uSeconds when the class was instantiated/reset. }; -/// This class performs a simple timer in milli-seoncds since instantiated. +/// This class offers a simple counter in milli-seconds since instantiated. /// @note Handles when the system timer wraps around (once). class TimerMs { public: @@ -35,6 +35,6 @@ class TimerMs { #endif // UNIT_TEST private: - uint32_t start; + uint32_t start; ///< Time in mSeconds when the class was instantiated/reset. }; #endif // IRTIMER_H_ diff --git a/lib/IRremoteESP8266-2.7.8/src/IRutils.cpp b/lib/IRremoteESP8266-2.7.8/src/IRutils.cpp index 9393fcf2d..beec2fbfb 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRutils.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRutils.cpp @@ -161,6 +161,7 @@ bool hasACState(const decode_type_t protocol) { case NEOCLIMA: case PANASONIC_AC: case SAMSUNG_AC: + case SANYO_AC: case SHARP_AC: case TCL112AC: case TOSHIBA_AC: @@ -915,4 +916,35 @@ namespace irutils { // Merge in the data. *dst |= ((data & mask) << offset); } + + /// Create byte pairs where the second byte of the pair is a bit + /// inverted/flipped copy of the first/previous byte of the pair. + /// @param[in,out] ptr A pointer to the start of array to modify. + /// @param[in] length The byte size of the array. + /// @note A length of `<= 1` will do nothing. + /// @return A ptr to the modified array. + uint8_t * invertBytePairs(uint8_t *ptr, const uint16_t length) { + for (uint16_t i = 1; i < length; i += 2) { + // Code done this way to avoid a compiler warning bug. + uint8_t inv = ~*(ptr + i - 1); + *(ptr + i) = inv; + } + return ptr; + } + + /// Check an array to see if every second byte of a pair is a bit + /// inverted/flipped copy of the first/previous byte of the pair. + /// @param[in] ptr A pointer to the start of array to check. + /// @param[in] length The byte size of the array. + /// @note A length of `<= 1` will always return true. + /// @return true, if every second byte is inverted. Otherwise false. + bool checkInvertedBytePairs(const uint8_t * const ptr, + const uint16_t length) { + for (uint16_t i = 1; i < length; i += 2) { + // Code done this way to avoid a compiler warning bug. + uint8_t inv = ~*(ptr + i - 1); + if (*(ptr + i) != inv) return false; + } + return true; + } } // namespace irutils diff --git a/lib/IRremoteESP8266-2.7.8/src/IRutils.h b/lib/IRremoteESP8266-2.7.8/src/IRutils.h index 3c865dfcf..a3320ae93 100644 --- a/lib/IRremoteESP8266-2.7.8/src/IRutils.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRutils.h @@ -107,5 +107,7 @@ namespace irutils { const uint32_t data); void setBits(uint64_t * const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data); + uint8_t * invertBytePairs(uint8_t *ptr, const uint16_t length); + bool checkInvertedBytePairs(const uint8_t * const ptr, const uint16_t length); } // namespace irutils #endif // IRUTILS_H_ diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp index 2bf0a2db8..106e9c7bf 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp @@ -1,23 +1,28 @@ // Copyright 2020 David Conran - +#include "ir_Airwell.h" +#include #include "IRrecv.h" #include "IRsend.h" +#include "IRtext.h" +#include "IRutils.h" /// @file /// @brief Airwell "Manchester code" based protocol. /// Some other Airwell products use the COOLIX protocol. -// Supports: -// Brand: Airwell, Model: RC08W remote -// Brand: Airwell, Model: RC04 remote -// Brand: Airwell, Model: DLS 21 DCI R410 AW A/C - const uint8_t kAirwellOverhead = 4; const uint16_t kAirwellHalfClockPeriod = 950; // uSeconds const uint16_t kAirwellHdrMark = 3 * kAirwellHalfClockPeriod; // uSeconds const uint16_t kAirwellHdrSpace = 3 * kAirwellHalfClockPeriod; // uSeconds const uint16_t kAirwellFooterMark = 5 * kAirwellHalfClockPeriod; // uSeconds +using irutils::addBoolToString; +using irutils::addModeToString; +using irutils::addFanToString; +using irutils::addTempToString; +using irutils::setBit; +using irutils::setBits; + #if SEND_AIRWELL /// Send an Airwell Manchester Code formatted message. /// Status: BETA / Appears to be working. @@ -74,3 +79,203 @@ bool IRrecv::decodeAirwell(decode_results *results, uint16_t offset, return true; } #endif + +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? +IRAirwellAc::IRAirwellAc(const uint16_t pin, const bool inverted, + const bool use_modulation) + : _irsend(pin, inverted, use_modulation) { stateReset(); } + +/// Set up hardware to be able to send a message. +void IRAirwellAc::begin(void) { _irsend.begin(); } + +/// Get the raw state of the object, suitable to be sent with the appropriate +/// IRsend object method. +/// @return A copy of the internal state. +uint64_t IRAirwellAc::getRaw(void) { + return remote_state; +} + +/// Set the raw state of the object. +/// @param[in] state The raw state from the native IR message. +void IRAirwellAc::setRaw(const uint64_t state) { + remote_state = state; +} + +#if SEND_AIRWELL +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRAirwellAc::send(const uint16_t repeat) { + _irsend.sendAirwell(getRaw(), kAirwellBits, repeat); +} +#endif // SEND_AIRWELL + +/// Reset the internals of the object to a known good state. +void IRAirwellAc::stateReset(void) { + remote_state = kAirwellKnownGoodState; +} + +/// Turn on/off the Power Airwell setting. +/// @param[in] on The desired setting state. +void IRAirwellAc::setPowerToggle(const bool on) { + setBit(&remote_state, kAirwellPowerToggleBit, on); +} + +/// Get the power toggle setting from the internal state. +/// @return A boolean indicating the setting. +bool IRAirwellAc::getPowerToggle(void) { + return GETBIT64(remote_state, kAirwellPowerToggleBit); +} + +/// Get the current operation mode setting. +/// @return The current operation mode. +uint8_t IRAirwellAc::getMode(void) { + return GETBITS64(remote_state, kAirwellModeOffset, kAirwellModeSize); +} + +/// Set the desired operation mode. +/// @param[in] mode The desired operation mode. +void IRAirwellAc::setMode(const uint8_t mode) { + switch (mode) { + case kAirwellFan: + case kAirwellCool: + case kAirwellHeat: + case kAirwellDry: + case kAirwellAuto: + setBits(&remote_state, kAirwellModeOffset, kAirwellModeSize, mode); + break; + default: + setMode(kAirwellAuto); + } + setFan(getFan()); // Ensure the fan is at the correct speed for the new mode. +} + +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRAirwellAc::convertMode(const stdAc::opmode_t mode) { + switch (mode) { + case stdAc::opmode_t::kCool: return kAirwellCool; + case stdAc::opmode_t::kHeat: return kAirwellHeat; + case stdAc::opmode_t::kDry: return kAirwellDry; + case stdAc::opmode_t::kFan: return kAirwellFan; + default: return kAirwellAuto; + } +} + +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::opmode_t IRAirwellAc::toCommonMode(const uint8_t mode) { + switch (mode) { + case kAirwellCool: return stdAc::opmode_t::kCool; + case kAirwellHeat: return stdAc::opmode_t::kHeat; + case kAirwellDry: return stdAc::opmode_t::kDry; + case kAirwellFan: return stdAc::opmode_t::kFan; + default: return stdAc::opmode_t::kAuto; + } +} + +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @note The speed is locked to Low when in Dry mode. +void IRAirwellAc::setFan(const uint8_t speed) { + setBits(&remote_state, kAirwellFanOffset, kAirwellFanSize, + (getMode() == kAirwellDry) ? kAirwellFanLow + : std::min(speed, kAirwellFanAuto)); +} + +/// Get the current fan speed setting. +/// @return The current fan speed. +uint8_t IRAirwellAc::getFan(void) { + return GETBITS64(remote_state, kAirwellFanOffset, kAirwellFanSize); +} + +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRAirwellAc::convertFan(const stdAc::fanspeed_t speed) { + switch (speed) { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: + return kAirwellFanLow; + case stdAc::fanspeed_t::kMedium: + return kAirwellFanMedium; + case stdAc::fanspeed_t::kHigh: + case stdAc::fanspeed_t::kMax: + return kAirwellFanHigh; + default: + return kAirwellFanAuto; + } +} + +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::fanspeed_t IRAirwellAc::toCommonFanSpeed(const uint8_t speed) { + switch (speed) { + case kAirwellFanHigh: return stdAc::fanspeed_t::kMax; + case kAirwellFanMedium: return stdAc::fanspeed_t::kMedium; + case kAirwellFanLow: return stdAc::fanspeed_t::kMin; + default: return stdAc::fanspeed_t::kAuto; + } +} + +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. +void IRAirwellAc::setTemp(const uint8_t degrees) { + uint8_t temp = std::max(kAirwellMinTemp, degrees); + temp = std::min(kAirwellMaxTemp, temp); + setBits(&remote_state, kAirwellTempOffset, kAirwellTempSize, + temp - kAirwellMinTemp + 1); +} + +/// Get the current temperature setting. +/// @return Get current setting for temp. in degrees celsius. +uint8_t IRAirwellAc::getTemp(void) { + return GETBITS64(remote_state, kAirwellTempOffset, + kAirwellTempSize) + kAirwellMinTemp - 1; +} + +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. +stdAc::state_t IRAirwellAc::toCommon(void) { + stdAc::state_t result; + result.protocol = decode_type_t::AIRWELL; + result.power = getPowerToggle(); + result.mode = toCommonMode(getMode()); + result.celsius = true; + result.degrees = getTemp(); + result.fanspeed = toCommonFanSpeed(getFan()); + // Not supported. + result.model = -1; + result.turbo = false; + result.swingv = stdAc::swingv_t::kOff; + result.swingh = stdAc::swingh_t::kOff; + result.light = false; + result.filter = false; + result.econo = false; + result.quiet = false; + result.clean = false; + result.beep = false; + result.sleep = -1; + result.clock = -1; + return result; +} + +/// Convert the current internal state into a human readable string. +/// @return A human readable string. +String IRAirwellAc::toString(void) { + String result = ""; + result.reserve(70); // Reserve some heap for the string to reduce fragging. + result += addBoolToString(getPowerToggle(), kPowerToggleStr, false); + result += addModeToString(getMode(), kAirwellAuto, kAirwellCool, + kAirwellHeat, kAirwellDry, kAirwellFan); + result += addFanToString(getFan(), kAirwellFanHigh, kAirwellFanLow, + kAirwellFanAuto, kAirwellFanAuto, + kAirwellFanMedium); + result += addTempToString(getTemp()); + return result; +} diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.h b/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.h new file mode 100644 index 000000000..3ffbd21c7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.h @@ -0,0 +1,97 @@ +// Copyright 2020 David Conran + +/// @file +/// @brief Airwell "Manchester code" based protocol. +/// Some other Airwell products use the COOLIX protocol. + +// Supports: +// Brand: Airwell, Model: RC08W remote +// Brand: Airwell, Model: RC04 remote +// Brand: Airwell, Model: DLS 21 DCI R410 AW A/C + +#ifndef IR_AIRWELL_H_ +#define IR_AIRWELL_H_ + +#define __STDC_LIMIT_MACROS +#include +#ifndef UNIT_TEST +#include +#endif +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif + + +// Constants +const uint64_t kAirwellKnownGoodState = 0x140500002; // Mode Fan, Speed 1, 25C +// Temperature +const uint8_t kAirwellMinTemp = 16; // Celsius +const uint8_t kAirwellMaxTemp = 30; // Celsius +const uint8_t kAirwellTempSize = 4; // Bits +const uint8_t kAirwellTempOffset = 19; // 0b1111 << 19 +// Fan +const uint8_t kAirwellFanSize = 2; // Bits +const uint8_t kAirwellFanOffset = 28; // 0b11 << 28 +const uint8_t kAirwellFanLow = 0; // 0b00 +const uint8_t kAirwellFanMedium = 1; // 0b01 +const uint8_t kAirwellFanHigh = 2; // 0b10 +const uint8_t kAirwellFanAuto = 3; // 0b11 +// Modes +const uint8_t kAirwellModeSize = 3; // Bits +const uint8_t kAirwellModeOffset = 30; // 0b111 << 30 +const uint8_t kAirwellCool = 1; // 0b001 +const uint8_t kAirwellHeat = 2; // 0b010 +const uint8_t kAirwellAuto = 3; // 0b011 +const uint8_t kAirwellDry = 4; // 0b100 +const uint8_t kAirwellFan = 5; // 0b101 +// Power +const uint8_t kAirwellPowerToggleBit = 33; // 0b1 << 33 + + +// Classes +/// Class for handling detailed Airwell A/C messages. +class IRAirwellAc { + public: + explicit IRAirwellAc(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + void stateReset(); +#if SEND_AIRWELL + void send(const uint16_t repeat = kAirwellMinRepeats); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. + int8_t calibrate(void) { return _irsend.calibrate(); } +#endif // SEND_AIRWELL + void begin(); + void setPowerToggle(const bool on); + bool getPowerToggle(); + void setTemp(const uint8_t temp); + uint8_t getTemp(); + void setFan(const uint8_t speed); + uint8_t getFan(); + void setMode(const uint8_t mode); + uint8_t getMode(); + uint64_t getRaw(); + void setRaw(const uint64_t state); + uint8_t convertMode(const stdAc::opmode_t mode); + uint8_t convertFan(const stdAc::fanspeed_t speed); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + stdAc::state_t toCommon(void); + String toString(); +#ifndef UNIT_TEST + + private: + IRsend _irsend; ///< Instance of the IR send class +#else + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif + uint64_t remote_state; // The state of the IR remote in native IR code form. + void checksum(void); +}; +#endif // IR_AIRWELL_H_ diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h index 8c11dfb9f..35e62302b 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h @@ -598,7 +598,7 @@ class IRDaikinESP { }; /// Class for handling detailed Daikin 312-bit A/C messages. -/// Code by crankyoldgit, Reverse engineering analysis by sheppy99 +/// @note Code by crankyoldgit, Reverse engineering analysis by sheppy99 class IRDaikin2 { public: explicit IRDaikin2(const uint16_t pin, const bool inverted = false, @@ -859,8 +859,7 @@ class IRDaikin176 { }; /// Class for handling detailed Daikin 128-bit A/C messages. -/// Code by crankyoldgit. -/// Analysis by Daniel Vena +/// @note Code by crankyoldgit. Analysis by Daniel Vena class IRDaikin128 { public: explicit IRDaikin128(const uint16_t pin, const bool inverted = false, diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp index 368f9995a..68d562fce 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp @@ -52,6 +52,8 @@ using irutils::addModeToString; using irutils::addModelToString; using irutils::addFanToString; using irutils::addTempToString; +using irutils::checkInvertedBytePairs; +using irutils::invertBytePairs; using irutils::minsToString; using irutils::setBit; using irutils::setBits; @@ -1047,8 +1049,7 @@ void IRHitachiAc424::stateReset(void) { /// Update the internal consistency check for the protocol. void IRHitachiAc424::setInvertedStates(void) { - for (uint8_t i = 3; i < kHitachiAc424StateLength - 1; i += 2) - remote_state[i + 1] = ~remote_state[i]; + invertBytePairs(remote_state + 3, kHitachiAc424StateLength - 3); } /// Set up hardware to be able to send a message. @@ -1402,8 +1403,7 @@ void IRHitachiAc3::stateReset(void) { /// @param[in] length The size of the state array. /// @note This is this protocols integrity check. void IRHitachiAc3::setInvertedStates(const uint16_t length) { - for (uint8_t i = 3; i < length - 1; i += 2) - remote_state[i + 1] = ~remote_state[i]; + if (length > 3) invertBytePairs(remote_state + 3, length - 3); } /// Check if every second byte of the state, after the fixed header @@ -1413,9 +1413,7 @@ void IRHitachiAc3::setInvertedStates(const uint16_t length) { /// @note This is this protocols integrity check. bool IRHitachiAc3::hasInvertedStates(const uint8_t state[], const uint16_t length) { - for (uint8_t i = 3; i < length - 1; i += 2) - if ((state[i + 1] ^ state[i]) != 0xFF) return false; - return true; + return (length <= 3 || checkInvertedBytePairs(state + 3, length - 3)); } /// Set up hardware to be able to send a message. diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp index 65fe91883..40b141176 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp @@ -400,6 +400,7 @@ uint8_t IRLgAc::getTemp(void) { void IRLgAc::setFan(const uint8_t speed) { switch (speed) { case kLgAcFanAuto: + case kLgAcFanLowest: case kLgAcFanLow: case kLgAcFanMedium: case kLgAcFanHigh: @@ -469,12 +470,12 @@ stdAc::opmode_t IRLgAc::toCommonMode(const uint8_t mode) { /// @return The native equivilant of the enum. uint8_t IRLgAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { - case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kMin: return kLgAcFanLowest; case stdAc::fanspeed_t::kLow: return kLgAcFanLow; case stdAc::fanspeed_t::kMedium: return kLgAcFanMedium; case stdAc::fanspeed_t::kHigh: - case stdAc::fanspeed_t::kMax: return kHitachiAcFanHigh; - default: return kHitachiAcFanAuto; + case stdAc::fanspeed_t::kMax: return kLgAcFanHigh; + default: return kLgAcFanAuto; } } @@ -486,6 +487,7 @@ stdAc::fanspeed_t IRLgAc::toCommonFanSpeed(const uint8_t speed) { case kLgAcFanHigh: return stdAc::fanspeed_t::kMax; case kLgAcFanMedium: return stdAc::fanspeed_t::kMedium; case kLgAcFanLow: return stdAc::fanspeed_t::kLow; + case kLgAcFanLowest: return stdAc::fanspeed_t::kMin; default: return stdAc::fanspeed_t::kAuto; } } @@ -528,7 +530,7 @@ String IRLgAc::toString(void) { kLgAcHeat, kLgAcDry, kLgAcFan); result += addTempToString(getTemp()); result += addFanToString(getFan(), kLgAcFanHigh, kLgAcFanLow, - kLgAcFanAuto, kLgAcFanAuto, kLgAcFanMedium); + kLgAcFanAuto, kLgAcFanLowest, kLgAcFanMedium); } return result; } diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_LG.h b/lib/IRremoteESP8266-2.7.8/src/ir_LG.h index bf0cdd0b6..1748d143e 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_LG.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_LG.h @@ -32,7 +32,8 @@ const uint8_t kLgAcChecksumOffset = 0; // Nr. of bits const uint8_t kLgAcChecksumSize = kNibbleSize; // Nr. of bits const uint8_t kLgAcFanOffset = 4; // Nr. of bits const uint8_t kLgAcFanSize = 3; // Nr. of bits -const uint8_t kLgAcFanLow = 0; // 0b000 +const uint8_t kLgAcFanLowest = 0; // 0b000 +const uint8_t kLgAcFanLow = 1; // 0b001 const uint8_t kLgAcFanMedium = 2; // 0b010 const uint8_t kLgAcFanHigh = 4; // 0b100 const uint8_t kLgAcFanAuto = 5; // 0b101 diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp index 5d270d3d4..d02088cef 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp @@ -3,7 +3,9 @@ /// @brief Support for Midea protocols. /// Midea added by crankyoldgit & bwze. /// send: bwze/crankyoldgit, decode: crankyoldgit +/// @note SwingV has the function of an Ion Filter on Danby A/C units. /// @see https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing +/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/1213 #include "ir_Midea.h" #include "ir_NEC.h" @@ -99,6 +101,7 @@ void IRMideaAC::stateReset(void) { // Power On, Mode Auto, Fan Auto, Temp = 25C/77F remote_state = 0xA1826FFFFF62; _SwingVToggle = false; + _EconoToggle = false; } /// Set up hardware to be able to send a message. @@ -110,11 +113,14 @@ void IRMideaAC::begin(void) { _irsend.begin(); } void IRMideaAC::send(const uint16_t repeat) { this->checksum(); // Ensure correct checksum before sending. _irsend.sendMidea(remote_state, kMideaBits, repeat); - // Handle toggling the swing if we need to. - if (_SwingVToggle && !isSwingVToggle()) { + // Handle toggling the swing & econo mode if we need to. + if (_SwingVToggle && !isSwingVToggle()) _irsend.sendMidea(kMideaACToggleSwingV, kMideaBits, repeat); - } - _SwingVToggle = false; // The toggle message has been sent, so reset. + if (_EconoToggle && !isEconoToggle()) + _irsend.sendMidea(kMideaACToggleEcono, kMideaBits, repeat); + // The toggle messages has been sent, so reset. + _SwingVToggle = false; + _EconoToggle = false; } #endif // SEND_MIDEA @@ -246,22 +252,42 @@ bool IRMideaAC::getSleep(void) { } /// Set the A/C to toggle the vertical swing toggle for the next send. +/// @note On Danby A/C units, this is associated with the Ion Filter instead. /// @param[in] on true, the setting is on. false, the setting is off. void IRMideaAC::setSwingVToggle(const bool on) { _SwingVToggle = on; } /// Is the current state a vertical swing toggle message? +/// @note On Danby A/C units, this is associated with the Ion Filter instead. /// @return true, it is. false, it isn't. bool IRMideaAC::isSwingVToggle(void) { return remote_state == kMideaACToggleSwingV; } // Get the vertical swing toggle state of the A/C. +/// @note On Danby A/C units, this is associated with the Ion Filter instead. /// @return true, the setting is on. false, the setting is off. bool IRMideaAC::getSwingVToggle(void) { _SwingVToggle |= isSwingVToggle(); return _SwingVToggle; } +/// Set the A/C to toggle the Econo (energy saver) mode for the next send. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRMideaAC::setEconoToggle(const bool on) { _EconoToggle = on; } + +/// Is the current state an Econo (energy saver) toggle message? +/// @return true, it is. false, it isn't. +bool IRMideaAC::isEconoToggle(void) { + return remote_state == kMideaACToggleEcono; +} + +// Get the Econo (energy saver) toggle state of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRMideaAC::getEconoToggle(void) { + _EconoToggle |= isEconoToggle(); + return _EconoToggle; +} + /// Calculate the checksum for a given state. /// @param[in] state The value to calc the checksum of. /// @return The calculated checksum value. @@ -376,6 +402,7 @@ stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) { result.degrees = this->getTemp(result.celsius); result.fanspeed = this->toCommonFanSpeed(this->getFan()); result.sleep = this->getSleep() ? 0 : -1; + result.econo = this->getEconoToggle(); return result; } @@ -384,7 +411,8 @@ stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) { String IRMideaAC::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. - if (!isSwingVToggle()) { + bool needComma = false; + if (!isSwingVToggle() && !isEconoToggle()) { result += addBoolToString(getPower(), kPowerStr, false); result += addModeToString(getMode(), kMideaACAuto, kMideaACCool, kMideaACHeat, kMideaACDry, kMideaACFan); @@ -396,9 +424,10 @@ String IRMideaAC::toString(void) { result += addFanToString(getFan(), kMideaACFanHigh, kMideaACFanLow, kMideaACFanAuto, kMideaACFanAuto, kMideaACFanMed); result += addBoolToString(getSleep(), kSleepStr); + needComma = true; } - result += addBoolToString(getSwingVToggle(), kSwingVToggleStr, - !isSwingVToggle()); + result += addBoolToString(getSwingVToggle(), kSwingVToggleStr, needComma); + result += addBoolToString(getEconoToggle(), kEconoToggleStr); return result; } diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Midea.h b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.h index b7825f569..96a1ffec4 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Midea.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.h @@ -11,6 +11,10 @@ // Brand: Comfee, Model: MPD1-12CRN7 A/C (MIDEA) // Brand: Keystone, Model: RG57H4(B)BGEF remote (MIDEA) // Brand: Midea, Model: FS40-7AR Stand Fan (MIDEA24) +// Brand: Danby, Model: DAC080BGUWDB (MIDEA) +// Brand: Danby, Model: DAC100BGUWDB (MIDEA) +// Brand: Danby, Model: DAC120BGUWDB (MIDEA) +// Brand: Danby, Model: R09C/BCGE remote (MIDEA) #ifndef IR_MIDEA_H_ #define IR_MIDEA_H_ @@ -26,6 +30,10 @@ #include "IRsend_test.h" #endif +#if DANBY_DAC + kSwingVToggleStr = kIonStr; +#endif + // Constants const uint8_t kMideaACTempOffset = 24; const uint8_t kMideaACTempSize = 5; // Bits @@ -49,6 +57,9 @@ const uint8_t kMideaACFanHigh = 3; // 0b11 const uint8_t kMideaACSleepOffset = 38; const uint8_t kMideaACPowerOffset = 39; const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C; +// For Danby DAC unit, the Ionizer toggle is the same as ToggleSwingV +// const uint64_t kMideaACToggleIonizer = 0x0000A201FFFFFF7C; +const uint64_t kMideaACToggleEcono = 0x0000A202FFFFFF7E; // Legacy defines. (Deprecated) #define MIDEA_AC_COOL kMideaACCool @@ -104,6 +115,9 @@ class IRMideaAC { bool isSwingVToggle(void); void setSwingVToggle(const bool on); bool getSwingVToggle(void); + bool isEconoToggle(void); + void setEconoToggle(const bool on); + bool getEconoToggle(void); uint8_t convertMode(const stdAc::opmode_t mode); uint8_t convertFan(const stdAc::fanspeed_t speed); static stdAc::opmode_t toCommonMode(const uint8_t mode); @@ -121,6 +135,7 @@ class IRMideaAC { #endif // UNIT_TEST uint64_t remote_state; ///< The state of the IR remote in IR code form. bool _SwingVToggle; + bool _EconoToggle; void checksum(void); static uint8_t calcChecksum(const uint64_t state); }; diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h index 04c7bf57d..60f997095 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h @@ -163,7 +163,7 @@ const uint8_t kMitsubishi112SwingHAuto = 0b1100; /// Class for handling detailed Mitsubishi 144-bit A/C messages. -/// Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control +/// @note Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control /// @warning Consider this very alpha code. Seems to work, but not validated. class IRMitsubishiAC { public: @@ -282,7 +282,7 @@ class IRMitsubishi136 { void checksum(void); }; - +/// Class for handling detailed Mitsubishi 122-bit A/C messages. class IRMitsubishi112 { public: explicit IRMitsubishi112(const uint16_t pin, const bool inverted = false, diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp index 7747ded6d..8a52bb762 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp @@ -33,6 +33,8 @@ using irutils::addIntToString; using irutils::addLabeledString; using irutils::addModeToString; using irutils::addTempToString; +using irutils::checkInvertedBytePairs; +using irutils::invertBytePairs; using irutils::setBit; using irutils::setBits; @@ -321,32 +323,24 @@ bool IRMitsubishiHeavy152Ac::checkZmsSig(const uint8_t *state) { } /// Calculate the checksum for the current internal state of the remote. -/// Note: Technically it has no checksum, but does has inverted byte pairs. +/// Note: Technically it has no checksum, but does have inverted byte pairs. void IRMitsubishiHeavy152Ac::checksum(void) { - for (uint8_t i = kMitsubishiHeavySigLength - 2; - i < kMitsubishiHeavy152StateLength; - i += 2) { - remote_state[i + 1] = ~remote_state[i]; - } + const uint8_t kOffset = kMitsubishiHeavySigLength - 2; + invertBytePairs(remote_state + kOffset, + kMitsubishiHeavy152StateLength - kOffset); } /// Verify the checksum is valid for a given state. /// @param[in] state The array to verify the checksum of. /// @param[in] length The length/size of the state array. /// @return true, if the state has a valid checksum. Otherwise, false. -/// Note: Technically it has no checksum, but does has inverted byte pairs. +/// Note: Technically it has no checksum, but does have inverted byte pairs. bool IRMitsubishiHeavy152Ac::validChecksum(const uint8_t *state, const uint16_t length) { // Assume anything too short is fine. if (length < kMitsubishiHeavySigLength) return true; - // Check all the byte pairs. - for (uint16_t i = kMitsubishiHeavySigLength - 2; - i < length; - i += 2) { - // XOR of a byte and it's self inverted should be 0xFF; - if ((state[i] ^ state[i + 1]) != 0xFF) return false; - } - return true; + const uint8_t kOffset = kMitsubishiHeavySigLength - 2; + return checkInvertedBytePairs(state + kOffset, length - kOffset); } /// Convert a stdAc::opmode_t enum into its native mode. @@ -856,20 +850,18 @@ bool IRMitsubishiHeavy88Ac::checkZjsSig(const uint8_t *state) { } /// Calculate the checksum for the current internal state of the remote. -/// Note: Technically it has no checksum, but does has inverted byte pairs. +/// Note: Technically it has no checksum, but does have inverted byte pairs. void IRMitsubishiHeavy88Ac::checksum(void) { - for (uint8_t i = kMitsubishiHeavySigLength - 2; - i < kMitsubishiHeavy88StateLength; - i += 2) { - remote_state[i + 1] = ~remote_state[i]; - } + const uint8_t kOffset = kMitsubishiHeavySigLength - 2; + invertBytePairs(remote_state + kOffset, + kMitsubishiHeavy88StateLength - kOffset); } /// Verify the checksum is valid for a given state. /// @param[in] state The array to verify the checksum of. /// @param[in] length The length/size of the state array. /// @return true, if the state has a valid checksum. Otherwise, false. -/// Note: Technically it has no checksum, but does has inverted byte pairs. +/// Note: Technically it has no checksum, but does have inverted byte pairs. bool IRMitsubishiHeavy88Ac::validChecksum(const uint8_t *state, const uint16_t length) { return IRMitsubishiHeavy152Ac::validChecksum(state, length); diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp index d5ac89765..90f58c6ed 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp @@ -8,9 +8,12 @@ /// @see http://www.adrian-kingston.com/IRFormatPioneer.htm /// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/547 /// @see https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1220 // Supports: // Brand: Pioneer, Model: AV Receivers +// Brand: Pioneer, Model: VSX-324 AV Receiver +// Brand: Pioneer, Model: AXD7690 Remote #define __STDC_LIMIT_MACROS #include @@ -20,22 +23,15 @@ #include "IRutils.h" // Constants -const uint16_t kPioneerTick = 534; -const uint16_t kPioneerHdrMarkTicks = 16; -const uint16_t kPioneerHdrMark = kPioneerHdrMarkTicks * kPioneerTick; -const uint16_t kPioneerHdrSpaceTicks = 8; -const uint16_t kPioneerHdrSpace = kPioneerHdrSpaceTicks * kPioneerTick; -const uint16_t kPioneerBitMarkTicks = 1; -const uint16_t kPioneerBitMark = kPioneerBitMarkTicks * kPioneerTick; -const uint16_t kPioneerOneSpaceTicks = 3; -const uint16_t kPioneerOneSpace = kPioneerOneSpaceTicks * kPioneerTick; -const uint16_t kPioneerZeroSpaceTicks = 1; -const uint16_t kPioneerZeroSpace = kPioneerZeroSpaceTicks * kPioneerTick; -const uint16_t kPioneerMinCommandLengthTicks = 159; -const uint32_t kPioneerMinCommandLength = kPioneerMinCommandLengthTicks * - kPioneerTick; -const uint16_t kPioneerMinGapTicks = 47; -const uint32_t kPioneerMinGap = kPioneerMinGapTicks * kPioneerTick; +// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1220 +const uint16_t kPioneerTick = 534; ///< uSeconds. +const uint16_t kPioneerHdrMark = 8506; ///< uSeconds. +const uint16_t kPioneerHdrSpace = 4191; ///< uSeconds. +const uint16_t kPioneerBitMark = 568; ///< uSeconds. +const uint16_t kPioneerOneSpace = 1542; ///< uSeconds. +const uint16_t kPioneerZeroSpace = 487; ///< uSeconds. +const uint32_t kPioneerMinCommandLength = 84906; ///< uSeconds. +const uint32_t kPioneerMinGap = 25181; ///< uSeconds. #if SEND_PIONEER /// Send a raw Pioneer formatted message. diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp index 02aa4abdd..c3ff5ec7d 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp @@ -53,6 +53,14 @@ const uint16_t kSamsungAcBitMark = 586; const uint16_t kSamsungAcOneSpace = 1432; const uint16_t kSamsungAcZeroSpace = 436; +// Data from https://github.com/crankyoldgit/IRremoteESP8266/issues/1220 +// Values calculated based on the average of ten messages. +const uint16_t kSamsung36HdrMark = 4515; /// < uSeconds +const uint16_t kSamsung36HdrSpace = 4438; /// < uSeconds +const uint16_t kSamsung36BitMark = 512; /// < uSeconds +const uint16_t kSamsung36OneSpace = 1468; /// < uSeconds +const uint16_t kSamsung36ZeroSpace = 490; /// < uSeconds + using irutils::addBoolToString; using irutils::addFanToString; using irutils::addIntToString; @@ -146,7 +154,7 @@ bool IRrecv::decodeSAMSUNG(decode_results *results, uint16_t offset, #if SEND_SAMSUNG36 /// Send a Samsung 36-bit formatted message. -/// Status: Alpha / Experimental. +/// Status: STABLE / Works on real devices. /// @param[in] data The message to be sent. /// @param[in] nbits The number of bits of message to be sent. /// @param[in] repeat The number of times the command is to be repeated. @@ -156,16 +164,16 @@ void IRsend::sendSamsung36(const uint64_t data, const uint16_t nbits, if (nbits < 16) return; // To small to send. for (uint16_t r = 0; r <= repeat; r++) { // Block #1 (16 bits) - sendGeneric(kSamsungHdrMark, kSamsungHdrSpace, - kSamsungBitMark, kSamsungOneSpace, - kSamsungBitMark, kSamsungZeroSpace, - kSamsungBitMark, kSamsungHdrSpace, + sendGeneric(kSamsung36HdrMark, kSamsung36HdrSpace, + kSamsung36BitMark, kSamsung36OneSpace, + kSamsung36BitMark, kSamsung36ZeroSpace, + kSamsung36BitMark, kSamsung36HdrSpace, data >> (nbits - 16), 16, 38, true, 0, kDutyDefault); // Block #2 (The rest, typically 20 bits) sendGeneric(0, 0, // No header - kSamsungBitMark, kSamsungOneSpace, - kSamsungBitMark, kSamsungZeroSpace, - kSamsungBitMark, kSamsungMinGap, // Gap is just a guess. + kSamsung36BitMark, kSamsung36OneSpace, + kSamsung36BitMark, kSamsung36ZeroSpace, + kSamsung36BitMark, kSamsungMinGap, // Gap is just a guess. // Mask off the rest of the bits. data & ((1ULL << (nbits - 16)) - 1), nbits - 16, 38, true, 0, kDutyDefault); @@ -175,7 +183,7 @@ void IRsend::sendSamsung36(const uint64_t data, const uint16_t nbits, #if DECODE_SAMSUNG36 /// Decode the supplied Samsung36 message. -/// Status: Alpha / Experimental +/// Status: STABLE / Expected to work. /// @param[in,out] results Ptr to the data to decode & where to store the result /// @param[in] offset The starting index to use when attempting to decode the /// raw data. Typically/Defaults to kStartOffset. @@ -198,10 +206,10 @@ bool IRrecv::decodeSamsung36(decode_results *results, uint16_t offset, uint16_t used; used = matchGeneric(results->rawbuf + offset, &data, results->rawlen - offset, 16, - kSamsungHdrMark, kSamsungHdrSpace, - kSamsungBitMark, kSamsungOneSpace, - kSamsungBitMark, kSamsungZeroSpace, - kSamsungBitMark, kSamsungHdrSpace, false); + kSamsung36HdrMark, kSamsung36HdrSpace, + kSamsung36BitMark, kSamsung36OneSpace, + kSamsung36BitMark, kSamsung36ZeroSpace, + kSamsung36BitMark, kSamsung36HdrSpace, false); if (!used) return false; offset += used; // Data (Block #2) @@ -209,9 +217,9 @@ bool IRrecv::decodeSamsung36(decode_results *results, uint16_t offset, if (!matchGeneric(results->rawbuf + offset, &data2, results->rawlen - offset, nbits - 16, 0, 0, - kSamsungBitMark, kSamsungOneSpace, - kSamsungBitMark, kSamsungZeroSpace, - kSamsungBitMark, kSamsungMinGap, true)) return false; + kSamsung36BitMark, kSamsung36OneSpace, + kSamsung36BitMark, kSamsung36ZeroSpace, + kSamsung36BitMark, kSamsungMinGap, true)) return false; data <<= (nbits - 16); data += data2; diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h index fa6f9f2f3..d5c9955ec 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h @@ -14,6 +14,8 @@ // Brand: Samsung, Model: DB93-16761C remote // Brand: Samsung, Model: IEC-R03 remote // Brand: Samsung, Model: AK59-00167A Bluray remote (SAMSUNG36) +// Brand: Samsung, Model: AH59-02692E Soundbar remote (SAMSUNG36) +// Brand: Samsung, Model: HW-J551 Soundbar (SAMSUNG36) // Brand: Samsung, Model: AR09FSSDAWKNFA A/C (SAMSUNG_AC) // Brand: Samsung, Model: AR12KSFPEWQNET A/C (SAMSUNG_AC) // Brand: Samsung, Model: AR12HSSDBWKNEU A/C (SAMSUNG_AC) diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp index 25baf380b..04a9f4f2f 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp @@ -1,6 +1,6 @@ // Copyright 2009 Ken Shirriff // Copyright 2016 marcosamarinho -// Copyright 2017 David Conran +// Copyright 2017-2020 David Conran /// @file /// @brief Support for Sanyo protocols. @@ -11,15 +11,27 @@ /// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf /// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp /// @see http://slydiman.narod.ru/scr/kb/sanyo.htm +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211 +/// @see https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?usp=sharing -// Supports: -// Brand: Sanyo, Model: SA 8650B - disabled -// Brand: Sanyo, Model: LC7461 transmitter IC (SANYO_LC7461) - +#include "ir_Sanyo.h" #include +#include #include "IRrecv.h" #include "IRsend.h" +#include "IRtext.h" +#include "IRutils.h" +using irutils::addBoolToString; +using irutils::addFanToString; +using irutils::addIntToString; +using irutils::addLabeledString; +using irutils::addModeToString; +using irutils::addTempToString; +using irutils::minsToString; +using irutils::sumNibbles; +using irutils::setBit; +using irutils::setBits; // Constants // Sanyo SA 8650B @@ -48,6 +60,14 @@ const uint16_t kSanyoLc7461MinGap = (kSanyoLc7461OneSpace + kSanyoLc7461ZeroSpace) / 2) + kSanyoLc7461BitMark); +const uint16_t kSanyoAcHdrMark = 8500; ///< uSeconds +const uint16_t kSanyoAcHdrSpace = 4200; ///< uSeconds +const uint16_t kSanyoAcBitMark = 500; ///< uSeconds +const uint16_t kSanyoAcOneSpace = 1600; ///< uSeconds +const uint16_t kSanyoAcZeroSpace = 550; ///< uSeconds +const uint32_t kSanyoAcGap = kDefaultMessageGap; ///< uSeconds (Guess only) +const uint16_t kSanyoAcFreq = 38000; ///< Hz. (Guess only) + #if SEND_SANYO /// Construct a Sanyo LC7461 message. /// @param[in] address The 13 bit value of the address(Custom) portion of the @@ -221,3 +241,453 @@ bool IRrecv::decodeSanyo(decode_results *results, uint16_t nbits, bool strict) { } */ #endif // DECODE_SANYO + + +#if SEND_SANYO_AC +/// Send a SanyoAc formatted message. +/// Status: STABLE / Reported as working. +/// @param[in] data An array of bytes containing the IR command. +/// @param[in] nbytes Nr. of bytes of data in the array. +/// @param[in] repeat Nr. of times the message is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211 +void IRsend::sendSanyoAc(const uint8_t data[], const uint16_t nbytes, + const uint16_t repeat) { + // Header + Data + Footer + sendGeneric(kSanyoAcHdrMark, kSanyoAcHdrSpace, + kSanyoAcBitMark, kSanyoAcOneSpace, + kSanyoAcBitMark, kSanyoAcZeroSpace, + kSanyoAcBitMark, kSanyoAcGap, + data, nbytes, kSanyoAcFreq, false, repeat, kDutyDefault); +} +#endif // SEND_SANYO_AC + +#if DECODE_SANYO_AC +/// Decode the supplied SanyoAc message. +/// Status: STABLE / Reported as working. +/// @param[in,out] results Ptr to the data to decode & where to store the decode +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return A boolean. True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211 +bool IRrecv::decodeSanyoAc(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (strict && nbits != kSanyoAcBits) + return false; + + // Header + Data + Footer + if (!matchGeneric(results->rawbuf + offset, results->state, + results->rawlen - offset, nbits, + kSanyoAcHdrMark, kSanyoAcHdrSpace, + kSanyoAcBitMark, kSanyoAcOneSpace, + kSanyoAcBitMark, kSanyoAcZeroSpace, + kSanyoAcBitMark, kSanyoAcGap, + true, kUseDefTol, kMarkExcess, false)) return false; + // Compliance + if (strict) + if (!IRSanyoAc::validChecksum(results->state, nbits / 8)) return false; + + // Success + results->decode_type = decode_type_t::SANYO_AC; + results->bits = nbits; + // No need to record the state as we stored it as we decoded it. + // As we use result->state, we don't record value, address, or command as it + // is a union data type. + return true; +} +#endif // DECODE_SANYO_AC + +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? +IRSanyoAc::IRSanyoAc(const uint16_t pin, const bool inverted, + const bool use_modulation) + : _irsend(pin, inverted, use_modulation) { stateReset(); } + +/// Reset the state of the remote to a known good state/sequence. +/// @see https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?ts=5f0190a5#gid=1050142776&range=A2:B2 +void IRSanyoAc::stateReset(void) { + static const uint8_t kReset[kSanyoAcStateLength] = { + 0x6A, 0x6D, 0x51, 0x00, 0x10, 0x45, 0x00, 0x00, 0x33}; + memcpy(remote_state, kReset, kSanyoAcStateLength); +} + +/// Set up hardware to be able to send a message. +void IRSanyoAc::begin(void) { _irsend.begin(); } + +#if SEND_SANYO_AC +/// Send the current internal state as IR messages. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRSanyoAc::send(const uint16_t repeat) { + _irsend.sendSanyoAc(getRaw(), kSanyoAcStateLength, repeat); +} +#endif // SEND_SANYO_AC + +/// Get a PTR to the internal state/code for this protocol with all integrity +/// checks passing. +/// @return PTR to a code for this protocol based on the current internal state. +uint8_t* IRSanyoAc::getRaw(void) { + checksum(); + return remote_state; +} + +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. +void IRSanyoAc::setRaw(const uint8_t newState[]) { + memcpy(remote_state, newState, kSanyoAcStateLength); +} + +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. +uint8_t IRSanyoAc::calcChecksum(const uint8_t state[], + const uint16_t length) { + return length ? sumNibbles(state, length - 1) : 0; +} + +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. +bool IRSanyoAc::validChecksum(const uint8_t state[], const uint16_t length) { + return length && state[length - 1] == IRSanyoAc::calcChecksum(state, length); +} + +/// Calculate & set the checksum for the current internal state of the remote. +void IRSanyoAc::checksum(void) { + // Stored the checksum value in the last byte. + remote_state[kSanyoAcStateLength - 1] = calcChecksum(remote_state); +} + + +/// Set the requested power state of the A/C to on. +void IRSanyoAc::on(void) { setPower(true); } + +/// Set the requested power state of the A/C to off. +void IRSanyoAc::off(void) { setPower(false); } + +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRSanyoAc::setPower(const bool on) { + setBits(&remote_state[kSanyoAcPowerByte], kSanyoAcPowerOffset, + kSanyoAcPowerSize, on ? kSanyoAcPowerOn : kSanyoAcPowerOff); +} + +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. +bool IRSanyoAc::getPower(void) { + return GETBITS8(remote_state[kSanyoAcPowerByte], kSanyoAcPowerOffset, + kSanyoAcPowerSize) == kSanyoAcPowerOn; +} + +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. +uint8_t IRSanyoAc::getMode(void) { + return GETBITS8(remote_state[kSanyoAcModeByte], kSanyoAcModeOffset, + kSanyoAcModeSize); +} + +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @note If we get an unexpected mode, default to AUTO. +void IRSanyoAc::setMode(const uint8_t mode) { + switch (mode) { + case kSanyoAcAuto: + case kSanyoAcCool: + case kSanyoAcDry: + case kSanyoAcHeat: + setBits(&remote_state[kSanyoAcModeByte], kSanyoAcModeOffset, + kSanyoAcModeSize, mode); + break; + default: setMode(kSanyoAcAuto); + } +} + +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRSanyoAc::convertMode(const stdAc::opmode_t mode) { + switch (mode) { + case stdAc::opmode_t::kCool: return kSanyoAcCool; + case stdAc::opmode_t::kHeat: return kSanyoAcHeat; + case stdAc::opmode_t::kDry: return kSanyoAcDry; + default: return kSanyoAcAuto; + } +} + +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::opmode_t IRSanyoAc::toCommonMode(const uint8_t mode) { + switch (mode) { + case kSanyoAcCool: return stdAc::opmode_t::kCool; + case kSanyoAcHeat: return stdAc::opmode_t::kHeat; + case kSanyoAcDry: return stdAc::opmode_t::kDry; + default: return stdAc::opmode_t::kAuto; + } +} + +/// Set the temperature at a given location. +/// @param[out] ptr A pointer to a temperature byte. +/// @param[in] degrees The temperature in degrees celsius. +void IRSanyoAc::_setTemp(uint8_t *ptr, const uint8_t degrees) { + uint8_t temp = std::max((uint8_t)kSanyoAcTempMin, degrees); + temp = std::min((uint8_t)kSanyoAcTempMax, temp); + setBits(ptr, kSanyoAcTempOffset, kSanyoAcTempSize, temp - kSanyoAcTempDelta); +} + +/// Get the temperature from a given location. +/// @param[in] ptr A pointer to a temperature byte. +/// @return The current setting for temp. in degrees celsius. +uint8_t IRSanyoAc::_getTemp(uint8_t *ptr) { + return GETBITS8(*ptr, kSanyoAcTempOffset, kSanyoAcTempSize) + + kSanyoAcTempDelta; +} + +/// Set the desired temperature. +/// @param[in] degrees The temperature in degrees celsius. +void IRSanyoAc::setTemp(const uint8_t degrees) { + _setTemp(&remote_state[kSanyoAcTempByte], degrees); +} + +/// Get the current desired temperature setting. +/// @return The current setting for temp. in degrees celsius. +uint8_t IRSanyoAc::getTemp(void) { + return _getTemp(&remote_state[kSanyoAcTempByte]); +} + +/// Set the sensor temperature. +/// @param[in] degrees The temperature in degrees celsius. +void IRSanyoAc::setSensorTemp(const uint8_t degrees) { + _setTemp(&remote_state[kSanyoAcSensorByte], degrees); +} + +/// Get the current sensor temperature setting. +/// @return The current setting for temp. in degrees celsius. +uint8_t IRSanyoAc::getSensorTemp(void) { + return _getTemp(&remote_state[kSanyoAcSensorByte]); +} + +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +void IRSanyoAc::setFan(const uint8_t speed) { + setBits(&remote_state[kSanyoAcModeByte], kSanyoAcFanOffset, kSanyoAcFanSize, + speed); +} + +/// Get the current fan speed setting. +/// @return The current fan speed/mode. +uint8_t IRSanyoAc::getFan(void) { + return GETBITS8(remote_state[kSanyoAcModeByte], kSanyoAcFanOffset, + kSanyoAcFanSize); +} + +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRSanyoAc::convertFan(const stdAc::fanspeed_t speed) { + switch (speed) { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: return kSanyoAcFanLow; + case stdAc::fanspeed_t::kMedium: return kSanyoAcFanMedium; + case stdAc::fanspeed_t::kHigh: + case stdAc::fanspeed_t::kMax: return kSanyoAcFanHigh; + default: return kSanyoAcFanAuto; + } +} + +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::fanspeed_t IRSanyoAc::toCommonFanSpeed(const uint8_t spd) { + switch (spd) { + case kSanyoAcFanHigh: return stdAc::fanspeed_t::kHigh; + case kSanyoAcFanMedium: return stdAc::fanspeed_t::kMedium; + case kSanyoAcFanLow: return stdAc::fanspeed_t::kLow; + default: return stdAc::fanspeed_t::kAuto; + } +} + +/// Get the vertical swing setting of the A/C. +/// @return The current swing mode setting. +uint8_t IRSanyoAc::getSwingV(void) { + return GETBITS8(remote_state[kSanyoAcPowerByte], kSanyoAcSwingVOffset, + kSanyoAcSwingVSize); +} + +/// Set the vertical swing setting of the A/C. +/// @param[in] setting The value of the desired setting. +void IRSanyoAc::setSwingV(const uint8_t setting) { + if (setting == kSanyoAcSwingVAuto || + (setting >= kSanyoAcSwingVLowest && setting <= kSanyoAcSwingVHighest)) + setBits(&remote_state[kSanyoAcPowerByte], kSanyoAcSwingVOffset, + kSanyoAcSwingVSize, setting); + + else + setSwingV(kSanyoAcSwingVAuto); +} + +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRSanyoAc::convertSwingV(const stdAc::swingv_t position) { + switch (position) { + case stdAc::swingv_t::kHighest: return kSanyoAcSwingVHighest; + case stdAc::swingv_t::kHigh: return kSanyoAcSwingVHigh; + case stdAc::swingv_t::kMiddle: return kSanyoAcSwingVUpperMiddle; + case stdAc::swingv_t::kLow: return kSanyoAcSwingVLow; + case stdAc::swingv_t::kLowest: return kSanyoAcSwingVLowest; + default: return kSanyoAcSwingVAuto; + } +} + +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] setting A native position to convert. +/// @return The common vertical swing position. +stdAc::swingv_t IRSanyoAc::toCommonSwingV(const uint8_t setting) { + switch (setting) { + case kSanyoAcSwingVHighest: return stdAc::swingv_t::kHighest; + case kSanyoAcSwingVHigh: return stdAc::swingv_t::kHigh; + case kSanyoAcSwingVUpperMiddle: + case kSanyoAcSwingVLowerMiddle: return stdAc::swingv_t::kMiddle; + case kSanyoAcSwingVLow: return stdAc::swingv_t::kLow; + case kSanyoAcSwingVLowest: return stdAc::swingv_t::kLowest; + default: return stdAc::swingv_t::kAuto; + } +} + +/// Set the Sleep (Night Setback) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRSanyoAc::setSleep(const bool on) { + setBit(&remote_state[kSanyoAcSleepByte], kSanyoAcSleepBit, on); +} + +/// Get the Sleep (Night Setback) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRSanyoAc::getSleep(void) { + return GETBIT8(remote_state[kSanyoAcSleepByte], kSanyoAcSleepBit); +} + +/// Set the Sensor Location setting of the A/C. +/// i.e. Where the ambient temperature is measured. +/// @param[in] location true is Unit/Wall, false is Remote/Room. +void IRSanyoAc::setSensor(const bool location) { + setBit(&remote_state[kSanyoAcSensorByte], kSanyoAcSensorBit, location); +} + +/// Get the Sensor Location setting of the A/C. +/// i.e. Where the ambient temperature is measured. +/// @return true is Unit/Wall, false is Remote/Room. +bool IRSanyoAc::getSensor(void) { + return GETBIT8(remote_state[kSanyoAcSensorByte], kSanyoAcSensorBit); +} + +/// Set the Beep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRSanyoAc::setBeep(const bool on) { + setBit(&remote_state[kSanyoAcSensorByte], kSanyoAcBeepBit, on); +} + +/// Get the Beep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRSanyoAc::getBeep(void) { + return GETBIT8(remote_state[kSanyoAcSensorByte], kSanyoAcBeepBit); +} + +/// Get the nr of minutes the Off Timer is set to. +/// @return The timer time expressed as the number of minutes. +/// A value of 0 means the Off Timer is off/disabled. +/// @note The internal precission has a resolution of 1 hour. +uint16_t IRSanyoAc::getOffTimer(void) { + if (GETBIT8(remote_state[kSanyoAcModeByte], kSanyoAcOffTimerEnableBit)) + return GETBITS8(remote_state[kSanyoAcOffHourByte], kSanyoAcOffHourOffset, + kSanyoAcOffHourSize) * 60; + else + return 0; +} + +/// Set the nr of minutes for the Off Timer. +/// @param[in] mins The timer time expressed as nr. of minutes. +/// A value of 0 means the Off Timer is off/disabled. +/// @note The internal precission has a resolution of 1 hour. +void IRSanyoAc::setOffTimer(const uint16_t mins) { + const uint8_t hours = std::min((uint8_t)(mins / 60), kSanyoAcHourMax); + setBit(&remote_state[kSanyoAcModeByte], kSanyoAcOffTimerEnableBit, hours > 0); + setBits(&remote_state[kSanyoAcOffHourByte], kSanyoAcOffHourOffset, + kSanyoAcOffHourSize, hours); +} + +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. +stdAc::state_t IRSanyoAc::toCommon(void) { + stdAc::state_t result; + result.protocol = decode_type_t::SANYO_AC; + result.model = -1; // Not supported. + result.power = getPower(); + result.mode = toCommonMode(getMode()); + result.celsius = true; + result.degrees = getTemp(); + result.fanspeed = toCommonFanSpeed(getFan()); + result.sleep = getSleep() ? 0 : -1; + result.swingv = toCommonSwingV(getSwingV()); + result.beep = getBeep(); + // Not supported. + result.swingh = stdAc::swingh_t::kOff; + result.turbo = false; + result.econo = false; + result.light = false; + result.filter = false; + result.quiet = false; + result.clean = false; + result.clock = -1; + return result; +} + +/// Convert the current internal state into a human readable string. +/// @return A human readable string. +String IRSanyoAc::toString(void) { + String result = ""; + result.reserve(140); + result += addBoolToString(getPower(), kPowerStr, false); + result += addModeToString(getMode(), kSanyoAcAuto, kSanyoAcCool, + kSanyoAcHeat, kSanyoAcDry, kSanyoAcAuto); + result += addTempToString(getTemp()); + result += addFanToString(getFan(), kSanyoAcFanHigh, kSanyoAcFanLow, + kSanyoAcFanAuto, kSanyoAcFanAuto, + kSanyoAcFanMedium); + result += addIntToString(getSwingV(), kSwingVStr); + result += kSpaceLBraceStr; + switch (getSwingV()) { + case kSanyoAcSwingVHighest: result += kHighestStr; break; + case kSanyoAcSwingVHigh: result += kHighStr; break; + case kSanyoAcSwingVUpperMiddle: + result += kUpperStr; + result += ' '; + result += kMiddleStr; + break; + case kSanyoAcSwingVLowerMiddle: + result += kLowerStr; + result += ' '; + result += kMiddleStr; + break; + case kSanyoAcSwingVLow: result += kLowStr; break; + case kSanyoAcSwingVLowest: result += kLowestStr; break; + case kSanyoAcSwingVAuto: result += kAutoStr; break; + default: result += kUnknownStr; + } + result += ')'; + result += addBoolToString(getSleep(), kSleepStr); + result += addBoolToString(getBeep(), kBeepStr); + result += addLabeledString(getSensor() ? kRoomStr : kWallStr, kSensorStr); + result += kCommaSpaceStr; + result += kSensorStr; + result += ' '; + result += addTempToString(getSensorTemp(), true, false); + const uint16_t offtime = getOffTimer(); + result += addLabeledString(offtime ? minsToString(offtime) : kOffStr, + kOffTimerStr); + return result; +} diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.h b/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.h new file mode 100644 index 000000000..9cdde61c8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.h @@ -0,0 +1,163 @@ +// Copyright 2020 David Conran + +/// @file +/// @brief Support for Sanyo protocols. +/// Sanyo LC7461 support originally by marcosamarinho +/// Sanyo SA 8650B originally added from +/// https://github.com/shirriff/Arduino-IRremote/ +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp +/// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp +/// @see http://slydiman.narod.ru/scr/kb/sanyo.htm +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1211 +/// @see https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?usp=sharing + +// Supports: +// Brand: Sanyo, Model: SA 8650B - disabled +// Brand: Sanyo, Model: LC7461 transmitter IC (SANYO_LC7461) +// Brand: Sanyo, Model: SAP-K121AHA A/C (SANYO_AC) +// Brand: Sanyo, Model: RCS-2HS4E remote (SANYO_AC) +// Brand: Sanyo, Model: SAP-K242AH A/C (SANYO_AC) +// Brand: Sanyo, Model: RCS-2S4E remote (SANYO_AC) + +#ifndef IR_SANYO_H_ +#define IR_SANYO_H_ + +#define __STDC_LIMIT_MACROS +#include +#ifdef ARDUINO +#include +#endif +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif + +// Constants + +// Sanyo A/C +// Ref: https://docs.google.com/spreadsheets/d/1dYfLsnYvpjV-SgO8pdinpfuBIpSzm8Q1R5SabrLeskw/edit?usp=sharing +// Byte[0] - 0x6A (Fixed?) +// Byte[1] - Address + Temperature +const uint8_t kSanyoAcTempByte = 1; ///< Index +const uint8_t kSanyoAcTempOffset = 0; ///< Mask 0b000xxxxx +const uint8_t kSanyoAcTempSize = 5; ///< Mask 0b000xxxxx +const uint8_t kSanyoAcTempMin = 16; ///< Celsius +const uint8_t kSanyoAcTempMax = 30; ///< Celsius +const uint8_t kSanyoAcTempDelta = 4; ///< Celsius to Native Temp difference. +// Byte[2] - Ambient Temp + Sensor +const uint8_t kSanyoAcSensorByte = 2; ///< Index +const uint8_t kSanyoAcSensorBit = 2; ///< Mask 0b00x00000 +// Ambient Temp Mask 0b000xxxxx +const uint8_t kSanyoAcBeepBit = 6; ///< Mask 0b0x000000 +// Byte[3] - Off Hour +const uint8_t kSanyoAcOffHourByte = 3; ///< Index +const uint8_t kSanyoAcOffHourOffset = 0; ///< Mask 0b0000xxxx +const uint8_t kSanyoAcOffHourSize = 4; ///< Mask 0b0000xxxx +const uint8_t kSanyoAcHourMax = 15; ///< 0b1111 +// Byte[4] - Mode + Fan + Timer Enables +const uint8_t kSanyoAcModeByte = 4; ///< Index +const uint8_t kSanyoAcModeOffset = 4; ///< Mask 0b0xxx0000 +const uint8_t kSanyoAcModeSize = 3; ///< Mask 0b0xxx0000 +const uint8_t kSanyoAcHeat = 1; ///< 0b001 +const uint8_t kSanyoAcCool = 2; ///< 0b010 +const uint8_t kSanyoAcDry = 3; ///< 0b011 +const uint8_t kSanyoAcAuto = 4; ///< 0b100 +const uint8_t kSanyoAcOffTimerEnableBit = 2; ///< Mask 0b00000x00 +const uint8_t kSanyoAcFanOffset = 0; ///< Mask 0b000000xx +const uint8_t kSanyoAcFanSize = 2; ///< Mask 0b000000xx +const uint8_t kSanyoAcFanAuto = 0; ///< 0b00 +const uint8_t kSanyoAcFanHigh = 1; ///< 0b01 +const uint8_t kSanyoAcFanLow = 2; ///< 0b10 +const uint8_t kSanyoAcFanMedium = 3; ///< 0b11 +// Byte[5] - Power + SwingV +const uint8_t kSanyoAcPowerByte = 5; ///< Index +const uint8_t kSanyoAcPowerOffset = 6; ///< Mask 0bxx000000 +const uint8_t kSanyoAcPowerSize = 2; ///< Mask 0bxx000000 +// const uint8_t kSanyoAcPowerStandby = 0b00; ///< Standby? +const uint8_t kSanyoAcPowerOff = 0b01; ///< Off +const uint8_t kSanyoAcPowerOn = 0b10; ///< On +const uint8_t kSanyoAcSwingVOffset = 0; ///< Mask 0b00000xxx +const uint8_t kSanyoAcSwingVSize = 3; ///< Mask 0b00000xxx +const uint8_t kSanyoAcSwingVAuto = 0; ///< 0b000 +const uint8_t kSanyoAcSwingVLowest = 2; ///< 0b010 +const uint8_t kSanyoAcSwingVLow = 3; ///< 0b011 +const uint8_t kSanyoAcSwingVLowerMiddle = 4; ///< 0b100 +const uint8_t kSanyoAcSwingVUpperMiddle = 5; ///< 0b101 +const uint8_t kSanyoAcSwingVHigh = 6; ///< 0b110 +const uint8_t kSanyoAcSwingVHighest = 7; ///< 0b111 +// Byte[6] - Sleep +const uint8_t kSanyoAcSleepByte = 6; ///< Index +const uint8_t kSanyoAcSleepBit = 3; ///< Mask 0b0000x000 +// Byte[8] - Checksum (8-bit Sum of all preceeding nibbles) + + +// Classes +/// Class for handling detailed Sanyo A/C messages. +class IRSanyoAc { + public: + explicit IRSanyoAc(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + void stateReset(void); +#if SEND_SANYO_AC + void send(const uint16_t repeat = kNoRepeat); + /// Run the calibration to calculate uSec timing offsets for this platform. + /// @return The uSec timing offset needed per modulation of the IR Led. + /// @note This will produce a 65ms IR signal pulse at 38kHz. + /// Only ever needs to be run once per object instantiation, if at all. + int8_t calibrate(void) { return _irsend.calibrate(); } +#endif // SEND_SANYO_AC + void begin(void); + void on(void); + void off(void); + void setPower(const bool on); + bool getPower(void); + void setTemp(const uint8_t degrees); + uint8_t getTemp(void); + void setSensorTemp(const uint8_t degrees); + uint8_t getSensorTemp(void); + void setFan(const uint8_t speed); + uint8_t getFan(void); + void setMode(const uint8_t mode); + uint8_t getMode(void); + void setSleep(const bool on); + bool getSleep(void); + void setSensor(const bool location); + bool getSensor(void); + void setBeep(const bool on); + bool getBeep(void); + void setSwingV(const uint8_t setting); + uint8_t getSwingV(void); + void setRaw(const uint8_t newState[]); + uint8_t* getRaw(void); + uint16_t getOffTimer(void); + void setOffTimer(const uint16_t mins); + static bool validChecksum(const uint8_t state[], + const uint16_t length = kSanyoAcStateLength); + uint8_t convertMode(const stdAc::opmode_t mode); + uint8_t convertFan(const stdAc::fanspeed_t speed); + uint8_t convertSwingV(const stdAc::swingv_t position); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + static stdAc::swingv_t toCommonSwingV(const uint8_t setting); + stdAc::state_t toCommon(void); + String toString(void); +#ifndef UNIT_TEST + + private: + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kSanyoAcStateLength]; ///< The state in IR code form. + void checksum(void); + static uint8_t calcChecksum(const uint8_t state[], + const uint16_t length = kSanyoAcStateLength); + void _setTemp(uint8_t *ptr, const uint8_t degrees); + uint8_t _getTemp(uint8_t *ptr); +}; + +#endif // IR_SANYO_H_ diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp index c28b700f8..f799885b3 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp @@ -4,6 +4,9 @@ /// @brief Support for Toshiba protocols. /// @see https://github.com/r45635/HVAC-IR-Control /// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1205 +/// @see https://www.toshiba-carrier.co.jp/global/about/index.htm +/// @see http://www.toshiba-carrier.co.th/AboutUs/Pages/CompanyProfile.aspx #include "ir_Toshiba.h" #include @@ -21,10 +24,10 @@ // Toshiba A/C const uint16_t kToshibaAcHdrMark = 4400; const uint16_t kToshibaAcHdrSpace = 4300; -const uint16_t kToshibaAcBitMark = 543; -const uint16_t kToshibaAcOneSpace = 1623; -const uint16_t kToshibaAcZeroSpace = 472; -const uint16_t kToshibaAcMinGap = 7048; +const uint16_t kToshibaAcBitMark = 580; +const uint16_t kToshibaAcOneSpace = 1600; +const uint16_t kToshibaAcZeroSpace = 490; +const uint16_t kToshibaAcMinGap = 7400; using irutils::addBoolToString; using irutils::addFanToString; @@ -32,6 +35,8 @@ using irutils::addIntToString; using irutils::addLabeledString; using irutils::addModeToString; using irutils::addTempToString; +using irutils::checkInvertedBytePairs; +using irutils::invertBytePairs; using irutils::setBit; using irutils::setBits; @@ -41,10 +46,8 @@ using irutils::setBits; /// @param[in] data The message to be sent. /// @param[in] nbytes The number of bytes of message to be sent. /// @param[in] repeat The number of times the command is to be repeated. -void IRsend::sendToshibaAC(const unsigned char data[], const uint16_t nbytes, +void IRsend::sendToshibaAC(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { - if (nbytes < kToshibaACStateLength) - return; // Not enough bytes to send a proper message. sendGeneric(kToshibaAcHdrMark, kToshibaAcHdrSpace, kToshibaAcBitMark, kToshibaAcOneSpace, kToshibaAcBitMark, kToshibaAcZeroSpace, kToshibaAcBitMark, kToshibaAcMinGap, data, nbytes, 38, true, @@ -58,7 +61,7 @@ void IRsend::sendToshibaAC(const unsigned char data[], const uint16_t nbytes, /// @param[in] use_modulation Is frequency modulation to be used? IRToshibaAC::IRToshibaAC(const uint16_t pin, const bool inverted, const bool use_modulation) - : _irsend(pin, inverted, use_modulation) { this->stateReset(); } + : _irsend(pin, inverted, use_modulation) { stateReset(); } /// Reset the state of the remote to a known good state/sequence. /// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L103 @@ -66,24 +69,72 @@ void IRToshibaAC::stateReset(void) { static const uint8_t kReset[kToshibaACStateLength] = { 0xF2, 0x0D, 0x03, 0xFC, 0x01}; memcpy(remote_state, kReset, kToshibaACStateLength); - mode_state = getMode(true); + setTemp(22); // Remote defaults to 22C after factory reset. So do the same. + setSwing(kToshibaAcSwingOff); + prev_mode = getMode(); } /// Set up hardware to be able to send a message. void IRToshibaAC::begin(void) { _irsend.begin(); } #if SEND_TOSHIBA_AC -/// Send the current internal state as an IR message. +/// Send the current internal state as IR messages. /// @param[in] repeat Nr. of times the message will be repeated. void IRToshibaAC::send(const uint16_t repeat) { - _irsend.sendToshibaAC(getRaw(), kToshibaACStateLength, repeat); + _backupState(); + _irsend.sendToshibaAC(getRaw(), getStateLength(), repeat); + if (_send_swing && (getStateLength() != kToshibaACStateLengthShort)) { + setStateLength(kToshibaACStateLengthShort); + // Swing settings expect the min temp to be set. + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1205#issuecomment-653922374 + setTemp(kToshibaAcMinTemp); + setSwing(_swing_mode); + _irsend.sendToshibaAC(getRaw(), getStateLength(), repeat); + _restoreState(); + } + _send_swing = false; } #endif // SEND_TOSHIBA_AC -/// Get a PTR to the internal state/code for this protocol. +/// Get the length of the supplied Toshiba state per it's protocol structure. +/// @param[in] state The array to get the built-in length from. +/// @param[in] size The physical size of the state array. +/// @return Nr. of bytes in use for the provided state message. +uint16_t IRToshibaAC::getInternalStateLength(const uint8_t state[], + const uint16_t size) { + if (size < kToshibaAcLengthByte) return 0; + return std::min((uint16_t)(state[kToshibaAcLengthByte] + kToshibaAcMinLength), + kToshibaACStateLengthLong); +} + +/// Get the length of the current internal state per the protocol structure. +/// @return Nr. of bytes in use for the current internal state message. +uint16_t IRToshibaAC::getStateLength(void) { + return getInternalStateLength(remote_state, kToshibaACStateLengthLong); +} + +/// Set the internal length of the current internal state per the protocol. +/// @param[in] size Nr. of bytes in use for the current internal state message. +void IRToshibaAC::setStateLength(const uint16_t size) { + if (size < kToshibaAcMinLength) return; + remote_state[kToshibaAcLengthByte] = size - kToshibaAcMinLength; +} + +/// Make a copy of the internal code-form A/C state. +void IRToshibaAC::_backupState(void) { + memcpy(backup, remote_state, kToshibaACStateLengthLong); +} + +/// Recover the internal code-form A/C state from the backup. +void IRToshibaAC::_restoreState(void) { + memcpy(remote_state, backup, kToshibaACStateLengthLong); +} + +/// Get a PTR to the internal state/code for this protocol with all integrity +/// checks passing. /// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRToshibaAC::getRaw(void) { - this->checksum(); + checksum(getStateLength()); return remote_state; } @@ -91,7 +142,8 @@ uint8_t* IRToshibaAC::getRaw(void) { /// @param[in] newState A valid code for this protocol. void IRToshibaAC::setRaw(const uint8_t newState[]) { memcpy(remote_state, newState, kToshibaACStateLength); - mode_state = this->getMode(true); + prev_mode = getMode(); + _send_swing = true; } /// Calculate the checksum for a given state. @@ -100,13 +152,7 @@ void IRToshibaAC::setRaw(const uint8_t newState[]) { /// @return The calculated checksum value. uint8_t IRToshibaAC::calcChecksum(const uint8_t state[], const uint16_t length) { - uint8_t checksum = 0; - // Only calculate it for valid lengths. - if (length > 1) { - // Checksum is simple XOR of all bytes except the last one. - for (uint8_t i = 0; i < length - 1; i++) checksum ^= state[i]; - } - return checksum; + return length ? xorBytes(state, length - 1) : 0; } /// Verify the checksum is valid for a given state. @@ -114,17 +160,27 @@ uint8_t IRToshibaAC::calcChecksum(const uint8_t state[], /// @param[in] length The length/size of the array. /// @return true, if the state has a valid checksum. Otherwise, false. bool IRToshibaAC::validChecksum(const uint8_t state[], const uint16_t length) { - return (length > 1 && state[length - 1] == IRToshibaAC::calcChecksum(state, - length)); + return length >= kToshibaAcMinLength && + state[length - 1] == IRToshibaAC::calcChecksum(state, length) && + checkInvertedBytePairs(state, kToshibaAcInvertedLength) && + IRToshibaAC::getInternalStateLength(state, length) == length; } /// Calculate & set the checksum for the current internal state of the remote. /// @param[in] length The length/size of the internal array to checksum. - void IRToshibaAC::checksum(const uint16_t length) { // Stored the checksum value in the last byte. - if (length > 1) remote_state[length - 1] = this->calcChecksum(remote_state, - length); + if (length >= kToshibaAcMinLength) { + // Set/clear the short msg bit. + setBit(&remote_state[4], kToshibaAcShortMsgBit, + getStateLength() == kToshibaACStateLengthShort); + // Set/clear the long msg bit. + setBit(&remote_state[4], kToshibaAcLongMsgBit, + getStateLength() == kToshibaACStateLengthLong); + invertBytePairs(remote_state, kToshibaAcInvertedLength); + // Always do the Xor checksum LAST! + remote_state[length - 1] = calcChecksum(remote_state, length); + } } /// Set the requested power state of the A/C to on. @@ -136,19 +192,18 @@ void IRToshibaAC::off(void) { setPower(false); } /// Change the power setting. /// @param[in] on true, the setting is on. false, the setting is off. void IRToshibaAC::setPower(const bool on) { - setBit(&remote_state[6], kToshibaAcPowerOffset, !on); // Cleared when on. - if (on) - setMode(mode_state); - else - setBits(&remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize, - kToshibaAcHeat); + if (on) { // On + // If not already on, pick the last non-off mode used + if (!getPower()) setMode(prev_mode); + } else { // Off + setMode(kToshibaAcOff); + } } - /// Get the value of the current power setting. /// @return true, the setting is on. false, the setting is off. bool IRToshibaAC::getPower(void) { - return !GETBIT8(remote_state[6], kToshibaAcPowerOffset); + return getMode(true) != kToshibaAcOff; } /// Set the temperature. @@ -187,32 +242,104 @@ uint8_t IRToshibaAC::getFan(void) { return --fan; } +/// Get the swing setting of the A/C. +/// @param[in] raw Calculate the answer from just the state data. +/// @return The current swing mode setting. +uint8_t IRToshibaAC::getSwing(const bool raw) { + return raw ? GETBITS8(remote_state[5], kToshibaAcSwingOffset, + kToshibaAcSwingSize) : _swing_mode; +} + +/// Set the swing setting of the A/C. +/// @param[in] setting The value of the desired setting. +void IRToshibaAC::setSwing(const uint8_t setting) { + switch (setting) { + case kToshibaAcSwingStep: + case kToshibaAcSwingOn: + case kToshibaAcSwingOff: + _send_swing = true; + _swing_mode = setting; + if (getStateLength() == kToshibaACStateLengthShort) + setBits(&remote_state[5], kToshibaAcSwingOffset, kToshibaAcSwingSize, + setting); + } +} + /// Get the operating mode setting of the A/C. -/// @param[in] useRaw Indicate to get the mode from the internal state array. +/// @param[in] raw Get the value without any intelligent processing. /// @return The current operating mode setting. -uint8_t IRToshibaAC::getMode(const bool useRaw) { - if (useRaw) - return GETBITS8(remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize); - else - return mode_state; +uint8_t IRToshibaAC::getMode(const bool raw) { + const uint8_t mode = GETBITS8(remote_state[6], kToshibaAcModeOffset, + kToshibaAcModeSize); + if (raw) return mode; + switch (mode) { + case kToshibaAcOff: return prev_mode; + default: return mode; + } } /// Set the operating mode of the A/C. /// @param[in] mode The desired operating mode. /// @note If we get an unexpected mode, default to AUTO. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1205#issuecomment-654446771 void IRToshibaAC::setMode(const uint8_t mode) { + if (mode != prev_mode) + // Changing mode or power turns Econo & Turbo to off on a real remote. + // Setting the internal message length to "normal" will do that. + setStateLength(kToshibaACStateLength); switch (mode) { case kToshibaAcAuto: case kToshibaAcCool: case kToshibaAcDry: case kToshibaAcHeat: - mode_state = mode; - // Only adjust the remote_state if we have power set to on. - if (getPower()) - setBits(&remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize, - mode_state); - return; - default: this->setMode(kToshibaAcAuto); // There is no Fan mode. + case kToshibaAcFan: + prev_mode = mode; + // FALL-THRU + case kToshibaAcOff: + setBits(&remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize, + mode); + break; + default: setMode(kToshibaAcAuto); + } +} + +/// Get the Turbo (Powerful) setting of the A/C. +/// @return true, if the current setting is on. Otherwise, false. +bool IRToshibaAC::getTurbo(void) { + if (getStateLength() == kToshibaACStateLengthLong) + return remote_state[8] == kToshibaAcTurboOn; + return false; +} + +/// Set the Turbo (Powerful) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// Note: Turbo mode is mutually exclusive with Economy mode. +void IRToshibaAC::setTurbo(const bool on) { + if (on) { + remote_state[8] = kToshibaAcTurboOn; + setStateLength(kToshibaACStateLengthLong); + } else { + if (!getEcono()) setStateLength(kToshibaACStateLength); + } +} + +/// Get the Economy mode setting of the A/C. +/// @return true, if the current setting is on. Otherwise, false. +bool IRToshibaAC::getEcono(void) { + if (getStateLength() == kToshibaACStateLengthLong) + return remote_state[8] == kToshibaAcEconoOn; + return false; +} + +/// Set the Economy mode setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// Note: Economy mode is mutually exclusive with Turbo mode. +void IRToshibaAC::setEcono(const bool on) { + if (on) { + remote_state[8] = kToshibaAcEconoOn; + setStateLength(kToshibaACStateLengthLong); + } else { + if (!getTurbo()) setStateLength(kToshibaACStateLength); } } @@ -224,7 +351,8 @@ uint8_t IRToshibaAC::convertMode(const stdAc::opmode_t mode) { case stdAc::opmode_t::kCool: return kToshibaAcCool; case stdAc::opmode_t::kHeat: return kToshibaAcHeat; case stdAc::opmode_t::kDry: return kToshibaAcDry; - // No Fan mode. + case stdAc::opmode_t::kFan: return kToshibaAcFan; + case stdAc::opmode_t::kOff: return kToshibaAcOff; default: return kToshibaAcAuto; } } @@ -251,6 +379,8 @@ stdAc::opmode_t IRToshibaAC::toCommonMode(const uint8_t mode) { case kToshibaAcCool: return stdAc::opmode_t::kCool; case kToshibaAcHeat: return stdAc::opmode_t::kHeat; case kToshibaAcDry: return stdAc::opmode_t::kDry; + case kToshibaAcFan: return stdAc::opmode_t::kFan; + case kToshibaAcOff: return stdAc::opmode_t::kOff; default: return stdAc::opmode_t::kAuto; } } @@ -280,12 +410,13 @@ stdAc::state_t IRToshibaAC::toCommon(void) { result.celsius = true; result.degrees = this->getTemp(); result.fanspeed = this->toCommonFanSpeed(this->getFan()); + result.swingv = (getSwing() == kToshibaAcSwingOn) ? stdAc::swingv_t::kAuto + : stdAc::swingv_t::kOff; + result.turbo = getTurbo(); + result.econo = getEcono(); // Not supported. - result.turbo = false; result.light = false; result.filter = false; - result.econo = false; - result.swingv = stdAc::swingv_t::kOff; result.swingh = stdAc::swingh_t::kOff; result.quiet = false; result.clean = false; @@ -299,14 +430,33 @@ stdAc::state_t IRToshibaAC::toCommon(void) { /// @return A human readable string. String IRToshibaAC::toString(void) { String result = ""; - result.reserve(40); - result += addBoolToString(getPower(), kPowerStr, false); - result += addModeToString(getMode(), kToshibaAcAuto, kToshibaAcCool, - kToshibaAcHeat, kToshibaAcDry, kToshibaAcAuto); - result += addTempToString(getTemp()); - result += addFanToString(getFan(), kToshibaAcFanMax, kToshibaAcFanMin, - kToshibaAcFanAuto, kToshibaAcFanAuto, - kToshibaAcFanMed); + result.reserve(80); + result += addTempToString(getTemp(), true, false); + switch (getStateLength()) { + case kToshibaACStateLengthShort: + result += addIntToString(getSwing(true), kSwingVStr); + result += kSpaceLBraceStr; + switch (getSwing(true)) { + case kToshibaAcSwingOff: result += kOffStr; break; + case kToshibaAcSwingOn: result += kOnStr; break; + case kToshibaAcSwingStep: result += kStepStr; break; + default: result += kUnknownStr; + } + result += ')'; + break; + case kToshibaACStateLengthLong: + case kToshibaACStateLength: + default: + result += addBoolToString(getPower(), kPowerStr); + if (getPower()) + result += addModeToString(getMode(), kToshibaAcAuto, kToshibaAcCool, + kToshibaAcHeat, kToshibaAcDry, kToshibaAcFan); + result += addFanToString(getFan(), kToshibaAcFanMax, kToshibaAcFanMin, + kToshibaAcFanAuto, kToshibaAcFanAuto, + kToshibaAcFanMed); + result += addBoolToString(getTurbo(), kTurboStr); + result += addBoolToString(getEcono(), kEconoStr); + } return result; } @@ -322,8 +472,16 @@ String IRToshibaAC::toString(void) { bool IRrecv::decodeToshibaAC(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance - if (strict && nbits != kToshibaACBits) - return false; // Must be called with the correct nr. of bytes. + if (strict) { + switch (nbits) { // Must be called with the correct nr. of bits. + case kToshibaACBits: + case kToshibaACBitsShort: + case kToshibaACBitsLong: + break; + default: + return false; + } + } // Match Header + Data + Footer if (!matchGeneric(results->rawbuf + offset, results->state, @@ -336,7 +494,7 @@ bool IRrecv::decodeToshibaAC(decode_results* results, uint16_t offset, // Compliance if (strict) { // Check that the checksum of the message is correct. - if (!IRToshibaAC::validChecksum(results->state)) return false; + if (!IRToshibaAC::validChecksum(results->state, nbits / 8)) return false; } // Success diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h index 0e5022ae7..803cc59b5 100644 --- a/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h @@ -4,6 +4,10 @@ /// @brief Support for Toshiba protocols. /// @see https://github.com/r45635/HVAC-IR-Control /// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1205 +/// @see https://docs.google.com/spreadsheets/d/1yidE2fvaO9kpCHfKafIdH31q4uaskYR1OwwrkyOxbp0/edit?usp=drivesdk +/// @see https://www.toshiba-carrier.co.jp/global/about/index.htm +/// @see http://www.toshiba-carrier.co.th/AboutUs/Pages/CompanyProfile.aspx // Supports: // Brand: Toshiba, Model: RAS-B13N3KV2 @@ -12,6 +16,10 @@ // Brand: Toshiba, Model: RAS 18SKP-ES // Brand: Toshiba, Model: WH-TA04NE // Brand: Toshiba, Model: WC-L03SE +// Brand: Carrier, Model: 42NQV060M2 / 38NYV060M2 A/C +// Brand: Carrier, Model: 42NQV050M2 / 38NYV050M2 A/C +// Brand: Carrier, Model: 42NQV035M2 / 38NYV035M2 A/C +// Brand: Carrier, Model: 42NQV025M2 / 38NYV025M2 A/C #ifndef IR_TOSHIBA_H_ #define IR_TOSHIBA_H_ @@ -28,23 +36,53 @@ #endif // Constants +// Byte[0] - 0xF2 +// Byte[1] - 0x0D (inverted previous byte's value) +// Byte[2] - The expected payload length (in bytes) past the Byte[4]. +const uint8_t kToshibaAcLengthByte = 2; ///< Byte pos of the "length" attribute +const uint8_t kToshibaAcMinLength = 6; ///< Min Nr. of bytes in a message. +///< Known lengths are: +///< 1 (56 bit message) +///< 3 (72 bit message) +///< 4 (80 bit message) +// Byte[3] - The bit-inverted value of the "length" byte. +const uint16_t kToshibaAcInvertedLength = 4; ///< Nr. of leading bytes in + ///< inverted pairs. +// Byte[4] +const uint8_t kToshibaAcShortMsgBit = 5; ///< Mask 0b00x00000 +const uint8_t kToshibaAcLongMsgBit = 3; ///< Mask 0b00001000 +// Byte[5] +const uint8_t kToshibaAcSwingOffset = 0; ///< Bit offset. +const uint8_t kToshibaAcSwingSize = 2; ///< Mask 0b000000xx +const uint8_t kToshibaAcSwingStep = 0; ///< 0b00 +const uint8_t kToshibaAcSwingOn = 1; ///< 0b01 +const uint8_t kToshibaAcSwingOff = 2; ///< 0b10 + +const uint8_t kToshibaAcTempOffset = 4; ///< Bit offset. +const uint8_t kToshibaAcTempSize = 4; ///< Mask 0bxxxx0000 +const uint8_t kToshibaAcMinTemp = 17; ///< 17C +const uint8_t kToshibaAcMaxTemp = 30; ///< 30C +// Byte[6] const uint8_t kToshibaAcModeOffset = 0; -const uint8_t kToshibaAcModeSize = 2; // Nr. of bits -const uint8_t kToshibaAcAuto = 0; -const uint8_t kToshibaAcCool = 1; -const uint8_t kToshibaAcDry = 2; -const uint8_t kToshibaAcHeat = 3; -const uint8_t kToshibaAcPowerOffset = 2; +const uint8_t kToshibaAcModeSize = 3; // Mask 0b00000xxx +const uint8_t kToshibaAcAuto = 0; // 0b000 +const uint8_t kToshibaAcCool = 1; // 0b001 +const uint8_t kToshibaAcDry = 2; // 0b010 +const uint8_t kToshibaAcHeat = 3; // 0b011 +const uint8_t kToshibaAcFan = 4; // 0b100 +const uint8_t kToshibaAcOff = 7; // 0b111 const uint8_t kToshibaAcFanOffset = 5; -const uint8_t kToshibaAcFanSize = 3; // Nr. of bits -const uint8_t kToshibaAcFanAuto = 0b000; -const uint8_t kToshibaAcFanMin = 0b001; -const uint8_t kToshibaAcFanMed = 0b011; -const uint8_t kToshibaAcFanMax = 0b101; -const uint8_t kToshibaAcTempOffset = 4; -const uint8_t kToshibaAcTempSize = 4; // Nr. of bits -const uint8_t kToshibaAcMinTemp = 17; // 17C -const uint8_t kToshibaAcMaxTemp = 30; // 30C +const uint8_t kToshibaAcFanSize = 3; // Mask 0bxxx00000 +const uint8_t kToshibaAcFanAuto = 0; // 0b000 +const uint8_t kToshibaAcFanMin = 1; // 0b001 +const uint8_t kToshibaAcFanMed = 3; // 0b011 +const uint8_t kToshibaAcFanMax = 5; // 0b101 +// Byte[8] (Checksum for 72 bit messages, Eco/Turbo for long 80 bit messages) +const uint8_t kToshibaAcEcoTurboOffset = 0; +const uint8_t kToshibaAcEcoTurboSize = 2; // Mask 0b000000xx +const uint8_t kToshibaAcTurboOn = 1; // 0b01 +const uint8_t kToshibaAcEconoOn = 3; // 0b11 +// Byte[last] - Checksum (xor) // Legacy defines. (Deperecated) #define TOSHIBA_AC_AUTO kToshibaAcAuto @@ -81,12 +119,21 @@ class IRToshibaAC { uint8_t getTemp(void); void setFan(const uint8_t speed); uint8_t getFan(void); + void setTurbo(const bool on); + bool getTurbo(void); + void setEcono(const bool on); + bool getEcono(void); void setMode(const uint8_t mode); - uint8_t getMode(const bool useRaw = false); + uint8_t getMode(const bool raw = false); void setRaw(const uint8_t newState[]); uint8_t* getRaw(void); + static uint16_t getInternalStateLength(const uint8_t state[], + const uint16_t size); + uint16_t getStateLength(void); static bool validChecksum(const uint8_t state[], const uint16_t length = kToshibaACStateLength); + uint8_t getSwing(const bool raw = true); + void setSwing(const uint8_t setting); uint8_t convertMode(const stdAc::opmode_t mode); uint8_t convertFan(const stdAc::fanspeed_t speed); static stdAc::opmode_t toCommonMode(const uint8_t mode); @@ -102,11 +149,17 @@ class IRToshibaAC { IRsendTest _irsend; ///< Instance of the testing IR send class /// @endcond #endif // UNIT_TEST - uint8_t remote_state[kToshibaACStateLength]; ///< The state in IR code form. + uint8_t remote_state[kToshibaACStateLengthLong]; ///< The state in code form. + uint8_t backup[kToshibaACStateLengthLong]; ///< A backup copy of the state. + uint8_t prev_mode; ///< Store of the previously set mode. + bool _send_swing; ///< Flag indicating if we need to send a swing message. + uint8_t _swing_mode; ///< The saved swing state/mode/command. void checksum(const uint16_t length = kToshibaACStateLength); static uint8_t calcChecksum(const uint8_t state[], const uint16_t length = kToshibaACStateLength); - uint8_t mode_state; + void setStateLength(const uint16_t size); + void _backupState(void); + void _restoreState(void); }; #endif // IR_TOSHIBA_H_ diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h b/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h index 340e2b8fe..7fc0990e1 100644 --- a/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h @@ -360,6 +360,9 @@ // Compound words/phrases/descriptions from pre-defined words. // Note: Obviously these need to be defined *after* their component words. +#ifndef D_STR_ECONOTOGGLE +#define D_STR_ECONOTOGGLE D_STR_ECONO " " D_STR_TOGGLE +#endif // D_STR_ECONOTOGGLE #ifndef D_STR_EYEAUTO #define D_STR_EYEAUTO D_STR_EYE " " D_STR_AUTO #endif // D_STR_EYEAUTO @@ -685,6 +688,9 @@ #ifndef D_STR_SANYO #define D_STR_SANYO "SANYO" #endif // D_STR_SANYO +#ifndef D_STR_SANYO_AC +#define D_STR_SANYO_AC "SANYO_AC" +#endif // D_STR_SANYO_AC #ifndef D_STR_SANYO_LC7461 #define D_STR_SANYO_LC7461 "SANYO_LC7461" #endif // D_STR_SANYO_LC7461 diff --git a/lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp index a0f975666..f91be3459 100644 --- a/lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp @@ -1,6 +1,7 @@ // Copyright 2019 David Conran #include +#include "ir_Airwell.h" #include "ir_Amcor.h" #include "ir_Argo.h" #include "ir_Carrier.h" @@ -39,10 +40,33 @@ // Tests for IRac class. +TEST(TestIRac, Airwell) { + IRAirwellAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + char expected[] = + "Power Toggle: On, Mode: 3 (Auto), Fan: 1 (Medium), Temp: 18C"; + + ac.begin(); + irac.airwell(&ac, + true, // Power + stdAc::opmode_t::kAuto, // Mode + 18, // Celsius + stdAc::fanspeed_t::kMedium); // Fan speed + ASSERT_EQ(expected, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(AIRWELL, ac._irsend.capture.decode_type); + ASSERT_EQ(kAirwellBits, ac._irsend.capture.bits); + ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); +} + TEST(TestIRac, Amcor) { - IRAmcorAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRAmcorAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 5 (Auto), Fan: 3 (High), Temp: 19C, Max: Off"; @@ -63,8 +87,8 @@ TEST(TestIRac, Amcor) { } TEST(TestIRac, Argo) { - IRArgoAC ac(0); - IRac irac(0); + IRArgoAC ac(kGpioUnused); + IRac irac(kGpioUnused); ac.begin(); irac.argo(&ac, @@ -118,9 +142,9 @@ TEST(TestIRac, Carrier64) { } TEST(TestIRac, Coolix) { - IRCoolixAC ac(0); - IRac irac(0); - IRrecv capture(0); + IRCoolixAC ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 3 (Heat), Fan: 1 (Max), Temp: 21C, Zone Follow: Off, " "Sensor Temp: Off"; @@ -221,9 +245,9 @@ TEST(TestIRac, Corona) { } TEST(TestIRac, Daikin) { - IRDaikinESP ac(0); - IRac irac(0); - IRrecv capture(0); + IRDaikinESP ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 3 (Cool), Temp: 19C, Fan: 5 (High), Powerful: Off, " "Quiet: Off, Sensor: Off, Mould: On, Comfort: Off, " @@ -254,9 +278,9 @@ TEST(TestIRac, Daikin) { } TEST(TestIRac, Daikin128) { - IRDaikin128 ac(0); - IRac irac(0); - IRrecv capture(0); + IRDaikin128 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power Toggle: On, Mode: 8 (Heat), Temp: 27C, Fan: 9 (Quiet), " "Powerful: Off, Quiet: On, Swing(V): On, Sleep: On, " @@ -287,9 +311,9 @@ TEST(TestIRac, Daikin128) { } TEST(TestIRac, Daikin152) { - IRDaikin152 ac(0); - IRac irac(0); - IRrecv capture(0); + IRDaikin152 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 3 (Cool), Temp: 27C, Fan: 3 (Medium), Swing(V): On, " "Powerful: Off, Quiet: Off, Econo: On, Sensor: Off, Comfort: Off"; @@ -315,9 +339,9 @@ TEST(TestIRac, Daikin152) { } TEST(TestIRac, Daikin160) { - IRDaikin160 ac(0); - IRac irac(0); - IRrecv capture(0); + IRDaikin160 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 2 (Dry), Temp: 23C, Fan: 1 (Low), " "Swing(V): 3 (Middle)"; @@ -340,9 +364,9 @@ TEST(TestIRac, Daikin160) { } TEST(TestIRac, Daikin176) { - IRDaikin176 ac(0); - IRac irac(0); - IRrecv capture(0); + IRDaikin176 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 7 (Cool), Temp: 26C, Fan: 1 (Low), Swing(H): 5 (Auto)"; @@ -364,9 +388,9 @@ TEST(TestIRac, Daikin176) { } TEST(TestIRac, Daikin2) { - IRDaikin2 ac(0); - IRac irac(0); - IRrecv capture(0); + IRDaikin2 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 3 (Cool), Temp: 19C, Fan: 1 (Low), " "Swing(V): 14 (Auto), Swing(H): 170 (UNKNOWN), Clock: 00:00, " @@ -402,9 +426,9 @@ TEST(TestIRac, Daikin2) { } TEST(TestIRac, Daikin216) { - IRDaikin216 ac(0); - IRac irac(0); - IRrecv capture(0); + IRDaikin216 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 4 (Heat), Temp: 31C, Fan: 11 (Quiet), " "Swing(H): On, Swing(V): On, Quiet: On, Powerful: Off"; @@ -511,9 +535,9 @@ TEST(TestIRac, Electra) { } TEST(TestIRac, Fujitsu) { - IRFujitsuAC ac(0); - IRac irac(0); - IRrecv capture(0); + IRFujitsuAC ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); std::string ardb1_expected = "Model: 2 (ARDB1), Power: On, Mode: 1 (Cool), Temp: 19C, " "Fan: 2 (Medium), Command: N/A"; @@ -591,9 +615,9 @@ TEST(TestIRac, Fujitsu) { } TEST(TestIRac, Goodweather) { - IRGoodweatherAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRGoodweatherAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 1 (Cool), Temp: 19C, Fan: 2 (Medium), Turbo: Toggle, " "Light: Toggle, Sleep: Toggle, Swing: 1 (Slow), Command: 0 (Power)"; @@ -619,9 +643,9 @@ TEST(TestIRac, Goodweather) { } TEST(TestIRac, Gree) { - IRGreeAC ac(0); - IRac irac(0); - IRrecv capture(0); + IRGreeAC ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 71F, " "Fan: 2 (Medium), Turbo: Off, IFeel: Off, WiFi: Off, XFan: On, " @@ -652,9 +676,9 @@ TEST(TestIRac, Gree) { } TEST(TestIRac, Haier) { - IRHaierAC ac(0); - IRac irac(0); - IRrecv capture(0); + IRHaierAC ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Command: 1 (On), Mode: 1 (Cool), Temp: 24C, Fan: 2 (Medium), " "Swing: 1 (Up), Sleep: On, Health: On, Clock: 13:45, " @@ -682,9 +706,9 @@ TEST(TestIRac, Haier) { TEST(TestIRac, HaierYrwo2) { - IRHaierACYRW02 ac(0); - IRac irac(0); - IRrecv capture(0); + IRHaierACYRW02 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 23C, " "Fan: 2 (Medium), Turbo: 1 (High), Swing: 1 (Highest), Sleep: On, " @@ -711,9 +735,9 @@ TEST(TestIRac, HaierYrwo2) { } TEST(TestIRac, Hitachi) { - IRHitachiAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRHitachiAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 2 (Auto), Temp: 22C, Fan: 3 (Medium), " "Swing(V): Off, Swing(H): On"; @@ -821,9 +845,9 @@ TEST(TestIRac, Hitachi344) { } TEST(TestIRac, Hitachi424) { - IRHitachiAc424 ac(0); - IRac irac(0); - IRrecv capture(0); + IRHitachiAc424 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), " "Button: 19 (Power/Mode), Swing(V) Toggle: Off"; @@ -866,9 +890,9 @@ TEST(TestIRac, Hitachi424) { } TEST(TestIRac, Kelvinator) { - IRKelvinatorAC ac(0); - IRac irac(0); - IRrecv capture(0); + IRKelvinatorAC ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 1 (Cool), Temp: 19C, Fan: 3 (Medium), Turbo: Off, " "Quiet: Off, XFan: On, Ion: On, Light: On, " @@ -899,9 +923,9 @@ TEST(TestIRac, Kelvinator) { } TEST(TestIRac, LG) { - IRLgAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRLgAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Model: 1 (GE6711AR2853M), " "Power: On, Mode: 1 (Dry), Temp: 27C, Fan: 2 (Medium)"; @@ -925,12 +949,12 @@ TEST(TestIRac, LG) { } TEST(TestIRac, Midea) { - IRMideaAC ac(0); - IRac irac(0); - IRrecv capture(0); + IRMideaAC ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 1 (Dry), Celsius: On, Temp: 27C/80F, Fan: 2 (Medium), " - "Sleep: On, Swing(V) Toggle: Off"; + "Sleep: On, Swing(V) Toggle: Off, Econo Toggle: Off"; ac.begin(); irac.midea(&ac, @@ -940,6 +964,7 @@ TEST(TestIRac, Midea) { 27, // Degrees stdAc::fanspeed_t::kMedium, // Fan speed stdAc::swingv_t::kOff, // Swing(V) + false, // Econo 8 * 60 + 0); // Sleep time ASSERT_EQ(expected, ac.toString()); @@ -953,9 +978,9 @@ TEST(TestIRac, Midea) { } TEST(TestIRac, Mitsubishi) { - IRMitsubishiAC ac(0); - IRac irac(0); - IRrecv capture(0); + IRMitsubishiAC ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 3 (Cool), Temp: 20C, Fan: 2 (Medium), " "Swing(V): 0 (Auto), Swing(H): 3 (UNKNOWN), " @@ -982,9 +1007,9 @@ TEST(TestIRac, Mitsubishi) { } TEST(TestIRac, Mitsubishi136) { - IRMitsubishi136 ac(0); - IRac irac(0); - IRrecv capture(0); + IRMitsubishi136 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 5 (Dry), Temp: 22C, Fan: 3 (High), " "Swing(V): 3 (Highest), Quiet: Off"; @@ -1008,9 +1033,9 @@ TEST(TestIRac, Mitsubishi136) { } TEST(TestIRac, MitsubishiHeavy88) { - IRMitsubishiHeavy88Ac ac(0); - IRac irac(0); - IRrecv capture(0); + IRMitsubishiHeavy88Ac ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 1 (Cool), Temp: 21C, Fan: 3 (Med), " "Swing(V): 4 (Auto), Swing(H): 0 (Off), Turbo: Off, Econo: Off, " @@ -1038,9 +1063,9 @@ TEST(TestIRac, MitsubishiHeavy88) { } TEST(TestIRac, MitsubishiHeavy152) { - IRMitsubishiHeavy152Ac ac(0); - IRac irac(0); - IRrecv capture(0); + IRMitsubishiHeavy152Ac ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 6 (Econo), " "Swing(V): 6 (Off), Swing(H): 0 (Auto), Silent: On, Turbo: Off, " @@ -1071,9 +1096,9 @@ TEST(TestIRac, MitsubishiHeavy152) { } TEST(TestIRac, Neoclima) { - IRNeoclimaAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRNeoclimaAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 3 (Low), " "Swing(V): Off, Swing(H): On, Sleep: On, Turbo: Off, Hold: Off, Ion: On, " @@ -1103,9 +1128,9 @@ TEST(TestIRac, Neoclima) { } TEST(TestIRac, Panasonic) { - IRPanasonicAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRPanasonicAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected_nke[] = "Model: 2 (NKE), Power: On, Mode: 4 (Heat), Temp: 28C, Fan: 2 (Medium), " "Swing(V): 15 (Auto), Swing(H): 6 (Middle), Quiet: On, " @@ -1161,9 +1186,9 @@ TEST(TestIRac, Panasonic) { } TEST(TestIRac, Samsung) { - IRSamsungAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRSamsungAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 0 (Auto), Temp: 28C, Fan: 6 (Auto), Swing: On, " "Beep: On, Clean: On, Quiet: On, Powerful: Off, Breeze: Off, " @@ -1223,10 +1248,38 @@ TEST(TestIRac, Samsung) { ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); } +TEST(TestIRac, Sanyo) { + IRSanyoAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + char expected[] = + "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), " + "Swing(V): 7 (Highest), Sleep: On, Beep: On, " + "Sensor: Wall, Sensor Temp: 28C, Off Timer: Off"; + + ac.begin(); + irac.sanyo(&ac, + true, // Power + stdAc::opmode_t::kCool, // Mode + 28, // Celsius + stdAc::fanspeed_t::kMedium, // Fan speed + stdAc::swingv_t::kHighest, // Vertical Swing + true, // Beep + 17); // Sleep + ASSERT_EQ(expected, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(SANYO_AC, ac._irsend.capture.decode_type); + ASSERT_EQ(kSanyoAcBits, ac._irsend.capture.bits); + ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); +} + TEST(TestIRac, Sharp) { - IRSharpAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRSharpAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), " "Turbo: Off, Swing(V) Toggle: On, Ion: On, Econo: -, Clean: Off"; @@ -1253,9 +1306,9 @@ TEST(TestIRac, Sharp) { } TEST(TestIRac, Tcl112) { - IRTcl112Ac ac(0); - IRac irac(0); - IRrecv capture(0); + IRTcl112Ac ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 3 (Cool), Temp: 20C, Fan: 3 (Medium), Econo: On, " "Health: On, Light: On, Turbo: Off, Swing(H): On, Swing(V): Off"; @@ -1283,9 +1336,9 @@ TEST(TestIRac, Tcl112) { } TEST(TestIRac, Teco) { - IRTecoAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRTecoAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 0 (Auto), Temp: 21C, Fan: 2 (Medium), Sleep: On, " "Swing: On, Light: On, Humid: Off, Save: Off, Timer: Off"; @@ -1310,31 +1363,82 @@ TEST(TestIRac, Teco) { } TEST(TestIRac, Toshiba) { - IRToshibaAC ac(0); - IRac irac(0); - IRrecv capture(0); - char expected[] = "Power: On, Mode: 2 (Dry), Temp: 29C, Fan: 2 (UNKNOWN)"; + IRToshibaAC ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + char expected[] = + "Temp: 29C, Power: On, Mode: 2 (Dry), Fan: 2 (UNKNOWN), " + "Turbo: Off, Econo: On"; ac.begin(); irac.toshiba(&ac, true, // Power stdAc::opmode_t::kDry, // Mode 29, // Celsius - stdAc::fanspeed_t::kLow); // Fan speed + stdAc::fanspeed_t::kLow, // Fan speed + stdAc::swingv_t::kOff, // Vertical Swing + false, // Turbo + true); // Econo ASSERT_EQ(expected, ac.toString()); + ASSERT_EQ(kToshibaACStateLengthLong, ac.getStateLength()); ac._irsend.makeDecodeResult(); EXPECT_TRUE(capture.decode(&ac._irsend.capture)); ASSERT_EQ(TOSHIBA_AC, ac._irsend.capture.decode_type); - ASSERT_EQ(kToshibaACBits, ac._irsend.capture.bits); + ASSERT_EQ(kToshibaACBitsLong, ac._irsend.capture.bits); ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); + EXPECT_EQ( + "f38000d50" + "m4400s4300" + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s1600m580s490m580s490" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s1600m580s1600" + "m580s490m580s490m580s490m580s490m580s1600m580s490m580s490m580s1600" + "m580s1600m580s1600m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s1600m580s1600m580s490m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600" + "m580s1600m580s490m580s1600m580s490m580s1600m580s490m580s490m580s490" + "m580s7400" + "m4400s4300" + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s1600m580s490m580s490" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s1600m580s1600" + "m580s490m580s490m580s490m580s490m580s1600m580s490m580s490m580s1600" + "m580s1600m580s1600m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s1600m580s1600m580s490m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600" + "m580s1600m580s490m580s1600m580s490m580s1600m580s490m580s490m580s490" + "m580s7400" + "m4400s4300" + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490" + "m580s490m580s490m580s1600m580s490m580s490m580s490m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s1600m580s490m580s490m580s490m580s1600m580s1600" + "m580s7400" + "m4400s4300" + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490" + "m580s490m580s490m580s1600m580s490m580s490m580s490m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s1600m580s490m580s490m580s490m580s1600m580s1600" + "m580s7400", + ac._irsend.outputStr()); } TEST(TestIRac, Trotec) { - IRTrotecESP ac(0); - IRac irac(0); - IRrecv capture(0); + IRTrotecESP ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 1 (Cool), Temp: 18C, Fan: 3 (High), Sleep: On"; @@ -1361,9 +1465,9 @@ TEST(TestIRac, Trotec) { } TEST(TestIRac, Vestel) { - IRVestelAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRVestelAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Power: On, Mode: 0 (Auto), Temp: 22C, Fan: 5 (Low), Sleep: On, " "Turbo: Off, Ion: On, Swing: On"; @@ -1452,9 +1556,9 @@ TEST(TestIRac, Vestel) { TEST(TestIRac, Whirlpool) { - IRWhirlpoolAc ac(0); - IRac irac(0); - IRrecv capture(0); + IRWhirlpoolAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); char expected[] = "Model: 1 (DG11J13A), Power Toggle: On, Mode: 1 (Auto), Temp: 21C, " "Fan: 3 (Low), Swing: On, Light: On, Clock: 23:58, On Timer: Off, " @@ -1755,9 +1859,9 @@ TEST(TestIRac, Issue821) { next = prev; next.light = true; - IRac irac(0); - IRrecv capture(0); - IRCoolixAC ac(0); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + IRCoolixAC ac(kGpioUnused); ac.begin(); result = irac.handleToggles(next, &prev); @@ -1844,9 +1948,9 @@ TEST(TestIRac, Issue1001) { desired = prev; desired.power = false; - IRac irac(0); - IRrecv capture(0); - IRWhirlpoolAc ac(0); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + IRWhirlpoolAc ac(kGpioUnused); ac.begin(); ASSERT_TRUE(prev.power); diff --git a/lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp index ecb23dbbf..0dde7ec04 100644 --- a/lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp @@ -220,32 +220,32 @@ TEST(TestResultToSourceCode, ComplexProtocols) { ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type); ASSERT_EQ(kToshibaACBits, irsend.capture.bits); EXPECT_EQ( - "uint16_t rawData[296] = {4400, 4300, 542, 1622, 542, 1622, " - "542, 1622, 542, 1622, 542, 472, 542, 472, 542, 1622, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 1622, 542, 1622, " - "542, 472, 542, 1622, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 1622, 542, 1622, 542, 1622, 542, 1622, " - "542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 1622, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 1622, 542, 7048, 4400, 4300, " - "542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 472, 542, 472, " - "542, 1622, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 1622, 542, 1622, 542, 472, 542, 1622, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 1622, 542, 1622, " - "542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 1622, 542, 1622, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 1622, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 472, " - "542, 472, 542, 472, 542, 472, 542, 472, 542, 472, 542, 1622, " - "542, 7048 }; // TOSHIBA_AC\n" + "uint16_t rawData[296] = {4400, 4300, 580, 1600, 580, 1600, " + "580, 1600, 580, 1600, 580, 490, 580, 490, 580, 1600, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 1600, 580, 1600, " + "580, 490, 580, 1600, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 1600, 580, 1600, 580, 1600, 580, 1600, " + "580, 1600, 580, 1600, 580, 1600, 580, 1600, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 1600, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 1600, 580, 7400, 4400, 4300, " + "580, 1600, 580, 1600, 580, 1600, 580, 1600, 580, 490, 580, 490, " + "580, 1600, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 1600, 580, 1600, 580, 490, 580, 1600, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 1600, 580, 1600, " + "580, 1600, 580, 1600, 580, 1600, 580, 1600, 580, 1600, 580, 1600, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 1600, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 490, " + "580, 490, 580, 490, 580, 490, 580, 490, 580, 490, 580, 1600, " + "580, 7400 }; // TOSHIBA_AC\n" "uint8_t state[9] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, " "0x01};\n", resultToSourceCode(&irsend.capture)); @@ -744,3 +744,35 @@ TEST(TestUtils, setBits64Bit) { irutils::setBits(&data, 32, 4, 0b1001); EXPECT_EQ(0x4000000900000013, data); } + +TEST(TestUtils, InvertedBytePairs) { + const uint8_t correct[] = {0x00, 0xFF, 0x01, 0xFE, 0xAA, 0x55}; + uint8_t wrong[] = {0x00, 0xFF, 0x01, 0xFD, 0xAA, 0x55}; + + ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 6)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 5)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 4)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 3)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 2)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 1)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(correct, 0)); + + ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 6)); + ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 5)); + ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 4)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 3)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 2)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 1)); + ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 0)); + + irutils::invertBytePairs(wrong, 0); + ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 6)); + irutils::invertBytePairs(wrong, 1); + ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 6)); + irutils::invertBytePairs(wrong, 2); + ASSERT_FALSE(irutils::checkInvertedBytePairs(wrong, 6)); + + irutils::invertBytePairs(wrong, 6); + ASSERT_TRUE(irutils::checkInvertedBytePairs(wrong, 6)); + EXPECT_STATE_EQ(correct, wrong, 6 * 8); +} diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp index 09300bac2..e5f28d4df 100644 --- a/lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp @@ -1,5 +1,6 @@ // Copyright 2020 David Conran +#include "ir_Airwell.h" #include "IRac.h" #include "IRrecv.h" #include "IRrecv_test.h" @@ -44,6 +45,9 @@ TEST(TestDecodeAirwell, RealExample) { EXPECT_EQ(0x2B0D0181B, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "Power Toggle: On, Mode: 2 (Heat), Fan: 3 (Auto), Temp: 25C", + IRAcUtils::resultAcToString(&irsend.capture)); const uint16_t rawData_2[175] = { 2862, 3892, @@ -76,6 +80,9 @@ TEST(TestDecodeAirwell, RealExample) { EXPECT_EQ(0x270F8181B, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "Power Toggle: On, Mode: 1 (Cool), Fan: 3 (Auto), Temp: 30C", + IRAcUtils::resultAcToString(&irsend.capture)); } TEST(TestDecodeAirwell, SyntheticExample) { @@ -192,6 +199,9 @@ TEST(TestDecodeAirwell, RealExample2) { EXPECT_EQ(0xB0C0181B, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "Power Toggle: Off, Mode: 2 (Heat), Fan: 3 (Auto), Temp: 23C", + IRAcUtils::resultAcToString(&irsend.capture)); // Resend it as a synthetic to see if it decodes to the same value. irsend.reset(); @@ -210,7 +220,7 @@ TEST(TestUtils, Housekeeping) { ASSERT_EQ("AIRWELL", typeToString(decode_type_t::AIRWELL)); ASSERT_EQ(decode_type_t::AIRWELL, strToDecodeType("AIRWELL")); ASSERT_FALSE(hasACState(decode_type_t::AIRWELL)); - ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::AIRWELL)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::AIRWELL)); ASSERT_EQ(kAirwellBits, IRsend::defaultBits(decode_type_t::AIRWELL)); ASSERT_EQ(kAirwellMinRepeats, IRsend::minRepeats(decode_type_t::AIRWELL)); } @@ -250,4 +260,142 @@ TEST(TestDecodeAirwell, RealExample3) { EXPECT_EQ(0x60080002, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "Power Toggle: Off, Mode: 1 (Cool), Fan: 2 (High), Temp: 16C", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +// Tests for IRAirwellAc class. + +TEST(TestAirwellAcClass, PowerToggle) { + IRAirwellAc ac(kGpioUnused); + ac.begin(); + + ac.setPowerToggle(true); + EXPECT_TRUE(ac.getPowerToggle()); + ac.setPowerToggle(false); + EXPECT_FALSE(ac.getPowerToggle()); + ac.setPowerToggle(true); + EXPECT_TRUE(ac.getPowerToggle()); +} + +TEST(TestAirwellAcClass, Temperature) { + IRAirwellAc ac(kGpioUnused); + ac.begin(); + + ac.setTemp(0); + EXPECT_EQ(kAirwellMinTemp, ac.getTemp()); + + ac.setTemp(255); + EXPECT_EQ(kAirwellMaxTemp, ac.getTemp()); + + ac.setTemp(kAirwellMinTemp); + EXPECT_EQ(kAirwellMinTemp, ac.getTemp()); + + ac.setTemp(kAirwellMaxTemp); + EXPECT_EQ(kAirwellMaxTemp, ac.getTemp()); + + ac.setTemp(kAirwellMinTemp - 1); + EXPECT_EQ(kAirwellMinTemp, ac.getTemp()); + + ac.setTemp(kAirwellMaxTemp + 1); + EXPECT_EQ(kAirwellMaxTemp, ac.getTemp()); + + ac.setTemp(17); + EXPECT_EQ(17, ac.getTemp()); + + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); + + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); + + ac.setTemp(29); + EXPECT_EQ(29, ac.getTemp()); +} + +TEST(TestAirwellAcClass, OperatingMode) { + IRAirwellAc ac(kGpioUnused); + ac.begin(); + + ac.setMode(kAirwellAuto); + EXPECT_EQ(kAirwellAuto, ac.getMode()); + + ac.setMode(kAirwellCool); + EXPECT_EQ(kAirwellCool, ac.getMode()); + + ac.setMode(kAirwellHeat); + EXPECT_EQ(kAirwellHeat, ac.getMode()); + + ac.setMode(kAirwellDry); + EXPECT_EQ(kAirwellDry, ac.getMode()); + + ac.setMode(kAirwellFan); + EXPECT_EQ(kAirwellFan, ac.getMode()); + + ac.setMode(kAirwellFan + 1); + EXPECT_EQ(kAirwellAuto, ac.getMode()); + + ac.setMode(255); + EXPECT_EQ(kAirwellAuto, ac.getMode()); +} + +TEST(TestAirwellAcClass, FanSpeed) { + IRAirwellAc ac(0); + ac.begin(); + + ac.setFan(0); + EXPECT_EQ(kAirwellFanLow, ac.getFan()); + + ac.setFan(255); + EXPECT_EQ(kAirwellFanAuto, ac.getFan()); + + ac.setFan(kAirwellFanHigh); + EXPECT_EQ(kAirwellFanHigh, ac.getFan()); + + ac.setFan(kAirwellFanHigh + 2); + EXPECT_EQ(kAirwellFanAuto, ac.getFan()); + + ac.setFan(kAirwellFanHigh - 1); + EXPECT_EQ(kAirwellFanHigh - 1, ac.getFan()); + + ac.setFan(1); + EXPECT_EQ(1, ac.getFan()); + + ac.setFan(1); + EXPECT_EQ(1, ac.getFan()); + + ac.setFan(3); + EXPECT_EQ(3, ac.getFan()); +} + +// Test human readable output. +TEST(TestAirwellAcClass, HumanReadable) { + IRAirwellAc ac(kGpioUnused); + EXPECT_EQ( + "Power Toggle: Off, Mode: 5 (Fan), Fan: 0 (Low), Temp: 25C", + ac.toString()); + ac.setPowerToggle(true); + ac.setMode(kAirwellHeat); + ac.setTemp(30); + ac.setFan(kAirwellFanAuto); + EXPECT_EQ( + "Power Toggle: On, Mode: 2 (Heat), Fan: 3 (Auto), Temp: 30C", + ac.toString()); +} + +TEST(TestAirwellAcClass, ReconstructKnownState) { + IRAirwellAc ac(kGpioUnused); + const uint64_t expected = 0x240380002; + ac.begin(); + ac.stateReset(); + ASSERT_NE(expected, ac.getRaw()); + ac.setPowerToggle(true); + ac.setMode(kAirwellCool); + ac.setTemp(22); + ac.setFan(kAirwellFanLow); + EXPECT_EQ(expected, ac.getRaw()); + EXPECT_EQ( + "Power Toggle: On, Mode: 1 (Cool), Fan: 0 (Low), Temp: 22C", + ac.toString()); } diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp index d899576b9..8d5dc1246 100644 --- a/lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp @@ -448,7 +448,7 @@ TEST(TestDecodeLG, Issue620) { // Resend the same code as the report is a sent code doesn't decode // to the same message code. - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); irsend.sendLG(0x8808721); irsend.makeDecodeResult(); ASSERT_TRUE(irrecv.decode(&irsend.capture)); @@ -477,7 +477,7 @@ TEST(TestDecodeLG, Issue620) { } TEST(TestIRLgAcClass, SetAndGetPower) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.on(); EXPECT_TRUE(ac.getPower()); ac.off(); @@ -489,7 +489,7 @@ TEST(TestIRLgAcClass, SetAndGetPower) { } TEST(TestIRLgAcClass, SetAndGetTemp) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.setTemp(25); EXPECT_EQ(25, ac.getTemp()); ac.setTemp(kLgAcMinTemp); @@ -503,7 +503,7 @@ TEST(TestIRLgAcClass, SetAndGetTemp) { } TEST(TestIRLgAcClass, SetAndGetMode) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.setMode(kLgAcCool); ac.setFan(kLgAcFanAuto); ac.setTemp(25); @@ -517,22 +517,22 @@ TEST(TestIRLgAcClass, SetAndGetMode) { } TEST(TestIRLgAcClass, SetAndGetFan) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.setMode(kLgAcCool); ac.setFan(kLgAcFanAuto); EXPECT_EQ(kLgAcFanAuto, ac.getFan()); - ac.setFan(kLgAcFanLow); - EXPECT_EQ(kLgAcFanLow, ac.getFan()); + ac.setFan(kLgAcFanLowest); + EXPECT_EQ(kLgAcFanLowest, ac.getFan()); ac.setFan(kLgAcFanHigh); EXPECT_EQ(kLgAcFanHigh, ac.getFan()); ac.setFan(kLgAcFanAuto + 1); EXPECT_EQ(kLgAcFanAuto, ac.getFan()); - ac.setFan(kLgAcFanLow - 1); + ac.setFan(kLgAcFanLowest - 1); EXPECT_EQ(kLgAcFanAuto, ac.getFan()); } TEST(TestIRLgAcClass, toCommon) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.setPower(true); ac.setMode(kLgAcCool); ac.setTemp(20); @@ -564,7 +564,7 @@ TEST(TestIRLgAcClass, toCommon) { } TEST(TestIRLgAcClass, HumanReadable) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); EXPECT_EQ( "Model: 1 (GE6711AR2853M), " @@ -583,17 +583,17 @@ TEST(TestIRLgAcClass, HumanReadable) { ac.setTemp(kLgAcMinTemp); EXPECT_EQ( "Model: 1 (GE6711AR2853M), " - "Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 0 (Low)", + "Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 1 (Low)", ac.toString()); ac.setTemp(ac.getTemp() + 1); EXPECT_EQ( "Model: 1 (GE6711AR2853M), " - "Power: On, Mode: 0 (Cool), Temp: 17C, Fan: 0 (Low)", + "Power: On, Mode: 0 (Cool), Temp: 17C, Fan: 1 (Low)", ac.toString()); ac.setTemp(ac.getTemp() - 1); EXPECT_EQ( "Model: 1 (GE6711AR2853M), " - "Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 0 (Low)", + "Power: On, Mode: 0 (Cool), Temp: 16C, Fan: 1 (Low)", ac.toString()); ac.setPower(false); EXPECT_EQ( @@ -603,7 +603,7 @@ TEST(TestIRLgAcClass, HumanReadable) { } TEST(TestIRLgAcClass, SetAndGetRaw) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.setRaw(0x8800A4E); ASSERT_EQ(0x8800A4E, ac.getRaw()); @@ -621,7 +621,7 @@ TEST(TestIRLgAcClass, SetAndGetRaw) { } TEST(TestIRLgAcClass, MessageConstruction) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.on(); ac.setMode(kLgAcCool); @@ -635,7 +635,7 @@ TEST(TestIRLgAcClass, MessageConstruction) { } TEST(TestIRLgAcClass, isValidLgAc) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.setRaw(0x8800A4E); ASSERT_TRUE(ac.isValidLgAc()); @@ -670,7 +670,7 @@ TEST(TestUtils, Housekeeping) { } TEST(TestIRLgAcClass, KnownExamples) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); // Ref: // https://github.com/crankyoldgit/IRremoteESP8266/issues/1008#issuecomment-570646648 @@ -694,7 +694,7 @@ TEST(TestIRLgAcClass, KnownExamples) { ASSERT_TRUE(ac.isValidLgAc()); EXPECT_EQ( "Model: 1 (GE6711AR2853M), " - "Power: On, Mode: 1 (Dry), Temp: 21C, Fan: 0 (Low)", + "Power: On, Mode: 1 (Dry), Temp: 21C, Fan: 0 (Quiet)", ac.toString()); ac.setRaw(0x880C758); @@ -716,7 +716,7 @@ TEST(TestIRLgAcClass, KnownExamples) { ASSERT_TRUE(ac.isValidLgAc()); EXPECT_EQ( "Model: 1 (GE6711AR2853M), " - "Power: On, Mode: 0 (Cool), Temp: 22C, Fan: 0 (Low)", + "Power: On, Mode: 0 (Cool), Temp: 22C, Fan: 0 (Quiet)", ac.toString()); ac.setRaw(0x8808721); @@ -816,7 +816,7 @@ TEST(TestDecodeLG2, Issue1008) { EXPECT_EQ(0x8800347, irsend.capture.value); irsend.reset(); - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); ac.setRaw(0x8800347); ac.setModel(lg_ac_remote_model_t::AKB75215403); // aka. 2 ac.send(); @@ -835,7 +835,7 @@ TEST(TestDecodeLG2, Issue1008) { } TEST(TestIRLgAcClass, DifferentModels) { - IRLgAc ac(0); + IRLgAc ac(kGpioUnused); IRrecv capture(0); ac.setRaw(0x8800347); @@ -872,3 +872,12 @@ TEST(TestIRLgAcClass, DifferentModels) { ASSERT_EQ(expected2, IRAcUtils::resultAcToString(&ac._irsend.capture)); ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); } + +TEST(TestIRLgAcClass, FanSpeedIssue1214) { + EXPECT_EQ(kLgAcFanLowest, IRLgAc::convertFan(stdAc::fanspeed_t::kMin)); + EXPECT_EQ(kLgAcFanLow, IRLgAc::convertFan(stdAc::fanspeed_t::kLow)); + EXPECT_EQ(kLgAcFanMedium, IRLgAc::convertFan(stdAc::fanspeed_t::kMedium)); + EXPECT_EQ(kLgAcFanHigh, IRLgAc::convertFan(stdAc::fanspeed_t::kHigh)); + EXPECT_EQ(kLgAcFanHigh, IRLgAc::convertFan(stdAc::fanspeed_t::kMax)); + EXPECT_EQ(kLgAcFanAuto, IRLgAc::convertFan(stdAc::fanspeed_t::kAuto)); +} diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp index 24c2610a4..adce3f9d9 100644 --- a/lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp @@ -441,13 +441,13 @@ TEST(TestMideaACClass, Sleep) { } TEST(TestMideaACClass, HumanReadableOutput) { - IRMideaAC ac(0); + IRMideaAC ac(kGpioUnused); ac.begin(); ac.setRaw(0xA1826FFFFF62); EXPECT_EQ( "Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), " - "Sleep: Off, Swing(V) Toggle: Off", ac.toString()); + "Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString()); ac.off(); ac.setTemp(25, true); ac.setFan(kMideaACFanHigh); @@ -455,16 +455,16 @@ TEST(TestMideaACClass, HumanReadableOutput) { ac.setSleep(true); EXPECT_EQ( "Power: Off, Mode: 1 (Dry), Celsius: Off, Temp: 25C/77F, Fan: 3 (High), " - "Sleep: On, Swing(V) Toggle: Off", ac.toString()); + "Sleep: On, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString()); ac.setUseCelsius(true); EXPECT_EQ( "Power: Off, Mode: 1 (Dry), Celsius: On, Temp: 25C/77F, Fan: 3 (High), " - "Sleep: On, Swing(V) Toggle: Off", ac.toString()); + "Sleep: On, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString()); ac.setRaw(0xA19867FFFF7E); EXPECT_EQ( "Power: On, Mode: 0 (Cool), Celsius: Off, Temp: 21C/69F, Fan: 3 (High), " - "Sleep: Off, Swing(V) Toggle: Off", ac.toString()); + "Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString()); } // Tests for decodeMidea(). @@ -672,14 +672,14 @@ TEST(TestDecodeMidea, DecodeRealExample) { EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value); EXPECT_EQ( "Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 18C/65F, Fan: 0 (Auto), " - "Sleep: Off, Swing(V) Toggle: Off", + "Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); } TEST(TestMideaACClass, toCommon) { - IRMideaAC ac(0); + IRMideaAC ac(kGpioUnused); ac.setPower(true); ac.setMode(kMideaACCool); ac.setUseCelsius(true); @@ -709,7 +709,7 @@ TEST(TestMideaACClass, toCommon) { // https://github.com/crankyoldgit/IRremoteESP8266/issues/819 TEST(TestMideaACClass, CelsiusRemoteTemp) { - IRMideaAC ac(0); + IRMideaAC ac(kGpioUnused); uint64_t on_cool_low_17c = 0xA18840FFFF56; uint64_t on_cool_low_30c = 0xA1884DFFFF5D; ac.on(); @@ -722,13 +722,13 @@ TEST(TestMideaACClass, CelsiusRemoteTemp) { EXPECT_EQ(on_cool_low_17c, ac.getRaw()); EXPECT_EQ( "Power: On, Mode: 0 (Cool), Celsius: On, Temp: 17C/62F, Fan: 1 (Low), " - "Sleep: Off, Swing(V) Toggle: Off", ac.toString()); + "Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString()); ac.setRaw(on_cool_low_17c); EXPECT_EQ(17, ac.getTemp(true)); EXPECT_EQ(62, ac.getTemp(false)); EXPECT_EQ( "Power: On, Mode: 0 (Cool), Celsius: On, Temp: 17C/62F, Fan: 1 (Low), " - "Sleep: Off, Swing(V) Toggle: Off", ac.toString()); + "Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString()); ac.setTemp(17, true); EXPECT_EQ(17, ac.getTemp(true)); EXPECT_EQ(62, ac.getTemp(false)); @@ -737,26 +737,45 @@ TEST(TestMideaACClass, CelsiusRemoteTemp) { ac.setRaw(on_cool_low_30c); EXPECT_EQ( "Power: On, Mode: 0 (Cool), Celsius: On, Temp: 30C/86F, Fan: 1 (Low), " - "Sleep: Off, Swing(V) Toggle: Off", ac.toString()); + "Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString()); } // https://github.com/crankyoldgit/IRremoteESP8266/issues/819 TEST(TestMideaACClass, SwingV) { - IRMideaAC ac(0); + IRMideaAC ac(kGpioUnused); ac.setSwingVToggle(false); ASSERT_FALSE(ac.getSwingVToggle()); ac.setSwingVToggle(true); ASSERT_TRUE(ac.getSwingVToggle()); EXPECT_EQ( "Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), " - "Sleep: Off, Swing(V) Toggle: On", ac.toString()); + "Sleep: Off, Swing(V) Toggle: On, Econo Toggle: Off", ac.toString()); ac.setSwingVToggle(false); ASSERT_FALSE(ac.getSwingVToggle()); EXPECT_EQ( "Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), " - "Sleep: Off, Swing(V) Toggle: Off", ac.toString()); + "Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString()); ac.setRaw(kMideaACToggleSwingV); - EXPECT_EQ("Swing(V) Toggle: On", ac.toString()); + EXPECT_EQ("Swing(V) Toggle: On, Econo Toggle: Off", ac.toString()); +} + +// https://github.com/crankyoldgit/IRremoteESP8266/pull/1213 +TEST(TestMideaACClass, Econo) { + IRMideaAC ac(kGpioUnused); + ac.setEconoToggle(false); + ASSERT_FALSE(ac.getEconoToggle()); + ac.setEconoToggle(true); + ASSERT_TRUE(ac.getEconoToggle()); + EXPECT_EQ( + "Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), " + "Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: On", ac.toString()); + ac.setEconoToggle(false); + ASSERT_FALSE(ac.getEconoToggle()); + EXPECT_EQ( + "Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 25C/77F, Fan: 0 (Auto), " + "Sleep: Off, Swing(V) Toggle: Off, Econo Toggle: Off", ac.toString()); + ac.setRaw(kMideaACToggleEcono); + EXPECT_EQ("Swing(V) Toggle: Off, Econo Toggle: On", ac.toString()); } // Test abusing the protocol for sending 6 arbitary bytes. diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp index 37cb56fa2..fce2503e4 100644 --- a/lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp @@ -14,34 +14,34 @@ TEST(TestSendPioneer, SendDataOnly) { irsend.sendPioneer(0); EXPECT_EQ( "f40000d33" - "m8544s4272" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s37380" - "m8544s4272" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s37380", + "m8506s4191" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s37881" + "m8506s4191" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s37881", irsend.outputStr()); irsend.sendPioneer(0x55FF00AAAA00FF55); EXPECT_EQ( "f40000d33" - "m8544s4272" - "m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602" - "m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534" - "m534s25098" - "m8544s4272" - "m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534" - "m534s534m534s534m534s534m534s534m534s534m534s534m534s534m534s534" - "m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602m534s1602" - "m534s534m534s1602m534s534m534s1602m534s534m534s1602m534s534m534s1602" - "m534s25098", + "m8506s4191" + "m568s487m568s1542m568s487m568s1542m568s487m568s1542m568s487m568s1542" + "m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s1542m568s487m568s1542m568s487m568s1542m568s487m568s1542m568s487" + "m568s25181" + "m8506s4191" + "m568s1542m568s487m568s1542m568s487m568s1542m568s487m568s1542m568s487" + "m568s487m568s487m568s487m568s487m568s487m568s487m568s487m568s487" + "m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542m568s1542" + "m568s487m568s1542m568s487m568s1542m568s487m568s1542m568s487m568s1542" + "m568s25181", irsend.outputStr()); } @@ -139,17 +139,91 @@ TEST(TestDecodePioneer, SyntheticPioneerMessage) { irsend.sendPioneer(0x659A857AF50A3DC2, 64, 0); EXPECT_EQ( "f40000d33" - "m8544s4272" - "m534s534m534s1602m534s1602m534s534m534s534m534s1602m534s534m534s1602" - "m534s1602m534s534m534s534m534s1602m534s1602m534s534m534s1602m534s534" - "m534s1602m534s534m534s534m534s534m534s534m534s1602m534s534m534s1602" - "m534s534m534s1602m534s1602m534s1602m534s1602m534s534m534s1602m534s534" - "m534s25098" - "m8544s4272" - "m534s1602m534s1602m534s1602m534s1602m534s534m534s1602m534s534m534s1602" - "m534s534m534s534m534s534m534s534m534s1602m534s534m534s1602m534s534" - "m534s534m534s534m534s1602m534s1602m534s1602m534s1602m534s534m534s1602" - "m534s1602m534s1602m534s534m534s534m534s534m534s534m534s1602m534s534" - "m534s25098", + "m8506s4191" + "m568s487m568s1542m568s1542m568s487m568s487m568s1542m568s487m568s1542" + "m568s1542m568s487m568s487m568s1542m568s1542m568s487m568s1542m568s487" + "m568s1542m568s487m568s487m568s487m568s487m568s1542m568s487m568s1542" + "m568s487m568s1542m568s1542m568s1542m568s1542m568s487m568s1542m568s487" + "m568s25181" + "m8506s4191" + "m568s1542m568s1542m568s1542m568s1542m568s487m568s1542m568s487m568s1542" + "m568s487m568s487m568s487m568s487m568s1542m568s487m568s1542m568s487" + "m568s487m568s487m568s1542m568s1542m568s1542m568s1542m568s487m568s1542" + "m568s1542m568s1542m568s487m568s487m568s487m568s487m568s1542m568s487" + "m568s25181", irsend.outputStr()); } + +// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1220#issuecomment-661598412 +TEST(TestDecodePioneer, Issue1220) { + IRsendTest irsend(0); + IRrecv irrecv(0); + irsend.begin(); + + irsend.reset(); + // Pwr Toggle {"IrReceived":{"Protocol":"PIONEER","Bits":64, + // "Data":"0xA55A38C7A55A38C7"}} + const uint16_t rawPowerToggle[203] = { + 8510, 4188, 580, 1544, 556, 470, 582, 1566, 556, 494, 560, 488, 556, 1542, + 580, 470, 584, 1540, 582, 492, 552, 1522, 578, 496, 558, 1564, 558, 1542, + 580, 470, 586, 1564, 536, 512, 532, 494, 560, 464, 582, 1542, 580, 1544, + 578, 1544, 578, 498, 558, 492, 562, 488, 556, 1518, 582, 1542, 582, 492, + 552, 498, 556, 494, 550, 1572, 560, 1538, 562, 1536, 586, 25188, + 8512, 4186, 584, 1540, 584, 468, 576, 1572, 528, 522, 532, 492, 552, 1546, + 584, 492, 550, 1548, 582, 494, 560, 1538, 580, 468, 586, 1514, 586, 1538, + 584, 490, 554, 1546, 586, 488, 554, 470, 584, 490, 556, 1542, 556, 1542, + 580, 1544, 578, 496, 560, 466, 578, 496, 560, 1538, 584, 1516, 584, 490, + 554, 472, 582, 492, 552, 1546, 586, 1536, 586, 1538, 586, 25162, + 8514, 4184, 582, 1542, 580, 496, 562, 1536, 584, 490, 554, 496, 560, 1538, + 562, 514, 530, 1542, 580, 496, 560, 1538, 584, 466, 578, 1546, 576, 1524, + 578, 496, 558, 1542, 586, 488, 554, 496, 558, 466, 576, 1546, 576, 1548, + 586, 1512, 578, 498, 558, 492, 552, 496, 558, 1540, 580, 1542, 578, 498, + 556, 494, 550, 498, 556, 1516, 584, 1540, 584, 1540, 580}; + irsend.sendRaw(rawPowerToggle, 203, 40); // Pioneer uses 40kHz + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(PIONEER, irsend.capture.decode_type); + EXPECT_EQ(kPioneerBits, irsend.capture.bits); + EXPECT_EQ(0xA55A38C7A55A38C7, irsend.capture.value); + EXPECT_EQ(0xA51C, irsend.capture.address); + EXPECT_EQ(0xA51C, irsend.capture.command); + + irsend.reset(); + irsend.sendPioneer(0xA55A38C7A55A38C7, 64, 1); + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(PIONEER, irsend.capture.decode_type); + EXPECT_EQ(kPioneerBits, irsend.capture.bits); + EXPECT_EQ(0xA55A38C7A55A38C7, irsend.capture.value); + EXPECT_EQ(0xA51C, irsend.capture.address); + EXPECT_EQ(0xA51C, irsend.capture.command); + EXPECT_EQ( + "f40000d33" + "m8506s4191" + "m568s1542m568s487m568s1542m568s487m568s487m568s1542m568s487m568s1542" + "m568s487m568s1542m568s487m568s1542m568s1542m568s487m568s1542m568s487" + "m568s487m568s487m568s1542m568s1542m568s1542m568s487m568s487m568s487" + "m568s1542m568s1542m568s487m568s487m568s487m568s1542m568s1542m568s1542" + "m568s25181" + "m8506s4191" + "m568s1542m568s487m568s1542m568s487m568s487m568s1542m568s487m568s1542" + "m568s487m568s1542m568s487m568s1542m568s1542m568s487m568s1542m568s487" + "m568s487m568s487m568s1542m568s1542m568s1542m568s487m568s487m568s487" + "m568s1542m568s1542m568s487m568s487m568s487m568s1542m568s1542m568s1542" + "m568s25181" + "m8506s4191" + "m568s1542m568s487m568s1542m568s487m568s487m568s1542m568s487m568s1542" + "m568s487m568s1542m568s487m568s1542m568s1542m568s487m568s1542m568s487" + "m568s487m568s487m568s1542m568s1542m568s1542m568s487m568s487m568s487" + "m568s1542m568s1542m568s487m568s487m568s487m568s1542m568s1542m568s1542" + "m568s25181" + "m8506s4191" + "m568s1542m568s487m568s1542m568s487m568s487m568s1542m568s487m568s1542" + "m568s487m568s1542m568s487m568s1542m568s1542m568s487m568s1542m568s487" + "m568s487m568s487m568s1542m568s1542m568s1542m568s487m568s487m568s487" + "m568s1542m568s1542m568s487m568s487m568s487m568s1542m568s1542m568s1542" + "m568s25181", + irsend.outputStr()); + + EXPECT_EQ(0xA55A38C7A55A38C7, irsend.encodePioneer(0xA51C, 0xA51C)); +} diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp index 52165b780..59fc964e3 100644 --- a/lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp @@ -12,8 +12,10 @@ // General housekeeping TEST(TestSamsung, Housekeeping) { - ASSERT_EQ("SAMSUNG", typeToString(SAMSUNG)); - ASSERT_FALSE(hasACState(SAMSUNG)); + ASSERT_EQ("SAMSUNG", typeToString(decode_type_t::SAMSUNG)); + ASSERT_EQ(decode_type_t::SAMSUNG, strToDecodeType("SAMSUNG")); + ASSERT_FALSE(hasACState(decode_type_t::SAMSUNG)); + ASSERT_EQ(kSamsungBits, IRsend::defaultBits(decode_type_t::SAMSUNG)); } // Tests for sendSAMSUNG(). @@ -307,8 +309,12 @@ TEST(TestDecodeSamsung, FailToDecodeNonSamsungExample) { // General housekeeping TEST(TestSamsungAC, Housekeeping) { - ASSERT_EQ("SAMSUNG_AC", typeToString(SAMSUNG_AC)); - ASSERT_TRUE(hasACState(SAMSUNG_AC)); + ASSERT_EQ("SAMSUNG_AC", typeToString(decode_type_t::SAMSUNG_AC)); + ASSERT_EQ(decode_type_t::SAMSUNG_AC, strToDecodeType("SAMSUNG_AC")); + ASSERT_TRUE(hasACState(decode_type_t::SAMSUNG_AC)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::SAMSUNG_AC)); + ASSERT_EQ(kSamsungAcBits, IRsend::defaultBits(decode_type_t::SAMSUNG_AC)); + ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::SAMSUNG_AC)); } // Tests for sendSamsungAC(). @@ -1143,34 +1149,36 @@ TEST(TestSendSamsung36, SendDataOnly) { irsend.sendSamsung36(0); EXPECT_EQ( "f38000d50" - "m4480s4480" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s4480" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s560m560s560m560s560m560s560" - "m560s26880", + "m4515s4438" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s4438" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s490m512s490m512s490m512s490" + "m512s26880", irsend.outputStr()); irsend.sendSamsung36(0x400E00FF); EXPECT_EQ( "f38000d50" - "m4480s4480" - "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s4480" - "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680" - "m560s1680m560s1680m560s1680m560s1680" - "m560s26880", + "m4515s4438" + "m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s4438" + "m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468" + "m512s1468m512s1468m512s1468m512s1468" + "m512s26880", irsend.outputStr()); irsend.reset(); } // General housekeeping TEST(TestSamsung36, Housekeeping) { - ASSERT_EQ("SAMSUNG36", typeToString(SAMSUNG36)); - ASSERT_FALSE(hasACState(SAMSUNG36)); + ASSERT_EQ("SAMSUNG36", typeToString(decode_type_t::SAMSUNG36)); + ASSERT_EQ(decode_type_t::SAMSUNG36, strToDecodeType("SAMSUNG36")); + ASSERT_FALSE(hasACState(decode_type_t::SAMSUNG36)); + ASSERT_EQ(kSamsung36Bits, IRsend::defaultBits(decode_type_t::SAMSUNG36)); } // Test sending with different repeats. @@ -1182,50 +1190,50 @@ TEST(TestSendSamsung36, SendWithRepeats) { irsend.sendSamsung36(0x400E00FF, kSamsung36Bits, 1); // 1 repeat. EXPECT_EQ( "f38000d50" - "m4480s4480" - "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s4480" - "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680" - "m560s1680m560s1680m560s1680m560s1680" - "m560s26880" - "m4480s4480" - "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s4480" - "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680" - "m560s1680m560s1680m560s1680m560s1680" - "m560s26880", + "m4515s4438" + "m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s4438" + "m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468" + "m512s1468m512s1468m512s1468m512s1468" + "m512s26880" + "m4515s4438" + "m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s4438" + "m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468" + "m512s1468m512s1468m512s1468m512s1468" + "m512s26880", irsend.outputStr()); irsend.sendSamsung36(0x400E00FF, kSamsung36Bits, 2); // 2 repeats. EXPECT_EQ( "f38000d50" - "m4480s4480" - "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s4480" - "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680" - "m560s1680m560s1680m560s1680m560s1680" - "m560s26880" - "m4480s4480" - "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s4480" - "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680" - "m560s1680m560s1680m560s1680m560s1680" - "m560s26880" - "m4480s4480" - "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560" - "m560s4480" - "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560" - "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680" - "m560s1680m560s1680m560s1680m560s1680" - "m560s26880", + "m4515s4438" + "m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s4438" + "m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468" + "m512s1468m512s1468m512s1468m512s1468" + "m512s26880" + "m4515s4438" + "m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s4438" + "m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468" + "m512s1468m512s1468m512s1468m512s1468" + "m512s26880" + "m4515s4438" + "m512s490m512s490m512s490m512s490m512s490m512s1468m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s490m512s490m512s490m512s490" + "m512s4438" + "m512s1468m512s1468m512s1468m512s490m512s490m512s490m512s490m512s490" + "m512s490m512s490m512s490m512s490m512s1468m512s1468m512s1468m512s1468" + "m512s1468m512s1468m512s1468m512s1468" + "m512s26880", irsend.outputStr()); } diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp index c59113cda..cbdd6ba39 100644 --- a/lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp @@ -1,5 +1,9 @@ -// Copyright 2017 David Conran +// Copyright 2017-2020 David Conran +#include "ir_Sanyo.h" +#include "IRac.h" +#include "IRrecv.h" +#include "IRrecv_test.h" #include "IRsend.h" #include "IRsend_test.h" #include "gtest/gtest.h" @@ -257,3 +261,272 @@ TEST(TestDecodeSanyoLC7461, FailToDecodeNonSanyoLC7461Example) { irrecv.decodeSanyoLC7461(&irsend.capture, kStartOffset, kSanyoLC7461Bits, false)); } + +TEST(TestUtils, Housekeeping) { + // Sanyo LC7461 + ASSERT_EQ("SANYO_LC7461", typeToString(decode_type_t::SANYO_LC7461)); + ASSERT_EQ(decode_type_t::SANYO_LC7461, strToDecodeType("SANYO_LC7461")); + ASSERT_FALSE(hasACState(decode_type_t::SANYO_LC7461)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::SANYO_LC7461)); + ASSERT_EQ(kSanyoLC7461Bits, IRsend::defaultBits(decode_type_t::SANYO_LC7461)); + ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::SANYO_LC7461)); + // Sanyo A/C + ASSERT_EQ("SANYO_AC", typeToString(decode_type_t::SANYO_AC)); + ASSERT_EQ(decode_type_t::SANYO_AC, strToDecodeType("SANYO_AC")); + ASSERT_TRUE(hasACState(decode_type_t::SANYO_AC)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::SANYO_AC)); + ASSERT_EQ(kSanyoAcBits, IRsend::defaultBits(decode_type_t::SANYO_AC)); + ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::SANYO_AC)); +} + +TEST(TestDecodeSanyoAc, DecodeRealExamples) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + // Ref: "On" from https://github.com/crankyoldgit/IRremoteESP8266/issues/1211#issue-650997449 + const uint16_t rawData[148] = { + 8456, 4192, + 624, 448, 584, 1508, 608, 452, 580, 1512, 628, 452, 604, 1468, 560, 1552, + 600, 472, 584, 1532, 580, 472, 528, 516, 512, 540, 576, 1516, 628, 1472, + 612, 1508, 612, 452, 580, 1512, 628, 1468, 612, 1496, 632, 444, 580, 480, + 580, 476, 580, 1496, 564, 508, 576, 480, 576, 480, 580, 476, 584, 472, + 584, 468, 584, 480, 520, 512, 580, 480, 576, 480, 580, 476, 584, 472, + 584, 472, 528, 508, 524, 1568, 600, 480, 576, 480, 584, 1492, 560, 512, + 580, 1536, 576, 480, 580, 476, 580, 476, 528, 528, 524, 1568, 580, 476, + 584, 476, 580, 476, 580, 472, 528, 512, 520, 536, 576, 480, 580, 480, + 576, 480, 576, 476, 532, 528, 520, 512, 576, 480, 584, 476, 580, 476, + 580, 480, 576, 472, 528, 1548, 600, 480, 576, 480, 576, 1520, 592, 1496, + 600, 476, 580, 480, 576}; + const uint8_t expectedState[kSanyoAcStateLength] = { + 0x6A, 0x71, 0x47, 0x00, 0x20, 0x85, 0x00, 0x00, 0x32}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData, 148, 38000); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(SANYO_AC, irsend.capture.decode_type); + EXPECT_EQ(kSanyoAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); + EXPECT_FALSE(irsend.capture.repeat); + EXPECT_EQ( + "Power: On, Mode: 2 (Cool), Temp: 21C, Fan: 0 (Auto), " + "Swing(V): 5 (Upper Middle), Sleep: Off, Beep: On, Sensor: Room, " + "Sensor Temp: 11C, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestDecodeSanyoAc, SyntheticSelfDecode) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + const uint8_t expectedState[kSanyoAcStateLength] = { + 0x6A, 0x71, 0x47, 0x00, 0x20, 0x85, 0x00, 0x00, 0x32}; + irsend.begin(); + irsend.reset(); + irsend.sendSanyoAc(expectedState); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(SANYO_AC, irsend.capture.decode_type); + EXPECT_EQ(kSanyoAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); + EXPECT_FALSE(irsend.capture.repeat); + EXPECT_EQ( + "Power: On, Mode: 2 (Cool), Temp: 21C, Fan: 0 (Auto), " + "Swing(V): 5 (Upper Middle), Sleep: Off, Beep: On, Sensor: Room, " + "Sensor Temp: 11C, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + EXPECT_EQ( + "f38000d50" + "m8500s4200" + "m500s550m500s1600m500s550m500s1600m500s550m500s1600m500s1600m500s550" + "m500s1600m500s550m500s550m500s550m500s1600m500s1600m500s1600m500s550" + "m500s1600m500s1600m500s1600m500s550m500s550m500s550m500s1600m500s550" + "m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s550" + "m500s550m500s550m500s550m500s550m500s1600m500s550m500s550m500s1600" + "m500s550m500s1600m500s550m500s550m500s550m500s550m500s1600m500s550" + "m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s550" + "m500s550m500s550m500s550m500s550m500s550m500s550m500s550m500s1600" + "m500s550m500s550m500s1600m500s1600m500s550m500s550" + "m500s100000", + irsend.outputStr()); +} + +// Tests for IRSanyoAc class. + +TEST(TestSanyoAcClass, Power) { + IRSanyoAc ac(kGpioUnused); + ac.begin(); + + ac.on(); + EXPECT_TRUE(ac.getPower()); + + ac.off(); + EXPECT_FALSE(ac.getPower()); + + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); + + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); +} + +TEST(TestSanyoAcClass, Temperature) { + IRSanyoAc ac(kGpioUnused); + ac.begin(); + + ac.setTemp(0); + EXPECT_EQ(kSanyoAcTempMin, ac.getTemp()); + + ac.setTemp(255); + EXPECT_EQ(kSanyoAcTempMax, ac.getTemp()); + + ac.setTemp(kSanyoAcTempMin); + EXPECT_EQ(kSanyoAcTempMin, ac.getTemp()); + + ac.setTemp(kSanyoAcTempMax); + EXPECT_EQ(kSanyoAcTempMax, ac.getTemp()); + + ac.setTemp(kSanyoAcTempMin - 1); + EXPECT_EQ(kSanyoAcTempMin, ac.getTemp()); + + ac.setTemp(kSanyoAcTempMax + 1); + EXPECT_EQ(kSanyoAcTempMax, ac.getTemp()); + + ac.setTemp(17); + EXPECT_EQ(17, ac.getTemp()); + + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); + + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); + + ac.setTemp(30); + EXPECT_EQ(30, ac.getTemp()); +} + +TEST(TestSanyoAcClass, OperatingMode) { + IRSanyoAc ac(kGpioUnused); + ac.begin(); + + ac.setMode(kSanyoAcAuto); + EXPECT_EQ(kSanyoAcAuto, ac.getMode()); + + ac.setMode(kSanyoAcCool); + EXPECT_EQ(kSanyoAcCool, ac.getMode()); + + ac.setMode(kSanyoAcHeat); + EXPECT_EQ(kSanyoAcHeat, ac.getMode()); + + ac.setMode(kSanyoAcDry); + EXPECT_EQ(kSanyoAcDry, ac.getMode()); + + ac.setMode(kSanyoAcAuto + 1); + EXPECT_EQ(kSanyoAcAuto, ac.getMode()); + + ac.setMode(0); + EXPECT_EQ(kSanyoAcAuto, ac.getMode()); + + ac.setMode(255); + EXPECT_EQ(kSanyoAcAuto, ac.getMode()); +} + +TEST(TestSanyoAcClass, FanSpeed) { + IRSanyoAc ac(kGpioUnused); + ac.begin(); + + ac.setFan(kSanyoAcFanAuto); + EXPECT_EQ(kSanyoAcFanAuto, ac.getFan()); + + ac.setFan(kSanyoAcFanHigh); + EXPECT_EQ(kSanyoAcFanHigh, ac.getFan()); + + ac.setFan(kSanyoAcFanLow); + EXPECT_EQ(kSanyoAcFanLow, ac.getFan()); + + ac.setFan(kSanyoAcFanMedium); + EXPECT_EQ(kSanyoAcFanMedium, ac.getFan()); +} + +TEST(TestSanyoAcClass, Sleep) { + IRSanyoAc ac(kGpioUnused); + ac.begin(); + + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); + ac.setSleep(false); + EXPECT_FALSE(ac.getSleep()); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); +} + +TEST(TestSanyoAcClass, SwingV) { + IRSanyoAc ac(kGpioUnused); + ac.begin(); + + ac.setSwingV(kSanyoAcSwingVAuto); + EXPECT_EQ(kSanyoAcSwingVAuto, ac.getSwingV()); + + ac.setSwingV(kSanyoAcSwingVHigh); + EXPECT_EQ(kSanyoAcSwingVHigh, ac.getSwingV()); + + ac.setSwingV(kSanyoAcSwingVLow); + EXPECT_EQ(kSanyoAcSwingVLow, ac.getSwingV()); + + ac.setSwingV(kSanyoAcSwingVUpperMiddle); + EXPECT_EQ(kSanyoAcSwingVUpperMiddle, ac.getSwingV()); + + ac.setSwingV(0); + EXPECT_EQ(kSanyoAcSwingVAuto, ac.getSwingV()); + ac.setSwingV(255); + EXPECT_EQ(kSanyoAcSwingVAuto, ac.getSwingV()); +} + +TEST(TestSanyoAcClass, Timers) { + IRSanyoAc ac(kGpioUnused); + ac.begin(); + + ac.setOffTimer(0); + EXPECT_EQ(0, ac.getOffTimer()); + ac.setOffTimer(59); + EXPECT_EQ(0, ac.getOffTimer()); + ac.setOffTimer(60); + EXPECT_EQ(60, ac.getOffTimer()); + ac.setOffTimer(61); + EXPECT_EQ(60, ac.getOffTimer()); + ac.setOffTimer(15 * 60 + 59); + EXPECT_EQ(15 * 60, ac.getOffTimer()); + ac.setOffTimer(16 * 60); + EXPECT_EQ(15 * 60, ac.getOffTimer()); + + const uint8_t offTimer2Hr[kSanyoAcStateLength] = { + 0x6A, 0x6D, 0x4F, 0x02, 0x14, 0x85, 0x00, 0x00, 0x4A}; + ac.setRaw(offTimer2Hr); + EXPECT_EQ(2 * 60, ac.getOffTimer()); + EXPECT_EQ( + "Power: On, Mode: 1 (Heat), Temp: 17C, Fan: 0 (Auto), " + "Swing(V): 5 (Upper Middle), Sleep: Off, Beep: On, " + "Sensor: Room, Sensor Temp: 19C, Off Timer: 02:00", + ac.toString()); +} + +TEST(TestSanyoAcClass, Beep) { + IRSanyoAc ac(kGpioUnused); + ac.begin(); + + ac.setBeep(true); + EXPECT_TRUE(ac.getBeep()); + ac.setBeep(false); + EXPECT_FALSE(ac.getBeep()); + ac.setBeep(true); + EXPECT_TRUE(ac.getBeep()); + + const uint8_t beep_off[kSanyoAcStateLength] = { + 0x6A, 0x6D, 0x11, 0x00, 0x10, 0x85, 0x00, 0x00, 0x33}; + ac.setRaw(beep_off); + EXPECT_FALSE(ac.getBeep()); + const uint8_t beep_on[kSanyoAcStateLength] = { + 0x6A, 0x6E, 0x54, 0x00, 0x10, 0x83, 0x00, 0x00, 0x39}; + ac.setRaw(beep_on); + EXPECT_TRUE(ac.getBeep()); +} diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp index e0ae82987..fcd0e510e 100644 --- a/lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp @@ -11,7 +11,7 @@ // Test sending typical data only. TEST(TestSendToshibaAC, SendDataOnly) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); uint8_t toshiba_code[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, @@ -21,33 +21,33 @@ TEST(TestSendToshibaAC, SendDataOnly) { EXPECT_EQ( "f38000d50" "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s7048" + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s7400" "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s7048", + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s7400", irsend.outputStr()); } // Test sending with repeats. TEST(TestSendToshibaAC, SendWithRepeats) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); irsend.reset(); @@ -58,16 +58,16 @@ TEST(TestSendToshibaAC, SendWithRepeats) { EXPECT_EQ( "f38000d50" "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s7048", + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s7400", irsend.outputStr()); irsend.reset(); @@ -75,242 +75,200 @@ TEST(TestSendToshibaAC, SendWithRepeats) { EXPECT_EQ( "f38000d50" "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s7048" + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s7400" "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s7048" + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s7400" "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s7048", - irsend.outputStr()); -} - -// Test sending atypical sizes. -TEST(TestSendToshibaAC, SendUnexpectedSizes) { - IRsendTest irsend(4); - irsend.begin(); - - uint8_t toshiba_short_code[8] = {0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x08}; - uint8_t toshiba_long_code[10] = {0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0A}; - irsend.reset(); - irsend.sendToshibaAC(toshiba_short_code, kToshibaACStateLength - 1); - ASSERT_EQ("", irsend.outputStr()); - - irsend.reset(); - irsend.sendToshibaAC(toshiba_long_code, kToshibaACStateLength + 1); - ASSERT_EQ( - "f38000d50" - "m4400s4300" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s1623" - "m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623m543s472" - "m543s7048" - "m4400s4300" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623m543s1623" - "m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s1623m543s472m543s1623m543s472" - "m543s7048", + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s1600m580s1600" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s7400", irsend.outputStr()); } // Tests for IRToshibaAC class. TEST(TestToshibaACClass, Power) { - IRToshibaAC toshiba(0); - toshiba.begin(); + IRToshibaAC ac(kGpioUnused); + ac.begin(); - toshiba.on(); - EXPECT_TRUE(toshiba.getPower()); + ac.on(); + EXPECT_TRUE(ac.getPower()); - toshiba.off(); - EXPECT_FALSE(toshiba.getPower()); + ac.off(); + EXPECT_FALSE(ac.getPower()); - toshiba.setPower(true); - EXPECT_TRUE(toshiba.getPower()); + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); - toshiba.setPower(false); - EXPECT_FALSE(toshiba.getPower()); + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); } TEST(TestToshibaACClass, Temperature) { - IRToshibaAC toshiba(0); - toshiba.begin(); + IRToshibaAC ac(kGpioUnused); + ac.begin(); - toshiba.setTemp(0); - EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp()); + ac.setTemp(0); + EXPECT_EQ(kToshibaAcMinTemp, ac.getTemp()); - toshiba.setTemp(255); - EXPECT_EQ(kToshibaAcMaxTemp, toshiba.getTemp()); + ac.setTemp(255); + EXPECT_EQ(kToshibaAcMaxTemp, ac.getTemp()); - toshiba.setTemp(kToshibaAcMinTemp); - EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp()); + ac.setTemp(kToshibaAcMinTemp); + EXPECT_EQ(kToshibaAcMinTemp, ac.getTemp()); - toshiba.setTemp(kToshibaAcMaxTemp); - EXPECT_EQ(kToshibaAcMaxTemp, toshiba.getTemp()); + ac.setTemp(kToshibaAcMaxTemp); + EXPECT_EQ(kToshibaAcMaxTemp, ac.getTemp()); - toshiba.setTemp(kToshibaAcMinTemp - 1); - EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp()); + ac.setTemp(kToshibaAcMinTemp - 1); + EXPECT_EQ(kToshibaAcMinTemp, ac.getTemp()); - toshiba.setTemp(kToshibaAcMaxTemp + 1); - EXPECT_EQ(kToshibaAcMaxTemp, toshiba.getTemp()); + ac.setTemp(kToshibaAcMaxTemp + 1); + EXPECT_EQ(kToshibaAcMaxTemp, ac.getTemp()); - toshiba.setTemp(17); - EXPECT_EQ(17, toshiba.getTemp()); + ac.setTemp(17); + EXPECT_EQ(17, ac.getTemp()); - toshiba.setTemp(21); - EXPECT_EQ(21, toshiba.getTemp()); + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); - toshiba.setTemp(25); - EXPECT_EQ(25, toshiba.getTemp()); + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); - toshiba.setTemp(30); - EXPECT_EQ(30, toshiba.getTemp()); + ac.setTemp(30); + EXPECT_EQ(30, ac.getTemp()); } TEST(TestToshibaACClass, OperatingMode) { - IRToshibaAC toshiba(0); - toshiba.begin(); + IRToshibaAC ac(kGpioUnused); + ac.begin(); - toshiba.setMode(kToshibaAcAuto); - EXPECT_EQ(kToshibaAcAuto, toshiba.getMode()); + ac.setMode(kToshibaAcAuto); + EXPECT_EQ(kToshibaAcAuto, ac.getMode()); - toshiba.setMode(kToshibaAcCool); - EXPECT_EQ(kToshibaAcCool, toshiba.getMode()); + ac.setMode(kToshibaAcCool); + EXPECT_EQ(kToshibaAcCool, ac.getMode()); - toshiba.setMode(kToshibaAcHeat); - EXPECT_EQ(kToshibaAcHeat, toshiba.getMode()); + ac.setMode(kToshibaAcHeat); + EXPECT_EQ(kToshibaAcHeat, ac.getMode()); - toshiba.setMode(kToshibaAcDry); - EXPECT_EQ(kToshibaAcDry, toshiba.getMode()); + ac.setMode(kToshibaAcDry); + EXPECT_EQ(kToshibaAcDry, ac.getMode()); - toshiba.setMode(kToshibaAcHeat + 1); - EXPECT_EQ(kToshibaAcAuto, toshiba.getMode()); + ac.setMode(kToshibaAcFan); + EXPECT_EQ(kToshibaAcFan, ac.getMode()); - toshiba.setMode(255); - EXPECT_EQ(kToshibaAcAuto, toshiba.getMode()); + ac.setMode(kToshibaAcFan + 1); + EXPECT_EQ(kToshibaAcAuto, ac.getMode()); - // Setting the power off changes the underlying mode in the state to heat. - toshiba.setPower(true); - toshiba.setMode(kToshibaAcCool); - EXPECT_EQ(kToshibaAcCool, toshiba.getMode()); - EXPECT_EQ(kToshibaAcCool, toshiba.getMode(true)); - toshiba.setPower(false); - EXPECT_EQ(kToshibaAcCool, toshiba.getMode()); - EXPECT_EQ(kToshibaAcHeat, toshiba.getMode(true)); + ac.setMode(255); + EXPECT_EQ(kToshibaAcAuto, ac.getMode()); + + // Setting the power off changes the underlying mode in the state to a special + // off mode. + ac.setPower(true); + ac.setMode(kToshibaAcCool); + EXPECT_EQ(kToshibaAcCool, ac.getMode()); + ac.setPower(false); + EXPECT_EQ(kToshibaAcCool, ac.getMode()); } TEST(TestToshibaACClass, FanSpeed) { - IRToshibaAC toshiba(0); - toshiba.begin(); + IRToshibaAC ac(kGpioUnused); + ac.begin(); - toshiba.setFan(kToshibaAcFanAuto); - EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan()); + ac.setFan(kToshibaAcFanAuto); + EXPECT_EQ(kToshibaAcFanAuto, ac.getFan()); - toshiba.setFan(255); - EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan()); + ac.setFan(255); + EXPECT_EQ(kToshibaAcFanMax, ac.getFan()); - toshiba.setFan(kToshibaAcFanMax); - EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan()); + ac.setFan(kToshibaAcFanMax); + EXPECT_EQ(kToshibaAcFanMax, ac.getFan()); - toshiba.setFan(kToshibaAcFanMax - 1); - EXPECT_EQ(kToshibaAcFanMax - 1, toshiba.getFan()); + ac.setFan(kToshibaAcFanMax - 1); + EXPECT_EQ(kToshibaAcFanMax - 1, ac.getFan()); - toshiba.setFan(1); - EXPECT_EQ(1, toshiba.getFan()); + ac.setFan(1); + EXPECT_EQ(1, ac.getFan()); - toshiba.setFan(2); - EXPECT_EQ(2, toshiba.getFan()); + ac.setFan(2); + EXPECT_EQ(2, ac.getFan()); - toshiba.setFan(3); - EXPECT_EQ(3, toshiba.getFan()); + ac.setFan(3); + EXPECT_EQ(3, ac.getFan()); - toshiba.setFan(4); - EXPECT_EQ(4, toshiba.getFan()); + ac.setFan(4); + EXPECT_EQ(4, ac.getFan()); - toshiba.setFan(kToshibaAcFanMax + 1); - EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan()); + ac.setFan(kToshibaAcFanMax + 1); + EXPECT_EQ(kToshibaAcFanMax, ac.getFan()); } TEST(TestToshibaACClass, RawState) { - IRToshibaAC toshiba(0); - toshiba.begin(); + IRToshibaAC ac(kGpioUnused); + ac.begin(); uint8_t initial_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, - 0x00, 0x00, 0x00, 0x01}; + 0x50, 0x00, 0x00, 0x51}; uint8_t modified_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0xC1, 0x00, 0xC0}; // Verify the starting state. - EXPECT_STATE_EQ(initial_state, toshiba.getRaw(), kToshibaACBits); - EXPECT_TRUE(toshiba.getPower()); - EXPECT_EQ(kToshibaAcAuto, toshiba.getMode()); - EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan()); + EXPECT_STATE_EQ(initial_state, ac.getRaw(), kToshibaACBits); + EXPECT_TRUE(ac.getPower()); + EXPECT_EQ(kToshibaAcAuto, ac.getMode()); + EXPECT_EQ(kToshibaAcFanAuto, ac.getFan()); // Change some settings. - toshiba.setMode(kToshibaAcCool); - toshiba.setFan(kToshibaAcFanMax); - toshiba.setTemp(kToshibaAcMinTemp); + ac.setMode(kToshibaAcCool); + ac.setFan(kToshibaAcFanMax); + ac.setTemp(kToshibaAcMinTemp); // Verify those were set. - EXPECT_EQ(kToshibaAcCool, toshiba.getMode()); - EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan()); - EXPECT_EQ(kToshibaAcMinTemp, toshiba.getTemp()); + EXPECT_EQ(kToshibaAcCool, ac.getMode()); + EXPECT_EQ(kToshibaAcFanMax, ac.getFan()); + EXPECT_EQ(kToshibaAcMinTemp, ac.getTemp()); // Retrieve the modified state. - EXPECT_STATE_EQ(modified_state, toshiba.getRaw(), kToshibaACBits); + EXPECT_STATE_EQ(modified_state, ac.getRaw(), kToshibaACBits); // Set it back to the initial state. - toshiba.setRaw(initial_state); + ac.setRaw(initial_state); // Check the new state was set correctly. - EXPECT_TRUE(toshiba.getPower()); - EXPECT_EQ(kToshibaAcAuto, toshiba.getMode()); - EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan()); - EXPECT_STATE_EQ(initial_state, toshiba.getRaw(), kToshibaACBits); + EXPECT_TRUE(ac.getPower()); + EXPECT_EQ(kToshibaAcAuto, ac.getMode()); + EXPECT_EQ(kToshibaAcFanAuto, ac.getFan()); + EXPECT_STATE_EQ(initial_state, ac.getRaw(), kToshibaACBits); } TEST(TestToshibaACClass, Checksums) { - IRToshibaAC toshiba(0); - toshiba.begin(); + IRToshibaAC ac(kGpioUnused); + ac.begin(); uint8_t initial_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x01}; @@ -319,8 +277,8 @@ TEST(TestToshibaACClass, Checksums) { uint8_t invalid_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00}; - EXPECT_EQ(0x01, toshiba.calcChecksum(initial_state)); - EXPECT_EQ(0xC0, toshiba.calcChecksum(modified_state)); + EXPECT_EQ(0x01, ac.calcChecksum(initial_state)); + EXPECT_EQ(0xC0, ac.calcChecksum(modified_state)); // Check we can call it without instantiating the object. EXPECT_EQ(0x01, IRToshibaAC::calcChecksum(initial_state)); // Use different lengths. @@ -344,150 +302,69 @@ TEST(TestToshibaACClass, Checksums) { } TEST(TestToshibaACClass, HumanReadableOutput) { - IRToshibaAC toshiba(0); - toshiba.begin(); + IRToshibaAC ac(kGpioUnused); + ac.begin(); uint8_t initial_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x01}; uint8_t modified_state[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0xC1, 0x00, 0xC0}; - toshiba.setRaw(initial_state); - EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto)", - toshiba.toString()); - toshiba.setRaw(modified_state); - EXPECT_EQ("Power: On, Mode: 1 (Cool), Temp: 17C, Fan: 5 (High)", - toshiba.toString()); - toshiba.off(); - toshiba.setTemp(25); - toshiba.setFan(3); - toshiba.setMode(kToshibaAcDry); - EXPECT_EQ("Power: Off, Mode: 2 (Dry), Temp: 25C, Fan: 3 (Medium)", - toshiba.toString()); + ac.setRaw(initial_state); + EXPECT_EQ("Temp: 17C, Power: On, Mode: 0 (Auto), Fan: 0 (Auto), " + "Turbo: Off, Econo: Off", + ac.toString()); + ac.setRaw(modified_state); + EXPECT_EQ("Temp: 17C, Power: On, Mode: 1 (Cool), Fan: 5 (High), " + "Turbo: Off, Econo: Off", + ac.toString()); + ac.setTemp(25); + ac.setFan(3); + ac.setMode(kToshibaAcDry); + EXPECT_EQ("Temp: 25C, Power: On, Mode: 2 (Dry), Fan: 3 (Medium), " + "Turbo: Off, Econo: Off", + ac.toString()); + ac.off(); + EXPECT_EQ("Temp: 25C, Power: Off, Fan: 3 (Medium), Turbo: Off, Econo: Off", + ac.toString()); } TEST(TestToshibaACClass, MessageConstuction) { - IRToshibaAC toshiba(0); - IRsendTest irsend(4); - toshiba.begin(); - irsend.begin(); + IRToshibaAC ac(kGpioUnused); + ac.begin(); - toshiba.setFan(1); - toshiba.setMode(kToshibaAcCool); - toshiba.setTemp(27); - toshiba.on(); + ac.on(); + ac.setFan(1); + ac.setMode(kToshibaAcCool); + ac.setTemp(27); // Check everything for kicks. - EXPECT_EQ(1, toshiba.getFan()); - EXPECT_EQ(kToshibaAcCool, toshiba.getMode()); - EXPECT_EQ(27, toshiba.getTemp()); - EXPECT_TRUE(toshiba.getPower()); - - irsend.reset(); - irsend.sendToshibaAC(toshiba.getRaw()); - EXPECT_EQ( - "f38000d50" - "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s7048" - "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s7048", - irsend.outputStr()); + EXPECT_EQ(1, ac.getFan()); + EXPECT_EQ(kToshibaAcCool, ac.getMode()); + EXPECT_EQ(27, ac.getTemp()); + EXPECT_TRUE(ac.getPower()); // Turn off the power and re-check. - toshiba.setPower(false); + ac.setPower(false); // Check everything for kicks. - EXPECT_EQ(1, toshiba.getFan()); - EXPECT_EQ(kToshibaAcCool, toshiba.getMode()); - EXPECT_EQ(27, toshiba.getTemp()); - EXPECT_FALSE(toshiba.getPower()); - - irsend.reset(); - irsend.sendToshibaAC(toshiba.getRaw()); - EXPECT_EQ( - "f38000d50" - "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s1623m543s472m543s472m543s472m543s1623m543s1623m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s1623m543s472" - "m543s7048" - "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s1623m543s472m543s472m543s472m543s1623m543s1623m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s1623m543s472" - "m543s7048", - irsend.outputStr()); + EXPECT_EQ(1, ac.getFan()); + EXPECT_EQ(kToshibaAcCool, ac.getMode()); + EXPECT_EQ(27, ac.getTemp()); + EXPECT_FALSE(ac.getPower()); // Turn the power back on, and check nothing changed. - toshiba.on(); + ac.on(); - EXPECT_EQ(1, toshiba.getFan()); - EXPECT_EQ(kToshibaAcCool, toshiba.getMode()); - EXPECT_EQ(27, toshiba.getTemp()); - EXPECT_TRUE(toshiba.getPower()); - - irsend.reset(); - irsend.sendToshibaAC(toshiba.getRaw()); - EXPECT_EQ( - "f38000d50" - "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s7048" - "m4400s4300" - "m543s1623m543s1623m543s1623m543s1623m543s472m543s472m543s1623m543s472" - "m543s472m543s472m543s472m543s472m543s1623m543s1623m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s1623m543s1623" - "m543s1623m543s1623m543s1623m543s1623m543s1623m543s1623m543s472m543s472" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s1623m543s472m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s472m543s1623m543s472m543s472m543s472m543s472m543s472m543s1623" - "m543s472m543s472m543s472m543s472m543s472m543s472m543s472m543s472" - "m543s1623m543s1623m543s1623m543s472m543s472m543s472m543s472m543s472" - "m543s7048", - irsend.outputStr()); + EXPECT_EQ(1, ac.getFan()); + EXPECT_EQ(kToshibaAcCool, ac.getMode()); + EXPECT_EQ(27, ac.getTemp()); + EXPECT_TRUE(ac.getPower()); } // Decoding a message we entirely constructed based solely on a given state. TEST(TestDecodeToshibaAC, SyntheticExample) { - IRsendTest irsend(4); - IRrecv irrecv(4); + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); irsend.begin(); uint8_t expectedState[kToshibaACStateLength] = {0xF2, 0x0D, 0x03, 0xFC, 0x01, @@ -501,7 +378,8 @@ TEST(TestDecodeToshibaAC, SyntheticExample) { ASSERT_EQ(kToshibaACBits, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); EXPECT_EQ( - "Power: On, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto)", + "Temp: 17C, Power: On, Mode: 0 (Auto), Fan: 0 (Auto), Turbo: Off, " + "Econo: Off", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); @@ -510,9 +388,9 @@ TEST(TestDecodeToshibaAC, SyntheticExample) { // Test decoding against captures from a real Toshiba A/C remote. // Recorded by @mwildbolz TEST(TestDecodeToshibaAC, RealExamples) { - IRToshibaAC toshiba(0); - IRsendTest irsend(4); - IRrecv irrecv(4); + IRToshibaAC ac(kGpioUnused); + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); irsend.begin(); uint16_t rawData1[295] = { @@ -548,11 +426,11 @@ TEST(TestDecodeToshibaAC, RealExamples) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type); ASSERT_EQ(kToshibaACBits, irsend.capture.bits); - toshiba.setRaw(irsend.capture.state); - EXPECT_TRUE(toshiba.getPower()); - EXPECT_EQ(23, toshiba.getTemp()); - EXPECT_EQ(kToshibaAcFanAuto, toshiba.getFan()); - EXPECT_EQ(kToshibaAcAuto, toshiba.getMode()); + ac.setRaw(irsend.capture.state); + EXPECT_TRUE(ac.getPower()); + EXPECT_EQ(23, ac.getTemp()); + EXPECT_EQ(kToshibaAcFanAuto, ac.getFan()); + EXPECT_EQ(kToshibaAcAuto, ac.getMode()); uint16_t rawData2[295] = { 4500, 4236, 636, 1520, 642, 1520, 640, 1520, 664, 1492, 642, 440, @@ -587,11 +465,11 @@ TEST(TestDecodeToshibaAC, RealExamples) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type); ASSERT_EQ(kToshibaACBits, irsend.capture.bits); - toshiba.setRaw(irsend.capture.state); - EXPECT_TRUE(toshiba.getPower()); - EXPECT_EQ(17, toshiba.getTemp()); - EXPECT_EQ(3, toshiba.getFan()); - EXPECT_EQ(kToshibaAcCool, toshiba.getMode()); + ac.setRaw(irsend.capture.state); + EXPECT_TRUE(ac.getPower()); + EXPECT_EQ(17, ac.getTemp()); + EXPECT_EQ(3, ac.getFan()); + EXPECT_EQ(kToshibaAcCool, ac.getMode()); uint16_t rawData3[295] = { 4474, 4262, 642, 1514, 642, 1520, 642, 1520, 642, 1514, 642, 438, @@ -626,11 +504,11 @@ TEST(TestDecodeToshibaAC, RealExamples) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type); ASSERT_EQ(kToshibaACBits, irsend.capture.bits); - toshiba.setRaw(irsend.capture.state); - EXPECT_TRUE(toshiba.getPower()); - EXPECT_EQ(24, toshiba.getTemp()); - EXPECT_EQ(kToshibaAcFanMax, toshiba.getFan()); - EXPECT_EQ(kToshibaAcHeat, toshiba.getMode()); + ac.setRaw(irsend.capture.state); + EXPECT_TRUE(ac.getPower()); + EXPECT_EQ(24, ac.getTemp()); + EXPECT_EQ(kToshibaAcFanMax, ac.getFan()); + EXPECT_EQ(kToshibaAcHeat, ac.getMode()); uint16_t rawData4[295] = { 4474, 4262, 636, 1520, 640, 1520, 640, 1520, 638, 1518, 642, 438, @@ -665,16 +543,10 @@ TEST(TestDecodeToshibaAC, RealExamples) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type); ASSERT_EQ(kToshibaACBits, irsend.capture.bits); - toshiba.setRaw(irsend.capture.state); - EXPECT_FALSE(toshiba.getPower()); - EXPECT_EQ(22, toshiba.getTemp()); - EXPECT_EQ(4, toshiba.getFan()); - - // Confirming the quirky behaviour that the 'Power OFF' signal - // sets the mode to heat. - // The previous state the remote was in was 'AUTO' just prior to - // sending the power off message. - EXPECT_EQ(kToshibaAcHeat, toshiba.getMode()); + ac.setRaw(irsend.capture.state); + EXPECT_FALSE(ac.getPower()); + EXPECT_EQ(22, ac.getTemp()); + EXPECT_EQ(4, ac.getFan()); } TEST(TestToshibaACClass, toCommon) { @@ -704,3 +576,166 @@ TEST(TestToshibaACClass, toCommon) { ASSERT_EQ(-1, ac.toCommon().sleep); ASSERT_EQ(-1, ac.toCommon().clock); } + +// Tests for CarrierAc2 +/// Decode a "real" long example message. +TEST(TestDecodeToshibaAC, RealLongExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + // Data from: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1205#issuecomment-650475434 + const uint16_t high_power_on[327] = { + 4424, 4320, + 582, 1574, 588, 1578, 582, 1574, 586, 1578, 586, 496, 582, 492, 586, 1576, + 586, 492, 586, 492, 588, 496, 584, 496, 584, 496, 584, 1626, 534, 1626, + 534, 494, 586, 1578, 582, 494, 586, 494, 586, 494, 588, 492, 586, 492, + 586, 1576, 586, 494, 588, 492, 588, 1574, 588, 1576, 584, 1578, 584, 1574, + 588, 1574, 588, 492, 588, 1572, 590, 1570, 590, 492, 588, 492, 590, 488, + 590, 494, 584, 1570, 592, 492, 586, 490, 590, 1572, 590, 490, 590, 1570, + 590, 490, 590, 1570, 590, 492, 588, 490, 588, 492, 588, 492, 590, 490, + 590, 494, 586, 490, 590, 490, 588, 490, 590, 490, 588, 492, 590, 490, + 588, 492, 590, 490, 590, 490, 590, 494, 584, 490, 590, 490, 590, 490, + 590, 490, 588, 490, 588, 492, 588, 492, 586, 492, 588, 490, 588, 492, + 588, 490, 590, 1572, 588, 494, 586, 1574, 588, 492, 588, 1572, 590, 1572, + 588, 492, 588, 492, 586, 494, 588, + 7422, + 4424, 4320, + 586, 1572, 588, 1572, 588, 1576, 584, 1574, 588, 494, 586, 492, 588, 1572, + 588, 492, 588, 492, 588, 492, 588, 494, 586, 496, 584, 1574, 586, 1578, + 582, 494, 586, 1578, 584, 494, 586, 492, 588, 492, 586, 496, 584, 494, + 586, 1578, 584, 494, 586, 494, 584, 1574, 588, 1572, 586, 1574, 588, 1574, + 588, 1572, 588, 494, 590, 1572, 588, 1574, 588, 492, 588, 492, 588, 492, + 586, 492, 588, 1572, 588, 498, 582, 492, 588, 1576, 586, 492, 588, 1572, + 588, 494, 588, 1572, 588, 492, 586, 492, 588, 492, 590, 490, 588, 492, + 586, 492, 588, 492, 590, 490, 588, 490, 588, 492, 590, 490, 588, 492, + 590, 490, 588, 490, 590, 490, 590, 490, 592, 488, 592, 494, 584, 494, + 586, 490, 590, 494, 586, 494, 588, 488, 592, 490, 588, 492, 586, 490, + 592, 490, 588, 1576, 584, 494, 586, 1570, 590, 494, 586, 1576, 582, 1572, + 590, 490, 590, 490, 588, 490, 590}; // UNKNOWN 54926187 + + const uint8_t expectedState[kToshibaACStateLengthLong] = { + 0xF2, 0x0D, 0x04, 0xFB, 0x09, 0x50, 0x00, 0x00, 0x01, 0x58}; + irsend.sendRaw(high_power_on, 327, 38000); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::TOSHIBA_AC, irsend.capture.decode_type); + EXPECT_EQ(kToshibaACBitsLong, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Temp: 22C, Power: On, Mode: 0 (Auto), Fan: 0 (Auto), Turbo: On, " + "Econo: Off", + IRAcUtils::resultAcToString(&irsend.capture)); +} + + +/// Decode a synthetic long message. +TEST(TestDecodeToshibaAC, SyntheticLongExample) { + IRsendTest irsend(0); + IRrecv irrecv(0); + + const uint8_t expectedState[kToshibaACStateLengthLong] = { + 0xF2, 0x0D, 0x04, 0xFB, 0x09, 0x50, 0x00, 0x00, 0x01, 0x58}; + irsend.begin(); + irsend.reset(); + irsend.sendToshibaAC(expectedState, kToshibaACStateLengthLong); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::TOSHIBA_AC, irsend.capture.decode_type); + EXPECT_EQ(kToshibaACBitsLong, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "f38000d50" + // 4424 4320 + "m4400s4300" + // 582 1574 588 1578 582 1574 586 1578 586 496 582 492 586 1576 586 492 + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + // 586 492 588 496 584 496 584 496 584 1626 534 1626 534 494 586 1578 + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + // 582 494 586 494 586 494 588 492 586 492 586 1576 586 494 588 492 + "m580s490m580s490m580s490m580s490m580s490m580s1600m580s490m580s490" + // 588 1574 588 1576 584 1578 584 1574 588 1574 588 492 588 1572 590 1570 + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s1600m580s1600" + // 590 492 588 492 590 488 590 494 584 1570 592 492 586 490 590 1572 + "m580s490m580s490m580s490m580s490m580s1600m580s490m580s490m580s1600" + // 590 490 590 1570 590 490 590 1570 590 492 588 490 588 492 588 492 + "m580s490m580s1600m580s490m580s1600m580s490m580s490m580s490m580s490" + // 590 490 590 494 586 490 590 490 588 490 590 490 588 492 590 490 + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + // 588 492 590 490 590 490 590 494 584 490 590 490 590 490 590 490 + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + // 588 490 588 492 588 492 586 492 588 490 588 492 588 490 590 1572 + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + // 588 494 586 1574 588 492 588 1572 590 1572 588 492 588 492 586 494 + "m580s490m580s1600m580s490m580s1600m580s1600m580s490m580s490m580s490" + // 588 7422 + "m580s7400" + "m4400s4300" + "m580s1600m580s1600m580s1600m580s1600m580s490m580s490m580s1600m580s490" + "m580s490m580s490m580s490m580s490m580s1600m580s1600m580s490m580s1600" + "m580s490m580s490m580s490m580s490m580s490m580s1600m580s490m580s490" + "m580s1600m580s1600m580s1600m580s1600m580s1600m580s490m580s1600m580s1600" + "m580s490m580s490m580s490m580s490m580s1600m580s490m580s490m580s1600" + "m580s490m580s1600m580s490m580s1600m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s490" + "m580s490m580s490m580s490m580s490m580s490m580s490m580s490m580s1600" + "m580s490m580s1600m580s490m580s1600m580s1600m580s490m580s490m580s490" + "m580s7400", + irsend.outputStr()); +} + +/// Decode a "real" short example message. +TEST(TestDecodeToshibaAC, RealShortExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + // Data from: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1205#issuecomment-650475096 + const uint16_t air_direction[115] = { + 4424, 4318, + 588, 1574, 588, 1572, 588, 1574, 586, 1572, 590, 490, 586, 494, 586, 1574, + 588, 492, 586, 494, 586, 494, 586, 496, 584, 492, 588, 1572, 588, 1572, + 590, 492, 588, 1572, 590, 490, 588, 492, 586, 494, 588, 492, 588, 492, + 588, 494, 584, 492, 588, 1572, 588, 1574, 588, 1574, 588, 1572, 588, 1572, + 588, 1572, 588, 1574, 590, 1570, 588, 494, 586, 496, 584, 494, 588, 1572, + 588, 492, 588, 492, 588, 490, 588, 492, 590, 1572, 588, 492, 588, 496, + 586, 492, 588, 492, 586, 492, 588, 492, 588, 490, 590, 490, 588, 492, + 588, 490, 588, 1572, 588, 492, 588, 492, 588, 490, 588, 492, 588, 1572, + 586}; // UNKNOWN DEB8845C + const uint8_t expectedState[kToshibaACStateLengthShort] = { + 0xF2, 0x0D, 0x01, 0xFE, 0x21, 0x00, 0x21}; + irsend.sendRaw(air_direction, 115, 38000); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::TOSHIBA_AC, irsend.capture.decode_type); + EXPECT_EQ(kToshibaACBitsShort, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Temp: 17C, Swing(V): 0 (Step)", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestToshibaACClass, ConstructLongState) { + IRToshibaAC ac(kGpioUnused); + ac.setPower(true); + ac.setMode(kToshibaAcDry); + ac.setTemp(29); + ac.setFan(2); + ac.setSwing(false); + ac.setTurbo(false); + ac.setEcono(true); + EXPECT_EQ( + "Temp: 29C, Power: On, Mode: 2 (Dry), Fan: 2 (UNKNOWN), " + "Turbo: Off, Econo: On", + ac.toString()); + EXPECT_EQ(kToshibaACStateLengthLong, ac.getStateLength()); + const uint8_t expectedState[kToshibaACStateLengthLong] = { + 0xF2, 0x0D, 0x04, 0xFB, 0x09, 0xC0, 0x62, 0x00, 0x03, 0xA8}; + EXPECT_STATE_EQ(expectedState, ac.getRaw(), kToshibaACBitsLong); + EXPECT_EQ(kToshibaACStateLengthLong, ac.getStateLength()); +} diff --git a/lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh b/lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh old mode 100644 new mode 100755 diff --git a/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py old mode 100644 new mode 100755 diff --git a/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py old mode 100644 new mode 100755 diff --git a/lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh b/lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh old mode 100644 new mode 100755 diff --git a/lib/IRremoteESP8266-2.7.8/tools/mkkeywords b/lib/IRremoteESP8266-2.7.8/tools/mkkeywords old mode 100644 new mode 100755 diff --git a/lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py b/lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py old mode 100644 new mode 100755 diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 6a9520fcc..0f13cfe48 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -13,6 +13,7 @@ - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 - Add command (``S``)``SerialSend6`` \ (#8937) - Add support for Sonoff Zigbee Bridge as module 75 (#8583) +- Change IRRemoteESP8266 IR lib to pre-2.7.9, fixing Samsung and Pioneer protocols (#8938) ### 8.3.1.6 20200617 From ba3856d900d48365ab8bd3ec2d0069dbb893db49 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 29 Jul 2020 14:44:45 +0200 Subject: [PATCH 581/581] Change IRRemoteESP8266 library Change IRRemoteESP8266 library from v2.7.6 to v2.7.8.10, fixing Samsung and Pioneer protocols (#8938) --- RELEASENOTES.md | 2 +- .../CPPLINT.cfg | 0 .../Doxyfile | 0 .../LICENSE.txt | 0 .../README.md | 0 .../README_fr.md | 0 .../ReleaseNotes.md | 0 .../SupportedProtocols.md | 0 .../docs/README.md | 0 .../docs/README_fr.md | 0 .../docs/_config.yml | 0 .../docs/doxygen/html/IRac_8cpp.html | 0 .../docs/doxygen/html/IRac_8h.html | 0 .../docs/doxygen/html/IRac_8h_source.html | 0 .../docs/doxygen/html/IRrecv_8cpp.html | 0 .../docs/doxygen/html/IRrecv_8h.html | 0 .../docs/doxygen/html/IRrecv_8h_source.html | 0 .../docs/doxygen/html/IRremoteESP8266_8h.html | 0 .../html/IRremoteESP8266_8h_source.html | 0 .../docs/doxygen/html/IRsend_8cpp.html | 0 .../docs/doxygen/html/IRsend_8h.html | 0 .../docs/doxygen/html/IRsend_8h_source.html | 0 .../docs/doxygen/html/IRtext_8cpp.html | 0 .../docs/doxygen/html/IRtext_8h.html | 0 .../docs/doxygen/html/IRtext_8h_source.html | 0 .../docs/doxygen/html/IRtimer_8cpp.html | 0 .../docs/doxygen/html/IRtimer_8h.html | 0 .../docs/doxygen/html/IRtimer_8h_source.html | 0 .../docs/doxygen/html/IRutils_8cpp.html | 0 .../docs/doxygen/html/IRutils_8h.html | 0 .../docs/doxygen/html/IRutils_8h_source.html | 0 .../docs/doxygen/html/README_8md.html | 0 .../docs/doxygen/html/annotated.html | 0 .../docs/doxygen/html/bc_s.png | Bin .../docs/doxygen/html/bdwn.png | Bin .../doxygen/html/classIRAmcorAc-members.html | 0 .../docs/doxygen/html/classIRAmcorAc.html | 0 .../html/classIRAmcorAc__coll__graph.map | 0 .../html/classIRAmcorAc__coll__graph.md5 | 0 .../html/classIRAmcorAc__coll__graph.png | Bin .../doxygen/html/classIRArgoAC-members.html | 0 .../docs/doxygen/html/classIRArgoAC.html | 0 .../html/classIRArgoAC__coll__graph.map | 0 .../html/classIRArgoAC__coll__graph.md5 | 0 .../html/classIRArgoAC__coll__graph.png | Bin .../html/classIRCarrierAc64-members.html | 0 .../docs/doxygen/html/classIRCarrierAc64.html | 0 .../html/classIRCarrierAc64__coll__graph.map | 0 .../html/classIRCarrierAc64__coll__graph.md5 | 0 .../html/classIRCarrierAc64__coll__graph.png | Bin .../doxygen/html/classIRCoolixAC-members.html | 0 .../docs/doxygen/html/classIRCoolixAC.html | 0 .../html/classIRCoolixAC__coll__graph.map | 0 .../html/classIRCoolixAC__coll__graph.md5 | 0 .../html/classIRCoolixAC__coll__graph.png | Bin .../doxygen/html/classIRCoronaAc-members.html | 0 .../docs/doxygen/html/classIRCoronaAc.html | 0 .../html/classIRCoronaAc__coll__graph.map | 0 .../html/classIRCoronaAc__coll__graph.md5 | 0 .../html/classIRCoronaAc__coll__graph.png | Bin .../html/classIRDaikin128-members.html | 0 .../docs/doxygen/html/classIRDaikin128.html | 0 .../html/classIRDaikin128__coll__graph.map | 0 .../html/classIRDaikin128__coll__graph.md5 | 0 .../html/classIRDaikin128__coll__graph.png | Bin .../html/classIRDaikin152-members.html | 0 .../docs/doxygen/html/classIRDaikin152.html | 0 .../html/classIRDaikin152__coll__graph.map | 0 .../html/classIRDaikin152__coll__graph.md5 | 0 .../html/classIRDaikin152__coll__graph.png | Bin .../html/classIRDaikin160-members.html | 0 .../docs/doxygen/html/classIRDaikin160.html | 0 .../html/classIRDaikin160__coll__graph.map | 0 .../html/classIRDaikin160__coll__graph.md5 | 0 .../html/classIRDaikin160__coll__graph.png | Bin .../html/classIRDaikin176-members.html | 0 .../docs/doxygen/html/classIRDaikin176.html | 0 .../html/classIRDaikin176__coll__graph.map | 0 .../html/classIRDaikin176__coll__graph.md5 | 0 .../html/classIRDaikin176__coll__graph.png | Bin .../doxygen/html/classIRDaikin2-members.html | 0 .../docs/doxygen/html/classIRDaikin2.html | 0 .../html/classIRDaikin216-members.html | 0 .../docs/doxygen/html/classIRDaikin216.html | 0 .../html/classIRDaikin216__coll__graph.map | 0 .../html/classIRDaikin216__coll__graph.md5 | 0 .../html/classIRDaikin216__coll__graph.png | Bin .../html/classIRDaikin2__coll__graph.map | 0 .../html/classIRDaikin2__coll__graph.md5 | 0 .../html/classIRDaikin2__coll__graph.png | Bin .../doxygen/html/classIRDaikin64-members.html | 0 .../docs/doxygen/html/classIRDaikin64.html | 0 .../html/classIRDaikin64__coll__graph.map | 0 .../html/classIRDaikin64__coll__graph.md5 | 0 .../html/classIRDaikin64__coll__graph.png | Bin .../html/classIRDaikinESP-members.html | 0 .../docs/doxygen/html/classIRDaikinESP.html | 0 .../html/classIRDaikinESP__coll__graph.map | 0 .../html/classIRDaikinESP__coll__graph.md5 | 0 .../html/classIRDaikinESP__coll__graph.png | Bin .../html/classIRDelonghiAc-members.html | 0 .../docs/doxygen/html/classIRDelonghiAc.html | 0 .../html/classIRDelonghiAc__coll__graph.map | 0 .../html/classIRDelonghiAc__coll__graph.md5 | 0 .../html/classIRDelonghiAc__coll__graph.png | Bin .../html/classIRElectraAc-members.html | 0 .../docs/doxygen/html/classIRElectraAc.html | 0 .../html/classIRElectraAc__coll__graph.map | 0 .../html/classIRElectraAc__coll__graph.md5 | 0 .../html/classIRElectraAc__coll__graph.png | Bin .../html/classIRFujitsuAC-members.html | 0 .../docs/doxygen/html/classIRFujitsuAC.html | 0 .../html/classIRFujitsuAC__coll__graph.map | 0 .../html/classIRFujitsuAC__coll__graph.md5 | 0 .../html/classIRFujitsuAC__coll__graph.png | Bin .../html/classIRGoodweatherAc-members.html | 0 .../doxygen/html/classIRGoodweatherAc.html | 0 .../classIRGoodweatherAc__coll__graph.map | 0 .../classIRGoodweatherAc__coll__graph.md5 | 0 .../classIRGoodweatherAc__coll__graph.png | Bin .../doxygen/html/classIRGreeAC-members.html | 0 .../docs/doxygen/html/classIRGreeAC.html | 0 .../html/classIRGreeAC__coll__graph.map | 0 .../html/classIRGreeAC__coll__graph.md5 | 0 .../html/classIRGreeAC__coll__graph.png | Bin .../doxygen/html/classIRHaierAC-members.html | 0 .../docs/doxygen/html/classIRHaierAC.html | 0 .../html/classIRHaierACYRW02-members.html | 0 .../doxygen/html/classIRHaierACYRW02.html | 0 .../html/classIRHaierACYRW02__coll__graph.map | 0 .../html/classIRHaierACYRW02__coll__graph.md5 | 0 .../html/classIRHaierACYRW02__coll__graph.png | Bin .../html/classIRHaierAC__coll__graph.map | 0 .../html/classIRHaierAC__coll__graph.md5 | 0 .../html/classIRHaierAC__coll__graph.png | Bin .../html/classIRHitachiAc-members.html | 0 .../docs/doxygen/html/classIRHitachiAc.html | 0 .../html/classIRHitachiAc1-members.html | 0 .../docs/doxygen/html/classIRHitachiAc1.html | 0 .../html/classIRHitachiAc1__coll__graph.map | 0 .../html/classIRHitachiAc1__coll__graph.md5 | 0 .../html/classIRHitachiAc1__coll__graph.png | Bin .../html/classIRHitachiAc3-members.html | 0 .../docs/doxygen/html/classIRHitachiAc3.html | 0 .../html/classIRHitachiAc344-members.html | 0 .../doxygen/html/classIRHitachiAc344.html | 0 .../html/classIRHitachiAc344__coll__graph.map | 0 .../html/classIRHitachiAc344__coll__graph.md5 | 0 .../html/classIRHitachiAc344__coll__graph.png | Bin .../classIRHitachiAc344__inherit__graph.map | 0 .../classIRHitachiAc344__inherit__graph.md5 | 0 .../classIRHitachiAc344__inherit__graph.png | Bin .../html/classIRHitachiAc3__coll__graph.map | 0 .../html/classIRHitachiAc3__coll__graph.md5 | 0 .../html/classIRHitachiAc3__coll__graph.png | Bin .../html/classIRHitachiAc424-members.html | 0 .../doxygen/html/classIRHitachiAc424.html | 0 .../html/classIRHitachiAc424__coll__graph.map | 0 .../html/classIRHitachiAc424__coll__graph.md5 | 0 .../html/classIRHitachiAc424__coll__graph.png | Bin .../classIRHitachiAc424__inherit__graph.map | 0 .../classIRHitachiAc424__inherit__graph.md5 | 0 .../classIRHitachiAc424__inherit__graph.png | Bin .../html/classIRHitachiAc__coll__graph.map | 0 .../html/classIRHitachiAc__coll__graph.md5 | 0 .../html/classIRHitachiAc__coll__graph.png | Bin .../html/classIRKelvinatorAC-members.html | 0 .../doxygen/html/classIRKelvinatorAC.html | 0 .../html/classIRKelvinatorAC__coll__graph.map | 0 .../html/classIRKelvinatorAC__coll__graph.md5 | 0 .../html/classIRKelvinatorAC__coll__graph.png | Bin .../doxygen/html/classIRLgAc-members.html | 0 .../docs/doxygen/html/classIRLgAc.html | 0 .../doxygen/html/classIRLgAc__coll__graph.map | 0 .../doxygen/html/classIRLgAc__coll__graph.md5 | 0 .../doxygen/html/classIRLgAc__coll__graph.png | Bin .../doxygen/html/classIRMideaAC-members.html | 0 .../docs/doxygen/html/classIRMideaAC.html | 0 .../html/classIRMideaAC__coll__graph.map | 0 .../html/classIRMideaAC__coll__graph.md5 | 0 .../html/classIRMideaAC__coll__graph.png | Bin .../html/classIRMitsubishi112-members.html | 0 .../doxygen/html/classIRMitsubishi112.html | 0 .../classIRMitsubishi112__coll__graph.map | 0 .../classIRMitsubishi112__coll__graph.md5 | 0 .../classIRMitsubishi112__coll__graph.png | Bin .../html/classIRMitsubishi136-members.html | 0 .../doxygen/html/classIRMitsubishi136.html | 0 .../classIRMitsubishi136__coll__graph.map | 0 .../classIRMitsubishi136__coll__graph.md5 | 0 .../classIRMitsubishi136__coll__graph.png | Bin .../html/classIRMitsubishiAC-members.html | 0 .../doxygen/html/classIRMitsubishiAC.html | 0 .../html/classIRMitsubishiAC__coll__graph.map | 0 .../html/classIRMitsubishiAC__coll__graph.md5 | 0 .../html/classIRMitsubishiAC__coll__graph.png | Bin .../classIRMitsubishiHeavy152Ac-members.html | 0 .../html/classIRMitsubishiHeavy152Ac.html | 0 ...assIRMitsubishiHeavy152Ac__coll__graph.map | 0 ...assIRMitsubishiHeavy152Ac__coll__graph.md5 | 0 ...assIRMitsubishiHeavy152Ac__coll__graph.png | Bin .../classIRMitsubishiHeavy88Ac-members.html | 0 .../html/classIRMitsubishiHeavy88Ac.html | 0 ...lassIRMitsubishiHeavy88Ac__coll__graph.map | 0 ...lassIRMitsubishiHeavy88Ac__coll__graph.md5 | 0 ...lassIRMitsubishiHeavy88Ac__coll__graph.png | Bin .../html/classIRNeoclimaAc-members.html | 0 .../docs/doxygen/html/classIRNeoclimaAc.html | 0 .../html/classIRNeoclimaAc__coll__graph.map | 0 .../html/classIRNeoclimaAc__coll__graph.md5 | 0 .../html/classIRNeoclimaAc__coll__graph.png | Bin .../html/classIRPanasonicAc-members.html | 0 .../docs/doxygen/html/classIRPanasonicAc.html | 0 .../html/classIRPanasonicAc__coll__graph.map | 0 .../html/classIRPanasonicAc__coll__graph.md5 | 0 .../html/classIRPanasonicAc__coll__graph.png | Bin .../html/classIRSamsungAc-members.html | 0 .../docs/doxygen/html/classIRSamsungAc.html | 0 .../html/classIRSamsungAc__coll__graph.map | 0 .../html/classIRSamsungAc__coll__graph.md5 | 0 .../html/classIRSamsungAc__coll__graph.png | Bin .../doxygen/html/classIRSharpAc-members.html | 0 .../docs/doxygen/html/classIRSharpAc.html | 0 .../html/classIRSharpAc__coll__graph.map | 0 .../html/classIRSharpAc__coll__graph.md5 | 0 .../html/classIRSharpAc__coll__graph.png | Bin .../doxygen/html/classIRTcl112Ac-members.html | 0 .../docs/doxygen/html/classIRTcl112Ac.html | 0 .../html/classIRTcl112Ac__coll__graph.map | 0 .../html/classIRTcl112Ac__coll__graph.md5 | 0 .../html/classIRTcl112Ac__coll__graph.png | Bin .../doxygen/html/classIRTecoAc-members.html | 0 .../docs/doxygen/html/classIRTecoAc.html | 0 .../html/classIRTecoAc__coll__graph.map | 0 .../html/classIRTecoAc__coll__graph.md5 | 0 .../html/classIRTecoAc__coll__graph.png | Bin .../html/classIRToshibaAC-members.html | 0 .../docs/doxygen/html/classIRToshibaAC.html | 0 .../html/classIRToshibaAC__coll__graph.map | 0 .../html/classIRToshibaAC__coll__graph.md5 | 0 .../html/classIRToshibaAC__coll__graph.png | Bin .../html/classIRTrotecESP-members.html | 0 .../docs/doxygen/html/classIRTrotecESP.html | 0 .../html/classIRTrotecESP__coll__graph.map | 0 .../html/classIRTrotecESP__coll__graph.md5 | 0 .../html/classIRTrotecESP__coll__graph.png | Bin .../doxygen/html/classIRVestelAc-members.html | 0 .../docs/doxygen/html/classIRVestelAc.html | 0 .../html/classIRVestelAc__coll__graph.map | 0 .../html/classIRVestelAc__coll__graph.md5 | 0 .../html/classIRVestelAc__coll__graph.png | Bin .../html/classIRWhirlpoolAc-members.html | 0 .../docs/doxygen/html/classIRWhirlpoolAc.html | 0 .../html/classIRWhirlpoolAc__coll__graph.map | 0 .../html/classIRWhirlpoolAc__coll__graph.md5 | 0 .../html/classIRWhirlpoolAc__coll__graph.png | Bin .../docs/doxygen/html/classIRac-members.html | 0 .../docs/doxygen/html/classIRac.html | 0 .../doxygen/html/classIRac__coll__graph.map | 0 .../doxygen/html/classIRac__coll__graph.md5 | 0 .../doxygen/html/classIRac__coll__graph.png | Bin .../doxygen/html/classIRrecv-members.html | 0 .../docs/doxygen/html/classIRrecv.html | 0 .../doxygen/html/classIRrecv__coll__graph.map | 0 .../doxygen/html/classIRrecv__coll__graph.md5 | 0 .../doxygen/html/classIRrecv__coll__graph.png | Bin .../doxygen/html/classIRsend-members.html | 0 .../docs/doxygen/html/classIRsend.html | 0 .../doxygen/html/classIRtimer-members.html | 0 .../docs/doxygen/html/classIRtimer.html | 0 .../doxygen/html/classTimerMs-members.html | 0 .../docs/doxygen/html/classTimerMs.html | 0 .../html/classdecode__results-members.html | 0 .../doxygen/html/classdecode__results.html | 0 .../docs/doxygen/html/classes.html | 0 .../docs/doxygen/html/closed.png | Bin .../docs/doxygen/html/de-CH_8h.html | 0 .../docs/doxygen/html/de-CH_8h_source.html | 0 .../docs/doxygen/html/de-DE_8h.html | 0 .../docs/doxygen/html/de-DE_8h_source.html | 0 .../docs/doxygen/html/defaults_8h.html | 0 .../docs/doxygen/html/defaults_8h_source.html | 0 .../docs/doxygen/html/deprecated.html | 0 .../dir_49e56c817e5e54854c35e136979f97ca.html | 0 .../dir_68267d1309a1af8e8297ef4c3efbcdba.html | 0 .../dir_84fe998d1eb06414cc389ad334e77e63.html | 0 .../docs/doxygen/html/doc.png | Bin .../docs/doxygen/html/doxygen.css | 0 .../docs/doxygen/html/doxygen.png | Bin .../docs/doxygen/html/doxygen__index_8md.html | 0 .../docs/doxygen/html/dynsections.js | 0 .../docs/doxygen/html/en-AU_8h.html | 0 .../docs/doxygen/html/en-AU_8h_source.html | 0 .../docs/doxygen/html/en-IE_8h.html | 0 .../docs/doxygen/html/en-IE_8h_source.html | 0 .../docs/doxygen/html/en-UK_8h.html | 0 .../docs/doxygen/html/en-UK_8h_source.html | 0 .../docs/doxygen/html/en-US_8h.html | 0 .../docs/doxygen/html/en-US_8h_source.html | 0 .../docs/doxygen/html/es-ES_8h.html | 0 .../docs/doxygen/html/es-ES_8h_source.html | 0 .../docs/doxygen/html/files.html | 0 .../docs/doxygen/html/folderclosed.png | Bin .../docs/doxygen/html/folderopen.png | Bin .../docs/doxygen/html/fr-FR_8h.html | 0 .../docs/doxygen/html/fr-FR_8h_source.html | 0 .../docs/doxygen/html/functions.html | 0 .../docs/doxygen/html/functions_a.html | 0 .../docs/doxygen/html/functions_b.html | 0 .../docs/doxygen/html/functions_c.html | 0 .../docs/doxygen/html/functions_d.html | 0 .../docs/doxygen/html/functions_e.html | 0 .../docs/doxygen/html/functions_f.html | 0 .../docs/doxygen/html/functions_func.html | 0 .../docs/doxygen/html/functions_func_a.html | 0 .../docs/doxygen/html/functions_func_b.html | 0 .../docs/doxygen/html/functions_func_c.html | 0 .../docs/doxygen/html/functions_func_d.html | 0 .../docs/doxygen/html/functions_func_e.html | 0 .../docs/doxygen/html/functions_func_f.html | 0 .../docs/doxygen/html/functions_func_g.html | 0 .../docs/doxygen/html/functions_func_h.html | 0 .../docs/doxygen/html/functions_func_i.html | 0 .../docs/doxygen/html/functions_func_k.html | 0 .../docs/doxygen/html/functions_func_l.html | 0 .../docs/doxygen/html/functions_func_m.html | 0 .../docs/doxygen/html/functions_func_n.html | 0 .../docs/doxygen/html/functions_func_o.html | 0 .../docs/doxygen/html/functions_func_p.html | 0 .../docs/doxygen/html/functions_func_r.html | 0 .../docs/doxygen/html/functions_func_s.html | 0 .../docs/doxygen/html/functions_func_t.html | 0 .../docs/doxygen/html/functions_func_u.html | 0 .../docs/doxygen/html/functions_func_v.html | 0 .../docs/doxygen/html/functions_func_w.html | 0 .../docs/doxygen/html/functions_func_~.html | 0 .../docs/doxygen/html/functions_g.html | 0 .../docs/doxygen/html/functions_h.html | 0 .../docs/doxygen/html/functions_i.html | 0 .../docs/doxygen/html/functions_k.html | 0 .../docs/doxygen/html/functions_l.html | 0 .../docs/doxygen/html/functions_m.html | 0 .../docs/doxygen/html/functions_n.html | 0 .../docs/doxygen/html/functions_o.html | 0 .../docs/doxygen/html/functions_p.html | 0 .../docs/doxygen/html/functions_q.html | 0 .../docs/doxygen/html/functions_r.html | 0 .../docs/doxygen/html/functions_rela.html | 0 .../docs/doxygen/html/functions_s.html | 0 .../docs/doxygen/html/functions_t.html | 0 .../docs/doxygen/html/functions_u.html | 0 .../docs/doxygen/html/functions_v.html | 0 .../docs/doxygen/html/functions_vars.html | 0 .../docs/doxygen/html/functions_vars_a.html | 0 .../docs/doxygen/html/functions_vars_b.html | 0 .../docs/doxygen/html/functions_vars_c.html | 0 .../docs/doxygen/html/functions_vars_d.html | 0 .../docs/doxygen/html/functions_vars_e.html | 0 .../docs/doxygen/html/functions_vars_f.html | 0 .../docs/doxygen/html/functions_vars_h.html | 0 .../docs/doxygen/html/functions_vars_i.html | 0 .../docs/doxygen/html/functions_vars_l.html | 0 .../docs/doxygen/html/functions_vars_m.html | 0 .../docs/doxygen/html/functions_vars_n.html | 0 .../docs/doxygen/html/functions_vars_o.html | 0 .../docs/doxygen/html/functions_vars_p.html | 0 .../docs/doxygen/html/functions_vars_q.html | 0 .../docs/doxygen/html/functions_vars_r.html | 0 .../docs/doxygen/html/functions_vars_s.html | 0 .../docs/doxygen/html/functions_vars_t.html | 0 .../docs/doxygen/html/functions_vars_u.html | 0 .../docs/doxygen/html/functions_vars_v.html | 0 .../docs/doxygen/html/functions_vars_w.html | 0 .../docs/doxygen/html/functions_vars_z.html | 0 .../docs/doxygen/html/functions_w.html | 0 .../docs/doxygen/html/functions_z.html | 0 .../docs/doxygen/html/functions_~.html | 0 .../docs/doxygen/html/globals.html | 0 .../docs/doxygen/html/globals_a.html | 0 .../docs/doxygen/html/globals_c.html | 0 .../docs/doxygen/html/globals_d.html | 0 .../docs/doxygen/html/globals_e.html | 0 .../docs/doxygen/html/globals_enum.html | 0 .../docs/doxygen/html/globals_eval.html | 0 .../docs/doxygen/html/globals_f.html | 0 .../docs/doxygen/html/globals_func.html | 0 .../docs/doxygen/html/globals_g.html | 0 .../docs/doxygen/html/globals_h.html | 0 .../docs/doxygen/html/globals_i.html | 0 .../docs/doxygen/html/globals_j.html | 0 .../docs/doxygen/html/globals_k.html | 0 .../docs/doxygen/html/globals_l.html | 0 .../docs/doxygen/html/globals_m.html | 0 .../docs/doxygen/html/globals_n.html | 0 .../docs/doxygen/html/globals_p.html | 0 .../docs/doxygen/html/globals_r.html | 0 .../docs/doxygen/html/globals_s.html | 0 .../docs/doxygen/html/globals_t.html | 0 .../docs/doxygen/html/globals_type.html | 0 .../docs/doxygen/html/globals_u.html | 0 .../docs/doxygen/html/globals_v.html | 0 .../docs/doxygen/html/globals_vars.html | 0 .../docs/doxygen/html/globals_vars_i.html | 0 .../docs/doxygen/html/globals_vars_k.html | 0 .../docs/doxygen/html/globals_w.html | 0 .../docs/doxygen/html/globals_x.html | 0 .../docs/doxygen/html/globals_y.html | 0 .../docs/doxygen/html/globals_z.html | 0 .../docs/doxygen/html/graph_legend.html | 0 .../docs/doxygen/html/graph_legend.md5 | 0 .../docs/doxygen/html/graph_legend.png | Bin .../docs/doxygen/html/hierarchy.html | 0 .../docs/doxygen/html/i18n_8h.html | 0 .../docs/doxygen/html/i18n_8h_source.html | 0 .../docs/doxygen/html/index.html | 0 .../docs/doxygen/html/inherit_graph_0.map | 0 .../docs/doxygen/html/inherit_graph_0.md5 | 0 .../docs/doxygen/html/inherit_graph_0.png | Bin .../docs/doxygen/html/inherit_graph_1.map | 0 .../docs/doxygen/html/inherit_graph_1.md5 | 0 .../docs/doxygen/html/inherit_graph_1.png | Bin .../docs/doxygen/html/inherit_graph_10.map | 0 .../docs/doxygen/html/inherit_graph_10.md5 | 0 .../docs/doxygen/html/inherit_graph_10.png | Bin .../docs/doxygen/html/inherit_graph_11.map | 0 .../docs/doxygen/html/inherit_graph_11.md5 | 0 .../docs/doxygen/html/inherit_graph_11.png | Bin .../docs/doxygen/html/inherit_graph_12.map | 0 .../docs/doxygen/html/inherit_graph_12.md5 | 0 .../docs/doxygen/html/inherit_graph_12.png | Bin .../docs/doxygen/html/inherit_graph_13.map | 0 .../docs/doxygen/html/inherit_graph_13.md5 | 0 .../docs/doxygen/html/inherit_graph_13.png | Bin .../docs/doxygen/html/inherit_graph_14.map | 0 .../docs/doxygen/html/inherit_graph_14.md5 | 0 .../docs/doxygen/html/inherit_graph_14.png | Bin .../docs/doxygen/html/inherit_graph_15.map | 0 .../docs/doxygen/html/inherit_graph_15.md5 | 0 .../docs/doxygen/html/inherit_graph_15.png | Bin .../docs/doxygen/html/inherit_graph_16.map | 0 .../docs/doxygen/html/inherit_graph_16.md5 | 0 .../docs/doxygen/html/inherit_graph_16.png | Bin .../docs/doxygen/html/inherit_graph_17.map | 0 .../docs/doxygen/html/inherit_graph_17.md5 | 0 .../docs/doxygen/html/inherit_graph_17.png | Bin .../docs/doxygen/html/inherit_graph_18.map | 0 .../docs/doxygen/html/inherit_graph_18.md5 | 0 .../docs/doxygen/html/inherit_graph_18.png | Bin .../docs/doxygen/html/inherit_graph_19.map | 0 .../docs/doxygen/html/inherit_graph_19.md5 | 0 .../docs/doxygen/html/inherit_graph_19.png | Bin .../docs/doxygen/html/inherit_graph_2.map | 0 .../docs/doxygen/html/inherit_graph_2.md5 | 0 .../docs/doxygen/html/inherit_graph_2.png | Bin .../docs/doxygen/html/inherit_graph_20.map | 0 .../docs/doxygen/html/inherit_graph_20.md5 | 0 .../docs/doxygen/html/inherit_graph_20.png | Bin .../docs/doxygen/html/inherit_graph_21.map | 0 .../docs/doxygen/html/inherit_graph_21.md5 | 0 .../docs/doxygen/html/inherit_graph_21.png | Bin .../docs/doxygen/html/inherit_graph_22.map | 0 .../docs/doxygen/html/inherit_graph_22.md5 | 0 .../docs/doxygen/html/inherit_graph_22.png | Bin .../docs/doxygen/html/inherit_graph_23.map | 0 .../docs/doxygen/html/inherit_graph_23.md5 | 0 .../docs/doxygen/html/inherit_graph_23.png | Bin .../docs/doxygen/html/inherit_graph_24.map | 0 .../docs/doxygen/html/inherit_graph_24.md5 | 0 .../docs/doxygen/html/inherit_graph_24.png | Bin .../docs/doxygen/html/inherit_graph_25.map | 0 .../docs/doxygen/html/inherit_graph_25.md5 | 0 .../docs/doxygen/html/inherit_graph_25.png | Bin .../docs/doxygen/html/inherit_graph_26.map | 0 .../docs/doxygen/html/inherit_graph_26.md5 | 0 .../docs/doxygen/html/inherit_graph_26.png | Bin .../docs/doxygen/html/inherit_graph_27.map | 0 .../docs/doxygen/html/inherit_graph_27.md5 | 0 .../docs/doxygen/html/inherit_graph_27.png | Bin .../docs/doxygen/html/inherit_graph_28.map | 0 .../docs/doxygen/html/inherit_graph_28.md5 | 0 .../docs/doxygen/html/inherit_graph_28.png | Bin .../docs/doxygen/html/inherit_graph_29.map | 0 .../docs/doxygen/html/inherit_graph_29.md5 | 0 .../docs/doxygen/html/inherit_graph_29.png | Bin .../docs/doxygen/html/inherit_graph_3.map | 0 .../docs/doxygen/html/inherit_graph_3.md5 | 0 .../docs/doxygen/html/inherit_graph_3.png | Bin .../docs/doxygen/html/inherit_graph_30.map | 0 .../docs/doxygen/html/inherit_graph_30.md5 | 0 .../docs/doxygen/html/inherit_graph_30.png | Bin .../docs/doxygen/html/inherit_graph_31.map | 0 .../docs/doxygen/html/inherit_graph_31.md5 | 0 .../docs/doxygen/html/inherit_graph_31.png | Bin .../docs/doxygen/html/inherit_graph_32.map | 0 .../docs/doxygen/html/inherit_graph_32.md5 | 0 .../docs/doxygen/html/inherit_graph_32.png | Bin .../docs/doxygen/html/inherit_graph_33.map | 0 .../docs/doxygen/html/inherit_graph_33.md5 | 0 .../docs/doxygen/html/inherit_graph_33.png | Bin .../docs/doxygen/html/inherit_graph_34.map | 0 .../docs/doxygen/html/inherit_graph_34.md5 | 0 .../docs/doxygen/html/inherit_graph_34.png | Bin .../docs/doxygen/html/inherit_graph_35.map | 0 .../docs/doxygen/html/inherit_graph_35.md5 | 0 .../docs/doxygen/html/inherit_graph_35.png | Bin .../docs/doxygen/html/inherit_graph_36.map | 0 .../docs/doxygen/html/inherit_graph_36.md5 | 0 .../docs/doxygen/html/inherit_graph_36.png | Bin .../docs/doxygen/html/inherit_graph_37.map | 0 .../docs/doxygen/html/inherit_graph_37.md5 | 0 .../docs/doxygen/html/inherit_graph_37.png | Bin .../docs/doxygen/html/inherit_graph_38.map | 0 .../docs/doxygen/html/inherit_graph_38.md5 | 0 .../docs/doxygen/html/inherit_graph_38.png | Bin .../docs/doxygen/html/inherit_graph_39.map | 0 .../docs/doxygen/html/inherit_graph_39.md5 | 0 .../docs/doxygen/html/inherit_graph_39.png | Bin .../docs/doxygen/html/inherit_graph_4.map | 0 .../docs/doxygen/html/inherit_graph_4.md5 | 0 .../docs/doxygen/html/inherit_graph_4.png | Bin .../docs/doxygen/html/inherit_graph_40.map | 0 .../docs/doxygen/html/inherit_graph_40.md5 | 0 .../docs/doxygen/html/inherit_graph_40.png | Bin .../docs/doxygen/html/inherit_graph_41.map | 0 .../docs/doxygen/html/inherit_graph_41.md5 | 0 .../docs/doxygen/html/inherit_graph_41.png | Bin .../docs/doxygen/html/inherit_graph_42.map | 0 .../docs/doxygen/html/inherit_graph_42.md5 | 0 .../docs/doxygen/html/inherit_graph_42.png | Bin .../docs/doxygen/html/inherit_graph_43.map | 0 .../docs/doxygen/html/inherit_graph_43.md5 | 0 .../docs/doxygen/html/inherit_graph_43.png | Bin .../docs/doxygen/html/inherit_graph_44.map | 0 .../docs/doxygen/html/inherit_graph_44.md5 | 0 .../docs/doxygen/html/inherit_graph_44.png | Bin .../docs/doxygen/html/inherit_graph_45.map | 0 .../docs/doxygen/html/inherit_graph_45.md5 | 0 .../docs/doxygen/html/inherit_graph_45.png | Bin .../docs/doxygen/html/inherit_graph_46.map | 0 .../docs/doxygen/html/inherit_graph_46.md5 | 0 .../docs/doxygen/html/inherit_graph_46.png | Bin .../docs/doxygen/html/inherit_graph_47.map | 0 .../docs/doxygen/html/inherit_graph_47.md5 | 0 .../docs/doxygen/html/inherit_graph_47.png | Bin .../docs/doxygen/html/inherit_graph_48.map | 0 .../docs/doxygen/html/inherit_graph_48.md5 | 0 .../docs/doxygen/html/inherit_graph_48.png | Bin .../docs/doxygen/html/inherit_graph_49.map | 0 .../docs/doxygen/html/inherit_graph_49.md5 | 0 .../docs/doxygen/html/inherit_graph_49.png | Bin .../docs/doxygen/html/inherit_graph_5.map | 0 .../docs/doxygen/html/inherit_graph_5.md5 | 0 .../docs/doxygen/html/inherit_graph_5.png | Bin .../docs/doxygen/html/inherit_graph_50.map | 0 .../docs/doxygen/html/inherit_graph_50.md5 | 0 .../docs/doxygen/html/inherit_graph_50.png | Bin .../docs/doxygen/html/inherit_graph_51.map | 0 .../docs/doxygen/html/inherit_graph_51.md5 | 0 .../docs/doxygen/html/inherit_graph_51.png | Bin .../docs/doxygen/html/inherit_graph_6.map | 0 .../docs/doxygen/html/inherit_graph_6.md5 | 0 .../docs/doxygen/html/inherit_graph_6.png | Bin .../docs/doxygen/html/inherit_graph_7.map | 0 .../docs/doxygen/html/inherit_graph_7.md5 | 0 .../docs/doxygen/html/inherit_graph_7.png | Bin .../docs/doxygen/html/inherit_graph_8.map | 0 .../docs/doxygen/html/inherit_graph_8.md5 | 0 .../docs/doxygen/html/inherit_graph_8.png | Bin .../docs/doxygen/html/inherit_graph_9.map | 0 .../docs/doxygen/html/inherit_graph_9.md5 | 0 .../docs/doxygen/html/inherit_graph_9.png | Bin .../docs/doxygen/html/inherits.html | 0 .../docs/doxygen/html/ir__Airwell_8cpp.html | 0 .../docs/doxygen/html/ir__Aiwa_8cpp.html | 0 .../docs/doxygen/html/ir__Amcor_8cpp.html | 0 .../docs/doxygen/html/ir__Amcor_8h.html | 0 .../doxygen/html/ir__Amcor_8h_source.html | 0 .../docs/doxygen/html/ir__Argo_8cpp.html | 0 .../docs/doxygen/html/ir__Argo_8h.html | 0 .../docs/doxygen/html/ir__Argo_8h_source.html | 0 .../docs/doxygen/html/ir__Carrier_8cpp.html | 0 .../docs/doxygen/html/ir__Carrier_8h.html | 0 .../doxygen/html/ir__Carrier_8h_source.html | 0 .../docs/doxygen/html/ir__Coolix_8cpp.html | 0 .../docs/doxygen/html/ir__Coolix_8h.html | 0 .../doxygen/html/ir__Coolix_8h_source.html | 0 .../docs/doxygen/html/ir__Corona_8cpp.html | 0 .../docs/doxygen/html/ir__Corona_8h.html | 0 .../doxygen/html/ir__Corona_8h_source.html | 0 .../docs/doxygen/html/ir__Daikin_8cpp.html | 0 .../docs/doxygen/html/ir__Daikin_8h.html | 0 .../doxygen/html/ir__Daikin_8h_source.html | 0 .../docs/doxygen/html/ir__Delonghi_8cpp.html | 0 .../docs/doxygen/html/ir__Delonghi_8h.html | 0 .../doxygen/html/ir__Delonghi_8h_source.html | 0 .../docs/doxygen/html/ir__Denon_8cpp.html | 0 .../docs/doxygen/html/ir__Dish_8cpp.html | 0 .../docs/doxygen/html/ir__Doshisha_8cpp.html | 0 .../docs/doxygen/html/ir__Electra_8cpp.html | 0 .../docs/doxygen/html/ir__Electra_8h.html | 0 .../doxygen/html/ir__Electra_8h_source.html | 0 .../docs/doxygen/html/ir__Epson_8cpp.html | 0 .../docs/doxygen/html/ir__Fujitsu_8cpp.html | 0 .../docs/doxygen/html/ir__Fujitsu_8h.html | 0 .../doxygen/html/ir__Fujitsu_8h_source.html | 0 .../docs/doxygen/html/ir__GICable_8cpp.html | 0 .../doxygen/html/ir__GlobalCache_8cpp.html | 0 .../doxygen/html/ir__Goodweather_8cpp.html | 0 .../docs/doxygen/html/ir__Goodweather_8h.html | 0 .../html/ir__Goodweather_8h_source.html | 0 .../docs/doxygen/html/ir__Gree_8cpp.html | 0 .../docs/doxygen/html/ir__Gree_8h.html | 0 .../docs/doxygen/html/ir__Gree_8h_source.html | 0 .../docs/doxygen/html/ir__Haier_8cpp.html | 0 .../docs/doxygen/html/ir__Haier_8h.html | 0 .../doxygen/html/ir__Haier_8h_source.html | 0 .../docs/doxygen/html/ir__Hitachi_8cpp.html | 0 .../docs/doxygen/html/ir__Hitachi_8h.html | 0 .../doxygen/html/ir__Hitachi_8h_source.html | 0 .../docs/doxygen/html/ir__Inax_8cpp.html | 0 .../docs/doxygen/html/ir__JVC_8cpp.html | 0 .../doxygen/html/ir__Kelvinator_8cpp.html | 0 .../docs/doxygen/html/ir__Kelvinator_8h.html | 0 .../html/ir__Kelvinator_8h_source.html | 0 .../docs/doxygen/html/ir__LG_8cpp.html | 0 .../docs/doxygen/html/ir__LG_8h.html | 0 .../docs/doxygen/html/ir__LG_8h_source.html | 0 .../docs/doxygen/html/ir__Lasertag_8cpp.html | 0 .../docs/doxygen/html/ir__Lego_8cpp.html | 0 .../docs/doxygen/html/ir__Lutron_8cpp.html | 0 .../docs/doxygen/html/ir__MWM_8cpp.html | 0 .../docs/doxygen/html/ir__Magiquest_8cpp.html | 0 .../docs/doxygen/html/ir__Magiquest_8h.html | 0 .../doxygen/html/ir__Magiquest_8h_source.html | 0 .../docs/doxygen/html/ir__Midea_8cpp.html | 0 .../docs/doxygen/html/ir__Midea_8h.html | 0 .../doxygen/html/ir__Midea_8h_source.html | 0 .../html/ir__MitsubishiHeavy_8cpp.html | 0 .../doxygen/html/ir__MitsubishiHeavy_8h.html | 0 .../html/ir__MitsubishiHeavy_8h_source.html | 0 .../doxygen/html/ir__Mitsubishi_8cpp.html | 0 .../docs/doxygen/html/ir__Mitsubishi_8h.html | 0 .../html/ir__Mitsubishi_8h_source.html | 0 .../doxygen/html/ir__Multibrackets_8cpp.html | 0 .../docs/doxygen/html/ir__NEC_8cpp.html | 0 .../docs/doxygen/html/ir__NEC_8h.html | 0 .../docs/doxygen/html/ir__NEC_8h_source.html | 0 .../docs/doxygen/html/ir__Neoclima_8cpp.html | 0 .../docs/doxygen/html/ir__Neoclima_8h.html | 0 .../doxygen/html/ir__Neoclima_8h_source.html | 0 .../docs/doxygen/html/ir__Nikai_8cpp.html | 0 .../docs/doxygen/html/ir__Panasonic_8cpp.html | 0 .../docs/doxygen/html/ir__Panasonic_8h.html | 0 .../doxygen/html/ir__Panasonic_8h_source.html | 0 .../docs/doxygen/html/ir__Pioneer_8cpp.html | 0 .../docs/doxygen/html/ir__Pronto_8cpp.html | 0 .../docs/doxygen/html/ir__RC5__RC6_8cpp.html | 0 .../docs/doxygen/html/ir__RCMM_8cpp.html | 0 .../docs/doxygen/html/ir__Samsung_8cpp.html | 0 .../docs/doxygen/html/ir__Samsung_8h.html | 0 .../doxygen/html/ir__Samsung_8h_source.html | 0 .../docs/doxygen/html/ir__Sanyo_8cpp.html | 0 .../docs/doxygen/html/ir__Sharp_8cpp.html | 0 .../docs/doxygen/html/ir__Sharp_8h.html | 0 .../doxygen/html/ir__Sharp_8h_source.html | 0 .../docs/doxygen/html/ir__Sherwood_8cpp.html | 0 .../docs/doxygen/html/ir__Sony_8cpp.html | 0 .../docs/doxygen/html/ir__Symphony_8cpp.html | 0 .../docs/doxygen/html/ir__Tcl_8cpp.html | 0 .../docs/doxygen/html/ir__Tcl_8h.html | 0 .../docs/doxygen/html/ir__Tcl_8h_source.html | 0 .../docs/doxygen/html/ir__Teco_8cpp.html | 0 .../docs/doxygen/html/ir__Teco_8h.html | 0 .../docs/doxygen/html/ir__Teco_8h_source.html | 0 .../docs/doxygen/html/ir__Toshiba_8cpp.html | 0 .../docs/doxygen/html/ir__Toshiba_8h.html | 0 .../doxygen/html/ir__Toshiba_8h_source.html | 0 .../docs/doxygen/html/ir__Trotec_8cpp.html | 0 .../docs/doxygen/html/ir__Trotec_8h.html | 0 .../doxygen/html/ir__Trotec_8h_source.html | 0 .../docs/doxygen/html/ir__Vestel_8cpp.html | 0 .../docs/doxygen/html/ir__Vestel_8h.html | 0 .../doxygen/html/ir__Vestel_8h_source.html | 0 .../docs/doxygen/html/ir__Whirlpool_8cpp.html | 0 .../docs/doxygen/html/ir__Whirlpool_8h.html | 0 .../doxygen/html/ir__Whirlpool_8h_source.html | 0 .../docs/doxygen/html/ir__Whynter_8cpp.html | 0 .../docs/doxygen/html/ir__Zepeal_8cpp.html | 0 .../docs/doxygen/html/it-IT_8h.html | 0 .../docs/doxygen/html/it-IT_8h_source.html | 0 .../docs/doxygen/html/jquery.js | 0 .../doxygen/html/md_src_locale_README.html | 0 .../docs/doxygen/html/menu.js | 0 .../docs/doxygen/html/menudata.js | 0 .../docs/doxygen/html/namespaceIRAcUtils.html | 0 .../docs/doxygen/html/namespaceirutils.html | 0 .../docs/doxygen/html/namespacemembers.html | 0 .../doxygen/html/namespacemembers_enum.html | 0 .../doxygen/html/namespacemembers_func.html | 0 .../docs/doxygen/html/namespaces.html | 0 .../docs/doxygen/html/namespacestdAc.html | 0 .../docs/doxygen/html/nav_f.png | Bin .../docs/doxygen/html/nav_g.png | Bin .../docs/doxygen/html/nav_h.png | Bin .../docs/doxygen/html/open.png | Bin .../docs/doxygen/html/pages.html | 0 .../docs/doxygen/html/search/all_0.html | 0 .../docs/doxygen/html/search/all_0.js | 0 .../docs/doxygen/html/search/all_1.html | 0 .../docs/doxygen/html/search/all_1.js | 0 .../docs/doxygen/html/search/all_10.html | 0 .../docs/doxygen/html/search/all_10.js | 0 .../docs/doxygen/html/search/all_11.html | 0 .../docs/doxygen/html/search/all_11.js | 0 .../docs/doxygen/html/search/all_12.html | 0 .../docs/doxygen/html/search/all_12.js | 0 .../docs/doxygen/html/search/all_13.html | 0 .../docs/doxygen/html/search/all_13.js | 0 .../docs/doxygen/html/search/all_14.html | 0 .../docs/doxygen/html/search/all_14.js | 0 .../docs/doxygen/html/search/all_15.html | 0 .../docs/doxygen/html/search/all_15.js | 0 .../docs/doxygen/html/search/all_16.html | 0 .../docs/doxygen/html/search/all_16.js | 0 .../docs/doxygen/html/search/all_17.html | 0 .../docs/doxygen/html/search/all_17.js | 0 .../docs/doxygen/html/search/all_18.html | 0 .../docs/doxygen/html/search/all_18.js | 0 .../docs/doxygen/html/search/all_19.html | 0 .../docs/doxygen/html/search/all_19.js | 0 .../docs/doxygen/html/search/all_1a.html | 0 .../docs/doxygen/html/search/all_1a.js | 0 .../docs/doxygen/html/search/all_1b.html | 0 .../docs/doxygen/html/search/all_1b.js | 0 .../docs/doxygen/html/search/all_2.html | 0 .../docs/doxygen/html/search/all_2.js | 0 .../docs/doxygen/html/search/all_3.html | 0 .../docs/doxygen/html/search/all_3.js | 0 .../docs/doxygen/html/search/all_4.html | 0 .../docs/doxygen/html/search/all_4.js | 0 .../docs/doxygen/html/search/all_5.html | 0 .../docs/doxygen/html/search/all_5.js | 0 .../docs/doxygen/html/search/all_6.html | 0 .../docs/doxygen/html/search/all_6.js | 0 .../docs/doxygen/html/search/all_7.html | 0 .../docs/doxygen/html/search/all_7.js | 0 .../docs/doxygen/html/search/all_8.html | 0 .../docs/doxygen/html/search/all_8.js | 0 .../docs/doxygen/html/search/all_9.html | 0 .../docs/doxygen/html/search/all_9.js | 0 .../docs/doxygen/html/search/all_a.html | 0 .../docs/doxygen/html/search/all_a.js | 0 .../docs/doxygen/html/search/all_b.html | 0 .../docs/doxygen/html/search/all_b.js | 0 .../docs/doxygen/html/search/all_c.html | 0 .../docs/doxygen/html/search/all_c.js | 0 .../docs/doxygen/html/search/all_d.html | 0 .../docs/doxygen/html/search/all_d.js | 0 .../docs/doxygen/html/search/all_e.html | 0 .../docs/doxygen/html/search/all_e.js | 0 .../docs/doxygen/html/search/all_f.html | 0 .../docs/doxygen/html/search/all_f.js | 0 .../docs/doxygen/html/search/classes_0.html | 0 .../docs/doxygen/html/search/classes_0.js | 0 .../docs/doxygen/html/search/classes_1.html | 0 .../docs/doxygen/html/search/classes_1.js | 0 .../docs/doxygen/html/search/classes_2.html | 0 .../docs/doxygen/html/search/classes_2.js | 0 .../docs/doxygen/html/search/classes_3.html | 0 .../docs/doxygen/html/search/classes_3.js | 0 .../docs/doxygen/html/search/classes_4.html | 0 .../docs/doxygen/html/search/classes_4.js | 0 .../docs/doxygen/html/search/close.png | Bin .../docs/doxygen/html/search/enums_0.html | 0 .../docs/doxygen/html/search/enums_0.js | 0 .../docs/doxygen/html/search/enums_1.html | 0 .../docs/doxygen/html/search/enums_1.js | 0 .../docs/doxygen/html/search/enums_2.html | 0 .../docs/doxygen/html/search/enums_2.js | 0 .../docs/doxygen/html/search/enums_3.html | 0 .../docs/doxygen/html/search/enums_3.js | 0 .../docs/doxygen/html/search/enums_4.html | 0 .../docs/doxygen/html/search/enums_4.js | 0 .../docs/doxygen/html/search/enums_5.html | 0 .../docs/doxygen/html/search/enums_5.js | 0 .../docs/doxygen/html/search/enums_6.html | 0 .../docs/doxygen/html/search/enums_6.js | 0 .../docs/doxygen/html/search/enums_7.html | 0 .../docs/doxygen/html/search/enums_7.js | 0 .../docs/doxygen/html/search/enums_8.html | 0 .../docs/doxygen/html/search/enums_8.js | 0 .../doxygen/html/search/enumvalues_0.html | 0 .../docs/doxygen/html/search/enumvalues_0.js | 0 .../doxygen/html/search/enumvalues_1.html | 0 .../docs/doxygen/html/search/enumvalues_1.js | 0 .../doxygen/html/search/enumvalues_10.html | 0 .../docs/doxygen/html/search/enumvalues_10.js | 0 .../doxygen/html/search/enumvalues_11.html | 0 .../docs/doxygen/html/search/enumvalues_11.js | 0 .../doxygen/html/search/enumvalues_12.html | 0 .../docs/doxygen/html/search/enumvalues_12.js | 0 .../doxygen/html/search/enumvalues_13.html | 0 .../docs/doxygen/html/search/enumvalues_13.js | 0 .../doxygen/html/search/enumvalues_14.html | 0 .../docs/doxygen/html/search/enumvalues_14.js | 0 .../doxygen/html/search/enumvalues_15.html | 0 .../docs/doxygen/html/search/enumvalues_15.js | 0 .../doxygen/html/search/enumvalues_2.html | 0 .../docs/doxygen/html/search/enumvalues_2.js | 0 .../doxygen/html/search/enumvalues_3.html | 0 .../docs/doxygen/html/search/enumvalues_3.js | 0 .../doxygen/html/search/enumvalues_4.html | 0 .../docs/doxygen/html/search/enumvalues_4.js | 0 .../doxygen/html/search/enumvalues_5.html | 0 .../docs/doxygen/html/search/enumvalues_5.js | 0 .../doxygen/html/search/enumvalues_6.html | 0 .../docs/doxygen/html/search/enumvalues_6.js | 0 .../doxygen/html/search/enumvalues_7.html | 0 .../docs/doxygen/html/search/enumvalues_7.js | 0 .../doxygen/html/search/enumvalues_8.html | 0 .../docs/doxygen/html/search/enumvalues_8.js | 0 .../doxygen/html/search/enumvalues_9.html | 0 .../docs/doxygen/html/search/enumvalues_9.js | 0 .../doxygen/html/search/enumvalues_a.html | 0 .../docs/doxygen/html/search/enumvalues_a.js | 0 .../doxygen/html/search/enumvalues_b.html | 0 .../docs/doxygen/html/search/enumvalues_b.js | 0 .../doxygen/html/search/enumvalues_c.html | 0 .../docs/doxygen/html/search/enumvalues_c.js | 0 .../doxygen/html/search/enumvalues_d.html | 0 .../docs/doxygen/html/search/enumvalues_d.js | 0 .../doxygen/html/search/enumvalues_e.html | 0 .../docs/doxygen/html/search/enumvalues_e.js | 0 .../doxygen/html/search/enumvalues_f.html | 0 .../docs/doxygen/html/search/enumvalues_f.js | 0 .../docs/doxygen/html/search/files_0.html | 0 .../docs/doxygen/html/search/files_0.js | 0 .../docs/doxygen/html/search/files_1.html | 0 .../docs/doxygen/html/search/files_1.js | 0 .../docs/doxygen/html/search/files_2.html | 0 .../docs/doxygen/html/search/files_2.js | 0 .../docs/doxygen/html/search/files_3.html | 0 .../docs/doxygen/html/search/files_3.js | 0 .../docs/doxygen/html/search/files_4.html | 0 .../docs/doxygen/html/search/files_4.js | 0 .../docs/doxygen/html/search/files_5.html | 0 .../docs/doxygen/html/search/files_5.js | 0 .../docs/doxygen/html/search/functions_0.html | 0 .../docs/doxygen/html/search/functions_0.js | 0 .../docs/doxygen/html/search/functions_1.html | 0 .../docs/doxygen/html/search/functions_1.js | 0 .../doxygen/html/search/functions_10.html | 0 .../docs/doxygen/html/search/functions_10.js | 0 .../doxygen/html/search/functions_11.html | 0 .../docs/doxygen/html/search/functions_11.js | 0 .../doxygen/html/search/functions_12.html | 0 .../docs/doxygen/html/search/functions_12.js | 0 .../doxygen/html/search/functions_13.html | 0 .../docs/doxygen/html/search/functions_13.js | 0 .../doxygen/html/search/functions_14.html | 0 .../docs/doxygen/html/search/functions_14.js | 0 .../doxygen/html/search/functions_15.html | 0 .../docs/doxygen/html/search/functions_15.js | 0 .../doxygen/html/search/functions_16.html | 0 .../docs/doxygen/html/search/functions_16.js | 0 .../doxygen/html/search/functions_17.html | 0 .../docs/doxygen/html/search/functions_17.js | 0 .../docs/doxygen/html/search/functions_2.html | 0 .../docs/doxygen/html/search/functions_2.js | 0 .../docs/doxygen/html/search/functions_3.html | 0 .../docs/doxygen/html/search/functions_3.js | 0 .../docs/doxygen/html/search/functions_4.html | 0 .../docs/doxygen/html/search/functions_4.js | 0 .../docs/doxygen/html/search/functions_5.html | 0 .../docs/doxygen/html/search/functions_5.js | 0 .../docs/doxygen/html/search/functions_6.html | 0 .../docs/doxygen/html/search/functions_6.js | 0 .../docs/doxygen/html/search/functions_7.html | 0 .../docs/doxygen/html/search/functions_7.js | 0 .../docs/doxygen/html/search/functions_8.html | 0 .../docs/doxygen/html/search/functions_8.js | 0 .../docs/doxygen/html/search/functions_9.html | 0 .../docs/doxygen/html/search/functions_9.js | 0 .../docs/doxygen/html/search/functions_a.html | 0 .../docs/doxygen/html/search/functions_a.js | 0 .../docs/doxygen/html/search/functions_b.html | 0 .../docs/doxygen/html/search/functions_b.js | 0 .../docs/doxygen/html/search/functions_c.html | 0 .../docs/doxygen/html/search/functions_c.js | 0 .../docs/doxygen/html/search/functions_d.html | 0 .../docs/doxygen/html/search/functions_d.js | 0 .../docs/doxygen/html/search/functions_e.html | 0 .../docs/doxygen/html/search/functions_e.js | 0 .../docs/doxygen/html/search/functions_f.html | 0 .../docs/doxygen/html/search/functions_f.js | 0 .../docs/doxygen/html/search/mag_sel.png | Bin .../doxygen/html/search/namespaces_0.html | 0 .../docs/doxygen/html/search/namespaces_0.js | 0 .../doxygen/html/search/namespaces_1.html | 0 .../docs/doxygen/html/search/namespaces_1.js | 0 .../docs/doxygen/html/search/nomatches.html | 0 .../docs/doxygen/html/search/pages_0.html | 0 .../docs/doxygen/html/search/pages_0.js | 0 .../docs/doxygen/html/search/pages_1.html | 0 .../docs/doxygen/html/search/pages_1.js | 0 .../docs/doxygen/html/search/pages_2.html | 0 .../docs/doxygen/html/search/pages_2.js | 0 .../docs/doxygen/html/search/related_0.html | 0 .../docs/doxygen/html/search/related_0.js | 0 .../docs/doxygen/html/search/search.css | 0 .../docs/doxygen/html/search/search.js | 0 .../docs/doxygen/html/search/search_l.png | Bin .../docs/doxygen/html/search/search_m.png | Bin .../docs/doxygen/html/search/search_r.png | Bin .../docs/doxygen/html/search/searchdata.js | 0 .../docs/doxygen/html/search/typedefs_0.html | 0 .../docs/doxygen/html/search/typedefs_0.js | 0 .../docs/doxygen/html/search/variables_0.html | 0 .../docs/doxygen/html/search/variables_0.js | 0 .../docs/doxygen/html/search/variables_1.html | 0 .../docs/doxygen/html/search/variables_1.js | 0 .../doxygen/html/search/variables_10.html | 0 .../docs/doxygen/html/search/variables_10.js | 0 .../doxygen/html/search/variables_11.html | 0 .../docs/doxygen/html/search/variables_11.js | 0 .../doxygen/html/search/variables_12.html | 0 .../docs/doxygen/html/search/variables_12.js | 0 .../doxygen/html/search/variables_13.html | 0 .../docs/doxygen/html/search/variables_13.js | 0 .../doxygen/html/search/variables_14.html | 0 .../docs/doxygen/html/search/variables_14.js | 0 .../doxygen/html/search/variables_15.html | 0 .../docs/doxygen/html/search/variables_15.js | 0 .../doxygen/html/search/variables_16.html | 0 .../docs/doxygen/html/search/variables_16.js | 0 .../docs/doxygen/html/search/variables_2.html | 0 .../docs/doxygen/html/search/variables_2.js | 0 .../docs/doxygen/html/search/variables_3.html | 0 .../docs/doxygen/html/search/variables_3.js | 0 .../docs/doxygen/html/search/variables_4.html | 0 .../docs/doxygen/html/search/variables_4.js | 0 .../docs/doxygen/html/search/variables_5.html | 0 .../docs/doxygen/html/search/variables_5.js | 0 .../docs/doxygen/html/search/variables_6.html | 0 .../docs/doxygen/html/search/variables_6.js | 0 .../docs/doxygen/html/search/variables_7.html | 0 .../docs/doxygen/html/search/variables_7.js | 0 .../docs/doxygen/html/search/variables_8.html | 0 .../docs/doxygen/html/search/variables_8.js | 0 .../docs/doxygen/html/search/variables_9.html | 0 .../docs/doxygen/html/search/variables_9.js | 0 .../docs/doxygen/html/search/variables_a.html | 0 .../docs/doxygen/html/search/variables_a.js | 0 .../docs/doxygen/html/search/variables_b.html | 0 .../docs/doxygen/html/search/variables_b.js | 0 .../docs/doxygen/html/search/variables_c.html | 0 .../docs/doxygen/html/search/variables_c.js | 0 .../docs/doxygen/html/search/variables_d.html | 0 .../docs/doxygen/html/search/variables_d.js | 0 .../docs/doxygen/html/search/variables_e.html | 0 .../docs/doxygen/html/search/variables_e.js | 0 .../docs/doxygen/html/search/variables_f.html | 0 .../docs/doxygen/html/search/variables_f.js | 0 .../docs/doxygen/html/splitbar.png | Bin .../html/structirparams__t-members.html | 0 .../docs/doxygen/html/structirparams__t.html | 0 .../html/structmatch__result__t-members.html | 0 .../doxygen/html/structmatch__result__t.html | 0 .../html/structstdAc_1_1state__t-members.html | 0 .../doxygen/html/structstdAc_1_1state__t.html | 0 .../docs/doxygen/html/sync_off.png | Bin .../docs/doxygen/html/sync_on.png | Bin .../docs/doxygen/html/tab_a.png | Bin .../docs/doxygen/html/tab_b.png | Bin .../docs/doxygen/html/tab_h.png | Bin .../docs/doxygen/html/tab_s.png | Bin .../docs/doxygen/html/tabs.css | 0 .../docs/doxygen/html/todo.html | 0 .../doxygen/html/unionmagiquest-members.html | 0 .../docs/doxygen/html/unionmagiquest.html | 0 .../docs/doxygen/html/zh-CN_8h.html | 0 .../docs/doxygen/html/zh-CN_8h_source.html | 0 .../docs/doxygen_index.md | 0 .../examples/BlynkIrRemote/BlynkIrRemote.ino | 392 +++++++++--------- .../examples/BlynkIrRemote/platformio.ini | 0 .../CommonAcControl/CommonAcControl.ino | 0 .../examples/CommonAcControl/platformio.ini | 0 .../ControlSamsungAC/ControlSamsungAC.ino | 0 .../examples/ControlSamsungAC/platformio.ini | 0 .../DumbIRRepeater/DumbIRRepeater.ino | 0 .../examples/DumbIRRepeater/platformio.ini | 0 .../examples/IRGCSendDemo/IRGCSendDemo.ino | 0 .../examples/IRGCSendDemo/platformio.ini | 0 .../examples/IRGCTCPServer/IRGCTCPServer.ino | 0 .../examples/IRGCTCPServer/platformio.ini | 0 .../examples/IRMQTTServer/IRMQTTServer.h | 0 .../examples/IRMQTTServer/IRMQTTServer.ino | 0 .../examples/IRMQTTServer/platformio.ini | 0 .../examples/IRServer/IRServer.ino | 0 .../examples/IRServer/platformio.ini | 0 .../examples/IRrecvDemo/IRrecvDemo.ino | 0 .../examples/IRrecvDemo/platformio.ini | 0 .../examples/IRrecvDump/IRrecvDump.ino | 0 .../examples/IRrecvDump/platformio.ini | 0 .../examples/IRrecvDumpV2/IRrecvDumpV2.ino | 0 .../examples/IRrecvDumpV2/platformio.ini | 0 .../examples/IRrecvDumpV3/BaseOTA.h | 0 .../examples/IRrecvDumpV3/IRrecvDumpV3.ino | 0 .../examples/IRrecvDumpV3/platformio.ini | 0 .../examples/IRsendDemo/IRsendDemo.ino | 0 .../examples/IRsendDemo/platformio.ini | 0 .../IRsendProntoDemo/IRsendProntoDemo.ino | 0 .../examples/IRsendProntoDemo/platformio.ini | 0 .../JVCPanasonicSendDemo.ino | 0 .../JVCPanasonicSendDemo/platformio.ini | 0 .../examples/LGACSend/LGACSend.ino | 0 .../examples/LGACSend/platformio.ini | 0 .../SmartIRRepeater/SmartIRRepeater.ino | 0 .../examples/SmartIRRepeater/platformio.ini | 0 .../examples/TurnOnArgoAC/TurnOnArgoAC.ino | 0 .../examples/TurnOnArgoAC/platformio.ini | 0 .../TurnOnDaikinAC/TurnOnDaikinAC.ino | 0 .../examples/TurnOnDaikinAC/platformio.ini | 0 .../TurnOnFujitsuAC/TurnOnFujitsuAC.ino | 0 .../examples/TurnOnFujitsuAC/platformio.ini | 0 .../examples/TurnOnGreeAC/TurnOnGreeAC.ino | 154 +++---- .../examples/TurnOnGreeAC/platformio.ini | 0 .../TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino | 0 .../TurnOnKelvinatorAC/platformio.ini | 0 .../TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino | 0 .../TurnOnMitsubishiAC/platformio.ini | 0 .../TurnOnMitsubishiHeavyAc.ino | 0 .../TurnOnMitsubishiHeavyAc/platformio.ini | 0 .../TurnOnPanasonicAC/TurnOnPanasonicAC.ino | 0 .../examples/TurnOnPanasonicAC/platformio.ini | 0 .../TurnOnToshibaAC/TurnOnToshibaAC.ino | 0 .../examples/TurnOnToshibaAC/platformio.ini | 0 .../TurnOnTrotecAC/TurnOnTrotecAC.ino | 0 .../examples/TurnOnTrotecAC/platformio.ini | 0 .../examples/Web-AC-control/README.md | 0 .../Web-AC-control/Web-AC-control.ino | 0 .../examples/Web-AC-control/platformio.ini | 0 .../examples/Web-AC-control/printscreen.png | Bin .../Web-AC-control/upload/favicon.ico | Bin .../Web-AC-control/upload/level_1_off.svg | 0 .../Web-AC-control/upload/level_1_on.svg | 0 .../Web-AC-control/upload/level_2_off.svg | 0 .../Web-AC-control/upload/level_2_on.svg | 0 .../Web-AC-control/upload/level_3_off.svg | 0 .../Web-AC-control/upload/level_3_on.svg | 0 .../Web-AC-control/upload/level_4_off.svg | 0 .../Web-AC-control/upload/level_4_on.svg | 0 .../examples/Web-AC-control/upload/ui.html | 0 .../examples/Web-AC-control/upload/ui.js | 0 .../keywords.txt | 0 .../library.json | 0 .../library.properties | 0 .../platformio.ini | 0 .../pylintrc | 0 .../src/CPPLINT.cfg | 0 .../src/IRac.cpp | 0 .../src/IRac.h | 0 .../src/IRrecv.cpp | 0 .../src/IRrecv.h | 0 .../src/IRremoteESP8266.h | 0 .../src/IRsend.cpp | 0 .../src/IRsend.h | 0 .../src/IRtext.cpp | 0 .../src/IRtext.h | 0 .../src/IRtimer.cpp | 0 .../src/IRtimer.h | 0 .../src/IRutils.cpp | 0 .../src/IRutils.h | 0 .../src/i18n.h | 0 .../src/ir_Airwell.cpp | 0 .../src/ir_Airwell.h | 0 .../src/ir_Aiwa.cpp | 0 .../src/ir_Amcor.cpp | 0 .../src/ir_Amcor.h | 0 .../src/ir_Argo.cpp | 0 .../src/ir_Argo.h | 0 .../src/ir_Carrier.cpp | 0 .../src/ir_Carrier.h | 0 .../src/ir_Coolix.cpp | 0 .../src/ir_Coolix.h | 0 .../src/ir_Corona.cpp | 0 .../src/ir_Corona.h | 0 .../src/ir_Daikin.cpp | 0 .../src/ir_Daikin.h | 0 .../src/ir_Delonghi.cpp | 0 .../src/ir_Delonghi.h | 0 .../src/ir_Denon.cpp | 0 .../src/ir_Dish.cpp | 0 .../src/ir_Doshisha.cpp | 0 .../src/ir_Electra.cpp | 0 .../src/ir_Electra.h | 0 .../src/ir_Epson.cpp | 0 .../src/ir_Fujitsu.cpp | 0 .../src/ir_Fujitsu.h | 0 .../src/ir_GICable.cpp | 0 .../src/ir_GlobalCache.cpp | 0 .../src/ir_Goodweather.cpp | 0 .../src/ir_Goodweather.h | 0 .../src/ir_Gree.cpp | 0 .../src/ir_Gree.h | 0 .../src/ir_Haier.cpp | 0 .../src/ir_Haier.h | 0 .../src/ir_Hitachi.cpp | 0 .../src/ir_Hitachi.h | 0 .../src/ir_Inax.cpp | 0 .../src/ir_JVC.cpp | 0 .../src/ir_Kelvinator.cpp | 0 .../src/ir_Kelvinator.h | 0 .../src/ir_LG.cpp | 0 .../src/ir_LG.h | 0 .../src/ir_Lasertag.cpp | 0 .../src/ir_Lego.cpp | 0 .../src/ir_Lutron.cpp | 0 .../src/ir_MWM.cpp | 0 .../src/ir_Magiquest.cpp | 0 .../src/ir_Magiquest.h | 0 .../src/ir_Midea.cpp | 0 .../src/ir_Midea.h | 0 .../src/ir_Mitsubishi.cpp | 0 .../src/ir_Mitsubishi.h | 0 .../src/ir_MitsubishiHeavy.cpp | 0 .../src/ir_MitsubishiHeavy.h | 0 .../src/ir_Multibrackets.cpp | 0 .../src/ir_NEC.cpp | 0 .../src/ir_NEC.h | 0 .../src/ir_Neoclima.cpp | 0 .../src/ir_Neoclima.h | 0 .../src/ir_Nikai.cpp | 0 .../src/ir_Panasonic.cpp | 0 .../src/ir_Panasonic.h | 0 .../src/ir_Pioneer.cpp | 0 .../src/ir_Pronto.cpp | 0 .../src/ir_RC5_RC6.cpp | 0 .../src/ir_RCMM.cpp | 0 .../src/ir_Samsung.cpp | 0 .../src/ir_Samsung.h | 0 .../src/ir_Sanyo.cpp | 0 .../src/ir_Sanyo.h | 0 .../src/ir_Sharp.cpp | 0 .../src/ir_Sharp.h | 0 .../src/ir_Sherwood.cpp | 0 .../src/ir_Sony.cpp | 0 .../src/ir_Symphony.cpp | 0 .../src/ir_Tcl.cpp | 0 .../src/ir_Tcl.h | 0 .../src/ir_Teco.cpp | 0 .../src/ir_Teco.h | 0 .../src/ir_Toshiba.cpp | 0 .../src/ir_Toshiba.h | 0 .../src/ir_Trotec.cpp | 0 .../src/ir_Trotec.h | 0 .../src/ir_Vestel.cpp | 0 .../src/ir_Vestel.h | 0 .../src/ir_Whirlpool.cpp | 0 .../src/ir_Whirlpool.h | 0 .../src/ir_Whynter.cpp | 0 .../src/ir_Zepeal.cpp | 0 .../src/locale/README.md | 0 .../src/locale/de-CH.h | 0 .../src/locale/de-DE.h | 0 .../src/locale/defaults.h | 0 .../src/locale/en-AU.h | 0 .../src/locale/en-IE.h | 0 .../src/locale/en-UK.h | 0 .../src/locale/en-US.h | 0 .../src/locale/es-ES.h | 0 .../src/locale/fr-FR.h | 0 .../src/locale/it-IT.h | 0 .../src/locale/zh-CN.h | 0 .../test/IRac_test.cpp | 0 .../test/IRrecv_test.cpp | 0 .../test/IRrecv_test.h | 0 .../test/IRsend_test.cpp | 0 .../test/IRsend_test.h | 0 .../test/IRutils_test.cpp | 0 .../test/Makefile | 0 .../test/ir_Airwell_test.cpp | 0 .../test/ir_Aiwa_test.cpp | 0 .../test/ir_Amcor_test.cpp | 0 .../test/ir_Argo_test.cpp | 0 .../test/ir_Carrier_test.cpp | 0 .../test/ir_Coolix_test.cpp | 0 .../test/ir_Corona_test.cpp | 0 .../test/ir_Daikin_test.cpp | 0 .../test/ir_Delonghi_test.cpp | 0 .../test/ir_Denon_test.cpp | 0 .../test/ir_Dish_test.cpp | 0 .../test/ir_Doshisha_test.cpp | 0 .../test/ir_Electra_test.cpp | 0 .../test/ir_Epson_test.cpp | 0 .../test/ir_Fujitsu_test.cpp | 0 .../test/ir_GICable_test.cpp | 0 .../test/ir_GlobalCache_test.cpp | 0 .../test/ir_Goodweather_test.cpp | 0 .../test/ir_Gree_test.cpp | 0 .../test/ir_Haier_test.cpp | 0 .../test/ir_Hitachi_test.cpp | 0 .../test/ir_Inax_test.cpp | 0 .../test/ir_JVC_test.cpp | 0 .../test/ir_Kelvinator_test.cpp | 0 .../test/ir_LG_test.cpp | 0 .../test/ir_Lasertag_test.cpp | 0 .../test/ir_Lego_test.cpp | 0 .../test/ir_Lutron_test.cpp | 0 .../test/ir_MWM_test.cpp | 0 .../test/ir_Magiquest_test.cpp | 0 .../test/ir_Midea_test.cpp | 0 .../test/ir_MitsubishiHeavy_test.cpp | 0 .../test/ir_Mitsubishi_test.cpp | 0 .../test/ir_Multibrackets_test.cpp | 0 .../test/ir_NEC_test.cpp | 0 .../test/ir_Neoclima_test.cpp | 0 .../test/ir_Nikai_test.cpp | 0 .../test/ir_Panasonic_test.cpp | 0 .../test/ir_Pioneer_test.cpp | 0 .../test/ir_Pronto_test.cpp | 0 .../test/ir_RC5_RC6_test.cpp | 0 .../test/ir_RCMM_test.cpp | 0 .../test/ir_Samsung_test.cpp | 0 .../test/ir_Sanyo_test.cpp | 0 .../test/ir_Sharp_test.cpp | 0 .../test/ir_Sherwood_test.cpp | 0 .../test/ir_Sony_test.cpp | 0 .../test/ir_Symphony_test.cpp | 0 .../test/ir_Tcl_test.cpp | 0 .../test/ir_Teco_test.cpp | 0 .../test/ir_Toshiba_test.cpp | 0 .../test/ir_Trotec_test.cpp | 0 .../test/ir_Vestel_test.cpp | 0 .../test/ir_Whirlpool_test.cpp | 0 .../test/ir_Whynter_test.cpp | 0 .../test/ir_Zepeal_test.cpp | 0 .../tools/Makefile | 0 .../tools/RawToGlobalCache.sh | 0 .../tools/auto_analyse_raw_data.py | 0 .../tools/auto_analyse_raw_data_test.py | 0 .../tools/gc_decode.cpp | 0 .../tools/generate_irtext_h.sh | 0 .../tools/mkkeywords | 0 .../tools/mode2_decode.cpp | 0 .../tools/raw_to_pronto_code.py | 0 .../tools/raw_to_pronto_code_test.py | 0 .../tools/scrape_supported_devices.py | 0 tasmota/CHANGELOG.md | 8 +- 1249 files changed, 275 insertions(+), 281 deletions(-) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/CPPLINT.cfg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/Doxyfile (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/LICENSE.txt (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/README.md (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/README_fr.md (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/ReleaseNotes.md (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/SupportedProtocols.md (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/README.md (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/README_fr.md (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/_config.yml (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRac_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRac_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRac_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRrecv_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRrecv_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRrecv_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRremoteESP8266_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRremoteESP8266_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRsend_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRsend_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRsend_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRtext_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRtext_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRtext_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRtimer_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRtimer_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRtimer_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRutils_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRutils_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/IRutils_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/README_8md.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/annotated.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/bc_s.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/bdwn.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRAmcorAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRAmcorAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRAmcorAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRAmcorAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRArgoAC-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRArgoAC.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRArgoAC__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRArgoAC__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRArgoAC__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCarrierAc64-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCarrierAc64.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCarrierAc64__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCarrierAc64__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoolixAC-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoolixAC.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoolixAC__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoolixAC__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoronaAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoronaAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoronaAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRCoronaAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin128-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin128.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin128__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin128__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin128__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin152-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin152.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin152__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin152__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin152__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin160-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin160.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin160__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin160__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin160__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin176-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin176.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin176__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin176__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin176__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin2-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin2.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin216-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin216.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin216__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin216__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin216__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin2__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin2__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin2__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin64-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin64.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin64__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin64__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikin64__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikinESP-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikinESP.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikinESP__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDaikinESP__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDelonghiAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDelonghiAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDelonghiAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRDelonghiAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRElectraAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRElectraAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRElectraAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRElectraAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRElectraAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRFujitsuAC-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRFujitsuAC.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRFujitsuAC__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRFujitsuAC__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGoodweatherAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGoodweatherAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGreeAC-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGreeAC.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGreeAC__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGreeAC__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRGreeAC__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierAC-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierAC.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierACYRW02-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierACYRW02.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierAC__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierAC__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHaierAC__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc1-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc1__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc1__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc3-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc3.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc344-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc344.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc344__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc344__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc344__inherit__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc3__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc3__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc424-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc424.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc424__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc424__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc424__inherit__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRHitachiAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRKelvinatorAC-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRKelvinatorAC.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRLgAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRLgAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRLgAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRLgAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRLgAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMideaAC-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMideaAC.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMideaAC__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMideaAC__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMideaAC__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi112-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi112.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi112__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi112__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi136-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi136.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi136__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishi136__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiAC-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiAC.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRNeoclimaAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRNeoclimaAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRPanasonicAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRPanasonicAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRPanasonicAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRPanasonicAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSamsungAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSamsungAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSamsungAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSamsungAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSharpAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSharpAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSharpAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSharpAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRSharpAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTcl112Ac-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTcl112Ac.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTcl112Ac__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTcl112Ac__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTecoAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTecoAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTecoAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTecoAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTecoAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRToshibaAC-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRToshibaAC.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRToshibaAC__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRToshibaAC__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTrotecESP-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTrotecESP.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTrotecESP__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRTrotecESP__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRVestelAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRVestelAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRVestelAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRVestelAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRVestelAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRWhirlpoolAc-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRWhirlpoolAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRac-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRac.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRac__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRac__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRac__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRrecv-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRrecv.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRrecv__coll__graph.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRrecv__coll__graph.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRrecv__coll__graph.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRsend-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRsend.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRtimer-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classIRtimer.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classTimerMs-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classTimerMs.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classdecode__results-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classdecode__results.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/classes.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/closed.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/de-CH_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/de-CH_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/de-DE_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/de-DE_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/defaults_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/defaults_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/deprecated.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/doc.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/doxygen.css (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/doxygen.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/doxygen__index_8md.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/dynsections.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/en-AU_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/en-AU_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/en-IE_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/en-IE_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/en-UK_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/en-UK_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/en-US_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/en-US_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/es-ES_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/es-ES_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/files.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/folderclosed.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/folderopen.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/fr-FR_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/fr-FR_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_a.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_b.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_c.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_d.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_e.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_f.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_a.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_b.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_c.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_d.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_e.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_f.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_g.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_i.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_k.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_l.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_m.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_n.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_o.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_p.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_r.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_s.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_t.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_u.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_v.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_w.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_func_~.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_g.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_i.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_k.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_l.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_m.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_n.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_o.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_p.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_q.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_r.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_rela.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_s.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_t.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_u.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_v.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_a.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_b.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_c.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_d.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_e.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_f.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_i.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_l.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_m.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_n.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_o.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_p.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_q.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_r.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_s.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_t.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_u.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_v.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_w.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_vars_z.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_w.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_z.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/functions_~.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_a.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_c.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_d.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_e.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_enum.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_eval.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_f.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_func.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_g.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_i.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_j.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_k.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_l.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_m.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_n.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_p.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_r.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_s.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_t.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_type.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_u.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_v.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_vars.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_vars_i.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_vars_k.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_w.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_x.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_y.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/globals_z.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/graph_legend.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/graph_legend.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/graph_legend.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/hierarchy.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/i18n_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/i18n_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/index.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_0.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_0.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_0.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_1.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_1.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_1.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_10.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_10.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_10.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_11.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_11.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_11.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_12.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_12.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_12.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_13.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_13.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_13.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_14.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_14.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_14.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_15.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_15.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_15.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_16.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_16.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_16.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_17.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_17.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_17.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_18.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_18.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_18.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_19.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_19.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_19.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_2.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_2.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_2.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_20.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_20.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_20.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_21.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_21.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_21.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_22.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_22.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_22.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_23.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_23.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_23.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_24.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_24.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_24.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_25.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_25.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_25.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_26.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_26.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_26.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_27.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_27.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_27.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_28.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_28.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_28.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_29.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_29.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_29.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_3.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_3.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_3.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_30.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_30.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_30.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_31.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_31.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_31.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_32.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_32.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_32.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_33.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_33.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_33.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_34.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_34.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_34.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_35.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_35.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_35.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_36.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_36.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_36.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_37.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_37.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_37.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_38.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_38.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_38.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_39.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_39.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_39.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_4.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_4.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_4.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_40.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_40.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_40.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_41.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_41.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_41.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_42.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_42.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_42.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_43.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_43.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_43.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_44.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_44.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_44.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_45.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_45.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_45.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_46.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_46.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_46.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_47.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_47.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_47.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_48.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_48.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_48.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_49.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_49.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_49.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_5.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_5.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_5.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_50.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_50.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_50.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_51.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_51.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_51.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_6.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_6.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_6.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_7.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_7.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_7.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_8.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_8.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_8.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_9.map (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_9.md5 (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherit_graph_9.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/inherits.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Airwell_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Aiwa_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Amcor_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Amcor_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Amcor_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Argo_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Argo_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Argo_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Carrier_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Carrier_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Carrier_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Coolix_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Coolix_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Coolix_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Corona_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Corona_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Corona_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Daikin_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Daikin_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Daikin_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Delonghi_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Delonghi_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Delonghi_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Denon_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Dish_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Doshisha_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Electra_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Electra_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Electra_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Epson_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Fujitsu_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Fujitsu_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Fujitsu_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__GICable_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__GlobalCache_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Goodweather_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Goodweather_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Goodweather_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Gree_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Gree_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Gree_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Haier_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Haier_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Haier_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Hitachi_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Hitachi_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Hitachi_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Inax_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__JVC_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Kelvinator_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Kelvinator_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Kelvinator_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__LG_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__LG_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__LG_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Lasertag_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Lego_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Lutron_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__MWM_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Magiquest_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Magiquest_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Magiquest_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Midea_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Midea_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Midea_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__MitsubishiHeavy_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Mitsubishi_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Mitsubishi_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Mitsubishi_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Multibrackets_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__NEC_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__NEC_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__NEC_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Neoclima_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Neoclima_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Neoclima_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Nikai_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Panasonic_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Panasonic_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Panasonic_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Pioneer_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Pronto_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__RC5__RC6_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__RCMM_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Samsung_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Samsung_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Samsung_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Sanyo_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Sharp_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Sharp_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Sharp_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Sherwood_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Sony_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Symphony_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Tcl_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Tcl_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Tcl_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Teco_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Teco_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Teco_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Toshiba_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Toshiba_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Toshiba_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Trotec_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Trotec_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Trotec_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Vestel_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Vestel_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Vestel_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Whirlpool_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Whirlpool_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Whirlpool_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Whynter_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/ir__Zepeal_8cpp.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/it-IT_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/it-IT_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/jquery.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/md_src_locale_README.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/menu.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/menudata.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/namespaceIRAcUtils.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/namespaceirutils.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/namespacemembers.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/namespacemembers_enum.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/namespacemembers_func.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/namespaces.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/namespacestdAc.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/nav_f.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/nav_g.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/nav_h.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/open.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/pages.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_1.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_10.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_10.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_11.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_11.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_12.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_12.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_13.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_13.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_14.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_14.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_15.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_15.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_16.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_16.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_17.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_17.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_18.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_18.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_19.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_19.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_1a.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_1a.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_1b.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_1b.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_2.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_2.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_3.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_3.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_4.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_4.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_5.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_5.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_6.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_6.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_7.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_7.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_8.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_8.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_9.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_9.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_a.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_a.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_b.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_b.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_c.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_c.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_d.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_d.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_e.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_e.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_f.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/all_f.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_1.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_2.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_2.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_3.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_3.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_4.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/classes_4.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/close.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_1.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_2.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_2.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_3.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_3.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_4.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_4.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_5.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_5.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_6.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_6.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_7.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_7.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_8.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enums_8.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_1.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_10.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_10.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_11.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_11.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_12.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_12.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_13.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_13.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_14.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_14.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_15.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_15.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_2.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_2.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_3.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_3.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_4.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_4.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_5.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_5.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_6.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_6.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_7.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_7.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_8.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_8.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_9.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_9.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_a.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_a.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_b.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_b.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_c.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_c.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_d.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_d.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_e.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_e.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_f.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/enumvalues_f.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_1.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_2.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_2.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_3.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_3.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_4.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_4.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_5.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/files_5.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_1.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_10.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_10.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_11.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_11.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_12.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_12.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_13.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_13.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_14.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_14.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_15.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_15.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_16.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_16.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_17.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_17.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_2.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_2.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_3.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_3.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_4.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_4.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_5.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_5.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_6.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_6.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_7.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_7.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_8.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_8.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_9.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_9.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_a.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_a.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_b.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_b.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_c.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_c.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_d.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_d.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_e.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_e.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_f.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/functions_f.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/mag_sel.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/namespaces_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/namespaces_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/namespaces_1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/namespaces_1.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/nomatches.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/pages_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/pages_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/pages_1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/pages_1.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/pages_2.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/pages_2.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/related_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/related_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/search.css (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/search.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/search_l.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/search_m.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/search_r.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/searchdata.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/typedefs_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/typedefs_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_0.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_0.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_1.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_1.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_10.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_10.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_11.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_11.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_12.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_12.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_13.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_13.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_14.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_14.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_15.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_15.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_16.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_16.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_2.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_2.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_3.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_3.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_4.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_4.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_5.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_5.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_6.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_6.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_7.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_7.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_8.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_8.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_9.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_9.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_a.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_a.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_b.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_b.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_c.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_c.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_d.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_d.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_e.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_e.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_f.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/search/variables_f.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/splitbar.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/structirparams__t-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/structirparams__t.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/structmatch__result__t-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/structmatch__result__t.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/structstdAc_1_1state__t-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/structstdAc_1_1state__t.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/sync_off.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/sync_on.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/tab_a.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/tab_b.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/tab_h.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/tab_s.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/tabs.css (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/todo.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/unionmagiquest-members.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/unionmagiquest.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/zh-CN_8h.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen/html/zh-CN_8h_source.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/docs/doxygen_index.md (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/BlynkIrRemote/BlynkIrRemote.ino (97%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/BlynkIrRemote/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/CommonAcControl/CommonAcControl.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/CommonAcControl/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/ControlSamsungAC/ControlSamsungAC.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/ControlSamsungAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/DumbIRRepeater/DumbIRRepeater.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/DumbIRRepeater/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRGCSendDemo/IRGCSendDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRGCSendDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRGCTCPServer/IRGCTCPServer.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRGCTCPServer/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRMQTTServer/IRMQTTServer.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRMQTTServer/IRMQTTServer.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRMQTTServer/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRServer/IRServer.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRServer/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRrecvDemo/IRrecvDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRrecvDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRrecvDump/IRrecvDump.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRrecvDump/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRrecvDumpV2/IRrecvDumpV2.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRrecvDumpV2/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRrecvDumpV3/BaseOTA.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRrecvDumpV3/IRrecvDumpV3.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRrecvDumpV3/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRsendDemo/IRsendDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRsendDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRsendProntoDemo/IRsendProntoDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/IRsendProntoDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/JVCPanasonicSendDemo/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/LGACSend/LGACSend.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/LGACSend/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/SmartIRRepeater/SmartIRRepeater.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/SmartIRRepeater/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnArgoAC/TurnOnArgoAC.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnArgoAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnDaikinAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnFujitsuAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnGreeAC/TurnOnGreeAC.ino (97%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnGreeAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnKelvinatorAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnMitsubishiAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnMitsubishiHeavyAc/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnPanasonicAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnToshibaAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/TurnOnTrotecAC/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/README.md (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/Web-AC-control.ino (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/printscreen.png (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/favicon.ico (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/level_1_off.svg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/level_1_on.svg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/level_2_off.svg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/level_2_on.svg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/level_3_off.svg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/level_3_on.svg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/level_4_off.svg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/level_4_on.svg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/ui.html (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/examples/Web-AC-control/upload/ui.js (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/keywords.txt (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/library.json (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/library.properties (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/platformio.ini (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/pylintrc (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/CPPLINT.cfg (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRac.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRac.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRrecv.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRrecv.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRremoteESP8266.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRsend.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRsend.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRtext.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRtext.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRtimer.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRtimer.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRutils.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/IRutils.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/i18n.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Airwell.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Airwell.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Aiwa.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Amcor.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Amcor.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Argo.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Argo.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Carrier.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Carrier.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Coolix.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Coolix.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Corona.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Corona.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Daikin.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Daikin.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Delonghi.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Delonghi.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Denon.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Dish.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Doshisha.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Electra.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Electra.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Epson.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Fujitsu.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Fujitsu.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_GICable.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_GlobalCache.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Goodweather.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Goodweather.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Gree.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Gree.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Haier.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Haier.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Hitachi.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Hitachi.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Inax.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_JVC.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Kelvinator.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Kelvinator.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_LG.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_LG.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Lasertag.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Lego.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Lutron.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_MWM.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Magiquest.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Magiquest.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Midea.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Midea.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Mitsubishi.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Mitsubishi.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_MitsubishiHeavy.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_MitsubishiHeavy.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Multibrackets.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_NEC.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_NEC.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Neoclima.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Neoclima.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Nikai.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Panasonic.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Panasonic.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Pioneer.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Pronto.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_RC5_RC6.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_RCMM.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Samsung.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Samsung.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Sanyo.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Sanyo.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Sharp.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Sharp.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Sherwood.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Sony.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Symphony.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Tcl.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Tcl.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Teco.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Teco.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Toshiba.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Toshiba.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Trotec.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Trotec.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Vestel.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Vestel.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Whirlpool.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Whirlpool.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Whynter.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/ir_Zepeal.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/README.md (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/de-CH.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/de-DE.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/defaults.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/en-AU.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/en-IE.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/en-UK.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/en-US.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/es-ES.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/fr-FR.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/it-IT.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/src/locale/zh-CN.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/IRac_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/IRrecv_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/IRrecv_test.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/IRsend_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/IRsend_test.h (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/IRutils_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/Makefile (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Airwell_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Aiwa_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Amcor_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Argo_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Carrier_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Coolix_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Corona_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Daikin_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Delonghi_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Denon_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Dish_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Doshisha_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Electra_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Epson_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Fujitsu_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_GICable_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_GlobalCache_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Goodweather_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Gree_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Haier_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Hitachi_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Inax_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_JVC_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Kelvinator_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_LG_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Lasertag_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Lego_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Lutron_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_MWM_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Magiquest_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Midea_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_MitsubishiHeavy_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Mitsubishi_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Multibrackets_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_NEC_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Neoclima_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Nikai_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Panasonic_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Pioneer_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Pronto_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_RC5_RC6_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_RCMM_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Samsung_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Sanyo_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Sharp_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Sherwood_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Sony_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Symphony_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Tcl_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Teco_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Toshiba_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Trotec_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Vestel_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Whirlpool_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Whynter_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/test/ir_Zepeal_test.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/Makefile (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/RawToGlobalCache.sh (100%) mode change 100755 => 100644 rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/auto_analyse_raw_data.py (100%) mode change 100755 => 100644 rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/auto_analyse_raw_data_test.py (100%) mode change 100755 => 100644 rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/gc_decode.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/generate_irtext_h.sh (100%) mode change 100755 => 100644 rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/mkkeywords (100%) mode change 100755 => 100644 rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/mode2_decode.cpp (100%) rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/raw_to_pronto_code.py (100%) mode change 100755 => 100644 rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/raw_to_pronto_code_test.py (100%) mode change 100755 => 100644 rename lib/{IRremoteESP8266-2.7.8 => IRremoteESP8266-2.7.8.10}/tools/scrape_supported_devices.py (100%) mode change 100755 => 100644 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index bc9abff0c..565f9fc53 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -57,7 +57,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Remove Arduino ESP8266 Core support for versions before 2.7.1 - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE -- Change IRremoteESP8266 library from v2.7.6 to v2.7.8 +- Change IRRemoteESP8266 library from v2.7.6 to v2.7.8.10, fixing Samsung and Pioneer protocols (#8938) - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` diff --git a/lib/IRremoteESP8266-2.7.8/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.8.10/CPPLINT.cfg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/CPPLINT.cfg rename to lib/IRremoteESP8266-2.7.8.10/CPPLINT.cfg diff --git a/lib/IRremoteESP8266-2.7.8/Doxyfile b/lib/IRremoteESP8266-2.7.8.10/Doxyfile similarity index 100% rename from lib/IRremoteESP8266-2.7.8/Doxyfile rename to lib/IRremoteESP8266-2.7.8.10/Doxyfile diff --git a/lib/IRremoteESP8266-2.7.8/LICENSE.txt b/lib/IRremoteESP8266-2.7.8.10/LICENSE.txt similarity index 100% rename from lib/IRremoteESP8266-2.7.8/LICENSE.txt rename to lib/IRremoteESP8266-2.7.8.10/LICENSE.txt diff --git a/lib/IRremoteESP8266-2.7.8/README.md b/lib/IRremoteESP8266-2.7.8.10/README.md similarity index 100% rename from lib/IRremoteESP8266-2.7.8/README.md rename to lib/IRremoteESP8266-2.7.8.10/README.md diff --git a/lib/IRremoteESP8266-2.7.8/README_fr.md b/lib/IRremoteESP8266-2.7.8.10/README_fr.md similarity index 100% rename from lib/IRremoteESP8266-2.7.8/README_fr.md rename to lib/IRremoteESP8266-2.7.8.10/README_fr.md diff --git a/lib/IRremoteESP8266-2.7.8/ReleaseNotes.md b/lib/IRremoteESP8266-2.7.8.10/ReleaseNotes.md similarity index 100% rename from lib/IRremoteESP8266-2.7.8/ReleaseNotes.md rename to lib/IRremoteESP8266-2.7.8.10/ReleaseNotes.md diff --git a/lib/IRremoteESP8266-2.7.8/SupportedProtocols.md b/lib/IRremoteESP8266-2.7.8.10/SupportedProtocols.md similarity index 100% rename from lib/IRremoteESP8266-2.7.8/SupportedProtocols.md rename to lib/IRremoteESP8266-2.7.8.10/SupportedProtocols.md diff --git a/lib/IRremoteESP8266-2.7.8/docs/README.md b/lib/IRremoteESP8266-2.7.8.10/docs/README.md similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/README.md rename to lib/IRremoteESP8266-2.7.8.10/docs/README.md diff --git a/lib/IRremoteESP8266-2.7.8/docs/README_fr.md b/lib/IRremoteESP8266-2.7.8.10/docs/README_fr.md similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/README_fr.md rename to lib/IRremoteESP8266-2.7.8.10/docs/README_fr.md diff --git a/lib/IRremoteESP8266-2.7.8/docs/_config.yml b/lib/IRremoteESP8266-2.7.8.10/docs/_config.yml similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/_config.yml rename to lib/IRremoteESP8266-2.7.8.10/docs/_config.yml diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRac_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRac_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRac_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRac_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRac_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRac_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRrecv_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRrecv_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRrecv_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRrecv_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRrecv_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRrecv_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRremoteESP8266_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRremoteESP8266_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRremoteESP8266_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRremoteESP8266_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRsend_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRsend_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRsend_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRsend_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRsend_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRsend_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtext_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtext_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtext_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtext_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtext_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtext_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtimer_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtimer_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtimer_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtimer_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtimer_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRtimer_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRutils_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRutils_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRutils_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRutils_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRutils_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/IRutils_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/README_8md.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/README_8md.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/README_8md.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/README_8md.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/annotated.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/annotated.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/annotated.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/annotated.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bc_s.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/bc_s.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bc_s.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/bc_s.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bdwn.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/bdwn.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bdwn.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/bdwn.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRAmcorAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRArgoAC__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCarrierAc64__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoolixAC__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRCoronaAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin128__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin152__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin160__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin176__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin216__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin2__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikin64__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDaikinESP__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRDelonghiAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRElectraAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRFujitsuAC__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRGreeAC__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHaierAC__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc1__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__inherit__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__inherit__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc3__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__inherit__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__inherit__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRHitachiAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRLgAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMideaAC__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi112__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishi136__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRPanasonicAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSamsungAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRSharpAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTcl112Ac__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTecoAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRToshibaAC__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRTrotecESP__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRVestelAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRac__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv__coll__graph.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv__coll__graph.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv__coll__graph.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv__coll__graph.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv__coll__graph.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRrecv__coll__graph.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRsend-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRsend-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRsend.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRsend.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRtimer-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRtimer-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRtimer.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classIRtimer.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classTimerMs-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classTimerMs-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classTimerMs.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classTimerMs.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classdecode__results-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classdecode__results-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classdecode__results.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classdecode__results.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classes.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classes.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classes.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/classes.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/closed.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/closed.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/closed.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/closed.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/de-CH_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/de-CH_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/de-CH_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/de-CH_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/de-DE_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/de-DE_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/de-DE_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/de-DE_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/defaults_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/defaults_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/defaults_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/defaults_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/deprecated.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/deprecated.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/deprecated.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/deprecated.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doc.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/doc.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doc.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/doc.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.css b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/doxygen.css similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.css rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/doxygen.css diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/doxygen.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/doxygen.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen__index_8md.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/doxygen__index_8md.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen__index_8md.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/doxygen__index_8md.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dynsections.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/dynsections.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dynsections.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/dynsections.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-AU_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-AU_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-AU_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-AU_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-IE_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-IE_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-IE_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-IE_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-UK_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-UK_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-UK_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-UK_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-US_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-US_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-US_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/en-US_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/es-ES_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/es-ES_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/es-ES_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/es-ES_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/files.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/files.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/files.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/files.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderclosed.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/folderclosed.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderclosed.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/folderclosed.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderopen.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/folderopen.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderopen.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/folderopen.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/fr-FR_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/fr-FR_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/fr-FR_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/fr-FR_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_a.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_a.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_a.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_a.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_b.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_b.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_b.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_b.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_c.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_c.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_c.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_c.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_d.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_d.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_d.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_d.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_e.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_e.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_e.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_e.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_f.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_f.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_f.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_f.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_a.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_a.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_a.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_a.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_b.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_b.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_b.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_b.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_c.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_c.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_c.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_c.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_d.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_d.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_d.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_d.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_e.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_e.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_e.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_e.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_f.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_f.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_f.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_f.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_g.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_g.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_g.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_g.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_i.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_i.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_i.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_i.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_k.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_k.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_k.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_k.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_l.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_l.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_l.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_l.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_m.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_m.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_m.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_m.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_n.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_n.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_n.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_n.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_o.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_o.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_o.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_o.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_p.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_p.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_p.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_p.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_r.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_r.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_r.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_r.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_s.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_s.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_s.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_s.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_t.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_t.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_t.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_t.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_u.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_u.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_u.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_u.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_v.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_v.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_v.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_v.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_w.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_w.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_w.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_w.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_~.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_~.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_~.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_func_~.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_g.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_g.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_g.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_g.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_i.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_i.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_i.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_i.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_k.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_k.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_k.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_k.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_l.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_l.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_l.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_l.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_m.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_m.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_m.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_m.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_n.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_n.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_n.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_n.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_o.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_o.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_o.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_o.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_p.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_p.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_p.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_p.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_q.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_q.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_q.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_q.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_r.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_r.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_r.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_r.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_rela.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_rela.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_rela.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_rela.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_s.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_s.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_s.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_s.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_t.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_t.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_t.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_t.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_u.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_u.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_u.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_u.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_v.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_v.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_v.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_v.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_a.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_a.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_a.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_a.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_b.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_b.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_b.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_b.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_c.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_c.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_c.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_c.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_d.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_d.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_d.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_d.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_e.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_e.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_e.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_e.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_f.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_f.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_f.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_f.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_i.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_i.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_i.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_i.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_l.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_l.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_l.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_l.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_m.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_m.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_m.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_m.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_n.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_n.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_n.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_n.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_o.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_o.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_o.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_o.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_p.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_p.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_p.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_p.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_q.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_q.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_q.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_q.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_r.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_r.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_r.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_r.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_s.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_s.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_s.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_s.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_t.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_t.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_t.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_t.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_u.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_u.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_u.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_u.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_v.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_v.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_v.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_v.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_w.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_w.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_w.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_w.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_z.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_z.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_z.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_vars_z.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_w.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_w.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_w.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_w.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_z.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_z.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_z.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_z.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_~.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_~.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_~.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/functions_~.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_a.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_a.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_a.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_a.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_c.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_c.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_c.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_c.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_d.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_d.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_d.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_d.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_e.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_e.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_e.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_e.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_enum.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_enum.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_enum.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_enum.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_eval.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_eval.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_eval.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_eval.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_f.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_f.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_f.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_f.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_func.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_func.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_func.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_func.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_g.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_g.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_g.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_g.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_i.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_i.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_i.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_i.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_j.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_j.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_j.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_j.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_k.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_k.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_k.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_k.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_l.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_l.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_l.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_l.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_m.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_m.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_m.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_m.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_n.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_n.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_n.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_n.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_p.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_p.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_p.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_p.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_r.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_r.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_r.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_r.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_s.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_s.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_s.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_s.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_t.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_t.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_t.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_t.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_type.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_type.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_type.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_type.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_u.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_u.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_u.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_u.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_v.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_v.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_v.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_v.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_vars.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_vars.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_i.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_vars_i.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_i.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_vars_i.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_k.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_vars_k.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_k.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_vars_k.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_w.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_w.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_w.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_w.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_x.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_x.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_x.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_x.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_y.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_y.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_y.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_y.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_z.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_z.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_z.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/globals_z.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/graph_legend.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/graph_legend.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/graph_legend.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/graph_legend.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/graph_legend.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/graph_legend.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/hierarchy.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/hierarchy.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/hierarchy.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/hierarchy.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/i18n_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/i18n_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/i18n_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/i18n_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/index.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/index.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/index.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/index.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_0.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_0.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_0.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_0.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_0.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_0.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_1.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_1.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_1.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_1.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_1.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_1.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_10.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_10.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_10.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_10.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_10.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_10.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_11.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_11.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_11.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_11.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_11.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_11.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_12.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_12.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_12.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_12.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_12.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_12.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_13.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_13.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_13.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_13.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_13.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_13.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_14.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_14.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_14.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_14.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_14.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_14.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_15.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_15.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_15.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_15.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_15.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_15.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_16.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_16.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_16.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_16.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_16.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_16.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_17.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_17.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_17.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_17.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_17.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_17.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_18.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_18.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_18.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_18.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_18.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_18.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_19.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_19.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_19.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_19.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_19.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_19.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_2.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_2.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_2.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_2.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_2.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_2.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_20.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_20.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_20.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_20.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_20.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_20.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_21.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_21.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_21.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_21.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_21.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_21.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_22.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_22.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_22.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_22.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_22.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_22.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_23.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_23.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_23.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_23.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_23.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_23.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_24.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_24.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_24.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_24.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_24.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_24.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_25.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_25.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_25.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_25.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_25.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_25.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_26.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_26.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_26.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_26.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_26.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_26.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_27.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_27.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_27.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_27.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_27.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_27.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_28.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_28.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_28.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_28.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_28.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_28.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_29.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_29.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_29.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_29.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_29.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_29.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_3.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_3.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_3.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_3.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_3.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_3.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_30.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_30.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_30.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_30.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_30.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_30.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_31.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_31.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_31.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_31.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_31.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_31.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_32.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_32.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_32.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_32.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_32.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_32.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_33.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_33.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_33.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_33.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_33.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_33.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_34.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_34.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_34.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_34.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_34.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_34.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_35.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_35.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_35.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_35.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_35.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_35.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_36.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_36.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_36.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_36.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_36.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_36.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_37.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_37.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_37.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_37.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_37.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_37.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_38.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_38.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_38.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_38.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_38.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_38.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_39.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_39.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_39.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_39.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_39.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_39.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_4.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_4.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_4.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_4.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_4.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_4.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_40.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_40.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_40.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_40.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_40.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_40.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_41.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_41.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_41.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_41.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_41.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_41.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_42.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_42.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_42.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_42.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_42.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_42.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_43.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_43.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_43.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_43.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_43.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_43.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_44.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_44.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_44.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_44.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_44.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_44.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_45.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_45.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_45.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_45.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_45.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_45.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_46.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_46.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_46.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_46.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_46.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_46.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_47.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_47.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_47.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_47.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_47.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_47.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_48.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_48.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_48.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_48.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_48.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_48.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_49.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_49.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_49.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_49.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_49.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_49.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_5.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_5.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_5.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_5.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_5.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_5.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_50.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_50.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_50.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_50.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_50.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_50.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_51.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_51.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_51.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_51.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_51.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_51.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_6.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_6.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_6.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_6.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_6.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_6.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_7.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_7.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_7.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_7.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_7.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_7.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_8.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_8.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_8.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_8.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_8.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_8.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.map b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_9.map similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.map rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_9.map diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.md5 b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_9.md5 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.md5 rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_9.md5 diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_9.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherit_graph_9.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherits.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherits.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherits.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/inherits.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Airwell_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Airwell_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Airwell_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Airwell_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Aiwa_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Aiwa_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Aiwa_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Aiwa_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Amcor_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Amcor_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Amcor_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Amcor_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Amcor_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Amcor_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Argo_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Argo_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Argo_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Argo_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Argo_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Argo_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Carrier_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Carrier_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Carrier_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Carrier_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Carrier_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Carrier_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Coolix_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Coolix_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Coolix_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Coolix_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Coolix_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Coolix_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Corona_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Corona_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Corona_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Corona_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Corona_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Corona_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Daikin_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Daikin_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Daikin_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Daikin_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Daikin_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Daikin_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Delonghi_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Delonghi_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Delonghi_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Delonghi_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Delonghi_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Delonghi_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Denon_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Denon_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Denon_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Denon_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Dish_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Dish_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Dish_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Dish_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Doshisha_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Doshisha_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Doshisha_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Doshisha_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Electra_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Electra_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Electra_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Electra_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Electra_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Electra_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Epson_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Epson_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Epson_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Epson_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Fujitsu_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Fujitsu_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Fujitsu_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Fujitsu_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Fujitsu_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Fujitsu_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GICable_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__GICable_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GICable_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__GICable_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GlobalCache_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__GlobalCache_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GlobalCache_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__GlobalCache_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Goodweather_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Goodweather_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Goodweather_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Goodweather_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Goodweather_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Goodweather_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Gree_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Gree_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Gree_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Gree_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Gree_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Gree_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Haier_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Haier_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Haier_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Haier_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Haier_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Haier_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Hitachi_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Hitachi_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Hitachi_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Hitachi_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Hitachi_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Hitachi_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Inax_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Inax_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Inax_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Inax_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__JVC_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__JVC_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__JVC_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__JVC_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Kelvinator_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Kelvinator_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Kelvinator_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Kelvinator_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Kelvinator_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Kelvinator_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__LG_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__LG_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__LG_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__LG_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__LG_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__LG_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lasertag_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Lasertag_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lasertag_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Lasertag_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lego_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Lego_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lego_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Lego_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lutron_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Lutron_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lutron_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Lutron_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MWM_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__MWM_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MWM_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__MWM_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Magiquest_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Magiquest_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Magiquest_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Magiquest_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Magiquest_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Magiquest_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Midea_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Midea_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Midea_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Midea_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Midea_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Midea_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__MitsubishiHeavy_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__MitsubishiHeavy_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Mitsubishi_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Mitsubishi_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Mitsubishi_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Mitsubishi_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Mitsubishi_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Mitsubishi_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Multibrackets_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Multibrackets_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Multibrackets_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Multibrackets_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__NEC_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__NEC_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__NEC_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__NEC_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__NEC_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__NEC_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Neoclima_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Neoclima_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Neoclima_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Neoclima_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Neoclima_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Neoclima_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Nikai_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Nikai_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Nikai_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Nikai_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Panasonic_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Panasonic_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Panasonic_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Panasonic_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Panasonic_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Panasonic_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pioneer_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Pioneer_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pioneer_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Pioneer_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pronto_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Pronto_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pronto_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Pronto_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RC5__RC6_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__RC5__RC6_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RC5__RC6_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__RC5__RC6_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RCMM_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__RCMM_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RCMM_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__RCMM_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Samsung_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Samsung_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Samsung_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Samsung_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Samsung_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Samsung_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sanyo_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sanyo_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sanyo_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sanyo_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sharp_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sharp_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sharp_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sharp_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sharp_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sharp_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sherwood_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sherwood_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sherwood_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sherwood_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sony_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sony_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sony_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Sony_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Symphony_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Symphony_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Symphony_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Symphony_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Tcl_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Tcl_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Tcl_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Tcl_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Tcl_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Tcl_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Teco_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Teco_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Teco_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Teco_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Teco_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Teco_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Toshiba_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Toshiba_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Toshiba_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Toshiba_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Toshiba_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Toshiba_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Trotec_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Trotec_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Trotec_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Trotec_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Trotec_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Trotec_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Vestel_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Vestel_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Vestel_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Vestel_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Vestel_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Vestel_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Whirlpool_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Whirlpool_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Whirlpool_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Whirlpool_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Whirlpool_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Whirlpool_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whynter_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Whynter_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whynter_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Whynter_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Zepeal_8cpp.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Zepeal_8cpp.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Zepeal_8cpp.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/ir__Zepeal_8cpp.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/it-IT_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/it-IT_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/it-IT_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/it-IT_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/jquery.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/jquery.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/jquery.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/jquery.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/md_src_locale_README.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/md_src_locale_README.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/md_src_locale_README.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/md_src_locale_README.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menu.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/menu.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menu.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/menu.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menudata.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/menudata.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menudata.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/menudata.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceIRAcUtils.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespaceIRAcUtils.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceIRAcUtils.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespaceIRAcUtils.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceirutils.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespaceirutils.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceirutils.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespaceirutils.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespacemembers.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespacemembers.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_enum.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespacemembers_enum.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_enum.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespacemembers_enum.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_func.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespacemembers_func.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_func.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespacemembers_func.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaces.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespaces.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaces.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespaces.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacestdAc.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespacestdAc.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacestdAc.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/namespacestdAc.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_f.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/nav_f.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_f.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/nav_f.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_g.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/nav_g.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_g.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/nav_g.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_h.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/nav_h.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_h.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/nav_h.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/open.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/open.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/open.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/open.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/pages.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/pages.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/pages.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/pages.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_10.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_10.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_10.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_10.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_11.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_11.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_11.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_11.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_12.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_12.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_12.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_12.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_13.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_13.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_13.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_13.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_14.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_14.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_14.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_14.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_15.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_15.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_15.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_15.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_16.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_16.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_16.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_16.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_17.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_17.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_17.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_17.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_18.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_18.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_18.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_18.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_19.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_19.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_19.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_19.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1a.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1a.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1a.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1a.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1b.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1b.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1b.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_1b.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_2.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_2.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_2.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_2.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_3.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_3.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_3.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_3.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_4.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_4.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_4.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_4.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_5.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_5.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_5.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_5.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_6.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_6.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_6.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_6.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_7.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_7.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_7.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_7.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_8.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_8.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_8.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_8.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_9.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_9.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_9.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_9.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_a.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_a.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_a.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_a.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_b.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_b.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_b.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_b.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_c.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_c.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_c.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_c.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_d.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_d.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_d.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_d.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_e.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_e.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_e.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_e.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_f.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_f.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_f.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/all_f.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_1.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_1.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_2.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_2.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_2.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_2.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_3.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_3.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_3.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_3.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_4.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_4.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_4.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/classes_4.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/close.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/close.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/close.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/close.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_1.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_1.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_2.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_2.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_2.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_2.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_3.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_3.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_3.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_3.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_4.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_4.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_4.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_4.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_5.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_5.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_5.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_5.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_6.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_6.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_6.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_6.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_7.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_7.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_7.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_7.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_8.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_8.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_8.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enums_8.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_1.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_1.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_10.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_10.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_10.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_10.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_11.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_11.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_11.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_11.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_12.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_12.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_12.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_12.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_13.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_13.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_13.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_13.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_14.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_14.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_14.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_14.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_15.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_15.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_15.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_15.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_2.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_2.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_2.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_2.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_3.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_3.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_3.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_3.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_4.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_4.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_4.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_4.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_5.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_5.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_5.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_5.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_6.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_6.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_6.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_6.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_7.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_7.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_7.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_7.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_8.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_8.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_8.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_8.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_9.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_9.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_9.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_9.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_a.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_a.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_a.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_a.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_b.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_b.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_b.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_b.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_c.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_c.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_c.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_c.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_d.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_d.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_d.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_d.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_e.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_e.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_e.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_e.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_f.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_f.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_f.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/enumvalues_f.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_1.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_1.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_2.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_2.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_2.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_2.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_3.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_3.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_3.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_3.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_4.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_4.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_4.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_4.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_5.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_5.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_5.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/files_5.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_1.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_1.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_10.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_10.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_10.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_10.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_11.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_11.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_11.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_11.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_12.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_12.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_12.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_12.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_13.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_13.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_13.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_13.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_14.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_14.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_14.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_14.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_15.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_15.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_15.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_15.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_16.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_16.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_16.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_16.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_17.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_17.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_17.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_17.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_2.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_2.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_2.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_2.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_3.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_3.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_3.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_3.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_4.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_4.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_4.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_4.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_5.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_5.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_5.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_5.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_6.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_6.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_6.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_6.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_7.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_7.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_7.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_7.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_8.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_8.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_8.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_8.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_9.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_9.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_9.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_9.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_a.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_a.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_a.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_a.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_b.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_b.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_b.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_b.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_c.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_c.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_c.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_c.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_d.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_d.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_d.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_d.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_e.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_e.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_e.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_e.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_f.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_f.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_f.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/functions_f.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/mag_sel.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/mag_sel.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/mag_sel.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/mag_sel.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/namespaces_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/namespaces_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/namespaces_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/namespaces_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/namespaces_1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/namespaces_1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/namespaces_1.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/namespaces_1.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/nomatches.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/nomatches.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/nomatches.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/nomatches.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_1.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_1.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_2.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_2.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_2.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/pages_2.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/related_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/related_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/related_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/related_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.css b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search.css similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.css rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search.css diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_l.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search_l.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_l.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search_l.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_m.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search_m.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_m.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search_m.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_r.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search_r.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search_r.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/search_r.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/searchdata.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/searchdata.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/searchdata.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/searchdata.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/typedefs_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/typedefs_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/typedefs_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/typedefs_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_0.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_0.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_0.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_0.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_1.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_1.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_1.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_1.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_10.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_10.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_10.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_10.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_11.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_11.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_11.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_11.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_12.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_12.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_12.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_12.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_13.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_13.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_13.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_13.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_14.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_14.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_14.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_14.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_15.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_15.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_15.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_15.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_16.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_16.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_16.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_16.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_2.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_2.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_2.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_2.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_3.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_3.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_3.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_3.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_4.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_4.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_4.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_4.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_5.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_5.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_5.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_5.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_6.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_6.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_6.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_6.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_7.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_7.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_7.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_7.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_8.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_8.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_8.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_8.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_9.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_9.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_9.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_9.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_a.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_a.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_a.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_a.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_b.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_b.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_b.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_b.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_c.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_c.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_c.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_c.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_d.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_d.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_d.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_d.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_e.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_e.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_e.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_e.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_f.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_f.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.js b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_f.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.js rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/search/variables_f.js diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/splitbar.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/splitbar.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/splitbar.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/splitbar.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structirparams__t-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structirparams__t-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structirparams__t.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structirparams__t.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structmatch__result__t-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structmatch__result__t-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structmatch__result__t.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structmatch__result__t.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structstdAc_1_1state__t-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structstdAc_1_1state__t-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structstdAc_1_1state__t.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/structstdAc_1_1state__t.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_off.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/sync_off.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_off.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/sync_off.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_on.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/sync_on.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_on.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/sync_on.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_a.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tab_a.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_a.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tab_a.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_b.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tab_b.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_b.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tab_b.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_h.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tab_h.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_h.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tab_h.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_s.png b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tab_s.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_s.png rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tab_s.png diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tabs.css b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tabs.css similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tabs.css rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/tabs.css diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/todo.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/todo.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/todo.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/todo.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest-members.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/unionmagiquest-members.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest-members.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/unionmagiquest-members.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/unionmagiquest.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/unionmagiquest.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/zh-CN_8h.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/zh-CN_8h.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h_source.html b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/zh-CN_8h_source.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h_source.html rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen/html/zh-CN_8h_source.html diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen_index.md b/lib/IRremoteESP8266-2.7.8.10/docs/doxygen_index.md similarity index 100% rename from lib/IRremoteESP8266-2.7.8/docs/doxygen_index.md rename to lib/IRremoteESP8266-2.7.8.10/docs/doxygen_index.md diff --git a/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/BlynkIrRemote.ino b/lib/IRremoteESP8266-2.7.8.10/examples/BlynkIrRemote/BlynkIrRemote.ino similarity index 97% rename from lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/BlynkIrRemote.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/BlynkIrRemote/BlynkIrRemote.ino index 6e659bd64..7eaed8f83 100644 --- a/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/BlynkIrRemote.ino +++ b/lib/IRremoteESP8266-2.7.8.10/examples/BlynkIrRemote/BlynkIrRemote.ino @@ -1,196 +1,196 @@ -/************************************************************* - Emulate a physical remote via an iOS and Android App. - Copyright Gaurav Barwalia 2020 - - Download latest Blynk library here: - https://github.com/blynkkk/blynk-library/releases/latest - - Blynk is a platform with iOS and Android apps to control - Arduino, Raspberry Pi and the likes over the Internet. - You can easily build graphic interfaces for all your - projects by simply dragging and dropping widgets. - - Downloads, docs, tutorials: http://www.blynk.cc - Sketch generator: http://examples.blynk.cc - Blynk community: http://community.blynk.cc - Follow us: http://www.fb.com/blynkapp - http://twitter.com/blynk_app - - Blynk library is licensed under MIT license - This example code is in public domain. - - ************************************************************* - This example runs directly on ESP8266 chip. - - Note: This requires ESP8266 support package: - https://github.com/esp8266/Arduino - - Please be sure to select the right ESP8266 module - in the Tools -> Board menu! - - Change WiFi ssid, pass, and Blynk auth token to run :) - Feel free to apply it to any other example. It's simple! - *************************************************************/ - - /* - // After decoding received below codes - - // Power button - -18:12:33.993 -> Protocol : NEC -18:12:33.993 -> Code : 0x1FE50AF (32 Bits) -18:12:33.993 -> uint16_t rawData[71] = {9040, 4452, 606, 532, 606, 534, 630, 508, 604, 534, 604, 534, 604, 534, 630, 506, 606, 1646, 632, 1620, 606, 1646, 632, 1620, 630, 1620, 632, 1620, 630, 1620, 606, 1646, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1620, 632, 506, 632, 508, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1624, 628, 506, 632, 1620, 632, 1618, 632, 1620, 632, 1620, 632, 39016, 9040, 2216, 630}; // NEC 1FE50AF -18:12:34.027 -> uint32_t address = 0x80; -18:12:34.027 -> uint32_t command = 0xA; -18:12:34.027 -> uint64_t data = 0x1FE50AF; - -//mute button - -18:13:27.215 -> Protocol : NEC -18:13:27.215 -> Code : 0x1FE30CF (32 Bits) -18:13:27.215 -> uint16_t rawData[71] = {9094, 4398, 660, 478, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 660, 480, 658, 1594, 658, 1594, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 1592, 658, 1594, 660, 480, 658, 480, 658, 480, 658, 1592, 658, 1592, 658, 480, 658, 480, 660, 478, 660, 478, 658, 1594, 658, 1592, 658, 480, 658, 480, 658, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 38986, 9094, 2162, 658}; // NEC 1FE30CF -18:13:27.285 -> uint32_t address = 0x80; -18:13:27.285 -> uint32_t command = 0xC; -18:13:27.285 -> uint64_t data = 0x1FE30CF; - -//Vol. low - -18:14:44.427 -> Protocol : NEC -18:14:44.427 -> Code : 0x1FEC03F (32 Bits) -18:14:44.427 -> uint16_t rawData[71] = {9120, 4374, 658, 478, 658, 480, 658, 480, 658, 480, 658, 482, 658, 478, 658, 480, 658, 1594, 658, 1594, 658, 1592, 660, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 1592, 660, 480, 658, 1594, 658, 1594, 658, 480, 658, 480, 660, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 1594, 660, 1592, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 39002, 9094, 2162, 658}; // NEC 1FEC03F -18:14:44.497 -> uint32_t address = 0x80; -18:14:44.497 -> uint32_t command = 0x3; -18:14:44.497 -> uint64_t data = 0x1FEC03F; - -//VOl. High - -18:15:11.677 -> Protocol : NEC -18:15:11.677 -> Code : 0x1FE40BF (32 Bits) -18:15:11.677 -> uint16_t rawData[67] = {9068, 4426, 630, 506, 632, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 656, 1594, 630, 1622, 632, 1620, 630, 1622, 630, 508, 630, 508, 630, 1622, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 656, 482, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 632, 1620, 630}; // NEC 1FE40BF -18:15:11.747 -> uint32_t address = 0x80; -18:15:11.747 -> uint32_t command = 0x2; -18:15:11.747 -> uint64_t data = 0x1FE40BF; - -//Play/Pause - -18:15:38.529 -> Protocol : NEC -18:15:38.529 -> Code : 0x1FE32CD (32 Bits) -18:15:38.529 -> uint16_t rawData[71] = {9092, 4400, 632, 504, 658, 480, 658, 480, 632, 506, 658, 480, 658, 480, 658, 482, 632, 1620, 658, 1594, 658, 1594, 632, 1618, 658, 1594, 658, 1594, 632, 1620, 632, 1618, 634, 506, 658, 480, 658, 480, 632, 1620, 658, 1598, 656, 478, 658, 478, 658, 1594, 658, 482, 632, 1618, 632, 1618, 634, 506, 632, 506, 658, 1594, 632, 1620, 658, 480, 632, 1620, 658, 38998, 9094, 2162, 660}; // NEC 1FE32CD -18:15:38.564 -> uint32_t address = 0x80; -18:15:38.564 -> uint32_t command = 0x4C; -18:15:38.564 -> uint64_t data = 0x1FE32CD; - -//Song Back - -18:16:07.527 -> Protocol : NEC -18:16:07.527 -> Code : 0x1FEA05F (32 Bits) -18:16:07.562 -> uint16_t rawData[71] = {9590, 3902, 684, 452, 686, 456, 652, 480, 660, 480, 684, 456, 656, 480, 658, 480, 684, 1568, 658, 1594, 658, 1594, 686, 1566, 658, 1594, 684, 1568, 658, 1594, 658, 1594, 686, 454, 684, 1568, 686, 454, 658, 1594, 684, 454, 686, 454, 658, 480, 660, 480, 684, 454, 658, 482, 658, 1594, 682, 456, 658, 1596, 658, 1594, 686, 1568, 660, 1592, 684, 1568, 686, 38982, 9098, 2162, 684}; // NEC 1FEA05F -18:16:07.597 -> uint32_t address = 0x80; -18:16:07.597 -> uint32_t command = 0x5; -18:16:07.597 -> uint64_t data = 0x1FEA05F; - -//Song Forward - -18:17:20.541 -> Protocol : NEC -18:17:20.541 -> Code : 0x1FEE01F (32 Bits) -18:17:20.575 -> uint16_t rawData[71] = {9068, 4424, 632, 506, 630, 506, 632, 508, 606, 532, 632, 506, 630, 508, 630, 508, 632, 1620, 632, 1620, 632, 1620, 604, 1646, 606, 1646, 630, 1622, 604, 1646, 632, 1620, 606, 534, 630, 1622, 604, 1646, 630, 1622, 604, 534, 630, 508, 604, 534, 606, 534, 630, 508, 630, 508, 606, 534, 606, 532, 630, 1622, 604, 1646, 632, 1620, 604, 1648, 604, 1646, 604, 39040, 9040, 2216, 604}; // NEC 1FEE01F -18:17:20.610 -> uint32_t address = 0x80; -18:17:20.610 -> uint32_t command = 0x7; -18:17:20.610 -> uint64_t data = 0x1FEE01F; - - */ - -// check complete video tutorial here for program explanation https://www.youtube.com/watch?v=LqmkDKu54XY&t=17s - -/* Comment this out to disable prints and save space */ -#define BLYNK_PRINT Serial - -#if defined(ESP8266) -#include -#include -#else -#include -#endif // ESP8266 -#if defined(ESP32) -#include -#endif // ESP32 - -// IR library -#include -#include - -const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). -IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message. - -// You should get Auth Token in the Blynk App. -// Go to the Project Settings (nut icon). -char auth[] = "YourAuthToken"; - -// Your WiFi credentials. -// Set password to "" for open networks. -char ssid[] = "YourNetworkName"; -char pass[] = "YourPassword"; - - BLYNK_WRITE(V51) { // Power button - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FE50AF); - } - } - - BLYNK_WRITE(V52) { // Mute button - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FE30CF); - } - } - - BLYNK_WRITE(V53) { // Song Forward - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FEE01F); - } - } - - BLYNK_WRITE(V54) { // Song Backward - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FEA05F); - delay(10); // double tap back button to back one song - irsend.sendNEC(0x1FEA05F); - } - } - - BLYNK_WRITE(V55) { // Volume -- - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FEC03F); - } - } - - BLYNK_WRITE(V56) { // Volume ++ - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FE40BF); - } - } - - BLYNK_WRITE(V57) { // Play/Pause - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FE32CD); - } - } - -void setup() { -#if defined(BLYNK_PRINT) - // Debug console - Serial.begin(115200); -#endif // BLYNK_PRINT - - Blynk.begin(auth, ssid, pass); -} - -void loop() { - Blynk.run(); -} +/************************************************************* + Emulate a physical remote via an iOS and Android App. + Copyright Gaurav Barwalia 2020 + + Download latest Blynk library here: + https://github.com/blynkkk/blynk-library/releases/latest + + Blynk is a platform with iOS and Android apps to control + Arduino, Raspberry Pi and the likes over the Internet. + You can easily build graphic interfaces for all your + projects by simply dragging and dropping widgets. + + Downloads, docs, tutorials: http://www.blynk.cc + Sketch generator: http://examples.blynk.cc + Blynk community: http://community.blynk.cc + Follow us: http://www.fb.com/blynkapp + http://twitter.com/blynk_app + + Blynk library is licensed under MIT license + This example code is in public domain. + + ************************************************************* + This example runs directly on ESP8266 chip. + + Note: This requires ESP8266 support package: + https://github.com/esp8266/Arduino + + Please be sure to select the right ESP8266 module + in the Tools -> Board menu! + + Change WiFi ssid, pass, and Blynk auth token to run :) + Feel free to apply it to any other example. It's simple! + *************************************************************/ + + /* + // After decoding received below codes + + // Power button + +18:12:33.993 -> Protocol : NEC +18:12:33.993 -> Code : 0x1FE50AF (32 Bits) +18:12:33.993 -> uint16_t rawData[71] = {9040, 4452, 606, 532, 606, 534, 630, 508, 604, 534, 604, 534, 604, 534, 630, 506, 606, 1646, 632, 1620, 606, 1646, 632, 1620, 630, 1620, 632, 1620, 630, 1620, 606, 1646, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1620, 632, 506, 632, 508, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1624, 628, 506, 632, 1620, 632, 1618, 632, 1620, 632, 1620, 632, 39016, 9040, 2216, 630}; // NEC 1FE50AF +18:12:34.027 -> uint32_t address = 0x80; +18:12:34.027 -> uint32_t command = 0xA; +18:12:34.027 -> uint64_t data = 0x1FE50AF; + +//mute button + +18:13:27.215 -> Protocol : NEC +18:13:27.215 -> Code : 0x1FE30CF (32 Bits) +18:13:27.215 -> uint16_t rawData[71] = {9094, 4398, 660, 478, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 660, 480, 658, 1594, 658, 1594, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 1592, 658, 1594, 660, 480, 658, 480, 658, 480, 658, 1592, 658, 1592, 658, 480, 658, 480, 660, 478, 660, 478, 658, 1594, 658, 1592, 658, 480, 658, 480, 658, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 38986, 9094, 2162, 658}; // NEC 1FE30CF +18:13:27.285 -> uint32_t address = 0x80; +18:13:27.285 -> uint32_t command = 0xC; +18:13:27.285 -> uint64_t data = 0x1FE30CF; + +//Vol. low + +18:14:44.427 -> Protocol : NEC +18:14:44.427 -> Code : 0x1FEC03F (32 Bits) +18:14:44.427 -> uint16_t rawData[71] = {9120, 4374, 658, 478, 658, 480, 658, 480, 658, 480, 658, 482, 658, 478, 658, 480, 658, 1594, 658, 1594, 658, 1592, 660, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 1592, 660, 480, 658, 1594, 658, 1594, 658, 480, 658, 480, 660, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 1594, 660, 1592, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 39002, 9094, 2162, 658}; // NEC 1FEC03F +18:14:44.497 -> uint32_t address = 0x80; +18:14:44.497 -> uint32_t command = 0x3; +18:14:44.497 -> uint64_t data = 0x1FEC03F; + +//VOl. High + +18:15:11.677 -> Protocol : NEC +18:15:11.677 -> Code : 0x1FE40BF (32 Bits) +18:15:11.677 -> uint16_t rawData[67] = {9068, 4426, 630, 506, 632, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 656, 1594, 630, 1622, 632, 1620, 630, 1622, 630, 508, 630, 508, 630, 1622, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 656, 482, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 632, 1620, 630}; // NEC 1FE40BF +18:15:11.747 -> uint32_t address = 0x80; +18:15:11.747 -> uint32_t command = 0x2; +18:15:11.747 -> uint64_t data = 0x1FE40BF; + +//Play/Pause + +18:15:38.529 -> Protocol : NEC +18:15:38.529 -> Code : 0x1FE32CD (32 Bits) +18:15:38.529 -> uint16_t rawData[71] = {9092, 4400, 632, 504, 658, 480, 658, 480, 632, 506, 658, 480, 658, 480, 658, 482, 632, 1620, 658, 1594, 658, 1594, 632, 1618, 658, 1594, 658, 1594, 632, 1620, 632, 1618, 634, 506, 658, 480, 658, 480, 632, 1620, 658, 1598, 656, 478, 658, 478, 658, 1594, 658, 482, 632, 1618, 632, 1618, 634, 506, 632, 506, 658, 1594, 632, 1620, 658, 480, 632, 1620, 658, 38998, 9094, 2162, 660}; // NEC 1FE32CD +18:15:38.564 -> uint32_t address = 0x80; +18:15:38.564 -> uint32_t command = 0x4C; +18:15:38.564 -> uint64_t data = 0x1FE32CD; + +//Song Back + +18:16:07.527 -> Protocol : NEC +18:16:07.527 -> Code : 0x1FEA05F (32 Bits) +18:16:07.562 -> uint16_t rawData[71] = {9590, 3902, 684, 452, 686, 456, 652, 480, 660, 480, 684, 456, 656, 480, 658, 480, 684, 1568, 658, 1594, 658, 1594, 686, 1566, 658, 1594, 684, 1568, 658, 1594, 658, 1594, 686, 454, 684, 1568, 686, 454, 658, 1594, 684, 454, 686, 454, 658, 480, 660, 480, 684, 454, 658, 482, 658, 1594, 682, 456, 658, 1596, 658, 1594, 686, 1568, 660, 1592, 684, 1568, 686, 38982, 9098, 2162, 684}; // NEC 1FEA05F +18:16:07.597 -> uint32_t address = 0x80; +18:16:07.597 -> uint32_t command = 0x5; +18:16:07.597 -> uint64_t data = 0x1FEA05F; + +//Song Forward + +18:17:20.541 -> Protocol : NEC +18:17:20.541 -> Code : 0x1FEE01F (32 Bits) +18:17:20.575 -> uint16_t rawData[71] = {9068, 4424, 632, 506, 630, 506, 632, 508, 606, 532, 632, 506, 630, 508, 630, 508, 632, 1620, 632, 1620, 632, 1620, 604, 1646, 606, 1646, 630, 1622, 604, 1646, 632, 1620, 606, 534, 630, 1622, 604, 1646, 630, 1622, 604, 534, 630, 508, 604, 534, 606, 534, 630, 508, 630, 508, 606, 534, 606, 532, 630, 1622, 604, 1646, 632, 1620, 604, 1648, 604, 1646, 604, 39040, 9040, 2216, 604}; // NEC 1FEE01F +18:17:20.610 -> uint32_t address = 0x80; +18:17:20.610 -> uint32_t command = 0x7; +18:17:20.610 -> uint64_t data = 0x1FEE01F; + + */ + +// check complete video tutorial here for program explanation https://www.youtube.com/watch?v=LqmkDKu54XY&t=17s + +/* Comment this out to disable prints and save space */ +#define BLYNK_PRINT Serial + +#if defined(ESP8266) +#include +#include +#else +#include +#endif // ESP8266 +#if defined(ESP32) +#include +#endif // ESP32 + +// IR library +#include +#include + +const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). +IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message. + +// You should get Auth Token in the Blynk App. +// Go to the Project Settings (nut icon). +char auth[] = "YourAuthToken"; + +// Your WiFi credentials. +// Set password to "" for open networks. +char ssid[] = "YourNetworkName"; +char pass[] = "YourPassword"; + + BLYNK_WRITE(V51) { // Power button + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE50AF); + } + } + + BLYNK_WRITE(V52) { // Mute button + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE30CF); + } + } + + BLYNK_WRITE(V53) { // Song Forward + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEE01F); + } + } + + BLYNK_WRITE(V54) { // Song Backward + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEA05F); + delay(10); // double tap back button to back one song + irsend.sendNEC(0x1FEA05F); + } + } + + BLYNK_WRITE(V55) { // Volume -- + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEC03F); + } + } + + BLYNK_WRITE(V56) { // Volume ++ + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE40BF); + } + } + + BLYNK_WRITE(V57) { // Play/Pause + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE32CD); + } + } + +void setup() { +#if defined(BLYNK_PRINT) + // Debug console + Serial.begin(115200); +#endif // BLYNK_PRINT + + Blynk.begin(auth, ssid, pass); +} + +void loop() { + Blynk.run(); +} diff --git a/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/BlynkIrRemote/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/BlynkIrRemote/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/CommonAcControl.ino b/lib/IRremoteESP8266-2.7.8.10/examples/CommonAcControl/CommonAcControl.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/CommonAcControl.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/CommonAcControl/CommonAcControl.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/CommonAcControl/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/CommonAcControl/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/ControlSamsungAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/ControlSamsungAC/ControlSamsungAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/ControlSamsungAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/ControlSamsungAC/ControlSamsungAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/ControlSamsungAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/ControlSamsungAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/DumbIRRepeater.ino b/lib/IRremoteESP8266-2.7.8.10/examples/DumbIRRepeater/DumbIRRepeater.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/DumbIRRepeater.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/DumbIRRepeater/DumbIRRepeater.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/DumbIRRepeater/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/DumbIRRepeater/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/IRGCSendDemo.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRGCSendDemo/IRGCSendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/IRGCSendDemo.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRGCSendDemo/IRGCSendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRGCSendDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRGCSendDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/IRGCTCPServer.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRGCTCPServer/IRGCTCPServer.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/IRGCTCPServer.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRGCTCPServer/IRGCTCPServer.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRGCTCPServer/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRGCTCPServer/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.h b/lib/IRremoteESP8266-2.7.8.10/examples/IRMQTTServer/IRMQTTServer.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.h rename to lib/IRremoteESP8266-2.7.8.10/examples/IRMQTTServer/IRMQTTServer.h diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRMQTTServer/IRMQTTServer.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRMQTTServer/IRMQTTServer.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRMQTTServer/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRMQTTServer/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRServer/IRServer.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRServer/IRServer.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRServer/IRServer.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRServer/IRServer.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRServer/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRServer/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRServer/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRServer/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/IRrecvDemo.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDemo/IRrecvDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/IRrecvDemo.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDemo/IRrecvDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/IRrecvDump.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDump/IRrecvDump.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/IRrecvDump.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDump/IRrecvDump.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDump/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDump/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV2/IRrecvDumpV2.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/IRrecvDumpV2.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV2/IRrecvDumpV2.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV2/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV2/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/BaseOTA.h b/lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV3/BaseOTA.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/BaseOTA.h rename to lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV3/BaseOTA.h diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/IRrecvDumpV3.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV3/IRrecvDumpV3.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/IRrecvDumpV3.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV3/IRrecvDumpV3.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV3/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRrecvDumpV3/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/IRsendDemo.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRsendDemo/IRsendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/IRsendDemo.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRsendDemo/IRsendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRsendDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRsendDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/IRsendProntoDemo.ino b/lib/IRremoteESP8266-2.7.8.10/examples/IRsendProntoDemo/IRsendProntoDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/IRsendProntoDemo.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/IRsendProntoDemo/IRsendProntoDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/IRsendProntoDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/IRsendProntoDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino b/lib/IRremoteESP8266-2.7.8.10/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/JVCPanasonicSendDemo/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/JVCPanasonicSendDemo/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/LGACSend/LGACSend.ino b/lib/IRremoteESP8266-2.7.8.10/examples/LGACSend/LGACSend.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/LGACSend/LGACSend.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/LGACSend/LGACSend.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/LGACSend/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/LGACSend/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/LGACSend/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/LGACSend/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/SmartIRRepeater.ino b/lib/IRremoteESP8266-2.7.8.10/examples/SmartIRRepeater/SmartIRRepeater.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/SmartIRRepeater.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/SmartIRRepeater/SmartIRRepeater.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/SmartIRRepeater/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/SmartIRRepeater/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/TurnOnArgoAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnArgoAC/TurnOnArgoAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/TurnOnArgoAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnArgoAC/TurnOnArgoAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnArgoAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnArgoAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnDaikinAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnDaikinAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnFujitsuAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnFujitsuAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/TurnOnGreeAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnGreeAC/TurnOnGreeAC.ino similarity index 97% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/TurnOnGreeAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnGreeAC/TurnOnGreeAC.ino index 64c857f3d..ecb3b8869 100644 --- a/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/TurnOnGreeAC.ino +++ b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnGreeAC/TurnOnGreeAC.ino @@ -1,77 +1,77 @@ -/* Copyright 2016, 2018 David Conran -* Copyright 2020 Sadid Rafsun Tulon -* -* An IR LED circuit *MUST* be connected to the ESP8266 on a pin -* as specified by kIrLed below. -* -* TL;DR: The IR LED needs to be driven by a transistor for a good result. -* -* Suggested circuit: -* https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-sending -* -* Common mistakes & tips: -* * Don't just connect the IR LED directly to the pin, it won't -* have enough current to drive the IR LED effectively. -* * Make sure you have the IR LED polarity correct. -* See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity -* * Typical digital camera/phones can be used to see if the IR LED is flashed. -* Replace the IR LED with a normal LED if you don't have a digital camera -* when debugging. -* * Avoid using the following pins unless you really know what you are doing: -* * Pin 0/D3: Can interfere with the boot/program mode & support circuits. -* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere. -* * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere. -* * ESP-01 modules are tricky. We suggest you use a module with more GPIOs -* for your first time. e.g. ESP-12 etc. -*/ -#include -#include -#include -#include - -const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). -IRGreeAC ac(kIrLed); // Set the GPIO to be used for sending messages. - -void printState() { - // Display the settings. - Serial.println("GREE A/C remote is in the following state:"); - Serial.printf(" %s\n", ac.toString().c_str()); - // Display the encoded IR sequence. - unsigned char* ir_code = ac.getRaw(); - Serial.print("IR Code: 0x"); - for (uint8_t i = 0; i < kGreeStateLength; i++) - Serial.printf("%02X", ir_code[i]); - Serial.println(); -} - -void setup() { - ac.begin(); - Serial.begin(115200); - delay(200); - - // Set up what we want to send. See ir_Gree.cpp for all the options. - // Most things default to off. - Serial.println("Default state of the remote."); - printState(); - Serial.println("Setting desired state for A/C."); - ac.on(); - ac.setFan(1); - // kGreeAuto, kGreeDry, kGreeCool, kGreeFan, kGreeHeat - ac.setMode(kGreeCool); - ac.setTemp(20); // 16-30C - ac.setSwingVertical(true, kGreeSwingAuto); - ac.setXFan(false); - ac.setLight(false); - ac.setSleep(false); - ac.setTurbo(false); -} - -void loop() { - // Now send the IR signal. -#if SEND_GREE - Serial.println("Sending IR command to A/C ..."); - ac.send(); -#endif // SEND_GREE - printState(); - delay(5000); -} +/* Copyright 2016, 2018 David Conran +* Copyright 2020 Sadid Rafsun Tulon +* +* An IR LED circuit *MUST* be connected to the ESP8266 on a pin +* as specified by kIrLed below. +* +* TL;DR: The IR LED needs to be driven by a transistor for a good result. +* +* Suggested circuit: +* https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-sending +* +* Common mistakes & tips: +* * Don't just connect the IR LED directly to the pin, it won't +* have enough current to drive the IR LED effectively. +* * Make sure you have the IR LED polarity correct. +* See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity +* * Typical digital camera/phones can be used to see if the IR LED is flashed. +* Replace the IR LED with a normal LED if you don't have a digital camera +* when debugging. +* * Avoid using the following pins unless you really know what you are doing: +* * Pin 0/D3: Can interfere with the boot/program mode & support circuits. +* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere. +* * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere. +* * ESP-01 modules are tricky. We suggest you use a module with more GPIOs +* for your first time. e.g. ESP-12 etc. +*/ +#include +#include +#include +#include + +const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). +IRGreeAC ac(kIrLed); // Set the GPIO to be used for sending messages. + +void printState() { + // Display the settings. + Serial.println("GREE A/C remote is in the following state:"); + Serial.printf(" %s\n", ac.toString().c_str()); + // Display the encoded IR sequence. + unsigned char* ir_code = ac.getRaw(); + Serial.print("IR Code: 0x"); + for (uint8_t i = 0; i < kGreeStateLength; i++) + Serial.printf("%02X", ir_code[i]); + Serial.println(); +} + +void setup() { + ac.begin(); + Serial.begin(115200); + delay(200); + + // Set up what we want to send. See ir_Gree.cpp for all the options. + // Most things default to off. + Serial.println("Default state of the remote."); + printState(); + Serial.println("Setting desired state for A/C."); + ac.on(); + ac.setFan(1); + // kGreeAuto, kGreeDry, kGreeCool, kGreeFan, kGreeHeat + ac.setMode(kGreeCool); + ac.setTemp(20); // 16-30C + ac.setSwingVertical(true, kGreeSwingAuto); + ac.setXFan(false); + ac.setLight(false); + ac.setSleep(false); + ac.setTurbo(false); +} + +void loop() { + // Now send the IR signal. +#if SEND_GREE + Serial.println("Sending IR command to A/C ..."); + ac.send(); +#endif // SEND_GREE + printState(); + delay(5000); +} diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnGreeAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnGreeAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnKelvinatorAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnKelvinatorAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnMitsubishiAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnMitsubishiAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnMitsubishiHeavyAc/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnMitsubishiHeavyAc/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnPanasonicAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnPanasonicAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnToshibaAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnToshibaAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/TurnOnTrotecAC/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/TurnOnTrotecAC/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/README.md b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/README.md similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/README.md rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/README.md diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/Web-AC-control.ino b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/Web-AC-control.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/Web-AC-control.ino rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/Web-AC-control.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/printscreen.png b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/printscreen.png similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/printscreen.png rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/printscreen.png diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/favicon.ico b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/favicon.ico similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/favicon.ico rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/favicon.ico diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_off.svg b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_1_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_off.svg rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_1_off.svg diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_on.svg b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_1_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_on.svg rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_1_on.svg diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_off.svg b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_2_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_off.svg rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_2_off.svg diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_on.svg b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_2_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_on.svg rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_2_on.svg diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_off.svg b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_3_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_off.svg rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_3_off.svg diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_on.svg b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_3_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_on.svg rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_3_on.svg diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_off.svg b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_4_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_off.svg rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_4_off.svg diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_on.svg b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_4_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_on.svg rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/level_4_on.svg diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.html b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/ui.html similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.html rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/ui.html diff --git a/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.js b/lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/ui.js similarity index 100% rename from lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.js rename to lib/IRremoteESP8266-2.7.8.10/examples/Web-AC-control/upload/ui.js diff --git a/lib/IRremoteESP8266-2.7.8/keywords.txt b/lib/IRremoteESP8266-2.7.8.10/keywords.txt similarity index 100% rename from lib/IRremoteESP8266-2.7.8/keywords.txt rename to lib/IRremoteESP8266-2.7.8.10/keywords.txt diff --git a/lib/IRremoteESP8266-2.7.8/library.json b/lib/IRremoteESP8266-2.7.8.10/library.json similarity index 100% rename from lib/IRremoteESP8266-2.7.8/library.json rename to lib/IRremoteESP8266-2.7.8.10/library.json diff --git a/lib/IRremoteESP8266-2.7.8/library.properties b/lib/IRremoteESP8266-2.7.8.10/library.properties similarity index 100% rename from lib/IRremoteESP8266-2.7.8/library.properties rename to lib/IRremoteESP8266-2.7.8.10/library.properties diff --git a/lib/IRremoteESP8266-2.7.8/platformio.ini b/lib/IRremoteESP8266-2.7.8.10/platformio.ini similarity index 100% rename from lib/IRremoteESP8266-2.7.8/platformio.ini rename to lib/IRremoteESP8266-2.7.8.10/platformio.ini diff --git a/lib/IRremoteESP8266-2.7.8/pylintrc b/lib/IRremoteESP8266-2.7.8.10/pylintrc similarity index 100% rename from lib/IRremoteESP8266-2.7.8/pylintrc rename to lib/IRremoteESP8266-2.7.8.10/pylintrc diff --git a/lib/IRremoteESP8266-2.7.8/src/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.8.10/src/CPPLINT.cfg similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/CPPLINT.cfg rename to lib/IRremoteESP8266-2.7.8.10/src/CPPLINT.cfg diff --git a/lib/IRremoteESP8266-2.7.8/src/IRac.cpp b/lib/IRremoteESP8266-2.7.8.10/src/IRac.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRac.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/IRac.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/IRac.h b/lib/IRremoteESP8266-2.7.8.10/src/IRac.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRac.h rename to lib/IRremoteESP8266-2.7.8.10/src/IRac.h diff --git a/lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp b/lib/IRremoteESP8266-2.7.8.10/src/IRrecv.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/IRrecv.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/IRrecv.h b/lib/IRremoteESP8266-2.7.8.10/src/IRrecv.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRrecv.h rename to lib/IRremoteESP8266-2.7.8.10/src/IRrecv.h diff --git a/lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h b/lib/IRremoteESP8266-2.7.8.10/src/IRremoteESP8266.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h rename to lib/IRremoteESP8266-2.7.8.10/src/IRremoteESP8266.h diff --git a/lib/IRremoteESP8266-2.7.8/src/IRsend.cpp b/lib/IRremoteESP8266-2.7.8.10/src/IRsend.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRsend.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/IRsend.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/IRsend.h b/lib/IRremoteESP8266-2.7.8.10/src/IRsend.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRsend.h rename to lib/IRremoteESP8266-2.7.8.10/src/IRsend.h diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp b/lib/IRremoteESP8266-2.7.8.10/src/IRtext.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRtext.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/IRtext.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtext.h b/lib/IRremoteESP8266-2.7.8.10/src/IRtext.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRtext.h rename to lib/IRremoteESP8266-2.7.8.10/src/IRtext.h diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp b/lib/IRremoteESP8266-2.7.8.10/src/IRtimer.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/IRtimer.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtimer.h b/lib/IRremoteESP8266-2.7.8.10/src/IRtimer.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRtimer.h rename to lib/IRremoteESP8266-2.7.8.10/src/IRtimer.h diff --git a/lib/IRremoteESP8266-2.7.8/src/IRutils.cpp b/lib/IRremoteESP8266-2.7.8.10/src/IRutils.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRutils.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/IRutils.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/IRutils.h b/lib/IRremoteESP8266-2.7.8.10/src/IRutils.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/IRutils.h rename to lib/IRremoteESP8266-2.7.8.10/src/IRutils.h diff --git a/lib/IRremoteESP8266-2.7.8/src/i18n.h b/lib/IRremoteESP8266-2.7.8.10/src/i18n.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/i18n.h rename to lib/IRremoteESP8266-2.7.8.10/src/i18n.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Airwell.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Airwell.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Airwell.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Airwell.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Airwell.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Aiwa.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Aiwa.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Aiwa.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Aiwa.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Amcor.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Amcor.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Amcor.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Amcor.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Amcor.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Amcor.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Argo.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Argo.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Argo.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Argo.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Argo.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Argo.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Argo.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Argo.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Carrier.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Carrier.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Carrier.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Carrier.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Coolix.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Coolix.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Coolix.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Coolix.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Coolix.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Coolix.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Corona.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Corona.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Corona.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Corona.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Corona.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Corona.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Daikin.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Daikin.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Daikin.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Daikin.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Daikin.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Delonghi.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Delonghi.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Delonghi.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Delonghi.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Denon.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Denon.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Denon.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Denon.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Dish.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Dish.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Dish.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Dish.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Doshisha.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Doshisha.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Doshisha.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Doshisha.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Electra.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Electra.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Electra.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Electra.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Electra.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Electra.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Electra.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Electra.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Epson.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Epson.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Epson.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Epson.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Fujitsu.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Fujitsu.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Fujitsu.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Fujitsu.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_GICable.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_GICable.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_GICable.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_GICable.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_GlobalCache.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_GlobalCache.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_GlobalCache.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_GlobalCache.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Goodweather.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Goodweather.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Goodweather.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Goodweather.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Gree.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Gree.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Gree.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Gree.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Gree.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Gree.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Gree.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Gree.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Haier.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Haier.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Haier.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Haier.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Haier.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Haier.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Haier.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Haier.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Hitachi.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Hitachi.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Hitachi.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Hitachi.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Inax.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Inax.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Inax.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Inax.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_JVC.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_JVC.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_JVC.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_JVC.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Kelvinator.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Kelvinator.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Kelvinator.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Kelvinator.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_LG.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_LG.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_LG.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_LG.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_LG.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_LG.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Lasertag.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Lasertag.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Lasertag.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Lasertag.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Lego.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Lego.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Lego.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Lego.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Lutron.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Lutron.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Lutron.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Lutron.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_MWM.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_MWM.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_MWM.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_MWM.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Magiquest.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Magiquest.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Magiquest.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Magiquest.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Midea.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Midea.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Midea.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Midea.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Midea.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Midea.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Mitsubishi.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Mitsubishi.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Mitsubishi.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Mitsubishi.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_MitsubishiHeavy.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_MitsubishiHeavy.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_MitsubishiHeavy.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_MitsubishiHeavy.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Multibrackets.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Multibrackets.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Multibrackets.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Multibrackets.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_NEC.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_NEC.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_NEC.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_NEC.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_NEC.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_NEC.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_NEC.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_NEC.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Neoclima.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Neoclima.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Neoclima.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Neoclima.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Nikai.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Nikai.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Nikai.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Nikai.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Panasonic.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Panasonic.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Panasonic.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Panasonic.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Pioneer.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Pioneer.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Pronto.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Pronto.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Pronto.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Pronto.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_RC5_RC6.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_RC5_RC6.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_RC5_RC6.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_RC5_RC6.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_RCMM.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_RCMM.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_RCMM.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_RCMM.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Samsung.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Samsung.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Samsung.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Samsung.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Sanyo.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Sanyo.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Sanyo.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Sanyo.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Sharp.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Sharp.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Sharp.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Sharp.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Sharp.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Sharp.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Sherwood.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Sherwood.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sony.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Sony.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Sony.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Sony.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Symphony.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Symphony.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Symphony.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Symphony.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Tcl.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Tcl.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Tcl.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Tcl.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Tcl.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Tcl.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Teco.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Teco.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Teco.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Teco.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Teco.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Teco.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Teco.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Teco.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Toshiba.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Toshiba.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Toshiba.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Toshiba.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Trotec.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Trotec.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Trotec.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Trotec.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Trotec.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Trotec.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Vestel.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Vestel.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Vestel.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Vestel.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Vestel.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Vestel.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Whirlpool.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Whirlpool.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.h b/lib/IRremoteESP8266-2.7.8.10/src/ir_Whirlpool.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.h rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Whirlpool.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Whynter.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Whynter.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Whynter.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Whynter.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp b/lib/IRremoteESP8266-2.7.8.10/src/ir_Zepeal.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp rename to lib/IRremoteESP8266-2.7.8.10/src/ir_Zepeal.cpp diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/README.md b/lib/IRremoteESP8266-2.7.8.10/src/locale/README.md similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/README.md rename to lib/IRremoteESP8266-2.7.8.10/src/locale/README.md diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/de-CH.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/de-CH.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/de-CH.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/de-CH.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/de-DE.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/de-DE.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/de-DE.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/de-DE.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/defaults.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/defaults.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/defaults.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/en-AU.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/en-AU.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/en-AU.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/en-AU.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/en-IE.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/en-IE.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/en-IE.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/en-IE.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/en-UK.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/en-UK.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/en-UK.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/en-UK.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/en-US.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/en-US.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/en-US.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/en-US.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/es-ES.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/es-ES.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/es-ES.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/es-ES.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/fr-FR.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/fr-FR.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/fr-FR.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/fr-FR.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/it-IT.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/it-IT.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/it-IT.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/it-IT.h diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/zh-CN.h b/lib/IRremoteESP8266-2.7.8.10/src/locale/zh-CN.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/src/locale/zh-CN.h rename to lib/IRremoteESP8266-2.7.8.10/src/locale/zh-CN.h diff --git a/lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/IRac_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/IRac_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/IRrecv_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/IRrecv_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/IRrecv_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/IRrecv_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/IRrecv_test.h b/lib/IRremoteESP8266-2.7.8.10/test/IRrecv_test.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/IRrecv_test.h rename to lib/IRremoteESP8266-2.7.8.10/test/IRrecv_test.h diff --git a/lib/IRremoteESP8266-2.7.8/test/IRsend_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/IRsend_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/IRsend_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/IRsend_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/IRsend_test.h b/lib/IRremoteESP8266-2.7.8.10/test/IRsend_test.h similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/IRsend_test.h rename to lib/IRremoteESP8266-2.7.8.10/test/IRsend_test.h diff --git a/lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/IRutils_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/IRutils_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/Makefile b/lib/IRremoteESP8266-2.7.8.10/test/Makefile similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/Makefile rename to lib/IRremoteESP8266-2.7.8.10/test/Makefile diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Airwell_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Airwell_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Aiwa_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Aiwa_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Aiwa_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Aiwa_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Amcor_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Amcor_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Amcor_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Amcor_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Argo_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Argo_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Argo_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Argo_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Carrier_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Carrier_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Carrier_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Carrier_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Coolix_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Coolix_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Coolix_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Coolix_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Corona_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Corona_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Corona_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Corona_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Daikin_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Daikin_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Daikin_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Daikin_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Delonghi_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Delonghi_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Delonghi_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Delonghi_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Denon_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Denon_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Denon_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Denon_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Dish_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Dish_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Dish_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Dish_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Doshisha_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Doshisha_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Doshisha_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Doshisha_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Electra_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Electra_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Electra_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Electra_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Epson_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Epson_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Epson_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Epson_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Fujitsu_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Fujitsu_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Fujitsu_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Fujitsu_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_GICable_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_GICable_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_GICable_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_GICable_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_GlobalCache_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_GlobalCache_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_GlobalCache_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_GlobalCache_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Goodweather_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Goodweather_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Goodweather_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Goodweather_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Gree_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Gree_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Gree_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Gree_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Haier_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Haier_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Haier_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Haier_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Hitachi_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Hitachi_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Hitachi_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Hitachi_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Inax_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Inax_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Inax_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Inax_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_JVC_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_JVC_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_JVC_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_JVC_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Kelvinator_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Kelvinator_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Kelvinator_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Kelvinator_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_LG_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_LG_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Lasertag_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Lasertag_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Lasertag_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Lasertag_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Lego_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Lego_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Lego_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Lego_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Lutron_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Lutron_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Lutron_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Lutron_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_MWM_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_MWM_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_MWM_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_MWM_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Magiquest_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Magiquest_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Magiquest_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Magiquest_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Midea_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Midea_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_MitsubishiHeavy_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_MitsubishiHeavy_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_MitsubishiHeavy_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_MitsubishiHeavy_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Mitsubishi_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Mitsubishi_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Mitsubishi_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Mitsubishi_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Multibrackets_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Multibrackets_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Multibrackets_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Multibrackets_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_NEC_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_NEC_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_NEC_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_NEC_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Neoclima_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Neoclima_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Neoclima_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Neoclima_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Nikai_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Nikai_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Nikai_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Nikai_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Panasonic_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Panasonic_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Panasonic_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Panasonic_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Pioneer_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Pioneer_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Pronto_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Pronto_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Pronto_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Pronto_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_RC5_RC6_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_RC5_RC6_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_RC5_RC6_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_RC5_RC6_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_RCMM_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_RCMM_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_RCMM_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_RCMM_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Samsung_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Samsung_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Sanyo_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Sanyo_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Sharp_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Sharp_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Sharp_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Sharp_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Sherwood_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Sherwood_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Sherwood_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Sherwood_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Sony_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Sony_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Sony_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Sony_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Symphony_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Symphony_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Symphony_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Symphony_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Tcl_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Tcl_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Tcl_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Tcl_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Teco_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Teco_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Teco_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Teco_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Toshiba_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Toshiba_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Trotec_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Trotec_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Trotec_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Trotec_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Vestel_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Vestel_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Vestel_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Vestel_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Whirlpool_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Whirlpool_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Whirlpool_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Whirlpool_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Whynter_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Whynter_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Whynter_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Whynter_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Zepeal_test.cpp b/lib/IRremoteESP8266-2.7.8.10/test/ir_Zepeal_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/test/ir_Zepeal_test.cpp rename to lib/IRremoteESP8266-2.7.8.10/test/ir_Zepeal_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/tools/Makefile b/lib/IRremoteESP8266-2.7.8.10/tools/Makefile similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/Makefile rename to lib/IRremoteESP8266-2.7.8.10/tools/Makefile diff --git a/lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh b/lib/IRremoteESP8266-2.7.8.10/tools/RawToGlobalCache.sh old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh rename to lib/IRremoteESP8266-2.7.8.10/tools/RawToGlobalCache.sh diff --git a/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py b/lib/IRremoteESP8266-2.7.8.10/tools/auto_analyse_raw_data.py old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py rename to lib/IRremoteESP8266-2.7.8.10/tools/auto_analyse_raw_data.py diff --git a/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py b/lib/IRremoteESP8266-2.7.8.10/tools/auto_analyse_raw_data_test.py old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py rename to lib/IRremoteESP8266-2.7.8.10/tools/auto_analyse_raw_data_test.py diff --git a/lib/IRremoteESP8266-2.7.8/tools/gc_decode.cpp b/lib/IRremoteESP8266-2.7.8.10/tools/gc_decode.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/gc_decode.cpp rename to lib/IRremoteESP8266-2.7.8.10/tools/gc_decode.cpp diff --git a/lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh b/lib/IRremoteESP8266-2.7.8.10/tools/generate_irtext_h.sh old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh rename to lib/IRremoteESP8266-2.7.8.10/tools/generate_irtext_h.sh diff --git a/lib/IRremoteESP8266-2.7.8/tools/mkkeywords b/lib/IRremoteESP8266-2.7.8.10/tools/mkkeywords old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/mkkeywords rename to lib/IRremoteESP8266-2.7.8.10/tools/mkkeywords diff --git a/lib/IRremoteESP8266-2.7.8/tools/mode2_decode.cpp b/lib/IRremoteESP8266-2.7.8.10/tools/mode2_decode.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/mode2_decode.cpp rename to lib/IRremoteESP8266-2.7.8.10/tools/mode2_decode.cpp diff --git a/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code.py b/lib/IRremoteESP8266-2.7.8.10/tools/raw_to_pronto_code.py old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code.py rename to lib/IRremoteESP8266-2.7.8.10/tools/raw_to_pronto_code.py diff --git a/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code_test.py b/lib/IRremoteESP8266-2.7.8.10/tools/raw_to_pronto_code_test.py old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code_test.py rename to lib/IRremoteESP8266-2.7.8.10/tools/raw_to_pronto_code_test.py diff --git a/lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py b/lib/IRremoteESP8266-2.7.8.10/tools/scrape_supported_devices.py old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py rename to lib/IRremoteESP8266-2.7.8.10/tools/scrape_supported_devices.py diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 0f13cfe48..d61be6e00 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,6 +3,7 @@ ### 8.3.1.7 20200716 - Remove Arduino ESP8266 Core support for versions before 2.7.1 +- Change IRRemoteESP8266 library to v2.7.8.10, fixing Samsung and Pioneer protocols (#8938) - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE - Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message - Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` @@ -13,7 +14,6 @@ - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 - Add command (``S``)``SerialSend6`` \ (#8937) - Add support for Sonoff Zigbee Bridge as module 75 (#8583) -- Change IRRemoteESP8266 IR lib to pre-2.7.9, fixing Samsung and Pioneer protocols (#8938) ### 8.3.1.6 20200617 @@ -79,8 +79,6 @@ - Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) - Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) -## Released - ### 8.3.1 20200518 - Release Fred @@ -97,8 +95,6 @@ - Change Quick Power Cycle detection from 4 to 7 power interrupts (#4066) - Fix default state of ``SetOption73 0`` for button decoupling and send multi-press and hold MQTT messages -## Released - ### 8.3.0 20200514 - Release Fred @@ -183,8 +179,6 @@ - Add support for unreachable (unplugged) Zigbee devices in Philips Hue emulation and Alexa - Add support for 64x48 SSD1306 OLED (#6740) -## Released - ### 8.2.0 20200321 - Release Elliot